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