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... ============================================================================== --- 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-ro... ============================================================================== --- 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-ro... ============================================================================== --- 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/Makefil... ============================================================================== --- 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/Makefil... ============================================================================== --- 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/Makefil... ============================================================================== --- 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-l... ============================================================================== --- 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/explore... ============================================================================== --- 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/explore... ============================================================================== --- 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/explore... ============================================================================== --- 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_ex... ============================================================================== --- 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... ============================================================================== --- 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... ============================================================================== --- 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... ============================================================================== --- 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/utility... ============================================================================== --- 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... ============================================================================== --- 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@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