diff --git a/direct/src/dcparser/dcClass.cxx b/direct/src/dcparser/dcClass.cxx index 9768957e79..92102e133a 100644 --- a/direct/src/dcparser/dcClass.cxx +++ b/direct/src/dcparser/dcClass.cxx @@ -494,8 +494,9 @@ receive_update(PyObject *distobj, DatagramIterator &di) const { PStatTimer timer(((DCClass *)this)->_class_update_pcollector); #endif DCPacker packer; - packer.set_unpack_data(di.get_remaining_bytes()); - + const char *data = (const char *)di.get_datagram().get_data(); + packer.set_unpack_data(data + di.get_current_index(), + di.get_remaining_size(), false); int field_id = packer.raw_unpack_uint16(); DCField *field = get_field_by_index(field_id); @@ -532,7 +533,9 @@ receive_update_broadcast_required(PyObject *distobj, DatagramIterator &di) const PStatTimer timer(((DCClass *)this)->_class_update_pcollector); #endif DCPacker packer; - packer.set_unpack_data(di.get_remaining_bytes()); + const char *data = (const char *)di.get_datagram().get_data(); + packer.set_unpack_data(data + di.get_current_index(), + di.get_remaining_size(), false); int num_fields = get_num_inherited_fields(); for (int i = 0; i < num_fields && !PyErr_Occurred(); ++i) { @@ -568,7 +571,9 @@ receive_update_broadcast_required_owner(PyObject *distobj, PStatTimer timer(((DCClass *)this)->_class_update_pcollector); #endif DCPacker packer; - packer.set_unpack_data(di.get_remaining_bytes()); + const char *data = (const char *)di.get_datagram().get_data(); + packer.set_unpack_data(data + di.get_current_index(), + di.get_remaining_size(), false); int num_fields = get_num_inherited_fields(); for (int i = 0; i < num_fields && !PyErr_Occurred(); ++i) { @@ -608,7 +613,9 @@ receive_update_all_required(PyObject *distobj, DatagramIterator &di) const { PStatTimer timer(((DCClass *)this)->_class_update_pcollector); #endif DCPacker packer; - packer.set_unpack_data(di.get_remaining_bytes()); + const char *data = (const char *)di.get_datagram().get_data(); + packer.set_unpack_data(data + di.get_current_index(), + di.get_remaining_size(), false); int num_fields = get_num_inherited_fields(); for (int i = 0; i < num_fields && !PyErr_Occurred(); ++i) { diff --git a/direct/src/dcparser/dcField.cxx b/direct/src/dcparser/dcField.cxx index e557a1ff27..befbfc1c6c 100644 --- a/direct/src/dcparser/dcField.cxx +++ b/direct/src/dcparser/dcField.cxx @@ -344,6 +344,7 @@ unpack_args(DCPacker &packer) const { nassertr(!packer.had_error(), NULL); nassertr(packer.get_current_field() == this, NULL); + size_t start_byte = packer.get_num_unpacked_bytes(); PyObject *object = packer.unpack_object(); if (!packer.had_error()) { @@ -356,23 +357,35 @@ unpack_args(DCPacker &packer) const { return object; } - - ostringstream strm; - if (packer.had_pack_error()) { - strm << "Error unpacking to field " << get_name(); - } else { - PyObject *str = PyObject_Str(object); - strm << "Found value outside specified range when unpacking field " - << get_name() << ": " << PyString_AsString(str); - Py_DECREF(str); + + if (!Notify::ptr()->has_assert_failed()) { + ostringstream strm; + PyObject *exc_type = PyExc_StandardError; + + if (packer.had_pack_error()) { + strm << "Data error unpacking field "; + output(strm, true); + size_t length = packer.get_unpack_length() - start_byte; + strm << "\nGot data (" << (int)length << " bytes):\n"; + Datagram dg(packer.get_unpack_data() + start_byte, length); + dg.dump_hex(strm); + size_t error_byte = packer.get_num_unpacked_bytes() - start_byte; + strm << "Error detected on byte " << error_byte + << " (" << hex << error_byte << dec << " hex)"; + + exc_type = PyExc_RuntimeError; + } else { + PyObject *str = PyObject_Str(object); + strm << "Value outside specified range when unpacking field " + << get_name() << ": " << PyString_AsString(str); + Py_DECREF(str); + exc_type = PyExc_ValueError; + } + + string message = strm.str(); + PyErr_SetString(exc_type, message.c_str()); } - /* - Datagram dg(data.data(), packer.get_num_unpacked_bytes()); - dg.dump_hex(cerr); - */ - - nassert_raise(strm.str()); Py_XDECREF(object); return NULL; } diff --git a/direct/src/dcparser/dcPacker.I b/direct/src/dcparser/dcPacker.I index 07ea945e9e..10f202e307 100755 --- a/direct/src/dcparser/dcPacker.I +++ b/direct/src/dcparser/dcPacker.I @@ -664,6 +664,33 @@ get_string() const { return _pack_data.get_string(); } +//////////////////////////////////////////////////////////////////// +// Function: DCPacker::get_unpack_length +// Access: Published +// Description: Returns the total number of bytes in the unpack data +// buffer. This is the buffer used when unpacking; it +// is separate from the pack data returned by +// get_length(), which is filled during packing. +//////////////////////////////////////////////////////////////////// +INLINE size_t DCPacker:: +get_unpack_length() const { + return _unpack_length; +} + +//////////////////////////////////////////////////////////////////// +// Function: DCPacker::get_unpack_string +// Access: Published +// Description: Returns the unpack data buffer, as a string. +// This is the buffer used when unpacking; it is +// separate from the pack data returned by get_string(), +// which is filled during packing. Also see +// get_unpack_data(). +//////////////////////////////////////////////////////////////////// +INLINE string DCPacker:: +get_unpack_string() const { + return string(_unpack_data, _unpack_length); +} + //////////////////////////////////////////////////////////////////// // Function: DCPacker::get_string // Access: Published @@ -736,6 +763,19 @@ get_write_pointer(size_t size) { return _pack_data.get_write_pointer(size); } +//////////////////////////////////////////////////////////////////// +// Function: DCPacker::get_unpack_data +// Access: Public +// Description: Returns a read pointer to the unpack data buffer. +// This is the buffer used when unpacking; it is +// separate from the pack data returned by get_data(), +// which is filled during packing. +//////////////////////////////////////////////////////////////////// +INLINE const char *DCPacker:: +get_unpack_data() const { + return _unpack_data; +} + //////////////////////////////////////////////////////////////////// // Function: DCPacker::StackElement::get_num_stack_elements_ever_allocated // Access: Published, Static diff --git a/direct/src/dcparser/dcPacker.h b/direct/src/dcparser/dcPacker.h index 6537cc65b8..0c7cfb58ab 100755 --- a/direct/src/dcparser/dcPacker.h +++ b/direct/src/dcparser/dcPacker.h @@ -123,6 +123,8 @@ PUBLISHED: INLINE size_t get_length() const; INLINE string get_string() const; + INLINE size_t get_unpack_length() const; + INLINE string get_unpack_string() const; public: INLINE void get_string(string &data) const; INLINE const char *get_data() const; @@ -131,6 +133,8 @@ public: INLINE void append_data(const char *buffer, size_t size); INLINE char *get_write_pointer(size_t size); + INLINE const char *get_unpack_data() const; + PUBLISHED: INLINE static int get_num_stack_elements_ever_allocated();