Sync with 5.2.0
[deliverable/titan.core.git] / core / Integer.cc
1 ///////////////////////////////////////////////////////////////////////////////
2 // Copyright (c) 2000-2014 Ericsson Telecom AB
3 // All rights reserved. This program and the accompanying materials
4 // are made available under the terms of the Eclipse Public License v1.0
5 // which accompanies this distribution, and is available at
6 // http://www.eclipse.org/legal/epl-v10.html
7 ///////////////////////////////////////////////////////////////////////////////
8 #include "Integer.hh"
9
10 #include <limits.h>
11 #include <strings.h>
12 #include <string.h>
13 #include <ctype.h>
14
15 #include "Error.hh"
16 #include "Logger.hh"
17 #include "Optional.hh"
18 #include "Types.h"
19 #include "Param_Types.hh"
20 #include "Encdec.hh"
21 #include "RAW.hh"
22 #include "BER.hh"
23 #include "TEXT.hh"
24 #include "Charstring.hh"
25 #include "Addfunc.hh"
26 #include "XmlReader.hh"
27
28 #include <openssl/bn.h>
29 #include <openssl/crypto.h>
30
31 #include "../common/dbgnew.hh"
32
33 #if defined(__GNUC__) && __GNUC__ >= 3
34 // To provide prediction information for the compiler.
35 // Borrowed from /usr/src/linux/include/linux/compiler.h.
36 #define likely(x) __builtin_expect(!!(x), 1)
37 #define unlikely(x) __builtin_expect(!!(x), 0)
38 #else
39 #define likely(x) (x)
40 #define unlikely(x) (x)
41 #endif
42
43 static const Token_Match integer_value_match("^([\t ]*-?[0-9]+).*$", TRUE);
44
45 int_val_t INTEGER::get_val() const
46 {
47 if (likely(native_flag)) return int_val_t(val.native);
48 else return int_val_t(BN_dup(val.openssl));
49 }
50
51 void INTEGER::set_val(const int_val_t& other_value)
52 {
53 clean_up();
54 bound_flag = TRUE;
55 native_flag = other_value.native_flag;
56 if (likely(native_flag)) val.native = other_value.val.native;
57 else val.openssl = BN_dup(other_value.val.openssl);
58 }
59
60 INTEGER::INTEGER()
61 {
62 bound_flag = FALSE;
63 native_flag = TRUE;
64 }
65
66 INTEGER::INTEGER(int other_value)
67 {
68 bound_flag = TRUE;
69 native_flag = TRUE;
70 val.native = other_value;
71 }
72
73 INTEGER::INTEGER(const INTEGER& other_value)
74 : Base_Type(other_value)
75 {
76 other_value.must_bound("Copying an unbound integer value.");
77 bound_flag = TRUE;
78 native_flag = other_value.native_flag;
79 if (likely(native_flag)) val.native = other_value.val.native;
80 else val.openssl = BN_dup(other_value.val.openssl);
81 }
82
83 /// Return 0 if fail, 1 on success
84 int INTEGER::from_string(const char *s) {
85 BIGNUM *other_value_int = NULL;
86 if (BN_dec2bn(&other_value_int, s + (*s == '+')))
87 {
88 bound_flag = TRUE;
89 if (BN_num_bits(other_value_int) > (int)sizeof(int) * 8 - 1) {
90 native_flag = FALSE;
91 val.openssl = other_value_int;
92 } else {
93 native_flag = TRUE;
94 val.native = string2RInt(s);
95 BN_free(other_value_int);
96 }
97 return 1;
98 }
99 else return 0;
100 }
101
102 INTEGER::INTEGER(const char *other_value)
103 {
104 if (unlikely(!other_value))
105 TTCN_error("Unexpected error when converting `%s' to integer",
106 other_value);
107 bound_flag = TRUE;
108 if (!from_string(other_value)) TTCN_error(
109 "Unexpected error when converting `%s' to integer", other_value);
110 }
111
112 // For internal use only. It's not part of the public interface.
113 INTEGER::INTEGER(BIGNUM *other_value)
114 {
115 if (unlikely(!other_value))
116 TTCN_error("Unexpected error when initializing an integer");
117 bound_flag = TRUE;
118 native_flag = FALSE;
119 val.openssl = other_value;
120 }
121
122 INTEGER::~INTEGER()
123 {
124 if (unlikely(!native_flag)) BN_free(val.openssl);
125 }
126
127 void INTEGER::clean_up()
128 {
129 if (!bound_flag) return;
130 if (unlikely(!native_flag)) BN_free(val.openssl);
131 bound_flag = FALSE;
132 }
133
134 INTEGER& INTEGER::operator=(int other_value)
135 {
136 clean_up();
137 bound_flag = TRUE;
138 native_flag = TRUE;
139 val.native = other_value;
140 return *this;
141 }
142
143 INTEGER& INTEGER::operator=(const INTEGER& other_value)
144 {
145 if (this == &other_value)
146 return *this;
147 other_value.must_bound("Assignment of an unbound integer value.");
148 clean_up();
149 bound_flag = TRUE;
150 native_flag = other_value.native_flag;
151 if (likely(native_flag)) val.native = other_value.val.native;
152 else val.openssl = BN_dup(other_value.val.openssl);
153 return *this;
154 }
155
156 // A bit more specific than operator+().
157 INTEGER& INTEGER::operator++()
158 {
159 must_bound("Unbound integer operand of unary increment operator.");
160 if (likely(native_flag)) {
161 unsigned int result_u = val.native + 1;
162 int result = val.native + 1;
163 if (unlikely((static_cast<int>(result_u) != result) || (val.native > 0 && result < 0))) {
164 BIGNUM *val_openssl = to_openssl(val.native);
165 BIGNUM *one = BN_new();
166 BN_set_word(one, 1);
167 BN_add(val_openssl, val_openssl, one);
168 BN_free(one);
169 native_flag = FALSE;
170 val.openssl = val_openssl;
171 } else {
172 val.native++;
173 }
174 } else {
175 BIGNUM *one = BN_new();
176 BN_set_word(one, 1);
177 BN_add(val.openssl, val.openssl, one);
178 BN_free(one);
179 }
180 return *this;
181 }
182
183 // A bit more specific than operator-().
184 INTEGER& INTEGER::operator--()
185 {
186 must_bound("Unbound integer operand of unary decrement operator.");
187 if (likely(native_flag)) {
188 if (unlikely(val.native == INT_MIN)) {
189 BIGNUM *val_openssl = to_openssl(val.native);
190 BIGNUM *one = BN_new();
191 BN_set_word(one, 1);
192 BN_sub(val_openssl, val_openssl, one);
193 BN_free(one);
194 native_flag = FALSE;
195 val.openssl = val_openssl;
196 } else {
197 val.native--;
198 }
199 } else {
200 BIGNUM *one = BN_new();
201 BN_set_word(one, 1);
202 BN_sub(val.openssl, val.openssl, one);
203 BN_free(one);
204 }
205 return *this;
206 }
207
208 INTEGER INTEGER::operator+() const
209 {
210 must_bound("Unbound integer operand of unary + operator.");
211 return *this;
212 }
213
214 INTEGER INTEGER::operator-() const
215 {
216 must_bound("Unbound integer operand of unary - operator (negation).");
217 if (likely(native_flag)) {
218 if (unlikely(val.native == INT_MIN)) {
219 BIGNUM *result = to_openssl(INT_MIN);
220 BN_set_negative(result, 0);
221 return INTEGER(result);
222 } else {
223 return INTEGER(-val.native);
224 }
225 } else {
226 BIGNUM *int_max_plus_one = to_openssl(INT_MIN);
227 BN_set_negative(int_max_plus_one, 0);
228 int cmp = BN_cmp(val.openssl, int_max_plus_one);
229 BN_free(int_max_plus_one);
230 if (unlikely(cmp == 0)) {
231 return INTEGER(INT_MIN);
232 } else {
233 BIGNUM *result = BN_dup(val.openssl);
234 BN_set_negative(result, !BN_is_negative(result));
235 return INTEGER(result);
236 }
237 }
238 }
239
240 INTEGER INTEGER::operator+(int other_value) const
241 {
242 must_bound("Unbound left operand of integer addition.");
243 // Don't call out if slow. Implement this specific case right here.
244 return *this + INTEGER(other_value);
245 }
246
247 INTEGER INTEGER::operator+(const INTEGER& other_value) const
248 {
249 must_bound("Unbound left operand of integer addition.");
250 other_value.must_bound("Unbound right operand of integer addition.");
251 // *this + other_value = *this add other_value
252 // *this + -other_value = *this sub other_value
253 // -*this + other_value = other_value sub *this
254 // -*this + -other_value = -(*this add other_value)
255 // Use only inline functions and BN_* directly. Call out for operator- in
256 // the beginning.
257 boolean this_neg = native_flag ? (val.native < 0)
258 : BN_is_negative(val.openssl);
259 boolean other_value_neg = other_value.native_flag
260 ? (other_value.val.native < 0) : BN_is_negative(other_value.val.openssl);
261 boolean result_neg = this_neg && other_value_neg;
262 if (!this_neg && other_value_neg) return operator-(-other_value);
263 if (this_neg && !other_value_neg) return other_value.operator-(-(*this));
264 if (likely(native_flag)) {
265 if (likely(other_value.native_flag)) {
266 unsigned int result_u = val.native + other_value.val.native;
267 int result = val.native + other_value.val.native;
268 if ((static_cast<int>(result_u) != result) || (!result_neg &&
269 result < 0) || (result_neg && result > 0)) {
270 // We can safely assume that the sum of two non-negative int values
271 // fit in an unsigned int. limits.h says:
272 // # define INT_MAX 2147483647
273 // # define UINT_MAX 4294967295
274 BIGNUM *this_int = to_openssl(val.native);
275 BIGNUM *other_val_int = to_openssl(other_value.val.native);
276 BN_add(this_int, this_int, other_val_int);
277 BN_free(other_val_int);
278 return INTEGER(this_int);
279 } else {
280 return INTEGER(result);
281 }
282 } else {
283 // int (>= 0) + BIGNUM == BIGNUM.
284 BIGNUM *this_int = to_openssl(val.native);
285 BN_add(this_int, this_int, other_value.val.openssl);
286 return INTEGER(this_int);
287 }
288 } else {
289 // BIGNUM + int (>= 0) == BIGNUM.
290 BIGNUM *result = BN_new();
291 BIGNUM *other_value_int;
292 other_value_int = other_value.native_flag
293 ? to_openssl(other_value.val.native) : other_value.val.openssl;
294 BN_add(result, val.openssl, other_value_int);
295 if (likely(other_value.native_flag)) BN_free(other_value_int);
296 return INTEGER(result);
297 }
298 }
299
300 INTEGER INTEGER::operator-(int other_value) const
301 {
302 must_bound("Unbound left operand of integer subtraction.");
303 return *this - INTEGER(other_value);
304 }
305
306 INTEGER INTEGER::operator-(const INTEGER& other_value) const
307 {
308 must_bound("Unbound left operand of integer subtraction.");
309 other_value.must_bound("Unbound right operand of integer subtraction.");
310 // *this - other_value = *this sub other_value
311 // -*this - other_value = -(*this add other_value)
312 // *this - -other_value = *this add other_value
313 // -*this - -other_value = -*this add other_value = other_value sub *this
314 boolean this_neg = native_flag ? (val.native < 0)
315 : BN_is_negative(val.openssl);
316 boolean other_value_neg = other_value.native_flag
317 ? (other_value.val.native < 0) : BN_is_negative(other_value.val.openssl);
318 if (!this_neg && other_value_neg) return operator+(-other_value);
319 if (this_neg && !other_value_neg) return -other_value.operator+(-(*this));
320 if (likely(native_flag)) {
321 if (likely(other_value.native_flag)) {
322 // Since both operands are non-negative the most negative result of a
323 // subtraction can be -INT_MAX and according to limits.h:
324 // # define INT_MIN (-INT_MAX - 1)
325 return INTEGER(val.native - other_value.val.native);
326 } else {
327 BIGNUM *this_int = to_openssl(val.native);
328 BN_sub(this_int, this_int, other_value.val.openssl);
329 // The result can be small enough to fit in int. Back conversion is a
330 // costly operation using strings all the time.
331 if (BN_num_bits(this_int) <= (int)sizeof(int) * 8 - 1) {
332 char *result_str = BN_bn2dec(this_int);
333 RInt result = string2RInt(result_str);
334 OPENSSL_free(result_str);
335 BN_free(this_int);
336 return INTEGER(result);
337 } else {
338 return INTEGER(this_int);
339 }
340 }
341 } else {
342 BIGNUM *result = BN_new();
343 BIGNUM *other_value_int = other_value.native_flag ?
344 to_openssl(other_value.val.native) : other_value.val.openssl;
345 BN_sub(result, val.openssl, other_value_int);
346 if (other_value.native_flag) BN_free(other_value_int);
347 if (BN_num_bits(result) <= (int)sizeof(int) * 8 - 1) {
348 char *result_str = BN_bn2dec(result);
349 RInt result_int = string2RInt(result_str);
350 OPENSSL_free(result_str);
351 BN_free(result);
352 return INTEGER(result_int);
353 } else {
354 return INTEGER(result);
355 }
356 }
357 }
358
359 INTEGER INTEGER::operator*(int other_value) const
360 {
361 must_bound("Unbound left operand of integer multiplication.");
362 return *this * INTEGER(other_value);
363 }
364
365 INTEGER INTEGER::operator*(const INTEGER& other_value) const
366 {
367 must_bound("Unbound left operand of integer multiplication.");
368 other_value.must_bound("Unbound right operand of integer multiplication.");
369 if ((native_flag && val.native == 0) || (other_value.native_flag &&
370 other_value.val.native == 0)) return INTEGER((int)0);
371 if (likely(native_flag)) {
372 if (likely(other_value.native_flag)) {
373 // TODO: Improve.
374 if (likely(abs(val.native) < 32768 && abs(other_value.val.native) < 32768)) {
375 return INTEGER(val.native * other_value.val.native);
376 } else {
377 BIGNUM *this_int = to_openssl(val.native);
378 BIGNUM *other_value_int = to_openssl(other_value.val.native);
379 BN_CTX *ctx = BN_CTX_new();
380 BN_CTX_init(ctx);
381 BN_mul(this_int, this_int, other_value_int, ctx);
382 BN_CTX_free(ctx);
383 BN_free(other_value_int);
384 if (BN_num_bits(this_int) < (int)sizeof(int) * 8) {
385 BN_free(this_int);
386 return INTEGER(val.native * other_value.val.native);
387 } else {
388 return INTEGER(this_int);
389 }
390 }
391 } else {
392 BIGNUM *this_int = to_openssl(val.native);
393 BN_CTX *ctx = BN_CTX_new();
394 BN_CTX_init(ctx);
395 BN_mul(this_int, this_int, other_value.val.openssl, ctx);
396 BN_CTX_free(ctx);
397 return INTEGER(this_int);
398 }
399 } else {
400 BIGNUM *result = BN_new();
401 BIGNUM *other_value_int = NULL;
402 BN_CTX *ctx = BN_CTX_new();
403 BN_CTX_init(ctx);
404 other_value_int = other_value.native_flag
405 ? to_openssl(other_value.val.native) : other_value.val.openssl;
406 BN_mul(result, val.openssl, other_value_int, ctx);
407 BN_CTX_free(ctx);
408 if (likely(other_value.native_flag)) BN_free(other_value_int);
409 return INTEGER(result);
410 }
411 }
412
413 INTEGER INTEGER::operator/(int other_value) const
414 {
415 must_bound("Unbound left operand of integer division.");
416 if (other_value == 0) TTCN_error("Integer division by zero.");
417 return *this / INTEGER(other_value);
418 }
419
420 INTEGER INTEGER::operator/(const INTEGER& other_value) const
421 {
422 must_bound("Unbound left operand of integer division.");
423 other_value.must_bound("Unbound right operand of integer division.");
424 if (other_value == 0) TTCN_error("Integer division by zero.");
425 if (native_flag && val.native == 0) return INTEGER((int)0);
426 if (likely(native_flag)) {
427 if (likely(other_value.native_flag)) {
428 return INTEGER(val.native / other_value.val.native);
429 } else {
430 BIGNUM *this_int = to_openssl(val.native);
431 BN_CTX *ctx = BN_CTX_new();
432 BN_CTX_init(ctx);
433 BN_div(this_int, NULL, this_int, other_value.val.openssl, ctx);
434 BN_CTX_free(ctx);
435 if (BN_num_bits(this_int) <= (int)sizeof(int) * 8 - 1) {
436 char *result_str = BN_bn2dec(this_int);
437 RInt result = string2RInt(result_str);
438 OPENSSL_free(result_str);
439 BN_free(this_int);
440 return INTEGER(result);
441 } else {
442 return INTEGER(this_int);
443 }
444 }
445 } else {
446 BIGNUM *result = BN_new();
447 BIGNUM *other_value_int = NULL;
448 BN_CTX *ctx = BN_CTX_new();
449 BN_CTX_init(ctx);
450 other_value_int = other_value.native_flag
451 ? to_openssl(other_value.val.native) : other_value.val.openssl;
452 BN_div(result, NULL, val.openssl, other_value_int, ctx);
453 if (likely(other_value.native_flag)) BN_free(other_value_int);
454 BN_CTX_free(ctx);
455 if (BN_num_bits(result) <= (int)sizeof(int) * 8 - 1) {
456 char *result_str = BN_bn2dec(result);
457 RInt result_i = string2RInt(result_str);
458 OPENSSL_free(result_str);
459 BN_free(result);
460 return INTEGER(result_i);
461 } else {
462 return INTEGER(result);
463 }
464 }
465 }
466
467 boolean INTEGER::operator==(int other_value) const
468 {
469 must_bound("Unbound left operand of integer comparison.");
470 if (likely(native_flag)) {
471 return val.native == other_value;
472 } else {
473 BIGNUM *other_value_int = to_openssl(other_value);
474 int equal = BN_cmp(val.openssl, other_value_int);
475 BN_free(other_value_int);
476 return equal == 0;
477 }
478 }
479
480 boolean INTEGER::operator==(const INTEGER& other_value) const
481 {
482 must_bound("Unbound left operand of integer comparison.");
483 other_value.must_bound("Unbound right operand of integer comparison.");
484 if (likely(native_flag)) {
485 if (likely(other_value.native_flag)) {
486 return val.native == other_value.val.native;
487 } else {
488 BIGNUM *this_int = to_openssl(val.native);
489 int equal = BN_cmp(this_int, other_value.val.openssl);
490 BN_free(this_int);
491 return equal == 0;
492 }
493 } else {
494 if (likely(other_value.native_flag)) {
495 BIGNUM *other_value_int = to_openssl(other_value.val.native);
496 int equal = BN_cmp(val.openssl, other_value_int);
497 BN_free(other_value_int);
498 return equal == 0;
499 } else {
500 return BN_cmp(val.openssl, other_value.val.openssl) == 0;
501 }
502 }
503 }
504
505 boolean INTEGER::operator<(int other_value) const
506 {
507 must_bound("Unbound left operand of integer comparison.");
508 return *this < INTEGER(other_value);
509 }
510
511 boolean INTEGER::operator<(const INTEGER& other_value) const
512 {
513 must_bound("Unbound left operand of integer comparison.");
514 other_value.must_bound("Unbound right operand of integer comparison.");
515 if (likely(native_flag)) {
516 if (likely(other_value.native_flag)) {
517 return val.native < other_value.val.native;
518 } else {
519 BIGNUM *this_int = to_openssl(val.native);
520 int equal = BN_cmp(this_int, other_value.val.openssl);
521 BN_free(this_int);
522 return equal == -1;
523 }
524 } else {
525 if (likely(other_value.native_flag)) {
526 BIGNUM *other_value_int = to_openssl(other_value.val.native);
527 int equal = BN_cmp(val.openssl, other_value_int);
528 BN_free(other_value_int);
529 return equal == -1;
530 } else {
531 return BN_cmp(val.openssl, other_value.val.openssl) == -1;
532 }
533 }
534 }
535
536 boolean INTEGER::operator>(int other_value) const
537 {
538 must_bound("Unbound left operand of integer comparison.");
539 return *this > INTEGER(other_value);
540 }
541
542 boolean INTEGER::operator>(const INTEGER& other_value) const
543 {
544 // A simple call to operator< and operator== would be much simplier.
545 must_bound("Unbound left operand of integer comparison.");
546 other_value.must_bound("Unbound right operand of integer comparison.");
547 if (likely(native_flag)) {
548 if (likely(other_value.native_flag)) {
549 return val.native > other_value.val.native;
550 } else {
551 BIGNUM *this_int = to_openssl(val.native);
552 int equal = BN_cmp(this_int, other_value.val.openssl);
553 BN_free(this_int);
554 return equal == 1;
555 }
556 } else {
557 if (likely(other_value.native_flag)) {
558 BIGNUM *other_value_int = to_openssl(other_value.val.native);
559 int equal = BN_cmp(val.openssl, other_value_int);
560 BN_free(other_value_int);
561 return equal == 1;
562 } else {
563 return BN_cmp(val.openssl, other_value.val.openssl) == 1;
564 }
565 }
566 }
567
568 INTEGER::operator int() const
569 {
570 must_bound("Using the value of an unbound integer variable.");
571 if (unlikely(!native_flag))
572 TTCN_error("Invalid conversion of a large integer value");
573 return val.native;
574 }
575
576 // To avoid ambiguity we have a separate function to convert our INTEGER
577 // object to long long.
578 long long int INTEGER::get_long_long_val() const
579 {
580 must_bound("Using the value of an unbound integer variable.");
581 if (likely(native_flag)) return val.native;
582 size_t slot_size = sizeof(BN_ULONG);
583 bool is_negative = BN_is_negative(val.openssl);
584 long long int ret_val = 0;
585 if (unlikely(val.openssl->top == 0)) return 0;
586 // It feels so bad accessing a BIGNUM directly, but faster than string
587 // conversion...
588 else if (likely(val.openssl->top == 1))
589 return !is_negative ? val.openssl->d[0] : -val.openssl->d[0];
590 ret_val = val.openssl->d[val.openssl->top - 1];
591 // From now, shift by 8.
592 for (int i = val.openssl->top - 2; i >= 0; i--) {
593 for (int j = slot_size - 1; j >= 0; j--) {
594 unsigned char tmp = (val.openssl->d[i] >> 8 * j) & 0xff;
595 ret_val <<= 8;
596 ret_val += tmp;
597 }
598 }
599 return !is_negative ? ret_val : -ret_val;
600 }
601
602 void INTEGER::set_long_long_val(long long int other_value)
603 {
604 clean_up();
605 bound_flag = TRUE;
606 // Seems to be a native. It's very strange if someone calls this with a
607 // small number. A simple assignment should be used for such values.
608 if (unlikely((RInt)other_value == other_value)) {
609 native_flag = TRUE;
610 val.native = other_value;
611 return;
612 }
613 native_flag = FALSE;
614 val.openssl = BN_new();
615 // Make it 0.
616 BN_zero(val.openssl);
617 bool is_negative = other_value < 0;
618 unsigned long long int tmp = !is_negative ? other_value : -other_value;
619 for (int i = sizeof(long long int) - 1; i >= 0; i--) {
620 BN_add_word(val.openssl, (tmp >> 8 * i) & 0xff);
621 if (i) BN_lshift(val.openssl, val.openssl, 8);
622 }
623 BN_set_negative(val.openssl, is_negative ? 1 : 0);
624 }
625
626 void INTEGER::log() const
627 {
628 if (likely(bound_flag)) {
629 if (likely(native_flag)) {
630 TTCN_Logger::log_event("%d", val.native);
631 } else {
632 char *tmp = BN_bn2dec(val.openssl);
633 TTCN_Logger::log_event("%s", tmp);
634 OPENSSL_free(tmp);
635 }
636 } else {
637 TTCN_Logger::log_event_unbound();
638 }
639 }
640
641 void INTEGER::set_param(Module_Param& param)
642 {
643 param.basic_check(Module_Param::BC_VALUE, "integer value");
644 if (param.get_type()!=Module_Param::MP_Integer) param.type_error("integer value");
645 clean_up();
646 bound_flag = TRUE;
647 const int_val_t* const int_val = param.get_integer();
648 native_flag = int_val->is_native();
649 if (likely(native_flag)){
650 val.native = int_val->get_val();
651 } else {
652 val.openssl = BN_dup(int_val->get_val_openssl());
653 }
654 }
655
656 void INTEGER::encode_text(Text_Buf& text_buf) const
657 {
658 must_bound("Text encoder: Encoding an unbound integer value.");
659 if (likely(native_flag)) {
660 text_buf.push_int(val.native);
661 } else {
662 int_val_t *tmp = new int_val_t(BN_dup(val.openssl));
663 text_buf.push_int(*tmp);
664 delete tmp;
665 }
666 }
667
668 void INTEGER::decode_text(Text_Buf& text_buf)
669 {
670 clean_up();
671 bound_flag = TRUE;
672 int_val_t tmp(text_buf.pull_int());
673 if (likely(tmp.native_flag)) {
674 native_flag = TRUE;
675 val.native = tmp.get_val();
676 } else {
677 native_flag = FALSE;
678 val.openssl = BN_dup(tmp.get_val_openssl());
679 }
680 }
681
682 void INTEGER::encode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf,
683 TTCN_EncDec::coding_t p_coding, ...) const
684 {
685 va_list pvar;
686 va_start(pvar, p_coding);
687 switch(p_coding) {
688 case TTCN_EncDec::CT_BER: {
689 TTCN_EncDec_ErrorContext ec("While BER-encoding type '%s': ", p_td.name);
690 unsigned BER_coding=va_arg(pvar, unsigned);
691 BER_encode_chk_coding(BER_coding);
692 ASN_BER_TLV_t *tlv=BER_encode_TLV(p_td, BER_coding);
693 tlv->put_in_buffer(p_buf);
694 ASN_BER_TLV_t::destruct(tlv);
695 break;}
696 case TTCN_EncDec::CT_RAW: {
697 TTCN_EncDec_ErrorContext ec("While RAW-encoding type '%s': ", p_td.name);
698 if(!p_td.raw)
699 TTCN_EncDec_ErrorContext::error_internal
700 ("No RAW descriptor available for type '%s'.", p_td.name);
701 RAW_enc_tr_pos rp;
702 rp.level=0;
703 rp.pos=NULL;
704 RAW_enc_tree root(TRUE,NULL,&rp,1,p_td.raw);
705 RAW_encode(p_td, root);
706 root.put_to_buf(p_buf);
707 break;}
708 case TTCN_EncDec::CT_TEXT: {
709 TTCN_EncDec_ErrorContext ec("While TEXT-encoding type '%s': ", p_td.name);
710 if(!p_td.text)
711 TTCN_EncDec_ErrorContext::error_internal
712 ("No TEXT descriptor available for type '%s'.", p_td.name);
713 TEXT_encode(p_td,p_buf);
714 break;}
715 case TTCN_EncDec::CT_XER: {
716 TTCN_EncDec_ErrorContext ec("While XER-encoding type '%s': ", p_td.name);
717 unsigned XER_coding=va_arg(pvar, unsigned);
718 XER_encode(*p_td.xer, p_buf, XER_coding, 0, 0);
719 break;}
720 case TTCN_EncDec::CT_JSON: {
721 TTCN_EncDec_ErrorContext ec("While JSON-encoding type '%s': ", p_td.name);
722 if(!p_td.json)
723 TTCN_EncDec_ErrorContext::error_internal
724 ("No JSON descriptor available for type '%s'.", p_td.name);
725 JSON_Tokenizer tok(va_arg(pvar, int) != 0);
726 JSON_encode(p_td, tok);
727 p_buf.put_s(tok.get_buffer_length(), (const unsigned char*)tok.get_buffer());
728 break;}
729 default:
730 TTCN_error("Unknown coding method requested to encode type '%s'",
731 p_td.name);
732 }
733 va_end(pvar);
734 }
735
736 void INTEGER::decode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf,
737 TTCN_EncDec::coding_t p_coding, ...)
738 {
739 va_list pvar;
740 va_start(pvar, p_coding);
741 switch(p_coding) {
742 case TTCN_EncDec::CT_BER: {
743 TTCN_EncDec_ErrorContext ec("While BER-decoding type '%s': ", p_td.name);
744 unsigned L_form=va_arg(pvar, unsigned);
745 ASN_BER_TLV_t tlv;
746 BER_decode_str2TLV(p_buf, tlv, L_form);
747 BER_decode_TLV(p_td, tlv, L_form);
748 if(tlv.isComplete) p_buf.increase_pos(tlv.get_len());
749 break;}
750 case TTCN_EncDec::CT_RAW: {
751 TTCN_EncDec_ErrorContext ec("While RAW-decoding type '%s': ", p_td.name);
752 if(!p_td.raw)
753 TTCN_EncDec_ErrorContext::error_internal
754 ("No RAW descriptor available for type '%s'.", p_td.name);
755 raw_order_t order;
756 switch(p_td.raw->top_bit_order){
757 case TOP_BIT_LEFT:
758 order=ORDER_LSB;
759 break;
760 case TOP_BIT_RIGHT:
761 default:
762 order=ORDER_MSB;
763 }
764 if(RAW_decode(p_td, p_buf, p_buf.get_len()*8, order)<0)
765 ec.error(TTCN_EncDec::ET_INCOMPL_MSG,
766 "Can not decode type '%s', because invalid or incomplete"
767 " message was received"
768 , p_td.name);
769 break;}
770 case TTCN_EncDec::CT_TEXT: {
771 Limit_Token_List limit;
772 TTCN_EncDec_ErrorContext ec("While TEXT-decoding type '%s': ", p_td.name);
773 if(!p_td.text)
774 TTCN_EncDec_ErrorContext::error_internal
775 ("No TEXT descriptor available for type '%s'.", p_td.name);
776 const unsigned char *b=p_buf.get_data();
777 if(b[p_buf.get_len()-1]!='\0'){
778 p_buf.set_pos(p_buf.get_len());
779 p_buf.put_zero(8,ORDER_LSB);
780 p_buf.rewind();
781 }
782 if(TEXT_decode(p_td,p_buf,limit)<0)
783 ec.error(TTCN_EncDec::ET_INCOMPL_MSG,
784 "Can not decode type '%s', because invalid or incomplete"
785 " message was received"
786 , p_td.name);
787 break;}
788 case TTCN_EncDec::CT_XER: {
789 TTCN_EncDec_ErrorContext ec("While XER-decoding type '%s': ", p_td.name);
790 unsigned XER_coding=va_arg(pvar, unsigned);
791 XmlReaderWrap reader(p_buf);
792 for (int success = reader.Read(); success==1; success=reader.Read()) {
793 int type = reader.NodeType();
794 if (type==XML_READER_TYPE_ELEMENT)
795 break;
796 }
797 XER_decode(*p_td.xer, reader, XER_coding, 0);
798 size_t bytes = reader.ByteConsumed();
799 p_buf.set_pos(bytes);
800 break;}
801 case TTCN_EncDec::CT_JSON: {
802 TTCN_EncDec_ErrorContext ec("While JSON-decoding type '%s': ", p_td.name);
803 if(!p_td.json)
804 TTCN_EncDec_ErrorContext::error_internal
805 ("No JSON descriptor available for type '%s'.", p_td.name);
806 JSON_Tokenizer tok((const char*)p_buf.get_data(), p_buf.get_len());
807 if(JSON_decode(p_td, tok, false)<0)
808 ec.error(TTCN_EncDec::ET_INCOMPL_MSG,
809 "Can not decode type '%s', because invalid or incomplete"
810 " message was received"
811 , p_td.name);
812 p_buf.set_pos(tok.get_buf_pos());
813 break;}
814 default:
815 TTCN_error("Unknown coding method requested to decode type '%s'",
816 p_td.name);
817 }
818 va_end(pvar);
819 }
820
821 ASN_BER_TLV_t *INTEGER::BER_encode_TLV(const TTCN_Typedescriptor_t& p_td,
822 unsigned p_coding) const
823 {
824 BER_chk_descr(p_td);
825 ASN_BER_TLV_t *new_tlv = BER_encode_chk_bound(is_bound());
826 if (!new_tlv) {
827 if (native_flag) {
828 new_tlv = BER_encode_TLV_INTEGER(p_coding, val.native);
829 } else {
830 // Temporary.
831 int_val_t *tmp = new int_val_t(BN_dup(val.openssl));
832 new_tlv = BER_encode_TLV_INTEGER(p_coding, *tmp);
833 delete tmp;
834 }
835 }
836 new_tlv = ASN_BER_V2TLV(new_tlv, p_td, p_coding);
837 return new_tlv;
838 }
839
840 boolean INTEGER::BER_decode_TLV(const TTCN_Typedescriptor_t& p_td,
841 const ASN_BER_TLV_t& p_tlv,
842 unsigned L_form)
843 {
844 clean_up();
845 bound_flag = FALSE;
846 BER_chk_descr(p_td);
847 ASN_BER_TLV_t stripped_tlv;
848 BER_decode_strip_tags(*p_td.ber, p_tlv, L_form, stripped_tlv);
849 TTCN_EncDec_ErrorContext ec("While decoding INTEGER type: ");
850 int_val_t tmp;
851 boolean ret_val = BER_decode_TLV_INTEGER(stripped_tlv, L_form, tmp);
852 if (tmp.is_native()) {
853 native_flag = TRUE;
854 val.native = tmp.get_val();
855 } else {
856 native_flag = FALSE;
857 val.openssl = BN_dup(tmp.get_val_openssl());
858 }
859 if (ret_val) bound_flag = TRUE;
860 return ret_val;
861 }
862
863 int INTEGER::TEXT_decode(const TTCN_Typedescriptor_t& p_td,
864 TTCN_Buffer& buff, Limit_Token_List& limit, boolean no_err, boolean /*first_call*/)
865 {
866 int decoded_length = 0;
867 int str_len = 0;
868 if (p_td.text->begin_decode) {
869 int tl;
870 if ((tl = p_td.text->begin_decode->match_begin(buff)) < 0) {
871 if (no_err) return -1;
872 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR,
873 "The specified token '%s' not found for '%s': ",
874 (const char*)*(p_td.text->begin_decode), p_td.name);
875 return 0;
876 }
877 decoded_length += tl;
878 buff.increase_pos(tl);
879 }
880 if (buff.get_read_len() <= 1 && no_err) return -TTCN_EncDec::ET_LEN_ERR;
881 if (p_td.text->select_token) {
882 int tl;
883 if ((tl = p_td.text->select_token->match_begin(buff)) < 0) {
884 if (no_err) return -1;
885 else tl = 0;
886 }
887 str_len = tl;
888 } else if ( p_td.text->val.parameters
889 && p_td.text->val.parameters->decoding_params.min_length != -1) {
890 str_len = p_td.text->val.parameters->decoding_params.min_length;
891 } else if (p_td.text->end_decode) {
892 int tl;
893 if ((tl = p_td.text->end_decode->match_first(buff)) < 0) {
894 if (no_err) return -1;
895 else tl = 0;
896 }
897 str_len = tl;
898 } else if (limit.has_token()) {
899 int tl;
900 if ((tl = limit.match(buff)) < 0) {
901 if (no_err) return -1;
902 else tl = 0;
903 }
904 str_len = tl;
905 } else {
906 int tl;
907 if ((tl = integer_value_match.match_begin(buff)) < 0) {
908 if (no_err) return -1;
909 else tl = 0;
910 }
911 str_len = tl;
912 }
913 boolean err = FALSE;
914 if (str_len > 0) {
915 int offs = 0;
916 char *atm = (char*)Malloc(str_len + 1); // sizeof(char) == 1 by definition
917 const char *b = (const char*)buff.get_read_data();
918 memcpy(atm, b, str_len);
919 atm[str_len] = 0;
920 // 0x2d ('-')
921 // 0x20 (' ')
922 // 0x30 ('0')
923 int neg = *atm == 0x2d ? 1 : 0;
924 if (!*(atm + neg)) {
925 for (offs = neg; *(atm + offs) == 0x30; offs++) ; // E.g. 0, -0, 00001234, -00001234.
926 if (neg && offs > 1) *(atm + offs - 1) = *atm; // E.g. -00001234 -> -000-1234.
927 offs -= neg;
928 } else {
929 for(; atm[offs] == 0x20; offs++) ;
930 }
931 clean_up();
932 if (0 == strlen(atm + offs) || 0 == from_string(atm+offs)) {
933 err = TRUE;
934 native_flag = TRUE;
935 val.native = 0;
936 }
937 Free(atm);
938 buff.increase_pos(str_len);
939 decoded_length += str_len;
940 } else {
941 err = TRUE;
942 }
943 if (err) {
944 if (no_err) return -1;
945 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR,
946 "Can not decode a valid integer for '%s': ", p_td.name);
947 }
948 if (p_td.text->end_decode) {
949 int tl;
950 if ((tl = p_td.text->end_decode->match_begin(buff)) < 0) {
951 if (no_err) return -1;
952 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR,
953 "The specified token '%s' not found for '%s': ",
954 (const char*)*(p_td.text->end_decode), p_td.name);
955 return 0;
956 }
957 decoded_length += tl;
958 buff.increase_pos(tl);
959 }
960 bound_flag = TRUE;
961 return decoded_length;
962 }
963
964 int INTEGER::TEXT_encode(const TTCN_Typedescriptor_t& p_td,
965 TTCN_Buffer& buff) const
966 {
967 int encoded_length = 0;
968 if (p_td.text->begin_encode) {
969 buff.put_cs(*p_td.text->begin_encode);
970 encoded_length += p_td.text->begin_encode->lengthof();
971 }
972 if (!is_bound()) {
973 TTCN_EncDec_ErrorContext::error
974 (TTCN_EncDec::ET_UNBOUND,"Encoding an unbound value.");
975 if (p_td.text->end_encode) {
976 buff.put_cs(*p_td.text->end_encode);
977 encoded_length+=p_td.text->end_encode->lengthof();
978 }
979 return encoded_length;
980 }
981 char *tmp_str;
982 // Temporary.
983 if (native_flag) tmp_str = mprintf("%d", val.native);
984 else tmp_str = BN_bn2dec(val.openssl);
985 CHARSTRING ch(tmp_str);
986 if (native_flag) Free(tmp_str);
987 else OPENSSL_free(tmp_str);
988 if (p_td.text->val.parameters == NULL) {
989 buff.put_cs(ch);
990 encoded_length += ch.lengthof();
991 } else {
992 TTCN_TEXTdescriptor_values params = p_td.text->val.parameters
993 ->coding_params;
994 if (params.min_length < 0) {
995 buff.put_cs(ch);
996 encoded_length += ch.lengthof();
997 } else {
998 unsigned char *p = NULL;
999 int a = 0;
1000 size_t len = params.min_length + 1;
1001 buff.get_end(p, len);
1002 if (params.leading_zero) {
1003 if (native_flag) {
1004 a = snprintf((char*)p, len, "%0*d", params.min_length, val.native);
1005 } else {
1006 int chlen = ch.lengthof(), pad = 0;
1007 int neg = native_flag ? (val.native < 0) : BN_is_negative(val.openssl);
1008 if (params.min_length > chlen)
1009 pad = params.min_length - chlen + neg;
1010 // `sprintf' style.
1011 if (neg) *p = 0x2d;
1012 memset(p + neg, 0x30, pad);
1013 for (int i = 0; i < chlen - neg; i++)
1014 p[i + pad] = ch[i + neg].get_char();
1015 a += pad + chlen - neg;
1016 }
1017 } else {
1018 a = snprintf((char*)p, len, "%*s", p_td.text->val.parameters->
1019 coding_params.min_length, (const char*)ch);
1020 }
1021 buff.increase_length(a);
1022 encoded_length += a;
1023 }
1024 }
1025 if (p_td.text->end_encode) {
1026 buff.put_cs(*p_td.text->end_encode);
1027 encoded_length += p_td.text->end_encode->lengthof();
1028 }
1029 return encoded_length;
1030 }
1031
1032 int INTEGER::RAW_encode(const TTCN_Typedescriptor_t& p_td, RAW_enc_tree& myleaf) const
1033 {
1034 if (!native_flag) return RAW_encode_openssl(p_td, myleaf);
1035 unsigned char *bc;
1036 int length = (p_td.raw->fieldlength + 7) / 8; // in bytes
1037 int value = val.native;
1038 boolean neg_sgbit = (value < 0) && (p_td.raw->comp == SG_SG_BIT);
1039 if (!is_bound()) {
1040 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND,
1041 "Encoding an unbound value.");
1042 value = 0;
1043 neg_sgbit = FALSE;
1044 }
1045 if (value != 0 && value == -value) {
1046 // value == -INT_MAX-1 a.k.a. INT_MIN a.k.a. 0x8000....
1047 INTEGER big_value(to_openssl(val.native)); // too big for native
1048 return big_value.RAW_encode_openssl(p_td, myleaf);
1049 }
1050 if (min_bits(value) > p_td.raw->fieldlength) {
1051 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_LEN_ERR,
1052 "There are insufficient bits to encode '%s' : ", p_td.name);
1053 value = 0; // substitute with zero
1054 }
1055 if ((value < 0) && (p_td.raw->comp == SG_NO)) {
1056 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_SIGN_ERR,
1057 "Unsigned encoding of a negative number: %s", p_td.name);
1058 value = -value;
1059 }
1060 if (neg_sgbit) value = -value;
1061 //myleaf.ext_bit=EXT_BIT_NO;
1062 if (myleaf.must_free) Free(myleaf.body.leaf.data_ptr);
1063 if (length > RAW_INT_ENC_LENGTH) { // does not fit in the small buffer
1064 myleaf.body.leaf.data_ptr = bc = (unsigned char*)Malloc(length * sizeof(*bc));
1065 myleaf.must_free = TRUE;
1066 myleaf.data_ptr_used = TRUE;
1067 }
1068 else bc = myleaf.body.leaf.data_array;
1069 for (int a = 0; a < length; a++) {
1070 bc[a] = value & 0xFF;
1071 value >>= 8;
1072 }
1073 if (neg_sgbit) {
1074 unsigned char mask = 0x01 << (p_td.raw->fieldlength - 1) % 8;
1075 bc[length - 1] |= mask;
1076 }
1077 return myleaf.length = p_td.raw->fieldlength;
1078 }
1079
1080 int INTEGER::RAW_encode_openssl(const TTCN_Typedescriptor_t& p_td,
1081 RAW_enc_tree& myleaf) const
1082 {
1083 unsigned char *bc = NULL;
1084 int length = (p_td.raw->fieldlength + 7) / 8;
1085 BIGNUM *D = BN_new();
1086 BN_copy(D, val.openssl);
1087 boolean neg_sgbit = (D->neg) && (p_td.raw->comp == SG_SG_BIT);
1088 if (!is_bound()) {
1089 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND,
1090 "Encoding an unbound value.");
1091 BN_clear(D);
1092 neg_sgbit = FALSE;
1093 }
1094 if (min_bits(D) > p_td.raw->fieldlength) {
1095 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_LEN_ERR,
1096 "There are insufficient bits to encode '%s': ", p_td.name);
1097 // `tmp = -((-tmp) & BitMaskTable[min_bits(tmp)]);' doesn't make any sense
1098 // at all for negative values. Just simply clear the value.
1099 BN_clear(D);
1100 neg_sgbit = FALSE;
1101 }
1102 if ((D->neg) && (p_td.raw->comp == SG_NO)) {
1103 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_SIGN_ERR,
1104 "Unsigned encoding of a negative number: %s", p_td.name);
1105 BN_set_negative(D, 0);
1106 neg_sgbit = FALSE;
1107 }
1108 // `if (neg_sgbit) tmp->neg = tmp->neg == 0;' is not needed, because the
1109 // sign is stored separately from the number. Default encoding of negative
1110 // values in 2's complement form.
1111 if (myleaf.must_free) Free(myleaf.body.leaf.data_ptr);
1112 if (length > RAW_INT_ENC_LENGTH) {
1113 myleaf.body.leaf.data_ptr = bc =
1114 (unsigned char *)Malloc(length * sizeof(*bc));
1115 myleaf.must_free = TRUE;
1116 myleaf.data_ptr_used = TRUE;
1117 } else {
1118 bc = myleaf.body.leaf.data_array;
1119 }
1120 boolean twos_compl = (D->neg) && !neg_sgbit;
1121 // Conversion to 2's complement.
1122 if (twos_compl) {
1123 BN_set_negative(D, 0);
1124 for (int a = 0; a < D->dmax; a++) D->d[a] = ~D->d[a];
1125 BN_add_word(D, 1);
1126 }
1127 int num_bytes = BN_num_bytes(D);
1128 for (int a = 0; a < length; a++) {
1129 if (twos_compl && num_bytes - 1 < a) bc[a] = 0xff;
1130 else bc[a] = (D->top ? D->d[0] : 0) & 0xff;
1131 BN_rshift(D, D, 8);
1132 }
1133 if (neg_sgbit) {
1134 unsigned char mask = 0x01 << (p_td.raw->fieldlength - 1) % 8;
1135 bc[length - 1] |= mask;
1136 }
1137 BN_free(D);
1138 return myleaf.length = p_td.raw->fieldlength;
1139 }
1140
1141 int INTEGER::RAW_decode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& buff,
1142 int limit, raw_order_t top_bit_ord, boolean no_err, int /*sel_field*/,
1143 boolean /*first_call*/)
1144 {
1145 bound_flag = FALSE;
1146 int prepaddlength = buff.increase_pos_padd(p_td.raw->prepadding);
1147 limit -= prepaddlength;
1148 int decode_length = p_td.raw->fieldlength;
1149 if (decode_length > limit) {
1150 if (no_err) return -TTCN_EncDec::ET_LEN_ERR;
1151 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_LEN_ERR,
1152 "There are not enough bits in the buffer to decode type %s (needed: %d, "
1153 "found: %d).", p_td.name, decode_length, limit);
1154 decode_length = limit;
1155 }
1156 int nof_unread_bits = buff.unread_len_bit();
1157 if (decode_length > nof_unread_bits) {
1158 if (no_err) return -TTCN_EncDec::ET_INCOMPL_MSG;
1159 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INCOMPL_MSG,
1160 "There are not enough bits in the buffer to decode type %s (needed: %d, "
1161 "found: %d).", p_td.name, decode_length, nof_unread_bits);
1162 decode_length = nof_unread_bits;
1163 }
1164 clean_up();
1165 if (decode_length < 0) return -1;
1166 else if (decode_length == 0) {
1167 native_flag = TRUE;
1168 val.native = 0;
1169 }
1170 else {
1171 int tmp = 0;
1172 int twos_compl = 0;
1173 unsigned char *data = (unsigned char *) Malloc((decode_length + 7) / 8);
1174 RAW_coding_par cp;
1175 boolean orders = FALSE;
1176 if (p_td.raw->bitorderinoctet == ORDER_MSB) orders = TRUE;
1177 if (p_td.raw->bitorderinfield == ORDER_MSB) orders = !orders;
1178 cp.bitorder = orders ? ORDER_MSB : ORDER_LSB;
1179 orders = FALSE;
1180 if (p_td.raw->byteorder == ORDER_MSB) orders = TRUE;
1181 if (p_td.raw->bitorderinfield == ORDER_MSB) orders = !orders;
1182 cp.byteorder = orders ? ORDER_MSB : ORDER_LSB;
1183 cp.fieldorder = p_td.raw->fieldorder;
1184 cp.hexorder = ORDER_LSB;
1185 buff.get_b((size_t) decode_length, data, cp, top_bit_ord);
1186 int end_pos = decode_length;
1187 int idx = (end_pos - 1) / 8;
1188 boolean negativ_num = FALSE;
1189 switch (p_td.raw->comp) {
1190 case SG_2COMPL:
1191 if (data[idx] >> ((end_pos - 1) % 8) & 0x01) {
1192 tmp = -1;
1193 twos_compl = 1;
1194 }
1195 break;
1196 case SG_NO:
1197 break;
1198 case SG_SG_BIT:
1199 negativ_num = (data[idx] >> ((end_pos - 1) % 8)) & 0x01;
1200 end_pos--;
1201 break;
1202 default:
1203 break;
1204 }
1205 if (end_pos < 9) {
1206 tmp <<= end_pos;
1207 tmp |= data[0] & BitMaskTable[end_pos];
1208 }
1209 else {
1210 idx = (end_pos - 1) / 8;
1211 tmp <<= (end_pos - 1) % 8 + 1;
1212 tmp |= data[idx--] & BitMaskTable[(end_pos - 1) % 8 + 1];
1213 if (decode_length > (RInt) sizeof(RInt) * 8 - 1) {
1214 BIGNUM *D = BN_new();
1215 BN_set_word(D, tmp);
1216 int pad = tmp == 0 ? 1 : 0;
1217 for (; idx >= 0; idx--) {
1218 if (pad && data[idx] != 0) {
1219 BN_set_word(D, data[idx] & 0xff);
1220 pad = 0;
1221 continue;
1222 }
1223 if (pad) continue;
1224 BN_lshift(D, D, 8);
1225 BN_add_word(D, data[idx] & 0xff);
1226 }
1227 if (twos_compl) {
1228 BIGNUM *D_tmp = BN_new();
1229 BN_set_bit(D_tmp, BN_num_bits(D));
1230 BN_sub(D, D, D_tmp);
1231 BN_free(D_tmp);
1232 }
1233 else if (negativ_num) {
1234 BN_set_negative(D, 1);
1235 }
1236 // Back to native. "BN_num_bits(D) + BN_is_negative(D) >
1237 // (RInt)sizeof(RInt) * 8 - !BN_is_negative(D)" was an over-complicated
1238 // condition.
1239 if (BN_num_bits(D) > (RInt) sizeof(RInt) * 8 - 1) {
1240 native_flag = FALSE;
1241 val.openssl = D;
1242 }
1243 else {
1244 native_flag = TRUE;
1245 val.native = BN_is_negative(D) ? -D->d[0] : D->d[0];
1246 BN_free(D);
1247 }
1248 Free(data);
1249 goto end;
1250 }
1251 else {
1252 for (; idx >= 0; idx--) {
1253 tmp <<= 8;
1254 tmp |= data[idx] & 0xff;
1255 }
1256 }
1257 }
1258 Free(data);
1259 native_flag = TRUE;
1260 val.native = negativ_num ? (RInt) -tmp : (RInt) tmp;
1261 }
1262 end: decode_length += buff.increase_pos_padd(p_td.raw->padding);
1263 bound_flag = TRUE;
1264 return decode_length + prepaddlength;
1265 }
1266
1267 int INTEGER::XER_encode(const XERdescriptor_t& p_td, TTCN_Buffer& p_buf,
1268 unsigned int flavor, int indent, embed_values_enc_struct_t*) const
1269 {
1270 if (!is_bound()) {
1271 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND,
1272 "Encoding an unbound integer value.");
1273 }
1274 int encoded_length = (int) p_buf.get_len();
1275
1276 flavor |= SIMPLE_TYPE;
1277 flavor &= ~XER_RECOF; // integer doesn't care
1278 if (begin_xml(p_td, p_buf, flavor, indent, false) == -1) --encoded_length;
1279
1280 char *tmp_str;
1281 if (native_flag)
1282 tmp_str = mprintf("%d", val.native);
1283 else
1284 tmp_str = BN_bn2dec(val.openssl);
1285 CHARSTRING value(tmp_str);
1286 if (native_flag)
1287 Free(tmp_str);
1288 else
1289 OPENSSL_free(tmp_str);
1290 p_buf.put_string(value);
1291
1292 end_xml(p_td, p_buf, flavor, indent, false);
1293
1294 return (int) p_buf.get_len() - encoded_length;
1295 }
1296
1297 int INTEGER::XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& reader,
1298 unsigned int flavor, embed_values_dec_struct_t*)
1299 {
1300 const boolean exer = is_exer(flavor);
1301 int depth = -1, success = reader.Ok(), type;
1302 const char * value = 0;
1303
1304 boolean own_tag = !(exer && (p_td.xer_bits & UNTAGGED)) && !is_exerlist(flavor);
1305
1306 if (!own_tag) goto tagless;
1307 if (exer && (p_td.xer_bits & XER_ATTRIBUTE)) {
1308 verify_name(reader, p_td, exer);
1309 tagless:
1310 value = (const char *)reader.Value();
1311
1312 for (; *value && isspace(*value); ++value) {}
1313 from_string(value);
1314 if (get_nof_digits() != (int)strlen(value) - (value[0] == '-') ? 1 : 0) {
1315 clean_up();
1316 }
1317 // Let the caller do reader.AdvanceAttribute();
1318 }
1319 else {
1320 for (; success == 1; success = reader.Read()) {
1321 type = reader.NodeType();
1322 if (XML_READER_TYPE_ELEMENT == type) {
1323 verify_name(reader, p_td, exer);
1324 if (reader.IsEmptyElement()) {
1325 if (exer && p_td.dfeValue != 0) {
1326 *this = *static_cast<const INTEGER*> (p_td.dfeValue);
1327 }
1328 reader.Read();
1329 break;
1330 }
1331 depth = reader.Depth();
1332 }
1333 else if (XML_READER_TYPE_TEXT == type && depth != -1) {
1334 value = (const char*) reader.Value();
1335 for (; *value && isspace(*value); ++value) {}
1336 from_string(value);
1337 if (get_nof_digits() != (int)strlen(value) - (value[0] == '-') ? 1 : 0) {
1338 clean_up();
1339 }
1340 }
1341 else if (XML_READER_TYPE_END_ELEMENT == type) {
1342 verify_end(reader, p_td, depth, exer);
1343 if (!bound_flag && exer && p_td.dfeValue != 0) {
1344 *this = *static_cast<const INTEGER*> (p_td.dfeValue);
1345 }
1346 reader.Read();
1347 break;
1348 }
1349 } // next read
1350 } // if not attribute
1351
1352 return 1;
1353 }
1354
1355 int INTEGER::get_nof_digits()
1356 {
1357 int digits = 0;
1358 if (native_flag) {
1359 RInt x = val.native;
1360 if (x == 0) return 1;
1361 if (x < 0) x = -x;
1362 while (x > 0) {
1363 ++digits;
1364 x /= 10;
1365 }
1366 } else {
1367 BIGNUM *x = BN_new();
1368 BN_copy(x, val.openssl);
1369 if (BN_is_zero(x)) return 1;
1370 x->neg = 0;
1371 while (!BN_is_zero(x)) {
1372 ++digits;
1373 BN_div_word(x, 10);
1374 }
1375 }
1376 return digits;
1377 }
1378
1379 int INTEGER::JSON_encode(const TTCN_Typedescriptor_t&, JSON_Tokenizer& p_tok) const
1380 {
1381 if (!is_bound()) {
1382 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND,
1383 "Encoding an unbound integer value.");
1384 return -1;
1385 }
1386 char* tmp_str = 0;
1387 if (native_flag) {
1388 tmp_str = mprintf("%d", val.native);
1389 } else {
1390 tmp_str = BN_bn2dec(val.openssl);
1391 }
1392
1393 int enc_len = p_tok.put_next_token(JSON_TOKEN_NUMBER, tmp_str);
1394
1395 if (native_flag) {
1396 Free(tmp_str);
1397 } else {
1398 OPENSSL_free(tmp_str);
1399 }
1400
1401 return enc_len;
1402 }
1403
1404 int INTEGER::JSON_decode(const TTCN_Typedescriptor_t& p_td, JSON_Tokenizer& p_tok, boolean p_silent)
1405 {
1406 json_token_t token = JSON_TOKEN_NONE;
1407 char* value = 0;
1408 size_t value_len = 0;
1409 int dec_len = 0;
1410 boolean use_default = p_td.json->default_value && 0 == p_tok.get_buffer_length();
1411 if (use_default) {
1412 // No JSON data in the buffer -> use default value
1413 value = (char*)p_td.json->default_value;
1414 value_len = strlen(value);
1415 } else {
1416 dec_len = p_tok.get_next_token(&token, &value, &value_len);
1417 }
1418 if (JSON_TOKEN_ERROR == token) {
1419 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_BAD_TOKEN_ERROR, "");
1420 return JSON_ERROR_FATAL;
1421 }
1422 else if (JSON_TOKEN_NUMBER == token || use_default) {
1423 char* number = mcopystrn(value, value_len);
1424 if (from_string(number) && (int)value_len == get_nof_digits() + ('-' == value[0] ? 1 : 0)) {
1425 bound_flag = true;
1426 } else {
1427 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_FORMAT_ERROR, "number", "integer");
1428 bound_flag = false;
1429 dec_len = JSON_ERROR_FATAL;
1430 }
1431 Free(number);
1432 } else {
1433 bound_flag = false;
1434 return JSON_ERROR_INVALID_TOKEN;
1435 }
1436 return dec_len;
1437 }
1438
1439
1440 // Global functions.
1441
1442 INTEGER operator+(int int_value, const INTEGER& other_value)
1443 {
1444 other_value.must_bound("Unbound right operand of integer addition.");
1445 return INTEGER(int_value) + other_value;
1446 }
1447
1448 INTEGER operator-(int int_value, const INTEGER& other_value)
1449 {
1450 other_value.must_bound("Unbound right operand of integer subtraction.");
1451 return INTEGER(int_value) - other_value;
1452 }
1453
1454 INTEGER operator*(int int_value, const INTEGER& other_value)
1455 {
1456 other_value.must_bound("Unbound right operand of integer multiplication.");
1457 return INTEGER(int_value) * other_value;
1458 }
1459
1460 INTEGER operator/(int int_value, const INTEGER& other_value)
1461 {
1462 other_value.must_bound("Unbound right operand of integer division.");
1463 if (other_value.get_val() == 0)
1464 TTCN_error("Integer division by zero.");
1465 return INTEGER(int_value) / other_value;
1466 }
1467
1468 INTEGER rem(int left_value, int right_value)
1469 {
1470 if (right_value == 0)
1471 TTCN_error("The right operand of rem operator is zero.");
1472 return INTEGER(left_value - right_value * (left_value / right_value));
1473 }
1474
1475 INTEGER rem(const INTEGER& left_value, const INTEGER& right_value)
1476 {
1477 left_value.must_bound("Unbound left operand of rem operator.");
1478 right_value.must_bound("Unbound right operand of rem operator.");
1479 return left_value - right_value * (left_value / right_value);
1480 }
1481
1482 INTEGER rem(const INTEGER& left_value, int right_value)
1483 {
1484 left_value.must_bound("Unbound left operand of rem operator.");
1485 return rem(left_value, INTEGER(right_value));
1486 }
1487
1488 INTEGER rem(int left_value, const INTEGER& right_value)
1489 {
1490 right_value.must_bound("Unbound right operand of rem operator.");
1491 return rem(INTEGER(left_value), right_value);
1492 }
1493
1494 INTEGER mod(int left_value, int right_value)
1495 {
1496 if (right_value < 0) right_value = -right_value;
1497 else if (right_value == 0)
1498 TTCN_error("The right operand of mod operator is zero.");
1499 if (left_value > 0) return rem(left_value, right_value);
1500 else {
1501 int result = rem(left_value, right_value);
1502 if (result == 0) return 0;
1503 else return INTEGER(right_value + result);
1504 }
1505 }
1506
1507 INTEGER mod(const INTEGER& left_value, const INTEGER& right_value)
1508 {
1509 left_value.must_bound("Unbound left operand of mod operator.");
1510 right_value.must_bound("Unbound right operand of mod operator.");
1511 INTEGER right_value_abs(right_value);
1512 if (right_value < 0) right_value_abs = -right_value_abs;
1513 else if (right_value == 0)
1514 TTCN_error("The right operand of mod operator is zero.");
1515 if (left_value > 0) {
1516 return rem(left_value, right_value_abs);
1517 } else {
1518 INTEGER result = rem(left_value, right_value_abs);
1519 if (result == 0) return INTEGER((int)0);
1520 else return INTEGER(right_value_abs + result);
1521 }
1522 }
1523
1524 INTEGER mod(const INTEGER& left_value, int right_value)
1525 {
1526 left_value.must_bound("Unbound left operand of mod operator.");
1527 return mod(left_value, INTEGER(right_value));
1528 }
1529
1530 INTEGER mod(int left_value, const INTEGER& right_value)
1531 {
1532 right_value.must_bound("Unbound right operand of mod operator.");
1533 return mod(INTEGER(left_value), right_value);
1534 }
1535
1536 boolean operator==(int int_value, const INTEGER& other_value)
1537 {
1538 other_value.must_bound("Unbound right operand of integer comparison.");
1539 return INTEGER(int_value) == other_value;
1540 }
1541
1542 boolean operator<(int int_value, const INTEGER& other_value)
1543 {
1544 other_value.must_bound("Unbound right operand of integer comparison.");
1545 return INTEGER(int_value) < other_value;
1546 }
1547
1548 boolean operator>(int int_value, const INTEGER& other_value)
1549 {
1550 other_value.must_bound("Unbound right operand of integer comparison.");
1551 return INTEGER(int_value) > other_value;
1552 }
1553
1554 // Integer template class.
1555
1556 void INTEGER_template::clean_up()
1557 {
1558 switch (template_selection) {
1559 case SPECIFIC_VALUE:
1560 if (unlikely(!int_val.native_flag)) BN_free(int_val.val.openssl);
1561 break;
1562 case VALUE_LIST:
1563 case COMPLEMENTED_LIST:
1564 delete [] value_list.list_value;
1565 break;
1566 case VALUE_RANGE:
1567 if (value_range.min_is_present && unlikely(!value_range.min_value.native_flag))
1568 BN_free(value_range.min_value.val.openssl);
1569 if (value_range.max_is_present && unlikely(!value_range.max_value.native_flag))
1570 BN_free(value_range.max_value.val.openssl);
1571 break;
1572 default:
1573 break;
1574 }
1575 template_selection = UNINITIALIZED_TEMPLATE;
1576 }
1577
1578 void INTEGER_template::copy_template(const INTEGER_template& other_value)
1579 {
1580 switch (other_value.template_selection) {
1581 case SPECIFIC_VALUE:
1582 int_val.native_flag = other_value.int_val.native_flag;
1583 if (likely(int_val.native_flag))
1584 int_val.val.native = other_value.int_val.val.native;
1585 else int_val.val.openssl = BN_dup(other_value.int_val.val.openssl);
1586 break;
1587 case OMIT_VALUE:
1588 case ANY_VALUE:
1589 case ANY_OR_OMIT:
1590 break;
1591 case VALUE_LIST:
1592 case COMPLEMENTED_LIST:
1593 value_list.n_values = other_value.value_list.n_values;
1594 value_list.list_value = new INTEGER_template[value_list.n_values];
1595 for (unsigned int i = 0; i < value_list.n_values; i++)
1596 value_list.list_value[i].copy_template(
1597 other_value.value_list.list_value[i]);
1598 break;
1599 case VALUE_RANGE:
1600 value_range.min_is_present = other_value.value_range.min_is_present;
1601 if (value_range.min_is_present) {
1602 value_range.min_value.native_flag = other_value.value_range.min_value.native_flag;
1603 if (likely(value_range.min_value.native_flag))
1604 value_range.min_value.val.native =
1605 other_value.value_range.min_value.val.native;
1606 else
1607 value_range.min_value.val.openssl =
1608 BN_dup(other_value.value_range.min_value.val.openssl);
1609 }
1610 value_range.max_is_present = other_value.value_range.max_is_present;
1611 if (value_range.max_is_present) {
1612 value_range.max_value.native_flag = other_value.value_range.max_value.native_flag;
1613 if (likely(value_range.max_value.native_flag))
1614 value_range.max_value.val.native =
1615 other_value.value_range.max_value.val.native;
1616 else
1617 value_range.max_value.val.openssl =
1618 BN_dup(other_value.value_range.max_value.val.openssl);
1619 }
1620 break;
1621 default:
1622 TTCN_error("Copying an uninitialized/unsupported integer template.");
1623 }
1624 set_selection(other_value);
1625 }
1626
1627 INTEGER_template::INTEGER_template()
1628 {
1629 }
1630
1631 INTEGER_template::INTEGER_template(template_sel other_value)
1632 : Base_Template(other_value)
1633 {
1634 check_single_selection(other_value);
1635 }
1636
1637 INTEGER_template::INTEGER_template(int other_value)
1638 : Base_Template(SPECIFIC_VALUE)
1639 {
1640 int_val.native_flag = TRUE;
1641 int_val.val.native = other_value;
1642 }
1643
1644 INTEGER_template::INTEGER_template(const INTEGER& other_value)
1645 : Base_Template(SPECIFIC_VALUE)
1646 {
1647 other_value.must_bound("Creating a template from an unbound integer "
1648 "value.");
1649 int_val_t other_value_int = other_value.get_val();
1650 int_val.native_flag = other_value_int.native_flag;
1651 if (likely(int_val.native_flag))
1652 int_val.val.native = other_value_int.val.native;
1653 else int_val.val.openssl = BN_dup(other_value_int.val.openssl);
1654 }
1655
1656 INTEGER_template::INTEGER_template(const OPTIONAL<INTEGER>& other_value)
1657 {
1658 switch (other_value.get_selection()) {
1659 case OPTIONAL_PRESENT: {
1660 set_selection(SPECIFIC_VALUE);
1661 int_val_t other_value_int = ((const INTEGER &)other_value).get_val();
1662 int_val.native_flag = other_value_int.native_flag;
1663 if (likely(int_val.native_flag))
1664 int_val.val.native = other_value_int.val.native;
1665 else int_val.val.openssl = BN_dup(other_value_int.val.openssl);
1666 break; }
1667 case OPTIONAL_OMIT:
1668 set_selection(OMIT_VALUE);
1669 break;
1670 default:
1671 TTCN_error("Creating an integer template from an unbound optional field.");
1672 }
1673 }
1674
1675 INTEGER_template::INTEGER_template(const INTEGER_template& other_value)
1676 : Base_Template()
1677 {
1678 copy_template(other_value);
1679 }
1680
1681 INTEGER_template::~INTEGER_template()
1682 {
1683 clean_up();
1684 }
1685
1686 INTEGER_template& INTEGER_template::operator=(template_sel other_value)
1687 {
1688 check_single_selection(other_value);
1689 clean_up();
1690 set_selection(other_value);
1691 return *this;
1692 }
1693
1694 INTEGER_template& INTEGER_template::operator=(int other_value)
1695 {
1696 clean_up();
1697 set_selection(SPECIFIC_VALUE);
1698 int_val.native_flag = TRUE;
1699 int_val.val.native = other_value;
1700 return *this;
1701 }
1702
1703 INTEGER_template& INTEGER_template::operator=(const INTEGER& other_value)
1704 {
1705 other_value.must_bound("Assignment of an unbound integer value to a "
1706 "template.");
1707 clean_up();
1708 set_selection(SPECIFIC_VALUE);
1709 int_val_t other_value_int = other_value.get_val();
1710 int_val.native_flag = other_value_int.native_flag;
1711 if (likely(int_val.native_flag))
1712 int_val.val.native = other_value_int.val.native;
1713 else int_val.val.openssl = BN_dup(other_value_int.val.openssl);
1714 return *this;
1715 }
1716
1717 INTEGER_template& INTEGER_template::operator=
1718 (const OPTIONAL<INTEGER>& other_value)
1719 {
1720 clean_up();
1721 switch (other_value.get_selection()) {
1722 case OPTIONAL_PRESENT: {
1723 set_selection(SPECIFIC_VALUE);
1724 int_val_t other_value_int = ((const INTEGER &)other_value).get_val();
1725 int_val.native_flag = other_value_int.native_flag;
1726 if (likely(int_val.native_flag))
1727 int_val.val.native = other_value_int.val.native;
1728 else int_val.val.openssl = BN_dup(other_value_int.val.openssl);
1729 break; }
1730 case OPTIONAL_OMIT:
1731 set_selection(OMIT_VALUE);
1732 break;
1733 default:
1734 TTCN_error("Assignment of an unbound optional field to an integer "
1735 "template.");
1736 }
1737 return *this;
1738 }
1739
1740 INTEGER_template& INTEGER_template::operator=
1741 (const INTEGER_template& other_value)
1742 {
1743 if (&other_value != this) {
1744 clean_up();
1745 copy_template(other_value);
1746 }
1747 return *this;
1748 }
1749
1750 boolean INTEGER_template::match(int other_value) const
1751 {
1752 switch (template_selection) {
1753 case SPECIFIC_VALUE:
1754 if (likely(int_val.native_flag)) return int_val.val.native == other_value;
1755 return int_val_t(BN_dup(int_val.val.openssl)) == other_value;
1756 case OMIT_VALUE:
1757 return FALSE;
1758 case ANY_VALUE:
1759 case ANY_OR_OMIT:
1760 return TRUE;
1761 case VALUE_LIST:
1762 case COMPLEMENTED_LIST:
1763 for(unsigned int i = 0; i < value_list.n_values; i++)
1764 if (value_list.list_value[i].match(other_value))
1765 return template_selection == VALUE_LIST;
1766 return template_selection == COMPLEMENTED_LIST;
1767 case VALUE_RANGE: {
1768 boolean lower_boundary = !value_range.min_is_present;
1769 boolean upper_boundary = !value_range.max_is_present;
1770 // Lower boundary is set.
1771 if (!lower_boundary) {
1772 lower_boundary = (likely(value_range.min_value.native_flag) ?
1773 int_val_t(value_range.min_value.val.native) :
1774 int_val_t(BN_dup(value_range.min_value.val.openssl))) <= other_value;
1775 }
1776 // Upper boundary is set.
1777 if (!upper_boundary) {
1778 upper_boundary = (likely(value_range.max_value.native_flag) ?
1779 int_val_t(value_range.max_value.val.native) :
1780 int_val_t(BN_dup(value_range.max_value.val.openssl))) >= other_value;
1781 }
1782 return lower_boundary && upper_boundary; }
1783 default:
1784 TTCN_error("Matching with an uninitialized/unsupported integer "
1785 "template.");
1786 }
1787 return FALSE;
1788 }
1789
1790 boolean INTEGER_template::match(const INTEGER& other_value) const
1791 {
1792 if (!other_value.is_bound()) return FALSE;
1793 switch (template_selection) {
1794 case SPECIFIC_VALUE: {
1795 int_val_t int_val_int = likely(int_val.native_flag) ?
1796 int_val_t(int_val.val.native) : int_val_t(BN_dup(int_val.val.openssl));
1797 return int_val_int == other_value.get_val(); }
1798 case OMIT_VALUE:
1799 return FALSE;
1800 case ANY_VALUE:
1801 case ANY_OR_OMIT:
1802 return TRUE;
1803 case VALUE_LIST:
1804 case COMPLEMENTED_LIST: // Merged cases.
1805 for (unsigned int i = 0; i < value_list.n_values; i++)
1806 if (value_list.list_value[i].match(other_value))
1807 return template_selection == VALUE_LIST;
1808 return template_selection == COMPLEMENTED_LIST;
1809 case VALUE_RANGE: {
1810 boolean lower_boundary = !value_range.min_is_present;
1811 boolean upper_boundary = !value_range.max_is_present;
1812 // Lower boundary is set.
1813 if (!lower_boundary) {
1814 lower_boundary = (likely(value_range.min_value.native_flag) ?
1815 int_val_t(value_range.min_value.val.native) :
1816 int_val_t(BN_dup(value_range.min_value.val.openssl))) <= other_value.get_val();
1817 }
1818 // Upper boundary is set.
1819 if (!upper_boundary) {
1820 upper_boundary = (likely(value_range.max_value.native_flag) ?
1821 int_val_t(value_range.max_value.val.native) :
1822 int_val_t(BN_dup(value_range.max_value.val.openssl))) >= other_value.get_val();
1823 }
1824 return lower_boundary && upper_boundary; }
1825 default:
1826 TTCN_error("Matching with an uninitialized/unsupported integer "
1827 "template.");
1828 }
1829 return FALSE;
1830 }
1831
1832 INTEGER INTEGER_template::valueof() const
1833 {
1834 if (template_selection != SPECIFIC_VALUE || is_ifpresent)
1835 TTCN_error("Performing a valueof or send operation on a non-specific "
1836 "integer template.");
1837 if (likely(int_val.native_flag)) return INTEGER(int_val.val.native);
1838 else return INTEGER(BN_dup(int_val.val.openssl));
1839 }
1840
1841 void INTEGER_template::set_type(template_sel template_type,
1842 unsigned int list_length)
1843 {
1844 clean_up();
1845 switch (template_type) {
1846 case VALUE_LIST:
1847 case COMPLEMENTED_LIST:
1848 set_selection(template_type);
1849 value_list.n_values = list_length;
1850 value_list.list_value = new INTEGER_template[list_length];
1851 break;
1852 case VALUE_RANGE:
1853 set_selection(VALUE_RANGE);
1854 value_range.min_is_present = FALSE;
1855 value_range.max_is_present = FALSE;
1856 break;
1857 default:
1858 TTCN_error("Setting an invalid type for an integer template.");
1859 }
1860 }
1861
1862 INTEGER_template& INTEGER_template::list_item(unsigned int list_index)
1863 {
1864 if (template_selection != VALUE_LIST &&
1865 template_selection != COMPLEMENTED_LIST)
1866 TTCN_error("Accessing a list element of a non-list integer template.");
1867 if (list_index >= value_list.n_values)
1868 TTCN_error("Index overflow in an integer value list template.");
1869 return value_list.list_value[list_index];
1870 }
1871
1872 void INTEGER_template::set_min(int min_value)
1873 {
1874 if (template_selection != VALUE_RANGE)
1875 TTCN_error("Integer template is not range when setting lower limit.");
1876 if (value_range.max_is_present) {
1877 int_val_t max_value_int = likely(value_range.max_value.native_flag) ?
1878 int_val_t(value_range.max_value.val.native) :
1879 int_val_t(BN_dup(value_range.max_value.val.openssl));
1880 if (max_value_int < min_value)
1881 TTCN_error("The lower limit of the range is greater than the upper "
1882 "limit in an integer template.");
1883 }
1884 value_range.min_is_present = TRUE;
1885 value_range.min_value.native_flag = TRUE;
1886 value_range.min_value.val.native = min_value;
1887 }
1888
1889 void INTEGER_template::set_min(const INTEGER& min_value)
1890 {
1891 // Redundant, but performace matters. :)
1892 min_value.must_bound("Using an unbound value when setting the lower bound "
1893 "in an integer range template.");
1894 if (template_selection != VALUE_RANGE)
1895 TTCN_error("Integer template is not range when setting lower limit.");
1896 int_val_t min_value_int = min_value.get_val();
1897 if (value_range.max_is_present) {
1898 int_val_t max_value_int = likely(value_range.max_value.native_flag) ?
1899 int_val_t(value_range.max_value.val.native) :
1900 int_val_t(BN_dup(value_range.max_value.val.openssl));
1901 if (max_value_int < min_value_int)
1902 TTCN_error("The lower limit of the range is greater than the upper "
1903 "limit in an integer template.");
1904 }
1905 value_range.min_is_present = TRUE;
1906 value_range.min_value.native_flag = min_value_int.native_flag;
1907 if (likely(value_range.min_value.native_flag))
1908 value_range.min_value.val.native = min_value_int.val.native;
1909 else value_range.min_value.val.openssl = BN_dup(min_value_int.val.openssl);
1910 }
1911
1912 void INTEGER_template::set_max(int max_value)
1913 {
1914 if (template_selection != VALUE_RANGE)
1915 TTCN_error("Integer template is not range when setting upper limit.");
1916 if (value_range.min_is_present) {
1917 int_val_t min_value_int = likely(value_range.min_value.native_flag) ?
1918 int_val_t(value_range.min_value.val.native) :
1919 int_val_t(BN_dup(value_range.min_value.val.openssl));
1920 if (min_value_int > max_value)
1921 TTCN_error("The upper limit of the range is smaller than the lower "
1922 "limit in an integer template.");
1923 }
1924 value_range.max_is_present = TRUE;
1925 value_range.max_value.native_flag = TRUE;
1926 value_range.max_value.val.native = max_value;
1927 }
1928
1929 void INTEGER_template::set_max(const INTEGER& max_value)
1930 {
1931 max_value.must_bound("Using an unbound value when setting the upper bound "
1932 "in an integer range template.");
1933 if (template_selection != VALUE_RANGE)
1934 TTCN_error("Integer template is not range when setting upper limit.");
1935 int_val_t max_value_int = max_value.get_val();
1936 if (value_range.min_is_present) {
1937 int_val_t min_value_int = likely(value_range.min_value.native_flag) ?
1938 int_val_t(value_range.min_value.val.native) :
1939 int_val_t(BN_dup(value_range.min_value.val.openssl));
1940 if (min_value_int > max_value_int)
1941 TTCN_error("The upper limit of the range is smaller than the lower "
1942 "limit in an integer template.");
1943 }
1944 value_range.max_is_present = TRUE;
1945 value_range.max_value.native_flag = max_value_int.native_flag;
1946 if (likely(value_range.max_value.native_flag))
1947 value_range.max_value.val.native = max_value_int.val.native;
1948 else value_range.max_value.val.openssl = BN_dup(max_value_int.val.openssl);
1949 }
1950
1951 void INTEGER_template::log() const
1952 {
1953 switch (template_selection) {
1954 case SPECIFIC_VALUE: {
1955 int_val_t int_val_int = likely(int_val.native_flag) ?
1956 int_val_t(int_val.val.native) : int_val_t(BN_dup(int_val.val.openssl));
1957 char *tmp_str = int_val_int.as_string();
1958 TTCN_Logger::log_event("%s", tmp_str);
1959 Free(tmp_str);
1960 break; }
1961 case COMPLEMENTED_LIST:
1962 TTCN_Logger::log_event_str("complement ");
1963 // no break
1964 case VALUE_LIST:
1965 TTCN_Logger::log_char('(');
1966 for (unsigned int i = 0; i < value_list.n_values; i++) {
1967 if (i > 0) TTCN_Logger::log_event_str(", ");
1968 value_list.list_value[i].log();
1969 }
1970 TTCN_Logger::log_char(')');
1971 break;
1972 case VALUE_RANGE:
1973 TTCN_Logger::log_char('(');
1974 if (value_range.min_is_present) {
1975 int_val_t min_value_int = likely(value_range.min_value.native_flag) ?
1976 int_val_t(value_range.min_value.val.native) :
1977 int_val_t(BN_dup(value_range.min_value.val.openssl));
1978 char *min_str = min_value_int.as_string();
1979 TTCN_Logger::log_event("%s", min_str);
1980 Free(min_str);
1981 } else {
1982 TTCN_Logger::log_event_str("-infinity");
1983 }
1984 TTCN_Logger::log_event_str(" .. ");
1985 if (value_range.max_is_present) {
1986 int_val_t max_value_int = likely(value_range.max_value.native_flag) ?
1987 int_val_t(value_range.max_value.val.native) :
1988 int_val_t(BN_dup(value_range.max_value.val.openssl));
1989 char *max_str = max_value_int.as_string();
1990 TTCN_Logger::log_event("%s", max_str);
1991 Free(max_str);
1992 } else {
1993 TTCN_Logger::log_event_str("infinity");
1994 }
1995 TTCN_Logger::log_char(')');
1996 break;
1997 default:
1998 log_generic();
1999 break;
2000 }
2001 log_ifpresent();
2002 }
2003
2004 void INTEGER_template::log_match(const INTEGER& match_value) const
2005 {
2006 if (TTCN_Logger::VERBOSITY_COMPACT == TTCN_Logger::get_matching_verbosity()
2007 && TTCN_Logger::get_logmatch_buffer_len() != 0) {
2008 TTCN_Logger::print_logmatch_buffer();
2009 TTCN_Logger::log_event_str(" := ");
2010 }
2011 match_value.log();
2012 TTCN_Logger::log_event_str(" with ");
2013 log();
2014 if (match(match_value)) TTCN_Logger::log_event_str(" matched");
2015 else TTCN_Logger::log_event_str(" unmatched");
2016 }
2017
2018 void INTEGER_template::set_param(Module_Param& param) {
2019 param.basic_check(Module_Param::BC_TEMPLATE, "integer template");
2020 switch (param.get_type()) {
2021 case Module_Param::MP_Omit:
2022 *this = OMIT_VALUE;
2023 break;
2024 case Module_Param::MP_Any:
2025 *this = ANY_VALUE;
2026 break;
2027 case Module_Param::MP_AnyOrNone:
2028 *this = ANY_OR_OMIT;
2029 break;
2030 case Module_Param::MP_List_Template:
2031 case Module_Param::MP_ComplementList_Template:
2032 set_type(param.get_type()==Module_Param::MP_List_Template ? VALUE_LIST : COMPLEMENTED_LIST, param.get_size());
2033 for (size_t i=0; i<param.get_size(); i++) {
2034 list_item(i).set_param(*param.get_elem(i));
2035 }
2036 break;
2037 case Module_Param::MP_Integer: {
2038 INTEGER tmp;
2039 tmp.set_val(*param.get_integer());
2040 *this = tmp;
2041 } break;
2042 case Module_Param::MP_IntRange: {
2043 set_type(VALUE_RANGE);
2044 if (param.get_lower_int()!=NULL) {
2045 INTEGER tmp;
2046 tmp.set_val(*param.get_lower_int());
2047 set_min(tmp);
2048 }
2049 if (param.get_upper_int()!=NULL) {
2050 INTEGER tmp;
2051 tmp.set_val(*param.get_upper_int());
2052 set_max(tmp);
2053 }
2054 } break;
2055 default:
2056 param.type_error("integer template");
2057 }
2058 is_ifpresent = param.get_ifpresent();
2059 }
2060
2061 void INTEGER_template::encode_text(Text_Buf& text_buf) const
2062 {
2063 encode_text_base(text_buf);
2064 switch (template_selection) {
2065 case OMIT_VALUE:
2066 case ANY_VALUE:
2067 case ANY_OR_OMIT:
2068 break;
2069 case SPECIFIC_VALUE:
2070 text_buf.push_int(likely(int_val.native_flag) ? int_val_t(int_val.val.native)
2071 : int_val_t(BN_dup(int_val.val.openssl)));
2072 break;
2073 case VALUE_LIST:
2074 case COMPLEMENTED_LIST:
2075 text_buf.push_int(value_list.n_values);
2076 for (unsigned int i = 0; i < value_list.n_values; i++)
2077 value_list.list_value[i].encode_text(text_buf);
2078 break;
2079 case VALUE_RANGE:
2080 text_buf.push_int(value_range.min_is_present ? 1 : 0);
2081 if (value_range.min_is_present)
2082 text_buf.push_int(likely(value_range.min_value.native_flag) ?
2083 int_val_t(value_range.min_value.val.native) :
2084 int_val_t(BN_dup(value_range.min_value.val.openssl)));
2085 text_buf.push_int(value_range.max_is_present ? 1 : 0);
2086 if (value_range.max_is_present)
2087 text_buf.push_int(likely(value_range.max_value.native_flag) ?
2088 int_val_t(value_range.max_value.val.native) :
2089 int_val_t(BN_dup(value_range.max_value.val.openssl)));
2090 break;
2091 default:
2092 TTCN_error("Text encoder: Encoding an uninitialized/unsupported integer "
2093 "template.");
2094 }
2095 }
2096
2097 void INTEGER_template::decode_text(Text_Buf& text_buf)
2098 {
2099 clean_up();
2100 decode_text_base(text_buf);
2101 switch (template_selection) {
2102 case OMIT_VALUE:
2103 case ANY_VALUE:
2104 case ANY_OR_OMIT:
2105 break;
2106 case SPECIFIC_VALUE: {
2107 int_val_t int_val_int = text_buf.pull_int();
2108 int_val.native_flag = int_val_int.native_flag;
2109 if (likely(int_val.native_flag)) int_val.val.native = int_val_int.val.native;
2110 else int_val.val.openssl = BN_dup(int_val_int.val.openssl);
2111 break; }
2112 case VALUE_LIST:
2113 case COMPLEMENTED_LIST:
2114 value_list.n_values = text_buf.pull_int().get_val();
2115 value_list.list_value = new INTEGER_template[value_list.n_values];
2116 for (unsigned int i = 0; i < value_list.n_values; i++)
2117 value_list.list_value[i].decode_text(text_buf);
2118 break;
2119 case VALUE_RANGE:
2120 value_range.min_is_present = text_buf.pull_int() != 0;
2121 if (value_range.min_is_present) {
2122 int_val_t min_value_int = text_buf.pull_int();
2123 value_range.min_value.native_flag = min_value_int.native_flag;
2124 if (likely(value_range.min_value.native_flag))
2125 value_range.min_value.val.native = min_value_int.val.native;
2126 else value_range.min_value.val.openssl = BN_dup(min_value_int.val.openssl);
2127 }
2128 value_range.max_is_present = text_buf.pull_int() != 0;
2129 if (value_range.max_is_present) {
2130 int_val_t max_value_int = text_buf.pull_int();
2131 value_range.max_value.native_flag = max_value_int.native_flag;
2132 if (likely(value_range.max_value.native_flag))
2133 value_range.max_value.val.native = max_value_int.val.native;
2134 else value_range.max_value.val.openssl = BN_dup(max_value_int.val.openssl);
2135 }
2136 break;
2137 default:
2138 TTCN_error("Text decoder: An unknown/unsupported selection was received "
2139 "for an integer template.");
2140 }
2141 }
2142
2143 boolean INTEGER_template::is_present() const
2144 {
2145 if (template_selection==UNINITIALIZED_TEMPLATE) return FALSE;
2146 return !match_omit();
2147 }
2148
2149 boolean INTEGER_template::match_omit() const
2150 {
2151 if (is_ifpresent) return TRUE;
2152 switch (template_selection) {
2153 case OMIT_VALUE:
2154 case ANY_OR_OMIT:
2155 return TRUE;
2156 case VALUE_LIST:
2157 case COMPLEMENTED_LIST:
2158 for (unsigned int i=0; i<value_list.n_values; i++)
2159 if (value_list.list_value[i].match_omit())
2160 return template_selection==VALUE_LIST;
2161 return template_selection==COMPLEMENTED_LIST;
2162 default:
2163 return FALSE;
2164 }
2165 return FALSE;
2166 }
2167
2168 #ifndef TITAN_RUNTIME_2
2169 void INTEGER_template::check_restriction(template_res t_res, const char* t_name) const
2170 {
2171 if (template_selection==UNINITIALIZED_TEMPLATE) return;
2172 switch ((t_name&&(t_res==TR_VALUE))?TR_OMIT:t_res) {
2173 case TR_VALUE:
2174 if (!is_ifpresent && template_selection==SPECIFIC_VALUE) return;
2175 break;
2176 case TR_OMIT:
2177 if (!is_ifpresent && (template_selection==OMIT_VALUE ||
2178 template_selection==SPECIFIC_VALUE)) return;
2179 break;
2180 case TR_PRESENT:
2181 if (!match_omit()) return;
2182 break;
2183 default:
2184 return;
2185 }
2186 TTCN_error("Restriction `%s' on template of type %s violated.",
2187 get_res_name(t_res), t_name ? t_name : "integer");
2188 }
2189 #endif
This page took 0.138079 seconds and 5 git commands to generate.