Ticket #6256: archiving.patch

File archiving.patch, 25.4 KB (added by yourpalal, 14 years ago)

Updated patch

  • src/kits/support/Archivable.cpp

     
    11/*
    2  * Copyright (c) 2001-2008, Haiku, Inc.
     2 * Copyright (c) 2001-2010, Haiku, Inc.
    33 * Distributed under the terms of the MIT License.
    44 *
    55 * Authors:
    66 *      Erik Jaesler (erik@cgsoftware.com)
     7 *      Alex Wilson (yourpalal2@gmail.com)
    78 */
    89
    910/*! BArchivable mix-in class defines the archiving protocol.
     
    2930#include <Roster.h>
    3031#include <String.h>
    3132
     33#include <binary_compatibility/Support.h>
    3234
     35#include "ArchivingManagers.h"
     36
     37
    3338using std::string;
    3439using std::vector;
    3540
     41using namespace BPrivate::Archiving;
     42
    3643const char* B_CLASS_FIELD = "class";
    3744const char* B_ADD_ON_FIELD = "add_on";
    3845const int32 FUNC_NAME_LEN = 1024;
     
    209216
    210217BArchivable::BArchivable(BMessage* from)
    211218{
     219    if (BUnarchiver::IsArchiveManaged(from)) {
     220        BUnarchiver::PrepareArchive(from);
     221        BUnarchiver(from).RegisterArchivable(this);
     222    }
    212223}
    213224
    214225
     
    225236        return B_BAD_VALUE;
    226237    }
    227238
     239    if (BManagerBase::ArchiveManager(into))
     240        BArchiver(into).RegisterArchivable(this);
     241
    228242    BString name;
    229243    status_t status = demangle_class_name(typeid(*this).name(), name);
    230244    if (status != B_OK)
     
    245259status_t
    246260BArchivable::Perform(perform_code d, void* arg)
    247261{
    248     // TODO: Check against original
    249     return B_ERROR;
     262    switch (d) {
     263        case PERFORM_CODE_ALL_UNARCHIVED:
     264        {
     265            perform_data_all_unarchived* data =
     266                (perform_data_all_unarchived*)arg;
     267
     268            data->return_value = BArchivable::AllUnarchived(data->archive);
     269            return B_OK;
     270        }
     271           
     272        case PERFORM_CODE_ALL_ARCHIVED:
     273        {
     274            perform_data_all_archived* data =
     275                (perform_data_all_archived*)arg;
     276
     277            data->return_value = BArchivable::AllArchived(data->archive);
     278            return B_OK;
     279        }
     280    }
     281    return B_NAME_NOT_FOUND;
    250282}
    251283
    252284
    253 void BArchivable::_ReservedArchivable1() {}
    254 void BArchivable::_ReservedArchivable2() {}
    255 void BArchivable::_ReservedArchivable3() {}
     285status_t
     286BArchivable::AllUnarchived(const BMessage* archive)
     287{
     288    return B_OK;
     289}
    256290
    257291
     292status_t
     293BArchivable::AllArchived(BMessage* archive) const
     294{
     295    return B_OK;
     296}
     297
    258298// #pragma mark -
    259299
     300BArchiver::BArchiver(BMessage* archive)
     301    :
     302    fManager(BManagerBase::ArchiveManager(archive)),
     303    fArchive(archive),
     304    fFinished(false)
     305{
     306    if (!fManager)
     307        fManager = new BArchiveManager(this);
     308}
    260309
     310
     311BArchiver::~BArchiver()
     312{
     313    if (!fFinished)
     314        fManager->ArchiverLeaving(this);   
     315}
     316
     317
     318status_t
     319BArchiver::AddArchivable(const char* name, BArchivable* archivable, bool deep)
     320{
     321    int32 token;
     322    status_t err = GetTokenForArchivable(archivable, token, deep);
     323
     324    if (err != B_OK)
     325        return err;
     326
     327    return fArchive->AddInt32(name, token);
     328}
     329
     330
     331status_t
     332BArchiver::GetTokenForArchivable(BArchivable* archivable,
     333    int32& _token, bool deep)
     334{
     335    status_t err = B_OK;
     336
     337    if (!IsArchived(archivable))
     338        err = fManager->ArchiveObject(archivable, deep);
     339
     340    if (err == B_OK)
     341        return fManager->GetTokenForArchivable(archivable, _token);
     342
     343    return err;
     344}
     345
     346
     347bool
     348BArchiver::IsArchived(BArchivable* archivable)
     349{
     350    return fManager->IsArchived(archivable);
     351}
     352
     353
     354status_t
     355BArchiver::Finish()
     356{
     357    if (fFinished)
     358        debugger("Finish() called multiple times on same BArchiver.");
     359
     360    fFinished = true;
     361    return fManager->ArchiverLeaving(this);
     362}
     363
     364
     365BMessage*
     366BArchiver::ArchiveMessage() const
     367{
     368    return fArchive;
     369}
     370
     371
     372void
     373BArchiver::RegisterArchivable(const BArchivable* archivable)
     374{
     375    fManager->RegisterArchivable(archivable);
     376}
     377
     378
     379// #pragma mark -
     380
     381
     382BUnarchiver::BUnarchiver(const BMessage* archive)
     383    :
     384    fManager(BManagerBase::UnarchiveManager(archive)),
     385    fArchive(archive),
     386    fFinished(false)
     387{
     388}
     389
     390
     391BUnarchiver::~BUnarchiver()
     392{
     393    if (!fFinished && fManager)
     394        fManager->UnarchiverLeaving(this);
     395}
     396
     397
     398status_t
     399BUnarchiver::GetArchivable(int32 token, BArchivable** archivable)
     400{
     401    _CallDebuggerIfManagerNull();
     402
     403    if (archivable == NULL)
     404        return B_BAD_VALUE;
     405   
     406    return fManager->ArchivableForToken(archivable, token);
     407}
     408
     409
     410status_t
     411BUnarchiver::FindArchivable(const char* name, BArchivable** archivable)
     412{
     413    return FindArchivable(name, 0, archivable);
     414}
     415
     416
     417status_t
     418BUnarchiver::FindArchivable(const char* name,
     419    int32 index, BArchivable** archivable)
     420{
     421
     422    int32 token;
     423    status_t err = fArchive->FindInt32(name, index, &token);
     424    if (err != B_OK)
     425        return err;
     426
     427    return GetArchivable(token, archivable);
     428}
     429
     430
     431status_t
     432BUnarchiver::EnsureUnarchived(const char* name, int32 index)
     433{
     434    BArchivable* dummy;
     435    return FindArchivable(name, index, &dummy);
     436}
     437
     438
     439status_t
     440BUnarchiver::EnsureUnarchived(int32 token)
     441{
     442    BArchivable* dummy;
     443    return GetArchivable(token, &dummy);
     444}
     445
     446
     447bool
     448BUnarchiver::IsInstantiated(int32 token)
     449{
     450    return fManager->IsInstantiated(token);
     451}
     452
     453bool
     454BUnarchiver::IsInstantiated(const char* field, int32 index)
     455{
     456    int32 token;
     457    if (fArchive->FindInt32(field, index, &token) == B_OK)
     458        return IsInstantiated(token);
     459    return false;
     460}
     461
     462status_t
     463BUnarchiver::Finish()
     464{
     465    if (fFinished)
     466        debugger("Finish() called multiple times on same BArchiver.");
     467
     468    fFinished = true;
     469    return fManager->UnarchiverLeaving(this);
     470}
     471
     472
     473const BMessage*
     474BUnarchiver::ArchiveMessage() const
     475{
     476    return fArchive;
     477}
     478
     479
     480bool
     481BUnarchiver::IsArchiveManaged(BMessage* archive)
     482{
     483    // managed child archives will return here
     484    if (BManagerBase::ManagerPointer(archive))
     485        return true;
     486
     487    // managed top level archives return here
     488    int32 dummy;
     489    if (archive->FindInt32(kArchiveCountField, &dummy) == B_OK)
     490        return true;
     491
     492    return false;
     493}
     494
     495
     496BMessage*
     497BUnarchiver::PrepareArchive(BMessage*& archive)
     498{
     499    // this check allows PrepareArchive to be
     500    // called on new or old-style archives
     501    if (BUnarchiver::IsArchiveManaged(archive)) {
     502        BUnarchiveManager* manager = BManagerBase::UnarchiveManager(archive);
     503        if (!manager)
     504            manager = new BUnarchiveManager(archive);
     505        manager->Acquire();
     506    }
     507    return archive;
     508}
     509
     510
     511void
     512BUnarchiver::RegisterArchivable(BArchivable* archivable)
     513{
     514    _CallDebuggerIfManagerNull();
     515    fManager->RegisterArchivable(archivable);
     516}
     517
     518
     519void
     520BUnarchiver::_CallDebuggerIfManagerNull()
     521{
     522    if (!fManager)
     523        debugger("BUnarchiver used with legacy or unprepared archive.");
     524}
     525
     526
     527// #pragma mark -
     528
     529
    261530BArchivable*
    262531instantiate_object(BMessage* archive, image_id* _id)
    263532{
     
    475744    return find_instantiation_func(name, signature);
    476745}
    477746
     747// BArchivable binary compatability
     748#if __GNUC__ == 2
     749
     750extern "C" status_t
     751_ReservedArchivable1__11BArchivable(BArchivable* archivable,
     752    const BMessage* archive)
     753{
     754    // AllUnarchived
     755    perform_data_all_unarchived performData;
     756    performData.archive = archive;
     757
     758    archivable->Perform(PERFORM_CODE_ALL_UNARCHIVED, &performData);
     759    return performData.return_value;
     760}
     761
     762extern "C" status_t
     763_ReservedArchivable2__11BArchivable(BArchivable* archivable,
     764    const BMessage* archive)
     765{
     766    // AllArchived
     767    perform_data_all_archived performData;
     768    performData.archive = archive;
     769
     770    archivable->Perform(PERFORM_CODE_ALL_ARCHIVED, &performData);
     771    return performData.return_value;
     772}
     773
     774#elif __GNUC__ > 2
     775
     776extern "C" status_t
     777_ZN11BArchivable20_ReservedArchivable1Ev(BArchivable* archivable,
     778    const BMessage* archive)
     779{
     780    // AllUnarchived
     781    perform_data_all_unarchived performData;
     782    performData.archive = archive;
     783
     784    archivable->Perform(PERFORM_CODE_ALL_UNARCHIVED, &performData);
     785    return performData.return_value;
     786}
     787
     788extern "C" status_t
     789_ZN11BArchivable20_ReservedArchivable2Ev(BArchivable* archivable,
     790    BMessage* archive)
     791{
     792    // AllArchived
     793    perform_data_all_archived performData;
     794    performData.archive = archive;
     795
     796    archivable->Perform(PERFORM_CODE_ALL_ARCHIVED, &performData);
     797    return performData.return_value;
     798}
     799
     800#endif // _GNUC__ > 2
     801
     802void BArchivable::_ReservedArchivable3() {}
     803
     804
  • src/kits/support/ArchivingManagers.cpp

     
     1/*
     2 * Copyright (c) 2010, Haiku, Inc.
     3 * Distributed under the terms of the MIT License.
     4 *
     5 * Authors:
     6 *      Alex Wilson (yourpalal2@gmail.com)
     7 */
     8
     9
     10#include <syslog.h>
     11#include <typeinfo>
     12
     13#include "ArchivingManagers.h"
     14
     15
     16namespace BPrivate {
     17namespace Archiving {
     18    extern const char* kArchiveCountField = "_managed_archive_count";
     19    extern const char* kArchivableField = "_managed_archivable";
     20    extern const char* kTokenField = "_managed_token";
     21} }
     22
     23
     24using namespace BPrivate::Archiving;
     25
     26
     27BArchiveManager*
     28BManagerBase::ArchiveManager(const BMessage* archive)
     29{
     30    BManagerBase* manager = ManagerPointer(archive);
     31    if (!manager)
     32        return NULL;
     33   
     34    if (manager->fType == ARCHIVE_MANAGER)
     35        return static_cast<BArchiveManager*>(manager);
     36   
     37    debugger("Overlapping managed unarchive/archive sessions.");
     38    return NULL;
     39}
     40
     41
     42BUnarchiveManager*
     43BManagerBase::UnarchiveManager(const BMessage* archive)
     44{
     45    BManagerBase* manager = ManagerPointer(archive);
     46    if (!manager)
     47        return NULL;
     48   
     49    if (manager->fType == UNARCHIVE_MANAGER)
     50        return static_cast<BUnarchiveManager*>(manager);
     51   
     52    debugger("More calls to BUnarchiver::PrepareMessage()"
     53        " than BUnarchivers created.");
     54
     55    return NULL;
     56}
     57
     58
     59// #pragma mark -
     60
     61
     62struct BArchiveManager::ArchiveInfo {
     63    ArchiveInfo()
     64        :
     65        token(-1),
     66        archive(NULL)
     67    {
     68    }
     69
     70
     71    ~ArchiveInfo()
     72    {
     73        delete archive;
     74    }
     75
     76
     77    int32       token;
     78    BMessage*   archive;
     79};
     80
     81
     82BArchiveManager::BArchiveManager(const BArchiver* creator)
     83    :
     84    BManagerBase(creator->ArchiveMessage(), BManagerBase::ARCHIVE_MANAGER),
     85    fTokenMap(),
     86    fCreator(creator)
     87{
     88}
     89
     90
     91BArchiveManager::~BArchiveManager()
     92{
     93    fTopLevelArchive->AddInt32(kArchiveCountField, fTokenMap.size());
     94}
     95
     96
     97status_t
     98BArchiveManager::GetTokenForArchivable(BArchivable* archivable, int32& _token)
     99{
     100    if (!archivable) {
     101        _token = -42;
     102        return B_OK;
     103    }
     104
     105    TokenMap::iterator it = fTokenMap.find(archivable);
     106
     107    if (it == fTokenMap.end())
     108        return B_ENTRY_NOT_FOUND;
     109
     110    _token = it->second.token;
     111    return B_OK;
     112}
     113
     114status_t
     115BArchiveManager::ArchiveObject(BArchivable* archivable, bool deep)
     116{
     117    if (IsArchived(archivable)){
     118        debugger("BArchivable requested to be archived"
     119            " was previously archived.");
     120    }
     121
     122    ArchiveInfo& info = fTokenMap[archivable];
     123
     124    info.archive = new BMessage();
     125    info.token = fTokenMap.size() - 1;
     126
     127    MarkArchive(info.archive);
     128    status_t err = archivable->Archive(info.archive, deep);
     129
     130    if (err != B_OK)
     131        fTokenMap.erase(archivable);
     132            // info.archive gets deleted here
     133
     134    return err;
     135}
     136
     137
     138bool
     139BArchiveManager::IsArchived(BArchivable* archivable)
     140{
     141    if (!archivable)
     142        return true;
     143
     144    return (fTokenMap.find(archivable) != fTokenMap.end());
     145}
     146
     147
     148status_t
     149BArchiveManager::ArchiverLeaving(const BArchiver* archiver)
     150{
     151    if (archiver == fCreator) {
     152
     153        // first, we must sort the objects into the order they were archived in
     154        typedef std::pair<BMessage*, const BArchivable*> archivePair ;
     155        archivePair pairs[fTokenMap.size()];
     156
     157        for(TokenMap::iterator it = fTokenMap.begin(), end = fTokenMap.end();
     158            it != end; it++) {
     159
     160            ArchiveInfo& info = it->second;
     161            pairs[info.token].first = info.archive;
     162            pairs[info.token].second = it->first;
     163
     164            // make sure fTopLevelArchive isn't deleted
     165            if (info.archive == fTopLevelArchive)
     166                info.archive = NULL;
     167        }
     168
     169        status_t err;
     170        int32 count = fTokenMap.size();
     171        for (int32 i = 0; i < count; i++) {
     172
     173            const archivePair& pair = pairs[i];
     174            err = pair.second->AllArchived(pair.first);
     175
     176            if (err == B_OK && i > 0) {
     177                err = fTopLevelArchive->AddMessage(kArchivableField,
     178                    pair.first);
     179            }
     180
     181            if (err != B_OK) {
     182                syslog(LOG_ERR, "AllArchived failed for object of type %s.",
     183                    typeid(*pairs[i].second).name());
     184                break;
     185            }
     186        }
     187   
     188        delete this;
     189        return err;
     190    }
     191
     192    return B_OK;
     193}
     194
     195
     196void
     197BArchiveManager::RegisterArchivable(const BArchivable* archivable)
     198{
     199    if (fTokenMap.size() == 0) {
     200        ArchiveInfo& info = fTokenMap[archivable];
     201        info.archive = fTopLevelArchive;
     202        info.token = 0;
     203    }
     204}
     205
     206
     207// #pragma mark -
     208
     209
     210struct BUnarchiveManager::ArchiveInfo {
     211    ArchiveInfo()
     212        :
     213        archivable(NULL),
     214        archive()
     215    {
     216    }
     217
     218    bool
     219    operator<(const ArchiveInfo& other)
     220    {
     221        return archivable < other.archivable;
     222    }
     223
     224    BArchivable*    archivable;
     225    BMessage        archive;
     226};
     227
     228
     229// #pragma mark -
     230
     231BUnarchiveManager::BUnarchiveManager(BMessage* archive)
     232    :
     233    BManagerBase(archive, BManagerBase::UNARCHIVE_MANAGER),
     234    fObjects(NULL),
     235    fObjectCount(0),
     236    fTokenInProgress(0),
     237    fRefCount(0)
     238{
     239    archive->FindInt32(kArchiveCountField, &fObjectCount);
     240    fObjects = new ArchiveInfo[fObjectCount];
     241
     242    // fObjects[0] is a placeholder for the object that started
     243    // this unarchiving session.
     244    for (int32 i = 0; i < fObjectCount - 1; i++) {
     245        BMessage* into = &fObjects[i + 1].archive;
     246        status_t err = archive->FindMessage(kArchivableField, i, into);
     247        MarkArchive(into);
     248
     249        if (err != B_OK)
     250            syslog(LOG_ERR, "Failed to find managed archivable");
     251    }
     252}
     253
     254
     255BUnarchiveManager::~BUnarchiveManager()
     256{
     257    delete[] fObjects;
     258}
     259
     260
     261status_t
     262BUnarchiveManager::ArchivableForToken(BArchivable** _archivable, int32 token)
     263{
     264    if (!_archivable || token > fObjectCount)
     265        return B_BAD_VALUE;
     266
     267    if (token < 0) {
     268        *_archivable = NULL;
     269        return B_OK;
     270    }
     271
     272    status_t err = B_OK;
     273    if (!fObjects[token].archivable) {
     274        if (fRefCount > 0)
     275            err = _InstantiateObjectForToken(token);
     276        else {
     277            syslog(LOG_ERR, "Object requested from AllUnarchived()"
     278                " was not previously instantiated");
     279            err = B_ERROR;
     280        }
     281    }
     282
     283    *_archivable = fObjects[token].archivable;
     284    return err;
     285}
     286
     287
     288bool
     289BUnarchiveManager::IsInstantiated(int32 token)
     290{
     291    if (token < 0 || token >= fObjectCount)
     292        return false;
     293    return fObjects[token].archivable;
     294}
     295
     296
     297void
     298BUnarchiveManager::RegisterArchivable(BArchivable* archivable)
     299{
     300    if (!archivable)
     301        debugger("Cannot register NULL pointer");
     302
     303    fObjects[fTokenInProgress].archivable = archivable;
     304}
     305
     306
     307status_t
     308BUnarchiveManager::UnarchiverLeaving(const BUnarchiver* unarchiver)
     309{
     310    if (--fRefCount == 0) {
     311
     312        fRefCount = -1;
     313            // make sure we de not end up here again!
     314
     315        BArchivable* archivable = fObjects[0].archivable;
     316        status_t err = archivable->AllUnarchived(fTopLevelArchive);
     317   
     318        for (int32 i = 1; i < fObjectCount; i++) {
     319            if (err != B_OK)
     320                break;
     321
     322            archivable = fObjects[i].archivable;
     323            err = archivable->AllUnarchived(&fObjects[i].archive);
     324        }
     325
     326        if (err != B_OK) {
     327            syslog(LOG_ERR, "AllUnarchived failed for object of type %s.",
     328                typeid(*archivable).name());
     329        }
     330       
     331        delete this;
     332        return err;
     333    }
     334
     335    return B_OK;
     336}
     337
     338
     339void
     340BUnarchiveManager::Acquire()
     341{
     342    if (fRefCount >= 0)
     343        fRefCount++;
     344}
     345
     346
     347status_t
     348BUnarchiveManager::_InstantiateObjectForToken(int32 token)
     349{
     350    fTokenInProgress = token;
     351    if(!instantiate_object(&fObjects[token].archive))
     352        return B_ERROR;
     353    return B_OK;
     354}
     355
  • src/kits/support/ArchivingManagers.h

     
     1/*
     2 * Copyright 2010, Haiku, Inc. All Rights Reserved.
     3 * Distributed under the terms of the MIT License.
     4 */
     5#ifndef _ARCHIVING_MANAGERS_H
     6#define _ARCHIVING_MANAGERS_H
     7
     8
     9#include <map>
     10
     11#include <String.h>
     12#include <ObjectList.h>
     13#include <MessagePrivate.h>
     14
     15#include <Archivable.h>
     16
     17namespace BPrivate {
     18namespace Archiving {
     19
     20extern const char* kArchiveCountField;
     21extern const char* kArchivableField;
     22extern const char* kTokenField;
     23
     24class BManagerBase {
     25public:
     26    enum manager_type {
     27        ARCHIVE_MANAGER,
     28        UNARCHIVE_MANAGER
     29    };
     30
     31    BManagerBase(BMessage* topLevelArchive, manager_type type)
     32        :
     33        fTopLevelArchive(topLevelArchive),
     34        fType(type)
     35    {
     36        MarkArchive(topLevelArchive);
     37    }
     38
     39
     40    static BManagerBase*
     41    ManagerPointer(const BMessage* constArchive)
     42    {
     43        BMessage* archive = const_cast<BMessage*>(constArchive);
     44
     45        return static_cast<BManagerBase*>(
     46            BMessage::Private(archive).ArchivingPointer());
     47    }
     48
     49
     50    static void
     51    SetManagerPointer(BMessage* archive, BManagerBase* manager)
     52    {
     53        BMessage::Private(archive).SetArchivingPointer(manager);
     54    }
     55
     56
     57    void
     58    MarkArchive(BMessage* archive)
     59    {
     60        BManagerBase* manager = ManagerPointer(archive);
     61        if (manager != NULL)
     62            debugger("Overlapping managed archiving/unarchiving sessions!");
     63
     64        SetManagerPointer(archive, this);
     65    }
     66
     67
     68    void
     69    UnmarkArchive(BMessage* archive)
     70    {
     71        BManagerBase* manager = ManagerPointer(archive);
     72        if (manager == this)
     73            SetManagerPointer(archive, NULL);
     74        else
     75            debugger("Overlapping managed archiving/unarchiving sessions!");
     76    }
     77
     78
     79    static  BArchiveManager*    ArchiveManager(const BMessage* archive);
     80    static  BUnarchiveManager*  UnarchiveManager(const BMessage* archive);
     81
     82protected:
     83
     84    ~BManagerBase()
     85    {
     86        UnmarkArchive(fTopLevelArchive);
     87    }
     88            BMessage*           fTopLevelArchive;
     89            manager_type        fType;
     90};
     91
     92
     93class BArchiveManager: public BManagerBase {
     94public:
     95                        BArchiveManager(const BArchiver* creator);
     96
     97            status_t    GetTokenForArchivable(BArchivable* archivable,
     98                            int32& _token);
     99
     100            status_t    ArchiveObject(BArchivable* archivable, bool deep);
     101
     102            bool        IsArchived(BArchivable* archivable);
     103
     104            status_t    ArchiverLeaving(const BArchiver* archiver);
     105            void        Acquire();
     106            void        RegisterArchivable(const BArchivable* archivable);
     107
     108private:
     109                        ~BArchiveManager();
     110
     111            struct ArchiveInfo;
     112            typedef std::map<const BArchivable*, ArchiveInfo> TokenMap;
     113
     114            TokenMap            fTokenMap;
     115            const BArchiver*    fCreator;
     116};
     117
     118
     119
     120
     121class BUnarchiveManager: public BManagerBase {
     122public:
     123                    BUnarchiveManager(BMessage* topLevelArchive);
     124
     125    status_t        ArchivableForToken(BArchivable** archivable,
     126                        int32 token);
     127
     128    bool            IsInstantiated(int32 token);
     129
     130    void            RegisterArchivable(BArchivable* archivable);
     131    status_t        UnarchiverLeaving(const BUnarchiver* archiver);
     132    void            Acquire();
     133
     134private:
     135                    ~BUnarchiveManager();
     136    status_t        _ExtractArchiveAt(int32 index);
     137    status_t        _InstantiateObjectForToken(int32 token);
     138
     139    struct ArchiveInfo;
     140    ArchiveInfo*            fObjects;
     141    int32                   fObjectCount;
     142    int32                   fTokenInProgress;
     143    int32                   fRefCount;
     144};
     145
     146
     147} // namespace Archiving
     148} // namespace BPrivate
     149
     150#endif
  • headers/os/support/Archivable.h

     
    11/*
    2  * Copyright 2001-2007, Haiku, Inc. All Rights Reserved.
     2 * Copyright 2001-2010, Haiku, Inc. All Rights Reserved.
    33 * Distributed under the terms of the MIT License.
    44 */
    55#ifndef _ARCHIVABLE_H
     
    1212
    1313class BMessage;
    1414
     15namespace BPrivate {
     16namespace Archiving {
     17    class BArchiveManager;
     18    class BUnarchiveManager;
     19}
     20}
    1521
     22using BPrivate::Archiving::BArchiveManager;
     23using BPrivate::Archiving::BUnarchiveManager;
     24
     25
    1626class BArchivable {
    17     public:
    18         BArchivable(BMessage* from);
    19         BArchivable();
    20         virtual ~BArchivable();
     27public:
     28                            BArchivable(BMessage* from);
     29                            BArchivable();
     30    virtual                 ~BArchivable();
    2131
    22         virtual status_t Archive(BMessage* into, bool deep = true) const;
    23         static BArchivable* Instantiate(BMessage* archive);
     32    virtual status_t        Archive(BMessage* into, bool deep = true) const;
     33    static  BArchivable*    Instantiate(BMessage* archive);
    2434
    25         // Private or reserved
    26         virtual status_t Perform(perform_code d, void* arg);
     35    virtual status_t        Perform(perform_code d, void* arg);
    2736
    28     private:
    29         virtual void _ReservedArchivable1();
    30         virtual void _ReservedArchivable2();
    31         virtual void _ReservedArchivable3();
     37    virtual status_t        AllUnarchived(const BMessage* archive);
     38    virtual status_t        AllArchived(BMessage* archive) const;
    3239
    33         uint32 _reserved[2];
     40private:
     41    virtual void _ReservedArchivable3();
     42
     43    uint32 _reserved[2];
    3444};
    3545
    3646
     47class BArchiver {
     48public:
     49                            BArchiver(BMessage* archive);
     50                            ~BArchiver();
     51
     52        status_t            AddArchivable(const char* name,
     53                                BArchivable* archivable, bool deep = true);
     54
     55        status_t            GetTokenForArchivable(BArchivable* archivable,
     56                                int32& _token, bool deep = true);
     57
     58        bool                IsArchived(BArchivable* archivable);
     59        status_t            Finish();
     60        BMessage*           ArchiveMessage() const;
     61
     62private:
     63    friend class BArchivable;
     64
     65                            BArchiver(); // not defined
     66                            BArchiver(const BArchiver&); // not defined
     67
     68        void                RegisterArchivable(const BArchivable* archivable);
     69
     70        BArchiveManager*    fManager;
     71        BMessage*           fArchive;
     72        bool                fFinished;
     73};
     74
     75
     76class BUnarchiver {
     77public:
     78                                BUnarchiver(const BMessage* archive);
     79                                ~BUnarchiver();
     80
     81            status_t            GetArchivable(int32 token,
     82                                    BArchivable** archivable);
     83
     84            status_t            FindArchivable(const char* name,
     85                                    BArchivable** archivable);
     86
     87            status_t            FindArchivable(const char* name, int32 index,
     88                                    BArchivable** archivable);
     89
     90            status_t            EnsureUnarchived(const char* name,
     91                                    int32 index = 0);
     92            status_t            EnsureUnarchived(int32 token);
     93
     94            bool                IsInstantiated(int32 token);
     95            bool                IsInstantiated(const char* name,
     96                                    int32 index = 0);
     97
     98            status_t            Finish();
     99            const BMessage*     ArchiveMessage() const;
     100
     101    static  bool                IsArchiveManaged(BMessage* archive);
     102    static  BMessage*           PrepareArchive(BMessage*& archive);
     103private:
     104    friend class BArchivable;
     105
     106                                BUnarchiver(); // not defined
     107                                BUnarchiver(const BUnarchiver&); // not defined
     108
     109            void                RegisterArchivable(BArchivable* archivable);
     110
     111            void                _CallDebuggerIfManagerNull();
     112
     113            BUnarchiveManager*  fManager;
     114            const BMessage*     fArchive;
     115            bool                fFinished;
     116};
     117
     118
    37119// global functions
    38120
    39121typedef BArchivable* (*instantiation_func)(BMessage*);
    40122
    41 BArchivable* instantiate_object(BMessage *from, image_id *id);
    42 BArchivable* instantiate_object(BMessage *from);
     123BArchivable* instantiate_object(BMessage* from, image_id* id);
     124BArchivable* instantiate_object(BMessage* from);
    43125bool validate_instantiation(BMessage* from, const char* className);
    44126
    45127instantiation_func find_instantiation_func(const char* className,
  • headers/os/app/Message.h

     
    11/*
    2  * Copyright 2005-2009, Haiku Inc. All Rights Reserved.
     2 * Copyright 2005-2010, Haiku Inc. All Rights Reserved.
    33 * Distributed under the terms of the MIT License.
    44 *
    55 * Authors:
     
    320320        BMessage*       fQueueLink;
    321321            // fQueueLink is used by BMessageQueue to build a linked list
    322322
    323         uint32          fReserved[9];
     323        void*           fArchivingPointer;
    324324
     325        uint32          fReserved[8];
     326
    325327                        // deprecated
    326328                        BMessage(BMessage *message);
    327329
  • headers/private/app/MessagePrivate.h

     
    11/*
    2  * Copyright 2005-2009, Haiku Inc. All rights reserved.
     2 * Copyright 2005-2010, Haiku Inc. All rights reserved.
    33 * Distributed under the terms of the MIT License.
    44 *
    55 * Authors:
     
    191191                reply, sendTimeout, replyTimeout);
    192192        }
    193193
     194
     195        void*
     196        ArchivingPointer()
     197        {
     198            return fMessage->fArchivingPointer;
     199        }
     200
     201
     202        void
     203        SetArchivingPointer(void* pointer)
     204        {
     205            fMessage->fArchivingPointer = pointer;
     206        }
     207
    194208        // static methods
    195209
    196210        static status_t
  • src/kits/app/Message.cpp

     
    11/*
    2  * Copyright 2005-2009, Haiku Inc. All rights reserved.
     2 * Copyright 2005-2010, Haiku Inc. All rights reserved.
    33 * Distributed under the terms of the MIT License.
    44 *
    55 * Authors:
     
    333333    fOriginal = NULL;
    334334    fQueueLink = NULL;
    335335
     336    fArchivingPointer = NULL;
     337
    336338    if (initHeader)
    337339        return _InitHeader();
    338340
     
    394396    free(fData);
    395397    fData = NULL;
    396398
     399    fArchivingPointer = NULL;
     400
    397401    fFieldsAvailable = 0;
    398402    fDataAvailable = 0;
    399403
  • headers/private/binary_compatibility/Support.h

     
     1/*
     2 * Copyright 2010, Haiku, Inc.
     3 * Distributed under the terms of the MIT License.
     4 */
     5#ifndef _BINARY_COMPATIBILITY_SUPPORT_H
     6#define _BINARY_COMPATIBILITY_SUPPORT_H
     7
     8
     9#include <binary_compatibility/Global.h>
     10
     11
     12struct perform_data_all_unarchived {
     13    const BMessage* archive;
     14    status_t        return_value;
     15};
     16
     17
     18struct perform_data_all_archived {
     19    BMessage*   archive;
     20    status_t    return_value;
     21};
     22
     23#endif /* _BINARY_COMPATIBILITY_INTERFACE_H_ */
  • headers/private/binary_compatibility/Global.h

     
    2121    PERFORM_CODE_SET_LAYOUT             = 1006,
    2222    PERFORM_CODE_INVALIDATE_LAYOUT      = 1007,
    2323    PERFORM_CODE_DO_LAYOUT              = 1008,
    24     PERFORM_CODE_GET_TOOL_TIP_AT        = 1009
     24    PERFORM_CODE_GET_TOOL_TIP_AT        = 1009,
    2525
    2626    // support kit
     27
     28    PERFORM_CODE_ALL_ARCHIVED           = 1010,
     29    PERFORM_CODE_ALL_UNARCHIVED         = 1011
    2730};
    2831
    2932