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  */
69 get_num_elements() const {
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  */
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  */
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  */
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  */
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  */
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  */
222 add_element(DCParameter *element) {
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 }
indent
std::ostream & indent(std::ostream &out, int indent_level)
A handy function for doing text formatting.
Definition: indent.cxx:20
DCSimpleParameter::get_type
DCSubatomicType get_type() const
Returns the particular subatomic type represented by this instance.
Definition: dcSimpleParameter.cxx:256
DCPacker::set_unpack_data
void set_unpack_data(const std::vector< unsigned char > &data)
Sets up the unpack_data pointer.
Definition: dcPacker.cxx:117
DCAtomicField::as_atomic_field
virtual DCAtomicField * as_atomic_field()
Returns the same field pointer converted to an atomic field pointer, if this is in fact an atomic fie...
Definition: dcAtomicField.cxx:52
DCField::get_default_value
const std::vector< unsigned char > & get_default_value() const
Returns the default value for this field.
Definition: dcField.I:46
DCAtomicField::get_element
DCParameter * get_element(int n) const
Returns the parameter object describing the nth element.
Definition: dcAtomicField.cxx:77
DCAtomicField::write
virtual void write(std::ostream &out, bool brief, int indent_level) const
Generates a parseable description of the object to the indicated output stream.
Definition: dcAtomicField.cxx:179
dcSimpleParameter.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
dcAtomicField.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
DCPackerInterface::has_fixed_byte_size
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.
Definition: dcPackerInterface.I:37
DCAtomicField::has_element_default
bool has_element_default(int n) const
Returns true if the nth element of the field has a default value specified, false otherwise.
Definition: dcAtomicField.cxx:106
HashGenerator::add_int
void add_int(int num)
Adds another integer to the hash so far.
Definition: hashGenerator.cxx:41
DCPackerInterface::has_fixed_structure
bool has_fixed_structure() const
Returns true if this field type always has the same structure regardless of the data in the stream,...
Definition: dcPackerInterface.I:59
DCPacker::unpack_and_format
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
DCPackerInterface::get_fixed_byte_size
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.
Definition: dcPackerInterface.I:46
DCPackerInterface
This defines the internal interface for packing values into a DCField.
Definition: dcPackerInterface.h:67
DCAtomicField::get_element_name
std::string get_element_name(int n) const
Returns the name of the nth element of the field.
Definition: dcAtomicField.cxx:119
DCPacker
This class can be used for packing a series of numeric and string data into a binary stream,...
Definition: dcPacker.h:34
DCField
A single field of a Distributed Class, either atomic or molecular.
Definition: dcField.h:37
DCAtomicField::add_element
void add_element(DCParameter *element)
Adds a new element (parameter) to the field.
Definition: dcAtomicField.cxx:222
dcPacker.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
DCSimpleParameter::get_divisor
int get_divisor() const
Returns the divisor associated with this type.
Definition: dcSimpleParameter.cxx:287
DCPackerInterface::has_range_limits
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...
Definition: dcPackerInterface.I:69
DCAtomicField::get_element_default
std::vector< unsigned char > get_element_default(int n) const
Returns the pre-formatted default value associated with the nth element of the field.
Definition: dcAtomicField.cxx:94
DCSubatomicType
DCSubatomicType
This defines the numeric type of each element of a DCAtomicField; that is, the particular values that...
Definition: dcSubatomicType.h:25
DCPackerInterface::check_match
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 ...
Definition: dcPackerInterface.I:28
hashGenerator.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
DCAtomicField::get_nested_field
virtual DCPackerInterface * get_nested_field(int n) const
Returns the DCPackerInterface object that represents the nth nested field.
Definition: dcAtomicField.cxx:211
DCAtomicField::get_num_elements
int get_num_elements() const
Returns the number of elements (parameters) of the atomic field.
Definition: dcAtomicField.cxx:69
DCPackerInterface::do_check_match_atomic_field
virtual bool do_check_match_atomic_field(const DCAtomicField *other) const
Returns true if this field matches the indicated atomic field, false otherwise.
Definition: dcPackerInterface.cxx:435
DCAtomicField::generate_hash
virtual void generate_hash(HashGenerator &hashgen) const
Accumulates the properties of this field into the hash.
Definition: dcAtomicField.cxx:193
DCPacker::end_unpack
bool end_unpack()
Finishes the unpacking session.
Definition: dcPacker.cxx:179
DCParameter
Represents the type specification for a single parameter within a field specification.
Definition: dcParameter.h:35
DCField::has_default_value
bool has_default_value() const
Returns true if a default value has been explicitly established for this field, false otherwise.
Definition: dcField.I:36
DCKeywordList::generate_hash
void generate_hash(HashGenerator &hashgen) const
Accumulates the properties of these keywords into the hash.
Definition: dcKeywordList.cxx:162
dcindent.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
DCAtomicField
A single atomic field of a Distributed Class, as read from a .dc file.
Definition: dcAtomicField.h:30
HashGenerator
This class generates an arbitrary hash number from a sequence of ints.
Definition: hashGenerator.h:23
DCSimpleParameter
This is the most fundamental kind of parameter type: a single number or string, one of the DCSubatomi...
Definition: dcSimpleParameter.h:28
DCAtomicField::get_element_divisor
int get_element_divisor(int n) const
Returns the divisor associated with the nth element of the field.
Definition: dcAtomicField.cxx:145
DCField::generate_hash
virtual void generate_hash(HashGenerator &hashgen) const
Accumulates the properties of this field into the hash.
Definition: dcField.cxx:467
DCClass
Defines a particular DistributedClass as read from an input .dc file.
Definition: dcClass.h:44
DCPacker::begin_unpack
void begin_unpack(const DCPackerInterface *root)
Begins an unpacking session.
Definition: dcPacker.cxx:153
DCAtomicField::get_element_type
DCSubatomicType get_element_type(int n) const
Returns the numeric type of the nth element of the field.
Definition: dcAtomicField.cxx:129