Panda3D

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   _ostream->write(buffer, num_bytes);
00215   fail = _ostream->fail();
00216   release();
00217 }
00218 
00219 ////////////////////////////////////////////////////////////////////
00220 //     Function: StreamWrapper::Destructor
00221 //       Access: Published
00222 //  Description: 
00223 ////////////////////////////////////////////////////////////////////
00224 StreamWrapper::
00225 ~StreamWrapper() {
00226   if (_owns_pointer) {
00227     // For some reason--compiler bug in gcc 3.2?--explicitly deleting
00228     // the stream pointer does not call the appropriate global delete
00229     // function; instead apparently calling the system delete
00230     // function.  So we call the delete function by hand instead.
00231 #if !defined(WIN32_VC) && !defined(USE_MEMORY_NOWRAPPERS) && defined(REDEFINE_GLOBAL_OPERATOR_NEW)
00232     _iostream->~iostream();
00233     (*global_operator_delete)(_iostream);
00234 #else
00235     delete _iostream;
00236 #endif
00237   }
00238 }
 All Classes Functions Variables Enumerations