vil_stream_fstream64.cxx
Go to the documentation of this file.
1 // This is core/vil/vil_stream_fstream64.cxx
2 #ifdef VIL_USE_FSTREAM64 // only compile this file when needed
3 
4 #include <iostream>
5 #include "vil_stream_fstream64.h"
6 #include <cassert>
7 #ifdef _MSC_VER
8 # include <vcl_msvc_warnings.h>
9 #endif
10 
11 #if defined(WIN32)
12 #include <io.h>
13 #endif
14 #include <fcntl.h>
15 #include <sys/stat.h>
16 
17 #ifndef WIN32
18 //RaR: My attempt at cross-platform compatibility
19 // This stuff really isn't that important because
20 // this file is only added to the configuration
21 // for WIN32 builds
22 #define _O_RDWR O_RDWR
23 #define _O_RDONLY O_RDONLY
24 #define _O_WRONLY O_WRONLY
25 #define _O_BINARY 0
26 #define _O_CREAT O_CREAT
27 #define _S_IREAD S_IREAD
28 #define _S_IWRITE S_IWRITE
29 #define _open ::open
30 #define _close ::close
31 #define _telli64(fd) ::lseek(fd, 0, SEEK_CUR)
32 #define _lseeki64 ::lseek
33 #include <unistd.h>
34 #define _commit ::fsync
35 #define _read ::read
36 #define _write ::write
37 #endif
38 
39 #define xerr if (true) ; else (std::cerr << "std::fstream#" << fd_ << ": ")
40 
41 static int modeflags(char const* mode)
42 {
43  bool read = false,
44  write = false;
45 
46  for ( unsigned int i = 0; mode[i] != 0; ++i ) {
47  if ( mode[i] == 'r' )
48  read = true;
49  else if ( mode[i] == 'w' )
50  write = true;
51  }
52 
53  if ( read && write ) return _O_RDWR;
54  else if ( read ) return _O_RDONLY;
55  else if ( write ) return _O_WRONLY;
56 
57  std::cerr << '\n' << __FILE__ ": DODGY MODE " << mode << '\n';
58  return 0;
59 }
60 
61 
62 vil_stream_fstream64::vil_stream_fstream64(char const* fn, char const* mode) :
63  mode_( modeflags(mode) )
64 {
65  if ( mode_ == O_RDONLY ) {
66  fd_ = _open( fn, mode_ | _O_BINARY );
67  } else {
68  fd_ = _open( fn, mode_ | _O_CREAT | _O_BINARY, _S_IREAD | _S_IWRITE );
69  }
70  if ( fd_ == -1 ){
71  std::cerr << "vil_stream_fstream64::Could not open [" << fn << "]\n";
72  }
73 }
74 
75 #if defined(_WIN32) && VXL_USE_WIN_WCHAR_T
76 vil_stream_fstream64::vil_stream_fstream64(wchar_t const* fn, char const* mode):
77  mode_(modeflags(mode))
78 {
79  if ( mode_ == O_RDONLY )
80  fd_ = _wopen( fn, mode_ | _O_BINARY );
81  else
82  fd_ = _wopen( fn, mode_ | _O_CREAT | _O_BINARY, _S_IREAD | _S_IWRITE );
83  if ( fd_ == -1 )
84  {
85  std::cerr << "vil_stream_fstream64::Could not open [" << fn << "]\n";
86  }
87 }
88 #endif //defined(_WIN32) && VXL_USE_WIN_WCHAR_T
89 
90 vil_stream_fstream64::~vil_stream_fstream64()
91 {
92  //xerr << "vil_stream_fstream64 # " << fd_ << " being deleted\n";
93 
94  if ( ok() ){
95  _close( fd_ );
96  }
97 }
98 
99 vil_streampos vil_stream_fstream64::write(void const* buf, vil_streampos n)
100 {
101  assert(ok());
102 
103  if ( !( ( mode_ == _O_WRONLY ) ||
104  ( mode_ == _O_RDWR ) ) )
105  {
106  std::cerr << "vil_stream_fstream64: write failed, stream not open for write\n";
107  return 0;
108  }
109 
110  //cast should be ok unless trying to write >2GB (not likely)
111  int ret_val = _write( fd_, buf, (unsigned int)n );
112  if ( ret_val == -1 ){
113  std::cerr << ("vil_stream_fstream64: ERROR: write failed!\n");
114  return 0;
115  } else {
116  //apparently calling _commit is relatively slow
117  //for file types like pnm whose put_view() functions
118  //write() one byte at a time, it takes minutes to write a
119  //single (relatively) small file. That's why we comment
120  //out this commit() (ie. flush) logic. All tests pass,
121  //so this should be ok.
122  //if ( _commit( fd_ ) == -1 ){
123  // return 0;
124  //} else {
125  return ret_val;
126  //}
127  }
128 }
129 
130 
131 vil_streampos vil_stream_fstream64::read(void* buf, vil_streampos n)
132 {
133  assert(ok());
134 
135  if ( !( ( mode_ == _O_RDONLY ) ||
136  ( mode_ == _O_RDWR ) ) )
137  {
138  xerr << "vil_stream_fstream64: read failed, stream not open for read\n";
139  return 0;
140  }
141  //cast should be ok unless trying to read >2GB
142  int ret_val = _read( fd_, buf, (unsigned int)n );
143  if ( ret_val == -1 )
144  xerr << "read failed!\n";
145  else if ( ret_val < n )
146  xerr << "only read " << ret_val << std::endl;
147 
148  return ret_val;
149 }
150 
151 vil_streampos vil_stream_fstream64::tell() const
152 {
153  assert(ok());
154  return _telli64( fd_ );
155 }
156 
157 void vil_stream_fstream64::seek(vil_streampos position)
158 {
159  assert(ok());
160  long long ret_val = _lseeki64( fd_, position, SEEK_SET );
161  if ( ret_val == -1L ){
162  xerr << "error during seek.";
163  }
164 }
165 
166 vil_streampos vil_stream_fstream64::file_size() const
167 {
168  vil_streampos curr = tell();
169  _lseeki64( fd_, 0, SEEK_END );
170  vil_streampos end = tell();
171  _lseeki64( fd_, curr, SEEK_SET );
172  return end;
173 }
174 
175 #endif // VIL_USE_FSTREAM64
vxl_int_32 vil_streampos
Definition: vil_stream.h:16
#define xerr