#ifndef XmlFile_H #define XmlFile_H // XmlFile.h: interface for the XmlFile class. // // Adapted from http://www.codeproject.com/cpp/xmlite.asp. // On 2004-02-09 Cho, Kyung-Min gave us permission to use and modify this // library. // // XmlFile : XML Lite Parser Library // by bro ( Cho,Kyung Min: bro@shinbiro.com ) 2002-10-30 // History. // 2002-10-29 : First Coded. Parsing XMLElelement and Attributes. // get xml parsed string ( looks good ) // 2002-10-30 : Get Node Functions, error handling ( not completed ) // 2002-12-06 : Helper Funtion string to long // 2002-12-12 : Entity Helper Support // 2003-04-08 : Close, // 2003-07=23 : add property escape_value. (now no escape on default) // fix escape functions ////////////////////////////////////////////////////////////////////// #include struct DateTime; class RageFileBasic; struct XAttr; typedef multimap XAttrs; struct XNode; typedef multimap XNodes; #define FOREACH_Attr( pNode, Var ) \ XAttrs::iterator Var##Iter; \ XAttr *Var = NULL; \ for( Var##Iter = (pNode)->m_attrs.begin(), Var = Var##Iter->second; \ Var##Iter != (pNode)->m_attrs.end(); \ ++Var##Iter, Var = Var##Iter->second ) #define FOREACH_CONST_Attr( pNode, Var ) \ XAttrs::const_iterator Var##Iter; \ const XAttr *Var = NULL; \ for( Var##Iter = (pNode)->m_attrs.begin(), Var = Var##Iter->second; \ Var##Iter != (pNode)->m_attrs.end(); \ ++Var##Iter, Var = Var##Iter->second ) #define FOREACH_Child( pNode, Var ) \ XNodes::iterator Var##Iter; \ XNode *Var = NULL; \ for( Var##Iter = (pNode)->m_childs.begin(), Var = Var##Iter->second; \ Var##Iter != (pNode)->m_childs.end(); \ ++Var##Iter, Var = Var##Iter->second ) #define FOREACH_CONST_Child( pNode, Var ) \ XNodes::const_iterator Var##Iter; \ const XNode *Var = NULL; \ for( Var##Iter = (pNode)->m_childs.begin(), Var = Var##Iter->second; \ Var##Iter != (pNode)->m_childs.end(); \ ++Var##Iter, Var = Var##Iter->second ) // Entity Encode/Decode Support struct XENTITY { char entity; // entity ( & " ' < > ) char ref[10]; // entity reference ( & " etc ) int ref_len; // entity reference length }; struct XENTITYS : public vector { XENTITY *GetEntity( int entity ); XENTITY *GetEntity( char* entity ); int GetEntityCount( const char* str ); int Ref2Entity( const char* estr, char* str, int strlen ); int Entity2Ref( const char* str, char* estr, int estrlen ); CString Ref2Entity( const char* estr ); CString Entity2Ref( const char* str ); XENTITYS(){}; XENTITYS( XENTITY *entities, int count ); }; extern XENTITYS entityDefault; CString XRef2Entity( const char* estr ); CString XEntity2Ref( const char* str ); enum PCODE { PIE_PARSE_WELFORMED = 0, PIE_ALONE_NOT_CLOSED, PIE_NOT_CLOSED, PIE_NOT_NESTED, PIE_ATTR_NO_VALUE, PIE_READ_ERROR }; // Parse info. struct PARSEINFO { bool trim_value; // [set] do trim when parse? bool entity_value; // [set] do convert from reference to entity? ( < -> < ) XENTITYS *entitys; // [set] entity table for entity decode char escape_value; // [set] escape value (default '\\') char* xml; // [get] xml source bool erorr_occur; // [get] is occurance of error? char* error_pointer; // [get] error position of xml source PCODE error_code; // [get] error code CString error_string; // [get] error string PARSEINFO() { trim_value = true; entity_value = true; entitys = &entityDefault; xml = NULL; erorr_occur = false; error_pointer = NULL; error_code = PIE_PARSE_WELFORMED; escape_value = 0; } }; extern PARSEINFO piDefault; // display optional environment struct DISP_OPT { bool newline; // newline when new tag bool reference_value; // do convert from entity to reference ( < -> < ) XENTITYS *entitys; // entity table for entity encode CString stylesheet; // empty string = no stylesheet bool write_tabs; // if false, don't write tab indent characters int tab_base; // internal usage DISP_OPT() { newline = true; reference_value = true; entitys = &entityDefault; stylesheet = ""; write_tabs = true; tab_base = 0; } }; extern DISP_OPT optDefault; // XAttr : Attribute Implementation struct XAttr { CString m_sName; // a duplicate of the m_sName in the parent's map CString m_sValue; void GetValue(CString &out) const; void GetValue(int &out) const; void GetValue(float &out) const; void GetValue(bool &out) const; void GetValue(unsigned &out) const; void GetValue(DateTime &out) const; bool GetXML( RageFileBasic &f, DISP_OPT *opt = &optDefault ); }; // XMLNode structure struct XNode { CString m_sName; // a duplicate of the m_sName in the parent's map CString m_sValue; void GetValue(CString &out) const; void GetValue(int &out) const; void GetValue(float &out) const; void GetValue(bool &out) const; void GetValue(unsigned &out) const; void GetValue(DateTime &out) const; void SetValue(int v); void SetValue(float v); void SetValue(bool v); void SetValue(unsigned v); void SetValue(const DateTime &v); // internal variables XNodes m_childs; // child node XAttrs m_attrs; // attributes // Load/Save XML char* Load( const char* pszXml, PARSEINFO *pi = &piDefault ); char* LoadAttributes( const char* pszAttrs, PARSEINFO *pi = &piDefault ); bool GetXML( RageFileBasic &f, DISP_OPT *opt = &optDefault ); bool LoadFromFile( const CString &sFile, PARSEINFO *pi = &piDefault ); bool LoadFromFile( RageFileBasic &f, PARSEINFO *pi = &piDefault ); bool SaveToFile( const CString &sFile, DISP_OPT *opt = &optDefault ); bool SaveToFile( RageFileBasic &f, DISP_OPT *opt = &optDefault ); // in own attribute list const XAttr *GetAttr( const char* attrname ) const; XAttr *GetAttr( const char* attrname ); const char* GetAttrValue( const char* attrname ); bool GetAttrValue(const char* name,CString &out) const { const XAttr* pAttr=GetAttr(name); if(pAttr==NULL) return false; pAttr->GetValue(out); return true; } bool GetAttrValue(const char* name,int &out) const { const XAttr* pAttr=GetAttr(name); if(pAttr==NULL) return false; pAttr->GetValue(out); return true; } bool GetAttrValue(const char* name,float &out) const { const XAttr* pAttr=GetAttr(name); if(pAttr==NULL) return false; pAttr->GetValue(out); return true; } bool GetAttrValue(const char* name,bool &out) const { const XAttr* pAttr=GetAttr(name); if(pAttr==NULL) return false; pAttr->GetValue(out); return true; } bool GetAttrValue(const char* name,unsigned &out) const { const XAttr* pAttr=GetAttr(name); if(pAttr==NULL) return false; pAttr->GetValue(out); return true; } bool GetAttrValue(const char* name,DateTime &out) const { const XAttr* pAttr=GetAttr(name); if(pAttr==NULL) return false; pAttr->GetValue(out); return true; } // in one level child nodes const XNode *GetChild( const char* m_sName ) const; XNode *GetChild( const char* m_sName ); const char* GetChildValue( const char* m_sName ); bool GetChildValue(const char* name,CString &out) const { const XNode* pChild=GetChild(name); if(pChild==NULL) return false; pChild->GetValue(out); return true; } bool GetChildValue(const char* name,int &out) const { const XNode* pChild=GetChild(name); if(pChild==NULL) return false; pChild->GetValue(out); return true; } bool GetChildValue(const char* name,float &out) const { const XNode* pChild=GetChild(name); if(pChild==NULL) return false; pChild->GetValue(out); return true; } bool GetChildValue(const char* name,bool &out) const { const XNode* pChild=GetChild(name); if(pChild==NULL) return false; pChild->GetValue(out); return true; } bool GetChildValue(const char* name,unsigned &out) const{ const XNode* pChild=GetChild(name); if(pChild==NULL) return false; pChild->GetValue(out); return true; } bool GetChildValue(const char* name,DateTime &out) const{ const XNode* pChild=GetChild(name); if(pChild==NULL) return false; pChild->GetValue(out); return true; } XAttr *GetChildAttr( const char* name, const char* attrname ); const char* GetChildAttrValue( const char* name, const char* attrname ); // modify DOM int GetChildCount(); XNode *AppendChild( const char* m_sName = NULL, const char* value = NULL ); XNode *AppendChild( const char* m_sName, float value ); XNode *AppendChild( const char* m_sName, int value ); XNode *AppendChild( const char* m_sName, unsigned value ); XNode *AppendChild( const char* m_sName, const DateTime &value ); XNode *AppendChild( XNode *node ); bool RemoveChild( XNode *node ); XAttr *AppendAttr( const char* m_sName = NULL, const char* value = NULL ); XAttr *AppendAttr( const char* m_sName, float value ); XAttr *AppendAttr( const char* m_sName, int value ); XAttr *AppendAttr( const char* m_sName, unsigned value ); XAttr *AppendAttr( const char* m_sName, const DateTime &value ); XAttr *AppendAttr( XAttr *attr ); bool RemoveAttr( XAttr *attr ); // creates the attribute if it doesn't already exist void SetAttrValue( const char* m_sName, const char* value ); XNode() { } ~XNode(); void Clear(); }; // Helper Funtion inline long XStr2Int( const char* str, long default_value = 0 ) { return str ? atol(str) : default_value; } bool XIsEmptyString( const char* str ); #endif