update to XMLStorage version 1.2
authorMartin Fuchs <martin-fuchs@gmx.net>
Sat, 5 May 2007 07:30:20 +0000 (07:30 +0000)
committerMartin Fuchs <martin-fuchs@gmx.net>
Sat, 5 May 2007 07:30:20 +0000 (07:30 +0000)
svn path=/trunk/; revision=26646

reactos/base/shell/explorer/utility/xmlstorage.cpp
reactos/base/shell/explorer/utility/xmlstorage.h
reactos/base/shell/explorer/utility/xs-native.cpp

index 29c79cd..f447701 100644 (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
@@ -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 = "<![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 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++ = ';';                             // "&amp;"
                                break;
 
                          case '<':
-                               *o++ = '&';     *o++ = 'l'; *o++ = 't'; *o++ = ';';
+                               *o++ = '&';     *o++ = 'l'; *o++ = 't'; *o++ = ';';                                                     // "&lt;"
                                break;
 
                          case '>':
-                               *o++ = '&';     *o++ = 'g'; *o++ = 't'; *o++ = ';';
+                               *o++ = '&';     *o++ = 'g'; *o++ = 't'; *o++ = ';';                                                     // "&gt;"
                                break;
 
                          case '"':
-                               *o++ = '&';     *o++ = 'q'; *o++ = 'u'; *o++ = 'o'; *o++ = 't'; *o++ = ';';
+                               *o++ = '&';     *o++ = 'q'; *o++ = 'u'; *o++ = 'o'; *o++ = 't'; *o++ = ';';     // "&quot;"
                                break;
 
                          case '\'':
-                               *o++ = '&';     *o++ = 'a'; *o++ = 'p'; *o++ = 'o'; *o++ = 's'; *o++ = ';';
+                               *o++ = '&';     *o++ = 'a'; *o++ = 'p'; *o++ = 'o'; *o++ = 's'; *o++ = ';';     // "&apos;"
                                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 = "<![CDATA[";
-
-#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;
+                // 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<e; ++p)
-               if (*p == '\n') {
-                       ++p;
-                       break;
-               }
+       if (!strncmp(s,"<![CDATA[",9) && !strncmp(e-3,"]]>",3)) {
+               s += 9;
+               p = (e-=3);
+       } else
+               for(; p<e; ++p)
+                       if (*p == '\n') {
+                               ++p;
+                               break;
+                       }
 
        if (p != s)
                if (_pos->_children.empty())    // no children in current node?
index a488bbf..8e2d80c 100644 (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
 #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,20 +149,54 @@ typedef XMLCh XML_Char;
 #endif // _MSC_VER
 
 
-#ifdef UNICODE
-#ifndef _UNICODE
-#define _UNICODE
-#endif
+#ifdef _WIN32
+
+#include <windows.h>   // for LPCTSTR
+#include <tchar.h>
+#include <malloc.h>
+
 #else
-#ifdef _UNICODE
-#define UNICODE
+
+#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
 
-#include <windows.h>   // for LPCTSTR
+#endif
 
-#include <tchar.h>
-#include <malloc.h>
 
 #include <fstream>
 #include <sstream>
@@ -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<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
 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;
index 67add3c..59c923d 100644 (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
@@ -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;
        }