mirror of
https://github.com/leethomason/tinyxml2.git
synced 2026-07-25 21:23:00 +04:00
Compare commits
86 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 96a2dd3a43 | |||
| 8224e427b6 | |||
| 935ddecc91 | |||
| 88d678c39e | |||
| 999a21fa86 | |||
| a737ecb2cb | |||
| 9901919829 | |||
| 63428c8852 | |||
| beb16fbca0 | |||
| 26ab0bd591 | |||
| 8d8472fe1a | |||
| 3dcad8e3c3 | |||
| 418229dc5c | |||
| 98137e6936 | |||
| 111f462dc4 | |||
| aba13c50bf | |||
| e48a1310fe | |||
| 3324d04d58 | |||
| c4e29afeaf | |||
| 5c9a452c73 | |||
| 2722500313 | |||
| b5e767a6b9 | |||
| e186491558 | |||
| 36ff404c34 | |||
| 302f4661a7 | |||
| e6caeae857 | |||
| b765a210b3 | |||
| 6e246aec4d | |||
| 30dee1efa0 | |||
| a93163d2f5 | |||
| f87d0e3077 | |||
| 487f42aa69 | |||
| afff7bf328 | |||
| 9148bdf719 | |||
| 57eea48c5b | |||
| 198cb82c9b | |||
| c6ab6d76e8 | |||
| 008e32968f | |||
| 0ca3584fa4 | |||
| 57ec94127b | |||
| 1fadaae0c9 | |||
| 4cbb25155c | |||
| ff48ea1bae | |||
| 494735de30 | |||
| d418ac22f2 | |||
| d13a151c8d | |||
| 601a953b74 | |||
| 162bd4e925 | |||
| 1fdf653269 | |||
| 86fe31c836 | |||
| 20ecbb22d8 | |||
| 374292e9ba | |||
| 2ac336a253 | |||
| 38894bfa7f | |||
| 780b16b5ae | |||
| 04bbc06cd0 | |||
| 62f6b14e91 | |||
| b25c39aaad | |||
| 8a519a556a | |||
| c93b6f78d4 | |||
| 8e4bfebad5 | |||
| eb3ab0df5d | |||
| 3a893e5757 | |||
| a0f66fdf71 | |||
| a965e28c4f | |||
| 5b04868fee | |||
| 8df9b25bb9 | |||
| 53d8ec5573 | |||
| 5e27269c04 | |||
| 693052afe4 | |||
| 42875a9f60 | |||
| afb8fabf58 | |||
| a151353f3a | |||
| ef185a8f85 | |||
| 8fed517e5d | |||
| e269b2e91f | |||
| cd8c1a6322 | |||
| 668fd81256 | |||
| 095a8ffa42 | |||
| 574c760b7f | |||
| 5d219c893b | |||
| fd26a5ee1f | |||
| dded8bb2e9 | |||
| 312a809224 | |||
| 0f9c021a44 | |||
| dfc20c5f8f |
+14
-14
@@ -6,15 +6,15 @@ jobs:
|
|||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
os: [ windows-2019, macos-latest, ubuntu-20.04 ]
|
os: [ windows-latest, macos-latest, ubuntu-latest ]
|
||||||
cmake: [ 3.15, 3.x ]
|
cmake: [ 3.15, 3.x ]
|
||||||
include:
|
include:
|
||||||
- os: windows-2019
|
- os: windows-latest
|
||||||
static_postfix: _static
|
static_postfix: _static
|
||||||
tree: tree /F
|
tree: tree /F
|
||||||
CXX: cl
|
CXX: cl
|
||||||
|
|
||||||
- os: ubuntu-20.04
|
- os: ubuntu-latest
|
||||||
tree: tree
|
tree: tree
|
||||||
|
|
||||||
- os: macos-latest
|
- os: macos-latest
|
||||||
@@ -31,16 +31,16 @@ jobs:
|
|||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
steps:
|
steps:
|
||||||
# System set-up
|
# System set-up
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v4
|
||||||
- uses: ilammy/msvc-dev-cmd@v1
|
- uses: ilammy/msvc-dev-cmd@v1
|
||||||
- uses: seanmiddleditch/gha-setup-ninja@master
|
- uses: seanmiddleditch/gha-setup-ninja@v4
|
||||||
- uses: jwlawson/actions-setup-cmake@v1.8
|
- uses: jwlawson/actions-setup-cmake@v2
|
||||||
with:
|
with:
|
||||||
cmake-version: ${{ matrix.cmake }}
|
cmake-version: ${{ matrix.cmake }}
|
||||||
|
|
||||||
# Static Debug
|
# Static Debug
|
||||||
- name: "Static Debug: Configure"
|
- name: "Static Debug: Configure"
|
||||||
run: cmake -G Ninja -S . -B build-static-dbg -DCMAKE_BUILD_TYPE=Debug "-DCMAKE_DEBUG_POSTFIX=d${{matrix.static_postfix}}"
|
run: cmake -G Ninja -S . -B build-static-dbg -DCMAKE_BUILD_TYPE=Debug "-DCMAKE_DEBUG_POSTFIX=d${{matrix.static_postfix}}" -DCMAKE_CXX_STANDARD=11 -DCMAKE_CXX_STANDARD_REQUIRED=ON
|
||||||
- name: "Static Debug: Build"
|
- name: "Static Debug: Build"
|
||||||
run: cmake --build build-static-dbg
|
run: cmake --build build-static-dbg
|
||||||
- name: "Static Debug: Test"
|
- name: "Static Debug: Test"
|
||||||
@@ -49,7 +49,7 @@ jobs:
|
|||||||
|
|
||||||
# Shared Debug
|
# Shared Debug
|
||||||
- name: "Shared Debug: Configure"
|
- name: "Shared Debug: Configure"
|
||||||
run: cmake -G Ninja -S . -B build-shared-dbg -DCMAKE_BUILD_TYPE=Debug -DCMAKE_DEBUG_POSTFIX=d -DBUILD_SHARED_LIBS=ON
|
run: cmake -G Ninja -S . -B build-shared-dbg -DCMAKE_BUILD_TYPE=Debug -DCMAKE_DEBUG_POSTFIX=d -DBUILD_SHARED_LIBS=ON -DCMAKE_CXX_STANDARD=11 -DCMAKE_CXX_STANDARD_REQUIRED=ON
|
||||||
- name: "Shared Debug: Build"
|
- name: "Shared Debug: Build"
|
||||||
run: cmake --build build-shared-dbg
|
run: cmake --build build-shared-dbg
|
||||||
- name: "Shared Debug: Test"
|
- name: "Shared Debug: Test"
|
||||||
@@ -58,7 +58,7 @@ jobs:
|
|||||||
|
|
||||||
# Static Release
|
# Static Release
|
||||||
- name: "Static Release: Configure"
|
- name: "Static Release: Configure"
|
||||||
run: cmake -G Ninja -S . -B build-static-rel -DCMAKE_BUILD_TYPE=Release "-DCMAKE_RELEASE_POSTFIX=${{matrix.static_postfix}}"
|
run: cmake -G Ninja -S . -B build-static-rel -DCMAKE_BUILD_TYPE=Release "-DCMAKE_RELEASE_POSTFIX=${{matrix.static_postfix}}" -DCMAKE_CXX_STANDARD=11 -DCMAKE_CXX_STANDARD_REQUIRED=ON
|
||||||
- name: "Static Release: Build"
|
- name: "Static Release: Build"
|
||||||
run: cmake --build build-static-rel
|
run: cmake --build build-static-rel
|
||||||
- name: "Static Release: Test"
|
- name: "Static Release: Test"
|
||||||
@@ -67,7 +67,7 @@ jobs:
|
|||||||
|
|
||||||
# Shared Release
|
# Shared Release
|
||||||
- name: "Shared Release: Configure"
|
- name: "Shared Release: Configure"
|
||||||
run: cmake -G Ninja -S . -B build-shared-rel -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=ON
|
run: cmake -G Ninja -S . -B build-shared-rel -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=ON -DCMAKE_CXX_STANDARD=11 -DCMAKE_CXX_STANDARD_REQUIRED=ON
|
||||||
- name: "Shared Release: Build"
|
- name: "Shared Release: Build"
|
||||||
run: cmake --build build-shared-rel
|
run: cmake --build build-shared-rel
|
||||||
- name: "Shared Release: Test"
|
- name: "Shared Release: Test"
|
||||||
@@ -89,23 +89,23 @@ jobs:
|
|||||||
run: >-
|
run: >-
|
||||||
ctest --build-and-test test test-static-dbg
|
ctest --build-and-test test test-static-dbg
|
||||||
--build-generator Ninja
|
--build-generator Ninja
|
||||||
--build-options -DCMAKE_BUILD_TYPE=Debug -Dtinyxml2_SHARED_LIBS=NO -DCMAKE_PREFIX_PATH=${{github.workspace}}/install
|
--build-options -DCMAKE_BUILD_TYPE=Debug -Dtinyxml2_SHARED_LIBS=NO -DCMAKE_PREFIX_PATH=${{github.workspace}}/install -DCMAKE_CXX_STANDARD=11 -DCMAKE_CXX_STANDARD_REQUIRED=ON
|
||||||
--test-command ctest --output-on-failure
|
--test-command ctest --output-on-failure
|
||||||
- name: "Test find_package: Static Release"
|
- name: "Test find_package: Static Release"
|
||||||
run: >-
|
run: >-
|
||||||
ctest --build-and-test test test-static-rel
|
ctest --build-and-test test test-static-rel
|
||||||
--build-generator Ninja
|
--build-generator Ninja
|
||||||
--build-options -DCMAKE_BUILD_TYPE=Release -Dtinyxml2_SHARED_LIBS=NO -DCMAKE_PREFIX_PATH=${{github.workspace}}/install
|
--build-options -DCMAKE_BUILD_TYPE=Release -Dtinyxml2_SHARED_LIBS=NO -DCMAKE_PREFIX_PATH=${{github.workspace}}/install -DCMAKE_CXX_STANDARD=11 -DCMAKE_CXX_STANDARD_REQUIRED=ON
|
||||||
--test-command ctest --output-on-failure
|
--test-command ctest --output-on-failure
|
||||||
- name: "Test find_package: Shared Debug"
|
- name: "Test find_package: Shared Debug"
|
||||||
run: >-
|
run: >-
|
||||||
ctest --build-and-test test test-shared-dbg
|
ctest --build-and-test test test-shared-dbg
|
||||||
--build-generator Ninja
|
--build-generator Ninja
|
||||||
--build-options -DCMAKE_BUILD_TYPE=Debug -Dtinyxml2_SHARED_LIBS=YES -DCMAKE_PREFIX_PATH=${{github.workspace}}/install
|
--build-options -DCMAKE_BUILD_TYPE=Debug -Dtinyxml2_SHARED_LIBS=YES -DCMAKE_PREFIX_PATH=${{github.workspace}}/install -DCMAKE_CXX_STANDARD=11 -DCMAKE_CXX_STANDARD_REQUIRED=ON
|
||||||
--test-command ctest --output-on-failure
|
--test-command ctest --output-on-failure
|
||||||
- name: "Test find_package: Shared Release"
|
- name: "Test find_package: Shared Release"
|
||||||
run: >-
|
run: >-
|
||||||
ctest --build-and-test test test-shared-rel
|
ctest --build-and-test test test-shared-rel
|
||||||
--build-generator Ninja
|
--build-generator Ninja
|
||||||
--build-options -DCMAKE_BUILD_TYPE=Release -Dtinyxml2_SHARED_LIBS=YES -DCMAKE_PREFIX_PATH=${{github.workspace}}/install
|
--build-options -DCMAKE_BUILD_TYPE=Release -Dtinyxml2_SHARED_LIBS=YES -DCMAKE_PREFIX_PATH=${{github.workspace}}/install -DCMAKE_CXX_STANDARD=11 -DCMAKE_CXX_STANDARD_REQUIRED=ON
|
||||||
--test-command ctest --output-on-failure
|
--test-command ctest --output-on-failure
|
||||||
|
|||||||
+15
-11
@@ -1,5 +1,5 @@
|
|||||||
cmake_minimum_required(VERSION 3.15)
|
cmake_minimum_required(VERSION 3.15)
|
||||||
project(tinyxml2 VERSION 10.0.0)
|
project(tinyxml2 VERSION 11.0.0)
|
||||||
|
|
||||||
include(CTest)
|
include(CTest)
|
||||||
option(tinyxml2_BUILD_TESTING "Build tests for tinyxml2" "${BUILD_TESTING}")
|
option(tinyxml2_BUILD_TESTING "Build tests for tinyxml2" "${BUILD_TESTING}")
|
||||||
@@ -22,8 +22,8 @@ set(CMAKE_VISIBILITY_INLINES_HIDDEN YES)
|
|||||||
add_library(tinyxml2 tinyxml2.cpp tinyxml2.h)
|
add_library(tinyxml2 tinyxml2.cpp tinyxml2.h)
|
||||||
add_library(tinyxml2::tinyxml2 ALIAS tinyxml2)
|
add_library(tinyxml2::tinyxml2 ALIAS tinyxml2)
|
||||||
|
|
||||||
# Uncomment the following line to require C++11 (or greater) to use tinyxml2
|
# Require C++11 (or greater) to use tinyxml2
|
||||||
# target_compile_features(tinyxml2 PUBLIC cxx_std_11)
|
target_compile_features(tinyxml2 PUBLIC cxx_std_11)
|
||||||
target_include_directories(tinyxml2 PUBLIC "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>")
|
target_include_directories(tinyxml2 PUBLIC "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>")
|
||||||
|
|
||||||
target_compile_definitions(
|
target_compile_definitions(
|
||||||
@@ -63,7 +63,9 @@ endif ()
|
|||||||
include(GNUInstallDirs)
|
include(GNUInstallDirs)
|
||||||
include(CMakePackageConfigHelpers)
|
include(CMakePackageConfigHelpers)
|
||||||
|
|
||||||
## Custom locations
|
## Custom settings
|
||||||
|
option(tinyxml2_INSTALL_PKGCONFIG "Create and install pkgconfig files" ON)
|
||||||
|
|
||||||
set(tinyxml2_INSTALL_PKGCONFIGDIR "${CMAKE_INSTALL_LIBDIR}/pkgconfig"
|
set(tinyxml2_INSTALL_PKGCONFIGDIR "${CMAKE_INSTALL_LIBDIR}/pkgconfig"
|
||||||
CACHE PATH "Directory for pkgconfig files")
|
CACHE PATH "Directory for pkgconfig files")
|
||||||
|
|
||||||
@@ -121,10 +123,12 @@ install(
|
|||||||
|
|
||||||
## pkg-config
|
## pkg-config
|
||||||
|
|
||||||
configure_file(cmake/tinyxml2.pc.in tinyxml2.pc.gen @ONLY)
|
if (tinyxml2_INSTALL_PKGCONFIG)
|
||||||
file(GENERATE OUTPUT tinyxml2.pc INPUT "${CMAKE_CURRENT_BINARY_DIR}/tinyxml2.pc.gen")
|
configure_file(cmake/tinyxml2.pc.in tinyxml2.pc.gen @ONLY)
|
||||||
install(
|
file(GENERATE OUTPUT tinyxml2.pc INPUT "${CMAKE_CURRENT_BINARY_DIR}/tinyxml2.pc.gen")
|
||||||
FILES "${CMAKE_CURRENT_BINARY_DIR}/tinyxml2.pc"
|
install(
|
||||||
DESTINATION "${tinyxml2_INSTALL_PKGCONFIGDIR}"
|
FILES "${CMAKE_CURRENT_BINARY_DIR}/tinyxml2.pc"
|
||||||
COMPONENT tinyxml2_development
|
DESTINATION "${tinyxml2_INSTALL_PKGCONFIGDIR}"
|
||||||
)
|
COMPONENT tinyxml2_development
|
||||||
|
)
|
||||||
|
endif ()
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
// In HTML5, there are 16 so-called "void" elements. "void elements" NEVER have
|
// In HTML5, there are 16 so-called "void" elements. "void elements" NEVER have
|
||||||
// inner content (but they MAY have attributes), and are assumed to be self-closing.
|
// inner content (but they MAY have attributes), and are assumed to be self-closing.
|
||||||
// An example of a self-closig HTML5 element is "<br/>" (line break)
|
// An example of a self-closing HTML5 element is "<br/>" (line break)
|
||||||
// All other elements are called "non-void" and MUST never self-close.
|
// All other elements are called "non-void" and MUST never self-close.
|
||||||
// Examples: "<div class='lolcats'></div>".
|
// Examples: "<div class='lolcats'></div>".
|
||||||
|
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ PROJECT_NAME = "TinyXML-2"
|
|||||||
# could be handy for archiving the generated documentation or if some version
|
# could be handy for archiving the generated documentation or if some version
|
||||||
# control system is used.
|
# control system is used.
|
||||||
|
|
||||||
PROJECT_NUMBER = 10.0.0
|
PROJECT_NUMBER = 11.0.0
|
||||||
|
|
||||||
# Using the PROJECT_BRIEF tag one can provide an optional one line description
|
# Using the PROJECT_BRIEF tag one can provide an optional one line description
|
||||||
# for a project that appears at the top of each page and should give viewer a
|
# for a project that appears at the top of each page and should give viewer a
|
||||||
|
|||||||
+1
-1
@@ -22,7 +22,7 @@
|
|||||||
project(
|
project(
|
||||||
'tinyxml2',
|
'tinyxml2',
|
||||||
['cpp'],
|
['cpp'],
|
||||||
version : '10.0.0',
|
version : '11.0.0',
|
||||||
meson_version : '>= 0.49.0',
|
meson_version : '>= 0.49.0',
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,13 @@
|
|||||||
TinyXML-2
|
# TinyXML-2
|
||||||
=========
|
|
||||||
|
|
||||||
[](https://github.com/leethomason/tinyxml2/actions/workflows/test.yml)
|
[](https://github.com/leethomason/tinyxml2/actions/workflows/test.yml)
|
||||||
|
|
||||||
TinyXML-2 is a simple, small, efficient, C++ XML parser that can be
|
TinyXML-2 is a simple, small, efficient, C++ XML parser that can be
|
||||||
easily integrated into other programs.
|
easily integrated into other programs.
|
||||||
|
|
||||||
The master is hosted on github:
|
It is written in C++ 11 and does not use any Standard Library (std::) features.
|
||||||
|
|
||||||
|
The master is hosted on GitHub:
|
||||||
https://github.com/leethomason/tinyxml2
|
https://github.com/leethomason/tinyxml2
|
||||||
|
|
||||||
The online HTML version of these docs:
|
The online HTML version of these docs:
|
||||||
@@ -14,8 +15,7 @@ http://leethomason.github.io/tinyxml2/
|
|||||||
|
|
||||||
Examples are in the "related pages" tab of the HTML docs.
|
Examples are in the "related pages" tab of the HTML docs.
|
||||||
|
|
||||||
What it does.
|
## What it does.
|
||||||
-------------
|
|
||||||
|
|
||||||
In brief, TinyXML-2 parses an XML document, and builds from that a
|
In brief, TinyXML-2 parses an XML document, and builds from that a
|
||||||
Document Object Model (DOM) that can be read, modified, and saved.
|
Document Object Model (DOM) that can be read, modified, and saved.
|
||||||
@@ -37,7 +37,7 @@ code without creating a document first.
|
|||||||
|
|
||||||
TinyXML-2 is designed to be easy and fast to learn. It is one header and
|
TinyXML-2 is designed to be easy and fast to learn. It is one header and
|
||||||
one cpp file. Simply add these to your project and off you go.
|
one cpp file. Simply add these to your project and off you go.
|
||||||
There is an example file - xmltest.cpp - to get you started.
|
There is an example file - `xmltest.cpp` - to get you started.
|
||||||
|
|
||||||
TinyXML-2 is released under the ZLib license,
|
TinyXML-2 is released under the ZLib license,
|
||||||
so you can use it in open source or commercial code. The details
|
so you can use it in open source or commercial code. The details
|
||||||
@@ -45,10 +45,10 @@ of the license are at the top of every source file.
|
|||||||
|
|
||||||
TinyXML-2 attempts to be a flexible parser, but with truly correct and
|
TinyXML-2 attempts to be a flexible parser, but with truly correct and
|
||||||
compliant XML output. TinyXML-2 should compile on any reasonably C++
|
compliant XML output. TinyXML-2 should compile on any reasonably C++
|
||||||
compliant system. It does not rely on exceptions, RTTI, or the STL.
|
compliant system. It does not rely on exceptions, run-time type information,
|
||||||
|
or the C++ Standard Library.
|
||||||
|
|
||||||
What it doesn't do.
|
## What it doesn't do.
|
||||||
-------------------
|
|
||||||
|
|
||||||
TinyXML-2 doesn't parse or use DTDs (Document Type Definitions) or XSLs
|
TinyXML-2 doesn't parse or use DTDs (Document Type Definitions) or XSLs
|
||||||
(eXtensible Stylesheet Language.) There are other parsers out there
|
(eXtensible Stylesheet Language.) There are other parsers out there
|
||||||
@@ -56,10 +56,9 @@ that are much more fully featured. But they are generally bigger and
|
|||||||
more difficult to use. If you are working with
|
more difficult to use. If you are working with
|
||||||
browsers or have more complete XML needs, TinyXML-2 is not the parser for you.
|
browsers or have more complete XML needs, TinyXML-2 is not the parser for you.
|
||||||
|
|
||||||
TinyXML-1 vs. TinyXML-2
|
## TinyXML-1 vs. TinyXML-2
|
||||||
-----------------------
|
|
||||||
|
|
||||||
TinyXML-2 long been the focus of all development. It is well tested
|
TinyXML-2 has long been the focus of all development. It is well tested
|
||||||
and should be used instead of TinyXML-1.
|
and should be used instead of TinyXML-1.
|
||||||
|
|
||||||
TinyXML-2 uses a similar API to TinyXML-1 and the same
|
TinyXML-2 uses a similar API to TinyXML-1 and the same
|
||||||
@@ -67,10 +66,10 @@ rich test cases. But the implementation of the parser is completely re-written
|
|||||||
to make it more appropriate for use in a game. It uses less memory, is faster,
|
to make it more appropriate for use in a game. It uses less memory, is faster,
|
||||||
and uses far fewer memory allocations.
|
and uses far fewer memory allocations.
|
||||||
|
|
||||||
TinyXML-2 has no requirement or support for STL.
|
TinyXML-2 has no dependency on the C++ Standard Library, and does not adapt or use any
|
||||||
|
of its collection types either.
|
||||||
|
|
||||||
Features
|
## Features
|
||||||
--------
|
|
||||||
|
|
||||||
### Code Page
|
### Code Page
|
||||||
|
|
||||||
@@ -81,17 +80,17 @@ Filenames for loading / saving are passed unchanged to the underlying OS.
|
|||||||
|
|
||||||
### Memory Model
|
### Memory Model
|
||||||
|
|
||||||
An XMLDocument is a C++ object like any other, that can be on the stack, or
|
An `XMLDocument` is a C++ object like any other, that can be on the stack, or
|
||||||
new'd and deleted on the heap.
|
`new`'d and `delete`d on the heap.
|
||||||
|
|
||||||
However, any sub-node of the Document, XMLElement, XMLText, etc, can only
|
However, any sub-node of the `XMLDocument`, `XMLElement`, `XMLText`, etc, can only
|
||||||
be created by calling the appropriate XMLDocument::NewElement, NewText, etc.
|
be created by calling the appropriate `XMLDocument::NewElement`, `XMLDocument::NewText`, etc.
|
||||||
method. Although you have pointers to these objects, they are still owned
|
method. Although you have pointers to these objects, they are still owned
|
||||||
by the Document. When the Document is deleted, so are all the nodes it contains.
|
by the `XMLDocument`. When the `XMLDocument` is `delete`d, so are all the nodes it contains.
|
||||||
|
|
||||||
### White Space
|
### White Space
|
||||||
|
|
||||||
#### Whitespace Preservation (default, PRESERVE_WHITESPACE)
|
#### Whitespace Preservation (default, `PRESERVE_WHITESPACE`)
|
||||||
|
|
||||||
Microsoft has an excellent article on white space: http://msdn.microsoft.com/en-us/library/ms256097.aspx
|
Microsoft has an excellent article on white space: http://msdn.microsoft.com/en-us/library/ms256097.aspx
|
||||||
|
|
||||||
@@ -103,51 +102,57 @@ line-feed character, as required by the XML spec.
|
|||||||
|
|
||||||
White space in text is preserved. For example:
|
White space in text is preserved. For example:
|
||||||
|
|
||||||
<element> Hello, World</element>
|
```xml
|
||||||
|
<element> Hello, World</element>
|
||||||
|
```
|
||||||
|
|
||||||
The leading space before the "Hello" and the double space after the comma are
|
The leading space before the `"Hello"` and the double space after the comma are
|
||||||
preserved. Line-feeds are preserved, as in this example:
|
preserved. Line-feeds are preserved, as in this example:
|
||||||
|
|
||||||
<element> Hello again,
|
```xml
|
||||||
World</element>
|
<element> Hello again,
|
||||||
|
World</element>
|
||||||
|
```
|
||||||
|
|
||||||
However, white space between elements is **not** preserved. Although not strictly
|
However, white space between elements is **not** preserved. Although not strictly
|
||||||
compliant, tracking and reporting inter-element space is awkward, and not normally
|
compliant, tracking and reporting inter-element space is awkward, and not normally
|
||||||
valuable. TinyXML-2 sees these as the same XML:
|
valuable. TinyXML-2 sees these as the same XML:
|
||||||
|
|
||||||
<document>
|
```xml
|
||||||
<data>1</data>
|
<document>
|
||||||
<data>2</data>
|
<data>1</data>
|
||||||
<data>3</data>
|
<data>2</data>
|
||||||
</document>
|
<data>3</data>
|
||||||
|
</document>
|
||||||
|
|
||||||
<document><data>1</data><data>2</data><data>3</data></document>
|
<document><data>1</data><data>2</data><data>3</data></document>
|
||||||
|
```
|
||||||
|
|
||||||
#### Whitespace Collapse (COLLAPSE_WHITESPACE)
|
#### Whitespace Collapse (`COLLAPSE_WHITESPACE`)
|
||||||
|
|
||||||
For some applications, it is preferable to collapse whitespace. Collapsing
|
For some applications, it is preferable to collapse whitespace. Collapsing
|
||||||
whitespace gives you "HTML-like" behavior, which is sometimes more suitable
|
whitespace gives you "HTML-like" behavior, which is sometimes more suitable
|
||||||
for hand typed documents.
|
for hand typed documents.
|
||||||
|
|
||||||
TinyXML-2 supports this with the 'whitespace' parameter to the XMLDocument constructor.
|
TinyXML-2 supports this with the `whitespace` parameter to the `XMLDocument` constructor.
|
||||||
(The default is to preserve whitespace, as described above.)
|
(The default is to preserve whitespace, as described above.)
|
||||||
|
|
||||||
However, you may also use COLLAPSE_WHITESPACE, which will:
|
However, you may also use `COLLAPSE_WHITESPACE`, which will:
|
||||||
|
|
||||||
* Remove leading and trailing whitespace
|
* Remove leading and trailing whitespace
|
||||||
* Convert newlines and line-feeds into a space character
|
* Convert newlines and line-feeds into a space character
|
||||||
* Collapse a run of any number of space characters into a single space character
|
* Collapse a run of any number of space characters into a single space character
|
||||||
|
|
||||||
Note that (currently) there is a performance impact for using COLLAPSE_WHITESPACE.
|
Note that (currently) there is a performance impact for using `COLLAPSE_WHITESPACE`.
|
||||||
It essentially causes the XML to be parsed twice.
|
It essentially causes the XML to be parsed twice.
|
||||||
|
|
||||||
#### Pedantic Whitespace (PEDANTIC_WHITESPACE)
|
#### Pedantic Whitespace (`PEDANTIC_WHITESPACE`)
|
||||||
|
|
||||||
For applications that need to know about text nodes that are composed entirely of
|
For applications that need to know about text nodes that are composed entirely of
|
||||||
whitespace, PEDANTIC_WHITESPACE is available. PEDANTIC_WHITESPACE maintains all the
|
whitespace, `PEDANTIC_WHITESPACE` is available. `PEDANTIC_WHITESPACE` maintains all the
|
||||||
whilespace between elements.
|
whitespace between elements.
|
||||||
|
|
||||||
PEDANTIC_WHITESPACE is a new mode and not as tested as the other whitespace modes.
|
`PEDANTIC_WHITESPACE` is a new mode and not as tested as the other whitespace modes.
|
||||||
|
|
||||||
### Error Reporting
|
### Error Reporting
|
||||||
|
|
||||||
@@ -163,22 +168,26 @@ line number information for error messages.
|
|||||||
TinyXML-2 recognizes the pre-defined "character entities", meaning special
|
TinyXML-2 recognizes the pre-defined "character entities", meaning special
|
||||||
characters. Namely:
|
characters. Namely:
|
||||||
|
|
||||||
& &
|
```html
|
||||||
< <
|
& &
|
||||||
> >
|
< <
|
||||||
" "
|
> >
|
||||||
' '
|
" "
|
||||||
|
' '
|
||||||
|
```
|
||||||
|
|
||||||
These are recognized when the XML document is read, and translated to their
|
These are recognized when the XML document is read, and translated to their
|
||||||
UTF-8 equivalents. For instance, text with the XML of:
|
UTF-8 equivalents. For instance, text with the XML of:
|
||||||
|
|
||||||
Far & Away
|
```xml
|
||||||
|
Far & Away
|
||||||
|
```
|
||||||
|
|
||||||
will have the Value() of "Far & Away" when queried from the XMLText object,
|
will have the `Value()` of `"Far & Away"` when queried from the `XMLText` object,
|
||||||
and will be written back to the XML stream/file as an ampersand.
|
and will be written back to the XML stream/file as an ampersand.
|
||||||
|
|
||||||
Additionally, any character can be specified by its Unicode code point:
|
Additionally, any character can be specified by its Unicode code point:
|
||||||
The syntax ` ` or ` ` are both to the non-breaking space character.
|
The syntax ` ` or ` ` both refer to the non-breaking space character.
|
||||||
This is called a 'numeric character reference'. Any numeric character reference
|
This is called a 'numeric character reference'. Any numeric character reference
|
||||||
that isn't one of the special entities above, will be read, but written as a
|
that isn't one of the special entities above, will be read, but written as a
|
||||||
regular code point. The output is correct, but the entity syntax isn't preserved.
|
regular code point. The output is correct, but the entity syntax isn't preserved.
|
||||||
@@ -188,21 +197,27 @@ regular code point. The output is correct, but the entity syntax isn't preserved
|
|||||||
#### Print to file
|
#### Print to file
|
||||||
You can directly use the convenience function:
|
You can directly use the convenience function:
|
||||||
|
|
||||||
XMLDocument doc;
|
```cpp
|
||||||
...
|
XMLDocument doc;
|
||||||
doc.SaveFile( "foo.xml" );
|
// ...
|
||||||
|
doc.SaveFile("foo.xml");
|
||||||
|
```
|
||||||
|
|
||||||
Or the XMLPrinter class:
|
Or the `XMLPrinter` class:
|
||||||
|
|
||||||
XMLPrinter printer( fp );
|
```cpp
|
||||||
doc.Print( &printer );
|
XMLPrinter printer(fp);
|
||||||
|
doc.Print(&printer);
|
||||||
|
```
|
||||||
|
|
||||||
#### Print to memory
|
#### Print to memory
|
||||||
Printing to memory is supported by the XMLPrinter.
|
Printing to memory is supported by the `XMLPrinter`.
|
||||||
|
|
||||||
XMLPrinter printer;
|
```cpp
|
||||||
doc.Print( &printer );
|
XMLPrinter printer;
|
||||||
// printer.CStr() has a const char* to the XML
|
doc.Print(&printer);
|
||||||
|
// printer.CStr() has a const char* to the XML
|
||||||
|
```
|
||||||
|
|
||||||
#### Print without an XMLDocument
|
#### Print without an XMLDocument
|
||||||
|
|
||||||
@@ -210,92 +225,95 @@ When loading, an XML parser is very useful. However, sometimes
|
|||||||
when saving, it just gets in the way. The code is often set up
|
when saving, it just gets in the way. The code is often set up
|
||||||
for streaming, and constructing the DOM is just overhead.
|
for streaming, and constructing the DOM is just overhead.
|
||||||
|
|
||||||
The Printer supports the streaming case. The following code
|
The `XMLPrinter` supports the streaming case. The following code
|
||||||
prints out a trivially simple XML file without ever creating
|
prints out a trivially simple XML file without ever creating
|
||||||
an XML document.
|
an XML document.
|
||||||
|
|
||||||
XMLPrinter printer( fp );
|
```cpp
|
||||||
printer.OpenElement( "foo" );
|
XMLPrinter printer(fp);
|
||||||
printer.PushAttribute( "foo", "bar" );
|
printer.OpenElement("foo");
|
||||||
printer.CloseElement();
|
printer.PushAttribute("foo", "bar");
|
||||||
|
printer.CloseElement();
|
||||||
|
```
|
||||||
|
|
||||||
Examples
|
### Examples
|
||||||
--------
|
|
||||||
|
|
||||||
#### Load and parse an XML file.
|
#### Load and parse an XML file.
|
||||||
|
|
||||||
/* ------ Example 1: Load and parse an XML file. ---- */
|
```cpp
|
||||||
{
|
/* ------ Example 1: Load and parse an XML file. ---- */
|
||||||
XMLDocument doc;
|
{
|
||||||
doc.LoadFile( "dream.xml" );
|
XMLDocument doc;
|
||||||
}
|
doc.LoadFile("dream.xml");
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
#### Lookup information.
|
#### Lookup information.
|
||||||
|
|
||||||
/* ------ Example 2: Lookup information. ---- */
|
```cpp
|
||||||
{
|
/* ------ Example 2: Lookup information. ---- */
|
||||||
XMLDocument doc;
|
{
|
||||||
doc.LoadFile( "dream.xml" );
|
XMLDocument doc;
|
||||||
|
doc.LoadFile("dream.xml");
|
||||||
|
|
||||||
// Structure of the XML file:
|
// Structure of the XML file:
|
||||||
// - Element "PLAY" the root Element, which is the
|
// - Element "PLAY" the root Element, which is the
|
||||||
// FirstChildElement of the Document
|
// FirstChildElement of the Document
|
||||||
// - - Element "TITLE" child of the root PLAY Element
|
// - - Element "TITLE" child of the root PLAY Element
|
||||||
// - - - Text child of the TITLE Element
|
// - - - Text child of the TITLE Element
|
||||||
|
|
||||||
// Navigate to the title, using the convenience function,
|
// Navigate to the title, using the convenience function,
|
||||||
// with a dangerous lack of error checking.
|
// with a dangerous lack of error checking.
|
||||||
const char* title = doc.FirstChildElement( "PLAY" )->FirstChildElement( "TITLE" )->GetText();
|
const char* title = doc.FirstChildElement("PLAY")->FirstChildElement("TITLE")->GetText();
|
||||||
printf( "Name of play (1): %s\n", title );
|
printf("Name of play (1): %s\n", title);
|
||||||
|
|
||||||
// Text is just another Node to TinyXML-2. The more
|
// Text is just another Node to TinyXML-2. The more
|
||||||
// general way to get to the XMLText:
|
// general way to get to the XMLText:
|
||||||
XMLText* textNode = doc.FirstChildElement( "PLAY" )->FirstChildElement( "TITLE" )->FirstChild()->ToText();
|
XMLText* textNode = doc.FirstChildElement("PLAY")->FirstChildElement("TITLE")->FirstChild()->ToText();
|
||||||
title = textNode->Value();
|
title = textNode->Value();
|
||||||
printf( "Name of play (2): %s\n", title );
|
printf("Name of play (2): %s\n", title);
|
||||||
}
|
}
|
||||||
|
```
|
||||||
|
|
||||||
Using and Installing
|
## Using and Installing
|
||||||
--------------------
|
|
||||||
|
|
||||||
There are 2 files in TinyXML-2:
|
There are 2 files in TinyXML-2:
|
||||||
* tinyxml2.cpp
|
* `tinyxml2.cpp`
|
||||||
* tinyxml2.h
|
* `tinyxml2.h`
|
||||||
|
|
||||||
And additionally a test file:
|
And additionally a test file:
|
||||||
* xmltest.cpp
|
* `xmltest.cpp`
|
||||||
|
|
||||||
Generally speaking, the intent is that you simply include the tinyxml2.cpp and
|
Generally speaking, the intent is that you simply include the `tinyxml2.cpp` and
|
||||||
tinyxml2.h files in your project and build with your other source code.
|
`tinyxml2.h` files in your project and build with your other source code.
|
||||||
|
|
||||||
There is also a CMake build included. CMake is the general build for TinyXML-2.
|
There is also a CMake build included. CMake is the general build for TinyXML-2.
|
||||||
|
|
||||||
(Additional build systems are costly to maintain, and tend to bit-rot. They are
|
(Additional build systems are costly to maintain, and tend to become outdated. They are
|
||||||
being removed over time.)
|
being removed over time.)
|
||||||
|
|
||||||
Building TinyXML-2 - Using vcpkg
|
### Building TinyXML-2 - Using vcpkg
|
||||||
--------------------------------
|
|
||||||
|
|
||||||
You can download and install TinyXML-2 using the [vcpkg](https://github.com/Microsoft/vcpkg) dependency manager:
|
You can download and install TinyXML-2 using the [vcpkg](https://github.com/Microsoft/vcpkg) dependency manager:
|
||||||
|
|
||||||
git clone https://github.com/Microsoft/vcpkg.git
|
```sh
|
||||||
cd vcpkg
|
git clone https://github.com/Microsoft/vcpkg.git
|
||||||
./bootstrap-vcpkg.sh
|
cd vcpkg
|
||||||
./vcpkg integrate install
|
./bootstrap-vcpkg.sh
|
||||||
./vcpkg install tinyxml2
|
./vcpkg integrate install
|
||||||
|
./vcpkg install tinyxml2
|
||||||
|
```
|
||||||
|
|
||||||
The TinyXML-2 port in vcpkg is kept up to date by Microsoft team members and community contributors. If the version is out of date, please [create an issue or pull request](https://github.com/Microsoft/vcpkg) on the vcpkg repository.
|
The TinyXML-2 port in vcpkg is kept up to date by Microsoft team members and community contributors. If the version is out of date, please [create an issue or pull request](https://github.com/Microsoft/vcpkg) on the vcpkg repository.
|
||||||
|
|
||||||
Versioning
|
## Versioning
|
||||||
----------
|
|
||||||
|
|
||||||
TinyXML-2 uses semantic versioning. http://semver.org/ Releases are now tagged in github.
|
TinyXML-2 uses semantic versioning. http://semver.org/ Releases are now tagged in GitHub.
|
||||||
|
|
||||||
Note that the major version will (probably) change fairly rapidly. API changes are fairly
|
Note that the major version will (probably) change fairly rapidly. API changes are fairly
|
||||||
common.
|
common.
|
||||||
|
|
||||||
License
|
## License
|
||||||
-------
|
|
||||||
|
|
||||||
TinyXML-2 is released under the zlib license:
|
TinyXML-2 is released under the zlib license:
|
||||||
|
|
||||||
@@ -316,8 +334,7 @@ must not be misrepresented as being the original software.
|
|||||||
3. This notice may not be removed or altered from any source
|
3. This notice may not be removed or altered from any source
|
||||||
distribution.
|
distribution.
|
||||||
|
|
||||||
Contributors
|
## Contributors
|
||||||
------------
|
|
||||||
|
|
||||||
Thanks very much to everyone who sends suggestions, bugs, ideas, and
|
Thanks very much to everyone who sends suggestions, bugs, ideas, and
|
||||||
encouragement. It all helps, and makes this project fun.
|
encouragement. It all helps, and makes this project fun.
|
||||||
|
|||||||
Executable → Regular
Executable → Regular
Executable → Regular
Executable → Regular
+230
-233
File diff suppressed because it is too large
Load Diff
Executable → Regular
+142
-142
@@ -24,15 +24,12 @@ distribution.
|
|||||||
#ifndef TINYXML2_INCLUDED
|
#ifndef TINYXML2_INCLUDED
|
||||||
#define TINYXML2_INCLUDED
|
#define TINYXML2_INCLUDED
|
||||||
|
|
||||||
#if defined(ANDROID_NDK) || defined(__BORLANDC__) || defined(__QNXNTO__)
|
#if defined(ANDROID_NDK)
|
||||||
# include <ctype.h>
|
# include <ctype.h>
|
||||||
# include <limits.h>
|
# include <limits.h>
|
||||||
# include <stdio.h>
|
# include <stdio.h>
|
||||||
# include <stdlib.h>
|
# include <stdlib.h>
|
||||||
# include <string.h>
|
# include <string.h>
|
||||||
# if defined(__PS3__)
|
|
||||||
# include <stddef.h>
|
|
||||||
# endif
|
|
||||||
#else
|
#else
|
||||||
# include <cctype>
|
# include <cctype>
|
||||||
# include <climits>
|
# include <climits>
|
||||||
@@ -40,15 +37,7 @@ distribution.
|
|||||||
# include <cstdlib>
|
# include <cstdlib>
|
||||||
# include <cstring>
|
# include <cstring>
|
||||||
#endif
|
#endif
|
||||||
#include <stdint.h>
|
#include <cstdint>
|
||||||
|
|
||||||
/*
|
|
||||||
gcc:
|
|
||||||
g++ -Wall -DTINYXML2_DEBUG tinyxml2.cpp xmltest.cpp -o gccxmltest.exe
|
|
||||||
|
|
||||||
Formatting, Artistic Style:
|
|
||||||
AStyle.exe --style=1tbs --indent-switches --break-closing-brackets --indent-preprocessor tinyxml2.cpp tinyxml2.h
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if defined( _DEBUG ) || defined (__DEBUG__)
|
#if defined( _DEBUG ) || defined (__DEBUG__)
|
||||||
# ifndef TINYXML2_DEBUG
|
# ifndef TINYXML2_DEBUG
|
||||||
@@ -93,14 +82,22 @@ distribution.
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(__cplusplus) && __cplusplus >= 201703L
|
||||||
|
#define TINYXML2_CONSTANT inline constexpr
|
||||||
|
#elif defined(__cplusplus) && __cplusplus >= 201103L
|
||||||
|
#define TINYXML2_CONSTANT static constexpr
|
||||||
|
#else
|
||||||
|
#define TINYXML2_CONSTANT static const
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Versioning, past 1.0.14:
|
/* Versioning, past 1.0.14:
|
||||||
http://semver.org/
|
http://semver.org/
|
||||||
*/
|
*/
|
||||||
static const int TIXML2_MAJOR_VERSION = 10;
|
TINYXML2_CONSTANT int TIXML2_MAJOR_VERSION = 11;
|
||||||
static const int TIXML2_MINOR_VERSION = 0;
|
TINYXML2_CONSTANT int TIXML2_MINOR_VERSION = 0;
|
||||||
static const int TIXML2_PATCH_VERSION = 0;
|
TINYXML2_CONSTANT int TIXML2_PATCH_VERSION = 0;
|
||||||
|
|
||||||
#define TINYXML2_MAJOR_VERSION 10
|
#define TINYXML2_MAJOR_VERSION 11
|
||||||
#define TINYXML2_MINOR_VERSION 0
|
#define TINYXML2_MINOR_VERSION 0
|
||||||
#define TINYXML2_PATCH_VERSION 0
|
#define TINYXML2_PATCH_VERSION 0
|
||||||
|
|
||||||
@@ -109,7 +106,7 @@ static const int TIXML2_PATCH_VERSION = 0;
|
|||||||
// system, and the capacity of the stack. On the other hand, it's a trivial
|
// system, and the capacity of the stack. On the other hand, it's a trivial
|
||||||
// attack that can result from ill, malicious, or even correctly formed XML,
|
// attack that can result from ill, malicious, or even correctly formed XML,
|
||||||
// so there needs to be a limit in place.
|
// so there needs to be a limit in place.
|
||||||
static const int TINYXML2_MAX_ELEMENT_DEPTH = 500;
|
TINYXML2_CONSTANT int TINYXML2_MAX_ELEMENT_DEPTH = 500;
|
||||||
|
|
||||||
namespace tinyxml2
|
namespace tinyxml2
|
||||||
{
|
{
|
||||||
@@ -146,7 +143,7 @@ public:
|
|||||||
COMMENT = NEEDS_NEWLINE_NORMALIZATION
|
COMMENT = NEEDS_NEWLINE_NORMALIZATION
|
||||||
};
|
};
|
||||||
|
|
||||||
StrPair() : _flags( 0 ), _start( 0 ), _end( 0 ) {}
|
StrPair() : _flags( 0 ), _start( nullptr ), _end( nullptr ) {}
|
||||||
~StrPair();
|
~StrPair();
|
||||||
|
|
||||||
void Set( char* start, char* end, int flags ) {
|
void Set( char* start, char* end, int flags ) {
|
||||||
@@ -189,8 +186,8 @@ private:
|
|||||||
char* _start;
|
char* _start;
|
||||||
char* _end;
|
char* _end;
|
||||||
|
|
||||||
StrPair( const StrPair& other ); // not supported
|
StrPair( const StrPair& ) = delete;
|
||||||
void operator=( const StrPair& other ); // not supported, use TransferTo()
|
StrPair& operator=( const StrPair& ) = delete;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -199,7 +196,7 @@ private:
|
|||||||
Has a small initial memory pool, so that low or no usage will not
|
Has a small initial memory pool, so that low or no usage will not
|
||||||
cause a call to new/delete
|
cause a call to new/delete
|
||||||
*/
|
*/
|
||||||
template <class T, int INITIAL_SIZE>
|
template <class T, size_t INITIAL_SIZE>
|
||||||
class DynArray
|
class DynArray
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -227,9 +224,8 @@ public:
|
|||||||
++_size;
|
++_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
T* PushArr( int count ) {
|
T* PushArr( size_t count ) {
|
||||||
TIXMLASSERT( count >= 0 );
|
TIXMLASSERT( _size <= SIZE_MAX - count );
|
||||||
TIXMLASSERT( _size <= INT_MAX - count );
|
|
||||||
EnsureCapacity( _size+count );
|
EnsureCapacity( _size+count );
|
||||||
T* ret = &_mem[_size];
|
T* ret = &_mem[_size];
|
||||||
_size += count;
|
_size += count;
|
||||||
@@ -242,7 +238,7 @@ public:
|
|||||||
return _mem[_size];
|
return _mem[_size];
|
||||||
}
|
}
|
||||||
|
|
||||||
void PopArr( int count ) {
|
void PopArr( size_t count ) {
|
||||||
TIXMLASSERT( _size >= count );
|
TIXMLASSERT( _size >= count );
|
||||||
_size -= count;
|
_size -= count;
|
||||||
}
|
}
|
||||||
@@ -251,13 +247,13 @@ public:
|
|||||||
return _size == 0;
|
return _size == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
T& operator[](int i) {
|
T& operator[](size_t i) {
|
||||||
TIXMLASSERT( i>= 0 && i < _size );
|
TIXMLASSERT( i < _size );
|
||||||
return _mem[i];
|
return _mem[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
const T& operator[](int i) const {
|
const T& operator[](size_t i) const {
|
||||||
TIXMLASSERT( i>= 0 && i < _size );
|
TIXMLASSERT( i < _size );
|
||||||
return _mem[i];
|
return _mem[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -266,18 +262,17 @@ public:
|
|||||||
return _mem[ _size - 1];
|
return _mem[ _size - 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
int Size() const {
|
size_t Size() const {
|
||||||
TIXMLASSERT( _size >= 0 );
|
|
||||||
return _size;
|
return _size;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Capacity() const {
|
size_t Capacity() const {
|
||||||
TIXMLASSERT( _allocated >= INITIAL_SIZE );
|
TIXMLASSERT( _allocated >= INITIAL_SIZE );
|
||||||
return _allocated;
|
return _allocated;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SwapRemove(int i) {
|
void SwapRemove(size_t i) {
|
||||||
TIXMLASSERT(i >= 0 && i < _size);
|
TIXMLASSERT(i < _size);
|
||||||
TIXMLASSERT(_size > 0);
|
TIXMLASSERT(_size > 0);
|
||||||
_mem[i] = _mem[_size - 1];
|
_mem[i] = _mem[_size - 1];
|
||||||
--_size;
|
--_size;
|
||||||
@@ -294,17 +289,17 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DynArray( const DynArray& ); // not supported
|
DynArray( const DynArray& ) = delete;
|
||||||
void operator=( const DynArray& ); // not supported
|
DynArray& operator=( const DynArray& ) = delete;
|
||||||
|
|
||||||
void EnsureCapacity( int cap ) {
|
void EnsureCapacity( size_t cap ) {
|
||||||
TIXMLASSERT( cap > 0 );
|
TIXMLASSERT( cap > 0 );
|
||||||
if ( cap > _allocated ) {
|
if ( cap > _allocated ) {
|
||||||
TIXMLASSERT( cap <= INT_MAX / 2 );
|
TIXMLASSERT( cap <= SIZE_MAX / 2 / sizeof(T));
|
||||||
const int newAllocated = cap * 2;
|
const size_t newAllocated = cap * 2;
|
||||||
T* newMem = new T[static_cast<unsigned int>(newAllocated)];
|
T* newMem = new T[newAllocated];
|
||||||
TIXMLASSERT( newAllocated >= _size );
|
TIXMLASSERT( newAllocated >= _size );
|
||||||
memcpy( newMem, _mem, sizeof(T)*static_cast<size_t>(_size) ); // warning: not using constructors, only works for PODs
|
memcpy( newMem, _mem, sizeof(T) * _size ); // warning: not using constructors, only works for PODs
|
||||||
if ( _mem != _pool ) {
|
if ( _mem != _pool ) {
|
||||||
delete [] _mem;
|
delete [] _mem;
|
||||||
}
|
}
|
||||||
@@ -314,9 +309,9 @@ private:
|
|||||||
}
|
}
|
||||||
|
|
||||||
T* _mem;
|
T* _mem;
|
||||||
T _pool[static_cast<size_t>(INITIAL_SIZE)];
|
T _pool[INITIAL_SIZE];
|
||||||
int _allocated; // objects allocated
|
size_t _allocated; // objects allocated
|
||||||
int _size; // number objects in use
|
size_t _size; // number objects in use
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -330,7 +325,7 @@ public:
|
|||||||
MemPool() {}
|
MemPool() {}
|
||||||
virtual ~MemPool() {}
|
virtual ~MemPool() {}
|
||||||
|
|
||||||
virtual int ItemSize() const = 0;
|
virtual size_t ItemSize() const = 0;
|
||||||
virtual void* Alloc() = 0;
|
virtual void* Alloc() = 0;
|
||||||
virtual void Free( void* ) = 0;
|
virtual void Free( void* ) = 0;
|
||||||
virtual void SetTracked() = 0;
|
virtual void SetTracked() = 0;
|
||||||
@@ -340,11 +335,11 @@ public:
|
|||||||
/*
|
/*
|
||||||
Template child class to create pools of the correct type.
|
Template child class to create pools of the correct type.
|
||||||
*/
|
*/
|
||||||
template< int ITEM_SIZE >
|
template< size_t ITEM_SIZE >
|
||||||
class MemPoolT : public MemPool
|
class MemPoolT : public MemPool
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
MemPoolT() : _blockPtrs(), _root(0), _currentAllocs(0), _nAllocs(0), _maxAllocs(0), _nUntracked(0) {}
|
MemPoolT() : _blockPtrs(), _root(nullptr), _currentAllocs(0), _nAllocs(0), _maxAllocs(0), _nUntracked(0) {}
|
||||||
~MemPoolT() {
|
~MemPoolT() {
|
||||||
MemPoolT< ITEM_SIZE >::Clear();
|
MemPoolT< ITEM_SIZE >::Clear();
|
||||||
}
|
}
|
||||||
@@ -355,17 +350,17 @@ public:
|
|||||||
Block* lastBlock = _blockPtrs.Pop();
|
Block* lastBlock = _blockPtrs.Pop();
|
||||||
delete lastBlock;
|
delete lastBlock;
|
||||||
}
|
}
|
||||||
_root = 0;
|
_root = nullptr;
|
||||||
_currentAllocs = 0;
|
_currentAllocs = 0;
|
||||||
_nAllocs = 0;
|
_nAllocs = 0;
|
||||||
_maxAllocs = 0;
|
_maxAllocs = 0;
|
||||||
_nUntracked = 0;
|
_nUntracked = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual int ItemSize() const override{
|
virtual size_t ItemSize() const override {
|
||||||
return ITEM_SIZE;
|
return ITEM_SIZE;
|
||||||
}
|
}
|
||||||
int CurrentAllocs() const {
|
size_t CurrentAllocs() const {
|
||||||
return _currentAllocs;
|
return _currentAllocs;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -376,14 +371,14 @@ public:
|
|||||||
_blockPtrs.Push( block );
|
_blockPtrs.Push( block );
|
||||||
|
|
||||||
Item* blockItems = block->items;
|
Item* blockItems = block->items;
|
||||||
for( int i = 0; i < ITEMS_PER_BLOCK - 1; ++i ) {
|
for( size_t i = 0; i < ITEMS_PER_BLOCK - 1; ++i ) {
|
||||||
blockItems[i].next = &(blockItems[i + 1]);
|
blockItems[i].next = &(blockItems[i + 1]);
|
||||||
}
|
}
|
||||||
blockItems[ITEMS_PER_BLOCK - 1].next = 0;
|
blockItems[ITEMS_PER_BLOCK - 1].next = nullptr;
|
||||||
_root = blockItems;
|
_root = blockItems;
|
||||||
}
|
}
|
||||||
Item* const result = _root;
|
Item* const result = _root;
|
||||||
TIXMLASSERT( result != 0 );
|
TIXMLASSERT( result != nullptr );
|
||||||
_root = _root->next;
|
_root = _root->next;
|
||||||
|
|
||||||
++_currentAllocs;
|
++_currentAllocs;
|
||||||
@@ -417,7 +412,7 @@ public:
|
|||||||
--_nUntracked;
|
--_nUntracked;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Untracked() const {
|
size_t Untracked() const {
|
||||||
return _nUntracked;
|
return _nUntracked;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -435,8 +430,8 @@ public:
|
|||||||
enum { ITEMS_PER_BLOCK = (4 * 1024) / ITEM_SIZE };
|
enum { ITEMS_PER_BLOCK = (4 * 1024) / ITEM_SIZE };
|
||||||
|
|
||||||
private:
|
private:
|
||||||
MemPoolT( const MemPoolT& ); // not supported
|
MemPoolT( const MemPoolT& ) = delete;
|
||||||
void operator=( const MemPoolT& ); // not supported
|
MemPoolT& operator=( const MemPoolT& ) = delete;
|
||||||
|
|
||||||
union Item {
|
union Item {
|
||||||
Item* next;
|
Item* next;
|
||||||
@@ -448,10 +443,10 @@ private:
|
|||||||
DynArray< Block*, 10 > _blockPtrs;
|
DynArray< Block*, 10 > _blockPtrs;
|
||||||
Item* _root;
|
Item* _root;
|
||||||
|
|
||||||
int _currentAllocs;
|
size_t _currentAllocs;
|
||||||
int _nAllocs;
|
size_t _nAllocs;
|
||||||
int _maxAllocs;
|
size_t _maxAllocs;
|
||||||
int _nUntracked;
|
size_t _nUntracked;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -687,46 +682,46 @@ public:
|
|||||||
|
|
||||||
/// Safely cast to an Element, or null.
|
/// Safely cast to an Element, or null.
|
||||||
virtual XMLElement* ToElement() {
|
virtual XMLElement* ToElement() {
|
||||||
return 0;
|
return nullptr;
|
||||||
}
|
}
|
||||||
/// Safely cast to Text, or null.
|
/// Safely cast to Text, or null.
|
||||||
virtual XMLText* ToText() {
|
virtual XMLText* ToText() {
|
||||||
return 0;
|
return nullptr;
|
||||||
}
|
}
|
||||||
/// Safely cast to a Comment, or null.
|
/// Safely cast to a Comment, or null.
|
||||||
virtual XMLComment* ToComment() {
|
virtual XMLComment* ToComment() {
|
||||||
return 0;
|
return nullptr;
|
||||||
}
|
}
|
||||||
/// Safely cast to a Document, or null.
|
/// Safely cast to a Document, or null.
|
||||||
virtual XMLDocument* ToDocument() {
|
virtual XMLDocument* ToDocument() {
|
||||||
return 0;
|
return nullptr;
|
||||||
}
|
}
|
||||||
/// Safely cast to a Declaration, or null.
|
/// Safely cast to a Declaration, or null.
|
||||||
virtual XMLDeclaration* ToDeclaration() {
|
virtual XMLDeclaration* ToDeclaration() {
|
||||||
return 0;
|
return nullptr;
|
||||||
}
|
}
|
||||||
/// Safely cast to an Unknown, or null.
|
/// Safely cast to an Unknown, or null.
|
||||||
virtual XMLUnknown* ToUnknown() {
|
virtual XMLUnknown* ToUnknown() {
|
||||||
return 0;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual const XMLElement* ToElement() const {
|
virtual const XMLElement* ToElement() const {
|
||||||
return 0;
|
return nullptr;
|
||||||
}
|
}
|
||||||
virtual const XMLText* ToText() const {
|
virtual const XMLText* ToText() const {
|
||||||
return 0;
|
return nullptr;
|
||||||
}
|
}
|
||||||
virtual const XMLComment* ToComment() const {
|
virtual const XMLComment* ToComment() const {
|
||||||
return 0;
|
return nullptr;
|
||||||
}
|
}
|
||||||
virtual const XMLDocument* ToDocument() const {
|
virtual const XMLDocument* ToDocument() const {
|
||||||
return 0;
|
return nullptr;
|
||||||
}
|
}
|
||||||
virtual const XMLDeclaration* ToDeclaration() const {
|
virtual const XMLDeclaration* ToDeclaration() const {
|
||||||
return 0;
|
return nullptr;
|
||||||
}
|
}
|
||||||
virtual const XMLUnknown* ToUnknown() const {
|
virtual const XMLUnknown* ToUnknown() const {
|
||||||
return 0;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ChildElementCount was originally suggested by msteiger on the sourceforge page for TinyXML and modified by KB1SPH for TinyXML-2.
|
// ChildElementCount was originally suggested by msteiger on the sourceforge page for TinyXML and modified by KB1SPH for TinyXML-2.
|
||||||
@@ -780,9 +775,9 @@ public:
|
|||||||
/** Get the first child element, or optionally the first child
|
/** Get the first child element, or optionally the first child
|
||||||
element with the specified name.
|
element with the specified name.
|
||||||
*/
|
*/
|
||||||
const XMLElement* FirstChildElement( const char* name = 0 ) const;
|
const XMLElement* FirstChildElement( const char* name = nullptr ) const;
|
||||||
|
|
||||||
XMLElement* FirstChildElement( const char* name = 0 ) {
|
XMLElement* FirstChildElement( const char* name = nullptr ) {
|
||||||
return const_cast<XMLElement*>(const_cast<const XMLNode*>(this)->FirstChildElement( name ));
|
return const_cast<XMLElement*>(const_cast<const XMLNode*>(this)->FirstChildElement( name ));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -798,9 +793,9 @@ public:
|
|||||||
/** Get the last child element or optionally the last child
|
/** Get the last child element or optionally the last child
|
||||||
element with the specified name.
|
element with the specified name.
|
||||||
*/
|
*/
|
||||||
const XMLElement* LastChildElement( const char* name = 0 ) const;
|
const XMLElement* LastChildElement( const char* name = nullptr ) const;
|
||||||
|
|
||||||
XMLElement* LastChildElement( const char* name = 0 ) {
|
XMLElement* LastChildElement( const char* name = nullptr ) {
|
||||||
return const_cast<XMLElement*>(const_cast<const XMLNode*>(this)->LastChildElement(name) );
|
return const_cast<XMLElement*>(const_cast<const XMLNode*>(this)->LastChildElement(name) );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -814,9 +809,9 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Get the previous (left) sibling element of this node, with an optionally supplied name.
|
/// Get the previous (left) sibling element of this node, with an optionally supplied name.
|
||||||
const XMLElement* PreviousSiblingElement( const char* name = 0 ) const ;
|
const XMLElement* PreviousSiblingElement( const char* name = nullptr ) const ;
|
||||||
|
|
||||||
XMLElement* PreviousSiblingElement( const char* name = 0 ) {
|
XMLElement* PreviousSiblingElement( const char* name = nullptr ) {
|
||||||
return const_cast<XMLElement*>(const_cast<const XMLNode*>(this)->PreviousSiblingElement( name ) );
|
return const_cast<XMLElement*>(const_cast<const XMLNode*>(this)->PreviousSiblingElement( name ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -830,9 +825,9 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Get the next (right) sibling element of this node, with an optionally supplied name.
|
/// Get the next (right) sibling element of this node, with an optionally supplied name.
|
||||||
const XMLElement* NextSiblingElement( const char* name = 0 ) const;
|
const XMLElement* NextSiblingElement( const char* name = nullptr ) const;
|
||||||
|
|
||||||
XMLElement* NextSiblingElement( const char* name = 0 ) {
|
XMLElement* NextSiblingElement( const char* name = nullptr ) {
|
||||||
return const_cast<XMLElement*>(const_cast<const XMLNode*>(this)->NextSiblingElement( name ) );
|
return const_cast<XMLElement*>(const_cast<const XMLNode*>(this)->NextSiblingElement( name ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -892,7 +887,7 @@ public:
|
|||||||
|
|
||||||
If the 'target' is null, then the nodes will
|
If the 'target' is null, then the nodes will
|
||||||
be allocated in the current document. If 'target'
|
be allocated in the current document. If 'target'
|
||||||
is specified, the memory will be allocated is the
|
is specified, the memory will be allocated in the
|
||||||
specified XMLDocument.
|
specified XMLDocument.
|
||||||
|
|
||||||
NOTE: This is probably not the correct tool to
|
NOTE: This is probably not the correct tool to
|
||||||
@@ -974,8 +969,8 @@ private:
|
|||||||
void InsertChildPreamble( XMLNode* insertThis ) const;
|
void InsertChildPreamble( XMLNode* insertThis ) const;
|
||||||
const XMLElement* ToElementWithName( const char* name ) const;
|
const XMLElement* ToElementWithName( const char* name ) const;
|
||||||
|
|
||||||
XMLNode( const XMLNode& ); // not supported
|
XMLNode( const XMLNode& ) = delete;
|
||||||
XMLNode& operator=( const XMLNode& ); // not supported
|
XMLNode& operator=( const XMLNode& ) = delete;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -1025,8 +1020,8 @@ protected:
|
|||||||
private:
|
private:
|
||||||
bool _isCData;
|
bool _isCData;
|
||||||
|
|
||||||
XMLText( const XMLText& ); // not supported
|
XMLText( const XMLText& ) = delete;
|
||||||
XMLText& operator=( const XMLText& ); // not supported
|
XMLText& operator=( const XMLText& ) = delete;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -1054,8 +1049,8 @@ protected:
|
|||||||
char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr) override;
|
char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
XMLComment( const XMLComment& ); // not supported
|
XMLComment( const XMLComment& ) = delete;
|
||||||
XMLComment& operator=( const XMLComment& ); // not supported
|
XMLComment& operator=( const XMLComment& ) = delete;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -1093,8 +1088,8 @@ protected:
|
|||||||
char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr ) override;
|
char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr ) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
XMLDeclaration( const XMLDeclaration& ); // not supported
|
XMLDeclaration( const XMLDeclaration& ) = delete;
|
||||||
XMLDeclaration& operator=( const XMLDeclaration& ); // not supported
|
XMLDeclaration& operator=( const XMLDeclaration& ) = delete;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -1128,8 +1123,8 @@ protected:
|
|||||||
char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr ) override;
|
char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr ) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
XMLUnknown( const XMLUnknown& ); // not supported
|
XMLUnknown( const XMLUnknown& ) = delete;
|
||||||
XMLUnknown& operator=( const XMLUnknown& ); // not supported
|
XMLUnknown& operator=( const XMLUnknown& ) = delete;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -1243,11 +1238,11 @@ public:
|
|||||||
private:
|
private:
|
||||||
enum { BUF_SIZE = 200 };
|
enum { BUF_SIZE = 200 };
|
||||||
|
|
||||||
XMLAttribute() : _name(), _value(),_parseLineNum( 0 ), _next( 0 ), _memPool( 0 ) {}
|
XMLAttribute() : _name(), _value(),_parseLineNum( 0 ), _next( nullptr ), _memPool( nullptr ) {}
|
||||||
virtual ~XMLAttribute() {}
|
virtual ~XMLAttribute() {}
|
||||||
|
|
||||||
XMLAttribute( const XMLAttribute& ); // not supported
|
XMLAttribute( const XMLAttribute& ) = delete;
|
||||||
void operator=( const XMLAttribute& ); // not supported
|
XMLAttribute& operator=( const XMLAttribute& ) = delete;
|
||||||
void SetName( const char* name );
|
void SetName( const char* name );
|
||||||
|
|
||||||
char* ParseDeep( char* p, bool processEntities, int* curLineNumPtr );
|
char* ParseDeep( char* p, bool processEntities, int* curLineNumPtr );
|
||||||
@@ -1308,7 +1303,7 @@ public:
|
|||||||
}
|
}
|
||||||
@endverbatim
|
@endverbatim
|
||||||
*/
|
*/
|
||||||
const char* Attribute( const char* name, const char* value=0 ) const;
|
const char* Attribute( const char* name, const char* value=nullptr ) const;
|
||||||
|
|
||||||
/** Given an attribute name, IntAttribute() returns the value
|
/** Given an attribute name, IntAttribute() returns the value
|
||||||
of the attribute interpreted as an integer. The default
|
of the attribute interpreted as an integer. The default
|
||||||
@@ -1688,8 +1683,8 @@ protected:
|
|||||||
private:
|
private:
|
||||||
XMLElement( XMLDocument* doc );
|
XMLElement( XMLDocument* doc );
|
||||||
virtual ~XMLElement();
|
virtual ~XMLElement();
|
||||||
XMLElement( const XMLElement& ); // not supported
|
XMLElement( const XMLElement& ) = delete;
|
||||||
void operator=( const XMLElement& ); // not supported
|
XMLElement& operator=( const XMLElement& ) = delete;
|
||||||
|
|
||||||
XMLAttribute* FindOrCreateAttribute( const char* name );
|
XMLAttribute* FindOrCreateAttribute( const char* name );
|
||||||
char* ParseAttributes( char* p, int* curLineNumPtr );
|
char* ParseAttributes( char* p, int* curLineNumPtr );
|
||||||
@@ -1832,7 +1827,7 @@ public:
|
|||||||
// printer.CStr() has a const char* to the XML
|
// printer.CStr() has a const char* to the XML
|
||||||
@endverbatim
|
@endverbatim
|
||||||
*/
|
*/
|
||||||
void Print( XMLPrinter* streamer=0 ) const;
|
void Print( XMLPrinter* streamer=nullptr ) const;
|
||||||
virtual bool Accept( XMLVisitor* visitor ) const override;
|
virtual bool Accept( XMLVisitor* visitor ) const override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1864,7 +1859,7 @@ public:
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
@endverbatim
|
@endverbatim
|
||||||
*/
|
*/
|
||||||
XMLDeclaration* NewDeclaration( const char* text=0 );
|
XMLDeclaration* NewDeclaration( const char* text=nullptr );
|
||||||
/**
|
/**
|
||||||
Create a new Unknown associated with
|
Create a new Unknown associated with
|
||||||
this Document. The memory for the object
|
this Document. The memory for the object
|
||||||
@@ -1932,8 +1927,8 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
XMLDocument( const XMLDocument& ); // not supported
|
XMLDocument( const XMLDocument& ) = delete;
|
||||||
void operator=( const XMLDocument& ); // not supported
|
XMLDocument& operator=( const XMLDocument& ) = delete;
|
||||||
|
|
||||||
bool _writeBOM;
|
bool _writeBOM;
|
||||||
bool _processEntities;
|
bool _processEntities;
|
||||||
@@ -1981,11 +1976,11 @@ private:
|
|||||||
void PushDepth();
|
void PushDepth();
|
||||||
void PopDepth();
|
void PopDepth();
|
||||||
|
|
||||||
template<class NodeType, int PoolElementSize>
|
template<class NodeType, size_t PoolElementSize>
|
||||||
NodeType* CreateUnlinkedNode( MemPoolT<PoolElementSize>& pool );
|
NodeType* CreateUnlinkedNode( MemPoolT<PoolElementSize>& pool );
|
||||||
};
|
};
|
||||||
|
|
||||||
template<class NodeType, int PoolElementSize>
|
template<class NodeType, size_t PoolElementSize>
|
||||||
inline NodeType* XMLDocument::CreateUnlinkedNode( MemPoolT<PoolElementSize>& pool )
|
inline NodeType* XMLDocument::CreateUnlinkedNode( MemPoolT<PoolElementSize>& pool )
|
||||||
{
|
{
|
||||||
TIXMLASSERT( sizeof( NodeType ) == PoolElementSize );
|
TIXMLASSERT( sizeof( NodeType ) == PoolElementSize );
|
||||||
@@ -2073,35 +2068,35 @@ public:
|
|||||||
|
|
||||||
/// Get the first child of this handle.
|
/// Get the first child of this handle.
|
||||||
XMLHandle FirstChild() {
|
XMLHandle FirstChild() {
|
||||||
return XMLHandle( _node ? _node->FirstChild() : 0 );
|
return XMLHandle( _node ? _node->FirstChild() : nullptr );
|
||||||
}
|
}
|
||||||
/// Get the first child element of this handle.
|
/// Get the first child element of this handle.
|
||||||
XMLHandle FirstChildElement( const char* name = 0 ) {
|
XMLHandle FirstChildElement( const char* name = nullptr ) {
|
||||||
return XMLHandle( _node ? _node->FirstChildElement( name ) : 0 );
|
return XMLHandle( _node ? _node->FirstChildElement( name ) : nullptr );
|
||||||
}
|
}
|
||||||
/// Get the last child of this handle.
|
/// Get the last child of this handle.
|
||||||
XMLHandle LastChild() {
|
XMLHandle LastChild() {
|
||||||
return XMLHandle( _node ? _node->LastChild() : 0 );
|
return XMLHandle( _node ? _node->LastChild() : nullptr );
|
||||||
}
|
}
|
||||||
/// Get the last child element of this handle.
|
/// Get the last child element of this handle.
|
||||||
XMLHandle LastChildElement( const char* name = 0 ) {
|
XMLHandle LastChildElement( const char* name = nullptr ) {
|
||||||
return XMLHandle( _node ? _node->LastChildElement( name ) : 0 );
|
return XMLHandle( _node ? _node->LastChildElement( name ) : nullptr );
|
||||||
}
|
}
|
||||||
/// Get the previous sibling of this handle.
|
/// Get the previous sibling of this handle.
|
||||||
XMLHandle PreviousSibling() {
|
XMLHandle PreviousSibling() {
|
||||||
return XMLHandle( _node ? _node->PreviousSibling() : 0 );
|
return XMLHandle( _node ? _node->PreviousSibling() : nullptr );
|
||||||
}
|
}
|
||||||
/// Get the previous sibling element of this handle.
|
/// Get the previous sibling element of this handle.
|
||||||
XMLHandle PreviousSiblingElement( const char* name = 0 ) {
|
XMLHandle PreviousSiblingElement( const char* name = nullptr ) {
|
||||||
return XMLHandle( _node ? _node->PreviousSiblingElement( name ) : 0 );
|
return XMLHandle( _node ? _node->PreviousSiblingElement( name ) : nullptr );
|
||||||
}
|
}
|
||||||
/// Get the next sibling of this handle.
|
/// Get the next sibling of this handle.
|
||||||
XMLHandle NextSibling() {
|
XMLHandle NextSibling() {
|
||||||
return XMLHandle( _node ? _node->NextSibling() : 0 );
|
return XMLHandle( _node ? _node->NextSibling() : nullptr );
|
||||||
}
|
}
|
||||||
/// Get the next sibling element of this handle.
|
/// Get the next sibling element of this handle.
|
||||||
XMLHandle NextSiblingElement( const char* name = 0 ) {
|
XMLHandle NextSiblingElement( const char* name = nullptr ) {
|
||||||
return XMLHandle( _node ? _node->NextSiblingElement( name ) : 0 );
|
return XMLHandle( _node ? _node->NextSiblingElement( name ) : nullptr );
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Safe cast to XMLNode. This can return null.
|
/// Safe cast to XMLNode. This can return null.
|
||||||
@@ -2110,19 +2105,19 @@ public:
|
|||||||
}
|
}
|
||||||
/// Safe cast to XMLElement. This can return null.
|
/// Safe cast to XMLElement. This can return null.
|
||||||
XMLElement* ToElement() {
|
XMLElement* ToElement() {
|
||||||
return ( _node ? _node->ToElement() : 0 );
|
return ( _node ? _node->ToElement() : nullptr );
|
||||||
}
|
}
|
||||||
/// Safe cast to XMLText. This can return null.
|
/// Safe cast to XMLText. This can return null.
|
||||||
XMLText* ToText() {
|
XMLText* ToText() {
|
||||||
return ( _node ? _node->ToText() : 0 );
|
return ( _node ? _node->ToText() : nullptr );
|
||||||
}
|
}
|
||||||
/// Safe cast to XMLUnknown. This can return null.
|
/// Safe cast to XMLUnknown. This can return null.
|
||||||
XMLUnknown* ToUnknown() {
|
XMLUnknown* ToUnknown() {
|
||||||
return ( _node ? _node->ToUnknown() : 0 );
|
return ( _node ? _node->ToUnknown() : nullptr );
|
||||||
}
|
}
|
||||||
/// Safe cast to XMLDeclaration. This can return null.
|
/// Safe cast to XMLDeclaration. This can return null.
|
||||||
XMLDeclaration* ToDeclaration() {
|
XMLDeclaration* ToDeclaration() {
|
||||||
return ( _node ? _node->ToDeclaration() : 0 );
|
return ( _node ? _node->ToDeclaration() : nullptr );
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -2150,28 +2145,28 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
const XMLConstHandle FirstChild() const {
|
const XMLConstHandle FirstChild() const {
|
||||||
return XMLConstHandle( _node ? _node->FirstChild() : 0 );
|
return XMLConstHandle( _node ? _node->FirstChild() : nullptr );
|
||||||
}
|
}
|
||||||
const XMLConstHandle FirstChildElement( const char* name = 0 ) const {
|
const XMLConstHandle FirstChildElement( const char* name = nullptr ) const {
|
||||||
return XMLConstHandle( _node ? _node->FirstChildElement( name ) : 0 );
|
return XMLConstHandle( _node ? _node->FirstChildElement( name ) : nullptr );
|
||||||
}
|
}
|
||||||
const XMLConstHandle LastChild() const {
|
const XMLConstHandle LastChild() const {
|
||||||
return XMLConstHandle( _node ? _node->LastChild() : 0 );
|
return XMLConstHandle( _node ? _node->LastChild() : nullptr );
|
||||||
}
|
}
|
||||||
const XMLConstHandle LastChildElement( const char* name = 0 ) const {
|
const XMLConstHandle LastChildElement( const char* name = nullptr ) const {
|
||||||
return XMLConstHandle( _node ? _node->LastChildElement( name ) : 0 );
|
return XMLConstHandle( _node ? _node->LastChildElement( name ) : nullptr );
|
||||||
}
|
}
|
||||||
const XMLConstHandle PreviousSibling() const {
|
const XMLConstHandle PreviousSibling() const {
|
||||||
return XMLConstHandle( _node ? _node->PreviousSibling() : 0 );
|
return XMLConstHandle( _node ? _node->PreviousSibling() : nullptr );
|
||||||
}
|
}
|
||||||
const XMLConstHandle PreviousSiblingElement( const char* name = 0 ) const {
|
const XMLConstHandle PreviousSiblingElement( const char* name = nullptr ) const {
|
||||||
return XMLConstHandle( _node ? _node->PreviousSiblingElement( name ) : 0 );
|
return XMLConstHandle( _node ? _node->PreviousSiblingElement( name ) : nullptr );
|
||||||
}
|
}
|
||||||
const XMLConstHandle NextSibling() const {
|
const XMLConstHandle NextSibling() const {
|
||||||
return XMLConstHandle( _node ? _node->NextSibling() : 0 );
|
return XMLConstHandle( _node ? _node->NextSibling() : nullptr );
|
||||||
}
|
}
|
||||||
const XMLConstHandle NextSiblingElement( const char* name = 0 ) const {
|
const XMLConstHandle NextSiblingElement( const char* name = nullptr ) const {
|
||||||
return XMLConstHandle( _node ? _node->NextSiblingElement( name ) : 0 );
|
return XMLConstHandle( _node ? _node->NextSiblingElement( name ) : nullptr );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -2179,16 +2174,16 @@ public:
|
|||||||
return _node;
|
return _node;
|
||||||
}
|
}
|
||||||
const XMLElement* ToElement() const {
|
const XMLElement* ToElement() const {
|
||||||
return ( _node ? _node->ToElement() : 0 );
|
return ( _node ? _node->ToElement() : nullptr );
|
||||||
}
|
}
|
||||||
const XMLText* ToText() const {
|
const XMLText* ToText() const {
|
||||||
return ( _node ? _node->ToText() : 0 );
|
return ( _node ? _node->ToText() : nullptr );
|
||||||
}
|
}
|
||||||
const XMLUnknown* ToUnknown() const {
|
const XMLUnknown* ToUnknown() const {
|
||||||
return ( _node ? _node->ToUnknown() : 0 );
|
return ( _node ? _node->ToUnknown() : nullptr );
|
||||||
}
|
}
|
||||||
const XMLDeclaration* ToDeclaration() const {
|
const XMLDeclaration* ToDeclaration() const {
|
||||||
return ( _node ? _node->ToDeclaration() : 0 );
|
return ( _node ? _node->ToDeclaration() : nullptr );
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -2241,13 +2236,18 @@ private:
|
|||||||
class TINYXML2_LIB XMLPrinter : public XMLVisitor
|
class TINYXML2_LIB XMLPrinter : public XMLVisitor
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
enum EscapeAposCharsInAttributes {
|
||||||
|
ESCAPE_APOS_CHARS_IN_ATTRIBUTES,
|
||||||
|
DONT_ESCAPE_APOS_CHARS_IN_ATTRIBUTES
|
||||||
|
};
|
||||||
|
|
||||||
/** Construct the printer. If the FILE* is specified,
|
/** Construct the printer. If the FILE* is specified,
|
||||||
this will print to the FILE. Else it will print
|
this will print to the FILE. Else it will print
|
||||||
to memory, and the result is available in CStr().
|
to memory, and the result is available in CStr().
|
||||||
If 'compact' is set to true, then output is created
|
If 'compact' is set to true, then output is created
|
||||||
with only required whitespace and newlines.
|
with only required whitespace and newlines.
|
||||||
*/
|
*/
|
||||||
XMLPrinter( FILE* file=0, bool compact = false, int depth = 0 );
|
XMLPrinter( FILE* file=nullptr, bool compact = false, int depth = 0, EscapeAposCharsInAttributes aposInAttributes = ESCAPE_APOS_CHARS_IN_ATTRIBUTES );
|
||||||
virtual ~XMLPrinter() {}
|
virtual ~XMLPrinter() {}
|
||||||
|
|
||||||
/** If streaming, write the BOM and declaration. */
|
/** If streaming, write the BOM and declaration. */
|
||||||
@@ -2315,7 +2315,7 @@ public:
|
|||||||
of the XML file in memory. (Note the size returned
|
of the XML file in memory. (Note the size returned
|
||||||
includes the terminating null.)
|
includes the terminating null.)
|
||||||
*/
|
*/
|
||||||
int CStrSize() const {
|
size_t CStrSize() const {
|
||||||
return _buffer.Size();
|
return _buffer.Size();
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
@@ -2369,13 +2369,13 @@ private:
|
|||||||
|
|
||||||
DynArray< char, 20 > _buffer;
|
DynArray< char, 20 > _buffer;
|
||||||
|
|
||||||
// Prohibit cloning, intentionally not implemented
|
// Prohibit cloning
|
||||||
XMLPrinter( const XMLPrinter& );
|
XMLPrinter( const XMLPrinter& ) = delete;
|
||||||
XMLPrinter& operator=( const XMLPrinter& );
|
XMLPrinter& operator=( const XMLPrinter& ) = delete;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
} // tinyxml2
|
} // namespace tinyxml2
|
||||||
|
|
||||||
#if defined(_MSC_VER)
|
#if defined(_MSC_VER)
|
||||||
# pragma warning(pop)
|
# pragma warning(pop)
|
||||||
|
|||||||
Executable → Regular
+153
-31
@@ -45,13 +45,15 @@ bool XMLTest (const char* testString, const char* expected, const char* found, b
|
|||||||
printf (" %s\n", testString);
|
printf (" %s\n", testString);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
const char* expectedStr = expected ? expected : "(null)";
|
||||||
|
const char* foundStr = found ? found : "(null)";
|
||||||
if ( extraNL ) {
|
if ( extraNL ) {
|
||||||
printf( " %s\n", testString );
|
printf( " %s\n", testString );
|
||||||
printf( "%s\n", expected );
|
printf( "%s\n", expectedStr );
|
||||||
printf( "%s\n", found );
|
printf( "%s\n", foundStr );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
printf (" %s [%s][%s]\n", testString, expected, found);
|
printf (" %s [%s][%s]\n", testString, expectedStr, foundStr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -324,9 +326,9 @@ int main( int argc, const char ** argv )
|
|||||||
|
|
||||||
printf( "Test file '%s' loaded. ErrorID=%d\n", argv[1], errorID );
|
printf( "Test file '%s' loaded. ErrorID=%d\n", argv[1], errorID );
|
||||||
if ( !errorID ) {
|
if ( !errorID ) {
|
||||||
printf( "Load time=%u\n", (unsigned)(loadTime - startTime) );
|
printf( "Load time=%u\n", static_cast<unsigned>(loadTime - startTime) );
|
||||||
printf( "Delete time=%u\n", (unsigned)(deleteTime - loadTime) );
|
printf( "Delete time=%u\n", static_cast<unsigned>(deleteTime - loadTime) );
|
||||||
printf( "Total time=%u\n", (unsigned)(deleteTime - startTime) );
|
printf( "Total time=%u\n", static_cast<unsigned>(deleteTime - startTime) );
|
||||||
}
|
}
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
@@ -595,8 +597,8 @@ int main( int argc, const char ** argv )
|
|||||||
|
|
||||||
result = ele->QueryDoubleAttribute( "attr0", &dVal );
|
result = ele->QueryDoubleAttribute( "attr0", &dVal );
|
||||||
XMLTest( "Query attribute: int as double", XML_SUCCESS, result);
|
XMLTest( "Query attribute: int as double", XML_SUCCESS, result);
|
||||||
XMLTest( "Query attribute: int as double", 1, (int)dVal );
|
XMLTest( "Query attribute: int as double", 1, static_cast<int>(dVal) );
|
||||||
XMLTest( "Query attribute: int as double", 1, (int)ele->DoubleAttribute("attr0"));
|
XMLTest( "Query attribute: int as double", 1, static_cast<int>(ele->DoubleAttribute("attr0")));
|
||||||
|
|
||||||
result = ele->QueryDoubleAttribute( "attr1", &dVal );
|
result = ele->QueryDoubleAttribute( "attr1", &dVal );
|
||||||
XMLTest( "Query attribute: double as double", XML_SUCCESS, result);
|
XMLTest( "Query attribute: double as double", XML_SUCCESS, result);
|
||||||
@@ -648,17 +650,17 @@ int main( int argc, const char ** argv )
|
|||||||
|
|
||||||
{
|
{
|
||||||
XMLError queryResult = ele->QueryAttribute( "int", &iVal2 );
|
XMLError queryResult = ele->QueryAttribute( "int", &iVal2 );
|
||||||
XMLTest( "Query int attribute generic", (int)XML_SUCCESS, queryResult);
|
XMLTest( "Query int attribute generic", static_cast<int>(XML_SUCCESS), queryResult);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
XMLError queryResult = ele->QueryAttribute( "double", &dVal2 );
|
XMLError queryResult = ele->QueryAttribute( "double", &dVal2 );
|
||||||
XMLTest( "Query double attribute generic", (int)XML_SUCCESS, queryResult);
|
XMLTest( "Query double attribute generic", static_cast<int>(XML_SUCCESS), queryResult);
|
||||||
}
|
}
|
||||||
|
|
||||||
XMLTest( "Attribute match test", "strValue", ele->Attribute( "str", "strValue" ) );
|
XMLTest( "Attribute match test", "strValue", ele->Attribute( "str", "strValue" ) );
|
||||||
XMLTest( "Attribute round trip. c-string.", "strValue", cStr );
|
XMLTest( "Attribute round trip. c-string.", "strValue", cStr );
|
||||||
XMLTest( "Attribute round trip. int.", 1, iVal );
|
XMLTest( "Attribute round trip. int.", 1, iVal );
|
||||||
XMLTest( "Attribute round trip. double.", -1, (int)dVal );
|
XMLTest( "Attribute round trip. double.", -1, static_cast<int>(dVal) );
|
||||||
XMLTest( "Alternate query", true, iVal == iVal2 );
|
XMLTest( "Alternate query", true, iVal == iVal2 );
|
||||||
XMLTest( "Alternate query", true, dVal == dVal2 );
|
XMLTest( "Alternate query", true, dVal == dVal2 );
|
||||||
XMLTest( "Alternate query", true, iVal == ele->IntAttribute("int") );
|
XMLTest( "Alternate query", true, iVal == ele->IntAttribute("int") );
|
||||||
@@ -675,7 +677,7 @@ int main( int argc, const char ** argv )
|
|||||||
const unsigned char correctValue[] = { 0xd1U, 0x86U, 0xd0U, 0xb5U, 0xd0U, 0xbdU, 0xd0U, 0xbdU,
|
const unsigned char correctValue[] = { 0xd1U, 0x86U, 0xd0U, 0xb5U, 0xd0U, 0xbdU, 0xd0U, 0xbdU,
|
||||||
0xd0U, 0xbeU, 0xd1U, 0x81U, 0xd1U, 0x82U, 0xd1U, 0x8cU, 0 };
|
0xd0U, 0xbeU, 0xd1U, 0x81U, 0xd1U, 0x82U, 0xd1U, 0x8cU, 0 };
|
||||||
|
|
||||||
XMLTest( "UTF-8: Russian value.", (const char*)correctValue, element->Attribute( "value" ) );
|
XMLTest( "UTF-8: Russian value.", reinterpret_cast<const char*>(correctValue), element->Attribute( "value" ) );
|
||||||
|
|
||||||
const unsigned char russianElementName[] = { 0xd0U, 0xa0U, 0xd1U, 0x83U,
|
const unsigned char russianElementName[] = { 0xd0U, 0xa0U, 0xd1U, 0x83U,
|
||||||
0xd1U, 0x81U, 0xd1U, 0x81U,
|
0xd1U, 0x81U, 0xd1U, 0x81U,
|
||||||
@@ -683,7 +685,7 @@ int main( int argc, const char ** argv )
|
|||||||
0xd0U, 0xb9U, 0 };
|
0xd0U, 0xb9U, 0 };
|
||||||
const char russianText[] = "<\xD0\xB8\xD0\xBC\xD0\xB5\xD0\xB5\xD1\x82>";
|
const char russianText[] = "<\xD0\xB8\xD0\xBC\xD0\xB5\xD0\xB5\xD1\x82>";
|
||||||
|
|
||||||
XMLText* text = doc.FirstChildElement( "document" )->FirstChildElement( (const char*) russianElementName )->FirstChild()->ToText();
|
XMLText* text = doc.FirstChildElement( "document" )->FirstChildElement( reinterpret_cast<const char*>(russianElementName) )->FirstChild()->ToText();
|
||||||
XMLTest( "UTF-8: Browsing russian element name.",
|
XMLTest( "UTF-8: Browsing russian element name.",
|
||||||
russianText,
|
russianText,
|
||||||
text->Value() );
|
text->Value() );
|
||||||
@@ -824,7 +826,7 @@ int main( int argc, const char ** argv )
|
|||||||
{
|
{
|
||||||
int v = 0;
|
int v = 0;
|
||||||
XMLError queryResult = element->QueryAttribute("attrib", &v);
|
XMLError queryResult = element->QueryAttribute("attrib", &v);
|
||||||
XMLTest("Attribute: int", (int)XML_SUCCESS, queryResult, true);
|
XMLTest("Attribute: int", static_cast<int>(XML_SUCCESS), queryResult, true);
|
||||||
XMLTest("Attribute: int", -100, v, true);
|
XMLTest("Attribute: int", -100, v, true);
|
||||||
}
|
}
|
||||||
XMLTest("Attribute: int", -100, element->IntAttribute("attrib"), true);
|
XMLTest("Attribute: int", -100, element->IntAttribute("attrib"), true);
|
||||||
@@ -840,7 +842,7 @@ int main( int argc, const char ** argv )
|
|||||||
{
|
{
|
||||||
unsigned v = 0;
|
unsigned v = 0;
|
||||||
XMLError queryResult = element->QueryAttribute("attrib", &v);
|
XMLError queryResult = element->QueryAttribute("attrib", &v);
|
||||||
XMLTest("Attribute: unsigned", (int)XML_SUCCESS, queryResult, true);
|
XMLTest("Attribute: unsigned", static_cast<int>(XML_SUCCESS), queryResult, true);
|
||||||
XMLTest("Attribute: unsigned", unsigned(100), v, true);
|
XMLTest("Attribute: unsigned", unsigned(100), v, true);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
@@ -864,7 +866,7 @@ int main( int argc, const char ** argv )
|
|||||||
{
|
{
|
||||||
int64_t v = 0;
|
int64_t v = 0;
|
||||||
XMLError queryResult = element->QueryAttribute("attrib", &v);
|
XMLError queryResult = element->QueryAttribute("attrib", &v);
|
||||||
XMLTest("Attribute: int64_t", (int)XML_SUCCESS, queryResult, true);
|
XMLTest("Attribute: int64_t", static_cast<int>(XML_SUCCESS), queryResult, true);
|
||||||
XMLTest("Attribute: int64_t", BIG, v, true);
|
XMLTest("Attribute: int64_t", BIG, v, true);
|
||||||
}
|
}
|
||||||
XMLTest("Attribute: int64_t", BIG, element->Int64Attribute("attrib"), true);
|
XMLTest("Attribute: int64_t", BIG, element->Int64Attribute("attrib"), true);
|
||||||
@@ -880,7 +882,7 @@ int main( int argc, const char ** argv )
|
|||||||
{
|
{
|
||||||
uint64_t v = 0;
|
uint64_t v = 0;
|
||||||
XMLError queryResult = element->QueryAttribute("attrib", &v);
|
XMLError queryResult = element->QueryAttribute("attrib", &v);
|
||||||
XMLTest("Attribute: uint64_t", (int)XML_SUCCESS, queryResult, true);
|
XMLTest("Attribute: uint64_t", static_cast<int>(XML_SUCCESS), queryResult, true);
|
||||||
XMLTest("Attribute: uint64_t", BIG_POS, v, true);
|
XMLTest("Attribute: uint64_t", BIG_POS, v, true);
|
||||||
}
|
}
|
||||||
XMLTest("Attribute: uint64_t", BIG_POS, element->Unsigned64Attribute("attrib"), true);
|
XMLTest("Attribute: uint64_t", BIG_POS, element->Unsigned64Attribute("attrib"), true);
|
||||||
@@ -896,7 +898,7 @@ int main( int argc, const char ** argv )
|
|||||||
{
|
{
|
||||||
bool v = false;
|
bool v = false;
|
||||||
XMLError queryResult = element->QueryAttribute("attrib", &v);
|
XMLError queryResult = element->QueryAttribute("attrib", &v);
|
||||||
XMLTest("Attribute: bool", (int)XML_SUCCESS, queryResult, true);
|
XMLTest("Attribute: bool", static_cast<int>(XML_SUCCESS), queryResult, true);
|
||||||
XMLTest("Attribute: bool", true, v, true);
|
XMLTest("Attribute: bool", true, v, true);
|
||||||
}
|
}
|
||||||
XMLTest("Attribute: bool", true, element->BoolAttribute("attrib"), true);
|
XMLTest("Attribute: bool", true, element->BoolAttribute("attrib"), true);
|
||||||
@@ -924,7 +926,7 @@ int main( int argc, const char ** argv )
|
|||||||
{
|
{
|
||||||
double v = 0;
|
double v = 0;
|
||||||
XMLError queryResult = element->QueryAttribute("attrib", &v);
|
XMLError queryResult = element->QueryAttribute("attrib", &v);
|
||||||
XMLTest("Attribute: bool", (int)XML_SUCCESS, queryResult, true);
|
XMLTest("Attribute: bool", static_cast<int>(XML_SUCCESS), queryResult, true);
|
||||||
XMLTest("Attribute: double", 100.0, v, true);
|
XMLTest("Attribute: double", 100.0, v, true);
|
||||||
}
|
}
|
||||||
XMLTest("Attribute: double", 100.0, element->DoubleAttribute("attrib"), true);
|
XMLTest("Attribute: double", 100.0, element->DoubleAttribute("attrib"), true);
|
||||||
@@ -940,7 +942,7 @@ int main( int argc, const char ** argv )
|
|||||||
{
|
{
|
||||||
float v = 0;
|
float v = 0;
|
||||||
XMLError queryResult = element->QueryAttribute("attrib", &v);
|
XMLError queryResult = element->QueryAttribute("attrib", &v);
|
||||||
XMLTest("Attribute: float", (int)XML_SUCCESS, queryResult, true);
|
XMLTest("Attribute: float", static_cast<int>(XML_SUCCESS), queryResult, true);
|
||||||
XMLTest("Attribute: float", 100.0f, v, true);
|
XMLTest("Attribute: float", 100.0f, v, true);
|
||||||
}
|
}
|
||||||
XMLTest("Attribute: float", 100.0f, element->FloatAttribute("attrib"), true);
|
XMLTest("Attribute: float", 100.0f, element->FloatAttribute("attrib"), true);
|
||||||
@@ -1005,7 +1007,7 @@ int main( int argc, const char ** argv )
|
|||||||
FILE* fp1 = fopen("resources/out/printer_1.xml", "w");
|
FILE* fp1 = fopen("resources/out/printer_1.xml", "w");
|
||||||
XMLPrinter printer(fp1);
|
XMLPrinter printer(fp1);
|
||||||
|
|
||||||
printer.PushDeclaration("version = '1.0' enconding = 'utf-8'");
|
printer.PushDeclaration("version = '1.0' encoding = 'utf-8'");
|
||||||
|
|
||||||
printer.OpenElement("foo");
|
printer.OpenElement("foo");
|
||||||
printer.PushAttribute("attrib-text", "text");
|
printer.PushAttribute("attrib-text", "text");
|
||||||
@@ -1068,15 +1070,15 @@ int main( int argc, const char ** argv )
|
|||||||
|
|
||||||
unsigned unsigned_value;
|
unsigned unsigned_value;
|
||||||
unsigned_value = root->FirstChildElement("unsigned")->UnsignedText();
|
unsigned_value = root->FirstChildElement("unsigned")->UnsignedText();
|
||||||
XMLTest("PushText( unsigned value ) test", (unsigned)12, unsigned_value);
|
XMLTest("PushText( unsigned value ) test", static_cast<unsigned>(12), unsigned_value);
|
||||||
|
|
||||||
int64_t int64_t_value;
|
int64_t int64_t_value;
|
||||||
int64_t_value = root->FirstChildElement("int64_t")->Int64Text();
|
int64_t_value = root->FirstChildElement("int64_t")->Int64Text();
|
||||||
XMLTest("PushText( int64_t value ) test", (int64_t) 13, int64_t_value);
|
XMLTest("PushText( int64_t value ) test", static_cast<int64_t>(13), int64_t_value);
|
||||||
|
|
||||||
uint64_t uint64_t_value;
|
uint64_t uint64_t_value;
|
||||||
uint64_t_value = root->FirstChildElement("uint64_t")->Unsigned64Text();
|
uint64_t_value = root->FirstChildElement("uint64_t")->Unsigned64Text();
|
||||||
XMLTest("PushText( uint64_t value ) test", (uint64_t) 14, uint64_t_value);
|
XMLTest("PushText( uint64_t value ) test", static_cast<uint64_t>(14), uint64_t_value);
|
||||||
|
|
||||||
float float_value;
|
float float_value;
|
||||||
float_value = root->FirstChildElement("float")->FloatText();
|
float_value = root->FirstChildElement("float")->FloatText();
|
||||||
@@ -1096,7 +1098,7 @@ int main( int argc, const char ** argv )
|
|||||||
|
|
||||||
const XMLDeclaration* declaration = cdoc.FirstChild()->ToDeclaration();
|
const XMLDeclaration* declaration = cdoc.FirstChild()->ToDeclaration();
|
||||||
const char* declaration_value = declaration->Value();
|
const char* declaration_value = declaration->Value();
|
||||||
XMLTest("PushDeclaration() test", "version = '1.0' enconding = 'utf-8'", declaration_value);
|
XMLTest("PushDeclaration() test", "version = '1.0' encoding = 'utf-8'", declaration_value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1397,7 +1399,7 @@ int main( int argc, const char ** argv )
|
|||||||
buf[61] = 0;
|
buf[61] = 0;
|
||||||
|
|
||||||
XMLDocument doc;
|
XMLDocument doc;
|
||||||
doc.Parse( (const char*)buf);
|
doc.Parse( reinterpret_cast<const char*>(buf) );
|
||||||
XMLTest( "Broken CDATA", true, doc.Error() );
|
XMLTest( "Broken CDATA", true, doc.Error() );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1642,7 +1644,7 @@ int main( int argc, const char ** argv )
|
|||||||
|
|
||||||
static const char* result = "\xef\xbb\xbf<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
|
static const char* result = "\xef\xbb\xbf<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
|
||||||
XMLTest( "BOM and default declaration", result, printer.CStr(), false );
|
XMLTest( "BOM and default declaration", result, printer.CStr(), false );
|
||||||
XMLTest( "CStrSize", 42, printer.CStrSize(), false );
|
XMLTest( "CStrSize", true, printer.CStrSize() == 42, false );
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
const char* xml = "<ipxml ws='1'><info bla=' /></ipxml>";
|
const char* xml = "<ipxml ws='1'><info bla=' /></ipxml>";
|
||||||
@@ -1753,7 +1755,7 @@ int main( int argc, const char ** argv )
|
|||||||
unsigned unsignedValue = 0;
|
unsigned unsignedValue = 0;
|
||||||
XMLError queryResult = pointElement->FirstChildElement( "y" )->QueryUnsignedText( &unsignedValue );
|
XMLError queryResult = pointElement->FirstChildElement( "y" )->QueryUnsignedText( &unsignedValue );
|
||||||
XMLTest( "QueryUnsignedText result", XML_SUCCESS, queryResult, false );
|
XMLTest( "QueryUnsignedText result", XML_SUCCESS, queryResult, false );
|
||||||
XMLTest( "QueryUnsignedText", (unsigned)1, unsignedValue, false );
|
XMLTest( "QueryUnsignedText", static_cast<unsigned>(1), unsignedValue, false );
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
@@ -2025,6 +2027,12 @@ int main( int argc, const char ** argv )
|
|||||||
XMLTest("Parse nested elements with pedantic whitespace", false, doc.Error());
|
XMLTest("Parse nested elements with pedantic whitespace", false, doc.Error());
|
||||||
XMLTest("Pedantic whitespace", true, 0 == doc.RootElement()->FirstChildElement()->GetText());
|
XMLTest("Pedantic whitespace", true, 0 == doc.RootElement()->FirstChildElement()->GetText());
|
||||||
}
|
}
|
||||||
|
//Check the robustness of the DeleteNode function in handling null pointers.
|
||||||
|
{
|
||||||
|
XMLDocument doc;
|
||||||
|
doc.DeleteNode(nullptr);
|
||||||
|
XMLTest("DeleteNode with null pointer", true, doc.Error() == XML_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
// Check sample xml can be parsed with pedantic mode
|
// Check sample xml can be parsed with pedantic mode
|
||||||
{
|
{
|
||||||
@@ -2639,7 +2647,7 @@ int main( int argc, const char ** argv )
|
|||||||
"<?xml version=\"1.0\"?>\n" // 2 DecL
|
"<?xml version=\"1.0\"?>\n" // 2 DecL
|
||||||
"<root>\r\n" // 3 Element
|
"<root>\r\n" // 3 Element
|
||||||
"\n" // 4
|
"\n" // 4
|
||||||
"text contining new line \n" // 5 Text
|
"text containing new line \n" // 5 Text
|
||||||
" and also containing crlf \r\n" // 6
|
" and also containing crlf \r\n" // 6
|
||||||
"<sub><![CDATA[\n" // 7 Element Text
|
"<sub><![CDATA[\n" // 7 Element Text
|
||||||
"cdata containing new line \n" // 8
|
"cdata containing new line \n" // 8
|
||||||
@@ -2666,6 +2674,120 @@ int main( int argc, const char ** argv )
|
|||||||
doc.PrintError();
|
doc.PrintError();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ---------- CVE-2024-50615 -----------
|
||||||
|
{
|
||||||
|
const char* xml = "<Hello value='12A34' value2='56B78'>Text</Hello>";
|
||||||
|
XMLDocument doc;
|
||||||
|
doc.Parse(xml);
|
||||||
|
const char* value = doc.FirstChildElement()->Attribute("value");
|
||||||
|
const char* value2 = doc.FirstChildElement()->Attribute("value2");
|
||||||
|
XMLTest("Test attribute encode", false, doc.Error());
|
||||||
|
XMLTest("Test decimal value", value, "12A34");
|
||||||
|
XMLTest("Test hex encode", value2, "56B78");
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const char* xml = "<Hello value='&#ABC9000000065;' value2='�' value3='�' value4='E' value5='!'>Text</Hello>";
|
||||||
|
XMLDocument doc;
|
||||||
|
doc.Parse(xml);
|
||||||
|
const char* value = doc.FirstChildElement()->Attribute("value");
|
||||||
|
const char* value2 = doc.FirstChildElement()->Attribute("value2");
|
||||||
|
const char* value3 = doc.FirstChildElement()->Attribute("value3");
|
||||||
|
const char* value4 = doc.FirstChildElement()->Attribute("value4");
|
||||||
|
const char* value5 = doc.FirstChildElement()->Attribute("value5");
|
||||||
|
XMLTest("Test attribute encode", false, doc.Error());
|
||||||
|
XMLTest("Test attribute encode too long value", value, "&#ABC9000000065;"); // test long value
|
||||||
|
XMLTest("Test attribute encode out of unicode range", value2, "�"); // out of unicode range
|
||||||
|
XMLTest("Test attribute encode out of int max value", value3, "�"); // out of int max value
|
||||||
|
XMLTest("Test attribute encode with a Hex value", value4, "E"); // hex value in unicode value
|
||||||
|
XMLTest("Test attribute encode with a Hex value", value5, "!"); // hex value in unicode value
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------- Security: numeric character reference bounds ----------
|
||||||
|
{
|
||||||
|
// Regression: U+10FFFF is the last valid Unicode code point and must
|
||||||
|
// parse correctly. The in-loop overflow guard must not reject it.
|
||||||
|
XMLDocument doc;
|
||||||
|
doc.Parse( "<t v=''/>" );
|
||||||
|
XMLTest( "Numeric ref U+10FFFF: no error", false, doc.Error() );
|
||||||
|
const char* v = doc.FirstChildElement()->Attribute( "v" );
|
||||||
|
// U+10FFFF encodes to the 4-byte UTF-8 sequence F4 8F BF BF.
|
||||||
|
const char expected[] = {
|
||||||
|
static_cast<char>(0xF4), static_cast<char>(0x8F),
|
||||||
|
static_cast<char>(0xBF), static_cast<char>(0xBF), 0
|
||||||
|
};
|
||||||
|
XMLTest( "Numeric ref U+10FFFF: correct UTF-8 output", expected, v );
|
||||||
|
}
|
||||||
|
{
|
||||||
|
// Boundary check: U+110000 is one above the maximum code point.
|
||||||
|
// The in-loop overflow guard must catch this before ucs is written,
|
||||||
|
// leaving the entity as a literal (starting with '&').
|
||||||
|
XMLDocument doc;
|
||||||
|
doc.Parse( "<t v='�'/>" );
|
||||||
|
XMLTest( "Numeric ref U+110000: no parse error", false, doc.Error() );
|
||||||
|
const char* v = doc.FirstChildElement()->Attribute( "v" );
|
||||||
|
XMLTest( "Numeric ref U+110000: not resolved (left as literal)", true,
|
||||||
|
v != nullptr && v[0] == '&' );
|
||||||
|
}
|
||||||
|
{
|
||||||
|
// A hex entity with enough digits to overflow uint32_t must
|
||||||
|
// be rejected by the in-loop guard before the accumulator wraps.
|
||||||
|
// Before the fix, ucs could wrap around and pass the post-loop range
|
||||||
|
// check, producing an attacker-chosen character in the parsed output.
|
||||||
|
// Build "&#x" + 300 'F' digits + ";" -- far beyond what fits in uint32_t.
|
||||||
|
const char prefix[] = "<t v='&#x";
|
||||||
|
const char suffix[] = ";'/>";
|
||||||
|
static const int NDIGITS = 300;
|
||||||
|
char xml[sizeof(prefix) + NDIGITS + sizeof(suffix)];
|
||||||
|
strcpy( xml, prefix );
|
||||||
|
memset( xml + strlen(prefix), 'F', NDIGITS );
|
||||||
|
strcpy( xml + strlen(prefix) + NDIGITS, suffix );
|
||||||
|
|
||||||
|
XMLDocument doc;
|
||||||
|
doc.Parse( xml );
|
||||||
|
XMLTest( "Overflow hex entity: no parse error", false, doc.Error() );
|
||||||
|
const char* v = doc.FirstChildElement()->Attribute( "v" );
|
||||||
|
// GetCharacterRef returns 0 for rejected refs; the caller then copies
|
||||||
|
// the literal '&', so the attribute must start with '&', not a char.
|
||||||
|
XMLTest( "Overflow hex entity: not resolved to a character", true,
|
||||||
|
v != nullptr && v[0] == '&' );
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------- XMLPrinter Apos Escaping ------
|
||||||
|
{
|
||||||
|
const char* testText = "text containing a ' character";
|
||||||
|
XMLDocument doc;
|
||||||
|
XMLElement* element = doc.NewElement( "element" );
|
||||||
|
doc.InsertEndChild( element );
|
||||||
|
element->SetAttribute( "attrib", testText );
|
||||||
|
{
|
||||||
|
XMLPrinter defaultPrinter;
|
||||||
|
doc.Print( &defaultPrinter );
|
||||||
|
const char* defaultOutput = defaultPrinter.CStr();
|
||||||
|
const bool foundTextWithUnescapedApos = (strstr(defaultOutput, testText) != nullptr);
|
||||||
|
XMLTest("Default XMLPrinter should escape ' characters", false, foundTextWithUnescapedApos);
|
||||||
|
{
|
||||||
|
XMLDocument parsingDoc;
|
||||||
|
parsingDoc.Parse(defaultOutput);
|
||||||
|
const XMLAttribute* attrib = parsingDoc.FirstChildElement("element")->FindAttribute("attrib");
|
||||||
|
XMLTest("Default XMLPrinter should output parsable xml", testText, attrib->Value(), true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
XMLPrinter customPrinter(0, false, 0, XMLPrinter::DONT_ESCAPE_APOS_CHARS_IN_ATTRIBUTES);
|
||||||
|
doc.Print( &customPrinter );
|
||||||
|
const char* customOutput = customPrinter.CStr();
|
||||||
|
const bool foundTextWithUnescapedApos = (strstr(customOutput, testText) != nullptr);
|
||||||
|
XMLTest("Custom XMLPrinter should not escape ' characters", true, foundTextWithUnescapedApos);
|
||||||
|
{
|
||||||
|
XMLDocument parsingDoc;
|
||||||
|
parsingDoc.Parse(customOutput);
|
||||||
|
const XMLAttribute* attrib = parsingDoc.FirstChildElement("element")->FindAttribute("attrib");
|
||||||
|
XMLTest("Custom XMLPrinter should output parsable xml", testText, attrib->Value(), true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ----------- Performance tracking --------------
|
// ----------- Performance tracking --------------
|
||||||
{
|
{
|
||||||
#if defined( _MSC_VER )
|
#if defined( _MSC_VER )
|
||||||
@@ -2715,9 +2837,9 @@ int main( int argc, const char ** argv )
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined( _MSC_VER )
|
#if defined( _MSC_VER )
|
||||||
const double duration = 1000.0 * (double)(end - start) / ((double)freq * (double)COUNT);
|
const double duration = 1000.0 * static_cast<double>(end - start) / (static_cast<double>(freq) * static_cast<double>(COUNT));
|
||||||
#else
|
#else
|
||||||
const double duration = (double)(cend - cstart) / (double)COUNT;
|
const double duration = static_cast<double>(cend - cstart) / static_cast<double>(COUNT);
|
||||||
#endif
|
#endif
|
||||||
printf("\nParsing dream.xml (%s): %.3f milli-seconds\n", note, duration);
|
printf("\nParsing dream.xml (%s): %.3f milli-seconds\n", note, duration);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user