slightly better unpack exception generating

This commit is contained in:
David Rose 2008-10-21 21:43:30 +00:00
parent e200773139
commit f28396fead
4 changed files with 84 additions and 20 deletions

View File

@ -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) {

View File

@ -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;
}

View File

@ -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

View File

@ -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();