rapidxml_utils.hpp 3.3 KB

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