瀏覽代碼

dcparser: use vector_uchar for blobs, step towards Python 3 compat

Closes #298
rdb 7 年之前
父節點
當前提交
e4f493b872

+ 72 - 0
direct/src/dcparser/dcArrayParameter.cxx

@@ -262,6 +262,38 @@ pack_string(DCPackData &pack_data, const string &value,
   }
   }
 }
 }
 
 
+/**
+ * Packs the indicated numeric or string value into the stream.
+ */
+void DCArrayParameter::
+pack_blob(DCPackData &pack_data, const vector_uchar &value,
+          bool &pack_error, bool &range_error) const {
+  // We can only pack a string if the array element type is char or int8.
+  DCSimpleParameter *simple_type = _element_type->as_simple_parameter();
+  if (simple_type == nullptr) {
+    pack_error = true;
+    return;
+  }
+
+  size_t blob_size = value.size();
+
+  switch (simple_type->get_type()) {
+  case ST_char:
+  case ST_uint8:
+  case ST_int8:
+    _array_size_range.validate(blob_size, range_error);
+    if (_num_length_bytes != 0) {
+      nassertv(_num_length_bytes == 2);
+      do_pack_uint16(pack_data.get_write_pointer(2), blob_size);
+    }
+    pack_data.append_data((const char *)value.data(), blob_size);
+    break;
+
+  default:
+    pack_error = true;
+  }
+}
+
 /**
 /**
  * Packs the arrayParameter's specified default value (or a sensible default
  * Packs the arrayParameter's specified default value (or a sensible default
  * if no value is specified) into the stream.  Returns true if the default
  * if no value is specified) into the stream.  Returns true if the default
@@ -339,6 +371,46 @@ unpack_string(const char *data, size_t length, size_t &p, string &value,
   }
   }
 }
 }
 
 
+/**
+ * Unpacks the current numeric or string value from the stream.
+ */
+void DCArrayParameter::
+unpack_blob(const char *data, size_t length, size_t &p, vector_uchar &value,
+            bool &pack_error, bool &range_error) const {
+  // We can only unpack a string if the array element type is char or int8.
+  DCSimpleParameter *simple_type = _element_type->as_simple_parameter();
+  if (simple_type == nullptr) {
+    pack_error = true;
+    return;
+  }
+
+  size_t blob_size;
+
+  switch (simple_type->get_type()) {
+  case ST_char:
+  case ST_uint8:
+  case ST_int8:
+    if (_num_length_bytes != 0) {
+      blob_size = do_unpack_uint16(data + p);
+      p += 2;
+    } else {
+      nassertv(_array_size >= 0);
+      blob_size = _array_size;
+    }
+    if (p + blob_size > length) {
+      pack_error = true;
+      return;
+    }
+    value = vector_uchar((const unsigned char *)data + p,
+                         (const unsigned char *)data + p + blob_size);
+    p += blob_size;
+    break;
+
+  default:
+    pack_error = true;
+  }
+}
+
 /**
 /**
  * Returns true if the other interface is bitwise the same as this one--that
  * Returns true if the other interface is bitwise the same as this one--that
  * is, a uint32 only matches a uint32, etc.  Names of components, and range
  * is, a uint32 only matches a uint32, etc.  Names of components, and range

+ 4 - 0
direct/src/dcparser/dcArrayParameter.h

@@ -51,9 +51,13 @@ public:
   virtual void generate_hash(HashGenerator &hashgen) const;
   virtual void generate_hash(HashGenerator &hashgen) const;
   virtual void pack_string(DCPackData &pack_data, const std::string &value,
   virtual void pack_string(DCPackData &pack_data, const std::string &value,
                            bool &pack_error, bool &range_error) const;
                            bool &pack_error, bool &range_error) const;
+  virtual void pack_blob(DCPackData &pack_data, const vector_uchar &value,
+                         bool &pack_error, bool &range_error) const;
   virtual bool pack_default_value(DCPackData &pack_data, bool &pack_error) const;
   virtual bool pack_default_value(DCPackData &pack_data, bool &pack_error) const;
   virtual void unpack_string(const char *data, size_t length, size_t &p,
   virtual void unpack_string(const char *data, size_t length, size_t &p,
                              std::string &value, bool &pack_error, bool &range_error) const;
                              std::string &value, bool &pack_error, bool &range_error) const;
+  virtual void unpack_blob(const char *data, size_t length, size_t &p,
+                           vector_uchar &value, bool &pack_error, bool &range_error) const;
 
 
 protected:
 protected:
   virtual bool do_check_match(const DCPackerInterface *other) const;
   virtual bool do_check_match(const DCPackerInterface *other) const;

+ 5 - 5
direct/src/dcparser/dcAtomicField.cxx

@@ -88,11 +88,11 @@ get_element(int n) const {
  * If the element is an array-type element, the returned value will include
  * If the element is an array-type element, the returned value will include
  * the two-byte length preceding the array data.
  * the two-byte length preceding the array data.
  *
  *
- * This is deprecated; use get_element() instead.
+ * @deprecated use get_element() instead.
  */
  */
-string DCAtomicField::
+vector_uchar DCAtomicField::
 get_element_default(int n) const {
 get_element_default(int n) const {
-  nassertr(n >= 0 && n < (int)_elements.size(), string());
+  nassertr(n >= 0 && n < (int)_elements.size(), vector_uchar());
   return _elements[n]->get_default_value();
   return _elements[n]->get_default_value();
 }
 }
 
 
@@ -100,7 +100,7 @@ get_element_default(int n) const {
  * Returns true if the nth element of the field has a default value specified,
  * Returns true if the nth element of the field has a default value specified,
  * false otherwise.
  * false otherwise.
  *
  *
- * This is deprecated; use get_element() instead.
+ * @deprecated use get_element() instead.
  */
  */
 bool DCAtomicField::
 bool DCAtomicField::
 has_element_default(int n) const {
 has_element_default(int n) const {
@@ -113,7 +113,7 @@ has_element_default(int n) const {
  * for documentary purposes; it does not generally affect operation.  If a
  * for documentary purposes; it does not generally affect operation.  If a
  * name is not specified, this will be the empty string.
  * name is not specified, this will be the empty string.
  *
  *
- * This method is deprecated; use get_element()->get_name() instead.
+ * @deprecated use get_element()->get_name() instead.
  */
  */
 string DCAtomicField::
 string DCAtomicField::
 get_element_name(int n) const {
 get_element_name(int n) const {

+ 1 - 1
direct/src/dcparser/dcAtomicField.h

@@ -40,7 +40,7 @@ PUBLISHED:
   DCParameter *get_element(int n) const;
   DCParameter *get_element(int n) const;
 
 
   // These five methods are deprecated and will be removed soon.
   // These five methods are deprecated and will be removed soon.
-  std::string get_element_default(int n) const;
+  vector_uchar get_element_default(int n) const;
   bool has_element_default(int n) const;
   bool has_element_default(int n) const;
   std::string get_element_name(int n) const;
   std::string get_element_name(int n) const;
   DCSubatomicType get_element_type(int n) const;
   DCSubatomicType get_element_type(int n) const;

+ 9 - 2
direct/src/dcparser/dcClass.cxx

@@ -587,7 +587,7 @@ receive_update_other(PyObject *distobj, DatagramIterator &di) const {
  */
  */
 void DCClass::
 void DCClass::
 direct_update(PyObject *distobj, const string &field_name,
 direct_update(PyObject *distobj, const string &field_name,
-              const string &value_blob) {
+              const vector_uchar &value_blob) {
   DCField *field = get_field_by_name(field_name);
   DCField *field = get_field_by_name(field_name);
   nassertv_always(field != nullptr);
   nassertv_always(field != nullptr);
 
 
@@ -606,7 +606,14 @@ direct_update(PyObject *distobj, const string &field_name,
 void DCClass::
 void DCClass::
 direct_update(PyObject *distobj, const string &field_name,
 direct_update(PyObject *distobj, const string &field_name,
               const Datagram &datagram) {
               const Datagram &datagram) {
-  direct_update(distobj, field_name, datagram.get_message());
+  DCField *field = get_field_by_name(field_name);
+  nassertv_always(field != nullptr);
+
+  DCPacker packer;
+  packer.set_unpack_data((const char *)datagram.get_data(), datagram.get_length(), false);
+  packer.begin_unpack(field);
+  field->receive_update(packer, distobj);
+  packer.end_unpack();
 }
 }
 #endif  // HAVE_PYTHON
 #endif  // HAVE_PYTHON
 
 

+ 1 - 1
direct/src/dcparser/dcClass.h

@@ -95,7 +95,7 @@ PUBLISHED:
   void receive_update_other(PyObject *distobj, DatagramIterator &di) const;
   void receive_update_other(PyObject *distobj, DatagramIterator &di) const;
 
 
   void direct_update(PyObject *distobj, const std::string &field_name,
   void direct_update(PyObject *distobj, const std::string &field_name,
-                     const std::string &value_blob);
+                     const vector_uchar &value_blob);
   void direct_update(PyObject *distobj, const std::string &field_name,
   void direct_update(PyObject *distobj, const std::string &field_name,
                      const Datagram &datagram);
                      const Datagram &datagram);
   bool pack_required_field(Datagram &datagram, PyObject *distobj,
   bool pack_required_field(Datagram &datagram, PyObject *distobj,

+ 3 - 3
direct/src/dcparser/dcField.I

@@ -42,7 +42,7 @@ has_default_value() const {
  * explicitly set (e.g.  has_default_value() returns true), returns that
  * explicitly set (e.g.  has_default_value() returns true), returns that
  * value; otherwise, returns an implicit default for the field.
  * value; otherwise, returns an implicit default for the field.
  */
  */
-INLINE const std::string &DCField::
+INLINE const vector_uchar &DCField::
 get_default_value() const {
 get_default_value() const {
   if (_default_value_stale) {
   if (_default_value_stale) {
     ((DCField *)this)->refresh_default_value();
     ((DCField *)this)->refresh_default_value();
@@ -172,8 +172,8 @@ set_class(DCClass *dclass) {
  * Establishes a default value for this field.
  * Establishes a default value for this field.
  */
  */
 INLINE void DCField::
 INLINE void DCField::
-set_default_value(const std::string &default_value) {
-  _default_value = default_value;
+set_default_value(vector_uchar default_value) {
+  _default_value = std::move(default_value);
   _has_default_value = true;
   _has_default_value = true;
   _default_value_stale = false;
   _default_value_stale = false;
 }
 }

+ 10 - 9
direct/src/dcparser/dcField.cxx

@@ -162,7 +162,7 @@ as_parameter() const {
  * is an error.
  * is an error.
  */
  */
 string DCField::
 string DCField::
-format_data(const string &packed_data, bool show_field_names) {
+format_data(const vector_uchar &packed_data, bool show_field_names) {
   DCPacker packer;
   DCPacker packer;
   packer.set_unpack_data(packed_data);
   packer.set_unpack_data(packed_data);
   packer.begin_unpack(this);
   packer.begin_unpack(this);
@@ -178,20 +178,20 @@ format_data(const string &packed_data, bool show_field_names) {
  * above) that represents the value of this field, parse the string and return
  * above) that represents the value of this field, parse the string and return
  * the corresponding packed data.  Returns empty string if there is an error.
  * the corresponding packed data.  Returns empty string if there is an error.
  */
  */
-string DCField::
+vector_uchar DCField::
 parse_string(const string &formatted_string) {
 parse_string(const string &formatted_string) {
   DCPacker packer;
   DCPacker packer;
   packer.begin_pack(this);
   packer.begin_pack(this);
   if (!packer.parse_and_pack(formatted_string)) {
   if (!packer.parse_and_pack(formatted_string)) {
     // Parse error.
     // Parse error.
-    return string();
+    return vector_uchar();
   }
   }
   if (!packer.end_pack()) {
   if (!packer.end_pack()) {
     // Data type mismatch.
     // Data type mismatch.
-    return string();
+    return vector_uchar();
   }
   }
 
 
-  return packer.get_string();
+  return packer.get_bytes();
 }
 }
 
 
 /**
 /**
@@ -200,7 +200,7 @@ parse_string(const string &formatted_string) {
  * record.  Returns true if all fields are valid, false otherwise.
  * record.  Returns true if all fields are valid, false otherwise.
  */
  */
 bool DCField::
 bool DCField::
-validate_ranges(const string &packed_data) const {
+validate_ranges(const vector_uchar &packed_data) const {
   DCPacker packer;
   DCPacker packer;
   packer.set_unpack_data(packed_data);
   packer.set_unpack_data(packed_data);
   packer.begin_unpack(this);
   packer.begin_unpack(this);
@@ -209,7 +209,7 @@ validate_ranges(const string &packed_data) const {
     return false;
     return false;
   }
   }
 
 
-  return (packer.get_num_unpacked_bytes() == packed_data.length());
+  return (packer.get_num_unpacked_bytes() == packed_data.size());
 }
 }
 
 
 #ifdef HAVE_PYTHON
 #ifdef HAVE_PYTHON
@@ -488,7 +488,7 @@ pack_default_value(DCPackData &pack_data, bool &) const {
   // The default behavior is to pack the default value if we got it;
   // The default behavior is to pack the default value if we got it;
   // otherwise, to return false and let the packer visit our nested elements.
   // otherwise, to return false and let the packer visit our nested elements.
   if (!_default_value_stale) {
   if (!_default_value_stale) {
-    pack_data.append_data(_default_value.data(), _default_value.length());
+    pack_data.append_data((const char *)_default_value.data(), _default_value.size());
     return true;
     return true;
   }
   }
 
 
@@ -566,7 +566,8 @@ refresh_default_value() {
   if (!packer.end_pack()) {
   if (!packer.end_pack()) {
     std::cerr << "Error while packing default value for " << get_name() << "\n";
     std::cerr << "Error while packing default value for " << get_name() << "\n";
   } else {
   } else {
-    _default_value.assign(packer.get_data(), packer.get_length());
+    const unsigned char *data = (const unsigned char *)packer.get_data();
+    _default_value = vector_uchar(data, data + packer.get_length());
   }
   }
   _default_value_stale = false;
   _default_value_stale = false;
 }
 }

+ 6 - 6
direct/src/dcparser/dcField.h

@@ -53,13 +53,13 @@ PUBLISHED:
   virtual DCParameter *as_parameter();
   virtual DCParameter *as_parameter();
   virtual const DCParameter *as_parameter() const;
   virtual const DCParameter *as_parameter() const;
 
 
-  std::string format_data(const std::string &packed_data, bool show_field_names = true);
-  std::string parse_string(const std::string &formatted_string);
+  std::string format_data(const vector_uchar &packed_data, bool show_field_names = true);
+  vector_uchar parse_string(const std::string &formatted_string);
 
 
-  bool validate_ranges(const std::string &packed_data) const;
+  bool validate_ranges(const vector_uchar &packed_data) const;
 
 
   INLINE bool has_default_value() const;
   INLINE bool has_default_value() const;
-  INLINE const std::string &get_default_value() const;
+  INLINE const vector_uchar &get_default_value() const;
 
 
   INLINE bool is_bogus_field() const;
   INLINE bool is_bogus_field() const;
 
 
@@ -98,7 +98,7 @@ public:
 
 
   INLINE void set_number(int number);
   INLINE void set_number(int number);
   INLINE void set_class(DCClass *dclass);
   INLINE void set_class(DCClass *dclass);
-  INLINE void set_default_value(const std::string &default_value);
+  INLINE void set_default_value(vector_uchar default_value);
 
 
 #ifdef HAVE_PYTHON
 #ifdef HAVE_PYTHON
   static std::string get_pystr(PyObject *value);
   static std::string get_pystr(PyObject *value);
@@ -115,7 +115,7 @@ protected:
   bool _bogus_field;
   bool _bogus_field;
 
 
 private:
 private:
-  std::string _default_value;
+  vector_uchar _default_value;
 
 
 #ifdef WITHIN_PANDA
 #ifdef WITHIN_PANDA
   PStatCollector _field_update_pcollector;
   PStatCollector _field_update_pcollector;

File diff suppressed because it is too large
+ 160 - 142
direct/src/dcparser/dcLexer.cxx.prebuilt


+ 31 - 31
direct/src/dcparser/dcLexer.lxx

@@ -1,7 +1,7 @@
 /*
 /*
 // Filename: dcLexer.lxx
 // Filename: dcLexer.lxx
 // Created by:  drose (05Oct00)
 // Created by:  drose (05Oct00)
-// 
+//
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 */
 */
 
 
@@ -103,12 +103,12 @@ dcyyerror(const std::string &msg) {
   if (!dc_filename.empty()) {
   if (!dc_filename.empty()) {
     cerr << " in " << dc_filename;
     cerr << " in " << dc_filename;
   }
   }
-  cerr 
+  cerr
     << " at line " << line_number << ", column " << col_number << ":\n"
     << " at line " << line_number << ", column " << col_number << ":\n"
     << current_line << "\n";
     << current_line << "\n";
-  indent(cerr, col_number-1) 
+  indent(cerr, col_number-1)
     << "^\n" << msg << "\n\n";
     << "^\n" << msg << "\n\n";
-  
+
   error_count++;
   error_count++;
 }
 }
 
 
@@ -120,10 +120,10 @@ dcyywarning(const std::string &msg) {
   if (!dc_filename.empty()) {
   if (!dc_filename.empty()) {
     cerr << " in " << dc_filename;
     cerr << " in " << dc_filename;
   }
   }
-  cerr 
+  cerr
     << " at line " << line_number << ", column " << col_number << ":\n"
     << " at line " << line_number << ", column " << col_number << ":\n"
     << current_line << "\n";
     << current_line << "\n";
-  indent(cerr, col_number-1) 
+  indent(cerr, col_number-1)
     << "^\n" << msg << "\n\n";
     << "^\n" << msg << "\n\n";
 
 
   warning_count++;
   warning_count++;
@@ -313,9 +313,9 @@ scan_quoted_string(char quote_mark) {
 
 
 // scan_hex_string reads a string of hexadecimal digits delimited by
 // scan_hex_string reads a string of hexadecimal digits delimited by
 // angle brackets and returns the representative string.
 // angle brackets and returns the representative string.
-static std::string
+static vector_uchar
 scan_hex_string() {
 scan_hex_string() {
-  std::string result;
+  vector_uchar result;
 
 
   // We don't touch the current line number and column number during
   // We don't touch the current line number and column number during
   // scanning, so that if we detect an error while scanning the string
   // scanning, so that if we detect an error while scanning the string
@@ -345,24 +345,24 @@ scan_hex_string() {
       line_number = line;
       line_number = line;
       col_number = col;
       col_number = col;
       dcyyerror("Invalid hex digit.");
       dcyyerror("Invalid hex digit.");
-      return std::string();
+      return vector_uchar();
     }
     }
 
 
     odd = !odd;
     odd = !odd;
     if (odd) {
     if (odd) {
       last = value;
       last = value;
     } else {
     } else {
-      result += (char)((last << 4) | value);
+      result.push_back((unsigned char)((last << 4) | value));
     }
     }
     c = read_char(line, col);
     c = read_char(line, col);
   }
   }
 
 
   if (c == EOF) {
   if (c == EOF) {
     dcyyerror("This hex string is unterminated.");
     dcyyerror("This hex string is unterminated.");
-    return std::string();
+    return vector_uchar();
   } else if (odd) {
   } else if (odd) {
     dcyyerror("Odd number of hex digits.");
     dcyyerror("Odd number of hex digits.");
-    return std::string();
+    return vector_uchar();
   }
   }
 
 
   line_number = line;
   line_number = line;
@@ -382,7 +382,7 @@ eat_c_comment() {
   int col = col_number;
   int col = col_number;
 
 
   int c, last_c;
   int c, last_c;
-  
+
   last_c = '\0';
   last_c = '\0';
   c = read_char(line, col);
   c = read_char(line, col);
   while (c != EOF && !(last_c == '*' && c == '/')) {
   while (c != EOF && !(last_c == '*' && c == '/')) {
@@ -440,12 +440,12 @@ REALNUM              ([+-]?(([0-9]+[.])|([0-9]*[.][0-9]+))([eE][+-]?[0-9]+)?)
   yyless(1);
   yyless(1);
 }
 }
 
 
-[ \t\r] { 
+[ \t\r] {
   // Eat whitespace.
   // Eat whitespace.
   accept();
   accept();
 }
 }
 
 
-"//".* { 
+"//".* {
   // Eat C++-style comments.
   // Eat C++-style comments.
   accept();
   accept();
 }
 }
@@ -453,7 +453,7 @@ REALNUM              ([+-]?(([0-9]+[.])|([0-9]*[.][0-9]+))([eE][+-]?[0-9]+)?)
 "/*" {
 "/*" {
   // Eat C-style comments.
   // Eat C-style comments.
   accept();
   accept();
-  eat_c_comment(); 
+  eat_c_comment();
 }
 }
 
 
 
 
@@ -607,7 +607,7 @@ REALNUM              ([+-]?(([0-9]+[.])|([0-9]*[.][0-9]+))([eE][+-]?[0-9]+)?)
   return KW_CHAR;
   return KW_CHAR;
 }
 }
 
 
-{UNSIGNED_INTEGERNUM} { 
+{UNSIGNED_INTEGERNUM} {
   // An unsigned integer number.
   // An unsigned integer number.
   accept();
   accept();
 
 
@@ -626,11 +626,11 @@ REALNUM              ([+-]?(([0-9]+[.])|([0-9]*[.][0-9]+))([eE][+-]?[0-9]+)?)
     dcyylval.u.uint64 = next_value + (*p - '0');
     dcyylval.u.uint64 = next_value + (*p - '0');
     ++p;
     ++p;
   }
   }
-  
+
   return UNSIGNED_INTEGER;
   return UNSIGNED_INTEGER;
 }
 }
 
 
-{SIGNED_INTEGERNUM} { 
+{SIGNED_INTEGERNUM} {
   // A signed integer number.
   // A signed integer number.
   accept();
   accept();
 
 
@@ -671,14 +671,14 @@ REALNUM              ([+-]?(([0-9]+[.])|([0-9]*[.][0-9]+))([eE][+-]?[0-9]+)?)
       dcyyerror("Number out of range.");
       dcyyerror("Number out of range.");
       dcyylval.u.int64 = 1;
       dcyylval.u.int64 = 1;
     }
     }
-  }    
-  
+  }
+
   return SIGNED_INTEGER;
   return SIGNED_INTEGER;
 }
 }
 
 
 {UNSIGNED_HEXNUM} {
 {UNSIGNED_HEXNUM} {
   // A hexadecimal integer number.
   // A hexadecimal integer number.
-  accept(); 
+  accept();
 
 
   // As above, we'll decode the hex string by hand.
   // As above, we'll decode the hex string by hand.
   dcyylval.str = dcyytext;
   dcyylval.str = dcyytext;
@@ -700,15 +700,15 @@ REALNUM              ([+-]?(([0-9]+[.])|([0-9]*[.][0-9]+))([eE][+-]?[0-9]+)?)
     ++p;
     ++p;
   }
   }
 
 
-  return UNSIGNED_INTEGER; 
+  return UNSIGNED_INTEGER;
 }
 }
 
 
-{REALNUM} { 
+{REALNUM} {
   // A floating-point number.
   // A floating-point number.
-  accept(); 
-  dcyylval.u.real = patof(dcyytext); 
+  accept();
+  dcyylval.u.real = patof(dcyytext);
   dcyylval.str = dcyytext;
   dcyylval.str = dcyytext;
-  return REAL; 
+  return REAL;
 }
 }
 
 
 ["] {
 ["] {
@@ -728,11 +728,11 @@ REALNUM              ([+-]?(([0-9]+[.])|([0-9]*[.][0-9]+))([eE][+-]?[0-9]+)?)
 [<] {
 [<] {
   // Long hex string.
   // Long hex string.
   accept();
   accept();
-  dcyylval.str = scan_hex_string();
+  dcyylval.bytes = scan_hex_string();
   return HEX_STRING;
   return HEX_STRING;
 }
 }
 
 
-[A-Za-z_][A-Za-z_0-9]* { 
+[A-Za-z_][A-Za-z_0-9]* {
   // Identifier or keyword.
   // Identifier or keyword.
   accept();
   accept();
   dcyylval.str = dcyytext;
   dcyylval.str = dcyytext;
@@ -750,7 +750,7 @@ REALNUM              ([+-]?(([0-9]+[.])|([0-9]*[.][0-9]+))([eE][+-]?[0-9]+)?)
 
 
 . {
 . {
   // Send any other printable character as itself.
   // Send any other printable character as itself.
-  accept(); 
+  accept();
   return dcyytext[0];
   return dcyytext[0];
 }
 }
-  
+

+ 107 - 9
direct/src/dcparser/dcPacker.I

@@ -216,17 +216,31 @@ pack_string(const std::string &value) {
   }
   }
 }
 }
 
 
+/**
+ * Packs the indicated numeric or string value into the stream.
+ */
+INLINE void DCPacker::
+pack_blob(const vector_uchar &value) {
+  nassertv(_mode == M_pack || _mode == M_repack);
+  if (_current_field == nullptr) {
+    _pack_error = true;
+  } else {
+    _current_field->pack_blob(_pack_data, value, _pack_error, _range_error);
+    advance();
+  }
+}
+
 /**
 /**
  * Adds the indicated string value into the stream, representing a single pre-
  * Adds the indicated string value into the stream, representing a single pre-
  * packed field element, or a whole group of field elements at once.
  * packed field element, or a whole group of field elements at once.
  */
  */
 INLINE void DCPacker::
 INLINE void DCPacker::
-pack_literal_value(const std::string &value) {
+pack_literal_value(const vector_uchar &value) {
   nassertv(_mode == M_pack || _mode == M_repack);
   nassertv(_mode == M_pack || _mode == M_repack);
   if (_current_field == nullptr) {
   if (_current_field == nullptr) {
     _pack_error = true;
     _pack_error = true;
   } else {
   } else {
-    _pack_data.append_data(value.data(), value.length());
+    _pack_data.append_data((const char *)value.data(), value.size());
     advance();
     advance();
   }
   }
 }
 }
@@ -345,16 +359,36 @@ unpack_string() {
   return value;
   return value;
 }
 }
 
 
+/**
+ * Unpacks the current binary data value from the stream.
+ */
+INLINE vector_uchar DCPacker::
+unpack_blob() {
+  vector_uchar value;
+  nassertr(_mode == M_unpack, value);
+  if (_current_field == nullptr) {
+    _pack_error = true;
+
+  } else {
+    _current_field->unpack_blob(_unpack_data, _unpack_length, _unpack_p,
+                                 value, _pack_error, _range_error);
+    advance();
+  }
+
+  return value;
+}
+
 /**
 /**
  * Returns the literal string that represents the packed value of the current
  * Returns the literal string that represents the packed value of the current
  * field, and advances the field pointer.
  * field, and advances the field pointer.
  */
  */
-INLINE std::string DCPacker::
+INLINE vector_uchar DCPacker::
 unpack_literal_value() {
 unpack_literal_value() {
   size_t start = _unpack_p;
   size_t start = _unpack_p;
   unpack_skip();
   unpack_skip();
-  nassertr(_unpack_p >= start, std::string());
-  return std::string(_unpack_data + start, _unpack_p - start);
+  nassertr(_unpack_p >= start, vector_uchar());
+  return vector_uchar((const unsigned char *)_unpack_data + start,
+                      (const unsigned char *)_unpack_data + _unpack_p);
 }
 }
 
 
 /**
 /**
@@ -453,16 +487,33 @@ unpack_string(std::string &value) {
   }
   }
 }
 }
 
 
+/**
+ * Unpacks the current numeric or string value from the stream.
+ */
+INLINE void DCPacker::
+unpack_blob(vector_uchar &value) {
+  nassertv(_mode == M_unpack);
+  if (_current_field == nullptr) {
+    _pack_error = true;
+
+  } else {
+    _current_field->unpack_blob(_unpack_data, _unpack_length, _unpack_p,
+                                value, _pack_error, _range_error);
+    advance();
+  }
+}
+
 /**
 /**
  * Returns the literal string that represents the packed value of the current
  * Returns the literal string that represents the packed value of the current
  * field, and advances the field pointer.
  * field, and advances the field pointer.
  */
  */
 INLINE void DCPacker::
 INLINE void DCPacker::
-unpack_literal_value(std::string &value) {
+unpack_literal_value(vector_uchar &value) {
   size_t start = _unpack_p;
   size_t start = _unpack_p;
   unpack_skip();
   unpack_skip();
   nassertv(_unpack_p >= start);
   nassertv(_unpack_p >= start);
-  value.assign(_unpack_data + start, _unpack_p - start);
+  value = vector_uchar((const unsigned char *)_unpack_data + start,
+                       (const unsigned char *)_unpack_data + _unpack_p);
 }
 }
 
 
 /**
 /**
@@ -541,6 +592,15 @@ get_string() const {
   return _pack_data.get_string();
   return _pack_data.get_string();
 }
 }
 
 
+/**
+ * Returns the packed data buffer as a bytes object.  Also see get_data().
+ */
+INLINE vector_uchar DCPacker::
+get_bytes() const {
+  const unsigned char *p = (const unsigned char *)_pack_data.get_data();
+  return vector_uchar(p, p + _pack_data.get_length());
+}
+
 /**
 /**
  * Returns the total number of bytes in the unpack data buffer.  This is the
  * Returns the total number of bytes in the unpack data buffer.  This is the
  * buffer used when unpacking; it is separate from the pack data returned by
  * buffer used when unpacking; it is separate from the pack data returned by
@@ -601,9 +661,9 @@ take_data() {
  * between packing sessions.
  * between packing sessions.
  */
  */
 INLINE void DCPacker::
 INLINE void DCPacker::
-append_data(const char *buffer, size_t size) {
+append_data(const unsigned char *buffer, size_t size) {
   nassertv(_mode == M_idle);
   nassertv(_mode == M_idle);
-  _pack_data.append_data(buffer, size);
+  _pack_data.append_data((const char *)buffer, size);
 }
 }
 
 
 /**
 /**
@@ -728,6 +788,16 @@ raw_pack_string(const std::string &value) {
   _pack_data.append_data(value.data(), value.length());
   _pack_data.append_data(value.data(), value.length());
 }
 }
 
 
+/**
+ * Packs the data into the buffer between packing sessions.
+ */
+INLINE void DCPacker::
+raw_pack_blob(const vector_uchar &value) {
+  nassertv(_mode == M_idle);
+  DCPackerInterface::do_pack_uint16(_pack_data.get_write_pointer(2), value.size());
+  _pack_data.append_data((const char *)value.data(), value.size());
+}
+
 /**
 /**
  * Unpacks the data from the buffer between unpacking sessions.
  * Unpacks the data from the buffer between unpacking sessions.
  */
  */
@@ -870,6 +940,16 @@ raw_unpack_string() {
   return value;
   return value;
 }
 }
 
 
+/**
+ * Unpacks the data from the buffer between unpacking sessions.
+ */
+INLINE vector_uchar DCPacker::
+raw_unpack_blob() {
+  vector_uchar value;
+  raw_unpack_blob(value);
+  return value;
+}
+
 /**
 /**
  * Unpacks the data from the buffer between unpacking sessions.
  * Unpacks the data from the buffer between unpacking sessions.
  */
  */
@@ -971,6 +1051,24 @@ raw_unpack_string(std::string &value) {
   _unpack_p += string_length;
   _unpack_p += string_length;
 }
 }
 
 
+/**
+ * Unpacks the data from the buffer between unpacking sessions.
+ */
+INLINE void DCPacker::
+raw_unpack_blob(vector_uchar &value) {
+  nassertv(_mode == M_idle && _unpack_data != nullptr);
+  unsigned int blob_size = raw_unpack_uint16();
+
+  if (_unpack_p + blob_size > _unpack_length) {
+    _pack_error = true;
+    return;
+  }
+
+  const unsigned char *p = (const unsigned char *)_unpack_data + _unpack_p;
+  value = vector_uchar(p, p + blob_size);
+  _unpack_p += blob_size;
+}
+
 /**
 /**
  * Advances to the next field after a call to pack_value() or pop().
  * Advances to the next field after a call to pack_value() or pop().
  */
  */

+ 9 - 9
direct/src/dcparser/dcPacker.cxx

@@ -114,12 +114,12 @@ end_pack() {
  * version of begin_unpack() that takes only one parameter.
  * version of begin_unpack() that takes only one parameter.
  */
  */
 void DCPacker::
 void DCPacker::
-set_unpack_data(const string &data) {
+set_unpack_data(const vector_uchar &data) {
   nassertv(_mode == M_idle);
   nassertv(_mode == M_idle);
 
 
-  char *buffer = new char[data.length()];
-  memcpy(buffer, data.data(), data.length());
-  set_unpack_data(buffer, data.length(), true);
+  char *buffer = new char[data.size()];
+  memcpy(buffer, data.data(), data.size());
+  set_unpack_data(buffer, data.size(), true);
 }
 }
 
 
 /**
 /**
@@ -721,11 +721,11 @@ pack_object(PyObject *object) {
       pack_string(string(buffer, length));
       pack_string(string(buffer, length));
     }
     }
   } else if (PyBytes_Check(object)) {
   } else if (PyBytes_Check(object)) {
-    char *buffer;
+    const unsigned char *buffer;
     Py_ssize_t length;
     Py_ssize_t length;
-    PyBytes_AsStringAndSize(object, &buffer, &length);
+    PyBytes_AsStringAndSize(object, (char **)&buffer, &length);
     if (buffer) {
     if (buffer) {
-      pack_string(string(buffer, length));
+      pack_blob(vector_uchar(buffer, buffer + length));
     }
     }
 #else
 #else
   } else if (PyString_Check(object) || PyUnicode_Check(object)) {
   } else if (PyString_Check(object) || PyUnicode_Check(object)) {
@@ -1118,9 +1118,9 @@ enquote_string(ostream &out, char quote_mark, const string &str) {
  * Outputs the indicated string as a hex constant.
  * Outputs the indicated string as a hex constant.
  */
  */
 void DCPacker::
 void DCPacker::
-output_hex_string(ostream &out, const string &str) {
+output_hex_string(ostream &out, const vector_uchar &str) {
   out << '<';
   out << '<';
-  for (string::const_iterator pi = str.begin();
+  for (vector_uchar::const_iterator pi = str.begin();
        pi != str.end();
        pi != str.end();
        ++pi) {
        ++pi) {
     char buffer[10];
     char buffer[10];

+ 13 - 6
direct/src/dcparser/dcPacker.h

@@ -41,7 +41,7 @@ PUBLISHED:
   void begin_pack(const DCPackerInterface *root);
   void begin_pack(const DCPackerInterface *root);
   bool end_pack();
   bool end_pack();
 
 
-  void set_unpack_data(const std::string &data);
+  void set_unpack_data(const vector_uchar &data);
 public:
 public:
   void set_unpack_data(const char *unpack_data, size_t unpack_length,
   void set_unpack_data(const char *unpack_data, size_t unpack_length,
                        bool owns_unpack_data);
                        bool owns_unpack_data);
@@ -75,7 +75,8 @@ PUBLISHED:
   INLINE void pack_int64(int64_t value);
   INLINE void pack_int64(int64_t value);
   INLINE void pack_uint64(uint64_t value);
   INLINE void pack_uint64(uint64_t value);
   INLINE void pack_string(const std::string &value);
   INLINE void pack_string(const std::string &value);
-  INLINE void pack_literal_value(const std::string &value);
+  INLINE void pack_blob(const vector_uchar &value);
+  INLINE void pack_literal_value(const vector_uchar &value);
   void pack_default_value();
   void pack_default_value();
 
 
   INLINE double unpack_double();
   INLINE double unpack_double();
@@ -84,7 +85,8 @@ PUBLISHED:
   INLINE int64_t unpack_int64();
   INLINE int64_t unpack_int64();
   INLINE uint64_t unpack_uint64();
   INLINE uint64_t unpack_uint64();
   INLINE std::string unpack_string();
   INLINE std::string unpack_string();
-  INLINE std::string unpack_literal_value();
+  INLINE vector_uchar unpack_blob();
+  INLINE vector_uchar unpack_literal_value();
   void unpack_validate();
   void unpack_validate();
   void unpack_skip();
   void unpack_skip();
 
 
@@ -97,7 +99,8 @@ public:
   INLINE void unpack_int64(int64_t &value);
   INLINE void unpack_int64(int64_t &value);
   INLINE void unpack_uint64(uint64_t &value);
   INLINE void unpack_uint64(uint64_t &value);
   INLINE void unpack_string(std::string &value);
   INLINE void unpack_string(std::string &value);
-  INLINE void unpack_literal_value(std::string &value);
+  INLINE void unpack_blob(vector_uchar &value);
+  INLINE void unpack_literal_value(vector_uchar &value);
 
 
 PUBLISHED:
 PUBLISHED:
 
 
@@ -119,6 +122,7 @@ PUBLISHED:
 
 
   INLINE size_t get_length() const;
   INLINE size_t get_length() const;
   INLINE std::string get_string() const;
   INLINE std::string get_string() const;
+  INLINE vector_uchar get_bytes() const;
   INLINE size_t get_unpack_length() const;
   INLINE size_t get_unpack_length() const;
   INLINE std::string get_unpack_string() const;
   INLINE std::string get_unpack_string() const;
 public:
 public:
@@ -126,7 +130,7 @@ public:
   INLINE const char *get_data() const;
   INLINE const char *get_data() const;
   INLINE char *take_data();
   INLINE char *take_data();
 
 
-  INLINE void append_data(const char *buffer, size_t size);
+  INLINE void append_data(const unsigned char *buffer, size_t size);
   INLINE char *get_write_pointer(size_t size);
   INLINE char *get_write_pointer(size_t size);
 
 
   INLINE const char *get_unpack_data() const;
   INLINE const char *get_unpack_data() const;
@@ -148,6 +152,7 @@ PUBLISHED:
   INLINE void raw_pack_uint64(uint64_t value);
   INLINE void raw_pack_uint64(uint64_t value);
   INLINE void raw_pack_float64(double value);
   INLINE void raw_pack_float64(double value);
   INLINE void raw_pack_string(const std::string &value);
   INLINE void raw_pack_string(const std::string &value);
+  INLINE void raw_pack_blob(const vector_uchar &value);
 
 
 // this is a hack to allw me to get in and out of 32bit Mode Faster need to
 // this is a hack to allw me to get in and out of 32bit Mode Faster need to
 // agree with channel_type in dcbase.h
 // agree with channel_type in dcbase.h
@@ -165,6 +170,7 @@ PUBLISHED:
   INLINE uint64_t raw_unpack_uint64();
   INLINE uint64_t raw_unpack_uint64();
   INLINE double raw_unpack_float64();
   INLINE double raw_unpack_float64();
   INLINE std::string raw_unpack_string();
   INLINE std::string raw_unpack_string();
+  INLINE vector_uchar raw_unpack_blob();
 
 
 public:
 public:
   INLINE void raw_unpack_int8(int &value);
   INLINE void raw_unpack_int8(int &value);
@@ -177,10 +183,11 @@ public:
   INLINE void raw_unpack_uint64(uint64_t &value);
   INLINE void raw_unpack_uint64(uint64_t &value);
   INLINE void raw_unpack_float64(double &value);
   INLINE void raw_unpack_float64(double &value);
   INLINE void raw_unpack_string(std::string &value);
   INLINE void raw_unpack_string(std::string &value);
+  INLINE void raw_unpack_blob(vector_uchar &value);
 
 
 public:
 public:
   static void enquote_string(std::ostream &out, char quote_mark, const std::string &str);
   static void enquote_string(std::ostream &out, char quote_mark, const std::string &str);
-  static void output_hex_string(std::ostream &out, const std::string &str);
+  static void output_hex_string(std::ostream &out, const vector_uchar &str);
 
 
 private:
 private:
   INLINE void advance();
   INLINE void advance();

+ 16 - 0
direct/src/dcparser/dcPackerInterface.cxx

@@ -248,6 +248,14 @@ pack_string(DCPackData &, const string &, bool &pack_error, bool &) const {
   pack_error = true;
   pack_error = true;
 }
 }
 
 
+/**
+ * Packs the indicated numeric or string value into the stream.
+ */
+void DCPackerInterface::
+pack_blob(DCPackData &, const vector_uchar &, bool &pack_error, bool &) const {
+  pack_error = true;
+}
+
 /**
 /**
  * Packs the field's specified default value (or a sensible default if no
  * Packs the field's specified default value (or a sensible default if no
  * value is specified) into the stream.  Returns true if the default value is
  * value is specified) into the stream.  Returns true if the default value is
@@ -306,6 +314,14 @@ unpack_string(const char *, size_t, size_t &, string &, bool &pack_error, bool &
   pack_error = true;
   pack_error = true;
 }
 }
 
 
+/**
+ * Unpacks the current numeric or string value from the stream.
+ */
+void DCPackerInterface::
+unpack_blob(const char *, size_t, size_t &, vector_uchar &, bool &pack_error, bool &) const {
+  pack_error = true;
+}
+
 /**
 /**
  * Internally unpacks the current numeric or string value and validates it
  * Internally unpacks the current numeric or string value and validates it
  * against the type range limits, but does not return the value.  Returns true
  * against the type range limits, but does not return the value.  Returns true

+ 7 - 2
direct/src/dcparser/dcPackerInterface.h

@@ -16,6 +16,7 @@
 
 
 #include "dcbase.h"
 #include "dcbase.h"
 #include "dcSubatomicType.h"
 #include "dcSubatomicType.h"
+#include "vector_uchar.h"
 
 
 class DCFile;
 class DCFile;
 class DCField;
 class DCField;
@@ -37,8 +38,8 @@ enum DCPackType {
 
 
   // These PackTypes are all fundamental types, and should be packed (or
   // These PackTypes are all fundamental types, and should be packed (or
   // unpacked) with the corresponding call to pack_double(), pack_int(), etc.
   // unpacked) with the corresponding call to pack_double(), pack_int(), etc.
-  // PT_blob is the same as PT_string, but implies that the string contains
-  // binary data.
+  // PT_blob is similar to PT_string, except that it contains arbitrary binary
+  // data instead of just UTF-8 text.
   PT_double,
   PT_double,
   PT_int,
   PT_int,
   PT_uint,
   PT_uint,
@@ -113,6 +114,8 @@ public:
                            bool &pack_error, bool &range_error) const;
                            bool &pack_error, bool &range_error) const;
   virtual void pack_string(DCPackData &pack_data, const std::string &value,
   virtual void pack_string(DCPackData &pack_data, const std::string &value,
                            bool &pack_error, bool &range_error) const;
                            bool &pack_error, bool &range_error) const;
+  virtual void pack_blob(DCPackData &pack_data, const vector_uchar &value,
+                         bool &pack_error, bool &range_error) const;
   virtual bool pack_default_value(DCPackData &pack_data, bool &pack_error) const;
   virtual bool pack_default_value(DCPackData &pack_data, bool &pack_error) const;
 
 
   virtual void unpack_double(const char *data, size_t length, size_t &p,
   virtual void unpack_double(const char *data, size_t length, size_t &p,
@@ -127,6 +130,8 @@ public:
                              uint64_t &value, bool &pack_error, bool &range_error) const;
                              uint64_t &value, bool &pack_error, bool &range_error) const;
   virtual void unpack_string(const char *data, size_t length, size_t &p,
   virtual void unpack_string(const char *data, size_t length, size_t &p,
                              std::string &value, bool &pack_error, bool &range_error) const;
                              std::string &value, bool &pack_error, bool &range_error) const;
+  virtual void unpack_blob(const char *data, size_t length, size_t &p,
+                           vector_uchar &value, bool &pack_error, bool &range_error) const;
   virtual bool unpack_validate(const char *data, size_t length, size_t &p,
   virtual bool unpack_validate(const char *data, size_t length, size_t &p,
                                bool &pack_error, bool &range_error) const;
                                bool &pack_error, bool &range_error) const;
   virtual bool unpack_skip(const char *data, size_t length, size_t &p,
   virtual bool unpack_skip(const char *data, size_t length, size_t &p,

File diff suppressed because it is too large
+ 430 - 543
direct/src/dcparser/dcParser.cxx.prebuilt


+ 66 - 63
direct/src/dcparser/dcParser.h.prebuilt

@@ -1,20 +1,19 @@
-/* A Bison parser, made by GNU Bison 2.4.2.  */
+/* A Bison parser, made by GNU Bison 3.0.4.  */
+
+/* Bison interface for Yacc-like parsers in C
+
+   Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc.
 
 
-/* Skeleton interface for Bison's Yacc-like parsers in C
-   
-      Copyright (C) 1984, 1989-1990, 2000-2006, 2009-2010 Free Software
-   Foundation, Inc.
-   
    This program is free software: you can redistribute it and/or modify
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.
    (at your option) any later version.
-   
+
    This program is distributed in the hope that it will be useful,
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
    GNU General Public License for more details.
-   
+
    You should have received a copy of the GNU General Public License
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 
@@ -27,66 +26,74 @@
    special exception, which will cause the skeleton and the resulting
    special exception, which will cause the skeleton and the resulting
    Bison output files to be licensed under the GNU General Public
    Bison output files to be licensed under the GNU General Public
    License without this special exception.
    License without this special exception.
-   
+
    This special exception was added by the Free Software Foundation in
    This special exception was added by the Free Software Foundation in
    version 2.2 of Bison.  */
    version 2.2 of Bison.  */
 
 
+#ifndef YY_DCYY_BUILT_TMP_DCPARSER_YXX_H_INCLUDED
+# define YY_DCYY_BUILT_TMP_DCPARSER_YXX_H_INCLUDED
+/* Debug traces.  */
+#ifndef YYDEBUG
+# define YYDEBUG 0
+#endif
+#if YYDEBUG
+extern int dcyydebug;
+#endif
 
 
-/* Tokens.  */
+/* Token type.  */
 #ifndef YYTOKENTYPE
 #ifndef YYTOKENTYPE
 # define YYTOKENTYPE
 # define YYTOKENTYPE
-   /* Put the tokens into the symbol table, so that GDB and other debuggers
-      know about them.  */
-   enum yytokentype {
-     UNSIGNED_INTEGER = 258,
-     SIGNED_INTEGER = 259,
-     REAL = 260,
-     STRING = 261,
-     HEX_STRING = 262,
-     IDENTIFIER = 263,
-     KEYWORD = 264,
-     KW_DCLASS = 265,
-     KW_STRUCT = 266,
-     KW_FROM = 267,
-     KW_IMPORT = 268,
-     KW_TYPEDEF = 269,
-     KW_KEYWORD = 270,
-     KW_SWITCH = 271,
-     KW_CASE = 272,
-     KW_DEFAULT = 273,
-     KW_BREAK = 274,
-     KW_INT8 = 275,
-     KW_INT16 = 276,
-     KW_INT32 = 277,
-     KW_INT64 = 278,
-     KW_UINT8 = 279,
-     KW_UINT16 = 280,
-     KW_UINT32 = 281,
-     KW_UINT64 = 282,
-     KW_FLOAT64 = 283,
-     KW_STRING = 284,
-     KW_BLOB = 285,
-     KW_BLOB32 = 286,
-     KW_INT8ARRAY = 287,
-     KW_INT16ARRAY = 288,
-     KW_INT32ARRAY = 289,
-     KW_UINT8ARRAY = 290,
-     KW_UINT16ARRAY = 291,
-     KW_UINT32ARRAY = 292,
-     KW_UINT32UINT8ARRAY = 293,
-     KW_CHAR = 294,
-     START_DC = 295,
-     START_PARAMETER_VALUE = 296,
-     START_PARAMETER_DESCRIPTION = 297
-   };
+  enum yytokentype
+  {
+    UNSIGNED_INTEGER = 258,
+    SIGNED_INTEGER = 259,
+    REAL = 260,
+    STRING = 261,
+    IDENTIFIER = 262,
+    HEX_STRING = 263,
+    KEYWORD = 264,
+    KW_DCLASS = 265,
+    KW_STRUCT = 266,
+    KW_FROM = 267,
+    KW_IMPORT = 268,
+    KW_TYPEDEF = 269,
+    KW_KEYWORD = 270,
+    KW_SWITCH = 271,
+    KW_CASE = 272,
+    KW_DEFAULT = 273,
+    KW_BREAK = 274,
+    KW_INT8 = 275,
+    KW_INT16 = 276,
+    KW_INT32 = 277,
+    KW_INT64 = 278,
+    KW_UINT8 = 279,
+    KW_UINT16 = 280,
+    KW_UINT32 = 281,
+    KW_UINT64 = 282,
+    KW_FLOAT64 = 283,
+    KW_STRING = 284,
+    KW_BLOB = 285,
+    KW_BLOB32 = 286,
+    KW_INT8ARRAY = 287,
+    KW_INT16ARRAY = 288,
+    KW_INT32ARRAY = 289,
+    KW_UINT8ARRAY = 290,
+    KW_UINT16ARRAY = 291,
+    KW_UINT32ARRAY = 292,
+    KW_UINT32UINT8ARRAY = 293,
+    KW_CHAR = 294,
+    START_DC = 295,
+    START_PARAMETER_VALUE = 296,
+    START_PARAMETER_DESCRIPTION = 297
+  };
 #endif
 #endif
 /* Tokens.  */
 /* Tokens.  */
 #define UNSIGNED_INTEGER 258
 #define UNSIGNED_INTEGER 258
 #define SIGNED_INTEGER 259
 #define SIGNED_INTEGER 259
 #define REAL 260
 #define REAL 260
 #define STRING 261
 #define STRING 261
-#define HEX_STRING 262
-#define IDENTIFIER 263
+#define IDENTIFIER 262
+#define HEX_STRING 263
 #define KEYWORD 264
 #define KEYWORD 264
 #define KW_DCLASS 265
 #define KW_DCLASS 265
 #define KW_STRUCT 266
 #define KW_STRUCT 266
@@ -122,15 +129,11 @@
 #define START_PARAMETER_VALUE 296
 #define START_PARAMETER_VALUE 296
 #define START_PARAMETER_DESCRIPTION 297
 #define START_PARAMETER_DESCRIPTION 297
 
 
+/* Value type.  */
 
 
 
 
-
-#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
-
-# define yystype YYSTYPE /* obsolescent; will be withdrawn */
-# define YYSTYPE_IS_DECLARED 1
-#endif
-
 extern YYSTYPE dcyylval;
 extern YYSTYPE dcyylval;
 
 
+int dcyyparse (void);
 
 
+#endif /* !YY_DCYY_BUILT_TMP_DCPARSER_YXX_H_INCLUDED  */

+ 28 - 27
direct/src/dcparser/dcParser.yxx

@@ -57,7 +57,7 @@ dc_init_parser(istream &in, const string &filename, DCFile &file) {
 }
 }
 
 
 void
 void
-dc_init_parser_parameter_value(istream &in, const string &filename, 
+dc_init_parser_parameter_value(istream &in, const string &filename,
                                DCPacker &packer) {
                                DCPacker &packer) {
   dc_file = nullptr;
   dc_file = nullptr;
   current_packer = &packer;
   current_packer = &packer;
@@ -89,15 +89,16 @@ dc_cleanup_parser() {
 %token <u.uint64> UNSIGNED_INTEGER
 %token <u.uint64> UNSIGNED_INTEGER
 %token <u.int64> SIGNED_INTEGER
 %token <u.int64> SIGNED_INTEGER
 %token <u.real> REAL
 %token <u.real> REAL
-%token <str> STRING HEX_STRING IDENTIFIER
+%token <str> STRING IDENTIFIER
+%token <bytes> HEX_STRING
 %token <u.keyword> KEYWORD
 %token <u.keyword> KEYWORD
 
 
-%token KW_DCLASS 
-%token KW_STRUCT 
-%token KW_FROM 
-%token KW_IMPORT 
-%token KW_TYPEDEF 
-%token KW_KEYWORD 
+%token KW_DCLASS
+%token KW_STRUCT
+%token KW_FROM
+%token KW_IMPORT
+%token KW_TYPEDEF
+%token KW_KEYWORD
 %token KW_SWITCH
 %token KW_SWITCH
 %token KW_CASE
 %token KW_CASE
 %token KW_DEFAULT
 %token KW_DEFAULT
@@ -224,7 +225,7 @@ import:
 {
 {
   dc_file->add_import_module($2);
   dc_file->add_import_module($2);
 }
 }
-        | KW_FROM import_identifier KW_IMPORT 
+        | KW_FROM import_identifier KW_IMPORT
 {
 {
   dc_file->add_import_module($2);
   dc_file->add_import_module($2);
 }
 }
@@ -255,7 +256,7 @@ typedef_decl:
 {
 {
   if ($2 != nullptr) {
   if ($2 != nullptr) {
     DCTypedef *dtypedef = new DCTypedef($2);
     DCTypedef *dtypedef = new DCTypedef($2);
-    
+
     if (!dc_file->add_typedef(dtypedef)) {
     if (!dc_file->add_typedef(dtypedef)) {
       DCTypedef *old_typedef = dc_file->get_typedef_by_name(dtypedef->get_name());
       DCTypedef *old_typedef = dc_file->get_typedef_by_name(dtypedef->get_name());
       if (old_typedef->is_bogus_typedef()) {
       if (old_typedef->is_bogus_typedef()) {
@@ -294,7 +295,7 @@ dclass_or_struct:
         ;
         ;
 
 
 dclass:
 dclass:
-        KW_DCLASS optional_name 
+        KW_DCLASS optional_name
 {
 {
   current_class = new DCClass(dc_file, $2, false, false);
   current_class = new DCClass(dc_file, $2, false, false);
 }
 }
@@ -322,7 +323,7 @@ dclass_name:
     if (dclass->is_struct()) {
     if (dclass->is_struct()) {
       yyerror("struct name not allowed");
       yyerror("struct name not allowed");
     }
     }
-  
+
     $$ = dclass;
     $$ = dclass;
   }
   }
 }
 }
@@ -398,7 +399,7 @@ dclass_field:
         ;
         ;
 
 
 struct:
 struct:
-        KW_STRUCT optional_name 
+        KW_STRUCT optional_name
 {
 {
   current_class = new DCClass(dc_file, $2, true, false);
   current_class = new DCClass(dc_file, $2, true, false);
 }
 }
@@ -426,7 +427,7 @@ struct_name:
     if (!dstruct->is_struct()) {
     if (!dstruct->is_struct()) {
       yyerror("struct name required");
       yyerror("struct name required");
     }
     }
-  
+
     $$ = dstruct;
     $$ = dstruct;
   }
   }
 }
 }
@@ -538,7 +539,7 @@ unnamed_parameter:
 
 
 named_parameter_with_default:
 named_parameter_with_default:
         named_parameter
         named_parameter
-        | named_parameter '=' 
+        | named_parameter '='
 {
 {
   current_packer = &default_packer;
   current_packer = &default_packer;
   current_packer->clear_data();
   current_packer->clear_data();
@@ -553,7 +554,7 @@ named_parameter_with_default:
     is_valid = $1->is_valid();
     is_valid = $1->is_valid();
   }
   }
   if (current_packer->end_pack()) {
   if (current_packer->end_pack()) {
-    $1->set_default_value(current_packer->get_string());
+    $1->set_default_value(current_packer->get_bytes());
 
 
   } else {
   } else {
     if (is_valid) {
     if (is_valid) {
@@ -568,7 +569,7 @@ named_parameter_with_default:
 
 
 unnamed_parameter_with_default:
 unnamed_parameter_with_default:
         unnamed_parameter
         unnamed_parameter
-        | unnamed_parameter '=' 
+        | unnamed_parameter '='
 {
 {
   current_packer = &default_packer;
   current_packer = &default_packer;
   current_packer->clear_data();
   current_packer->clear_data();
@@ -583,7 +584,7 @@ unnamed_parameter_with_default:
     is_valid = $1->is_valid();
     is_valid = $1->is_valid();
   }
   }
   if (current_packer->end_pack()) {
   if (current_packer->end_pack()) {
-    $1->set_default_value(current_packer->get_string());
+    $1->set_default_value(current_packer->get_bytes());
 
 
   } else {
   } else {
     if (is_valid) {
     if (is_valid) {
@@ -663,7 +664,7 @@ simple_type_name:
   $$ = simple_param;
   $$ = simple_param;
 }
 }
         | simple_type_name '%' number
         | simple_type_name '%' number
-{ 
+{
   DCSimpleParameter *simple_param = $1->as_simple_parameter();
   DCSimpleParameter *simple_param = $1->as_simple_parameter();
   nassertr(simple_param != nullptr, 0);
   nassertr(simple_param != nullptr, 0);
   if (!simple_param->is_numeric_type()) {
   if (!simple_param->is_numeric_type()) {
@@ -703,10 +704,10 @@ type_name:
           dtypedef = new DCTypedef($1);
           dtypedef = new DCTypedef($1);
         }
         }
       }
       }
-      
+
       dc_file->add_typedef(dtypedef);
       dc_file->add_typedef(dtypedef);
     }
     }
-    
+
     $$ = dtypedef->make_new_parameter();
     $$ = dtypedef->make_new_parameter();
   }
   }
 }
 }
@@ -974,7 +975,7 @@ parameter_value:
 {
 {
   if ($1 != current_packer->get_current_field_name()) {
   if ($1 != current_packer->get_current_field_name()) {
     ostringstream strm;
     ostringstream strm;
-    strm << "Got '" << $1 << "', expected '" 
+    strm << "Got '" << $1 << "', expected '"
          << current_packer->get_current_field_name() << "'";
          << current_packer->get_current_field_name() << "'";
     yyerror(strm.str());
     yyerror(strm.str());
   }
   }
@@ -1005,7 +1006,7 @@ parameter_actual_value:
 {
 {
   current_packer->pack_literal_value($1);
   current_packer->pack_literal_value($1);
 }
 }
-        | '{' 
+        | '{'
 {
 {
   current_packer->push();
   current_packer->push();
 }
 }
@@ -1013,7 +1014,7 @@ parameter_actual_value:
 {
 {
   current_packer->pop();
   current_packer->pop();
 }
 }
-        | '[' 
+        | '['
 {
 {
   current_packer->push();
   current_packer->push();
 }
 }
@@ -1021,7 +1022,7 @@ parameter_actual_value:
 {
 {
   current_packer->pop();
   current_packer->pop();
 }
 }
-        | '(' 
+        | '('
 {
 {
   current_packer->push();
   current_packer->push();
 }
 }
@@ -1223,7 +1224,7 @@ molecular_atom_list:
   if ($3 != nullptr) {
   if ($3 != nullptr) {
     current_molecular->add_atomic($3);
     current_molecular->add_atomic($3);
     if (!$3->is_bogus_field() && !current_molecular->compare_keywords(*$3)) {
     if (!$3->is_bogus_field() && !current_molecular->compare_keywords(*$3)) {
-      yyerror("Mismatched keywords in molecule between " + 
+      yyerror("Mismatched keywords in molecule between " +
               current_molecular->get_atomic(0)->get_name() + " and " +
               current_molecular->get_atomic(0)->get_name() + " and " +
               $3->get_name());
               $3->get_name());
     }
     }
@@ -1283,7 +1284,7 @@ switch_case:
     yyerror("Invalid value for switch parameter");
     yyerror("Invalid value for switch parameter");
     current_switch->add_invalid_case();
     current_switch->add_invalid_case();
   } else {
   } else {
-    int case_index = current_switch->add_case(current_packer->get_string());
+    int case_index = current_switch->add_case(current_packer->get_bytes());
     if (case_index == -1) {
     if (case_index == -1) {
       yyerror("Duplicate case value");
       yyerror("Duplicate case value");
     }
     }

+ 2 - 0
direct/src/dcparser/dcParserDefs.h

@@ -16,6 +16,7 @@
 
 
 #include "dcbase.h"
 #include "dcbase.h"
 #include "dcSubatomicType.h"
 #include "dcSubatomicType.h"
+#include "vector_uchar.h"
 
 
 class DCFile;
 class DCFile;
 class DCClass;
 class DCClass;
@@ -61,6 +62,7 @@ public:
     const DCKeyword *keyword;
     const DCKeyword *keyword;
   } u;
   } u;
   std::string str;
   std::string str;
+  vector_uchar bytes;
 };
 };
 
 
 // The yacc-generated code expects to use the symbol 'YYSTYPE' to refer to the
 // The yacc-generated code expects to use the symbol 'YYSTYPE' to refer to the

+ 119 - 0
direct/src/dcparser/dcSimpleParameter.cxx

@@ -1069,6 +1069,52 @@ pack_string(DCPackData &pack_data, const string &value,
   }
   }
 }
 }
 
 
+/**
+ * Packs the indicated numeric or string value into the stream.
+ */
+void DCSimpleParameter::
+pack_blob(DCPackData &pack_data, const vector_uchar &value,
+          bool &pack_error, bool &range_error) const {
+  size_t blob_size = value.size();
+
+  switch (_type) {
+  case ST_char:
+  case ST_uint8:
+  case ST_int8:
+    if (blob_size == 0) {
+      pack_error = true;
+    } else {
+      if (blob_size != 1) {
+        range_error = true;
+      }
+      _uint_range.validate((unsigned int)value[0], range_error);
+      do_pack_uint8(pack_data.get_write_pointer(1), (unsigned int)value[0]);
+    }
+    break;
+
+  case ST_string:
+  case ST_blob:
+    _uint_range.validate(blob_size, range_error);
+    validate_uint_limits(blob_size, 16, range_error);
+    if (_num_length_bytes != 0) {
+      do_pack_uint16(pack_data.get_write_pointer(2), blob_size);
+    }
+    pack_data.append_data((const char *)value.data(), blob_size);
+    break;
+
+  case ST_blob32:
+    _uint_range.validate(blob_size, range_error);
+    if (_num_length_bytes != 0) {
+      do_pack_uint32(pack_data.get_write_pointer(4), blob_size);
+    }
+    pack_data.append_data((const char *)value.data(), blob_size);
+    break;
+
+  default:
+    pack_error = true;
+  }
+}
+
 /**
 /**
  * Packs the simpleParameter's specified default value (or a sensible default
  * Packs the simpleParameter's specified default value (or a sensible default
  * if no value is specified) into the stream.  Returns true if the default
  * if no value is specified) into the stream.  Returns true if the default
@@ -1937,6 +1983,79 @@ unpack_string(const char *data, size_t length, size_t &p, string &value,
   return;
   return;
 }
 }
 
 
+/**
+ * Unpacks the current numeric or string value from the stream.
+ */
+void DCSimpleParameter::
+unpack_blob(const char *data, size_t length, size_t &p, vector_uchar &value,
+            bool &pack_error, bool &range_error) const {
+  // If the type is a single byte, unpack it into a string of length 1.
+  switch (_type) {
+  case ST_char:
+  case ST_int8:
+  case ST_uint8:
+    {
+      if (p + 1 > length) {
+        pack_error = true;
+        return;
+      }
+      unsigned int int_value = do_unpack_uint8(data + p);
+      _uint_range.validate(int_value, range_error);
+      value.resize(1);
+      value[0] = int_value;
+      p++;
+    }
+    return;
+
+  default:
+    break;
+  }
+
+  size_t blob_size;
+
+  if (_num_length_bytes == 0) {
+    blob_size = _fixed_byte_size;
+
+  } else {
+    switch (_type) {
+    case ST_string:
+    case ST_blob:
+      if (p + 2 > length) {
+        pack_error = true;
+        return;
+      }
+      blob_size = do_unpack_uint16(data + p);
+      p += 2;
+      break;
+
+    case ST_blob32:
+      if (p + 4 > length) {
+        pack_error = true;
+        return;
+      }
+      blob_size = do_unpack_uint32(data + p);
+      p += 4;
+      break;
+
+    default:
+      pack_error = true;
+      return;
+    }
+  }
+
+  _uint_range.validate(blob_size, range_error);
+
+  if (p + blob_size > length) {
+    pack_error = true;
+    return;
+  }
+  value = vector_uchar((const unsigned char *)data + p,
+                       (const unsigned char *)data + p + blob_size);
+  p += blob_size;
+
+  return;
+}
+
 /**
 /**
  * Internally unpacks the current numeric or string value and validates it
  * Internally unpacks the current numeric or string value and validates it
  * against the type range limits, but does not return the value.  Returns true
  * against the type range limits, but does not return the value.  Returns true

+ 4 - 0
direct/src/dcparser/dcSimpleParameter.h

@@ -62,6 +62,8 @@ public:
                            bool &pack_error, bool &range_error) const;
                            bool &pack_error, bool &range_error) const;
   virtual void pack_string(DCPackData &pack_data, const std::string &value,
   virtual void pack_string(DCPackData &pack_data, const std::string &value,
                            bool &pack_error, bool &range_error) const;
                            bool &pack_error, bool &range_error) const;
+  virtual void pack_blob(DCPackData &pack_data, const vector_uchar &value,
+                         bool &pack_error, bool &range_error) const;
   virtual bool pack_default_value(DCPackData &pack_data, bool &pack_error) const;
   virtual bool pack_default_value(DCPackData &pack_data, bool &pack_error) const;
 
 
   virtual void unpack_double(const char *data, size_t length, size_t &p,
   virtual void unpack_double(const char *data, size_t length, size_t &p,
@@ -76,6 +78,8 @@ public:
                              uint64_t &value, bool &pack_error, bool &range_error) const;
                              uint64_t &value, bool &pack_error, bool &range_error) const;
   virtual void unpack_string(const char *data, size_t length, size_t &p,
   virtual void unpack_string(const char *data, size_t length, size_t &p,
                              std::string &value, bool &pack_error, bool &range_error) const;
                              std::string &value, bool &pack_error, bool &range_error) const;
+  virtual void unpack_blob(const char *data, size_t length, size_t &p,
+                           vector_uchar &value, bool &pack_error, bool &range_error) const;
   virtual bool unpack_validate(const char *data, size_t length, size_t &p,
   virtual bool unpack_validate(const char *data, size_t length, size_t &p,
                                bool &pack_error, bool &range_error) const;
                                bool &pack_error, bool &range_error) const;
   virtual bool unpack_skip(const char *data, size_t length, size_t &p,
   virtual bool unpack_skip(const char *data, size_t length, size_t &p,

+ 8 - 7
direct/src/dcparser/dcSwitch.cxx

@@ -109,7 +109,7 @@ get_num_cases() const {
  * if no case has this value.
  * if no case has this value.
  */
  */
 int DCSwitch::
 int DCSwitch::
-get_case_by_value(const string &case_value) const {
+get_case_by_value(const vector_uchar &case_value) const {
   CasesByValue::const_iterator vi;
   CasesByValue::const_iterator vi;
   vi = _cases_by_value.find(case_value);
   vi = _cases_by_value.find(case_value);
   if (vi != _cases_by_value.end()) {
   if (vi != _cases_by_value.end()) {
@@ -140,9 +140,9 @@ get_default_case() const {
 /**
 /**
  * Returns the packed value associated with the indicated case.
  * Returns the packed value associated with the indicated case.
  */
  */
-string DCSwitch::
+vector_uchar DCSwitch::
 get_value(int case_index) const {
 get_value(int case_index) const {
-  nassertr(case_index >= 0 && case_index < (int)_cases.size(), string());
+  nassertr(case_index >= 0 && case_index < (int)_cases.size(), vector_uchar());
   return _cases[case_index]->_value;
   return _cases[case_index]->_value;
 }
 }
 
 
@@ -198,7 +198,7 @@ is_field_valid() const {
  * -1. This is normally called only by the parser.
  * -1. This is normally called only by the parser.
  */
  */
 int DCSwitch::
 int DCSwitch::
-add_case(const string &value) {
+add_case(const vector_uchar &value) {
   int case_index = (int)_cases.size();
   int case_index = (int)_cases.size();
   if (!_cases_by_value.insert(CasesByValue::value_type(value, case_index)).second) {
   if (!_cases_by_value.insert(CasesByValue::value_type(value, case_index)).second) {
     add_invalid_case();
     add_invalid_case();
@@ -283,7 +283,8 @@ add_break() {
 const DCPackerInterface *DCSwitch::
 const DCPackerInterface *DCSwitch::
 apply_switch(const char *value_data, size_t length) const {
 apply_switch(const char *value_data, size_t length) const {
   CasesByValue::const_iterator vi;
   CasesByValue::const_iterator vi;
-  vi = _cases_by_value.find(string(value_data, length));
+  vi = _cases_by_value.find(vector_uchar((const unsigned char *)value_data,
+                                         (const unsigned char *)value_data + length));
   if (vi != _cases_by_value.end()) {
   if (vi != _cases_by_value.end()) {
     return _cases[(*vi).second]->_fields;
     return _cases[(*vi).second]->_fields;
   }
   }
@@ -421,7 +422,7 @@ generate_hash(HashGenerator &hashgen) const {
   Cases::const_iterator ci;
   Cases::const_iterator ci;
   for (ci = _cases.begin(); ci != _cases.end(); ++ci) {
   for (ci = _cases.begin(); ci != _cases.end(); ++ci) {
     const SwitchCase *dcase = (*ci);
     const SwitchCase *dcase = (*ci);
-    hashgen.add_string(dcase->_value);
+    hashgen.add_blob(dcase->_value);
 
 
     const SwitchFields *fields = dcase->_fields;
     const SwitchFields *fields = dcase->_fields;
     hashgen.add_int(fields->_fields.size());
     hashgen.add_int(fields->_fields.size());
@@ -702,7 +703,7 @@ do_check_match(const DCPackerInterface *) const {
  *
  *
  */
  */
 DCSwitch::SwitchCase::
 DCSwitch::SwitchCase::
-SwitchCase(const string &value, DCSwitch::SwitchFields *fields) :
+SwitchCase(const vector_uchar &value, DCSwitch::SwitchFields *fields) :
   _value(value),
   _value(value),
   _fields(fields)
   _fields(fields)
 {
 {

+ 6 - 6
direct/src/dcparser/dcSwitch.h

@@ -40,18 +40,18 @@ PUBLISHED:
   DCField *get_key_parameter() const;
   DCField *get_key_parameter() const;
 
 
   int get_num_cases() const;
   int get_num_cases() const;
-  int get_case_by_value(const std::string &case_value) const;
+  int get_case_by_value(const vector_uchar &case_value) const;
   DCPackerInterface *get_case(int n) const;
   DCPackerInterface *get_case(int n) const;
   DCPackerInterface *get_default_case() const;
   DCPackerInterface *get_default_case() const;
 
 
-  std::string get_value(int case_index) const;
+  vector_uchar get_value(int case_index) const;
   int get_num_fields(int case_index) const;
   int get_num_fields(int case_index) const;
   DCField *get_field(int case_index, int n) const;
   DCField *get_field(int case_index, int n) const;
   DCField *get_field_by_name(int case_index, const std::string &name) const;
   DCField *get_field_by_name(int case_index, const std::string &name) const;
 
 
 public:
 public:
   bool is_field_valid() const;
   bool is_field_valid() const;
-  int add_case(const std::string &value);
+  int add_case(const vector_uchar &value);
   void add_invalid_case();
   void add_invalid_case();
   bool add_default();
   bool add_default();
   bool add_field(DCField *field);
   bool add_field(DCField *field);
@@ -98,13 +98,13 @@ public:
 
 
   class SwitchCase {
   class SwitchCase {
   public:
   public:
-    SwitchCase(const std::string &value, SwitchFields *fields);
+    SwitchCase(const vector_uchar &value, SwitchFields *fields);
     ~SwitchCase();
     ~SwitchCase();
 
 
     bool do_check_match_switch_case(const SwitchCase *other) const;
     bool do_check_match_switch_case(const SwitchCase *other) const;
 
 
   public:
   public:
-    std::string _value;
+    vector_uchar _value;
     SwitchFields *_fields;
     SwitchFields *_fields;
   };
   };
 
 
@@ -137,7 +137,7 @@ private:
   bool _fields_added;
   bool _fields_added;
 
 
   // This map indexes into the _cases vector, above.
   // This map indexes into the _cases vector, above.
-  typedef pmap<std::string, int> CasesByValue;
+  typedef pmap<vector_uchar, int> CasesByValue;
   CasesByValue _cases_by_value;
   CasesByValue _cases_by_value;
 };
 };
 
 

+ 12 - 0
direct/src/dcparser/hashGenerator.cxx

@@ -56,6 +56,18 @@ add_string(const std::string &str) {
   }
   }
 }
 }
 
 
+/**
+ * Adds a blob to the hash, by breaking it down into a sequence of integers.
+ */
+void HashGenerator::
+add_blob(const vector_uchar &bytes) {
+  add_int(bytes.size());
+  vector_uchar::const_iterator bi;
+  for (bi = bytes.begin(); bi != bytes.end(); ++bi) {
+    add_int(*bi);
+  }
+}
+
 /**
 /**
  * Returns the hash number generated.
  * Returns the hash number generated.
  */
  */

+ 2 - 0
direct/src/dcparser/hashGenerator.h

@@ -16,6 +16,7 @@
 
 
 #include "dcbase.h"
 #include "dcbase.h"
 #include "primeNumberGenerator.h"
 #include "primeNumberGenerator.h"
+#include "vector_uchar.h"
 
 
 /**
 /**
  * This class generates an arbitrary hash number from a sequence of ints.
  * This class generates an arbitrary hash number from a sequence of ints.
@@ -26,6 +27,7 @@ public:
 
 
   void add_int(int num);
   void add_int(int num);
   void add_string(const std::string &str);
   void add_string(const std::string &str);
+  void add_blob(const vector_uchar &bytes);
 
 
   unsigned long get_hash() const;
   unsigned long get_hash() const;
 
 

+ 1 - 1
direct/src/distributed/cConnectionRepository.cxx

@@ -891,7 +891,7 @@ describe_message(std::ostream &out, const string &prefix,
                  const Datagram &dg) const {
                  const Datagram &dg) const {
   DCPacker packer;
   DCPacker packer;
 
 
-  packer.set_unpack_data(dg.get_message());
+  packer.set_unpack_data((const char *)dg.get_data(), dg.get_length(), false);
   CHANNEL_TYPE do_id;
   CHANNEL_TYPE do_id;
   int msg_type;
   int msg_type;
   bool is_update = false;
   bool is_update = false;

Some files were not shown because too many files changed in this diff