Tekkotsu Homepage
Demos
Overview
Downloads
Dev. Resources
Reference
Credits

plistCollections.h

Go to the documentation of this file.
00001 //-*-c++-*-
00002 #ifndef INCLUDED_plistCollections_h_
00003 #define INCLUDED_plistCollections_h_
00004 
00005 #include "plistPrimitives.h"
00006 #include <map>
00007 #include <vector>
00008 #include <set>
00009 
00010 namespace plist {
00011   
00012   //! Provides a common base class for the collection-oriented primitives, Dictionary, Map, Array, and Vector
00013   class Collection : public ObjectBase {
00014   public:
00015     //! get notified of changes; be sure to call removeCollectionListener() before destructing @a l!
00016     virtual void addCollectionListener(CollectionListener* l);
00017     //! no longer take notification of changes to this object's value
00018     virtual void removeCollectionListener(CollectionListener* l);
00019     //! test if @a l is currently registered as a listener
00020     virtual bool isCollectionListener(CollectionListener* l);
00021 
00022     //! insert a new entry to the dictionary, with key @a name and value @a val (replaces any previous entry by same name, but gives a warning)
00023     virtual void setEntry(const std::string& name, ObjectBase& val, bool warnExists=false)=0;
00024     //! insert a new entry to the dictionary, with key @a name and value @a val (replaces any previous entry by same name, but gives a warning)
00025     virtual void addEntry(const std::string& name, ObjectBase& val, const std::string& comment="")=0;
00026     //! insert a new entry to the dictionary, with key @a name and value @a val, control of deallocation given to collection
00027     virtual void setEntry(const std::string& name, ObjectBase* val, bool warnExists=false)=0;
00028     //! insert a new entry to the dictionary, with key @a name and value @a val, control of deallocation given to collection
00029     virtual void addEntry(const std::string& name, ObjectBase* val, const std::string& comment="")=0;
00030     
00031     //! remove the entry with key @a name
00032     virtual void removeEntry(const std::string& name)=0;
00033     //! return the value of the key @a name, or NULL if it doesn't exist
00034     virtual ObjectBase* getEntry(const std::string& name) const=0;
00035     //! return the value of the key @a name, or NULL if it doesn't exist (equivalent to getEntry(name))
00036     virtual ObjectBase* operator[](const std::string& name) const { return getEntry(name); }
00037     //! remove all entries in one fell swoop
00038     virtual void clear()=0;
00039     
00040     //! replaces previous comment for @a name, or adds it if it doesn't already exist (can preceed actual entry!)
00041     virtual void setComment(const std::string& name, const std::string& comment)=0;
00042     //! returns comment retrieved from loaded file, or any subsequent call to setComment
00043     virtual const std::string& getComment(const std::string& name) const=0;
00044 
00045     void setUnusedWarning(bool b) { warnUnused=b; } //!< set #warnUnused
00046     bool getUnusedWarning() { return warnUnused; } //!< returns #warnUnused
00047 
00048     virtual bool getTrimExtraLoad() const { return trimExtraLoad; } //!< returns #trimExtraLoad
00049     virtual bool getTrimExtraSave() const { return trimExtraSave; } //!< returns #trimExtraSave
00050     virtual void setTrimExtra(bool trim) { trimExtraLoad=trimExtraSave=trim; } //!< sets #trimExtraLoad and #trimExtraSave to the save value
00051     virtual void setTrimExtra(bool trimLoad, bool trimSave) { trimExtraLoad=trimLoad; trimExtraSave=trimSave; } //!< sets #trimExtraLoad and #trimExtraSave
00052     
00053   protected:
00054     //! constructor
00055     explicit Collection(bool bl, bool bs) : ObjectBase(), collectionListeners(), warnUnused(true), trimExtraLoad(bl), trimExtraSave(bs) {autoFormat=false;}
00056     //! copy constructor (don't assign listeners)
00057     Collection(const Collection& d) : ObjectBase(d), collectionListeners(), warnUnused(d.warnUnused), trimExtraLoad(d.trimExtraLoad), trimExtraSave(d.trimExtraSave) {autoFormat=false;}
00058     //! assignment (don't assign listeners); subclass should call fireEntriesChanged after calling this (and updating it storage)
00059     Collection& operator=(const Collection& d) { if(&d==this) return *this; ObjectBase::operator=(d); return *this; }
00060     //! destructor
00061     ~Collection();
00062     
00063     //! run through #collectionListeners, calling CollectionListener::plistCollectionEntryAdded(*this,val)
00064     virtual void fireEntryAdded(ObjectBase& val);
00065     //! run through #collectionListeners, calling CollectionListener::plistCollectionEntryRemoved(*this,val)
00066     virtual void fireEntryRemoved(ObjectBase& val);
00067     //! run through #collectionListeners, calling CollectionListener::plistCollectionEntriesChanged(*this)
00068     virtual void fireEntriesChanged();
00069     //! stores a list of the current listeners
00070     std::list<CollectionListener*>* collectionListeners;
00071     
00072     //! return the length of the longest key for formatting purposes
00073     virtual unsigned int getLongestKeyLen() const=0;
00074     //! a forwarding function to allow recursive flow of control (gets around not being able to call protected functions on non-this objects)
00075     static unsigned int getLongestKeyLenOther(const Collection& c) { return c.getLongestKeyLen(); }
00076     
00077     //! if true (the default) loadXML will give warnings if there are unused entries in the node it is passed (can only happen if trimExtraLoad is false), or extra values in a file being saved into (can only happen if trimExtraSave is false)
00078     bool warnUnused;    
00079     //! if true, unloaded items in the collection will be removed after a load, and new entries will be created for extras in the source (brings storage into complete sync with input)
00080     bool trimExtraLoad;
00081     //! if true, unsaved items in the destination will be removed after a save (brings output XML tree into complete sync with storage)
00082     bool trimExtraSave;
00083     
00084     //! when an empty string is needed for not found items
00085     /*!  (defined as a function instead of just a constant member so there's no issues with initialization order) */
00086     static const std::string& Collection::emptyStr() {
00087       static std::string mt;
00088       return mt;
00089     }
00090     //! defines separator between sub-collections
00091     /*!  (defined as a function instead of just a constant member so there's no issues with initialization order) */
00092     static const std::string& Collection::subCollectionSep() {
00093       static std::string sep=".";
00094       return sep;
00095     }
00096   };
00097   
00098   //! Maintains a set of (key,value) pairs, where a value can be any subclass of ObjectBase
00099   /*! This class supports callbacks upon modification through the use of the
00100    *  CollectionListener interface.  Note that we only store a pointer to the
00101    *  listener list, which is typically unallocated when no listeners are
00102    *  active.  This should ensure minimal memory usage per object, as well as
00103    *  support safe storage of plist objects in inter-process shared memory
00104    *  regions.
00105    *
00106    *  If you are using these in a shared memory region, just be sure that only
00107    *  the process with listeners does any and all modifications, and that it
00108    *  unsubscribes before detaching from the region (or else destroys the region
00109    *  itself)
00110    *
00111    *  There isn't a callback if entries themselves are modified, only when new
00112    *  entries are added, or old ones removed.  If you want to know any time any
00113    *  aspect of any entry is modified, listen for the add and remove callbacks,
00114    *  and then add yourself as a listener to each entry individually.  */
00115   class Dictionary : public Collection {
00116     friend std::ostream& operator<<(std::ostream& os, const Dictionary& d);
00117   public:
00118     //! shorthand for the type of the storage
00119     typedef std::map<std::string,ObjectBase*> storage_t;
00120     //! shorthand for iterators to be returned
00121     typedef storage_t::iterator iterator;
00122     //! shorthand for iterators to be returned
00123     typedef storage_t::const_iterator const_iterator;
00124     
00125     //! constructor
00126     Dictionary() : Collection(false,false), dict(), myRef(), comments() {}
00127     //! constructor
00128     explicit Dictionary(bool growable) : Collection(growable,growable), dict(), myRef(), comments() {}
00129     //! copy constructor (don't assign listeners)
00130     Dictionary(const Dictionary& d) : Collection(d), dict(d.dict), myRef(d.myRef), comments(d.comments) { cloneMyRef(); }
00131     //! assignment (don't assign listeners); subclass should call fireEntriesChanged after calling this (and updating its own storage)
00132     Dictionary& operator=(const Dictionary& d) { if(&d==this) return *this; clear(); Collection::operator=(d); dict=d.dict; myRef=d.myRef; comments=d.comments; cloneMyRef(); fireEntriesChanged(); return *this; }
00133     //! destructor
00134     ~Dictionary() { clear(); }
00135         
00136     //! insert a new entry to the map; expects @a val to be either a primitive type, like int, float, etc., or one of the variable-sized Collection's, like Vector
00137     template<typename T>
00138       void setValue(const std::string& name, const T& val, bool warnExists=false) { setEntry(name,new Primitive<T>(val),warnExists); }
00139     //! insert a new entry to the map, and corresponding comment; expects @a val to be either a primitive type, like int, float, etc., or one of the variable-sized Collection's, like Vector
00140     template<typename T>
00141       void addValue(const std::string& name, const T& val, const std::string& comment="", bool warnExists=true) { addEntry(name,new Primitive<T>(val),comment,warnExists); }
00142     //! "specialization" (actually just another override) for handling character arrays as strings
00143     virtual void setValue(const std::string& name, const char val[], bool warnExists=false) { setEntry(name,new Primitive<std::string>(val),warnExists); }
00144     //! "specialization" (actually just another override) for handling character arrays as strings
00145     virtual void addValue(const std::string& name, const char val[], const std::string& comment="") { addEntry(name,new Primitive<std::string>(val),comment,true); }
00146     //! "specialization" (actually just another override) for handling character arrays as strings
00147     virtual void addValue(const std::string& name, const char val[], const std::string& comment, bool warnExists) { addEntry(name,new Primitive<std::string>(val),comment,warnExists); }
00148     
00149     //! insert a new entry to the dictionary, with key @a name and value @a val (replaces any previous entry by same name, but can give a warning)
00150     virtual void setEntry(const std::string& name, ObjectBase& val, bool warnExists=false);
00151     //! insert a new entry to the dictionary, with key @a name and value @a val (replaces any previous entry by same name, but can give a warning)
00152     virtual void addEntry(const std::string& name, ObjectBase& val, const std::string& comment="") { addEntry(name,val,comment,true); }
00153     //! insert a new entry to the dictionary, with key @a name and value @a val (replaces any previous entry by same name, but can give a warning)
00154     virtual void addEntry(const std::string& name, ObjectBase& val, const std::string& comment, bool warnExists);
00155     virtual void setEntry(const std::string& name, ObjectBase* val, bool warnExists=false);
00156     virtual void addEntry(const std::string& name, ObjectBase* val, const std::string& comment="") { addEntry(name,val,comment,true); }
00157     //! insert a new entry to the dictionary, with key @a name and value @a val (replaces any previous entry by same name, but can give a warning)
00158     virtual void addEntry(const std::string& name, ObjectBase* val, const std::string& comment, bool warnExists);
00159         
00160     //! remove the entry with key @a name
00161     virtual void removeEntry(const std::string& name);
00162     //! return the value of the key @a name, or NULL if it doesn't exist
00163     virtual ObjectBase* getEntry(const std::string& name) const;
00164         
00165     virtual void clear();
00166     
00167     //! return an STL const_iterator to the first entry
00168     const_iterator begin() const { return dict.begin(); }
00169     //! return the one-past-end const_iterator
00170     const_iterator end() const { return dict.end(); }
00171     //! return the size of the dictionary
00172     size_t size() const { return dict.size(); }
00173     
00174     //! replaces previous comment for @a name, or adds it if it doesn't already exist (can preceed actual entry!)
00175     void setComment(const std::string& name, const std::string& comment);
00176     //! returns comment retrieved from loaded file, or any subsequent call to setComment
00177     const std::string& getComment(const std::string& name) const;
00178     
00179     virtual void loadXML(xmlNode* node);
00180     virtual void saveXML(xmlNode* node) const;
00181     
00182     virtual std::string toString() const;
00183     
00184     //! clone implementation for Dictionary
00185     PLIST_CLONE_DEF(Dictionary,new Dictionary(*this));
00186     
00187   protected:
00188     virtual void fireEntryRemoved(ObjectBase& val);
00189     
00190     //! indicates that the storage implementation should mark this as an externally supplied heap reference, which needs to be deleted on removal/destruction
00191     virtual void takeObject(const std::string& name, ObjectBase* obj);
00192     
00193     //! called with each node being loaded so subclass can handle appropriately
00194     virtual bool loadXMLNode(const std::string& key, xmlNode* val, const std::string& comment);
00195     
00196     virtual unsigned int getLongestKeyLen() const;
00197     
00198     //! returns an entry matching just the prefix
00199     /*! @param[in] name the name being looked up
00200      *  @param[out] seppos the position of the separator (sub-collections are separated by '.')
00201      *  @return iterator of the sub entry*/
00202     iterator getSubEntry(const std::string& name, std::string::size_type& seppos);
00203     //! returns an entry matching just the prefix
00204     /*! @param[in] name the name being looked up
00205      *  @param[out] seppos the position of the separator (sub-collections are separated by '.')
00206      *  @return iterator of the sub entry*/
00207     const_iterator getSubEntry(const std::string& name, std::string::size_type& seppos) const;
00208     
00209     //! called after an assignment or copy to clone the objects in #myRef to perform a deep copy
00210     virtual void cloneMyRef();
00211     
00212     //! storage of entries -- mapping from keys to value pointers
00213     storage_t dict;
00214     
00215     //! objects which have been handed over to the collection for eventual de-allocation
00216     std::set<ObjectBase*> myRef;
00217 
00218     //! shorthand for the type of #comments
00219     typedef std::map<std::string,std::string> comments_t;
00220     //! storage of entry comments -- mapping from keys to help text comments for manual editing or user feedback
00221     /*! not every key necessarily has a comment! */
00222     comments_t comments;
00223   };
00224   //! provides textual output
00225   std::ostream& operator<<(std::ostream& os, const Dictionary& d);
00226   
00227   //! A collection of plist objects, similar to a Dictionary, but no keys -- order matters!
00228   /*! There's two versions of the plist array -- one is this Array class, the other is
00229    *  the Vector.  This class is designed to be a fixed size -- you should add the entries
00230    *  which you expect to find in the array, and extra entries will be ignored when loading
00231    *  (with an optional warning).  You can mix different primitive types in any order
00232    *  you choose.
00233    *
00234    *  The other class, Vector, takes the opposite tack -- it handles loading a variable
00235    *  number of entries, but handles the allocation of those objects internally.
00236    */
00237   class Array : public Collection {
00238     friend std::ostream& operator<<(std::ostream& os, const Array& d);
00239   public:
00240     //! shorthand for the type of the storage
00241     typedef std::vector<ObjectBase*> storage_t;
00242     //! shorthand for iterators to be returned
00243     typedef storage_t::iterator iterator;
00244     //! shorthand for iterators to be returned
00245     typedef storage_t::const_iterator const_iterator;
00246     
00247     //! constructor
00248     Array() : Collection(false,false), arr(), myRef(), comments() {}
00249     //! constructor
00250     explicit Array(bool growable) : Collection(growable,growable), arr(), myRef(), comments() {}
00251     //! copy constructor (don't assign listeners)
00252     Array(const Array& d) : Collection(d), arr(d.arr), myRef(d.myRef), comments(d.comments) { cloneMyRef(); }
00253     //! assignment (don't assign listeners); subclass should call fireEntriesChanged after calling this (and updating it storage)
00254     Array& operator=(const Array& d) { if(&d==this) return *this; clear(); Collection::operator=(d); arr=d.arr; myRef=d.myRef; comments=d.comments; cloneMyRef(); return *this; }
00255     //! destructor
00256     ~Array() { clear(); }
00257     
00258     //! insert a new entry to the end of the vector, and corresponding comment; expects @a val to be either a primitive type, like int, float, etc., or one of the variable-sized Collection's, like Vector, control of (de)allocation will be assumed by the Vector
00259     template<typename T>
00260       void addValue(const T& val, const std::string& comment="") { addEntry(new Primitive<T>(val),comment); }
00261     //! "specialization" (actually just another override) for handling character arrays as strings
00262     virtual void addValue(const char val[], const std::string& comment="") { if(comment.size()>0) setComment(size(),comment); arr.push_back(new Primitive<std::string>(val)); takeObject(size()-1,arr.back()); fireEntryAdded(*arr.back()); }
00263     
00264     //! replaces previous entry at the specified @a index, which must represent an integer value less than or equal to the current array size; clone of @a val will be added
00265     virtual void addEntry(ObjectBase& val, const std::string& comment="") { if(comment.size()>0) setComment(size(),comment); arr.push_back(&val); fireEntryAdded(*arr.back()); }
00266     //! replaces previous entry at the specified @a index, which must represent an integer value less than or equal to the current array size; clone of @a val will be added
00267     virtual void addEntry(ObjectBase* val, const std::string& comment="") { if(comment.size()>0) setComment(size(),comment); arr.push_back(val); takeObject(size()-1,val); fireEntryAdded(*arr.back()); }
00268     
00269     //! replaces previous entry at the specified @a index, which must be less than or equal to the current array size, control of (de)allocation will be assumed by the Vector
00270     template<typename T>
00271       void setValue(size_t index, const T& val, bool warnExists=false) { setEntry(index,new Primitive<T>(val),warnExists); }
00272     //! replaces previous entry at the specified @a index, which must be less than or equal to the current array size, control of (de)allocation will be assumed by the Vector
00273     template<typename T>
00274       void addValue(size_t index, const T& val, const std::string& comment="") { addEntry(index,new Primitive<T>(val),comment); }
00275     //! "specialization" (actually just another override) for handling character arrays as strings
00276     virtual void setValue(size_t index, const char val[], bool warnExists=false) { setEntry(index,new Primitive<std::string>(val),warnExists); }
00277     //! "specialization" (actually just another override) for handling character arrays as strings
00278     virtual void addValue(size_t index, const char val[], const std::string& comment="") { addEntry(index,new Primitive<std::string>(val),comment); }
00279     
00280     //! replaces previous entry at the specified @a index, which must be less than or equal to the current array size; clone will be added
00281     virtual void setEntry(size_t index, ObjectBase& val, bool warnExists=false);
00282     //! replaces previous entry at the specified @a index, which must be less than or equal to the current array size; clone will be added
00283     virtual void addEntry(size_t index, ObjectBase& val, const std::string& comment="");
00284     //! replaces previous entry at the specified @a index, which must be less than or equal to the current array size; clone will be added
00285     virtual void setEntry(size_t index, ObjectBase* val, bool warnExists=false);
00286     //! replaces previous entry at the specified @a index, which must be less than or equal to the current array size; clone will be added
00287     virtual void addEntry(size_t index, ObjectBase* val, const std::string& comment="");
00288     
00289     //! replaces previous entry of the same name, which must represent an integer value less than or equal to the current array size, control of (de)allocation will be assumed by the Vector
00290     template<typename T>
00291       void setValue(const std::string& name, const T& val,bool warnExists=false) { setEntry(name,new Primitive<T>(val),warnExists); }
00292     //! replaces previous entry of the same name, which must represent an integer value less than or equal to the current array size, control of (de)allocation will be assumed by the Vector
00293     template<typename T>
00294       void addValue(const std::string& name, const T& val, const std::string& comment="") { addEntry(name,new Primitive<T>(val),comment); }
00295     //! "specialization" (actually just another override) for handling character arrays as strings
00296     virtual void setValue(const std::string& name, const char val[], bool warnExists=false) { setEntry(name,new Primitive<std::string>(val),warnExists); }
00297     //! "specialization" (actually just another override) for handling character arrays as strings
00298     virtual void addValue(const std::string& name, const char val[], const std::string& comment="") { addEntry(name,new Primitive<std::string>(val),comment); }
00299     
00300     //! replaces previous entry of the same name, which must represent an integer value less than or equal to the current array size; clone will be added
00301     virtual void setEntry(const std::string& name, ObjectBase& val, bool warnExists=false);
00302     //! replaces previous entry of the same name, which must represent an integer value less than or equal to the current array size; clone will be added
00303     virtual void addEntry(const std::string& name, ObjectBase& val, const std::string& comment="");
00304     //! replaces previous entry of the same name, which must represent an integer value less than or equal to the current array size; clone will be added
00305     virtual void setEntry(const std::string& name, ObjectBase* val, bool warnExists=false);
00306     //! replaces previous entry of the same name, which must represent an integer value less than or equal to the current array size; clone will be added
00307     virtual void addEntry(const std::string& name, ObjectBase* val, const std::string& comment="");
00308     
00309     //! remove the entry at position @a index
00310     virtual void removeEntry(size_t index);
00311     //! return the value at position @a index
00312     ObjectBase& getEntry(size_t index) const { return *arr[index]; }
00313     //! return the value of the key @a name, or NULL if it doesn't exist (equivalent to getEntry(index))
00314     ObjectBase& operator[](size_t index) const { return *arr[index]; }
00315     
00316     virtual void removeEntry(const std::string& name);
00317     virtual ObjectBase* getEntry(const std::string& name) const;
00318     virtual ObjectBase* operator[](const std::string& name) const { return getEntry(name); }
00319     
00320     virtual void clear();
00321     
00322     //! return an STL const_iterator to the first entry
00323     const_iterator begin() const { return arr.begin(); }
00324     //! return the one-past-end const_iterator
00325     const_iterator end() const { return arr.end(); }
00326     //! return the size of the dictionary
00327     size_t size() const { return arr.size(); }
00328     
00329     //! replaces previous comment for @a name, or adds it if it doesn't already exist (can preceed actual entry!)
00330     virtual void setComment(size_t index, const std::string& comment);
00331     //! returns comment retrieved from loaded file, or any subsequent call to setComment
00332     virtual const std::string& getComment(size_t index) const;
00333     
00334     //! replaces previous comment for @a name, or adds it if it doesn't already exist (can preceed actual entry!)
00335     virtual void setComment(const std::string& name, const std::string& comment);
00336     //! returns comment retrieved from loaded file, or any subsequent call to setComment
00337     virtual const std::string& getComment(const std::string& name) const;
00338     
00339     virtual void loadXML(xmlNode* node);
00340     virtual void saveXML(xmlNode* node) const;
00341     
00342     //! returns index corresponding to @a name, which should encode an integer value less than or equal to the current size
00343     size_t getIndex(const std::string& name) const;
00344     
00345     virtual std::string toString() const;
00346     
00347     //! clone implementation for Array
00348     PLIST_CLONE_DEF(Array,new Array(*this));
00349       
00350   protected:
00351     virtual void fireEntryRemoved(ObjectBase& val);
00352     
00353     //! indicates that the storage implementation should mark this as an externally supplied heap reference, which needs to be deleted on removal/destruction
00354     virtual void takeObject(size_t index, ObjectBase* obj);
00355     
00356     //! called with each node being loaded so subclass can handle appropriately
00357     virtual bool loadXMLNode(size_t index, xmlNode* val, const std::string& comment);
00358     
00359     virtual unsigned int getLongestKeyLen() const;
00360     
00361     //! returns an entry matching just the prefix
00362     /*! @param[in] name the name being looked up
00363      *  @param[out] seppos the position of the separator (sub-collections are separated by '.')
00364      *  @return iterator of the sub entry*/
00365     iterator getSubEntry(const std::string& name, std::string::size_type& seppos);
00366     //! returns an entry matching just the prefix
00367     /*! @param[in] name the name being looked up
00368      *  @param[out] seppos the position of the separator (sub-collections are separated by '.')
00369      *  @return iterator of the sub entry*/
00370     const_iterator getSubEntry(const std::string& name, std::string::size_type& seppos) const;
00371 
00372     //! called after an assignment or copy to clone the objects in #myRef to perform a deep copy
00373     virtual void cloneMyRef();
00374     
00375     //! storage of entries -- mapping from keys to value pointers
00376     storage_t arr;
00377     
00378     //! objects which have been handed over to the collection for eventual de-allocation
00379     std::set<ObjectBase*> myRef;
00380     
00381     //! shorthand for the type of #comments
00382     typedef std::map<size_t,std::string> comments_t;
00383     //! storage of entry comments -- mapping from keys to help text comments for manual editing or user feedback
00384     /*! not every key necessarily has a comment! */
00385     comments_t comments;
00386   };
00387   //! provides textual output
00388   std::ostream& operator<<(std::ostream& os, const Array& d);
00389   
00390   //! specialization of Dictionary::setValue() for ObjectBase subclasses
00391   template<>
00392   inline void Dictionary::setValue(const std::string& name, const ObjectBase& val, bool warnExists) { setEntry(name,dynamic_cast<ObjectBase*>(val.clone()),warnExists); }
00393   //! specialization of Dictionary::addValue() for ObjectBase subclasses
00394   template<>
00395   inline void Dictionary::addValue(const std::string& name, const ObjectBase& val, const std::string& comment, bool warnExists/*=true*/) { addEntry(name,dynamic_cast<ObjectBase*>(val.clone()),comment,warnExists); }
00396   //! specialization of Dictionary::setValue() for char* strings
00397   template<>
00398   inline void Dictionary::setValue(const std::string& name, const char* const& val, bool warnExists) { setEntry(name,new Primitive<std::string>(val),warnExists); }
00399   //! specialization of Dictionary::addValue() for char* strings
00400   template<>
00401   inline void Dictionary::addValue(const std::string& name, const char* const& val, const std::string& comment, bool warnExists/*=true*/) { addEntry(name,new Primitive<std::string>(val),comment,warnExists); }
00402   //! specialization of Dictionary::setValue() for char* strings
00403   template<>
00404   inline void Dictionary::setValue(const std::string& name, char* const& val, bool warnExists) { setEntry(name,new Primitive<std::string>(val),warnExists); }
00405   //! specialization of Dictionary::addValue() for char* strings
00406   template<>
00407   inline void Dictionary::addValue(const std::string& name, char* const& val, const std::string& comment, bool warnExists/*=true*/) { addEntry(name,new Primitive<std::string>(val),comment,warnExists); }
00408     
00409   //! specialization of Array::addValue() for ObjectBase subclasses
00410   template<>
00411   inline void Array::addValue(const ObjectBase& val, const std::string& comment/*=""*/) { addEntry(dynamic_cast<ObjectBase*>(val.clone()),comment); }
00412   //! specialization of Array::addValue() for char* strings
00413   template<>
00414   inline void Array::addValue(const char* const& val, const std::string& comment/*=""*/) { addEntry(new Primitive<std::string>(val),comment); }
00415   //! specialization of Array::addValue() for char* strings
00416   template<>
00417   inline void Array::addValue(char* const& val, const std::string& comment/*=""*/) { addEntry(new Primitive<std::string>(val),comment); }
00418   
00419   //! specialization of Array::setValue() for ObjectBase subclasses
00420   template<>
00421   inline void Array::setValue(size_t index, const ObjectBase& val, bool warnExists) { setEntry(index,dynamic_cast<ObjectBase*>(val.clone()),warnExists); }
00422   //! specialization of Array::setValue() for char* strings
00423   template<>
00424   inline void Array::setValue(size_t index, const char* const& val, bool warnExists) { setEntry(index,new Primitive<std::string>(val),warnExists); }
00425   //! specialization of Array::setValue() for char* strings
00426   template<>
00427   inline void Array::setValue(size_t index, char* const& val, bool warnExists) { setEntry(index,new Primitive<std::string>(val),warnExists); }
00428   //! specialization of Array::addValue() for ObjectBase subclasses
00429   template<>
00430   inline void Array::addValue(size_t index, const ObjectBase& val, const std::string& comment) { addEntry(index,dynamic_cast<ObjectBase*>(val.clone()),comment); }
00431   //! specialization of Array::addValue() for char* strings
00432   template<>
00433   inline void Array::addValue(size_t index, const char* const& val, const std::string& comment) { addEntry(index,new Primitive<std::string>(val),comment); }
00434   //! specialization of Array::addValue() for char* strings
00435   template<>
00436   inline void Array::addValue(size_t index, char* const& val, const std::string& comment) { addEntry(index,new Primitive<std::string>(val),comment); }
00437   
00438   //! specialization of Array::setValue() for ObjectBase subclasses
00439   template<>
00440   inline void Array::setValue(const std::string& name, const ObjectBase& val, bool warnExists) { setEntry(name,dynamic_cast<ObjectBase*>(val.clone()),warnExists); }
00441   //! specialization of Array::setValue() for char* strings
00442   template<>
00443   inline void Array::setValue(const std::string& name, const char* const& val, bool warnExists) { setEntry(name,new Primitive<std::string>(val),warnExists); }
00444   //! specialization of Array::setValue() for char* strings
00445   template<>
00446   inline void Array::setValue(const std::string& name, char* const& val, bool warnExists) { setEntry(name,new Primitive<std::string>(val),warnExists); }
00447   //! specialization of Array::addValue() for ObjectBase subclasses
00448   template<>
00449   inline void Array::addValue(const std::string& name, const ObjectBase& val, const std::string& comment) { addEntry(name,dynamic_cast<ObjectBase*>(val.clone()),comment); }
00450   //! specialization of Array::addValue() for char* strings
00451   template<>
00452   inline void Array::addValue(const std::string& name, const char* const& val, const std::string& comment) { addEntry(name,new Primitive<std::string>(val),comment); }
00453   //! specialization of Array::addValue() for char* strings
00454   template<>
00455   inline void Array::addValue(const std::string& name, char* const& val, const std::string& comment) { addEntry(name,new Primitive<std::string>(val),comment); }
00456   
00457 } //namespace plist
00458 
00459 
00460 /*! @file
00461  * @brief 
00462  * @author Ethan Tira-Thompson (ejt) (Creator)
00463  *
00464  * $Author: ejt $
00465  * $Name: tekkotsu-3_0 $
00466  * $Revision: 1.8 $
00467  * $State: Exp $
00468  * $Date: 2006/09/19 05:39:33 $
00469  */
00470 
00471 #endif

Tekkotsu v3.0
Generated Wed Oct 4 00:03:45 2006 by Doxygen 1.4.7