// Public interface to almost all of AtlasObject. // (See AtlasObjectText for the rest of it). // // Tries to include as few headers as possible, to minimise its impact // on compile times. #ifndef ATLASOBJECT_H__ #define ATLASOBJECT_H__ #include // for wchar_t ////////////////////////////////////////////////////////////////////////// // Mostly-private bits: // Simple reference-counted pointer. class T must contain a reference count, // initialised to 0. An external implementation (in AtlasObjectImpl.cpp) // provides the inc_ref and dec_ref methods, so that this header file doesn't // need to know their implementations. template class AtSmartPtr { public: // Constructors AtSmartPtr() : ptr(NULL) {} explicit AtSmartPtr(T* p) : ptr(p) { inc_ref(); } // Copy constructor AtSmartPtr(const AtSmartPtr& r) : ptr(r.ptr) { inc_ref(); } // Assignment operators AtSmartPtr& operator=(T* p) { dec_ref(); ptr = p; inc_ref(); return *this; } AtSmartPtr& operator=(const AtSmartPtr& r) { if (&r != this) { dec_ref(); ptr = r.ptr; inc_ref(); } return *this; } // Destructor ~AtSmartPtr() { dec_ref(); } // Allow conversion from non-const T* to const T* operator AtSmartPtr () { return AtSmartPtr(ptr); } // Override -> T* operator->() const { return ptr; } // Test whether the pointer is pointing to anything operator bool() const { return ptr!=NULL; } bool operator!() const { return ptr==NULL; } private: void inc_ref(); void dec_ref(); T* ptr; }; // A few required declarations class AtObj; class AtNode; class AtIterImpl; ////////////////////////////////////////////////////////////////////////// // Public bits: // AtIter is an iterator over AtObjs - use it like: // // for (AtIter thing = whatever["thing"]; thing.defined(); ++thing) // DoStuff(thing); // // to handle XML data like: // // // Stuff 1 // Stuff 2 // class AtIter { public: // Increment the iterator; or make it undefined, if there weren't any // AtObjs left to iterate over AtIter& operator ++ (); // Return whether this iterator has an AtObj to point to bool defined() const; // Return whether this iterator is pointing to a non-contentless AtObj bool hasContent() const; // Return an iterator to the children matching 'key'. (That is, children // of the AtObj currently pointed to by this iterator) const AtIter operator [] (const char* key) const; // Return the AtObj currently pointed to by this iterator operator const AtObj () const; // Return the string value of the AtObj currently pointed to by this iterator operator const wchar_t* () const; #ifdef __WXWINDOWS__ // Wrapper function around 'operator wchar_t*', for convenience in wx programs operator const wxString () const { return (const wchar_t*)*this; } #endif // Private implementation. (But not 'private:', because it's a waste of time // adding loads of friend functions) AtSmartPtr p; }; class AtObj { public: AtObj() {} AtObj(const AtObj& r) : p(r.p) {} // Return an iterator to the children matching 'key' const AtIter operator [] (const char* key) const; // Return the string value of this object operator const wchar_t* () const; // Check whether the object contains anything (even if those things are empty) bool defined() const { return (bool)p; } // Check recursively whether there's actually any non-empty data in the object bool hasContent() const; // Add or set a child. The wchar_t* versions create a new AtObj with // the appropriate string value, then use that as the child. // // These alter the AtObj's internal pointer, and the pointed-to data is // never actually altered. Copies of this AtObj (including copies stored // inside other AtObjs) will not be affected. void add(const char* key, const wchar_t* value); void add(const char* key, AtObj& data); void set(const char* key, const wchar_t* value); void set(const char* key, AtObj& data); void setString(const wchar_t* value); AtSmartPtr p; }; // Miscellaneous utility functions: namespace AtlasObject { // Returns AtObj() on failure - test with AtObj::defined() AtObj LoadFromXML(const wchar_t* filename); // Returns false on failure bool SaveToXML(AtObj& obj, const wchar_t* filename); AtObj TrimEmptyChildren(AtObj& obj); }; #endif // ATLASOBJECT_H__