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 #include <openbabel/mol.h> 00017 #include <openbabel/obconversion.h> 00018 #include <openbabel/obmolecformat.h> 00019 00020 #include <libxml/xmlreader.h> 00021 #include <libxml/xmlwriter.h> 00022 #include <typeinfo> 00023 00024 namespace OpenBabel 00025 { 00026 00027 00028 //forward declaration 00029 class XMLBaseFormat; 00030 00031 //****************************************************** 00048 class XMLConversion : public OBConversion 00049 { 00050 public: 00052 XMLConversion(OBConversion* pConv); 00053 00055 ~XMLConversion(); 00056 00057 bool SetupReader(); 00058 bool SetupWriter(); 00059 00061 bool ReadXML(XMLBaseFormat* pFormat, OBBase* pOb); 00062 00065 int SkipXML(const char* ctag); 00066 00067 typedef std::map<std::string, XMLBaseFormat*> NsMapType; 00068 00071 static NsMapType& Namespaces() 00072 { 00073 static NsMapType* nsm = NULL; 00074 if (!nsm) 00075 nsm = new NsMapType; 00076 return *nsm; 00077 }; 00078 00079 static void RegisterXMLFormat(XMLBaseFormat* pFormat, 00080 bool IsDefault=false, const char* uri=NULL); 00081 00083 static XMLConversion* GetDerived(OBConversion* pConv, bool ForReading=true); 00084 00087 bool IsLast() 00088 { return _pConv->IsLast(); } 00089 int GetOutputIndex() 00090 { return _pConv->GetOutputIndex(); } 00091 00092 00093 xmlTextReaderPtr GetReader() const 00094 { return _reader; }; 00095 00096 xmlTextWriterPtr GetWriter() const 00097 { return _writer; }; 00098 00099 void OutputToStream() 00100 { 00101 xmlOutputBufferFlush(_buf); 00102 } 00103 00104 static XMLBaseFormat* GetDefaultXMLClass() //TODO make dependent on object type 00105 { return _pDefault;}; 00106 00107 void LookForNamespace() 00108 { _LookingForNamespace = true; }; 00109 00111 static int ReadStream(void * context, char * buffer, int len); 00112 static int WriteStream(void * context, const char * buffer, int len); 00113 //static int CloseStream(void* context); 00114 00115 std::string GetAttribute(const char* attrname); 00116 00118 std::string GetContent(); 00119 00121 bool GetContentInt(int& value); 00122 00124 bool GetContentDouble(double& value); 00125 00126 private: 00127 static XMLBaseFormat* _pDefault; 00128 OBConversion* _pConv; 00129 std::streampos _requestedpos, _lastpos; 00130 xmlTextReaderPtr _reader; 00131 xmlTextWriterPtr _writer; 00132 xmlOutputBufferPtr _buf; 00133 // xmlBufferPtr _buf; 00134 bool _LookingForNamespace; 00135 public: 00136 bool _SkipNextRead; 00137 }; 00138 00139 //************************************************* 00142 class XMLBaseFormat : public OBFormat 00143 { 00144 protected: 00145 XMLConversion* _pxmlConv; 00146 00147 //formating for output 00148 std::string _prefix; 00149 int baseindent, ind; 00150 std::string nsdecl; 00151 int _embedlevel; 00152 00153 public: 00154 ~XMLBaseFormat(){} 00155 virtual const char* NamespaceURI()const=0; 00156 virtual bool DoElement(const std::string& ElName){return false;}; 00157 virtual bool EndElement(const std::string& ElName){return false;}; 00159 virtual const char* EndTag(){return ">";}; 00160 00161 protected: 00162 xmlTextReaderPtr reader() const 00163 { 00164 return _pxmlConv->GetReader(); 00165 } 00166 00167 xmlTextWriterPtr writer() const 00168 { 00169 return _pxmlConv->GetWriter(); 00170 } 00171 00172 void OutputToStream() 00173 { 00174 _pxmlConv->OutputToStream(); 00175 } 00176 00179 virtual int SkipObjects(int n, OBConversion* pConv) 00180 { 00181 //don't implement on base class 00182 if(*EndTag()=='>') 00183 return 0; 00184 00185 //Set up XMLConversion class with reader 00186 _pxmlConv = XMLConversion::GetDerived(pConv,true); 00187 if(!_pxmlConv) 00188 return -1; 00189 00190 //always find the end of at least 1 object 00191 if(n==0)++n; 00192 00193 //Skip n objects, returning -1 if not successful 00194 int i; 00195 for(i=0; i<n; ++i) 00196 if(_pxmlConv->SkipXML(EndTag())!=1) 00197 return -1; 00198 00199 return 1; 00200 } 00201 00202 }; 00203 00204 //************************************************* 00207 class XMLMoleculeFormat : public XMLBaseFormat 00208 { 00209 protected: 00210 OBMol* _pmol; 00211 00212 public: 00213 ~XMLMoleculeFormat(){} 00214 virtual bool ReadChemObject(OBConversion* pConv) 00215 { 00216 return OBMoleculeFormat::ReadChemObjectImpl(pConv, this); 00217 }; 00218 00219 virtual bool WriteChemObject(OBConversion* pConv) 00220 { 00221 return OBMoleculeFormat::WriteChemObjectImpl(pConv, this); 00222 }; 00223 00224 virtual bool ReadMolecule(OBBase* pOb, OBConversion* pConv) 00225 { 00226 _pmol = dynamic_cast<OBMol*>(pOb); 00227 if(!_pmol) 00228 return false; 00229 00230 _pxmlConv = XMLConversion::GetDerived(pConv,true); 00231 if(!_pxmlConv) 00232 return false; 00233 _embedlevel = -1; 00234 return _pxmlConv->ReadXML(this,pOb); 00235 }; 00236 00237 const std::type_info& GetType() 00238 { 00239 return typeid(OBMol*); 00240 }; 00241 00242 }; 00243 00244 00245 }//namespace 00246
This file is part of the documentation for Open Babel, version 2.2.0.