Open Babel  3.0
lineend.h
Go to the documentation of this file.
1 /**********************************************************************
2 lineend.h - Stream buffer for filtering line endings, converting \r or \r\n -> \n
3 
4  Copyright (C) 1998 by James Kanze
5  Copyright (C) 2007 by Chris Morley
6 
7 This file is part of the Open Babel project.
8 For more information, see <http://openbabel.org/>
9 
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation version 2 of the License.
13 
14 This program is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 General Public License for more details.
18 ***********************************************************************/
19 
20 #ifndef OB_LINEEND_H
21 #define OB_LINEEND_H
22 
23 #include <streambuf>
24 #include <climits>
25 
26 #ifndef OBCONV
27 #define OBCONV
28 #endif
29 
30 namespace OpenBabel
31 {
32 
58  template< class Extractor >
59  class FilteringInputStreambuf : public std::streambuf
60  {
61  public:
63  std::istream* source = NULL) ;
65  {
66  //sync(); comment out so can be deleted in OBConversion destructor
67  };
68  virtual int overflow( int ) {return EOF;};
69  virtual int underflow() ;
70  virtual int sync() ;
71 
72  //Pass the random acess functions to the source rdbuf and synchronize
73  virtual std::streampos seekoff(std::streamoff off, std::ios_base::seekdir way,
74  std::ios_base::openmode which = std::ios_base::in | std::ios_base::out )
75  {
76  setg( &myBuffer , &myBuffer , &myBuffer ) ; //ensure next character is from new position
77  mySource->seekg(off, way);
78  std::streampos ret = mySource->tellg();
79 // sync();
80  return ret;
81  };
82 
83  virtual std::streampos seekpos(std::streampos sp,
84  std::ios_base::openmode which = std::ios_base::in | std::ios_base::out )
85  {
86  setg( &myBuffer , &myBuffer , &myBuffer ) ;
87  //slight hack - if mySource has read past the end, won't let us seek
88  //and there's no good way to propagate a clear to the original stream
89  mySource->clear();
90  mySource->seekg(sp);
91  std::streampos ret = mySource->tellg();
92 // sync();
93  return ret;
94  };
95 
97  std::istream* GetSource()const
98  {
99  return mySource;
100  };
101 
103  void SetSource(std::istream* newsource)
104  {
105  mySource = newsource;
106  setg( &myBuffer , &myBuffer , &myBuffer + 1 ) ;
107  }
108 
109 // Extractor& extractor() {return myExtractor;};
110 
111  private:
112  std::istream* mySource ;
113  Extractor myExtractor ;
114  char myBuffer ;
115  } ;
116 
117 //*******************************************************
118  template< class Extractor >
120  std::istream* source )
121  : mySource(source)
122  {
123  setg( &myBuffer , &myBuffer , &myBuffer ) ;
124  }
125 
127  template< class Extractor >
128  int
130  {
131  int result( EOF ) ;
132  if( gptr() < egptr() )
133  result = *gptr() ;
134  else if ( mySource != NULL )
135  {
136  result = myExtractor( *mySource ) ;
137  if ( result != EOF )
138  {
139  if( result < 0 || result > UCHAR_MAX )
140  std::cerr << "FilteringInputStreambuf error" << std::endl;
141  myBuffer = result ;
142  setg( &myBuffer , &myBuffer , &myBuffer + 1 ) ;
143  }
144  }
145  return result ;
146  }
147 
149  template< class Extractor >
150  int
152  {
153  int result( 0 ) ;
154  if ( mySource != NULL )
155  {
156  if ( gptr() < egptr() )
157  { //have read something but not provided it
158  mySource->putback(*gptr() ) ;
159  setg( &myBuffer , &myBuffer , &myBuffer ) ;
160  }
161  result = mySource->sync();
162  }
163  return result ;
164  }
165 
166 //*********************************************
170 {
171 public:
172  int operator()( std::istream& src )
173  {
174  int ch( src.get() ) ;
175  switch (ch)
176  {
177  case 13: //CR or CRLF
178  if(src.peek() == 10)
179  src.get(); //CRLF
180  //fall through
181  case 10: //LF
182  return '\n';
183  break;
184  default:
185  return ch;
186  }
187  }
188  void finalize( std::streambuf& ) {}
189 };
190 
194 template <class Extractor >
196  virtual private FilteringInputStreambuf<Extractor>,
197  public std::istream
198 {
199 public:
200  typedef std::istream& istream_reference;
201  typedef std::istream istream_type;
202 
203  explicit FilteringInputStream(istream_reference istream):
204  FilteringInputStreambuf<Extractor>(&istream),std::istream(this) {}
206 
207 };
208 
209 } //namespace
210 
211 #endif //OB_LINEEND_H
212 
Delivers characters from an istream or streambuf from a source while filtering.
Definition: lineend.h:59
Replaces CRLF (DOS) and CR (Mac OS 9) line endings by LF (POSIX)
Definition: lineend.h:169
void SetSource(std::istream *newsource)
Changes the source.
Definition: lineend.h:103
virtual ~FilteringInputStreambuf()
Definition: lineend.h:64
std::istream * GetSource() const
Returns current source.
Definition: lineend.h:97
virtual int overflow(int)
Definition: lineend.h:68
virtual int underflow()
Definition: lineend.h:129
virtual int sync()
Definition: lineend.h:151
FilteringInputStreambuf(std::istream *source=NULL)
Definition: lineend.h:119
STL namespace.
virtual std::streampos seekoff(std::streamoff off, std::ios_base::seekdir way, std::ios_base::openmode which=std::ios_base::in|std::ios_base::out)
Definition: lineend.h:73
int operator()(std::istream &src)
Definition: lineend.h:172
void finalize(std::streambuf &)
Definition: lineend.h:188
std::istream istream_type
Definition: lineend.h:201
virtual std::streampos seekpos(std::streampos sp, std::ios_base::openmode which=std::ios_base::in|std::ios_base::out)
Definition: lineend.h:83
virtual ~FilteringInputStream()
Definition: lineend.h:205
std::istream & istream_reference
Definition: lineend.h:200
A stream interface for FilteringInputStreambuf.
Definition: lineend.h:195
FilteringInputStream(istream_reference istream)
Definition: lineend.h:203
Global namespace for all Open Babel code.
Definition: alias.h:22