//
// XML storage C++ classes version 1.3
//
- // Copyright (c) 2004, 2005, 2006, 2007, 2008 Martin Fuchs <martin-fuchs@gmx.net>
+ // Copyright (c) 2004, 2005, 2006, 2007, 2008, 2009, 2010 Martin Fuchs <martin-fuchs@gmx.net>
//
/// \file xmlstorage.h
#endif
-#if _MSC_VER>=1400
+#if _MSC_VER>=1400 // VS2005 or higher
#ifndef _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES
#define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES 1
#define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_COUNT 1
#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
+#if _MSC_VER==1500
+#pragma comment(lib, "xmlstorage-vc9d")
+#elif _MSC_VER==1400
#pragma comment(lib, "xmlstorage-vc8d")
#else
#pragma comment(lib, "xmlstorage-vc6d")
#endif
#else
#ifdef _DLL
-#if _MSC_VER==1400
+#if _MSC_VER==1500
+#pragma comment(lib, "xmlstorage-vc9")
+#elif _MSC_VER==1400
#pragma comment(lib, "xmlstorage-vc8")
#else
#pragma comment(lib, "xmlstorage-vc6")
#endif
#elif defined(_MT)
-#if _MSC_VER==1400
+#if _MSC_VER==1500
+#pragma comment(lib, "xmlstorage-vc9t")
+#elif _MSC_VER==1400
#pragma comment(lib, "xmlstorage-vc8t")
#else
#pragma comment(lib, "xmlstorage-vc6t")
#endif
#else
- // -ML is no more supported by VS2005.
+ // -ML is no more supported since VS2005.
#pragma comment(lib, "xmlstorage-vc6l")
#endif
#endif
#include <stdio.h> // vsnprintf(), snprintf()
#endif
-#else
+#else // _WIN32
#include <wchar.h>
+#include <stdlib.h>
+#include <string.h> // strcasecmp()
#include <stdarg.h>
typedef char CHAR;
#define _tcsicmp strcasecmp
#define strnicmp strncasecmp
#define _tcsnicmp strncasecmp
-#endif
+#endif // UNICODE
-#endif
+#endif // _WIN32
#ifdef __BORLANDC__
#define _stricmp stricmp
#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(const std::string& s) {assign(s.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(const std::wstring& ws) {assign(ws.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();}
#endif
#endif // _WIN32
+#ifdef __ISSD_H
+// XS_String(const _ISSD RString& s) {assign(s.c_str());}
+// void assign(const _ISSD RString& s) {assign(s.c_str());}
+ XS_String& operator=(const _ISSD RString& s) {assign(s); return *this;}
+#endif
+
#ifdef XS_STRING_UTF8
void assign(const XS_String& s) {assign(s.c_str());}
#endif
extern const XS_String XS_VALUE;
extern const XS_String XS_PROPERTY;
+#define CDATA_START "<![CDATA["
+#define CDATA_END "]]>"
+
#ifndef XS_STRING_UTF8
#endif // XS_STRING_UTF8
extern std::string EncodeXMLString(const XS_String& str, bool cdata=false);
-extern XS_String DecodeXMLString(const XS_String& str);
+extern XS_String DecodeXMLString(const std::string& str);
#ifdef __GNUC__
{
FileHolder(LPCTSTR path, LPCTSTR mode)
{
-#ifdef __STDC_WANT_SECURE_LIB__ // secure CRT functions using VS 2005
+//@@ _MS_VER: temporarily needed for the ReactOS build environment
+#if defined(__STDC_WANT_SECURE_LIB__) && defined(_MS_VER) // secure CRT functions using VS 2005
if (_tfopen_s(&_pfile, path, mode) != 0)
_pfile = NULL;
#else
_buf(_pfile)
#endif
{
+ if (!_pfile)
+ setstate(badbit);
}
protected:
_buf(_pfile)
#endif
{
+ if (!_pfile)
+ setstate(badbit);
}
~tofstream()
struct XPath : std::list<XPathElement>
{
+ XPath() : _absolute(false) {}
XPath(const char* path) {init(path);}
XPath(const std::string path) {init(path.c_str());}
friend struct XPathElement;
XMLNode(const XS_String& name)
- : XS_String(name)
+ : XS_String(name),
+ _cdata_content(false)
{
}
XMLNode(const XS_String& name, const std::string& leading)
: XS_String(name),
- _leading(leading)
+ _leading(leading),
+ _cdata_content(false)
{
}
_leading(other._leading),
_content(other._content),
_end_leading(other._end_leading),
- _trailing(other._trailing)
+ _trailing(other._trailing),
#ifdef XMLNODE_LOCATION
- , _location(other._location)
+ _location(other._location),
#endif
+ _cdata_content(false)
{
for(Children::const_iterator it=other._children.begin(); it!=other._children.end(); ++it)
_children.push_back(new XMLNode(**it));
_leading(other._leading),
_content(other._content),
_end_leading(other._end_leading),
- _trailing(other._trailing)
+ _trailing(other._trailing),
#ifdef XMLNODE_LOCATION
- , _location(other._location)
+ _location(other._location),
#endif
+ _cdata_content(false)
{
// assert(copy_no_children==COPY_NOCHILDREN);
}
{
Children::iterator it, next=_children.begin();
- while((it=next++)!=_children.end())
+ while((it=next++) != _children.end())
if (**it == name)
_children.erase(it);
}
return _attributes;
}
+ /// read element node content
XS_String get_content() const
{
-#ifdef XS_STRING_UTF8
- const XS_String& ret = _content;
-#else
- XS_String ret;
- assign_utf8(ret, _content.c_str(), _content.length());
-#endif
+ return DecodeXMLString(_content);
+ }
+
+ /// read content of a subnode specified by an XPath expression
+ XS_String get_sub_content(const XPath& xpath) const
+ {
+ const XMLNode* node = find_relative(xpath);
- return DecodeXMLString(ret.c_str());
+ if (node)
+ return node->get_content();
+ else
+ return XS_EMPTY_STR;
}
+ /// set element node content
void set_content(const XS_String& s, bool cdata=false)
{
_content.assign(EncodeXMLString(s.c_str(), cdata));
}
+ /// set content of a subnode specified by an XPath expression
+ bool set_sub_content(const XPath& xpath, const XS_String& s, bool cdata=false)
+ {
+ XMLNode* node = create_relative(xpath);
+
+ if (node) {
+ node->set_content(s, cdata);
+ return true;
+ } else
+ return false;
+ }
+
#ifdef XMLNODE_LOCATION
const XMLLocation& get_location() const {return _location;}
#endif
break;
case FORMAT_ORIGINAL:
- write_worker(out);
+ original_write_worker(out);
break;
- default: // FORMAT_SMART
+ default: // FORMAT_SMART
smart_write_worker(out, format, indent);
}
/// copy matching tree nodes using the given XPath filter expression
bool filter(const XPath& xpath, XMLNode& target) const;
+ /// XPath find function (const)
+ const XMLNode* find_relative(const XPath& xpath) const;
+
+ /// XPath find function
+ XMLNode* find_relative(const XPath& xpath);
+
+ XMLNode* get_first_child() const
+ {
+ if (!_children.empty())
+ return _children.front();
+ else
+ return NULL;
+ }
+
protected:
Children _children;
AttributeMap _attributes;
XMLLocation _location;
#endif
- XMLNode* get_first_child() const
- {
- if (!_children.empty())
- return _children.front();
- else
- return NULL;
- }
-
- /// XPath find function (const)
- const XMLNode* find_relative(const XPath& xpath) const;
-
- /// XPath find function
- XMLNode* find_relative(const XPath& xpath);
+ bool _cdata_content;
/// relative XPath create function
XMLNode* create_relative(const XPath& xpath);
/// create a new node tree using the given XPath filter expression
XMLNode* filter(XPath::const_iterator from, const XPath::const_iterator& to) const;
- void write_worker(std::ostream& out) const;
+ void original_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;
/// 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];}
+ const XS_String& operator[](const XS_String& attr_name) const {return (*_cur)[attr_name];}
/// insert children when building tree
void add_down(XMLNode* child)
return false;
}
+ /// iterate to the next matching child
+ bool iterate(const XS_String& child_name, size_t& cnt)
+ {
+ XMLNode* node = XPathElement(child_name, cnt).find(_cur);
+
+ if (node) {
+ go_to(node);
+ ++cnt;
+ return true;
+ } else
+ return false;
+ }
+
/// move to the position defined by xpath in XML tree
bool go(const XPath& xpath);
add_down(new XMLNode(name));
}
+ /// create node with string content
+ void create_node_content(const XS_String& node_name, const XS_String& content)
+ {
+ XMLNode* pNode = new XMLNode(node_name);
+ pNode->set_content(content);
+ _cur->add_child(pNode);
+ }
+
/// create node if not already existing and move to it
void smart_create(const XS_String& child_name)
{
{set_property(key, XS_String(value), name);}
protected:
+ friend struct const_XMLPos; // access to _root
+
XMLNode* _root;
XMLNode* _cur;
std::stack<XMLNode*> _stack;
: _root(other._root),
_cur(other._cur)
{ // don't copy _stack
+ }
+
+ const_XMLPos(const XMLPos& other)
+ : _root(other._root),
+ _cur(other._cur)
+ { // don't copy _stack
}
/// access to current node
/// index operator attribute access
template<typename T> XS_String get(const T& attr_name) const {return _cur->get(attr_name);}
+ XS_String operator[](const XS_String& attr_name) const {return _cur->get(attr_name);}
/// go back to previous position
bool back()
return false;
}
+ /// iterate to the next matching child
+ bool iterate(const XS_String& child_name, size_t& cnt)
+ {
+ const XMLNode* node = XPathElement(child_name, cnt).const_find(_cur);
+
+ if (node) {
+ go_to(node);
+ ++cnt;
+ return true;
+ } else
+ return false;
+ }
+
/// move to the position defined by xpath in XML tree
bool go(const XPath& xpath);
return read(reader, system_id);
}
+ bool read_buffer(const std::string& in, const std::string& system_id=std::string())
+ {
+ return read_buffer(in.c_str(), in.length(), system_id);
+ }
+
#else // XS_USE_XERCES
bool read_file(LPCTSTR path)
{
tifstream in(path);
+ if (!in.good())
+ return false;
+
XMLReader reader(this, in);
#if defined(_STRING_DEFINED) && !defined(XS_STRING_UTF8)
bool read_buffer(const char* buffer, size_t len, const std::string& system_id=std::string())
{
- std::istringstream in(std::string(buffer, len));
+ return read_buffer(std::string(buffer, len), system_id);
+ }
- return read(in, system_id);
+ bool read_buffer(const std::string& buffer, const std::string& system_id=std::string())
+ {
+ std::istringstream istr(buffer);
+
+ return read_stream(istr, system_id);
}
- bool read(std::istream& in, const std::string& system_id=std::string())
+ bool read_stream(std::istream& in, const std::string& system_id=std::string())
{
XMLReader reader(this, in);
_stack.top()._content = EncodeXMLString(s.c_str(), cdata);
}
+ /// create node with string content
+ void create_node_content(const XS_String& node_name, const XS_String& content)
+ {
+ create(node_name);
+ set_content(content);
+ back();
+ }
+
// public for access in StackEntry
enum WRITESTATE {
NOTHING, /*PRE,*/ ATTRIBUTES, PRE_CLOSED, /*CONTENT,*/ POST
protected:
tofstream* _pofstream;
std::ostream& _out;
- const XMLFormat&_format;
+ XMLFormat _format;
typedef XMLNode::AttributeMap AttrMap;