stringstream_hack

This commit is contained in:
David Rose 2011-11-07 20:15:57 +00:00
parent ead8b03712
commit 370a9886b7
4 changed files with 47 additions and 8 deletions

View File

@ -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)
{ {

View File

@ -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();

View File

@ -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();

View File

@ -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)
{ {
} }