23 if (_owns_unpack_data) {
24 delete[] _unpack_data;
25 _owns_unpack_data =
false;
27 _unpack_data =
nullptr;
38 if (_current_field ==
nullptr) {
59 return _num_nested_fields;
68 return (_current_field !=
nullptr && !_pack_error);
78 return _current_parent;
88 return _current_field;
115 if (_current_field ==
nullptr) {
128 if (_current_field ==
nullptr) {
129 return std::string();
140 nassertv(_mode == M_pack || _mode == M_repack);
141 if (_current_field ==
nullptr) {
144 _current_field->
pack_double(_pack_data, value, _pack_error, _range_error);
154 nassertv(_mode == M_pack || _mode == M_repack);
155 if (_current_field ==
nullptr) {
158 _current_field->
pack_int(_pack_data, value, _pack_error, _range_error);
168 nassertv(_mode == M_pack || _mode == M_repack);
169 if (_current_field ==
nullptr) {
172 _current_field->
pack_uint(_pack_data, value, _pack_error, _range_error);
182 nassertv(_mode == M_pack || _mode == M_repack);
183 if (_current_field ==
nullptr) {
186 _current_field->
pack_int64(_pack_data, value, _pack_error, _range_error);
196 nassertv(_mode == M_pack || _mode == M_repack);
197 if (_current_field ==
nullptr) {
200 _current_field->
pack_uint64(_pack_data, value, _pack_error, _range_error);
210 nassertv(_mode == M_pack || _mode == M_repack);
211 if (_current_field ==
nullptr) {
214 _current_field->
pack_string(_pack_data, value, _pack_error, _range_error);
224 nassertv(_mode == M_pack || _mode == M_repack);
225 if (_current_field ==
nullptr) {
228 _current_field->
pack_blob(_pack_data, value, _pack_error, _range_error);
239 nassertv(_mode == M_pack || _mode == M_repack);
240 if (_current_field ==
nullptr) {
243 _pack_data.
append_data((
const char *)value.data(), value.size());
254 nassertr(_mode == M_unpack, value);
255 if (_current_field ==
nullptr) {
259 _current_field->
unpack_double(_unpack_data, _unpack_length, _unpack_p,
260 value, _pack_error, _range_error);
273 nassertr(_mode == M_unpack, value);
274 if (_current_field ==
nullptr) {
278 _current_field->
unpack_int(_unpack_data, _unpack_length, _unpack_p,
279 value, _pack_error, _range_error);
291 unsigned int value = 0;
292 nassertr(_mode == M_unpack, value);
293 if (_current_field ==
nullptr) {
297 _current_field->
unpack_uint(_unpack_data, _unpack_length, _unpack_p,
298 value, _pack_error, _range_error);
311 nassertr(_mode == M_unpack, value);
312 if (_current_field ==
nullptr) {
316 _current_field->
unpack_int64(_unpack_data, _unpack_length, _unpack_p,
317 value, _pack_error, _range_error);
330 nassertr(_mode == M_unpack, value);
331 if (_current_field ==
nullptr) {
335 _current_field->
unpack_uint64(_unpack_data, _unpack_length, _unpack_p,
336 value, _pack_error, _range_error);
349 nassertr(_mode == M_unpack, value);
350 if (_current_field ==
nullptr) {
354 _current_field->
unpack_string(_unpack_data, _unpack_length, _unpack_p,
355 value, _pack_error, _range_error);
368 nassertr(_mode == M_unpack, value);
369 if (_current_field ==
nullptr) {
373 _current_field->
unpack_blob(_unpack_data, _unpack_length, _unpack_p,
374 value, _pack_error, _range_error);
387 size_t start = _unpack_p;
389 nassertr(_unpack_p >= start, vector_uchar());
390 return vector_uchar((
const unsigned char *)_unpack_data + start,
391 (
const unsigned char *)_unpack_data + _unpack_p);
399 nassertv(_mode == M_unpack);
400 if (_current_field ==
nullptr) {
404 _current_field->
unpack_double(_unpack_data, _unpack_length, _unpack_p,
405 value, _pack_error, _range_error);
415 nassertv(_mode == M_unpack);
416 if (_current_field ==
nullptr) {
420 _current_field->
unpack_int(_unpack_data, _unpack_length, _unpack_p,
421 value, _pack_error, _range_error);
431 nassertv(_mode == M_unpack);
432 if (_current_field ==
nullptr) {
436 _current_field->
unpack_uint(_unpack_data, _unpack_length, _unpack_p,
437 value, _pack_error, _range_error);
447 nassertv(_mode == M_unpack);
448 if (_current_field ==
nullptr) {
452 _current_field->
unpack_int64(_unpack_data, _unpack_length, _unpack_p,
453 value, _pack_error, _range_error);
463 nassertv(_mode == M_unpack);
464 if (_current_field ==
nullptr) {
468 _current_field->
unpack_uint64(_unpack_data, _unpack_length, _unpack_p,
469 value, _pack_error, _range_error);
479 nassertv(_mode == M_unpack);
480 if (_current_field ==
nullptr) {
484 _current_field->
unpack_string(_unpack_data, _unpack_length, _unpack_p,
485 value, _pack_error, _range_error);
495 nassertv(_mode == M_unpack);
496 if (_current_field ==
nullptr) {
500 _current_field->
unpack_blob(_unpack_data, _unpack_length, _unpack_p,
501 value, _pack_error, _range_error);
512 size_t start = _unpack_p;
514 nassertv(_unpack_p >= start);
515 value = vector_uchar((
const unsigned char *)_unpack_data + start,
516 (
const unsigned char *)_unpack_data + _unpack_p);
564 return _range_error || _pack_error || _parse_error;
600 const unsigned char *p = (
const unsigned char *)_pack_data.
get_data();
601 return vector_uchar(p, p + _pack_data.
get_length());
611 return _unpack_length;
621 return std::string(_unpack_data, _unpack_length);
665 nassertv(_mode == M_idle);
666 _pack_data.
append_data((
const char *)buffer, size);
676 nassertr(_mode == M_idle,
nullptr);
697 return StackElement::_num_ever_allocated;
705 nassertv(_mode == M_idle);
714 nassertv(_mode == M_idle);
723 nassertv(_mode == M_idle);
732 nassertv(_mode == M_idle);
741 nassertv(_mode == M_idle);
750 nassertv(_mode == M_idle);
759 nassertv(_mode == M_idle);
768 nassertv(_mode == M_idle);
777 nassertv(_mode == M_idle);
786 nassertv(_mode == M_idle);
787 DCPackerInterface::do_pack_uint16(_pack_data.
get_write_pointer(2), value.length());
788 _pack_data.
append_data(value.data(), value.length());
796 nassertv(_mode == M_idle);
797 DCPackerInterface::do_pack_uint16(_pack_data.
get_write_pointer(2), value.size());
798 _pack_data.
append_data((
const char *)value.data(), value.size());
846 nassertv(_mode == M_idle && _unpack_data !=
nullptr);
847 if (_unpack_p + 1 > _unpack_length) {
851 value = DCPackerInterface::do_unpack_int8(_unpack_data + _unpack_p);
860 nassertv(_mode == M_idle && _unpack_data !=
nullptr);
861 if (_unpack_p + 2 > _unpack_length) {
865 value = DCPackerInterface::do_unpack_int16(_unpack_data + _unpack_p);
874 nassertv(_mode == M_idle && _unpack_data !=
nullptr);
875 if (_unpack_p + 4 > _unpack_length) {
879 value = DCPackerInterface::do_unpack_int32(_unpack_data + _unpack_p);
888 unsigned int value = 0;
898 unsigned int value = 0;
908 unsigned int value = 0;
958 nassertv(_mode == M_idle && _unpack_data !=
nullptr);
959 if (_unpack_p + 8 > _unpack_length) {
963 value = DCPackerInterface::do_unpack_int64(_unpack_data + _unpack_p);
972 nassertv(_mode == M_idle && _unpack_data !=
nullptr);
973 if (_unpack_p + 1 > _unpack_length) {
977 value = DCPackerInterface::do_unpack_uint8(_unpack_data + _unpack_p);
986 nassertv(_mode == M_idle && _unpack_data !=
nullptr);
987 if (_unpack_p + 2 > _unpack_length) {
991 value = DCPackerInterface::do_unpack_uint16(_unpack_data + _unpack_p);
1000 nassertv(_mode == M_idle && _unpack_data !=
nullptr);
1001 if (_unpack_p + 4 > _unpack_length) {
1005 value = DCPackerInterface::do_unpack_uint32(_unpack_data + _unpack_p);
1014 nassertv(_mode == M_idle && _unpack_data !=
nullptr);
1015 if (_unpack_p + 8 > _unpack_length) {
1019 value = DCPackerInterface::do_unpack_uint64(_unpack_data + _unpack_p);
1028 nassertv(_mode == M_idle && _unpack_data !=
nullptr);
1029 if (_unpack_p + 8 > _unpack_length) {
1033 value = DCPackerInterface::do_unpack_float64(_unpack_data + _unpack_p);
1042 nassertv(_mode == M_idle && _unpack_data !=
nullptr);
1045 if (_unpack_p + string_length > _unpack_length) {
1050 value.assign(_unpack_data + _unpack_p, string_length);
1051 _unpack_p += string_length;
1059 nassertv(_mode == M_idle && _unpack_data !=
nullptr);
1062 if (_unpack_p + blob_size > _unpack_length) {
1067 const unsigned char *p = (
const unsigned char *)_unpack_data + _unpack_p;
1068 value = vector_uchar(p, p + blob_size);
1069 _unpack_p += blob_size;
1075 INLINE
void DCPacker::
1077 _current_field_index++;
1078 if (_num_nested_fields >= 0 &&
1079 _current_field_index >= _num_nested_fields) {
1082 _current_field =
nullptr;
1086 if (_current_parent !=
nullptr) {
1088 if (switch_parameter !=
nullptr) {
1089 handle_switch(switch_parameter);
1093 }
else if (_pop_marker != 0 && _unpack_p >= _pop_marker) {
1096 _current_field =
nullptr;
1108 INLINE
void *DCPacker::StackElement::
1109 operator
new(
size_t size) {
1110 if (_deleted_chain !=
nullptr) {
1111 StackElement *obj = _deleted_chain;
1112 _deleted_chain = _deleted_chain->_next;
1116 _num_ever_allocated++;
1118 return ::operator
new(size);
1125 INLINE
void DCPacker::StackElement::
1126 operator
delete(
void *ptr) {
1127 StackElement *obj = (StackElement *)ptr;
1128 obj->_next = _deleted_chain;
1129 _deleted_chain = obj;
char * get_write_pointer(size_t size)
Adds the indicated number of bytes to the end of the data without initializing them,...
uint64_t unpack_uint64()
Unpacks the current numeric or string value from the stream.
bool had_range_error() const
Returns true if there has been an range validation error since the most recent call to begin(); in pa...
void raw_pack_uint64(uint64_t value)
Packs the data into the buffer between packing sessions.
bool had_error() const
Returns true if there has been any error (either a pack error or a range error) since the most recent...
uint64_t raw_unpack_uint64()
Unpacks the data from the buffer between unpacking sessions.
DCPackType get_pack_type() const
Returns the type of value expected by the current field.
static int get_num_stack_elements_ever_allocated()
Returns the number of DCPacker::StackElement pointers ever simultaneously allocated; these are now ei...
void append_data(const char *buffer, size_t size)
Adds the indicated bytes to the end of the data.
void pack_int(int value)
Packs the indicated numeric or string value into the stream.
void raw_pack_int16(int value)
Packs the data into the buffer between packing sessions.
const std::string & get_name() const
Returns the name of this field, or empty string if the field is unnamed.
virtual void pack_uint(DCPackData &pack_data, unsigned int value, bool &pack_error, bool &range_error) const
Packs the indicated numeric or string value into the stream.
void pack_blob(const vector_uchar &value)
Packs the indicated numeric or string value into the stream.
bool has_nested_fields() const
Returns true if this field type has any nested fields (and thus expects a push() .
size_t get_num_unpacked_bytes() const
Returns the number of bytes that have been unpacked so far, or after unpack_end(),...
void clear()
Empties the contents of the data (without necessarily freeing its allocated memory).
int raw_unpack_int16()
Unpacks the data from the buffer between unpacking sessions.
const DCPackerInterface * get_current_field() const
Returns the field that will be referenced by the next call to pack_*() or unpack_*().
unsigned int raw_unpack_uint16()
Unpacks the data from the buffer between unpacking sessions.
int raw_unpack_int8()
Unpacks the data from the buffer between unpacking sessions.
void raw_pack_uint8(unsigned int value)
Packs the data into the buffer between packing sessions.
bool had_parse_error() const
Returns true if there has been an parse error since the most recent call to begin(); this can only ha...
vector_uchar raw_unpack_blob()
Unpacks the data from the buffer between unpacking sessions.
std::string get_string() const
Returns the packed data buffer as a string.
virtual void unpack_blob(const char *data, size_t length, size_t &p, vector_uchar &value, bool &pack_error, bool &range_error) const
Unpacks the current numeric or string value from the stream.
int get_num_nested_fields() const
Returns the number of nested fields associated with the current field, if has_nested_fields() returne...
This represents a switch object used as a parameter itself, which packs the appropriate fields of the...
unsigned int unpack_uint()
Unpacks the current numeric or string value from the stream.
virtual DCPackerInterface * get_nested_field(int n) const
Returns the DCPackerInterface object that represents the nth nested field.
void pack_uint(unsigned int value)
Packs the indicated numeric or string value into the stream.
bool had_pack_error() const
Returns true if there has been an packing error since the most recent call to begin(); in particular,...
void pack_uint64(uint64_t value)
Packs the indicated numeric or string value into the stream.
int64_t unpack_int64()
Unpacks the current numeric or string value from the stream.
void raw_pack_int64(int64_t value)
Packs the data into the buffer between packing sessions.
size_t get_length() const
Returns the current length of the buffer.
double unpack_double()
Unpacks the current numeric or string value from the stream.
std::string get_current_field_name() const
Returns the name of the current field, if it has a name, or the empty string if the field does not ha...
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.
std::string get_string() const
Returns the data buffer as a string.
void raw_pack_float64(double value)
Packs the data into the buffer between packing sessions.
std::string get_unpack_string() const
Returns the unpack data buffer, as a string.
bool has_nested_fields() const
Returns true if the current field has any nested fields (and thus expects a push() .
char * get_write_pointer(size_t size)
Adds the indicated number of bytes to the end of the data without initializing them,...
virtual void pack_uint64(DCPackData &pack_data, uint64_t value, bool &pack_error, bool &range_error) const
Packs the indicated numeric or string value into the stream.
char * take_data()
Returns the pointer to the beginning of the data buffer, and transfers ownership of the buffer to the...
unsigned int raw_unpack_uint8()
Unpacks the data from the buffer between unpacking sessions.
const DCPackerInterface * get_current_parent() const
Returns the field that we left in our last call to push(): the owner of the current level of fields.
virtual void pack_int64(DCPackData &pack_data, int64_t value, bool &pack_error, bool &range_error) const
Packs the indicated numeric or string value into the stream.
unsigned int raw_unpack_uint32()
Unpacks the data from the buffer between unpacking sessions.
int raw_unpack_int32()
Unpacks the data from the buffer between unpacking sessions.
void append_data(const unsigned char *buffer, size_t size)
Adds the indicated bytes to the end of the data.
void raw_pack_int8(int value)
Packs the data into the buffer between packing sessions.
void raw_pack_uint16(unsigned int value)
Packs the data into the buffer between packing sessions.
bool more_nested_fields() const
Returns true if there are more nested fields to pack or unpack in the current push sequence,...
virtual void unpack_uint(const char *data, size_t length, size_t &p, unsigned int &value, bool &pack_error, bool &range_error) const
Unpacks the current numeric or string value from the stream.
char * take_data()
Returns the pointer to the beginning of the data buffer, and transfers ownership of the buffer to the...
int64_t raw_unpack_int64()
Unpacks the data from the buffer between unpacking sessions.
const char * get_data() const
Returns the beginning of the data buffer.
size_t get_length() const
Returns the current length of the buffer.
const DCSwitchParameter * get_last_switch() const
Returns a pointer to the last DCSwitch instance that we have passed by and selected one case of durin...
std::string unpack_string()
Unpacks the current numeric or string value from the stream.
void raw_pack_string(const std::string &value)
Packs the data into the buffer between packing sessions.
DCPackType get_pack_type() const
Returns the type of value expected by this field.
virtual void unpack_int(const char *data, size_t length, size_t &p, int &value, bool &pack_error, bool &range_error) const
Unpacks the current numeric or string value from the stream.
virtual void unpack_string(const char *data, size_t length, size_t &p, std::string &value, bool &pack_error, bool &range_error) const
Unpacks the current numeric or string value from the stream.
void pack_literal_value(const vector_uchar &value)
Adds the indicated string value into the stream, representing a single pre- packed field element,...
vector_uchar unpack_blob()
Unpacks the current binary data value from the stream.
int unpack_int()
Unpacks the current numeric or string value from the stream.
const char * get_data() const
Returns the beginning of the data buffer.
std::string raw_unpack_string()
Unpacks the data from the buffer between unpacking sessions.
void raw_pack_int32(int value)
Packs the data into the buffer between packing sessions.
virtual void pack_string(DCPackData &pack_data, const std::string &value, bool &pack_error, bool &range_error) const
Packs the indicated numeric or string value into the stream.
void raw_pack_blob(const vector_uchar &value)
Packs the data into the buffer between packing sessions.
virtual void pack_blob(DCPackData &pack_data, const vector_uchar &value, bool &pack_error, bool &range_error) const
Packs the indicated numeric or string value into the stream.
void unpack_skip()
Skips the current field without unpacking it and advances to the next field.
double raw_unpack_float64()
Unpacks the data from the buffer between unpacking sessions.
virtual void unpack_double(const char *data, size_t length, size_t &p, double &value, bool &pack_error, bool &range_error) const
Unpacks the current numeric or string value from the stream.
vector_uchar unpack_literal_value()
Returns the literal string that represents the packed value of the current field, and advances the fi...
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.
virtual void unpack_int64(const char *data, size_t length, size_t &p, int64_t &value, bool &pack_error, bool &range_error) const
Unpacks the current numeric or string value from the stream.
void pack_double(double value)
Packs the indicated numeric or string value into the stream.
virtual void pack_double(DCPackData &pack_data, double value, bool &pack_error, bool &range_error) const
Packs the indicated numeric or string value into the stream.
This defines the internal interface for packing values into a DCField.
virtual void pack_int(DCPackData &pack_data, int value, bool &pack_error, bool &range_error) const
Packs the indicated numeric or string value into the stream.
void pack_string(const std::string &value)
Packs the indicated numeric or string value into the stream.
void clear_data()
Empties the data in the pack buffer and unpack buffer.
virtual void unpack_uint64(const char *data, size_t length, size_t &p, uint64_t &value, bool &pack_error, bool &range_error) const
Unpacks the current numeric or string value from the stream.
void pack_int64(int64_t value)
Packs the indicated numeric or string value into the stream.