update to XMLStorage version 1.2

svn path=/trunk/; revision=26646
This commit is contained in:
Martin Fuchs 2007-05-05 07:30:20 +00:00
parent 841a6e2567
commit 231dcbf43a
3 changed files with 224 additions and 57 deletions

View file

@ -1,8 +1,8 @@
// //
// XML storage classes Version 1.1 // XML storage classes version 1.2
// //
// Copyright (c) 2004, 2005, 2006 Martin Fuchs <martin-fuchs@gmx.net> // Copyright (c) 2004, 2005, 2006, 2007 Martin Fuchs <martin-fuchs@gmx.net>
// //
/// \file xmlstorage.cpp /// \file xmlstorage.cpp
@ -284,30 +284,43 @@ std::string EncodeXMLString(const XS_String& str, bool cdata)
LPCXSSTR s = str.c_str(); LPCXSSTR s = str.c_str();
size_t l = XS_len(s); size_t l = XS_len(s);
if (!cdata && l<=BUFFER_LEN) { if (cdata) {
// encode the whole string in a CDATA section
std::string ret = "<![CDATA[";
#ifdef XS_STRING_UTF8
ret += str;
#else
ret += get_utf8(str);
#endif
ret += "]]>";
return ret;
} else if (l <= BUFFER_LEN) {
LPXSSTR buffer = (LPXSSTR)alloca(6*sizeof(XS_CHAR)*XS_len(s)); // worst case "&quot;" / "&apos;" LPXSSTR buffer = (LPXSSTR)alloca(6*sizeof(XS_CHAR)*XS_len(s)); // worst case "&quot;" / "&apos;"
LPXSSTR o = buffer; LPXSSTR o = buffer;
for(LPCXSSTR p=s; *p; ++p) for(LPCXSSTR p=s; *p; ++p)
switch(*p) { switch(*p) {
case '&': case '&':
*o++ = '&'; *o++ = 'a'; *o++ = 'm'; *o++ = 'p'; *o++ = ';'; *o++ = '&'; *o++ = 'a'; *o++ = 'm'; *o++ = 'p'; *o++ = ';'; // "&amp;"
break; break;
case '<': case '<':
*o++ = '&'; *o++ = 'l'; *o++ = 't'; *o++ = ';'; *o++ = '&'; *o++ = 'l'; *o++ = 't'; *o++ = ';'; // "&lt;"
break; break;
case '>': case '>':
*o++ = '&'; *o++ = 'g'; *o++ = 't'; *o++ = ';'; *o++ = '&'; *o++ = 'g'; *o++ = 't'; *o++ = ';'; // "&gt;"
break; break;
case '"': case '"':
*o++ = '&'; *o++ = 'q'; *o++ = 'u'; *o++ = 'o'; *o++ = 't'; *o++ = ';'; *o++ = '&'; *o++ = 'q'; *o++ = 'u'; *o++ = 'o'; *o++ = 't'; *o++ = ';'; // "&quot;"
break; break;
case '\'': case '\'':
*o++ = '&'; *o++ = 'a'; *o++ = 'p'; *o++ = 'o'; *o++ = 's'; *o++ = ';'; *o++ = '&'; *o++ = 'a'; *o++ = 'p'; *o++ = 'o'; *o++ = 's'; *o++ = ';'; // "&apos;"
break; break;
default: default:
@ -326,23 +339,9 @@ std::string EncodeXMLString(const XS_String& str, bool cdata)
return get_utf8(buffer, o-buffer); return get_utf8(buffer, o-buffer);
#endif #endif
} else { // l > BUFFER_LEN } else { // l > BUFFER_LEN
// encode the whole string in a CDATA section // alternative code for larger strings using ostringstream
std::string ret = "<![CDATA["; // and avoiding to use alloca() for preallocated memory
fast_ostringstream out;
#ifdef XS_STRING_UTF8
ret += str;
#else
ret += get_utf8(str);
#endif
ret += "]]>";
return ret;
/* alternative code using ostringstream (beware: quite slow)
#include <sstream>
std::ostringstream out;
LPCXSSTR s = str.c_str(); LPCXSSTR s = str.c_str();
@ -369,7 +368,7 @@ std::string EncodeXMLString(const XS_String& str, bool cdata)
break; break;
default: default:
if ((unsigned)*p<20 && *p!='\t' *p!='\r' && *p!='\n') if ((unsigned)*p<20 && *p!='\t' && *p!='\r' && *p!='\n')
out << "&" << (unsigned)*p << ";"; out << "&" << (unsigned)*p << ";";
else else
out << *p; out << *p;
@ -380,7 +379,6 @@ std::string EncodeXMLString(const XS_String& str, bool cdata)
#else #else
return get_utf8(out.str()); return get_utf8(out.str());
#endif #endif
*/
} }
} }
@ -417,7 +415,7 @@ XS_String DecodeXMLString(const XS_String& str)
size_t l = e - p; size_t l = e - p;
memcpy(o, p, l); memcpy(o, p, l);
o += l; o += l;
p += 3; p = e + 2;
} else } else
*o++ = *p; *o++ = *p;
} else } else
@ -761,11 +759,15 @@ void XMLReaderBase::EndElementHandler()
const char* p = s; const char* p = s;
const char* e = p + _content.length(); const char* e = p + _content.length();
for(; p<e; ++p) if (!strncmp(s,"<![CDATA[",9) && !strncmp(e-3,"]]>",3)) {
if (*p == '\n') { s += 9;
++p; p = (e-=3);
break; } else
} for(; p<e; ++p)
if (*p == '\n') {
++p;
break;
}
if (p != s) if (p != s)
if (_pos->_children.empty()) // no children in current node? if (_pos->_children.empty()) // no children in current node?

View file

@ -1,8 +1,8 @@
// //
// XML storage classes Version 1.1 // XML storage classes version 1.2
// //
// Copyright (c) 2004, 2005, 2006 Martin Fuchs <martin-fuchs@gmx.net> // Copyright (c) 2004, 2005, 2006, 2007 Martin Fuchs <martin-fuchs@gmx.net>
// //
/// \file xmlstorage.h /// \file xmlstorage.h
@ -40,6 +40,26 @@
#ifndef _XMLSTORAGE_H #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 #if _MSC_VER>=1400
#ifndef _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES #ifndef _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES
#define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES 1 #define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES 1
@ -129,21 +149,55 @@ typedef XMLCh XML_Char;
#endif // _MSC_VER #endif // _MSC_VER
#ifdef UNICODE #ifdef _WIN32
#ifndef _UNICODE
#define _UNICODE
#endif
#else
#ifdef _UNICODE
#define UNICODE
#endif
#endif
#include <windows.h> // for LPCTSTR #include <windows.h> // for LPCTSTR
#include <tchar.h> #include <tchar.h>
#include <malloc.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 <fstream>
#include <sstream> #include <sstream>
#include <string> #include <string>
@ -168,7 +222,7 @@ namespace XMLStorage {
#define LPXSSTR LPSTR #define LPXSSTR LPSTR
#define LPCXSSTR LPCSTR #define LPCXSSTR LPCSTR
#define XS_cmp strcmp #define XS_cmp strcmp
#define XS_icmp stricmp #define XS_icmp _stricmp
#define XS_ncmp strncmp #define XS_ncmp strncmp
#define XS_nicmp strnicmp #define XS_nicmp strnicmp
#define XS_toi atoi #define XS_toi atoi
@ -238,6 +292,7 @@ struct XS_String
XS_String(const super& other) : super(other) {} XS_String(const super& other) : super(other) {}
XS_String(const XS_String& other) : super(other) {} XS_String(const XS_String& other) : super(other) {}
#ifdef _WIN32
#if defined(UNICODE) && !defined(XS_STRING_UTF8) #if defined(UNICODE) && !defined(XS_STRING_UTF8)
XS_String(LPCSTR s) {assign(s);} XS_String(LPCSTR s) {assign(s);}
XS_String(LPCSTR s, size_t l) {assign(s, l);} XS_String(LPCSTR s, size_t l) {assign(s, l);}
@ -251,13 +306,17 @@ struct XS_String
XS_String(const std::wstring& other) {assign(other.c_str());} XS_String(const std::wstring& other) {assign(other.c_str());}
XS_String& operator=(LPCWSTR s) {assign(s); return *this;} XS_String& operator=(LPCWSTR s) {assign(s); return *this;}
#ifdef XS_STRING_UTF8 #ifdef XS_STRING_UTF8
void assign(const XS_String& s) {assign(s.c_str());}
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) {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();} 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 #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) {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();} 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
#endif // _WIN32
#ifdef XS_STRING_UTF8
void assign(const XS_String& s) {assign(s.c_str());}
#endif #endif
XS_String& operator=(LPCXSSTR s) {if (s) super::assign(s); else erase(); return *this;} XS_String& operator=(LPCXSSTR s) {if (s) super::assign(s); else erase(); return *this;}
@ -267,12 +326,14 @@ struct XS_String
operator LPCXSSTR() const {return c_str();} operator LPCXSSTR() const {return c_str();}
#ifdef _WIN32
#ifdef XS_STRING_UTF8 #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));} 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) #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));} 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 #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));} 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 #endif
XS_String& printf(LPCXSSTR fmt, ...) XS_String& printf(LPCXSSTR fmt, ...)
@ -950,7 +1011,7 @@ struct XMLNode : public XS_String
#endif #endif
/// write node with children tree to output stream /// write node with children tree to output stream
std::ostream& write(std::ostream& out, const XMLFormat& format, WRITE_MODE mode=FORMAT_SMART, int indent=0) const bool write(std::ostream& out, const XMLFormat& format, WRITE_MODE mode=FORMAT_SMART, int indent=0) const
{ {
switch(mode) { switch(mode) {
case FORMAT_PLAIN: case FORMAT_PLAIN:
@ -969,7 +1030,7 @@ struct XMLNode : public XS_String
smart_write_worker(out, format, indent); smart_write_worker(out, format, indent);
} }
return out; return out.good();
} }
protected: protected:
@ -2136,6 +2197,102 @@ protected:
#endif // XS_USE_XERCES #endif // XS_USE_XERCES
#if defined(_MSC_VER) && _MSC_VER<1400
struct fast_ostringbuffer : public std::streambuf
{
typedef char _E;
typedef std::char_traits<_E> _Tr;
explicit fast_ostringbuffer()
{_Init(0, 0, std::_Noread);} // optimized for ios::out mode
virtual ~fast_ostringbuffer()
{_Tidy();}
std::string str() const
{if (pptr() != 0)
{std::string _Str(pbase(),
(_Seekhigh<pptr()? pptr(): _Seekhigh) - pbase());
return _Str;}
else
return std::string();}
protected:
virtual int_type overflow(int_type _C = _Tr::eof())
{if (_Tr::eq_int_type(_Tr::eof(), _C))
return _Tr::not_eof(_C);
else if (pptr() != 0 && pptr() < epptr())
{*_Pninc() = _Tr::to_char_type(_C);
return _C;}
else
{size_t _Os = gptr() == 0 ? 0 : epptr() - eback();
size_t _Ns = _Os + _Alsize;
_E *_P = _Al.allocate(_Ns, (void *)0);
if (0 < _Os)
_Tr::copy(_P, eback(), _Os);
else if (_ALSIZE < _Alsize)
_Alsize = _ALSIZE;
if (_Strmode & std::_Allocated)
_Al.deallocate(eback(), _Os);
_Strmode |= std::_Allocated;
if (_Os == 0)
{_Seekhigh = _P;
setp(_P, _P + _Ns);
setg(_P, _P, _P); }
else
{_Seekhigh = _Seekhigh - eback() + _P;
setp(pbase() - eback() + _P, pptr() - eback() + _P, _P + _Ns);
setg(_P, _P, _P);}
*_Pninc() = _Tr::to_char_type(_C);
return _C;}}
void _Init(const _E *_S, size_t _N, std::_Strstate _M)
{_Pendsave = 0, _Seekhigh = 0;
_Alsize = _MINSIZE, _Strmode = _M;
setg(0, 0, 0);
setp(0, 0);}
void _Tidy()
{if (_Strmode & std::_Allocated)
_Al.deallocate(eback(), (pptr() != 0 ? epptr() : egptr()) - eback());
_Seekhigh = 0;
_Strmode &= ~std::_Allocated;}
private:
enum {_ALSIZE = 65536/*512*/, _MINSIZE = 32768/*32*/}; // bigger buffer sizes
_E *_Pendsave, *_Seekhigh;
int _Alsize;
std::_Strstate _Strmode;
std::allocator<_E> _Al;
};
struct fast_ostringstream : public std::iostream
{
typedef std::iostream super;
explicit fast_ostringstream()
: super(&_Sb) {}
std::string str() const
{return _Sb.str();}
private:
fast_ostringbuffer _Sb;
};
#else
typedef std::ostringstream fast_ostringstream;
#endif
/// XML document holder /// XML document holder
struct XMLDoc : public XMLNode struct XMLDoc : public XMLNode
{ {
@ -2221,18 +2378,22 @@ struct XMLDoc : public XMLNode
} }
/// write XML stream preserving previous white space and comments /// write XML stream preserving previous white space and comments
std::ostream& write(std::ostream& out, WRITE_MODE mode=FORMAT_SMART) const bool write(std::ostream& out, WRITE_MODE mode=FORMAT_SMART) const
{ {
_format.print_header(out, mode!=FORMAT_PLAIN); _format.print_header(out, mode!=FORMAT_PLAIN);
if (!_children.empty()) if (_children.size() == 1)
_children.front()->write(out, _format, mode); _children.front()->write(out, _format, mode);
else if (!_children.empty()) {
//throw Exception("more than one XML root!");
return false;
}
return out; return out.good();
} }
/// write XML stream with formating /// write XML stream with formating
std::ostream& write_formating(std::ostream& out) const bool write_formating(std::ostream& out) const
{ {
return write(out, FORMAT_PRETTY); return write(out, FORMAT_PRETTY);
} }
@ -2241,14 +2402,14 @@ struct XMLDoc : public XMLNode
{ {
tofstream out(path); tofstream out(path);
return write(out, mode).good(); return write(out, mode);
} }
bool write_formating(LPCTSTR path) const bool write_formating(LPCTSTR path) const
{ {
tofstream out(path); tofstream out(path);
return write_formating(out).good(); return write_formating(out);
} }
XMLFormat _format; XMLFormat _format;

View file

@ -1,8 +1,8 @@
// //
// XML storage classes Version 1.1 // XML storage classes version 1.2
// //
// Copyright (c) 2006 Martin Fuchs <martin-fuchs@gmx.net> // Copyright (c) 2006, 2007 Martin Fuchs <martin-fuchs@gmx.net>
// //
/// \file xs-native.cpp /// \file xs-native.cpp
@ -109,10 +109,14 @@ struct Buffer
const std::string& str(bool utf8) // returns UTF-8 encoded buffer content const std::string& str(bool utf8) // returns UTF-8 encoded buffer content
{ {
#if defined(_WIN32) && !defined(XS_STRING_UTF8)
if (utf8) if (utf8)
#endif
_buffer_str.assign(_buffer, _wptr-_buffer); _buffer_str.assign(_buffer, _wptr-_buffer);
#if defined(_WIN32) && !defined(XS_STRING_UTF8)
else else
_buffer_str = get_utf8(_buffer, _wptr-_buffer); _buffer_str = get_utf8(_buffer, _wptr-_buffer);
#endif
return _buffer_str; return _buffer_str;
} }