Markup.h 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483
  1. // Markup.h: interface for the CMarkup class.
  2. //
  3. #ifdef RUNTIMEDEPOT_IMPL
  4. #define RUNTIMEDEPOTDLLEXPORT _declspec(dllexport)
  5. #else
  6. #define RUNTIMEDEPOTDLLEXPORT _declspec(dllimport)
  7. #endif
  8. // Markup Release 11.5
  9. // Copyright (C) 2011 First Objective Software, Inc. All rights reserved
  10. // Go to www.firstobject.com for the latest CMarkup and EDOM documentation
  11. // Use in commercial applications requires written permission
  12. // This software is provided "as is", with no warranty.
  13. #if !defined(_MARKUP_H_INCLUDED_)
  14. #define _MARKUP_H_INCLUDED_
  15. #include <stdlib.h>
  16. #include <string.h> // memcpy, memset, strcmp...
  17. // Major build options
  18. // MARKUP_WCHAR wide char (2-byte UTF-16 on Windows, 4-byte UTF-32 on Linux and OS X)
  19. // MARKUP_MBCS ANSI/double-byte strings on Windows
  20. // MARKUP_STL (default except VC++) use STL strings instead of MFC strings
  21. // MARKUP_SAFESTR to use string _s functions in VC++ 2005 (_MSC_VER >= 1400)
  22. // MARKUP_WINCONV (default for VC++) for Windows API character conversion
  23. // MARKUP_ICONV (default for GNU) for character conversion on Linux and OS X and other platforms
  24. // MARKUP_STDCONV to use neither WINCONV or ICONV, falls back to setlocale based conversion for ANSI
  25. //
  26. #if ! defined(MARKUP_WINDOWS)
  27. #if defined(_WIN32) || defined(WIN32)
  28. #define MARKUP_WINDOWS
  29. #endif // WIN32 or _WIN32
  30. #endif // not MARKUP_WINDOWS
  31. #if _MSC_VER > 1000 // VC++
  32. #pragma once
  33. #if ! defined(MARKUP_SAFESTR) // not VC++ safe strings
  34. #pragma warning(disable:4996) // VC++ 2005 deprecated function warnings
  35. #endif // not VC++ safe strings
  36. #if defined(MARKUP_STL) && _MSC_VER < 1400 // STL pre VC++ 2005
  37. #pragma warning(disable:4786) // std::string long names
  38. #endif // VC++ 2005 STL
  39. #else // not VC++
  40. #if ! defined(MARKUP_STL)
  41. #define MARKUP_STL
  42. #endif // not STL
  43. #if defined(__GNUC__) && ! defined(MARKUP_ICONV) && ! defined(MARKUP_STDCONV) && ! defined(MARKUP_WINCONV)
  44. #if ! defined(MARKUP_WINDOWS)
  45. #define MARKUP_ICONV
  46. #endif // not Windows
  47. #endif // GNUC and not ICONV not STDCONV not WINCONV
  48. #endif // not VC++
  49. #if (defined(_UNICODE) || defined(UNICODE)) && ! defined(MARKUP_WCHAR)
  50. #define MARKUP_WCHAR
  51. #endif // _UNICODE or UNICODE
  52. #if (defined(_MBCS) || defined(MBCS)) && ! defined(MARKUP_MBCS)
  53. #define MARKUP_MBCS
  54. #endif // _MBCS and not MBCS
  55. #if ! defined(MARKUP_SIZEOFWCHAR)
  56. #if __SIZEOF_WCHAR_T__ == 4 || __WCHAR_MAX__ > 0x10000
  57. #define MARKUP_SIZEOFWCHAR 4
  58. #else // sizeof(wchar_t) != 4
  59. #define MARKUP_SIZEOFWCHAR 2
  60. #endif // sizeof(wchar_t) != 4
  61. #endif // not MARKUP_SIZEOFWCHAR
  62. #if ! defined(MARKUP_WINCONV) && ! defined(MARKUP_STDCONV) && ! defined(MARKUP_ICONV)
  63. #define MARKUP_WINCONV
  64. #endif // not WINCONV not STDCONV not ICONV
  65. #if ! defined(MARKUP_FILEBLOCKSIZE)
  66. #define MARKUP_FILEBLOCKSIZE 16384
  67. #endif
  68. // Text type and function defines (compiler and build-option dependent)
  69. //
  70. #define MCD_ACP 0
  71. #define MCD_UTF8 65001
  72. #define MCD_UTF16 1200
  73. #define MCD_UTF32 65005
  74. #if defined(MARKUP_WCHAR)
  75. #define MCD_CHAR wchar_t
  76. #define MCD_PCSZ const wchar_t*
  77. #define MCD_PSZLEN (int)wcslen
  78. #define MCD_PSZCHR wcschr
  79. #define MCD_PSZSTR wcsstr
  80. #define MCD_PSZTOL wcstol
  81. #if defined(MARKUP_SAFESTR) // VC++ safe strings
  82. #define MCD_SSZ(sz) sz,(sizeof(sz)/sizeof(MCD_CHAR))
  83. #define MCD_PSZCPY(sz,p) wcscpy_s(MCD_SSZ(sz),p)
  84. #define MCD_PSZNCPY(sz,p,n) wcsncpy_s(MCD_SSZ(sz),p,n)
  85. #define MCD_SPRINTF swprintf_s
  86. #define MCD_FOPEN(f,n,m) {if(_wfopen_s(&f,n,m)!=0)f=NULL;}
  87. #else // not VC++ safe strings
  88. #if defined(__GNUC__) && ! defined(MARKUP_WINDOWS) // non-Windows GNUC
  89. #define MCD_SSZ(sz) sz,(sizeof(sz)/sizeof(MCD_CHAR))
  90. #else // not non-Windows GNUC
  91. #define MCD_SSZ(sz) sz
  92. #endif // not non-Windows GNUC
  93. #define MCD_PSZCPY wcscpy
  94. #define MCD_PSZNCPY wcsncpy
  95. #define MCD_SPRINTF swprintf
  96. #define MCD_FOPEN(f,n,m) f=_wfopen(n,m)
  97. #endif // not VC++ safe strings
  98. #define MCD_T(s) L ## s
  99. #if MARKUP_SIZEOFWCHAR == 4 // sizeof(wchar_t) == 4
  100. #define MCD_ENC MCD_T("UTF-32")
  101. #else // sizeof(wchar_t) == 2
  102. #define MCD_ENC MCD_T("UTF-16")
  103. #endif
  104. #define MCD_CLEN(p) 1
  105. #else // not MARKUP_WCHAR
  106. #define MCD_CHAR char
  107. #define MCD_PCSZ const char*
  108. #define MCD_PSZLEN (int)strlen
  109. #define MCD_PSZCHR strchr
  110. #define MCD_PSZSTR strstr
  111. #define MCD_PSZTOL strtol
  112. #if defined(MARKUP_SAFESTR) // VC++ safe strings
  113. #define MCD_SSZ(sz) sz,(sizeof(sz)/sizeof(MCD_CHAR))
  114. #define MCD_PSZCPY(sz,p) strcpy_s(MCD_SSZ(sz),p)
  115. #define MCD_PSZNCPY(sz,p,n) strncpy_s(MCD_SSZ(sz),p,n)
  116. #define MCD_SPRINTF sprintf_s
  117. #define MCD_FOPEN(f,n,m) {if(fopen_s(&f,n,m)!=0)f=NULL;}
  118. #else // not VC++ safe strings
  119. #define MCD_SSZ(sz) sz
  120. #define MCD_PSZCPY strcpy
  121. #define MCD_PSZNCPY strncpy
  122. #define MCD_SPRINTF sprintf
  123. #define MCD_FOPEN(f,n,m) f=fopen(n,m)
  124. #endif // not VC++ safe strings
  125. #define MCD_T(s) s
  126. #if defined(MARKUP_MBCS) // MBCS/double byte
  127. #define MCD_ENC MCD_T("")
  128. #if defined(MARKUP_WINCONV)
  129. #define MCD_CLEN(p) (int)_mbclen((const unsigned char*)p)
  130. #else // not WINCONV
  131. #define MCD_CLEN(p) (int)mblen(p,MB_CUR_MAX)
  132. #endif // not WINCONV
  133. #else // not MBCS/double byte
  134. #define MCD_ENC MCD_T("UTF-8")
  135. #define MCD_CLEN(p) 1
  136. #endif // not MBCS/double byte
  137. #endif // not MARKUP_WCHAR
  138. #if _MSC_VER < 1000 // not VC++
  139. #define MCD_STRERROR strerror(errno)
  140. #endif // not VC++
  141. // String type and function defines (compiler and build-option dependent)
  142. // Define MARKUP_STL to use STL strings
  143. //
  144. #if defined(MARKUP_STL) // STL
  145. #include <string>
  146. #if defined(MARKUP_WCHAR)
  147. #define MCD_STR std::wstring
  148. #else // not MARKUP_WCHAR
  149. #define MCD_STR std::string
  150. #endif // not MARKUP_WCHAR
  151. #define MCD_2PCSZ(s) s.c_str()
  152. #define MCD_STRLENGTH(s) (int)s.size()
  153. #define MCD_STRCLEAR(s) s.erase()
  154. #define MCD_STRCLEARSIZE(s) MCD_STR t; s.swap(t)
  155. #define MCD_STRISEMPTY(s) s.empty()
  156. #define MCD_STRMID(s,n,l) s.substr(n,l)
  157. #define MCD_STRASSIGN(s,p,n) s.assign(p,n)
  158. #define MCD_STRCAPACITY(s) (int)s.capacity()
  159. #define MCD_STRINSERTREPLACE(d,i,r,s) d.replace(i,r,s)
  160. #define MCD_GETBUFFER(s,n) new MCD_CHAR[n+1]; if ((int)s.capacity()<(int)n) s.reserve(n)
  161. #define MCD_RELEASEBUFFER(s,p,n) s.replace(0,s.size(),p,n); delete[]p
  162. #define MCD_BLDRESERVE(s,n) s.reserve(n)
  163. #define MCD_BLDCHECK(s,n,d) ;
  164. #define MCD_BLDRELEASE(s) ;
  165. #define MCD_BLDAPPENDN(s,p,n) s.append(p,n)
  166. #define MCD_BLDAPPEND(s,p) s.append(p)
  167. #define MCD_BLDAPPEND1(s,c) s+=(MCD_CHAR)(c)
  168. #define MCD_BLDLEN(s) (int)s.size()
  169. #define MCD_BLDTRUNC(s,n) s.resize(n)
  170. #else // not STL, i.e. MFC
  171. // afx.h provides CString, to avoid "WINVER not defined" #include stdafh.x in Markup.cpp
  172. #include <afx.h>
  173. #define MCD_STR CString
  174. #define MCD_2PCSZ(s) ((MCD_PCSZ)s)
  175. #define MCD_STRLENGTH(s) s.GetLength()
  176. #define MCD_STRCLEAR(s) s.Empty()
  177. #define MCD_STRCLEARSIZE(s) s=MCD_STR()
  178. #define MCD_STRISEMPTY(s) s.IsEmpty()
  179. #define MCD_STRMID(s,n,l) s.Mid(n,l)
  180. #define MCD_STRASSIGN(s,p,n) memcpy(s.GetBuffer(n),p,(n)*sizeof(MCD_CHAR));s.ReleaseBuffer(n);
  181. #define MCD_STRCAPACITY(s) (((CStringData*)((MCD_PCSZ)s)-1)->nAllocLength)
  182. #define MCD_GETBUFFER(s,n) s.GetBuffer(n)
  183. #define MCD_RELEASEBUFFER(s,p,n) s.ReleaseBuffer(n)
  184. #define MCD_BLDRESERVE(s,n) MCD_CHAR*pD=s.GetBuffer(n); int nL=0
  185. #define MCD_BLDCHECK(s,n,d) if(nL+(int)(d)>n){s.ReleaseBuffer(nL);n<<=2;pD=s.GetBuffer(n);}
  186. #define MCD_BLDRELEASE(s) s.ReleaseBuffer(nL)
  187. #define MCD_BLDAPPENDN(s,p,n) MCD_PSZNCPY(&pD[nL],p,n);nL+=n
  188. #define MCD_BLDAPPEND(s,p) MCD_PSZCPY(&pD[nL],p);nL+=MCD_PSZLEN(p)
  189. #define MCD_BLDAPPEND1(s,c) pD[nL++]=(MCD_CHAR)(c)
  190. #define MCD_BLDLEN(s) nL
  191. #define MCD_BLDTRUNC(s,n) nL=n
  192. #endif // not STL
  193. #define MCD_STRTOINT(s) MCD_PSZTOL(MCD_2PCSZ(s),NULL,10)
  194. // Allow function args to accept string objects as constant string pointers
  195. struct MCD_CSTR
  196. {
  197. MCD_CSTR() { pcsz=NULL; };
  198. MCD_CSTR( MCD_PCSZ p ) { pcsz=p; };
  199. MCD_CSTR( const MCD_STR& s ) { pcsz = MCD_2PCSZ(s); };
  200. operator MCD_PCSZ() const { return pcsz; };
  201. MCD_PCSZ pcsz;
  202. };
  203. // On Linux and OS X, filenames are not specified in wchar_t
  204. #if defined(MARKUP_WCHAR) && defined(__GNUC__)
  205. #undef MCD_FOPEN
  206. #define MCD_FOPEN(f,n,m) f=fopen(n,m)
  207. #define MCD_T_FILENAME(s) s
  208. #define MCD_PCSZ_FILENAME const char*
  209. struct MCD_CSTR_FILENAME
  210. {
  211. MCD_CSTR_FILENAME() { pcsz=NULL; };
  212. MCD_CSTR_FILENAME( MCD_PCSZ_FILENAME p ) { pcsz=p; };
  213. MCD_CSTR_FILENAME( const std::string& s ) { pcsz = s.c_str(); };
  214. operator MCD_PCSZ_FILENAME() const { return pcsz; };
  215. MCD_PCSZ_FILENAME pcsz;
  216. };
  217. #else // not WCHAR GNUC
  218. #define MCD_CSTR_FILENAME MCD_CSTR
  219. #define MCD_T_FILENAME MCD_T
  220. #define MCD_PCSZ_FILENAME MCD_PCSZ
  221. #endif // not WCHAR GNUC
  222. // File fseek, ftell and offset type
  223. #if defined(__GNUC__) && ! defined(MARKUP_WINDOWS) // non-Windows GNUC
  224. #define MCD_FSEEK fseeko
  225. #define MCD_FTELL ftello
  226. #define MCD_INTFILEOFFSET off_t
  227. #elif _MSC_VER >= 1000 && defined(MARKUP_HUGEFILE) // VC++ HUGEFILE
  228. #if _MSC_VER < 1400 // before VC++ 2005
  229. extern "C" int __cdecl _fseeki64(FILE *, __int64, int);
  230. extern "C" __int64 __cdecl _ftelli64(FILE *);
  231. #endif // before VC++ 2005
  232. #define MCD_FSEEK _fseeki64
  233. #define MCD_FTELL _ftelli64
  234. #define MCD_INTFILEOFFSET __int64
  235. #else // not non-Windows GNUC or VC++ HUGEFILE
  236. #define MCD_FSEEK fseek
  237. #define MCD_FTELL ftell
  238. #define MCD_INTFILEOFFSET long
  239. #endif // not non-Windows GNUC or VC++ HUGEFILE
  240. // End of line choices: none, return, newline, or CRLF
  241. #if defined(MARKUP_EOL_NONE)
  242. #define MCD_EOL MCD_T("")
  243. #elif defined(MARKUP_EOL_RETURN) // rare; only used on some old operating systems
  244. #define MCD_EOL MCD_T("\r")
  245. #elif defined(MARKUP_EOL_NEWLINE) // Unix standard
  246. #define MCD_EOL MCD_T("\n")
  247. #elif defined(MARKUP_EOL_CRLF) || defined(MARKUP_WINDOWS) // Windows standard
  248. #define MCD_EOL MCD_T("\r\n")
  249. #else // not Windows and not otherwise specified
  250. #define MCD_EOL MCD_T("\n")
  251. #endif // not Windows and not otherwise specified
  252. #define MCD_EOLLEN (sizeof(MCD_EOL)/sizeof(MCD_CHAR)-1) // string length of MCD_EOL
  253. struct FilePos;
  254. struct TokenPos;
  255. struct NodePos;
  256. struct PathPos;
  257. struct SavedPosMapArray;
  258. struct ElemPosTree;
  259. class RUNTIMEDEPOTDLLEXPORT CMarkup
  260. {
  261. public:
  262. CMarkup() { x_InitMarkup(); SetDoc( NULL ); };
  263. CMarkup( MCD_CSTR szDoc ) { x_InitMarkup(); SetDoc( szDoc ); };
  264. CMarkup( int nFlags ) { x_InitMarkup(); SetDoc( NULL ); m_nDocFlags = nFlags; };
  265. CMarkup( const CMarkup& markup ) { x_InitMarkup(); *this = markup; };
  266. void operator=( const CMarkup& markup );
  267. ~CMarkup();
  268. // Navigate
  269. bool Load( MCD_CSTR_FILENAME szFileName );
  270. bool SetDoc( MCD_PCSZ pDoc );
  271. bool SetDoc( const MCD_STR& strDoc );
  272. bool IsWellFormed();
  273. bool FindElem( MCD_CSTR szName=NULL );
  274. // bool FindPrevElem( MCD_CSTR szName=NULL ); // undo;
  275. bool FindChildElem( MCD_CSTR szName=NULL );
  276. // bool FindPrevChildElem( MCD_CSTR szName=NULL ); // undo;
  277. bool IntoElem();
  278. bool OutOfElem();
  279. void ResetChildPos() { x_SetPos(m_iPosParent,m_iPos,0); };
  280. void ResetMainPos() { x_SetPos(m_iPosParent,0,0); };
  281. void ResetPos() { x_SetPos(0,0,0); };
  282. MCD_STR GetTagName() const;
  283. MCD_STR GetChildTagName() const { return x_GetTagName(m_iPosChild); };
  284. MCD_STR GetData() { return x_GetData(m_iPos); };
  285. MCD_STR GetChildData() { return x_GetData(m_iPosChild); };
  286. MCD_STR GetElemContent() const { return x_GetElemContent(m_iPos); };
  287. MCD_STR GetAttrib( MCD_CSTR szAttrib ) const { return x_GetAttrib(m_iPos,szAttrib); };
  288. MCD_STR GetChildAttrib( MCD_CSTR szAttrib ) const { return x_GetAttrib(m_iPosChild,szAttrib); };
  289. bool GetNthAttrib( int n, MCD_STR& strAttrib, MCD_STR& strValue ) const;
  290. MCD_STR GetAttribName( int n ) const;
  291. int FindNode( int nType=0 );
  292. int GetNodeType() { return m_nNodeType; };
  293. bool SavePos( MCD_CSTR szPosName=MCD_T(""), int nMap = 0 );
  294. bool RestorePos( MCD_CSTR szPosName=MCD_T(""), int nMap = 0 );
  295. bool SetMapSize( int nSize, int nMap = 0 );
  296. MCD_STR GetError() const;
  297. const MCD_STR& GetResult() const { return m_strResult; };
  298. int GetDocFlags() const { return m_nDocFlags; };
  299. void SetDocFlags( int nFlags ) { m_nDocFlags = (nFlags & ~(MDF_READFILE|MDF_WRITEFILE|MDF_APPENDFILE)); };
  300. enum MarkupDocFlags
  301. {
  302. MDF_UTF16LEFILE = 1,
  303. MDF_UTF8PREAMBLE = 4,
  304. MDF_IGNORECASE = 8,
  305. MDF_READFILE = 16,
  306. MDF_WRITEFILE = 32,
  307. MDF_APPENDFILE = 64,
  308. MDF_UTF16BEFILE = 128,
  309. MDF_TRIMWHITESPACE = 256,
  310. MDF_COLLAPSEWHITESPACE = 512
  311. };
  312. enum MarkupNodeFlags
  313. {
  314. MNF_WITHCDATA = 0x01,
  315. MNF_WITHNOLINES = 0x02,
  316. MNF_WITHXHTMLSPACE = 0x04,
  317. MNF_WITHREFS = 0x08,
  318. MNF_WITHNOEND = 0x10,
  319. MNF_ESCAPEQUOTES = 0x100,
  320. MNF_NONENDED = 0x100000,
  321. MNF_ILLDATA = 0x200000
  322. };
  323. enum MarkupNodeType
  324. {
  325. MNT_ELEMENT = 1, // 0x0001
  326. MNT_TEXT = 2, // 0x0002
  327. MNT_WHITESPACE = 4, // 0x0004
  328. MNT_TEXT_AND_WHITESPACE = 6, // 0x0006
  329. MNT_CDATA_SECTION = 8, // 0x0008
  330. MNT_PROCESSING_INSTRUCTION = 16, // 0x0010
  331. MNT_COMMENT = 32, // 0x0020
  332. MNT_DOCUMENT_TYPE = 64, // 0x0040
  333. MNT_EXCLUDE_WHITESPACE = 123, // 0x007b
  334. MNT_LONE_END_TAG = 128, // 0x0080
  335. MNT_NODE_ERROR = 32768 // 0x8000
  336. };
  337. // Create
  338. bool Save( MCD_CSTR_FILENAME szFileName );
  339. const MCD_STR& GetDoc() const { return m_strDoc; };
  340. bool AddElem( MCD_CSTR szName, MCD_CSTR szData=NULL, int nFlags=0 ) { return x_AddElem(szName,szData,nFlags); };
  341. bool InsertElem( MCD_CSTR szName, MCD_CSTR szData=NULL, int nFlags=0 ) { return x_AddElem(szName,szData,nFlags|MNF_INSERT); };
  342. bool AddChildElem( MCD_CSTR szName, MCD_CSTR szData=NULL, int nFlags=0 ) { return x_AddElem(szName,szData,nFlags|MNF_CHILD); };
  343. bool InsertChildElem( MCD_CSTR szName, MCD_CSTR szData=NULL, int nFlags=0 ) { return x_AddElem(szName,szData,nFlags|MNF_INSERT|MNF_CHILD); };
  344. bool AddElem( MCD_CSTR szName, int nValue, int nFlags=0 ) { return x_AddElem(szName,nValue,nFlags); };
  345. bool InsertElem( MCD_CSTR szName, int nValue, int nFlags=0 ) { return x_AddElem(szName,nValue,nFlags|MNF_INSERT); };
  346. bool AddChildElem( MCD_CSTR szName, int nValue, int nFlags=0 ) { return x_AddElem(szName,nValue,nFlags|MNF_CHILD); };
  347. bool InsertChildElem( MCD_CSTR szName, int nValue, int nFlags=0 ) { return x_AddElem(szName,nValue,nFlags|MNF_INSERT|MNF_CHILD); };
  348. bool AddAttrib( MCD_CSTR szAttrib, MCD_CSTR szValue ) { return x_SetAttrib(m_iPos,szAttrib,szValue); };
  349. bool AddChildAttrib( MCD_CSTR szAttrib, MCD_CSTR szValue ) { return x_SetAttrib(m_iPosChild,szAttrib,szValue); };
  350. bool AddAttrib( MCD_CSTR szAttrib, int nValue ) { return x_SetAttrib(m_iPos,szAttrib,nValue); };
  351. bool AddChildAttrib( MCD_CSTR szAttrib, int nValue ) { return x_SetAttrib(m_iPosChild,szAttrib,nValue); };
  352. bool AddSubDoc( MCD_CSTR szSubDoc ) { return x_AddSubDoc(szSubDoc,0); };
  353. bool InsertSubDoc( MCD_CSTR szSubDoc ) { return x_AddSubDoc(szSubDoc,MNF_INSERT); };
  354. MCD_STR GetSubDoc() { return x_GetSubDoc(m_iPos); };
  355. bool AddChildSubDoc( MCD_CSTR szSubDoc ) { return x_AddSubDoc(szSubDoc,MNF_CHILD); };
  356. bool InsertChildSubDoc( MCD_CSTR szSubDoc ) { return x_AddSubDoc(szSubDoc,MNF_CHILD|MNF_INSERT); };
  357. MCD_STR GetChildSubDoc() { return x_GetSubDoc(m_iPosChild); };
  358. bool AddNode( int nType, MCD_CSTR szText ) { return x_AddNode(nType,szText,0); };
  359. bool InsertNode( int nType, MCD_CSTR szText ) { return x_AddNode(nType,szText,MNF_INSERT); };
  360. // Modify
  361. bool RemoveElem();
  362. bool RemoveChildElem();
  363. bool RemoveNode();
  364. bool SetAttrib( MCD_CSTR szAttrib, MCD_CSTR szValue, int nFlags=0 ) { return x_SetAttrib(m_iPos,szAttrib,szValue,nFlags); };
  365. bool SetChildAttrib( MCD_CSTR szAttrib, MCD_CSTR szValue, int nFlags=0 ) { return x_SetAttrib(m_iPosChild,szAttrib,szValue,nFlags); };
  366. bool SetAttrib( MCD_CSTR szAttrib, int nValue, int nFlags=0 ) { return x_SetAttrib(m_iPos,szAttrib,nValue,nFlags); };
  367. bool SetChildAttrib( MCD_CSTR szAttrib, int nValue, int nFlags=0 ) { return x_SetAttrib(m_iPosChild,szAttrib,nValue,nFlags); };
  368. bool SetData( MCD_CSTR szData, int nFlags=0 ) { return x_SetData(m_iPos,szData,nFlags); };
  369. bool SetChildData( MCD_CSTR szData, int nFlags=0 ) { return x_SetData(m_iPosChild,szData,nFlags); };
  370. bool SetData( int nValue ) { return x_SetData(m_iPos,nValue); };
  371. bool SetChildData( int nValue ) { return x_SetData(m_iPosChild,nValue); };
  372. bool SetElemContent( MCD_CSTR szContent ) { return x_SetElemContent(szContent); };
  373. // Utility
  374. static bool ReadTextFile( MCD_CSTR_FILENAME szFileName, MCD_STR& strDoc, MCD_STR* pstrResult=NULL, int* pnDocFlags=NULL, MCD_STR* pstrEncoding=NULL );
  375. static bool WriteTextFile( MCD_CSTR_FILENAME szFileName, const MCD_STR& strDoc, MCD_STR* pstrResult=NULL, int* pnDocFlags=NULL, MCD_STR* pstrEncoding=NULL );
  376. static MCD_STR EscapeText( MCD_CSTR szText, int nFlags = 0 );
  377. static MCD_STR UnescapeText( MCD_CSTR szText, int nTextLength = -1, int nFlags = 0 );
  378. static int UTF16To8( char *pszUTF8, const unsigned short* pwszUTF16, int nUTF8Count );
  379. static int UTF8To16( unsigned short* pwszUTF16, const char* pszUTF8, int nUTF8Count );
  380. static MCD_STR UTF8ToA( MCD_CSTR pszUTF8, int* pnFailed = NULL );
  381. static MCD_STR AToUTF8( MCD_CSTR pszANSI );
  382. static void EncodeCharUTF8( int nUChar, char* pszUTF8, int& nUTF8Len );
  383. static int DecodeCharUTF8( const char*& pszUTF8, const char* pszUTF8End = NULL );
  384. static void EncodeCharUTF16( int nUChar, unsigned short* pwszUTF16, int& nUTF16Len );
  385. static int DecodeCharUTF16( const unsigned short*& pwszUTF16, const unsigned short* pszUTF16End = NULL );
  386. static bool DetectUTF8( const char* pText, int nTextLen, int* pnNonASCII = NULL, bool* bErrorAtEnd = NULL );
  387. static MCD_STR GetDeclaredEncoding( MCD_CSTR szDoc );
  388. static int GetEncodingCodePage( MCD_CSTR pszEncoding );
  389. protected:
  390. #if defined(_DEBUG)
  391. MCD_PCSZ m_pDebugCur;
  392. MCD_PCSZ m_pDebugPos;
  393. #endif // DEBUG
  394. MCD_STR m_strDoc;
  395. MCD_STR m_strResult;
  396. int m_iPosParent;
  397. int m_iPos;
  398. int m_iPosChild;
  399. int m_iPosFree;
  400. int m_iPosDeleted;
  401. int m_nNodeType;
  402. int m_nNodeOffset;
  403. int m_nNodeLength;
  404. int m_nDocFlags;
  405. FilePos* m_pFilePos;
  406. SavedPosMapArray* m_pSavedPosMaps;
  407. ElemPosTree* m_pElemPosTree;
  408. enum MarkupNodeFlagsInternal
  409. {
  410. MNF_INSERT = 0x002000,
  411. MNF_CHILD = 0x004000
  412. };
  413. #if defined(_DEBUG) // DEBUG
  414. void x_SetDebugState();
  415. #define MARKUP_SETDEBUGSTATE x_SetDebugState()
  416. #else // not DEBUG
  417. #define MARKUP_SETDEBUGSTATE
  418. #endif // not DEBUG
  419. void x_InitMarkup();
  420. void x_SetPos( int iPosParent, int iPos, int iPosChild );
  421. int x_GetFreePos();
  422. bool x_AllocElemPos( int nNewSize = 0 );
  423. int x_GetParent( int i );
  424. bool x_ParseDoc();
  425. int x_ParseElem( int iPos, TokenPos& token );
  426. int x_FindElem( int iPosParent, int iPos, PathPos& path ) const;
  427. MCD_STR x_GetPath( int iPos ) const;
  428. MCD_STR x_GetTagName( int iPos ) const;
  429. MCD_STR x_GetData( int iPos );
  430. MCD_STR x_GetAttrib( int iPos, MCD_PCSZ pAttrib ) const;
  431. static MCD_STR x_EncodeCDATASection( MCD_PCSZ szData );
  432. bool x_AddElem( MCD_PCSZ pName, MCD_PCSZ pValue, int nFlags );
  433. bool x_AddElem( MCD_PCSZ pName, int nValue, int nFlags );
  434. MCD_STR x_GetSubDoc( int iPos );
  435. bool x_AddSubDoc( MCD_PCSZ pSubDoc, int nFlags );
  436. bool x_SetAttrib( int iPos, MCD_PCSZ pAttrib, MCD_PCSZ pValue, int nFlags=0 );
  437. bool x_SetAttrib( int iPos, MCD_PCSZ pAttrib, int nValue, int nFlags=0 );
  438. bool x_AddNode( int nNodeType, MCD_PCSZ pText, int nNodeFlags );
  439. void x_RemoveNode( int iPosParent, int& iPos, int& nNodeType, int& nNodeOffset, int& nNodeLength );
  440. static bool x_CreateNode( MCD_STR& strNode, int nNodeType, MCD_PCSZ pText );
  441. int x_InsertNew( int iPosParent, int& iPosRel, NodePos& node );
  442. void x_AdjustForNode( int iPosParent, int iPos, int nShift );
  443. void x_Adjust( int iPos, int nShift, bool bAfterPos = false );
  444. void x_LinkElem( int iPosParent, int iPosBefore, int iPos );
  445. int x_UnlinkElem( int iPos );
  446. int x_UnlinkPrevElem( int iPosParent, int iPosBefore, int iPos );
  447. int x_ReleaseSubDoc( int iPos );
  448. int x_ReleasePos( int iPos );
  449. void x_CheckSavedPos();
  450. bool x_SetData( int iPos, MCD_PCSZ szData, int nFlags );
  451. bool x_SetData( int iPos, int nValue );
  452. int x_RemoveElem( int iPos );
  453. MCD_STR x_GetElemContent( int iPos ) const;
  454. bool x_SetElemContent( MCD_PCSZ szContent );
  455. void x_DocChange( int nLeft, int nReplace, const MCD_STR& strInsert );
  456. };
  457. #endif // !defined(_MARKUP_H_INCLUDED_)