add unsigned pack/unpack, modularize packing methods

This commit is contained in:
David Rose 2004-06-18 18:46:25 +00:00
parent 89cf2c4aca
commit 7e70887ab2
11 changed files with 883 additions and 297 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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