Michele De Stefano's C++ Utilities
cfile_device_base.hpp
1 #ifndef CFILE_DEVICE_BASE_HPP_INCLUDED
2 #define CFILE_DEVICE_BASE_HPP_INCLUDED
3 
4 // cfile_device_base.hpp
5 //
6 // Copyright (c) 2009 - Michele De Stefano (micdestefano@users.sourceforge.net)
7 //
8 // Distributed under the MIT License (See accompanying file LICENSE)
9 
10 #include <mds_utils/file_utils/detail/cfile_stream_fwd.hpp>
11 #include <iosfwd> // streamsize
12 #include <boost/iostreams/categories.hpp> // source_tag
13 #include <boost/iostreams/traits.hpp>
14 #include <boost/iostreams/positioning.hpp>
15 #include <boost/type_traits/is_same.hpp>
16 #include <boost/mpl/if.hpp>
17 #include <boost/mpl/not.hpp>
18 #include <cstdio>
19 
21 
22 namespace mds_utils { namespace file_utils {
23 
24  // Contains implementation details (not to be used by the user)
25  namespace detail {
26 
27 // Base class for all FILE* devices
28 template<class Derived>
29 class cFile_Device_base {
30 
31 protected:
32 
33  FILE *file_ptr; // The FILE pointer
34 
35 public:
36 
37  typedef char char_type;
38  struct category : virtual boost::iostreams::device_tag,
39  virtual boost::mpl::if_<
40  boost::is_same<Derived,cFile_Sink>,
41  boost::iostreams::output_seekable,
42  typename boost::mpl::if_<
43  boost::is_same<Derived,cFile_Source>,
44  boost::iostreams::input_seekable,
45  boost::iostreams::seekable
46  >::type
47  >::type,
48  virtual boost::mpl::if_<boost::mpl::not_<
49  boost::is_same<Derived,cFile_Source> >,
50  boost::iostreams::flushable_tag,
51  boost::iostreams::any_tag
52  >::type {};
53 
54  cFile_Device_base() {}
55  cFile_Device_base(FILE *ptr) : file_ptr(ptr) {}
56 
57  void set_FILEp(FILE *ptr) { file_ptr = ptr; }
58 
59  boost::iostreams::stream_offset
60  seek(boost::iostreams::stream_offset off,std::ios_base::seekdir way) {
61 
62  using namespace boost::iostreams;
63  using namespace std;
64 
65  stream_offset next;
66  int whence;
67  switch (way) {
68  case ios_base::beg:
69  whence = SEEK_SET;
70  break;
71  case ios_base::cur:
72  whence = SEEK_CUR;
73  break;
74  case ios_base::end:
75  whence = SEEK_END;
76  break;
77  default:
78  throw ios_base::failure("Bad seek direction (cFile_Device_base::seek)");
79  }
80 
81 #ifdef HAVE_FSEEKO
82  fseeko(file_ptr,off,whence);
83  next = ftello(file_ptr);
84 #else
85  fseek(file_ptr,off,whence);
86  next = ftell(file_ptr);
87 #endif
88 
89  return next;
90  }
91 };
92 
93  } // namespace detail
94 
95 #define DEF_READ \
96 std::streamsize read(char_type *s,std::streamsize n) { \
97  if (feof(file_ptr)) return -1; \
98  return fread(reinterpret_cast<void*>(s),sizeof(char),n,file_ptr); \
99 }
100 
101 #define DEF_WRITE \
102 std::streamsize write(const char_type *s,std::streamsize n) { \
103  return fwrite(reinterpret_cast<const void*>(s),sizeof(char),n,file_ptr); \
104 }
105 
106 #define DEF_FLUSH \
107 bool flush() { return (fflush(file_ptr) == 0); }
108 
109 
110 }}
111 
113 
114 #endif
Main namespace of all Michele De Stefano&#39;s C++ utilities.
Definition: endian.hpp:30