Ticket #6256: archiving.2.patch

File archiving.2.patch, 26.0 KB (added by yourpalal, 11 years ago)

Update to provide new template methods, better error handling, fix binary compatibility stuff, cleanup & refactor some code... probably more, also update Layout stuff to use the new methods provided & for a better archiving/unarchiving system.

  • headers/os/support/Archivable.h

     
    77
    88
    99#include <image.h>
     10#include <Message.h>
    1011#include <SupportDefs.h>
    1112
    1213
     14#define NULL_TOKEN -42
     15
    1316class BMessage;
    1417
    1518namespace BPrivate {
     
    3841    virtual status_t            AllArchived(BMessage* archive) const;
    3942
    4043private:
     44    friend  class BUnarchiveManager;
     45
    4146    virtual void                _ReservedArchivable3();
    4247
    43             uint32              _reserved[2];
     48            int32               fArchivingToken;
     49            uint32              _reserved;
    4450};
    4551
    4652
     
    5258            status_t            AddArchivable(const char* name,
    5359                                    BArchivable* archivable, bool deep = true);
    5460
     61    inline  status_t            GetTokenForArchivable(BArchivable* archivable,
     62                                    int32& _token);
    5563            status_t            GetTokenForArchivable(BArchivable* archivable,
    56                                     int32& _token, bool deep = true);
     64                                    bool deep, int32& _token);
    5765
    5866            bool                IsArchived(BArchivable* archivable);
    59             status_t            Finish();
     67            status_t            Finish(status_t err = B_OK);
    6068            BMessage*           ArchiveMessage() const;
    6169
    6270private:
     
    7179            BArchiveManager*    fManager;
    7280            BMessage*           fArchive;
    7381            bool                fFinished;
     82            uint32              _reserved[2];
    7483};
    7584
    7685
     
    7988                                BUnarchiver(const BMessage* archive);
    8089                                ~BUnarchiver();
    8190
    82             status_t            GetArchivable(int32 token,
    83                                     BArchivable** archivable);
     91    template<class T>
     92    inline  status_t            GetObject(int32 token, T*& object);
    8493
    85             status_t            FindArchivable(const char* name,
    86                                     BArchivable** archivable);
     94    template<class T>
     95            status_t            GetObject(int32 token, ownership owning,
     96                                    T*& object);
    8797
    88             status_t            FindArchivable(const char* name, int32 index,
    89                                     BArchivable** archivable);
     98    template<class T>
     99    inline  status_t            FindObject(const char* name, T*& object);
    90100
    91             status_t            EnsureUnarchived(const char* name,
     101    template<class T>
     102    inline  status_t            FindObject(const char* name, ownership owning,
     103                                    T*& object);
     104
     105    template<class T>
     106    inline  status_t            FindObject(const char* name,
     107                                    int32 index, T*& object);
     108
     109    template<class T>
     110            status_t            FindObject(const char* name, int32 index,
     111                                    ownership owning, T*& object);
     112
     113    inline  status_t            EnsureUnarchived(const char* name,
    92114                                    int32 index = 0);
    93             status_t            EnsureUnarchived(int32 token);
     115    inline  status_t            EnsureUnarchived(int32 token);
    94116
    95117            bool                IsInstantiated(int32 token);
    96118            bool                IsInstantiated(const char* name,
    97119                                    int32 index = 0);
    98120
    99             status_t            Finish();
     121            status_t            Finish(status_t err = B_OK);
    100122            const BMessage*     ArchiveMessage() const;
    101123
     124            void                AssumeOwnership(BArchivable* archivable);
     125            void                RelinquishOwnership(BArchivable* archivable);
     126
    102127    static  bool                IsArchiveManaged(BMessage* archive);
    103128    static  BMessage*           PrepareArchive(BMessage*& archive);
    104129
     130    template<class T>
     131    static  status_t            InstantiateObject(BMessage* archive,
     132                                    T*& object);
     133
    105134private:
    106135    friend class BArchivable;
    107136
     
    110139
    111140            void                RegisterArchivable(BArchivable* archivable);
    112141
    113             void                _CallDebuggerIfManagerNull();
     142    inline  void                _CallDebuggerIfManagerNull();
    114143
    115144            BUnarchiveManager*  fManager;
    116145            const BMessage*     fArchive;
    117146            bool                fFinished;
     147            uint32              _reserved[2];
    118148};
    119149
    120150
     
    131161instantiation_func find_instantiation_func(const char* className);
    132162instantiation_func find_instantiation_func(BMessage* archive);
    133163
     164
     165status_t
     166BArchiver::GetTokenForArchivable(BArchivable* archivable, int32& _token)
     167{
     168    return GetTokenForArchivable(archivable, true, _token);
     169}
     170
     171
     172template<>
     173status_t BUnarchiver::FindObject<BArchivable>(const char* name, int32 index,
     174    ownership owning, BArchivable*& archivable);
     175
     176
     177template<class T>
     178status_t
     179BUnarchiver::FindObject(const char* name, int32 index,
     180    ownership owning, T*& object)
     181{
     182    object = NULL;
     183
     184    BArchivable* interim;
     185    status_t err = FindObject(name, index, owning, interim);
     186
     187    if (err == B_OK && interim) {
     188        object = dynamic_cast<T*>(interim);
     189        if (!object) {
     190            err = B_BAD_TYPE;   
     191            // we will not be deleting this item, but it must be deleted
     192            if (owning == B_ASSUME_OWNERSHIP)
     193                RelinquishOwnership(interim);
     194        }
     195    }
     196    return err;
     197}
     198
     199
     200template<>
     201status_t
     202BUnarchiver::GetObject<BArchivable>(int32 token,
     203    ownership owning, BArchivable*& object);
     204
     205
     206template<class T>
     207status_t
     208BUnarchiver::GetObject(int32 token, ownership owning, T*& object)
     209{
     210    object = NULL;
     211
     212    BArchivable* interim;
     213    status_t err = GetObject(token, owning, interim);
     214
     215    if (err == B_OK && interim) {
     216        object = dynamic_cast<T*>(interim);
     217        if (!object) {
     218            err = B_BAD_TYPE;   
     219            // we will not be deleting this item, but it must be deleted
     220            if (owning == B_ASSUME_OWNERSHIP)
     221                RelinquishOwnership(interim);
     222        }
     223    }
     224    return err;
     225}
     226
     227
     228template<class T>
     229status_t
     230BUnarchiver::GetObject(int32 token, T*& object)
     231{
     232    return GetObject<T>(token, B_ASSUME_OWNERSHIP, object);
     233}
     234
     235
     236template<class T>
     237status_t
     238BUnarchiver::FindObject(const char* name, ownership owning, T*& object)
     239{
     240    return FindObject(name, 0, owning, object);
     241}
     242
     243
     244template<class T>
     245status_t
     246BUnarchiver::FindObject(const char* name, T*& object)
     247{
     248    return FindObject<T>(name, 0, B_ASSUME_OWNERSHIP, object);
     249}
     250
     251
     252template<class T>
     253status_t
     254BUnarchiver::FindObject(const char* name,
     255    int32 index, T*& object)
     256{
     257    return FindObject(name, index, B_ASSUME_OWNERSHIP, object);
     258}
     259
     260
     261status_t
     262BUnarchiver::EnsureUnarchived(int32 token)
     263{
     264    BArchivable* dummy;
     265    return GetObject(token, B_DONT_ASSUME_OWNERSHIP, dummy);
     266}
     267
     268
     269status_t
     270BUnarchiver::EnsureUnarchived(const char* name, int32 index)
     271{
     272    BArchivable* dummy;
     273    return FindObject(name, index, B_DONT_ASSUME_OWNERSHIP, dummy);
     274}
     275
     276
     277template<class T>
     278status_t
     279BUnarchiver::InstantiateObject(BMessage* archive, T*& object)
     280{
     281    object = NULL;
     282    BUnarchiver unarchiver(BUnarchiver::PrepareArchive(archive));
     283    BArchivable* archivable = instantiate_object(archive);
     284    status_t err = unarchiver.Finish();
     285    if (err == B_OK && archivable) {
     286        object = dynamic_cast<T*>(archivable); 
     287        if (!object)
     288            err = B_BAD_TYPE;
     289    }
     290
     291    if (err != B_OK)
     292        delete archivable;
     293
     294    return err;
     295}
     296
     297
    134298#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 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 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;
  • 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#define NULL_TOKEN -42
    1516
     17
    1618namespace BPrivate {
    1719namespace Archiving {
    18     const char* kArchiveCountField = "_managed_archive_count";
    1920    const char* kArchivableField = "_managed_archivable";
    20     const char* kTokenField = "_managed_token";
     21    const char* kManagedField = "_managed_archive";
    2122}
    2223}
    2324
     
    5051    if (manager->fType == UNARCHIVE_MANAGER)
    5152        return static_cast<BUnarchiveManager*>(manager);
    5253
    53     debugger("More calls to BUnarchiver::PrepareMessage()"
     54    debugger("More calls to BUnarchiver::PrepareArchive()"
    5455        " than BUnarchivers created.");
    5556
    5657    return NULL;
     
    8485    :
    8586    BManagerBase(creator->ArchiveMessage(), BManagerBase::ARCHIVE_MANAGER),
    8687    fTokenMap(),
    87     fCreator(creator)
     88    fCreator(creator),
     89    fError(B_OK)
    8890{
    8991}
    9092
    9193
    9294BArchiveManager::~BArchiveManager()
    9395{
    94     fTopLevelArchive->AddInt32(kArchiveCountField, fTokenMap.size());
     96    fTopLevelArchive->AddBool(kManagedField, true);
    9597}
    9698
    9799
     
    99101BArchiveManager::GetTokenForArchivable(BArchivable* archivable, int32& _token)
    100102{
    101103    if (!archivable) {
    102         _token = -42;
     104        _token = NULL_TOKEN;
    103105        return B_OK;
    104106    }
    105107
     
    114116
    115117
    116118status_t
    117 BArchiveManager::ArchiveObject(BArchivable* archivable, bool deep)
     119BArchiveManager::ArchiveObject(BArchivable* archivable,
     120    bool deep, int32& _token)
    118121{
    119     if (IsArchived(archivable)){
    120         debugger("BArchivable requested to be archived"
    121             " was previously archived.");
     122    if (!archivable) {
     123        _token = NULL_TOKEN;
     124        return B_OK;
    122125    }
    123126
    124127    ArchiveInfo& info = fTokenMap[archivable];
    125128
    126     info.archive = new BMessage();
    127     info.token = fTokenMap.size() - 1;
     129    status_t err = B_OK;
    128130
    129     MarkArchive(info.archive);
    130     status_t err = archivable->Archive(info.archive, deep);
     131    if (!info.archive) {
     132        info.archive = new BMessage();
     133        info.token = fTokenMap.size() - 1;
     134   
     135        MarkArchive(info.archive);
     136        err = archivable->Archive(info.archive, deep);
     137    }
    131138
    132139    if (err != B_OK) {
    133140        fTokenMap.erase(archivable);
    134141            // info.archive gets deleted here
    135     }
     142        _token = NULL_TOKEN;
     143    } else
     144        _token = info.token;
    136145
    137146    return err;
    138147}
     
    149158
    150159
    151160status_t
    152 BArchiveManager::ArchiverLeaving(const BArchiver* archiver)
     161BArchiveManager::ArchiverLeaving(const BArchiver* archiver, status_t err)
    153162{
    154     if (archiver == fCreator) {
     163    if (fError == B_OK)
     164        fError = err;
     165
     166    if (archiver == fCreator && fError == B_OK) {
    155167        // first, we must sort the objects into the order they were archived in
    156168        typedef std::pair<BMessage*, const BArchivable*> ArchivePair;
    157169        ArchivePair pairs[fTokenMap.size()];
     
    167179                info.archive = NULL;
    168180        }
    169181
    170         status_t err = B_ERROR;
    171182        int32 count = fTokenMap.size();
    172183        for (int32 i = 0; i < count; i++) {
    173184            const ArchivePair& pair = pairs[i];
    174             err = pair.second->AllArchived(pair.first);
     185            fError = pair.second->AllArchived(pair.first);
    175186
    176             if (err == B_OK && i > 0) {
    177                 err = fTopLevelArchive->AddMessage(kArchivableField,
     187            if (fError == B_OK && i > 0) {
     188                fError = fTopLevelArchive->AddMessage(kArchivableField,
    178189                    pair.first);
    179190            }
    180191
    181             if (err != B_OK) {
     192            if (fError != B_OK) {
    182193                syslog(LOG_ERR, "AllArchived failed for object of type %s.",
    183194                    typeid(*pairs[i].second).name());
    184195                break;
    185196            }
    186197        }
    187 
     198    }
     199   
     200    if (archiver == fCreator)   
    188201        delete this;
    189         return err;
    190     }
    191202
    192     return B_OK;
     203    return fError;
    193204}
    194205
    195206
     
    211222    ArchiveInfo()
    212223        :
    213224        archivable(NULL),
    214         archive()
     225        archive(),
     226        adopted(false)
    215227    {
    216228    }
    217229
     
    223235
    224236    BArchivable*    archivable;
    225237    BMessage        archive;
     238    bool            adopted;
    226239};
    227240
    228241
     
    235248    fObjects(NULL),
    236249    fObjectCount(0),
    237250    fTokenInProgress(0),
    238     fRefCount(0)
     251    fRefCount(0),
     252    fError(B_OK)
    239253{
    240     archive->FindInt32(kArchiveCountField, &fObjectCount);
     254    archive->GetInfo(kArchivableField, NULL, &fObjectCount);
     255    fObjectCount++;
     256        // root object needs a spot too
    241257    fObjects = new ArchiveInfo[fObjectCount];
    242258
    243259    // fObjects[0] is a placeholder for the object that started
     
    260276
    261277
    262278status_t
    263 BUnarchiveManager::ArchivableForToken(BArchivable** _archivable, int32 token)
     279BUnarchiveManager::GetArchivableForToken(int32 token,
     280    ownership owning, BArchivable*& _archivable)
    264281{
    265     if (!_archivable || token > fObjectCount)
     282    if (token > fObjectCount)
    266283        return B_BAD_VALUE;
    267284
    268285    if (token < 0) {
    269         *_archivable = NULL;
     286        _archivable = NULL;
    270287        return B_OK;
    271288    }
    272289
    273290    status_t err = B_OK;
    274     if (!fObjects[token].archivable) {
    275         if (fRefCount > 0)
    276             err = _InstantiateObjectForToken(token);
    277         else {
     291    ArchiveInfo& info = fObjects[token];
     292    if (!info.archivable) {
     293        if (fRefCount > 0) {
     294            fTokenInProgress = token;
     295            if(!instantiate_object(&info.archive))
     296                err = B_ERROR;
     297        } else {
    278298            syslog(LOG_ERR, "Object requested from AllUnarchived()"
    279299                " was not previously instantiated");
    280300            err = B_ERROR;
    281301        }
    282302    }
    283303
    284     *_archivable = fObjects[token].archivable;
     304    if (!info.adopted && owning == B_ASSUME_OWNERSHIP)
     305        info.adopted = true;
     306    else if (info.adopted && owning == B_ASSUME_OWNERSHIP)
     307        debugger("Cannot assume ownership of an object that is already owned");
     308
     309    _archivable = info.archivable;
    285310    return err;
    286311}
    287312
     
    302327        debugger("Cannot register NULL pointer");
    303328
    304329    fObjects[fTokenInProgress].archivable = archivable;
     330    archivable->fArchivingToken = fTokenInProgress;
    305331}
    306332
    307333
    308334status_t
    309 BUnarchiveManager::UnarchiverLeaving(const BUnarchiver* unarchiver)
     335BUnarchiveManager::UnarchiverLeaving(const BUnarchiver* unarchiver,
     336    status_t err)
    310337{
    311     if (--fRefCount == 0) {
    312         fRefCount = -1;
    313             // make sure we de not end up here again!
     338    if (--fRefCount >= 0 && fError == B_OK)
     339        fError = err;
    314340
     341    if (fRefCount != 0)
     342        return fError;
     343
     344    if (fError == B_OK) {
    315345        BArchivable* archivable = fObjects[0].archivable;
    316         status_t err = archivable->AllUnarchived(fTopLevelArchive);
     346        if (archivable) {
     347            fError = archivable->AllUnarchived(fTopLevelArchive);
     348            archivable->fArchivingToken = NULL_TOKEN;
     349        }
    317350
    318         for (int32 i = 1; i < fObjectCount; i++) {
    319             if (err != B_OK)
    320                 break;
    321 
     351        for (int32 i = 1; i < fObjectCount && fError == B_OK; i++) {
    322352            archivable = fObjects[i].archivable;
    323             err = archivable->AllUnarchived(&fObjects[i].archive);
     353            if (archivable) {
     354                fError = archivable->AllUnarchived(&fObjects[i].archive);
     355                archivable->fArchivingToken = NULL_TOKEN;
     356            }
    324357        }
     358        if (fError != B_OK) {
     359            syslog(LOG_ERR, "Error in AllUnarchived"
     360                " method of object of type %s", typeid(*archivable).name());
     361        }
     362    }
    325363
    326         if (err != B_OK) {
    327             syslog(LOG_ERR, "AllUnarchived failed for object of type %s.",
    328                 typeid(*archivable).name());
     364    if (fError != B_OK) {
     365        syslog(LOG_ERR, "An error occured during unarchival, cleaning up.");
     366        for (int32 i = 1; i < fObjectCount; i++) {
     367            if (!fObjects[i].adopted)
     368                delete fObjects[i].archivable;
    329369        }
    330 
    331         delete this;
    332         return err;
    333370    }
    334371
    335     return B_OK;
     372    delete this;
     373    return fError;
    336374}
    337375
    338376
    339377void
    340 BUnarchiveManager::Acquire()
     378BUnarchiveManager::RelinquishOwnership(BArchivable* archivable)
    341379{
    342     if (fRefCount >= 0)
    343         fRefCount++;
     380    int32 token = NULL_TOKEN;
     381    if (archivable)
     382        token = archivable->fArchivingToken;
     383
     384    if (token < 0 || token >= fObjectCount
     385        || fObjects[token].archivable != archivable)
     386        return;
     387
     388    fObjects[token].adopted = false;
    344389}
    345390
    346391
    347 status_t
    348 BUnarchiveManager::_InstantiateObjectForToken(int32 token)
     392void
     393BUnarchiveManager::AssumeOwnership(BArchivable* archivable)
    349394{
    350     fTokenInProgress = token;
    351     if(!instantiate_object(&fObjects[token].archive))
    352         return B_ERROR;
    353     return B_OK;
     395    int32 token = NULL_TOKEN;
     396    if (archivable)
     397        token = archivable->fArchivingToken;
     398
     399    if (token < 0 || token >= fObjectCount
     400        || fObjects[token].archivable != archivable)
     401        return;
     402
     403    if (!fObjects[token].adopted)
     404        fObjects[token].adopted = true;
     405    else {
     406        debugger("Cannot assume ownership of an object that is already owned");
     407    }
    354408}
    355409
     410
     411void
     412BUnarchiveManager::Acquire()
     413{
     414    if (fRefCount >= 0)
     415        fRefCount++;
     416}
  • src/kits/support/ArchivingManagers.h

     
    1818namespace BPrivate {
    1919namespace Archiving {
    2020
    21 extern const char* kArchiveCountField;
    22 extern const char* kArchivableField;
    23 extern const char* kTokenField;
     21extern const char* kManagedField;
    2422
    2523
    2624class BManagerBase {
     
    10199                                    int32& _token);
    102100
    103101            status_t            ArchiveObject(BArchivable* archivable,
    104                                     bool deep);
     102                                    bool deep, int32& _token);
    105103
    106104            bool                IsArchived(BArchivable* archivable);
    107105
    108             status_t            ArchiverLeaving(const BArchiver* archiver);
     106            status_t            ArchiverLeaving(const BArchiver* archiver,
     107                                    status_t err);
     108
    109109            void                Acquire();
    110110            void                RegisterArchivable(
    111111                                    const BArchivable* archivable);
     
    118118
    119119            TokenMap            fTokenMap;
    120120            const BArchiver*    fCreator;
     121            status_t            fError;
    121122};
    122123
    123124
     
    127128public:
    128129                                BUnarchiveManager(BMessage* topLevelArchive);
    129130
    130             status_t            ArchivableForToken(BArchivable** archivable,
    131                                     int32 token);
     131            status_t            GetArchivableForToken(int32 token,
     132                                    ownership owning,
     133                                    BArchivable*& _archivable);
    132134
    133135            bool                IsInstantiated(int32 token);
    134136
    135137            void                RegisterArchivable(BArchivable* archivable);
    136             status_t            UnarchiverLeaving(const BUnarchiver* archiver);
     138            status_t            UnarchiverLeaving(const BUnarchiver* archiver,
     139                                    status_t err);
    137140            void                Acquire();
    138141
     142            void                RelinquishOwnership(BArchivable* archivable);
     143            void                AssumeOwnership(BArchivable* archivable);
    139144private:
    140145                                ~BUnarchiveManager();
    141146
    142147            status_t            _ExtractArchiveAt(int32 index);
    143             status_t            _InstantiateObjectForToken(int32 token);
    144148
    145149            struct ArchiveInfo;
    146150
     
    148152            int32               fObjectCount;
    149153            int32               fTokenInProgress;
    150154            int32               fRefCount;
     155            status_t            fError;
    151156};
    152157
    153158
  • 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.
  • 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                err = ItemUnarchived(from, item, i);
     250            } else
     251                err = B_NO_MEMORY;
    262252        }
    263 
    264         if (err != B_OK)
    265             return err;
    266253    }
    267254
    268     return B_OK;
     255    return err;
    269256}
    270257
    271258
    272259status_t
    273 BLayout::ArchiveLayoutData(BMessage* into, const BLayoutItem* of) const
     260BLayout::ItemArchived(BMessage* into, BLayoutItem* of, int32 index) const
    274261{
    275262    return B_OK;
    276263}
    277264
    278265
    279266status_t
    280 BLayout::RestoreItemAndData(const BMessage* from, BLayoutItem* item)
     267BLayout::ItemUnarchived(const BMessage* from, BLayoutItem* item, int32 index)
    281268{
    282     if (item && AddItem(item))
    283         return B_OK;
    284     return B_ERROR;
     269    return B_OK;
    285270}
    286271
    287272
  • 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};
  • headers/os/support/SupportDefs.h

     
    6363typedef generic_addr_t          generic_size_t;
    6464
    6565
     66/* enum types */
     67enum ownership {
     68    B_ASSUME_OWNERSHIP,
     69    B_DONT_ASSUME_OWNERSHIP
     70};
     71
     72
    6673/* printf()/scanf() format strings for [u]int* types */
    6774#define B_PRId8         "d"
    6875#define B_PRIi8         "i"