Author: martinf
Date: Tue Aug 1 03:23:19 2006
New Revision: 23398
URL:
http://svn.reactos.org/svn/reactos?rev=23398&view=rev
Log:
IBrowser: update XMLStorage library and remove Expat dependency
Added:
trunk/reactos/base/applications/ibrowser/utility/xs-native.cpp (with props)
Removed:
trunk/reactos/base/applications/ibrowser/expat-license.txt
Modified:
trunk/reactos/base/applications/ibrowser/Makefile-MinGW
trunk/reactos/base/applications/ibrowser/Makefile-precomp
trunk/reactos/base/applications/ibrowser/favorites.cpp
trunk/reactos/base/applications/ibrowser/ibrowser.dsp
trunk/reactos/base/applications/ibrowser/ibrowser.rbuild
trunk/reactos/base/applications/ibrowser/make_ibrowser.dsp
trunk/reactos/base/applications/ibrowser/utility/xmlstorage.cpp
trunk/reactos/base/applications/ibrowser/utility/xmlstorage.h
Modified: trunk/reactos/base/applications/ibrowser/Makefile-MinGW
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/ibrowser…
==============================================================================
--- trunk/reactos/base/applications/ibrowser/Makefile-MinGW (original)
+++ trunk/reactos/base/applications/ibrowser/Makefile-MinGW Tue Aug 1 03:23:19 2006
@@ -50,13 +50,14 @@
webchild.o \
mainframe.o \
favorites.o \
+ xs-native.o \
xmlstorage.o
LIBS = gdi32 comctl32 shell32 ole32 uuid oleaut32
all: $(TARGET)
-$(TARGET): $(OBJECTS) $(PROGRAM)$(RES_SUFFIX) libexpat.dll
+$(TARGET): $(OBJECTS) $(PROGRAM)$(RES_SUFFIX)
$(LINK) $(LFLAGS) -o $@ $^ $(addprefix -l,$(LIBS)) $(addprefix -l,$(DELAYIMPORTS))
ibrowser$(RES_SUFFIX): $(PROGRAM)_intres.rc res/*.bmp res/*.ico
Modified: trunk/reactos/base/applications/ibrowser/Makefile-precomp
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/ibrowser…
==============================================================================
--- trunk/reactos/base/applications/ibrowser/Makefile-precomp (original)
+++ trunk/reactos/base/applications/ibrowser/Makefile-precomp Tue Aug 1 03:23:19 2006
@@ -52,6 +52,7 @@
webchild.o \
mainframe.o \
favorites.o \
+ xs-native.o \
xmlstorage.o
LIBS = gdi32 comctl32 shell32 ole32 oleaut32 uuid
@@ -61,7 +62,7 @@
precomp.h.gch: *.h utility/*.h
$(CXX) $(CFLAGS) precomp.h
-$(TARGET): $(OBJECTS) $(PROGRAM)$(RES_SUFFIX) libexpat.dll
+$(TARGET): $(OBJECTS) $(PROGRAM)$(RES_SUFFIX)
$(LINK) $(LFLAGS) -o $@ $^ $(addprefix -l,$(LIBS)) $(addprefix -l,$(DELAYIMPORTS))
ibrowser$(RES_SUFFIX): $(PROGRAM)_intres.rc res/*.bmp res/*.ico
Removed: trunk/reactos/base/applications/ibrowser/expat-license.txt
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/ibrowser…
==============================================================================
--- trunk/reactos/base/applications/ibrowser/expat-license.txt (original)
+++ trunk/reactos/base/applications/ibrowser/expat-license.txt (removed)
@@ -1,22 +1,0 @@
-Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
- and Clark Cooper
-Copyright (c) 2001, 2002, 2003 Expat maintainers.
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice shall be included
-in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Modified: trunk/reactos/base/applications/ibrowser/favorites.cpp
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/ibrowser…
==============================================================================
--- trunk/reactos/base/applications/ibrowser/favorites.cpp (original)
+++ trunk/reactos/base/applications/ibrowser/favorites.cpp Tue Aug 1 03:23:19 2006
@@ -429,10 +429,10 @@
XMLDoc xbel;
if (!xbel.read(path))
- if (xbel._last_error == XML_ERROR_NO_ELEMENTS)
+/*@@ if (xbel._last_error == XML_ERROR_NO_ELEMENTS)
return false;
- else
- MessageBox(0/*@@g_Globals._hwndDesktop*/, String(xbel._last_error_msg.c_str()),
+ else */
+ MessageBox(0/*@@g_Globals._hwndDesktop*/, xbel._errors.str(),
TEXT("ROS Explorer - reading bookmark file"), MB_OK);
const_XMLPos pos(&xbel);
@@ -457,9 +457,9 @@
super::write(pos);
pos.back();
- xbel._header._doctype = "<!DOCTYPE xbel"
- " PUBLIC \"+//IDN
python.org//DTD XML Bookmark Exchange Language
1.0//EN//XML\"\n"
- " \"http://www.python.org/topics/xml/dtds/xbel-1.0.dtd\">";
+ xbel._format._doctype._name = "xbel";
+ xbel._format._doctype._public = "//IDN
python.org//DTD XML Bookmark Exchange
Language 1.0//EN//XML";
+ xbel._format._doctype._system =
"http://www.python.org/topics/xml/dtds/xbel-1.0.dtd";
xbel.write(path);
}
Modified: trunk/reactos/base/applications/ibrowser/ibrowser.dsp
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/ibrowser…
==============================================================================
--- trunk/reactos/base/applications/ibrowser/ibrowser.dsp (original)
+++ trunk/reactos/base/applications/ibrowser/ibrowser.dsp Tue Aug 1 03:23:19 2006
@@ -28,7 +28,7 @@
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
-CPP=cl.exe
+CPP=cl.cmd
RSC=rc.exe
!IF "$(CFG)" == "ibrowser - Win32 Release"
@@ -199,6 +199,10 @@
SOURCE=.\utility\xmlstorage.h
# End Source File
+# Begin Source File
+
+SOURCE=".\utility\xs-native.cpp"
+# End Source File
# End Group
# Begin Group "resources"
Modified: trunk/reactos/base/applications/ibrowser/ibrowser.rbuild
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/ibrowser…
==============================================================================
--- trunk/reactos/base/applications/ibrowser/ibrowser.rbuild (original)
+++ trunk/reactos/base/applications/ibrowser/ibrowser.rbuild Tue Aug 1 03:23:19 2006
@@ -3,7 +3,6 @@
<module name="ibrowser" type="win32gui"
installbase="system32" installname="ibrowser.exe" allowwarnings
="true">
<linkerflag>-fexceptions</linkerflag>
<include base="ibrowser">.</include>
- <include base="ReactOS">include/expat</include>
<define name="__USE_W32API" />
<define name="UNICODE" />
<define name="WIN32" />
@@ -18,12 +17,12 @@
<library>ole32</library>
<library>oleaut32</library>
<library>shell32</library>
- <library>expat</library>
<pch>precomp.h</pch>
<directory name="utility">
<file>utility.cpp</file>
<file>window.cpp</file>
<file>xmlstorage.cpp</file>
+ <file>xs-native.cpp</file>
</directory>
<file>ibrowser.cpp</file>
<file>favorites.cpp</file>
Modified: trunk/reactos/base/applications/ibrowser/make_ibrowser.dsp
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/ibrowser…
==============================================================================
--- trunk/reactos/base/applications/ibrowser/make_ibrowser.dsp (original)
+++ trunk/reactos/base/applications/ibrowser/make_ibrowser.dsp Tue Aug 1 03:23:19 2006
@@ -4,7 +4,7 @@
# TARGTYPE "Win32 (x86) External Target" 0x0106
-CFG=make_ibrowser - Win32 bjam
+CFG=make_ibrowser - Win32 Release
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
@@ -13,7 +13,7 @@
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
-!MESSAGE NMAKE /f "make_ibrowser.mak" CFG="make_ibrowser - Win32
bjam"
+!MESSAGE NMAKE /f "make_ibrowser.mak" CFG="make_ibrowser - Win32
Release"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
@@ -43,7 +43,7 @@
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
-# PROP Cmd_Line "msdevfilt -gcc -pipe "perl d:\tools\gSTLFilt.pl" make -f
Makefile-precomp UNICODE=0"
+# PROP Cmd_Line "msdevfilt -gcc -pipe "perl d:\tools\gSTLFilt.pl"
mingw32-make -f Makefile-precomp UNICODE=0"
# PROP Rebuild_Opt "clean all"
# PROP Target_File "ibrowser.exe"
# PROP Bsc_Name ""
@@ -64,7 +64,7 @@
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
-# PROP Cmd_Line "msdevfilt -gcc -pipe "perl d:\tools\gSTLFilt.pl" make -f
Makefile-precomp UNICODE=0 DEBUG=1"
+# PROP Cmd_Line "msdevfilt -gcc -pipe "perl d:\tools\gSTLFilt.pl"
mingw32-make -f Makefile-precomp UNICODE=0 DEBUG=1"
# PROP Rebuild_Opt "clean all"
# PROP Target_File "ibrowser.exe"
# PROP Bsc_Name "msdevfilt -gcc -pipe "perl d:\tools\gSTLFilt.pl" make -f
Makefile.MinGW UNICODE=0 DEBUG=1"
@@ -85,7 +85,7 @@
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "UDebug"
# PROP Intermediate_Dir "UDebug"
-# PROP Cmd_Line "msdevfilt -gcc -pipe "perl d:\tools\gSTLFilt.pl" make -f
Makefile.MinGW UNICODE=1 DEBUG=1"
+# PROP Cmd_Line "msdevfilt -gcc -pipe "perl d:\tools\gSTLFilt.pl"
mingw32-make -f Makefile.MinGW UNICODE=1 DEBUG=1"
# PROP Rebuild_Opt "clean all"
# PROP Target_File "ibrowser.exe"
# PROP Bsc_Name ""
@@ -106,7 +106,7 @@
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "URelease"
# PROP Intermediate_Dir "URelease"
-# PROP Cmd_Line "msdevfilt -gcc make -f Makefile-precomp UNICODE=1"
+# PROP Cmd_Line "msdevfilt -gcc mingw32-make -f Makefile-precomp UNICODE=1"
# PROP Rebuild_Opt "clean all"
# PROP Target_File "ibrowser.exe"
# PROP Bsc_Name ""
Modified: trunk/reactos/base/applications/ibrowser/utility/xmlstorage.cpp
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/ibrowser…
==============================================================================
--- trunk/reactos/base/applications/ibrowser/utility/xmlstorage.cpp (original)
+++ trunk/reactos/base/applications/ibrowser/utility/xmlstorage.cpp Tue Aug 1 03:23:19
2006
@@ -4,7 +4,7 @@
//
// xmlstorage.cpp
//
- // Copyright (c) 2004, 2005 Martin Fuchs <martin-fuchs(a)gmx.net>
+ // Copyright (c) 2004, 2005, 2006 Martin Fuchs <martin-fuchs(a)gmx.net>
//
@@ -36,22 +36,29 @@
*/
+#ifndef XS_NO_COMMENT
+#define XS_NO_COMMENT // no #pragma comment(lib, ...) statements in .lib files
+#endif
+
//#include "xmlstorage.h"
#include <precomp.h>
// work around GCC's wide string constant bug
#ifdef __GNUC__
-const LPCXSSTR XMLStorage::XS_TRUE = XS_TEXT("true");
-const LPCXSSTR XMLStorage::XS_FALSE = XS_TEXT("false");
-const LPCXSSTR XMLStorage::XS_NUMBERFMT = XS_TEXT("%d");
+const LPCXSSTR XMLStorage::XS_EMPTY = XS_EMPTY_STR;
+const LPCXSSTR XMLStorage::XS_TRUE = XS_TRUE_STR;
+const LPCXSSTR XMLStorage::XS_FALSE = XS_FALSE_STR;
+const LPCXSSTR XMLStorage::XS_INTFMT = XS_INTFMT_STR;
+const LPCXSSTR XMLStorage::XS_FLOATFMT = XS_FLOATFMT_STR;
#endif
namespace XMLStorage {
-static std::string unescape(const char* s, char b='"', char
e='"')
+ /// remove escape characters from zero terminated string
+static std::string unescape(const char* s, char b, char e)
{
const char* end = s + strlen(s);
@@ -68,7 +75,13 @@
return std::string(s, end-s);
}
-static std::string unescape(const char* s, int l, char b='"', char
e='"')
+inline std::string unescape(const char* s)
+{
+ return unescape(s, '"', '"');
+}
+
+ /// remove escape characters from string with specified length
+static std::string unescape(const char* s, size_t l, char b, char e)
{
const char* end = s + l;
@@ -85,6 +98,11 @@
return std::string(s, end-s);
}
+inline std::string unescape(const char* s, size_t l)
+{
+ return unescape(s, l, '"', '"');
+}
+
/// move XPath like to position in XML tree
bool XMLPos::go(const char* path)
@@ -137,7 +155,7 @@
if (slash == path)
return NULL;
- int l = slash? slash-path: strlen(path);
+ size_t l = slash? slash-path: strlen(path);
std::string comp(path, l);
path += l;
@@ -198,7 +216,7 @@
if (slash == path)
return NULL;
- int l = slash? slash-path: strlen(path);
+ size_t l = slash? slash-path: strlen(path);
std::string comp(path, l);
path += l;
@@ -259,239 +277,113 @@
}
- /// read XML stream into XML tree below _pos
-XML_Status XMLReaderBase::read()
-{
- XML_Status status = XML_STATUS_OK;
-
- while(status == XML_STATUS_OK) {
- char* buffer = (char*) XML_GetBuffer(_parser, BUFFER_LEN);
-
- int l = read_buffer(buffer, BUFFER_LEN);
- if (l < 0)
- break;
-
- status = XML_ParseBuffer(_parser, l, false);
+ /// encode XML string literals
+std::string EncodeXMLString(const XS_String& str)
+{
+ LPCXSSTR s = str.c_str();
+ size_t l = XS_len(s);
+
+ 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++ = ';';
+ break;
+
+ case '<':
+ *o++ = '&'; *o++ = 'l'; *o++ = 't'; *o++ = ';';
+ break;
+
+ case '>':
+ *o++ = '&'; *o++ = 'g'; *o++ = 't'; *o++ = ';';
+ break;
+
+ case '"':
+ *o++ = '&'; *o++ = 'q'; *o++ = 'u'; *o++ = 'o';
*o++ = 't'; *o++ = ';';
+ break;
+
+ case '\'':
+ *o++ = '&'; *o++ = 'a'; *o++ = 'p'; *o++ = 'o';
*o++ = 's'; *o++ = ';';
+ break;
+
+ default:
+ if ((unsigned)*p<20 && *p!='\t' && *p!='\r'
&& *p!='\n') {
+ char b[16];
+ sprintf(b, "&%d;", (unsigned)*p);
+ for(const char*q=b; *q; )
+ *o++ = *q++;
+ } else
+ *o++ = *p;
+ }
+
+#ifdef XS_STRING_UTF8
+ return XS_String(buffer, o-buffer);
+#else
+ 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;
+
+ LPCXSSTR s = str.c_str();
+
+ for(LPCXSSTR p=s; *p; ++p)
+ switch(*p) {
+ case '&':
+ out << "&";
+ break;
+
+ case '<':
+ out << "<";
+ break;
+
+ case '>':
+ out << ">";
+ break;
+
+ case '"':
+ out << """;
+ break;
+
+ case '\'':
+ out << "'";
+ break;
+
+ default:
+ if ((unsigned)*p<20 && *p!='\t' *p!='\r' &&
*p!='\n')
+ out << "&" << (unsigned)*p << ";";
+ else
+ out << *p;
+ }
+
+#ifdef XS_STRING_UTF8
+ return XS_String(out.str());
+#else
+ return get_utf8(out.str());
+#endif
+ */
}
-
- if (status != XML_STATUS_ERROR)
- status = XML_ParseBuffer(_parser, 0, true);
-
- if (_pos->_children.empty())
- _pos->_trailing.append(_content);
- else
- _pos->_children.back()->_trailing.append(_content);
-
- _content.erase();
-
- return status;
-}
-
-
- /// store XML version and encoding into XML reader
-void XMLCALL XMLReaderBase::XML_XmlDeclHandler(void* userData, const XML_Char* version,
const XML_Char* encoding, int standalone)
-{
- XMLReaderBase* pReader = (XMLReaderBase*) userData;
-
- if (version)
- pReader->_xml_version = version;
-
- if (encoding)
- pReader->_encoding = encoding;
-}
-
- /// notifications about XML start tag
-void XMLCALL XMLReaderBase::XML_StartElementHandler(void* userData, const XML_Char* name,
const XML_Char** atts)
-{
- XMLReaderBase* pReader = (XMLReaderBase*) userData;
- XMLPos& pos = pReader->_pos;
-
- // search for end of first line
- const char* s = pReader->_content.c_str();
- const char* p = s;
- const char* e = p + pReader->_content.length();
-
- for(; p<e; ++p)
- if (*p == '\n') {
- ++p;
- break;
- }
-
- if (p != s)
- if (pos->_children.empty()) { // no children in last node?
- if (pReader->_last_tag == TAG_START)
- pos->_content.append(s, p-s);
- else if (pReader->_last_tag == TAG_END)
- pos->_trailing.append(s, p-s);
- // else TAG_NONE -> don't store white space in root node
- } else
- pos->_children.back()->_trailing.append(s, p-s);
-
- std::string leading;
-
- if (p != e)
- leading.assign(p, e-p);
-
- XMLNode* node = new XMLNode(String_from_XML_Char(name), leading);
-
- pos.add_down(node);
-
- while(*atts) {
- const XML_Char* attr_name = *atts++;
- const XML_Char* attr_value = *atts++;
-
- (*node)[String_from_XML_Char(attr_name)] = String_from_XML_Char(attr_value);
- }
-
- pReader->_last_tag = TAG_START;
- pReader->_content.erase();
-}
-
- /// notifications about XML end tag
-void XMLCALL XMLReaderBase::XML_EndElementHandler(void* userData, const XML_Char* name)
-{
- XMLReaderBase* pReader = (XMLReaderBase*) userData;
- XMLPos& pos = pReader->_pos;
-
- // search for end of first line
- const char* s = pReader->_content.c_str();
- const char* p = s;
- const char* e = p + pReader->_content.length();
-
- for(; p<e; ++p)
- if (*p == '\n') {
- ++p;
- break;
- }
-
- if (p != s)
- if (pos->_children.empty()) // no children in current node?
- pos->_content.append(s, p-s);
- else
- if (pReader->_last_tag == TAG_START)
- pos->_content.append(s, p-s);
- else
- pos->_children.back()->_trailing.append(s, p-s);
-
- if (p != e)
- pos->_end_leading.assign(p, e-p);
-
- pos.back();
-
- pReader->_last_tag = TAG_END;
- pReader->_content.erase();
-}
-
- /// store content, white space and comments
-void XMLCALL XMLReaderBase::XML_DefaultHandler(void* userData, const XML_Char* s, int
len)
-{
- XMLReaderBase* pReader = (XMLReaderBase*) userData;
-
- pReader->_content.append(s, len);
-}
-
-
-std::string XMLReaderBase::get_error_string() const
-{
- XML_Error error = XML_GetErrorCode(_parser);
-
- switch(error) {
- case XML_ERROR_NONE: return "XML_ERROR_NONE";
- case XML_ERROR_NO_MEMORY: return "XML_ERROR_NO_MEMORY";
- case XML_ERROR_SYNTAX: return "XML_ERROR_SYNTAX";
- case XML_ERROR_NO_ELEMENTS: return "XML_ERROR_NO_ELEMENTS";
- case XML_ERROR_INVALID_TOKEN: return "XML_ERROR_INVALID_TOKEN";
- case XML_ERROR_UNCLOSED_TOKEN: return "XML_ERROR_UNCLOSED_TOKEN";
- case XML_ERROR_PARTIAL_CHAR: return "XML_ERROR_PARTIAL_CHAR";
- case XML_ERROR_TAG_MISMATCH: return "XML_ERROR_TAG_MISMATCH";
- case XML_ERROR_DUPLICATE_ATTRIBUTE: return
"XML_ERROR_DUPLICATE_ATTRIBUTE";
- case XML_ERROR_JUNK_AFTER_DOC_ELEMENT: return
"XML_ERROR_JUNK_AFTER_DOC_ELEMENT";
- case XML_ERROR_PARAM_ENTITY_REF: return "XML_ERROR_PARAM_ENTITY_REF";
- case XML_ERROR_UNDEFINED_ENTITY: return "XML_ERROR_UNDEFINED_ENTITY";
- case XML_ERROR_RECURSIVE_ENTITY_REF: return
"XML_ERROR_RECURSIVE_ENTITY_REF";
- case XML_ERROR_ASYNC_ENTITY: return "XML_ERROR_ASYNC_ENTITY";
- case XML_ERROR_BAD_CHAR_REF: return "XML_ERROR_BAD_CHAR_REF";
- case XML_ERROR_BINARY_ENTITY_REF: return "XML_ERROR_BINARY_ENTITY_REF";
- case XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF: return
"XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF";
- case XML_ERROR_MISPLACED_XML_PI: return "XML_ERROR_MISPLACED_XML_PI";
- case XML_ERROR_UNKNOWN_ENCODING: return "XML_ERROR_UNKNOWN_ENCODING";
- case XML_ERROR_INCORRECT_ENCODING: return
"XML_ERROR_INCORRECT_ENCODING";
- case XML_ERROR_UNCLOSED_CDATA_SECTION: return
"XML_ERROR_UNCLOSED_CDATA_SECTION";
- case XML_ERROR_EXTERNAL_ENTITY_HANDLING: return
"XML_ERROR_EXTERNAL_ENTITY_HANDLING";
- case XML_ERROR_NOT_STANDALONE: return "XML_ERROR_NOT_STANDALONE";
- case XML_ERROR_UNEXPECTED_STATE: return "XML_ERROR_UNEXPECTED_STATE";
- case XML_ERROR_ENTITY_DECLARED_IN_PE: return
"XML_ERROR_ENTITY_DECLARED_IN_PE";
- case XML_ERROR_FEATURE_REQUIRES_XML_DTD: return
"XML_ERROR_FEATURE_REQUIRES_XML_DTD";
- case XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING: return
"XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING";
- case XML_ERROR_UNBOUND_PREFIX: return "XML_ERROR_UNBOUND_PREFIX";
- // EXPAT version >= 1.95.8
-#if XML_MAJOR_VERSION>1 || (XML_MAJOR_VERSION==1 && XML_MINOR_VERSION>95)
|| (XML_MAJOR_VERSION==1 && XML_MINOR_VERSION==95 &&
XML_MICRO_VERSION>7)
- case XML_ERROR_UNDECLARING_PREFIX: return
"XML_ERROR_UNDECLARING_PREFIX";
- case XML_ERROR_INCOMPLETE_PE: return "XML_ERROR_INCOMPLETE_PE";
- case XML_ERROR_XML_DECL: return "XML_ERROR_XML_DECL";
- case XML_ERROR_TEXT_DECL: return "XML_ERROR_TEXT_DECL";
- case XML_ERROR_PUBLICID: return "XML_ERROR_PUBLICID";
- case XML_ERROR_SUSPENDED: return "XML_ERROR_SUSPENDED";
- case XML_ERROR_NOT_SUSPENDED: return "XML_ERROR_NOT_SUSPENDED";
- case XML_ERROR_ABORTED: return "XML_ERROR_ABORTED";
- case XML_ERROR_FINISHED: return "XML_ERROR_FINISHED";
- case XML_ERROR_SUSPEND_PE: return "XML_ERROR_SUSPEND_PE";
-//#endif
-//#if XML_MAJOR_VERSION>=2
- /* Added in 2.0. */
- case XML_ERROR_RESERVED_PREFIX_XML: return
"XML_ERROR_RESERVED_PREFIX_XML";
- case XML_ERROR_RESERVED_PREFIX_XMLNS: return
"XML_ERROR_RESERVED_PREFIX_XMLNS";
- case XML_ERROR_RESERVED_NAMESPACE_URI: return
"XML_ERROR_RESERVED_NAMESPACE_URI";
-#endif
- }
-
- std::ostringstream out;
-
- out << "XML parser error #" << error;
-
- return out.str();
-}
-
-
-std::string EncodeXMLString(const XS_String& str)
-{
- LPCXSSTR s = str.c_str();
- LPXSSTR buffer = (LPXSSTR)alloca(5*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++ = ';';
- break;
-
- case '<':
- *o++ = '&'; *o++ = 'l'; *o++ = 't'; *o++ = ';';
- break;
-
- case '>':
- *o++ = '&'; *o++ = 'g'; *o++ = 't'; *o++ = ';';
- break;
-
- case '"':
- *o++ = '&'; *o++ = 'q'; *o++ = 'u'; *o++ = 'o';
*o++ = 't'; *o++ = ';';
- break;
-
- case '\'':
- *o++ = '&'; *o++ = 'a'; *o++ = 'p'; *o++ = 'o';
*o++ = 's'; *o++ = ';';
- break;
-
- default:
- *o++ = *p;
- }
-
-#ifdef XS_STRING_UTF8
- return XS_String(buffer, o-buffer);
-#else
- return get_utf8(buffer, o-buffer);
-#endif
-}
-
+}
+
+ /// decode XML string literals
XS_String DecodeXMLString(const XS_String& str)
{
LPCXSSTR s = str.c_str();
@@ -517,6 +409,16 @@
p += 5;
} else
*o++ = *p;
+ } else if (*p=='<' && !XS_nicmp(p+1,XS_TEXT("!CDATA["),7))
{
+ p += 9;
+ LPCXSSTR e = XS_strstr(p, XS_TEXT("]]>"));
+ if (e) {
+ size_t l = e - p;
+ memcpy(o, p, l);
+ o += l;
+ p += 3;
+ } else
+ *o++ = *p;
} else
*o++ = *p;
@@ -546,8 +448,28 @@
}
+ /// print node without any white space
+void XMLNode::plain_write_worker(std::ostream& out) const
+{
+ 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()*/) {
+ out << ">";
+
+ for(Children::const_iterator it=_children.begin(); it!=_children.end(); ++it)
+ (*it)->plain_write_worker(out);
+
+ out << "</" << EncodeXMLString(*this) <<
">";
+ } else
+ out << "/>";
+}
+
+
/// pretty print node with children tree to output stream
-void XMLNode::pretty_write_worker(std::ostream& out, int indent) const
+void XMLNode::pretty_write_worker(std::ostream& out, const XMLFormat& format, int
indent) const
{
for(int i=indent; i--; )
out << XML_INDENT_SPACE;
@@ -557,23 +479,23 @@
for(AttributeMap::const_iterator it=_attributes.begin(); it!=_attributes.end(); ++it)
out << ' ' << EncodeXMLString(it->first) <<
"=\"" << EncodeXMLString(it->second) <<
"\"";
- if (!_children.empty() || !_content.empty()) {
- out << ">\n";
+ if (!_children.empty()/*@@ || !_content.empty()*/) {
+ out << '>' << format._endl;
for(Children::const_iterator it=_children.begin(); it!=_children.end(); ++it)
- (*it)->pretty_write_worker(out, indent+1);
+ (*it)->pretty_write_worker(out, format, indent+1);
for(int i=indent; i--; )
out << XML_INDENT_SPACE;
- out << "</" << EncodeXMLString(*this) <<
">\n";
+ out << "</" << EncodeXMLString(*this) << '>'
<< format._endl;
} else
- out << "/>\n";
+ out << "/>" << format._endl;
}
/// write node with children tree to output stream using smart formating
-void XMLNode::smart_write_worker(std::ostream& out, int indent) const
+void XMLNode::smart_write_worker(std::ostream& out, const XMLFormat& format, int
indent) const
{
if (_leading.empty())
for(int i=indent; i--; )
@@ -592,7 +514,7 @@
out << '>';
if (_content.empty())
- out << '\n';
+ out << format._endl;
else
out << _content;
@@ -600,7 +522,7 @@
if (it != _children.end()) {
for(; it!=_children.end(); ++it)
- (*it)->smart_write_worker(out, indent+1);
+ (*it)->smart_write_worker(out, format, indent+1);
if (_end_leading.empty())
for(int i=indent; i--; )
@@ -614,10 +536,269 @@
}
if (_trailing.empty())
- out << '\n';
+ out << format._endl;
else
out << _trailing;
}
+std::ostream& operator<<(std::ostream& out, const XMLError& err)
+{
+ out << err._systemId << "(" << err._line << ")
[column " << err._column << "] : "
+ << err._message;
+
+ return out;
+}
+
+
+void DocType::parse(const char* p)
+{
+ while(isspace((unsigned char)*p)) ++p;
+
+ const char* start = p;
+ while(isxmlsym(*p)) ++p;
+ _name.assign(start, p-start);
+
+ while(isspace((unsigned char)*p)) ++p;
+
+ start = p;
+ while(isxmlsym(*p)) ++p;
+ std::string keyword(p, p-start); // "PUBLIC" or "SYSTEM"
+
+ while(isspace((unsigned char)*p)) ++p;
+
+ if (*p=='"' || *p=='\'') {
+ char delim = *p;
+
+ start = ++p;
+ while(*p && *p!=delim) ++p;
+
+ if (*p == delim)
+ _public.assign(start, p++-start);
+ } else
+ _public.erase();
+
+ while(isspace((unsigned char)*p)) ++p;
+
+ if (*p=='"' || *p=='\'') {
+ char delim = *p;
+
+ start = ++p;
+ while(*p && *p!=delim) ++p;
+
+ if (*p == delim)
+ _system.assign(start, p++-start);
+ } else
+ _system.erase();
+}
+
+
+
+void XMLFormat::print_header(std::ostream& out, bool lf) const
+{
+ out << "<?xml version=\"" << _version <<
"\" encoding=\"" << _encoding << "\"";
+
+ if (_standalone != -1)
+ out << " standalone=\"yes\"";
+
+ out << "?>";
+
+ if (lf)
+ out << _endl;
+
+ if (!_doctype.empty()) {
+ out << "<!DOCTYPE " << _doctype._name;
+
+ if (!_doctype._public.empty()) {
+ out << " PUBLIC " << _doctype._public;
+
+ if (lf)
+ out << _endl;
+
+ out << " " << _doctype._system;
+ } else if (!_doctype._system.empty())
+ out << " SYSTEM " << _doctype._system;
+
+ out << "?>";
+
+ if (lf)
+ out << _endl;
+ }
+
+ for(StyleSheetList::const_iterator it=_stylesheets.begin(); it!=_stylesheets.end();
++it) {
+ it->print(out);
+
+ if (lf)
+ out << _endl;
+ }
+
+/* if (!_additional.empty()) {
+ out << _additional;
+
+ if (lf)
+ out << _endl;
+ } */
+}
+
+void StyleSheet::print(std::ostream& out) const
+{
+ out << "<?xml-stylesheet"
+ " href=\"" << _href << "\""
+ " type=\"" << _type << "\"";
+
+ if (!_title.empty())
+ out << " title=\"" << _title << "\"";
+
+ if (!_media.empty())
+ out << " media=\"" << _media << "\"";
+
+ if (!_charset.empty())
+ out << " charset=\"" << _charset <<
"\"";
+
+ if (_alternate)
+ out << " alternate=\"yes\"";
+
+ out << "?>";
+}
+
+
+ /// return formated error message
+std::string XMLError::str() const
+{
+ std::ostringstream out;
+
+ out << *this;
+
+ return out.str();
+}
+
+
+ /// return merged error strings
+XS_String XMLErrorList::str() const
+{
+ std::ostringstream out;
+
+ for(const_iterator it=begin(); it!=end(); ++it)
+ out << *it << std::endl;
+
+ return out.str();
+}
+
+
+void XMLReaderBase::finish_read()
+{
+ if (_pos->_children.empty())
+ _pos->_trailing.append(_content);
+ else
+ _pos->_children.back()->_trailing.append(_content);
+
+ _content.erase();
+}
+
+
+ /// store XML version and encoding into XML reader
+void XMLReaderBase::XmlDeclHandler(const char* version, const char* encoding, int
standalone)
+{
+ if (version)
+ _format._version = version;
+
+ if (encoding)
+ _format._encoding = encoding;
+
+ _format._standalone = standalone;
+}
+
+
+ /// 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* p = s;
+ const char* e = p + _content.length();
+
+ for(; p<e; ++p)
+ if (*p == '\n') {
+ ++p;
+ break;
+ }
+
+ if (p != s)
+ if (_pos->_children.empty()) { // no children in last node?
+ if (_last_tag == TAG_START)
+ _pos->_content.append(s, p-s);
+ else if (_last_tag == TAG_END)
+ _pos->_trailing.append(s, p-s);
+ else // TAG_NONE at root node
+ p = s;
+ } else
+ _pos->_children.back()->_trailing.append(s, p-s);
+
+ std::string leading;
+
+ if (p != e)
+ leading.assign(p, e-p);
+
+ XMLNode* node = new XMLNode(name, leading);
+
+ _pos.add_down(node);
+
+#ifdef XMLNODE_LOCATION
+ node->_location = get_location();
+#endif
+
+ node->_attributes = attributes;
+
+ _last_tag = TAG_START;
+ _content.erase();
+}
+
+ /// 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();
+
+ for(; p<e; ++p)
+ if (*p == '\n') {
+ ++p;
+ 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
+ _pos->_children.back()->_trailing.append(s, p-s);
+
+ if (p != e)
+ _pos->_end_leading.assign(p, e-p);
+
+ _pos.back();
+
+ _last_tag = TAG_END;
+ _content.erase();
+}
+
+#if defined(XS_USE_XERCES) || defined(XS_USE_EXPAT)
+ /// store content, white space and comments
+void XMLReaderBase::DefaultHandler(const XML_Char* s, int len)
+{
+#if defined(XML_UNICODE) || defined(XS_USE_XERCES)
+ _content.append(String_from_XML_Char(s, len));
+#else
+ _content.append(s, len);
+#endif
+}
+#endif
+
+
+XS_String XMLWriter::s_empty_attr;
+
+
} // namespace XMLStorage
Modified: trunk/reactos/base/applications/ibrowser/utility/xmlstorage.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/ibrowser…
==============================================================================
--- trunk/reactos/base/applications/ibrowser/utility/xmlstorage.h (original)
+++ trunk/reactos/base/applications/ibrowser/utility/xmlstorage.h Tue Aug 1 03:23:19
2006
@@ -4,7 +4,7 @@
//
// xmlstorage.h
//
- // Copyright (c) 2004, 2005 Martin Fuchs <martin-fuchs(a)gmx.net>
+ // Copyright (c) 2004, 2005, 2006 Martin Fuchs <martin-fuchs(a)gmx.net>
//
@@ -38,19 +38,107 @@
#ifndef _XMLSTORAGE_H
+
+#if _MSC_VER>=1400
+#ifndef _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES
+#define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES 1
+#define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_COUNT 1
+#define _CRT_SECURE_CPP_OVERLOAD_SECURE_NAMES 1
+#endif
+#endif
+
+
+#ifdef XS_USE_XERCES
+
+#ifndef UNICODE
+#ifndef XS_STRING_UTF8
+#define XS_STRING_UTF8
+#endif
+#endif
+
+#include <xercesc/parsers/SAXParser.hpp>
+#include <xercesc/sax/HandlerBase.hpp>
+
+using XERCES_CPP_NAMESPACE_QUALIFIER Locator;
+using XERCES_CPP_NAMESPACE_QUALIFIER SAXParser;
+using XERCES_CPP_NAMESPACE_QUALIFIER HandlerBase;
+using XERCES_CPP_NAMESPACE_QUALIFIER InputSource;
+using XERCES_CPP_NAMESPACE_QUALIFIER AttributeList;
+using XERCES_CPP_NAMESPACE_QUALIFIER SAXParseException;
+
+typedef XMLCh XML_Char;
+
+#elif defined(XS_USE_EXPAT)
+
#include <expat/expat.h>
+#endif
+
+
#ifdef _MSC_VER
-#pragma comment(lib, "libexpat.lib")
#pragma warning(disable: 4786)
-#endif
-
+
+#ifndef XS_NO_COMMENT
+
+#ifdef XS_USE_XERCES
+#ifdef _DEBUG
+#pragma comment(lib, "xerces-c_2D")
+#else
+#pragma comment(lib, "xerces-c_2")
+#endif
+#elif defined(XS_USE_EXPAT)
+#ifdef XML_STATIC
+#ifndef _DEBUG
+#pragma comment(lib, "libexpatMT")
+#endif
+#else
+#pragma comment(lib, "libexpat")
+#endif
+#endif
+
+#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
+#pragma comment(lib, "xmlstorage-vc8d")
+#else
+#pragma comment(lib, "xmlstorage-vc6d")
+#endif
+#else
+#ifdef _DLL
+#if _MSC_VER==1400
+#pragma comment(lib, "xmlstorage-vc8")
+#else
+#pragma comment(lib, "xmlstorage-vc6")
+#endif
+#elif defined(_MT)
+#if _MSC_VER==1400
+#pragma comment(lib, "xmlstorage-vc8t")
+#else
+#pragma comment(lib, "xmlstorage-vc6t")
+#endif
+#else
+ // -ML is no more supported by VS2005.
+#pragma comment(lib, "xmlstorage-vc6l")
+#endif
+#endif
+#endif // _STRING_DEFINED
+
+#endif // XS_NO_COMMENT
+
+#endif // _MSC_VER
+
+
+#ifdef UNICODE
+#ifndef _UNICODE
+#define _UNICODE
+#endif
+#else
+#ifdef _UNICODE
+#define UNICODE
+#endif
+#endif
#include <windows.h> // for LPCTSTR
-
-#ifdef UNICODE
-#define _UNICODE
-#endif
#include <tchar.h>
#include <malloc.h>
@@ -78,24 +166,47 @@
#define XS_TEXT(x) x
#define LPXSSTR LPSTR
#define LPCXSSTR LPCSTR
+#define XS_cmp strcmp
#define XS_icmp stricmp
+#define XS_ncmp strncmp
#define XS_nicmp strnicmp
#define XS_toi atoi
+#define XS_tod strtod
#define XS_len strlen
-#define XS_sprintf sprintf
-#define XS_vsprintf vsprintf
+#define XS_snprintf _snprintf
+#define XS_vsnprintf _vsnprintf
+#define XS_strstr strstr
#else
#define XS_CHAR TCHAR
#define XS_TEXT(x) TEXT(x)
#define LPXSSTR LPTSTR
#define LPCXSSTR LPCTSTR
+#define XS_cmp _tcscmp
#define XS_icmp _tcsicmp
+#define XS_ncmp _tcsncmp
#define XS_nicmp _tcsnicmp
#define XS_toi _ttoi
+#define XS_tod _tcstod
#define XS_len _tcslen
-#define XS_sprintf _stprintf
-#define XS_vsprintf _vstprintf
-#endif
+#define XS_snprintf _sntprintf
+#define XS_vsnprintf _vsntprintf
+#define XS_strstr _tcsstr
+#endif
+
+#ifndef COUNTOF
+#if _MSC_VER>=1400
+#define COUNTOF _countof
+#else
+#define COUNTOF(b) (sizeof(b)/sizeof(b[0]))
+#endif
+#endif
+
+
+int inline isxmlsym(unsigned char c)
+{
+ return isalnum(c) || c=='_' || c=='-';
+}
+
#if defined(_STRING_DEFINED) && !defined(XS_STRING_UTF8)
@@ -121,46 +232,46 @@
XS_String() {}
XS_String(LPCXSSTR s) {if (s) super::assign(s);}
- XS_String(LPCXSSTR s, int l) : super(s, l) {}
+ XS_String(LPCXSSTR s, size_t l) : super(s, l) {}
XS_String(const super& other) : super(other) {}
XS_String(const XS_String& other) : super(other) {}
#if defined(UNICODE) && !defined(XS_STRING_UTF8)
XS_String(LPCSTR s) {assign(s);}
- XS_String(LPCSTR s, int l) {assign(s, l);}
+ XS_String(LPCSTR s, size_t l) {assign(s, l);}
XS_String(const std::string& other) {assign(other.c_str());}
XS_String& operator=(LPCSTR s) {assign(s); return *this;}
- void assign(LPCSTR s) {if (s) {int 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, int l) {if (s) {int bl=l; LPWSTR
b=(LPWSTR)alloca(sizeof(WCHAR)*bl); super::assign(b, MultiByteToWideChar(CP_ACP, 0, s, l,
b, bl));} else erase();}
+ 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, int l) {assign(s, l);}
+ XS_String(LPCWSTR s, size_t l) {assign(s, l);}
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) {int bl=wcslen(s); LPSTR b=(LPSTR)alloca(bl);
super::assign(b, WideCharToMultiByte(CP_UTF8, 0, s, bl, b, bl, 0, 0));} else erase();}
- void assign(LPCWSTR s, int l) {int bl=l; if (s) {LPSTR b=(LPSTR)alloca(bl);
super::assign(b, WideCharToMultiByte(CP_UTF8, 0, s, l, b, bl, 0, 0));} else erase();}
+ 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) {int bl=wcslen(s); LPSTR b=(LPSTR)alloca(bl);
super::assign(b, WideCharToMultiByte(CP_ACP, 0, s, bl, b, bl, 0, 0));} else erase();}
- void assign(LPCWSTR s, int l) {int bl=l; if (s) {LPSTR b=(LPSTR)alloca(bl);
super::assign(b, WideCharToMultiByte(CP_ACP, 0, s, l, b, bl, 0, 0));} else erase();}
+ 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
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);}
- void assign(LPCXSSTR s, int l) {super::assign(s, l);}
+ void assign(LPCXSSTR s, size_t l) {super::assign(s, l);}
operator LPCXSSTR() const {return c_str();}
#ifdef XS_STRING_UTF8
- operator std::wstring() const {int bl=length(); LPWSTR
b=(LPWSTR)alloca(sizeof(WCHAR)*bl); return std::wstring(b, MultiByteToWideChar(CP_UTF8, 0,
c_str(), bl, b, bl));}
+ 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 {int 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 {int bl=length(); LPWSTR
b=(LPWSTR)alloca(sizeof(WCHAR)*bl); return std::wstring(b, MultiByteToWideChar(CP_ACP, 0,
c_str(), bl, b, bl));}
+ 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
XS_String& printf(LPCXSSTR fmt, ...)
@@ -169,7 +280,7 @@
XS_CHAR b[BUFFER_LEN];
va_start(l, fmt);
- super::assign(b, XS_vsprintf(b, fmt, l));
+ super::assign(b, XS_vsnprintf(b, COUNTOF(b), fmt, l));
va_end(l);
return *this;
@@ -179,7 +290,7 @@
{
XS_CHAR b[BUFFER_LEN];
- super::assign(b, XS_vsprintf(b, fmt, l));
+ super::assign(b, XS_vsnprintf(b, COUNTOF(b), fmt, l));
return *this;
}
@@ -190,7 +301,7 @@
XS_CHAR b[BUFFER_LEN];
va_start(l, fmt);
- super::append(b, XS_vsprintf(b, fmt, l));
+ super::append(b, XS_vsnprintf(b, COUNTOF(b), fmt, l));
va_end(l);
return *this;
@@ -200,7 +311,7 @@
{
XS_CHAR b[BUFFER_LEN];
- super::append(b, XS_vsprintf(b, fmt, l));
+ super::append(b, XS_vsnprintf(b, COUNTOF(b), fmt, l));
return *this;
}
@@ -211,12 +322,33 @@
#endif // XS_String
+#define XS_EMPTY_STR XS_TEXT("")
+#define XS_TRUE_STR XS_TEXT("true")
+#define XS_FALSE_STR XS_TEXT("false")
+#define XS_INTFMT_STR XS_TEXT("%d")
+#define XS_FLOATFMT_STR XS_TEXT("%f")
+
+ // work around GCC's wide string constant bug
+#ifdef __GNUC__
+extern const LPCXSSTR XS_EMPTY;
+extern const LPCXSSTR XS_TRUE;
+extern const LPCXSSTR XS_FALSE;
+extern const LPCXSSTR XS_INTFMT;
+extern const LPCXSSTR XS_FLOATFMT;
+#else
+#define XS_EMPTY XS_EMPTY_STR
+#define XS_TRUE XS_TRUE_STR
+#define XS_FALSE XS_FALSE_STR
+#define XS_INTFMT XS_INTFMT_STR
+#define XS_FLOATFMT XS_FLOATFMT_STR
+#endif
+
+
#ifndef XS_STRING_UTF8
-inline void assign_utf8(XS_String& s, const char* str)
-{
- int lutf8 = strlen(str);
-
+ // from UTF-8 to XS internal string encoding
+inline void assign_utf8(XS_String& s, const char* str, int lutf8)
+{
#ifdef UNICODE
LPTSTR buffer = (LPTSTR)alloca(sizeof(TCHAR)*lutf8);
int l = MultiByteToWideChar(CP_UTF8, 0, str, lutf8, buffer, lutf8);
@@ -231,22 +363,44 @@
s.assign(buffer, l);
}
-inline std::string get_utf8(LPCTSTR s, int l)
+ // from UTF-8 to XS internal string encoding
+inline void assign_utf8(XS_String& s, const char* str)
+{
+ assign_utf8(s, str, strlen(str));
+}
+
+ // from XS internal string encoding to UTF-8
+inline std::string get_utf8(LPCTSTR s, size_t l)
{
#ifdef UNICODE
- int bl=2*l; LPSTR buffer = (LPSTR)alloca(bl);
- l = WideCharToMultiByte(CP_UTF8, 0, s, l, buffer, bl, 0, 0);
+ size_t bl=2*l; LPSTR buffer = (LPSTR)alloca(bl);
+ l = WideCharToMultiByte(CP_UTF8, 0, s, (int)l, buffer, (int)bl, 0, 0);
#else
LPWSTR wbuffer = (LPWSTR)alloca(sizeof(WCHAR)*l);
- l = MultiByteToWideChar(CP_ACP, 0, s, l, wbuffer, l);
-
- int bl=2*l; LPSTR buffer = (LPSTR)alloca(bl);
- l = WideCharToMultiByte(CP_UTF8, 0, wbuffer, l, buffer, bl, 0, 0);
+ l = MultiByteToWideChar(CP_ACP, 0, s, (int)l, wbuffer, (int)l);
+
+ size_t bl=2*l; LPSTR buffer = (LPSTR)alloca(bl);
+ l = WideCharToMultiByte(CP_UTF8, 0, wbuffer, (int)l, buffer, (int)bl, 0, 0);
#endif
return std::string(buffer, l);
}
+#ifdef UNICODE
+ // from XS internal string encoding to UTF-8
+inline std::string get_utf8(const char* s, size_t l)
+{
+ LPWSTR wbuffer = (LPWSTR)alloca(sizeof(WCHAR)*l);
+ l = MultiByteToWideChar(CP_ACP, 0, s, (int)l, wbuffer, (int)l);
+
+ size_t bl=2*l; LPSTR buffer = (LPSTR)alloca(bl);
+ l = WideCharToMultiByte(CP_UTF8, 0, wbuffer, (int)l, buffer, (int)bl, 0, 0);
+
+ return std::string(buffer, l);
+}
+#endif
+
+ // from XS internal string encoding to UTF-8
inline std::string get_utf8(const XS_String& s)
{
return get_utf8(s.c_str(), s.length());
@@ -265,43 +419,58 @@
typedef std::filebuf STDIO_FILEBUF;
#endif
+struct FileHolder
+{
+ FileHolder(LPCTSTR path, LPCTSTR mode)
+ {
+#ifdef __STDC_WANT_SECURE_LIB__ // secure CRT functions using VS 2005
+ if (_tfopen_s(&_pfile, path, mode) != 0)
+ _pfile = NULL;
+#else
+ _pfile = _tfopen(path, mode);
+#endif
+ }
+
+ ~FileHolder()
+ {
+ if (_pfile)
+ fclose(_pfile);
+ }
+
+protected:
+ FILE* _pfile;
+};
+
/// input file stream with ANSI/UNICODE file names
-struct tifstream : public std::istream
+struct tifstream : public std::istream, FileHolder
{
typedef std::istream super;
tifstream(LPCTSTR path)
: super(&_buf),
- _pfile(_tfopen(path, TEXT("r"))),
+ FileHolder(path, TEXT("rb")), // binary mode is important for
XMLReader::read_buffer() with MinGW libraries
#ifdef __GNUC__
- _buf(_pfile, ios::in)
+ _buf(_pfile, std::ios::in)
#else
_buf(_pfile)
#endif
{
}
- ~tifstream()
- {
- if (_pfile)
- fclose(_pfile);
- }
-
protected:
- FILE* _pfile;
STDIO_FILEBUF _buf;
};
/// output file stream with ANSI/UNICODE file names
-struct tofstream : public std::ostream
+struct tofstream : public std::ostream, FileHolder
{
typedef std::ostream super;
tofstream(LPCTSTR path)
: super(&_buf),
- _pfile(_tfopen(path, TEXT("w"))),
+ FileHolder(path, TEXT("wb")),
#ifdef __GNUC__
- _buf(_pfile, ios::out)
+ _buf(_pfile, std::ios::out)
#else
_buf(_pfile)
#endif
@@ -311,13 +480,9 @@
~tofstream()
{
flush();
-
- if (_pfile)
- fclose(_pfile);
}
protected:
- FILE* _pfile;
STDIO_FILEBUF _buf;
};
@@ -326,16 +491,17 @@
#define XML_INDENT_SPACE " "
-#ifdef XML_UNICODE // Are XML_Char strings UTF-16 encoded?
-
+#if defined(XS_USE_XERCES) || defined(XS_USE_EXPAT)
+
+#if defined(XML_UNICODE)/*Expat*/ || defined(XS_USE_XERCES)/*Xerces*/ // Are Expat/Xerces
XML strings UTF-16 encoded?
typedef XS_String String_from_XML_Char;
#elif defined(XS_STRING_UTF8)
-
typedef XS_String String_from_XML_Char;
#else
+ /// converter from Expat/Xerces strings to XMLStorage internal strings
struct String_from_XML_Char : public XS_String
{
String_from_XML_Char(const XML_Char* str)
@@ -345,6 +511,8 @@
};
#endif
+
+#endif // defined(XS_USE_XERCES) || defined(XS_USE_EXPAT)
#if defined(UNICODE) && !defined(XS_STRING_UTF8)
@@ -363,6 +531,152 @@
};
#endif
+
+
+ /// XML Error with message and location
+struct XMLError
+{
+ XMLError()
+ : _line(0),
+ _column(0),
+ _error_code(0)
+ {
+ }
+
+ std::string str() const;
+ friend std::ostream& operator<<(std::ostream&, const XMLError& err);
+
+ XS_String _message;
+ XS_String _systemId;
+ int _line;
+ int _column;
+ int _error_code;
+};
+
+struct XMLErrorList : public std::list<XMLError>
+{
+ XS_String str() const;
+};
+
+
+#ifdef XMLNODE_LOCATION
+ /// location of XML Node including XML file name
+struct XMLLocation
+{
+ XMLLocation()
+ : _pdisplay_path(NULL),
+ _line(0),
+ _column(0)
+ {
+ }
+
+ XMLLocation(const char* display_path, int line, int column)
+ : _pdisplay_path(display_path),
+ _line(line),
+ _column(column)
+ {
+ }
+
+ std::string str() const;
+
+protected:
+ const char* _pdisplay_path; // character pointer for fast reference
+ int _line;
+ int _column;
+};
+#endif
+
+
+enum PRETTY_FLAGS {
+ PRETTY_PLAIN = 0,
+ PRETTY_LINEFEED = 1,
+ PRETTY_INDENT = 2
+};
+
+
+struct StyleSheet
+{
+ std::string _href; // CDATA #REQUIRED
+ std::string _type; // CDATA #REQUIRED
+ std::string _title; // CDATA #IMPLIED
+ std::string _media; // CDATA #IMPLIED
+ std::string _charset; // CDATA #IMPLIED
+ bool _alternate; // (yes|no) "no"
+
+ StyleSheet() : _alternate(false) {}
+
+ StyleSheet(const std::string& href, const std::string&
type="text/xsl", bool alternate=false)
+ : _href(href),
+ _type(type),
+ _alternate(alternate)
+ {
+ }
+
+ bool empty() const {return _href.empty();}
+ void print(std::ostream& out) const;
+};
+
+struct StyleSheetList : public std::list<StyleSheet>
+{
+ void set(const StyleSheet& stylesheet)
+ {
+ clear();
+ push_back(stylesheet);
+ }
+};
+
+
+struct DocType
+{
+ std::string _name;
+
+ // External Document Types are noted, but not parsed.
+ std::string _public;
+ std::string _system;
+
+ // Internal DTDs are not supported.
+
+ void parse(const char* str);
+ bool empty() const {return _name.empty();}
+};
+
+ /// Management of XML file headers and formating
+struct XMLFormat
+{
+ XMLFormat(PRETTY_FLAGS pretty=PRETTY_INDENT, const std::string&
xml_version="1.0", const std::string& encoding="utf-8", const
DocType& doctype=DocType())
+ : _pretty(pretty),
+ _endl("\n"),
+ _version(xml_version),
+ _encoding(encoding),
+ _doctype(doctype),
+ _standalone(-1)
+ {
+ }
+
+ void print_header(std::ostream& out, bool lf=true) const;
+
+ PRETTY_FLAGS _pretty;
+ const char* _endl; // line ending string: "\n" or "\r\n"
+
+ std::string _version;
+ std::string _encoding;
+
+ DocType _doctype;
+
+ StyleSheetList _stylesheets;
+
+// std::string _additional;
+
+ int _standalone;
+};
+
+
+enum WRITE_MODE {
+ FORMAT_PLAIN, /// write XML without any white space
+ FORMAT_SMART, /// preserve original white space and comments if present; pretty print
otherwise
+ FORMAT_ORIGINAL, /// write XML stream preserving original white space and comments
+ FORMAT_PRETTY /// pretty print node to stream without preserving original white space
+};
/// in memory representation of an XML node
@@ -392,11 +706,33 @@
{
return super::find(x);
}
+
+ XS_String get(const char* x, LPXSSTR def=XS_EMPTY_STR) const
+ {
+ const_iterator found = find(x);
+
+ if (found != end())
+ return found->second;
+ else
+ return def;
+ }
};
#else
- typedef std::map<XS_String, XS_String> AttributeMap;
-#endif
-
+ struct AttributeMap : public std::map<XS_String, XS_String>
+ {
+ XS_String get(const char* x, LPXSSTR def=XS_EMPTY_STR) const
+ {
+ const_iterator found = find(x);
+
+ if (found != end())
+ return found->second;
+ else
+ return def;
+ }
+ };
+#endif
+
+ /// internal children node list
struct Children : public std::list<XMLNode*>
{
void assign(const Children& other)
@@ -436,17 +772,21 @@
}
XMLNode(const XMLNode& other)
- : _attributes(other._attributes),
+ : XS_String(other),
+ _attributes(other._attributes),
_leading(other._leading),
_content(other._content),
_end_leading(other._end_leading),
_trailing(other._trailing)
+#ifdef XMLNODE_LOCATION
+ , _location(other._location)
+#endif
{
for(Children::const_iterator it=other._children.begin(); it!=other._children.end();
++it)
_children.push_back(new XMLNode(**it));
}
- ~XMLNode()
+ virtual ~XMLNode()
{
while(!_children.empty()) {
delete _children.back();
@@ -500,14 +840,14 @@
}
/// read only access to an attribute
- template<typename T> XS_String get(const T& attr_name) const
+ template<typename T> XS_String get(const T& attr_name, LPXSSTR
def=XS_EMPTY_STR) const
{
AttributeMap::const_iterator found = _attributes.find(attr_name);
if (found != _attributes.end())
return found->second;
else
- return XS_String();
+ return def;
}
/// convenient value access in children node
@@ -570,13 +910,23 @@
return _children;
}
+ const AttributeMap& get_attributes() const
+ {
+ return _attributes;
+ }
+
+ AttributeMap& get_attributes()
+ {
+ return _attributes;
+ }
+
XS_String get_content() const
{
#ifdef XS_STRING_UTF8
const XS_String& ret = _content;
#else
XS_String ret;
- assign_utf8(ret, _content.c_str());
+ assign_utf8(ret, _content.c_str(), _content.length());
#endif
return DecodeXMLString(ret.c_str());
@@ -587,18 +937,20 @@
_content.assign(EncodeXMLString(s.c_str()));
}
- enum WRITE_MODE {
- FORMAT_SMART = 0, /// preserve original white space and comments if present; pretty
print otherwise
- FORMAT_ORIGINAL = 1, /// write XML stream preserving original white space and comments
- FORMAT_PRETTY = 2 /// pretty print node to stream without preserving original white
space
- };
+#ifdef XMLNODE_LOCATION
+ const XMLLocation& get_location() const {return _location;}
+#endif
/// write node with children tree to output stream
- std::ostream& write(std::ostream& out, WRITE_MODE mode=FORMAT_SMART, int
indent=0) const
+ std::ostream& write(std::ostream& out, const XMLFormat& format, WRITE_MODE
mode=FORMAT_SMART, int indent=0) const
{
switch(mode) {
+ case FORMAT_PLAIN:
+ plain_write_worker(out);
+ break;
+
case FORMAT_PRETTY:
- pretty_write_worker(out, indent);
+ pretty_write_worker(out, format, indent);
break;
case FORMAT_ORIGINAL:
@@ -606,7 +958,7 @@
break;
default: // FORMAT_SMART
- smart_write_worker(out, indent);
+ smart_write_worker(out, format, indent);
}
return out;
@@ -616,10 +968,14 @@
Children _children;
AttributeMap _attributes;
- std::string _leading;
- std::string _content;
- std::string _end_leading;
- std::string _trailing;
+ std::string _leading; // UTF-8 encoded
+ std::string _content; // UTF-8 and entity encoded, may contain CDATA sections; decode
with DecodeXMLString()
+ std::string _end_leading; // UTF-8 encoded
+ std::string _trailing; // UTF-8 encoded
+
+#ifdef XMLNODE_LOCATION
+ XMLLocation _location;
+#endif
XMLNode* get_first_child() const
{
@@ -678,18 +1034,20 @@
}
#endif
- /// XPath find functions
+ /// XPath find function (const)
const XMLNode* find_relative(const char* path) const;
+ /// XPath find function
XMLNode* find_relative(const char* path)
{return const_cast<XMLNode*>(const_cast<const
XMLNode*>(this)->find_relative(path));}
/// relative XPath create function
XMLNode* create_relative(const char* path);
- void write_worker(std::ostream& out, int indent) const;
- void pretty_write_worker(std::ostream& out, int indent) const;
- void smart_write_worker(std::ostream& out, int indent) const;
+ void write_worker(std::ostream& out, int indent) 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;
};
@@ -708,6 +1066,7 @@
{
}
+ /// internal iterator class
struct iterator
{
typedef XMLNode::Children::iterator BaseIterator;
@@ -806,6 +1165,7 @@
{
}
+ /// internal iterator class
struct const_iterator
{
typedef XMLNode::Children::const_iterator BaseIterator;
@@ -954,6 +1314,7 @@
return _cur->get(attr_name);
}
+ /// attribute setting
void put(const XS_String& attr_name, const XS_String& value)
{
_cur->put(attr_name, value);
@@ -1218,18 +1579,7 @@
};
- // work around GCC's wide string constant bug
-#ifdef __GNUC__
-extern const LPCXSSTR XS_TRUE;
-extern const LPCXSSTR XS_FALSE;
-extern const LPCXSSTR XS_NUMBERFMT;
-#else
-#define XS_TRUE XS_TEXT("true")
-#define XS_FALSE XS_TEXT("false")
-#define XS_NUMBERFMT XS_TEXT("%d")
-#endif
-
-
+ /// type converter for boolean data
struct XMLBool
{
XMLBool(bool value=false)
@@ -1277,6 +1627,7 @@
void operator=(const XMLBool&); // disallow assignment operations
};
+ /// type converter for boolean data with write access
struct XMLBoolRef
{
XMLBoolRef(XMLNode* node, const XS_String& attr_name, bool def=false)
@@ -1318,6 +1669,7 @@
};
+ /// type converter for integer data
struct XMLInt
{
XMLInt(int value)
@@ -1351,7 +1703,7 @@
operator XS_String() const
{
XS_CHAR buffer[32];
- XS_sprintf(buffer, XS_NUMBERFMT, _value);
+ XS_snprintf(buffer, COUNTOF(buffer), XS_INTFMT, _value);
return buffer;
}
@@ -1362,6 +1714,7 @@
void operator=(const XMLInt&); // disallow assignment operations
};
+ /// type converter for integer data with write access
struct XMLIntRef
{
XMLIntRef(XMLNode* node, const XS_String& attr_name, int def=0)
@@ -1386,7 +1739,7 @@
void assign(int value)
{
XS_CHAR buffer[32];
- XS_sprintf(buffer, XS_NUMBERFMT, value);
+ XS_snprintf(buffer, COUNTOF(buffer), XS_INTFMT, value);
_ref.assign(buffer);
}
@@ -1395,6 +1748,90 @@
};
+ /// type converter for numeric data
+struct XMLDouble
+{
+ XMLDouble(double value)
+ : _value(value)
+ {
+ }
+
+ XMLDouble(LPCXSSTR value, double def=0.)
+ {
+ LPTSTR end;
+
+ if (value && *value)
+ _value = XS_tod(value, &end);
+ else
+ _value = def;
+ }
+
+ XMLDouble(const XMLNode* node, const XS_String& attr_name, double def=0.)
+ {
+ LPTSTR end;
+ const XS_String& value = node->get(attr_name);
+
+ if (!value.empty())
+ _value = XS_tod(value.c_str(), &end);
+ else
+ _value = def;
+ }
+
+ operator double() const
+ {
+ return _value;
+ }
+
+ operator XS_String() const
+ {
+ XS_CHAR buffer[32];
+ XS_snprintf(buffer, COUNTOF(buffer), XS_FLOATFMT, _value);
+ return buffer;
+ }
+
+protected:
+ double _value;
+
+private:
+ void operator=(const XMLDouble&); // disallow assignment operations
+};
+
+ /// type converter for numeric data with write access
+struct XMLDoubleRef
+{
+ XMLDoubleRef(XMLNode* node, const XS_String& attr_name, double def=0.)
+ : _ref((*node)[attr_name])
+ {
+ if (_ref.empty())
+ assign(def);
+ }
+
+ XMLDoubleRef& operator=(double value)
+ {
+ assign(value);
+
+ return *this;
+ }
+
+ operator double() const
+ {
+ LPTSTR end;
+ return XS_tod(_ref.c_str(), &end);
+ }
+
+ void assign(double value)
+ {
+ XS_CHAR buffer[32];
+ XS_snprintf(buffer, COUNTOF(buffer), XS_FLOATFMT, value);
+ _ref.assign(buffer);
+ }
+
+protected:
+ XS_String& _ref;
+};
+
+
+ /// type converter for string data
struct XMLString
{
XMLString(const XS_String& value)
@@ -1402,7 +1839,7 @@
{
}
- XMLString(LPCXSSTR value, LPCXSSTR def=XS_TEXT(""))
+ XMLString(LPCXSSTR value, LPCXSSTR def=XS_EMPTY)
{
if (value && *value)
_value = value;
@@ -1410,7 +1847,7 @@
_value = def;
}
- XMLString(const XMLNode* node, const XS_String& attr_name, LPCXSSTR
def=XS_TEXT(""))
+ XMLString(const XMLNode* node, const XS_String& attr_name, LPCXSSTR def=XS_EMPTY)
{
const XS_String& value = node->get(attr_name);
@@ -1437,16 +1874,17 @@
void operator=(const XMLString&); // disallow assignment operations
};
+ /// type converter for string data with write access
struct XMStringRef
{
- XMStringRef(XMLNode* node, const XS_String& attr_name, LPCXSSTR
def=XS_TEXT(""))
+ XMStringRef(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_TEXT(""))
+ XMStringRef(XMLNode* node, const XS_String& node_name, const XS_String&
attr_name, LPCXSSTR def=XS_EMPTY)
: _ref(node->subvalue(node_name, attr_name))
{
if (_ref.empty())
@@ -1500,62 +1938,175 @@
/// XML reader base class
struct XMLReaderBase
-{
- XMLReaderBase(XMLNode* node)
- : _pos(node),
- _parser(XML_ParserCreate(NULL))
- {
- XML_SetUserData(_parser, this);
- XML_SetXmlDeclHandler(_parser, XML_XmlDeclHandler);
- XML_SetElementHandler(_parser, XML_StartElementHandler, XML_EndElementHandler);
- XML_SetDefaultHandler(_parser, XML_DefaultHandler);
-
- _last_tag = TAG_NONE;
- }
-
- virtual ~XMLReaderBase()
- {
- XML_ParserFree(_parser);
- }
-
- XML_Status read();
-
- virtual int read_buffer(char* buffer, int len) = 0;
-
- std::string get_position() const
- {
- int line = XML_GetCurrentLineNumber(_parser);
- int column = XML_GetCurrentColumnNumber(_parser);
-
- std::ostringstream out;
- out << "(" << line << ") : [column " <<
column << "]";
-
- return out.str();
- }
-
- std::string get_instructions() const {return _instructions;}
-
- XML_Error get_error_code() {return XML_GetErrorCode(_parser);}
- std::string get_error_string() const;
+#ifdef XS_USE_XERCES
+ : public HandlerBase
+#endif
+{
+#ifdef XS_USE_XERCES
+
+ XMLReaderBase(XMLNode* node, InputSource* source, bool adoptSource=false);
+ virtual ~XMLReaderBase();
+
+ void read();
protected:
- XMLPos _pos;
+ SAXParser* _parser;
+ InputSource* _source;
+ bool _deleteSource;
+
+ virtual void XMLDecl(const XMLCh* const versionStr, const XMLCh* const encodingStr,
+ const XMLCh* const standaloneStr, const XMLCh* const actualEncodingStr);
+
+ // Handlers for the SAX DocumentHandler interface
+ virtual void setDocumentLocator(const Locator* const locator);
+ virtual void startElement(const XMLCh* const name, AttributeList& attributes);
+ virtual void endElement(const XMLCh* const name);
+ virtual void characters(const XMLCh* const chars, const unsigned int length);
+ virtual void ignorableWhitespace(const XMLCh* const chars, const unsigned int
length);
+
+ // Handlers for the SAX ErrorHandler interface
+ virtual void error(const SAXParseException& e);
+ virtual void fatalError(const SAXParseException& e);
+ virtual void warning(const SAXParseException& e);
+ virtual void resetErrors();
+
+#elif defined(XS_USE_EXPAT) // !XS_USE_XERCES
+
+ XMLReaderBase(XMLNode* node);
+ virtual ~XMLReaderBase();
+
+protected:
XML_Parser _parser;
- std::string _xml_version;
- std::string _encoding;
- std::string _instructions;
-
- std::string _content;
- enum {TAG_NONE, TAG_START, TAG_END} _last_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=-1);
static void XMLCALL XML_StartElementHandler(void* userData, const XML_Char* name, const
XML_Char** atts);
static void XMLCALL XML_EndElementHandler(void* userData, const XML_Char* name);
static void XMLCALL XML_DefaultHandler(void* userData, const XML_Char* s, int len);
+
+ static std::string get_expat_error_string(XML_Error error_code);
+
+#else // XS_USE_EXPAT
+
+ XMLReaderBase(XMLNode* node)
+ : _pos(node),
+ _endl_defined(false),
+ _utf8(false)
+ {
+ _last_tag = TAG_NONE;
+ }
+
+ virtual ~XMLReaderBase();
+
+ bool parse();
+
+#endif
+
+public:
+#ifndef XS_USE_XERCES
+ void read();
+
+ std::string get_position() const;
+#endif
+ const XMLFormat& get_format() const {return _format;}
+ const char* get_endl() const {return _endl_defined? _format._endl: "\n";}
+
+ const XMLErrorList& get_errors() const {return _errors;}
+ const XMLErrorList& get_warnings() const {return _warnings;}
+
+ void clear_errors() {_errors.clear(); _warnings.clear();}
+
+#ifdef XMLNODE_LOCATION
+ const char* _display_path; // character pointer for fast reference in XMLLocation
+
+#ifdef XS_USE_XERCES
+ const Locator* _locator;
+#endif
+
+ XMLLocation get_location() const;
+#endif
+
+protected:
+ XMLPos _pos;
+
+ std::string _content; // UTF-8 encoded
+ enum {TAG_NONE, TAG_START, TAG_END} _last_tag;
+
+ XMLErrorList _errors;
+ XMLErrorList _warnings;
+
+ XMLFormat _format;
+ bool _endl_defined;
+
+#ifdef XS_USE_XERCES
+ //@@
+#elif defined(XS_USE_EXPAT)
+ virtual int read_buffer(char* buffer, int len) = 0;
+#else
+ virtual int get() = 0;
+ int eat_endl();
+
+ bool _utf8;
+#endif
+
+ void finish_read();
+
+ virtual void XmlDeclHandler(const char* version, const char* encoding, int standalone);
+ virtual void StartElementHandler(const XS_String& name, const
XMLNode::AttributeMap& attributes);
+ virtual void EndElementHandler();
+#if defined(XS_USE_XERCES) || defined(XS_USE_EXPAT)
+ virtual void DefaultHandler(const XML_Char* s, int len);
+#else
+ virtual void DefaultHandler(const std::string& s);
+#endif
};
/// XML file reader
+
+#ifdef XS_USE_XERCES
+
+struct XercesXMLReader : public XMLReaderBase
+{
+ XercesXMLReader(XMLNode* node, InputSource* source, bool adoptSource=false)
+ : XMLReaderBase(node, source, adoptSource)
+ {
+ }
+
+ XercesXMLReader(XMLNode* node, LPCTSTR path);
+ XercesXMLReader(XMLNode* node, const XMLByte* buffer, size_t bytes, const
std::string& system_id=std::string());
+};
+
+#define XMLReader XercesXMLReader
+
+#elif defined(XS_USE_EXPAT)
+
+struct ExpatXMLReader : public XMLReaderBase
+{
+ ExpatXMLReader(XMLNode* node, std::istream& in)
+ : XMLReaderBase(node),
+ _in(in)
+ {
+ }
+
+ /// read XML stream into XML tree below _pos
+ int read_buffer(char* buffer, int len)
+ {
+ if (!_in.good())
+ return -1;
+
+ _in.read(buffer, len);
+
+ return _in.gcount();
+ }
+
+protected:
+ std::istream& _in;
+};
+
+#define XMLReader ExpatXMLReader
+
+#else // XS_USE_XERCES, XS_USE_EXPAT
+
struct XMLReader : public XMLReaderBase
{
XMLReader(XMLNode* node, std::istream& in)
@@ -1564,127 +2115,110 @@
{
}
- /// read XML stream into XML tree below _pos
- int read_buffer(char* buffer, int len)
- {
- if (!_in.good())
- return -1;
-
- _in.read(buffer, len);
-
- return _in.gcount();
+ /// read one character from XML stream
+ int get()
+ {
+ return _in.get();
}
protected:
std::istream& _in;
};
-
-struct XMLHeader
-{
- XMLHeader(const std::string& xml_version="1.0", const std::string&
encoding="UTF-8", const std::string& doctype="")
- : _version(xml_version),
- _encoding(encoding),
- _doctype(doctype)
- {
- }
-
- void print(std::ostream& out) const
- {
- out << "<?xml version=\"" << _version <<
"\" encoding=\"" << _encoding <<
"\"?>\n";
-
- if (!_doctype.empty())
- out << _doctype << '\n';
- if (!_additional.empty())
- out << _additional << '\n';
- }
-
- std::string _version;
- std::string _encoding;
- std::string _doctype;
- std::string _additional;
-};
-
-
+#endif // XS_USE_XERCES
+
+
+ /// XML document holder
struct XMLDoc : public XMLNode
{
XMLDoc()
- : XMLNode(""),
- _last_error(XML_ERROR_NONE)
+ : XMLNode("")
{
}
XMLDoc(LPCTSTR path)
- : XMLNode(""),
- _last_error(XML_ERROR_NONE)
+ : XMLNode("")
{
read(path);
}
- std::istream& read(std::istream& in)
- {
- XMLReader reader(this, in);
-
- read(reader);
-
- return in;
- }
+#ifdef XS_USE_XERCES
+ bool read(LPCTSTR path)
+ {
+ XMLReader reader(this, path);
+
+#if defined(_STRING_DEFINED) && !defined(XS_STRING_UTF8)
+ return read(reader, std::string(ANS(path)));
+#else
+ return read(reader, XS_String(path));
+#endif
+ }
+
+ bool read(const char* buffer, size_t len, const std::string&
system_id=std::string())
+ {
+ XMLReader reader(this, (const XMLByte*)buffer, len, system_id);
+
+ return read(reader, system_id);
+ }
+
+#else // XS_USE_XERCES
bool read(LPCTSTR path)
{
tifstream in(path);
XMLReader reader(this, in);
-//#if defined(_STRING_DEFINED) && !defined(XS_STRING_UTF8)
-// return read(reader, std::string(ANS(path)));
-//#else
+#if defined(_STRING_DEFINED) && !defined(XS_STRING_UTF8)
+ return read(reader, std::string(ANS(path)));
+#else
return read(reader, XS_String(path));
-//#endif
- }
-
- bool read(XMLReaderBase& reader)
- {
- XML_Status status = reader.read();
-
- _header._additional = reader.get_instructions();
-
- if (status == XML_STATUS_ERROR) {
- std::ostringstream out;
-
- out << "input stream" << reader.get_position() << "
" << reader.get_error_string();
-
- _last_error = reader.get_error_code();
- _last_error_msg = out.str();
- }
-
- return status != XML_STATUS_ERROR;
- }
+#endif
+ }
+
+ bool read(const char* buffer, size_t len, const std::string&
system_id=std::string())
+ {
+ std::istringstream in(std::string(buffer, len));
+
+ return read(in, system_id);
+ }
+
+ bool read(std::istream& in, const std::string& system_id=std::string())
+ {
+ XMLReader reader(this, in);
+
+ return read(reader, system_id);
+ }
+#endif // XS_USE_XERCES
bool read(XMLReaderBase& reader, const std::string& display_path)
{
- XML_Status status = reader.read();
-
- _header._additional = reader.get_instructions();
-
- if (status == XML_STATUS_ERROR) {
- std::ostringstream out;
-
- out << display_path << reader.get_position() << " "
<< reader.get_error_string();
-
- _last_error = reader.get_error_code();
- _last_error_msg = out.str();
- }
-
- return status != XML_STATUS_ERROR;
+#ifdef XMLNODE_LOCATION
+ // make a string copy to handle temporary string objects
+ _display_path = display_path;
+ reader._display_path = _display_path.c_str();
+#endif
+
+ reader.clear_errors();
+ reader.read();
+
+ _format = reader.get_format();
+ _format._endl = reader.get_endl();
+
+ if (!reader.get_errors().empty()) {
+ _errors = reader.get_errors();
+ return false;
+ }
+
+ return true;
}
/// write XML stream preserving previous white space and comments
std::ostream& write(std::ostream& out, WRITE_MODE mode=FORMAT_SMART) const
{
- _header.print(out);
+ _format.print_header(out, mode!=FORMAT_PLAIN);
if (!_children.empty())
- _children.front()->write(out);
+ _children.front()->write(out, _format, mode);
return out;
}
@@ -1695,26 +2229,30 @@
return write(out, FORMAT_PRETTY);
}
- void write(LPCTSTR path, WRITE_MODE mode=FORMAT_SMART) const
+ bool write(LPCTSTR path, WRITE_MODE mode=FORMAT_SMART) const
{
tofstream out(path);
- write(out, mode);
- }
-
- void write_formating(LPCTSTR path) const
+ return write(out, mode).good();
+ }
+
+ bool write_formating(LPCTSTR path) const
{
tofstream out(path);
- write_formating(out);
- }
-
- XMLHeader _header;
- XML_Error _last_error;
- std::string _last_error_msg;
-};
-
-
+ return write_formating(out).good();
+ }
+
+ XMLFormat _format;
+ XMLErrorList _errors;
+
+#ifdef XMLNODE_LOCATION
+ std::string _display_path;
+#endif
+};
+
+
+ /// XML message wrapper
struct XMLMessage : public XMLDoc
{
XMLMessage(const char* name)
@@ -1723,7 +2261,212 @@
_pos.create(name);
}
+ std::string toString() const
+ {
+ std::ostringstream out;
+
+ write(out);
+
+ return out.str();
+ }
+
XMLPos _pos;
+
+protected:
+ XMLMessage()
+ : _pos(this)
+ {
+ }
+};
+
+
+struct XMLMessageFromString : public XMLMessage
+{
+ XMLMessageFromString(const std::string& xml_str, const std::string&
system_id=std::string())
+ {
+ read(xml_str.c_str(), xml_str.length(), system_id);
+ }
+};
+
+
+ /// Reader for XML Messages
+struct XMLMessageReader : public XMLPos
+{
+ 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);
+ }
+
+ const XMLDoc& get_document()
+ {
+ return _msg;
+ }
+
+protected:
+ XMLDoc _msg;
+};
+
+
+struct XMLWriter
+{
+ XMLWriter(std::ostream& out, const XMLFormat& format=XMLFormat())
+ : _pofstream(NULL),
+ _out(out),
+ _format(format)
+ {
+ format.print_header(_out, false); // _format._endl is printed in write_pre()
+ }
+
+ XMLWriter(LPCTSTR path, const XMLFormat& format=XMLFormat())
+ : _pofstream(new tofstream(path)),
+ _out(*_pofstream),
+ _format(format)
+ {
+ format.print_header(_out, false); // _format._endl is printed in write_pre()
+ }
+
+ ~XMLWriter()
+ {
+ _out << _format._endl;
+ delete _pofstream;
+ }
+
+ /// create node and move to it
+ void create(const XS_String& name)
+ {
+ if (!_stack.empty()) {
+ StackEntry& last = _stack.top();
+
+ if (last._state < PRE_CLOSED) {
+ write_attributes(last);
+ close_pre(last);
+ }
+
+ ++last._children;
+ }
+
+ StackEntry entry;
+ entry._node_name = name;
+ _stack.push(entry);
+
+ write_pre(entry);
+ }
+
+ /// go back to previous position
+ bool back()
+ {
+ if (!_stack.empty()) {
+ write_post(_stack.top());
+
+ _stack.pop();
+ return true;
+ } else
+ return false;
+ }
+
+ /// attribute setting
+ void put(const XS_String& attr_name, const XS_String& value)
+ {
+ if (!_stack.empty())
+ _stack.top()._attributes[attr_name] = value;
+ }
+
+ /// C++ write access to an attribute
+ XS_String& operator[](const XS_String& attr_name)
+ {
+ if (_stack.empty())
+ return s_empty_attr;
+
+ return _stack.top()._attributes[attr_name];
+ }
+
+ void set_content(const XS_String& s)
+ {
+ if (!_stack.empty())
+ _stack.top()._content = EncodeXMLString(s.c_str());
+ }
+
+ // public for access in StackEntry
+ enum WRITESTATE {
+ NOTHING, /*PRE,*/ ATTRIBUTES, PRE_CLOSED, /*CONTENT,*/ POST
+ };
+
+protected:
+ tofstream* _pofstream;
+ std::ostream& _out;
+ const XMLFormat&_format;
+
+ typedef XMLNode::AttributeMap AttrMap;
+
+ struct StackEntry {
+ XS_String _node_name;
+ AttrMap _attributes;
+ std::string _content;
+ WRITESTATE _state;
+ bool _children;
+
+ StackEntry() : _state(NOTHING), _children(false) {}
+ };
+
+ std::stack<StackEntry> _stack;
+
+ static XS_String s_empty_attr;
+
+ void close_pre(StackEntry& entry)
+ {
+ _out << '>';
+
+ entry._state = PRE_CLOSED;
+ }
+
+ void write_pre(StackEntry& entry)
+ {
+ if (_format._pretty >= PRETTY_LINEFEED)
+ _out << _format._endl;
+
+ if (_format._pretty == PRETTY_INDENT)
+ for(size_t i=_stack.size(); --i>0; )
+ _out << XML_INDENT_SPACE;
+
+ _out << '<' << EncodeXMLString(entry._node_name);
+ //entry._state = PRE;
+ }
+
+ void write_attributes(StackEntry& entry)
+ {
+ for(AttrMap::const_iterator it=entry._attributes.begin(); it!=entry._attributes.end();
++it)
+ _out << ' ' << EncodeXMLString(it->first) <<
"=\"" << EncodeXMLString(it->second) <<
"\"";
+
+ entry._state = ATTRIBUTES;
+ }
+
+ void write_post(StackEntry& entry)
+ {
+ if (entry._state < ATTRIBUTES)
+ write_attributes(entry);
+
+ if (entry._children || !entry._content.empty()) {
+ if (entry._state < PRE_CLOSED)
+ close_pre(entry);
+
+ _out << entry._content;
+ //entry._state = CONTENT;
+
+ if (_format._pretty>=PRETTY_LINEFEED && entry._content.empty())
+ _out << _format._endl;
+
+ if (_format._pretty==PRETTY_INDENT && entry._content.empty())
+ for(size_t i=_stack.size(); --i>0; )
+ _out << XML_INDENT_SPACE;
+
+ _out << "</" << EncodeXMLString(entry._node_name) <<
">";
+ } else {
+ _out << "/>";
+ }
+
+ entry._state = POST;
+ }
};
Added: trunk/reactos/base/applications/ibrowser/utility/xs-native.cpp
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/ibrowser…
==============================================================================
--- trunk/reactos/base/applications/ibrowser/utility/xs-native.cpp (added)
+++ trunk/reactos/base/applications/ibrowser/utility/xs-native.cpp Tue Aug 1 03:23:19
2006
@@ -1,0 +1,438 @@
+
+ //
+ // XML storage classes
+ //
+ // xs-native.cpp
+ //
+ // Copyright (c) 2006 Martin Fuchs <martin-fuchs(a)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.
+
+*/
+
+#ifndef XS_NO_COMMENT
+#define XS_NO_COMMENT // no #pragma comment(lib, ...) statements in .lib files to enable
static linking
+#endif
+
+//#include "xmlstorage.h"
+#include <precomp.h>
+
+
+#if !defined(XS_USE_EXPAT) && !defined(XS_USE_XERCES)
+
+namespace XMLStorage {
+
+
+XMLReaderBase::~XMLReaderBase()
+{
+}
+
+ /// read XML stream into XML tree below _pos
+void XMLReaderBase::read()
+{
+ if (!parse()) {
+ XMLError error;
+
+ error._message = "XML parsing error";
+ //error._line = ;
+ //error._column = ;
+
+ _errors.push_back(error);
+ }
+
+ finish_read();
+}
+
+
+struct Buffer
+{
+ Buffer()
+ {
+ _buffer = (char*) malloc(BUFFER_LEN);
+ _len = BUFFER_LEN;
+
+ reset();
+ }
+
+ ~Buffer()
+ {
+ free(_buffer);
+ }
+
+ void reset()
+ {
+ _wptr = _buffer;
+ _buffer_str.erase();
+ }
+
+ void append(char c)
+ {
+ size_t wpos = _wptr-_buffer;
+
+ if (wpos >= _len) {
+ _len <<= 1;
+ _buffer = (char*) realloc(_buffer, _len);
+ _wptr = _buffer + wpos;
+ }
+
+ *_wptr++ = c;
+ }
+
+ const std::string& str(bool utf8) // returns UTF-8 encoded buffer content
+ {
+ if (utf8)
+ _buffer_str.assign(_buffer, _wptr-_buffer);
+ else
+ _buffer_str = get_utf8(_buffer, _wptr-_buffer);
+
+ return _buffer_str;
+ }
+
+ size_t len() const
+ {
+ return _wptr - _buffer;
+ }
+
+ bool has_CDEnd() const
+ {
+ //if (_wptr-_buffer < 3)
+ // return false;
+
+ return !strncmp(_wptr-3, "]]>", 3);
+ }
+
+ XS_String get_tag() const
+ {
+ const char* p = _buffer_str.c_str();
+
+ if (*p == '<')
+ ++p;
+
+ if (*p == '/')
+ ++p;
+
+ const char* q = p;
+
+ if (*q == '?')
+ ++q;
+
+ while(isxmlsym(*q))
+ ++q;
+
+#ifdef XS_STRING_UTF8
+ return XS_String(p, q-p);
+#else
+ XS_String tag;
+ assign_utf8(tag, p, q-p);
+ return tag;
+#endif
+ }
+
+ /// read attributes and values
+ void get_attributes(XMLNode::AttributeMap& attributes) const
+ {
+ const char* p = _buffer_str.c_str();
+
+ // find end of tag name
+ if (*p == '<')
+ ++p;
+
+ if (*p == '/')
+ ++p;
+ else if (*p == '?')
+ ++p;
+
+ while(isxmlsym(*p))
+ ++p;
+
+ // read attributes from buffer
+ while(*p && *p!='>' && *p!='/') {
+ while(isspace((unsigned char)*p))
+ ++p;
+
+ const char* attr_name = p;
+
+ while(isxmlsym(*p))
+ ++p;
+
+ if (*p != '=')
+ break; //@TODO error handling
+
+ size_t attr_len = p - attr_name;
+
+ if (*++p!='"' && *p!='\'')
+ break; //@TODO error handling
+
+ char delim = *p;
+ const char* value = ++p;
+
+ while(*p && *p!=delim)
+ ++p;
+
+ size_t value_len = p - value;
+
+ if (*p)
+ ++p; // '"'
+
+#ifdef XS_STRING_UTF8
+ XS_String name_str(attr_name, attr_len);
+ XS_String value_str(value, value_len);
+#else
+ XS_String name_str, value_str;
+ assign_utf8(name_str, attr_name, attr_len);
+ assign_utf8(value_str, value, value_len);
+#endif
+
+ attributes[name_str] = DecodeXMLString(value_str);
+ }
+ }
+
+protected:
+ char* _buffer;
+ char* _wptr;
+ size_t _len;
+ std::string _buffer_str; // UF-8 encoded
+};
+
+bool XMLReaderBase::parse()
+{
+ Buffer buffer;
+ int c = get();
+ bool in_comment = false;
+
+ while(c != EOF) {
+ if (in_comment || c=='<') {
+ buffer.append(c);
+
+ // read start or end tag
+ for(;;) {
+ c = get();
+
+ if (c == EOF)
+ break;
+
+ buffer.append(c);
+
+ if (c == '>')
+ break;
+ }
+
+ const std::string& b = buffer.str(_utf8);
+ const char* str = b.c_str();
+
+ if (in_comment || !strncmp(str+1, "!--", 3)) {
+ // XML comment
+ DefaultHandler(b);
+
+ if (strcmp(str+b.length()-3, "-->"))
+ in_comment = true;
+ else
+ in_comment = false;
+
+ c = get();
+ } else if (str[1] == '/') {
+ // end tag
+
+ /*@TODO error handling
+ const XS_String& tag = buffer.get_tag();
+
+ if (tag != last_opened_tag) {
+ ERROR
+ }
+ */
+
+ EndElementHandler();
+
+ c = get();
+ } else if (str[1] == '?') {
+ // XML declaration
+ const XS_String& tag = buffer.get_tag();
+
+ if (tag == "?xml") {
+ XMLNode::AttributeMap attributes;
+ buffer.get_attributes(attributes);
+
+ const std::string& version = attributes.get("version");
+ const std::string& encoding = attributes.get("encoding");
+
+ int standalone;
+ XMLNode::AttributeMap::const_iterator found = // const_cast for ISO C++
compatibility error of GCC
+ const_cast<const
XMLNode::AttributeMap&>(attributes).find("standalone");
+ if (found != attributes.end())
+ standalone = !XS_icmp(found->second.c_str(), XS_TEXT("yes"));
+ else
+ standalone = -1;
+
+ XmlDeclHandler(version.empty()?NULL:version.c_str(),
encoding.empty()?NULL:encoding.c_str(), standalone);
+
+ if (!encoding.empty() && !_stricmp(encoding.c_str(), "utf-8"))
+ _utf8 = true;
+
+ c = eat_endl();
+ } else if (tag == "?xml-stylesheet") {
+ XMLNode::AttributeMap attributes;
+ buffer.get_attributes(attributes);
+
+ StyleSheet stylesheet(attributes.get("href"),
attributes.get("type"), !XS_icmp(attributes.get("alternate"),
XS_TEXT("yes")));
+ stylesheet._title = attributes.get("title");
+ stylesheet._media = attributes.get("media");
+ stylesheet._charset = attributes.get("charset");
+
+ _format._stylesheets.push_back(stylesheet);
+
+ c = eat_endl();
+ } else {
+ DefaultHandler(b);
+ c = get();
+ }
+ } else if (str[1] == '!') {
+ if (!strncmp(str+2, "DOCTYPE ", 8)) {
+ _format._doctype.parse(str+10);
+
+ c = eat_endl();
+ } else if (!strncmp(str+2, "[CDATA[", 7)) {
+ // parse <![CDATA[ ... ]]> strings
+ while(!buffer.has_CDEnd()) {
+ c = get();
+
+ if (c == EOF)
+ break;
+
+ buffer.append(c);
+ }
+
+ DefaultHandler(buffer.str(_utf8));
+
+ c = get();
+ }
+ } else {
+ // start tag
+ const XS_String& tag = buffer.get_tag();
+
+ if (!tag.empty()) {
+ XMLNode::AttributeMap attributes;
+ buffer.get_attributes(attributes);
+
+ StartElementHandler(tag, attributes);
+
+ if (str[b.length()-2] == '/')
+ EndElementHandler();
+ }
+
+ c = get();
+ }
+ } else {
+ buffer.append(c);
+
+ // read white space
+ for(;;) {
+ // check for the encoding of the first line end
+ if (!_endl_defined)
+ if (c == '\n') {
+ _format._endl = "\n";
+ _endl_defined = true;
+ } else if (c == '\r') {
+ _format._endl = "\r\n";
+ _endl_defined = true;
+ }
+
+ c = get();
+
+ if (c == EOF)
+ break;
+
+ if (c == '<')
+ break;
+
+ buffer.append(c);
+ }
+
+ DefaultHandler(buffer.str(_utf8));
+ }
+
+ buffer.reset();
+ }
+
+ return true;
+}
+
+int XMLReaderBase::eat_endl()
+{
+ int c = get();
+
+ if (c == '\r')
+ c = get();
+
+ if (c == '\n')
+ c = get();
+
+ return c;
+}
+
+ /// return current parser position as string
+std::string XMLReaderBase::get_position() const
+{
+/*@TODO display parser position in case of errors
+ int line = XML_GetCurrentLineNumber(_parser);
+ int column = XML_GetCurrentColumnNumber(_parser);
+
+ std::ostringstream out;
+ out << "(" << line << ") : [column " <<
column << "]";
+
+ return out.str();
+*/
+ return "";
+}
+
+
+#ifdef XMLNODE_LOCATION
+
+XMLLocation XMLReaderBase::get_location() const
+{
+ return XMLLocation(); //@TODO XMLLocation for XS-native
+}
+
+std::string XMLLocation::str() const
+{
+ return ""; //TODO
+}
+
+#endif
+
+
+ /// store content, white space and comments
+void XMLReaderBase::DefaultHandler(const std::string& s)
+{
+ _content.append(s);
+}
+
+
+} // namespace XMLStorage
+
+#endif // !defined(XS_USE_EXPAT) && !defined(XS_USE_XERCES)
Propchange: trunk/reactos/base/applications/ibrowser/utility/xs-native.cpp
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: trunk/reactos/base/applications/ibrowser/utility/xs-native.cpp
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision