xml.h

Go to the documentation of this file.
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 
00023 namespace OpenBabel
00024 {
00025 
00026   // This macro is used in DLL builds. If it has not
00027   // been set in babelconfig.h, define it as nothing.
00028 #ifndef OBCOMMON
00029 #define OBCOMMON
00030 #endif
00031 
00032   //forward declaration
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() //TODO make dependent on object type
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       //static int CloseStream(void* context);
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       //        xmlBufferPtr _buf;
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       //formating for output
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           //don't implement on base class
00185           if(*EndTag()=='>')
00186             return 0;
00187 
00188           //Set up XMLConversion class with reader 
00189           _pxmlConv = XMLConversion::GetDerived(pConv,true);
00190           if(!_pxmlConv)
00191             return -1;
00192 
00193           //always find the end of at least 1 object
00194           if(n==0)++n;
00195                 
00196           //Skip n objects, returning -1 if not successful
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 }//namespace
00248