From 7e70887ab2388f7b0b14f8e210995774d443121f Mon Sep 17 00:00:00 2001 From: David Rose Date: Fri, 18 Jun 2004 18:46:25 +0000 Subject: [PATCH] add unsigned pack/unpack, modularize packing methods --- direct/src/dcparser/Sources.pp | 2 +- direct/src/dcparser/dcPackData.I | 25 + direct/src/dcparser/dcPackData.h | 2 + direct/src/dcparser/dcPacker.I | 84 +++ direct/src/dcparser/dcPacker.cxx | 49 +- direct/src/dcparser/dcPacker.h | 4 + direct/src/dcparser/dcPackerInterface.I | 261 +++++++++ direct/src/dcparser/dcPackerInterface.cxx | 44 ++ direct/src/dcparser/dcPackerInterface.h | 31 + direct/src/dcparser/dcSimpleParameter.cxx | 674 +++++++++++++--------- direct/src/dcparser/dcSimpleParameter.h | 4 + 11 files changed, 883 insertions(+), 297 deletions(-) create mode 100644 direct/src/dcparser/dcPackerInterface.I diff --git a/direct/src/dcparser/Sources.pp b/direct/src/dcparser/Sources.pp index fac1cf4405..96f9a25cd6 100644 --- a/direct/src/dcparser/Sources.pp +++ b/direct/src/dcparser/Sources.pp @@ -20,7 +20,7 @@ dcSubatomicType.h \ dcPackData.h dcPackData.I \ dcPacker.h dcPacker.I \ - dcPackerInterface.h \ + dcPackerInterface.h dcPackerInterface.I \ dcParameter.h dcArrayParameter.h dcSimpleParameter.h \ dcTypedef.h \ dcbase.h dcindent.h hashGenerator.h \ diff --git a/direct/src/dcparser/dcPackData.I b/direct/src/dcparser/dcPackData.I index 4c25543318..f447ff87bb 100755 --- a/direct/src/dcparser/dcPackData.I +++ b/direct/src/dcparser/dcPackData.I @@ -63,6 +63,19 @@ append_data(const char *buffer, size_t size) { memcpy(_buffer + _used_length - size, buffer, size); } +//////////////////////////////////////////////////////////////////// +// Function: DCPackData::get_write_pointer +// Access: Published +// 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. +//////////////////////////////////////////////////////////////////// +INLINE char *DCPackData:: +get_write_pointer(size_t size) { + set_used_length(_used_length + size); + return _buffer + _used_length - size; +} + //////////////////////////////////////////////////////////////////// // Function: DCPackData::append_junk // Access: Published @@ -86,6 +99,18 @@ rewrite_data(size_t position, const char *buffer, size_t size) { memcpy(_buffer + position, buffer, size); } +//////////////////////////////////////////////////////////////////// +// Function: DCPackData::get_rewrite_pointer +// Access: Published +// Description: Returns a pointer into the middle of the data at the +// indicated point. +//////////////////////////////////////////////////////////////////// +INLINE char *DCPackData:: +get_rewrite_pointer(size_t position, size_t size) { + nassertr(position + size <= _used_length, NULL); + return _buffer + position; +} + //////////////////////////////////////////////////////////////////// // Function: DCPackData::get_string // Access: Published diff --git a/direct/src/dcparser/dcPackData.h b/direct/src/dcparser/dcPackData.h index 848497076c..14bc9921a3 100755 --- a/direct/src/dcparser/dcPackData.h +++ b/direct/src/dcparser/dcPackData.h @@ -34,8 +34,10 @@ PUBLISHED: INLINE void clear(); 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); INLINE string get_string() const; INLINE size_t get_length() const; diff --git a/direct/src/dcparser/dcPacker.I b/direct/src/dcparser/dcPacker.I index c0d251f96c..2ec2b45e8c 100755 --- a/direct/src/dcparser/dcPacker.I +++ b/direct/src/dcparser/dcPacker.I @@ -123,6 +123,25 @@ pack_int(int value) { } } +//////////////////////////////////////////////////////////////////// +// Function: DCPacker::pack_uint +// Access: Published +// Description: Packs the indicated numeric or string value into the +// stream. +//////////////////////////////////////////////////////////////////// +INLINE void DCPacker:: +pack_uint(unsigned int value) { + nassertv(_mode == M_pack); + if (_current_field == NULL) { + _pack_error = true; + } else { + if (!_current_field->pack_uint(_pack_data, value)) { + _pack_error = true; + } + advance(); + } +} + //////////////////////////////////////////////////////////////////// // Function: DCPacker::pack_int64 // Access: Published @@ -142,6 +161,25 @@ pack_int64(PN_int64 value) { } } +//////////////////////////////////////////////////////////////////// +// Function: DCPacker::pack_uint64 +// Access: Published +// Description: Packs the indicated numeric or string value into the +// stream. +//////////////////////////////////////////////////////////////////// +INLINE void DCPacker:: +pack_uint64(PN_uint64 value) { + nassertv(_mode == M_pack); + if (_current_field == NULL) { + _pack_error = true; + } else { + if (!_current_field->pack_uint64(_pack_data, value)) { + _pack_error = true; + } + advance(); + } +} + //////////////////////////////////////////////////////////////////// // Function: DCPacker::pack_string // Access: Published @@ -225,6 +263,29 @@ unpack_int() { return value; } +//////////////////////////////////////////////////////////////////// +// Function: DCPacker::unpack_uint +// Access: Published +// Description: Unpacks the current numeric or string value from the +// stream. +//////////////////////////////////////////////////////////////////// +INLINE unsigned int DCPacker:: +unpack_uint() { + unsigned int value = 0; + nassertr(_mode == M_unpack, value); + if (_current_field == NULL) { + _pack_error = true; + + } else { + if (!_current_field->unpack_uint(_unpack_data, _unpack_length, _unpack_p, value)) { + _pack_error = true; + } + advance(); + } + + return value; +} + //////////////////////////////////////////////////////////////////// // Function: DCPacker::unpack_int64 // Access: Published @@ -248,6 +309,29 @@ unpack_int64() { return value; } +//////////////////////////////////////////////////////////////////// +// Function: DCPacker::unpack_uint64 +// Access: Published +// Description: Unpacks the current numeric or string value from the +// stream. +//////////////////////////////////////////////////////////////////// +INLINE PN_uint64 DCPacker:: +unpack_uint64() { + PN_uint64 value = 0; + nassertr(_mode == M_unpack, value); + if (_current_field == NULL) { + _pack_error = true; + + } else { + if (!_current_field->unpack_uint64(_unpack_data, _unpack_length, _unpack_p, value)) { + _pack_error = true; + } + advance(); + } + + return value; +} + //////////////////////////////////////////////////////////////////// // Function: DCPacker::unpack_string // Access: Published diff --git a/direct/src/dcparser/dcPacker.cxx b/direct/src/dcparser/dcPacker.cxx index 1e3e55a030..880c389f59 100755 --- a/direct/src/dcparser/dcPacker.cxx +++ b/direct/src/dcparser/dcPacker.cxx @@ -209,15 +209,13 @@ push() { } else { size_t length; if (length_bytes == 4) { - length = (size_t)((size_t)(unsigned char)_unpack_data[_unpack_p + 0] | - ((size_t)(unsigned char)_unpack_data[_unpack_p + 1] << 8) | - ((size_t)(unsigned char)_unpack_data[_unpack_p + 2] << 16) | - ((size_t)(unsigned char)_unpack_data[_unpack_p + 3] << 24)); + length = DCPackerInterface::do_unpack_uint32 + (_unpack_data + _unpack_p); _unpack_p += 4; _push_marker = _unpack_p + length; } else { - length = (size_t)((size_t)(unsigned char)_unpack_data[_unpack_p + 0] | - ((size_t)(unsigned char)_unpack_data[_unpack_p + 1] << 8)); + length = DCPackerInterface::do_unpack_uint16 + (_unpack_data + _unpack_p); _unpack_p += 2; } _push_marker = _unpack_p + length; @@ -280,18 +278,13 @@ pop() { size_t length_bytes = _current_parent->get_num_length_bytes(); if (length_bytes != 0) { // Now go back and fill in the length of the array. - char buffer[4]; size_t length = _pack_data.get_length() - _push_marker - length_bytes; if (length_bytes == 4) { - buffer[0] = (char)(length & 0xff); - buffer[1] = (char)((length >> 8) & 0xff); - buffer[2] = (char)((length >> 16) & 0xff); - buffer[3] = (char)((length >> 24) & 0xff); - _pack_data.rewrite_data(_push_marker, buffer, 4); + DCPackerInterface::do_pack_uint32 + (_pack_data.get_rewrite_pointer(_push_marker, 4), length); } else { - buffer[0] = (char)(length & 0xff); - buffer[1] = (char)((length >> 8) & 0xff); - _pack_data.rewrite_data(_push_marker, buffer, 2); + DCPackerInterface::do_pack_uint16 + (_pack_data.get_rewrite_pointer(_push_marker, 2), length); } } } @@ -384,12 +377,30 @@ unpack_object() { } break; + case PT_uint: + { + unsigned int value = unpack_uint(); + if (value & 0x80000000) { + object = PyLong_FromUnsignedLong(value); + } else { + object = PyInt_FromLong(value); + } + } + break; + case PT_int64: { PN_int64 value = unpack_int64(); object = PyLong_FromLongLong(value); } break; + + case PT_uint64: + { + PN_uint64 value = unpack_uint64(); + object = PyLong_FromUnsignedLongLong(value); + } + break; case PT_string: { @@ -494,9 +505,17 @@ unpack_and_format(ostream &out) { out << unpack_int(); break; + case PT_uint: + out << unpack_uint(); + break; + case PT_int64: out << unpack_int64(); break; + + case PT_uint64: + out << unpack_uint64(); + break; case PT_string: out << '"' << unpack_string() << '"'; diff --git a/direct/src/dcparser/dcPacker.h b/direct/src/dcparser/dcPacker.h index 7e584cea7c..62f98c0d74 100755 --- a/direct/src/dcparser/dcPacker.h +++ b/direct/src/dcparser/dcPacker.h @@ -56,13 +56,17 @@ PUBLISHED: INLINE void pack_double(double value); INLINE void pack_int(int value); + INLINE void pack_uint(unsigned int value); INLINE void pack_int64(PN_int64 value); + INLINE void pack_uint64(PN_uint64 value); INLINE void pack_string(const string &value); INLINE void pack_literal_value(const string &value); INLINE double unpack_double(); INLINE int unpack_int(); + INLINE unsigned int unpack_uint(); INLINE PN_int64 unpack_int64(); + INLINE PN_uint64 unpack_uint64(); INLINE string unpack_string(); #ifdef HAVE_PYTHON diff --git a/direct/src/dcparser/dcPackerInterface.I b/direct/src/dcparser/dcPackerInterface.I new file mode 100644 index 0000000000..891ac1866e --- /dev/null +++ b/direct/src/dcparser/dcPackerInterface.I @@ -0,0 +1,261 @@ +// Filename: dcPackerInterface.I +// Created by: drose (18Jun04) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved +// +// All use of this software is subject to the terms of the Panda 3d +// Software license. You should have received a copy of this license +// along with this source code; you will also find a current copy of +// the license at http://etc.cmu.edu/panda3d/docs/license/ . +// +// To contact the maintainers of this program write to +// panda3d-general@lists.sourceforge.net . +// +//////////////////////////////////////////////////////////////////// + + +//////////////////////////////////////////////////////////////////// +// Function: DCPackerInterface::do_pack_int8 +// Access: Public, Static +// Description: +//////////////////////////////////////////////////////////////////// +INLINE void DCPackerInterface:: +do_pack_int8(char *buffer, int value) { + buffer[0] = (char)(value & 0xff); +} + +//////////////////////////////////////////////////////////////////// +// Function: DCPackerInterface::do_pack_int16 +// Access: Public, Static +// Description: +//////////////////////////////////////////////////////////////////// +INLINE void DCPackerInterface:: +do_pack_int16(char *buffer, int value) { + buffer[0] = (char)(value & 0xff); + buffer[1] = (char)((value >> 8) & 0xff); +} + +//////////////////////////////////////////////////////////////////// +// Function: DCPackerInterface::do_pack_int32 +// Access: Public, Static +// Description: +//////////////////////////////////////////////////////////////////// +INLINE void DCPackerInterface:: +do_pack_int32(char *buffer, int value) { + buffer[0] = (char)(value & 0xff); + buffer[1] = (char)((value >> 8) & 0xff); + buffer[2] = (char)((value >> 16) & 0xff); + buffer[3] = (char)((value >> 24) & 0xff); +} + +//////////////////////////////////////////////////////////////////// +// Function: DCPackerInterface::do_pack_int64 +// Access: Public, Static +// Description: +//////////////////////////////////////////////////////////////////// +INLINE void DCPackerInterface:: +do_pack_int64(char *buffer, PN_int64 value) { + buffer[0] = (char)(value & 0xff); + buffer[1] = (char)((value >> 8) & 0xff); + buffer[2] = (char)((value >> 16) & 0xff); + buffer[3] = (char)((value >> 24) & 0xff); + buffer[4] = (char)((value >> 32) & 0xff); + buffer[5] = (char)((value >> 40) & 0xff); + buffer[6] = (char)((value >> 48) & 0xff); + buffer[7] = (char)((value >> 56) & 0xff); +} + +//////////////////////////////////////////////////////////////////// +// Function: DCPackerInterface::do_pack_uint8 +// Access: Public, Static +// Description: +//////////////////////////////////////////////////////////////////// +INLINE void DCPackerInterface:: +do_pack_uint8(char *buffer, unsigned int value) { + buffer[0] = (char)(value & 0xff); +} + +//////////////////////////////////////////////////////////////////// +// Function: DCPackerInterface::do_pack_uint16 +// Access: Public, Static +// Description: +//////////////////////////////////////////////////////////////////// +INLINE void DCPackerInterface:: +do_pack_uint16(char *buffer, unsigned int value) { + buffer[0] = (char)(value & 0xff); + buffer[1] = (char)((value >> 8) & 0xff); +} + +//////////////////////////////////////////////////////////////////// +// Function: DCPackerInterface::do_pack_uint32 +// Access: Public, Static +// Description: +//////////////////////////////////////////////////////////////////// +INLINE void DCPackerInterface:: +do_pack_uint32(char *buffer, unsigned int value) { + buffer[0] = (char)(value & 0xff); + buffer[1] = (char)((value >> 8) & 0xff); + buffer[2] = (char)((value >> 16) & 0xff); + buffer[3] = (char)((value >> 24) & 0xff); +} + +//////////////////////////////////////////////////////////////////// +// Function: DCPackerInterface::do_pack_uint64 +// Access: Public, Static +// Description: +//////////////////////////////////////////////////////////////////// +INLINE void DCPackerInterface:: +do_pack_uint64(char *buffer, PN_uint64 value) { + buffer[0] = (char)(value & 0xff); + buffer[1] = (char)((value >> 8) & 0xff); + buffer[2] = (char)((value >> 16) & 0xff); + buffer[3] = (char)((value >> 24) & 0xff); + buffer[4] = (char)((value >> 32) & 0xff); + buffer[5] = (char)((value >> 40) & 0xff); + buffer[6] = (char)((value >> 48) & 0xff); + buffer[7] = (char)((value >> 56) & 0xff); +} + +//////////////////////////////////////////////////////////////////// +// Function: DCPackerInterface::do_pack_float64 +// Access: Public, Static +// Description: +//////////////////////////////////////////////////////////////////// +INLINE void DCPackerInterface:: +do_pack_float64(char *buffer, double value) { +#ifdef WORDS_BIGENDIAN + // Reverse the byte ordering for big-endian machines. + char *p = (char *)value; + for (size_t i = 0; i < 8; i++) { + buffer[i] = p[7 - i]; + } +#else + memcpy(buffer, &value, 8); +#endif +} + + +//////////////////////////////////////////////////////////////////// +// Function: DCPackerInterface::do_unpack_int8 +// Access: Public, Static +// Description: +//////////////////////////////////////////////////////////////////// +INLINE int DCPackerInterface:: +do_unpack_int8(const char *buffer) { + return (int)(signed char)buffer[0]; +} + +//////////////////////////////////////////////////////////////////// +// Function: DCPackerInterface::do_unpack_int16 +// Access: Public, Static +// Description: +//////////////////////////////////////////////////////////////////// +INLINE int DCPackerInterface:: +do_unpack_int16(const char *buffer) { + return (int)((unsigned int)(unsigned char)buffer[0] | + ((int)(signed char)buffer[1] << 8)); +} + +//////////////////////////////////////////////////////////////////// +// Function: DCPackerInterface::do_unpack_int32 +// Access: Public, Static +// Description: +//////////////////////////////////////////////////////////////////// +INLINE int DCPackerInterface:: +do_unpack_int32(const char *buffer) { + return (int)((unsigned int)(unsigned char)buffer[0] | + ((unsigned int)(unsigned char)buffer[1] << 8) | + ((unsigned int)(unsigned char)buffer[2] << 16) | + ((int)(signed char)buffer[3] << 24)); +} + +//////////////////////////////////////////////////////////////////// +// Function: DCPackerInterface::do_unpack_int64 +// Access: Public, Static +// Description: +//////////////////////////////////////////////////////////////////// +INLINE PN_int64 DCPackerInterface:: +do_unpack_int64(const char *buffer) { + return (PN_int64)((PN_uint64)(unsigned char)buffer[0] | + ((PN_uint64)(unsigned char)buffer[1] << 8) | + ((PN_uint64)(unsigned char)buffer[2] << 16) | + ((PN_uint64)(unsigned char)buffer[3] << 24) | + ((PN_uint64)(unsigned char)buffer[4] << 32) | + ((PN_uint64)(unsigned char)buffer[5] << 40) | + ((PN_uint64)(unsigned char)buffer[6] << 48) | + ((PN_int64)(signed char)buffer[7] << 54)); +} +//////////////////////////////////////////////////////////////////// +// Function: DCPackerInterface::do_unpack_uint8 +// Access: Public, Static +// Description: +//////////////////////////////////////////////////////////////////// +INLINE unsigned int DCPackerInterface:: +do_unpack_uint8(const char *buffer) { + return (unsigned int)(unsigned char)buffer[0]; +} + +//////////////////////////////////////////////////////////////////// +// Function: DCPackerInterface::do_unpack_uint16 +// Access: Public, Static +// Description: +//////////////////////////////////////////////////////////////////// +INLINE unsigned int DCPackerInterface:: +do_unpack_uint16(const char *buffer) { + return ((unsigned int)(unsigned char)buffer[0] | + ((unsigned int)(unsigned char)buffer[1] << 8)); +} + +//////////////////////////////////////////////////////////////////// +// Function: DCPackerInterface::do_unpack_uint32 +// Access: Public, Static +// Description: +//////////////////////////////////////////////////////////////////// +INLINE unsigned int DCPackerInterface:: +do_unpack_uint32(const char *buffer) { + return ((unsigned int)(unsigned char)buffer[0] | + ((unsigned int)(unsigned char)buffer[1] << 8) | + ((unsigned int)(unsigned char)buffer[2] << 16) | + ((unsigned int)(unsigned char)buffer[3] << 24)); +} + +//////////////////////////////////////////////////////////////////// +// Function: DCPackerInterface::do_unpack_uint64 +// Access: Public, Static +// Description: +//////////////////////////////////////////////////////////////////// +INLINE PN_uint64 DCPackerInterface:: +do_unpack_uint64(const char *buffer) { + return ((PN_uint64)(unsigned char)buffer[0] | + ((PN_uint64)(unsigned char)buffer[1] << 8) | + ((PN_uint64)(unsigned char)buffer[2] << 16) | + ((PN_uint64)(unsigned char)buffer[3] << 24) | + ((PN_uint64)(unsigned char)buffer[4] << 32) | + ((PN_uint64)(unsigned char)buffer[5] << 40) | + ((PN_uint64)(unsigned char)buffer[6] << 48) | + ((PN_int64)(signed char)buffer[7] << 54)); +} + + +//////////////////////////////////////////////////////////////////// +// Function: DCPackerInterface::do_unpack_float64 +// Access: Public, Static +// Description: +//////////////////////////////////////////////////////////////////// +INLINE double DCPackerInterface:: +do_unpack_float64(const char *buffer) { +#ifdef WORDS_BIGENDIAN + char reverse[8]; + + // Reverse the byte ordering for big-endian machines. + for (size_t i = 0; i < 8; i++) { + reverse[i] = buffer[7 - i]; + } + return *(double *)reverse; +#else + return *(double *)buffer; +#endif // WORDS_BIGENDIAN +} diff --git a/direct/src/dcparser/dcPackerInterface.cxx b/direct/src/dcparser/dcPackerInterface.cxx index 687257dbc9..f131caec6d 100755 --- a/direct/src/dcparser/dcPackerInterface.cxx +++ b/direct/src/dcparser/dcPackerInterface.cxx @@ -205,6 +205,17 @@ pack_int(DCPackData &, int) const { return false; } +//////////////////////////////////////////////////////////////////// +// Function: DCPackerInterface::pack_uint +// Access: Public, Virtual +// Description: Packs the indicated numeric or string value into the +// stream. Returns true on success, false on failure. +//////////////////////////////////////////////////////////////////// +bool DCPackerInterface:: +pack_uint(DCPackData &, unsigned int) const { + return false; +} + //////////////////////////////////////////////////////////////////// // Function: DCPackerInterface::pack_int64 // Access: Public, Virtual @@ -216,6 +227,17 @@ pack_int64(DCPackData &, PN_int64) const { return false; } +//////////////////////////////////////////////////////////////////// +// Function: DCPackerInterface::pack_uint64 +// Access: Public, Virtual +// Description: Packs the indicated numeric or string value into the +// stream. Returns true on success, false on failure. +//////////////////////////////////////////////////////////////////// +bool DCPackerInterface:: +pack_uint64(DCPackData &, PN_uint64) const { + return false; +} + //////////////////////////////////////////////////////////////////// // Function: DCPackerInterface::pack_string // Access: Public, Virtual @@ -249,6 +271,17 @@ unpack_int(const char *, size_t, size_t &, int &) const { return false; } +//////////////////////////////////////////////////////////////////// +// Function: DCPackerInterface::unpack_uint +// Access: Public, Virtual +// Description: Unpacks the current numeric or string value from the +// stream. Returns true on success, false on failure. +//////////////////////////////////////////////////////////////////// +bool DCPackerInterface:: +unpack_uint(const char *, size_t, size_t &, unsigned int &) const { + return false; +} + //////////////////////////////////////////////////////////////////// // Function: DCPackerInterface::unpack_int64 // Access: Public, Virtual @@ -260,6 +293,17 @@ unpack_int64(const char *, size_t, size_t &, PN_int64 &) const { return false; } +//////////////////////////////////////////////////////////////////// +// Function: DCPackerInterface::unpack_uint64 +// Access: Public, Virtual +// Description: Unpacks the current numeric or string value from the +// stream. Returns true on success, false on failure. +//////////////////////////////////////////////////////////////////// +bool DCPackerInterface:: +unpack_uint64(const char *, size_t, size_t &, PN_uint64 &) const { + return false; +} + //////////////////////////////////////////////////////////////////// // Function: DCPackerInterface::unpack_string // Access: Public, Virtual diff --git a/direct/src/dcparser/dcPackerInterface.h b/direct/src/dcparser/dcPackerInterface.h index 1f1073a519..e7db794478 100755 --- a/direct/src/dcparser/dcPackerInterface.h +++ b/direct/src/dcparser/dcPackerInterface.h @@ -36,7 +36,9 @@ enum DCPackType { // pack_int(), etc. PT_double, PT_int, + PT_uint, PT_int64, + PT_uint64, PT_string, // The remaining PackTypes imply a need to call push() and pop(). @@ -82,14 +84,41 @@ public: virtual bool pack_double(DCPackData &pack_data, double value) const; virtual bool pack_int(DCPackData &pack_data, int value) const; + virtual bool pack_uint(DCPackData &pack_data, unsigned int value) const; virtual bool pack_int64(DCPackData &pack_data, PN_int64 value) const; + virtual bool pack_uint64(DCPackData &pack_data, PN_uint64 value) const; virtual bool pack_string(DCPackData &pack_data, const string &value) const; virtual bool unpack_double(const char *data, size_t length, size_t &p, double &value) const; virtual bool unpack_int(const char *data, size_t length, size_t &p, int &value) const; + virtual bool unpack_uint(const char *data, size_t length, size_t &p, unsigned int &value) const; virtual bool unpack_int64(const char *data, size_t length, size_t &p, PN_int64 &value) const; + virtual bool unpack_uint64(const char *data, size_t length, size_t &p, PN_uint64 &value) const; virtual bool unpack_string(const char *data, size_t length, size_t &p, string &value) const; + // These are the low-level interfaces for packing and unpacking + // numbers from a buffer. You're responsible for making sure the + // buffer has enough room, and for incrementing the pointer. + INLINE static void do_pack_int8(char *buffer, int value); + INLINE static void do_pack_int16(char *buffer, int value); + INLINE static void do_pack_int32(char *buffer, int value); + INLINE static void do_pack_int64(char *buffer, PN_int64 value); + INLINE static void do_pack_uint8(char *buffer, unsigned int value); + INLINE static void do_pack_uint16(char *buffer, unsigned int value); + INLINE static void do_pack_uint32(char *buffer, unsigned int value); + INLINE static void do_pack_uint64(char *buffer, PN_uint64 value); + INLINE static void do_pack_float64(char *buffer, double value); + + INLINE static int do_unpack_int8(const char *buffer); + INLINE static int do_unpack_int16(const char *buffer); + INLINE static int do_unpack_int32(const char *buffer); + INLINE static PN_int64 do_unpack_int64(const char *buffer); + INLINE static unsigned int do_unpack_uint8(const char *buffer); + INLINE static unsigned int do_unpack_uint16(const char *buffer); + INLINE static unsigned int do_unpack_uint32(const char *buffer); + INLINE static PN_uint64 do_unpack_uint64(const char *buffer); + INLINE static double do_unpack_float64(const char *buffer); + protected: string _name; bool _has_fixed_byte_size; @@ -100,4 +129,6 @@ protected: DCPackType _pack_type; }; +#include "dcPackerInterface.I" + #endif diff --git a/direct/src/dcparser/dcSimpleParameter.cxx b/direct/src/dcparser/dcSimpleParameter.cxx index df0b466590..f011e315ce 100644 --- a/direct/src/dcparser/dcSimpleParameter.cxx +++ b/direct/src/dcparser/dcSimpleParameter.cxx @@ -134,25 +134,25 @@ DCSimpleParameter(DCSubatomicType type, int divisor) : break; case ST_uint8: - _pack_type = PT_int; + _pack_type = PT_uint; _has_fixed_byte_size = true; _fixed_byte_size = 1; break; case ST_uint16: - _pack_type = PT_int; + _pack_type = PT_uint; _has_fixed_byte_size = true; _fixed_byte_size = 2; break; case ST_uint32: - _pack_type = PT_int; + _pack_type = PT_uint; _has_fixed_byte_size = true; _fixed_byte_size = 4; break; case ST_uint64: - _pack_type = PT_int64; + _pack_type = PT_uint64; _has_fixed_byte_size = true; _fixed_byte_size = 8; break; @@ -259,7 +259,8 @@ set_divisor(int divisor) { _divisor = divisor; if ((_divisor != 1) && - (_pack_type == PT_int || _pack_type == PT_int64)) { + (_pack_type == PT_int || _pack_type == PT_int64 || + _pack_type == PT_uint || _pack_type == PT_uint64)) { _pack_type = PT_double; } @@ -306,62 +307,50 @@ get_nested_field(int) const { bool DCSimpleParameter:: pack_double(DCPackData &pack_data, double value) const { double real_value = value * _divisor; - int int_value = (int)floor(real_value + 0.5); - - char buffer[8]; switch (_type) { case ST_int8: - case ST_uint8: - buffer[0] = (char)(int_value & 0xff); - pack_data.append_data(buffer, 1); + do_pack_int8(pack_data.get_write_pointer(1), + (int)floor(real_value + 0.5)); break; case ST_int16: - case ST_uint16: - buffer[0] = (char)(int_value & 0xff); - buffer[1] = (char)((int_value >> 8) & 0xff); - pack_data.append_data(buffer, 2); + do_pack_int16(pack_data.get_write_pointer(2), + (int)floor(real_value + 0.5)); break; case ST_int32: - case ST_uint32: - buffer[0] = (char)(int_value & 0xff); - buffer[1] = (char)((int_value >> 8) & 0xff); - buffer[2] = (char)((int_value >> 16) & 0xff); - buffer[3] = (char)((int_value >> 24) & 0xff); - pack_data.append_data(buffer, 4); + do_pack_int32(pack_data.get_write_pointer(4), + (int)floor(real_value + 0.5)); break; case ST_int64: + do_pack_int64(pack_data.get_write_pointer(8), + (PN_int64)floor(real_value + 0.5)); + break; + + case ST_uint8: + do_pack_uint8(pack_data.get_write_pointer(1), + (unsigned int)floor(real_value + 0.5)); + break; + + case ST_uint16: + do_pack_uint16(pack_data.get_write_pointer(2), + (unsigned int)floor(real_value + 0.5)); + break; + + case ST_uint32: + do_pack_uint32(pack_data.get_write_pointer(4), + (unsigned int)floor(real_value + 0.5)); + break; + case ST_uint64: - { - PN_int64 int64_value = (PN_int64)floor(real_value + 0.5); - buffer[0] = (char)(int64_value & 0xff); - buffer[1] = (char)((int64_value >> 8) & 0xff); - buffer[2] = (char)((int64_value >> 16) & 0xff); - buffer[3] = (char)((int64_value >> 24) & 0xff); - buffer[4] = (char)((int64_value >> 32) & 0xff); - buffer[5] = (char)((int64_value >> 40) & 0xff); - buffer[6] = (char)((int64_value >> 48) & 0xff); - buffer[7] = (char)((int64_value >> 56) & 0xff); - pack_data.append_data(buffer, 8); - } + do_pack_uint64(pack_data.get_write_pointer(8), + (PN_uint64)floor(real_value + 0.5)); break; case ST_float64: -#ifdef WORDS_BIGENDIAN - { - // Reverse the byte ordering for big-endian machines. - char *p = (char *)real_value; - for (size_t i = 0; i < 8; i++) { - buffer[i] = p[7 - i]; - } - } -#else - memcpy(buffer, &real_value, 8); -#endif - pack_data.append_data(buffer, 8); + do_pack_float64(pack_data.get_write_pointer(8), real_value); break; default: @@ -381,70 +370,95 @@ bool DCSimpleParameter:: pack_int(DCPackData &pack_data, int value) const { int int_value = value * _divisor; - char buffer[8]; - switch (_type) { case ST_int8: - case ST_uint8: - buffer[0] = (char)(int_value & 0xff); - pack_data.append_data(buffer, 1); + do_pack_int8(pack_data.get_write_pointer(1), int_value); break; case ST_int16: - case ST_uint16: - buffer[0] = (char)(int_value & 0xff); - buffer[1] = (char)((int_value >> 8) & 0xff); - pack_data.append_data(buffer, 2); + do_pack_int16(pack_data.get_write_pointer(2), int_value); break; case ST_int32: - case ST_uint32: - buffer[0] = (char)(int_value & 0xff); - buffer[1] = (char)((int_value >> 8) & 0xff); - buffer[2] = (char)((int_value >> 16) & 0xff); - buffer[3] = (char)((int_value >> 24) & 0xff); - pack_data.append_data(buffer, 4); + do_pack_int32(pack_data.get_write_pointer(4), int_value); break; case ST_int64: - buffer[0] = (char)(int_value & 0xff); - buffer[1] = (char)((int_value >> 8) & 0xff); - buffer[2] = (char)((int_value >> 16) & 0xff); - buffer[3] = (char)((int_value >> 24) & 0xff); - if ((int_value & 0x80000000) != 0) { - buffer[4] = buffer[5] = buffer[6] = buffer[7] = (char)0xff; - } else { - buffer[4] = buffer[5] = buffer[6] = buffer[7] = (char)0; - } - pack_data.append_data(buffer, 8); + do_pack_int64(pack_data.get_write_pointer(8), int_value); + break; + + case ST_uint8: + do_pack_uint8(pack_data.get_write_pointer(1), (unsigned int)int_value); + break; + + case ST_uint16: + do_pack_uint16(pack_data.get_write_pointer(2), (unsigned int)int_value); + break; + + case ST_uint32: + do_pack_uint32(pack_data.get_write_pointer(4), (unsigned int)int_value); break; case ST_uint64: - buffer[0] = (char)(int_value & 0xff); - buffer[1] = (char)((int_value >> 8) & 0xff); - buffer[2] = (char)((int_value >> 16) & 0xff); - buffer[3] = (char)((int_value >> 24) & 0xff); - buffer[4] = buffer[5] = buffer[6] = buffer[7] = (char)0; - pack_data.append_data(buffer, 8); + do_pack_uint64(pack_data.get_write_pointer(8), (unsigned int)int_value); break; case ST_float64: -#ifdef WORDS_BIGENDIAN - { - // Reverse the byte ordering for big-endian machines. - double real_value = int_value; - char *p = (char *)real_value; - for (size_t i = 0; i < 8; i++) { - buffer[i] = p[7 - i]; - } - } -#else - { - double real_value = int_value; - memcpy(buffer, &real_value, 8); - } -#endif - pack_data.append_data(buffer, 8); + do_pack_float64(pack_data.get_write_pointer(8), int_value); + break; + + default: + return false; + } + + return true; +} + +//////////////////////////////////////////////////////////////////// +// Function: DCSimpleParameter::pack_uint +// Access: Published, Virtual +// Description: Packs the indicated numeric or string value into the +// stream. Returns true on success, false on failure. +//////////////////////////////////////////////////////////////////// +bool DCSimpleParameter:: +pack_uint(DCPackData &pack_data, unsigned int value) const { + unsigned int int_value = value * _divisor; + + switch (_type) { + case ST_int8: + do_pack_int8(pack_data.get_write_pointer(1), (int)int_value); + break; + + case ST_int16: + do_pack_int16(pack_data.get_write_pointer(2), (int)int_value); + break; + + case ST_int32: + do_pack_int32(pack_data.get_write_pointer(4), (int)int_value); + break; + + case ST_int64: + do_pack_int64(pack_data.get_write_pointer(8), (int)int_value); + break; + + case ST_uint8: + do_pack_uint8(pack_data.get_write_pointer(1), int_value); + break; + + case ST_uint16: + do_pack_uint16(pack_data.get_write_pointer(2), int_value); + break; + + case ST_uint32: + do_pack_uint32(pack_data.get_write_pointer(4), int_value); + break; + + case ST_uint64: + do_pack_uint64(pack_data.get_write_pointer(8), int_value); + break; + + case ST_float64: + do_pack_float64(pack_data.get_write_pointer(8), (double)int_value); break; default: @@ -464,63 +478,95 @@ bool DCSimpleParameter:: pack_int64(DCPackData &pack_data, PN_int64 value) const { PN_int64 int_value = value * _divisor; - char buffer[8]; - switch (_type) { case ST_int8: - case ST_uint8: - buffer[0] = (char)(int_value & 0xff); - pack_data.append_data(buffer, 1); + do_pack_int8(pack_data.get_write_pointer(1), (int)int_value); break; case ST_int16: - case ST_uint16: - buffer[0] = (char)(int_value & 0xff); - buffer[1] = (char)((int_value >> 8) & 0xff); - pack_data.append_data(buffer, 2); + do_pack_int16(pack_data.get_write_pointer(2), (int)int_value); break; case ST_int32: - case ST_uint32: - buffer[0] = (char)(int_value & 0xff); - buffer[1] = (char)((int_value >> 8) & 0xff); - buffer[2] = (char)((int_value >> 16) & 0xff); - buffer[3] = (char)((int_value >> 24) & 0xff); - pack_data.append_data(buffer, 4); + do_pack_int32(pack_data.get_write_pointer(4), (int)int_value); break; case ST_int64: + do_pack_int64(pack_data.get_write_pointer(8), int_value); + break; + + case ST_uint8: + do_pack_uint8(pack_data.get_write_pointer(1), (unsigned int)(PN_uint64)int_value); + break; + + case ST_uint16: + do_pack_uint16(pack_data.get_write_pointer(2), (unsigned int)(PN_uint64)int_value); + break; + + case ST_uint32: + do_pack_uint32(pack_data.get_write_pointer(4), (unsigned int)(PN_uint64)int_value); + break; + case ST_uint64: - { - buffer[0] = (char)(int_value & 0xff); - buffer[1] = (char)((int_value >> 8) & 0xff); - buffer[2] = (char)((int_value >> 16) & 0xff); - buffer[3] = (char)((int_value >> 24) & 0xff); - buffer[4] = (char)((int_value >> 32) & 0xff); - buffer[5] = (char)((int_value >> 40) & 0xff); - buffer[6] = (char)((int_value >> 48) & 0xff); - buffer[7] = (char)((int_value >> 56) & 0xff); - pack_data.append_data(buffer, 8); - } + do_pack_uint64(pack_data.get_write_pointer(8), (PN_uint64)int_value); break; case ST_float64: -#ifdef WORDS_BIGENDIAN - { - // Reverse the byte ordering for big-endian machines. - double real_value = int_value; - char *p = (char *)real_value; - for (size_t i = 0; i < 8; i++) { - buffer[i] = p[7 - i]; - } - } -#else - { - double real_value = int_value; - memcpy(buffer, &real_value, 8); - } -#endif - pack_data.append_data(buffer, 8); + do_pack_float64(pack_data.get_write_pointer(8), (double)int_value); + break; + + default: + return false; + } + + return true; +} + +//////////////////////////////////////////////////////////////////// +// Function: DCSimpleParameter::pack_uint64 +// Access: Published, Virtual +// Description: Packs the indicated numeric or string value into the +// stream. Returns true on success, false on failure. +//////////////////////////////////////////////////////////////////// +bool DCSimpleParameter:: +pack_uint64(DCPackData &pack_data, PN_uint64 value) const { + PN_uint64 int_value = value * _divisor; + + switch (_type) { + case ST_int8: + do_pack_int8(pack_data.get_write_pointer(1), (int)(PN_int64)int_value); + break; + + case ST_int16: + do_pack_int16(pack_data.get_write_pointer(2), (int)(PN_int64)int_value); + break; + + case ST_int32: + do_pack_int32(pack_data.get_write_pointer(4), (int)(PN_int64)int_value); + break; + + case ST_int64: + do_pack_int64(pack_data.get_write_pointer(8), (PN_int64)int_value); + break; + + case ST_uint8: + do_pack_uint8(pack_data.get_write_pointer(1), (unsigned int)int_value); + break; + + case ST_uint16: + do_pack_uint16(pack_data.get_write_pointer(2), (unsigned int)int_value); + break; + + case ST_uint32: + do_pack_uint32(pack_data.get_write_pointer(4), (unsigned int)int_value); + break; + + case ST_uint64: + do_pack_uint64(pack_data.get_write_pointer(8), int_value); + break; + + case ST_float64: + do_pack_float64(pack_data.get_write_pointer(8), (double)int_value); break; default: @@ -538,30 +584,16 @@ pack_int64(DCPackData &pack_data, PN_int64 value) const { //////////////////////////////////////////////////////////////////// bool DCSimpleParameter:: pack_string(DCPackData &pack_data, const string &value) const { - char buffer[4]; - switch (_type) { case ST_string: case ST_blob: - { - int length = value.length(); - buffer[0] = (char)(length & 0xff); - buffer[1] = (char)((length >> 8) & 0xff); - pack_data.append_data(buffer, 2); - pack_data.append_data(value.data(), length); - } + do_pack_uint16(pack_data.get_write_pointer(2), value.length()); + pack_data.append_data(value.data(), value.length()); break; case ST_blob32: - { - int length = value.length(); - buffer[0] = (char)(length & 0xff); - buffer[1] = (char)((length >> 8) & 0xff); - buffer[2] = (char)((length >> 16) & 0xff); - buffer[3] = (char)((length >> 24) & 0xff); - pack_data.append_data(buffer, 4); - pack_data.append_data(value.data(), length); - } + do_pack_uint32(pack_data.get_write_pointer(4), value.length()); + pack_data.append_data(value.data(), value.length()); break; default: @@ -584,7 +616,7 @@ unpack_double(const char *data, size_t length, size_t &p, double &value) const { if (p + 1 > length) { return false; } - value = (double)(int)(signed char)data[p]; + value = do_unpack_int8(data + p); p++; break; @@ -592,8 +624,7 @@ unpack_double(const char *data, size_t length, size_t &p, double &value) const { if (p + 2 > length) { return false; } - value = (double)(int)((unsigned int)(unsigned char)data[p] | - ((int)(signed char)data[p + 1] << 8)); + value = do_unpack_int16(data + p); p += 2; break; @@ -601,10 +632,7 @@ unpack_double(const char *data, size_t length, size_t &p, double &value) const { if (p + 4 > length) { return false; } - value = (double)(int)((unsigned int)(unsigned char)data[p] | - ((unsigned int)(unsigned char)data[p + 1] << 8) | - ((unsigned int)(unsigned char)data[p + 2] << 16) | - ((int)(signed char)data[p + 3] << 24)); + value = do_unpack_int32(data + p); p += 4; break; @@ -612,14 +640,7 @@ unpack_double(const char *data, size_t length, size_t &p, double &value) const { if (p + 8 > length) { return false; } - value = (double)(PN_int64)((PN_uint64)(unsigned char)data[p] | - ((PN_uint64)(unsigned char)data[p + 1] << 8) | - ((PN_uint64)(unsigned char)data[p + 2] << 16) | - ((PN_uint64)(unsigned char)data[p + 3] << 24) | - ((PN_uint64)(unsigned char)data[p + 4] << 32) | - ((PN_uint64)(unsigned char)data[p + 5] << 40) | - ((PN_uint64)(unsigned char)data[p + 6] << 48) | - ((PN_int64)(signed char)data[p + 7] << 54)); + value = (double)do_unpack_int64(data + p); p += 8; break; @@ -627,7 +648,7 @@ unpack_double(const char *data, size_t length, size_t &p, double &value) const { if (p + 1 > length) { return false; } - value = (double)(unsigned int)(unsigned char)data[p]; + value = do_unpack_uint8(data + p); p++; break; @@ -635,8 +656,7 @@ unpack_double(const char *data, size_t length, size_t &p, double &value) const { if (p + 2 > length) { return false; } - value = (double)(unsigned int)((unsigned int)(unsigned char)data[p] | - ((unsigned int)(unsigned char)data[p + 1] << 8)); + value = do_unpack_uint16(data + p); p += 2; break; @@ -644,10 +664,7 @@ unpack_double(const char *data, size_t length, size_t &p, double &value) const { if (p + 4 > length) { return false; } - value = (double)(unsigned int)((unsigned int)(unsigned char)data[p] | - ((unsigned int)(unsigned char)data[p + 1] << 8) | - ((unsigned int)(unsigned char)data[p + 2] << 16) | - ((unsigned int)(unsigned char)data[p + 3] << 24)); + value = do_unpack_uint32(data + p); p += 4; break; @@ -655,14 +672,7 @@ unpack_double(const char *data, size_t length, size_t &p, double &value) const { if (p + 8 > length) { return false; } - value = (double)(PN_uint64)((PN_uint64)(unsigned char)data[p] | - ((PN_uint64)(unsigned char)data[p + 1] << 8) | - ((PN_uint64)(unsigned char)data[p + 2] << 16) | - ((PN_uint64)(unsigned char)data[p + 3] << 24) | - ((PN_uint64)(unsigned char)data[p + 4] << 32) | - ((PN_uint64)(unsigned char)data[p + 5] << 40) | - ((PN_uint64)(unsigned char)data[p + 6] << 48) | - ((PN_uint64)(unsigned char)data[p + 7] << 54)); + value = (double)do_unpack_uint64(data + p); p += 8; break; @@ -670,21 +680,7 @@ unpack_double(const char *data, size_t length, size_t &p, double &value) const { if (p + 8 > length) { return false; } - { - double *real_value; -#ifdef WORDS_BIGENDIAN - char buffer[8]; - - // Reverse the byte ordering for big-endian machines. - for (size_t i = 0; i < 8; i++) { - buffer[i] = data[p + 7 - i]; - } - real_value = (double *)buffer; -#else - real_value = (double *)(data + p); -#endif // WORDS_BIGENDIAN - value = (*real_value); - } + value = do_unpack_float64(data + p); p += 8; break; @@ -712,7 +708,7 @@ unpack_int(const char *data, size_t length, size_t &p, int &value) const { if (p + 1 > length) { return false; } - value = (int)(signed char)data[p]; + value = do_unpack_int8(data + p); p++; break; @@ -720,8 +716,7 @@ unpack_int(const char *data, size_t length, size_t &p, int &value) const { if (p + 2 > length) { return false; } - value = (int)((unsigned int)(unsigned char)data[p] | - ((int)(signed char)data[p + 1] << 8)); + value = do_unpack_int16(data + p); p += 2; break; @@ -729,10 +724,7 @@ unpack_int(const char *data, size_t length, size_t &p, int &value) const { if (p + 4 > length) { return false; } - value = (int)((unsigned int)(unsigned char)data[p] | - ((unsigned int)(unsigned char)data[p + 1] << 8) | - ((unsigned int)(unsigned char)data[p + 2] << 16) | - ((int)(signed char)data[p + 3] << 24)); + value = do_unpack_int32(data + p); p += 4; break; @@ -740,10 +732,7 @@ unpack_int(const char *data, size_t length, size_t &p, int &value) const { if (p + 8 > length) { return false; } - value = (int)((unsigned int)(unsigned char)data[p] | - ((unsigned int)(unsigned char)data[p + 1] << 8) | - ((unsigned int)(unsigned char)data[p + 2] << 16) | - ((unsigned int)(unsigned char)data[p + 3] << 24)); + value = (int)do_unpack_int64(data + p); p += 8; break; @@ -751,7 +740,7 @@ unpack_int(const char *data, size_t length, size_t &p, int &value) const { if (p + 1 > length) { return false; } - value = (unsigned int)(unsigned char)data[p]; + value = (int)do_unpack_uint8(data + p); p++; break; @@ -759,8 +748,7 @@ unpack_int(const char *data, size_t length, size_t &p, int &value) const { if (p + 2 > length) { return false; } - value = (unsigned int)((unsigned int)(unsigned char)data[p] | - ((unsigned int)(unsigned char)data[p + 1] << 8)); + value = (int)do_unpack_uint16(data + p); p += 2; break; @@ -768,10 +756,7 @@ unpack_int(const char *data, size_t length, size_t &p, int &value) const { if (p + 4 > length) { return false; } - value = (unsigned int)((unsigned int)(unsigned char)data[p] | - ((unsigned int)(unsigned char)data[p + 1] << 8) | - ((unsigned int)(unsigned char)data[p + 2] << 16) | - ((unsigned int)(unsigned char)data[p + 3] << 24)); + value = (int)do_unpack_uint32(data + p); p += 4; break; @@ -779,10 +764,7 @@ unpack_int(const char *data, size_t length, size_t &p, int &value) const { if (p + 8 > length) { return false; } - value = (unsigned int)((unsigned int)(unsigned char)data[p] | - ((unsigned int)(unsigned char)data[p + 1] << 8) | - ((unsigned int)(unsigned char)data[p + 2] << 16) | - ((unsigned int)(unsigned char)data[p + 3] << 24)); + value = (int)(unsigned int)do_unpack_uint64(data + p); p += 8; break; @@ -790,21 +772,99 @@ unpack_int(const char *data, size_t length, size_t &p, int &value) const { if (p + 8 > length) { return false; } - { - double *real_value; -#ifdef WORDS_BIGENDIAN - char buffer[8]; + value = (int)do_unpack_float64(data + p); + p += 8; + break; - // Reverse the byte ordering for big-endian machines. - for (size_t i = 0; i < 8; i++) { - buffer[i] = data[p + 7 - i]; - } - real_value = (double *)buffer; -#else - real_value = (double *)(data + p); -#endif // WORDS_BIGENDIAN - value = (int)(*real_value); + default: + return false; + } + + if (_divisor != 1) { + value = value / _divisor; + } + + return true; +} + +//////////////////////////////////////////////////////////////////// +// Function: DCSimpleParameter::unpack_uint +// Access: Public, Virtual +// Description: Unpacks the current numeric or string value from the +// stream. Returns true on success, false on failure. +//////////////////////////////////////////////////////////////////// +bool DCSimpleParameter:: +unpack_uint(const char *data, size_t length, size_t &p, unsigned int &value) const { + switch (_type) { + case ST_int8: + if (p + 1 > length) { + return false; } + value = (unsigned int)do_unpack_int8(data + p); + p++; + break; + + case ST_int16: + if (p + 2 > length) { + return false; + } + value = (unsigned int)do_unpack_int16(data + p); + p += 2; + break; + + case ST_int32: + if (p + 4 > length) { + return false; + } + value = (unsigned int)do_unpack_int32(data + p); + p += 4; + break; + + case ST_int64: + if (p + 8 > length) { + return false; + } + value = (unsigned int)do_unpack_int64(data + p); + p += 8; + break; + + case ST_uint8: + if (p + 1 > length) { + return false; + } + value = do_unpack_uint8(data + p); + p++; + break; + + case ST_uint16: + if (p + 2 > length) { + return false; + } + value = do_unpack_uint16(data + p); + p += 2; + break; + + case ST_uint32: + if (p + 4 > length) { + return false; + } + value = do_unpack_uint32(data + p); + p += 4; + break; + + case ST_uint64: + if (p + 8 > length) { + return false; + } + value = (unsigned int)do_unpack_uint64(data + p); + p += 8; + break; + + case ST_float64: + if (p + 8 > length) { + return false; + } + value = (unsigned int)do_unpack_float64(data + p); p += 8; break; @@ -832,7 +892,7 @@ unpack_int64(const char *data, size_t length, size_t &p, PN_int64 &value) const if (p + 1 > length) { return false; } - value = (int)(signed char)data[p]; + value = do_unpack_int8(data + p); p++; break; @@ -840,8 +900,7 @@ unpack_int64(const char *data, size_t length, size_t &p, PN_int64 &value) const if (p + 2 > length) { return false; } - value = (int)((unsigned int)(unsigned char)data[p] | - ((int)(signed char)data[p + 1] << 8)); + value = do_unpack_int16(data + p); p += 2; break; @@ -849,10 +908,7 @@ unpack_int64(const char *data, size_t length, size_t &p, PN_int64 &value) const if (p + 4 > length) { return false; } - value = (int)((unsigned int)(unsigned char)data[p] | - ((unsigned int)(unsigned char)data[p + 1] << 8) | - ((unsigned int)(unsigned char)data[p + 2] << 16) | - ((int)(signed char)data[p + 3] << 24)); + value = do_unpack_int32(data + p); p += 4; break; @@ -860,14 +916,7 @@ unpack_int64(const char *data, size_t length, size_t &p, PN_int64 &value) const if (p + 8 > length) { return false; } - value = (PN_int64)((PN_uint64)(unsigned char)data[p] | - ((PN_uint64)(unsigned char)data[p + 1] << 8) | - ((PN_uint64)(unsigned char)data[p + 2] << 16) | - ((PN_uint64)(unsigned char)data[p + 3] << 24) | - ((PN_uint64)(unsigned char)data[p + 4] << 32) | - ((PN_uint64)(unsigned char)data[p + 5] << 40) | - ((PN_uint64)(unsigned char)data[p + 6] << 48) | - ((PN_int64)(signed char)data[p + 7] << 54)); + value = do_unpack_int64(data + p); p += 8; break; @@ -875,7 +924,7 @@ unpack_int64(const char *data, size_t length, size_t &p, PN_int64 &value) const if (p + 1 > length) { return false; } - value = (unsigned int)(unsigned char)data[p]; + value = (int)do_unpack_uint8(data + p); p++; break; @@ -883,8 +932,7 @@ unpack_int64(const char *data, size_t length, size_t &p, PN_int64 &value) const if (p + 2 > length) { return false; } - value = (unsigned int)((unsigned int)(unsigned char)data[p] | - ((unsigned int)(unsigned char)data[p + 1] << 8)); + value = (int)do_unpack_uint16(data + p); p += 2; break; @@ -892,10 +940,7 @@ unpack_int64(const char *data, size_t length, size_t &p, PN_int64 &value) const if (p + 4 > length) { return false; } - value = (unsigned int)((unsigned int)(unsigned char)data[p] | - ((unsigned int)(unsigned char)data[p + 1] << 8) | - ((unsigned int)(unsigned char)data[p + 2] << 16) | - ((unsigned int)(unsigned char)data[p + 3] << 24)); + value = (int)do_unpack_uint32(data + p); p += 4; break; @@ -903,14 +948,7 @@ unpack_int64(const char *data, size_t length, size_t &p, PN_int64 &value) const if (p + 8 > length) { return false; } - value = (PN_int64)((PN_uint64)(unsigned char)data[p] | - ((PN_uint64)(unsigned char)data[p + 1] << 8) | - ((PN_uint64)(unsigned char)data[p + 2] << 16) | - ((PN_uint64)(unsigned char)data[p + 3] << 24) | - ((PN_uint64)(unsigned char)data[p + 4] << 32) | - ((PN_uint64)(unsigned char)data[p + 5] << 40) | - ((PN_uint64)(unsigned char)data[p + 6] << 48) | - ((PN_uint64)(unsigned char)data[p + 7] << 54)); + value = (PN_int64)do_unpack_uint64(data + p); p += 8; break; @@ -918,21 +956,99 @@ unpack_int64(const char *data, size_t length, size_t &p, PN_int64 &value) const if (p + 8 > length) { return false; } - { - double *real_value; -#ifdef WORDS_BIGENDIAN - char buffer[8]; + value = (PN_int64)do_unpack_float64(data + p); + p += 8; + break; - // Reverse the byte ordering for big-endian machines. - for (size_t i = 0; i < 8; i++) { - buffer[i] = data[p + 7 - i]; - } - real_value = (double *)buffer; -#else - real_value = (double *)(data + p); -#endif // WORDS_BIGENDIAN - value = (PN_int64)(*real_value); + default: + return false; + } + + if (_divisor != 1) { + value = value / _divisor; + } + + return true; +} + +//////////////////////////////////////////////////////////////////// +// Function: DCSimpleParameter::unpack_uint64 +// Access: Public, Virtual +// Description: Unpacks the current numeric or string value from the +// stream. Returns true on success, false on failure. +//////////////////////////////////////////////////////////////////// +bool DCSimpleParameter:: +unpack_uint64(const char *data, size_t length, size_t &p, PN_uint64 &value) const { + switch (_type) { + case ST_int8: + if (p + 1 > length) { + return false; } + value = (unsigned int)do_unpack_int8(data + p); + p++; + break; + + case ST_int16: + if (p + 2 > length) { + return false; + } + value = (unsigned int)do_unpack_int16(data + p); + p += 2; + break; + + case ST_int32: + if (p + 4 > length) { + return false; + } + value = (unsigned int)do_unpack_int32(data + p); + p += 4; + break; + + case ST_int64: + if (p + 8 > length) { + return false; + } + value = (PN_uint64)do_unpack_int64(data + p); + p += 8; + break; + + case ST_uint8: + if (p + 1 > length) { + return false; + } + value = do_unpack_uint8(data + p); + p++; + break; + + case ST_uint16: + if (p + 2 > length) { + return false; + } + value = do_unpack_uint16(data + p); + p += 2; + break; + + case ST_uint32: + if (p + 4 > length) { + return false; + } + value = do_unpack_uint32(data + p); + p += 4; + break; + + case ST_uint64: + if (p + 8 > length) { + return false; + } + value = do_unpack_uint64(data + p); + p += 8; + break; + + case ST_float64: + if (p + 8 > length) { + return false; + } + value = (PN_uint64)do_unpack_float64(data + p); p += 8; break; @@ -963,8 +1079,7 @@ unpack_string(const char *data, size_t length, size_t &p, string &value) const { if (p + 2 > length) { return false; } - string_length = (size_t)((unsigned int)(unsigned char)data[p] | - ((unsigned int)(unsigned char)data[p + 1] << 8)); + string_length = do_unpack_uint16(data + p); p += 2; break; @@ -972,10 +1087,7 @@ unpack_string(const char *data, size_t length, size_t &p, string &value) const { if (p + 4 > length) { return false; } - string_length = (size_t)((unsigned int)(unsigned char)data[p] | - ((unsigned int)(unsigned char)data[p + 1] << 8) | - ((unsigned int)(unsigned char)data[p + 2] << 16) | - ((unsigned int)(unsigned char)data[p + 3] << 24)); + string_length = do_unpack_uint32(data + p); p += 4; break; diff --git a/direct/src/dcparser/dcSimpleParameter.h b/direct/src/dcparser/dcSimpleParameter.h index c3835c9be1..e8866aa140 100644 --- a/direct/src/dcparser/dcSimpleParameter.h +++ b/direct/src/dcparser/dcSimpleParameter.h @@ -52,12 +52,16 @@ public: virtual bool pack_double(DCPackData &pack_data, double value) const; virtual bool pack_int(DCPackData &pack_data, int value) const; + virtual bool pack_uint(DCPackData &pack_data, unsigned int value) const; virtual bool pack_int64(DCPackData &pack_data, PN_int64 value) const; + virtual bool pack_uint64(DCPackData &pack_data, PN_uint64 value) const; virtual bool pack_string(DCPackData &pack_data, const string &value) const; virtual bool unpack_double(const char *data, size_t length, size_t &p, double &value) const; virtual bool unpack_int(const char *data, size_t length, size_t &p, int &value) const; + virtual bool unpack_uint(const char *data, size_t length, size_t &p, unsigned int &value) const; virtual bool unpack_int64(const char *data, size_t length, size_t &p, PN_int64 &value) const; + virtual bool unpack_uint64(const char *data, size_t length, size_t &p, PN_uint64 &value) const; virtual bool unpack_string(const char *data, size_t length, size_t &p, string &value) const; virtual void output_instance(ostream &out, const string &prename,