00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef OB_LINEEND_H
00021 #define OB_LINEEND_H
00022
00023 #include <streambuf>
00024
00025 #ifndef OBCONV
00026 #define OBCONV
00027 #endif
00028
00029 namespace OpenBabel
00030 {
00031
00057 template< class Extractor >
00058 class FilteringInputStreambuf : public std::streambuf
00059 {
00060 public:
00061 FilteringInputStreambuf(
00062 std::streambuf* source = NULL ,
00063 bool deleteWhenFinished = false
00064 ) ;
00065 virtual ~FilteringInputStreambuf()
00066 {
00067 sync();
00068 };
00069 virtual int overflow( int ) {return EOF;};
00070 virtual int underflow() ;
00071 virtual int sync() ;
00072
00073
00074 virtual std::streampos seekoff(std::streamoff off, std::ios_base::seekdir way,
00075 std::ios_base::openmode which = std::ios_base::in | std::ios_base::out )
00076 {
00077 std::streampos ret = mySource->pubseekoff(off, way, which);
00078
00079 return ret;
00080 };
00081
00082 virtual std::streampos seekpos(std::streampos sp,
00083 std::ios_base::openmode which = std::ios_base::in | std::ios_base::out )
00084 {
00085 std::streampos ret = mySource->pubseekpos(sp, which);
00086
00087 return ret;
00088 };
00089
00091 std::streambuf* GetSource()const
00092 {
00093 return mySource;
00094 };
00095
00097 void SetSource(std::streambuf* newsource)
00098 {
00099 mySource = newsource;
00100 setg( &myBuffer , &myBuffer , &myBuffer + 1 ) ;
00101 }
00102
00103
00104
00105 private:
00106 std::streambuf* mySource ;
00107 Extractor myExtractor ;
00108 char myBuffer ;
00109 bool myDeleteWhenFinished ;
00110 } ;
00111
00112
00113 template< class Extractor >
00114 FilteringInputStreambuf< Extractor >::FilteringInputStreambuf(
00115 std::streambuf* source ,
00116 bool deleteWhenFinished)
00117 : mySource(source), myDeleteWhenFinished(deleteWhenFinished)
00118 {
00119 setg( &myBuffer , &myBuffer , &myBuffer ) ;
00120 }
00121
00123 template< class Extractor >
00124 int
00125 FilteringInputStreambuf< Extractor >::underflow()
00126 {
00127 int result( EOF ) ;
00128 if( gptr() < egptr() )
00129 result = *gptr() ;
00130 else if ( mySource != NULL )
00131 {
00132 result = myExtractor( *mySource ) ;
00133 if ( result != EOF )
00134 {
00135 if( result < 0 || result > UCHAR_MAX )
00136 std::cerr << "FilteringInputStreambuf error" << std::endl;
00137 myBuffer = result ;
00138 setg( &myBuffer , &myBuffer , &myBuffer + 1 ) ;
00139 }
00140 }
00141 return result ;
00142 }
00143
00145 template< class Extractor >
00146 int
00147 FilteringInputStreambuf< Extractor >::sync()
00148 {
00149 int result( 0 ) ;
00150 if ( mySource != NULL )
00151 {
00152 if ( gptr() < egptr() )
00153 {
00154 result = mySource->sputbackc( *gptr() ) ;
00155 setg( NULL , NULL , NULL ) ;
00156 }
00157 if ( mySource->pubsync() == EOF )
00158 result = EOF ;
00159 }
00160 return result ;
00161 }
00162
00163
00166 class OBCONV LineEndingExtractor
00167 {
00168 public:
00169 int operator()( std::streambuf& src )
00170 {
00171 int ch( src.sbumpc() ) ;
00172 switch (ch)
00173 {
00174 case 13:
00175 if(src.sgetc() == 10)
00176 src.sbumpc();
00177
00178 case 10:
00179 return '\n';
00180 break;
00181 default:
00182 return ch;
00183 }
00184 }
00185 void finalize( std::streambuf& ) {}
00186 };
00187
00188 }
00189
00190 #endif //OB_LINEEND_H