Panda3D
dcField.cxx
1 // Filename: dcField.cxx
2 // Created by: drose (11Oct00)
3 //
4 ////////////////////////////////////////////////////////////////////
5 //
6 // PANDA 3D SOFTWARE
7 // Copyright (c) Carnegie Mellon University. All rights reserved.
8 //
9 // All use of this software is subject to the terms of the revised BSD
10 // license. You should have received a copy of this license along
11 // with this source code in a file named "LICENSE."
12 //
13 ////////////////////////////////////////////////////////////////////
14 
15 #include "dcField.h"
16 #include "dcFile.h"
17 #include "dcPacker.h"
18 #include "dcClass.h"
19 #include "hashGenerator.h"
20 #include "dcmsgtypes.h"
21 
22 #ifdef HAVE_PYTHON
23 #include "py_panda.h"
24 #endif
25 
26 #ifdef WITHIN_PANDA
27 #include "pStatTimer.h"
28 #endif
29 
30 ////////////////////////////////////////////////////////////////////
31 // Function: DCField::Constructor
32 // Access: Public
33 // Description:
34 ////////////////////////////////////////////////////////////////////
35 DCField::
36 DCField() :
37  _dclass(NULL)
38 #ifdef WITHIN_PANDA
39  ,
40  _field_update_pcollector("DCField")
41 #endif
42 {
43  _number = -1;
44  _default_value_stale = true;
45  _has_default_value = false;
46 
47  _bogus_field = false;
48 
49  _has_nested_fields = true;
50  _num_nested_fields = 0;
51  _pack_type = PT_field;
52 
53  _has_fixed_byte_size = true;
54  _fixed_byte_size = 0;
55  _has_fixed_structure = true;
56 }
57 
58 ////////////////////////////////////////////////////////////////////
59 // Function: DCField::Constructor
60 // Access: Public
61 // Description:
62 ////////////////////////////////////////////////////////////////////
63 DCField::
64 DCField(const string &name, DCClass *dclass) :
65  DCPackerInterface(name),
66  _dclass(dclass)
67 #ifdef WITHIN_PANDA
68  ,
69  _field_update_pcollector(dclass->_class_update_pcollector, name)
70 #endif
71 {
72  _number = -1;
73  _has_default_value = false;
74  _default_value_stale = true;
75 
76  _bogus_field = false;
77 
78  _has_nested_fields = true;
79  _num_nested_fields = 0;
80  _pack_type = PT_field;
81 
82  _has_fixed_byte_size = true;
83  _fixed_byte_size = 0;
84  _has_fixed_structure = true;
85 }
86 
87 ////////////////////////////////////////////////////////////////////
88 // Function: DCField::Destructor
89 // Access: Public, Virtual
90 // Description:
91 ////////////////////////////////////////////////////////////////////
92 DCField::
93 ~DCField() {
94 }
95 
96 ////////////////////////////////////////////////////////////////////
97 // Function: DCField::as_field
98 // Access: Published, Virtual
99 // Description:
100 ////////////////////////////////////////////////////////////////////
101 DCField *DCField::
102 as_field() {
103  return this;
104 }
105 
106 ////////////////////////////////////////////////////////////////////
107 // Function: DCField::as_field
108 // Access: Published, Virtual
109 // Description:
110 ////////////////////////////////////////////////////////////////////
111 const DCField *DCField::
112 as_field() const {
113  return this;
114 }
115 
116 ////////////////////////////////////////////////////////////////////
117 // Function: DCField::as_atomic_field
118 // Access: Published, Virtual
119 // Description: Returns the same field pointer converted to an atomic
120 // field pointer, if this is in fact an atomic field;
121 // otherwise, returns NULL.
122 ////////////////////////////////////////////////////////////////////
125  return (DCAtomicField *)NULL;
126 }
127 
128 ////////////////////////////////////////////////////////////////////
129 // Function: DCField::as_atomic_field
130 // Access: Published, Virtual
131 // Description: Returns the same field pointer converted to an atomic
132 // field pointer, if this is in fact an atomic field;
133 // otherwise, returns NULL.
134 ////////////////////////////////////////////////////////////////////
137  return (DCAtomicField *)NULL;
138 }
139 
140 ////////////////////////////////////////////////////////////////////
141 // Function: DCField::as_molecular_field
142 // Access: Published, Virtual
143 // Description: Returns the same field pointer converted to a
144 // molecular field pointer, if this is in fact a
145 // molecular field; otherwise, returns NULL.
146 ////////////////////////////////////////////////////////////////////
149  return (DCMolecularField *)NULL;
150 }
151 
152 ////////////////////////////////////////////////////////////////////
153 // Function: DCField::as_molecular_field
154 // Access: Published, Virtual
155 // Description: Returns the same field pointer converted to a
156 // molecular field pointer, if this is in fact a
157 // molecular field; otherwise, returns NULL.
158 ////////////////////////////////////////////////////////////////////
161  return (DCMolecularField *)NULL;
162 }
163 
164 ////////////////////////////////////////////////////////////////////
165 // Function: DCField::as_parameter
166 // Access: Published, Virtual
167 // Description:
168 ////////////////////////////////////////////////////////////////////
169 DCParameter *DCField::
170 as_parameter() {
171  return (DCParameter *)NULL;
172 }
173 
174 ////////////////////////////////////////////////////////////////////
175 // Function: DCField::as_parameter
176 // Access: Published, Virtual
177 // Description:
178 ////////////////////////////////////////////////////////////////////
179 const DCParameter *DCField::
180 as_parameter() const {
181  return (DCParameter *)NULL;
182 }
183 
184 ////////////////////////////////////////////////////////////////////
185 // Function: DCField::format_data
186 // Access: Published
187 // Description: Given a blob that represents the packed data for this
188 // field, returns a string formatting it for human
189 // consumption. Returns empty string if there is an error.
190 ////////////////////////////////////////////////////////////////////
191 string DCField::
192 format_data(const string &packed_data, bool show_field_names) {
193  DCPacker packer;
194  packer.set_unpack_data(packed_data);
195  packer.begin_unpack(this);
196  string result = packer.unpack_and_format(show_field_names);
197  if (!packer.end_unpack()) {
198  return string();
199  }
200  return result;
201 }
202 
203 ////////////////////////////////////////////////////////////////////
204 // Function: DCField::parse_string
205 // Access: Published
206 // Description: Given a human-formatted string (for instance, as
207 // returned by format_data(), above) that represents the
208 // value of this field, parse the string and return the
209 // corresponding packed data. Returns empty string if
210 // there is an error.
211 ////////////////////////////////////////////////////////////////////
212 string DCField::
213 parse_string(const string &formatted_string) {
214  DCPacker packer;
215  packer.begin_pack(this);
216  if (!packer.parse_and_pack(formatted_string)) {
217  // Parse error.
218  return string();
219  }
220  if (!packer.end_pack()) {
221  // Data type mismatch.
222  return string();
223  }
224 
225  return packer.get_string();
226 }
227 
228 ////////////////////////////////////////////////////////////////////
229 // Function: DCField::validate_ranges
230 // Access: Published
231 // Description: Verifies that all of the packed values in the field
232 // data are within the specified ranges and that there
233 // are no extra bytes on the end of the record. Returns
234 // true if all fields are valid, false otherwise.
235 ////////////////////////////////////////////////////////////////////
236 bool DCField::
237 validate_ranges(const string &packed_data) const {
238  DCPacker packer;
239  packer.set_unpack_data(packed_data);
240  packer.begin_unpack(this);
241  packer.unpack_validate();
242  if (!packer.end_unpack()) {
243  return false;
244  }
245 
246  return (packer.get_num_unpacked_bytes() == packed_data.length());
247 }
248 
249 #ifdef HAVE_PYTHON
250 ////////////////////////////////////////////////////////////////////
251 // Function: DCField::pack_args
252 // Access: Published
253 // Description: Packs the Python arguments from the indicated tuple
254 // into the packer. Returns true on success, false on
255 // failure.
256 //
257 // It is assumed that the packer is currently positioned
258 // on this field.
259 ////////////////////////////////////////////////////////////////////
260 bool DCField::
261 pack_args(DCPacker &packer, PyObject *sequence) const {
262  nassertr(!packer.had_error(), false);
263  nassertr(packer.get_current_field() == this, false);
264 
265  packer.pack_object(sequence);
266  if (!packer.had_error()) {
267  /*
268  cerr << "pack " << get_name() << get_pystr(sequence) << "\n";
269  */
270 
271  return true;
272  }
273 
274  if (!Notify::ptr()->has_assert_failed()) {
275  ostringstream strm;
276  PyObject *exc_type = PyExc_Exception;
277 
278  if (as_parameter() != (DCParameter *)NULL) {
279  // If it's a parameter-type field, the value may or may not be a
280  // sequence.
281  if (packer.had_pack_error()) {
282  strm << "Incorrect arguments to field: " << get_name()
283  << " = " << get_pystr(sequence);
284  exc_type = PyExc_TypeError;
285  } else {
286  strm << "Value out of range on field: " << get_name()
287  << " = " << get_pystr(sequence);
288  exc_type = PyExc_ValueError;
289  }
290 
291  } else {
292  // If it's a molecular or atomic field, the value should be a
293  // sequence.
294  PyObject *tuple = PySequence_Tuple(sequence);
295  if (tuple == (PyObject *)NULL) {
296  strm << "Value for " << get_name() << " not a sequence: " \
297  << get_pystr(sequence);
298  exc_type = PyExc_TypeError;
299 
300  } else {
301  if (packer.had_pack_error()) {
302  strm << "Incorrect arguments to field: " << get_name()
303  << get_pystr(sequence);
304  exc_type = PyExc_TypeError;
305  } else {
306  strm << "Value out of range on field: " << get_name()
307  << get_pystr(sequence);
308  exc_type = PyExc_ValueError;
309  }
310 
311  Py_DECREF(tuple);
312  }
313  }
314 
315  string message = strm.str();
316  PyErr_SetString(exc_type, message.c_str());
317  }
318  return false;
319 }
320 #endif // HAVE_PYTHON
321 
322 #ifdef HAVE_PYTHON
323 ////////////////////////////////////////////////////////////////////
324 // Function: DCField::unpack_args
325 // Access: Published
326 // Description: Unpacks the values from the packer, beginning at
327 // the current point in the unpack_buffer, into a Python
328 // tuple and returns the tuple.
329 //
330 // It is assumed that the packer is currently positioned
331 // on this field.
332 ////////////////////////////////////////////////////////////////////
333 PyObject *DCField::
334 unpack_args(DCPacker &packer) const {
335  nassertr(!packer.had_error(), NULL);
336  nassertr(packer.get_current_field() == this, NULL);
337 
338  size_t start_byte = packer.get_num_unpacked_bytes();
339  PyObject *object = packer.unpack_object();
340 
341  if (!packer.had_error()) {
342  // Successfully unpacked.
343  /*
344  cerr << "recv " << get_name() << get_pystr(object) << "\n";
345  */
346 
347  return object;
348  }
349 
350  if (!Notify::ptr()->has_assert_failed()) {
351  ostringstream strm;
352  PyObject *exc_type = PyExc_Exception;
353 
354  if (packer.had_pack_error()) {
355  strm << "Data error unpacking field ";
356  output(strm, true);
357  size_t length = packer.get_unpack_length() - start_byte;
358  strm << "\nGot data (" << (int)length << " bytes):\n";
359  Datagram dg(packer.get_unpack_data() + start_byte, length);
360  dg.dump_hex(strm);
361  size_t error_byte = packer.get_num_unpacked_bytes() - start_byte;
362  strm << "Error detected on byte " << error_byte
363  << " (" << hex << error_byte << dec << " hex)";
364 
365  exc_type = PyExc_RuntimeError;
366  } else {
367  strm << "Value outside specified range when unpacking field "
368  << get_name() << ": " << get_pystr(object);
369  exc_type = PyExc_ValueError;
370  }
371 
372  string message = strm.str();
373  PyErr_SetString(exc_type, message.c_str());
374  }
375 
376  Py_XDECREF(object);
377  return NULL;
378 }
379 #endif // HAVE_PYTHON
380 
381 #ifdef HAVE_PYTHON
382 ////////////////////////////////////////////////////////////////////
383 // Function: DCField::receive_update
384 // Access: Published
385 // Description: Extracts the update message out of the datagram and
386 // applies it to the indicated object by calling the
387 // appropriate method.
388 ////////////////////////////////////////////////////////////////////
389 void DCField::
390 receive_update(DCPacker &packer, PyObject *distobj) const {
391  if (as_parameter() != (DCParameter *)NULL) {
392  // If it's a parameter-type field, just store a new value on the
393  // object.
394  PyObject *value = unpack_args(packer);
395  if (value != (PyObject *)NULL) {
396  PyObject_SetAttrString(distobj, (char *)_name.c_str(), value);
397  }
398  Py_DECREF(value);
399 
400  } else {
401  // Otherwise, it must be an atomic or molecular field, so call the
402  // corresponding method.
403 
404  if (!PyObject_HasAttrString(distobj, (char *)_name.c_str())) {
405  // If there's no Python method to receive this message, don't
406  // bother unpacking it to a Python tuple--just skip past the
407  // message.
408  packer.unpack_skip();
409 
410  } else {
411  // Otherwise, get a Python tuple from the args and call the Python
412  // method.
413  PyObject *args = unpack_args(packer);
414 
415  if (args != (PyObject *)NULL) {
416  PyObject *func = PyObject_GetAttrString(distobj, (char *)_name.c_str());
417  nassertv(func != (PyObject *)NULL);
418 
419  PyObject *result;
420  {
421 #ifdef WITHIN_PANDA
422  PStatTimer timer(((DCField *)this)->_field_update_pcollector);
423 #endif
424  result = PyObject_CallObject(func, args);
425  }
426  Py_XDECREF(result);
427  Py_DECREF(func);
428  Py_DECREF(args);
429  }
430  }
431  }
432 }
433 #endif // HAVE_PYTHON
434 
435 #ifdef HAVE_PYTHON
436 ////////////////////////////////////////////////////////////////////
437 // Function: DCField::client_format_update
438 // Access: Published
439 // Description: Generates a datagram containing the message necessary
440 // to send an update for the indicated distributed
441 // object from the client.
442 ////////////////////////////////////////////////////////////////////
443 Datagram DCField::
444 client_format_update(DOID_TYPE do_id, PyObject *args) const {
445  DCPacker packer;
446 
447  packer.raw_pack_uint16(CLIENT_OBJECT_UPDATE_FIELD);
448  packer.raw_pack_uint32(do_id);
449  packer.raw_pack_uint16(_number);
450 
451  packer.begin_pack(this);
452  pack_args(packer, args);
453  if (!packer.end_pack()) {
454  return Datagram();
455  }
456 
457  return Datagram(packer.get_data(), packer.get_length());
458 }
459 #endif // HAVE_PYTHON
460 
461 #ifdef HAVE_PYTHON
462 ////////////////////////////////////////////////////////////////////
463 // Function: DCField::ai_format_update
464 // Access: Published
465 // Description: Generates a datagram containing the message necessary
466 // to send an update for the indicated distributed
467 // object from the AI.
468 ////////////////////////////////////////////////////////////////////
469 Datagram DCField::
470 ai_format_update(DOID_TYPE do_id, CHANNEL_TYPE to_id, CHANNEL_TYPE from_id, PyObject *args) const {
471  DCPacker packer;
472 
473  packer.raw_pack_uint8(1);
474  packer.RAW_PACK_CHANNEL(to_id);
475  packer.RAW_PACK_CHANNEL(from_id);
476  packer.raw_pack_uint16(STATESERVER_OBJECT_UPDATE_FIELD);
477  packer.raw_pack_uint32(do_id);
478  packer.raw_pack_uint16(_number);
479 
480  packer.begin_pack(this);
481  pack_args(packer, args);
482  if (!packer.end_pack()) {
483  return Datagram();
484  }
485 
486  return Datagram(packer.get_data(), packer.get_length());
487 }
488 #endif // HAVE_PYTHON
489 
490 #ifdef HAVE_PYTHON
491 ////////////////////////////////////////////////////////////////////
492 // Function: DCField::ai_format_update_msg_type
493 // Access: Published
494 // Description: Generates a datagram containing the message necessary
495 // to send an update, with the msg type,
496 // for the indicated distributed
497 // object from the AI.
498 ////////////////////////////////////////////////////////////////////
499 Datagram DCField::
500 ai_format_update_msg_type(DOID_TYPE do_id, CHANNEL_TYPE to_id, CHANNEL_TYPE from_id, int msg_type, PyObject *args) const {
501  DCPacker packer;
502 
503  packer.raw_pack_uint8(1);
504  packer.RAW_PACK_CHANNEL(to_id);
505  packer.RAW_PACK_CHANNEL(from_id);
506  packer.raw_pack_uint16(msg_type);
507  packer.raw_pack_uint32(do_id);
508  packer.raw_pack_uint16(_number);
509 
510  packer.begin_pack(this);
511  pack_args(packer, args);
512  if (!packer.end_pack()) {
513  return Datagram();
514  }
515 
516  return Datagram(packer.get_data(), packer.get_length());
517 }
518 #endif // HAVE_PYTHON
519 
520 
521 ////////////////////////////////////////////////////////////////////
522 // Function: DCField::generate_hash
523 // Access: Public, Virtual
524 // Description: Accumulates the properties of this field into the
525 // hash.
526 ////////////////////////////////////////////////////////////////////
527 void DCField::
528 generate_hash(HashGenerator &hashgen) const {
529  // It shouldn't be necessary to explicitly add _number to the
530  // hash--this is computed based on the relative position of this
531  // field with the other fields, so adding it explicitly will be
532  // redundant. However, the field name is significant.
533  hashgen.add_string(_name);
534 
535  // Actually, we add _number anyway, since we need to ensure the hash
536  // code comes out different in the dc_multiple_inheritance case.
537  if (dc_multiple_inheritance) {
538  hashgen.add_int(_number);
539  }
540 }
541 
542 ////////////////////////////////////////////////////////////////////
543 // Function: DCField::pack_default_value
544 // Access: Public, Virtual
545 // Description: Packs the field's specified default value (or a
546 // sensible default if no value is specified) into the
547 // stream. Returns true if the default value is packed,
548 // false if the field doesn't know how to pack its
549 // default value.
550 ////////////////////////////////////////////////////////////////////
551 bool DCField::
552 pack_default_value(DCPackData &pack_data, bool &) const {
553  // The default behavior is to pack the default value if we got it;
554  // otherwise, to return false and let the packer visit our nested
555  // elements.
556  if (!_default_value_stale) {
557  pack_data.append_data(_default_value.data(), _default_value.length());
558  return true;
559  }
560 
561  return false;
562 }
563 
564 ////////////////////////////////////////////////////////////////////
565 // Function: DCField::set_name
566 // Access: Public, Virtual
567 // Description: Sets the name of this field.
568 ////////////////////////////////////////////////////////////////////
569 void DCField::
570 set_name(const string &name) {
572  if (_dclass != (DCClass *)NULL) {
573  _dclass->_dc_file->mark_inherited_fields_stale();
574  }
575 }
576 
577 #ifdef HAVE_PYTHON
578 ////////////////////////////////////////////////////////////////////
579 // Function: DCField::get_pystr
580 // Access: Public, Static
581 // Description: Returns the string representation of the indicated
582 // Python object.
583 ////////////////////////////////////////////////////////////////////
584 string DCField::
585 get_pystr(PyObject *value) {
586  if (value == NULL) {
587  return "(null)";
588  }
589 
590  PyObject *str = PyObject_Str(value);
591  if (str != NULL) {
592 #if PY_MAJOR_VERSION >= 3
593  string result = PyUnicode_AsUTF8(str);
594 #else
595  string result = PyString_AsString(str);
596 #endif
597  Py_DECREF(str);
598  return result;
599  }
600 
601  PyObject *repr = PyObject_Repr(value);
602  if (repr != NULL) {
603 #if PY_MAJOR_VERSION >= 3
604  string result = PyUnicode_AsUTF8(repr);
605 #else
606  string result = PyString_AsString(repr);
607 #endif
608  Py_DECREF(repr);
609  return result;
610  }
611 
612  if (value->ob_type != NULL) {
613  PyObject *typestr = PyObject_Str((PyObject *)(value->ob_type));
614  if (typestr != NULL) {
615 #if PY_MAJOR_VERSION >= 3
616  string result = PyUnicode_AsUTF8(typestr);
617 #else
618  string result = PyString_AsString(typestr);
619 #endif
620  Py_DECREF(typestr);
621  return result;
622  }
623  }
624 
625  return "(invalid object)";
626 }
627 #endif // HAVE_PYTHON
628 
629 ////////////////////////////////////////////////////////////////////
630 // Function: DCField::refresh_default_value
631 // Access: Protected
632 // Description: Recomputes the default value of the field by
633 // repacking it.
634 ////////////////////////////////////////////////////////////////////
635 void DCField::
636 refresh_default_value() {
637  DCPacker packer;
638  packer.begin_pack(this);
639  packer.pack_default_value();
640  if (!packer.end_pack()) {
641  cerr << "Error while packing default value for " << get_name() << "\n";
642  } else {
643  _default_value.assign(packer.get_data(), packer.get_length());
644  }
645  _default_value_stale = false;
646 }
void add_string(const string &str)
Adds a string to the hash, by breaking it down into a sequence of integers.
bool had_error() const
Returns true if there has been any error (either a pack error or a range error) since the most recent...
Definition: dcPacker.I:625
This is a block of data that receives the results of DCPacker.
Definition: dcPackData.h:25
void append_data(const char *buffer, size_t size)
Adds the indicated bytes to the end of the data.
Definition: dcPackData.I:57
string format_data(const string &packed_data, bool show_field_names=true)
Given a blob that represents the packed data for this field, returns a string formatting it for human...
Definition: dcField.cxx:192
bool parse_and_pack(const string &formatted_object)
Parses an object&#39;s value according to the DC file syntax (e.g.
Definition: dcPacker.cxx:1022
void add_int(int num)
Adds another integer to the hash so far.
string get_string() const
Returns the packed data buffer as a string.
Definition: dcPacker.I:663
size_t get_num_unpacked_bytes() const
Returns the number of bytes that have been unpacked so far, or after unpack_end(), the total number of bytes that were unpacked at all.
Definition: dcPacker.I:640
A single field of a Distributed Class, either atomic or molecular.
Definition: dcField.h:40
void dump_hex(ostream &out, unsigned int indent=0) const
Writes a representation of the entire datagram contents, as a sequence of hex (and ASCII) values...
Definition: datagram.cxx:52
bool has_assert_failed() const
Returns true if an assertion test has failed (and not been ignored) since the last call to clear_asse...
Definition: pnotify.I:37
const DCPackerInterface * get_current_field() const
Returns the field that will be referenced by the next call to pack_*() or unpack_*().
Definition: dcPacker.I:109
void raw_pack_uint8(unsigned int value)
Packs the data into the buffer between packing sessions.
Definition: dcPacker.I:847
const string & get_name() const
Returns the name of this field, or empty string if the field is unnamed.
virtual bool pack_default_value(DCPackData &pack_data, bool &pack_error) const
Packs the field&#39;s specified default value (or a sensible default if no value is specified) into the s...
Definition: dcField.cxx:552
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: dcField.cxx:124
Defines a particular DistributedClass as read from an input .dc file.
Definition: dcClass.h:47
bool had_pack_error() const
Returns true if there has been an packing error since the most recent call to begin(); in particular...
Definition: dcPacker.I:592
A lightweight class that can be used to automatically start and stop a PStatCollector around a sectio...
Definition: pStatTimer.h:34
size_t get_length() const
Returns the current length of the buffer.
Definition: dcPacker.I:652
A single atomic field of a Distributed Class, as read from a .dc file.
Definition: dcAtomicField.h:34
virtual DCMolecularField * as_molecular_field()
Returns the same field pointer converted to a molecular field pointer, if this is in fact a molecular...
Definition: dcField.cxx:148
virtual void generate_hash(HashGenerator &hashgen) const
Accumulates the properties of this field into the hash.
Definition: dcField.cxx:528
void raw_pack_uint32(unsigned int value)
Packs the data into the buffer between packing sessions.
Definition: dcPacker.I:871
size_t get_unpack_length() const
Returns the total number of bytes in the unpack data buffer.
Definition: dcPacker.I:676
static Notify * ptr()
Returns the pointer to the global Notify object.
Definition: notify.cxx:337
bool validate_ranges(const string &packed_data) const
Verifies that all of the packed values in the field data are within the specified ranges and that the...
Definition: dcField.cxx:237
Represents the type specification for a single parameter within a field specification.
Definition: dcParameter.h:39
string parse_string(const string &formatted_string)
Given a human-formatted string (for instance, as returned by format_data(), above) that represents th...
Definition: dcField.cxx:213
void pack_default_value()
Adds the default value for the current element into the stream.
Definition: dcPacker.cxx:597
void raw_pack_uint16(unsigned int value)
Packs the data into the buffer between packing sessions.
Definition: dcPacker.I:859
void output(ostream &out) const
Write a string representation of this instance to <out>.
Definition: dcField.I:187
const char * get_data() const
Returns the beginning of the data buffer.
Definition: dcPacker.I:717
This class generates an arbitrary hash number from a sequence of ints.
Definition: hashGenerator.h:26
void mark_inherited_fields_stale()
Indicates that something has changed in one or more of the inheritance chains or the set of fields; t...
Definition: dcFile.I:52
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:1056
void begin_pack(const DCPackerInterface *root)
Begins a packing session.
Definition: dcPacker.cxx:76
This class can be used for packing a series of numeric and string data into a binary stream...
Definition: dcPacker.h:38
virtual void set_name(const string &name)
Sets the name of this field.
Definition: dcField.cxx:570
void unpack_skip()
Skips the current field without unpacking it and advances to the next field.
Definition: dcPacker.cxx:655
virtual void set_name(const string &name)
Sets the name of this field.
bool end_pack()
Finishes a packing session.
Definition: dcPacker.cxx:103
void set_unpack_data(const string &data)
Sets up the unpack_data pointer.
Definition: dcPacker.cxx:125
const char * get_unpack_data() const
Returns a read pointer to the unpack data buffer.
Definition: dcPacker.I:775
A single molecular field of a Distributed Class, as read from a .dc file.
An ordered list of data elements, formatted in memory for transmission over a socket or writing to a ...
Definition: datagram.h:43
This defines the internal interface for packing values into a DCField.
void begin_unpack(const DCPackerInterface *root)
Begins an unpacking session.
Definition: dcPacker.cxx:168
bool end_unpack()
Finishes the unpacking session.
Definition: dcPacker.cxx:197
void unpack_validate()
Internally unpacks the current numeric or string value and validates it against the type range limits...
Definition: dcPacker.cxx:626