begin ranges

This commit is contained in:
David Rose 2004-06-22 05:28:59 +00:00
parent 38aadc22f5
commit b0b2fe350c
8 changed files with 1016 additions and 309 deletions

View File

@ -25,6 +25,7 @@
dcPackerCatalog.h dcPackerCatalog.I \
dcPackerInterface.h dcPackerInterface.I \
dcParameter.h dcClassParameter.h dcArrayParameter.h dcSimpleParameter.h \
dcNumericRange.h dcNumericRange.I \
dcTypedef.h \
dcbase.h dcindent.h hashGenerator.h \
primeNumberGenerator.h

View File

@ -0,0 +1,222 @@
// Filename: dcNumericRange.I
// Created by: drose (21Jun04)
//
////////////////////////////////////////////////////////////////////
//
// 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: DCNumericRange::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template <class NUM>
INLINE DCNumericRange<NUM>::
DCNumericRange() {
}
////////////////////////////////////////////////////////////////////
// Function: DCNumericRange::Copy Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template <class NUM>
INLINE DCNumericRange<NUM>::
DCNumericRange(const DCNumericRange<NUM> &copy) :
_ranges(copy._ranges)
{
}
////////////////////////////////////////////////////////////////////
// Function: DCNumericRange::Copy Assignment Operator
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template <class NUM>
INLINE void DCNumericRange<NUM>::
operator = (const DCNumericRange<NUM> &copy) {
_ranges = copy._ranges;
}
////////////////////////////////////////////////////////////////////
// Function: DCNumericRange::is_in_range
// Access: Public
// Description: Returns true if the indicated number is within the
// specified range, false otherwise.
////////////////////////////////////////////////////////////////////
template <class NUM>
bool DCNumericRange<NUM>::
is_in_range(Number num) const {
if (_ranges.empty()) {
return true;
}
TYPENAME Ranges::const_iterator ri;
for (ri = _ranges.begin(); ri != _ranges.end(); ++ri) {
if (num >= (*ri)._min && num <= (*ri)._max) {
return true;
}
}
return false;
}
////////////////////////////////////////////////////////////////////
// Function: DCNumericRange::validate
// Access: Public
// Description: Convenience function to validate the indicated
// number. If the number is within the specified range,
// does nothing; otherwise, if it is outside the range,
// sets validation_error to true.
////////////////////////////////////////////////////////////////////
template <class NUM>
INLINE void DCNumericRange<NUM>::
validate(Number num, bool &validation_error) const {
if (!is_in_range(num)) {
validation_error = true;
}
}
////////////////////////////////////////////////////////////////////
// Function: DCNumericRange::output
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template <class NUM>
void DCNumericRange<NUM>::
output(ostream &out, Number divisor) const {
if (!_ranges.empty()) {
TYPENAME Ranges::const_iterator ri;
ri = _ranges.begin();
output_minmax(out, divisor, *ri);
++ri;
while (ri != _ranges.end()) {
out << ", ";
output_minmax(out, divisor, *ri);
++ri;
}
}
}
////////////////////////////////////////////////////////////////////
// Function: DCNumericRange::clear
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template <class NUM>
INLINE void DCNumericRange<NUM>::
clear() {
_ranges.clear();
}
////////////////////////////////////////////////////////////////////
// Function: DCNumericRange::add_range
// Access: Public
// Description: Adds a new minmax to the list of ranges. This is
// normally called only during dc file parsing. Returns
// true if successful, or false if the new minmax
// overlaps an existing minmax.
////////////////////////////////////////////////////////////////////
template <class NUM>
bool DCNumericRange<NUM>::
add_range(Number min, Number max) {
// Check for an overlap. This is probably indicative of a typo and
// should be reported.
if (max < min) {
return false;
}
TYPENAME Ranges::const_iterator ri;
for (ri = _ranges.begin(); ri != _ranges.end(); ++ri) {
if ((min >= (*ri)._min && min <= (*ri)._max) ||
(max >= (*ri)._min && max <= (*ri)._max) ||
(min < (*ri)._min && max > (*ri)._max)) {
return false;
}
}
MinMax minmax;
minmax._min = min;
minmax._max = max;
_ranges.push_back(minmax);
return true;
}
////////////////////////////////////////////////////////////////////
// Function: DCNumericRange::is_empty
// Access: Private
// Description: Returns true if the range contains no elements (and
// thus allows all numbers), false if it contains at
// least one.
////////////////////////////////////////////////////////////////////
template <class NUM>
INLINE bool DCNumericRange<NUM>::
is_empty() const {
return _ranges.empty();
}
////////////////////////////////////////////////////////////////////
// Function: DCNumericRange::get_num_ranges
// Access: Private
// Description: Returns the number of minmax components in the range
// description.
////////////////////////////////////////////////////////////////////
template <class NUM>
INLINE int DCNumericRange<NUM>::
get_num_ranges() const {
return _ranges.size();
}
////////////////////////////////////////////////////////////////////
// Function: DCNumericRange::get_min
// Access: Private
// Description: Returns the minimum value defined by the nth component.
////////////////////////////////////////////////////////////////////
template <class NUM>
INLINE TYPENAME DCNumericRange<NUM>::Number DCNumericRange<NUM>::
get_min(int n) const {
nassertr(n >= 0 && n < (int)_ranges.size(), 0);
return _ranges[n]._min;
}
////////////////////////////////////////////////////////////////////
// Function: DCNumericRange::get_max
// Access: Private
// Description: Returns the maximum value defined by the nth component.
////////////////////////////////////////////////////////////////////
template <class NUM>
INLINE TYPENAME DCNumericRange<NUM>::Number DCNumericRange<NUM>::
get_max(int n) const {
nassertr(n >= 0 && n < (int)_ranges.size(), 0);
return _ranges[n]._max;
}
////////////////////////////////////////////////////////////////////
// Function: DCNumericRange::output_minmax
// Access: Private
// Description: Outputs a single element of the range description.
////////////////////////////////////////////////////////////////////
template <class NUM>
INLINE void DCNumericRange<NUM>::
output_minmax(ostream &out, Number divisor, const MinMax &range) const {
if (range._min == range._max) {
out << (double)range._min / (double)divisor;
} else {
out << (double)range._min / (double)divisor
<< "-"
<< (double)range._max / (double)divisor;
}
}

View File

@ -0,0 +1,75 @@
// Filename: dcNumericRange.h
// Created by: drose (21Jun04)
//
////////////////////////////////////////////////////////////////////
//
// 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 .
//
////////////////////////////////////////////////////////////////////
#ifndef DCNUMERICRANGE_H
#define DCNUMERICRANGE_H
#include "dcbase.h"
////////////////////////////////////////////////////////////////////
// Class : DCNumericRange
// Description : Represents a range of legal integer or floating-point
// values. This is used to constrain simple numeric
// types, as well as array sizes.
////////////////////////////////////////////////////////////////////
template <class NUM>
class DCNumericRange {
public:
typedef NUM Number;
INLINE DCNumericRange();
INLINE DCNumericRange(const DCNumericRange &copy);
INLINE void operator = (const DCNumericRange &copy);
bool is_in_range(Number num) const;
INLINE void validate(Number num, bool &validation_error) const;
void output(ostream &out, Number divisor = 1) const;
public:
INLINE void clear();
bool add_range(Number min, Number max);
INLINE bool is_empty() const;
INLINE int get_num_ranges() const;
INLINE Number get_min(int n) const;
INLINE Number get_max(int n) const;
private:
class MinMax {
public:
INLINE bool operator < (const MinMax &other) const;
Number _min;
Number _max;
};
INLINE void output_minmax(ostream &out, Number divisor, const MinMax &range) const;
typedef pvector<MinMax> Ranges;
Ranges _ranges;
};
#include "dcNumericRange.I"
typedef DCNumericRange<int> DCIntRange;
typedef DCNumericRange<unsigned int> DCUnsignedIntRange;
typedef DCNumericRange<PN_int64> DCInt64Range;
typedef DCNumericRange<PN_uint64> DCUnsignedInt64Range;
typedef DCNumericRange<double> DCDoubleRange;
#endif

File diff suppressed because it is too large Load Diff

View File

@ -15,6 +15,7 @@
#include "dcSimpleParameter.h"
#include "dcTypedef.h"
#include "dcPacker.h"
#include "dcNumericRange.h"
// Because our token type contains objects of type string, which
// require correct copy construction (and not simply memcpying), we
@ -32,6 +33,7 @@ static DCAtomicField::ElementType atomic_element(new DCSimpleParameter(ST_invali
static DCParameter *current_parameter = (DCParameter *)NULL;
static DCPacker default_packer;
static DCPacker *current_packer;
static DCDoubleRange double_range;
////////////////////////////////////////////////////////////////////
// Defining the interface to the parser.
@ -117,6 +119,7 @@ dc_cleanup_parser() {
%type <u.parameter> parameter_definition
%type <str> import_identifier
%type <str> slash_identifier
%type <u.real> number
%%
@ -364,6 +367,12 @@ type_name:
type_token
{
$$ = new DCSimpleParameter($1);
}
| type_token '(' double_range ')'
{
DCSimpleParameter *simple_param = new DCSimpleParameter($1);
simple_param->set_range(double_range);
$$ = simple_param;
}
| type_token '/' INTEGER
{
@ -375,6 +384,30 @@ type_name:
yyerror("A divisor is only valid on a numeric type.");
}
$$ = simple_param;
}
| type_token '/' INTEGER '(' double_range ')'
{
DCSimpleParameter *simple_param = new DCSimpleParameter($1);
if ($3 == 0) {
yyerror("Invalid divisor.");
} else if (!simple_param->set_divisor($3)) {
yyerror("A divisor is only valid on a numeric type.");
}
simple_param->set_range(double_range);
$$ = simple_param;
}
| type_token '(' double_range ')' '/' INTEGER
{
DCSimpleParameter *simple_param = new DCSimpleParameter($1);
if ($6 == 0) {
yyerror("Invalid divisor.");
} else if (!simple_param->set_divisor($6)) {
yyerror("A divisor is only valid on a numeric type.");
}
simple_param->set_range(double_range);
$$ = simple_param;
}
| IDENTIFIER
{
@ -397,6 +430,58 @@ type_name:
}
;
double_range:
empty
{
double_range.clear();
}
| number
{
double_range.clear();
if (!double_range.add_range($1, $1)) {
yyerror("Overlapping range");
}
}
| number '-' number
{
double_range.clear();
if (!double_range.add_range($1, $3)) {
yyerror("Overlapping range");
}
}
| number number
{
double_range.clear();
if ($2 >= 0) {
yyerror("Syntax error");
}
if (!double_range.add_range($1, -$2)) {
yyerror("Overlapping range");
}
}
| double_range ',' number
{
if (!double_range.add_range($3, $3)) {
yyerror("Overlapping range");
}
}
| double_range ',' number '-' number
{
if (!double_range.add_range($3, $5)) {
yyerror("Overlapping range");
}
}
| double_range ',' number number
{
if ($4 >= 0) {
yyerror("Syntax error");
}
if (!double_range.add_range($3, -$4)) {
yyerror("Overlapping range");
}
}
;
type_definition:
type_name
| type_definition '[' ']'
@ -439,6 +524,14 @@ parameter_definition:
}
;
number:
INTEGER
{
$$ = (double)$1;
}
| REAL
;
parameter_value:
INTEGER
{

View File

@ -194,7 +194,12 @@ DCSimpleParameter(const DCSimpleParameter &copy) :
_type(copy._type),
_divisor(copy._divisor),
_nested_field(copy._nested_field),
_bytes_per_element(copy._bytes_per_element)
_bytes_per_element(copy._bytes_per_element),
_int_range(copy._int_range),
_uint_range(copy._uint_range),
_int64_range(copy._int64_range),
_uint64_range(copy._uint64_range),
_double_range(copy._double_range)
{
}
@ -279,6 +284,74 @@ set_divisor(int divisor) {
return true;
}
////////////////////////////////////////////////////////////////////
// Function: DCSimpleParameter::set_range
// Access: Public
// Description: Sets the parameter with the indicated range. A
// DCDoubleRange is used for specification, since this
// is the most generic type; but it is converted to the
// appropriate type internally.
////////////////////////////////////////////////////////////////////
void DCSimpleParameter::
set_range(const DCDoubleRange &range) {
int num_ranges = range.get_num_ranges();
int i;
switch (_type) {
case ST_int8:
case ST_int16:
case ST_int32:
_int_range.clear();
for (i = 0; i < num_ranges; i++) {
int min = (int)floor(range.get_min(i) * _divisor + 0.5);
int max = (int)floor(range.get_max(i) * _divisor + 0.5);
_int_range.add_range(min, max);
}
break;
case ST_int64:
_int64_range.clear();
for (i = 0; i < num_ranges; i++) {
PN_int64 min = (PN_int64)floor(range.get_min(i) * _divisor + 0.5);
PN_int64 max = (PN_int64)floor(range.get_max(i) * _divisor + 0.5);
_int64_range.add_range(min, max);
}
break;
case ST_uint8:
case ST_uint16:
case ST_uint32:
_uint_range.clear();
for (i = 0; i < num_ranges; i++) {
unsigned int min = (unsigned int)floor(range.get_min(i) * _divisor + 0.5);
unsigned int max = (unsigned int)floor(range.get_max(i) * _divisor + 0.5);
_uint_range.add_range(min, max);
}
break;
case ST_uint64:
_uint64_range.clear();
for (i = 0; i < num_ranges; i++) {
PN_uint64 min = (PN_uint64)floor(range.get_min(i) * _divisor + 0.5);
PN_uint64 max = (PN_uint64)floor(range.get_max(i) * _divisor + 0.5);
_uint64_range.add_range(min, max);
}
break;
case ST_float64:
_double_range.clear();
for (i = 0; i < num_ranges; i++) {
double min = range.get_min(i) * _divisor;
double max = range.get_max(i) * _divisor;
_double_range.add_range(min, max);
}
break;
default:
break;
}
}
////////////////////////////////////////////////////////////////////
// Function: DCSimpleParameter::calc_num_nested_fields
// Access: Public, Virtual
@ -323,46 +396,71 @@ pack_double(DCPackData &pack_data, double value) const {
switch (_type) {
case ST_int8:
do_pack_int8(pack_data.get_write_pointer(1),
(int)floor(real_value + 0.5), pack_error);
{
int int_value = (int)floor(real_value + 0.5);
_int_range.validate(int_value, pack_error);
do_pack_int8(pack_data.get_write_pointer(1), int_value, pack_error);
}
break;
case ST_int16:
do_pack_int16(pack_data.get_write_pointer(2),
(int)floor(real_value + 0.5), pack_error);
{
int int_value = (int)floor(real_value + 0.5);
_int_range.validate(int_value, pack_error);
do_pack_int16(pack_data.get_write_pointer(2), int_value, pack_error);
}
break;
case ST_int32:
do_pack_int32(pack_data.get_write_pointer(4),
(int)floor(real_value + 0.5), pack_error);
{
int int_value = (int)floor(real_value + 0.5);
_int_range.validate(int_value, pack_error);
do_pack_int32(pack_data.get_write_pointer(4), int_value, pack_error);
}
break;
case ST_int64:
do_pack_int64(pack_data.get_write_pointer(8),
(PN_int64)floor(real_value + 0.5), pack_error);
{
PN_int64 int64_value = (PN_int64)floor(real_value + 0.5);
_int64_range.validate(int64_value, pack_error);
do_pack_int64(pack_data.get_write_pointer(8), int64_value, pack_error);
}
break;
case ST_uint8:
do_pack_uint8(pack_data.get_write_pointer(1),
(unsigned int)floor(real_value + 0.5), pack_error);
{
unsigned int int_value = (unsigned int)floor(real_value + 0.5);
_uint_range.validate(int_value, pack_error);
do_pack_uint8(pack_data.get_write_pointer(1), int_value, pack_error);
}
break;
case ST_uint16:
do_pack_uint16(pack_data.get_write_pointer(2),
(unsigned int)floor(real_value + 0.5), pack_error);
{
unsigned int int_value = (unsigned int)floor(real_value + 0.5);
_uint_range.validate(int_value, pack_error);
do_pack_uint16(pack_data.get_write_pointer(2), int_value, pack_error);
}
break;
case ST_uint32:
do_pack_uint32(pack_data.get_write_pointer(4),
(unsigned int)floor(real_value + 0.5), pack_error);
{
unsigned int int_value = (unsigned int)floor(real_value + 0.5);
_uint_range.validate(int_value, pack_error);
do_pack_uint32(pack_data.get_write_pointer(4), int_value, pack_error);
}
break;
case ST_uint64:
do_pack_uint64(pack_data.get_write_pointer(8),
(PN_uint64)floor(real_value + 0.5), pack_error);
{
PN_uint64 int64_value = (PN_uint64)floor(real_value + 0.5);
_uint64_range.validate(int64_value, pack_error);
do_pack_uint64(pack_data.get_write_pointer(8), int64_value, pack_error);
}
break;
case ST_float64:
_double_range.validate(real_value, pack_error);
do_pack_float64(pack_data.get_write_pointer(8), real_value, pack_error);
break;
@ -386,38 +484,47 @@ pack_int(DCPackData &pack_data, int value) const {
switch (_type) {
case ST_int8:
_int_range.validate(int_value, pack_error);
do_pack_int8(pack_data.get_write_pointer(1), int_value, pack_error);
break;
case ST_int16:
_int_range.validate(int_value, pack_error);
do_pack_int16(pack_data.get_write_pointer(2), int_value, pack_error);
break;
case ST_int32:
_int_range.validate(int_value, pack_error);
do_pack_int32(pack_data.get_write_pointer(4), int_value, pack_error);
break;
case ST_int64:
_int64_range.validate(int_value, pack_error);
do_pack_int64(pack_data.get_write_pointer(8), int_value, pack_error);
break;
case ST_uint8:
_uint_range.validate((unsigned int)int_value, pack_error);
do_pack_uint8(pack_data.get_write_pointer(1), (unsigned int)int_value, pack_error);
break;
case ST_uint16:
_uint_range.validate((unsigned int)int_value, pack_error);
do_pack_uint16(pack_data.get_write_pointer(2), (unsigned int)int_value, pack_error);
break;
case ST_uint32:
_uint_range.validate((unsigned int)int_value, pack_error);
do_pack_uint32(pack_data.get_write_pointer(4), (unsigned int)int_value, pack_error);
break;
case ST_uint64:
_uint64_range.validate((unsigned int)int_value, pack_error);
do_pack_uint64(pack_data.get_write_pointer(8), (unsigned int)int_value, pack_error);
break;
case ST_float64:
_double_range.validate(int_value, pack_error);
do_pack_float64(pack_data.get_write_pointer(8), int_value, pack_error);
break;
@ -441,39 +548,48 @@ pack_uint(DCPackData &pack_data, unsigned int value) const {
switch (_type) {
case ST_int8:
_int_range.validate((int)int_value, pack_error);
do_pack_int8(pack_data.get_write_pointer(1), (int)int_value, pack_error);
break;
case ST_int16:
_int_range.validate((int)int_value, pack_error);
do_pack_int16(pack_data.get_write_pointer(2), (int)int_value, pack_error);
break;
case ST_int32:
_int_range.validate((int)int_value, pack_error);
do_pack_int32(pack_data.get_write_pointer(4), (int)int_value, pack_error);
break;
case ST_int64:
_int64_range.validate((int)int_value, pack_error);
do_pack_int64(pack_data.get_write_pointer(8), (int)int_value, pack_error);
break;
case ST_uint8:
_uint_range.validate(int_value, pack_error);
do_pack_uint8(pack_data.get_write_pointer(1), int_value, pack_error);
break;
case ST_uint16:
_uint_range.validate(int_value, pack_error);
do_pack_uint16(pack_data.get_write_pointer(2), int_value, pack_error);
break;
case ST_uint32:
_uint_range.validate(int_value, pack_error);
do_pack_uint32(pack_data.get_write_pointer(4), int_value, pack_error);
break;
case ST_uint64:
_uint64_range.validate(int_value, pack_error);
do_pack_uint64(pack_data.get_write_pointer(8), int_value, pack_error);
break;
case ST_float64:
do_pack_float64(pack_data.get_write_pointer(8), (double)int_value, pack_error);
_double_range.validate(int_value, pack_error);
do_pack_float64(pack_data.get_write_pointer(8), int_value, pack_error);
break;
default:
@ -496,38 +612,47 @@ pack_int64(DCPackData &pack_data, PN_int64 value) const {
switch (_type) {
case ST_int8:
_int_range.validate((int)int_value, pack_error);
do_pack_int8(pack_data.get_write_pointer(1), (int)int_value, pack_error);
break;
case ST_int16:
_int_range.validate((int)int_value, pack_error);
do_pack_int16(pack_data.get_write_pointer(2), (int)int_value, pack_error);
break;
case ST_int32:
_int_range.validate((int)int_value, pack_error);
do_pack_int32(pack_data.get_write_pointer(4), (int)int_value, pack_error);
break;
case ST_int64:
_int64_range.validate(int_value, pack_error);
do_pack_int64(pack_data.get_write_pointer(8), int_value, pack_error);
break;
case ST_uint8:
_uint_range.validate((unsigned int)(PN_uint64)int_value, pack_error);
do_pack_uint8(pack_data.get_write_pointer(1), (unsigned int)(PN_uint64)int_value, pack_error);
break;
case ST_uint16:
_uint_range.validate((unsigned int)(PN_uint64)int_value, pack_error);
do_pack_uint16(pack_data.get_write_pointer(2), (unsigned int)(PN_uint64)int_value, pack_error);
break;
case ST_uint32:
_uint_range.validate((unsigned int)(PN_uint64)int_value, pack_error);
do_pack_uint32(pack_data.get_write_pointer(4), (unsigned int)(PN_uint64)int_value, pack_error);
break;
case ST_uint64:
_uint64_range.validate((PN_uint64)int_value, pack_error);
do_pack_uint64(pack_data.get_write_pointer(8), (PN_uint64)int_value, pack_error);
break;
case ST_float64:
_double_range.validate((double)int_value, pack_error);
do_pack_float64(pack_data.get_write_pointer(8), (double)int_value, pack_error);
break;
@ -551,38 +676,47 @@ pack_uint64(DCPackData &pack_data, PN_uint64 value) const {
switch (_type) {
case ST_int8:
_int_range.validate((int)(PN_int64)int_value, pack_error);
do_pack_int8(pack_data.get_write_pointer(1), (int)(PN_int64)int_value, pack_error);
break;
case ST_int16:
_int_range.validate((int)(PN_int64)int_value, pack_error);
do_pack_int16(pack_data.get_write_pointer(2), (int)(PN_int64)int_value, pack_error);
break;
case ST_int32:
_int_range.validate((int)(PN_int64)int_value, pack_error);
do_pack_int32(pack_data.get_write_pointer(4), (int)(PN_int64)int_value, pack_error);
break;
case ST_int64:
_int64_range.validate((PN_int64)int_value, pack_error);
do_pack_int64(pack_data.get_write_pointer(8), (PN_int64)int_value, pack_error);
break;
case ST_uint8:
_uint_range.validate((unsigned int)int_value, pack_error);
do_pack_uint8(pack_data.get_write_pointer(1), (unsigned int)int_value, pack_error);
break;
case ST_uint16:
_uint_range.validate((unsigned int)int_value, pack_error);
do_pack_uint16(pack_data.get_write_pointer(2), (unsigned int)int_value, pack_error);
break;
case ST_uint32:
_uint_range.validate((unsigned int)int_value, pack_error);
do_pack_uint32(pack_data.get_write_pointer(4), (unsigned int)int_value, pack_error);
break;
case ST_uint64:
_uint64_range.validate(int_value, pack_error);
do_pack_uint64(pack_data.get_write_pointer(8), int_value, pack_error);
break;
case ST_float64:
_double_range.validate((double)int_value, pack_error);
do_pack_float64(pack_data.get_write_pointer(8), (double)int_value, pack_error);
break;
@ -602,19 +736,21 @@ pack_uint64(DCPackData &pack_data, PN_uint64 value) const {
bool DCSimpleParameter::
pack_string(DCPackData &pack_data, const string &value) const {
bool pack_error = false;
size_t string_length = value.length();
_uint_range.validate(string_length, pack_error);
switch (_type) {
case ST_string:
case ST_blob:
do_pack_uint16(pack_data.get_write_pointer(2), value.length(),
do_pack_uint16(pack_data.get_write_pointer(2), string_length,
pack_error);
pack_data.append_data(value.data(), value.length());
pack_data.append_data(value.data(), string_length);
break;
case ST_blob32:
do_pack_uint32(pack_data.get_write_pointer(4), value.length(),
do_pack_uint32(pack_data.get_write_pointer(4), string_length,
pack_error);
pack_data.append_data(value.data(), value.length());
pack_data.append_data(value.data(), string_length);
break;
default:
@ -1197,11 +1333,62 @@ output_instance(ostream &out, const string &prename, const string &name,
const string &postname) const {
if (get_typedef() != (DCTypedef *)NULL) {
out << get_typedef()->get_name();
} else {
out << _type;
}
if (_divisor != 1) {
out << "/" << _divisor;
if (_divisor != 1) {
out << "/" << _divisor;
}
switch (_type) {
case ST_int8:
case ST_int16:
case ST_int32:
if (!_int_range.is_empty()) {
out << "(";
_int_range.output(out, _divisor);
out << ")";
}
break;
case ST_int64:
if (!_int64_range.is_empty()) {
out << "(";
_int64_range.output(out, _divisor);
out << ")";
}
break;
case ST_uint8:
case ST_uint16:
case ST_uint32:
if (!_uint_range.is_empty()) {
out << "(";
_uint_range.output(out, _divisor);
out << ")";
}
break;
case ST_uint64:
if (!_uint64_range.is_empty()) {
out << "(";
_uint64_range.output(out, _divisor);
out << ")";
}
break;
case ST_float64:
if (!_double_range.is_empty()) {
out << "(";
_double_range.output(out, _divisor);
out << ")";
}
break;
default:
break;
}
}
if (!prename.empty() || !name.empty() || !postname.empty()) {

View File

@ -22,6 +22,7 @@
#include "dcbase.h"
#include "dcParameter.h"
#include "dcSubatomicType.h"
#include "dcNumericRange.h"
////////////////////////////////////////////////////////////////////
// Class : DCSimpleParameter
@ -47,6 +48,7 @@ PUBLISHED:
public:
bool set_divisor(int divisor);
void set_range(const DCDoubleRange &range);
virtual int calc_num_nested_fields(size_t length_bytes) const;
virtual DCPackerInterface *get_nested_field(int n) const;
@ -98,6 +100,12 @@ private:
DCSimpleParameter *_uint8_type;
};
DCIntRange _int_range;
DCUnsignedIntRange _uint_range;
DCInt64Range _int64_range;
DCUnsignedInt64Range _uint64_range;
DCDoubleRange _double_range;
static Uint32Uint8Type *_uint32uint8_type;
};

View File

@ -67,6 +67,7 @@
using namespace std;
#define INLINE inline
#define TYPENAME typename
// These symbols are used within the Panda environment for exporting
// classes and functions to the scripting language. They're largely