Go to the documentation of this file.00001
00002 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00003 #pragma implementation
00004 #endif
00005
00006 #include "vil_stream_fstream.h"
00007 #include <vcl_cassert.h>
00008 #include <vcl_limits.h>
00009 #include <vcl_iostream.h>
00010 #include <vcl_ios.h>
00011
00012 static vcl_ios_openmode modeflags(char const* mode)
00013 {
00014 if (*mode == 0)
00015 return vcl_ios_openmode(0);
00016
00017 if (*mode == 'r') {
00018 if (mode[1] == '+' || mode[1] == 'w')
00019 return vcl_ios_in | vcl_ios_out | modeflags(mode+2);
00020 else
00021 return vcl_ios_in | modeflags(mode+1);
00022 }
00023
00024 if (*mode == 'w') {
00025 if (mode[1] == '+')
00026 return vcl_ios_in | vcl_ios_out | vcl_ios_trunc | modeflags(mode+2);
00027 else
00028 return vcl_ios_out | vcl_ios_trunc | modeflags(mode+1);
00029 }
00030
00031 vcl_cerr << vcl_endl << __FILE__ ": DODGY MODE " << mode << vcl_endl;
00032 return vcl_ios_openmode(0);
00033 }
00034
00035 #define xerr if (true) ; else (vcl_cerr << "vcl_fstream#" << id_ << ": ")
00036
00037 static int id = 0;
00038
00039 vil_stream_fstream::vil_stream_fstream(char const* fn, char const* mode):
00040 flags_(modeflags(mode)),
00041 f_(fn, flags_ | vcl_ios_binary),
00042 end_( -1 )
00043 {
00044 id_ = ++id;
00045 xerr << "vil_stream_fstream(\"" << fn << "\", \""<<mode<<"\") = " << id_ << '\n';
00046 #if 0
00047 if (!f_) {
00048 vcl_cerr << "vil_stream_fstream::Could not open [" << fn << "]\n";
00049 }
00050 #endif // 0
00051 }
00052
00053 #if defined(VCL_WIN32) && VXL_USE_WIN_WCHAR_T
00054 vil_stream_fstream::vil_stream_fstream(wchar_t const* fn, char const* mode):
00055 flags_(modeflags(mode)),
00056 f_(fn, flags_ | vcl_ios_binary),
00057 end_( -1 )
00058 {
00059 id_ = ++id;
00060 }
00061 #endif //defined(VCL_WIN32) && VXL_USE_WIN_WCHAR_T
00062
00063 #if 0
00064 vil_stream_fstream::vil_stream_fstream(vcl_fstream& f):
00065 f_(f.rdbuf()->fd()),
00066 end_( -1 )
00067 {
00068 }
00069 #endif // 0
00070
00071 vil_stream_fstream::~vil_stream_fstream()
00072 {
00073 xerr << "vil_stream_fstream# " << id_ << " being deleted\n";
00074 }
00075
00076 vil_streampos vil_stream_fstream::write(void const* buf, vil_streampos n)
00077 {
00078 assert(id > 0);
00079
00080
00081
00082 #ifndef VCL_GCC_295
00083 assert( n <= vcl_numeric_limits<vcl_streamoff>::max() );
00084 #endif
00085
00086 if (!(flags_ & vcl_ios_out)) {
00087 vcl_cerr << "vil_stream_fstream: write failed, not a vcl_ostream\n";
00088 return 0;
00089 }
00090
00091 vil_streampos a = tell();
00092 xerr << "write " << n << vcl_endl;
00093 f_.write((char const*)buf, (vcl_streamoff)n);
00094 if (!f_.good())
00095 vcl_cerr << ("vil_stream_fstream: ERROR: write failed!\n");
00096 vil_streampos b = tell();
00097 f_.flush();
00098 return b-a;
00099 }
00100
00101
00102 vil_streampos vil_stream_fstream::read(void* buf, vil_streampos n)
00103 {
00104 assert(id > 0);
00105
00106
00107
00108 #ifndef VCL_GCC_295
00109 assert( n <= vcl_numeric_limits<vcl_streamoff>::max() );
00110 #endif
00111
00112 if (!(flags_ & vcl_ios_in))
00113 return 0;
00114
00115 vil_streampos a = tell();
00116 xerr << "read " << n << vcl_endl;
00117 f_.read((char *)buf, (vcl_streamoff)n);
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127 if (!f_.good() && !f_.bad() && f_.eof())
00128 f_.clear();
00129
00130 vil_streampos b = tell();
00131
00132 vil_streampos numread = b-a;
00133 if (b < a) { xerr << "urgh!\n"; return numread; }
00134 if (numread != n) { xerr << "only read " << numread << vcl_endl; }
00135 return numread;
00136 }
00137
00138 vil_streampos vil_stream_fstream::tell() const
00139 {
00140 assert(id > 0);
00141 if (flags_ & vcl_ios_in) {
00142 xerr << "tellg\n";
00143 return f_.tellg();
00144 }
00145
00146 if (flags_ & vcl_ios_out) {
00147 xerr << "tellp\n";
00148 return f_.tellp();
00149 }
00150
00151 assert(false);
00152 return (vil_streampos)(-1L);
00153 }
00154
00155 void vil_stream_fstream::seek(vil_streampos position)
00156 {
00157 assert(id > 0);
00158
00159
00160
00161 #ifndef VCL_GCC_295
00162 assert( position <= vcl_numeric_limits< vcl_streamoff >::max() );
00163 #endif
00164
00165 bool fi = (flags_ & vcl_ios_in) != 0;
00166 bool fo = (flags_ & vcl_ios_out) != 0;
00167
00168 if (fi && fo) {
00169 xerr << "seekg and seekp to " << position << vcl_endl;
00170 if (position != vil_streampos(f_.tellg())) {
00171 f_.seekg((vcl_streamoff)position);
00172 f_.seekp((vcl_streamoff)position);
00173 assert(f_.good());
00174 }
00175 }
00176
00177 else if (fi) {
00178 xerr << "seek to " << position << vcl_endl;
00179 if (position != vil_streampos(f_.tellg())) {
00180 f_.seekg((vcl_streamoff)position);
00181 assert(f_.good());
00182 }
00183 }
00184
00185 else if (fo) {
00186 xerr << "seekp to " << position << vcl_endl;
00187 vcl_streamoff at = f_.tellp();
00188 if (position != at) {
00189 xerr << "seekp to " << position << ", at " << (long)f_.tellp() << vcl_endl;
00190 f_.seekp((vcl_streamoff)position);
00191 assert(f_.good());
00192 }
00193 }
00194 else
00195 assert(false);
00196 }
00197
00198 vil_streampos vil_stream_fstream::file_size() const
00199 {
00200
00201 if ( end_ == -1 ) {
00202 vcl_streampos curr = f_.tellg();
00203 f_.seekg( 0, vcl_ios_end );
00204 end_ = f_.tellg();
00205 f_.seekg( curr );
00206 }
00207
00208 return end_;
00209 }