lean cpp library
A lean C++ library providing efficient utility classes for high-performance C++ applications.
xml/utility.h
00001 /*****************************************************/
00002 /* lean XML                     (c) Tobias Zirr 2011 */
00003 /*****************************************************/
00004 
00005 #ifndef LEAN_XML_UTILITY
00006 #define LEAN_XML_UTILITY
00007 
00008 #include "../lean.h"
00009 #include "../strings/types.h"
00010 #include "../rapidxml/rapidxml.hpp"
00011 
00012 namespace lean
00013 {
00014 namespace xml
00015 {
00016 
00017 namespace impl
00018 {
00019     template <class Char, class Traits>
00020     LEAN_INLINE Char* allocate_string(rapidxml::xml_document<Char> &document, const nullterminated_range_implicit<Char, Traits> &string)
00021     {
00022         return document.allocate_string(string.c_str(), string.size() + 1);
00023     }
00024 }
00025 using impl::allocate_string;
00026 
00028 template <class Char, class Range>
00029 LEAN_INLINE Char* allocate_string(rapidxml::xml_document<Char> &document, const Range &string)
00030 {
00031     // impl namespace required to avoid recursion
00032     return impl::allocate_string(document, make_ntr<Char>(string));
00033 }
00034 
00036 template <class Char, class Range1, class Rage2>
00037 LEAN_INLINE rapidxml::xml_attribute<Char>* allocate_attribute(rapidxml::xml_document<Char> &document, const Range1 &name, const Rage2 &value)
00038 {
00039     return document.allocate_attribute(
00040             allocate_string(document, name),
00041             allocate_string(document, value)
00042         );
00043 }
00044 
00046 template <class Char, class Range1, class Rage2>
00047 LEAN_INLINE void append_attribute(rapidxml::xml_document<Char> &document, rapidxml::xml_node<Char> &node, const Range1 &name, const Rage2 &value)
00048 {
00049     node.append_attribute( allocate_attribute(document, name, value) );
00050 }
00051 
00052 namespace impl
00053 {
00054     template <class Char, class Traits>
00055     LEAN_INLINE nullterminated_range<Char, Traits> get_attribute(const rapidxml::xml_node<Char> &node, const nullterminated_range_implicit<Char, Traits> &name)
00056     {
00057         rapidxml::xml_attribute<utf8_t> *att = node.first_attribute(name.c_str(), name.size());
00058         return (att)
00059             ? nullterminated_range<Char, Traits>(att->value(), att->value() + att->value_size())
00060             : nullterminated_range<Char, Traits>("");
00061     }
00062 }
00063 using impl::get_attribute;
00064 
00066 template <class Char, class Range>
00067 LEAN_INLINE nullterminated_range<Char> get_attribute(const rapidxml::xml_node<Char> &node, const Range &name)
00068 {
00069     // impl namespace required to avoid recursion
00070     return impl::get_attribute(node, make_ntr<Char>(name));
00071 }
00072 
00074 template <class Char, class Traits, class Range>
00075 LEAN_INLINE nullterminated_range<Char, Traits> get_attribute(const rapidxml::xml_node<Char> &node, const Range &name)
00076 {
00077     // impl namespace required to avoid recursion
00078     return impl::get_attribute(node, make_ntr<Char, Traits>(name));
00079 }
00080 
00081 namespace impl
00082 {
00083     template <class Char, class Traits, class StringTraits, class StringAlloc>
00084     LEAN_INLINE void get_attribute(const rapidxml::xml_node<Char> &node,
00085         const nullterminated_range_implicit<Char, Traits> &name,
00086         std::basic_string<Char, StringTraits, StringAlloc> &value)
00087     {
00088         rapidxml::xml_attribute<utf8_t> *att = node.first_attribute(name.c_str(), name.size());
00089 
00090         if (att)
00091             value.assign(att->value(), att->value_size());
00092     }
00093 }
00094 using impl::get_attribute;
00095 
00097 template <class Char, class Range, class StringTraits, class StringAlloc>
00098 LEAN_INLINE void get_attribute(const rapidxml::xml_node<Char> &node, const Range &name,
00099     std::basic_string<Char, StringTraits, StringAlloc> &value)
00100 {
00101     // impl namespace required to avoid recursion
00102     impl::get_attribute(node, make_ntr<Char>(name), value);
00103 }
00104 
00106 template <class Char>
00107 LEAN_INLINE rapidxml::xml_node<Char>* allocate_node(rapidxml::xml_document<Char> &document)
00108 {
00109     return document.allocate_node(rapidxml::node_element);
00110 }
00111 
00113 template <class Char, class Range>
00114 LEAN_INLINE rapidxml::xml_node<Char>* allocate_node(rapidxml::xml_document<Char> &document, const Range &name)
00115 {
00116     return document.allocate_node(
00117             rapidxml::node_element,
00118             allocate_string(document, name)
00119         );
00120 }
00121 
00123 template <class Char, class Range1, class Range2>
00124 LEAN_INLINE rapidxml::xml_node<Char>* allocate_node(rapidxml::xml_document<Char> &document, const Range1 &name, const Range2 &value)
00125 {
00126     return document.allocate_node(
00127             rapidxml::node_element,
00128             allocate_string(document, name),
00129             allocate_string(document, value)
00130         );
00131 }
00132 
00133 } // namespace
00134 
00135 using xml::allocate_string;
00136 using xml::allocate_attribute;
00137 using xml::append_attribute;
00138 using xml::get_attribute;
00139 using xml::allocate_node;
00140 
00141 } // namespace
00142 
00143 #endif