Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenxmlstorage.h
Go to the documentation of this file.
00001 00002 // 00003 // XML storage C++ classes version 1.3 00004 // 00005 // Copyright (c) 2004, 2005, 2006, 2007, 2008, 2009, 2010 Martin Fuchs <martin-fuchs@gmx.net> 00006 // 00007 00010 00011 00012 /* 00013 00014 All rights reserved. 00015 00016 Redistribution and use in source and binary forms, with or without 00017 modification, are permitted provided that the following conditions are met: 00018 00019 * Redistributions of source code must retain the above copyright 00020 notice, this list of conditions and the following disclaimer. 00021 * Redistributions in binary form must reproduce the above copyright 00022 notice, this list of conditions and the following disclaimer in 00023 the documentation and/or other materials provided with the 00024 distribution. 00025 00026 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00027 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00028 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00029 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 00030 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 00031 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 00032 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 00033 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 00034 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 00035 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00036 POSSIBILITY OF SUCH DAMAGE. 00037 00038 */ 00039 00040 #ifndef _XMLSTORAGE_H 00041 00042 00043 #ifdef UNICODE 00044 #ifndef _UNICODE 00045 #define _UNICODE 00046 #endif 00047 #else 00048 #ifdef _UNICODE 00049 #define UNICODE 00050 #endif 00051 #endif 00052 00053 #ifndef _WIN32 00054 #ifdef UNICODE 00055 #error no UNICODE build in Unix version available 00056 #endif 00057 #ifndef XS_STRING_UTF8 00058 #define XS_STRING_UTF8 00059 #endif 00060 #endif 00061 00062 00063 #if _MSC_VER>=1400 // VS2005 or higher 00064 #ifndef _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES 00065 #define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES 1 00066 #define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_COUNT 1 00067 #define _CRT_SECURE_CPP_OVERLOAD_SECURE_NAMES 1 00068 #endif 00069 #endif 00070 00071 00072 #ifdef XS_USE_XERCES 00073 00074 #ifndef UNICODE 00075 #ifndef XS_STRING_UTF8 00076 #define XS_STRING_UTF8 00077 #endif 00078 #endif 00079 00080 #include <xercesc/parsers/SAXParser.hpp> 00081 #include <xercesc/sax/HandlerBase.hpp> 00082 00083 using XERCES_CPP_NAMESPACE_QUALIFIER Locator; 00084 using XERCES_CPP_NAMESPACE_QUALIFIER SAXParser; 00085 using XERCES_CPP_NAMESPACE_QUALIFIER HandlerBase; 00086 using XERCES_CPP_NAMESPACE_QUALIFIER InputSource; 00087 using XERCES_CPP_NAMESPACE_QUALIFIER AttributeList; 00088 using XERCES_CPP_NAMESPACE_QUALIFIER SAXParseException; 00089 00090 typedef XMLCh XML_Char; 00091 00092 #elif defined(XS_USE_EXPAT) 00093 00094 #include <expat/expat.h> 00095 00096 #endif 00097 00098 00099 #ifdef _MSC_VER 00100 #pragma warning(disable: 4786) 00101 00102 #ifndef XS_NO_COMMENT 00103 00104 #ifdef XS_USE_XERCES 00105 #ifdef _DEBUG 00106 #pragma comment(lib, "xerces-c_2D") 00107 #else 00108 #pragma comment(lib, "xerces-c_2") 00109 #endif 00110 #elif defined(XS_USE_EXPAT) 00111 #ifdef XML_STATIC 00112 #ifndef _DEBUG 00113 #pragma comment(lib, "libexpatMT") 00114 #endif 00115 #else 00116 #pragma comment(lib, "libexpat") 00117 #endif 00118 #endif 00119 00120 #ifndef _STRING_DEFINED // _STRING_DEFINED only allowed if using xmlstorage.cpp embedded in the project 00121 #if defined(_DEBUG) && defined(_DLL) // DEBUG version only supported with MSVCRTD 00122 #if _MSC_VER==1500 00123 #pragma comment(lib, "xmlstorage-vc9d") 00124 #elif _MSC_VER==1400 00125 #pragma comment(lib, "xmlstorage-vc8d") 00126 #else 00127 #pragma comment(lib, "xmlstorage-vc6d") 00128 #endif 00129 #else 00130 #ifdef _DLL 00131 #if _MSC_VER==1500 00132 #pragma comment(lib, "xmlstorage-vc9") 00133 #elif _MSC_VER==1400 00134 #pragma comment(lib, "xmlstorage-vc8") 00135 #else 00136 #pragma comment(lib, "xmlstorage-vc6") 00137 #endif 00138 #elif defined(_MT) 00139 #if _MSC_VER==1500 00140 #pragma comment(lib, "xmlstorage-vc9t") 00141 #elif _MSC_VER==1400 00142 #pragma comment(lib, "xmlstorage-vc8t") 00143 #else 00144 #pragma comment(lib, "xmlstorage-vc6t") 00145 #endif 00146 #else 00147 // -ML is no more supported since VS2005. 00148 #pragma comment(lib, "xmlstorage-vc6l") 00149 #endif 00150 #endif 00151 #endif // _STRING_DEFINED 00152 00153 #endif // XS_NO_COMMENT 00154 00155 #endif // _MSC_VER 00156 00157 00158 #ifdef _WIN32 00159 00160 #include <windows.h> // for LPCTSTR 00161 #include <tchar.h> 00162 #include <malloc.h> 00163 00164 #ifndef _MSC_VER 00165 #include <stdio.h> // vsnprintf(), snprintf() 00166 #endif 00167 00168 #else // _WIN32 00169 00170 #include <wchar.h> 00171 #include <stdlib.h> 00172 #include <string.h> // strcasecmp() 00173 #include <stdarg.h> 00174 00175 typedef char CHAR; 00176 #ifdef _WCHAR_T_DEFINED 00177 #define __wchar_t wchar_t 00178 #endif 00179 00180 typedef __wchar_t WCHAR; 00181 typedef unsigned char UCHAR; 00182 typedef char* LPSTR; 00183 typedef const char* LPCSTR; 00184 typedef WCHAR* LPWSTR; 00185 typedef const WCHAR* LPCWSTR; 00186 00187 #ifndef UNICODE 00188 #define TEXT(x) x 00189 typedef char TCHAR; 00190 typedef unsigned char _TUCHAR; 00191 typedef CHAR* PTSTR; 00192 typedef CHAR* LPTSTR; 00193 typedef const CHAR* LPCTSTR; 00194 00195 #define _ttoi atoi 00196 #define _tfopen fopen 00197 #define _tcstod strtod 00198 #define _tcslen strlen 00199 #define _tcsstr strstr 00200 #define _snprintf snprintf 00201 #define _sntprintf snprintf 00202 #define _vsnprintf vsnprintf 00203 #define _vsntprintf vsnprintf 00204 #define _stricmp strcasecmp 00205 #define _tcsicmp strcasecmp 00206 #define strnicmp strncasecmp 00207 #define _tcsnicmp strncasecmp 00208 #endif // UNICODE 00209 00210 #endif // _WIN32 00211 00212 #ifdef __BORLANDC__ 00213 #define _stricmp stricmp 00214 #endif 00215 00216 00217 #include <fstream> 00218 #include <sstream> 00219 #include <string> 00220 #include <stack> 00221 #include <list> 00222 #include <map> 00223 00224 00225 #ifndef BUFFER_LEN 00226 #define BUFFER_LEN 2048 00227 #endif 00228 00229 00230 namespace XMLStorage { 00231 00232 00233 #ifndef XS_String 00234 00235 #ifdef XS_STRING_UTF8 00236 #define XS_CHAR char 00237 #define XS_TEXT(x) x 00238 #define LPXSSTR LPSTR 00239 #define LPCXSSTR LPCSTR 00240 #define XS_cmp strcmp 00241 #define XS_icmp _stricmp 00242 #define XS_ncmp strncmp 00243 #define XS_nicmp strnicmp 00244 #define XS_toi atoi 00245 #define XS_tod strtod 00246 #define XS_len strlen 00247 #define XS_snprintf _snprintf 00248 #define XS_vsnprintf _vsnprintf 00249 #define XS_strstr strstr 00250 #else 00251 #define XS_CHAR TCHAR 00252 #define XS_TEXT(x) TEXT(x) 00253 #define LPXSSTR LPTSTR 00254 #define LPCXSSTR LPCTSTR 00255 #define XS_cmp _tcscmp 00256 #define XS_icmp _tcsicmp 00257 #define XS_ncmp _tcsncmp 00258 #define XS_nicmp _tcsnicmp 00259 #define XS_toi _ttoi 00260 #define XS_tod _tcstod 00261 #define XS_len _tcslen 00262 #define XS_snprintf _sntprintf 00263 #define XS_vsnprintf _vsntprintf 00264 #define XS_strstr _tcsstr 00265 #endif 00266 00267 #ifndef COUNTOF 00268 #if _MSC_VER>=1400 00269 #define COUNTOF _countof 00270 #else 00271 #define COUNTOF(b) (sizeof(b)/sizeof(b[0])) 00272 #endif 00273 #endif 00274 00275 00276 extern const char* get_xmlsym_end_utf8(const char* p); 00277 00278 00279 #if defined(_STRING_DEFINED) && !defined(XS_STRING_UTF8) 00280 00281 #define XS_String String 00282 00283 #else // _STRING_DEFINED, !XS_STRING_UTF8 00284 00286 00287 struct XS_String 00288 #if defined(UNICODE) && !defined(XS_STRING_UTF8) 00289 : public std::wstring 00290 #else 00291 : public std::string 00292 #endif 00293 { 00294 #if defined(UNICODE) && !defined(XS_STRING_UTF8) 00295 typedef std::wstring super; 00296 #else 00297 typedef std::string super; 00298 #endif 00299 00300 XS_String() {} 00301 00302 XS_String(LPCXSSTR s) {if (s) super::assign(s);} 00303 XS_String(LPCXSSTR s, size_t l) : super(s, l) {} 00304 00305 XS_String(const super& other) : super(other) {} 00306 XS_String(const XS_String& other) : super(other) {} 00307 00308 #ifdef _WIN32 00309 #if defined(UNICODE) && !defined(XS_STRING_UTF8) 00310 XS_String(LPCSTR s) {assign(s);} 00311 XS_String(LPCSTR s, size_t l) {assign(s, l);} 00312 XS_String(const std::string& s) {assign(s.c_str());} 00313 XS_String& operator=(LPCSTR s) {assign(s); return *this;} 00314 void assign(LPCSTR s) {if (s) {size_t bl=strlen(s); LPWSTR b=(LPWSTR)alloca(sizeof(WCHAR)*bl); super::assign(b, MultiByteToWideChar(CP_ACP, 0, s, bl, b, bl));} else erase();} 00315 void assign(LPCSTR s, size_t l) {if (s) {size_t bl=l; LPWSTR b=(LPWSTR)alloca(sizeof(WCHAR)*bl); super::assign(b, MultiByteToWideChar(CP_ACP, 0, s, l, b, bl));} else erase();} 00316 #else 00317 XS_String(LPCWSTR s) {assign(s);} 00318 XS_String(LPCWSTR s, size_t l) {assign(s, l);} 00319 XS_String(const std::wstring& ws) {assign(ws.c_str());} 00320 XS_String& operator=(LPCWSTR s) {assign(s); return *this;} 00321 #ifdef XS_STRING_UTF8 00322 void assign(LPCWSTR s) {if (s) {size_t bl=wcslen(s); LPSTR b=(LPSTR)alloca(bl); super::assign(b, WideCharToMultiByte(CP_UTF8, 0, s, (int)bl, b, (int)bl, 0, 0));} else erase();} 00323 void assign(LPCWSTR s, size_t l) {size_t bl=l; if (s) {LPSTR b=(LPSTR)alloca(bl); super::assign(b, WideCharToMultiByte(CP_UTF8, 0, s, (int)l, b, (int)bl, 0, 0));} else erase();} 00324 #else // if !UNICODE && !XS_STRING_UTF8 00325 void assign(LPCWSTR s) {if (s) {size_t bl=wcslen(s); LPSTR b=(LPSTR)alloca(bl); super::assign(b, WideCharToMultiByte(CP_ACP, 0, s, (int)bl, b, (int)bl, 0, 0));} else erase();} 00326 void assign(LPCWSTR s, size_t l) {size_t bl=l; if (s) {LPSTR b=(LPSTR)alloca(bl); super::assign(b, WideCharToMultiByte(CP_ACP, 0, s, (int)l, b, (int)bl, 0, 0));} else erase();} 00327 #endif 00328 #endif 00329 #endif // _WIN32 00330 00331 #ifdef __ISSD_H 00332 // XS_String(const _ISSD RString& s) {assign(s.c_str());} 00333 // void assign(const _ISSD RString& s) {assign(s.c_str());} 00334 XS_String& operator=(const _ISSD RString& s) {assign(s); return *this;} 00335 #endif 00336 00337 #ifdef XS_STRING_UTF8 00338 void assign(const XS_String& s) {assign(s.c_str());} 00339 #endif 00340 00341 XS_String& operator=(LPCXSSTR s) {if (s) super::assign(s); else erase(); return *this;} 00342 XS_String& operator=(const super& s) {super::assign(s); return *this;} 00343 void assign(LPCXSSTR s) {super::assign(s);} 00344 void assign(LPCXSSTR s, size_t l) {super::assign(s, l);} 00345 00346 operator LPCXSSTR() const {return c_str();} 00347 00348 #ifdef _WIN32 00349 #ifdef XS_STRING_UTF8 00350 operator std::wstring() const {size_t bl=length(); LPWSTR b=(LPWSTR)alloca(sizeof(WCHAR)*bl); return std::wstring(b, MultiByteToWideChar(CP_UTF8, 0, c_str(), bl, b, bl));} 00351 #elif defined(UNICODE) 00352 operator std::string() const {size_t bl=length(); LPSTR b=(LPSTR)alloca(bl); return std::string(b, WideCharToMultiByte(CP_ACP, 0, c_str(), bl, b, bl, 0, 0));} 00353 #else 00354 operator std::wstring() const {size_t bl=length(); LPWSTR b=(LPWSTR)alloca(sizeof(WCHAR)*bl); return std::wstring(b, MultiByteToWideChar(CP_ACP, 0, c_str(), (int)bl, b, (int)bl));} 00355 #endif 00356 #endif 00357 00358 XS_String& printf(LPCXSSTR fmt, ...) 00359 { 00360 va_list l; 00361 XS_CHAR b[BUFFER_LEN]; 00362 00363 va_start(l, fmt); 00364 super::assign(b, XS_vsnprintf(b, COUNTOF(b), fmt, l)); 00365 va_end(l); 00366 00367 return *this; 00368 } 00369 00370 XS_String& vprintf(LPCXSSTR fmt, va_list l) 00371 { 00372 XS_CHAR b[BUFFER_LEN]; 00373 00374 super::assign(b, XS_vsnprintf(b, COUNTOF(b), fmt, l)); 00375 00376 return *this; 00377 } 00378 00379 XS_String& appendf(LPCXSSTR fmt, ...) 00380 { 00381 va_list l; 00382 XS_CHAR b[BUFFER_LEN]; 00383 00384 va_start(l, fmt); 00385 super::append(b, XS_vsnprintf(b, COUNTOF(b), fmt, l)); 00386 va_end(l); 00387 00388 return *this; 00389 } 00390 00391 XS_String& vappendf(LPCXSSTR fmt, va_list l) 00392 { 00393 XS_CHAR b[BUFFER_LEN]; 00394 00395 super::append(b, XS_vsnprintf(b, COUNTOF(b), fmt, l)); 00396 00397 return *this; 00398 } 00399 }; 00400 00401 #endif // _STRING_DEFINED, !XS_STRING_UTF8 00402 00403 #endif // XS_String 00404 00405 00406 #define XS_EMPTY_STR XS_TEXT("") 00407 #define XS_TRUE_STR XS_TEXT("true") 00408 #define XS_FALSE_STR XS_TEXT("false") 00409 #define XS_INTFMT_STR XS_TEXT("%d") 00410 #define XS_FLOATFMT_STR XS_TEXT("%f") 00411 00412 #define XS_KEY_STR XS_TEXT("key") 00413 #define XS_VALUE_STR XS_TEXT("value") 00414 #define XS_PROPERTY_STR XS_TEXT("property") 00415 00416 // work around GCC's wide string constant bug 00417 #ifdef __GNUC__ 00418 extern const LPCXSSTR XS_EMPTY; 00419 extern const LPCXSSTR XS_TRUE; 00420 extern const LPCXSSTR XS_FALSE; 00421 extern const LPCXSSTR XS_INTFMT; 00422 extern const LPCXSSTR XS_FLOATFMT; 00423 #else 00424 #define XS_EMPTY XS_EMPTY_STR 00425 #define XS_TRUE XS_TRUE_STR 00426 #define XS_FALSE XS_FALSE_STR 00427 #define XS_INTFMT XS_INTFMT_STR 00428 #define XS_FLOATFMT XS_FLOATFMT_STR 00429 #endif 00430 00431 extern const XS_String XS_KEY; 00432 extern const XS_String XS_VALUE; 00433 extern const XS_String XS_PROPERTY; 00434 00435 #define CDATA_START "<![CDATA[" 00436 #define CDATA_END "]]>" 00437 00438 00439 #ifndef XS_STRING_UTF8 00440 00441 // from UTF-8 to XS internal string encoding 00442 inline void assign_utf8(XS_String& s, const char* str, size_t lutf8) 00443 { 00444 #ifdef UNICODE 00445 LPTSTR buffer = (LPTSTR)alloca(sizeof(TCHAR)*lutf8); 00446 int l = MultiByteToWideChar(CP_UTF8, 0, str, (int)lutf8, buffer, (int)lutf8); 00447 #else 00448 LPWSTR wbuffer = (LPWSTR)alloca(sizeof(WCHAR)*lutf8); 00449 int l = MultiByteToWideChar(CP_UTF8, 0, str, (int)lutf8, wbuffer, (int)lutf8); 00450 00451 int bl=2*l; LPSTR buffer = (LPSTR)alloca(bl); 00452 l = WideCharToMultiByte(CP_ACP, 0, wbuffer, l, buffer, bl, 0, 0); 00453 #endif 00454 00455 s.assign(buffer, l); 00456 } 00457 00458 // from UTF-8 to XS internal string encoding 00459 inline void assign_utf8(XS_String& s, const char* str) 00460 { 00461 assign_utf8(s, str, strlen(str)); 00462 } 00463 00464 // from XS internal string encoding to UTF-8 00465 inline std::string get_utf8(LPCTSTR s, size_t l) 00466 { 00467 #ifdef UNICODE 00468 size_t bl=2*l; LPSTR buffer = (LPSTR)alloca(bl); 00469 l = WideCharToMultiByte(CP_UTF8, 0, s, (int)l, buffer, (int)bl, 0, 0); 00470 #else 00471 LPWSTR wbuffer = (LPWSTR)alloca(sizeof(WCHAR)*l); 00472 l = MultiByteToWideChar(CP_ACP, 0, s, (int)l, wbuffer, (int)l); 00473 00474 size_t bl=2*l; LPSTR buffer = (LPSTR)alloca(bl); 00475 l = WideCharToMultiByte(CP_UTF8, 0, wbuffer, (int)l, buffer, (int)bl, 0, 0); 00476 #endif 00477 00478 return std::string(buffer, l); 00479 } 00480 00481 #ifdef UNICODE 00482 // from XS internal string encoding to UTF-8 00483 inline std::string get_utf8(const char* s, size_t l) 00484 { 00485 LPWSTR wbuffer = (LPWSTR)alloca(sizeof(WCHAR)*l); 00486 l = MultiByteToWideChar(CP_ACP, 0, s, (int)l, wbuffer, (int)l); 00487 00488 size_t bl=2*l; LPSTR buffer = (LPSTR)alloca(bl); 00489 l = WideCharToMultiByte(CP_UTF8, 0, wbuffer, (int)l, buffer, (int)bl, 0, 0); 00490 00491 return std::string(buffer, l); 00492 } 00493 #endif 00494 00495 // from XS internal string encoding to UTF-8 00496 inline std::string get_utf8(const XS_String& s) 00497 { 00498 return get_utf8(s.c_str(), s.length()); 00499 } 00500 00501 #endif // XS_STRING_UTF8 00502 00503 extern std::string EncodeXMLString(const XS_String& str, bool cdata=false); 00504 extern XS_String DecodeXMLString(const std::string& str); 00505 00506 00507 #ifdef __GNUC__ 00508 #include <ext/stdio_filebuf.h> 00509 #define FILE_FILEBUF __gnu_cxx::stdio_filebuf<char> 00510 #elif defined(_MSC_VER) 00511 #define FILE_FILEBUF std::filebuf 00512 #endif 00513 00514 #ifdef FILE_FILEBUF 00515 00517 struct FileHolder 00518 { 00519 FileHolder(LPCTSTR path, LPCTSTR mode) 00520 { 00521 //@@ _MS_VER: temporarily needed for the ReactOS build environment 00522 #if defined(__STDC_WANT_SECURE_LIB__) && defined(_MS_VER) // secure CRT functions using VS 2005 00523 if (_tfopen_s(&_pfile, path, mode) != 0) 00524 _pfile = NULL; 00525 #else 00526 _pfile = _tfopen(path, mode); 00527 #endif 00528 } 00529 00530 ~FileHolder() 00531 { 00532 if (_pfile) 00533 fclose(_pfile); 00534 } 00535 00536 protected: 00537 FILE* _pfile; 00538 }; 00539 00541 struct tifstream : public std::istream, FileHolder 00542 { 00543 typedef std::istream super; 00544 00545 tifstream(LPCTSTR path) 00546 : super(&_buf), 00547 FileHolder(path, TEXT("rb")), // binary mode is important for XMLReader::read_buffer() with MinGW libraries 00548 #ifdef __GNUC__ 00549 _buf(_pfile, std::ios::in) 00550 #else 00551 _buf(_pfile) 00552 #endif 00553 { 00554 if (!_pfile) 00555 setstate(badbit); 00556 } 00557 00558 protected: 00559 FILE_FILEBUF _buf; 00560 }; 00561 00563 struct tofstream : public std::ostream, FileHolder 00564 { 00565 typedef std::ostream super; 00566 00567 tofstream(LPCTSTR path) 00568 : super(&_buf), 00569 FileHolder(path, TEXT("wb")), 00570 #ifdef __GNUC__ 00571 _buf(_pfile, std::ios::out) 00572 #else 00573 _buf(_pfile) 00574 #endif 00575 { 00576 if (!_pfile) 00577 setstate(badbit); 00578 } 00579 00580 ~tofstream() 00581 { 00582 flush(); 00583 } 00584 00585 protected: 00586 FILE_FILEBUF _buf; 00587 }; 00588 00589 #else // FILE_FILEBUF 00590 00591 #ifdef UNICODE 00592 #error UNICODE not supported for this platform 00593 #endif 00594 00595 struct tifstream : public std::ifstream 00596 { 00597 typedef std::ifstream super; 00598 00599 tifstream(const char* path) 00600 : super(path, std::ios::in|std::ios::binary) 00601 { 00602 } 00603 }; 00604 00605 struct tofstream : public std::ofstream 00606 { 00607 typedef std::ofstream super; 00608 00609 tofstream(const char* path) 00610 : super(path, std::ios::out|std::ios::binary) 00611 { 00612 } 00613 }; 00614 00615 #endif 00616 00617 00618 // write XML files with 2 spaces indenting 00619 #define XML_INDENT_SPACE " " 00620 00621 00622 #if defined(XS_USE_XERCES) || defined(XS_USE_EXPAT) 00623 00624 #if defined(XML_UNICODE)/*Expat*/ || defined(XS_USE_XERCES)/*Xerces*/ // Are Expat/Xerces XML strings UTF-16 encoded? 00625 typedef XS_String String_from_XML_Char; 00626 00627 #elif defined(XS_STRING_UTF8) 00628 typedef XS_String String_from_XML_Char; 00629 00630 #else 00631 00633 struct String_from_XML_Char : public XS_String 00634 { 00635 String_from_XML_Char(const XML_Char* str) 00636 { 00637 assign_utf8(*this, str); 00638 } 00639 }; 00640 00641 #endif 00642 00643 #endif // defined(XS_USE_XERCES) || defined(XS_USE_EXPAT) 00644 00645 00646 #if defined(UNICODE) && !defined(XS_STRING_UTF8) 00647 00648 // optimization for faster UNICODE/ASCII string comparison without temporary A/U conversion 00649 inline bool operator==(const XS_String& s1, const char* s2) 00650 { 00651 LPCWSTR p = s1; 00652 const unsigned char* q = (const unsigned char*)s2; 00653 00654 while(*p && *q) 00655 if (*p++ != *q++) 00656 return false; 00657 00658 return *p == *q; 00659 }; 00660 00661 #endif 00662 00663 00665 struct XMLError 00666 { 00667 XMLError() 00668 : _line(0), 00669 _column(0), 00670 _error_code(0) 00671 { 00672 } 00673 00674 std::string str() const; 00675 friend std::ostream& operator<<(std::ostream&, const XMLError& err); 00676 00677 XS_String _message; 00678 XS_String _systemId; 00679 int _line; 00680 int _column; 00681 int _error_code; 00682 }; 00683 00685 struct XMLErrorList : public std::list<XMLError> 00686 { 00687 XS_String str() const; 00688 }; 00689 00690 00691 #ifdef XMLNODE_LOCATION 00692 00693 struct XMLLocation 00694 { 00695 XMLLocation() 00696 : _pdisplay_path(NULL), 00697 _line(0), 00698 _column(0) 00699 { 00700 } 00701 00702 XMLLocation(const char* display_path, int line, int column) 00703 : _pdisplay_path(display_path), 00704 _line(line), 00705 _column(column) 00706 { 00707 } 00708 00709 std::string str() const; 00710 00711 protected: 00712 const char* _pdisplay_path; // character pointer for fast reference 00713 int _line; 00714 int _column; 00715 }; 00716 #endif 00717 00718 00719 enum PRETTY_FLAGS { 00720 PRETTY_PLAIN = 0, 00721 PRETTY_LINEFEED = 1, 00722 PRETTY_INDENT = 2 00723 }; 00724 00725 00727 struct StyleSheet 00728 { 00729 std::string _href; // CDATA #REQUIRED 00730 std::string _type; // CDATA #REQUIRED 00731 std::string _title; // CDATA #IMPLIED 00732 std::string _media; // CDATA #IMPLIED 00733 std::string _charset; // CDATA #IMPLIED 00734 bool _alternate; // (yes|no) "no" 00735 00736 StyleSheet() : _alternate(false) {} 00737 00738 StyleSheet(const std::string& href, const std::string& type="text/xsl", bool alternate=false) 00739 : _href(href), 00740 _type(type), 00741 _alternate(alternate) 00742 { 00743 } 00744 00745 bool empty() const {return _href.empty();} 00746 void print(std::ostream& out) const; 00747 }; 00748 00750 struct StyleSheetList : public std::list<StyleSheet> 00751 { 00752 void set(const StyleSheet& stylesheet) 00753 { 00754 clear(); 00755 push_back(stylesheet); 00756 } 00757 }; 00758 00759 00761 struct DocType 00762 { 00763 std::string _name; 00764 00765 // External Document Types are noted, but not parsed. 00766 std::string _public; 00767 std::string _system; 00768 00769 // Internal DTDs are not supported. 00770 00771 void parse(const char* str); 00772 bool empty() const {return _name.empty();} 00773 }; 00774 00776 struct XMLFormat 00777 { 00778 XMLFormat(PRETTY_FLAGS pretty=PRETTY_INDENT, const std::string& xml_version="1.0", const std::string& encoding="utf-8", const DocType& doctype=DocType()) 00779 : _pretty(pretty), 00780 _endl("\n"), 00781 _version(xml_version), 00782 _encoding(encoding), 00783 _doctype(doctype), 00784 _standalone(-1) 00785 { 00786 } 00787 00788 void print_header(std::ostream& out, bool lf=true) const; 00789 00790 PRETTY_FLAGS _pretty; 00791 const char* _endl; // line ending string: "\n" or "\r\n" 00792 00793 std::string _version; 00794 std::string _encoding; 00795 00796 DocType _doctype; 00797 00798 StyleSheetList _stylesheets; 00799 00800 // std::string _additional; 00801 00802 int _standalone; 00803 }; 00804 00805 00806 enum WRITE_MODE { 00807 FORMAT_PLAIN, 00808 FORMAT_SMART, 00809 FORMAT_ORIGINAL, 00810 FORMAT_PRETTY 00811 }; 00812 00813 00814 struct XMLNode; 00815 00816 struct XPathElement 00817 { 00818 XPathElement() : _child_idx(-1) {} 00819 00820 XPathElement(const XS_String& child_name, int child_idx=-1) 00821 : _child_name(child_name), _child_idx(child_idx) {} 00822 00823 XPathElement(const XS_String& child_name, int child_idx, const XS_String& attr_name, const XS_String& attr_value) 00824 : _child_name(child_name), _child_idx(child_idx), 00825 _attr_name(attr_name), _attr_value(attr_value) 00826 { 00827 } 00828 00829 XS_String _child_name; 00830 int _child_idx; 00831 00832 XS_String _attr_name; 00833 XS_String _attr_value; 00834 00835 const char* parse(const char* path); 00836 00837 XMLNode* find(XMLNode* node) const; 00838 const XMLNode* const_find(const XMLNode* node) const; 00839 00840 bool matches(const XMLNode& node, int& n) const; 00841 }; 00842 00843 struct XPath : std::list<XPathElement> 00844 { 00845 XPath() : _absolute(false) {} 00846 XPath(const char* path) {init(path);} 00847 XPath(const std::string path) {init(path.c_str());} 00848 00849 void init(const char* path); 00850 00851 bool _absolute; 00852 }; 00853 00854 00856 struct XMLNode : public XS_String 00857 { 00858 #if defined(UNICODE) && !defined(XS_STRING_UTF8) 00859 00860 // optimized read access without temporary A/U conversion when using ASCII attribute names 00861 struct AttributeMap : public std::map<XS_String, XS_String> 00862 { 00863 typedef std::map<XS_String, XS_String> super; 00864 00865 const_iterator find(const char* x) const 00866 { 00867 for(const_iterator it=begin(); it!=end(); ++it) 00868 if (it->first == x) 00869 return it; 00870 00871 return end(); 00872 } 00873 00874 const_iterator find(const key_type& x) const 00875 { 00876 return super::find(x); 00877 } 00878 00879 iterator find(const key_type& x) 00880 { 00881 return super::find(x); 00882 } 00883 00884 XS_String get(const char* x, LPCXSSTR def=XS_EMPTY_STR) const 00885 { 00886 const_iterator found = find(x); 00887 00888 if (found != end()) 00889 return found->second; 00890 else 00891 return def; 00892 } 00893 }; 00894 #else 00895 00896 struct AttributeMap : public std::map<XS_String, XS_String> 00897 { 00898 XS_String get(const char* x, LPCXSSTR def=XS_EMPTY_STR) const 00899 { 00900 const_iterator found = find(x); 00901 00902 if (found != end()) 00903 return found->second; 00904 else 00905 return def; 00906 } 00907 }; 00908 #endif 00909 00911 struct Children : public std::list<XMLNode*> 00912 { 00913 typedef std::list<XMLNode*> super; 00914 00915 Children() 00916 { 00917 } 00918 00919 Children(Children& other) 00920 { 00921 for(Children::const_iterator it=other.begin(); it!=other.end(); ++it) 00922 push_back(*it); 00923 } 00924 00925 void assign(Children& other) 00926 { 00927 clear(); 00928 move(other); 00929 } 00930 00931 void move(Children& other) 00932 { 00933 for(Children::const_iterator it=other.begin(); it!=other.end(); ++it) 00934 push_back(*it); 00935 00936 other.reset(); 00937 } 00938 00939 Children& operator=(Children& other) 00940 { 00941 assign(other); 00942 return *this; 00943 } 00944 00945 void copy(const Children& other) 00946 { 00947 for(Children::const_iterator it=other.begin(); it!=other.end(); ++it) 00948 push_back(new XMLNode(**it)); 00949 } 00950 00951 void clear() 00952 { 00953 while(!empty()) { 00954 XMLNode* node = back(); 00955 pop_back(); 00956 00957 node->clear(); 00958 delete node; 00959 } 00960 } 00961 00962 bool remove(XMLNode* node) 00963 { 00964 for(iterator it=begin(); it!=end(); ++it) 00965 if (*it == node) { 00966 erase(it); 00967 return true; 00968 } 00969 00970 return false; 00971 } 00972 00973 private: 00974 void reset() 00975 { 00976 super::clear(); 00977 } 00978 }; 00979 00980 // access to protected class members for XMLPos and XMLReader 00981 friend struct XMLPos; 00982 friend struct const_XMLPos; 00983 friend struct XMLReaderBase; 00984 friend struct XPathElement; 00985 00986 XMLNode(const XS_String& name) 00987 : XS_String(name), 00988 _cdata_content(false) 00989 { 00990 } 00991 00992 XMLNode(const XS_String& name, const std::string& leading) 00993 : XS_String(name), 00994 _leading(leading), 00995 _cdata_content(false) 00996 { 00997 } 00998 00999 XMLNode(const XMLNode& other) 01000 : XS_String(other), 01001 _attributes(other._attributes), 01002 _leading(other._leading), 01003 _content(other._content), 01004 _end_leading(other._end_leading), 01005 _trailing(other._trailing), 01006 #ifdef XMLNODE_LOCATION 01007 _location(other._location), 01008 #endif 01009 _cdata_content(false) 01010 { 01011 for(Children::const_iterator it=other._children.begin(); it!=other._children.end(); ++it) 01012 _children.push_back(new XMLNode(**it)); 01013 } 01014 01015 enum COPY_FLAGS {COPY_NOCHILDREN}; 01016 01017 XMLNode(const XMLNode& other, COPY_FLAGS copy_no_children) 01018 : XS_String(other), 01019 _attributes(other._attributes), 01020 _leading(other._leading), 01021 _content(other._content), 01022 _end_leading(other._end_leading), 01023 _trailing(other._trailing), 01024 #ifdef XMLNODE_LOCATION 01025 _location(other._location), 01026 #endif 01027 _cdata_content(false) 01028 { 01029 // assert(copy_no_children==COPY_NOCHILDREN); 01030 } 01031 01032 virtual ~XMLNode() 01033 { 01034 while(!_children.empty()) { 01035 delete _children.back(); 01036 _children.pop_back(); 01037 } 01038 } 01039 01040 void clear() 01041 { 01042 _leading.erase(); 01043 _content.erase(); 01044 _end_leading.erase(); 01045 _trailing.erase(); 01046 01047 _attributes.clear(); 01048 _children.clear(); 01049 01050 XS_String::erase(); 01051 } 01052 01053 XMLNode& operator=(const XMLNode& other) 01054 { 01055 _children.clear(); 01056 _children.copy(other._children); 01057 01058 _attributes = other._attributes; 01059 01060 _leading = other._leading; 01061 _content = other._content; 01062 _end_leading = other._end_leading; 01063 _trailing = other._trailing; 01064 01065 return *this; 01066 } 01067 01069 void add_child(XMLNode* child) 01070 { 01071 _children.push_back(child); 01072 } 01073 01075 void remove_children(const XS_String& name) 01076 { 01077 Children::iterator it, next=_children.begin(); 01078 01079 while((it=next++) != _children.end()) 01080 if (**it == name) 01081 _children.erase(it); 01082 } 01083 01085 void put(const XS_String& attr_name, const XS_String& value) 01086 { 01087 _attributes[attr_name] = value; 01088 } 01089 01091 XS_String& operator[](const XS_String& attr_name) 01092 { 01093 return _attributes[attr_name]; 01094 } 01095 01097 template<typename T> XS_String get(const T& attr_name, LPCXSSTR def=XS_EMPTY_STR) const 01098 { 01099 AttributeMap::const_iterator found = _attributes.find(attr_name); 01100 01101 if (found != _attributes.end()) 01102 return found->second; 01103 else 01104 return def; 01105 } 01106 01108 void erase(const XS_String& attr_name) 01109 { 01110 _attributes.erase(attr_name); 01111 } 01112 01114 XS_String subvalue(const XS_String& child_name, const XS_String& attr_name, int n=0) const 01115 { 01116 const XMLNode* node = XPathElement(child_name, n).const_find(this); 01117 01118 if (node) 01119 return node->get(attr_name); 01120 else 01121 return XS_String(); 01122 } 01123 01125 XS_String& subvalue(const XS_String& child_name, const XS_String& attr_name, int n=0) 01126 { 01127 XMLNode* node = XPathElement(child_name, n).find(this); 01128 01129 if (!node) { 01130 node = new XMLNode(child_name); 01131 add_child(node); 01132 } 01133 01134 return (*node)[attr_name]; 01135 } 01136 01137 #if defined(UNICODE) && !defined(XS_STRING_UTF8) 01138 01139 XS_String subvalue(const char* child_name, const char* attr_name, int n=0) const 01140 { 01141 const XMLNode* node = XPathElement(child_name, n).const_find(this); 01142 01143 if (node) 01144 return node->get(attr_name); 01145 else 01146 return XS_String(); 01147 } 01148 01150 XS_String& subvalue(const char* child_name, const XS_String& attr_name, int n=0) 01151 { 01152 XMLNode* node = XPathElement(child_name, n).find(this); 01153 01154 if (!node) { 01155 node = new XMLNode(child_name); 01156 add_child(node); 01157 } 01158 01159 return (*node)[attr_name]; 01160 } 01161 #endif 01162 01163 const Children& get_children() const 01164 { 01165 return _children; 01166 } 01167 01168 Children& get_children() 01169 { 01170 return _children; 01171 } 01172 01173 const AttributeMap& get_attributes() const 01174 { 01175 return _attributes; 01176 } 01177 01178 AttributeMap& get_attributes() 01179 { 01180 return _attributes; 01181 } 01182 01184 XS_String get_content() const 01185 { 01186 return DecodeXMLString(_content); 01187 } 01188 01190 XS_String get_sub_content(const XPath& xpath) const 01191 { 01192 const XMLNode* node = find_relative(xpath); 01193 01194 if (node) 01195 return node->get_content(); 01196 else 01197 return XS_EMPTY_STR; 01198 } 01199 01201 void set_content(const XS_String& s, bool cdata=false) 01202 { 01203 _content.assign(EncodeXMLString(s.c_str(), cdata)); 01204 } 01205 01207 bool set_sub_content(const XPath& xpath, const XS_String& s, bool cdata=false) 01208 { 01209 XMLNode* node = create_relative(xpath); 01210 01211 if (node) { 01212 node->set_content(s, cdata); 01213 return true; 01214 } else 01215 return false; 01216 } 01217 01218 #ifdef XMLNODE_LOCATION 01219 const XMLLocation& get_location() const {return _location;} 01220 #endif 01221 01223 bool write(std::ostream& out, const XMLFormat& format, WRITE_MODE mode=FORMAT_SMART, int indent=0) const 01224 { 01225 switch(mode) { 01226 case FORMAT_PLAIN: 01227 plain_write_worker(out); 01228 break; 01229 01230 case FORMAT_PRETTY: 01231 pretty_write_worker(out, format, indent); 01232 break; 01233 01234 case FORMAT_ORIGINAL: 01235 original_write_worker(out); 01236 break; 01237 01238 default: // FORMAT_SMART 01239 smart_write_worker(out, format, indent); 01240 } 01241 01242 return out.good(); 01243 } 01244 01246 int count(const XPath& xpath) const 01247 { 01248 return count(xpath.begin(), xpath.end()); 01249 } 01250 01252 int count(XPath::const_iterator from, const XPath::const_iterator& to) const; 01253 01255 bool filter(const XPath& xpath, XMLNode& target) const; 01256 01258 const XMLNode* find_relative(const XPath& xpath) const; 01259 01261 XMLNode* find_relative(const XPath& xpath); 01262 01263 XMLNode* get_first_child() const 01264 { 01265 if (!_children.empty()) 01266 return _children.front(); 01267 else 01268 return NULL; 01269 } 01270 01271 protected: 01272 Children _children; 01273 AttributeMap _attributes; 01274 01275 std::string _leading; // UTF-8 encoded 01276 std::string _content; // UTF-8 and entity encoded, may contain CDATA sections; decode with DecodeXMLString() 01277 std::string _end_leading; // UTF-8 encoded 01278 std::string _trailing; // UTF-8 encoded 01279 01280 #ifdef XMLNODE_LOCATION 01281 XMLLocation _location; 01282 #endif 01283 01284 bool _cdata_content; 01285 01287 XMLNode* create_relative(const XPath& xpath); 01288 01290 XMLNode* filter(XPath::const_iterator from, const XPath::const_iterator& to) const; 01291 01292 void original_write_worker(std::ostream& out) const; 01293 void plain_write_worker(std::ostream& out) const; 01294 void pretty_write_worker(std::ostream& out, const XMLFormat& format, int indent) const; 01295 void smart_write_worker(std::ostream& out, const XMLFormat& format, int indent) const; 01296 }; 01297 01298 01300 struct XMLChildrenFilter 01301 { 01302 XMLChildrenFilter(XMLNode::Children& children, const XS_String& name) 01303 : _begin(children.begin(), children.end(), name), 01304 _end(children.end(), children.end(), name) 01305 { 01306 } 01307 01308 XMLChildrenFilter(XMLNode* node, const XS_String& name) 01309 : _begin(node->get_children().begin(), node->get_children().end(), name), 01310 _end(node->get_children().end(), node->get_children().end(), name) 01311 { 01312 } 01313 01315 struct iterator 01316 { 01317 typedef XMLNode::Children::iterator BaseIterator; 01318 typedef iterator myType; 01319 01320 iterator(BaseIterator begin, BaseIterator end, const XS_String& filter_name) 01321 : _cur(begin), 01322 _end(end), 01323 _filter_name(filter_name) 01324 { 01325 search_next(); 01326 } 01327 01328 operator BaseIterator() 01329 { 01330 return _cur; 01331 } 01332 01333 const XMLNode* operator*() const 01334 { 01335 return *_cur; 01336 } 01337 01338 XMLNode* operator*() 01339 { 01340 return *_cur; 01341 } 01342 01343 myType& operator++() 01344 { 01345 ++_cur; 01346 search_next(); 01347 01348 return *this; 01349 } 01350 01351 myType operator++(int) 01352 { 01353 myType ret = *this; 01354 01355 ++_cur; 01356 search_next(); 01357 01358 return ret; 01359 } 01360 01361 bool operator==(const myType& other) const 01362 { 01363 return _cur == other._cur; 01364 } 01365 01366 bool operator!=(const myType& other) const 01367 { 01368 return _cur != other._cur; 01369 } 01370 01371 protected: 01372 BaseIterator _cur; 01373 BaseIterator _end; 01374 XS_String _filter_name; 01375 01376 void search_next() 01377 { 01378 while(_cur!=_end && **_cur!=_filter_name) 01379 ++_cur; 01380 } 01381 }; 01382 01383 iterator begin() 01384 { 01385 return _begin; 01386 } 01387 01388 iterator end() 01389 { 01390 return _end; 01391 } 01392 01393 protected: 01394 iterator _begin; 01395 iterator _end; 01396 }; 01397 01398 01400 struct const_XMLChildrenFilter 01401 { 01402 const_XMLChildrenFilter(const XMLNode::Children& children, const XS_String& name) 01403 : _begin(children.begin(), children.end(), name), 01404 _end(children.end(), children.end(), name) 01405 { 01406 } 01407 01408 const_XMLChildrenFilter(const XMLNode* node, const XS_String& name) 01409 : _begin(node->get_children().begin(), node->get_children().end(), name), 01410 _end(node->get_children().end(), node->get_children().end(), name) 01411 { 01412 } 01413 01415 struct const_iterator 01416 { 01417 typedef XMLNode::Children::const_iterator BaseIterator; 01418 typedef const_iterator myType; 01419 01420 const_iterator(BaseIterator begin, BaseIterator end, const XS_String& filter_name) 01421 : _cur(begin), 01422 _end(end), 01423 _filter_name(filter_name) 01424 { 01425 search_next(); 01426 } 01427 01428 operator BaseIterator() 01429 { 01430 return _cur; 01431 } 01432 01433 const XMLNode* operator*() const 01434 { 01435 return *_cur; 01436 } 01437 01438 myType& operator++() 01439 { 01440 ++_cur; 01441 search_next(); 01442 01443 return *this; 01444 } 01445 01446 myType operator++(int) 01447 { 01448 myType ret = *this; 01449 01450 ++_cur; 01451 search_next(); 01452 01453 return ret; 01454 } 01455 01456 bool operator==(const myType& other) const 01457 { 01458 return _cur == other._cur; 01459 } 01460 01461 bool operator!=(const myType& other) const 01462 { 01463 return _cur != other._cur; 01464 } 01465 01466 protected: 01467 BaseIterator _cur; 01468 BaseIterator _end; 01469 XS_String _filter_name; 01470 01471 void search_next() 01472 { 01473 while(_cur!=_end && **_cur!=_filter_name) 01474 ++_cur; 01475 } 01476 }; 01477 01478 const_iterator begin() 01479 { 01480 return _begin; 01481 } 01482 01483 const_iterator end() 01484 { 01485 return _end; 01486 } 01487 01488 protected: 01489 const_iterator _begin; 01490 const_iterator _end; 01491 }; 01492 01493 01495 struct XMLPos 01496 { 01497 XMLPos(XMLNode* root) 01498 : _root(root), 01499 _cur(root) 01500 { 01501 } 01502 01503 XMLPos(const XMLPos& other) 01504 : _root(other._root), 01505 _cur(other._cur) 01506 { // don't copy _stack 01507 } 01508 01509 XMLPos(XMLNode* node, const XS_String& name) 01510 : _root(node), 01511 _cur(node) 01512 { 01513 smart_create(name); 01514 } 01515 01516 XMLPos(XMLNode* node, const XS_String& name, const XS_String& attr_name, const XS_String& attr_value) 01517 : _root(node), 01518 _cur(node) 01519 { 01520 smart_create(name, attr_name, attr_value); 01521 } 01522 01523 XMLPos(const XMLPos& other, const XS_String& name) 01524 : _root(other._root), 01525 _cur(other._cur) 01526 { 01527 smart_create(name); 01528 } 01529 01530 XMLPos(const XMLPos& other, const XS_String& name, const XS_String& attr_name, const XS_String& attr_value) 01531 : _root(other._root), 01532 _cur(other._cur) 01533 { 01534 smart_create(name, attr_name, attr_value); 01535 } 01536 01538 XMLNode& cur() 01539 { 01540 return *_cur; 01541 } 01542 01543 const XMLNode& cur() const 01544 { 01545 return *_cur; 01546 } 01547 01549 operator const XMLNode*() const {return _cur;} 01550 operator XMLNode*() {return _cur;} 01551 01552 const XMLNode* operator->() const {return _cur;} 01553 XMLNode* operator->() {return _cur;} 01554 01555 const XMLNode& operator*() const {return *_cur;} 01556 XMLNode& operator*() {return *_cur;} 01557 01559 XS_String get(const XS_String& attr_name, LPCXSSTR def=XS_EMPTY_STR) const 01560 { 01561 return _cur->get(attr_name, def); 01562 } 01563 01565 void put(const XS_String& attr_name, const XS_String& value) 01566 { 01567 _cur->put(attr_name, value); 01568 } 01569 01571 template<typename T> XS_String get(const T& attr_name) const {return (*_cur)[attr_name];} 01572 XS_String& operator[](const XS_String& attr_name) {return (*_cur)[attr_name];} 01573 const XS_String& operator[](const XS_String& attr_name) const {return (*_cur)[attr_name];} 01574 01576 void add_down(XMLNode* child) 01577 { 01578 _cur->add_child(child); 01579 go_to(child); 01580 } 01581 01583 bool back() 01584 { 01585 if (!_stack.empty()) { 01586 _cur = _stack.top(); 01587 _stack.pop(); 01588 return true; 01589 } else 01590 return false; 01591 } 01592 01594 bool go_down() 01595 { 01596 XMLNode* node = _cur->get_first_child(); 01597 01598 if (node) { 01599 go_to(node); 01600 return true; 01601 } else 01602 return false; 01603 } 01604 01606 bool go_down(const XS_String& child_name, int n=0) 01607 { 01608 XMLNode* node = XPathElement(child_name, n).find(_cur); 01609 01610 if (node) { 01611 go_to(node); 01612 return true; 01613 } else 01614 return false; 01615 } 01616 01618 bool iterate(const XS_String& child_name, size_t& cnt) 01619 { 01620 XMLNode* node = XPathElement(child_name, cnt).find(_cur); 01621 01622 if (node) { 01623 go_to(node); 01624 ++cnt; 01625 return true; 01626 } else 01627 return false; 01628 } 01629 01631 bool go(const XPath& xpath); 01632 01634 bool create_relative(const XPath& xpath) 01635 { 01636 XMLNode* node = _cur->create_relative(xpath); 01637 if (!node) 01638 return false; // invalid path specified 01639 01640 go_to(node); 01641 return true; 01642 } 01643 01645 void create(const XS_String& name) 01646 { 01647 add_down(new XMLNode(name)); 01648 } 01649 01651 void create_node_content(const XS_String& node_name, const XS_String& content) 01652 { 01653 XMLNode* pNode = new XMLNode(node_name); 01654 pNode->set_content(content); 01655 _cur->add_child(pNode); 01656 } 01657 01659 void smart_create(const XS_String& child_name) 01660 { 01661 XMLNode* node = XPathElement(child_name).find(_cur); 01662 01663 if (node) 01664 go_to(node); 01665 else 01666 add_down(new XMLNode(child_name)); 01667 } 01668 01670 void smart_create(const XS_String& child_name, const XS_String& attr_name, const XS_String& attr_value) 01671 { 01672 XMLNode* node = XPathElement(child_name, 0, attr_name, attr_value).find(_cur); 01673 01674 if (node) 01675 go_to(node); 01676 else { 01677 node = new XMLNode(child_name); 01678 add_down(node); 01679 (*node)[attr_name] = attr_value; 01680 } 01681 } 01682 01684 int count(const XPath& xpath) const 01685 { 01686 return _cur->count(xpath); 01687 } 01688 01690 int filter(const XPath& xpath, XMLNode& target) const 01691 { 01692 return _cur->filter(xpath, target); 01693 } 01694 01695 #if defined(UNICODE) && !defined(XS_STRING_UTF8) 01696 01697 bool go_down(const char* child_name, int n=0) 01698 { 01699 XMLNode* node = XPathElement(child_name, n).find(_cur); 01700 01701 if (node) { 01702 go_to(node); 01703 return true; 01704 } else 01705 return false; 01706 } 01707 01709 void create(const char* child_name) 01710 { 01711 add_down(new XMLNode(child_name)); 01712 } 01713 01715 void smart_create(const char* child_name) 01716 { 01717 XMLNode* node = XPathElement(child_name).find(_cur); 01718 01719 if (node) 01720 go_to(node); 01721 else 01722 add_down(new XMLNode(child_name)); 01723 } 01724 01726 template<typename T, typename U> 01727 void smart_create(const char* child_name, const T& attr_name, const U& attr_value) 01728 { 01729 XMLNode* node = XPathElement(child_name, 0, attr_name, attr_value).find(_cur); 01730 01731 if (node) 01732 go_to(node); 01733 else { 01734 node = new XMLNode(child_name); 01735 add_down(node); 01736 (*node)[attr_name] = attr_value; 01737 } 01738 } 01739 #endif 01740 01742 bool delete_this() 01743 { 01744 if (!_stack.empty()) { 01745 XMLNode* pLast = _stack.top(); 01746 01747 if (pLast->_children.remove(_cur)) { 01748 _cur = _stack.top(); 01749 return true; 01750 } 01751 } 01752 01753 return false; 01754 } 01755 01757 void remove_children(const XS_String& name) 01758 { 01759 _cur->remove_children(name); 01760 } 01761 01763 void erase(const XS_String& attr_name) 01764 { 01765 _cur->erase(attr_name); 01766 } 01767 01768 XS_String& str() {return *_cur;} 01769 const XS_String& str() const {return *_cur;} 01770 01771 // property (key/value pair) setter functions 01772 void set_property(const XS_String& key, int value, const XS_String& name=XS_PROPERTY); 01773 void set_property(const XS_String& key, double value, const XS_String& name=XS_PROPERTY); 01774 void set_property(const XS_String& key, const XS_String& value, const XS_String& name=XS_PROPERTY); 01775 void set_property(const XS_String& key, const struct XMLBool& value, const XS_String& name=XS_PROPERTY); 01776 01777 void set_property(const XS_String& key, const char* value, const XS_String& name=XS_PROPERTY) 01778 {set_property(key, XS_String(value), name);} 01779 01780 protected: 01781 friend struct const_XMLPos; // access to _root 01782 01783 XMLNode* _root; 01784 XMLNode* _cur; 01785 std::stack<XMLNode*> _stack; 01786 01788 void go_to(XMLNode* child) 01789 { 01790 _stack.push(_cur); 01791 _cur = child; 01792 } 01793 }; 01794 01795 01797 struct const_XMLPos 01798 { 01799 const_XMLPos(const XMLNode* root) 01800 : _root(root), 01801 _cur(root) 01802 { 01803 } 01804 01805 const_XMLPos(const const_XMLPos& other) 01806 : _root(other._root), 01807 _cur(other._cur) 01808 { // don't copy _stack 01809 } 01810 01811 const_XMLPos(const XMLPos& other) 01812 : _root(other._root), 01813 _cur(other._cur) 01814 { // don't copy _stack 01815 } 01816 01818 const XMLNode& cur() const 01819 { 01820 return *_cur; 01821 } 01822 01824 operator const XMLNode*() const {return _cur;} 01825 01826 const XMLNode* operator->() const {return _cur;} 01827 01828 const XMLNode& operator*() const {return *_cur;} 01829 01831 XS_String get(const XS_String& attr_name) const 01832 { 01833 return _cur->get(attr_name); 01834 } 01835 01837 template<typename T> XS_String get(const T& attr_name) const {return _cur->get(attr_name);} 01838 XS_String operator[](const XS_String& attr_name) const {return _cur->get(attr_name);} 01839 01841 bool back() 01842 { 01843 if (!_stack.empty()) { 01844 _cur = _stack.top(); 01845 _stack.pop(); 01846 return true; 01847 } else 01848 return false; 01849 } 01850 01852 bool go_down() 01853 { 01854 const XMLNode* node = _cur->get_first_child(); 01855 01856 if (node) { 01857 go_to(node); 01858 return true; 01859 } else 01860 return false; 01861 } 01862 01864 bool go_down(const XS_String& child_name, int n=0) 01865 { 01866 const XMLNode* node = XPathElement(child_name, n).const_find(_cur); 01867 01868 if (node) { 01869 go_to(node); 01870 return true; 01871 } else 01872 return false; 01873 } 01874 01876 bool iterate(const XS_String& child_name, size_t& cnt) 01877 { 01878 const XMLNode* node = XPathElement(child_name, cnt).const_find(_cur); 01879 01880 if (node) { 01881 go_to(node); 01882 ++cnt; 01883 return true; 01884 } else 01885 return false; 01886 } 01887 01889 bool go(const XPath& xpath); 01890 01891 #if defined(UNICODE) && !defined(XS_STRING_UTF8) 01892 01893 bool go_down(const char* child_name, int n=0) 01894 { 01895 const XMLNode* node = XPathElement(child_name, n).const_find(_cur); 01896 01897 if (node) { 01898 go_to(node); 01899 return true; 01900 } else 01901 return false; 01902 } 01903 #endif 01904 01905 const XS_String& str() const {return *_cur;} 01906 01907 protected: 01908 const XMLNode* _root; 01909 const XMLNode* _cur; 01910 std::stack<const XMLNode*> _stack; 01911 01913 void go_to(const XMLNode* child) 01914 { 01915 _stack.push(_cur); 01916 _cur = child; 01917 } 01918 }; 01919 01920 01922 struct XMLBool 01923 { 01924 XMLBool(bool value=false) 01925 : _value(value) 01926 { 01927 } 01928 01929 XMLBool(LPCXSSTR value, bool def=false) 01930 { 01931 if (value && *value)//@@ also handle white space and return def instead of false 01932 _value = !XS_icmp(value, XS_TRUE); 01933 else 01934 _value = def; 01935 } 01936 01937 XMLBool(const XMLNode* node, const XS_String& attr_name, bool def=false) 01938 { 01939 const XS_String& value = node->get(attr_name); 01940 01941 if (!value.empty()) 01942 _value = !XS_icmp(value.c_str(), XS_TRUE); 01943 else 01944 _value = def; 01945 } 01946 01947 operator bool() const 01948 { 01949 return _value; 01950 } 01951 01952 bool operator!() const 01953 { 01954 return !_value; 01955 } 01956 01957 operator LPCXSSTR() const 01958 { 01959 return _value? XS_TRUE: XS_FALSE; 01960 } 01961 01962 protected: 01963 bool _value; 01964 01965 private: 01966 void operator=(const XMLBool&); // disallow assignment operations 01967 }; 01968 01970 struct XMLBoolRef 01971 { 01972 XMLBoolRef(XMLNode* node, const XS_String& attr_name, bool def=false) 01973 : _ref((*node)[attr_name]) 01974 { 01975 if (_ref.empty()) 01976 assign(def); 01977 } 01978 01979 operator bool() const 01980 { 01981 return !XS_icmp(_ref.c_str(), XS_TRUE); 01982 } 01983 01984 bool operator!() const 01985 { 01986 return XS_icmp(_ref.c_str(), XS_TRUE)? true: false; 01987 } 01988 01989 XMLBoolRef& operator=(bool value) 01990 { 01991 assign(value); 01992 01993 return *this; 01994 } 01995 01996 void assign(bool value) 01997 { 01998 _ref.assign(value? XS_TRUE: XS_FALSE); 01999 } 02000 02001 void toggle() 02002 { 02003 assign(!operator bool()); 02004 } 02005 02006 protected: 02007 XS_String& _ref; 02008 }; 02009 02010 02012 struct XMLInt 02013 { 02014 XMLInt(int value) 02015 : _value(value) 02016 { 02017 } 02018 02019 XMLInt(LPCXSSTR value, int def=0) 02020 { 02021 if (value && *value)//@@ also handle white space and return def instead of 0 02022 _value = XS_toi(value); 02023 else 02024 _value = def; 02025 } 02026 02027 XMLInt(const XMLNode* node, const XS_String& attr_name, int def=0) 02028 { 02029 const XS_String& value = node->get(attr_name); 02030 02031 if (!value.empty()) 02032 _value = XS_toi(value.c_str()); 02033 else 02034 _value = def; 02035 } 02036 02037 operator int() const 02038 { 02039 return _value; 02040 } 02041 02042 operator XS_String() const 02043 { 02044 XS_CHAR buffer[32]; 02045 XS_snprintf(buffer, COUNTOF(buffer), XS_INTFMT, _value); 02046 return XS_String(buffer); 02047 } 02048 02049 protected: 02050 int _value; 02051 02052 private: 02053 void operator=(const XMLInt&); // disallow assignment operations 02054 }; 02055 02057 struct XMLIntRef 02058 { 02059 XMLIntRef(XMLNode* node, const XS_String& attr_name, int def=0) 02060 : _ref((*node)[attr_name]) 02061 { 02062 if (_ref.empty()) 02063 assign(def); 02064 } 02065 02066 XMLIntRef& operator=(int value) 02067 { 02068 assign(value); 02069 02070 return *this; 02071 } 02072 02073 operator int() const 02074 { 02075 return XS_toi(_ref.c_str()); 02076 } 02077 02078 void assign(int value) 02079 { 02080 XS_CHAR buffer[32]; 02081 XS_snprintf(buffer, COUNTOF(buffer), XS_INTFMT, value); 02082 _ref.assign(buffer); 02083 } 02084 02085 protected: 02086 XS_String& _ref; 02087 }; 02088 02089 02091 struct XMLDouble 02092 { 02093 XMLDouble(double value) 02094 : _value(value) 02095 { 02096 } 02097 02098 XMLDouble(LPCXSSTR value, double def=0.) 02099 { 02100 LPTSTR end; 02101 02102 if (value && *value)//@@ also handle white space and return def instead of 0 02103 _value = XS_tod(value, &end); 02104 else 02105 _value = def; 02106 } 02107 02108 XMLDouble(const XMLNode* node, const XS_String& attr_name, double def=0.) 02109 { 02110 LPTSTR end; 02111 const XS_String& value = node->get(attr_name); 02112 02113 if (!value.empty()) 02114 _value = XS_tod(value.c_str(), &end); 02115 else 02116 _value = def; 02117 } 02118 02119 operator double() const 02120 { 02121 return _value; 02122 } 02123 02124 operator XS_String() const 02125 { 02126 XS_CHAR buffer[32]; 02127 XS_snprintf(buffer, COUNTOF(buffer), XS_FLOATFMT, _value); 02128 return XS_String(buffer); 02129 } 02130 02131 protected: 02132 double _value; 02133 02134 private: 02135 void operator=(const XMLDouble&); // disallow assignment operations 02136 }; 02137 02139 struct XMLDoubleRef 02140 { 02141 XMLDoubleRef(XMLNode* node, const XS_String& attr_name, double def=0.) 02142 : _ref((*node)[attr_name]) 02143 { 02144 if (_ref.empty()) 02145 assign(def); 02146 } 02147 02148 XMLDoubleRef& operator=(double value) 02149 { 02150 assign(value); 02151 02152 return *this; 02153 } 02154 02155 operator double() const 02156 { 02157 LPTSTR end; 02158 return XS_tod(_ref.c_str(), &end); 02159 } 02160 02161 void assign(double value) 02162 { 02163 XS_CHAR buffer[32]; 02164 XS_snprintf(buffer, COUNTOF(buffer), XS_FLOATFMT, value); 02165 _ref.assign(buffer); 02166 } 02167 02168 protected: 02169 XS_String& _ref; 02170 }; 02171 02172 02174 struct XMLString 02175 { 02176 XMLString(const XS_String& value) 02177 : _value(value) 02178 { 02179 } 02180 02181 XMLString(LPCXSSTR value, LPCXSSTR def=XS_EMPTY) 02182 { 02183 if (value && *value) 02184 _value = value; 02185 else 02186 _value = def; 02187 } 02188 02189 XMLString(const XMLNode* node, const XS_String& attr_name, LPCXSSTR def=XS_EMPTY) 02190 { 02191 const XS_String& value = node->get(attr_name); 02192 02193 if (!value.empty()) 02194 _value = value; 02195 else 02196 _value = def; 02197 } 02198 02199 operator const XS_String&() const 02200 { 02201 return _value; 02202 } 02203 02204 const XS_String& c_str() const 02205 { 02206 return _value; 02207 } 02208 02209 protected: 02210 XS_String _value; 02211 02212 private: 02213 void operator=(const XMLString&); // disallow assignment operations 02214 }; 02215 02217 struct XMLStringRef 02218 { 02219 XMLStringRef(XMLNode* node, const XS_String& attr_name, LPCXSSTR def=XS_EMPTY) 02220 : _ref((*node)[attr_name]) 02221 { 02222 if (_ref.empty()) 02223 assign(def); 02224 } 02225 02226 XMLStringRef(const XS_String& node_name, XMLNode* node, const XS_String& attr_name, LPCXSSTR def=XS_EMPTY) 02227 : _ref(node->subvalue(node_name, attr_name)) 02228 { 02229 if (_ref.empty()) 02230 assign(def); 02231 } 02232 02233 XMLStringRef& operator=(const XS_String& value) 02234 { 02235 assign(value); 02236 02237 return *this; 02238 } 02239 02240 operator const XS_String&() const 02241 { 02242 return _ref; 02243 } 02244 02245 void assign(const XS_String& value) 02246 { 02247 _ref.assign(value); 02248 } 02249 02250 protected: 02251 XS_String& _ref; 02252 }; 02253 02254 02255 // read option (for example configuration) values from XML node attributes 02256 template<typename T> 02257 inline void read_option(T& var, const_XMLPos& cfg, LPCXSSTR key) 02258 { 02259 const XS_String& val = cfg.get(key); 02260 02261 if (!val.empty()) 02262 var = val; 02263 } 02264 02265 // read integer option values from XML node attributes 02266 template<> 02267 inline void read_option(int& var, const_XMLPos& cfg, LPCXSSTR key) 02268 { 02269 const XS_String& val = cfg.get(key); 02270 02271 if (!val.empty()) 02272 var = XS_toi(val.c_str()); 02273 } 02274 02275 02276 inline void XMLPos::set_property(const XS_String& key, int value, const XS_String& name) 02277 { 02278 smart_create(name, XS_KEY, key); 02279 XMLIntRef(_cur, XS_VALUE) = value; 02280 back(); 02281 } 02282 02283 inline void XMLPos::set_property(const XS_String& key, double value, const XS_String& name) 02284 { 02285 smart_create(name, XS_KEY, key); 02286 XMLDoubleRef(_cur, XS_VALUE) = value; 02287 back(); 02288 } 02289 02290 inline void XMLPos::set_property(const XS_String& key, const XS_String& value, const XS_String& name) 02291 { 02292 smart_create(name, XS_KEY, key); 02293 put(XS_VALUE, value); 02294 back(); 02295 } 02296 02297 inline void XMLPos::set_property(const XS_String& key, const XMLBool& value, const XS_String& name) 02298 { 02299 smart_create(name, XS_KEY, key); 02300 XMLBoolRef(_cur, XS_VALUE) = value; 02301 back(); 02302 } 02303 02304 02306 struct XMLProperty { 02307 XMLProperty(const XMLNode* node) 02308 : _key(node->get(XS_KEY)), 02309 _value(node->get(XS_VALUE)) 02310 { 02311 } 02312 02313 XS_String _key; 02314 XS_String _value; 02315 }; 02316 02317 02319 struct XMLPropertyReader 02320 { 02321 XMLPropertyReader(const XMLNode::Children& children) 02322 : _filter(children, XS_PROPERTY), 02323 _begin(_filter.begin(), _filter.end()), 02324 _end(_filter.end(), _filter.end()) 02325 { 02326 } 02327 02328 XMLPropertyReader(const XMLNode* node) 02329 : _filter(node, XS_PROPERTY), 02330 _begin(_filter.begin(), _filter.end()), 02331 _end(_filter.end(), _filter.end()) 02332 { 02333 } 02334 02336 struct const_iterator 02337 { 02338 typedef const_XMLChildrenFilter::const_iterator BaseIterator; 02339 typedef const_iterator myType; 02340 02341 const_iterator(BaseIterator begin, BaseIterator end) 02342 : _cur(begin), 02343 _end(end) 02344 { 02345 } 02346 02347 operator BaseIterator() 02348 { 02349 return _cur; 02350 } 02351 02352 XMLProperty operator*() const 02353 { 02354 return XMLProperty(*_cur); 02355 } 02356 02357 const XMLNode* get_node() const 02358 { 02359 return *_cur; 02360 } 02361 02362 myType& operator++() 02363 { 02364 ++_cur; 02365 02366 return *this; 02367 } 02368 02369 myType operator++(int) 02370 { 02371 myType ret = *this; 02372 02373 ++_cur; 02374 02375 return ret; 02376 } 02377 02378 bool operator==(const myType& other) const 02379 { 02380 return _cur == other._cur; 02381 } 02382 02383 bool operator!=(const myType& other) const 02384 { 02385 return _cur != other._cur; 02386 } 02387 02388 protected: 02389 BaseIterator _cur; 02390 BaseIterator _end; 02391 }; 02392 02393 const_iterator begin() 02394 { 02395 return _begin; 02396 } 02397 02398 const_iterator end() 02399 { 02400 return _end; 02401 } 02402 02403 protected: 02404 const_XMLChildrenFilter _filter; 02405 02406 const_iterator _begin; 02407 const_iterator _end; 02408 }; 02409 02410 02411 #ifdef _MSC_VER 02412 #pragma warning(disable: 4355) 02413 #endif 02414 02416 struct XMLReaderBase 02417 #ifdef XS_USE_XERCES 02418 : public HandlerBase 02419 #endif 02420 { 02421 #ifdef XS_USE_XERCES 02422 02423 XMLReaderBase(XMLNode* node, InputSource* source, bool adoptSource=false); 02424 virtual ~XMLReaderBase(); 02425 02426 void read(); 02427 02428 protected: 02429 SAXParser* _parser; 02430 InputSource* _source; 02431 bool _deleteSource; 02432 02433 virtual void XMLDecl(const XMLCh* const versionStr, const XMLCh* const encodingStr, 02434 const XMLCh* const standaloneStr, const XMLCh* const actualEncodingStr); 02435 02436 // Handlers for the SAX DocumentHandler interface 02437 virtual void setDocumentLocator(const Locator* const locator); 02438 virtual void startElement(const XMLCh* const name, AttributeList& attributes); 02439 virtual void endElement(const XMLCh* const name); 02440 virtual void characters(const XMLCh* const chars, const unsigned int length); 02441 virtual void ignorableWhitespace(const XMLCh* const chars, const unsigned int length); 02442 02443 // Handlers for the SAX ErrorHandler interface 02444 virtual void error(const SAXParseException& e); 02445 virtual void fatalError(const SAXParseException& e); 02446 virtual void warning(const SAXParseException& e); 02447 virtual void resetErrors(); 02448 02449 #elif defined(XS_USE_EXPAT) // !XS_USE_XERCES 02450 02451 XMLReaderBase(XMLNode* node); 02452 virtual ~XMLReaderBase(); 02453 02454 protected: 02455 XML_Parser _parser; 02456 02457 static void XMLCALL XML_XmlDeclHandler(void* userData, const XML_Char* version, const XML_Char* encoding, int standalone=-1); 02458 static void XMLCALL XML_StartElementHandler(void* userData, const XML_Char* name, const XML_Char** atts); 02459 static void XMLCALL XML_EndElementHandler(void* userData, const XML_Char* name); 02460 static void XMLCALL XML_DefaultHandler(void* userData, const XML_Char* s, int len); 02461 02462 static std::string get_expat_error_string(XML_Error error_code); 02463 02464 #else // XS_USE_EXPAT 02465 02466 XMLReaderBase(XMLNode* node) 02467 : _pos(node), 02468 _endl_defined(false), 02469 _utf8(false) 02470 { 02471 _last_tag = TAG_NONE; 02472 } 02473 02474 virtual ~XMLReaderBase(); 02475 02476 bool parse(); 02477 02478 #endif 02479 02480 public: 02481 #ifndef XS_USE_XERCES 02482 void read(); 02483 02484 std::string get_position() const; 02485 #endif 02486 const XMLFormat& get_format() const {return _format;} 02487 const char* get_endl() const {return _endl_defined? _format._endl: "\n";} 02488 02489 const XMLErrorList& get_errors() const {return _errors;} 02490 const XMLErrorList& get_warnings() const {return _warnings;} 02491 02492 void clear_errors() {_errors.clear(); _warnings.clear();} 02493 02494 #ifdef XMLNODE_LOCATION 02495 const char* _display_path; // character pointer for fast reference in XMLLocation 02496 02497 #ifdef XS_USE_XERCES 02498 const Locator* _locator; 02499 #endif 02500 02501 XMLLocation get_location() const; 02502 #endif 02503 02504 protected: 02505 XMLPos _pos; 02506 02507 std::string _content; // UTF-8 encoded 02508 enum {TAG_NONE, TAG_START, TAG_END} _last_tag; 02509 02510 XMLErrorList _errors; 02511 XMLErrorList _warnings; 02512 02513 XMLFormat _format; 02514 bool _endl_defined; 02515 02516 #ifdef XS_USE_XERCES 02517 //@@ 02518 #elif defined(XS_USE_EXPAT) 02519 virtual int read_buffer(char* buffer, int len) = 0; 02520 #else 02521 virtual int get() = 0; 02522 int eat_endl(); 02523 02524 bool _utf8; 02525 #endif 02526 02527 void finish_read(); 02528 02529 virtual void XmlDeclHandler(const char* version, const char* encoding, int standalone); 02530 virtual void StartElementHandler(const XS_String& name, const XMLNode::AttributeMap& attributes); 02531 virtual void EndElementHandler(); 02532 #if defined(XS_USE_XERCES) || defined(XS_USE_EXPAT) 02533 virtual void DefaultHandler(const XML_Char* s, int len); 02534 #else 02535 virtual void DefaultHandler(const std::string& s); 02536 #endif 02537 }; 02538 02539 02541 02542 #ifdef XS_USE_XERCES 02543 02544 struct XercesXMLReader : public XMLReaderBase 02545 { 02546 XercesXMLReader(XMLNode* node, InputSource* source, bool adoptSource=false) 02547 : XMLReaderBase(node, source, adoptSource) 02548 { 02549 } 02550 02551 XercesXMLReader(XMLNode* node, LPCTSTR path); 02552 XercesXMLReader(XMLNode* node, const XMLByte* buffer, size_t bytes, const std::string& system_id=std::string()); 02553 }; 02554 02555 #define XMLReader XercesXMLReader 02556 02557 #elif defined(XS_USE_EXPAT) 02558 02559 struct ExpatXMLReader : public XMLReaderBase 02560 { 02561 ExpatXMLReader(XMLNode* node, std::istream& in) 02562 : XMLReaderBase(node), 02563 _in(in) 02564 { 02565 } 02566 02568 int read_buffer(char* buffer, int len) 02569 { 02570 if (!_in.good()) 02571 return -1; 02572 02573 _in.read(buffer, len); 02574 02575 return _in.gcount(); 02576 } 02577 02578 protected: 02579 std::istream& _in; 02580 }; 02581 02582 #define XMLReader ExpatXMLReader 02583 02584 #else // XS_USE_XERCES, XS_USE_EXPAT 02585 02586 struct XMLReader : public XMLReaderBase 02587 { 02588 XMLReader(XMLNode* node, std::istream& in) 02589 : XMLReaderBase(node), 02590 _in(in) 02591 { 02592 } 02593 02595 int get() 02596 { 02597 return _in.get(); 02598 } 02599 02600 protected: 02601 std::istream& _in; 02602 }; 02603 02604 #endif // XS_USE_XERCES 02605 02606 02607 #if defined(_MSC_VER) && _MSC_VER<1400 02608 02609 struct fast_ostringbuffer : public std::streambuf 02610 { 02611 typedef char _E; 02612 typedef std::char_traits<_E> _Tr; 02613 02614 explicit fast_ostringbuffer() 02615 {_Init(0, 0, std::_Noread);} // optimized for ios::out mode 02616 02617 virtual ~fast_ostringbuffer() 02618 {_Tidy();} 02619 02620 std::string str() const 02621 {if (pptr() != 0) 02622 {std::string _Str(pbase(), 02623 (_Seekhigh<pptr()? pptr(): _Seekhigh) - pbase()); 02624 return _Str;} 02625 else 02626 return std::string();} 02627 02628 protected: 02629 virtual int_type overflow(int_type _C = _Tr::eof()) 02630 {if (_Tr::eq_int_type(_Tr::eof(), _C)) 02631 return _Tr::not_eof(_C); 02632 else if (pptr() != 0 && pptr() < epptr()) 02633 {*_Pninc() = _Tr::to_char_type(_C); 02634 return _C;} 02635 else 02636 {size_t _Os = gptr() == 0 ? 0 : epptr() - eback(); 02637 size_t _Ns = _Os + _Alsize; 02638 _E *_P = _Al.allocate(_Ns, (void *)0); 02639 if (0 < _Os) 02640 _Tr::copy(_P, eback(), _Os); 02641 else if (_ALSIZE < _Alsize) 02642 _Alsize = _ALSIZE; 02643 02644 if (_Strmode & std::_Allocated) 02645 _Al.deallocate(eback(), _Os); 02646 02647 _Strmode |= std::_Allocated; 02648 02649 if (_Os == 0) 02650 {_Seekhigh = _P; 02651 setp(_P, _P + _Ns); 02652 setg(_P, _P, _P); } 02653 else 02654 {_Seekhigh = _Seekhigh - eback() + _P; 02655 setp(pbase() - eback() + _P, pptr() - eback() + _P, _P + _Ns); 02656 setg(_P, _P, _P);} 02657 *_Pninc() = _Tr::to_char_type(_C); 02658 02659 return _C;}} 02660 02661 void _Init(const _E *_S, size_t _N, std::_Strstate _M) 02662 {_Pendsave = 0, _Seekhigh = 0; 02663 _Alsize = _MINSIZE, _Strmode = _M; 02664 setg(0, 0, 0); 02665 setp(0, 0);} 02666 02667 void _Tidy() 02668 {if (_Strmode & std::_Allocated) 02669 _Al.deallocate(eback(), (pptr() != 0 ? epptr() : egptr()) - eback()); 02670 _Seekhigh = 0; 02671 _Strmode &= ~std::_Allocated;} 02672 02673 private: 02674 enum {_ALSIZE = 65536/*512*/, _MINSIZE = 32768/*32*/}; // bigger buffer sizes 02675 02676 _E *_Pendsave, *_Seekhigh; 02677 int _Alsize; 02678 std::_Strstate _Strmode; 02679 std::allocator<_E> _Al; 02680 }; 02681 02682 struct fast_ostringstream : public std::iostream 02683 { 02684 typedef std::iostream super; 02685 02686 explicit fast_ostringstream() 02687 : super(&_Sb) {} 02688 02689 std::string str() const 02690 {return _Sb.str();} 02691 02692 private: 02693 fast_ostringbuffer _Sb; 02694 }; 02695 02696 #else 02697 02698 typedef std::ostringstream fast_ostringstream; 02699 02700 #endif 02701 02702 02704 struct XMLDoc : public XMLNode 02705 { 02706 XMLDoc() 02707 : XMLNode("") 02708 { 02709 } 02710 02711 XMLDoc(LPCTSTR path) 02712 : XMLNode("") 02713 { 02714 read_file(path); 02715 } 02716 02717 #ifdef XS_USE_XERCES 02718 bool read_file(LPCTSTR path) 02719 { 02720 XMLReader reader(this, path); 02721 02722 #if defined(_STRING_DEFINED) && !defined(XS_STRING_UTF8) 02723 return read(reader, std::string(ANS(path))); 02724 #else 02725 return read(reader, XS_String(path)); 02726 #endif 02727 } 02728 02729 bool read_buffer(const char* buffer, size_t len, const std::string& system_id=std::string()) 02730 { 02731 XMLReader reader(this, (const XMLByte*)buffer, len, system_id); 02732 02733 return read(reader, system_id); 02734 } 02735 02736 bool read_buffer(const std::string& in, const std::string& system_id=std::string()) 02737 { 02738 return read_buffer(in.c_str(), in.length(), system_id); 02739 } 02740 02741 #else // XS_USE_XERCES 02742 02743 bool read_file(LPCTSTR path) 02744 { 02745 tifstream in(path); 02746 if (!in.good()) 02747 return false; 02748 02749 XMLReader reader(this, in); 02750 02751 #if defined(_STRING_DEFINED) && !defined(XS_STRING_UTF8) 02752 return read(reader, std::string(ANS(path))); 02753 #else 02754 return read(reader, XS_String(path)); 02755 #endif 02756 } 02757 02758 bool read_buffer(const char* buffer, size_t len, const std::string& system_id=std::string()) 02759 { 02760 return read_buffer(std::string(buffer, len), system_id); 02761 } 02762 02763 bool read_buffer(const std::string& buffer, const std::string& system_id=std::string()) 02764 { 02765 std::istringstream istr(buffer); 02766 02767 return read_stream(istr, system_id); 02768 } 02769 02770 bool read_stream(std::istream& in, const std::string& system_id=std::string()) 02771 { 02772 XMLReader reader(this, in); 02773 02774 return read(reader, system_id); 02775 } 02776 #endif // XS_USE_XERCES 02777 02778 bool read(XMLReaderBase& reader, const std::string& display_path) 02779 { 02780 #ifdef XMLNODE_LOCATION 02781 // make a string copy to handle temporary string objects 02782 _display_path = display_path; 02783 reader._display_path = _display_path.c_str(); 02784 #endif 02785 02786 reader.clear_errors(); 02787 reader.read(); 02788 02789 _format = reader.get_format(); 02790 _format._endl = reader.get_endl(); 02791 02792 if (!reader.get_errors().empty()) { 02793 _errors = reader.get_errors(); 02794 return false; 02795 } 02796 02797 return true; 02798 } 02799 02801 // FORMAT_SMART: preserving previous white space and comments 02802 bool write(std::ostream& out, WRITE_MODE mode=FORMAT_SMART) const 02803 { 02804 _format.print_header(out, mode!=FORMAT_PLAIN); 02805 02806 if (_children.size() == 1) 02807 _children.front()->write(out, _format, mode); 02808 else if (!_children.empty()) { 02809 //throw Exception("more than one XML root!"); 02810 return false; 02811 } 02812 02813 return out.good(); 02814 } 02815 02817 bool write_formating(std::ostream& out) const 02818 { 02819 return write(out, FORMAT_PRETTY); 02820 } 02821 02822 bool write_file(LPCTSTR path, WRITE_MODE mode=FORMAT_SMART) const 02823 { 02824 tofstream out(path); 02825 02826 return write(out, mode); 02827 } 02828 02829 bool write_formating(LPCTSTR path) const 02830 { 02831 tofstream out(path); 02832 02833 return write_formating(out); 02834 } 02835 02836 XMLFormat _format; 02837 XMLErrorList _errors; 02838 02839 #ifdef XMLNODE_LOCATION 02840 std::string _display_path; 02841 #endif 02842 }; 02843 02844 02846 struct XMLMessage : public XMLDoc 02847 { 02848 XMLMessage(const char* name) 02849 : _pos(this) 02850 { 02851 _pos.create(name); 02852 } 02853 02854 std::string toString() const 02855 { 02856 std::ostringstream out; 02857 02858 write(out); 02859 02860 return out.str(); 02861 } 02862 02863 XMLPos _pos; 02864 02865 protected: 02866 XMLMessage() 02867 : _pos(this) 02868 { 02869 } 02870 }; 02871 02872 02874 struct XMLMessageFromString : public XMLMessage 02875 { 02876 XMLMessageFromString(const std::string& xml_str, const std::string& system_id=std::string()) 02877 { 02878 read_buffer(xml_str.c_str(), xml_str.length(), system_id); 02879 } 02880 }; 02881 02882 02884 struct XMLMessageReader : public XMLPos 02885 { 02886 XMLMessageReader(const std::string& xml_str, const std::string& system_id=std::string()) 02887 : XMLPos(&_msg) 02888 { 02889 _msg.read_buffer(xml_str.c_str(), xml_str.length(), system_id); 02890 } 02891 02892 const XMLDoc& get_document() 02893 { 02894 return _msg; 02895 } 02896 02897 protected: 02898 XMLDoc _msg; 02899 }; 02900 02901 02903 struct XMLWriter 02904 { 02905 XMLWriter(std::ostream& out, const XMLFormat& format=XMLFormat()) 02906 : _pofstream(NULL), 02907 _out(out), 02908 _format(format) 02909 { 02910 format.print_header(_out, false); // _format._endl is printed in write_pre() 02911 } 02912 02913 XMLWriter(LPCTSTR path, const XMLFormat& format=XMLFormat()) 02914 : _pofstream(new tofstream(path)), 02915 _out(*_pofstream), 02916 _format(format) 02917 { 02918 format.print_header(_out, false); // _format._endl is printed in write_pre() 02919 } 02920 02921 ~XMLWriter() 02922 { 02923 _out << _format._endl; 02924 delete _pofstream; 02925 } 02926 02928 void create(const XS_String& name); 02929 02931 bool back(); 02932 02934 void put(const XS_String& attr_name, const XS_String& value) 02935 { 02936 if (!_stack.empty()) 02937 _stack.top()._attributes[attr_name] = value; 02938 } 02939 02941 XS_String& operator[](const XS_String& attr_name) 02942 { 02943 if (_stack.empty()) 02944 return s_empty_attr; 02945 02946 return _stack.top()._attributes[attr_name]; 02947 } 02948 02949 void set_content(const XS_String& s, bool cdata=false) 02950 { 02951 if (!_stack.empty()) 02952 _stack.top()._content = EncodeXMLString(s.c_str(), cdata); 02953 } 02954 02956 void create_node_content(const XS_String& node_name, const XS_String& content) 02957 { 02958 create(node_name); 02959 set_content(content); 02960 back(); 02961 } 02962 02963 // public for access in StackEntry 02964 enum WRITESTATE { 02965 NOTHING, /*PRE,*/ ATTRIBUTES, PRE_CLOSED, /*CONTENT,*/ POST 02966 }; 02967 02968 protected: 02969 tofstream* _pofstream; 02970 std::ostream& _out; 02971 XMLFormat _format; 02972 02973 typedef XMLNode::AttributeMap AttrMap; 02974 02976 struct StackEntry { 02977 XS_String _node_name; 02978 AttrMap _attributes; 02979 std::string _content; 02980 WRITESTATE _state; 02981 bool _children; 02982 02983 StackEntry() : _state(NOTHING), _children(false) {} 02984 }; 02985 02986 std::stack<StackEntry> _stack; 02987 02988 static XS_String s_empty_attr; 02989 02990 void close_pre(StackEntry& entry); 02991 void write_pre(StackEntry& entry); 02992 void write_attributes(StackEntry& entry); 02993 void write_post(StackEntry& entry); 02994 }; 02995 02996 02997 } // namespace XMLStorage 02998 02999 #define _XMLSTORAGE_H 03000 #endif // _XMLSTORAGE_H Generated on Sun May 27 2012 04:18:45 for ReactOS by
1.7.6.1
|