| #ifndef RAPIDXML_UTILS_HPP_INCLUDED |
| #define RAPIDXML_UTILS_HPP_INCLUDED |
| |
| // Copyright (C) 2006, 2009 Marcin Kalicinski |
| // Version 1.13 |
| // Revision $DateTime: 2009/05/13 01:46:17 $ |
| //! \file rapidxml_utils.hpp This file contains high-level rapidxml utilities that can be useful |
| //! in certain simple scenarios. They should probably not be used if maximizing performance is the main objective. |
| |
| #include "rapidxml.hpp" |
| #include <vector> |
| #include <string> |
| #include <fstream> |
| #include <stdexcept> |
| |
| namespace rapidxml |
| { |
| |
| //! Represents data loaded from a file |
| template<class Ch = char> |
| class file |
| { |
| |
| public: |
| |
| //! Loads file into the memory. Data will be automatically destroyed by the destructor. |
| //! \param filename Filename to load. |
| file(const char *filename) |
| { |
| using namespace std; |
| |
| // Open stream |
| basic_ifstream<Ch> stream(filename, ios::binary); |
| if (!stream) |
| throw runtime_error(string("cannot open file ") + filename); |
| stream.unsetf(ios::skipws); |
| |
| // Determine stream size |
| stream.seekg(0, ios::end); |
| size_t size = stream.tellg(); |
| stream.seekg(0); |
| |
| // Load data and add terminating 0 |
| m_data.resize(size + 1); |
| stream.read(&m_data.front(), static_cast<streamsize>(size)); |
| m_data[size] = 0; |
| } |
| |
| //! Loads file into the memory. Data will be automatically destroyed by the destructor |
| //! \param stream Stream to load from |
| file(std::basic_istream<Ch> &stream) |
| { |
| using namespace std; |
| |
| // Load data and add terminating 0 |
| stream.unsetf(ios::skipws); |
| m_data.assign(istreambuf_iterator<Ch>(stream), istreambuf_iterator<Ch>()); |
| if (stream.fail() || stream.bad()) |
| throw runtime_error("error reading stream"); |
| m_data.push_back(0); |
| } |
| |
| //! Gets file data. |
| //! \return Pointer to data of file. |
| Ch *data() |
| { |
| return &m_data.front(); |
| } |
| |
| //! Gets file data. |
| //! \return Pointer to data of file. |
| const Ch *data() const |
| { |
| return &m_data.front(); |
| } |
| |
| //! Gets file data size. |
| //! \return Size of file data, in characters. |
| std::size_t size() const |
| { |
| return m_data.size(); |
| } |
| |
| private: |
| |
| std::vector<Ch> m_data; // File data |
| |
| }; |
| |
| //! Counts children of node. Time complexity is O(n). |
| //! \return Number of children of node |
| template<class Ch> |
| inline std::size_t count_children(xml_node<Ch> *node) |
| { |
| xml_node<Ch> *child = node->first_node(); |
| std::size_t count = 0; |
| while (child) |
| { |
| ++count; |
| child = child->next_sibling(); |
| } |
| return count; |
| } |
| |
| //! Counts attributes of node. Time complexity is O(n). |
| //! \return Number of attributes of node |
| template<class Ch> |
| inline std::size_t count_attributes(xml_node<Ch> *node) |
| { |
| xml_attribute<Ch> *attr = node->first_attribute(); |
| std::size_t count = 0; |
| while (attr) |
| { |
| ++count; |
| attr = attr->next_attribute(); |
| } |
| return count; |
| } |
| |
| } |
| |
| #endif |