123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200 |
- /* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2009 Robert Osfield
- *
- * This library is open source and may be redistributed and/or modified under
- * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
- * (at your option) any later version. The full license is in LICENSE file
- * included with this distribution, and on the openscenegraph.org website.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * OpenSceneGraph Public License for more details.
- */
- #ifndef OSGDB_XML_PARSER
- #define OSGDB_XML_PARSER 1
- #include <osgDB/Registry>
- namespace osgDB {
- // forward declare
- class XmlNode;
- /** read an Xml file, find the file in Options DataFilePathList.*/
- extern OSGDB_EXPORT XmlNode* readXmlFile(const std::string& filename,const Options* options);
- /** read an Xml file, find the file in osgDB::Registry's eaderWriter::Options DataFilePathList.*/
- inline XmlNode* readXmlFile(const std::string& filename)
- {
- return readXmlFile(filename, osgDB::Registry::instance()->getOptions());
- }
- /** read an Xml from from an istream.*/
- extern OSGDB_EXPORT XmlNode* readXmlStream(std::istream& fin);
- extern OSGDB_EXPORT std::string trimEnclosingSpaces(const std::string& str);
- /** XmlNode class for very basic reading and writing of xml files.*/
- class OSGDB_EXPORT XmlNode : public osg::Referenced
- {
- public:
- XmlNode();
- enum NodeType
- {
- UNASSIGNED,
- ATOM,
- NODE,
- GROUP,
- ROOT,
- COMMENT,
- INFORMATION
- };
- typedef std::map< std::string, std::string > Properties;
- typedef std::vector< osg::ref_ptr<XmlNode> > Children;
- NodeType type;
- std::string name;
- std::string contents;
- Properties properties;
- Children children;
- std::string getTrimmedContents() const { return trimEnclosingSpaces(contents); }
- public:
- class OSGDB_EXPORT ControlMap
- {
- public:
- ControlMap();
- typedef std::map< std::string, int > ControlToCharacterMap;
- typedef std::map< int, std::string> CharacterToControlMap;
- void addControlToCharacter(const std::string& control, int c);
- ControlToCharacterMap _controlToCharacterMap;
- CharacterToControlMap _characterToControlMap;
- private:
- void setUpControlMappings();
- };
- class OSGDB_EXPORT Input : public ControlMap
- {
- public:
- Input();
- Input(const Input&);
- ~Input();
- typedef std::string::size_type size_type;
- void open(const std::string& filename);
- void attach(std::istream& istream);
- void readAllDataIntoBuffer();
- operator bool () const { return _currentPos<_buffer.size(); }
- size_type currentPosition() const { return _currentPos; }
- int get() { if (_currentPos<_buffer.size()) return static_cast<unsigned char>(_buffer[_currentPos++]); else return -1; }
- int operator [] (size_type i) const { if ((_currentPos+i)<_buffer.size()) return static_cast<unsigned char>(_buffer[_currentPos+i]); else return -1; }
- void operator ++ () { if (_currentPos<_buffer.size()) ++_currentPos; }
- void operator += (size_type n) { if ((_currentPos+n)<_buffer.size()) _currentPos+=n; else _currentPos = _buffer.size(); }
- void skipWhiteSpace();
- std::string substr(size_type pos, size_type n=std::string::npos) { return (_currentPos<_buffer.size()) ? _buffer.substr(_currentPos+pos,n) : std::string(); }
- size_type find(const std::string& str)
- {
- if (_currentPos<_buffer.size())
- {
- size_type pos = _buffer.find(str, _currentPos);
- if (pos==std::string::npos) return std::string::npos;
- else return pos-_currentPos;
- } else return std::string::npos;
- }
- bool match(const std::string& str) { return (_currentPos<_buffer.size()) ? _buffer.compare(_currentPos, str.size(), str)==0 : false; }
- enum Encoding
- {
- ENCODING_ASCII,
- ENCODING_UTF8
- };
- void setEncoding(Encoding encoding) { _encoding = encoding; }
- Encoding getEncoding() const { return _encoding; }
- inline void copyCharacterToString(std::string& str)
- {
- if (_currentPos>=_buffer.size()) return;
- switch (_encoding)
- {
- case(ENCODING_UTF8) :
- {
- int char0 = static_cast<unsigned char>(_buffer[_currentPos]); ++_currentPos;
- str.push_back(char0);
- if (char0 < 0x80 || _currentPos>=_buffer.size()) break; // 1-byte character
- str.push_back(_buffer[_currentPos]); ++_currentPos;
- if (char0<0xe0 || _currentPos<_buffer.size()) break; // 2-byte character
- str.push_back(_buffer[_currentPos]); ++_currentPos;
- if (char0<0xf0 || _currentPos>=_buffer.size()) break; // 3-byte character
- str.push_back(_buffer[_currentPos]); ++_currentPos;
- if (char0<0xf8 || _currentPos>=_buffer.size()) break; // 4-byte character
- if (_currentPos>=_buffer.size()) break;
- str.push_back(_buffer[_currentPos]); ++_currentPos; // 5-byte character?
- break;
- }
- case(ENCODING_ASCII) :
- default:
- str.push_back(_buffer[_currentPos]);
- ++_currentPos;
- return;
- }
- }
- private:
- size_type _currentPos;
- std::ifstream _fin;
- std::string _buffer;
- Encoding _encoding;
- };
- bool read(Input& input);
- bool write(std::ostream& fout, const std::string& indent = "") const;
- bool write(const ControlMap& controlMap, std::ostream& fout, const std::string& indent = "") const;
- bool writeString(const ControlMap& controlMap, std::ostream& fout, const std::string& str) const;
- protected:
- bool writeChildren(const ControlMap& controlMap, std::ostream& fout, const std::string& indent) const;
- bool writeProperties(const ControlMap& controlMap, std::ostream& fout) const;
- bool readAndReplaceControl(std::string& in_contents, Input& input) const;
- };
- }
- #endif
|