From 9b2636d3cbd6159d86db657aba5c1d8725814970 Mon Sep 17 00:00:00 2001 From: Ingo Randolf Date: Sun, 31 May 2015 14:50:55 +0200 Subject: [PATCH 1/2] update pugixml to version 1.6, remove glut - using glfw, make it compile for 64bit --- projectGenerator.xcodeproj/project.pbxproj | 52 +- src/main.cpp | 23 +- src/pugixmlLib/Jamfile.jam | 167 - src/pugixmlLib/Jamrules.jam | 807 -- src/pugixmlLib/contrib/foreach.hpp | 51 +- src/pugixmlLib/lib/libpugixml_d.a | Bin 1480680 -> 0 bytes src/pugixmlLib/readme.txt | 6 +- src/pugixmlLib/scripts/CMakeLists.txt | 33 +- src/pugixmlLib/scripts/premake4.lua | 30 +- .../scripts/pugixml.xcodeproj/project.pbxproj | 85 +- src/pugixmlLib/scripts/pugixml_airplay.mkf | 13 + src/pugixmlLib/scripts/pugixml_codeblocks.cbp | 4 +- .../scripts/pugixml_codelite.project | 6 +- src/pugixmlLib/scripts/pugixml_vs2005.vcproj | 8 +- .../scripts/pugixml_vs2005_static.vcproj | 24 +- src/pugixmlLib/scripts/pugixml_vs2008.vcproj | 8 +- .../scripts/pugixml_vs2008_static.vcproj | 24 +- src/pugixmlLib/scripts/pugixml_vs2010.vcxproj | 348 +- .../scripts/pugixml_vs2010_static.vcxproj | 350 +- src/pugixmlLib/src/pugiconfig.hpp | 19 +- src/pugixmlLib/src/pugixml.cpp | 6474 +++++++++++------ src/pugixmlLib/src/pugixml.hpp | 601 +- 22 files changed, 5216 insertions(+), 3917 deletions(-) delete mode 100644 src/pugixmlLib/Jamfile.jam delete mode 100644 src/pugixmlLib/Jamrules.jam delete mode 100644 src/pugixmlLib/lib/libpugixml_d.a create mode 100644 src/pugixmlLib/scripts/pugixml_airplay.mkf diff --git a/projectGenerator.xcodeproj/project.pbxproj b/projectGenerator.xcodeproj/project.pbxproj index f9af052..7e0a2ee 100644 --- a/projectGenerator.xcodeproj/project.pbxproj +++ b/projectGenerator.xcodeproj/project.pbxproj @@ -3,11 +3,10 @@ archiveVersion = 1; classes = { }; - objectVersion = 42; + objectVersion = 44; objects = { /* Begin PBXBuildFile section */ - 1120712114AE3D360035CB7E /* libpugixml_d.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1120712014AE3D360035CB7E /* libpugixml_d.a */; }; 1120713014AE3D4F0035CB7E /* xcodeProject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1120712B14AE3D4F0035CB7E /* xcodeProject.cpp */; }; 1120713614AE3D840035CB7E /* ofAddon.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1120713414AE3D840035CB7E /* ofAddon.cpp */; }; 113CAA5C14F88EDD00D3906E /* Utils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 113CAA5914F88EDD00D3906E /* Utils.cpp */; }; @@ -27,8 +26,6 @@ 27C4A1BF179491920031C6E4 /* ofxSlider.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 27C4A1B4179491920031C6E4 /* ofxSlider.cpp */; }; 27C4A1C0179491920031C6E4 /* ofxSliderGroup.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 27C4A1B6179491920031C6E4 /* ofxSliderGroup.cpp */; }; 27C4A1C1179491920031C6E4 /* ofxToggle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 27C4A1B8179491920031C6E4 /* ofxToggle.cpp */; }; - 667FEFA41982A58D0061271D /* CoreVideo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 667FEFA31982A58D0061271D /* CoreVideo.framework */; }; - BBAB23CB13894F3D00AA2426 /* GLUT.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = BBAB23BE13894E4700AA2426 /* GLUT.framework */; }; E4328149138ABC9F0047C5CB /* openFrameworksDebug.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E4328148138ABC890047C5CB /* openFrameworksDebug.a */; }; E45BE97B0E8CC7DD009D7055 /* AGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E45BE9710E8CC7DD009D7055 /* AGL.framework */; }; E45BE97C0E8CC7DD009D7055 /* ApplicationServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E45BE9720E8CC7DD009D7055 /* ApplicationServices.framework */; }; @@ -38,13 +35,13 @@ E45BE9800E8CC7DD009D7055 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E45BE9760E8CC7DD009D7055 /* CoreFoundation.framework */; }; E45BE9810E8CC7DD009D7055 /* CoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E45BE9770E8CC7DD009D7055 /* CoreServices.framework */; }; E45BE9830E8CC7DD009D7055 /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E45BE9790E8CC7DD009D7055 /* OpenGL.framework */; }; - E45BE9840E8CC7DD009D7055 /* QuickTime.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E45BE97A0E8CC7DD009D7055 /* QuickTime.framework */; }; E4B69E200A3A1BDC003C02F2 /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4B69E1D0A3A1BDC003C02F2 /* main.cpp */; }; E4B69E210A3A1BDC003C02F2 /* testApp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4B69E1E0A3A1BDC003C02F2 /* testApp.cpp */; }; E4C2424710CC5A17004149E2 /* AppKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E4C2424410CC5A17004149E2 /* AppKit.framework */; }; E4C2424810CC5A17004149E2 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E4C2424510CC5A17004149E2 /* Cocoa.framework */; }; E4C2424910CC5A17004149E2 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E4C2424610CC5A17004149E2 /* IOKit.framework */; }; - E4EB6799138ADC1D00A09F29 /* GLUT.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BBAB23BE13894E4700AA2426 /* GLUT.framework */; }; + F59021A91B1B161F0073F41E /* CoreVideo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F59021A81B1B161F0073F41E /* CoreVideo.framework */; }; + F59021B01B1B1DC30073F41E /* pugixml.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F59021AF1B1B1DC30073F41E /* pugixml.cpp */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -71,14 +68,12 @@ dstPath = ""; dstSubfolderSpec = 10; files = ( - BBAB23CB13894F3D00AA2426 /* GLUT.framework in CopyFiles */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ - 1120712014AE3D360035CB7E /* libpugixml_d.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libpugixml_d.a; path = lib/libpugixml_d.a; sourceTree = ""; }; 1120712214AE3D410035CB7E /* foreach.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = foreach.hpp; path = src/pugixmlLib/contrib/foreach.hpp; sourceTree = SOURCE_ROOT; }; 1120712414AE3D4F0035CB7E /* baseProject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = baseProject.h; sourceTree = ""; }; 1120712B14AE3D4F0035CB7E /* xcodeProject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = xcodeProject.cpp; sourceTree = ""; }; @@ -120,8 +115,6 @@ 27C4A1B7179491920031C6E4 /* ofxSliderGroup.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ofxSliderGroup.h; sourceTree = ""; }; 27C4A1B8179491920031C6E4 /* ofxToggle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ofxToggle.cpp; sourceTree = ""; }; 27C4A1B9179491920031C6E4 /* ofxToggle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ofxToggle.h; sourceTree = ""; }; - 667FEFA31982A58D0061271D /* CoreVideo.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreVideo.framework; path = System/Library/Frameworks/CoreVideo.framework; sourceTree = SDKROOT; }; - BBAB23BE13894E4700AA2426 /* GLUT.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = GLUT.framework; path = ../../../libs/glut/lib/osx/GLUT.framework; sourceTree = ""; }; E4328143138ABC890047C5CB /* openFrameworksLib.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = openFrameworksLib.xcodeproj; path = ../../../libs/openFrameworksCompiled/project/osx/openFrameworksLib.xcodeproj; sourceTree = SOURCE_ROOT; }; E45BE9710E8CC7DD009D7055 /* AGL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AGL.framework; path = /System/Library/Frameworks/AGL.framework; sourceTree = ""; }; E45BE9720E8CC7DD009D7055 /* ApplicationServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ApplicationServices.framework; path = /System/Library/Frameworks/ApplicationServices.framework; sourceTree = ""; }; @@ -142,6 +135,8 @@ E4C2424610CC5A17004149E2 /* IOKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = /System/Library/Frameworks/IOKit.framework; sourceTree = ""; }; E4EB691F138AFCF100A09F29 /* CoreOF.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = CoreOF.xcconfig; path = ../../../libs/openFrameworksCompiled/project/osx/CoreOF.xcconfig; sourceTree = SOURCE_ROOT; }; E4EB6923138AFD0F00A09F29 /* Project.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Project.xcconfig; sourceTree = ""; }; + F59021A81B1B161F0073F41E /* CoreVideo.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreVideo.framework; path = System/Library/Frameworks/CoreVideo.framework; sourceTree = SDKROOT; }; + F59021AF1B1B1DC30073F41E /* pugixml.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = pugixml.cpp; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -149,8 +144,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 667FEFA41982A58D0061271D /* CoreVideo.framework in Frameworks */, - E4EB6799138ADC1D00A09F29 /* GLUT.framework in Frameworks */, + F59021A91B1B161F0073F41E /* CoreVideo.framework in Frameworks */, E4328149138ABC9F0047C5CB /* openFrameworksDebug.a in Frameworks */, E45BE97B0E8CC7DD009D7055 /* AGL.framework in Frameworks */, E45BE97C0E8CC7DD009D7055 /* ApplicationServices.framework in Frameworks */, @@ -160,11 +154,9 @@ E45BE9800E8CC7DD009D7055 /* CoreFoundation.framework in Frameworks */, E45BE9810E8CC7DD009D7055 /* CoreServices.framework in Frameworks */, E45BE9830E8CC7DD009D7055 /* OpenGL.framework in Frameworks */, - E45BE9840E8CC7DD009D7055 /* QuickTime.framework in Frameworks */, E4C2424710CC5A17004149E2 /* AppKit.framework in Frameworks */, E4C2424810CC5A17004149E2 /* Cocoa.framework in Frameworks */, E4C2424910CC5A17004149E2 /* IOKit.framework in Frameworks */, - 1120712114AE3D360035CB7E /* libpugixml_d.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -230,7 +222,6 @@ 119B95D214A65CA0001E1E20 /* pugixmlLib */ = { isa = PBXGroup; children = ( - 1120712014AE3D360035CB7E /* libpugixml_d.a */, 119B95D514A65CA0001E1E20 /* src */, ); path = pugixmlLib; @@ -239,6 +230,7 @@ 119B95D514A65CA0001E1E20 /* src */ = { isa = PBXGroup; children = ( + F59021AF1B1B1DC30073F41E /* pugixml.cpp */, 1120712214AE3D410035CB7E /* foreach.hpp */, 119B95D714A65CA0001E1E20 /* pugiconfig.hpp */, 119B95D814A65CA0001E1E20 /* pugixml.hpp */, @@ -300,6 +292,7 @@ BBAB23C913894ECA00AA2426 /* system frameworks */ = { isa = PBXGroup; children = ( + F59021A81B1B161F0073F41E /* CoreVideo.framework */, E4C2424410CC5A17004149E2 /* AppKit.framework */, E4C2424510CC5A17004149E2 /* Cocoa.framework */, E4C2424610CC5A17004149E2 /* IOKit.framework */, @@ -316,14 +309,6 @@ name = "system frameworks"; sourceTree = ""; }; - BBAB23CA13894EDB00AA2426 /* 3rd party frameworks */ = { - isa = PBXGroup; - children = ( - BBAB23BE13894E4700AA2426 /* GLUT.framework */, - ); - name = "3rd party frameworks"; - sourceTree = ""; - }; E4328144138ABC890047C5CB /* Products */ = { isa = PBXGroup; children = ( @@ -335,7 +320,6 @@ E45BE5980E8CC70C009D7055 /* frameworks */ = { isa = PBXGroup; children = ( - BBAB23CA13894EDB00AA2426 /* 3rd party frameworks */, BBAB23C913894ECA00AA2426 /* system frameworks */, ); name = frameworks; @@ -344,7 +328,6 @@ E4B69B4A0A3A1720003C02F2 = { isa = PBXGroup; children = ( - 667FEFA31982A58D0061271D /* CoreVideo.framework */, E4B6FCAD0C3E899E008CF71C /* openFrameworks-Info.plist */, E4EB6923138AFD0F00A09F29 /* Project.xcconfig */, E4B69E1C0A3A1BDC003C02F2 /* src */, @@ -485,6 +468,7 @@ 27C4A1BE179491920031C6E4 /* ofxPanel.cpp in Sources */, 27C4A1BF179491920031C6E4 /* ofxSlider.cpp in Sources */, 27C4A1C0179491920031C6E4 /* ofxSliderGroup.cpp in Sources */, + F59021B01B1B1DC30073F41E /* pugixml.cpp in Sources */, 27C4A1C1179491920031C6E4 /* ofxToggle.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -504,7 +488,7 @@ isa = XCBuildConfiguration; baseConfigurationReference = E4EB6923138AFD0F00A09F29 /* Project.xcconfig */; buildSettings = { - ARCHS = "$(NATIVE_ARCH)"; + ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; CONFIGURATION_BUILD_DIR = "$(SRCROOT)/bin/"; COPY_PHASE_STRIP = NO; DEAD_CODE_STRIPPING = YES; @@ -531,7 +515,7 @@ isa = XCBuildConfiguration; baseConfigurationReference = E4EB6923138AFD0F00A09F29 /* Project.xcconfig */; buildSettings = { - ARCHS = "$(NATIVE_ARCH)"; + ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; CONFIGURATION_BUILD_DIR = "$(SRCROOT)/bin/"; COPY_PHASE_STRIP = YES; DEAD_CODE_STRIPPING = YES; @@ -563,6 +547,7 @@ FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", + /Users/inx/Documents/_src/openFrameworks_orig/libs/glut/lib/osx, ); FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/../../../libs/glut/lib/osx\""; GCC_DYNAMIC_NO_PIC = NO; @@ -638,14 +623,10 @@ "$(LIBRARY_SEARCH_PATHS_QUOTED_FOR_TARGET_52)", "$(LIBRARY_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", "$(LIBRARY_SEARCH_PATHS_QUOTED_FOR_TARGET_2)", + "$(PROJECT_DIR)/src/pugixmlLib/lib", ); LIBRARY_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/src/pugixmlLib\""; LIBRARY_SEARCH_PATHS_QUOTED_FOR_TARGET_2 = "\"$(SRCROOT)/src/pugixmlLib/lib\""; - OTHER_CPLUSPLUSFLAGS = ( - "-D__MACOSX_CORE__", - "-lpthread", - "-DMAKE_IOS", - ); PREBINDING = NO; PRODUCT_NAME = "$(TARGET_NAME)Debug"; WRAPPER_EXTENSION = app; @@ -659,6 +640,7 @@ FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", + /Users/inx/Documents/_src/openFrameworks_orig/libs/glut/lib/osx, ); FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/../../../libs/glut/lib/osx\""; GCC_ENABLE_FIX_AND_CONTINUE = NO; @@ -733,14 +715,10 @@ "$(LIBRARY_SEARCH_PATHS_QUOTED_FOR_TARGET_51)", "$(LIBRARY_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", "$(LIBRARY_SEARCH_PATHS_QUOTED_FOR_TARGET_2)", + "$(PROJECT_DIR)/src/pugixmlLib/lib", ); LIBRARY_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/src/pugixmlLib\""; LIBRARY_SEARCH_PATHS_QUOTED_FOR_TARGET_2 = "\"$(SRCROOT)/src/pugixmlLib/lib\""; - OTHER_CPLUSPLUSFLAGS = ( - "-D__MACOSX_CORE__", - "-lpthread", - "-DMAKE_IOS", - ); PREBINDING = NO; PRODUCT_NAME = "$(TARGET_NAME)"; WRAPPER_EXTENSION = app; diff --git a/src/main.cpp b/src/main.cpp index 390bf81..0e8a8fb 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,16 +1,23 @@ #include "ofMain.h" #include "testApp.h" -#include "ofAppGlutWindow.h" +#include "ofAppGLFWWindow.h" #include "ofAppNoWindow.h" //======================================================================== int main( int argc, char *argv[] ){ - - - ofAppGlutWindow window; - ofSetupOpenGL(&window, 1024, 610, OF_WINDOW); - testApp * app = new testApp; - //app->buildAllExamples = false; - ofRunApp( app ); + + ofGLFWWindowSettings settings; + settings.width = 1024; + settings.height = 610; + settings.setPosition(ofVec2f(300,0)); + settings.resizable = false; + shared_ptr mainWindow = ofCreateWindow(settings); + mainWindow->setVerticalSync(true); + + shared_ptr mainApp(new testApp); + + ofRunApp(mainWindow, mainApp); + ofRunMainLoop(); + } diff --git a/src/pugixmlLib/Jamfile.jam b/src/pugixmlLib/Jamfile.jam deleted file mode 100644 index 6d329fb..0000000 --- a/src/pugixmlLib/Jamfile.jam +++ /dev/null @@ -1,167 +0,0 @@ -# Latest jamplus is needed to use this - -# Targets: -# pugixml - build pugixml library -# tests - build pugixml test suite -# run_tests - run pugixml test suite -# coverage - get test suite coverage - -# Options: -# toolset=name - select toolset -# supported toolsets: mingw*, msvc* - -# default toolset/configuration -if ( ! $(toolset) ) -{ - if ( $(OS) = SOLARIS ) - { - toolset = suncc ; - } - else if ( $(UNIX) ) - { - local GCCVERSION = [ Subst [ Shell "gcc -dumpversion" ] : $(NEWLINE) ] ; - toolset = "gcc"$(GCCVERSION) ; - } - else - { - toolset = msvc ; - } -} - -if ( ! $(configuration) ) -{ - configuration = "debug" ; -} - -if ( ! $(defines) ) -{ - defines = "PUGIXML_STANDARD" ; -} - -# coverage options -if ( $(toolset:I=^mingw) || $(toolset:I=^gcc) ) -{ - CCFLAGS = -fprofile-arcs -ftest-coverage ; - LDFLAGS = -fprofile-arcs ; - - if $(fullcoverage) - { - GCOVFLAGS = --branch-probabilities --function-summaries ; - } - else - { - GCOVFLAGS = --no-output ; - } -} - -# build folder -BUILD = build ; - -# enable dependency cache -DEPCACHE.standard = $(BUILD)/.depcache ; - -# rules -include "Jamrules.jam" ; - -# split define sets into list -local DEFINESETS = [ Split $(defines) : ':' ] ; - -# split configurations into list -local CONFIGURATIONS = [ Split $(configuration) : ',' ] ; - -for CONFIG in $(CONFIGURATIONS) -{ - for DEFINESET in $(DEFINESETS) - { - local DEFINES = [ Split $(DEFINESET) : ',' ] ; - - # build folder - local CFGBUILD = $(BUILD)/$(toolset)/$(DEFINES:J=_)/$(CONFIG) ; - - # compilation options - local CFGFLAGS = $(CCFLAGS) [ GetCFlags $(CONFIG) : $(DEFINES) ] ; - - # build library - local PUGIXML = $(CFGBUILD)/pugixml.lib ; - Library $(PUGIXML) : src/pugixml.cpp : $(CFGFLAGS) ; - Alias pugixml : $(PUGIXML) ; - - # build tests - local TESTS = $(CFGBUILD)/tests.exe ; - Application $(TESTS) : [ Glob tests : *.cpp ] : $(CFGFLAGS) : $(PUGIXML) ; - Alias tests : $(TESTS) ; - - # run tests - Test $(TESTS)_run : $(TESTS) ; - Alias run_tests : $(TESTS)_run ; - - # gather coverage - Coverage $(TESTS)_coverage : $(PUGIXML) ; - Alias coverage : $(TESTS)_coverage ; - - GCOVFLAGS on $(TESTS)_coverage = $(GCOVFLAGS) -o $(CFGBUILD)/src ; # because stupid gcov can't find files via relative paths - - # add special autotest markers to build log - if $(autotest) - { - COVPREFIX on $(TESTS)_coverage = "... autotest $(CONFIG) [$(DEFINESET)]" ; - } - - # gather coverage after tests run - Depends $(TESTS)_coverage : $(TESTS)_run ; - } -} - -# documentation -Documentation docs/manual.html : docs/manual.qbk : docs/manual.xsl ; -Documentation docs/quickstart.html : docs/quickstart.qbk : docs/quickstart.xsl ; - -Alias docs : docs/manual.html docs/quickstart.html ; - -# samples -for SAMPLE in [ Glob docs/samples : *.cpp ] -{ - local CONFIG = "debug" ; - local DEFINES = "PUGIXML_STANDARD" ; - - # build folder - local CFGBUILD = $(BUILD)/$(toolset)/$(DEFINES:J=_)/$(CONFIG) ; - - # compilation options - local CFGFLAGS = $(CCFLAGS) [ GetCFlags $(CONFIG) : $(DEFINES) ] ; - CFGFLAGS += -I src ; - - # build and run sample - local EXECUTABLE = $(CFGBUILD)/samples/$(SAMPLE:B).exe ; - local PUGIXML = $(CFGBUILD)/pugixml.lib ; - - Application $(EXECUTABLE) : $(SAMPLE) : $(CFGFLAGS) : $(PUGIXML) ; - - RunSampleAction $(EXECUTABLE)_run : $(EXECUTABLE) ; - Depends $(EXECUTABLE)_run : $(EXECUTABLE) ; - - Depends samples : $(EXECUTABLE)_run ; -} - -# release -VERSION = 1.0 ; -RELEASE_FILES = - [ Glob contrib : *.cpp *.hpp ] - [ Glob src : *.cpp *.hpp ] - [ Glob docs : *.html *.css ] - [ Glob docs/samples : *.cpp *.hpp *.xml ] - [ Glob docs/images : *.png ] - [ Glob docs/manual : *.html ] - @("scripts/**":W=:X=svn) - readme.txt - ; - -actions ArchiveAction -{ - perl tests/archive.pl $(<) $(>) -} - -ArchiveAction pugixml-$(VERSION).zip : $(RELEASE_FILES) ; -ArchiveAction pugixml-$(VERSION).tar.gz : $(RELEASE_FILES) ; -Depends release : pugixml-$(VERSION).zip pugixml-$(VERSION).tar.gz : $(RELEASE_FILES) ; -NotFile release ; diff --git a/src/pugixmlLib/Jamrules.jam b/src/pugixmlLib/Jamrules.jam deleted file mode 100644 index e3a76ce..0000000 --- a/src/pugixmlLib/Jamrules.jam +++ /dev/null @@ -1,807 +0,0 @@ -# Rules for Jamfile.jam - -if ( $(toolset:I=^mingw) || $(toolset:I=^gcc) ) -{ - if ( $(toolset:I=^gcc) ) - { - GCCPATH = "" ; - } - else - { - GCCPATH = "%$(toolset)_PATH%\\bin\\" ; - } - - if ( $(OS) != MACOSX ) - { - LDFLAGS += -static-libgcc -static ; - ARCH = "" ; - } - else - { - if ( $(toolset:I=_x64) ) - { - ARCH = -arch x86_64 ; - } - else if ( $(toolset:I=_ppc) ) - { - ARCH = -arch ppc ; - } - - LDFLAGS += $(ARCH) ; - } - - rule GetCFlags CONFIG : DEFINES - { - local RESULT = -D$(DEFINES) ; - - RESULT += -W -Wall -Wextra -Werror -pedantic ; - - if ( $(toolset:I=_0x) ) - { - RESULT += -std=c++0x ; - } - - if ( $(fulldebug) ) - { - RESULT += -g ; - } - - if ( $(CONFIG) = "debug" ) - { - RESULT += -D_DEBUG ; - } - else - { - RESULT += -DNDEBUG -O3 ; - } - - if ( PUGIXML_NO_EXCEPTIONS in $(DEFINES) ) - { - RESULT += -fno-exceptions ; - } - - RESULT += $(ARCH) ; - - return $(RESULT) ; - } - - actions ObjectAction - { - "$(GCCPATH)gcc" -c $(>) -o $(<) $(CCFLAGS) - } - - actions LibraryAction - { - "$(GCCPATH)ar" rcs $(<) $(>) - } - - actions LinkAction - { - "$(GCCPATH)g++" $(>) -o $(<) $(LDFLAGS) - } -} -else if ( $(toolset:I=^msvc) ) -{ - if ( $(fulldebug) ) - { - LDFLAGS += /DEBUG ; - } - - if ( $(toolset:I=x64$) ) - { - postfix = "\\amd64" ; - sdk_postfix = "\\x64" ; - LDFLAGS += /MACHINE:X64 ; - } - else - { - postfix = "" ; - sdk_postfix = "" ; - } - - rule GetCFlags CONFIG : DEFINES - { - local RESULT = /D$(DEFINES) ; - - if ( $(fulldebug) ) - { - RESULT += /Z7 ; - } - - if ( $(CONFIG) = "debug" ) - { - RESULT += /D_DEBUG /MTd ; - } - else - { - RESULT += /DNDEBUG /Ox /MT ; - } - - if ( $(toolset) = msvc7 || $(toolset) = msvc71 || $(toolset) = msvc8 ) - { - RESULT += /Wp64 ; # Wp64 is deprecated from msvc9 - } - - if ( $(toolset) != msvc6 ) - { - RESULT += /W4 ; - } - else - { - RESULT += /W3 ; # lots of warnings at W4 in standard library - } - - if ( ! ( PUGIXML_NO_EXCEPTIONS in $(DEFINES) ) ) - { - RESULT += /EHsc ; - } - else if ( $(toolset) = "msvc6" || $(toolset) = "msvc71" ) - { - # No no-exception STL in MSVC6, buggy no-exception STL in MSVC71 - RESULT += /EHsc ; - } - else - { - RESULT += /D_HAS_EXCEPTIONS=0 ; - } - - return $(RESULT) ; - } - - actions ObjectAction - { - "%$(toolset)_PATH%\bin$(postfix)\cl.exe" /WX /I"%$(toolset)_PATH%\include" /I"%$(toolset)_PATH%\PlatformSDK\include" /I"%WINSDK_PATH%\Include" /c $(>) /Fo$(<) /nologo $(CCFLAGS) - } - - actions LibraryAction - { - "%$(toolset)_PATH%\bin$(postfix)\lib.exe" /NOLOGO /OUT:$(<) $(>) - } - - actions LinkAction - { - "%$(toolset)_PATH%\bin$(postfix)\link.exe" /SUBSYSTEM:CONSOLE /NOLOGO /OUT:$(<) /PDB:$(<:S=.pdb) $(>) /LIBPATH:"%$(toolset)_PATH%\lib$(postfix)" /LIBPATH:"%$(toolset)_PATH%\PlatformSDK\lib$(postfix)" /LIBPATH:"%WINSDK_PATH%\Lib$(sdk_postfix)" $(LDFLAGS) - } -} -else if ( $(toolset:I=^ic) ) -{ - if ( $(toolset) = ic8 || $(toolset) = ic9 ) - { - msvc = "msvc71" ; - } - else - { - msvc = "msvc8" ; - } - - if ( $(toolset) = ic11 ) - { - postfix = "\\ia32" ; - } - else if ( $(toolset) = ic11_x64 ) - { - postfix = "\\intel64" ; - } - else - { - postfix = "" ; - } - - if ( $(toolset:I=_x64$) ) - { - msvc_postfix = "\\amd64" ; - LDFLAGS += /MACHINE:X64 ; - } - else - { - msvc_postfix = "" ; - } - - rule GetCFlags CONFIG : DEFINES - { - local RESULT = /D$(DEFINES) ; - - RESULT += /W3 /WX /Qvec_report0 ; - - if ( $(toolset) != ic8 ) - { - RESULT += /fp:precise ; - } - - if ( $(CONFIG) = "debug" ) - { - RESULT += /D_DEBUG /Od /MTd ; - } - else - { - RESULT += /DNDEBUG /Ox /MT ; - } - - if ( ! ( PUGIXML_NO_EXCEPTIONS in $(DEFINES) ) ) - { - RESULT += /EHsc ; - } - - return $(RESULT) ; - } - - actions ObjectAction - { - set PATH=%$(msvc)_PATH%\bin - "%$(toolset)_PATH%\bin$(postfix)\icl.exe" /I"%$(msvc)_PATH%\include" /I"%$(msvc)_PATH%\PlatformSDK\Include" /I"%$(toolset)_PATH%\include" /c $(>) /Fo$(<) /nologo $(CCFLAGS) - } - - actions LibraryAction - { - "%$(msvc)_PATH%\bin\lib.exe" /NOLOGO /OUT:$(<) $(>) - } - - actions LinkAction - { - "%$(msvc)_PATH%\bin\link.exe" /SUBSYSTEM:CONSOLE /NOLOGO /OUT:$(<) $(>) /LIBPATH:"%$(toolset)_PATH%\lib$(postfix)" /LIBPATH:"%$(msvc)_PATH%\lib$(msvc_postfix)" /LIBPATH:"%$(msvc)_PATH%\PlatformSDK\lib$(msvc_postfix)" $(LDFLAGS) - } -} -else if ( $(toolset:I=^dmc) ) -{ - rule GetCFlags CONFIG : DEFINES - { - local RESULT = -D$(DEFINES) ; - - RESULT += -wx -f ; - - if ( $(CONFIG) = "debug" ) - { - RESULT += -D_DEBUG ; - } - else - { - RESULT += -DNDEBUG -o ; - } - - if ( ! ( PUGIXML_NO_EXCEPTIONS in $(DEFINES) ) ) - { - RESULT += -Ae ; - } - - return $(RESULT) ; - } - - actions ObjectAction - { - "%$(toolset)_PATH%\bin\dmc.exe" -c -I%$(toolset)_PATH%\stlport\stlport $(>) -o$(<) $(CCFLAGS) - } - - actions LibraryAction - { - "%$(toolset)_PATH%\bin\lib.exe" -c $(<) $(>) - } - - actions LinkAction - { - "%$(toolset)_PATH%\bin\link.exe" $(>:\\) , $(<:\\) , nul , $(LDFLAGS:\\) -L/co/ma - } -} -else if ( $(toolset:I=^cw) ) -{ - cw_bin = "%$(toolset)_PATH%\\Other Metrowerks Tools\\Command Line Tools" ; - - rule GetCFlags CONFIG : DEFINES - { - local RESULT = -D$(DEFINES) ; - - RESULT += -cwd include -ansi strict -iso_templates on -msext off -w all,cmdline,iserror,nonotused,nonotinlined,noimplicitconv,nounwanted ; - - if ( $(CONFIG) = "debug" ) - { - RESULT += -D_DEBUG ; - } - else - { - RESULT += -DNDEBUG -O4 ; - } - - if ( PUGIXML_NO_EXCEPTIONS in $(DEFINES) ) - { - RESULT += -Cpp_exceptions off ; - } - - return $(RESULT) ; - } - - actions ObjectAction - { - "$(cw_bin)\mwcc.exe" -c $(>) -o $(<) $(CCFLAGS) - } - - actions LibraryAction - { - "$(cw_bin)\mwld.exe" -library -o $(<) $(>) - } - - actions LinkAction - { - "$(cw_bin)\mwld.exe" -subsystem console -o $(<) $(>) $(LDFLAGS) - } -} -else if ( $(toolset:I=^bcc) ) -{ - rule GetCFlags CONFIG : DEFINES - { - local RESULT = -D$(DEFINES) ; - - RESULT += -fp -w -w! -w-8026 -w-8027 -w-8091 -w-8004 ; - - if ( $(CONFIG) = "debug" ) - { - RESULT += -D_DEBUG ; - } - else - { - RESULT += -DNDEBUG -Ox ; - } - - return $(RESULT) ; - } - - actions ObjectAction - { - "%$(toolset)_PATH%\bin\bcc32.exe" $(CCFLAGS) -c -q -Q -o $(<) $(>) - } - - actions LibraryAction - { - "%$(toolset)_PATH%\bin\tlib.exe" /C $(<:\\) -+$(>:\\) - } - - actions LinkAction - { - "%$(toolset)_PATH%\bin\ilink32.exe" -L"%$(toolset)_PATH%\lib" -Tpe -ap -Gn -x -c "%$(toolset)_PATH%\lib\c0x32.obj" $(>:\\) , $(<:\\) , , $(LDFLAGS:\\) cw32 import32 - } -} -else if ( $(toolset:I=^suncc) ) -{ - if ( $(toolset:I=_x64) ) - { - ARCH = -m64 ; - } - else - { - ARCH = -m32 ; - } - - LDFLAGS += $(ARCH) ; - - rule GetCFlags CONFIG : DEFINES - { - local RESULT = -D$(DEFINES) ; - - RESULT += +w -xwe ; - - if ( $(CONFIG) = "debug" ) - { - RESULT += -D_DEBUG ; - } - else - { - RESULT += -DNDEBUG -O ; - } - - if ( PUGIXML_NO_EXCEPTIONS in $(DEFINES) ) - { - RESULT += -noex ; - } - - RESULT += $(ARCH) ; - - return $(RESULT) ; - } - - actions ObjectAction - { - sunCC $(CCFLAGS) -c -o $(<) $(>) - } - - actions LibraryAction - { - ar rcs $(<) $(>) - } - - actions LinkAction - { - sunCC $(>) -o $(<) $(LDFLAGS) - } -} -else if ( $(toolset:I=^xbox360) ) -{ - rule GetCFlags CONFIG : DEFINES - { - local RESULT = /D$(DEFINES) ; - - if ( $(CONFIG) = "debug" ) - { - RESULT += /D_DEBUG /MTd ; - } - else - { - RESULT += /DNDEBUG /Ox /MT ; - } - - RESULT += /W4 ; - - if ( ! ( PUGIXML_NO_EXCEPTIONS in $(DEFINES) ) ) - { - RESULT += /EHsc ; - } - else - { - RESULT += /D_HAS_EXCEPTIONS=0 ; - } - - return $(RESULT) ; - } - - actions ObjectAction - { - "%XEDK%\bin\win32\cl.exe" /WX /I"%XEDK%\include\xbox" /c $(>) /Fo$(<) /nologo $(CCFLAGS) - } - - actions LibraryAction - { - "%XEDK%\bin\win32\lib.exe" /NOLOGO /OUT:$(<) $(>) - } - - actions LinkAction - { - "%XEDK%\bin\win32\link.exe" /NOLOGO /OUT:$(<) /PDB:$(<:S=.pdb) $(>) /LIBPATH:"%XEDK%\lib\xbox" $(LDFLAGS) - } -} -else if ( $(toolset:I=^ps3_gcc) ) -{ - rule GetCFlags CONFIG : DEFINES - { - local RESULT = -D$(DEFINES) ; - - RESULT += -W -Wall -Wextra -Werror ; - - if ( $(CONFIG) = "debug" ) - { - RESULT += -D_DEBUG ; - } - else - { - RESULT += -DNDEBUG -O3 ; - } - - if ( PUGIXML_NO_EXCEPTIONS in $(DEFINES) ) - { - RESULT += -fno-exceptions ; - } - - return $(RESULT) ; - } - - actions ObjectAction - { - "%SCE_PS3_ROOT%\host-win32\ppu\bin\ppu-lv2-gcc" -c $(>) -o $(<) $(CCFLAGS) - } - - actions LibraryAction - { - "%SCE_PS3_ROOT%\host-win32\ppu\bin\ppu-lv2-ar" rcs $(<) $(>) - } - - actions LinkAction - { - "%SCE_PS3_ROOT%\host-win32\ppu\bin\ppu-lv2-g++" $(>) -o $(<) $(LDFLAGS) - } -} -else if ( $(toolset:I=^ps3_snc) ) -{ - rule GetCFlags CONFIG : DEFINES - { - local RESULT = -D$(DEFINES) ; - - RESULT += -Werror -Xuninitwarn=0 ; - - if ( $(CONFIG) = "debug" ) - { - RESULT += -D_DEBUG ; - } - else - { - RESULT += -DNDEBUG -O3 ; - } - - if ! ( PUGIXML_NO_EXCEPTIONS in $(DEFINES) ) - { - RESULT += -Xc+=exceptions ; - } - - return $(RESULT) ; - } - - actions ObjectAction - { - "%SCE_PS3_ROOT%\host-win32\sn\bin\ps3ppusnc" -c $(>) -o $(<) $(CCFLAGS) - } - - actions LibraryAction - { - "%SCE_PS3_ROOT%\host-win32\sn\bin\ps3snarl" rcs $(<) $(>) - } - - actions LinkAction - { - "%SCE_PS3_ROOT%\host-win32\sn\bin\ps3ppuld" $(>) -o $(<) $(LDFLAGS) - } -} -else -{ - exit "Unknown toolset $(toolset)!" ; -} - -COVSUCCESS = "echo $" "(COVPREFIX) success" ; - -if ( $(toolset:I=^mingw) || $(toolset:I=^gcc) ) -{ - actions maxtargets 1 CoverageAction - { - @($(COVSUCCESS:J=):A) - "$(GCCPATH)gcov" $(>) $(GCOVFLAGS) | perl tests/gcov-filter.pl $(COVPREFIX)$(SPACE)gcov - } -} -else -{ - actions CoverageAction - { - @($(COVSUCCESS:J=):A) - } -} - -if ( $(UNIX) ) -{ - actions screenoutput RunAction - { - $(>) - } - - actions RunSampleAction - { - cd docs/samples - ../../$(>) - } - - actions quietly ignore MakeDirAction - { - mkdir -p $(<) - } - - actions quietly ignore DeleteAction - { - rm -f $(>) - } -} -else -{ - if ( $(toolset:I=^(xbox360|ps3)) ) - { - actions RunAction - { - } - - actions RunSampleAction - { - } - } - else - { - actions screenoutput RunAction - { - $(>:\\) - } - - actions RunSampleAction - { - cd docs\samples - ..\..\$(>:\\) - } - } - - actions quietly ignore MakeDirAction - { - mkdir $(<:\\) >nul 2>&1 - } - - actions quietly ignore DeleteAction - { - del /F $(>:\\) >nul 2>&1 - } -} - -actions QuickbookAction -{ - %QUICKBOOK_PATH%\bin\quickbook.exe --output-file $(<) --input-file $(>) >nul -} - -actions response XSLTProcAction -{ - %QUICKBOOK_PATH%\bin\xsltproc.exe --path$(SPACE)$(XSLPATH:C) --stringparam$(SPACE)$(XSLPARAM) --output $(<) @( - - - ) $(>) -} - -rule MakeFileDir TARGET -{ - local DIR = $(TARGET:D) ; - - MakeDirAction $(DIR) ; - Needs $(TARGET) : $(DIR) ; -} - -rule Alias TARGET : SOURCE -{ - NotFile $(TARGET) ; - Always $(TARGET) ; - Depends $(TARGET) : $(SOURCE) ; -} - -rule Object TARGET : SOURCE : CCFLAGS -{ - HDRRULE on $(SOURCE) = C.HdrRule ; - HDRSCAN on $(SOURCE) = $(C.HDRPATTERN) ; - - MakeFileDir $(TARGET) ; - - ObjectAction $(TARGET) : $(SOURCE) ; - Depends $(TARGET) : $(SOURCE) ; - - CCFLAGS on $(TARGET) = $(CCFLAGS) ; - UseCommandLine $(TARGET) : $(CCFLAGS) ; -} - -rule Objects BUILD : SOURCES : CCFLAGS -{ - local OBJECTS ; - - for SOURCE in $(SOURCES) - { - local OBJECT = $(BUILD)/$(SOURCE:S=.o) ; - - Object $(OBJECT) : $(SOURCE) : $(CCFLAGS) ; - OBJECTS += $(OBJECT) ; - } - - return $(OBJECTS) ; -} - -rule Library TARGET : SOURCES : CCFLAGS -{ - # build object files - local OBJECTS = [ Objects $(TARGET:D) : $(SOURCES) : $(CCFLAGS) ] ; - - # build library - MakeFileDir $(TARGET) ; - LibraryAction $(TARGET) : $(OBJECTS) ; - Depends $(TARGET) : $(OBJECTS) ; - - # remember library objects for coverage - $(TARGET)_objects = $(OBJECTS) ; -} - -rule Application TARGET : SOURCES : CCFLAGS : LIBRARIES -{ - # build object files - local OBJECTS = [ Objects $(TARGET:D) : $(SOURCES) : $(CCFLAGS) ] ; - - # set libraries - LDFLAGS on $(TARGET) = $(LDFLAGS) $(LIBRARIES) ; - - # build application - MakeFileDir $(TARGET) ; - - LinkAction $(TARGET) : $(OBJECTS) ; - Depends $(TARGET) : $(OBJECTS) $(LIBRARIES) ; - - # remember executable objects for coverage - $(TARGET)_objects = $(OBJECTS) $($(LIBRARIES)_objects) ; -} - -rule CleanCoverage TARGET -{ - # make target - local CLEAN_TARGET = $(TARGET)_clean_coverage ; - - NotFile $(CLEAN_TARGET) ; - Always $(CLEAN_TARGET) ; - Depends $(TARGET) : $(CLEAN_TARGET) ; - - # clean object files - local FILES = $($(SOURCE)_objects:S=.gcda) ; - - # disable "independent target" warnings - NotFile $(FILES) ; - - DeleteAction $(CLEAN_TARGET) : $(FILES) ; -} - -rule Test TARGET : SOURCE -{ - # make alias - Alias $(TARGET) : $(SOURCE) ; - - # run tests - RunAction $(TARGET) : $(SOURCE) ; - - # remember executable objects for coverage - $(TARGET)_objects = $($(SOURCE)_objects) ; - - # clean coverage files before run - CleanCoverage $(TARGET) ; -} - -rule Coverage TARGET : SOURCE -{ - local FILES = $($(SOURCE)_objects:S=.gcda) ; - - # disable "independent target" warnings - NotFile $(FILES) ; - - CoverageAction $(TARGET) : $(FILES) ; - Depends $(TARGET) : $(SOURCE) ; -} - -rule QuickbookImport SOURCE : IMPORT -{ - Includes $(SOURCE) : $(SOURCE:D)/$(IMPORT) ; -} - -rule FullPath FILE -{ - local PWD = [ Subst [ Shell "cd" ] : "%c" : "" ] ; - return "$(PWD)/$(FILE)" ; -} - -rule Documentation TARGET : SOURCE : STYLESHEET -{ - # escape colon with %3A because colon is a path list separator - local XSLDIR = [ Subst $(QUICKBOOK_PATH) : ":" : "%%%%3A" ] ; - - # quickbook import scan - HDRRULE on $(SOURCE) = QuickbookImport ; - HDRSCAN on $(SOURCE) = "\\[import[ ]+([^]]*)\\]" ; - - # quickbook -> boostbook - local BOOSTBOOK = $(BUILD)/$(SOURCE:S=.bb.xml) ; - - MakeFileDir $(BOOSTBOOK) ; - QuickbookAction $(BOOSTBOOK) : $(SOURCE) ; - Depends $(BOOSTBOOK) : $(SOURCE) ; - - # boostbook -> docbook - local DOCBOOK = $(BUILD)/$(SOURCE:S=.db.xml) ; - - XSL on $(DOCBOOK) = $(QUICKBOOK_PATH)/boostbook/xsl/docbook.xsl ; - XSLPATH on $(DOCBOOK) = $(XSLDIR)/boostbook/dtd $(XSLDIR)/docbook-xml ; - XSLTProcAction $(DOCBOOK) : $(BOOSTBOOK) ; - Depends $(DOCBOOK) : $(BOOSTBOOK) ; - - # docbook -> html - local HTML = $(TARGET) ; - - XSL on $(HTML) = $(QUICKBOOK_PATH)/boostbook/xsl/html.xsl [ FullPath $(STYLESHEET) ] ; - XSLPATH on $(HTML) = $(XSLDIR)/docbook-xml $(XSLDIR)/docbook-xsl/html $(XSLDIR)/docbook-xsl/lib ; - - XSLPARAM on $(HTML) = - "generate.manifest 0" - "html.stylesheet pugixml.css" - "root.filename $(TARGET:B)" - "generate.section.toc.level 1" - "toc.section.depth 3" - "admon.graphics.path images/" - "navig.graphics.path images/" - ; - - XSLTProcAction $(HTML) : $(DOCBOOK) ; - Depends $(HTML) : $(DOCBOOK) $(STYLESHEET) ; -} diff --git a/src/pugixmlLib/contrib/foreach.hpp b/src/pugixmlLib/contrib/foreach.hpp index efe6d6d..c423151 100644 --- a/src/pugixmlLib/contrib/foreach.hpp +++ b/src/pugixmlLib/contrib/foreach.hpp @@ -7,6 +7,8 @@ #ifndef HEADER_PUGIXML_FOREACH_HPP #define HEADER_PUGIXML_FOREACH_HPP +#include + #include "pugixml.hpp" /* @@ -17,9 +19,6 @@ namespace boost { - template struct range_mutable_iterator; - template struct range_const_iterator; - template<> struct range_mutable_iterator { typedef pugi::xml_node::iterator type; @@ -50,52 +49,14 @@ namespace boost namespace pugi { - struct xml_node_children_adapter - { - typedef pugi::xml_node::iterator iterator; - typedef pugi::xml_node::iterator const_iterator; - - xml_node node; - - const_iterator begin() const - { - return node.begin(); - } - - const_iterator end() const - { - return node.end(); - } - }; - - xml_node_children_adapter children(const pugi::xml_node& node) + inline xml_object_range children(const pugi::xml_node& node) { - xml_node_children_adapter result = {node}; - return result; + return node.children(); } - struct xml_node_attribute_adapter - { - typedef pugi::xml_node::attribute_iterator iterator; - typedef pugi::xml_node::attribute_iterator const_iterator; - - xml_node node; - - const_iterator begin() const - { - return node.attributes_begin(); - } - - const_iterator end() const - { - return node.attributes_end(); - } - }; - - xml_node_attribute_adapter attributes(const pugi::xml_node& node) + inline xml_object_range attributes(const pugi::xml_node& node) { - xml_node_attribute_adapter result = {node}; - return result; + return node.attributes(); } } diff --git a/src/pugixmlLib/lib/libpugixml_d.a b/src/pugixmlLib/lib/libpugixml_d.a deleted file mode 100644 index d7141462cc8ddc1acbef5e8277d4587a618f7f21..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1480680 zcmeEv51d?8b^mM#u!O)Yh#Ey5oO|E9@6DUp z-GG!|%Y1g zHsMcp@ZA}+7Oh*d{L%?;pYrahZLR)q%CxC7re4@Ked_y!dUFh22MBd3ImG zWZ+%{2MjzDt(N>w8`x>!7Y)4Iz{d@2I!WWd-N5S%+-u-~ftQ}F@oqNopAGzufzKOw z`s*}a(!fs`_~!=RZQ!pAJo6Nd{~iNBVc?AhZZq(ZfzKLv?&~$(6$WMv{F;Fe8aQO& z`EStpR~dM{fq!q{69%@vQR98k!0Qa$Wnjg?b0=xMj~Ms`1OLsy_?t|A26h_wRRens zeAd9@q3~F57aDklfh!ICw1Kx8_CQ25sev~cxWm8$1|Bx>#4|Kqn}JstxW>RgH}IPVK4ReW2EOHOn*L$~ml{|y@J<7N zXyEv_Yy7hf{9OZA8TeTP_ZV0<@R&0--Mb9@sDYm{@b3(~-@qXQ-+q>+OB#5MfuA<; zRs$b0aLB;7oUQ2+2Hs%c?FN3|z@~FF-edzmXy8Tz|JuO&3_NkN#{XRd|H#0v8~7sw zhYfu5xf*|lf%6Rfgn>63_;&{O7&!hNn(iV4HyQX>2JSNO`v#uyPK|%Afk^`w8F;;c ze`(@RtS-8`yk)EY{xs(JQ8}&0Mo$O53%oR<>_kx1zIS-TS5{H$;cbX{#GDB^0uD zQRnjZ)oYe^yl+bK$`4#IzkSLy=CG);}nz)XF;VbQu3ix#i!XkXva=@vVXYU+`sniH%9 z7vY>Bg;UA*rE8XCR&}iIoHAwQnng?77iX3&>sW_;H>~` zIcbb5=dTz8lWdyKDbp4&TEAjR`-=6Q>pB*#n!9m6xW8oiqIK<^>lUr(Tt9bXGFdn0 z8S6SIGFN_Jep`Dz>P#HBF$8#h!4l+))>k*eg-bg?+nVd@$I#kZwqhmf2z(m7s00#j z97961p}O>jlvSXxq4p3A3pR+La+(P~x36BbN=oRkIvDFB#@euGWoFdT+$K;L*V55s zxMDPsTuBOMN3Dd4n<`r0)5-0q`OK1lQmRSjRzxTeI_pSqHmZn4^C@F>%ZlLoEJa{_ zRwA%I3lZqDZo2Aic2m^Z)7P(A*BQt+6yd`5MeEnExCW|6`n@(kd2;?Vx8;V?Nms$< z6iRUg+WQ5a*RAbn4^&NU>ab?0jp5c_IFwz^k>}2yGN_ko@i)jl)Ko)hL%mlh6xCHH zZ`;*QquvY(lED#(p>|3LyW8_cC2|EYD%_R9Pm z9jlinuSA7K8Ykh{GZuGTvtsq=aB#>@tO*Y4^P1p@f~#fP&R%DR+@m@- zta22CAaP=`F}d8Y3$4}O&f&tM&Nb`EZR!r;vMNgL zO6E^>6<%aQVN|3LM@DxmEh2(;LPtPIBU3*zpT>k>NYgmNs#Sp=s5T2kXpCX)+7U1y z!Uz~TYaqNOq*Ve`7cjv!%kw$mbTJEy3$*VOcTQL#+#IAZtLAZ@Un zH;CwVmkpx1y=FwTXvVs13-wSDIHIf1#St_+rpoxiH`D5RDT~&wg~{8#WX;;^jByo`s!^m0j8J^sQ!Vc0D^@N|Qqu}*F=Rq& zwqBw@VVp>7*L55L*;7Nw>e0Op^0A?#eTmRrkAy&^&`8OrbefmtSeOt>RfmKN41Yc4 z8LWGshzks@M-VYmTSke*g)3IC?^xFsaKM9`Y@QPdktMWL`A^at#8k~af0UFLVRGp!B10OL^fRi-wn&cV5Pf^3(HqvCSb}1b|S33W2G2QK}3Pb)7PV=YBP0aOxc~) zo6j)y7=>m2nj=g%s=+OByEPJ^;3Aeo+-am8eb-pX4oD$ZUKg#mS6-XD0A0!#roh%q~KtrE4;nr*4#; zX?oDTb%wu<5=ZIcAlt5qP{*Md?tEw@>rsFjl^(O*~itm;ipW&tSH$x-ZXa#p#g0Xv1_P{ z@Xt+iotH+^BBD)SwgMAj=!BfUuAYk}qQv#0MikpKFYESTPK=d{)?sKsZDK=w(ReoN zJJNe ztGa#hb(nO7vV=&ujn!k-)M;$WD#?uOF^(y$dnHuyBc-X6tfoKqh^Xxq{2-w|lJx28 z)~pHknSQF8PQ(j}=&=2;pieJU>a3~=hXz+M1Vd}*V>Nt!J(6rdG)aNb8j}3bD3WYwJ(50L zk0cuqO;RAVh9o~UiX-?G*Xdw53@%MwP^aeO( zQz5pl$gjP<6Fvg-0MOokRr2bq{AYW2;Jf4GmiWfwuJ7Z`u?g5Og@;WNU@q-y*|aZP zhsB?G*WNzo_hw)DelN;FgXgJ5`s%J9j+2d!t=PP_PP5Q!2;Yj;%Y;2)d^;~DXRzmL zn!@dK6z+VYIhH1Ux{p$Bc(L>?TD%x8j9U7Bv-%i``z108zyI8*&-x_SNctA7TeSL` z4$iv;%lpL*!Sux&g3rJhiEq`SB~s*<3m>LGh4_~X-`dP#I(639!?zcEp713q;ZnUFAj^Zr%&_ixy{$zS47 zkiJ0UKzJ>E!TzK5`-<;vCSl7{%0EFKacOT~ynem&zNWmUADisNVSU)2VS{}HeXG_i zg@G=Ppub$WOcme8pK7XkYxH?->A2WOv5yzOK$Td0D^?RD7l8%w zJ?hv2OuQfcc<2|v#|LbyjU^^ehRtCQ2FU=B%!47X*_JphPIk|=0$@Z;Z(pT0#xJ<6CC8D%DbLjw$|{+=LFWaX5DY=1)P zRuJz`h=MiutWnKyf1=g7pX}Y&5EA5#GQ;o%q$XOWy!qJpX>vvV4NvwnGvL; zPxrCfa1Y+2-1tj(r}9k_Xc=cqy!qaQt*gz4TfO@AaRzD#RonXUZ!c5sc=BM2hV14x zJ0h^`{6Kwr@j;ixFQVerHd_O^M`03rhf;p6^4``e?`^H}zLgxZ^dUE!pZ#!D=y4Xs@J@qshPW__;1PE@>jWt%196Hrj`J+Q~5(GBb13< z2@;GSC5ns*h3`+ylTfLfW%1MJ#9}Plvi#7peDcL*#pH|eJG;*sMx35<^Ri<4#brH} z=4HqA;%z?pY%%$4J~@PZ@W=+eiMW_PfBg%^vgd~>Vy)X9?EJy!~8Z6-LUbEQW+twSgu}x;7f+liP#8M-D|rnS6{E`jD2UC zYZ))gXip;hp1f;*8s8c*22F$bhQ3xnieHY+5Ook#-{tBJ9--54*E4X;L<%jUF6DNXhlLQEyQ~@00lz@gMwz91J?HM?EqBKgOre|Pc5OpB0ae=&! z8U?rFrzb={QkxIA`E`29Fl0k3t(blmB5EZV3QQ}l=C!GWe!zZPc~Dqwj$Y96kW0&q ze%Te`r9on9KA^umdBcYIrdZFwgnaTblvbY38U{bn4HuJ-Eju~}5+nx@f~UvyX|`c} zL(y^Ci{XWGFeENPDvdsN<#TND!AjHR?`lXL8s8Q+XRR+kzavV&Klv=FEF_L3AIQT&)l%eXck6U?TTSBKKk< zml@72crlm$O)mLDAvruNmN}!4d=cQyh2(E$y_k7jA^F0r;mkykNX(T_f>6dA)_5;! zyqLy|Nj#ELnQP(+h8GP6HnhsSJq*D8BC;TEieBaQCgf*C`r@pAA=2N>x=j6{lQq{}o? zOd^r`>PMYOmuaMHHPR}H#1d3zDEY{M*?AcNGc%Ca4ocLg2nL##b|kj_Za$nqA7V{r zNXX`)=1g2fBHxow_g5;&OkR)AoD-Ck$Anm5evCy!BSllK?6%R54M*qES0Y$t6)afI z{gtAP9_wsIE_hY_W32_}A-x-yOWv<{ zN9B?S3(12J^g{an_#O8Z795J-@lc|Wc_0zL<5&F8KZh6jM-Y}jKoh>lFD-P7+VT)| zm~d8O12gOskc#eIZq+Kb-KWzYv_I|{7{9rE6pE0CiI^;JygXGp`VS;=8a?2F)RI%S zrb^?-4VUp=kfK+tzT16xoBQy3_o3Mu?Vu!Jo@=6vf&~{uvY^IZdli-cI#ak4GP8NNFE$};kr^4AH6im>5y%oo4q{D< zu=y7ASom~eB%i|e&u>Zo+x&_iQT{7`g;KtJEV|sFdU>R6;KhawZWAlWA8&|$i*Fu^ ztA2~${A(7ibTm(Kgk4rw$5ph;t(kdGwB<$xNu z?z1{-{A!c}xj`Ou)MwSWWA8$Ly~@g0tH#N5Z?GR$<0G(OMjaN+G4}qeul!?G<9(@7 zsqqo`bV4Mbw7YZcD~@M>`|@Jd`e@q2k*M_sEUQ)PFGc#ER<&N!05?Hzdj5fzkDue~ z=$A3^^A75CRZ-ElXft!^Fx{VLY_v8uHX5*e5>f4o)glO(AtT7|{gIshEz9rA!td|C zdieeF3jaSwS4r4^J}+ASM;5_FjDoI>9V%uKg2O3!S$8-^5zc5jIJHve_Ckk3LKgrX zI^aiA`MolfI+Bsv#5!$otx(Hs{5~GUb1c`bL$>bJE+}F7sRvfV8keC*u!hQBuJ9~! zhBQnZ-}28!^r9Nyh{-#(M4`O9glAph>gWQxu7=b|bs$=!>Tri|Bj|(KwZb^1p&`Q`7d|C#dl^6JOaB1P2mc{wv)sp3hge2Y#*nmJH2Z3vML=u^0jsRz;Y)nObC zhrG9{kBolCiJs@}aCMDwGM*{#Ja_bXkjF0J{M)pXW)K^TeYe4B!T1TWglen>TK|d0nGx%U8@0;O^P>3z_BJm zGu^xz0i_t!Qh*_xu7j7(_$$LRmUdPcsH|IWcMG$}PbSNo{X(L0oplCw?wXR2$9f84 zD9W;gL6mkNwTBe&CtXSgR^}sk51<}Z<%1c;wr~h5Zf0V6DKxz#Ow8QQcn3<_=F#Vt zlzr(RnsT>rB>|kEvhIWTo#$C+fqF}K@0|!%lx8SLFk&P};Ga&HMWlfSER@wJVB?jT z(|?q~rmL^)A|I8*nv+>!5}DKfa8CW2Q@@|nF18o`xT;|!%6r53`V?QEkI$#PCDk)9 zE=WD9+M5x4iSk#shK{J--IWf~j8kB)zmnz%X&nJ8C7s1EPV|V@W)Os0Z2dG{tjJlh z&WVE8wjL=+pnWyKz_!`|gK3>u5Tt5l0D2bcP1H(Y-OdOx>Qg|{gXK1Sf=aWA6DtM7M0IL%otB&)NgbiRe4v-9-?S9P99a9!uI1Ru#9 zvoHCJrs{ZHF`xYl$efCiV-y^jygKy0&8G_H0r=q*0KFJy@s770q4o3DG@2+rICzB* zE?y}6Bf`7u{)75UJ@-Va=O;&t-I8A*RUewqEykD!%EmTsA_RH$nw<>{;cm72%) zLy#AmQQpGedYV4E<-BYX&IYLK>p)O3wz+)l=I$m4Fb6g=Hjs{#eYfg>TB#=nr|nG& zx9Le^X?u45*)MhG4en$s+81ooWM6fzuSMD<$1~j*B~BW8b596ihuc>@B|?q&Ar$7R zHd!@1jSbW$HvEW`r2UL1L&w)pGZ{MmWuT@tM2*{xG>@?xQN4t2~OWoUG1|T?7^bL6ke1aF~+h! zJ||QtPs5@jtfJxY7jS&$L@$&yo?)I)?M#DzNOtDyPJVdlD0d?zjp}9Q5!Oo$PREXz zDbn5wT8yzWQ_43sgJl%7AE^!G%ak>junG&*YP0=-JLk+5VF!!pgPWf}mPX4{94b^l zSWF(=JTy*Th!u0Gn}pJ2ssRpefBG6s8J59xF8O33`6N~qeI5vz9y=*K>jljlVr8Yj z5tm!TTn57vY{?J+Pp^z*77CYdJlqE=a!@hqu*fBUX6r7W+=SarseJZY9Ue%HQlE0q z#-NbEwM~Oq9EG)isiMZqCv%mXF&x*BI49nJrW5beQY90`SgQHtR>a!s=YU-go|i?| zX^EwR@U@_zdMdKuO(>GS(;zs#{R}&?a83jB+2s}iZ^8)VT~Xq&ES+yaI=%~F%j~t- ziX};ar38UOe-_R=lMoayv>EayoT0ocN}NC*9>pNz{LBKIVSp)q?pPEF&UUAYCBav^ zMe0c$EqD!A%bV%*%qO>j$=d*Pm7jsT1}SrhXSbp9?TbVc-`wQCNd;Cm`}r<2`IbtW z;RE^Xn`jbuYy6g; zO+Rni^h6U@0&`q(kBlqs!MNg{Tyjq#xd&?ix8%SKkI90ww4hs^LHX<)DaS1{0gU5F zDzsRVfa2W@z%s%3o*q=iXI_vJ_M!>Q6WY?~dP;I@6_Kwa9xWsvg&3ZIl4*=&u6iLJ zv{dNBl^ymCnq)ltBi6OE?h&k{PRjx20Ly^o)Q$JDwObwI*m_uik4VrS(PIPjZoX!d zHfeEeKD^NDrENj%B%$3+luvdc_bw_7bddX#ePF2P5(pm>+XB*7Oz-66C3|vO3}qHW*h=H=gI-LaX;v&zXn@h8 zF@}dhL+1AhV&M$8y&;K2=AHYH%aufq~0|8HNyADxHfon>CpH*UpAZ z721u>xE=H`s*o@Ur4jdft4H_CkH_;})6?azS*j_PP~(S3_(TFe|CfL*;k5nxF;b8)F?0((L5JFCvV|d+x&bCNxNKs0$6Qj zl$lE|-ds2)ExL@plFYghY>DYMM35LtotM}s*@!!vQ1f4 zsxcLbXY`S0FpM}oU}`ME8pEC;iCAog(gMFx7_EG_Et2T)dbq|P}&%XBeAG=E{ku*EokLilFqkfcmMB8O>h08FIRhQ z74E%U*b-h{fCK-1t$!xDuRYXjt)CL7f(U4p<^Pb@Z_2h`&cl#WI#YGtk_BJCf)69a z4eyT?9}LtNwoJjRoWGtrsaHA=OxdGx_sJGWgv@5k$INSZ9}!%3qx2#&=81NN{eQC8 z!fqk8>!3oScM(-+#4#QLv}C0_^t?0lygl^1HT1kG_*`A@Ag?ZSA3owfaK{r;3JulE z+=r>|!&&YF=2rYP5mO4%m7vc(3FhG$_@9FR+4%nu{ukl@llcD>{)_nEhX23A|84lc z2mc50|6Tl>KB&#pOTK*zE3whB0R5;==yPwJ&W@=MYYAFoV3FJhjwjf4HH(j*<9;xG zfcUATw`B(g0rCwoHGXIXn>#@C9_XhK;ixUz5c2c6+bcG<<>6PTjuT8PZh0* ziZmi)Fg-cMJ^8wxx?Z@ib87llRyMHc0KwXnSQqH^#5~8OMT89AAdf?o*CB{Be|mBS zNdh8c7$W=$8O4wZ8#=2mBwn9q^+%zQdfd8Hw=cH1X$~4Q%L>DqogznX_ue3V$9#z z29)3!a`Tbfu$c_=wTQJv%t{$$*Sgt~qk`ZGs0 zi&scA%jhgL(FbL)MR;bUEaBB44BXowSL9;+j=gYkF&a404_WIiB+EI`QoWSbLb5L> z+GqgGgq)Z$j4B#;zl)J5(RJV`x_|j;vxQItN$4eHQytKqEv$tC#dxrA98NpB%ZB*H zA3&RNMxHhKCvw<#HjF*x@JenTn7w)EO&d?Z)5KPKDU;7ukJBJ^*n{QBT31yf+&iem zEsq(m*k*qQTAa*ZmZ7!Ln!N56e4!S{JNLcs5PZ6je41O4k=|y@#Y5T_9esV{;hn4m zu#rPfjMDOH8Et2mLTy&Dg3rx0>$ts{cTr-IKDp6HoXddYp!RWjsk*d@1f*KhUFSQi zTAkX0gidLFET*3#63JfXC_Eb=*OM#VfOrMD@=%6J$V%eJy)`_WDk(@pwJk_~atD~U z!!XUE$aoUjG6Ixho}mO+XfeGNgYX=BSyTXoSDdOUyZPjHMA?QY+Yx0O3YjY2PM@m; zgVglRh4jrJGM=UN6(R?&T{$_aSH}2;K}>W{A$<=^#$CXuVD@}Y`MEJay{WpQIy*8r zmwvR6ew4{E1+|F{qRJU3S9tothyDh_^GG522!v-l(z7*TN(Y?*BnizO4q*z6XCGL9 z33}}+3{*5XucBp`&uj(*?;)d|?~*sdP^VzzQ^?2usCa@Ng(v9IT+)#Bmx0oZ30*_S z650msp3r)2)MWP!zlgUa2YwO%X!kSmlahna;0c$Ll0&?MapSZntB>e}g6ct~%TM(Y zRS$F$6xv0-oyRjqAu&9wt@As)#U>MrDTwb#cDXdu((7e*Q0M1m)Fl>Dgw&1+dN#BBS(DXDJ}o} z?jqC`njWytv9sLv(FX)D-t{O6w}rb6A(wuM$+ zqvi&b5XRg+Bn90Um+(E!n{XG6?*HiqBGuU;byk~9kv2#vO#-bDnj9^V>lV@MS_#4= z3|3F$>q7eJTytbNUZManm9iXXOB93lB1xDSZa{~uP>NI!ssL1gU z{^5t#(zB~2-wQg>zF}z;(}$aSQB8aiE+{r%9PTMkuu=Fla15TN*aV^>zJ>Rt@&8I8 z3dB6##uO}ZC(N}vf>x+58x&gHF|^%wKpM?Kd%<+Z3qF99=nzq5sGph`US!bI!B-VJQK?vwmRWPN ziZ{f{^@!y$fb8>Wv-n-@Nh^6aZA}$u-X1?=tUhVOwe1c#usoze+tF@K=+gryxtgRk zm;C7s6AQ_oZt3n^UAY(v5BIbF_=YP9K6*nN0CZgs^yuj*1njMH{N~pq7F=pmn#n27 zIyf#vCi_@?%Pg!);qAxcTRx22$`8@@`1~jFEd_Lym51=mLc`7VW-z?c5ATB%04pOd z$#4-N3dq@H{u~TdW@tTigC{=4(=5BUG&N zbBJanaV8Qin##cuBAv`gUmYP5k6*6*=?IZ{j&|kaCK8xB>)nl;-bskxxS_NVBhFcu zQWE3&nX|OO(T#Z$<9Ff0NcF3g)^leknPf#tk%rpRkyNp7@Eg>&isK^|_KhU|G_(FL zY#yK!5J};|^OfgOdMP0cx1U9l&e*nW4U2)rO0QE?uur`8e%KA@rDp-yShxa6X#fc$ z)EmD>QJHV4M7_PIu_W*lA0hd-i5qo6@h$&?gbuAoq!PR;V<~l9Q`_tsGI6xMq$>-R z>5w*MZJp$*^z0D@qpHn1n1V_#p1no6#uhT`9T}dUTiZQi2CZQmdZkn&za9_}4ZphK zRlNr@3%|w!z5l>6#M_@&$a{JB>*3*X|1~`P3A{f8|DVMD`vC_4KaYRL8_oZA6K@sr zdIA5Z;-BgM9r>D(C9GZ7gAbEUUBu3^G|mBdb3MKjsK&>Pxu&408nW47C)SvC*6xEf zE3>`nfy>2FgtaSrBrvoGZuA7WcDSFvP}nOJeGWElZX9;-!(Z0 z_%Fw?n{;JL9!#+>(S#F=pVGW=7I0bb^c-L{mNl1%A%@8vZmLwPoj<7IX~4dwjjkkv z+s;fyo74qD(3&sIB_F@x?SG`A9%{31{<-?hHnDvIvld6}Qx4oO5AGhw! z)iyJ9lXKwAKK#ld2%^2;>)hLOfW(An$1+37VnyvA;2~2M<^e^b4@X~Tx619MB3P>yWG=J_g z#lTq6UBM2gn^)7!ll>>X=l+n)jBf1y4m(Q1C~se^2}w{PF>rlVF8L5m{fEf)FK>GO zXf^eF<2QekTD^4i0a5O0w1|MI|In<}@hxA4T13)WYvWt`%uRKz_(k@(*V%>3q8=8Q!n%`~bn)&UFNx@h$A8D|g{CGOh4Q zJ|!YXrdh{iorY2=q${R;Pf?VsOR68OpTkcI>7Urx6v*m~M!c&Q(p4K<#=+R__Y_ir zX=df9d6zBSKYz&#u_WQW`VqR%rL-7M|UVp>Z8F~FFBtuWxG z4*979EUqyxYI)~V2Il#^>h(yjvkG8r>B23?um}aC<1IosEc!a@#I=JuGAs$N72CDz za+D6L0jHy2_8_0u)peK%819@TtS+L$&D@(=oQ!FJ>rFI|ma4nnvUwN8i%;dC@N{HSt>oR0Q_)qh*!(Yn1egs-~jeq%T+^PLF&;i~3 zH6=^;{wOIm++DT1Ev2VTcIZ$MePp}BO2*gN$p zVtWtIcF=feV|re*zR(@HenL-*&%h#A7{4~*BsR{KnFD?|m1tmu*p<>^kujK_bltgoqOE7sFlSg(kI_#Ko4OFmT;*Ce_H4GV-75@|?>a!rOvesVx6aM+RWFmHccB zS_D)LDSmm%m-NXh!fO#`v2dSH)LblWjaIj?{T#VsIGYEl|OfJ#l}AGDHO zGz%H4WOkjJeo=SU+N^vMdDMF$%PVW#9RBaJ^IAo=mY`^QN8PaNbuDZC8b{AqLXTQR z&xqAgC>mB`dBLpZHOx=04!eaPe_B%zto+hl=G$1+-H3%}hqmMnWVRid?LcPRJwAGc zOMbbK{4$G`)uaxO(0i1qp3~h(N(i*<#g{up33pd0iWkiFVRshNcRGa-nYp``$bJwF z1+Hzpq`II~+A5Oh4P}VWjyxy&LQ-7|-NVw`!eJ+E>C=2J8VnCeQ_Jto-;$Hpw=j0` zZpOL1D0$8)mKc=3dnqI2A1&U(oBSh}=l9OZ-zUk9O+sZ>6!~{Md1_PNDsA<&xFbuM z(^1BHV*%*(QJz|+#-bf>MCZf_p!zwDc+iw%kGgx(#2z;b3w1yibgrSAGd%VRj`C*I zFn^JQMR%GWX~Leqnl(M%xR|c{M&p)R+A`C}PS1$@FM~9+*t&KH%WnCt2-H*wN74D& z+H==%EI+#y`Ly^l^@`^sKGB+yKGq_gk_xQrnFOU^KWb{M7?0K?#$nc9)LWAx@{MT# z=%gX6kC`;qwJsiA#ks9xSX+aldLy_&N><26K#Cg2uujlsDS@}(CE$}7O&l20u(}$r z<}*CBOYdZA(u_heTjX!h0x3}Jo-t_(=J~lz8C}0nK%}*$$70W<;_v9eQd5pgD7ZDU z;HI+E8zaWtmuNvzJ$xurkmrpgguCv>XX0daA<+Wu0Xw+f*;)wo+nT3UiD4WMLXq{e zi59M;9jH!_{y^@zs&;^PW!~Xp*W9X-aO;)0j*@eaAhKW*M>65@OCNHQtxxC;cn4t` zMOB4!X_EO$bO6SwW|s4e29?yhbBaC+E?o5IOE@?j!sljksTOyRgfk!x4^dCT3q}?u z5`nNyW{G7rGS?+1fF$CWQm;hzkYrubz}CKhe2?@j($CPGkS9(Z+R@+8Wg8x}b;&mH zQgOJFukFr1yjef1insVP^38KR{Q01u?2;Y9-Vrs7mu!FGb|-N)ztP$TZmF4*rmm|c zYW%T@(0~vaFksnD54dnSe(M2U_tjVVC|FMlmlb39>g^$X_4d%RONJlaIE{Dsw5_og zgPvQI-NPj{HdHwocubP>Vr6_ad>G$z9y6AMAkV`BPsJtt+-Usf?Rc#$ceAB$1;f+L ze`-RP6%*r7hJ!$G5R{)6!y+m{u<>$(Q@&n`m8WpmHzA)iqTP4n6U;-L;WUeD3d)H9 z{*+-uD)u$yuk%{#Ug`YPTWFH1jPwJ-Og6e&HYEG|8Kbbo$0m2_AfnVMC{sN;dtR z#n4MO;gb0SjepiSz~nCx~TI-%&U2vb@sk9u`=UKv^8 zyNdCfzm6M2(YW|c+x1D7j@;4hQ)LgQqpeDI`XQOMhThYKUK||n(A)FGF+ws*fK-i3 za1^rU&vZ#blP?jb1p2*YO51td3$=OZ*!azlG7*Ie)eyhwK7EQP!L43Mums+6I;5dE zIAz0El$qCAaVgu$p|VX3mCY$F@H8&1Cq~+3X=%NeTH4X=#nrfm0q{|NjK|$YcVzId z*L<(ktO0theH+CTssk%nueI;j+V^Yi8^-Kw{kKsGul3*PPvKV(7lCWMxjmZKslV2L zhb)^~1DFQPSo&{&{K*M&d(g!tBA!@%x2!lmg#i`*jO%Baemg8x%#@eqC$57rQ+7Uz zjuTyUvt(IJOdJ|isHs_#V-tajk!qBkDrG~EM*^aGss zqZ<=p$(>c6KF(O;1jHM4b?Sl2{(FB~@=zgp2pej?jAZb5m}Khx*a@UNfdYKQzZ@TH z%Lcb9JboPN_({-m0*+9FD|&XNLEPH&<05k7icZ+dG8Gk=6%o&MV86NRSM;cjO7F?X zE1h4hzr>#G8RTfP8wY&QAm&tYaY1iL80;Y*&4|;DdczP4FpNT8(qDyRnjq7N73n96 z^mkb|TA-e#BMnu);$P2w?=>Ni8D|4=#LVOavIpS-3^yOhC5?REESL=0I>iFnuH5T2 z8ZN;K=Y>ALdV@&_h6GxUT^Ihl2(QB=EBTbN+AY^1zIvX=DBdXDadXa1ZGN_qqGnOM zqxCm>BW2&;Sh*hBm?eh4IIJ?4<jFzGFnAS?-Ce;SG*tFWD(Euuf|mHxCB{b_G5xxbLy4}0%(lH1O(b+8i|;2)(z zZWK2@bOpN3hzt%$1_zMAfn4&wLh?Rj@Yg~r?M^i!w^vH4QV-bOd((l`iM6d3J{22{9aq1v$$a&n^bXE8ijl zTGD|^U|r+9`?_XJE`5I?eLv}09F;hjFqb}5NFQQkuH_F^riw;Q_HG5#=Ab+VpG8LE z*^4PVe$g_MC5eX0`TG6J(Pq5w!|hH8a^-5Z8^~d3yL`^OvD_-c*0!SV`(tNbDBYG7ShSx9&8wH3JDKYv&GyMmJudKc_D~< zeBr@qSd>gpaH<@IhAKpvKvr!J;3^*I&0b%+Wg$TZLjGg@|7c7O6P0(=rw)BPS{zN#Y}phAJ6u~{Gq$@$w`Mrd2C8pq1V#9EPj3uQpdm8 z)7pbCW5w_2!8jVt%v;7S#uB@inA(#8`zr?XXaK0714+w}9&C*#8d|Wk%)%9S{fd*G z3vCWFwI-GWmj`hI9aD}_UhhM#AzHolnPMZ-UkLOy<-Mgl{)L|AdgUDrj^4QU;piiv zpf~P)3ObZJYJE;yxIaLds0P7icsux#EMW5X*tHBL7$-ols1oirDCbL`hnGE6K zZmV8y)+-a4n;yn0jw!eP-E-erKkEEtrbAq>e933vC%IuV=+N%7$STZ~h2BhGDt`zO z`@~yXc~*M_FDcy2;bZ+usV4L8l2mC4c9K5$L)$?O~p!tE+xz9-s zApTsQSKh_rE6|OFlME>xr;I}esJ!dTsdIZ!_fTrsD$Eo+HH91jZ_nem?FqcBrlk5p z_6dkVovL>%(s(hoi{sl{uxh+nwi8?S!|V7@UNe?98L{^s8Pt=I*W@v9%;f(9d9?m} zyOO@~yn3eOF*vU4`A zf>BC`Ey9yY6MimDmLAOBWrCbyd$d$~3&8Jf^&0ZX`dF1OhKJ^B;G81t#5wRf5u>%X z`!pQxmnzNh=*mD-Q9m0sMcMzqG0y5gj)&K0bo4)6MCLSt*Zf0-#=A3M;Qn)(hgJlc=Tky#(}m! z;eoc`DIR}@>jFh&1>E=GGj>1n*fCdf)CcTS0B zQ1t8jFPCo|Uk~=eg2PwxA+1>*_u@lktK9AFP zgY=W|i+VqGhVV`891ti5OGRDu{V2m=^>jqg9B3s_2=)#1Y6Qpx4G3cc(XNQYu84nT zuLdIsHV)hp{8)-UsG*_4m)W7k+F|?Kh1Qa`+6}3=fg_eV8#A$k`*1+Il$3`O3rDYP z7LFc5(G-VdlRzj%mYu9nD@{jgaCVD20V3*uUWEN;3-DU|47y`pYoGsH+o!dMVH@On zZHvh-IGjsX@fA`%7w=)t!E&$L!%(6zIgYCjXW6kG<3nx9{(U&lLt7|ENUnXDH+GJ&4@7H(6-D9>^y-f$a+&9#bn<%($>%U~&-aMh(3La!391{c zt&sOzO835_ij_aq$0<-RZ=q|G zJF35rT)OuqyX!DMj3jJ>oG~e6gKSmRz16DS?Z~AcIqv{01LB^OLHr)kT3@TT2@fLc zM-{o%${O#|On?uDcZ(tb|OAM0yN1Yp& z|Gjd#ac20H%Z*1VzH+%8|MKN#SMrIZqROSo=;Fghql^nrVR@ZVMnELxb9ZQa#D~#? zT_^?-)z95Q3{5_WLPd{ZAqCg!Qrqq^QfWm|@so*MZ@7jbOlzyW4+OYl(H0K}2TA8j zOAMS`;0^vPbz(5}!bd!SX7kV~GErDh zZ9F7Rxn3QqZlX&#)f(XbZ;{@U8`694OQx6mxCdTN2EVQ$!T&ZQ!Q5%jJ@+_l!O_gt zQ^KAt(Ykr)cs;*M?&F>OLXN&arSoL({zRVj@wD_6PouAp5BX5C!(Hz%4qp#6Omv6r zEBgJuA~0H)2FiZHHhlS7SMB=I*8KJO_;3ch#a}2ThOxPdO?%@!=)4=)JZa*i`(AR& zRt#px4YN;2Yu5%-{k_1`+`!Ytfv0e39>*#Afzp%%J)iItHs)v17j4J?*YSTB{*4|H zN%r>C^W zmu>jJ!CL+ru7|6ld%Sj)(HG}2>Lw3=7(&tn-y zJ?+^0_7O;+)K%d z4Tl;lpZcK5&Nosw)M(7sSqV+D(}tDgM#F?Of$MqR{Jp! zKR`smcg`N(Ew($?63I_0BePXHmTi~gOgCGkZs6#}Q88Q(u8Zd(ja+ZUF{?@yWDG+* z(a<*@-UKV%YcBr8BL%+@8~>$QC$shDv%T2G8o&7q(%l~Y070?DceP!P5elC*wda26 zbSi2ugJTmP1r|9rkvBLtksz0S1lNLGdD@&g1I}+X`D_^xQbh&Pe9jJN6ahhQm-ue? zdEn$88Km4}xC&0(-OW@uqT}|vaFc(ecncv83dY%Q3^IIHrrd(;5 zvE|AYd!v%zY>Z33iVEuRw^^eI2=SNicJuo?dt`v?@^>eQ5&nJ+H{>s&@|QuDzk)TN zZ2=Z3?lg2 z^5HbvonsZT4dBCNKq7qL4fsHi%U+6WL9TW9kU#{GAfOH(QW`}-9X>E@&lx@+zGC^n z8;1{q17|`by70ky1`&L1`S1q%YR1Y3%0oMl2p@O@J`m)xe}HR2u5~ogLPP)w0_yN# zxkeEXYAJlT`vR1|wxw(nRzMSd4mWHmgxXRVWFYRxspBR^a{7RY(fOkA)pR>avDVd*@N9oSw8G)17CKF zh7NXox97+a3xI^0np1VN7X{l@-!weHloE6}$l}2y)pk z;aZSu9ZA`a2p~Z~9aiknC;~!~!gssrOQ@BUO(?$T)IT9#ASr|@DGail5v=*_P9PG_ zIL{!9uPtXDf^(_zHF}tiq#@k{Ou`=CfIS4c>>gYTa;?LjZbSeb0_w1*SEC3Bv4`(= z(}vx{NsN@+<*c>rS!viqsO({oWshLZXZwIi*yB8dEWWnv`6g!gD9)eu<2e=mGTBjkE5dm}vsKcHCjUvD{BtGndpvPn!rlp5pjY7}1@(pBUO8WN#O3WF?X1S^aaAQH|v&)^JSTh8P$4j(gTHbUFJ z2}p!9ya8tja@k3^7UYVd2#?RjSPw%7EUVjt-amE^Kh~PRd!7)zAKjwd+>!#w??vtM zM$2Gq)1P2mUAY&RBckzCOCxVUBS9|vW}%VS8XDh98c!1%=U5u`=9Zb3M&1NyeE*S> z_g0V~EaVNyBgkdnf@?vpHRQoYkKKc@4OlqclBYMfOt$3lCP3a-<44H7(=BcA7s}5?oD>GMiD^S-v|_C@v_OH6_}q`7qa=+ zNR@4sa+W3mWN=FMOr(4V@bNnuyniQg7X@Ll#1}dY<(Yrb8B7JKA`WGV#su0nM3t5y zH0U$%@U?9jYw%6WF-slokjsEXs+Bk38v)E!Tw$)_T1RIj5Cjqg)Ztr7qX-D;48Gfa zKDbe9&>Ox)EkqDV5KxCR%QcDsa^^afD3EC#7ugufN)fsiQKuRa;{7xg zAtuFP_qay(Lqqs}q{tM}K&JR?IVZWoz(rc&obwE_`Py>sRD52n@=MIkjg@_B-~yAd z?*`m}eFQLYafN}4E7=!i;35cgY$B+`zMMu8K=z4&i+8(Vi%0j%gO(q>0Y3;VKLm}Q zelPrRo|txW2bhFCya9U%VCCWpD;L)~t*skDphG|%_Vj8L0d-niKMKs&){m(0a*D#{eJk#P zok@%GiIXV5;q857AT>DAK)U#B*(bTe3I+yYpYsgFd~MnH&&@~3xyOM-IL8}sjsONQ zt}uXct;4x8fkdeS52xb>d?0}BgezQkxYprAD}q3RfI57btWgBi;RD0=oJl^Y>#oc4fj15x1P5#% zL>E3d&me-YEgzO(1;i1_!(~7seBcfEKmc0^SJ*JcEdN%*gatAA?|xmJj?CFXwN@$+1zqJ4&2*Kqnk&#|=0_ z02>Hb*g&|FBN0~hLIi;r0d+XCT%!meN9tJB<4~9#!imy$05OS>@@(*lRy9BVa}Ms2 z88PYie*#uDQ$e#3ht({Sr+zX{IOseB&sq{@IQS-r;afcE+a|R1`?0FZ^8LhKbN(b%B8^5(7H4jkZ z1fbjjV&YF{qFzv9##FQzKLB)(6zv`q?Ven6Pa(OdPSLuN8;+r3x5{5&R4NB~^-9rZ zBUm-L8v;+cMd%Y-KpOjASfT+)uuF8E8Q8TkJk}#$adWv%E&4b=} zFK0iw{U?@ua(H;@Q^UjeLU{TA(*gf}Qq{k|@UY&;ex~q&UnqS1+2P?Ae>psS;)~we zmxMR1O1kWD%c0R<)WF03SY!0&VCEHD4(H)Xr7S}5(F$HYs}OXdw7XyG#=~2s z#!*sp5)CJlSsXbrCfz4a2gmyehec)^_a_w>0N4p^dt{u;F6=jz>Fz@!1hV!(3|rK$eq8Iox%D1kJk0O*zbTlV-X}MM~$!8Lc-Z(kOyrR+;cz4s#ZWUBogY z72ND~F}rSO8RqTsbvF@T-WigsQ;Ny2VDC7H-C@KJj53R}ScHDO-67wu`bu@W751(8 zASk)|@ozJfX}L(^E3#(7c^p^$o9aQutQbwbgw79aOXZQLJtl|?K)9NpU)vqvnq-qH zD-2vp+SO{~E80gCA@B0&&phQY`a%ec%z zX=V$%D2ni+rPqa+&7D~o#`yb@QK#gU4;R4Td+qr7Yd1=xkf zANSE-BKj(5|MBo$5sEX`T$4+S}jGy{;A)#Jj|o8Vbv{`v&h;v zZ23+O#BV;8{cGvy-;r(>-lNc(MerK!A<+UhL78*jB9_`iJDWdkz-4W~<>9`{fAOX0 z&DumVdKd1A?Q7_)kLX`&D8+ibI&UEM+4hHWB_#*yS;6K#<6Mo}IkAja~HC&uG zKAdr|so_hyD0-}#MhOQ|SN*z_Y^X3ErzSmGNInXEc~&=K$VU`9x$VM>hUHt;bMT@+ zyo?j7053t=hJTRwy3PyL4W%Q7mb7WR+hG&1dqqNf&Zl|22ZjNi69tZoXa6swP(18u zWja~X<+No4X}gzYO8oHDy%ZeohPszxS4`fUPks$wY%Zps!UiXP2YDyT+ok0NCf!t8 z!iLfZkq=a-ySdSe%0n0`mtkdYb82(>MP%Arc}lQ@;A0HIN5`{&>l3_PSfB)N4-&jh zD&HgcVQ59&zJ=kmZr}P`G5I+qxD9BwQRgVZz+^X-UMjm_dxkJz2~q9EC)Lkm$83dh zNjVlEV|7_rNT-HnC8ugRXH^ztN4kN2bZDDEqqomMbOaYQLpho{=C?X75#@k2*qd4= z!_$y_SPGhXsNY%{yfSJHKx#%i{rc_q6f){339=J=Dy-s|_mY=ZQ#_v(_; z1xTkQXbR+)B199Sd{&E<>6d=o>@#1mQ;rgzXLlhvdvk%bS-2#OF9$^hsZ8S87eIJWjKb{U)dPX zhGSsd;gN}Q7Z&^?9D|LTKQ)aIP*ZB2v@~dY6cHaLK0sH=u3fLwJzR^vMFk0$vjpKZqdwCYckUtwak|UZ=MHAgncD-N*r@C?zT` zb%D0}ue$LK^p?P5YLdwcLCxkC8Z*^g`7>0t7Zn46umd$birGX$>JPOoSu&)krNexh z9okd}9f)B`!z(COo(({Uj41R}EABDi;d@dIr+FL5jgUxxYC%4iGJ zhLDv24t1hkLgsJa+!(lrSK{At)p>t)o(9H(Sz30(VzmyiqK{U35o{8(OrYO}oeDY{ zGqCeX73UzRz-Z`n0j9kry#CRjASm&aDv}2eWVa53v_tHL(+s>ZouG#t9ygY)4`nL{ zdPy)TkFAoVQ0@TPp;|VA5%hUD{sZ^?cZS(M+oqwAPVm0svmEKc(8Nr`oIV-gO~qS~ zf<1~J(L4r2Di=A^Z7niDa`}Ezb&}$dr9(Z!fyL?m;(}*`d;~Rc&ybID2S|RR1X9lEO$H&I95*%uhPHYPC9z~Ph)qn! zTNFv!5X2_cW>R+JezL})!bwf`*vuyumG~t@?rjxYb_<&=m)krkrT80OS>p?|&20w1 zXjefV+yerNVqC?y{F*gln+e)j8ICyq_zhLBUQsA+Is`XWFUg1A`J_2w#_c(oaeEFk zZanrz=m_hpeOy}X>MN9x?u0(;P9VZb$h2G~56b3=LVzkYCaPP_tQWXMK-PX0EV)f^ zO+AZ**9kZe%ss24NHs8<$iWMSfCuhA+!l|Qes-v4*E+W2gqoNE4?x3E2#c}1O&v5k zHRFR}rhye?TG=uURgA(y0!1R#aJKd4@6d1cJXi_l4llPbp$OqfcS}90M(|53zIbUz zlmk`*s*9B(?F?1Ldv%8g%vp8kJ>CdA;uy%K=kMWr}O`a~;=bWdtT_cEd{@fxQ4 z8D?dOv}Ea09=u(y`RNLtl04Zs-pB2-*ATZ{v18#qQDg_ooR>95SQm6Hk>`ayl|K^W zR#|0pz@&Ssl+2;@TcNgczGAjaOWs^a-i$ooUPC{p6!345zZJ-<@3w>uIQ$F}W|n|x zs#=^oLCp?OvlG*8*y4~7Tw6A3t4m{i!Pf5de>oY z_y4N&xnD(}`_)|X?+eMlhoofBmKuuAFqgI;t2?bWE2{W@!=Z2}Go)2Bs$yWNaR-Qy z#aX<;;w*w(b}6m}xsuRJv0Vx%MWjsyTFU{9Pzy$vS?>MiBCcY&^u zeN;&oD~io6r;dSxrcty88wEbIoiDM;7Nz0h2nZbWKr(K;w~R(iA5X%Lzy00@hDTs& zOW4vm5FVM8qdM(?sfF&Kk}5!qXQshHXFqR9|B`Evf!fL zjb}xLl%XzK)p0M8AY6}&a6Jy;dfZk^xR|GfiwO%MV9)`rvASelfrP;bqv0U0HCL=x zX*3D-ws0meN0^CsvTY5vY>G)Vn@O}pGaK;aaI2v&aB?`mZq3h(_K4OuEB(AZvog^v z+W%f$L%B9G^V-6>qOr4--c%cN8rdZ(Ws3)0sEqF&+ zLREQIFUC%R5wV_AgENh=N=<(10RWmLJ{rppAO;0btw#i7pwm2h@fy|1LSQ6W#8Ge@P4WbPmeo|0jz!(?X#%Hb z2#7S;2Irq{g)tAP=zODQfYA*b4QElUa~p#S|46t{Z1S}>wmY5@Erf%b_sFn>T#y;s zvd+)~=xL!Cl)zq(8n2F#{%DFsK$&@ne#$_Iey~Yg2)h1(f&wPWV1U($$iAm0JTT*G z9wujkK3P7&dTqlKs}J{H^0z{W@QT9>yv9ETfyu$^NbV&-Jb%i)ZZp5_a1UMxBeBRm z$TL>&nZP|rKi;%?)z5z);3v_%9mS|1&RSHEe8A! z&OJRbl1tuX4XDDRaKnz1sbNg%Ia25Jc^Sk*nGl+LQ})acEol@ZHrV={Rc1MyMX_ut zMN?HB&dv;Tme>uetXeY_G|8(72RB~Y=qP)tHG;Ez53E|3N6guUj{HGmVj4hxsxkY3 zzAv@wSm))gA*)l-IPH*}jyXB3-fwO8#3t5_@0vDe%6Fl3-KpKagZ4qLrO}0>JIT2} zVXf^nPfuTO`2mK~~X&C%*ahu&(L3}vy9ftWX(fn2(U z{VV~j6#CtT09vmDdz)X=Vb|(7ootJ+EDX4stZx!+2--K)h9Xnc zuFrP;-R@eeMpjf3qlN(8-2sz;RqfNw);CC2WG3MbPw>RR7WKa9^jLK+-08io68 zRMl=@RrQ&cRHk0T$0@Wc5axEy0GE&*JcS4&kI|p)_Dm32tcG`2Hgnw?dIxaN`4D+M z#qeJvf3ZZnbNQ+!MFyWV7eY|q0rPIatOLc+q!|%F3VJEWtg#;ak($i-@ae{3{Rl+} zwnMRF8d3{A8d59jQAE+FofN=8r{AZnX zldML|*jvK+Zqt0XSv@RRfp{b?ofJm2RS|6sBLXg`i=)NnOliP=It~JDCN&V1D?Re8 zKD2i>N&KsoipeAQbohk7L$nW|MQ1X`>|7 z3pC$QBT;D0O%+qW!XaPz^b-ZE!hc1&@f!0!Xef4mF1X$h+Yy?$9)GAXw;7%##6r0j z?38sint@D(?N63b*`R>kn-yn_m3HDOG~YH-h3yGfSXiuwf_!kS-86)e`zPGdlN6Z( z#}H}zs3|uBLejmmA41zADpZ=~z63t{Cf&5{UvE5|V4b<t+?Rgr(GP zHa~w<{N@WKuRvmpBo(CUJjN`^9(*rGFjx5h5>i$Lx~;x)g}Q`wFTIwR=QSRMqZvzP zhrR!HJa@Hz5JX;VfKSHyu(l;B5)P+cB z>iW7Sbd-K*IB-=+N+m__HN09^G`itP@A4utw?3L&dVe9kpEC*(g+N!sL4IT*=wODW zFlzcBVrh^fBE}nt7(p(3Ij#k{LStutM|{ji;InL?1v!o(rKY|zu1FeKLd=)(wru=1$J!kpxMt-abEyGcgb&A=JClHw1@+q3xwTA zwmTCZ#C;f3;{jU{>eX?Xsmeta$+`wq7aewRy~{7TYyJNHCx#3_afGfogwiY>yrNMDpEbr!ixI=BTyc@Z`m<``Gn zF;!bg#_;uENV=N1kHc9H&3Z!0ezXzh07ofcJmu9h2@RPj6|IA2NoDLD7B&Y{IIu3F z)yor=8tU*lp8!OVYK}7eEXXvda0E)a8jdCWTAJr^jIyd_0hc^&(5TT1tJnmg zBIvh?QVo4Bxsfrn`O3#|(MrL=o7lM^8Oi}~3|gGu{NlIvpuBx(;@CSxd7O*fIgo^2 z!5GnarAIpy`b1dEbZLw7<}#20OhDB#-MDY4W$H%2_UCBbGzo>QDV>z6MVm2d)wdsn z+fpxe5mG5(5~Q{T8XI25ahsL95F9gYfH8`A-N0|~JZQ+18V+H+i3K}s0jipBfC433 z7pgpLPUBU&-&o6iY}8dQsxMRNAXC(zr$8{WubEF+C^E|OTV3STuy_@FiOGDQ*^a;9 zSWNIWezf3a80HMsoOE|Fium3VjE!HN5_ir;G|;d8aFvNzn*QoVvI(6l^L7}O#S%lD z95o}w+#!eaf2F$CCIv)0g|m@k!VvFwrgqO%dZYyMrP7c{>_l2LApHA&t%ado?UicU(5f10!zvHl3BGw(%^OZW2IDm7A-)8K zwiEw*@&7RXja}B}*)r%W__bVYShv%G+k{efA!7LYSp{^iIOA*w0=-Pvo!jGKhnF}2 ztCxdZHjzQ?>w;>Y))V^2&QnsJGq4O(rA6_{)FV1ctY3(p?nD=8d+>x;B3ftGJ|4l! zT=#ZVitA`c=MWeu022tWXR*N*iLbxh{5O_ib^sXgg~I{vlnzD$7ip-Y6D)xZj|gUQ z0(lfZcL!frY8JT#rQVQ==1@&QU6ZS|G9(oGwH36oYU(cf!|bRScFf+$8qW>CmX7GK zksNyt2B}y)kf>1K0j`*_^JrOz6e1Yp1f{Ef;dS&GIbLJknkh_?_UZ+|HYk?akc@Ls zADHnM*+s31RZ+8BU0Vql;~8eo$gb6sO4H7oc)Ei&49+^C59-sTr2{@XA1;vRJd5na@C4MP9 zqAY?>ff*Vd;MYjqe=i*gPhLQW@SteVMUbgH+4~&7$=g2SGi5-}F^Jz}r<`7)Q!%~) z#Z|ph&p9-?xAm-ecPhM9jg*|uARN};zaKH?|~ihJv}&2+QPUFk+5#h}uMU?U6QXY#SgSlIWDH4hElaBnysc?8$6w`O*7j)$h;FO(Y*PMLvTPXFMV)|QNNyRameGaQsp3&#yXfkW#lMQmvGMi^`&m_^=!; znM2>WBys24P_g$|#5lAvzNa^TKw~I6q_=B$(?fccC_ed?`5GKZIO-|C*TV)RlD^v# zSiIgOw3>`g9+yUMCN!z;<9PNI*!~{Nu!^XrXJX@-b=w(RX2UM2UCdJ-G|rzV6PHeyfxCa z^M_cMJ?WGq*m+V|8LJUG-!FIL=`g%_fA%imCH3ORrj&tLPs)lCjD16SxzR@m;zhmd z;P3SXo>R`8ST4%7GWc}P)BzW;4@Y%NBz;M&hdGtukS?c>L-wu zP*z;<6rIbZyZIU)Fx(^n=YPm23G%o9i9GMi-*TY%qeCWFz^6h7A2AL7N1s> zR|@nT{Zz@En{Ngno{Y=U?RtPa=LdP}T;;pRss01U1f#TL6$)$A=nTCaW!x=9=|rWS zJJ0SA3fL-u#L*5?;*x~=)nWL64&ARI)+*~VzU3y>`wX?^ll2Rw2CErzJ-L!BV~{JS zU#ByZZ?xX_?!+CJDoKgl?HfU*ZJb#?_!3%~V7nU=-BTaFc%*c4)SDBPFD6twFwoO2 zX|z%XikYWSv)hG9cP|%!rQ9XnPwUD@TLLztf65)Va8n-XTgI6DXkov%;KfSdYukr;h+i=<`h)F3ix>loR z+afK+?A5?x8G5xwm*o@Q#zT363>I(qqSh`1*ci%qxnf#KfNCYkm*mM*jV=tiFqG_C zO}18($y2^0PfjvfIdU1I$h1ChFs)AzJ|X_B(FkkwnhYV&p2&A|A$>FJDHWtPxg8zk zHYm~Un7P~LHAI*s`l&X4Z1pN|mz{5xH+k)UtJ6YwA{S-=FB}M{A#YE~5lE{_(|jR9 z70&--?_J>QI;wMV*>Q*x5{?rB7-$=XrwJs8mWKfoWXPc>kW*ZU!EFdN&!#O8x77)T z;v&~NTTKx8iSIH5;<{fB|IWZn&^K^iGY;oaC||978J_G|L^^Y>&8t!6n|dC#dh5-BNS`_-R}>N|28&BLQB$w( z1&sEu<%u+7psY)JP^1~E@4GNI(4na);774)n7rDxehEqeGaBuw4#OjDHV} z-leCz3dJnZ(=l2-9Rtm(enU@p+=PB9fO#4=s(ecj`cJarnPQZU$_hqdz%fePb#t}g z;wMALhaT8@C^hKFIoE`txK} z%m7frstyn+?5?-;#V8RufpCsPc7Bw@jV)< zee%Vh3f)Rvzh#K?3NN;5z6%CE^U6)*F9q?RZ^YLac;5!Rgtp|1Xy2$Z5!*@L-+I*qPWgx-Ya(pq1x2+l<8?Ui{_)>Ga^wnP8R^HCd0hgAh9+cE84ZRdk|;cR#jTZr8I49 z`ErIOHaS?T8(_erdj61`HZ2Rv!aU6KQnZhNo^_-?d9~2T`VZLQdliNq&Hyw$<3wC! zc163&vEE4jnc(?`X%F=#`Z!glHbM2PDsRs@Xw^Zx8d|%zJ zwr_%3uriIbZrr*p)0ik7L;muVsZ@0FVGk4NAPe^9UeKt%^BRx|iO1@dQFiskQMwwg z@xs8$$Aka&InCnrHpoXm3QuDq4lri%ZGvo5ydDEre;&GeU7m-2eVfBkWHiLRk9>Ou za}5U#d!(fa0qjSOZfZqg-`qJ@-+8s+KB_wlfcswJesv1>P#kf;)*L_Mz!U8iqXM+h zRK;<&Q}J5izFi9;#t}14+^-ex$e6@^*Wqnw#T@i6sF&$r0;O%YfWQ68NzH^L+{VT+w%czEkgR6aKpJx7&ua;Qu3!@y)i<5U^Cx8iO;=Zz zm_J!F@u!5&z>q%)xV;YinfKlEr{Wx`9Dg2nD{s;SSZ-Sv>oaO@>yO2%KbhuUq7JU9 zDQin}>jm%t=GMYEwpjm?SUk5DXh*E_>B_V?vh!$|Hg~=0W_K2BIPM$E_-f8crY#rq zX3DQ>zrB>0k;bkq;4`6Hp5_pm)}pLwbVB4ScmkQ!wy8%@rM$-$w{6jg4t@fXIJ5n*i_hRl6vP1U}OKN^FClN{ow;G92rc$aJGY z1k7iBNnmOAuX2*pdOaFb8BrQx5BL|c8Frds^7Cw-s1LzKw-k0vc6v%+o&BTsef}dS zx@yJ$jfp9Y8@NmWt5GSY{O8wYVELzCVH~E?JWh8oT~~@sx~nf7zE7OQsLv%zq7ji%P0+MfS>TdZql%POgqXJN;mb2)W}2|iN}L* z8WRsT;w{K#Yx_-4mFFp>#?Zz2o>?!z%+b#h%nton(}l% zKWQJxii0y@FWs$*rkS@^{!F9%8IFq|o3UD_z)BM>HxoHel2b&u07)-Rt#no!U|kY3 zvv)HdR8NP@|JQg~?d9T{WuWKBA21HaI!xJ}X4Ar<8V;-?^w|V-gaQ3y27S!4f~_fc z$n^_bj`hQbCJV!Pn{vB|g|uKrACZo5kQSnOVL#IKCqE%ufFvmWxF=}$;zMS$=$ zX*JH6!;?kD{JX*xAPE{4DuV}44Rmk@K3bdV$RRPSedt5Rv6w5?lY5e%j7jEA8;Onn z6LLjL{Vt^^{N_FiBN#D=I>NXg=wFr>bx496wfZslP76@f?`@Rt^;&2y0UcpL|09DA zd2*X4O1)?ZYbpqFqR+$LL&_Y_<%`eRv3Hz5rW0%U23*vZE=JP6Xbs7zzC=S#Ot%MgUn!ppu$fiwrfbLA=vYukv;zz*z=#M6+hi5ei}`dZzDa|h7oAD9uRm;N@ff_ z%{smTwuQSKi#5h&-TCH|UqUIke&pny5$7kJI^8S8F;us}@|IJTbmtf&KyeT#pNN4< zrLC8+p8CK}C=iFjC#jQJAWX0iVzxNTeD zHg*vSCAJzWB=hMcDzQUSVuzr_4%LbW8^wc8i9u2_2Hc&d6BhH8%|uW(OW1CCw#9V& z-9Rki2KJgp1@UCSZpNE$*ar?td9UZgfaC@V<995T8n9|f|)Ai&Mw30}ot zQmYIk@IxWiRHjk#+xZ@~^F3(iduqkI8^ycP&Uwu-t6f$iR$u^UQpfr+*mtalZ?6UP zFF@L<(Db0wS0Gq*yAJoTPxOXYM@KCGNBy39#1lJI0<6~&zTn18%z%Ck>(F)T*MlV#ADup`rCjRPGy7OCerUd3okz3Xkn1aG_U88&*griXX zFq1{f5;G^-6s#KN!YS5~9eOYMbtm2%E6beasdgRh`+u_S+b3$#E6;Bb=?@CHL!F%3hbIyw<>p! zPh~YHI0UcCNeOY4%~O!8*2NT=WEh{;#-FlWl^$}6s}iXNz;hK@f6kQ&dbtv_TynP~ zpL$CqbDl-UzhIkmzzE(T=wtx61`_ut^otjhbax{4$rpg*607FDS>z`ha7Hpzg#Ov) zjCo9{C!I-g$uLnMz{!(LQR;#T0U{9DSs0oS&B(%dj4%>s&QV!}T+G=dmnA!088~F* zW^di%=4Ox(!PN5@kn|cBiTZC($YQYQz+GcW6Oyh1dZ*Twf-`8M^(kslqSov|c~b~d z9gVi%iO?9zLpQr+)E1ism1R=~d!0=0?Jm>Yu@pz6qinwnUjWW2fta|XsqZmc`%d5; zRPQm`Kn{vHn6?<%r|;L>*1-=Et^8nbAU}xNlc@2SYCMiQ!6Ul`bmKyyOpQlfjpGW$ zh&nCC8pqLWZq^v!LXEv3kEOoHfbwhXb%JNYZLD#;f6CfF&HtzeCu=!qVclcBJNQeg zzW%=iHD^c*j3_QbMME+ze*#*5#>c=3Dm5bNd}+|?M0@4!D%zQf;7)t>++8r%$f z5$k&fAEoCi9HARj!F;^eLyK6A%b z^dJe?Z|8!JQ7_qGfGEs=a#bmM6dMK1s_}xxC$(u096YEUG2T9PUiUfh6l+_=xd1l5 zK|d!(JJ0`8t@>IduAI@(lTEkl0Fk-$R>AbWytqe)w3E|_3ybo_QdTH4b9g2g$klBM z;LwZ3CD&=#?_5Bmp>DiZ35%rq|GpHx2nkWM$*pAJ`k{-Os@+BPgS8PNS-+zZ@maDB zL>;v*Ax;>j<{IWn^0;hY>t94-)|yYNHPOtgwVS0%&-co)p^G&p8e+H1r4i+Qp%8sYL1nw?VLC!;!xSZF# zDbc>yNl^gbeI+_nYzZPl4p{Yd`dZzLhk=>^>iQQhw749HgDSzn9(2YEWoV>t%__?R z!tXmLr0-uMed~S{)A}-gkcdtzZ4<&#SMCKi#P0e2-HRt*j%GfnZtftuxr4r$vkt{~ zWSV*3K&UW7uCe2ia8{_j^kN<=TOs1pUIVwguK^B3rq!}s?dP#On`8*YC|vn-c=bim zG8tYghm)h|c}u`-V;Qka=F!OF$#!#PabtL@==bh#U6rJ6AZX~V$z5484rj@@A&`-w z6d6H~5n@ookSk)KbYnck!>N+?Eo~`^=1F=~FCl><X1-;c8wIFoUzY9dpp z&9N(N2g{&O6kaHh^zAWLP*VTwKD@2uSGmK)F!Rc~BrGA7iQoss7>;V>H-^vS=vvOY z9PH@y78G8(rR^*@CbfYtmSxPc8QYiW6HR*FT#!lc%L&qEPV zQFigE^V3ENH$MmU8uX(ue)bNO)-P!iOnC?N-F&tx#>9;qwMtZTABw zx_!4AbJ)m(>d50~gA`Xr4+`{LpTLiw1Ac!i0|@vf$~Zx*c~YNri~tXU5S7i=qH$kWE_-JB*erFN$4LNx5bHL*%Ie0wG?=kjg3UDJ2TA^GEpcnE%^K$_GIrZ@A zDn6|8(oUwC55UAU;kA=#po%^wRrE2aqL0;zA8iyrirRbpMgx94MkS}}{2cImdJcZ8 zebxOkau0eUfS%0<&Cdb!43!~imT2A8c~zeYz*P0{np^d}4YMA=r{tNq<4ap6~zrkt1V2I&$Pb{LQd;$KTVD>~r|zmCbIXKT6h0 z&Y43y9jd+;i9wwddC&!;>8jfi)!u6Sp{{Zcn|S$AYI@&g3IV68g+{jN0~Ret47ui> zWTb`tQVfG!id2Aa5_EFz)|}#XjpB8JN?Q%W{0X9QB7BiIr(+{ z9W(uiXum#D2lz7g@uSsYy+W*mg+}`HfpuWW*MX6)4mMi}3s?#L$t@0|r3p3B)iicN z4V{0NGmF3c*?c$fEp=@b8WRb`=V95+WhfuT#7%Jb(KVm77OQTdk*%Tm81hw*oANlC zkCh8vwC?-|{hr~!>RusZESPM*2g`!hF#>MdV;M%QegbJ5`b{*SvE;Hcg zt$sGUy6cBTvZ~XB9aX1PyGU>KNN-N%#qw3XS=Hh%bTw}#ax(2Xd`3X3dKigXyQrHx z63#PWRGm}$NN@E>Z=HqSi$pja3%~h=E(l0f4_D}^D75{g&SKY6bvCPd$z>k-iMi4!zr5M{(qZI@(x* z`x%d3M^(pJlxylG#bKKg9*d@05eH*p=bc*-hy6J+d<^1{>c_fE19xLf;yJUdL(;qz zl_TFfOuqH#F5j;#b!gq~%n0AA@<)2B>kvF|N_DC>4DNm%$)&LvfbjECtG*S#4gFI1 zHGk7l-VoA2-Rj{GjV1m;_s4q)J*w_eA(7tdk={D{kSm2PfAjm0Q2}wM`KecH{bp{* zHNk|Do#WVy^j43?`LVOm>+rcz$v7DsUFAFSV~u ziLI|&_mPs91xiI`+!0&tPG;uJYPWHFu2l^L*r6Wp?TaZ3J-eiqku9D47g^b!4eI$P z{l&(VTl+frL?D(ff~Wj(@rypUrpXe#xG&WipY@M_!)D{N9@-*?&D6)9-;05X0V|ht>YbTllyZvQ%!QbV^=Ul9eF)XbB zgSP7c(FtQQIYhe3q{GiQGGwy??=h$AjBC)s@&J0!gci5uRM&dzcrdo5`p3mYGv@S< z;+>{Hs8#k%rfZ^n`p1)yT*{IGC`&$S)raA?q2Eqr zX|;Fv_>=qKZs=EtpXl-kJ}|Bh1o-T0n)q{?r#Ts-SoM!J${zy+ z^sygh-dzVMWIk<%1DbA81h=s6s-5_?P2bm7C{q-zKrd9b)$T>IO8gl z;SdQ?Fn;LR^xmnzxENzkW8g$63@$`b@CBSG{HVP1ABA`RqqX8k8pV&04Cgp)k(_fX z)(TggA+bF1QHti|LVC6d?1P=V+BU?A6;(UInY?3}svT1}i50_JAjpXauH%St76$b}d$*_3{M36QK z5vUGHQA*Lbw|5XLnlw?=B!kf_b{5H%RnNG!K|rSPwPYF#*Q6I&ywo&CT z1&XUAp^;g!P|G>iB}e{^3%uWKX)a((TCLdVwoHm4RDw~4xSvpP+_!YOUZ*|O<#Gjw zt1Qp{J5-z+VErlb&gjAdyW2}Qz8GKmkLRA*-uMYEb#0!C3&zW1?YAJyn9l-T!tAKG zYD!(>H_$#SnT|)39De?nDqJFg%(&c@OM11^179Fc*jxLXifaz^;%!V}E~WS&&JScM zaUqBvM>Lm~aLpb$-cVzSXOZ<{s9oyp9=?;|Y zGoDOH34u4^cSpY;s^b!o`WKtU&)3~iC>|P-`B|i%LD`g!m?T=%FvnxY=15nl1Y3Mk zFLFV#t(h3`J-GHt`uJO%u@RK8+?j;#6PS#vEV@|@uphb&$1 z{>tvq@q~(koyS|9MTuC^*vKu6d`AF_Qfv`lq1!GpxRh27Kqp zfqQ)dF_jbxyxan?1tb|wMsr8B?W!5gtN}wZyG(O0u!Edx>%DPPc6~b%?2)qCW4m9Z z-Mrnnoz@o_hU8COxfv@`?Q3u9H@fiOc0Yi@kDQo=D{h3lq!gX_s$M+2V>4^T<*#i<$7_Ku3mN4LZ)4?2JQ8%5b zyx@!xI)-5jH{~H#`E8$tgEb^>U)-!d3D0^Fw?Mh21Qb74oWI1xi!9o93OU)8Q`swP z>q>Y+eGY?)Hv&h>&3LqqfX%ydg(4h>AcIW1?i{rHfz#|9gj)1IfNtoQL*%Zl+`V1Q ziZm2ow={}sEI)JrmTOr%Vi^#3qyPNIdunRvnZ*#9Y%TSkmfLeBZCVdkPC7qM!{~PVtR3gBsIM_t6;aH4^^j^ zgUF?tr#j&)f3{Kn?D2_R7Yqp9i*|XkQJy4pc#z#aW=;TgMUG=0H{~|`1vlBF$*IiZ zcz$cqo(BE9bxOM*c$BZz&5iQS$6c$S3T#HrVUF{|-?c7OLyO=_^$*-eoZC3EMr4PA zo?`1HdvmLIPIZvS61%KR)GN^QrbhWD)T>baHx|>46pCm@qGL27sz&?7K}2k1k5FW9 z!jLtBJALD9W$o-@4@tQipW0a5Z&KWKfaZcO43IW6>EeX})L89)$V%S#pY8Jfl-6@_ zyHe|(AL8diEG7hzOi7y4_m&@ECk+z30kEHfG%vxrLxz)oHz1ovqPq|G1v4hJsfIlB z&beXj(|E_Z-0Rt7_?NOkoNdTX?6q3w$V2MqPDe5gX4W!2dLKH& zaK;E`UdC^x%cyR9@9LFN4iKRXx9qLMWmDdJ5wx`vWivT3_)Qw0b~;UWsePm;lHbvB z>?S~$<{>H1@auPPYm{%3?3`z^gNEv025bcPBjuPI@_JT6et2Pc$Y|BQZl?}zQ_FON z@d$S$d$;(4Zu;yF|4ed1ViQ=ccw3`*8$3e8A7-!9O+yg^<4t21?~?^QPLju zB9v+~yiX&>Yh?(c^CpgyI!lj6cR#S!^YVup4Rk{fw{ZoH0kG;*vphJRxlmjPEr%_aGOmtERfS^A$nCK?jxYVOr9)^?- z;;81~-HVSNT&L$_2G{DjZm?I+lPjEgSwv&jgoZgP0ermWc3a>(Ug+Rc!fu-8bWcKO zI~9iCu~Zhpip6UR@7UJ7K2Rjg&!BYcjL3K-;dFNrUIvnhgbaX$e0UO)J7z>eg#c&< zHpC93$e?nRGVo?(gA7E3&|M5B-^>EwmDIg3CJY)&Kc$+ z&#zxXPhBrP^~WAW-0VkbW>DYEETeB|?BL38r*E!BWub3IP2U`qdC{S7ObvD8_oGtz zDI3d97cErx#r6Xj2u$Sdh?J+@S|qLIrdt2*X_$wW+6TnFQ9LI#Iu$n&tVtc@obD&M z*FSF;&{8&3+fkKG>wz9_hJ!6QR=)*ypg%hm zsp$fy9jFkVBop#?(a7xBPw^V)3yty@WU2kVQ5r<(u++B2mfGfJyN6y6*-hRQhSjTd zLq=GFNLO1s7}hb-j4oY>W*kAHov%uRXgBgm6}#2`W`y()D6<{wmFwXs+HyTeH{lf> z3Dw!B&UAE{)^=VYq|WQx9w-uHJ<)p1Qu>??aPr^_x;7AeJh0#1%yZ>G&!rX|Dtw-E zd2}D5L&xhh7kNOxc_q{cj{NfgxkDEV;!*>I)=iqZIFOva15(GXVxa(sf@ z4Y%y6b9}M~#0>^ZK3`6B#aCo03=b2%ZtTJ|XI419m*1IpT5TH7Rk(5Dm~wPE@3>HX zO01FQ0dyXeT)>mV+uRXN+yE1;Z!TT6r8)-TAH&Kv<}~7uVhp+!3WPV!fV1vn-=tZs zlMO2jLUAO~u{QDy>dzV2V;O{=w9E*gw`0idyMvpTB)+p^hgctP#l|EXZ>?KeDCa?q#7b^9Mv@@CDaYhssHs>dU5tCk`E>IWllek}<3ClE(KyaoKguBOy!9!{)omt_U>|^RY=w$nsRXBJYmKAB6V>A}3_bzF0IX~&P z97XmYKwFUZzaDM-b7%{8>eAHIgO59U?1K$6bf_ASh%wsEkh% zSp;vxws89_qn$OR8N#xB4aDm>u5^Tc4=&uq+JA&Fif5EFZg&n@z*~BLwToZinBp*B zFl&EEsC6ZThiWDVtnW&(G|{U(tc6=K9!hoZ8kE|3hY`*@wDXIiGmt(pO+H=X1;74O z#n`RU(I#9mlbR&8O%X80aFi0(mf2;+XoAtUdP)#-)Q(33);;peomEQRP0hKoRjTu$ z0aYd$-F_B2X{@nA{5b8MR2&OnYvYVIblBIn&ou)1o4MJuy4$S_OclSbZvR#L%LdYj zw9+E+j1F4tr=>-3133*xzpP8PKE|B%1wvY_>8Kr64Ps--lOcfGSi%4{mhe&2{9Hr7 zShL;5U2w4aL}ocu{TV!*jga5#u&_tFVRpnLKN|X_fBu=4owkO-GoH@#fV2jdnhanW zkMU(ZRb}v3{@(kkt~zAWOFkofIK31oe;9AOWt#TjU>>78_pQ8O-a?LjvrhBL``CZd zTgbUr=PhKgS!E2og`B)MZy`e_l@2mCVxThZNBENL9dBCQWYegvr(j^zwVI^QI!_;M zii!Ap%=F=^1(d5t7y8iai6nY>`q(#5ACBNU=yMk;E&6aa+R=x>W|c9Z4;L>OeHile z5oB9jCHf@Zfy6fA;^^}*=*dG`dxYY#D#fjT2@1bE^ZMzq=L%;N z!?$I*+9+31jl8hOt5B|i3ro-TIJR%;mOv+Q9r=?R zjfTI!TmwGB8?_&4lt01-?1Ggs7F`re)EjbXqS1ViA{v(Ae6&&i=n`0U#ibkjv@sdw zREJ@Tg~m8+{P%G(nm#uMe!TGo6)ZD$Z$~zsQ+cY-as!%A|8#qVQW#mF3VYh8SeOG* z?Lg?R0KM?~eSU*aPKa$cY3o*_d~T!hs~FEnekVkJFJp$OEaOX&4Q47%ksqNhvvUM- zImzgz2~J^Szmlz`Lf89QbQ~ApWayCz1YmjFBIFC2RYqKtJig2<=LvZVX+uw-kO^?J zRx%#a8b849X=y=pHwvWdqosZ6Pj33NOBH93ct%w$E7Xh@faZ-n_uBSkB&G}|$5kWL zF}cDNBP@P*`V_!&oS$}pLbobVlRN~AaBNW|tpRM8a4RGutv-wOjh4!ZzRheD@>t@f z7grM5u%^c^U8!D5$~3LzQY+3t4IA?AIzWp#o;BJQjAssRNg5l3Rr0Su<$)SL6*nPr zPMuAIZ{SO;PzNi!V}&udPfepq*f3t~T*B3ltW3EUDd!Ulv^rDfduy~E2PZL<(c+;P zz$61qv`Y>;F-0l(Q}6V82oK(fazE>!uws6JF`ah;I+@^9IsS5HIQ=Ny4jN5S5wa8v zFN8s{lJDt2Yop>=OM5;&DabuZ!Ym}}mP?r1cBia+kTw@`S?hAc}EsPb>_762rh&AM)BK=%W2!9(rI6Z}F__+`+;Xs}1rFgFK&w zj4CgJ)s47xpjxj;4~8^b*43&zbC-21^5bK<3Shr zU&ELM963*0EV2y@sa_*bfS}5u4%{~VksW~CCJpFTf`AXHXrQNhWfX#gSVzjeq{h*baDDl$1^%?}Ot`Zqsf5j1?6&=;UC%b$56rgSQUh6+jn)Y49LUbSfmq zw(m5!j!m{53!C&=i>~u6y4hOPKC?v`<0LML_W<+;h+IPQ)))r_k-|AXCpZEPI2<2> zWj^UB8c-1PVOU%#go6@Z|)q_)2?!j}#1qVHPtdLp7AvzOZtrGOb%q--G_FpVHo;U+#UemR%dD*PJa)oC+;PMeP)EUk~R zqOJ{M8f-%vfYHMmE1M=hFHCa{I%=HQJOgON9M*oRm%IZ2H$l{C|KZX)1&yMTyon%r z2b|*N4Keyc1qY-wwQRoiEE>xc-Yj%j!ReQYMpZUk@_D zd5+G5p&qNQaXeti~sJVbbF(W^ZhjcF2)6?kHXG$nzoX%BTsMGN6 z@GOV&(LK2`g<0zbK*zW0U2&^os=R9H60Hi$+jUQOxmGQLN}j5&Mm zN9KewmlrT3IM$!AZUO&X6^m-Pf-KwRz7BJ79cEDnOO&Vs2CJ?PbFL0Njoj+su5mPn z_lcfFl}hp_F)-lyD0r4S?2tVoZ~qOq6yG8EUQuAs2V@ zIIOc#f8IUn16`xq@6LzTeruQSukP}Fpv(7jTMx(P&ejF|*}RCKI)A3H!L#)Me?9>mYP}4jzGl@BTs`=3 zkKpRcZ*@VArw%NtJgL7d?ukPQfQ}t35RE89vVt)Jw_#Z25jY{H&RfWscAY%2L>GwjYepkO1Vr4*~mUqahlmG3mDX|pawfZ{mFji<3Pef!TMcq0Q)?^ zaRX?d36L?)RzjWaww1^^{3p$jB3KI(SB%^DM!%HeXe!o(Jyt?T**8C=7HM zi|jQOmhG>s)uVlvDb{KCUXg*?ogo!Pgc2+s?JFfS^n?ry`3&xCa#tlbDDt%amCVp# z=xkur2U2{}rxKC~t0p*MCKCa-i}d>lyHs%sT?fG4KC@x1vlXWpkbT6ZRA+^SF0iw1 zSY4Zd^cfKQOd!_j2?)7E@zJEps!v)ML+-Fp%pLa#t45X2TD1VEjflTALmz3!P@vvD zhl;~g8SPgg!1wlrj$3#ZikJX6?jTNZEeQFzZ}cg;_=UBF!e3dOpf%p@^D19{UcbHDt~ElzJy3&p$s1xVEUF}ho+4m0Bsr{$LuT

i2kk997!ha98?i3D@Gy=oKK>UBP~o?z6LRRF3@jO z`AaeSLsT(OjOc$MVi*O||6&Z1K%D*;Lmd7WN?z;l5~ILm^41ppnQmKH+8e%UZEAJapx`U{ng|PXo%2>bj zSIlX-90l!+&(@|Cb8hWG+%f0&OayeYppR_FL%_F+(IWdy)ESeoDpa+|-Jd>rnIhS5 zSSao{eq8`@LkFIA0epPFVXEIa;JNcanmecBMxH<;Ta^-x%%Q$DGG;E+$UM5qb7wkv zvv?rMouWcU$?KbMk-(k$8o2W{;!ggOJEJb#ITIt!(X2610&$LJ4RH+5g!rQph^LZg z@8kW)$I<#o_!+i}{u~-Iq{=t7exzQ!t697Y4jP{5>W79b)gi}0p2~hT8OIRHM!l$e z)Kj}ho!&i4JD2mz`e%0C`B8UvkJ16^`MEycJy+Brh)_V@8~E<@*GJlXnr4o3%hLebyw=M8-QEM&9wV>Dyyc?`8Fs$S0-`(Usr zE6dKCTp2H}j2BnNi}TQFbaAYV7Z=qRu*+UhXl1`PA}0S<#*1m^=E`_c{@s=F zVu`CH&4$D&5-a0H8pqD}Vpngaof$STTp2H}j2HdrBn%~2#*3a5Kc(ZvK2E75SG{(b zU!0YnAU(gx&6V)h(b~q2U`%`S0}SuMr6%a+1gPr-9c_2$8ag!-$Gpi5{2qNvTDI)JVC&8Jm*Z(Mf>(D)_H)Y`k)a&S@33&BqiVxbql!?GvC&R1Xe2y z6^urNDO)||%H}K+T-lF4RAu`EV=Qgs)FT2t?Mp1oukBajJba`G*A1)}+B*3W^|#u^ z{x|!Mb%01^Cv4)JX@pyE?2X-r=}b0%2@m3_Zko&1J2h?1S;mnlqGiaAmLpEVk(i!( z`W?h2rp;6rO`Exj>>!ch0VN1WPcVfYiUCejML2DyT6`!mVU*6{he6Iozn$PRxa(Vn zm0<*=aMxwIRsPZm`g3S+YalfX<`xWn&U6|2n(3Oz;I5f2LmV?*Li|Yy#FNQeFV^JH zEFfqp!+YehciQLp=Ze;gg*jKm(9z5l^@+79_zcB@Kd0}`W&B|0iq;9($XYxk_!~^X z>@x+7F;2h~mm^^P$|C_&u-jbGGm*~bih_U@JLih5JxAmA>^fIu?TNV}wdXT_(sM=U z0sTgmzwulVE0ShJ&J{UE>^fIuh{N_5;veodSM+Ido@d1BV2Tlk--6dzr5fzL^glSwI&RD(@iLzYSIVWUXI2AW0=Y*^}v1-SfP_GU#C#1$q z&IzTHXXb=Nfs8uTw+vk!t%555C7|D^@|Rr5Jui9ckaI$g3%kw<85i=_0|03q^_py&^1gFUDDV5G*1d~p z*vIqd<(vt+l0RCfxCU$bTQAoVMNS9Z#-De0pA!;vCvRFs=++Oe*!Nh!xMJTQX|34z zt{>1zF;1(k*!LQgqTk$0o$veW75m=VVSTcJR_yx~``#v$SL}N~&|IXCa(9fvq008{8(@d=P(WAm(k? zM#(ay{qTw7E24cilyN=qI)^V#l0zu=uqDSkKx3_vjr8InAK5zL8rf(1$Qa|D(83`2 zM0zYwbCLlSfV#@RX(WJgWH?)n);*8mEW@b)QmkAXZC!OQ)7oR^NdmQZ<#O zuI#PDkM-VVBk&@vjV1|fArZJou$Lro5g4J39D(ODej96F(7^2n#V#PFa0Fh&z|!U} z7>WsOi2{`tlx$=k4-t4=xJLGw1ZIpQu;M%~)T?urr#Z<$K7kEqN8roBu%5uWCkflM zjlk-3qSSJ65!gB-M_^`g1a5-!tUx31XdtkKL}2HZvveNo6bH2K!x_#ofz79u^q5hA zk_5giN#I!#hBhQaF@Y^nAn=TmjZEVq0&g_}+h-D(F^<5B^QhLVQS-*gIkxlnvI`si%4x+rFtJ^L(*Xw@o168l2l!6%1ckO6a*QPCcu(#hFslWZ^=h zJhF=>3mM-mVzQ7~S|0_!8C@cGLV;t%r(hqTAt(OXD^N-Pso{&`pFKVps|UvVy49;p zfVWtOMI%aJ{PQL(=?DLm)QlqoMnz2gDpO>i+0Kk{?QDyuoCrbvSRQO)RFdj;Weta2 zVF?0u1(Of<^(z6l+%cq@bK+;c0B903`S~)y;YU7|mh&u6RoX_C&sz0E2EC+-f=rpJZkq} zt-=1h*WFRatwJurOH0w3UM86NZei<}-dZ^Cmfs;dV?Zr1Y16$rbjA_q&^d$^0HNp! zE(hSh@0JSZOas*Py9RtDo~NCL(%)KGkAhzJB_w&qEgp%Uq0+OMem}oXmkKZ0kA|H< zDeZ@&8)1Nu!OaXJYMUC$9z5Z&kK)g7Ns7P-P`c+&|1Qo?xs5>DCs_c8dGMW0QqUQM0$CC@X=9@?M2gwMF%8OI9jG1{O-{R=l0YX1 zlxa6> zp0*Y6j$UaqKS1jNspLolM>?}YRJ6a~UvRntqnM_Zba2QM_GFT1uDJc4RtF>yi3M&tM zT`Og9UQ%y$oaGsgl!H-FISZ6g!CuRyt+!`*<%+|gRN#opjrMI9Z^Pq&{=+UTf+-km zJ+8-L2jKQ@53p&H9R%0nGhS=))j@o!H|`*k$y+b5L-No;K!s$-qO-)wIdxnw5JmPe z?n8XdaO{PWdxd}(CxJXd4;793jri2nHyuU^Q8b-bkbTT6$YNYUGjTz0w}O0cH!i3# zfJ4<$d~vujrNZwcp`!5;Fkw;OEx zOxTQZ-Lv9+^G1=-(1>aW(nt!yG9WhY>>A-GEE^CBc%};Ywz^%QMlK7fVe}!4IyEO5 zz*t*JnsE}wRSk%1-n~H3_y~eGPHY`Ut@lB(`_T{2v~v={MNP?c1gS+$CJ{K(P7*O1 zmezqYbIz}OoyVHz*YRb!^XtBn)mocbMV(*AkfWE%+IT|c=|GCC6}ypRLT{I7n>+bW zZABb0MDhZcILE*-Lv?M*8OiWYh1%r+T2SsU>ZAlES22@#EWEQG!i0eEVhtm)z(Px4VfT)4yR<&+YUQ77mp&%mJmX1S7q82!c>( zM)sKy7~>!qwG6#B_7ae*u{tdl1TKaHV9ldDyWTUPnYvf1$ zarda9?oq$lJxYg@<(GAS_gw3{N9ihse1Jb9ALU1VvwPG`_bB=Zx&Y)l(-&IU3*{VNbY2Ppj}ka-T!@ZVnpL~g|26XAYz>j4MQ%XH2eZhUI3 z`Uzn8zUMdegx1)W#qS1Mo2Mx4yc2apZ_9h8%1H1n~dVfmGc?%PeT%p$oPUG?KC2y z3CLyZHggl?f&DkhZ8xw(1pD_$La=;+TPOzmj_zPTx+K^g1p9jqEMLA`_>~y!W4eR= z#U;URCs?k|CANI|ZsGMY*eSM`(KbWC`30oSCp&4&iK+Q72;5qoNiN;U7!mif7;d)B z$P{qf{eJM|nG+3;ys41=X)Zf(9_R~SA8B9F1H<&|HkO3XV(n>f9?@8Gf1bM#l}~WN z&Ez{y{P7-wC1I{TYM8%eFz0DBMA0alhbCllPg#PK-GPfbl#kQqB)hhWF(j(0TbvRY z?*i`PD^=xx{i>s^d?}KH)|)=9ztc{+t58tA`Zh_H_vUWnTRJt63MVx0MV6+r)T_+i z`aQIi>n!~g(hlLDB!lRa8GqS{^&rD$R9^L_lLe||tH=UgQj9YP6z6S7+x#Z9N=m#G zjb8dkjz;_Iw+ELqJj%i49J2_T(BZBcwW3~{;6|nQrl_>tsAQ>~kwPlzI}ZC2m6*j* zX$$xyL#1sURLav&=;PSQ4XB#&NudiyD*H@QZBPQ7=Yh!%0ru>p$xe}~e_2wk`ya1v4 zV_+itOv*6EF_Gc|6B$NcCN>_k?kd;eZ9(v!6~oDUZ+}fl>tLSMdYzW zfjN4Rr}aaC2RzXi+iaDyQ+oZO))O4@fDZz{AF`VfW5s zP$`^zi(l^Exl8C`N1&e81ppEG0wS$&`U9= zNY`l5V|90W4tSjU_it1G-?jKbXKyU{?mH^(^9jqwBIEew}2f@&y?6ZwDJh2X|m z;}WN>Se0d?^T($B_>%bzq~v2toyvd_B&abULz~hX(c!$OecLMuFedqlS;%Um$`R08GtYEp6l7&qkgV?RB!jF@3LdcNB%3_qYieD8t)$Ur`@B5yGFHtJ0HFF>$`k^ zMeF_lidOj?fBu{&KiLe>b5x?k@Zc{_X(qP4G8N;BVK$kt4JCdnWt_@5kRi z;qN(^`+h#)W&Z~8{V$NGf#+B8_w%^-!1)!1sM70;rFsQ_@TAu1NiQ!pP9A#Td9~;| z$!~R3kIB7w(9^)L^fY{T=z&wr)366$3Ripy)?q0+@iiK2=~Azh!@x3b+<@EjAX@J2 z`Gw&pp(AaLFt0SBe6Twp6G>HgNDG$HzFZ5q9gzz9^lmw`Q>1oa2Y|%}T{Kc6K!3VC z{jfFF$*+&Y%lx;HM5>MX;-PnDVe^pk(O_d}exGH6^A-WEgF&Z*1&1+yAc-9rVRIJB zu2H{BGr3)#Z1}EhaO@IW4N#%_E@QmyRaO=$NK4_g9F(@+&Ao$}GIvo>eG^ot9jad6 zgc{kA==DwOpaG4-PVv9Imx}*qP%7>rLApMb&)wdsbfV5IM27Lr;(c{xX}t!yU1bt9 z=j>XvZ&8(V#_l$~kai5szgrdK+V_oXD_oXni47;$eryM{M-1y`l8FCsUglQ8yA$v% z7Pl_ckvs3XhKsMD*eiaKj8xUTg=F3@j^-vyv`jy}-7SiSL7 zTclqC$ifwuQGB8kuT*@*Zz+~PSlt7dWNg&Idh&sWJGAEhff}w`R3SDL7;w399z8-< z@FyV~2jvpT0vQvs9Y8h&APgChw+YC24ki=%K>7m^h78D41!O7*$aFrC^#KS&2IT9Q z?K-Ht__EcR%?HvKfG}i0J|ZAc!s6#f6+P}@+G;)fc=4`DG_ zr33#dPdWIIFww`miFwa;c`5*@!?cbt@!jObzpBx{eEKWw`o}aPyDzjPsw{>FLM{mD5ChsF#nzoa6ZiE+ZK-;sp9Vr z{1sp`UyQ#$!5>#XJ`r~CW%%P^?Kk1?1kTLkFT$U*iKjHu*$IOfYgytOrO#ec>HHu& zEM(7bgki`t3ao1xxTZ2<@7*EoLPNo^n!|E3lIdI!L7FnTrV^ynH?$Os(d>&0+5=1E zDhI)Gy&wk?o96ItZ>g3;MYc{)`^A8-4_?=}*Nh8JNt*Bp$7nnal8z7j2vt$}3;?N| zaFLWNoE@aE1nw*=y#Ir$rmI!B?Wb@Zn4iOs3wupN7|pQ3g=7F-+$B3$&~2B1!2?Lh zyK#T&Rr`m&wu)mBymYL=J}J9|V2Cu63^Sx+06)H-1VLH>z>=+DO@`|enJbJjWG0xT zLv~=>MI%ZOFXjc=cc>t3$3X!RlsN2oeM26%ONVEB>vHUYMrF@HZ985owNkwwNYI|i zu*4KTwe}eO817p1WhzEnK2C;41Z$d#f2tPirFO9RF$RDaD{TrhE99^agw*7w=jb@HcY+i0sWWS`AY z+(vVFQ^VL|eg<*rpivNsCz$QV1W(;+30N zcbU3W5xHEAe&-4ltW2>`teQ3^J~_?9C0{NBfH!N!>#-~YKQ>F80RbU#81lqHM`^%k z_&8J@$Ak1~jp8RJ5kD_QqA|p`OGwW^0~vKuUX7zl0Z!Gm?rzq$T^*Sy0tj%hCjGDR zqS74JwXfVNiRZS-lz{ZIRL_QIzeH%0d>=A|=M-_LaJ_v^Sed;yI^bX%Tx1^>G5# z)L@N$9LrE2m-qd|*1J%-_BaS)7#OC0hqxLn|8&>bY@@D(RQ(U!faawt+gq>C9w=t| znT*4b)#gxf+$otfY^nD#&>{V~Q@DzwNCeZdxVKdUB)rg;MBTQG!2@7@i}L_n#wOKN zIzyhCbH0PG@8A8vYE$O5@=cBMO}w~u*cq&I01A)9i0iBpM~tGx@vbWcv{~ufgPJj2 zdb3jD!&4}`Z$G9GSY)n>P2q_@*v8G%OLZ7X?4nB0kBCk8lf}{YrTE+( zS8UZN-`ObN$-P=0{0ws7@2J2d>E3LaKnny&3l%=3TW+sc!L{OKqd3V)vR9G$wbFu? zzc$K3Q}n=BO$NO5R@pI-AI>WlHYpG6vZK33V#f?91CmAYnDhR=r_F<%YUnubong z+~^mpyY~@Ot20%(V6=EPZ9`4K(XUqe<&-(*)1!O|wl_w-$(pV)Ehzk%*$H$^p9r1u z5Ojm-w-}`n)2?(TFa)n)T%cGqGQy%o!T-J@BYQ)A7;7Lv5oC)MH#dQX^z) z?M}4Q;JZ7Z*Amc84B1;IRZCrqZRgM^vsNmk*h+=A-U0!SOCA{lG-DKo&>S&%H3zyh zx7(D0?KAoYm|^Z+2PpNI-s=0xTpiF4VxwNr0X!L(IzV}CNF{I+km?=`w)s6*2e=GV zh%XGkK3@ljIipEE>ibOcxvFEFh)M@Aq{o*EW*-wyU-L6w>dphGs(b{ zi2|Oc4q`nZk&mSL(6*)k>~cw;Ce{N~ie4_0dSFgCQxA+K@G;4E$HF?d7xjSY8q))t z0nr+ZNLsxEjMkrvzt{}a16PUaUiZXhjwZ^K5U0nI&dm0;@xxB9Gl-EimNB0B&Y}_1 z4&)+3EF;%ozqnY_2D7XH^}Be_<=PW!#gJ#lIeyJ(1AU9qS{hDArVQHPxuQRRsSW-w z94&d;U@x@69+?F7@*ZGgrG{24UfC#K2|eDa4Qc_!x=a8_evw8Tw85yCOQ?mIDAWca zlhX#)S~=QaC;^>X0MbpvC}AR+7MR6%Y73MKyWF$^{DAD>&dZnGf%E9wr8J!n|i*aIfagB*Ko&9^%isLYOi?BT~3pEJ9ID$&$q z7+=g0aLVprqS)@3XS~-7E8~y z&594RKC(yMPRjF-=^YLCR(zQMHGP;^u)U%?yssj7&R2YxGJ98in0``dW&UF^x%&&J zuEV&-ewLLn%ZlzuPS#Ol*ks*`?pVG!Lf~A92pF6S(3~|3bVup{KB~!ezq_Rn1^% zFB-m|#`L8oE&(L)Gmz1zXjabzOxw`5PGxF|{#1Z%d)XMJy=+X~`Wr0*!^}y91;+7i zM{TUb680X#!46wIY#s%B>iCJJRu{kOziQ)Ae;;uoawCi>t-1rX=x6Gvg2l^NQ@(G3 z-?=5dYN3&NeYgchFcepG(P!0=Xill3S)W9^XZTi+?(*MY5b_JqnofMOoZJJ?ugxlx zhdV6LHm)*OFt!951$p?5qaZdfq!XcfoKIA|4!>cR_HP(X^nXt(!ssLN;ySrO+p!IUt zRmCR9Rt@gG;`v9e0^DH5tyLcGwydCN;}`d5Z=r}?)&%qN z^atlkYd@=5ytZD%VQi2h&des`NZ%RCSF`w)dhy!!vpn2UAhwM(HPHjr5L-yUu5SND z8wUXqtdYm<1rEVOuk|C%HvWxM)Ib)rRniR10NDIgn~Yq?%H;H~Ff~p+V-U@pl~{9Yn$*5NU{vN1$zJ5!=BZzN~Iv z*}j=+d@cMwo1r8n?NkKlM8J=>jEZbYULu|GHLwAS0m@s396K~Y@j5851*NF^OzW`* zw`eEP6rOYBn5(4OumXRLvwJ z>a);2jF(DdmiEQ2ert=kUhnkcJP$CO2MLf`OCf z2o!>#loW)#@2lIp+Bbp-igPUOb?bPNleG28G|j1piabEGr}Yo`0bb%%wbiMqQ5>8&n3!24R6%>6N-s|8U zY}iu_1SXVjiHP|e5MeyH3@6zm(Eepbs;@uXEFLCvp_>9BL|MTykff|~kg|E-Pi$R& z1OTrKC|FB6&C(x4)b^Btr$Qyc6~LCg4Z8~(ML29Qwhn6haimPWd{?u4SH0|!+hHZ`ZSU}7wt*O>uTMJqP4D?ad+B-m)32l?-mW%%I78qY7lAV#d&h23bi}$Q* zufcCmqj*oPcz2_CHwO1S_jm#vGMlIZKH(MW@;nC}kQU8n4(f~OcN|2afThWF-9R5x6Si`tXL!8C=l2E08oAY`a9vb|pxhbqpR zNa28nAP!-;g?c&JGP9mI0nY>%Q2}wKCmI668(Wd9z62&cLe8E6l6C;bDWyY2Yc}59 zhVRr`TL6=F2TUHN!Q!Vp31Y#hla=wOVP3}mvikDCGuAmq7{GxYXizx~1zIOzukiZP(GCe;JT0JG>g~RXlG2VoQOl_8GIW9{p-bR+GjV5pT`&w{iVz>+M$d^ zsxb~~u4(UM&;!o1s?)S!UH@CrV%r6^sSIn>ir)ay=FP1)b+C9dTWlfAsT7F?(0ZKD zMi0sVCUA$j<5ul&tlHS~-e({VtU+Bqyu7W_$CuI#+_c7jJT;Bg zdH!?-*2W#OHtvA6aYwCqU88s%tc^!u!1&}Ia5ONp15b;eYoCmdyXSBa(B~S(&+)v6 zCjy|-ha+GhayUl^nFf!w5+v}{ja-_RG;qAJLIN!Vk(Em{!>dqbgK6!9(V)8!>bPM7 zBI-xQAvQo`)r$0{Ea(8U9NuaaZ{GOg%H>RghCP4qMK07+IjK?n20koPr8H-GFk!gH zCIqvt+7BH@1~cNLdaWv24uyAev)HYdjXL}sq-h@qvog07I>lymNeE!1r#h@(T)9Uf zTrqn7;2A#HQ`s*C#6VJQI&m;Iz=b1R=H*-b(8%46bzD(z2~a zXl$;0I=7Fh&07BxT=^eMBUOiFubhldiW8;nlYDQ5nl{UyFTLq@oudd2mclGg$$uxk zID=0!Al)pUFcs*k^*-eOpm2>~8!M0YWu0AlxCK{lykrn6=3c3od%=_Uk|(JjvX<5e zPgzg+87e51rp}D-oI6!_YlI^23up5$@Cw_rD^CiAS00NX)c}}Prhy%w10H#u%Xn$U zq!Jk~t^B;tcz#8Un^u|L#4?*>4pfyJA*(=)?~nYhN$t4>{Y1l z53j2?o?EDXD!iV+*N?l`(hb}k%6~^$t3FqOb7Nh3uB#QUCOE%>6LgQiVY0X^qsDUD zHo^8lB+aD*wdoqhGdA;DD}Sd}{I)}OqgMr>992QWx6w@%jAvB=h7?o)P!Sk3EBkdw{%3$VEPog-k_47kOnd3kT?X0{gpm7ey4(yAY7dMY{IM=JF8x~|1i zNp4IA=j01VXMpi#dW;DVfz!Bso{#qJqqu+L69-??Is=9o!*6}xT0Y)T82%U7m#u$C{rUduh2altu&{sQ+X}-) zC?kIT?ZWVP5N!PeQXMKDP-_u5BzH%l>Xhzuws&v{)QYz@innfjA$%9+HJE9QsI*%l zsJrL;cQ2m&u17bE2Yzd6ZKI5Dx38MU*Lv|l`$foiYM)ZQVfW&R?|N)VHFP^ZE8%OI z@JtmT-z`)SCIp|&=45I4GyzI2&b;O(X??`Fr+a27ms?WxxlMGsC9co2h3P4cGQNfS zSR#z>ufgX)smZ88Q^Yv7&K)S9RMW0rtRhIxCT zx^HO`Y}{UXayQHf;e{NoCTz)C@vDvES24<*%U<0eH6cPY!7y zu)R>dbD1iwRruYbsNvUSEq@In@-@s*Hi~m`4WIf@*YJ%nd|F%ZvlP;UM}hP= zg!DIn^fzk7uQ!TckC8tAp+=gkn_8pzd9XYQ_|& z;67277(v0suKC!D-10MfNPBK&hv1@jI#(v9ZVWSThJrnn*EWhjfT6xwct^Y}C%B!= zM+D??|K5eGhaNZ|^qAt1{60FaI3&N1V-UF5SS|R%{9ON*SxxT|+nx$12xgJ2r~NpU zkx^}nEuQFx7+6(FYG>vH`cw2q%N#$w*B%eOXS&n7hPsK$Js6H}Q3&+DwDNKbVi+Xv zk)!vsjo$Qia#0d$(n0SGh2}EEoLh>RZ6hXZwm{4<`?&jXSD$mfF;5OER8KZlyHpbL zAu80FMDEwsB>3x9VOVoF!XW8M)H=rWSRJN-I1jdi9G2FpAW70&;xc~~njMyirMVNK z*q;jf6X*i5O22^_SVumGjk#8crrhP`;`Q$G)*)12x#7OKWhjBciI^N1dw=3;2*{_+ zpNQoGM>kYXV-wf*Bmyv*#i*a7Z;0w=y{LYcqRJG_@@Hf3S?eP(f>mLoRh4oWBu<%v_AUNhG_?ik_;$*iQNH88+*tDU=k;G2NGiU6cZlu4%JtV*mcqd zG6jKond3~3IA2+)J}x$!+uXo!{Ab|CgQ^Bi=*7Zb zZF;e;i@jLanHNiW;KhO@KDh@Kk}N(QSc;Lyv+XhtJjc7*USVd)q}YfaI^+l4HI2L3 z9D2dS44USC8UsgQ7eM`dPU`1#Aou5JAF`{=dSsppv{DYJQS-=*&WjdoHiG9|2|sAA zge}DewYidmYkJ9q)?Tm-T7QXjj8?{9U{jyF++=0C+ev4>WVy^8+`I(mn|@RQqUj?E4;q$W}9{Lg%~-7SZZGJ3#7T)$5FbYXvBIRfWw!=0dNHL3AQHH@6q7k2^|yiUV3c(>lwl7Svb8>7DV9JGYPUmPQ2Jv4rjtK-L8$NXthm+7 zEpSM~Z~Xwpkq@6)`CSL<*w?wFK_=_#L3UY-v6ChD$T@(znMH-h)*3`e$5AY?Nf&*L zb^mMAtd0XNat2{Xv$_hcg*=QQJa#l1_YtX9Y&+UQcE%bfZ5yGUaMFbu?K=ffx`R5rP<^WzMq{*m2H#^D&>r-F<6EQrjSbV4=jjCo_Ohyvi|$h0 z^b%a&foc$uhd@O?=crgGjc)rDuKLTa>PqKhu54>9w0_wQ6hK(4li+v_D4CK4QMN2# zk!mU0iSB&oD7y4|f+pIuc zY+s|*%73M^r@_MyD-6E^_cXV>V*FlC(e)zno#C^IA~a*8_SES{x?HTPc^us+T{r)I1;n>eU89CEG8cWu!DJDC|Ys+{&^@~X3Ocp&2h#rt0v-N^rk(K8b z=?SCW#K0%m+@JvZZ9=qfQ%+i~dU(~EzDTl~|3ccX@fR?M^mr}|_xJ}$kX3g-2MPFa zIWABelu0@{Cn-v&tuG`jKkdNn7m-k^ zp)bA-rZUn?TG#mA&X|6hs#p{`X%ekY20f!3LhbloHWa!!ID1Jx7>4)+bZm% z5UpVEguIiQ7r5n(a0m{7R%!2!bY{}iE;wfJvl?3PFpz@+0j9h#_0-H&V#?)^1MPXC zYQ#AQ_aPUWA6)k*YiPp-o%P`MLE8a;_s7);GqC#1EqHC~do$M@vuWm*ZK5g|e7fxIC?9A22T(WZ3>Y1zlg7U7eDf->BHLL!@RqU^km9t*EVAgB& z2De@BA(Kaa@XVXtX7~P;xG0bGY5(OWmUY4gSx#dmKpj+9itp$nBQT-#o4Vg785q~C z>RKTk1n-=kwz_5o%YsG(!^iZzX~d!5N#})HK+W>R=4PsG9Qfi3>*YblTAX2Aj=Y_n zLX!iG5LGOMflR3E)m`r)_qV5E!_SOWZ%%pg;J#=hYRZ!l`aqL-QR)UCHO@ZQO>%_C z-euc^Jiz^(<$*HrD4tplodpkhHJD})qMD5&3mi|8c0^1 zxf!nCO!Rtf8AOAtyFOff=6h&fIFR!kx4KQFGCGR030@A4!%e|nJeES1viP9aG^PB{ zm+uidbzm5(9p^=)59)QLRb4oo^gIrOqL*%1wGrEYY}&05OuoymG5U>~-GIF~tDF~< zZ>H9HCRPpKBfbwR(0EWFy~0LE!qAH8F130DW}qUovijm035N~_jo_%PeSm8@UDcXv z^RzRZRfYX{52;}vD69=N(lgg}?aF7xxkIh0AP2=iETu%4H!XamWGrI>MMLY*G*qe2oQhlPFH}erU^i4cvhl+R>jOrGRx<lnxn2HNw|Lcgoo+yfo&}4QT%^5@q1xY z%k{xnof-An4R(vGS-0xUYi8nDPuEp;i@ORf4qf>gyJ6gey244Vpq}d1(pJ2U&W12y}n9p|3xqx-&WJ64PgGv@q7 zolZm8mi*KFvo`br>g-?HqaK>JG+H$KHSz-8HFvM0p>@>*ZTw-sLLNV6u3B>nK5Q++ z$>h4nAKh1_Df|@7bKkx3eMb?0)%l?F&P<~M_4&JV1arMWVo9P!O8`#Y!0Lo!^ryHeG z9l=z(574|5{Yu`Nea_ctedkUmI=oaIADz2_k~4F+try(^7u9we`JpWJV(QlCQWEs+ zHT%3Qk>n&_o53Kot6d-z(`u-koc!Y{FlPeoUdj^qJ+( z)JPeNu#D)PMBlv+Q<29@-&ijnP-&UluVs%O&n>mVXlh$mAM+uc2+UO4aCOz)LxghG z6@&Q;%-|Y=BN7$<(tvm_A?z{n14U6W&cGFk6tf)PP@!~2oNGrHpM=82Rs4otda}bw zKKOyuq#q0MPa&4G9-~gq(HxjnUhhlM94NaF25UCJ>9%vd_xnv~Hy_-fuiF)1dkFq< zj><2N0a;JmF<={s1&|LP>WlU~6Jsm82C$Nw*h+39D+#wi&gpW={O7;V`tbj^PkOBE zk$qbJ-PxzAZrCR>d26Ks>uD@`1*qTe)*@Z@Ke0%=|1T|4Y7ZyZ`wB8rwj*){8=nVa zxI{kq-KAU&Fwh<|LZe5~2=p_=sM|t`KBsS=W7bpbtihCaC-+Y&cMf~^ z0Ub1PgbdEzj*dqOwosfr%(&^qRMzFjgrC;`6~|3U&+I-5i0>&c@59=%s^;_6DP=Tk zc$;%lsu;qcj{j>ZYjN>TefnO4P8lQV@o)3(^wdSEDF0Oo5!sX~EIu#Ni`Fv=a&6ox zcL;7D18$|pO)}s%Y23aBoLVRO(o;eD7bc(FRq9;*B@B0-zF%&@kqM`NW8@<=-?#Ps zu?Acz=@tLZl8;cn>ov|KAIGEt*P{l$OW=pmzmf70n(umzD>LA>XxvZ(u8^7!{>_k& z(0q^AxHAm6=d#4r(qtC@PLPk#eAj8*1Osl1#!WNeCi7HWsTKonoyM8!W3$GsH}KI$ zI{McnAED(f)=zlj23(uQjW^)vBscv_%13CvrF{ipDsOF;xaAr*&XDi=EODxz5SjX0 zg~plMOPj_$r2BE09jc)1DfqXi0XLg=FyY@G@)4@%HF<=d)OK0&d3rM*+YnC82BF1dd{i{7U0?m+V9H-KcTe42I%1XNmh#<4p69 zV(plkaQkZ90futS*SHY|+~pcqZNP2J5~ubSA`@SAmbj)Yao1;wdr{-&7|J_B8{GK@ z+~pc~jsZ7VJ7A{zn5J>Z8~Cot68E{rnf%i|^+eUwFQ;josehc1C9X~5Ozr-HEOEco zI8*<4Q{znaQMjK}gsDAG%M!OVOWe9Faqnh{8=?zpD#vV%GwEfS2AJCE^BQLwKL&qK z^laj5)3^%^{o`wmyU2iBsXKxsDucag@OV&MBog_;1V3}|iYTPLX`99P*Q~kCdC`6|E-H;`2 zs8-x^gM8O&oT+}l)i^!Oh1#oqCrgGV+$kETn`)6xKlK4cLU$@EOFOroOV+~^WC6vruDVFLqxDn zgM7<0P7j-*`QEN^RR+GdHEyE;cl)6NC^g`o(YSpKxGy!%G_DTT1D46Jo2GHY4f(cd zoXLOLq;VYvzST+Z-vH{7;sl>oT(kWu5qURtB#foPcY{DX+}GwURDV04EI8A+P@!?Ab}(DxO#Z>08h4sOFELHDs{walmbl|JZmOZbU2}?L zSZc`kevKQDBfzlwc&}dWo1RDYN(j!RmxUUqvk$G`%^G)x(1zkpY!raWPM)W6CV%Zt zjWhZ8|I8A%=RA?G#!!y=S>kTjxDEr~p7RA@!d<+n`E!jk>3L{U^1aK@PB$+Q zoauR9ZIj@xmyb~SKGir)8;U!zS%`knTRy|u{XOk+Ul%8oZ%?h@xd!=GXxvW?xYAAm zoMXWKQsZ=U2$gTAE+I1EIyKHTe%zBK?i-CWjcyLp9FS zUM6asUTz3&_lq@7yQ!hL4H~D-c_?n=5-G>whVm}exG4tQ{TgTLZ)&L!ncBg$EO9F} zZn{CfO&Vt!FTc?^Q+-T4T{1Ma`!np3{CRQ*ErL-aATIZEgJWzsl0lk zFv}8PSp63NQtq4l`{f#E%D46g;WOpC_C~?&As?aj_K3zEY`_hfdZ=C^ zzZD`At}RR4>sjJv-j!Xx_i5avhVst5TL9AxxJxvy#(;ZX<4pEtYnHfOe&O>jRl0T(`@-KwwaRc8WUkboXq?HvuO2LX9R|JJs&S@yZE;lio-**gs&TIv%6rdl0(j8C zw_I;1IL^Sgnd1H6p9wd4Sa!IzI&grA&pt?em7yFr?llyB#K1u))Fj#`b|J4b+F z|C=DTjB;3zsM{R`tOt`I;XKQr#C{ROwlz&HN@0qALKXuf+MC^$XM48^^! zai;S2oh*EhNijnCp4PZ047jyZgzr%Uu1#;WZ8h|d&C`Uh)PPfm3eMyg-`B7+V*}sQS>hUWgE!UNhgsq}<09W> z2KoA)BDl2%+&Yb$WWa6FxP=B>W1ZxCo&mQ-nw5Y zmrA~RS{+)BD=!n=S%!QE>j(QL+|?S_W#B8mLh?P`fV)uR^tOS}a!kBZ_)OzvXO_5i z8fWqk?)$OidwpLiNLasIu~u*+4duO4;|dJ@cm4Ikx6;s$rr#*Iy$raPTLh<@SE!zq zo{;HbGZeSrSHjm{K0u>Q`zB8cv^773N!cLEiVghZv(FM{p@hH{}$XU20d5gNXIbY zb}ACw6T4+D$K?G4_k2-i+*SJv?ykJdxL?tW@A2=f+|0OD!qI};-+;UF`0Q}co+!9J2ELb1$qx5sLw5NNO=gEXp*cI;m8WHgd$ub( zT;bB}aEC3+4tL(!g8Qp{gtmhd&J}>kue(#@O!M=_`hn>T>7JqaK61X~tG5?~;_g~0 zIK4a&iYvW9aKAOQ`{y)nhQLGlhOQBSY1~?>JLHLme4p1ilil5TvCh}PSEd6+A7#KT z);R6%gqFATQpwl!JanDLy=TaG?PbEZ(STcUx!`s(w3mffWQRLj2U6|mEg6UTlVAQ+ z`1Ep3s9sL|nc!}ek5F7>tpMIKl;ho>3(lm!XRa5V-nJ5&@1|b}Zh>L^n0%|?^zu(A z-@4lbS7Rv0m%kF+a|XYCc(e{Yoba6uE8~C{3-Zsd$^$Ee%8`|HAPiBW( zuW^kAzOoI%XL`Q6R^v?Tb*KDM_--(iH}@&QEjP$_UY5Axr-g64VVs`6NpKB@eAj8* zFazJF=Y-Fs=jy)+POCAry?pzE;7t3L&UjI9OAY1tQsYd|-%fc+_`+~A#^fkL^tHy0 z96hqKbf1IkIuZ?~tu3Wf+S-~Dr88RUN0!d*N;Wl=R#jJxFE8C^=FDSf=_{khjHw=3 zIkKXnT=i<}nwMPM+%&SjtxXFrAES=xNVIp1YHn@9|3^(rbe!7R+BT}Ky>&sNzVpyT zOQOB5v$cIxYh%2vJuy4cltBLRg%uU!;;kKvN7c2pb&NXl5Zp__r(Ni1uOFpln3) z$Z)mOt3GUGf@N6+r_tR)B3DIU`tR>=-&Vy#k<&7lGBU}E6f4W3%ryfW-u}k{w`hJ{ zr-Hf;pVK+PNivqM)+|(!$u}V@q>kv+chFC@vje1*-h@*}Qz};!)sH+OC?>BJOB*D> z+`0y-16@t)0jKxwmq_U={qHGAn$D3;UM;{sH!FRh$pvWuBx{q_C8)W{|>8 z1I}AmCy8CyoM~=hIrWoLSO=&J>-?TtiNfZ%qNssqzeBa&o~UbXZERH52mNT_2WzQ= z@-T2VwzYOlipQJhc66fs#XAqgol{EUv*Ls$^;mPEiX6Ja2=xoFS@n_OeRGOl!);2h zdM`l9-=G_+=-_&*C!Mc}FeyS9Uq} zJ3#awM9?;~X0htM>JyS!t4A~uo$6uuUIvEd8N_gT0K>T+hW&I;36!CU7=BJQ4jEW^ zT81Y*4ByMZ(3~WOJJK0;wRK=fJ^S!Em8gRIy%kva-&4^O)WA#NGfE@qNG^rRn!elA zKComnT07#0GPuf>8WZg;bxo?6el;Z;J5?!tYpw58>lJ-#PtKd)sg^TUM}0EU(wS^b)~n@A*)hL$ z(OirOYB|%=&$d=Fx67Gbes`$l%-(TovTYH5a0Xp1$eroANjqJ1#4_-t5A7cUOaJP zJl@jU-i(3Oxk(c4J3`D3be^n-Icrb0%wy5@b;86u+v}2@9a18F-4RHxmL5p|Q&taz zXl?1}EZq*G40;gNlU^(~vgxJb%V~we(6`sHfmpMPPa$t4K0n!zXvf7~)&Qz>8W2k{ z3bd(L&^WBV7B1}ZF{)#k51-cygQQjP531@yuCzV<_j|jyiAXA44F_{WU1wceQ&)%j zDOjz6ltE7H1QJN@iIM6Ur+;Ep$lJwYVXT6WxoO4L_|bD*aBaQH+s#J*o28?qYS3m% zGCR>0=N>=Ux;!8JO^KFyo%2=64^fIMAO~HmuWPHTPj)Vmt5;$Kq^s?T#`@MS*oMiZ zl^;ij7ps2nfpReVNHrFGi5fqCI)FqY9qxr*nrLq8T!N%+Ja}}BB@jGA&kZWvUH>I9 zt!NY0d684H17g*k3S-BErIX5Yhf+QGYh;ZYIQ%nwsOT+D;tsU#;KXu=5z+?WIadcJO(nkcPRA}$aW5AJ9rPwdG&o_ubT@iLL;?KTa|K;Qg3uqFLhH(O~mV3 z8sY&&qpKYusKR`(nr4;vjLlhSp(<7MP9a96QDgH;Q~@G=nS^;!w<{@5^h-%M4+Zfg zqLxUPYB0pr&8V-LGdiyFUiGHr)-6puc0d7CGACXSM-2AbRmKG8Voh_iW>We6BR?Qb zS}eHyVe>fn45C4YNOr(i^72$t5%gtSB9-?KM+2O^?0%g*0rS_o#3P0zm&;D_{M)Fv zvJ#{e(a$A4H~Y4<^!hSs@C&aV)ZUP-zNxjvEAV*xnw?#<%0D^cO(yE&s#CGK)SIZ1 zxYry$r-SMqzbLa|mT1ei1D6XnIX5vc*+PW`d;;Kdfl};c4f!Yc6Ky#j(J5#M6g<@~ z9D@czm;2FW9|)TIqo|O;^ozjXBb~8{QL%mStOU2}=O^kJ2|2jf^t-0H_HbCGu@;*d zZNsFh$>&#P3q6T#lO(cLQU_vEeH~4Q$tF?WTqIA!VYb+BgsmyrjG

NEH5!ZRu8HOo||pi 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

8v3 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

luz8TEd8v~7ocREnRAshIm! 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

~m{XNQ!FX0>d#3 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 - diff --git a/src/pugixmlLib/scripts/pugixml_codelite.project b/src/pugixmlLib/scripts/pugixml_codelite.project index 0c242c8..637a81d 100644 --- a/src/pugixmlLib/scripts/pugixml_codelite.project +++ b/src/pugixmlLib/scripts/pugixml_codelite.project @@ -7,7 +7,7 @@ - + @@ -29,10 +29,10 @@ - + - + diff --git a/src/pugixmlLib/scripts/pugixml_vs2005.vcproj b/src/pugixmlLib/scripts/pugixml_vs2005.vcproj index 27616ea..b60f5af 100644 --- a/src/pugixmlLib/scripts/pugixml_vs2005.vcproj +++ b/src/pugixmlLib/scripts/pugixml_vs2005.vcproj @@ -50,7 +50,7 @@ UsePrecompiledHeader="0" WarningLevel="3" Detect64BitPortabilityProblems="true" - ProgramDataBaseFileName="$(OutDir)\pugixml_d.pdb" + ProgramDataBaseFileName="$(OutDir)\pugixmld.pdb" DebugInformationFormat="3" /> @@ -50,7 +50,7 @@ UsePrecompiledHeader="0" WarningLevel="3" Detect64BitPortabilityProblems="true" - ProgramDataBaseFileName="$(OutDir)\pugixml_sd.pdb" + ProgramDataBaseFileName="$(OutDir)\pugixmlsd.pdb" DebugInformationFormat="3" /> @@ -125,7 +125,7 @@ UsePrecompiledHeader="0" WarningLevel="3" Detect64BitPortabilityProblems="true" - ProgramDataBaseFileName="$(OutDir)\pugixml_sd.pdb" + ProgramDataBaseFileName="$(OutDir)\pugixmlsd.pdb" DebugInformationFormat="3" /> @@ -199,7 +199,7 @@ UsePrecompiledHeader="0" WarningLevel="3" Detect64BitPortabilityProblems="true" - ProgramDataBaseFileName="$(OutDir)\pugixml_s.pdb" + ProgramDataBaseFileName="$(OutDir)\pugixmls.pdb" DebugInformationFormat="3" /> @@ -274,7 +274,7 @@ UsePrecompiledHeader="0" WarningLevel="3" Detect64BitPortabilityProblems="true" - ProgramDataBaseFileName="$(OutDir)\pugixml_s.pdb" + ProgramDataBaseFileName="$(OutDir)\pugixmls.pdb" DebugInformationFormat="3" /> @@ -49,7 +49,7 @@ EnableFunctionLevelLinking="true" UsePrecompiledHeader="0" WarningLevel="3" - ProgramDataBaseFileName="$(OutDir)\pugixml_sd.pdb" + ProgramDataBaseFileName="$(OutDir)\pugixmlsd.pdb" DebugInformationFormat="3" /> @@ -123,7 +123,7 @@ EnableFunctionLevelLinking="true" UsePrecompiledHeader="0" WarningLevel="3" - ProgramDataBaseFileName="$(OutDir)\pugixml_sd.pdb" + ProgramDataBaseFileName="$(OutDir)\pugixmlsd.pdb" DebugInformationFormat="3" /> @@ -196,7 +196,7 @@ EnableFunctionLevelLinking="true" UsePrecompiledHeader="0" WarningLevel="3" - ProgramDataBaseFileName="$(OutDir)\pugixml_s.pdb" + ProgramDataBaseFileName="$(OutDir)\pugixmls.pdb" DebugInformationFormat="3" /> @@ -270,7 +270,7 @@ EnableFunctionLevelLinking="true" UsePrecompiledHeader="0" WarningLevel="3" - ProgramDataBaseFileName="$(OutDir)\pugixml_s.pdb" + ProgramDataBaseFileName="$(OutDir)\pugixmls.pdb" DebugInformationFormat="3" /> + - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - pugixml - {89A1E353-E2DC-495C-B403-742BE206ACED} - pugixml - Win32Proj - - - - StaticLibrary - MultiByte - - - StaticLibrary - MultiByte - - - StaticLibrary - MultiByte - - - StaticLibrary - MultiByte - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>10.0.30319.1 - vs2010\x32\ - vs2010\x32\Debug\ - vs2010\x64\ - vs2010\x64\Debug\ - vs2010\x32\ - vs2010\x32\Release\ - vs2010\x64\ - vs2010\x64\Release\ - $(ProjectName)_d - $(ProjectName)_d - - - - Disabled - _DEBUG;%(PreprocessorDefinitions) - EnableFastChecks - MultiThreadedDebugDLL - true - - - Level3 - $(OutDir)pugixml_d.pdb - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - - - - - - X64 - - - Disabled - _DEBUG;%(PreprocessorDefinitions) - EnableFastChecks - MultiThreadedDebugDLL - true - - - Level3 - $(OutDir)pugixml_d.pdb - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - - - - - - Full - NDEBUG;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - - - Level3 - $(OutDir)pugixml.pdb - ProgramDatabase - - - NDEBUG;%(PreprocessorDefinitions) - - - - - - X64 - - - Full - NDEBUG;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - - - Level3 - $(OutDir)pugixml.pdb - ProgramDatabase - - - NDEBUG;%(PreprocessorDefinitions) - - - - - - - - - - - - - + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {89A1E353-E2DC-495C-B403-742BE206ACED} + pugixml + Win32Proj + + + + StaticLibrary + MultiByte + true + + + StaticLibrary + MultiByte + true + + + StaticLibrary + MultiByte + true + false + + + StaticLibrary + MultiByte + true + false + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + vs2010\x32\ + vs2010\x32\Debug\ + pugixmld + vs2010\x64\ + vs2010\x64\Debug\ + pugixmld + vs2010\x32\ + vs2010\x32\Release\ + pugixml + vs2010\x64\ + vs2010\x64\Release\ + pugixml + + + + Disabled + _DEBUG;%(PreprocessorDefinitions) + false + EnableFastChecks + MultiThreadedDebugDLL + true + + Level3 + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + + + $(OutDir)pugixmld.lib + + + Windows + true + $(OutDir)pugixmld.pdb + + + + + Disabled + _DEBUG;%(PreprocessorDefinitions) + false + EnableFastChecks + MultiThreadedDebugDLL + true + + Level3 + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + + + $(OutDir)pugixmld.lib + + + Windows + true + $(OutDir)pugixmld.pdb + + + + + Full + NDEBUG;%(PreprocessorDefinitions) + false + true + MultiThreadedDLL + true + + Level3 + ProgramDatabase + + + NDEBUG;%(PreprocessorDefinitions) + + + $(OutDir)pugixml.lib + + + Windows + true + true + true + $(OutDir)pugixml.pdb + + + + + Full + NDEBUG;%(PreprocessorDefinitions) + false + true + MultiThreadedDLL + true + + Level3 + ProgramDatabase + + + NDEBUG;%(PreprocessorDefinitions) + + + $(OutDir)pugixml.lib + + + Windows + true + true + true + $(OutDir)pugixml.pdb + + + + + + + + + + + + + diff --git a/src/pugixmlLib/scripts/pugixml_vs2010_static.vcxproj b/src/pugixmlLib/scripts/pugixml_vs2010_static.vcxproj index c111373..c1e133c 100644 --- a/src/pugixmlLib/scripts/pugixml_vs2010_static.vcxproj +++ b/src/pugixmlLib/scripts/pugixml_vs2010_static.vcxproj @@ -1,163 +1,191 @@ - + - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - pugixml - {89A1E353-E2DC-495C-B403-742BE206ACED} - pugixml - Win32Proj - - - - StaticLibrary - MultiByte - - - StaticLibrary - MultiByte - - - StaticLibrary - MultiByte - - - StaticLibrary - MultiByte - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>10.0.30319.1 - vs2010\x32\ - vs2010\x32\Debug\ - vs2010\x64\ - vs2010\x64\Debug\ - vs2010\x32\ - vs2010\x32\Release\ - vs2010\x64\ - vs2010\x64\Release\ - $(ProjectName)_sd - $(ProjectName)_sd - $(ProjectName)_s - $(ProjectName)_s - - - - Disabled - _DEBUG;%(PreprocessorDefinitions) - EnableFastChecks - MultiThreadedDebug - true - - - Level3 - $(OutDir)pugixml_sd.pdb - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - - - - - - X64 - - - Disabled - _DEBUG;%(PreprocessorDefinitions) - EnableFastChecks - MultiThreadedDebug - true - - - Level3 - $(OutDir)pugixml_sd.pdb - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - - - - - - Full - NDEBUG;%(PreprocessorDefinitions) - true - MultiThreaded - true - - - Level3 - $(OutDir)pugixml_s.pdb - ProgramDatabase - - - NDEBUG;%(PreprocessorDefinitions) - - - - - - X64 - - - Full - NDEBUG;%(PreprocessorDefinitions) - true - MultiThreaded - true - - - Level3 - $(OutDir)pugixml_s.pdb - ProgramDatabase - - - NDEBUG;%(PreprocessorDefinitions) - - - - - - - - - - - - - + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {89A1E353-E2DC-495C-B403-742BE206ACED} + pugixml + Win32Proj + + + + StaticLibrary + MultiByte + true + + + StaticLibrary + MultiByte + true + + + StaticLibrary + MultiByte + true + false + + + StaticLibrary + MultiByte + true + false + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + vs2010\x32\ + vs2010\x32\DebugStatic\ + pugixmlsd + vs2010\x64\ + vs2010\x64\DebugStatic\ + pugixmlsd + vs2010\x32\ + vs2010\x32\ReleaseStatic\ + pugixmls + vs2010\x64\ + vs2010\x64\ReleaseStatic\ + pugixmls + + + + Disabled + _DEBUG;%(PreprocessorDefinitions) + false + EnableFastChecks + MultiThreadedDebug + true + + Level3 + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + + + $(OutDir)pugixmlsd.lib + + + Windows + true + $(OutDir)pugixmlsd.pdb + + + + + Disabled + _DEBUG;%(PreprocessorDefinitions) + false + EnableFastChecks + MultiThreadedDebug + true + + Level3 + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + + + $(OutDir)pugixmlsd.lib + + + Windows + true + $(OutDir)pugixmlsd.pdb + + + + + Full + NDEBUG;%(PreprocessorDefinitions) + false + true + MultiThreaded + true + + Level3 + ProgramDatabase + + + NDEBUG;%(PreprocessorDefinitions) + + + $(OutDir)pugixmls.lib + + + Windows + true + true + true + $(OutDir)pugixmls.pdb + + + + + Full + NDEBUG;%(PreprocessorDefinitions) + false + true + MultiThreaded + true + + Level3 + ProgramDatabase + + + NDEBUG;%(PreprocessorDefinitions) + + + $(OutDir)pugixmls.lib + + + Windows + true + true + true + $(OutDir)pugixmls.pdb + + + + + + + + + + + + + diff --git a/src/pugixmlLib/src/pugiconfig.hpp b/src/pugixmlLib/src/pugiconfig.hpp index 6b553ae..5ee5131 100644 --- a/src/pugixmlLib/src/pugiconfig.hpp +++ b/src/pugixmlLib/src/pugiconfig.hpp @@ -1,7 +1,7 @@ /** - * pugixml parser - version 1.0 + * pugixml parser - version 1.6 * -------------------------------------------------------- - * Copyright (C) 2006-2010, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com) + * Copyright (C) 2006-2015, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com) * Report bugs and download new versions at http://pugixml.org/ * * This library is distributed under the MIT License. See notice at the end @@ -21,11 +21,9 @@ // #define PUGIXML_NO_XPATH // Uncomment this to disable STL -// Note: you can't use XPath with PUGIXML_NO_STL // #define PUGIXML_NO_STL // Uncomment this to disable exceptions -// Note: you can't use XPath with PUGIXML_NO_EXCEPTIONS // #define PUGIXML_NO_EXCEPTIONS // Set this to control attributes for public classes/functions, i.e.: @@ -34,10 +32,21 @@ // #define PUGIXML_FUNCTION __fastcall // to set calling conventions to all public functions to fastcall // In absence of PUGIXML_CLASS/PUGIXML_FUNCTION definitions PUGIXML_API is used instead +// Tune these constants to adjust memory-related behavior +// #define PUGIXML_MEMORY_PAGE_SIZE 32768 +// #define PUGIXML_MEMORY_OUTPUT_STACK 10240 +// #define PUGIXML_MEMORY_XPATH_PAGE_SIZE 4096 + +// Uncomment this to switch to header-only version +// #define PUGIXML_HEADER_ONLY + +// Uncomment this to enable long long support +// #define PUGIXML_HAS_LONG_LONG + #endif /** - * Copyright (c) 2006-2010 Arseny Kapoulkine + * Copyright (c) 2006-2015 Arseny Kapoulkine * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation diff --git a/src/pugixmlLib/src/pugixml.cpp b/src/pugixmlLib/src/pugixml.cpp index 9132d8a..5b77a27 100644 --- a/src/pugixmlLib/src/pugixml.cpp +++ b/src/pugixmlLib/src/pugixml.cpp @@ -1,7 +1,7 @@ /** - * pugixml parser - version 1.0 + * pugixml parser - version 1.6 * -------------------------------------------------------- - * Copyright (C) 2006-2010, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com) + * Copyright (C) 2006-2015, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com) * Report bugs and download new versions at http://pugixml.org/ * * This library is distributed under the MIT License. See notice at the end @@ -11,18 +11,26 @@ * Copyright (C) 2003, by Kristen Wegner (kristen@tima.net) */ +#ifndef SOURCE_PUGIXML_CPP +#define SOURCE_PUGIXML_CPP + #include "pugixml.hpp" #include #include #include #include -#include -#include + +#ifdef PUGIXML_WCHAR_MODE +# include +#endif #ifndef PUGIXML_NO_XPATH # include # include +# ifdef PUGIXML_NO_EXCEPTIONS +# include +# endif #endif #ifndef PUGIXML_NO_STL @@ -35,85 +43,139 @@ #include #ifdef _MSC_VER +# pragma warning(push) # pragma warning(disable: 4127) // conditional expression is constant # pragma warning(disable: 4324) // structure was padded due to __declspec(align()) # pragma warning(disable: 4611) // interaction between '_setjmp' and C++ object destruction is non-portable # pragma warning(disable: 4702) // unreachable code # pragma warning(disable: 4996) // this function or variable may be unsafe +# pragma warning(disable: 4793) // function compiled as native: presence of '_setjmp' makes a function unmanaged #endif #ifdef __INTEL_COMPILER # pragma warning(disable: 177) // function was declared but never referenced +# pragma warning(disable: 279) // controlling expression is constant # pragma warning(disable: 1478 1786) // function was declared "deprecated" +# pragma warning(disable: 1684) // conversion from pointer to same-sized integral type +#endif + +#if defined(__BORLANDC__) && defined(PUGIXML_HEADER_ONLY) +# pragma warn -8080 // symbol is declared but never used; disabling this inside push/pop bracket does not make the warning go away #endif #ifdef __BORLANDC__ +# pragma option push # pragma warn -8008 // condition is always false # pragma warn -8066 // unreachable code #endif #ifdef __SNC__ +// Using diag_push/diag_pop does not disable the warnings inside templates due to a compiler bug # pragma diag_suppress=178 // function was declared but never referenced # pragma diag_suppress=237 // controlling expression is constant #endif -// uintptr_t -#if !defined(_MSC_VER) || _MSC_VER >= 1600 -# include -#else -# if _MSC_VER < 1300 -// No native uintptr_t in MSVC6 -typedef size_t uintptr_t; -# endif -typedef unsigned __int8 uint8_t; -typedef unsigned __int16 uint16_t; -typedef unsigned __int32 uint32_t; -typedef __int32 int32_t; -#endif - // Inlining controls #if defined(_MSC_VER) && _MSC_VER >= 1300 -# define PUGIXML_NO_INLINE __declspec(noinline) +# define PUGI__NO_INLINE __declspec(noinline) #elif defined(__GNUC__) -# define PUGIXML_NO_INLINE __attribute__((noinline)) +# define PUGI__NO_INLINE __attribute__((noinline)) +#else +# define PUGI__NO_INLINE +#endif + +// Branch weight controls +#if defined(__GNUC__) +# define PUGI__UNLIKELY(cond) __builtin_expect(cond, 0) #else -# define PUGIXML_NO_INLINE +# define PUGI__UNLIKELY(cond) (cond) #endif // Simple static assertion -#define STATIC_ASSERT(cond) { static const char condition_failed[(cond) ? 1 : -1] = {0}; (void)condition_failed[0]; } +#define PUGI__STATIC_ASSERT(cond) { static const char condition_failed[(cond) ? 1 : -1] = {0}; (void)condition_failed[0]; } // Digital Mars C++ bug workaround for passing char loaded from memory via stack #ifdef __DMC__ -# define DMC_VOLATILE volatile +# define PUGI__DMC_VOLATILE volatile +#else +# define PUGI__DMC_VOLATILE +#endif + +// Borland C++ bug workaround for not defining ::memcpy depending on header include order (can't always use std::memcpy because some compilers don't have it at all) +#if defined(__BORLANDC__) && !defined(__MEM_H_USING_LIST) +using std::memcpy; +using std::memmove; +#endif + +// In some environments MSVC is a compiler but the CRT lacks certain MSVC-specific features +#if defined(_MSC_VER) && !defined(__S3E__) +# define PUGI__MSVC_CRT_VERSION _MSC_VER +#endif + +#ifdef PUGIXML_HEADER_ONLY +# define PUGI__NS_BEGIN namespace pugi { namespace impl { +# define PUGI__NS_END } } +# define PUGI__FN inline +# define PUGI__FN_NO_INLINE inline #else -# define DMC_VOLATILE +# if defined(_MSC_VER) && _MSC_VER < 1300 // MSVC6 seems to have an amusing bug with anonymous namespaces inside namespaces +# define PUGI__NS_BEGIN namespace pugi { namespace impl { +# define PUGI__NS_END } } +# else +# define PUGI__NS_BEGIN namespace pugi { namespace impl { namespace { +# define PUGI__NS_END } } } +# endif +# define PUGI__FN +# define PUGI__FN_NO_INLINE PUGI__NO_INLINE #endif -using namespace pugi; +// uintptr_t +#if !defined(_MSC_VER) || _MSC_VER >= 1600 +# include +#else +# ifndef _UINTPTR_T_DEFINED +// No native uintptr_t in MSVC6 and in some WinCE versions +typedef size_t uintptr_t; +#define _UINTPTR_T_DEFINED +# endif +PUGI__NS_BEGIN + typedef unsigned __int8 uint8_t; + typedef unsigned __int16 uint16_t; + typedef unsigned __int32 uint32_t; +PUGI__NS_END +#endif // Memory allocation -namespace -{ - void* default_allocate(size_t size) +PUGI__NS_BEGIN + PUGI__FN void* default_allocate(size_t size) { return malloc(size); } - void default_deallocate(void* ptr) + PUGI__FN void default_deallocate(void* ptr) { free(ptr); } - allocation_function global_allocate = default_allocate; - deallocation_function global_deallocate = default_deallocate; -} + template + struct xml_memory_management_function_storage + { + static allocation_function allocate; + static deallocation_function deallocate; + }; + + // Global allocation functions are stored in class statics so that in header mode linker deduplicates them + // Without a template<> we'll get multiple definitions of the same static + template allocation_function xml_memory_management_function_storage::allocate = default_allocate; + template deallocation_function xml_memory_management_function_storage::deallocate = default_deallocate; + + typedef xml_memory_management_function_storage xml_memory; +PUGI__NS_END // String utilities -namespace -{ +PUGI__NS_BEGIN // Get string length - size_t strlength(const char_t* s) + PUGI__FN size_t strlength(const char_t* s) { assert(s); @@ -125,7 +187,7 @@ namespace } // Compare two strings - bool strequal(const char_t* src, const char_t* dst) + PUGI__FN bool strequal(const char_t* src, const char_t* dst) { assert(src && dst); @@ -137,7 +199,7 @@ namespace } // Compare lhs with [rhs_begin, rhs_end) - bool strequalrange(const char_t* lhs, const char_t* rhs, size_t count) + PUGI__FN bool strequalrange(const char_t* lhs, const char_t* rhs, size_t count) { for (size_t i = 0; i < count; ++i) if (lhs[i] != rhs[i]) @@ -145,27 +207,40 @@ namespace return lhs[count] == 0; } - + + // Get length of wide string, even if CRT lacks wide character support + PUGI__FN size_t strlength_wide(const wchar_t* s) + { + assert(s); + + #ifdef PUGIXML_WCHAR_MODE + return wcslen(s); + #else + const wchar_t* end = s; + while (*end) end++; + return static_cast(end - s); + #endif + } + #ifdef PUGIXML_WCHAR_MODE // Convert string to wide string, assuming all symbols are ASCII - void widen_ascii(wchar_t* dest, const char* source) + PUGI__FN void widen_ascii(wchar_t* dest, const char* source) { for (const char* i = source; *i; ++i) *dest++ = *i; *dest = 0; } #endif -} +PUGI__NS_END #if !defined(PUGIXML_NO_STL) || !defined(PUGIXML_NO_XPATH) // auto_ptr-like buffer holder for exception recovery -namespace -{ +PUGI__NS_BEGIN struct buffer_holder { void* data; void (*deleter)(void*); - buffer_holder(void* data, void (*deleter)(void*)): data(data), deleter(deleter) + buffer_holder(void* data_, void (*deleter_)(void*)): data(data_), deleter(deleter_) { } @@ -181,18 +256,28 @@ namespace return result; } }; -} +PUGI__NS_END #endif -namespace -{ - static const size_t xml_memory_page_size = 32768; +PUGI__NS_BEGIN + static const size_t xml_memory_page_size = + #ifdef PUGIXML_MEMORY_PAGE_SIZE + PUGIXML_MEMORY_PAGE_SIZE + #else + 32768 + #endif + ; - static const uintptr_t xml_memory_page_alignment = 32; + static const uintptr_t xml_memory_page_alignment = 64; static const uintptr_t xml_memory_page_pointer_mask = ~(xml_memory_page_alignment - 1); + static const uintptr_t xml_memory_page_contents_shared_mask = 32; static const uintptr_t xml_memory_page_name_allocated_mask = 16; static const uintptr_t xml_memory_page_value_allocated_mask = 8; static const uintptr_t xml_memory_page_type_mask = 7; + static const uintptr_t xml_memory_page_name_allocated_or_shared_mask = xml_memory_page_name_allocated_mask | xml_memory_page_contents_shared_mask; + static const uintptr_t xml_memory_page_value_allocated_or_shared_mask = xml_memory_page_value_allocated_mask | xml_memory_page_contents_shared_mask; + + #define PUGI__NODETYPE(n) static_cast(((n)->header & impl::xml_memory_page_type_mask) + 1) struct xml_allocator; @@ -200,12 +285,9 @@ namespace { static xml_memory_page* construct(void* memory) { - if (!memory) return 0; //$ redundant, left for performance - xml_memory_page* result = static_cast(memory); result->allocator = 0; - result->memory = 0; result->prev = 0; result->next = 0; result->busy_size = 0; @@ -216,15 +298,11 @@ namespace xml_allocator* allocator; - void* memory; - xml_memory_page* prev; xml_memory_page* next; size_t busy_size; size_t freed_size; - - char data[1]; }; struct xml_memory_string_header @@ -241,27 +319,33 @@ namespace xml_memory_page* allocate_page(size_t data_size) { - size_t size = offsetof(xml_memory_page, data) + data_size; + size_t size = sizeof(xml_memory_page) + data_size; // allocate block with some alignment, leaving memory for worst-case padding - void* memory = global_allocate(size + xml_memory_page_alignment); + void* memory = xml_memory::allocate(size + xml_memory_page_alignment); if (!memory) return 0; - // align upwards to page boundary - void* page_memory = reinterpret_cast((reinterpret_cast(memory) + (xml_memory_page_alignment - 1)) & ~(xml_memory_page_alignment - 1)); + // align to next page boundary (note: this guarantees at least 1 usable byte before the page) + char* page_memory = reinterpret_cast((reinterpret_cast(memory) + xml_memory_page_alignment) & ~(xml_memory_page_alignment - 1)); // prepare page structure xml_memory_page* page = xml_memory_page::construct(page_memory); + assert(page); - page->memory = memory; page->allocator = _root->allocator; + // record the offset for freeing the memory block + assert(page_memory > memory && page_memory - static_cast(memory) <= 127); + page_memory[-1] = static_cast(page_memory - static_cast(memory)); + return page; } static void deallocate_page(xml_memory_page* page) { - global_deallocate(page->memory); + char* page_memory = reinterpret_cast(page); + + xml_memory::deallocate(page_memory - page_memory[-1]); } void* allocate_memory_oob(size_t size, xml_memory_page*& out_page); @@ -270,7 +354,7 @@ namespace { if (_busy_size + size > xml_memory_page_size) return allocate_memory_oob(size, out_page); - void* buf = _root->data + _busy_size; + void* buf = reinterpret_cast(_root) + sizeof(xml_memory_page) + _busy_size; _busy_size += size; @@ -283,7 +367,7 @@ namespace { if (page == _root) page->busy_size = _busy_size; - assert(ptr >= page->data && ptr < page->data + page->busy_size); + assert(ptr >= reinterpret_cast(page) + sizeof(xml_memory_page) && ptr < reinterpret_cast(page) + sizeof(xml_memory_page) + page->busy_size); (void)!ptr; page->freed_size += size; @@ -316,6 +400,10 @@ namespace char_t* allocate_string(size_t length) { + static const size_t max_encoded_offset = (1 << 16) * sizeof(void*); + + PUGI__STATIC_ASSERT(xml_memory_page_size <= max_encoded_offset); + // allocate memory for string and header block size_t size = sizeof(xml_memory_string_header) + length * sizeof(char_t); @@ -328,29 +416,37 @@ namespace if (!header) return 0; // setup header - ptrdiff_t page_offset = reinterpret_cast(header) - page->data; + ptrdiff_t page_offset = reinterpret_cast(header) - reinterpret_cast(page) - sizeof(xml_memory_page); - assert(page_offset >= 0 && page_offset < (1 << 16)); - header->page_offset = static_cast(page_offset); + assert(page_offset % sizeof(void*) == 0); + assert(page_offset >= 0 && static_cast(page_offset) < max_encoded_offset); + header->page_offset = static_cast(static_cast(page_offset) / sizeof(void*)); // full_size == 0 for large strings that occupy the whole page - assert(full_size < (1 << 16) || (page->busy_size == full_size && page_offset == 0)); - header->full_size = static_cast(full_size < (1 << 16) ? full_size : 0); + assert(full_size % sizeof(void*) == 0); + assert(full_size < max_encoded_offset || (page->busy_size == full_size && page_offset == 0)); + header->full_size = static_cast(full_size < max_encoded_offset ? full_size / sizeof(void*) : 0); - return reinterpret_cast(header + 1); + // round-trip through void* to avoid 'cast increases required alignment of target type' warning + // header is guaranteed a pointer-sized alignment, which should be enough for char_t + return static_cast(static_cast(header + 1)); } void deallocate_string(char_t* string) { + // this function casts pointers through void* to avoid 'cast increases required alignment of target type' warnings + // we're guaranteed the proper (pointer-sized) alignment on the input string if it was allocated via allocate_string + // get header - xml_memory_string_header* header = reinterpret_cast(string) - 1; + xml_memory_string_header* header = static_cast(static_cast(string)) - 1; + assert(header); // deallocate - size_t page_offset = offsetof(xml_memory_page, data) + header->page_offset; - xml_memory_page* page = reinterpret_cast(reinterpret_cast(header) - page_offset); + size_t page_offset = sizeof(xml_memory_page) + header->page_offset * sizeof(void*); + xml_memory_page* page = reinterpret_cast(static_cast(reinterpret_cast(header) - page_offset)); // if full_size == 0 then this string occupies the whole page - size_t full_size = header->full_size == 0 ? page->busy_size : header->full_size; + size_t full_size = header->full_size == 0 ? page->busy_size : header->full_size * sizeof(void*); deallocate_memory(header, full_size, page); } @@ -359,11 +455,13 @@ namespace size_t _busy_size; }; - PUGIXML_NO_INLINE void* xml_allocator::allocate_memory_oob(size_t size, xml_memory_page*& out_page) + PUGI__FN_NO_INLINE void* xml_allocator::allocate_memory_oob(size_t size, xml_memory_page*& out_page) { const size_t large_allocation_threshold = xml_memory_page_size / 4; xml_memory_page* page = allocate_page(size <= large_allocation_threshold ? xml_memory_page_size : size); + out_page = page; + if (!page) return 0; if (size <= large_allocation_threshold) @@ -393,10 +491,9 @@ namespace // allocate inside page page->busy_size = size; - out_page = page; - return page->data; + return reinterpret_cast(page) + sizeof(xml_memory_page); } -} +PUGI__NS_END namespace pugi { @@ -404,7 +501,7 @@ namespace pugi struct xml_attribute_struct { /// Default ctor - xml_attribute_struct(xml_memory_page* page): header(reinterpret_cast(page)), name(0), value(0), prev_attribute_c(0), next_attribute(0) + xml_attribute_struct(impl::xml_memory_page* page): header(reinterpret_cast(page)), name(0), value(0), prev_attribute_c(0), next_attribute(0) { } @@ -422,7 +519,7 @@ namespace pugi { /// Default ctor /// \param type - node type - xml_node_struct(xml_memory_page* page, xml_node_type type): header(reinterpret_cast(page) | (type - 1)), parent(0), name(0), value(0), first_child(0), prev_sibling_c(0), next_sibling(0), first_attribute(0) + xml_node_struct(impl::xml_memory_page* page, xml_node_type type): header(reinterpret_cast(page) | (type - 1)), parent(0), name(0), value(0), first_child(0), prev_sibling_c(0), next_sibling(0), first_attribute(0) { } @@ -442,28 +539,41 @@ namespace pugi }; } -namespace -{ +PUGI__NS_BEGIN + struct xml_extra_buffer + { + char_t* buffer; + xml_extra_buffer* next; + }; + struct xml_document_struct: public xml_node_struct, public xml_allocator { - xml_document_struct(xml_memory_page* page): xml_node_struct(page, node_document), xml_allocator(page), buffer(0) + xml_document_struct(xml_memory_page* page): xml_node_struct(page, node_document), xml_allocator(page), buffer(0), extra_buffers(0) { } const char_t* buffer; + + xml_extra_buffer* extra_buffers; }; - static inline xml_allocator& get_allocator(const xml_node_struct* node) + inline xml_allocator& get_allocator(const xml_node_struct* node) { assert(node); return *reinterpret_cast(node->header & xml_memory_page_pointer_mask)->allocator; } -} + + template inline xml_document_struct& get_document(const Object* object) + { + assert(object); + + return *static_cast(reinterpret_cast(object->header & xml_memory_page_pointer_mask)->allocator); + } +PUGI__NS_END // Low-level DOM operations -namespace -{ +PUGI__NS_BEGIN inline xml_attribute_struct* allocate_attribute(xml_allocator& alloc) { xml_memory_page* page; @@ -484,8 +594,8 @@ namespace { uintptr_t header = a->header; - if (header & xml_memory_page_name_allocated_mask) alloc.deallocate_string(a->name); - if (header & xml_memory_page_value_allocated_mask) alloc.deallocate_string(a->value); + if (header & impl::xml_memory_page_name_allocated_mask) alloc.deallocate_string(a->name); + if (header & impl::xml_memory_page_value_allocated_mask) alloc.deallocate_string(a->value); alloc.deallocate_memory(a, sizeof(xml_attribute_struct), reinterpret_cast(header & xml_memory_page_pointer_mask)); } @@ -494,8 +604,8 @@ namespace { uintptr_t header = n->header; - if (header & xml_memory_page_name_allocated_mask) alloc.deallocate_string(n->name); - if (header & xml_memory_page_value_allocated_mask) alloc.deallocate_string(n->value); + if (header & impl::xml_memory_page_name_allocated_mask) alloc.deallocate_string(n->name); + if (header & impl::xml_memory_page_value_allocated_mask) alloc.deallocate_string(n->value); for (xml_attribute_struct* attr = n->first_attribute; attr; ) { @@ -518,60 +628,196 @@ namespace alloc.deallocate_memory(n, sizeof(xml_node_struct), reinterpret_cast(header & xml_memory_page_pointer_mask)); } - PUGIXML_NO_INLINE xml_node_struct* append_node(xml_node_struct* node, xml_allocator& alloc, xml_node_type type = node_element) + inline void append_node(xml_node_struct* child, xml_node_struct* node) { - xml_node_struct* child = allocate_node(alloc, type); - if (!child) return 0; - child->parent = node; - xml_node_struct* first_child = node->first_child; - - if (first_child) + xml_node_struct* head = node->first_child; + + if (head) { - xml_node_struct* last_child = first_child->prev_sibling_c; + xml_node_struct* tail = head->prev_sibling_c; - last_child->next_sibling = child; - child->prev_sibling_c = last_child; - first_child->prev_sibling_c = child; + tail->next_sibling = child; + child->prev_sibling_c = tail; + head->prev_sibling_c = child; } else { node->first_child = child; child->prev_sibling_c = child; } - - return child; } - PUGIXML_NO_INLINE xml_attribute_struct* append_attribute_ll(xml_node_struct* node, xml_allocator& alloc) + inline void prepend_node(xml_node_struct* child, xml_node_struct* node) + { + child->parent = node; + + xml_node_struct* head = node->first_child; + + if (head) + { + child->prev_sibling_c = head->prev_sibling_c; + head->prev_sibling_c = child; + } + else + child->prev_sibling_c = child; + + child->next_sibling = head; + node->first_child = child; + } + + inline void insert_node_after(xml_node_struct* child, xml_node_struct* node) + { + xml_node_struct* parent = node->parent; + + child->parent = parent; + + if (node->next_sibling) + node->next_sibling->prev_sibling_c = child; + else + parent->first_child->prev_sibling_c = child; + + child->next_sibling = node->next_sibling; + child->prev_sibling_c = node; + + node->next_sibling = child; + } + + inline void insert_node_before(xml_node_struct* child, xml_node_struct* node) + { + xml_node_struct* parent = node->parent; + + child->parent = parent; + + if (node->prev_sibling_c->next_sibling) + node->prev_sibling_c->next_sibling = child; + else + parent->first_child = child; + + child->prev_sibling_c = node->prev_sibling_c; + child->next_sibling = node; + + node->prev_sibling_c = child; + } + + inline void remove_node(xml_node_struct* node) { - xml_attribute_struct* a = allocate_attribute(alloc); - if (!a) return 0; + xml_node_struct* parent = node->parent; + + if (node->next_sibling) + node->next_sibling->prev_sibling_c = node->prev_sibling_c; + else + parent->first_child->prev_sibling_c = node->prev_sibling_c; + + if (node->prev_sibling_c->next_sibling) + node->prev_sibling_c->next_sibling = node->next_sibling; + else + parent->first_child = node->next_sibling; + + node->parent = 0; + node->prev_sibling_c = 0; + node->next_sibling = 0; + } - xml_attribute_struct* first_attribute = node->first_attribute; + inline void append_attribute(xml_attribute_struct* attr, xml_node_struct* node) + { + xml_attribute_struct* head = node->first_attribute; - if (first_attribute) + if (head) { - xml_attribute_struct* last_attribute = first_attribute->prev_attribute_c; + xml_attribute_struct* tail = head->prev_attribute_c; - last_attribute->next_attribute = a; - a->prev_attribute_c = last_attribute; - first_attribute->prev_attribute_c = a; + tail->next_attribute = attr; + attr->prev_attribute_c = tail; + head->prev_attribute_c = attr; } else { - node->first_attribute = a; - a->prev_attribute_c = a; + node->first_attribute = attr; + attr->prev_attribute_c = attr; } - - return a; } -} + + inline void prepend_attribute(xml_attribute_struct* attr, xml_node_struct* node) + { + xml_attribute_struct* head = node->first_attribute; + + if (head) + { + attr->prev_attribute_c = head->prev_attribute_c; + head->prev_attribute_c = attr; + } + else + attr->prev_attribute_c = attr; + + attr->next_attribute = head; + node->first_attribute = attr; + } + + inline void insert_attribute_after(xml_attribute_struct* attr, xml_attribute_struct* place, xml_node_struct* node) + { + if (place->next_attribute) + place->next_attribute->prev_attribute_c = attr; + else + node->first_attribute->prev_attribute_c = attr; + + attr->next_attribute = place->next_attribute; + attr->prev_attribute_c = place; + place->next_attribute = attr; + } + + inline void insert_attribute_before(xml_attribute_struct* attr, xml_attribute_struct* place, xml_node_struct* node) + { + if (place->prev_attribute_c->next_attribute) + place->prev_attribute_c->next_attribute = attr; + else + node->first_attribute = attr; + + attr->prev_attribute_c = place->prev_attribute_c; + attr->next_attribute = place; + place->prev_attribute_c = attr; + } + + inline void remove_attribute(xml_attribute_struct* attr, xml_node_struct* node) + { + if (attr->next_attribute) + attr->next_attribute->prev_attribute_c = attr->prev_attribute_c; + else + node->first_attribute->prev_attribute_c = attr->prev_attribute_c; + + if (attr->prev_attribute_c->next_attribute) + attr->prev_attribute_c->next_attribute = attr->next_attribute; + else + node->first_attribute = attr->next_attribute; + + attr->prev_attribute_c = 0; + attr->next_attribute = 0; + } + + PUGI__FN_NO_INLINE xml_node_struct* append_new_node(xml_node_struct* node, xml_allocator& alloc, xml_node_type type = node_element) + { + xml_node_struct* child = allocate_node(alloc, type); + if (!child) return 0; + + append_node(child, node); + + return child; + } + + PUGI__FN_NO_INLINE xml_attribute_struct* append_new_attribute(xml_node_struct* node, xml_allocator& alloc) + { + xml_attribute_struct* attr = allocate_attribute(alloc); + if (!attr) return 0; + + append_attribute(attr, node); + + return attr; + } +PUGI__NS_END // Helper classes for code generation -namespace -{ +PUGI__NS_BEGIN struct opt_false { enum { value = 0 }; @@ -581,11 +827,10 @@ namespace { enum { value = 1 }; }; -} +PUGI__NS_END // Unicode utilities -namespace -{ +PUGI__NS_BEGIN inline uint16_t endian_swap(uint16_t value) { return static_cast(((value & 0xff) << 8) | (value >> 8)); @@ -690,8 +935,8 @@ namespace static value_type high(value_type result, uint32_t ch) { - uint32_t msh = (uint32_t)(ch - 0x10000) >> 10; - uint32_t lsh = (uint32_t)(ch - 0x10000) & 0x3ff; + uint32_t msh = static_cast(ch - 0x10000) >> 10; + uint32_t lsh = static_cast(ch - 0x10000) & 0x3ff; result[0] = static_cast(0xD800 + msh); result[1] = static_cast(0xDC00 + lsh); @@ -746,6 +991,27 @@ namespace } }; + struct latin1_writer + { + typedef uint8_t* value_type; + + static value_type low(value_type result, uint32_t ch) + { + *result = static_cast(ch > 255 ? '?' : ch); + + return result + 1; + } + + static value_type high(value_type result, uint32_t ch) + { + (void)ch; + + *result = '?'; + + return result + 1; + } + }; + template struct wchar_selector; template <> struct wchar_selector<2> @@ -785,7 +1051,8 @@ namespace // process aligned single-byte (ascii) blocks if ((reinterpret_cast(data) & 3) == 0) { - while (size >= 4 && (*reinterpret_cast(data) & 0x80808080) == 0) + // round-trip through void* to silence 'cast increases required alignment of target type' warnings + while (size >= 4 && (*static_cast(static_cast(data)) & 0x80808080) == 0) { result = Traits::low(result, data[0]); result = Traits::low(result, data[1]); @@ -797,21 +1064,21 @@ namespace } } // 110xxxxx -> U+0080..U+07FF - else if ((unsigned)(lead - 0xC0) < 0x20 && size >= 2 && (data[1] & 0xc0) == 0x80) + else if (static_cast(lead - 0xC0) < 0x20 && size >= 2 && (data[1] & 0xc0) == 0x80) { result = Traits::low(result, ((lead & ~0xC0) << 6) | (data[1] & utf8_byte_mask)); data += 2; size -= 2; } // 1110xxxx -> U+0800-U+FFFF - else if ((unsigned)(lead - 0xE0) < 0x10 && size >= 3 && (data[1] & 0xc0) == 0x80 && (data[2] & 0xc0) == 0x80) + else if (static_cast(lead - 0xE0) < 0x10 && size >= 3 && (data[1] & 0xc0) == 0x80 && (data[2] & 0xc0) == 0x80) { result = Traits::low(result, ((lead & ~0xE0) << 12) | ((data[1] & utf8_byte_mask) << 6) | (data[2] & utf8_byte_mask)); data += 3; size -= 3; } // 11110xxx -> U+10000..U+10FFFF - else if ((unsigned)(lead - 0xF0) < 0x08 && size >= 4 && (data[1] & 0xc0) == 0x80 && (data[2] & 0xc0) == 0x80 && (data[3] & 0xc0) == 0x80) + else if (static_cast(lead - 0xF0) < 0x08 && size >= 4 && (data[1] & 0xc0) == 0x80 && (data[2] & 0xc0) == 0x80 && (data[3] & 0xc0) == 0x80) { result = Traits::high(result, ((lead & ~0xF0) << 18) | ((data[1] & utf8_byte_mask) << 12) | ((data[2] & utf8_byte_mask) << 6) | (data[3] & utf8_byte_mask)); data += 4; @@ -834,7 +1101,7 @@ namespace while (data < end) { - uint16_t lead = opt_swap::value ? endian_swap(*data) : *data; + unsigned int lead = opt_swap::value ? endian_swap(*data) : *data; // U+0000..U+D7FF if (lead < 0xD800) @@ -843,17 +1110,17 @@ namespace data += 1; } // U+E000..U+FFFF - else if ((unsigned)(lead - 0xE000) < 0x2000) + else if (static_cast(lead - 0xE000) < 0x2000) { result = Traits::low(result, lead); data += 1; } // surrogate pair lead - else if ((unsigned)(lead - 0xD800) < 0x400 && data + 1 < end) + else if (static_cast(lead - 0xD800) < 0x400 && data + 1 < end) { uint16_t next = opt_swap::value ? endian_swap(data[1]) : data[1]; - if ((unsigned)(next - 0xDC00) < 0x400) + if (static_cast(next - 0xDC00) < 0x400) { result = Traits::high(result, 0x10000 + ((lead & 0x3ff) << 10) + (next & 0x3ff)); data += 2; @@ -896,21 +1163,47 @@ namespace return result; } + + static inline typename Traits::value_type decode_latin1_block(const uint8_t* data, size_t size, typename Traits::value_type result) + { + for (size_t i = 0; i < size; ++i) + { + result = Traits::low(result, data[i]); + } + + return result; + } + + static inline typename Traits::value_type decode_wchar_block_impl(const uint16_t* data, size_t size, typename Traits::value_type result) + { + return decode_utf16_block(data, size, result); + } + + static inline typename Traits::value_type decode_wchar_block_impl(const uint32_t* data, size_t size, typename Traits::value_type result) + { + return decode_utf32_block(data, size, result); + } + + static inline typename Traits::value_type decode_wchar_block(const wchar_t* data, size_t size, typename Traits::value_type result) + { + return decode_wchar_block_impl(reinterpret_cast::type*>(data), size, result); + } }; - template inline void convert_utf_endian_swap(T* result, const T* data, size_t length) + template PUGI__FN void convert_utf_endian_swap(T* result, const T* data, size_t length) { for (size_t i = 0; i < length; ++i) result[i] = endian_swap(data[i]); } - inline void convert_wchar_endian_swap(wchar_t* result, const wchar_t* data, size_t length) +#ifdef PUGIXML_WCHAR_MODE + PUGI__FN void convert_wchar_endian_swap(wchar_t* result, const wchar_t* data, size_t length) { for (size_t i = 0; i < length; ++i) result[i] = static_cast(endian_swap(static_cast::type>(data[i]))); } -} +#endif +PUGI__NS_END -namespace -{ +PUGI__NS_BEGIN enum chartype_t { ct_parse_pcdata = 1, // \0, &, \r, < @@ -923,7 +1216,7 @@ namespace ct_start_symbol = 128 // Any symbol > 127, a-z, A-Z, _, : }; - const unsigned char chartype_table[256] = + static const unsigned char chartype_table[256] = { 55, 0, 0, 0, 0, 0, 0, 0, 0, 12, 12, 0, 0, 63, 0, 0, // 0-15 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 16-31 @@ -953,7 +1246,7 @@ namespace ctx_symbol = 16 // Any symbol > 127, a-z, A-Z, 0-9, _, -, . }; - const unsigned char chartypex_table[256] = + static const unsigned char chartypex_table[256] = { 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 2, 3, 3, 2, 3, 3, // 0-15 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 16-31 @@ -976,24 +1269,24 @@ namespace }; #ifdef PUGIXML_WCHAR_MODE - #define IS_CHARTYPE_IMPL(c, ct, table) ((static_cast(c) < 128 ? table[static_cast(c)] : table[128]) & (ct)) + #define PUGI__IS_CHARTYPE_IMPL(c, ct, table) ((static_cast(c) < 128 ? table[static_cast(c)] : table[128]) & (ct)) #else - #define IS_CHARTYPE_IMPL(c, ct, table) (table[static_cast(c)] & (ct)) + #define PUGI__IS_CHARTYPE_IMPL(c, ct, table) (table[static_cast(c)] & (ct)) #endif - #define IS_CHARTYPE(c, ct) IS_CHARTYPE_IMPL(c, ct, chartype_table) - #define IS_CHARTYPEX(c, ct) IS_CHARTYPE_IMPL(c, ct, chartypex_table) + #define PUGI__IS_CHARTYPE(c, ct) PUGI__IS_CHARTYPE_IMPL(c, ct, chartype_table) + #define PUGI__IS_CHARTYPEX(c, ct) PUGI__IS_CHARTYPE_IMPL(c, ct, chartypex_table) - bool is_little_endian() + PUGI__FN bool is_little_endian() { unsigned int ui = 1; return *reinterpret_cast(&ui) == 1; } - xml_encoding get_wchar_encoding() + PUGI__FN xml_encoding get_wchar_encoding() { - STATIC_ASSERT(sizeof(wchar_t) == 2 || sizeof(wchar_t) == 4); + PUGI__STATIC_ASSERT(sizeof(wchar_t) == 2 || sizeof(wchar_t) == 4); if (sizeof(wchar_t) == 2) return is_little_endian() ? encoding_utf16_le : encoding_utf16_be; @@ -1001,7 +1294,7 @@ namespace return is_little_endian() ? encoding_utf32_le : encoding_utf32_be; } - xml_encoding guess_buffer_encoding(uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3) + PUGI__FN xml_encoding guess_buffer_encoding(uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3) { // look for BOM in first few bytes if (d0 == 0 && d1 == 0 && d2 == 0xfe && d3 == 0xff) return encoding_utf32_be; @@ -1025,7 +1318,7 @@ namespace return encoding_utf8; } - xml_encoding get_buffer_encoding(xml_encoding encoding, const void* contents, size_t size) + PUGI__FN xml_encoding get_buffer_encoding(xml_encoding encoding, const void* contents, size_t size) { // replace wchar encoding with utf implementation if (encoding == encoding_wchar) return get_wchar_encoding(); @@ -1045,126 +1338,176 @@ namespace // try to guess encoding (based on XML specification, Appendix F.1) const uint8_t* data = static_cast(contents); - DMC_VOLATILE uint8_t d0 = data[0], d1 = data[1], d2 = data[2], d3 = data[3]; + PUGI__DMC_VOLATILE uint8_t d0 = data[0], d1 = data[1], d2 = data[2], d3 = data[3]; return guess_buffer_encoding(d0, d1, d2, d3); } - bool get_mutable_buffer(char_t*& out_buffer, size_t& out_length, const void* contents, size_t size, bool is_mutable) + PUGI__FN bool get_mutable_buffer(char_t*& out_buffer, size_t& out_length, const void* contents, size_t size, bool is_mutable) { + size_t length = size / sizeof(char_t); + if (is_mutable) { out_buffer = static_cast(const_cast(contents)); + out_length = length; } else { - void* buffer = global_allocate(size > 0 ? size : 1); + char_t* buffer = static_cast(xml_memory::allocate((length + 1) * sizeof(char_t))); if (!buffer) return false; - memcpy(buffer, contents, size); + if (contents) + memcpy(buffer, contents, length * sizeof(char_t)); + else + assert(length == 0); + + buffer[length] = 0; - out_buffer = static_cast(buffer); + out_buffer = buffer; + out_length = length + 1; } - out_length = size / sizeof(char_t); - return true; } #ifdef PUGIXML_WCHAR_MODE - inline bool need_endian_swap_utf(xml_encoding le, xml_encoding re) + PUGI__FN bool need_endian_swap_utf(xml_encoding le, xml_encoding re) { return (le == encoding_utf16_be && re == encoding_utf16_le) || (le == encoding_utf16_le && re == encoding_utf16_be) || - (le == encoding_utf32_be && re == encoding_utf32_le) || (le == encoding_utf32_le && re == encoding_utf32_be); + (le == encoding_utf32_be && re == encoding_utf32_le) || (le == encoding_utf32_le && re == encoding_utf32_be); } - bool convert_buffer_endian_swap(char_t*& out_buffer, size_t& out_length, const void* contents, size_t size, bool is_mutable) + PUGI__FN bool convert_buffer_endian_swap(char_t*& out_buffer, size_t& out_length, const void* contents, size_t size, bool is_mutable) { const char_t* data = static_cast(contents); - + size_t length = size / sizeof(char_t); + if (is_mutable) { - out_buffer = const_cast(data); + char_t* buffer = const_cast(data); + + convert_wchar_endian_swap(buffer, data, length); + + out_buffer = buffer; + out_length = length; } else { - out_buffer = static_cast(global_allocate(size > 0 ? size : 1)); - if (!out_buffer) return false; - } + char_t* buffer = static_cast(xml_memory::allocate((length + 1) * sizeof(char_t))); + if (!buffer) return false; - out_length = size / sizeof(char_t); + convert_wchar_endian_swap(buffer, data, length); + buffer[length] = 0; - convert_wchar_endian_swap(out_buffer, data, out_length); + out_buffer = buffer; + out_length = length + 1; + } return true; } - bool convert_buffer_utf8(char_t*& out_buffer, size_t& out_length, const void* contents, size_t size) + PUGI__FN bool convert_buffer_utf8(char_t*& out_buffer, size_t& out_length, const void* contents, size_t size) { const uint8_t* data = static_cast(contents); + size_t data_length = size; // first pass: get length in wchar_t units - out_length = utf_decoder::decode_utf8_block(data, size, 0); + size_t length = utf_decoder::decode_utf8_block(data, data_length, 0); // allocate buffer of suitable length - out_buffer = static_cast(global_allocate((out_length > 0 ? out_length : 1) * sizeof(char_t))); - if (!out_buffer) return false; + char_t* buffer = static_cast(xml_memory::allocate((length + 1) * sizeof(char_t))); + if (!buffer) return false; // second pass: convert utf8 input to wchar_t - wchar_writer::value_type out_begin = reinterpret_cast(out_buffer); - wchar_writer::value_type out_end = utf_decoder::decode_utf8_block(data, size, out_begin); + wchar_writer::value_type obegin = reinterpret_cast(buffer); + wchar_writer::value_type oend = utf_decoder::decode_utf8_block(data, data_length, obegin); + + assert(oend == obegin + length); + *oend = 0; - assert(out_end == out_begin + out_length); - (void)!out_end; + out_buffer = buffer; + out_length = length + 1; return true; } - template bool convert_buffer_utf16(char_t*& out_buffer, size_t& out_length, const void* contents, size_t size, opt_swap) + template PUGI__FN bool convert_buffer_utf16(char_t*& out_buffer, size_t& out_length, const void* contents, size_t size, opt_swap) { const uint16_t* data = static_cast(contents); - size_t length = size / sizeof(uint16_t); + size_t data_length = size / sizeof(uint16_t); // first pass: get length in wchar_t units - out_length = utf_decoder::decode_utf16_block(data, length, 0); + size_t length = utf_decoder::decode_utf16_block(data, data_length, 0); // allocate buffer of suitable length - out_buffer = static_cast(global_allocate((out_length > 0 ? out_length : 1) * sizeof(char_t))); - if (!out_buffer) return false; + char_t* buffer = static_cast(xml_memory::allocate((length + 1) * sizeof(char_t))); + if (!buffer) return false; // second pass: convert utf16 input to wchar_t - wchar_writer::value_type out_begin = reinterpret_cast(out_buffer); - wchar_writer::value_type out_end = utf_decoder::decode_utf16_block(data, length, out_begin); + wchar_writer::value_type obegin = reinterpret_cast(buffer); + wchar_writer::value_type oend = utf_decoder::decode_utf16_block(data, data_length, obegin); - assert(out_end == out_begin + out_length); - (void)!out_end; + assert(oend == obegin + length); + *oend = 0; + + out_buffer = buffer; + out_length = length + 1; return true; } - template bool convert_buffer_utf32(char_t*& out_buffer, size_t& out_length, const void* contents, size_t size, opt_swap) + template PUGI__FN bool convert_buffer_utf32(char_t*& out_buffer, size_t& out_length, const void* contents, size_t size, opt_swap) { const uint32_t* data = static_cast(contents); - size_t length = size / sizeof(uint32_t); + size_t data_length = size / sizeof(uint32_t); // first pass: get length in wchar_t units - out_length = utf_decoder::decode_utf32_block(data, length, 0); + size_t length = utf_decoder::decode_utf32_block(data, data_length, 0); // allocate buffer of suitable length - out_buffer = static_cast(global_allocate((out_length > 0 ? out_length : 1) * sizeof(char_t))); - if (!out_buffer) return false; + char_t* buffer = static_cast(xml_memory::allocate((length + 1) * sizeof(char_t))); + if (!buffer) return false; // second pass: convert utf32 input to wchar_t - wchar_writer::value_type out_begin = reinterpret_cast(out_buffer); - wchar_writer::value_type out_end = utf_decoder::decode_utf32_block(data, length, out_begin); + wchar_writer::value_type obegin = reinterpret_cast(buffer); + wchar_writer::value_type oend = utf_decoder::decode_utf32_block(data, data_length, obegin); + + assert(oend == obegin + length); + *oend = 0; + + out_buffer = buffer; + out_length = length + 1; + + return true; + } - assert(out_end == out_begin + out_length); - (void)!out_end; + PUGI__FN bool convert_buffer_latin1(char_t*& out_buffer, size_t& out_length, const void* contents, size_t size) + { + const uint8_t* data = static_cast(contents); + size_t data_length = size; + + // get length in wchar_t units + size_t length = data_length; + + // allocate buffer of suitable length + char_t* buffer = static_cast(xml_memory::allocate((length + 1) * sizeof(char_t))); + if (!buffer) return false; + + // convert latin1 input to wchar_t + wchar_writer::value_type obegin = reinterpret_cast(buffer); + wchar_writer::value_type oend = utf_decoder::decode_latin1_block(data, data_length, obegin); + + assert(oend == obegin + length); + *oend = 0; + + out_buffer = buffer; + out_length = length + 1; return true; } - bool convert_buffer(char_t*& out_buffer, size_t& out_length, xml_encoding encoding, const void* contents, size_t size, bool is_mutable) + PUGI__FN bool convert_buffer(char_t*& out_buffer, size_t& out_length, xml_encoding encoding, const void* contents, size_t size, bool is_mutable) { // get native encoding xml_encoding wchar_encoding = get_wchar_encoding(); @@ -1198,55 +1541,110 @@ namespace convert_buffer_utf32(out_buffer, out_length, contents, size, opt_true()); } + // source encoding is latin1 + if (encoding == encoding_latin1) return convert_buffer_latin1(out_buffer, out_length, contents, size); + assert(!"Invalid encoding"); return false; } #else - template bool convert_buffer_utf16(char_t*& out_buffer, size_t& out_length, const void* contents, size_t size, opt_swap) + template PUGI__FN bool convert_buffer_utf16(char_t*& out_buffer, size_t& out_length, const void* contents, size_t size, opt_swap) { const uint16_t* data = static_cast(contents); - size_t length = size / sizeof(uint16_t); + size_t data_length = size / sizeof(uint16_t); // first pass: get length in utf8 units - out_length = utf_decoder::decode_utf16_block(data, length, 0); + size_t length = utf_decoder::decode_utf16_block(data, data_length, 0); // allocate buffer of suitable length - out_buffer = static_cast(global_allocate((out_length > 0 ? out_length : 1) * sizeof(char_t))); - if (!out_buffer) return false; + char_t* buffer = static_cast(xml_memory::allocate((length + 1) * sizeof(char_t))); + if (!buffer) return false; // second pass: convert utf16 input to utf8 - uint8_t* out_begin = reinterpret_cast(out_buffer); - uint8_t* out_end = utf_decoder::decode_utf16_block(data, length, out_begin); + uint8_t* obegin = reinterpret_cast(buffer); + uint8_t* oend = utf_decoder::decode_utf16_block(data, data_length, obegin); + + assert(oend == obegin + length); + *oend = 0; - assert(out_end == out_begin + out_length); - (void)!out_end; + out_buffer = buffer; + out_length = length + 1; return true; } - template bool convert_buffer_utf32(char_t*& out_buffer, size_t& out_length, const void* contents, size_t size, opt_swap) + template PUGI__FN bool convert_buffer_utf32(char_t*& out_buffer, size_t& out_length, const void* contents, size_t size, opt_swap) { const uint32_t* data = static_cast(contents); - size_t length = size / sizeof(uint32_t); + size_t data_length = size / sizeof(uint32_t); // first pass: get length in utf8 units - out_length = utf_decoder::decode_utf32_block(data, length, 0); + size_t length = utf_decoder::decode_utf32_block(data, data_length, 0); // allocate buffer of suitable length - out_buffer = static_cast(global_allocate((out_length > 0 ? out_length : 1) * sizeof(char_t))); - if (!out_buffer) return false; + char_t* buffer = static_cast(xml_memory::allocate((length + 1) * sizeof(char_t))); + if (!buffer) return false; // second pass: convert utf32 input to utf8 - uint8_t* out_begin = reinterpret_cast(out_buffer); - uint8_t* out_end = utf_decoder::decode_utf32_block(data, length, out_begin); + uint8_t* obegin = reinterpret_cast(buffer); + uint8_t* oend = utf_decoder::decode_utf32_block(data, data_length, obegin); + + assert(oend == obegin + length); + *oend = 0; + + out_buffer = buffer; + out_length = length + 1; + + return true; + } + + PUGI__FN size_t get_latin1_7bit_prefix_length(const uint8_t* data, size_t size) + { + for (size_t i = 0; i < size; ++i) + if (data[i] > 127) + return i; + + return size; + } + + PUGI__FN bool convert_buffer_latin1(char_t*& out_buffer, size_t& out_length, const void* contents, size_t size, bool is_mutable) + { + const uint8_t* data = static_cast(contents); + size_t data_length = size; + + // get size of prefix that does not need utf8 conversion + size_t prefix_length = get_latin1_7bit_prefix_length(data, data_length); + assert(prefix_length <= data_length); + + const uint8_t* postfix = data + prefix_length; + size_t postfix_length = data_length - prefix_length; + + // if no conversion is needed, just return the original buffer + if (postfix_length == 0) return get_mutable_buffer(out_buffer, out_length, contents, size, is_mutable); + + // first pass: get length in utf8 units + size_t length = prefix_length + utf_decoder::decode_latin1_block(postfix, postfix_length, 0); + + // allocate buffer of suitable length + char_t* buffer = static_cast(xml_memory::allocate((length + 1) * sizeof(char_t))); + if (!buffer) return false; + + // second pass: convert latin1 input to utf8 + memcpy(buffer, data, prefix_length); + + uint8_t* obegin = reinterpret_cast(buffer); + uint8_t* oend = utf_decoder::decode_latin1_block(postfix, postfix_length, obegin + prefix_length); + + assert(oend == obegin + length); + *oend = 0; - assert(out_end == out_begin + out_length); - (void)!out_end; + out_buffer = buffer; + out_length = length + 1; return true; } - bool convert_buffer(char_t*& out_buffer, size_t& out_length, xml_encoding encoding, const void* contents, size_t size, bool is_mutable) + PUGI__FN bool convert_buffer(char_t*& out_buffer, size_t& out_length, xml_encoding encoding, const void* contents, size_t size, bool is_mutable) { // fast path: no conversion required if (encoding == encoding_utf8) return get_mutable_buffer(out_buffer, out_length, contents, size, is_mutable); @@ -1271,43 +1669,38 @@ namespace convert_buffer_utf32(out_buffer, out_length, contents, size, opt_true()); } + // source encoding is latin1 + if (encoding == encoding_latin1) return convert_buffer_latin1(out_buffer, out_length, contents, size, is_mutable); + assert(!"Invalid encoding"); return false; } #endif - size_t as_utf8_begin(const wchar_t* str, size_t length) + PUGI__FN size_t as_utf8_begin(const wchar_t* str, size_t length) { - STATIC_ASSERT(sizeof(wchar_t) == 2 || sizeof(wchar_t) == 4); - // get length in utf8 characters - return sizeof(wchar_t) == 2 ? - utf_decoder::decode_utf16_block(reinterpret_cast(str), length, 0) : - utf_decoder::decode_utf32_block(reinterpret_cast(str), length, 0); - } - - void as_utf8_end(char* buffer, size_t size, const wchar_t* str, size_t length) - { - STATIC_ASSERT(sizeof(wchar_t) == 2 || sizeof(wchar_t) == 4); - - // convert to utf8 - uint8_t* begin = reinterpret_cast(buffer); - uint8_t* end = sizeof(wchar_t) == 2 ? - utf_decoder::decode_utf16_block(reinterpret_cast(str), length, begin) : - utf_decoder::decode_utf32_block(reinterpret_cast(str), length, begin); - - assert(begin + size == end); - (void)!end; + return utf_decoder::decode_wchar_block(str, length, 0); + } + + PUGI__FN void as_utf8_end(char* buffer, size_t size, const wchar_t* str, size_t length) + { + // convert to utf8 + uint8_t* begin = reinterpret_cast(buffer); + uint8_t* end = utf_decoder::decode_wchar_block(str, length, begin); + + assert(begin + size == end); + (void)!end; // zero-terminate buffer[size] = 0; } - + #ifndef PUGIXML_NO_STL - std::string as_utf8_impl(const wchar_t* str, size_t length) - { + PUGI__FN std::string as_utf8_impl(const wchar_t* str, size_t length) + { // first pass: get length in utf8 characters - size_t size = as_utf8_begin(str, length); + size_t size = as_utf8_begin(str, length); // allocate resulting string std::string result; @@ -1316,10 +1709,10 @@ namespace // second pass: convert to utf8 if (size > 0) as_utf8_end(&result[0], size, str, length); - return result; - } + return result; + } - std::wstring as_wide_impl(const char* str, size_t size) + PUGI__FN std::basic_string as_wide_impl(const char* str, size_t size) { const uint8_t* data = reinterpret_cast(str); @@ -1327,7 +1720,7 @@ namespace size_t length = utf_decoder::decode_utf8_block(data, size, 0); // allocate resulting string - std::wstring result; + std::basic_string result; result.resize(length); // second pass: convert to wchar_t @@ -1344,13 +1737,15 @@ namespace } #endif - inline bool strcpy_insitu_allow(size_t length, uintptr_t allocated, char_t* target) + inline bool strcpy_insitu_allow(size_t length, uintptr_t header, uintptr_t header_mask, char_t* target) { - assert(target); + // never reuse shared memory + if (header & xml_memory_page_contents_shared_mask) return false; + size_t target_length = strlength(target); // always reuse document buffer memory if possible - if (!allocated) return target_length >= length; + if ((header & header_mask) == 0) return target_length >= length; // reuse heap memory if waste is not too great const size_t reuse_threshold = 32; @@ -1358,8 +1753,10 @@ namespace return target_length >= length && (target_length < reuse_threshold || target_length - length < target_length / 2); } - bool strcpy_insitu(char_t*& dest, uintptr_t& header, uintptr_t header_mask, const char_t* source) + PUGI__FN bool strcpy_insitu(char_t*& dest, uintptr_t& header, uintptr_t header_mask, const char_t* source) { + assert(header); + size_t source_length = strlength(source); if (source_length == 0) @@ -1375,7 +1772,7 @@ namespace return true; } - else if (dest && strcpy_insitu_allow(source_length, header & header_mask, dest)) + else if (dest && strcpy_insitu_allow(source_length, header, header_mask, dest)) { // we can reuse old buffer, so just copy the new data (including zero terminator) memcpy(dest, source, (source_length + 1) * sizeof(char_t)); @@ -1446,7 +1843,7 @@ namespace } }; - char_t* strconv_escape(char_t* s, gap& g) + PUGI__FN char_t* strconv_escape(char_t* s, gap& g) { char_t* stre = s + 1; @@ -1488,7 +1885,7 @@ namespace for (;;) { - if (static_cast(ch - '0') <= 9) + if (static_cast(static_cast(ch) - '0') <= 9) ucsc = 10 * ucsc + (ch - '0'); else if (ch == ';') break; @@ -1510,6 +1907,7 @@ namespace g.push(s, stre - s); return stre; } + case 'a': // &a { ++stre; @@ -1538,6 +1936,7 @@ namespace } break; } + case 'g': // &g { if (*++stre == 't' && *++stre == ';') // > @@ -1550,6 +1949,7 @@ namespace } break; } + case 'l': // &l { if (*++stre == 't' && *++stre == ';') // < @@ -1562,6 +1962,7 @@ namespace } break; } + case 'q': // &q { if (*++stre == 'u' && *++stre == 'o' && *++stre == 't' && *++stre == ';') // " @@ -1574,21 +1975,34 @@ namespace } break; } + + default: + break; } return stre; } - // Utility macro for last character handling - #define ENDSWITH(c, e) ((c) == (e) || ((c) == 0 && endch == (e))) + // Parser utilities + #define PUGI__ENDSWITH(c, e) ((c) == (e) || ((c) == 0 && endch == (e))) + #define PUGI__SKIPWS() { while (PUGI__IS_CHARTYPE(*s, ct_space)) ++s; } + #define PUGI__OPTSET(OPT) ( optmsk & (OPT) ) + #define PUGI__PUSHNODE(TYPE) { cursor = append_new_node(cursor, alloc, TYPE); if (!cursor) PUGI__THROW_ERROR(status_out_of_memory, s); } + #define PUGI__POPNODE() { cursor = cursor->parent; } + #define PUGI__SCANFOR(X) { while (*s != 0 && !(X)) ++s; } + #define PUGI__SCANWHILE(X) { while (X) ++s; } + #define PUGI__SCANWHILE_UNROLL(X) { for (;;) { char_t ss = s[0]; if (PUGI__UNLIKELY(!(X))) { break; } ss = s[1]; if (PUGI__UNLIKELY(!(X))) { s += 1; break; } ss = s[2]; if (PUGI__UNLIKELY(!(X))) { s += 2; break; } ss = s[3]; if (PUGI__UNLIKELY(!(X))) { s += 3; break; } s += 4; } } + #define PUGI__ENDSEG() { ch = *s; *s = 0; ++s; } + #define PUGI__THROW_ERROR(err, m) return error_offset = m, error_status = err, static_cast(0) + #define PUGI__CHECK_ERROR(err, m) { if (*s == 0) PUGI__THROW_ERROR(err, m); } - char_t* strconv_comment(char_t* s, char_t endch) + PUGI__FN char_t* strconv_comment(char_t* s, char_t endch) { gap g; while (true) { - while (!IS_CHARTYPE(*s, ct_parse_comment)) ++s; + PUGI__SCANWHILE_UNROLL(!PUGI__IS_CHARTYPE(ss, ct_parse_comment)); if (*s == '\r') // Either a single 0x0d or 0x0d 0x0a pair { @@ -1596,7 +2010,7 @@ namespace if (*s == '\n') g.push(s, 1); } - else if (s[0] == '-' && s[1] == '-' && ENDSWITH(s[2], '>')) // comment ends here + else if (s[0] == '-' && s[1] == '-' && PUGI__ENDSWITH(s[2], '>')) // comment ends here { *g.flush(s) = 0; @@ -1610,13 +2024,13 @@ namespace } } - char_t* strconv_cdata(char_t* s, char_t endch) + PUGI__FN char_t* strconv_cdata(char_t* s, char_t endch) { gap g; while (true) { - while (!IS_CHARTYPE(*s, ct_parse_cdata)) ++s; + PUGI__SCANWHILE_UNROLL(!PUGI__IS_CHARTYPE(ss, ct_parse_cdata)); if (*s == '\r') // Either a single 0x0d or 0x0d 0x0a pair { @@ -1624,7 +2038,7 @@ namespace if (*s == '\n') g.push(s, 1); } - else if (s[0] == ']' && s[1] == ']' && ENDSWITH(s[2], '>')) // CDATA ends here + else if (s[0] == ']' && s[1] == ']' && PUGI__ENDSWITH(s[2], '>')) // CDATA ends here { *g.flush(s) = 0; @@ -1640,19 +2054,27 @@ namespace typedef char_t* (*strconv_pcdata_t)(char_t*); - template struct strconv_pcdata_impl + template struct strconv_pcdata_impl { static char_t* parse(char_t* s) { gap g; - + + char_t* begin = s; + while (true) { - while (!IS_CHARTYPE(*s, ct_parse_pcdata)) ++s; - + PUGI__SCANWHILE_UNROLL(!PUGI__IS_CHARTYPE(ss, ct_parse_pcdata)); + if (*s == '<') // PCDATA ends here { - *g.flush(s) = 0; + char_t* end = g.flush(s); + + if (opt_trim::value) + while (end > begin && PUGI__IS_CHARTYPE(end[-1], ct_space)) + --end; + + *end = 0; return s + 1; } @@ -1668,6 +2090,14 @@ namespace } else if (*s == 0) { + char_t* end = g.flush(s); + + if (opt_trim::value) + while (end > begin && PUGI__IS_CHARTYPE(end[-1], ct_space)) + --end; + + *end = 0; + return s; } else ++s; @@ -1675,17 +2105,21 @@ namespace } }; - strconv_pcdata_t get_strconv_pcdata(unsigned int optmask) + PUGI__FN strconv_pcdata_t get_strconv_pcdata(unsigned int optmask) { - STATIC_ASSERT(parse_escapes == 0x10 && parse_eol == 0x20); + PUGI__STATIC_ASSERT(parse_escapes == 0x10 && parse_eol == 0x20 && parse_trim_pcdata == 0x0800); - switch ((optmask >> 4) & 3) // get bitmask for flags (eol escapes) + switch (((optmask >> 4) & 3) | ((optmask >> 9) & 4)) // get bitmask for flags (eol escapes trim) { - case 0: return strconv_pcdata_impl::parse; - case 1: return strconv_pcdata_impl::parse; - case 2: return strconv_pcdata_impl::parse; - case 3: return strconv_pcdata_impl::parse; - default: return 0; // should not get here + case 0: return strconv_pcdata_impl::parse; + case 1: return strconv_pcdata_impl::parse; + case 2: return strconv_pcdata_impl::parse; + case 3: return strconv_pcdata_impl::parse; + case 4: return strconv_pcdata_impl::parse; + case 5: return strconv_pcdata_impl::parse; + case 6: return strconv_pcdata_impl::parse; + case 7: return strconv_pcdata_impl::parse; + default: assert(false); return 0; // should not get here } } @@ -1698,37 +2132,37 @@ namespace gap g; // trim leading whitespaces - if (IS_CHARTYPE(*s, ct_space)) + if (PUGI__IS_CHARTYPE(*s, ct_space)) { char_t* str = s; do ++str; - while (IS_CHARTYPE(*str, ct_space)); + while (PUGI__IS_CHARTYPE(*str, ct_space)); g.push(s, str - s); } while (true) { - while (!IS_CHARTYPE(*s, ct_parse_attr_ws | ct_space)) ++s; + PUGI__SCANWHILE_UNROLL(!PUGI__IS_CHARTYPE(ss, ct_parse_attr_ws | ct_space)); if (*s == end_quote) { char_t* str = g.flush(s); do *str-- = 0; - while (IS_CHARTYPE(*str, ct_space)); + while (PUGI__IS_CHARTYPE(*str, ct_space)); return s + 1; } - else if (IS_CHARTYPE(*s, ct_space)) + else if (PUGI__IS_CHARTYPE(*s, ct_space)) { *s++ = ' '; - if (IS_CHARTYPE(*s, ct_space)) + if (PUGI__IS_CHARTYPE(*s, ct_space)) { char_t* str = s + 1; - while (IS_CHARTYPE(*str, ct_space)) ++str; + while (PUGI__IS_CHARTYPE(*str, ct_space)) ++str; g.push(s, str - s); } @@ -1751,7 +2185,7 @@ namespace while (true) { - while (!IS_CHARTYPE(*s, ct_parse_attr_ws)) ++s; + PUGI__SCANWHILE_UNROLL(!PUGI__IS_CHARTYPE(ss, ct_parse_attr_ws)); if (*s == end_quote) { @@ -1759,7 +2193,7 @@ namespace return s + 1; } - else if (IS_CHARTYPE(*s, ct_space)) + else if (PUGI__IS_CHARTYPE(*s, ct_space)) { if (*s == '\r') { @@ -1787,7 +2221,7 @@ namespace while (true) { - while (!IS_CHARTYPE(*s, ct_parse_attr)) ++s; + PUGI__SCANWHILE_UNROLL(!PUGI__IS_CHARTYPE(ss, ct_parse_attr)); if (*s == end_quote) { @@ -1819,7 +2253,7 @@ namespace while (true) { - while (!IS_CHARTYPE(*s, ct_parse_attr)) ++s; + PUGI__SCANWHILE_UNROLL(!PUGI__IS_CHARTYPE(ss, ct_parse_attr)); if (*s == end_quote) { @@ -1840,9 +2274,9 @@ namespace } }; - strconv_attribute_t get_strconv_attribute(unsigned int optmask) + PUGI__FN strconv_attribute_t get_strconv_attribute(unsigned int optmask) { - STATIC_ASSERT(parse_escapes == 0x10 && parse_eol == 0x20 && parse_wconv_attribute == 0x40 && parse_wnorm_attribute == 0x80); + PUGI__STATIC_ASSERT(parse_escapes == 0x10 && parse_eol == 0x20 && parse_wconv_attribute == 0x40 && parse_wnorm_attribute == 0x80); switch ((optmask >> 4) & 15) // get bitmask for flags (wconv wnorm eol escapes) { @@ -1862,7 +2296,7 @@ namespace case 13: return strconv_attribute_impl::parse_wnorm; case 14: return strconv_attribute_impl::parse_wnorm; case 15: return strconv_attribute_impl::parse_wnorm; - default: return 0; // should not get here + default: assert(false); return 0; // should not get here } } @@ -1879,20 +2313,9 @@ namespace { xml_allocator alloc; char_t* error_offset; - jmp_buf error_handler; - - // Parser utilities. - #define SKIPWS() { while (IS_CHARTYPE(*s, ct_space)) ++s; } - #define OPTSET(OPT) ( optmsk & OPT ) - #define PUSHNODE(TYPE) { cursor = append_node(cursor, alloc, TYPE); if (!cursor) THROW_ERROR(status_out_of_memory, s); } - #define POPNODE() { cursor = cursor->parent; } - #define SCANFOR(X) { while (*s != 0 && !(X)) ++s; } - #define SCANWHILE(X) { while ((X)) ++s; } - #define ENDSEG() { ch = *s; *s = 0; ++s; } - #define THROW_ERROR(err, m) error_offset = m, longjmp(error_handler, err) - #define CHECK_ERROR(err, m) { if (*s == 0) THROW_ERROR(err, m); } + xml_parse_status error_status; - xml_parser(const xml_allocator& alloc): alloc(alloc), error_offset(0) + xml_parser(const xml_allocator& alloc_): alloc(alloc_), error_offset(0), error_status(status_ok) { } @@ -1909,8 +2332,8 @@ namespace { // quoted string char_t ch = *s++; - SCANFOR(*s == ch); - if (!*s) THROW_ERROR(status_bad_doctype, s); + PUGI__SCANFOR(*s == ch); + if (!*s) PUGI__THROW_ERROR(status_bad_doctype, s); s++; } @@ -1918,55 +2341,61 @@ namespace { // s += 2; - SCANFOR(s[0] == '?' && s[1] == '>'); // no need for ENDSWITH because ?> can't terminate proper doctype - if (!*s) THROW_ERROR(status_bad_doctype, s); + PUGI__SCANFOR(s[0] == '?' && s[1] == '>'); // no need for ENDSWITH because ?> can't terminate proper doctype + if (!*s) PUGI__THROW_ERROR(status_bad_doctype, s); s += 2; } else if (s[0] == '<' && s[1] == '!' && s[2] == '-' && s[3] == '-') { s += 4; - SCANFOR(s[0] == '-' && s[1] == '-' && s[2] == '>'); // no need for ENDSWITH because --> can't terminate proper doctype - if (!*s) THROW_ERROR(status_bad_doctype, s); + PUGI__SCANFOR(s[0] == '-' && s[1] == '-' && s[2] == '>'); // no need for ENDSWITH because --> can't terminate proper doctype + if (!*s) PUGI__THROW_ERROR(status_bad_doctype, s); - s += 4; + s += 3; } - else THROW_ERROR(status_bad_doctype, s); + else PUGI__THROW_ERROR(status_bad_doctype, s); return s; } char_t* parse_doctype_ignore(char_t* s) { + size_t depth = 0; + assert(s[0] == '<' && s[1] == '!' && s[2] == '['); - s++; + s += 3; while (*s) { if (s[0] == '<' && s[1] == '!' && s[2] == '[') { // nested ignore section - s = parse_doctype_ignore(s); + s += 3; + depth++; } else if (s[0] == ']' && s[1] == ']' && s[2] == '>') { // ignore section end s += 3; - return s; + if (depth == 0) + return s; + + depth--; } else s++; } - THROW_ERROR(status_bad_doctype, s); - - return s; + PUGI__THROW_ERROR(status_bad_doctype, s); } - char_t* parse_doctype_group(char_t* s, char_t endch, bool toplevel) + char_t* parse_doctype_group(char_t* s, char_t endch) { - assert(s[0] == '<' && s[1] == '!'); - s++; + size_t depth = 0; + + assert((s[0] == '<' || s[0] == 0) && s[1] == '!'); + s += 2; while (*s) { @@ -1976,28 +2405,33 @@ namespace { // ignore s = parse_doctype_ignore(s); + if (!s) return s; } else { // some control group - s = parse_doctype_group(s, endch, false); + s += 2; + depth++; } } else if (s[0] == '<' || s[0] == '"' || s[0] == '\'') { // unknown tag (forbidden), or some primitive group s = parse_doctype_primitive(s); + if (!s) return s; } else if (*s == '>') { - s++; + if (depth == 0) + return s; - return s; + depth--; + s++; } else s++; } - if (!toplevel || endch != '>') THROW_ERROR(status_bad_doctype, s); + if (depth != 0 || endch != '>') PUGI__THROW_ERROR(status_bad_doctype, s); return s; } @@ -2015,31 +2449,31 @@ namespace { ++s; - if (OPTSET(parse_comments)) + if (PUGI__OPTSET(parse_comments)) { - PUSHNODE(node_comment); // Append a new node on the tree. + PUGI__PUSHNODE(node_comment); // Append a new node on the tree. cursor->value = s; // Save the offset. } - if (OPTSET(parse_eol) && OPTSET(parse_comments)) + if (PUGI__OPTSET(parse_eol) && PUGI__OPTSET(parse_comments)) { s = strconv_comment(s, endch); - if (!s) THROW_ERROR(status_bad_comment, cursor->value); + if (!s) PUGI__THROW_ERROR(status_bad_comment, cursor->value); } else { // Scan for terminating '-->'. - SCANFOR(s[0] == '-' && s[1] == '-' && ENDSWITH(s[2], '>')); - CHECK_ERROR(status_bad_comment, s); + PUGI__SCANFOR(s[0] == '-' && s[1] == '-' && PUGI__ENDSWITH(s[2], '>')); + PUGI__CHECK_ERROR(status_bad_comment, s); - if (OPTSET(parse_comments)) + if (PUGI__OPTSET(parse_comments)) *s = 0; // Zero-terminate this segment at the first terminating '-'. s += (s[2] == '>' ? 3 : 2); // Step over the '\0->'. } } - else THROW_ERROR(status_bad_comment, s); + else PUGI__THROW_ERROR(status_bad_comment, s); } else if (*s == '[') { @@ -2048,22 +2482,22 @@ namespace { ++s; - if (OPTSET(parse_cdata)) + if (PUGI__OPTSET(parse_cdata)) { - PUSHNODE(node_cdata); // Append a new node on the tree. + PUGI__PUSHNODE(node_cdata); // Append a new node on the tree. cursor->value = s; // Save the offset. - if (OPTSET(parse_eol)) + if (PUGI__OPTSET(parse_eol)) { s = strconv_cdata(s, endch); - if (!s) THROW_ERROR(status_bad_cdata, cursor->value); + if (!s) PUGI__THROW_ERROR(status_bad_cdata, cursor->value); } else { // Scan for terminating ']]>'. - SCANFOR(s[0] == ']' && s[1] == ']' && ENDSWITH(s[2], '>')); - CHECK_ERROR(status_bad_cdata, s); + PUGI__SCANFOR(s[0] == ']' && s[1] == ']' && PUGI__ENDSWITH(s[2], '>')); + PUGI__CHECK_ERROR(status_bad_cdata, s); *s++ = 0; // Zero-terminate this segment. } @@ -2071,43 +2505,42 @@ namespace else // Flagged for discard, but we still have to scan for the terminator. { // Scan for terminating ']]>'. - SCANFOR(s[0] == ']' && s[1] == ']' && ENDSWITH(s[2], '>')); - CHECK_ERROR(status_bad_cdata, s); + PUGI__SCANFOR(s[0] == ']' && s[1] == ']' && PUGI__ENDSWITH(s[2], '>')); + PUGI__CHECK_ERROR(status_bad_cdata, s); ++s; } s += (s[1] == '>' ? 2 : 1); // Step over the last ']>'. } - else THROW_ERROR(status_bad_cdata, s); + else PUGI__THROW_ERROR(status_bad_cdata, s); } - else if (s[0] == 'D' && s[1] == 'O' && s[2] == 'C' && s[3] == 'T' && s[4] == 'Y' && s[5] == 'P' && ENDSWITH(s[6], 'E')) + else if (s[0] == 'D' && s[1] == 'O' && s[2] == 'C' && s[3] == 'T' && s[4] == 'Y' && s[5] == 'P' && PUGI__ENDSWITH(s[6], 'E')) { s -= 2; - if (cursor->parent) THROW_ERROR(status_bad_doctype, s); - - char_t* mark = s + 9; + if (cursor->parent) PUGI__THROW_ERROR(status_bad_doctype, s); - s = parse_doctype_group(s, endch, true); + char_t* mark = s + 9; - if (OPTSET(parse_doctype)) - { - while (IS_CHARTYPE(*mark, ct_space)) ++mark; + s = parse_doctype_group(s, endch); + if (!s) return s; - PUSHNODE(node_doctype); + assert((*s == 0 && endch == '>') || *s == '>'); + if (*s) *s++ = 0; - cursor->value = mark; + if (PUGI__OPTSET(parse_doctype)) + { + while (PUGI__IS_CHARTYPE(*mark, ct_space)) ++mark; - assert((s[0] == 0 && endch == '>') || s[-1] == '>'); - s[*s == 0 ? 0 : -1] = 0; + PUGI__PUSHNODE(node_doctype); - POPNODE(); - } + cursor->value = mark; + } } - else if (*s == 0 && endch == '-') THROW_ERROR(status_bad_comment, s); - else if (*s == 0 && endch == '[') THROW_ERROR(status_bad_cdata, s); - else THROW_ERROR(status_unrecognized_tag, s); + else if (*s == 0 && endch == '-') PUGI__THROW_ERROR(status_bad_comment, s); + else if (*s == 0 && endch == '[') PUGI__THROW_ERROR(status_bad_cdata, s); + else PUGI__THROW_ERROR(status_unrecognized_tag, s); return s; } @@ -2124,50 +2557,50 @@ namespace // read PI target char_t* target = s; - if (!IS_CHARTYPE(*s, ct_start_symbol)) THROW_ERROR(status_bad_pi, s); + if (!PUGI__IS_CHARTYPE(*s, ct_start_symbol)) PUGI__THROW_ERROR(status_bad_pi, s); - SCANWHILE(IS_CHARTYPE(*s, ct_symbol)); - CHECK_ERROR(status_bad_pi, s); + PUGI__SCANWHILE(PUGI__IS_CHARTYPE(*s, ct_symbol)); + PUGI__CHECK_ERROR(status_bad_pi, s); // determine node type; stricmp / strcasecmp is not portable bool declaration = (target[0] | ' ') == 'x' && (target[1] | ' ') == 'm' && (target[2] | ' ') == 'l' && target + 3 == s; - if (declaration ? OPTSET(parse_declaration) : OPTSET(parse_pi)) + if (declaration ? PUGI__OPTSET(parse_declaration) : PUGI__OPTSET(parse_pi)) { if (declaration) { // disallow non top-level declarations - if (cursor->parent) THROW_ERROR(status_bad_pi, s); + if (cursor->parent) PUGI__THROW_ERROR(status_bad_pi, s); - PUSHNODE(node_declaration); + PUGI__PUSHNODE(node_declaration); } else { - PUSHNODE(node_pi); + PUGI__PUSHNODE(node_pi); } cursor->name = target; - ENDSEG(); + PUGI__ENDSEG(); // parse value/attributes if (ch == '?') { // empty node - if (!ENDSWITH(*s, '>')) THROW_ERROR(status_bad_pi, s); + if (!PUGI__ENDSWITH(*s, '>')) PUGI__THROW_ERROR(status_bad_pi, s); s += (*s == '>'); - POPNODE(); + PUGI__POPNODE(); } - else if (IS_CHARTYPE(ch, ct_space)) + else if (PUGI__IS_CHARTYPE(ch, ct_space)) { - SKIPWS(); + PUGI__SKIPWS(); // scan for tag end char_t* value = s; - SCANFOR(s[0] == '?' && ENDSWITH(s[1], '>')); - CHECK_ERROR(status_bad_pi, s); + PUGI__SCANFOR(s[0] == '?' && PUGI__ENDSWITH(s[1], '>')); + PUGI__CHECK_ERROR(status_bad_pi, s); if (declaration) { @@ -2181,20 +2614,20 @@ namespace { // store value and step over > cursor->value = value; - POPNODE(); + PUGI__POPNODE(); - ENDSEG(); + PUGI__ENDSEG(); s += (*s == '>'); } } - else THROW_ERROR(status_bad_pi, s); + else PUGI__THROW_ERROR(status_bad_pi, s); } else { // scan for tag end - SCANFOR(s[0] == '?' && ENDSWITH(s[1], '>')); - CHECK_ERROR(status_bad_pi, s); + PUGI__SCANFOR(s[0] == '?' && PUGI__ENDSWITH(s[1], '>')); + PUGI__CHECK_ERROR(status_bad_pi, s); s += (s[1] == '>' ? 2 : 1); } @@ -2205,13 +2638,13 @@ namespace return s; } - void parse(char_t* s, xml_node_struct* xmldoc, unsigned int optmsk, char_t endch) + char_t* parse_tree(char_t* s, xml_node_struct* root, unsigned int optmsk, char_t endch) { strconv_attribute_t strconv_attribute = get_strconv_attribute(optmsk); strconv_pcdata_t strconv_pcdata = get_strconv_pcdata(optmsk); char_t ch = 0; - xml_node_struct* cursor = xmldoc; + xml_node_struct* cursor = root; char_t* mark = s; while (*s != 0) @@ -2221,43 +2654,39 @@ namespace ++s; LOC_TAG: - if (IS_CHARTYPE(*s, ct_start_symbol)) // '<#...' + if (PUGI__IS_CHARTYPE(*s, ct_start_symbol)) // '<#...' { - PUSHNODE(node_element); // Append a new node to the tree. + PUGI__PUSHNODE(node_element); // Append a new node to the tree. cursor->name = s; - SCANWHILE(IS_CHARTYPE(*s, ct_symbol)); // Scan for a terminator. - ENDSEG(); // Save char in 'ch', terminate & step over. + PUGI__SCANWHILE_UNROLL(PUGI__IS_CHARTYPE(ss, ct_symbol)); // Scan for a terminator. + PUGI__ENDSEG(); // Save char in 'ch', terminate & step over. if (ch == '>') { // end of tag } - else if (IS_CHARTYPE(ch, ct_space)) + else if (PUGI__IS_CHARTYPE(ch, ct_space)) { LOC_ATTRIBUTES: - while (true) - { - SKIPWS(); // Eat any whitespace. + while (true) + { + PUGI__SKIPWS(); // Eat any whitespace. - if (IS_CHARTYPE(*s, ct_start_symbol)) // <... #... + if (PUGI__IS_CHARTYPE(*s, ct_start_symbol)) // <... #... { - xml_attribute_struct* a = append_attribute_ll(cursor, alloc); // Make space for this attribute. - if (!a) THROW_ERROR(status_out_of_memory, s); + xml_attribute_struct* a = append_new_attribute(cursor, alloc); // Make space for this attribute. + if (!a) PUGI__THROW_ERROR(status_out_of_memory, s); a->name = s; // Save the offset. - SCANWHILE(IS_CHARTYPE(*s, ct_symbol)); // Scan for a terminator. - CHECK_ERROR(status_bad_attribute, s); //$ redundant, left for performance - - ENDSEG(); // Save char in 'ch', terminate & step over. - CHECK_ERROR(status_bad_attribute, s); //$ redundant, left for performance + PUGI__SCANWHILE_UNROLL(PUGI__IS_CHARTYPE(ss, ct_symbol)); // Scan for a terminator. + PUGI__ENDSEG(); // Save char in 'ch', terminate & step over. - if (IS_CHARTYPE(ch, ct_space)) + if (PUGI__IS_CHARTYPE(ch, ct_space)) { - SKIPWS(); // Eat any whitespace. - CHECK_ERROR(status_bad_attribute, s); //$ redundant, left for performance + PUGI__SKIPWS(); // Eat any whitespace. ch = *s; ++s; @@ -2265,7 +2694,7 @@ namespace if (ch == '=') // '<... #=...' { - SKIPWS(); // Eat any whitespace. + PUGI__SKIPWS(); // Eat any whitespace. if (*s == '"' || *s == '\'') // '<... #="...' { @@ -2275,16 +2704,16 @@ namespace s = strconv_attribute(s, ch); - if (!s) THROW_ERROR(status_bad_attribute, a->value); + if (!s) PUGI__THROW_ERROR(status_bad_attribute, a->value); // After this line the loop continues from the start; // Whitespaces, / and > are ok, symbols and EOF are wrong, // everything else will be detected - if (IS_CHARTYPE(*s, ct_start_symbol)) THROW_ERROR(status_bad_attribute, s); + if (PUGI__IS_CHARTYPE(*s, ct_start_symbol)) PUGI__THROW_ERROR(status_bad_attribute, s); } - else THROW_ERROR(status_bad_attribute, s); + else PUGI__THROW_ERROR(status_bad_attribute, s); } - else THROW_ERROR(status_bad_attribute, s); + else PUGI__THROW_ERROR(status_bad_attribute, s); } else if (*s == '/') { @@ -2292,16 +2721,16 @@ namespace if (*s == '>') { - POPNODE(); + PUGI__POPNODE(); s++; break; } else if (*s == 0 && endch == '>') { - POPNODE(); + PUGI__POPNODE(); break; } - else THROW_ERROR(status_bad_start_element, s); + else PUGI__THROW_ERROR(status_bad_start_element, s); } else if (*s == '>') { @@ -2313,16 +2742,16 @@ namespace { break; } - else THROW_ERROR(status_bad_start_element, s); + else PUGI__THROW_ERROR(status_bad_start_element, s); } // !!! } else if (ch == '/') // '<#.../' { - if (!ENDSWITH(*s, '>')) THROW_ERROR(status_bad_start_element, s); + if (!PUGI__ENDSWITH(*s, '>')) PUGI__THROW_ERROR(status_bad_start_element, s); - POPNODE(); // Pop. + PUGI__POPNODE(); // Pop. s += (*s == '>'); } @@ -2331,83 +2760,96 @@ namespace // we stepped over null terminator, backtrack & handle closing tag --s; - if (endch != '>') THROW_ERROR(status_bad_start_element, s); + if (endch != '>') PUGI__THROW_ERROR(status_bad_start_element, s); } - else THROW_ERROR(status_bad_start_element, s); + else PUGI__THROW_ERROR(status_bad_start_element, s); } else if (*s == '/') { ++s; char_t* name = cursor->name; - if (!name) THROW_ERROR(status_end_element_mismatch, s); + if (!name) PUGI__THROW_ERROR(status_end_element_mismatch, s); - while (IS_CHARTYPE(*s, ct_symbol)) + while (PUGI__IS_CHARTYPE(*s, ct_symbol)) { - if (*s++ != *name++) THROW_ERROR(status_end_element_mismatch, s); + if (*s++ != *name++) PUGI__THROW_ERROR(status_end_element_mismatch, s); } if (*name) { - if (*s == 0 && name[0] == endch && name[1] == 0) THROW_ERROR(status_bad_end_element, s); - else THROW_ERROR(status_end_element_mismatch, s); + if (*s == 0 && name[0] == endch && name[1] == 0) PUGI__THROW_ERROR(status_bad_end_element, s); + else PUGI__THROW_ERROR(status_end_element_mismatch, s); } - POPNODE(); // Pop. + PUGI__POPNODE(); // Pop. - SKIPWS(); + PUGI__SKIPWS(); if (*s == 0) { - if (endch != '>') THROW_ERROR(status_bad_end_element, s); + if (endch != '>') PUGI__THROW_ERROR(status_bad_end_element, s); } else { - if (*s != '>') THROW_ERROR(status_bad_end_element, s); + if (*s != '>') PUGI__THROW_ERROR(status_bad_end_element, s); ++s; } } else if (*s == '?') // 'header & xml_memory_page_type_mask) + 1 == node_declaration) goto LOC_ATTRIBUTES; + if (PUGI__NODETYPE(cursor) == node_declaration) goto LOC_ATTRIBUTES; } else if (*s == '!') // 'first_child) continue; + } } - s = mark; + if (!PUGI__OPTSET(parse_trim_pcdata)) + s = mark; - if (cursor->parent) + if (cursor->parent || PUGI__OPTSET(parse_fragment)) { - PUSHNODE(node_pcdata); // Append a new node on the tree. + PUGI__PUSHNODE(node_pcdata); // Append a new node on the tree. cursor->value = s; // Save the offset. s = strconv_pcdata(s); - POPNODE(); // Pop since this is a standalone. + PUGI__POPNODE(); // Pop since this is a standalone. if (!*s) break; } else { - SCANFOR(*s == '<'); // '...<' + PUGI__SCANFOR(*s == '<'); // '...<' if (!*s) break; ++s; @@ -2419,45 +2861,84 @@ namespace } // check that last tag is closed - if (cursor != xmldoc) THROW_ERROR(status_end_element_mismatch, s); + if (cursor != root) PUGI__THROW_ERROR(status_end_element_mismatch, s); + + return s; + } + + #ifdef PUGIXML_WCHAR_MODE + static char_t* parse_skip_bom(char_t* s) + { + unsigned int bom = 0xfeff; + return (s[0] == static_cast(bom)) ? s + 1 : s; } + #else + static char_t* parse_skip_bom(char_t* s) + { + return (s[0] == '\xef' && s[1] == '\xbb' && s[2] == '\xbf') ? s + 3 : s; + } + #endif - static xml_parse_result parse(char_t* buffer, size_t length, xml_node_struct* root, unsigned int optmsk) + static bool has_element_node_siblings(xml_node_struct* node) { - xml_document_struct* xmldoc = static_cast(root); + while (node) + { + if (PUGI__NODETYPE(node) == node_element) return true; + + node = node->next_sibling; + } + + return false; + } - // store buffer for offset_debug - xmldoc->buffer = buffer; + static xml_parse_result parse(char_t* buffer, size_t length, xml_document_struct* xmldoc, xml_node_struct* root, unsigned int optmsk) + { + // allocator object is a part of document object + xml_allocator& alloc_ = *static_cast(xmldoc); // early-out for empty documents - if (length == 0) return make_parse_result(status_ok); + if (length == 0) + return make_parse_result(PUGI__OPTSET(parse_fragment) ? status_ok : status_no_document_element); + // get last child of the root before parsing + xml_node_struct* last_root_child = root->first_child ? root->first_child->prev_sibling_c : 0; + // create parser on stack - xml_parser parser(*xmldoc); + xml_parser parser(alloc_); // save last character and make buffer zero-terminated (speeds up parsing) char_t endch = buffer[length - 1]; buffer[length - 1] = 0; + // skip BOM to make sure it does not end up as part of parse output + char_t* buffer_data = parse_skip_bom(buffer); + // perform actual parsing - int error = setjmp(parser.error_handler); + parser.parse_tree(buffer_data, root, optmsk, endch); - if (error == 0) - { - parser.parse(buffer, xmldoc, optmsk, endch); - } + // update allocator state + alloc_ = parser.alloc; - xml_parse_result result = make_parse_result(static_cast(error), parser.error_offset ? parser.error_offset - buffer : 0); + xml_parse_result result = make_parse_result(parser.error_status, parser.error_offset ? parser.error_offset - buffer : 0); assert(result.offset >= 0 && static_cast(result.offset) <= length); - // update allocator state - *static_cast(xmldoc) = parser.alloc; + if (result) + { + // since we removed last character, we have to handle the only possible false positive (stray <) + if (endch == '<') + return make_parse_result(status_unrecognized_tag, length - 1); - // since we removed last character, we have to handle the only possible false positive - if (result && endch == '<') + // check if there are any element nodes parsed + xml_node_struct* first_root_child_parsed = last_root_child ? last_root_child->next_sibling : root->first_child; + + if (!PUGI__OPTSET(parse_fragment) && !has_element_node_siblings(first_root_child_parsed)) + return make_parse_result(status_no_document_element, length - 1); + } + else { - // there's no possible well-formed document with < at the end - return make_parse_result(status_unrecognized_tag, length); + // roll back offset if it occurs on a null terminator in the source buffer + if (result.offset > 0 && static_cast(result.offset) == length - 1 && endch == 0) + result.offset--; } return result; @@ -2465,7 +2946,7 @@ namespace }; // Output facilities - xml_encoding get_write_native_encoding() + PUGI__FN xml_encoding get_write_native_encoding() { #ifdef PUGIXML_WCHAR_MODE return get_wchar_encoding(); @@ -2474,7 +2955,7 @@ namespace #endif } - xml_encoding get_write_encoding(xml_encoding encoding) + PUGI__FN xml_encoding get_write_encoding(xml_encoding encoding) { // replace wchar encoding with utf implementation if (encoding == encoding_wchar) return get_wchar_encoding(); @@ -2493,20 +2974,20 @@ namespace } #ifdef PUGIXML_WCHAR_MODE - size_t get_valid_length(const char_t* data, size_t length) + PUGI__FN size_t get_valid_length(const char_t* data, size_t length) { - assert(length > 0); + if (length < 1) return 0; // discard last character if it's the lead of a surrogate pair - return (sizeof(wchar_t) == 2 && (unsigned)(static_cast(data[length - 1]) - 0xD800) < 0x400) ? length - 1 : length; + return (sizeof(wchar_t) == 2 && static_cast(static_cast(data[length - 1]) - 0xD800) < 0x400) ? length - 1 : length; } - size_t convert_buffer(char* result, const char_t* data, size_t length, xml_encoding encoding) + PUGI__FN size_t convert_buffer_output(char_t* r_char, uint8_t* r_u8, uint16_t* r_u16, uint32_t* r_u32, const char_t* data, size_t length, xml_encoding encoding) { // only endian-swapping is required if (need_endian_swap_utf(encoding, get_wchar_encoding())) { - convert_wchar_endian_swap(reinterpret_cast(result), data, length); + convert_wchar_endian_swap(r_char, data, length); return length * sizeof(char_t); } @@ -2514,11 +2995,8 @@ namespace // convert to utf8 if (encoding == encoding_utf8) { - uint8_t* dest = reinterpret_cast(result); - - uint8_t* end = sizeof(wchar_t) == 2 ? - utf_decoder::decode_utf16_block(reinterpret_cast(data), length, dest) : - utf_decoder::decode_utf32_block(reinterpret_cast(data), length, dest); + uint8_t* dest = r_u8; + uint8_t* end = utf_decoder::decode_wchar_block(data, length, dest); return static_cast(end - dest); } @@ -2526,10 +3004,10 @@ namespace // convert to utf16 if (encoding == encoding_utf16_be || encoding == encoding_utf16_le) { - uint16_t* dest = reinterpret_cast(result); + uint16_t* dest = r_u16; // convert to native utf16 - uint16_t* end = utf_decoder::decode_utf32_block(reinterpret_cast(data), length, dest); + uint16_t* end = utf_decoder::decode_wchar_block(data, length, dest); // swap if necessary xml_encoding native_encoding = is_little_endian() ? encoding_utf16_le : encoding_utf16_be; @@ -2542,10 +3020,10 @@ namespace // convert to utf32 if (encoding == encoding_utf32_be || encoding == encoding_utf32_le) { - uint32_t* dest = reinterpret_cast(result); + uint32_t* dest = r_u32; // convert to native utf32 - uint32_t* end = utf_decoder::decode_utf16_block(reinterpret_cast(data), length, dest); + uint32_t* end = utf_decoder::decode_wchar_block(data, length, dest); // swap if necessary xml_encoding native_encoding = is_little_endian() ? encoding_utf32_le : encoding_utf32_be; @@ -2555,13 +3033,22 @@ namespace return static_cast(end - dest) * sizeof(uint32_t); } + // convert to latin1 + if (encoding == encoding_latin1) + { + uint8_t* dest = r_u8; + uint8_t* end = utf_decoder::decode_wchar_block(data, length, dest); + + return static_cast(end - dest); + } + assert(!"Invalid encoding"); return 0; } #else - size_t get_valid_length(const char_t* data, size_t length) + PUGI__FN size_t get_valid_length(const char_t* data, size_t length) { - assert(length > 4); + if (length < 5) return 0; for (size_t i = 1; i <= 4; ++i) { @@ -2575,11 +3062,11 @@ namespace return length; } - size_t convert_buffer(char* result, const char_t* data, size_t length, xml_encoding encoding) + PUGI__FN size_t convert_buffer_output(char_t* /* r_char */, uint8_t* r_u8, uint16_t* r_u16, uint32_t* r_u32, const char_t* data, size_t length, xml_encoding encoding) { if (encoding == encoding_utf16_be || encoding == encoding_utf16_le) { - uint16_t* dest = reinterpret_cast(result); + uint16_t* dest = r_u16; // convert to native utf16 uint16_t* end = utf_decoder::decode_utf8_block(reinterpret_cast(data), length, dest); @@ -2594,7 +3081,7 @@ namespace if (encoding == encoding_utf32_be || encoding == encoding_utf32_le) { - uint32_t* dest = reinterpret_cast(result); + uint32_t* dest = r_u32; // convert to native utf32 uint32_t* end = utf_decoder::decode_utf8_block(reinterpret_cast(data), length, dest); @@ -2607,6 +3094,14 @@ namespace return static_cast(end - dest) * sizeof(uint32_t); } + if (encoding == encoding_latin1) + { + uint8_t* dest = r_u8; + uint8_t* end = utf_decoder::decode_utf8_block(reinterpret_cast(data), length, dest); + + return static_cast(end - dest); + } + assert(!"Invalid encoding"); return 0; } @@ -2618,8 +3113,9 @@ namespace xml_buffered_writer& operator=(const xml_buffered_writer&); public: - xml_buffered_writer(xml_writer& writer, xml_encoding user_encoding): writer(writer), bufsize(0), encoding(get_write_encoding(user_encoding)) + xml_buffered_writer(xml_writer& writer_, xml_encoding user_encoding): writer(writer_), bufsize(0), encoding(get_write_encoding(user_encoding)) { + PUGI__STATIC_ASSERT(bufcapacity >= 8); } ~xml_buffered_writer() @@ -2627,10 +3123,11 @@ namespace flush(); } - void flush() + size_t flush() { flush(buffer, bufsize); bufsize = 0; + return 0; } void flush(const char_t* data, size_t size) @@ -2643,175 +3140,202 @@ namespace else { // convert chunk - size_t result = convert_buffer(scratch, data, size, encoding); + size_t result = convert_buffer_output(scratch.data_char, scratch.data_u8, scratch.data_u16, scratch.data_u32, data, size, encoding); assert(result <= sizeof(scratch)); // write data - writer.write(scratch, result); + writer.write(scratch.data_u8, result); } } - void write(const char_t* data, size_t length) + void write_direct(const char_t* data, size_t length) { - if (bufsize + length > bufcapacity) - { - // flush the remaining buffer contents - flush(); + // flush the remaining buffer contents + flush(); - // handle large chunks - if (length > bufcapacity) + // handle large chunks + if (length > bufcapacity) + { + if (encoding == get_write_native_encoding()) { - if (encoding == get_write_native_encoding()) - { - // fast path, can just write data chunk - writer.write(data, length * sizeof(char_t)); - return; - } - - // need to convert in suitable chunks - while (length > bufcapacity) - { - // get chunk size by selecting such number of characters that are guaranteed to fit into scratch buffer - // and form a complete codepoint sequence (i.e. discard start of last codepoint if necessary) - size_t chunk_size = get_valid_length(data, bufcapacity); + // fast path, can just write data chunk + writer.write(data, length * sizeof(char_t)); + return; + } - // convert chunk and write - flush(data, chunk_size); + // need to convert in suitable chunks + while (length > bufcapacity) + { + // get chunk size by selecting such number of characters that are guaranteed to fit into scratch buffer + // and form a complete codepoint sequence (i.e. discard start of last codepoint if necessary) + size_t chunk_size = get_valid_length(data, bufcapacity); + assert(chunk_size); - // iterate - data += chunk_size; - length -= chunk_size; - } + // convert chunk and write + flush(data, chunk_size); - // small tail is copied below - bufsize = 0; + // iterate + data += chunk_size; + length -= chunk_size; } + + // small tail is copied below + bufsize = 0; } memcpy(buffer + bufsize, data, length * sizeof(char_t)); bufsize += length; } - void write(const char_t* data) + void write_buffer(const char_t* data, size_t length) + { + size_t offset = bufsize; + + if (offset + length <= bufcapacity) + { + memcpy(buffer + offset, data, length * sizeof(char_t)); + bufsize = offset + length; + } + else + { + write_direct(data, length); + } + } + + void write_string(const char_t* data) { - write(data, strlength(data)); + // write the part of the string that fits in the buffer + size_t offset = bufsize; + + while (*data && offset < bufcapacity) + buffer[offset++] = *data++; + + // write the rest + if (offset < bufcapacity) + { + bufsize = offset; + } + else + { + // backtrack a bit if we have split the codepoint + size_t length = offset - bufsize; + size_t extra = length - get_valid_length(data - length, length); + + bufsize = offset - extra; + + write_direct(data - extra, strlength(data) + extra); + } } void write(char_t d0) { - if (bufsize + 1 > bufcapacity) flush(); + size_t offset = bufsize; + if (offset > bufcapacity - 1) offset = flush(); - buffer[bufsize + 0] = d0; - bufsize += 1; + buffer[offset + 0] = d0; + bufsize = offset + 1; } void write(char_t d0, char_t d1) { - if (bufsize + 2 > bufcapacity) flush(); + size_t offset = bufsize; + if (offset > bufcapacity - 2) offset = flush(); - buffer[bufsize + 0] = d0; - buffer[bufsize + 1] = d1; - bufsize += 2; + buffer[offset + 0] = d0; + buffer[offset + 1] = d1; + bufsize = offset + 2; } void write(char_t d0, char_t d1, char_t d2) { - if (bufsize + 3 > bufcapacity) flush(); + size_t offset = bufsize; + if (offset > bufcapacity - 3) offset = flush(); - buffer[bufsize + 0] = d0; - buffer[bufsize + 1] = d1; - buffer[bufsize + 2] = d2; - bufsize += 3; + buffer[offset + 0] = d0; + buffer[offset + 1] = d1; + buffer[offset + 2] = d2; + bufsize = offset + 3; } void write(char_t d0, char_t d1, char_t d2, char_t d3) { - if (bufsize + 4 > bufcapacity) flush(); + size_t offset = bufsize; + if (offset > bufcapacity - 4) offset = flush(); - buffer[bufsize + 0] = d0; - buffer[bufsize + 1] = d1; - buffer[bufsize + 2] = d2; - buffer[bufsize + 3] = d3; - bufsize += 4; + buffer[offset + 0] = d0; + buffer[offset + 1] = d1; + buffer[offset + 2] = d2; + buffer[offset + 3] = d3; + bufsize = offset + 4; } void write(char_t d0, char_t d1, char_t d2, char_t d3, char_t d4) { - if (bufsize + 5 > bufcapacity) flush(); + size_t offset = bufsize; + if (offset > bufcapacity - 5) offset = flush(); - buffer[bufsize + 0] = d0; - buffer[bufsize + 1] = d1; - buffer[bufsize + 2] = d2; - buffer[bufsize + 3] = d3; - buffer[bufsize + 4] = d4; - bufsize += 5; + buffer[offset + 0] = d0; + buffer[offset + 1] = d1; + buffer[offset + 2] = d2; + buffer[offset + 3] = d3; + buffer[offset + 4] = d4; + bufsize = offset + 5; } void write(char_t d0, char_t d1, char_t d2, char_t d3, char_t d4, char_t d5) { - if (bufsize + 6 > bufcapacity) flush(); + size_t offset = bufsize; + if (offset > bufcapacity - 6) offset = flush(); - buffer[bufsize + 0] = d0; - buffer[bufsize + 1] = d1; - buffer[bufsize + 2] = d2; - buffer[bufsize + 3] = d3; - buffer[bufsize + 4] = d4; - buffer[bufsize + 5] = d5; - bufsize += 6; + buffer[offset + 0] = d0; + buffer[offset + 1] = d1; + buffer[offset + 2] = d2; + buffer[offset + 3] = d3; + buffer[offset + 4] = d4; + buffer[offset + 5] = d5; + bufsize = offset + 6; } // utf8 maximum expansion: x4 (-> utf32) // utf16 maximum expansion: x2 (-> utf32) // utf32 maximum expansion: x1 - enum { bufcapacity = 2048 }; + enum + { + bufcapacitybytes = + #ifdef PUGIXML_MEMORY_OUTPUT_STACK + PUGIXML_MEMORY_OUTPUT_STACK + #else + 10240 + #endif + , + bufcapacity = bufcapacitybytes / (sizeof(char_t) + 4) + }; char_t buffer[bufcapacity]; - char scratch[4 * bufcapacity]; + + union + { + uint8_t data_u8[4 * bufcapacity]; + uint16_t data_u16[2 * bufcapacity]; + uint32_t data_u32[bufcapacity]; + char_t data_char[bufcapacity]; + } scratch; xml_writer& writer; size_t bufsize; xml_encoding encoding; }; - void write_bom(xml_writer& writer, xml_encoding encoding) - { - switch (encoding) - { - case encoding_utf8: - writer.write("\xef\xbb\xbf", 3); - break; - - case encoding_utf16_be: - writer.write("\xfe\xff", 2); - break; - - case encoding_utf16_le: - writer.write("\xff\xfe", 2); - break; - - case encoding_utf32_be: - writer.write("\x00\x00\xfe\xff", 4); - break; - - case encoding_utf32_le: - writer.write("\xff\xfe\x00\x00", 4); - break; - - default: - assert(!"Invalid encoding"); - } - } - - void text_output_escaped(xml_buffered_writer& writer, const char_t* s, chartypex_t type) + PUGI__FN void text_output_escaped(xml_buffered_writer& writer, const char_t* s, chartypex_t type) { while (*s) { const char_t* prev = s; // While *s is a usual symbol - while (!IS_CHARTYPEX(*s, type)) ++s; + PUGI__SCANWHILE_UNROLL(!PUGI__IS_CHARTYPEX(ss, type)); - writer.write(prev, static_cast(s - prev)); + writer.write_buffer(prev, static_cast(s - prev)); switch (*s) { @@ -2843,7 +3367,15 @@ namespace } } - void text_output_cdata(xml_buffered_writer& writer, const char_t* s) + PUGI__FN void text_output(xml_buffered_writer& writer, const char_t* s, chartypex_t type, unsigned int flags) + { + if (flags & format_no_escapes) + writer.write_string(s); + else + text_output_escaped(writer, s, type); + } + + PUGI__FN void text_output_cdata(xml_buffered_writer& writer, const char_t* s) { do { @@ -2858,244 +3390,646 @@ namespace // skip ]] if we stopped at ]]>, > will go to the next CDATA section if (*s) s += 2; - writer.write(prev, static_cast(s - prev)); + writer.write_buffer(prev, static_cast(s - prev)); writer.write(']', ']', '>'); } while (*s); } - void node_output_attributes(xml_buffered_writer& writer, const xml_node& node) + PUGI__FN void text_output_indent(xml_buffered_writer& writer, const char_t* indent, size_t indent_length, unsigned int depth) { - const char_t* default_name = PUGIXML_TEXT(":anonymous"); - - for (xml_attribute a = node.first_attribute(); a; a = a.next_attribute()) + switch (indent_length) { - writer.write(' '); - writer.write(a.name()[0] ? a.name() : default_name); - writer.write('=', '"'); - - text_output_escaped(writer, a.value(), ctx_special_attr); - - writer.write('"'); + case 1: + { + for (unsigned int i = 0; i < depth; ++i) + writer.write(indent[0]); + break; } - } - - void node_output(xml_buffered_writer& writer, const xml_node& node, const char_t* indent, unsigned int flags, unsigned int depth) - { - const char_t* default_name = PUGIXML_TEXT(":anonymous"); - if ((flags & format_indent) != 0 && (flags & format_raw) == 0) - for (unsigned int i = 0; i < depth; ++i) writer.write(indent); - - switch (node.type()) - { - case node_document: + case 2: { - for (xml_node n = node.first_child(); n; n = n.next_sibling()) - node_output(writer, n, indent, flags, depth); + for (unsigned int i = 0; i < depth; ++i) + writer.write(indent[0], indent[1]); break; } - - case node_element: + + case 3: { - const char_t* name = node.name()[0] ? node.name() : default_name; + for (unsigned int i = 0; i < depth; ++i) + writer.write(indent[0], indent[1], indent[2]); + break; + } - writer.write('<'); - writer.write(name); + case 4: + { + for (unsigned int i = 0; i < depth; ++i) + writer.write(indent[0], indent[1], indent[2], indent[3]); + break; + } - node_output_attributes(writer, node); + default: + { + for (unsigned int i = 0; i < depth; ++i) + writer.write_buffer(indent, indent_length); + } + } + } - if (flags & format_raw) - { - if (!node.first_child()) - writer.write(' ', '/', '>'); - else - { - writer.write('>'); + PUGI__FN void node_output_comment(xml_buffered_writer& writer, const char_t* s) + { + writer.write('<', '!', '-', '-'); - for (xml_node n = node.first_child(); n; n = n.next_sibling()) - node_output(writer, n, indent, flags, depth + 1); + while (*s) + { + const char_t* prev = s; - writer.write('<', '/'); - writer.write(name); - writer.write('>'); - } - } - else if (!node.first_child()) - writer.write(' ', '/', '>', '\n'); - else if (node.first_child() == node.last_child() && (node.first_child().type() == node_pcdata || node.first_child().type() == node_cdata)) - { - writer.write('>'); + // look for -\0 or -- sequence - we can't output it since -- is illegal in comment body + while (*s && !(s[0] == '-' && (s[1] == '-' || s[1] == 0))) ++s; - if (node.first_child().type() == node_pcdata) - text_output_escaped(writer, node.first_child().value(), ctx_special_pcdata); - else - text_output_cdata(writer, node.first_child().value()); + writer.write_buffer(prev, static_cast(s - prev)); - writer.write('<', '/'); - writer.write(name); - writer.write('>', '\n'); - } - else + if (*s) { - writer.write('>', '\n'); - - for (xml_node n = node.first_child(); n; n = n.next_sibling()) - node_output(writer, n, indent, flags, depth + 1); + assert(*s == '-'); - if ((flags & format_indent) != 0 && (flags & format_raw) == 0) - for (unsigned int i = 0; i < depth; ++i) writer.write(indent); - - writer.write('<', '/'); - writer.write(name); - writer.write('>', '\n'); + writer.write('-', ' '); + ++s; } - - break; } - - case node_pcdata: - text_output_escaped(writer, node.value(), ctx_special_pcdata); - if ((flags & format_raw) == 0) writer.write('\n'); - break; - case node_cdata: - text_output_cdata(writer, node.value()); - if ((flags & format_raw) == 0) writer.write('\n'); - break; + writer.write('-', '-', '>'); + } - case node_comment: - writer.write('<', '!', '-', '-'); - writer.write(node.value()); - writer.write('-', '-', '>'); - if ((flags & format_raw) == 0) writer.write('\n'); - break; + PUGI__FN void node_output_pi_value(xml_buffered_writer& writer, const char_t* s) + { + while (*s) + { + const char_t* prev = s; - case node_pi: - case node_declaration: - writer.write('<', '?'); - writer.write(node.name()[0] ? node.name() : default_name); + // look for ?> sequence - we can't output it since ?> terminates PI + while (*s && !(s[0] == '?' && s[1] == '>')) ++s; - if (node.type() == node_declaration) - { - node_output_attributes(writer, node); - } - else if (node.value()[0]) + writer.write_buffer(prev, static_cast(s - prev)); + + if (*s) { - writer.write(' '); - writer.write(node.value()); - } + assert(s[0] == '?' && s[1] == '>'); - writer.write('?', '>'); - if ((flags & format_raw) == 0) writer.write('\n'); - break; + writer.write('?', ' ', '>'); + s += 2; + } + } + } - case node_doctype: - writer.write('<', '!', 'D', 'O', 'C'); - writer.write('T', 'Y', 'P', 'E'); + PUGI__FN void node_output_attributes(xml_buffered_writer& writer, xml_node_struct* node, unsigned int flags) + { + const char_t* default_name = PUGIXML_TEXT(":anonymous"); - if (node.value()[0]) - { - writer.write(' '); - writer.write(node.value()); - } + for (xml_attribute_struct* a = node->first_attribute; a; a = a->next_attribute) + { + writer.write(' '); + writer.write_string(a->name ? a->name : default_name); + writer.write('=', '"'); - writer.write('>'); - if ((flags & format_raw) == 0) writer.write('\n'); - break; + if (a->value) + text_output(writer, a->value, ctx_special_attr, flags); - default: - assert(!"Invalid node type"); + writer.write('"'); } } - inline bool has_declaration(const xml_node& node) + PUGI__FN bool node_output_start(xml_buffered_writer& writer, xml_node_struct* node, unsigned int flags) { - for (xml_node child = node.first_child(); child; child = child.next_sibling()) + const char_t* default_name = PUGIXML_TEXT(":anonymous"); + const char_t* name = node->name ? node->name : default_name; + + writer.write('<'); + writer.write_string(name); + + if (node->first_attribute) + node_output_attributes(writer, node, flags); + + if (!node->first_child) { - xml_node_type type = child.type(); + writer.write(' ', '/', '>'); - if (type == node_declaration) return true; - if (type == node_element) return false; + return false; } + else + { + writer.write('>'); - return false; + return true; + } } - inline bool allow_insert_child(xml_node_type parent, xml_node_type child) + PUGI__FN void node_output_end(xml_buffered_writer& writer, xml_node_struct* node) { - if (parent != node_document && parent != node_element) return false; - if (child == node_document || child == node_null) return false; - if (parent != node_document && (child == node_declaration || child == node_doctype)) return false; + const char_t* default_name = PUGIXML_TEXT(":anonymous"); + const char_t* name = node->name ? node->name : default_name; - return true; + writer.write('<', '/'); + writer.write_string(name); + writer.write('>'); } - void recursive_copy_skip(xml_node& dest, const xml_node& source, const xml_node& skip) + PUGI__FN void node_output_simple(xml_buffered_writer& writer, xml_node_struct* node, unsigned int flags) { - assert(dest.type() == source.type()); + const char_t* default_name = PUGIXML_TEXT(":anonymous"); - switch (source.type()) - { - case node_element: + switch (PUGI__NODETYPE(node)) { - dest.set_name(source.name()); + case node_pcdata: + text_output(writer, node->value ? node->value : PUGIXML_TEXT(""), ctx_special_pcdata, flags); + break; - for (xml_attribute a = source.first_attribute(); a; a = a.next_attribute()) - dest.append_attribute(a.name()).set_value(a.value()); + case node_cdata: + text_output_cdata(writer, node->value ? node->value : PUGIXML_TEXT("")); + break; - for (xml_node c = source.first_child(); c; c = c.next_sibling()) + case node_comment: + node_output_comment(writer, node->value ? node->value : PUGIXML_TEXT("")); + break; + + case node_pi: + writer.write('<', '?'); + writer.write_string(node->name ? node->name : default_name); + + if (node->value) + { + writer.write(' '); + node_output_pi_value(writer, node->value); + } + + writer.write('?', '>'); + break; + + case node_declaration: + writer.write('<', '?'); + writer.write_string(node->name ? node->name : default_name); + node_output_attributes(writer, node, flags); + writer.write('?', '>'); + break; + + case node_doctype: + writer.write('<', '!', 'D', 'O', 'C'); + writer.write('T', 'Y', 'P', 'E'); + + if (node->value) + { + writer.write(' '); + writer.write_string(node->value); + } + + writer.write('>'); + break; + + default: + assert(!"Invalid node type"); + } + } + + enum indent_flags_t + { + indent_newline = 1, + indent_indent = 2 + }; + + PUGI__FN void node_output(xml_buffered_writer& writer, xml_node_struct* root, const char_t* indent, unsigned int flags, unsigned int depth) + { + size_t indent_length = ((flags & (format_indent | format_raw)) == format_indent) ? strlength(indent) : 0; + unsigned int indent_flags = indent_indent; + + xml_node_struct* node = root; + + do + { + assert(node); + + // begin writing current node + if (PUGI__NODETYPE(node) == node_pcdata || PUGI__NODETYPE(node) == node_cdata) + { + node_output_simple(writer, node, flags); + + indent_flags = 0; + } + else { - if (c == skip) continue; + if ((indent_flags & indent_newline) && (flags & format_raw) == 0) + writer.write('\n'); + + if ((indent_flags & indent_indent) && indent_length) + text_output_indent(writer, indent, indent_length, depth); + + if (PUGI__NODETYPE(node) == node_element) + { + indent_flags = indent_newline | indent_indent; - xml_node cc = dest.append_child(c.type()); - assert(cc); + if (node_output_start(writer, node, flags)) + { + node = node->first_child; + depth++; + continue; + } + } + else if (PUGI__NODETYPE(node) == node_document) + { + indent_flags = indent_indent; + + if (node->first_child) + { + node = node->first_child; + continue; + } + } + else + { + node_output_simple(writer, node, flags); - recursive_copy_skip(cc, c, skip); + indent_flags = indent_newline | indent_indent; + } } - break; + // continue to the next node + while (node != root) + { + if (node->next_sibling) + { + node = node->next_sibling; + break; + } + + node = node->parent; + + // write closing node + if (PUGI__NODETYPE(node) == node_element) + { + depth--; + + if ((indent_flags & indent_newline) && (flags & format_raw) == 0) + writer.write('\n'); + + if ((indent_flags & indent_indent) && indent_length) + text_output_indent(writer, indent, indent_length, depth); + + node_output_end(writer, node); + + indent_flags = indent_newline | indent_indent; + } + } } + while (node != root); - case node_pcdata: - case node_cdata: - case node_comment: - case node_doctype: - dest.set_value(source.value()); - break; + if ((indent_flags & indent_newline) && (flags & format_raw) == 0) + writer.write('\n'); + } - case node_pi: - dest.set_name(source.name()); - dest.set_value(source.value()); - break; + PUGI__FN bool has_declaration(xml_node_struct* node) + { + for (xml_node_struct* child = node->first_child; child; child = child->next_sibling) + { + xml_node_type type = PUGI__NODETYPE(child); - case node_declaration: + if (type == node_declaration) return true; + if (type == node_element) return false; + } + + return false; + } + + PUGI__FN bool is_attribute_of(xml_attribute_struct* attr, xml_node_struct* node) + { + for (xml_attribute_struct* a = node->first_attribute; a; a = a->next_attribute) + if (a == attr) + return true; + + return false; + } + + PUGI__FN bool allow_insert_attribute(xml_node_type parent) + { + return parent == node_element || parent == node_declaration; + } + + PUGI__FN bool allow_insert_child(xml_node_type parent, xml_node_type child) + { + if (parent != node_document && parent != node_element) return false; + if (child == node_document || child == node_null) return false; + if (parent != node_document && (child == node_declaration || child == node_doctype)) return false; + + return true; + } + + PUGI__FN bool allow_move(xml_node parent, xml_node child) + { + // check that child can be a child of parent + if (!allow_insert_child(parent.type(), child.type())) + return false; + + // check that node is not moved between documents + if (parent.root() != child.root()) + return false; + + // check that new parent is not in the child subtree + xml_node cur = parent; + + while (cur) { - dest.set_name(source.name()); + if (cur == child) + return false; - for (xml_attribute a = source.first_attribute(); a; a = a.next_attribute()) - dest.append_attribute(a.name()).set_value(a.value()); + cur = cur.parent(); + } - break; + return true; + } + + PUGI__FN void node_copy_string(char_t*& dest, uintptr_t& header, uintptr_t header_mask, char_t* source, uintptr_t& source_header, xml_allocator* alloc) + { + assert(!dest && (header & header_mask) == 0); + + if (source) + { + if (alloc && (source_header & header_mask) == 0) + { + dest = source; + + // since strcpy_insitu can reuse document buffer memory we need to mark both source and dest as shared + header |= xml_memory_page_contents_shared_mask; + source_header |= xml_memory_page_contents_shared_mask; + } + else + strcpy_insitu(dest, header, header_mask, source); } + } - default: - assert(!"Invalid node type"); + PUGI__FN void node_copy_contents(xml_node_struct* dn, xml_node_struct* sn, xml_allocator* shared_alloc) + { + node_copy_string(dn->name, dn->header, xml_memory_page_name_allocated_mask, sn->name, sn->header, shared_alloc); + node_copy_string(dn->value, dn->header, xml_memory_page_value_allocated_mask, sn->value, sn->header, shared_alloc); + + for (xml_attribute_struct* sa = sn->first_attribute; sa; sa = sa->next_attribute) + { + xml_attribute_struct* da = append_new_attribute(dn, get_allocator(dn)); + + if (da) + { + node_copy_string(da->name, da->header, xml_memory_page_name_allocated_mask, sa->name, sa->header, shared_alloc); + node_copy_string(da->value, da->header, xml_memory_page_value_allocated_mask, sa->value, sa->header, shared_alloc); + } + } + } + + PUGI__FN void node_copy_tree(xml_node_struct* dn, xml_node_struct* sn) + { + xml_allocator& alloc = get_allocator(dn); + xml_allocator* shared_alloc = (&alloc == &get_allocator(sn)) ? &alloc : 0; + + node_copy_contents(dn, sn, shared_alloc); + + xml_node_struct* dit = dn; + xml_node_struct* sit = sn->first_child; + + while (sit && sit != sn) + { + if (sit != dn) + { + xml_node_struct* copy = append_new_node(dit, alloc, PUGI__NODETYPE(sit)); + + if (copy) + { + node_copy_contents(copy, sit, shared_alloc); + + if (sit->first_child) + { + dit = copy; + sit = sit->first_child; + continue; + } + } + } + + // continue to the next node + do + { + if (sit->next_sibling) + { + sit = sit->next_sibling; + break; + } + + sit = sit->parent; + dit = dit->parent; + } + while (sit != sn); } } + inline bool is_text_node(xml_node_struct* node) + { + xml_node_type type = PUGI__NODETYPE(node); + + return type == node_pcdata || type == node_cdata; + } + + // get value with conversion functions + PUGI__FN int get_integer_base(const char_t* value) + { + const char_t* s = value; + + while (PUGI__IS_CHARTYPE(*s, ct_space)) + s++; + + if (*s == '-') + s++; + + return (s[0] == '0' && (s[1] == 'x' || s[1] == 'X')) ? 16 : 10; + } + + PUGI__FN int get_value_int(const char_t* value, int def) + { + if (!value) return def; + + int base = get_integer_base(value); + + #ifdef PUGIXML_WCHAR_MODE + return static_cast(wcstol(value, 0, base)); + #else + return static_cast(strtol(value, 0, base)); + #endif + } + + PUGI__FN unsigned int get_value_uint(const char_t* value, unsigned int def) + { + if (!value) return def; + + int base = get_integer_base(value); + + #ifdef PUGIXML_WCHAR_MODE + return static_cast(wcstoul(value, 0, base)); + #else + return static_cast(strtoul(value, 0, base)); + #endif + } + + PUGI__FN double get_value_double(const char_t* value, double def) + { + if (!value) return def; + + #ifdef PUGIXML_WCHAR_MODE + return wcstod(value, 0); + #else + return strtod(value, 0); + #endif + } + + PUGI__FN float get_value_float(const char_t* value, float def) + { + if (!value) return def; + + #ifdef PUGIXML_WCHAR_MODE + return static_cast(wcstod(value, 0)); + #else + return static_cast(strtod(value, 0)); + #endif + } + + PUGI__FN bool get_value_bool(const char_t* value, bool def) + { + if (!value) return def; + + // only look at first char + char_t first = *value; + + // 1*, t* (true), T* (True), y* (yes), Y* (YES) + return (first == '1' || first == 't' || first == 'T' || first == 'y' || first == 'Y'); + } + +#ifdef PUGIXML_HAS_LONG_LONG + PUGI__FN long long get_value_llong(const char_t* value, long long def) + { + if (!value) return def; + + int base = get_integer_base(value); + + #ifdef PUGIXML_WCHAR_MODE + #ifdef PUGI__MSVC_CRT_VERSION + return _wcstoi64(value, 0, base); + #else + return wcstoll(value, 0, base); + #endif + #else + #ifdef PUGI__MSVC_CRT_VERSION + return _strtoi64(value, 0, base); + #else + return strtoll(value, 0, base); + #endif + #endif + } + + PUGI__FN unsigned long long get_value_ullong(const char_t* value, unsigned long long def) + { + if (!value) return def; + + int base = get_integer_base(value); + + #ifdef PUGIXML_WCHAR_MODE + #ifdef PUGI__MSVC_CRT_VERSION + return _wcstoui64(value, 0, base); + #else + return wcstoull(value, 0, base); + #endif + #else + #ifdef PUGI__MSVC_CRT_VERSION + return _strtoui64(value, 0, base); + #else + return strtoull(value, 0, base); + #endif + #endif + } +#endif + + // set value with conversion functions + PUGI__FN bool set_value_buffer(char_t*& dest, uintptr_t& header, uintptr_t header_mask, char (&buf)[128]) + { + #ifdef PUGIXML_WCHAR_MODE + char_t wbuf[128]; + impl::widen_ascii(wbuf, buf); + + return strcpy_insitu(dest, header, header_mask, wbuf); + #else + return strcpy_insitu(dest, header, header_mask, buf); + #endif + } + + PUGI__FN bool set_value_convert(char_t*& dest, uintptr_t& header, uintptr_t header_mask, int value) + { + char buf[128]; + sprintf(buf, "%d", value); + + return set_value_buffer(dest, header, header_mask, buf); + } + + PUGI__FN bool set_value_convert(char_t*& dest, uintptr_t& header, uintptr_t header_mask, unsigned int value) + { + char buf[128]; + sprintf(buf, "%u", value); + + return set_value_buffer(dest, header, header_mask, buf); + } + + PUGI__FN bool set_value_convert(char_t*& dest, uintptr_t& header, uintptr_t header_mask, float value) + { + char buf[128]; + sprintf(buf, "%.9g", value); + + return set_value_buffer(dest, header, header_mask, buf); + } + + PUGI__FN bool set_value_convert(char_t*& dest, uintptr_t& header, uintptr_t header_mask, double value) + { + char buf[128]; + sprintf(buf, "%.17g", value); + + return set_value_buffer(dest, header, header_mask, buf); + } + + PUGI__FN bool set_value_convert(char_t*& dest, uintptr_t& header, uintptr_t header_mask, bool value) + { + return strcpy_insitu(dest, header, header_mask, value ? PUGIXML_TEXT("true") : PUGIXML_TEXT("false")); + } + +#ifdef PUGIXML_HAS_LONG_LONG + PUGI__FN bool set_value_convert(char_t*& dest, uintptr_t& header, uintptr_t header_mask, long long value) + { + char buf[128]; + sprintf(buf, "%lld", value); + + return set_value_buffer(dest, header, header_mask, buf); + } + + PUGI__FN bool set_value_convert(char_t*& dest, uintptr_t& header, uintptr_t header_mask, unsigned long long value) + { + char buf[128]; + sprintf(buf, "%llu", value); + + return set_value_buffer(dest, header, header_mask, buf); + } +#endif + // we need to get length of entire file to load it in memory; the only (relatively) sane way to do it is via seek/tell trick - xml_parse_status get_file_size(FILE* file, size_t& out_result) + PUGI__FN xml_parse_status get_file_size(FILE* file, size_t& out_result) { - #if defined(_MSC_VER) && _MSC_VER >= 1400 + #if defined(PUGI__MSVC_CRT_VERSION) && PUGI__MSVC_CRT_VERSION >= 1400 && !defined(_WIN32_WCE) // there are 64-bit versions of fseek/ftell, let's use them typedef __int64 length_type; _fseeki64(file, 0, SEEK_END); length_type length = _ftelli64(file); _fseeki64(file, 0, SEEK_SET); - #elif defined(__MINGW32__) && !defined(__NO_MINGW_LFS) && !defined(__STRICT_ANSI__) + #elif defined(__MINGW32__) && !defined(__NO_MINGW_LFS) && (!defined(__STRICT_ANSI__) || defined(__MINGW64_VERSION_MAJOR)) // there are 64-bit versions of fseek/ftell, let's use them typedef off64_t length_type; @@ -3125,7 +4059,31 @@ namespace return status_ok; } - xml_parse_result load_file_impl(xml_document& doc, FILE* file, unsigned int options, xml_encoding encoding) + PUGI__FN size_t zero_terminate_buffer(void* buffer, size_t size, xml_encoding encoding) + { + // We only need to zero-terminate if encoding conversion does not do it for us + #ifdef PUGIXML_WCHAR_MODE + xml_encoding wchar_encoding = get_wchar_encoding(); + + if (encoding == wchar_encoding || need_endian_swap_utf(encoding, wchar_encoding)) + { + size_t length = size / sizeof(char_t); + + static_cast(buffer)[length] = 0; + return (length + 1) * sizeof(char_t); + } + #else + if (encoding == encoding_utf8) + { + static_cast(buffer)[size] = 0; + return size + 1; + } + #endif + + return size; + } + + PUGI__FN xml_parse_result load_file_impl(xml_document& doc, FILE* file, unsigned int options, xml_encoding encoding) { if (!file) return make_parse_result(status_file_not_found); @@ -3139,8 +4097,10 @@ namespace return make_parse_result(size_status); } + size_t max_suffix_size = sizeof(char_t); + // allocate buffer for the whole file - char* contents = static_cast(global_allocate(size > 0 ? size : 1)); + char* contents = static_cast(xml_memory::allocate(size + max_suffix_size)); if (!contents) { @@ -3154,15 +4114,105 @@ namespace if (read_size != size) { - global_deallocate(contents); + xml_memory::deallocate(contents); return make_parse_result(status_io_error); } + + xml_encoding real_encoding = get_buffer_encoding(encoding, contents, size); - return doc.load_buffer_inplace_own(contents, size, options, encoding); + return doc.load_buffer_inplace_own(contents, zero_terminate_buffer(contents, size, real_encoding), options, real_encoding); } #ifndef PUGIXML_NO_STL - template xml_parse_result load_stream_impl(xml_document& doc, std::basic_istream& stream, unsigned int options, xml_encoding encoding) + template struct xml_stream_chunk + { + static xml_stream_chunk* create() + { + void* memory = xml_memory::allocate(sizeof(xml_stream_chunk)); + + return new (memory) xml_stream_chunk(); + } + + static void destroy(void* ptr) + { + xml_stream_chunk* chunk = static_cast(ptr); + + // free chunk chain + while (chunk) + { + xml_stream_chunk* next_ = chunk->next; + + xml_memory::deallocate(chunk); + + chunk = next_; + } + } + + xml_stream_chunk(): next(0), size(0) + { + } + + xml_stream_chunk* next; + size_t size; + + T data[xml_memory_page_size / sizeof(T)]; + }; + + template PUGI__FN xml_parse_status load_stream_data_noseek(std::basic_istream& stream, void** out_buffer, size_t* out_size) + { + buffer_holder chunks(0, xml_stream_chunk::destroy); + + // read file to a chunk list + size_t total = 0; + xml_stream_chunk* last = 0; + + while (!stream.eof()) + { + // allocate new chunk + xml_stream_chunk* chunk = xml_stream_chunk::create(); + if (!chunk) return status_out_of_memory; + + // append chunk to list + if (last) last = last->next = chunk; + else chunks.data = last = chunk; + + // read data to chunk + stream.read(chunk->data, static_cast(sizeof(chunk->data) / sizeof(T))); + chunk->size = static_cast(stream.gcount()) * sizeof(T); + + // read may set failbit | eofbit in case gcount() is less than read length, so check for other I/O errors + if (stream.bad() || (!stream.eof() && stream.fail())) return status_io_error; + + // guard against huge files (chunk size is small enough to make this overflow check work) + if (total + chunk->size < total) return status_out_of_memory; + total += chunk->size; + } + + size_t max_suffix_size = sizeof(char_t); + + // copy chunk list to a contiguous buffer + char* buffer = static_cast(xml_memory::allocate(total + max_suffix_size)); + if (!buffer) return status_out_of_memory; + + char* write = buffer; + + for (xml_stream_chunk* chunk = static_cast*>(chunks.data); chunk; chunk = chunk->next) + { + assert(write + chunk->size <= buffer + total); + memcpy(write, chunk->data, chunk->size); + write += chunk->size; + } + + assert(write == buffer + total); + + // return buffer + *out_buffer = buffer; + *out_size = total; + + return status_ok; + } + + template PUGI__FN xml_parse_status load_stream_data_seek(std::basic_istream& stream, void** out_buffer, size_t* out_size) { // get length of remaining data in stream typename std::basic_istream::pos_type pos = stream.tellg(); @@ -3170,55 +4220,85 @@ namespace std::streamoff length = stream.tellg() - pos; stream.seekg(pos); - if (stream.fail() || pos < 0) return make_parse_result(status_io_error); + if (stream.fail() || pos < 0) return status_io_error; // guard against huge files size_t read_length = static_cast(length); - if (static_cast(read_length) != length || length < 0) return make_parse_result(status_out_of_memory); + if (static_cast(read_length) != length || length < 0) return status_out_of_memory; + + size_t max_suffix_size = sizeof(char_t); // read stream data into memory (guard against stream exceptions with buffer holder) - buffer_holder buffer(global_allocate((read_length > 0 ? read_length : 1) * sizeof(T)), global_deallocate); - if (!buffer.data) return make_parse_result(status_out_of_memory); + buffer_holder buffer(xml_memory::allocate(read_length * sizeof(T) + max_suffix_size), xml_memory::deallocate); + if (!buffer.data) return status_out_of_memory; stream.read(static_cast(buffer.data), static_cast(read_length)); // read may set failbit | eofbit in case gcount() is less than read_length (i.e. line ending conversion), so check for other I/O errors - if (stream.bad()) return make_parse_result(status_io_error); + if (stream.bad() || (!stream.eof() && stream.fail())) return status_io_error; - // load data from buffer + // return buffer size_t actual_length = static_cast(stream.gcount()); assert(actual_length <= read_length); + + *out_buffer = buffer.release(); + *out_size = actual_length * sizeof(T); + + return status_ok; + } - return doc.load_buffer_inplace_own(buffer.release(), actual_length * sizeof(T), options, encoding); + template PUGI__FN xml_parse_result load_stream_impl(xml_document& doc, std::basic_istream& stream, unsigned int options, xml_encoding encoding) + { + void* buffer = 0; + size_t size = 0; + xml_parse_status status = status_ok; + + // if stream has an error bit set, bail out (otherwise tellg() can fail and we'll clear error bits) + if (stream.fail()) return make_parse_result(status_io_error); + + // load stream to memory (using seek-based implementation if possible, since it's faster and takes less memory) + if (stream.tellg() < 0) + { + stream.clear(); // clear error flags that could be set by a failing tellg + status = load_stream_data_noseek(stream, &buffer, &size); + } + else + status = load_stream_data_seek(stream, &buffer, &size); + + if (status != status_ok) return make_parse_result(status); + + xml_encoding real_encoding = get_buffer_encoding(encoding, buffer, size); + + return doc.load_buffer_inplace_own(buffer, zero_terminate_buffer(buffer, size, real_encoding), options, real_encoding); } #endif -#if defined(_MSC_VER) || defined(__BORLANDC__) || defined(__MINGW32__) - FILE* open_file_wide(const wchar_t* path, const wchar_t* mode) +#if defined(PUGI__MSVC_CRT_VERSION) || defined(__BORLANDC__) || (defined(__MINGW32__) && (!defined(__STRICT_ANSI__) || defined(__MINGW64_VERSION_MAJOR))) + PUGI__FN FILE* open_file_wide(const wchar_t* path, const wchar_t* mode) { return _wfopen(path, mode); } #else - char* convert_path_heap(const wchar_t* str) + PUGI__FN char* convert_path_heap(const wchar_t* str) { assert(str); // first pass: get length in utf8 characters - size_t length = wcslen(str); - size_t size = as_utf8_begin(str, length); + size_t length = strlength_wide(str); + size_t size = as_utf8_begin(str, length); // allocate resulting string - char* result = static_cast(global_allocate(size + 1)); + char* result = static_cast(xml_memory::allocate(size + 1)); if (!result) return 0; // second pass: convert to utf8 - as_utf8_end(result, size, str, length); + as_utf8_end(result, size, str, length); - return result; + return result; } - FILE* open_file_wide(const wchar_t* path, const wchar_t* mode) + PUGI__FN FILE* open_file_wide(const wchar_t* path, const wchar_t* mode) { // there is no standard function to open wide paths, so our best bet is to try utf8 path char* path_utf8 = convert_path_heap(path); @@ -3232,34 +4312,81 @@ namespace FILE* result = fopen(path_utf8, mode_ascii); // free dummy buffer - global_deallocate(path_utf8); + xml_memory::deallocate(path_utf8); return result; } #endif -} + + PUGI__FN bool save_file_impl(const xml_document& doc, FILE* file, const char_t* indent, unsigned int flags, xml_encoding encoding) + { + if (!file) return false; + + xml_writer_file writer(file); + doc.save(writer, indent, flags, encoding); + + int result = ferror(file); + + fclose(file); + + return result == 0; + } + + PUGI__FN xml_parse_result load_buffer_impl(xml_document_struct* doc, xml_node_struct* root, void* contents, size_t size, unsigned int options, xml_encoding encoding, bool is_mutable, bool own, char_t** out_buffer) + { + // check input buffer + if (!contents && size) return make_parse_result(status_io_error); + + // get actual encoding + xml_encoding buffer_encoding = impl::get_buffer_encoding(encoding, contents, size); + + // get private buffer + char_t* buffer = 0; + size_t length = 0; + + if (!impl::convert_buffer(buffer, length, buffer_encoding, contents, size, is_mutable)) return impl::make_parse_result(status_out_of_memory); + + // delete original buffer if we performed a conversion + if (own && buffer != contents && contents) impl::xml_memory::deallocate(contents); + + // store buffer for offset_debug + doc->buffer = buffer; + + // parse + xml_parse_result res = impl::xml_parser::parse(buffer, length, doc, root, options); + + // remember encoding + res.encoding = buffer_encoding; + + // grab onto buffer if it's our buffer, user is responsible for deallocating contents himself + if (own || buffer != contents) *out_buffer = buffer; + + return res; + } +PUGI__NS_END namespace pugi { - xml_writer_file::xml_writer_file(void* file): file(file) + PUGI__FN xml_writer_file::xml_writer_file(void* file_): file(file_) { } - void xml_writer_file::write(const void* data, size_t size) + PUGI__FN void xml_writer_file::write(const void* data, size_t size) { - fwrite(data, size, 1, static_cast(file)); + size_t result = fwrite(data, 1, size, static_cast(file)); + (void)!result; // unfortunately we can't do proper error handling here } #ifndef PUGIXML_NO_STL - xml_writer_stream::xml_writer_stream(std::basic_ostream >& stream): narrow_stream(&stream), wide_stream(0) + PUGI__FN xml_writer_stream::xml_writer_stream(std::basic_ostream >& stream): narrow_stream(&stream), wide_stream(0) { } - xml_writer_stream::xml_writer_stream(std::basic_ostream >& stream): narrow_stream(0), wide_stream(&stream) + PUGI__FN xml_writer_stream::xml_writer_stream(std::basic_ostream >& stream): narrow_stream(0), wide_stream(&stream) { } - void xml_writer_stream::write(const void* data, size_t size) + PUGI__FN void xml_writer_stream::write(const void* data, size_t size) { if (narrow_stream) { @@ -3276,411 +4403,439 @@ namespace pugi } #endif - xml_tree_walker::xml_tree_walker(): _depth(0) + PUGI__FN xml_tree_walker::xml_tree_walker(): _depth(0) { } - xml_tree_walker::~xml_tree_walker() + PUGI__FN xml_tree_walker::~xml_tree_walker() { } - int xml_tree_walker::depth() const + PUGI__FN int xml_tree_walker::depth() const { return _depth; } - bool xml_tree_walker::begin(xml_node&) + PUGI__FN bool xml_tree_walker::begin(xml_node&) { return true; } - bool xml_tree_walker::end(xml_node&) + PUGI__FN bool xml_tree_walker::end(xml_node&) { return true; } - xml_attribute::xml_attribute(): _attr(0) + PUGI__FN xml_attribute::xml_attribute(): _attr(0) + { + } + + PUGI__FN xml_attribute::xml_attribute(xml_attribute_struct* attr): _attr(attr) { } - xml_attribute::xml_attribute(xml_attribute_struct* attr): _attr(attr) + PUGI__FN static void unspecified_bool_xml_attribute(xml_attribute***) { } - xml_attribute::operator xml_attribute::unspecified_bool_type() const + PUGI__FN xml_attribute::operator xml_attribute::unspecified_bool_type() const { - return _attr ? &xml_attribute::_attr : 0; - } + return _attr ? unspecified_bool_xml_attribute : 0; + } - bool xml_attribute::operator!() const - { - return !_attr; - } + PUGI__FN bool xml_attribute::operator!() const + { + return !_attr; + } - bool xml_attribute::operator==(const xml_attribute& r) const + PUGI__FN bool xml_attribute::operator==(const xml_attribute& r) const { return (_attr == r._attr); } - bool xml_attribute::operator!=(const xml_attribute& r) const + PUGI__FN bool xml_attribute::operator!=(const xml_attribute& r) const { return (_attr != r._attr); } - bool xml_attribute::operator<(const xml_attribute& r) const + PUGI__FN bool xml_attribute::operator<(const xml_attribute& r) const { return (_attr < r._attr); } - bool xml_attribute::operator>(const xml_attribute& r) const + PUGI__FN bool xml_attribute::operator>(const xml_attribute& r) const { return (_attr > r._attr); } - bool xml_attribute::operator<=(const xml_attribute& r) const + PUGI__FN bool xml_attribute::operator<=(const xml_attribute& r) const { return (_attr <= r._attr); } - bool xml_attribute::operator>=(const xml_attribute& r) const + PUGI__FN bool xml_attribute::operator>=(const xml_attribute& r) const { return (_attr >= r._attr); } - xml_attribute xml_attribute::next_attribute() const - { - return _attr ? xml_attribute(_attr->next_attribute) : xml_attribute(); - } - - xml_attribute xml_attribute::previous_attribute() const - { - return _attr && _attr->prev_attribute_c->next_attribute ? xml_attribute(_attr->prev_attribute_c) : xml_attribute(); - } - - int xml_attribute::as_int() const + PUGI__FN xml_attribute xml_attribute::next_attribute() const { - if (!_attr || !_attr->value) return 0; - - #ifdef PUGIXML_WCHAR_MODE - return (int)wcstol(_attr->value, 0, 10); - #else - return (int)strtol(_attr->value, 0, 10); - #endif + return _attr ? xml_attribute(_attr->next_attribute) : xml_attribute(); } - unsigned int xml_attribute::as_uint() const + PUGI__FN xml_attribute xml_attribute::previous_attribute() const { - if (!_attr || !_attr->value) return 0; + return _attr && _attr->prev_attribute_c->next_attribute ? xml_attribute(_attr->prev_attribute_c) : xml_attribute(); + } - #ifdef PUGIXML_WCHAR_MODE - return (unsigned int)wcstoul(_attr->value, 0, 10); - #else - return (unsigned int)strtoul(_attr->value, 0, 10); - #endif + PUGI__FN const char_t* xml_attribute::as_string(const char_t* def) const + { + return (_attr && _attr->value) ? _attr->value : def; } - double xml_attribute::as_double() const + PUGI__FN int xml_attribute::as_int(int def) const { - if (!_attr || !_attr->value) return 0; + return impl::get_value_int(_attr ? _attr->value : 0, def); + } - #ifdef PUGIXML_WCHAR_MODE - return wcstod(_attr->value, 0); - #else - return strtod(_attr->value, 0); - #endif + PUGI__FN unsigned int xml_attribute::as_uint(unsigned int def) const + { + return impl::get_value_uint(_attr ? _attr->value : 0, def); } - float xml_attribute::as_float() const + PUGI__FN double xml_attribute::as_double(double def) const { - if (!_attr || !_attr->value) return 0; + return impl::get_value_double(_attr ? _attr->value : 0, def); + } - #ifdef PUGIXML_WCHAR_MODE - return (float)wcstod(_attr->value, 0); - #else - return (float)strtod(_attr->value, 0); - #endif + PUGI__FN float xml_attribute::as_float(float def) const + { + return impl::get_value_float(_attr ? _attr->value : 0, def); } - bool xml_attribute::as_bool() const + PUGI__FN bool xml_attribute::as_bool(bool def) const { - if (!_attr || !_attr->value) return false; + return impl::get_value_bool(_attr ? _attr->value : 0, def); + } - // only look at first char - char_t first = *_attr->value; +#ifdef PUGIXML_HAS_LONG_LONG + PUGI__FN long long xml_attribute::as_llong(long long def) const + { + return impl::get_value_llong(_attr ? _attr->value : 0, def); + } - // 1*, t* (true), T* (True), y* (yes), Y* (YES) - return (first == '1' || first == 't' || first == 'T' || first == 'y' || first == 'Y'); + PUGI__FN unsigned long long xml_attribute::as_ullong(unsigned long long def) const + { + return impl::get_value_ullong(_attr ? _attr->value : 0, def); } +#endif - bool xml_attribute::empty() const + PUGI__FN bool xml_attribute::empty() const { return !_attr; } - const char_t* xml_attribute::name() const + PUGI__FN const char_t* xml_attribute::name() const { return (_attr && _attr->name) ? _attr->name : PUGIXML_TEXT(""); } - const char_t* xml_attribute::value() const + PUGI__FN const char_t* xml_attribute::value() const { return (_attr && _attr->value) ? _attr->value : PUGIXML_TEXT(""); } - size_t xml_attribute::hash_value() const - { - return static_cast(reinterpret_cast(_attr) / sizeof(xml_attribute_struct)); - } + PUGI__FN size_t xml_attribute::hash_value() const + { + return static_cast(reinterpret_cast(_attr) / sizeof(xml_attribute_struct)); + } - xml_attribute_struct* xml_attribute::internal_object() const + PUGI__FN xml_attribute_struct* xml_attribute::internal_object() const { - return _attr; + return _attr; } - xml_attribute& xml_attribute::operator=(const char_t* rhs) + PUGI__FN xml_attribute& xml_attribute::operator=(const char_t* rhs) { set_value(rhs); return *this; } - xml_attribute& xml_attribute::operator=(int rhs) + PUGI__FN xml_attribute& xml_attribute::operator=(int rhs) { set_value(rhs); return *this; } - xml_attribute& xml_attribute::operator=(unsigned int rhs) + PUGI__FN xml_attribute& xml_attribute::operator=(unsigned int rhs) { set_value(rhs); return *this; } - xml_attribute& xml_attribute::operator=(double rhs) + PUGI__FN xml_attribute& xml_attribute::operator=(double rhs) { set_value(rhs); return *this; } - xml_attribute& xml_attribute::operator=(bool rhs) + PUGI__FN xml_attribute& xml_attribute::operator=(float rhs) + { + set_value(rhs); + return *this; + } + + PUGI__FN xml_attribute& xml_attribute::operator=(bool rhs) + { + set_value(rhs); + return *this; + } + +#ifdef PUGIXML_HAS_LONG_LONG + PUGI__FN xml_attribute& xml_attribute::operator=(long long rhs) + { + set_value(rhs); + return *this; + } + + PUGI__FN xml_attribute& xml_attribute::operator=(unsigned long long rhs) { set_value(rhs); return *this; } +#endif - bool xml_attribute::set_name(const char_t* rhs) + PUGI__FN bool xml_attribute::set_name(const char_t* rhs) { if (!_attr) return false; - return strcpy_insitu(_attr->name, _attr->header, xml_memory_page_name_allocated_mask, rhs); + return impl::strcpy_insitu(_attr->name, _attr->header, impl::xml_memory_page_name_allocated_mask, rhs); } - bool xml_attribute::set_value(const char_t* rhs) + PUGI__FN bool xml_attribute::set_value(const char_t* rhs) { if (!_attr) return false; - return strcpy_insitu(_attr->value, _attr->header, xml_memory_page_value_allocated_mask, rhs); + return impl::strcpy_insitu(_attr->value, _attr->header, impl::xml_memory_page_value_allocated_mask, rhs); } - bool xml_attribute::set_value(int rhs) + PUGI__FN bool xml_attribute::set_value(int rhs) { - char buf[128]; - sprintf(buf, "%d", rhs); - - #ifdef PUGIXML_WCHAR_MODE - char_t wbuf[128]; - widen_ascii(wbuf, buf); + if (!_attr) return false; - return set_value(wbuf); - #else - return set_value(buf); - #endif + return impl::set_value_convert(_attr->value, _attr->header, impl::xml_memory_page_value_allocated_mask, rhs); } - bool xml_attribute::set_value(unsigned int rhs) + PUGI__FN bool xml_attribute::set_value(unsigned int rhs) { - char buf[128]; - sprintf(buf, "%u", rhs); - - #ifdef PUGIXML_WCHAR_MODE - char_t wbuf[128]; - widen_ascii(wbuf, buf); + if (!_attr) return false; - return set_value(wbuf); - #else - return set_value(buf); - #endif + return impl::set_value_convert(_attr->value, _attr->header, impl::xml_memory_page_value_allocated_mask, rhs); } - bool xml_attribute::set_value(double rhs) + PUGI__FN bool xml_attribute::set_value(double rhs) { - char buf[128]; - sprintf(buf, "%g", rhs); + if (!_attr) return false; - #ifdef PUGIXML_WCHAR_MODE - char_t wbuf[128]; - widen_ascii(wbuf, buf); + return impl::set_value_convert(_attr->value, _attr->header, impl::xml_memory_page_value_allocated_mask, rhs); + } + + PUGI__FN bool xml_attribute::set_value(float rhs) + { + if (!_attr) return false; - return set_value(wbuf); - #else - return set_value(buf); - #endif + return impl::set_value_convert(_attr->value, _attr->header, impl::xml_memory_page_value_allocated_mask, rhs); } - bool xml_attribute::set_value(bool rhs) + PUGI__FN bool xml_attribute::set_value(bool rhs) { - return set_value(rhs ? PUGIXML_TEXT("true") : PUGIXML_TEXT("false")); + if (!_attr) return false; + + return impl::set_value_convert(_attr->value, _attr->header, impl::xml_memory_page_value_allocated_mask, rhs); } +#ifdef PUGIXML_HAS_LONG_LONG + PUGI__FN bool xml_attribute::set_value(long long rhs) + { + if (!_attr) return false; + + return impl::set_value_convert(_attr->value, _attr->header, impl::xml_memory_page_value_allocated_mask, rhs); + } + + PUGI__FN bool xml_attribute::set_value(unsigned long long rhs) + { + if (!_attr) return false; + + return impl::set_value_convert(_attr->value, _attr->header, impl::xml_memory_page_value_allocated_mask, rhs); + } +#endif + #ifdef __BORLANDC__ - bool operator&&(const xml_attribute& lhs, bool rhs) + PUGI__FN bool operator&&(const xml_attribute& lhs, bool rhs) { return (bool)lhs && rhs; } - bool operator||(const xml_attribute& lhs, bool rhs) + PUGI__FN bool operator||(const xml_attribute& lhs, bool rhs) { return (bool)lhs || rhs; } #endif - xml_node::xml_node(): _root(0) + PUGI__FN xml_node::xml_node(): _root(0) { } - xml_node::xml_node(xml_node_struct* p): _root(p) + PUGI__FN xml_node::xml_node(xml_node_struct* p): _root(p) { } - xml_node::operator xml_node::unspecified_bool_type() const + PUGI__FN static void unspecified_bool_xml_node(xml_node***) { - return _root ? &xml_node::_root : 0; - } + } + + PUGI__FN xml_node::operator xml_node::unspecified_bool_type() const + { + return _root ? unspecified_bool_xml_node : 0; + } - bool xml_node::operator!() const - { - return !_root; - } + PUGI__FN bool xml_node::operator!() const + { + return !_root; + } - xml_node::iterator xml_node::begin() const + PUGI__FN xml_node::iterator xml_node::begin() const { return iterator(_root ? _root->first_child : 0, _root); } - xml_node::iterator xml_node::end() const + PUGI__FN xml_node::iterator xml_node::end() const + { + return iterator(0, _root); + } + + PUGI__FN xml_node::attribute_iterator xml_node::attributes_begin() const + { + return attribute_iterator(_root ? _root->first_attribute : 0, _root); + } + + PUGI__FN xml_node::attribute_iterator xml_node::attributes_end() const { - return iterator(0, _root); + return attribute_iterator(0, _root); } - xml_node::attribute_iterator xml_node::attributes_begin() const + PUGI__FN xml_object_range xml_node::children() const { - return attribute_iterator(_root ? _root->first_attribute : 0, _root); + return xml_object_range(begin(), end()); } - xml_node::attribute_iterator xml_node::attributes_end() const + PUGI__FN xml_object_range xml_node::children(const char_t* name_) const { - return attribute_iterator(0, _root); + return xml_object_range(xml_named_node_iterator(child(name_)._root, _root, name_), xml_named_node_iterator(0, _root, name_)); } - bool xml_node::operator==(const xml_node& r) const + PUGI__FN xml_object_range xml_node::attributes() const + { + return xml_object_range(attributes_begin(), attributes_end()); + } + + PUGI__FN bool xml_node::operator==(const xml_node& r) const { return (_root == r._root); } - bool xml_node::operator!=(const xml_node& r) const + PUGI__FN bool xml_node::operator!=(const xml_node& r) const { return (_root != r._root); } - bool xml_node::operator<(const xml_node& r) const + PUGI__FN bool xml_node::operator<(const xml_node& r) const { return (_root < r._root); } - bool xml_node::operator>(const xml_node& r) const + PUGI__FN bool xml_node::operator>(const xml_node& r) const { return (_root > r._root); } - bool xml_node::operator<=(const xml_node& r) const + PUGI__FN bool xml_node::operator<=(const xml_node& r) const { return (_root <= r._root); } - bool xml_node::operator>=(const xml_node& r) const + PUGI__FN bool xml_node::operator>=(const xml_node& r) const { return (_root >= r._root); } - bool xml_node::empty() const + PUGI__FN bool xml_node::empty() const { return !_root; } - const char_t* xml_node::name() const + PUGI__FN const char_t* xml_node::name() const { return (_root && _root->name) ? _root->name : PUGIXML_TEXT(""); } - xml_node_type xml_node::type() const + PUGI__FN xml_node_type xml_node::type() const { - return _root ? static_cast((_root->header & xml_memory_page_type_mask) + 1) : node_null; + return _root ? PUGI__NODETYPE(_root) : node_null; } - const char_t* xml_node::value() const + PUGI__FN const char_t* xml_node::value() const { return (_root && _root->value) ? _root->value : PUGIXML_TEXT(""); } - xml_node xml_node::child(const char_t* name) const + PUGI__FN xml_node xml_node::child(const char_t* name_) const { if (!_root) return xml_node(); for (xml_node_struct* i = _root->first_child; i; i = i->next_sibling) - if (i->name && strequal(name, i->name)) return xml_node(i); + if (i->name && impl::strequal(name_, i->name)) return xml_node(i); return xml_node(); } - xml_attribute xml_node::attribute(const char_t* name) const + PUGI__FN xml_attribute xml_node::attribute(const char_t* name_) const { if (!_root) return xml_attribute(); for (xml_attribute_struct* i = _root->first_attribute; i; i = i->next_attribute) - if (i->name && strequal(name, i->name)) + if (i->name && impl::strequal(name_, i->name)) return xml_attribute(i); return xml_attribute(); } - xml_node xml_node::next_sibling(const char_t* name) const + PUGI__FN xml_node xml_node::next_sibling(const char_t* name_) const { if (!_root) return xml_node(); for (xml_node_struct* i = _root->next_sibling; i; i = i->next_sibling) - if (i->name && strequal(name, i->name)) return xml_node(i); + if (i->name && impl::strequal(name_, i->name)) return xml_node(i); return xml_node(); } - xml_node xml_node::next_sibling() const + PUGI__FN xml_node xml_node::next_sibling() const { - if (!_root) return xml_node(); - - if (_root->next_sibling) return xml_node(_root->next_sibling); - else return xml_node(); + return _root ? xml_node(_root->next_sibling) : xml_node(); } - xml_node xml_node::previous_sibling(const char_t* name) const + PUGI__FN xml_node xml_node::previous_sibling(const char_t* name_) const { if (!_root) return xml_node(); for (xml_node_struct* i = _root->prev_sibling_c; i->next_sibling; i = i->prev_sibling_c) - if (i->name && strequal(name, i->name)) return xml_node(i); + if (i->name && impl::strequal(name_, i->name)) return xml_node(i); return xml_node(); } - xml_node xml_node::previous_sibling() const + PUGI__FN xml_node xml_node::previous_sibling() const { if (!_root) return xml_node(); @@ -3688,75 +4843,72 @@ namespace pugi else return xml_node(); } - xml_node xml_node::parent() const + PUGI__FN xml_node xml_node::parent() const { return _root ? xml_node(_root->parent) : xml_node(); } - xml_node xml_node::root() const + PUGI__FN xml_node xml_node::root() const { - if (!_root) return xml_node(); - - xml_memory_page* page = reinterpret_cast(_root->header & xml_memory_page_pointer_mask); + return _root ? xml_node(&impl::get_document(_root)) : xml_node(); + } - return xml_node(static_cast(page->allocator)); + PUGI__FN xml_text xml_node::text() const + { + return xml_text(_root); } - const char_t* xml_node::child_value() const + PUGI__FN const char_t* xml_node::child_value() const { if (!_root) return PUGIXML_TEXT(""); for (xml_node_struct* i = _root->first_child; i; i = i->next_sibling) - { - xml_node_type type = static_cast((i->header & xml_memory_page_type_mask) + 1); - - if (i->value && (type == node_pcdata || type == node_cdata)) + if (i->value && impl::is_text_node(i)) return i->value; - } return PUGIXML_TEXT(""); } - const char_t* xml_node::child_value(const char_t* name) const + PUGI__FN const char_t* xml_node::child_value(const char_t* name_) const { - return child(name).child_value(); + return child(name_).child_value(); } - xml_attribute xml_node::first_attribute() const + PUGI__FN xml_attribute xml_node::first_attribute() const { return _root ? xml_attribute(_root->first_attribute) : xml_attribute(); } - xml_attribute xml_node::last_attribute() const + PUGI__FN xml_attribute xml_node::last_attribute() const { return _root && _root->first_attribute ? xml_attribute(_root->first_attribute->prev_attribute_c) : xml_attribute(); } - xml_node xml_node::first_child() const + PUGI__FN xml_node xml_node::first_child() const { return _root ? xml_node(_root->first_child) : xml_node(); } - xml_node xml_node::last_child() const + PUGI__FN xml_node xml_node::last_child() const { return _root && _root->first_child ? xml_node(_root->first_child->prev_sibling_c) : xml_node(); } - bool xml_node::set_name(const char_t* rhs) + PUGI__FN bool xml_node::set_name(const char_t* rhs) { switch (type()) { case node_pi: case node_declaration: case node_element: - return strcpy_insitu(_root->name, _root->header, xml_memory_page_name_allocated_mask, rhs); + return impl::strcpy_insitu(_root->name, _root->header, impl::xml_memory_page_name_allocated_mask, rhs); default: return false; } } - bool xml_node::set_value(const char_t* rhs) + PUGI__FN bool xml_node::set_value(const char_t* rhs) { switch (type()) { @@ -3764,106 +4916,73 @@ namespace pugi case node_cdata: case node_pcdata: case node_comment: - case node_doctype: - return strcpy_insitu(_root->value, _root->header, xml_memory_page_value_allocated_mask, rhs); + case node_doctype: + return impl::strcpy_insitu(_root->value, _root->header, impl::xml_memory_page_value_allocated_mask, rhs); default: return false; } } - xml_attribute xml_node::append_attribute(const char_t* name) + PUGI__FN xml_attribute xml_node::append_attribute(const char_t* name_) { - if (type() != node_element && type() != node_declaration) return xml_attribute(); + if (!impl::allow_insert_attribute(type())) return xml_attribute(); - xml_attribute a(append_attribute_ll(_root, get_allocator(_root))); - a.set_name(name); + xml_attribute a(impl::allocate_attribute(impl::get_allocator(_root))); + if (!a) return xml_attribute(); + + impl::append_attribute(a._attr, _root); + + a.set_name(name_); return a; } - xml_attribute xml_node::prepend_attribute(const char_t* name) + PUGI__FN xml_attribute xml_node::prepend_attribute(const char_t* name_) { - if (type() != node_element && type() != node_declaration) return xml_attribute(); + if (!impl::allow_insert_attribute(type())) return xml_attribute(); - xml_attribute a(allocate_attribute(get_allocator(_root))); + xml_attribute a(impl::allocate_attribute(impl::get_allocator(_root))); if (!a) return xml_attribute(); - a.set_name(name); - - xml_attribute_struct* head = _root->first_attribute; + impl::prepend_attribute(a._attr, _root); + + a.set_name(name_); - if (head) - { - a._attr->prev_attribute_c = head->prev_attribute_c; - head->prev_attribute_c = a._attr; - } - else - a._attr->prev_attribute_c = a._attr; - - a._attr->next_attribute = head; - _root->first_attribute = a._attr; - return a; } - xml_attribute xml_node::insert_attribute_before(const char_t* name, const xml_attribute& attr) + PUGI__FN xml_attribute xml_node::insert_attribute_after(const char_t* name_, const xml_attribute& attr) { - if ((type() != node_element && type() != node_declaration) || attr.empty()) return xml_attribute(); + if (!impl::allow_insert_attribute(type())) return xml_attribute(); + if (!attr || !impl::is_attribute_of(attr._attr, _root)) return xml_attribute(); - // check that attribute belongs to *this - xml_attribute_struct* cur = attr._attr; - - while (cur->prev_attribute_c->next_attribute) cur = cur->prev_attribute_c; - - if (cur != _root->first_attribute) return xml_attribute(); - - xml_attribute a(allocate_attribute(get_allocator(_root))); + xml_attribute a(impl::allocate_attribute(impl::get_allocator(_root))); if (!a) return xml_attribute(); - a.set_name(name); + impl::insert_attribute_after(a._attr, attr._attr, _root); + + a.set_name(name_); - if (attr._attr->prev_attribute_c->next_attribute) - attr._attr->prev_attribute_c->next_attribute = a._attr; - else - _root->first_attribute = a._attr; - - a._attr->prev_attribute_c = attr._attr->prev_attribute_c; - a._attr->next_attribute = attr._attr; - attr._attr->prev_attribute_c = a._attr; - return a; } - xml_attribute xml_node::insert_attribute_after(const char_t* name, const xml_attribute& attr) + PUGI__FN xml_attribute xml_node::insert_attribute_before(const char_t* name_, const xml_attribute& attr) { - if ((type() != node_element && type() != node_declaration) || attr.empty()) return xml_attribute(); + if (!impl::allow_insert_attribute(type())) return xml_attribute(); + if (!attr || !impl::is_attribute_of(attr._attr, _root)) return xml_attribute(); - // check that attribute belongs to *this - xml_attribute_struct* cur = attr._attr; - - while (cur->prev_attribute_c->next_attribute) cur = cur->prev_attribute_c; - - if (cur != _root->first_attribute) return xml_attribute(); - - xml_attribute a(allocate_attribute(get_allocator(_root))); + xml_attribute a(impl::allocate_attribute(impl::get_allocator(_root))); if (!a) return xml_attribute(); - a.set_name(name); + impl::insert_attribute_before(a._attr, attr._attr, _root); - if (attr._attr->next_attribute) - attr._attr->next_attribute->prev_attribute_c = a._attr; - else - _root->first_attribute->prev_attribute_c = a._attr; - - a._attr->next_attribute = attr._attr->next_attribute; - a._attr->prev_attribute_c = attr._attr; - attr._attr->next_attribute = a._attr; + a.set_name(name_); return a; } - xml_attribute xml_node::append_copy(const xml_attribute& proto) + PUGI__FN xml_attribute xml_node::append_copy(const xml_attribute& proto) { if (!proto) return xml_attribute(); @@ -3873,7 +4992,7 @@ namespace pugi return result; } - xml_attribute xml_node::prepend_copy(const xml_attribute& proto) + PUGI__FN xml_attribute xml_node::prepend_copy(const xml_attribute& proto) { if (!proto) return xml_attribute(); @@ -3883,7 +5002,7 @@ namespace pugi return result; } - xml_attribute xml_node::insert_copy_after(const xml_attribute& proto, const xml_attribute& attr) + PUGI__FN xml_attribute xml_node::insert_copy_after(const xml_attribute& proto, const xml_attribute& attr) { if (!proto) return xml_attribute(); @@ -3893,7 +5012,7 @@ namespace pugi return result; } - xml_attribute xml_node::insert_copy_before(const xml_attribute& proto, const xml_attribute& attr) + PUGI__FN xml_attribute xml_node::insert_copy_before(const xml_attribute& proto, const xml_attribute& attr) { if (!proto) return xml_attribute(); @@ -3903,246 +5022,315 @@ namespace pugi return result; } - xml_node xml_node::append_child(xml_node_type type) + PUGI__FN xml_node xml_node::append_child(xml_node_type type_) { - if (!allow_insert_child(this->type(), type)) return xml_node(); + if (!impl::allow_insert_child(type(), type_)) return xml_node(); - xml_node n(append_node(_root, get_allocator(_root), type)); + xml_node n(impl::allocate_node(impl::get_allocator(_root), type_)); + if (!n) return xml_node(); + + impl::append_node(n._root, _root); - if (type == node_declaration) n.set_name(PUGIXML_TEXT("xml")); + if (type_ == node_declaration) n.set_name(PUGIXML_TEXT("xml")); return n; } - xml_node xml_node::prepend_child(xml_node_type type) + PUGI__FN xml_node xml_node::prepend_child(xml_node_type type_) { - if (!allow_insert_child(this->type(), type)) return xml_node(); + if (!impl::allow_insert_child(type(), type_)) return xml_node(); - xml_node n(allocate_node(get_allocator(_root), type)); + xml_node n(impl::allocate_node(impl::get_allocator(_root), type_)); if (!n) return xml_node(); - n._root->parent = _root; - - xml_node_struct* head = _root->first_child; - - if (head) - { - n._root->prev_sibling_c = head->prev_sibling_c; - head->prev_sibling_c = n._root; - } - else - n._root->prev_sibling_c = n._root; - - n._root->next_sibling = head; - _root->first_child = n._root; + impl::prepend_node(n._root, _root); - if (type == node_declaration) n.set_name(PUGIXML_TEXT("xml")); + if (type_ == node_declaration) n.set_name(PUGIXML_TEXT("xml")); return n; } - xml_node xml_node::insert_child_before(xml_node_type type, const xml_node& node) + PUGI__FN xml_node xml_node::insert_child_before(xml_node_type type_, const xml_node& node) { - if (!allow_insert_child(this->type(), type)) return xml_node(); + if (!impl::allow_insert_child(type(), type_)) return xml_node(); if (!node._root || node._root->parent != _root) return xml_node(); - xml_node n(allocate_node(get_allocator(_root), type)); + xml_node n(impl::allocate_node(impl::get_allocator(_root), type_)); if (!n) return xml_node(); - n._root->parent = _root; - - if (node._root->prev_sibling_c->next_sibling) - node._root->prev_sibling_c->next_sibling = n._root; - else - _root->first_child = n._root; - - n._root->prev_sibling_c = node._root->prev_sibling_c; - n._root->next_sibling = node._root; - node._root->prev_sibling_c = n._root; + impl::insert_node_before(n._root, node._root); - if (type == node_declaration) n.set_name(PUGIXML_TEXT("xml")); + if (type_ == node_declaration) n.set_name(PUGIXML_TEXT("xml")); return n; } - xml_node xml_node::insert_child_after(xml_node_type type, const xml_node& node) + PUGI__FN xml_node xml_node::insert_child_after(xml_node_type type_, const xml_node& node) { - if (!allow_insert_child(this->type(), type)) return xml_node(); + if (!impl::allow_insert_child(type(), type_)) return xml_node(); if (!node._root || node._root->parent != _root) return xml_node(); - xml_node n(allocate_node(get_allocator(_root), type)); + xml_node n(impl::allocate_node(impl::get_allocator(_root), type_)); if (!n) return xml_node(); - n._root->parent = _root; - - if (node._root->next_sibling) - node._root->next_sibling->prev_sibling_c = n._root; - else - _root->first_child->prev_sibling_c = n._root; - - n._root->next_sibling = node._root->next_sibling; - n._root->prev_sibling_c = node._root; - node._root->next_sibling = n._root; + impl::insert_node_after(n._root, node._root); - if (type == node_declaration) n.set_name(PUGIXML_TEXT("xml")); + if (type_ == node_declaration) n.set_name(PUGIXML_TEXT("xml")); return n; } - xml_node xml_node::append_child(const char_t* name) - { - xml_node result = append_child(node_element); + PUGI__FN xml_node xml_node::append_child(const char_t* name_) + { + xml_node result = append_child(node_element); - result.set_name(name); + result.set_name(name_); - return result; - } + return result; + } - xml_node xml_node::prepend_child(const char_t* name) - { - xml_node result = prepend_child(node_element); + PUGI__FN xml_node xml_node::prepend_child(const char_t* name_) + { + xml_node result = prepend_child(node_element); - result.set_name(name); + result.set_name(name_); - return result; - } + return result; + } - xml_node xml_node::insert_child_after(const char_t* name, const xml_node& node) - { - xml_node result = insert_child_after(node_element, node); + PUGI__FN xml_node xml_node::insert_child_after(const char_t* name_, const xml_node& node) + { + xml_node result = insert_child_after(node_element, node); - result.set_name(name); + result.set_name(name_); - return result; - } + return result; + } - xml_node xml_node::insert_child_before(const char_t* name, const xml_node& node) - { - xml_node result = insert_child_before(node_element, node); + PUGI__FN xml_node xml_node::insert_child_before(const char_t* name_, const xml_node& node) + { + xml_node result = insert_child_before(node_element, node); - result.set_name(name); + result.set_name(name_); - return result; - } + return result; + } - xml_node xml_node::append_copy(const xml_node& proto) + PUGI__FN xml_node xml_node::append_copy(const xml_node& proto) { - xml_node result = append_child(proto.type()); + xml_node_type type_ = proto.type(); + if (!impl::allow_insert_child(type(), type_)) return xml_node(); - if (result) recursive_copy_skip(result, proto, result); + xml_node n(impl::allocate_node(impl::get_allocator(_root), type_)); + if (!n) return xml_node(); - return result; + impl::append_node(n._root, _root); + impl::node_copy_tree(n._root, proto._root); + + return n; } - xml_node xml_node::prepend_copy(const xml_node& proto) + PUGI__FN xml_node xml_node::prepend_copy(const xml_node& proto) { - xml_node result = prepend_child(proto.type()); + xml_node_type type_ = proto.type(); + if (!impl::allow_insert_child(type(), type_)) return xml_node(); - if (result) recursive_copy_skip(result, proto, result); + xml_node n(impl::allocate_node(impl::get_allocator(_root), type_)); + if (!n) return xml_node(); - return result; + impl::prepend_node(n._root, _root); + impl::node_copy_tree(n._root, proto._root); + + return n; } - xml_node xml_node::insert_copy_after(const xml_node& proto, const xml_node& node) + PUGI__FN xml_node xml_node::insert_copy_after(const xml_node& proto, const xml_node& node) { - xml_node result = insert_child_after(proto.type(), node); + xml_node_type type_ = proto.type(); + if (!impl::allow_insert_child(type(), type_)) return xml_node(); + if (!node._root || node._root->parent != _root) return xml_node(); + + xml_node n(impl::allocate_node(impl::get_allocator(_root), type_)); + if (!n) return xml_node(); - if (result) recursive_copy_skip(result, proto, result); + impl::insert_node_after(n._root, node._root); + impl::node_copy_tree(n._root, proto._root); - return result; + return n; } - xml_node xml_node::insert_copy_before(const xml_node& proto, const xml_node& node) + PUGI__FN xml_node xml_node::insert_copy_before(const xml_node& proto, const xml_node& node) { - xml_node result = insert_child_before(proto.type(), node); + xml_node_type type_ = proto.type(); + if (!impl::allow_insert_child(type(), type_)) return xml_node(); + if (!node._root || node._root->parent != _root) return xml_node(); - if (result) recursive_copy_skip(result, proto, result); + xml_node n(impl::allocate_node(impl::get_allocator(_root), type_)); + if (!n) return xml_node(); - return result; + impl::insert_node_before(n._root, node._root); + impl::node_copy_tree(n._root, proto._root); + + return n; } - bool xml_node::remove_attribute(const char_t* name) + PUGI__FN xml_node xml_node::append_move(const xml_node& moved) { - return remove_attribute(attribute(name)); + if (!impl::allow_move(*this, moved)) return xml_node(); + + // disable document_buffer_order optimization since moving nodes around changes document order without changing buffer pointers + impl::get_document(_root).header |= impl::xml_memory_page_contents_shared_mask; + + impl::remove_node(moved._root); + impl::append_node(moved._root, _root); + + return moved; } - bool xml_node::remove_attribute(const xml_attribute& a) + PUGI__FN xml_node xml_node::prepend_move(const xml_node& moved) { - if (!_root || !a._attr) return false; + if (!impl::allow_move(*this, moved)) return xml_node(); - // check that attribute belongs to *this - xml_attribute_struct* attr = a._attr; + // disable document_buffer_order optimization since moving nodes around changes document order without changing buffer pointers + impl::get_document(_root).header |= impl::xml_memory_page_contents_shared_mask; - while (attr->prev_attribute_c->next_attribute) attr = attr->prev_attribute_c; + impl::remove_node(moved._root); + impl::prepend_node(moved._root, _root); - if (attr != _root->first_attribute) return false; + return moved; + } - if (a._attr->next_attribute) a._attr->next_attribute->prev_attribute_c = a._attr->prev_attribute_c; - else if (_root->first_attribute) _root->first_attribute->prev_attribute_c = a._attr->prev_attribute_c; - - if (a._attr->prev_attribute_c->next_attribute) a._attr->prev_attribute_c->next_attribute = a._attr->next_attribute; - else _root->first_attribute = a._attr->next_attribute; + PUGI__FN xml_node xml_node::insert_move_after(const xml_node& moved, const xml_node& node) + { + if (!impl::allow_move(*this, moved)) return xml_node(); + if (!node._root || node._root->parent != _root) return xml_node(); + if (moved._root == node._root) return xml_node(); + + // disable document_buffer_order optimization since moving nodes around changes document order without changing buffer pointers + impl::get_document(_root).header |= impl::xml_memory_page_contents_shared_mask; + + impl::remove_node(moved._root); + impl::insert_node_after(moved._root, node._root); + + return moved; + } + + PUGI__FN xml_node xml_node::insert_move_before(const xml_node& moved, const xml_node& node) + { + if (!impl::allow_move(*this, moved)) return xml_node(); + if (!node._root || node._root->parent != _root) return xml_node(); + if (moved._root == node._root) return xml_node(); + + // disable document_buffer_order optimization since moving nodes around changes document order without changing buffer pointers + impl::get_document(_root).header |= impl::xml_memory_page_contents_shared_mask; - destroy_attribute(a._attr, get_allocator(_root)); + impl::remove_node(moved._root); + impl::insert_node_before(moved._root, node._root); + + return moved; + } + + PUGI__FN bool xml_node::remove_attribute(const char_t* name_) + { + return remove_attribute(attribute(name_)); + } + + PUGI__FN bool xml_node::remove_attribute(const xml_attribute& a) + { + if (!_root || !a._attr) return false; + if (!impl::is_attribute_of(a._attr, _root)) return false; + + impl::remove_attribute(a._attr, _root); + impl::destroy_attribute(a._attr, impl::get_allocator(_root)); return true; } - bool xml_node::remove_child(const char_t* name) + PUGI__FN bool xml_node::remove_child(const char_t* name_) { - return remove_child(child(name)); + return remove_child(child(name_)); } - bool xml_node::remove_child(const xml_node& n) + PUGI__FN bool xml_node::remove_child(const xml_node& n) { if (!_root || !n._root || n._root->parent != _root) return false; - if (n._root->next_sibling) n._root->next_sibling->prev_sibling_c = n._root->prev_sibling_c; - else if (_root->first_child) _root->first_child->prev_sibling_c = n._root->prev_sibling_c; - - if (n._root->prev_sibling_c->next_sibling) n._root->prev_sibling_c->next_sibling = n._root->next_sibling; - else _root->first_child = n._root->next_sibling; - - destroy_node(n._root, get_allocator(_root)); + impl::remove_node(n._root); + impl::destroy_node(n._root, impl::get_allocator(_root)); return true; } - xml_node xml_node::find_child_by_attribute(const char_t* name, const char_t* attr_name, const char_t* attr_value) const + PUGI__FN xml_parse_result xml_node::append_buffer(const void* contents, size_t size, unsigned int options, xml_encoding encoding) + { + // append_buffer is only valid for elements/documents + if (!impl::allow_insert_child(type(), node_element)) return impl::make_parse_result(status_append_invalid_root); + + // get document node + impl::xml_document_struct* doc = &impl::get_document(_root); + + // disable document_buffer_order optimization since in a document with multiple buffers comparing buffer pointers does not make sense + doc->header |= impl::xml_memory_page_contents_shared_mask; + + // get extra buffer element (we'll store the document fragment buffer there so that we can deallocate it later) + impl::xml_memory_page* page = 0; + impl::xml_extra_buffer* extra = static_cast(doc->allocate_memory(sizeof(impl::xml_extra_buffer), page)); + (void)page; + + if (!extra) return impl::make_parse_result(status_out_of_memory); + + // save name; name of the root has to be NULL before parsing - otherwise closing node mismatches will not be detected at the top level + char_t* rootname = _root->name; + _root->name = 0; + + // parse + char_t* buffer = 0; + xml_parse_result res = impl::load_buffer_impl(doc, _root, const_cast(contents), size, options, encoding, false, false, &buffer); + + // restore name + _root->name = rootname; + + // add extra buffer to the list + extra->buffer = buffer; + extra->next = doc->extra_buffers; + doc->extra_buffers = extra; + + return res; + } + + PUGI__FN xml_node xml_node::find_child_by_attribute(const char_t* name_, const char_t* attr_name, const char_t* attr_value) const { if (!_root) return xml_node(); for (xml_node_struct* i = _root->first_child; i; i = i->next_sibling) - if (i->name && strequal(name, i->name)) + if (i->name && impl::strequal(name_, i->name)) { for (xml_attribute_struct* a = i->first_attribute; a; a = a->next_attribute) - if (strequal(attr_name, a->name) && strequal(attr_value, a->value)) + if (a->name && impl::strequal(attr_name, a->name) && impl::strequal(attr_value, a->value ? a->value : PUGIXML_TEXT(""))) return xml_node(i); } return xml_node(); } - xml_node xml_node::find_child_by_attribute(const char_t* attr_name, const char_t* attr_value) const + PUGI__FN xml_node xml_node::find_child_by_attribute(const char_t* attr_name, const char_t* attr_value) const { if (!_root) return xml_node(); for (xml_node_struct* i = _root->first_child; i; i = i->next_sibling) for (xml_attribute_struct* a = i->first_attribute; a; a = a->next_attribute) - if (strequal(attr_name, a->name) && strequal(attr_value, a->value)) + if (a->name && impl::strequal(attr_name, a->name) && impl::strequal(attr_value, a->value ? a->value : PUGIXML_TEXT(""))) return xml_node(i); return xml_node(); } #ifndef PUGIXML_NO_STL - string_t xml_node::path(char_t delimiter) const + PUGI__FN string_t xml_node::path(char_t delimiter) const { - string_t path; - xml_node cursor = *this; // Make a copy. - path = cursor.name(); + string_t result = cursor.name(); while (cursor.parent()) { @@ -4150,28 +5338,28 @@ namespace pugi string_t temp = cursor.name(); temp += delimiter; - temp += path; - path.swap(temp); + temp += result; + result.swap(temp); } - return path; + return result; } #endif - xml_node xml_node::first_element_by_path(const char_t* path, char_t delimiter) const + PUGI__FN xml_node xml_node::first_element_by_path(const char_t* path_, char_t delimiter) const { xml_node found = *this; // Current search context. - if (!_root || !path || !path[0]) return found; + if (!_root || !path_ || !path_[0]) return found; - if (path[0] == delimiter) + if (path_[0] == delimiter) { // Absolute path; e.g. '/foo/bar' found = found.root(); - ++path; + ++path_; } - const char_t* path_segment = path; + const char_t* path_segment = path_; while (*path_segment == delimiter) ++path_segment; @@ -4193,7 +5381,7 @@ namespace pugi { for (xml_node_struct* j = found._root->first_child; j; j = j->next_sibling) { - if (j->name && strequalrange(j->name, path_segment, static_cast(path_segment_end - path_segment))) + if (j->name && impl::strequalrange(j->name, path_segment, static_cast(path_segment_end - path_segment))) { xml_node subsearch = xml_node(j).first_element_by_path(next_segment, delimiter); @@ -4205,7 +5393,7 @@ namespace pugi } } - bool xml_node::traverse(xml_tree_walker& walker) + PUGI__FN bool xml_node::traverse(xml_tree_walker& walker) { walker._depth = -1; @@ -4234,7 +5422,7 @@ namespace pugi else { // Borland C++ workaround - while (!cur.next_sibling() && cur != *this && (bool)cur.parent()) + while (!cur.next_sibling() && cur != *this && !cur.parent().empty()) { --walker._depth; cur = cur.parent(); @@ -4249,220 +5437,525 @@ namespace pugi assert(walker._depth == -1); - xml_node arg_end = *this; - return walker.end(arg_end); + xml_node arg_end = *this; + return walker.end(arg_end); + } + + PUGI__FN size_t xml_node::hash_value() const + { + return static_cast(reinterpret_cast(_root) / sizeof(xml_node_struct)); + } + + PUGI__FN xml_node_struct* xml_node::internal_object() const + { + return _root; + } + + PUGI__FN void xml_node::print(xml_writer& writer, const char_t* indent, unsigned int flags, xml_encoding encoding, unsigned int depth) const + { + if (!_root) return; + + impl::xml_buffered_writer buffered_writer(writer, encoding); + + impl::node_output(buffered_writer, _root, indent, flags, depth); + } + +#ifndef PUGIXML_NO_STL + PUGI__FN void xml_node::print(std::basic_ostream >& stream, const char_t* indent, unsigned int flags, xml_encoding encoding, unsigned int depth) const + { + xml_writer_stream writer(stream); + + print(writer, indent, flags, encoding, depth); + } + + PUGI__FN void xml_node::print(std::basic_ostream >& stream, const char_t* indent, unsigned int flags, unsigned int depth) const + { + xml_writer_stream writer(stream); + + print(writer, indent, flags, encoding_wchar, depth); + } +#endif + + PUGI__FN ptrdiff_t xml_node::offset_debug() const + { + if (!_root) return -1; + + impl::xml_document_struct& doc = impl::get_document(_root); + + // we can determine the offset reliably only if there is exactly once parse buffer + if (!doc.buffer || doc.extra_buffers) return -1; + + switch (type()) + { + case node_document: + return 0; + + case node_element: + case node_declaration: + case node_pi: + return _root->name && (_root->header & impl::xml_memory_page_name_allocated_or_shared_mask) == 0 ? _root->name - doc.buffer : -1; + + case node_pcdata: + case node_cdata: + case node_comment: + case node_doctype: + return _root->value && (_root->header & impl::xml_memory_page_value_allocated_or_shared_mask) == 0 ? _root->value - doc.buffer : -1; + + default: + return -1; + } + } + +#ifdef __BORLANDC__ + PUGI__FN bool operator&&(const xml_node& lhs, bool rhs) + { + return (bool)lhs && rhs; + } + + PUGI__FN bool operator||(const xml_node& lhs, bool rhs) + { + return (bool)lhs || rhs; + } +#endif + + PUGI__FN xml_text::xml_text(xml_node_struct* root): _root(root) + { + } + + PUGI__FN xml_node_struct* xml_text::_data() const + { + if (!_root || impl::is_text_node(_root)) return _root; + + for (xml_node_struct* node = _root->first_child; node; node = node->next_sibling) + if (impl::is_text_node(node)) + return node; + + return 0; + } + + PUGI__FN xml_node_struct* xml_text::_data_new() + { + xml_node_struct* d = _data(); + if (d) return d; + + return xml_node(_root).append_child(node_pcdata).internal_object(); + } + + PUGI__FN xml_text::xml_text(): _root(0) + { + } + + PUGI__FN static void unspecified_bool_xml_text(xml_text***) + { + } + + PUGI__FN xml_text::operator xml_text::unspecified_bool_type() const + { + return _data() ? unspecified_bool_xml_text : 0; + } + + PUGI__FN bool xml_text::operator!() const + { + return !_data(); + } + + PUGI__FN bool xml_text::empty() const + { + return _data() == 0; + } + + PUGI__FN const char_t* xml_text::get() const + { + xml_node_struct* d = _data(); + + return (d && d->value) ? d->value : PUGIXML_TEXT(""); + } + + PUGI__FN const char_t* xml_text::as_string(const char_t* def) const + { + xml_node_struct* d = _data(); + + return (d && d->value) ? d->value : def; + } + + PUGI__FN int xml_text::as_int(int def) const + { + xml_node_struct* d = _data(); + + return impl::get_value_int(d ? d->value : 0, def); + } + + PUGI__FN unsigned int xml_text::as_uint(unsigned int def) const + { + xml_node_struct* d = _data(); + + return impl::get_value_uint(d ? d->value : 0, def); + } + + PUGI__FN double xml_text::as_double(double def) const + { + xml_node_struct* d = _data(); + + return impl::get_value_double(d ? d->value : 0, def); + } + + PUGI__FN float xml_text::as_float(float def) const + { + xml_node_struct* d = _data(); + + return impl::get_value_float(d ? d->value : 0, def); + } + + PUGI__FN bool xml_text::as_bool(bool def) const + { + xml_node_struct* d = _data(); + + return impl::get_value_bool(d ? d->value : 0, def); + } + +#ifdef PUGIXML_HAS_LONG_LONG + PUGI__FN long long xml_text::as_llong(long long def) const + { + xml_node_struct* d = _data(); + + return impl::get_value_llong(d ? d->value : 0, def); + } + + PUGI__FN unsigned long long xml_text::as_ullong(unsigned long long def) const + { + xml_node_struct* d = _data(); + + return impl::get_value_ullong(d ? d->value : 0, def); + } +#endif + + PUGI__FN bool xml_text::set(const char_t* rhs) + { + xml_node_struct* dn = _data_new(); + + return dn ? impl::strcpy_insitu(dn->value, dn->header, impl::xml_memory_page_value_allocated_mask, rhs) : false; + } + + PUGI__FN bool xml_text::set(int rhs) + { + xml_node_struct* dn = _data_new(); + + return dn ? impl::set_value_convert(dn->value, dn->header, impl::xml_memory_page_value_allocated_mask, rhs) : false; } - size_t xml_node::hash_value() const - { - return static_cast(reinterpret_cast(_root) / sizeof(xml_node_struct)); - } + PUGI__FN bool xml_text::set(unsigned int rhs) + { + xml_node_struct* dn = _data_new(); + + return dn ? impl::set_value_convert(dn->value, dn->header, impl::xml_memory_page_value_allocated_mask, rhs) : false; + } - xml_node_struct* xml_node::internal_object() const + PUGI__FN bool xml_text::set(float rhs) { - return _root; + xml_node_struct* dn = _data_new(); + + return dn ? impl::set_value_convert(dn->value, dn->header, impl::xml_memory_page_value_allocated_mask, rhs) : false; } - void xml_node::print(xml_writer& writer, const char_t* indent, unsigned int flags, xml_encoding encoding, unsigned int depth) const + PUGI__FN bool xml_text::set(double rhs) { - if (!_root) return; + xml_node_struct* dn = _data_new(); - xml_buffered_writer buffered_writer(writer, encoding); + return dn ? impl::set_value_convert(dn->value, dn->header, impl::xml_memory_page_value_allocated_mask, rhs) : false; + } + + PUGI__FN bool xml_text::set(bool rhs) + { + xml_node_struct* dn = _data_new(); - node_output(buffered_writer, *this, indent, flags, depth); + return dn ? impl::set_value_convert(dn->value, dn->header, impl::xml_memory_page_value_allocated_mask, rhs) : false; } -#ifndef PUGIXML_NO_STL - void xml_node::print(std::basic_ostream >& stream, const char_t* indent, unsigned int flags, xml_encoding encoding, unsigned int depth) const +#ifdef PUGIXML_HAS_LONG_LONG + PUGI__FN bool xml_text::set(long long rhs) { - xml_writer_stream writer(stream); + xml_node_struct* dn = _data_new(); - print(writer, indent, flags, encoding, depth); + return dn ? impl::set_value_convert(dn->value, dn->header, impl::xml_memory_page_value_allocated_mask, rhs) : false; } - void xml_node::print(std::basic_ostream >& stream, const char_t* indent, unsigned int flags, unsigned int depth) const + PUGI__FN bool xml_text::set(unsigned long long rhs) { - xml_writer_stream writer(stream); + xml_node_struct* dn = _data_new(); - print(writer, indent, flags, encoding_wchar, depth); + return dn ? impl::set_value_convert(dn->value, dn->header, impl::xml_memory_page_value_allocated_mask, rhs) : false; } #endif - ptrdiff_t xml_node::offset_debug() const + PUGI__FN xml_text& xml_text::operator=(const char_t* rhs) { - xml_node_struct* r = root()._root; + set(rhs); + return *this; + } - if (!r) return -1; + PUGI__FN xml_text& xml_text::operator=(int rhs) + { + set(rhs); + return *this; + } - const char_t* buffer = static_cast(r)->buffer; + PUGI__FN xml_text& xml_text::operator=(unsigned int rhs) + { + set(rhs); + return *this; + } - if (!buffer) return -1; + PUGI__FN xml_text& xml_text::operator=(double rhs) + { + set(rhs); + return *this; + } - switch (type()) - { - case node_document: - return 0; + PUGI__FN xml_text& xml_text::operator=(float rhs) + { + set(rhs); + return *this; + } - case node_element: - case node_declaration: - case node_pi: - return (_root->header & xml_memory_page_name_allocated_mask) ? -1 : _root->name - buffer; + PUGI__FN xml_text& xml_text::operator=(bool rhs) + { + set(rhs); + return *this; + } - case node_pcdata: - case node_cdata: - case node_comment: - case node_doctype: - return (_root->header & xml_memory_page_value_allocated_mask) ? -1 : _root->value - buffer; +#ifdef PUGIXML_HAS_LONG_LONG + PUGI__FN xml_text& xml_text::operator=(long long rhs) + { + set(rhs); + return *this; + } - default: - return -1; - } + PUGI__FN xml_text& xml_text::operator=(unsigned long long rhs) + { + set(rhs); + return *this; + } +#endif + + PUGI__FN xml_node xml_text::data() const + { + return xml_node(_data()); } #ifdef __BORLANDC__ - bool operator&&(const xml_node& lhs, bool rhs) + PUGI__FN bool operator&&(const xml_text& lhs, bool rhs) { return (bool)lhs && rhs; } - bool operator||(const xml_node& lhs, bool rhs) + PUGI__FN bool operator||(const xml_text& lhs, bool rhs) { return (bool)lhs || rhs; } #endif - xml_node_iterator::xml_node_iterator() + PUGI__FN xml_node_iterator::xml_node_iterator() { } - xml_node_iterator::xml_node_iterator(const xml_node& node): _wrap(node), _parent(node.parent()) + PUGI__FN xml_node_iterator::xml_node_iterator(const xml_node& node): _wrap(node), _parent(node.parent()) { } - xml_node_iterator::xml_node_iterator(xml_node_struct* ref, xml_node_struct* parent): _wrap(ref), _parent(parent) + PUGI__FN xml_node_iterator::xml_node_iterator(xml_node_struct* ref, xml_node_struct* parent): _wrap(ref), _parent(parent) { } - bool xml_node_iterator::operator==(const xml_node_iterator& rhs) const + PUGI__FN bool xml_node_iterator::operator==(const xml_node_iterator& rhs) const { return _wrap._root == rhs._wrap._root && _parent._root == rhs._parent._root; } - bool xml_node_iterator::operator!=(const xml_node_iterator& rhs) const + PUGI__FN bool xml_node_iterator::operator!=(const xml_node_iterator& rhs) const { return _wrap._root != rhs._wrap._root || _parent._root != rhs._parent._root; } - xml_node& xml_node_iterator::operator*() + PUGI__FN xml_node& xml_node_iterator::operator*() const { assert(_wrap._root); return _wrap; } - xml_node* xml_node_iterator::operator->() + PUGI__FN xml_node* xml_node_iterator::operator->() const { assert(_wrap._root); - return &_wrap; + return const_cast(&_wrap); // BCC32 workaround } - const xml_node_iterator& xml_node_iterator::operator++() + PUGI__FN const xml_node_iterator& xml_node_iterator::operator++() { assert(_wrap._root); _wrap._root = _wrap._root->next_sibling; return *this; } - xml_node_iterator xml_node_iterator::operator++(int) + PUGI__FN xml_node_iterator xml_node_iterator::operator++(int) { xml_node_iterator temp = *this; ++*this; return temp; } - const xml_node_iterator& xml_node_iterator::operator--() + PUGI__FN const xml_node_iterator& xml_node_iterator::operator--() { _wrap = _wrap._root ? _wrap.previous_sibling() : _parent.last_child(); return *this; } - xml_node_iterator xml_node_iterator::operator--(int) + PUGI__FN xml_node_iterator xml_node_iterator::operator--(int) { xml_node_iterator temp = *this; --*this; return temp; } - xml_attribute_iterator::xml_attribute_iterator() + PUGI__FN xml_attribute_iterator::xml_attribute_iterator() { } - xml_attribute_iterator::xml_attribute_iterator(const xml_attribute& attr, const xml_node& parent): _wrap(attr), _parent(parent) + PUGI__FN xml_attribute_iterator::xml_attribute_iterator(const xml_attribute& attr, const xml_node& parent): _wrap(attr), _parent(parent) { } - xml_attribute_iterator::xml_attribute_iterator(xml_attribute_struct* ref, xml_node_struct* parent): _wrap(ref), _parent(parent) + PUGI__FN xml_attribute_iterator::xml_attribute_iterator(xml_attribute_struct* ref, xml_node_struct* parent): _wrap(ref), _parent(parent) { } - bool xml_attribute_iterator::operator==(const xml_attribute_iterator& rhs) const + PUGI__FN bool xml_attribute_iterator::operator==(const xml_attribute_iterator& rhs) const { return _wrap._attr == rhs._wrap._attr && _parent._root == rhs._parent._root; } - bool xml_attribute_iterator::operator!=(const xml_attribute_iterator& rhs) const + PUGI__FN bool xml_attribute_iterator::operator!=(const xml_attribute_iterator& rhs) const { return _wrap._attr != rhs._wrap._attr || _parent._root != rhs._parent._root; } - xml_attribute& xml_attribute_iterator::operator*() + PUGI__FN xml_attribute& xml_attribute_iterator::operator*() const { assert(_wrap._attr); return _wrap; } - xml_attribute* xml_attribute_iterator::operator->() + PUGI__FN xml_attribute* xml_attribute_iterator::operator->() const { assert(_wrap._attr); - return &_wrap; + return const_cast(&_wrap); // BCC32 workaround } - const xml_attribute_iterator& xml_attribute_iterator::operator++() + PUGI__FN const xml_attribute_iterator& xml_attribute_iterator::operator++() { assert(_wrap._attr); _wrap._attr = _wrap._attr->next_attribute; return *this; } - xml_attribute_iterator xml_attribute_iterator::operator++(int) + PUGI__FN xml_attribute_iterator xml_attribute_iterator::operator++(int) { xml_attribute_iterator temp = *this; ++*this; return temp; } - const xml_attribute_iterator& xml_attribute_iterator::operator--() + PUGI__FN const xml_attribute_iterator& xml_attribute_iterator::operator--() { _wrap = _wrap._attr ? _wrap.previous_attribute() : _parent.last_attribute(); return *this; } - xml_attribute_iterator xml_attribute_iterator::operator--(int) + PUGI__FN xml_attribute_iterator xml_attribute_iterator::operator--(int) { xml_attribute_iterator temp = *this; --*this; return temp; } - xml_parse_result::xml_parse_result(): status(status_internal_error), offset(0), encoding(encoding_auto) - { - } + PUGI__FN xml_named_node_iterator::xml_named_node_iterator(): _name(0) + { + } + + PUGI__FN xml_named_node_iterator::xml_named_node_iterator(const xml_node& node, const char_t* name): _wrap(node), _parent(node.parent()), _name(name) + { + } + + PUGI__FN xml_named_node_iterator::xml_named_node_iterator(xml_node_struct* ref, xml_node_struct* parent, const char_t* name): _wrap(ref), _parent(parent), _name(name) + { + } + + PUGI__FN bool xml_named_node_iterator::operator==(const xml_named_node_iterator& rhs) const + { + return _wrap._root == rhs._wrap._root && _parent._root == rhs._parent._root; + } + + PUGI__FN bool xml_named_node_iterator::operator!=(const xml_named_node_iterator& rhs) const + { + return _wrap._root != rhs._wrap._root || _parent._root != rhs._parent._root; + } + + PUGI__FN xml_node& xml_named_node_iterator::operator*() const + { + assert(_wrap._root); + return _wrap; + } + + PUGI__FN xml_node* xml_named_node_iterator::operator->() const + { + assert(_wrap._root); + return const_cast(&_wrap); // BCC32 workaround + } + + PUGI__FN const xml_named_node_iterator& xml_named_node_iterator::operator++() + { + assert(_wrap._root); + _wrap = _wrap.next_sibling(_name); + return *this; + } + + PUGI__FN xml_named_node_iterator xml_named_node_iterator::operator++(int) + { + xml_named_node_iterator temp = *this; + ++*this; + return temp; + } + + PUGI__FN const xml_named_node_iterator& xml_named_node_iterator::operator--() + { + if (_wrap._root) + _wrap = _wrap.previous_sibling(_name); + else + { + _wrap = _parent.last_child(); + + if (!impl::strequal(_wrap.name(), _name)) + _wrap = _wrap.previous_sibling(_name); + } + + return *this; + } + + PUGI__FN xml_named_node_iterator xml_named_node_iterator::operator--(int) + { + xml_named_node_iterator temp = *this; + --*this; + return temp; + } + + PUGI__FN xml_parse_result::xml_parse_result(): status(status_internal_error), offset(0), encoding(encoding_auto) + { + } - xml_parse_result::operator bool() const - { - return status == status_ok; - } + PUGI__FN xml_parse_result::operator bool() const + { + return status == status_ok; + } - const char* xml_parse_result::description() const + PUGI__FN const char* xml_parse_result::description() const { switch (status) { @@ -4485,106 +5978,116 @@ namespace pugi case status_bad_end_element: return "Error parsing end element tag"; case status_end_element_mismatch: return "Start-end tags mismatch"; + case status_append_invalid_root: return "Unable to append nodes: root is not an element or document"; + + case status_no_document_element: return "No document element found"; + default: return "Unknown error"; } } - xml_document::xml_document(): _buffer(0) + PUGI__FN xml_document::xml_document(): _buffer(0) { create(); } - xml_document::~xml_document() + PUGI__FN xml_document::~xml_document() { destroy(); } - void xml_document::reset() + PUGI__FN void xml_document::reset() { destroy(); create(); } - void xml_document::reset(const xml_document& proto) - { - reset(); + PUGI__FN void xml_document::reset(const xml_document& proto) + { + reset(); - for (xml_node cur = proto.first_child(); cur; cur = cur.next_sibling()) - append_copy(cur); - } + for (xml_node cur = proto.first_child(); cur; cur = cur.next_sibling()) + append_copy(cur); + } - void xml_document::create() + PUGI__FN void xml_document::create() { + assert(!_root); + // initialize sentinel page - STATIC_ASSERT(offsetof(xml_memory_page, data) + sizeof(xml_document_struct) + xml_memory_page_alignment <= sizeof(_memory)); + PUGI__STATIC_ASSERT(sizeof(impl::xml_memory_page) + sizeof(impl::xml_document_struct) + impl::xml_memory_page_alignment - sizeof(void*) <= sizeof(_memory)); // align upwards to page boundary - void* page_memory = reinterpret_cast((reinterpret_cast(_memory) + (xml_memory_page_alignment - 1)) & ~(xml_memory_page_alignment - 1)); + void* page_memory = reinterpret_cast((reinterpret_cast(_memory) + (impl::xml_memory_page_alignment - 1)) & ~(impl::xml_memory_page_alignment - 1)); // prepare page structure - xml_memory_page* page = xml_memory_page::construct(page_memory); + impl::xml_memory_page* page = impl::xml_memory_page::construct(page_memory); + assert(page); - page->busy_size = xml_memory_page_size; + page->busy_size = impl::xml_memory_page_size; // allocate new root - _root = new (page->data) xml_document_struct(page); + _root = new (reinterpret_cast(page) + sizeof(impl::xml_memory_page)) impl::xml_document_struct(page); _root->prev_sibling_c = _root; // setup sentinel page - page->allocator = static_cast(_root); + page->allocator = static_cast(_root); + + // verify the document allocation + assert(reinterpret_cast(_root) + sizeof(impl::xml_document_struct) <= _memory + sizeof(_memory)); } - void xml_document::destroy() + PUGI__FN void xml_document::destroy() { + assert(_root); + // destroy static storage if (_buffer) { - global_deallocate(_buffer); + impl::xml_memory::deallocate(_buffer); _buffer = 0; } - // destroy dynamic storage, leave sentinel page (it's in static memory) - if (_root) + // destroy extra buffers (note: no need to destroy linked list nodes, they're allocated using document allocator) + for (impl::xml_extra_buffer* extra = static_cast(_root)->extra_buffers; extra; extra = extra->next) { - xml_memory_page* root_page = reinterpret_cast(_root->header & xml_memory_page_pointer_mask); - assert(root_page && !root_page->prev && !root_page->memory); - - // destroy all pages - for (xml_memory_page* page = root_page->next; page; ) - { - xml_memory_page* next = page->next; + if (extra->buffer) impl::xml_memory::deallocate(extra->buffer); + } - xml_allocator::deallocate_page(page); + // destroy dynamic storage, leave sentinel page (it's in static memory) + impl::xml_memory_page* root_page = reinterpret_cast(_root->header & impl::xml_memory_page_pointer_mask); + assert(root_page && !root_page->prev); + assert(reinterpret_cast(root_page) >= _memory && reinterpret_cast(root_page) < _memory + sizeof(_memory)); - page = next; - } + for (impl::xml_memory_page* page = root_page->next; page; ) + { + impl::xml_memory_page* next = page->next; - // cleanup root page - root_page->allocator = 0; - root_page->next = 0; - root_page->busy_size = root_page->freed_size = 0; + impl::xml_allocator::deallocate_page(page); - _root = 0; + page = next; } + + _root = 0; } #ifndef PUGIXML_NO_STL - xml_parse_result xml_document::load(std::basic_istream >& stream, unsigned int options, xml_encoding encoding) + PUGI__FN xml_parse_result xml_document::load(std::basic_istream >& stream, unsigned int options, xml_encoding encoding) { reset(); - return load_stream_impl(*this, stream, options, encoding); + return impl::load_stream_impl(*this, stream, options, encoding); } - xml_parse_result xml_document::load(std::basic_istream >& stream, unsigned int options) + PUGI__FN xml_parse_result xml_document::load(std::basic_istream >& stream, unsigned int options) { reset(); - return load_stream_impl(*this, stream, options, encoding_wchar); + return impl::load_stream_impl(*this, stream, options, encoding_wchar); } #endif - xml_parse_result xml_document::load(const char_t* contents, unsigned int options) + PUGI__FN xml_parse_result xml_document::load_string(const char_t* contents, unsigned int options) { // Force native encoding (skip autodetection) #ifdef PUGIXML_WCHAR_MODE @@ -4593,97 +6096,88 @@ namespace pugi xml_encoding encoding = encoding_utf8; #endif - return load_buffer(contents, strlength(contents) * sizeof(char_t), options, encoding); + return load_buffer(contents, impl::strlength(contents) * sizeof(char_t), options, encoding); } - xml_parse_result xml_document::load_file(const char* path, unsigned int options, xml_encoding encoding) + PUGI__FN xml_parse_result xml_document::load(const char_t* contents, unsigned int options) { - reset(); - - FILE* file = fopen(path, "rb"); - - return load_file_impl(*this, file, options, encoding); + return load_string(contents, options); } - xml_parse_result xml_document::load_file(const wchar_t* path, unsigned int options, xml_encoding encoding) + PUGI__FN xml_parse_result xml_document::load_file(const char* path_, unsigned int options, xml_encoding encoding) { reset(); - FILE* file = open_file_wide(path, L"rb"); + FILE* file = fopen(path_, "rb"); - return load_file_impl(*this, file, options, encoding); + return impl::load_file_impl(*this, file, options, encoding); } - xml_parse_result xml_document::load_buffer_impl(void* contents, size_t size, unsigned int options, xml_encoding encoding, bool is_mutable, bool own) + PUGI__FN xml_parse_result xml_document::load_file(const wchar_t* path_, unsigned int options, xml_encoding encoding) { reset(); - // check input buffer - assert(contents || size == 0); - - // get actual encoding - xml_encoding buffer_encoding = get_buffer_encoding(encoding, contents, size); - - // get private buffer - char_t* buffer = 0; - size_t length = 0; - - if (!convert_buffer(buffer, length, buffer_encoding, contents, size, is_mutable)) return make_parse_result(status_out_of_memory); - - // delete original buffer if we performed a conversion - if (own && buffer != contents && contents) global_deallocate(contents); - - // parse - xml_parse_result res = xml_parser::parse(buffer, length, _root, options); - - // remember encoding - res.encoding = buffer_encoding; - - // grab onto buffer if it's our buffer, user is responsible for deallocating contens himself - if (own || buffer != contents) _buffer = buffer; + FILE* file = impl::open_file_wide(path_, L"rb"); - return res; + return impl::load_file_impl(*this, file, options, encoding); } - xml_parse_result xml_document::load_buffer(const void* contents, size_t size, unsigned int options, xml_encoding encoding) + PUGI__FN xml_parse_result xml_document::load_buffer(const void* contents, size_t size, unsigned int options, xml_encoding encoding) { - return load_buffer_impl(const_cast(contents), size, options, encoding, false, false); + reset(); + + return impl::load_buffer_impl(static_cast(_root), _root, const_cast(contents), size, options, encoding, false, false, &_buffer); } - xml_parse_result xml_document::load_buffer_inplace(void* contents, size_t size, unsigned int options, xml_encoding encoding) + PUGI__FN xml_parse_result xml_document::load_buffer_inplace(void* contents, size_t size, unsigned int options, xml_encoding encoding) { - return load_buffer_impl(contents, size, options, encoding, true, false); + reset(); + + return impl::load_buffer_impl(static_cast(_root), _root, contents, size, options, encoding, true, false, &_buffer); } - - xml_parse_result xml_document::load_buffer_inplace_own(void* contents, size_t size, unsigned int options, xml_encoding encoding) + + PUGI__FN xml_parse_result xml_document::load_buffer_inplace_own(void* contents, size_t size, unsigned int options, xml_encoding encoding) { - return load_buffer_impl(contents, size, options, encoding, true, true); + reset(); + + return impl::load_buffer_impl(static_cast(_root), _root, contents, size, options, encoding, true, true, &_buffer); } - void xml_document::save(xml_writer& writer, const char_t* indent, unsigned int flags, xml_encoding encoding) const + PUGI__FN void xml_document::save(xml_writer& writer, const char_t* indent, unsigned int flags, xml_encoding encoding) const { - if (flags & format_write_bom) write_bom(writer, get_write_encoding(encoding)); + impl::xml_buffered_writer buffered_writer(writer, encoding); - xml_buffered_writer buffered_writer(writer, encoding); + if ((flags & format_write_bom) && encoding != encoding_latin1) + { + // BOM always represents the codepoint U+FEFF, so just write it in native encoding + #ifdef PUGIXML_WCHAR_MODE + unsigned int bom = 0xfeff; + buffered_writer.write(static_cast(bom)); + #else + buffered_writer.write('\xef', '\xbb', '\xbf'); + #endif + } - if (!(flags & format_no_declaration) && !has_declaration(*this)) + if (!(flags & format_no_declaration) && !impl::has_declaration(_root)) { - buffered_writer.write(PUGIXML_TEXT("")); + buffered_writer.write_string(PUGIXML_TEXT("'); if (!(flags & format_raw)) buffered_writer.write('\n'); } - node_output(buffered_writer, *this, indent, flags, 0); + impl::node_output(buffered_writer, _root, indent, flags, 0); } #ifndef PUGIXML_NO_STL - void xml_document::save(std::basic_ostream >& stream, const char_t* indent, unsigned int flags, xml_encoding encoding) const + PUGI__FN void xml_document::save(std::basic_ostream >& stream, const char_t* indent, unsigned int flags, xml_encoding encoding) const { xml_writer_stream writer(stream); save(writer, indent, flags, encoding); } - void xml_document::save(std::basic_ostream >& stream, const char_t* indent, unsigned int flags) const + PUGI__FN void xml_document::save(std::basic_ostream >& stream, const char_t* indent, unsigned int flags) const { xml_writer_stream writer(stream); @@ -4691,94 +6185,87 @@ namespace pugi } #endif - bool xml_document::save_file(const char* path, const char_t* indent, unsigned int flags, xml_encoding encoding) const + PUGI__FN bool xml_document::save_file(const char* path_, const char_t* indent, unsigned int flags, xml_encoding encoding) const { - FILE* file = fopen(path, "wb"); - if (!file) return false; - - xml_writer_file writer(file); - save(writer, indent, flags, encoding); - - fclose(file); - - return true; + FILE* file = fopen(path_, (flags & format_save_file_text) ? "w" : "wb"); + return impl::save_file_impl(*this, file, indent, flags, encoding); } - bool xml_document::save_file(const wchar_t* path, const char_t* indent, unsigned int flags, xml_encoding encoding) const + PUGI__FN bool xml_document::save_file(const wchar_t* path_, const char_t* indent, unsigned int flags, xml_encoding encoding) const { - FILE* file = open_file_wide(path, L"wb"); - if (!file) return false; - - xml_writer_file writer(file); - save(writer, indent, flags, encoding); - - fclose(file); - - return true; + FILE* file = impl::open_file_wide(path_, (flags & format_save_file_text) ? L"w" : L"wb"); + return impl::save_file_impl(*this, file, indent, flags, encoding); } - xml_node xml_document::document_element() const - { + PUGI__FN xml_node xml_document::document_element() const + { + assert(_root); + for (xml_node_struct* i = _root->first_child; i; i = i->next_sibling) - if ((i->header & xml_memory_page_type_mask) + 1 == node_element) - return xml_node(i); + if (PUGI__NODETYPE(i) == node_element) + return xml_node(i); - return xml_node(); - } + return xml_node(); + } #ifndef PUGIXML_NO_STL - std::string PUGIXML_FUNCTION as_utf8(const wchar_t* str) + PUGI__FN std::string PUGIXML_FUNCTION as_utf8(const wchar_t* str) { assert(str); - return as_utf8_impl(str, wcslen(str)); + return impl::as_utf8_impl(str, impl::strlength_wide(str)); } - std::string PUGIXML_FUNCTION as_utf8(const std::wstring& str) + PUGI__FN std::string PUGIXML_FUNCTION as_utf8(const std::basic_string& str) { - return as_utf8_impl(str.c_str(), str.size()); + return impl::as_utf8_impl(str.c_str(), str.size()); } - std::wstring PUGIXML_FUNCTION as_wide(const char* str) + PUGI__FN std::basic_string PUGIXML_FUNCTION as_wide(const char* str) { assert(str); - return as_wide_impl(str, strlen(str)); + return impl::as_wide_impl(str, strlen(str)); } - std::wstring PUGIXML_FUNCTION as_wide(const std::string& str) + PUGI__FN std::basic_string PUGIXML_FUNCTION as_wide(const std::string& str) { - return as_wide_impl(str.c_str(), str.size()); + return impl::as_wide_impl(str.c_str(), str.size()); } #endif - void PUGIXML_FUNCTION set_memory_management_functions(allocation_function allocate, deallocation_function deallocate) - { - global_allocate = allocate; - global_deallocate = deallocate; - } - - allocation_function PUGIXML_FUNCTION get_memory_allocation_function() - { - return global_allocate; - } - - deallocation_function PUGIXML_FUNCTION get_memory_deallocation_function() - { - return global_deallocate; - } + PUGI__FN void PUGIXML_FUNCTION set_memory_management_functions(allocation_function allocate, deallocation_function deallocate) + { + impl::xml_memory::allocate = allocate; + impl::xml_memory::deallocate = deallocate; + } + + PUGI__FN allocation_function PUGIXML_FUNCTION get_memory_allocation_function() + { + return impl::xml_memory::allocate; + } + + PUGI__FN deallocation_function PUGIXML_FUNCTION get_memory_deallocation_function() + { + return impl::xml_memory::deallocate; + } } #if !defined(PUGIXML_NO_STL) && (defined(_MSC_VER) || defined(__ICC)) namespace std { // Workarounds for (non-standard) iterator category detection for older versions (MSVC7/IC8 and earlier) - std::bidirectional_iterator_tag _Iter_cat(const xml_node_iterator&) + PUGI__FN std::bidirectional_iterator_tag _Iter_cat(const pugi::xml_node_iterator&) + { + return std::bidirectional_iterator_tag(); + } + + PUGI__FN std::bidirectional_iterator_tag _Iter_cat(const pugi::xml_attribute_iterator&) { return std::bidirectional_iterator_tag(); } - std::bidirectional_iterator_tag _Iter_cat(const xml_attribute_iterator&) + PUGI__FN std::bidirectional_iterator_tag _Iter_cat(const pugi::xml_named_node_iterator&) { return std::bidirectional_iterator_tag(); } @@ -4789,12 +6276,17 @@ namespace std namespace std { // Workarounds for (non-standard) iterator category detection - std::bidirectional_iterator_tag __iterator_category(const xml_node_iterator&) + PUGI__FN std::bidirectional_iterator_tag __iterator_category(const pugi::xml_node_iterator&) + { + return std::bidirectional_iterator_tag(); + } + + PUGI__FN std::bidirectional_iterator_tag __iterator_category(const pugi::xml_attribute_iterator&) { return std::bidirectional_iterator_tag(); } - std::bidirectional_iterator_tag __iterator_category(const xml_attribute_iterator&) + PUGI__FN std::bidirectional_iterator_tag __iterator_category(const pugi::xml_named_node_iterator&) { return std::bidirectional_iterator_tag(); } @@ -4802,10 +6294,8 @@ namespace std #endif #ifndef PUGIXML_NO_XPATH - // STL replacements -namespace -{ +PUGI__NS_BEGIN struct equal_to { template bool operator()(const T& lhs, const T& rhs) const @@ -4858,13 +6348,13 @@ namespace template void reverse(I begin, I end) { - while (begin + 1 < end) swap(*begin++, *--end); + while (end - begin > 1) swap(*begin++, *--end); } template I unique(I begin, I end) { // fast skip head - while (begin + 1 < end && *begin != *(begin + 1)) begin++; + while (end - begin > 1 && *begin != *(begin + 1)) begin++; if (begin == end) return begin; @@ -5029,16 +6519,22 @@ namespace // insertion sort small chunk if (begin != end) insertion_sort(begin, end, pred, &*begin); } -} +PUGI__NS_END // Allocator used for AST and evaluation stacks -namespace -{ +PUGI__NS_BEGIN struct xpath_memory_block { xpath_memory_block* next; + size_t capacity; - char data[4096]; + char data[ + #ifdef PUGIXML_MEMORY_XPATH_PAGE_SIZE + PUGIXML_MEMORY_XPATH_PAGE_SIZE + #else + 4096 + #endif + ]; }; class xpath_allocator @@ -5060,12 +6556,10 @@ namespace void* allocate_nothrow(size_t size) { - const size_t block_capacity = sizeof(_root->data); - // align size so that we're able to store pointers in subsequent blocks size = (size + sizeof(void*) - 1) & ~(sizeof(void*) - 1); - if (_root_size + size <= block_capacity) + if (_root_size + size <= _root->capacity) { void* buf = _root->data + _root_size; _root_size += size; @@ -5073,13 +6567,18 @@ namespace } else { - size_t block_data_size = (size > block_capacity) ? size : block_capacity; - size_t block_size = block_data_size + offsetof(xpath_memory_block, data); + // make sure we have at least 1/4th of the page free after allocation to satisfy subsequent allocation requests + size_t block_capacity_base = sizeof(_root->data); + size_t block_capacity_req = size + block_capacity_base / 4; + size_t block_capacity = (block_capacity_base > block_capacity_req) ? block_capacity_base : block_capacity_req; + + size_t block_size = block_capacity + offsetof(xpath_memory_block, data); - xpath_memory_block* block = static_cast(global_allocate(block_size)); + xpath_memory_block* block = static_cast(xml_memory::allocate(block_size)); if (!block) return 0; block->next = _root; + block->capacity = block_capacity; _root = block; _root_size = size; @@ -5127,7 +6626,7 @@ namespace if (result != ptr && ptr) { // copy old data - assert(new_size > old_size); + assert(new_size >= old_size); memcpy(result, ptr, old_size); // free the previous page if it had no other objects @@ -5141,7 +6640,7 @@ namespace if (next) { // deallocate the whole page, unless it was the first one - global_deallocate(_root->next); + xml_memory::deallocate(_root->next); _root->next = next; } } @@ -5159,7 +6658,7 @@ namespace { xpath_memory_block* next = cur->next; - global_deallocate(cur); + xml_memory::deallocate(cur); cur = next; } @@ -5178,7 +6677,7 @@ namespace { xpath_memory_block* next = cur->next; - global_deallocate(cur); + xml_memory::deallocate(cur); cur = next; } @@ -5220,6 +6719,7 @@ namespace xpath_stack_data(): result(blocks + 0), temp(blocks + 1) { blocks[0].next = blocks[1].next = 0; + blocks[0].capacity = blocks[1].capacity = sizeof(blocks[0].data); stack.result = &result; stack.temp = &temp; @@ -5235,15 +6735,15 @@ namespace temp.release(); } }; -} +PUGI__NS_END // String class -namespace -{ +PUGI__NS_BEGIN class xpath_string { const char_t* _buffer; bool _uses_heap; + size_t _length_heap; static char_t* duplicate_string(const char_t* string, size_t length, xpath_allocator* alloc) { @@ -5256,36 +6756,34 @@ namespace return result; } - static char_t* duplicate_string(const char_t* string, xpath_allocator* alloc) + xpath_string(const char_t* buffer, bool uses_heap_, size_t length_heap): _buffer(buffer), _uses_heap(uses_heap_), _length_heap(length_heap) { - return duplicate_string(string, strlength(string), alloc); } public: - xpath_string(): _buffer(PUGIXML_TEXT("")), _uses_heap(false) + static xpath_string from_const(const char_t* str) { + return xpath_string(str, false, 0); } - explicit xpath_string(const char_t* str, xpath_allocator* alloc) + static xpath_string from_heap_preallocated(const char_t* begin, const char_t* end) { - bool empty = (*str == 0); + assert(begin <= end && *end == 0); - _buffer = empty ? PUGIXML_TEXT("") : duplicate_string(str, alloc); - _uses_heap = !empty; + return xpath_string(begin, true, static_cast(end - begin)); } - explicit xpath_string(const char_t* str, bool use_heap): _buffer(str), _uses_heap(use_heap) - { - } - - xpath_string(const char_t* begin, const char_t* end, xpath_allocator* alloc) + static xpath_string from_heap(const char_t* begin, const char_t* end, xpath_allocator* alloc) { assert(begin <= end); - bool empty = (begin == end); + size_t length = static_cast(end - begin); + + return length == 0 ? xpath_string() : xpath_string(duplicate_string(begin, length, alloc), true, length); + } - _buffer = empty ? PUGIXML_TEXT("") : duplicate_string(begin, static_cast(end - begin), alloc); - _uses_heap = !empty; + xpath_string(): _buffer(PUGIXML_TEXT("")), _uses_heap(false), _length_heap(0) + { } void append(const xpath_string& o, xpath_allocator* alloc) @@ -5301,12 +6799,12 @@ namespace else { // need to make heap copy - size_t target_length = strlength(_buffer); - size_t source_length = strlength(o._buffer); - size_t length = target_length + source_length; + size_t target_length = length(); + size_t source_length = o.length(); + size_t result_length = target_length + source_length; // allocate new buffer - char_t* result = static_cast(alloc->reallocate(_uses_heap ? const_cast(_buffer) : 0, (target_length + 1) * sizeof(char_t), (length + 1) * sizeof(char_t))); + char_t* result = static_cast(alloc->reallocate(_uses_heap ? const_cast(_buffer) : 0, (target_length + 1) * sizeof(char_t), (result_length + 1) * sizeof(char_t))); assert(result); // append first string to the new buffer in case there was no reallocation @@ -5314,11 +6812,12 @@ namespace // append second string to the new buffer memcpy(result + target_length, o._buffer, source_length * sizeof(char_t)); - result[length] = 0; + result[result_length] = 0; // finalize _buffer = result; _uses_heap = true; + _length_heap = result_length; } } @@ -5329,7 +6828,7 @@ namespace size_t length() const { - return strlength(_buffer); + return _uses_heap ? _length_heap : strlength(_buffer); } char_t* data(xpath_allocator* alloc) @@ -5337,8 +6836,11 @@ namespace // make private heap copy if (!_uses_heap) { - _buffer = duplicate_string(_buffer, alloc); + size_t length_ = strlength(_buffer); + + _buffer = duplicate_string(_buffer, length_, alloc); _uses_heap = true; + _length_heap = length_; } return const_cast(_buffer); @@ -5364,16 +6866,10 @@ namespace return _uses_heap; } }; +PUGI__NS_END - xpath_string xpath_string_const(const char_t* str) - { - return xpath_string(str, false); - } -} - -namespace -{ - bool starts_with(const char_t* string, const char_t* pattern) +PUGI__NS_BEGIN + PUGI__FN bool starts_with(const char_t* string, const char_t* pattern) { while (*pattern && *string == *pattern) { @@ -5384,7 +6880,7 @@ namespace return *pattern == 0; } - const char_t* find_char(const char_t* s, char_t c) + PUGI__FN const char_t* find_char(const char_t* s, char_t c) { #ifdef PUGIXML_WCHAR_MODE return wcschr(s, c); @@ -5393,7 +6889,7 @@ namespace #endif } - const char_t* find_substring(const char_t* s, const char_t* p) + PUGI__FN const char_t* find_substring(const char_t* s, const char_t* p) { #ifdef PUGIXML_WCHAR_MODE // MSVC6 wcsstr bug workaround (if s is empty it always returns 0) @@ -5404,18 +6900,18 @@ namespace } // Converts symbol to lower case, if it is an ASCII one - char_t tolower_ascii(char_t ch) + PUGI__FN char_t tolower_ascii(char_t ch) { return static_cast(ch - 'A') < 26 ? static_cast(ch | ' ') : ch; } - xpath_string string_value(const xpath_node& na, xpath_allocator* alloc) + PUGI__FN xpath_string string_value(const xpath_node& na, xpath_allocator* alloc) { if (na.attribute()) - return xpath_string_const(na.attribute().value()); + return xpath_string::from_const(na.attribute().value()); else { - const xml_node& n = na.node(); + xml_node n = na.node(); switch (n.type()) { @@ -5423,7 +6919,7 @@ namespace case node_cdata: case node_comment: case node_pi: - return xpath_string_const(n.value()); + return xpath_string::from_const(n.value()); case node_document: case node_element: @@ -5435,7 +6931,7 @@ namespace while (cur && cur != n) { if (cur.type() == node_pcdata || cur.type() == node_cdata) - result.append(xpath_string_const(cur.value()), alloc); + result.append(xpath_string::from_const(cur.value()), alloc); if (cur.first_child()) cur = cur.first_child(); @@ -5459,87 +6955,122 @@ namespace } } - unsigned int node_height(xml_node n) - { - unsigned int result = 0; - - while (n) - { - ++result; - n = n.parent(); - } - - return result; + PUGI__FN bool node_is_before_sibling(xml_node_struct* ln, xml_node_struct* rn) + { + assert(ln->parent == rn->parent); + + // there is no common ancestor (the shared parent is null), nodes are from different documents + if (!ln->parent) return ln < rn; + + // determine sibling order + xml_node_struct* ls = ln; + xml_node_struct* rs = rn; + + while (ls && rs) + { + if (ls == rn) return true; + if (rs == ln) return false; + + ls = ls->next_sibling; + rs = rs->next_sibling; + } + + // if rn sibling chain ended ln must be before rn + return !rs; } - bool node_is_before(xml_node ln, unsigned int lh, xml_node rn, unsigned int rh) + PUGI__FN bool node_is_before(xml_node_struct* ln, xml_node_struct* rn) { - // normalize heights - for (unsigned int i = rh; i < lh; i++) ln = ln.parent(); - for (unsigned int j = lh; j < rh; j++) rn = rn.parent(); - + // find common ancestor at the same depth, if any + xml_node_struct* lp = ln; + xml_node_struct* rp = rn; + + while (lp && rp && lp->parent != rp->parent) + { + lp = lp->parent; + rp = rp->parent; + } + + // parents are the same! + if (lp && rp) return node_is_before_sibling(lp, rp); + + // nodes are at different depths, need to normalize heights + bool left_higher = !lp; + + while (lp) + { + lp = lp->parent; + ln = ln->parent; + } + + while (rp) + { + rp = rp->parent; + rn = rn->parent; + } + // one node is the ancestor of the other - if (ln == rn) return lh < rh; - - // find common ancestor - while (ln.parent() != rn.parent()) - { - ln = ln.parent(); - rn = rn.parent(); - } + if (ln == rn) return left_higher; + + // find common ancestor... again + while (ln->parent != rn->parent) + { + ln = ln->parent; + rn = rn->parent; + } + + return node_is_before_sibling(ln, rn); + } + + PUGI__FN bool node_is_ancestor(xml_node_struct* parent, xml_node_struct* node) + { + while (node && node != parent) node = node->parent; + + return parent && node == parent; + } + + PUGI__FN const void* document_buffer_order(const xpath_node& xnode) + { + xml_node_struct* node = xnode.node().internal_object(); + + if (node) + { + if ((get_document(node).header & xml_memory_page_contents_shared_mask) == 0) + { + if (node->name && (node->header & impl::xml_memory_page_name_allocated_or_shared_mask) == 0) return node->name; + if (node->value && (node->header & impl::xml_memory_page_value_allocated_or_shared_mask) == 0) return node->value; + } + + return 0; + } - // there is no common ancestor (the shared parent is null), nodes are from different documents - if (!ln.parent()) return ln < rn; + xml_attribute_struct* attr = xnode.attribute().internal_object(); - // determine sibling order - for (; ln; ln = ln.next_sibling()) - if (ln == rn) - return true; - - return false; - } - - bool node_is_ancestor(xml_node parent, xml_node node) - { - while (node && node != parent) node = node.parent(); - - return parent && node == parent; - } - - const void* document_order(const xpath_node& xnode) - { - xml_node_struct* node = xnode.node().internal_object(); - - if (node) - { - if (node->name && (node->header & xml_memory_page_name_allocated_mask) == 0) return node->name; - if (node->value && (node->header & xml_memory_page_value_allocated_mask) == 0) return node->value; - return 0; - } - - xml_attribute_struct* attr = xnode.attribute().internal_object(); - - if (attr) - { - if ((attr->header & xml_memory_page_name_allocated_mask) == 0) return attr->name; - if ((attr->header & xml_memory_page_value_allocated_mask) == 0) return attr->value; - return 0; - } + if (attr) + { + if ((get_document(attr).header & xml_memory_page_contents_shared_mask) == 0) + { + if ((attr->header & impl::xml_memory_page_name_allocated_or_shared_mask) == 0) return attr->name; + if ((attr->header & impl::xml_memory_page_value_allocated_or_shared_mask) == 0) return attr->value; + } + + return 0; + } return 0; - } - + } + struct document_order_comparator { bool operator()(const xpath_node& lhs, const xpath_node& rhs) const { // optimized document order based check - const void* lo = document_order(lhs); - const void* ro = document_order(rhs); + const void* lo = document_buffer_order(lhs); + const void* ro = document_buffer_order(rhs); if (lo && ro) return lo < ro; - // slow comparison + // slow comparison xml_node ln = lhs.node(), rn = rhs.node(); // compare attributes @@ -5549,11 +7080,11 @@ namespace if (lhs.parent() == rhs.parent()) { // determine sibling order - for (xml_attribute a = lhs.attribute(); a; a = a.next_attribute()) - if (a == rhs.attribute()) - return true; - - return false; + for (xml_attribute a = lhs.attribute(); a; a = a.next_attribute()) + if (a == rhs.attribute()) + return true; + + return false; } // compare attribute parents @@ -5576,11 +7107,10 @@ namespace } if (ln == rn) return false; + + if (!ln || !rn) return ln < rn; - unsigned int lh = node_height(ln); - unsigned int rh = node_height(rn); - - return node_is_before(ln, lh, rn, rh); + return node_is_before(ln.internal_object(), rn.internal_object()); } }; @@ -5593,10 +7123,10 @@ namespace } }; - double gen_nan() + PUGI__FN double gen_nan() { #if defined(__STDC_IEC_559__) || ((FLT_RADIX - 0 == 2) && (FLT_MAX_EXP - 0 == 128) && (FLT_MANT_DIG - 0 == 24)) - union { float f; int32_t i; } u[sizeof(float) == sizeof(int32_t) ? 1 : -1]; + union { float f; uint32_t i; } u[sizeof(float) == sizeof(uint32_t) ? 1 : -1]; u[0].i = 0x7fc00000; return u[0].f; #else @@ -5606,9 +7136,9 @@ namespace #endif } - bool is_nan(double value) + PUGI__FN bool is_nan(double value) { - #if defined(_MSC_VER) || defined(__BORLANDC__) + #if defined(PUGI__MSVC_CRT_VERSION) || defined(__BORLANDC__) return !!_isnan(value); #elif defined(fpclassify) && defined(FP_NAN) return fpclassify(value) == FP_NAN; @@ -5619,12 +7149,12 @@ namespace #endif } - const char_t* convert_number_to_string_special(double value) + PUGI__FN const char_t* convert_number_to_string_special(double value) { - #if defined(_MSC_VER) || defined(__BORLANDC__) + #if defined(PUGI__MSVC_CRT_VERSION) || defined(__BORLANDC__) if (_finite(value)) return (value == 0) ? PUGIXML_TEXT("0") : 0; if (_isnan(value)) return PUGIXML_TEXT("NaN"); - return PUGIXML_TEXT("-Infinity") + (value > 0); + return value > 0 ? PUGIXML_TEXT("Infinity") : PUGIXML_TEXT("-Infinity"); #elif defined(fpclassify) && defined(FP_NAN) && defined(FP_INFINITE) && defined(FP_ZERO) switch (fpclassify(value)) { @@ -5632,7 +7162,7 @@ namespace return PUGIXML_TEXT("NaN"); case FP_INFINITE: - return PUGIXML_TEXT("-Infinity") + (value > 0); + return value > 0 ? PUGIXML_TEXT("Infinity") : PUGIXML_TEXT("-Infinity"); case FP_ZERO: return PUGIXML_TEXT("0"); @@ -5646,17 +7176,17 @@ namespace if (v == 0) return PUGIXML_TEXT("0"); if (v != v) return PUGIXML_TEXT("NaN"); - if (v * 2 == v) return PUGIXML_TEXT("-Infinity") + (value > 0); + if (v * 2 == v) return value > 0 ? PUGIXML_TEXT("Infinity") : PUGIXML_TEXT("-Infinity"); return 0; #endif } - bool convert_number_to_boolean(double value) + PUGI__FN bool convert_number_to_boolean(double value) { return (value != 0 && !is_nan(value)); } - void truncate_zeros(char* begin, char* end) + PUGI__FN void truncate_zeros(char* begin, char* end) { while (begin != end && end[-1] == '0') end--; @@ -5664,8 +7194,8 @@ namespace } // gets mantissa digits in the form of 0.xxxxx with 0. implied and the exponent -#if defined(_MSC_VER) && _MSC_VER >= 1400 - void convert_number_to_mantissa_exponent(double value, char* buffer, size_t buffer_size, char** out_mantissa, int* out_exponent) +#if defined(PUGI__MSVC_CRT_VERSION) && PUGI__MSVC_CRT_VERSION >= 1400 && !defined(_WIN32_WCE) + PUGI__FN void convert_number_to_mantissa_exponent(double value, char* buffer, size_t buffer_size, char** out_mantissa, int* out_exponent) { // get base values int sign, exponent; @@ -5679,7 +7209,7 @@ namespace *out_exponent = exponent; } #else - void convert_number_to_mantissa_exponent(double value, char* buffer, size_t buffer_size, char** out_mantissa, int* out_exponent) + PUGI__FN void convert_number_to_mantissa_exponent(double value, char* buffer, size_t buffer_size, char** out_mantissa, int* out_exponent) { // get a scientific notation value with IEEE DBL_DIG decimals sprintf(buffer, "%.*e", DBL_DIG, value); @@ -5710,21 +7240,25 @@ namespace } #endif - xpath_string convert_number_to_string(double value, xpath_allocator* alloc) + PUGI__FN xpath_string convert_number_to_string(double value, xpath_allocator* alloc) { // try special number conversion const char_t* special = convert_number_to_string_special(value); - if (special) return xpath_string_const(special); + if (special) return xpath_string::from_const(special); // get mantissa + exponent form - char mantissa_buffer[64]; + char mantissa_buffer[32]; char* mantissa; int exponent; convert_number_to_mantissa_exponent(value, mantissa_buffer, sizeof(mantissa_buffer), &mantissa, &exponent); + // allocate a buffer of suitable length for the number + size_t result_size = strlen(mantissa_buffer) + (exponent > 0 ? exponent : -exponent) + 4; + char_t* result = static_cast(alloc->allocate(sizeof(char_t) * result_size)); + assert(result); + // make the number! - char_t result[512]; char_t* s = result; // sign @@ -5739,7 +7273,7 @@ namespace { while (exponent > 0) { - assert(*mantissa == 0 || (unsigned)(*mantissa - '0') <= 9); + assert(*mantissa == 0 || static_cast(static_cast(*mantissa) - '0') <= 9); *s++ = *mantissa ? *mantissa++ : '0'; exponent--; } @@ -5761,22 +7295,22 @@ namespace // extra mantissa digits while (*mantissa) { - assert((unsigned)(*mantissa - '0') <= 9); + assert(static_cast(*mantissa - '0') <= 9); *s++ = *mantissa++; } } // zero-terminate - assert(s < result + sizeof(result) / sizeof(result[0])); + assert(s < result + result_size); *s = 0; - return xpath_string(result, alloc); + return xpath_string::from_heap_preallocated(result, s); } - bool check_string_to_number_format(const char_t* string) + PUGI__FN bool check_string_to_number_format(const char_t* string) { // parse leading whitespace - while (IS_CHARTYPE(*string, ct_space)) ++string; + while (PUGI__IS_CHARTYPE(*string, ct_space)) ++string; // parse sign if (*string == '-') ++string; @@ -5784,26 +7318,26 @@ namespace if (!*string) return false; // if there is no integer part, there should be a decimal part with at least one digit - if (!IS_CHARTYPEX(string[0], ctx_digit) && (string[0] != '.' || !IS_CHARTYPEX(string[1], ctx_digit))) return false; + if (!PUGI__IS_CHARTYPEX(string[0], ctx_digit) && (string[0] != '.' || !PUGI__IS_CHARTYPEX(string[1], ctx_digit))) return false; // parse integer part - while (IS_CHARTYPEX(*string, ctx_digit)) ++string; + while (PUGI__IS_CHARTYPEX(*string, ctx_digit)) ++string; // parse decimal part if (*string == '.') { ++string; - while (IS_CHARTYPEX(*string, ctx_digit)) ++string; + while (PUGI__IS_CHARTYPEX(*string, ctx_digit)) ++string; } // parse trailing whitespace - while (IS_CHARTYPE(*string, ct_space)) ++string; + while (PUGI__IS_CHARTYPE(*string, ct_space)) ++string; return *string == 0; } - double convert_string_to_number(const char_t* string) + PUGI__FN double convert_string_to_number(const char_t* string) { // check string format if (!check_string_to_number_format(string)) return gen_nan(); @@ -5816,17 +7350,15 @@ namespace #endif } - bool convert_string_to_number(const char_t* begin, const char_t* end, double* out_result) + PUGI__FN bool convert_string_to_number_scratch(char_t (&buffer)[32], const char_t* begin, const char_t* end, double* out_result) { - char_t buffer[32]; - size_t length = static_cast(end - begin); char_t* scratch = buffer; if (length >= sizeof(buffer) / sizeof(buffer[0])) { // need to make dummy on-heap copy - scratch = static_cast(global_allocate((length + 1) * sizeof(char_t))); + scratch = static_cast(xml_memory::allocate((length + 1) * sizeof(char_t))); if (!scratch) return false; } @@ -5837,29 +7369,29 @@ namespace *out_result = convert_string_to_number(scratch); // free dummy buffer - if (scratch != buffer) global_deallocate(scratch); + if (scratch != buffer) xml_memory::deallocate(scratch); return true; } - double round_nearest(double value) + PUGI__FN double round_nearest(double value) { return floor(value + 0.5); } - double round_nearest_nzero(double value) + PUGI__FN double round_nearest_nzero(double value) { // same as round_nearest, but returns -0 for [-0.5, -0] // ceil is used to differentiate between +0 and -0 (we return -0 for [-0.5, -0] and +0 for +0) return (value >= -0.5 && value <= 0) ? ceil(value) : floor(value + 0.5); } - const char_t* qualified_name(const xpath_node& node) + PUGI__FN const char_t* qualified_name(const xpath_node& node) { return node.attribute() ? node.attribute().name() : node.node().name(); } - const char_t* local_name(const xpath_node& node) + PUGI__FN const char_t* local_name(const xpath_node& node) { const char_t* name = qualified_name(node); const char_t* p = find_char(name, ':'); @@ -5880,7 +7412,7 @@ namespace prefix_length = pos ? static_cast(pos - name) : 0; } - bool operator()(const xml_attribute& a) const + bool operator()(xml_attribute a) const { const char_t* name = a.name(); @@ -5890,7 +7422,7 @@ namespace } }; - const char_t* namespace_uri(const xml_node& node) + PUGI__FN const char_t* namespace_uri(xml_node node) { namespace_uri_predicate pred = node.name(); @@ -5908,7 +7440,7 @@ namespace return PUGIXML_TEXT(""); } - const char_t* namespace_uri(const xml_attribute& attr, const xml_node& parent) + PUGI__FN const char_t* namespace_uri(xml_attribute attr, xml_node parent) { namespace_uri_predicate pred = attr.name(); @@ -5929,12 +7461,12 @@ namespace return PUGIXML_TEXT(""); } - const char_t* namespace_uri(const xpath_node& node) + PUGI__FN const char_t* namespace_uri(const xpath_node& node) { return node.attribute() ? namespace_uri(node.attribute(), node.parent()) : namespace_uri(node.node()); } - void normalize_space(char_t* buffer) + PUGI__FN char_t* normalize_space(char_t* buffer) { char_t* write = buffer; @@ -5942,10 +7474,10 @@ namespace { char_t ch = *it++; - if (IS_CHARTYPE(ch, ct_space)) + if (PUGI__IS_CHARTYPE(ch, ct_space)) { // replace whitespace sequence with single space - while (IS_CHARTYPE(*it, ct_space)) it++; + while (PUGI__IS_CHARTYPE(*it, ct_space)) it++; // avoid leading spaces if (write != buffer) *write++ = ' '; @@ -5954,21 +7486,21 @@ namespace } // remove trailing space - if (write != buffer && IS_CHARTYPE(write[-1], ct_space)) write--; + if (write != buffer && PUGI__IS_CHARTYPE(write[-1], ct_space)) write--; // zero-terminate *write = 0; + + return write; } - void translate(char_t* buffer, const char_t* from, const char_t* to) + PUGI__FN char_t* translate(char_t* buffer, const char_t* from, const char_t* to, size_t to_length) { - size_t to_length = strlength(to); - char_t* write = buffer; while (*buffer) { - DMC_VOLATILE char_t ch = *buffer++; + PUGI__DMC_VOLATILE char_t ch = *buffer++; const char_t* pos = find_char(from, ch); @@ -5980,6 +7512,77 @@ namespace // zero-terminate *write = 0; + + return write; + } + + PUGI__FN unsigned char* translate_table_generate(xpath_allocator* alloc, const char_t* from, const char_t* to) + { + unsigned char table[128] = {0}; + + while (*from) + { + unsigned int fc = static_cast(*from); + unsigned int tc = static_cast(*to); + + if (fc >= 128 || tc >= 128) + return 0; + + // code=128 means "skip character" + if (!table[fc]) + table[fc] = static_cast(tc ? tc : 128); + + from++; + if (tc) to++; + } + + for (int i = 0; i < 128; ++i) + if (!table[i]) + table[i] = static_cast(i); + + void* result = alloc->allocate_nothrow(sizeof(table)); + + if (result) + { + memcpy(result, table, sizeof(table)); + } + + return static_cast(result); + } + + PUGI__FN char_t* translate_table(char_t* buffer, const unsigned char* table) + { + char_t* write = buffer; + + while (*buffer) + { + char_t ch = *buffer++; + unsigned int index = static_cast(ch); + + if (index < 128) + { + unsigned char code = table[index]; + + // code=128 means "skip character" (table size is 128 so 128 can be a special value) + // this code skips these characters without extra branches + *write = static_cast(code); + write += 1 - (code >> 7); + } + else + { + *write++ = ch; + } + } + + // zero-terminate + *write = 0; + + return write; + } + + inline bool is_xpath_attribute(const char_t* name) + { + return !(starts_with(name, PUGIXML_TEXT("xmlns")) && (name[5] == 0 || name[5] == ':')); } struct xpath_variable_boolean: xpath_variable @@ -6010,7 +7613,7 @@ namespace ~xpath_variable_string() { - if (value) global_deallocate(value); + if (value) xml_memory::deallocate(value); } char_t* value; @@ -6023,9 +7626,9 @@ namespace char_t name[1]; }; - const xpath_node_set dummy_node_set; + static const xpath_node_set dummy_node_set; - unsigned int hash_string(const char_t* str) + PUGI__FN unsigned int hash_string(const char_t* str) { // Jenkins one-at-a-time hash (http://en.wikipedia.org/wiki/Jenkins_hash_function#one-at-a-time) unsigned int result = 0; @@ -6044,13 +7647,13 @@ namespace return result; } - template T* new_xpath_variable(const char_t* name) + template PUGI__FN T* new_xpath_variable(const char_t* name) { size_t length = strlength(name); if (length == 0) return 0; // empty variable names are invalid // $$ we can't use offsetof(T, name) because T is non-POD, so we just allocate additional length characters - void* memory = global_allocate(sizeof(T) + length * sizeof(char_t)); + void* memory = xml_memory::allocate(sizeof(T) + length * sizeof(char_t)); if (!memory) return 0; T* result = new (memory) T(); @@ -6060,7 +7663,7 @@ namespace return result; } - xpath_variable* new_xpath_variable(xpath_value_type type, const char_t* name) + PUGI__FN xpath_variable* new_xpath_variable(xpath_value_type type, const char_t* name) { switch (type) { @@ -6081,13 +7684,13 @@ namespace } } - template void delete_xpath_variable(T* var) + template PUGI__FN void delete_xpath_variable(T* var) { var->~T(); - global_deallocate(var); + xml_memory::deallocate(var); } - void delete_xpath_variable(xpath_value_type type, xpath_variable* var) + PUGI__FN void delete_xpath_variable(xpath_value_type type, xpath_variable* var) { switch (type) { @@ -6112,17 +7715,15 @@ namespace } } - xpath_variable* get_variable(xpath_variable_set* set, const char_t* begin, const char_t* end) + PUGI__FN xpath_variable* get_variable_scratch(char_t (&buffer)[32], xpath_variable_set* set, const char_t* begin, const char_t* end) { - char_t buffer[32]; - size_t length = static_cast(end - begin); char_t* scratch = buffer; if (length >= sizeof(buffer) / sizeof(buffer[0])) { // need to make dummy on-heap copy - scratch = static_cast(global_allocate((length + 1) * sizeof(char_t))); + scratch = static_cast(xml_memory::allocate((length + 1) * sizeof(char_t))); if (!scratch) return 0; } @@ -6133,24 +7734,46 @@ namespace xpath_variable* result = set->get(scratch); // free dummy buffer - if (scratch != buffer) global_deallocate(scratch); + if (scratch != buffer) xml_memory::deallocate(scratch); return result; } -} +PUGI__NS_END // Internal node set class -namespace -{ - xpath_node_set::type_t xpath_sort(xpath_node* begin, xpath_node* end, xpath_node_set::type_t type, bool rev) +PUGI__NS_BEGIN + PUGI__FN xpath_node_set::type_t xpath_get_order(const xpath_node* begin, const xpath_node* end) + { + if (end - begin < 2) + return xpath_node_set::type_sorted; + + document_order_comparator cmp; + + bool first = cmp(begin[0], begin[1]); + + for (const xpath_node* it = begin + 1; it + 1 < end; ++it) + if (cmp(it[0], it[1]) != first) + return xpath_node_set::type_unsorted; + + return first ? xpath_node_set::type_sorted : xpath_node_set::type_sorted_reverse; + } + + PUGI__FN xpath_node_set::type_t xpath_sort(xpath_node* begin, xpath_node* end, xpath_node_set::type_t type, bool rev) { xpath_node_set::type_t order = rev ? xpath_node_set::type_sorted_reverse : xpath_node_set::type_sorted; if (type == xpath_node_set::type_unsorted) { - sort(begin, end, document_order_comparator()); + xpath_node_set::type_t sorted = xpath_get_order(begin, end); + + if (sorted == xpath_node_set::type_unsorted) + { + sort(begin, end, document_order_comparator()); - type = xpath_node_set::type_sorted; + type = xpath_node_set::type_sorted; + } + else + type = sorted; } if (type != order) reverse(begin, end); @@ -6158,7 +7781,7 @@ namespace return order; } - xpath_node xpath_first(const xpath_node* begin, const xpath_node* end, xpath_node_set::type_t type) + PUGI__FN xpath_node xpath_first(const xpath_node* begin, const xpath_node* end, xpath_node_set::type_t type) { if (begin == end) return xpath_node(); @@ -6178,6 +7801,7 @@ namespace return xpath_node(); } } + class xpath_node_set_raw { xpath_node_set::type_t _type; @@ -6216,47 +7840,37 @@ namespace return xpath_first(_begin, _end, _type); } + void push_back_grow(const xpath_node& node, xpath_allocator* alloc); + void push_back(const xpath_node& node, xpath_allocator* alloc) { - if (_end == _eos) - { - size_t capacity = static_cast(_eos - _begin); - - // get new capacity (1.5x rule) - size_t new_capacity = capacity + capacity / 2 + 1; - - // reallocate the old array or allocate a new one - xpath_node* data = static_cast(alloc->reallocate(_begin, capacity * sizeof(xpath_node), new_capacity * sizeof(xpath_node))); - assert(data); - - // finalize - _begin = data; - _end = data + capacity; - _eos = data + new_capacity; - } - - *_end++ = node; + if (_end != _eos) + *_end++ = node; + else + push_back_grow(node, alloc); } - void append(const xpath_node* begin, const xpath_node* end, xpath_allocator* alloc) + void append(const xpath_node* begin_, const xpath_node* end_, xpath_allocator* alloc) { - size_t size = static_cast(_end - _begin); + if (begin_ == end_) return; + + size_t size_ = static_cast(_end - _begin); size_t capacity = static_cast(_eos - _begin); - size_t count = static_cast(end - begin); + size_t count = static_cast(end_ - begin_); - if (size + count > capacity) + if (size_ + count > capacity) { // reallocate the old array or allocate a new one - xpath_node* data = static_cast(alloc->reallocate(_begin, capacity * sizeof(xpath_node), (size + count) * sizeof(xpath_node))); + xpath_node* data = static_cast(alloc->reallocate(_begin, capacity * sizeof(xpath_node), (size_ + count) * sizeof(xpath_node))); assert(data); // finalize _begin = data; - _end = data + size; - _eos = data + size + count; + _end = data + size_; + _eos = data + size_ + count; } - memcpy(_end, begin, count * sizeof(xpath_node)); + memcpy(_end, begin_, count * sizeof(xpath_node)); _end += count; } @@ -6285,21 +7899,40 @@ namespace return _type; } - void set_type(xpath_node_set::type_t type) + void set_type(xpath_node_set::type_t value) { - _type = type; + _type = value; } }; -} -namespace -{ + PUGI__FN_NO_INLINE void xpath_node_set_raw::push_back_grow(const xpath_node& node, xpath_allocator* alloc) + { + size_t capacity = static_cast(_eos - _begin); + + // get new capacity (1.5x rule) + size_t new_capacity = capacity + capacity / 2 + 1; + + // reallocate the old array or allocate a new one + xpath_node* data = static_cast(alloc->reallocate(_begin, capacity * sizeof(xpath_node), new_capacity * sizeof(xpath_node))); + assert(data); + + // finalize + _begin = data; + _end = data + capacity; + _eos = data + new_capacity; + + // push + *_end++ = node; + } +PUGI__NS_END + +PUGI__NS_BEGIN struct xpath_context { xpath_node n; size_t position, size; - xpath_context(const xpath_node& n, size_t position, size_t size): n(n), position(position), size(size) + xpath_context(const xpath_node& n_, size_t position_, size_t size_): n(n_), position(position_), size(size_) { } }; @@ -6375,7 +8008,7 @@ namespace { const char_t* cur = _cur; - while (IS_CHARTYPE(*cur, ct_space)) ++cur; + while (PUGI__IS_CHARTYPE(*cur, ct_space)) ++cur; // save lexeme position for error reporting _cur_lexeme_pos = cur; @@ -6457,17 +8090,17 @@ namespace case '$': cur += 1; - if (IS_CHARTYPEX(*cur, ctx_start_symbol)) + if (PUGI__IS_CHARTYPEX(*cur, ctx_start_symbol)) { _cur_lexeme_contents.begin = cur; - while (IS_CHARTYPEX(*cur, ctx_symbol)) cur++; + while (PUGI__IS_CHARTYPEX(*cur, ctx_symbol)) cur++; - if (cur[0] == ':' && IS_CHARTYPEX(cur[1], ctx_symbol)) // qname + if (cur[0] == ':' && PUGI__IS_CHARTYPEX(cur[1], ctx_symbol)) // qname { cur++; // : - while (IS_CHARTYPEX(*cur, ctx_symbol)) cur++; + while (PUGI__IS_CHARTYPEX(*cur, ctx_symbol)) cur++; } _cur_lexeme_contents.end = cur; @@ -6530,13 +8163,13 @@ namespace cur += 2; _cur_lexeme = lex_double_dot; } - else if (IS_CHARTYPEX(*(cur+1), ctx_digit)) + else if (PUGI__IS_CHARTYPEX(*(cur+1), ctx_digit)) { _cur_lexeme_contents.begin = cur; // . ++cur; - while (IS_CHARTYPEX(*cur, ctx_digit)) cur++; + while (PUGI__IS_CHARTYPEX(*cur, ctx_digit)) cur++; _cur_lexeme_contents.end = cur; @@ -6590,28 +8223,28 @@ namespace break; default: - if (IS_CHARTYPEX(*cur, ctx_digit)) + if (PUGI__IS_CHARTYPEX(*cur, ctx_digit)) { _cur_lexeme_contents.begin = cur; - while (IS_CHARTYPEX(*cur, ctx_digit)) cur++; + while (PUGI__IS_CHARTYPEX(*cur, ctx_digit)) cur++; if (*cur == '.') { cur++; - while (IS_CHARTYPEX(*cur, ctx_digit)) cur++; + while (PUGI__IS_CHARTYPEX(*cur, ctx_digit)) cur++; } _cur_lexeme_contents.end = cur; _cur_lexeme = lex_number; } - else if (IS_CHARTYPEX(*cur, ctx_start_symbol)) + else if (PUGI__IS_CHARTYPEX(*cur, ctx_start_symbol)) { _cur_lexeme_contents.begin = cur; - while (IS_CHARTYPEX(*cur, ctx_symbol)) cur++; + while (PUGI__IS_CHARTYPEX(*cur, ctx_symbol)) cur++; if (cur[0] == ':') { @@ -6619,11 +8252,11 @@ namespace { cur += 2; // :* } - else if (IS_CHARTYPEX(cur[1], ctx_symbol)) // namespace test qname + else if (PUGI__IS_CHARTYPEX(cur[1], ctx_symbol)) // namespace test qname { cur++; // : - while (IS_CHARTYPEX(*cur, ctx_symbol)) cur++; + while (PUGI__IS_CHARTYPEX(*cur, ctx_symbol)) cur++; } } @@ -6660,10 +8293,11 @@ namespace enum ast_type_t { + ast_unknown, ast_op_or, // left or right ast_op_and, // left and right ast_op_equal, // left = right - ast_op_not_equal, // left != right + ast_op_not_equal, // left != right ast_op_less, // left < right ast_op_greater, // left > right ast_op_less_or_equal, // left <= right @@ -6677,7 +8311,6 @@ namespace ast_op_union, // left | right ast_predicate, // apply predicate to set; next points to next predicate ast_filter, // select * from left where right - ast_filter_posinv, // select * from left where right; proximity position invariant ast_string_constant, // string constant ast_number_constant, // number constant ast_variable, // variable @@ -6717,7 +8350,10 @@ namespace ast_func_ceiling, // ceiling(left) ast_func_round, // round(left) ast_step, // process set left with step - ast_step_root // select root node + ast_step_root, // select root node + + ast_opt_translate_table, // translate(left, right, third) where right/third are constants + ast_opt_compare_attribute // @name = 'string' }; enum axis_t @@ -6750,6 +8386,21 @@ namespace nodetest_all_in_namespace }; + enum predicate_t + { + predicate_default, + predicate_posinv, + predicate_constant, + predicate_constant_one + }; + + enum nodeset_eval_t + { + nodeset_eval_all, + nodeset_eval_any, + nodeset_eval_first + }; + template struct axis_to_type { static const axis_t axis; @@ -6764,8 +8415,10 @@ namespace char _type; char _rettype; - // for ast_step / ast_predicate + // for ast_step char _axis; + + // for ast_step/ast_predicate/ast_filter char _test; // tree node structure @@ -6783,6 +8436,8 @@ namespace xpath_variable* variable; // node test for ast_step (node name/namespace/node type/pi target) const char_t* nodetest; + // table for ast_opt_translate_table + const unsigned char* table; } _data; xpath_ast_node(const xpath_ast_node&); @@ -6812,8 +8467,8 @@ namespace { xpath_allocator_capture cr(stack.result); - xpath_node_set_raw ls = lhs->eval_node_set(c, stack); - xpath_node_set_raw rs = rhs->eval_node_set(c, stack); + xpath_node_set_raw ls = lhs->eval_node_set(c, stack, nodeset_eval_all); + xpath_node_set_raw rs = rhs->eval_node_set(c, stack, nodeset_eval_all); for (const xpath_node* li = ls.begin(); li != ls.end(); ++li) for (const xpath_node* ri = rs.begin(); ri != rs.end(); ++ri) @@ -6841,7 +8496,7 @@ namespace xpath_allocator_capture cr(stack.result); double l = lhs->eval_number(c, stack); - xpath_node_set_raw rs = rhs->eval_node_set(c, stack); + xpath_node_set_raw rs = rhs->eval_node_set(c, stack, nodeset_eval_all); for (const xpath_node* ri = rs.begin(); ri != rs.end(); ++ri) { @@ -6858,7 +8513,7 @@ namespace xpath_allocator_capture cr(stack.result); xpath_string l = lhs->eval_string(c, stack); - xpath_node_set_raw rs = rhs->eval_node_set(c, stack); + xpath_node_set_raw rs = rhs->eval_node_set(c, stack, nodeset_eval_all); for (const xpath_node* ri = rs.begin(); ri != rs.end(); ++ri) { @@ -6876,6 +8531,11 @@ namespace return false; } + static bool eval_once(xpath_node_set::type_t type, nodeset_eval_t eval) + { + return type == xpath_node_set::type_sorted ? eval != nodeset_eval_all : eval == nodeset_eval_any; + } + template static bool compare_rel(xpath_ast_node* lhs, xpath_ast_node* rhs, const xpath_context& c, const xpath_stack& stack, const Comp& comp) { xpath_value_type lt = lhs->rettype(), rt = rhs->rettype(); @@ -6886,8 +8546,8 @@ namespace { xpath_allocator_capture cr(stack.result); - xpath_node_set_raw ls = lhs->eval_node_set(c, stack); - xpath_node_set_raw rs = rhs->eval_node_set(c, stack); + xpath_node_set_raw ls = lhs->eval_node_set(c, stack, nodeset_eval_all); + xpath_node_set_raw rs = rhs->eval_node_set(c, stack, nodeset_eval_all); for (const xpath_node* li = ls.begin(); li != ls.end(); ++li) { @@ -6911,7 +8571,7 @@ namespace xpath_allocator_capture cr(stack.result); double l = lhs->eval_number(c, stack); - xpath_node_set_raw rs = rhs->eval_node_set(c, stack); + xpath_node_set_raw rs = rhs->eval_node_set(c, stack, nodeset_eval_all); for (const xpath_node* ri = rs.begin(); ri != rs.end(); ++ri) { @@ -6927,7 +8587,7 @@ namespace { xpath_allocator_capture cr(stack.result); - xpath_node_set_raw ls = lhs->eval_node_set(c, stack); + xpath_node_set_raw ls = lhs->eval_node_set(c, stack, nodeset_eval_all); double r = rhs->eval_number(c, stack); for (const xpath_node* li = ls.begin(); li != ls.end(); ++li) @@ -6947,123 +8607,226 @@ namespace } } - void apply_predicate(xpath_node_set_raw& ns, size_t first, xpath_ast_node* expr, const xpath_stack& stack) + static void apply_predicate_boolean(xpath_node_set_raw& ns, size_t first, xpath_ast_node* expr, const xpath_stack& stack, bool once) { assert(ns.size() >= first); + assert(expr->rettype() != xpath_type_number); size_t i = 1; size_t size = ns.size() - first; - + xpath_node* last = ns.begin() + first; - + // remove_if... or well, sort of for (xpath_node* it = last; it != ns.end(); ++it, ++i) { xpath_context c(*it, i, size); - - if (expr->rettype() == xpath_type_number) + + if (expr->eval_boolean(c, stack)) { - if (expr->eval_number(c, stack) == i) - *last++ = *it; + *last++ = *it; + + if (once) break; } - else if (expr->eval_boolean(c, stack)) + } + + ns.truncate(last); + } + + static void apply_predicate_number(xpath_node_set_raw& ns, size_t first, xpath_ast_node* expr, const xpath_stack& stack, bool once) + { + assert(ns.size() >= first); + assert(expr->rettype() == xpath_type_number); + + size_t i = 1; + size_t size = ns.size() - first; + + xpath_node* last = ns.begin() + first; + + // remove_if... or well, sort of + for (xpath_node* it = last; it != ns.end(); ++it, ++i) + { + xpath_context c(*it, i, size); + + if (expr->eval_number(c, stack) == i) + { *last++ = *it; + + if (once) break; + } } - + ns.truncate(last); } - void apply_predicates(xpath_node_set_raw& ns, size_t first, const xpath_stack& stack) + static void apply_predicate_number_const(xpath_node_set_raw& ns, size_t first, xpath_ast_node* expr, const xpath_stack& stack) { - if (ns.size() == first) return; - - for (xpath_ast_node* pred = _right; pred; pred = pred->_next) + assert(ns.size() >= first); + assert(expr->rettype() == xpath_type_number); + + size_t size = ns.size() - first; + + xpath_node* last = ns.begin() + first; + + xpath_context c(xpath_node(), 1, size); + + double er = expr->eval_number(c, stack); + + if (er >= 1.0 && er <= size) { - apply_predicate(ns, first, pred->_left, stack); + size_t eri = static_cast(er); + + if (er == eri) + { + xpath_node r = last[eri - 1]; + + *last++ = r; + } } + + ns.truncate(last); } - void step_push(xpath_node_set_raw& ns, const xml_attribute& a, const xml_node& parent, xpath_allocator* alloc) + void apply_predicate(xpath_node_set_raw& ns, size_t first, const xpath_stack& stack, bool once) { - if (!a) return; + if (ns.size() == first) return; - const char_t* name = a.name(); + assert(_type == ast_filter || _type == ast_predicate); + + if (_test == predicate_constant || _test == predicate_constant_one) + apply_predicate_number_const(ns, first, _right, stack); + else if (_right->rettype() == xpath_type_number) + apply_predicate_number(ns, first, _right, stack, once); + else + apply_predicate_boolean(ns, first, _right, stack, once); + } + + void apply_predicates(xpath_node_set_raw& ns, size_t first, const xpath_stack& stack, nodeset_eval_t eval) + { + if (ns.size() == first) return; + + bool last_once = eval_once(ns.type(), eval); + + for (xpath_ast_node* pred = _right; pred; pred = pred->_next) + pred->apply_predicate(ns, first, stack, !pred->_next && last_once); + } + + bool step_push(xpath_node_set_raw& ns, xml_attribute_struct* a, xml_node_struct* parent, xpath_allocator* alloc) + { + assert(a); + + const char_t* name = a->name ? a->name : PUGIXML_TEXT(""); - // There are no attribute nodes corresponding to attributes that declare namespaces - // That is, "xmlns:..." or "xmlns" - if (starts_with(name, PUGIXML_TEXT("xmlns")) && (name[5] == 0 || name[5] == ':')) return; - switch (_test) { case nodetest_name: - if (strequal(name, _data.nodetest)) ns.push_back(xpath_node(a, parent), alloc); + if (strequal(name, _data.nodetest) && is_xpath_attribute(name)) + { + ns.push_back(xpath_node(xml_attribute(a), xml_node(parent)), alloc); + return true; + } break; case nodetest_type_node: case nodetest_all: - ns.push_back(xpath_node(a, parent), alloc); + if (is_xpath_attribute(name)) + { + ns.push_back(xpath_node(xml_attribute(a), xml_node(parent)), alloc); + return true; + } break; case nodetest_all_in_namespace: - if (starts_with(name, _data.nodetest)) - ns.push_back(xpath_node(a, parent), alloc); + if (starts_with(name, _data.nodetest) && is_xpath_attribute(name)) + { + ns.push_back(xpath_node(xml_attribute(a), xml_node(parent)), alloc); + return true; + } break; default: ; } + + return false; } - void step_push(xpath_node_set_raw& ns, const xml_node& n, xpath_allocator* alloc) + bool step_push(xpath_node_set_raw& ns, xml_node_struct* n, xpath_allocator* alloc) { - if (!n) return; + assert(n); + + xml_node_type type = PUGI__NODETYPE(n); switch (_test) { case nodetest_name: - if (n.type() == node_element && strequal(n.name(), _data.nodetest)) ns.push_back(n, alloc); + if (type == node_element && n->name && strequal(n->name, _data.nodetest)) + { + ns.push_back(xml_node(n), alloc); + return true; + } break; case nodetest_type_node: - ns.push_back(n, alloc); - break; + ns.push_back(xml_node(n), alloc); + return true; case nodetest_type_comment: - if (n.type() == node_comment) - ns.push_back(n, alloc); + if (type == node_comment) + { + ns.push_back(xml_node(n), alloc); + return true; + } break; case nodetest_type_text: - if (n.type() == node_pcdata || n.type() == node_cdata) - ns.push_back(n, alloc); + if (type == node_pcdata || type == node_cdata) + { + ns.push_back(xml_node(n), alloc); + return true; + } break; case nodetest_type_pi: - if (n.type() == node_pi) - ns.push_back(n, alloc); + if (type == node_pi) + { + ns.push_back(xml_node(n), alloc); + return true; + } break; case nodetest_pi: - if (n.type() == node_pi && strequal(n.name(), _data.nodetest)) - ns.push_back(n, alloc); + if (type == node_pi && n->name && strequal(n->name, _data.nodetest)) + { + ns.push_back(xml_node(n), alloc); + return true; + } break; case nodetest_all: - if (n.type() == node_element) - ns.push_back(n, alloc); + if (type == node_element) + { + ns.push_back(xml_node(n), alloc); + return true; + } break; case nodetest_all_in_namespace: - if (n.type() == node_element && starts_with(n.name(), _data.nodetest)) - ns.push_back(n, alloc); + if (type == node_element && n->name && starts_with(n->name, _data.nodetest)) + { + ns.push_back(xml_node(n), alloc); + return true; + } break; default: assert(!"Unknown axis"); - } + } + + return false; } - template void step_fill(xpath_node_set_raw& ns, const xml_node& n, xpath_allocator* alloc, T) + template void step_fill(xpath_node_set_raw& ns, xml_node_struct* n, xpath_allocator* alloc, bool once, T) { const axis_t axis = T::axis; @@ -7071,16 +8834,18 @@ namespace { case axis_attribute: { - for (xml_attribute a = n.first_attribute(); a; a = a.next_attribute()) - step_push(ns, a, n, alloc); + for (xml_attribute_struct* a = n->first_attribute; a; a = a->next_attribute) + if (step_push(ns, a, n, alloc) & once) + return; break; } case axis_child: { - for (xml_node c = n.first_child(); c; c = c.next_sibling()) - step_push(ns, c, alloc); + for (xml_node_struct* c = n->first_child; c; c = c->next_sibling) + if (step_push(ns, c, alloc) & once) + return; break; } @@ -7089,24 +8854,28 @@ namespace case axis_descendant_or_self: { if (axis == axis_descendant_or_self) - step_push(ns, n, alloc); + if (step_push(ns, n, alloc) & once) + return; - xml_node cur = n.first_child(); + xml_node_struct* cur = n->first_child; - while (cur && cur != n) + while (cur) { - step_push(ns, cur, alloc); + if (step_push(ns, cur, alloc) & once) + return; - if (cur.first_child()) - cur = cur.first_child(); - else if (cur.next_sibling()) - cur = cur.next_sibling(); + if (cur->first_child) + cur = cur->first_child; else { - while (!cur.next_sibling() && cur != n) - cur = cur.parent(); + while (!cur->next_sibling) + { + cur = cur->parent; + + if (cur == n) return; + } - if (cur != n) cur = cur.next_sibling(); + cur = cur->next_sibling; } } @@ -7115,42 +8884,53 @@ namespace case axis_following_sibling: { - for (xml_node c = n.next_sibling(); c; c = c.next_sibling()) - step_push(ns, c, alloc); + for (xml_node_struct* c = n->next_sibling; c; c = c->next_sibling) + if (step_push(ns, c, alloc) & once) + return; break; } case axis_preceding_sibling: { - for (xml_node c = n.previous_sibling(); c; c = c.previous_sibling()) - step_push(ns, c, alloc); + for (xml_node_struct* c = n->prev_sibling_c; c->next_sibling; c = c->prev_sibling_c) + if (step_push(ns, c, alloc) & once) + return; break; } case axis_following: { - xml_node cur = n; + xml_node_struct* cur = n; // exit from this node so that we don't include descendants - while (cur && !cur.next_sibling()) cur = cur.parent(); - cur = cur.next_sibling(); + while (!cur->next_sibling) + { + cur = cur->parent; + + if (!cur) return; + } + + cur = cur->next_sibling; - for (;;) + while (cur) { - step_push(ns, cur, alloc); + if (step_push(ns, cur, alloc) & once) + return; - if (cur.first_child()) - cur = cur.first_child(); - else if (cur.next_sibling()) - cur = cur.next_sibling(); + if (cur->first_child) + cur = cur->first_child; else { - while (cur && !cur.next_sibling()) cur = cur.parent(); - cur = cur.next_sibling(); + while (!cur->next_sibling) + { + cur = cur->parent; - if (!cur) break; + if (!cur) return; + } + + cur = cur->next_sibling; } } @@ -7159,37 +8939,40 @@ namespace case axis_preceding: { - xml_node cur = n; + xml_node_struct* cur = n; + + // exit from this node so that we don't include descendants + while (!cur->prev_sibling_c->next_sibling) + { + cur = cur->parent; + + if (!cur) return; + } - while (cur && !cur.previous_sibling()) cur = cur.parent(); - cur = cur.previous_sibling(); + cur = cur->prev_sibling_c; - for (;;) + while (cur) { - if (cur.last_child()) - cur = cur.last_child(); + if (cur->first_child) + cur = cur->first_child->prev_sibling_c; else { // leaf node, can't be ancestor - step_push(ns, cur, alloc); + if (step_push(ns, cur, alloc) & once) + return; - if (cur.previous_sibling()) - cur = cur.previous_sibling(); - else + while (!cur->prev_sibling_c->next_sibling) { - do - { - cur = cur.parent(); - if (!cur) break; - - if (!node_is_ancestor(cur, n)) step_push(ns, cur, alloc); - } - while (!cur.previous_sibling()); + cur = cur->parent; - cur = cur.previous_sibling(); + if (!cur) return; - if (!cur) break; + if (!node_is_ancestor(cur, n)) + if (step_push(ns, cur, alloc) & once) + return; } + + cur = cur->prev_sibling_c; } } @@ -7200,15 +8983,17 @@ namespace case axis_ancestor_or_self: { if (axis == axis_ancestor_or_self) - step_push(ns, n, alloc); + if (step_push(ns, n, alloc) & once) + return; - xml_node cur = n.parent(); + xml_node_struct* cur = n->parent; while (cur) { - step_push(ns, cur, alloc); + if (step_push(ns, cur, alloc) & once) + return; - cur = cur.parent(); + cur = cur->parent; } break; @@ -7223,7 +9008,8 @@ namespace case axis_parent: { - if (n.parent()) step_push(ns, n.parent(), alloc); + if (n->parent) + step_push(ns, n->parent, alloc); break; } @@ -7233,7 +9019,7 @@ namespace } } - template void step_fill(xpath_node_set_raw& ns, const xml_attribute& a, const xml_node& p, xpath_allocator* alloc, T v) + template void step_fill(xpath_node_set_raw& ns, xml_attribute_struct* a, xml_node_struct* p, xpath_allocator* alloc, bool once, T v) { const axis_t axis = T::axis; @@ -7243,15 +9029,17 @@ namespace case axis_ancestor_or_self: { if (axis == axis_ancestor_or_self && _test == nodetest_type_node) // reject attributes based on principal node type test - step_push(ns, a, p, alloc); + if (step_push(ns, a, p, alloc) & once) + return; - xml_node cur = p; + xml_node_struct* cur = p; while (cur) { - step_push(ns, cur, alloc); + if (step_push(ns, cur, alloc) & once) + return; - cur = cur.parent(); + cur = cur->parent; } break; @@ -7268,23 +9056,26 @@ namespace case axis_following: { - xml_node cur = p; - - for (;;) - { - if (cur.first_child()) - cur = cur.first_child(); - else if (cur.next_sibling()) - cur = cur.next_sibling(); + xml_node_struct* cur = p; + + while (cur) + { + if (cur->first_child) + cur = cur->first_child; else { - while (cur && !cur.next_sibling()) cur = cur.parent(); - cur = cur.next_sibling(); - - if (!cur) break; + while (!cur->next_sibling) + { + cur = cur->parent; + + if (!cur) return; + } + + cur = cur->next_sibling; } - step_push(ns, cur, alloc); + if (step_push(ns, cur, alloc) & once) + return; } break; @@ -7300,7 +9091,7 @@ namespace case axis_preceding: { // preceding:: axis does not include attribute nodes and attribute ancestors (they are the same as parent's ancestors), so we can reuse node preceding - step_fill(ns, p, alloc, v); + step_fill(ns, p, alloc, once, v); break; } @@ -7308,18 +9099,35 @@ namespace assert(!"Unimplemented axis"); } } - - template xpath_node_set_raw step_do(const xpath_context& c, const xpath_stack& stack, T v) + + template void step_fill(xpath_node_set_raw& ns, const xpath_node& xn, xpath_allocator* alloc, bool once, T v) + { + const axis_t axis = T::axis; + const bool axis_has_attributes = (axis == axis_ancestor || axis == axis_ancestor_or_self || axis == axis_descendant_or_self || axis == axis_following || axis == axis_parent || axis == axis_preceding || axis == axis_self); + + if (xn.node()) + step_fill(ns, xn.node().internal_object(), alloc, once, v); + else if (axis_has_attributes && xn.attribute() && xn.parent()) + step_fill(ns, xn.attribute().internal_object(), xn.parent().internal_object(), alloc, once, v); + } + + template xpath_node_set_raw step_do(const xpath_context& c, const xpath_stack& stack, nodeset_eval_t eval, T v) { const axis_t axis = T::axis; - bool attributes = (axis == axis_ancestor || axis == axis_ancestor_or_self || axis == axis_descendant_or_self || axis == axis_following || axis == axis_parent || axis == axis_preceding || axis == axis_self); + const bool axis_reverse = (axis == axis_ancestor || axis == axis_ancestor_or_self || axis == axis_preceding || axis == axis_preceding_sibling); + const xpath_node_set::type_t axis_type = axis_reverse ? xpath_node_set::type_sorted_reverse : xpath_node_set::type_sorted; + + bool once = + (axis == axis_attribute && _test == nodetest_name) || + (!_right && eval_once(axis_type, eval)) || + (_right && !_right->_next && _right->_test == predicate_constant_one); xpath_node_set_raw ns; - ns.set_type((axis == axis_ancestor || axis == axis_ancestor_or_self || axis == axis_preceding || axis == axis_preceding_sibling) ? xpath_node_set::type_sorted_reverse : xpath_node_set::type_sorted); + ns.set_type(axis_type); if (_left) { - xpath_node_set_raw s = _left->eval_node_set(c, stack); + xpath_node_set_raw s = _left->eval_node_set(c, stack, nodeset_eval_all); // self axis preserves the original order if (axis == axis_self) ns.set_type(s.type()); @@ -7331,22 +9139,14 @@ namespace // in general, all axes generate elements in a particular order, but there is no order guarantee if axis is applied to two nodes if (axis != axis_self && size != 0) ns.set_type(xpath_node_set::type_unsorted); - if (it->node()) - step_fill(ns, it->node(), stack.result, v); - else if (attributes) - step_fill(ns, it->attribute(), it->parent(), stack.result, v); - - apply_predicates(ns, size, stack); + step_fill(ns, *it, stack.result, once, v); + if (_right) apply_predicates(ns, size, stack, eval); } } else { - if (c.n.node()) - step_fill(ns, c.n.node(), stack.result, v); - else if (attributes) - step_fill(ns, c.n.attribute(), c.n.parent(), stack.result, v); - - apply_predicates(ns, 0, stack); + step_fill(ns, c.n, stack.result, once, v); + if (_right) apply_predicates(ns, 0, stack, eval); } // child, attribute and self axes always generate unique set of nodes @@ -7358,38 +9158,45 @@ namespace } public: - xpath_ast_node(ast_type_t type, xpath_value_type rettype, const char_t* value): - _type((char)type), _rettype((char)rettype), _axis(0), _test(0), _left(0), _right(0), _next(0) + xpath_ast_node(ast_type_t type, xpath_value_type rettype_, const char_t* value): + _type(static_cast(type)), _rettype(static_cast(rettype_)), _axis(0), _test(0), _left(0), _right(0), _next(0) { assert(type == ast_string_constant); _data.string = value; } - xpath_ast_node(ast_type_t type, xpath_value_type rettype, double value): - _type((char)type), _rettype((char)rettype), _axis(0), _test(0), _left(0), _right(0), _next(0) + xpath_ast_node(ast_type_t type, xpath_value_type rettype_, double value): + _type(static_cast(type)), _rettype(static_cast(rettype_)), _axis(0), _test(0), _left(0), _right(0), _next(0) { assert(type == ast_number_constant); _data.number = value; } - xpath_ast_node(ast_type_t type, xpath_value_type rettype, xpath_variable* value): - _type((char)type), _rettype((char)rettype), _axis(0), _test(0), _left(0), _right(0), _next(0) + xpath_ast_node(ast_type_t type, xpath_value_type rettype_, xpath_variable* value): + _type(static_cast(type)), _rettype(static_cast(rettype_)), _axis(0), _test(0), _left(0), _right(0), _next(0) { assert(type == ast_variable); _data.variable = value; } - xpath_ast_node(ast_type_t type, xpath_value_type rettype, xpath_ast_node* left = 0, xpath_ast_node* right = 0): - _type((char)type), _rettype((char)rettype), _axis(0), _test(0), _left(left), _right(right), _next(0) + xpath_ast_node(ast_type_t type, xpath_value_type rettype_, xpath_ast_node* left = 0, xpath_ast_node* right = 0): + _type(static_cast(type)), _rettype(static_cast(rettype_)), _axis(0), _test(0), _left(left), _right(right), _next(0) { } xpath_ast_node(ast_type_t type, xpath_ast_node* left, axis_t axis, nodetest_t test, const char_t* contents): - _type((char)type), _rettype(xpath_type_node_set), _axis((char)axis), _test((char)test), _left(left), _right(0), _next(0) + _type(static_cast(type)), _rettype(xpath_type_node_set), _axis(static_cast(axis)), _test(static_cast(test)), _left(left), _right(0), _next(0) { + assert(type == ast_step); _data.nodetest = contents; } + xpath_ast_node(ast_type_t type, xpath_ast_node* left, xpath_ast_node* right, predicate_t test): + _type(static_cast(type)), _rettype(xpath_type_node_set), _axis(0), _test(static_cast(test)), _left(left), _right(right), _next(0) + { + assert(type == ast_filter || type == ast_predicate); + } + void set_next(xpath_ast_node* value) { _next = value; @@ -7490,6 +9297,15 @@ namespace return false; } + case ast_opt_compare_attribute: + { + const char_t* value = (_right->_type == ast_string_constant) ? _right->_data.string : _right->_data.variable->get_string(); + + xml_attribute attr = c.n.node().attribute(_left->_data.nodetest); + + return attr && strequal(attr.value(), value) && is_xpath_attribute(attr.name()); + } + case ast_variable: { assert(_rettype == _data.variable->type()); @@ -7518,7 +9334,7 @@ namespace { xpath_allocator_capture cr(stack.result); - return !eval_node_set(c, stack).empty(); + return !eval_node_set(c, stack, nodeset_eval_any).empty(); } default: @@ -7555,30 +9371,30 @@ namespace return _data.number; case ast_func_last: - return (double)c.size; + return static_cast(c.size); case ast_func_position: - return (double)c.position; + return static_cast(c.position); case ast_func_count: { xpath_allocator_capture cr(stack.result); - return (double)_left->eval_node_set(c, stack).size(); + return static_cast(_left->eval_node_set(c, stack, nodeset_eval_all).size()); } case ast_func_string_length_0: { xpath_allocator_capture cr(stack.result); - return (double)string_value(c.n, stack.result).length(); + return static_cast(string_value(c.n, stack.result).length()); } case ast_func_string_length_1: { xpath_allocator_capture cr(stack.result); - return (double)_left->eval_string(c, stack).length(); + return static_cast(_left->eval_string(c, stack).length()); } case ast_func_number_0: @@ -7597,7 +9413,7 @@ namespace double r = 0; - xpath_node_set_raw ns = _left->eval_node_set(c, stack); + xpath_node_set_raw ns = _left->eval_node_set(c, stack, nodeset_eval_all); for (const xpath_node* it = ns.begin(); it != ns.end(); ++it) { @@ -7712,7 +9528,7 @@ namespace *ri = 0; - return xpath_string(result, true); + return xpath_string::from_heap_preallocated(result, ri); } xpath_string eval_string(const xpath_context& c, const xpath_stack& stack) @@ -7720,57 +9536,57 @@ namespace switch (_type) { case ast_string_constant: - return xpath_string_const(_data.string); + return xpath_string::from_const(_data.string); case ast_func_local_name_0: { xpath_node na = c.n; - return xpath_string_const(local_name(na)); + return xpath_string::from_const(local_name(na)); } case ast_func_local_name_1: { xpath_allocator_capture cr(stack.result); - xpath_node_set_raw ns = _left->eval_node_set(c, stack); + xpath_node_set_raw ns = _left->eval_node_set(c, stack, nodeset_eval_first); xpath_node na = ns.first(); - return xpath_string_const(local_name(na)); + return xpath_string::from_const(local_name(na)); } case ast_func_name_0: { xpath_node na = c.n; - return xpath_string_const(qualified_name(na)); + return xpath_string::from_const(qualified_name(na)); } case ast_func_name_1: { xpath_allocator_capture cr(stack.result); - xpath_node_set_raw ns = _left->eval_node_set(c, stack); + xpath_node_set_raw ns = _left->eval_node_set(c, stack, nodeset_eval_first); xpath_node na = ns.first(); - return xpath_string_const(qualified_name(na)); + return xpath_string::from_const(qualified_name(na)); } case ast_func_namespace_uri_0: { xpath_node na = c.n; - return xpath_string_const(namespace_uri(na)); + return xpath_string::from_const(namespace_uri(na)); } case ast_func_namespace_uri_1: { xpath_allocator_capture cr(stack.result); - xpath_node_set_raw ns = _left->eval_node_set(c, stack); + xpath_node_set_raw ns = _left->eval_node_set(c, stack, nodeset_eval_first); xpath_node na = ns.first(); - return xpath_string_const(namespace_uri(na)); + return xpath_string::from_const(namespace_uri(na)); } case ast_func_string_0: @@ -7793,7 +9609,7 @@ namespace const char_t* pos = find_substring(s.c_str(), p.c_str()); - return pos ? xpath_string(s.c_str(), pos, stack.result) : xpath_string(); + return pos ? xpath_string::from_heap(s.c_str(), pos, stack.result) : xpath_string(); } case ast_func_substring_after: @@ -7808,9 +9624,10 @@ namespace const char_t* pos = find_substring(s.c_str(), p.c_str()); if (!pos) return xpath_string(); - const char_t* result = pos + p.length(); + const char_t* rbegin = pos + p.length(); + const char_t* rend = s.c_str() + s.length(); - return s.uses_heap() ? xpath_string(result, stack.result) : xpath_string_const(result); + return s.uses_heap() ? xpath_string::from_heap(rbegin, rend, stack.result) : xpath_string::from_const(rbegin); } case ast_func_substring_2: @@ -7827,12 +9644,13 @@ namespace if (is_nan(first)) return xpath_string(); // NaN else if (first >= s_length + 1) return xpath_string(); - size_t pos = first < 1 ? 1 : (size_t)first; + size_t pos = first < 1 ? 1 : static_cast(first); assert(1 <= pos && pos <= s_length + 1); const char_t* rbegin = s.c_str() + (pos - 1); + const char_t* rend = s.c_str() + s.length(); - return s.uses_heap() ? xpath_string(rbegin, stack.result) : xpath_string_const(rbegin); + return s.uses_heap() ? xpath_string::from_heap(rbegin, rend, stack.result) : xpath_string::from_const(rbegin); } case ast_func_substring_3: @@ -7852,32 +9670,34 @@ namespace else if (first >= last) return xpath_string(); else if (last < 1) return xpath_string(); - size_t pos = first < 1 ? 1 : (size_t)first; - size_t end = last >= s_length + 1 ? s_length + 1 : (size_t)last; + size_t pos = first < 1 ? 1 : static_cast(first); + size_t end = last >= s_length + 1 ? s_length + 1 : static_cast(last); assert(1 <= pos && pos <= end && end <= s_length + 1); const char_t* rbegin = s.c_str() + (pos - 1); const char_t* rend = s.c_str() + (end - 1); - return (end == s_length + 1 && !s.uses_heap()) ? xpath_string_const(rbegin) : xpath_string(rbegin, rend, stack.result); + return (end == s_length + 1 && !s.uses_heap()) ? xpath_string::from_const(rbegin) : xpath_string::from_heap(rbegin, rend, stack.result); } case ast_func_normalize_space_0: { xpath_string s = string_value(c.n, stack.result); - normalize_space(s.data(stack.result)); + char_t* begin = s.data(stack.result); + char_t* end = normalize_space(begin); - return s; + return xpath_string::from_heap_preallocated(begin, end); } case ast_func_normalize_space_1: { xpath_string s = _left->eval_string(c, stack); - normalize_space(s.data(stack.result)); + char_t* begin = s.data(stack.result); + char_t* end = normalize_space(begin); - return s; + return xpath_string::from_heap_preallocated(begin, end); } case ast_func_translate: @@ -7890,9 +9710,20 @@ namespace xpath_string from = _right->eval_string(c, swapped_stack); xpath_string to = _right->_next->eval_string(c, swapped_stack); - translate(s.data(stack.result), from.c_str(), to.c_str()); + char_t* begin = s.data(stack.result); + char_t* end = translate(begin, from.c_str(), to.c_str(), to.length()); + + return xpath_string::from_heap_preallocated(begin, end); + } + + case ast_opt_translate_table: + { + xpath_string s = _left->eval_string(c, stack); + + char_t* begin = s.data(stack.result); + char_t* end = translate_table(begin, _data.table); - return s; + return xpath_string::from_heap_preallocated(begin, end); } case ast_variable: @@ -7900,7 +9731,7 @@ namespace assert(_rettype == _data.variable->type()); if (_rettype == xpath_type_string) - return xpath_string_const(_data.variable->get_string()); + return xpath_string::from_const(_data.variable->get_string()); // fallthrough to type conversion } @@ -7910,7 +9741,7 @@ namespace switch (_rettype) { case xpath_type_boolean: - return xpath_string_const(eval_boolean(c, stack) ? PUGIXML_TEXT("true") : PUGIXML_TEXT("false")); + return xpath_string::from_const(eval_boolean(c, stack) ? PUGIXML_TEXT("true") : PUGIXML_TEXT("false")); case xpath_type_number: return convert_number_to_string(eval_number(c, stack), stack.result); @@ -7921,7 +9752,7 @@ namespace xpath_stack swapped_stack = {stack.temp, stack.result}; - xpath_node_set_raw ns = eval_node_set(c, swapped_stack); + xpath_node_set_raw ns = eval_node_set(c, swapped_stack, nodeset_eval_first); return ns.empty() ? xpath_string() : string_value(ns.first(), stack.result); } @@ -7933,7 +9764,7 @@ namespace } } - xpath_node_set_raw eval_node_set(const xpath_context& c, const xpath_stack& stack) + xpath_node_set_raw eval_node_set(const xpath_context& c, const xpath_stack& stack, nodeset_eval_t eval) { switch (_type) { @@ -7943,27 +9774,28 @@ namespace xpath_stack swapped_stack = {stack.temp, stack.result}; - xpath_node_set_raw ls = _left->eval_node_set(c, swapped_stack); - xpath_node_set_raw rs = _right->eval_node_set(c, stack); - + xpath_node_set_raw ls = _left->eval_node_set(c, swapped_stack, eval); + xpath_node_set_raw rs = _right->eval_node_set(c, stack, eval); + // we can optimize merging two sorted sets, but this is a very rare operation, so don't bother - rs.set_type(xpath_node_set::type_unsorted); + rs.set_type(xpath_node_set::type_unsorted); rs.append(ls.begin(), ls.end(), stack.result); rs.remove_duplicates(); - + return rs; } case ast_filter: - case ast_filter_posinv: { - xpath_node_set_raw set = _left->eval_node_set(c, stack); + xpath_node_set_raw set = _left->eval_node_set(c, stack, _test == predicate_constant_one ? nodeset_eval_first : nodeset_eval_all); // either expression is a number or it contains position() call; sort by document order - if (_type == ast_filter) set.sort_do(); + if (_test != predicate_posinv) set.sort_do(); - apply_predicate(set, 0, _right, stack); + bool once = eval_once(set.type(), eval); + + apply_predicate(set, 0, stack, once); return set; } @@ -7976,44 +9808,48 @@ namespace switch (_axis) { case axis_ancestor: - return step_do(c, stack, axis_to_type()); + return step_do(c, stack, eval, axis_to_type()); case axis_ancestor_or_self: - return step_do(c, stack, axis_to_type()); + return step_do(c, stack, eval, axis_to_type()); case axis_attribute: - return step_do(c, stack, axis_to_type()); + return step_do(c, stack, eval, axis_to_type()); case axis_child: - return step_do(c, stack, axis_to_type()); + return step_do(c, stack, eval, axis_to_type()); case axis_descendant: - return step_do(c, stack, axis_to_type()); + return step_do(c, stack, eval, axis_to_type()); case axis_descendant_or_self: - return step_do(c, stack, axis_to_type()); + return step_do(c, stack, eval, axis_to_type()); case axis_following: - return step_do(c, stack, axis_to_type()); + return step_do(c, stack, eval, axis_to_type()); case axis_following_sibling: - return step_do(c, stack, axis_to_type()); + return step_do(c, stack, eval, axis_to_type()); case axis_namespace: // namespaced axis is not supported return xpath_node_set_raw(); case axis_parent: - return step_do(c, stack, axis_to_type()); + return step_do(c, stack, eval, axis_to_type()); case axis_preceding: - return step_do(c, stack, axis_to_type()); + return step_do(c, stack, eval, axis_to_type()); case axis_preceding_sibling: - return step_do(c, stack, axis_to_type()); + return step_do(c, stack, eval, axis_to_type()); case axis_self: - return step_do(c, stack, axis_to_type()); + return step_do(c, stack, eval, axis_to_type()); + + default: + assert(!"Unknown axis"); + return xpath_node_set_raw(); } } @@ -8055,12 +9891,77 @@ namespace return xpath_node_set_raw(); } } + + void optimize(xpath_allocator* alloc) + { + if (_left) _left->optimize(alloc); + if (_right) _right->optimize(alloc); + if (_next) _next->optimize(alloc); + + // Rewrite [position()=expr] with [expr] + // Note that this step has to go before classification to recognize [position()=1] + if ((_type == ast_filter || _type == ast_predicate) && + _right->_type == ast_op_equal && _right->_left->_type == ast_func_position && _right->_right->_rettype == xpath_type_number) + { + _right = _right->_right; + } + + // Classify filter/predicate ops to perform various optimizations during evaluation + if (_type == ast_filter || _type == ast_predicate) + { + assert(_test == predicate_default); + + if (_right->_type == ast_number_constant && _right->_data.number == 1.0) + _test = predicate_constant_one; + else if (_right->_rettype == xpath_type_number && (_right->_type == ast_number_constant || _right->_type == ast_variable || _right->_type == ast_func_last)) + _test = predicate_constant; + else if (_right->_rettype != xpath_type_number && _right->is_posinv_expr()) + _test = predicate_posinv; + } + + // Rewrite descendant-or-self::node()/child::foo with descendant::foo + // The former is a full form of //foo, the latter is much faster since it executes the node test immediately + // Do a similar kind of rewrite for self/descendant/descendant-or-self axes + // Note that we only rewrite positionally invariant steps (//foo[1] != /descendant::foo[1]) + if (_type == ast_step && (_axis == axis_child || _axis == axis_self || _axis == axis_descendant || _axis == axis_descendant_or_self) && _left && + _left->_type == ast_step && _left->_axis == axis_descendant_or_self && _left->_test == nodetest_type_node && !_left->_right && + is_posinv_step()) + { + if (_axis == axis_child || _axis == axis_descendant) + _axis = axis_descendant; + else + _axis = axis_descendant_or_self; + + _left = _left->_left; + } + + // Use optimized lookup table implementation for translate() with constant arguments + if (_type == ast_func_translate && _right->_type == ast_string_constant && _right->_next->_type == ast_string_constant) + { + unsigned char* table = translate_table_generate(alloc, _right->_data.string, _right->_next->_data.string); + + if (table) + { + _type = ast_opt_translate_table; + _data.table = table; + } + } + + // Use optimized path for @attr = 'value' or @attr = $value + if (_type == ast_op_equal && + _left->_type == ast_step && _left->_axis == axis_attribute && _left->_test == nodetest_name && !_left->_left && !_left->_right && + (_right->_type == ast_string_constant || (_right->_type == ast_variable && _right->_rettype == xpath_type_string))) + { + _type = ast_opt_compare_attribute; + } + } - bool is_posinv() + bool is_posinv_expr() const { switch (_type) { case ast_func_position: + case ast_func_last: return false; case ast_string_constant: @@ -8074,19 +9975,33 @@ namespace case ast_predicate: case ast_filter: - case ast_filter_posinv: return true; default: - if (_left && !_left->is_posinv()) return false; + if (_left && !_left->is_posinv_expr()) return false; for (xpath_ast_node* n = _right; n; n = n->_next) - if (!n->is_posinv()) return false; + if (!n->is_posinv_expr()) return false; return true; } } + bool is_posinv_step() const + { + assert(_type == ast_step); + + for (xpath_ast_node* n = _right; n; n = n->_next) + { + assert(n->_type == ast_predicate); + + if (n->_test != predicate_posinv) + return false; + } + + return true; + } + xpath_value_type rettype() const { return static_cast(_rettype); @@ -8095,14 +10010,16 @@ namespace struct xpath_parser { - xpath_allocator* _alloc; - xpath_lexer _lexer; + xpath_allocator* _alloc; + xpath_lexer _lexer; const char_t* _query; xpath_variable_set* _variables; xpath_parse_result* _result; + char_t _scratch[32]; + #ifdef PUGIXML_NO_EXCEPTIONS jmp_buf _error_handler; #endif @@ -8120,13 +10037,13 @@ namespace } void throw_error_oom() - { - #ifdef PUGIXML_NO_EXCEPTIONS - throw_error("Out of memory"); - #else - throw std::bad_alloc(); - #endif - } + { + #ifdef PUGIXML_NO_EXCEPTIONS + throw_error("Out of memory"); + #else + throw std::bad_alloc(); + #endif + } void* alloc_node() { @@ -8145,6 +10062,7 @@ namespace char_t* c = static_cast(_alloc->allocate_nothrow((length + 1) * sizeof(char_t))); if (!c) throw_error_oom(); + assert(c); // workaround for clang static analysis memcpy(c, value.begin, length * sizeof(char_t)); c[length] = 0; @@ -8180,7 +10098,7 @@ namespace return new (alloc_node()) xpath_ast_node(ast_func_count, xpath_type_number, args[0]); } else if (name == PUGIXML_TEXT("contains") && argc == 2) - return new (alloc_node()) xpath_ast_node(ast_func_contains, xpath_type_string, args[0], args[1]); + return new (alloc_node()) xpath_ast_node(ast_func_contains, xpath_type_boolean, args[0], args[1]); else if (name == PUGIXML_TEXT("concat") && argc >= 2) return new (alloc_node()) xpath_ast_node(ast_func_concat, xpath_type_string, args[0], args[1]); else if (name == PUGIXML_TEXT("ceiling") && argc == 1) @@ -8242,7 +10160,7 @@ namespace if (name == PUGIXML_TEXT("string") && argc <= 1) return new (alloc_node()) xpath_ast_node(argc == 0 ? ast_func_string_0 : ast_func_string_1, xpath_type_string, args[0]); else if (name == PUGIXML_TEXT("string-length") && argc <= 1) - return new (alloc_node()) xpath_ast_node(argc == 0 ? ast_func_string_length_0 : ast_func_string_length_1, xpath_type_string, args[0]); + return new (alloc_node()) xpath_ast_node(argc == 0 ? ast_func_string_length_0 : ast_func_string_length_1, xpath_type_number, args[0]); else if (name == PUGIXML_TEXT("starts-with") && argc == 2) return new (alloc_node()) xpath_ast_node(ast_func_starts_with, xpath_type_boolean, args[0], args[1]); else if (name == PUGIXML_TEXT("substring-before") && argc == 2) @@ -8266,6 +10184,9 @@ namespace return new (alloc_node()) xpath_ast_node(ast_func_true, xpath_type_boolean); break; + + default: + break; } throw_error("Unrecognized function or wrong parameter count"); @@ -8332,6 +10253,9 @@ namespace return axis_self; break; + + default: + break; } specified = false; @@ -8365,31 +10289,34 @@ namespace return nodetest_type_text; break; + + default: + break; } return nodetest_none; } - // PrimaryExpr ::= VariableReference | '(' Expr ')' | Literal | Number | FunctionCall - xpath_ast_node* parse_primary_expression() - { - switch (_lexer.current()) - { - case lex_var_ref: - { + // PrimaryExpr ::= VariableReference | '(' Expr ')' | Literal | Number | FunctionCall + xpath_ast_node* parse_primary_expression() + { + switch (_lexer.current()) + { + case lex_var_ref: + { xpath_lexer_string name = _lexer.contents(); if (!_variables) throw_error("Unknown variable: variable set is not provided"); - xpath_variable* var = get_variable(_variables, name.begin, name.end); + xpath_variable* var = get_variable_scratch(_scratch, _variables, name.begin, name.end); if (!var) throw_error("Unknown variable: variable set does not contain the given name"); _lexer.next(); - return new (alloc_node()) xpath_ast_node(ast_variable, var->type(), var); + return new (alloc_node()) xpath_ast_node(ast_variable, var->type(), var); } case lex_open_brace: @@ -8420,7 +10347,7 @@ namespace { double value = 0; - if (!convert_string_to_number(_lexer.contents().begin, _lexer.contents().end, &value)) + if (!convert_string_to_number_scratch(_scratch, _lexer.contents().begin, _lexer.contents().end, &value)) throw_error_oom(); xpath_ast_node* n = new (alloc_node()) xpath_ast_node(ast_number_constant, xpath_type_number, value); @@ -8466,48 +10393,46 @@ namespace return parse_function(function, argc, args); } - default: - throw_error("Unrecognizable primary expression"); + default: + throw_error("Unrecognizable primary expression"); - return 0; - } - } - - // FilterExpr ::= PrimaryExpr | FilterExpr Predicate - // Predicate ::= '[' PredicateExpr ']' - // PredicateExpr ::= Expr - xpath_ast_node* parse_filter_expression() - { - xpath_ast_node* n = parse_primary_expression(); + return 0; + } + } + + // FilterExpr ::= PrimaryExpr | FilterExpr Predicate + // Predicate ::= '[' PredicateExpr ']' + // PredicateExpr ::= Expr + xpath_ast_node* parse_filter_expression() + { + xpath_ast_node* n = parse_primary_expression(); - while (_lexer.current() == lex_open_square_brace) - { - _lexer.next(); + while (_lexer.current() == lex_open_square_brace) + { + _lexer.next(); xpath_ast_node* expr = parse_expression(); if (n->rettype() != xpath_type_node_set) throw_error("Predicate has to be applied to node set"); - bool posinv = expr->rettype() != xpath_type_number && expr->is_posinv(); - - n = new (alloc_node()) xpath_ast_node(posinv ? ast_filter_posinv : ast_filter, xpath_type_node_set, n, expr); - - if (_lexer.current() != lex_close_square_brace) - throw_error("Unmatched square brace"); - - _lexer.next(); - } - - return n; - } - - // Step ::= AxisSpecifier NodeTest Predicate* | AbbreviatedStep - // AxisSpecifier ::= AxisName '::' | '@'? - // NodeTest ::= NameTest | NodeType '(' ')' | 'processing-instruction' '(' Literal ')' - // NameTest ::= '*' | NCName ':' '*' | QName - // AbbreviatedStep ::= '.' | '..' - xpath_ast_node* parse_step(xpath_ast_node* set) - { + n = new (alloc_node()) xpath_ast_node(ast_filter, n, expr, predicate_default); + + if (_lexer.current() != lex_close_square_brace) + throw_error("Unmatched square brace"); + + _lexer.next(); + } + + return n; + } + + // Step ::= AxisSpecifier NodeTest Predicate* | AbbreviatedStep + // AxisSpecifier ::= AxisName '::' | '@'? + // NodeTest ::= NameTest | NodeType '(' ')' | 'processing-instruction' '(' Literal ')' + // NameTest ::= '*' | NCName ':' '*' | QName + // AbbreviatedStep ::= '.' | '..' + xpath_ast_node* parse_step(xpath_ast_node* set) + { if (set && set->rettype() != xpath_type_node_set) throw_error("Step has to be applied to node set"); @@ -8533,7 +10458,7 @@ namespace return new (alloc_node()) xpath_ast_node(ast_step, set, axis_parent, nodetest_type_node, 0); } - + nodetest_t nt_type = nodetest_none; xpath_lexer_string nt_name; @@ -8634,10 +10559,10 @@ namespace xpath_ast_node* expr = parse_expression(); - xpath_ast_node* pred = new (alloc_node()) xpath_ast_node(ast_predicate, xpath_type_node_set, expr); + xpath_ast_node* pred = new (alloc_node()) xpath_ast_node(ast_predicate, 0, expr, predicate_default); if (_lexer.current() != lex_close_square_brace) - throw_error("Unmatched square brace"); + throw_error("Unmatched square brace"); _lexer.next(); if (last) last->set_next(pred); @@ -8645,13 +10570,13 @@ namespace last = pred; } - + return n; - } - - // RelativeLocationPath ::= Step | RelativeLocationPath '/' Step | RelativeLocationPath '//' Step - xpath_ast_node* parse_relative_location_path(xpath_ast_node* set) - { + } + + // RelativeLocationPath ::= Step | RelativeLocationPath '/' Step | RelativeLocationPath '//' Step + xpath_ast_node* parse_relative_location_path(xpath_ast_node* set) + { xpath_ast_node* n = parse_step(set); while (_lexer.current() == lex_slash || _lexer.current() == lex_double_slash) @@ -8666,12 +10591,12 @@ namespace } return n; - } - - // LocationPath ::= RelativeLocationPath | AbsoluteLocationPath - // AbsoluteLocationPath ::= '/' RelativeLocationPath? | '//' RelativeLocationPath - xpath_ast_node* parse_location_path() - { + } + + // LocationPath ::= RelativeLocationPath | AbsoluteLocationPath + // AbsoluteLocationPath ::= '/' RelativeLocationPath? | '//' RelativeLocationPath + xpath_ast_node* parse_location_path() + { if (_lexer.current() == lex_slash) { _lexer.next(); @@ -8698,14 +10623,16 @@ namespace // else clause moved outside of if because of bogus warning 'control may reach end of non-void function being inlined' in gcc 4.0.1 return parse_relative_location_path(0); - } - - // PathExpr ::= LocationPath - // | FilterExpr - // | FilterExpr '/' RelativeLocationPath - // | FilterExpr '//' RelativeLocationPath - xpath_ast_node* parse_path_expression() - { + } + + // PathExpr ::= LocationPath + // | FilterExpr + // | FilterExpr '/' RelativeLocationPath + // | FilterExpr '//' RelativeLocationPath + // UnionExpr ::= PathExpr | UnionExpr '|' PathExpr + // UnaryExpr ::= UnionExpr | '-' UnaryExpr + xpath_ast_node* parse_path_or_unary_expression() + { // Clarification. // PathExpr begins with either LocationPath or FilterExpr. // FilterExpr begins with PrimaryExpr @@ -8716,27 +10643,27 @@ namespace if (_lexer.current() == lex_var_ref || _lexer.current() == lex_open_brace || _lexer.current() == lex_quoted_string || _lexer.current() == lex_number || _lexer.current() == lex_string) - { - if (_lexer.current() == lex_string) - { - // This is either a function call, or not - if not, we shall proceed with location path - const char_t* state = _lexer.state(); - - while (IS_CHARTYPE(*state, ct_space)) ++state; - - if (*state != '(') return parse_location_path(); + { + if (_lexer.current() == lex_string) + { + // This is either a function call, or not - if not, we shall proceed with location path + const char_t* state = _lexer.state(); + + while (PUGI__IS_CHARTYPE(*state, ct_space)) ++state; + + if (*state != '(') return parse_location_path(); // This looks like a function call; however this still can be a node-test. Check it. if (parse_node_test_type(_lexer.contents()) != nodetest_none) return parse_location_path(); - } - - xpath_ast_node* n = parse_filter_expression(); + } + + xpath_ast_node* n = parse_filter_expression(); - if (_lexer.current() == lex_slash || _lexer.current() == lex_double_slash) - { + if (_lexer.current() == lex_slash || _lexer.current() == lex_double_slash) + { lexeme_t l = _lexer.current(); - _lexer.next(); - + _lexer.next(); + if (l == lex_double_slash) { if (n->rettype() != xpath_type_node_set) throw_error("Step has to be applied to node set"); @@ -8744,176 +10671,142 @@ namespace n = new (alloc_node()) xpath_ast_node(ast_step, n, axis_descendant_or_self, nodetest_type_node, 0); } - // select from location path - return parse_relative_location_path(n); - } + // select from location path + return parse_relative_location_path(n); + } + + return n; + } + else if (_lexer.current() == lex_minus) + { + _lexer.next(); + + // precedence 7+ - only parses union expressions + xpath_ast_node* expr = parse_expression_rec(parse_path_or_unary_expression(), 7); - return n; - } - else return parse_location_path(); - } + return new (alloc_node()) xpath_ast_node(ast_op_negate, xpath_type_number, expr); + } + else + return parse_location_path(); + } + + struct binary_op_t + { + ast_type_t asttype; + xpath_value_type rettype; + int precedence; + + binary_op_t(): asttype(ast_unknown), rettype(xpath_type_none), precedence(0) + { + } - // UnionExpr ::= PathExpr | UnionExpr '|' PathExpr - xpath_ast_node* parse_union_expression() - { - xpath_ast_node* n = parse_path_expression(); + binary_op_t(ast_type_t asttype_, xpath_value_type rettype_, int precedence_): asttype(asttype_), rettype(rettype_), precedence(precedence_) + { + } + + static binary_op_t parse(xpath_lexer& lexer) + { + switch (lexer.current()) + { + case lex_string: + if (lexer.contents() == PUGIXML_TEXT("or")) + return binary_op_t(ast_op_or, xpath_type_boolean, 1); + else if (lexer.contents() == PUGIXML_TEXT("and")) + return binary_op_t(ast_op_and, xpath_type_boolean, 2); + else if (lexer.contents() == PUGIXML_TEXT("div")) + return binary_op_t(ast_op_divide, xpath_type_number, 6); + else if (lexer.contents() == PUGIXML_TEXT("mod")) + return binary_op_t(ast_op_mod, xpath_type_number, 6); + else + return binary_op_t(); - while (_lexer.current() == lex_union) - { - _lexer.next(); + case lex_equal: + return binary_op_t(ast_op_equal, xpath_type_boolean, 3); - xpath_ast_node* expr = parse_union_expression(); + case lex_not_equal: + return binary_op_t(ast_op_not_equal, xpath_type_boolean, 3); - if (n->rettype() != xpath_type_node_set || expr->rettype() != xpath_type_node_set) - throw_error("Union operator has to be applied to node sets"); + case lex_less: + return binary_op_t(ast_op_less, xpath_type_boolean, 4); - n = new (alloc_node()) xpath_ast_node(ast_op_union, xpath_type_node_set, n, expr); - } - - return n; - } - - // UnaryExpr ::= UnionExpr | '-' UnaryExpr - xpath_ast_node* parse_unary_expression() - { - if (_lexer.current() == lex_minus) - { - _lexer.next(); - - xpath_ast_node* expr = parse_unary_expression(); - - return new (alloc_node()) xpath_ast_node(ast_op_negate, xpath_type_number, expr); - } - else return parse_union_expression(); - } - - // MultiplicativeExpr ::= UnaryExpr - // | MultiplicativeExpr '*' UnaryExpr - // | MultiplicativeExpr 'div' UnaryExpr - // | MultiplicativeExpr 'mod' UnaryExpr - xpath_ast_node* parse_multiplicative_expression() - { - xpath_ast_node* n = parse_unary_expression(); - - while (_lexer.current() == lex_multiply || (_lexer.current() == lex_string && - (_lexer.contents() == PUGIXML_TEXT("mod") || _lexer.contents() == PUGIXML_TEXT("div")))) - { - ast_type_t op = _lexer.current() == lex_multiply ? ast_op_multiply : - _lexer.contents().begin[0] == 'd' ? ast_op_divide : ast_op_mod; - _lexer.next(); - - xpath_ast_node* expr = parse_unary_expression(); - - n = new (alloc_node()) xpath_ast_node(op, xpath_type_number, n, expr); - } - - return n; - } - - // AdditiveExpr ::= MultiplicativeExpr - // | AdditiveExpr '+' MultiplicativeExpr - // | AdditiveExpr '-' MultiplicativeExpr - xpath_ast_node* parse_additive_expression() - { - xpath_ast_node* n = parse_multiplicative_expression(); - - while (_lexer.current() == lex_plus || _lexer.current() == lex_minus) - { - lexeme_t l = _lexer.current(); - - _lexer.next(); - - xpath_ast_node* expr = parse_multiplicative_expression(); - - n = new (alloc_node()) xpath_ast_node(l == lex_plus ? ast_op_add : ast_op_subtract, xpath_type_number, n, expr); - } - - return n; - } - - // RelationalExpr ::= AdditiveExpr - // | RelationalExpr '<' AdditiveExpr - // | RelationalExpr '>' AdditiveExpr - // | RelationalExpr '<=' AdditiveExpr - // | RelationalExpr '>=' AdditiveExpr - xpath_ast_node* parse_relational_expression() - { - xpath_ast_node* n = parse_additive_expression(); - - while (_lexer.current() == lex_less || _lexer.current() == lex_less_or_equal || - _lexer.current() == lex_greater || _lexer.current() == lex_greater_or_equal) - { - lexeme_t l = _lexer.current(); - _lexer.next(); - - xpath_ast_node* expr = parse_additive_expression(); - - n = new (alloc_node()) xpath_ast_node(l == lex_less ? ast_op_less : l == lex_greater ? ast_op_greater : - l == lex_less_or_equal ? ast_op_less_or_equal : ast_op_greater_or_equal, xpath_type_boolean, n, expr); - } - - return n; - } - - // EqualityExpr ::= RelationalExpr - // | EqualityExpr '=' RelationalExpr - // | EqualityExpr '!=' RelationalExpr - xpath_ast_node* parse_equality_expression() - { - xpath_ast_node* n = parse_relational_expression(); - - while (_lexer.current() == lex_equal || _lexer.current() == lex_not_equal) - { - lexeme_t l = _lexer.current(); - - _lexer.next(); - - xpath_ast_node* expr = parse_relational_expression(); - - n = new (alloc_node()) xpath_ast_node(l == lex_equal ? ast_op_equal : ast_op_not_equal, xpath_type_boolean, n, expr); - } - - return n; - } - - // AndExpr ::= EqualityExpr | AndExpr 'and' EqualityExpr - xpath_ast_node* parse_and_expression() - { - xpath_ast_node* n = parse_equality_expression(); - - while (_lexer.current() == lex_string && _lexer.contents() == PUGIXML_TEXT("and")) - { - _lexer.next(); - - xpath_ast_node* expr = parse_equality_expression(); - - n = new (alloc_node()) xpath_ast_node(ast_op_and, xpath_type_boolean, n, expr); - } - - return n; - } + case lex_greater: + return binary_op_t(ast_op_greater, xpath_type_boolean, 4); - // OrExpr ::= AndExpr | OrExpr 'or' AndExpr - xpath_ast_node* parse_or_expression() - { - xpath_ast_node* n = parse_and_expression(); + case lex_less_or_equal: + return binary_op_t(ast_op_less_or_equal, xpath_type_boolean, 4); - while (_lexer.current() == lex_string && _lexer.contents() == PUGIXML_TEXT("or")) - { - _lexer.next(); + case lex_greater_or_equal: + return binary_op_t(ast_op_greater_or_equal, xpath_type_boolean, 4); - xpath_ast_node* expr = parse_and_expression(); + case lex_plus: + return binary_op_t(ast_op_add, xpath_type_number, 5); - n = new (alloc_node()) xpath_ast_node(ast_op_or, xpath_type_boolean, n, expr); - } + case lex_minus: + return binary_op_t(ast_op_subtract, xpath_type_number, 5); + + case lex_multiply: + return binary_op_t(ast_op_multiply, xpath_type_number, 6); + + case lex_union: + return binary_op_t(ast_op_union, xpath_type_node_set, 7); + + default: + return binary_op_t(); + } + } + }; + + xpath_ast_node* parse_expression_rec(xpath_ast_node* lhs, int limit) + { + binary_op_t op = binary_op_t::parse(_lexer); + + while (op.asttype != ast_unknown && op.precedence >= limit) + { + _lexer.next(); + + xpath_ast_node* rhs = parse_path_or_unary_expression(); + + binary_op_t nextop = binary_op_t::parse(_lexer); + + while (nextop.asttype != ast_unknown && nextop.precedence > op.precedence) + { + rhs = parse_expression_rec(rhs, nextop.precedence); + + nextop = binary_op_t::parse(_lexer); + } + + if (op.asttype == ast_op_union && (lhs->rettype() != xpath_type_node_set || rhs->rettype() != xpath_type_node_set)) + throw_error("Union operator has to be applied to node sets"); + + lhs = new (alloc_node()) xpath_ast_node(op.asttype, op.rettype, lhs, rhs); + + op = binary_op_t::parse(_lexer); + } + + return lhs; + } - return n; - } - // Expr ::= OrExpr + // OrExpr ::= AndExpr | OrExpr 'or' AndExpr + // AndExpr ::= EqualityExpr | AndExpr 'and' EqualityExpr + // EqualityExpr ::= RelationalExpr + // | EqualityExpr '=' RelationalExpr + // | EqualityExpr '!=' RelationalExpr + // RelationalExpr ::= AdditiveExpr + // | RelationalExpr '<' AdditiveExpr + // | RelationalExpr '>' AdditiveExpr + // | RelationalExpr '<=' AdditiveExpr + // | RelationalExpr '>=' AdditiveExpr + // AdditiveExpr ::= MultiplicativeExpr + // | AdditiveExpr '+' MultiplicativeExpr + // | AdditiveExpr '-' MultiplicativeExpr + // MultiplicativeExpr ::= UnaryExpr + // | MultiplicativeExpr '*' UnaryExpr + // | MultiplicativeExpr 'div' UnaryExpr + // | MultiplicativeExpr 'mod' UnaryExpr xpath_ast_node* parse_expression() { - return parse_or_expression(); + return parse_expression_rec(parse_path_or_unary_expression(), 0); } xpath_parser(const char_t* query, xpath_variable_set* variables, xpath_allocator* alloc, xpath_parse_result* result): _alloc(alloc), _lexer(query), _query(query), _variables(variables), _result(result) @@ -8947,13 +10840,13 @@ namespace } }; - struct xpath_query_impl - { + struct xpath_query_impl + { static xpath_query_impl* create() { - void* memory = global_allocate(sizeof(xpath_query_impl)); + void* memory = xml_memory::allocate(sizeof(xpath_query_impl)); - return new (memory) xpath_query_impl(); + return new (memory) xpath_query_impl(); } static void destroy(void* ptr) @@ -8964,20 +10857,21 @@ namespace static_cast(ptr)->alloc.release(); // free allocator memory (with the first page) - global_deallocate(ptr); + xml_memory::deallocate(ptr); } - xpath_query_impl(): root(0), alloc(&block) - { - block.next = 0; - } + xpath_query_impl(): root(0), alloc(&block) + { + block.next = 0; + block.capacity = sizeof(block.data); + } - xpath_ast_node* root; - xpath_allocator alloc; - xpath_memory_block block; - }; + xpath_ast_node* root; + xpath_allocator alloc; + xpath_memory_block block; + }; - xpath_string evaluate_string_impl(xpath_query_impl* impl, const xpath_node& n, xpath_stack_data& sd) + PUGI__FN xpath_string evaluate_string_impl(xpath_query_impl* impl, const xpath_node& n, xpath_stack_data& sd) { if (!impl) return xpath_string(); @@ -8989,107 +10883,130 @@ namespace return impl->root->eval_string(c, sd.stack); } -} + + PUGI__FN impl::xpath_ast_node* evaluate_node_set_prepare(xpath_query_impl* impl) + { + if (!impl) return 0; + + if (impl->root->rettype() != xpath_type_node_set) + { + #ifdef PUGIXML_NO_EXCEPTIONS + return 0; + #else + xpath_parse_result res; + res.error = "Expression does not evaluate to node set"; + + throw xpath_exception(res); + #endif + } + + return impl->root; + } +PUGI__NS_END namespace pugi { #ifndef PUGIXML_NO_EXCEPTIONS - xpath_exception::xpath_exception(const xpath_parse_result& result): _result(result) + PUGI__FN xpath_exception::xpath_exception(const xpath_parse_result& result_): _result(result_) { - assert(result.error); + assert(_result.error); } - const char* xpath_exception::what() const throw() + PUGI__FN const char* xpath_exception::what() const throw() { return _result.error; } - const xpath_parse_result& xpath_exception::result() const + PUGI__FN const xpath_parse_result& xpath_exception::result() const { return _result; } #endif - xpath_node::xpath_node() + PUGI__FN xpath_node::xpath_node() { } - xpath_node::xpath_node(const xml_node& node): _node(node) + PUGI__FN xpath_node::xpath_node(const xml_node& node_): _node(node_) { } - xpath_node::xpath_node(const xml_attribute& attribute, const xml_node& parent): _node(attribute ? parent : xml_node()), _attribute(attribute) + PUGI__FN xpath_node::xpath_node(const xml_attribute& attribute_, const xml_node& parent_): _node(attribute_ ? parent_ : xml_node()), _attribute(attribute_) { } - xml_node xpath_node::node() const + PUGI__FN xml_node xpath_node::node() const { return _attribute ? xml_node() : _node; } - xml_attribute xpath_node::attribute() const + PUGI__FN xml_attribute xpath_node::attribute() const { return _attribute; } - xml_node xpath_node::parent() const + PUGI__FN xml_node xpath_node::parent() const { return _attribute ? _node : _node.parent(); } - xpath_node::operator xpath_node::unspecified_bool_type() const + PUGI__FN static void unspecified_bool_xpath_node(xpath_node***) + { + } + + PUGI__FN xpath_node::operator xpath_node::unspecified_bool_type() const { - return (_node || _attribute) ? &xpath_node::_node : 0; + return (_node || _attribute) ? unspecified_bool_xpath_node : 0; } - bool xpath_node::operator!() const + PUGI__FN bool xpath_node::operator!() const { return !(_node || _attribute); } - bool xpath_node::operator==(const xpath_node& n) const + PUGI__FN bool xpath_node::operator==(const xpath_node& n) const { return _node == n._node && _attribute == n._attribute; } - bool xpath_node::operator!=(const xpath_node& n) const + PUGI__FN bool xpath_node::operator!=(const xpath_node& n) const { return _node != n._node || _attribute != n._attribute; } #ifdef __BORLANDC__ - bool operator&&(const xpath_node& lhs, bool rhs) + PUGI__FN bool operator&&(const xpath_node& lhs, bool rhs) { return (bool)lhs && rhs; } - bool operator||(const xpath_node& lhs, bool rhs) + PUGI__FN bool operator||(const xpath_node& lhs, bool rhs) { return (bool)lhs || rhs; } #endif - void xpath_node_set::_assign(const_iterator begin, const_iterator end) + PUGI__FN void xpath_node_set::_assign(const_iterator begin_, const_iterator end_) { - assert(begin <= end); + assert(begin_ <= end_); - size_t size = static_cast(end - begin); + size_t size_ = static_cast(end_ - begin_); - if (size <= 1) + if (size_ <= 1) { // deallocate old buffer - if (_begin != &_storage) global_deallocate(_begin); + if (_begin != &_storage) impl::xml_memory::deallocate(_begin); // use internal buffer - if (begin != end) _storage = *begin; + if (begin_ != end_) _storage = *begin_; _begin = &_storage; - _end = &_storage + size; + _end = &_storage + size_; } else { // make heap copy - xpath_node* storage = static_cast(global_allocate(size * sizeof(xpath_node))); + xpath_node* storage = static_cast(impl::xml_memory::allocate(size_ * sizeof(xpath_node))); if (!storage) { @@ -9100,37 +11017,37 @@ namespace pugi #endif } - memcpy(storage, begin, size * sizeof(xpath_node)); + memcpy(storage, begin_, size_ * sizeof(xpath_node)); // deallocate old buffer - if (_begin != &_storage) global_deallocate(_begin); + if (_begin != &_storage) impl::xml_memory::deallocate(_begin); // finalize _begin = storage; - _end = storage + size; + _end = storage + size_; } } - xpath_node_set::xpath_node_set(): _type(type_unsorted), _begin(&_storage), _end(&_storage) + PUGI__FN xpath_node_set::xpath_node_set(): _type(type_unsorted), _begin(&_storage), _end(&_storage) { } - xpath_node_set::xpath_node_set(const_iterator begin, const_iterator end, type_t type): _type(type), _begin(&_storage), _end(&_storage) + PUGI__FN xpath_node_set::xpath_node_set(const_iterator begin_, const_iterator end_, type_t type_): _type(type_), _begin(&_storage), _end(&_storage) { - _assign(begin, end); + _assign(begin_, end_); } - xpath_node_set::~xpath_node_set() + PUGI__FN xpath_node_set::~xpath_node_set() { - if (_begin != &_storage) global_deallocate(_begin); + if (_begin != &_storage) impl::xml_memory::deallocate(_begin); } - xpath_node_set::xpath_node_set(const xpath_node_set& ns): _type(ns._type), _begin(&_storage), _end(&_storage) + PUGI__FN xpath_node_set::xpath_node_set(const xpath_node_set& ns): _type(ns._type), _begin(&_storage), _end(&_storage) { _assign(ns._begin, ns._end); } - xpath_node_set& xpath_node_set::operator=(const xpath_node_set& ns) + PUGI__FN xpath_node_set& xpath_node_set::operator=(const xpath_node_set& ns) { if (this == &ns) return *this; @@ -9140,79 +11057,80 @@ namespace pugi return *this; } - xpath_node_set::type_t xpath_node_set::type() const + PUGI__FN xpath_node_set::type_t xpath_node_set::type() const { return _type; } - size_t xpath_node_set::size() const + PUGI__FN size_t xpath_node_set::size() const { return _end - _begin; } - bool xpath_node_set::empty() const + PUGI__FN bool xpath_node_set::empty() const { return _begin == _end; } - const xpath_node& xpath_node_set::operator[](size_t index) const + PUGI__FN const xpath_node& xpath_node_set::operator[](size_t index) const { assert(index < size()); return _begin[index]; } - xpath_node_set::const_iterator xpath_node_set::begin() const + PUGI__FN xpath_node_set::const_iterator xpath_node_set::begin() const { return _begin; } - xpath_node_set::const_iterator xpath_node_set::end() const + PUGI__FN xpath_node_set::const_iterator xpath_node_set::end() const { return _end; } - void xpath_node_set::sort(bool reverse) + PUGI__FN void xpath_node_set::sort(bool reverse) { - _type = xpath_sort(_begin, _end, _type, reverse); + _type = impl::xpath_sort(_begin, _end, _type, reverse); } - xpath_node xpath_node_set::first() const + PUGI__FN xpath_node xpath_node_set::first() const { - return xpath_first(_begin, _end, _type); + return impl::xpath_first(_begin, _end, _type); } - xpath_parse_result::xpath_parse_result(): error("Internal error"), offset(0) - { - } + PUGI__FN xpath_parse_result::xpath_parse_result(): error("Internal error"), offset(0) + { + } + + PUGI__FN xpath_parse_result::operator bool() const + { + return error == 0; + } - xpath_parse_result::operator bool() const - { - return error == 0; - } - const char* xpath_parse_result::description() const + PUGI__FN const char* xpath_parse_result::description() const { return error ? error : "No error"; } - xpath_variable::xpath_variable() - { - } + PUGI__FN xpath_variable::xpath_variable(): _type(xpath_type_none), _next(0) + { + } - const char_t* xpath_variable::name() const + PUGI__FN const char_t* xpath_variable::name() const { switch (_type) { case xpath_type_node_set: - return static_cast(this)->name; + return static_cast(this)->name; case xpath_type_number: - return static_cast(this)->name; + return static_cast(this)->name; case xpath_type_string: - return static_cast(this)->name; + return static_cast(this)->name; case xpath_type_boolean: - return static_cast(this)->name; + return static_cast(this)->name; default: assert(!"Invalid variable type"); @@ -9220,83 +11138,83 @@ namespace pugi } } - xpath_value_type xpath_variable::type() const + PUGI__FN xpath_value_type xpath_variable::type() const { return _type; } - bool xpath_variable::get_boolean() const + PUGI__FN bool xpath_variable::get_boolean() const { - return (_type == xpath_type_boolean) ? static_cast(this)->value : false; + return (_type == xpath_type_boolean) ? static_cast(this)->value : false; } - double xpath_variable::get_number() const + PUGI__FN double xpath_variable::get_number() const { - return (_type == xpath_type_number) ? static_cast(this)->value : gen_nan(); + return (_type == xpath_type_number) ? static_cast(this)->value : impl::gen_nan(); } - const char_t* xpath_variable::get_string() const + PUGI__FN const char_t* xpath_variable::get_string() const { - const char_t* value = (_type == xpath_type_string) ? static_cast(this)->value : 0; + const char_t* value = (_type == xpath_type_string) ? static_cast(this)->value : 0; return value ? value : PUGIXML_TEXT(""); } - const xpath_node_set& xpath_variable::get_node_set() const + PUGI__FN const xpath_node_set& xpath_variable::get_node_set() const { - return (_type == xpath_type_node_set) ? static_cast(this)->value : dummy_node_set; + return (_type == xpath_type_node_set) ? static_cast(this)->value : impl::dummy_node_set; } - bool xpath_variable::set(bool value) + PUGI__FN bool xpath_variable::set(bool value) { if (_type != xpath_type_boolean) return false; - static_cast(this)->value = value; + static_cast(this)->value = value; return true; } - bool xpath_variable::set(double value) + PUGI__FN bool xpath_variable::set(double value) { if (_type != xpath_type_number) return false; - static_cast(this)->value = value; + static_cast(this)->value = value; return true; } - bool xpath_variable::set(const char_t* value) + PUGI__FN bool xpath_variable::set(const char_t* value) { if (_type != xpath_type_string) return false; - xpath_variable_string* var = static_cast(this); + impl::xpath_variable_string* var = static_cast(this); // duplicate string - size_t size = (strlength(value) + 1) * sizeof(char_t); + size_t size = (impl::strlength(value) + 1) * sizeof(char_t); - char_t* copy = static_cast(global_allocate(size)); + char_t* copy = static_cast(impl::xml_memory::allocate(size)); if (!copy) return false; memcpy(copy, value, size); // replace old string - if (var->value) global_deallocate(var->value); + if (var->value) impl::xml_memory::deallocate(var->value); var->value = copy; return true; } - bool xpath_variable::set(const xpath_node_set& value) + PUGI__FN bool xpath_variable::set(const xpath_node_set& value) { if (_type != xpath_type_node_set) return false; - static_cast(this)->value = value; + static_cast(this)->value = value; return true; } - xpath_variable_set::xpath_variable_set() + PUGI__FN xpath_variable_set::xpath_variable_set() { for (size_t i = 0; i < sizeof(_data) / sizeof(_data[0]); ++i) _data[i] = 0; } - xpath_variable_set::~xpath_variable_set() + PUGI__FN xpath_variable_set::~xpath_variable_set() { for (size_t i = 0; i < sizeof(_data) / sizeof(_data[0]); ++i) { @@ -9306,38 +11224,38 @@ namespace pugi { xpath_variable* next = var->_next; - delete_xpath_variable(var->_type, var); + impl::delete_xpath_variable(var->_type, var); var = next; } } } - xpath_variable* xpath_variable_set::find(const char_t* name) const + PUGI__FN xpath_variable* xpath_variable_set::find(const char_t* name) const { const size_t hash_size = sizeof(_data) / sizeof(_data[0]); - size_t hash = hash_string(name) % hash_size; + size_t hash = impl::hash_string(name) % hash_size; // look for existing variable for (xpath_variable* var = _data[hash]; var; var = var->_next) - if (strequal(var->name(), name)) + if (impl::strequal(var->name(), name)) return var; return 0; } - xpath_variable* xpath_variable_set::add(const char_t* name, xpath_value_type type) + PUGI__FN xpath_variable* xpath_variable_set::add(const char_t* name, xpath_value_type type) { const size_t hash_size = sizeof(_data) / sizeof(_data[0]); - size_t hash = hash_string(name) % hash_size; + size_t hash = impl::hash_string(name) % hash_size; // look for existing variable for (xpath_variable* var = _data[hash]; var; var = var->_next) - if (strequal(var->name(), name)) + if (impl::strequal(var->name(), name)) return var->type() == type ? var : 0; // add new variable - xpath_variable* result = new_xpath_variable(type, name); + xpath_variable* result = impl::new_xpath_variable(type, name); if (result) { @@ -9350,208 +11268,268 @@ namespace pugi return result; } - bool xpath_variable_set::set(const char_t* name, bool value) + PUGI__FN bool xpath_variable_set::set(const char_t* name, bool value) { xpath_variable* var = add(name, xpath_type_boolean); return var ? var->set(value) : false; } - bool xpath_variable_set::set(const char_t* name, double value) + PUGI__FN bool xpath_variable_set::set(const char_t* name, double value) { xpath_variable* var = add(name, xpath_type_number); return var ? var->set(value) : false; } - bool xpath_variable_set::set(const char_t* name, const char_t* value) + PUGI__FN bool xpath_variable_set::set(const char_t* name, const char_t* value) { xpath_variable* var = add(name, xpath_type_string); return var ? var->set(value) : false; } - bool xpath_variable_set::set(const char_t* name, const xpath_node_set& value) + PUGI__FN bool xpath_variable_set::set(const char_t* name, const xpath_node_set& value) { xpath_variable* var = add(name, xpath_type_node_set); return var ? var->set(value) : false; } - xpath_variable* xpath_variable_set::get(const char_t* name) + PUGI__FN xpath_variable* xpath_variable_set::get(const char_t* name) { return find(name); } - const xpath_variable* xpath_variable_set::get(const char_t* name) const + PUGI__FN const xpath_variable* xpath_variable_set::get(const char_t* name) const { return find(name); } - xpath_query::xpath_query(const char_t* query, xpath_variable_set* variables): _impl(0) + PUGI__FN xpath_query::xpath_query(const char_t* query, xpath_variable_set* variables): _impl(0) { - xpath_query_impl* impl = xpath_query_impl::create(); + impl::xpath_query_impl* qimpl = impl::xpath_query_impl::create(); - if (!impl) + if (!qimpl) { #ifdef PUGIXML_NO_EXCEPTIONS _result.error = "Out of memory"; - #else + #else throw std::bad_alloc(); #endif } else { - buffer_holder impl_holder(impl, xpath_query_impl::destroy); + impl::buffer_holder impl_holder(qimpl, impl::xpath_query_impl::destroy); - impl->root = xpath_parser::parse(query, variables, &impl->alloc, &_result); + qimpl->root = impl::xpath_parser::parse(query, variables, &qimpl->alloc, &_result); - if (impl->root) + if (qimpl->root) { - _impl = static_cast(impl_holder.release()); + qimpl->root->optimize(&qimpl->alloc); + + _impl = static_cast(impl_holder.release()); _result.error = 0; } } } - xpath_query::~xpath_query() + PUGI__FN xpath_query::~xpath_query() { - xpath_query_impl::destroy(_impl); + impl::xpath_query_impl::destroy(_impl); } - xpath_value_type xpath_query::return_type() const + PUGI__FN xpath_value_type xpath_query::return_type() const { if (!_impl) return xpath_type_none; - return static_cast(_impl)->root->rettype(); + return static_cast(_impl)->root->rettype(); } - bool xpath_query::evaluate_boolean(const xpath_node& n) const + PUGI__FN bool xpath_query::evaluate_boolean(const xpath_node& n) const { if (!_impl) return false; - xpath_context c(n, 1, 1); - xpath_stack_data sd; + impl::xpath_context c(n, 1, 1); + impl::xpath_stack_data sd; #ifdef PUGIXML_NO_EXCEPTIONS if (setjmp(sd.error_handler)) return false; #endif - return static_cast(_impl)->root->eval_boolean(c, sd.stack); + return static_cast(_impl)->root->eval_boolean(c, sd.stack); } - double xpath_query::evaluate_number(const xpath_node& n) const + PUGI__FN double xpath_query::evaluate_number(const xpath_node& n) const { - if (!_impl) return gen_nan(); + if (!_impl) return impl::gen_nan(); - xpath_context c(n, 1, 1); - xpath_stack_data sd; + impl::xpath_context c(n, 1, 1); + impl::xpath_stack_data sd; #ifdef PUGIXML_NO_EXCEPTIONS - if (setjmp(sd.error_handler)) return gen_nan(); + if (setjmp(sd.error_handler)) return impl::gen_nan(); #endif - return static_cast(_impl)->root->eval_number(c, sd.stack); + return static_cast(_impl)->root->eval_number(c, sd.stack); } #ifndef PUGIXML_NO_STL - string_t xpath_query::evaluate_string(const xpath_node& n) const + PUGI__FN string_t xpath_query::evaluate_string(const xpath_node& n) const { - xpath_stack_data sd; + impl::xpath_stack_data sd; + + impl::xpath_string r = impl::evaluate_string_impl(static_cast(_impl), n, sd); - return evaluate_string_impl(static_cast(_impl), n, sd).c_str(); + return string_t(r.c_str(), r.length()); } #endif - size_t xpath_query::evaluate_string(char_t* buffer, size_t capacity, const xpath_node& n) const + PUGI__FN size_t xpath_query::evaluate_string(char_t* buffer, size_t capacity, const xpath_node& n) const { - xpath_stack_data sd; + impl::xpath_stack_data sd; - xpath_string r = evaluate_string_impl(static_cast(_impl), n, sd); + impl::xpath_string r = impl::evaluate_string_impl(static_cast(_impl), n, sd); size_t full_size = r.length() + 1; if (capacity > 0) - { - size_t size = (full_size < capacity) ? full_size : capacity; - assert(size > 0); + { + size_t size = (full_size < capacity) ? full_size : capacity; + assert(size > 0); - memcpy(buffer, r.c_str(), (size - 1) * sizeof(char_t)); - buffer[size - 1] = 0; - } + memcpy(buffer, r.c_str(), (size - 1) * sizeof(char_t)); + buffer[size - 1] = 0; + } return full_size; } - xpath_node_set xpath_query::evaluate_node_set(const xpath_node& n) const + PUGI__FN xpath_node_set xpath_query::evaluate_node_set(const xpath_node& n) const { - if (!_impl) return xpath_node_set(); - - xpath_ast_node* root = static_cast(_impl)->root; - - if (root->rettype() != xpath_type_node_set) - { - #ifdef PUGIXML_NO_EXCEPTIONS - return xpath_node_set(); - #else - xpath_parse_result result; - result.error = "Expression does not evaluate to node set"; + impl::xpath_ast_node* root = impl::evaluate_node_set_prepare(static_cast(_impl)); + if (!root) return xpath_node_set(); - throw xpath_exception(result); - #endif - } - - xpath_context c(n, 1, 1); - xpath_stack_data sd; + impl::xpath_context c(n, 1, 1); + impl::xpath_stack_data sd; #ifdef PUGIXML_NO_EXCEPTIONS if (setjmp(sd.error_handler)) return xpath_node_set(); #endif - xpath_node_set_raw r = root->eval_node_set(c, sd.stack); + impl::xpath_node_set_raw r = root->eval_node_set(c, sd.stack, impl::nodeset_eval_all); return xpath_node_set(r.begin(), r.end(), r.type()); } - const xpath_parse_result& xpath_query::result() const + PUGI__FN xpath_node xpath_query::evaluate_node(const xpath_node& n) const + { + impl::xpath_ast_node* root = impl::evaluate_node_set_prepare(static_cast(_impl)); + if (!root) return xpath_node(); + + impl::xpath_context c(n, 1, 1); + impl::xpath_stack_data sd; + + #ifdef PUGIXML_NO_EXCEPTIONS + if (setjmp(sd.error_handler)) return xpath_node(); + #endif + + impl::xpath_node_set_raw r = root->eval_node_set(c, sd.stack, impl::nodeset_eval_first); + + return r.first(); + } + + PUGI__FN const xpath_parse_result& xpath_query::result() const { return _result; } - xpath_query::operator xpath_query::unspecified_bool_type() const + PUGI__FN static void unspecified_bool_xpath_query(xpath_query***) { - return _impl ? &xpath_query::_impl : 0; } - bool xpath_query::operator!() const + PUGI__FN xpath_query::operator xpath_query::unspecified_bool_type() const + { + return _impl ? unspecified_bool_xpath_query : 0; + } + + PUGI__FN bool xpath_query::operator!() const { return !_impl; } - xpath_node xml_node::select_single_node(const char_t* query, xpath_variable_set* variables) const + PUGI__FN xpath_node xml_node::select_node(const char_t* query, xpath_variable_set* variables) const { xpath_query q(query, variables); - return select_single_node(q); + return select_node(q); } - xpath_node xml_node::select_single_node(const xpath_query& query) const + PUGI__FN xpath_node xml_node::select_node(const xpath_query& query) const { - xpath_node_set s = query.evaluate_node_set(*this); - return s.empty() ? xpath_node() : s.first(); + return query.evaluate_node(*this); } - xpath_node_set xml_node::select_nodes(const char_t* query, xpath_variable_set* variables) const + PUGI__FN xpath_node_set xml_node::select_nodes(const char_t* query, xpath_variable_set* variables) const { xpath_query q(query, variables); return select_nodes(q); } - xpath_node_set xml_node::select_nodes(const xpath_query& query) const + PUGI__FN xpath_node_set xml_node::select_nodes(const xpath_query& query) const { return query.evaluate_node_set(*this); } + + PUGI__FN xpath_node xml_node::select_single_node(const char_t* query, xpath_variable_set* variables) const + { + xpath_query q(query, variables); + return select_single_node(q); + } + + PUGI__FN xpath_node xml_node::select_single_node(const xpath_query& query) const + { + return query.evaluate_node(*this); + } } #endif +#ifdef __BORLANDC__ +# pragma option pop +#endif + +// Intel C++ does not properly keep warning state for function templates, +// so popping warning state at the end of translation unit leads to warnings in the middle. +#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) +# pragma warning(pop) +#endif + +// Undefine all local macros (makes sure we're not leaking macros in header-only mode) +#undef PUGI__NO_INLINE +#undef PUGI__UNLIKELY +#undef PUGI__STATIC_ASSERT +#undef PUGI__DMC_VOLATILE +#undef PUGI__MSVC_CRT_VERSION +#undef PUGI__NS_BEGIN +#undef PUGI__NS_END +#undef PUGI__FN +#undef PUGI__FN_NO_INLINE +#undef PUGI__NODETYPE +#undef PUGI__IS_CHARTYPE_IMPL +#undef PUGI__IS_CHARTYPE +#undef PUGI__IS_CHARTYPEX +#undef PUGI__ENDSWITH +#undef PUGI__SKIPWS +#undef PUGI__OPTSET +#undef PUGI__PUSHNODE +#undef PUGI__POPNODE +#undef PUGI__SCANFOR +#undef PUGI__SCANWHILE +#undef PUGI__SCANWHILE_UNROLL +#undef PUGI__ENDSEG +#undef PUGI__THROW_ERROR +#undef PUGI__CHECK_ERROR + +#endif + /** - * Copyright (c) 2006-2010 Arseny Kapoulkine + * Copyright (c) 2006-2015 Arseny Kapoulkine * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation diff --git a/src/pugixmlLib/src/pugixml.hpp b/src/pugixmlLib/src/pugixml.hpp index 78959ac..d59f864 100644 --- a/src/pugixmlLib/src/pugixml.hpp +++ b/src/pugixmlLib/src/pugixml.hpp @@ -1,7 +1,7 @@ /** - * pugixml parser - version 1.0 + * pugixml parser - version 1.6 * -------------------------------------------------------- - * Copyright (C) 2006-2010, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com) + * Copyright (C) 2006-2015, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com) * Report bugs and download new versions at http://pugixml.org/ * * This library is distributed under the MIT License. See notice at the end @@ -11,38 +11,30 @@ * Copyright (C) 2003, by Kristen Wegner (kristen@tima.net) */ +#ifndef PUGIXML_VERSION +// Define version macro; evaluates to major * 100 + minor so that it's safe to use in less-than comparisons +# define PUGIXML_VERSION 160 +#endif + +// Include user configuration file (this can define various configuration macros) +#include "pugiconfig.hpp" + #ifndef HEADER_PUGIXML_HPP #define HEADER_PUGIXML_HPP -#include "pugiconfig.hpp" +// Include stddef.h for size_t and ptrdiff_t +#include -#ifndef PUGIXML_NO_STL -namespace std -{ - struct bidirectional_iterator_tag; - -#ifdef __SUNPRO_CC - // Sun C++ compiler has a bug which forces template argument names in forward declarations to be the same as in actual definitions - template class allocator; - template struct char_traits; - template class basic_istream; - template class basic_ostream; - template class basic_string; -#else - // Borland C++ compiler has a bug which forces template argument names in forward declarations to be the same as in actual definitions - template class allocator; - template struct char_traits; - template class basic_istream; - template class basic_ostream; - template class basic_string; +// Include exception header for XPath +#if !defined(PUGIXML_NO_XPATH) && !defined(PUGIXML_NO_EXCEPTIONS) +# include #endif - // Digital Mars compiler has a bug which requires a forward declaration for explicit instantiation (otherwise type selection is messed up later, producing link errors) - // Also note that we have to declare char_traits as a class here, since it's defined that way -#ifdef __DMC__ - template <> class char_traits; -#endif -} +// Include STL headers +#ifndef PUGIXML_NO_STL +# include +# include +# include #endif // Macro for deprecated features @@ -56,27 +48,29 @@ namespace std # endif #endif -// Include exception header for XPath -#if !defined(PUGIXML_NO_XPATH) && !defined(PUGIXML_NO_EXCEPTIONS) -# include -#endif - // If no API is defined, assume default #ifndef PUGIXML_API -# define PUGIXML_API +# define PUGIXML_API #endif // If no API for classes is defined, assume default #ifndef PUGIXML_CLASS -# define PUGIXML_CLASS PUGIXML_API +# define PUGIXML_CLASS PUGIXML_API #endif // If no API for functions is defined, assume default #ifndef PUGIXML_FUNCTION -# define PUGIXML_FUNCTION PUGIXML_API +# define PUGIXML_FUNCTION PUGIXML_API #endif -#include +// If the platform is known to have long long support, enable long long functions +#ifndef PUGIXML_HAS_LONG_LONG +# if defined(__cplusplus) && __cplusplus >= 201103 +# define PUGIXML_HAS_LONG_LONG +# elif defined(_MSC_VER) && _MSC_VER >= 1400 +# define PUGIXML_HAS_LONG_LONG +# endif +#endif // Character interface macros #ifdef PUGIXML_WCHAR_MODE @@ -104,7 +98,7 @@ namespace pugi // Tree node types enum xml_node_type { - node_null, // Empty (null) node handle + node_null, // Empty (null) node handle node_document, // A document tree's absolute root node_element, // Element tag, i.e. '' node_pcdata, // Plain character data, i.e. 'text' @@ -112,13 +106,13 @@ namespace pugi node_comment, // Comment tag, i.e. '' node_pi, // Processing instruction, i.e. '' node_declaration, // Document declaration, i.e. '' - node_doctype // Document type declaration, i.e. '' + node_doctype // Document type declaration, i.e. '' }; // Parsing options // Minimal parsing mode (equivalent to turning all other flags off). - // Only elements and PCDATA sections are added to the DOM tree, no text conversions are performed. + // Only elements and PCDATA sections are added to the DOM tree, no text conversions are performed. const unsigned int parse_minimal = 0x0000; // This flag determines if processing instructions (node_pi) are added to the DOM tree. This flag is off by default. @@ -131,7 +125,7 @@ namespace pugi const unsigned int parse_cdata = 0x0004; // This flag determines if plain character data (node_pcdata) that consist only of whitespace are added to the DOM tree. - // This flag is off by default; turning it on usually results in slower parsing and more memory consumption. + // This flag is off by default; turning it on usually results in slower parsing and more memory consumption. const unsigned int parse_ws_pcdata = 0x0008; // This flag determines if character and entity references are expanded during parsing. This flag is on by default. @@ -140,40 +134,53 @@ namespace pugi // This flag determines if EOL characters are normalized (converted to #xA) during parsing. This flag is on by default. const unsigned int parse_eol = 0x0020; - // This flag determines if attribute values are normalized using CDATA normalization rules during parsing. This flag is on by default. - const unsigned int parse_wconv_attribute = 0x0040; + // This flag determines if attribute values are normalized using CDATA normalization rules during parsing. This flag is on by default. + const unsigned int parse_wconv_attribute = 0x0040; - // This flag determines if attribute values are normalized using NMTOKENS normalization rules during parsing. This flag is off by default. - const unsigned int parse_wnorm_attribute = 0x0080; + // This flag determines if attribute values are normalized using NMTOKENS normalization rules during parsing. This flag is off by default. + const unsigned int parse_wnorm_attribute = 0x0080; - // This flag determines if document declaration (node_declaration) is added to the DOM tree. This flag is off by default. + // This flag determines if document declaration (node_declaration) is added to the DOM tree. This flag is off by default. const unsigned int parse_declaration = 0x0100; - // This flag determines if document type declaration (node_doctype) is added to the DOM tree. This flag is off by default. + // This flag determines if document type declaration (node_doctype) is added to the DOM tree. This flag is off by default. const unsigned int parse_doctype = 0x0200; + // This flag determines if plain character data (node_pcdata) that is the only child of the parent node and that consists only + // of whitespace is added to the DOM tree. + // This flag is off by default; turning it on may result in slower parsing and more memory consumption. + const unsigned int parse_ws_pcdata_single = 0x0400; + + // This flag determines if leading and trailing whitespace is to be removed from plain character data. This flag is off by default. + const unsigned int parse_trim_pcdata = 0x0800; + + // This flag determines if plain character data that does not have a parent node is added to the DOM tree, and if an empty document + // is a valid document. This flag is off by default. + const unsigned int parse_fragment = 0x1000; + // The default parsing mode. - // Elements, PCDATA and CDATA sections are added to the DOM tree, character/reference entities are expanded, - // End-of-Line characters are normalized, attribute values are normalized using CDATA normalization rules. + // Elements, PCDATA and CDATA sections are added to the DOM tree, character/reference entities are expanded, + // End-of-Line characters are normalized, attribute values are normalized using CDATA normalization rules. const unsigned int parse_default = parse_cdata | parse_escapes | parse_wconv_attribute | parse_eol; - // The full parsing mode. - // Nodes of all types are added to the DOM tree, character/reference entities are expanded, - // End-of-Line characters are normalized, attribute values are normalized using CDATA normalization rules. - const unsigned int parse_full = parse_default | parse_pi | parse_comments | parse_declaration | parse_doctype; + // The full parsing mode. + // Nodes of all types are added to the DOM tree, character/reference entities are expanded, + // End-of-Line characters are normalized, attribute values are normalized using CDATA normalization rules. + const unsigned int parse_full = parse_default | parse_pi | parse_comments | parse_declaration | parse_doctype; // These flags determine the encoding of input data for XML document enum xml_encoding { - encoding_auto, // Auto-detect input encoding using BOM or < / class xml_object_range + { + public: + typedef It const_iterator; + typedef It iterator; + + xml_object_range(It b, It e): _begin(b), _end(e) + { + } + + It begin() const { return _begin; } + It end() const { return _end; } + + private: + It _begin, _end; + }; + // Writer interface for node printing (see xml_node::print) class PUGIXML_CLASS xml_writer { @@ -226,7 +262,7 @@ namespace pugi class PUGIXML_CLASS xml_writer_file: public xml_writer { public: - // Construct writer from a FILE* object; void* is used to avoid header dependencies on stdio + // Construct writer from a FILE* object; void* is used to avoid header dependencies on stdio xml_writer_file(void* file); virtual void write(const void* data, size_t size); @@ -240,7 +276,7 @@ namespace pugi class PUGIXML_CLASS xml_writer_stream: public xml_writer { public: - // Construct writer from an output stream object + // Construct writer from an output stream object xml_writer_stream(std::basic_ostream >& stream); xml_writer_stream(std::basic_ostream >& stream); @@ -261,20 +297,20 @@ namespace pugi private: xml_attribute_struct* _attr; - typedef xml_attribute_struct* xml_attribute::*unspecified_bool_type; + typedef void (*unspecified_bool_type)(xml_attribute***); public: - // Default constructor. Constructs an empty attribute. + // Default constructor. Constructs an empty attribute. xml_attribute(); - // Constructs attribute from internal pointer + // Constructs attribute from internal pointer explicit xml_attribute(xml_attribute_struct* attr); - // Safe bool conversion operator - operator unspecified_bool_type() const; + // Safe bool conversion operator + operator unspecified_bool_type() const; - // Borland C++ workaround - bool operator!() const; + // Borland C++ workaround + bool operator!() const; // Comparison operators (compares wrapped attribute pointers) bool operator==(const xml_attribute& r) const; @@ -291,38 +327,58 @@ namespace pugi const char_t* name() const; const char_t* value() const; - // Get attribute value as a number, or 0 if conversion did not succeed or attribute is empty - int as_int() const; - unsigned int as_uint() const; - double as_double() const; - float as_float() const; + // Get attribute value, or the default value if attribute is empty + const char_t* as_string(const char_t* def = PUGIXML_TEXT("")) const; - // Get attribute value as bool (returns true if first character is in '1tTyY' set), or false if attribute is empty - bool as_bool() const; + // Get attribute value as a number, or the default value if conversion did not succeed or attribute is empty + int as_int(int def = 0) const; + unsigned int as_uint(unsigned int def = 0) const; + double as_double(double def = 0) const; + float as_float(float def = 0) const; - // Set attribute name/value (returns false if attribute is empty or there is not enough memory) + #ifdef PUGIXML_HAS_LONG_LONG + long long as_llong(long long def = 0) const; + unsigned long long as_ullong(unsigned long long def = 0) const; + #endif + + // Get attribute value as bool (returns true if first character is in '1tTyY' set), or the default value if attribute is empty + bool as_bool(bool def = false) const; + + // Set attribute name/value (returns false if attribute is empty or there is not enough memory) bool set_name(const char_t* rhs); bool set_value(const char_t* rhs); - // Set attribute value with type conversion (numbers are converted to strings, boolean is converted to "true"/"false") + // Set attribute value with type conversion (numbers are converted to strings, boolean is converted to "true"/"false") bool set_value(int rhs); bool set_value(unsigned int rhs); bool set_value(double rhs); + bool set_value(float rhs); bool set_value(bool rhs); + #ifdef PUGIXML_HAS_LONG_LONG + bool set_value(long long rhs); + bool set_value(unsigned long long rhs); + #endif + // Set attribute value (equivalent to set_value without error checking) xml_attribute& operator=(const char_t* rhs); xml_attribute& operator=(int rhs); xml_attribute& operator=(unsigned int rhs); xml_attribute& operator=(double rhs); + xml_attribute& operator=(float rhs); xml_attribute& operator=(bool rhs); - // Get next/previous attribute in the attribute list of the parent node - xml_attribute next_attribute() const; - xml_attribute previous_attribute() const; + #ifdef PUGIXML_HAS_LONG_LONG + xml_attribute& operator=(long long rhs); + xml_attribute& operator=(unsigned long long rhs); + #endif - // Get hash value (unique for handles to the same object) - size_t hash_value() const; + // Get next/previous attribute in the attribute list of the parent node + xml_attribute next_attribute() const; + xml_attribute previous_attribute() const; + + // Get hash value (unique for handles to the same object) + size_t hash_value() const; // Get internal pointer xml_attribute_struct* internal_object() const; @@ -339,20 +395,21 @@ namespace pugi { friend class xml_attribute_iterator; friend class xml_node_iterator; + friend class xml_named_node_iterator; protected: xml_node_struct* _root; - typedef xml_node_struct* xml_node::*unspecified_bool_type; + typedef void (*unspecified_bool_type)(xml_node***); public: // Default constructor. Constructs an empty node. xml_node(); - // Constructs node from internal pointer + // Constructs node from internal pointer explicit xml_node(xml_node_struct* p); - // Safe bool conversion operator + // Safe bool conversion operator operator unspecified_bool_type() const; // Borland C++ workaround @@ -372,28 +429,34 @@ namespace pugi // Get node type xml_node_type type() const; - // Get node name/value, or "" if node is empty or it has no name/value + // Get node name, or "" if node is empty or it has no name const char_t* name() const; + + // Get node value, or "" if node is empty or it has no value + // Note: For text node.value() does not return "text"! Use child_value() or text() methods to access text inside nodes. const char_t* value() const; // Get attribute list xml_attribute first_attribute() const; - xml_attribute last_attribute() const; + xml_attribute last_attribute() const; - // Get children list + // Get children list xml_node first_child() const; - xml_node last_child() const; + xml_node last_child() const; - // Get next/previous sibling in the children list of the parent node + // Get next/previous sibling in the children list of the parent node xml_node next_sibling() const; xml_node previous_sibling() const; - // Get parent node + // Get parent node xml_node parent() const; // Get root of DOM tree this node belongs to xml_node root() const; + // Get text object for the current node + xml_text text() const; + // Get child, attribute or next/previous sibling with the specified name xml_node child(const char_t* name) const; xml_attribute attribute(const char_t* name) const; @@ -440,6 +503,12 @@ namespace pugi xml_node insert_copy_after(const xml_node& proto, const xml_node& node); xml_node insert_copy_before(const xml_node& proto, const xml_node& node); + // Move the specified node to become a child of this node. Returns moved node, or empty node on errors. + xml_node append_move(const xml_node& moved); + xml_node prepend_move(const xml_node& moved); + xml_node insert_move_after(const xml_node& moved, const xml_node& node); + xml_node insert_move_before(const xml_node& moved, const xml_node& node); + // Remove specified attribute bool remove_attribute(const xml_attribute& a); bool remove_attribute(const char_t* name); @@ -448,6 +517,11 @@ namespace pugi bool remove_child(const xml_node& n); bool remove_child(const char_t* name); + // Parses buffer as an XML document fragment and appends all nodes as children of the current node. + // Copies/converts the buffer, so it may be deleted or changed after the function returns. + // Note: append_buffer allocates memory that has the lifetime of the owning document; removing the appended nodes does not immediately reclaim that memory. + xml_parse_result append_buffer(const void* contents, size_t size, unsigned int options = parse_default, xml_encoding encoding = encoding_auto); + // Find attribute using predicate. Returns first attribute for which predicate returned true. template xml_attribute find_attribute(Predicate pred) const { @@ -468,8 +542,8 @@ namespace pugi for (xml_node node = first_child(); node; node = node.next_sibling()) if (pred(node)) return node; - - return xml_node(); + + return xml_node(); } // Find node from subtree using predicate. Returns first node from subtree (depth-first), for which predicate returned true. @@ -513,12 +587,17 @@ namespace pugi #ifndef PUGIXML_NO_XPATH // Select single node by evaluating XPath query. Returns first node from the resulting node set. - xpath_node select_single_node(const char_t* query, xpath_variable_set* variables = 0) const; - xpath_node select_single_node(const xpath_query& query) const; + xpath_node select_node(const char_t* query, xpath_variable_set* variables = 0) const; + xpath_node select_node(const xpath_query& query) const; // Select node set by evaluating XPath query xpath_node_set select_nodes(const char_t* query, xpath_variable_set* variables = 0) const; xpath_node_set select_nodes(const xpath_query& query) const; + + // (deprecated: use select_node instead) Select single node by evaluating XPath query. + xpath_node select_single_node(const char_t* query, xpath_variable_set* variables = 0) const; + xpath_node select_single_node(const xpath_query& query) const; + #endif // Print subtree using a writer object @@ -542,11 +621,16 @@ namespace pugi attribute_iterator attributes_begin() const; attribute_iterator attributes_end() const; + // Range-based for support + xml_object_range children() const; + xml_object_range children(const char_t* name) const; + xml_object_range attributes() const; + // Get node offset in parsed file/string (in char_t units) for debugging purposes ptrdiff_t offset_debug() const; - // Get hash value (unique for handles to the same object) - size_t hash_value() const; + // Get hash value (unique for handles to the same object) + size_t hash_value() const; // Get internal pointer xml_node_struct* internal_object() const; @@ -558,13 +642,98 @@ namespace pugi bool PUGIXML_FUNCTION operator||(const xml_node& lhs, bool rhs); #endif + // A helper for working with text inside PCDATA nodes + class PUGIXML_CLASS xml_text + { + friend class xml_node; + + xml_node_struct* _root; + + typedef void (*unspecified_bool_type)(xml_text***); + + explicit xml_text(xml_node_struct* root); + + xml_node_struct* _data_new(); + xml_node_struct* _data() const; + + public: + // Default constructor. Constructs an empty object. + xml_text(); + + // Safe bool conversion operator + operator unspecified_bool_type() const; + + // Borland C++ workaround + bool operator!() const; + + // Check if text object is empty + bool empty() const; + + // Get text, or "" if object is empty + const char_t* get() const; + + // Get text, or the default value if object is empty + const char_t* as_string(const char_t* def = PUGIXML_TEXT("")) const; + + // Get text as a number, or the default value if conversion did not succeed or object is empty + int as_int(int def = 0) const; + unsigned int as_uint(unsigned int def = 0) const; + double as_double(double def = 0) const; + float as_float(float def = 0) const; + + #ifdef PUGIXML_HAS_LONG_LONG + long long as_llong(long long def = 0) const; + unsigned long long as_ullong(unsigned long long def = 0) const; + #endif + + // Get text as bool (returns true if first character is in '1tTyY' set), or the default value if object is empty + bool as_bool(bool def = false) const; + + // Set text (returns false if object is empty or there is not enough memory) + bool set(const char_t* rhs); + + // Set text with type conversion (numbers are converted to strings, boolean is converted to "true"/"false") + bool set(int rhs); + bool set(unsigned int rhs); + bool set(double rhs); + bool set(float rhs); + bool set(bool rhs); + + #ifdef PUGIXML_HAS_LONG_LONG + bool set(long long rhs); + bool set(unsigned long long rhs); + #endif + + // Set text (equivalent to set without error checking) + xml_text& operator=(const char_t* rhs); + xml_text& operator=(int rhs); + xml_text& operator=(unsigned int rhs); + xml_text& operator=(double rhs); + xml_text& operator=(float rhs); + xml_text& operator=(bool rhs); + + #ifdef PUGIXML_HAS_LONG_LONG + xml_text& operator=(long long rhs); + xml_text& operator=(unsigned long long rhs); + #endif + + // Get the data node (node_pcdata or node_cdata) for this object + xml_node data() const; + }; + +#ifdef __BORLANDC__ + // Borland C++ workaround + bool PUGIXML_FUNCTION operator&&(const xml_text& lhs, bool rhs); + bool PUGIXML_FUNCTION operator||(const xml_text& lhs, bool rhs); +#endif + // Child node iterator (a bidirectional iterator over a collection of xml_node) class PUGIXML_CLASS xml_node_iterator { friend class xml_node; private: - xml_node _wrap; + mutable xml_node _wrap; xml_node _parent; xml_node_iterator(xml_node_struct* ref, xml_node_struct* parent); @@ -580,18 +749,18 @@ namespace pugi typedef std::bidirectional_iterator_tag iterator_category; #endif - // Default constructor + // Default constructor xml_node_iterator(); - // Construct an iterator which points to the specified node + // Construct an iterator which points to the specified node xml_node_iterator(const xml_node& node); - // Iterator operators + // Iterator operators bool operator==(const xml_node_iterator& rhs) const; bool operator!=(const xml_node_iterator& rhs) const; - xml_node& operator*(); - xml_node* operator->(); + xml_node& operator*() const; + xml_node* operator->() const; const xml_node_iterator& operator++(); xml_node_iterator operator++(int); @@ -606,7 +775,7 @@ namespace pugi friend class xml_node; private: - xml_attribute _wrap; + mutable xml_attribute _wrap; xml_node _parent; xml_attribute_iterator(xml_attribute_struct* ref, xml_node_struct* parent); @@ -622,18 +791,18 @@ namespace pugi typedef std::bidirectional_iterator_tag iterator_category; #endif - // Default constructor + // Default constructor xml_attribute_iterator(); - // Construct an iterator which points to the specified attribute + // Construct an iterator which points to the specified attribute xml_attribute_iterator(const xml_attribute& attr, const xml_node& parent); // Iterator operators bool operator==(const xml_attribute_iterator& rhs) const; bool operator!=(const xml_attribute_iterator& rhs) const; - xml_attribute& operator*(); - xml_attribute* operator->(); + xml_attribute& operator*() const; + xml_attribute* operator->() const; const xml_attribute_iterator& operator++(); xml_attribute_iterator operator++(int); @@ -642,6 +811,49 @@ namespace pugi xml_attribute_iterator operator--(int); }; + // Named node range helper + class PUGIXML_CLASS xml_named_node_iterator + { + friend class xml_node; + + public: + // Iterator traits + typedef ptrdiff_t difference_type; + typedef xml_node value_type; + typedef xml_node* pointer; + typedef xml_node& reference; + + #ifndef PUGIXML_NO_STL + typedef std::bidirectional_iterator_tag iterator_category; + #endif + + // Default constructor + xml_named_node_iterator(); + + // Construct an iterator which points to the specified node + xml_named_node_iterator(const xml_node& node, const char_t* name); + + // Iterator operators + bool operator==(const xml_named_node_iterator& rhs) const; + bool operator!=(const xml_named_node_iterator& rhs) const; + + xml_node& operator*() const; + xml_node* operator->() const; + + const xml_named_node_iterator& operator++(); + xml_named_node_iterator operator++(int); + + const xml_named_node_iterator& operator--(); + xml_named_node_iterator operator--(int); + + private: + mutable xml_node _wrap; + xml_node _parent; + const char_t* _name; + + xml_named_node_iterator(xml_node_struct* ref, xml_node_struct* parent, const char_t* name); + }; + // Abstract tree walker class (see xml_node::traverse) class PUGIXML_CLASS xml_tree_walker { @@ -671,24 +883,28 @@ namespace pugi // Parsing status, returned as part of xml_parse_result object enum xml_parse_status { - status_ok = 0, // No error - - status_file_not_found, // File was not found during load_file() - status_io_error, // Error reading from file/stream - status_out_of_memory, // Could not allocate memory - status_internal_error, // Internal error occurred - - status_unrecognized_tag, // Parser could not determine tag type - - status_bad_pi, // Parsing error occurred while parsing document declaration/processing instruction - status_bad_comment, // Parsing error occurred while parsing comment - status_bad_cdata, // Parsing error occurred while parsing CDATA section - status_bad_doctype, // Parsing error occurred while parsing document type declaration - status_bad_pcdata, // Parsing error occurred while parsing PCDATA section - status_bad_start_element, // Parsing error occurred while parsing start element tag - status_bad_attribute, // Parsing error occurred while parsing element attribute - status_bad_end_element, // Parsing error occurred while parsing end element tag - status_end_element_mismatch // There was a mismatch of start-end tags (closing tag had incorrect name, some tag was not closed or there was an excessive closing tag) + status_ok = 0, // No error + + status_file_not_found, // File was not found during load_file() + status_io_error, // Error reading from file/stream + status_out_of_memory, // Could not allocate memory + status_internal_error, // Internal error occurred + + status_unrecognized_tag, // Parser could not determine tag type + + status_bad_pi, // Parsing error occurred while parsing document declaration/processing instruction + status_bad_comment, // Parsing error occurred while parsing comment + status_bad_cdata, // Parsing error occurred while parsing CDATA section + status_bad_doctype, // Parsing error occurred while parsing document type declaration + status_bad_pcdata, // Parsing error occurred while parsing PCDATA section + status_bad_start_element, // Parsing error occurred while parsing start element tag + status_bad_attribute, // Parsing error occurred while parsing element attribute + status_bad_end_element, // Parsing error occurred while parsing end element tag + status_end_element_mismatch,// There was a mismatch of start-end tags (closing tag had incorrect name, some tag was not closed or there was an excessive closing tag) + + status_append_invalid_root, // Unable to append nodes since root type is not node_element or node_document (exclusive to xml_node::append_buffer) + + status_no_document_element // Parsing resulted in a document without element nodes }; // Parsing result @@ -703,7 +919,7 @@ namespace pugi // Source document encoding xml_encoding encoding; - // Default constructor, initializes object to failed state + // Default constructor, initializes object to failed state xml_parse_result(); // Cast to bool operator @@ -728,8 +944,6 @@ namespace pugi void create(); void destroy(); - xml_parse_result load_buffer_impl(void* contents, size_t size, unsigned int options, xml_encoding encoding, bool is_mutable, bool own); - public: // Default constructor, makes empty document xml_document(); @@ -737,10 +951,10 @@ namespace pugi // Destructor, invalidates all node/attribute handles to this document ~xml_document(); - // Removes all nodes, leaving the empty document + // Removes all nodes, leaving the empty document void reset(); - // Removes all nodes, then copies the entire contents of the specified document + // Removes all nodes, then copies the entire contents of the specified document void reset(const xml_document& proto); #ifndef PUGIXML_NO_STL @@ -749,9 +963,12 @@ namespace pugi xml_parse_result load(std::basic_istream >& stream, unsigned int options = parse_default); #endif - // Load document from zero-terminated string. No encoding conversions are applied. + // (deprecated: use load_string instead) Load document from zero-terminated string. No encoding conversions are applied. xml_parse_result load(const char_t* contents, unsigned int options = parse_default); + // Load document from zero-terminated string. No encoding conversions are applied. + xml_parse_result load_string(const char_t* contents, unsigned int options = parse_default); + // Load document from file xml_parse_result load_file(const char* path, unsigned int options = parse_default, xml_encoding encoding = encoding_auto); xml_parse_result load_file(const wchar_t* path, unsigned int options = parse_default, xml_encoding encoding = encoding_auto); @@ -760,11 +977,11 @@ namespace pugi xml_parse_result load_buffer(const void* contents, size_t size, unsigned int options = parse_default, xml_encoding encoding = encoding_auto); // Load document from buffer, using the buffer for in-place parsing (the buffer is modified and used for storage of document data). - // You should ensure that buffer data will persist throughout the document's lifetime, and free the buffer memory manually once document is destroyed. + // You should ensure that buffer data will persist throughout the document's lifetime, and free the buffer memory manually once document is destroyed. xml_parse_result load_buffer_inplace(void* contents, size_t size, unsigned int options = parse_default, xml_encoding encoding = encoding_auto); // Load document from buffer, using the buffer for in-place parsing (the buffer is modified and used for storage of document data). - // You should allocate the buffer with pugixml allocation function; document will free the buffer when it is no longer needed (you can't use it anymore). + // You should allocate the buffer with pugixml allocation function; document will free the buffer when it is no longer needed (you can't use it anymore). xml_parse_result load_buffer_inplace_own(void* contents, size_t size, unsigned int options = parse_default, xml_encoding encoding = encoding_auto); // Save XML document to writer (semantics is slightly different from xml_node::print, see documentation for details). @@ -780,22 +997,22 @@ namespace pugi bool save_file(const char* path, const char_t* indent = PUGIXML_TEXT("\t"), unsigned int flags = format_default, xml_encoding encoding = encoding_auto) const; bool save_file(const wchar_t* path, const char_t* indent = PUGIXML_TEXT("\t"), unsigned int flags = format_default, xml_encoding encoding = encoding_auto) const; - // Get document element - xml_node document_element() const; + // Get document element + xml_node document_element() const; }; #ifndef PUGIXML_NO_XPATH // XPath query return type enum xpath_value_type { - xpath_type_none, // Unknown type (query failed to compile) + xpath_type_none, // Unknown type (query failed to compile) xpath_type_node_set, // Node set (xpath_node_set) - xpath_type_number, // Number - xpath_type_string, // String - xpath_type_boolean // Boolean + xpath_type_number, // Number + xpath_type_string, // String + xpath_type_boolean // Boolean }; - // XPath parsing result + // XPath parsing result struct PUGIXML_CLASS xpath_parse_result { // Error message (0 if no error) @@ -804,7 +1021,7 @@ namespace pugi // Last parsed offset (in char_t units from string start) ptrdiff_t offset; - // Default constructor, initializes object to failed state + // Default constructor, initializes object to failed state xpath_parse_result(); // Cast to bool operator @@ -830,19 +1047,19 @@ namespace pugi xpath_variable& operator=(const xpath_variable&); public: - // Get variable name + // Get variable name const char_t* name() const; - // Get variable type + // Get variable type xpath_value_type type() const; - // Get variable value; no type conversion is performed, default value (false, NaN, empty string, empty node set) is returned on type mismatch error + // Get variable value; no type conversion is performed, default value (false, NaN, empty string, empty node set) is returned on type mismatch error bool get_boolean() const; double get_number() const; const char_t* get_string() const; const xpath_node_set& get_node_set() const; - // Set variable value; no type conversion is performed, false is returned on type mismatch error + // Set variable value; no type conversion is performed, false is returned on type mismatch error bool set(bool value); bool set(double value); bool set(const char_t* value); @@ -862,20 +1079,20 @@ namespace pugi xpath_variable* find(const char_t* name) const; public: - // Default constructor/destructor + // Default constructor/destructor xpath_variable_set(); ~xpath_variable_set(); - // Add a new variable or get the existing one, if the types match + // Add a new variable or get the existing one, if the types match xpath_variable* add(const char_t* name, xpath_value_type type); - // Set value of an existing variable; no type conversion is performed, false is returned if there is no such variable or if types mismatch + // Set value of an existing variable; no type conversion is performed, false is returned if there is no such variable or if types mismatch bool set(const char_t* name, bool value); bool set(const char_t* name, double value); bool set(const char_t* name, const char_t* value); bool set(const char_t* name, const xpath_node_set& value); - // Get existing variable by name + // Get existing variable by name xpath_variable* get(const char_t* name); const xpath_variable* get(const char_t* name) const; }; @@ -887,15 +1104,15 @@ namespace pugi void* _impl; xpath_parse_result _result; - typedef void* xpath_query::*unspecified_bool_type; + typedef void (*unspecified_bool_type)(xpath_query***); // Non-copyable semantics xpath_query(const xpath_query&); xpath_query& operator=(const xpath_query&); public: - // Construct a compiled object from XPath expression. - // If PUGIXML_NO_EXCEPTIONS is not defined, throws xpath_exception on compilation errors. + // Construct a compiled object from XPath expression. + // If PUGIXML_NO_EXCEPTIONS is not defined, throws xpath_exception on compilation errors. explicit xpath_query(const char_t* query, xpath_variable_set* variables = 0); // Destructor @@ -905,37 +1122,43 @@ namespace pugi xpath_value_type return_type() const; // Evaluate expression as boolean value in the specified context; performs type conversion if necessary. - // If PUGIXML_NO_EXCEPTIONS is not defined, throws std::bad_alloc on out of memory errors. + // If PUGIXML_NO_EXCEPTIONS is not defined, throws std::bad_alloc on out of memory errors. bool evaluate_boolean(const xpath_node& n) const; // Evaluate expression as double value in the specified context; performs type conversion if necessary. - // If PUGIXML_NO_EXCEPTIONS is not defined, throws std::bad_alloc on out of memory errors. + // If PUGIXML_NO_EXCEPTIONS is not defined, throws std::bad_alloc on out of memory errors. double evaluate_number(const xpath_node& n) const; #ifndef PUGIXML_NO_STL // Evaluate expression as string value in the specified context; performs type conversion if necessary. - // If PUGIXML_NO_EXCEPTIONS is not defined, throws std::bad_alloc on out of memory errors. + // If PUGIXML_NO_EXCEPTIONS is not defined, throws std::bad_alloc on out of memory errors. string_t evaluate_string(const xpath_node& n) const; #endif // Evaluate expression as string value in the specified context; performs type conversion if necessary. - // At most capacity characters are written to the destination buffer, full result size is returned (includes terminating zero). - // If PUGIXML_NO_EXCEPTIONS is not defined, throws std::bad_alloc on out of memory errors. - // If PUGIXML_NO_EXCEPTIONS is defined, returns empty set instead. + // At most capacity characters are written to the destination buffer, full result size is returned (includes terminating zero). + // If PUGIXML_NO_EXCEPTIONS is not defined, throws std::bad_alloc on out of memory errors. + // If PUGIXML_NO_EXCEPTIONS is defined, returns empty set instead. size_t evaluate_string(char_t* buffer, size_t capacity, const xpath_node& n) const; // Evaluate expression as node set in the specified context. - // If PUGIXML_NO_EXCEPTIONS is not defined, throws xpath_exception on type mismatch and std::bad_alloc on out of memory errors. - // If PUGIXML_NO_EXCEPTIONS is defined, returns empty node set instead. + // If PUGIXML_NO_EXCEPTIONS is not defined, throws xpath_exception on type mismatch and std::bad_alloc on out of memory errors. + // If PUGIXML_NO_EXCEPTIONS is defined, returns empty node set instead. xpath_node_set evaluate_node_set(const xpath_node& n) const; + // Evaluate expression as node set in the specified context. + // Return first node in document order, or empty node if node set is empty. + // If PUGIXML_NO_EXCEPTIONS is not defined, throws xpath_exception on type mismatch and std::bad_alloc on out of memory errors. + // If PUGIXML_NO_EXCEPTIONS is defined, returns empty node instead. + xpath_node evaluate_node(const xpath_node& n) const; + // Get parsing result (used to get compilation errors in PUGIXML_NO_EXCEPTIONS mode) const xpath_parse_result& result() const; // Safe bool conversion operator operator unspecified_bool_type() const; - // Borland C++ workaround + // Borland C++ workaround bool operator!() const; }; @@ -953,7 +1176,7 @@ namespace pugi // Get error message virtual const char* what() const throw(); - // Get parse result + // Get parse result const xpath_parse_result& result() const; }; #endif @@ -965,7 +1188,7 @@ namespace pugi xml_node _node; xml_attribute _attribute; - typedef xml_node xpath_node::*unspecified_bool_type; + typedef void (*unspecified_bool_type)(xpath_node***); public: // Default constructor; constructs empty XPath node @@ -982,11 +1205,11 @@ namespace pugi // Get parent of contained node/attribute xml_node parent() const; - // Safe bool conversion operator + // Safe bool conversion operator operator unspecified_bool_type() const; - // Borland C++ workaround - bool operator!() const; + // Borland C++ workaround + bool operator!() const; // Comparison operators bool operator==(const xpath_node& n) const; @@ -1013,6 +1236,9 @@ namespace pugi // Constant iterator type typedef const xpath_node* const_iterator; + + // We define non-constant iterator to be the same as constant iterator so that various generic algorithms (i.e. boost foreach) work + typedef const xpath_node* iterator; // Default constructor. Constructs empty set. xpath_node_set(); @@ -1033,7 +1259,7 @@ namespace pugi // Get collection size size_t size() const; - // Indexing operator + // Indexing operator const xpath_node& operator[](size_t index) const; // Collection iterators @@ -1048,7 +1274,7 @@ namespace pugi // Check if collection is empty bool empty() const; - + private: type_t _type; @@ -1075,14 +1301,14 @@ namespace pugi typedef void* (*allocation_function)(size_t size); // Memory deallocation function interface - typedef void (*deallocation_function)(void* ptr); - - // Override default memory management functions. All subsequent allocations/deallocations will be performed via supplied functions. - void PUGIXML_FUNCTION set_memory_management_functions(allocation_function allocate, deallocation_function deallocate); - - // Get current memory management functions - allocation_function PUGIXML_FUNCTION get_memory_allocation_function(); - deallocation_function PUGIXML_FUNCTION get_memory_deallocation_function(); + typedef void (*deallocation_function)(void* ptr); + + // Override default memory management functions. All subsequent allocations/deallocations will be performed via supplied functions. + void PUGIXML_FUNCTION set_memory_management_functions(allocation_function allocate, deallocation_function deallocate); + + // Get current memory management functions + allocation_function PUGIXML_FUNCTION get_memory_allocation_function(); + deallocation_function PUGIXML_FUNCTION get_memory_deallocation_function(); } #if !defined(PUGIXML_NO_STL) && (defined(_MSC_VER) || defined(__ICC)) @@ -1091,6 +1317,7 @@ namespace std // Workarounds for (non-standard) iterator category detection for older versions (MSVC7/IC8 and earlier) std::bidirectional_iterator_tag PUGIXML_FUNCTION _Iter_cat(const pugi::xml_node_iterator&); std::bidirectional_iterator_tag PUGIXML_FUNCTION _Iter_cat(const pugi::xml_attribute_iterator&); + std::bidirectional_iterator_tag PUGIXML_FUNCTION _Iter_cat(const pugi::xml_named_node_iterator&); } #endif @@ -1100,13 +1327,21 @@ namespace std // Workarounds for (non-standard) iterator category detection std::bidirectional_iterator_tag PUGIXML_FUNCTION __iterator_category(const pugi::xml_node_iterator&); std::bidirectional_iterator_tag PUGIXML_FUNCTION __iterator_category(const pugi::xml_attribute_iterator&); + std::bidirectional_iterator_tag PUGIXML_FUNCTION __iterator_category(const pugi::xml_named_node_iterator&); } #endif #endif +// Make sure implementation is included in header-only mode +// Use macro expansion in #include to work around QMake (QTBUG-11923) +#if defined(PUGIXML_HEADER_ONLY) && !defined(PUGIXML_SOURCE) +# define PUGIXML_SOURCE "pugixml.cpp" +# include PUGIXML_SOURCE +#endif + /** - * Copyright (c) 2006-2010 Arseny Kapoulkine + * Copyright (c) 2006-2015 Arseny Kapoulkine * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation From 9a5af8a12bd07a2282d572e5385e82194e6f93fc Mon Sep 17 00:00:00 2001 From: Ingo Randolf Date: Mon, 1 Jun 2015 10:43:22 +0200 Subject: [PATCH 2/2] use standard way to create the window --- src/main.cpp | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 0e8a8fb..da95ad4 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,23 +1,9 @@ #include "ofMain.h" #include "testApp.h" -#include "ofAppGLFWWindow.h" -#include "ofAppNoWindow.h" - //======================================================================== int main( int argc, char *argv[] ){ - ofGLFWWindowSettings settings; - settings.width = 1024; - settings.height = 610; - settings.setPosition(ofVec2f(300,0)); - settings.resizable = false; - shared_ptr mainWindow = ofCreateWindow(settings); - mainWindow->setVerticalSync(true); - - shared_ptr mainApp(new testApp); - - ofRunApp(mainWindow, mainApp); - ofRunMainLoop(); - + ofSetupOpenGL(1024,610,OF_WINDOW); + ofRunApp(new testApp()); }