XmlParser 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. /* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2009 Robert Osfield
  2. *
  3. * This library is open source and may be redistributed and/or modified under
  4. * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
  5. * (at your option) any later version. The full license is in LICENSE file
  6. * included with this distribution, and on the openscenegraph.org website.
  7. *
  8. * This library is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * OpenSceneGraph Public License for more details.
  12. */
  13. #ifndef OSGDB_XML_PARSER
  14. #define OSGDB_XML_PARSER 1
  15. #include <osgDB/Registry>
  16. namespace osgDB {
  17. // forward declare
  18. class XmlNode;
  19. /** read an Xml file, find the file in Options DataFilePathList.*/
  20. extern OSGDB_EXPORT XmlNode* readXmlFile(const std::string& filename,const Options* options);
  21. /** read an Xml file, find the file in osgDB::Registry's eaderWriter::Options DataFilePathList.*/
  22. inline XmlNode* readXmlFile(const std::string& filename)
  23. {
  24. return readXmlFile(filename, osgDB::Registry::instance()->getOptions());
  25. }
  26. /** read an Xml from from an istream.*/
  27. extern OSGDB_EXPORT XmlNode* readXmlStream(std::istream& fin);
  28. extern OSGDB_EXPORT std::string trimEnclosingSpaces(const std::string& str);
  29. /** XmlNode class for very basic reading and writing of xml files.*/
  30. class OSGDB_EXPORT XmlNode : public osg::Referenced
  31. {
  32. public:
  33. XmlNode();
  34. enum NodeType
  35. {
  36. UNASSIGNED,
  37. ATOM,
  38. NODE,
  39. GROUP,
  40. ROOT,
  41. COMMENT,
  42. INFORMATION
  43. };
  44. typedef std::map< std::string, std::string > Properties;
  45. typedef std::vector< osg::ref_ptr<XmlNode> > Children;
  46. NodeType type;
  47. std::string name;
  48. std::string contents;
  49. Properties properties;
  50. Children children;
  51. std::string getTrimmedContents() const { return trimEnclosingSpaces(contents); }
  52. public:
  53. class OSGDB_EXPORT ControlMap
  54. {
  55. public:
  56. ControlMap();
  57. typedef std::map< std::string, int > ControlToCharacterMap;
  58. typedef std::map< int, std::string> CharacterToControlMap;
  59. void addControlToCharacter(const std::string& control, int c);
  60. ControlToCharacterMap _controlToCharacterMap;
  61. CharacterToControlMap _characterToControlMap;
  62. private:
  63. void setUpControlMappings();
  64. };
  65. class OSGDB_EXPORT Input : public ControlMap
  66. {
  67. public:
  68. Input();
  69. Input(const Input&);
  70. ~Input();
  71. typedef std::string::size_type size_type;
  72. void open(const std::string& filename);
  73. void attach(std::istream& istream);
  74. void readAllDataIntoBuffer();
  75. operator bool () const { return _currentPos<_buffer.size(); }
  76. size_type currentPosition() const { return _currentPos; }
  77. int get() { if (_currentPos<_buffer.size()) return static_cast<unsigned char>(_buffer[_currentPos++]); else return -1; }
  78. int operator [] (size_type i) const { if ((_currentPos+i)<_buffer.size()) return static_cast<unsigned char>(_buffer[_currentPos+i]); else return -1; }
  79. void operator ++ () { if (_currentPos<_buffer.size()) ++_currentPos; }
  80. void operator += (size_type n) { if ((_currentPos+n)<_buffer.size()) _currentPos+=n; else _currentPos = _buffer.size(); }
  81. void skipWhiteSpace();
  82. std::string substr(size_type pos, size_type n=std::string::npos) { return (_currentPos<_buffer.size()) ? _buffer.substr(_currentPos+pos,n) : std::string(); }
  83. size_type find(const std::string& str)
  84. {
  85. if (_currentPos<_buffer.size())
  86. {
  87. size_type pos = _buffer.find(str, _currentPos);
  88. if (pos==std::string::npos) return std::string::npos;
  89. else return pos-_currentPos;
  90. } else return std::string::npos;
  91. }
  92. bool match(const std::string& str) { return (_currentPos<_buffer.size()) ? _buffer.compare(_currentPos, str.size(), str)==0 : false; }
  93. enum Encoding
  94. {
  95. ENCODING_ASCII,
  96. ENCODING_UTF8
  97. };
  98. void setEncoding(Encoding encoding) { _encoding = encoding; }
  99. Encoding getEncoding() const { return _encoding; }
  100. inline void copyCharacterToString(std::string& str)
  101. {
  102. if (_currentPos>=_buffer.size()) return;
  103. switch (_encoding)
  104. {
  105. case(ENCODING_UTF8) :
  106. {
  107. int char0 = static_cast<unsigned char>(_buffer[_currentPos]); ++_currentPos;
  108. str.push_back(char0);
  109. if (char0 < 0x80 || _currentPos>=_buffer.size()) break; // 1-byte character
  110. str.push_back(_buffer[_currentPos]); ++_currentPos;
  111. if (char0<0xe0 || _currentPos<_buffer.size()) break; // 2-byte character
  112. str.push_back(_buffer[_currentPos]); ++_currentPos;
  113. if (char0<0xf0 || _currentPos>=_buffer.size()) break; // 3-byte character
  114. str.push_back(_buffer[_currentPos]); ++_currentPos;
  115. if (char0<0xf8 || _currentPos>=_buffer.size()) break; // 4-byte character
  116. if (_currentPos>=_buffer.size()) break;
  117. str.push_back(_buffer[_currentPos]); ++_currentPos; // 5-byte character?
  118. break;
  119. }
  120. case(ENCODING_ASCII) :
  121. default:
  122. str.push_back(_buffer[_currentPos]);
  123. ++_currentPos;
  124. return;
  125. }
  126. }
  127. private:
  128. size_type _currentPos;
  129. std::ifstream _fin;
  130. std::string _buffer;
  131. Encoding _encoding;
  132. };
  133. bool read(Input& input);
  134. bool write(std::ostream& fout, const std::string& indent = "") const;
  135. bool write(const ControlMap& controlMap, std::ostream& fout, const std::string& indent = "") const;
  136. bool writeString(const ControlMap& controlMap, std::ostream& fout, const std::string& str) const;
  137. protected:
  138. bool writeChildren(const ControlMap& controlMap, std::ostream& fout, const std::string& indent) const;
  139. bool writeProperties(const ControlMap& controlMap, std::ostream& fout) const;
  140. bool readAndReplaceControl(std::string& in_contents, Input& input) const;
  141. };
  142. }
  143. #endif