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