open_toontown_panda3d/dtool/src/prc/streamWrapper.cxx

304 lines
10 KiB
C++

// Filename: streamWrapper.cxx
// Created by: drose (11Nov08)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) Carnegie Mellon University. All rights reserved.
//
// All use of this software is subject to the terms of the revised BSD
// license. You should have received a copy of this license along
// with this source code in a file named "LICENSE."
//
////////////////////////////////////////////////////////////////////
#include "streamWrapper.h"
////////////////////////////////////////////////////////////////////
// Function: IStreamWrapper::Destructor
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
IStreamWrapper::
~IStreamWrapper() {
if (_owns_pointer) {
// For some reason--compiler bug in gcc 3.2?--explicitly deleting
// the stream pointer does not call the appropriate global delete
// function; instead apparently calling the system delete
// function. So we call the delete function by hand instead.
#if !defined(WIN32_VC) && !defined(USE_MEMORY_NOWRAPPERS) && defined(REDEFINE_GLOBAL_OPERATOR_NEW)
_istream->~istream();
(*global_operator_delete)(_istream);
#else
delete _istream;
#endif
}
}
////////////////////////////////////////////////////////////////////
// Function: IStreamWrapper::read
// Access: Public
// Description: Atomically reads a number of bytes from the stream,
// without error detection. If fewer bytes than
// requested are read, quietly fills the remaining bytes
// with 0.
////////////////////////////////////////////////////////////////////
void IStreamWrapper::
read(char *buffer, streamsize num_bytes) {
acquire();
_istream->clear();
_istream->read(buffer, num_bytes);
streamsize read_bytes = _istream->gcount();
while (read_bytes < num_bytes) {
// Fewer bytes than expected were read. Maybe more will be
// coming later.
release();
thread_yield();
acquire();
_istream->read(buffer + read_bytes, num_bytes - read_bytes);
streamsize this_read_bytes = _istream->gcount();
assert(this_read_bytes <= num_bytes - read_bytes);
read_bytes += this_read_bytes;
if (this_read_bytes == 0) {
// No, don't expect any more.
memset(buffer + read_bytes, 0, num_bytes - read_bytes);
break;
}
}
assert(read_bytes <= num_bytes);
release();
}
////////////////////////////////////////////////////////////////////
// Function: IStreamWrapper::read
// Access: Public
// Description: Atomically reads a number of bytes from the stream.
// Returns the number of bytes actually read.
////////////////////////////////////////////////////////////////////
void IStreamWrapper::
read(char *buffer, streamsize num_bytes, streamsize &read_bytes) {
acquire();
_istream->clear();
_istream->read(buffer, num_bytes);
read_bytes = _istream->gcount();
assert(read_bytes <= num_bytes);
release();
}
////////////////////////////////////////////////////////////////////
// Function: IStreamWrapper::read
// Access: Public
// Description: Atomically reads a number of bytes from the stream.
// Returns the number of bytes actually read, and
// whether an eof condition was detected by the
// operation.
////////////////////////////////////////////////////////////////////
void IStreamWrapper::
read(char *buffer, streamsize num_bytes, streamsize &read_bytes, bool &eof) {
acquire();
_istream->clear();
_istream->read(buffer, num_bytes);
read_bytes = _istream->gcount();
assert(read_bytes <= num_bytes);
eof = _istream->eof() || _istream->fail();
release();
}
////////////////////////////////////////////////////////////////////
// Function: IStreamWrapper::seek_read
// Access: Public
// Description: Atomically seeks to a particular offset from the
// beginning of the file, and reads a number of bytes
// from the stream. Returns the number of bytes
// actually read, and whether an eof condition was
// detected by the operation.
////////////////////////////////////////////////////////////////////
void IStreamWrapper::
seek_read(streamsize pos, char *buffer, streamsize num_bytes,
streamsize &read_bytes, bool &eof) {
acquire();
_istream->clear();
_istream->seekg(pos);
_istream->read(buffer, num_bytes);
read_bytes = _istream->gcount();
assert(read_bytes <= num_bytes);
eof = _istream->eof() || _istream->fail();
release();
}
////////////////////////////////////////////////////////////////////
// Function: IStreamWrapper::seek_gpos_eof
// Access: Public
// Description: Atomically seeks to EOF and returns the gpos there;
// that is, returns the file size. Note that the EOF
// might have been moved in another thread by the time
// this method returns.
////////////////////////////////////////////////////////////////////
streamsize IStreamWrapper::
seek_gpos_eof() {
streamsize pos;
acquire();
_istream->seekg(0, ios::end);
pos = _istream->tellg();
release();
return pos;
}
////////////////////////////////////////////////////////////////////
// Function: OStreamWrapper::Destructor
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
OStreamWrapper::
~OStreamWrapper() {
if (_owns_pointer) {
// For some reason--compiler bug in gcc 3.2?--explicitly deleting
// the stream pointer does not call the appropriate global delete
// function; instead apparently calling the system delete
// function. So we call the delete function by hand instead.
#if !defined(WIN32_VC) && !defined(USE_MEMORY_NOWRAPPERS) && defined(REDEFINE_GLOBAL_OPERATOR_NEW)
_ostream->~ostream();
(*global_operator_delete)(_ostream);
#else
delete _ostream;
#endif
}
}
////////////////////////////////////////////////////////////////////
// Function: OStreamWrapper::write
// Access: Public
// Description: Atomically writes a number of bytes to the stream,
// without error detection.
////////////////////////////////////////////////////////////////////
void OStreamWrapper::
write(const char *buffer, streamsize num_bytes) {
acquire();
_ostream->write(buffer, num_bytes);
release();
}
////////////////////////////////////////////////////////////////////
// Function: OStreamWrapper::read
// Access: Public
// Description: Atomically writes a number of bytes to the stream.
// Returns whether a failure condition was detected by
// the operation.
////////////////////////////////////////////////////////////////////
void OStreamWrapper::
write(const char *buffer, streamsize num_bytes, bool &fail) {
acquire();
_ostream->clear();
_ostream->write(buffer, num_bytes);
fail = _ostream->fail();
release();
}
////////////////////////////////////////////////////////////////////
// Function: OStreamWrapper::seek_write
// Access: Public
// Description: Atomically seeks to a particular offset from the
// beginning of the file, and writes a number of bytes
// to the stream. Returns whether a failure condition
// was detected by the operation.
////////////////////////////////////////////////////////////////////
void OStreamWrapper::
seek_write(streamsize pos, const char *buffer, streamsize num_bytes,
bool &fail) {
acquire();
_ostream->clear();
_ostream->seekp(pos);
#ifdef WIN32_VC
if (_ostream->fail() && _stringstream_hack && pos == 0) {
// Ignore an unsuccessful attempt to seekp(0) if
// _stringstream_hack is true.
_ostream->clear();
}
#endif // WIN32_VC
_ostream->write(buffer, num_bytes);
fail = _ostream->fail();
release();
}
////////////////////////////////////////////////////////////////////
// Function: OStreamWrapper::seek_eof_write
// Access: Public
// Description: Atomically seeks to the end of the file, and writes a
// number of bytes to the stream. Returns whether a
// failure condition was detected by the operation.
////////////////////////////////////////////////////////////////////
void OStreamWrapper::
seek_eof_write(const char *buffer, streamsize num_bytes, bool &fail) {
acquire();
_ostream->clear();
_ostream->seekp(0, ios::end);
#ifdef WIN32_VC
if (_ostream->fail() && _stringstream_hack) {
// Ignore an unsuccessful attempt to seekp(0) if
// _stringstream_hack is true.
_ostream->clear();
}
#endif // WIN32_VC
_ostream->write(buffer, num_bytes);
fail = _ostream->fail();
release();
}
////////////////////////////////////////////////////////////////////
// Function: OStreamWrapper::seek_ppos_eof
// Access: Public
// Description: Atomically seeks to EOF and returns the ppos there;
// that is, returns the file size. Note that the EOF
// might have been moved in another thread by the time
// this method returns.
////////////////////////////////////////////////////////////////////
streamsize OStreamWrapper::
seek_ppos_eof() {
streamsize pos;
acquire();
_ostream->seekp(0, ios::end);
#ifdef WIN32_VC
if (_ostream->fail() && _stringstream_hack) {
// Ignore an unsuccessful attempt to seekp(0) if
// _stringstream_hack is true.
_ostream->clear();
release();
return 0;
}
#endif // WIN32_VC
pos = _ostream->tellp();
release();
return pos;
}
////////////////////////////////////////////////////////////////////
// Function: StreamWrapper::Destructor
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
StreamWrapper::
~StreamWrapper() {
if (_owns_pointer) {
// For some reason--compiler bug in gcc 3.2?--explicitly deleting
// the stream pointer does not call the appropriate global delete
// function; instead apparently calling the system delete
// function. So we call the delete function by hand instead.
#if !defined(WIN32_VC) && !defined(USE_MEMORY_NOWRAPPERS) && defined(REDEFINE_GLOBAL_OPERATOR_NEW)
_iostream->~iostream();
(*global_operator_delete)(_iostream);
#else
delete _iostream;
#endif
}
}