rapidxml_utils.hpp 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. #ifndef RAPIDXML_UTILS_HPP_INCLUDED
  2. #define RAPIDXML_UTILS_HPP_INCLUDED
  3. // Copyright (C) 2006, 2009 Marcin Kalicinski
  4. // Version 1.13
  5. // Revision $DateTime: 2009/05/13 01:46:17 $
  6. //! \file rapidxml_utils.hpp This file contains high-level rapidxml utilities
  7. //! that can be useful in certain simple scenarios. They should probably not be
  8. //! used if maximizing performance is the main objective.
  9. #include <fstream>
  10. #include <stdexcept>
  11. #include <string>
  12. #include <vector>
  13. #include "rapidxml.hpp"
  14. namespace rapidxml {
  15. //! Represents data loaded from a file
  16. template <class Ch = char>
  17. class file {
  18. public:
  19. //! Loads file into the memory. Data will be automatically destroyed by the
  20. //! destructor. \param filename Filename to load.
  21. file(const char *filename) {
  22. using namespace std;
  23. // Open stream
  24. basic_ifstream<Ch> stream(filename, ios::binary);
  25. if (!stream) throw runtime_error(string("cannot open file ") + filename);
  26. stream.unsetf(ios::skipws);
  27. // Determine stream size
  28. stream.seekg(0, ios::end);
  29. size_t size = stream.tellg();
  30. stream.seekg(0);
  31. // Load data and add terminating 0
  32. m_data.resize(size + 1);
  33. stream.read(&m_data.front(), static_cast<streamsize>(size));
  34. m_data[size] = 0;
  35. }
  36. //! Loads file into the memory. Data will be automatically destroyed by the
  37. //! destructor \param stream Stream to load from
  38. file(std::basic_istream<Ch> &stream) {
  39. using namespace std;
  40. // Load data and add terminating 0
  41. stream.unsetf(ios::skipws);
  42. m_data.assign(istreambuf_iterator<Ch>(stream), istreambuf_iterator<Ch>());
  43. if (stream.fail() || stream.bad())
  44. throw runtime_error("error reading stream");
  45. m_data.push_back(0);
  46. }
  47. //! Gets file data.
  48. //! \return Pointer to data of file.
  49. Ch *data() { return &m_data.front(); }
  50. //! Gets file data.
  51. //! \return Pointer to data of file.
  52. const Ch *data() const { return &m_data.front(); }
  53. //! Gets file data size.
  54. //! \return Size of file data, in characters.
  55. std::size_t size() const { return m_data.size(); }
  56. private:
  57. std::vector<Ch> m_data; // File data
  58. };
  59. //! Counts children of node. Time complexity is O(n).
  60. //! \return Number of children of node
  61. template <class Ch>
  62. inline std::size_t count_children(xml_node<Ch> *node) {
  63. xml_node<Ch> *child = node->first_node();
  64. std::size_t count = 0;
  65. while (child) {
  66. ++count;
  67. child = child->next_sibling();
  68. }
  69. return count;
  70. }
  71. //! Counts attributes of node. Time complexity is O(n).
  72. //! \return Number of attributes of node
  73. template <class Ch>
  74. inline std::size_t count_attributes(xml_node<Ch> *node) {
  75. xml_attribute<Ch> *attr = node->first_attribute();
  76. std::size_t count = 0;
  77. while (attr) {
  78. ++count;
  79. attr = attr->next_attribute();
  80. }
  81. return count;
  82. }
  83. } // namespace rapidxml
  84. #endif