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