00001 /********************************************************************** 00002 xml.h Declaration of XMLConversion, 00003 declaration and definition of XMLBaseFormat and XMLMoleculeFormat 00004 Copyright (C) 2005-2006 by Chris Morley 00005 00006 This program is free software; you can redistribute it and/or modify 00007 it under the terms of the GNU General Public License as published by 00008 the Free Software Foundation version 2 of the License. 00009 00010 This program is distributed in the hope that it will be useful, 00011 but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 GNU General Public License for more details. 00014 ***********************************************************************/ 00015 00016 #ifndef OB_XML_H 00017 #define OB_XML_H 00018 00019 #include <typeinfo> 00020 00021 #include <openbabel/mol.h> 00022 #include <openbabel/obconversion.h> 00023 #include <openbabel/obmolecformat.h> 00024 00025 #include <libxml/xmlreader.h> 00026 #include <libxml/xmlwriter.h> 00027 #include <typeinfo> 00028 00029 namespace OpenBabel 00030 { 00031 00032 00033 //forward declaration 00034 class XMLBaseFormat; 00035 00036 //****************************************************** 00053 class XMLConversion : public OBConversion 00054 { 00055 public: 00057 XMLConversion(OBConversion* pConv); 00058 00060 ~XMLConversion(); 00061 00062 bool SetupReader(); 00063 bool SetupWriter(); 00064 00066 bool ReadXML(XMLBaseFormat* pFormat, OBBase* pOb); 00067 00070 int SkipXML(const char* ctag); 00071 00072 typedef std::map<std::string, XMLBaseFormat*> NsMapType; 00073 00076 static NsMapType& Namespaces() 00077 { 00078 static NsMapType ns; 00079 return ns; 00080 00081 //static NsMapType* nsm = NULL; 00082 //if (!nsm) 00083 // nsm = new NsMapType; 00084 //return *nsm; 00085 }; 00086 00087 static void RegisterXMLFormat(XMLBaseFormat* pFormat, 00088 bool IsDefault=false, const char* uri=NULL); 00089 00091 static XMLConversion* GetDerived(OBConversion* pConv, bool ForReading=true); 00092 00095 bool IsLast() 00096 { return _pConv->IsLast(); } 00097 int GetOutputIndex() 00098 { return _pConv->GetOutputIndex(); } 00099 00100 00101 xmlTextReaderPtr GetReader() const 00102 { return _reader; }; 00103 00104 xmlTextWriterPtr GetWriter() const 00105 { return _writer; }; 00106 00107 void OutputToStream() 00108 { 00109 xmlOutputBufferFlush(_buf); 00110 } 00111 00112 static XMLBaseFormat* GetDefaultXMLClass() //TODO make dependent on object type 00113 { return _pDefault;}; 00114 00115 void LookForNamespace() 00116 { _LookingForNamespace = true; }; 00117 00119 static int ReadStream(void * context, char * buffer, int len); 00120 static int WriteStream(void * context, const char * buffer, int len); 00121 //static int CloseStream(void* context); 00122 00123 std::string GetAttribute(const char* attrname); 00124 00126 std::string GetContent(); 00127 00129 bool GetContentInt(int& value); 00130 00132 bool GetContentDouble(double& value); 00133 00134 private: 00135 static XMLBaseFormat* _pDefault; 00136 OBConversion* _pConv; 00137 std::streampos _requestedpos, _lastpos; 00138 xmlTextReaderPtr _reader; 00139 xmlTextWriterPtr _writer; 00140 xmlOutputBufferPtr _buf; 00141 // xmlBufferPtr _buf; 00142 bool _LookingForNamespace; 00143 public: 00144 bool _SkipNextRead; 00145 }; 00146 00147 //************************************************* 00150 class XMLBaseFormat : public OBFormat 00151 { 00152 protected: 00153 XMLConversion* _pxmlConv; 00154 00155 //formating for output 00156 std::string _prefix; 00157 int baseindent, ind; 00158 std::string nsdecl; 00159 int _embedlevel; 00160 00161 public: 00162 ~XMLBaseFormat(){} 00163 virtual const char* NamespaceURI()const=0; 00164 virtual bool DoElement(const std::string& ElName){return false;}; 00165 virtual bool EndElement(const std::string& ElName){return false;}; 00167 virtual const char* EndTag(){return ">";}; 00168 00169 protected: 00170 xmlTextReaderPtr reader() const 00171 { 00172 return _pxmlConv->GetReader(); 00173 } 00174 00175 xmlTextWriterPtr writer() const 00176 { 00177 return _pxmlConv->GetWriter(); 00178 } 00179 00180 void OutputToStream() 00181 { 00182 _pxmlConv->OutputToStream(); 00183 } 00184 00187 virtual int SkipObjects(int n, OBConversion* pConv) 00188 { 00189 //don't implement on base class 00190 if(*EndTag()=='>') 00191 return 0; 00192 00193 //Set up XMLConversion class with reader 00194 _pxmlConv = XMLConversion::GetDerived(pConv,true); 00195 if(!_pxmlConv) 00196 return -1; 00197 00198 //always find the end of at least 1 object 00199 if(n==0)++n; 00200 00201 //Skip n objects, returning -1 if not successful 00202 int i; 00203 for(i=0; i<n; ++i) 00204 if(_pxmlConv->SkipXML(EndTag())!=1) 00205 return -1; 00206 00207 return 1; 00208 } 00209 00210 }; 00211 00212 //************************************************* 00215 class XMLMoleculeFormat : public XMLBaseFormat 00216 { 00217 protected: 00218 OBMol* _pmol; 00219 00220 public: 00221 ~XMLMoleculeFormat(){} 00222 virtual bool ReadChemObject(OBConversion* pConv) 00223 { 00224 return OBMoleculeFormat::ReadChemObjectImpl(pConv, this); 00225 }; 00226 00227 virtual bool WriteChemObject(OBConversion* pConv) 00228 { 00229 return OBMoleculeFormat::WriteChemObjectImpl(pConv, this); 00230 }; 00231 00232 virtual bool ReadMolecule(OBBase* pOb, OBConversion* pConv) 00233 { 00234 _pmol = dynamic_cast<OBMol*>(pOb); 00235 if(!_pmol) 00236 return false; 00237 _pxmlConv = XMLConversion::GetDerived(pConv,true); 00238 if(!_pxmlConv) 00239 return false; 00240 _embedlevel = -1; 00241 return _pxmlConv->ReadXML(this,pOb); 00242 }; 00243 00244 const std::type_info& GetType() 00245 { 00246 return typeid(OBMol*); 00247 }; 00248 00249 }; 00250 00251 00252 }//namespace 00253 00257 00258 #endif
This file is part of the documentation for Open Babel, version 2.3.