add check_match

This commit is contained in:
David Rose 2004-07-09 23:11:20 +00:00
parent 1f8a73a6c7
commit 37b1ea93da
26 changed files with 1643 additions and 863 deletions

View File

@ -17,6 +17,8 @@
////////////////////////////////////////////////////////////////////
#include "dcArrayParameter.h"
#include "dcSimpleParameter.h"
#include "dcClassParameter.h"
#include "hashGenerator.h"
////////////////////////////////////////////////////////////////////
@ -276,3 +278,52 @@ pack_default_value(DCPackData &pack_data, bool &pack_error) const {
return true;
}
////////////////////////////////////////////////////////////////////
// Function: DCArrayParameter::do_check_match
// Access: Protected, Virtual
// Description: 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 limits,
// are not compared.
////////////////////////////////////////////////////////////////////
bool DCArrayParameter::
do_check_match(const DCPackerInterface *other) const {
return other->do_check_match_array_parameter(this);
}
////////////////////////////////////////////////////////////////////
// Function: DCArrayParameter::do_check_match_simple_parameter
// Access: Protected, Virtual
// Description: Returns true if this field matches the indicated
// simple parameter, false otherwise.
////////////////////////////////////////////////////////////////////
bool DCArrayParameter::
do_check_match_simple_parameter(const DCSimpleParameter *other) const {
return ((const DCPackerInterface *)other)->do_check_match_array_parameter(this);
}
////////////////////////////////////////////////////////////////////
// Function: DCArrayParameter::do_check_match_class_parameter
// Access: Protected, Virtual
// Description: Returns true if this field matches the indicated
// class parameter, false otherwise.
////////////////////////////////////////////////////////////////////
bool DCArrayParameter::
do_check_match_class_parameter(const DCClassParameter *other) const {
return ((const DCPackerInterface *)other)->do_check_match_array_parameter(this);
}
////////////////////////////////////////////////////////////////////
// Function: DCArrayParameter::do_check_match_array_parameter
// Access: Protected, Virtual
// Description: Returns true if this field matches the indicated
// array parameter, false otherwise.
////////////////////////////////////////////////////////////////////
bool DCArrayParameter::
do_check_match_array_parameter(const DCArrayParameter *other) const {
if (_array_size != other->_array_size) {
return false;
}
return _element_type->check_match(other->_element_type);
}

View File

@ -56,6 +56,12 @@ public:
virtual void generate_hash(HashGenerator &hashgen) const;
virtual bool pack_default_value(DCPackData &pack_data, bool &pack_error) const;
protected:
virtual bool do_check_match(const DCPackerInterface *other) const;
virtual bool do_check_match_simple_parameter(const DCSimpleParameter *other) const;
virtual bool do_check_match_class_parameter(const DCClassParameter *other) const;
virtual bool do_check_match_array_parameter(const DCArrayParameter *other) const;
private:
DCParameter *_element_type;
int _array_size;

View File

@ -284,6 +284,39 @@ add_element(DCParameter *element) {
_default_value_stale = true;
}
////////////////////////////////////////////////////////////////////
// Function: DCAtomicField::do_check_match
// Access: Protected, Virtual
// Description: 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 limits,
// are not compared.
////////////////////////////////////////////////////////////////////
bool DCAtomicField::
do_check_match(const DCPackerInterface *other) const {
return other->do_check_match_atomic_field(this);
}
////////////////////////////////////////////////////////////////////
// Function: DCAtomicField::do_check_match_atomic_field
// Access: Protected, Virtual
// Description: Returns true if this field matches the indicated
// atomic field, false otherwise.
////////////////////////////////////////////////////////////////////
bool DCAtomicField::
do_check_match_atomic_field(const DCAtomicField *other) const {
if (_elements.size() != other->_elements.size()) {
return false;
}
for (size_t i = 0; i < _elements.size(); i++) {
if (!_elements[i]->check_match(other->_elements[i])) {
return false;
}
}
return true;
}
////////////////////////////////////////////////////////////////////
// Function: DCAtomicField::output_element
// Access: Private

View File

@ -63,6 +63,10 @@ public:
virtual DCPackerInterface *get_nested_field(int n) const;
protected:
virtual bool do_check_match(const DCPackerInterface *other) const;
virtual bool do_check_match_atomic_field(const DCAtomicField *other) const;
private:
void output_element(ostream &out, bool brief, DCParameter *element) const;

View File

@ -876,27 +876,29 @@ generate_hash(HashGenerator &hashgen) const {
////////////////////////////////////////////////////////////////////
bool DCClass::
add_field(DCField *field) {
if (!_name.empty() && field->get_name() == _name) {
// This field is a constructor.
if (_constructor != (DCField *)NULL) {
// We already have a constructor.
if (!field->get_name().empty()) {
if (field->get_name() == _name) {
// This field is a constructor.
if (_constructor != (DCField *)NULL) {
// We already have a constructor.
return false;
}
if (field->as_atomic_field() == (DCAtomicField *)NULL) {
// The constructor must be an atomic field.
return false;
}
_constructor = field;
_fields_by_name.insert
(FieldsByName::value_type(field->get_name(), field));
return true;
}
bool inserted = _fields_by_name.insert
(FieldsByName::value_type(field->get_name(), field)).second;
if (!inserted) {
return false;
}
if (field->as_atomic_field() == (DCAtomicField *)NULL) {
// The constructor must be an atomic field.
return false;
}
_constructor = field;
_fields_by_name.insert
(FieldsByName::value_type(field->get_name(), field));
return true;
}
bool inserted = _fields_by_name.insert
(FieldsByName::value_type(field->get_name(), field)).second;
if (!inserted) {
return false;
}
if (!is_struct()) {

View File

@ -18,6 +18,7 @@
#include "dcClassParameter.h"
#include "dcClass.h"
#include "dcArrayParameter.h"
#include "hashGenerator.h"
////////////////////////////////////////////////////////////////////
@ -176,3 +177,60 @@ generate_hash(HashGenerator &hashgen) const {
DCParameter::generate_hash(hashgen);
_dclass->generate_hash(hashgen);
}
////////////////////////////////////////////////////////////////////
// Function: DCClassParameter::do_check_match
// Access: Protected, Virtual
// Description: 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 limits,
// are not compared.
////////////////////////////////////////////////////////////////////
bool DCClassParameter::
do_check_match(const DCPackerInterface *other) const {
return other->do_check_match_class_parameter(this);
}
////////////////////////////////////////////////////////////////////
// Function: DCClassParameter::do_check_match_class_parameter
// Access: Protected, Virtual
// Description: Returns true if this field matches the indicated
// class parameter, false otherwise.
////////////////////////////////////////////////////////////////////
bool DCClassParameter::
do_check_match_class_parameter(const DCClassParameter *other) const {
if (_nested_fields.size() != other->_nested_fields.size()) {
return false;
}
for (size_t i = 0; i < _nested_fields.size(); i++) {
if (!_nested_fields[i]->check_match(other->_nested_fields[i])) {
return false;
}
}
return true;
}
////////////////////////////////////////////////////////////////////
// Function: DCClassParameter::do_check_match_array_parameter
// Access: Protected, Virtual
// Description: Returns true if this field matches the indicated
// array parameter, false otherwise.
////////////////////////////////////////////////////////////////////
bool DCClassParameter::
do_check_match_array_parameter(const DCArrayParameter *other) const {
if ((int)_nested_fields.size() != other->get_array_size()) {
// We can only match a fixed-size array whose size happens to
// exactly match our number of fields.
return false;
}
const DCPackerInterface *element_type = other->get_element_type();
for (size_t i = 0; i < _nested_fields.size(); i++) {
if (!_nested_fields[i]->check_match(element_type)) {
return false;
}
}
return true;
}

View File

@ -50,6 +50,11 @@ public:
const string &name, const string &postname) const;
virtual void generate_hash(HashGenerator &hashgen) const;
protected:
virtual bool do_check_match(const DCPackerInterface *other) const;
virtual bool do_check_match_class_parameter(const DCClassParameter *other) const;
virtual bool do_check_match_array_parameter(const DCArrayParameter *other) const;
private:
typedef pvector<DCPackerInterface *> Fields;
Fields _nested_fields;

View File

@ -569,6 +569,13 @@ dc_start_parameter_value() {
initial_token = START_PARAMETER_VALUE;
}
void
dc_start_parameter_description() {
/* Set the initial state to begin parsing a parameter description, instead
of at the beginning of the dc file. */
initial_token = START_PARAMETER_DESCRIPTION;
}
int
dc_error_count() {
return error_count;
@ -627,6 +634,10 @@ input_chars(char *buffer, int &result, int max_size) {
if (*inp) {
inp->read(buffer, max_size);
result = inp->gcount();
if (result >= 0 && result < max_size) {
// Truncate at the end of the read.
buffer[result] = '\0';
}
if (line_number == 0) {
// This is a special case. If we are reading the very first bit
@ -888,7 +899,7 @@ inline void accept() {
col_number += yyleng;
}
#line 893 "lex.yy.c"
#line 904 "lex.yy.c"
/* Macros after this point can all be overridden by user definitions in
* section 1.
@ -1039,7 +1050,7 @@ YY_DECL
register char *yy_cp = NULL, *yy_bp = NULL;
register int yy_act;
#line 395 "dcLexer.lxx"
#line 406 "dcLexer.lxx"
@ -1050,7 +1061,7 @@ YY_DECL
}
#line 1055 "lex.yy.c"
#line 1066 "lex.yy.c"
if ( yy_init )
{
@ -1135,7 +1146,7 @@ do_action: /* This label is used only to access EOF actions. */
case 1:
YY_RULE_SETUP
#line 405 "dcLexer.lxx"
#line 416 "dcLexer.lxx"
{
// New line. Save a copy of the line so we can print it out for the
// benefit of the user in case we get an error.
@ -1152,7 +1163,7 @@ YY_RULE_SETUP
YY_BREAK
case 2:
YY_RULE_SETUP
#line 419 "dcLexer.lxx"
#line 430 "dcLexer.lxx"
{
// Eat whitespace.
accept();
@ -1160,7 +1171,7 @@ YY_RULE_SETUP
YY_BREAK
case 3:
YY_RULE_SETUP
#line 424 "dcLexer.lxx"
#line 435 "dcLexer.lxx"
{
// Eat C++-style comments.
accept();
@ -1168,7 +1179,7 @@ YY_RULE_SETUP
YY_BREAK
case 4:
YY_RULE_SETUP
#line 429 "dcLexer.lxx"
#line 440 "dcLexer.lxx"
{
// Eat C-style comments.
accept();
@ -1177,7 +1188,7 @@ YY_RULE_SETUP
YY_BREAK
case 5:
YY_RULE_SETUP
#line 436 "dcLexer.lxx"
#line 447 "dcLexer.lxx"
{
accept();
return KW_DCLASS;
@ -1185,7 +1196,7 @@ YY_RULE_SETUP
YY_BREAK
case 6:
YY_RULE_SETUP
#line 441 "dcLexer.lxx"
#line 452 "dcLexer.lxx"
{
accept();
return KW_STRUCT;
@ -1193,7 +1204,7 @@ YY_RULE_SETUP
YY_BREAK
case 7:
YY_RULE_SETUP
#line 446 "dcLexer.lxx"
#line 457 "dcLexer.lxx"
{
accept();
return KW_FROM;
@ -1201,7 +1212,7 @@ YY_RULE_SETUP
YY_BREAK
case 8:
YY_RULE_SETUP
#line 451 "dcLexer.lxx"
#line 462 "dcLexer.lxx"
{
accept();
return KW_IMPORT;
@ -1209,7 +1220,7 @@ YY_RULE_SETUP
YY_BREAK
case 9:
YY_RULE_SETUP
#line 456 "dcLexer.lxx"
#line 467 "dcLexer.lxx"
{
accept();
return KW_TYPEDEF;
@ -1217,7 +1228,7 @@ YY_RULE_SETUP
YY_BREAK
case 10:
YY_RULE_SETUP
#line 461 "dcLexer.lxx"
#line 472 "dcLexer.lxx"
{
accept();
return KW_SWITCH;
@ -1225,7 +1236,7 @@ YY_RULE_SETUP
YY_BREAK
case 11:
YY_RULE_SETUP
#line 466 "dcLexer.lxx"
#line 477 "dcLexer.lxx"
{
accept();
return KW_CASE;
@ -1233,7 +1244,7 @@ YY_RULE_SETUP
YY_BREAK
case 12:
YY_RULE_SETUP
#line 471 "dcLexer.lxx"
#line 482 "dcLexer.lxx"
{
accept();
return KW_INT8;
@ -1241,7 +1252,7 @@ YY_RULE_SETUP
YY_BREAK
case 13:
YY_RULE_SETUP
#line 476 "dcLexer.lxx"
#line 487 "dcLexer.lxx"
{
accept();
return KW_INT16;
@ -1249,7 +1260,7 @@ YY_RULE_SETUP
YY_BREAK
case 14:
YY_RULE_SETUP
#line 481 "dcLexer.lxx"
#line 492 "dcLexer.lxx"
{
accept();
return KW_INT32;
@ -1257,7 +1268,7 @@ YY_RULE_SETUP
YY_BREAK
case 15:
YY_RULE_SETUP
#line 486 "dcLexer.lxx"
#line 497 "dcLexer.lxx"
{
accept();
return KW_INT64;
@ -1265,7 +1276,7 @@ YY_RULE_SETUP
YY_BREAK
case 16:
YY_RULE_SETUP
#line 491 "dcLexer.lxx"
#line 502 "dcLexer.lxx"
{
accept();
return KW_UINT8;
@ -1273,7 +1284,7 @@ YY_RULE_SETUP
YY_BREAK
case 17:
YY_RULE_SETUP
#line 496 "dcLexer.lxx"
#line 507 "dcLexer.lxx"
{
accept();
return KW_UINT16;
@ -1281,7 +1292,7 @@ YY_RULE_SETUP
YY_BREAK
case 18:
YY_RULE_SETUP
#line 501 "dcLexer.lxx"
#line 512 "dcLexer.lxx"
{
accept();
return KW_UINT32;
@ -1289,7 +1300,7 @@ YY_RULE_SETUP
YY_BREAK
case 19:
YY_RULE_SETUP
#line 506 "dcLexer.lxx"
#line 517 "dcLexer.lxx"
{
accept();
return KW_UINT64;
@ -1297,7 +1308,7 @@ YY_RULE_SETUP
YY_BREAK
case 20:
YY_RULE_SETUP
#line 511 "dcLexer.lxx"
#line 522 "dcLexer.lxx"
{
accept();
return KW_FLOAT64;
@ -1305,7 +1316,7 @@ YY_RULE_SETUP
YY_BREAK
case 21:
YY_RULE_SETUP
#line 516 "dcLexer.lxx"
#line 527 "dcLexer.lxx"
{
accept();
return KW_STRING;
@ -1313,7 +1324,7 @@ YY_RULE_SETUP
YY_BREAK
case 22:
YY_RULE_SETUP
#line 521 "dcLexer.lxx"
#line 532 "dcLexer.lxx"
{
accept();
return KW_BLOB;
@ -1321,7 +1332,7 @@ YY_RULE_SETUP
YY_BREAK
case 23:
YY_RULE_SETUP
#line 526 "dcLexer.lxx"
#line 537 "dcLexer.lxx"
{
accept();
return KW_BLOB32;
@ -1329,7 +1340,7 @@ YY_RULE_SETUP
YY_BREAK
case 24:
YY_RULE_SETUP
#line 531 "dcLexer.lxx"
#line 542 "dcLexer.lxx"
{
accept();
return KW_INT8ARRAY;
@ -1337,7 +1348,7 @@ YY_RULE_SETUP
YY_BREAK
case 25:
YY_RULE_SETUP
#line 536 "dcLexer.lxx"
#line 547 "dcLexer.lxx"
{
accept();
return KW_INT16ARRAY;
@ -1345,7 +1356,7 @@ YY_RULE_SETUP
YY_BREAK
case 26:
YY_RULE_SETUP
#line 541 "dcLexer.lxx"
#line 552 "dcLexer.lxx"
{
accept();
return KW_INT32ARRAY;
@ -1353,7 +1364,7 @@ YY_RULE_SETUP
YY_BREAK
case 27:
YY_RULE_SETUP
#line 546 "dcLexer.lxx"
#line 557 "dcLexer.lxx"
{
accept();
return KW_UINT8ARRAY;
@ -1361,7 +1372,7 @@ YY_RULE_SETUP
YY_BREAK
case 28:
YY_RULE_SETUP
#line 551 "dcLexer.lxx"
#line 562 "dcLexer.lxx"
{
accept();
return KW_UINT16ARRAY;
@ -1369,7 +1380,7 @@ YY_RULE_SETUP
YY_BREAK
case 29:
YY_RULE_SETUP
#line 556 "dcLexer.lxx"
#line 567 "dcLexer.lxx"
{
accept();
return KW_UINT32ARRAY;
@ -1377,7 +1388,7 @@ YY_RULE_SETUP
YY_BREAK
case 30:
YY_RULE_SETUP
#line 561 "dcLexer.lxx"
#line 572 "dcLexer.lxx"
{
accept();
return KW_UINT32UINT8ARRAY;
@ -1385,7 +1396,7 @@ YY_RULE_SETUP
YY_BREAK
case 31:
YY_RULE_SETUP
#line 566 "dcLexer.lxx"
#line 577 "dcLexer.lxx"
{
accept();
return KW_CHAR;
@ -1393,7 +1404,7 @@ YY_RULE_SETUP
YY_BREAK
case 32:
YY_RULE_SETUP
#line 571 "dcLexer.lxx"
#line 582 "dcLexer.lxx"
{
accept();
return KW_REQUIRED;
@ -1401,7 +1412,7 @@ YY_RULE_SETUP
YY_BREAK
case 33:
YY_RULE_SETUP
#line 576 "dcLexer.lxx"
#line 587 "dcLexer.lxx"
{
accept();
return KW_BROADCAST;
@ -1409,7 +1420,7 @@ YY_RULE_SETUP
YY_BREAK
case 34:
YY_RULE_SETUP
#line 581 "dcLexer.lxx"
#line 592 "dcLexer.lxx"
{
accept();
return KW_P2P;
@ -1417,7 +1428,7 @@ YY_RULE_SETUP
YY_BREAK
case 35:
YY_RULE_SETUP
#line 586 "dcLexer.lxx"
#line 597 "dcLexer.lxx"
{
accept();
return KW_RAM;
@ -1425,7 +1436,7 @@ YY_RULE_SETUP
YY_BREAK
case 36:
YY_RULE_SETUP
#line 591 "dcLexer.lxx"
#line 602 "dcLexer.lxx"
{
accept();
return KW_DB;
@ -1433,7 +1444,7 @@ YY_RULE_SETUP
YY_BREAK
case 37:
YY_RULE_SETUP
#line 596 "dcLexer.lxx"
#line 607 "dcLexer.lxx"
{
accept();
return KW_CLSEND;
@ -1441,7 +1452,7 @@ YY_RULE_SETUP
YY_BREAK
case 38:
YY_RULE_SETUP
#line 601 "dcLexer.lxx"
#line 612 "dcLexer.lxx"
{
accept();
return KW_CLRECV;
@ -1449,7 +1460,7 @@ YY_RULE_SETUP
YY_BREAK
case 39:
YY_RULE_SETUP
#line 606 "dcLexer.lxx"
#line 617 "dcLexer.lxx"
{
accept();
return KW_OWNSEND;
@ -1457,7 +1468,7 @@ YY_RULE_SETUP
YY_BREAK
case 40:
YY_RULE_SETUP
#line 611 "dcLexer.lxx"
#line 622 "dcLexer.lxx"
{
accept();
return KW_AIRECV;
@ -1465,7 +1476,7 @@ YY_RULE_SETUP
YY_BREAK
case 41:
YY_RULE_SETUP
#line 616 "dcLexer.lxx"
#line 627 "dcLexer.lxx"
{
// An unsigned integer number.
accept();
@ -1491,7 +1502,7 @@ YY_RULE_SETUP
YY_BREAK
case 42:
YY_RULE_SETUP
#line 639 "dcLexer.lxx"
#line 650 "dcLexer.lxx"
{
// A signed integer number.
accept();
@ -1540,7 +1551,7 @@ YY_RULE_SETUP
YY_BREAK
case 43:
YY_RULE_SETUP
#line 685 "dcLexer.lxx"
#line 696 "dcLexer.lxx"
{
// A hexadecimal integer number.
accept();
@ -1570,7 +1581,7 @@ YY_RULE_SETUP
YY_BREAK
case 44:
YY_RULE_SETUP
#line 712 "dcLexer.lxx"
#line 723 "dcLexer.lxx"
{
// A floating-point number.
accept();
@ -1581,7 +1592,7 @@ YY_RULE_SETUP
YY_BREAK
case 45:
YY_RULE_SETUP
#line 720 "dcLexer.lxx"
#line 731 "dcLexer.lxx"
{
// Quoted string.
accept();
@ -1591,7 +1602,7 @@ YY_RULE_SETUP
YY_BREAK
case 46:
YY_RULE_SETUP
#line 727 "dcLexer.lxx"
#line 738 "dcLexer.lxx"
{
// Single-quoted string.
accept();
@ -1601,7 +1612,7 @@ YY_RULE_SETUP
YY_BREAK
case 47:
YY_RULE_SETUP
#line 734 "dcLexer.lxx"
#line 745 "dcLexer.lxx"
{
// Long hex string.
accept();
@ -1611,7 +1622,7 @@ YY_RULE_SETUP
YY_BREAK
case 48:
YY_RULE_SETUP
#line 741 "dcLexer.lxx"
#line 752 "dcLexer.lxx"
{
// Identifier.
accept();
@ -1621,7 +1632,7 @@ YY_RULE_SETUP
YY_BREAK
case 49:
YY_RULE_SETUP
#line 749 "dcLexer.lxx"
#line 760 "dcLexer.lxx"
{
// Send any other printable character as itself.
accept();
@ -1630,10 +1641,10 @@ YY_RULE_SETUP
YY_BREAK
case 50:
YY_RULE_SETUP
#line 755 "dcLexer.lxx"
#line 766 "dcLexer.lxx"
ECHO;
YY_BREAK
#line 1638 "lex.yy.c"
#line 1649 "lex.yy.c"
case YY_STATE_EOF(INITIAL):
yyterminate();
@ -2514,4 +2525,4 @@ int main()
return 0;
}
#endif
#line 755 "dcLexer.lxx"
#line 766 "dcLexer.lxx"

View File

@ -66,6 +66,13 @@ dc_start_parameter_value() {
initial_token = START_PARAMETER_VALUE;
}
void
dc_start_parameter_description() {
/* Set the initial state to begin parsing a parameter description, instead
of at the beginning of the dc file. */
initial_token = START_PARAMETER_DESCRIPTION;
}
int
dc_error_count() {
return error_count;
@ -124,6 +131,10 @@ input_chars(char *buffer, int &result, int max_size) {
if (*inp) {
inp->read(buffer, max_size);
result = inp->gcount();
if (result >= 0 && result < max_size) {
// Truncate at the end of the read.
buffer[result] = '\0';
}
if (line_number == 0) {
// This is a special case. If we are reading the very first bit

View File

@ -23,6 +23,7 @@
void dc_init_lexer(istream &in, const string &filename);
void dc_start_parameter_value();
void dc_start_parameter_description();
int dc_error_count();
int dc_warning_count();

View File

@ -192,3 +192,36 @@ get_nested_field(int n) const {
nassertr(n >= 0 && n < (int)_nested_fields.size(), NULL);
return _nested_fields[n];
}
////////////////////////////////////////////////////////////////////
// Function: DCMolecularField::do_check_match
// Access: Protected, Virtual
// Description: 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 limits,
// are not compared.
////////////////////////////////////////////////////////////////////
bool DCMolecularField::
do_check_match(const DCPackerInterface *other) const {
return other->do_check_match_molecular_field(this);
}
////////////////////////////////////////////////////////////////////
// Function: DCMolecularField::do_check_match_molecular_field
// Access: Protected, Virtual
// Description: Returns true if this field matches the indicated
// molecular field, false otherwise.
////////////////////////////////////////////////////////////////////
bool DCMolecularField::
do_check_match_molecular_field(const DCMolecularField *other) const {
if (_nested_fields.size() != other->_nested_fields.size()) {
return false;
}
for (size_t i = 0; i < _nested_fields.size(); i++) {
if (!_nested_fields[i]->check_match(other->_nested_fields[i])) {
return false;
}
}
return true;
}

View File

@ -52,6 +52,10 @@ public:
virtual DCPackerInterface *get_nested_field(int n) const;
protected:
virtual bool do_check_match(const DCPackerInterface *other) const;
virtual bool do_check_match_molecular_field(const DCMolecularField *other) const;
private:
// These members define the primary interface to the molecular field
// definition as read from the file.

View File

@ -190,8 +190,23 @@ add_entry(const string &name, const DCPackerInterface *field,
int entry_index = (int)_entries.size();
_entries.push_back(entry);
_entries_by_name.insert(EntriesByName::value_type(name, entry_index));
_entries_by_field.insert(EntriesByField::value_type(field, entry_index));
// Add an entry for the fully-qualified field name
// (e.g. dna.topTex). If there was another entry for this name
// previously, completely replace it--the fully-qualified name is
// supposed to be unique and trumps the local field names (which are
// not necessarily unique).
_entries_by_name[name] = entry_index;
// We'll also add an entry for the local field name, for the user's
// convenience. This won't override a fully-qualified name that
// might already have been recorded, and a fully-qualified name
// discovered later that conflicts with this name will replace it.
string local_name = field->get_name();
if (local_name != name) {
_entries_by_name.insert(EntriesByName::value_type(local_name, entry_index));
}
}
////////////////////////////////////////////////////////////////////

View File

@ -28,6 +28,19 @@ get_name() const {
return _name;
}
////////////////////////////////////////////////////////////////////
// Function: DCPackerInterface::check_match
// Access: Published
// Description: 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 limits,
// are not compared.
////////////////////////////////////////////////////////////////////
INLINE bool DCPackerInterface::
check_match(const DCPackerInterface *other) const {
return do_check_match(other);
}
////////////////////////////////////////////////////////////////////
// Function: DCPackerInterface::set_name
// Access: Public

View File

@ -18,6 +18,8 @@
#include "dcPackerInterface.h"
#include "dcPackerCatalog.h"
#include "dcParserDefs.h"
#include "dcLexerDefs.h"
////////////////////////////////////////////////////////////////////
// Function: DCPackerInterface::Constructor
@ -151,6 +153,42 @@ as_class_parameter() const {
return (DCClassParameter *)NULL;
}
////////////////////////////////////////////////////////////////////
// Function: DCPackerInterface::check_match
// Access: Published
// Description: Returns true if this interface is bitwise the same as
// the interface described with the indicated formatted
// string, e.g. "(uint8, uint8, int16)", or false
// otherwise.
//
// If DCFile is not NULL, it specifies the DCFile that
// was previously loaded, from which some predefined
// structs and typedefs may be referenced in the
// description string.
////////////////////////////////////////////////////////////////////
bool DCPackerInterface::
check_match(const string &description, DCFile *dcfile) const {
bool match = false;
istringstream strm(description);
dc_init_parser_parameter_description(strm, "check_match", dcfile);
dcyyparse();
dc_cleanup_parser();
DCField *field = dc_get_parameter_description();
if (field != NULL) {
match = check_match(field);
delete field;
}
if (dc_error_count() == 0) {
return match;
}
// Parse error: no match is allowed.
return false;
}
////////////////////////////////////////////////////////////////////
// Function: DCPackerInterface::calc_num_nested_fields
// Access: Public, Virtual
@ -417,6 +455,72 @@ get_catalog() const {
return _catalog;
}
////////////////////////////////////////////////////////////////////
// Function: DCPackerInterface::do_check_match_simple_parameter
// Access: Protected, Virtual
// Description: Returns true if this field matches the indicated
// simple parameter, false otherwise.
////////////////////////////////////////////////////////////////////
bool DCPackerInterface::
do_check_match_simple_parameter(const DCSimpleParameter *) const {
return false;
}
////////////////////////////////////////////////////////////////////
// Function: DCPackerInterface::do_check_match_class_parameter
// Access: Protected, Virtual
// Description: Returns true if this field matches the indicated
// class parameter, false otherwise.
////////////////////////////////////////////////////////////////////
bool DCPackerInterface::
do_check_match_class_parameter(const DCClassParameter *) const {
return false;
}
////////////////////////////////////////////////////////////////////
// Function: DCPackerInterface::do_check_match_switch_parameter
// Access: Protected, Virtual
// Description: Returns true if this field matches the indicated
// switch parameter, false otherwise.
////////////////////////////////////////////////////////////////////
bool DCPackerInterface::
do_check_match_switch_parameter(const DCSwitchParameter *) const {
return false;
}
////////////////////////////////////////////////////////////////////
// Function: DCPackerInterface::do_check_match_array_parameter
// Access: Protected, Virtual
// Description: Returns true if this field matches the indicated
// array parameter, false otherwise.
////////////////////////////////////////////////////////////////////
bool DCPackerInterface::
do_check_match_array_parameter(const DCArrayParameter *) const {
return false;
}
////////////////////////////////////////////////////////////////////
// Function: DCPackerInterface::do_check_match_atomic_field
// Access: Protected, Virtual
// Description: Returns true if this field matches the indicated
// atomic field, false otherwise.
////////////////////////////////////////////////////////////////////
bool DCPackerInterface::
do_check_match_atomic_field(const DCAtomicField *) const {
return false;
}
////////////////////////////////////////////////////////////////////
// Function: DCPackerInterface::do_check_match_molecular_field
// Access: Protected, Virtual
// Description: Returns true if this field matches the indicated
// molecular field, false otherwise.
////////////////////////////////////////////////////////////////////
bool DCPackerInterface::
do_check_match_molecular_field(const DCMolecularField *) const {
return false;
}
////////////////////////////////////////////////////////////////////
// Function: DCPackerInterface::make_catalog
// Access: Private

View File

@ -22,9 +22,14 @@
#include "dcbase.h"
#include "dcSubatomicType.h"
class DCFile;
class DCField;
class DCSimpleParameter;
class DCSwitchParameter;
class DCClassParameter;
class DCArrayParameter;
class DCAtomicField;
class DCMolecularField;
class DCPackData;
class DCPackerCatalog;
@ -84,6 +89,9 @@ PUBLISHED:
virtual DCClassParameter *as_class_parameter();
virtual const DCClassParameter *as_class_parameter() const;
INLINE bool check_match(const DCPackerInterface *other) const;
bool check_match(const string &description, DCFile *dcfile = NULL) const;
public:
INLINE void set_name(const string &name);
INLINE bool has_fixed_byte_size() const;
@ -166,6 +174,20 @@ public:
const DCPackerCatalog *get_catalog() const;
protected:
virtual bool do_check_match(const DCPackerInterface *other) const=0;
public:
// These are declared public just so the derived classes can call
// them easily. They're not intended to be called directly.
virtual bool do_check_match_simple_parameter(const DCSimpleParameter *other) const;
virtual bool do_check_match_class_parameter(const DCClassParameter *other) const;
virtual bool do_check_match_switch_parameter(const DCSwitchParameter *other) const;
virtual bool do_check_match_array_parameter(const DCArrayParameter *other) const;
virtual bool do_check_match_atomic_field(const DCAtomicField *other) const;
virtual bool do_check_match_molecular_field(const DCMolecularField *other) const;
private:
void make_catalog();

File diff suppressed because it is too large Load Diff

View File

@ -45,6 +45,7 @@
# define KW_AIRECV 298
# define START_DC 299
# define START_PARAMETER_VALUE 300
# define START_PARAMETER_DESCRIPTION 301
extern YYSTYPE dcyylval;

View File

@ -37,6 +37,7 @@ static DCPacker default_packer;
static DCPacker *current_packer;
static DCDoubleRange double_range;
static DCUnsignedIntRange uint_range;
static DCField *parameter_description = (DCField *)NULL;
////////////////////////////////////////////////////////////////////
// Defining the interface to the parser.
@ -57,6 +58,20 @@ dc_init_parser_parameter_value(istream &in, const string &filename,
dc_start_parameter_value();
}
void
dc_init_parser_parameter_description(istream &in, const string &filename,
DCFile *file) {
dc_file = file;
dc_init_lexer(in, filename);
parameter_description = NULL;
dc_start_parameter_description();
}
DCField *
dc_get_parameter_description() {
return parameter_description;
}
void
dc_cleanup_parser() {
dc_file = (DCFile *)NULL;
@ -113,6 +128,7 @@ dc_cleanup_parser() {
of the input stream. */
%token START_DC
%token START_PARAMETER_VALUE
%token START_PARAMETER_DESCRIPTION
%type <u.atomic> atomic_name
%type <u.s_int> server_flags
@ -124,6 +140,7 @@ dc_cleanup_parser() {
%type <u.dclass> struct_name
%type <u.dclass> struct
%type <u.field> struct_field
%type <u.field> parameter_description
%type <u.dswitch> switch
%type <u.field> switch_field
%type <u.field> atomic_field
@ -153,6 +170,10 @@ dc_cleanup_parser() {
grammar:
START_DC dc
| START_PARAMETER_VALUE parameter_value
| START_PARAMETER_DESCRIPTION parameter_description
{
parameter_description = $2;
}
;
dc:
@ -229,14 +250,16 @@ import_symbol_list:
typedef_decl:
KW_TYPEDEF parameter_with_default
{
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()) {
yyerror("typedef defined after its first reference: " + dtypedef->get_name());
} else {
yyerror("Duplicate typedef name: " + dtypedef->get_name());
if ($2 != (DCParameter *)NULL) {
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()) {
yyerror("typedef defined after its first reference: " + dtypedef->get_name());
} else {
yyerror("Duplicate typedef name: " + dtypedef->get_name());
}
}
}
}
@ -263,17 +286,23 @@ dclass:
dclass_name:
IDENTIFIER
{
DCClass *dclass = dc_file->get_class_by_name($1);
if (dclass == (DCClass *)NULL) {
// Create a bogus class as a forward reference.
dclass = new DCClass($1, false, true);
dc_file->add_class(dclass);
}
if (dclass->is_struct()) {
yyerror("struct name not allowed");
}
if (dc_file == (DCFile *)NULL) {
yyerror("No DCFile available, so no class names are predefined.");
$$ = NULL;
} else {
DCClass *dclass = dc_file->get_class_by_name($1);
if (dclass == (DCClass *)NULL) {
// Create a bogus class as a forward reference.
dclass = new DCClass($1, false, true);
dc_file->add_class(dclass);
}
if (dclass->is_struct()) {
yyerror("struct name not allowed");
}
$$ = dclass;
$$ = dclass;
}
}
;
@ -302,7 +331,9 @@ dclass_fields:
| dclass_fields ';'
| dclass_fields dclass_field
{
if (!current_class->add_field($2)) {
if ($2 == (DCField *)NULL) {
// Pass this error up.
} else if (!current_class->add_field($2)) {
yyerror("Duplicate field name: " + $2->get_name());
} else if ($2->get_number() < 0) {
yyerror("A non-network field cannot be stored on a dclass");
@ -313,20 +344,29 @@ dclass_fields:
dclass_field:
atomic_field server_flags
{
if ($1 != (DCField *)NULL) {
if ($1->get_name().empty()) {
yyerror("Field name required.");
}
$1->set_flags($2);
}
$$ = $1;
$$->set_flags($2);
}
| molecular_field no_server_flags
| unnamed_parameter_with_default server_flags ';'
{
yyerror("Unnamed parameters are not allowed on a dclass");
if ($1 != (DCField *)NULL) {
$1->set_flags($2);
}
$$ = $1;
$$->set_flags($2);
}
| named_parameter_with_default server_flags
{
if ($1 != (DCField *)NULL) {
$1->set_flags($2);
}
$$ = $1;
$$->set_flags($2);
}
;
@ -346,17 +386,23 @@ struct:
struct_name:
IDENTIFIER
{
DCClass *dstruct = dc_file->get_class_by_name($1);
if (dstruct == (DCClass *)NULL) {
// Create a bogus class as a forward reference.
dstruct = new DCClass($1, false, true);
dc_file->add_class(dstruct);
}
if (!dstruct->is_struct()) {
yyerror("struct name required");
}
if (dc_file == (DCFile *)NULL) {
yyerror("No DCFile available, so no struct names are predefined.");
$$ = NULL;
} else {
DCClass *dstruct = dc_file->get_class_by_name($1);
if (dstruct == (DCClass *)NULL) {
// Create a bogus class as a forward reference.
dstruct = new DCClass($1, false, true);
dc_file->add_class(dstruct);
}
if (!dstruct->is_struct()) {
yyerror("struct name required");
}
$$ = dstruct;
$$ = dstruct;
}
}
;
@ -385,7 +431,9 @@ struct_fields:
| struct_fields ';'
| struct_fields struct_field
{
if (!current_class->add_field($2)) {
if ($2 == (DCField *)NULL) {
// Pass this error up.
} else if (!current_class->add_field($2)) {
yyerror("Duplicate field name: " + $2->get_name());
}
}
@ -393,6 +441,12 @@ struct_fields:
struct_field:
atomic_field no_server_flags
{
if ($1->get_name().empty()) {
yyerror("Field name required.");
}
$$ = $1;
}
| molecular_field no_server_flags
| unnamed_parameter_with_default no_server_flags ';'
{
@ -405,7 +459,7 @@ struct_field:
;
atomic_field:
IDENTIFIER '('
optional_name '('
{
$$ = current_atomic;
current_atomic = new DCAtomicField($1);
@ -430,7 +484,9 @@ nonempty_parameter_list:
atomic_element:
parameter_with_default
{
current_atomic->add_element($1);
if ($1 != (DCParameter *)NULL) {
current_atomic->add_element($1);
}
}
;
@ -455,11 +511,16 @@ named_parameter_with_default:
{
current_packer = &default_packer;
current_packer->clear_data();
current_packer->begin_pack($1);
if ($1 != (DCField *)NULL) {
current_packer->begin_pack($1);
}
}
parameter_value
{
bool is_valid = $1->is_valid();
bool is_valid = false;
if ($1 != (DCField *)NULL) {
is_valid = $1->is_valid();
}
if (current_packer->end_pack()) {
$1->set_default_value(current_packer->get_string());
@ -480,11 +541,16 @@ unnamed_parameter_with_default:
{
current_packer = &default_packer;
current_packer->clear_data();
current_packer->begin_pack($1);
if ($1 != (DCField *)NULL) {
current_packer->begin_pack($1);
}
}
parameter_value
{
bool is_valid = $1->is_valid();
bool is_valid = false;
if ($1 != (DCField *)NULL) {
is_valid = $1->is_valid();
}
if (current_packer->end_pack()) {
$1->set_default_value(current_packer->get_string());
@ -509,6 +575,21 @@ parameter_with_default:
| unnamed_parameter_with_default
;
parameter_description:
atomic_field no_server_flags
{
$$ = $1;
}
| unnamed_parameter_with_default no_server_flags
{
$$ = $1;
}
| named_parameter_with_default no_server_flags
{
$$ = $1;
}
;
type_name:
type_token
{
@ -563,44 +644,62 @@ type_name:
}
| IDENTIFIER
{
DCTypedef *dtypedef = dc_file->get_typedef_by_name($1);
if (dtypedef == (DCTypedef *)NULL) {
// Maybe it's a class name.
DCClass *dclass = dc_file->get_class_by_name($1);
if (dclass != (DCClass *)NULL) {
if (!dclass->is_struct()) {
yyerror("cannot embed a dclass object within a message; use a struct");
}
// Create an implicit typedef for this.
dtypedef = new DCTypedef(new DCClassParameter(dclass), true);
} else {
// Maybe it's a switch name.
DCSwitch *dswitch = dc_file->get_switch_by_name($1);
if (dswitch != (DCSwitch *)NULL) {
// This also gets an implicit typedef.
dtypedef = new DCTypedef(new DCSwitchParameter(dswitch), true);
if (dc_file == (DCFile *)NULL) {
yyerror("Invalid type.");
$$ = NULL;
} else {
DCTypedef *dtypedef = dc_file->get_typedef_by_name($1);
if (dtypedef == (DCTypedef *)NULL) {
// Maybe it's a class name.
DCClass *dclass = dc_file->get_class_by_name($1);
if (dclass != (DCClass *)NULL) {
if (!dclass->is_struct()) {
yyerror("cannot embed a dclass object within a message; use a struct");
}
// Create an implicit typedef for this.
dtypedef = new DCTypedef(new DCClassParameter(dclass), true);
} else {
// It's an undefined typedef. Create a bogus forward reference.
dtypedef = new DCTypedef($1);
// Maybe it's a switch name.
DCSwitch *dswitch = dc_file->get_switch_by_name($1);
if (dswitch != (DCSwitch *)NULL) {
// This also gets an implicit typedef.
dtypedef = new DCTypedef(new DCSwitchParameter(dswitch), true);
} else {
// It's an undefined typedef. Create a bogus forward reference.
dtypedef = new DCTypedef($1);
}
}
dc_file->add_typedef(dtypedef);
}
dc_file->add_typedef(dtypedef);
$$ = dtypedef->make_new_parameter();
}
$$ = dtypedef->make_new_parameter();
}
| struct
{
// This is an inline struct definition.
dc_file->add_thing_to_delete($1);
$$ = new DCClassParameter($1);
if ($1 == (DCClass *)NULL) {
$$ = NULL;
} else {
if (dc_file != (DCFile *)NULL) {
dc_file->add_thing_to_delete($1);
}
$$ = new DCClassParameter($1);
}
}
| switch
{
// This is an inline switch definition.
dc_file->add_thing_to_delete($1);
$$ = new DCSwitchParameter($1);
if ($1 == (DCSwitch *)NULL) {
$$ = NULL;
} else {
if (dc_file != (DCFile *)NULL) {
dc_file->add_thing_to_delete($1);
}
$$ = new DCSwitchParameter($1);
}
}
;
@ -691,7 +790,11 @@ type_definition:
type_name
| type_definition '[' uint_range ']'
{
$$ = new DCArrayParameter($1, uint_range);
if ($1 == (DCParameter *)NULL) {
$$ = NULL;
} else {
$$ = new DCArrayParameter($1, uint_range);
}
}
;
@ -1078,8 +1181,10 @@ switch_fields:
{
if (current_switch->get_num_cases() == 0) {
yyerror("case declaration required before first element");
} else if (!current_switch->add_field($2)) {
yyerror("Duplicate field name: " + $2->get_name());
} else if ($2 != (DCField *)NULL) {
if (!current_switch->add_field($2)) {
yyerror("Duplicate field name: " + $2->get_name());
}
}
}
;

View File

@ -33,6 +33,9 @@ class DCPacker;
void dc_init_parser(istream &in, const string &filename, DCFile &file);
void dc_init_parser_parameter_value(istream &in, const string &filename,
DCPacker &packer);
void dc_init_parser_parameter_description(istream &in, const string &filename,
DCFile *file);
DCField *dc_get_parameter_description();
void dc_cleanup_parser();
int dcyyparse();

View File

@ -19,11 +19,14 @@
#include "dcSimpleParameter.h"
#include "dcPackData.h"
#include "dcTypedef.h"
#include "dcArrayParameter.h"
#include "dcClassParameter.h"
#include "dcClass.h"
#include "hashGenerator.h"
#include <math.h>
DCSimpleParameter::NestedFieldMap DCSimpleParameter::_nested_field_map;
DCSimpleParameter::Uint32Uint8Type *DCSimpleParameter::_uint32uint8_type = NULL;
DCClassParameter *DCSimpleParameter::_uint32uint8_type = NULL;
////////////////////////////////////////////////////////////////////
// Function: DCSimpleParameter::Constructor
@ -2150,6 +2153,87 @@ generate_hash(HashGenerator &hashgen) const {
_double_range.generate_hash(hashgen);
}
////////////////////////////////////////////////////////////////////
// Function: DCSimpleParameter::do_check_match
// Access: Protected, Virtual
// Description: 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 limits,
// are not compared.
////////////////////////////////////////////////////////////////////
bool DCSimpleParameter::
do_check_match(const DCPackerInterface *other) const {
return other->do_check_match_simple_parameter(this);
}
////////////////////////////////////////////////////////////////////
// Function: DCSimpleParameter::do_check_match_simple_parameter
// Access: Protected, Virtual
// Description: Returns true if this field matches the indicated
// simple parameter, false otherwise.
////////////////////////////////////////////////////////////////////
bool DCSimpleParameter::
do_check_match_simple_parameter(const DCSimpleParameter *other) const {
if (_divisor != other->_divisor) {
return false;
}
if (_type == other->_type) {
return true;
}
// Check for certain types that are considered equivalent to each
// other.
switch (_type) {
case ST_uint8:
case ST_char:
switch (other->_type) {
case ST_uint8:
case ST_char:
return true;
default:
return false;
}
case ST_string:
case ST_blob:
case ST_uint8array:
switch (other->_type) {
case ST_string:
case ST_blob:
case ST_uint8array:
return true;
default:
return false;
}
default:
return false;
}
}
////////////////////////////////////////////////////////////////////
// Function: DCSimpleParameter::do_check_match_array_parameter
// Access: Protected, Virtual
// Description: Returns true if this field matches the indicated
// array parameter, false otherwise.
////////////////////////////////////////////////////////////////////
bool DCSimpleParameter::
do_check_match_array_parameter(const DCArrayParameter *other) const {
if (other->get_array_size() != -1) {
// We cannot match a fixed-size array.
return false;
}
if (_nested_field == NULL) {
// Only an array-style simple parameter can match a DCArrayParameter.
return false;
}
return _nested_field->check_match(other->get_element_type());
}
////////////////////////////////////////////////////////////////////
// Function: DCSimpleParameter::create_nested_field
// Access: Private, Static
@ -2180,43 +2264,10 @@ create_nested_field(DCSubatomicType type, unsigned int divisor) {
DCPackerInterface *DCSimpleParameter::
create_uint32uint8_type() {
if (_uint32uint8_type == NULL) {
_uint32uint8_type = new Uint32Uint8Type;
DCClass *dclass = new DCClass("", true, false);
dclass->add_field(new DCSimpleParameter(ST_uint32));
dclass->add_field(new DCSimpleParameter(ST_uint8));
_uint32uint8_type = new DCClassParameter(dclass);
}
return _uint32uint8_type;
}
////////////////////////////////////////////////////////////////////
// Function: DCSimpleParameter::Uint32Uint8Type::Constructor
// Access: Public
// Description: This special packer interface is provided just to
// implement uint32uint8array, which is a special kind
// of array that consists of nested pairs of (uint32,
// uint8) values.
////////////////////////////////////////////////////////////////////
DCSimpleParameter::Uint32Uint8Type::
Uint32Uint8Type() {
_uint32_type = new DCSimpleParameter(ST_uint32);
_uint8_type = new DCSimpleParameter(ST_uint8);
_has_nested_fields = true;
_num_nested_fields = 2;
_pack_type = PT_class;
}
////////////////////////////////////////////////////////////////////
// Function: DCSimpleParameter::Uint32Uint8Type::get_nested_field
// Access: Public, Virtual
// Description:
////////////////////////////////////////////////////////////////////
DCPackerInterface *DCSimpleParameter::Uint32Uint8Type::
get_nested_field(int n) const {
switch (n) {
case 0:
return _uint32_type;
case 1:
return _uint8_type;
default:
return NULL;
}
}

View File

@ -89,6 +89,11 @@ public:
const string &name, const string &postname) const;
virtual void generate_hash(HashGenerator &hashgen) const;
protected:
virtual bool do_check_match(const DCPackerInterface *other) const;
virtual bool do_check_match_simple_parameter(const DCSimpleParameter *other) const;
virtual bool do_check_match_array_parameter(const DCArrayParameter *other) const;
private:
static DCSimpleParameter *create_nested_field(DCSubatomicType type,
unsigned int divisor);
@ -109,22 +114,13 @@ private:
typedef pmap<DCSubatomicType, DivisorMap> NestedFieldMap;
static NestedFieldMap _nested_field_map;
class Uint32Uint8Type : public DCPackerInterface {
public:
Uint32Uint8Type();
virtual DCPackerInterface *get_nested_field(int n) const;
DCSimpleParameter *_uint32_type;
DCSimpleParameter *_uint8_type;
};
DCIntRange _int_range;
DCUnsignedIntRange _uint_range;
DCInt64Range _int64_range;
DCUnsignedInt64Range _uint64_range;
DCDoubleRange _double_range;
static Uint32Uint8Type *_uint32uint8_type;
static DCClassParameter *_uint32uint8_type;
};
#endif

View File

@ -410,6 +410,45 @@ pack_default_value(DCPackData &pack_data, bool &pack_error) const {
return true;
}
////////////////////////////////////////////////////////////////////
// Function: DCSwitch::do_check_match_switch
// Access: Public
// Description: Returns true if this switch matches the indicated
// switch, false otherwise. This is only intended to be
// called internally from
// DCSwitchParameter::do_check_match_switch_parameter().
////////////////////////////////////////////////////////////////////
bool DCSwitch::
do_check_match_switch(const DCSwitch *other) const {
if (!_key_parameter->check_match(other->_key_parameter)) {
return false;
}
if (_cases.size() != other->_cases.size()) {
return false;
}
Cases::const_iterator ci;
for (ci = _cases.begin(); ci != _cases.end(); ++ci) {
const SwitchCase *c1 = (*ci);
CasesByValue::const_iterator vi;
vi = other->_cases_by_value.find(c1->_value);
if (vi == other->_cases_by_value.end()) {
// No matching value.
return false;
}
int c2_index = (*vi).second;
nassertr(c2_index >= 0 && c2_index < (int)other->_cases.size(), false);
const SwitchCase *c2 = other->_cases[c2_index];
if (!c1->do_check_match_switch_case(c2)) {
return false;
}
}
return true;
}
////////////////////////////////////////////////////////////////////
// Function: DCSwitch::SwitchCase::Constructor
// Access: Public
@ -477,11 +516,13 @@ get_nested_field(int n) const {
////////////////////////////////////////////////////////////////////
bool DCSwitch::SwitchCase::
add_field(DCField *field) {
bool inserted = _fields_by_name.insert
(FieldsByName::value_type(field->get_name(), field)).second;
if (!inserted) {
return false;
if (!field->get_name().empty()) {
bool inserted = _fields_by_name.insert
(FieldsByName::value_type(field->get_name(), field)).second;
if (!inserted) {
return false;
}
}
_fields.push_back(field);
@ -504,3 +545,40 @@ add_field(DCField *field) {
}
return true;
}
////////////////////////////////////////////////////////////////////
// Function: DCSwitch::SwitchCase::do_check_match_switch_case
// Access: Public
// Description: Returns true if this case matches the indicated
// case, false otherwise. This is only intended to be
// called internally from
// DCSwitch::do_check_match_switch().
////////////////////////////////////////////////////////////////////
bool DCSwitch::SwitchCase::
do_check_match_switch_case(const DCSwitch::SwitchCase *other) const {
if (_fields.size() != other->_fields.size()) {
return false;
}
for (size_t i = 0; i < _fields.size(); i++) {
if (!_fields[i]->check_match(other->_fields[i])) {
return false;
}
}
return true;
}
////////////////////////////////////////////////////////////////////
// Function: DCSwitch::SwitchCase::do_check_match
// Access: Protected, Virtual
// Description: 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 limits,
// are not compared.
////////////////////////////////////////////////////////////////////
bool DCSwitch::SwitchCase::
do_check_match(const DCPackerInterface *) const {
// This should never be called on a SwitchCase.
nassertr(false, false);
return false;
}

View File

@ -70,6 +70,8 @@ public:
virtual void generate_hash(HashGenerator &hashgen) const;
virtual bool pack_default_value(DCPackData &pack_data, bool &pack_error) const;
bool do_check_match_switch(const DCSwitch *other) const;
public:
typedef pvector<DCField *> Fields;
typedef pmap<string, DCField *> FieldsByName;
@ -81,7 +83,12 @@ public:
virtual DCPackerInterface *get_nested_field(int n) const;
bool add_field(DCField *field);
bool do_check_match_switch_case(const SwitchCase *other) const;
protected:
virtual bool do_check_match(const DCPackerInterface *other) const;
public:
string _value;
Fields _fields;
FieldsByName _fields_by_name;

View File

@ -224,3 +224,27 @@ pack_default_value(DCPackData &pack_data, bool &pack_error) const {
return _dswitch->pack_default_value(pack_data, pack_error);
}
////////////////////////////////////////////////////////////////////
// Function: DCSwitchParameter::do_check_match
// Access: Protected, Virtual
// Description: 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 limits,
// are not compared.
////////////////////////////////////////////////////////////////////
bool DCSwitchParameter::
do_check_match(const DCPackerInterface *other) const {
return other->do_check_match_switch_parameter(this);
}
////////////////////////////////////////////////////////////////////
// Function: DCSwitchParameter::do_check_match_switch_parameter
// Access: Protected, Virtual
// Description: Returns true if this field matches the indicated
// switch parameter, false otherwise.
////////////////////////////////////////////////////////////////////
bool DCSwitchParameter::
do_check_match_switch_parameter(const DCSwitchParameter *other) const {
return _dswitch->do_check_match_switch(other->_dswitch);
}

View File

@ -56,6 +56,10 @@ public:
virtual void generate_hash(HashGenerator &hashgen) const;
virtual bool pack_default_value(DCPackData &pack_data, bool &pack_error) const;
protected:
virtual bool do_check_match(const DCPackerInterface *other) const;
virtual bool do_check_match_switch_parameter(const DCSwitchParameter *other) const;
private:
const DCSwitch *_dswitch;
};