mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 10:04:49 +00:00
- XMLChildrenFilter iterator
- correctly encode special characters while writing XML strings - MIT license for XmlStorage classes svn path=/trunk/; revision=8890
This commit is contained in:
parent
287b32c870
commit
bf1b24c1fb
6 changed files with 437 additions and 161 deletions
|
@ -3,7 +3,7 @@
|
||||||
<tr>
|
<tr>
|
||||||
<td><address style="align: right;"><small>
|
<td><address style="align: right;"><small>
|
||||||
ROS Explorer Source Code Documentation
|
ROS Explorer Source Code Documentation
|
||||||
<br>generated on 22.03.2004 by <a href="http://www.doxygen.org/index.html">
|
<br>generated on 27.03.2004 by <a href="http://www.doxygen.org/index.html">
|
||||||
<img src="doxygen.png" alt="doxygen" align="middle" border=0>
|
<img src="doxygen.png" alt="doxygen" align="middle" border=0>
|
||||||
</small></address>
|
</small></address>
|
||||||
</td>
|
</td>
|
||||||
|
|
|
@ -28,6 +28,8 @@
|
||||||
|
|
||||||
#include "utility/xmlstorage.h"
|
#include "utility/xmlstorage.h"
|
||||||
|
|
||||||
|
using namespace XMLStorage;
|
||||||
|
|
||||||
|
|
||||||
/// management of file types
|
/// management of file types
|
||||||
struct FileTypeInfo {
|
struct FileTypeInfo {
|
||||||
|
|
|
@ -195,11 +195,10 @@ void NotifyArea::read_config()
|
||||||
|
|
||||||
if (pos.go_down("explorer-cfg")) {
|
if (pos.go_down("explorer-cfg")) {
|
||||||
if (pos.go_down("notify-icons")) {
|
if (pos.go_down("notify-icons")) {
|
||||||
const XMLNode::Children& children = pos->get_children();
|
XMLChildrenFilter icons(pos, "icon");
|
||||||
|
|
||||||
for(XMLNode::Children::const_iterator it=children.begin(); it!=children.end(); ++it) {
|
for(XMLChildrenFilter::iterator it=icons.begin(); it!=icons.end(); ++it) {
|
||||||
const XMLNode& node = **it;
|
const XMLNode& node = **it;
|
||||||
assert(node==TEXT("icon"));
|
|
||||||
|
|
||||||
NotifyIconConfig cfg;
|
NotifyIconConfig cfg;
|
||||||
|
|
||||||
|
|
|
@ -772,38 +772,6 @@ struct String
|
||||||
operator wstring() const {WCHAR b[BUFFER_LEN]; return wstring(b, MultiByteToWideChar(CP_ACP, 0, c_str(), -1, b, BUFFER_LEN)-1);}
|
operator wstring() const {WCHAR b[BUFFER_LEN]; return wstring(b, MultiByteToWideChar(CP_ACP, 0, c_str(), -1, b, BUFFER_LEN)-1);}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void assign_utf8(const char* str)
|
|
||||||
{
|
|
||||||
TCHAR buffer[BUFFER_LEN];
|
|
||||||
|
|
||||||
#ifdef UNICODE
|
|
||||||
int l = MultiByteToWideChar(CP_UTF8, 0, str, -1, buffer, BUFFER_LEN) - 1;
|
|
||||||
#else
|
|
||||||
WCHAR wbuffer[BUFFER_LEN];
|
|
||||||
|
|
||||||
int l = MultiByteToWideChar(CP_UTF8, 0, str, -1, wbuffer, BUFFER_LEN) - 1;
|
|
||||||
l = WideCharToMultiByte(CP_ACP, 0, wbuffer, l, buffer, BUFFER_LEN, 0, 0);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
assign(buffer, l);
|
|
||||||
}
|
|
||||||
|
|
||||||
string get_utf8() const
|
|
||||||
{
|
|
||||||
char buffer[BUFFER_LEN];
|
|
||||||
|
|
||||||
#ifdef UNICODE
|
|
||||||
int l = WideCharToMultiByte(CP_UTF8, 0, c_str(), length(), buffer, BUFFER_LEN, 0, 0);
|
|
||||||
#else
|
|
||||||
WCHAR wbuffer[BUFFER_LEN];
|
|
||||||
|
|
||||||
int l = MultiByteToWideChar(CP_ACP, 0, c_str(), length(), wbuffer, BUFFER_LEN);
|
|
||||||
l = WideCharToMultiByte(CP_UTF8, 0, wbuffer, l, buffer, BUFFER_LEN, 0, 0);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return string(buffer, l);
|
|
||||||
}
|
|
||||||
|
|
||||||
String& printf(LPCTSTR fmt, ...)
|
String& printf(LPCTSTR fmt, ...)
|
||||||
{
|
{
|
||||||
va_list l;
|
va_list l;
|
||||||
|
@ -847,6 +815,8 @@ struct String
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define _STRING_DEFINED
|
||||||
|
|
||||||
|
|
||||||
struct FmtString : public String
|
struct FmtString : public String
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,50 +1,47 @@
|
||||||
/*
|
|
||||||
* Copyright 2004 Martin Fuchs
|
|
||||||
*
|
|
||||||
* This library is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
|
||||||
* License as published by the Free Software Foundation; either
|
|
||||||
* version 2.1 of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This library is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
|
||||||
* License along with this library; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// XML storage classes
|
// XML storage classes
|
||||||
//
|
//
|
||||||
// xmlstorage.cpp
|
// xmlstorage.cpp
|
||||||
//
|
//
|
||||||
// Martin Fuchs, 22.03.2004
|
// Copyright (c) 2004, Martin Fuchs <martin-fuchs@gmx.net>
|
||||||
//
|
//
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
* Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in
|
||||||
|
the documentation and/or other materials provided with the
|
||||||
|
distribution.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||||
|
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
#include "utility.h"
|
#include "utility.h"
|
||||||
|
|
||||||
#include "xmlstorage.h"
|
#include "xmlstorage.h"
|
||||||
|
|
||||||
|
|
||||||
void xml_test() //@@
|
namespace XMLStorage {
|
||||||
{
|
|
||||||
XMLDoc doc;
|
|
||||||
|
|
||||||
doc.read("explorer-cfg.xml");
|
|
||||||
doc.write("out.xml");
|
|
||||||
|
|
||||||
XMLPos pos(&doc);
|
|
||||||
|
|
||||||
if (pos.go("\\explorer-cfg\\startmenu")) {
|
|
||||||
|
|
||||||
pos.back();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// move X-Path like to position in XML tree
|
/// move X-Path like to position in XML tree
|
||||||
|
@ -107,3 +104,6 @@ void XMLCALL XMLReader::XML_DefaultHandler(void* userData, const XML_Char* s, in
|
||||||
else
|
else
|
||||||
pThis->_pos->append_trailing(s, len);
|
pThis->_pos->append_trailing(s, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace XMLStorage
|
||||||
|
|
|
@ -1,42 +1,234 @@
|
||||||
/*
|
|
||||||
* Copyright 2004 Martin Fuchs
|
|
||||||
*
|
|
||||||
* This library is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
|
||||||
* License as published by the Free Software Foundation; either
|
|
||||||
* version 2.1 of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This library is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
|
||||||
* License along with this library; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// XML storage classes
|
// XML storage classes
|
||||||
//
|
//
|
||||||
// xmlstorage.h
|
// xmlstorage.h
|
||||||
//
|
//
|
||||||
// Martin Fuchs, 22.03.2004
|
// Copyright (c) 2004, Martin Fuchs <martin-fuchs@gmx.net>
|
||||||
//
|
//
|
||||||
|
|
||||||
|
|
||||||
#include "expat.h"
|
/*
|
||||||
|
|
||||||
#include <fstream>
|
All rights reserved.
|
||||||
#include <sstream>
|
|
||||||
#include <stack>
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
* Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in
|
||||||
|
the documentation and/or other materials provided with the
|
||||||
|
distribution.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||||
|
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "expat.h"
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#pragma comment(lib, "libexpat.lib")
|
#pragma comment(lib, "libexpat.lib")
|
||||||
|
#pragma warning(disable: 4786)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#include <windows.h> // for LPCTSTR
|
||||||
|
|
||||||
|
#ifdef UNICODE
|
||||||
|
#define _UNICODE
|
||||||
|
#endif
|
||||||
|
#include <tchar.h>
|
||||||
|
|
||||||
|
#include <fstream>
|
||||||
|
#include <sstream>
|
||||||
|
#include <string>
|
||||||
|
#include <stack>
|
||||||
|
#include <list>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef BUFFER_LEN
|
||||||
|
#define BUFFER_LEN 2048
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
namespace XMLStorage {
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef _STRING_DEFINED
|
||||||
|
|
||||||
|
/// string class for TCHAR strings
|
||||||
|
|
||||||
|
struct String
|
||||||
|
#ifdef UNICODE
|
||||||
|
: public std::wstring
|
||||||
|
#else
|
||||||
|
: public std::string
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
#ifdef UNICODE
|
||||||
|
typedef std::wstring super;
|
||||||
|
#else
|
||||||
|
typedef std::string super;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
String() {}
|
||||||
|
String(LPCTSTR s) {if (s) super::assign(s);}
|
||||||
|
String(LPCTSTR s, int l) : super(s, l) {}
|
||||||
|
String(const super& other) : super(other) {}
|
||||||
|
String(const String& other) : super(other) {}
|
||||||
|
|
||||||
|
#ifdef UNICODE
|
||||||
|
String(LPCSTR s) {assign(s);}
|
||||||
|
String(LPCSTR s, int l) {assign(s, l);}
|
||||||
|
String(const std::string& other) {assign(other.c_str());}
|
||||||
|
String& operator=(LPCSTR s) {assign(s); return *this;}
|
||||||
|
void assign(LPCSTR s) {if (s) {TCHAR b[BUFFER_LEN]; super::assign(b, MultiByteToWideChar(CP_ACP, 0, s, -1, b, BUFFER_LEN)-1);} else erase();}
|
||||||
|
void assign(LPCSTR s, int l) {if (s) {TCHAR b[BUFFER_LEN]; super::assign(b, MultiByteToWideChar(CP_ACP, 0, s, l, b, BUFFER_LEN));} else erase();}
|
||||||
|
#else
|
||||||
|
String(LPCWSTR s) {assign(s);}
|
||||||
|
String(LPCWSTR s, int l) {assign(s, l);}
|
||||||
|
String(const std::wstring& other) {assign(other.c_str());}
|
||||||
|
String& operator=(LPCWSTR s) {assign(s); return *this;}
|
||||||
|
void assign(LPCWSTR s) {if (s) {char b[BUFFER_LEN]; super::assign(b, WideCharToMultiByte(CP_ACP, 0, s, -1, b, BUFFER_LEN, 0, 0)-1);} else erase();}
|
||||||
|
void assign(LPCWSTR s, int l) {if (s) {char b[BUFFER_LEN]; super::assign(b, WideCharToMultiByte(CP_ACP, 0, s, l, b, BUFFER_LEN, 0, 0));} else erase();}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
String& operator=(LPCTSTR s) {if (s) super::assign(s); else erase(); return *this;}
|
||||||
|
String& operator=(const super& s) {super::assign(s); return *this;}
|
||||||
|
void assign(LPCTSTR s) {super::assign(s);}
|
||||||
|
void assign(LPCTSTR s, int l) {super::assign(s, l);}
|
||||||
|
|
||||||
|
operator LPCTSTR() const {return c_str();}
|
||||||
|
|
||||||
|
#ifdef UNICODE
|
||||||
|
operator std::string() const {char b[BUFFER_LEN]; return std::string(b, WideCharToMultiByte(CP_ACP, 0, c_str(), -1, b, BUFFER_LEN, 0, 0)-1);}
|
||||||
|
#else
|
||||||
|
operator std::wstring() const {WCHAR b[BUFFER_LEN]; return std::wstring(b, MultiByteToWideChar(CP_ACP, 0, c_str(), -1, b, BUFFER_LEN)-1);}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
String& printf(LPCTSTR fmt, ...)
|
||||||
|
{
|
||||||
|
va_list l;
|
||||||
|
TCHAR b[BUFFER_LEN];
|
||||||
|
|
||||||
|
va_start(l, fmt);
|
||||||
|
super::assign(b, _vstprintf(b, fmt, l));
|
||||||
|
va_end(l);
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
String& vprintf(LPCTSTR fmt, va_list l)
|
||||||
|
{
|
||||||
|
TCHAR b[BUFFER_LEN];
|
||||||
|
|
||||||
|
super::assign(b, _vstprintf(b, fmt, l));
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
String& appendf(LPCTSTR fmt, ...)
|
||||||
|
{
|
||||||
|
va_list l;
|
||||||
|
TCHAR b[BUFFER_LEN];
|
||||||
|
|
||||||
|
va_start(l, fmt);
|
||||||
|
super::append(b, _vstprintf(b, fmt, l));
|
||||||
|
va_end(l);
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
String& vappendf(LPCTSTR fmt, va_list l)
|
||||||
|
{
|
||||||
|
TCHAR b[BUFFER_LEN];
|
||||||
|
|
||||||
|
super::append(b, _vstprintf(b, fmt, l));
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
inline void assign_utf8(String& s, const char* str)
|
||||||
|
{
|
||||||
|
TCHAR buffer[BUFFER_LEN];
|
||||||
|
|
||||||
|
#ifdef UNICODE
|
||||||
|
int l = MultiByteToWideChar(CP_UTF8, 0, str, -1, buffer, BUFFER_LEN) - 1;
|
||||||
|
#else
|
||||||
|
WCHAR wbuffer[BUFFER_LEN];
|
||||||
|
|
||||||
|
int l = MultiByteToWideChar(CP_UTF8, 0, str, -1, wbuffer, BUFFER_LEN) - 1;
|
||||||
|
l = WideCharToMultiByte(CP_ACP, 0, wbuffer, l, buffer, BUFFER_LEN, 0, 0);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
s.assign(buffer, l);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline std::string get_utf8(LPCTSTR s, int l)
|
||||||
|
{
|
||||||
|
char buffer[BUFFER_LEN];
|
||||||
|
|
||||||
|
#ifdef UNICODE
|
||||||
|
l = WideCharToMultiByte(CP_UTF8, 0, s, l, buffer, BUFFER_LEN, 0, 0);
|
||||||
|
#else
|
||||||
|
WCHAR wbuffer[BUFFER_LEN];
|
||||||
|
|
||||||
|
l = MultiByteToWideChar(CP_ACP, 0, s, l, wbuffer, BUFFER_LEN);
|
||||||
|
l = WideCharToMultiByte(CP_UTF8, 0, wbuffer, l, buffer, BUFFER_LEN, 0, 0);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return std::string(buffer, l);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline std::string get_utf8(const String& s)
|
||||||
|
{
|
||||||
|
return get_utf8(s.c_str(), s.length());
|
||||||
|
}
|
||||||
|
|
||||||
|
inline std::string XMLString(const String& s)
|
||||||
|
{
|
||||||
|
TCHAR buffer[BUFFER_LEN];
|
||||||
|
LPTSTR o = buffer;
|
||||||
|
|
||||||
|
for(LPCTSTR p=s; *p; ++p)
|
||||||
|
switch(*p) {
|
||||||
|
case '&':
|
||||||
|
*o++ = '&'; *o++ = 'a'; *o++ = 'm'; *o++ = 'p'; *o++ = ';';
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '<':
|
||||||
|
*o++ = '&'; *o++ = 'l'; *o++ = 't'; *o++ = ';';
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '>':
|
||||||
|
*o++ = '&'; *o++ = 'g'; *o++ = 't'; *o++ = ';';
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
*o++ = *p;
|
||||||
|
}
|
||||||
|
|
||||||
|
return get_utf8(buffer, o-buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// write XML files with 2 spaces indenting
|
// write XML files with 2 spaces indenting
|
||||||
#define XML_INDENT_SPACE " "
|
#define XML_INDENT_SPACE " "
|
||||||
|
|
||||||
|
@ -51,7 +243,7 @@ struct String_from_XML_Char : public String
|
||||||
{
|
{
|
||||||
String_from_XML_Char(const XML_Char* str)
|
String_from_XML_Char(const XML_Char* str)
|
||||||
{
|
{
|
||||||
assign_utf8(str);
|
assign_utf8(*this, str);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -61,8 +253,12 @@ struct String_from_XML_Char : public String
|
||||||
/// in memory representation of an XML node
|
/// in memory representation of an XML node
|
||||||
struct XMLNode : public String
|
struct XMLNode : public String
|
||||||
{
|
{
|
||||||
typedef map<String, String> AttributeMap;
|
typedef std::map<String, String> AttributeMap;
|
||||||
typedef list<XMLNode*> Children;
|
typedef std::list<XMLNode*> Children;
|
||||||
|
|
||||||
|
// access to protected class members for XMLPos anbd XMLReader
|
||||||
|
friend struct XMLPos;
|
||||||
|
friend struct XMLReader;
|
||||||
|
|
||||||
XMLNode(const String& name)
|
XMLNode(const String& name)
|
||||||
: String(name)
|
: String(name)
|
||||||
|
@ -105,6 +301,68 @@ struct XMLNode : public String
|
||||||
return _children;
|
return _children;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Children& get_children()
|
||||||
|
{
|
||||||
|
return _children;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// write XML stream preserving original white space and comments
|
||||||
|
std::ostream& write(std::ostream& out)
|
||||||
|
{
|
||||||
|
out << "<" << XMLString(*this);
|
||||||
|
|
||||||
|
for(AttributeMap::const_iterator it=_attributes.begin(); it!=_attributes.end(); ++it)
|
||||||
|
out << " " << XMLString(it->first) << "=\"" << XMLString(it->second) << "\"";
|
||||||
|
|
||||||
|
if (!_children.empty() || !_content.empty()) {
|
||||||
|
out << ">" << _content;
|
||||||
|
|
||||||
|
for(Children::const_iterator it=_children.begin(); it!=_children.end(); ++it)
|
||||||
|
(*it)->write(out);
|
||||||
|
|
||||||
|
out << "</" << XMLString(*this) << ">" << _trailing;
|
||||||
|
} else {
|
||||||
|
out << "/>" << _trailing;
|
||||||
|
}
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// print write node to stream without preserving original white space
|
||||||
|
std::ostream& write_formating(std::ostream& out, int indent=0)
|
||||||
|
{
|
||||||
|
for(int i=indent; i--; )
|
||||||
|
out << XML_INDENT_SPACE;
|
||||||
|
|
||||||
|
out << "<" << XMLString(*this);
|
||||||
|
|
||||||
|
for(AttributeMap::const_iterator it=_attributes.begin(); it!=_attributes.end(); ++it)
|
||||||
|
out << " " << XMLString(it->first) << "=\"" << XMLString(it->second) << "\"";
|
||||||
|
|
||||||
|
if (!_children.empty()) {
|
||||||
|
out << ">\n";
|
||||||
|
|
||||||
|
for(Children::const_iterator it=_children.begin(); it!=_children.end(); ++it)
|
||||||
|
(*it)->write_formating(out, indent+1);
|
||||||
|
|
||||||
|
for(int i=indent; i--; )
|
||||||
|
out << XML_INDENT_SPACE;
|
||||||
|
|
||||||
|
out << "</" << XMLString(*this) << ">\n";
|
||||||
|
} else {
|
||||||
|
out << "/>\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Children _children;
|
||||||
|
AttributeMap _attributes;
|
||||||
|
|
||||||
|
std::string _content;
|
||||||
|
std::string _trailing;
|
||||||
|
|
||||||
XMLNode* get_first_child() const
|
XMLNode* get_first_child() const
|
||||||
{
|
{
|
||||||
if (!_children.empty())
|
if (!_children.empty())
|
||||||
|
@ -149,63 +407,104 @@ struct XMLNode : public String
|
||||||
else
|
else
|
||||||
_children.back()->_trailing.append(s, l);
|
_children.back()->_trailing.append(s, l);
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/// write XML stream preserving original white space and comments
|
|
||||||
ostream& write(ostream& out)
|
/// iterator access to children nodes with name filtering
|
||||||
|
struct XMLChildrenFilter
|
||||||
|
{
|
||||||
|
XMLChildrenFilter(XMLNode::Children& children, const String& name)
|
||||||
|
: _begin(children.begin(), children.end(), name),
|
||||||
|
_end(children.end(), children.end(), name)
|
||||||
{
|
{
|
||||||
out << "<" << get_utf8();
|
|
||||||
|
|
||||||
for(AttributeMap::const_iterator it=_attributes.begin(); it!=_attributes.end(); ++it)
|
|
||||||
out << " " << it->first.get_utf8() << "=\"" << it->second.get_utf8() << "\"";
|
|
||||||
|
|
||||||
if (!_children.empty() || !_content.empty()) {
|
|
||||||
out << ">" << _content;
|
|
||||||
|
|
||||||
for(Children::const_iterator it=_children.begin(); it!=_children.end(); ++it)
|
|
||||||
(*it)->write(out);
|
|
||||||
|
|
||||||
out << "</" << get_utf8() << ">" << _trailing;
|
|
||||||
} else {
|
|
||||||
out << "/>" << _trailing;
|
|
||||||
}
|
|
||||||
|
|
||||||
return out;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// print write node to stream without preserving original white space
|
XMLChildrenFilter(XMLNode* node, const String& name)
|
||||||
ostream& write_formating(ostream& out, int indent=0)
|
: _begin(node->get_children().begin(), node->get_children().end(), name),
|
||||||
|
_end(node->get_children().end(), node->get_children().end(), name)
|
||||||
{
|
{
|
||||||
for(int i=indent; i--; )
|
}
|
||||||
out << XML_INDENT_SPACE;
|
|
||||||
|
|
||||||
out << "<" << get_utf8();
|
struct iterator
|
||||||
|
{
|
||||||
|
typedef XMLNode::Children::iterator BaseIterator;
|
||||||
|
|
||||||
for(AttributeMap::const_iterator it=_attributes.begin(); it!=_attributes.end(); ++it)
|
iterator(BaseIterator begin, BaseIterator end, const String& filter_name)
|
||||||
out << " " << it->first.get_utf8() << "=\"" << it->second.get_utf8() << "\"";
|
: _cur(begin),
|
||||||
|
_end(end),
|
||||||
if (!_children.empty()) {
|
_filter_name(filter_name)
|
||||||
out << ">\n";
|
{
|
||||||
|
search_next();
|
||||||
for(Children::const_iterator it=_children.begin(); it!=_children.end(); ++it)
|
|
||||||
(*it)->write_formating(out, indent+1);
|
|
||||||
|
|
||||||
for(int i=indent; i--; )
|
|
||||||
out << XML_INDENT_SPACE;
|
|
||||||
|
|
||||||
out << "</" << get_utf8() << ">\n";
|
|
||||||
} else {
|
|
||||||
out << "/>\n";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return out;
|
operator BaseIterator()
|
||||||
|
{
|
||||||
|
return _cur;
|
||||||
|
}
|
||||||
|
|
||||||
|
const XMLNode* operator*() const
|
||||||
|
{
|
||||||
|
return *_cur;
|
||||||
|
}
|
||||||
|
|
||||||
|
XMLNode* operator*()
|
||||||
|
{
|
||||||
|
return *_cur;
|
||||||
|
}
|
||||||
|
|
||||||
|
iterator& operator++()
|
||||||
|
{
|
||||||
|
++_cur;
|
||||||
|
search_next();
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
iterator operator++(int)
|
||||||
|
{
|
||||||
|
iterator ret = *this;
|
||||||
|
|
||||||
|
++_cur;
|
||||||
|
search_next();
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator==(const BaseIterator& other) const
|
||||||
|
{
|
||||||
|
return _cur == other;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator!=(const BaseIterator& other) const
|
||||||
|
{
|
||||||
|
return _cur != other;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
BaseIterator _cur;
|
||||||
|
BaseIterator _end;
|
||||||
|
String _filter_name;
|
||||||
|
|
||||||
|
void search_next()
|
||||||
|
{
|
||||||
|
while(_cur!=_end && **_cur!=_filter_name)
|
||||||
|
++_cur;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
iterator begin()
|
||||||
|
{
|
||||||
|
return _begin;
|
||||||
|
}
|
||||||
|
|
||||||
|
iterator end()
|
||||||
|
{
|
||||||
|
return _end;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Children _children;
|
iterator _begin;
|
||||||
AttributeMap _attributes;
|
iterator _end;
|
||||||
|
|
||||||
string _content;
|
|
||||||
string _trailing;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -219,11 +518,14 @@ struct XMLPos
|
||||||
}
|
}
|
||||||
|
|
||||||
/// access to current node
|
/// access to current node
|
||||||
XMLNode* operator->() {return _cur;}
|
operator XMLNode*() {return _cur;}
|
||||||
const XMLNode* operator->() const {return _cur;}
|
operator const XMLNode*() const {return _cur;}
|
||||||
|
|
||||||
|
const XMLNode* operator->() const {return _cur;}
|
||||||
|
XMLNode* operator->() {return _cur;}
|
||||||
|
|
||||||
XMLNode& operator*() {return *_cur;}
|
|
||||||
const XMLNode& operator*() const {return *_cur;}
|
const XMLNode& operator*() const {return *_cur;}
|
||||||
|
XMLNode& operator*() {return *_cur;}
|
||||||
|
|
||||||
/// attribute access
|
/// attribute access
|
||||||
String& operator[](const String& attr_name) {return (*_cur)[attr_name];}
|
String& operator[](const String& attr_name) {return (*_cur)[attr_name];}
|
||||||
|
@ -301,7 +603,7 @@ struct XMLPos
|
||||||
protected:
|
protected:
|
||||||
XMLNode* _root;
|
XMLNode* _root;
|
||||||
XMLNode* _cur;
|
XMLNode* _cur;
|
||||||
stack<XMLNode*> _stack;
|
std::stack<XMLNode*> _stack;
|
||||||
|
|
||||||
/// go to specified node
|
/// go to specified node
|
||||||
void go_to(XMLNode* child)
|
void go_to(XMLNode* child)
|
||||||
|
@ -336,7 +638,7 @@ struct XMLReader
|
||||||
XML_ParserFree(_parser);
|
XML_ParserFree(_parser);
|
||||||
}
|
}
|
||||||
|
|
||||||
XML_Status read(istream& in)
|
XML_Status read(std::istream& in)
|
||||||
{
|
{
|
||||||
XML_Status status = XML_STATUS_OK;
|
XML_Status status = XML_STATUS_OK;
|
||||||
|
|
||||||
|
@ -359,22 +661,22 @@ struct XMLReader
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
string get_position() const
|
std::string get_position() const
|
||||||
{
|
{
|
||||||
int line = XML_GetCurrentLineNumber(_parser);
|
int line = XML_GetCurrentLineNumber(_parser);
|
||||||
int column = XML_GetCurrentColumnNumber(_parser);
|
int column = XML_GetCurrentColumnNumber(_parser);
|
||||||
|
|
||||||
ostringstream out;
|
std::ostringstream out;
|
||||||
out << "(" << line << ") : [column " << column << "]";
|
out << "(" << line << ") : [column " << column << "]";
|
||||||
|
|
||||||
return out.str();
|
return out.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
string get_error_string() const
|
std::string get_error_string() const
|
||||||
{
|
{
|
||||||
XML_Error error = XML_GetErrorCode(_parser);
|
XML_Error error = XML_GetErrorCode(_parser);
|
||||||
|
|
||||||
ostringstream out;
|
std::ostringstream out;
|
||||||
out << get_position() << " XML parser error #" << error << "\n";
|
out << get_position() << " XML parser error #" << error << "\n";
|
||||||
|
|
||||||
return out.str();
|
return out.str();
|
||||||
|
@ -383,8 +685,8 @@ struct XMLReader
|
||||||
protected:
|
protected:
|
||||||
XMLPos _pos;
|
XMLPos _pos;
|
||||||
XML_Parser _parser;
|
XML_Parser _parser;
|
||||||
string _xml_version;
|
std::string _xml_version;
|
||||||
string _encoding;
|
std::string _encoding;
|
||||||
bool _in_tag;
|
bool _in_tag;
|
||||||
|
|
||||||
static void XMLCALL XML_XmlDeclHandler(void* userData, const XML_Char* version, const XML_Char* encoding, int standalone);
|
static void XMLCALL XML_XmlDeclHandler(void* userData, const XML_Char* version, const XML_Char* encoding, int standalone);
|
||||||
|
@ -401,28 +703,28 @@ struct XMLDoc : public XMLNode
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
XMLDoc(const string& path)
|
XMLDoc(const std::string& path)
|
||||||
: XMLNode("")
|
: XMLNode("")
|
||||||
{
|
{
|
||||||
read(path);
|
read(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
istream& read(istream& in)
|
std::istream& read(std::istream& in)
|
||||||
{
|
{
|
||||||
XMLReader(this).read(in);
|
XMLReader(this).read(in);
|
||||||
|
|
||||||
return in;
|
return in;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool read(const string& path)
|
bool read(const std::string& path)
|
||||||
{
|
{
|
||||||
ifstream in(path.c_str());
|
std::ifstream in(path.c_str());
|
||||||
|
|
||||||
return XMLReader(this).read(in) != XML_STATUS_ERROR;
|
return XMLReader(this).read(in) != XML_STATUS_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// write XML stream preserving previous white space and comments
|
/// write XML stream preserving previous white space and comments
|
||||||
ostream& write(ostream& out, const string& xml_version="1.0", const string& encoding="UTF-8")
|
std::ostream& write(std::ostream& out, const std::string& xml_version="1.0", const std::string& encoding="UTF-8")
|
||||||
{
|
{
|
||||||
out << "<?xml version=\"" << xml_version << "\" encoding=\"" << encoding << "\"?>\n";
|
out << "<?xml version=\"" << xml_version << "\" encoding=\"" << encoding << "\"?>\n";
|
||||||
|
|
||||||
|
@ -433,7 +735,7 @@ struct XMLDoc : public XMLNode
|
||||||
}
|
}
|
||||||
|
|
||||||
/// write XML stream with formating
|
/// write XML stream with formating
|
||||||
ostream& write_formating(ostream& out)
|
std::ostream& write_formating(std::ostream& out)
|
||||||
{
|
{
|
||||||
out << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
|
out << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
|
||||||
|
|
||||||
|
@ -443,17 +745,20 @@ struct XMLDoc : public XMLNode
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
void write(const string& path, const string& xml_version="1.0", const string& encoding="UTF-8")
|
void write(const std::string& path, const std::string& xml_version="1.0", const std::string& encoding="UTF-8")
|
||||||
{
|
{
|
||||||
ofstream out(path.c_str());
|
std::ofstream out(path.c_str());
|
||||||
|
|
||||||
write(out, xml_version);
|
write(out, xml_version);
|
||||||
}
|
}
|
||||||
|
|
||||||
void write_formating(const string& path)
|
void write_formating(const std::string& path)
|
||||||
{
|
{
|
||||||
ofstream out(path.c_str());
|
std::ofstream out(path.c_str());
|
||||||
|
|
||||||
write_formating(out);
|
write_formating(out);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace XMLStorage
|
||||||
|
|
Loading…
Reference in a new issue