core/vil1/vil1_stream_fstream.cxx

Go to the documentation of this file.
00001 // This is core/vil1/vil1_stream_fstream.cxx
00002 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00003 #pragma implementation
00004 #endif
00005 
00006 #include "vil1_stream_fstream.h"
00007 #include <vcl_cassert.h>
00008 #include <vcl_iostream.h>
00009 
00010 static vcl_ios_openmode modeflags(char const* mode)
00011 {
00012   if (*mode == 0)
00013     return vcl_ios_openmode(0);
00014 
00015   if (*mode == 'r') {
00016     if (mode[1] == '+')
00017       return vcl_ios_in | vcl_ios_out | modeflags(mode+2);
00018     else
00019       return vcl_ios_in | modeflags(mode+1);
00020   }
00021 
00022   if (*mode == 'w') {
00023     if (mode[1] == '+')
00024       return vcl_ios_in | vcl_ios_out | vcl_ios_trunc | modeflags(mode+2);
00025     else
00026       return vcl_ios_out | modeflags(mode+1);
00027   }
00028 
00029   vcl_cerr << vcl_endl << __FILE__ ": DODGY MODE " << mode << vcl_endl;
00030   return vcl_ios_openmode(0);
00031 }
00032 
00033 #define xerr if (true) ; else (vcl_cerr << "vcl_fstream#" << id_ << ": ")
00034 
00035 static int id = 0;
00036 
00037 vil1_stream_fstream::vil1_stream_fstream(char const* fn, char const* mode):
00038   flags_(modeflags(mode)),
00039   f_(fn, flags_ | vcl_ios_binary) // need ios::binary on windows.
00040 {
00041   id_ = ++id;
00042   xerr << "vil1_stream_fstream(\"" << fn << "\", \""<<mode<<"\") = " << id_ << '\n';
00043 #if 0
00044   if (!f_)
00045     vcl_cerr << "vil1_stream_fstream::Could not open [" << fn << "]\n";
00046 #endif // 0
00047 }
00048 
00049 #if 0
00050 vil1_stream_fstream::vil1_stream_fstream(vcl_fstream& f):
00051   f_(f.rdbuf()->fd())
00052 {
00053 }
00054 #endif // 0
00055 
00056 vil1_stream_fstream::~vil1_stream_fstream()
00057 {
00058   xerr << "vil1_stream_fstream# " << id_ << " being deleted\n";
00059 }
00060 
00061 vil1_streampos vil1_stream_fstream::write(void const* buf, vil1_streampos n)
00062 {
00063   assert(id > 0);
00064   if (!(flags_ & vcl_ios_out)) {
00065     vcl_cerr << "vil1_stream_fstream: write failed, not an vcl_ostream\n";
00066     return 0;
00067   }
00068 
00069   vil1_streampos a = tell();
00070   xerr << "write " << n << vcl_endl;
00071   f_.write((char const*)buf, n);
00072   if (!f_.good())
00073     vcl_cerr << ("vil1_stream_fstream: ERROR: write failed!\n");
00074   vil1_streampos b = tell();
00075   f_.flush();
00076   return b-a;
00077 }
00078 
00079 
00080 vil1_streampos vil1_stream_fstream::read(void* buf, vil1_streampos n)
00081 {
00082   assert(id > 0);
00083 
00084   if (!(flags_ & vcl_ios_in))
00085     return 0;
00086 
00087   vil1_streampos a = tell();
00088   xerr << "read " << n << vcl_endl;
00089   f_.read((char *)buf, n);
00090 
00091   // fsm  This is for gcc 2.95 :
00092   // If we try to read more data than is in the file, the good()
00093   // function will return false even though bad() returns false
00094   // too. The stream is actually fine but we need to clear the
00095   // eof flag to use it again.
00096   // iscott@man It does something similar under Windows, but has the added
00097   // advantage, of making tell() return a sensible value (instead
00098   // of -1)
00099   if (!f_.good() && !f_.bad() && f_.eof())
00100     f_.clear(); // allows subsequent operations
00101 
00102   vil1_streampos b = tell();
00103 
00104   vil1_streampos numread = b-a;
00105   if (b < a) { xerr << "urgh!\n"; return numread; }
00106   if (numread != n) xerr << "only read " << numread << vcl_endl;
00107   return numread;
00108 }
00109 
00110 vil1_streampos vil1_stream_fstream::tell() const
00111 {
00112   assert(id > 0);
00113   if (flags_ & vcl_ios_in) {
00114     xerr << "tellg\n";
00115     return f_.tellg();
00116   }
00117   if (flags_ & vcl_ios_out) {
00118     xerr << "tellp\n";
00119     return f_.tellp();
00120   }
00121 
00122   assert(false); // did you get here? use at least one of vcl_ios_in, vcl_ios_out.
00123   return (vil1_streampos)(-1L);
00124 }
00125 
00126 void vil1_stream_fstream::seek(vil1_streampos position)
00127 {
00128   assert(id > 0);
00129   bool fi = (flags_ & vcl_ios_in)  != 0;
00130   bool fo = (flags_ & vcl_ios_out) != 0;
00131 
00132   if (fi && fo) {
00133     xerr << "seekg and seekp to " << position << vcl_endl;
00134     if (position != vil1_streampos(f_.tellg())) {
00135       f_.seekg(position);
00136       f_.seekp(position);
00137       assert(f_.good());
00138     }
00139   }
00140   else if (fi) {
00141     xerr << "seek to " << position << vcl_endl;
00142     if (position != vil1_streampos(f_.tellg())) {
00143       f_.seekg(position);
00144       assert(f_.good());
00145     }
00146   }
00147   else if (fo) {
00148     xerr << "seekp to " << position << vcl_endl;
00149     int at = f_.tellp();
00150     if (position != at) {
00151       xerr << "seekp to " << position << ", at " << (long)f_.tellp() << vcl_endl;
00152       f_.seekp(position);
00153       assert(f_.good());
00154     }
00155   }
00156   else
00157     assert(false); // did you get here? use at least one of vcl_ios_in, vcl_ios_out.
00158 }

Generated on Sat Nov 22 05:08:29 2008 for core/vil1 by  doxygen 1.5.1