Added boost header
This commit is contained in:
83
test/external/boost/property_tree/detail/exception_implementation.hpp
vendored
Normal file
83
test/external/boost/property_tree/detail/exception_implementation.hpp
vendored
Normal file
@@ -0,0 +1,83 @@
|
||||
// ----------------------------------------------------------------------------
|
||||
// Copyright (C) 2002-2006 Marcin Kalicinski
|
||||
// Copyright (C) 2009 Sebastian Redl
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// For more information, see www.boost.org
|
||||
// ----------------------------------------------------------------------------
|
||||
#ifndef BOOST_PROPERTY_TREE_DETAIL_EXCEPTIONS_IMPLEMENTATION_HPP_INCLUDED
|
||||
#define BOOST_PROPERTY_TREE_DETAIL_EXCEPTIONS_IMPLEMENTATION_HPP_INCLUDED
|
||||
|
||||
namespace boost { namespace property_tree
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
// Helper for preparing what string in ptree_bad_path exception
|
||||
template<class P> inline
|
||||
std::string prepare_bad_path_what(const std::string &what,
|
||||
const P &path)
|
||||
{
|
||||
return what + " (" + path.dump() + ")";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// ptree_error
|
||||
|
||||
inline ptree_error::ptree_error(const std::string &w):
|
||||
std::runtime_error(w)
|
||||
{
|
||||
}
|
||||
|
||||
inline ptree_error::~ptree_error() throw()
|
||||
{
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// ptree_bad_data
|
||||
|
||||
template<class D> inline
|
||||
ptree_bad_data::ptree_bad_data(const std::string &w, const D &d):
|
||||
ptree_error(w), m_data(d)
|
||||
{
|
||||
}
|
||||
|
||||
inline ptree_bad_data::~ptree_bad_data() throw()
|
||||
{
|
||||
}
|
||||
|
||||
template<class D> inline
|
||||
D ptree_bad_data::data()
|
||||
{
|
||||
return boost::any_cast<D>(m_data);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// ptree_bad_path
|
||||
|
||||
template<class P> inline
|
||||
ptree_bad_path::ptree_bad_path(const std::string &w, const P &p):
|
||||
ptree_error(detail::prepare_bad_path_what(w, p)), m_path(p)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
inline ptree_bad_path::~ptree_bad_path() throw()
|
||||
{
|
||||
}
|
||||
|
||||
template<class P> inline
|
||||
P ptree_bad_path::path()
|
||||
{
|
||||
return boost::any_cast<P>(m_path);
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
88
test/external/boost/property_tree/detail/file_parser_error.hpp
vendored
Normal file
88
test/external/boost/property_tree/detail/file_parser_error.hpp
vendored
Normal file
@@ -0,0 +1,88 @@
|
||||
// ----------------------------------------------------------------------------
|
||||
// Copyright (C) 2002-2006 Marcin Kalicinski
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// For more information, see www.boost.org
|
||||
// ----------------------------------------------------------------------------
|
||||
#ifndef BOOST_PROPERTY_TREE_DETAIL_FILE_PARSER_ERROR_HPP_INCLUDED
|
||||
#define BOOST_PROPERTY_TREE_DETAIL_FILE_PARSER_ERROR_HPP_INCLUDED
|
||||
|
||||
#include <boost/property_tree/ptree.hpp>
|
||||
#include <string>
|
||||
|
||||
namespace boost { namespace property_tree
|
||||
{
|
||||
|
||||
//! File parse error
|
||||
class file_parser_error: public ptree_error
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// Construction & destruction
|
||||
|
||||
// Construct error
|
||||
file_parser_error(const std::string &msg,
|
||||
const std::string &file,
|
||||
unsigned long l) :
|
||||
ptree_error(format_what(msg, file, l)),
|
||||
m_message(msg), m_filename(file), m_line(l)
|
||||
{
|
||||
}
|
||||
|
||||
~file_parser_error() throw()
|
||||
// gcc 3.4.2 complains about lack of throw specifier on compiler
|
||||
// generated dtor
|
||||
{
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// Data access
|
||||
|
||||
// Get error message (without line and file - use what() to get
|
||||
// full message)
|
||||
std::string message() const
|
||||
{
|
||||
return m_message;
|
||||
}
|
||||
|
||||
// Get error filename
|
||||
std::string filename() const
|
||||
{
|
||||
return m_filename;
|
||||
}
|
||||
|
||||
// Get error line number
|
||||
unsigned long line() const
|
||||
{
|
||||
return m_line;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
std::string m_message;
|
||||
std::string m_filename;
|
||||
unsigned long m_line;
|
||||
|
||||
// Format error message to be returned by std::runtime_error::what()
|
||||
static std::string format_what(const std::string &msg,
|
||||
const std::string &file,
|
||||
unsigned long l)
|
||||
{
|
||||
std::stringstream stream;
|
||||
stream << (file.empty() ? "<unspecified file>" : file.c_str());
|
||||
if (l > 0)
|
||||
stream << '(' << l << ')';
|
||||
stream << ": " << msg;
|
||||
return stream.str();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
} }
|
||||
|
||||
#endif
|
||||
32
test/external/boost/property_tree/detail/info_parser_error.hpp
vendored
Normal file
32
test/external/boost/property_tree/detail/info_parser_error.hpp
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
// ----------------------------------------------------------------------------
|
||||
// Copyright (C) 2002-2006 Marcin Kalicinski
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// For more information, see www.boost.org
|
||||
// ----------------------------------------------------------------------------
|
||||
#ifndef BOOST_PROPERTY_TREE_DETAIL_INFO_PARSER_ERROR_HPP_INCLUDED
|
||||
#define BOOST_PROPERTY_TREE_DETAIL_INFO_PARSER_ERROR_HPP_INCLUDED
|
||||
|
||||
#include <boost/property_tree/detail/file_parser_error.hpp>
|
||||
#include <string>
|
||||
|
||||
namespace boost { namespace property_tree { namespace info_parser
|
||||
{
|
||||
|
||||
class info_parser_error: public file_parser_error
|
||||
{
|
||||
public:
|
||||
info_parser_error(const std::string &message,
|
||||
const std::string &filename,
|
||||
unsigned long line) :
|
||||
file_parser_error(message, filename, line)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
} } }
|
||||
|
||||
#endif
|
||||
380
test/external/boost/property_tree/detail/info_parser_read.hpp
vendored
Normal file
380
test/external/boost/property_tree/detail/info_parser_read.hpp
vendored
Normal file
@@ -0,0 +1,380 @@
|
||||
// ----------------------------------------------------------------------------
|
||||
// Copyright (C) 2002-2006 Marcin Kalicinski
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// For more information, see www.boost.org
|
||||
// ----------------------------------------------------------------------------
|
||||
#ifndef BOOST_PROPERTY_TREE_DETAIL_INFO_PARSER_READ_HPP_INCLUDED
|
||||
#define BOOST_PROPERTY_TREE_DETAIL_INFO_PARSER_READ_HPP_INCLUDED
|
||||
|
||||
#include "boost/property_tree/ptree.hpp"
|
||||
#include "boost/property_tree/detail/info_parser_error.hpp"
|
||||
#include "boost/property_tree/detail/info_parser_utils.hpp"
|
||||
#include <iterator>
|
||||
#include <string>
|
||||
#include <stack>
|
||||
#include <fstream>
|
||||
#include <cctype>
|
||||
|
||||
namespace boost { namespace property_tree { namespace info_parser
|
||||
{
|
||||
|
||||
// Expand known escape sequences
|
||||
template<class It>
|
||||
std::basic_string<typename std::iterator_traits<It>::value_type>
|
||||
expand_escapes(It b, It e)
|
||||
{
|
||||
typedef typename std::iterator_traits<It>::value_type Ch;
|
||||
std::basic_string<Ch> result;
|
||||
while (b != e)
|
||||
{
|
||||
if (*b == Ch('\\'))
|
||||
{
|
||||
++b;
|
||||
if (b == e)
|
||||
{
|
||||
BOOST_PROPERTY_TREE_THROW(info_parser_error(
|
||||
"character expected after backslash", "", 0));
|
||||
}
|
||||
else if (*b == Ch('0')) result += Ch('\0');
|
||||
else if (*b == Ch('a')) result += Ch('\a');
|
||||
else if (*b == Ch('b')) result += Ch('\b');
|
||||
else if (*b == Ch('f')) result += Ch('\f');
|
||||
else if (*b == Ch('n')) result += Ch('\n');
|
||||
else if (*b == Ch('r')) result += Ch('\r');
|
||||
else if (*b == Ch('t')) result += Ch('\t');
|
||||
else if (*b == Ch('v')) result += Ch('\v');
|
||||
else if (*b == Ch('"')) result += Ch('"');
|
||||
else if (*b == Ch('\'')) result += Ch('\'');
|
||||
else if (*b == Ch('\\')) result += Ch('\\');
|
||||
else
|
||||
BOOST_PROPERTY_TREE_THROW(info_parser_error(
|
||||
"unknown escape sequence", "", 0));
|
||||
}
|
||||
else
|
||||
result += *b;
|
||||
++b;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// Advance pointer past whitespace
|
||||
template<class Ch>
|
||||
void skip_whitespace(const Ch *&text)
|
||||
{
|
||||
using namespace std;
|
||||
while (isspace(*text))
|
||||
++text;
|
||||
}
|
||||
|
||||
// Extract word (whitespace delimited) and advance pointer accordingly
|
||||
template<class Ch>
|
||||
std::basic_string<Ch> read_word(const Ch *&text)
|
||||
{
|
||||
using namespace std;
|
||||
skip_whitespace(text);
|
||||
const Ch *start = text;
|
||||
while (!isspace(*text) && *text != Ch(';') && *text != Ch('\0'))
|
||||
++text;
|
||||
return expand_escapes(start, text);
|
||||
}
|
||||
|
||||
// Extract line (eol delimited) and advance pointer accordingly
|
||||
template<class Ch>
|
||||
std::basic_string<Ch> read_line(const Ch *&text)
|
||||
{
|
||||
using namespace std;
|
||||
skip_whitespace(text);
|
||||
const Ch *start = text;
|
||||
while (*text != Ch('\0') && *text != Ch(';'))
|
||||
++text;
|
||||
while (text > start && isspace(*(text - 1)))
|
||||
--text;
|
||||
return expand_escapes(start, text);
|
||||
}
|
||||
|
||||
// Extract string (inside ""), and advance pointer accordingly
|
||||
// Set need_more_lines to true if \ continuator found
|
||||
template<class Ch>
|
||||
std::basic_string<Ch> read_string(const Ch *&text, bool *need_more_lines)
|
||||
{
|
||||
skip_whitespace(text);
|
||||
if (*text == Ch('\"'))
|
||||
{
|
||||
|
||||
// Skip "
|
||||
++text;
|
||||
|
||||
// Find end of string, but skip escaped "
|
||||
bool escaped = false;
|
||||
const Ch *start = text;
|
||||
while ((escaped || *text != Ch('\"')) && *text != Ch('\0'))
|
||||
{
|
||||
escaped = (!escaped && *text == Ch('\\'));
|
||||
++text;
|
||||
}
|
||||
|
||||
// If end of string found
|
||||
if (*text == Ch('\"'))
|
||||
{
|
||||
std::basic_string<Ch> result = expand_escapes(start, text++);
|
||||
skip_whitespace(text);
|
||||
if (*text == Ch('\\'))
|
||||
{
|
||||
if (!need_more_lines)
|
||||
BOOST_PROPERTY_TREE_THROW(info_parser_error(
|
||||
"unexpected \\", "", 0));
|
||||
++text;
|
||||
skip_whitespace(text);
|
||||
if (*text == Ch('\0') || *text == Ch(';'))
|
||||
*need_more_lines = true;
|
||||
else
|
||||
BOOST_PROPERTY_TREE_THROW(info_parser_error(
|
||||
"expected end of line after \\", "", 0));
|
||||
}
|
||||
else
|
||||
if (need_more_lines)
|
||||
*need_more_lines = false;
|
||||
return result;
|
||||
}
|
||||
else
|
||||
BOOST_PROPERTY_TREE_THROW(info_parser_error(
|
||||
"unexpected end of line", "", 0));
|
||||
|
||||
}
|
||||
else
|
||||
BOOST_PROPERTY_TREE_THROW(info_parser_error("expected \"", "", 0));
|
||||
}
|
||||
|
||||
// Extract key
|
||||
template<class Ch>
|
||||
std::basic_string<Ch> read_key(const Ch *&text)
|
||||
{
|
||||
skip_whitespace(text);
|
||||
if (*text == Ch('\"'))
|
||||
return read_string(text, NULL);
|
||||
else
|
||||
return read_word(text);
|
||||
}
|
||||
|
||||
// Extract data
|
||||
template<class Ch>
|
||||
std::basic_string<Ch> read_data(const Ch *&text, bool *need_more_lines)
|
||||
{
|
||||
skip_whitespace(text);
|
||||
if (*text == Ch('\"'))
|
||||
return read_string(text, need_more_lines);
|
||||
else
|
||||
{
|
||||
*need_more_lines = false;
|
||||
return read_word(text);
|
||||
}
|
||||
}
|
||||
|
||||
// Build ptree from info stream
|
||||
template<class Ptree, class Ch>
|
||||
void read_info_internal(std::basic_istream<Ch> &stream,
|
||||
Ptree &pt,
|
||||
const std::string &filename,
|
||||
int include_depth)
|
||||
{
|
||||
typedef std::basic_string<Ch> str_t;
|
||||
// Possible parser states
|
||||
enum state_t {
|
||||
s_key, // Parser expects key
|
||||
s_data, // Parser expects data
|
||||
s_data_cont // Parser expects data continuation
|
||||
};
|
||||
|
||||
unsigned long line_no = 0;
|
||||
state_t state = s_key; // Parser state
|
||||
Ptree *last = NULL; // Pointer to last created ptree
|
||||
// Define line here to minimize reallocations
|
||||
str_t line;
|
||||
|
||||
// Initialize ptree stack (used to handle nesting)
|
||||
std::stack<Ptree *> stack;
|
||||
stack.push(&pt); // Push root ptree on stack initially
|
||||
|
||||
try {
|
||||
// While there are characters in the stream
|
||||
while (stream.good()) {
|
||||
// Read one line from stream
|
||||
++line_no;
|
||||
std::getline(stream, line);
|
||||
if (!stream.good() && !stream.eof())
|
||||
BOOST_PROPERTY_TREE_THROW(info_parser_error(
|
||||
"read error", filename, line_no));
|
||||
const Ch *text = line.c_str();
|
||||
|
||||
// If directive found
|
||||
skip_whitespace(text);
|
||||
if (*text == Ch('#')) {
|
||||
// Determine directive type
|
||||
++text; // skip #
|
||||
std::basic_string<Ch> directive = read_word(text);
|
||||
if (directive == convert_chtype<Ch, char>("include")) {
|
||||
// #include
|
||||
if (include_depth > 100) {
|
||||
BOOST_PROPERTY_TREE_THROW(info_parser_error(
|
||||
"include depth too large, "
|
||||
"probably recursive include",
|
||||
filename, line_no));
|
||||
}
|
||||
str_t s = read_string(text, NULL);
|
||||
std::string inc_name =
|
||||
convert_chtype<char, Ch>(s.c_str());
|
||||
std::basic_ifstream<Ch> inc_stream(inc_name.c_str());
|
||||
if (!inc_stream.good())
|
||||
BOOST_PROPERTY_TREE_THROW(info_parser_error(
|
||||
"cannot open include file " + inc_name,
|
||||
filename, line_no));
|
||||
read_info_internal(inc_stream, *stack.top(),
|
||||
inc_name, include_depth + 1);
|
||||
} else { // Unknown directive
|
||||
BOOST_PROPERTY_TREE_THROW(info_parser_error(
|
||||
"unknown directive", filename, line_no));
|
||||
}
|
||||
|
||||
// Directive must be followed by end of line
|
||||
skip_whitespace(text);
|
||||
if (*text != Ch('\0')) {
|
||||
BOOST_PROPERTY_TREE_THROW(info_parser_error(
|
||||
"expected end of line", filename, line_no));
|
||||
}
|
||||
|
||||
// Go to next line
|
||||
continue;
|
||||
}
|
||||
|
||||
// While there are characters left in line
|
||||
while (1) {
|
||||
|
||||
// Stop parsing on end of line or comment
|
||||
skip_whitespace(text);
|
||||
if (*text == Ch('\0') || *text == Ch(';')) {
|
||||
if (state == s_data) // If there was no data set state to s_key
|
||||
state = s_key;
|
||||
break;
|
||||
}
|
||||
|
||||
// Process according to current parser state
|
||||
switch (state)
|
||||
{
|
||||
|
||||
// Parser expects key
|
||||
case s_key:
|
||||
{
|
||||
|
||||
if (*text == Ch('{')) // Brace opening found
|
||||
{
|
||||
if (!last)
|
||||
BOOST_PROPERTY_TREE_THROW(info_parser_error("unexpected {", "", 0));
|
||||
stack.push(last);
|
||||
last = NULL;
|
||||
++text;
|
||||
}
|
||||
else if (*text == Ch('}')) // Brace closing found
|
||||
{
|
||||
if (stack.size() <= 1)
|
||||
BOOST_PROPERTY_TREE_THROW(info_parser_error("unmatched }", "", 0));
|
||||
stack.pop();
|
||||
last = NULL;
|
||||
++text;
|
||||
}
|
||||
else // Key text found
|
||||
{
|
||||
std::basic_string<Ch> key = read_key(text);
|
||||
last = &stack.top()->push_back(
|
||||
std::make_pair(key, Ptree()))->second;
|
||||
state = s_data;
|
||||
}
|
||||
|
||||
}; break;
|
||||
|
||||
// Parser expects data
|
||||
case s_data:
|
||||
{
|
||||
|
||||
// Last ptree must be defined because we are going to add data to it
|
||||
BOOST_ASSERT(last);
|
||||
|
||||
if (*text == Ch('{')) // Brace opening found
|
||||
{
|
||||
stack.push(last);
|
||||
last = NULL;
|
||||
++text;
|
||||
state = s_key;
|
||||
}
|
||||
else if (*text == Ch('}')) // Brace closing found
|
||||
{
|
||||
if (stack.size() <= 1)
|
||||
BOOST_PROPERTY_TREE_THROW(info_parser_error("unmatched }", "", 0));
|
||||
stack.pop();
|
||||
last = NULL;
|
||||
++text;
|
||||
state = s_key;
|
||||
}
|
||||
else // Data text found
|
||||
{
|
||||
bool need_more_lines;
|
||||
std::basic_string<Ch> data = read_data(text, &need_more_lines);
|
||||
last->data() = data;
|
||||
state = need_more_lines ? s_data_cont : s_key;
|
||||
}
|
||||
|
||||
|
||||
}; break;
|
||||
|
||||
// Parser expects continuation of data after \ on previous line
|
||||
case s_data_cont:
|
||||
{
|
||||
|
||||
// Last ptree must be defined because we are going to update its data
|
||||
BOOST_ASSERT(last);
|
||||
|
||||
if (*text == Ch('\"')) // Continuation must start with "
|
||||
{
|
||||
bool need_more_lines;
|
||||
std::basic_string<Ch> data = read_string(text, &need_more_lines);
|
||||
last->put_value(last->template get_value<std::basic_string<Ch> >() + data);
|
||||
state = need_more_lines ? s_data_cont : s_key;
|
||||
}
|
||||
else
|
||||
BOOST_PROPERTY_TREE_THROW(info_parser_error("expected \" after \\ in previous line", "", 0));
|
||||
|
||||
}; break;
|
||||
|
||||
// Should never happen
|
||||
default:
|
||||
BOOST_ASSERT(0);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check if stack has initial size, otherwise some {'s have not been closed
|
||||
if (stack.size() != 1)
|
||||
BOOST_PROPERTY_TREE_THROW(info_parser_error("unmatched {", "", 0));
|
||||
|
||||
}
|
||||
catch (info_parser_error &e)
|
||||
{
|
||||
// If line undefined rethrow error with correct filename and line
|
||||
if (e.line() == 0)
|
||||
{
|
||||
BOOST_PROPERTY_TREE_THROW(info_parser_error(e.message(), filename, line_no));
|
||||
}
|
||||
else
|
||||
BOOST_PROPERTY_TREE_THROW(e);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} } }
|
||||
|
||||
#endif
|
||||
32
test/external/boost/property_tree/detail/info_parser_utils.hpp
vendored
Normal file
32
test/external/boost/property_tree/detail/info_parser_utils.hpp
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
// ----------------------------------------------------------------------------
|
||||
// Copyright (C) 2002-2006 Marcin Kalicinski
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// For more information, see www.boost.org
|
||||
// ----------------------------------------------------------------------------
|
||||
#ifndef BOOST_PROPERTY_TREE_DETAIL_INFO_PARSER_CHCONV_HPP_INCLUDED
|
||||
#define BOOST_PROPERTY_TREE_DETAIL_INFO_PARSER_CHCONV_HPP_INCLUDED
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace boost { namespace property_tree { namespace info_parser
|
||||
{
|
||||
|
||||
template<class ChDest, class ChSrc>
|
||||
std::basic_string<ChDest> convert_chtype(const ChSrc *text)
|
||||
{
|
||||
std::basic_string<ChDest> result;
|
||||
while (*text)
|
||||
{
|
||||
result += ChDest(*text);
|
||||
++text;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
} } }
|
||||
|
||||
#endif
|
||||
147
test/external/boost/property_tree/detail/info_parser_write.hpp
vendored
Normal file
147
test/external/boost/property_tree/detail/info_parser_write.hpp
vendored
Normal file
@@ -0,0 +1,147 @@
|
||||
// ----------------------------------------------------------------------------
|
||||
// Copyright (C) 2002-2006 Marcin Kalicinski
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// For more information, see www.boost.org
|
||||
// ----------------------------------------------------------------------------
|
||||
#ifndef BOOST_PROPERTY_TREE_DETAIL_INFO_PARSER_WRITE_HPP_INCLUDED
|
||||
#define BOOST_PROPERTY_TREE_DETAIL_INFO_PARSER_WRITE_HPP_INCLUDED
|
||||
|
||||
#include "boost/property_tree/ptree.hpp"
|
||||
#include "boost/property_tree/detail/info_parser_utils.hpp"
|
||||
#include <string>
|
||||
|
||||
namespace boost { namespace property_tree { namespace info_parser
|
||||
{
|
||||
template<class Ch>
|
||||
void write_info_indent(std::basic_ostream<Ch> &stream,
|
||||
int indent,
|
||||
const info_writer_settings<Ch> &settings
|
||||
)
|
||||
{
|
||||
stream << std::basic_string<Ch>(indent * settings.indent_count, settings.indent_char);
|
||||
}
|
||||
|
||||
// Create necessary escape sequences from illegal characters
|
||||
template<class Ch>
|
||||
std::basic_string<Ch> create_escapes(const std::basic_string<Ch> &s)
|
||||
{
|
||||
std::basic_string<Ch> result;
|
||||
typename std::basic_string<Ch>::const_iterator b = s.begin();
|
||||
typename std::basic_string<Ch>::const_iterator e = s.end();
|
||||
while (b != e)
|
||||
{
|
||||
if (*b == Ch('\0')) result += Ch('\\'), result += Ch('0');
|
||||
else if (*b == Ch('\a')) result += Ch('\\'), result += Ch('a');
|
||||
else if (*b == Ch('\b')) result += Ch('\\'), result += Ch('b');
|
||||
else if (*b == Ch('\f')) result += Ch('\\'), result += Ch('f');
|
||||
else if (*b == Ch('\n')) result += Ch('\\'), result += Ch('n');
|
||||
else if (*b == Ch('\r')) result += Ch('\\'), result += Ch('r');
|
||||
else if (*b == Ch('\v')) result += Ch('\\'), result += Ch('v');
|
||||
else if (*b == Ch('"')) result += Ch('\\'), result += Ch('"');
|
||||
else if (*b == Ch('\\')) result += Ch('\\'), result += Ch('\\');
|
||||
else
|
||||
result += *b;
|
||||
++b;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template<class Ch>
|
||||
bool is_simple_key(const std::basic_string<Ch> &key)
|
||||
{
|
||||
const static std::basic_string<Ch> chars = convert_chtype<Ch, char>(" \t{};\n\"");
|
||||
return !key.empty() && key.find_first_of(chars) == key.npos;
|
||||
}
|
||||
|
||||
template<class Ch>
|
||||
bool is_simple_data(const std::basic_string<Ch> &data)
|
||||
{
|
||||
const static std::basic_string<Ch> chars = convert_chtype<Ch, char>(" \t{};\n\"");
|
||||
return !data.empty() && data.find_first_of(chars) == data.npos;
|
||||
}
|
||||
|
||||
template<class Ptree>
|
||||
void write_info_helper(std::basic_ostream<typename Ptree::key_type::value_type> &stream,
|
||||
const Ptree &pt,
|
||||
int indent,
|
||||
const info_writer_settings<typename Ptree::key_type::value_type> &settings)
|
||||
{
|
||||
|
||||
// Character type
|
||||
typedef typename Ptree::key_type::value_type Ch;
|
||||
|
||||
// Write data
|
||||
if (indent >= 0)
|
||||
{
|
||||
if (!pt.data().empty())
|
||||
{
|
||||
std::basic_string<Ch> data = create_escapes(pt.template get_value<std::basic_string<Ch> >());
|
||||
if (is_simple_data(data))
|
||||
stream << Ch(' ') << data << Ch('\n');
|
||||
else
|
||||
stream << Ch(' ') << Ch('\"') << data << Ch('\"') << Ch('\n');
|
||||
}
|
||||
else if (pt.empty())
|
||||
stream << Ch(' ') << Ch('\"') << Ch('\"') << Ch('\n');
|
||||
else
|
||||
stream << Ch('\n');
|
||||
}
|
||||
|
||||
// Write keys
|
||||
if (!pt.empty())
|
||||
{
|
||||
|
||||
// Open brace
|
||||
if (indent >= 0)
|
||||
{
|
||||
write_info_indent( stream, indent, settings);
|
||||
stream << Ch('{') << Ch('\n');
|
||||
}
|
||||
|
||||
// Write keys
|
||||
typename Ptree::const_iterator it = pt.begin();
|
||||
for (; it != pt.end(); ++it)
|
||||
{
|
||||
|
||||
// Output key
|
||||
std::basic_string<Ch> key = create_escapes(it->first);
|
||||
write_info_indent( stream, indent+1, settings);
|
||||
if (is_simple_key(key))
|
||||
stream << key;
|
||||
else
|
||||
stream << Ch('\"') << key << Ch('\"');
|
||||
|
||||
// Output data and children
|
||||
write_info_helper(stream, it->second, indent + 1, settings);
|
||||
|
||||
}
|
||||
|
||||
// Close brace
|
||||
if (indent >= 0)
|
||||
{
|
||||
write_info_indent( stream, indent, settings);
|
||||
stream << Ch('}') << Ch('\n');
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// Write ptree to info stream
|
||||
template<class Ptree>
|
||||
void write_info_internal(std::basic_ostream<typename Ptree::key_type::value_type> &stream,
|
||||
const Ptree &pt,
|
||||
const std::string &filename,
|
||||
const info_writer_settings<typename Ptree::key_type::value_type> &settings)
|
||||
{
|
||||
write_info_helper(stream, pt, -1, settings);
|
||||
if (!stream.good())
|
||||
BOOST_PROPERTY_TREE_THROW(info_parser_error("write error", filename, 0));
|
||||
}
|
||||
|
||||
} } }
|
||||
|
||||
#endif
|
||||
40
test/external/boost/property_tree/detail/info_parser_writer_settings.hpp
vendored
Normal file
40
test/external/boost/property_tree/detail/info_parser_writer_settings.hpp
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
// ----------------------------------------------------------------------------
|
||||
// Copyright (C) 2002-2006 Marcin Kalicinski
|
||||
// Copyright (C) 2007 Alexey Baskakov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// For more information, see www.boost.org
|
||||
// ----------------------------------------------------------------------------
|
||||
#ifndef BOOST_PROPERTY_TREE_DETAIL_INFO_PARSER_WRITER_SETTINGS_HPP_INCLUDED
|
||||
#define BOOST_PROPERTY_TREE_DETAIL_INFO_PARSER_WRITER_SETTINGS_HPP_INCLUDED
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace boost { namespace property_tree { namespace info_parser
|
||||
{
|
||||
|
||||
template <class Ch>
|
||||
class info_writer_settings
|
||||
{
|
||||
public:
|
||||
info_writer_settings(Ch indent_char = Ch(' '), unsigned indent_count = 4):
|
||||
indent_char(indent_char),
|
||||
indent_count(indent_count)
|
||||
{
|
||||
}
|
||||
Ch indent_char;
|
||||
int indent_count;
|
||||
};
|
||||
|
||||
template <class Ch>
|
||||
info_writer_settings<Ch> info_writer_make_settings(Ch indent_char = Ch(' '), unsigned indent_count = 4)
|
||||
{
|
||||
return info_writer_settings<Ch>(indent_char, indent_count);
|
||||
}
|
||||
|
||||
} } }
|
||||
|
||||
#endif
|
||||
33
test/external/boost/property_tree/detail/json_parser_error.hpp
vendored
Normal file
33
test/external/boost/property_tree/detail/json_parser_error.hpp
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
// ----------------------------------------------------------------------------
|
||||
// Copyright (C) 2002-2006 Marcin Kalicinski
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// For more information, see www.boost.org
|
||||
// ----------------------------------------------------------------------------
|
||||
#ifndef BOOST_PROPERTY_TREE_DETAIL_JSON_PARSER_ERROR_HPP_INCLUDED
|
||||
#define BOOST_PROPERTY_TREE_DETAIL_JSON_PARSER_ERROR_HPP_INCLUDED
|
||||
|
||||
#include <boost/property_tree/detail/file_parser_error.hpp>
|
||||
#include <string>
|
||||
|
||||
namespace boost { namespace property_tree { namespace json_parser
|
||||
{
|
||||
|
||||
//! Json parser error
|
||||
class json_parser_error: public file_parser_error
|
||||
{
|
||||
public:
|
||||
json_parser_error(const std::string &message,
|
||||
const std::string &filename,
|
||||
unsigned long line):
|
||||
file_parser_error(message, filename, line)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
} } }
|
||||
|
||||
#endif
|
||||
331
test/external/boost/property_tree/detail/json_parser_read.hpp
vendored
Normal file
331
test/external/boost/property_tree/detail/json_parser_read.hpp
vendored
Normal file
@@ -0,0 +1,331 @@
|
||||
// ----------------------------------------------------------------------------
|
||||
// Copyright (C) 2002-2006 Marcin Kalicinski
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// For more information, see www.boost.org
|
||||
// ----------------------------------------------------------------------------
|
||||
#ifndef BOOST_PROPERTY_TREE_DETAIL_JSON_PARSER_READ_HPP_INCLUDED
|
||||
#define BOOST_PROPERTY_TREE_DETAIL_JSON_PARSER_READ_HPP_INCLUDED
|
||||
|
||||
//#define BOOST_SPIRIT_DEBUG
|
||||
|
||||
#include <boost/property_tree/ptree.hpp>
|
||||
#include <boost/property_tree/detail/ptree_utils.hpp>
|
||||
#include <boost/property_tree/detail/json_parser_error.hpp>
|
||||
#include <boost/spirit/include/classic.hpp>
|
||||
#include <boost/limits.hpp>
|
||||
#include <string>
|
||||
#include <locale>
|
||||
#include <istream>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
namespace boost { namespace property_tree { namespace json_parser
|
||||
{
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// Json parser context
|
||||
|
||||
template<class Ptree>
|
||||
struct context
|
||||
{
|
||||
|
||||
typedef typename Ptree::key_type::value_type Ch;
|
||||
typedef std::basic_string<Ch> Str;
|
||||
typedef typename std::vector<Ch>::iterator It;
|
||||
|
||||
Str string;
|
||||
Str name;
|
||||
Ptree root;
|
||||
std::vector<Ptree *> stack;
|
||||
|
||||
struct a_object_s
|
||||
{
|
||||
context &c;
|
||||
a_object_s(context &c): c(c) { }
|
||||
void operator()(Ch) const
|
||||
{
|
||||
if (c.stack.empty())
|
||||
c.stack.push_back(&c.root);
|
||||
else
|
||||
{
|
||||
Ptree *parent = c.stack.back();
|
||||
Ptree *child = &parent->push_back(std::make_pair(c.name, Ptree()))->second;
|
||||
c.stack.push_back(child);
|
||||
c.name.clear();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct a_object_e
|
||||
{
|
||||
context &c;
|
||||
a_object_e(context &c): c(c) { }
|
||||
void operator()(Ch) const
|
||||
{
|
||||
BOOST_ASSERT(c.stack.size() >= 1);
|
||||
c.stack.pop_back();
|
||||
}
|
||||
};
|
||||
|
||||
struct a_name
|
||||
{
|
||||
context &c;
|
||||
a_name(context &c): c(c) { }
|
||||
void operator()(It, It) const
|
||||
{
|
||||
c.name.swap(c.string);
|
||||
c.string.clear();
|
||||
}
|
||||
};
|
||||
|
||||
struct a_string_val
|
||||
{
|
||||
context &c;
|
||||
a_string_val(context &c): c(c) { }
|
||||
void operator()(It, It) const
|
||||
{
|
||||
BOOST_ASSERT(c.stack.size() >= 1);
|
||||
c.stack.back()->push_back(std::make_pair(c.name, Ptree(c.string)));
|
||||
c.name.clear();
|
||||
c.string.clear();
|
||||
}
|
||||
};
|
||||
|
||||
struct a_literal_val
|
||||
{
|
||||
context &c;
|
||||
a_literal_val(context &c): c(c) { }
|
||||
void operator()(It b, It e) const
|
||||
{
|
||||
BOOST_ASSERT(c.stack.size() >= 1);
|
||||
c.stack.back()->push_back(std::make_pair(c.name, Str(b, e)));
|
||||
c.name.clear();
|
||||
c.string.clear();
|
||||
}
|
||||
};
|
||||
|
||||
struct a_char
|
||||
{
|
||||
context &c;
|
||||
a_char(context &c): c(c) { }
|
||||
void operator()(It b, It e) const
|
||||
{
|
||||
c.string += *b;
|
||||
}
|
||||
};
|
||||
|
||||
struct a_escape
|
||||
{
|
||||
context &c;
|
||||
a_escape(context &c): c(c) { }
|
||||
void operator()(Ch ch) const
|
||||
{
|
||||
switch (ch)
|
||||
{
|
||||
case Ch('\"'): c.string += Ch('\"'); break;
|
||||
case Ch('\\'): c.string += Ch('\\'); break;
|
||||
case Ch('/'): c.string += Ch('/'); break;
|
||||
case Ch('b'): c.string += Ch('\b'); break;
|
||||
case Ch('f'): c.string += Ch('\f'); break;
|
||||
case Ch('n'): c.string += Ch('\n'); break;
|
||||
case Ch('r'): c.string += Ch('\r'); break;
|
||||
case Ch('t'): c.string += Ch('\t'); break;
|
||||
default: BOOST_ASSERT(0);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct a_unicode
|
||||
{
|
||||
context &c;
|
||||
a_unicode(context &c): c(c) { }
|
||||
void operator()(unsigned long u) const
|
||||
{
|
||||
u = (std::min)(u, static_cast<unsigned long>((std::numeric_limits<Ch>::max)()));
|
||||
c.string += Ch(u);
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// Json grammar
|
||||
|
||||
template<class Ptree>
|
||||
struct json_grammar :
|
||||
public boost::spirit::classic::grammar<json_grammar<Ptree> >
|
||||
{
|
||||
|
||||
typedef context<Ptree> Context;
|
||||
typedef typename Ptree::key_type::value_type Ch;
|
||||
|
||||
mutable Context c;
|
||||
|
||||
template<class Scanner>
|
||||
struct definition
|
||||
{
|
||||
|
||||
boost::spirit::classic::rule<Scanner>
|
||||
root, object, member, array, item, value, string, number;
|
||||
boost::spirit::classic::rule<
|
||||
typename boost::spirit::classic::lexeme_scanner<Scanner>::type>
|
||||
character, escape;
|
||||
|
||||
definition(const json_grammar &self)
|
||||
{
|
||||
|
||||
using namespace boost::spirit::classic;
|
||||
// There's a boost::assertion too, so another explicit using
|
||||
// here:
|
||||
using boost::spirit::classic::assertion;
|
||||
|
||||
// Assertions
|
||||
assertion<std::string> expect_root("expected object or array");
|
||||
assertion<std::string> expect_eoi("expected end of input");
|
||||
assertion<std::string> expect_objclose("expected ',' or '}'");
|
||||
assertion<std::string> expect_arrclose("expected ',' or ']'");
|
||||
assertion<std::string> expect_name("expected object name");
|
||||
assertion<std::string> expect_colon("expected ':'");
|
||||
assertion<std::string> expect_value("expected value");
|
||||
assertion<std::string> expect_escape("invalid escape sequence");
|
||||
|
||||
// JSON grammar rules
|
||||
root
|
||||
= expect_root(object | array)
|
||||
>> expect_eoi(end_p)
|
||||
;
|
||||
|
||||
object
|
||||
= ch_p('{')[typename Context::a_object_s(self.c)]
|
||||
>> (ch_p('}')[typename Context::a_object_e(self.c)]
|
||||
| (list_p(member, ch_p(','))
|
||||
>> expect_objclose(ch_p('}')[typename Context::a_object_e(self.c)])
|
||||
)
|
||||
)
|
||||
;
|
||||
|
||||
member
|
||||
= expect_name(string[typename Context::a_name(self.c)])
|
||||
>> expect_colon(ch_p(':'))
|
||||
>> expect_value(value)
|
||||
;
|
||||
|
||||
array
|
||||
= ch_p('[')[typename Context::a_object_s(self.c)]
|
||||
>> (ch_p(']')[typename Context::a_object_e(self.c)]
|
||||
| (list_p(item, ch_p(','))
|
||||
>> expect_arrclose(ch_p(']')[typename Context::a_object_e(self.c)])
|
||||
)
|
||||
)
|
||||
;
|
||||
|
||||
item
|
||||
= expect_value(value)
|
||||
;
|
||||
|
||||
value
|
||||
= string[typename Context::a_string_val(self.c)]
|
||||
| (number | str_p("true") | "false" | "null")[typename Context::a_literal_val(self.c)]
|
||||
| object
|
||||
| array
|
||||
;
|
||||
|
||||
number
|
||||
= !ch_p("-") >>
|
||||
(ch_p("0") | (range_p(Ch('1'), Ch('9')) >> *digit_p)) >>
|
||||
!(ch_p(".") >> +digit_p) >>
|
||||
!(chset_p(detail::widen<Ch>("eE").c_str()) >>
|
||||
!chset_p(detail::widen<Ch>("-+").c_str()) >>
|
||||
+digit_p)
|
||||
;
|
||||
|
||||
string
|
||||
= +(lexeme_d[confix_p('\"', *character, '\"')])
|
||||
;
|
||||
|
||||
character
|
||||
= (anychar_p - "\\" - "\"")
|
||||
[typename Context::a_char(self.c)]
|
||||
| ch_p("\\") >> expect_escape(escape)
|
||||
;
|
||||
|
||||
escape
|
||||
= chset_p(detail::widen<Ch>("\"\\/bfnrt").c_str())
|
||||
[typename Context::a_escape(self.c)]
|
||||
| 'u' >> uint_parser<unsigned long, 16, 4, 4>()
|
||||
[typename Context::a_unicode(self.c)]
|
||||
;
|
||||
|
||||
// Debug
|
||||
BOOST_SPIRIT_DEBUG_RULE(root);
|
||||
BOOST_SPIRIT_DEBUG_RULE(object);
|
||||
BOOST_SPIRIT_DEBUG_RULE(member);
|
||||
BOOST_SPIRIT_DEBUG_RULE(array);
|
||||
BOOST_SPIRIT_DEBUG_RULE(item);
|
||||
BOOST_SPIRIT_DEBUG_RULE(value);
|
||||
BOOST_SPIRIT_DEBUG_RULE(string);
|
||||
BOOST_SPIRIT_DEBUG_RULE(number);
|
||||
BOOST_SPIRIT_DEBUG_RULE(escape);
|
||||
BOOST_SPIRIT_DEBUG_RULE(character);
|
||||
|
||||
}
|
||||
|
||||
const boost::spirit::classic::rule<Scanner> &start() const
|
||||
{
|
||||
return root;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
template<class It, class Ch>
|
||||
unsigned long count_lines(It begin, It end)
|
||||
{
|
||||
return static_cast<unsigned long>(std::count(begin, end, Ch('\n')) + 1);
|
||||
}
|
||||
|
||||
template<class Ptree>
|
||||
void read_json_internal(std::basic_istream<typename Ptree::key_type::value_type> &stream,
|
||||
Ptree &pt,
|
||||
const std::string &filename)
|
||||
{
|
||||
|
||||
using namespace boost::spirit::classic;
|
||||
typedef typename Ptree::key_type::value_type Ch;
|
||||
typedef typename std::vector<Ch>::iterator It;
|
||||
|
||||
// Load data into vector
|
||||
std::vector<Ch> v(std::istreambuf_iterator<Ch>(stream.rdbuf()),
|
||||
std::istreambuf_iterator<Ch>());
|
||||
if (!stream.good())
|
||||
BOOST_PROPERTY_TREE_THROW(json_parser_error("read error", filename, 0));
|
||||
|
||||
// Prepare grammar
|
||||
json_grammar<Ptree> g;
|
||||
|
||||
// Parse
|
||||
try
|
||||
{
|
||||
parse_info<It> pi = parse(v.begin(), v.end(), g,
|
||||
space_p | comment_p("//") | comment_p("/*", "*/"));
|
||||
if (!pi.hit || !pi.full)
|
||||
BOOST_PROPERTY_TREE_THROW((parser_error<std::string, It>(v.begin(), "syntax error")));
|
||||
}
|
||||
catch (parser_error<std::string, It> &e)
|
||||
{
|
||||
BOOST_PROPERTY_TREE_THROW(json_parser_error(e.descriptor, filename, count_lines<It, Ch>(v.begin(), e.where)));
|
||||
}
|
||||
|
||||
// Swap grammar context root and pt
|
||||
pt.swap(g.c.root);
|
||||
|
||||
}
|
||||
|
||||
} } }
|
||||
|
||||
#endif
|
||||
170
test/external/boost/property_tree/detail/json_parser_write.hpp
vendored
Normal file
170
test/external/boost/property_tree/detail/json_parser_write.hpp
vendored
Normal file
@@ -0,0 +1,170 @@
|
||||
// ----------------------------------------------------------------------------
|
||||
// Copyright (C) 2002-2006 Marcin Kalicinski
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// For more information, see www.boost.org
|
||||
// ----------------------------------------------------------------------------
|
||||
#ifndef BOOST_PROPERTY_TREE_DETAIL_JSON_PARSER_WRITE_HPP_INCLUDED
|
||||
#define BOOST_PROPERTY_TREE_DETAIL_JSON_PARSER_WRITE_HPP_INCLUDED
|
||||
|
||||
#include <boost/property_tree/ptree.hpp>
|
||||
#include <boost/next_prior.hpp>
|
||||
#include <boost/type_traits/make_unsigned.hpp>
|
||||
#include <string>
|
||||
#include <ostream>
|
||||
#include <iomanip>
|
||||
|
||||
namespace boost { namespace property_tree { namespace json_parser
|
||||
{
|
||||
|
||||
// Create necessary escape sequences from illegal characters
|
||||
template<class Ch>
|
||||
std::basic_string<Ch> create_escapes(const std::basic_string<Ch> &s)
|
||||
{
|
||||
std::basic_string<Ch> result;
|
||||
typename std::basic_string<Ch>::const_iterator b = s.begin();
|
||||
typename std::basic_string<Ch>::const_iterator e = s.end();
|
||||
while (b != e)
|
||||
{
|
||||
// This assumes an ASCII superset. But so does everything in PTree.
|
||||
// We escape everything outside ASCII, because this code can't
|
||||
// handle high unicode characters.
|
||||
if (*b == 0x20 || *b == 0x21 || (*b >= 0x23 && *b <= 0x2E) ||
|
||||
(*b >= 0x30 && *b <= 0x5B) || (*b >= 0x5D && *b <= 0xFF))
|
||||
result += *b;
|
||||
else if (*b == Ch('\b')) result += Ch('\\'), result += Ch('b');
|
||||
else if (*b == Ch('\f')) result += Ch('\\'), result += Ch('f');
|
||||
else if (*b == Ch('\n')) result += Ch('\\'), result += Ch('n');
|
||||
else if (*b == Ch('\r')) result += Ch('\\'), result += Ch('r');
|
||||
else if (*b == Ch('/')) result += Ch('\\'), result += Ch('/');
|
||||
else if (*b == Ch('"')) result += Ch('\\'), result += Ch('"');
|
||||
else if (*b == Ch('\\')) result += Ch('\\'), result += Ch('\\');
|
||||
else
|
||||
{
|
||||
const char *hexdigits = "0123456789ABCDEF";
|
||||
typedef typename make_unsigned<Ch>::type UCh;
|
||||
unsigned long u = (std::min)(static_cast<unsigned long>(
|
||||
static_cast<UCh>(*b)),
|
||||
0xFFFFul);
|
||||
int d1 = u / 4096; u -= d1 * 4096;
|
||||
int d2 = u / 256; u -= d2 * 256;
|
||||
int d3 = u / 16; u -= d3 * 16;
|
||||
int d4 = u;
|
||||
result += Ch('\\'); result += Ch('u');
|
||||
result += Ch(hexdigits[d1]); result += Ch(hexdigits[d2]);
|
||||
result += Ch(hexdigits[d3]); result += Ch(hexdigits[d4]);
|
||||
}
|
||||
++b;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template<class Ptree>
|
||||
void write_json_helper(std::basic_ostream<typename Ptree::key_type::value_type> &stream,
|
||||
const Ptree &pt,
|
||||
int indent, bool pretty)
|
||||
{
|
||||
|
||||
typedef typename Ptree::key_type::value_type Ch;
|
||||
typedef typename std::basic_string<Ch> Str;
|
||||
|
||||
// Value or object or array
|
||||
if (indent > 0 && pt.empty())
|
||||
{
|
||||
// Write value
|
||||
Str data = create_escapes(pt.template get_value<Str>());
|
||||
stream << Ch('"') << data << Ch('"');
|
||||
|
||||
}
|
||||
else if (indent > 0 && pt.count(Str()) == pt.size())
|
||||
{
|
||||
// Write array
|
||||
stream << Ch('[');
|
||||
if (pretty) stream << Ch('\n');
|
||||
typename Ptree::const_iterator it = pt.begin();
|
||||
for (; it != pt.end(); ++it)
|
||||
{
|
||||
if (pretty) stream << Str(4 * (indent + 1), Ch(' '));
|
||||
write_json_helper(stream, it->second, indent + 1, pretty);
|
||||
if (boost::next(it) != pt.end())
|
||||
stream << Ch(',');
|
||||
if (pretty) stream << Ch('\n');
|
||||
}
|
||||
stream << Str(4 * indent, Ch(' ')) << Ch(']');
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
// Write object
|
||||
stream << Ch('{');
|
||||
if (pretty) stream << Ch('\n');
|
||||
typename Ptree::const_iterator it = pt.begin();
|
||||
for (; it != pt.end(); ++it)
|
||||
{
|
||||
if (pretty) stream << Str(4 * (indent + 1), Ch(' '));
|
||||
stream << Ch('"') << create_escapes(it->first) << Ch('"') << Ch(':');
|
||||
if (pretty) {
|
||||
if (it->second.empty())
|
||||
stream << Ch(' ');
|
||||
else
|
||||
stream << Ch('\n') << Str(4 * (indent + 1), Ch(' '));
|
||||
}
|
||||
write_json_helper(stream, it->second, indent + 1, pretty);
|
||||
if (boost::next(it) != pt.end())
|
||||
stream << Ch(',');
|
||||
if (pretty) stream << Ch('\n');
|
||||
}
|
||||
if (pretty) stream << Str(4 * indent, Ch(' '));
|
||||
stream << Ch('}');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Verify if ptree does not contain information that cannot be written to json
|
||||
template<class Ptree>
|
||||
bool verify_json(const Ptree &pt, int depth)
|
||||
{
|
||||
|
||||
typedef typename Ptree::key_type::value_type Ch;
|
||||
typedef typename std::basic_string<Ch> Str;
|
||||
|
||||
// Root ptree cannot have data
|
||||
if (depth == 0 && !pt.template get_value<Str>().empty())
|
||||
return false;
|
||||
|
||||
// Ptree cannot have both children and data
|
||||
if (!pt.template get_value<Str>().empty() && !pt.empty())
|
||||
return false;
|
||||
|
||||
// Check children
|
||||
typename Ptree::const_iterator it = pt.begin();
|
||||
for (; it != pt.end(); ++it)
|
||||
if (!verify_json(it->second, depth + 1))
|
||||
return false;
|
||||
|
||||
// Success
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
// Write ptree to json stream
|
||||
template<class Ptree>
|
||||
void write_json_internal(std::basic_ostream<typename Ptree::key_type::value_type> &stream,
|
||||
const Ptree &pt,
|
||||
const std::string &filename,
|
||||
bool pretty)
|
||||
{
|
||||
if (!verify_json(pt, 0))
|
||||
BOOST_PROPERTY_TREE_THROW(json_parser_error("ptree contains data that cannot be represented in JSON format", filename, 0));
|
||||
write_json_helper(stream, pt, 0, pretty);
|
||||
stream << std::endl;
|
||||
if (!stream.good())
|
||||
BOOST_PROPERTY_TREE_THROW(json_parser_error("write error", filename, 0));
|
||||
}
|
||||
|
||||
} } }
|
||||
|
||||
#endif
|
||||
905
test/external/boost/property_tree/detail/ptree_implementation.hpp
vendored
Normal file
905
test/external/boost/property_tree/detail/ptree_implementation.hpp
vendored
Normal file
@@ -0,0 +1,905 @@
|
||||
// ----------------------------------------------------------------------------
|
||||
// Copyright (C) 2002-2006 Marcin Kalicinski
|
||||
// Copyright (C) 2009 Sebastian Redl
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// For more information, see www.boost.org
|
||||
// ----------------------------------------------------------------------------
|
||||
#ifndef BOOST_PROPERTY_TREE_DETAIL_PTREE_IMPLEMENTATION_HPP_INCLUDED
|
||||
#define BOOST_PROPERTY_TREE_DETAIL_PTREE_IMPLEMENTATION_HPP_INCLUDED
|
||||
|
||||
#include <boost/iterator/iterator_adaptor.hpp>
|
||||
#include <boost/iterator/reverse_iterator.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
#include <memory>
|
||||
|
||||
#if defined(BOOST_MSVC) && \
|
||||
(_MSC_FULL_VER >= 160000000 && _MSC_FULL_VER < 170000000)
|
||||
#define BOOST_PROPERTY_TREE_PAIR_BUG
|
||||
#endif
|
||||
|
||||
namespace boost { namespace property_tree
|
||||
{
|
||||
template <class K, class D, class C>
|
||||
struct basic_ptree<K, D, C>::subs
|
||||
{
|
||||
struct by_name {};
|
||||
// The actual child container.
|
||||
#if defined(BOOST_PROPERTY_TREE_PAIR_BUG)
|
||||
// MSVC 10 has moved std::pair's members to a base
|
||||
// class. Unfortunately this does break the interface.
|
||||
BOOST_STATIC_CONSTANT(unsigned,
|
||||
first_offset = offsetof(value_type, first));
|
||||
typedef multi_index_container<value_type,
|
||||
multi_index::indexed_by<
|
||||
multi_index::sequenced<>,
|
||||
multi_index::ordered_non_unique<multi_index::tag<by_name>,
|
||||
multi_index::member_offset<value_type, const key_type,
|
||||
first_offset>,
|
||||
key_compare
|
||||
>
|
||||
>
|
||||
> base_container;
|
||||
#else
|
||||
typedef multi_index_container<value_type,
|
||||
multi_index::indexed_by<
|
||||
multi_index::sequenced<>,
|
||||
multi_index::ordered_non_unique<multi_index::tag<by_name>,
|
||||
multi_index::member<value_type, const key_type,
|
||||
&value_type::first>,
|
||||
key_compare
|
||||
>
|
||||
>
|
||||
> base_container;
|
||||
#endif
|
||||
// The by-name lookup index.
|
||||
typedef typename base_container::template index<by_name>::type
|
||||
by_name_index;
|
||||
|
||||
// Access functions for getting to the children of a tree.
|
||||
static base_container& ch(self_type *s) {
|
||||
return *static_cast<base_container*>(s->m_children);
|
||||
}
|
||||
static const base_container& ch(const self_type *s) {
|
||||
return *static_cast<const base_container*>(s->m_children);
|
||||
}
|
||||
static by_name_index& assoc(self_type *s) {
|
||||
return ch(s).BOOST_NESTED_TEMPLATE get<by_name>();
|
||||
}
|
||||
static const by_name_index& assoc(const self_type *s) {
|
||||
return ch(s).BOOST_NESTED_TEMPLATE get<by_name>();
|
||||
}
|
||||
};
|
||||
template <class K, class D, class C>
|
||||
class basic_ptree<K, D, C>::iterator : public boost::iterator_adaptor<
|
||||
iterator, typename subs::base_container::iterator, value_type>
|
||||
{
|
||||
friend class boost::iterator_core_access;
|
||||
typedef boost::iterator_adaptor<
|
||||
iterator, typename subs::base_container::iterator, value_type>
|
||||
baset;
|
||||
public:
|
||||
typedef typename baset::reference reference;
|
||||
iterator() {}
|
||||
explicit iterator(typename iterator::base_type b)
|
||||
: iterator::iterator_adaptor_(b)
|
||||
{}
|
||||
reference dereference() const
|
||||
{
|
||||
// multi_index doesn't allow modification of its values, because
|
||||
// indexes could sort by anything, and modification screws that up.
|
||||
// However, we only sort by the key, and it's protected against
|
||||
// modification in the value_type, so this const_cast is safe.
|
||||
return const_cast<reference>(*this->base_reference());
|
||||
}
|
||||
};
|
||||
template <class K, class D, class C>
|
||||
class basic_ptree<K, D, C>::const_iterator : public boost::iterator_adaptor<
|
||||
const_iterator, typename subs::base_container::const_iterator>
|
||||
{
|
||||
public:
|
||||
const_iterator() {}
|
||||
explicit const_iterator(typename const_iterator::base_type b)
|
||||
: const_iterator::iterator_adaptor_(b)
|
||||
{}
|
||||
const_iterator(iterator b)
|
||||
: const_iterator::iterator_adaptor_(b.base())
|
||||
{}
|
||||
};
|
||||
template <class K, class D, class C>
|
||||
class basic_ptree<K, D, C>::reverse_iterator
|
||||
: public boost::reverse_iterator<iterator>
|
||||
{
|
||||
public:
|
||||
reverse_iterator() {}
|
||||
explicit reverse_iterator(iterator b)
|
||||
: boost::reverse_iterator<iterator>(b)
|
||||
{}
|
||||
};
|
||||
template <class K, class D, class C>
|
||||
class basic_ptree<K, D, C>::const_reverse_iterator
|
||||
: public boost::reverse_iterator<const_iterator>
|
||||
{
|
||||
public:
|
||||
const_reverse_iterator() {}
|
||||
explicit const_reverse_iterator(const_iterator b)
|
||||
: boost::reverse_iterator<const_iterator>(b)
|
||||
{}
|
||||
const_reverse_iterator(
|
||||
typename basic_ptree<K, D, C>::reverse_iterator b)
|
||||
: boost::reverse_iterator<const_iterator>(b)
|
||||
{}
|
||||
};
|
||||
template <class K, class D, class C>
|
||||
class basic_ptree<K, D, C>::assoc_iterator
|
||||
: public boost::iterator_adaptor<assoc_iterator,
|
||||
typename subs::by_name_index::iterator,
|
||||
value_type>
|
||||
{
|
||||
friend class boost::iterator_core_access;
|
||||
typedef boost::iterator_adaptor<assoc_iterator,
|
||||
typename subs::by_name_index::iterator,
|
||||
value_type>
|
||||
baset;
|
||||
public:
|
||||
typedef typename baset::reference reference;
|
||||
assoc_iterator() {}
|
||||
explicit assoc_iterator(typename assoc_iterator::base_type b)
|
||||
: assoc_iterator::iterator_adaptor_(b)
|
||||
{}
|
||||
reference dereference() const
|
||||
{
|
||||
return const_cast<reference>(*this->base_reference());
|
||||
}
|
||||
};
|
||||
template <class K, class D, class C>
|
||||
class basic_ptree<K, D, C>::const_assoc_iterator
|
||||
: public boost::iterator_adaptor<const_assoc_iterator,
|
||||
typename subs::by_name_index::const_iterator>
|
||||
{
|
||||
public:
|
||||
const_assoc_iterator() {}
|
||||
explicit const_assoc_iterator(
|
||||
typename const_assoc_iterator::base_type b)
|
||||
: const_assoc_iterator::iterator_adaptor_(b)
|
||||
{}
|
||||
const_assoc_iterator(assoc_iterator b)
|
||||
: const_assoc_iterator::iterator_adaptor_(b.base())
|
||||
{}
|
||||
};
|
||||
|
||||
|
||||
// Big five
|
||||
|
||||
// Perhaps the children collection could be created on-demand only, to
|
||||
// reduce heap traffic. But that's a lot more work to implement.
|
||||
|
||||
template<class K, class D, class C> inline
|
||||
basic_ptree<K, D, C>::basic_ptree()
|
||||
: m_children(new typename subs::base_container)
|
||||
{
|
||||
}
|
||||
|
||||
template<class K, class D, class C> inline
|
||||
basic_ptree<K, D, C>::basic_ptree(const data_type &d)
|
||||
: m_data(d), m_children(new typename subs::base_container)
|
||||
{
|
||||
}
|
||||
|
||||
template<class K, class D, class C> inline
|
||||
basic_ptree<K, D, C>::basic_ptree(const basic_ptree<K, D, C> &rhs)
|
||||
: m_data(rhs.m_data),
|
||||
m_children(new typename subs::base_container(subs::ch(&rhs)))
|
||||
{
|
||||
}
|
||||
|
||||
template<class K, class D, class C>
|
||||
basic_ptree<K, D, C> &
|
||||
basic_ptree<K, D, C>::operator =(const basic_ptree<K, D, C> &rhs)
|
||||
{
|
||||
self_type(rhs).swap(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<class K, class D, class C>
|
||||
basic_ptree<K, D, C>::~basic_ptree()
|
||||
{
|
||||
delete &subs::ch(this);
|
||||
}
|
||||
|
||||
template<class K, class D, class C> inline
|
||||
void basic_ptree<K, D, C>::swap(basic_ptree<K, D, C> &rhs)
|
||||
{
|
||||
m_data.swap(rhs.m_data);
|
||||
// Void pointers, no ADL necessary
|
||||
std::swap(m_children, rhs.m_children);
|
||||
}
|
||||
|
||||
// Container view
|
||||
|
||||
template<class K, class D, class C> inline
|
||||
typename basic_ptree<K, D, C>::size_type
|
||||
basic_ptree<K, D, C>::size() const
|
||||
{
|
||||
return subs::ch(this).size();
|
||||
}
|
||||
|
||||
template<class K, class D, class C> inline
|
||||
typename basic_ptree<K, D, C>::size_type
|
||||
basic_ptree<K, D, C>::max_size() const
|
||||
{
|
||||
return subs::ch(this).max_size();
|
||||
}
|
||||
|
||||
template<class K, class D, class C> inline
|
||||
bool basic_ptree<K, D, C>::empty() const
|
||||
{
|
||||
return subs::ch(this).empty();
|
||||
}
|
||||
|
||||
template<class K, class D, class C> inline
|
||||
typename basic_ptree<K, D, C>::iterator
|
||||
basic_ptree<K, D, C>::begin()
|
||||
{
|
||||
return iterator(subs::ch(this).begin());
|
||||
}
|
||||
|
||||
template<class K, class D, class C> inline
|
||||
typename basic_ptree<K, D, C>::const_iterator
|
||||
basic_ptree<K, D, C>::begin() const
|
||||
{
|
||||
return const_iterator(subs::ch(this).begin());
|
||||
}
|
||||
|
||||
template<class K, class D, class C> inline
|
||||
typename basic_ptree<K, D, C>::iterator
|
||||
basic_ptree<K, D, C>::end()
|
||||
{
|
||||
return iterator(subs::ch(this).end());
|
||||
}
|
||||
|
||||
template<class K, class D, class C> inline
|
||||
typename basic_ptree<K, D, C>::const_iterator
|
||||
basic_ptree<K, D, C>::end() const
|
||||
{
|
||||
return const_iterator(subs::ch(this).end());
|
||||
}
|
||||
|
||||
template<class K, class D, class C> inline
|
||||
typename basic_ptree<K, D, C>::reverse_iterator
|
||||
basic_ptree<K, D, C>::rbegin()
|
||||
{
|
||||
return reverse_iterator(this->end());
|
||||
}
|
||||
|
||||
template<class K, class D, class C> inline
|
||||
typename basic_ptree<K, D, C>::const_reverse_iterator
|
||||
basic_ptree<K, D, C>::rbegin() const
|
||||
{
|
||||
return const_reverse_iterator(this->end());
|
||||
}
|
||||
|
||||
template<class K, class D, class C> inline
|
||||
typename basic_ptree<K, D, C>::reverse_iterator
|
||||
basic_ptree<K, D, C>::rend()
|
||||
{
|
||||
return reverse_iterator(this->begin());
|
||||
}
|
||||
|
||||
template<class K, class D, class C> inline
|
||||
typename basic_ptree<K, D, C>::const_reverse_iterator
|
||||
basic_ptree<K, D, C>::rend() const
|
||||
{
|
||||
return const_reverse_iterator(this->begin());
|
||||
}
|
||||
|
||||
template<class K, class D, class C> inline
|
||||
typename basic_ptree<K, D, C>::value_type &
|
||||
basic_ptree<K, D, C>::front()
|
||||
{
|
||||
return const_cast<value_type&>(subs::ch(this).front());
|
||||
}
|
||||
|
||||
template<class K, class D, class C> inline
|
||||
const typename basic_ptree<K, D, C>::value_type &
|
||||
basic_ptree<K, D, C>::front() const
|
||||
{
|
||||
return subs::ch(this).front();
|
||||
}
|
||||
|
||||
template<class K, class D, class C> inline
|
||||
typename basic_ptree<K, D, C>::value_type &
|
||||
basic_ptree<K, D, C>::back()
|
||||
{
|
||||
return const_cast<value_type&>(subs::ch(this).back());
|
||||
}
|
||||
|
||||
template<class K, class D, class C> inline
|
||||
const typename basic_ptree<K, D, C>::value_type &
|
||||
basic_ptree<K, D, C>::back() const
|
||||
{
|
||||
return subs::ch(this).back();
|
||||
}
|
||||
|
||||
template<class K, class D, class C> inline
|
||||
typename basic_ptree<K, D, C>::iterator
|
||||
basic_ptree<K, D, C>::insert(iterator where, const value_type &value)
|
||||
{
|
||||
return iterator(subs::ch(this).insert(where.base(), value).first);
|
||||
}
|
||||
|
||||
template<class K, class D, class C>
|
||||
template<class It> inline
|
||||
void basic_ptree<K, D, C>::insert(iterator where, It first, It last)
|
||||
{
|
||||
subs::ch(this).insert(where.base(), first, last);
|
||||
}
|
||||
|
||||
template<class K, class D, class C> inline
|
||||
typename basic_ptree<K, D, C>::iterator
|
||||
basic_ptree<K, D, C>::erase(iterator where)
|
||||
{
|
||||
return iterator(subs::ch(this).erase(where.base()));
|
||||
}
|
||||
|
||||
template<class K, class D, class C> inline
|
||||
typename basic_ptree<K, D, C>::iterator
|
||||
basic_ptree<K, D, C>::erase(iterator first, iterator last)
|
||||
{
|
||||
return iterator(subs::ch(this).erase(first.base(), last.base()));
|
||||
}
|
||||
|
||||
template<class K, class D, class C> inline
|
||||
typename basic_ptree<K, D, C>::iterator
|
||||
basic_ptree<K, D, C>::push_front(const value_type &value)
|
||||
{
|
||||
return iterator(subs::ch(this).push_front(value).first);
|
||||
}
|
||||
|
||||
template<class K, class D, class C> inline
|
||||
typename basic_ptree<K, D, C>::iterator
|
||||
basic_ptree<K, D, C>::push_back(const value_type &value)
|
||||
{
|
||||
return iterator(subs::ch(this).push_back(value).first);
|
||||
}
|
||||
|
||||
template<class K, class D, class C> inline
|
||||
void basic_ptree<K, D, C>::pop_front()
|
||||
{
|
||||
subs::ch(this).pop_front();
|
||||
}
|
||||
|
||||
template<class K, class D, class C> inline
|
||||
void basic_ptree<K, D, C>::pop_back()
|
||||
{
|
||||
subs::ch(this).pop_back();
|
||||
}
|
||||
|
||||
template<class K, class D, class C> inline
|
||||
void basic_ptree<K, D, C>::reverse()
|
||||
{
|
||||
subs::ch(this).reverse();
|
||||
}
|
||||
|
||||
template<class K, class D, class C> inline
|
||||
void basic_ptree<K, D, C>::sort()
|
||||
{
|
||||
subs::ch(this).sort();
|
||||
}
|
||||
|
||||
template<class K, class D, class C>
|
||||
template<class Compare> inline
|
||||
void basic_ptree<K, D, C>::sort(Compare comp)
|
||||
{
|
||||
subs::ch(this).sort(comp);
|
||||
}
|
||||
|
||||
// Equality
|
||||
|
||||
template<class K, class D, class C> inline
|
||||
bool basic_ptree<K, D, C>::operator ==(
|
||||
const basic_ptree<K, D, C> &rhs) const
|
||||
{
|
||||
// The size test is cheap, so add it as an optimization
|
||||
return size() == rhs.size() && data() == rhs.data() &&
|
||||
subs::ch(this) == subs::ch(&rhs);
|
||||
}
|
||||
|
||||
template<class K, class D, class C> inline
|
||||
bool basic_ptree<K, D, C>::operator !=(
|
||||
const basic_ptree<K, D, C> &rhs) const
|
||||
{
|
||||
return !(*this == rhs);
|
||||
}
|
||||
|
||||
// Associative view
|
||||
|
||||
template<class K, class D, class C> inline
|
||||
typename basic_ptree<K, D, C>::assoc_iterator
|
||||
basic_ptree<K, D, C>::ordered_begin()
|
||||
{
|
||||
return assoc_iterator(subs::assoc(this).begin());
|
||||
}
|
||||
|
||||
template<class K, class D, class C> inline
|
||||
typename basic_ptree<K, D, C>::const_assoc_iterator
|
||||
basic_ptree<K, D, C>::ordered_begin() const
|
||||
{
|
||||
return const_assoc_iterator(subs::assoc(this).begin());
|
||||
}
|
||||
|
||||
template<class K, class D, class C> inline
|
||||
typename basic_ptree<K, D, C>::assoc_iterator
|
||||
basic_ptree<K, D, C>::not_found()
|
||||
{
|
||||
return assoc_iterator(subs::assoc(this).end());
|
||||
}
|
||||
|
||||
template<class K, class D, class C> inline
|
||||
typename basic_ptree<K, D, C>::const_assoc_iterator
|
||||
basic_ptree<K, D, C>::not_found() const
|
||||
{
|
||||
return const_assoc_iterator(subs::assoc(this).end());
|
||||
}
|
||||
|
||||
template<class K, class D, class C> inline
|
||||
typename basic_ptree<K, D, C>::assoc_iterator
|
||||
basic_ptree<K, D, C>::find(const key_type &key)
|
||||
{
|
||||
return assoc_iterator(subs::assoc(this).find(key));
|
||||
}
|
||||
|
||||
template<class K, class D, class C> inline
|
||||
typename basic_ptree<K, D, C>::const_assoc_iterator
|
||||
basic_ptree<K, D, C>::find(const key_type &key) const
|
||||
{
|
||||
return const_assoc_iterator(subs::assoc(this).find(key));
|
||||
}
|
||||
|
||||
template<class K, class D, class C> inline
|
||||
std::pair<
|
||||
typename basic_ptree<K, D, C>::assoc_iterator,
|
||||
typename basic_ptree<K, D, C>::assoc_iterator
|
||||
> basic_ptree<K, D, C>::equal_range(const key_type &key)
|
||||
{
|
||||
std::pair<typename subs::by_name_index::iterator,
|
||||
typename subs::by_name_index::iterator> r(
|
||||
subs::assoc(this).equal_range(key));
|
||||
return std::pair<assoc_iterator, assoc_iterator>(
|
||||
assoc_iterator(r.first), assoc_iterator(r.second));
|
||||
}
|
||||
|
||||
template<class K, class D, class C> inline
|
||||
std::pair<
|
||||
typename basic_ptree<K, D, C>::const_assoc_iterator,
|
||||
typename basic_ptree<K, D, C>::const_assoc_iterator
|
||||
> basic_ptree<K, D, C>::equal_range(const key_type &key) const
|
||||
{
|
||||
std::pair<typename subs::by_name_index::const_iterator,
|
||||
typename subs::by_name_index::const_iterator> r(
|
||||
subs::assoc(this).equal_range(key));
|
||||
return std::pair<const_assoc_iterator, const_assoc_iterator>(
|
||||
const_assoc_iterator(r.first), const_assoc_iterator(r.second));
|
||||
}
|
||||
|
||||
template<class K, class D, class C> inline
|
||||
typename basic_ptree<K, D, C>::size_type
|
||||
basic_ptree<K, D, C>::count(const key_type &key) const
|
||||
{
|
||||
return subs::assoc(this).count(key);
|
||||
}
|
||||
|
||||
template<class K, class D, class C> inline
|
||||
typename basic_ptree<K, D, C>::size_type
|
||||
basic_ptree<K, D, C>::erase(const key_type &key)
|
||||
{
|
||||
return subs::assoc(this).erase(key);
|
||||
}
|
||||
|
||||
template<class K, class D, class C> inline
|
||||
typename basic_ptree<K, D, C>::iterator
|
||||
basic_ptree<K, D, C>::to_iterator(assoc_iterator ai)
|
||||
{
|
||||
return iterator(subs::ch(this).
|
||||
BOOST_NESTED_TEMPLATE project<0>(ai.base()));
|
||||
}
|
||||
|
||||
template<class K, class D, class C> inline
|
||||
typename basic_ptree<K, D, C>::const_iterator
|
||||
basic_ptree<K, D, C>::to_iterator(const_assoc_iterator ai) const
|
||||
{
|
||||
return const_iterator(subs::ch(this).
|
||||
BOOST_NESTED_TEMPLATE project<0>(ai.base()));
|
||||
}
|
||||
|
||||
// Property tree view
|
||||
|
||||
template<class K, class D, class C> inline
|
||||
typename basic_ptree<K, D, C>::data_type &
|
||||
basic_ptree<K, D, C>::data()
|
||||
{
|
||||
return m_data;
|
||||
}
|
||||
|
||||
template<class K, class D, class C> inline
|
||||
const typename basic_ptree<K, D, C>::data_type &
|
||||
basic_ptree<K, D, C>::data() const
|
||||
{
|
||||
return m_data;
|
||||
}
|
||||
|
||||
template<class K, class D, class C> inline
|
||||
void basic_ptree<K, D, C>::clear()
|
||||
{
|
||||
m_data = data_type();
|
||||
subs::ch(this).clear();
|
||||
}
|
||||
|
||||
template<class K, class D, class C>
|
||||
basic_ptree<K, D, C> &
|
||||
basic_ptree<K, D, C>::get_child(const path_type &path)
|
||||
{
|
||||
path_type p(path);
|
||||
self_type *n = walk_path(p);
|
||||
if (!n) {
|
||||
BOOST_PROPERTY_TREE_THROW(ptree_bad_path("No such node", path));
|
||||
}
|
||||
return *n;
|
||||
}
|
||||
|
||||
template<class K, class D, class C> inline
|
||||
const basic_ptree<K, D, C> &
|
||||
basic_ptree<K, D, C>::get_child(const path_type &path) const
|
||||
{
|
||||
return const_cast<self_type*>(this)->get_child(path);
|
||||
}
|
||||
|
||||
template<class K, class D, class C> inline
|
||||
basic_ptree<K, D, C> &
|
||||
basic_ptree<K, D, C>::get_child(const path_type &path,
|
||||
self_type &default_value)
|
||||
{
|
||||
path_type p(path);
|
||||
self_type *n = walk_path(p);
|
||||
return n ? *n : default_value;
|
||||
}
|
||||
|
||||
template<class K, class D, class C> inline
|
||||
const basic_ptree<K, D, C> &
|
||||
basic_ptree<K, D, C>::get_child(const path_type &path,
|
||||
const self_type &default_value) const
|
||||
{
|
||||
return const_cast<self_type*>(this)->get_child(path,
|
||||
const_cast<self_type&>(default_value));
|
||||
}
|
||||
|
||||
|
||||
template<class K, class D, class C>
|
||||
optional<basic_ptree<K, D, C> &>
|
||||
basic_ptree<K, D, C>::get_child_optional(const path_type &path)
|
||||
{
|
||||
path_type p(path);
|
||||
self_type *n = walk_path(p);
|
||||
if (!n) {
|
||||
return optional<self_type&>();
|
||||
}
|
||||
return *n;
|
||||
}
|
||||
|
||||
template<class K, class D, class C>
|
||||
optional<const basic_ptree<K, D, C> &>
|
||||
basic_ptree<K, D, C>::get_child_optional(const path_type &path) const
|
||||
{
|
||||
path_type p(path);
|
||||
self_type *n = walk_path(p);
|
||||
if (!n) {
|
||||
return optional<const self_type&>();
|
||||
}
|
||||
return *n;
|
||||
}
|
||||
|
||||
template<class K, class D, class C>
|
||||
basic_ptree<K, D, C> &
|
||||
basic_ptree<K, D, C>::put_child(const path_type &path,
|
||||
const self_type &value)
|
||||
{
|
||||
path_type p(path);
|
||||
self_type &parent = force_path(p);
|
||||
// Got the parent. Now get the correct child.
|
||||
key_type fragment = p.reduce();
|
||||
assoc_iterator el = parent.find(fragment);
|
||||
// If the new child exists, replace it.
|
||||
if(el != parent.not_found()) {
|
||||
return el->second = value;
|
||||
} else {
|
||||
return parent.push_back(value_type(fragment, value))->second;
|
||||
}
|
||||
}
|
||||
|
||||
template<class K, class D, class C>
|
||||
basic_ptree<K, D, C> &
|
||||
basic_ptree<K, D, C>::add_child(const path_type &path,
|
||||
const self_type &value)
|
||||
{
|
||||
path_type p(path);
|
||||
self_type &parent = force_path(p);
|
||||
// Got the parent.
|
||||
key_type fragment = p.reduce();
|
||||
return parent.push_back(value_type(fragment, value))->second;
|
||||
}
|
||||
|
||||
template<class K, class D, class C>
|
||||
template<class Type, class Translator>
|
||||
typename boost::enable_if<detail::is_translator<Translator>, Type>::type
|
||||
basic_ptree<K, D, C>::get_value(Translator tr) const
|
||||
{
|
||||
if(boost::optional<Type> o = get_value_optional<Type>(tr)) {
|
||||
return *o;
|
||||
}
|
||||
BOOST_PROPERTY_TREE_THROW(ptree_bad_data(
|
||||
std::string("conversion of data to type \"") +
|
||||
typeid(Type).name() + "\" failed", data()));
|
||||
}
|
||||
|
||||
template<class K, class D, class C>
|
||||
template<class Type> inline
|
||||
Type basic_ptree<K, D, C>::get_value() const
|
||||
{
|
||||
return get_value<Type>(
|
||||
typename translator_between<data_type, Type>::type());
|
||||
}
|
||||
|
||||
template<class K, class D, class C>
|
||||
template<class Type, class Translator> inline
|
||||
Type basic_ptree<K, D, C>::get_value(const Type &default_value,
|
||||
Translator tr) const
|
||||
{
|
||||
return get_value_optional<Type>(tr).get_value_or(default_value);
|
||||
}
|
||||
|
||||
template<class K, class D, class C>
|
||||
template <class Ch, class Translator>
|
||||
typename boost::enable_if<
|
||||
detail::is_character<Ch>,
|
||||
std::basic_string<Ch>
|
||||
>::type
|
||||
basic_ptree<K, D, C>::get_value(const Ch *default_value, Translator tr)const
|
||||
{
|
||||
return get_value<std::basic_string<Ch>, Translator>(default_value, tr);
|
||||
}
|
||||
|
||||
template<class K, class D, class C>
|
||||
template<class Type> inline
|
||||
typename boost::disable_if<detail::is_translator<Type>, Type>::type
|
||||
basic_ptree<K, D, C>::get_value(const Type &default_value) const
|
||||
{
|
||||
return get_value(default_value,
|
||||
typename translator_between<data_type, Type>::type());
|
||||
}
|
||||
|
||||
template<class K, class D, class C>
|
||||
template <class Ch>
|
||||
typename boost::enable_if<
|
||||
detail::is_character<Ch>,
|
||||
std::basic_string<Ch>
|
||||
>::type
|
||||
basic_ptree<K, D, C>::get_value(const Ch *default_value) const
|
||||
{
|
||||
return get_value< std::basic_string<Ch> >(default_value);
|
||||
}
|
||||
|
||||
template<class K, class D, class C>
|
||||
template<class Type, class Translator> inline
|
||||
optional<Type> basic_ptree<K, D, C>::get_value_optional(
|
||||
Translator tr) const
|
||||
{
|
||||
return tr.get_value(data());
|
||||
}
|
||||
|
||||
template<class K, class D, class C>
|
||||
template<class Type> inline
|
||||
optional<Type> basic_ptree<K, D, C>::get_value_optional() const
|
||||
{
|
||||
return get_value_optional<Type>(
|
||||
typename translator_between<data_type, Type>::type());
|
||||
}
|
||||
|
||||
template<class K, class D, class C>
|
||||
template<class Type, class Translator> inline
|
||||
typename boost::enable_if<detail::is_translator<Translator>, Type>::type
|
||||
basic_ptree<K, D, C>::get(const path_type &path,
|
||||
Translator tr) const
|
||||
{
|
||||
return get_child(path).BOOST_NESTED_TEMPLATE get_value<Type>(tr);
|
||||
}
|
||||
|
||||
template<class K, class D, class C>
|
||||
template<class Type> inline
|
||||
Type basic_ptree<K, D, C>::get(const path_type &path) const
|
||||
{
|
||||
return get_child(path).BOOST_NESTED_TEMPLATE get_value<Type>();
|
||||
}
|
||||
|
||||
template<class K, class D, class C>
|
||||
template<class Type, class Translator> inline
|
||||
Type basic_ptree<K, D, C>::get(const path_type &path,
|
||||
const Type &default_value,
|
||||
Translator tr) const
|
||||
{
|
||||
return get_optional<Type>(path, tr).get_value_or(default_value);
|
||||
}
|
||||
|
||||
template<class K, class D, class C>
|
||||
template <class Ch, class Translator>
|
||||
typename boost::enable_if<
|
||||
detail::is_character<Ch>,
|
||||
std::basic_string<Ch>
|
||||
>::type
|
||||
basic_ptree<K, D, C>::get(
|
||||
const path_type &path, const Ch *default_value, Translator tr) const
|
||||
{
|
||||
return get<std::basic_string<Ch>, Translator>(path, default_value, tr);
|
||||
}
|
||||
|
||||
template<class K, class D, class C>
|
||||
template<class Type> inline
|
||||
typename boost::disable_if<detail::is_translator<Type>, Type>::type
|
||||
basic_ptree<K, D, C>::get(const path_type &path,
|
||||
const Type &default_value) const
|
||||
{
|
||||
return get_optional<Type>(path).get_value_or(default_value);
|
||||
}
|
||||
|
||||
template<class K, class D, class C>
|
||||
template <class Ch>
|
||||
typename boost::enable_if<
|
||||
detail::is_character<Ch>,
|
||||
std::basic_string<Ch>
|
||||
>::type
|
||||
basic_ptree<K, D, C>::get(
|
||||
const path_type &path, const Ch *default_value) const
|
||||
{
|
||||
return get< std::basic_string<Ch> >(path, default_value);
|
||||
}
|
||||
|
||||
template<class K, class D, class C>
|
||||
template<class Type, class Translator>
|
||||
optional<Type> basic_ptree<K, D, C>::get_optional(const path_type &path,
|
||||
Translator tr) const
|
||||
{
|
||||
if (optional<const self_type&> child = get_child_optional(path))
|
||||
return child.get().
|
||||
BOOST_NESTED_TEMPLATE get_value_optional<Type>(tr);
|
||||
else
|
||||
return optional<Type>();
|
||||
}
|
||||
|
||||
template<class K, class D, class C>
|
||||
template<class Type>
|
||||
optional<Type> basic_ptree<K, D, C>::get_optional(
|
||||
const path_type &path) const
|
||||
{
|
||||
if (optional<const self_type&> child = get_child_optional(path))
|
||||
return child.get().BOOST_NESTED_TEMPLATE get_value_optional<Type>();
|
||||
else
|
||||
return optional<Type>();
|
||||
}
|
||||
|
||||
template<class K, class D, class C>
|
||||
template<class Type, class Translator>
|
||||
void basic_ptree<K, D, C>::put_value(const Type &value, Translator tr)
|
||||
{
|
||||
if(optional<data_type> o = tr.put_value(value)) {
|
||||
data() = *o;
|
||||
} else {
|
||||
BOOST_PROPERTY_TREE_THROW(ptree_bad_data(
|
||||
std::string("conversion of type \"") + typeid(Type).name() +
|
||||
"\" to data failed", boost::any()));
|
||||
}
|
||||
}
|
||||
|
||||
template<class K, class D, class C>
|
||||
template<class Type> inline
|
||||
void basic_ptree<K, D, C>::put_value(const Type &value)
|
||||
{
|
||||
put_value(value, typename translator_between<data_type, Type>::type());
|
||||
}
|
||||
|
||||
template<class K, class D, class C>
|
||||
template<class Type, typename Translator>
|
||||
basic_ptree<K, D, C> & basic_ptree<K, D, C>::put(
|
||||
const path_type &path, const Type &value, Translator tr)
|
||||
{
|
||||
if(optional<self_type &> child = get_child_optional(path)) {
|
||||
child.get().put_value(value, tr);
|
||||
return *child;
|
||||
} else {
|
||||
self_type &child2 = put_child(path, self_type());
|
||||
child2.put_value(value, tr);
|
||||
return child2;
|
||||
}
|
||||
}
|
||||
|
||||
template<class K, class D, class C>
|
||||
template<class Type> inline
|
||||
basic_ptree<K, D, C> & basic_ptree<K, D, C>::put(
|
||||
const path_type &path, const Type &value)
|
||||
{
|
||||
return put(path, value,
|
||||
typename translator_between<data_type, Type>::type());
|
||||
}
|
||||
|
||||
template<class K, class D, class C>
|
||||
template<class Type, typename Translator> inline
|
||||
basic_ptree<K, D, C> & basic_ptree<K, D, C>::add(
|
||||
const path_type &path, const Type &value, Translator tr)
|
||||
{
|
||||
self_type &child = add_child(path, self_type());
|
||||
child.put_value(value, tr);
|
||||
return child;
|
||||
}
|
||||
|
||||
template<class K, class D, class C>
|
||||
template<class Type> inline
|
||||
basic_ptree<K, D, C> & basic_ptree<K, D, C>::add(
|
||||
const path_type &path, const Type &value)
|
||||
{
|
||||
return add(path, value,
|
||||
typename translator_between<data_type, Type>::type());
|
||||
}
|
||||
|
||||
|
||||
template<class K, class D, class C>
|
||||
basic_ptree<K, D, C> *
|
||||
basic_ptree<K, D, C>::walk_path(path_type &p) const
|
||||
{
|
||||
if(p.empty()) {
|
||||
// I'm the child we're looking for.
|
||||
return const_cast<basic_ptree*>(this);
|
||||
}
|
||||
// Recurse down the tree to find the path.
|
||||
key_type fragment = p.reduce();
|
||||
const_assoc_iterator el = find(fragment);
|
||||
if(el == not_found()) {
|
||||
// No such child.
|
||||
return 0;
|
||||
}
|
||||
// Not done yet, recurse.
|
||||
return el->second.walk_path(p);
|
||||
}
|
||||
|
||||
template<class K, class D, class C>
|
||||
basic_ptree<K, D, C> & basic_ptree<K, D, C>::force_path(path_type &p)
|
||||
{
|
||||
BOOST_ASSERT(!p.empty() && "Empty path not allowed for put_child.");
|
||||
if(p.single()) {
|
||||
// I'm the parent we're looking for.
|
||||
return *this;
|
||||
}
|
||||
key_type fragment = p.reduce();
|
||||
assoc_iterator el = find(fragment);
|
||||
// If we've found an existing child, go down that path. Else
|
||||
// create a new one.
|
||||
self_type& child = el == not_found() ?
|
||||
push_back(value_type(fragment, self_type()))->second : el->second;
|
||||
return child.force_path(p);
|
||||
}
|
||||
|
||||
// Free functions
|
||||
|
||||
template<class K, class D, class C>
|
||||
inline void swap(basic_ptree<K, D, C> &pt1, basic_ptree<K, D, C> &pt2)
|
||||
{
|
||||
pt1.swap(pt2);
|
||||
}
|
||||
|
||||
} }
|
||||
|
||||
#if defined(BOOST_PROPERTY_TREE_PAIR_BUG)
|
||||
#undef BOOST_PROPERTY_TREE_PAIR_BUG
|
||||
#endif
|
||||
|
||||
#endif
|
||||
106
test/external/boost/property_tree/detail/ptree_utils.hpp
vendored
Normal file
106
test/external/boost/property_tree/detail/ptree_utils.hpp
vendored
Normal file
@@ -0,0 +1,106 @@
|
||||
// ----------------------------------------------------------------------------
|
||||
// Copyright (C) 2002-2006 Marcin Kalicinski
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// For more information, see www.boost.org
|
||||
// ----------------------------------------------------------------------------
|
||||
#ifndef BOOST_PROPERTY_TREE_DETAIL_PTREE_UTILS_HPP_INCLUDED
|
||||
#define BOOST_PROPERTY_TREE_DETAIL_PTREE_UTILS_HPP_INCLUDED
|
||||
|
||||
#include <boost/limits.hpp>
|
||||
#include <boost/type_traits/integral_constant.hpp>
|
||||
#include <boost/mpl/has_xxx.hpp>
|
||||
#include <boost/mpl/and.hpp>
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
#include <locale>
|
||||
|
||||
namespace boost { namespace property_tree { namespace detail
|
||||
{
|
||||
|
||||
template<class T>
|
||||
struct less_nocase
|
||||
{
|
||||
typedef typename T::value_type Ch;
|
||||
std::locale m_locale;
|
||||
inline bool operator()(Ch c1, Ch c2) const
|
||||
{
|
||||
return std::toupper(c1, m_locale) < std::toupper(c2, m_locale);
|
||||
}
|
||||
inline bool operator()(const T &t1, const T &t2) const
|
||||
{
|
||||
return std::lexicographical_compare(t1.begin(), t1.end(),
|
||||
t2.begin(), t2.end(), *this);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Ch>
|
||||
struct is_character : public boost::false_type {};
|
||||
template <>
|
||||
struct is_character<char> : public boost::true_type {};
|
||||
template <>
|
||||
struct is_character<wchar_t> : public boost::true_type {};
|
||||
|
||||
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(internal_type)
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(external_type)
|
||||
template <typename T>
|
||||
struct is_translator : public boost::mpl::and_<
|
||||
has_internal_type<T>, has_external_type<T> > {};
|
||||
|
||||
|
||||
|
||||
// Naively convert narrow string to another character type
|
||||
template<class Ch>
|
||||
std::basic_string<Ch> widen(const char *text)
|
||||
{
|
||||
std::basic_string<Ch> result;
|
||||
while (*text)
|
||||
{
|
||||
result += Ch(*text);
|
||||
++text;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// Naively convert string to narrow character type
|
||||
template<class Ch>
|
||||
std::string narrow(const Ch *text)
|
||||
{
|
||||
std::string result;
|
||||
while (*text)
|
||||
{
|
||||
if (*text < 0 || *text > (std::numeric_limits<char>::max)())
|
||||
result += '*';
|
||||
else
|
||||
result += char(*text);
|
||||
++text;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// Remove trailing and leading spaces
|
||||
template<class Ch>
|
||||
std::basic_string<Ch> trim(const std::basic_string<Ch> &s,
|
||||
const std::locale &loc = std::locale())
|
||||
{
|
||||
typename std::basic_string<Ch>::const_iterator first = s.begin();
|
||||
typename std::basic_string<Ch>::const_iterator end = s.end();
|
||||
while (first != end && std::isspace(*first, loc))
|
||||
++first;
|
||||
if (first == end)
|
||||
return std::basic_string<Ch>();
|
||||
typename std::basic_string<Ch>::const_iterator last = end;
|
||||
do --last; while (std::isspace(*last, loc));
|
||||
if (first != s.begin() || last + 1 != end)
|
||||
return std::basic_string<Ch>(first, last + 1);
|
||||
else
|
||||
return s;
|
||||
}
|
||||
|
||||
} } }
|
||||
|
||||
#endif
|
||||
2594
test/external/boost/property_tree/detail/rapidxml.hpp
vendored
Normal file
2594
test/external/boost/property_tree/detail/rapidxml.hpp
vendored
Normal file
File diff suppressed because it is too large
Load Diff
33
test/external/boost/property_tree/detail/xml_parser_error.hpp
vendored
Normal file
33
test/external/boost/property_tree/detail/xml_parser_error.hpp
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
// ----------------------------------------------------------------------------
|
||||
// Copyright (C) 2002-2006 Marcin Kalicinski
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// For more information, see www.boost.org
|
||||
// ----------------------------------------------------------------------------
|
||||
#ifndef BOOST_PROPERTY_TREE_DETAIL_XML_PARSER_ERROR_HPP_INCLUDED
|
||||
#define BOOST_PROPERTY_TREE_DETAIL_XML_PARSER_ERROR_HPP_INCLUDED
|
||||
|
||||
#include <boost/property_tree/detail/file_parser_error.hpp>
|
||||
#include <string>
|
||||
|
||||
namespace boost { namespace property_tree { namespace xml_parser
|
||||
{
|
||||
|
||||
//! Xml parser error
|
||||
class xml_parser_error: public file_parser_error
|
||||
{
|
||||
public:
|
||||
xml_parser_error(const std::string &msg,
|
||||
const std::string &file,
|
||||
unsigned long l):
|
||||
file_parser_error(msg, file, l)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
} } }
|
||||
|
||||
#endif
|
||||
31
test/external/boost/property_tree/detail/xml_parser_flags.hpp
vendored
Normal file
31
test/external/boost/property_tree/detail/xml_parser_flags.hpp
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
// ----------------------------------------------------------------------------
|
||||
// Copyright (C) 2002-2006 Marcin Kalicinski
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// For more information, see www.boost.org
|
||||
// ----------------------------------------------------------------------------
|
||||
#ifndef BOOST_PROPERTY_TREE_DETAIL_XML_PARSER_FLAGS_HPP_INCLUDED
|
||||
#define BOOST_PROPERTY_TREE_DETAIL_XML_PARSER_FLAGS_HPP_INCLUDED
|
||||
|
||||
namespace boost { namespace property_tree { namespace xml_parser
|
||||
{
|
||||
|
||||
/// Text elements should be put in separate keys,
|
||||
/// not concatenated in parent data.
|
||||
static const int no_concat_text = 0x1;
|
||||
/// Comments should be omitted.
|
||||
static const int no_comments = 0x2;
|
||||
/// Whitespace should be collapsed and trimmed.
|
||||
static const int trim_whitespace = 0x4;
|
||||
|
||||
inline bool validate_flags(int flags)
|
||||
{
|
||||
return (flags & ~(no_concat_text | no_comments | trim_whitespace)) == 0;
|
||||
}
|
||||
|
||||
} } }
|
||||
|
||||
#endif
|
||||
144
test/external/boost/property_tree/detail/xml_parser_read_rapidxml.hpp
vendored
Normal file
144
test/external/boost/property_tree/detail/xml_parser_read_rapidxml.hpp
vendored
Normal file
@@ -0,0 +1,144 @@
|
||||
// ----------------------------------------------------------------------------
|
||||
// Copyright (C) 2007 Marcin Kalicinski
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// For more information, see www.boost.org
|
||||
// ----------------------------------------------------------------------------
|
||||
#ifndef BOOST_PROPERTY_TREE_DETAIL_XML_PARSER_READ_RAPIDXML_HPP_INCLUDED
|
||||
#define BOOST_PROPERTY_TREE_DETAIL_XML_PARSER_READ_RAPIDXML_HPP_INCLUDED
|
||||
|
||||
#include <boost/property_tree/ptree.hpp>
|
||||
#include <boost/property_tree/detail/xml_parser_error.hpp>
|
||||
#include <boost/property_tree/detail/xml_parser_flags.hpp>
|
||||
#include <boost/property_tree/detail/xml_parser_utils.hpp>
|
||||
#include <boost/property_tree/detail/rapidxml.hpp>
|
||||
#include <vector>
|
||||
|
||||
namespace boost { namespace property_tree { namespace xml_parser
|
||||
{
|
||||
|
||||
template<class Ptree, class Ch>
|
||||
void read_xml_node(detail::rapidxml::xml_node<Ch> *node,
|
||||
Ptree &pt, int flags)
|
||||
{
|
||||
using namespace detail::rapidxml;
|
||||
switch (node->type())
|
||||
{
|
||||
// Element nodes
|
||||
case node_element:
|
||||
{
|
||||
// Create node
|
||||
Ptree &pt_node = pt.push_back(std::make_pair(node->name(),
|
||||
Ptree()))->second;
|
||||
|
||||
// Copy attributes
|
||||
if (node->first_attribute())
|
||||
{
|
||||
Ptree &pt_attr_root = pt_node.push_back(
|
||||
std::make_pair(xmlattr<Ch>(), Ptree()))->second;
|
||||
for (xml_attribute<Ch> *attr = node->first_attribute();
|
||||
attr; attr = attr->next_attribute())
|
||||
{
|
||||
Ptree &pt_attr = pt_attr_root.push_back(
|
||||
std::make_pair(attr->name(), Ptree()))->second;
|
||||
pt_attr.data() = attr->value();
|
||||
}
|
||||
}
|
||||
|
||||
// Copy children
|
||||
for (xml_node<Ch> *child = node->first_node();
|
||||
child; child = child->next_sibling())
|
||||
read_xml_node(child, pt_node, flags);
|
||||
}
|
||||
break;
|
||||
|
||||
// Data nodes
|
||||
case node_data:
|
||||
case node_cdata:
|
||||
{
|
||||
if (flags & no_concat_text)
|
||||
pt.push_back(std::make_pair(xmltext<Ch>(),
|
||||
Ptree(node->value())));
|
||||
else
|
||||
pt.data() += node->value();
|
||||
}
|
||||
break;
|
||||
|
||||
// Comment nodes
|
||||
case node_comment:
|
||||
{
|
||||
if (!(flags & no_comments))
|
||||
pt.push_back(std::make_pair(xmlcomment<Ch>(),
|
||||
Ptree(node->value())));
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
// Skip other node types
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
template<class Ptree>
|
||||
void read_xml_internal(std::basic_istream<
|
||||
typename Ptree::key_type::value_type> &stream,
|
||||
Ptree &pt,
|
||||
int flags,
|
||||
const std::string &filename)
|
||||
{
|
||||
typedef typename Ptree::key_type::value_type Ch;
|
||||
using namespace detail::rapidxml;
|
||||
|
||||
// Load data into vector
|
||||
stream.unsetf(std::ios::skipws);
|
||||
std::vector<Ch> v(std::istreambuf_iterator<Ch>(stream.rdbuf()),
|
||||
std::istreambuf_iterator<Ch>());
|
||||
if (!stream.good())
|
||||
BOOST_PROPERTY_TREE_THROW(
|
||||
xml_parser_error("read error", filename, 0));
|
||||
v.push_back(0); // zero-terminate
|
||||
|
||||
try {
|
||||
// Parse using appropriate flags
|
||||
const int f_tws = parse_normalize_whitespace
|
||||
| parse_trim_whitespace;
|
||||
const int f_c = parse_comment_nodes;
|
||||
// Some compilers don't like the bitwise or in the template arg.
|
||||
const int f_tws_c = parse_normalize_whitespace
|
||||
| parse_trim_whitespace
|
||||
| parse_comment_nodes;
|
||||
xml_document<Ch> doc;
|
||||
if (flags & no_comments) {
|
||||
if (flags & trim_whitespace)
|
||||
doc.BOOST_NESTED_TEMPLATE parse<f_tws>(&v.front());
|
||||
else
|
||||
doc.BOOST_NESTED_TEMPLATE parse<0>(&v.front());
|
||||
} else {
|
||||
if (flags & trim_whitespace)
|
||||
doc.BOOST_NESTED_TEMPLATE parse<f_tws_c>(&v.front());
|
||||
else
|
||||
doc.BOOST_NESTED_TEMPLATE parse<f_c>(&v.front());
|
||||
}
|
||||
|
||||
// Create ptree from nodes
|
||||
Ptree local;
|
||||
for (xml_node<Ch> *child = doc.first_node();
|
||||
child; child = child->next_sibling())
|
||||
read_xml_node(child, local, flags);
|
||||
|
||||
// Swap local and result ptrees
|
||||
pt.swap(local);
|
||||
} catch (parse_error &e) {
|
||||
long line = static_cast<long>(
|
||||
std::count(&v.front(), e.where<Ch>(), Ch('\n')) + 1);
|
||||
BOOST_PROPERTY_TREE_THROW(
|
||||
xml_parser_error(e.what(), filename, line));
|
||||
}
|
||||
}
|
||||
|
||||
} } }
|
||||
|
||||
#endif
|
||||
136
test/external/boost/property_tree/detail/xml_parser_utils.hpp
vendored
Normal file
136
test/external/boost/property_tree/detail/xml_parser_utils.hpp
vendored
Normal file
@@ -0,0 +1,136 @@
|
||||
// ----------------------------------------------------------------------------
|
||||
// Copyright (C) 2002-2006 Marcin Kalicinski
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// For more information, see www.boost.org
|
||||
// ----------------------------------------------------------------------------
|
||||
#ifndef BOOST_PROPERTY_TREE_DETAIL_XML_PARSER_UTILS_HPP_INCLUDED
|
||||
#define BOOST_PROPERTY_TREE_DETAIL_XML_PARSER_UTILS_HPP_INCLUDED
|
||||
|
||||
#include <boost/property_tree/detail/ptree_utils.hpp>
|
||||
#include <boost/property_tree/detail/xml_parser_error.hpp>
|
||||
#include <boost/property_tree/detail/xml_parser_writer_settings.hpp>
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
#include <locale>
|
||||
|
||||
namespace boost { namespace property_tree { namespace xml_parser
|
||||
{
|
||||
|
||||
template<class Ch>
|
||||
std::basic_string<Ch> condense(const std::basic_string<Ch> &s)
|
||||
{
|
||||
std::basic_string<Ch> r;
|
||||
std::locale loc;
|
||||
bool space = false;
|
||||
typename std::basic_string<Ch>::const_iterator end = s.end();
|
||||
for (typename std::basic_string<Ch>::const_iterator it = s.begin();
|
||||
it != end; ++it)
|
||||
{
|
||||
if (isspace(*it, loc) || *it == Ch('\n'))
|
||||
{
|
||||
if (!space)
|
||||
r += Ch(' '), space = true;
|
||||
}
|
||||
else
|
||||
r += *it, space = false;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
template<class Ch>
|
||||
std::basic_string<Ch> encode_char_entities(const std::basic_string<Ch> &s)
|
||||
{
|
||||
// Don't do anything for empty strings.
|
||||
if(s.empty()) return s;
|
||||
|
||||
typedef typename std::basic_string<Ch> Str;
|
||||
Str r;
|
||||
// To properly round-trip spaces and not uglify the XML beyond
|
||||
// recognition, we have to encode them IF the text contains only spaces.
|
||||
Str sp(1, Ch(' '));
|
||||
if(s.find_first_not_of(sp) == Str::npos) {
|
||||
// The first will suffice.
|
||||
r = detail::widen<Ch>(" ");
|
||||
r += Str(s.size() - 1, Ch(' '));
|
||||
} else {
|
||||
typename Str::const_iterator end = s.end();
|
||||
for (typename Str::const_iterator it = s.begin(); it != end; ++it)
|
||||
{
|
||||
switch (*it)
|
||||
{
|
||||
case Ch('<'): r += detail::widen<Ch>("<"); break;
|
||||
case Ch('>'): r += detail::widen<Ch>(">"); break;
|
||||
case Ch('&'): r += detail::widen<Ch>("&"); break;
|
||||
case Ch('"'): r += detail::widen<Ch>("""); break;
|
||||
case Ch('\''): r += detail::widen<Ch>("'"); break;
|
||||
default: r += *it; break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
template<class Ch>
|
||||
std::basic_string<Ch> decode_char_entities(const std::basic_string<Ch> &s)
|
||||
{
|
||||
typedef typename std::basic_string<Ch> Str;
|
||||
Str r;
|
||||
typename Str::const_iterator end = s.end();
|
||||
for (typename Str::const_iterator it = s.begin(); it != end; ++it)
|
||||
{
|
||||
if (*it == Ch('&'))
|
||||
{
|
||||
typename Str::const_iterator semicolon = std::find(it + 1, end, Ch(';'));
|
||||
if (semicolon == end)
|
||||
BOOST_PROPERTY_TREE_THROW(xml_parser_error("invalid character entity", "", 0));
|
||||
Str ent(it + 1, semicolon);
|
||||
if (ent == detail::widen<Ch>("lt")) r += Ch('<');
|
||||
else if (ent == detail::widen<Ch>("gt")) r += Ch('>');
|
||||
else if (ent == detail::widen<Ch>("amp")) r += Ch('&');
|
||||
else if (ent == detail::widen<Ch>("quot")) r += Ch('"');
|
||||
else if (ent == detail::widen<Ch>("apos")) r += Ch('\'');
|
||||
else
|
||||
BOOST_PROPERTY_TREE_THROW(xml_parser_error("invalid character entity", "", 0));
|
||||
it = semicolon;
|
||||
}
|
||||
else
|
||||
r += *it;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
template<class Ch>
|
||||
const std::basic_string<Ch> &xmldecl()
|
||||
{
|
||||
static std::basic_string<Ch> s = detail::widen<Ch>("<?xml>");
|
||||
return s;
|
||||
}
|
||||
|
||||
template<class Ch>
|
||||
const std::basic_string<Ch> &xmlattr()
|
||||
{
|
||||
static std::basic_string<Ch> s = detail::widen<Ch>("<xmlattr>");
|
||||
return s;
|
||||
}
|
||||
|
||||
template<class Ch>
|
||||
const std::basic_string<Ch> &xmlcomment()
|
||||
{
|
||||
static std::basic_string<Ch> s = detail::widen<Ch>("<xmlcomment>");
|
||||
return s;
|
||||
}
|
||||
|
||||
template<class Ch>
|
||||
const std::basic_string<Ch> &xmltext()
|
||||
{
|
||||
static std::basic_string<Ch> s = detail::widen<Ch>("<xmltext>");
|
||||
return s;
|
||||
}
|
||||
|
||||
} } }
|
||||
|
||||
#endif
|
||||
194
test/external/boost/property_tree/detail/xml_parser_write.hpp
vendored
Normal file
194
test/external/boost/property_tree/detail/xml_parser_write.hpp
vendored
Normal file
@@ -0,0 +1,194 @@
|
||||
// ----------------------------------------------------------------------------
|
||||
// Copyright (C) 2002-2006 Marcin Kalicinski
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// For more information, see www.boost.org
|
||||
// ----------------------------------------------------------------------------
|
||||
#ifndef BOOST_PROPERTY_TREE_DETAIL_XML_PARSER_WRITE_HPP_INCLUDED
|
||||
#define BOOST_PROPERTY_TREE_DETAIL_XML_PARSER_WRITE_HPP_INCLUDED
|
||||
|
||||
#include <boost/property_tree/ptree.hpp>
|
||||
#include <boost/property_tree/detail/xml_parser_utils.hpp>
|
||||
#include <string>
|
||||
#include <ostream>
|
||||
#include <iomanip>
|
||||
|
||||
namespace boost { namespace property_tree { namespace xml_parser
|
||||
{
|
||||
template<class Ch>
|
||||
void write_xml_indent(std::basic_ostream<Ch> &stream,
|
||||
int indent,
|
||||
const xml_writer_settings<Ch> & settings
|
||||
)
|
||||
{
|
||||
stream << std::basic_string<Ch>(indent * settings.indent_count, settings.indent_char);
|
||||
}
|
||||
|
||||
template<class Ch>
|
||||
void write_xml_comment(std::basic_ostream<Ch> &stream,
|
||||
const std::basic_string<Ch> &s,
|
||||
int indent,
|
||||
bool separate_line,
|
||||
const xml_writer_settings<Ch> & settings
|
||||
)
|
||||
{
|
||||
typedef typename std::basic_string<Ch> Str;
|
||||
if (separate_line)
|
||||
write_xml_indent(stream,indent,settings);
|
||||
stream << Ch('<') << Ch('!') << Ch('-') << Ch('-');
|
||||
stream << s;
|
||||
stream << Ch('-') << Ch('-') << Ch('>');
|
||||
if (separate_line)
|
||||
stream << Ch('\n');
|
||||
}
|
||||
|
||||
template<class Ch>
|
||||
void write_xml_text(std::basic_ostream<Ch> &stream,
|
||||
const std::basic_string<Ch> &s,
|
||||
int indent,
|
||||
bool separate_line,
|
||||
const xml_writer_settings<Ch> & settings
|
||||
)
|
||||
{
|
||||
if (separate_line)
|
||||
write_xml_indent(stream,indent,settings);
|
||||
stream << encode_char_entities(s);
|
||||
if (separate_line)
|
||||
stream << Ch('\n');
|
||||
}
|
||||
|
||||
template<class Ptree>
|
||||
void write_xml_element(std::basic_ostream<typename Ptree::key_type::value_type> &stream,
|
||||
const std::basic_string<typename Ptree::key_type::value_type> &key,
|
||||
const Ptree &pt,
|
||||
int indent,
|
||||
const xml_writer_settings<typename Ptree::key_type::value_type> & settings)
|
||||
{
|
||||
|
||||
typedef typename Ptree::key_type::value_type Ch;
|
||||
typedef typename std::basic_string<Ch> Str;
|
||||
typedef typename Ptree::const_iterator It;
|
||||
|
||||
bool want_pretty = settings.indent_count > 0;
|
||||
// Find if elements present
|
||||
bool has_elements = false;
|
||||
bool has_attrs_only = pt.data().empty();
|
||||
for (It it = pt.begin(), end = pt.end(); it != end; ++it)
|
||||
{
|
||||
if (it->first != xmlattr<Ch>() )
|
||||
{
|
||||
has_attrs_only = false;
|
||||
if (it->first != xmltext<Ch>())
|
||||
{
|
||||
has_elements = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Write element
|
||||
if (pt.data().empty() && pt.empty()) // Empty key
|
||||
{
|
||||
if (indent >= 0)
|
||||
{
|
||||
write_xml_indent(stream,indent,settings);
|
||||
stream << Ch('<') << key <<
|
||||
Ch('/') << Ch('>');
|
||||
if (want_pretty)
|
||||
stream << Ch('\n');
|
||||
}
|
||||
}
|
||||
else // Nonempty key
|
||||
{
|
||||
|
||||
// Write opening tag, attributes and data
|
||||
if (indent >= 0)
|
||||
{
|
||||
|
||||
// Write opening brace and key
|
||||
write_xml_indent(stream,indent,settings);
|
||||
stream << Ch('<') << key;
|
||||
|
||||
// Write attributes
|
||||
if (optional<const Ptree &> attribs = pt.get_child_optional(xmlattr<Ch>()))
|
||||
for (It it = attribs.get().begin(); it != attribs.get().end(); ++it)
|
||||
stream << Ch(' ') << it->first << Ch('=') <<
|
||||
Ch('"') << it->second.template get_value<std::basic_string<Ch> >() << Ch('"');
|
||||
|
||||
if ( has_attrs_only )
|
||||
{
|
||||
// Write closing brace
|
||||
stream << Ch('/') << Ch('>');
|
||||
if (want_pretty)
|
||||
stream << Ch('\n');
|
||||
}
|
||||
else
|
||||
{
|
||||
// Write closing brace
|
||||
stream << Ch('>');
|
||||
|
||||
// Break line if needed and if we want pretty-printing
|
||||
if (has_elements && want_pretty)
|
||||
stream << Ch('\n');
|
||||
}
|
||||
}
|
||||
|
||||
// Write data text, if present
|
||||
if (!pt.data().empty())
|
||||
write_xml_text(stream,
|
||||
pt.template get_value<std::basic_string<Ch> >(),
|
||||
indent + 1, has_elements && want_pretty, settings);
|
||||
|
||||
// Write elements, comments and texts
|
||||
for (It it = pt.begin(); it != pt.end(); ++it)
|
||||
{
|
||||
if (it->first == xmlattr<Ch>())
|
||||
continue;
|
||||
else if (it->first == xmlcomment<Ch>())
|
||||
write_xml_comment(stream,
|
||||
it->second.template get_value<std::basic_string<Ch> >(),
|
||||
indent + 1, want_pretty, settings);
|
||||
else if (it->first == xmltext<Ch>())
|
||||
write_xml_text(stream,
|
||||
it->second.template get_value<std::basic_string<Ch> >(),
|
||||
indent + 1, has_elements && want_pretty, settings);
|
||||
else
|
||||
write_xml_element(stream, it->first, it->second,
|
||||
indent + 1, settings);
|
||||
}
|
||||
|
||||
// Write closing tag
|
||||
if (indent >= 0 && !has_attrs_only)
|
||||
{
|
||||
if (has_elements)
|
||||
write_xml_indent(stream,indent,settings);
|
||||
stream << Ch('<') << Ch('/') << key << Ch('>');
|
||||
if (want_pretty)
|
||||
stream << Ch('\n');
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
template<class Ptree>
|
||||
void write_xml_internal(std::basic_ostream<typename Ptree::key_type::value_type> &stream,
|
||||
const Ptree &pt,
|
||||
const std::string &filename,
|
||||
const xml_writer_settings<typename Ptree::key_type::value_type> & settings)
|
||||
{
|
||||
typedef typename Ptree::key_type::value_type Ch;
|
||||
typedef typename std::basic_string<Ch> Str;
|
||||
stream << detail::widen<Ch>("<?xml version=\"1.0\" encoding=\"")
|
||||
<< settings.encoding
|
||||
<< detail::widen<Ch>("\"?>\n");
|
||||
write_xml_element(stream, Str(), pt, -1, settings);
|
||||
if (!stream)
|
||||
BOOST_PROPERTY_TREE_THROW(xml_parser_error("write error", filename, 0));
|
||||
}
|
||||
|
||||
} } }
|
||||
|
||||
#endif
|
||||
62
test/external/boost/property_tree/detail/xml_parser_writer_settings.hpp
vendored
Normal file
62
test/external/boost/property_tree/detail/xml_parser_writer_settings.hpp
vendored
Normal file
@@ -0,0 +1,62 @@
|
||||
// ----------------------------------------------------------------------------
|
||||
// Copyright (C) 2002-2007 Marcin Kalicinski
|
||||
// Copyright (C) 2007 Alexey Baskakov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// For more information, see www.boost.org
|
||||
// ----------------------------------------------------------------------------
|
||||
#ifndef BOOST_PROPERTY_TREE_DETAIL_XML_PARSER_WRITER_SETTINGS_HPP_INCLUDED
|
||||
#define BOOST_PROPERTY_TREE_DETAIL_XML_PARSER_WRITER_SETTINGS_HPP_INCLUDED
|
||||
|
||||
#include <string>
|
||||
#include <boost/property_tree/detail/ptree_utils.hpp>
|
||||
|
||||
namespace boost { namespace property_tree { namespace xml_parser
|
||||
{
|
||||
|
||||
// Naively convert narrow string to another character type
|
||||
template<class Ch>
|
||||
std::basic_string<Ch> widen(const char *text)
|
||||
{
|
||||
std::basic_string<Ch> result;
|
||||
while (*text)
|
||||
{
|
||||
result += Ch(*text);
|
||||
++text;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
//! Xml writer settings. The default settings lead to no pretty printing.
|
||||
template<class Ch>
|
||||
class xml_writer_settings
|
||||
{
|
||||
public:
|
||||
xml_writer_settings(Ch inchar = Ch(' '),
|
||||
typename std::basic_string<Ch>::size_type incount = 0,
|
||||
const std::basic_string<Ch> &enc = widen<Ch>("utf-8"))
|
||||
: indent_char(inchar)
|
||||
, indent_count(incount)
|
||||
, encoding(enc)
|
||||
{
|
||||
}
|
||||
|
||||
Ch indent_char;
|
||||
typename std::basic_string<Ch>::size_type indent_count;
|
||||
std::basic_string<Ch> encoding;
|
||||
};
|
||||
|
||||
template <class Ch>
|
||||
xml_writer_settings<Ch> xml_writer_make_settings(Ch indent_char = Ch(' '),
|
||||
typename std::basic_string<Ch>::size_type indent_count = 0,
|
||||
const std::basic_string<Ch> &encoding = widen<Ch>("utf-8"))
|
||||
{
|
||||
return xml_writer_settings<Ch>(indent_char, indent_count, encoding);
|
||||
}
|
||||
|
||||
} } }
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user