Pārlūkot izejas kodu

regularize StreamReader, StreamWriter, StringStream

David Rose 18 gadi atpakaļ
vecāks
revīzija
87a23944fb

+ 1 - 1
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);

+ 3 - 0
dtool/src/prc/streamReader.I

@@ -63,6 +63,9 @@ StreamReader(const StreamReader &copy) :
 ////////////////////////////////////////////////////////////////////
 INLINE void StreamReader::
 operator = (const StreamReader &copy) {
+  if (_owns_stream) {
+    delete _in;
+  }
   _in = copy._in;
   _owns_stream = false;
 }

+ 20 - 25
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);
 }
 
 

+ 18 - 6
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 &copy) :
-  _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 &copy) {
+  if (_owns_stream) {
+    delete _out;
+  }
   _out = copy._out;
+  _owns_stream = false;
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -67,6 +76,9 @@ operator = (const StreamWriter &copy) {
 ////////////////////////////////////////////////////////////////////
 INLINE StreamWriter::
 ~StreamWriter() {
+  if (_owns_stream) {
+    delete _out;
+  }
 }
 
 ////////////////////////////////////////////////////////////////////

+ 2 - 1
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 &copy);
   INLINE void operator = (const StreamWriter &copy);
   INLINE ~StreamWriter();
@@ -80,6 +80,7 @@ PUBLISHED:
 
 private:
   ostream *_out;
+  bool _owns_stream;
 };
 
 #include "streamWriter.I"

+ 3 - 3
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);

+ 4 - 4
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;
 }

+ 1 - 1
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.

+ 28 - 32
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<unsigned char> &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.
+//  Description: Replaces the contents of the data stream.  This
+//               implicitly reseeks to 0.
 ////////////////////////////////////////////////////////////////////
-INLINE string StringStream::
-read() {
-  string data;
-  read(data);
-  return data;
+INLINE void StringStream::
+set_data(const string &data) {
+  _buf.clear();
+  if (!data.empty()) {
+    pvector<unsigned char> pv;
+    pv.insert(pv.end(), (const unsigned char *)&data[0], (const unsigned char *)&data[0] + data.size());
+    _buf.swap_data(pv);
+  }
 }
 
 ////////////////////////////////////////////////////////////////////
-//     Function: StringStream::write
+//     Function: StringStream::swap_data
 //       Access: Published
-//  Description: Appends the indicated data to the data stream.
+//  Description: Swaps the indicated buffer for the contents of the
+//               internal buffer.
 ////////////////////////////////////////////////////////////////////
 INLINE void StringStream::
-write(const string &data) {
-  _buf.write_chars(data.data(), data.size());
+swap_data(pvector<unsigned char> &data) {
+  flush();
+  _buf.swap_data(data);
 }

+ 0 - 15
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);
-}

+ 3 - 6
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<unsigned char> &data);
 
 private:
   StringStreamBuf _buf;

+ 18 - 7
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<unsigned char> &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<unsigned char> &StringStreamBuf::
+get_data() const {
+  return _data;
 }

+ 6 - 1
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;
     }
   }

+ 4 - 2
panda/src/putil/stringStreamBuf.h

@@ -36,7 +36,9 @@ public:
 
   void clear();
 
-  INLINE size_t get_data_size() const;
+  INLINE void swap_data(pvector<unsigned char> &data);
+  INLINE const pvector<unsigned char> &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<char> _data;
+  pvector<unsigned char> _data;
   char *_buffer;
   size_t _ppos;
   size_t _gpos;