// 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