| 1 | tim | 741 | /********************************************************************** | 
| 2 |  |  | obconversion.h - Handle file conversions. Declaration of OBFormat, OBConversion | 
| 3 |  |  |  | 
| 4 |  |  | Copyright (C) 2004-2005 by Chris Morley | 
| 5 |  |  |  | 
| 6 |  |  | This file is part of the Open Babel project. | 
| 7 |  |  | For more information, see <http://openbabel.sourceforge.net/> | 
| 8 |  |  |  | 
| 9 |  |  | This program is free software; you can redistribute it and/or modify | 
| 10 |  |  | it under the terms of the GNU General Public License as published by | 
| 11 |  |  | the Free Software Foundation version 2 of the License. | 
| 12 |  |  |  | 
| 13 |  |  | This program is distributed in the hope that it will be useful, | 
| 14 |  |  | but WITHOUT ANY WARRANTY; without even the implied warranty of | 
| 15 |  |  | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
| 16 |  |  | GNU General Public License for more details. | 
| 17 |  |  | ***********************************************************************/ | 
| 18 |  |  |  | 
| 19 |  |  | #ifndef OB_CONV_H | 
| 20 |  |  | #define OB_CONV_H | 
| 21 |  |  |  | 
| 22 | gezelter | 751 | #include "config.h" | 
| 23 | tim | 741 |  | 
| 24 |  |  | #if HAVE_IOSTREAM | 
| 25 |  |  | #include <iostream> | 
| 26 |  |  | #elif HAVE_IOSTREAM_H | 
| 27 |  |  | #include <iostream.h> | 
| 28 |  |  | #endif | 
| 29 |  |  | #if HAVE_FSTREAM | 
| 30 |  |  | #include <fstream> | 
| 31 |  |  | #elif HAVE_FSTREAM_H | 
| 32 |  |  | #include <fstream.h> | 
| 33 |  |  | #endif | 
| 34 |  |  |  | 
| 35 |  |  | #if HAVE_SSTREAM | 
| 36 |  |  | #include <sstream> | 
| 37 |  |  | #elif | 
| 38 |  |  | #include <sstream.h> | 
| 39 |  |  | #endif | 
| 40 |  |  |  | 
| 41 |  |  | #include <string> | 
| 42 |  |  | #include <vector> | 
| 43 |  |  | #include <map> | 
| 44 | gezelter | 809 | #include <typeinfo> | 
| 45 | tim | 741 |  | 
| 46 |  |  | //#include "dlhandler.h" | 
| 47 |  |  |  | 
| 48 |  |  | // These macros are used in DLL builds. If they have not | 
| 49 |  |  | // been set in babelconfig.h, define them as nothing. | 
| 50 |  |  | #ifndef OBCONV | 
| 51 |  |  | #define OBCONV | 
| 52 |  |  | #endif | 
| 53 |  |  | #ifndef OBDLL | 
| 54 |  |  | #define OBDLL | 
| 55 |  |  | #endif | 
| 56 |  |  |  | 
| 57 |  |  | //using namespace std; | 
| 58 |  |  | namespace OpenBabel { | 
| 59 |  |  |  | 
| 60 |  |  |  | 
| 61 |  |  | class OBBase; | 
| 62 |  |  | class OBConversion; | 
| 63 |  |  | //************************************************* | 
| 64 |  |  |  | 
| 65 |  |  | /// @brief Base class for file formats. | 
| 66 |  |  |  | 
| 67 |  |  | /// Two sets of Read and Write functions are specified for each format | 
| 68 |  |  | /// to handle two different requirements. | 
| 69 |  |  | /// The "Convert" interface is for use in file format conversion applications. The | 
| 70 |  |  | /// user interface, a console, a GUI, or another program is kept unaware of the | 
| 71 |  |  | /// details of the chemistry and does not need to \#include mol.h. It is then | 
| 72 |  |  | /// necessary to manipulate only pointers to OBBase in OBConversion and the user | 
| 73 |  |  | /// interface, with all the construction and deletion of OBMol etc objects being | 
| 74 |  |  | /// done in the Format classes or the OB core. The convention  with "Covert" | 
| 75 |  |  | /// interface functions is that chemical objects are made on the heap with new | 
| 76 |  |  | /// in the ReadChemicalObject() functions and and deleted in WriteChemicalObject() | 
| 77 |  |  | /// functions | 
| 78 |  |  | /// | 
| 79 |  |  | /// The "API" interface is for programatic use of the OB routines in application | 
| 80 |  |  | /// programs where mol.h is \#included. There is generally no creation or | 
| 81 |  |  | /// destruction of objects in ReadMolecule() and WriteMolecule() and no restriction | 
| 82 |  |  | /// on whether the pointers are to the heap or the stack. | 
| 83 |  |  | /// | 
| 84 |  |  | class OBCONV OBFormat | 
| 85 |  |  | { | 
| 86 |  |  | public: | 
| 87 |  |  | /// @brief The "API" interface Read function. | 
| 88 |  |  |  | 
| 89 |  |  | /// Reads a single object. | 
| 90 |  |  | /// Does not make a new object on the heap; | 
| 91 |  |  | /// can be used with a pointer to an chem object on the heap or the stack. | 
| 92 |  |  | virtual bool ReadMolecule(OBBase* pOb, OBConversion* pConv) | 
| 93 |  |  | { std::cerr << "Not a valid input format"; return false;} | 
| 94 |  |  |  | 
| 95 |  |  | /// @brief The "Convert" interface Read function. | 
| 96 |  |  |  | 
| 97 |  |  | /// Possibly reads multiple new objects on the heap and subjects them | 
| 98 |  |  | /// to its DoTransformations() function, which may delete them again. | 
| 99 |  |  | /// Sends result to pConv->AddChemObject() | 
| 100 |  |  | virtual bool ReadChemObject(OBConversion* pConv) | 
| 101 |  |  | { std::cerr << "Not a valid input format"; return false;} | 
| 102 |  |  |  | 
| 103 |  |  | /// @brief The "API" interface Write function. | 
| 104 |  |  |  | 
| 105 |  |  | /// Writes a single object | 
| 106 |  |  | /// Does not delete the object; | 
| 107 |  |  | /// can be used with a pointer to an chem object on the heap or the stack. | 
| 108 |  |  | /// Returns false on error. | 
| 109 |  |  | virtual bool WriteMolecule(OBBase* pOb, OBConversion* pConv) | 
| 110 |  |  | { std::cerr << "Not a valid output format"; return false;} | 
| 111 |  |  |  | 
| 112 |  |  | /// @brief The "Convert" interface Write function. | 
| 113 |  |  |  | 
| 114 |  |  | /// Writes a single object | 
| 115 |  |  | /// Deletes the object after writing | 
| 116 |  |  | /// Returns false on error | 
| 117 |  |  | virtual bool WriteChemObject(OBConversion* pConv) | 
| 118 |  |  | { std::cerr << "Not a valid output format"; return false;} | 
| 119 |  |  |  | 
| 120 |  |  | /// @brief Information on this format. Printed out in response to -Hxxx option where xxx id the id of the format. | 
| 121 |  |  |  | 
| 122 |  |  | /// Must be provided by each format class. | 
| 123 |  |  | /// Can include a list of command line Options. These may be used to construction | 
| 124 |  |  | /// check boxes, radio buttons etc for GUI interface. | 
| 125 |  |  | virtual const char* Description()=0; | 
| 126 |  |  |  | 
| 127 |  |  | /// @brief A decription of the chemical object converted by this format. | 
| 128 |  |  |  | 
| 129 |  |  | /// If not provided, the object type used by the default format is used (usually OBMol). | 
| 130 |  |  | virtual const char* TargetClassDescription(); | 
| 131 |  |  |  | 
| 132 |  |  | /// @brief Returns the type of chemical object used by the format. | 
| 133 |  |  |  | 
| 134 |  |  | /// Defaults to that used by the default format. Useful for checking | 
| 135 |  |  | /// that a format can handle a particular object. | 
| 136 |  |  | virtual const std::type_info& GetType(); | 
| 137 |  |  |  | 
| 138 |  |  | /// @brief Web address where the format is defined. | 
| 139 |  |  | virtual const char* SpecificationURL() { return ""; } | 
| 140 |  |  |  | 
| 141 |  |  | /// @brief Chemical MIME type associated with this file type (if any) | 
| 142 |  |  | virtual const char* GetMIMEType() { return ""; } | 
| 143 |  |  |  | 
| 144 |  |  | /// @brief Decribes the capabilities of the format (Read only etc.) | 
| 145 |  |  |  | 
| 146 |  |  | /// Currently, can be a bitwise OR of any of the following | 
| 147 |  |  | /// NOTREADABLE READONEONLY NOTWRITABLE WRITEONEONLY DEFAULTFORMAT | 
| 148 |  |  | /// READBINARY WRITEBINARY | 
| 149 |  |  | virtual unsigned int Flags() { return 0;}; | 
| 150 |  |  |  | 
| 151 |  |  | /// @brief Skip past first n objects in input stream (or current one with n=0) | 
| 152 |  |  |  | 
| 153 |  |  | /// Returns 1 on success, -1 on error and 0 if not implemented | 
| 154 |  |  | virtual int SkipObjects(int n, OBConversion* pConv) | 
| 155 |  |  | { | 
| 156 |  |  | return 0; //shows not implemented in the format class | 
| 157 |  |  | }; | 
| 158 |  |  |  | 
| 159 |  |  | /// @brief Returns a pointer to a new instance of the format, or NULL if fails. | 
| 160 |  |  |  | 
| 161 |  |  | /// Normally a single global instance is used but this may cause problems | 
| 162 |  |  | /// if there are member variables and the format is used in more than one place | 
| 163 |  |  | /// in the program. | 
| 164 |  |  | virtual OBFormat* MakeNewInstance() | 
| 165 |  |  | { | 
| 166 |  |  | return NULL; //shows not implemented in the format class | 
| 167 |  |  | } | 
| 168 |  |  |  | 
| 169 |  |  | /// @brief Format classes do not have a destructor | 
| 170 |  |  | virtual ~OBFormat(){}; | 
| 171 |  |  | }; | 
| 172 |  |  |  | 
| 173 |  |  | //************************************************* | 
| 174 |  |  | /// @brief Case insensitive string comparison for FormatsMap key. | 
| 175 |  |  | struct CharPtrLess : public std::binary_function<const char*,const char*, bool> | 
| 176 |  |  | { | 
| 177 |  |  | bool operator()(const char* p1,const char* p2) const | 
| 178 |  |  | { return strcasecmp(p1,p2)<0; } | 
| 179 |  |  | }; | 
| 180 |  |  |  | 
| 181 |  |  | typedef std::map<const char*,OBFormat*,CharPtrLess > FMapType; | 
| 182 |  |  | typedef FMapType::iterator Formatpos; | 
| 183 |  |  |  | 
| 184 |  |  | //************************************************* | 
| 185 |  |  |  | 
| 186 |  |  | /// Class to convert from one format to another. | 
| 187 |  |  | class OBCONV OBConversion | 
| 188 |  |  | { | 
| 189 |  |  | /// @nosubgrouping | 
| 190 |  |  | public: | 
| 191 |  |  | /// @name Construction | 
| 192 |  |  | //@{ | 
| 193 |  |  | OBConversion(std::istream* is=NULL, std::ostream* os=NULL); | 
| 194 |  |  | /// @brief Copy constructor | 
| 195 |  |  | OBConversion(const OBConversion& o); | 
| 196 |  |  | virtual     ~OBConversion(); | 
| 197 |  |  | //@} | 
| 198 |  |  | /// @name Collection of formats | 
| 199 |  |  | //@{ | 
| 200 |  |  | /// @brief Called once by each format class | 
| 201 |  |  | static int                              RegisterFormat(const char* ID, OBFormat* pFormat, const char* MIME = NULL); | 
| 202 |  |  | /// @brief Searches registered formats | 
| 203 |  |  | static OBFormat*        FindFormat(const char* ID); | 
| 204 |  |  | /// @brief Searches registered formats for an ID the same as the file extension | 
| 205 |  |  | static OBFormat*        FormatFromExt(const char* filename); | 
| 206 |  |  | /// @brief Searches registered formats for a MIME the same as the chemical MIME type passed | 
| 207 |  |  | static OBFormat*        FormatFromMIME(const char* MIME); | 
| 208 |  |  |  | 
| 209 |  |  | ///Repeatedly called to recover available Formats | 
| 210 |  |  | static bool             GetNextFormat(Formatpos& itr, const char*& str,OBFormat*& pFormat); | 
| 211 |  |  | //@} | 
| 212 |  |  |  | 
| 213 |  |  | /// @name Information | 
| 214 |  |  | //@{ | 
| 215 |  |  | static const char* Description(); //generic conversion options | 
| 216 |  |  | //@} | 
| 217 |  |  |  | 
| 218 |  |  | /// @name Parameter get and set | 
| 219 |  |  | //@{ | 
| 220 |  |  | std::istream* GetInStream() const {return pInStream;}; | 
| 221 |  |  | std::ostream* GetOutStream() const {return pOutStream;}; | 
| 222 |  |  | void          SetInStream(std::istream* pIn){pInStream=pIn;}; | 
| 223 |  |  | void          SetOutStream(std::ostream* pOut){pOutStream=pOut;}; | 
| 224 |  |  | bool          SetInAndOutFormats(const char* inID, const char* outID);///< Sets the formats from their ids, e g CML | 
| 225 |  |  | bool          SetInAndOutFormats(OBFormat* pIn, OBFormat* pOut); | 
| 226 |  |  | bool          SetInFormat(const char* inID); | 
| 227 |  |  | bool          SetInFormat(OBFormat* pIn); | 
| 228 |  |  | bool          SetOutFormat(const char* outID); | 
| 229 |  |  | bool          SetOutFormat(OBFormat* pOut); | 
| 230 |  |  |  | 
| 231 |  |  | OBFormat*   GetInFormat() const{return pInFormat;}; | 
| 232 |  |  | OBFormat*   GetOutFormat() const{return pOutFormat;}; | 
| 233 |  |  | std::string GetInFilename() const{return InFilename;}; | 
| 234 |  |  |  | 
| 235 |  |  | ///Get the position in the input stream of the object being read | 
| 236 |  |  | std::streampos GetInPos()const{return wInpos;}; | 
| 237 |  |  |  | 
| 238 |  |  | ///Get the length in the input stream of the object being read | 
| 239 |  |  | size_t GetInLen()const{return wInlen;}; | 
| 240 |  |  |  | 
| 241 |  |  | ///@brief Returns a default title which is the filename | 
| 242 |  |  | const char* GetTitle() const; | 
| 243 |  |  |  | 
| 244 |  |  | ///@brief Extension method: deleted in ~OBConversion() | 
| 245 |  |  | OBConversion* GetAuxConv() const {return pAuxConv;}; | 
| 246 |  |  | void          SetAuxConv(OBConversion* pConv) {pAuxConv=pConv;}; | 
| 247 |  |  | //@} | 
| 248 |  |  | /// @name Option handling | 
| 249 |  |  | //@{ | 
| 250 |  |  | ///@brief Three types of options set on the the command line by -a? , -x? , or -? | 
| 251 |  |  | enum Option_type { INOPTIONS, OUTOPTIONS, GENOPTIONS }; | 
| 252 |  |  |  | 
| 253 |  |  | ///@brief Determine whether an option is set. Returns NULL if option not and a pointer to the associated text if it is | 
| 254 |  |  | const char* IsOption(const char* opt,Option_type opttyp=OUTOPTIONS); | 
| 255 |  |  |  | 
| 256 |  |  | ///@brief Access the map with option name as key and any associated text as value | 
| 257 |  |  | const std::map<std::string,std::string>* GetOptions(Option_type opttyp) | 
| 258 |  |  | { return &OptionsArray[opttyp];}; | 
| 259 |  |  |  | 
| 260 |  |  | ///@brief Set an option of specified type, with optional text | 
| 261 |  |  | void AddOption(const char* opt, Option_type opttyp, const char* txt=NULL); | 
| 262 |  |  |  | 
| 263 |  |  | bool RemoveOption(const char* opt, Option_type optype); | 
| 264 |  |  |  | 
| 265 |  |  | ///@brief Set several single character options of specified type from string like ab"btext"c"ctext" | 
| 266 |  |  | void SetOptions(const char* options, Option_type opttyp); | 
| 267 |  |  |  | 
| 268 |  |  | ///@brief For example -h takes 0 parameters; -f takes 1. Call in a format constructor. | 
| 269 |  |  | static void RegisterOptionParam(std::string name, OBFormat* pFormat, | 
| 270 |  |  | int numberParams=0, Option_type typ=OUTOPTIONS); | 
| 271 |  |  |  | 
| 272 |  |  | ///@brief Returns the number of parameters registered for the option, or 0 if not found | 
| 273 |  |  | static int GetOptionParams(std::string name, Option_type typ); | 
| 274 |  |  | //@} | 
| 275 |  |  |  | 
| 276 |  |  | /// @name Conversion | 
| 277 |  |  | //@{ | 
| 278 |  |  | /// @brief Conversion for single input and output stream | 
| 279 |  |  | int         Convert(std::istream* is, std::ostream* os); | 
| 280 |  |  |  | 
| 281 |  |  | /// @brief Conversion with existing streams | 
| 282 |  |  | int         Convert(); | 
| 283 |  |  |  | 
| 284 |  |  | /// @brief Conversion with multiple input/output files: | 
| 285 |  |  | /// makes input and output streams, and carries out normal, batch, aggregation, and splitting conversion. | 
| 286 |  |  | int                                     FullConvert(std::vector<std::string>& FileList, | 
| 287 |  |  | std::string& OutputFileName, std::vector<std::string>& OutputFileList); | 
| 288 |  |  | //@} | 
| 289 |  |  |  | 
| 290 |  |  | /// @name Conversion loop control | 
| 291 |  |  | //@{ | 
| 292 |  |  | int                                     AddChemObject(OBBase* pOb);///< @brief Adds to internal array during input | 
| 293 |  |  | OBBase*                 GetChemObject(); ///< @brief Retrieve from internal array during output | 
| 294 |  |  | bool                            IsLast();///< @brief True if no more objects to be output | 
| 295 |  |  | bool                            IsFirstInput();///< @brief True if the first input object is being processed | 
| 296 |  |  | int         GetOutputIndex() const ;///< @brief Retrieves number of ChemObjects that have been actually output | 
| 297 |  |  | void                            SetOutputIndex(int indx);///< @brief Sets ouput index (maybe to control whether seen as first object) | 
| 298 |  |  | void                            SetMoreFilesToCome();///<@brief Used with multiple input files. Off by default. | 
| 299 |  |  | void                            SetOneObjectOnly();///<@brief Used with multiple input files. Off by default. | 
| 300 |  |  | //@} | 
| 301 |  |  | /// @name Convenience functions | 
| 302 |  |  | //@{ | 
| 303 |  |  | ///The default format is set in a single OBFormat class (generally it is OBMol) | 
| 304 |  |  | static OBFormat* GetDefaultFormat(){return pDefaultFormat;}; | 
| 305 |  |  |  | 
| 306 |  |  | /// @brief Outputs an object of a class derived from OBBase. | 
| 307 |  |  |  | 
| 308 |  |  | /// Part of "API" interface. | 
| 309 |  |  | /// The output stream can be specified and the change is retained in the OBConversion instance | 
| 310 |  |  | bool                            Write(OBBase* pOb, std::ostream* pout=NULL); | 
| 311 |  |  |  | 
| 312 |  |  | /// @brief Outputs an object of a class derived from OBBase as a string | 
| 313 |  |  |  | 
| 314 |  |  | /// Part of "API" interface. | 
| 315 |  |  | /// The output stream is temporarily changed to the string and then restored | 
| 316 |  |  | /// This method is primarily intended for scripting languages without "stream" classes | 
| 317 |  |  | std::string                     WriteString(OBBase* pOb); | 
| 318 |  |  |  | 
| 319 |  |  | /// @brief Outputs an object of a class derived from OBBase as a file (with the supplied path) | 
| 320 |  |  |  | 
| 321 |  |  | /// Part of "API" interface. | 
| 322 |  |  | /// The output stream is changed to the supplied file and the change is retained in the | 
| 323 |  |  | /// OBConversion instance. | 
| 324 |  |  | /// This method is primarily intended for scripting languages without "stream" classes | 
| 325 |  |  | bool                            WriteFile(OBBase* pOb, std::string filePath); | 
| 326 |  |  |  | 
| 327 |  |  | /// @brief Reads an object of a class derived from OBBase into pOb. | 
| 328 |  |  |  | 
| 329 |  |  | /// Part of "API" interface. | 
| 330 |  |  | /// The input stream can be specified and the change is retained in the OBConversion instance | 
| 331 |  |  | /// Returns false and pOb=NULL on error | 
| 332 |  |  | bool    Read(OBBase* pOb, std::istream* pin=NULL); | 
| 333 |  |  |  | 
| 334 |  |  | /// @brief Reads an object of a class derived from OBBase into pOb from the supplied string | 
| 335 |  |  |  | 
| 336 |  |  | /// Part of "API" interface. | 
| 337 |  |  | /// Returns false and pOb=NULL on error | 
| 338 |  |  | /// This method is primarily intended for scripting languages without "stream" classes | 
| 339 |  |  | bool  ReadString(OBBase* pOb, std::string input); | 
| 340 |  |  |  | 
| 341 |  |  | /// @brief Reads an object of a class derived from OBBase into pOb from the file specified | 
| 342 |  |  |  | 
| 343 |  |  | /// Part of "API" interface. | 
| 344 |  |  | /// The output stream is changed to the supplied file and the change is retained in the | 
| 345 |  |  | /// OBConversion instance. | 
| 346 |  |  | /// Returns false and pOb=NULL on error | 
| 347 |  |  | /// This method is primarily intended for scripting languages without "stream" classes | 
| 348 |  |  | bool  ReadFile(OBBase* pOb, std::string filePath); | 
| 349 |  |  |  | 
| 350 |  |  |  | 
| 351 |  |  | ///Replaces * in BaseName by InFile without extension and path | 
| 352 |  |  | static std::string BatchFileName(std::string& BaseName, std::string& InFile); | 
| 353 |  |  | ///Replaces * in BaseName by Count | 
| 354 |  |  | static std::string IncrementedFileName(std::string& BaseName, const int Count); | 
| 355 |  |  | //@} | 
| 356 |  |  |  | 
| 357 |  |  | protected: | 
| 358 |  |  | bool             SetStartAndEnd(); | 
| 359 |  |  | static FMapType& FormatsMap();///<contains ID and pointer to all OBFormat classes | 
| 360 |  |  | static FMapType& FormatsMIMEMap();///<contains MIME and pointer to all OBFormat classes | 
| 361 |  |  | typedef std::map<std::string,int> OPAMapType; | 
| 362 |  |  | static OPAMapType& OptionParamArray(Option_type typ); | 
| 363 |  |  | static int       LoadFormatFiles(); | 
| 364 |  |  | bool             OpenAndSetFormat(bool SetFormat, std::ifstream* is); | 
| 365 |  |  |  | 
| 366 |  |  | std::string       InFilename; | 
| 367 |  |  | std::istream*     pInStream; | 
| 368 |  |  | std::ostream*     pOutStream; | 
| 369 |  |  | static OBFormat*  pDefaultFormat; | 
| 370 |  |  | OBFormat*         pInFormat; | 
| 371 |  |  | OBFormat*         pOutFormat; | 
| 372 |  |  |  | 
| 373 |  |  | std::map<std::string,std::string> OptionsArray[3]; | 
| 374 |  |  |  | 
| 375 |  |  | int               Index; | 
| 376 |  |  | unsigned int      StartNumber; | 
| 377 |  |  | unsigned int      EndNumber; | 
| 378 |  |  | int               Count; | 
| 379 |  |  | bool              m_IsLast; | 
| 380 |  |  | bool              MoreFilesToCome; | 
| 381 |  |  | bool              OneObjectOnly; | 
| 382 |  |  | bool              ReadyToInput; | 
| 383 |  |  | static int FormatFilesLoaded; | 
| 384 |  |  | OBBase*           pOb1; | 
| 385 |  |  | std::streampos wInpos; ///<position in the input stream of the object being written | 
| 386 |  |  | std::streampos rInpos; ///<position in the input stream of the object being read | 
| 387 |  |  | size_t wInlen; ///<length in the input stream of the object being written | 
| 388 |  |  | size_t rInlen; ///<length in the input stream of the object being read | 
| 389 |  |  |  | 
| 390 |  |  | OBConversion* pAuxConv;///<Way to extend OBConversion | 
| 391 |  |  | }; | 
| 392 |  |  |  | 
| 393 |  |  | ///For OBFormat::Flags() | 
| 394 |  |  | #define NOTREADABLE     0x01 | 
| 395 |  |  | #define READONEONLY     0x02 | 
| 396 |  |  | #define READBINARY      0x04 | 
| 397 |  |  | #define NOTWRITABLE     0x10 | 
| 398 |  |  | #define WRITEONEONLY    0x20 | 
| 399 |  |  | #define WRITEBINARY     0x40 | 
| 400 |  |  | #define DEFAULTFORMAT 0x4000 | 
| 401 |  |  |  | 
| 402 |  |  | } //namespace OpenBabel | 
| 403 |  |  | #endif //OB_CONV_H | 
| 404 |  |  |  | 
| 405 |  |  | //! \file | 
| 406 |  |  | //! \brief Handle file conversions. Declaration of OBFormat, OBConversion. | 
| 407 |  |  |  | 
| 408 |  |  |  |