/* -*-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. */ #include #include #include using namespace osgDB; XmlNode* osgDB::readXmlFile(const std::string& filename,const Options* options) { std::string foundFile = osgDB::findDataFile(filename, options); if (!foundFile.empty()) { XmlNode::Input input; input.open(foundFile); if (!input) { osg::notify(osg::NOTICE)<<"Could not open XML file: "< root = new XmlNode; root->read(input); return root.release(); } else { osg::notify(osg::NOTICE)<<"Could not find XML file: "< root = new XmlNode; root->read(input); return root.release(); } XmlNode::Input::Input(): _currentPos(0) { setUpControlMappings(); } XmlNode::Input::Input(const Input&): _currentPos(0) { setUpControlMappings(); } XmlNode::Input::~Input() { } void XmlNode::Input::setUpControlMappings() { addControlToCharacter("&",'&'); addControlToCharacter("<",'<'); addControlToCharacter(">",'>'); addControlToCharacter(""",'"'); addControlToCharacter("'",'\''); } void XmlNode::Input::addControlToCharacter(const std::string& control, int c) { _controlToCharacterMap[control] = c; _characterToControlMap[c] = control; } void XmlNode::Input::open(const std::string& filename) { _fin.open(filename.c_str()); } void XmlNode::Input::attach(std::istream& fin) { std::ios &fios = _fin; fios.rdbuf(fin.rdbuf()); } void XmlNode::Input::readAllDataIntoBuffer() { while(_fin) { int c = _fin.get(); if (c>=0 && c<=255) { _buffer.push_back(c); } } } void XmlNode::Input::skipWhiteSpace() { while(_currentPos<_buffer.size() && _buffer[_currentPos]==' ') { // osg::notify(osg::NOTICE)<<"_currentPos="<<_currentPos<<"_buffer.size()="<<_buffer.size()<<" v="<<_buffer[_currentPos]<type = XmlNode::COMMENT; children.push_back(commentNode); input += 4; XmlNode::Input::size_type end = input.find("-->"); commentNode->contents = input.substr(0, end); if (end!=std::string::npos) { osg::notify(osg::INFO)<<"Valid Comment record ["<contents<<"]"<contents<<"]"<"); std::string comment = input.substr(0, end); if (end!=std::string::npos) { osg::notify(osg::INFO)<<"Valid end tag ["<type = XmlNode::INFORMATION; children.push_back(commentNode); input += 2; XmlNode::Input::size_type end = input.find("?>"); commentNode->contents = input.substr(0, end); if (end!=std::string::npos) { osg::notify(osg::INFO)<<"Valid infomation record ["<contents<<"]"<contents<<"]"<type = XmlNode::NODE; children.push_back(childNode); input += 1; input.skipWhiteSpace(); int c = 0; while ((c=input[0])>=0 && c!=' ' && c!='>' ) { childNode->name.push_back(c); ++input; } while ((c=input[0])>=0 && c!='>') { Input::size_type prev_pos = input.currentPosition(); input.skipWhiteSpace(); std::string option; std::string value; while((c=input[0])>=0 && c!='>' && c!='"' && c!='\'' && c!='=' && c!=' ') { option.push_back(c); ++input; } input.skipWhiteSpace(); if (input[0]=='=') { ++input; input.skipWhiteSpace(); if (input[0]=='"') { ++input; while((c=input[0])>=0 && c!='"') { value.push_back(c); ++input; } ++input; } else if (input[0]=='\'') { ++input; while((c=input[0])>=0 && c!='\'') { value.push_back(c); ++input; } ++input; } else { ++input; while((c=input[0])>=0 && c!=' ' && c!='"' && c!='\'' && c!='>') { value.push_back(c); ++input; } } } if (prev_pos == input.currentPosition()) { osg::notify(osg::NOTICE)<<"Error, parser iterator note advanced, position: "<properties[option] = value; } } if ((c=input[0])>=0 && c=='>' ) { ++input; osg::notify(osg::INFO)<<"Valid tag ["<name<<"]"<read(input); if (!result) return false; if (type==NODE && !children.empty()) type = GROUP; } else { osg::notify(osg::NOTICE)<<"Unclosed tag ["<name<<"]"<first<<"\""; writeString(fout,oitr->second); fout<<"\""<write(fout); } return true; } case(NODE): { fout<<"<"<first<<"=\""; writeString(fout,oitr->second); fout<<"\""; } fout<<">"; for(Children::const_iterator citr = children.begin(); citr != children.end(); ++citr) { (*citr)->write(fout); } if (!contents.empty()) writeString(fout,contents); fout<<""<first<<"=\""; writeString(fout,oitr->second); fout<<"\""; } fout<<">"<write(fout); } fout<<""<"<"<