Panda3D
dcSwitchParameter.cxx
Go to the documentation of this file.
1 /**
2  * PANDA 3D SOFTWARE
3  * Copyright (c) Carnegie Mellon University. All rights reserved.
4  *
5  * All use of this software is subject to the terms of the revised BSD
6  * license. You should have received a copy of this license along
7  * with this source code in a file named "LICENSE."
8  *
9  * @file dcSwitchParameter.cxx
10  * @author drose
11  * @date 2004-06-18
12  */
13 
14 #include "dcSwitchParameter.h"
15 #include "dcSwitch.h"
16 #include "hashGenerator.h"
17 
18 using std::string;
19 
20 /**
21  *
22  */
23 DCSwitchParameter::
24 DCSwitchParameter(const DCSwitch *dswitch) :
25  _dswitch(dswitch)
26 {
27  set_name(dswitch->get_name());
28 
29  _has_fixed_byte_size = true;
30  _fixed_byte_size = 0;
31  _has_fixed_structure = false;
32 
33  // The DCSwitch presents just one nested field initially, which is the key
34  // parameter. When we pack or unpack that, the DCPacker calls
35  // apply_switch(), which returns a new record that presents the remaining
36  // nested fields.
37  _has_nested_fields = true;
38  _num_nested_fields = 1;
39 
40  _pack_type = PT_switch;
41 
42  DCField *key_parameter = dswitch->get_key_parameter();
43  _has_fixed_byte_size = _has_fixed_byte_size && key_parameter->has_fixed_byte_size();
44  _has_range_limits = _has_range_limits || key_parameter->has_range_limits();
45  _has_default_value = _has_default_value || key_parameter->has_default_value();
46 
47  int num_cases = _dswitch->get_num_cases();
48  if (num_cases > 0) {
49  _fixed_byte_size = _dswitch->get_case(0)->get_fixed_byte_size();
50 
51  // Consider each case for fixed size, etc.
52  for (int i = 0; i < num_cases; i++) {
53  const DCSwitch::SwitchFields *fields =
54  (const DCSwitch::SwitchFields *)_dswitch->get_case(i);
55 
56  if (!fields->has_fixed_byte_size() ||
57  fields->get_fixed_byte_size() != _fixed_byte_size) {
58 
59  // Nope, we have a variable byte size.
60  _has_fixed_byte_size = false;
61  }
62 
63  _has_range_limits = _has_range_limits || fields->has_range_limits();
64  _has_default_value = _has_default_value || fields->_has_default_value;
65  }
66  }
67 
68  // Also consider the default case, if there is one.
69  const DCSwitch::SwitchFields *fields =
70  (DCSwitch::SwitchFields *)_dswitch->get_default_case();
71  if (fields != nullptr) {
72  if (!fields->has_fixed_byte_size() ||
73  fields->get_fixed_byte_size() != _fixed_byte_size) {
74  _has_fixed_byte_size = false;
75  }
76 
77  _has_range_limits = _has_range_limits || fields->has_range_limits();
78  _has_default_value = _has_default_value || fields->_has_default_value;
79  }
80 }
81 
82 /**
83  *
84  */
85 DCSwitchParameter::
86 DCSwitchParameter(const DCSwitchParameter &copy) :
87  DCParameter(copy),
88  _dswitch(copy._dswitch)
89 {
90 }
91 
92 /**
93  *
94  */
95 DCSwitchParameter *DCSwitchParameter::
96 as_switch_parameter() {
97  return this;
98 }
99 
100 /**
101  *
102  */
103 const DCSwitchParameter *DCSwitchParameter::
104 as_switch_parameter() const {
105  return this;
106 }
107 
108 /**
109  *
110  */
111 DCParameter *DCSwitchParameter::
112 make_copy() const {
113  return new DCSwitchParameter(*this);
114 }
115 
116 /**
117  * Returns false if the type is an invalid type (e.g. declared from an
118  * undefined typedef), true if it is valid.
119  */
121 is_valid() const {
122  return true; //_dswitch->is_valid();
123 }
124 
125 /**
126  * Returns the switch object this parameter represents.
127  */
129 get_switch() const {
130  return _dswitch;
131 }
132 
133 /**
134  * Returns the DCPackerInterface object that represents the nth nested field.
135  * This may return NULL if there is no such field (but it shouldn't do this if
136  * n is in the range 0 <= n < get_num_nested_fields()).
137  */
139 get_nested_field(int) const {
140  return _dswitch->get_key_parameter();
141 }
142 
143 /**
144  * Returns the DCPackerInterface that presents the alternative fields for the
145  * case indicated by the given packed value string, or NULL if the value
146  * string does not match one of the expected cases.
147  */
149 apply_switch(const char *value_data, size_t length) const {
150  return _dswitch->apply_switch(value_data, length);
151 }
152 
153 /**
154  * Formats the parameter in the C++-like dc syntax as a typename and
155  * identifier.
156  */
158 output_instance(std::ostream &out, bool brief, const string &prename,
159  const string &name, const string &postname) const {
160  if (get_typedef() != nullptr) {
161  output_typedef_name(out, brief, prename, name, postname);
162 
163  } else {
164  _dswitch->output_instance(out, brief, prename, name, postname);
165  }
166 }
167 
168 /**
169  * Formats the parameter in the C++-like dc syntax as a typename and
170  * identifier.
171  */
173 write_instance(std::ostream &out, bool brief, int indent_level,
174  const string &prename, const string &name,
175  const string &postname) const {
176  if (get_typedef() != nullptr) {
177  write_typedef_name(out, brief, indent_level, prename, name, postname);
178 
179  } else {
180  _dswitch->write_instance(out, brief, indent_level, prename, name, postname);
181  }
182 }
183 
184 /**
185  * Accumulates the properties of this type into the hash.
186  */
188 generate_hash(HashGenerator &hashgen) const {
190  _dswitch->generate_hash(hashgen);
191 }
192 
193 /**
194  * Packs the switchParameter's specified default value (or a sensible default
195  * if no value is specified) into the stream. Returns true if the default
196  * value is packed, false if the switchParameter doesn't know how to pack its
197  * default value.
198  */
200 pack_default_value(DCPackData &pack_data, bool &pack_error) const {
201  if (has_default_value()) {
202  return DCField::pack_default_value(pack_data, pack_error);
203  }
204 
205  return _dswitch->pack_default_value(pack_data, pack_error);
206 }
207 
208 /**
209  * Returns true if the other interface is bitwise the same as this one--that
210  * is, a uint32 only matches a uint32, etc. Names of components, and range
211  * limits, are not compared.
212  */
213 bool DCSwitchParameter::
214 do_check_match(const DCPackerInterface *other) const {
215  return other->do_check_match_switch_parameter(this);
216 }
217 
218 /**
219  * Returns true if this field matches the indicated switch parameter, false
220  * otherwise.
221  */
222 bool DCSwitchParameter::
223 do_check_match_switch_parameter(const DCSwitchParameter *other) const {
224  return _dswitch->do_check_match_switch(other->_dswitch);
225 }
virtual void generate_hash(HashGenerator &hashgen) const
Accumulates the properties of this type into the hash.
This is a block of data that receives the results of DCPacker.
Definition: dcPackData.h:22
const DCSwitch * get_switch() const
Returns the switch object this parameter represents.
DCField * get_key_parameter() const
Returns the key parameter on which the switch is based.
Definition: dcSwitch.cxx:94
A single field of a Distributed Class, either atomic or molecular.
Definition: dcField.h:37
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
virtual void write_instance(std::ostream &out, bool brief, int indent_level, const std::string &prename, const std::string &name, const std::string &postname) const
Formats the parameter in the C++-like dc syntax as a typename and identifier.
virtual DCPackerInterface * get_nested_field(int n) const
Returns the DCPackerInterface object that represents the nth nested field.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
virtual bool pack_default_value(DCPackData &pack_data, bool &pack_error) const
Packs the field's specified default value (or a sensible default if no value is specified) into the s...
Definition: dcField.cxx:487
bool has_fixed_byte_size() const
Returns true if this field type always packs to the same number of bytes, false if it is variable.
This represents a switch statement, which can appear inside a class body and represents two or more a...
Definition: dcSwitch.h:30
This represents a switch object used as a parameter itself, which packs the appropriate fields of the...
virtual void generate_hash(HashGenerator &hashgen) const
Accumulates the properties of this type into the hash.
size_t get_fixed_byte_size() const
If has_fixed_byte_size() returns true, this returns the number of bytes this field type will use.
bool has_range_limits() const
Returns true if this field, or any sub-field of this field, has a limit imposed in the DC file on its...
Represents the type specification for a single parameter within a field specification.
Definition: dcParameter.h:35
virtual bool pack_default_value(DCPackData &pack_data, bool &pack_error) const
Packs the switchParameter's specified default value (or a sensible default if no value is specified) ...
const std::string & get_name() const
Returns the name of this switch.
Definition: dcSwitch.cxx:84
bool has_default_value() const
Returns true if a default value has been explicitly established for this field, false otherwise.
Definition: dcField.I:36
This class generates an arbitrary hash number from a sequence of ints.
Definition: hashGenerator.h:24
virtual void output_instance(std::ostream &out, bool brief, const std::string &prename, const std::string &name, const std::string &postname) const
Formats the parameter in the C++-like dc syntax as a typename and identifier.
virtual bool is_valid() const
Returns false if the type is an invalid type (e.g.
virtual bool do_check_match_switch_parameter(const DCSwitchParameter *other) const
Returns true if this field matches the indicated switch parameter, false otherwise.
This defines the internal interface for packing values into a DCField.
const DCPackerInterface * apply_switch(const char *value_data, size_t length) const
Returns the DCPackerInterface that presents the alternative fields for the case indicated by the give...