expand StreamReader a bit for Python

This commit is contained in:
David Rose 2002-08-07 17:06:59 +00:00
parent 9701bfcd43
commit 93b4c7e8ba
13 changed files with 193 additions and 130 deletions

View File

@ -172,6 +172,13 @@ step() {
_subfile_length = _multifile.get_subfile_length(_subfile_index);
_subfile_pos = 0;
_read = _multifile.open_read_subfile(_subfile_index);
if (_read == (istream *)NULL) {
downloader_cat.error()
<< "Unable to read subfile "
<< _multifile.get_subfile_name(_subfile_index) << ".\n";
cleanup();
return EU_error_abort;
}
} else if (_subfile_pos >= _subfile_length) {
// Time to close this subfile.

View File

@ -715,6 +715,68 @@ get_subfile_compressed_length(int index) const {
return _subfiles[index]->_data_length;
}
////////////////////////////////////////////////////////////////////
// Function: Multifile::open_read_subfile
// Access: Published
// Description: Returns an istream that may be used to read the
// indicated subfile. You may seek() within this
// istream to your heart's content; even though it will
// be a reference to the already-opened fstream of the
// Multifile itself, byte 0 appears to be the beginning
// of the subfile and EOF appears to be the end of the
// subfile.
//
// The returned istream will have been allocated via
// new; you should delete it when you are finished
// reading the subfile.
//
// Any future calls to repack() or close() (or the
// Multifile destructor) will invalidate all currently
// open subfile pointers.
//
// The return value will be NULL if the stream cannot be
// opened for some reason.
////////////////////////////////////////////////////////////////////
istream *Multifile::
open_read_subfile(int index) {
nassertr(is_read_valid(), NULL);
nassertr(index >= 0 && index < (int)_subfiles.size(), NULL);
Subfile *subfile = _subfiles[index];
if (subfile->_source != (istream *)NULL ||
!subfile->_source_filename.empty()) {
// The subfile has not yet been copied into the physical
// Multifile. Force a flush operation to incorporate it.
flush();
// That shouldn't change the subfile index or delete the subfile
// pointer.
nassertr(subfile == _subfiles[index], NULL);
}
// Return an ISubStream object that references into the open
// Multifile istream.
nassertr(subfile->_data_start != (streampos)0, NULL);
istream *stream =
new ISubStream(_read, subfile->_data_start,
subfile->_data_start + (streampos)subfile->_data_length);
if ((subfile->_flags & SF_compressed) != 0) {
// Oops, the subfile is compressed. So actually, return an
// IDecompressStream that wraps around the ISubStream.
IDecompressStream *wrapper = new IDecompressStream(stream, true);
stream = wrapper;
}
if (stream->fail()) {
// Hmm, some inexplicable problem.
delete stream;
return NULL;
}
return stream;
}
////////////////////////////////////////////////////////////////////
// Function: Multifile::extract_subfile
// Access: Published
@ -777,6 +839,10 @@ read_subfile(int index, string &result) {
result = string();
istream *in = open_read_subfile(index);
if (in == (istream *)NULL) {
return false;
}
int byte = in->get();
while (!in->eof() && !in->fail()) {
result += (char)byte;
@ -884,6 +950,9 @@ extract_subfile_to(int index, ostream &out) {
nassertr(index >= 0 && index < (int)_subfiles.size(), false);
istream *in = open_read_subfile(index);
if (in == (istream *)NULL) {
return false;
}
int byte = in->get();
while (!in->fail() && !in->eof()) {
@ -898,62 +967,6 @@ extract_subfile_to(int index, ostream &out) {
return (!out.fail());
}
////////////////////////////////////////////////////////////////////
// Function: Multifile::open_read_subfile
// Access: Public
// Description: Returns an istream that may be used to read the
// indicated subfile. You may seek() within this
// istream to your heart's content; even though it will
// be a reference to the already-opened fstream of the
// Multifile itself, byte 0 appears to be the beginning
// of the subfile and EOF appears to be the end of the
// subfile.
//
// The returned istream will have been allocated via
// new; you should delete it when you are finished
// reading the subfile.
//
// Any future calls to repack() or close() (or the
// Multifile destructor) will invalidate all currently
// open subfile pointers.
//
// The return value will never be NULL. If there is a
// problem, an unopened fstream is returned.
////////////////////////////////////////////////////////////////////
istream *Multifile::
open_read_subfile(int index) {
nassertr(is_read_valid(), new fstream);
nassertr(index >= 0 && index < (int)_subfiles.size(), new fstream);
Subfile *subfile = _subfiles[index];
if (subfile->_source != (istream *)NULL ||
!subfile->_source_filename.empty()) {
// The subfile has not yet been copied into the physical
// Multifile. Force a flush operation to incorporate it.
flush();
// That shouldn't change the subfile index or delete the subfile
// pointer.
nassertr(subfile == _subfiles[index], new fstream);
}
// Return an ISubStream object that references into the open
// Multifile istream.
nassertr(subfile->_data_start != (streampos)0, new fstream);
istream *stream =
new ISubStream(_read, subfile->_data_start,
subfile->_data_start + (streampos)subfile->_data_length);
if ((subfile->_flags & SF_compressed) != 0) {
// Oops, the subfile is compressed. So actually, return an
// IDecompressStream that wraps around the ISubStream.
IDecompressStream *wrapper = new IDecompressStream(stream, true);
stream = wrapper;
}
return stream;
}
////////////////////////////////////////////////////////////////////
// Function: Multifile::pad_to_streampos
// Access: Private
@ -1076,7 +1089,7 @@ read_index() {
}
// Now get the version numbers out.
StreamReader reader(_read);
StreamReader reader(_read, false);
_file_major_ver = reader.get_int16();
_file_minor_ver = reader.get_int16();
_scale_factor = reader.get_uint32();

View File

@ -72,6 +72,7 @@ PUBLISHED:
size_t get_subfile_compressed_length(int index) const;
INLINE string read_subfile(int index);
istream *open_read_subfile(int index);
bool extract_subfile(int index, const Filename &filename);
void output(ostream &out) const;
@ -88,7 +89,6 @@ public:
int compression_level);
bool extract_subfile_to(int index, ostream &out);
istream *open_read_subfile(int index);
private:
enum SubfileFlags {

View File

@ -24,54 +24,64 @@
////////////////////////////////////////////////////////////////////
INLINE StreamReader::
StreamReader(istream &in) :
_in(&in)
_in(&in),
_owns_stream(false)
{
}
////////////////////////////////////////////////////////////////////
// Function: StreamReader::Constructor
// Access: Public
// Description:
// Access: Published
// Description: If owns_stream is true, the stream pointer will be
// deleted when the StreamReader destructs.
////////////////////////////////////////////////////////////////////
INLINE StreamReader::
StreamReader(istream *in) :
_in(in)
StreamReader(istream *in, bool owns_stream) :
_in(in),
_owns_stream(owns_stream)
{
}
////////////////////////////////////////////////////////////////////
// Function: StreamReader::Copy Constructor
// Access: Public
// Description:
// Access: Published
// Description: The copy constructor does not copy ownership of the
// stream.
////////////////////////////////////////////////////////////////////
INLINE StreamReader::
StreamReader(const StreamReader &copy) :
_in(copy._in)
_in(copy._in),
_owns_stream(false)
{
}
////////////////////////////////////////////////////////////////////
// Function: StreamReader::Copy Assignment Operator
// Access: Public
// Description:
// Access: Published
// Description: The copy constructor does not copy ownership of the
// stream.
////////////////////////////////////////////////////////////////////
INLINE void StreamReader::
operator = (const StreamReader &copy) {
_in = copy._in;
_owns_stream = false;
}
////////////////////////////////////////////////////////////////////
// Function: StreamReader::Destructor
// Access: Public
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
INLINE StreamReader::
~StreamReader() {
if (_owns_stream) {
delete _in;
}
}
////////////////////////////////////////////////////////////////////
// Function: StreamReader::get_istream
// Access: Public
// Access: Published
// Description: Returns the stream in use.
////////////////////////////////////////////////////////////////////
INLINE istream *StreamReader::
@ -81,7 +91,7 @@ get_istream() const {
////////////////////////////////////////////////////////////////////
// Function: StreamReader::get_bool
// Access: Public
// Access: Published
// Description: Extracts a boolean value.
////////////////////////////////////////////////////////////////////
INLINE bool StreamReader::
@ -91,7 +101,7 @@ get_bool() {
////////////////////////////////////////////////////////////////////
// Function: StreamReader::get_int8
// Access: Public
// Access: Published
// Description: Extracts a signed 8-bit integer.
////////////////////////////////////////////////////////////////////
INLINE PN_int8 StreamReader::
@ -101,7 +111,7 @@ get_int8() {
////////////////////////////////////////////////////////////////////
// Function: StreamReader::get_uint8
// Access: Public
// Access: Published
// Description: Extracts an unsigned 8-bit integer.
////////////////////////////////////////////////////////////////////
INLINE PN_uint8 StreamReader::
@ -111,7 +121,7 @@ get_uint8() {
////////////////////////////////////////////////////////////////////
// Function: StreamReader::get_int16
// Access: Public
// Access: Published
// Description: Extracts a signed 16-bit integer.
////////////////////////////////////////////////////////////////////
INLINE PN_int16 StreamReader::
@ -125,7 +135,7 @@ get_int16() {
////////////////////////////////////////////////////////////////////
// Function: StreamReader::get_int32
// Access: Public
// Access: Published
// Description: Extracts a signed 32-bit integer.
////////////////////////////////////////////////////////////////////
INLINE PN_int32 StreamReader::
@ -139,7 +149,7 @@ get_int32() {
////////////////////////////////////////////////////////////////////
// Function: StreamReader::get_int64
// Access: Public
// Access: Published
// Description: Extracts a signed 64-bit integer.
////////////////////////////////////////////////////////////////////
INLINE PN_int64 StreamReader::
@ -153,7 +163,7 @@ get_int64() {
////////////////////////////////////////////////////////////////////
// Function: StreamReader::get_uint16
// Access: Public
// Access: Published
// Description: Extracts an unsigned 16-bit integer.
////////////////////////////////////////////////////////////////////
INLINE PN_uint16 StreamReader::
@ -167,7 +177,7 @@ get_uint16() {
////////////////////////////////////////////////////////////////////
// Function: StreamReader::get_uint32
// Access: Public
// Access: Published
// Description: Extracts an unsigned 32-bit integer.
////////////////////////////////////////////////////////////////////
INLINE PN_uint32 StreamReader::
@ -181,7 +191,7 @@ get_uint32() {
////////////////////////////////////////////////////////////////////
// Function: StreamReader::get_uint64
// Access: Public
// Access: Published
// Description: Extracts an unsigned 64-bit integer.
////////////////////////////////////////////////////////////////////
INLINE PN_uint64 StreamReader::
@ -195,7 +205,7 @@ get_uint64() {
////////////////////////////////////////////////////////////////////
// Function: StreamReader::get_float32
// Access: Public
// Access: Published
// Description: Extracts a 32-bit single-precision floating-point
// number. Since this kind of float is not necessarily
// portable across different architectures, special care
@ -217,7 +227,7 @@ get_float32() {
////////////////////////////////////////////////////////////////////
// Function: StreamReader::get_float64
// Access: Public
// Access: Published
// Description: Extracts a 64-bit floating-point number.
////////////////////////////////////////////////////////////////////
INLINE PN_float64 StreamReader::
@ -231,7 +241,7 @@ get_float64() {
////////////////////////////////////////////////////////////////////
// Function: StreamReader::get_be_int16
// Access: Public
// Access: Published
// Description: Extracts a signed big-endian 16-bit integer.
////////////////////////////////////////////////////////////////////
INLINE PN_int16 StreamReader::
@ -245,7 +255,7 @@ get_be_int16() {
////////////////////////////////////////////////////////////////////
// Function: StreamReader::get_be_int32
// Access: Public
// Access: Published
// Description: Extracts a signed big-endian 32-bit integer.
////////////////////////////////////////////////////////////////////
INLINE PN_int32 StreamReader::
@ -259,7 +269,7 @@ get_be_int32() {
////////////////////////////////////////////////////////////////////
// Function: StreamReader::get_be_int64
// Access: Public
// Access: Published
// Description: Extracts a signed big-endian 64-bit integer.
////////////////////////////////////////////////////////////////////
INLINE PN_int64 StreamReader::
@ -273,7 +283,7 @@ get_be_int64() {
////////////////////////////////////////////////////////////////////
// Function: StreamReader::get_be_uint16
// Access: Public
// Access: Published
// Description: Extracts an unsigned big-endian 16-bit integer.
////////////////////////////////////////////////////////////////////
INLINE PN_uint16 StreamReader::
@ -287,7 +297,7 @@ get_be_uint16() {
////////////////////////////////////////////////////////////////////
// Function: StreamReader::get_be_uint32
// Access: Public
// Access: Published
// Description: Extracts an unsigned big-endian 32-bit integer.
////////////////////////////////////////////////////////////////////
INLINE PN_uint32 StreamReader::
@ -301,7 +311,7 @@ get_be_uint32() {
////////////////////////////////////////////////////////////////////
// Function: StreamReader::get_be_uint64
// Access: Public
// Access: Published
// Description: Extracts an unsigned big-endian 64-bit integer.
////////////////////////////////////////////////////////////////////
INLINE PN_uint64 StreamReader::
@ -315,7 +325,7 @@ get_be_uint64() {
////////////////////////////////////////////////////////////////////
// Function: StreamReader::get_be_float32
// Access: Public
// Access: Published
// Description: Extracts a 32-bit single-precision big-endian
// floating-point number. Since this kind of float is
// not necessarily portable across different
@ -337,7 +347,7 @@ get_be_float32() {
////////////////////////////////////////////////////////////////////
// Function: StreamReader::get_be_float64
// Access: Public
// Access: Published
// Description: Extracts a 64-bit big-endian floating-point number.
////////////////////////////////////////////////////////////////////
INLINE PN_float64 StreamReader::

View File

@ -21,7 +21,7 @@
////////////////////////////////////////////////////////////////////
// Function: StreamReader::get_string
// Access: Public
// Access: Published
// Description: Extracts a variable-length string.
////////////////////////////////////////////////////////////////////
string StreamReader::
@ -41,7 +41,7 @@ get_string() {
////////////////////////////////////////////////////////////////////
// Function: StreamReader::get_z_string
// Access: Public
// Access: Published
// Description: Extracts a variable-length string, as a
// NULL-terminated string.
////////////////////////////////////////////////////////////////////
@ -60,7 +60,7 @@ get_z_string() {
////////////////////////////////////////////////////////////////////
// Function: StreamReader::get_fixed_string
// Access: Public
// Access: Published
// Description: Extracts a fixed-length string. However, if a zero
// byte occurs within the string, it marks the end of
// the string.
@ -81,7 +81,7 @@ get_fixed_string(size_t size) {
////////////////////////////////////////////////////////////////////
// Function: StreamReader::skip_bytes
// Access: Public
// Access: Published
// Description: Skips over the indicated number of bytes in the
// stream.
////////////////////////////////////////////////////////////////////
@ -98,7 +98,7 @@ skip_bytes(size_t size) {
////////////////////////////////////////////////////////////////////
// Function: StreamReader::extract_bytes
// Access: Public
// Access: Published
// Description: Extracts the indicated number of bytes in the
// stream and returns them as a string.
////////////////////////////////////////////////////////////////////
@ -115,3 +115,32 @@ extract_bytes(size_t size) {
return result;
}
////////////////////////////////////////////////////////////////////
// Function: StreamReader::readline
// Access: Published
// Description: Assumes the stream represents a text file, and
// extracts one line up to and including the trailing
// newline character. Returns empty string when the end
// of file is reached.
//
// The interface here is intentionally designed to be
// similar to that for Python's File.readline()
// function.
////////////////////////////////////////////////////////////////////
string StreamReader::
readline() {
string line;
int ch = _in->get();
while (!_in->eof() && !_in->fail()) {
line += ch;
if (ch == '\n') {
// Here's the newline character.
return line;
}
ch = _in->get();
}
return line;
}

View File

@ -34,7 +34,8 @@
class EXPCL_PANDAEXPRESS StreamReader {
public:
INLINE StreamReader(istream &in);
INLINE StreamReader(istream *in);
PUBLISHED:
INLINE StreamReader(istream *in, bool owns_stream);
INLINE StreamReader(const StreamReader &copy);
INLINE void operator = (const StreamReader &copy);
INLINE ~StreamReader();
@ -70,8 +71,11 @@ public:
void skip_bytes(size_t size);
string extract_bytes(size_t size);
string readline();
private:
istream *_in;
bool _owns_stream;
};
#include "streamReader.I"

View File

@ -149,6 +149,19 @@ ls_all(ostream &out) const {
}
}
////////////////////////////////////////////////////////////////////
// Function: VirtualFile::open_read_file
// Access: Published, Virtual
// Description: Opens the file for reading. Returns a newly
// allocated istream on success (which you should
// eventually delete when you are done reading).
// Returns NULL on failure.
////////////////////////////////////////////////////////////////////
istream *VirtualFile::
open_read_file() const {
return NULL;
}
////////////////////////////////////////////////////////////////////
// Function: VirtualFile::read_file
// Access: Public
@ -181,19 +194,6 @@ read_file(string &result) const {
return !failed;
}
////////////////////////////////////////////////////////////////////
// Function: VirtualFile::open_read_file
// Access: Public, Virtual
// Description: Opens the file for reading. Returns a newly
// allocated istream on success (which you should
// eventually delete when you are done reading).
// Returns NULL on failure.
////////////////////////////////////////////////////////////////////
istream *VirtualFile::
open_read_file() const {
return NULL;
}
////////////////////////////////////////////////////////////////////
// Function: VirtualFile::scan_local_directory
// Access: Protected, Virtual

View File

@ -53,10 +53,10 @@ PUBLISHED:
void ls_all(ostream &out = cout) const;
INLINE string read_file() const;
virtual istream *open_read_file() const;
public:
bool read_file(string &result) const;
virtual istream *open_read_file() const;
protected:

View File

@ -78,7 +78,7 @@ is_regular_file(const Filename &file) const {
// Description: Opens the file for reading, if it exists. Returns a
// newly allocated istream on success (which you should
// eventually delete when you are done reading).
// Returns NULL or an invalid istream on failure.
// Returns NULL on failure.
////////////////////////////////////////////////////////////////////
istream *VirtualFileMountMultifile::
open_read_file(const Filename &file) const {

View File

@ -63,7 +63,7 @@ is_regular_file(const Filename &file) const {
// Description: Opens the file for reading, if it exists. Returns a
// newly allocated istream on success (which you should
// eventually delete when you are done reading).
// Returns NULL or an invalid istream on failure.
// Returns NULL on failure.
////////////////////////////////////////////////////////////////////
istream *VirtualFileMountSystem::
open_read_file(const Filename &file) const {

View File

@ -105,22 +105,9 @@ read_file(const Filename &filename) const {
return result;
}
////////////////////////////////////////////////////////////////////
// Function: VirtualFileSystem::read_file
// Access: Public
// Description: Convenience function; fills the string up with the
// data from the indicated file, if it exists and can be
// read. Returns true on success, false otherwise.
////////////////////////////////////////////////////////////////////
INLINE bool VirtualFileSystem::
read_file(const Filename &filename, string &result) const {
PT(VirtualFile) file = get_file(filename);
return (file != (VirtualFile *)NULL && file->read_file(result));
}
////////////////////////////////////////////////////////////////////
// Function: VirtualFileSystem::open_read_file
// Access: Public
// Access: Published
// Description: Convenience function; returns a newly allocated
// istream if the file exists and can be read, or NULL
// otherwise. Does not return an invalid istream.
@ -138,3 +125,16 @@ open_read_file(const Filename &filename) const {
}
return str;
}
////////////////////////////////////////////////////////////////////
// Function: VirtualFileSystem::read_file
// Access: Public
// Description: Convenience function; fills the string up with the
// data from the indicated file, if it exists and can be
// read. Returns true on success, false otherwise.
////////////////////////////////////////////////////////////////////
INLINE bool VirtualFileSystem::
read_file(const Filename &filename, string &result) const {
PT(VirtualFile) file = get_file(filename);
return (file != (VirtualFile *)NULL && file->read_file(result));
}

View File

@ -81,10 +81,10 @@ PUBLISHED:
static VirtualFileSystem *get_global_ptr();
INLINE string read_file(const Filename &filename) const;
INLINE istream *open_read_file(const Filename &filename) const;
public:
INLINE bool read_file(const Filename &filename, string &result) const;
INLINE istream *open_read_file(const Filename &filename) const;
void scan_mount_points(vector_string &names, const Filename &path) const;

View File

@ -128,7 +128,7 @@ pm_freerow(char *itrow) {
int
pm_readbigshort(istream *in, short *sP) {
StreamReader reader(in);
StreamReader reader(in, false);
*sP = reader.get_be_int16();
return (!in->eof() && !in->fail()) ? 0 : -1;
}
@ -142,7 +142,7 @@ pm_writebigshort(ostream *out, short s) {
int
pm_readbiglong(istream *in, long *lP) {
StreamReader reader(in);
StreamReader reader(in, false);
*lP = reader.get_be_int32();
return (!in->eof() && !in->fail()) ? 0 : -1;
}
@ -156,7 +156,7 @@ pm_writebiglong(ostream *out, long l) {
int
pm_readlittleshort(istream *in, short *sP) {
StreamReader reader(in);
StreamReader reader(in, false);
*sP = reader.get_int16();
return (!in->eof() && !in->fail()) ? 0 : -1;
}
@ -170,7 +170,7 @@ pm_writelittleshort(ostream *out, short s) {
int
pm_readlittlelong(istream *in, long *lP) {
StreamReader reader(in);
StreamReader reader(in, false);
*lP = reader.get_int32();
return (!in->eof() && !in->fail()) ? 0 : -1;
}