[ros-diffs] [martinf] 23397: Explorer: update XMLStorage library and remove Expat dependency

martinf at svn.reactos.org martinf at svn.reactos.org
Tue Aug 1 01:21:57 CEST 2006


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/Jamfile?rev=23397&r1=23396&r2=23397&view=diff
==============================================================================
--- 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-rosshell-MinGW?rev=23397&r1=23396&r2=23397&view=diff
==============================================================================
--- 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-rosshell.mak?rev=23397&r1=23396&r2=23397&view=diff
==============================================================================
--- 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/Makefile-MinGW?rev=23397&r1=23396&r2=23397&view=diff
==============================================================================
--- 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/Makefile-Wine?rev=23397&r1=23396&r2=23397&view=diff
==============================================================================
--- 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/Makefile-precomp?rev=23397&r1=23396&r2=23397&view=diff
==============================================================================
--- 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-license.txt?rev=23396&view=auto
==============================================================================
--- 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/explorer.cpp?rev=23397&r1=23396&r2=23397&view=diff
==============================================================================
--- 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/explorer.dsp?rev=23397&r1=23396&r2=23397&view=diff
==============================================================================
--- 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/explorer.rbuild?rev=23397&r1=23396&r2=23397&view=diff
==============================================================================
--- 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_explorer.dsp?rev=23397&r1=23396&r2=23397&view=diff
==============================================================================
--- 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/taskbar/favorites.cpp?rev=23397&r1=23396&r2=23397&view=diff
==============================================================================
--- 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/taskbar/startmenu.cpp?rev=23397&r1=23396&r2=23397&view=diff
==============================================================================
--- 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/utility/xmlstorage.cpp?rev=23397&r1=23396&r2=23397&view=diff
==============================================================================
--- 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 "&quot;" / "&apos;"
-	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 "&quot;" / "&apos;"
+		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 << "&amp;";
+				break;
+
+			  case '<':
+				out << "&lt;";
+				break;
+
+			  case '>':
+				out << "&gt;";
+				break;
+
+			  case '"':
+				out << "&quot;";
+				break;
+
+			  case '\'':
+				out << "&apos;";
+				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/utility/xmlstorage.h?rev=23397&r1=23396&r2=23397&view=diff
==============================================================================
--- 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/utility/xs-native.cpp?rev=23397&view=auto
==============================================================================
--- 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 at 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




More information about the Ros-diffs mailing list