lean cpp library
A lean C++ library providing efficient utility classes for high-performance C++ applications.
xml_file.h
00001 /*****************************************************/
00002 /* lean XML                     (c) Tobias Zirr 2011 */
00003 /*****************************************************/
00004 
00005 #ifndef LEAN_XML_XML_FILE
00006 #define LEAN_XML_XML_FILE
00007 
00008 #include "../lean.h"
00009 #include "../strings/types.h"
00010 #include "../meta/constexpr.h"
00011 #include "../io/raw_file.h"
00012 #include "../io/raw_file_inserter.h"
00013 #include "../rapidxml/rapidxml.hpp"
00014 #include "../rapidxml/rapidxml_print.hpp"
00015 
00016 #ifndef LEAN_XML_FILE_SAVE_BATCH_SIZE
00017 
00018 
00019     #define LEAN_XML_FILE_SAVE_BATCH_SIZE 4096
00020 #endif
00021 
00022 namespace lean
00023 {
00024 namespace xml
00025 {
00026 
00027 namespace impl
00028 {
00030     template <class Char>
00031     inline char* load_xml_source(const utf8_ntri &fileName, rapidxml::xml_document<Char> &document)
00032     {
00033         raw_file file(fileName, file::read);
00034         
00035         size_t fileSize = static_cast<size_t>(file.size());
00036         char *source = document.allocate_string(nullptr, fileSize);
00037         
00038         file.read(source, fileSize); // TODO: strict (exception on error)
00039         return source;
00040     }
00041 }
00042 
00044 template <int ParseFlags, class Char>
00045 LEAN_INLINE void load_xml_file(const utf8_ntri &fileName, rapidxml::xml_document<Char> &document)
00046 {
00047     try
00048     {
00049         document.parse<ParseFlags>(
00050             impl::load_xml_source(fileName, document) );
00051     }
00052     catch(rapidxml::parse_error &error)
00053     {
00054         throw std::runtime_error(error.what());
00055     }
00056 }
00057 
00059 template <int PrintFlags, class Char>
00060 LEAN_INLINE void save_xml_file(const utf8_ntri &fileName, const rapidxml::xml_node<Char> &document)
00061 {
00062     raw_file file(fileName, file::write, file::overwrite);
00063     print(raw_file_inserter<LEAN_XML_FILE_SAVE_BATCH_SIZE>(file).iter(), document, PrintFlags);
00064 }
00065 
00067 template <class Char = char>
00068 class xml_file
00069 {
00070 private:
00071     rapidxml::xml_document<Char> m_document;
00072 
00073 public:
00075     LEAN_INLINE xml_file() { }
00077     LEAN_INLINE explicit xml_file(const utf8_ntri &name)
00078     {
00079         load_xml_file<rapidxml::parse_trim_whitespace | rapidxml::parse_normalize_whitespace>(name, m_document);
00080     }
00082     template <int ParseFlags>
00083     LEAN_INLINE xml_file(const utf8_ntri &name, ce_int<ParseFlags>)
00084     {
00085         load_xml_file<ParseFlags>(name, m_document);
00086     }
00087 
00089     LEAN_INLINE void save(const utf8_ntri &name) const
00090     {
00091         save_xml_file<0>(name, m_document);
00092     }
00094     template <int ParseFlags>
00095     LEAN_INLINE void save(const utf8_ntri &name, ce_int<ParseFlags>) const
00096     {
00097         save_xml_file<PrintFlags>(name, m_document);
00098     }
00099 
00101     LEAN_INLINE rapidxml::xml_document<Char>& document() { return m_document; }
00103     LEAN_INLINE const rapidxml::xml_document<Char>& document() const { return m_document; }
00104 };
00105 
00106 } // namespace
00107 
00108 using xml::xml_file;
00109 
00110 } // namespace
00111 
00112 #endif