📄 xmlstorage.h
字号:
//
// XML storage classes version 1.2
//
// Copyright (c) 2004, 2005, 2006, 2007 Martin Fuchs <martin-fuchs@gmx.net>
//
/// \file xmlstorage.h
/// XMLStorage header file
/*
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _XMLSTORAGE_H
#ifdef UNICODE
#ifndef _UNICODE
#define _UNICODE
#endif
#else
#ifdef _UNICODE
#define UNICODE
#endif
#endif
#ifndef _WIN32
#ifdef UNICODE
#error no UNICODE build in Unix version available
#endif
#ifndef XS_STRING_UTF8
#define XS_STRING_UTF8
#endif
#endif
#if _MSC_VER>=1400
#ifndef _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES
#define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES 1
#define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_COUNT 1
#define _CRT_SECURE_CPP_OVERLOAD_SECURE_NAMES 1
#endif
#endif
#ifdef XS_USE_XERCES
#ifndef UNICODE
#ifndef XS_STRING_UTF8
#define XS_STRING_UTF8
#endif
#endif
#include <xercesc/parsers/SAXParser.hpp>
#include <xercesc/sax/HandlerBase.hpp>
using XERCES_CPP_NAMESPACE_QUALIFIER Locator;
using XERCES_CPP_NAMESPACE_QUALIFIER SAXParser;
using XERCES_CPP_NAMESPACE_QUALIFIER HandlerBase;
using XERCES_CPP_NAMESPACE_QUALIFIER InputSource;
using XERCES_CPP_NAMESPACE_QUALIFIER AttributeList;
using XERCES_CPP_NAMESPACE_QUALIFIER SAXParseException;
typedef XMLCh XML_Char;
#elif defined(XS_USE_EXPAT)
#include <expat/expat.h>
#endif
#ifdef _MSC_VER
#pragma warning(disable: 4786)
#ifndef XS_NO_COMMENT
#ifdef XS_USE_XERCES
#ifdef _DEBUG
#pragma comment(lib, "xerces-c_2D")
#else
#pragma comment(lib, "xerces-c_2")
#endif
#elif defined(XS_USE_EXPAT)
#ifdef XML_STATIC
#ifndef _DEBUG
#pragma comment(lib, "libexpatMT")
#endif
#else
#pragma comment(lib, "libexpat")
#endif
#endif
#ifndef _STRING_DEFINED // _STRING_DEFINED only allowed if using xmlstorage.cpp embedded in the project
#if defined(_DEBUG) && defined(_DLL) // DEBUG version only supported with MSVCRTD
#if _MSC_VER==1400
#pragma comment(lib, "xmlstorage-vc8d")
#else
#pragma comment(lib, "xmlstorage-vc6d")
#endif
#else
#ifdef _DLL
#if _MSC_VER==1400
#pragma comment(lib, "xmlstorage-vc8")
#else
#pragma comment(lib, "xmlstorage-vc6")
#endif
#elif defined(_MT)
#if _MSC_VER==1400
#pragma comment(lib, "xmlstorage-vc8t")
#else
#pragma comment(lib, "xmlstorage-vc6t")
#endif
#else
// -ML is no more supported by VS2005.
#pragma comment(lib, "xmlstorage-vc6l")
#endif
#endif
#endif // _STRING_DEFINED
#endif // XS_NO_COMMENT
#endif // _MSC_VER
#ifdef _WIN32
#include <windows.h> // for LPCTSTR
#include <tchar.h>
#include <malloc.h>
#else
#include <wchar.h>
#include <stdarg.h>
typedef char CHAR;
#ifdef _WCHAR_T_DEFINED
#define __wchar_t wchar_t
#endif
typedef __wchar_t WCHAR;
typedef unsigned char UCHAR;
typedef char* LPSTR;
typedef const char* LPCSTR;
typedef WCHAR* LPWSTR;
typedef const WCHAR* LPCWSTR;
#ifndef UNICODE
#define TEXT(x) x
typedef char TCHAR;
typedef unsigned char _TUCHAR;
typedef CHAR* PTSTR;
typedef CHAR* LPTSTR;
typedef const CHAR* LPCTSTR;
#define _ttoi atoi
#define _tfopen fopen
#define _tcstod strtod
#define _tcslen strlen
#define _tcsstr strstr
#define _snprintf snprintf
#define _sntprintf snprintf
#define _vsnprintf vsnprintf
#define _vsntprintf vsnprintf
#define _stricmp strcasecmp
#define _tcsicmp strcasecmp
#define strnicmp strncasecmp
#define _tcsnicmp strncasecmp
#endif
#endif
#include <fstream>
#include <sstream>
#include <string>
#include <stack>
#include <list>
#include <map>
#ifndef BUFFER_LEN
#define BUFFER_LEN 2048
#endif
namespace XMLStorage {
#ifndef XS_String
#ifdef XS_STRING_UTF8
#define XS_CHAR char
#define XS_TEXT(x) x
#define LPXSSTR LPSTR
#define LPCXSSTR LPCSTR
#define XS_cmp strcmp
#define XS_icmp _stricmp
#define XS_ncmp strncmp
#define XS_nicmp strnicmp
#define XS_toi atoi
#define XS_tod strtod
#define XS_len strlen
#define XS_snprintf _snprintf
#define XS_vsnprintf _vsnprintf
#define XS_strstr strstr
#else
#define XS_CHAR TCHAR
#define XS_TEXT(x) TEXT(x)
#define LPXSSTR LPTSTR
#define LPCXSSTR LPCTSTR
#define XS_cmp _tcscmp
#define XS_icmp _tcsicmp
#define XS_ncmp _tcsncmp
#define XS_nicmp _tcsnicmp
#define XS_toi _ttoi
#define XS_tod _tcstod
#define XS_len _tcslen
#define XS_snprintf _sntprintf
#define XS_vsnprintf _vsntprintf
#define XS_strstr _tcsstr
#endif
#ifndef COUNTOF
#if _MSC_VER>=1400
#define COUNTOF _countof
#else
#define COUNTOF(b) (sizeof(b)/sizeof(b[0]))
#endif
#endif
int inline isxmlsym(unsigned char c)
{
return isalnum(c) || c=='_' || c=='-';
}
#if defined(_STRING_DEFINED) && !defined(XS_STRING_UTF8)
#define XS_String String
#else // _STRING_DEFINED, !XS_STRING_UTF8
/// string class for TCHAR strings
struct XS_String
#if defined(UNICODE) && !defined(XS_STRING_UTF8)
: public std::wstring
#else
: public std::string
#endif
{
#if defined(UNICODE) && !defined(XS_STRING_UTF8)
typedef std::wstring super;
#else
typedef std::string super;
#endif
XS_String() {}
XS_String(LPCXSSTR s) {if (s) super::assign(s);}
XS_String(LPCXSSTR s, size_t l) : super(s, l) {}
XS_String(const super& other) : super(other) {}
XS_String(const XS_String& other) : super(other) {}
#ifdef _WIN32
#if defined(UNICODE) && !defined(XS_STRING_UTF8)
XS_String(LPCSTR s) {assign(s);}
XS_String(LPCSTR s, size_t l) {assign(s, l);}
XS_String(const std::string& other) {assign(other.c_str());}
XS_String& operator=(LPCSTR s) {assign(s); return *this;}
void assign(LPCSTR s) {if (s) {size_t bl=strlen(s); LPWSTR b=(LPWSTR)alloca(sizeof(WCHAR)*bl); super::assign(b, MultiByteToWideChar(CP_ACP, 0, s, bl, b, bl));} else erase();}
void assign(LPCSTR s, size_t l) {if (s) {size_t bl=l; LPWSTR b=(LPWSTR)alloca(sizeof(WCHAR)*bl); super::assign(b, MultiByteToWideChar(CP_ACP, 0, s, l, b, bl));} else erase();}
#else
XS_String(LPCWSTR s) {assign(s);}
XS_String(LPCWSTR s, size_t l) {assign(s, l);}
XS_String(const std::wstring& other) {assign(other.c_str());}
XS_String& operator=(LPCWSTR s) {assign(s); return *this;}
#ifdef XS_STRING_UTF8
void assign(LPCWSTR s) {if (s) {size_t bl=wcslen(s); LPSTR b=(LPSTR)alloca(bl); super::assign(b, WideCharToMultiByte(CP_UTF8, 0, s, (int)bl, b, (int)bl, 0, 0));} else erase();}
void assign(LPCWSTR s, size_t l) {size_t bl=l; if (s) {LPSTR b=(LPSTR)alloca(bl); super::assign(b, WideCharToMultiByte(CP_UTF8, 0, s, (int)l, b, (int)bl, 0, 0));} else erase();}
#else // if !UNICODE && !XS_STRING_UTF8
void assign(LPCWSTR s) {if (s) {size_t bl=wcslen(s); LPSTR b=(LPSTR)alloca(bl); super::assign(b, WideCharToMultiByte(CP_ACP, 0, s, (int)bl, b, (int)bl, 0, 0));} else erase();}
void assign(LPCWSTR s, size_t l) {size_t bl=l; if (s) {LPSTR b=(LPSTR)alloca(bl); super::assign(b, WideCharToMultiByte(CP_ACP, 0, s, (int)l, b, (int)bl, 0, 0));} else erase();}
#endif
#endif
#endif // _WIN32
#ifdef XS_STRING_UTF8
void assign(const XS_String& s) {assign(s.c_str());}
#endif
XS_String& operator=(LPCXSSTR s) {if (s) super::assign(s); else erase(); return *this;}
XS_String& operator=(const super& s) {super::assign(s); return *this;}
void assign(LPCXSSTR s) {super::assign(s);}
void assign(LPCXSSTR s, size_t l) {super::assign(s, l);}
operator LPCXSSTR() const {return c_str();}
#ifdef _WIN32
#ifdef XS_STRING_UTF8
operator std::wstring() const {size_t bl=length(); LPWSTR b=(LPWSTR)alloca(sizeof(WCHAR)*bl); return std::wstring(b, MultiByteToWideChar(CP_UTF8, 0, c_str(), bl, b, bl));}
#elif defined(UNICODE)
operator std::string() const {size_t bl=length(); LPSTR b=(LPSTR)alloca(bl); return std::string(b, WideCharToMultiByte(CP_ACP, 0, c_str(), bl, b, bl, 0, 0));}
#else
operator std::wstring() const {size_t bl=length(); LPWSTR b=(LPWSTR)alloca(sizeof(WCHAR)*bl); return std::wstring(b, MultiByteToWideChar(CP_ACP, 0, c_str(), (int)bl, b, (int)bl));}
#endif
#endif
XS_String& printf(LPCXSSTR fmt, ...)
{
va_list l;
XS_CHAR b[BUFFER_LEN];
va_start(l, fmt);
super::assign(b, XS_vsnprintf(b, COUNTOF(b), fmt, l));
va_end(l);
return *this;
}
XS_String& vprintf(LPCXSSTR fmt, va_list l)
{
XS_CHAR b[BUFFER_LEN];
super::assign(b, XS_vsnprintf(b, COUNTOF(b), fmt, l));
return *this;
}
XS_String& appendf(LPCXSSTR fmt, ...)
{
va_list l;
XS_CHAR b[BUFFER_LEN];
va_start(l, fmt);
super::append(b, XS_vsnprintf(b, COUNTOF(b), fmt, l));
va_end(l);
return *this;
}
XS_String& vappendf(LPCXSSTR fmt, va_list l)
{
XS_CHAR b[BUFFER_LEN];
super::append(b, XS_vsnprintf(b, COUNTOF(b), fmt, l));
return *this;
}
};
#endif // _STRING_DEFINED, !XS_STRING_UTF8
#endif // XS_String
#define XS_EMPTY_STR XS_TEXT("")
#define XS_TRUE_STR XS_TEXT("true")
#define XS_FALSE_STR XS_TEXT("false")
#define XS_INTFMT_STR XS_TEXT("%d")
#define XS_FLOATFMT_STR XS_TEXT("%f")
// work around GCC's wide string constant bug
#ifdef __GNUC__
extern const LPCXSSTR XS_EMPTY;
extern const LPCXSSTR XS_TRUE;
extern const LPCXSSTR XS_FALSE;
extern const LPCXSSTR XS_INTFMT;
extern const LPCXSSTR XS_FLOATFMT;
#else
#define XS_EMPTY XS_EMPTY_STR
#define XS_TRUE XS_TRUE_STR
#define XS_FALSE XS_FALSE_STR
#define XS_INTFMT XS_INTFMT_STR
#define XS_FLOATFMT XS_FLOATFMT_STR
#endif
#ifndef XS_STRING_UTF8
// from UTF-8 to XS internal string encoding
inline void assign_utf8(XS_String& s, const char* str, size_t lutf8)
{
#ifdef UNICODE
LPTSTR buffer = (LPTSTR)alloca(sizeof(TCHAR)*lutf8);
int l = MultiByteToWideChar(CP_UTF8, 0, str, (int)lutf8, buffer, (int)lutf8);
#else
LPWSTR wbuffer = (LPWSTR)alloca(sizeof(WCHAR)*lutf8);
int l = MultiByteToWideChar(CP_UTF8, 0, str, (int)lutf8, wbuffer, (int)lutf8);
int bl=2*l; LPSTR buffer = (LPSTR)alloca(bl);
l = WideCharToMultiByte(CP_ACP, 0, wbuffer, l, buffer, bl, 0, 0);
#endif
s.assign(buffer, l);
}
// from UTF-8 to XS internal string encoding
inline void assign_utf8(XS_String& s, const char* str)
{
assign_utf8(s, str, strlen(str));
}
// from XS internal string encoding to UTF-8
inline std::string get_utf8(LPCTSTR s, size_t l)
{
#ifdef UNICODE
size_t bl=2*l; LPSTR buffer = (LPSTR)alloca(bl);
l = WideCharToMultiByte(CP_UTF8, 0, s, (int)l, buffer, (int)bl, 0, 0);
#else
LPWSTR wbuffer = (LPWSTR)alloca(sizeof(WCHAR)*l);
l = MultiByteToWideChar(CP_ACP, 0, s, (int)l, wbuffer, (int)l);
size_t bl=2*l; LPSTR buffer = (LPSTR)alloca(bl);
l = WideCharToMultiByte(CP_UTF8, 0, wbuffer, (int)l, buffer, (int)bl, 0, 0);
#endif
return std::string(buffer, l);
}
#ifdef UNICODE
// from XS internal string encoding to UTF-8
inline std::string get_utf8(const char* s, size_t l)
{
LPWSTR wbuffer = (LPWSTR)alloca(sizeof(WCHAR)*l);
l = MultiByteToWideChar(CP_ACP, 0, s, (int)l, wbuffer, (int)l);
size_t bl=2*l; LPSTR buffer = (LPSTR)alloca(bl);
l = WideCharToMultiByte(CP_UTF8, 0, wbuffer, (int)l, buffer, (int)bl, 0, 0);
return std::string(buffer, l);
}
#endif
// from XS internal string encoding to UTF-8
inline std::string get_utf8(const XS_String& s)
{
return get_utf8(s.c_str(), s.length());
}
#endif // XS_STRING_UTF8
extern std::string EncodeXMLString(const XS_String& str, bool cdata=false);
extern XS_String DecodeXMLString(const XS_String& str);
#ifdef __GNUC__
#include <ext/stdio_filebuf.h>
typedef __gnu_cxx::stdio_filebuf<char> STDIO_FILEBUF;
#else
typedef std::filebuf STDIO_FILEBUF;
#endif
/// base class for XMLStorage::tifstream and XMLStorage::tofstream
struct FileHolder
{
FileHolder(LPCTSTR path, LPCTSTR mode)
{
#ifdef __STDC_WANT_SECURE_LIB__ // secure CRT functions using VS 2005
if (_tfopen_s(&_pfile, path, mode) != 0)
_pfile = NULL;
#else
_pfile = _tfopen(path, mode);
#endif
}
~FileHolder()
{
if (_pfile)
fclose(_pfile);
}
protected:
FILE* _pfile;
};
/// input file stream with ANSI/UNICODE file names
struct tifstream : public std::istream, FileHolder
{
typedef std::istream super;
tifstream(LPCTSTR path)
: super(&_buf),
FileHolder(path, TEXT("rb")), // binary mode is important for XMLReader::read_buffer() with MinGW libraries
#ifdef __GNUC__
_buf(_pfile, std::ios::in)
#else
_buf(_pfile)
#endif
{
}
protected:
STDIO_FILEBUF _buf;
};
/// output file stream with ANSI/UNICODE file names
struct tofstream : public std::ostream, FileHolder
{
typedef std::ostream super;
tofstream(LPCTSTR path)
: super(&_buf),
FileHolder(path, TEXT("wb")),
#ifdef __GNUC__
_buf(_pfile, std::ios::out)
#else
_buf(_pfile)
#endif
{
}
~tofstream()
{
flush();
}
protected:
STDIO_FILEBUF _buf;
};
// write XML files with 2 spaces indenting
#define XML_INDENT_SPACE " "
#if defined(XS_USE_XERCES) || defined(XS_USE_EXPAT)
#if defined(XML_UNICODE)/*Expat*/ || defined(XS_USE_XERCES)/*Xerces*/ // Are Expat/Xerces XML strings UTF-16 encoded?
typedef XS_String String_from_XML_Char;
#elif defined(XS_STRING_UTF8)
typedef XS_String String_from_XML_Char;
#else
/// converter from Expat/Xerces strings to XMLStorage internal strings
struct String_from_XML_Char : public XS_String
{
String_from_XML_Char(const XML_Char* str)
{
assign_utf8(*this, str);
}
};
#endif
#endif // defined(XS_USE_XERCES) || defined(XS_USE_EXPAT)
#if defined(UNICODE) && !defined(XS_STRING_UTF8)
// optimization for faster UNICODE/ASCII string comparison without temporary A/U conversion
inline bool operator==(const XS_String& s1, const char* s2)
{
LPCWSTR p = s1;
const unsigned char* q = (const unsigned char*)s2;
while(*p && *q)
if (*p++ != *q++)
return false;
return *p == *q;
};
#endif
/// XML Error with message and location
struct XMLError
{
XMLError()
: _line(0),
_column(0),
_error_code(0)
{
}
std::string str() const;
friend std::ostream& operator<<(std::ostream&, const XMLError& err);
XS_String _message;
XS_String _systemId;
int _line;
int _column;
int _error_code;
};
/// list of XMLError entries
struct XMLErrorList : public std::list<XMLError>
{
XS_String str() const;
};
#ifdef XMLNODE_LOCATION
/// location of XML Node including XML file name
struct XMLLocation
{
XMLLocation()
: _pdisplay_path(NULL),
_line(0),
_column(0)
{
}
XMLLocation(const char* display_path, int line, int column)
: _pdisplay_path(display_path),
_line(line),
_column(column)
{
}
std::string str() const;
protected:
const char* _pdisplay_path; // character pointer for fast reference
int _line;
int _column;
};
#endif
enum PRETTY_FLAGS {
PRETTY_PLAIN = 0,
PRETTY_LINEFEED = 1,
PRETTY_INDENT = 2
};
/// XML Stylesheet entry
struct StyleSheet
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -