diff --git a/dtool/src/prc/streamWrapper.I b/dtool/src/prc/streamWrapper.I index d1e4e5a8fc..d97eb575af 100644 --- a/dtool/src/prc/streamWrapper.I +++ b/dtool/src/prc/streamWrapper.I @@ -125,9 +125,10 @@ get() { // Description: //////////////////////////////////////////////////////////////////// INLINE OStreamWrapper:: -OStreamWrapper(ostream *stream, bool owns_pointer) : +OStreamWrapper(ostream *stream, bool owns_pointer, bool stringstream_hack) : _ostream(stream), - _owns_pointer(owns_pointer) + _owns_pointer(owns_pointer), + _stringstream_hack(stringstream_hack) { } @@ -139,7 +140,8 @@ OStreamWrapper(ostream *stream, bool owns_pointer) : INLINE OStreamWrapper:: OStreamWrapper(ostream &stream) : _ostream(&stream), - _owns_pointer(false) + _owns_pointer(false), + _stringstream_hack(false) { } @@ -175,9 +177,9 @@ put(char c) { // Description: //////////////////////////////////////////////////////////////////// INLINE StreamWrapper:: -StreamWrapper(iostream *stream, bool owns_pointer) : +StreamWrapper(iostream *stream, bool owns_pointer, bool stringstream_hack) : IStreamWrapper(stream, false), - OStreamWrapper(stream, false), + OStreamWrapper(stream, false, stringstream_hack), _iostream(stream), _owns_pointer(owns_pointer) { diff --git a/dtool/src/prc/streamWrapper.cxx b/dtool/src/prc/streamWrapper.cxx index ad298a8bba..16e568c459 100644 --- a/dtool/src/prc/streamWrapper.cxx +++ b/dtool/src/prc/streamWrapper.cxx @@ -211,6 +211,15 @@ seek_write(streamsize pos, const char *buffer, streamsize num_bytes, 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(); @@ -228,6 +237,15 @@ 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(); @@ -246,6 +264,17 @@ 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(); diff --git a/dtool/src/prc/streamWrapper.h b/dtool/src/prc/streamWrapper.h index c8ce024b1b..1b64fde3f6 100644 --- a/dtool/src/prc/streamWrapper.h +++ b/dtool/src/prc/streamWrapper.h @@ -80,7 +80,7 @@ private: //////////////////////////////////////////////////////////////////// class EXPCL_DTOOLCONFIG OStreamWrapper : virtual public StreamWrapperBase { public: - INLINE OStreamWrapper(ostream *stream, bool owns_pointer); + INLINE OStreamWrapper(ostream *stream, bool owns_pointer, bool stringstream_hack = false); PUBLISHED: INLINE OStreamWrapper(ostream &stream); ~OStreamWrapper(); @@ -98,6 +98,14 @@ public: private: ostream *_ostream; bool _owns_pointer; + + // This flag is necessary to work around a weird quirk in the MSVS + // C++ runtime library: an empty stringstream cannot successfully + // seekp(0), until some data has been written to the stream. When + // this flag is set true, we know we have a possibly-empty + // stringstream, so we allow seekp(0) to fail silently, knowing that + // there's no harm in this case. + bool _stringstream_hack; }; //////////////////////////////////////////////////////////////////// @@ -107,7 +115,7 @@ private: //////////////////////////////////////////////////////////////////// class EXPCL_DTOOLCONFIG StreamWrapper : public IStreamWrapper, public OStreamWrapper { public: - INLINE StreamWrapper(iostream *stream, bool owns_pointer); + INLINE StreamWrapper(iostream *stream, bool owns_pointer, bool stringstream_hack = false); PUBLISHED: INLINE StreamWrapper(iostream &stream); ~StreamWrapper(); diff --git a/panda/src/express/virtualFileMountRamdisk.I b/panda/src/express/virtualFileMountRamdisk.I index 3aba493399..863706fa0e 100644 --- a/panda/src/express/virtualFileMountRamdisk.I +++ b/panda/src/express/virtualFileMountRamdisk.I @@ -40,7 +40,7 @@ operator < (const FileBase &other) const { INLINE VirtualFileMountRamdisk::File:: File(const string &basename) : FileBase(basename), - _wrapper(_data) + _wrapper(&_data, false, true) { }