00001 /********************************************************************** 00002 lineend.h - Stream buffer for filtering line endings, converting \r or \r\n -> \n 00003 00004 Copyright (C) 1998 by James Kanze 00005 Copyright (C) 2007 by Chris Morley 00006 00007 This file is part of the Open Babel project. 00008 For more information, see <http://openbabel.org/> 00009 00010 This program is free software; you can redistribute it and/or modify 00011 it under the terms of the GNU General Public License as published by 00012 the Free Software Foundation version 2 of the License. 00013 00014 This program is distributed in the hope that it will be useful, but 00015 WITHOUT ANY WARRANTY; without even the implied warranty of 00016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00017 General Public License for more details. 00018 ***********************************************************************/ 00019 00020 #ifndef OB_LINEEND_H 00021 #define OB_LINEEND_H 00022 00023 #include <streambuf> 00024 #include <climits> 00025 00026 #ifndef OBCONV 00027 #define OBCONV 00028 #endif 00029 00030 namespace OpenBabel 00031 { 00032 00058 template< class Extractor > 00059 class FilteringInputStreambuf : public std::streambuf 00060 { 00061 public: 00062 FilteringInputStreambuf( 00063 std::streambuf* source = NULL , 00064 bool deleteWhenFinished = false 00065 ) ; 00066 virtual ~FilteringInputStreambuf() 00067 { 00068 //sync(); comment out so can be deleted in OBConversion destructor 00069 }; 00070 virtual int overflow( int ) {return EOF;}; 00071 virtual int underflow() ; 00072 virtual int sync() ; 00073 00074 //Pass the random acess functions to the source rdbuf and synchronize 00075 virtual std::streampos seekoff(std::streamoff off, std::ios_base::seekdir way, 00076 std::ios_base::openmode which = std::ios_base::in | std::ios_base::out ) 00077 { 00078 std::streampos ret = mySource->pubseekoff(off, way, which); 00079 // sync(); 00080 return ret; 00081 }; 00082 00083 virtual std::streampos seekpos(std::streampos sp, 00084 std::ios_base::openmode which = std::ios_base::in | std::ios_base::out ) 00085 { 00086 std::streampos ret = mySource->pubseekpos(sp, which); 00087 // sync(); 00088 return ret; 00089 }; 00090 00092 std::streambuf* GetSource()const 00093 { 00094 return mySource; 00095 }; 00096 00098 void SetSource(std::streambuf* newsource) 00099 { 00100 mySource = newsource; 00101 setg( &myBuffer , &myBuffer , &myBuffer + 1 ) ; 00102 } 00103 00104 // Extractor& extractor() {return myExtractor;}; 00105 00106 private: 00107 std::streambuf* mySource ; 00108 Extractor myExtractor ; 00109 char myBuffer ; 00110 bool myDeleteWhenFinished ; 00111 } ; 00112 00113 //******************************************************* 00114 template< class Extractor > 00115 FilteringInputStreambuf< Extractor >::FilteringInputStreambuf( 00116 std::streambuf* source , 00117 bool deleteWhenFinished) 00118 : mySource(source), myDeleteWhenFinished(deleteWhenFinished) 00119 { 00120 setg( &myBuffer , &myBuffer , &myBuffer ) ; 00121 } 00122 00124 template< class Extractor > 00125 int 00126 FilteringInputStreambuf< Extractor >::underflow() 00127 { 00128 int result( EOF ) ; 00129 if( gptr() < egptr() ) 00130 result = *gptr() ; 00131 else if ( mySource != NULL ) 00132 { 00133 result = myExtractor( *mySource ) ; 00134 if ( result != EOF ) 00135 { 00136 if( result < 0 || result > UCHAR_MAX ) 00137 std::cerr << "FilteringInputStreambuf error" << std::endl; 00138 myBuffer = result ; 00139 setg( &myBuffer , &myBuffer , &myBuffer + 1 ) ; 00140 } 00141 } 00142 return result ; 00143 } 00144 00146 template< class Extractor > 00147 int 00148 FilteringInputStreambuf< Extractor >::sync() 00149 { 00150 int result( 0 ) ; 00151 if ( mySource != NULL ) 00152 { 00153 if ( gptr() < egptr() ) 00154 { 00155 result = mySource->sputbackc( *gptr() ) ; 00156 setg( NULL , NULL , NULL ) ; 00157 } 00158 if ( mySource->pubsync() == EOF ) 00159 result = EOF ; 00160 } 00161 return result ; 00162 } 00163 00164 //********************************************* 00167 class OBCONV LineEndingExtractor 00168 { 00169 public: 00170 int operator()( std::streambuf& src ) 00171 { 00172 int ch( src.sbumpc() ) ; 00173 switch (ch) 00174 { 00175 case 13: //CR or CRLF 00176 if(src.sgetc() == 10) 00177 src.sbumpc(); //CRLF 00178 //fall through 00179 case 10: //LF 00180 return '\n'; 00181 break; 00182 default: 00183 return ch; 00184 } 00185 } 00186 void finalize( std::streambuf& ) {} 00187 }; 00188 00189 } //namespace 00190 00191 #endif //OB_LINEEND_H 00192 00193
This file is part of the documentation for Open Babel, version 2.3.