00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040 #ifndef _XMLSTORAGE_H
00041
00042 #ifndef XS_STRICT_XML_1_0
00043
00044 #endif
00045
00046
00047 #ifdef UNICODE
00048 #ifndef _UNICODE
00049 #define _UNICODE
00050 #endif
00051 #else
00052 #ifdef _UNICODE
00053 #define UNICODE
00054 #endif
00055 #endif
00056
00057 #ifndef _WIN32
00058 #ifdef UNICODE
00059 #error no UNICODE build in Unix version available
00060 #endif
00061 #ifndef XS_STRING_UTF8
00062 #define XS_STRING_UTF8
00063 #endif
00064 #endif
00065
00066
00067 #if _MSC_VER>=1400 // VS2005 or higher
00068 #ifndef _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES
00069 #define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES 1
00070 #define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_COUNT 1
00071 #define _CRT_SECURE_CPP_OVERLOAD_SECURE_NAMES 1
00072 #endif
00073 #endif
00074
00075
00076 #ifdef XS_USE_XERCES
00077
00078 #ifndef UNICODE
00079 #ifndef XS_STRING_UTF8
00080 #define XS_STRING_UTF8
00081 #endif
00082 #endif
00083
00084 #include <xercesc/parsers/SAXParser.hpp>
00085 #include <xercesc/sax/HandlerBase.hpp>
00086
00087 using XERCES_CPP_NAMESPACE_QUALIFIER Locator;
00088 using XERCES_CPP_NAMESPACE_QUALIFIER SAXParser;
00089 using XERCES_CPP_NAMESPACE_QUALIFIER HandlerBase;
00090 using XERCES_CPP_NAMESPACE_QUALIFIER InputSource;
00091 using XERCES_CPP_NAMESPACE_QUALIFIER AttributeList;
00092 using XERCES_CPP_NAMESPACE_QUALIFIER SAXParseException;
00093
00094 typedef XMLCh XML_Char;
00095
00096 #elif defined(XS_USE_EXPAT)
00097
00098 #include <expat/expat.h>
00099
00100 #else
00101 #define XS_NATIVE
00102 #endif
00103
00104
00105 #ifdef _MSC_VER
00106 #pragma warning(disable: 4786) // identifier was truncated to 'number' characters in the debug information
00107
00108 #pragma warning(push)
00109 #pragma warning(disable: 4512) // assignment operator could not be generated
00110
00111 #ifndef XS_NO_COMMENT
00112
00113 #ifdef XS_USE_XERCES
00114 #ifdef _DEBUG
00115 #pragma comment(lib, "xerces-c_2D")
00116 #else
00117 #pragma comment(lib, "xerces-c_2")
00118 #endif
00119 #elif defined(XS_USE_EXPAT)
00120 #ifdef XML_STATIC
00121 #ifndef _DEBUG
00122 #pragma comment(lib, "libexpatMT")
00123 #endif
00124 #else
00125 #pragma comment(lib, "libexpat")
00126 #endif
00127 #endif
00128
00129 #ifndef _STRING_DEFINED // _STRING_DEFINED only allowed if using xmlstorage.cpp embedded in the project
00130 #if defined(_DEBUG) && defined(_DLL) // DEBUG version only supported with MSVCRTD
00131 #if _MSC_VER==1600 // VS2010
00132 #pragma comment(lib, "xmlstorage-vc10d")
00133 #elif _MSC_VER==1500 // VS2008
00134 #pragma comment(lib, "xmlstorage-vc9d")
00135 #elif _MSC_VER==1400 // VS2005
00136 #pragma comment(lib, "xmlstorage-vc8d")
00137 #else
00138 #pragma comment(lib, "xmlstorage-vc6d")
00139 #endif
00140 #else
00141 #ifdef _DLL
00142 #if _MSC_VER==1600 // VS2010
00143 #pragma comment(lib, "xmlstorage-vc10")
00144 #elif _MSC_VER==1500 // VS2008
00145 #pragma comment(lib, "xmlstorage-vc9")
00146 #elif _MSC_VER==1400 // VS2005
00147 #pragma comment(lib, "xmlstorage-vc8")
00148 #else
00149 #pragma comment(lib, "xmlstorage-vc6")
00150 #endif
00151 #elif defined(_MT)
00152 #if _MSC_VER==1600 // VS2010
00153 #pragma comment(lib, "xmlstorage-vc10t")
00154 #elif _MSC_VER==1500 // VS2008
00155 #pragma comment(lib, "xmlstorage-vc9t")
00156 #elif _MSC_VER==1400 // VS2005
00157 #pragma comment(lib, "xmlstorage-vc8t")
00158 #else
00159 #pragma comment(lib, "xmlstorage-vc6t")
00160 #endif
00161 #else
00162
00163 #pragma comment(lib, "xmlstorage-vc6l")
00164 #endif
00165 #endif
00166 #endif // _STRING_DEFINED
00167
00168 #endif // XS_NO_COMMENT
00169
00170 #endif // _MSC_VER
00171
00172
00173 #ifdef _WIN32
00174
00175 #include <windows.h>
00176 #include <tchar.h>
00177 #include <malloc.h>
00178
00179 #ifndef _MSC_VER
00180 #include <stdio.h>
00181 #endif
00182
00183 #else // _WIN32
00184
00185 #include <wchar.h>
00186 #include <stdlib.h>
00187 #include <string.h>
00188 #include <stdarg.h>
00189 #include <alloca.h>
00190
00191 typedef char CHAR;
00192 #ifdef _WCHAR_T_DEFINED
00193 #define __wchar_t wchar_t
00194 #endif
00195
00196 typedef __wchar_t WCHAR;
00197 typedef unsigned char UCHAR;
00198 typedef char* LPSTR;
00199 typedef const char* LPCSTR;
00200 typedef WCHAR* LPWSTR;
00201 typedef const WCHAR* LPCWSTR;
00202
00203 #ifndef UNICODE
00204 #define TEXT(x) x
00205 typedef char TCHAR;
00206 typedef unsigned char _TUCHAR;
00207 typedef CHAR* PTSTR;
00208 typedef CHAR* LPTSTR;
00209 typedef const CHAR* LPCTSTR;
00210
00211 #define _ttoi atoi
00212 #define _tfopen fopen
00213 #define _tcstod strtod
00214 #define _tcslen strlen
00215 #define _tcschr strchr
00216 #define _tcsstr strstr
00217 #define _snprintf snprintf
00218 #define _sntprintf snprintf
00219 #define _vsnprintf vsnprintf
00220 #define _vsntprintf vsnprintf
00221 #define _stricmp strcasecmp
00222 #define _tcsicmp strcasecmp
00223 #define strnicmp strncasecmp
00224 #define _tcsnicmp strncasecmp
00225 #endif // UNICODE
00226
00227 #endif // _WIN32
00228
00229 #include <assert.h>
00230
00231 #ifdef __BORLANDC__
00232 #define _stricmp stricmp
00233 #endif
00234
00235
00236 #include <fstream>
00237 #include <sstream>
00238 #include <string>
00239 #include <stack>
00240 #include <list>
00241 #include <map>
00242
00243
00244 #ifndef BUFFER_LEN
00245 #define BUFFER_LEN 2048
00246 #endif
00247
00248 #define BUFFER_HUGE 0x7F80
00249
00250 #ifndef ALLOCA_MAX
00251 #define ALLOCA_MAX 0x10000
00252 #endif
00253
00254
00255 namespace XMLStorage {
00256
00257
00258 #ifndef XS_String
00259
00260 #ifdef XS_STRING_UTF8
00261 #define XS_CHAR char
00262 #define XS_TEXT(x) x
00263 #define LPXSSTR LPSTR
00264 #define LPCXSSTR LPCSTR
00265 #define XS_cmp strcmp
00266 #define XS_icmp _stricmp
00267 #define XS_ncmp strncmp
00268 #define XS_nicmp strnicmp
00269 #define XS_toi atoi
00270 #define XS_toi64 _atoi64
00271 #define XS_tod strtod
00272 #define XS_len strlen
00273 #define XS_snprintf _snprintf
00274 #define XS_vsnprintf _vsnprintf
00275 #define XS_vsnprintf_s _vsnprintf_s
00276 #define XS_strstr strstr
00277 #else
00278 #define XS_CHAR TCHAR
00279 #define XS_TEXT(x) TEXT(x)
00280 #define LPXSSTR LPTSTR
00281 #define LPCXSSTR LPCTSTR
00282 #define XS_cmp _tcscmp
00283 #define XS_icmp _tcsicmp
00284 #define XS_ncmp _tcsncmp
00285 #define XS_nicmp _tcsnicmp
00286 #define XS_toi _ttoi
00287 #define XS_toi64 _ttoi64
00288 #define XS_tod _tcstod
00289 #define XS_len _tcslen
00290 #define XS_snprintf _sntprintf
00291 #define XS_vsnprintf _vsntprintf
00292 #define XS_vsnprintf_s _vsntprintf_s
00293 #define XS_strstr _tcsstr
00294 #endif
00295
00296 #ifndef COUNTOF
00297 #if _MSC_VER>=1400 // VS2005 or higher
00298 #define COUNTOF _countof
00299 #else
00300 #define COUNTOF(b) (sizeof(b)/sizeof(b[0]))
00301 #endif
00302 #endif
00303
00304 #ifndef _MSC_VER
00305 typedef long long INT64;
00306 typedef unsigned long long UINT64;
00307 #define _atoi64 atoll
00308 #endif
00309
00310
00311
00312 struct TmpHeap
00313 {
00314 TmpHeap()
00315 {
00316 _pHeap = NULL;
00317 }
00318
00319 ~TmpHeap()
00320 {
00321 if (_pHeap)
00322 free(_pHeap);
00323 }
00324
00325 void operator=(void* p)
00326 {
00327 _pHeap = p;
00328 }
00329
00330 private:
00331 void* _pHeap;
00332 };
00333
00334
00335 #define TMP_ALLOC(T, b, h, l) \
00336 TmpHeap h; T* b; \
00337 if (l <= ALLOCA_MAX) b = (T*)alloca(sizeof(T)*l); \
00338 else h = b = (T*)malloc(sizeof(T)*l)
00339
00340
00341 extern const char* get_xmlsym_end_utf8(const char* p);
00342
00343
00344 #if defined(_STRING_DEFINED) && !defined(XS_STRING_UTF8)
00345
00346 #define XS_String String
00347
00348 #else // _STRING_DEFINED, !XS_STRING_UTF8
00349
00350
00351
00352 struct XS_String
00353 #if defined(UNICODE) && !defined(XS_STRING_UTF8)
00354 : public std::wstring
00355 #else
00356 : public std::string
00357 #endif
00358 {
00359 #if defined(UNICODE) && !defined(XS_STRING_UTF8)
00360 typedef std::wstring super;
00361 #else
00362 typedef std::string super;
00363 #endif
00364
00365 XS_String() {}
00366
00367 XS_String(LPCXSSTR s) {if (s) super::assign(s);}
00368 XS_String(LPCXSSTR s, size_t l) : super(s, l) {}
00369
00370 XS_String(const super& other) : super(other) {}
00371 XS_String(const XS_String& other) : super(other) {}
00372
00373 #ifdef _WIN32
00374 #if defined(UNICODE) && !defined(XS_STRING_UTF8)
00375 XS_String(LPCSTR s) {assign(s);}
00376 XS_String(LPCSTR s, size_t l) {assign(s, l);}
00377 XS_String(const std::string& s) {assign(s.c_str());}
00378 XS_String& operator=(LPCSTR s) {assign(s); return *this;}
00379 void assign(LPCSTR s) {if (s) {size_t bl=strlen(s); TMP_ALLOC(WCHAR, b, h, bl); if (b) super::assign(b, MultiByteToWideChar(CP_ACP, 0, s, (int)bl, b, (int)bl));} else erase();}
00380 void assign(LPCSTR s, size_t l) {if (s) {size_t bl=l; TMP_ALLOC(WCHAR, b, h, bl); if (b) super::assign(b, MultiByteToWideChar(CP_ACP, 0, s, (int)l, b, (int)bl));} else erase();}
00381 #else
00382 XS_String(LPCWSTR s) {assign(s);}
00383 XS_String(LPCWSTR s, size_t l) {assign(s, l);}
00384 XS_String(const std::wstring& ws) {assign(ws.c_str());}
00385 XS_String& operator=(LPCWSTR s) {assign(s); return *this;}
00386 #ifdef XS_STRING_UTF8
00387 void assign(LPCWSTR s) {if (s) {size_t bl=4*wcslen(s); TMP_ALLOC(char, b, h, bl); if (b) super::assign(b, WideCharToMultiByte(CP_UTF8, 0, s, (int)bl, b, (int)bl, 0, 0));} else erase();}
00388 void assign(LPCWSTR s, size_t l) {if (s) {size_t bl=4*l; TMP_ALLOC(char, b, h, bl); if (b) super::assign(b, WideCharToMultiByte(CP_UTF8, 0, s, (int)l, b, (int)bl, 0, 0));} else erase();}
00389 #else // if !UNICODE && !XS_STRING_UTF8
00390 void assign(LPCWSTR s) {if (s) {size_t bl=wcslen(s); TMP_ALLOC(char, b, h, bl); if (b) super::assign(b, WideCharToMultiByte(CP_ACP, 0, s, (int)bl, b, (int)bl, 0, 0));} else erase();}
00391 void assign(LPCWSTR s, size_t l) {if (s) {size_t bl=l; TMP_ALLOC(char, b, h, bl); if (b) super::assign(b, WideCharToMultiByte(CP_ACP, 0, s, (int)l, b, (int)bl, 0, 0));} else erase();}
00392 #endif
00393 #endif
00394 #endif // _WIN32
00395
00396 #ifdef __ISSD_H
00397
00398
00399 XS_String& operator=(const _ISSD RString& s) {assign(s); return *this;}
00400 #endif
00401
00402 #ifdef XS_STRING_UTF8
00403 void assign(const XS_String& s) {assign(s.c_str());}
00404 #endif
00405
00406 XS_String& operator=(LPCXSSTR s) {if (s) super::assign(s); else erase(); return *this;}
00407 XS_String& operator=(const super& s) {super::assign(s); return *this;}
00408 void assign(LPCXSSTR s) {super::assign(s);}
00409 void assign(LPCXSSTR s, size_t l) {super::assign(s, l);}
00410
00411 operator LPCXSSTR() const {return c_str();}
00412
00413 #ifdef _WIN32
00414 #ifdef XS_STRING_UTF8
00415 operator std::wstring() const {size_t bl=length(); TMP_ALLOC(WCHAR, b, h, bl); return b? std::wstring(b, MultiByteToWideChar(CP_UTF8, 0, c_str(), bl, b, bl)): std::wstring();}
00416 #elif defined(UNICODE)
00417 operator std::string() const {size_t bl=length(); TMP_ALLOC(char, b, h, bl); return b? std::string(b, WideCharToMultiByte(CP_ACP, 0, c_str(), (int)bl, b, (int)bl, 0, 0)): std::string();}
00418 #else
00419 operator std::wstring() const {size_t bl=length(); TMP_ALLOC(WCHAR, b, h, bl); return b? std::wstring(b, MultiByteToWideChar(CP_ACP, 0, c_str(), (int)bl, b, (int)bl)): std::wstring();}
00420 #endif
00421 #endif
00422
00423 XS_String& printf(LPCXSSTR fmt, ...)
00424 {
00425 va_list vl;
00426
00427 va_start(vl, fmt);
00428 vprintf(fmt, vl);
00429 va_end(vl);
00430
00431 return *this;
00432 }
00433
00434 XS_String& vprintf(LPCXSSTR fmt, va_list vl)
00435 {
00436 XS_CHAR b[BUFFER_LEN];
00437
00438 int l = XS_vsnprintf(b, COUNTOF(b), fmt, vl);
00439
00440 if (l >= 0)
00441 super::assign(b, l);
00442 else {
00443 LPTSTR p = (LPTSTR)malloc(sizeof(TCHAR)*BUFFER_HUGE);
00444
00445 if (p) {
00446 #ifdef __STDC_WANT_SECURE_LIB__
00447 l = XS_vsnprintf_s(p, BUFFER_HUGE, _TRUNCATE, fmt, vl);
00448 #else
00449 l = XS_vsnprintf(p, BUFFER_HUGE, fmt, vl);
00450 #endif
00451 if (l >= 0)
00452 super::assign(p, l);
00453 else
00454 super::assign(fmt);
00455
00456 free(p);
00457 } else
00458 super::assign(fmt);
00459 }
00460
00461 return *this;
00462 }
00463
00464 XS_String& appendf(LPCXSSTR fmt, ...)
00465 {
00466 va_list vl;
00467
00468 va_start(vl, fmt);
00469 vappendf(fmt, vl);
00470 va_end(vl);
00471
00472 return *this;
00473 }
00474
00475 XS_String& vappendf(LPCXSSTR fmt, va_list vl)
00476 {
00477 XS_CHAR b[BUFFER_LEN];
00478
00479 int l = XS_vsnprintf(b, COUNTOF(b), fmt, vl);
00480
00481 if (l >= 0)
00482 super::append(b, l);
00483 else {
00484 LPTSTR p = (LPTSTR)malloc(sizeof(TCHAR)*BUFFER_HUGE);
00485
00486 if (p) {
00487 #ifdef __STDC_WANT_SECURE_LIB__
00488 l = XS_vsnprintf_s(p, BUFFER_HUGE, _TRUNCATE, fmt, vl);
00489 #else
00490 l = XS_vsnprintf(p, BUFFER_HUGE, fmt, vl);
00491 #endif
00492 if (l >= 0)
00493 super::append(p, l);
00494 else
00495 super::append(fmt);
00496
00497 free(p);
00498 } else
00499 super::append(fmt);
00500 }
00501
00502 return *this;
00503 }
00504 };
00505
00506 #endif // _STRING_DEFINED, !XS_STRING_UTF8
00507
00508 #endif // XS_String
00509
00510
00511 #define XS_EMPTY_STR XS_TEXT("")
00512 #define XS_TRUE_STR XS_TEXT("true")
00513 #define XS_FALSE_STR XS_TEXT("false")
00514 #define XS_INTFMT_STR XS_TEXT("%d")
00515 #define XS_INT64FMT_STR XS_TEXT("%I64d")
00516 #define XS_FLOATFMT_STR XS_TEXT("%f")
00517
00518 #define XS_KEY_STR XS_TEXT("key")
00519 #define XS_VALUE_STR XS_TEXT("value")
00520 #define XS_PROPERTY_STR XS_TEXT("property")
00521
00522
00523 #ifdef __GNUC__
00524 extern const LPCXSSTR XS_EMPTY;
00525 extern const LPCXSSTR XS_TRUE;
00526 extern const LPCXSSTR XS_FALSE;
00527 extern const LPCXSSTR XS_INTFMT;
00528 extern const LPCXSSTR XS_INT64FMT;
00529 extern const LPCXSSTR XS_FLOATFMT;
00530 #else
00531 #define XS_EMPTY XS_EMPTY_STR
00532 #define XS_TRUE XS_TRUE_STR
00533 #define XS_FALSE XS_FALSE_STR
00534 #define XS_INTFMT XS_INTFMT_STR
00535 #define XS_INT64FMT XS_INT64FMT_STR
00536 #define XS_FLOATFMT XS_FLOATFMT_STR
00537 #endif
00538
00539 extern const XS_String XS_KEY;
00540 extern const XS_String XS_VALUE;
00541 extern const XS_String XS_PROPERTY;
00542
00543 #define CDATA_START "<![CDATA["
00544 #define CDATA_END "]]>"
00545
00546
00547 #ifndef _MSC_VER
00548 inline int _istspace(TCHAR c)
00549 {
00550 #ifdef UNICODE
00551 return u_isspace(c);
00552 #else
00553 return isspace(c);
00554 #endif
00555 }
00556 #endif
00557
00558 inline LPCXSSTR safe_skip_space(LPCXSSTR s)
00559 {
00560 if (s) {
00561
00562 while(_istspace(*s))
00563 ++s;
00564
00565 return s;
00566 } else
00567 return XS_EMPTY_STR;
00568 }
00569
00570
00571 #ifdef XS_STRING_UTF8
00572
00573 template<typename T> inline XS_String from_utf8(const T& s)
00574 {
00575 return s;
00576 }
00577
00578 inline XS_String from_utf8(const char* s, size_t l)
00579 {
00580 return XS_String(s, l);
00581 }
00582
00583 #else
00584
00585
00586 inline void assign_utf8(XS_String& s, const char* str, size_t lutf8)
00587 {
00588 int l;
00589
00590
00591 #ifdef UNICODE
00592 TMP_ALLOC(TCHAR, buffer, h, lutf8);
00593 l = buffer? MultiByteToWideChar(CP_UTF8, 0, str, (int)lutf8, buffer, (int)lutf8): 0;
00594 #else
00595 TMP_ALLOC(WCHAR, wbuffer, hw, lutf8);
00596 l = wbuffer? MultiByteToWideChar(CP_UTF8, 0, str, (int)lutf8, wbuffer, (int)lutf8): 0;
00597
00598 int bl = 2*l;
00599 TMP_ALLOC(char, buffer, h, bl);
00600 l = wbuffer && buffer? WideCharToMultiByte(CP_ACP, 0, wbuffer, l, buffer, bl, 0, 0): 0;
00601 #endif
00602
00603 if (buffer)
00604 s.assign(buffer, l);
00605 }
00606
00607
00608 inline void assign_utf8(XS_String& s, const char* str)
00609 {
00610 assign_utf8(s, str, strlen(str));
00611 }
00612
00613
00614 inline std::string get_utf8(LPCTSTR s, size_t l)
00615 {
00616 #ifdef UNICODE
00617 size_t bl = 4*l;
00618 TMP_ALLOC(char, buffer, h, bl);
00619 l = buffer? WideCharToMultiByte(CP_UTF8, 0, s, (int)l, buffer, (int)bl, 0, 0): 0;
00620 #else
00621 TMP_ALLOC(WCHAR, wbuffer, hw, l);
00622 l = wbuffer? MultiByteToWideChar(CP_ACP, 0, s, (int)l, wbuffer, (int)l): 0;
00623
00624 size_t bl = 4*l;
00625 TMP_ALLOC(char, buffer, h, bl);
00626 l = wbuffer && buffer? WideCharToMultiByte(CP_UTF8, 0, wbuffer, (int)l, buffer, (int)bl, 0, 0): 0;
00627 #endif
00628
00629 return buffer? std::string(buffer, l): std::string();
00630 }
00631
00632 #ifdef UNICODE
00633
00634 inline std::string get_utf8(const char* s, size_t l)
00635 {
00636 TMP_ALLOC(WCHAR, wbuffer, wh, l);
00637 l = wbuffer? MultiByteToWideChar(CP_ACP, 0, s, (int)l, wbuffer, (int)l): 0;
00638
00639 size_t bl = 4*l;
00640 TMP_ALLOC(char, buffer, h, bl);
00641 l = buffer? WideCharToMultiByte(CP_UTF8, 0, wbuffer, (int)l, buffer, (int)bl, 0, 0): 0;
00642
00643 return wbuffer && buffer? std::string(buffer, l): std::string();
00644 }
00645 #endif
00646
00647
00648 inline std::string get_utf8(const XS_String& s)
00649 {
00650 return get_utf8(s.c_str(), s.length());
00651 }
00652
00653 inline XS_String from_utf8(const char* s)
00654 {
00655 XS_String ret;
00656 assign_utf8(ret, s, strlen(s));
00657 return ret;
00658 }
00659
00660 inline XS_String from_utf8(const std::string& s)
00661 {
00662 XS_String ret;
00663 assign_utf8(ret, s.c_str(), s.length());
00664 return ret;
00665 }
00666
00667 inline XS_String from_utf8(const char* s, size_t l)
00668 {
00669 XS_String ret;
00670 assign_utf8(ret, s, l);
00671 return ret;
00672 }
00673
00674 #endif // XS_STRING_UTF8
00675
00676 extern std::string EncodeXMLString(const XS_String& str, bool cdata=false);
00677 extern XS_String DecodeXMLString(const std::string& str_utf8);
00678
00679
00680 #ifdef __GNUC__
00681 #include <ext/stdio_filebuf.h>
00682 #define FILE_FILEBUF __gnu_cxx::stdio_filebuf<char>
00683 #elif defined(_MSC_VER)
00684 #define FILE_FILEBUF std::filebuf
00685 #endif
00686
00687 #ifdef FILE_FILEBUF
00688
00689
00690 struct FileHolder
00691 {
00692 FileHolder(LPCTSTR path, LPCTSTR mode)
00693 : _own_file(true)
00694 {
00695 #ifdef __STDC_WANT_SECURE_LIB__ // secure CRT functions using VS 2005
00696 if (_tfopen_s(&_pfile, path, mode) != 0)
00697 _pfile = NULL;
00698 #else
00699 _pfile = _tfopen(path, mode);
00700 #endif
00701 }
00702
00703 FileHolder(FILE* pfile)
00704 : _pfile(pfile),
00705 _own_file(false)
00706 {
00707 }
00708
00709 ~FileHolder()
00710 {
00711 if (_own_file && _pfile)
00712 fclose(_pfile);
00713 }
00714
00715 operator FILE*() {return _pfile;}
00716
00717 protected:
00718 FILE* _pfile;
00719 bool _own_file;
00720 };
00721
00722
00723 struct tifstream : public std::istream, FileHolder
00724 {
00725 typedef std::istream super;
00726
00727 tifstream(LPCTSTR path)
00728 : super(&_buf),
00729 FileHolder(path, TEXT("rb")),
00730 #ifdef __GNUC__
00731 _buf(_pfile, std::ios::in)
00732 #else
00733 _buf(_pfile)
00734 #endif
00735 {
00736 if (!_pfile)
00737 setstate(badbit);
00738 }
00739
00740 protected:
00741 FILE_FILEBUF _buf;
00742 };
00743
00744
00745 struct tofstream : public std::ostream, FileHolder
00746 {
00747 typedef std::ostream super;
00748
00749 tofstream(LPCTSTR path, LPCTSTR mode=TEXT("wb"))
00750 : super(&_buf),
00751 FileHolder(path, mode),
00752 #ifdef __GNUC__
00753 _buf(_pfile, std::ios::out)
00754 #else
00755 _buf(_pfile)
00756 #endif
00757 {
00758 if (!_pfile)
00759 setstate(badbit);
00760 }
00761
00762 tofstream(FILE* pFile)
00763 : super(&_buf),
00764 FileHolder(pFile),
00765 #ifdef __GNUC__
00766 _buf(_pfile, std::ios::out)
00767 #else
00768 _buf(_pfile)
00769 #endif
00770 {
00771 if (!_pfile)
00772 setstate(badbit);
00773 }
00774
00775 ~tofstream()
00776 {
00777 flush();
00778 }
00779
00780 protected:
00781 FILE_FILEBUF _buf;
00782 };
00783
00784 #else // FILE_FILEBUF
00785
00786 #ifdef UNICODE
00787 #error UNICODE not supported for this platform
00788 #endif
00789
00790 struct tifstream : public std::ifstream
00791 {
00792 typedef std::ifstream super;
00793
00794 tifstream(const char* path)
00795 : super(path, std::ios::in|std::ios::binary)
00796 {
00797 }
00798 };
00799
00800 struct tofstream : public std::ofstream
00801 {
00802 typedef std::ofstream super;
00803
00804 tofstream(const char* path)
00805 : super(path, std::ios::out|std::ios::binary)
00806 {
00807 }
00808 };
00809
00810 #endif
00811
00812
00813
00814 #define XML_INDENT_SPACE " "
00815
00816
00817 #if defined(XS_USE_XERCES) || defined(XS_USE_EXPAT)
00818
00819 #if defined(XML_UNICODE) || defined(XS_USE_XERCES) // Are Expat/Xerces XML strings UTF-16 encoded?
00820 typedef XS_String String_from_XML_Char;
00821
00822 #elif defined(XS_STRING_UTF8)
00823 typedef XS_String String_from_XML_Char;
00824
00825 #else
00826
00827
00828 struct String_from_XML_Char : public XS_String
00829 {
00830 String_from_XML_Char(const XML_Char* str)
00831 {
00832 assign_utf8(*this, str);
00833 }
00834 };
00835
00836 #endif
00837
00838 #endif // defined(XS_USE_XERCES) || defined(XS_USE_EXPAT)
00839
00840
00841 #if defined(UNICODE) && !defined(XS_STRING_UTF8)
00842
00843
00844 inline bool operator==(const XS_String& s1, const char* s2)
00845 {
00846 LPCWSTR p = s1;
00847 const unsigned char* q = (const unsigned char*)s2;
00848
00849 while(*p && *q)
00850 if (*p++ != *q++)
00851 return false;
00852
00853 return *p == *q;
00854 };
00855
00856 #endif
00857
00858
00859 #if defined(XS_NATIVE) || defined(XMLNODE_LOCATION)
00860
00861 struct XMLLocation
00862 {
00863 XMLLocation()
00864 : _pdisplay_path(NULL),
00865 _line(0),
00866 _column(0)
00867 {
00868 }
00869
00870 XMLLocation(const char* display_path, int line, int column)
00871 : _pdisplay_path(display_path),
00872 _line(line),
00873 _column(column)
00874 {
00875 }
00876
00877 std::string str() const;
00878
00879 const char* get_path() const {return _pdisplay_path? _pdisplay_path: "";}
00880 int get_line() const {return _line;}
00881 int get_column() const {return _column;}
00882
00883 void set_path(const char* path)
00884 {
00885 _pdisplay_path = path;
00886 _line = 1;
00887 _column = 1;
00888 }
00889
00890 protected:
00891 const char* _pdisplay_path;
00892 int _line;
00893 int _column;
00894
00895 friend struct XMLReader;
00896 };
00897 #endif
00898
00899
00900
00901 struct XMLError
00902 {
00903 XMLError()
00904 : _line(0),
00905 _column(0),
00906 _error_code(0)
00907 {
00908 }
00909
00910 XMLError(const char* msg)
00911 : _line(0),
00912 _column(0),
00913 _error_code(0),
00914 _message(msg)
00915 {
00916 }
00917
00918 XMLError(const XMLLocation& location, const char* msg)
00919 : _systemId(location.get_path()),
00920 _line(location.get_line()),
00921 _column(location.get_column()),
00922 _error_code(0),
00923 _message(msg)
00924 {
00925 }
00926
00927 std::string str() const;
00928
00929 friend std::ostream& operator<<(std::ostream&, const XMLError& err);
00930
00931 std::string _message;
00932 std::string _systemId;
00933 int _line;
00934 int _column;
00935 int _error_code;
00936 };
00937
00938
00939 struct XMLErrorList : public std::list<XMLError>
00940 {
00941 XS_String str(const char* del="\n") const;
00942 };
00943
00944
00945 enum PRETTY_FLAGS {
00946 PRETTY_PLAIN = 0,
00947 PRETTY_LINEFEED = 1,
00948 PRETTY_INDENT = 2
00949 };
00950
00951
00952
00953 struct StyleSheet
00954 {
00955 std::string _href;
00956 std::string _type;
00957 std::string _title;
00958 std::string _media;
00959 std::string _charset;
00960 bool _alternate;
00961
00962 StyleSheet() : _alternate(false) {}
00963
00964 StyleSheet(const std::string& href, const std::string& type="text/xsl", bool alternate=false)
00965 : _href(href),
00966 _type(type),
00967 _alternate(alternate)
00968 {
00969 }
00970
00971 bool empty() const {return _href.empty();}
00972 void print(std::ostream& out) const;
00973 };
00974
00975
00976 struct StyleSheetList : public std::list<StyleSheet>
00977 {
00978 void set(const StyleSheet& stylesheet)
00979 {
00980 clear();
00981 push_back(stylesheet);
00982 }
00983 };
00984
00985
00986
00987 struct DocType
00988 {
00989 std::string _name;
00990
00991
00992 std::string _public;
00993 std::string _system;
00994
00995
00996
00997 void parse(const char* str);
00998 bool empty() const {return _name.empty();}
00999 };
01000
01001
01002 struct XMLFormat
01003 {
01004 XMLFormat(PRETTY_FLAGS pretty=PRETTY_INDENT, const std::string& encoding="utf-8", const DocType& doctype=DocType()
01005 #ifndef XS_STRICT_XML_1_0
01006 , const std::string& xml_version="1.0"
01007 #endif
01008 )
01009 : _pretty(pretty),
01010 _endl("\n"),
01011 #ifdef XS_STRICT_XML_1_0
01012 _version("1.0"),
01013 #else
01014 _version(xml_version),
01015 #endif
01016 _encoding(encoding),
01017 _utf8_bom(false),
01018 _inhibit_header(false),
01019 _doctype(doctype),
01020 _standalone(-1)
01021 {
01022 }
01023
01024 XMLFormat(PRETTY_FLAGS pretty, bool utf8_bom, const DocType& doctype=DocType())
01025 : _pretty(pretty),
01026 _endl("\n"),
01027 _version("1.0"),
01028 _encoding("utf-8"),
01029 _utf8_bom(utf8_bom),
01030 _inhibit_header(false),
01031 _doctype(doctype),
01032 _standalone(-1)
01033 {
01034 }
01035
01036 void print_header(std::ostream& out, bool lf=true) const;
01037
01038 PRETTY_FLAGS _pretty;
01039 const char* _endl;
01040
01041 std::string _version;
01042 std::string _encoding;
01043 bool _utf8_bom;
01044 bool _inhibit_header;
01045
01046 DocType _doctype;
01047
01048 StyleSheetList _stylesheets;
01049
01050
01051
01052 int _standalone;
01053 };
01054
01055 struct HeaderlessXMLFormat : public XMLFormat
01056 {
01057 HeaderlessXMLFormat(PRETTY_FLAGS pretty=PRETTY_INDENT)
01058 : XMLFormat(pretty)
01059 {
01060 _inhibit_header = true;
01061 }
01062 };
01063
01064
01065 enum WRITE_MODE {
01066 FORMAT_PLAIN,
01067 FORMAT_SMART,
01068 FORMAT_ORIGINAL,
01069 FORMAT_PRETTY
01070 };
01071
01072
01073 #if 1
01074
01075
01076 struct XS_SMNode
01077 {
01078 XS_SMNode(const XS_String& key)
01079 : first(key),
01080 _pNext(NULL)
01081 {
01082 }
01083
01084
01085 XS_SMNode(const XS_SMNode& other)
01086 : first(other.first),
01087 second(other.second)
01088 {
01089 if (other._pNext)
01090 _pNext = new XS_SMNode(*other._pNext);
01091 else
01092 _pNext = NULL;
01093 }
01094
01095 ~XS_SMNode()
01096 {
01097 delete _pNext;
01098 }
01099
01100 XS_String first;
01101 XS_String second;
01102
01103 XS_SMNode* _pNext;
01104
01105 private:
01106 XS_SMNode& operator=(const XS_SMNode&);
01107 };
01108
01109
01110 struct XS_StringMap
01111 {
01112 typedef XS_String key_type;
01113 typedef XS_String value_type;
01114
01115 struct iterator
01116 {
01117 iterator(XS_SMNode* ptr)
01118 : _ptr(ptr)
01119 {
01120 }
01121
01122 operator bool() const
01123 {
01124 return _ptr != NULL;
01125 }
01126
01127 XS_SMNode* operator->()
01128 {
01129 return _ptr;
01130 }
01131
01132 const XS_SMNode* operator->() const
01133 {
01134 return _ptr;
01135 }
01136
01137 void operator++()
01138 {
01139 _ptr = _ptr->_pNext;
01140 }
01141
01142 XS_SMNode* ptr()
01143 {
01144 return _ptr;
01145 }
01146
01147 const XS_SMNode* ptr() const
01148 {
01149 return _ptr;
01150 }
01151
01152 XS_SMNode& operator*()
01153 {
01154 return *_ptr;
01155 }
01156
01157 const XS_SMNode& operator*() const
01158 {
01159 return *_ptr;
01160 }
01161
01162 private:
01163 XS_SMNode* _ptr;
01164 };
01165
01166 struct const_iterator
01167 {
01168 const_iterator(const XS_SMNode* ptr)
01169 : _ptr(ptr)
01170 {
01171 }
01172
01173 const_iterator(const iterator& it)
01174 : _ptr(it.ptr())
01175 {
01176 }
01177
01178 operator bool() const
01179 {
01180 return _ptr != NULL;
01181 }
01182
01183 const XS_SMNode* operator->() const
01184 {
01185 return _ptr;
01186 }
01187
01188 void operator++()
01189 {
01190 _ptr = _ptr->_pNext;
01191 }
01192
01193 const XS_SMNode* ptr() const
01194 {
01195 return _ptr;
01196 }
01197
01198 const XS_SMNode& operator*() const
01199 {
01200 return *_ptr;
01201 }
01202
01203 private:
01204 const XS_SMNode* _ptr;
01205 };
01206
01207 XS_StringMap()
01208 : _firstNode(NULL)
01209 {
01210 }
01211
01212 XS_StringMap(const XS_StringMap& other)
01213 : _firstNode(NULL)
01214 {
01215 assign(other);
01216 }
01217
01218 XS_StringMap& operator=(const XS_StringMap& other)
01219 {
01220 clear();
01221 assign(other);
01222 return *this;
01223 }
01224
01225 ~XS_StringMap()
01226 {
01227 clear();
01228 }
01229
01230 void clear()
01231 {
01232 XS_SMNode* node = _firstNode;
01233 _firstNode = NULL;
01234
01235 while(node) {
01236 XS_SMNode* pNext = node->_pNext;
01237 node->_pNext = NULL;
01238
01239 delete node;
01240
01241 node = pNext;
01242 }
01243 }
01244
01245 iterator begin()
01246 {
01247 return _firstNode;
01248 }
01249
01250 const_iterator begin() const
01251 {
01252 return _firstNode;
01253 }
01254
01255 iterator end()
01256 {
01257 return NULL;
01258 }
01259
01260 const_iterator end() const
01261 {
01262 return NULL;
01263 }
01264
01265 iterator find(const key_type& key)
01266 {
01267 for(iterator node=_firstNode; node; node=node->_pNext) {
01268 int c = node->first.compare(key);
01269
01270 if (c == 0)
01271 return node;
01272 else if (c > 0)
01273 break;
01274 }
01275
01276 return NULL;
01277 }
01278
01279 const_iterator find(const key_type& key) const
01280 {
01281 for(const_iterator node=_firstNode; node; node=node->_pNext) {
01282 int c = node->first.compare(key);
01283
01284 if (c == 0)
01285 return node;
01286 else if (c > 0)
01287 break;
01288 }
01289
01290 return NULL;
01291 }
01292
01293 value_type& operator[](const key_type& key)
01294 {
01295 iterator last = NULL;
01296 iterator node = _firstNode;
01297
01298 for(; node; node=(last=node)->_pNext) {
01299 int c = node->first.compare(key);
01300
01301 if (c == 0)
01302 break;
01303 else if (c > 0) {
01304 node = NULL;
01305 break;
01306 }
01307 }
01308
01309 if (!node) {
01310
01311 node = new XS_SMNode(key);
01312
01313 if (last) {
01314 node->_pNext = last->_pNext;
01315 last->_pNext = node.ptr();
01316 } else {
01317 node->_pNext = _firstNode;
01318 _firstNode = node.ptr();
01319 }
01320 }
01321
01322 return node->second;
01323 }
01324
01325 bool empty() const
01326 {
01327 return _firstNode == NULL;
01328 }
01329
01330 size_t size() const
01331 {
01332 size_t count = 0;
01333
01334 for(iterator node=_firstNode; node; node=node->_pNext)
01335 ++count;
01336
01337 return count;
01338 }
01339
01340 bool erase(const key_type& key)
01341 {
01342 iterator last = NULL;
01343 iterator node = _firstNode;
01344
01345 for(; node; node=(last=node)->_pNext) {
01346 int c = node->first.compare(key);
01347
01348 if (c == 0) {
01349
01350 if (last)
01351 last->_pNext = node->_pNext;
01352 else
01353 _firstNode = node->_pNext;
01354
01355 node->_pNext = NULL;
01356
01357 delete node.ptr();
01358
01359 return true;
01360 } else if (c > 0)
01361 break;
01362 }
01363
01364 return false;
01365 }
01366
01367 bool operator==(const XS_StringMap& other) const
01368 {
01369 const_iterator it1 = _firstNode;
01370 const_iterator it2 = other._firstNode;
01371
01372 while(it1 || it2) {
01373 if (!it1 || !it2)
01374 return false;
01375
01376 if (it1->first != it2->first)
01377 return false;
01378
01379 if (it1->second != it2->second)
01380 return false;
01381
01382 it1 = it1->_pNext;
01383 it2 = it2->_pNext;
01384 }
01385
01386 return !it1 && !it2;
01387 }
01388
01389 bool operator!=(const XS_StringMap& other) const
01390 {
01391 return !operator==(other);
01392 }
01393
01394 private:
01395 XS_SMNode* _firstNode;
01396
01397 void assign(const XS_StringMap& other)
01398 {
01399 if (other._firstNode)
01400 _firstNode = new XS_SMNode(*other._firstNode);
01401 }
01402 };
01403
01404 #else
01405
01406 typedef std::map<XS_String, XS_String> XS_StringMap;
01407
01408 #endif
01409
01410
01411 struct XMLNode;
01412
01413 struct XPathElement
01414 {
01415 XPathElement() : _child_idx(-1) {}
01416
01417 XPathElement(const XS_String& child_name, int child_idx=-1)
01418 : _child_name(child_name), _child_idx(child_idx)
01419 {
01420 }
01421
01422 XPathElement(const XS_String& child_name, int child_idx, const XS_String& attr_name, const XS_String& attr_value)
01423 : _child_name(child_name), _child_idx(child_idx)
01424 {
01425 _mAttrAndAttr[attr_name] = attr_value;
01426 }
01427
01428 XS_String _child_name;
01429 int _child_idx;
01430
01431 typedef XS_StringMap MAPATTR;
01432 MAPATTR _mAttrAndAttr;
01433
01434 LPCXSSTR parse(LPCXSSTR path);
01435
01436 XMLNode* find(XMLNode* node) const;
01437 const XMLNode* const_find(const XMLNode* node) const;
01438
01439 bool matches(const XMLNode& node, int& n) const;
01440 };
01441
01442 struct XPath : std::list<XPathElement>
01443 {
01444 XPath() : _absolute(false) {}
01445 XPath(LPCXSSTR path) {init(path);}
01446 XPath(const XS_String& path) {init(path.c_str());}
01447
01448 void init(LPCXSSTR path);
01449
01450 bool _absolute;
01451 };
01452
01453
01454
01455 struct XMLNode : public XS_String
01456 {
01457 #if defined(UNICODE) && !defined(XS_STRING_UTF8)
01458
01459
01460 struct AttributeMap : public XS_StringMap
01461 {
01462 typedef XS_StringMap super;
01463
01464 const_iterator find(const char* x) const
01465 {
01466 for(const_iterator it=begin(); it!=end(); ++it)
01467 if (it->first == x)
01468 return it;
01469
01470 return end();
01471 }
01472
01473 const_iterator find(const key_type& x) const
01474 {
01475 return super::find(x);
01476 }
01477
01478 iterator find(const key_type& x)
01479 {
01480 return super::find(x);
01481 }
01482
01483 XS_String get(const char* x, LPCXSSTR def=XS_EMPTY_STR) const
01484 {
01485 const_iterator found = find(x);
01486
01487 if (found != end())
01488 return found->second;
01489 else
01490 return def;
01491 }
01492 };
01493 #else
01494
01495 struct AttributeMap : public XS_StringMap
01496 {
01497 XS_String get(const char* x, LPCXSSTR def=XS_EMPTY_STR) const
01498 {
01499 const_iterator found = find(x);
01500
01501 if (found != end())
01502 return found->second;
01503 else
01504 return def;
01505 }
01506 };
01507 #endif
01508
01509
01510 struct Children : public std::list<XMLNode*>
01511 {
01512 typedef std::list<XMLNode*> super;
01513
01514 Children()
01515 {
01516 }
01517
01518 Children(Children& other)
01519 {
01520 for(Children::const_iterator it=other.begin(); it!=other.end(); ++it)
01521 push_back(*it);
01522 }
01523
01524 void assign(Children& other)
01525 {
01526 clear();
01527 move(other);
01528 }
01529
01530 void move(Children& other)
01531 {
01532 for(Children::const_iterator it=other.begin(); it!=other.end(); ++it)
01533 push_back(*it);
01534
01535 other.reset();
01536 }
01537
01538 Children& operator=(Children& other)
01539 {
01540 assign(other);
01541 return *this;
01542 }
01543
01544 void copy(const Children& other)
01545 {
01546 for(Children::const_iterator it=other.begin(); it!=other.end(); ++it)
01547 push_back(new XMLNode(**it));
01548 }
01549
01550 void clear()
01551 {
01552 while(!empty()) {
01553 XMLNode* node = back();
01554 pop_back();
01555
01556 node->clear();
01557 delete node;
01558 }
01559 }
01560
01561 bool remove(XMLNode* node)
01562 {
01563 for(iterator it=begin(); it!=end(); ++it)
01564 if (*it == node) {
01565 erase(it);
01566 return true;
01567 }
01568
01569 return false;
01570 }
01571
01572 private:
01573 void reset()
01574 {
01575 super::clear();
01576 }
01577 };
01578
01579
01580 friend struct XMLPos;
01581 friend struct const_XMLPos;
01582 friend struct XMLReaderBase;
01583 friend struct XPathElement;
01584
01585 XMLNode(const XS_String& name)
01586 : XS_String(name),
01587 _cdata_content(false)
01588 {
01589 }
01590
01591 XMLNode(const XS_String& name, const std::string& leading)
01592 : XS_String(name),
01593 _leading(leading),
01594 _cdata_content(false)
01595 {
01596 }
01597
01598 XMLNode(const XMLNode& other)
01599 : XS_String(other),
01600 _attributes(other._attributes),
01601 _leading(other._leading),
01602 _content(other._content),
01603 _end_leading(other._end_leading),
01604 _trailing(other._trailing),
01605 #ifdef XMLNODE_LOCATION
01606 _location(other._location),
01607 #endif
01608 _cdata_content(false)
01609 {
01610 for(Children::const_iterator it=other._children.begin(); it!=other._children.end(); ++it)
01611 _children.push_back(new XMLNode(**it));
01612 }
01613
01614 enum COPY_FLAGS {COPY_NOCHILDREN};
01615
01616 #ifdef _MSC_VER
01617 #pragma warning(disable: 4100) // unreferenced formal parameter
01618 #endif
01619 XMLNode(const XMLNode& other, COPY_FLAGS copy_no_children)
01620 : XS_String(other),
01621 _attributes(other._attributes),
01622 _leading(other._leading),
01623 _content(other._content),
01624 _end_leading(other._end_leading),
01625 _trailing(other._trailing),
01626 #ifdef XMLNODE_LOCATION
01627 _location(other._location),
01628 #endif
01629 _cdata_content(false)
01630 {
01631 assert(copy_no_children==COPY_NOCHILDREN);
01632 }
01633
01634 virtual ~XMLNode()
01635 {
01636 while(!_children.empty()) {
01637 delete _children.back();
01638 _children.pop_back();
01639 }
01640 }
01641
01642 void clear()
01643 {
01644 _leading.erase();
01645 _content.erase();
01646 _end_leading.erase();
01647 _trailing.erase();
01648
01649 _attributes.clear();
01650 _children.clear();
01651
01652 XS_String::erase();
01653 }
01654
01655 XMLNode& operator=(const XMLNode& other)
01656 {
01657 _children.clear();
01658 _children.copy(other._children);
01659
01660 _attributes = other._attributes;
01661
01662 _leading = other._leading;
01663 _content = other._content;
01664 _end_leading = other._end_leading;
01665 _trailing = other._trailing;
01666 _cdata_content = other._cdata_content;
01667
01668 return *this;
01669 }
01670
01671
01672 void add_child(XMLNode* child)
01673 {
01674 _children.push_back(child);
01675 }
01676
01677
01678 void remove_children(const XS_String& name)
01679 {
01680 Children::iterator it, next=_children.begin();
01681
01682 while((it=next) != _children.end()) {
01683 ++next;
01684
01685 if (**it == name)
01686 _children.erase(it);
01687 }
01688 }
01689
01690
01691 void put(const XS_String& attr_name, const XS_String& value)
01692 {
01693 _attributes[attr_name] = value;
01694 }
01695
01696
01697 XS_String& operator[](const XS_String& attr_name)
01698 {
01699 return _attributes[attr_name];
01700 }
01701
01702
01703 XS_String operator[](const XS_String& attr_name) const
01704 {
01705 #if defined(UNICODE) && !defined(XS_STRING_UTF8)
01706 return _attributes.get(((std::string)attr_name).c_str());
01707 #else
01708 return _attributes.get(attr_name.c_str());
01709 #endif
01710 }
01711
01712
01713 template<typename T> XS_String get(const T& attr_name, LPCXSSTR def=XS_EMPTY_STR) const
01714 {
01715 AttributeMap::const_iterator found = _attributes.find(attr_name);
01716
01717 if (found != _attributes.end())
01718 return found->second;
01719 else
01720 return def;
01721 }
01722
01723
01724 void erase(const XS_String& attr_name)
01725 {
01726 _attributes.erase(attr_name);
01727 }
01728
01729
01730 XS_String subvalue(const XS_String& child_name, const XS_String& attr_name, int n=0) const
01731 {
01732 const XMLNode* node = XPathElement(child_name, n).const_find(this);
01733
01734 if (node)
01735 return node->get(attr_name);
01736 else
01737 return XS_String();
01738 }
01739
01740
01741 XS_String& subvalue(const XS_String& child_name, const XS_String& attr_name, int n=0)
01742 {
01743 XMLNode* node = XPathElement(child_name, n).find(this);
01744
01745 if (!node) {
01746 node = new XMLNode(child_name);
01747 add_child(node);
01748 }
01749
01750 return (*node)[attr_name];
01751 }
01752
01753 #if defined(UNICODE) && !defined(XS_STRING_UTF8)
01754
01755 XS_String subvalue(const char* child_name, const char* attr_name, int n=0) const
01756 {
01757 const XMLNode* node = XPathElement(child_name, n).const_find(this);
01758
01759 if (node)
01760 return node->get(attr_name);
01761 else
01762 return XS_String();
01763 }
01764
01765
01766 XS_String& subvalue(const char* child_name, const XS_String& attr_name, int n=0)
01767 {
01768 XMLNode* node = XPathElement(child_name, n).find(this);
01769
01770 if (!node) {
01771 node = new XMLNode(child_name);
01772 add_child(node);
01773 }
01774
01775 return (*node)[attr_name];
01776 }
01777 #endif
01778
01779 const Children& get_children() const
01780 {
01781 return _children;
01782 }
01783
01784 Children& get_children()
01785 {
01786 return _children;
01787 }
01788
01789 const AttributeMap& get_attributes() const
01790 {
01791 return _attributes;
01792 }
01793
01794 AttributeMap& get_attributes()
01795 {
01796 return _attributes;
01797 }
01798
01799
01800 XS_String get_content() const
01801 {
01802 return DecodeXMLString(_content);
01803 }
01804
01805
01806 std::string get_encoded_content() const
01807 {
01808 return _content;
01809 }
01810
01811
01812 XS_String get_sub_content(const XPath& xpath) const
01813 {
01814 const XMLNode* node = find_relative(xpath);
01815
01816 if (node)
01817 return node->get_content();
01818 else
01819 return XS_EMPTY_STR;
01820 }
01821
01822
01823 void set_content(const XS_String& s, bool cdata=false)
01824 {
01825 _content.assign(EncodeXMLString(s.c_str(), cdata));
01826 }
01827
01828
01829 void set_encoded_content(const std::string& s)
01830 {
01831 _content.assign(s);
01832 }
01833
01834
01835 bool set_sub_content(const XPath& xpath, const XS_String& s, bool cdata=false)
01836 {
01837 XMLNode* node = create_relative(xpath);
01838
01839 if (node) {
01840 node->set_content(s, cdata);
01841 return true;
01842 } else
01843 return false;
01844 }
01845
01846 XS_String get_trailing() const
01847 {
01848 return DecodeXMLString(_trailing);
01849 }
01850
01851 #ifdef XMLNODE_LOCATION
01852 const XMLLocation& get_location() const {return _location;}
01853 #endif
01854
01855
01856 bool write(std::ostream& out, const XMLFormat& format, WRITE_MODE mode=FORMAT_SMART, int indent=0) const
01857 {
01858 switch(mode) {
01859 case FORMAT_PLAIN:
01860 plain_write_worker(out);
01861 break;
01862
01863 case FORMAT_PRETTY:
01864 pretty_write_worker(out, format, indent);
01865 break;
01866
01867 case FORMAT_ORIGINAL:
01868 original_write_worker(out);
01869 break;
01870
01871 default:
01872 smart_write_worker(out, format, indent);
01873 }
01874
01875 return out.good();
01876 }
01877
01878
01879 int count(const XPath& xpath) const
01880 {
01881 return count(xpath.begin(), xpath.end());
01882 }
01883
01884
01885 int count(XPath::const_iterator from, const XPath::const_iterator& to) const;
01886
01887
01888 bool filter(const XPath& xpath, XMLNode& target) const;
01889
01890
01891 const XMLNode* find_relative(const XPath& xpath) const;
01892
01893
01894 XMLNode* find_relative(const XPath& xpath);
01895
01896 XMLNode* get_first_child() const
01897 {
01898 if (!_children.empty())
01899 return _children.front();
01900 else
01901 return NULL;
01902 }
01903
01904 protected:
01905 Children _children;
01906 AttributeMap _attributes;
01907
01908 std::string _leading;
01909 std::string _content;
01910 std::string _end_leading;
01911 std::string _trailing;
01912
01913 #ifdef XMLNODE_LOCATION
01914 XMLLocation _location;
01915 #endif
01916
01917 bool _cdata_content;
01918
01919
01920 XMLNode* create_relative(const XPath& xpath);
01921
01922
01923 XMLNode* filter(XPath::const_iterator from, const XPath::const_iterator& to) const;
01924
01925 void original_write_worker(std::ostream& out) const;
01926 void plain_write_worker(std::ostream& out) const;
01927 void pretty_write_worker(std::ostream& out, const XMLFormat& format, int indent) const;
01928 void smart_write_worker(std::ostream& out, const XMLFormat& format, int indent) const;
01929 };
01930
01931
01932
01933 struct XMLChildrenFilter
01934 {
01935 XMLChildrenFilter(XMLNode::Children& children, const XS_String& name)
01936 : _begin(children.begin(), children.end(), name),
01937 _end(children.end(), children.end(), name)
01938 {
01939 }
01940
01941 XMLChildrenFilter(XMLNode* node, const XS_String& name)
01942 : _begin(node->get_children().begin(), node->get_children().end(), name),
01943 _end(node->get_children().end(), node->get_children().end(), name)
01944 {
01945 }
01946
01947
01948 struct iterator
01949 {
01950 typedef XMLNode::Children::iterator BaseIterator;
01951 typedef iterator myType;
01952
01953 iterator(BaseIterator begin, BaseIterator end, const XS_String& filter_name)
01954 : _cur(begin),
01955 _end(end),
01956 _filter_name(filter_name)
01957 {
01958 search_next();
01959 }
01960
01961 operator BaseIterator()
01962 {
01963 return _cur;
01964 }
01965
01966 const XMLNode* operator*() const
01967 {
01968 return *_cur;
01969 }
01970
01971 XMLNode* operator*()
01972 {
01973 return *_cur;
01974 }
01975
01976 myType& operator++()
01977 {
01978 ++_cur;
01979 search_next();
01980
01981 return *this;
01982 }
01983
01984 myType operator++(int)
01985 {
01986 myType ret = *this;
01987
01988 ++_cur;
01989 search_next();
01990
01991 return ret;
01992 }
01993
01994 bool operator==(const myType& other) const
01995 {
01996 return _cur == other._cur;
01997 }
01998
01999 bool operator!=(const myType& other) const
02000 {
02001 return _cur != other._cur;
02002 }
02003
02004 protected:
02005 BaseIterator _cur;
02006 BaseIterator _end;
02007 XS_String _filter_name;
02008
02009 void search_next()
02010 {
02011 while(_cur!=_end && **_cur!=_filter_name)
02012 ++_cur;
02013 }
02014 };
02015
02016 iterator begin()
02017 {
02018 return _begin;
02019 }
02020
02021 iterator end()
02022 {
02023 return _end;
02024 }
02025
02026 protected:
02027 iterator _begin;
02028 iterator _end;
02029 };
02030
02031
02032
02033 struct const_XMLChildrenFilter
02034 {
02035 const_XMLChildrenFilter(const XMLNode::Children& children, const XS_String& name)
02036 : _begin(children.begin(), children.end(), name),
02037 _end(children.end(), children.end(), name)
02038 {
02039 }
02040
02041 const_XMLChildrenFilter(const XMLNode* node, const XS_String& name)
02042 : _begin(node->get_children().begin(), node->get_children().end(), name),
02043 _end(node->get_children().end(), node->get_children().end(), name)
02044 {
02045 }
02046
02047
02048 struct const_iterator
02049 {
02050 typedef XMLNode::Children::const_iterator BaseIterator;
02051 typedef const_iterator myType;
02052
02053 const_iterator(BaseIterator begin, BaseIterator end, const XS_String& filter_name)
02054 : _cur(begin),
02055 _end(end),
02056 _filter_name(filter_name)
02057 {
02058 search_next();
02059 }
02060
02061 operator BaseIterator()
02062 {
02063 return _cur;
02064 }
02065
02066 const XMLNode* operator*() const
02067 {
02068 return *_cur;
02069 }
02070
02071 const XMLNode* operator->() const
02072 {
02073 return *_cur;
02074 }
02075
02076 myType& operator++()
02077 {
02078 ++_cur;
02079 search_next();
02080
02081 return *this;
02082 }
02083
02084 myType operator++(int)
02085 {
02086 myType ret = *this;
02087
02088 ++_cur;
02089 search_next();
02090
02091 return ret;
02092 }
02093
02094 bool operator==(const myType& other) const
02095 {
02096 return _cur == other._cur;
02097 }
02098
02099 bool operator!=(const myType& other) const
02100 {
02101 return _cur != other._cur;
02102 }
02103
02104 protected:
02105 BaseIterator _cur;
02106 BaseIterator _end;
02107 XS_String _filter_name;
02108
02109 void search_next()
02110 {
02111 while(_cur!=_end && **_cur!=_filter_name)
02112 ++_cur;
02113 }
02114 };
02115
02116 const_iterator begin()
02117 {
02118 return _begin;
02119 }
02120
02121 const_iterator end()
02122 {
02123 return _end;
02124 }
02125
02126 bool empty() const
02127 {
02128 return _end == _begin;
02129 }
02130
02131 protected:
02132 const_iterator _begin;
02133 const_iterator _end;
02134 };
02135
02136
02137
02138 struct XMLPos
02139 {
02140 XMLPos(XMLNode* root)
02141 : _root(root),
02142 _cur(root)
02143 {
02144 }
02145
02146 XMLPos(const XMLPos& other)
02147 : _root(other._root),
02148 _cur(other._cur)
02149 {
02150 }
02151
02152 XMLPos(XMLNode* node, const XS_String& name)
02153 : _root(node),
02154 _cur(node)
02155 {
02156 smart_create(name);
02157 }
02158
02159 XMLPos(XMLNode* node, const XS_String& name, const XS_String& attr_name, const XS_String& attr_value)
02160 : _root(node),
02161 _cur(node)
02162 {
02163 smart_create(name, attr_name, attr_value);
02164 }
02165
02166 XMLPos(const XMLPos& other, const XS_String& name)
02167 : _root(other._root),
02168 _cur(other._cur)
02169 {
02170 smart_create(name);
02171 }
02172
02173 XMLPos(const XMLPos& other, const XS_String& name, const XS_String& attr_name, const XS_String& attr_value)
02174 : _root(other._root),
02175 _cur(other._cur)
02176 {
02177 smart_create(name, attr_name, attr_value);
02178 }
02179
02180
02181 XMLNode& cur()
02182 {
02183 return *_cur;
02184 }
02185
02186 const XMLNode& cur() const
02187 {
02188 return *_cur;
02189 }
02190
02191
02192 operator const XMLNode*() const {return _cur;}
02193 operator XMLNode*() {return _cur;}
02194
02195 const XMLNode* operator->() const {return _cur;}
02196 XMLNode* operator->() {return _cur;}
02197
02198 const XMLNode& operator*() const {return *_cur;}
02199 XMLNode& operator*() {return *_cur;}
02200
02201
02202 XS_String get(const XS_String& attr_name, LPCXSSTR def=XS_EMPTY_STR) const
02203 {
02204 return _cur->get(attr_name, def);
02205 }
02206
02207
02208 void put(const XS_String& attr_name, const XS_String& value)
02209 {
02210 _cur->put(attr_name, value);
02211 }
02212
02213
02214 template<typename T> XS_String get(const T& attr_name) const {return (*_cur)[attr_name];}
02215 XS_String& operator[](const XS_String& attr_name) {return (*_cur)[attr_name];}
02216 const XS_String& operator[](const XS_String& attr_name) const {return (*_cur)[attr_name];}
02217
02218
02219 void add_down(XMLNode* child)
02220 {
02221 _cur->add_child(child);
02222 go_to(child);
02223 }
02224
02225
02226 bool back()
02227 {
02228 if (!_stack.empty()) {
02229 _cur = _stack.top();
02230 _stack.pop();
02231 return true;
02232 } else {
02233 assert(!_stack.empty());
02234 return false;
02235 }
02236 }
02237
02238
02239 bool go_down()
02240 {
02241 XMLNode* node = _cur->get_first_child();
02242
02243 if (node) {
02244 go_to(node);
02245 return true;
02246 } else
02247 return false;
02248 }
02249
02250
02251 bool go_down(const XS_String& child_name, int n=0)
02252 {
02253 XMLNode* node = XPathElement(child_name, n).find(_cur);
02254
02255 if (node) {
02256 go_to(node);
02257 return true;
02258 } else
02259 return false;
02260 }
02261
02262
02263 bool iterate(const XS_String& child_name, int& cnt)
02264 {
02265 XMLNode* node = XPathElement(child_name, cnt).find(_cur);
02266
02267 if (node) {
02268 go_to(node);
02269 ++cnt;
02270 return true;
02271 } else
02272 return false;
02273 }
02274
02275
02276 bool go(const XPath& xpath);
02277
02278
02279 bool create_relative(const XPath& xpath)
02280 {
02281 XMLNode* node = _cur->create_relative(xpath);
02282 if (!node)
02283 return false;
02284
02285 go_to(node);
02286 return true;
02287 }
02288
02289
02290 void create(const XS_String& name)
02291 {
02292 add_down(new XMLNode(name));
02293 }
02294
02295
02296 void create_node_content(const XS_String& node_name, const XS_String& content)
02297 {
02298 XMLNode* pNode = new XMLNode(node_name);
02299 pNode->set_content(content);
02300 _cur->add_child(pNode);
02301 }
02302
02303
02304 void smart_create(const XS_String& child_name)
02305 {
02306 XMLNode* node = XPathElement(child_name).find(_cur);
02307
02308 if (node)
02309 go_to(node);
02310 else
02311 add_down(new XMLNode(child_name));
02312 }
02313
02314
02315 void smart_create(const XS_String& child_name, const XS_String& attr_name, const XS_String& attr_value)
02316 {
02317 XMLNode* node = XPathElement(child_name, 0, attr_name, attr_value).find(_cur);
02318
02319 if (node)
02320 go_to(node);
02321 else {
02322 node = new XMLNode(child_name);
02323 add_down(node);
02324 (*node)[attr_name] = attr_value;
02325 }
02326 }
02327
02328
02329 int count(const XPath& xpath) const
02330 {
02331 return _cur->count(xpath);
02332 }
02333
02334
02335 int filter(const XPath& xpath, XMLNode& target) const
02336 {
02337 return _cur->filter(xpath, target);
02338 }
02339
02340 #if defined(UNICODE) && !defined(XS_STRING_UTF8)
02341
02342 bool go_down(const char* child_name, int n=0)
02343 {
02344 XMLNode* node = XPathElement(child_name, n).find(_cur);
02345
02346 if (node) {
02347 go_to(node);
02348 return true;
02349 } else
02350 return false;
02351 }
02352
02353
02354 void create(const char* child_name)
02355 {
02356 add_down(new XMLNode(child_name));
02357 }
02358
02359
02360 void smart_create(const char* child_name)
02361 {
02362 XMLNode* node = XPathElement(child_name).find(_cur);
02363
02364 if (node)
02365 go_to(node);
02366 else
02367 add_down(new XMLNode(child_name));
02368 }
02369
02370
02371 template<typename T, typename U>
02372 void smart_create(const char* child_name, const T& attr_name, const U& attr_value)
02373 {
02374 XMLNode* node = XPathElement(child_name, 0, attr_name, attr_value).find(_cur);
02375
02376 if (node)
02377 go_to(node);
02378 else {
02379 node = new XMLNode(child_name);
02380 add_down(node);
02381 (*node)[attr_name] = attr_value;
02382 }
02383 }
02384 #endif
02385
02386
02387 bool delete_this()
02388 {
02389 if (!_stack.empty()) {
02390 XMLNode* pLast = _stack.top();
02391
02392 if (pLast->_children.remove(_cur)) {
02393 _cur = _stack.top();
02394 return true;
02395 }
02396 }
02397
02398 return false;
02399 }
02400
02401
02402 void remove_children(const XS_String& name)
02403 {
02404 _cur->remove_children(name);
02405 }
02406
02407
02408 void erase(const XS_String& attr_name)
02409 {
02410 _cur->erase(attr_name);
02411 }
02412
02413 XS_String& str() {return *_cur;}
02414 const XS_String& str() const {return *_cur;}
02415
02416
02417 void set_property(const XS_String& key, int value, const XS_String& name=XS_PROPERTY);
02418 void set_property(const XS_String& key, double value, const XS_String& name=XS_PROPERTY);
02419 void set_property(const XS_String& key, const XS_String& value, const XS_String& name=XS_PROPERTY);
02420 void set_property(const XS_String& key, const struct XMLBool& value, const XS_String& name=XS_PROPERTY);
02421
02422 void set_property(const XS_String& key, const char* value, const XS_String& name=XS_PROPERTY)
02423 {set_property(key, XS_String(value), name);}
02424
02425 protected:
02426 friend struct const_XMLPos;
02427
02428 XMLNode* _root;
02429 XMLNode* _cur;
02430 std::stack<XMLNode*> _stack;
02431
02432
02433 void go_to(XMLNode* child)
02434 {
02435 _stack.push(_cur);
02436 _cur = child;
02437 }
02438 };
02439
02440
02441
02442 struct const_XMLPos
02443 {
02444 const_XMLPos(const XMLNode* root)
02445 : _root(root),
02446 _cur(root)
02447 {
02448 }
02449
02450 const_XMLPos(const const_XMLPos& other)
02451 : _root(other._root),
02452 _cur(other._cur)
02453 {
02454 }
02455
02456 const_XMLPos(const XMLPos& other)
02457 : _root(other._root),
02458 _cur(other._cur)
02459 {
02460 }
02461
02462
02463 const XMLNode& cur() const
02464 {
02465 return *_cur;
02466 }
02467
02468
02469 operator const XMLNode*() const {return _cur;}
02470
02471 const XMLNode* operator->() const {return _cur;}
02472
02473 const XMLNode& operator*() const {return *_cur;}
02474
02475
02476 XS_String get(const XS_String& attr_name) const
02477 {
02478 return _cur->get(attr_name);
02479 }
02480
02481
02482 template<typename T> XS_String get(const T& attr_name) const {return _cur->get(attr_name);}
02483 XS_String operator[](const XS_String& attr_name) const {return _cur->get(attr_name);}
02484
02485
02486 bool back()
02487 {
02488 if (!_stack.empty()) {
02489 _cur = _stack.top();
02490 _stack.pop();
02491 return true;
02492 } else {
02493 assert(!_stack.empty());
02494 return false;
02495 }
02496 }
02497
02498
02499 bool go_down()
02500 {
02501 const XMLNode* node = _cur->get_first_child();
02502
02503 if (node) {
02504 go_to(node);
02505 return true;
02506 } else
02507 return false;
02508 }
02509
02510
02511 bool go_down(const XS_String& child_name, int n=0)
02512 {
02513 const XMLNode* node = XPathElement(child_name, n).const_find(_cur);
02514
02515 if (node) {
02516 go_to(node);
02517 return true;
02518 } else
02519 return false;
02520 }
02521
02522
02523 bool iterate(const XS_String& child_name, int& cnt)
02524 {
02525 const XMLNode* node = XPathElement(child_name, cnt).const_find(_cur);
02526
02527 if (node) {
02528 go_to(node);
02529 ++cnt;
02530 return true;
02531 } else
02532 return false;
02533 }
02534
02535
02536 bool go(const XPath& xpath);
02537
02538 #if defined(UNICODE) && !defined(XS_STRING_UTF8)
02539
02540 bool go_down(const char* child_name, int n=0)
02541 {
02542 const XMLNode* node = XPathElement(child_name, n).const_find(_cur);
02543
02544 if (node) {
02545 go_to(node);
02546 return true;
02547 } else
02548 return false;
02549 }
02550 #endif
02551
02552 const XS_String& str() const {return *_cur;}
02553
02554 protected:
02555 const XMLNode* _root;
02556 const XMLNode* _cur;
02557 std::stack<const XMLNode*> _stack;
02558
02559
02560 void go_to(const XMLNode* child)
02561 {
02562 _stack.push(_cur);
02563 _cur = child;
02564 }
02565 };
02566
02567
02568 #ifdef _MSC_VER
02569 #pragma warning(disable: 4355) // 'this' : used in base member initializer list
02570 #endif
02571
02572
02573 struct XMLReaderBase
02574 #ifdef XS_USE_XERCES
02575 : public HandlerBase
02576 #endif
02577 {
02578 #ifdef XS_USE_XERCES
02579
02580 XMLReaderBase(XMLNode* node, InputSource* source, bool adoptSource=false);
02581 virtual ~XMLReaderBase();
02582
02583 void read(bool force_utf8=false);
02584
02585 protected:
02586 SAXParser* _parser;
02587 InputSource* _source;
02588 bool _deleteSource;
02589
02590 virtual void XMLDecl(const XMLCh* const versionStr, const XMLCh* const encodingStr,
02591 const XMLCh* const standaloneStr, const XMLCh* const actualEncodingStr);
02592
02593
02594 virtual void setDocumentLocator(const Locator* const locator);
02595 virtual void startElement(const XMLCh* const name, AttributeList& attributes);
02596 virtual void endElement(const XMLCh* const name);
02597 virtual void characters(const XMLCh* const chars, const unsigned int length);
02598 virtual void ignorableWhitespace(const XMLCh* const chars, const unsigned int length);
02599
02600
02601 virtual void error(const SAXParseException& e);
02602 virtual void fatalError(const SAXParseException& e);
02603 virtual void warning(const SAXParseException& e);
02604 virtual void resetErrors();
02605
02606 #elif defined(XS_USE_EXPAT) // !XS_USE_XERCES
02607
02608 XMLReaderBase(XMLNode* node);
02609 virtual ~XMLReaderBase();
02610
02611 protected:
02612 XML_Parser _parser;
02613
02614 static void XMLCALL XML_XmlDeclHandler(void* userData, const XML_Char* version, const XML_Char* encoding, int standalone=-1);
02615 static void XMLCALL XML_StartElementHandler(void* userData, const XML_Char* name, const XML_Char** atts);
02616 static void XMLCALL XML_EndElementHandler(void* userData, const XML_Char* name);
02617 static void XMLCALL XML_DefaultHandler(void* userData, const XML_Char* s, int len);
02618
02619 static std::string get_expat_error_string(XML_Error error_code);
02620
02621 #else // XS_USE_EXPAT
02622
02623 XMLReaderBase(XMLNode* node)
02624 : _pos(node),
02625 _endl_defined(false)
02626 {
02627 _last_tag = TAG_NONE;
02628 }
02629
02630 virtual ~XMLReaderBase();
02631
02632 bool parse(bool force_utf8=false);
02633
02634 #endif
02635
02636 public:
02637 #ifndef XS_USE_XERCES
02638 void read(bool force_utf8=false);
02639
02640 std::string get_position() const {return _location.str();}
02641 #endif
02642 const XMLFormat& get_format() const {return _format;}
02643 const char* get_endl() const {return _endl_defined? _format._endl: "\n";}
02644
02645 const XMLErrorList& get_errors() const {return _errors;}
02646 const XMLErrorList& get_warnings() const {return _warnings;}
02647
02648 void clear_errors() {_errors.clear(); _warnings.clear();}
02649
02650 #ifdef XS_NATIVE
02651 XMLLocation get_location() const {return _location;}
02652 void setSystemId(const char* systemId) {_location.set_path(systemId);}
02653 #elif defined(XMLNODE_LOCATION)
02654 const char* _display_path;
02655
02656 #ifdef XS_USE_XERCES
02657 const Locator* _locator;
02658 #endif
02659
02660 XMLLocation get_location() const;
02661 void setSystemId(const char* systemId) {_display_path = systemId;}
02662 #endif
02663
02664 std::string get_encoded_content() const {return _content;}
02665
02666 protected:
02667 XMLPos _pos;
02668
02669 std::string _content;
02670 enum {TAG_NONE, TAG_START, TAG_END} _last_tag;
02671
02672 XMLErrorList _errors;
02673 XMLErrorList _warnings;
02674
02675 XMLFormat _format;
02676 bool _endl_defined;
02677
02678 #ifdef XS_NATIVE
02679 XMLLocation _location;
02680
02681 virtual int get() = 0;
02682 int eat_endl();
02683 #elif defined(XS_USE_XERCES)
02684
02685 #elif defined(XS_USE_EXPAT)
02686 virtual int read_buffer(char* buffer, int len) = 0;
02687 #endif
02688
02689 void finish_read();
02690
02691 virtual void XmlDeclHandler(const char* version, const char* encoding, int standalone);
02692 virtual void StartElementHandler(const XS_String& name, const XMLNode::AttributeMap& attributes);
02693 virtual void EndElementHandler();
02694 #if defined(XS_USE_XERCES) || defined(XS_USE_EXPAT)
02695 virtual void DefaultHandler(const XML_Char* s, int len);
02696 #else
02697 virtual void DefaultHandler(const std::string& s);
02698 #endif
02699
02700 #if !defined(XS_USE_XERCES) && !defined(XS_USE_EXPAT)
02701 friend struct ParseContext;
02702 #endif
02703 };
02704
02705
02706
02707
02708 #ifdef XS_USE_XERCES
02709
02710 struct XercesXMLReader : public XMLReaderBase
02711 {
02712 XercesXMLReader(XMLNode* node, InputSource* source, bool adoptSource=false)
02713 : XMLReaderBase(node, source, adoptSource)
02714 {
02715 }
02716
02717 XercesXMLReader(XMLNode* node, LPCTSTR path);
02718 XercesXMLReader(XMLNode* node, const XMLByte* buffer, size_t bytes, const std::string& system_id=std::string());
02719 };
02720
02721 #define XMLReader XercesXMLReader
02722
02723 #elif defined(XS_USE_EXPAT)
02724
02725 struct ExpatXMLReader : public XMLReaderBase
02726 {
02727 ExpatXMLReader(XMLNode* node, std::istream& in)
02728 : XMLReaderBase(node),
02729 _in(in)
02730 {
02731 }
02732
02733
02734 int read_buffer(char* buffer, int len)
02735 {
02736 if (!_in.good())
02737 return -1;
02738
02739 _in.read(buffer, len);
02740
02741 return _in.gcount();
02742 }
02743
02744 protected:
02745 std::istream& _in;
02746 };
02747
02748 #define XMLReader ExpatXMLReader
02749
02750 #else // XS_USE_XERCES, XS_USE_EXPAT
02751
02752 struct XMLReader : public XMLReaderBase
02753 {
02754 XMLReader(XMLNode* node, std::istream& in)
02755 : XMLReaderBase(node),
02756 _in(in),
02757 _last_crlf(0)
02758 {
02759 }
02760
02761
02762 int get()
02763 {
02764 int c = _in.get();
02765
02766
02767
02768
02769
02770
02771 if (c=='\n' || c=='\r') {
02772 if (!_last_crlf || c==_last_crlf) {
02773 _location._column = 1;
02774 ++_location._line;
02775 _last_crlf = c;
02776 } else
02777 _last_crlf = 0;
02778 } else {
02779 ++_location._column;
02780 _last_crlf = 0;
02781 }
02782
02783 return c;
02784 }
02785
02786 protected:
02787 std::istream& _in;
02788 int _last_crlf;
02789 };
02790
02791 struct ReadBuffer
02792 {
02793 ReadBuffer(XMLErrorList& errors, XMLLocation& location);
02794 ~ReadBuffer();
02795
02796 void reset();
02797 bool empty() const {return _wptr==_buffer;}
02798 bool append(int c);
02799 const std::string& str(bool utf8);
02800 size_t len() const;
02801 bool has_CDEnd() const;
02802 XS_String get_tag() const;
02803 void get_attributes(XMLNode::AttributeMap& attributes) const;
02804 XMLLocation& get_location() const {return _location;}
02805
02806 protected:
02807 XMLErrorList& _errors;
02808 XMLLocation& _location;
02809 char* _buffer;
02810 char* _wptr;
02811 size_t _len;
02812 std::string _buffer_str;
02813
02814 private:
02815 ReadBuffer(const ReadBuffer&);
02816 };
02817
02818 struct ParseContext
02819 {
02820 ParseContext(XMLReaderBase& reader, bool force_utf8=false);
02821
02822 void read_bom();
02823 bool proceed();
02824 int process_next(int c);
02825
02826 XMLReaderBase& _reader;
02827 ReadBuffer _buffer;
02828 int _next;
02829 bool _in_comment;
02830 bool _utf8;
02831 };
02832
02833 #endif // XS_USE_XERCES
02834
02835
02836 #if defined(_MSC_VER) && _MSC_VER<1400
02837
02838 struct fast_ostringbuffer : public std::streambuf
02839 {
02840 typedef char _E;
02841 typedef std::char_traits<_E> _Tr;
02842
02843 explicit fast_ostringbuffer()
02844 {_Init(0, 0, std::_Noread);}
02845
02846 virtual ~fast_ostringbuffer()
02847 {_Tidy();}
02848
02849 std::string str() const
02850 {if (pptr() != 0)
02851 {std::string _Str(pbase(),
02852 (_Seekhigh<pptr()? pptr(): _Seekhigh) - pbase());
02853 return _Str;}
02854 else
02855 return std::string();}
02856
02857 protected:
02858 virtual int_type overflow(int_type _C = _Tr::eof())
02859 {if (_Tr::eq_int_type(_Tr::eof(), _C))
02860 return _Tr::not_eof(_C);
02861 else if (pptr() != 0 && pptr() < epptr())
02862 {*_Pninc() = _Tr::to_char_type(_C);
02863 return _C;}
02864 else
02865 {size_t _Os = gptr() == 0 ? 0 : epptr() - eback();
02866 size_t _Ns = _Os + _Alsize;
02867 _E *_P = _Al.allocate(_Ns, (void *)0);
02868 if (0 < _Os)
02869 _Tr::copy(_P, eback(), _Os);
02870 else if (_ALSIZE < _Alsize)
02871 _Alsize = _ALSIZE;
02872
02873 if (_Strmode & std::_Allocated)
02874 _Al.deallocate(eback(), _Os);
02875
02876 _Strmode |= std::_Allocated;
02877
02878 if (_Os == 0)
02879 {_Seekhigh = _P;
02880 setp(_P, _P + _Ns);
02881 setg(_P, _P, _P); }
02882 else
02883 {_Seekhigh = _Seekhigh - eback() + _P;
02884 setp(pbase() - eback() + _P, pptr() - eback() + _P, _P + _Ns);
02885 setg(_P, _P, _P);}
02886 *_Pninc() = _Tr::to_char_type(_C);
02887
02888 return _C;}}
02889
02890 void _Init(const _E *_S, size_t _N, std::_Strstate _M)
02891 {_Pendsave = 0, _Seekhigh = 0;
02892 _Alsize = _MINSIZE, _Strmode = _M;
02893 setg(0, 0, 0);
02894 setp(0, 0);}
02895
02896 void _Tidy()
02897 {if (_Strmode & std::_Allocated)
02898 _Al.deallocate(eback(), (pptr() != 0 ? epptr() : egptr()) - eback());
02899 _Seekhigh = 0;
02900 _Strmode &= ~std::_Allocated;}
02901
02902 private:
02903 enum {_ALSIZE = 65536, _MINSIZE = 32768};
02904
02905 _E *_Pendsave, *_Seekhigh;
02906 int _Alsize;
02907 std::_Strstate _Strmode;
02908 std::allocator<_E> _Al;
02909 };
02910
02911 struct fast_ostringstream : public std::iostream
02912 {
02913 typedef std::iostream super;
02914
02915 explicit fast_ostringstream()
02916 : super(&_Sb) {}
02917
02918 std::string str() const
02919 {return _Sb.str();}
02920
02921 private:
02922 fast_ostringbuffer _Sb;
02923 };
02924
02925 #else
02926
02927 typedef std::ostringstream fast_ostringstream;
02928
02929 #endif
02930
02931
02932
02933 struct XMLDoc : public XMLNode
02934 {
02935 XMLDoc()
02936 : XMLNode("")
02937 {
02938 }
02939
02940 XMLDoc(LPCTSTR path, bool force_utf8=false)
02941 : XMLNode("")
02942 {
02943 read_file(path, force_utf8);
02944 }
02945
02946 #ifdef XS_USE_XERCES
02947 bool read_file(LPCTSTR path, bool force_utf8=false)
02948 {
02949 XMLReader reader(this, path);
02950
02951 #if defined(_STRING_DEFINED) && !defined(XS_STRING_UTF8)
02952 return read(reader, std::string(ANS(path)), force_utf8);
02953 #else
02954 return read(reader, XS_String(path), force_utf8);
02955 #endif
02956 }
02957
02958 bool read_buffer(const char* buffer, size_t len, const std::string& system_id=std::string(), bool force_utf8=false)
02959 {
02960 XMLReader reader(this, (const XMLByte*)buffer, len, system_id);
02961
02962 return read(reader, system_id, force_utf8);
02963 }
02964
02965 bool read_buffer(const std::string& in, const std::string& system_id=std::string(), bool force_utf8=false)
02966 {
02967 return read_buffer(in.c_str(), in.length(), system_id, force_utf8);
02968 }
02969
02970 #else // XS_USE_XERCES
02971
02972 bool read_file(LPCTSTR path, bool force_utf8=false)
02973 {
02974 tifstream in(path);
02975 if (!in.good())
02976 return false;
02977
02978 XMLReader reader(this, in);
02979
02980 #if defined(_STRING_DEFINED) && !defined(XS_STRING_UTF8)
02981 return read(reader, std::string(ANS(path)), force_utf8);
02982 #else
02983 return read(reader, XS_String(path), force_utf8);
02984 #endif
02985 }
02986
02987 bool read_buffer(const char* buffer, size_t len, const std::string& system_id=std::string(), bool force_utf8=false)
02988 {
02989 return read_buffer(std::string(buffer, len), system_id, force_utf8);
02990 }
02991
02992 bool read_buffer(const std::string& buffer, const std::string& system_id=std::string(), bool force_utf8=false)
02993 {
02994 std::istringstream istr(buffer);
02995
02996 return read_stream(istr, system_id, force_utf8);
02997 }
02998
02999 bool read_stream(std::istream& in, const std::string& system_id=std::string(), bool force_utf8=false)
03000 {
03001 XMLReader reader(this, in);
03002
03003 return read(reader, system_id, force_utf8);
03004 }
03005 #endif // XS_USE_XERCES
03006
03007 bool read(XMLReaderBase& reader, const std::string& display_path, bool force_utf8=false)
03008 {
03009 #ifdef XS_NATIVE
03010 reader.setSystemId(display_path.c_str());
03011 #elif defiend(XMLNODE_LOCATION)
03012
03013 _display_path = display_path;
03014 reader._display_path = _display_path.c_str();
03015 #endif
03016
03017 reader.clear_errors();
03018 reader.read(force_utf8);
03019
03020 _format = reader.get_format();
03021 _format._endl = reader.get_endl();
03022
03023 if (!reader.get_errors().empty()) {
03024 _errors = reader.get_errors();
03025 return false;
03026 }
03027
03028 return true;
03029 }
03030
03031
03032
03033 bool write(std::ostream& out, WRITE_MODE mode=FORMAT_SMART) const
03034 {
03035 _format.print_header(out, mode!=FORMAT_PLAIN);
03036
03037 if (_children.size() == 1)
03038 _children.front()->write(out, _format, mode);
03039 else if (!_children.empty()) {
03040
03041 return false;
03042 }
03043
03044 return out.good();
03045 }
03046
03047
03048 bool write_formating(std::ostream& out) const
03049 {
03050 return write(out, FORMAT_PRETTY);
03051 }
03052
03053 bool write_file(LPCTSTR path, WRITE_MODE mode=FORMAT_SMART) const
03054 {
03055 tofstream out(path);
03056
03057 return write(out, mode);
03058 }
03059
03060 bool write_formating(LPCTSTR path) const
03061 {
03062 tofstream out(path);
03063
03064 return write_formating(out);
03065 }
03066
03067 XMLFormat _format;
03068 XMLErrorList _errors;
03069
03070 #ifdef XMLNODE_LOCATION
03071 std::string _display_path;
03072 #endif
03073 };
03074
03075
03076 struct XMLStateReader : public XMLReader
03077 {
03078 enum XML_STATE {
03079 XSS_NONE,
03080 XSS_START_ELEMENT,
03081 XSS_END_ELEMENT,
03082 XSS_ELEMENT,
03083 XSS_CHARACTERS,
03084
03085
03086
03087
03088 };
03089
03090 XMLStateReader(XMLNode* node, std::istream& in)
03091 : XMLReader(node, in),
03092 _parse_ctx(*this),
03093 _state(XSS_NONE)
03094 {
03095 }
03096
03097 bool has_next();
03098 void next();
03099
03100
03101 virtual void StartElementHandler(const XS_String& name, const XMLNode::AttributeMap& attr);
03102 virtual void EndElementHandler();
03103 virtual void DefaultHandler(const std::string& s);
03104
03105 ParseContext _parse_ctx;
03106
03107 enum XML_STATE _state;
03108 XS_String _node_name;
03109 XMLNode::AttributeMap _attrs;
03110 };
03111
03112
03113 struct XMLStreamReader
03114 {
03115 typedef XMLReader super;
03116
03117 XMLStreamReader(std::istream& in)
03118 : _pInFile(NULL),
03119 _state_rdr(NULL, in),
03120 _level(0),
03121 _node(XS_EMPTY_STR)
03122 {
03123 }
03124
03125 XMLStreamReader(LPCTSTR path)
03126 : _pInFile(new tifstream(path)),
03127 _state_rdr(NULL, *_pInFile),
03128 _level(0),
03129 _node(XS_EMPTY_STR)
03130 {
03131 #ifdef UNICODE
03132 _state_rdr._parse_ctx._reader.setSystemId(std::string(XS_String(path)).c_str());
03133 #else
03134 _state_rdr._parse_ctx._reader.setSystemId(path);
03135 #endif
03136 }
03137
03138 ~XMLStreamReader()
03139 {
03140 delete _pInFile;
03141 }
03142
03143
03144
03145
03146
03147
03148
03149 const XMLNode* operator->() const
03150 {
03151 return &_node;
03152 }
03153
03154 operator const XMLNode*() const
03155 {
03156 return &_node;
03157 }
03158
03159 XS_String str() const
03160 {
03161 return _node;
03162 }
03163
03164
03165
03166
03167
03168
03169 XS_String operator[](const XS_String& attr_name) const
03170 {
03171 return _node[attr_name];
03172 }
03173
03174
03175
03176
03177
03178 bool go_down()
03179 {
03180 return first_child();
03181 }
03182
03183
03184
03185
03186
03187
03188 bool go_down(LPCXSSTR child_name)
03189 {
03190 return first_child(child_name);
03191 }
03192
03193
03194
03195
03196
03197
03198
03199 bool back()
03200 {
03201 if (find_node(NULL, -1, _level+1, false))
03202
03203 return true;
03204 else {
03205 assert(_level>=0);
03206 return false;
03207 }
03208 }
03209
03210
03211
03212
03213
03214 bool first_child(LPCXSSTR node_name=NULL)
03215 {
03216 return find_node(node_name, _level+1, _level, false);
03217 }
03218
03219
03220
03221
03222
03223 bool next()
03224 {
03225 return find_node(NULL, _level, _level-1, false);
03226 }
03227
03228
03229
03230
03231
03232 bool next_skip_others(const XS_String& node_name)
03233 {
03234 return find_node(node_name, _level, _level-1, false);
03235 }
03236
03237
03238
03239
03240
03241
03242 bool next_stop_on_others(LPCXSSTR node_name=NULL)
03243 {
03244 return find_node(node_name, _level, _level-1, true);
03245 }
03246
03247
03248 bool find(const XPathElement& xelem)
03249 {
03250
03251 int n = 0;
03252
03253 if (first_child(xelem._child_name)) {
03254 if (xelem.matches(_node, n))
03255 return true;
03256
03257 while(next_skip_others(xelem._child_name))
03258 if (xelem.matches(_node, n))
03259 return true;
03260 }
03261
03262 return false;
03263 }
03264
03265 bool find_relative(const XPath& xpath);
03266
03267 const XMLErrorList& get_errors() const {return _state_rdr.get_errors();}
03268
03269 int _level;
03270
03271 private:
03272 tifstream* _pInFile;
03273 XMLStateReader _state_rdr;
03274 std::string _content;
03275
03276 XMLStreamReader(const XMLStreamReader&);
03277
03278 protected:
03279 bool find_node(LPCXSSTR target_tag, int target_level, int min_level, bool stop_on_others);
03280
03281 XMLNode _node;
03282
03283
03284
03285 virtual void StartElementHandler(const XS_String& name, const XMLNode::AttributeMap& attr);
03286 virtual void EndElementHandler();
03287 virtual void DefaultHandler(const std::string& s);
03288 };
03289
03290
03291
03292 struct XMLStreamChildrenIterator
03293 {
03294 XMLStreamChildrenIterator(XMLStreamReader& reader)
03295 : _begin(reader, false),
03296 _end(reader, true)
03297 {
03298 }
03299
03300
03301 struct const_iterator
03302 {
03303 typedef const_iterator myType;
03304
03305 const_iterator(XMLStreamReader& reader, bool is_end)
03306 : _reader(reader),
03307 _start_level(reader._level),
03308 _is_end(is_end)
03309 {
03310 search_next();
03311 }
03312
03313 const XMLStreamReader& operator->() const
03314 {
03315 return _reader;
03316 }
03317
03318 XS_String operator*() const
03319 {
03320 return _reader.str();
03321 }
03322
03323 myType& operator++()
03324 {
03325 if (!_at_end)
03326 search_next();
03327
03328 return *this;
03329 }
03330
03331 myType operator++(int)
03332 {
03333 myType ret = *this;
03334
03335 if (!_at_end)
03336 search_next();
03337
03338 return ret;
03339 }
03340
03341 bool operator==(const myType& other) const
03342 {
03343 if (other._is_end)
03344 return _at_end;
03345 else if (_is_end)
03346 return other._at_end;
03347 else
03348 return _reader.str() == other._reader.str();
03349 }
03350
03351 bool operator!=(const myType& other) const
03352 {
03353 if (other._is_end)
03354 return !_at_end;
03355 else if (_is_end)
03356 return !other._at_end;
03357 else
03358 return _reader.str() != other._reader.str();
03359 }
03360
03361 protected:
03362 XMLStreamReader& _reader;
03363 int _start_level;
03364 bool _is_end;
03365 bool _at_end;
03366
03367 void search_next()
03368 {
03369 while(!_at_end) {
03370 _reader.next();
03371
03372 if (_reader._level == _start_level)
03373 _at_end = true;
03374 }
03375 }
03376 };
03377
03378 const_iterator begin()
03379 {
03380 return _begin;
03381 }
03382
03383 const_iterator end()
03384 {
03385 return _end;
03386 }
03387
03388 bool empty() const
03389 {
03390 return _end == _begin;
03391 }
03392
03393 protected:
03394 const_iterator _begin;
03395 const_iterator _end;
03396 };
03397
03398
03399
03400 struct XMLStreamChildrenFilter
03401 {
03402 XMLStreamChildrenFilter(XMLStreamReader& reader, const XS_String& name)
03403 : _begin(reader, name, false),
03404 _end(reader, name, true)
03405 {
03406 }
03407
03408
03409 struct const_iterator
03410 {
03411 typedef const_iterator myType;
03412
03413 const_iterator(XMLStreamReader& reader, const XS_String& filter_name, bool is_end)
03414 : _reader(reader),
03415 _filter_name(filter_name),
03416 _start_level(reader._level),
03417 _is_end(is_end)
03418 {
03419 search_next();
03420 }
03421
03422 const XMLStreamReader& operator->() const
03423 {
03424 return _reader;
03425 }
03426
03427 XS_String operator*() const
03428 {
03429 return _reader.str();
03430 }
03431
03432 myType& operator++()
03433 {
03434 if (!_at_end)
03435 search_next();
03436
03437 return *this;
03438 }
03439
03440 myType operator++(int)
03441 {
03442 myType ret = *this;
03443
03444 if (!_at_end)
03445 search_next();
03446
03447 return ret;
03448 }
03449
03450 bool operator==(const myType& other) const
03451 {
03452 if (other._is_end)
03453 return _at_end;
03454 else if (_is_end)
03455 return other._at_end;
03456 else
03457 return _reader.str() == other._reader.str();
03458 }
03459
03460 bool operator!=(const myType& other) const
03461 {
03462 if (other._is_end)
03463 return !_at_end;
03464 else if (_is_end)
03465 return !other._at_end;
03466 else
03467 return _reader.str() != other._reader.str();
03468 }
03469
03470 protected:
03471 XMLStreamReader& _reader;
03472 XS_String _filter_name;
03473 int _start_level;
03474 bool _is_end;
03475 bool _at_end;
03476
03477 void search_next()
03478 {
03479 while(!_at_end) {
03480 _reader.next_skip_others(_filter_name);
03481
03482 if (_reader._level == _start_level)
03483 _at_end = true;
03484 }
03485 }
03486 };
03487
03488 const_iterator begin()
03489 {
03490 return _begin;
03491 }
03492
03493 const_iterator end()
03494 {
03495 return _end;
03496 }
03497
03498 bool empty() const
03499 {
03500 return _end == _begin;
03501 }
03502
03503 protected:
03504 const_iterator _begin;
03505 const_iterator _end;
03506 };
03507
03508
03509
03510 struct XMLBool
03511 {
03512 XMLBool(bool value=false)
03513 : _value(value)
03514 {
03515 }
03516
03517 XMLBool(LPCXSSTR value, bool def=false)
03518 {
03519 LPCXSSTR p = safe_skip_space(value);
03520
03521 if (*p)
03522 _value = !XS_nicmp(p, XS_TRUE, 4);
03523 else
03524 _value = def;
03525 }
03526
03527 XMLBool(const XMLNode* node, const XS_String& attr_name, bool def=false)
03528 {
03529 const XS_String& value = node->get(attr_name);
03530
03531 if (!value.empty())
03532 _value = !XS_icmp(value.c_str(), XS_TRUE);
03533 else
03534 _value = def;
03535 }
03536
03537 operator bool() const
03538 {
03539 return _value;
03540 }
03541
03542 bool operator!() const
03543 {
03544 return !_value;
03545 }
03546
03547 operator LPCXSSTR() const
03548 {
03549 return _value? XS_TRUE: XS_FALSE;
03550 }
03551
03552 protected:
03553 bool _value;
03554
03555 private:
03556 XMLBool& operator=(const XMLBool&);
03557 };
03558
03559
03560 struct XMLBoolRef
03561 {
03562 XMLBoolRef(XMLNode* node, const XS_String& attr_name, bool def=false)
03563 : _ref((*node)[attr_name])
03564 {
03565 if (_ref.empty())
03566 assign(def);
03567 }
03568
03569 operator bool() const
03570 {
03571 return !XS_icmp(_ref.c_str(), XS_TRUE);
03572 }
03573
03574 bool operator!() const
03575 {
03576 return XS_icmp(_ref.c_str(), XS_TRUE)? true: false;
03577 }
03578
03579 XMLBoolRef& operator=(bool value)
03580 {
03581 assign(value);
03582
03583 return *this;
03584 }
03585
03586 void assign(bool value)
03587 {
03588 _ref.assign(value? XS_TRUE: XS_FALSE);
03589 }
03590
03591 void toggle()
03592 {
03593 assign(!operator bool());
03594 }
03595
03596 protected:
03597 XS_String& _ref;
03598 };
03599
03600
03601
03602 struct XMLInt
03603 {
03604 XMLInt(int value)
03605 : _value(value)
03606 {
03607 }
03608
03609 XMLInt(size_t value)
03610 : _value((int)value)
03611 {
03612 }
03613
03614 XMLInt(LPCXSSTR value, int def=0)
03615 {
03616 LPCXSSTR p = safe_skip_space(value);
03617
03618 if (*p)
03619 _value = XS_toi(p);
03620 else
03621 _value = def;
03622 }
03623
03624 XMLInt(const XMLNode* node, const XS_String& attr_name, int def=0)
03625 {
03626 const XS_String& value = node->get(attr_name);
03627
03628 if (!value.empty())
03629 _value = XS_toi(value.c_str());
03630 else
03631 _value = def;
03632 }
03633
03634 operator int() const
03635 {
03636 return _value;
03637 }
03638
03639 operator XS_String() const
03640 {
03641 XS_CHAR buffer[32];
03642 XS_snprintf(buffer, COUNTOF(buffer), XS_INTFMT, _value);
03643 return XS_String(buffer);
03644 }
03645
03646 protected:
03647 int _value;
03648
03649 private:
03650 XMLInt& operator=(const XMLInt&);
03651 };
03652
03653
03654 struct XMLIntRef
03655 {
03656 XMLIntRef(XMLNode* node, const XS_String& attr_name, int def=0)
03657 : _ref((*node)[attr_name])
03658 {
03659 if (_ref.empty())
03660 assign(def);
03661 }
03662
03663 XMLIntRef& operator=(int value)
03664 {
03665 assign(value);
03666
03667 return *this;
03668 }
03669
03670 operator int() const
03671 {
03672 return XS_toi(_ref.c_str());
03673 }
03674
03675 void assign(int value)
03676 {
03677 XS_CHAR buffer[32];
03678 XS_snprintf(buffer, COUNTOF(buffer), XS_INTFMT, value);
03679 _ref.assign(buffer);
03680 }
03681
03682 protected:
03683 XS_String& _ref;
03684 };
03685
03686
03687
03688 struct XMLInt64
03689 {
03690 XMLInt64(INT64 value)
03691 : _value(value)
03692 {
03693 }
03694
03695 XMLInt64(UINT64 value)
03696 : _value((INT64)value)
03697 {
03698 }
03699
03700 XMLInt64(LPCXSSTR value, INT64 def=0)
03701 {
03702 LPCXSSTR p = safe_skip_space(value);
03703
03704 if (*p)
03705 _value = XS_toi64(p);
03706 else
03707 _value = def;
03708 }
03709
03710 XMLInt64(const XMLNode* node, const XS_String& attr_name, INT64 def=0)
03711 {
03712 const XS_String& value = node->get(attr_name);
03713
03714 if (!value.empty())
03715 _value = XS_toi64(value.c_str());
03716 else
03717 _value = def;
03718 }
03719
03720 operator INT64() const
03721 {
03722 return _value;
03723 }
03724
03725 operator XS_String() const
03726 {
03727 XS_CHAR buffer[64];
03728 XS_snprintf(buffer, COUNTOF(buffer), XS_INT64FMT, _value);
03729 return XS_String(buffer);
03730 }
03731
03732 protected:
03733 INT64 _value;
03734
03735 private:
03736 XMLInt64& operator=(const XMLInt64&);
03737 };
03738
03739
03740 struct XMLInt64Ref
03741 {
03742 XMLInt64Ref(XMLNode* node, const XS_String& attr_name, INT64 def=0)
03743 : _ref((*node)[attr_name])
03744 {
03745 if (_ref.empty())
03746 assign(def);
03747 }
03748
03749 XMLInt64Ref& operator=(INT64 value)
03750 {
03751 assign(value);
03752
03753 return *this;
03754 }
03755
03756 operator INT64() const
03757 {
03758 return XS_toi64(_ref.c_str());
03759 }
03760
03761 void assign(INT64 value)
03762 {
03763 XS_CHAR buffer[64];
03764 XS_snprintf(buffer, COUNTOF(buffer), XS_INT64FMT, value);
03765 _ref.assign(buffer);
03766 }
03767
03768 protected:
03769 XS_String& _ref;
03770 };
03771
03772
03773
03774 struct XMLDouble
03775 {
03776 XMLDouble(double value)
03777 : _value(value)
03778 {
03779 }
03780
03781 XMLDouble(LPCXSSTR value, double def=0.)
03782 {
03783 LPCXSSTR p = safe_skip_space(value);
03784 LPTSTR end;
03785
03786 if (*p)
03787 _value = XS_tod(p, &end);
03788 else
03789 _value = def;
03790 }
03791
03792 XMLDouble(const XMLNode* node, const XS_String& attr_name, double def=0.)
03793 {
03794 LPTSTR end;
03795 const XS_String& value = node->get(attr_name);
03796
03797 if (!value.empty())
03798 _value = XS_tod(value.c_str(), &end);
03799 else
03800 _value = def;
03801 }
03802
03803 operator double() const
03804 {
03805 return _value;
03806 }
03807
03808 operator XS_String() const
03809 {
03810 XS_CHAR buffer[32];
03811 XS_snprintf(buffer, COUNTOF(buffer), XS_FLOATFMT, _value);
03812 return XS_String(buffer);
03813 }
03814
03815 protected:
03816 double _value;
03817
03818 private:
03819 XMLDouble& operator=(const XMLDouble&);
03820 };
03821
03822
03823 struct XMLDoubleRef
03824 {
03825 XMLDoubleRef(XMLNode* node, const XS_String& attr_name, double def=0.)
03826 : _ref((*node)[attr_name])
03827 {
03828 if (_ref.empty())
03829 assign(def);
03830 }
03831
03832 XMLDoubleRef& operator=(double value)
03833 {
03834 assign(value);
03835
03836 return *this;
03837 }
03838
03839 operator double() const
03840 {
03841 LPTSTR end;
03842 return XS_tod(_ref.c_str(), &end);
03843 }
03844
03845 void assign(double value)
03846 {
03847 XS_CHAR buffer[32];
03848 XS_snprintf(buffer, COUNTOF(buffer), XS_FLOATFMT, value);
03849 _ref.assign(buffer);
03850 }
03851
03852 protected:
03853 XS_String& _ref;
03854 };
03855
03856
03857
03858 struct XMLString
03859 {
03860 XMLString(const XS_String& value)
03861 : _value(value)
03862 {
03863 }
03864
03865 XMLString(LPCXSSTR value, LPCXSSTR def=XS_EMPTY)
03866 {
03867 if (value && *value)
03868 _value = value;
03869 else
03870 _value = def;
03871 }
03872
03873 XMLString(const XMLNode* node, const XS_String& attr_name, LPCXSSTR def=XS_EMPTY)
03874 {
03875 const XS_String& value = node->get(attr_name);
03876
03877 if (!value.empty())
03878 _value = value;
03879 else
03880 _value = def;
03881 }
03882
03883 operator const XS_String&() const
03884 {
03885 return _value;
03886 }
03887
03888 const XS_String& c_str() const
03889 {
03890 return _value;
03891 }
03892
03893 protected:
03894 XS_String _value;
03895
03896 private:
03897 XMLString& operator=(const XMLString&);
03898 };
03899
03900
03901 struct XMLStringRef
03902 {
03903 XMLStringRef(XMLNode* node, const XS_String& attr_name, LPCXSSTR def=XS_EMPTY)
03904 : _ref((*node)[attr_name])
03905 {
03906 if (_ref.empty())
03907 assign(def);
03908 }
03909
03910 XMLStringRef(const XS_String& node_name, XMLNode* node, const XS_String& attr_name, LPCXSSTR def=XS_EMPTY)
03911 : _ref(node->subvalue(node_name, attr_name))
03912 {
03913 if (_ref.empty())
03914 assign(def);
03915 }
03916
03917 XMLStringRef& operator=(const XS_String& value)
03918 {
03919 assign(value);
03920
03921 return *this;
03922 }
03923
03924 operator const XS_String&() const
03925 {
03926 return _ref;
03927 }
03928
03929 void assign(const XS_String& value)
03930 {
03931 _ref.assign(value);
03932 }
03933
03934 protected:
03935 XS_String& _ref;
03936 };
03937
03938
03939
03940 template<typename T>
03941 inline void read_option(T& var, const_XMLPos& cfg, LPCXSSTR key)
03942 {
03943 const XS_String& val = cfg.get(key);
03944
03945 if (!val.empty())
03946 var = val;
03947 }
03948
03949
03950 template<>
03951 inline void read_option(int& var, const_XMLPos& cfg, LPCXSSTR key)
03952 {
03953 const XS_String& val = cfg.get(key);
03954
03955 if (!val.empty())
03956 var = XS_toi(val.c_str());
03957 }
03958
03959
03960 inline void XMLPos::set_property(const XS_String& key, int value, const XS_String& name)
03961 {
03962 smart_create(name, XS_KEY, key);
03963 XMLIntRef(_cur, XS_VALUE) = value;
03964 back();
03965 }
03966
03967 inline void XMLPos::set_property(const XS_String& key, double value, const XS_String& name)
03968 {
03969 smart_create(name, XS_KEY, key);
03970 XMLDoubleRef(_cur, XS_VALUE) = value;
03971 back();
03972 }
03973
03974 inline void XMLPos::set_property(const XS_String& key, const XS_String& value, const XS_String& name)
03975 {
03976 smart_create(name, XS_KEY, key);
03977 put(XS_VALUE, value);
03978 back();
03979 }
03980
03981 inline void XMLPos::set_property(const XS_String& key, const XMLBool& value, const XS_String& name)
03982 {
03983 smart_create(name, XS_KEY, key);
03984 XMLBoolRef(_cur, XS_VALUE) = value;
03985 back();
03986 }
03987
03988
03989
03990 struct XMLProperty {
03991 XMLProperty(const XMLNode* node)
03992 : _key(node->get(XS_KEY)),
03993 _value(node->get(XS_VALUE))
03994 {
03995 }
03996
03997 XS_String _key;
03998 XS_String _value;
03999 };
04000
04001
04002
04003 struct XMLPropertyReader
04004 {
04005 XMLPropertyReader(const XMLNode::Children& children)
04006 : _filter(children, XS_PROPERTY),
04007 _begin(_filter.begin(), _filter.end()),
04008 _end(_filter.end(), _filter.end())
04009 {
04010 }
04011
04012 XMLPropertyReader(const XMLNode* node)
04013 : _filter(node, XS_PROPERTY),
04014 _begin(_filter.begin(), _filter.end()),
04015 _end(_filter.end(), _filter.end())
04016 {
04017 }
04018
04019
04020 struct const_iterator
04021 {
04022 typedef const_XMLChildrenFilter::const_iterator BaseIterator;
04023 typedef const_iterator myType;
04024
04025 const_iterator(BaseIterator begin, BaseIterator end)
04026 : _cur(begin),
04027 _end(end)
04028 {
04029 }
04030
04031 operator BaseIterator()
04032 {
04033 return _cur;
04034 }
04035
04036 XMLProperty operator*() const
04037 {
04038 return XMLProperty(*_cur);
04039 }
04040
04041 const XMLNode* get_node() const
04042 {
04043 return *_cur;
04044 }
04045
04046 myType& operator++()
04047 {
04048 ++_cur;
04049
04050 return *this;
04051 }
04052
04053 myType operator++(int)
04054 {
04055 myType ret = *this;
04056
04057 ++_cur;
04058
04059 return ret;
04060 }
04061
04062 bool operator==(const myType& other) const
04063 {
04064 return _cur == other._cur;
04065 }
04066
04067 bool operator!=(const myType& other) const
04068 {
04069 return _cur != other._cur;
04070 }
04071
04072 protected:
04073 BaseIterator _cur;
04074 BaseIterator _end;
04075 };
04076
04077 const_iterator begin()
04078 {
04079 return _begin;
04080 }
04081
04082 const_iterator end()
04083 {
04084 return _end;
04085 }
04086
04087 bool empty() const
04088 {
04089 return _end == _begin;
04090 }
04091
04092 protected:
04093 const_XMLChildrenFilter _filter;
04094
04095 const_iterator _begin;
04096 const_iterator _end;
04097 };
04098
04099
04100
04101 struct XMLMessage : public XMLDoc
04102 {
04103 XMLMessage(const char* name)
04104 : _pos(this)
04105 {
04106 _pos.create(name);
04107 }
04108
04109 std::string toString() const
04110 {
04111 std::ostringstream out;
04112
04113 write(out);
04114
04115 return out.str();
04116 }
04117
04118 XMLPos _pos;
04119
04120 protected:
04121 XMLMessage()
04122 : _pos(this)
04123 {
04124 }
04125 };
04126
04127
04128
04129 struct XMLMessageFromString : public XMLMessage
04130 {
04131 XMLMessageFromString(const std::string& xml_str, const std::string& system_id=std::string())
04132 {
04133 read_buffer(xml_str.c_str(), xml_str.length(), system_id);
04134 }
04135 };
04136
04137
04138
04139 struct XMLMessageReader : public XMLPos
04140 {
04141 XMLMessageReader(const std::string& xml_str, const std::string& system_id=std::string())
04142 : XMLPos(&_msg)
04143 {
04144 _msg.read_buffer(xml_str.c_str(), xml_str.length(), system_id);
04145 }
04146
04147 const XMLDoc& get_document()
04148 {
04149 return _msg;
04150 }
04151
04152 protected:
04153 XMLDoc _msg;
04154 };
04155
04156
04157
04158 struct XMLWriter
04159 {
04160 XMLWriter(std::ostream& out, const XMLFormat& format=XMLFormat())
04161 : _pofstream(NULL),
04162 _out(out),
04163 _format(format)
04164 {
04165 format.print_header(_out, false);
04166 }
04167
04168 XMLWriter(FILE* pFile, const XMLFormat& format=XMLFormat())
04169 : _pofstream(new tofstream(pFile)),
04170 _out(*_pofstream),
04171 _format(format)
04172 {
04173 format.print_header(_out, false);
04174 }
04175
04176 XMLWriter(LPCTSTR path, const XMLFormat& format=XMLFormat())
04177 : _pofstream(new tofstream(path)),
04178 _out(*_pofstream),
04179 _format(format)
04180 {
04181 format.print_header(_out, false);
04182 }
04183
04184 ~XMLWriter()
04185 {
04186 _out << _format._endl;
04187 _out.flush();
04188 delete _pofstream;
04189 }
04190
04191 bool good() const
04192 {
04193 return _out.good();
04194 }
04195
04196
04197 void create(const XS_String& name);
04198
04199
04200 bool back();
04201
04202
04203 void put(const XS_String& attr_name, const XS_String& value)
04204 {
04205 if (!_stack.empty())
04206 _stack.top()._attributes[attr_name] = value;
04207 }
04208
04209
04210 XS_String& operator[](const XS_String& attr_name)
04211 {
04212 if (_stack.empty())
04213 return s_empty_attr;
04214
04215 return _stack.top()._attributes[attr_name];
04216 }
04217
04218 void set_attributes(const XMLNode::AttributeMap& attrs)
04219 {
04220 if (!_stack.empty())
04221 _stack.top()._attributes = attrs;
04222 }
04223
04224
04225 void set_content(const XS_String& s, bool cdata=false)
04226 {
04227 if (!_stack.empty())
04228 _stack.top()._content = EncodeXMLString(s.c_str(), cdata);
04229 }
04230
04231
04232 void set_encoded_content(const std::string& s)
04233 {
04234 if (!_stack.empty())
04235 _stack.top()._content = s;
04236 }
04237
04238
04239 void create_node_content(const XS_String& node_name, const XS_String& content)
04240 {
04241 create(node_name);
04242 set_content(content);
04243 back();
04244 }
04245
04246
04247 void write(const std::string& s);
04248
04249
04250 enum WRITESTATE {
04251 NOTHING, ATTRIBUTES, PRE_CLOSED, POST
04252 };
04253
04254 protected:
04255 tofstream* _pofstream;
04256 std::ostream& _out;
04257 XMLFormat _format;
04258
04259 typedef XMLNode::AttributeMap AttrMap;
04260
04261
04262 struct StackEntry {
04263 XS_String _node_name;
04264 AttrMap _attributes;
04265 std::string _content;
04266 WRITESTATE _state;
04267 bool _children;
04268
04269 StackEntry() : _state(NOTHING), _children(false) {}
04270 };
04271
04272 std::stack<StackEntry> _stack;
04273
04274 static XS_String s_empty_attr;
04275
04276 void close_pre(StackEntry& entry);
04277 void write_pre(StackEntry& entry);
04278 void write_attributes(StackEntry& entry);
04279 void write_post(StackEntry& entry);
04280
04281 private:
04282 XMLWriter(const XMLWriter&);
04283 };
04284
04285
04286 }
04287
04288 #ifdef _MSC_VER
04289 #pragma warning(pop) // C4512: assignment operator could not be generated
04290 #endif
04291
04292 #define _XMLSTORAGE_H
04293 #endif // _XMLSTORAGE_H