Tekkotsu Homepage | Demos | Overview | Downloads | Dev. Resources | Reference | Credits |
XMLLoadSave.hGo to the documentation of this file.00001 //-*-c++-*- 00002 #ifndef INCLUDED_XMLLoadSave_h_ 00003 #define INCLUDED_XMLLoadSave_h_ 00004 00005 #include "LoadSave.h" 00006 00007 /*! @cond INTERNAL */ 00008 // libxml2 forward declarations 00009 extern "C" { 00010 struct _xmlNode; 00011 struct _xmlDoc; 00012 struct _xmlAttr; 00013 typedef _xmlNode xmlNode; 00014 typedef _xmlDoc xmlDoc; 00015 typedef _xmlAttr xmlAttr; 00016 } 00017 /*! @endcond */ 00018 00019 //! XMLLoadSave adds functions for XML format serialization, although if you write binary LoadSave functions as well, you can do either 00020 class XMLLoadSave : public virtual LoadSave { 00021 public: 00022 00023 //! an exception to be thrown when a bad XML file is parsed, allows file position information to be passed to the user 00024 class bad_format : public std::exception { 00025 public: 00026 //!constructor 00027 bad_format(xmlNode * node) throw() : std::exception(), node_(node), msg_("invalid format in xml data") {} 00028 //!constructor 00029 bad_format(xmlNode * node, const std::string& msg) throw() : std::exception(), node_(node), msg_(msg) {} 00030 //!copy constructor 00031 bad_format(const bad_format& bf) : std::exception(bf), node_(bf.node_), msg_(bf.msg_) {} 00032 //!assignment 00033 bad_format& operator=(const bad_format& bf) { std::exception::operator=(bf); node_=bf.node_; msg_=bf.msg_; return *this; } 00034 virtual ~bad_format() throw() {} //!< destructor 00035 virtual const char * what() const throw() { return msg_.c_str(); } //!< standard interface for getting the exception's message string 00036 virtual xmlNode * getNode() const throw() { return node_; } //!< returns the xmlNode at which the error occurred 00037 protected: 00038 xmlNode * node_; //!< the node of the error 00039 std::string msg_; //!< message regarding the type of error 00040 }; 00041 00042 XMLLoadSave(); //!< constructor 00043 XMLLoadSave(const XMLLoadSave& xls); //!< copy constructor 00044 XMLLoadSave& operator=(const XMLLoadSave& xls); //!< assignment operator 00045 virtual ~XMLLoadSave(); //!< destructor 00046 00047 //! This is called when the subclass needs to update its values from those values in the parse tree 00048 /*! @a node is the current node in the tree -- it may be the root, but it 00049 * may also be a subnode within the tree if a recursive structure is used */ 00050 virtual void loadXML(xmlNode* node)=0; 00051 //! This is called when XMLLoadSave needs to have the subclass update values in the tree currently in memory -- may already be filled out by previous contents 00052 /*! @a node is the current node in the tree -- it may be the root, but it 00053 * may also be a subnode within the tree if a recursive structure is used */ 00054 virtual void saveXML(xmlNode * node) const=0; 00055 00056 virtual unsigned int getBinSize() const; 00057 virtual unsigned int loadBuffer(const char buf[], unsigned int len, const char* filename=NULL); 00058 virtual unsigned int saveBuffer(char buf[], unsigned int len) const; 00059 00060 virtual unsigned int loadFile(const char* filename); 00061 virtual unsigned int saveFile(const char* filename) const; 00062 00063 virtual unsigned int loadFileStream(FILE* f, const char* filename=NULL); 00064 virtual unsigned int saveFileStream(FILE* f) const; 00065 00066 //! loads from a std::istream, optionally cleaning up stream to allow additional loads if @a asFragment is true 00067 virtual unsigned int loadStream(std::istream& is, bool asFragment=false); 00068 00069 //! saves to a std::ostream, optionally skipping xml document header if @a asFragment is true 00070 virtual unsigned int saveStream(std::ostream& os, bool asFragment) const; 00071 virtual unsigned int saveStream(std::ostream& os) const { return saveStream(os,false); } 00072 00073 //! resets the parse tree currently in memory so that a future save will write a "fresh" copy from scratch. 00074 /*! You may also want to call this in order to save memory after a Load so that 00075 * the parse tree information isn't retained in memory if you don't care about 00076 * retaining the file formatting */ 00077 virtual void clearParseTree(); 00078 00079 //! assigns a parse tree which you have obtained from some other source 00080 /*! This doesn't update the contents of the subclass's values. The values in 00081 * @a doc will be overwritten by those in the subclass on the next Save. 00082 * If you wish to have the subclass's values updated from @a doc, call 00083 * readParseTree() after calling this. */ 00084 virtual void setParseTree(xmlDoc* doc) const; 00085 00086 //! returns the current parse tree, either from a previous Load, Save, or setParseTree() 00087 virtual xmlDoc* getParseTree() const { return xmldocument; } 00088 00089 //! sets the object's parse tree to NULL and returns the former tree, which is then caller's responisibility 00090 virtual xmlDoc* stealParseTree(xmlDoc* newdoc=NULL) const; 00091 00092 //! calls loadXML with the root of the current parse tree 00093 virtual void readParseTree(); 00094 //! calls saveXML with the root of the current parse tree 00095 virtual void writeParseTree() const; 00096 00097 //! allows you to set the compression level used by libxml2 -- this corresponds to the compression level setting of zlib, i.e. 0-9 00098 virtual void setCompression(int level); 00099 //! returns the current compression level setting used by libxml2 (via zlib) 00100 virtual int getCompression() const { return compressionLevel; } 00101 00102 protected: 00103 //! returns the root element of the xml document 00104 virtual xmlNode* FindRootXMLElement(xmlDoc* doc) const; 00105 00106 //! cleans up after an error occurs and sends a message to cerr 00107 void reportError(const std::string& context, const bad_format& err) const; 00108 00109 //! called by libxml2 when it's ready for more data to be read from the source (in this case, a file) 00110 static int fileReadCallback(void* f,char* buf, int len); 00111 //! called by libxml2 when it's done reading data 00112 static int fileCloseCallback(void* f); 00113 00114 //! returns the next element following @a cur 00115 /*! You should call this with node->next, otherwise you'll just keep getting the same node back again */ 00116 static xmlNode* skipToElement(xmlNode* cur); 00117 00118 //! returns the next element following @a cur; comment is set to the concatination of any comments is encountered in the interim 00119 /*! You should call this with node->next, otherwise you'll just keep getting the same node back again */ 00120 static xmlNode* skipToElement(xmlNode* cur, std::string& comment); 00121 00122 //! the cached xml parse tree -- contains additional formatting information such as white space and comments 00123 mutable xmlDoc* xmldocument; 00124 00125 //! the current compression level, or level to be used for the next save 00126 int compressionLevel; 00127 00128 //! if true, the saved document will use automatic indenting and formatting 00129 bool autoFormat; 00130 00131 //static const char * const base64="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; 00132 00133 //! allows automatic (de)initialization of libxml when the first or last XMLLoadSave class is created or destroyed 00134 class AutoInit { 00135 public: 00136 AutoInit(); //!< if #libxmlrefc is 0, calls libxml2 initialization and configuration functions 00137 ~AutoInit(); //!< if #libxmlrefc is 1, calls libxml2 destruction functions 00138 protected: 00139 static unsigned int libxmlrefc; //!< current number of XMLLoadSave subclass instances 00140 } libxmlInit; //!< allows tracking of libxml usage so the library can be initialized and destructed automatically 00141 00142 }; 00143 00144 /*! @file 00145 * @brief 00146 * @author Ethan Tira-Thompson (ejt) (Creator) 00147 */ 00148 00149 #endif |
Tekkotsu v5.1CVS |
Generated Mon May 9 04:58:53 2016 by Doxygen 1.6.3 |