On Wed, Aug 11, 2010 at 4:09 PM, <yourpalal2@xxxxxxxxx> wrote: > Author: yourpalal > Date: 2010-08-12 00:09:14 +0200 (Thu, 12 Aug 2010) > New Revision: 38035 > Changeset: http://dev.haiku-os.org/changeset/38035 > > Added: > haiku/trunk/docs/user/support/Archiver.dox > haiku/trunk/docs/user/support/Unarchiver.dox > Modified: > haiku/trunk/docs/user/compatibility.dox > haiku/trunk/docs/user/support/Archivable.dox > haiku/trunk/docs/user/support/support_intro.dox > Log: > Update doxygen docs for recent changes to BArchivable, also document the > BArchiver and BUnarchiver classes, and add a not in compatibility.dox. > ugh, add a NOTE in compatibility.dox. > Modified: haiku/trunk/docs/user/compatibility.dox > =================================================================== > --- haiku/trunk/docs/user/compatibility.dox 2010-08-11 18:08:45 UTC > (rev 38034) > +++ haiku/trunk/docs/user/compatibility.dox 2010-08-11 22:09:14 UTC > (rev 38035) > @@ -47,4 +47,6 @@ > have such an interface in the first place). > - In several places we also dropped compatibility support for older BeOS > versions (PR2, R3, R4), which BeOS R5 still featured. > +- The BArchivable class has been updated, and for some classes, > unarchiving > + is slightly different. > */ > > Modified: haiku/trunk/docs/user/support/Archivable.dox > =================================================================== > --- haiku/trunk/docs/user/support/Archivable.dox 2010-08-11 18:08:45 > UTC (rev 38034) > +++ haiku/trunk/docs/user/support/Archivable.dox 2010-08-11 22:09:14 > UTC (rev 38035) > @@ -2,22 +2,24 @@ > * Copyright 2007, Haiku, Inc. All Rights Reserved. > * Distributed under the terms of the MIT License. > * > - * Author: > + * Authors: > * Niels Sascha Reedijk, niels.reedijk@xxxxxxxxx > + * Alex Wilson, yourpalal2@xxxxxxxxx > * > * Proofreader: > * David Weizades, ddewbofh@xxxxxxxxxxx > * Thom Holwerda, slakje@xxxxxxxxxxx > * > * Corresponds to: > - * /trunk/headers/os/support/Archivable.h rev 19972 > - * /trunk/src/kits/support/Archivable.cpp rev 19095 > + * /trunk/headers/os/support/Archivable.h rev 37751 > + * /trunk/src/kits/support/Archivable.cpp rev 37751 > */ > > > /*! > \file Archivable.h > - \brief Provides the BArchivable interface. > + \brief Provides the BArchivable interface and declares the > BArchiver and > + BUnarchiver classes. > */ > > > @@ -35,9 +37,10 @@ > BArchivable differs from BFlattenable in that BFlattenable is > designed to > store objects into flat streams of data, the main objective being > storage to > disk. The objective of this interface, however, is to store objects > that > - will be restored to other objects. To illustrate this point, > BArchivable > - messages know how to restore themselves whereas BFlattenables have > a > - datatype which you need to map to classes manually. > + will later be restored as new (but identical) objects. To > illustrate this > + point, BArchivable objects can be restored automatically to the > correct > + class, whereas BFlattenables have a data type which you need to map > to > + classes manually. > > Archiving is done with the Archive() method. If your class supports > it, the > caller can request it to store into a deep archive, meaning that all > child > @@ -52,15 +55,25 @@ > To provide this interface in your classes you should publicly > inherit this > class. You should implement Archive() and Instantiate(), and provide > one > constructor that takes one BMessage argument. > + > + If your class holds references to other BArchivable objects that > you wish > + to archive, then you should consider using the BArchiver and > BUnarchiver > + classes in your Archive() method and archive constructor, > respectively. > + You should also consider implementing the AllArchived() and > AllUnarchived() > + methods, which were designed to ease archiving and unarchiving in > such > + a situation. > */ > > > /*! > \fn BArchivable::BArchivable(BMessage* from) > - \brief Constructor. Does nothing. > + \brief Constructor. Does important behind-the-scenes work in the > unarchiving > + process. > > If you inherit this interface you should provide at least one > constructor > - that takes one BMessage argument. > + that takes one BMessage argument. In that constructor, you should > call your > + parent class' archive constructor (even if your parent class is > + BArchivable). > */ > > > @@ -85,9 +98,8 @@ > data needed to instantiate your object to the message. > > \param into The message you store your object in. > - \param deep If \c true, all children of this object should be > stored as > - well. Only pay attention to this parameter if you actually > have child > - objects. > + \param deep If \c true, all children of this object should be > archived as > + well. > \retval B_OK The archiving succeeded. > \retval "error codes" The archiving did not succeed. > */ > @@ -98,27 +110,73 @@ > \brief Static member to restore objects from messages. > > You should always check that the \a archive argument actually > corresponds to > - your class. The automatic functions, such as #instantiate_object() > will not > - choose the wrong class but manual calls to this member might be > faulty. > + your class. The automatic functions, such as #instantiate_object() > and > + BUnarchiver::InstantiateObject() will not choose the wrong class > but manual > + calls to this member might be faulty. You can verify that \c > archive > + stores an object of your calss with the validate_instantiation() > function. > > \param archive The message with the data of the object to restore. > - \retval You should return a pointer to your object, or \c NULL if > you > - fail. > + \retval You should return a pointer to the object you create with > + \c archive, or \c NULL if unarchival fails. > \warning The default implementation will always return \c NULL. Even > though > it is possible to store plain BArchive objects, it is > impossible to > restore them. > + > \see instantiate_object(BMessage *from) > + \see BUnarchiver::InstantiateObject() > */ > > > /*! > \fn virtual status_t BArchivable::Perform(perform_code d, void* arg) > \brief Internal method. > - \internal This method is defined in case of unforeseen binary > compatibility > - API issues. Currently nothing of interest is implemented. > + \internal This method is defined for binary compatibility purposes, > it is > + used to ensure that the correct AllUnarchived() and > AllArchived() > + methods are called for objects, as those methods are new to > Haiku. > */ > > > +/*! > + \fn virtual status_t BArchivable::AllUnarchived(const BMessage* > archive) > + \brief Method relating to the use of \c BUnarchiver. > + > + This hook function is called triggered in the BUnarchiver::Finish() > method. > + In this method, you can rebuild references to objects that may be > direct > + children of your object, or may be children of other objects. > + Implementations of this method should call the implementation of > + their parent class, the same as for the Archive() method. > + > + \note To guarantee that your AllUnarchived() method will be called > during > + unarchival, you must create a BUnarchiver object in your > archive > + constructor. > + > + \see BUnarchiver, BUnarchiver::Finish() > +*/ > + > + > +/*! > + \fn virtual status_t BArchivable::AllArchived(BMessage* into) const > + \brief Method relating to the use of \c BArchiver. > + > + This hook function is called once the first BArchiver that was > created in > + an archiving session is either destroyed, or has its \c Finish() > method > + called. Implementations of this method can be used, in conjunction > with > + BArchiver::IsArchived(), to reference objects in your archive that > you > + do not own, depending on whether or not those objects were archived > by their > + owners. Implementations of this method should call the > implementation of > + their parent class, the same as for the Archive() method. > + > + \note To guarantee that your AllArchived() method will be called > during > + archival, you must create a BArchiver object in your > Archive() > + implementation. > + > + \note You should archive any objects you own in your Archive() > method > + implementation, \b NOT your AllArchived() method. > + > + \see BArchiver BArchiver::Finish() > +*/ > + > + > ///// Global methods ///// > /*! > \addtogroup support_globals > > Added: haiku/trunk/docs/user/support/Archiver.dox > =================================================================== > --- haiku/trunk/docs/user/support/Archiver.dox > (rev 0) > +++ haiku/trunk/docs/user/support/Archiver.dox 2010-08-11 22:09:14 UTC > (rev 38035) > @@ -0,0 +1,138 @@ > +/* > + * Copyright 2010, Haiku, Inc. All Rights Reserved. > + * Distributed under the terms of the MIT License. > + * > + * Author: > + * Alex Wilson, yourpalal2@xxxxxxxxx > + * > + * Corresponds to: > + * /trunk/headers/os/support/Archivable.h rev 37751 > + * /trunk/src/kits/support/Archivable.cpp rev 37751 > + */ > + > + > +/*! > + \class BArchiver > + \ingroup support > + \ingroup libbe > + \brief A class that simplifies the archiving of complicated > BArchivable > + hierarchies. > + > + The BArchiver class is a small class that is used for archiving of > + complicated BArchivable hierarchies. Such a hierarchy may include > + multiple BArchivable objects, each of which might be referenced by > + many BArchivable objects. With the BArchiver class, you can be > certain > + that each BArchivable object is archived only once with very little > work. > + When used in conjuction with the BArchivable::AllArchived() and > + BArchivable::AllUnarchived() methods, it is simple to rebuild your > system of > + references upon unarchival so that they are equivalent to those > that were > + present in your original hierarchy. > + > + The objects you archive can be retrieved using a BUnarchiver > object. > +*/ > + > + > +/*! > + \fn BArchiver::BArchiver(BMessage* archive) > + \brief Constructs a BArchiver object that manages \c archive. > +*/ > + > + > +/*! > + \fn BArchiver::~BArchiver() > + \brief Destroys a BArchiver object. If the BArchiver object has not > had its > + Finish() method called, this will be done now. > +*/ > + > + > +/*! > + \fn status_t BArchiver::AddArchivable(const char* name, > + BArchivable* archivable, bool deep = true) > + \brief Adds a reference to \c archivable to the archive used to > + construct this BArchiver. May call \c archivable's > Archive() method. > + > + \param name Where this reference will be stored in the archive. > + \param archivable The BArchivable* object that to reference. > + \param deep Passed to \c archivable->Archive() if \c archivable > must > + be archived. > + > + Adds a reference to \c archivable to your archive. If \c archivable > has > + not yet been archived, then its Archive() method is called. > BArchiver > + can only track BArchivable objects that have been archived through > this > + method or the GetTokenForArchivable() methods. > + > + \warning If you manually archive an object, and then pass it to > + AddArchivable() or GetTokenForArchivable(), it will be > archived again, > + and when unarchived you will end up with two different > BArchivable > + objects. > +*/ > + > + > +/*! > + \fn status_t BArchiver::GetTokenForArchivable(BArchivable* > archivable, > + bool deep, int32& _token); > + \brief Get a token representing \c archivable for this archiving > + session. > + > + \param deep Controls how \c archivable will be archived, if it has > not yet > + been archived in this session. > + \param[out] _token The token representing \c archivable is stored > here. > + > + Retrieves or creates a token to represent \c archivable in this > archiving > + session. If \c archivable has not yet been archived, it will be > now. If > + \c archivable gets archived, the \c deep parameter will be passed > to its > + Archive() method. > + > + \warning If you manually archive an object, and then pass it to > + GetTokenForArchivable(), it will be archived again, and > when unarchived > + you will end up with two different BArchivable objects. > +*/ > + > + > +/*! > + \fn status_t BArchiver::GetTokenForArchivable(BArchivable* > archivable, > + int32 &_token) > + \brief Equivalent to calling the expanded GetTokenForArchivable( > + BArchivable*, bool, int32&), with the deep parameter equal > to true. > + > + \see GetTokenForArchivable(BArchivable*, bool, int32&) > +*/ > + > + > +/*! > + \fn bool BArchiver::IsArchived(BArchivable* archivable); > + \brief Returns whether \c archivable has already been archived in > this > + session. > + > + \retval true \c archivable has been archived in this archiving > session. > + \retval false \c archivable has not been archived in this archiving > session. > +*/ > + > + > +/*! > + \fn status_t BArchiver::Finish(status_t err = B_OK); > + \brief Report any archiving errors and possibly complete the > archiving > + session. > + \return The first error reported in this archiving session, or > B_OK. > + > + This method may finish an archiving session (triggering the call of > all > + archived objects' AllArchived() methods) if the following > conditions > + are true: > + \li No errors have been reported to this or any other BArchiver > object > + within this session. > + \li This is the last remaining BArchiver that has not had its > Finish() > + method invoked. > + If you call this method with an error code not equal to B_OK, then > this > + archiving session has failed, archived objects will not have their > + AllArchived() methods called, and any subsequent calls to this > method > + on any BArchiver objects in this session will return your error > code. > +*/ > + > + > +/*! > + \fn const BMessage* BArchiver::ArchiveMessage() const > + \brief Returns the BMessage* used to construct this BArchiver. This > is > + the archive that AddArchivable() modifies. > +*/ > + > + > > Added: haiku/trunk/docs/user/support/Unarchiver.dox > =================================================================== > --- haiku/trunk/docs/user/support/Unarchiver.dox > (rev 0) > +++ haiku/trunk/docs/user/support/Unarchiver.dox 2010-08-11 22:09:14 > UTC (rev 38035) > @@ -0,0 +1,304 @@ > +/* > + * Copyright 2010, Haiku, Inc. All Rights Reserved. > + * Distributed under the terms of the MIT License. > + * > + * Author: > + * Alex Wilson, yourpalal2@xxxxxxxxx > + * > + * Corresponds to: > + * /trunk/headers/os/support/Archivable.h rev 37751 > + * /trunk/src/kits/support/Archivable.cpp rev 37751 > + */ > + > + > +/*! > +\class BUnarchiver > +\ingroup support > +\ingroup libbe > +\brief A class that simplifies the unarchiving of complicated BArchivable > + hierarchies. > + > + The BUnarchiver class is a small class used to recover BArchivable > objects > + that have been archived with the BArchiver class. It also provides > ownership > + semantics, so that memory leaks can be avoided during the > unarchival > + process. When retrieving an object (either via GetObject() or > FindObject()), > + you can specify a BUnarchiver::ownership_policy. If you specify > + BUnarchiver::B_ASSUME_OWNERSHIP, you will become responsible for > deleting > + the retrieved item. If you specify > BUnarchiver::B_DONT_ASSUME_OWNERSHIP, > + you will not become responsible. You cannot take ownership of the > same > + object twice. After the unarchival process finishes, any unclaimed > objects, > + excluding the root object (the object being instantiated via > + instantiate_object() or BUnarchiver::InstantiateObject()), will be > deleted. > + > + If you are updating a class that previously did not use the > BArchiver and > + BUnarchiver helper classes, and want to maintain backwards > compatibility > + with old archive, this can be done using the IsArchiveManaged() > method. > + > + \Warning Calling methods on your BUnarchiver with a legacy archive > (one that > + was not managed by a BArchiver during archival) will result > in a > + call to debugger(). > +*/ > + > + > +/*! > + \fn BUnarchiver::BUnarchiver(const BMessage* archive) > + \brief Constructs a BUnarchiver object to manage \c archive. > + > + \note To guarantee that your AllUnarchived() method will be called > during > + archival, you must create a BUnarchiver object in your > archive > + constructor. It is necessary to do this even if you won't > use the > + BUnarchiver object in your archive constructor. > + > + \warning Do not construct a BUnarchiver object without first > calling > + BUnarchiver::PrepareArchive() on \c archive. It is only > safe to build a > + BUnarchiver without this call in your AllUnarchived() > implementation. > + > + \see BUnarchiver::PrepareArchive() > +*/ > + > + > +/*! > + \fn BUnarchiver::~BUnarchiver() > + \brief Destroys a BUnarchiver object. Calls this objects Finish() > method, > + if it has not yet been called. > +*/ > + > + > +/*! > + \fn status_t BUnarchiver::EnsureUnarchived(int32 token) > + \brief Ensure the object represented by \c token is unarchived and > + instantiated. > +*/ > + > + > +/*! > + \fn status_t BUnarchiver::EnsureUnarchived(const char* name, > + int32 index = 0) > + \brief Ensure the object archived under \c name at \c index is > unarchived > + and instantiated. > +*/ > + > + > +/*! > + \fn bool BUnarchiver::IsInstantiated(int32 token) > + \brief Checks whether the object represented by \c token has been > + instantiated in this session. > +*/ > + > + > +/*! > + \fn bool BUnarchiver::IsInstantiated(const char* name, int32 index > = 0) > + \brief Checks whether the object archived under \c name at \c index > has been > + instantiated in this session. > + */ > + > + > +/*! > + \fn template<class T> status_t BUnarchiver::GetObject(int32 token, > + ownership_policy owning, T*& object) > + > + \brief Recover an object by token that was archived by a BArchiver > object. > + If the object has not yet been instantiated, and this request is > not coming > + from an AllUnarchived() implementation, the object will be > instantiated now. > + > + If the retrieved object is not of the type \c T, then this method > will fail. > + If this method fails, you will not receive ownership of the object, > no > + matter what you specified in \c owning. > + > + \tparam T The type of object you wish to find. > + > + \param token The token you got for this object from > + BArchiver::GetTokenForArchivable() during archival. > + \param owning Whether or not you wish to take ownership of the > + retrieved object. > + \param object Return parameter for the retrieved object of type \c > T. > + > + \retval B_BAD_TYPE The object retrieved was not of type \c T. > +*/ > + > + > +/*! > + \fn template<class T> status_t BUnarchiver::GetObject(int32 token, > + T*& object) > + > + \brief Recover and take ownership of an object represented by \c > token. > + > + Equivalent to calling GetObject(token, > BUnarchiver::B_ASSUME_OWNERSHIP, > + object) > +*/ > + > + > +/*! > + \fn template<class T> status_t BUnarchiver::FindObject(const char* > name, > + int32 index, ownership_policy owning, T*& object) > + > + \brief Recover an object that had previously been archived using > + the BArchiver::AddArchivable() method. If the object has > not yet been > + instantiated, and this request is not coming from an > AllUnarchived() > + implementation, the object will be instantiated now. > + > + If the retrieved object is not of the type \c T, then this method > will fail. > + If this method fails, you will not receive ownership of the object, > no > + matter what you specified in \c owning. > + > + \tparam T The type of object you wish to find. > + > + \param name The name that was passed to BArchiver::AddArchivable() > when > + adding this object. > + \param index The index of the object you wish to recover (0 based, > like > + BMessage::FindData(). > + \param owning Dictates whether or not you wish to take ownership of > the > + retrieved object. > + \param object Return parameter for the retrieved object of type \c > T. > + > + \retval B_BAD_TYPE The object retrieved was not of type \c T. > +*/ > + > + > +/*! > + \fn template<class T> status_t BUnarchiver::FindObject(const char* > name, > + int32 index, T*& object) > + > + \brief Recover and take ownership of an object that had previously > been > + archived using the BArchiver::AddArchivable() method. > +*/ > + > + > +/*! > + \fn template<class T> status_t BUnarchiver::FindObject(const char* > name, > + ownership_policy owning, T*& object) > + > + \brief Recover an object at index 0 that had previously been > archived using > + the BArchiver::AddArchivable() method. > + > + Equivalent to calling FindObject(name, 0, owning, object). > +*/ > + > + > +/*! > + \fn template<class T> status_t BUnarchiver::FindObject(const char* > name, > + T*& object) > + > + \brief Recover and take ownership of an object at index 0 that had > + previously been archived using the > BArchiver::AddArchivable() method. > + > + Equivalent to calling FindObject(name, 0, > BUnarchiver::B_ASSUME_OWNERSHIP, > + object). > +*/ > + > + > +/*! > + \fn status_t BUnarchiver::Finish(status_t err = B_OK); > + \brief Report any unarchiving errors and possibly complete the > archiving > + session. > + \return The first error reported in this unarchiving session, or > B_OK. > + > + This method may finish an unarchiving session (triggering the call > of all > + instantiated objects' AllUnarchived() methods) if the following > conditions > + are true: > + \li No errors have been reported to this or any other BUnarchiver > object > + within this session. > + \li This is the last remaining BUnarchiver that has not had its > Finish() > + method invoked. > + If you call this method with an error code not equal to B_OK, then > this > + unarchiving session has failed, instantiated objects will not have > their > + AllUnarchived() methods called, and any subsequent calls to this > method > + on any BUnarchiver objects in this session will return your error > code. > + Furthermore, any objects that have been instantiated, but have not > had > + their ownership assumed by another object will now be deleted > (excluding > + the root object). > +*/ > + > + > +/*! > + \fn const BMessage* BUnarchiver::ArchiveMessage() const > + \brief Returns the BMessage* used to construct this BUnarchiver. > This is > + the archive that FindObject() uses. > +*/ > + > + > +/*! > + \fn static bool BUnarchiver::IsArchiveManaged(const BMessage* > archive) > + > + \brief Checks whether \c archive was managed by a BArchiver object. > + \retval true if \c archive was managed by a BArchiver object. > + \retval false otherwise. > + > + This method can be used to maintain archive backwards-compatibility > for a > + class that has been updated to use the BArchiver class. If there is > a > + possibility that you are may dealing with a legacy archive, you can > use > + this method to find out before calling any methods on your > BUnarchiver > + object. > + > + Here is an example of how you might use this method. Note that you > + must still call BUnarchiver::PrepareArchive(archive), either way. > + > + \code > +MyArchivableClas::MyArchivableClass(BMessage* archive) > + : > + BArchivable(BUnarchiver::PrepareArchive(archive)) > +{ > + BUnarchiver unarchiver(archive); > + > + if (BUnarchiver::IsArchiveManaged(archive)) { > + // ... calls to FindObject() or GetObject() here ... > + } else { > + // ... calls to BMessage::FindMessage() here ... > + } > +} > + \endcode > +*/ > + > + > +/*! > + \fn static BMessage* BUnarchiver::PrepareArchive(BMessage*& > archive) > + \brief Prepares \c archive for use by a BUnarchiver. > + \param archive The archive you wish to have prepared. > + \return The same BMessage as is passed in. > + > + This method must be called if you plan to use a BUnarchiver on an > archive. > + It must be called once for each class an object inherits from that > + will use a BUnarchiver. > + > + \warning This method \bold must be called \bold before a call to > the > + archive constructor of your parent class. > + > + Notice the use of this method in the example provided below. > + \code > +MyArchivableClas::MyArchivableClas(BMessage* archive) > + : > + BArchivable(BUnarchiver::PrepareArchive(archive)) > +{ > + // ... > +} > + \endcode > +*/ > + > + > +/*! > + \fn void BUnarchiver::AssumeOwnership(BArchivable* archivable) > + \brief Become the owner of \c archivable. > + > + After calling this method, you are responsible for the deletion > + of \c archivable. > +*/ > + > + > +/*! > + \fn void BUnarchiver::RelinquishOwnership(BArchivable* archivable) > + \brief Relinquish ownership of \c archivable. If \c archivable > remains > + unclaimed at the end of the unarchiving session, it will be > deleted > + (unless it is the root object). > +*/ > + > + > +/*! > + \fn template<class T> status_t BUnarchiver::InstantiateObject( > + BMessage* from, T*& object) > + \brief Attempt to instantiate an object of type \c T from BMessage* > \c from. > + > + If the instantiated object is not of type \c T, then it will be > deleted, > + and this method will return \c B_BAD_TYPE. This method is similar > to > + the instantiate_object() function, but provides error reporting and > + protection from memory leaks. > +*/ > > Modified: haiku/trunk/docs/user/support/support_intro.dox > =================================================================== > --- haiku/trunk/docs/user/support/support_intro.dox 2010-08-11 18:08:45 > UTC (rev 38034) > +++ haiku/trunk/docs/user/support/support_intro.dox 2010-08-11 22:09:14 > UTC (rev 38035) > @@ -20,6 +20,8 @@ > - \ref TLS.h "Thread Local Storage" > - Archiving and IO: > - BArchivable > + - BArchiver > + - BUnarchiver > - BFlattenable > - BDataIO > - BPositionIO > > >