27 using std::istringstream;
29 using std::ostringstream;
32 DCPacker::StackElement *DCPacker::StackElement::_deleted_chain =
nullptr;
33 int DCPacker::StackElement::_num_ever_allocated = 0;
41 _unpack_data =
nullptr;
43 _owns_unpack_data =
false;
45 _live_catalog =
nullptr;
74 nassertv(_mode == M_idle);
83 _live_catalog =
nullptr;
85 _current_field = root;
86 _current_parent =
nullptr;
87 _current_field_index = 0;
88 _num_nested_fields = 0;
99 nassertr(_mode == M_pack,
false);
103 if (_stack !=
nullptr || _current_field !=
nullptr || _current_parent !=
nullptr) {
118 nassertv(_mode == M_idle);
120 char *buffer =
new char[data.size()];
121 memcpy(buffer, data.data(), data.size());
131 bool owns_unpack_data) {
132 nassertv(_mode == M_idle);
134 if (_owns_unpack_data) {
135 delete[] _unpack_data;
137 _unpack_data = unpack_data;
138 _unpack_length = unpack_length;
139 _owns_unpack_data = owns_unpack_data;
154 nassertv(_mode == M_idle);
155 nassertv(_unpack_data !=
nullptr);
158 _parse_error =
false;
160 _range_error =
false;
164 _live_catalog =
nullptr;
166 _current_field = root;
167 _current_parent =
nullptr;
168 _current_field_index = 0;
169 _num_nested_fields = 0;
180 nassertr(_mode == M_unpack,
false);
184 if (_stack !=
nullptr || _current_field !=
nullptr || _current_parent !=
nullptr) {
190 if (_catalog ==
nullptr) {
214 nassertv(_mode == M_idle);
215 nassertv(_unpack_data !=
nullptr);
216 nassertv(_unpack_p == 0);
219 _parse_error =
false;
221 _range_error =
false;
229 if (_live_catalog ==
nullptr) {
235 _current_field =
nullptr;
236 _current_parent =
nullptr;
237 _current_field_index = 0;
238 _num_nested_fields = 0;
249 nassertr(_mode == M_repack,
false);
252 _pack_data.
append_data(_unpack_data + _unpack_p, _unpack_length - _unpack_p);
270 seek(
const string &field_name) {
271 if (_catalog ==
nullptr) {
275 nassertr(_catalog !=
nullptr,
false);
276 if (_live_catalog ==
nullptr) {
282 if (seek_index < 0) {
288 return seek(seek_index);
300 seek(
int seek_index) {
301 if (_catalog ==
nullptr) {
305 nassertr(_catalog !=
nullptr,
false);
306 if (_live_catalog ==
nullptr) {
311 if (_mode == M_unpack) {
317 _current_field = entry._field;
318 _current_parent = entry._parent;
319 _current_field_index = entry._field_index;
321 _unpack_p = _live_catalog->
get_begin(seek_index);
327 _push_marker = _unpack_p;
332 }
else if (_mode == M_repack) {
333 nassertr(_catalog !=
nullptr,
false);
335 if (_stack !=
nullptr || _current_field !=
nullptr) {
343 if (entry._parent->as_switch_parameter() !=
nullptr) {
353 size_t begin = _live_catalog->
get_begin(seek_index);
354 if (begin < _unpack_p) {
357 _pack_data.
append_data(_unpack_data + _unpack_p, _unpack_length - _unpack_p);
366 if (_live_catalog ==
nullptr) {
371 begin = _live_catalog->
get_begin(seek_index);
377 _pack_data.
append_data(_unpack_data + _unpack_p, begin - _unpack_p);
381 _current_field = entry._field;
382 _current_parent = entry._parent;
383 _current_field_index = entry._field_index;
384 _num_nested_fields = 1;
385 _unpack_p = _live_catalog->
get_end(seek_index);
389 _push_marker = begin;
390 _pop_marker = _live_catalog->
get_end(seek_index);
416 StackElement *element =
new StackElement;
417 element->_current_parent = _current_parent;
418 element->_current_field_index = _current_field_index;
419 element->_push_marker = _push_marker;
420 element->_pop_marker = _pop_marker;
421 element->_next = _stack;
423 _current_parent = _current_field;
431 if (_mode == M_pack || _mode == M_repack) {
437 }
else if (_mode == M_unpack) {
439 _push_marker = _unpack_p;
442 if (length_bytes != 0) {
443 if (_unpack_p + length_bytes > _unpack_length) {
448 if (length_bytes == 4) {
449 length = DCPackerInterface::do_unpack_uint32
450 (_unpack_data + _unpack_p);
453 length = DCPackerInterface::do_unpack_uint16
454 (_unpack_data + _unpack_p);
457 _pop_marker = _unpack_p + length;
462 num_nested_fields = 0;
474 _num_nested_fields = num_nested_fields;
475 _current_field_index = 0;
477 if (_num_nested_fields >= 0 &&
478 _current_field_index >= _num_nested_fields) {
479 _current_field =
nullptr;
496 if (_current_field !=
nullptr && _num_nested_fields >= 0) {
500 }
else if (_mode == M_unpack && _pop_marker != 0 &&
501 _unpack_p != _pop_marker) {
506 if (_stack ==
nullptr) {
516 if (_mode == M_pack || _mode == M_repack) {
518 if (length_bytes != 0) {
520 size_t length = _pack_data.
get_length() - _push_marker - length_bytes;
521 if (length_bytes == 4) {
522 DCPackerInterface::do_pack_uint32
526 DCPackerInterface::do_pack_uint16
532 _current_field = _current_parent;
533 _current_parent = _stack->_current_parent;
534 _current_field_index = _stack->_current_field_index;
535 _push_marker = _stack->_push_marker;
536 _pop_marker = _stack->_pop_marker;
539 StackElement *next = _stack->_next;
553 nassertv(_mode == M_pack || _mode == M_repack);
554 if (_current_field ==
nullptr) {
579 nassertv(_mode == M_unpack);
580 if (_current_field ==
nullptr) {
584 if (_current_field->
unpack_validate(_unpack_data, _unpack_length, _unpack_p,
585 _pack_error, _range_error)) {
605 nassertv(_mode == M_unpack);
606 if (_current_field ==
nullptr) {
610 if (_current_field->
unpack_skip(_unpack_data, _unpack_length, _unpack_p,
633 pack_object(PyObject *
object) {
634 nassertv(_mode == M_pack || _mode == M_repack);
643 if(PyLong_Check(
object))
648 #if PY_MAJOR_VERSION < 3
649 else if (PyInt_Check(
object))
657 if(PyLong_Check(
object))
662 #if PY_MAJOR_VERSION < 3
663 else if(PyInt_Check(
object))
665 PyObject *obj1 = PyNumber_Long(
object);
666 pack_int(PyLong_AsUnsignedLongLong(obj1));
673 if(PyLong_Check(
object))
678 #if PY_MAJOR_VERSION < 3
679 else if (PyInt_Check(
object))
687 if(PyLong_Check(
object))
689 pack_uint(PyLong_AsUnsignedLong(
object));
692 #if PY_MAJOR_VERSION < 3
693 else if (PyInt_Check(
object))
695 PyObject *obj1 = PyNumber_Long(
object);
705 if (PyLong_Check(
object)) {
707 #if PY_MAJOR_VERSION < 3
708 }
else if (PyInt_Check(
object)) {
711 }
else if (PyFloat_Check(
object)) {
713 }
else if (PyLong_Check(
object)) {
715 #if PY_MAJOR_VERSION >= 3
716 }
else if (PyUnicode_Check(
object)) {
719 buffer = PyUnicode_AsUTF8AndSize(
object, &length);
723 }
else if (PyBytes_Check(
object)) {
724 const unsigned char *buffer;
726 PyBytes_AsStringAndSize(
object, (
char **)&buffer, &length);
728 pack_blob(vector_uchar(buffer, buffer + length));
731 }
else if (PyString_Check(
object) || PyUnicode_Check(
object)) {
734 PyString_AsStringAndSize(
object, &buffer, &length);
744 (PySequence_Check(
object) != 0) &&
745 (PyObject_HasAttrString(
object,
"__len__") != 0);
746 bool is_instance =
false;
748 const DCClass *dclass =
nullptr;
750 if (current_field !=
nullptr) {
752 if (class_param !=
nullptr) {
755 if (dclass->has_class_def()) {
756 PyObject *class_def = dclass->get_class_def();
757 is_instance = (PyObject_IsInstance(
object, dclass->get_class_def()) != 0);
758 Py_DECREF(class_def);
780 if (dclass !=
nullptr && (is_instance || !is_sequence)) {
783 pack_class_object(dclass,
object);
784 }
else if (is_sequence) {
788 int size = PySequence_Size(
object);
789 for (
int i = 0; i < size; ++i) {
790 PyObject *element = PySequence_GetItem(
object, i);
791 if (element !=
nullptr) {
792 pack_object(element);
795 std::cerr <<
"Unable to extract item " << i <<
" from sequence.\n";
803 strm <<
"Don't know how to pack object: "
804 << DCField::get_pystr(
object);
805 nassert_raise(strm.str());
810 #endif // HAVE_PYTHON
821 PyObject *
object =
nullptr;
835 object = PyFloat_FromDouble(value);
842 #if PY_MAJOR_VERSION >= 3
843 object = PyLong_FromLong(value);
845 object = PyInt_FromLong(value);
853 #if PY_MAJOR_VERSION >= 3
854 object = PyLong_FromLong(value);
856 if (value & 0x80000000) {
857 object = PyLong_FromUnsignedLong(value);
859 object = PyInt_FromLong(value);
868 object = PyLong_FromLongLong(value);
875 object = PyLong_FromUnsignedLongLong(value);
880 #if PY_MAJOR_VERSION >= 3
884 object = PyBytes_FromStringAndSize(str.data(), str.size());
894 #if PY_MAJOR_VERSION >= 3
895 object = PyUnicode_FromStringAndSize(str.data(), str.size());
897 object = PyString_FromStringAndSize(str.data(), str.size());
905 if (class_param !=
nullptr) {
907 if (dclass->has_class_def()) {
910 object = unpack_class_object(dclass);
911 if (
object ==
nullptr) {
912 std::cerr <<
"Unable to construct object of class "
927 object = PyList_New(0);
931 PyObject *element = unpack_object();
932 PyList_Append(
object, element);
937 if (pack_type != PT_array) {
940 PyObject *tuple = PyList_AsTuple(
object);
948 nassertr(
object !=
nullptr,
nullptr);
951 #endif // HAVE_PYTHON
961 istringstream strm(formatted_object);
972 dc_init_parser_parameter_value(in,
"parse_and_pack", *
this);
976 bool parse_error = (dc_error_count() != 0);
1004 nassertv(_current_field !=
nullptr);
1005 const DCField *field = _current_field->as_field();
1006 if (field !=
nullptr &&
1007 field->as_parameter() !=
nullptr) {
1012 switch (pack_type) {
1047 switch (pack_type) {
1073 switch (pack_type) {
1097 enquote_string(ostream &out,
char quote_mark,
const string &str) {
1099 for (string::const_iterator pi = str.begin();
1102 if ((*pi) == quote_mark || (*pi) ==
'\\') {
1103 out <<
'\\' << (*pi);
1105 }
else if (!isprint(*pi) || (*pi) ==
'\t') {
1107 sprintf(buffer,
"%02x", (
unsigned char)(*pi));
1108 out <<
"\\x" << buffer;
1123 for (vector_uchar::const_iterator pi = str.begin();
1127 sprintf(buffer,
"%02x", (
unsigned char)(*pi));
1141 handle_switch(const DCSwitchParameter *switch_parameter) {
1142 // First, get the value from the key. This is either found in the unpack or
1143 // the pack data, depending on what mode we're in.
1146 if (_mode == M_pack || _mode == M_repack) {
1147 const char *data = _pack_data.
get_data();
1148 new_parent = switch_parameter->apply_switch
1149 (data + _push_marker, _pack_data.
get_length() - _push_marker);
1151 }
else if (_mode == M_unpack) {
1152 new_parent = switch_parameter->apply_switch
1153 (_unpack_data + _push_marker, _unpack_p - _push_marker);
1156 if (new_parent ==
nullptr) {
1158 _range_error =
true;
1162 _last_switch = switch_parameter;
1167 _current_parent = new_parent;
1170 if (_num_nested_fields < 0 ||
1171 _current_field_index < _num_nested_fields) {
1182 _current_field =
nullptr;
1183 _current_parent =
nullptr;
1184 _current_field_index = 0;
1185 _num_nested_fields = 0;
1188 _last_switch =
nullptr;
1190 if (_live_catalog !=
nullptr) {
1192 _live_catalog =
nullptr;
1203 while (_stack !=
nullptr) {
1204 StackElement *next = _stack->_next;
1217 pack_class_object(
const DCClass *dclass, PyObject *
object) {
1221 nassertv(field !=
nullptr);
1222 get_class_element(dclass,
object, field);
1226 #endif // HAVE_PYTHON
1233 PyObject *DCPacker::
1234 unpack_class_object(
const DCClass *dclass) {
1235 PyObject *class_def = dclass->get_class_def();
1236 nassertr(class_def !=
nullptr,
nullptr);
1238 PyObject *
object =
nullptr;
1243 object = PyObject_CallObject(class_def,
nullptr);
1244 if (
object ==
nullptr) {
1253 nassertr(field !=
nullptr,
object);
1256 set_class_element(class_def,
object, field);
1259 if (
object ==
nullptr) {
1265 nassertr(field !=
nullptr,
object);
1267 set_class_element(class_def,
object, field);
1273 #endif // HAVE_PYTHON
1282 set_class_element(PyObject *class_def, PyObject *&
object,
1284 string field_name = field->
get_name();
1287 if (field_name.empty()) {
1288 switch (pack_type) {
1296 nassertv(field !=
nullptr);
1297 nassertv(
object !=
nullptr);
1298 set_class_element(class_def,
object, field);
1313 PyObject *element = unpack_object();
1315 if (pack_type == PT_field) {
1316 if (
object ==
nullptr) {
1319 object = PyObject_CallObject(class_def, element);
1322 if (PyObject_HasAttrString(
object, (
char *)field_name.c_str())) {
1323 PyObject *func = PyObject_GetAttrString(
object, (
char *)field_name.c_str());
1324 if (func !=
nullptr) {
1325 PyObject *result = PyObject_CallObject(func, element);
1333 nassertv(
object !=
nullptr);
1334 PyObject_SetAttrString(
object, (
char *)field_name.c_str(), element);
1340 #endif // HAVE_PYTHON
1348 get_class_element(
const DCClass *dclass, PyObject *
object,
1350 string field_name = field->
get_name();
1353 if (field_name.empty()) {
1354 switch (pack_type) {
1362 nassertv(field !=
nullptr);
1363 get_class_element(dclass,
object, field);
1378 if (!dclass->pack_required_field(*
this,
object, field)) {
1383 #endif // HAVE_PYTHON