├── .drone.star ├── .drone └── drone.sh ├── .gitattributes ├── .github └── workflows │ └── ci.yml ├── CMakeLists.txt ├── README.md ├── appveyor.yml ├── breaking_changes.txt ├── build.jam ├── cmake └── config.cmake.in ├── doc ├── Jamfile.v2 ├── accessing.qbk ├── cmd_line_parser.qbk ├── container.qbk ├── images │ └── ptree2code.png ├── info_parser.qbk ├── ini_parser.qbk ├── intro.qbk ├── json_parser.qbk ├── parsers.qbk ├── property_tree.qbk ├── synopsis.qbk ├── system_environment_parser.qbk ├── tutorial.qbk ├── windows_registry_parser.qbk └── xml_parser.qbk ├── examples ├── CMakeLists.txt ├── Jamfile.v2 ├── custom_data_type.cpp ├── debug_settings.cpp ├── debug_settings.xml ├── empty_ptree_trick.cpp ├── info_grammar_spirit.cpp ├── settings_fully-existent.info ├── settings_non-existent.info ├── settings_partially-existent.info └── speed_test.cpp ├── include └── boost │ └── property_tree │ ├── detail │ ├── exception_implementation.hpp │ ├── file_parser_error.hpp │ ├── info_parser_error.hpp │ ├── info_parser_read.hpp │ ├── info_parser_utils.hpp │ ├── info_parser_write.hpp │ ├── info_parser_writer_settings.hpp │ ├── ptree_implementation.hpp │ ├── ptree_utils.hpp │ ├── rapidxml.hpp │ ├── xml_parser_error.hpp │ ├── xml_parser_flags.hpp │ ├── xml_parser_read_rapidxml.hpp │ ├── xml_parser_utils.hpp │ ├── xml_parser_write.hpp │ └── xml_parser_writer_settings.hpp │ ├── exceptions.hpp │ ├── id_translator.hpp │ ├── info_parser.hpp │ ├── ini_parser.hpp │ ├── json_parser.hpp │ ├── json_parser │ ├── detail │ │ ├── narrow_encoding.hpp │ │ ├── parser.hpp │ │ ├── read.hpp │ │ ├── standard_callbacks.hpp │ │ ├── wide_encoding.hpp │ │ └── write.hpp │ └── error.hpp │ ├── ptree.hpp │ ├── ptree_fwd.hpp │ ├── ptree_serialization.hpp │ ├── stream_translator.hpp │ ├── string_path.hpp │ └── xml_parser.hpp ├── index.html ├── meta └── libraries.json └── test ├── CMakeLists.txt ├── Jamfile.v2 ├── cmake_install_test ├── CMakeLists.txt └── main.cpp ├── cmake_subdir_test ├── CMakeLists.txt └── main.cpp ├── prefixing_callbacks.hpp ├── sandbox.cpp ├── self_contained_header.cpp ├── test_info_parser.cpp ├── test_ini_parser.cpp ├── test_json_parser.cpp ├── test_json_parser2.cpp ├── test_json_parser3.cpp ├── test_multi_module1.cpp ├── test_multi_module2.cpp ├── test_property_tree.cpp ├── test_property_tree.hpp ├── test_rapidxml.cpp ├── test_utils.hpp ├── test_xml_parser_common.hpp ├── test_xml_parser_rapidxml.cpp └── xml_parser_test_data.hpp /.drone/drone.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright 2020 Rene Rivera, Sam Darwin 4 | # Distributed under the Boost Software License, Version 1.0. 5 | # (See accompanying file LICENSE.txt or copy at http://boost.org/LICENSE_1_0.txt) 6 | 7 | set -e 8 | export TRAVIS_BUILD_DIR=$(pwd) 9 | export DRONE_BUILD_DIR=$(pwd) 10 | export TRAVIS_BRANCH=$DRONE_BRANCH 11 | export TRAVIS_EVENT_TYPE=$DRONE_BUILD_EVENT 12 | export VCS_COMMIT_ID=$DRONE_COMMIT 13 | export GIT_COMMIT=$DRONE_COMMIT 14 | export REPO_NAME=$DRONE_REPO 15 | export USER=$(whoami) 16 | export CC=${CC:-gcc} 17 | export PATH=~/.local/bin:/usr/local/bin:$PATH 18 | 19 | if [[ ${TRAVIS_OS_NAME} =~ [Ll]inux ]]; then 20 | echo Installing locales for ${TRAVIS_OS_NAME} ... 21 | sudo /usr/sbin/locale-gen fr_FR 22 | sudo /usr/sbin/locale-gen en_GB 23 | sudo locale -a 24 | echo ...done with locales 25 | fi 26 | 27 | if [ "$DRONE_JOB_BUILDTYPE" == "boost" ]; then 28 | 29 | echo '==================================> INSTALL' 30 | 31 | git clone https://github.com/boostorg/boost-ci.git boost-ci-cloned 32 | cp -prf boost-ci-cloned/ci . 33 | rm -rf boost-ci-cloned 34 | 35 | if [ "$TRAVIS_OS_NAME" == "osx" ]; then 36 | unset -f cd 37 | fi 38 | 39 | export SELF=`basename $REPO_NAME` 40 | export BOOST_CI_TARGET_BRANCH="$TRAVIS_BRANCH" 41 | export BOOST_CI_SRC_FOLDER=$(pwd) 42 | 43 | . ./ci/common_install.sh 44 | 45 | echo '==================================> SCRIPT' 46 | 47 | $BOOST_ROOT/libs/$SELF/ci/travis/build.sh 48 | 49 | elif [ "$DRONE_JOB_BUILDTYPE" == "fc4716b68c-0fcaf592f9" ]; then 50 | 51 | echo '==================================> INSTALL' 52 | 53 | git clone https://github.com/boostorg/boost-ci.git boost-ci-cloned 54 | cp -prf boost-ci-cloned/ci . 55 | rm -rf boost-ci-cloned 56 | 57 | if [ "$TRAVIS_OS_NAME" == "osx" ]; then 58 | unset -f cd 59 | fi 60 | 61 | export SELF=`basename $REPO_NAME` 62 | export BOOST_CI_TARGET_BRANCH="$TRAVIS_BRANCH" 63 | export BOOST_CI_SRC_FOLDER=$(pwd) 64 | 65 | . ./ci/common_install.sh 66 | 67 | echo '==================================> SCRIPT' 68 | 69 | cd $BOOST_ROOT/libs/$SELF 70 | ci/travis/codecov.sh 71 | 72 | elif [ "$DRONE_JOB_BUILDTYPE" == "fc4716b68c-db180b7bd2" ]; then 73 | 74 | echo '==================================> INSTALL' 75 | 76 | git clone https://github.com/boostorg/boost-ci.git boost-ci-cloned 77 | cp -prf boost-ci-cloned/ci . 78 | rm -rf boost-ci-cloned 79 | 80 | if [ "$TRAVIS_OS_NAME" == "osx" ]; then 81 | unset -f cd 82 | fi 83 | 84 | export SELF=`basename $REPO_NAME` 85 | export BOOST_CI_TARGET_BRANCH="$TRAVIS_BRANCH" 86 | export BOOST_CI_SRC_FOLDER=$(pwd) 87 | 88 | . ./ci/common_install.sh 89 | 90 | echo '==================================> SCRIPT' 91 | 92 | cd $BOOST_ROOT/libs/$SELF 93 | ci/travis/valgrind.sh 94 | 95 | elif [ "$DRONE_JOB_BUILDTYPE" == "fc4716b68c-cce9827eb5" ]; then 96 | 97 | echo '==================================> INSTALL' 98 | 99 | git clone https://github.com/boostorg/boost-ci.git boost-ci-cloned 100 | cp -prf boost-ci-cloned/ci . 101 | rm -rf boost-ci-cloned 102 | 103 | if [ "$TRAVIS_OS_NAME" == "osx" ]; then 104 | unset -f cd 105 | fi 106 | 107 | export SELF=`basename $REPO_NAME` 108 | export BOOST_CI_TARGET_BRANCH="$TRAVIS_BRANCH" 109 | export BOOST_CI_SRC_FOLDER=$(pwd) 110 | 111 | . ./ci/common_install.sh 112 | 113 | echo '==================================> SCRIPT' 114 | 115 | if [ -n "${COVERITY_SCAN_NOTIFICATION_EMAIL}" -a \( "$TRAVIS_BRANCH" = "develop" -o "$TRAVIS_BRANCH" = "master" \) -a \( "$DRONE_BUILD_EVENT" = "push" -o "$DRONE_BUILD_EVENT" = "cron" \) ] ; then 116 | cd $BOOST_ROOT/libs/$SELF 117 | ci/travis/coverity.sh 118 | fi 119 | 120 | fi 121 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto !eol svneol=native#text/plain 2 | *.gitattributes text svneol=native#text/plain 3 | 4 | # Scriptish formats 5 | *.bat text svneol=native#text/plain 6 | *.bsh text svneol=native#text/x-beanshell 7 | *.cgi text svneol=native#text/plain 8 | *.cmd text svneol=native#text/plain 9 | *.js text svneol=native#text/javascript 10 | *.php text svneol=native#text/x-php 11 | *.pl text svneol=native#text/x-perl 12 | *.pm text svneol=native#text/x-perl 13 | *.py text svneol=native#text/x-python 14 | *.sh eol=lf svneol=LF#text/x-sh 15 | configure eol=lf svneol=LF#text/x-sh 16 | 17 | # Image formats 18 | *.bmp binary svneol=unset#image/bmp 19 | *.gif binary svneol=unset#image/gif 20 | *.ico binary svneol=unset#image/ico 21 | *.jpeg binary svneol=unset#image/jpeg 22 | *.jpg binary svneol=unset#image/jpeg 23 | *.png binary svneol=unset#image/png 24 | *.tif binary svneol=unset#image/tiff 25 | *.tiff binary svneol=unset#image/tiff 26 | *.svg text svneol=native#image/svg%2Bxml 27 | 28 | # Data formats 29 | *.pdf binary svneol=unset#application/pdf 30 | *.avi binary svneol=unset#video/avi 31 | *.doc binary svneol=unset#application/msword 32 | *.dsp text svneol=crlf#text/plain 33 | *.dsw text svneol=crlf#text/plain 34 | *.eps binary svneol=unset#application/postscript 35 | *.gz binary svneol=unset#application/gzip 36 | *.mov binary svneol=unset#video/quicktime 37 | *.mp3 binary svneol=unset#audio/mpeg 38 | *.ppt binary svneol=unset#application/vnd.ms-powerpoint 39 | *.ps binary svneol=unset#application/postscript 40 | *.psd binary svneol=unset#application/photoshop 41 | *.rdf binary svneol=unset#text/rdf 42 | *.rss text svneol=unset#text/xml 43 | *.rtf binary svneol=unset#text/rtf 44 | *.sln text svneol=native#text/plain 45 | *.swf binary svneol=unset#application/x-shockwave-flash 46 | *.tgz binary svneol=unset#application/gzip 47 | *.vcproj text svneol=native#text/xml 48 | *.vcxproj text svneol=native#text/xml 49 | *.vsprops text svneol=native#text/xml 50 | *.wav binary svneol=unset#audio/wav 51 | *.xls binary svneol=unset#application/vnd.ms-excel 52 | *.zip binary svneol=unset#application/zip 53 | 54 | # Text formats 55 | .htaccess text svneol=native#text/plain 56 | *.bbk text svneol=native#text/xml 57 | *.cmake text svneol=native#text/plain 58 | *.css text svneol=native#text/css 59 | *.dtd text svneol=native#text/xml 60 | *.htm text svneol=native#text/html 61 | *.html text svneol=native#text/html 62 | *.ini text svneol=native#text/plain 63 | *.log text svneol=native#text/plain 64 | *.mak text svneol=native#text/plain 65 | *.qbk text svneol=native#text/plain 66 | *.rst text svneol=native#text/plain 67 | *.sql text svneol=native#text/x-sql 68 | *.txt text svneol=native#text/plain 69 | *.xhtml text svneol=native#text/xhtml%2Bxml 70 | *.xml text svneol=native#text/xml 71 | *.xsd text svneol=native#text/xml 72 | *.xsl text svneol=native#text/xml 73 | *.xslt text svneol=native#text/xml 74 | *.xul text svneol=native#text/xul 75 | *.yml text svneol=native#text/plain 76 | boost-no-inspect text svneol=native#text/plain 77 | CHANGES text svneol=native#text/plain 78 | COPYING text svneol=native#text/plain 79 | INSTALL text svneol=native#text/plain 80 | Jamfile text svneol=native#text/plain 81 | Jamroot text svneol=native#text/plain 82 | Jamfile.v2 text svneol=native#text/plain 83 | Jamrules text svneol=native#text/plain 84 | Makefile* text svneol=native#text/plain 85 | README text svneol=native#text/plain 86 | TODO text svneol=native#text/plain 87 | 88 | # Code formats 89 | *.c text svneol=native#text/plain 90 | *.cpp text svneol=native#text/plain 91 | *.h text svneol=native#text/plain 92 | *.hpp text svneol=native#text/plain 93 | *.ipp text svneol=native#text/plain 94 | *.tpp text svneol=native#text/plain 95 | *.jam text svneol=native#text/plain 96 | *.java text svneol=native#text/plain 97 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Generated by `boostdep --cmake property_tree` 2 | # Copyright 2020, 2021 Peter Dimov 3 | # Distributed under the Boost Software License, Version 1.0. 4 | # https://www.boost.org/LICENSE_1_0.txt 5 | 6 | cmake_minimum_required(VERSION 3.8...3.20) 7 | 8 | project(boost_property_tree VERSION "${BOOST_SUPERPROJECT_VERSION}" LANGUAGES CXX) 9 | 10 | add_library(boost_property_tree INTERFACE) 11 | add_library(Boost::property_tree ALIAS boost_property_tree) 12 | 13 | target_include_directories(boost_property_tree INTERFACE include) 14 | 15 | target_link_libraries(boost_property_tree 16 | INTERFACE 17 | Boost::any 18 | Boost::assert 19 | Boost::bind 20 | Boost::config 21 | Boost::core 22 | Boost::iterator 23 | Boost::mpl 24 | Boost::multi_index 25 | Boost::optional 26 | Boost::range 27 | Boost::serialization 28 | Boost::static_assert 29 | Boost::throw_exception 30 | Boost::type_traits 31 | ) 32 | 33 | target_compile_features(boost_property_tree INTERFACE cxx_std_11) 34 | 35 | if(BUILD_TESTING AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/test/CMakeLists.txt") 36 | 37 | add_subdirectory(test) 38 | 39 | endif() 40 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Maintainer 2 | 3 | This library is currently maintained by [Richard Hodges](mailto:hodges.r@gmail.com) with generous support 4 | from the C++ Alliance. 5 | 6 | # Build Status 7 | 8 | Branch | Status 9 | --------|------- 10 | develop | [![CI](https://github.com/boostorg/property_tree/actions/workflows/ci.yml/badge.svg?branch=develop)](https://github.com/boostorg/property_tree/actions/workflows/ci.yml) 11 | master | [![CI](https://github.com/boostorg/property_tree/actions/workflows/ci.yml/badge.svg?branch=master)](https://github.com/boostorg/property_tree/actions/workflows/ci.yml) 12 | 13 | # Licence 14 | 15 | This software is distributed under the [Boost Software License, Version 1.0](http://www.boost.org/LICENSE_1_0.txt). 16 | 17 | # Original Work 18 | 19 | This library is the work of Marcin Kalicinski and Sebastian Redl
20 | 21 | Copyright (C) 2002-2006 Marcin Kalicinski
22 | Copyright (C) 2009 Sebastian Redl 23 | -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | # Copyright 2016-2021 Peter Dimov 2 | # Distributed under the Boost Software License, Version 1.0. 3 | # (See accompanying file LICENSE_1_0.txt or copy at http://boost.org/LICENSE_1_0.txt) 4 | 5 | version: 1.0.{build}-{branch} 6 | 7 | shallow_clone: true 8 | 9 | branches: 10 | only: 11 | - master 12 | - develop 13 | - /feature\/.*/ 14 | 15 | environment: 16 | matrix: 17 | - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015 18 | TOOLSET: msvc-14.0 19 | ADDRMD: 32,64 20 | - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 21 | TOOLSET: msvc-14.1 22 | ADDRMD: 32,64 23 | CXXSTD: 14,17,latest 24 | - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 25 | TOOLSET: msvc-14.1 26 | ADDRMD: 32,64 27 | CXXSTD: 14,17,latest 28 | CXXFLAGS: /permissive- 29 | - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 30 | TOOLSET: clang-win 31 | ADDRMD: 64 32 | CXXSTD: 14,17,latest 33 | - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019 34 | TOOLSET: clang-win 35 | ADDRMD: 64 36 | CXXSTD: 14,17,latest 37 | 38 | install: 39 | - set BOOST_BRANCH=develop 40 | - if "%APPVEYOR_REPO_BRANCH%" == "master" set BOOST_BRANCH=master 41 | - cd .. 42 | - git clone -b %BOOST_BRANCH% --depth 1 https://github.com/boostorg/boost.git boost-root 43 | - cd boost-root 44 | - git submodule update --init tools/boostdep 45 | - xcopy /s /e /q %APPVEYOR_BUILD_FOLDER% libs\property_tree\ 46 | - python tools/boostdep/depinst/depinst.py -I examples property_tree 47 | - cmd /c bootstrap 48 | - b2 -d0 headers 49 | 50 | build: off 51 | 52 | test_script: 53 | - if not "%CXXSTD%" == "" set CXXSTD=cxxstd=%CXXSTD% 54 | - if not "%ADDRMD%" == "" set ADDRMD=address-model=%ADDRMD% 55 | - if not "%CXXFLAGS%" == "" set CXXFLAGS=cxxflags=%CXXFLAGS% 56 | - b2 -j1 libs/property_tree/test toolset=%TOOLSET% %CXXSTD% %ADDRMD% %CXXFLAGS% variant=debug,release embed-manifest-via=linker 57 | -------------------------------------------------------------------------------- /breaking_changes.txt: -------------------------------------------------------------------------------- 1 | Copyright (C) 2009 Sebastian Redl 2 | Distributed under the Boost Software License, Version 1.0. 3 | See http://www.boost.org/LICENSE_1_0.txt 4 | 5 | 6 | List all breaking changes done to the interface during the update here. 7 | 8 | - Template parameters 9 | Template parameters have been thoroughly changed. 10 | Impact: If you were using a custom instantiation of basic_ptree, you have to 11 | change your code. 12 | Rationale: The old order made no sense. It ordered the key comparison predicate 13 | before the key, although it could easily be defaulted based on it, 14 | and the path before the data type, when the path is something you 15 | will very rarely want to change (and it could default, too). 16 | 17 | - put* 18 | The put and put_child functions of basic_ptree had add and add_child split from 19 | them, by separating along the lines of the do_not_replace parameter. 20 | Impact: If you were using the third parameter of these functions, you have to 21 | change your code. 22 | Rationale: I'm not fond of using boolean parameters to change function behavior. 23 | They're hard to remember and hard to read in code. When projects 24 | adopt the convention of passing /*boolean=*/true, 25 | /*parameters=*/false, /*like=*/false this, something's wrong. 26 | It's even more wrong when the parameter has a negative name, as 27 | do_not_replace had. 28 | 29 | - Custom paths 30 | Custom paths have been thoroughly changed. 31 | Impact: If you were using custom paths, you have to change your code. If you 32 | referred to the basic_path template by name, you have to change your 33 | code. 34 | Rationale: The old interface required a huge amount of repeated code for 35 | custom paths. The new interface is a lot easier to implement. 36 | 37 | - Translators 38 | Translators have been thoroughly changed. 39 | Impact: If you were using translators at all, you probably have to change your 40 | code. 41 | Rationale: The new interface makes it easier to pass custom translators to 42 | specific get/put operations. It also keeps the translator out of 43 | the tree's type. 44 | 45 | - find 46 | find() returns an assoc_iterator. 47 | Impact: If you use find, you may have to change your code. Most importantly, 48 | you need to compare against not_found() instead of end(). 49 | Rationale: equal_range() also returns assoc_iterators. equal_range() cannot 50 | return normal iterators, since the conversion would not preserve 51 | the equal range or even the range property. 52 | -------------------------------------------------------------------------------- /build.jam: -------------------------------------------------------------------------------- 1 | # Copyright René Ferdinand Rivera Morell 2023-2024 2 | # Distributed under the Boost Software License, Version 1.0. 3 | # (See accompanying file LICENSE_1_0.txt or copy at 4 | # http://www.boost.org/LICENSE_1_0.txt) 5 | 6 | require-b2 5.2 ; 7 | 8 | constant boost_dependencies : 9 | /boost/any//boost_any 10 | /boost/assert//boost_assert 11 | /boost/bind//boost_bind 12 | /boost/config//boost_config 13 | /boost/core//boost_core 14 | /boost/iterator//boost_iterator 15 | /boost/mpl//boost_mpl 16 | /boost/multi_index//boost_multi_index 17 | /boost/optional//boost_optional 18 | /boost/range//boost_range 19 | /boost/serialization//boost_serialization 20 | /boost/static_assert//boost_static_assert 21 | /boost/throw_exception//boost_throw_exception 22 | /boost/type_traits//boost_type_traits ; 23 | 24 | project /boost/property_tree 25 | ; 26 | 27 | explicit 28 | [ alias boost_property_tree : : : 29 | : include $(boost_dependencies) ] 30 | [ alias all : examples test ] 31 | ; 32 | 33 | call-if : boost-library property_tree 34 | ; 35 | 36 | -------------------------------------------------------------------------------- /cmake/config.cmake.in: -------------------------------------------------------------------------------- 1 | @PACKAGE_INIT@ 2 | 3 | include(CMakeFindDependencyMacro) 4 | find_dependency(Boost REQUIRED ) #COMPONENTS container system) 5 | 6 | include("${CMAKE_CURRENT_LIST_DIR}/boost_property_tree-targets.cmake") 7 | -------------------------------------------------------------------------------- /doc/Jamfile.v2: -------------------------------------------------------------------------------- 1 | # Boost.PropertyTree 2 | # 3 | # Copyright (c) 2006-2007 Matias Capeletto 4 | # 5 | # Distributed under the Boost Software License, Version 1.0. 6 | # (See accompanying file LICENSE_1_0.txt or copy at 7 | # http://www.boost.org/LICENSE_1_0.txt) 8 | 9 | 10 | # Quickbook 11 | # ----------------------------------------------------------------------------- 12 | 13 | import doxygen ; 14 | import quickbook ; 15 | 16 | doxygen autodoc 17 | : 18 | [ glob ../include/boost/property_tree/*.hpp ] 19 | : 20 | EXTRACT_ALL=YES 21 | "PREDEFINED=\"BOOST_PROPERTY_TREE_DOXYGEN_INVOKED\" \\ 22 | \"BOOST_DEDUCED_TYPENAME=typename\"" 23 | HIDE_UNDOC_MEMBERS=NO 24 | EXTRACT_PRIVATE=NO 25 | ENABLE_PREPROCESSING=YES 26 | MACRO_EXPANSION=YES 27 | EXPAND_ONLY_PREDEF=YES 28 | SEARCH_INCLUDES=YES 29 | INCLUDE_PATH=$(BOOST_ROOT) 30 | EXAMPLE_PATH=$(BOOST_ROOT)/libs/property_tree/examples 31 | BRIEF_MEMBER_DESC=YES 32 | REPEAT_BRIEF=YES 33 | ALWAYS_DETAILED_SEC=YES 34 | MULTILINE_CPP_IS_BRIEF=YES 35 | ; 36 | 37 | xml property_tree : property_tree.qbk ; 38 | 39 | boostbook standalone 40 | : property_tree 41 | : boost.root=../../../.. 42 | toc.max.depth=3 43 | toc.section.depth=2 44 | chunk.section.depth=3 45 | autodoc 46 | pdf:boost.url.prefix=http://www.boost.org/doc/libs/release/libs/property_tree/doc/html 47 | ; 48 | 49 | ############################################################################### 50 | alias boostdoc 51 | : property_tree 52 | : 53 | : autodoc 54 | : ; 55 | explicit boostdoc ; 56 | alias boostrelease ; 57 | explicit boostrelease ; 58 | -------------------------------------------------------------------------------- /doc/accessing.qbk: -------------------------------------------------------------------------------- 1 | [/ 2 | / Copyright (c) 2008 Marcin Kalicinski (kalita poczta dot onet dot pl) 3 | / Copyright (c) 2009 Sebastian Redl (sebastian dot redl getdesigned dot at) 4 | / 5 | / Distributed under the Boost Software License, Version 1.0. (See accompanying 6 | / file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 7 | /] 8 | [section:accessing How to Access Data in a Property Tree] 9 | [/ __ptree_*__ macros expected from property_tree.qbk] 10 | [def __pi__ ['pi]] [/ mathematical constant] 11 | 12 | Property tree resembles (almost is) a standard container with value type of `pair`. It has the usual member functions, such as __ptree_insert__, __ptree_push_back__, __ptree_find__, __ptree_erase__, etc. These can of course be used to populate and access the tree. For example the following code adds key `"pi"` with data (almost) equal to mathematical __pi__ value: 13 | 14 | __ptree__ pt; 15 | pt.__ptree_push_back__(__ptree__::__ptree_value_type__("pi", __ptree__("3.14159"))); 16 | 17 | To find the value of `pi` we might do the following: 18 | 19 | __ptree__::__ptree_const_assoc_iterator__ it = pt.__ptree_find__("pi"); 20 | double pi = boost::lexical_cast(it->second.__ptree_data__()); 21 | 22 | This looks quite cumbersome, and would be even more so if `pi` value was not stored so near the top of the tree, and we cared just a little bit more about errors. Fortunately, there is another, correct way of doing it: 23 | 24 | ptree pt; 25 | pt.__ptree_put__("pi", 3.14159); // put double 26 | double pi = pt.__ptree_get__("pi"); // get double 27 | 28 | It doesn't get simpler than that. Basically, there are 2 families of member functions, __ptree_get__ and __ptree_put__, which allow intuitive access to data stored in the tree (direct children or not). 29 | 30 | [heading Three Ways of Getting Data] 31 | 32 | There are three versions of get: get, get (default-value version), and get_optional, which differ by failure handling strategy. All versions take path specifier, which determines in which key to search for a value. It can be a single key, or a path to key, where path elements are separated with a special character (a '.' if not specified differently). For example debug.logging.errorlevel might be a valid path with dot as a separator. 33 | 34 | # The throwing version (__ptree_get__): 35 | `` 36 | __ptree__ pt; 37 | /* ... */ 38 | float v = pt.__ptree_get__("a.path.to.float.value"); 39 | `` 40 | This call locates the proper node in the tree and tries to translate its data string to a float value. If that fails, exception is thrown. If path does not exist, it will be __ptree_bad_path__ exception. If value could not be translated, it will be __ptree_bad_data__. Both of them derive from __ptree_error__ to make common handling possible. 41 | # The default-value version (__ptree_get_defaulted__): 42 | `` 43 | __ptree__ pt; 44 | /* ... */ 45 | float v = pt.__ptree_get_defaulted__("a.path.to.float.value", -1.f); 46 | `` 47 | It will do the same as above, but if it fails, it will return the default value specified by second parameter (here -1.f) instead of throwing. This is very useful in common situations where one wants to allow omitting of some keys. Note that type specification needed in throwing version is normally not necessary here, because type is determined by the default value parameter. 48 | # The optional version (__ptree_get_optional__): 49 | `` 50 | __ptree__ pt; 51 | /* ... */ 52 | boost::optional v = pt.__ptree_get_optional__("a.path.to.float.value"); 53 | `` 54 | This version uses boost::optional class to handle extraction failure. On successful extraction, it will return boost::optional initialized with extracted value. Otherwise, it will return uninitialized boost::optional. 55 | 56 | To retrieve a value from this tree (not some subkey), use __ptree_get_value__, __ptree_get_value__ (default-value version), and __ptree_get_value_optional__. They have identical semantics to __ptree_get__ functions, except they don't take the __path__ parameter. Don't call __ptree_get__ with and empty __path__ to do this as it will try to extract contents of subkey with empty name. 57 | 58 | To use a separator character other than default '[^.]', you need to construct 59 | a path object explicitly. The path type for a __ptree__ is a string_path 60 | instantiation, so the easiest way to refer to it is __ptree__::path_type. 61 | This way you can use trees that have dots in their keys: 62 | 63 | typedef ptree::path_type path; 64 | pt.get(path("p.a.t.h/t.o/v.a.l.u.e", '/')); 65 | pt.get(path("p.a.t.h/t.o/v.a.l.u.e", '/'), 0, NULL); 66 | pt.get_optional(path("p.a.t.h/t.o/v.a.l.u.e", '/')); 67 | 68 | Note: the special overloads of __ptree_get__ and __ptree_get_optional__ taking 69 | a separator character that existed in pre-release versions of PropertyTree have 70 | been removed. This is because the overloads conflicted with using per-call data 71 | translators. 72 | 73 | [heading Two Ways of Putting Data] 74 | 75 | To complement __ptree_get__, there are __ptree_put__ and __ptree_add__. Contrary to __ptree_get__, they have only one variant each. This is because there is no need to deal with missing values when adding data. If the supplied value cannot be converted to the tree's data type, the functions will throw __ptree_bad_data__. 76 | 77 | __ptree__ pt; 78 | pt.__ptree_put__("a.path.to.float.value", 3.14f); 79 | // Overwrites the value 80 | pt.__ptree_put__("a.path.to.float.value", 2.72f); 81 | // Adds a second node with the new value. 82 | pt.__ptree_add__("a.path.to.float.value", 3.14f); 83 | 84 | Calling __ptree_put__ will insert a new value at specified path, so that a call to __ptree_get__ specifying the same path will retrieve it. Further, __ptree_put__ will insert any missing path elements during path traversal. For example, calling `__ptree_put__("key1.key2.key3", 3.14f)` on an empty tree will insert three new children: `key1`, `key1.key2` and `key1.key2.key3`. The last one will receive a string `"3.14"` as data, while the two former ones will have empty data strings. __ptree_put__ always inserts new keys at the back of the existing sequences. 85 | The difference between __ptree_put__ and __ptree_add__ is that put will overwrite existing values if there are any, while add will create a new node to hold the value even if the specified path references an existing node. 86 | 87 | Similar to __ptree_get_value__, there is also a __ptree_put_value__ function. It does the same for this property tree what __ptree_put__ does for its children. Thus, it does not receive a __path__: 88 | 89 | __ptree__ pt; 90 | pt.__ptree_put_value__(3.14f); 91 | 92 | There is no add_value function. 93 | 94 | [endsect] 95 | -------------------------------------------------------------------------------- /doc/cmd_line_parser.qbk: -------------------------------------------------------------------------------- 1 | [/ 2 | / Copyright (c) 2008 Marcin Kalicinski (kalita poczta dot onet dot pl) 3 | / Copyright (c) 2009 Sebastian Redl (sebastian dot redl getdesigned dot at) 4 | / 5 | / Distributed under the Boost Software License, Version 1.0. (See accompanying 6 | / file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 7 | /] 8 | [section:cmdline_parser Command Line Parser] 9 | [def __read_cmdline__ [funcref boost::property_tree::cmdline_parser::read_cmdline read_cmdline]] 10 | This is a simple parser that converts command line parameters (in form of standard `argc` and `argv` arguments) into a property tree. There is no write function. The parser correctly recognizes simple command line styles, both from Unix and Windows worlds. 11 | 12 | During parse, parameters are converted to __ptree__ keys and grouped by their prefix, if any. Grouping means that they are inserted as children of a key representing appropriate group. Prefix is a single character that comes directly after so called "metacharacter", which is usually a dash '-' (on Unix) or a slash '/' (on Windows). For example, parameter [^-I/usr/include/foobar] has prefix [^I] after metacharacter '[^-]'. Parameters that do not start with a metacharacter (e.g. source files given to gcc), are inserted as children of a special, unnamed group. Additionally, data of each group contains value of last parameter assigned to that group. For example, this command line: 13 | 14 | [pre myprogram.exe -c -I/usr/include -Lm -I/home/mammamia/stuff foo.c bar.c -g] 15 | 16 | will result in the following property tree being created: 17 | 18 | "" bar.c ;"unnamed" group 19 | { 20 | "0" myprogram.exe ;first argument is name of program 21 | "1" foo.c 22 | "2" bar.c 23 | } 24 | c ;no data 25 | { 26 | "0" "" ;no value associated with 'c' option 27 | } 28 | I /home/mammamia/stuff 29 | { 30 | "0" /usr/include 31 | "1" /home/mammamia/stuff 32 | } 33 | L m 34 | { 35 | "0" m 36 | } 37 | 38 | Within each group, parameters are numbered, starting from zero. 39 | 40 | Metacharacters can be specified as a parameter to read function. This code will parse command line using both dash and slash as metachatacters: 41 | 42 | __ptree__ pt; 43 | __read_cmdline__(argc, argv, "-/", pt); 44 | 45 | Once the command line is parsed into a __ptree__, the power of the __ptree_get__, __ptree_get_child__, and __ptree_get_value__ interfaces can be used to conveniently extract the values of options needed. In the simplest case, user only needs to query key with name of option to get its value. For example: 46 | 47 | // default to 0 if -Nxx or /Nxx not specified on command line 48 | int n = pt.__ptree_get_defaulted__("N", 0); 49 | 50 | or 51 | 52 | // throw if -Nxx or /Nxx not specified on command line 53 | int n = pt.__ptree_get__("N"); 54 | 55 | If there is more than one instance of 'N' in command line, they can be accessed as: 56 | 57 | // Copy values of all -N arguments to vector 58 | std::vector vec; 59 | BOOST_FOREACH(const __ptree__::__ptree_value_type__ &v, pt.__ptree_get_child__("N", empty_ptree())) 60 | vec.push_back(v.second.__ptree_get_value__()); 61 | 62 | or: 63 | 64 | // Use numbering to access specific instances of parameter -N 65 | int first_n = pt.__ptree_get_defaulted__("N.0", default_n_value); 66 | int second_n = pt.__ptree_get_defaulted__("N.1", default_n_value); 67 | /* ... */ 68 | int tenth_n = pt.__ptree_get_defaulted__("N.9", default_n_value); 69 | 70 | If you want to know how many [^-N]'s were specified: 71 | 72 | // Count -N parameters 73 | size_t count = pt.__ptree_get_child__("N", empty_ptree()).size(); 74 | 75 | First argument, `argv[0]`, normally contains path to executable, which is rarely used for arguments parsing. To skip it, invoke the parser like in the following manner: 76 | 77 | // Skip program path 78 | __read_cmdline__(argc - 1, argv + 1, "-", pt) 79 | 80 | [endsect] [/cmd_line_parser] 81 | -------------------------------------------------------------------------------- /doc/container.qbk: -------------------------------------------------------------------------------- 1 | [/ 2 | / Copyright (c) 2008 Marcin Kalicinski (kalita poczta dot onet dot pl) 3 | / Copyright (c) 2009 Sebastian Redl (sebastian dot redl getdesigned dot at) 4 | / 5 | / Distributed under the Boost Software License, Version 1.0. (See accompanying 6 | / file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 7 | /] 8 | [section:container Property Tree as a Container] 9 | [/ __ptree_*__ macros expected from property_tree.qbk] 10 | Every property tree node models the ReversibleSequence concept, providing 11 | access to its immediate children. This means that iterating over a __ptree__ 12 | (which is the same as its root node - every __ptree__ node is also the 13 | subtree it starts) iterates only a single level of the hierarchy. There is no 14 | way to iterate over the entire tree. 15 | 16 | It is very important to remember that the property sequence is *not* ordered by 17 | the key. It preserves the order of insertion. It closely resembles a std::list. 18 | Fast access to children by name is provided via a separate lookup structure. Do 19 | not attempt to use algorithms that expect an ordered sequence (like 20 | binary_search) on a node's children. 21 | 22 | The property tree exposes a second container-like interface, called the 23 | associative view. Its iterator type is the nested type assoc_iterator (and its 24 | const counterpart const_assoc_iterator). You can get an ordered view of all 25 | children by using ordered_begin() and ordered_end(). 26 | 27 | The associative view also provides find() and equal_range() members, which 28 | return assoc_iterators, but otherwise have the same semantics as the members 29 | of std::map of the same name. 30 | 31 | You can get a normal iterator from an assoc_iterator by using the to_iterator() 32 | member function. Converting the other way is not possible. 33 | [endsect] [/container] 34 | -------------------------------------------------------------------------------- /doc/images/ptree2code.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostorg/property_tree/472e87eaf6daf89fe08985d2d5ecc693cb778c58/doc/images/ptree2code.png -------------------------------------------------------------------------------- /doc/info_parser.qbk: -------------------------------------------------------------------------------- 1 | [/ 2 | / Copyright (c) 2008 Marcin Kalicinski (kalita poczta dot onet dot pl) 3 | / Copyright (c) 2009 Sebastian Redl (sebastian dot redl getdesigned dot at) 4 | / 5 | / Distributed under the Boost Software License, Version 1.0. (See accompanying 6 | / file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 7 | /] 8 | [section INFO Parser] 9 | The INFO format was created specifically for the property tree library. It 10 | provides a simple, efficient format that can be used to serialize property 11 | trees that are otherwise only stored in memory. It can also be used for any 12 | other purpose, although the lack of widespread existing use may prove to be an 13 | impediment. 14 | 15 | INFO provides several features that make it familiar to C++ programmers and 16 | efficient for medium-sized datasets, especially those used for test input. It 17 | supports C-style character escapes, nesting via curly braces, and file inclusion 18 | via #include. 19 | 20 | INFO is also used for visualization of property trees in this documentation. 21 | 22 | A typical INFO file might look like this: 23 | 24 | key1 value1 25 | key2 26 | { 27 | key3 value3 28 | { 29 | key4 "value4 with spaces" 30 | } 31 | key5 value5 32 | } 33 | 34 | Here's a more complicated file demonstrating all of INFO's features: 35 | 36 | ; A comment 37 | key1 value1 ; Another comment 38 | key2 "value with special characters in it {};#\n\t\"\0" 39 | { 40 | subkey "value split "\ 41 | "over three"\ 42 | "lines" 43 | { 44 | a_key_without_value "" 45 | "a key with special characters in it {};#\n\t\"\0" "" 46 | "" value ; Empty key with a value 47 | "" "" ; Empty key with empty value! 48 | } 49 | } 50 | #include "file.info" ; included file 51 | 52 | INFO round-trips except for the loss of comments and include directives. 53 | 54 | [endsect] [/info_parser] 55 | -------------------------------------------------------------------------------- /doc/ini_parser.qbk: -------------------------------------------------------------------------------- 1 | [/ 2 | / Copyright (c) 2008 Marcin Kalicinski (kalita poczta dot onet dot pl) 3 | / Copyright (c) 2009 Sebastian Redl (sebastian dot redl getdesigned dot at) 4 | / 5 | / Distributed under the Boost Software License, Version 1.0. (See accompanying 6 | / file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 7 | /] 8 | [section INI Parser] 9 | [def __ini__ [@https://en.wikipedia.org/wiki/INI_file INI format]] 10 | The __ini__ was once widely used in the world of Windows. It is now deprecated, 11 | but is still used by a surprisingly large number of applications. The reason is 12 | probably its simplicity, plus that Microsoft recommends using the registry as 13 | a replacement, which not all developers want to do. 14 | 15 | INI is a simple key-value format with a single level of sectioning. It is thus 16 | less rich than the property tree dataset, which means that not all property 17 | trees can be serialized as INI files. 18 | 19 | The INI parser creates a tree node for every section, and a child node for 20 | every property in that section. All properties not in a section are directly 21 | added to the root node. Empty sections are ignored. (They don't round-trip, as 22 | described below.) 23 | 24 | The INI serializer reverses this process. It first writes out every child of the 25 | root that contains data, but no child nodes, as properties. Then it creates a 26 | section for every child that contains child nodes, but no data. The children of 27 | the sections must only contain data. It is an error if the root node contains 28 | data, or any child of the root contains both data and content, or there's more 29 | than three levels of hierarchy. There must also not be any duplicate keys. 30 | 31 | An empty tree node is assumed to be an empty property. There is no way to create 32 | empty sections. 33 | 34 | Since the Windows INI parser discards trailing spaces and does not support 35 | quoting, the property tree parser follows this example. This means that 36 | property values containing trailing spaces do not round-trip. 37 | [endsect] [/ini_parser] 38 | -------------------------------------------------------------------------------- /doc/intro.qbk: -------------------------------------------------------------------------------- 1 | [/ 2 | / Copyright (c) 2008 Marcin Kalicinski (kalita poczta dot onet dot pl) 3 | / Copyright (c) 2009 Sebastian Redl (sebastian dot redl getdesigned dot at) 4 | / 5 | / Distributed under the Boost Software License, Version 1.0. (See accompanying 6 | / file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 7 | /] 8 | [template ptree2codeImage[] [$images/ptree2code.png]] 9 | [section:intro What is Property Tree?] 10 | The Property Tree library provides a data structure that stores an arbitrarily 11 | deeply nested tree of values, indexed at each level by some key. Each node of 12 | the tree stores its own value, plus an ordered list of its subnodes and their 13 | keys. The tree allows easy access to any of its nodes by means of a path, which 14 | is a concatenation of multiple keys. 15 | 16 | In addition, the library provides parsers and generators for a number of data 17 | formats that can be represented by such a tree, including XML, INI, and JSON. 18 | 19 | Property trees are versatile data structures, but are particularly suited for 20 | holding configuration data. The tree provides its own, tree-specific interface, 21 | and each node is also an STL-compatible Sequence for its child nodes. 22 | 23 | Conceptually, then, a node can be thought of as the following structure: 24 | 25 | struct ptree 26 | { 27 | data_type data; // data associated with the node 28 | list< pair > children; // ordered list of named children 29 | }; 30 | 31 | Both key_type and data_type are configurable to some extent, but will usually be 32 | std::string or std::wstring, and the parsers only work with this kind of tree. 33 | 34 | Many software projects develop a similar tool at some point of their lifetime, 35 | and property tree originated the same way. We hope the library can save many 36 | from reinventing the wheel. 37 | [endsect] [/intro] 38 | -------------------------------------------------------------------------------- /doc/json_parser.qbk: -------------------------------------------------------------------------------- 1 | [/ 2 | / Copyright (c) 2008 Marcin Kalicinski (kalita poczta dot onet dot pl) 3 | / Copyright (c) 2009 Sebastian Redl (sebastian dot redl getdesigned dot at) 4 | / 5 | / Distributed under the Boost Software License, Version 1.0. (See accompanying 6 | / file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 7 | /] 8 | [section JSON Parser] 9 | [def __json__ [@http://en.wikipedia.org/wiki/JSON JSON format]] 10 | The __json__ is a data interchange format derived from the object literal 11 | notation of JavaScript. (JSON stands for JavaScript Object Notation.) 12 | JSON is a simple, compact format for loosely structured node trees of any depth, 13 | very similar to the property tree dataset. It is less structured than XML and 14 | has no schema support, but has the advantage of being simpler, smaller and typed 15 | without the need for a complex schema. 16 | 17 | The property tree dataset is not typed, and does not support arrays as such. 18 | Thus, the following JSON / property tree mapping is used: 19 | 20 | * JSON objects are mapped to nodes. Each property is a child node. 21 | * JSON arrays are mapped to nodes. Each element is a child node with an empty 22 | name. If a node has both named and unnamed child nodes, it cannot be mapped 23 | to a JSON representation. 24 | * JSON values are mapped to nodes containing the value. However, all type 25 | information is lost; numbers, as well as the literals "null", "true" and 26 | "false" are simply mapped to their string form. 27 | * Property tree nodes containing both child nodes and data cannot be mapped. 28 | 29 | JSON round-trips, except for the type information loss. 30 | 31 | For example this JSON: 32 | 33 | { 34 | "menu": 35 | { 36 | "foo": true, 37 | "bar": "true", 38 | "value": 102.3E+06, 39 | "popup": 40 | [ 41 | {"value": "New", "onclick": "CreateNewDoc()"}, 42 | {"value": "Open", "onclick": "OpenDoc()"}, 43 | ] 44 | } 45 | } 46 | 47 | will be translated into the following property tree: 48 | 49 | menu 50 | { 51 | foo true 52 | bar true 53 | value 102.3E+06 54 | popup 55 | { 56 | "" 57 | { 58 | value New 59 | onclick CreateNewDoc() 60 | } 61 | "" 62 | { 63 | value Open 64 | onclick OpenDoc() 65 | } 66 | } 67 | } 68 | 69 | [endsect] [/json_parser] 70 | -------------------------------------------------------------------------------- /doc/parsers.qbk: -------------------------------------------------------------------------------- 1 | [/ 2 | / Copyright (c) 2008 Marcin Kalicinski (kalita poczta dot onet dot pl) 3 | / Copyright (c) 2009 Sebastian Redl (sebastian dot redl getdesigned dot at) 4 | / 5 | / Distributed under the Boost Software License, Version 1.0. (See accompanying 6 | / file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 7 | /] 8 | [section:parsers How to Populate a Property Tree] 9 | [include xml_parser.qbk] 10 | 11 | [include json_parser.qbk] 12 | 13 | [include ini_parser.qbk] 14 | 15 | [include info_parser.qbk] 16 | 17 | [/ These parsers will be dropped for now.] 18 | [/ include cmd_line_parser.qbk] 19 | 20 | [/ include windows_registry_parser.qbk] 21 | 22 | [/ include system_environment_parser.qbk] 23 | 24 | [endsect] [/parsers] 25 | -------------------------------------------------------------------------------- /doc/property_tree.qbk: -------------------------------------------------------------------------------- 1 | [/ 2 | / Copyright (c) 2008 Marcin Kalicinski (kalita poczta dot onet dot pl) 3 | / Copyright (c) 2009 Sebastian Redl (sebastian dot redl getdesigned dot at) 4 | / 5 | / Distributed under the Boost Software License, Version 1.0. (See accompanying 6 | / file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 7 | /] 8 | 9 | [library Boost.PropertyTree 10 | [quickbook 1.6] 11 | [copyright 2008-2010 Marcin Kalicinski] 12 | [copyright 2010-2013 Sebastian Redl] 13 | [purpose Property Tree library] 14 | [license 15 | Distributed under the Boost Software License, Version 1.0. 16 | (See accompanying file LICENSE_1_0.txt or copy at 17 | [@http://www.boost.org/LICENSE_1_0.txt]) 18 | ] 19 | [authors [Kalicinski, Marcin], [Redl, Sebastian]] 20 | [id property_tree] 21 | [dirname property_tree] 22 | [category container] 23 | [category template] 24 | ] 25 | 26 | [/ Tried to use templates here but got errors expanding them in [classref ...] etc.] 27 | [/ types] 28 | [def __ptree__ [classref boost::property_tree::ptree ptree]] 29 | [def __ptree_value_type__ [classref boost::property_tree::basic_ptree::value_type value_type]] 30 | [def __ptree_data_type__ [classref boost::property_tree::basic_ptree::data_type data_type]] 31 | [def __ptree_iterator__ [classref boost::property_tree::basic_ptree::iterator iterator]] 32 | [def __ptree_const_iterator__ [classref boost::property_tree::basic_ptree::const_iterator const_iterator]] 33 | [def __ptree_assoc_iterator__ [classref boost::property_tree::basic_ptree::assoc_iterator assoc_iterator]] 34 | [def __ptree_const_assoc_iterator__ [classref boost::property_tree::basic_ptree::const_assoc_iterator const_assoc_iterator]] 35 | [def __path__ [classref boost::property_tree::string_path path]] 36 | [def __ptree_error__ [classref boost::property_tree::ptree_error ptree_error]] 37 | [def __ptree_bad_data__ [classref boost::property_tree::ptree_bad_data ptree_bad_data]] 38 | [def __ptree_bad_path__ [classref boost::property_tree::ptree_bad_path ptree_bad_path]] 39 | 40 | [/ members] 41 | [def __ptree_data__ [memberref boost::property_tree::basic_ptree::data data]] 42 | [def __ptree_find__ [memberref boost::property_tree::basic_ptree::find find]] 43 | [def __ptree_insert__ [memberref boost::property_tree::basic_ptree::insert insert]] 44 | [def __ptree_push_front__ [memberref boost::property_tree::basic_ptree::push_front push_front]] 45 | [def __ptree_push_back__ [memberref boost::property_tree::basic_ptree::push_back push_back]] 46 | [def __ptree_erase__ [memberref boost::property_tree::basic_ptree::erase erase]] 47 | [def __ptree_sort__ [memberref boost::property_tree::basic_ptree::sort sort]] 48 | [def __ptree_get__ [memberref boost::property_tree::basic_ptree::get get]] 49 | [/ XXX: Don't know how to specify overloads] 50 | [def __ptree_get_defaulted__ [memberref boost::property_tree::basic_ptree::get get]] 51 | [def __ptree_get_optional__ [memberref boost::property_tree::basic_ptree::get_optional get_optional]] 52 | [def __ptree_get_value__ [memberref boost::property_tree::basic_ptree::get_value get_value]] 53 | [/ XXX: Don't know how to specify overloads] 54 | [def __ptree_get_value_defaulted__ [memberref boost::property_tree::basic_ptree::get_value get_value]] 55 | [def __ptree_get_value_optional__ [memberref boost::property_tree::basic_ptree::get_value_optional get_value_optional]] 56 | [def __ptree_get_child__ [memberref boost::property_tree::basic_ptree::get_child get_child]] 57 | [def __ptree_put__ [memberref boost::property_tree::basic_ptree::put put]] 58 | [def __ptree_add__ [memberref boost::property_tree::basic_ptree::add add]] 59 | [def __ptree_put_value__ [memberref boost::property_tree::basic_ptree::put_value put_value]] 60 | 61 | [/ free-functions] 62 | [def __read_xml__ [funcref boost::property_tree::xml_parser::read_xml read_xml]] 63 | [def __write_xml__ [funcref boost::property_tree::xml_parser::write_xml write_xml]] 64 | 65 | [include intro.qbk] 66 | 67 | [include tutorial.qbk] 68 | 69 | [include container.qbk] 70 | 71 | [include synopsis.qbk] 72 | 73 | [include parsers.qbk] 74 | 75 | [include accessing.qbk] 76 | 77 | [section Appendices] 78 | [heading Compatibility] 79 | Property tree uses partial class template specialization. There has been no 80 | attempt to work around lack of support for this. The library will therefore 81 | most probably not work with Visual C++ 7.0 or earlier, or gcc 2.x. 82 | 83 | Property tree has been tested (regressions successfully compiled and run) 84 | with the following compilers: 85 | 86 | * Visual C++ 8.0 87 | * gcc 3.4.2 (MinGW) 88 | * gcc 3.3.5 (Linux) 89 | * gcc 3.4.4 (Linux) 90 | * gcc 4.3.3 (Linux) 91 | * Intel C++ 9.0 (Linux) 92 | 93 | [heading Rationale] 94 | # [*Why are there 3 versions of __ptree_get__? Couldn't there be just one?] 95 | The three versions reflect experience gathered during several of years of using 96 | property tree in several different applications. During that time I tried hard 97 | to come up with one, proper form of the get function, and failed. I know of 98 | these three basic patterns of usage: 99 | 100 | * ['Just get the data and I do not care if it cannot be done.] This is used 101 | when the programmer is fairly sure that data exists. Or in homework 102 | assignments. Or when tomorrow is final deadline for your project. 103 | * ['Get the data and revert to default value if it cannot be done.] Used when 104 | you want to allow omitting the key in question. Implemented by some similar 105 | tools (windows INI file access functions). 106 | * ['Get the data, but I care more whether you succeeded than I do for the data 107 | itself.] Used when you want to vary control flow depending on get 108 | success/failure. Or to check for presence of a key. 109 | 110 | [heading Future Development] 111 | * More parsers: YAML, environment strings. 112 | * More robust XML parser. 113 | * Mathematical relations: ptree difference, union, intersection. 114 | Useful for finding configuration file changes etc. 115 | 116 | [endsect] [/ Appendices] 117 | 118 | [xinclude autodoc.xml] 119 | -------------------------------------------------------------------------------- /doc/synopsis.qbk: -------------------------------------------------------------------------------- 1 | [/ 2 | / Copyright (c) 2008 Marcin Kalicinski (kalita poczta dot onet dot pl) 3 | / Copyright (c) 2009 Sebastian Redl (sebastian dot redl getdesigned dot at) 4 | / 5 | / Distributed under the Boost Software License, Version 1.0. (See accompanying 6 | / file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 7 | /] 8 | [section:synopsis Property Tree Synopsis] 9 | [def __basic_ptree__ [classref boost::property_tree::basic_ptree basic_ptree]] 10 | [def __ptree__ [classref boost::property_tree::ptree ptree]] 11 | [def __wptree__ [classref boost::property_tree::wptree wptree]] 12 | [def __iptree__ [classref boost::property_tree::iptree iptree]] 13 | [def __wiptree__ [classref boost::property_tree::wiptree wiptree]] 14 | [/ basic_ptree members] 15 | [def __ptree_get__ [memberref boost::property_tree::basic_ptree::get get]] 16 | [def __ptree_put__ [memberref boost::property_tree::basic_ptree::put put]] 17 | [def __ptree_get_value__ [memberref boost::property_tree::basic_ptree::get_value get_value]] 18 | [def __ptree_put_value__ [memberref boost::property_tree::basic_ptree::put_value put_value]] 19 | [def __ptree_get_child__ [memberref boost::property_tree::basic_ptree::get_child get_child]] 20 | [def __ptree_put_child__ [memberref boost::property_tree::basic_ptree::put_child put_child]] 21 | [def __ptree_data__ [memberref boost::property_tree::basic_ptree::data data]] 22 | The central component of the library is the __basic_ptree__ class template. 23 | Instances of this class are property trees. It is parametrized on key and data 24 | type, and key comparison policy; __ptree__, __wptree__, __iptree__ and 25 | __wiptree__ are typedefs of __basic_ptree__ using predefined combinations of 26 | template parameters. Property tree is basically a somewhat simplified standard 27 | container (the closest being std::list), plus a bunch of extra member 28 | functions. These functions allow easy and effective access to the data stored 29 | in property tree. They are various variants of __ptree_get__, __ptree_put__, 30 | __ptree_get_value__, __ptree_put_value__, __ptree_get_child__, 31 | __ptree_put_child__. Additionally, there is a __ptree_data__ function to access 32 | node data directly. 33 | 34 | See the [classref boost::property_tree::basic_ptree basic_ptree class template synopsis] for more information. 35 | [endsect] 36 | -------------------------------------------------------------------------------- /doc/system_environment_parser.qbk: -------------------------------------------------------------------------------- 1 | [/ 2 | / Copyright (c) 2008 Marcin Kalicinski (kalita poczta dot onet dot pl) 3 | / Copyright (c) 2009 Sebastian Redl (sebastian dot redl getdesigned dot at) 4 | / 5 | / Distributed under the Boost Software License, Version 1.0. (See accompanying 6 | / file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 7 | /] 8 | [section System Environment Parser] 9 | [note The system environment parser is not yet implemented.] 10 | [endsect] [/env_parser] 11 | -------------------------------------------------------------------------------- /doc/tutorial.qbk: -------------------------------------------------------------------------------- 1 | [/ 2 | / Copyright (c) 2008 Marcin Kalicinski (kalita poczta dot onet dot pl) 3 | / Copyright (c) 2009, 2013 Sebastian Redl (sebastian dot redl getdesigned dot at) 4 | / 5 | / Distributed under the Boost Software License, Version 1.0. (See accompanying 6 | / file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 7 | /] 8 | [section:tutorial Five Minute Tutorial] 9 | [import ../examples/debug_settings.cpp] 10 | 11 | This tutorial uses XML. Note that the library is not specifically bound to XML, 12 | and any other supported format (such as INI or JSON) could be used instead. 13 | XML was chosen because the author thinks that a wide range of people is familiar 14 | with it. 15 | 16 | Suppose we are writing a logging system for some application, and need to read 17 | log configuration from a file when the program starts. The file with the log 18 | configuration looks like this: 19 | 20 | [pre 21 | 22 | debug.log 23 | 24 | Finance 25 | Admin 26 | HR 27 | 28 | 2 29 | 30 | ] 31 | 32 | It contains the log filename, a list of modules where logging is enabled, and 33 | the debug level value. 34 | 35 | First we need some includes: 36 | 37 | [debug_settings_includes] 38 | 39 | To store the logging configuration in the program we create a debug_settings 40 | structure: 41 | 42 | [debug_settings_data] 43 | 44 | All that needs to be done now is to write implementations of load() and save() 45 | member functions. Let's first deal with load(). It contains just 7 lines of 46 | code, although it does all the necessary things, including error reporting: 47 | 48 | [debug_settings_load] 49 | 50 | Now the save() function. It is also 7 lines of code: 51 | 52 | [debug_settings_save] 53 | 54 | The full program [@boost:/libs/property_tree/examples/debug_settings.cpp debug_settings.cpp] is 55 | included in the examples directory. 56 | [endsect] [/tutorial] 57 | -------------------------------------------------------------------------------- /doc/windows_registry_parser.qbk: -------------------------------------------------------------------------------- 1 | [/ 2 | / Copyright (c) 2008 Marcin Kalicinski (kalita poczta dot onet dot pl) 3 | / Copyright (c) 2009 Sebastian Redl (sebastian dot redl getdesigned dot at) 4 | / 5 | / Distributed under the Boost Software License, Version 1.0. (See accompanying 6 | / file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 7 | /] 8 | [section:registry_parser Windows Registry Parser] 9 | [def __registry_parser.hpp__ [headerref boost/property_tree/registry_parser.hpp registry_parser.hpp]] 10 | [def __read_registry__ [funcref boost::property_tree::registry_parser::read_registry read_registry]] 11 | [def __translate__ [funcref boost::property_tree::registry_parser::translate translate]] 12 | [def __write_registry__ [funcref boost::property_tree::registry_parser::write_registry write_registry]] 13 | This parser supports reading and writing data from Windows registry. There is only a subset of registry functionality implemented, because property tree is not intended to replace registry API. For example, access rights are not supported, as well as some exotic value formats. Registry is a rich data source, providing hierarchy of keys, each of whose can have any number of named and typed values attached to it. Because of that - like in XML - some translation is necessary. 14 | 15 | [important This parser will only work on a Windows system because it uses Windows API to access the registry. You will need to link with [^advapi32.lib]. A minimalist version of the [^windows.h] Windows header file is included by __registry_parser.hpp__. If you want to include [^windows.h] header on your own, do it before including __registry_parser.hpp__.] 16 | 17 | [heading How Registry Keys are Translated to Property Trees (__read_registry__):] 18 | 19 | * Values of each registry key are stored in a subkey with name [^\values]. The preceding backslash is there to prevent name clashes with regular keys. Each subkey of [^\values] is one registry value. If [^\values] subkey does not exist or is empty, there are no values attached to that key. 20 | * Types of values of each registry key are stored in a subkey with name [^\types]. These subkeys contain an integer equal to type of data stored in its corresponding entry in [^\values] (correspondence is by name, not position). 21 | * So called "default value" (value attached to key itself), is translated directly to key data and is always assumed to be of type [^REG_SZ]. 22 | * [^REG_BINARY] values are translated to textual format before placing in property tree. The format is the same as the one displayed by regedit application: a series of two-digit hexadecimal numbers representing bytes separated with spaces. To translate from this format to binary data, or vice versa, use the __translate__ function. 23 | * Supported value types are: [^REG_NONE], [^REG_SZ], [^REG_EXPAND_SZ], [^REG_DWORD], [^REG_QWORD], [^REG_BINARY]. 24 | 25 | Translation of property tree back into registry (__write_registry__) assumes the same structure as outlined above. That means if you want to have named values, you need to create [^\values] and [^\types] subkeys, and put them there. Also, you have to convert all [^REG_BINARY] values to textual format. Passing "normal" property tree (i.e. not containing [^\types] and [^\values] keys) to the __write_registry__ function will put all data in "default value" section of each key. This is fine, especially if you intend to read this data using property tree, but is probably not a standard way of storing things in the registry. 26 | 27 | For example, when you read registry key [^HKEY_CURRENT_USER\Software\Microsoft\Notepad], under Windows XP, you will get property tree containing Notepad font settings (among other things): 28 | 29 | Notepad 30 | { 31 | \values 32 | { 33 | lfFaceName Courier 34 | lfItalic 0 35 | lfWeight 190 36 | } 37 | \types 38 | { 39 | lfFaceName 1 ; REG_SZ 40 | lfItalic 4 ; REG_DWORD 41 | lfWeight 4 ; REG_DWORD 42 | } 43 | } 44 | 45 | [endsect] [/win_reg_parser] 46 | -------------------------------------------------------------------------------- /doc/xml_parser.qbk: -------------------------------------------------------------------------------- 1 | [/ 2 | / Copyright (c) 2008 Marcin Kalicinski (kalita poczta dot onet dot pl) 3 | / Copyright (c) 2009 Sebastian Redl (sebastian dot redl getdesigned dot at) 4 | / 5 | / Distributed under the Boost Software License, Version 1.0. (See accompanying 6 | / file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 7 | /] 8 | [section XML Parser] 9 | [def __xml__ [@http://en.wikipedia.org/wiki/XML XML format]] 10 | [def __xml_parser.hpp__ [headerref boost/property_tree/xml_parser.hpp xml_parser.hpp]] 11 | [def __RapidXML__ [@http://rapidxml.sourceforge.net/ RapidXML]] 12 | [def __boost__ [@http://www.boost.org Boost]] 13 | The __xml__ is an industry standard for storing information in textual 14 | form. Unfortunately, there is no XML parser in __boost__ as of the 15 | time of this writing. The library therefore contains the fast and tiny 16 | __RapidXML__ parser (currently in version 1.13) to provide XML parsing support. 17 | RapidXML does not fully support the XML standard; it is not capable of parsing 18 | DTDs and therefore cannot do full entity substitution. 19 | 20 | By default, the parser will preserve most whitespace, but remove element content 21 | that consists only of whitespace. Encoded whitespaces (e.g. ) does not 22 | count as whitespace in this regard. You can pass the trim_whitespace flag if you 23 | want all leading and trailing whitespace trimmed and all continuous whitespace 24 | collapsed into a single space. 25 | 26 | Please note that RapidXML does not understand the encoding specification. If 27 | you pass it a character buffer, it assumes the data is already correctly 28 | encoded; if you pass it a filename, it will read the file using the character 29 | conversion of the locale you give it (or the global locale if you give it none). 30 | This means that, in order to parse a UTF-8-encoded XML file into a wptree, you 31 | have to supply an alternate locale, either directly or by replacing the global 32 | one. 33 | 34 | XML / property tree conversion schema (__read_xml__ and __write_xml__): 35 | 36 | * Each XML element corresponds to a property tree node. The child elements 37 | correspond to the children of the node. 38 | * The attributes of an XML element are stored in the subkey [^]. There 39 | is one child node per attribute in the attribute node. Existence of the 40 | [^] node is not guaranteed or necessary when there are no attributes. 41 | * XML comments are stored in nodes named [^], unless comment 42 | ignoring is enabled via the flags. 43 | * Text content is stored in one of two ways, depending on the flags. The default 44 | way concatenates all text nodes and stores them as the data of the element 45 | node. This way, the entire content can be conveniently read, but the 46 | relative ordering of text and child elements is lost. The other way stores 47 | each text content as a separate node, all called [^]. 48 | 49 | The XML storage encoding does not round-trip perfectly. A read-write cycle loses 50 | trimmed whitespace, low-level formatting information, and the distinction 51 | between normal data and CDATA nodes. Comments are only preserved when enabled. 52 | A write-read cycle loses trimmed whitespace; that is, if the origin tree has 53 | string data that starts or ends with whitespace, that whitespace is lost. 54 | [endsect] [/xml_parser] 55 | -------------------------------------------------------------------------------- /examples/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com) 3 | # Copyright (c) 2021 Richard Hodges (hodges.r@gmail.com) 4 | # 5 | # Distributed under the Boost Software License, Version 1.0. (See accompanying 6 | # file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 7 | # 8 | # Official repository: https://github.com/boostorg/json 9 | # 10 | 11 | source_group("test" FILES 12 | custom_data_type.cpp 13 | debug_settings.cpp 14 | empty_ptree_trick.cpp 15 | info_grammar_spirit.cpp 16 | speed_test.cpp 17 | ) 18 | 19 | function(add_example) 20 | cmake_parse_arguments("addex" "" "NAME" "SRCS;DEPS" ${ARGN}) 21 | if("${addex_NAME}" STREQUAL "") 22 | message(SEND_ERROR "add_example: no NAME") 23 | return() 24 | endif() 25 | if("${addex_SRCS}" STREQUAL "") 26 | message(SEND_ERROR "add_example: no SRCS") 27 | return() 28 | endif() 29 | #message(STATUS "add_example: ${addex_NAME} SRCS: ${addex_SRCS} DEPS: ${addex_DEPS}") 30 | add_executable("${PROJECT_NAME}-example-${addex_NAME}" 31 | ${addex_SRCS}) 32 | set_property(TARGET "${PROJECT_NAME}-example-${addex_NAME}" PROPERTY FOLDER "example") 33 | target_link_libraries("${PROJECT_NAME}-example-${addex_NAME}" PRIVATE ${addex_DEPS}) 34 | endfunction() 35 | 36 | add_example(NAME custom_data_type SRCS custom_data_type.cpp DEPS Boost::property_tree) 37 | add_example(NAME debug_settings SRCS debug_settings.cpp DEPS Boost::property_tree Boost::foreach) 38 | configure_file(debug_settings.xml debug_settings.xml COPYONLY) 39 | add_example(NAME empty_ptree_trick SRCS empty_ptree_trick.cpp DEPS Boost::property_tree) 40 | add_example(NAME info_grammar_spirit SRCS info_grammar_spirit.cpp DEPS Boost::property_tree) 41 | add_example(NAME speed_test SRCS speed_test.cpp DEPS Boost::property_tree Boost::format) 42 | -------------------------------------------------------------------------------- /examples/Jamfile.v2: -------------------------------------------------------------------------------- 1 | # Boost PropertyTree Library Example Jamfile 2 | # Copyright (c) 2013 Sebastian Redl 3 | # Distributed under the Boost Software License, Version 1.0. 4 | # See http://www.boost.org/LICENSE_1_0.txt 5 | 6 | project : requirements /boost/property_tree//boost_property_tree ; 7 | 8 | exe custom_data_type : custom_data_type.cpp ; 9 | exe debug_settings : debug_settings.cpp 10 | /boost/foreach//boost_foreach ; 11 | exe empty_ptree_trick : empty_ptree_trick.cpp ; 12 | exe info_grammar_spirit : info_grammar_spirit.cpp ; 13 | exe speed_test : speed_test.cpp /boost/format//boost_format ; 14 | -------------------------------------------------------------------------------- /examples/custom_data_type.cpp: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------------- 2 | // Copyright (C) 2002-2006 Marcin Kalicinski 3 | // 4 | // Distributed under the Boost Software License, Version 1.0. 5 | // (See accompanying file LICENSE_1_0.txt or copy at 6 | // http://www.boost.org/LICENSE_1_0.txt) 7 | // 8 | // For more information, see www.boost.org 9 | // ---------------------------------------------------------------------------- 10 | 11 | // This example shows what need to be done to customize data_type of ptree. 12 | // 13 | // It creates my_ptree type, which is a basic_ptree having boost::any as its data 14 | // container (instead of std::string that standard ptree has). 15 | 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | // Custom translator that works with boost::any instead of std::string 23 | template 24 | struct variant_translator 25 | { 26 | typedef Ext external_type; 27 | typedef Int internal_type; 28 | 29 | external_type 30 | get_value(const internal_type &value) const 31 | { 32 | return boost::any_cast(value); 33 | } 34 | internal_type 35 | put_value(const external_type &value) const 36 | { 37 | return value; 38 | } 39 | }; 40 | 41 | int main() 42 | { 43 | 44 | using namespace boost::property_tree; 45 | 46 | // Property_tree with boost::any as data type 47 | // Key type: std::string 48 | // Data type: boost::any 49 | // Key comparison: default (std::less) 50 | typedef basic_ptree my_ptree; 51 | my_ptree pt; 52 | 53 | // Put/get int value 54 | typedef variant_translator int_tran; 55 | pt.put("int value", 3, int_tran()); 56 | int int_value = pt.get("int value", int_tran()); 57 | std::cout << "Int value: " << int_value << "\n"; 58 | 59 | // Put/get string value 60 | typedef variant_translator string_tran; 61 | pt.put("string value", "foo bar", string_tran()); 62 | std::string string_value = pt.get( 63 | "string value" 64 | , string_tran() 65 | ); 66 | std::cout << "String value: " << string_value << "\n"; 67 | 68 | // Put/get list value 69 | typedef std::list intlist; 70 | typedef variant_translator intlist_tran; 71 | int list_data[] = { 1, 2, 3, 4, 5 }; 72 | pt.put( 73 | "list value" 74 | , intlist( 75 | list_data 76 | , list_data + sizeof(list_data) / sizeof(*list_data) 77 | ) 78 | , intlist_tran() 79 | ); 80 | intlist list_value = pt.get( 81 | "list value" 82 | , intlist_tran() 83 | ); 84 | std::cout << "List value: "; 85 | for (intlist::iterator it = list_value.begin(); it != list_value.end(); ++it) 86 | std::cout << *it << ' '; 87 | std::cout << '\n'; 88 | } 89 | -------------------------------------------------------------------------------- /examples/debug_settings.cpp: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------------- 2 | // Copyright (C) 2002-2006 Marcin Kalicinski 3 | // 4 | // Distributed under the Boost Software License, Version 1.0. 5 | // (See accompanying file LICENSE_1_0.txt or copy at 6 | // http://www.boost.org/LICENSE_1_0.txt) 7 | // 8 | // For more information, see www.boost.org 9 | // ---------------------------------------------------------------------------- 10 | 11 | //[debug_settings_includes 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | namespace pt = boost::property_tree; 20 | //] 21 | //[debug_settings_data 22 | struct debug_settings 23 | { 24 | std::string m_file; // log filename 25 | int m_level; // debug level 26 | std::set m_modules; // modules where logging is enabled 27 | void load(const std::string &filename); 28 | void save(const std::string &filename); 29 | }; 30 | //] 31 | //[debug_settings_load 32 | void debug_settings::load(const std::string &filename) 33 | { 34 | // Create empty property tree object 35 | pt::ptree tree; 36 | 37 | // Parse the XML into the property tree. 38 | pt::read_xml(filename, tree); 39 | 40 | // Use the throwing version of get to find the debug filename. 41 | // If the path cannot be resolved, an exception is thrown. 42 | m_file = tree.get("debug.filename"); 43 | 44 | // Use the default-value version of get to find the debug level. 45 | // Note that the default value is used to deduce the target type. 46 | m_level = tree.get("debug.level", 0); 47 | 48 | // Use get_child to find the node containing the modules, and iterate over 49 | // its children. If the path cannot be resolved, get_child throws. 50 | // A C++11 for-range loop would also work. 51 | BOOST_FOREACH(pt::ptree::value_type &v, tree.get_child("debug.modules")) { 52 | // The data function is used to access the data stored in a node. 53 | m_modules.insert(v.second.data()); 54 | } 55 | 56 | } 57 | //] 58 | //[debug_settings_save 59 | void debug_settings::save(const std::string &filename) 60 | { 61 | // Create an empty property tree object. 62 | pt::ptree tree; 63 | 64 | // Put the simple values into the tree. The integer is automatically 65 | // converted to a string. Note that the "debug" node is automatically 66 | // created if it doesn't exist. 67 | tree.put("debug.filename", m_file); 68 | tree.put("debug.level", m_level); 69 | 70 | // Add all the modules. Unlike put, which overwrites existing nodes, add 71 | // adds a new node at the lowest level, so the "modules" node will have 72 | // multiple "module" children. 73 | BOOST_FOREACH(const std::string &name, m_modules) 74 | tree.add("debug.modules.module", name); 75 | 76 | // Write property tree to XML file 77 | pt::write_xml(filename, tree); 78 | } 79 | //] 80 | 81 | int main() 82 | { 83 | try 84 | { 85 | debug_settings ds; 86 | ds.load("debug_settings.xml"); 87 | ds.save("debug_settings_out.xml"); 88 | std::cout << "Success\n"; 89 | } 90 | catch (std::exception &e) 91 | { 92 | std::cout << "Error: " << e.what() << "\n"; 93 | } 94 | return 0; 95 | } 96 | -------------------------------------------------------------------------------- /examples/debug_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | debug.log 9 | 10 | Finance 11 | Admin 12 | HR 13 | 14 | 2 15 | 16 | -------------------------------------------------------------------------------- /examples/empty_ptree_trick.cpp: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------------- 2 | // Copyright (C) 2002-2006 Marcin Kalicinski 3 | // 4 | // Distributed under the Boost Software License, Version 1.0. 5 | // (See accompanying file LICENSE_1_0.txt or copy at 6 | // http://www.boost.org/LICENSE_1_0.txt) 7 | // 8 | // For more information, see www.boost.org 9 | // ---------------------------------------------------------------------------- 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | using namespace boost::property_tree; 18 | 19 | static ptree dflt; 20 | 21 | // Process settings using empty ptree trick. Note that it is considerably simpler 22 | // than version which does not use the "trick" 23 | void process_settings(const std::string &filename) 24 | { 25 | ptree pt; 26 | read_info(filename, pt); 27 | const ptree &settings = pt.get_child("settings", dflt); 28 | std::cout << "\n Processing " << filename << std::endl; 29 | std::cout << " Setting 1 is " << settings.get("setting1", 0) << std::endl; 30 | std::cout << " Setting 2 is " << settings.get("setting2", 0.0) << std::endl; 31 | std::cout << " Setting 3 is " << settings.get("setting3", "default") << std::endl; 32 | } 33 | 34 | // Process settings not using empty ptree trick. This one must duplicate much of the code. 35 | void process_settings_without_trick(const std::string &filename) 36 | { 37 | ptree pt; 38 | read_info(filename, pt); 39 | if (boost::optional settings = pt.get_child_optional("settings")) 40 | { 41 | std::cout << "\n Processing " << filename << std::endl; 42 | std::cout << " Setting 1 is " << settings.get().get("setting1", 0) << std::endl; 43 | std::cout << " Setting 2 is " << settings.get().get("setting2", 0.0) << std::endl; 44 | std::cout << " Setting 3 is " << settings.get().get("setting3", "default") << std::endl; 45 | } 46 | else 47 | { 48 | std::cout << "\n Processing " << filename << std::endl; 49 | std::cout << " Setting 1 is " << 0 << std::endl; 50 | std::cout << " Setting 2 is " << 0.0 << std::endl; 51 | std::cout << " Setting 3 is " << "default" << std::endl; 52 | } 53 | } 54 | 55 | int main() 56 | { 57 | try 58 | { 59 | std::cout << "Processing settings with empty-ptree-trick:\n"; 60 | process_settings("settings_fully-existent.info"); 61 | process_settings("settings_partially-existent.info"); 62 | process_settings("settings_non-existent.info"); 63 | std::cout << "\nProcessing settings without empty-ptree-trick:\n"; 64 | process_settings_without_trick("settings_fully-existent.info"); 65 | process_settings_without_trick("settings_partially-existent.info"); 66 | process_settings_without_trick("settings_non-existent.info"); 67 | } 68 | catch (std::exception &e) 69 | { 70 | std::cout << "Error: " << e.what() << "\n"; 71 | } 72 | return 0; 73 | } 74 | -------------------------------------------------------------------------------- /examples/info_grammar_spirit.cpp: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------------- 2 | // Copyright (C) 2002-2006 Marcin Kalicinski 3 | // 4 | // Distributed under the Boost Software License, Version 1.0. 5 | // (See accompanying file LICENSE_1_0.txt or copy at 6 | // http://www.boost.org/LICENSE_1_0.txt) 7 | // 8 | // For more information, see www.boost.org 9 | // ---------------------------------------------------------------------------- 10 | 11 | /* This is grammar of INFO file format written in form of boost::spirit rules. 12 | For simplicity, it does not parse #include directive. Note that INFO parser 13 | included in property_tree library does not use Spirit. 14 | */ 15 | 16 | //#define BOOST_SPIRIT_DEBUG // uncomment to enable debug output 17 | #include 18 | 19 | namespace spirit = boost::spirit; 20 | 21 | struct info_grammar: public spirit::classic::grammar 22 | { 23 | 24 | template 25 | struct definition 26 | { 27 | 28 | spirit::classic::rule::type> chr, qchr, escape_seq; 29 | spirit::classic::rule string, qstring, cstring, key, value, entry, info; 30 | 31 | definition(const info_grammar & /*self*/) 32 | { 33 | 34 | using namespace spirit::classic; 35 | 36 | escape_seq = chset_p("0abfnrtv\"\'\\"); 37 | chr = (anychar_p - space_p - '\\' - '{' - '}' - '#' - '"') | ('\\' >> escape_seq); 38 | qchr = (anychar_p - '"' - '\n' - '\\') | ('\\' >> escape_seq); 39 | string = lexeme_d[+chr]; 40 | qstring = lexeme_d['"' >> *qchr >> '"']; 41 | cstring = lexeme_d['"' >> *qchr >> '"' >> '\\']; 42 | key = string | qstring; 43 | value = string | qstring | (+cstring >> qstring) | eps_p; 44 | entry = key >> value >> !('{' >> *entry >> '}'); 45 | info = *entry >> end_p; 46 | 47 | // Debug nodes 48 | BOOST_SPIRIT_DEBUG_NODE(escape_seq); 49 | BOOST_SPIRIT_DEBUG_NODE(chr); 50 | BOOST_SPIRIT_DEBUG_NODE(qchr); 51 | BOOST_SPIRIT_DEBUG_NODE(string); 52 | BOOST_SPIRIT_DEBUG_NODE(qstring); 53 | BOOST_SPIRIT_DEBUG_NODE(key); 54 | BOOST_SPIRIT_DEBUG_NODE(value); 55 | BOOST_SPIRIT_DEBUG_NODE(entry); 56 | BOOST_SPIRIT_DEBUG_NODE(info); 57 | 58 | } 59 | 60 | const spirit::classic::rule &start() const 61 | { 62 | return info; 63 | } 64 | 65 | }; 66 | }; 67 | 68 | void info_parse(const char *s) 69 | { 70 | 71 | using namespace boost::spirit::classic; 72 | 73 | // Parse and display result 74 | info_grammar g; 75 | parse_info pi = parse(s, g, space_p | comment_p(";")); 76 | std::cout << "Parse result: " << (pi.hit ? "Success" : "Failure") << "\n"; 77 | 78 | } 79 | 80 | int main() 81 | { 82 | 83 | // Sample data 1 84 | const char *data1 = 85 | "\n" 86 | "key1 data1\n" 87 | "{\n" 88 | "\tkey data\n" 89 | "}\n" 90 | "key2 \"data2 \" {\n" 91 | "\tkey data\n" 92 | "}\n" 93 | "key3 \"data\"\n" 94 | "\t \"3\" {\n" 95 | "\tkey data\n" 96 | "}\n" 97 | "\n" 98 | "\"key4\" data4\n" 99 | "{\n" 100 | "\tkey data\n" 101 | "}\n" 102 | "\"key.5\" \"data.5\" { \n" 103 | "\tkey data \n" 104 | "}\n" 105 | "\"key6\" \"data\"\n" 106 | "\t \"6\" {\n" 107 | "\tkey data\n" 108 | "}\n" 109 | " \n" 110 | "key1 data1\n" 111 | "{\n" 112 | "\tkey data\n" 113 | "}\n" 114 | "key2 \"data2 \" {\n" 115 | "\tkey data\n" 116 | "}\n" 117 | "key3 \"data\"\n" 118 | "\t \"3\" {\n" 119 | "\tkey data\n" 120 | "}\n" 121 | "\n" 122 | "\"key4\" data4\n" 123 | "{\n" 124 | "\tkey data\n" 125 | "}\n" 126 | "\"key.5\" \"data.5\" {\n" 127 | "\tkey data\n" 128 | "}\n" 129 | "\"key6\" \"data\"\n" 130 | "\t \"6\" {\n" 131 | "\tkey data\n" 132 | "}\n" 133 | "\\\\key\\t7 data7\\n\\\"data7\\\"\n" 134 | "{\n" 135 | "\tkey data\n" 136 | "}\n" 137 | "\"\\\\key\\t8\" \"data8\\n\\\"data8\\\"\"\n" 138 | "{\n" 139 | "\tkey data\n" 140 | "}\n" 141 | "\n"; 142 | 143 | // Sample data 2 144 | const char *data2 = 145 | "key1\n" 146 | "key2\n" 147 | "key3\n" 148 | "key4\n"; 149 | 150 | // Parse sample data 151 | info_parse(data1); 152 | info_parse(data2); 153 | 154 | } 155 | -------------------------------------------------------------------------------- /examples/settings_fully-existent.info: -------------------------------------------------------------------------------- 1 | settings 2 | { 3 | setting1 15 4 | setting2 9.876 5 | setting3 Alice in Wonderland 6 | } 7 | -------------------------------------------------------------------------------- /examples/settings_non-existent.info: -------------------------------------------------------------------------------- 1 | ;settings // non-existent 2 | ;{ 3 | ; setting1 15 4 | ; setting2 9.876 5 | ; setting3 Alice in Wonderland 6 | ;} 7 | -------------------------------------------------------------------------------- /examples/settings_partially-existent.info: -------------------------------------------------------------------------------- 1 | settings 2 | { 3 | setting1 15 4 | ;setting2 9.876 // non-existent 5 | ;setting3 Alice in Wonderland // non-existent 6 | } 7 | -------------------------------------------------------------------------------- /examples/speed_test.cpp: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------------- 2 | // Copyright (C) 2002-2006 Marcin Kalicinski 3 | // 4 | // Distributed under the Boost Software License, Version 1.0. 5 | // (See accompanying file LICENSE_1_0.txt or copy at 6 | // http://www.boost.org/LICENSE_1_0.txt) 7 | // 8 | // For more information, see www.boost.org 9 | // ---------------------------------------------------------------------------- 10 | 11 | #define _HAS_ITERATOR_DEBUGGING 0 12 | 13 | #define _SILENCE_CXX17_OLD_ALLOCATOR_MEMBERS_DEPRECATION_WARNING 14 | 15 | // -Wdeprecated-copy-with-user-provided-copy in boost/format/group.hpp 16 | 17 | #if defined(__clang__) && defined(__has_warning) 18 | # if __has_warning( "-Wdeprecated-copy-with-user-provided-copy" ) 19 | # pragma clang diagnostic ignored "-Wdeprecated-copy-with-user-provided-copy" 20 | # endif 21 | // clang 10..12 emits this instead 22 | # if __has_warning( "-Wdeprecated-copy" ) 23 | # pragma clang diagnostic ignored "-Wdeprecated-copy" 24 | # endif 25 | #endif 26 | 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | 35 | using namespace std; 36 | using namespace boost; 37 | using namespace boost::property_tree; 38 | 39 | string dummy; 40 | vector keys; 41 | vector shuffled_keys; 42 | 43 | void prepare_keys(int size) 44 | { 45 | // Prepare keys 46 | keys.clear(); 47 | for (int i = 0; i < size; ++i) 48 | keys.push_back((boost::format("%d") % i).str()); 49 | shuffled_keys = keys; 50 | // Seed the engine with default seed every time 51 | std::shuffle(shuffled_keys.begin(), shuffled_keys.end(), std::mt19937()); 52 | } 53 | 54 | void clock_push_back(int size) 55 | { 56 | prepare_keys(size); 57 | int max_repeats = 1000000 / size; 58 | shared_array pt_array(new ptree[max_repeats]); 59 | 60 | int n = 0; 61 | clock_t t1 = clock(), t2 = t1; 62 | do 63 | { 64 | if (n >= max_repeats) 65 | break; 66 | ptree &pt = pt_array[n]; 67 | for (int i = 0; i < size; ++i) 68 | pt.push_back(ptree::value_type(shuffled_keys[i], ptree())); 69 | t2 = clock(); 70 | ++n; 71 | } while (t2 - t1 < CLOCKS_PER_SEC); 72 | 73 | cout << " push_back (" << size << "): " << double(t2 - t1) / CLOCKS_PER_SEC / n * 1000 << " ms\n"; 74 | 75 | } 76 | 77 | void clock_find(int size) 78 | { 79 | prepare_keys(size); 80 | 81 | ptree pt; 82 | for (int i = 0; i < size; ++i) 83 | pt.push_back(ptree::value_type(keys[i], ptree("data"))); 84 | 85 | int n = 0; 86 | clock_t t1 = clock(), t2; 87 | do 88 | { 89 | for (int i = 0; i < size; ++i) 90 | pt.find(shuffled_keys[i]); 91 | t2 = clock(); 92 | ++n; 93 | } while (t2 - t1 < CLOCKS_PER_SEC); 94 | 95 | cout << " find (" << size << "): " << double(t2 - t1) / CLOCKS_PER_SEC / n * 1000 << " ms\n"; 96 | 97 | } 98 | 99 | void clock_erase(int size) 100 | { 101 | prepare_keys(size); 102 | 103 | int max_repeats = 100000 / size; 104 | shared_array pt_array(new ptree[max_repeats]); 105 | 106 | for (int n = 0; n < max_repeats; ++n) 107 | for (int i = 0; i < size; ++i) 108 | pt_array[n].push_back(ptree::value_type(keys[i], ptree("data"))); 109 | 110 | int n = 0; 111 | clock_t t1 = clock(), t2 = t1; 112 | do 113 | { 114 | if (n >= max_repeats) 115 | break; 116 | ptree &pt = pt_array[n]; 117 | for (int i = 0; i < size; ++i) 118 | pt.erase(shuffled_keys[i]); 119 | t2 = clock(); 120 | ++n; 121 | } while (t2 - t1 < CLOCKS_PER_SEC); 122 | 123 | cout << " erase (" << size << "): " << double(t2 - t1) / CLOCKS_PER_SEC / n * 1000 << " ms\n"; 124 | } 125 | 126 | int main() 127 | { 128 | 129 | // push_back 130 | clock_push_back(10); 131 | clock_push_back(100); 132 | clock_push_back(1000); 133 | 134 | // erase 135 | clock_erase(10); 136 | clock_erase(100); 137 | clock_erase(1000); 138 | 139 | // find 140 | clock_find(10); 141 | clock_find(100); 142 | clock_find(1000); 143 | 144 | } 145 | -------------------------------------------------------------------------------- /include/boost/property_tree/detail/exception_implementation.hpp: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------------- 2 | // Copyright (C) 2002-2006 Marcin Kalicinski 3 | // Copyright (C) 2009 Sebastian Redl 4 | // 5 | // Distributed under the Boost Software License, Version 1.0. 6 | // (See accompanying file LICENSE_1_0.txt or copy at 7 | // http://www.boost.org/LICENSE_1_0.txt) 8 | // 9 | // For more information, see www.boost.org 10 | // ---------------------------------------------------------------------------- 11 | #ifndef BOOST_PROPERTY_TREE_DETAIL_EXCEPTIONS_IMPLEMENTATION_HPP_INCLUDED 12 | #define BOOST_PROPERTY_TREE_DETAIL_EXCEPTIONS_IMPLEMENTATION_HPP_INCLUDED 13 | 14 | #include 15 | 16 | #include 17 | 18 | namespace boost { namespace property_tree 19 | { 20 | 21 | namespace detail 22 | { 23 | 24 | // Helper for preparing what string in ptree_bad_path exception 25 | template inline 26 | std::string prepare_bad_path_what(const std::string &what, 27 | const P &path) 28 | { 29 | return what + " (" + path.dump() + ")"; 30 | } 31 | 32 | } 33 | 34 | /////////////////////////////////////////////////////////////////////////// 35 | // ptree_error 36 | 37 | inline ptree_error::ptree_error(const std::string &w): 38 | std::runtime_error(w) 39 | { 40 | } 41 | 42 | /////////////////////////////////////////////////////////////////////////// 43 | // ptree_bad_data 44 | 45 | template inline 46 | ptree_bad_data::ptree_bad_data(const std::string &w, const D &d): 47 | ptree_error(w), m_data(d) 48 | { 49 | } 50 | 51 | template inline 52 | D ptree_bad_data::data() const 53 | { 54 | return boost::any_cast(m_data); 55 | } 56 | 57 | /////////////////////////////////////////////////////////////////////////// 58 | // ptree_bad_path 59 | 60 | template inline 61 | ptree_bad_path::ptree_bad_path(const std::string &w, const P &p): 62 | ptree_error(detail::prepare_bad_path_what(w, p)), m_path(p) 63 | { 64 | 65 | } 66 | 67 | template inline 68 | P ptree_bad_path::path() const 69 | { 70 | return boost::any_cast

(m_path); 71 | } 72 | 73 | }} 74 | 75 | #endif 76 | -------------------------------------------------------------------------------- /include/boost/property_tree/detail/file_parser_error.hpp: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------------- 2 | // Copyright (C) 2002-2006 Marcin Kalicinski 3 | // 4 | // Distributed under the Boost Software License, Version 1.0. 5 | // (See accompanying file LICENSE_1_0.txt or copy at 6 | // http://www.boost.org/LICENSE_1_0.txt) 7 | // 8 | // For more information, see www.boost.org 9 | // ---------------------------------------------------------------------------- 10 | #ifndef BOOST_PROPERTY_TREE_DETAIL_FILE_PARSER_ERROR_HPP_INCLUDED 11 | #define BOOST_PROPERTY_TREE_DETAIL_FILE_PARSER_ERROR_HPP_INCLUDED 12 | 13 | #include 14 | #include 15 | #include 16 | 17 | namespace boost { namespace property_tree 18 | { 19 | 20 | //! File parse error 21 | class file_parser_error: public ptree_error 22 | { 23 | 24 | public: 25 | 26 | /////////////////////////////////////////////////////////////////////// 27 | // Construction 28 | 29 | // Construct error 30 | file_parser_error(const std::string &msg, 31 | const std::string &file, 32 | unsigned long l) : 33 | ptree_error(format_what(msg, file, l)), 34 | m_message(msg), m_filename(file), m_line(l) 35 | { 36 | } 37 | 38 | /////////////////////////////////////////////////////////////////////// 39 | // Data access 40 | 41 | // Get error message (without line and file - use what() to get 42 | // full message) 43 | std::string message() const 44 | { 45 | return m_message; 46 | } 47 | 48 | // Get error filename 49 | std::string filename() const 50 | { 51 | return m_filename; 52 | } 53 | 54 | // Get error line number 55 | unsigned long line() const 56 | { 57 | return m_line; 58 | } 59 | 60 | private: 61 | 62 | std::string m_message; 63 | std::string m_filename; 64 | unsigned long m_line; 65 | 66 | // Format error message to be returned by std::runtime_error::what() 67 | static std::string format_what(const std::string &msg, 68 | const std::string &file, 69 | unsigned long l) 70 | { 71 | std::stringstream stream; 72 | stream << (file.empty() ? "" : file.c_str()); 73 | if (l > 0) 74 | stream << '(' << l << ')'; 75 | stream << ": " << msg; 76 | return stream.str(); 77 | } 78 | 79 | }; 80 | 81 | } } 82 | 83 | #endif 84 | -------------------------------------------------------------------------------- /include/boost/property_tree/detail/info_parser_error.hpp: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------------- 2 | // Copyright (C) 2002-2006 Marcin Kalicinski 3 | // 4 | // Distributed under the Boost Software License, Version 1.0. 5 | // (See accompanying file LICENSE_1_0.txt or copy at 6 | // http://www.boost.org/LICENSE_1_0.txt) 7 | // 8 | // For more information, see www.boost.org 9 | // ---------------------------------------------------------------------------- 10 | #ifndef BOOST_PROPERTY_TREE_DETAIL_INFO_PARSER_ERROR_HPP_INCLUDED 11 | #define BOOST_PROPERTY_TREE_DETAIL_INFO_PARSER_ERROR_HPP_INCLUDED 12 | 13 | #include 14 | #include 15 | 16 | namespace boost { namespace property_tree { namespace info_parser 17 | { 18 | 19 | class info_parser_error: public file_parser_error 20 | { 21 | public: 22 | info_parser_error(const std::string &message, 23 | const std::string &filename, 24 | unsigned long line) : 25 | file_parser_error(message, filename, line) 26 | { 27 | } 28 | }; 29 | 30 | } } } 31 | 32 | #endif 33 | -------------------------------------------------------------------------------- /include/boost/property_tree/detail/info_parser_utils.hpp: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------------- 2 | // Copyright (C) 2002-2006 Marcin Kalicinski 3 | // 4 | // Distributed under the Boost Software License, Version 1.0. 5 | // (See accompanying file LICENSE_1_0.txt or copy at 6 | // http://www.boost.org/LICENSE_1_0.txt) 7 | // 8 | // For more information, see www.boost.org 9 | // ---------------------------------------------------------------------------- 10 | #ifndef BOOST_PROPERTY_TREE_DETAIL_INFO_PARSER_CHCONV_HPP_INCLUDED 11 | #define BOOST_PROPERTY_TREE_DETAIL_INFO_PARSER_CHCONV_HPP_INCLUDED 12 | 13 | #include 14 | 15 | namespace boost { namespace property_tree { namespace info_parser 16 | { 17 | 18 | template 19 | std::basic_string convert_chtype(const ChSrc *text) 20 | { 21 | std::basic_string result; 22 | while (*text) 23 | { 24 | result += ChDest(*text); 25 | ++text; 26 | } 27 | return result; 28 | } 29 | 30 | } } } 31 | 32 | #endif 33 | -------------------------------------------------------------------------------- /include/boost/property_tree/detail/info_parser_write.hpp: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------------- 2 | // Copyright (C) 2002-2006 Marcin Kalicinski 3 | // 4 | // Distributed under the Boost Software License, Version 1.0. 5 | // (See accompanying file LICENSE_1_0.txt or copy at 6 | // http://www.boost.org/LICENSE_1_0.txt) 7 | // 8 | // For more information, see www.boost.org 9 | // ---------------------------------------------------------------------------- 10 | #ifndef BOOST_PROPERTY_TREE_DETAIL_INFO_PARSER_WRITE_HPP_INCLUDED 11 | #define BOOST_PROPERTY_TREE_DETAIL_INFO_PARSER_WRITE_HPP_INCLUDED 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | #include 19 | 20 | namespace boost { namespace property_tree { namespace info_parser 21 | { 22 | template 23 | void write_info_indent(std::basic_ostream &stream, 24 | int indent, 25 | const info_writer_settings &settings 26 | ) 27 | { 28 | stream << std::basic_string(indent * settings.indent_count, settings.indent_char); 29 | } 30 | 31 | // Create necessary escape sequences from illegal characters 32 | template 33 | std::basic_string create_escapes(const std::basic_string &s) 34 | { 35 | std::basic_string result; 36 | typename std::basic_string::const_iterator b = s.begin(); 37 | typename std::basic_string::const_iterator e = s.end(); 38 | while (b != e) 39 | { 40 | if (*b == Ch('\0')) result += Ch('\\'), result += Ch('0'); 41 | else if (*b == Ch('\a')) result += Ch('\\'), result += Ch('a'); 42 | else if (*b == Ch('\b')) result += Ch('\\'), result += Ch('b'); 43 | else if (*b == Ch('\f')) result += Ch('\\'), result += Ch('f'); 44 | else if (*b == Ch('\n')) result += Ch('\\'), result += Ch('n'); 45 | else if (*b == Ch('\r')) result += Ch('\\'), result += Ch('r'); 46 | else if (*b == Ch('\v')) result += Ch('\\'), result += Ch('v'); 47 | else if (*b == Ch('"')) result += Ch('\\'), result += Ch('"'); 48 | else if (*b == Ch('\\')) result += Ch('\\'), result += Ch('\\'); 49 | else 50 | result += *b; 51 | ++b; 52 | } 53 | return result; 54 | } 55 | 56 | template 57 | bool is_simple_key(const std::basic_string &key) 58 | { 59 | const static std::basic_string chars = convert_chtype(" \t{};\n\""); 60 | return !key.empty() && key.find_first_of(chars) == key.npos; 61 | } 62 | 63 | template 64 | bool is_simple_data(const std::basic_string &data) 65 | { 66 | const static std::basic_string chars = convert_chtype(" \t{};\n\""); 67 | return !data.empty() && data.find_first_of(chars) == data.npos; 68 | } 69 | 70 | template 71 | void write_info_helper(std::basic_ostream &stream, 72 | const Ptree &pt, 73 | int indent, 74 | const info_writer_settings &settings) 75 | { 76 | 77 | // Character type 78 | typedef typename Ptree::key_type::value_type Ch; 79 | 80 | // Write data 81 | if (indent >= 0) 82 | { 83 | if (!pt.data().empty()) 84 | { 85 | std::basic_string data = create_escapes(pt.template get_value >()); 86 | if (is_simple_data(data)) 87 | stream << Ch(' ') << data << Ch('\n'); 88 | else 89 | stream << Ch(' ') << Ch('\"') << data << Ch('\"') << Ch('\n'); 90 | } 91 | else if (pt.empty()) 92 | stream << Ch(' ') << Ch('\"') << Ch('\"') << Ch('\n'); 93 | else 94 | stream << Ch('\n'); 95 | } 96 | 97 | // Write keys 98 | if (!pt.empty()) 99 | { 100 | 101 | // Open brace 102 | if (indent >= 0) 103 | { 104 | write_info_indent( stream, indent, settings); 105 | stream << Ch('{') << Ch('\n'); 106 | } 107 | 108 | // Write keys 109 | typename Ptree::const_iterator it = pt.begin(); 110 | for (; it != pt.end(); ++it) 111 | { 112 | 113 | // Output key 114 | std::basic_string key = create_escapes(it->first); 115 | write_info_indent( stream, indent+1, settings); 116 | if (is_simple_key(key)) 117 | stream << key; 118 | else 119 | stream << Ch('\"') << key << Ch('\"'); 120 | 121 | // Output data and children 122 | write_info_helper(stream, it->second, indent + 1, settings); 123 | 124 | } 125 | 126 | // Close brace 127 | if (indent >= 0) 128 | { 129 | write_info_indent( stream, indent, settings); 130 | stream << Ch('}') << Ch('\n'); 131 | } 132 | 133 | } 134 | } 135 | 136 | // Write ptree to info stream 137 | template 138 | void write_info_internal(std::basic_ostream &stream, 139 | const Ptree &pt, 140 | const std::string &filename, 141 | const info_writer_settings &settings) 142 | { 143 | write_info_helper(stream, pt, -1, settings); 144 | stream.flush(); 145 | if (!stream.good()) 146 | BOOST_PROPERTY_TREE_THROW(info_parser_error("write error", filename, 0)); 147 | } 148 | 149 | } } } 150 | 151 | #endif 152 | -------------------------------------------------------------------------------- /include/boost/property_tree/detail/info_parser_writer_settings.hpp: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------------- 2 | // Copyright (C) 2002-2006 Marcin Kalicinski 3 | // Copyright (C) 2007 Alexey Baskakov 4 | // 5 | // Distributed under the Boost Software License, Version 1.0. 6 | // (See accompanying file LICENSE_1_0.txt or copy at 7 | // http://www.boost.org/LICENSE_1_0.txt) 8 | // 9 | // For more information, see www.boost.org 10 | // ---------------------------------------------------------------------------- 11 | #ifndef BOOST_PROPERTY_TREE_DETAIL_INFO_PARSER_WRITER_SETTINGS_HPP_INCLUDED 12 | #define BOOST_PROPERTY_TREE_DETAIL_INFO_PARSER_WRITER_SETTINGS_HPP_INCLUDED 13 | 14 | #include 15 | 16 | namespace boost { namespace property_tree { namespace info_parser 17 | { 18 | 19 | template 20 | class info_writer_settings 21 | { 22 | public: 23 | info_writer_settings(Ch indent_char = Ch(' '), unsigned indent_count = 4): 24 | indent_char(indent_char), 25 | indent_count(indent_count) 26 | { 27 | } 28 | Ch indent_char; 29 | int indent_count; 30 | }; 31 | 32 | template 33 | info_writer_settings info_writer_make_settings(Ch indent_char = Ch(' '), unsigned indent_count = 4) 34 | { 35 | return info_writer_settings(indent_char, indent_count); 36 | } 37 | 38 | } } } 39 | 40 | #endif 41 | -------------------------------------------------------------------------------- /include/boost/property_tree/detail/ptree_utils.hpp: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------------- 2 | // Copyright (C) 2002-2006 Marcin Kalicinski 3 | // 4 | // Distributed under the Boost Software License, Version 1.0. 5 | // (See accompanying file LICENSE_1_0.txt or copy at 6 | // http://www.boost.org/LICENSE_1_0.txt) 7 | // 8 | // For more information, see www.boost.org 9 | // ---------------------------------------------------------------------------- 10 | #ifndef BOOST_PROPERTY_TREE_DETAIL_PTREE_UTILS_HPP_INCLUDED 11 | #define BOOST_PROPERTY_TREE_DETAIL_PTREE_UTILS_HPP_INCLUDED 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | 21 | namespace boost { namespace property_tree { namespace detail 22 | { 23 | 24 | template 25 | struct less_nocase 26 | { 27 | typedef typename T::value_type Ch; 28 | std::locale m_locale; 29 | inline bool operator()(Ch c1, Ch c2) const 30 | { 31 | return std::toupper(c1, m_locale) < std::toupper(c2, m_locale); 32 | } 33 | inline bool operator()(const T &t1, const T &t2) const 34 | { 35 | return std::lexicographical_compare(t1.begin(), t1.end(), 36 | t2.begin(), t2.end(), *this); 37 | } 38 | }; 39 | 40 | template 41 | struct is_character : public boost::false_type {}; 42 | template <> 43 | struct is_character : public boost::true_type {}; 44 | template <> 45 | struct is_character : public boost::true_type {}; 46 | 47 | 48 | BOOST_MPL_HAS_XXX_TRAIT_DEF(internal_type) 49 | BOOST_MPL_HAS_XXX_TRAIT_DEF(external_type) 50 | template 51 | struct is_translator : public boost::mpl::and_< 52 | has_internal_type, has_external_type > {}; 53 | 54 | 55 | 56 | // Naively convert narrow string to another character type 57 | template 58 | Str widen(const char *text) 59 | { 60 | Str result; 61 | while (*text) 62 | { 63 | result += typename Str::value_type(*text); 64 | ++text; 65 | } 66 | return result; 67 | } 68 | 69 | // Naively convert string to narrow character type 70 | template 71 | Str narrow(const char_type *text) 72 | { 73 | Str result; 74 | while (*text) 75 | { 76 | if (*text < 0 || *text > static_cast((std::numeric_limits::max)())) 77 | result += '*'; 78 | else 79 | result += typename Str::value_type(*text); 80 | ++text; 81 | } 82 | return result; 83 | } 84 | 85 | // Remove trailing and leading spaces 86 | template 87 | Str trim(const Str &s, const std::locale &loc = std::locale()) 88 | { 89 | typename Str::const_iterator first = s.begin(); 90 | typename Str::const_iterator end = s.end(); 91 | while (first != end && std::isspace(*first, loc)) 92 | ++first; 93 | if (first == end) 94 | return Str(); 95 | typename Str::const_iterator last = end; 96 | do --last; while (std::isspace(*last, loc)); 97 | if (first != s.begin() || last + 1 != end) 98 | return Str(first, last + 1); 99 | else 100 | return s; 101 | } 102 | 103 | } } } 104 | 105 | #endif 106 | -------------------------------------------------------------------------------- /include/boost/property_tree/detail/xml_parser_error.hpp: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------------- 2 | // Copyright (C) 2002-2006 Marcin Kalicinski 3 | // 4 | // Distributed under the Boost Software License, Version 1.0. 5 | // (See accompanying file LICENSE_1_0.txt or copy at 6 | // http://www.boost.org/LICENSE_1_0.txt) 7 | // 8 | // For more information, see www.boost.org 9 | // ---------------------------------------------------------------------------- 10 | #ifndef BOOST_PROPERTY_TREE_DETAIL_XML_PARSER_ERROR_HPP_INCLUDED 11 | #define BOOST_PROPERTY_TREE_DETAIL_XML_PARSER_ERROR_HPP_INCLUDED 12 | 13 | #include 14 | #include 15 | 16 | namespace boost { namespace property_tree { namespace xml_parser 17 | { 18 | 19 | //! Xml parser error 20 | class xml_parser_error: public file_parser_error 21 | { 22 | public: 23 | xml_parser_error(const std::string &msg, 24 | const std::string &file, 25 | unsigned long l): 26 | file_parser_error(msg, file, l) 27 | { 28 | } 29 | }; 30 | 31 | } } } 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /include/boost/property_tree/detail/xml_parser_flags.hpp: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------------- 2 | // Copyright (C) 2002-2006 Marcin Kalicinski 3 | // 4 | // Distributed under the Boost Software License, Version 1.0. 5 | // (See accompanying file LICENSE_1_0.txt or copy at 6 | // http://www.boost.org/LICENSE_1_0.txt) 7 | // 8 | // For more information, see www.boost.org 9 | // ---------------------------------------------------------------------------- 10 | #ifndef BOOST_PROPERTY_TREE_DETAIL_XML_PARSER_FLAGS_HPP_INCLUDED 11 | #define BOOST_PROPERTY_TREE_DETAIL_XML_PARSER_FLAGS_HPP_INCLUDED 12 | 13 | namespace boost { namespace property_tree { namespace xml_parser 14 | { 15 | 16 | /// Text elements should be put in separate keys, 17 | /// not concatenated in parent data. 18 | static const int no_concat_text = 0x1; 19 | /// Comments should be omitted. 20 | static const int no_comments = 0x2; 21 | /// Whitespace should be collapsed and trimmed. 22 | static const int trim_whitespace = 0x4; 23 | 24 | inline bool validate_flags(int flags) 25 | { 26 | return (flags & ~(no_concat_text | no_comments | trim_whitespace)) == 0; 27 | } 28 | 29 | } } } 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /include/boost/property_tree/detail/xml_parser_read_rapidxml.hpp: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------------- 2 | // Copyright (C) 2007 Marcin Kalicinski 3 | // 4 | // Distributed under the Boost Software License, Version 1.0. 5 | // (See accompanying file LICENSE_1_0.txt or copy at 6 | // http://www.boost.org/LICENSE_1_0.txt) 7 | // 8 | // For more information, see www.boost.org 9 | // ---------------------------------------------------------------------------- 10 | #ifndef BOOST_PROPERTY_TREE_DETAIL_XML_PARSER_READ_RAPIDXML_HPP_INCLUDED 11 | #define BOOST_PROPERTY_TREE_DETAIL_XML_PARSER_READ_RAPIDXML_HPP_INCLUDED 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | namespace boost { namespace property_tree { namespace xml_parser 21 | { 22 | 23 | template 24 | void read_xml_node(detail::rapidxml::xml_node *node, 25 | Ptree &pt, int flags) 26 | { 27 | using namespace detail::rapidxml; 28 | switch (node->type()) 29 | { 30 | // Element nodes 31 | case node_element: 32 | { 33 | // Create node 34 | Ptree &pt_node = pt.push_back(std::make_pair(node->name(), 35 | Ptree()))->second; 36 | 37 | // Copy attributes 38 | if (node->first_attribute()) 39 | { 40 | Ptree &pt_attr_root = pt_node.push_back( 41 | std::make_pair(xmlattr(), Ptree()))->second; 42 | for (xml_attribute *attr = node->first_attribute(); 43 | attr; attr = attr->next_attribute()) 44 | { 45 | Ptree &pt_attr = pt_attr_root.push_back( 46 | std::make_pair(attr->name(), Ptree()))->second; 47 | pt_attr.data() = typename Ptree::key_type(attr->value(), attr->value_size()); 48 | } 49 | } 50 | 51 | // Copy children 52 | for (xml_node *child = node->first_node(); 53 | child; child = child->next_sibling()) 54 | read_xml_node(child, pt_node, flags); 55 | } 56 | break; 57 | 58 | // Data nodes 59 | case node_data: 60 | case node_cdata: 61 | { 62 | if (flags & no_concat_text) 63 | pt.push_back(std::make_pair(xmltext(), 64 | Ptree(node->value()))); 65 | else 66 | pt.data() += typename Ptree::key_type(node->value(), node->value_size()); 67 | } 68 | break; 69 | 70 | // Comment nodes 71 | case node_comment: 72 | { 73 | if (!(flags & no_comments)) 74 | pt.push_back(std::make_pair(xmlcomment(), 75 | Ptree(typename Ptree::key_type(node->value(), node->value_size())))); 76 | } 77 | break; 78 | 79 | default: 80 | // Skip other node types 81 | break; 82 | } 83 | } 84 | 85 | template 86 | void read_xml_internal(std::basic_istream< 87 | typename Ptree::key_type::value_type> &stream, 88 | Ptree &pt, 89 | int flags, 90 | const std::string &filename) 91 | { 92 | typedef typename Ptree::key_type::value_type Ch; 93 | using namespace detail::rapidxml; 94 | 95 | // Load data into vector 96 | stream.unsetf(std::ios::skipws); 97 | std::vector v(std::istreambuf_iterator(stream.rdbuf()), 98 | std::istreambuf_iterator()); 99 | if (!stream.good()) 100 | BOOST_PROPERTY_TREE_THROW( 101 | xml_parser_error("read error", filename, 0)); 102 | v.push_back(0); // zero-terminate 103 | 104 | try { 105 | // Parse using appropriate flags 106 | const int f_tws = parse_normalize_whitespace 107 | | parse_trim_whitespace; 108 | const int f_c = parse_comment_nodes; 109 | // Some compilers don't like the bitwise or in the template arg. 110 | const int f_tws_c = parse_normalize_whitespace 111 | | parse_trim_whitespace 112 | | parse_comment_nodes; 113 | xml_document doc; 114 | if (flags & no_comments) { 115 | if (flags & trim_whitespace) 116 | doc.BOOST_NESTED_TEMPLATE parse(&v.front()); 117 | else 118 | doc.BOOST_NESTED_TEMPLATE parse<0>(&v.front()); 119 | } else { 120 | if (flags & trim_whitespace) 121 | doc.BOOST_NESTED_TEMPLATE parse(&v.front()); 122 | else 123 | doc.BOOST_NESTED_TEMPLATE parse(&v.front()); 124 | } 125 | 126 | // Create ptree from nodes 127 | Ptree local; 128 | for (xml_node *child = doc.first_node(); 129 | child; child = child->next_sibling()) 130 | read_xml_node(child, local, flags); 131 | 132 | // Swap local and result ptrees 133 | pt.swap(local); 134 | } catch (parse_error &e) { 135 | long line = static_cast( 136 | std::count(&v.front(), e.where(), Ch('\n')) + 1); 137 | BOOST_PROPERTY_TREE_THROW( 138 | xml_parser_error(e.what(), filename, line)); 139 | } 140 | } 141 | 142 | } } } 143 | 144 | #endif 145 | -------------------------------------------------------------------------------- /include/boost/property_tree/detail/xml_parser_utils.hpp: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------------- 2 | // Copyright (C) 2002-2006 Marcin Kalicinski 3 | // 4 | // Distributed under the Boost Software License, Version 1.0. 5 | // (See accompanying file LICENSE_1_0.txt or copy at 6 | // http://www.boost.org/LICENSE_1_0.txt) 7 | // 8 | // For more information, see www.boost.org 9 | // ---------------------------------------------------------------------------- 10 | #ifndef BOOST_PROPERTY_TREE_DETAIL_XML_PARSER_UTILS_HPP_INCLUDED 11 | #define BOOST_PROPERTY_TREE_DETAIL_XML_PARSER_UTILS_HPP_INCLUDED 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | namespace boost { namespace property_tree { namespace xml_parser 21 | { 22 | 23 | template 24 | Str condense(const Str &s) 25 | { 26 | typedef typename Str::value_type Ch; 27 | Str r; 28 | std::locale loc; 29 | bool space = false; 30 | typename Str::const_iterator end = s.end(); 31 | for (typename Str::const_iterator it = s.begin(); 32 | it != end; ++it) 33 | { 34 | if (isspace(*it, loc) || *it == Ch('\n')) 35 | { 36 | if (!space) 37 | r += Ch(' '), space = true; 38 | } 39 | else 40 | r += *it, space = false; 41 | } 42 | return r; 43 | } 44 | 45 | 46 | template 47 | Str encode_char_entities(const Str &s) 48 | { 49 | // Don't do anything for empty strings. 50 | if(s.empty()) return s; 51 | 52 | typedef typename Str::value_type Ch; 53 | 54 | Str r; 55 | // To properly round-trip spaces and not uglify the XML beyond 56 | // recognition, we have to encode them IF the text contains only spaces. 57 | Str sp(1, Ch(' ')); 58 | if(s.find_first_not_of(sp) == Str::npos) { 59 | // The first will suffice. 60 | r = detail::widen(" "); 61 | r += Str(s.size() - 1, Ch(' ')); 62 | } else { 63 | typename Str::const_iterator end = s.end(); 64 | for (typename Str::const_iterator it = s.begin(); it != end; ++it) 65 | { 66 | switch (*it) 67 | { 68 | case Ch('<'): r += detail::widen("<"); break; 69 | case Ch('>'): r += detail::widen(">"); break; 70 | case Ch('&'): r += detail::widen("&"); break; 71 | case Ch('"'): r += detail::widen("""); break; 72 | case Ch('\''): r += detail::widen("'"); break; 73 | default: r += *it; break; 74 | } 75 | } 76 | } 77 | return r; 78 | } 79 | 80 | template 81 | Str decode_char_entities(const Str &s) 82 | { 83 | typedef typename Str::value_type Ch; 84 | Str r; 85 | typename Str::const_iterator end = s.end(); 86 | for (typename Str::const_iterator it = s.begin(); it != end; ++it) 87 | { 88 | if (*it == Ch('&')) 89 | { 90 | typename Str::const_iterator semicolon = std::find(it + 1, end, Ch(';')); 91 | if (semicolon == end) 92 | BOOST_PROPERTY_TREE_THROW(xml_parser_error("invalid character entity", "", 0)); 93 | Str ent(it + 1, semicolon); 94 | if (ent == detail::widen("lt")) r += Ch('<'); 95 | else if (ent == detail::widen("gt")) r += Ch('>'); 96 | else if (ent == detail::widen("amp")) r += Ch('&'); 97 | else if (ent == detail::widen("quot")) r += Ch('"'); 98 | else if (ent == detail::widen("apos")) r += Ch('\''); 99 | else 100 | BOOST_PROPERTY_TREE_THROW(xml_parser_error("invalid character entity", "", 0)); 101 | it = semicolon; 102 | } 103 | else 104 | r += *it; 105 | } 106 | return r; 107 | } 108 | 109 | template 110 | const Str &xmldecl() 111 | { 112 | static Str s = detail::widen(""); 113 | return s; 114 | } 115 | 116 | template 117 | const Str &xmlattr() 118 | { 119 | static Str s = detail::widen(""); 120 | return s; 121 | } 122 | 123 | template 124 | const Str &xmlcomment() 125 | { 126 | static Str s = detail::widen(""); 127 | return s; 128 | } 129 | 130 | template 131 | const Str &xmltext() 132 | { 133 | static Str s = detail::widen(""); 134 | return s; 135 | } 136 | 137 | } } } 138 | 139 | #endif 140 | -------------------------------------------------------------------------------- /include/boost/property_tree/detail/xml_parser_writer_settings.hpp: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------------- 2 | // Copyright (C) 2002-2007 Marcin Kalicinski 3 | // Copyright (C) 2007 Alexey Baskakov 4 | // 5 | // Distributed under the Boost Software License, Version 1.0. 6 | // (See accompanying file LICENSE_1_0.txt or copy at 7 | // http://www.boost.org/LICENSE_1_0.txt) 8 | // 9 | // For more information, see www.boost.org 10 | // ---------------------------------------------------------------------------- 11 | #ifndef BOOST_PROPERTY_TREE_DETAIL_XML_PARSER_WRITER_SETTINGS_HPP_INCLUDED 12 | #define BOOST_PROPERTY_TREE_DETAIL_XML_PARSER_WRITER_SETTINGS_HPP_INCLUDED 13 | 14 | #include 15 | #include 16 | 17 | namespace boost { namespace property_tree { namespace xml_parser 18 | { 19 | 20 | // Naively convert narrow string to another character type 21 | template 22 | Str widen(const char *text) 23 | { 24 | typedef typename Str::value_type Ch; 25 | Str result; 26 | while (*text) 27 | { 28 | result += Ch(*text); 29 | ++text; 30 | } 31 | return result; 32 | } 33 | 34 | //! Xml writer settings. The default settings lead to no pretty printing. 35 | template 36 | class xml_writer_settings 37 | { 38 | typedef typename Str::value_type Ch; 39 | public: 40 | xml_writer_settings(Ch inchar = Ch(' '), 41 | typename Str::size_type incount = 0, 42 | const Str &enc = widen("utf-8")) 43 | : indent_char(inchar) 44 | , indent_count(incount) 45 | , encoding(enc) 46 | { 47 | } 48 | 49 | Ch indent_char; 50 | typename Str::size_type indent_count; 51 | Str encoding; 52 | }; 53 | 54 | template 55 | xml_writer_settings xml_writer_make_settings(typename Str::value_type indent_char = (typename Str::value_type)(' '), 56 | typename Str::size_type indent_count = 0, 57 | const Str &encoding = widen("utf-8")) 58 | { 59 | return xml_writer_settings(indent_char, indent_count, encoding); 60 | } 61 | 62 | } } } 63 | 64 | #endif 65 | -------------------------------------------------------------------------------- /include/boost/property_tree/exceptions.hpp: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------------- 2 | // Copyright (C) 2002-2006 Marcin Kalicinski 3 | // Copyright (C) 2009 Sebastian Redl 4 | // 5 | // Distributed under the Boost Software License, Version 1.0. 6 | // (See accompanying file LICENSE_1_0.txt or copy at 7 | // http://www.boost.org/LICENSE_1_0.txt) 8 | // 9 | // For more information, see www.boost.org 10 | // ---------------------------------------------------------------------------- 11 | 12 | #ifndef BOOST_PROPERTY_TREE_EXCEPTIONS_HPP_INCLUDED 13 | #define BOOST_PROPERTY_TREE_EXCEPTIONS_HPP_INCLUDED 14 | 15 | #include 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | namespace boost { namespace property_tree 22 | { 23 | 24 | /// Base class for all property tree errors. Derives from 25 | /// @c std::runtime_error. Call member function @c what to get human 26 | /// readable message associated with the error. 27 | class ptree_error : public std::runtime_error 28 | { 29 | public: 30 | /// Instantiate a ptree_error instance with the given message. 31 | /// @param what The message to associate with this error. 32 | ptree_error(const std::string &what); 33 | }; 34 | 35 | 36 | /// Error indicating that translation from given value to the property tree 37 | /// data_type (or vice versa) failed. Derives from ptree_error. 38 | class ptree_bad_data : public ptree_error 39 | { 40 | public: 41 | /// Instantiate a ptree_bad_data instance with the given message and 42 | /// data. 43 | /// @param what The message to associate with this error. 44 | /// @param data The value associated with this error that was the source 45 | /// of the translation failure. 46 | template ptree_bad_data(const std::string &what, 47 | const T &data); 48 | 49 | /// Retrieve the data associated with this error. This is the source 50 | /// value that failed to be translated. You need to explicitly 51 | /// specify its type. 52 | template T data() const; 53 | private: 54 | boost::any m_data; 55 | }; 56 | 57 | 58 | /// Error indicating that specified path does not exist. Derives from 59 | /// ptree_error. 60 | class ptree_bad_path : public ptree_error 61 | { 62 | public: 63 | /// Instantiate a ptree_bad_path with the given message and path data. 64 | /// @param what The message to associate with this error. 65 | /// @param path The path that could not be found in the property_tree. 66 | template ptree_bad_path(const std::string &what, 67 | const T &path); 68 | 69 | /// Retrieve the invalid path. You need to explicitly specify the 70 | /// type of path. 71 | template T path() const; 72 | private: 73 | boost::any m_path; 74 | }; 75 | 76 | }} 77 | 78 | #include 79 | 80 | #endif 81 | -------------------------------------------------------------------------------- /include/boost/property_tree/id_translator.hpp: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------------- 2 | // Copyright (C) 2009 Sebastian Redl 3 | // 4 | // Distributed under the Boost Software License, Version 1.0. 5 | // (See accompanying file LICENSE_1_0.txt or copy at 6 | // http://www.boost.org/LICENSE_1_0.txt) 7 | // 8 | // For more information, see www.boost.org 9 | // ---------------------------------------------------------------------------- 10 | 11 | #ifndef BOOST_PROPERTY_TREE_ID_TRANSLATOR_HPP_INCLUDED 12 | #define BOOST_PROPERTY_TREE_ID_TRANSLATOR_HPP_INCLUDED 13 | 14 | #include 15 | 16 | #include 17 | #include 18 | 19 | namespace boost { namespace property_tree 20 | { 21 | 22 | /// Simple implementation of the Translator concept. It does no translation. 23 | template 24 | struct id_translator 25 | { 26 | typedef T internal_type; 27 | typedef T external_type; 28 | 29 | boost::optional get_value(const T &v) { return v; } 30 | boost::optional put_value(const T &v) { return v; } 31 | }; 32 | 33 | // This is the default translator whenever you get two equal types. 34 | template 35 | struct translator_between 36 | { 37 | typedef id_translator type; 38 | }; 39 | 40 | // A more specific specialization for std::basic_string. Otherwise, 41 | // stream_translator's specialization wins. 42 | template 43 | struct translator_between< std::basic_string, 44 | std::basic_string > 45 | { 46 | typedef id_translator< std::basic_string > type; 47 | }; 48 | 49 | }} 50 | 51 | #endif 52 | -------------------------------------------------------------------------------- /include/boost/property_tree/info_parser.hpp: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------------- 2 | // Copyright (C) 2002-2006 Marcin Kalicinski 3 | // 4 | // Distributed under the Boost Software License, Version 1.0. 5 | // (See accompanying file LICENSE_1_0.txt or copy at 6 | // http://www.boost.org/LICENSE_1_0.txt) 7 | // 8 | // For more information, see www.boost.org 9 | // ---------------------------------------------------------------------------- 10 | #ifndef BOOST_PROPERTY_TREE_INFO_PARSER_HPP_INCLUDED 11 | #define BOOST_PROPERTY_TREE_INFO_PARSER_HPP_INCLUDED 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | namespace boost { namespace property_tree { namespace info_parser 21 | { 22 | 23 | /** 24 | * Read INFO from a the given stream and translate it to a property tree. 25 | * @note Replaces the existing contents. Strong exception guarantee. 26 | * @throw info_parser_error If the stream cannot be read, doesn't contain 27 | * valid INFO, or a conversion fails. 28 | */ 29 | template 30 | void read_info(std::basic_istream &stream, Ptree &pt) 31 | { 32 | Ptree local; 33 | read_info_internal(stream, local, std::string(), 0); 34 | pt.swap(local); 35 | } 36 | 37 | /** 38 | * Read INFO from a the given stream and translate it to a property tree. 39 | * @note Replaces the existing contents. Strong exception guarantee. 40 | * @param default_ptree If parsing fails, pt is set to a copy of this tree. 41 | */ 42 | template 43 | void read_info(std::basic_istream &stream, Ptree &pt, 44 | const Ptree &default_ptree) 45 | { 46 | try { 47 | read_info(stream, pt); 48 | } catch(file_parser_error &) { 49 | pt = default_ptree; 50 | } 51 | } 52 | 53 | /** 54 | * Read INFO from a the given file and translate it to a property tree. The 55 | * tree's key type must be a string type, i.e. it must have a nested 56 | * value_type typedef that is a valid parameter for basic_ifstream. 57 | * @note Replaces the existing contents. Strong exception guarantee. 58 | * @throw info_parser_error If the file cannot be read, doesn't contain 59 | * valid INFO, or a conversion fails. 60 | */ 61 | template 62 | void read_info(const std::string &filename, Ptree &pt, 63 | const std::locale &loc = std::locale()) 64 | { 65 | std::basic_ifstream 66 | stream(filename.c_str()); 67 | if (!stream) { 68 | BOOST_PROPERTY_TREE_THROW(info_parser_error( 69 | "cannot open file for reading", filename, 0)); 70 | } 71 | stream.imbue(loc); 72 | Ptree local; 73 | read_info_internal(stream, local, filename, 0); 74 | pt.swap(local); 75 | } 76 | 77 | /** 78 | * Read INFO from a the given file and translate it to a property tree. The 79 | * tree's key type must be a string type, i.e. it must have a nested 80 | * value_type typedef that is a valid parameter for basic_ifstream. 81 | * @note Replaces the existing contents. Strong exception guarantee. 82 | * @param default_ptree If parsing fails, pt is set to a copy of this tree. 83 | */ 84 | template 85 | void read_info(const std::string &filename, 86 | Ptree &pt, 87 | const Ptree &default_ptree, 88 | const std::locale &loc = std::locale()) 89 | { 90 | try { 91 | read_info(filename, pt, loc); 92 | } catch(file_parser_error &) { 93 | pt = default_ptree; 94 | } 95 | } 96 | 97 | /** 98 | * Writes a tree to the stream in INFO format. 99 | * @throw info_parser_error If the stream cannot be written to, or a 100 | * conversion fails. 101 | * @param settings The settings to use when writing the INFO data. 102 | */ 103 | template 104 | void write_info(std::basic_ostream &stream, 105 | const Ptree &pt, 106 | const info_writer_settings &settings = 107 | info_writer_settings()) 108 | { 109 | write_info_internal(stream, pt, std::string(), settings); 110 | } 111 | 112 | /** 113 | * Writes a tree to the file in INFO format. The tree's key type must be a 114 | * string type, i.e. it must have a nested value_type typedef that is a 115 | * valid parameter for basic_ofstream. 116 | * @throw info_parser_error If the file cannot be written to, or a 117 | * conversion fails. 118 | * @param settings The settings to use when writing the INFO data. 119 | */ 120 | template 121 | void write_info(const std::string &filename, 122 | const Ptree &pt, 123 | const std::locale &loc = std::locale(), 124 | const info_writer_settings< 125 | typename Ptree::key_type::value_type 126 | > &settings = 127 | info_writer_make_settings< 128 | typename Ptree::key_type::value_type>()) 129 | { 130 | std::basic_ofstream 131 | stream(filename.c_str()); 132 | if (!stream) { 133 | BOOST_PROPERTY_TREE_THROW(info_parser_error( 134 | "cannot open file for writing", filename, 0)); 135 | } 136 | stream.imbue(loc); 137 | write_info_internal(stream, pt, filename, settings); 138 | } 139 | 140 | } } } 141 | 142 | namespace boost { namespace property_tree 143 | { 144 | using info_parser::info_parser_error; 145 | using info_parser::read_info; 146 | using info_parser::write_info; 147 | using info_parser::info_writer_settings; 148 | using info_parser::info_writer_make_settings; 149 | } } 150 | 151 | #endif 152 | -------------------------------------------------------------------------------- /include/boost/property_tree/json_parser.hpp: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------------- 2 | // Copyright (C) 2002-2006 Marcin Kalicinski 3 | // Copyright (C) 2015 Sebastian Redl 4 | // 5 | // Distributed under the Boost Software License, Version 1.0. 6 | // (See accompanying file LICENSE_1_0.txt or copy at 7 | // http://www.boost.org/LICENSE_1_0.txt) 8 | // 9 | // For more information, see www.boost.org 10 | // ---------------------------------------------------------------------------- 11 | #ifndef BOOST_PROPERTY_TREE_JSON_PARSER_HPP_INCLUDED 12 | #define BOOST_PROPERTY_TREE_JSON_PARSER_HPP_INCLUDED 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | #include 20 | #include 21 | #include 22 | 23 | namespace boost { namespace property_tree { namespace json_parser 24 | { 25 | 26 | /** 27 | * Read JSON from a the given stream and translate it to a property tree. 28 | * @note Clears existing contents of property tree. In case of error the 29 | * property tree unmodified. 30 | * @note Items of JSON arrays are translated into ptree keys with empty 31 | * names. Members of objects are translated into named keys. 32 | * @note JSON data can be a string, a numeric value, or one of literals 33 | * "null", "true" and "false". During parse, any of the above is 34 | * copied verbatim into ptree data string. 35 | * @throw json_parser_error In case of error deserializing the property 36 | * tree. 37 | * @param stream Stream from which to read in the property tree. 38 | * @param[out] pt The property tree to populate. 39 | */ 40 | template 41 | void read_json(std::basic_istream< 42 | typename Ptree::key_type::value_type 43 | > &stream, 44 | Ptree &pt) 45 | { 46 | detail::read_json_internal(stream, pt, std::string()); 47 | } 48 | 49 | /** 50 | * Read JSON from a the given file and translate it to a property tree. 51 | * @note Clears existing contents of property tree. In case of error the 52 | * property tree unmodified. 53 | * @note Items of JSON arrays are translated into ptree keys with empty 54 | * names. Members of objects are translated into named keys. 55 | * @note JSON data can be a string, a numeric value, or one of literals 56 | * "null", "true" and "false". During parse, any of the above is 57 | * copied verbatim into ptree data string. 58 | * @throw json_parser_error In case of error deserializing the property 59 | * tree. 60 | * @param filename Name of file from which to read in the property tree. 61 | * @param[out] pt The property tree to populate. 62 | * @param loc The locale to use when reading in the file contents. 63 | */ 64 | template 65 | void read_json(const std::string &filename, 66 | Ptree &pt, 67 | const std::locale &loc = std::locale()) 68 | { 69 | std::basic_ifstream 70 | stream(filename.c_str()); 71 | if (!stream) 72 | BOOST_PROPERTY_TREE_THROW(json_parser_error( 73 | "cannot open file", filename, 0)); 74 | stream.imbue(loc); 75 | detail::read_json_internal(stream, pt, filename); 76 | } 77 | 78 | /** 79 | * Translates the property tree to JSON and writes it the given output 80 | * stream. 81 | * @note Any property tree key containing only unnamed subkeys will be 82 | * rendered as JSON arrays. 83 | * @pre @e pt cannot contain keys that have both subkeys and non-empty data. 84 | * @throw json_parser_error In case of error translating the property tree 85 | * to JSON or writing to the output stream. 86 | * @param stream The stream to which to write the JSON representation of the 87 | * property tree. 88 | * @param pt The property tree to tranlsate to JSON and output. 89 | * @param pretty Whether to pretty-print. Defaults to true for backward 90 | * compatibility. 91 | */ 92 | template 93 | void write_json(std::basic_ostream< 94 | typename Ptree::key_type::value_type 95 | > &stream, 96 | const Ptree &pt, 97 | bool pretty = true) 98 | { 99 | write_json_internal(stream, pt, std::string(), pretty); 100 | } 101 | 102 | /** 103 | * Translates the property tree to JSON and writes it the given file. 104 | * @note Any property tree key containing only unnamed subkeys will be 105 | * rendered as JSON arrays. 106 | * @pre @e pt cannot contain keys that have both subkeys and non-empty data. 107 | * @throw json_parser_error In case of error translating the property tree 108 | * to JSON or writing to the file. 109 | * @param filename The name of the file to which to write the JSON 110 | * representation of the property tree. 111 | * @param pt The property tree to translate to JSON and output. 112 | * @param loc The locale to use when writing out to the output file. 113 | * @param pretty Whether to pretty-print. Defaults to true and last place 114 | * for backward compatibility. 115 | */ 116 | template 117 | void write_json(const std::string &filename, 118 | const Ptree &pt, 119 | const std::locale &loc = std::locale(), 120 | bool pretty = true) 121 | { 122 | std::basic_ofstream 123 | stream(filename.c_str()); 124 | if (!stream) 125 | BOOST_PROPERTY_TREE_THROW(json_parser_error( 126 | "cannot open file", filename, 0)); 127 | stream.imbue(loc); 128 | write_json_internal(stream, pt, filename, pretty); 129 | } 130 | 131 | } } } 132 | 133 | namespace boost { namespace property_tree 134 | { 135 | using json_parser::read_json; 136 | using json_parser::write_json; 137 | using json_parser::json_parser_error; 138 | } } 139 | 140 | #endif 141 | -------------------------------------------------------------------------------- /include/boost/property_tree/json_parser/detail/narrow_encoding.hpp: -------------------------------------------------------------------------------- 1 | #ifndef BOOST_PROPERTY_TREE_DETAIL_JSON_PARSER_NARROW_ENCODING_HPP 2 | #define BOOST_PROPERTY_TREE_DETAIL_JSON_PARSER_NARROW_ENCODING_HPP 3 | 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | namespace boost { namespace property_tree { 10 | namespace json_parser { namespace detail 11 | { 12 | 13 | struct external_ascii_superset_encoding 14 | { 15 | typedef char external_char; 16 | 17 | bool is_nl(char c) const { return c == '\n'; } 18 | bool is_ws(char c) const { 19 | return c == ' ' || c == '\t' || c == '\n' || c == '\r'; 20 | } 21 | 22 | bool is_minus(char c) const { return c == '-'; } 23 | bool is_plusminus(char c) const { return c == '+' || c == '-'; } 24 | bool is_dot(char c) const { return c == '.'; } 25 | bool is_eE(char c) const { return c == 'e' || c == 'E'; } 26 | bool is_0(char c) const { return c == '0'; } 27 | bool is_digit(char c) const { return c >= '0' && c <= '9'; } 28 | bool is_digit0(char c) const { return c >= '1' && c <= '9'; } 29 | 30 | bool is_quote(char c) const { return c == '"'; } 31 | bool is_backslash(char c) const { return c == '\\'; } 32 | bool is_slash(char c) const { return c == '/'; } 33 | 34 | bool is_comma(char c) const { return c == ','; } 35 | bool is_open_bracket(char c) const { return c == '['; } 36 | bool is_close_bracket(char c) const { return c == ']'; } 37 | bool is_colon(char c) const { return c == ':'; } 38 | bool is_open_brace(char c) const { return c == '{'; } 39 | bool is_close_brace(char c) const { return c == '}'; } 40 | 41 | bool is_a(char c) const { return c == 'a'; } 42 | bool is_b(char c) const { return c == 'b'; } 43 | bool is_e(char c) const { return c == 'e'; } 44 | bool is_f(char c) const { return c == 'f'; } 45 | bool is_l(char c) const { return c == 'l'; } 46 | bool is_n(char c) const { return c == 'n'; } 47 | bool is_r(char c) const { return c == 'r'; } 48 | bool is_s(char c) const { return c == 's'; } 49 | bool is_t(char c) const { return c == 't'; } 50 | bool is_u(char c) const { return c == 'u'; } 51 | 52 | int decode_hexdigit(char c) { 53 | if (c >= '0' && c <= '9') return c - '0'; 54 | if (c >= 'A' && c <= 'F') return c - 'A' + 10; 55 | if (c >= 'a' && c <= 'f') return c - 'a' + 10; 56 | return -1; 57 | } 58 | }; 59 | 60 | struct utf8_utf8_encoding : external_ascii_superset_encoding 61 | { 62 | typedef char internal_char; 63 | 64 | template 65 | boost::iterator_range 66 | to_internal(Iterator first, Iterator last) const { 67 | return boost::make_iterator_range(first, last); 68 | } 69 | 70 | char to_internal_trivial(char c) const { 71 | BOOST_ASSERT(static_cast(c) <= 0x7f); 72 | return c; 73 | } 74 | 75 | template 77 | void skip_codepoint(Iterator& cur, Sentinel end, 78 | EncodingErrorFn error_fn) const { 79 | transcode_codepoint(cur, end, DoNothing(), error_fn); 80 | } 81 | 82 | template 84 | void transcode_codepoint(Iterator& cur, Sentinel end, 85 | TranscodedFn transcoded_fn, EncodingErrorFn error_fn) const { 86 | unsigned char c = *cur; 87 | ++cur; 88 | if (c <= 0x7f) { 89 | // Solo byte, filter out disallowed codepoints. 90 | if (c < 0x20) { 91 | error_fn(); 92 | } 93 | transcoded_fn(c); 94 | return; 95 | } 96 | int trailing = trail_table(c); 97 | if (trailing == -1) { 98 | // Standalone trailing byte or overly long sequence. 99 | error_fn(); 100 | } 101 | transcoded_fn(c); 102 | for (int i = 0; i < trailing; ++i) { 103 | if (cur == end || !is_trail(*cur)) { 104 | error_fn(); 105 | } 106 | transcoded_fn(*cur); 107 | ++cur; 108 | } 109 | } 110 | 111 | template 112 | void feed_codepoint(unsigned codepoint, 113 | TranscodedFn transcoded_fn) const { 114 | if (codepoint <= 0x7f) { 115 | transcoded_fn(static_cast(codepoint)); 116 | } else if (codepoint <= 0x7ff) { 117 | transcoded_fn(static_cast(0xc0 | (codepoint >> 6))); 118 | transcoded_fn(trail(codepoint)); 119 | } else if (codepoint <= 0xffff) { 120 | transcoded_fn(static_cast(0xe0 | (codepoint >> 12))); 121 | transcoded_fn(trail(codepoint >> 6)); 122 | transcoded_fn(trail(codepoint)); 123 | } else if (codepoint <= 0x10ffff) { 124 | transcoded_fn(static_cast(0xf0 | (codepoint >> 18))); 125 | transcoded_fn(trail(codepoint >> 12)); 126 | transcoded_fn(trail(codepoint >> 6)); 127 | transcoded_fn(trail(codepoint)); 128 | } 129 | } 130 | 131 | template 132 | void skip_introduction(Iterator& cur, Sentinel end) const { 133 | if (cur != end && static_cast(*cur) == 0xef) { 134 | if (++cur == end) return; 135 | if (++cur == end) return; 136 | if (++cur == end) return; 137 | } 138 | } 139 | 140 | private: 141 | struct DoNothing { 142 | void operator ()(char) const {} 143 | }; 144 | 145 | bool is_trail(unsigned char c) const { 146 | return (c & 0xc0) == 0x80; 147 | } 148 | 149 | int trail_table(unsigned char c) const { 150 | static const signed char table[] = { 151 | /* not a lead byte */ 152 | /* 0x10???sss */ -1, -1, -1, -1, -1, -1, -1, -1, 153 | /* 0x110??sss */ 1, 1, 1, 1, /* 1 trailing byte */ 154 | /* 0x1110?sss */ 2, 2, /* 2 trailing bytes */ 155 | /* 0x11110sss */ 3, /* 3 trailing bytes */ 156 | /* 0x11111sss */ -1 /* 4 or 5 trailing bytes, disallowed */ 157 | }; 158 | return table[(c & 0x7f) >> 3]; 159 | } 160 | 161 | char trail(unsigned unmasked) const { 162 | return static_cast(0x80 | (unmasked & 0x3f)); 163 | } 164 | }; 165 | 166 | }}}} 167 | 168 | #endif 169 | -------------------------------------------------------------------------------- /include/boost/property_tree/json_parser/detail/read.hpp: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------------- 2 | // Copyright (C) 2015 Sebastian Redl 3 | // 4 | // Distributed under the Boost Software License, Version 1.0. 5 | // (See accompanying file LICENSE_1_0.txt or copy at 6 | // http://www.boost.org/LICENSE_1_0.txt) 7 | // 8 | // For more information, see www.boost.org 9 | // ---------------------------------------------------------------------------- 10 | #ifndef BOOST_PROPERTY_TREE_DETAIL_JSON_PARSER_READ_HPP 11 | #define BOOST_PROPERTY_TREE_DETAIL_JSON_PARSER_READ_HPP 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | #include 19 | #include 20 | 21 | #include 22 | #include 23 | #include 24 | 25 | namespace boost { namespace property_tree { 26 | namespace json_parser { namespace detail 27 | { 28 | 29 | template 30 | class minirange 31 | { 32 | public: 33 | minirange(Iterator first, Sentinel last) : first(first), last(last) {} 34 | Iterator begin() const { return first; } 35 | Sentinel end() const { return last; } 36 | 37 | private: 38 | Iterator first; 39 | Sentinel last; 40 | }; 41 | template 42 | minirange make_minirange(Iterator first, Sentinel last) 43 | { 44 | return minirange(first, last); 45 | } 46 | 47 | template 49 | void read_json_internal(Iterator first, Sentinel last, Encoding& encoding, 50 | Callbacks& callbacks, const std::string& filename) 51 | { 52 | BOOST_STATIC_ASSERT_MSG((boost::is_same< 53 | typename std::iterator_traits::value_type, 54 | typename Encoding::external_char>::value), 55 | "Encoding is not capable of using the iterator's value type."); 56 | BOOST_STATIC_ASSERT_MSG((boost::is_same< 57 | typename Callbacks::char_type, 58 | typename Encoding::internal_char>::value), 59 | "Encoding is not capable of producing the needed character type."); 60 | 61 | detail::parser 62 | parser(callbacks, encoding); 63 | parser.set_input(filename, make_minirange(first, last)); 64 | parser.parse_value(); 65 | parser.finish(); 66 | } 67 | 68 | template struct encoding; 69 | template <> struct encoding : utf8_utf8_encoding {}; 70 | template <> struct encoding : wide_wide_encoding {}; 71 | 72 | template 73 | void read_json_internal( 74 | std::basic_istream &stream, 75 | Ptree &pt, const std::string &filename) 76 | { 77 | typedef typename Ptree::key_type::value_type char_type; 78 | typedef standard_callbacks callbacks_type; 79 | typedef detail::encoding encoding_type; 80 | typedef std::istreambuf_iterator iterator; 81 | callbacks_type callbacks; 82 | encoding_type encoding; 83 | read_json_internal(iterator(stream), iterator(), 84 | encoding, callbacks, filename); 85 | pt.swap(callbacks.output()); 86 | } 87 | 88 | }}}} 89 | 90 | #endif 91 | -------------------------------------------------------------------------------- /include/boost/property_tree/json_parser/detail/standard_callbacks.hpp: -------------------------------------------------------------------------------- 1 | #ifndef BOOST_PROPERTY_TREE_DETAIL_JSON_PARSER_STANDARD_CALLBACKS_HPP 2 | #define BOOST_PROPERTY_TREE_DETAIL_JSON_PARSER_STANDARD_CALLBACKS_HPP 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | namespace boost { namespace property_tree { 9 | namespace json_parser { namespace detail 10 | { 11 | 12 | namespace constants 13 | { 14 | template const Ch* null_value(); 15 | template <> inline const char* null_value() { return "null"; } 16 | template <> inline const wchar_t* null_value() { return L"null"; } 17 | 18 | template const Ch* true_value(); 19 | template <> inline const char* true_value() { return "true"; } 20 | template <> inline const wchar_t* true_value() { return L"true"; } 21 | 22 | template const Ch* false_value(); 23 | template <> inline const char* false_value() { return "false"; } 24 | template <> inline const wchar_t* false_value() { return L"false"; } 25 | } 26 | 27 | template 28 | class standard_callbacks { 29 | public: 30 | typedef typename Ptree::data_type string; 31 | typedef typename string::value_type char_type; 32 | 33 | void on_null() { 34 | new_value() = constants::null_value(); 35 | } 36 | 37 | void on_boolean(bool b) { 38 | new_value() = b ? constants::true_value() 39 | : constants::false_value(); 40 | } 41 | 42 | template 43 | void on_number(Range code_units) { 44 | new_value().assign(code_units.begin(), code_units.end()); 45 | } 46 | void on_begin_number() { 47 | new_value(); 48 | } 49 | void on_digit(char_type d) { 50 | current_value() += d; 51 | } 52 | void on_end_number() {} 53 | 54 | void on_begin_string() { 55 | new_value(); 56 | } 57 | template 58 | void on_code_units(Range code_units) { 59 | current_value().append(code_units.begin(), code_units.end()); 60 | } 61 | void on_code_unit(char_type c) { 62 | current_value() += c; 63 | } 64 | void on_end_string() {} 65 | 66 | void on_begin_array() { 67 | new_tree(); 68 | stack.back().k = array; 69 | } 70 | void on_end_array() { 71 | if (stack.back().k == leaf) stack.pop_back(); 72 | stack.pop_back(); 73 | } 74 | 75 | void on_begin_object() { 76 | new_tree(); 77 | stack.back().k = object; 78 | } 79 | void on_end_object() { 80 | if (stack.back().k == leaf) stack.pop_back(); 81 | stack.pop_back(); 82 | } 83 | 84 | Ptree& output() { return root; } 85 | 86 | protected: 87 | bool is_key() const { 88 | return stack.back().k == key; 89 | } 90 | string& current_value() { 91 | layer& l = stack.back(); 92 | switch (l.k) { 93 | case key: return key_buffer; 94 | default: return l.t->data(); 95 | } 96 | } 97 | 98 | private: 99 | Ptree root; 100 | string key_buffer; 101 | enum kind { array, object, key, leaf }; 102 | struct layer { kind k; Ptree* t; }; 103 | std::vector stack; 104 | 105 | Ptree& new_tree() { 106 | if (stack.empty()) { 107 | layer l = {leaf, &root}; 108 | stack.push_back(l); 109 | return root; 110 | } 111 | layer& l = stack.back(); 112 | switch (l.k) { 113 | case array: { 114 | l.t->push_back(std::make_pair(string(), Ptree())); 115 | layer nl = {leaf, &l.t->back().second}; 116 | stack.push_back(nl); 117 | return *stack.back().t; 118 | } 119 | case object: 120 | BOOST_ASSERT(false); // must start with string, i.e. call new_value 121 | case key: { 122 | l.t->push_back(std::make_pair(key_buffer, Ptree())); 123 | l.k = object; 124 | layer nl = {leaf, &l.t->back().second}; 125 | stack.push_back(nl); 126 | return *stack.back().t; 127 | } 128 | case leaf: 129 | stack.pop_back(); 130 | return new_tree(); 131 | } 132 | BOOST_ASSERT(false); 133 | BOOST_UNREACHABLE_RETURN(root); 134 | } 135 | string& new_value() { 136 | if (stack.empty()) return new_tree().data(); 137 | layer& l = stack.back(); 138 | switch (l.k) { 139 | case leaf: 140 | stack.pop_back(); 141 | return new_value(); 142 | case object: 143 | l.k = key; 144 | key_buffer.clear(); 145 | return key_buffer; 146 | default: 147 | return new_tree().data(); 148 | } 149 | } 150 | }; 151 | 152 | }}}} 153 | 154 | #endif 155 | -------------------------------------------------------------------------------- /include/boost/property_tree/json_parser/detail/wide_encoding.hpp: -------------------------------------------------------------------------------- 1 | #ifndef BOOST_PROPERTY_TREE_DETAIL_JSON_PARSER_WIDE_ENCODING_HPP 2 | #define BOOST_PROPERTY_TREE_DETAIL_JSON_PARSER_WIDE_ENCODING_HPP 3 | 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | namespace boost { namespace property_tree { 10 | namespace json_parser { namespace detail 11 | { 12 | 13 | struct external_wide_encoding 14 | { 15 | typedef wchar_t external_char; 16 | 17 | bool is_nl(wchar_t c) const { return c == L'\n'; } 18 | bool is_ws(wchar_t c) const { 19 | return c == L' ' || c == L'\t' || c == L'\n' || c == L'\r'; 20 | } 21 | 22 | bool is_minus(wchar_t c) const { return c == L'-'; } 23 | bool is_plusminus(wchar_t c) const { return c == L'+' || c == L'-'; } 24 | bool is_dot(wchar_t c) const { return c == L'.'; } 25 | bool is_eE(wchar_t c) const { return c == L'e' || c == L'E'; } 26 | bool is_0(wchar_t c) const { return c == L'0'; } 27 | bool is_digit(wchar_t c) const { return c >= L'0' && c <= L'9'; } 28 | bool is_digit0(wchar_t c) const { return c >= L'1' && c <= L'9'; } 29 | 30 | bool is_quote(wchar_t c) const { return c == L'"'; } 31 | bool is_backslash(wchar_t c) const { return c == L'\\'; } 32 | bool is_slash(wchar_t c) const { return c == L'/'; } 33 | 34 | bool is_comma(wchar_t c) const { return c == L','; } 35 | bool is_open_bracket(wchar_t c) const { return c == L'['; } 36 | bool is_close_bracket(wchar_t c) const { return c == L']'; } 37 | bool is_colon(wchar_t c) const { return c == L':'; } 38 | bool is_open_brace(wchar_t c) const { return c == L'{'; } 39 | bool is_close_brace(wchar_t c) const { return c == L'}'; } 40 | 41 | bool is_a(wchar_t c) const { return c == L'a'; } 42 | bool is_b(wchar_t c) const { return c == L'b'; } 43 | bool is_e(wchar_t c) const { return c == L'e'; } 44 | bool is_f(wchar_t c) const { return c == L'f'; } 45 | bool is_l(wchar_t c) const { return c == L'l'; } 46 | bool is_n(wchar_t c) const { return c == L'n'; } 47 | bool is_r(wchar_t c) const { return c == L'r'; } 48 | bool is_s(wchar_t c) const { return c == L's'; } 49 | bool is_t(wchar_t c) const { return c == L't'; } 50 | bool is_u(wchar_t c) const { return c == L'u'; } 51 | 52 | int decode_hexdigit(wchar_t c) { 53 | if (c >= L'0' && c <= L'9') return c - L'0'; 54 | if (c >= L'A' && c <= L'F') return c - L'A' + 10; 55 | if (c >= L'a' && c <= L'f') return c - L'a' + 10; 56 | return -1; 57 | } 58 | }; 59 | 60 | template struct is_utf16 {}; 61 | 62 | class wide_wide_encoding : public external_wide_encoding 63 | { 64 | typedef is_utf16 test_utf16; 65 | public: 66 | typedef wchar_t internal_char; 67 | 68 | template 69 | boost::iterator_range 70 | to_internal(Iterator first, Iterator last) const { 71 | return boost::make_iterator_range(first, last); 72 | } 73 | 74 | wchar_t to_internal_trivial(wchar_t c) const { 75 | BOOST_ASSERT(!is_surrogate_high(c) && !is_surrogate_low(c)); 76 | return c; 77 | } 78 | 79 | template 81 | void skip_codepoint(Iterator& cur, Sentinel end, 82 | EncodingErrorFn error_fn) const { 83 | transcode_codepoint(cur, end, DoNothing(), error_fn); 84 | } 85 | 86 | template 88 | void transcode_codepoint(Iterator& cur, Sentinel end, 89 | TranscodedFn transcoded_fn, EncodingErrorFn error_fn) const { 90 | return transcode_codepoint(cur, end, transcoded_fn, error_fn, 91 | test_utf16()); 92 | } 93 | 94 | template 95 | void feed_codepoint(unsigned codepoint, 96 | TranscodedFn transcoded_fn) const { 97 | feed_codepoint(codepoint, transcoded_fn, test_utf16()); 98 | } 99 | 100 | template 101 | void skip_introduction(Iterator& cur, Sentinel end) const { 102 | // Endianness is already decoded at this level. 103 | if (cur != end && *cur == 0xfeff) { 104 | ++cur; 105 | } 106 | } 107 | 108 | private: 109 | struct DoNothing { 110 | void operator ()(wchar_t) const {} 111 | }; 112 | 113 | template 115 | void transcode_codepoint(Iterator& cur, Sentinel, 116 | TranscodedFn transcoded_fn, 117 | EncodingErrorFn error_fn, 118 | is_utf16) const { 119 | wchar_t c = *cur; 120 | if (c < 0x20) { 121 | error_fn(); 122 | } 123 | transcoded_fn(c); 124 | ++cur; 125 | } 126 | template 128 | void transcode_codepoint(Iterator& cur, Sentinel end, 129 | TranscodedFn transcoded_fn, 130 | EncodingErrorFn error_fn, 131 | is_utf16) const { 132 | wchar_t c = *cur; 133 | if (c < 0x20) { 134 | error_fn(); 135 | } 136 | if (is_surrogate_low(c)) { 137 | error_fn(); 138 | } 139 | transcoded_fn(c); 140 | ++cur; 141 | if (is_surrogate_high(c)) { 142 | if (cur == end) { 143 | error_fn(); 144 | } 145 | c = *cur; 146 | if (!is_surrogate_low(c)) { 147 | error_fn(); 148 | } 149 | transcoded_fn(c); 150 | ++cur; 151 | } 152 | } 153 | 154 | template 155 | void feed_codepoint(unsigned codepoint, TranscodedFn transcoded_fn, 156 | is_utf16) const { 157 | transcoded_fn(static_cast(codepoint)); 158 | } 159 | template 160 | void feed_codepoint(unsigned codepoint, TranscodedFn transcoded_fn, 161 | is_utf16) const { 162 | if (codepoint < 0x10000) { 163 | transcoded_fn(static_cast(codepoint)); 164 | } else { 165 | codepoint -= 0x10000; 166 | transcoded_fn(static_cast((codepoint >> 10) | 0xd800)); 167 | transcoded_fn(static_cast( 168 | (codepoint & 0x3ff) | 0xdc00)); 169 | } 170 | } 171 | 172 | static bool is_surrogate_high(unsigned codepoint) { 173 | return (codepoint & 0xfc00) == 0xd800; 174 | } 175 | static bool is_surrogate_low(unsigned codepoint) { 176 | return (codepoint & 0xfc00) == 0xdc00; 177 | } 178 | }; 179 | 180 | }}}} 181 | 182 | #endif 183 | -------------------------------------------------------------------------------- /include/boost/property_tree/json_parser/detail/write.hpp: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------------- 2 | // Copyright (C) 2002-2006 Marcin Kalicinski 3 | // 4 | // Distributed under the Boost Software License, Version 1.0. 5 | // (See accompanying file LICENSE_1_0.txt or copy at 6 | // http://www.boost.org/LICENSE_1_0.txt) 7 | // 8 | // For more information, see www.boost.org 9 | // ---------------------------------------------------------------------------- 10 | #ifndef BOOST_PROPERTY_TREE_DETAIL_JSON_PARSER_WRITE_HPP_INCLUDED 11 | #define BOOST_PROPERTY_TREE_DETAIL_JSON_PARSER_WRITE_HPP_INCLUDED 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | 21 | namespace boost { namespace property_tree { namespace json_parser 22 | { 23 | 24 | // Create necessary escape sequences from illegal characters 25 | template 26 | std::basic_string create_escapes(const std::basic_string &s) 27 | { 28 | std::basic_string result; 29 | typename std::basic_string::const_iterator b = s.begin(); 30 | typename std::basic_string::const_iterator e = s.end(); 31 | while (b != e) 32 | { 33 | typedef typename make_unsigned::type UCh; 34 | UCh c(*b); 35 | // This assumes an ASCII superset. But so does everything in PTree. 36 | // We escape everything outside ASCII, because this code can't 37 | // handle high unicode characters. 38 | if (c == 0x20 || c == 0x21 || (c >= 0x23 && c <= 0x2E) || 39 | (c >= 0x30 && c <= 0x5B) || (c >= 0x5D && c <= 0xFF)) 40 | result += *b; 41 | else if (*b == Ch('\b')) result += Ch('\\'), result += Ch('b'); 42 | else if (*b == Ch('\f')) result += Ch('\\'), result += Ch('f'); 43 | else if (*b == Ch('\n')) result += Ch('\\'), result += Ch('n'); 44 | else if (*b == Ch('\r')) result += Ch('\\'), result += Ch('r'); 45 | else if (*b == Ch('\t')) result += Ch('\\'), result += Ch('t'); 46 | else if (*b == Ch('/')) result += Ch('\\'), result += Ch('/'); 47 | else if (*b == Ch('"')) result += Ch('\\'), result += Ch('"'); 48 | else if (*b == Ch('\\')) result += Ch('\\'), result += Ch('\\'); 49 | else 50 | { 51 | const char *hexdigits = "0123456789ABCDEF"; 52 | unsigned long u = (std::min)(static_cast( 53 | static_cast(*b)), 54 | 0xFFFFul); 55 | unsigned long d1 = u / 4096; u -= d1 * 4096; 56 | unsigned long d2 = u / 256; u -= d2 * 256; 57 | unsigned long d3 = u / 16; u -= d3 * 16; 58 | unsigned long d4 = u; 59 | result += Ch('\\'); result += Ch('u'); 60 | result += Ch(hexdigits[d1]); result += Ch(hexdigits[d2]); 61 | result += Ch(hexdigits[d3]); result += Ch(hexdigits[d4]); 62 | } 63 | ++b; 64 | } 65 | return result; 66 | } 67 | 68 | template 69 | void write_json_helper(std::basic_ostream &stream, 70 | const Ptree &pt, 71 | int indent, bool pretty) 72 | { 73 | 74 | typedef typename Ptree::key_type::value_type Ch; 75 | typedef typename std::basic_string Str; 76 | 77 | // Value or object or array 78 | if (indent > 0 && pt.empty()) 79 | { 80 | // Write value 81 | Str data = create_escapes(pt.template get_value()); 82 | stream << Ch('"') << data << Ch('"'); 83 | 84 | } 85 | else if (indent > 0 && pt.count(Str()) == pt.size()) 86 | { 87 | // Write array 88 | stream << Ch('['); 89 | if (pretty) stream << Ch('\n'); 90 | typename Ptree::const_iterator it = pt.begin(); 91 | for (; it != pt.end(); ++it) 92 | { 93 | if (pretty) stream << Str(4 * (indent + 1), Ch(' ')); 94 | write_json_helper(stream, it->second, indent + 1, pretty); 95 | if (boost::next(it) != pt.end()) 96 | stream << Ch(','); 97 | if (pretty) stream << Ch('\n'); 98 | } 99 | if (pretty) stream << Str(4 * indent, Ch(' ')); 100 | stream << Ch(']'); 101 | 102 | } 103 | else 104 | { 105 | // Write object 106 | stream << Ch('{'); 107 | if (pretty) stream << Ch('\n'); 108 | typename Ptree::const_iterator it = pt.begin(); 109 | for (; it != pt.end(); ++it) 110 | { 111 | if (pretty) stream << Str(4 * (indent + 1), Ch(' ')); 112 | stream << Ch('"') << create_escapes(it->first) << Ch('"') << Ch(':'); 113 | if (pretty) stream << Ch(' '); 114 | write_json_helper(stream, it->second, indent + 1, pretty); 115 | if (boost::next(it) != pt.end()) 116 | stream << Ch(','); 117 | if (pretty) stream << Ch('\n'); 118 | } 119 | if (pretty) stream << Str(4 * indent, Ch(' ')); 120 | stream << Ch('}'); 121 | } 122 | 123 | } 124 | 125 | // Verify if ptree does not contain information that cannot be written to json 126 | template 127 | bool verify_json(const Ptree &pt, int depth) 128 | { 129 | 130 | typedef typename Ptree::key_type::value_type Ch; 131 | typedef typename std::basic_string Str; 132 | 133 | // Root ptree cannot have data 134 | if (depth == 0 && !pt.template get_value().empty()) 135 | return false; 136 | 137 | // Ptree cannot have both children and data 138 | if (!pt.template get_value().empty() && !pt.empty()) 139 | return false; 140 | 141 | // Check children 142 | typename Ptree::const_iterator it = pt.begin(); 143 | for (; it != pt.end(); ++it) 144 | if (!verify_json(it->second, depth + 1)) 145 | return false; 146 | 147 | // Success 148 | return true; 149 | 150 | } 151 | 152 | // Write ptree to json stream 153 | template 154 | void write_json_internal(std::basic_ostream &stream, 155 | const Ptree &pt, 156 | const std::string &filename, 157 | bool pretty) 158 | { 159 | if (!verify_json(pt, 0)) 160 | BOOST_PROPERTY_TREE_THROW(json_parser_error("ptree contains data that cannot be represented in JSON format", filename, 0)); 161 | write_json_helper(stream, pt, 0, pretty); 162 | 163 | if (pretty) stream << std::endl; 164 | else stream << std::flush; 165 | 166 | if (!stream.good()) 167 | BOOST_PROPERTY_TREE_THROW(json_parser_error("write error", filename, 0)); 168 | } 169 | 170 | } } } 171 | 172 | #endif 173 | -------------------------------------------------------------------------------- /include/boost/property_tree/json_parser/error.hpp: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------------- 2 | // Copyright (C) 2002-2006 Marcin Kalicinski 3 | // 4 | // Distributed under the Boost Software License, Version 1.0. 5 | // (See accompanying file LICENSE_1_0.txt or copy at 6 | // http://www.boost.org/LICENSE_1_0.txt) 7 | // 8 | // For more information, see www.boost.org 9 | // ---------------------------------------------------------------------------- 10 | #ifndef BOOST_PROPERTY_TREE_DETAIL_JSON_PARSER_ERROR_HPP_INCLUDED 11 | #define BOOST_PROPERTY_TREE_DETAIL_JSON_PARSER_ERROR_HPP_INCLUDED 12 | 13 | #include 14 | #include 15 | 16 | namespace boost { namespace property_tree { namespace json_parser 17 | { 18 | 19 | //! Json parser error 20 | class json_parser_error: public file_parser_error 21 | { 22 | public: 23 | json_parser_error(const std::string &message, 24 | const std::string &filename, 25 | unsigned long line): 26 | file_parser_error(message, filename, line) 27 | { 28 | } 29 | }; 30 | 31 | } } } 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /include/boost/property_tree/ptree_fwd.hpp: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------------- 2 | // Copyright (C) 2002-2006 Marcin Kalicinski 3 | // Copyright (C) 2009 Sebastian Redl 4 | // 5 | // Distributed under the Boost Software License, Version 1.0. 6 | // (See accompanying file LICENSE_1_0.txt or copy at 7 | // http://www.boost.org/LICENSE_1_0.txt) 8 | // 9 | // For more information, see www.boost.org 10 | // ---------------------------------------------------------------------------- 11 | #ifndef BOOST_PROPERTY_TREE_PTREE_FWD_HPP_INCLUDED 12 | #define BOOST_PROPERTY_TREE_PTREE_FWD_HPP_INCLUDED 13 | 14 | #include 15 | #include 16 | #include 17 | #include // for std::less 18 | #include // for std::allocator 19 | #include 20 | 21 | namespace boost { namespace property_tree 22 | { 23 | namespace detail { 24 | template struct less_nocase; 25 | } 26 | 27 | // Classes 28 | 29 | template < class Key, class Data, class KeyCompare = std::less > 30 | class basic_ptree; 31 | 32 | template 33 | struct id_translator; 34 | 35 | template 36 | class string_path; 37 | 38 | // Texas-style concepts for documentation only. 39 | #if 0 40 | concept PropertyTreePath { 41 | // The key type for which this path works. 42 | typename key_type; 43 | // Return the key that the first segment of the path names. 44 | // Split the head off the state. 45 | key_type Path::reduce(); 46 | 47 | // Return true if the path is empty. 48 | bool Path::empty() const; 49 | 50 | // Return true if the path contains a single element. 51 | bool Path::single() const; 52 | 53 | // Dump as a std::string, for exception messages. 54 | std::string Path::dump() const; 55 | } 56 | concept PropertyTreeKey { 57 | PropertyTreePath path; 58 | requires SameType::key_type>; 59 | } 60 | concept PropertyTreeTranslator { 61 | typename internal_type; 62 | typename external_type; 63 | 64 | boost::optional Tr::get_value(internal_type); 65 | boost::optional Tr::put_value(external_type); 66 | } 67 | #endif 68 | /// If you want to use a custom key type, specialize this struct for it 69 | /// and give it a 'type' typedef that specifies your path type. The path 70 | /// type must conform to the Path concept described in the documentation. 71 | /// This is already specialized for std::basic_string. 72 | template 73 | struct path_of; 74 | 75 | /// Specialize this struct to specify a default translator between the data 76 | /// in a tree whose data_type is Internal, and the external data_type 77 | /// specified in a get_value, get, put_value or put operation. 78 | /// This is already specialized for Internal being std::basic_string. 79 | template 80 | struct translator_between; 81 | 82 | class ptree_error; 83 | class ptree_bad_data; 84 | class ptree_bad_path; 85 | 86 | // Typedefs 87 | 88 | /** Implements a path using a std::string as the key. */ 89 | typedef string_path > path; 90 | 91 | /** 92 | * A property tree with std::string for key and data, and default 93 | * comparison. 94 | */ 95 | typedef basic_ptree ptree; 96 | 97 | /** 98 | * A property tree with std::string for key and data, and case-insensitive 99 | * comparison. 100 | */ 101 | typedef basic_ptree > 103 | iptree; 104 | 105 | #ifndef BOOST_NO_STD_WSTRING 106 | /** Implements a path using a std::wstring as the key. */ 107 | typedef string_path > wpath; 108 | 109 | /** 110 | * A property tree with std::wstring for key and data, and default 111 | * comparison. 112 | * @note The type only exists if the platform supports @c wchar_t. 113 | */ 114 | typedef basic_ptree wptree; 115 | 116 | /** 117 | * A property tree with std::wstring for key and data, and case-insensitive 118 | * comparison. 119 | * @note The type only exists if the platform supports @c wchar_t. 120 | */ 121 | typedef basic_ptree > 123 | wiptree; 124 | #endif 125 | 126 | // Free functions 127 | 128 | /** 129 | * Swap two property tree instances. 130 | */ 131 | template 132 | void swap(basic_ptree &pt1, 133 | basic_ptree &pt2); 134 | 135 | } } 136 | 137 | 138 | #if !defined(BOOST_PROPERTY_TREE_DOXYGEN_INVOKED) 139 | // Throwing macro to avoid no return warnings portably 140 | # define BOOST_PROPERTY_TREE_THROW(e) BOOST_THROW_EXCEPTION(e) 141 | #endif 142 | 143 | #endif 144 | -------------------------------------------------------------------------------- /include/boost/property_tree/ptree_serialization.hpp: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------------- 2 | // Copyright (C) 2002-2006 Marcin Kalicinski 3 | // 4 | // Distributed under the Boost Software License, Version 1.0. 5 | // (See accompanying file LICENSE_1_0.txt or copy at 6 | // http://www.boost.org/LICENSE_1_0.txt) 7 | // 8 | // For more information, see www.boost.org 9 | // ---------------------------------------------------------------------------- 10 | #ifndef BOOST_PROPERTY_TREE_PTREE_SERIALIZATION_HPP_INCLUDED 11 | #define BOOST_PROPERTY_TREE_PTREE_SERIALIZATION_HPP_INCLUDED 12 | 13 | #include 14 | 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | namespace boost { namespace property_tree 23 | { 24 | 25 | /////////////////////////////////////////////////////////////////////////// 26 | // boost::serialization support 27 | 28 | /** 29 | * Serialize the property tree to the given archive. 30 | * @note In addition to serializing to regular archives, this supports 31 | * serializing to archives requiring name-value pairs, e.g. XML 32 | * archives. However, the output format in the XML archive is not 33 | * guaranteed to be the same as that when using the Boost.PropertyTree 34 | * library's @c boost::property_tree::xml_parser::write_xml. 35 | * @param ar The archive to which to save the serialized property tree. 36 | * This archive should conform to the concept laid out by the 37 | * Boost.Serialization library. 38 | * @param t The property tree to serialize. 39 | * @param file_version file_version for the archive. 40 | * @post @c ar will contain the serialized form of @c t. 41 | */ 42 | template 43 | inline void save(Archive &ar, 44 | const basic_ptree &t, 45 | const unsigned int /*file_version*/) 46 | { 47 | using namespace boost::serialization; 48 | stl::save_collection >(ar, t); 49 | ar << make_nvp("data", t.data()); 50 | } 51 | 52 | namespace detail 53 | { 54 | template 55 | inline void load_children(Archive &ar, 56 | basic_ptree &t) 57 | { 58 | namespace bsl = boost::serialization; 59 | 60 | typedef basic_ptree tree; 61 | typedef typename tree::value_type value_type; 62 | 63 | bsl::collection_size_type count; 64 | ar >> BOOST_SERIALIZATION_NVP(count); 65 | bsl::item_version_type item_version(0); 66 | const bsl::library_version_type library_version( 67 | ar.get_library_version() 68 | ); 69 | if(bsl::library_version_type(3) < library_version){ 70 | ar >> BOOST_SERIALIZATION_NVP(item_version); 71 | } 72 | // Can't use the serialization helper, it expects resize() to exist 73 | // for default-constructible elements. 74 | // This is a copy/paste of the fallback version. 75 | t.clear(); 76 | while(count-- > 0){ 77 | bsl::detail::stack_construct 78 | u(ar, item_version); 79 | ar >> bsl::make_nvp("item", u.reference()); 80 | t.push_back(u.reference()); 81 | ar.reset_object_address(& t.back() , & u.reference()); 82 | } 83 | } 84 | } 85 | 86 | /** 87 | * De-serialize the property tree to the given archive. 88 | * @note In addition to de-serializing from regular archives, this supports 89 | * loading from archives requiring name-value pairs, e.g. XML 90 | * archives. The format should be that used by 91 | * boost::property_tree::save. 92 | * @param ar The archive from which to load the serialized property tree. 93 | * This archive should conform to the concept laid out by the 94 | * Boost.Serialization library. 95 | * @param t The property tree to de-serialize. 96 | * @param file_version file_version for the archive. 97 | * @post @c t will contain the de-serialized data from @c ar. 98 | */ 99 | template 100 | inline void load(Archive &ar, 101 | basic_ptree &t, 102 | const unsigned int /*file_version*/) 103 | { 104 | namespace bsl = boost::serialization; 105 | 106 | detail::load_children(ar, t); 107 | ar >> bsl::make_nvp("data", t.data()); 108 | } 109 | 110 | /** 111 | * Load or store the property tree using the given archive. 112 | * @param ar The archive from which to load or save the serialized property 113 | * tree. The type of this archive will determine whether saving or 114 | * loading is performed. 115 | * @param t The property tree to load or save. 116 | * @param file_version file_version for the archive. 117 | */ 118 | template 119 | inline void serialize(Archive &ar, 120 | basic_ptree &t, 121 | const unsigned int file_version) 122 | { 123 | using namespace boost::serialization; 124 | split_free(ar, t, file_version); 125 | } 126 | 127 | } } 128 | 129 | #endif 130 | -------------------------------------------------------------------------------- /include/boost/property_tree/xml_parser.hpp: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------------- 2 | // Copyright (C) 2002-2006 Marcin Kalicinski 3 | // Copyright (C) 2009 Sebastian Redl 4 | // 5 | // Distributed under the Boost Software License, Version 1.0. 6 | // (See accompanying file LICENSE_1_0.txt or copy at 7 | // http://www.boost.org/LICENSE_1_0.txt) 8 | // 9 | // For more information, see www.boost.org 10 | // ---------------------------------------------------------------------------- 11 | #ifndef BOOST_PROPERTY_TREE_XML_PARSER_HPP_INCLUDED 12 | #define BOOST_PROPERTY_TREE_XML_PARSER_HPP_INCLUDED 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | 21 | #include 22 | #include 23 | #include 24 | 25 | namespace boost { namespace property_tree { namespace xml_parser 26 | { 27 | 28 | /** 29 | * Reads XML from an input stream and translates it to property tree. 30 | * @note Clears existing contents of property tree. In case of error the 31 | * property tree unmodified. 32 | * @note XML attributes are placed under keys named @c \. 33 | * @throw xml_parser_error In case of error deserializing the property tree. 34 | * @param stream Stream from which to read in the property tree. 35 | * @param[out] pt The property tree to populate. 36 | * @param flags Flags controlling the behaviour of the parser. 37 | * The following flags are supported: 38 | * @li @c no_concat_text -- Prevents concatenation of text nodes into 39 | * datastring of property tree. Puts them in 40 | * separate @c \ strings instead. 41 | * @li @c no_comments -- Skip XML comments. 42 | * @li @c trim_whitespace -- Trim leading and trailing whitespace from text, 43 | * and collapse sequences of whitespace. 44 | */ 45 | template 46 | void read_xml(std::basic_istream< 47 | typename Ptree::key_type::value_type 48 | > &stream, 49 | Ptree &pt, 50 | int flags = 0) 51 | { 52 | read_xml_internal(stream, pt, flags, std::string()); 53 | } 54 | 55 | /** 56 | * Reads XML from a file using the given locale and translates it to 57 | * property tree. 58 | * @note Clears existing contents of property tree. In case of error the 59 | * property tree unmodified. 60 | * @note XML attributes are placed under keys named @c \. 61 | * @throw xml_parser_error In case of error deserializing the property tree. 62 | * @param filename The file from which to read in the property tree. 63 | * @param[out] pt The property tree to populate. 64 | * @param flags Flags controlling the bahviour of the parser. 65 | * The following flags are supported: 66 | * @li @c no_concat_text -- Prevents concatenation of text nodes into 67 | * datastring of property tree. Puts them in 68 | * separate @c \ strings instead. 69 | * @li @c no_comments -- Skip XML comments. 70 | * @param loc The locale to use when reading in the file contents. 71 | */ 72 | template 73 | void read_xml(const std::string &filename, 74 | Ptree &pt, 75 | int flags = 0, 76 | const std::locale &loc = std::locale()) 77 | { 78 | BOOST_ASSERT(validate_flags(flags)); 79 | std::basic_ifstream 80 | stream(filename.c_str()); 81 | if (!stream) 82 | BOOST_PROPERTY_TREE_THROW(xml_parser_error( 83 | "cannot open file", filename, 0)); 84 | stream.imbue(loc); 85 | read_xml_internal(stream, pt, flags, filename); 86 | } 87 | 88 | /** 89 | * Translates the property tree to XML and writes it the given output 90 | * stream. 91 | * @throw xml_parser_error In case of error translating the property tree to 92 | * XML or writing to the output stream. 93 | * @param stream The stream to which to write the XML representation of the 94 | * property tree. 95 | * @param pt The property tree to tranlsate to XML and output. 96 | * @param settings The settings to use when writing out the property tree as 97 | * XML. 98 | */ 99 | template 100 | void write_xml(std::basic_ostream< 101 | typename Ptree::key_type::value_type 102 | > &stream, 103 | const Ptree &pt, 104 | const xml_writer_settings< 105 | typename Ptree::key_type 106 | > & settings = xml_writer_settings< 107 | typename Ptree::key_type>() ) 108 | { 109 | write_xml_internal(stream, pt, std::string(), settings); 110 | } 111 | 112 | /** 113 | * Translates the property tree to XML and writes it the given file. 114 | * @throw xml_parser_error In case of error translating the property tree to 115 | * XML or writing to the output stream. 116 | * @param filename The file to which to write the XML representation of the 117 | * property tree. 118 | * @param pt The property tree to tranlsate to XML and output. 119 | * @param loc The locale to use when writing the output to file. 120 | * @param settings The settings to use when writing out the property tree as 121 | * XML. 122 | */ 123 | template 124 | void write_xml(const std::string &filename, 125 | const Ptree &pt, 126 | const std::locale &loc = std::locale(), 127 | const xml_writer_settings< 128 | typename Ptree::key_type 129 | > & settings = xml_writer_settings()) 130 | { 131 | std::basic_ofstream 132 | stream(filename.c_str()); 133 | if (!stream) 134 | BOOST_PROPERTY_TREE_THROW(xml_parser_error( 135 | "cannot open file", filename, 0)); 136 | stream.imbue(loc); 137 | write_xml_internal(stream, pt, filename, settings); 138 | } 139 | 140 | } } } 141 | 142 | namespace boost { namespace property_tree 143 | { 144 | using xml_parser::read_xml; 145 | using xml_parser::write_xml; 146 | using xml_parser::xml_parser_error; 147 | 148 | using xml_parser::xml_writer_settings; 149 | using xml_parser::xml_writer_make_settings; 150 | } } 151 | 152 | #endif 153 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Automatic redirection failed, please go to the 7 | Boost.PropertyTree documentation. 8 |

Copyright Sebastian Redl 2009

9 |

Distributed under the Boost Software License, Version 1.0. (See accompanying file 10 | LICENSE_1_0.txt or copy at 11 | www.boost.org/LICENSE_1_0.txt). 12 |

13 | 14 | 15 | -------------------------------------------------------------------------------- /meta/libraries.json: -------------------------------------------------------------------------------- 1 | { 2 | "key": "property_tree", 3 | "name": "Property Tree", 4 | "authors": [ 5 | "Marcin Kalicinski", 6 | "Sebastian Redl" 7 | ], 8 | "description": "A tree data structure especially suited to storing configuration data.", 9 | "category": [ 10 | "Containers", 11 | "Data" 12 | ], 13 | "maintainers": [ 14 | "Richard Hodges " 15 | ], 16 | "cxxstd": "11" 17 | } 18 | -------------------------------------------------------------------------------- /test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright 2018, 2019 Peter Dimov 2 | # Distributed under the Boost Software License, Version 1.0. 3 | # See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt 4 | 5 | include(BoostTestJamfile OPTIONAL RESULT_VARIABLE HAVE_BOOST_TEST) 6 | 7 | if(HAVE_BOOST_TEST) 8 | 9 | boost_test_jamfile(FILE Jamfile.v2 LINK_LIBRARIES Boost::property_tree Boost::format Boost::foreach) 10 | 11 | boost_test(TYPE run SOURCES test_property_tree.cpp LINK_LIBRARIES Boost::property_tree Boost::serialization) 12 | 13 | endif() 14 | -------------------------------------------------------------------------------- /test/Jamfile.v2: -------------------------------------------------------------------------------- 1 | # Boost.PropertyTree 2 | # 3 | # Copyright (c) 2009 Sebastian Redl 4 | # 5 | # Distributed under the Boost Software License, Version 1.0. 6 | # (See accompanying file LICENSE_1_0.txt or copy at 7 | # http://www.boost.org/LICENSE_1_0.txt) 8 | 9 | # bring in rules for testing 10 | import path ; 11 | import regex ; 12 | import testing ; 13 | 14 | project 15 | : requirements 16 | 17 | /boost/property_tree//boost_property_tree 18 | 19 | static 20 | msvc:_SCL_SECURE_NO_WARNINGS=1 21 | 22 | extra 23 | msvc:on 24 | clang:on 25 | gcc:on 26 | ; 27 | 28 | run test_property_tree.cpp /boost/serialization//boost_serialization/off ; 29 | run test_rapidxml.cpp ; 30 | run test_info_parser.cpp ; 31 | run test_json_parser.cpp ; 32 | run test_json_parser2.cpp ; 33 | compile test_json_parser3.cpp ; 34 | run test_ini_parser.cpp ; 35 | run test_xml_parser_rapidxml.cpp ; 36 | 37 | run test_multi_module1.cpp test_multi_module2.cpp ; 38 | 39 | # Ensure that all headers are self-contained. 40 | for local file in [ glob-tree-ex ../include : *.hpp ] 41 | { 42 | local rel_name = [ path.relative-to ../include $(file) ] ; 43 | compile self_contained_header.cpp : HEADER_PATH=$(rel_name) : [ regex.replace $(rel_name) "/" "_" ] ; 44 | } 45 | 46 | compile ../examples/custom_data_type.cpp ; 47 | compile ../examples/debug_settings.cpp /boost/foreach//boost_foreach ; 48 | compile ../examples/empty_ptree_trick.cpp ; 49 | compile ../examples/info_grammar_spirit.cpp ; 50 | compile ../examples/speed_test.cpp /boost/format//boost_format ; 51 | -------------------------------------------------------------------------------- /test/cmake_install_test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright 2018, 2019 Peter Dimov 2 | # Distributed under the Boost Software License, Version 1.0. 3 | # See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt 4 | 5 | cmake_minimum_required(VERSION 3.5...3.16) 6 | 7 | project(cmake_install_test LANGUAGES CXX) 8 | 9 | find_package(boost_property_tree REQUIRED) 10 | 11 | add_executable(main main.cpp) 12 | target_link_libraries(main Boost::property_tree) 13 | 14 | enable_testing() 15 | add_test(main main) 16 | 17 | add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure -C $) 18 | -------------------------------------------------------------------------------- /test/cmake_install_test/main.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Peter Dimov. 2 | // Distributed under the Boost Software License, Version 1.0. 3 | // https://www.boost.org/LICENSE_1_0.txt 4 | 5 | #include 6 | 7 | namespace pt = boost::property_tree; 8 | 9 | int main() 10 | { 11 | pt::ptree tree; 12 | 13 | tree.put( "source.file", __FILE__ ); 14 | tree.put( "source.line", __LINE__ ); 15 | } 16 | -------------------------------------------------------------------------------- /test/cmake_subdir_test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright 2018-2021 Peter Dimov 2 | # Distributed under the Boost Software License, Version 1.0. 3 | # See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt 4 | 5 | cmake_minimum_required(VERSION 3.5...3.20) 6 | 7 | project(cmake_subdir_test LANGUAGES CXX) 8 | 9 | set(BOOST_INCLUDE_LIBRARIES property_tree) 10 | add_subdirectory(../../../.. boostorg/boost) 11 | 12 | add_executable(main main.cpp) 13 | target_link_libraries(main Boost::property_tree) 14 | 15 | enable_testing() 16 | add_test(main main) 17 | 18 | add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure --no-tests=error -C $) 19 | -------------------------------------------------------------------------------- /test/cmake_subdir_test/main.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Peter Dimov. 2 | // Distributed under the Boost Software License, Version 1.0. 3 | // https://www.boost.org/LICENSE_1_0.txt 4 | 5 | #include 6 | 7 | namespace pt = boost::property_tree; 8 | 9 | int main() 10 | { 11 | pt::ptree tree; 12 | 13 | tree.put( "source.file", __FILE__ ); 14 | tree.put( "source.line", __LINE__ ); 15 | } 16 | -------------------------------------------------------------------------------- /test/prefixing_callbacks.hpp: -------------------------------------------------------------------------------- 1 | #ifndef JSON_PARSER_PREFIXING_CALLBACKS_HPP 2 | #define JSON_PARSER_PREFIXING_CALLBACKS_HPP 3 | 4 | #include 5 | 6 | namespace constants 7 | { 8 | template const Ch* null_prefix(); 9 | template <> inline const char* null_prefix() { return "_:"; } 10 | template <> inline const wchar_t* null_prefix() { return L"_:"; } 11 | 12 | template const Ch* boolean_prefix(); 13 | template <> inline const char* boolean_prefix() { return "b:"; } 14 | template <> inline const wchar_t* boolean_prefix() { return L"b:"; } 15 | 16 | template const Ch* number_prefix(); 17 | template <> inline const char* number_prefix() { return "n:"; } 18 | template <> inline const wchar_t* number_prefix() { return L"n:"; } 19 | 20 | template const Ch* string_prefix(); 21 | template <> inline const char* string_prefix() { return "s:"; } 22 | template <> inline const wchar_t* string_prefix() { return L"s:"; } 23 | 24 | template const Ch* array_prefix(); 25 | template <> inline const char* array_prefix() { return "a:"; } 26 | template <> inline const wchar_t* array_prefix() { return L"a:"; } 27 | 28 | template const Ch* object_prefix(); 29 | template <> inline const char* object_prefix() { return "o:"; } 30 | template <> inline const wchar_t* object_prefix() { return L"o:"; } 31 | } 32 | 33 | template 34 | struct prefixing_callbacks 35 | : boost::property_tree::json_parser::detail::standard_callbacks { 36 | typedef boost::property_tree::json_parser::detail::standard_callbacks 37 | base; 38 | typedef typename base::string string; 39 | typedef typename base::char_type char_type; 40 | 41 | void on_null() { 42 | base::on_null(); 43 | this->current_value().insert(0, constants::null_prefix()); 44 | } 45 | 46 | void on_boolean(bool b) { 47 | base::on_boolean(b); 48 | this->current_value().insert(0, constants::boolean_prefix()); 49 | } 50 | 51 | template 52 | void on_number(Range code_units) { 53 | base::on_number(code_units); 54 | this->current_value().insert(0, constants::number_prefix()); 55 | } 56 | void on_begin_number() { 57 | base::on_begin_number(); 58 | this->current_value() = constants::number_prefix(); 59 | } 60 | 61 | void on_begin_string() { 62 | base::on_begin_string(); 63 | if (!this->is_key()) { 64 | this->current_value() = constants::string_prefix(); 65 | } 66 | } 67 | 68 | void on_begin_array() { 69 | base::on_begin_array(); 70 | this->current_value() = constants::array_prefix(); 71 | } 72 | 73 | void on_begin_object() { 74 | base::on_begin_object(); 75 | this->current_value() = constants::object_prefix(); 76 | } 77 | }; 78 | 79 | #endif 80 | -------------------------------------------------------------------------------- /test/sandbox.cpp: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------------- 2 | // Copyright (C) 2009 Sebastian Redl 3 | // 4 | // Distributed under the Boost Software License, Version 1.0. 5 | // (See accompanying file LICENSE_1_0.txt or copy at 6 | // http://www.boost.org/LICENSE_1_0.txt) 7 | // 8 | // For more information, see www.boost.org 9 | // ---------------------------------------------------------------------------- 10 | 11 | #define _CRT_SECURE_NO_DEPRECATE 12 | #include 13 | #include 14 | #include 15 | 16 | int main() 17 | { 18 | using namespace boost::property_tree; 19 | ptree pt; 20 | read_xml("simple_all.xml", pt); 21 | write_info(std::cout, pt); 22 | } 23 | -------------------------------------------------------------------------------- /test/self_contained_header.cpp: -------------------------------------------------------------------------------- 1 | #define INCLUDE_HEADER() 2 | 3 | #include INCLUDE_HEADER() 4 | -------------------------------------------------------------------------------- /test/test_info_parser.cpp: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------------- 2 | // Copyright (C) 2002-2006 Marcin Kalicinski 3 | // 4 | // Distributed under the Boost Software License, Version 1.0. 5 | // (See accompanying file LICENSE_1_0.txt or copy at 6 | // http://www.boost.org/LICENSE_1_0.txt) 7 | // 8 | // For more information, see www.boost.org 9 | // ---------------------------------------------------------------------------- 10 | 11 | #include "test_utils.hpp" 12 | #include 13 | 14 | /////////////////////////////////////////////////////////////////////////////// 15 | // Test data 16 | 17 | const char *ok_data_1 = 18 | ";Test file for info_parser\n" 19 | "\n" 20 | "key1 data1\n" 21 | "{\n" 22 | "\tkey data\n" 23 | "}\n" 24 | "#include \"testok1_inc.info\"\n" 25 | "key2 \"data2 \" {\n" 26 | "\tkey data\n" 27 | "}\n" 28 | "#\tinclude \"testok1_inc.info\"\n" 29 | "key3 \"data\"\n" 30 | "\t \"3\" {\n" 31 | "\tkey data\n" 32 | "}\n" 33 | "\t#include \"testok1_inc.info\"\n" 34 | "\n" 35 | "\"key4\" data4\n" 36 | "{\n" 37 | "\tkey data\n" 38 | "}\n" 39 | "#include \"testok1_inc.info\"\n" 40 | "\"key.5\" \"data.5\" { \n" 41 | "\tkey data \n" 42 | "}\n" 43 | "#\tinclude \"testok1_inc.info\"\n" 44 | "\"key6\" \"data\"\n" 45 | "\t \"6\" {\n" 46 | "\tkey data\n" 47 | "}\n" 48 | "\t#include \"testok1_inc.info\"\n" 49 | " \n" 50 | "key1 data1; comment\n" 51 | "{; comment\n" 52 | "\tkey data; comment\n" 53 | "}; comment\n" 54 | "#include \"testok1_inc.info\"\n" 55 | "key2 \"data2 \" {; comment\n" 56 | "\tkey data; comment\n" 57 | "}; comment\n" 58 | "#\tinclude \"testok1_inc.info\"\n" 59 | "key3 \"data\"; comment\n" 60 | "\t \"3\" {; comment\n" 61 | "\tkey data; comment\n" 62 | "}; comment\n" 63 | "\t#include \"testok1_inc.info\"\n" 64 | "\n" 65 | "\"key4\" data4; comment\n" 66 | "{; comment\n" 67 | "\tkey data; comment\n" 68 | "}; comment\n" 69 | "#include \"testok1_inc.info\"\n" 70 | "\"key.5\" \"data.5\" {; comment\n" 71 | "\tkey data; comment\n" 72 | "}; comment\n" 73 | "#\tinclude \"testok1_inc.info\"\n" 74 | "\"key6\" \"data\"; comment\n" 75 | "\t \"6\" {; comment\n" 76 | "\tkey data; comment\n" 77 | "}; comment\n" 78 | "\t#include \"testok1_inc.info\"\n" 79 | "\\\\key\\t7 data7\\n\\\"data7\\\"\n" 80 | "{\n" 81 | "\tkey data\n" 82 | "}\n" 83 | "\"\\\\key\\t8\" \"data8\\n\\\"data8\\\"\"\n" 84 | "{\n" 85 | "\tkey data\n" 86 | "}\n" 87 | "\n"; 88 | 89 | const char *ok_data_1_inc = 90 | ";Test file for info_parser\n" 91 | "\n" 92 | "inc_key inc_data ;;; comment\\"; 93 | 94 | const char *ok_data_2 = 95 | ""; 96 | 97 | const char *ok_data_3 = 98 | "key1 \"\"\n" 99 | "key2 \"\"\n" 100 | "key3 \"\"\n" 101 | "key4 \"\"\n"; 102 | 103 | const char *ok_data_4 = 104 | "key1 data key2 data"; 105 | 106 | const char *ok_data_5 = 107 | "key { key \"\" key \"\" }\n"; 108 | 109 | const char *ok_data_6 = 110 | "\"key with spaces\" \"data with spaces\"\n" 111 | "\"key with spaces\" \"multiline data\"\\\n" 112 | "\"cont\"\\\n" 113 | "\"cont\""; 114 | 115 | const char *error_data_1 = 116 | ";Test file for info_parser\n" 117 | "#include \"bogus_file\"\n"; // Nonexistent include file 118 | 119 | const char *error_data_2 = 120 | ";Test file for info_parser\n" 121 | "key \"data with bad escape: \\q\"\n"; // Bad escape 122 | 123 | const char *error_data_3 = 124 | ";Test file for info_parser\n" 125 | "{\n"; // Opening brace without key 126 | 127 | const char *error_data_4 = 128 | ";Test file for info_parser\n" 129 | "}\n"; // Closing brace without opening brace 130 | 131 | const char *error_data_5 = 132 | ";Test file for info_parser\n" 133 | "key data\n" 134 | "{\n" 135 | ""; // No closing brace 136 | 137 | struct ReadFunc 138 | { 139 | template 140 | void operator()(const std::string &filename, Ptree &pt) const 141 | { 142 | boost::property_tree::read_info(filename, pt); 143 | } 144 | }; 145 | 146 | struct WriteFunc 147 | { 148 | template 149 | void operator()(const std::string &filename, const Ptree &pt) const 150 | { 151 | boost::property_tree::write_info(filename, pt); 152 | } 153 | }; 154 | 155 | template 156 | void test_info_parser() 157 | { 158 | 159 | using namespace boost::property_tree; 160 | 161 | generic_parser_test_ok 162 | ( 163 | ReadFunc(), WriteFunc(), ok_data_1, ok_data_1_inc, 164 | "testok1.info", "testok1_inc.info", "testok1out.info", 45, 240, 192 165 | ); 166 | 167 | generic_parser_test_ok 168 | ( 169 | ReadFunc(), WriteFunc(), ok_data_2, NULL, 170 | "testok2.info", NULL, "testok2out.info", 1, 0, 0 171 | ); 172 | 173 | generic_parser_test_ok 174 | ( 175 | ReadFunc(), WriteFunc(), ok_data_3, NULL, 176 | "testok3.info", NULL, "testok3out.info", 5, 0, 16 177 | ); 178 | 179 | generic_parser_test_ok 180 | ( 181 | ReadFunc(), WriteFunc(), ok_data_4, NULL, 182 | "testok4.info", NULL, "testok4out.info", 3, 8, 8 183 | ); 184 | 185 | generic_parser_test_ok 186 | ( 187 | ReadFunc(), WriteFunc(), ok_data_5, NULL, 188 | "testok5.info", NULL, "testok5out.info", 4, 0, 9 189 | ); 190 | 191 | generic_parser_test_ok 192 | ( 193 | ReadFunc(), WriteFunc(), ok_data_6, NULL, 194 | "testok6.info", NULL, "testok6out.info", 3, 38, 30 195 | ); 196 | 197 | generic_parser_test_error 198 | ( 199 | ReadFunc(), WriteFunc(), error_data_1, NULL, 200 | "testerr1.info", NULL, "testerr1out.info", 2 201 | ); 202 | 203 | generic_parser_test_error 204 | ( 205 | ReadFunc(), WriteFunc(), error_data_2, NULL, 206 | "testerr2.info", NULL, "testerr2out.info", 2 207 | ); 208 | 209 | generic_parser_test_error 210 | ( 211 | ReadFunc(), WriteFunc(), error_data_3, NULL, 212 | "testerr3.info", NULL, "testerr3out.info", 2 213 | ); 214 | 215 | generic_parser_test_error 216 | ( 217 | ReadFunc(), WriteFunc(), error_data_4, NULL, 218 | "testerr4.info", NULL, "testerr4out.info", 2 219 | ); 220 | 221 | generic_parser_test_error 222 | ( 223 | ReadFunc(), WriteFunc(), error_data_5, NULL, 224 | "testerr5.info", NULL, "testerr5out.info", 4 225 | ); 226 | 227 | // Test read with default ptree 228 | { 229 | Ptree pt, default_pt; 230 | pt.put_value(1); 231 | default_pt.put_value(2); 232 | BOOST_TEST(pt != default_pt); 233 | read_info("nonexisting file.nonexisting file", pt, default_pt); 234 | BOOST_TEST(pt == default_pt); 235 | } 236 | 237 | } 238 | 239 | int main() 240 | { 241 | using namespace boost::property_tree; 242 | test_info_parser(); 243 | test_info_parser(); 244 | #ifndef BOOST_NO_CWCHAR 245 | test_info_parser(); 246 | test_info_parser(); 247 | #endif 248 | return boost::report_errors(); 249 | } 250 | -------------------------------------------------------------------------------- /test/test_ini_parser.cpp: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------------- 2 | // Copyright (C) 2002-2006 Marcin Kalicinski 3 | // 4 | // Distributed under the Boost Software License, Version 1.0. 5 | // (See accompanying file LICENSE_1_0.txt or copy at 6 | // http://www.boost.org/LICENSE_1_0.txt) 7 | // 8 | // For more information, see www.boost.org 9 | // ---------------------------------------------------------------------------- 10 | 11 | #include "test_utils.hpp" 12 | #include 13 | #include 14 | 15 | using namespace boost::property_tree; 16 | 17 | /////////////////////////////////////////////////////////////////////////////// 18 | // Test data 19 | 20 | // Correct data 21 | const char *ok_data_1 = 22 | "\n" 23 | "; Comment\n" 24 | "[Section1]\n" 25 | "\t \t; Comment\n" 26 | " Key1=Data1\n" 27 | " \n" 28 | " Key2 = Data2\n" 29 | "Key 3 = Data 3 \n" 30 | "Key4=Data4\n" 31 | "[Section2] ;Comment\n" 32 | "\t \tKey1=Data4\n"; 33 | 34 | // Correct data 35 | const char *ok_data_2 = 36 | "[Section1]\n" 37 | "Key1=Data1"; // No eol 38 | 39 | // Correct data 40 | const char *ok_data_3 = 41 | ""; 42 | 43 | // Correct data 44 | const char *ok_data_4 = 45 | ";Comment"; 46 | 47 | // Correct data 48 | const char *ok_data_5 = 49 | "Key1=Data1\n" // No section 50 | "Key2=Data2\n"; 51 | 52 | // Treat # as comment. 53 | const char *ok_data_6 = 54 | "# Comment\n" 55 | "[Section1]\n" 56 | "Key1=Data1\n"; 57 | 58 | // Erroneous data 59 | const char *error_data_1 = 60 | "[Section1]\n" 61 | "Key1\n" // No equals sign 62 | "Key2=Data2"; 63 | 64 | // Erroneous data 65 | const char *error_data_2 = 66 | "[Section1]\n" 67 | "Key1=Data1\n" 68 | "=Data2\n"; // No key 69 | 70 | struct ReadFunc 71 | { 72 | template 73 | void operator()(const std::string &filename, Ptree &pt) const 74 | { 75 | read_ini(filename, pt); 76 | } 77 | }; 78 | 79 | struct WriteFunc 80 | { 81 | template 82 | void operator()(const std::string &filename, const Ptree &pt) const 83 | { 84 | write_ini(filename, pt); 85 | } 86 | }; 87 | 88 | void test_erroneous_write(const boost::property_tree::ptree &pt) 89 | { 90 | std::stringstream stream; 91 | try 92 | { 93 | write_ini(stream, pt); 94 | BOOST_ERROR("No required exception thrown"); 95 | } 96 | catch (ini_parser_error &e) 97 | { 98 | (void)e; 99 | } 100 | catch (...) 101 | { 102 | BOOST_ERROR("Wrong exception type thrown"); 103 | } 104 | } 105 | 106 | template 107 | void test_ini_parser() 108 | { 109 | generic_parser_test_ok 110 | ( 111 | ReadFunc(), WriteFunc(), ok_data_1, NULL, 112 | "testok1.ini", NULL, "testok1out.ini", 8, 26, 37 113 | ); 114 | 115 | generic_parser_test_ok 116 | ( 117 | ReadFunc(), WriteFunc(), ok_data_2, NULL, 118 | "testok2.ini", NULL, "testok2out.ini", 3, 5, 12 119 | ); 120 | 121 | generic_parser_test_ok 122 | ( 123 | ReadFunc(), WriteFunc(), ok_data_3, NULL, 124 | "testok3.ini", NULL, "testok3out.ini", 1, 0, 0 125 | ); 126 | 127 | generic_parser_test_ok 128 | ( 129 | ReadFunc(), WriteFunc(), ok_data_4, NULL, 130 | "testok4.ini", NULL, "testok4out.ini", 1, 0, 0 131 | ); 132 | 133 | generic_parser_test_ok 134 | ( 135 | ReadFunc(), WriteFunc(), ok_data_5, NULL, 136 | "testok5.ini", NULL, "testok5out.ini", 3, 10, 8 137 | ); 138 | 139 | generic_parser_test_ok 140 | ( 141 | ReadFunc(), WriteFunc(), ok_data_6, NULL, 142 | "testok6.ini", NULL, "testok6out.ini", 3, 5, 12 143 | ); 144 | 145 | generic_parser_test_error 146 | ( 147 | ReadFunc(), WriteFunc(), error_data_1, NULL, 148 | "testerr1.ini", NULL, "testerr1out.ini", 2 149 | ); 150 | 151 | generic_parser_test_error 152 | ( 153 | ReadFunc(), WriteFunc(), error_data_2, NULL, 154 | "testerr2.ini", NULL, "testerr2out.ini", 3 155 | ); 156 | } 157 | 158 | void test_unmappable_trees() 159 | { 160 | // Test too deep ptrees 161 | { 162 | ptree pt; 163 | pt.put_child("section.key.bogus", ptree()); 164 | test_erroneous_write(pt); 165 | } 166 | 167 | // Test duplicate sections 168 | { 169 | ptree pt; 170 | pt.push_back(std::make_pair("section", ptree())); 171 | pt.push_back(std::make_pair("section", ptree())); 172 | test_erroneous_write(pt); 173 | } 174 | 175 | // Test duplicate keys 176 | { 177 | ptree pt; 178 | ptree &child = pt.put_child("section", ptree()); 179 | child.push_back(std::make_pair("key", ptree())); 180 | child.push_back(std::make_pair("key", ptree())); 181 | test_erroneous_write(pt); 182 | } 183 | 184 | // Test mixed data and children. 185 | { 186 | ptree pt; 187 | ptree &child = pt.put_child("section", ptree("value")); 188 | child.push_back(std::make_pair("key", ptree())); 189 | child.push_back(std::make_pair("key", ptree())); 190 | test_erroneous_write(pt); 191 | } 192 | } 193 | 194 | void test_other_trees() 195 | { 196 | // Top-level keys must be written before any section. 197 | { 198 | ptree pt; 199 | pt.put("section.innerkey", "v1"); 200 | pt.put("nosection", "v2"); 201 | std::stringstream s; 202 | write_ini(s, pt); 203 | s.clear(); 204 | s.seekg(0, std::ios_base::beg); 205 | ptree result; 206 | read_ini(s, result); 207 | BOOST_TEST(result.get("section.innerkey", "bad") == "v1"); 208 | BOOST_TEST(result.get("nosection", "bad") == "v2"); 209 | } 210 | } 211 | 212 | int main() 213 | { 214 | test_ini_parser(); 215 | test_ini_parser(); 216 | #ifndef BOOST_NO_CWCHAR 217 | test_ini_parser(); 218 | test_ini_parser(); 219 | #endif 220 | 221 | test_unmappable_trees(); 222 | test_other_trees(); 223 | 224 | return boost::report_errors(); 225 | 226 | } 227 | -------------------------------------------------------------------------------- /test/test_json_parser3.cpp: -------------------------------------------------------------------------------- 1 | #define BOOST_BIND_NO_PLACEHOLDERS 2 | #include 3 | 4 | // Must be able to build with BOOST_BIND_NO_PLACEHOLDERS defined 5 | // History: https://github.com/boostorg/property_tree/pull/112#issuecomment-1812867565 6 | 7 | int main() {} 8 | -------------------------------------------------------------------------------- /test/test_multi_module1.cpp: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------------- 2 | // Copyright (C) 2002-2006 Marcin Kalicinski 3 | // 4 | // Distributed under the Boost Software License, Version 1.0. 5 | // (See accompanying file LICENSE_1_0.txt or copy at 6 | // http://www.boost.org/LICENSE_1_0.txt) 7 | // 8 | // For more information, see www.boost.org 9 | // ---------------------------------------------------------------------------- 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | void f(); 17 | 18 | int main() 19 | { 20 | f(); 21 | } 22 | -------------------------------------------------------------------------------- /test/test_multi_module2.cpp: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------------- 2 | // Copyright (C) 2002-2006 Marcin Kalicinski 3 | // 4 | // Distributed under the Boost Software License, Version 1.0. 5 | // (See accompanying file LICENSE_1_0.txt or copy at 6 | // http://www.boost.org/LICENSE_1_0.txt) 7 | // 8 | // For more information, see www.boost.org 9 | // ---------------------------------------------------------------------------- 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | void f() 17 | { 18 | } 19 | -------------------------------------------------------------------------------- /test/test_property_tree.cpp: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------------- 2 | // Copyright (C) 2002-2006 Marcin Kalicinski 3 | // 4 | // Distributed under the Boost Software License, Version 1.0. 5 | // (See accompanying file LICENSE_1_0.txt or copy at 6 | // http://www.boost.org/LICENSE_1_0.txt) 7 | // 8 | // For more information, see www.boost.org 9 | // ---------------------------------------------------------------------------- 10 | #include "test_utils.hpp" 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | // If using VC, disable some warnings that trip in boost::serialization bowels 18 | #ifdef BOOST_MSVC 19 | #pragma warning(disable:4267) // Narrowing conversion 20 | #pragma warning(disable:4996) // Deprecated functions 21 | #endif 22 | 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | // Predicate for sorting keys 32 | template 33 | struct SortPred 34 | { 35 | bool operator()(const typename Ptree::value_type &v1, 36 | const typename Ptree::value_type &v2) const 37 | { 38 | return v1.first < v2.first; 39 | } 40 | }; 41 | 42 | // Predicate for sorting keys in reverse 43 | template 44 | struct SortPredRev 45 | { 46 | bool operator()(const typename Ptree::value_type &v1, 47 | const typename Ptree::value_type &v2) const 48 | { 49 | return v1.first > v2.first; 50 | } 51 | }; 52 | 53 | // Custom translator that works with boost::any instead of std::string 54 | template 55 | struct any_translator 56 | { 57 | typedef boost::any internal_type; 58 | typedef E external_type; 59 | 60 | boost::optional get_value(const internal_type &v) { 61 | if(const E *p = boost::any_cast(&v)) { 62 | return *p; 63 | } 64 | return boost::optional(); 65 | } 66 | boost::optional put_value(const E &v) { 67 | return boost::any(v); 68 | } 69 | }; 70 | 71 | // Checks the validity of calling get_child with a default value type 72 | template 73 | using get_child_accepts_default_of_type = decltype( 74 | std::declval

().get_child(std::declval(), std::declval())); 75 | 76 | namespace boost { namespace property_tree { 77 | template 78 | struct translator_between 79 | { 80 | typedef any_translator type; 81 | }; 82 | }} 83 | 84 | // Include char tests, case sensitive 85 | #define CHTYPE char 86 | #define T(s) s 87 | #define PTREE boost::property_tree::ptree 88 | #define NOCASE 0 89 | #define WIDECHAR 0 90 | # include "test_property_tree.hpp" 91 | #undef CHTYPE 92 | #undef T 93 | #undef PTREE 94 | #undef NOCASE 95 | #undef WIDECHAR 96 | 97 | // Include wchar_t tests, case sensitive 98 | #ifndef BOOST_NO_CWCHAR 99 | # define CHTYPE wchar_t 100 | # define T(s) L ## s 101 | # define PTREE boost::property_tree::wptree 102 | # define NOCASE 0 103 | # define WIDECHAR 1 104 | # include "test_property_tree.hpp" 105 | # undef CHTYPE 106 | # undef T 107 | # undef PTREE 108 | # undef NOCASE 109 | # undef WIDECHAR 110 | #endif 111 | 112 | // Include char tests, case insensitive 113 | #define CHTYPE char 114 | #define T(s) s 115 | #define PTREE boost::property_tree::iptree 116 | #define NOCASE 1 117 | # define WIDECHAR 0 118 | # include "test_property_tree.hpp" 119 | #undef CHTYPE 120 | #undef T 121 | #undef PTREE 122 | #undef NOCASE 123 | #undef WIDECHAR 124 | 125 | // Include wchar_t tests, case insensitive 126 | #ifndef BOOST_NO_CWCHAR 127 | # define CHTYPE wchar_t 128 | # define T(s) L ## s 129 | # define PTREE boost::property_tree::wiptree 130 | # define NOCASE 1 131 | # define WIDECHAR 1 132 | # include "test_property_tree.hpp" 133 | # undef CHTYPE 134 | # undef T 135 | # undef PTREE 136 | # undef NOCASE 137 | # undef WIDECHAR 138 | #endif 139 | 140 | template 141 | void run_tests(Ptree* pt) 142 | { 143 | test_debug(pt); 144 | test_constructor_destructor_assignment(pt); 145 | test_insertion(pt); 146 | test_erasing(pt); 147 | test_clear(pt); 148 | test_pushpop(pt); 149 | test_container_iteration(pt); 150 | test_swap(pt); 151 | test_sort_reverse(pt); 152 | test_case(pt); 153 | test_comparison(pt); 154 | test_front_back(pt); 155 | test_get_put(pt); 156 | test_get_child_put_child(pt); 157 | test_equal_range(pt); 158 | test_path_separator(pt); 159 | test_path(pt); 160 | test_precision(pt); 161 | test_locale(pt); 162 | test_custom_data_type(pt); 163 | test_empty_size_max_size(pt); 164 | test_ptree_bad_path(pt); 165 | test_ptree_bad_data(pt); 166 | test_serialization(pt); 167 | test_bool(pt); 168 | test_char(pt); 169 | test_float(pt); 170 | test_sort(pt); 171 | test_leaks(pt); // must be a final test 172 | } 173 | 174 | int main(int, char *[]) 175 | { 176 | 177 | using namespace boost::property_tree; 178 | 179 | // char tests, case sensitive 180 | { 181 | ptree *pt = 0; 182 | run_tests(pt); 183 | } 184 | 185 | // wchar_t tests, case sensitive 186 | #ifndef BOOST_NO_CWCHAR 187 | { 188 | wptree *pt = 0; 189 | run_tests(pt); 190 | } 191 | #endif 192 | 193 | // char tests, case insensitive 194 | { 195 | iptree *pt = 0; 196 | run_tests(pt); 197 | } 198 | 199 | // wchar_t tests, case insensitive 200 | #ifndef BOOST_NO_CWCHAR 201 | { 202 | wiptree *pt = 0; 203 | run_tests(pt); 204 | } 205 | #endif 206 | 207 | return boost::report_errors(); 208 | } 209 | -------------------------------------------------------------------------------- /test/test_rapidxml.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | int main() {} 3 | -------------------------------------------------------------------------------- /test/test_xml_parser_common.hpp: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------------- 2 | // Copyright (C) 2002-2006 Marcin Kalicinski 3 | // 4 | // Distributed under the Boost Software License, Version 1.0. 5 | // (See accompanying file LICENSE_1_0.txt or copy at 6 | // http://www.boost.org/LICENSE_1_0.txt) 7 | // 8 | // For more information, see www.boost.org 9 | // ---------------------------------------------------------------------------- 10 | #ifndef TEST_XML_PARSER_COMMON_HPP_INCLUDED 11 | #define TEST_XML_PARSER_COMMON_HPP_INCLUDED 12 | 13 | #include "test_utils.hpp" 14 | #include 15 | #include "xml_parser_test_data.hpp" 16 | 17 | struct ReadFuncWS 18 | { 19 | template 20 | void operator()(const std::string &filename, Ptree &pt) const 21 | { 22 | boost::property_tree::read_xml(filename, pt, 23 | boost::property_tree::xml_parser::no_concat_text); 24 | } 25 | }; 26 | 27 | struct WriteFuncWS 28 | { 29 | template 30 | void operator()(const std::string &filename, const Ptree &pt) const 31 | { 32 | boost::property_tree::write_xml(filename, pt); 33 | } 34 | }; 35 | 36 | struct ReadFuncNS 37 | { 38 | template 39 | void operator()(const std::string &filename, Ptree &pt) const 40 | { 41 | boost::property_tree::read_xml(filename, pt, 42 | boost::property_tree::xml_parser::trim_whitespace); 43 | } 44 | }; 45 | 46 | struct WriteFuncNS 47 | { 48 | template 49 | void operator()(const std::string &filename, const Ptree &pt) const 50 | { 51 | boost::property_tree::write_xml(filename, pt, std::locale(), 52 | boost::property_tree::xml_writer_make_settings(' ', 4)); 53 | } 54 | }; 55 | 56 | template int umlautsize(); 57 | template <> inline int umlautsize() { return 2; } 58 | template <> inline int umlautsize() { return 1; } 59 | 60 | template 61 | void test_xml_parser() 62 | { 63 | 64 | using namespace boost::property_tree; 65 | typedef typename Ptree::data_type::value_type char_type; 66 | 67 | generic_parser_test_ok 68 | ( 69 | ReadFuncWS(), WriteFuncWS(), ok_data_1, NULL, 70 | "testok1.xml", NULL, "testok1out.xml", 2, 0, 5 71 | ); 72 | 73 | generic_parser_test_ok 74 | ( 75 | ReadFuncWS(), WriteFuncWS(), ok_data_2, NULL, 76 | "testok2a.xml", NULL, "testok2aout.xml", 15, 23, 89 77 | ); 78 | 79 | generic_parser_test_ok 80 | ( 81 | ReadFuncNS(), WriteFuncNS(), ok_data_2, NULL, 82 | "testok2b.xml", NULL, "testok2bout.xml", 6, 15, 8 83 | ); 84 | 85 | generic_parser_test_ok 86 | ( 87 | ReadFuncWS(), WriteFuncWS(), ok_data_3, NULL, 88 | "testok3a.xml", NULL, "testok3aout.xml", 1662, 35377, 11706 89 | ); 90 | 91 | generic_parser_test_ok 92 | ( 93 | ReadFuncNS(), WriteFuncNS(), ok_data_3, NULL, 94 | "testok3b.xml", NULL, "testok3bout.xml", 787, 31376, 3831 95 | ); 96 | 97 | generic_parser_test_ok 98 | ( 99 | ReadFuncWS(), WriteFuncWS(), ok_data_4, NULL, 100 | "testok4.xml", NULL, "testok4out.xml", 11, 7, 74 101 | ); 102 | 103 | generic_parser_test_ok 104 | ( 105 | ReadFuncWS(), WriteFuncWS(), ok_data_5, NULL, 106 | "testok5.xml", NULL, "testok5out.xml", 107 | 3, umlautsize(), 12 108 | ); 109 | 110 | generic_parser_test_error 111 | ( 112 | ReadFuncWS(), WriteFuncWS(), error_data_1, NULL, 113 | "testerr1.xml", NULL, "testerr1out.xml", 1 114 | ); 115 | 116 | generic_parser_test_error 117 | ( 118 | ReadFuncWS(), WriteFuncWS(), error_data_2, NULL, 119 | "testerr2.xml", NULL, "testerr2out.xml", 2 120 | ); 121 | 122 | generic_parser_test_ok 123 | ( 124 | ReadFuncWS(), WriteFuncWS(), bug_data_pr2855, NULL, 125 | "testpr2855.xml", NULL, "testpr2855out.xml", 3, 7, 14 126 | ); 127 | 128 | generic_parser_test_ok 129 | ( 130 | ReadFuncWS(), WriteFuncWS(), bug_data_pr1678, NULL, 131 | "testpr1678.xml", NULL, "testpr1678out.xml", 2, 0, 4 132 | ); 133 | 134 | generic_parser_test_ok 135 | ( 136 | ReadFuncWS(), WriteFuncWS(), bug_data_pr5203, NULL, 137 | "testpr5203.xml", NULL, "testpr5203out.xml", 138 | 3, 4 * umlautsize(), 13 139 | ); 140 | 141 | generic_parser_test_ok 142 | ( 143 | ReadFuncWS(), WriteFuncWS(), bug_data_pr4840, NULL, 144 | "testpr4840.xml", NULL, "testpr4840out.xml", 145 | 4, 13, 15 146 | ); 147 | 148 | } 149 | 150 | #endif 151 | -------------------------------------------------------------------------------- /test/test_xml_parser_rapidxml.cpp: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------------- 2 | // Copyright (C) 2002-2006 Marcin Kalicinski 3 | // Copyright (C) 2009-2010 Sebastian Redl 4 | // 5 | // Distributed under the Boost Software License, Version 1.0. 6 | // (See accompanying file LICENSE_1_0.txt or copy at 7 | // http://www.boost.org/LICENSE_1_0.txt) 8 | // 9 | // For more information, see www.boost.org 10 | // ---------------------------------------------------------------------------- 11 | 12 | #include "test_xml_parser_common.hpp" 13 | #include 14 | #define BOOST_UTF8_BEGIN_NAMESPACE namespace boost { namespace property_tree { 15 | #define BOOST_UTF8_END_NAMESPACE }} 16 | #define BOOST_UTF8_DECL 17 | #include 18 | #include 19 | 20 | int main(int , char *[]) 21 | { 22 | using namespace boost::property_tree; 23 | test_xml_parser(); 24 | test_xml_parser(); 25 | #ifndef BOOST_NO_CWCHAR 26 | using std::locale; 27 | // We need a UTF-8-aware global locale now. 28 | locale loc(locale(), new utf8_codecvt_facet); 29 | locale::global(loc); 30 | test_xml_parser(); 31 | test_xml_parser(); 32 | #endif 33 | return boost::report_errors(); 34 | } 35 | --------------------------------------------------------------------------------