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