39 _field_update_pcollector(
"DCField")
43 _default_value_stale =
true;
44 _has_default_value =
false;
48 _has_nested_fields =
true;
49 _num_nested_fields = 0;
50 _pack_type = PT_field;
52 _has_fixed_byte_size =
true;
54 _has_fixed_structure =
true;
61 DCField(
const string &name,
DCClass *dclass) :
66 _field_update_pcollector(dclass->_class_update_pcollector, name)
70 _has_default_value =
false;
71 _default_value_stale =
true;
75 _has_nested_fields =
true;
76 _num_nested_fields = 0;
77 _pack_type = PT_field;
79 _has_fixed_byte_size =
true;
81 _has_fixed_structure =
true;
155 as_parameter()
const {
165 format_data(
const vector_uchar &packed_data,
bool show_field_names) {
187 return vector_uchar();
191 return vector_uchar();
223 pack_args(
DCPacker &packer, PyObject *sequence)
const {
227 packer.pack_object(sequence);
237 std::ostringstream strm;
238 PyObject *exc_type = PyExc_Exception;
240 if (as_parameter() !=
nullptr) {
244 strm <<
"Incorrect arguments to field: " <<
get_name()
245 <<
" = " << get_pystr(sequence);
246 exc_type = PyExc_TypeError;
248 strm <<
"Value out of range on field: " <<
get_name()
249 <<
" = " << get_pystr(sequence);
250 exc_type = PyExc_ValueError;
255 PyObject *tuple = PySequence_Tuple(sequence);
256 if (tuple ==
nullptr) {
257 strm <<
"Value for " <<
get_name() <<
" not a sequence: " \
258 << get_pystr(sequence);
259 exc_type = PyExc_TypeError;
263 strm <<
"Incorrect arguments to field: " <<
get_name()
264 << get_pystr(sequence);
265 exc_type = PyExc_TypeError;
267 strm <<
"Value out of range on field: " <<
get_name()
268 << get_pystr(sequence);
269 exc_type = PyExc_ValueError;
276 string message = strm.str();
277 PyErr_SetString(exc_type, message.c_str());
281 #endif // HAVE_PYTHON 291 unpack_args(
DCPacker &packer)
const {
296 PyObject *
object = packer.unpack_object();
308 std::ostringstream strm;
309 PyObject *exc_type = PyExc_Exception;
312 strm <<
"Data error unpacking field ";
315 strm <<
"\nGot data (" << (int)length <<
" bytes):\n";
319 strm <<
"Error detected on byte " << error_byte
320 <<
" (" << std::hex << error_byte << std::dec <<
" hex)";
322 exc_type = PyExc_RuntimeError;
324 strm <<
"Value outside specified range when unpacking field " 325 <<
get_name() <<
": " << get_pystr(
object);
326 exc_type = PyExc_ValueError;
329 string message = strm.str();
330 PyErr_SetString(exc_type, message.c_str());
336 #endif // HAVE_PYTHON 344 receive_update(
DCPacker &packer, PyObject *distobj)
const {
345 if (as_parameter() !=
nullptr) {
347 PyObject *value = unpack_args(packer);
348 if (value !=
nullptr) {
349 PyObject_SetAttrString(distobj, (
char *)_name.c_str(), value);
357 if (!PyObject_HasAttrString(distobj, (
char *)_name.c_str())) {
365 PyObject *args = unpack_args(packer);
367 if (args !=
nullptr) {
368 PyObject *func = PyObject_GetAttrString(distobj, (
char *)_name.c_str());
369 nassertv(func !=
nullptr);
376 result = PyObject_CallObject(func, args);
385 #endif // HAVE_PYTHON 393 client_format_update(DOID_TYPE do_id, PyObject *args)
const {
401 pack_args(packer, args);
408 #endif // HAVE_PYTHON 416 ai_format_update(DOID_TYPE do_id, CHANNEL_TYPE to_id, CHANNEL_TYPE from_id, PyObject *args)
const {
420 packer.RAW_PACK_CHANNEL(to_id);
421 packer.RAW_PACK_CHANNEL(from_id);
427 pack_args(packer, args);
434 #endif // HAVE_PYTHON 442 ai_format_update_msg_type(DOID_TYPE do_id, CHANNEL_TYPE to_id, CHANNEL_TYPE from_id,
int msg_type, PyObject *args)
const {
446 packer.RAW_PACK_CHANNEL(to_id);
447 packer.RAW_PACK_CHANNEL(from_id);
453 pack_args(packer, args);
460 #endif // HAVE_PYTHON 476 if (dc_multiple_inheritance) {
490 if (!_default_value_stale) {
491 pack_data.
append_data((
const char *)_default_value.data(), _default_value.size());
504 if (_dclass !=
nullptr) {
514 get_pystr(PyObject *value) {
515 if (value ==
nullptr) {
519 PyObject *str = PyObject_Str(value);
520 if (str !=
nullptr) {
521 #if PY_MAJOR_VERSION >= 3 522 string result = PyUnicode_AsUTF8(str);
524 string result = PyString_AsString(str);
530 PyObject *repr = PyObject_Repr(value);
531 if (repr !=
nullptr) {
532 #if PY_MAJOR_VERSION >= 3 533 string result = PyUnicode_AsUTF8(repr);
535 string result = PyString_AsString(repr);
541 if (value->ob_type !=
nullptr) {
542 PyObject *typestr = PyObject_Str((PyObject *)(value->ob_type));
543 if (typestr !=
nullptr) {
544 #if PY_MAJOR_VERSION >= 3 545 string result = PyUnicode_AsUTF8(typestr);
547 string result = PyString_AsString(typestr);
554 return "(invalid object)";
556 #endif // HAVE_PYTHON 562 refresh_default_value() {
567 std::cerr <<
"Error while packing default value for " <<
get_name() <<
"\n";
569 const unsigned char *data = (
const unsigned char *)packer.
get_data();
570 _default_value = vector_uchar(data, data + packer.
get_length());
572 _default_value_stale =
false;
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
vector_uchar parse_string(const std::string &formatted_string)
Given a human-formatted string (for instance, as returned by format_data(), above) that represents th...
bool had_error() const
Returns true if there has been any error (either a pack error or a range error) since the most recent...
This is a block of data that receives the results of DCPacker.
void append_data(const char *buffer, size_t size)
Adds the indicated bytes to the end of the data.
const std::string & get_name() const
Returns the name of this field, or empty string if the field is unnamed.
void dump_hex(std::ostream &out, unsigned int indent=0) const
Writes a representation of the entire datagram contents, as a sequence of hex (and ASCII) values.
bool validate_ranges(const vector_uchar &packed_data) const
Verifies that all of the packed values in the field data are within the specified ranges and that the...
void add_int(int num)
Adds another integer to the hash so far.
size_t get_num_unpacked_bytes() const
Returns the number of bytes that have been unpacked so far, or after unpack_end(),...
A single field of a Distributed Class, either atomic or molecular.
bool has_assert_failed() const
Returns true if an assertion test has failed (and not been ignored) since the last call to clear_asse...
const DCPackerInterface * get_current_field() const
Returns the field that will be referenced by the next call to pack_*() or unpack_*().
void add_string(const std::string &str)
Adds a string to the hash, by breaking it down into a sequence of integers.
void raw_pack_uint8(unsigned int value)
Packs the data into the buffer between packing sessions.
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...
virtual DCAtomicField * as_atomic_field()
Returns the same field pointer converted to an atomic field pointer, if this is in fact an atomic fie...
Defines a particular DistributedClass as read from an input .dc file.
void output(std::ostream &out) const
Write a string representation of this instance to <out>.
bool had_pack_error() const
Returns true if there has been an packing error since the most recent call to begin(); in particular,...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
A lightweight class that can be used to automatically start and stop a PStatCollector around a sectio...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
virtual void set_name(const std::string &name)
Sets the name of this field.
virtual void set_name(const std::string &name)
Sets the name of this field.
size_t get_length() const
Returns the current length of the buffer.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
A single atomic field of a Distributed Class, as read from a .dc file.
virtual DCMolecularField * as_molecular_field()
Returns the same field pointer converted to a molecular field pointer, if this is in fact a molecular...
virtual void generate_hash(HashGenerator &hashgen) const
Accumulates the properties of this field into the hash.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void raw_pack_uint32(unsigned int value)
Packs the data into the buffer between packing sessions.
size_t get_unpack_length() const
Returns the total number of bytes in the unpack data buffer.
static Notify * ptr()
Returns the pointer to the global Notify object.
Represents the type specification for a single parameter within a field specification.
void set_unpack_data(const vector_uchar &data)
Sets up the unpack_data pointer.
void pack_default_value()
Adds the default value for the current element into the stream.
void raw_pack_uint16(unsigned int value)
Packs the data into the buffer between packing sessions.
const char * get_data() const
Returns the beginning of the data buffer.
This class generates an arbitrary hash number from a sequence of ints.
void mark_inherited_fields_stale()
Indicates that something has changed in one or more of the inheritance chains or the set of fields; t...
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....
void begin_pack(const DCPackerInterface *root)
Begins a packing session.
std::string format_data(const vector_uchar &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...
This class can be used for packing a series of numeric and string data into a binary stream,...
bool parse_and_pack(const std::string &formatted_object)
Parses an object's value according to the DC file syntax (e.g.
void unpack_skip()
Skips the current field without unpacking it and advances to the next field.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
bool end_pack()
Finishes a packing session.
vector_uchar get_bytes() const
Returns the packed data buffer as a bytes object.
const char * get_unpack_data() const
Returns a read pointer to the unpack data buffer.
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 ...
This defines the internal interface for packing values into a DCField.
void begin_unpack(const DCPackerInterface *root)
Begins an unpacking session.
bool end_unpack()
Finishes the unpacking session.
void unpack_validate()
Internally unpacks the current numeric or string value and validates it against the type range limits...