From 231dcbf43a6808696434f74a94c036c757046bd1 Mon Sep 17 00:00:00 2001 From: Martin Fuchs Date: Sat, 5 May 2007 07:30:20 +0000 Subject: [PATCH] update to XMLStorage version 1.2 svn path=/trunk/; revision=26646 --- .../shell/explorer/utility/xmlstorage.cpp | 68 +++--- .../base/shell/explorer/utility/xmlstorage.h | 205 ++++++++++++++++-- .../base/shell/explorer/utility/xs-native.cpp | 8 +- 3 files changed, 224 insertions(+), 57 deletions(-) diff --git a/reactos/base/shell/explorer/utility/xmlstorage.cpp b/reactos/base/shell/explorer/utility/xmlstorage.cpp index 29c79cd30c8..f4477017af2 100644 --- a/reactos/base/shell/explorer/utility/xmlstorage.cpp +++ b/reactos/base/shell/explorer/utility/xmlstorage.cpp @@ -1,8 +1,8 @@ // - // XML storage classes Version 1.1 + // XML storage classes version 1.2 // - // Copyright (c) 2004, 2005, 2006 Martin Fuchs + // Copyright (c) 2004, 2005, 2006, 2007 Martin Fuchs // /// \file xmlstorage.cpp @@ -284,30 +284,43 @@ std::string EncodeXMLString(const XS_String& str, bool cdata) LPCXSSTR s = str.c_str(); size_t l = XS_len(s); - if (!cdata && l<=BUFFER_LEN) { + if (cdata) { + // encode the whole string in a CDATA section + std::string ret = ""; + + return ret; + } else if (l <= BUFFER_LEN) { LPXSSTR buffer = (LPXSSTR)alloca(6*sizeof(XS_CHAR)*XS_len(s)); // worst case """ / "'" LPXSSTR o = buffer; for(LPCXSSTR p=s; *p; ++p) switch(*p) { case '&': - *o++ = '&'; *o++ = 'a'; *o++ = 'm'; *o++ = 'p'; *o++ = ';'; + *o++ = '&'; *o++ = 'a'; *o++ = 'm'; *o++ = 'p'; *o++ = ';'; // "&" break; case '<': - *o++ = '&'; *o++ = 'l'; *o++ = 't'; *o++ = ';'; + *o++ = '&'; *o++ = 'l'; *o++ = 't'; *o++ = ';'; // "<" break; case '>': - *o++ = '&'; *o++ = 'g'; *o++ = 't'; *o++ = ';'; + *o++ = '&'; *o++ = 'g'; *o++ = 't'; *o++ = ';'; // ">" break; case '"': - *o++ = '&'; *o++ = 'q'; *o++ = 'u'; *o++ = 'o'; *o++ = 't'; *o++ = ';'; + *o++ = '&'; *o++ = 'q'; *o++ = 'u'; *o++ = 'o'; *o++ = 't'; *o++ = ';'; // """ break; case '\'': - *o++ = '&'; *o++ = 'a'; *o++ = 'p'; *o++ = 'o'; *o++ = 's'; *o++ = ';'; + *o++ = '&'; *o++ = 'a'; *o++ = 'p'; *o++ = 'o'; *o++ = 's'; *o++ = ';'; // "'" break; default: @@ -326,23 +339,9 @@ std::string EncodeXMLString(const XS_String& str, bool cdata) return get_utf8(buffer, o-buffer); #endif } else { // l > BUFFER_LEN - // encode the whole string in a CDATA section - std::string ret = ""; - - return ret; - -/* alternative code using ostringstream (beware: quite slow) -#include - - std::ostringstream out; + // alternative code for larger strings using ostringstream + // and avoiding to use alloca() for preallocated memory + fast_ostringstream out; LPCXSSTR s = str.c_str(); @@ -369,7 +368,7 @@ std::string EncodeXMLString(const XS_String& str, bool cdata) break; default: - if ((unsigned)*p<20 && *p!='\t' *p!='\r' && *p!='\n') + if ((unsigned)*p<20 && *p!='\t' && *p!='\r' && *p!='\n') out << "&" << (unsigned)*p << ";"; else out << *p; @@ -380,7 +379,6 @@ std::string EncodeXMLString(const XS_String& str, bool cdata) #else return get_utf8(out.str()); #endif - */ } } @@ -417,7 +415,7 @@ XS_String DecodeXMLString(const XS_String& str) size_t l = e - p; memcpy(o, p, l); o += l; - p += 3; + p = e + 2; } else *o++ = *p; } else @@ -761,11 +759,15 @@ void XMLReaderBase::EndElementHandler() const char* p = s; const char* e = p + _content.length(); - for(; p",3)) { + s += 9; + p = (e-=3); + } else + for(; p_children.empty()) // no children in current node? diff --git a/reactos/base/shell/explorer/utility/xmlstorage.h b/reactos/base/shell/explorer/utility/xmlstorage.h index a488bbf6842..8e2d80cb299 100644 --- a/reactos/base/shell/explorer/utility/xmlstorage.h +++ b/reactos/base/shell/explorer/utility/xmlstorage.h @@ -1,8 +1,8 @@ // - // XML storage classes Version 1.1 + // XML storage classes version 1.2 // - // Copyright (c) 2004, 2005, 2006 Martin Fuchs + // Copyright (c) 2004, 2005, 2006, 2007 Martin Fuchs // /// \file xmlstorage.h @@ -40,6 +40,26 @@ #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 @@ -129,21 +149,55 @@ typedef XMLCh XML_Char; #endif // _MSC_VER -#ifdef UNICODE -#ifndef _UNICODE -#define _UNICODE -#endif -#else -#ifdef _UNICODE -#define UNICODE -#endif -#endif +#ifdef _WIN32 #include // for LPCTSTR - #include #include +#else + +#include +#include + +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 #include #include @@ -168,7 +222,7 @@ namespace XMLStorage { #define LPXSSTR LPSTR #define LPCXSSTR LPCSTR #define XS_cmp strcmp -#define XS_icmp stricmp +#define XS_icmp _stricmp #define XS_ncmp strncmp #define XS_nicmp strnicmp #define XS_toi atoi @@ -238,6 +292,7 @@ struct XS_String 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);} @@ -251,13 +306,17 @@ struct XS_String 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(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, 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;} @@ -267,12 +326,14 @@ struct XS_String 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, ...) @@ -950,7 +1011,7 @@ struct XMLNode : public XS_String #endif /// 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) { case FORMAT_PLAIN: @@ -969,7 +1030,7 @@ struct XMLNode : public XS_String smart_write_worker(out, format, indent); } - return out; + return out.good(); } protected: @@ -2136,6 +2197,102 @@ protected: #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 _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 struct XMLDoc : public XMLNode { @@ -2221,18 +2378,22 @@ struct XMLDoc : public XMLNode } /// 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); - if (!_children.empty()) + if (_children.size() == 1) _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 - std::ostream& write_formating(std::ostream& out) const + bool write_formating(std::ostream& out) const { return write(out, FORMAT_PRETTY); } @@ -2241,14 +2402,14 @@ struct XMLDoc : public XMLNode { tofstream out(path); - return write(out, mode).good(); + return write(out, mode); } bool write_formating(LPCTSTR path) const { tofstream out(path); - return write_formating(out).good(); + return write_formating(out); } XMLFormat _format; diff --git a/reactos/base/shell/explorer/utility/xs-native.cpp b/reactos/base/shell/explorer/utility/xs-native.cpp index 67add3cf271..59c923d65e8 100644 --- a/reactos/base/shell/explorer/utility/xs-native.cpp +++ b/reactos/base/shell/explorer/utility/xs-native.cpp @@ -1,8 +1,8 @@ // - // XML storage classes Version 1.1 + // XML storage classes version 1.2 // - // Copyright (c) 2006 Martin Fuchs + // Copyright (c) 2006, 2007 Martin Fuchs // /// \file xs-native.cpp @@ -109,10 +109,14 @@ struct Buffer const std::string& str(bool utf8) // returns UTF-8 encoded buffer content { +#if defined(_WIN32) && !defined(XS_STRING_UTF8) if (utf8) +#endif _buffer_str.assign(_buffer, _wptr-_buffer); +#if defined(_WIN32) && !defined(XS_STRING_UTF8) else _buffer_str = get_utf8(_buffer, _wptr-_buffer); +#endif return _buffer_str; }