Browse Source

stringstream_hack

David Rose 14 years ago
parent
commit
370a9886b7

+ 7 - 5
dtool/src/prc/streamWrapper.I

@@ -125,9 +125,10 @@ get() {
 //  Description: 
 //  Description: 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 INLINE OStreamWrapper::
 INLINE OStreamWrapper::
-OStreamWrapper(ostream *stream, bool owns_pointer) :
+OStreamWrapper(ostream *stream, bool owns_pointer, bool stringstream_hack) :
   _ostream(stream),
   _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::
 INLINE OStreamWrapper::
 OStreamWrapper(ostream &stream) :
 OStreamWrapper(ostream &stream) :
   _ostream(&stream),
   _ostream(&stream),
-  _owns_pointer(false)
+  _owns_pointer(false),
+  _stringstream_hack(false)
 {
 {
 }
 }
 
 
@@ -175,9 +177,9 @@ put(char c) {
 //  Description: 
 //  Description: 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 INLINE StreamWrapper::
 INLINE StreamWrapper::
-StreamWrapper(iostream *stream, bool owns_pointer) :
+StreamWrapper(iostream *stream, bool owns_pointer, bool stringstream_hack) :
   IStreamWrapper(stream, false),
   IStreamWrapper(stream, false),
-  OStreamWrapper(stream, false),
+  OStreamWrapper(stream, false, stringstream_hack),
   _iostream(stream),
   _iostream(stream),
   _owns_pointer(owns_pointer)
   _owns_pointer(owns_pointer)
 {
 {

+ 29 - 0
dtool/src/prc/streamWrapper.cxx

@@ -211,6 +211,15 @@ seek_write(streamsize pos, const char *buffer, streamsize num_bytes,
   acquire();
   acquire();
   _ostream->clear();
   _ostream->clear();
   _ostream->seekp(pos);
   _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);
   _ostream->write(buffer, num_bytes);
   fail = _ostream->fail();
   fail = _ostream->fail();
   release();
   release();
@@ -228,6 +237,15 @@ seek_eof_write(const char *buffer, streamsize num_bytes, bool &fail) {
   acquire();
   acquire();
   _ostream->clear();
   _ostream->clear();
   _ostream->seekp(0, ios::end);
   _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);
   _ostream->write(buffer, num_bytes);
   fail = _ostream->fail();
   fail = _ostream->fail();
   release();
   release();
@@ -246,6 +264,17 @@ seek_ppos_eof() {
   streamsize pos;
   streamsize pos;
   acquire();
   acquire();
   _ostream->seekp(0, ios::end);
   _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();
   pos = _ostream->tellp();
   release();
   release();
 
 

+ 10 - 2
dtool/src/prc/streamWrapper.h

@@ -80,7 +80,7 @@ private:
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 class EXPCL_DTOOLCONFIG OStreamWrapper : virtual public StreamWrapperBase {
 class EXPCL_DTOOLCONFIG OStreamWrapper : virtual public StreamWrapperBase {
 public:
 public:
-  INLINE OStreamWrapper(ostream *stream, bool owns_pointer);
+  INLINE OStreamWrapper(ostream *stream, bool owns_pointer, bool stringstream_hack = false);
 PUBLISHED:
 PUBLISHED:
   INLINE OStreamWrapper(ostream &stream);
   INLINE OStreamWrapper(ostream &stream);
   ~OStreamWrapper();
   ~OStreamWrapper();
@@ -98,6 +98,14 @@ public:
 private:
 private:
   ostream *_ostream;
   ostream *_ostream;
   bool _owns_pointer;
   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 {
 class EXPCL_DTOOLCONFIG StreamWrapper : public IStreamWrapper, public OStreamWrapper {
 public:
 public:
-  INLINE StreamWrapper(iostream *stream, bool owns_pointer);
+  INLINE StreamWrapper(iostream *stream, bool owns_pointer, bool stringstream_hack = false);
 PUBLISHED:
 PUBLISHED:
   INLINE StreamWrapper(iostream &stream);
   INLINE StreamWrapper(iostream &stream);
   ~StreamWrapper();
   ~StreamWrapper();

+ 1 - 1
panda/src/express/virtualFileMountRamdisk.I

@@ -40,7 +40,7 @@ operator < (const FileBase &other) const {
 INLINE VirtualFileMountRamdisk::File::
 INLINE VirtualFileMountRamdisk::File::
 File(const string &basename) : 
 File(const string &basename) : 
   FileBase(basename),
   FileBase(basename),
-  _wrapper(_data)
+  _wrapper(&_data, false, true)
 {
 {
 }
 }