15 #include "dcSimpleParameter.h" 16 #include "dcPackData.h" 17 #include "dcTypedef.h" 18 #include "dcArrayParameter.h" 19 #include "dcClassParameter.h" 21 #include "hashGenerator.h" 24 DCSimpleParameter::NestedFieldMap DCSimpleParameter::_nested_field_map;
33 DCSimpleParameter(DCSubatomicType type,
unsigned int divisor) :
38 _pack_type = PT_invalid;
39 _nested_type = ST_invalid;
40 _has_nested_fields =
false;
41 _bytes_per_element = 0;
42 _num_length_bytes = 2;
49 _pack_type = PT_array;
50 _nested_type = ST_int8;
51 _has_nested_fields =
true;
52 _bytes_per_element = 1;
56 _pack_type = PT_array;
57 _nested_type = ST_int16;
58 _has_nested_fields =
true;
59 _bytes_per_element = 2;
63 _pack_type = PT_array;
64 _nested_type = ST_int32;
65 _has_nested_fields =
true;
66 _bytes_per_element = 4;
70 _pack_type = PT_array;
71 _nested_type = ST_uint8;
72 _has_nested_fields =
true;
73 _bytes_per_element = 1;
77 _pack_type = PT_array;
78 _nested_type = ST_uint16;
79 _has_nested_fields =
true;
80 _bytes_per_element = 2;
84 _pack_type = PT_array;
85 _nested_type = ST_uint32;
86 _has_nested_fields =
true;
87 _bytes_per_element = 4;
90 case ST_uint32uint8array:
91 _pack_type = PT_array;
92 _has_nested_fields =
true;
93 _bytes_per_element = 5;
97 _num_length_bytes = 4;
103 _pack_type = PT_blob;
104 _nested_type = ST_uint8;
105 _has_nested_fields =
true;
106 _bytes_per_element = 1;
110 _pack_type = PT_string;
111 _nested_type = ST_char;
112 _has_nested_fields =
true;
113 _bytes_per_element = 1;
119 _has_fixed_byte_size =
true;
120 _fixed_byte_size = 1;
125 _has_fixed_byte_size =
true;
126 _fixed_byte_size = 2;
131 _has_fixed_byte_size =
true;
132 _fixed_byte_size = 4;
136 _pack_type = PT_int64;
137 _has_fixed_byte_size =
true;
138 _fixed_byte_size = 8;
142 _pack_type = PT_string;
143 _has_fixed_byte_size =
true;
144 _fixed_byte_size = 1;
148 _pack_type = PT_uint;
149 _has_fixed_byte_size =
true;
150 _fixed_byte_size = 1;
154 _pack_type = PT_uint;
155 _has_fixed_byte_size =
true;
156 _fixed_byte_size = 2;
160 _pack_type = PT_uint;
161 _has_fixed_byte_size =
true;
162 _fixed_byte_size = 4;
166 _pack_type = PT_uint64;
167 _has_fixed_byte_size =
true;
168 _fixed_byte_size = 8;
172 _pack_type = PT_double;
173 _has_fixed_byte_size =
true;
174 _fixed_byte_size = 8;
180 _has_fixed_structure = _has_fixed_byte_size;
184 if (_nested_type != ST_invalid) {
185 _nested_field = create_nested_field(_nested_type, _divisor);
187 }
else if (_type == ST_uint32uint8array) {
191 _nested_field = create_uint32uint8_type();
194 _nested_field = NULL;
207 _divisor(copy._divisor),
208 _nested_field(copy._nested_field),
209 _bytes_per_element(copy._bytes_per_element),
210 _orig_range(copy._orig_range),
211 _has_modulus(copy._has_modulus),
212 _orig_modulus(copy._orig_modulus),
213 _int_range(copy._int_range),
214 _uint_range(copy._uint_range),
215 _int64_range(copy._int64_range),
216 _uint64_range(copy._uint64_range),
217 _double_range(copy._double_range),
218 _uint_modulus(copy._uint_modulus),
219 _uint64_modulus(copy._uint64_modulus),
220 _double_modulus(copy._double_modulus)
230 as_simple_parameter() {
240 as_simple_parameter()
const {
263 return _type != ST_invalid;
301 return _orig_modulus;
328 return !(_pack_type == PT_string || _pack_type == PT_blob);
343 if (_pack_type == PT_string || _pack_type == PT_blob || modulus <= 0.0) {
348 _orig_modulus = modulus;
350 bool range_error =
false;
351 _double_modulus = modulus * _divisor;
352 _uint64_modulus = (PN_uint64)floor(_double_modulus + 0.5);
353 _uint_modulus = (
unsigned int)_uint64_modulus;
413 if (_pack_type == PT_string || _pack_type == PT_blob || divisor == 0) {
418 if ((_divisor != 1) &&
419 (_pack_type == PT_int || _pack_type == PT_int64 ||
420 _pack_type == PT_uint || _pack_type == PT_uint64)) {
421 _pack_type = PT_double;
424 if (_has_range_limits) {
446 bool range_error =
false;
450 _has_range_limits = (num_ranges != 0);
457 for (i = 0; i < num_ranges; i++) {
458 PN_int64 min = (PN_int64)floor(range.
get_min(i) * _divisor + 0.5);
459 PN_int64 max = (PN_int64)floor(range.
get_max(i) * _divisor + 0.5);
462 _int_range.
add_range((
int)min, (
int)max);
469 for (i = 0; i < num_ranges; i++) {
470 PN_int64 min = (PN_int64)floor(range.
get_min(i) * _divisor + 0.5);
471 PN_int64 max = (PN_int64)floor(range.
get_max(i) * _divisor + 0.5);
474 _int_range.
add_range((
int)min, (
int)max);
481 for (i = 0; i < num_ranges; i++) {
482 PN_int64 min = (PN_int64)floor(range.
get_min(i) * _divisor + 0.5);
483 PN_int64 max = (PN_int64)floor(range.
get_max(i) * _divisor + 0.5);
486 _int_range.
add_range((
int)min, (
int)max);
491 _int64_range.clear();
492 for (i = 0; i < num_ranges; i++) {
493 PN_int64 min = (PN_int64)floor(range.
get_min(i) * _divisor + 0.5);
494 PN_int64 max = (PN_int64)floor(range.
get_max(i) * _divisor + 0.5);
503 for (i = 0; i < num_ranges; i++) {
504 PN_uint64 min = (PN_uint64)floor(range.
get_min(i) * _divisor + 0.5);
505 PN_uint64 max = (PN_uint64)floor(range.
get_max(i) * _divisor + 0.5);
508 _uint_range.
add_range((
unsigned int)min, (
unsigned int)max);
515 for (i = 0; i < num_ranges; i++) {
516 PN_uint64 min = (PN_uint64)floor(range.
get_min(i) * _divisor + 0.5);
517 PN_uint64 max = (PN_uint64)floor(range.
get_max(i) * _divisor + 0.5);
520 _uint_range.
add_range((
unsigned int)min, (
unsigned int)max);
527 for (i = 0; i < num_ranges; i++) {
528 PN_uint64 min = (PN_uint64)floor(range.
get_min(i) * _divisor + 0.5);
529 PN_uint64 max = (PN_uint64)floor(range.
get_max(i) * _divisor + 0.5);
532 _uint_range.
add_range((
unsigned int)min, (
unsigned int)max);
537 _uint64_range.clear();
538 for (i = 0; i < num_ranges; i++) {
539 PN_uint64 min = (PN_uint64)floor(range.
get_min(i) * _divisor + 0.5);
540 PN_uint64 max = (PN_uint64)floor(range.
get_max(i) * _divisor + 0.5);
546 _double_range.clear();
547 for (i = 0; i < num_ranges; i++) {
548 double min = range.
get_min(i) * _divisor;
549 double max = range.
get_max(i) * _divisor;
557 for (i = 0; i < num_ranges; i++) {
558 PN_uint64 min = (PN_uint64)floor(range.
get_min(i) * _divisor + 0.5);
559 PN_uint64 max = (PN_uint64)floor(range.
get_max(i) * _divisor + 0.5);
562 _uint_range.
add_range((
unsigned int)min, (
unsigned int)max);
567 _num_length_bytes = 0;
568 _has_fixed_byte_size =
true;
570 _has_fixed_structure =
true;
572 _num_length_bytes = 2;
573 _has_fixed_byte_size =
false;
574 _has_fixed_structure =
false;
580 for (i = 0; i < num_ranges; i++) {
581 PN_uint64 min = (PN_uint64)floor(range.
get_min(i) * _divisor + 0.5);
582 PN_uint64 max = (PN_uint64)floor(range.
get_max(i) * _divisor + 0.5);
585 _uint_range.
add_range((
unsigned int)min, (
unsigned int)max);
590 _num_length_bytes = 0;
591 _has_fixed_byte_size =
true;
593 _has_fixed_structure =
true;
595 _num_length_bytes = 4;
596 _has_fixed_byte_size =
false;
597 _has_fixed_structure =
false;
620 if (_bytes_per_element != 0) {
621 return length_bytes / _bytes_per_element;
636 return _nested_field;
647 bool &pack_error,
bool &range_error)
const {
648 double real_value = value * _divisor;
650 if (real_value < 0.0) {
651 real_value = _double_modulus - fmod(-real_value, _double_modulus);
652 if (real_value == _double_modulus) {
656 real_value = fmod(real_value, _double_modulus);
663 int int_value = (int)floor(real_value + 0.5);
664 _int_range.
validate(int_value, range_error);
672 int int_value = (int)floor(real_value + 0.5);
673 _int_range.
validate(int_value, range_error);
681 int int_value = (int)floor(real_value + 0.5);
682 _int_range.
validate(int_value, range_error);
689 PN_int64 int64_value = (PN_int64)floor(real_value + 0.5);
690 _int64_range.
validate(int64_value, range_error);
698 unsigned int int_value = (
unsigned int)floor(real_value + 0.5);
699 _uint_range.
validate(int_value, range_error);
707 unsigned int int_value = (
unsigned int)floor(real_value + 0.5);
708 _uint_range.
validate(int_value, range_error);
716 unsigned int int_value = (
unsigned int)floor(real_value + 0.5);
717 _uint_range.
validate(int_value, range_error);
724 PN_uint64 int64_value = (PN_uint64)floor(real_value + 0.5);
725 _uint64_range.
validate(int64_value, range_error);
731 _double_range.
validate(real_value, range_error);
748 bool &pack_error,
bool &range_error)
const {
749 int int_value = value * _divisor;
751 if (value != 0 && (int_value / value) != (
int)_divisor) {
754 pack_int64(pack_data, (PN_int64)value, pack_error, range_error);
758 if (_has_modulus && _uint_modulus != 0) {
760 int_value = _uint_modulus - 1 - (-int_value - 1) % _uint_modulus;
762 int_value = int_value % _uint_modulus;
768 _int_range.
validate(int_value, range_error);
774 _int_range.
validate(int_value, range_error);
780 _int_range.
validate(int_value, range_error);
785 _int64_range.
validate(int_value, range_error);
794 _uint_range.
validate((
unsigned int)int_value, range_error);
803 _uint_range.
validate((
unsigned int)int_value, range_error);
812 _uint_range.
validate((
unsigned int)int_value, range_error);
820 _uint64_range.
validate((
unsigned int)int_value, range_error);
825 _double_range.
validate(int_value, range_error);
842 bool &pack_error,
bool &range_error)
const {
843 unsigned int int_value = value * _divisor;
844 if (_has_modulus && _uint_modulus != 0) {
845 int_value = int_value % _uint_modulus;
850 if ((
int)int_value < 0) {
853 _int_range.
validate((
int)int_value, range_error);
859 if ((
int)int_value < 0) {
862 _int_range.
validate((
int)int_value, range_error);
868 if ((
int)int_value < 0) {
871 _int_range.
validate((
int)int_value, range_error);
876 if ((
int)int_value < 0) {
879 _int64_range.
validate((
int)int_value, range_error);
885 _uint_range.
validate(int_value, range_error);
891 _uint_range.
validate(int_value, range_error);
897 _uint_range.
validate(int_value, range_error);
902 _uint64_range.
validate(int_value, range_error);
907 _double_range.
validate(int_value, range_error);
924 bool &pack_error,
bool &range_error)
const {
925 PN_int64 int_value = value * _divisor;
926 if (_has_modulus && _uint64_modulus != 0) {
928 int_value = _uint64_modulus - 1 - (-int_value - 1) % _uint64_modulus;
930 int_value = int_value % _uint64_modulus;
936 _int_range.
validate((
int)int_value, range_error);
942 _int_range.
validate((
int)int_value, range_error);
948 _int_range.
validate((
int)int_value, range_error);
954 _int64_range.
validate(int_value, range_error);
963 _uint_range.
validate((
unsigned int)(PN_uint64)int_value, range_error);
965 do_pack_uint8(pack_data.
get_write_pointer(1), (
unsigned int)(PN_uint64)int_value);
972 _uint_range.
validate((
unsigned int)(PN_uint64)int_value, range_error);
974 do_pack_uint16(pack_data.
get_write_pointer(2), (
unsigned int)(PN_uint64)int_value);
981 _uint_range.
validate((
unsigned int)(PN_uint64)int_value, range_error);
983 do_pack_uint32(pack_data.
get_write_pointer(4), (
unsigned int)(PN_uint64)int_value);
990 _uint64_range.
validate((PN_uint64)int_value, range_error);
995 _double_range.
validate((
double)int_value, range_error);
1012 bool &pack_error,
bool &range_error)
const {
1013 PN_uint64 int_value = value * _divisor;
1014 if (_has_modulus && _uint64_modulus != 0) {
1015 int_value = int_value % _uint64_modulus;
1020 if ((PN_int64)int_value < 0) {
1023 _int_range.
validate((
int)(PN_int64)int_value, range_error);
1029 if ((PN_int64)int_value < 0) {
1032 _int_range.
validate((
int)(PN_int64)int_value, range_error);
1038 if ((PN_int64)int_value < 0) {
1041 _int_range.
validate((
int)(PN_int64)int_value, range_error);
1047 if ((PN_int64)int_value < 0) {
1050 _int64_range.
validate((PN_int64)int_value, range_error);
1056 _uint_range.
validate((
unsigned int)int_value, range_error);
1062 _uint_range.
validate((
unsigned int)int_value, range_error);
1068 _uint_range.
validate((
unsigned int)int_value, range_error);
1074 _uint64_range.
validate(int_value, range_error);
1079 _double_range.
validate((
double)int_value, range_error);
1096 bool &pack_error,
bool &range_error)
const {
1097 size_t string_length = value.length();
1103 if (string_length == 0) {
1106 if (string_length != 1) {
1109 _uint_range.
validate((
unsigned int)value[0], range_error);
1116 _uint_range.
validate(string_length, range_error);
1118 if (_num_length_bytes != 0) {
1121 pack_data.
append_data(value.data(), string_length);
1125 _uint_range.
validate(string_length, range_error);
1126 if (_num_length_bytes != 0) {
1129 pack_data.
append_data(value.data(), string_length);
1152 if (_has_nested_fields) {
1157 unsigned int minimum_length = 0;
1159 minimum_length = _uint_range.
get_min(0);
1165 for (
unsigned int i = 0; i < minimum_length; i++) {
1184 pack_int(pack_data, 0, pack_error, pack_error);
1192 pack_int64(pack_data, 0, pack_error, pack_error);
1203 pack_uint(pack_data, 0, pack_error, pack_error);
1211 pack_uint64(pack_data, 0, pack_error, pack_error);
1219 pack_double(pack_data, 0.0, pack_error, pack_error);
1242 bool &pack_error,
bool &range_error)
const {
1246 if (p + 1 > length) {
1250 int int_value = do_unpack_int8(data + p);
1251 _int_range.
validate(int_value, range_error);
1259 if (p + 2 > length) {
1263 int int_value = do_unpack_int16(data + p);
1264 _int_range.
validate(int_value, range_error);
1272 if (p + 4 > length) {
1276 int int_value = do_unpack_int32(data + p);
1277 _int_range.
validate(int_value, range_error);
1285 if (p + 8 > length) {
1289 PN_int64 int_value = do_unpack_int64(data + p);
1290 _int64_range.
validate(int_value, range_error);
1291 value = (double)int_value;
1299 if (p + 1 > length) {
1303 unsigned int uint_value = do_unpack_uint8(data + p);
1304 _uint_range.
validate(uint_value, range_error);
1312 if (p + 2 > length) {
1316 unsigned int uint_value = do_unpack_uint16(data + p);
1317 _uint_range.
validate(uint_value, range_error);
1325 if (p + 4 > length) {
1329 unsigned int uint_value = do_unpack_uint32(data + p);
1330 _uint_range.
validate(uint_value, range_error);
1338 if (p + 8 > length) {
1342 PN_uint64 uint_value = do_unpack_uint64(data + p);
1343 _uint64_range.
validate(uint_value, range_error);
1344 value = (double)uint_value;
1351 if (p + 8 > length) {
1355 value = do_unpack_float64(data + p);
1356 _double_range.
validate(value, range_error);
1366 if (_divisor != 1) {
1367 value = value / _divisor;
1380 unpack_int(
const char *data,
size_t length,
size_t &p,
int &value,
1381 bool &pack_error,
bool &range_error)
const {
1384 if (p + 1 > length) {
1388 value = do_unpack_int8(data + p);
1389 _int_range.
validate(value, range_error);
1394 if (p + 2 > length) {
1398 value = do_unpack_int16(data + p);
1399 _int_range.
validate(value, range_error);
1404 if (p + 4 > length) {
1408 value = do_unpack_int32(data + p);
1409 _int_range.
validate(value, range_error);
1415 if (p + 8 > length) {
1419 PN_int64 int_value = do_unpack_uint64(data + p);
1420 _int64_range.
validate(int_value, range_error);
1421 value = (int)int_value;
1422 if (value != int_value) {
1433 if (p + 1 > length) {
1437 unsigned int uint_value = do_unpack_uint8(data + p);
1438 _uint_range.
validate(uint_value, range_error);
1446 if (p + 2 > length) {
1450 unsigned int uint_value = do_unpack_uint16(data + p);
1451 _uint_range.
validate(uint_value, range_error);
1452 value = (int)uint_value;
1459 if (p + 4 > length) {
1463 unsigned int uint_value = do_unpack_uint32(data + p);
1464 _uint_range.
validate(uint_value, range_error);
1465 value = (int)uint_value;
1475 if (p + 8 > length) {
1479 PN_uint64 uint_value = do_unpack_uint64(data + p);
1480 _uint64_range.
validate(uint_value, range_error);
1481 value = (int)(
unsigned int)uint_value;
1482 if ((
unsigned int)value != uint_value || value < 0) {
1491 if (p + 8 > length) {
1495 double real_value = do_unpack_float64(data + p);
1496 _double_range.
validate(real_value, range_error);
1497 value = (int)real_value;
1507 if (_divisor != 1) {
1508 value = value / _divisor;
1521 unpack_uint(
const char *data,
size_t length,
size_t &p,
unsigned int &value,
1522 bool &pack_error,
bool &range_error)
const {
1526 if (p + 1 > length) {
1530 int int_value = do_unpack_int8(data + p);
1531 _int_range.
validate(int_value, range_error);
1532 if (int_value < 0) {
1535 value = (
unsigned int)int_value;
1542 if (p + 2 > length) {
1546 int int_value = do_unpack_int16(data + p);
1547 _int_range.
validate(int_value, range_error);
1548 if (int_value < 0) {
1551 value = (
unsigned int)int_value;
1558 if (p + 4 > length) {
1562 int int_value = do_unpack_int32(data + p);
1563 _int_range.
validate(int_value, range_error);
1564 if (int_value < 0) {
1567 value = (
unsigned int)int_value;
1574 if (p + 8 > length) {
1578 PN_int64 int_value = do_unpack_int64(data + p);
1579 _int64_range.
validate(int_value, range_error);
1580 if (int_value < 0) {
1583 value = (
unsigned int)(
int)int_value;
1584 if (value != int_value) {
1593 if (p + 1 > length) {
1597 value = do_unpack_uint8(data + p);
1598 _uint_range.
validate(value, range_error);
1603 if (p + 2 > length) {
1607 value = do_unpack_uint16(data + p);
1608 _uint_range.
validate(value, range_error);
1613 if (p + 4 > length) {
1617 value = do_unpack_uint32(data + p);
1618 _uint_range.
validate(value, range_error);
1624 if (p + 8 > length) {
1628 PN_uint64 uint_value = do_unpack_uint64(data + p);
1629 _uint64_range.
validate(uint_value, range_error);
1630 value = (
unsigned int)uint_value;
1631 if (value != uint_value) {
1640 if (p + 8 > length) {
1644 double real_value = do_unpack_float64(data + p);
1645 _double_range.
validate(real_value, range_error);
1646 value = (
unsigned int)real_value;
1656 if (_divisor != 1) {
1657 value = value / _divisor;
1671 bool &pack_error,
bool &range_error)
const {
1675 if (p + 1 > length) {
1679 int int_value = do_unpack_int8(data + p);
1680 _int_range.
validate(int_value, range_error);
1681 value = (PN_int64)int_value;
1688 if (p + 2 > length) {
1692 int int_value = do_unpack_int16(data + p);
1693 _int_range.
validate(int_value, range_error);
1694 value = (PN_int64)int_value;
1701 if (p + 4 > length) {
1705 int int_value = do_unpack_int32(data + p);
1706 _int_range.
validate(int_value, range_error);
1707 value = (PN_int64)int_value;
1713 if (p + 8 > length) {
1717 value = do_unpack_int64(data + p);
1718 _int64_range.
validate(value, range_error);
1725 if (p + 1 > length) {
1729 unsigned int uint_value = do_unpack_uint8(data + p);
1730 _uint_range.
validate(uint_value, range_error);
1731 value = (PN_int64)(
int)uint_value;
1738 if (p + 2 > length) {
1742 unsigned int uint_value = do_unpack_uint16(data + p);
1743 _uint_range.
validate(uint_value, range_error);
1744 value = (PN_int64)(
int)uint_value;
1751 if (p + 4 > length) {
1755 unsigned int uint_value = do_unpack_uint32(data + p);
1756 _uint_range.
validate(uint_value, range_error);
1757 value = (PN_int64)(
int)uint_value;
1764 if (p + 8 > length) {
1768 PN_uint64 uint_value = do_unpack_uint64(data + p);
1769 _uint64_range.
validate(uint_value, range_error);
1770 value = (PN_int64)uint_value;
1780 if (p + 8 > length) {
1784 double real_value = do_unpack_float64(data + p);
1785 _double_range.
validate(real_value, range_error);
1786 value = (PN_int64)real_value;
1796 if (_divisor != 1) {
1797 value = value / _divisor;
1811 bool &pack_error,
bool &range_error)
const {
1815 if (p + 1 > length) {
1819 int int_value = do_unpack_int8(data + p);
1820 _int_range.
validate(int_value, range_error);
1821 if (int_value < 0) {
1824 value = (PN_uint64)(
unsigned int)int_value;
1831 if (p + 2 > length) {
1835 int int_value = do_unpack_int16(data + p);
1836 _int_range.
validate(int_value, range_error);
1837 if (int_value < 0) {
1840 value = (PN_uint64)(
unsigned int)int_value;
1847 if (p + 4 > length) {
1851 int int_value = do_unpack_int32(data + p);
1852 _int_range.
validate(int_value, range_error);
1853 if (int_value < 0) {
1856 value = (PN_uint64)(
unsigned int)int_value;
1863 if (p + 8 > length) {
1867 PN_int64 int_value = do_unpack_int64(data + p);
1868 _int64_range.
validate(int_value, range_error);
1869 if (int_value < 0) {
1872 value = (PN_uint64)int_value;
1880 if (p + 1 > length) {
1884 unsigned int uint_value = do_unpack_uint8(data + p);
1885 _uint_range.
validate(uint_value, range_error);
1886 value = (PN_uint64)uint_value;
1893 if (p + 2 > length) {
1897 unsigned int uint_value = do_unpack_uint16(data + p);
1898 _uint_range.
validate(uint_value, range_error);
1899 value = (PN_uint64)uint_value;
1906 if (p + 4 > length) {
1910 unsigned int uint_value = do_unpack_uint32(data + p);
1911 _uint_range.
validate(uint_value, range_error);
1912 value = (PN_uint64)uint_value;
1918 if (p + 8 > length) {
1922 value = do_unpack_uint64(data + p);
1923 _uint64_range.
validate(value, range_error);
1929 if (p + 8 > length) {
1933 double real_value = do_unpack_float64(data + p);
1934 _double_range.
validate(real_value, range_error);
1935 value = (PN_uint64)real_value;
1945 if (_divisor != 1) {
1946 value = value / _divisor;
1960 bool &pack_error,
bool &range_error)
const {
1967 if (p + 1 > length) {
1971 unsigned int int_value = do_unpack_uint8(data + p);
1972 _uint_range.
validate(int_value, range_error);
1973 value.assign(1, int_value);
1982 size_t string_length;
1984 if (_num_length_bytes == 0) {
1985 string_length = _fixed_byte_size;
1991 if (p + 2 > length) {
1995 string_length = do_unpack_uint16(data + p);
2000 if (p + 4 > length) {
2004 string_length = do_unpack_uint32(data + p);
2014 _uint_range.
validate(string_length, range_error);
2016 if (p + string_length > length) {
2020 value.assign(data + p, string_length);
2037 bool &pack_error,
bool &range_error)
const {
2038 if (!_has_range_limits) {
2044 if (p + 1 > length) {
2048 int int_value = do_unpack_int8(data + p);
2049 _int_range.
validate(int_value, range_error);
2056 if (p + 2 > length) {
2060 int int_value = do_unpack_int16(data + p);
2061 _int_range.
validate(int_value, range_error);
2068 if (p + 4 > length) {
2072 int int_value = do_unpack_int32(data + p);
2073 _int_range.
validate(int_value, range_error);
2080 if (p + 8 > length) {
2084 PN_int64 int_value = do_unpack_int64(data + p);
2085 _int64_range.
validate(int_value, range_error);
2093 if (p + 1 > length) {
2097 unsigned int uint_value = do_unpack_uint8(data + p);
2098 _uint_range.
validate(uint_value, range_error);
2105 if (p + 2 > length) {
2109 unsigned int uint_value = do_unpack_uint16(data + p);
2110 _uint_range.
validate(uint_value, range_error);
2117 if (p + 4 > length) {
2121 unsigned int uint_value = do_unpack_uint32(data + p);
2122 _uint_range.
validate(uint_value, range_error);
2129 if (p + 8 > length) {
2133 PN_uint64 uint_value = do_unpack_uint64(data + p);
2134 _uint64_range.
validate(uint_value, range_error);
2141 if (p + 8 > length) {
2145 double real_value = do_unpack_float64(data + p);
2146 _double_range.
validate(real_value, range_error);
2153 if (_num_length_bytes == 0) {
2154 p += _fixed_byte_size;
2157 if (p + 2 > length) {
2161 size_t string_length = do_unpack_uint16(data + p);
2162 _uint_range.
validate(string_length, range_error);
2163 p += 2 + string_length;
2168 if (_num_length_bytes == 0) {
2169 p += _fixed_byte_size;
2172 if (p + 4 > length) {
2176 size_t string_length = do_unpack_uint32(data + p);
2177 _uint_range.
validate(string_length, range_error);
2178 p += 4 + string_length;
2199 bool &pack_error)
const {
2200 size_t string_length;
2227 if (_num_length_bytes == 0) {
2228 p += _fixed_byte_size;
2231 if (p + 2 > length) {
2234 string_length = do_unpack_uint16(data + p);
2235 p += 2 + string_length;
2240 if (_num_length_bytes == 0) {
2241 p += _fixed_byte_size;
2244 if (p + 4 > length) {
2247 string_length = do_unpack_uint32(data + p);
2248 p += 4 + string_length;
2271 const string &name,
const string &postname)
const {
2278 out <<
"%" << _orig_modulus;
2280 if (_divisor != 1) {
2281 out <<
"/" << _divisor;
2290 _int_range.output(out, _divisor);
2298 _int64_range.output(out, _divisor);
2308 _uint_range.output(out, _divisor);
2324 _uint64_range.output(out, _divisor);
2332 _double_range.output(out, _divisor);
2340 _uint_range.output(out, _divisor);
2348 if (!prename.empty() || !name.empty() || !postname.empty()) {
2349 out <<
" " << prename << name << postname;
2367 hashgen.
add_int((
int)_double_modulus);
2370 _int_range.generate_hash(hashgen);
2371 _int64_range.generate_hash(hashgen);
2372 _uint_range.generate_hash(hashgen);
2373 _uint64_range.generate_hash(hashgen);
2374 _double_range.generate_hash(hashgen);
2385 bool DCSimpleParameter::
2396 bool DCSimpleParameter::
2398 if (_divisor != other->_divisor) {
2402 if (_type == other->_type) {
2411 switch (other->_type) {
2423 switch (other->_type) {
2444 bool DCSimpleParameter::
2450 if (_nested_field == NULL) {
2466 create_nested_field(DCSubatomicType type,
unsigned int divisor) {
2467 DivisorMap &divisor_map = _nested_field_map[type];
2468 DivisorMap::iterator di;
2469 di = divisor_map.find(divisor);
2470 if (di != divisor_map.end()) {
2471 return (*di).second;
2475 divisor_map[divisor] = nested_field;
2476 return nested_field;
2486 create_uint32uint8_type() {
2487 if (_uint32uint8_type == NULL) {
2493 return _uint32uint8_type;
virtual void pack_string(DCPackData &pack_data, const string &value, bool &pack_error, bool &range_error) const
Packs the indicated numeric or string value into the stream.
virtual void pack_int64(DCPackData &pack_data, PN_int64 value, bool &pack_error, bool &range_error) const
Packs the indicated numeric or string value into the stream.
char * get_write_pointer(size_t size)
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.
virtual void generate_hash(HashGenerator &hashgen) const
Accumulates the properties of this type into the hash.
This represents a single typedef declaration in the dc file.
This is a block of data that receives the results of DCPacker.
void output_typedef_name(ostream &out, bool brief, const string &prename, const string &name, const string &postname) const
Formats the instance like output_instance, but uses the typedef name instead.
void append_data(const char *buffer, size_t size)
Adds the indicated bytes to the end of the data.
bool set_divisor(unsigned int divisor)
Assigns the indicated divisor to the simple type.
int get_array_size() const
Returns the fixed number of elements in this array, or -1 if the array may contain a variable number ...
double get_modulus() const
Returns the modulus associated with this type, if any.
void add_int(int num)
Adds another integer to the hash so far.
This represents a class (or struct) object used as a parameter itself.
This is the most fundamental kind of parameter type: a single number or string, one of the DCSubatomi...
void validate(Number num, bool &range_error) const
Convenience function to validate the indicated number.
virtual bool unpack_validate(const char *data, size_t length, size_t &p, bool &pack_error, bool &range_error) const
Internally unpacks the current numeric or string value and validates it against the type range limits...
virtual DCPackerInterface * get_nested_field(int n) const
Returns the DCPackerInterface object that represents the nth nested field.
virtual bool pack_default_value(DCPackData &pack_data, bool &pack_error) const
Packs the field's specified default value (or a sensible default if no value is specified) into the s...
virtual void unpack_double(const char *data, size_t length, size_t &p, double &value, bool &pack_error, bool &range_error) const
Unpacks the current numeric or string value from the stream.
static void validate_int_limits(int value, int num_bits, bool &range_error)
Confirms that the signed value fits within num_bits bits.
Defines a particular DistributedClass as read from an input .dc file.
bool add_range(Number min, Number max)
Adds a new minmax to the list of ranges.
virtual bool do_check_match_simple_parameter(const DCSimpleParameter *other) const
Returns true if this field matches the indicated simple parameter, false otherwise.
bool has_one_value() const
Returns true if the numeric range specifies exactly one legal value, false if multiple values are leg...
DCSubatomicType get_type() const
Returns the particular subatomic type represented by this instance.
size_t get_length() const
Returns the current length of the buffer.
static void validate_uint64_limits(PN_uint64 value, int num_bits, bool &range_error)
Confirms that the unsigned value fits within num_bits bits.
virtual void pack_uint(DCPackData &pack_data, unsigned int value, bool &pack_error, bool &range_error) const
Packs the indicated numeric or string value into the stream.
int get_num_ranges() const
Returns the number of minmax components in the range description.
Represents the type specification for a single parameter within a field specification.
virtual void output_instance(ostream &out, bool brief, const string &prename, const string &name, const string &postname) const
Formats the parameter in the C++-like dc syntax as a typename and identifier.
virtual void pack_uint64(DCPackData &pack_data, PN_uint64 value, bool &pack_error, bool &range_error) const
Packs the indicated numeric or string value into the stream.
void pack_default_value()
Adds the default value for the current element into the stream.
virtual void unpack_uint64(const char *data, size_t length, size_t &p, PN_uint64 &value, bool &pack_error, bool &range_error) const
Unpacks the current numeric or string value from the stream.
This represents an array of some other kind of object, meaning this parameter type accepts an arbitra...
bool set_range(const DCDoubleRange &range)
Sets the parameter with the indicated range.
Number get_max(int n) const
Returns the maximum value defined by the nth component.
bool check_match(const DCPackerInterface *other) const
Returns true if the other interface is bitwise the same as this oneāthat is, a uint32 only matches a...
Number get_one_value() const
If has_one_value() returns true, this returns the one legal value accepted by the numeric range...
bool has_modulus() const
Returns true if there is a modulus associated, false otherwise.,.
void push()
Marks the beginning of a nested series of fields.
Number get_min(int n) const
Returns the minimum value defined by the nth component.
bool has_default_value() const
Returns true if a default value has been explicitly established for this field, false otherwise...
const char * get_data() const
Returns the beginning of the data buffer.
static void validate_int64_limits(PN_int64 value, int num_bits, bool &range_error)
Confirms that the signed value fits within num_bits bits.
This class generates an arbitrary hash number from a sequence of ints.
virtual bool unpack_skip(const char *data, size_t length, size_t &p, bool &pack_error) const
Increments p to the end of the current field without actually unpacking any data or performing any ra...
virtual void unpack_string(const char *data, size_t length, size_t &p, string &value, bool &pack_error, bool &range_error) const
Unpacks the current numeric or string value from the stream.
bool is_empty() const
Returns true if the range contains no elements (and thus allows all numbers), false if it contains at...
void output_char(ostream &out, Number divisor=1) const
Outputs the range, formatting the numeric values as quoted ASCII characters.
bool is_in_range(Number num) const
Returns true if the indicated number is within the specified range, false otherwise.
const DCTypedef * get_typedef() const
If this type has been referenced from a typedef, returns the DCTypedef instance, or NULL if the type ...
void begin_pack(const DCPackerInterface *root)
Begins a packing session.
virtual void generate_hash(HashGenerator &hashgen) const
Accumulates the properties of this type into the hash.
virtual bool is_valid() const
Returns false if the type is an invalid type (e.g.
bool is_numeric_type() const
Returns true if the type is a numeric type (and therefore can accept a divisor and/or a modulus)...
This class can be used for packing a series of numeric and string data into a binary stream...
virtual void unpack_int64(const char *data, size_t length, size_t &p, PN_int64 &value, bool &pack_error, bool &range_error) const
Unpacks the current numeric or string value from the stream.
DCParameter * get_element_type() const
Returns the type of the individual elements of this array.
bool add_field(DCField *field)
Adds the newly-allocated field to the class.
int get_divisor() const
Returns the divisor associated with this type.
bool end_pack()
Finishes a packing session.
virtual void pack_int(DCPackData &pack_data, int value, bool &pack_error, bool &range_error) const
Packs the indicated numeric or string value into the stream.
void pop()
Marks the end of a nested series of fields.
virtual void pack_double(DCPackData &pack_data, double value, bool &pack_error, bool &range_error) const
Packs the indicated numeric or string value into the stream.
virtual void unpack_int(const char *data, size_t length, size_t &p, int &value, bool &pack_error, bool &range_error) const
Unpacks the current numeric or string value from the stream.
virtual bool pack_default_value(DCPackData &pack_data, bool &pack_error) const
Packs the simpleParameter's specified default value (or a sensible default if no value is specified) ...
This defines the internal interface for packing values into a DCField.
bool set_modulus(double modulus)
Assigns the indicated modulus to the simple type.
static void validate_uint_limits(unsigned int value, int num_bits, bool &range_error)
Confirms that the unsigned value fits within num_bits bits.
virtual void unpack_uint(const char *data, size_t length, size_t &p, unsigned int &value, bool &pack_error, bool &range_error) const
Unpacks the current numeric or string value from the stream.
virtual int calc_num_nested_fields(size_t length_bytes) const
This flavor of get_num_nested_fields is used during unpacking.