add SubStream

This commit is contained in:
David Rose 2002-08-02 23:07:35 +00:00
parent eb431ed556
commit e202ad39ad
9 changed files with 428 additions and 27 deletions

View File

@ -35,7 +35,9 @@
profileTimer.I profileTimer.h \
pta_uchar.h referenceCount.I referenceCount.h \
register_type.I register_type.h \
reversedNumericData.I reversedNumericData.h tokenBoard.I \
reversedNumericData.I reversedNumericData.h \
subStream.I subStream.h subStreamBuf.h \
tokenBoard.I \
tokenBoard.h trueClock.I trueClock.h typeHandle.I \
typeHandle.h typedObject.I typedObject.h \
typedReferenceCount.I typedReferenceCount.h typedef.h \
@ -59,7 +61,9 @@
ordered_vector.cxx \
profileTimer.cxx \
pta_uchar.cxx referenceCount.cxx register_type.cxx \
reversedNumericData.cxx trueClock.cxx typeHandle.cxx \
reversedNumericData.cxx \
subStream.cxx subStreamBuf.cxx \
trueClock.cxx typeHandle.cxx \
typedObject.cxx typedReferenceCount.cxx \
typeRegistry.cxx typeRegistryNode.cxx vector_uchar.cxx
@ -85,7 +89,9 @@
pointerToArray.I pointerToArray.h profileTimer.I \
profileTimer.h pta_uchar.h referenceCount.I referenceCount.h \
register_type.I register_type.h \
reversedNumericData.I reversedNumericData.h tokenBoard.I \
reversedNumericData.I reversedNumericData.h \
subStream.I subStream.h subStreamBuf.h \
tokenBoard.I \
tokenBoard.h trueClock.I trueClock.h typeHandle.I typeHandle.h \
typedObject.I typedObject.h typedReferenceCount.I \
typedReferenceCount.h typedef.h \

View File

@ -8,6 +8,8 @@
#include "referenceCount.cxx"
#include "register_type.cxx"
#include "reversedNumericData.cxx"
#include "subStream.cxx"
#include "subStreamBuf.cxx"
#include "trueClock.cxx"
#include "typeHandle.cxx"
#include "typedObject.cxx"

View File

@ -532,10 +532,10 @@ read_subfile(int index, Datagram &data) {
data.clear();
istream &in = open_read_subfile(index);
size_t length = _subfiles[index]->_data_length;
for (size_t p = 0; p < length; p++) {
int byte = in.get();
int byte = in.get();
while (!in.eof() && !in.fail()) {
data.add_int8(byte);
byte = in.get();
}
bool failed = in.fail();
close_subfile();
@ -659,11 +659,13 @@ extract_subfile_to(int index, ostream &out) {
nassertr(index >= 0 && index < (int)_subfiles.size(), false);
istream &in = open_read_subfile(index);
size_t length = _subfiles[index]->_data_length;
for (size_t p = 0; p < length; p++) {
int byte = in.get();
int byte = in.get();
while (!in.fail() && !in.eof()) {
out.put(byte);
byte = in.get();
}
bool failed = in.fail();
close_subfile();
nassertr(!failed, false);
@ -675,16 +677,16 @@ extract_subfile_to(int index, ostream &out) {
// Function: Multifile::open_read_subfile
// Access: Public
// Description: Returns an istream that may be used to read the
// indicated subfile. The istream may or may not be a
// reference within the Multifile itself, so relative
// seeks are acceptable but global seeks will fail.
// Also, checking for eof() may fail; you must use
// get_subfile_length() instead.
// indicated subfile. You may seek() within this
// istream to your heart's content; even though it is
// probably 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.
//
// It is not valid to perform any other operations on
// this Multifile until the indicated subfile has been
// read to completion and close_subfile() has been
// called.
// It is not valid to perform any additional operations
// on this Multifile until close_subfile() has
// subsequently been called.
////////////////////////////////////////////////////////////////////
istream &Multifile::
open_read_subfile(int index) {
@ -695,17 +697,27 @@ open_read_subfile(int index) {
nassertr(index >= 0 && index < (int)_subfiles.size(), empty_stream);
#endif
_open_subfile = _subfiles[index];
if (_open_subfile->_source != (istream *)NULL) {
// The subfile has not yet been incorporated, and it is defined
// with an istream; return the istream directly.
_open_subfile->_source->seekg(0);
return *_open_subfile->_source;
}
if (!_open_subfile->_source_filename.empty()) {
_open_subfile->_source_filename.open_read(_subfile_read);
return _subfile_read;
// The subfile has not yet been incorporated, and it is defined
// with a filename; open the filename and return that.
_open_subfile->_source_filename.open_read(_subfile_fstream);
return _subfile_fstream;
}
// The subfile has been incorporated; return an ISubStream object
// that references into the open Multifile istream.
nassertr(_open_subfile->_data_start != (streampos)0, empty_stream);
_read->seekg(_open_subfile->_data_start);
return *_read;
_subfile_substream.open(_read, _open_subfile->_data_start,
_open_subfile->_data_start + _open_subfile->_data_length);
return _subfile_substream;
}
////////////////////////////////////////////////////////////////////
@ -717,8 +729,13 @@ open_read_subfile(int index) {
////////////////////////////////////////////////////////////////////
void Multifile::
close_subfile() {
if (_open_subfile != (Subfile *)NULL &&
_open_subfile->_source != (istream *)NULL) {
_open_subfile->_source->seekg(0);
}
_open_subfile = (Subfile *)NULL;
_subfile_read.close();
_subfile_fstream.close();
_subfile_substream.close();
}
////////////////////////////////////////////////////////////////////

View File

@ -23,7 +23,7 @@
#include "datagram.h"
#include "datagramIterator.h"
#include "subStream.h"
#include "filename.h"
#include "ordered_vector.h"
#include "indirectLess.h"
@ -138,10 +138,10 @@ private:
int _file_major_ver;
int _file_minor_ver;
// These are used to open a subfile for reading.
Subfile *_open_subfile;
// This is just to support open_read_subfile() for those subfiles
// that have recently been added but not flushed.
ifstream _subfile_read;
ifstream _subfile_fstream;
ISubStream _subfile_substream;
static const char _header[];
static const size_t _header_size;

View File

@ -0,0 +1,55 @@
// Filename: subStream.I
// Created by: drose (02Aug02)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://www.panda3d.org/license.txt .
//
// To contact the maintainers of this program write to
// panda3d@yahoogroups.com .
//
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Function: ISubStream::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE ISubStream::
ISubStream() : istream(&_buf) {
}
////////////////////////////////////////////////////////////////////
// Function: ISubStream::open
// Access: Public
// Description: Starts the SubStream reading from the indicated
// source, with the first character being the character
// at position "start" within the source, for end -
// start total characters. The character at "end"
// within the source will never be read; this will
// appear to be EOF.
////////////////////////////////////////////////////////////////////
INLINE void ISubStream::
open(istream *source, streampos start, streampos end) {
clear(0);
_buf.open(source, start, end);
}
////////////////////////////////////////////////////////////////////
// Function: ISubStream::close
// Access: Public
// Description: Resets the SubStream to empty, but does not actually
// close its source istream.
////////////////////////////////////////////////////////////////////
INLINE void ISubStream::
close() {
_buf.close();
}

View File

@ -0,0 +1,19 @@
// Filename: subStream.cxx
// Created by: drose (02Aug02)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://www.panda3d.org/license.txt .
//
// To contact the maintainers of this program write to
// panda3d@yahoogroups.com .
//
////////////////////////////////////////////////////////////////////
#include "subStream.h"

View File

@ -0,0 +1,48 @@
// Filename: subStream.h
// Created by: drose (02Aug02)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://www.panda3d.org/license.txt .
//
// To contact the maintainers of this program write to
// panda3d@yahoogroups.com .
//
////////////////////////////////////////////////////////////////////
#ifndef SUBSTREAM_H
#define SUBSTREAM_H
#include "pandabase.h"
#include "subStreamBuf.h"
////////////////////////////////////////////////////////////////////
// Class : ISubStream
// Description : An istream object that presents a subwindow into
// another istream. The first character read from this
// stream will be the "start" character from the source
// istream; just before the file pointer reaches the
// "end" character, eof is returned.
////////////////////////////////////////////////////////////////////
class EXPCL_PANDAEXPRESS ISubStream : public istream {
public:
INLINE ISubStream();
INLINE void open(istream *source, streampos start, streampos end);
INLINE void close();
private:
SubStreamBuf _buf;
};
#include "subStream.I"
#endif

View File

@ -0,0 +1,204 @@
// Filename: subStreamBuf.cxx
// Created by: drose (02Aug02)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://www.panda3d.org/license.txt .
//
// To contact the maintainers of this program write to
// panda3d@yahoogroups.com .
//
////////////////////////////////////////////////////////////////////
#include "subStreamBuf.h"
#ifndef HAVE_STREAMSIZE
// Some compilers (notably SGI) don't define this for us
typedef int streamsize;
#endif /* HAVE_STREAMSIZE */
////////////////////////////////////////////////////////////////////
// Function: SubStreamBuf::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
SubStreamBuf::
SubStreamBuf() {
_source = (istream *)NULL;
_start = 0;
_end = 0;
_cur = 0;
#ifndef WIN32_VC
// These lines, which are essential on Irix and Linux, seem to be
// unnecessary and not understood on Windows.
allocate();
setg(base(), ebuf(), ebuf());
#endif /* WIN32_VC */
}
////////////////////////////////////////////////////////////////////
// Function: SubStreamBuf::Destructor
// Access: Public, Virtual
// Description:
////////////////////////////////////////////////////////////////////
SubStreamBuf::
~SubStreamBuf() {
}
////////////////////////////////////////////////////////////////////
// Function: SubStreamBuf::open
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
void SubStreamBuf::
open(istream *source, streampos start, streampos end) {
_source = source;
_start = start;
_end = end;
_cur = _start;
}
////////////////////////////////////////////////////////////////////
// Function: SubStreamBuf::close
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
void SubStreamBuf::
close() {
sync();
_source = (istream *)NULL;
_start = 0;
_end = 0;
_cur = 0;
}
////////////////////////////////////////////////////////////////////
// Function: SubStreamBuf::seekoff
// Access: Public, Virtual
// Description: Implements seeking within the stream.
////////////////////////////////////////////////////////////////////
streampos SubStreamBuf::
seekoff(streamoff off, ios::seek_dir dir, int mode) {
switch (dir) {
case ios::beg:
_cur = _start + off;
break;
case ios::cur:
_cur += off;
break;
case ios::end:
_cur = _end + off;
break;
}
_cur = max(_start, _cur);
return _cur - _start;
}
////////////////////////////////////////////////////////////////////
// Function: SubStreamBuf::overflow
// Access: Protected, Virtual
// Description: Called by the system ostream implementation when its
// internal buffer is filled, plus one character.
////////////////////////////////////////////////////////////////////
int SubStreamBuf::
SubStreamBuf::overflow(int c) {
// We don't support ostream.
/*
streamsize n = pptr() - pbase();
if (n != 0) {
write_chars(pbase(), n, false);
pbump(-n); // reset pptr()
}
if (c != EOF) {
// write one more character
char ch = c;
write_chars(&ch, 1, false);
}
*/
return 0;
}
////////////////////////////////////////////////////////////////////
// Function: SubStreamBuf::sync
// Access: Protected, Virtual
// Description: Called by the system iostream implementation to
// implement a flush operation.
////////////////////////////////////////////////////////////////////
int SubStreamBuf::
sync() {
/*
streamsize n = pptr() - pbase();
if (n != 0) {
write_chars(pbase(), n, false);
pbump(-n);
}
*/
streamsize n = egptr() - gptr();
if (n != 0) {
gbump(n);
_cur += n;
}
return 0;
}
////////////////////////////////////////////////////////////////////
// Function: SubStreamBuf::underflow
// Access: Protected, Virtual
// Description: Called by the system istream implementation when its
// internal buffer needs more characters.
////////////////////////////////////////////////////////////////////
int SubStreamBuf::
underflow() {
if ((eback() == (char *)NULL) || (gptr() == (char *)NULL) ||
(egptr() == (char *)NULL)) {
// No buffer; allocate a new one. Rumor has it this is only
// possible in Win32.
char *buf = new char[4096];
char *ebuf = buf + 4096;
setg(buf, ebuf, ebuf);
}
// Sometimes underflow() is called even if the buffer is not empty.
if (gptr() >= egptr()) {
if (_cur >= _end) {
// We're done.
return EOF;
}
size_t buffer_size = egptr() - eback();
size_t num_bytes;
if (_end - _cur > buffer_size) {
// We have enough bytes in the input stream to fill our buffer.
num_bytes = buffer_size;
} else {
// We won't quite fill the buffer.
num_bytes = (size_t)(_end - _cur);
}
_source->seekg(_cur);
gbump(-(int)num_bytes);
nassertr(gptr() + num_bytes <= egptr(), EOF);
_source->read(gptr(), num_bytes);
if (_source->gcount() != num_bytes) {
// Oops, something screwed up.
_cur = _end;
return EOF;
}
_cur += num_bytes;
}
return *gptr();
}

View File

@ -0,0 +1,50 @@
// Filename: subStreamBuf.h
// Created by: drose (02Aug02)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://www.panda3d.org/license.txt .
//
// To contact the maintainers of this program write to
// panda3d@yahoogroups.com .
//
////////////////////////////////////////////////////////////////////
#ifndef SUBSTREAMBUF_H
#define SUBSTREAMBUF_H
#include "pandabase.h"
////////////////////////////////////////////////////////////////////
// Class : SubStreamBuf
// Description : The streambuf object that implements ISubStream.
////////////////////////////////////////////////////////////////////
class EXPCL_PANDAEXPRESS SubStreamBuf : public streambuf {
public:
SubStreamBuf();
virtual ~SubStreamBuf();
void open(istream *source, streampos start, streampos end);
void close();
virtual streampos seekoff(streamoff off, ios::seek_dir dir, int mode);
protected:
virtual int overflow(int c);
virtual int sync(void);
virtual int underflow(void);
private:
istream *_source;
streampos _start;
streampos _end;
streampos _cur;
};
#endif