Ticket #6256: archiving.3.patch

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

slightly updated patch w/ better names, a little cleaner maybe, a specialization of BUnarchiver::InstantiateObject()

  • headers/os/support/Archivable.h

     
    77
    88
    99#include <image.h>
     10#include <Message.h>
    1011#include <SupportDefs.h>
    1112
    1213
    1314class BMessage;
    1415
     16
    1517namespace BPrivate {
    1618namespace Archiving {
    1719    class BArchiveManager;
     
    3840    virtual status_t            AllArchived(BMessage* archive) const;
    3941
    4042private:
     43    friend  class BUnarchiveManager;
     44
    4145    virtual void                _ReservedArchivable3();
    4246
    43             uint32              _reserved[2];
     47            int32               fArchivingToken;
     48            uint32              _reserved;
    4449};
    4550
    4651
     
    5257            status_t            AddArchivable(const char* name,
    5358                                    BArchivable* archivable, bool deep = true);
    5459
     60    inline  status_t            GetTokenForArchivable(BArchivable* archivable,
     61                                    int32& _token);
    5562            status_t            GetTokenForArchivable(BArchivable* archivable,
    56                                     int32& _token, bool deep = true);
     63                                    bool deep, int32& _token);
    5764
    5865            bool                IsArchived(BArchivable* archivable);
    59             status_t            Finish();
     66            status_t            Finish(status_t err = B_OK);
    6067            BMessage*           ArchiveMessage() const;
    6168
    6269private:
     
    7178            BArchiveManager*    fManager;
    7279            BMessage*           fArchive;
    7380            bool                fFinished;
     81            uint32              _reserved[2];
    7482};
    7583
    7684
    7785class BUnarchiver {
    7886public:
     87    enum ownership_policy {
     88        B_ASSUME_OWNERSHIP,
     89        B_DONT_ASSUME_OWNERSHIP
     90    };
    7991                                BUnarchiver(const BMessage* archive);
    8092                                ~BUnarchiver();
    8193
    82             status_t            GetArchivable(int32 token,
    83                                     BArchivable** archivable);
     94    template<class T>
     95    inline  status_t            GetObject(int32 token, T*& object);
    8496
    85             status_t            FindArchivable(const char* name,
    86                                     BArchivable** archivable);
     97    template<class T>
     98            status_t            GetObject(int32 token, ownership_policy owning,
     99                                    T*& object);
    87100
    88             status_t            FindArchivable(const char* name, int32 index,
    89                                     BArchivable** archivable);
     101    template<class T>
     102    inline  status_t            FindObject(const char* name, T*& object);
    90103
    91             status_t            EnsureUnarchived(const char* name,
     104    template<class T>
     105    inline  status_t            FindObject(const char* name,
     106                                    ownership_policy owning,
     107                                    T*& object);
     108
     109    template<class T>
     110    inline  status_t            FindObject(const char* name,
     111                                    int32 index, T*& object);
     112
     113    template<class T>
     114            status_t            FindObject(const char* name, int32 index,
     115                                    ownership_policy owning, T*& object);
     116
     117    inline  status_t            EnsureUnarchived(const char* name,
    92118                                    int32 index = 0);
    93             status_t            EnsureUnarchived(int32 token);
     119    inline  status_t            EnsureUnarchived(int32 token);
    94120
    95121            bool                IsInstantiated(int32 token);
    96122            bool                IsInstantiated(const char* name,
    97123                                    int32 index = 0);
    98124
    99             status_t            Finish();
     125            status_t            Finish(status_t err = B_OK);
    100126            const BMessage*     ArchiveMessage() const;
    101127
     128            void                AssumeOwnership(BArchivable* archivable);
     129            void                RelinquishOwnership(BArchivable* archivable);
     130
    102131    static  bool                IsArchiveManaged(BMessage* archive);
    103132    static  BMessage*           PrepareArchive(BMessage*& archive);
    104133
     134    template<class T>
     135    static  status_t            InstantiateObject(BMessage* archive,
     136                                    T*& object);
     137
    105138private:
    106139    friend class BArchivable;
    107140
     
    110143
    111144            void                RegisterArchivable(BArchivable* archivable);
    112145
    113             void                _CallDebuggerIfManagerNull();
     146    inline  void                _CallDebuggerIfManagerNull();
    114147
    115148            BUnarchiveManager*  fManager;
    116149            const BMessage*     fArchive;
    117150            bool                fFinished;
     151            uint32              _reserved[2];
    118152};
    119153
    120154
     
    131165instantiation_func find_instantiation_func(const char* className);
    132166instantiation_func find_instantiation_func(BMessage* archive);
    133167
     168
     169status_t
     170BArchiver::GetTokenForArchivable(BArchivable* archivable, int32& _token)
     171{
     172    return GetTokenForArchivable(archivable, true, _token);
     173}
     174
     175
     176template<>
     177status_t BUnarchiver::FindObject<BArchivable>(const char* name, int32 index,
     178    ownership_policy owning, BArchivable*& archivable);
     179
     180
     181template<class T>
     182status_t
     183BUnarchiver::FindObject(const char* name, int32 index,
     184    ownership_policy owning, T*& object)
     185{
     186    object = NULL;
     187
     188    BArchivable* interim;
     189    status_t err = FindObject(name, index, owning, interim);
     190
     191    if (err == B_OK && interim) {
     192        object = dynamic_cast<T*>(interim);
     193        if (!object) {
     194            err = B_BAD_TYPE;   
     195            // we will not be deleting this item, but it must be deleted
     196            if (owning == B_ASSUME_OWNERSHIP)
     197                RelinquishOwnership(interim);
     198        }
     199    }
     200    return err;
     201}
     202
     203
     204template<>
     205status_t
     206BUnarchiver::GetObject<BArchivable>(int32 token,
     207    ownership_policy owning, BArchivable*& object);
     208
     209
     210template<class T>
     211status_t
     212BUnarchiver::GetObject(int32 token, ownership_policy owning, T*& object)
     213{
     214    object = NULL;
     215
     216    BArchivable* interim;
     217    status_t err = GetObject(token, owning, interim);
     218
     219    if (err == B_OK && interim) {
     220        object = dynamic_cast<T*>(interim);
     221        if (!object) {
     222            err = B_BAD_TYPE;   
     223            // we will not be deleting this item, but it must be deleted
     224            if (owning == B_ASSUME_OWNERSHIP)
     225                RelinquishOwnership(interim);
     226        }
     227    }
     228    return err;
     229}
     230
     231
     232template<class T>
     233status_t
     234BUnarchiver::GetObject(int32 token, T*& object)
     235{
     236    return GetObject<T>(token, B_ASSUME_OWNERSHIP, object);
     237}
     238
     239
     240template<class T>
     241status_t
     242BUnarchiver::FindObject(const char* name, ownership_policy owning, T*& object)
     243{
     244    return FindObject(name, 0, owning, object);
     245}
     246
     247
     248template<class T>
     249status_t
     250BUnarchiver::FindObject(const char* name, T*& object)
     251{
     252    return FindObject<T>(name, 0, B_ASSUME_OWNERSHIP, object);
     253}
     254
     255
     256template<class T>
     257status_t
     258BUnarchiver::FindObject(const char* name,
     259    int32 index, T*& object)
     260{
     261    return FindObject(name, index, B_ASSUME_OWNERSHIP, object);
     262}
     263
     264
     265status_t
     266BUnarchiver::EnsureUnarchived(int32 token)
     267{
     268    BArchivable* dummy;
     269    return GetObject(token, B_DONT_ASSUME_OWNERSHIP, dummy);
     270}
     271
     272
     273status_t
     274BUnarchiver::EnsureUnarchived(const char* name, int32 index)
     275{
     276    BArchivable* dummy;
     277    return FindObject(name, index, B_DONT_ASSUME_OWNERSHIP, dummy);
     278}
     279
     280
     281template<>
     282status_t
     283BUnarchiver::InstantiateObject<BArchivable>(BMessage* from,
     284    BArchivable*& object);
     285
     286
     287template<class T>
     288status_t
     289BUnarchiver::InstantiateObject(BMessage* archive, T*& object)
     290{
     291    object = NULL;
     292    BArchivable* interim;
     293    status_t err = InstantiateObject(archive, interim);
     294    if (err == B_OK && interim) {
     295        object = dynamic_cast<T*>(interim);
     296        if (!object)
     297            err = B_BAD_TYPE;
     298    }
     299
     300    if (err != B_OK)
     301        delete interim;
     302
     303    return err;
     304}
     305
     306
    134307#endif  // _ARCHIVABLE_H
  • headers/private/binary_compatibility/Support.h

     
    22 * Copyright 2010, Haiku, Inc.
    33 * Distributed under the terms of the MIT License.
    44 */
    5 #ifndef _BINARY_COMPATIBILITY_SUPPORT_H
    6 #define _BINARY_COMPATIBILITY_SUPPORT_H
     5#ifndef _BINARY_COMPATIBILITY_SUPPORT_H_
     6#define _BINARY_COMPATIBILITY_SUPPORT_H_
    77
    88
    99#include <binary_compatibility/Global.h>
     
    2020    status_t    return_value;
    2121};
    2222
    23 #endif /* _BINARY_COMPATIBILITY_INTERFACE_H_ */
     23#endif /* _BINARY_COMPATIBILITY_SUPPORT_H_ */
  • src/kits/support/Archivable.cpp

     
    210210
    211211
    212212BArchivable::BArchivable()
     213    :
     214    fArchivingToken(NULL_TOKEN)
    213215{
    214216}
    215217
    216218
    217219BArchivable::BArchivable(BMessage* from)
     220    :
     221    fArchivingToken(NULL_TOKEN)
    218222{
    219223    if (BUnarchiver::IsArchiveManaged(from)) {
    220224        BUnarchiver::PrepareArchive(from);
     
    313317BArchiver::~BArchiver()
    314318{
    315319    if (!fFinished)
    316         fManager->ArchiverLeaving(this);
     320        fManager->ArchiverLeaving(this, B_OK);
    317321}
    318322
    319323
     
    321325BArchiver::AddArchivable(const char* name, BArchivable* archivable, bool deep)
    322326{
    323327    int32 token;
    324     status_t err = GetTokenForArchivable(archivable, token, deep);
     328    status_t err = GetTokenForArchivable(archivable, deep, token);
    325329
    326330    if (err != B_OK)
    327331        return err;
     
    332336
    333337status_t
    334338BArchiver::GetTokenForArchivable(BArchivable* archivable,
    335     int32& _token, bool deep)
     339    bool deep, int32& _token)
    336340{
    337     status_t err = B_OK;
    338 
    339     if (!IsArchived(archivable))
    340         err = fManager->ArchiveObject(archivable, deep);
    341 
    342     if (err == B_OK)
    343         return fManager->GetTokenForArchivable(archivable, _token);
    344 
    345     return err;
     341    return fManager->ArchiveObject(archivable, deep, _token);
    346342}
    347343
    348344
     
    354350
    355351
    356352status_t
    357 BArchiver::Finish()
     353BArchiver::Finish(status_t err)
    358354{
    359355    if (fFinished)
    360356        debugger("Finish() called multiple times on same BArchiver.");
    361357
    362358    fFinished = true;
    363     return fManager->ArchiverLeaving(this);
     359
     360    return fManager->ArchiverLeaving(this, err);
    364361}
    365362
    366363
     
    393390BUnarchiver::~BUnarchiver()
    394391{
    395392    if (!fFinished && fManager)
    396         fManager->UnarchiverLeaving(this);
     393        fManager->UnarchiverLeaving(this, B_OK);
    397394}
    398395
    399396
     397template<>
    400398status_t
    401 BUnarchiver::GetArchivable(int32 token, BArchivable** archivable)
     399BUnarchiver::GetObject<BArchivable>(int32 token,
     400    ownership_policy owning, BArchivable*& object)
    402401{
    403402    _CallDebuggerIfManagerNull();
    404 
    405     if (archivable == NULL)
    406         return B_BAD_VALUE;
    407 
    408     return fManager->ArchivableForToken(archivable, token);
     403    return fManager->GetArchivableForToken(token, owning, object);
    409404}
    410405
    411406
     407template<>
    412408status_t
    413 BUnarchiver::FindArchivable(const char* name, BArchivable** archivable)
     409BUnarchiver::FindObject<BArchivable>(const char* name,
     410    int32 index, ownership_policy owning, BArchivable*& archivable)
    414411{
    415     return FindArchivable(name, 0, archivable);
    416 }
    417 
    418 
    419 status_t
    420 BUnarchiver::FindArchivable(const char* name,
    421     int32 index, BArchivable** archivable)
    422 {
    423 
     412    archivable = NULL;
    424413    int32 token;
    425414    status_t err = fArchive->FindInt32(name, index, &token);
    426415    if (err != B_OK)
    427416        return err;
    428417
    429     return GetArchivable(token, archivable);
     418    return GetObject(token, owning, archivable);
    430419}
    431420
    432421
    433 status_t
    434 BUnarchiver::EnsureUnarchived(const char* name, int32 index)
    435 {
    436     BArchivable* dummy;
    437     return FindArchivable(name, index, &dummy);
    438 }
    439 
    440 
    441 status_t
    442 BUnarchiver::EnsureUnarchived(int32 token)
    443 {
    444     BArchivable* dummy;
    445     return GetArchivable(token, &dummy);
    446 }
    447 
    448 
    449422bool
    450423BUnarchiver::IsInstantiated(int32 token)
    451424{
    452425    return fManager->IsInstantiated(token);
    453426}
    454427
     428
    455429bool
    456430BUnarchiver::IsInstantiated(const char* field, int32 index)
    457431{
     
    461435    return false;
    462436}
    463437
     438
    464439status_t
    465 BUnarchiver::Finish()
     440BUnarchiver::Finish(status_t err)
    466441{
    467442    if (fFinished)
    468443        debugger("Finish() called multiple times on same BArchiver.");
    469444
    470445    fFinished = true;
    471     return fManager->UnarchiverLeaving(this);
     446    if (fManager)
     447        return fManager->UnarchiverLeaving(this, err);
     448    else
     449        return B_OK;
    472450}
    473451
    474452
     
    479457}
    480458
    481459
     460void
     461BUnarchiver::AssumeOwnership(BArchivable* archivable)
     462{
     463    _CallDebuggerIfManagerNull();
     464    fManager->AssumeOwnership(archivable);
     465}
     466
     467
     468void
     469BUnarchiver::RelinquishOwnership(BArchivable* archivable)
     470{
     471    _CallDebuggerIfManagerNull();
     472    fManager->RelinquishOwnership(archivable);
     473}
     474
     475
    482476bool
    483477BUnarchiver::IsArchiveManaged(BMessage* archive)
    484478{
     
    487481        return true;
    488482
    489483    // managed top level archives return here
    490     int32 dummy;
    491     if (archive->FindInt32(kArchiveCountField, &dummy) == B_OK)
     484    bool dummy;
     485    if (archive->FindBool(kManagedField, &dummy) == B_OK)
    492486        return true;
    493487
    494488    return false;
    495489}
    496490
    497491
     492template<>
     493status_t
     494BUnarchiver::InstantiateObject<BArchivable>(BMessage* from,
     495    BArchivable*& object)
     496{
     497    BUnarchiver unarchiver(BUnarchiver::PrepareArchive(from));
     498    object = instantiate_object(from);
     499    return unarchiver.Finish();
     500}
     501
     502
    498503BMessage*
    499504BUnarchiver::PrepareArchive(BMessage*& archive)
    500505{
  • src/kits/support/ArchivingManagers.cpp

     
    66 *      Alex Wilson (yourpalal2@gmail.com)
    77 */
    88
     9#include "ArchivingManagers.h"
    910
    1011#include <syslog.h>
    1112#include <typeinfo>
    1213
    13 #include "ArchivingManagers.h"
    1414
    15 
    1615namespace BPrivate {
    1716namespace Archiving {
    18     const char* kArchiveCountField = "_managed_archive_count";
    1917    const char* kArchivableField = "_managed_archivable";
    20     const char* kTokenField = "_managed_token";
     18    const char* kManagedField = "_managed_archive";
    2119}
    2220}
    2321
     
    5048    if (manager->fType == UNARCHIVE_MANAGER)
    5149        return static_cast<BUnarchiveManager*>(manager);
    5250
    53     debugger("More calls to BUnarchiver::PrepareMessage()"
     51    debugger("More calls to BUnarchiver::PrepareArchive()"
    5452        " than BUnarchivers created.");
    5553
    5654    return NULL;
     
    8482    :
    8583    BManagerBase(creator->ArchiveMessage(), BManagerBase::ARCHIVE_MANAGER),
    8684    fTokenMap(),
    87     fCreator(creator)
     85    fCreator(creator),
     86    fError(B_OK)
    8887{
    8988}
    9089
    9190
    9291BArchiveManager::~BArchiveManager()
    9392{
    94     fTopLevelArchive->AddInt32(kArchiveCountField, fTokenMap.size());
     93    fTopLevelArchive->AddBool(kManagedField, true);
    9594}
    9695
    9796
     
    9998BArchiveManager::GetTokenForArchivable(BArchivable* archivable, int32& _token)
    10099{
    101100    if (!archivable) {
    102         _token = -42;
     101        _token = NULL_TOKEN;
    103102        return B_OK;
    104103    }
    105104
     
    114113
    115114
    116115status_t
    117 BArchiveManager::ArchiveObject(BArchivable* archivable, bool deep)
     116BArchiveManager::ArchiveObject(BArchivable* archivable,
     117    bool deep, int32& _token)
    118118{
    119     if (IsArchived(archivable)){
    120         debugger("BArchivable requested to be archived"
    121             " was previously archived.");
     119    if (!archivable) {
     120        _token = NULL_TOKEN;
     121        return B_OK;
    122122    }
    123123
    124124    ArchiveInfo& info = fTokenMap[archivable];
    125125
    126     info.archive = new BMessage();
    127     info.token = fTokenMap.size() - 1;
     126    status_t err = B_OK;
    128127
    129     MarkArchive(info.archive);
    130     status_t err = archivable->Archive(info.archive, deep);
     128    if (!info.archive) {
     129        info.archive = new BMessage();
     130        info.token = fTokenMap.size() - 1;
     131   
     132        MarkArchive(info.archive);
     133        err = archivable->Archive(info.archive, deep);
     134    }
    131135
    132136    if (err != B_OK) {
    133137        fTokenMap.erase(archivable);
    134138            // info.archive gets deleted here
    135     }
     139        _token = NULL_TOKEN;
     140    } else
     141        _token = info.token;
    136142
    137143    return err;
    138144}
     
    149155
    150156
    151157status_t
    152 BArchiveManager::ArchiverLeaving(const BArchiver* archiver)
     158BArchiveManager::ArchiverLeaving(const BArchiver* archiver, status_t err)
    153159{
    154     if (archiver == fCreator) {
     160    if (fError == B_OK)
     161        fError = err;
     162
     163    if (archiver == fCreator && fError == B_OK) {
    155164        // first, we must sort the objects into the order they were archived in
    156165        typedef std::pair<BMessage*, const BArchivable*> ArchivePair;
    157166        ArchivePair pairs[fTokenMap.size()];
     
    167176                info.archive = NULL;
    168177        }
    169178
    170         status_t err = B_ERROR;
    171179        int32 count = fTokenMap.size();
    172180        for (int32 i = 0; i < count; i++) {
    173181            const ArchivePair& pair = pairs[i];
    174             err = pair.second->AllArchived(pair.first);
     182            fError = pair.second->AllArchived(pair.first);
    175183
    176             if (err == B_OK && i > 0) {
    177                 err = fTopLevelArchive->AddMessage(kArchivableField,
     184            if (fError == B_OK && i > 0) {
     185                fError = fTopLevelArchive->AddMessage(kArchivableField,
    178186                    pair.first);
    179187            }
    180188
    181             if (err != B_OK) {
     189            if (fError != B_OK) {
    182190                syslog(LOG_ERR, "AllArchived failed for object of type %s.",
    183191                    typeid(*pairs[i].second).name());
    184192                break;
    185193            }
    186194        }
    187 
     195    }
     196   
     197    if (archiver == fCreator)   
    188198        delete this;
    189         return err;
    190     }
    191199
    192     return B_OK;
     200    return fError;
    193201}
    194202
    195203
     
    211219    ArchiveInfo()
    212220        :
    213221        archivable(NULL),
    214         archive()
     222        archive(),
     223        adopted(false)
    215224    {
    216225    }
    217226
     
    223232
    224233    BArchivable*    archivable;
    225234    BMessage        archive;
     235    bool            adopted;
    226236};
    227237
    228238
     
    235245    fObjects(NULL),
    236246    fObjectCount(0),
    237247    fTokenInProgress(0),
    238     fRefCount(0)
     248    fRefCount(0),
     249    fError(B_OK)
    239250{
    240     archive->FindInt32(kArchiveCountField, &fObjectCount);
     251    archive->GetInfo(kArchivableField, NULL, &fObjectCount);
     252    fObjectCount++;
     253        // root object needs a spot too
    241254    fObjects = new ArchiveInfo[fObjectCount];
    242255
    243256    // fObjects[0] is a placeholder for the object that started
     
    260273
    261274
    262275status_t
    263 BUnarchiveManager::ArchivableForToken(BArchivable** _archivable, int32 token)
     276BUnarchiveManager::GetArchivableForToken(int32 token,
     277    BUnarchiver::ownership_policy owning, BArchivable*& _archivable)
    264278{
    265     if (!_archivable || token > fObjectCount)
     279    if (token > fObjectCount)
    266280        return B_BAD_VALUE;
    267281
    268282    if (token < 0) {
    269         *_archivable = NULL;
     283        _archivable = NULL;
    270284        return B_OK;
    271285    }
    272286
    273287    status_t err = B_OK;
    274     if (!fObjects[token].archivable) {
    275         if (fRefCount > 0)
    276             err = _InstantiateObjectForToken(token);
    277         else {
     288    ArchiveInfo& info = fObjects[token];
     289    if (!info.archivable) {
     290        if (fRefCount > 0) {
     291            fTokenInProgress = token;
     292            if(!instantiate_object(&info.archive))
     293                err = B_ERROR;
     294        } else {
    278295            syslog(LOG_ERR, "Object requested from AllUnarchived()"
    279296                " was not previously instantiated");
    280297            err = B_ERROR;
    281298        }
    282299    }
    283300
    284     *_archivable = fObjects[token].archivable;
     301    if (!info.adopted && owning == BUnarchiver::B_ASSUME_OWNERSHIP)
     302        info.adopted = true;
     303    else if (info.adopted && owning == BUnarchiver::B_ASSUME_OWNERSHIP)
     304        debugger("Cannot assume ownership of an object that is already owned");
     305
     306    _archivable = info.archivable;
    285307    return err;
    286308}
    287309
     
    302324        debugger("Cannot register NULL pointer");
    303325
    304326    fObjects[fTokenInProgress].archivable = archivable;
     327    archivable->fArchivingToken = fTokenInProgress;
    305328}
    306329
    307330
    308331status_t
    309 BUnarchiveManager::UnarchiverLeaving(const BUnarchiver* unarchiver)
     332BUnarchiveManager::UnarchiverLeaving(const BUnarchiver* unarchiver,
     333    status_t err)
    310334{
    311     if (--fRefCount == 0) {
    312         fRefCount = -1;
    313             // make sure we de not end up here again!
     335    if (--fRefCount >= 0 && fError == B_OK)
     336        fError = err;
    314337
     338    if (fRefCount != 0)
     339        return fError;
     340
     341    if (fError == B_OK) {
    315342        BArchivable* archivable = fObjects[0].archivable;
    316         status_t err = archivable->AllUnarchived(fTopLevelArchive);
     343        if (archivable) {
     344            fError = archivable->AllUnarchived(fTopLevelArchive);
     345            archivable->fArchivingToken = NULL_TOKEN;
     346        }
    317347
    318         for (int32 i = 1; i < fObjectCount; i++) {
    319             if (err != B_OK)
    320                 break;
    321 
     348        for (int32 i = 1; i < fObjectCount && fError == B_OK; i++) {
    322349            archivable = fObjects[i].archivable;
    323             err = archivable->AllUnarchived(&fObjects[i].archive);
     350            if (archivable) {
     351                fError = archivable->AllUnarchived(&fObjects[i].archive);
     352                archivable->fArchivingToken = NULL_TOKEN;
     353            }
    324354        }
     355        if (fError != B_OK) {
     356            syslog(LOG_ERR, "Error in AllUnarchived"
     357                " method of object of type %s", typeid(*archivable).name());
     358        }
     359    }
    325360
    326         if (err != B_OK) {
    327             syslog(LOG_ERR, "AllUnarchived failed for object of type %s.",
    328                 typeid(*archivable).name());
     361    if (fError != B_OK) {
     362        syslog(LOG_ERR, "An error occured during unarchival, cleaning up.");
     363        for (int32 i = 1; i < fObjectCount; i++) {
     364            if (!fObjects[i].adopted)
     365                delete fObjects[i].archivable;
    329366        }
    330 
    331         delete this;
    332         return err;
    333367    }
    334368
    335     return B_OK;
     369    delete this;
     370    return fError;
    336371}
    337372
    338373
    339374void
    340 BUnarchiveManager::Acquire()
     375BUnarchiveManager::RelinquishOwnership(BArchivable* archivable)
    341376{
    342     if (fRefCount >= 0)
    343         fRefCount++;
     377    int32 token = NULL_TOKEN;
     378    if (archivable)
     379        token = archivable->fArchivingToken;
     380
     381    if (token < 0 || token >= fObjectCount
     382        || fObjects[token].archivable != archivable)
     383        return;
     384
     385    fObjects[token].adopted = false;
    344386}
    345387
    346388
    347 status_t
    348 BUnarchiveManager::_InstantiateObjectForToken(int32 token)
     389void
     390BUnarchiveManager::AssumeOwnership(BArchivable* archivable)
    349391{
    350     fTokenInProgress = token;
    351     if(!instantiate_object(&fObjects[token].archive))
    352         return B_ERROR;
    353     return B_OK;
     392    int32 token = NULL_TOKEN;
     393    if (archivable)
     394        token = archivable->fArchivingToken;
     395
     396    if (token < 0 || token >= fObjectCount
     397        || fObjects[token].archivable != archivable)
     398        return;
     399
     400    if (!fObjects[token].adopted)
     401        fObjects[token].adopted = true;
     402    else {
     403        debugger("Cannot assume ownership of an object that is already owned");
     404    }
    354405}
    355406
     407
     408void
     409BUnarchiveManager::Acquire()
     410{
     411    if (fRefCount >= 0)
     412        fRefCount++;
     413}
  • src/kits/support/ArchivingManagers.h

     
    1515#include <Archivable.h>
    1616
    1717
     18#define NULL_TOKEN -42
     19
     20
    1821namespace BPrivate {
    1922namespace Archiving {
    2023
    21 extern const char* kArchiveCountField;
    22 extern const char* kArchivableField;
    23 extern const char* kTokenField;
     24extern const char* kManagedField;
    2425
    2526
    2627class BManagerBase {
     
    101102                                    int32& _token);
    102103
    103104            status_t            ArchiveObject(BArchivable* archivable,
    104                                     bool deep);
     105                                    bool deep, int32& _token);
    105106
    106107            bool                IsArchived(BArchivable* archivable);
    107108
    108             status_t            ArchiverLeaving(const BArchiver* archiver);
     109            status_t            ArchiverLeaving(const BArchiver* archiver,
     110                                    status_t err);
     111
    109112            void                Acquire();
    110113            void                RegisterArchivable(
    111114                                    const BArchivable* archivable);
     
    118121
    119122            TokenMap            fTokenMap;
    120123            const BArchiver*    fCreator;
     124            status_t            fError;
    121125};
    122126
    123127
     
    127131public:
    128132                                BUnarchiveManager(BMessage* topLevelArchive);
    129133
    130             status_t            ArchivableForToken(BArchivable** archivable,
    131                                     int32 token);
     134            status_t            GetArchivableForToken(int32 token,
     135                                    BUnarchiver::ownership_policy owning,
     136                                    BArchivable*& _archivable);
    132137
    133138            bool                IsInstantiated(int32 token);
    134139
    135140            void                RegisterArchivable(BArchivable* archivable);
    136             status_t            UnarchiverLeaving(const BUnarchiver* archiver);
     141            status_t            UnarchiverLeaving(const BUnarchiver* archiver,
     142                                    status_t err);
    137143            void                Acquire();
    138144
     145            void                RelinquishOwnership(BArchivable* archivable);
     146            void                AssumeOwnership(BArchivable* archivable);
    139147private:
    140148                                ~BUnarchiveManager();
    141149
    142150            status_t            _ExtractArchiveAt(int32 index);
    143             status_t            _InstantiateObjectForToken(int32 token);
    144151
    145152            struct ArchiveInfo;
    146153
     
    148155            int32               fObjectCount;
    149156            int32               fTokenInProgress;
    150157            int32               fRefCount;
     158            status_t            fError;
    151159};
    152160
    153161
  • src/kits/interface/Layout.cpp

     
    77
    88#include <Layout.h>
    99
     10#include <syslog.h>
    1011#include <new>
    1112
    1213#include <Message.h>
     
    1920
    2021namespace {
    2122    const char* kLayoutItemField = "BLayout:_items";
    22     const char* kLayoutDataField = "BLayout:_data";
    2323}
    2424
    2525
    26 // constructor
    2726BLayout::BLayout()
    2827    :
    2928    fView(NULL),
     
    211210    BArchiver archiver(into);
    212211    status_t err = BArchivable::Archive(into, deep);
    213212
    214     if (err != B_OK)
    215         return err;
    216    
    217213    if (deep) {
    218214        int32 count = CountItems();
    219         for (int32 i = 0; i < count; i++) {
    220             err = archiver.AddArchivable(kLayoutItemField, ItemAt(i), deep);
     215        for (int32 i = 0; i < count && err == B_OK; i++) {
     216            BLayoutItem* item = ItemAt(i);
     217            err = archiver.AddArchivable(kLayoutItemField, item, deep);
    221218
    222219            if (err == B_OK) {
    223                 BMessage data;
    224                 err = ArchiveLayoutData(&data, ItemAt(i));
    225                 if (err == B_OK)
    226                     err = into->AddMessage(kLayoutDataField, &data);
     220                err = ItemArchived(into, item, i);
     221                if (err != B_OK)
     222                    syslog(LOG_ERR, "ItemArchived() failed at index: %d.", i);
    227223            }
    228 
    229             if (err != B_OK)
    230                 return err;
    231224        }
    232225    }
    233226
    234     return archiver.Finish();
     227    return archiver.Finish(err);
    235228}
    236229
    237230
    238231status_t
    239232BLayout::AllUnarchived(const BMessage* from)
    240233{
    241     status_t err = BArchivable::AllUnarchived(from);
    242234    BUnarchiver unarchiver(from);
     235    status_t err = BArchivable::AllUnarchived(from);
    243236
    244237    if (err != B_OK)
    245238        return err;
    246239
    247     for (int32 i = 0; ; i++) {
    248         BArchivable* retriever;
    249         err = unarchiver.FindArchivable(kLayoutItemField, i, &retriever);
     240    int32 itemCount;
     241    unarchiver.ArchiveMessage()->GetInfo(kLayoutItemField, NULL, &itemCount);
     242    for (int32 i = 0; i < itemCount && err == B_OK; i++) {
     243        BLayoutItem* item;
     244        err = unarchiver.FindObject(kLayoutItemField, i, item);
    250245
    251         if (err == B_BAD_INDEX)
    252             break;
    253 
    254         if (err == B_OK) {
    255             BMessage layoutData;
    256             err = from->FindMessage(kLayoutDataField, i, &layoutData);
    257 
    258             if (err == B_OK) {
    259                 BLayoutItem* item = dynamic_cast<BLayoutItem*>(retriever);
    260                 err = RestoreItemAndData(&layoutData, item);
    261             }
     246        if (err == B_OK && item) {
     247            if (fItems.AddItem(item)) {
     248                ItemAdded(item);
     249                item->SetLayout(this);
     250                err = ItemUnarchived(from, item, i);
     251            } else
     252                err = B_NO_MEMORY;
    262253        }
    263 
    264         if (err != B_OK)
    265             return err;
    266254    }
    267255
    268     return B_OK;
     256    return err;
    269257}
    270258
    271259
    272260status_t
    273 BLayout::ArchiveLayoutData(BMessage* into, const BLayoutItem* of) const
     261BLayout::ItemArchived(BMessage* into, BLayoutItem* of, int32 index) const
    274262{
    275263    return B_OK;
    276264}
    277265
    278266
    279267status_t
    280 BLayout::RestoreItemAndData(const BMessage* from, BLayoutItem* item)
     268BLayout::ItemUnarchived(const BMessage* from, BLayoutItem* item, int32 index)
    281269{
    282     if (item && AddItem(item))
    283         return B_OK;
    284     return B_ERROR;
     270    return B_OK;
    285271}
    286272
    287273
  • headers/os/interface/Layout.h

     
    5454
    5555    virtual status_t            Archive(BMessage* into, bool deep = true) const;
    5656    virtual status_t            AllUnarchived(const BMessage* from);
    57     virtual status_t            ArchiveLayoutData(BMessage* into,
    58                                     const BLayoutItem* of) const;
    59     virtual status_t            RestoreItemAndData(const BMessage* from,
    60                                     BLayoutItem* item);
    6157
     58    virtual status_t            ItemArchived(BMessage* into, BLayoutItem* item,
     59                                    int32 index) const;
     60    virtual status_t            ItemUnarchived(const BMessage* from,
     61                                    BLayoutItem* item, int32 index);
    6262protected:
    6363// TODO: Since memory allocations can fail, we should return a bool and
    6464// undo the addition, if false.
  • headers/private/binary_compatibility/Global.h

     
    44 * Distributed under the terms of the MIT License.
    55 */
    66#ifndef _BINARY_COMPATIBILITY_GLOBAL_H_
    7 #define _BINARY_COMPATIBILITY__GLOBAL_H_
     7#define _BINARY_COMPATIBILITY_GLOBAL_H_
    88
    99
    1010// method codes
     
    2424    PERFORM_CODE_GET_TOOL_TIP_AT        = 1009,
    2525
    2626    // support kit
    27 
    2827    PERFORM_CODE_ALL_ARCHIVED           = 1010,
    2928    PERFORM_CODE_ALL_UNARCHIVED         = 1011
    3029};