Panda3D
dcAtomicField.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 dcAtomicField.cxx
10  * @author drose
11  * @date 2000-10-05
12  */
13 
14 #include "dcAtomicField.h"
15 #include "hashGenerator.h"
16 #include "dcindent.h"
17 #include "dcSimpleParameter.h"
18 #include "dcPacker.h"
19 
20 #include <math.h>
21 
22 using std::string;
23 
24 /**
25  *
26  */
27 DCAtomicField::
28 DCAtomicField(const string &name, DCClass *dclass,
29  bool bogus_field) :
30  DCField(name, dclass)
31 {
32  _bogus_field = bogus_field;
33 }
34 
35 /**
36  *
37  */
38 DCAtomicField::
39 ~DCAtomicField() {
40  Elements::iterator ei;
41  for (ei = _elements.begin(); ei != _elements.end(); ++ei) {
42  delete (*ei);
43  }
44  _elements.clear();
45 }
46 
47 /**
48  * Returns the same field pointer converted to an atomic field pointer, if
49  * this is in fact an atomic field; otherwise, returns NULL.
50  */
53  return this;
54 }
55 
56 /**
57  * Returns the same field pointer converted to an atomic field pointer, if
58  * this is in fact an atomic field; otherwise, returns NULL.
59  */
61 as_atomic_field() const {
62  return this;
63 }
64 
65 /**
66  * Returns the number of elements (parameters) of the atomic field.
67  */
70  return _elements.size();
71 }
72 
73 /**
74  * Returns the parameter object describing the nth element.
75  */
77 get_element(int n) const {
78  nassertr(n >= 0 && n < (int)_elements.size(), nullptr);
79  return _elements[n];
80 }
81 
82 /**
83  * Returns the pre-formatted default value associated with the nth element of
84  * the field. This is only valid if has_element_default() returns true, in
85  * which case this string represents the bytes that should be assigned to the
86  * field as a default value.
87  *
88  * If the element is an array-type element, the returned value will include
89  * the two-byte length preceding the array data.
90  *
91  * @deprecated use get_element() instead.
92  */
93 vector_uchar DCAtomicField::
94 get_element_default(int n) const {
95  nassertr(n >= 0 && n < (int)_elements.size(), vector_uchar());
96  return _elements[n]->get_default_value();
97 }
98 
99 /**
100  * Returns true if the nth element of the field has a default value specified,
101  * false otherwise.
102  *
103  * @deprecated use get_element() instead.
104  */
105 bool DCAtomicField::
106 has_element_default(int n) const {
107  nassertr(n >= 0 && n < (int)_elements.size(), false);
108  return _elements[n]->has_default_value();
109 }
110 
111 /**
112  * Returns the name of the nth element of the field. This name is strictly
113  * for documentary purposes; it does not generally affect operation. If a
114  * name is not specified, this will be the empty string.
115  *
116  * @deprecated use get_element()->get_name() instead.
117  */
118 string DCAtomicField::
119 get_element_name(int n) const {
120  nassertr(n >= 0 && n < (int)_elements.size(), string());
121  return _elements[n]->get_name();
122 }
123 
124 /**
125  * Returns the numeric type of the nth element of the field. This method is
126  * deprecated; use get_element() instead.
127  */
129 get_element_type(int n) const {
130  nassertr(n >= 0 && n < (int)_elements.size(), ST_invalid);
131  DCSimpleParameter *simple_parameter = _elements[n]->as_simple_parameter();
132  nassertr(simple_parameter != nullptr, ST_invalid);
133  return simple_parameter->get_type();
134 }
135 
136 /**
137  * Returns the divisor associated with the nth element of the field. This
138  * implements an implicit fixed-point system; floating-point values are to be
139  * multiplied by this value before encoding into a packet, and divided by this
140  * number after decoding.
141  *
142  * This method is deprecated; use get_element()->get_divisor() instead.
143  */
144 int DCAtomicField::
145 get_element_divisor(int n) const {
146  nassertr(n >= 0 && n < (int)_elements.size(), 1);
147  DCSimpleParameter *simple_parameter = _elements[n]->as_simple_parameter();
148  nassertr(simple_parameter != nullptr, 1);
149  return simple_parameter->get_divisor();
150 }
151 
152 /**
153  *
154  */
155 void DCAtomicField::
156 output(std::ostream &out, bool brief) const {
157  out << _name << "(";
158 
159  if (!_elements.empty()) {
160  Elements::const_iterator ei = _elements.begin();
161  output_element(out, brief, *ei);
162  ++ei;
163  while (ei != _elements.end()) {
164  out << ", ";
165  output_element(out, brief, *ei);
166  ++ei;
167  }
168  }
169  out << ")";
170 
171  output_keywords(out);
172 }
173 
174 /**
175  * Generates a parseable description of the object to the indicated output
176  * stream.
177  */
178 void DCAtomicField::
179 write(std::ostream &out, bool brief, int indent_level) const {
180  indent(out, indent_level);
181  output(out, brief);
182  out << ";";
183  if (!brief && _number >= 0) {
184  out << " // field " << _number;
185  }
186  out << "\n";
187 }
188 
189 /**
190  * Accumulates the properties of this field into the hash.
191  */
192 void DCAtomicField::
193 generate_hash(HashGenerator &hashgen) const {
194  DCField::generate_hash(hashgen);
195 
196  hashgen.add_int(_elements.size());
197  Elements::const_iterator ei;
198  for (ei = _elements.begin(); ei != _elements.end(); ++ei) {
199  (*ei)->generate_hash(hashgen);
200  }
201 
203 }
204 
205 /**
206  * Returns the DCPackerInterface object that represents the nth nested field.
207  * This may return NULL if there is no such field (but it shouldn't do this if
208  * n is in the range 0 <= n < get_num_nested_fields()).
209  */
211 get_nested_field(int n) const {
212  nassertr(n >= 0 && n < (int)_elements.size(), nullptr);
213  return _elements[n];
214 }
215 
216 /**
217  * Adds a new element (parameter) to the field. Normally this is called only
218  * during parsing. The DCAtomicField object becomes the owner of the new
219  * pointer and will delete it upon destruction.
220  */
221 void DCAtomicField::
223  _elements.push_back(element);
224  _num_nested_fields = (int)_elements.size();
225 
226  // See if we still have a fixed byte size.
227  if (_has_fixed_byte_size) {
228  _has_fixed_byte_size = element->has_fixed_byte_size();
229  _fixed_byte_size += element->get_fixed_byte_size();
230  }
231  if (_has_fixed_structure) {
232  _has_fixed_structure = element->has_fixed_structure();
233  }
234  if (!_has_range_limits) {
235  _has_range_limits = element->has_range_limits();
236  }
237  if (!_has_default_value) {
238  _has_default_value = element->has_default_value();
239  }
240  _default_value_stale = true;
241 }
242 
243 /**
244  * Returns true if the other interface is bitwise the same as this one--that
245  * is, a uint32 only matches a uint32, etc. Names of components, and range
246  * limits, are not compared.
247  */
248 bool DCAtomicField::
249 do_check_match(const DCPackerInterface *other) const {
250  return other->do_check_match_atomic_field(this);
251 }
252 
253 /**
254  * Returns true if this field matches the indicated atomic field, false
255  * otherwise.
256  */
257 bool DCAtomicField::
258 do_check_match_atomic_field(const DCAtomicField *other) const {
259  if (_elements.size() != other->_elements.size()) {
260  return false;
261  }
262  for (size_t i = 0; i < _elements.size(); i++) {
263  if (!_elements[i]->check_match(other->_elements[i])) {
264  return false;
265  }
266  }
267 
268  return true;
269 }
270 
271 /**
272  *
273  */
274 void DCAtomicField::
275 output_element(std::ostream &out, bool brief, DCParameter *element) const {
276  element->output(out, brief);
277 
278  if (!brief && element->has_default_value()) {
279  out << " = ";
280  DCPacker packer;
281  packer.set_unpack_data(element->get_default_value());
282  packer.begin_unpack(element);
283  packer.unpack_and_format(out, false);
284  packer.end_unpack();
285  }
286 }
virtual void generate_hash(HashGenerator &hashgen) const
Accumulates the properties of this field into the hash.
DCSubatomicType
This defines the numeric type of each element of a DCAtomicField; that is, the particular values that...
virtual DCAtomicField * as_atomic_field()
Returns the same field pointer converted to an atomic field pointer, if this is in fact an atomic fie...
bool has_fixed_structure() const
Returns true if this field type always has the same structure regardless of the data in the stream,...
void add_int(int num)
Adds another integer to the hash so far.
A single field of a Distributed Class, either atomic or molecular.
Definition: dcField.h:37
DCParameter * get_element(int n) const
Returns the parameter object describing the nth element.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This is the most fundamental kind of parameter type: a single number or string, one of the DCSubatomi...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
virtual void write(std::ostream &out, bool brief, int indent_level) const
Generates a parseable description of the object to the indicated output stream.
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.
Defines a particular DistributedClass as read from an input .dc file.
Definition: dcClass.h:44
const vector_uchar & get_default_value() const
Returns the default value for this field.
Definition: dcField.I:46
vector_uchar get_element_default(int n) const
Returns the pre-formatted default value associated with the nth element of the field.
A single atomic field of a Distributed Class, as read from a .dc file.
Definition: dcAtomicField.h:30
virtual void generate_hash(HashGenerator &hashgen) const
Accumulates the properties of this field into the hash.
Definition: dcField.cxx:467
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.
void add_element(DCParameter *element)
Adds a new element (parameter) to the field.
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...
int get_num_elements() const
Returns the number of elements (parameters) of the atomic field.
Represents the type specification for a single parameter within a field specification.
Definition: dcParameter.h:35
void set_unpack_data(const vector_uchar &data)
Sets up the unpack_data pointer.
Definition: dcPacker.cxx:117
DCSubatomicType get_element_type(int n) const
Returns the numeric type of the nth element of the field.
bool check_match(const DCPackerInterface *other) const
Returns true if the other interface is bitwise the same as this oneā€“that is, a uint32 only matches a ...
std::ostream & indent(std::ostream &out, int indent_level)
A handy function for doing text formatting.
Definition: indent.cxx:20
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
std::string unpack_and_format(bool show_field_names=true)
Unpacks an object and formats its value into a syntax suitable for parsing in the dc file (e....
Definition: dcPacker.cxx:989
virtual bool do_check_match_atomic_field(const DCAtomicField *other) const
Returns true if this field matches the indicated atomic field, false otherwise.
void generate_hash(HashGenerator &hashgen) const
Accumulates the properties of these keywords into the hash.
This class can be used for packing a series of numeric and string data into a binary stream,...
Definition: dcPacker.h:34
int get_element_divisor(int n) const
Returns the divisor associated with the nth element of the field.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This defines the internal interface for packing values into a DCField.
bool has_element_default(int n) const
Returns true if the nth element of the field has a default value specified, false otherwise.
std::string get_element_name(int n) const
Returns the name of the nth element of the field.
void begin_unpack(const DCPackerInterface *root)
Begins an unpacking session.
Definition: dcPacker.cxx:153
bool end_unpack()
Finishes the unpacking session.
Definition: dcPacker.cxx:179
virtual DCPackerInterface * get_nested_field(int n) const
Returns the DCPackerInterface object that represents the nth nested field.