KJB
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
l_stdio_wrap.h
Go to the documentation of this file.
1 
6 /*
7  * $Id: l_stdio_wrap.h 17249 2014-08-07 16:03:32Z predoehl $
8  */
9 
10 /* =========================================================================== *
11 |
12 | Copyright (c) 2012 by Kobus Barnard and Andrew Predoehl.
13 |
14 | Personal and educational use of this code is granted, provided that this
15 | header is kept intact, and that the authorship is not misrepresented, that
16 | its use is acknowledged in publications, and relevant papers are cited.
17 |
18 | For other use contact the author (kobus AT sista DOT arizona DOT edu).
19 |
20 | Please note that the code in this file has not necessarily been adequately
21 | tested. Naturally, there is no guarantee of performance, support, or fitness
22 | for any particular task. Nonetheless, I am interested in hearing about
23 | problems that you encounter.
24 |
25 * =========================================================================== */
26 
27 
28 #ifndef L_STDIO_WRAP_H_UOFARIZONA_VISION
29 #define L_STDIO_WRAP_H_UOFARIZONA_VISION
30 
31 #include <l/l_sys_lib.h>
32 #include <l/l_sys_io.h>
33 #include <l/l_error.h>
34 #include <l/l_global.h>
35 #include <l_cpp/l_exception.h>
36 
37 #include <string>
38 #include <boost/scoped_ptr.hpp>
39 
40 namespace kjb {
41 
42 
60 class File_Ptr {
61  FILE* m_fp;
62 
63  File_Ptr( const File_Ptr& ); // teaser -- this is a non-copyable class
64  File_Ptr& operator=( const File_Ptr& ); // teaser -- non-assignable too
65 
66 protected:
67 
72  void throw_io_error( const std::string& pathname, const char* mode )
73  {
74  KJB_THROW_2( kjb::IO_error, "Unable to open " + pathname
75  + " with mode " + mode );
76  }
77 
82  File_Ptr( const std::string& pathname, const char* mode )
83  : m_fp( kjb_c::kjb_fopen( pathname.c_str(), mode ) )
84  {
85  if ( 0 == m_fp )
86  {
87  throw_io_error( pathname, mode );
88  }
89  }
90 
93  : m_fp( 0 )
94  {}
95 
97  void swap( File_Ptr& that )
98  {
99  std::swap( m_fp, that.m_fp );
100  }
101 
102 public:
103 
105  virtual int close()
106  {
107  int rc = kjb_c::kjb_fclose( m_fp );
108  m_fp = 0;
109  return rc;
110  }
111 
113  virtual ~File_Ptr()
114  {
115  close();
116  }
117 
119  operator FILE*() const
120  {
121  return m_fp;
122  }
123 };
124 
126 struct File_Ptr_Read : public File_Ptr {
127  File_Ptr_Read( const std::string& pathname )
128  : File_Ptr( pathname, "r" )
129  {}
130 };
131 
133 struct File_Ptr_Write : public File_Ptr {
134  File_Ptr_Write( const std::string& pathname )
135  : File_Ptr( pathname, "w" )
136  {}
137 };
138 
140 struct File_Ptr_Append : public File_Ptr {
141  File_Ptr_Append( const std::string& pathname )
142  : File_Ptr( pathname, "a" )
143  {}
144 };
145 
147 struct File_Ptr_Read_Plus : public File_Ptr {
148  File_Ptr_Read_Plus( const std::string& pathname )
149  : File_Ptr( pathname, "r+" )
150  {}
151 };
152 
153 // If you need a mode like w+ or a+ then please add a new derived class
154 
155 
156 
157 
180 class Temporary_File : public File_Ptr {
181 #ifdef UNIX_SYSTEM
182 
183  std::string m_filename;
184 
185 public:
186 
188  Temporary_File();
189 
191  int close()
192  {
193  int rc1 = 0, rc2 = 0;
194  if ( m_filename.size() )
195  {
196  rc1 = File_Ptr::close();
197  rc2 = kjb_c::kjb_unlink( m_filename.c_str() );
198  m_filename.clear();
199  }
200  return rc1 | rc2;
201  }
202 
204  ~Temporary_File()
205  {
206  close();
207  }
208 
216  const std::string& get_filename() const
217  {
218  return m_filename;
219  }
220 
221 #else /* UNIX_SYSTEM above, non-unix below. */
222 #warning "On non-Unix style systems, class Temporary_File does not work."
223 public:
225  int close() { return 0; }
226  const std::string& get_filename() const { return ""; }
227 #endif /* UNIX_SYSTEM (or not) */
228 };
229 
230 
248 
249  std::string m_pathname;
250 
251  bool m_silence;
252 
253  // this item is non-copyable and non-assignable
254  Temporary_Directory(const Temporary_Directory&); // copy ctor teaser
255  Temporary_Directory& operator=(const Temporary_Directory&); // teaser
256 
257 #ifdef UNIX_SYSTEM
258 
259  int do_rmdir() const
260  {
261  return kjb_c::kjb_rmdir( m_pathname.c_str() );
262  }
263 
264  int do_rmrf() const
265  {
266  return kjb_c::kjb_system( ("rm -rf " + m_pathname).c_str() );
267  }
268 
269  int do_the_cleaning(
270  int( Temporary_Directory::* pf_cleaning )() const,
271  const std::string& fail_func
272  )
273  {
274  using namespace kjb_c;
275  ASSERT( pf_cleaning );
276  if ( 0 == m_pathname.size() ) return NO_ERROR;
277 
278  int rc = (this ->* pf_cleaning)();
279  if ( ! is_directory( m_pathname.c_str() ) ) m_pathname.clear();
280 
281  if ( ERROR == rc )
282  {
283  add_error(("Temporary_Directory::"+ fail_func +" failed").c_str());
284  }
285  return rc;
286  }
287 
288 public:
289 
291 
303  int remove()
304  {
305  return do_the_cleaning( & Temporary_Directory::do_rmdir, __func__ );
306  }
307 
309  int recursively_remove()
310  {
311  return do_the_cleaning( & Temporary_Directory::do_rmrf, __func__ );
312  }
313 
315  virtual ~Temporary_Directory()
316  {
317  int status = remove();
318  if (!m_silence)
319  {
320  using namespace kjb_c;
321  EPE(status);
322  }
323  }
324 
325 #else /* UNIX_SYSTEM above, non-unix below. */
326 #warning "On non-Unix style systems, class Temporary_Directory does not work."
327 public:
329  int remove() { return kjb_c::NO_ERROR; }
330  int recursively_remove() { return kjb_c::NO_ERROR; }
331 #endif /* UNIX_SYSTEM (or not) */
332 
340  const std::string& get_pathname() const
341  {
342  return m_pathname;
343  }
344 
353  bool set_silence_flag(bool new_silence_setting = true)
354  {
355  std::swap(m_silence, new_silence_setting);
356  return new_silence_setting;
357  }
358 };
359 
360 
363 {
365  {
366  }
367 
369  {
370  using namespace kjb_c;
371  EPE( recursively_remove() );
372  }
373 
374 #ifndef UNIX_SYSTEM
375 #warning "class Temporary_Recursively_Removing_Directory unavailable w/o Unix."
376 #endif
377 };
378 
379 
380 
413 #ifdef UNIX_SYSTEM
414 
415  boost::scoped_ptr< Temporary_File > temp;
416 
417  void attempt_unzip( const std::string& );
418 
419 public:
420 
422  File_Ptr_Smart_Read( const std::string& filename )
423  {
424  try
425  {
426  File_Ptr_Read fp( filename );
427  File_Ptr::swap( fp );
428  }
429  catch( kjb::IO_error& )
430  {
431  attempt_unzip( filename );
432  }
433  }
434 
444  std::string get_temp_filename() const
445  {
446  if ( temp )
447  {
448  return temp -> get_filename();
449  }
450  return "";
451  }
452 
453 #else /* UNIX_SYSTEM above, non-unix below. */
454 #warning "On non-Unix style systems, class File_Ptr_Smart_Read does not work."
455 public:
456  File_Ptr_Smart_Read( const std::string& fn ) : File_Ptr_Read( fn ) {}
457  std::string get_temp_filename() const { return ""; }
458 #endif /* UNIX_SYSTEM (or not) */
459 };
460 
461 
488 int getline( FILE* fp, std::string* line, char EOL = '\n' );
489 
490 
491 } //namespace kjb
492 
493 #endif /* L_STDIO_WRAP_H_UOFARIZONA_VISION */
File_Ptr_Smart_Read(const std::string &fn)
Definition: l_stdio_wrap.h:456
This class transparently opens gzipped or bzip2-ed files.
Definition: l_stdio_wrap.h:412
File_Ptr_Append(const std::string &pathname)
Definition: l_stdio_wrap.h:141
RAII wrapper on stdio.h FILE pointers (use a derived class though).
Definition: l_stdio_wrap.h:60
File_Ptr_Read_Plus(const std::string &pathname)
Definition: l_stdio_wrap.h:148
File_Ptr_Read(const std::string &pathname)
Definition: l_stdio_wrap.h:127
#define ASSERT(condition, message)
Definition: Assert.h:45
~Temporary_Recursively_Removing_Directory()
Definition: l_stdio_wrap.h:368
int recursively_remove()
Definition: l_stdio_wrap.h:330
int close()
close file before destruction; rarely needed; safe to do twice.
Definition: l_stdio_wrap.h:225
Temporary_Recursively_Removing_Directory()
Definition: l_stdio_wrap.h:364
this class creates a temporary directory under TEMP_DIR (usu. /tmp)
Definition: l_stdio_wrap.h:247
virtual ~File_Ptr()
dtor can simply call close() because closing a null ptr is OK.
Definition: l_stdio_wrap.h:113
Temporary_Directory()
Definition: l_stdio_wrap.h:328
create a temp directory that destroys itself with "rm -rf" command.
Definition: l_stdio_wrap.h:362
File_Ptr(const std::string &pathname, const char *mode)
ctor needs the pathname and a mode; mode is set by derived class
Definition: l_stdio_wrap.h:82
RAII wrapper on FILE* used to append a file (write only at the end).
Definition: l_stdio_wrap.h:140
RAII wrapper on a FILE* used to write to a file.
Definition: l_stdio_wrap.h:133
File_Ptr_Write(const std::string &pathname)
Definition: l_stdio_wrap.h:134
virtual int close()
close file before destruction; rarely needed; safe to do twice.
Definition: l_stdio_wrap.h:105
This class safely opens a temporary file in TEMP_DIR (usually /tmp).
Definition: l_stdio_wrap.h:180
RAII wrapper on FILE* opened with mode "r+" to read and write.
Definition: l_stdio_wrap.h:147
#define KJB_THROW_2(ex, msg)
Definition: l_exception.h:48
void swap(kjb::Gsl_Multimin_fdf &m1, kjb::Gsl_Multimin_fdf &m2)
Swap two wrapped multimin objects.
Definition: gsl_multimin.h:693
RAII wrapper on FILE* used to read a file.
Definition: l_stdio_wrap.h:126
const std::string & get_filename() const
Definition: l_stdio_wrap.h:226
int getline(FILE *fp, std::string *line, char EOL= '\n')
Like C's fgets but with std::string, or C++'s getline but with FILE*.
Temporary_File()
Definition: l_stdio_wrap.h:224
const std::string & get_pathname() const
get the filename of this object (if still valid)
Definition: l_stdio_wrap.h:340
Object thrown when input or output fails.
Definition: l_exception.h:496
Support for error handling exception classes in libKJB.
File_Ptr()
default ctor wraps a null pointer (to set up a later swap maybe)
Definition: l_stdio_wrap.h:92
void swap(File_Ptr &that)
swap the contents of two wrappers
Definition: l_stdio_wrap.h:97
bool set_silence_flag(bool new_silence_setting=true)
By default the dtor prints errors (if any) – you can suppress it.
Definition: l_stdio_wrap.h:353
void throw_io_error(const std::string &pathname, const char *mode)
this is what we do when things go terribly wrong
Definition: l_stdio_wrap.h:72
std::string get_temp_filename() const
Definition: l_stdio_wrap.h:457