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
00023 namespace OpenBabel
00024 {
00025
00026
00027
00028 #ifndef OBCOMMON
00029 #define OBCOMMON
00030 #endif
00031
00032
00033 class XMLBaseFormat;
00034
00035
00052 class OBCOMMON XMLConversion : public OBConversion
00053 {
00054 public:
00056 XMLConversion(OBConversion* pConv);
00057
00059 ~XMLConversion();
00060
00061 bool SetupReader();
00062 bool SetupWriter();
00063
00065 bool ReadXML(XMLBaseFormat* pFormat, OBBase* pOb);
00066
00069 int SkipXML(const char* ctag);
00070
00071 typedef std::map<std::string, XMLBaseFormat*> NsMapType;
00072
00075 static NsMapType& Namespaces()
00076 {
00077 static NsMapType* nsm = NULL;
00078 if (!nsm)
00079 nsm = new NsMapType;
00080 return *nsm;
00081 };
00082
00083 static void RegisterXMLFormat(XMLBaseFormat* pFormat,
00084 bool IsDefault=false, const char* uri=NULL);
00085
00087 static XMLConversion* GetDerived(OBConversion* pConv, bool ForReading=true);
00088
00091 bool IsLast()
00092 { return _pConv->IsLast(); }
00093 int GetOutputIndex()
00094 { return _pConv->GetOutputIndex(); }
00095
00096
00097 xmlTextReaderPtr GetReader() const
00098 { return _reader; };
00099
00100 xmlTextWriterPtr GetWriter() const
00101 { return _writer; };
00102
00103 void OutputToStream()
00104 {
00105 xmlOutputBufferFlush(_buf);
00106 }
00107
00108 static XMLBaseFormat* GetDefaultXMLClass()
00109 { return _pDefault;};
00110
00111 void LookForNamespace()
00112 { _LookingForNamespace = true; };
00113
00115 static int ReadStream(void * context, char * buffer, int len);
00116 static int WriteStream(void * context, const char * buffer, int len);
00117
00118
00119 std::string GetAttribute(const char* attrname);
00120
00122 std::string GetContent();
00123
00125 bool GetContentInt(int& value);
00126
00128 bool GetContentDouble(double& value);
00129
00130 private:
00131 static XMLBaseFormat* _pDefault;
00132 OBConversion* _pConv;
00133 std::streampos _requestedpos, _lastpos;
00134 xmlTextReaderPtr _reader;
00135 xmlTextWriterPtr _writer;
00136 xmlOutputBufferPtr _buf;
00137
00138 bool _LookingForNamespace;
00139 public:
00140 bool _SkipNextRead;
00141 };
00142
00143
00146 class OBCOMMON XMLBaseFormat : public OBFormat
00147 {
00148 protected:
00149 XMLConversion* _pxmlConv;
00150
00151
00152 std::string _prefix;
00153 int baseindent, ind;
00154 std::string nsdecl;
00155 int _embedlevel;
00156
00157 public:
00158 virtual const char* NamespaceURI()const=0;
00159 virtual bool DoElement(const std::string& ElName){return false;};
00160 virtual bool EndElement(const std::string& ElName){return false;};
00162 virtual const char* EndTag(){return ">";};
00163
00164 protected:
00165 xmlTextReaderPtr reader() const
00166 {
00167 return _pxmlConv->GetReader();
00168 }
00169
00170 xmlTextWriterPtr writer() const
00171 {
00172 return _pxmlConv->GetWriter();
00173 }
00174
00175 void OutputToStream()
00176 {
00177 _pxmlConv->OutputToStream();
00178 }
00179
00182 virtual int SkipObjects(int n, OBConversion* pConv)
00183 {
00184
00185 if(*EndTag()=='>')
00186 return 0;
00187
00188
00189 _pxmlConv = XMLConversion::GetDerived(pConv,true);
00190 if(!_pxmlConv)
00191 return -1;
00192
00193
00194 if(n==0)++n;
00195
00196
00197 int i;
00198 for(i=0; i<n; ++i)
00199 if(_pxmlConv->SkipXML(EndTag())!=1)
00200 return -1;
00201
00202 return 1;
00203 }
00204
00205 };
00206
00207
00210 class OBCOMMON XMLMoleculeFormat : public XMLBaseFormat
00211 {
00212 protected:
00213 OBMol* _pmol;
00214
00215 public:
00216 virtual bool ReadChemObject(OBConversion* pConv)
00217 {
00218 return OBMoleculeFormat::ReadChemObjectImpl(pConv, this);
00219 };
00220
00221 virtual bool WriteChemObject(OBConversion* pConv)
00222 {
00223 return OBMoleculeFormat::WriteChemObjectImpl(pConv, this);
00224 };
00225
00226 virtual bool ReadMolecule(OBBase* pOb, OBConversion* pConv)
00227 {
00228 _pmol = dynamic_cast<OBMol*>(pOb);
00229 if(!_pmol)
00230 return false;
00231
00232 _pxmlConv = XMLConversion::GetDerived(pConv,true);
00233 if(!_pxmlConv)
00234 return false;
00235 _embedlevel = -1;
00236 return _pxmlConv->ReadXML(this,pOb);
00237 };
00238
00239 const std::type_info& GetType()
00240 {
00241 return typeid(OBMol*);
00242 };
00243
00244 };
00245
00246
00247 }
00248