dcparser: use vector_uchar for blobs, step towards Python 3 compat
Closes #298
This commit is contained in:
parent
840f28ef18
commit
e4f493b872
|
|
@ -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
|
||||
* 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
|
||||
* is, a uint32 only matches a uint32, etc. Names of components, and range
|
||||
|
|
|
|||
|
|
@ -51,9 +51,13 @@ public:
|
|||
virtual void generate_hash(HashGenerator &hashgen) const;
|
||||
virtual void pack_string(DCPackData &pack_data, const std::string &value,
|
||||
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 void unpack_string(const char *data, size_t length, size_t &p,
|
||||
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:
|
||||
virtual bool do_check_match(const DCPackerInterface *other) const;
|
||||
|
|
|
|||
|
|
@ -88,11 +88,11 @@ get_element(int n) const {
|
|||
* If the element is an array-type element, the returned value will include
|
||||
* 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 {
|
||||
nassertr(n >= 0 && n < (int)_elements.size(), string());
|
||||
nassertr(n >= 0 && n < (int)_elements.size(), vector_uchar());
|
||||
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,
|
||||
* false otherwise.
|
||||
*
|
||||
* This is deprecated; use get_element() instead.
|
||||
* @deprecated use get_element() instead.
|
||||
*/
|
||||
bool DCAtomicField::
|
||||
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
|
||||
* 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::
|
||||
get_element_name(int n) const {
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ PUBLISHED:
|
|||
DCParameter *get_element(int n) const;
|
||||
|
||||
// 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;
|
||||
std::string get_element_name(int n) const;
|
||||
DCSubatomicType get_element_type(int n) const;
|
||||
|
|
|
|||
|
|
@ -587,7 +587,7 @@ receive_update_other(PyObject *distobj, DatagramIterator &di) const {
|
|||
*/
|
||||
void DCClass::
|
||||
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);
|
||||
nassertv_always(field != nullptr);
|
||||
|
||||
|
|
@ -606,7 +606,14 @@ direct_update(PyObject *distobj, const string &field_name,
|
|||
void DCClass::
|
||||
direct_update(PyObject *distobj, const string &field_name,
|
||||
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
|
||||
|
||||
|
|
|
|||
|
|
@ -95,7 +95,7 @@ PUBLISHED:
|
|||
void receive_update_other(PyObject *distobj, DatagramIterator &di) const;
|
||||
|
||||
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,
|
||||
const Datagram &datagram);
|
||||
bool pack_required_field(Datagram &datagram, PyObject *distobj,
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ has_default_value() const {
|
|||
* explicitly set (e.g. has_default_value() returns true), returns that
|
||||
* value; otherwise, returns an implicit default for the field.
|
||||
*/
|
||||
INLINE const std::string &DCField::
|
||||
INLINE const vector_uchar &DCField::
|
||||
get_default_value() const {
|
||||
if (_default_value_stale) {
|
||||
((DCField *)this)->refresh_default_value();
|
||||
|
|
@ -172,8 +172,8 @@ set_class(DCClass *dclass) {
|
|||
* Establishes a default value for this field.
|
||||
*/
|
||||
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;
|
||||
_default_value_stale = false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -162,7 +162,7 @@ as_parameter() const {
|
|||
* is an error.
|
||||
*/
|
||||
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;
|
||||
packer.set_unpack_data(packed_data);
|
||||
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
|
||||
* the corresponding packed data. Returns empty string if there is an error.
|
||||
*/
|
||||
string DCField::
|
||||
vector_uchar DCField::
|
||||
parse_string(const string &formatted_string) {
|
||||
DCPacker packer;
|
||||
packer.begin_pack(this);
|
||||
if (!packer.parse_and_pack(formatted_string)) {
|
||||
// Parse error.
|
||||
return string();
|
||||
return vector_uchar();
|
||||
}
|
||||
if (!packer.end_pack()) {
|
||||
// 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.
|
||||
*/
|
||||
bool DCField::
|
||||
validate_ranges(const string &packed_data) const {
|
||||
validate_ranges(const vector_uchar &packed_data) const {
|
||||
DCPacker packer;
|
||||
packer.set_unpack_data(packed_data);
|
||||
packer.begin_unpack(this);
|
||||
|
|
@ -209,7 +209,7 @@ validate_ranges(const string &packed_data) const {
|
|||
return false;
|
||||
}
|
||||
|
||||
return (packer.get_num_unpacked_bytes() == packed_data.length());
|
||||
return (packer.get_num_unpacked_bytes() == packed_data.size());
|
||||
}
|
||||
|
||||
#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;
|
||||
// otherwise, to return false and let the packer visit our nested elements.
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
@ -566,7 +566,8 @@ refresh_default_value() {
|
|||
if (!packer.end_pack()) {
|
||||
std::cerr << "Error while packing default value for " << get_name() << "\n";
|
||||
} 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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -53,13 +53,13 @@ PUBLISHED:
|
|||
virtual DCParameter *as_parameter();
|
||||
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 const std::string &get_default_value() const;
|
||||
INLINE const vector_uchar &get_default_value() const;
|
||||
|
||||
INLINE bool is_bogus_field() const;
|
||||
|
||||
|
|
@ -98,7 +98,7 @@ public:
|
|||
|
||||
INLINE void set_number(int number);
|
||||
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
|
||||
static std::string get_pystr(PyObject *value);
|
||||
|
|
@ -115,7 +115,7 @@ protected:
|
|||
bool _bogus_field;
|
||||
|
||||
private:
|
||||
std::string _default_value;
|
||||
vector_uchar _default_value;
|
||||
|
||||
#ifdef WITHIN_PANDA
|
||||
PStatCollector _field_update_pcollector;
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
// Filename: dcLexer.lxx
|
||||
// Created by: drose (05Oct00)
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
*/
|
||||
|
||||
|
|
@ -103,12 +103,12 @@ dcyyerror(const std::string &msg) {
|
|||
if (!dc_filename.empty()) {
|
||||
cerr << " in " << dc_filename;
|
||||
}
|
||||
cerr
|
||||
cerr
|
||||
<< " at line " << line_number << ", column " << col_number << ":\n"
|
||||
<< current_line << "\n";
|
||||
indent(cerr, col_number-1)
|
||||
indent(cerr, col_number-1)
|
||||
<< "^\n" << msg << "\n\n";
|
||||
|
||||
|
||||
error_count++;
|
||||
}
|
||||
|
||||
|
|
@ -120,10 +120,10 @@ dcyywarning(const std::string &msg) {
|
|||
if (!dc_filename.empty()) {
|
||||
cerr << " in " << dc_filename;
|
||||
}
|
||||
cerr
|
||||
cerr
|
||||
<< " at line " << line_number << ", column " << col_number << ":\n"
|
||||
<< current_line << "\n";
|
||||
indent(cerr, col_number-1)
|
||||
indent(cerr, col_number-1)
|
||||
<< "^\n" << msg << "\n\n";
|
||||
|
||||
warning_count++;
|
||||
|
|
@ -313,9 +313,9 @@ scan_quoted_string(char quote_mark) {
|
|||
|
||||
// scan_hex_string reads a string of hexadecimal digits delimited by
|
||||
// angle brackets and returns the representative string.
|
||||
static std::string
|
||||
static vector_uchar
|
||||
scan_hex_string() {
|
||||
std::string result;
|
||||
vector_uchar result;
|
||||
|
||||
// We don't touch the current line number and column number during
|
||||
// scanning, so that if we detect an error while scanning the string
|
||||
|
|
@ -345,24 +345,24 @@ scan_hex_string() {
|
|||
line_number = line;
|
||||
col_number = col;
|
||||
dcyyerror("Invalid hex digit.");
|
||||
return std::string();
|
||||
return vector_uchar();
|
||||
}
|
||||
|
||||
odd = !odd;
|
||||
if (odd) {
|
||||
last = value;
|
||||
} else {
|
||||
result += (char)((last << 4) | value);
|
||||
result.push_back((unsigned char)((last << 4) | value));
|
||||
}
|
||||
c = read_char(line, col);
|
||||
}
|
||||
|
||||
if (c == EOF) {
|
||||
dcyyerror("This hex string is unterminated.");
|
||||
return std::string();
|
||||
return vector_uchar();
|
||||
} else if (odd) {
|
||||
dcyyerror("Odd number of hex digits.");
|
||||
return std::string();
|
||||
return vector_uchar();
|
||||
}
|
||||
|
||||
line_number = line;
|
||||
|
|
@ -382,7 +382,7 @@ eat_c_comment() {
|
|||
int col = col_number;
|
||||
|
||||
int c, last_c;
|
||||
|
||||
|
||||
last_c = '\0';
|
||||
c = read_char(line, col);
|
||||
while (c != EOF && !(last_c == '*' && c == '/')) {
|
||||
|
|
@ -440,12 +440,12 @@ REALNUM ([+-]?(([0-9]+[.])|([0-9]*[.][0-9]+))([eE][+-]?[0-9]+)?)
|
|||
yyless(1);
|
||||
}
|
||||
|
||||
[ \t\r] {
|
||||
[ \t\r] {
|
||||
// Eat whitespace.
|
||||
accept();
|
||||
}
|
||||
|
||||
"//".* {
|
||||
"//".* {
|
||||
// Eat C++-style comments.
|
||||
accept();
|
||||
}
|
||||
|
|
@ -453,7 +453,7 @@ REALNUM ([+-]?(([0-9]+[.])|([0-9]*[.][0-9]+))([eE][+-]?[0-9]+)?)
|
|||
"/*" {
|
||||
// Eat C-style comments.
|
||||
accept();
|
||||
eat_c_comment();
|
||||
eat_c_comment();
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -607,7 +607,7 @@ REALNUM ([+-]?(([0-9]+[.])|([0-9]*[.][0-9]+))([eE][+-]?[0-9]+)?)
|
|||
return KW_CHAR;
|
||||
}
|
||||
|
||||
{UNSIGNED_INTEGERNUM} {
|
||||
{UNSIGNED_INTEGERNUM} {
|
||||
// An unsigned integer number.
|
||||
accept();
|
||||
|
||||
|
|
@ -626,11 +626,11 @@ REALNUM ([+-]?(([0-9]+[.])|([0-9]*[.][0-9]+))([eE][+-]?[0-9]+)?)
|
|||
dcyylval.u.uint64 = next_value + (*p - '0');
|
||||
++p;
|
||||
}
|
||||
|
||||
|
||||
return UNSIGNED_INTEGER;
|
||||
}
|
||||
|
||||
{SIGNED_INTEGERNUM} {
|
||||
{SIGNED_INTEGERNUM} {
|
||||
// A signed integer number.
|
||||
accept();
|
||||
|
||||
|
|
@ -671,14 +671,14 @@ REALNUM ([+-]?(([0-9]+[.])|([0-9]*[.][0-9]+))([eE][+-]?[0-9]+)?)
|
|||
dcyyerror("Number out of range.");
|
||||
dcyylval.u.int64 = 1;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return SIGNED_INTEGER;
|
||||
}
|
||||
|
||||
{UNSIGNED_HEXNUM} {
|
||||
// A hexadecimal integer number.
|
||||
accept();
|
||||
accept();
|
||||
|
||||
// As above, we'll decode the hex string by hand.
|
||||
dcyylval.str = dcyytext;
|
||||
|
|
@ -700,15 +700,15 @@ REALNUM ([+-]?(([0-9]+[.])|([0-9]*[.][0-9]+))([eE][+-]?[0-9]+)?)
|
|||
++p;
|
||||
}
|
||||
|
||||
return UNSIGNED_INTEGER;
|
||||
return UNSIGNED_INTEGER;
|
||||
}
|
||||
|
||||
{REALNUM} {
|
||||
{REALNUM} {
|
||||
// A floating-point number.
|
||||
accept();
|
||||
dcyylval.u.real = patof(dcyytext);
|
||||
accept();
|
||||
dcyylval.u.real = patof(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.
|
||||
accept();
|
||||
dcyylval.str = scan_hex_string();
|
||||
dcyylval.bytes = scan_hex_string();
|
||||
return HEX_STRING;
|
||||
}
|
||||
|
||||
[A-Za-z_][A-Za-z_0-9]* {
|
||||
[A-Za-z_][A-Za-z_0-9]* {
|
||||
// Identifier or keyword.
|
||||
accept();
|
||||
dcyylval.str = dcyytext;
|
||||
|
|
@ -750,7 +750,7 @@ REALNUM ([+-]?(([0-9]+[.])|([0-9]*[.][0-9]+))([eE][+-]?[0-9]+)?)
|
|||
|
||||
. {
|
||||
// Send any other printable character as itself.
|
||||
accept();
|
||||
accept();
|
||||
return dcyytext[0];
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -217,16 +217,30 @@ pack_string(const std::string &value) {
|
|||
}
|
||||
|
||||
/**
|
||||
* Adds the indicated string value into the stream, representing a single pre-
|
||||
* packed field element, or a whole group of field elements at once.
|
||||
* Packs the indicated numeric or string value into the stream.
|
||||
*/
|
||||
INLINE void DCPacker::
|
||||
pack_literal_value(const std::string &value) {
|
||||
pack_blob(const vector_uchar &value) {
|
||||
nassertv(_mode == M_pack || _mode == M_repack);
|
||||
if (_current_field == nullptr) {
|
||||
_pack_error = true;
|
||||
} else {
|
||||
_pack_data.append_data(value.data(), value.length());
|
||||
_current_field->pack_blob(_pack_data, value, _pack_error, _range_error);
|
||||
advance();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the indicated string value into the stream, representing a single pre-
|
||||
* packed field element, or a whole group of field elements at once.
|
||||
*/
|
||||
INLINE void DCPacker::
|
||||
pack_literal_value(const vector_uchar &value) {
|
||||
nassertv(_mode == M_pack || _mode == M_repack);
|
||||
if (_current_field == nullptr) {
|
||||
_pack_error = true;
|
||||
} else {
|
||||
_pack_data.append_data((const char *)value.data(), value.size());
|
||||
advance();
|
||||
}
|
||||
}
|
||||
|
|
@ -345,16 +359,36 @@ unpack_string() {
|
|||
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
|
||||
* field, and advances the field pointer.
|
||||
*/
|
||||
INLINE std::string DCPacker::
|
||||
INLINE vector_uchar DCPacker::
|
||||
unpack_literal_value() {
|
||||
size_t start = _unpack_p;
|
||||
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
|
||||
* field, and advances the field pointer.
|
||||
*/
|
||||
INLINE void DCPacker::
|
||||
unpack_literal_value(std::string &value) {
|
||||
unpack_literal_value(vector_uchar &value) {
|
||||
size_t start = _unpack_p;
|
||||
unpack_skip();
|
||||
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();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
* buffer used when unpacking; it is separate from the pack data returned by
|
||||
|
|
@ -601,9 +661,9 @@ take_data() {
|
|||
* between packing sessions.
|
||||
*/
|
||||
INLINE void DCPacker::
|
||||
append_data(const char *buffer, size_t size) {
|
||||
append_data(const unsigned char *buffer, size_t size) {
|
||||
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());
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
|
@ -870,6 +940,16 @@ raw_unpack_string() {
|
|||
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.
|
||||
*/
|
||||
|
|
@ -971,6 +1051,24 @@ raw_unpack_string(std::string &value) {
|
|||
_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().
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -114,12 +114,12 @@ end_pack() {
|
|||
* version of begin_unpack() that takes only one parameter.
|
||||
*/
|
||||
void DCPacker::
|
||||
set_unpack_data(const string &data) {
|
||||
set_unpack_data(const vector_uchar &data) {
|
||||
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));
|
||||
}
|
||||
} else if (PyBytes_Check(object)) {
|
||||
char *buffer;
|
||||
const unsigned char *buffer;
|
||||
Py_ssize_t length;
|
||||
PyBytes_AsStringAndSize(object, &buffer, &length);
|
||||
PyBytes_AsStringAndSize(object, (char **)&buffer, &length);
|
||||
if (buffer) {
|
||||
pack_string(string(buffer, length));
|
||||
pack_blob(vector_uchar(buffer, buffer + length));
|
||||
}
|
||||
#else
|
||||
} 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.
|
||||
*/
|
||||
void DCPacker::
|
||||
output_hex_string(ostream &out, const string &str) {
|
||||
output_hex_string(ostream &out, const vector_uchar &str) {
|
||||
out << '<';
|
||||
for (string::const_iterator pi = str.begin();
|
||||
for (vector_uchar::const_iterator pi = str.begin();
|
||||
pi != str.end();
|
||||
++pi) {
|
||||
char buffer[10];
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ PUBLISHED:
|
|||
void begin_pack(const DCPackerInterface *root);
|
||||
bool end_pack();
|
||||
|
||||
void set_unpack_data(const std::string &data);
|
||||
void set_unpack_data(const vector_uchar &data);
|
||||
public:
|
||||
void set_unpack_data(const char *unpack_data, size_t unpack_length,
|
||||
bool owns_unpack_data);
|
||||
|
|
@ -75,7 +75,8 @@ PUBLISHED:
|
|||
INLINE void pack_int64(int64_t value);
|
||||
INLINE void pack_uint64(uint64_t 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();
|
||||
|
||||
INLINE double unpack_double();
|
||||
|
|
@ -84,7 +85,8 @@ PUBLISHED:
|
|||
INLINE int64_t unpack_int64();
|
||||
INLINE uint64_t unpack_uint64();
|
||||
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_skip();
|
||||
|
||||
|
|
@ -97,7 +99,8 @@ public:
|
|||
INLINE void unpack_int64(int64_t &value);
|
||||
INLINE void unpack_uint64(uint64_t &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:
|
||||
|
||||
|
|
@ -119,6 +122,7 @@ PUBLISHED:
|
|||
|
||||
INLINE size_t get_length() const;
|
||||
INLINE std::string get_string() const;
|
||||
INLINE vector_uchar get_bytes() const;
|
||||
INLINE size_t get_unpack_length() const;
|
||||
INLINE std::string get_unpack_string() const;
|
||||
public:
|
||||
|
|
@ -126,7 +130,7 @@ public:
|
|||
INLINE const char *get_data() const;
|
||||
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 const char *get_unpack_data() const;
|
||||
|
|
@ -148,6 +152,7 @@ PUBLISHED:
|
|||
INLINE void raw_pack_uint64(uint64_t value);
|
||||
INLINE void raw_pack_float64(double 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
|
||||
// agree with channel_type in dcbase.h
|
||||
|
|
@ -165,6 +170,7 @@ PUBLISHED:
|
|||
INLINE uint64_t raw_unpack_uint64();
|
||||
INLINE double raw_unpack_float64();
|
||||
INLINE std::string raw_unpack_string();
|
||||
INLINE vector_uchar raw_unpack_blob();
|
||||
|
||||
public:
|
||||
INLINE void raw_unpack_int8(int &value);
|
||||
|
|
@ -177,10 +183,11 @@ public:
|
|||
INLINE void raw_unpack_uint64(uint64_t &value);
|
||||
INLINE void raw_unpack_float64(double &value);
|
||||
INLINE void raw_unpack_string(std::string &value);
|
||||
INLINE void raw_unpack_blob(vector_uchar &value);
|
||||
|
||||
public:
|
||||
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:
|
||||
INLINE void advance();
|
||||
|
|
|
|||
|
|
@ -248,6 +248,14 @@ pack_string(DCPackData &, const string &, bool &pack_error, bool &) const {
|
|||
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
|
||||
* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
* against the type range limits, but does not return the value. Returns true
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
#include "dcbase.h"
|
||||
#include "dcSubatomicType.h"
|
||||
#include "vector_uchar.h"
|
||||
|
||||
class DCFile;
|
||||
class DCField;
|
||||
|
|
@ -37,8 +38,8 @@ enum DCPackType {
|
|||
|
||||
// These PackTypes are all fundamental types, and should be packed (or
|
||||
// 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_int,
|
||||
PT_uint,
|
||||
|
|
@ -113,6 +114,8 @@ public:
|
|||
bool &pack_error, bool &range_error) const;
|
||||
virtual void pack_string(DCPackData &pack_data, const std::string &value,
|
||||
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 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;
|
||||
virtual void unpack_string(const char *data, size_t length, size_t &p,
|
||||
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,
|
||||
bool &pack_error, bool &range_error) const;
|
||||
virtual bool unpack_skip(const char *data, size_t length, size_t &p,
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -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
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
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
|
||||
Bison output files to be licensed under the GNU General Public
|
||||
License without this special exception.
|
||||
|
||||
|
||||
This special exception was added by the Free Software Foundation in
|
||||
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
|
||||
# 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
|
||||
/* Tokens. */
|
||||
#define UNSIGNED_INTEGER 258
|
||||
#define SIGNED_INTEGER 259
|
||||
#define REAL 260
|
||||
#define STRING 261
|
||||
#define HEX_STRING 262
|
||||
#define IDENTIFIER 263
|
||||
#define IDENTIFIER 262
|
||||
#define HEX_STRING 263
|
||||
#define KEYWORD 264
|
||||
#define KW_DCLASS 265
|
||||
#define KW_STRUCT 266
|
||||
|
|
@ -122,15 +129,11 @@
|
|||
#define START_PARAMETER_VALUE 296
|
||||
#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;
|
||||
|
||||
int dcyyparse (void);
|
||||
|
||||
#endif /* !YY_DCYY_BUILT_TMP_DCPARSER_YXX_H_INCLUDED */
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ dc_init_parser(istream &in, const string &filename, DCFile &file) {
|
|||
}
|
||||
|
||||
void
|
||||
dc_init_parser_parameter_value(istream &in, const string &filename,
|
||||
dc_init_parser_parameter_value(istream &in, const string &filename,
|
||||
DCPacker &packer) {
|
||||
dc_file = nullptr;
|
||||
current_packer = &packer;
|
||||
|
|
@ -89,15 +89,16 @@ dc_cleanup_parser() {
|
|||
%token <u.uint64> UNSIGNED_INTEGER
|
||||
%token <u.int64> SIGNED_INTEGER
|
||||
%token <u.real> REAL
|
||||
%token <str> STRING HEX_STRING IDENTIFIER
|
||||
%token <str> STRING IDENTIFIER
|
||||
%token <bytes> HEX_STRING
|
||||
%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_CASE
|
||||
%token KW_DEFAULT
|
||||
|
|
@ -224,7 +225,7 @@ import:
|
|||
{
|
||||
dc_file->add_import_module($2);
|
||||
}
|
||||
| KW_FROM import_identifier KW_IMPORT
|
||||
| KW_FROM import_identifier KW_IMPORT
|
||||
{
|
||||
dc_file->add_import_module($2);
|
||||
}
|
||||
|
|
@ -255,7 +256,7 @@ typedef_decl:
|
|||
{
|
||||
if ($2 != nullptr) {
|
||||
DCTypedef *dtypedef = new DCTypedef($2);
|
||||
|
||||
|
||||
if (!dc_file->add_typedef(dtypedef)) {
|
||||
DCTypedef *old_typedef = dc_file->get_typedef_by_name(dtypedef->get_name());
|
||||
if (old_typedef->is_bogus_typedef()) {
|
||||
|
|
@ -294,7 +295,7 @@ dclass_or_struct:
|
|||
;
|
||||
|
||||
dclass:
|
||||
KW_DCLASS optional_name
|
||||
KW_DCLASS optional_name
|
||||
{
|
||||
current_class = new DCClass(dc_file, $2, false, false);
|
||||
}
|
||||
|
|
@ -322,7 +323,7 @@ dclass_name:
|
|||
if (dclass->is_struct()) {
|
||||
yyerror("struct name not allowed");
|
||||
}
|
||||
|
||||
|
||||
$$ = dclass;
|
||||
}
|
||||
}
|
||||
|
|
@ -398,7 +399,7 @@ dclass_field:
|
|||
;
|
||||
|
||||
struct:
|
||||
KW_STRUCT optional_name
|
||||
KW_STRUCT optional_name
|
||||
{
|
||||
current_class = new DCClass(dc_file, $2, true, false);
|
||||
}
|
||||
|
|
@ -426,7 +427,7 @@ struct_name:
|
|||
if (!dstruct->is_struct()) {
|
||||
yyerror("struct name required");
|
||||
}
|
||||
|
||||
|
||||
$$ = dstruct;
|
||||
}
|
||||
}
|
||||
|
|
@ -538,7 +539,7 @@ unnamed_parameter:
|
|||
|
||||
named_parameter_with_default:
|
||||
named_parameter
|
||||
| named_parameter '='
|
||||
| named_parameter '='
|
||||
{
|
||||
current_packer = &default_packer;
|
||||
current_packer->clear_data();
|
||||
|
|
@ -553,7 +554,7 @@ named_parameter_with_default:
|
|||
is_valid = $1->is_valid();
|
||||
}
|
||||
if (current_packer->end_pack()) {
|
||||
$1->set_default_value(current_packer->get_string());
|
||||
$1->set_default_value(current_packer->get_bytes());
|
||||
|
||||
} else {
|
||||
if (is_valid) {
|
||||
|
|
@ -568,7 +569,7 @@ named_parameter_with_default:
|
|||
|
||||
unnamed_parameter_with_default:
|
||||
unnamed_parameter
|
||||
| unnamed_parameter '='
|
||||
| unnamed_parameter '='
|
||||
{
|
||||
current_packer = &default_packer;
|
||||
current_packer->clear_data();
|
||||
|
|
@ -583,7 +584,7 @@ unnamed_parameter_with_default:
|
|||
is_valid = $1->is_valid();
|
||||
}
|
||||
if (current_packer->end_pack()) {
|
||||
$1->set_default_value(current_packer->get_string());
|
||||
$1->set_default_value(current_packer->get_bytes());
|
||||
|
||||
} else {
|
||||
if (is_valid) {
|
||||
|
|
@ -663,7 +664,7 @@ simple_type_name:
|
|||
$$ = simple_param;
|
||||
}
|
||||
| simple_type_name '%' number
|
||||
{
|
||||
{
|
||||
DCSimpleParameter *simple_param = $1->as_simple_parameter();
|
||||
nassertr(simple_param != nullptr, 0);
|
||||
if (!simple_param->is_numeric_type()) {
|
||||
|
|
@ -703,10 +704,10 @@ type_name:
|
|||
dtypedef = new DCTypedef($1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
dc_file->add_typedef(dtypedef);
|
||||
}
|
||||
|
||||
|
||||
$$ = dtypedef->make_new_parameter();
|
||||
}
|
||||
}
|
||||
|
|
@ -974,7 +975,7 @@ parameter_value:
|
|||
{
|
||||
if ($1 != current_packer->get_current_field_name()) {
|
||||
ostringstream strm;
|
||||
strm << "Got '" << $1 << "', expected '"
|
||||
strm << "Got '" << $1 << "', expected '"
|
||||
<< current_packer->get_current_field_name() << "'";
|
||||
yyerror(strm.str());
|
||||
}
|
||||
|
|
@ -1005,7 +1006,7 @@ parameter_actual_value:
|
|||
{
|
||||
current_packer->pack_literal_value($1);
|
||||
}
|
||||
| '{'
|
||||
| '{'
|
||||
{
|
||||
current_packer->push();
|
||||
}
|
||||
|
|
@ -1013,7 +1014,7 @@ parameter_actual_value:
|
|||
{
|
||||
current_packer->pop();
|
||||
}
|
||||
| '['
|
||||
| '['
|
||||
{
|
||||
current_packer->push();
|
||||
}
|
||||
|
|
@ -1021,7 +1022,7 @@ parameter_actual_value:
|
|||
{
|
||||
current_packer->pop();
|
||||
}
|
||||
| '('
|
||||
| '('
|
||||
{
|
||||
current_packer->push();
|
||||
}
|
||||
|
|
@ -1223,7 +1224,7 @@ molecular_atom_list:
|
|||
if ($3 != nullptr) {
|
||||
current_molecular->add_atomic($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 " +
|
||||
$3->get_name());
|
||||
}
|
||||
|
|
@ -1283,7 +1284,7 @@ switch_case:
|
|||
yyerror("Invalid value for switch parameter");
|
||||
current_switch->add_invalid_case();
|
||||
} 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) {
|
||||
yyerror("Duplicate case value");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
#include "dcbase.h"
|
||||
#include "dcSubatomicType.h"
|
||||
#include "vector_uchar.h"
|
||||
|
||||
class DCFile;
|
||||
class DCClass;
|
||||
|
|
@ -61,6 +62,7 @@ public:
|
|||
const DCKeyword *keyword;
|
||||
} u;
|
||||
std::string str;
|
||||
vector_uchar bytes;
|
||||
};
|
||||
|
||||
// The yacc-generated code expects to use the symbol 'YYSTYPE' to refer to the
|
||||
|
|
|
|||
|
|
@ -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
|
||||
* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
* against the type range limits, but does not return the value. Returns true
|
||||
|
|
|
|||
|
|
@ -62,6 +62,8 @@ public:
|
|||
bool &pack_error, bool &range_error) const;
|
||||
virtual void pack_string(DCPackData &pack_data, const std::string &value,
|
||||
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 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;
|
||||
virtual void unpack_string(const char *data, size_t length, size_t &p,
|
||||
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,
|
||||
bool &pack_error, bool &range_error) const;
|
||||
virtual bool unpack_skip(const char *data, size_t length, size_t &p,
|
||||
|
|
|
|||
|
|
@ -109,7 +109,7 @@ get_num_cases() const {
|
|||
* if no case has this value.
|
||||
*/
|
||||
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;
|
||||
vi = _cases_by_value.find(case_value);
|
||||
if (vi != _cases_by_value.end()) {
|
||||
|
|
@ -140,9 +140,9 @@ get_default_case() const {
|
|||
/**
|
||||
* Returns the packed value associated with the indicated case.
|
||||
*/
|
||||
string DCSwitch::
|
||||
vector_uchar DCSwitch::
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
@ -198,7 +198,7 @@ is_field_valid() const {
|
|||
* -1. This is normally called only by the parser.
|
||||
*/
|
||||
int DCSwitch::
|
||||
add_case(const string &value) {
|
||||
add_case(const vector_uchar &value) {
|
||||
int case_index = (int)_cases.size();
|
||||
if (!_cases_by_value.insert(CasesByValue::value_type(value, case_index)).second) {
|
||||
add_invalid_case();
|
||||
|
|
@ -283,7 +283,8 @@ add_break() {
|
|||
const DCPackerInterface *DCSwitch::
|
||||
apply_switch(const char *value_data, size_t length) const {
|
||||
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()) {
|
||||
return _cases[(*vi).second]->_fields;
|
||||
}
|
||||
|
|
@ -421,7 +422,7 @@ generate_hash(HashGenerator &hashgen) const {
|
|||
Cases::const_iterator ci;
|
||||
for (ci = _cases.begin(); ci != _cases.end(); ++ci) {
|
||||
const SwitchCase *dcase = (*ci);
|
||||
hashgen.add_string(dcase->_value);
|
||||
hashgen.add_blob(dcase->_value);
|
||||
|
||||
const SwitchFields *fields = dcase->_fields;
|
||||
hashgen.add_int(fields->_fields.size());
|
||||
|
|
@ -702,7 +703,7 @@ do_check_match(const DCPackerInterface *) const {
|
|||
*
|
||||
*/
|
||||
DCSwitch::SwitchCase::
|
||||
SwitchCase(const string &value, DCSwitch::SwitchFields *fields) :
|
||||
SwitchCase(const vector_uchar &value, DCSwitch::SwitchFields *fields) :
|
||||
_value(value),
|
||||
_fields(fields)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -40,18 +40,18 @@ PUBLISHED:
|
|||
DCField *get_key_parameter() 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_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;
|
||||
DCField *get_field(int case_index, int n) const;
|
||||
DCField *get_field_by_name(int case_index, const std::string &name) const;
|
||||
|
||||
public:
|
||||
bool is_field_valid() const;
|
||||
int add_case(const std::string &value);
|
||||
int add_case(const vector_uchar &value);
|
||||
void add_invalid_case();
|
||||
bool add_default();
|
||||
bool add_field(DCField *field);
|
||||
|
|
@ -98,13 +98,13 @@ public:
|
|||
|
||||
class SwitchCase {
|
||||
public:
|
||||
SwitchCase(const std::string &value, SwitchFields *fields);
|
||||
SwitchCase(const vector_uchar &value, SwitchFields *fields);
|
||||
~SwitchCase();
|
||||
|
||||
bool do_check_match_switch_case(const SwitchCase *other) const;
|
||||
|
||||
public:
|
||||
std::string _value;
|
||||
vector_uchar _value;
|
||||
SwitchFields *_fields;
|
||||
};
|
||||
|
||||
|
|
@ -137,7 +137,7 @@ private:
|
|||
bool _fields_added;
|
||||
|
||||
// This map indexes into the _cases vector, above.
|
||||
typedef pmap<std::string, int> CasesByValue;
|
||||
typedef pmap<vector_uchar, int> CasesByValue;
|
||||
CasesByValue _cases_by_value;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
#include "dcbase.h"
|
||||
#include "primeNumberGenerator.h"
|
||||
#include "vector_uchar.h"
|
||||
|
||||
/**
|
||||
* This class generates an arbitrary hash number from a sequence of ints.
|
||||
|
|
@ -26,6 +27,7 @@ public:
|
|||
|
||||
void add_int(int num);
|
||||
void add_string(const std::string &str);
|
||||
void add_blob(const vector_uchar &bytes);
|
||||
|
||||
unsigned long get_hash() const;
|
||||
|
||||
|
|
|
|||
|
|
@ -891,7 +891,7 @@ describe_message(std::ostream &out, const string &prefix,
|
|||
const Datagram &dg) const {
|
||||
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;
|
||||
int msg_type;
|
||||
bool is_update = false;
|
||||
|
|
|
|||
Loading…
Reference in New Issue