mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-01 09:23:03 -04:00
allow serial pack/unpack sessions
This commit is contained in:
parent
6845758d2b
commit
4b15c13cc0
@ -459,7 +459,8 @@ output(ostream &out, bool brief) const {
|
||||
if (!brief && _has_default_value) {
|
||||
out << " = ";
|
||||
DCPacker packer;
|
||||
packer.begin_unpack(_default_value, _param);
|
||||
packer.set_unpack_data(_default_value);
|
||||
packer.begin_unpack(_param);
|
||||
packer.unpack_and_format(out);
|
||||
packer.end_unpack();
|
||||
}
|
||||
|
@ -275,16 +275,21 @@ get_class_def() const {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCClass::receive_update
|
||||
// Access: Published
|
||||
// Description: Extracts the update message out of the datagram and
|
||||
// Description: Extracts the update message out of the packer and
|
||||
// applies it to the indicated object by calling the
|
||||
// appropriate method.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void DCClass::
|
||||
receive_update(PyObject *distobj, DatagramIterator &iterator) const {
|
||||
int field_id = iterator.get_uint16();
|
||||
receive_update(PyObject *distobj, DatagramIterator &di) const {
|
||||
DCPacker packer;
|
||||
packer.set_unpack_data(di.get_remaining_bytes());
|
||||
|
||||
int field_id = packer.raw_unpack_uint16();
|
||||
DCField *field = get_inherited_field(field_id);
|
||||
nassertv_always(field != NULL);
|
||||
field->receive_update(distobj, iterator);
|
||||
field->receive_update(packer, distobj);
|
||||
|
||||
di.skip_bytes(packer.get_num_unpacked_bytes());
|
||||
}
|
||||
#endif // HAVE_PYTHON
|
||||
|
||||
@ -298,16 +303,21 @@ receive_update(PyObject *distobj, DatagramIterator &iterator) const {
|
||||
// atomic fields that are marked "broadcast required".
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void DCClass::
|
||||
receive_update_broadcast_required(PyObject *distobj, DatagramIterator &iterator) const {
|
||||
receive_update_broadcast_required(PyObject *distobj, DatagramIterator &di) const {
|
||||
DCPacker packer;
|
||||
packer.set_unpack_data(di.get_remaining_bytes());
|
||||
|
||||
int num_fields = get_num_inherited_fields();
|
||||
for (int i = 0; i < num_fields && !PyErr_Occurred(); i++) {
|
||||
DCField *field = get_inherited_field(i);
|
||||
DCAtomicField *atom = field->as_atomic_field();
|
||||
if (atom != (DCAtomicField *)NULL &&
|
||||
atom->is_required() && atom->is_broadcast()) {
|
||||
atom->receive_update(distobj, iterator);
|
||||
atom->receive_update(packer, distobj);
|
||||
}
|
||||
}
|
||||
|
||||
di.skip_bytes(packer.get_num_unpacked_bytes());
|
||||
}
|
||||
#endif // HAVE_PYTHON
|
||||
|
||||
@ -321,15 +331,20 @@ receive_update_broadcast_required(PyObject *distobj, DatagramIterator &iterator)
|
||||
// marked "required", whether they are broadcast or not.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void DCClass::
|
||||
receive_update_all_required(PyObject *distobj, DatagramIterator &iterator) const {
|
||||
receive_update_all_required(PyObject *distobj, DatagramIterator &di) const {
|
||||
DCPacker packer;
|
||||
packer.set_unpack_data(di.get_remaining_bytes());
|
||||
|
||||
int num_fields = get_num_inherited_fields();
|
||||
for (int i = 0; i < num_fields && !PyErr_Occurred(); i++) {
|
||||
DCField *field = get_inherited_field(i);
|
||||
DCAtomicField *atom = field->as_atomic_field();
|
||||
if (atom != (DCAtomicField *)NULL && atom->is_required()) {
|
||||
atom->receive_update(distobj, iterator);
|
||||
atom->receive_update(packer, distobj);
|
||||
}
|
||||
}
|
||||
|
||||
di.skip_bytes(packer.get_num_unpacked_bytes());
|
||||
}
|
||||
#endif // HAVE_PYTHON
|
||||
|
||||
@ -341,10 +356,10 @@ receive_update_all_required(PyObject *distobj, DatagramIterator &iterator) const
|
||||
// fields that are broadcast in one chunk.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void DCClass::
|
||||
receive_update_other(PyObject *distobj, DatagramIterator &iterator) const {
|
||||
int num_fields = iterator.get_uint16();
|
||||
receive_update_other(PyObject *distobj, DatagramIterator &di) const {
|
||||
int num_fields = di.get_uint16();
|
||||
for (int i = 0; i < num_fields && !PyErr_Occurred(); i++) {
|
||||
receive_update(distobj, iterator);
|
||||
receive_update(distobj, di);
|
||||
}
|
||||
}
|
||||
#endif // HAVE_PYTHON
|
||||
@ -359,8 +374,12 @@ receive_update_other(PyObject *distobj, DatagramIterator &iterator) const {
|
||||
void DCClass::
|
||||
direct_update(PyObject *distobj, const string &field_name,
|
||||
const string &value_blob) {
|
||||
Datagram datagram(value_blob);
|
||||
direct_update(distobj, field_name, datagram);
|
||||
DCField *field = get_field_by_name(field_name);
|
||||
nassertv_always(field != NULL);
|
||||
|
||||
DCPacker packer;
|
||||
packer.set_unpack_data(value_blob);
|
||||
field->receive_update(packer, distobj);
|
||||
}
|
||||
#endif // HAVE_PYTHON
|
||||
|
||||
@ -374,10 +393,7 @@ direct_update(PyObject *distobj, const string &field_name,
|
||||
void DCClass::
|
||||
direct_update(PyObject *distobj, const string &field_name,
|
||||
const Datagram &datagram) {
|
||||
DCField *field = get_field_by_name(field_name);
|
||||
nassertv_always(field != NULL);
|
||||
DatagramIterator iterator(datagram);
|
||||
field->receive_update(distobj, iterator);
|
||||
direct_update(distobj, field_name, datagram.get_message());
|
||||
}
|
||||
#endif // HAVE_PYTHON
|
||||
|
||||
@ -387,7 +403,7 @@ direct_update(PyObject *distobj, const string &field_name,
|
||||
// Access: Published
|
||||
// Description: Looks up the current value of the indicated field by
|
||||
// calling the appropriate get*() function, then packs
|
||||
// that value into the datagram. This field is
|
||||
// that value into the packer. This field is
|
||||
// presumably either a required field or a specified
|
||||
// optional field, and we are building up a datagram for
|
||||
// the generate-with-required message.
|
||||
@ -395,7 +411,7 @@ direct_update(PyObject *distobj, const string &field_name,
|
||||
// Returns true on success, false on failure.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool DCClass::
|
||||
pack_required_field(Datagram &dg, PyObject *distobj, DCField *field) const {
|
||||
pack_required_field(DCPacker &packer, PyObject *distobj, DCField *field) const {
|
||||
DCAtomicField *atom = field->as_atomic_field();
|
||||
if (atom == (DCAtomicField *)NULL) {
|
||||
ostringstream strm;
|
||||
@ -461,7 +477,7 @@ pack_required_field(Datagram &dg, PyObject *distobj, DCField *field) const {
|
||||
}
|
||||
|
||||
// Now pack the arguments into the datagram.
|
||||
bool pack_ok = atom->pack_args(dg, result);
|
||||
bool pack_ok = atom->pack_args(packer, result);
|
||||
Py_DECREF(result);
|
||||
|
||||
return pack_ok;
|
||||
@ -487,7 +503,10 @@ client_format_update(const string &field_name, int do_id,
|
||||
nassert_raise(strm.str());
|
||||
return Datagram();
|
||||
}
|
||||
return field->client_format_update(do_id, args);
|
||||
|
||||
DCPacker packer;
|
||||
field->client_format_update(packer, do_id, args);
|
||||
return Datagram(packer.get_data(), packer.get_length());
|
||||
}
|
||||
#endif // HAVE_PYTHON
|
||||
|
||||
@ -510,7 +529,10 @@ ai_format_update(const string &field_name, int do_id,
|
||||
nassert_raise(strm.str());
|
||||
return Datagram();
|
||||
}
|
||||
return field->ai_format_update(do_id, to_id, from_id, args);
|
||||
|
||||
DCPacker packer;
|
||||
field->ai_format_update(packer, do_id, to_id, from_id, args);
|
||||
return Datagram(packer.get_data(), packer.get_length());
|
||||
}
|
||||
#endif // HAVE_PYTHON
|
||||
|
||||
@ -530,22 +552,23 @@ Datagram DCClass::
|
||||
ai_format_generate(PyObject *distobj, int do_id,
|
||||
int zone_id, int district_id, int from_channel_id,
|
||||
PyObject *optional_fields) const {
|
||||
Datagram dg;
|
||||
dg.add_uint32(district_id);
|
||||
dg.add_uint32(from_channel_id);
|
||||
dg.add_uint8('A');
|
||||
DCPacker packer;
|
||||
|
||||
packer.raw_pack_uint32(district_id);
|
||||
packer.raw_pack_uint32(from_channel_id);
|
||||
packer.raw_pack_uint8('A');
|
||||
|
||||
bool has_optional_fields = (PyObject_IsTrue(optional_fields) != 0);
|
||||
|
||||
if (has_optional_fields) {
|
||||
dg.add_uint16(STATESERVER_OBJECT_GENERATE_WITH_REQUIRED_OTHER);
|
||||
packer.raw_pack_uint16(STATESERVER_OBJECT_GENERATE_WITH_REQUIRED_OTHER);
|
||||
} else {
|
||||
dg.add_uint16(STATESERVER_OBJECT_GENERATE_WITH_REQUIRED);
|
||||
packer.raw_pack_uint16(STATESERVER_OBJECT_GENERATE_WITH_REQUIRED);
|
||||
}
|
||||
|
||||
dg.add_uint32(zone_id);
|
||||
dg.add_uint16(_number);
|
||||
dg.add_uint32(do_id);
|
||||
packer.raw_pack_uint32(zone_id);
|
||||
packer.raw_pack_uint16(_number);
|
||||
packer.raw_pack_uint32(do_id);
|
||||
|
||||
// Specify all of the required fields.
|
||||
int num_fields = get_num_inherited_fields();
|
||||
@ -553,7 +576,7 @@ ai_format_generate(PyObject *distobj, int do_id,
|
||||
DCField *field = get_inherited_field(i);
|
||||
DCAtomicField *atom = field->as_atomic_field();
|
||||
if (atom != (DCAtomicField *)NULL && atom->is_required()) {
|
||||
if (!pack_required_field(dg, distobj, atom)) {
|
||||
if (!pack_required_field(packer, distobj, atom)) {
|
||||
return Datagram();
|
||||
}
|
||||
}
|
||||
@ -562,7 +585,7 @@ ai_format_generate(PyObject *distobj, int do_id,
|
||||
// Also specify the optional fields.
|
||||
if (has_optional_fields) {
|
||||
int num_optional_fields = PySequence_Size(optional_fields);
|
||||
dg.add_uint16(num_optional_fields);
|
||||
packer.raw_pack_uint16(num_optional_fields);
|
||||
|
||||
for (int i = 0; i < num_optional_fields; i++) {
|
||||
PyObject *py_field_name = PySequence_GetItem(optional_fields, i);
|
||||
@ -578,13 +601,13 @@ ai_format_generate(PyObject *distobj, int do_id,
|
||||
return Datagram();
|
||||
}
|
||||
|
||||
if (!pack_required_field(dg, distobj, field)) {
|
||||
if (!pack_required_field(packer, distobj, field)) {
|
||||
return Datagram();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return dg;
|
||||
return Datagram(packer.get_data(), packer.get_length());
|
||||
}
|
||||
#endif // HAVE_PYTHON
|
||||
|
||||
|
@ -59,20 +59,21 @@ PUBLISHED:
|
||||
void set_class_def(PyObject *class_def);
|
||||
PyObject *get_class_def() const;
|
||||
|
||||
void receive_update(PyObject *distobj, DatagramIterator &iterator) const;
|
||||
void receive_update_broadcast_required(PyObject *distobj, DatagramIterator &iterator) const;
|
||||
void receive_update_all_required(PyObject *distobj, DatagramIterator &iterator) const;
|
||||
void receive_update_other(PyObject *distobj, DatagramIterator &iterator) const;
|
||||
void receive_update(PyObject *distobj, DatagramIterator &di) const;
|
||||
void receive_update_broadcast_required(PyObject *distobj, DatagramIterator &di) const;
|
||||
void receive_update_all_required(PyObject *distobj, DatagramIterator &di) const;
|
||||
void receive_update_other(PyObject *distobj, DatagramIterator &di) const;
|
||||
|
||||
void direct_update(PyObject *distobj, const string &field_name,
|
||||
const string &value_blob);
|
||||
void direct_update(PyObject *distobj, const string &field_name,
|
||||
const Datagram &datagram);
|
||||
bool pack_required_field(Datagram &dg, PyObject *distobj,
|
||||
bool pack_required_field(DCPacker &packer, PyObject *distobj,
|
||||
DCField *field) const;
|
||||
|
||||
|
||||
Datagram client_format_update(const string &field_name, int do_id,
|
||||
PyObject *args) const;
|
||||
Datagram client_format_update(const string &field_name,
|
||||
int do_id, PyObject *args) const;
|
||||
Datagram ai_format_update(const string &field_name, int do_id,
|
||||
int to_id, int from_id, PyObject *args) const;
|
||||
Datagram ai_format_generate(PyObject *distobj, int do_id, int zone_id,
|
||||
|
@ -124,7 +124,8 @@ as_switch() {
|
||||
string DCField::
|
||||
format_data(const string &packed_data) {
|
||||
DCPacker packer;
|
||||
packer.begin_unpack(packed_data, this);
|
||||
packer.set_unpack_data(packed_data);
|
||||
packer.begin_unpack(this);
|
||||
string result = packer.unpack_and_format();
|
||||
if (!packer.end_unpack()) {
|
||||
return string();
|
||||
@ -168,7 +169,8 @@ parse_string(const string &formatted_string) {
|
||||
bool DCField::
|
||||
validate_ranges(const string &packed_data) const {
|
||||
DCPacker packer;
|
||||
packer.begin_unpack(packed_data, this);
|
||||
packer.set_unpack_data(packed_data);
|
||||
packer.begin_unpack(this);
|
||||
packer.unpack_validate();
|
||||
if (!packer.end_unpack()) {
|
||||
return false;
|
||||
@ -182,18 +184,15 @@ validate_ranges(const string &packed_data) const {
|
||||
// Function: DCField::pack_args
|
||||
// Access: Published
|
||||
// Description: Packs the Python arguments from the indicated tuple
|
||||
// into the datagram, appending to the end of the
|
||||
// datagram. Returns true on success, false on failure.
|
||||
// into the packer. Returns true on success, false on
|
||||
// failure.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool DCField::
|
||||
pack_args(Datagram &datagram, PyObject *sequence) const {
|
||||
pack_args(DCPacker &packer, PyObject *sequence) const {
|
||||
nassertr(PySequence_Check(sequence), false);
|
||||
DCPacker packer;
|
||||
packer.begin_pack(this);
|
||||
packer.pack_object(sequence);
|
||||
if (packer.end_pack()) {
|
||||
datagram.append_data(packer.get_data(), packer.get_length());
|
||||
|
||||
/*
|
||||
PyObject *str = PyObject_Str(sequence);
|
||||
cerr << "pack " << get_name() << PyString_AsString(str) << "\n";
|
||||
@ -227,24 +226,20 @@ pack_args(Datagram &datagram, PyObject *sequence) const {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCField::unpack_args
|
||||
// Access: Published
|
||||
// Description: Unpacks the values from the datagram, beginning at
|
||||
// the current point in the interator, into a Python
|
||||
// Description: Unpacks the values from the packer, beginning at
|
||||
// the current point in the unpack_buffer, into a Python
|
||||
// tuple and returns the tuple. If there are remaining
|
||||
// bytes in the datagram, they are ignored (but the
|
||||
// iterator is left at the first unread byte).
|
||||
// bytes in the unpack buffer, they are ignored (but the
|
||||
// packer is left at the first unread byte).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PyObject *DCField::
|
||||
unpack_args(DatagramIterator &iterator) const {
|
||||
DCPacker packer;
|
||||
string data = iterator.get_remaining_bytes();
|
||||
packer.begin_unpack(data, this);
|
||||
unpack_args(DCPacker &packer) const {
|
||||
packer.begin_unpack(this);
|
||||
|
||||
PyObject *object = packer.unpack_object();
|
||||
|
||||
if (packer.end_unpack()) {
|
||||
// Successfully unpacked.
|
||||
iterator.skip_bytes(packer.get_num_unpacked_bytes());
|
||||
|
||||
/*
|
||||
PyObject *str = PyObject_Str(object);
|
||||
cerr << "recv " << get_name() << PyString_AsString(str) << "\n";
|
||||
@ -283,8 +278,8 @@ unpack_args(DatagramIterator &iterator) const {
|
||||
// appropriate method.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void DCField::
|
||||
receive_update(PyObject *distobj, DatagramIterator &iterator) const {
|
||||
PyObject *args = unpack_args(iterator);
|
||||
receive_update(DCPacker &packer, PyObject *distobj) const {
|
||||
PyObject *args = unpack_args(packer);
|
||||
|
||||
if (PyObject_HasAttrString(distobj, (char *)_name.c_str())) {
|
||||
PyObject *func = PyObject_GetAttrString(distobj, (char *)_name.c_str());
|
||||
@ -307,14 +302,12 @@ receive_update(PyObject *distobj, DatagramIterator &iterator) const {
|
||||
// to send an update for the indicated distributed
|
||||
// object from the client.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
Datagram DCField::
|
||||
client_format_update(int do_id, PyObject *args) const {
|
||||
Datagram dg;
|
||||
dg.add_uint16(CLIENT_OBJECT_UPDATE_FIELD);
|
||||
dg.add_uint32(do_id);
|
||||
dg.add_uint16(_number);
|
||||
pack_args(dg, args);
|
||||
return dg;
|
||||
void DCField::
|
||||
client_format_update(DCPacker &packer, int do_id, PyObject *args) const {
|
||||
packer.raw_pack_uint16(CLIENT_OBJECT_UPDATE_FIELD);
|
||||
packer.raw_pack_uint32(do_id);
|
||||
packer.raw_pack_uint16(_number);
|
||||
pack_args(packer, args);
|
||||
}
|
||||
#endif // HAVE_PYTHON
|
||||
|
||||
@ -326,17 +319,15 @@ client_format_update(int do_id, PyObject *args) const {
|
||||
// to send an update for the indicated distributed
|
||||
// object from the AI.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
Datagram DCField::
|
||||
ai_format_update(int do_id, int to_id, int from_id, PyObject *args) const {
|
||||
Datagram dg;
|
||||
dg.add_uint32(to_id);
|
||||
dg.add_uint32(from_id);
|
||||
dg.add_uint8('A');
|
||||
dg.add_uint16(STATESERVER_OBJECT_UPDATE_FIELD);
|
||||
dg.add_uint32(do_id);
|
||||
dg.add_uint16(_number);
|
||||
pack_args(dg, args);
|
||||
return dg;
|
||||
void DCField::
|
||||
ai_format_update(DCPacker &packer, int do_id, int to_id, int from_id, PyObject *args) const {
|
||||
packer.raw_pack_uint32(to_id);
|
||||
packer.raw_pack_uint32(from_id);
|
||||
packer.raw_pack_uint8('A');
|
||||
packer.raw_pack_uint16(STATESERVER_OBJECT_UPDATE_FIELD);
|
||||
packer.raw_pack_uint32(do_id);
|
||||
packer.raw_pack_uint16(_number);
|
||||
pack_args(packer, args);
|
||||
}
|
||||
#endif // HAVE_PYTHON
|
||||
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include "dcPackerInterface.h"
|
||||
#include "dcPython.h"
|
||||
|
||||
class DCPacker;
|
||||
class DCAtomicField;
|
||||
class DCMolecularField;
|
||||
class DCParameter;
|
||||
@ -54,13 +55,13 @@ PUBLISHED:
|
||||
bool validate_ranges(const string &packed_data) const;
|
||||
|
||||
#ifdef HAVE_PYTHON
|
||||
bool pack_args(Datagram &datagram, PyObject *sequence) const;
|
||||
PyObject *unpack_args(DatagramIterator &iterator) const;
|
||||
bool pack_args(DCPacker &packer, PyObject *sequence) const;
|
||||
PyObject *unpack_args(DCPacker &packer) const;
|
||||
|
||||
void receive_update(PyObject *distobj, DatagramIterator &iterator) const;
|
||||
void receive_update(DCPacker &packer, PyObject *distobj) const;
|
||||
|
||||
Datagram client_format_update(int do_id, PyObject *args) const;
|
||||
Datagram ai_format_update(int do_id, int to_id, int from_id, PyObject *args) const;
|
||||
void client_format_update(DCPacker &packer, int do_id, PyObject *args) const;
|
||||
void ai_format_update(DCPacker &packer, int do_id, int to_id, int from_id, PyObject *args) const;
|
||||
#endif
|
||||
|
||||
public:
|
||||
|
@ -54,7 +54,7 @@ clear() {
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCPackData::append_data
|
||||
// Access: Published
|
||||
// Access: Public
|
||||
// Description: Adds the indicated bytes to the end of the data.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void DCPackData::
|
||||
@ -65,7 +65,7 @@ append_data(const char *buffer, size_t size) {
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCPackData::get_write_pointer
|
||||
// Access: Published
|
||||
// Access: Public
|
||||
// Description: Adds the indicated number of bytes to the end of the
|
||||
// data without initializing them, and returns a pointer
|
||||
// to the beginning of the new data.
|
||||
@ -78,7 +78,7 @@ get_write_pointer(size_t size) {
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCPackData::append_junk
|
||||
// Access: Published
|
||||
// Access: Public
|
||||
// Description: Adds some uninitialized bytes to the end of the data.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void DCPackData::
|
||||
@ -88,7 +88,7 @@ append_junk(size_t size) {
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCPackData::rewrite_data
|
||||
// Access: Published
|
||||
// Access: Public
|
||||
// Description: Changes the data at the indicated position to the
|
||||
// given value. It is an error if there are not at
|
||||
// least position + size bytes in the data.
|
||||
@ -101,7 +101,7 @@ rewrite_data(size_t position, const char *buffer, size_t size) {
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCPackData::get_rewrite_pointer
|
||||
// Access: Published
|
||||
// Access: Public
|
||||
// Description: Returns a pointer into the middle of the data at the
|
||||
// indicated point.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
@ -33,12 +33,14 @@ PUBLISHED:
|
||||
|
||||
INLINE void clear();
|
||||
|
||||
public:
|
||||
INLINE void append_data(const char *buffer, size_t size);
|
||||
INLINE char *get_write_pointer(size_t size);
|
||||
INLINE void append_junk(size_t size);
|
||||
INLINE void rewrite_data(size_t position, const char *buffer, size_t size);
|
||||
INLINE char *get_rewrite_pointer(size_t position, size_t size);
|
||||
|
||||
PUBLISHED:
|
||||
INLINE string get_string() const;
|
||||
INLINE size_t get_length() const;
|
||||
public:
|
||||
|
@ -17,9 +17,28 @@
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCPacker::clear_data
|
||||
// Access: Published
|
||||
// Description: Empties the data in the pack buffer and unpack
|
||||
// buffer. This should be called between calls to
|
||||
// begin_pack(), unless you want to concatenate all of
|
||||
// the pack results together.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void DCPacker::
|
||||
clear_data() {
|
||||
_pack_data.clear();
|
||||
|
||||
if (_owns_unpack_data) {
|
||||
delete[] _unpack_data;
|
||||
_owns_unpack_data = false;
|
||||
}
|
||||
_unpack_data = NULL;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCPacker::has_nested_fields
|
||||
// Access: Public, Virtual
|
||||
// Access: Published
|
||||
// Description: Returns true if the current field has any nested
|
||||
// fields (and thus expects a push() .. pop()
|
||||
// interface), or false otherwise. If this returns
|
||||
@ -621,6 +640,456 @@ get_data() const {
|
||||
return _pack_data.get_data();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCPacker::append_data
|
||||
// Access: Public
|
||||
// Description: Adds the indicated bytes to the end of the data.
|
||||
// This may only be called between packing sessions.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void DCPacker::
|
||||
append_data(const char *buffer, size_t size) {
|
||||
nassertv(_mode == M_idle);
|
||||
_pack_data.append_data(buffer, size);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCPacker::get_write_pointer
|
||||
// Access: Public
|
||||
// Description: Adds the indicated number of bytes to the end of the
|
||||
// data without initializing them, and returns a pointer
|
||||
// to the beginning of the new data. This may only be
|
||||
// called between packing sessions.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE char *DCPacker::
|
||||
get_write_pointer(size_t size) {
|
||||
nassertr(_mode == M_idle, NULL);
|
||||
return _pack_data.get_write_pointer(size);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCPacker::raw_pack_int8
|
||||
// Access: Published
|
||||
// Description: Packs the data into the buffer between packing
|
||||
// sessions.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void DCPacker::
|
||||
raw_pack_int8(int value) {
|
||||
nassertv(_mode == M_idle);
|
||||
DCPackerInterface::do_pack_int8(_pack_data.get_write_pointer(1), value);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCPacker::raw_pack_int16
|
||||
// Access: Published
|
||||
// Description: Packs the data into the buffer between packing
|
||||
// sessions.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void DCPacker::
|
||||
raw_pack_int16(int value) {
|
||||
nassertv(_mode == M_idle);
|
||||
DCPackerInterface::do_pack_int16(_pack_data.get_write_pointer(2), value);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCPacker::raw_pack_int32
|
||||
// Access: Published
|
||||
// Description: Packs the data into the buffer between packing
|
||||
// sessions.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void DCPacker::
|
||||
raw_pack_int32(int value) {
|
||||
nassertv(_mode == M_idle);
|
||||
DCPackerInterface::do_pack_int32(_pack_data.get_write_pointer(4), value);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCPacker::raw_pack_int64
|
||||
// Access: Published
|
||||
// Description: Packs the data into the buffer between packing
|
||||
// sessions.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void DCPacker::
|
||||
raw_pack_int64(PN_int64 value) {
|
||||
nassertv(_mode == M_idle);
|
||||
DCPackerInterface::do_pack_int64(_pack_data.get_write_pointer(8), value);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCPacker::raw_pack_uint8
|
||||
// Access: Published
|
||||
// Description: Packs the data into the buffer between packing
|
||||
// sessions.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void DCPacker::
|
||||
raw_pack_uint8(unsigned int value) {
|
||||
nassertv(_mode == M_idle);
|
||||
DCPackerInterface::do_pack_uint8(_pack_data.get_write_pointer(1), value);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCPacker::raw_pack_uint16
|
||||
// Access: Published
|
||||
// Description: Packs the data into the buffer between packing
|
||||
// sessions.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void DCPacker::
|
||||
raw_pack_uint16(unsigned int value) {
|
||||
nassertv(_mode == M_idle);
|
||||
DCPackerInterface::do_pack_uint16(_pack_data.get_write_pointer(2), value);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCPacker::raw_pack_uint32
|
||||
// Access: Published
|
||||
// Description: Packs the data into the buffer between packing
|
||||
// sessions.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void DCPacker::
|
||||
raw_pack_uint32(unsigned int value) {
|
||||
nassertv(_mode == M_idle);
|
||||
DCPackerInterface::do_pack_uint32(_pack_data.get_write_pointer(4), value);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCPacker::raw_pack_uint64
|
||||
// Access: Published
|
||||
// Description: Packs the data into the buffer between packing
|
||||
// sessions.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void DCPacker::
|
||||
raw_pack_uint64(PN_uint64 value) {
|
||||
nassertv(_mode == M_idle);
|
||||
DCPackerInterface::do_pack_uint64(_pack_data.get_write_pointer(8), value);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCPacker::raw_pack_float64
|
||||
// Access: Published
|
||||
// Description: Packs the data into the buffer between packing
|
||||
// sessions.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void DCPacker::
|
||||
raw_pack_float64(double value) {
|
||||
nassertv(_mode == M_idle);
|
||||
DCPackerInterface::do_pack_float64(_pack_data.get_write_pointer(8), value);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCPacker::raw_pack_string
|
||||
// Access: Published
|
||||
// Description: Packs the data into the buffer between packing
|
||||
// sessions.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void DCPacker::
|
||||
raw_pack_string(const string &value) {
|
||||
nassertv(_mode == M_idle);
|
||||
DCPackerInterface::do_pack_uint16(_pack_data.get_write_pointer(2), value.length());
|
||||
_pack_data.append_data(value.data(), value.length());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCPacker::raw_unpack_int8
|
||||
// Access: Published
|
||||
// Description: Unpacks the data from the buffer between unpacking
|
||||
// sessions.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int DCPacker::
|
||||
raw_unpack_int8() {
|
||||
int value = 0;
|
||||
raw_unpack_int8(value);
|
||||
return value;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCPacker::raw_unpack_int16
|
||||
// Access: Published
|
||||
// Description: Unpacks the data from the buffer between unpacking
|
||||
// sessions.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int DCPacker::
|
||||
raw_unpack_int16() {
|
||||
int value = 0;
|
||||
raw_unpack_int16(value);
|
||||
return value;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCPacker::raw_unpack_int32
|
||||
// Access: Published
|
||||
// Description: Unpacks the data from the buffer between unpacking
|
||||
// sessions.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int DCPacker::
|
||||
raw_unpack_int32() {
|
||||
int value = 0;
|
||||
raw_unpack_int32(value);
|
||||
return value;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCPacker::raw_unpack_int64
|
||||
// Access: Published
|
||||
// Description: Unpacks the data from the buffer between unpacking
|
||||
// sessions.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE PN_int64 DCPacker::
|
||||
raw_unpack_int64() {
|
||||
PN_int64 value = 0;
|
||||
raw_unpack_int64(value);
|
||||
return value;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCPacker::raw_unpack_int8
|
||||
// Access: Public
|
||||
// Description: Unpacks the data from the buffer between unpacking
|
||||
// sessions.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void DCPacker::
|
||||
raw_unpack_int8(int &value) {
|
||||
nassertv(_mode == M_idle && _unpack_data != NULL);
|
||||
if (_unpack_p + 1 > _unpack_length) {
|
||||
_pack_error = true;
|
||||
return;
|
||||
}
|
||||
value = DCPackerInterface::do_unpack_int8(_unpack_data + _unpack_p);
|
||||
_unpack_p++;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCPacker::raw_unpack_int16
|
||||
// Access: Public
|
||||
// Description: Unpacks the data from the buffer between unpacking
|
||||
// sessions.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void DCPacker::
|
||||
raw_unpack_int16(int &value) {
|
||||
nassertv(_mode == M_idle && _unpack_data != NULL);
|
||||
if (_unpack_p + 2 > _unpack_length) {
|
||||
_pack_error = true;
|
||||
return;
|
||||
}
|
||||
value = DCPackerInterface::do_unpack_int16(_unpack_data + _unpack_p);
|
||||
_unpack_p += 2;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCPacker::raw_unpack_int32
|
||||
// Access: Public
|
||||
// Description: Unpacks the data from the buffer between unpacking
|
||||
// sessions.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void DCPacker::
|
||||
raw_unpack_int32(int &value) {
|
||||
nassertv(_mode == M_idle && _unpack_data != NULL);
|
||||
if (_unpack_p + 4 > _unpack_length) {
|
||||
_pack_error = true;
|
||||
return;
|
||||
}
|
||||
value = DCPackerInterface::do_unpack_int32(_unpack_data + _unpack_p);
|
||||
_unpack_p += 4;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCPacker::raw_unpack_uint8
|
||||
// Access: Published
|
||||
// Description: Unpacks the data from the buffer between unpacking
|
||||
// sessions.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE unsigned int DCPacker::
|
||||
raw_unpack_uint8() {
|
||||
unsigned int value = 0;
|
||||
raw_unpack_uint8(value);
|
||||
return value;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCPacker::raw_unpack_uint16
|
||||
// Access: Published
|
||||
// Description: Unpacks the data from the buffer between unpacking
|
||||
// sessions.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE unsigned int DCPacker::
|
||||
raw_unpack_uint16() {
|
||||
unsigned int value = 0;
|
||||
raw_unpack_uint16(value);
|
||||
return value;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCPacker::raw_unpack_uint32
|
||||
// Access: Published
|
||||
// Description: Unpacks the data from the buffer between unpacking
|
||||
// sessions.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE unsigned int DCPacker::
|
||||
raw_unpack_uint32() {
|
||||
unsigned int value = 0;
|
||||
raw_unpack_uint32(value);
|
||||
return value;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCPacker::raw_unpack_uint64
|
||||
// Access: Published
|
||||
// Description: Unpacks the data from the buffer between unpacking
|
||||
// sessions.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE PN_uint64 DCPacker::
|
||||
raw_unpack_uint64() {
|
||||
PN_uint64 value = 0;
|
||||
raw_unpack_uint64(value);
|
||||
return value;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCPacker::raw_unpack_float64
|
||||
// Access: Published
|
||||
// Description: Unpacks the data from the buffer between unpacking
|
||||
// sessions.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE double DCPacker::
|
||||
raw_unpack_float64() {
|
||||
double value = 0;
|
||||
raw_unpack_float64(value);
|
||||
return value;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCPacker::raw_unpack_string
|
||||
// Access: Published
|
||||
// Description: Unpacks the data from the buffer between unpacking
|
||||
// sessions.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE string DCPacker::
|
||||
raw_unpack_string() {
|
||||
string value;
|
||||
raw_unpack_string(value);
|
||||
return value;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCPacker::raw_unpack_int64
|
||||
// Access: Public
|
||||
// Description: Unpacks the data from the buffer between unpacking
|
||||
// sessions.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void DCPacker::
|
||||
raw_unpack_int64(PN_int64 &value) {
|
||||
nassertv(_mode == M_idle && _unpack_data != NULL);
|
||||
if (_unpack_p + 8 > _unpack_length) {
|
||||
_pack_error = true;
|
||||
return;
|
||||
}
|
||||
value = DCPackerInterface::do_unpack_int64(_unpack_data + _unpack_p);
|
||||
_unpack_p += 8;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCPacker::raw_unpack_uint8
|
||||
// Access: Public
|
||||
// Description: Unpacks the data from the buffer between unpacking
|
||||
// sessions.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void DCPacker::
|
||||
raw_unpack_uint8(unsigned int &value) {
|
||||
nassertv(_mode == M_idle && _unpack_data != NULL);
|
||||
if (_unpack_p + 1 > _unpack_length) {
|
||||
_pack_error = true;
|
||||
return;
|
||||
}
|
||||
value = DCPackerInterface::do_unpack_uint8(_unpack_data + _unpack_p);
|
||||
_unpack_p++;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCPacker::raw_unpack_uint16
|
||||
// Access: Public
|
||||
// Description: Unpacks the data from the buffer between unpacking
|
||||
// sessions.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void DCPacker::
|
||||
raw_unpack_uint16(unsigned int &value) {
|
||||
nassertv(_mode == M_idle && _unpack_data != NULL);
|
||||
if (_unpack_p + 2 > _unpack_length) {
|
||||
_pack_error = true;
|
||||
return;
|
||||
}
|
||||
value = DCPackerInterface::do_unpack_uint16(_unpack_data + _unpack_p);
|
||||
_unpack_p += 2;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCPacker::raw_unpack_uint32
|
||||
// Access: Public
|
||||
// Description: Unpacks the data from the buffer between unpacking
|
||||
// sessions.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void DCPacker::
|
||||
raw_unpack_uint32(unsigned int &value) {
|
||||
nassertv(_mode == M_idle && _unpack_data != NULL);
|
||||
if (_unpack_p + 4 > _unpack_length) {
|
||||
_pack_error = true;
|
||||
return;
|
||||
}
|
||||
value = DCPackerInterface::do_unpack_uint32(_unpack_data + _unpack_p);
|
||||
_unpack_p += 4;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCPacker::raw_unpack_uint64
|
||||
// Access: Public
|
||||
// Description: Unpacks the data from the buffer between unpacking
|
||||
// sessions.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void DCPacker::
|
||||
raw_unpack_uint64(PN_uint64 &value) {
|
||||
nassertv(_mode == M_idle && _unpack_data != NULL);
|
||||
if (_unpack_p + 8 > _unpack_length) {
|
||||
_pack_error = true;
|
||||
return;
|
||||
}
|
||||
value = DCPackerInterface::do_unpack_uint64(_unpack_data + _unpack_p);
|
||||
_unpack_p += 8;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCPacker::raw_unpack_float64
|
||||
// Access: Public
|
||||
// Description: Unpacks the data from the buffer between unpacking
|
||||
// sessions.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void DCPacker::
|
||||
raw_unpack_float64(double &value) {
|
||||
nassertv(_mode == M_idle && _unpack_data != NULL);
|
||||
if (_unpack_p + 8 > _unpack_length) {
|
||||
_pack_error = true;
|
||||
return;
|
||||
}
|
||||
value = DCPackerInterface::do_unpack_float64(_unpack_data + _unpack_p);
|
||||
_unpack_p += 8;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCPacker::raw_unpack_string
|
||||
// Access: Public
|
||||
// Description: Unpacks the data from the buffer between unpacking
|
||||
// sessions.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void DCPacker::
|
||||
raw_unpack_string(string &value) {
|
||||
nassertv(_mode == M_idle && _unpack_data != NULL);
|
||||
unsigned int string_length = raw_unpack_uint16();
|
||||
|
||||
if (_unpack_p + string_length > _unpack_length) {
|
||||
_pack_error = true;
|
||||
return;
|
||||
}
|
||||
|
||||
value.assign(_unpack_data + _unpack_p, string_length);
|
||||
_unpack_p += string_length;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCPacker::advance
|
||||
// Access: Private
|
||||
|
@ -49,6 +49,7 @@ DCPacker() {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
DCPacker::
|
||||
~DCPacker() {
|
||||
clear_data();
|
||||
clear();
|
||||
}
|
||||
|
||||
@ -58,6 +59,12 @@ DCPacker::
|
||||
// Description: Begins a packing session. The parameter is the DC
|
||||
// object that describes the packing format; it may be a
|
||||
// DCParameter or DCField.
|
||||
//
|
||||
// Unless you call clear_data() between sessions,
|
||||
// multiple packing sessions will be concatenated
|
||||
// together into the same buffer. If you wish to add
|
||||
// bytes to the buffer between packing sessions, use
|
||||
// append_data() or get_write_pointer().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void DCPacker::
|
||||
begin_pack(const DCPackerInterface *root) {
|
||||
@ -66,7 +73,6 @@ begin_pack(const DCPackerInterface *root) {
|
||||
_mode = M_pack;
|
||||
_pack_error = false;
|
||||
_range_error = false;
|
||||
_pack_data.clear();
|
||||
|
||||
_root = root;
|
||||
_catalog = NULL;
|
||||
@ -102,36 +108,63 @@ end_pack() {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCPacker::begin_unpack
|
||||
// Access: Published
|
||||
// Description: Begins an unpacking session. Unlike the other
|
||||
// version of begin_unpack(), this version makes a copy
|
||||
// of the data string.
|
||||
// Function: DCPacker::set_unpack_data
|
||||
// Access: Public
|
||||
// Description: Sets up the unpack_data pointer. You may call this
|
||||
// before calling the version of begin_unpack() that
|
||||
// takes only one parameter.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void DCPacker::
|
||||
begin_unpack(const string &data, const DCPackerInterface *root) {
|
||||
_unpack_str = data;
|
||||
begin_unpack(_unpack_str.data(), _unpack_str.length(), root);
|
||||
set_unpack_data(const string &data) {
|
||||
nassertv(_mode == M_idle);
|
||||
|
||||
char *buffer = new char[data.length()];
|
||||
memcpy(buffer, data.data(), data.length());
|
||||
set_unpack_data(buffer, data.length(), true);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCPacker::set_unpack_data
|
||||
// Access: Public
|
||||
// Description: Sets up the unpack_data pointer. You may call this
|
||||
// before calling the version of begin_unpack() that
|
||||
// takes only one parameter.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void DCPacker::
|
||||
set_unpack_data(const char *unpack_data, size_t unpack_length,
|
||||
bool owns_unpack_data) {
|
||||
nassertv(_mode == M_idle);
|
||||
|
||||
if (_owns_unpack_data) {
|
||||
delete[] _unpack_data;
|
||||
}
|
||||
_unpack_data = unpack_data;
|
||||
_unpack_length = unpack_length;
|
||||
_owns_unpack_data = owns_unpack_data;
|
||||
_unpack_p = 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCPacker::begin_unpack
|
||||
// Access: Public
|
||||
// Description: Begins an unpacking session. The data pointer is
|
||||
// used directly; the data buffer is not copied.
|
||||
// Therefore, you must not delete or modify the data
|
||||
// pointer until you call end_unpack().
|
||||
// Description: Begins an unpacking session. You must have
|
||||
// previously called set_unpack_data() to specify a
|
||||
// buffer to unpack.
|
||||
//
|
||||
// If there was data left in the buffer after a previous
|
||||
// begin_unpack() .. end_unpack() session, the new
|
||||
// session will resume from the current point. This
|
||||
// method may be used, therefore, to unpack a sequence
|
||||
// of objects from the same buffer.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void DCPacker::
|
||||
begin_unpack(const char *data, size_t length,
|
||||
const DCPackerInterface *root) {
|
||||
begin_unpack(const DCPackerInterface *root) {
|
||||
nassertv(_mode == M_idle);
|
||||
nassertv(_unpack_data != NULL);
|
||||
|
||||
_mode = M_unpack;
|
||||
_pack_error = false;
|
||||
_range_error = false;
|
||||
set_unpack_data(data, length, false);
|
||||
_unpack_p = 0;
|
||||
|
||||
_root = root;
|
||||
_catalog = NULL;
|
||||
@ -175,44 +208,34 @@ end_unpack() {
|
||||
return !_pack_error && !_range_error;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCPacker::begin_repack
|
||||
// Access: Published
|
||||
// Description: Begins an repacking session. Unlike the other
|
||||
// version of begin_repack(), this version makes a copy
|
||||
// of the data string.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void DCPacker::
|
||||
begin_repack(const string &data, const DCPackerInterface *root) {
|
||||
_unpack_str = data;
|
||||
begin_repack(_unpack_str.data(), _unpack_str.length(), root);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCPacker::begin_repack
|
||||
// Access: Public
|
||||
// Description: Begins an repacking session. The data pointer is
|
||||
// used directly; the data buffer is not copied.
|
||||
// Therefore, you must not delete or modify the data
|
||||
// pointer until you call end_repack().
|
||||
// Description: Begins a repacking session. You must have previously
|
||||
// called set_unpack_data() to specify a buffer to
|
||||
// unpack.
|
||||
//
|
||||
// When repacking, unlike in packing or unpacking modes,
|
||||
// you may not walk through the fields from beginning to
|
||||
// end, or even pack two consecutive fields at once.
|
||||
// Instead, you must call seek() for each field you wish
|
||||
// to modify and pack only that one field; then call
|
||||
// seek() again to modify another field.
|
||||
// Unlike begin_pack() or begin_unpack() you may not
|
||||
// concatenate the results of multiple begin_repack()
|
||||
// sessions in one buffer.
|
||||
//
|
||||
// Also, unlike in packing or unpacking modes, you may
|
||||
// not walk through the fields from beginning to end, or
|
||||
// even pack two consecutive fields at once. Instead,
|
||||
// you must call seek() for each field you wish to
|
||||
// modify and pack only that one field; then call seek()
|
||||
// again to modify another field.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void DCPacker::
|
||||
begin_repack(const char *data, size_t length,
|
||||
const DCPackerInterface *root) {
|
||||
begin_repack(const DCPackerInterface *root) {
|
||||
nassertv(_mode == M_idle);
|
||||
nassertv(_unpack_data != NULL);
|
||||
nassertv(_unpack_p == 0);
|
||||
|
||||
_mode = M_repack;
|
||||
_pack_error = false;
|
||||
_range_error = false;
|
||||
set_unpack_data(data, length, false);
|
||||
_unpack_p = 0;
|
||||
_pack_data.clear();
|
||||
|
||||
// In repack mode, we immediately get the catalog, since we know
|
||||
// we'll need it.
|
||||
@ -1009,24 +1032,6 @@ clear() {
|
||||
}
|
||||
_catalog = NULL;
|
||||
_root = NULL;
|
||||
|
||||
set_unpack_data(NULL, 0, false);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCPacker::set_unpack_data
|
||||
// Access: Private
|
||||
// Description: Sets up the unpack_data pointer.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void DCPacker::
|
||||
set_unpack_data(const char *unpack_data, size_t unpack_length,
|
||||
bool owns_unpack_data) {
|
||||
if (_owns_unpack_data) {
|
||||
delete[] _unpack_data;
|
||||
}
|
||||
_unpack_data = unpack_data;
|
||||
_unpack_length = unpack_length;
|
||||
_owns_unpack_data = owns_unpack_data;
|
||||
}
|
||||
|
||||
#ifdef HAVE_PYTHON
|
||||
|
@ -44,21 +44,21 @@ PUBLISHED:
|
||||
DCPacker();
|
||||
~DCPacker();
|
||||
|
||||
INLINE void clear_data();
|
||||
|
||||
void begin_pack(const DCPackerInterface *root);
|
||||
bool end_pack();
|
||||
|
||||
void set_unpack_data(const string &data);
|
||||
public:
|
||||
void begin_unpack(const char *data, size_t length,
|
||||
const DCPackerInterface *root);
|
||||
void set_unpack_data(const char *unpack_data, size_t unpack_length,
|
||||
bool owns_unpack_data);
|
||||
|
||||
PUBLISHED:
|
||||
void begin_unpack(const string &data, const DCPackerInterface *root);
|
||||
void begin_unpack(const DCPackerInterface *root);
|
||||
bool end_unpack();
|
||||
|
||||
public:
|
||||
void begin_repack(const char *data, size_t length,
|
||||
const DCPackerInterface *root);
|
||||
PUBLISHED:
|
||||
void begin_repack(const string &data, const DCPackerInterface *root);
|
||||
void begin_repack(const DCPackerInterface *root);
|
||||
bool end_repack();
|
||||
|
||||
bool seek(const string &field_name);
|
||||
@ -125,6 +125,49 @@ PUBLISHED:
|
||||
public:
|
||||
INLINE const char *get_data() const;
|
||||
|
||||
INLINE void append_data(const char *buffer, size_t size);
|
||||
INLINE char *get_write_pointer(size_t size);
|
||||
|
||||
PUBLISHED:
|
||||
// The following methods are used only for packing (or unpacking)
|
||||
// raw data into the buffer between packing sessions (e.g. between
|
||||
// calls to end_pack() and the next begin_pack()).
|
||||
|
||||
INLINE void raw_pack_int8(int value);
|
||||
INLINE void raw_pack_int16(int value);
|
||||
INLINE void raw_pack_int32(int value);
|
||||
INLINE void raw_pack_int64(PN_int64 value);
|
||||
INLINE void raw_pack_uint8(unsigned int value);
|
||||
INLINE void raw_pack_uint16(unsigned int value);
|
||||
INLINE void raw_pack_uint32(unsigned int value);
|
||||
INLINE void raw_pack_uint64(PN_uint64 value);
|
||||
INLINE void raw_pack_float64(double value);
|
||||
INLINE void raw_pack_string(const string &value);
|
||||
|
||||
INLINE int raw_unpack_int8();
|
||||
INLINE int raw_unpack_int16();
|
||||
INLINE int raw_unpack_int32();
|
||||
INLINE PN_int64 raw_unpack_int64();
|
||||
INLINE unsigned int raw_unpack_uint8();
|
||||
INLINE unsigned int raw_unpack_uint16();
|
||||
INLINE unsigned int raw_unpack_uint32();
|
||||
INLINE PN_uint64 raw_unpack_uint64();
|
||||
INLINE double raw_unpack_float64();
|
||||
INLINE string raw_unpack_string();
|
||||
|
||||
public:
|
||||
INLINE void raw_unpack_int8(int &value);
|
||||
INLINE void raw_unpack_int16(int &value);
|
||||
INLINE void raw_unpack_int32(int &value);
|
||||
INLINE void raw_unpack_int64(PN_int64 &value);
|
||||
INLINE void raw_unpack_uint8(unsigned int &value);
|
||||
INLINE void raw_unpack_uint16(unsigned int &value);
|
||||
INLINE void raw_unpack_uint32(unsigned int &value);
|
||||
INLINE void raw_unpack_uint64(PN_uint64 &value);
|
||||
INLINE void raw_unpack_float64(double &value);
|
||||
INLINE void raw_unpack_string(string &value);
|
||||
|
||||
public:
|
||||
static void enquote_string(ostream &out, char quote_mark, const string &str);
|
||||
static void output_hex_string(ostream &out, const string &str);
|
||||
|
||||
@ -132,8 +175,6 @@ private:
|
||||
INLINE void advance();
|
||||
void handle_switch(const DCSwitch *dswitch);
|
||||
void clear();
|
||||
void set_unpack_data(const char *unpack_data, size_t unpack_length,
|
||||
bool owns_unpack_data);
|
||||
|
||||
#ifdef HAVE_PYTHON
|
||||
PyObject *unpack_class_object(DCClass *dclass);
|
||||
@ -150,7 +191,6 @@ private:
|
||||
Mode _mode;
|
||||
|
||||
DCPackData _pack_data;
|
||||
string _unpack_str;
|
||||
const char *_unpack_data;
|
||||
size_t _unpack_length;
|
||||
bool _owns_unpack_data;
|
||||
|
@ -133,7 +133,8 @@ get_live_catalog(const char *data, size_t length) const {
|
||||
}
|
||||
|
||||
DCPacker packer;
|
||||
packer.begin_unpack(data, length, _root);
|
||||
packer.set_unpack_data(data, length, false);
|
||||
packer.begin_unpack(_root);
|
||||
const DCSwitch *last_switch = NULL;
|
||||
r_fill_live_catalog(live_catalog, packer, last_switch);
|
||||
bool okflag = packer.end_unpack();
|
||||
|
Loading…
x
Reference in New Issue
Block a user