Panda3D
 All Classes Functions Variables Enumerations
streamWrapper.cxx
00001 // Filename: streamWrapper.cxx
00002 // Created by:  drose (11Nov08)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) Carnegie Mellon University.  All rights reserved.
00008 //
00009 // All use of this software is subject to the terms of the revised BSD
00010 // license.  You should have received a copy of this license along
00011 // with this source code in a file named "LICENSE."
00012 //
00013 ////////////////////////////////////////////////////////////////////
00014 
00015 #include "streamWrapper.h"
00016 
00017 ////////////////////////////////////////////////////////////////////
00018 //     Function: IStreamWrapper::Destructor
00019 //       Access: Published
00020 //  Description: 
00021 ////////////////////////////////////////////////////////////////////
00022 IStreamWrapper::
00023 ~IStreamWrapper() {
00024   if (_owns_pointer) {
00025     // For some reason--compiler bug in gcc 3.2?--explicitly deleting
00026     // the stream pointer does not call the appropriate global delete
00027     // function; instead apparently calling the system delete
00028     // function.  So we call the delete function by hand instead.
00029 #if !defined(WIN32_VC) && !defined(USE_MEMORY_NOWRAPPERS) && defined(REDEFINE_GLOBAL_OPERATOR_NEW)
00030     _istream->~istream();
00031     (*global_operator_delete)(_istream);
00032 #else
00033     delete _istream;
00034 #endif
00035   }
00036 }
00037 
00038 ////////////////////////////////////////////////////////////////////
00039 //     Function: IStreamWrapper::read
00040 //       Access: Public
00041 //  Description: Atomically reads a number of bytes from the stream,
00042 //               without error detection.  If fewer bytes than
00043 //               requested are read, quietly fills the remaining bytes
00044 //               with 0.
00045 ////////////////////////////////////////////////////////////////////
00046 void IStreamWrapper::
00047 read(char *buffer, streamsize num_bytes) {
00048   acquire();
00049   _istream->clear();
00050   _istream->read(buffer, num_bytes);
00051   streamsize read_bytes = _istream->gcount();
00052   while (read_bytes < num_bytes) {
00053     // Fewer bytes than expected were read.  Maybe more will be
00054     // coming later.
00055     release();
00056     thread_yield();
00057     acquire();
00058 
00059     _istream->read(buffer + read_bytes, num_bytes - read_bytes);
00060     streamsize this_read_bytes = _istream->gcount();
00061     assert(this_read_bytes <= num_bytes - read_bytes);
00062     read_bytes += this_read_bytes;
00063 
00064     if (this_read_bytes == 0) {
00065       // No, don't expect any more.
00066       memset(buffer + read_bytes, 0, num_bytes - read_bytes);
00067       break;
00068     }
00069   }
00070   assert(read_bytes <= num_bytes);
00071   release();
00072 }
00073 
00074 ////////////////////////////////////////////////////////////////////
00075 //     Function: IStreamWrapper::read
00076 //       Access: Public
00077 //  Description: Atomically reads a number of bytes from the stream.
00078 //               Returns the number of bytes actually read.
00079 ////////////////////////////////////////////////////////////////////
00080 void IStreamWrapper::
00081 read(char *buffer, streamsize num_bytes, streamsize &read_bytes) {
00082   acquire();
00083   _istream->clear();
00084   _istream->read(buffer, num_bytes);
00085   read_bytes = _istream->gcount();
00086   assert(read_bytes <= num_bytes);
00087   release();
00088 }
00089 
00090 ////////////////////////////////////////////////////////////////////
00091 //     Function: IStreamWrapper::read
00092 //       Access: Public
00093 //  Description: Atomically reads a number of bytes from the stream.
00094 //               Returns the number of bytes actually read, and
00095 //               whether an eof condition was detected by the
00096 //               operation.
00097 ////////////////////////////////////////////////////////////////////
00098 void IStreamWrapper::
00099 read(char *buffer, streamsize num_bytes, streamsize &read_bytes, bool &eof) {
00100   acquire();
00101   _istream->clear();
00102   _istream->read(buffer, num_bytes);
00103   read_bytes = _istream->gcount();
00104   assert(read_bytes <= num_bytes);
00105   eof = _istream->eof() || _istream->fail();
00106   release();
00107 }
00108 
00109 ////////////////////////////////////////////////////////////////////
00110 //     Function: IStreamWrapper::seek_read
00111 //       Access: Public
00112 //  Description: Atomically seeks to a particular offset from the
00113 //               beginning of the file, and reads a number of bytes
00114 //               from the stream.  Returns the number of bytes
00115 //               actually read, and whether an eof condition was
00116 //               detected by the operation.
00117 ////////////////////////////////////////////////////////////////////
00118 void IStreamWrapper::
00119 seek_read(streamsize pos, char *buffer, streamsize num_bytes, 
00120           streamsize &read_bytes, bool &eof) {
00121   acquire();
00122   _istream->clear();
00123   _istream->seekg(pos);
00124   _istream->read(buffer, num_bytes);
00125   read_bytes = _istream->gcount();
00126   assert(read_bytes <= num_bytes);
00127   eof = _istream->eof() || _istream->fail();
00128   release();
00129 }
00130 
00131 ////////////////////////////////////////////////////////////////////
00132 //     Function: IStreamWrapper::seek_gpos_eof
00133 //       Access: Public
00134 //  Description: Atomically seeks to EOF and returns the gpos there;
00135 //               that is, returns the file size.  Note that the EOF
00136 //               might have been moved in another thread by the time
00137 //               this method returns.
00138 ////////////////////////////////////////////////////////////////////
00139 streamsize IStreamWrapper::
00140 seek_gpos_eof() {
00141   streamsize pos;
00142   acquire();
00143   _istream->seekg(0, ios::end);
00144   pos = _istream->tellg();
00145   release();
00146 
00147   return pos;
00148 }
00149 
00150 ////////////////////////////////////////////////////////////////////
00151 //     Function: OStreamWrapper::Destructor
00152 //       Access: Published
00153 //  Description: 
00154 ////////////////////////////////////////////////////////////////////
00155 OStreamWrapper::
00156 ~OStreamWrapper() {
00157   if (_owns_pointer) {
00158     // For some reason--compiler bug in gcc 3.2?--explicitly deleting
00159     // the stream pointer does not call the appropriate global delete
00160     // function; instead apparently calling the system delete
00161     // function.  So we call the delete function by hand instead.
00162 #if !defined(WIN32_VC) && !defined(USE_MEMORY_NOWRAPPERS) && defined(REDEFINE_GLOBAL_OPERATOR_NEW)
00163     _ostream->~ostream();
00164     (*global_operator_delete)(_ostream);
00165 #else
00166     delete _ostream;
00167 #endif
00168   }
00169 }
00170 
00171 ////////////////////////////////////////////////////////////////////
00172 //     Function: OStreamWrapper::write
00173 //       Access: Public
00174 //  Description: Atomically writes a number of bytes to the stream,
00175 //               without error detection.
00176 ////////////////////////////////////////////////////////////////////
00177 void OStreamWrapper::
00178 write(const char *buffer, streamsize num_bytes) {
00179   acquire();
00180   _ostream->write(buffer, num_bytes);
00181   release();
00182 }
00183 
00184 ////////////////////////////////////////////////////////////////////
00185 //     Function: OStreamWrapper::read
00186 //       Access: Public
00187 //  Description: Atomically writes a number of bytes to the stream.
00188 //               Returns whether a failure condition was detected by
00189 //               the operation.
00190 ////////////////////////////////////////////////////////////////////
00191 void OStreamWrapper::
00192 write(const char *buffer, streamsize num_bytes, bool &fail) {
00193   acquire();
00194   _ostream->clear();
00195   _ostream->write(buffer, num_bytes);
00196   fail = _ostream->fail();
00197   release();
00198 }
00199 
00200 ////////////////////////////////////////////////////////////////////
00201 //     Function: OStreamWrapper::seek_write
00202 //       Access: Public
00203 //  Description: Atomically seeks to a particular offset from the
00204 //               beginning of the file, and writes a number of bytes
00205 //               to the stream.  Returns whether a failure condition
00206 //               was detected by the operation.
00207 ////////////////////////////////////////////////////////////////////
00208 void OStreamWrapper::
00209 seek_write(streamsize pos, const char *buffer, streamsize num_bytes, 
00210            bool &fail) {
00211   acquire();
00212   _ostream->clear();
00213   _ostream->seekp(pos);
00214 
00215 #ifdef WIN32_VC
00216   if (_ostream->fail() && _stringstream_hack && pos == 0) {
00217     // Ignore an unsuccessful attempt to seekp(0) if
00218     // _stringstream_hack is true.
00219     _ostream->clear();
00220   }
00221 #endif // WIN32_VC
00222 
00223   _ostream->write(buffer, num_bytes);
00224   fail = _ostream->fail();
00225   release();
00226 }
00227 
00228 ////////////////////////////////////////////////////////////////////
00229 //     Function: OStreamWrapper::seek_eof_write
00230 //       Access: Public
00231 //  Description: Atomically seeks to the end of the file, and writes a
00232 //               number of bytes to the stream.  Returns whether a
00233 //               failure condition was detected by the operation.
00234 ////////////////////////////////////////////////////////////////////
00235 void OStreamWrapper::
00236 seek_eof_write(const char *buffer, streamsize num_bytes, bool &fail) {
00237   acquire();
00238   _ostream->clear();
00239   _ostream->seekp(0, ios::end);
00240 
00241 #ifdef WIN32_VC
00242   if (_ostream->fail() && _stringstream_hack) {
00243     // Ignore an unsuccessful attempt to seekp(0) if
00244     // _stringstream_hack is true.
00245     _ostream->clear();
00246   }
00247 #endif // WIN32_VC
00248 
00249   _ostream->write(buffer, num_bytes);
00250   fail = _ostream->fail();
00251   release();
00252 }
00253 
00254 ////////////////////////////////////////////////////////////////////
00255 //     Function: OStreamWrapper::seek_ppos_eof
00256 //       Access: Public
00257 //  Description: Atomically seeks to EOF and returns the ppos there;
00258 //               that is, returns the file size.  Note that the EOF
00259 //               might have been moved in another thread by the time
00260 //               this method returns.
00261 ////////////////////////////////////////////////////////////////////
00262 streamsize OStreamWrapper::
00263 seek_ppos_eof() {
00264   streamsize pos;
00265   acquire();
00266   _ostream->seekp(0, ios::end);
00267 
00268 #ifdef WIN32_VC
00269   if (_ostream->fail() && _stringstream_hack) {
00270     // Ignore an unsuccessful attempt to seekp(0) if
00271     // _stringstream_hack is true.
00272     _ostream->clear();
00273     release();
00274     return 0;
00275   }
00276 #endif // WIN32_VC
00277 
00278   pos = _ostream->tellp();
00279   release();
00280 
00281   return pos;
00282 }
00283 
00284 ////////////////////////////////////////////////////////////////////
00285 //     Function: StreamWrapper::Destructor
00286 //       Access: Published
00287 //  Description: 
00288 ////////////////////////////////////////////////////////////////////
00289 StreamWrapper::
00290 ~StreamWrapper() {
00291   if (_owns_pointer) {
00292     // For some reason--compiler bug in gcc 3.2?--explicitly deleting
00293     // the stream pointer does not call the appropriate global delete
00294     // function; instead apparently calling the system delete
00295     // function.  So we call the delete function by hand instead.
00296 #if !defined(WIN32_VC) && !defined(USE_MEMORY_NOWRAPPERS) && defined(REDEFINE_GLOBAL_OPERATOR_NEW)
00297     _iostream->~iostream();
00298     (*global_operator_delete)(_iostream);
00299 #else
00300     delete _iostream;
00301 #endif
00302   }
00303 }
 All Classes Functions Variables Enumerations