default values
This commit is contained in:
parent
9082f017d4
commit
9222e02084
|
|
@ -54,6 +54,10 @@ DCArrayParameter(DCParameter *element_type, const DCUnsignedIntRange &size) :
|
|||
_has_range_limits = true;
|
||||
}
|
||||
|
||||
if (_element_type->has_default_value()) {
|
||||
_has_default_value = true;
|
||||
}
|
||||
|
||||
_has_nested_fields = true;
|
||||
_num_nested_fields = _array_size;
|
||||
_pack_type = PT_array;
|
||||
|
|
@ -223,3 +227,42 @@ generate_hash(HashGenerator &hashgen) const {
|
|||
_element_type->generate_hash(hashgen);
|
||||
_array_size_range.generate_hash(hashgen);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCArrayParameter::pack_default_value
|
||||
// Access: Public, Virtual
|
||||
// Description: Packs the arrayParameter's specified default value (or a
|
||||
// sensible default if no value is specified) into the
|
||||
// stream. Returns true if the default value is packed,
|
||||
// false if the arrayParameter doesn't know how to pack its
|
||||
// default value.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool DCArrayParameter::
|
||||
pack_default_value(DCPackData &pack_data, bool &pack_error) const {
|
||||
if (has_default_value()) {
|
||||
return DCField::pack_default_value(pack_data, pack_error);
|
||||
}
|
||||
|
||||
// If a default value is not specified for a variable-length array,
|
||||
// the default is the minimum array.
|
||||
unsigned int minimum_length = 0;
|
||||
if (!_array_size_range.is_empty()) {
|
||||
minimum_length = _array_size_range.get_min(0);
|
||||
}
|
||||
|
||||
DCPacker packer;
|
||||
packer.begin_pack(this);
|
||||
packer.push();
|
||||
for (unsigned int i = 0; i < minimum_length; i++) {
|
||||
packer.pack_default_value();
|
||||
}
|
||||
packer.pop();
|
||||
if (!packer.end_pack()) {
|
||||
pack_error = true;
|
||||
|
||||
} else {
|
||||
pack_data.append_data(packer.get_data(), packer.get_length());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -53,6 +53,7 @@ public:
|
|||
virtual void output_instance(ostream &out, bool brief, const string &prename,
|
||||
const string &name, const string &postname) const;
|
||||
virtual void generate_hash(HashGenerator &hashgen) const;
|
||||
virtual bool pack_default_value(DCPackData &pack_data, bool &pack_error) const;
|
||||
|
||||
private:
|
||||
DCParameter *_element_type;
|
||||
|
|
|
|||
|
|
@ -33,6 +33,20 @@ DCAtomicField::
|
|||
DCAtomicField(const string &name) : DCField(name) {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCAtomicField::Destructor
|
||||
// Access: Public, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
DCAtomicField::
|
||||
~DCAtomicField() {
|
||||
Elements::iterator ei;
|
||||
for (ei = _elements.begin(); ei != _elements.end(); ++ei) {
|
||||
delete (*ei);
|
||||
}
|
||||
_elements.clear();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCAtomicField::as_atomic_field
|
||||
// Access: Published, Virtual
|
||||
|
|
@ -65,7 +79,7 @@ get_num_elements() const {
|
|||
DCParameter *DCAtomicField::
|
||||
get_element(int n) const {
|
||||
nassertr(n >= 0 && n < (int)_elements.size(), NULL);
|
||||
return _elements[n]._param;
|
||||
return _elements[n];
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -80,13 +94,13 @@ 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.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
string DCAtomicField::
|
||||
get_element_default(int n) const {
|
||||
nassertr(has_element_default(n), string());
|
||||
nassertr(n >= 0 && n < (int)_elements.size(), string());
|
||||
|
||||
return _elements[n]._default_value;
|
||||
return _elements[n]->get_default_value();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -94,11 +108,13 @@ get_element_default(int n) const {
|
|||
// Access: Published
|
||||
// Description: Returns true if the nth element of the field has a
|
||||
// default value specified, false otherwise.
|
||||
//
|
||||
// This is deprecated; use get_element() instead.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool DCAtomicField::
|
||||
has_element_default(int n) const {
|
||||
nassertr(n >= 0 && n < (int)_elements.size(), false);
|
||||
return _elements[n]._has_default_value;
|
||||
return _elements[n]->has_default_value();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -115,7 +131,7 @@ has_element_default(int n) const {
|
|||
string DCAtomicField::
|
||||
get_element_name(int n) const {
|
||||
nassertr(n >= 0 && n < (int)_elements.size(), string());
|
||||
return _elements[n]._param->get_name();
|
||||
return _elements[n]->get_name();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -128,7 +144,7 @@ get_element_name(int n) const {
|
|||
DCSubatomicType DCAtomicField::
|
||||
get_element_type(int n) const {
|
||||
nassertr(n >= 0 && n < (int)_elements.size(), ST_invalid);
|
||||
DCSimpleParameter *simple_parameter = _elements[n]._param->as_simple_parameter();
|
||||
DCSimpleParameter *simple_parameter = _elements[n]->as_simple_parameter();
|
||||
nassertr(simple_parameter != (DCSimpleParameter *)NULL, ST_invalid);
|
||||
return simple_parameter->get_type();
|
||||
}
|
||||
|
|
@ -148,7 +164,7 @@ get_element_type(int n) const {
|
|||
int DCAtomicField::
|
||||
get_element_divisor(int n) const {
|
||||
nassertr(n >= 0 && n < (int)_elements.size(), 1);
|
||||
DCSimpleParameter *simple_parameter = _elements[n]._param->as_simple_parameter();
|
||||
DCSimpleParameter *simple_parameter = _elements[n]->as_simple_parameter();
|
||||
nassertr(simple_parameter != (DCSimpleParameter *)NULL, 1);
|
||||
return simple_parameter->get_divisor();
|
||||
}
|
||||
|
|
@ -164,11 +180,11 @@ output(ostream &out, bool brief) const {
|
|||
|
||||
if (!_elements.empty()) {
|
||||
Elements::const_iterator ei = _elements.begin();
|
||||
(*ei).output(out, brief);
|
||||
output_element(out, brief, *ei);
|
||||
++ei;
|
||||
while (ei != _elements.end()) {
|
||||
out << ", ";
|
||||
(*ei).output(out, brief);
|
||||
output_element(out, brief, *ei);
|
||||
++ei;
|
||||
}
|
||||
}
|
||||
|
|
@ -207,8 +223,7 @@ generate_hash(HashGenerator &hashgen) const {
|
|||
hashgen.add_int(_elements.size());
|
||||
Elements::const_iterator ei;
|
||||
for (ei = _elements.begin(); ei != _elements.end(); ++ei) {
|
||||
const ElementType &element = (*ei);
|
||||
element._param->generate_hash(hashgen);
|
||||
(*ei)->generate_hash(hashgen);
|
||||
}
|
||||
hashgen.add_int(get_flags());
|
||||
}
|
||||
|
|
@ -224,107 +239,53 @@ generate_hash(HashGenerator &hashgen) const {
|
|||
DCPackerInterface *DCAtomicField::
|
||||
get_nested_field(int n) const {
|
||||
nassertr(n >= 0 && n < (int)_elements.size(), NULL);
|
||||
return _elements[n]._param;
|
||||
return _elements[n];
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCAtomicField::add_element
|
||||
// Access: Public
|
||||
// Description: Adds a new element (parameter) to the field.
|
||||
// Normally this is called only during parsing.
|
||||
// Normally this is called only during parsing. The
|
||||
// DCAtomicField object becomes the owner of the new
|
||||
// pointer and will delete it upon destruction.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void DCAtomicField::
|
||||
add_element(const DCAtomicField::ElementType &element) {
|
||||
add_element(DCParameter *element) {
|
||||
_elements.push_back(element);
|
||||
_num_nested_fields = (int)_elements.size();
|
||||
|
||||
// See if we still have a fixed byte size.
|
||||
if (_has_fixed_byte_size) {
|
||||
_has_fixed_byte_size = element._param->has_fixed_byte_size();
|
||||
_fixed_byte_size += element._param->get_fixed_byte_size();
|
||||
_has_fixed_byte_size = element->has_fixed_byte_size();
|
||||
_fixed_byte_size += element->get_fixed_byte_size();
|
||||
}
|
||||
if (_has_fixed_structure) {
|
||||
_has_fixed_structure = element._param->has_fixed_structure();
|
||||
_has_fixed_structure = element->has_fixed_structure();
|
||||
}
|
||||
if (!_has_range_limits) {
|
||||
_has_range_limits = element._param->has_range_limits();
|
||||
_has_range_limits = element->has_range_limits();
|
||||
}
|
||||
if (!_has_default_value) {
|
||||
_has_default_value = element->has_default_value();
|
||||
}
|
||||
_default_value_stale = true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCAtomicField::ElementType::Constructor
|
||||
// Access: Public
|
||||
// Description: The type parameter should be a newly-allocated DCParameter
|
||||
// object; it will eventually be freed with delete when
|
||||
// this object destructs.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
DCAtomicField::ElementType::
|
||||
ElementType(DCParameter *param) {
|
||||
_param = param;
|
||||
_has_default_value = false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCAtomicField::ElementType::Copy Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
DCAtomicField::ElementType::
|
||||
ElementType(const DCAtomicField::ElementType ©) :
|
||||
_param(copy._param->make_copy()),
|
||||
_default_value(copy._default_value),
|
||||
_has_default_value(copy._has_default_value)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCAtomicField::ElementType::Copy Assignment Operator
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void DCAtomicField::ElementType::
|
||||
operator = (const DCAtomicField::ElementType ©) {
|
||||
delete _param;
|
||||
_param = copy._param->make_copy();
|
||||
_default_value = copy._default_value;
|
||||
_has_default_value = copy._has_default_value;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCAtomicField::ElementType::Destructor
|
||||
// Access: Public
|
||||
// Function: DCAtomicField::output_element
|
||||
// Access: Private
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
DCAtomicField::ElementType::
|
||||
~ElementType() {
|
||||
delete _param;
|
||||
}
|
||||
void DCAtomicField::
|
||||
output_element(ostream &out, bool brief, DCParameter *element) const {
|
||||
element->output(out, brief);
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCAtomicField::ElementType::set_default_value
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void DCAtomicField::ElementType::
|
||||
set_default_value(const string &default_value) {
|
||||
_default_value = default_value;
|
||||
_has_default_value = true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCAtomicField::ElementType::output
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void DCAtomicField::ElementType::
|
||||
output(ostream &out, bool brief) const {
|
||||
_param->output(out, brief);
|
||||
|
||||
if (!brief && _has_default_value) {
|
||||
if (!brief && element->has_default_value()) {
|
||||
out << " = ";
|
||||
DCPacker packer;
|
||||
packer.set_unpack_data(_default_value);
|
||||
packer.begin_unpack(_param);
|
||||
packer.set_unpack_data(element->get_default_value());
|
||||
packer.begin_unpack(element);
|
||||
packer.unpack_and_format(out);
|
||||
packer.end_unpack();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,48 +38,34 @@
|
|||
class EXPCL_DIRECT DCAtomicField : public DCField {
|
||||
public:
|
||||
DCAtomicField(const string &name);
|
||||
virtual ~DCAtomicField();
|
||||
|
||||
PUBLISHED:
|
||||
virtual DCAtomicField *as_atomic_field();
|
||||
|
||||
int get_num_elements() const;
|
||||
DCParameter *get_element(int n) const;
|
||||
|
||||
// These five methods are deprecated and will be removed soon.
|
||||
string get_element_default(int n) const;
|
||||
bool has_element_default(int n) const;
|
||||
|
||||
// These three methods are deprecated and will be removed soon.
|
||||
string get_element_name(int n) const;
|
||||
DCSubatomicType get_element_type(int n) const;
|
||||
int get_element_divisor(int n) const;
|
||||
|
||||
public:
|
||||
void add_element(DCParameter *element);
|
||||
|
||||
virtual void output(ostream &out, bool brief) const;
|
||||
virtual void write(ostream &out, bool brief, int indent_level) const;
|
||||
virtual void generate_hash(HashGenerator &hashgen) const;
|
||||
|
||||
virtual DCPackerInterface *get_nested_field(int n) const;
|
||||
|
||||
public:
|
||||
class ElementType {
|
||||
public:
|
||||
ElementType(DCParameter *param);
|
||||
ElementType(const ElementType ©);
|
||||
void operator = (const ElementType ©);
|
||||
~ElementType();
|
||||
|
||||
void set_default_value(const string &default_value);
|
||||
|
||||
void output(ostream &out, bool brief) const;
|
||||
|
||||
DCParameter *_param;
|
||||
string _default_value;
|
||||
bool _has_default_value;
|
||||
};
|
||||
|
||||
void add_element(const ElementType &element);
|
||||
|
||||
private:
|
||||
typedef pvector<ElementType> Elements;
|
||||
void output_element(ostream &out, bool brief, DCParameter *element) const;
|
||||
|
||||
typedef pvector<DCParameter *> Elements;
|
||||
Elements _elements;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -42,11 +42,15 @@ DCClassParameter(const DCClass *dclass) :
|
|||
|
||||
_nested_fields.reserve(_num_nested_fields);
|
||||
if (_dclass->has_constructor()) {
|
||||
_nested_fields.push_back(_dclass->get_constructor());
|
||||
DCField *field = _dclass->get_constructor();
|
||||
_nested_fields.push_back(field);
|
||||
_has_default_value = _has_default_value || field->has_default_value();
|
||||
}
|
||||
int i;
|
||||
for (i = 0 ; i < num_fields; i++) {
|
||||
_nested_fields.push_back(_dclass->get_inherited_field(i));
|
||||
DCField *field = _dclass->get_inherited_field(i);
|
||||
_nested_fields.push_back(field);
|
||||
_has_default_value = _has_default_value || field->has_default_value();
|
||||
}
|
||||
|
||||
// If all of the nested fields have a fixed byte size, then so does
|
||||
|
|
|
|||
|
|
@ -30,6 +30,8 @@ DCField::
|
|||
DCField(const string &name) : DCPackerInterface(name) {
|
||||
_number = -1;
|
||||
_flags = 0;
|
||||
_has_default_value = false;
|
||||
_default_value_stale = true;
|
||||
|
||||
_has_nested_fields = true;
|
||||
_num_nested_fields = 0;
|
||||
|
|
@ -180,6 +182,34 @@ validate_ranges(const string &packed_data) const {
|
|||
return (packer.get_num_unpacked_bytes() == packed_data.length());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCField::has_default_value
|
||||
// Access: Published
|
||||
// Description: Returns true if a default value has been explicitly
|
||||
// established for this field, false otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool DCField::
|
||||
has_default_value() const {
|
||||
return _has_default_value;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCField::get_default_value
|
||||
// Access: Published
|
||||
// Description: Returns the default value for this field. If a
|
||||
// default value has been explicitly set
|
||||
// (e.g. has_default_value() returns true), returns that
|
||||
// value; otherwise, returns an implicit default for the
|
||||
// field.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
const string &DCField::
|
||||
get_default_value() const {
|
||||
if (_default_value_stale) {
|
||||
((DCField *)this)->refresh_default_value();
|
||||
}
|
||||
return _default_value;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCField::is_required
|
||||
// Access: Published
|
||||
|
|
@ -488,6 +518,28 @@ generate_hash(HashGenerator &hashgen) const {
|
|||
hashgen.add_string(_name);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCField::pack_default_value
|
||||
// Access: Public, Virtual
|
||||
// Description: 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 packed,
|
||||
// false if the field doesn't know how to pack its
|
||||
// default value.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool DCField::
|
||||
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());
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCField::set_number
|
||||
// Access: Public
|
||||
|
|
@ -500,6 +552,18 @@ set_number(int number) {
|
|||
_number = number;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCField::set_default_value
|
||||
// Access: Public
|
||||
// Description: Establishes a default value for this field.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void DCField::
|
||||
set_default_value(const string &default_value) {
|
||||
_default_value = default_value;
|
||||
_has_default_value = true;
|
||||
_default_value_stale = false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCField::add_flag
|
||||
// Access: Public
|
||||
|
|
@ -530,6 +594,25 @@ get_flags() const {
|
|||
return _flags;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCField::refresh_default_value
|
||||
// Access: Protected
|
||||
// Description: Recomputes the default value of the field by
|
||||
// repacking it.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void DCField::
|
||||
refresh_default_value() {
|
||||
DCPacker packer;
|
||||
packer.begin_pack(this);
|
||||
packer.pack_default_value();
|
||||
if (!packer.end_pack()) {
|
||||
cerr << "Error while packing default value for " << get_name() << "\n";
|
||||
} else {
|
||||
_default_value.assign(packer.get_data(), packer.get_length());
|
||||
}
|
||||
_default_value_stale = false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCField::output_flags
|
||||
// Access: Protected
|
||||
|
|
|
|||
|
|
@ -54,6 +54,9 @@ PUBLISHED:
|
|||
|
||||
bool validate_ranges(const string &packed_data) const;
|
||||
|
||||
bool has_default_value() const;
|
||||
const string &get_default_value() const;
|
||||
|
||||
bool is_required() const;
|
||||
bool is_broadcast() const;
|
||||
bool is_p2p() const;
|
||||
|
|
@ -81,8 +84,10 @@ public:
|
|||
virtual void output(ostream &out, bool brief) const=0;
|
||||
virtual void write(ostream &out, bool brief, int indent_level) const=0;
|
||||
virtual void generate_hash(HashGenerator &hashgen) const;
|
||||
virtual bool pack_default_value(DCPackData &pack_data, bool &pack_error) const;
|
||||
|
||||
void set_number(int number);
|
||||
void set_default_value(const string &default_value);
|
||||
|
||||
enum Flags {
|
||||
F_required = 0x0001,
|
||||
|
|
@ -100,13 +105,18 @@ public:
|
|||
int get_flags() const;
|
||||
|
||||
protected:
|
||||
void refresh_default_value();
|
||||
void output_flags(ostream &out) const;
|
||||
|
||||
protected:
|
||||
int _number;
|
||||
bool _default_value_stale;
|
||||
bool _has_default_value;
|
||||
|
||||
private:
|
||||
int _flags; // A bitmask union of any of the above values.
|
||||
|
||||
string _default_value;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -105,6 +105,10 @@ add_atomic(DCAtomicField *atomic) {
|
|||
if (!_has_range_limits) {
|
||||
_has_range_limits = atomic->has_range_limits();
|
||||
}
|
||||
if (!_has_default_value) {
|
||||
_has_default_value = atomic->has_default_value();
|
||||
}
|
||||
_default_value_stale = true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -560,6 +560,34 @@ pop() {
|
|||
advance();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCPacker::pack_default_value
|
||||
// Access: Published
|
||||
// Description: Adds the default value for the current element into
|
||||
// the stream. If no default has been set for the
|
||||
// current element, creates a sensible default.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void DCPacker::
|
||||
pack_default_value() {
|
||||
nassertv(_mode == M_pack || _mode == M_repack);
|
||||
if (_current_field == NULL) {
|
||||
_pack_error = true;
|
||||
} else {
|
||||
if (_current_field->pack_default_value(_pack_data, _pack_error)) {
|
||||
advance();
|
||||
|
||||
} else {
|
||||
// If the single field didn't know how to pack a default value,
|
||||
// try packing nested fields.
|
||||
push();
|
||||
while (more_nested_fields()) {
|
||||
pack_default_value();
|
||||
}
|
||||
pop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCPacker::unpack_validate
|
||||
// Access: Published
|
||||
|
|
@ -938,7 +966,7 @@ unpack_and_format(ostream &out) {
|
|||
}
|
||||
|
||||
push();
|
||||
while (more_nested_fields()) {
|
||||
while (more_nested_fields() && !had_pack_error()) {
|
||||
unpack_and_format(out);
|
||||
|
||||
if (more_nested_fields()) {
|
||||
|
|
|
|||
|
|
@ -82,6 +82,7 @@ PUBLISHED:
|
|||
INLINE void pack_uint64(PN_uint64 value);
|
||||
INLINE void pack_string(const string &value);
|
||||
INLINE void pack_literal_value(const string &value);
|
||||
void pack_default_value();
|
||||
|
||||
INLINE double unpack_double();
|
||||
INLINE int unpack_int();
|
||||
|
|
|
|||
|
|
@ -210,6 +210,20 @@ pack_string(DCPackData &, const string &, bool &pack_error, bool &) const {
|
|||
pack_error = true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCPackerInterface::pack_default_value
|
||||
// Access: Public, Virtual
|
||||
// Description: 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 packed,
|
||||
// false if the field doesn't know how to pack its
|
||||
// default value.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool DCPackerInterface::
|
||||
pack_default_value(DCPackData &, bool &) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCPackerInterface::unpack_double
|
||||
// Access: Public, Virtual
|
||||
|
|
|
|||
|
|
@ -109,6 +109,7 @@ public:
|
|||
bool &pack_error, bool &range_error) const;
|
||||
virtual void pack_string(DCPackData &pack_data, const string &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,
|
||||
double &value, bool &pack_error, bool &range_error) const;
|
||||
|
|
|
|||
|
|
@ -120,7 +120,7 @@ get_typedef() const {
|
|||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCParameter::set_typedef
|
||||
// Access: Published
|
||||
// Access: Public
|
||||
// Description: Records the DCTypedef object that generated this
|
||||
// parameter. This is normally called only from
|
||||
// DCTypedef::make_new_parameter().
|
||||
|
|
|
|||
|
|
@ -32,7 +32,6 @@ static DCClass *current_class = (DCClass *)NULL;
|
|||
static DCSwitch *current_switch = (DCSwitch *)NULL;
|
||||
static DCAtomicField *current_atomic = (DCAtomicField *)NULL;
|
||||
static DCMolecularField *current_molecular = (DCMolecularField *)NULL;
|
||||
static DCAtomicField::ElementType atomic_element(new DCSimpleParameter(ST_invalid));
|
||||
static DCParameter *current_parameter = (DCParameter *)NULL;
|
||||
static DCPacker default_packer;
|
||||
static DCPacker *current_packer;
|
||||
|
|
@ -424,8 +423,7 @@ nonempty_parameter_list:
|
|||
atomic_element:
|
||||
parameter
|
||||
{
|
||||
atomic_element = DCAtomicField::ElementType($1);
|
||||
current_atomic->add_element(atomic_element);
|
||||
current_atomic->add_element($1);
|
||||
}
|
||||
| parameter '='
|
||||
{
|
||||
|
|
@ -436,9 +434,8 @@ atomic_element:
|
|||
parameter_value
|
||||
{
|
||||
bool is_valid = $1->is_valid();
|
||||
atomic_element = DCAtomicField::ElementType($1);
|
||||
if (current_packer->end_pack()) {
|
||||
atomic_element.set_default_value(current_packer->get_string());
|
||||
$1->set_default_value(current_packer->get_string());
|
||||
|
||||
} else {
|
||||
if (is_valid) {
|
||||
|
|
@ -448,7 +445,7 @@ atomic_element:
|
|||
// error (there's no way for us to validate the syntax). So we'll
|
||||
// just ignore the default value in this case.
|
||||
}
|
||||
current_atomic->add_element(atomic_element);
|
||||
current_atomic->add_element($1);
|
||||
}
|
||||
;
|
||||
|
||||
|
|
|
|||
|
|
@ -666,7 +666,7 @@ pack_int(DCPackData &pack_data, int value,
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void DCSimpleParameter::
|
||||
pack_uint(DCPackData &pack_data, unsigned int value,
|
||||
bool &pack_error, bool &range_error) const {
|
||||
bool &pack_error, bool &range_error) const {
|
||||
unsigned int int_value = value * _divisor;
|
||||
|
||||
switch (_type) {
|
||||
|
|
@ -912,6 +912,103 @@ pack_string(DCPackData &pack_data, const string &value,
|
|||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCSimpleParameter::pack_default_value
|
||||
// Access: Public, Virtual
|
||||
// Description: Packs the simpleParameter's specified default value (or a
|
||||
// sensible default if no value is specified) into the
|
||||
// stream. Returns true if the default value is packed,
|
||||
// false if the simpleParameter doesn't know how to pack its
|
||||
// default value.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool DCSimpleParameter::
|
||||
pack_default_value(DCPackData &pack_data, bool &pack_error) const {
|
||||
if (has_default_value()) {
|
||||
return DCField::pack_default_value(pack_data, pack_error);
|
||||
}
|
||||
|
||||
if (_has_nested_fields) {
|
||||
// If the simple type is an array (or string) type, pack the
|
||||
// appropriate length array, with code similar to
|
||||
// DCArrayParameter::pack_default_value().
|
||||
|
||||
unsigned int minimum_length = 0;
|
||||
if (!_uint_range.is_empty()) {
|
||||
minimum_length = _uint_range.get_min(0);
|
||||
}
|
||||
|
||||
DCPacker packer;
|
||||
packer.begin_pack(this);
|
||||
packer.push();
|
||||
for (unsigned int i = 0; i < minimum_length; i++) {
|
||||
packer.pack_default_value();
|
||||
}
|
||||
packer.pop();
|
||||
if (!packer.end_pack()) {
|
||||
pack_error = true;
|
||||
|
||||
} else {
|
||||
pack_data.append_data(packer.get_data(), packer.get_length());
|
||||
}
|
||||
|
||||
} else {
|
||||
// Otherwise, if it's just a simple numeric type, pack a zero or
|
||||
// the minimum value.
|
||||
switch (_type) {
|
||||
case ST_int8:
|
||||
case ST_int16:
|
||||
case ST_int32:
|
||||
if (_int_range.is_in_range(0)) {
|
||||
pack_int(pack_data, 0, pack_error, pack_error);
|
||||
} else {
|
||||
pack_int(pack_data, _int_range.get_min(0), pack_error, pack_error);
|
||||
}
|
||||
break;
|
||||
|
||||
case ST_int64:
|
||||
if (_int64_range.is_in_range(0)) {
|
||||
pack_int64(pack_data, 0, pack_error, pack_error);
|
||||
} else {
|
||||
pack_int64(pack_data, _int64_range.get_min(0), pack_error, pack_error);
|
||||
}
|
||||
break;
|
||||
|
||||
case ST_char:
|
||||
case ST_uint8:
|
||||
case ST_uint16:
|
||||
case ST_uint32:
|
||||
if (_uint_range.is_in_range(0)) {
|
||||
pack_uint(pack_data, 0, pack_error, pack_error);
|
||||
} else {
|
||||
pack_uint(pack_data, _uint_range.get_min(0), pack_error, pack_error);
|
||||
}
|
||||
break;
|
||||
|
||||
case ST_uint64:
|
||||
if (_uint64_range.is_in_range(0)) {
|
||||
pack_uint64(pack_data, 0, pack_error, pack_error);
|
||||
} else {
|
||||
pack_uint64(pack_data, _uint64_range.get_min(0), pack_error, pack_error);
|
||||
}
|
||||
break;
|
||||
|
||||
case ST_float64:
|
||||
if (_double_range.is_in_range(0.0)) {
|
||||
pack_double(pack_data, 0.0, pack_error, pack_error);
|
||||
} else {
|
||||
pack_double(pack_data, _double_range.get_min(0), pack_error, pack_error);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
pack_error = true;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCSimpleParameter::unpack_double
|
||||
// Access: Public, Virtual
|
||||
|
|
|
|||
|
|
@ -65,6 +65,7 @@ public:
|
|||
bool &pack_error, bool &range_error) const;
|
||||
virtual void pack_string(DCPackData &pack_data, const string &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,
|
||||
double &value, bool &pack_error, bool &range_error) const;
|
||||
|
|
|
|||
|
|
@ -361,6 +361,44 @@ generate_hash(HashGenerator &hashgen) const {
|
|||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCSwitch::pack_default_value
|
||||
// Access: Public
|
||||
// Description: Packs the switchParameter's specified default value (or a
|
||||
// sensible default if no value is specified) into the
|
||||
// stream. Returns true if the default value is packed,
|
||||
// false if the switchParameter doesn't know how to pack its
|
||||
// default value.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool DCSwitch::
|
||||
pack_default_value(DCPackData &pack_data, bool &pack_error) const {
|
||||
if (_cases.empty()) {
|
||||
pack_error = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
// The default value for a switch is the first case.
|
||||
|
||||
DCPacker packer;
|
||||
packer.begin_pack(_cases[0]);
|
||||
packer.pack_literal_value(_cases[0]->_value);
|
||||
if (!packer.end_pack()) {
|
||||
pack_error = true;
|
||||
}
|
||||
|
||||
// Then everything within the case gets its normal default.
|
||||
for (size_t i = 1; i < _cases[0]->_fields.size(); i++) {
|
||||
packer.begin_pack(_cases[0]->_fields[i]);
|
||||
packer.pack_default_value();
|
||||
if (!packer.end_pack()) {
|
||||
pack_error = true;
|
||||
}
|
||||
}
|
||||
pack_data.append_data(packer.get_data(), packer.get_length());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCSwitch::SwitchCase::Constructor
|
||||
// Access: Public
|
||||
|
|
@ -379,6 +417,7 @@ SwitchCase(const string &name, const string &value) :
|
|||
_fixed_byte_size = 0;
|
||||
_has_fixed_structure = true;
|
||||
_has_range_limits = false;
|
||||
_has_default_value = false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -449,5 +488,8 @@ add_field(DCField *field) {
|
|||
if (!_has_range_limits) {
|
||||
_has_range_limits = field->has_range_limits();
|
||||
}
|
||||
if (!_has_default_value) {
|
||||
_has_default_value = field->has_default_value();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -67,11 +67,9 @@ public:
|
|||
const string &prename, const string &name,
|
||||
const string &postname) const;
|
||||
virtual void generate_hash(HashGenerator &hashgen) const;
|
||||
virtual bool pack_default_value(DCPackData &pack_data, bool &pack_error) const;
|
||||
|
||||
private:
|
||||
string _name;
|
||||
DCParameter *_key_parameter;
|
||||
|
||||
public:
|
||||
typedef pvector<DCField *> Fields;
|
||||
typedef pmap<string, DCField *> FieldsByName;
|
||||
|
||||
|
|
@ -86,8 +84,13 @@ private:
|
|||
string _value;
|
||||
Fields _fields;
|
||||
FieldsByName _fields_by_name;
|
||||
bool _has_default_value;
|
||||
};
|
||||
|
||||
private:
|
||||
string _name;
|
||||
DCParameter *_key_parameter;
|
||||
|
||||
typedef pvector<SwitchCase *> Cases;
|
||||
Cases _cases;
|
||||
|
||||
|
|
|
|||
|
|
@ -47,13 +47,14 @@ DCSwitchParameter(const DCSwitch *dswitch) :
|
|||
DCParameter *key_parameter = dswitch->get_key_parameter();
|
||||
_has_fixed_byte_size = _has_fixed_byte_size && key_parameter->has_fixed_byte_size();
|
||||
_has_range_limits = _has_range_limits || key_parameter->has_range_limits();
|
||||
_has_default_value = _has_default_value || key_parameter->has_default_value();
|
||||
|
||||
int num_cases = _dswitch->get_num_cases();
|
||||
if (num_cases > 0) {
|
||||
_fixed_byte_size = _dswitch->get_case(0)->get_fixed_byte_size();
|
||||
|
||||
for (int i = 0; i < num_cases; i++) {
|
||||
const DCPackerInterface *dcase = _dswitch->get_case(i);
|
||||
const DCSwitch::SwitchCase *dcase = (const DCSwitch::SwitchCase *)_dswitch->get_case(i);
|
||||
if (!dcase->has_fixed_byte_size() ||
|
||||
dcase->get_fixed_byte_size() != _fixed_byte_size) {
|
||||
|
||||
|
|
@ -62,6 +63,7 @@ DCSwitchParameter(const DCSwitch *dswitch) :
|
|||
}
|
||||
|
||||
_has_range_limits = _has_range_limits || dcase->has_range_limits();
|
||||
_has_default_value = _has_default_value || dcase->_has_default_value;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -194,3 +196,21 @@ generate_hash(HashGenerator &hashgen) const {
|
|||
DCParameter::generate_hash(hashgen);
|
||||
_dswitch->generate_hash(hashgen);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCSwitchParameter::pack_default_value
|
||||
// Access: Public, Virtual
|
||||
// Description: Packs the switchParameter's specified default value (or a
|
||||
// sensible default if no value is specified) into the
|
||||
// stream. Returns true if the default value is packed,
|
||||
// false if the switchParameter doesn't know how to pack its
|
||||
// default value.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool DCSwitchParameter::
|
||||
pack_default_value(DCPackData &pack_data, bool &pack_error) const {
|
||||
if (has_default_value()) {
|
||||
return DCField::pack_default_value(pack_data, pack_error);
|
||||
}
|
||||
|
||||
return _dswitch->pack_default_value(pack_data, pack_error);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -53,6 +53,7 @@ public:
|
|||
const string &prename, const string &name,
|
||||
const string &postname) const;
|
||||
virtual void generate_hash(HashGenerator &hashgen) const;
|
||||
virtual bool pack_default_value(DCPackData &pack_data, bool &pack_error) const;
|
||||
|
||||
private:
|
||||
const DCSwitch *_dswitch;
|
||||
|
|
|
|||
Loading…
Reference in New Issue