00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "dcSimpleParameter.h"
00016 #include "dcPackData.h"
00017 #include "dcTypedef.h"
00018 #include "dcArrayParameter.h"
00019 #include "dcClassParameter.h"
00020 #include "dcClass.h"
00021 #include "hashGenerator.h"
00022 #include <math.h>
00023
00024 DCSimpleParameter::NestedFieldMap DCSimpleParameter::_nested_field_map;
00025 DCClassParameter *DCSimpleParameter::_uint32uint8_type = NULL;
00026
00027
00028
00029
00030
00031
00032 DCSimpleParameter::
00033 DCSimpleParameter(DCSubatomicType type, unsigned int divisor) :
00034 _type(type),
00035 _divisor(1),
00036 _has_modulus(false)
00037 {
00038 _pack_type = PT_invalid;
00039 _nested_type = ST_invalid;
00040 _has_nested_fields = false;
00041 _bytes_per_element = 0;
00042 _num_length_bytes = 2;
00043
00044
00045
00046
00047 switch (_type) {
00048 case ST_int8array:
00049 _pack_type = PT_array;
00050 _nested_type = ST_int8;
00051 _has_nested_fields = true;
00052 _bytes_per_element = 1;
00053 break;
00054
00055 case ST_int16array:
00056 _pack_type = PT_array;
00057 _nested_type = ST_int16;
00058 _has_nested_fields = true;
00059 _bytes_per_element = 2;
00060 break;
00061
00062 case ST_int32array:
00063 _pack_type = PT_array;
00064 _nested_type = ST_int32;
00065 _has_nested_fields = true;
00066 _bytes_per_element = 4;
00067 break;
00068
00069 case ST_uint8array:
00070 _pack_type = PT_array;
00071 _nested_type = ST_uint8;
00072 _has_nested_fields = true;
00073 _bytes_per_element = 1;
00074 break;
00075
00076 case ST_uint16array:
00077 _pack_type = PT_array;
00078 _nested_type = ST_uint16;
00079 _has_nested_fields = true;
00080 _bytes_per_element = 2;
00081 break;
00082
00083 case ST_uint32array:
00084 _pack_type = PT_array;
00085 _nested_type = ST_uint32;
00086 _has_nested_fields = true;
00087 _bytes_per_element = 4;
00088 break;
00089
00090 case ST_uint32uint8array:
00091 _pack_type = PT_array;
00092 _has_nested_fields = true;
00093 _bytes_per_element = 5;
00094 break;
00095
00096 case ST_blob32:
00097 _num_length_bytes = 4;
00098
00099 case ST_blob:
00100
00101
00102
00103 _pack_type = PT_blob;
00104 _nested_type = ST_uint8;
00105 _has_nested_fields = true;
00106 _bytes_per_element = 1;
00107 break;
00108
00109 case ST_string:
00110 _pack_type = PT_string;
00111 _nested_type = ST_char;
00112 _has_nested_fields = true;
00113 _bytes_per_element = 1;
00114 break;
00115
00116
00117 case ST_int8:
00118 _pack_type = PT_int;
00119 _has_fixed_byte_size = true;
00120 _fixed_byte_size = 1;
00121 break;
00122
00123 case ST_int16:
00124 _pack_type = PT_int;
00125 _has_fixed_byte_size = true;
00126 _fixed_byte_size = 2;
00127 break;
00128
00129 case ST_int32:
00130 _pack_type = PT_int;
00131 _has_fixed_byte_size = true;
00132 _fixed_byte_size = 4;
00133 break;
00134
00135 case ST_int64:
00136 _pack_type = PT_int64;
00137 _has_fixed_byte_size = true;
00138 _fixed_byte_size = 8;
00139 break;
00140
00141 case ST_char:
00142 _pack_type = PT_string;
00143 _has_fixed_byte_size = true;
00144 _fixed_byte_size = 1;
00145 break;
00146
00147 case ST_uint8:
00148 _pack_type = PT_uint;
00149 _has_fixed_byte_size = true;
00150 _fixed_byte_size = 1;
00151 break;
00152
00153 case ST_uint16:
00154 _pack_type = PT_uint;
00155 _has_fixed_byte_size = true;
00156 _fixed_byte_size = 2;
00157 break;
00158
00159 case ST_uint32:
00160 _pack_type = PT_uint;
00161 _has_fixed_byte_size = true;
00162 _fixed_byte_size = 4;
00163 break;
00164
00165 case ST_uint64:
00166 _pack_type = PT_uint64;
00167 _has_fixed_byte_size = true;
00168 _fixed_byte_size = 8;
00169 break;
00170
00171 case ST_float64:
00172 _pack_type = PT_double;
00173 _has_fixed_byte_size = true;
00174 _fixed_byte_size = 8;
00175 break;
00176
00177 case ST_invalid:
00178 break;
00179 }
00180 _has_fixed_structure = _has_fixed_byte_size;
00181
00182 set_divisor(divisor);
00183
00184 if (_nested_type != ST_invalid) {
00185 _nested_field = create_nested_field(_nested_type, _divisor);
00186
00187 } else if (_type == ST_uint32uint8array) {
00188
00189
00190
00191 _nested_field = create_uint32uint8_type();
00192
00193 } else {
00194 _nested_field = NULL;
00195 }
00196 }
00197
00198
00199
00200
00201
00202
00203 DCSimpleParameter::
00204 DCSimpleParameter(const DCSimpleParameter ©) :
00205 DCParameter(copy),
00206 _type(copy._type),
00207 _divisor(copy._divisor),
00208 _nested_field(copy._nested_field),
00209 _bytes_per_element(copy._bytes_per_element),
00210 _orig_range(copy._orig_range),
00211 _has_modulus(copy._has_modulus),
00212 _orig_modulus(copy._orig_modulus),
00213 _int_range(copy._int_range),
00214 _uint_range(copy._uint_range),
00215 _int64_range(copy._int64_range),
00216 _uint64_range(copy._uint64_range),
00217 _double_range(copy._double_range),
00218 _uint_modulus(copy._uint_modulus),
00219 _uint64_modulus(copy._uint64_modulus),
00220 _double_modulus(copy._double_modulus)
00221 {
00222 }
00223
00224
00225
00226
00227
00228
00229 DCSimpleParameter *DCSimpleParameter::
00230 as_simple_parameter() {
00231 return this;
00232 }
00233
00234
00235
00236
00237
00238
00239 const DCSimpleParameter *DCSimpleParameter::
00240 as_simple_parameter() const {
00241 return this;
00242 }
00243
00244
00245
00246
00247
00248
00249 DCParameter *DCSimpleParameter::
00250 make_copy() const {
00251 return new DCSimpleParameter(*this);
00252 }
00253
00254
00255
00256
00257
00258
00259
00260
00261 bool DCSimpleParameter::
00262 is_valid() const {
00263 return _type != ST_invalid;
00264 }
00265
00266
00267
00268
00269
00270
00271
00272 DCSubatomicType DCSimpleParameter::
00273 get_type() const {
00274 return _type;
00275 }
00276
00277
00278
00279
00280
00281
00282
00283 bool DCSimpleParameter::
00284 has_modulus() const {
00285 return _has_modulus;
00286 }
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299 double DCSimpleParameter::
00300 get_modulus() const {
00301 return _orig_modulus;
00302 }
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314 int DCSimpleParameter::
00315 get_divisor() const {
00316 return _divisor;
00317 }
00318
00319
00320
00321
00322
00323
00324
00325
00326 bool DCSimpleParameter::
00327 is_numeric_type() const {
00328 return !(_pack_type == PT_string || _pack_type == PT_blob);
00329 }
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341 bool DCSimpleParameter::
00342 set_modulus(double modulus) {
00343 if (_pack_type == PT_string || _pack_type == PT_blob || modulus <= 0.0) {
00344 return false;
00345 }
00346
00347 _has_modulus = true;
00348 _orig_modulus = modulus;
00349
00350 bool range_error = false;
00351 _double_modulus = modulus * _divisor;
00352 _uint64_modulus = (PN_uint64)floor(_double_modulus + 0.5);
00353 _uint_modulus = (unsigned int)_uint64_modulus;
00354
00355
00356
00357 switch (_type) {
00358 case ST_int8:
00359 case ST_int8array:
00360 validate_uint64_limits(_uint64_modulus - 1, 7, range_error);
00361 break;
00362
00363 case ST_int16:
00364 case ST_int16array:
00365 validate_uint64_limits(_uint64_modulus - 1, 15, range_error);
00366 break;
00367
00368 case ST_int32:
00369 case ST_int32array:
00370 validate_uint64_limits(_uint64_modulus - 1, 31, range_error);
00371 break;
00372
00373 case ST_int64:
00374 validate_uint64_limits(_uint64_modulus - 1, 63, range_error);
00375 break;
00376
00377 case ST_char:
00378 case ST_uint8:
00379 case ST_uint8array:
00380 validate_uint64_limits(_uint64_modulus - 1, 8, range_error);
00381 break;
00382
00383 case ST_uint16:
00384 case ST_uint16array:
00385 validate_uint64_limits(_uint64_modulus - 1, 16, range_error);
00386 break;
00387
00388 case ST_uint32:
00389 case ST_uint32array:
00390 validate_uint64_limits(_uint64_modulus - 1, 32, range_error);
00391 break;
00392
00393 case ST_uint64:
00394 case ST_float64:
00395 break;
00396
00397 default:
00398 return false;
00399 }
00400
00401 return !range_error;
00402 }
00403
00404
00405
00406
00407
00408
00409
00410
00411 bool DCSimpleParameter::
00412 set_divisor(unsigned int divisor) {
00413 if (_pack_type == PT_string || _pack_type == PT_blob || divisor == 0) {
00414 return false;
00415 }
00416
00417 _divisor = divisor;
00418 if ((_divisor != 1) &&
00419 (_pack_type == PT_int || _pack_type == PT_int64 ||
00420 _pack_type == PT_uint || _pack_type == PT_uint64)) {
00421 _pack_type = PT_double;
00422 }
00423
00424 if (_has_range_limits) {
00425 set_range(_orig_range);
00426 }
00427 if (_has_modulus) {
00428 set_modulus(_orig_modulus);
00429 }
00430
00431 return true;
00432 }
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444 bool DCSimpleParameter::
00445 set_range(const DCDoubleRange &range) {
00446 bool range_error = false;
00447 int num_ranges = range.get_num_ranges();
00448 int i;
00449
00450 _has_range_limits = (num_ranges != 0);
00451 _orig_range = range;
00452
00453 switch (_type) {
00454 case ST_int8:
00455 case ST_int8array:
00456 _int_range.clear();
00457 for (i = 0; i < num_ranges; i++) {
00458 PN_int64 min = (PN_int64)floor(range.get_min(i) * _divisor + 0.5);
00459 PN_int64 max = (PN_int64)floor(range.get_max(i) * _divisor + 0.5);
00460 validate_int64_limits(min, 8, range_error);
00461 validate_int64_limits(max, 8, range_error);
00462 _int_range.add_range((int)min, (int)max);
00463 }
00464 break;
00465
00466 case ST_int16:
00467 case ST_int16array:
00468 _int_range.clear();
00469 for (i = 0; i < num_ranges; i++) {
00470 PN_int64 min = (PN_int64)floor(range.get_min(i) * _divisor + 0.5);
00471 PN_int64 max = (PN_int64)floor(range.get_max(i) * _divisor + 0.5);
00472 validate_int64_limits(min, 16, range_error);
00473 validate_int64_limits(max, 16, range_error);
00474 _int_range.add_range((int)min, (int)max);
00475 }
00476 break;
00477
00478 case ST_int32:
00479 case ST_int32array:
00480 _int_range.clear();
00481 for (i = 0; i < num_ranges; i++) {
00482 PN_int64 min = (PN_int64)floor(range.get_min(i) * _divisor + 0.5);
00483 PN_int64 max = (PN_int64)floor(range.get_max(i) * _divisor + 0.5);
00484 validate_int64_limits(min, 32, range_error);
00485 validate_int64_limits(max, 32, range_error);
00486 _int_range.add_range((int)min, (int)max);
00487 }
00488 break;
00489
00490 case ST_int64:
00491 _int64_range.clear();
00492 for (i = 0; i < num_ranges; i++) {
00493 PN_int64 min = (PN_int64)floor(range.get_min(i) * _divisor + 0.5);
00494 PN_int64 max = (PN_int64)floor(range.get_max(i) * _divisor + 0.5);
00495 _int64_range.add_range(min, max);
00496 }
00497 break;
00498
00499 case ST_char:
00500 case ST_uint8:
00501 case ST_uint8array:
00502 _uint_range.clear();
00503 for (i = 0; i < num_ranges; i++) {
00504 PN_uint64 min = (PN_uint64)floor(range.get_min(i) * _divisor + 0.5);
00505 PN_uint64 max = (PN_uint64)floor(range.get_max(i) * _divisor + 0.5);
00506 validate_uint64_limits(min, 8, range_error);
00507 validate_uint64_limits(max, 8, range_error);
00508 _uint_range.add_range((unsigned int)min, (unsigned int)max);
00509 }
00510 break;
00511
00512 case ST_uint16:
00513 case ST_uint16array:
00514 _uint_range.clear();
00515 for (i = 0; i < num_ranges; i++) {
00516 PN_uint64 min = (PN_uint64)floor(range.get_min(i) * _divisor + 0.5);
00517 PN_uint64 max = (PN_uint64)floor(range.get_max(i) * _divisor + 0.5);
00518 validate_uint64_limits(min, 16, range_error);
00519 validate_uint64_limits(max, 16, range_error);
00520 _uint_range.add_range((unsigned int)min, (unsigned int)max);
00521 }
00522 break;
00523
00524 case ST_uint32:
00525 case ST_uint32array:
00526 _uint_range.clear();
00527 for (i = 0; i < num_ranges; i++) {
00528 PN_uint64 min = (PN_uint64)floor(range.get_min(i) * _divisor + 0.5);
00529 PN_uint64 max = (PN_uint64)floor(range.get_max(i) * _divisor + 0.5);
00530 validate_uint64_limits(min, 32, range_error);
00531 validate_uint64_limits(max, 32, range_error);
00532 _uint_range.add_range((unsigned int)min, (unsigned int)max);
00533 }
00534 break;
00535
00536 case ST_uint64:
00537 _uint64_range.clear();
00538 for (i = 0; i < num_ranges; i++) {
00539 PN_uint64 min = (PN_uint64)floor(range.get_min(i) * _divisor + 0.5);
00540 PN_uint64 max = (PN_uint64)floor(range.get_max(i) * _divisor + 0.5);
00541 _uint64_range.add_range(min, max);
00542 }
00543 break;
00544
00545 case ST_float64:
00546 _double_range.clear();
00547 for (i = 0; i < num_ranges; i++) {
00548 double min = range.get_min(i) * _divisor;
00549 double max = range.get_max(i) * _divisor;
00550 _double_range.add_range(min, max);
00551 }
00552 break;
00553
00554 case ST_string:
00555 case ST_blob:
00556 _uint_range.clear();
00557 for (i = 0; i < num_ranges; i++) {
00558 PN_uint64 min = (PN_uint64)floor(range.get_min(i) * _divisor + 0.5);
00559 PN_uint64 max = (PN_uint64)floor(range.get_max(i) * _divisor + 0.5);
00560 validate_uint64_limits(min, 16, range_error);
00561 validate_uint64_limits(max, 16, range_error);
00562 _uint_range.add_range((unsigned int)min, (unsigned int)max);
00563 }
00564 if (_uint_range.has_one_value()) {
00565
00566
00567 _num_length_bytes = 0;
00568 _has_fixed_byte_size = true;
00569 _fixed_byte_size = _uint_range.get_one_value();
00570 _has_fixed_structure = true;
00571 } else {
00572 _num_length_bytes = 2;
00573 _has_fixed_byte_size = false;
00574 _has_fixed_structure = false;
00575 }
00576 break;
00577
00578 case ST_blob32:
00579 _uint_range.clear();
00580 for (i = 0; i < num_ranges; i++) {
00581 PN_uint64 min = (PN_uint64)floor(range.get_min(i) * _divisor + 0.5);
00582 PN_uint64 max = (PN_uint64)floor(range.get_max(i) * _divisor + 0.5);
00583 validate_uint64_limits(min, 32, range_error);
00584 validate_uint64_limits(max, 32, range_error);
00585 _uint_range.add_range((unsigned int)min, (unsigned int)max);
00586 }
00587 if (_uint_range.has_one_value()) {
00588
00589
00590 _num_length_bytes = 0;
00591 _has_fixed_byte_size = true;
00592 _fixed_byte_size = _uint_range.get_one_value();
00593 _has_fixed_structure = true;
00594 } else {
00595 _num_length_bytes = 4;
00596 _has_fixed_byte_size = false;
00597 _has_fixed_structure = false;
00598 }
00599 break;
00600
00601 default:
00602 return false;
00603 }
00604
00605 return !range_error;
00606 }
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618 int DCSimpleParameter::
00619 calc_num_nested_fields(size_t length_bytes) const {
00620 if (_bytes_per_element != 0) {
00621 return length_bytes / _bytes_per_element;
00622 }
00623 return 0;
00624 }
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634 DCPackerInterface *DCSimpleParameter::
00635 get_nested_field(int) const {
00636 return _nested_field;
00637 }
00638
00639
00640
00641
00642
00643
00644
00645 void DCSimpleParameter::
00646 pack_double(DCPackData &pack_data, double value,
00647 bool &pack_error, bool &range_error) const {
00648 double real_value = value * _divisor;
00649 if (_has_modulus) {
00650 if (real_value < 0.0) {
00651 real_value = _double_modulus - fmod(-real_value, _double_modulus);
00652 if (real_value == _double_modulus) {
00653 real_value = 0.0;
00654 }
00655 } else {
00656 real_value = fmod(real_value, _double_modulus);
00657 }
00658 }
00659
00660 switch (_type) {
00661 case ST_int8:
00662 {
00663 int int_value = (int)floor(real_value + 0.5);
00664 _int_range.validate(int_value, range_error);
00665 validate_int_limits(int_value, 8, range_error);
00666 do_pack_int8(pack_data.get_write_pointer(1), int_value);
00667 }
00668 break;
00669
00670 case ST_int16:
00671 {
00672 int int_value = (int)floor(real_value + 0.5);
00673 _int_range.validate(int_value, range_error);
00674 validate_int_limits(int_value, 16, range_error);
00675 do_pack_int16(pack_data.get_write_pointer(2), int_value);
00676 }
00677 break;
00678
00679 case ST_int32:
00680 {
00681 int int_value = (int)floor(real_value + 0.5);
00682 _int_range.validate(int_value, range_error);
00683 do_pack_int32(pack_data.get_write_pointer(4), int_value);
00684 }
00685 break;
00686
00687 case ST_int64:
00688 {
00689 PN_int64 int64_value = (PN_int64)floor(real_value + 0.5);
00690 _int64_range.validate(int64_value, range_error);
00691 do_pack_int64(pack_data.get_write_pointer(8), int64_value);
00692 }
00693 break;
00694
00695 case ST_char:
00696 case ST_uint8:
00697 {
00698 unsigned int int_value = (unsigned int)floor(real_value + 0.5);
00699 _uint_range.validate(int_value, range_error);
00700 validate_uint_limits(int_value, 8, range_error);
00701 do_pack_uint8(pack_data.get_write_pointer(1), int_value);
00702 }
00703 break;
00704
00705 case ST_uint16:
00706 {
00707 unsigned int int_value = (unsigned int)floor(real_value + 0.5);
00708 _uint_range.validate(int_value, range_error);
00709 validate_uint_limits(int_value, 16, range_error);
00710 do_pack_uint16(pack_data.get_write_pointer(2), int_value);
00711 }
00712 break;
00713
00714 case ST_uint32:
00715 {
00716 unsigned int int_value = (unsigned int)floor(real_value + 0.5);
00717 _uint_range.validate(int_value, range_error);
00718 do_pack_uint32(pack_data.get_write_pointer(4), int_value);
00719 }
00720 break;
00721
00722 case ST_uint64:
00723 {
00724 PN_uint64 int64_value = (PN_uint64)floor(real_value + 0.5);
00725 _uint64_range.validate(int64_value, range_error);
00726 do_pack_uint64(pack_data.get_write_pointer(8), int64_value);
00727 }
00728 break;
00729
00730 case ST_float64:
00731 _double_range.validate(real_value, range_error);
00732 do_pack_float64(pack_data.get_write_pointer(8), real_value);
00733 break;
00734
00735 default:
00736 pack_error = true;
00737 }
00738 }
00739
00740
00741
00742
00743
00744
00745
00746 void DCSimpleParameter::
00747 pack_int(DCPackData &pack_data, int value,
00748 bool &pack_error, bool &range_error) const {
00749 int int_value = value * _divisor;
00750
00751 if (value != 0 && (int_value / value) != (int)_divisor) {
00752
00753
00754 pack_int64(pack_data, (PN_int64)value, pack_error, range_error);
00755 return;
00756 }
00757
00758 if (_has_modulus && _uint_modulus != 0) {
00759 if (int_value < 0) {
00760 int_value = _uint_modulus - 1 - (-int_value - 1) % _uint_modulus;
00761 } else {
00762 int_value = int_value % _uint_modulus;
00763 }
00764 }
00765
00766 switch (_type) {
00767 case ST_int8:
00768 _int_range.validate(int_value, range_error);
00769 validate_int_limits(int_value, 8, range_error);
00770 do_pack_int8(pack_data.get_write_pointer(1), int_value);
00771 break;
00772
00773 case ST_int16:
00774 _int_range.validate(int_value, range_error);
00775 validate_int_limits(int_value, 16, range_error);
00776 do_pack_int16(pack_data.get_write_pointer(2), int_value);
00777 break;
00778
00779 case ST_int32:
00780 _int_range.validate(int_value, range_error);
00781 do_pack_int32(pack_data.get_write_pointer(4), int_value);
00782 break;
00783
00784 case ST_int64:
00785 _int64_range.validate(int_value, range_error);
00786 do_pack_int64(pack_data.get_write_pointer(8), int_value);
00787 break;
00788
00789 case ST_char:
00790 case ST_uint8:
00791 if (int_value < 0) {
00792 range_error = true;
00793 }
00794 _uint_range.validate((unsigned int)int_value, range_error);
00795 validate_uint_limits((unsigned int)int_value, 8, range_error);
00796 do_pack_uint8(pack_data.get_write_pointer(1), (unsigned int)int_value);
00797 break;
00798
00799 case ST_uint16:
00800 if (int_value < 0) {
00801 range_error = true;
00802 }
00803 _uint_range.validate((unsigned int)int_value, range_error);
00804 validate_uint_limits((unsigned int)int_value, 16, range_error);
00805 do_pack_uint16(pack_data.get_write_pointer(2), (unsigned int)int_value);
00806 break;
00807
00808 case ST_uint32:
00809 if (int_value < 0) {
00810 range_error = true;
00811 }
00812 _uint_range.validate((unsigned int)int_value, range_error);
00813 do_pack_uint32(pack_data.get_write_pointer(4), (unsigned int)int_value);
00814 break;
00815
00816 case ST_uint64:
00817 if (int_value < 0) {
00818 range_error = true;
00819 }
00820 _uint64_range.validate((unsigned int)int_value, range_error);
00821 do_pack_uint64(pack_data.get_write_pointer(8), (unsigned int)int_value);
00822 break;
00823
00824 case ST_float64:
00825 _double_range.validate(int_value, range_error);
00826 do_pack_float64(pack_data.get_write_pointer(8), int_value);
00827 break;
00828
00829 default:
00830 pack_error = true;
00831 }
00832 }
00833
00834
00835
00836
00837
00838
00839
00840 void DCSimpleParameter::
00841 pack_uint(DCPackData &pack_data, unsigned int value,
00842 bool &pack_error, bool &range_error) const {
00843 unsigned int int_value = value * _divisor;
00844 if (_has_modulus && _uint_modulus != 0) {
00845 int_value = int_value % _uint_modulus;
00846 }
00847
00848 switch (_type) {
00849 case ST_int8:
00850 if ((int)int_value < 0) {
00851 range_error = true;
00852 }
00853 _int_range.validate((int)int_value, range_error);
00854 validate_int_limits((int)int_value, 8, range_error);
00855 do_pack_int8(pack_data.get_write_pointer(1), (int)int_value);
00856 break;
00857
00858 case ST_int16:
00859 if ((int)int_value < 0) {
00860 range_error = true;
00861 }
00862 _int_range.validate((int)int_value, range_error);
00863 validate_int_limits((int)int_value, 16, range_error);
00864 do_pack_int16(pack_data.get_write_pointer(2), (int)int_value);
00865 break;
00866
00867 case ST_int32:
00868 if ((int)int_value < 0) {
00869 range_error = true;
00870 }
00871 _int_range.validate((int)int_value, range_error);
00872 do_pack_int32(pack_data.get_write_pointer(4), (int)int_value);
00873 break;
00874
00875 case ST_int64:
00876 if ((int)int_value < 0) {
00877 range_error = true;
00878 }
00879 _int64_range.validate((int)int_value, range_error);
00880 do_pack_int64(pack_data.get_write_pointer(8), (int)int_value);
00881 break;
00882
00883 case ST_char:
00884 case ST_uint8:
00885 _uint_range.validate(int_value, range_error);
00886 validate_uint_limits(int_value, 8, range_error);
00887 do_pack_uint8(pack_data.get_write_pointer(1), int_value);
00888 break;
00889
00890 case ST_uint16:
00891 _uint_range.validate(int_value, range_error);
00892 validate_uint_limits(int_value, 16, range_error);
00893 do_pack_uint16(pack_data.get_write_pointer(2), int_value);
00894 break;
00895
00896 case ST_uint32:
00897 _uint_range.validate(int_value, range_error);
00898 do_pack_uint32(pack_data.get_write_pointer(4), int_value);
00899 break;
00900
00901 case ST_uint64:
00902 _uint64_range.validate(int_value, range_error);
00903 do_pack_uint64(pack_data.get_write_pointer(8), int_value);
00904 break;
00905
00906 case ST_float64:
00907 _double_range.validate(int_value, range_error);
00908 do_pack_float64(pack_data.get_write_pointer(8), int_value);
00909 break;
00910
00911 default:
00912 pack_error = true;
00913 }
00914 }
00915
00916
00917
00918
00919
00920
00921
00922 void DCSimpleParameter::
00923 pack_int64(DCPackData &pack_data, PN_int64 value,
00924 bool &pack_error, bool &range_error) const {
00925 PN_int64 int_value = value * _divisor;
00926 if (_has_modulus && _uint64_modulus != 0) {
00927 if (int_value < 0) {
00928 int_value = _uint64_modulus - 1 - (-int_value - 1) % _uint64_modulus;
00929 } else {
00930 int_value = int_value % _uint64_modulus;
00931 }
00932 }
00933
00934 switch (_type) {
00935 case ST_int8:
00936 _int_range.validate((int)int_value, range_error);
00937 validate_int64_limits(int_value, 8, range_error);
00938 do_pack_int8(pack_data.get_write_pointer(1), (int)int_value);
00939 break;
00940
00941 case ST_int16:
00942 _int_range.validate((int)int_value, range_error);
00943 validate_int64_limits(int_value, 16, range_error);
00944 do_pack_int16(pack_data.get_write_pointer(2), (int)int_value);
00945 break;
00946
00947 case ST_int32:
00948 _int_range.validate((int)int_value, range_error);
00949 validate_int64_limits(int_value, 32, range_error);
00950 do_pack_int32(pack_data.get_write_pointer(4), (int)int_value);
00951 break;
00952
00953 case ST_int64:
00954 _int64_range.validate(int_value, range_error);
00955 do_pack_int64(pack_data.get_write_pointer(8), int_value);
00956 break;
00957
00958 case ST_char:
00959 case ST_uint8:
00960 if (int_value < 0) {
00961 range_error = true;
00962 }
00963 _uint_range.validate((unsigned int)(PN_uint64)int_value, range_error);
00964 validate_uint64_limits((PN_uint64)int_value, 8, range_error);
00965 do_pack_uint8(pack_data.get_write_pointer(1), (unsigned int)(PN_uint64)int_value);
00966 break;
00967
00968 case ST_uint16:
00969 if (int_value < 0) {
00970 range_error = true;
00971 }
00972 _uint_range.validate((unsigned int)(PN_uint64)int_value, range_error);
00973 validate_uint64_limits((PN_uint64)int_value, 16, range_error);
00974 do_pack_uint16(pack_data.get_write_pointer(2), (unsigned int)(PN_uint64)int_value);
00975 break;
00976
00977 case ST_uint32:
00978 if (int_value < 0) {
00979 range_error = true;
00980 }
00981 _uint_range.validate((unsigned int)(PN_uint64)int_value, range_error);
00982 validate_uint64_limits((PN_uint64)int_value, 32, range_error);
00983 do_pack_uint32(pack_data.get_write_pointer(4), (unsigned int)(PN_uint64)int_value);
00984 break;
00985
00986 case ST_uint64:
00987 if (int_value < 0) {
00988 range_error = true;
00989 }
00990 _uint64_range.validate((PN_uint64)int_value, range_error);
00991 do_pack_uint64(pack_data.get_write_pointer(8), (PN_uint64)int_value);
00992 break;
00993
00994 case ST_float64:
00995 _double_range.validate((double)int_value, range_error);
00996 do_pack_float64(pack_data.get_write_pointer(8), (double)int_value);
00997 break;
00998
00999 default:
01000 pack_error = true;
01001 }
01002 }
01003
01004
01005
01006
01007
01008
01009
01010 void DCSimpleParameter::
01011 pack_uint64(DCPackData &pack_data, PN_uint64 value,
01012 bool &pack_error, bool &range_error) const {
01013 PN_uint64 int_value = value * _divisor;
01014 if (_has_modulus && _uint64_modulus != 0) {
01015 int_value = int_value % _uint64_modulus;
01016 }
01017
01018 switch (_type) {
01019 case ST_int8:
01020 if ((PN_int64)int_value < 0) {
01021 range_error = true;
01022 }
01023 _int_range.validate((int)(PN_int64)int_value, range_error);
01024 validate_int64_limits((PN_int64)int_value, 8, range_error);
01025 do_pack_int8(pack_data.get_write_pointer(1), (int)(PN_int64)int_value);
01026 break;
01027
01028 case ST_int16:
01029 if ((PN_int64)int_value < 0) {
01030 range_error = true;
01031 }
01032 _int_range.validate((int)(PN_int64)int_value, range_error);
01033 validate_int64_limits((PN_int64)int_value, 16, range_error);
01034 do_pack_int16(pack_data.get_write_pointer(2), (int)(PN_int64)int_value);
01035 break;
01036
01037 case ST_int32:
01038 if ((PN_int64)int_value < 0) {
01039 range_error = true;
01040 }
01041 _int_range.validate((int)(PN_int64)int_value, range_error);
01042 validate_int64_limits((PN_int64)int_value, 32, range_error);
01043 do_pack_int32(pack_data.get_write_pointer(4), (int)(PN_int64)int_value);
01044 break;
01045
01046 case ST_int64:
01047 if ((PN_int64)int_value < 0) {
01048 range_error = true;
01049 }
01050 _int64_range.validate((PN_int64)int_value, range_error);
01051 do_pack_int64(pack_data.get_write_pointer(8), (PN_int64)int_value);
01052 break;
01053
01054 case ST_char:
01055 case ST_uint8:
01056 _uint_range.validate((unsigned int)int_value, range_error);
01057 validate_uint64_limits(int_value, 8, range_error);
01058 do_pack_uint8(pack_data.get_write_pointer(1), (unsigned int)int_value);
01059 break;
01060
01061 case ST_uint16:
01062 _uint_range.validate((unsigned int)int_value, range_error);
01063 validate_uint64_limits(int_value, 16, range_error);
01064 do_pack_uint16(pack_data.get_write_pointer(2), (unsigned int)int_value);
01065 break;
01066
01067 case ST_uint32:
01068 _uint_range.validate((unsigned int)int_value, range_error);
01069 validate_uint64_limits(int_value, 32, range_error);
01070 do_pack_uint32(pack_data.get_write_pointer(4), (unsigned int)int_value);
01071 break;
01072
01073 case ST_uint64:
01074 _uint64_range.validate(int_value, range_error);
01075 do_pack_uint64(pack_data.get_write_pointer(8), int_value);
01076 break;
01077
01078 case ST_float64:
01079 _double_range.validate((double)int_value, range_error);
01080 do_pack_float64(pack_data.get_write_pointer(8), (double)int_value);
01081 break;
01082
01083 default:
01084 pack_error = true;
01085 }
01086 }
01087
01088
01089
01090
01091
01092
01093
01094 void DCSimpleParameter::
01095 pack_string(DCPackData &pack_data, const string &value,
01096 bool &pack_error, bool &range_error) const {
01097 size_t string_length = value.length();
01098
01099 switch (_type) {
01100 case ST_char:
01101 case ST_uint8:
01102 case ST_int8:
01103 if (string_length == 0) {
01104 pack_error = true;
01105 } else {
01106 if (string_length != 1) {
01107 range_error = true;
01108 }
01109 _uint_range.validate((unsigned int)value[0], range_error);
01110 do_pack_uint8(pack_data.get_write_pointer(1), (unsigned int)value[0]);
01111 }
01112 break;
01113
01114 case ST_string:
01115 case ST_blob:
01116 _uint_range.validate(string_length, range_error);
01117 validate_uint_limits(string_length, 16, range_error);
01118 if (_num_length_bytes != 0) {
01119 do_pack_uint16(pack_data.get_write_pointer(2), string_length);
01120 }
01121 pack_data.append_data(value.data(), string_length);
01122 break;
01123
01124 case ST_blob32:
01125 _uint_range.validate(string_length, range_error);
01126 if (_num_length_bytes != 0) {
01127 do_pack_uint32(pack_data.get_write_pointer(4), string_length);
01128 }
01129 pack_data.append_data(value.data(), string_length);
01130 break;
01131
01132 default:
01133 pack_error = true;
01134 }
01135 }
01136
01137
01138
01139
01140
01141
01142
01143
01144
01145
01146 bool DCSimpleParameter::
01147 pack_default_value(DCPackData &pack_data, bool &pack_error) const {
01148 if (has_default_value()) {
01149 return DCField::pack_default_value(pack_data, pack_error);
01150 }
01151
01152 if (_has_nested_fields) {
01153
01154
01155
01156
01157 unsigned int minimum_length = 0;
01158 if (!_uint_range.is_empty()) {
01159 minimum_length = _uint_range.get_min(0);
01160 }
01161
01162 DCPacker packer;
01163 packer.begin_pack(this);
01164 packer.push();
01165 for (unsigned int i = 0; i < minimum_length; i++) {
01166 packer.pack_default_value();
01167 }
01168 packer.pop();
01169 if (!packer.end_pack()) {
01170 pack_error = true;
01171
01172 } else {
01173 pack_data.append_data(packer.get_data(), packer.get_length());
01174 }
01175
01176 } else {
01177
01178
01179 switch (_type) {
01180 case ST_int8:
01181 case ST_int16:
01182 case ST_int32:
01183 if (_int_range.is_in_range(0)) {
01184 pack_int(pack_data, 0, pack_error, pack_error);
01185 } else {
01186 pack_int(pack_data, _int_range.get_min(0), pack_error, pack_error);
01187 }
01188 break;
01189
01190 case ST_int64:
01191 if (_int64_range.is_in_range(0)) {
01192 pack_int64(pack_data, 0, pack_error, pack_error);
01193 } else {
01194 pack_int64(pack_data, _int64_range.get_min(0), pack_error, pack_error);
01195 }
01196 break;
01197
01198 case ST_char:
01199 case ST_uint8:
01200 case ST_uint16:
01201 case ST_uint32:
01202 if (_uint_range.is_in_range(0)) {
01203 pack_uint(pack_data, 0, pack_error, pack_error);
01204 } else {
01205 pack_uint(pack_data, _uint_range.get_min(0), pack_error, pack_error);
01206 }
01207 break;
01208
01209 case ST_uint64:
01210 if (_uint64_range.is_in_range(0)) {
01211 pack_uint64(pack_data, 0, pack_error, pack_error);
01212 } else {
01213 pack_uint64(pack_data, _uint64_range.get_min(0), pack_error, pack_error);
01214 }
01215 break;
01216
01217 case ST_float64:
01218 if (_double_range.is_in_range(0.0)) {
01219 pack_double(pack_data, 0.0, pack_error, pack_error);
01220 } else {
01221 pack_double(pack_data, _double_range.get_min(0), pack_error, pack_error);
01222 }
01223 break;
01224
01225 default:
01226 pack_error = true;
01227 }
01228 }
01229 return true;
01230 }
01231
01232
01233
01234
01235
01236
01237
01238
01239
01240 void DCSimpleParameter::
01241 unpack_double(const char *data, size_t length, size_t &p, double &value,
01242 bool &pack_error, bool &range_error) const {
01243 switch (_type) {
01244 case ST_int8:
01245 {
01246 if (p + 1 > length) {
01247 pack_error = true;
01248 return;
01249 }
01250 int int_value = do_unpack_int8(data + p);
01251 _int_range.validate(int_value, range_error);
01252 value = int_value;
01253 p++;
01254 }
01255 break;
01256
01257 case ST_int16:
01258 {
01259 if (p + 2 > length) {
01260 pack_error = true;
01261 return;
01262 }
01263 int int_value = do_unpack_int16(data + p);
01264 _int_range.validate(int_value, range_error);
01265 value = int_value;
01266 p += 2;
01267 }
01268 break;
01269
01270 case ST_int32:
01271 {
01272 if (p + 4 > length) {
01273 pack_error = true;
01274 return;
01275 }
01276 int int_value = do_unpack_int32(data + p);
01277 _int_range.validate(int_value, range_error);
01278 value = int_value;
01279 p += 4;
01280 }
01281 break;
01282
01283 case ST_int64:
01284 {
01285 if (p + 8 > length) {
01286 pack_error = true;
01287 return;
01288 }
01289 PN_int64 int_value = do_unpack_int64(data + p);
01290 _int64_range.validate(int_value, range_error);
01291 value = (double)int_value;
01292 p += 8;
01293 }
01294 break;
01295
01296 case ST_char:
01297 case ST_uint8:
01298 {
01299 if (p + 1 > length) {
01300 pack_error = true;
01301 return;
01302 }
01303 unsigned int uint_value = do_unpack_uint8(data + p);
01304 _uint_range.validate(uint_value, range_error);
01305 value = uint_value;
01306 p++;
01307 }
01308 break;
01309
01310 case ST_uint16:
01311 {
01312 if (p + 2 > length) {
01313 pack_error = true;
01314 return;
01315 }
01316 unsigned int uint_value = do_unpack_uint16(data + p);
01317 _uint_range.validate(uint_value, range_error);
01318 value = uint_value;
01319 p += 2;
01320 }
01321 break;
01322
01323 case ST_uint32:
01324 {
01325 if (p + 4 > length) {
01326 pack_error = true;
01327 return;
01328 }
01329 unsigned int uint_value = do_unpack_uint32(data + p);
01330 _uint_range.validate(uint_value, range_error);
01331 value = uint_value;
01332 p += 4;
01333 }
01334 break;
01335
01336 case ST_uint64:
01337 {
01338 if (p + 8 > length) {
01339 pack_error = true;
01340 return;
01341 }
01342 PN_uint64 uint_value = do_unpack_uint64(data + p);
01343 _uint64_range.validate(uint_value, range_error);
01344 value = (double)uint_value;
01345 p += 8;
01346 }
01347 break;
01348
01349 case ST_float64:
01350 {
01351 if (p + 8 > length) {
01352 pack_error = true;
01353 return;
01354 }
01355 value = do_unpack_float64(data + p);
01356 _double_range.validate(value, range_error);
01357 p += 8;
01358 }
01359 break;
01360
01361 default:
01362 pack_error = true;
01363 return;
01364 }
01365
01366 if (_divisor != 1) {
01367 value = value / _divisor;
01368 }
01369
01370 return;
01371 }
01372
01373
01374
01375
01376
01377
01378
01379 void DCSimpleParameter::
01380 unpack_int(const char *data, size_t length, size_t &p, int &value,
01381 bool &pack_error, bool &range_error) const {
01382 switch (_type) {
01383 case ST_int8:
01384 if (p + 1 > length) {
01385 pack_error = true;
01386 return;
01387 }
01388 value = do_unpack_int8(data + p);
01389 _int_range.validate(value, range_error);
01390 p++;
01391 break;
01392
01393 case ST_int16:
01394 if (p + 2 > length) {
01395 pack_error = true;
01396 return;
01397 }
01398 value = do_unpack_int16(data + p);
01399 _int_range.validate(value, range_error);
01400 p += 2;
01401 break;
01402
01403 case ST_int32:
01404 if (p + 4 > length) {
01405 pack_error = true;
01406 return;
01407 }
01408 value = do_unpack_int32(data + p);
01409 _int_range.validate(value, range_error);
01410 p += 4;
01411 break;
01412
01413 case ST_int64:
01414 {
01415 if (p + 8 > length) {
01416 pack_error = true;
01417 return;
01418 }
01419 PN_int64 int_value = do_unpack_uint64(data + p);
01420 _int64_range.validate(int_value, range_error);
01421 value = (int)int_value;
01422 if (value != int_value) {
01423
01424 pack_error = true;
01425 }
01426 p += 8;
01427 }
01428 break;
01429
01430 case ST_char:
01431 case ST_uint8:
01432 {
01433 if (p + 1 > length) {
01434 pack_error = true;
01435 return;
01436 }
01437 unsigned int uint_value = do_unpack_uint8(data + p);
01438 _uint_range.validate(uint_value, range_error);
01439 value = uint_value;
01440 p++;
01441 }
01442 break;
01443
01444 case ST_uint16:
01445 {
01446 if (p + 2 > length) {
01447 pack_error = true;
01448 return;
01449 }
01450 unsigned int uint_value = do_unpack_uint16(data + p);
01451 _uint_range.validate(uint_value, range_error);
01452 value = (int)uint_value;
01453 p += 2;
01454 }
01455 break;
01456
01457 case ST_uint32:
01458 {
01459 if (p + 4 > length) {
01460 pack_error = true;
01461 return;
01462 }
01463 unsigned int uint_value = do_unpack_uint32(data + p);
01464 _uint_range.validate(uint_value, range_error);
01465 value = (int)uint_value;
01466 if (value < 0) {
01467 pack_error = true;
01468 }
01469 p += 4;
01470 }
01471 break;
01472
01473 case ST_uint64:
01474 {
01475 if (p + 8 > length) {
01476 pack_error = true;
01477 return;
01478 }
01479 PN_uint64 uint_value = do_unpack_uint64(data + p);
01480 _uint64_range.validate(uint_value, range_error);
01481 value = (int)(unsigned int)uint_value;
01482 if ((unsigned int)value != uint_value || value < 0) {
01483 pack_error = true;
01484 }
01485 p += 8;
01486 }
01487 break;
01488
01489 case ST_float64:
01490 {
01491 if (p + 8 > length) {
01492 pack_error = true;
01493 return;
01494 }
01495 double real_value = do_unpack_float64(data + p);
01496 _double_range.validate(real_value, range_error);
01497 value = (int)real_value;
01498 p += 8;
01499 }
01500 break;
01501
01502 default:
01503 pack_error = true;
01504 return;
01505 }
01506
01507 if (_divisor != 1) {
01508 value = value / _divisor;
01509 }
01510
01511 return;
01512 }
01513
01514
01515
01516
01517
01518
01519
01520 void DCSimpleParameter::
01521 unpack_uint(const char *data, size_t length, size_t &p, unsigned int &value,
01522 bool &pack_error, bool &range_error) const {
01523 switch (_type) {
01524 case ST_int8:
01525 {
01526 if (p + 1 > length) {
01527 pack_error = true;
01528 return;
01529 }
01530 int int_value = do_unpack_int8(data + p);
01531 _int_range.validate(int_value, range_error);
01532 if (int_value < 0) {
01533 pack_error = true;
01534 }
01535 value = (unsigned int)int_value;
01536 p++;
01537 }
01538 break;
01539
01540 case ST_int16:
01541 {
01542 if (p + 2 > length) {
01543 pack_error = true;
01544 return;
01545 }
01546 int int_value = do_unpack_int16(data + p);
01547 _int_range.validate(int_value, range_error);
01548 if (int_value < 0) {
01549 pack_error = true;
01550 }
01551 value = (unsigned int)int_value;
01552 p += 2;
01553 }
01554 break;
01555
01556 case ST_int32:
01557 {
01558 if (p + 4 > length) {
01559 pack_error = true;
01560 return;
01561 }
01562 int int_value = do_unpack_int32(data + p);
01563 _int_range.validate(int_value, range_error);
01564 if (int_value < 0) {
01565 pack_error = true;
01566 }
01567 value = (unsigned int)int_value;
01568 p += 4;
01569 }
01570 break;
01571
01572 case ST_int64:
01573 {
01574 if (p + 8 > length) {
01575 pack_error = true;
01576 return;
01577 }
01578 PN_int64 int_value = do_unpack_int64(data + p);
01579 _int64_range.validate(int_value, range_error);
01580 if (int_value < 0) {
01581 pack_error = true;
01582 }
01583 value = (unsigned int)(int)int_value;
01584 if (value != int_value) {
01585 pack_error = true;
01586 }
01587 p += 8;
01588 }
01589 break;
01590
01591 case ST_char:
01592 case ST_uint8:
01593 if (p + 1 > length) {
01594 pack_error = true;
01595 return;
01596 }
01597 value = do_unpack_uint8(data + p);
01598 _uint_range.validate(value, range_error);
01599 p++;
01600 break;
01601
01602 case ST_uint16:
01603 if (p + 2 > length) {
01604 pack_error = true;
01605 return;
01606 }
01607 value = do_unpack_uint16(data + p);
01608 _uint_range.validate(value, range_error);
01609 p += 2;
01610 break;
01611
01612 case ST_uint32:
01613 if (p + 4 > length) {
01614 pack_error = true;
01615 return;
01616 }
01617 value = do_unpack_uint32(data + p);
01618 _uint_range.validate(value, range_error);
01619 p += 4;
01620 break;
01621
01622 case ST_uint64:
01623 {
01624 if (p + 8 > length) {
01625 pack_error = true;
01626 return;
01627 }
01628 PN_uint64 uint_value = do_unpack_uint64(data + p);
01629 _uint64_range.validate(uint_value, range_error);
01630 value = (unsigned int)uint_value;
01631 if (value != uint_value) {
01632 pack_error = true;
01633 }
01634 p += 8;
01635 }
01636 break;
01637
01638 case ST_float64:
01639 {
01640 if (p + 8 > length) {
01641 pack_error = true;
01642 return;
01643 }
01644 double real_value = do_unpack_float64(data + p);
01645 _double_range.validate(real_value, range_error);
01646 value = (unsigned int)real_value;
01647 p += 8;
01648 }
01649 break;
01650
01651 default:
01652 pack_error = true;
01653 return;
01654 }
01655
01656 if (_divisor != 1) {
01657 value = value / _divisor;
01658 }
01659
01660 return;
01661 }
01662
01663
01664
01665
01666
01667
01668
01669 void DCSimpleParameter::
01670 unpack_int64(const char *data, size_t length, size_t &p, PN_int64 &value,
01671 bool &pack_error, bool &range_error) const {
01672 switch (_type) {
01673 case ST_int8:
01674 {
01675 if (p + 1 > length) {
01676 pack_error = true;
01677 return;
01678 }
01679 int int_value = do_unpack_int8(data + p);
01680 _int_range.validate(int_value, range_error);
01681 value = (PN_int64)int_value;
01682 p++;
01683 }
01684 break;
01685
01686 case ST_int16:
01687 {
01688 if (p + 2 > length) {
01689 pack_error = true;
01690 return;
01691 }
01692 int int_value = do_unpack_int16(data + p);
01693 _int_range.validate(int_value, range_error);
01694 value = (PN_int64)int_value;
01695 p += 2;
01696 }
01697 break;
01698
01699 case ST_int32:
01700 {
01701 if (p + 4 > length) {
01702 pack_error = true;
01703 return;
01704 }
01705 int int_value = do_unpack_int32(data + p);
01706 _int_range.validate(int_value, range_error);
01707 value = (PN_int64)int_value;
01708 p += 4;
01709 }
01710 break;
01711
01712 case ST_int64:
01713 if (p + 8 > length) {
01714 pack_error = true;
01715 return;
01716 }
01717 value = do_unpack_int64(data + p);
01718 _int64_range.validate(value, range_error);
01719 p += 8;
01720 break;
01721
01722 case ST_char:
01723 case ST_uint8:
01724 {
01725 if (p + 1 > length) {
01726 pack_error = true;
01727 return;
01728 }
01729 unsigned int uint_value = do_unpack_uint8(data + p);
01730 _uint_range.validate(uint_value, range_error);
01731 value = (PN_int64)(int)uint_value;
01732 p++;
01733 }
01734 break;
01735
01736 case ST_uint16:
01737 {
01738 if (p + 2 > length) {
01739 pack_error = true;
01740 return;
01741 }
01742 unsigned int uint_value = do_unpack_uint16(data + p);
01743 _uint_range.validate(uint_value, range_error);
01744 value = (PN_int64)(int)uint_value;
01745 p += 2;
01746 }
01747 break;
01748
01749 case ST_uint32:
01750 {
01751 if (p + 4 > length) {
01752 pack_error = true;
01753 return;
01754 }
01755 unsigned int uint_value = do_unpack_uint32(data + p);
01756 _uint_range.validate(uint_value, range_error);
01757 value = (PN_int64)(int)uint_value;
01758 p += 4;
01759 }
01760 break;
01761
01762 case ST_uint64:
01763 {
01764 if (p + 8 > length) {
01765 pack_error = true;
01766 return;
01767 }
01768 PN_uint64 uint_value = do_unpack_uint64(data + p);
01769 _uint64_range.validate(uint_value, range_error);
01770 value = (PN_int64)uint_value;
01771 if (value < 0) {
01772 pack_error = true;
01773 }
01774 p += 8;
01775 }
01776 break;
01777
01778 case ST_float64:
01779 {
01780 if (p + 8 > length) {
01781 pack_error = true;
01782 return;
01783 }
01784 double real_value = do_unpack_float64(data + p);
01785 _double_range.validate(real_value, range_error);
01786 value = (PN_int64)real_value;
01787 p += 8;
01788 }
01789 break;
01790
01791 default:
01792 pack_error = true;
01793 return;
01794 }
01795
01796 if (_divisor != 1) {
01797 value = value / _divisor;
01798 }
01799
01800 return;
01801 }
01802
01803
01804
01805
01806
01807
01808
01809 void DCSimpleParameter::
01810 unpack_uint64(const char *data, size_t length, size_t &p, PN_uint64 &value,
01811 bool &pack_error, bool &range_error) const {
01812 switch (_type) {
01813 case ST_int8:
01814 {
01815 if (p + 1 > length) {
01816 pack_error = true;
01817 return;
01818 }
01819 int int_value = do_unpack_int8(data + p);
01820 _int_range.validate(int_value, range_error);
01821 if (int_value < 0) {
01822 pack_error = true;
01823 }
01824 value = (PN_uint64)(unsigned int)int_value;
01825 p++;
01826 }
01827 break;
01828
01829 case ST_int16:
01830 {
01831 if (p + 2 > length) {
01832 pack_error = true;
01833 return;
01834 }
01835 int int_value = do_unpack_int16(data + p);
01836 _int_range.validate(int_value, range_error);
01837 if (int_value < 0) {
01838 pack_error = true;
01839 }
01840 value = (PN_uint64)(unsigned int)int_value;
01841 p += 2;
01842 }
01843 break;
01844
01845 case ST_int32:
01846 {
01847 if (p + 4 > length) {
01848 pack_error = true;
01849 return;
01850 }
01851 int int_value = do_unpack_int32(data + p);
01852 _int_range.validate(int_value, range_error);
01853 if (int_value < 0) {
01854 pack_error = true;
01855 }
01856 value = (PN_uint64)(unsigned int)int_value;
01857 p += 4;
01858 }
01859 break;
01860
01861 case ST_int64:
01862 {
01863 if (p + 8 > length) {
01864 pack_error = true;
01865 return;
01866 }
01867 PN_int64 int_value = do_unpack_int64(data + p);
01868 _int64_range.validate(int_value, range_error);
01869 if (int_value < 0) {
01870 pack_error = true;
01871 }
01872 value = (PN_uint64)int_value;
01873 p += 8;
01874 }
01875 break;
01876
01877 case ST_char:
01878 case ST_uint8:
01879 {
01880 if (p + 1 > length) {
01881 pack_error = true;
01882 return;
01883 }
01884 unsigned int uint_value = do_unpack_uint8(data + p);
01885 _uint_range.validate(uint_value, range_error);
01886 value = (PN_uint64)uint_value;
01887 p++;
01888 }
01889 break;
01890
01891 case ST_uint16:
01892 {
01893 if (p + 2 > length) {
01894 pack_error = true;
01895 return;
01896 }
01897 unsigned int uint_value = do_unpack_uint16(data + p);
01898 _uint_range.validate(uint_value, range_error);
01899 value = (PN_uint64)uint_value;
01900 p += 2;
01901 }
01902 break;
01903
01904 case ST_uint32:
01905 {
01906 if (p + 4 > length) {
01907 pack_error = true;
01908 return;
01909 }
01910 unsigned int uint_value = do_unpack_uint32(data + p);
01911 _uint_range.validate(uint_value, range_error);
01912 value = (PN_uint64)uint_value;
01913 p += 4;
01914 }
01915 break;
01916
01917 case ST_uint64:
01918 if (p + 8 > length) {
01919 pack_error = true;
01920 return;
01921 }
01922 value = do_unpack_uint64(data + p);
01923 _uint64_range.validate(value, range_error);
01924 p += 8;
01925 break;
01926
01927 case ST_float64:
01928 {
01929 if (p + 8 > length) {
01930 pack_error = true;
01931 return;
01932 }
01933 double real_value = do_unpack_float64(data + p);
01934 _double_range.validate(real_value, range_error);
01935 value = (PN_uint64)real_value;
01936 p += 8;
01937 }
01938 break;
01939
01940 default:
01941 pack_error = true;
01942 return;
01943 }
01944
01945 if (_divisor != 1) {
01946 value = value / _divisor;
01947 }
01948
01949 return;
01950 }
01951
01952
01953
01954
01955
01956
01957
01958 void DCSimpleParameter::
01959 unpack_string(const char *data, size_t length, size_t &p, string &value,
01960 bool &pack_error, bool &range_error) const {
01961
01962 switch (_type) {
01963 case ST_char:
01964 case ST_int8:
01965 case ST_uint8:
01966 {
01967 if (p + 1 > length) {
01968 pack_error = true;
01969 return;
01970 }
01971 unsigned int int_value = do_unpack_uint8(data + p);
01972 _uint_range.validate(int_value, range_error);
01973 value.assign(1, int_value);
01974 p++;
01975 }
01976 return;
01977
01978 default:
01979 break;
01980 }
01981
01982 size_t string_length;
01983
01984 if (_num_length_bytes == 0) {
01985 string_length = _fixed_byte_size;
01986
01987 } else {
01988 switch (_type) {
01989 case ST_string:
01990 case ST_blob:
01991 if (p + 2 > length) {
01992 pack_error = true;
01993 return;
01994 }
01995 string_length = do_unpack_uint16(data + p);
01996 p += 2;
01997 break;
01998
01999 case ST_blob32:
02000 if (p + 4 > length) {
02001 pack_error = true;
02002 return;
02003 }
02004 string_length = do_unpack_uint32(data + p);
02005 p += 4;
02006 break;
02007
02008 default:
02009 pack_error = true;
02010 return;
02011 }
02012 }
02013
02014 _uint_range.validate(string_length, range_error);
02015
02016 if (p + string_length > length) {
02017 pack_error = true;
02018 return;
02019 }
02020 value.assign(data + p, string_length);
02021 p += string_length;
02022
02023 return;
02024 }
02025
02026
02027
02028
02029
02030
02031
02032
02033
02034
02035 bool DCSimpleParameter::
02036 unpack_validate(const char *data, size_t length, size_t &p,
02037 bool &pack_error, bool &range_error) const {
02038 if (!_has_range_limits) {
02039 return unpack_skip(data, length, p, pack_error);
02040 }
02041 switch (_type) {
02042 case ST_int8:
02043 {
02044 if (p + 1 > length) {
02045 pack_error = true;
02046 return true;
02047 }
02048 int int_value = do_unpack_int8(data + p);
02049 _int_range.validate(int_value, range_error);
02050 p++;
02051 }
02052 break;
02053
02054 case ST_int16:
02055 {
02056 if (p + 2 > length) {
02057 pack_error = true;
02058 return true;
02059 }
02060 int int_value = do_unpack_int16(data + p);
02061 _int_range.validate(int_value, range_error);
02062 p += 2;
02063 }
02064 break;
02065
02066 case ST_int32:
02067 {
02068 if (p + 4 > length) {
02069 pack_error = true;
02070 return true;
02071 }
02072 int int_value = do_unpack_int32(data + p);
02073 _int_range.validate(int_value, range_error);
02074 p += 4;
02075 }
02076 break;
02077
02078 case ST_int64:
02079 {
02080 if (p + 8 > length) {
02081 pack_error = true;
02082 return true;
02083 }
02084 PN_int64 int_value = do_unpack_int64(data + p);
02085 _int64_range.validate(int_value, range_error);
02086 p += 8;
02087 }
02088 break;
02089
02090 case ST_char:
02091 case ST_uint8:
02092 {
02093 if (p + 1 > length) {
02094 pack_error = true;
02095 return true;
02096 }
02097 unsigned int uint_value = do_unpack_uint8(data + p);
02098 _uint_range.validate(uint_value, range_error);
02099 p++;
02100 }
02101 break;
02102
02103 case ST_uint16:
02104 {
02105 if (p + 2 > length) {
02106 pack_error = true;
02107 return true;
02108 }
02109 unsigned int uint_value = do_unpack_uint16(data + p);
02110 _uint_range.validate(uint_value, range_error);
02111 p += 2;
02112 }
02113 break;
02114
02115 case ST_uint32:
02116 {
02117 if (p + 4 > length) {
02118 pack_error = true;
02119 return true;
02120 }
02121 unsigned int uint_value = do_unpack_uint32(data + p);
02122 _uint_range.validate(uint_value, range_error);
02123 p += 4;
02124 }
02125 break;
02126
02127 case ST_uint64:
02128 {
02129 if (p + 8 > length) {
02130 pack_error = true;
02131 return true;
02132 }
02133 PN_uint64 uint_value = do_unpack_uint64(data + p);
02134 _uint64_range.validate(uint_value, range_error);
02135 p += 8;
02136 }
02137 break;
02138
02139 case ST_float64:
02140 {
02141 if (p + 8 > length) {
02142 pack_error = true;
02143 return true;
02144 }
02145 double real_value = do_unpack_float64(data + p);
02146 _double_range.validate(real_value, range_error);
02147 p += 8;
02148 }
02149 break;
02150
02151 case ST_string:
02152 case ST_blob:
02153 if (_num_length_bytes == 0) {
02154 p += _fixed_byte_size;
02155
02156 } else {
02157 if (p + 2 > length) {
02158 pack_error = true;
02159 return true;
02160 }
02161 size_t string_length = do_unpack_uint16(data + p);
02162 _uint_range.validate(string_length, range_error);
02163 p += 2 + string_length;
02164 }
02165 break;
02166
02167 case ST_blob32:
02168 if (_num_length_bytes == 0) {
02169 p += _fixed_byte_size;
02170
02171 } else {
02172 if (p + 4 > length) {
02173 pack_error = true;
02174 return true;
02175 }
02176 size_t string_length = do_unpack_uint32(data + p);
02177 _uint_range.validate(string_length, range_error);
02178 p += 4 + string_length;
02179 }
02180 break;
02181
02182 default:
02183 return false;
02184 }
02185
02186 return true;
02187 }
02188
02189
02190
02191
02192
02193
02194
02195
02196
02197 bool DCSimpleParameter::
02198 unpack_skip(const char *data, size_t length, size_t &p,
02199 bool &pack_error) const {
02200 size_t string_length;
02201
02202 switch (_type) {
02203 case ST_char:
02204 case ST_int8:
02205 case ST_uint8:
02206 p++;
02207 break;
02208
02209 case ST_int16:
02210 case ST_uint16:
02211 p += 2;
02212 break;
02213
02214 case ST_int32:
02215 case ST_uint32:
02216 p += 4;
02217 break;
02218
02219 case ST_int64:
02220 case ST_uint64:
02221 case ST_float64:
02222 p += 8;
02223 break;
02224
02225 case ST_string:
02226 case ST_blob:
02227 if (_num_length_bytes == 0) {
02228 p += _fixed_byte_size;
02229
02230 } else {
02231 if (p + 2 > length) {
02232 return false;
02233 }
02234 string_length = do_unpack_uint16(data + p);
02235 p += 2 + string_length;
02236 }
02237 break;
02238
02239 case ST_blob32:
02240 if (_num_length_bytes == 0) {
02241 p += _fixed_byte_size;
02242
02243 } else {
02244 if (p + 4 > length) {
02245 return false;
02246 }
02247 string_length = do_unpack_uint32(data + p);
02248 p += 4 + string_length;
02249 }
02250 break;
02251
02252 default:
02253 return false;
02254 }
02255
02256 if (p > length) {
02257 pack_error = true;
02258 }
02259
02260 return true;
02261 }
02262
02263
02264
02265
02266
02267
02268
02269 void DCSimpleParameter::
02270 output_instance(ostream &out, bool brief, const string &prename,
02271 const string &name, const string &postname) const {
02272 if (get_typedef() != (DCTypedef *)NULL) {
02273 output_typedef_name(out, brief, prename, name, postname);
02274
02275 } else {
02276 out << _type;
02277 if (_has_modulus) {
02278 out << "%" << _orig_modulus;
02279 }
02280 if (_divisor != 1) {
02281 out << "/" << _divisor;
02282 }
02283
02284 switch (_type) {
02285 case ST_int8:
02286 case ST_int16:
02287 case ST_int32:
02288 if (!_int_range.is_empty()) {
02289 out << "(";
02290 _int_range.output(out, _divisor);
02291 out << ")";
02292 }
02293 break;
02294
02295 case ST_int64:
02296 if (!_int64_range.is_empty()) {
02297 out << "(";
02298 _int64_range.output(out, _divisor);
02299 out << ")";
02300 }
02301 break;
02302
02303 case ST_uint8:
02304 case ST_uint16:
02305 case ST_uint32:
02306 if (!_uint_range.is_empty()) {
02307 out << "(";
02308 _uint_range.output(out, _divisor);
02309 out << ")";
02310 }
02311 break;
02312
02313 case ST_char:
02314 if (!_uint_range.is_empty()) {
02315 out << "(";
02316 _uint_range.output_char(out, _divisor);
02317 out << ")";
02318 }
02319 break;
02320
02321 case ST_uint64:
02322 if (!_uint64_range.is_empty()) {
02323 out << "(";
02324 _uint64_range.output(out, _divisor);
02325 out << ")";
02326 }
02327 break;
02328
02329 case ST_float64:
02330 if (!_double_range.is_empty()) {
02331 out << "(";
02332 _double_range.output(out, _divisor);
02333 out << ")";
02334 }
02335 break;
02336
02337 case ST_string:
02338 if (!_uint_range.is_empty()) {
02339 out << "(";
02340 _uint_range.output(out, _divisor);
02341 out << ")";
02342 }
02343 break;
02344 default:
02345 break;
02346 }
02347
02348 if (!prename.empty() || !name.empty() || !postname.empty()) {
02349 out << " " << prename << name << postname;
02350 }
02351 }
02352 }
02353
02354
02355
02356
02357
02358
02359
02360 void DCSimpleParameter::
02361 generate_hash(HashGenerator &hashgen) const {
02362 DCParameter::generate_hash(hashgen);
02363
02364 hashgen.add_int(_type);
02365 hashgen.add_int(_divisor);
02366 if (_has_modulus) {
02367 hashgen.add_int((int)_double_modulus);
02368 }
02369
02370 _int_range.generate_hash(hashgen);
02371 _int64_range.generate_hash(hashgen);
02372 _uint_range.generate_hash(hashgen);
02373 _uint64_range.generate_hash(hashgen);
02374 _double_range.generate_hash(hashgen);
02375 }
02376
02377
02378
02379
02380
02381
02382
02383
02384
02385 bool DCSimpleParameter::
02386 do_check_match(const DCPackerInterface *other) const {
02387 return other->do_check_match_simple_parameter(this);
02388 }
02389
02390
02391
02392
02393
02394
02395
02396 bool DCSimpleParameter::
02397 do_check_match_simple_parameter(const DCSimpleParameter *other) const {
02398 if (_divisor != other->_divisor) {
02399 return false;
02400 }
02401
02402 if (_type == other->_type) {
02403 return true;
02404 }
02405
02406
02407
02408 switch (_type) {
02409 case ST_uint8:
02410 case ST_char:
02411 switch (other->_type) {
02412 case ST_uint8:
02413 case ST_char:
02414 return true;
02415
02416 default:
02417 return false;
02418 }
02419
02420 case ST_string:
02421 case ST_blob:
02422 case ST_uint8array:
02423 switch (other->_type) {
02424 case ST_string:
02425 case ST_blob:
02426 case ST_uint8array:
02427 return true;
02428
02429 default:
02430 return false;
02431 }
02432
02433 default:
02434 return false;
02435 }
02436 }
02437
02438
02439
02440
02441
02442
02443
02444 bool DCSimpleParameter::
02445 do_check_match_array_parameter(const DCArrayParameter *other) const {
02446 if (other->get_array_size() != -1) {
02447
02448 return false;
02449 }
02450 if (_nested_field == NULL) {
02451
02452 return false;
02453 }
02454
02455 return _nested_field->check_match(other->get_element_type());
02456 }
02457
02458
02459
02460
02461
02462
02463
02464
02465 DCSimpleParameter *DCSimpleParameter::
02466 create_nested_field(DCSubatomicType type, unsigned int divisor) {
02467 DivisorMap &divisor_map = _nested_field_map[type];
02468 DivisorMap::iterator di;
02469 di = divisor_map.find(divisor);
02470 if (di != divisor_map.end()) {
02471 return (*di).second;
02472 }
02473
02474 DCSimpleParameter *nested_field = new DCSimpleParameter(type, divisor);
02475 divisor_map[divisor] = nested_field;
02476 return nested_field;
02477 }
02478
02479
02480
02481
02482
02483
02484
02485 DCPackerInterface *DCSimpleParameter::
02486 create_uint32uint8_type() {
02487 if (_uint32uint8_type == NULL) {
02488 DCClass *dclass = new DCClass(NULL, "", true, false);
02489 dclass->add_field(new DCSimpleParameter(ST_uint32));
02490 dclass->add_field(new DCSimpleParameter(ST_uint8));
02491 _uint32uint8_type = new DCClassParameter(dclass);
02492 }
02493 return _uint32uint8_type;
02494 }