00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
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
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()
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
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
00134 bool _LookingForNamespace;
00135 public:
00136 bool _SkipNextRead;
00137 };
00138
00139
00142 class XMLBaseFormat : public OBFormat
00143 {
00144 protected:
00145 XMLConversion* _pxmlConv;
00146
00147
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
00182 if(*EndTag()=='>')
00183 return 0;
00184
00185
00186 _pxmlConv = XMLConversion::GetDerived(pConv,true);
00187 if(!_pxmlConv)
00188 return -1;
00189
00190
00191 if(n==0)++n;
00192
00193
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 }
00246