// Markup.h: interface for the CMarkup class. /** @copyright CMarkup Release 6.5 Lite Copyright (C) 1999-2003 First Objective Software, Inc. All rights reserved This entire notice must be retained in this source code Redistributing this source code requires written permission This software is provided "as is", with no warranty. Latest fixes enhancements and documentation at www.firstobject.com Retrieved from codeproject.com by GJP and PSM on 08/02/05 Posted license: CMarkup Lite is free for compiling into your commercial, personal and educational applications. Modify it as much as you like, but retain the copyright notice in the source code remarks. Redistribution of the modified or unmodified CMarkup Lite class source code is limited to your own development team and it cannot be made publicly available or distributable as part of any source code library or product, even if that offering is free. * * @file CMarkup.h * @brief The CMarkup Release 6.5 Lite class with some extra functionality added. * * @author * Modifications as Noted by Lance Deaver * * $Id$ */ #ifndef MARKUP_H #define MARKUP_H //Standard C++ libraries #include #include //STL Headers: #include #include //#include //Preprocessor macros: #ifdef _T #undef _T #endif #define _T(x) x #define _tcsstr strstr #define _tcslen strlen #define _tclen(p) 1 #define _tcschr strchr #define _tcsncmp strncmp #define _tcscpy strcpy #define _tccpy(p1,p2) *(p1)=*(p2) //Type defs: typedef char TCHAR; typedef TCHAR _TCHAR; typedef const TCHAR* LPCTSTR; class CMarkup { public: // Added by Lance Deaver static CMarkup* LoadXMLFile( const std::string& xmlfilename); static std::string TrimString( const std::string& stringToTrim); // end of additions //public enumeration type (enum ill-supported by g++) class MarkupNodeType { public: const static short MNT_ELEMENT = 1; // 0x01 const static short MNT_TEXT = 2; // 0x02 const static short MNT_WHITESPACE = 4; // 0x04 const static short MNT_CDATA_SECTION = 8; // 0x08 const static short MNT_PROCESSING_INSTRUCTION = 16; // 0x10 const static short MNT_COMMENT = 32; // 0x20 const static short MNT_DOCUMENT_TYPE = 64; // 0x40 const static short MNT_EXCLUDE_WHITESPACE = 123; // 0x7b }; protected: //protected member types class ElemPos { public: //data members int nStartL; int nStartR; int nEndL; int nEndR; int nReserved; int iElemParent; int iElemChild; int iElemNext; //method members ElemPos() { Clear(); } ElemPos( const ElemPos& pos ) { *this = pos; } bool IsEmptyElement() const { return (nStartR == nEndL + 1); } void Clear() { nStartL=0; nStartR=0; nEndL=0; nEndR=0; nReserved=0; iElemParent=0; iElemChild=0; iElemNext=0; }; void AdjustStart( int n ) { nStartL+=n; nStartR+=n; } void AdjustEnd( int n ) { nEndL+=n; nEndR+=n; } }; class TokenPos { public: //data members int nL; int nR; int nNext; LPCTSTR szDoc; bool bIsString; //method members TokenPos() { Clear(); } TokenPos( LPCTSTR sz ) { Clear(); szDoc = sz; } TokenPos( const TokenPos& tkpos ) { *this = tkpos; } bool IsValid() const { return (nL <= nR); } void Clear() { nL=0; nR=-1; nNext=0; bIsString=false; } bool Match( LPCTSTR szName ) { int nLen = nR - nL + 1; return ( (strncmp( &szDoc[nL], szName, nLen ) == 0) && ( szName[nLen] == '\0' || strchr(" =/[",szName[nLen]) ) ); } }; //protected data members #ifdef _DEBUG LPCTSTR m_pMainDS; LPCTSTR m_pChildDS; #endif std::string m_csDoc; //string containing the xml document std::string m_csError; //string containing the error message std::vector< ElemPos > m_aPos; int m_iPosParent; int m_iPos; int m_iPosChild; int m_iPosFree; int m_nNodeType; //protected member methods int x_GetFreePos(); int x_ReleasePos(); int x_ParseElem( int iPos ); int x_ParseError( LPCTSTR szError, LPCTSTR szName = NULL ); static bool x_FindChar( LPCTSTR szDoc, int& nChar, _TCHAR c ); static bool x_FindAny( LPCTSTR szDoc, int& nChar ); static bool x_FindToken( TokenPos& token ); std::string x_GetToken( const TokenPos& token ) const; int x_FindElem( int iPosParent, int iPos, LPCTSTR szPath ); std::string x_GetTagName( int iPos ) const; std::string x_GetData( int iPos ) const; std::string x_GetAttrib( int iPos, LPCTSTR szAttrib ) const; bool x_AddElem( LPCTSTR szName, LPCTSTR szValue, bool bInsert, bool bAddChild ); bool x_FindAttrib( TokenPos& token, LPCTSTR szAttrib=NULL ) const; bool x_SetAttrib( int iPos, LPCTSTR szAttrib, LPCTSTR szValue ); void x_LocateNew( int iPosParent, int& iPosRel, int& nOffset, int nLength, int nFlags ); int x_ParseNode( TokenPos& token ); void x_DocChange( int nLeft, int nReplace, const std::string& csInsert ); void x_Adjust( int iPos, int nShift, bool bAfterPos = false ); std::string x_TextToDoc( LPCTSTR szText, bool bAttrib = false ) const; std::string x_TextFromDoc( int nLeft, int nRight ) const; bool x_IsEmpty(int iPos) const; void x_SetPos( int iPosParent, int iPos, int iPosChild ) { m_iPosParent = iPosParent; m_iPos = iPos; m_iPosChild = iPosChild; m_nNodeType = iPos? MarkupNodeType::MNT_ELEMENT : 0; } public: CMarkup() { SetDoc( NULL ); } // Lance DeaverAdded explicit key word to the following three constructors explicit CMarkup( LPCTSTR szDoc ) { SetDoc( szDoc ); } // explicit CMarkup( std::string szDoc ) { SetDoc( szDoc.c_str() ); } explicit CMarkup( const std::string &szDoc ) { SetDoc( szDoc.c_str() ); } // End of additions CMarkup( const CMarkup& markup ) { *this = markup; } void operator=( const CMarkup& markup ); virtual ~CMarkup() { } // Create std::string GetDoc() { return m_csDoc; } bool AddElem( LPCTSTR szName, LPCTSTR szData=NULL ) { return x_AddElem(szName,szData,false,false); } bool AddChildElem( LPCTSTR szName, LPCTSTR szData=NULL ) { return x_AddElem(szName,szData,false,true); } bool AddAttrib( LPCTSTR szAttrib, LPCTSTR szValue ) { return x_SetAttrib(m_iPos,szAttrib,szValue); } bool AddChildAttrib( LPCTSTR szAttrib, LPCTSTR szValue ) { return x_SetAttrib(m_iPosChild,szAttrib,szValue); } bool SetAttrib( LPCTSTR szAttrib, LPCTSTR szValue ) { return x_SetAttrib(m_iPos,szAttrib,szValue); } bool SetChildAttrib( LPCTSTR szAttrib, LPCTSTR szValue ) { return x_SetAttrib(m_iPosChild,szAttrib,szValue); } // Navigate bool SetDoc( LPCTSTR szDoc ); bool IsWellFormed(); bool FindElem( LPCTSTR szName=NULL ); bool FindChildElem( LPCTSTR szName=NULL ); bool IntoElem(); bool OutOfElem(); void ResetChildPos() { x_SetPos(m_iPosParent,m_iPos,0); } void ResetMainPos() { x_SetPos(m_iPosParent,0,0); } void ResetPos() { x_SetPos(0,0,0); } // Added by Lance Deaver /** * @brief Sets Internal navigation pointer just inside the document root tag * @author * -Lance Deaver * * @bug * None Known. */ void InsideRoot() { x_SetPos(1,0,0); } //End of additions // Query bool isEmpty() const { return x_IsEmpty(m_iPos); } std::string GetTagName() const; std::string GetChildTagName() const { return x_GetTagName(m_iPosChild); } std::string GetData() const { return x_GetData(m_iPos); } std::string GetChildData() const { return x_GetData(m_iPosChild); } std::string GetAttrib( LPCTSTR szAttrib ) const { return x_GetAttrib(m_iPos,szAttrib); } std::string GetChildAttrib( LPCTSTR szAttrib ) const { return x_GetAttrib(m_iPosChild,szAttrib); } std::string GetError() const { return m_csError; } }; #endif