more substream fixes
This commit is contained in:
parent
31f1f8a99d
commit
07ca085727
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Reference in New Issue