more substream fixes

This commit is contained in:
David Rose 2002-08-06 22:54:45 +00:00
parent 31f1f8a99d
commit 07ca085727
2 changed files with 56 additions and 7 deletions

View File

@ -23,6 +23,34 @@
typedef int streamsize;
#endif /* HAVE_STREAMSIZE */
// Temporary hack to make these thread-safe.
//#define SUBSTREAM_THREAD_SAFE
#ifdef SUBSTREAM_THREAD_SAFE
// This requires NSPR for now.
#include <prlock.h>
PRLock *substream_mutex = (PRLock *)NULL;
inline void init_lock() {
if (substream_mutex == (PRLock *)NULL) {
substream_mutex = PR_NewLock();
}
}
inline void grab_lock() {
PR_Lock(substream_mutex);
}
inline void release_lock() {
PR_Unlock(substream_mutex);
}
#else // SUBSTREAM_THREAD_SAFE
inline void init_lock() {
}
inline void grab_lock() {
}
inline void release_lock() {
}
#endif // SUBSTREAM_THREAD_SAFE
////////////////////////////////////////////////////////////////////
// Function: SubStreamBuf::Constructor
// Access: Public
@ -47,13 +75,14 @@ SubStreamBuf() {
_cur = 0;
// _unused counts the number of bytes at the beginning of the buffer
// that are unused. Usually this is 0, but when we reach the end of
// the file we might not need the whole buffer to read the last bit,
// so the first part of the buffer is unused. This is important to
// prevent us from inadvertently seeking into the unused part of the
// buffer.
// that are unused. Usually this is 0 after a read, but when we
// reach the end of the file we might not need the whole buffer to
// read the last bit, so the first part of the buffer is unused.
// This is important to prevent us from inadvertently seeking into
// the unused part of the buffer.
_unused = 0;
init_lock();
#ifdef WIN32_VC
// In spite of the claims of the MSDN Library to the contrary,
@ -90,7 +119,9 @@ open(istream *source, streampos start, streampos end) {
_start = start;
_end = end;
_cur = _start;
_unused = 0;
// Initially, the entire buffer is unused. Duh.
_unused = egptr() - eback();
}
////////////////////////////////////////////////////////////////////
@ -136,8 +167,10 @@ seekoff(streamoff off, ios::seek_dir dir, int mode) {
if (_end == (streampos)0) {
// If the end of the file is unspecified, we have to seek to
// find it.
grab_lock();
_source->seekg(off, ios::end);
new_pos = _source->tellg();
release_lock();
} else {
new_pos = _end + off;
@ -181,6 +214,16 @@ seekpos(streampos pos, int mode) {
return seekoff(pos, ios::beg, mode);
}
#ifdef WIN32_VC
// Windows seems to be a little confused about the proper definition
// of seekoff(). We have to define both variants in order to get
// reliable seeking.
streampos SubStreamBuf::
seekoff(streamoff off, ios::seekdir dir, ios::openmode mode) {
return seekoff(off, (ios::seek_dir)dir, (int)mode);
}
#endif
////////////////////////////////////////////////////////////////////
// Function: SubStreamBuf::overflow
// Access: Protected, Virtual
@ -232,12 +275,14 @@ underflow() {
num_bytes = (size_t)(_end - _cur);
}
_source->seekg(_cur);
gbump(-(int)num_bytes);
nassertr(gptr() + num_bytes <= egptr(), EOF);
grab_lock();
_source->seekg(_cur);
_source->read(gptr(), num_bytes);
size_t read_count = _source->gcount();
release_lock();
if (read_count != num_bytes) {
// Oops, we didn't read what we thought we would.

View File

@ -36,6 +36,10 @@ public:
virtual streampos seekoff(streamoff off, ios::seek_dir dir, int mode);
virtual streampos seekpos(streampos pos, int mode);
#ifdef WIN32_VC
virtual streampos seekoff(streamoff off, ios::seekdir dir, ios::openmode mode);
#endif
protected:
virtual int overflow(int c);
virtual int sync(void);