[Ocipl-commits] SF.net SVN: ocipl: [35] trunk/xmlstorage
Brought to you by:
martinfuchs
|
From: <mar...@us...> - 2007-10-28 14:49:59
|
Revision: 35
http://ocipl.svn.sourceforge.net/ocipl/?rev=35&view=rev
Author: martinfuchs
Date: 2007-10-28 07:50:00 -0700 (Sun, 28 Oct 2007)
Log Message:
-----------
Update XMLStorage to version 1.2
Modified Paths:
--------------
trunk/xmlstorage/xmlstorage-license.txt
trunk/xmlstorage/xmlstorage.cpp
trunk/xmlstorage/xmlstorage.h
trunk/xmlstorage/xs-expat.cpp
trunk/xmlstorage/xs-native.cpp
trunk/xmlstorage/xs-xerces.cpp
Modified: trunk/xmlstorage/xmlstorage-license.txt
===================================================================
--- trunk/xmlstorage/xmlstorage-license.txt 2007-10-28 10:28:31 UTC (rev 34)
+++ trunk/xmlstorage/xmlstorage-license.txt 2007-10-28 14:50:00 UTC (rev 35)
@@ -2,7 +2,7 @@
//
// XML storage classes
//
- // Copyright (c) 2004, 2005, 2006 Martin Fuchs <mar...@gm...>
+ // Copyright (c) 2004, 2005, 2006, 2007 Martin Fuchs <mar...@gm...>
//
Modified: trunk/xmlstorage/xmlstorage.cpp
===================================================================
--- trunk/xmlstorage/xmlstorage.cpp 2007-10-28 10:28:31 UTC (rev 34)
+++ trunk/xmlstorage/xmlstorage.cpp 2007-10-28 14:50:00 UTC (rev 35)
@@ -1,8 +1,8 @@
//
- // XML storage classes Version 1.1
+ // XML storage C++ classes version 1.2
//
- // Copyright (c) 2004, 2005, 2006 Martin Fuchs <mar...@gm...>
+ // Copyright (c) 2004, 2005, 2006, 2007 Martin Fuchs <mar...@gm...>
//
/// \file xmlstorage.cpp
@@ -151,51 +151,8 @@
// parse relative path
while(*path) {
- const char* slash = strchr(path, '/');
- if (slash == path)
- return NULL;
+ node = const_cast<XMLNode*>(node)->get_child_relative(path, false); // get_child_relative() ist const for create==false
- size_t l = slash? slash-path: strlen(path);
- std::string comp(path, l);
- path += l;
-
- // look for [n] and [@attr_name="attr_value"] expressions in path components
- const char* bracket = strchr(comp.c_str(), '[');
- l = bracket? bracket-comp.c_str(): comp.length();
- std::string child_name(comp.c_str(), l);
- std::string attr_name, attr_value;
-
- int n = 0;
- if (bracket) {
- std::string expr = unescape(bracket, '[', ']');
- const char* p = expr.c_str();
-
- n = atoi(p); // read index number
-
- if (n)
- n = n - 1; // convert into zero based index
-
- const char* at = strchr(p, '@');
-
- if (at) {
- p = at + 1;
- const char* equal = strchr(p, '=');
-
- // read attribute name and value
- if (equal) {
- attr_name = unescape(p, equal-p);
- attr_value = unescape(equal+1);
- }
- }
- }
-
- if (attr_name.empty())
- // search n.th child node with specified name
- node = node->find(child_name, n);
- else
- // search n.th child node with specified name and matching attribute value
- node = node->find(child_name, attr_name, attr_value, n);
-
if (!node)
return NULL;
@@ -212,68 +169,73 @@
// parse relative path
while(*path) {
- const char* slash = strchr(path, '/');
- if (slash == path)
- return NULL;
+ node = node->get_child_relative(path, true);
- size_t l = slash? slash-path: strlen(path);
- std::string comp(path, l);
- path += l;
+ if (*path == '/')
+ ++path;
+ }
- // look for [n] and [@attr_name="attr_value"] expressions in path components
- const char* bracket = strchr(comp.c_str(), '[');
- l = bracket? bracket-comp.c_str(): comp.length();
- std::string child_name(comp.c_str(), l);
- std::string attr_name, attr_value;
+ return node;
+}
- int n = 0;
- if (bracket) {
- std::string expr = unescape(bracket, '[', ']');
- const char* p = expr.c_str();
+XMLNode* XMLNode::get_child_relative(const char*& path, bool create)
+{
+ const char* slash = strchr(path, '/');
+ if (slash == path)
+ return NULL;
- n = atoi(p); // read index number
+ size_t l = slash? slash-path: strlen(path);
+ std::string comp(path, l);
+ path += l;
- if (n)
- n = n - 1; // convert into zero based index
+ // look for [n] and [@attr_name="attr_value"] expressions in path components
+ const char* bracket = strchr(comp.c_str(), '[');
+ l = bracket? bracket-comp.c_str(): comp.length();
+ std::string child_name(comp.c_str(), l);
+ std::string attr_name, attr_value;
- const char* at = strchr(p, '@');
+ int n = 0;
+ if (bracket) {
+ std::string expr = unescape(bracket, '[', ']');
+ const char* p = expr.c_str();
- if (at) {
- p = at + 1;
- const char* equal = strchr(p, '=');
+ n = atoi(p); // read index number
- // read attribute name and value
- if (equal) {
- attr_name = unescape(p, equal-p);
- attr_value = unescape(equal+1);
- }
- }
- }
+ if (n)
+ n = n - 1; // convert into zero based index
- XMLNode* child;
+ const char* at = strchr(p, '@');
- if (attr_name.empty())
- // search n.th child node with specified name
- child = node->find(child_name, n);
- else
- // search n.th child node with specified name and matching attribute value
- child = node->find(child_name, attr_name, attr_value, n);
+ if (at) {
+ p = at + 1;
+ const char* equal = strchr(p, '=');
- if (!child) {
- child = new XMLNode(child_name);
- node->add_child(child);
-
- if (!attr_name.empty())
- (*node)[attr_name] = attr_value;
+ // read attribute name and value
+ if (equal) {
+ attr_name = unescape(p, equal-p);
+ attr_value = unescape(equal+1);
+ }
}
+ }
- node = child;
+ XMLNode* child;
- if (*path == '/')
- ++path;
+ if (attr_name.empty())
+ // search n.th child node with specified name
+ child = find(child_name, n);
+ else
+ // search n.th child node with specified name and matching attribute value
+ child = find(child_name, attr_name, attr_value, n);
+
+ if (!child && create) {
+ child = new XMLNode(child_name);
+ add_child(child);
+
+ if (!attr_name.empty())
+ (*this)[attr_name] = attr_value;
}
- return node;
+ return child;
}
@@ -283,36 +245,49 @@
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 """ / "'"
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:
- if ((unsigned)*p<20 && *p!='\t' && *p!='\r' && *p!='\n') {
+ if ((unsigned)*p<0x20 && *p!='\t' && *p!='\r' && *p!='\n') {
char b[16];
- sprintf(b, "&%d;", (unsigned)*p);
+ sprintf(b, "&#%d;", (unsigned)*p);
for(const char*q=b; *q; )
*o++ = *q++;
} else
@@ -325,24 +300,10 @@
return get_utf8(buffer, o-buffer);
#endif
} else { // l > BUFFER_LEN
- // encode the whole string in a CDATA section
- std::string ret = "<![CDATA[";
+ // alternative code for larger strings using ostringstream
+ // 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();
for(LPCXSSTR p=s; *p; ++p)
@@ -368,8 +329,8 @@
break;
default:
- if ((unsigned)*p<20 && *p!='\t' *p!='\r' && *p!='\n')
- out << "&" << (unsigned)*p << ";";
+ if ((unsigned)*p<0x20 && *p!='\t' && *p!='\r' && *p!='\n')
+ out << "&#" << (unsigned)*p << ";";
else
out << *p;
}
@@ -379,7 +340,6 @@
#else
return get_utf8(out.str());
#endif
- */
}
}
@@ -407,7 +367,7 @@
} else if (!XS_nicmp(p+1, XS_TEXT("apos;"), 5)) {
*o++ = '\'';
p += 5;
- } else
+ } else //@@ maybe decode "&#xx;" special characters
*o++ = *p;
} else if (*p=='<' && !XS_nicmp(p+1,XS_TEXT("![CDATA["),8)) {
LPCXSSTR e = XS_strstr(p+9, XS_TEXT("]]>"));
@@ -416,7 +376,7 @@
size_t l = e - p;
memcpy(o, p, l);
o += l;
- p += 3;
+ p = e + 2;
} else
*o++ = *p;
} else
@@ -427,7 +387,7 @@
/// write node with children tree to output stream using original white space
-void XMLNode::write_worker(std::ostream& out, int indent) const
+void XMLNode::write_worker(std::ostream& out) const
{
out << _leading << '<' << EncodeXMLString(*this);
@@ -438,7 +398,7 @@
out << '>' << _content;
for(Children::const_iterator it=_children.begin(); it!=_children.end(); ++it)
- (*it)->write_worker(out, indent+1);
+ (*it)->write_worker(out);
out << _end_leading << "</" << EncodeXMLString(*this) << '>';
} else
@@ -456,9 +416,13 @@
for(AttributeMap::const_iterator it=_attributes.begin(); it!=_attributes.end(); ++it)
out << ' ' << EncodeXMLString(it->first) << "=\"" << EncodeXMLString(it->second) << "\"";
- if (!_children.empty()/*@@ || !_content.empty()*/) {
- out << ">";
+ // strip leading white space from content
+ const char* content = _content.c_str();
+ while(isspace((unsigned char)*content)) ++content;
+ if (!_children.empty() || *content) {
+ out << ">" << content;
+
for(Children::const_iterator it=_children.begin(); it!=_children.end(); ++it)
(*it)->plain_write_worker(out);
@@ -479,9 +443,16 @@
for(AttributeMap::const_iterator it=_attributes.begin(); it!=_attributes.end(); ++it)
out << ' ' << EncodeXMLString(it->first) << "=\"" << EncodeXMLString(it->second) << "\"";
- if (!_children.empty()/*@@ || !_content.empty()*/) {
- out << '>' << format._endl;
+ // strip leading white space from content
+ const char* content = _content.c_str();
+ while(isspace((unsigned char)*content)) ++content;
+ if (!_children.empty() || *content) {
+ out << '>' << content;
+
+ if (!_children.empty())
+ out << format._endl;
+
for(Children::const_iterator it=_children.begin(); it!=_children.end(); ++it)
(*it)->pretty_write_worker(out, format, indent+1);
@@ -497,26 +468,34 @@
/// write node with children tree to output stream using smart formating
void XMLNode::smart_write_worker(std::ostream& out, const XMLFormat& format, int indent) const
{
- if (_leading.empty())
+ // strip the first line feed from _leading
+ const char* leading = _leading.c_str();
+ if (*leading == '\n') ++leading;
+
+ if (!*leading)
for(int i=indent; i--; )
out << XML_INDENT_SPACE;
else
- out << _leading;
+ out << leading;
out << '<' << EncodeXMLString(*this);
for(AttributeMap::const_iterator it=_attributes.begin(); it!=_attributes.end(); ++it)
out << ' ' << EncodeXMLString(it->first) << "=\"" << EncodeXMLString(it->second) << "\"";
- if (_children.empty() && _content.empty())
+ // strip leading white space from content
+ const char* content = _content.c_str();
+ while(isspace((unsigned char)*content)) ++content;
+
+ if (_children.empty() && !*content)
out << "/>";
else {
out << '>';
- if (_content.empty())
+ if (!*content)
out << format._endl;
else
- out << _content;
+ out << content;
Children::const_iterator it = _children.begin();
@@ -524,11 +503,15 @@
for(; it!=_children.end(); ++it)
(*it)->smart_write_worker(out, format, indent+1);
- if (_end_leading.empty())
+ // strip the first line feed from _end_leading
+ const char* end_leading = _end_leading.c_str();
+ if (*end_leading == '\n') ++end_leading;
+
+ if (!*end_leading)
for(int i=indent; i--; )
out << XML_INDENT_SPACE;
else
- out << _end_leading;
+ out << end_leading;
} else
out << _end_leading;
@@ -711,16 +694,14 @@
/// notifications about XML start tag
void XMLReaderBase::StartElementHandler(const XS_String& name, const XMLNode::AttributeMap& attributes)
{
- // search for end of first line
const char* s = _content.c_str();
+ const char* e = s + _content.length();
const char* p = s;
- const char* e = p + _content.length();
- for(; p<e; ++p)
- if (*p == '\n') {
- ++p;
+ // search for content end leaving only white space for leading
+ for(p=e; p>s; --p)
+ if (!isspace((unsigned char)p[-1]))
break;
- }
if (p != s)
if (_pos->_children.empty()) { // no children in last node?
@@ -755,25 +736,27 @@
/// notifications about XML end tag
void XMLReaderBase::EndElementHandler()
{
- // search for end of first line
const char* s = _content.c_str();
- const char* p = s;
- const char* e = p + _content.length();
+ const char* e = s + _content.length();
+ const char* p;
- for(; p<e; ++p)
- if (*p == '\n') {
- ++p;
- break;
- }
+ if (!strncmp(s,"<![CDATA[",9) && !strncmp(e-3,"]]>",3)) {
+ s += 9;
+ p = (e-=3);
+ } else {
+ // search for content end leaving only white space for _end_leading
+ for(p=e; p>s; --p)
+ if (!isspace((unsigned char)p[-1]))
+ break;
+ }
if (p != s)
if (_pos->_children.empty()) // no children in current node?
_pos->_content.append(s, p-s);
+ else if (_last_tag == TAG_START)
+ _pos->_content.append(s, p-s);
else
- if (_last_tag == TAG_START)
- _pos->_content.append(s, p-s);
- else
- _pos->_children.back()->_trailing.append(s, p-s);
+ _pos->_children.back()->_trailing.append(s, p-s);
if (p != e)
_pos->_end_leading.assign(p, e-p);
Modified: trunk/xmlstorage/xmlstorage.h
===================================================================
--- trunk/xmlstorage/xmlstorage.h 2007-10-28 10:28:31 UTC (rev 34)
+++ trunk/xmlstorage/xmlstorage.h 2007-10-28 14:50:00 UTC (rev 35)
@@ -1,8 +1,8 @@
//
- // XML storage classes Version 1.1
+ // XML storage C++ classes version 1.2
//
- // Copyright (c) 2004, 2005, 2006 Martin Fuchs <mar...@gm...>
+ // Copyright (c) 2004, 2005, 2006, 2007 Martin Fuchs <mar...@gm...>
//
/// \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,63 @@
#endif // _MSC_VER
-#ifdef UNICODE
-#ifndef _UNICODE
-#define _UNICODE
+#ifdef _WIN32
+
+#include <windows.h> // for LPCTSTR
+#include <tchar.h>
+#include <malloc.h>
+
+#ifndef _MSC_VER
+#include <stdio.h> // vsnprintf(), snprintf()
#endif
+
#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>
+#ifdef __BORLANDC__
+#define _strcmpi strcmpi
+#endif
+
#include <fstream>
#include <sstream>
#include <string>
@@ -168,7 +230,7 @@
#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 +300,7 @@
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,7 +314,6 @@
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
@@ -259,7 +321,12 @@
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);}
@@ -267,6 +334,7 @@
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)
@@ -274,6 +342,7 @@
#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, ...)
{
@@ -415,11 +484,13 @@
#ifdef __GNUC__
#include <ext/stdio_filebuf.h>
-typedef __gnu_cxx::stdio_filebuf<char> STDIO_FILEBUF;
-#else
-typedef std::filebuf STDIO_FILEBUF;
+#define FILE_FILEBUF __gnu_cxx::stdio_filebuf<char>
+#elif defined(_MSC_VER)
+#define FILE_FILEBUF std::filebuf
#endif
+#ifdef FILE_FILEBUF
+
/// base class for XMLStorage::tifstream and XMLStorage::tofstream
struct FileHolder
{
@@ -460,7 +531,7 @@
}
protected:
- STDIO_FILEBUF _buf;
+ FILE_FILEBUF _buf;
};
/// output file stream with ANSI/UNICODE file names
@@ -485,10 +556,38 @@
}
protected:
- STDIO_FILEBUF _buf;
+ FILE_FILEBUF _buf;
};
+#else // FILE_FILEBUF
+#ifdef UNICODE
+#error UNICODE not supported for this platform
+#endif
+
+struct tifstream : public std::ifstream
+{
+ typedef std::ifstream super;
+
+ tifstream(const char* path)
+ : super(path, std::ios::in|std::ios::binary)
+ {
+ }
+};
+
+struct tofstream : public std::ofstream
+{
+ typedef std::ofstream super;
+
+ tofstream(const char* path)
+ : super(path, std::ios::out|std::ios::binary)
+ {
+ }
+};
+
+#endif
+
+
// write XML files with 2 spaces indenting
#define XML_INDENT_SPACE " "
@@ -714,7 +813,7 @@
return super::find(x);
}
- XS_String get(const char* x, LPXSSTR def=XS_EMPTY_STR) const
+ XS_String get(const char* x, LPCXSSTR def=XS_EMPTY_STR) const
{
const_iterator found = find(x);
@@ -728,7 +827,7 @@
/// map of XML node attributes
struct AttributeMap : public std::map<XS_String, XS_String>
{
- XS_String get(const char* x, LPXSSTR def=XS_EMPTY_STR) const
+ XS_String get(const char* x, LPCXSSTR def=XS_EMPTY_STR) const
{
const_iterator found = find(x);
@@ -841,14 +940,14 @@
_attributes[attr_name] = value;
}
- /// C++ write access to an attribute
+ /// index operator write access to an attribute
XS_String& operator[](const XS_String& attr_name)
{
return _attributes[attr_name];
}
/// read only access to an attribute
- template<typename T> XS_String get(const T& attr_name, LPXSSTR def=XS_EMPTY_STR) const
+ template<typename T> XS_String get(const T& attr_name, LPCXSSTR def=XS_EMPTY_STR) const
{
AttributeMap::const_iterator found = _attributes.find(attr_name);
@@ -950,7 +1049,7 @@
#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:
@@ -962,14 +1061,14 @@
break;
case FORMAT_ORIGINAL:
- write_worker(out, indent);
+ write_worker(out);
break;
default: // FORMAT_SMART
smart_write_worker(out, format, indent);
}
- return out;
+ return out.good();
}
protected:
@@ -1052,10 +1151,13 @@
/// relative XPath create function
XMLNode* create_relative(const char* path);
- void write_worker(std::ostream& out, int indent) const;
+ void write_worker(std::ostream& out) const;
void plain_write_worker(std::ostream& out) const;
void pretty_write_worker(std::ostream& out, const XMLFormat& format, int indent) const;
void smart_write_worker(std::ostream& out, const XMLFormat& format, int indent) const;
+
+protected:
+ XMLNode* get_child_relative(const char*& path, bool create); // mutable for create==true
};
@@ -1306,7 +1408,7 @@
return *_cur;
}
- /// C++ access to current node
+ /// automatic access to current node
operator const XMLNode*() const {return _cur;}
operator XMLNode*() {return _cur;}
@@ -1317,9 +1419,9 @@
XMLNode& operator*() {return *_cur;}
/// attribute access
- XS_String get(const XS_String& attr_name) const
+ XS_String get(const XS_String& attr_name, LPCXSSTR def=XS_EMPTY_STR) const
{
- return _cur->get(attr_name);
+ return _cur->get(attr_name, def);
}
/// attribute setting
@@ -1328,7 +1430,7 @@
_cur->put(attr_name, value);
}
- /// C++ attribute access
+ /// index operator attribute access
template<typename T> XS_String get(const T& attr_name) const {return (*_cur)[attr_name];}
XS_String& operator[](const XS_String& attr_name) {return (*_cur)[attr_name];}
@@ -1503,7 +1605,7 @@
return *_cur;
}
- /// C++ access to current node
+ /// automatic access to current node
operator const XMLNode*() const {return _cur;}
const XMLNode* operator->() const {return _cur;}
@@ -1516,7 +1618,7 @@
return _cur->get(attr_name);
}
- /// C++ attribute access
+ /// index operator attribute access
template<typename T> XS_String get(const T& attr_name) const {return _cur->get(attr_name);}
/// go back to previous position
@@ -1883,23 +1985,23 @@
};
/// type converter for string data with write access
-struct XMStringRef
+struct XMLStringRef
{
- XMStringRef(XMLNode* node, const XS_String& attr_name, LPCXSSTR def=XS_EMPTY)
+ XMLStringRef(XMLNode* node, const XS_String& attr_name, LPCXSSTR def=XS_EMPTY)
: _ref((*node)[attr_name])
{
if (_ref.empty())
assign(def);
}
- XMStringRef(XMLNode* node, const XS_String& node_name, const XS_String& attr_name, LPCXSSTR def=XS_EMPTY)
+ XMLStringRef(const XS_String& node_name, XMLNode* node, const XS_String& attr_name, LPCXSSTR def=XS_EMPTY)
: _ref(node->subvalue(node_name, attr_name))
{
if (_ref.empty())
assign(def);
}
- XMStringRef& operator=(const XS_String& value)
+ XMLStringRef& operator=(const XS_String& value)
{
assign(value);
@@ -2136,6 +2238,102 @@
#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
{
@@ -2147,11 +2345,11 @@
XMLDoc(LPCTSTR path)
: XMLNode("")
{
- read(path);
+ read_file(path);
}
#ifdef XS_USE_XERCES
- bool read(LPCTSTR path)
+ bool read_file(LPCTSTR path)
{
XMLReader reader(this, path);
@@ -2162,7 +2360,7 @@
#endif
}
- bool read(const char* buffer, size_t len, const std::string& system_id=std::string())
+ bool read_buffer(const char* buffer, size_t len, const std::string& system_id=std::string())
{
XMLReader reader(this, (const XMLByte*)buffer, len, system_id);
@@ -2171,7 +2369,7 @@
#else // XS_USE_XERCES
- bool read(LPCTSTR path)
+ bool read_file(LPCTSTR path)
{
tifstream in(path);
XMLReader reader(this, in);
@@ -2183,7 +2381,7 @@
#endif
}
- bool read(const char* buffer, size_t len, const std::string& system_id=std::string())
+ bool read_buffer(const char* buffer, size_t len, const std::string& system_id=std::string())
{
std::istringstream in(std::string(buffer, len));
@@ -2220,35 +2418,40 @@
return true;
}
- /// write XML stream preserving previous white space and comments
- std::ostream& write(std::ostream& out, WRITE_MODE mode=FORMAT_SMART) const
+ /// write XML stream
+ // FORMAT_SMART: preserving previous white space and comments
+ 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);
}
- bool write(LPCTSTR path, WRITE_MODE mode=FORMAT_SMART) const
+ bool write_file(LPCTSTR path, WRITE_MODE mode=FORMAT_SMART) const
{
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;
@@ -2293,7 +2496,7 @@
{
XMLMessageFromString(const std::string& xml_str, const std::string& system_id=std::string())
{
- read(xml_str.c_str(), xml_str.length(), system_id);
+ read_buffer(xml_str.c_str(), xml_str.length(), system_id);
}
};
@@ -2304,7 +2507,7 @@
XMLMessageReader(const std::string& xml_str, const std::string& system_id=std::string())
: XMLPos(&_msg)
{
- _msg.read(xml_str.c_str(), xml_str.length(), system_id);
+ _msg.read_buffer(xml_str.c_str(), xml_str.length(), system_id);
}
const XMLDoc& get_document()
@@ -2382,7 +2585,7 @@
_stack.top()._attributes[attr_name] = value;
}
- /// C++ write access to an attribute
+ /// index operator write access to an attribute
XS_String& operator[](const XS_String& attr_name)
{
if (_stack.empty())
Modified: trunk/xmlstorage/xs-expat.cpp
===================================================================
--- trunk/xmlstorage/xs-expat.cpp 2007-10-28 10:28:31 UTC (rev 34)
+++ trunk/xmlstorage/xs-expat.cpp 2007-10-28 14:50:00 UTC (rev 35)
@@ -1,6 +1,6 @@
//
- // XML storage classes Version 1.1
+ // XML storage C++ classes version 1.2
//
// Copyright (c) 2006 Martin Fuchs <mar...@gm...>
//
Modified: trunk/xmlstorage/xs-native.cpp
===================================================================
--- trunk/xmlstorage/xs-native.cpp 2007-10-28 10:28:31 UTC (rev 34)
+++ trunk/xmlstorage/xs-native.cpp 2007-10-28 14:50:00 UTC (rev 35)
@@ -1,8 +1,8 @@
//
- // XML storage classes Version 1.1
+ // XML storage C++ classes version 1.2
//
- // Copyright (c) 2006 Martin Fuchs <mar...@gm...>
+ // Copyright (c) 2006, 2007 Martin Fuchs <mar...@gm...>
//
/// \file xs-native.cpp
@@ -108,10 +108,14 @@
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;
}
@@ -219,7 +223,7 @@
char* _buffer;
char* _wptr;
size_t _len;
- std::string _buffer_str; // UF-8 encoded
+ std::string _buffer_str; // UTF-8 encoded
};
bool XMLReaderBase::parse()
@@ -381,7 +385,7 @@
buffer.reset();
}
- return true;
+ return true; //TODO return false on invalid XML
}
int XMLReaderBase::eat_endl()
Modified: trunk/xmlstorage/xs-xerces.cpp
===================================================================
--- trunk/xmlstorage/xs-xerces.cpp 2007-10-28 10:28:31 UTC (rev 34)
+++ trunk/xmlstorage/xs-xerces.cpp 2007-10-28 14:50:00 UTC (rev 35)
@@ -1,6 +1,6 @@
//
- // XML storage classes Version 1.1
+ // XML storage C++ classes version 1.2
//
// Copyright (c) 2006 Martin Fuchs <mar...@gm...>
//
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|