Author: martinf
Date: Tue Aug 1 03:21:55 2006
New Revision: 23397
URL:
http://svn.reactos.org/svn/reactos?rev=23397&view=rev
Log:
Explorer: update XMLStorage library and remove Expat dependency
Added:
trunk/reactos/base/shell/explorer/utility/xs-native.cpp (with props)
Removed:
trunk/reactos/base/shell/explorer/expat-license.txt
Modified:
trunk/reactos/base/shell/explorer/Jamfile
trunk/reactos/base/shell/explorer/Make-rosshell-MinGW
trunk/reactos/base/shell/explorer/Make-rosshell.mak
trunk/reactos/base/shell/explorer/Makefile-MinGW
trunk/reactos/base/shell/explorer/Makefile-Wine
trunk/reactos/base/shell/explorer/Makefile-precomp
trunk/reactos/base/shell/explorer/explorer.cpp
trunk/reactos/base/shell/explorer/explorer.dsp
trunk/reactos/base/shell/explorer/explorer.rbuild
trunk/reactos/base/shell/explorer/make_explorer.dsp
trunk/reactos/base/shell/explorer/taskbar/favorites.cpp
trunk/reactos/base/shell/explorer/taskbar/startmenu.cpp
trunk/reactos/base/shell/explorer/utility/xmlstorage.cpp
trunk/reactos/base/shell/explorer/utility/xmlstorage.h
Modified: trunk/reactos/base/shell/explorer/Jamfile
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/shell/explorer/Jamfil…
==============================================================================
--- trunk/reactos/base/shell/explorer/Jamfile (original)
+++ trunk/reactos/base/shell/explorer/Jamfile Tue Aug 1 03:21:55 2006
@@ -6,8 +6,6 @@
# import rc ;
import rc-mingw ;
-
-EXPAT_INC = [ modules.peek : EXPAT_INC ] ;
exe explorer :
explorer.cpp
@@ -44,7 +42,7 @@
dialogs/settings.cpp
i386-stub-win32.c
: <define>WIN32 <define>_WIN32_IE=0x0600 <define>_WIN32_WINNT=0x0501
<define>WINVER=0x0500
- <include>. <include>$(EXPAT_INC)
+ <include>.
# only for GCC: <cxxflags>-fexceptions <cxxflags>-Wall
<cxxflags>-Wno-unused-value
<find-shared-library>gdi32
<find-shared-library>ole32
@@ -53,8 +51,6 @@
<find-shared-library>wsock32
<find-shared-library>oleaut32
<find-shared-library>msimg32
-# <find-shared-library>expat
<linkflags>notifyhook.dll
- <linkflags>libexpat.dll
;
Modified: trunk/reactos/base/shell/explorer/Make-rosshell-MinGW
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/shell/explorer/Make-r…
==============================================================================
--- trunk/reactos/base/shell/explorer/Make-rosshell-MinGW (original)
+++ trunk/reactos/base/shell/explorer/Make-rosshell-MinGW Tue Aug 1 03:21:55 2006
@@ -10,7 +10,7 @@
CXX = g++
LINK = g++
-CFLAGS = -DWIN32 -DROSSHELL -D_WIN32_IE=0x0600 -D_WIN32_WINNT=0x0501 -DWINVER=0x0500
-fexceptions -Wall -I. -I$(EXPAT_INC)
+CFLAGS = -DWIN32 -DROSSHELL -D_WIN32_IE=0x0600 -D_WIN32_WINNT=0x0501 -DWINVER=0x0500
-fexceptions -Wall -I.
RCFLAGS = -DWIN32 -DROSSHELL -D__WINDRES__
LFLAGS = -Wl,--subsystem,windows
@@ -68,7 +68,8 @@
searchprogram.o \
settings.o \
i386-stub-win32.o \
- xmlstorage.o
+ xmlstorage.o \
+ xs-native.o
LIBS = gdi32 comctl32 msimg32 ole32 uuid
DELAYIMPORTS = oleaut32 wsock32
@@ -78,7 +79,7 @@
precomp.h.gch: *.h utility/*.h shell/*.h desktop/*.h
$(CXX) $(CFLAGS) precomp.h
-$(TARGET): $(OBJECTS) $(PROGRAM)$(RES_SUFFIX) notifyhook.dll libexpat.dll
+$(TARGET): $(OBJECTS) $(PROGRAM)$(RES_SUFFIX) notifyhook.dll
$(LINK) $(LFLAGS) -o $@ $^ $(addprefix -l,$(LIBS)) $(addprefix -l,$(DELAYIMPORTS))
$(PROGRAM)$(RES_SUFFIX): explorer_intres.rc res/*.bmp res/*.ico
Modified: trunk/reactos/base/shell/explorer/Make-rosshell.mak
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/shell/explorer/Make-r…
==============================================================================
--- trunk/reactos/base/shell/explorer/Make-rosshell.mak (original)
+++ trunk/reactos/base/shell/explorer/Make-rosshell.mak Tue Aug 1 03:21:55 2006
@@ -17,15 +17,14 @@
TARGET_CFLAGS := \
-D__USE_W32API -DWIN32 -D_ROS_ \
-D_WIN32_IE=0x0600 -D_WIN32_WINNT=0x0501 -DWINVER=0x0500 \
- -DUNICODE -fexceptions -Wall -g \
- -I../../../include/expat
+ -DUNICODE -fexceptions -Wall -g
TARGET_CPPFLAGS := $(TARGET_CFLAGS)
TARGET_RCFLAGS := -D__USE_W32API -DWIN32 -D_ROS_ -D__WINDRES__
TARGET_SDKLIBS := \
- gdi32.a user32.a comctl32.a ole32.a oleaut32.a shell32.a expat.a \
+ gdi32.a user32.a comctl32.a ole32.a oleaut32.a shell32.a \
notifyhook.a ws2_32.a msimg32.a
TARGET_GCCLIBS := stdc++ uuid
@@ -53,7 +52,8 @@
utility/window.o \
utility/dragdropimpl.o \
utility/shellbrowserimpl.o \
- utility/xmlstorage.o
+ utility/xmlstorage.o \
+ utility/xs-native.o
TARGET_CPPAPP := yes
Modified: trunk/reactos/base/shell/explorer/Makefile-MinGW
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/shell/explorer/Makefi…
==============================================================================
--- trunk/reactos/base/shell/explorer/Makefile-MinGW (original)
+++ trunk/reactos/base/shell/explorer/Makefile-MinGW Tue Aug 1 03:21:55 2006
@@ -9,7 +9,7 @@
LINK = g++
# -D_NO_ALPHABLEND for builds without msimg32.dll dependency
-CFLAGS = -DWIN32 -D_WIN32_IE=0x0600 -D_WIN32_WINNT=0x0501 -DWINVER=0x0500 -fexceptions
-Wall -I. -I$(EXPAT_INC)
+CFLAGS = -DWIN32 -D_WIN32_IE=0x0600 -D_WIN32_WINNT=0x0501 -DWINVER=0x0500 -fexceptions
-Wall -I.
RCFLAGS = -DWIN32 -D__WINDRES__
LFLAGS = -Wl,--subsystem,windows
@@ -75,14 +75,15 @@
searchprogram.o \
settings.o \
i386-stub-win32.o \
- xmlstorage.o
+ xmlstorage.o \
+ xs-native.o
LIBS = gdi32 comctl32 msimg32 ole32 uuid
DELAYIMPORTS = oleaut32 wsock32
all: $(TARGET)
-$(TARGET): $(OBJECTS) $(PROGRAM)$(RES_SUFFIX) notifyhook.dll libexpat.dll
+$(TARGET): $(OBJECTS) $(PROGRAM)$(RES_SUFFIX) notifyhook.dll
$(LINK) $(LFLAGS) -o $@ $^ $(addprefix -l,$(LIBS)) $(addprefix -l,$(DELAYIMPORTS))
$(PROGRAM)$(RES_SUFFIX): $(PROGRAM)_intres.rc res/*.bmp res/*.ico
Modified: trunk/reactos/base/shell/explorer/Makefile-Wine
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/shell/explorer/Makefi…
==============================================================================
--- trunk/reactos/base/shell/explorer/Makefile-Wine (original)
+++ trunk/reactos/base/shell/explorer/Makefile-Wine Tue Aug 1 03:21:55 2006
@@ -6,7 +6,7 @@
APPMODE = gui
IMPORTS = shell32 comctl32 msimg32 ole32 user32 gdi32 kernel32 advapi32 oleaut32
EXTRADEFS = -D__WINE__ -D_WIN32_IE=0x0600 -D_WIN32_WINNT=0x0501 -DWINVER=0x0500
-D__MINGW32__ -DCINTERFACE
-EXTRA_OBJS = notifyhook.dll libexpat.dll
+EXTRA_OBJS = notifyhook.dll
EXTRALIBS = $(LIBUUID)
C_SRCS = \
@@ -22,6 +22,8 @@
utility/dragdropimpl.cpp \
utility/shellbrowserimpl.cpp \
utility/xmlstorage.cpp \
+ utility/xmlstorage.cpp \
+ utility/xs-native.cpp
shell/entries.cpp \
shell/winfs.cpp \
shell/unixfs.cpp \
Modified: trunk/reactos/base/shell/explorer/Makefile-precomp
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/shell/explorer/Makefi…
==============================================================================
--- trunk/reactos/base/shell/explorer/Makefile-precomp (original)
+++ trunk/reactos/base/shell/explorer/Makefile-precomp Tue Aug 1 03:21:55 2006
@@ -10,7 +10,7 @@
CXX = g++
LINK = g++
-CFLAGS = -DWIN32 -D_WIN32_IE=0x0600 -D_WIN32_WINNT=0x0501 -DWINVER=0x0500 -fexceptions
-Wall -I. -I$(EXPAT_INC)
+CFLAGS = -DWIN32 -D_WIN32_IE=0x0600 -D_WIN32_WINNT=0x0501 -DWINVER=0x0500 -fexceptions
-Wall -I.
RCFLAGS = -DWIN32 -D__WINDRES__
LFLAGS = -Wl,--subsystem,windows
@@ -76,7 +76,8 @@
searchprogram.o \
settings.o \
i386-stub-win32.o \
- xmlstorage.o
+ xmlstorage.o \
+ xs-native.o
LIBS = gdi32 comctl32 msimg32 ole32 uuid
DELAYIMPORTS = oleaut32 wsock32
@@ -86,7 +87,7 @@
precomp.h.gch: *.h utility/*.h shell/*.h desktop/*.h
$(CXX) $(CFLAGS) precomp.h
-$(TARGET): $(OBJECTS) $(PROGRAM)$(RES_SUFFIX) notifyhook.dll libexpat.dll
+$(TARGET): $(OBJECTS) $(PROGRAM)$(RES_SUFFIX) notifyhook.dll
$(LINK) $(LFLAGS) -o $@ $^ $(addprefix -l,$(LIBS)) $(addprefix -l,$(DELAYIMPORTS))
$(PROGRAM)$(RES_SUFFIX): explorer_intres.rc res/*.bmp res/*.ico
Removed: trunk/reactos/base/shell/explorer/expat-license.txt
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/shell/explorer/expat-…
==============================================================================
--- trunk/reactos/base/shell/explorer/expat-license.txt (original)
+++ trunk/reactos/base/shell/explorer/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/shell/explorer/explorer.cpp
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/shell/explorer/explor…
==============================================================================
--- trunk/reactos/base/shell/explorer/explorer.cpp (original)
+++ trunk/reactos/base/shell/explorer/explorer.cpp Tue Aug 1 03:21:55 2006
@@ -1,5 +1,5 @@
/*
- * Copyright 2003, 2004, 2005 Martin Fuchs
+ * Copyright 2003, 2004, 2005, 2006 Martin Fuchs
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -94,9 +94,9 @@
_cfg_path.printf(TEXT("%s\\ros-explorer-cfg.xml"), _cfg_dir.c_str());
if (!_cfg.read(_cfg_path)) {
- if (_cfg._last_error != XML_ERROR_NO_ELEMENTS)
- MessageBox(_hwndDesktop, String(_cfg._last_error_msg.c_str()),
- TEXT("ROS Explorer - reading user settings"), MB_OK);
+ //if (_cfg._last_error != XML_ERROR_NO_ELEMENTS)
+ MessageBox(_hwndDesktop, _cfg._errors.str(),
+ TEXT("ROS Explorer - reading user settings"), MB_OK);
_cfg.read(TEXT("explorer-cfg-template.xml"));
}
Modified: trunk/reactos/base/shell/explorer/explorer.dsp
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/shell/explorer/explor…
==============================================================================
--- trunk/reactos/base/shell/explorer/explorer.dsp (original)
+++ trunk/reactos/base/shell/explorer/explorer.dsp Tue Aug 1 03:21:55 2006
@@ -310,6 +310,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/shell/explorer/explorer.rbuild
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/shell/explorer/explor…
==============================================================================
--- trunk/reactos/base/shell/explorer/explorer.rbuild (original)
+++ trunk/reactos/base/shell/explorer/explorer.rbuild Tue Aug 1 03:21:55 2006
@@ -22,7 +22,6 @@
<library>ole32</library>
<library>oleaut32</library>
<library>shell32</library>
- <library>expat</library>
<library>notifyhook</library>
<pch>precomp.h</pch>
<directory name="desktop">
@@ -65,6 +64,7 @@
<file>dragdropimpl.cpp</file>
<file>shellbrowserimpl.cpp</file>
<file>xmlstorage.cpp</file>
+ <file>xs-native.cpp</file>
</directory>
<file>explorer.cpp</file>
<file>i386-stub-win32.c</file>
Modified: trunk/reactos/base/shell/explorer/make_explorer.dsp
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/shell/explorer/make_e…
==============================================================================
--- trunk/reactos/base/shell/explorer/make_explorer.dsp (original)
+++ trunk/reactos/base/shell/explorer/make_explorer.dsp Tue Aug 1 03:21:55 2006
@@ -45,7 +45,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.exe -f Makefile-precomp UNICODE=0"
# PROP Rebuild_Opt "clean all"
# PROP Target_File "explorer.exe"
# PROP Bsc_Name ""
@@ -66,7 +66,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.exe -f Makefile-precomp UNICODE=0 DEBUG=1"
# PROP Rebuild_Opt "clean all"
# PROP Target_File "explorer.exe"
# PROP Bsc_Name "msdevfilt -gcc -pipe "perl d:\tools\gSTLFilt.pl" make -f
Makefile.MinGW UNICODE=0 DEBUG=1"
@@ -87,7 +87,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.exe -f Makefile.MinGW UNICODE=1 DEBUG=1"
# PROP Rebuild_Opt "clean all"
# PROP Target_File "explorer.exe"
# PROP Bsc_Name ""
@@ -108,7 +108,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.exe -f Makefile-precomp
UNICODE=1"
# PROP Rebuild_Opt "clean all"
# PROP Target_File "explorer.exe"
# PROP Bsc_Name ""
Modified: trunk/reactos/base/shell/explorer/taskbar/favorites.cpp
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/shell/explorer/taskba…
==============================================================================
--- trunk/reactos/base/shell/explorer/taskbar/favorites.cpp (original)
+++ trunk/reactos/base/shell/explorer/taskbar/favorites.cpp Tue Aug 1 03:21:55 2006
@@ -1,5 +1,5 @@
/*
- * Copyright 2004 Martin Fuchs
+ * Copyright 2004, 2006 Martin Fuchs
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -426,12 +426,10 @@
{
XMLDoc xbel;
- if (!xbel.read(path))
- if (xbel._last_error == XML_ERROR_NO_ELEMENTS)
- return false;
- else
- MessageBox(g_Globals._hwndDesktop, String(xbel._last_error_msg.c_str()),
- TEXT("ROS Explorer - reading bookmark file"), MB_OK);
+ if (!xbel.read(path)) {
+ MessageBox(g_Globals._hwndDesktop, xbel._errors.str(),
+ TEXT("ROS Explorer - reading bookmark file"), MB_OK);
+ }
const_XMLPos pos(&xbel);
@@ -455,9 +453,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/shell/explorer/taskbar/startmenu.cpp
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/shell/explorer/taskba…
==============================================================================
--- trunk/reactos/base/shell/explorer/taskbar/startmenu.cpp (original)
+++ trunk/reactos/base/shell/explorer/taskbar/startmenu.cpp Tue Aug 1 03:21:55 2006
@@ -416,7 +416,7 @@
int new_id = ButtonHitTest(pt);
- if (new_id > 0 && new_id != _selected_id)
+ if (new_id>0 && new_id!=_selected_id)
SelectButton(new_id);
_last_mouse_pos = lparam;
@@ -707,13 +707,13 @@
for(;;) {
idx += step;
- if ((int)_buttons.size() <= 1 && (idx<0 || idx>(int)_buttons.size()))
+ if (_buttons.size()<=1 && (idx<0 || idx>(int)_buttons.size()))
break;
- if (idx<0)
+ if (idx < 0)
idx += _buttons.size();
- if (idx>(int)_buttons.size())
+ if (idx > (int)_buttons.size())
idx -= _buttons.size()+1;
if (SelectButtonIndex(idx, false))
Modified: trunk/reactos/base/shell/explorer/utility/xmlstorage.cpp
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/shell/explorer/utilit…
==============================================================================
--- trunk/reactos/base/shell/explorer/utility/xmlstorage.cpp (original)
+++ trunk/reactos/base/shell/explorer/utility/xmlstorage.cpp Tue Aug 1 03:21:55 2006
@@ -36,8 +36,8 @@
*/
-#ifndef _NO_COMMENT
-#define _NO_COMMENT // no #pragma comment(lib, ...) statements in .lib files
+#ifndef XS_NO_COMMENT
+#define XS_NO_COMMENT // no #pragma comment(lib, ...) statements in .lib files
#endif
//#include "xmlstorage.h"
@@ -46,6 +46,7 @@
// work around GCC's wide string constant bug
#ifdef __GNUC__
+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;
@@ -57,7 +58,7 @@
/// remove escape characters from zero terminated string
-static std::string unescape(const char* s, char b='"', char
e='"')
+static std::string unescape(const char* s, char b, char e)
{
const char* end = s + strlen(s);
@@ -74,8 +75,13 @@
return std::string(s, end-s);
}
+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, int l, char b='"', char
e='"')
+static std::string unescape(const char* s, size_t l, char b, char e)
{
const char* end = s + l;
@@ -90,6 +96,11 @@
++s, --end;
return std::string(s, end-s);
+}
+
+inline std::string unescape(const char* s, size_t l)
+{
+ return unescape(s, l, '"', '"');
}
@@ -205,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;
@@ -270,46 +281,106 @@
std::string EncodeXMLString(const XS_String& str)
{
LPCXSSTR s = str.c_str();
- 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;
- }
+ 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);
+ return XS_String(buffer, o-buffer);
#else
- return get_utf8(buffer, o-buffer);
+ 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
+ */
+ }
}
/// decode XML string literals
@@ -338,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;
@@ -367,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;
@@ -378,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--; )
@@ -413,7 +514,7 @@
out << '>';
if (_content.empty())
- out << '\n';
+ out << format._endl;
else
out << _content;
@@ -421,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--; )
@@ -435,181 +536,150 @@
}
if (_trailing.empty())
- out << '\n';
+ out << format._endl;
else
out << _trailing;
}
- /// read XML stream into XML tree below _pos
-XML_Status XMLReaderBase::read()
-{
- XML_Status status = XML_STATUS_OK;
-
- do {
- char* buffer = (char*) XML_GetBuffer(_parser, BUFFER_LEN);
-
- size_t l = read_buffer(buffer, BUFFER_LEN);
- if ((int)l < 0)
- break;
-
- status = XML_ParseBuffer(_parser, l, false);
- } while(status == XML_STATUS_OK);
-
- if (status != XML_STATUS_ERROR)
- status = XML_ParseBuffer(_parser, 0, true);
-
- finish_read();
-
- return status;
-}
-
-
- /// return current parser position as string
-std::string XMLReaderBase::get_position() const
-{
- int line = XML_GetCurrentLineNumber(_parser);
- int column = XML_GetCurrentColumnNumber(_parser);
-
+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 << "(" << line << ") : [column " <<
column << "]";
+
+ out << *this;
return out.str();
}
-#ifdef XMLNODE_LOCATION
-
-XMLLocation XMLReaderBase::get_location() const
-{
- int line = XML_GetCurrentLineNumber(_parser);
- int column = XML_GetCurrentColumnNumber(_parser);
-
- return XMLLocation(_display_path, line, column);
-}
-
-std::string XMLLocation::str() const
+ /// return merged error strings
+XS_String XMLErrorList::str() const
{
std::ostringstream out;
- if (_pdisplay_path)
- out << _pdisplay_path;
-
- out << "(" << _line << ") : [column " <<
_column << "]";
-
- return out.str();
-}
-
-#endif
-
-
- /// return current error code from Expat
-XML_Error XMLReaderBase::get_error_code() const
-{
- return XML_GetErrorCode(_parser);
-}
-
-
- /// 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;
-
- pReader->XmlDeclHandler(version, encoding, standalone);
-}
-
- /// notifications about XML start tag
-void XMLCALL XMLReaderBase::XML_StartElementHandler(void* userData, const XML_Char* name,
const XML_Char** atts)
-{
- XMLReaderBase* pReader = (XMLReaderBase*) userData;
-
- XMLNode::AttributeMap attributes;
-
- while(*atts) {
- const XML_Char* attr_name = *atts++;
- const XML_Char* attr_value = *atts++;
-
- attributes[String_from_XML_Char(attr_name)] = String_from_XML_Char(attr_value);
- }
-
- pReader->StartElementHandler(String_from_XML_Char(name), attributes);
-}
-
- /// notifications about XML end tag
-void XMLCALL XMLReaderBase::XML_EndElementHandler(void* userData, const XML_Char* name)
-{
- XMLReaderBase* pReader = (XMLReaderBase*) userData;
-
- pReader->EndElementHandler();
-}
-
- /// store content, white space and comments
-void XMLCALL XMLReaderBase::XML_DefaultHandler(void* userData, const XML_Char* s, int
len)
-{
- XMLReaderBase* pReader = (XMLReaderBase*) userData;
-
- pReader->DefaultHandler(s, len);
-}
-
-
- /// return error strings for Expat errors
-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;
+ for(const_iterator it=begin(); it!=end(); ++it)
+ out << *it << std::endl;
return out.str();
}
@@ -627,13 +697,15 @@
/// store XML version and encoding into XML reader
-void XMLReaderBase::XmlDeclHandler(const XML_Char* version, const XML_Char* encoding, int
standalone)
+void XMLReaderBase::XmlDeclHandler(const char* version, const char* encoding, int
standalone)
{
if (version)
- _xml_version = version;
+ _format._version = version;
if (encoding)
- _encoding = encoding;
+ _format._encoding = encoding;
+
+ _format._standalone = standalone;
}
@@ -657,7 +729,8 @@
_pos->_content.append(s, p-s);
else if (_last_tag == TAG_END)
_pos->_trailing.append(s, p-s);
- // else TAG_NONE -> don't store white space in root node
+ else // TAG_NONE at root node
+ p = s;
} else
_pos->_children.back()->_trailing.append(s, p-s);
@@ -712,13 +785,20 @@
_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/shell/explorer/utility/xmlstorage.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/shell/explorer/utilit…
==============================================================================
--- trunk/reactos/base/shell/explorer/utility/xmlstorage.h (original)
+++ trunk/reactos/base/shell/explorer/utility/xmlstorage.h Tue Aug 1 03:21:55 2006
@@ -48,24 +48,29 @@
#endif
-#ifndef _NO_EXPAT
-
-//#include "expat.h"
+#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>
-
-#else
-
-typedef char XML_Char;
-
-enum XML_Status {
- XML_STATUS_ERROR = 0,
- XML_STATUS_OK = 1
-};
-
-enum XML_Error {
- XML_ERROR_NONE,
- XML_ERROR_FAILURE
-};
#endif
@@ -73,8 +78,15 @@
#ifdef _MSC_VER
#pragma warning(disable: 4786)
-#ifndef _NO_COMMENT
-#ifndef _NO_EXPAT
+#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")
@@ -84,7 +96,7 @@
#endif
#endif
-#ifndef _STRING_DEFINED // _STRING_DEFINED only allowed if using xmlstorage.cpp embedded
in the project
+#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")
@@ -111,7 +123,7 @@
#endif
#endif // _STRING_DEFINED
-#endif // _NO_COMMENT
+#endif // XS_NO_COMMENT
#endif // _MSC_VER
@@ -150,29 +162,35 @@
#ifndef XS_String
#ifdef XS_STRING_UTF8
-#define XS_CHAR char
-#define XS_TEXT(x) x
+#define XS_CHAR char
+#define XS_TEXT(x) x
#define LPXSSTR LPSTR
#define LPCXSSTR LPCSTR
-#define XS_icmp stricmp
-#define XS_nicmp strnicmp
-#define XS_toi atoi
-#define XS_tod strtod
-#define XS_len strlen
-#define XS_snprintf snprintf
-#define XS_vsnprintf vsnprintf
-#else
-#define XS_CHAR TCHAR
-#define XS_TEXT(x) TEXT(x)
+#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_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_icmp _tcsicmp
-#define XS_nicmp _tcsnicmp
-#define XS_toi _ttoi
-#define XS_tod _tcstod
-#define XS_len _tcslen
-#define XS_snprintf _sntprintf
-#define XS_vsnprintf _vsntprintf
+#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_snprintf _sntprintf
+#define XS_vsnprintf _vsntprintf
+#define XS_strstr _tcsstr
#endif
#ifndef COUNTOF
@@ -183,9 +201,16 @@
#endif
#endif
+
+int inline isxmlsym(unsigned char c)
+{
+ return isalnum(c) || c=='_' || c=='-';
+}
+
+
#if defined(_STRING_DEFINED) && !defined(XS_STRING_UTF8)
-#define XS_String String
+#define XS_String String
#else // _STRING_DEFINED, !XS_STRING_UTF8
@@ -297,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 = (int)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);
@@ -317,6 +363,13 @@
s.assign(buffer, 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
@@ -333,6 +386,21 @@
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());
@@ -355,7 +423,7 @@
{
FileHolder(LPCTSTR path, LPCTSTR mode)
{
-#ifdef __STDC_WANT_SECURE_LIB__ // secure CRT functions using VS 2005
+#ifdef __STDC_WANT_SECURE_LIB__ // secure CRT functions using VS 2005
if (_tfopen_s(&_pfile, path, mode) != 0)
_pfile = NULL;
#else
@@ -400,7 +468,7 @@
tofstream(LPCTSTR path)
: super(&_buf),
- FileHolder(path, TEXT("w")),
+ FileHolder(path, TEXT("wb")),
#ifdef __GNUC__
_buf(_pfile, std::ios::out)
#else
@@ -423,17 +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 strings to XMLStorage internal strings
+ /// 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)
@@ -443,6 +511,8 @@
};
#endif
+
+#endif // defined(XS_USE_XERCES) || defined(XS_USE_EXPAT)
#if defined(UNICODE) && !defined(XS_STRING_UTF8)
@@ -461,6 +531,32 @@
};
#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
@@ -484,11 +580,103 @@
std::string str() const;
protected:
- const char* _pdisplay_path; // character pointer for fast reference
- int _line;
- int _column;
-};
-#endif
+ 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
@@ -518,9 +706,30 @@
{
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;
+ 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
@@ -631,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
@@ -717,7 +926,7 @@
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());
@@ -732,18 +941,16 @@
const XMLLocation& get_location() const {return _location;}
#endif
- 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
- };
-
/// 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:
@@ -751,7 +958,7 @@
break;
default: // FORMAT_SMART
- smart_write_worker(out, indent);
+ smart_write_worker(out, format, indent);
}
return out;
@@ -761,13 +968,13 @@
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;
+ XMLLocation _location;
#endif
XMLNode* get_first_child() const
@@ -838,8 +1045,9 @@
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 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;
};
@@ -1371,25 +1579,6 @@
};
-#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_TRUE;
-extern const LPCXSSTR XS_FALSE;
-extern const LPCXSSTR XS_INTFMT;
-extern const LPCXSSTR XS_FLOATFMT;
-#else
-#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
-
-
/// type converter for boolean data
struct XMLBool
{
@@ -1650,7 +1839,7 @@
{
}
- XMLString(LPCXSSTR value, LPCXSSTR def=XS_TEXT(""))
+ XMLString(LPCXSSTR value, LPCXSSTR def=XS_EMPTY)
{
if (value && *value)
_value = value;
@@ -1658,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);
@@ -1688,14 +1877,14 @@
/// 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())
@@ -1749,65 +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();
-
- std::string get_position() const;
- std::string get_instructions() const {return _instructions;}
-
- XML_Error get_error_code() const;
- std::string get_error_string() const;
-
-#ifdef XMLNODE_LOCATION
- const char* _display_path; // character pointer for fast reference in XMLLocation
-
- XMLLocation get_location() const;
-#endif
-
- virtual int read_buffer(char* buffer, int len) = 0;
+#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;
-
- void finish_read();
-
- virtual void XmlDeclHandler(const XML_Char* version, const XML_Char* encoding, int
standalone);
- virtual void StartElementHandler(const XS_String& name, const
XMLNode::AttributeMap& attributes);
- virtual void EndElementHandler();
- virtual void DefaultHandler(const XML_Char* s, int len);
-
- 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)
@@ -1816,105 +2115,80 @@
{
}
- /// 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;
};
-
- /// Management of XML file headers
-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, bool pretty=true) const
- {
- out << "<?xml version=\"" << _version <<
"\" encoding=\"" << _encoding <<
"\"?>";
-
- if (pretty)
- out << std::endl;
-
- 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);
}
- bool read(std::istream& in)
- {
- XMLReader reader(this, in);
-
- return read(reader);
- }
+#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)
{
@@ -1923,29 +2197,28 @@
_display_path = display_path;
reader._display_path = _display_path.c_str();
#endif
- 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;
+
+ 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;
}
@@ -1956,26 +2229,25 @@
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;
+ std::string _display_path;
#endif
};
@@ -1989,37 +2261,74 @@
_pos.create(name);
}
+ std::string toString() const
+ {
+ std::ostringstream out;
+
+ write(out);
+
+ return out.str();
+ }
+
XMLPos _pos;
-};
-
-
-enum PRETTY_FLAGS {
- PRETTY_PLAIN = 0,
- PRETTY_LINEFEED = 1,
- PRETTY_INDENT = 2
-};
+
+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, PRETTY_FLAGS pretty=PRETTY_INDENT, const XMLHeader&
header=XMLHeader())
+ XMLWriter(std::ostream& out, const XMLFormat& format=XMLFormat())
: _pofstream(NULL),
_out(out),
- _pretty(pretty)
- {
- header.print(_out, false);
- }
-
- XMLWriter(LPCTSTR path, PRETTY_FLAGS pretty=PRETTY_INDENT, const XMLHeader&
header=XMLHeader())
+ _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),
- _pretty(pretty)
- {
- header.print(_out, false);
+ _format(format)
+ {
+ format.print_header(_out, false); // _format._endl is printed in write_pre()
}
~XMLWriter()
{
- _out << std::endl;
+ _out << _format._endl;
delete _pofstream;
}
@@ -2086,14 +2395,14 @@
protected:
tofstream* _pofstream;
std::ostream& _out;
- PRETTY_FLAGS _pretty;
+ const XMLFormat&_format;
typedef XMLNode::AttributeMap AttrMap;
struct StackEntry {
XS_String _node_name;
- AttrMap _attributes;
- std::string _content;
+ AttrMap _attributes;
+ std::string _content;
WRITESTATE _state;
bool _children;
@@ -2113,10 +2422,10 @@
void write_pre(StackEntry& entry)
{
- if (_pretty >= PRETTY_LINEFEED)
- _out << std::endl;
-
- if (_pretty == PRETTY_INDENT)
+ 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;
@@ -2144,10 +2453,10 @@
_out << entry._content;
//entry._state = CONTENT;
- if (_pretty>=PRETTY_LINEFEED && entry._content.empty())
- _out << std::endl;
-
- if (_pretty==PRETTY_INDENT && entry._content.empty())
+ 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;
Added: trunk/reactos/base/shell/explorer/utility/xs-native.cpp
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/shell/explorer/utilit…
==============================================================================
--- trunk/reactos/base/shell/explorer/utility/xs-native.cpp (added)
+++ trunk/reactos/base/shell/explorer/utility/xs-native.cpp Tue Aug 1 03:21:55 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/shell/explorer/utility/xs-native.cpp
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: trunk/reactos/base/shell/explorer/utility/xs-native.cpp
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision