Cambridge SMT System
szfstream.hpp
Go to the documentation of this file.
1 // Licensed under the Apache License, Version 2.0 (the "License");
2 // you may not use these files except in compliance with the License.
3 // You may obtain a copy of the License at
4 //
5 // http://www.apache.org/licenses/LICENSE-2.0
6 //
7 // Unless required by applicable law or agreed to in writing, software
8 // distributed under the License is distributed on an "AS IS" BASIS,
9 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10 // See the License for the specific language governing permissions and
11 // limitations under the License.
12 
13 // Copyright 2012 - Gonzalo Iglesias, AdriĆ  de Gispert, William Byrne
14 
21 #ifndef SZFSTREAM_HPP
22 #define SZFSTREAM_HPP
23 
24 #ifdef USE_FDSTREAM_HPP
25 #include "fdstream.hpp"
26 #endif
27 
28 namespace ucam {
29 namespace util {
30 
34 class iszfstream {
35 
36  private:
37 
39  FILE* sfile_;
40 
41 #ifndef USE_FDSTREAM_HPP
42  boost::scoped_ptr<std::ifstream> file;
43  boost::scoped_ptr<boost::iostreams::filtering_streambuf<boost::iostreams::input> >
44  in;
45 #endif
46  std::istream *filestream_;
48  std::string auxfilename;
49 
50  public:
51 
54  sfile_ ( NULL ),
55  filestream_ ( NULL ) {
56  };
58  iszfstream ( const std::string& filename ) :
59  sfile_ ( NULL ),
60  filestream_ ( NULL ) {
61  open ( filename );
62  };
63 
64  iszfstream ( const std::stringstream& ss ) :
65  sfile_ ( NULL ),
66  filestream_ ( NULL ) {
67  open ( ss );
68  };
69 
71  inline std::istream *getStream() {
72  return filestream_;
73  };
74 
75  inline void open ( const std::stringstream& ss ) {
76  close();
77  filestream_ = new std::stringstream ( ss.str() );
78  };
79 
86  inline void open ( const std::string& filename ) {
87  close();
88 #ifdef USE_FDSTREAM_HPP
89  if ( filename != "-" ) {
90  LDEBUG ( "Test file=[" << filename << "]" );
91  sfile_ = fopen ( filename.c_str(), "r" );
92  USER_CHECK ( sfile_ != NULL, "Error while opening file" );
93  fclose ( sfile_ );
94  //Now we can assume more or less safely that file really exists (sigh)
95  }
96  //lets open this with the pipe.
97  std::string command = "zcat -f ";
98  command += filename;
99  LINFO ( "Opening (fd)" << command );
100  sfile_ = popen ( command.c_str(), "r" );
101  USER_CHECK ( sfile_ != NULL, "Error while opening pipe" );
102  filestream_ = new boost::fdistream ( fileno ( sfile_ ) );
103  USER_CHECK (filestream_, "File Stream allocation failed!");
104 #else
105  LINFO ( "Opening " << filename );
106  std::string auxfilename = filename;
107  if (auxfilename == "-" ) auxfilename = "/dev/stdin";
108  file.reset (new std::ifstream (auxfilename.c_str(),
109  std::ios_base::in | std::ios_base::binary) );
110  if (!USER_CHECK (file->is_open(),
111  "Error while opening file:") ) exit (EXIT_FAILURE);
112  in.reset (new boost::iostreams::filtering_streambuf<boost::iostreams::input>);
113  if (auxfilename.substr (0, 5) != "/dev/" ) {
114  if (ends_with (auxfilename, ".gz") )
115  in->push (boost::iostreams::gzip_decompressor() );
116  }
117  in->push (*file);
118  filestream_ = new std::istream (&*in);
119  if (!USER_CHECK (filestream_,
120  "File Stream allocation failed!") ) exit (EXIT_FAILURE);
121  //Try to detect whether it actually _is_ a compressed file (sigh) .
122  if (ends_with (auxfilename, ".gz") ) {
123  filestream_->peek();
124  if (!USER_CHECK (filestream_->good(),
125  "File not open/doesn't exist... Or possibly not compressed but ends with .gz? " ) )
126  exit (EXIT_FAILURE);
127  }
128 #endif
129  };
130 
132  inline bool is_open() {
133  return ( filestream_ != NULL );
134  };
135 
138  close();
139  };
140 
142  virtual inline int eof() {
143  return filestream_->eof();
144  };
145 
147  inline void close() {
148  if ( !is_open() ) return;
149 #ifndef USE_FDSTREAM_HPP
150  in.reset();
151  file.reset();
152 #endif
153  if ( sfile_ ) {
154  fclose ( sfile_ );
155  sfile_ = NULL;
156  }
157  if ( filestream_ ) {
158  delete filestream_;
159  filestream_ = NULL;
160  }
161  };
162 
164  virtual operator void *() {
165  return eof() ? NULL : this;
166  };
167 
169  virtual inline iszfstream& getline ( std::string& line );
170 
171  friend iszfstream& getline ( iszfstream&, std::string&);
172 
173  template <typename T>
174  friend iszfstream& operator>> ( iszfstream&, T&);
175 
176 };
177 
178 inline iszfstream& getline ( iszfstream& izs, std::string& line ) {
179  std::getline ( *izs.filestream_, line );
180  return izs;
181 };
182 
183 inline iszfstream& iszfstream::getline ( std::string& line ) {
184  ::ucam::util::getline ( *this, line );
185  return *this;
186 };
187 
189 template <typename T>
190 inline iszfstream& operator>> ( iszfstream& iszf, T& stff ) {
191  *iszf.filestream_ >> stff;
192  return iszf;
193 };
194 
200 class oszfstream {
201  private:
202  bool append_;
203 
205  FILE* sfile_;
206 
207 #ifndef USE_FDSTREAM_HPP
208  boost::scoped_ptr<std::ofstream> file;
209  boost::scoped_ptr<boost::iostreams::filtering_streambuf<boost::iostreams::output> >
210  out;
211 #endif
212  std::ostream *filestream_;
214  std::string myfilename;
215 
216  public:
217 
223  oszfstream ( const std::string& filename , bool append = false) :
224  sfile_ ( NULL ),
225  filestream_ ( NULL ),
226  append_ (append) {
227  open ( filename );
228  }
229 
235  oszfstream ( const std::stringstream& ss ) :
236  sfile_ ( NULL ), filestream_ ( NULL ), append_ (false) {
237  open ( ss );
238  }
239 
241  inline std::ostream *getStream() {
242  return filestream_;
243  };
244 
245  void open ( const std::stringstream& ss ) {
246  close();
247  filestream_ = new std::stringstream ( ss.str() );
248  }
249 
255  void open ( const std::string& filename ) {
256  close();
257  if (filename == "") {
258  LWARN ("Empty file name?");
259  return;
260  }
261  std::string cmd;
262  DirName ( cmd, filename );
263  if ( cmd != "" && cmd != "./" && cmd != "/" ) {
264  cmd = "mkdir -p " + cmd;
265  int a = system ( cmd.c_str() );
266  }
267 #ifdef USE_FDSTREAM_HPP
268  std::string command = "cat - >";
269  if ( filename.size() > 3 )
270  if ( filename.substr ( filename.size() - 3 ) == ".gz" ) command = "gzip > ";
271  if (append_) command += ">";
272  if ( filename == "-" ) command += "/dev/stdout";
273  else command += filename;
274  if ( ( sfile_ = popen ( command.c_str(), "w" ) ) == NULL ) {
275  cerr << "Error while opening file via: " << command << endl;
276  exit ( EXIT_FAILURE );
277  }
278  LINFO ( "Opening (fd)" << command );
279  filestream_ = new boost::fdostream ( fileno ( sfile_ ) );
280 #else
281  if ( filename == "-" ) myfilename = "/dev/stdout";
282  else myfilename = filename;
283  if (!append_)
284  file.reset (new std::ofstream (myfilename.c_str(),
285  std::ios_base::out | std::ios_base::binary ) );
286  else
287  file.reset (new std::ofstream (myfilename.c_str(),
288  std::ios_base::out | std::ios_base::binary | std::ios_base::app ) );
289  if (!file->is_open() ) {
290  std::cerr << "Error while opening " << filename << std::endl;
291  exit (EXIT_FAILURE);
292  }
293  out.reset (new boost::iostreams::filtering_streambuf<boost::iostreams::output>);
294  if (filename.substr (0, 5) != "/dev/" ) {
295  if (ends_with (filename, ".gz") ) {
296  out->push (boost::iostreams::gzip_compressor() );
297  }
298  }
299  out->push (*file);
300  LINFO ( "Opening " << filename );
301  filestream_ = new std::ostream (&*out);
302  if (filestream_ == NULL) {
303  std::cerr << "Error while opening " << filename << std::endl;
304  exit (EXIT_FAILURE);
305  }
306 #endif
307  };
308 
314  close();
315  };
316 
318  bool is_open() {
319  return ( filestream_ != NULL );
320  };
321 
323  inline void close() {
324  if ( !is_open() ) return;
325 #ifndef USE_FDSTREAM_HPP
326  out.reset();
327  file.reset();
328 #endif
329  if ( filestream_ ) {
330  delete filestream_;
331  filestream_ = NULL;
332  }
333  if ( sfile_ ) {
334  fclose ( sfile_ );
335  sfile_ = NULL;
336  }
337  };
338 
339  typedef std::basic_ostream<char, std::char_traits<char> > CoutType;
340  typedef CoutType& ( *StandardEndLine ) ( CoutType&);
341 
343  oszfstream& operator<< ( StandardEndLine manip ) {
344  *this << "\n";
345  return *this;
346  };
347 
349  template <typename T>
350  inline oszfstream& operator<< ( const T& stff ) {
351  *filestream_ << stff;
352  return *this;
353  };
354 
355 };
356 
358 template <typename FM>
359 inline void readtextfile ( const std::string& filename, FM& fm ) {
360  iszfstream iszf ( filename );
361  std::string line;
362  while ( getline ( iszf, line ) ) {
363  fm.parse ( line );
364  }
365  iszf.close();
366 };
367 
369 template <typename FM>
370 inline void writetextfile ( const std::string& filename, FM& fm ) {
371  oszfstream oszf ( filename );
372  std::string line;
373  while ( fm.toLine ( line ) ) {
374  oszf << line << endl;
375  }
376  oszf.close();
377 };
378 
380 template <class StreamT = std::istream >
382  private:
383  boost::scoped_ptr<StreamT> af_;
384  uint idx_;
385  public:
387  FastForwardRead ( StreamT *af ) :
388  af_ ( af ),
389  idx_ ( 0 ) {
390  LDEBUG ( "Ready!" );
391  };
392 
394  inline bool operator() ( uint id, std::string *line ) {
395  bool finished = false;
396  std::string aux;
397  *line = "";
398  USER_CHECK ( idx_ <= id, "Will not read backwards!" );
399  while ( ++idx_ < id ) {
400  USER_CHECK ( getline ( *af_, aux ), "source text file out of range!" );
401  }
402  if ( !getline ( *af_, *line ) ) {
403  finished = true;
404  }
405  return finished;
406  };
407 
408 };
409 
410 }
411 } // end namespaces
412 
413 #endif
Wrapper stream class that writes to pipes, text files or gzipped files.
Definition: szfstream.hpp:200
Convenience class that reads "quickly" until a queried line.
Definition: szfstream.hpp:381
std::basic_ostream< char, std::char_traits< char > > CoutType
Definition: szfstream.hpp:337
std::ostream * getStream()
Returns internal stream.
Definition: szfstream.hpp:241
friend iszfstream & operator>>(iszfstream &, T &)
Templated operator >> for streaming out of iszfstream.
Definition: szfstream.hpp:190
virtual iszfstream & getline(std::string &line)
Read a line.
Definition: szfstream.hpp:183
iszfstream()
Empty constructor.
Definition: szfstream.hpp:53
oszfstream(const std::stringstream &ss)
Constructor.
Definition: szfstream.hpp:235
#define LINFO(msg)
void open(const std::stringstream &ss)
Definition: szfstream.hpp:75
void open(const std::string &filename)
Opens a file. using boost: using fdstream: All three cases are handled with zcat -f,, which is piped (i.e. handled by another processor).
Definition: szfstream.hpp:86
iszfstream(const std::stringstream &ss)
Definition: szfstream.hpp:64
#define LDEBUG(msg)
iszfstream(const std::string &filename)
Constructor with a file name. Opens the file.
Definition: szfstream.hpp:58
bool is_open()
Checks if the file/pipe is open.
Definition: szfstream.hpp:132
std::ostream & operator<<(std::ostream &o, Container< T > const &container)
~iszfstream()
Destructor. Closes the file.
Definition: szfstream.hpp:137
iszfstream & getline(iszfstream &izs, std::string &line)
Definition: szfstream.hpp:178
void open(const std::string &filename)
Opens a [file].
Definition: szfstream.hpp:255
oszfstream(const std::string &filename, bool append=false)
Constructor.
Definition: szfstream.hpp:223
bool is_open()
Checks whether the file is open.
Definition: szfstream.hpp:318
#define LWARN(msg)
void close()
Closes file.
Definition: szfstream.hpp:147
void writetextfile(const std::string &filename, FM &fm)
Function that writes to file. Templated on any external class with a toLine method.
Definition: szfstream.hpp:370
bool DirName(std::string &dirname, const std::string &filename)
std::istream * getStream()
Returns internal stream.
Definition: szfstream.hpp:71
void readtextfile(const std::string &filename, FM &fm)
Function that reads from a file. Templated on any external class with a parse method.
Definition: szfstream.hpp:359
#define USER_CHECK(exp, comment)
Tests whether exp is true. If not, comment is printed and program ends.
void open(const std::stringstream &ss)
Definition: szfstream.hpp:245
~oszfstream()
Destructor. Closes the file.
Definition: szfstream.hpp:313
virtual int eof()
Checks for end-of-file.
Definition: szfstream.hpp:142
Wrapper stream class that reads pipes, text files or gzipped files.
Definition: szfstream.hpp:34
bool ends_with(std::string const &haystack, std::string const &needle)
Definition: bleu.hpp:14
FastForwardRead(StreamT *af)
Constructor.
Definition: szfstream.hpp:387
void close()
Closes the file.
Definition: szfstream.hpp:323