📄 tree_to_xml.ipp
字号:
/*=============================================================================
Copyright (c) 2001-2006 Hartmut Kaiser
Copyright (c) 2001-2003 Daniel Nuffer
http://spirit.sourceforge.net/
Use, modification and distribution is subject to 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)
=============================================================================*/
#if !defined(TREE_TO_XML_IPP)
#define TREE_TO_XML_IPP
#include <cstdio>
#include <cstdarg>
#include <locale>
#include <map>
#include <iostream>
#include <boost/config.hpp>
#ifdef BOOST_NO_STRINGSTREAM
#include <strstream>
#define BOOST_SPIRIT_OSSTREAM std::ostrstream
inline
std::string BOOST_SPIRIT_GETSTRING(std::ostrstream& ss)
{
ss << ends;
std::string rval = ss.str();
ss.freeze(false);
return rval;
}
#else
#include <sstream>
#define BOOST_SPIRIT_GETSTRING(ss) ss.str()
#define BOOST_SPIRIT_OSSTREAM std::basic_ostringstream<CharT>
#endif
namespace boost { namespace spirit {
namespace impl {
///////////////////////////////////////////////////////////////////////////
template <typename CharT>
struct string_lit;
template <>
struct string_lit<char>
{
static char get(char c) { return c; }
static char const* get(char const* str = "") { return str; }
};
template <>
struct string_lit<wchar_t>
{
static wchar_t const *to_wchar_t(char const* source)
{
typedef std::ctype<wchar_t> ctype_t;
static wchar_t result[64];
using namespace std; // some systems have size_t in ns std
size_t len = strlen(source);
BOOST_ASSERT(len < sizeof(result)/sizeof(result[0]));
std::use_facet<ctype_t>(std::locale())
.widen(source, source + len, result);
return result;
}
static wchar_t get(char c)
{
typedef std::ctype<wchar_t> ctype_t;
return std::use_facet<ctype_t>(std::locale()).widen(c);
}
static wchar_t const* get(char const* str = "")
{
return to_wchar_t(str);
}
};
}
// xml formatting helper classes
namespace xml {
template <typename CharT>
inline void
encode (std::basic_string<CharT> &str, char s, char const *r, int len)
{
typedef typename std::basic_string<CharT>::size_type size_type;
size_type pos = 0;
while ((pos = str.find_first_of (impl::string_lit<CharT>::get(s), pos)) !=
size_type(std::basic_string<CharT>::npos))
{
str.replace (pos, 1, impl::string_lit<CharT>::get(r));
pos += len;
}
}
template <typename CharT>
inline std::basic_string<CharT>
encode (std::basic_string<CharT> str)
{
encode(str, '&', "&", 3);
encode(str, '<', "<", 2);
encode(str, '>', ">", 2);
encode(str, '\r', "\\r", 1);
encode(str, '\n', "\\n", 1);
return str;
}
template <typename CharT>
inline std::basic_string<CharT>
encode (CharT const *text)
{
return encode (std::basic_string<CharT>(text));
}
// format a xml attribute
template <typename CharT>
struct attribute
{
attribute()
{
}
attribute (CharT const *key_, CharT const *value_) :
key (key_), value(value_)
{
}
bool has_value()
{
return value.size() > 0;
}
std::basic_string<CharT> key;
std::basic_string<CharT> value;
};
template <typename CharT>
inline std::basic_ostream<CharT>&
operator<< (std::basic_ostream<CharT> &ostrm, attribute<CharT> const &attr)
{
if (0 == attr.key.size())
return ostrm;
ostrm << impl::string_lit<CharT>::get(" ") << encode(attr.key)
<< impl::string_lit<CharT>::get("=\"") << encode(attr.value)
<< impl::string_lit<CharT>::get("\"");
return ostrm;
}
// output a xml element (base class, not used directly)
template <typename CharT>
class element
{
protected:
element(std::basic_ostream<CharT> &ostrm_, bool incr_indent_ = true)
: ostrm(ostrm_), incr_indent(incr_indent_)
{
if (incr_indent) ++get_indent();
}
~element()
{
if (incr_indent) --get_indent();
}
public:
void output_space ()
{
for (int i = 0; i < get_indent(); i++)
ostrm << impl::string_lit<CharT>::get(" ");
}
protected:
int &get_indent()
{
static int indent;
return indent;
}
std::basic_ostream<CharT> &ostrm;
bool incr_indent;
};
// a xml node
template <typename CharT>
class node : public element<CharT>
{
public:
node (std::basic_ostream<CharT> &ostrm_, CharT const *tag_,
attribute<CharT> &attr)
: element<CharT>(ostrm_), tag(tag_)
{
this->output_space();
this->ostrm
<< impl::string_lit<CharT>::get("<") << tag_ << attr
<< impl::string_lit<CharT>::get(">\n");
}
node (std::basic_ostream<CharT> &ostrm_, CharT const *tag_)
: element<CharT>(ostrm_), tag(tag_)
{
this->output_space();
this->ostrm
<< impl::string_lit<CharT>::get("<") << tag_
<< impl::string_lit<CharT>::get(">\n");
}
~node()
{
this->output_space();
this->ostrm
<< impl::string_lit<CharT>::get("</") << tag
<< impl::string_lit<CharT>::get(">\n");
}
private:
std::basic_string<CharT> tag;
};
template <typename CharT>
class text : public element<CharT>
{
public:
text (std::basic_ostream<CharT> &ostrm_, CharT const *tag,
CharT const *textlit)
: element<CharT>(ostrm_)
{
this->output_space();
this->ostrm
<< impl::string_lit<CharT>::get("<") << tag
<< impl::string_lit<CharT>::get(">") << encode(textlit)
<< impl::string_lit<CharT>::get("</") << tag
<< impl::string_lit<CharT>::get(">\n");
}
text (std::basic_ostream<CharT> &ostrm_, CharT const *tag,
CharT const *textlit, attribute<CharT> &attr)
: element<CharT>(ostrm_)
{
this->output_space();
this->ostrm
<< impl::string_lit<CharT>::get("<") << tag << attr
<< impl::string_lit<CharT>::get(">") << encode(textlit)
<< impl::string_lit<CharT>::get("</") << tag
<< impl::string_lit<CharT>::get(">\n");
}
text (std::basic_ostream<CharT> &ostrm_, CharT const *tag,
CharT const *textlit, attribute<CharT> &attr1,
attribute<CharT> &attr2)
: element<CharT>(ostrm_)
{
this->output_space();
this->ostrm
<< impl::string_lit<CharT>::get("<") << tag << attr1 << attr2
<< impl::string_lit<CharT>::get(">") << encode(textlit)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -