From 87a23944fb1b70d72048ca60bbf3d86b181aba3a Mon Sep 17 00:00:00 2001 From: David Rose Date: Fri, 6 Jul 2007 04:03:49 +0000 Subject: [PATCH] regularize StreamReader, StreamWriter, StringStream --- dtool/src/prc/encryptStreamBuf.cxx | 2 +- dtool/src/prc/streamReader.I | 3 ++ dtool/src/prc/streamReader.cxx | 45 ++++++++--------- dtool/src/prc/streamWriter.I | 24 ++++++--- dtool/src/prc/streamWriter.h | 3 +- panda/src/express/multifile.cxx | 6 +-- panda/src/pnmimage/pnmimage_base.cxx | 8 +-- panda/src/putil/datagramOutputFile.cxx | 2 +- panda/src/putil/stringStream.I | 70 ++++++++++++-------------- panda/src/putil/stringStream.cxx | 15 ------ panda/src/putil/stringStream.h | 9 ++-- panda/src/putil/stringStreamBuf.I | 25 ++++++--- panda/src/putil/stringStreamBuf.cxx | 7 ++- panda/src/putil/stringStreamBuf.h | 6 ++- 14 files changed, 116 insertions(+), 109 deletions(-) diff --git a/dtool/src/prc/encryptStreamBuf.cxx b/dtool/src/prc/encryptStreamBuf.cxx index 9ffac25ed1..8572c1e9a4 100644 --- a/dtool/src/prc/encryptStreamBuf.cxx +++ b/dtool/src/prc/encryptStreamBuf.cxx @@ -291,7 +291,7 @@ open_write(ostream *dest, bool owns_dest, const string &password) { nassertv(result > 0); // Now write the header information to the stream. - StreamWriter sw(_dest); + StreamWriter sw(_dest, false); nassertv((PN_uint16)nid == nid); sw.add_uint16(nid); nassertv((PN_uint16)key_length == key_length); diff --git a/dtool/src/prc/streamReader.I b/dtool/src/prc/streamReader.I index e495b2925b..117e1a1225 100644 --- a/dtool/src/prc/streamReader.I +++ b/dtool/src/prc/streamReader.I @@ -63,6 +63,9 @@ StreamReader(const StreamReader ©) : //////////////////////////////////////////////////////////////////// INLINE void StreamReader:: operator = (const StreamReader ©) { + if (_owns_stream) { + delete _in; + } _in = copy._in; _owns_stream = false; } diff --git a/dtool/src/prc/streamReader.cxx b/dtool/src/prc/streamReader.cxx index 3f81161adb..d999e88541 100644 --- a/dtool/src/prc/streamReader.cxx +++ b/dtool/src/prc/streamReader.cxx @@ -29,14 +29,12 @@ get_string() { nassertr(!_in->eof() && !_in->fail(), string()); // First, get the length of the string - size_t s_len = get_uint16(); + size_t size = get_uint16(); - string result; - result.reserve(s_len); - for (size_t p = 0; !_in->eof() && !_in->fail() && p < s_len; p++) { - result += _in->get(); - } - return result; + char *buffer = (char *)alloca(size); + _in->read(buffer, size); + size_t read_bytes = _in->gcount(); + return string(buffer, read_bytes); } //////////////////////////////////////////////////////////////////// @@ -50,13 +48,13 @@ get_string32() { nassertr(!_in->eof() && !_in->fail(), string()); // First, get the length of the string - size_t s_len = get_uint32(); + size_t size = get_uint32(); - string result; - result.reserve(s_len); - for (size_t p = 0; !_in->eof() && !_in->fail() && p < s_len; p++) { - result += _in->get(); - } + char *buffer = (char *)PANDA_MALLOC_ARRAY(size); + _in->read(buffer, size); + size_t read_bytes = _in->gcount(); + string result(buffer, read_bytes); + PANDA_FREE_ARRAY(buffer); return result; } @@ -74,6 +72,7 @@ get_z_string() { int ch = _in->get(); while (!_in->eof() && !_in->fail() && ch != '\0') { result += ch; + ch = _in->get(); } return result; @@ -90,11 +89,10 @@ string StreamReader:: get_fixed_string(size_t size) { nassertr(!_in->eof() && !_in->fail(), string()); - string result; - result.reserve(size); - for (size_t p = 0; !_in->eof() && !_in->fail() && p < size; p++) { - result += _in->get(); - } + char *buffer = (char *)alloca(size); + _in->read(buffer, size); + size_t read_bytes = _in->gcount(); + string result(buffer, read_bytes); size_t zero_byte = result.find('\0'); return result.substr(0, zero_byte); @@ -127,13 +125,10 @@ string StreamReader:: extract_bytes(size_t size) { nassertr(!_in->eof() && !_in->fail(), string()); - string result; - result.reserve(size); - for (size_t p = 0; !_in->eof() && !_in->fail() && p < size; p++) { - result += _in->get(); - } - - return result; + char *buffer = (char *)alloca(size); + _in->read(buffer, size); + size_t read_bytes = _in->gcount(); + return string(buffer, read_bytes); } diff --git a/dtool/src/prc/streamWriter.I b/dtool/src/prc/streamWriter.I index 2159491df0..72c72b72f9 100644 --- a/dtool/src/prc/streamWriter.I +++ b/dtool/src/prc/streamWriter.I @@ -24,7 +24,8 @@ //////////////////////////////////////////////////////////////////// INLINE StreamWriter:: StreamWriter(ostream &out) : - _out(&out) + _out(&out), + _owns_stream(false) { } @@ -34,30 +35,38 @@ StreamWriter(ostream &out) : // Description: //////////////////////////////////////////////////////////////////// INLINE StreamWriter:: -StreamWriter(ostream *out) : - _out(out) +StreamWriter(ostream *out, bool owns_stream) : + _out(out), + _owns_stream(owns_stream) { } //////////////////////////////////////////////////////////////////// // Function: StreamWriter::Copy Constructor // Access: Public -// Description: +// Description: The copy constructor does not copy ownership of the +// stream. //////////////////////////////////////////////////////////////////// INLINE StreamWriter:: StreamWriter(const StreamWriter ©) : - _out(copy._out) + _out(copy._out), + _owns_stream(false) { } //////////////////////////////////////////////////////////////////// // Function: StreamWriter::Copy Assignment Operator // Access: Public -// Description: +// Description: The copy constructor does not copy ownership of the +// stream. //////////////////////////////////////////////////////////////////// INLINE void StreamWriter:: operator = (const StreamWriter ©) { + if (_owns_stream) { + delete _out; + } _out = copy._out; + _owns_stream = false; } //////////////////////////////////////////////////////////////////// @@ -67,6 +76,9 @@ operator = (const StreamWriter ©) { //////////////////////////////////////////////////////////////////// INLINE StreamWriter:: ~StreamWriter() { + if (_owns_stream) { + delete _out; + } } //////////////////////////////////////////////////////////////////// diff --git a/dtool/src/prc/streamWriter.h b/dtool/src/prc/streamWriter.h index aa23489d37..dd21e3c156 100644 --- a/dtool/src/prc/streamWriter.h +++ b/dtool/src/prc/streamWriter.h @@ -38,7 +38,7 @@ class EXPCL_DTOOLCONFIG StreamWriter { public: INLINE StreamWriter(ostream &out); PUBLISHED: - INLINE StreamWriter(ostream *out); + INLINE StreamWriter(ostream *out, bool owns_stream); INLINE StreamWriter(const StreamWriter ©); INLINE void operator = (const StreamWriter ©); INLINE ~StreamWriter(); @@ -80,6 +80,7 @@ PUBLISHED: private: ostream *_out; + bool _owns_stream; }; #include "streamWriter.I" diff --git a/panda/src/express/multifile.cxx b/panda/src/express/multifile.cxx index cba52d413d..e9b0f2e6f3 100644 --- a/panda/src/express/multifile.cxx +++ b/panda/src/express/multifile.cxx @@ -595,7 +595,7 @@ flush() { // And update the forward link from the last_index to point to // this new index location. _write->seekp(_last_index); - StreamWriter writer(_write); + StreamWriter writer(_write, false); writer.add_uint32(streampos_to_word(_next_index)); } @@ -615,7 +615,7 @@ flush() { // Now we're at the end of the index. Write a 0 here to mark the // end. - StreamWriter writer(_write); + StreamWriter writer(_write, false); writer.add_uint32(0); _next_index += 4; nassertr(_next_index == _write->tellp(), false); @@ -1579,7 +1579,7 @@ write_header() { nassertr(_write != (ostream *)NULL, false); nassertr(_write->tellp() == (streampos)0, false); _write->write(_header, _header_size); - StreamWriter writer(_write); + StreamWriter writer(_write, false); writer.add_int16(_current_major_ver); writer.add_int16(_current_minor_ver); writer.add_uint32(_scale_factor); diff --git a/panda/src/pnmimage/pnmimage_base.cxx b/panda/src/pnmimage/pnmimage_base.cxx index 6db881c82f..624b3f9c8d 100644 --- a/panda/src/pnmimage/pnmimage_base.cxx +++ b/panda/src/pnmimage/pnmimage_base.cxx @@ -136,7 +136,7 @@ pm_readbigshort(istream *in, short *sP) { int pm_writebigshort(ostream *out, short s) { - StreamWriter writer(out); + StreamWriter writer(out, false); writer.add_be_int16(s); return (!out->fail()) ? 0 : -1; } @@ -150,7 +150,7 @@ pm_readbiglong(istream *in, long *lP) { int pm_writebiglong(ostream *out, long l) { - StreamWriter writer(out); + StreamWriter writer(out, false); writer.add_be_int32(l); return (!out->fail()) ? 0 : -1; } @@ -164,7 +164,7 @@ pm_readlittleshort(istream *in, short *sP) { int pm_writelittleshort(ostream *out, short s) { - StreamWriter writer(out); + StreamWriter writer(out, false); writer.add_int16(s); return (!out->fail()) ? 0 : -1; } @@ -178,7 +178,7 @@ pm_readlittlelong(istream *in, long *lP) { int pm_writelittlelong(ostream *out, long l) { - StreamWriter writer(out); + StreamWriter writer(out, false); writer.add_int32(l); return (!out->fail()) ? 0 : -1; } diff --git a/panda/src/putil/datagramOutputFile.cxx b/panda/src/putil/datagramOutputFile.cxx index cb2de8a65b..e01c5ee45b 100644 --- a/panda/src/putil/datagramOutputFile.cxx +++ b/panda/src/putil/datagramOutputFile.cxx @@ -117,7 +117,7 @@ put_datagram(const Datagram &data) { _wrote_first_datagram = true; // First, write the size of the upcoming datagram. - StreamWriter writer(_out); + StreamWriter writer(_out, false); writer.add_uint32(data.get_length()); // Now, write the datagram itself. diff --git a/panda/src/putil/stringStream.I b/panda/src/putil/stringStream.I index 8277868bdb..347fc1f5c7 100644 --- a/panda/src/putil/stringStream.I +++ b/panda/src/putil/stringStream.I @@ -34,7 +34,7 @@ StringStream() : iostream(&_buf) { //////////////////////////////////////////////////////////////////// INLINE StringStream:: StringStream(const string &source) : iostream(&_buf) { - write(source); + set_data(source); } //////////////////////////////////////////////////////////////////// @@ -56,52 +56,48 @@ clear_data() { INLINE size_t StringStream:: get_data_size() { flush(); - return _buf.get_data_size(); + return _buf.get_data().size(); } //////////////////////////////////////////////////////////////////// -// Function: StringStream::read +// Function: StringStream::get_data // Access: Published -// Description: Extracts all the remaining characters from the data -// stream and stores them in the indicated string. -//////////////////////////////////////////////////////////////////// -INLINE void StringStream:: -read(string &data) { - read(data, get_data_size()); -} - -//////////////////////////////////////////////////////////////////// -// Function: StringStream::read -// Access: Published -// Description: Extracts up to max_length characters from the data -// stream and returns them as a string. +// Description: Returns the contents of the data stream as a string. //////////////////////////////////////////////////////////////////// INLINE string StringStream:: -read(size_t max_length) { - string data; - read(data, max_length); - return data; +get_data() { + flush(); + const pvector &data = _buf.get_data(); + if (!data.empty()) { + return string((char *)&data[0], data.size()); + } + return string(); } //////////////////////////////////////////////////////////////////// -// Function: StringStream::read +// Function: StringStream::set_data // Access: Published -// Description: Extracts all the remaining characters from the data -// stream and returns them as a string. -//////////////////////////////////////////////////////////////////// -INLINE string StringStream:: -read() { - string data; - read(data); - return data; -} - -//////////////////////////////////////////////////////////////////// -// Function: StringStream::write -// Access: Published -// Description: Appends the indicated data to the data stream. +// Description: Replaces the contents of the data stream. This +// implicitly reseeks to 0. //////////////////////////////////////////////////////////////////// INLINE void StringStream:: -write(const string &data) { - _buf.write_chars(data.data(), data.size()); +set_data(const string &data) { + _buf.clear(); + if (!data.empty()) { + pvector pv; + pv.insert(pv.end(), (const unsigned char *)&data[0], (const unsigned char *)&data[0] + data.size()); + _buf.swap_data(pv); + } +} + +//////////////////////////////////////////////////////////////////// +// Function: StringStream::swap_data +// Access: Published +// Description: Swaps the indicated buffer for the contents of the +// internal buffer. +//////////////////////////////////////////////////////////////////// +INLINE void StringStream:: +swap_data(pvector &data) { + flush(); + _buf.swap_data(data); } diff --git a/panda/src/putil/stringStream.cxx b/panda/src/putil/stringStream.cxx index 305a4d0fca..ea93ad6f42 100644 --- a/panda/src/putil/stringStream.cxx +++ b/panda/src/putil/stringStream.cxx @@ -17,18 +17,3 @@ //////////////////////////////////////////////////////////////////// #include "stringStream.h" - -//////////////////////////////////////////////////////////////////// -// Function: StringStream::read -// Access: Published -// Description: Extracts up to max_length characters from the data -// stream and stores them in the indicated string. -//////////////////////////////////////////////////////////////////// -void StringStream:: -read(string &data, size_t max_length) { - flush(); - char *buffer = (char *)PANDA_MALLOC_ARRAY(max_length); - size_t length = _buf.read_chars(buffer, max_length); - data.append(buffer, length); - PANDA_FREE_ARRAY(buffer); -} diff --git a/panda/src/putil/stringStream.h b/panda/src/putil/stringStream.h index 41d853ad23..b4e0fc61a7 100644 --- a/panda/src/putil/stringStream.h +++ b/panda/src/putil/stringStream.h @@ -36,12 +36,9 @@ PUBLISHED: INLINE void clear_data(); INLINE size_t get_data_size(); - void read(string &data, size_t max_length); - INLINE void read(string &data); - INLINE string read(size_t max_length); - INLINE string read(); - - INLINE void write(const string &data); + INLINE string get_data(); + INLINE void set_data(const string &data); + INLINE void swap_data(pvector &data); private: StringStreamBuf _buf; diff --git a/panda/src/putil/stringStreamBuf.I b/panda/src/putil/stringStreamBuf.I index 736e44d7ec..fcfe701ed8 100644 --- a/panda/src/putil/stringStreamBuf.I +++ b/panda/src/putil/stringStreamBuf.I @@ -18,13 +18,24 @@ //////////////////////////////////////////////////////////////////// -// Function: StringStreamBuf::get_data_size +// Function: StringStreamBuf::swap_data // Access: Public -// Description: Returns the number of characters remaining in the -// internal data buffer, not counting data which might -// still be in the iostream buffer. +// Description: Swaps the indicated buffer for the contents of the +// internal buffer. Does not affect the ppos or gpos, +// or the iostream buffer. //////////////////////////////////////////////////////////////////// -INLINE size_t StringStreamBuf:: -get_data_size() const { - return _data.size() - _gpos; +INLINE void StringStreamBuf:: +swap_data(pvector &data) { + _data.swap(data); +} + +//////////////////////////////////////////////////////////////////// +// Function: StringStreamBuf::get_data +// Access: Public +// Description: Returns a reference to the contents of the internal +// buffer, without any of the iostream buffer. +//////////////////////////////////////////////////////////////////// +INLINE const pvector &StringStreamBuf:: +get_data() const { + return _data; } diff --git a/panda/src/putil/stringStreamBuf.cxx b/panda/src/putil/stringStreamBuf.cxx index b57d48a745..fd67bf39bf 100644 --- a/panda/src/putil/stringStreamBuf.cxx +++ b/panda/src/putil/stringStreamBuf.cxx @@ -125,10 +125,15 @@ write_chars(const char *start, size_t length) { _ppos += overwrite_length; start += overwrite_length; } + + if (_data.size() < _ppos) { + // We need to append some zeroes. + _data.insert(_data.end(), _ppos - _data.size(), (unsigned char)0); + } if (length != 0) { // We are appending some data. - _data.insert(_data.begin() + _ppos, start, start + length); + _data.insert(_data.begin() + _ppos, (const unsigned char *)start, (const unsigned char *)start + length); _ppos += length; } } diff --git a/panda/src/putil/stringStreamBuf.h b/panda/src/putil/stringStreamBuf.h index 0c5355a3c5..9b991d5e8b 100644 --- a/panda/src/putil/stringStreamBuf.h +++ b/panda/src/putil/stringStreamBuf.h @@ -36,7 +36,9 @@ public: void clear(); - INLINE size_t get_data_size() const; + INLINE void swap_data(pvector &data); + INLINE const pvector &get_data() const; + size_t read_chars(char *start, size_t length); void write_chars(const char *start, size_t length); @@ -49,7 +51,7 @@ protected: virtual int underflow(); private: - pvector _data; + pvector _data; char *_buffer; size_t _ppos; size_t _gpos;