1 ///////////////////////////////////////////////////////////////////////////////
2 // Copyright (c) 2000-2015 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 ///////////////////////////////////////////////////////////////////////////////
10 #include "Bitstring.hh"
11 #include "../common/memory.h"
13 #include "String_struct.hh"
14 #include "Parameters.h"
15 #include "Param_Types.hh"
20 #include "../common/dbgnew.hh"
22 // bitstring value class
24 /** The amount of memory needed for a bitstring containing n bits. */
25 #define MEMORY_SIZE(n) (sizeof(bitstring_struct) - sizeof(int) + ((n) + 7) / 8)
27 void BITSTRING::init_struct(int n_bits
)
31 TTCN_error("Initializing a bitstring with a negative length.");
32 } else if (n_bits
== 0) {
33 /** This will represent the empty strings so they won't need allocated
34 * memory, this delays the memory allocation until it is really needed.
36 static bitstring_struct empty_string
= { 1, 0, "" };
37 val_ptr
= &empty_string
;
38 empty_string
.ref_count
++;
40 val_ptr
= (bitstring_struct
*)Malloc(MEMORY_SIZE(n_bits
));
41 val_ptr
->ref_count
= 1;
42 val_ptr
->n_bits
= n_bits
;
46 boolean
BITSTRING::get_bit(int bit_index
) const
48 return val_ptr
->bits_ptr
[bit_index
/ 8] & (1 << (bit_index
% 8));
51 void BITSTRING::set_bit(int bit_index
, boolean new_value
)
53 unsigned char mask
= 1 << (bit_index
% 8);
54 if (new_value
) val_ptr
->bits_ptr
[bit_index
/ 8] |= mask
;
55 else val_ptr
->bits_ptr
[bit_index
/ 8] &= ~mask
;
58 void BITSTRING::copy_value()
60 if (val_ptr
== NULL
|| val_ptr
->n_bits
<= 0)
61 TTCN_error("Internal error: Invalid internal data structure when copying "
62 "the memory area of a bitstring value.");
63 if (val_ptr
->ref_count
> 1) {
64 bitstring_struct
*old_ptr
= val_ptr
;
66 init_struct(old_ptr
->n_bits
);
67 memcpy(val_ptr
->bits_ptr
, old_ptr
->bits_ptr
, (old_ptr
->n_bits
+ 7) / 8);
71 void BITSTRING::clear_unused_bits() const
73 int n_bits
= val_ptr
->n_bits
;
74 if (n_bits
% 8 != 0) val_ptr
->bits_ptr
[(n_bits
- 1) / 8] &=
75 (unsigned char)'\377' >> (7 - (n_bits
- 1) % 8);
78 BITSTRING::BITSTRING(int n_bits
)
83 BITSTRING::BITSTRING()
88 BITSTRING::BITSTRING(int n_bits
, const unsigned char *bits_ptr
)
91 memcpy(val_ptr
->bits_ptr
, bits_ptr
, (n_bits
+ 7) / 8);
95 BITSTRING::BITSTRING(const BITSTRING
& other_value
)
96 : Base_Type(other_value
)
98 other_value
.must_bound("Copying an unbound bitstring value.");
99 val_ptr
= other_value
.val_ptr
;
100 val_ptr
->ref_count
++;
103 BITSTRING::BITSTRING(const BITSTRING_ELEMENT
& other_value
)
105 other_value
.must_bound("Copying an unbound bitstring element.");
107 val_ptr
->bits_ptr
[0] = other_value
.get_bit() ? 1 : 0;
110 BITSTRING::~BITSTRING()
115 void BITSTRING::clean_up()
117 if (val_ptr
!= NULL
) {
118 if (val_ptr
->ref_count
> 1) val_ptr
->ref_count
--;
119 else if (val_ptr
->ref_count
== 1) Free(val_ptr
);
120 else TTCN_error("Internal error: Invalid reference counter in a bitstring "
126 BITSTRING
& BITSTRING::operator=(const BITSTRING
& other_value
)
128 other_value
.must_bound("Assignment of an unbound bitstring value.");
129 if (&other_value
!= this) {
131 val_ptr
= other_value
.val_ptr
;
132 val_ptr
->ref_count
++;
137 BITSTRING
& BITSTRING::operator=(const BITSTRING_ELEMENT
& other_value
)
139 other_value
.must_bound("Assignment of an unbound bitstring element to a "
141 boolean bit_value
= other_value
.get_bit();
144 val_ptr
->bits_ptr
[0] = bit_value
? 1 : 0;
148 boolean
BITSTRING::operator==(const BITSTRING
& other_value
) const
150 must_bound("Unbound left operand of bitstring comparison.");
151 other_value
.must_bound("Unbound right operand of bitstring comparison.");
152 int n_bits
= val_ptr
->n_bits
;
153 if (n_bits
!= other_value
.val_ptr
->n_bits
) return FALSE
;
154 if (n_bits
== 0) return TRUE
;
156 other_value
.clear_unused_bits();
157 return !memcmp(val_ptr
->bits_ptr
, other_value
.val_ptr
->bits_ptr
,
161 boolean
BITSTRING::operator==(const BITSTRING_ELEMENT
& other_value
) const
163 must_bound("Unbound left operand of bitstring comparison.");
164 other_value
.must_bound("Unbound right operand of bitstring element "
166 if (val_ptr
->n_bits
!= 1) return FALSE
;
167 return get_bit(0) == other_value
.get_bit();
170 BITSTRING
BITSTRING::operator+(const BITSTRING
& other_value
) const
172 must_bound("Unbound left operand of bitstring concatenation.");
173 other_value
.must_bound("Unbound right operand of bitstring concatenation.");
175 int left_n_bits
= val_ptr
->n_bits
;
176 if (left_n_bits
== 0) return other_value
;
178 int right_n_bits
= other_value
.val_ptr
->n_bits
;
179 if (right_n_bits
== 0) return *this;
181 // the length of result
182 int n_bits
= left_n_bits
+ right_n_bits
;
184 // the number of bytes used
185 int left_n_bytes
= (left_n_bits
+ 7) / 8;
186 int right_n_bytes
= (right_n_bits
+ 7) / 8;
188 // the number of bits used in the last incomplete octet of the left operand
189 int left_empty_bits
= left_n_bits
% 8;
192 BITSTRING
ret_val(n_bits
);
194 // pointers to the data areas
195 const unsigned char *left_ptr
= val_ptr
->bits_ptr
;
196 const unsigned char *right_ptr
= other_value
.val_ptr
->bits_ptr
;
197 unsigned char *dest_ptr
= ret_val
.val_ptr
->bits_ptr
;
199 // copying the left fragment into the result
200 memcpy(dest_ptr
, left_ptr
, left_n_bytes
);
202 if (left_empty_bits
!= 0) {
203 // non-trivial case: the length of left fragment is not a multiply of 8
204 // the bytes used in the result
205 int n_bytes
= (n_bits
+ 7) / 8;
206 // placing the bytes from the right fragment until the result is filled
207 for (int i
= left_n_bytes
; i
< n_bytes
; i
++) {
208 unsigned char right_byte
= right_ptr
[i
- left_n_bytes
];
209 // finish filling the previous byte
210 dest_ptr
[i
- 1] |= right_byte
<< left_empty_bits
;
211 // start filling the actual byte
212 dest_ptr
[i
] = right_byte
>> (8 - left_empty_bits
);
214 if (left_n_bytes
+ right_n_bytes
> n_bytes
) {
215 // if the result data area is shorter than the two operands together
216 // the last bits of right fragment were not placed into the result
217 // in the previous for loop
218 dest_ptr
[n_bytes
- 1] |= right_ptr
[right_n_bytes
- 1] << left_empty_bits
;
221 // trivial case: just append the bytes of the right fragment
222 memcpy(dest_ptr
+ left_n_bytes
, right_ptr
, right_n_bytes
);
224 ret_val
.clear_unused_bits();
228 BITSTRING
BITSTRING::operator+(const BITSTRING_ELEMENT
& other_value
) const
230 must_bound("Unbound left operand of bitstring concatenation.");
231 other_value
.must_bound("Unbound right operand of bitstring element "
234 int n_bits
= val_ptr
->n_bits
;
235 BITSTRING
ret_val(n_bits
+ 1);
236 memcpy(ret_val
.val_ptr
->bits_ptr
, val_ptr
->bits_ptr
, (n_bits
+ 7) / 8);
237 ret_val
.set_bit(n_bits
, other_value
.get_bit());
241 BITSTRING
BITSTRING::operator~() const
243 must_bound("Unbound bitstring operand of operator not4b.");
244 int n_bytes
= (val_ptr
->n_bits
+ 7) / 8;
245 if (n_bytes
== 0) return *this;
246 BITSTRING
ret_val(val_ptr
->n_bits
);
247 for (int i
= 0; i
< n_bytes
; i
++)
248 ret_val
.val_ptr
->bits_ptr
[i
] = ~val_ptr
->bits_ptr
[i
];
249 ret_val
.clear_unused_bits();
253 BITSTRING
BITSTRING::operator&(const BITSTRING
& other_value
) const
255 must_bound("Left operand of operator and4b is an unbound bitstring value.");
256 other_value
.must_bound("Right operand of operator and4b is an unbound "
258 int n_bits
= val_ptr
->n_bits
;
259 if (n_bits
!= other_value
.val_ptr
->n_bits
)
260 TTCN_error("The bitstring operands of operator and4b must have the "
262 if (n_bits
== 0) return *this;
263 BITSTRING
ret_val(n_bits
);
264 int n_bytes
= (n_bits
+ 7) / 8;
265 for (int i
= 0; i
< n_bytes
; i
++)
266 ret_val
.val_ptr
->bits_ptr
[i
] = val_ptr
->bits_ptr
[i
] &
267 other_value
.val_ptr
->bits_ptr
[i
];
268 ret_val
.clear_unused_bits();
272 BITSTRING
BITSTRING::operator&(const BITSTRING_ELEMENT
& other_value
) const
274 must_bound("Left operand of operator and4b is an unbound bitstring value.");
275 other_value
.must_bound("Right operand of operator and4b is an unbound "
276 "bitstring element.");
277 if (val_ptr
->n_bits
!= 1)
278 TTCN_error("The bitstring operands of "
279 "operator and4b must have the same length.");
280 unsigned char result
= get_bit(0) && other_value
.get_bit() ? 1 : 0;
281 return BITSTRING(1, &result
);
284 BITSTRING
BITSTRING::operator|(const BITSTRING
& other_value
) const
286 must_bound("Left operand of operator or4b is an unbound bitstring value.");
287 other_value
.must_bound("Right operand of operator or4b is an unbound "
289 int n_bits
= val_ptr
->n_bits
;
290 if (n_bits
!= other_value
.val_ptr
->n_bits
)
291 TTCN_error("The bitstring operands of operator or4b must have the "
293 if (n_bits
== 0) return *this;
294 BITSTRING
ret_val(n_bits
);
295 int n_bytes
= (n_bits
+ 7) / 8;
296 for (int i
= 0; i
< n_bytes
; i
++)
297 ret_val
.val_ptr
->bits_ptr
[i
] = val_ptr
->bits_ptr
[i
] |
298 other_value
.val_ptr
->bits_ptr
[i
];
299 ret_val
.clear_unused_bits();
303 BITSTRING
BITSTRING::operator|(const BITSTRING_ELEMENT
& other_value
) const
305 must_bound("Left operand of operator or4b is an unbound bitstring value.");
306 other_value
.must_bound("Right operand of operator or4b is an unbound "
307 "bitstring element.");
308 if (val_ptr
->n_bits
!= 1)
309 TTCN_error("The bitstring operands of "
310 "operator or4b must have the same length.");
311 unsigned char result
= get_bit(0) || other_value
.get_bit() ? 1 : 0;
312 return BITSTRING(1, &result
);
315 BITSTRING
BITSTRING::operator^(const BITSTRING
& other_value
) const
317 must_bound("Left operand of operator xor4b is an unbound bitstring value.");
318 other_value
.must_bound("Right operand of operator xor4b is an unbound "
320 int n_bits
= val_ptr
->n_bits
;
321 if (n_bits
!= other_value
.val_ptr
->n_bits
)
322 TTCN_error("The bitstring operands of operator xor4b must have the "
324 if (n_bits
== 0) return *this;
325 BITSTRING
ret_val(n_bits
);
326 int n_bytes
= (n_bits
+ 7) / 8;
327 for (int i
= 0; i
< n_bytes
; i
++)
328 ret_val
.val_ptr
->bits_ptr
[i
] = val_ptr
->bits_ptr
[i
] ^
329 other_value
.val_ptr
->bits_ptr
[i
];
330 ret_val
.clear_unused_bits();
334 BITSTRING
BITSTRING::operator^(const BITSTRING_ELEMENT
& other_value
) const
336 must_bound("Left operand of operator xor4b is an unbound bitstring value.");
337 other_value
.must_bound("Right operand of operator xor4b is an unbound "
338 "bitstring element.");
339 if (val_ptr
->n_bits
!= 1)
340 TTCN_error("The bitstring operands of "
341 "operator xor4b must have the same length.");
342 unsigned char result
= get_bit(0) != other_value
.get_bit() ? 1 : 0;
343 return BITSTRING(1, &result
);
346 BITSTRING
BITSTRING::operator<<(int shift_count
) const
348 must_bound("Unbound bitstring operand of shift left operator.");
349 if (shift_count
> 0) {
350 int n_bits
= val_ptr
->n_bits
;
351 if (n_bits
== 0) return *this;
352 BITSTRING
ret_val(n_bits
);
353 int n_bytes
= (n_bits
+ 7) / 8;
355 if (shift_count
> n_bits
) shift_count
= n_bits
;
356 int shift_bytes
= shift_count
/ 8,
357 shift_bits
= shift_count
% 8;
358 if (shift_bits
!= 0) {
360 for ( ; byte_count
< n_bytes
- shift_bytes
- 1; byte_count
++) {
361 ret_val
.val_ptr
->bits_ptr
[byte_count
] =
362 (val_ptr
->bits_ptr
[byte_count
+ shift_bytes
] >> shift_bits
)|
363 (val_ptr
->bits_ptr
[byte_count
+ shift_bytes
+ 1] <<
366 ret_val
.val_ptr
->bits_ptr
[n_bytes
- shift_bytes
- 1] =
367 val_ptr
->bits_ptr
[n_bytes
- 1] >> shift_bits
;
369 memcpy(ret_val
.val_ptr
->bits_ptr
, val_ptr
->bits_ptr
+ shift_bytes
,
370 n_bytes
- shift_bytes
);
372 memset(ret_val
.val_ptr
->bits_ptr
+ n_bytes
- shift_bytes
, 0,
374 ret_val
.clear_unused_bits();
376 } else if (shift_count
== 0) return *this;
377 else return *this >> (-shift_count
);
380 BITSTRING
BITSTRING::operator<<(const INTEGER
& shift_count
) const
382 shift_count
.must_bound("Unbound right operand of bitstring shift left "
384 return *this << (int)shift_count
;
387 BITSTRING
BITSTRING::operator>>(int shift_count
) const
389 must_bound("Unbound bitstring operand of shift right operator.");
390 if (shift_count
> 0) {
391 int n_bits
= val_ptr
->n_bits
;
392 if (n_bits
== 0) return *this;
393 BITSTRING
ret_val(n_bits
);
394 int n_bytes
= (n_bits
+ 7) / 8;
396 if (shift_count
> n_bits
) shift_count
= n_bits
;
397 int shift_bytes
= shift_count
/ 8, shift_bits
= shift_count
% 8;
398 memset(ret_val
.val_ptr
->bits_ptr
, 0, shift_bytes
);
399 if (shift_bits
!= 0) {
400 ret_val
.val_ptr
->bits_ptr
[shift_bytes
] =
401 val_ptr
->bits_ptr
[0] << shift_bits
;
402 for (int byte_count
= shift_bytes
+ 1; byte_count
< n_bytes
; byte_count
++)
404 ret_val
.val_ptr
->bits_ptr
[byte_count
] =
405 (val_ptr
->bits_ptr
[byte_count
- shift_bytes
- 1] >> (8 - shift_bits
))
406 | (val_ptr
->bits_ptr
[byte_count
- shift_bytes
] << shift_bits
);
409 memcpy(ret_val
.val_ptr
->bits_ptr
+ shift_bytes
, val_ptr
->bits_ptr
,
410 n_bytes
- shift_bytes
);
412 ret_val
.clear_unused_bits();
414 } else if (shift_count
== 0) return *this;
415 else return *this << (-shift_count
);
418 BITSTRING
BITSTRING::operator>>(const INTEGER
& shift_count
) const
420 shift_count
.must_bound("Unbound right operand of bitstring shift right "
422 return *this >> (int)shift_count
;
425 BITSTRING
BITSTRING::operator<<=(int rotate_count
) const
427 must_bound("Unbound bistring operand of rotate left operator.");
428 int n_bits
= val_ptr
->n_bits
;
429 if (n_bits
== 0) return *this;
430 if (rotate_count
>= 0) {
431 rotate_count
%= n_bits
;
432 if (rotate_count
== 0) return *this;
433 else return (*this << rotate_count
) |
434 (*this >> (n_bits
- rotate_count
));
435 } else return *this >>= (-rotate_count
);
438 BITSTRING
BITSTRING::operator<<=(const INTEGER
& rotate_count
) const
440 rotate_count
.must_bound("Unbound right operand of bitstring rotate left "
442 return *this <<= (int)rotate_count
;
445 BITSTRING
BITSTRING::operator>>=(int rotate_count
) const
447 must_bound("Unbound bistring operand of rotate right operator.");
448 int n_bits
= val_ptr
->n_bits
;
449 if (n_bits
== 0) return *this;
450 if (rotate_count
>= 0) {
451 rotate_count
%= n_bits
;
452 if (rotate_count
== 0) return *this;
453 else return (*this >> rotate_count
) |
454 (*this << (n_bits
- rotate_count
));
455 } else return *this <<= (-rotate_count
);
458 BITSTRING
BITSTRING::operator>>=(const INTEGER
& rotate_count
) const
460 rotate_count
.must_bound("Unbound right operand of bitstring rotate right "
462 return *this >>= (int)rotate_count
;
465 BITSTRING_ELEMENT
BITSTRING::operator[](int index_value
)
467 if (val_ptr
== NULL
&& index_value
== 0) {
470 return BITSTRING_ELEMENT(FALSE
, *this, 0);
472 must_bound("Accessing an element of an unbound bitstring value.");
473 if (index_value
< 0) TTCN_error("Accessing an bitstring element using "
474 "a negative index (%d).", index_value
);
475 int n_bits
= val_ptr
->n_bits
;
476 if (index_value
> n_bits
) TTCN_error("Index overflow when accessing a "
477 "bitstring element: The index is %d, but the string has only %d bits.",
478 index_value
, n_bits
);
479 if (index_value
== n_bits
) {
480 if (val_ptr
->ref_count
== 1) {
481 if (n_bits
% 8 == 0) val_ptr
= (bitstring_struct
*)
482 Realloc(val_ptr
, MEMORY_SIZE(n_bits
+ 1));
485 bitstring_struct
*old_ptr
= val_ptr
;
486 old_ptr
->ref_count
--;
487 init_struct(n_bits
+ 1);
488 memcpy(val_ptr
->bits_ptr
, old_ptr
->bits_ptr
, (n_bits
+ 7) / 8);
491 return BITSTRING_ELEMENT(FALSE
, *this, index_value
);
492 } else return BITSTRING_ELEMENT(TRUE
, *this, index_value
);
496 BITSTRING_ELEMENT
BITSTRING::operator[](const INTEGER
& index_value
)
498 index_value
.must_bound("Indexing a bitstring value with an unbound integer "
500 return (*this)[(int)index_value
];
503 const BITSTRING_ELEMENT
BITSTRING::operator[](int index_value
) const
505 must_bound("Accessing an element of an unbound bitstring value.");
506 if (index_value
< 0) TTCN_error("Accessing an bitstring element using a "
507 "negative index (%d).", index_value
);
508 if (index_value
>= val_ptr
->n_bits
) TTCN_error("Index overflow when "
509 "accessing a bitstring element: The index is %d, but the string has only "
510 "%d bits.", index_value
, val_ptr
->n_bits
);
511 return BITSTRING_ELEMENT(TRUE
, const_cast<BITSTRING
&>(*this), index_value
);
514 const BITSTRING_ELEMENT
BITSTRING::operator[](const INTEGER
& index_value
) const
516 index_value
.must_bound("Indexing a bitstring value with an unbound integer "
518 return (*this)[(int)index_value
];
521 int BITSTRING::lengthof() const
523 must_bound("Getting the length of an unbound bitstring value.");
524 return val_ptr
->n_bits
;
527 BITSTRING::operator const unsigned char*() const
529 must_bound("Casting an unbound bitstring value to const unsigned char*.");
530 return val_ptr
->bits_ptr
;
533 void BITSTRING::log() const
535 if (val_ptr
!= NULL
) {
536 TTCN_Logger::log_char('\'');
537 for (int bit_count
= 0; bit_count
< val_ptr
->n_bits
; bit_count
++)
538 TTCN_Logger::log_char(get_bit(bit_count
) ? '1' : '0');
539 TTCN_Logger::log_event_str("'B");
540 } else TTCN_Logger::log_event_unbound();
543 void BITSTRING::set_param(Module_Param
& param
) {
544 param
.basic_check(Module_Param::BC_VALUE
|Module_Param::BC_LIST
, "bitstring value");
545 Module_Param_Ptr mp
= ¶m
;
546 if (param
.get_type() == Module_Param::MP_Reference
) {
547 mp
= param
.get_referenced_param();
549 switch (mp
->get_type()) {
550 case Module_Param::MP_Bitstring
:
551 switch (param
.get_operation_type()) {
552 case Module_Param::OT_ASSIGN
:
554 init_struct(mp
->get_string_size());
555 memcpy(val_ptr
->bits_ptr
, mp
->get_string_data(), (val_ptr
->n_bits
+ 7) / 8);
558 case Module_Param::OT_CONCAT
:
560 *this = *this + BITSTRING(mp
->get_string_size(), (unsigned char*)mp
->get_string_data());
562 *this = BITSTRING(mp
->get_string_size(), (unsigned char*)mp
->get_string_data());
566 TTCN_error("Internal error: BITSTRING::set_param()");
569 case Module_Param::MP_Expression
:
570 if (mp
->get_expr_type() == Module_Param::EXPR_CONCATENATE
) {
571 BITSTRING operand1
, operand2
;
572 operand1
.set_param(*mp
->get_operand1());
573 operand2
.set_param(*mp
->get_operand2());
574 if (param
.get_operation_type() == Module_Param::OT_CONCAT
) {
575 *this = *this + operand1
+ operand2
;
578 *this = operand1
+ operand2
;
582 param
.expr_type_error("a bitstring");
586 param
.type_error("bitstring value");
591 Module_Param
* BITSTRING::get_param(Module_Param_Name
& /* param_name */) const
594 return new Module_Param_Unbound();
596 int n_bytes
= (val_ptr
->n_bits
+ 7) / 8;
597 unsigned char* val_cpy
= (unsigned char *)Malloc(n_bytes
);
598 memcpy(val_cpy
, val_ptr
->bits_ptr
, n_bytes
);
599 return new Module_Param_Bitstring(val_ptr
->n_bits
, val_cpy
);
602 void BITSTRING::encode_text(Text_Buf
& text_buf
) const
604 must_bound("Text encoder: Encoding an unbound bitstring value.");
605 int n_bits
= val_ptr
->n_bits
;
606 text_buf
.push_int(n_bits
);
607 if (n_bits
> 0) text_buf
.push_raw((n_bits
+ 7) / 8, val_ptr
->bits_ptr
);
610 void BITSTRING::decode_text(Text_Buf
& text_buf
)
612 int n_bits
= text_buf
.pull_int().get_val();
614 TTCN_error("Text decoder: Invalid length was received for a bitstring.");
618 text_buf
.pull_raw((n_bits
+ 7) / 8, val_ptr
->bits_ptr
);
623 void BITSTRING::encode(const TTCN_Typedescriptor_t
& p_td
, TTCN_Buffer
& p_buf
,
624 TTCN_EncDec::coding_t p_coding
, ...) const
627 va_start(pvar
, p_coding
);
629 case TTCN_EncDec::CT_BER
: {
630 TTCN_EncDec_ErrorContext
ec("While BER-encoding type '%s': ", p_td
.name
);
631 unsigned BER_coding
=va_arg(pvar
, unsigned);
632 BER_encode_chk_coding(BER_coding
);
633 ASN_BER_TLV_t
*tlv
=BER_encode_TLV(p_td
, BER_coding
);
634 tlv
->put_in_buffer(p_buf
);
635 ASN_BER_TLV_t::destruct(tlv
);
637 case TTCN_EncDec::CT_RAW
: {
638 TTCN_EncDec_ErrorContext
ec("While RAW-encoding type '%s': ", p_td
.name
);
640 TTCN_EncDec_ErrorContext::error_internal
641 ("No RAW descriptor available for type '%s'.", p_td
.name
);
645 RAW_enc_tree
root(true,NULL
,&rp
,1,p_td
.raw
);
646 RAW_encode(p_td
, root
);
647 root
.put_to_buf(p_buf
);
649 case TTCN_EncDec::CT_XER
: {
650 TTCN_EncDec_ErrorContext
ec("While XER-encoding type '%s': ", p_td
.name
);
651 unsigned XER_coding
=va_arg(pvar
, unsigned);
652 XER_encode(*p_td
.xer
, p_buf
, XER_coding
, 0, 0);
654 case TTCN_EncDec::CT_JSON
: {
655 TTCN_EncDec_ErrorContext
ec("While JSON-encoding type '%s': ", p_td
.name
);
657 TTCN_EncDec_ErrorContext::error_internal
658 ("No JSON descriptor available for type '%s'.", p_td
.name
);
659 JSON_Tokenizer
tok(va_arg(pvar
, int) != 0);
660 JSON_encode(p_td
, tok
);
661 p_buf
.put_s(tok
.get_buffer_length(), (const unsigned char*)tok
.get_buffer());
664 TTCN_error("Unknown coding method requested to encode type '%s'",
670 void BITSTRING::decode(const TTCN_Typedescriptor_t
& p_td
, TTCN_Buffer
& p_buf
,
671 TTCN_EncDec::coding_t p_coding
, ...)
674 va_start(pvar
, p_coding
);
676 case TTCN_EncDec::CT_BER
: {
677 TTCN_EncDec_ErrorContext
ec("While BER-decoding type '%s': ", p_td
.name
);
678 unsigned L_form
=va_arg(pvar
, unsigned);
680 BER_decode_str2TLV(p_buf
, tlv
, L_form
);
681 BER_decode_TLV(p_td
, tlv
, L_form
);
682 if(tlv
.isComplete
) p_buf
.increase_pos(tlv
.get_len());
684 case TTCN_EncDec::CT_RAW
: {
685 TTCN_EncDec_ErrorContext
ec("While RAW-decoding type '%s': ", p_td
.name
);
687 TTCN_EncDec_ErrorContext::error_internal
688 ("No RAW descriptor available for type '%s'.", p_td
.name
);
690 switch(p_td
.raw
->top_bit_order
){
698 if(RAW_decode(p_td
, p_buf
, p_buf
.get_len()*8, order
)<0)
699 ec
.error(TTCN_EncDec::ET_INCOMPL_MSG
,
700 "Can not decode type '%s', because invalid or incomplete"
701 " message was received"
704 case TTCN_EncDec::CT_XER
: {
705 TTCN_EncDec_ErrorContext
ec("While XER-decoding type '%s': ", p_td
.name
);
706 unsigned XER_coding
=va_arg(pvar
, unsigned);
707 XmlReaderWrap
reader(p_buf
);
708 int success
= reader
.Read();
709 for (; success
==1; success
=reader
.Read()) {
710 int type
= reader
.NodeType();
711 if (type
==XML_READER_TYPE_ELEMENT
)
714 XER_decode(*p_td
.xer
, reader
, XER_coding
, 0);
715 size_t bytes
= reader
.ByteConsumed();
716 p_buf
.set_pos(bytes
);
718 case TTCN_EncDec::CT_JSON
: {
719 TTCN_EncDec_ErrorContext
ec("While JSON-decoding type '%s': ", p_td
.name
);
721 TTCN_EncDec_ErrorContext::error_internal
722 ("No JSON descriptor available for type '%s'.", p_td
.name
);
723 JSON_Tokenizer
tok((const char*)p_buf
.get_data(), p_buf
.get_len());
724 if(JSON_decode(p_td
, tok
, false)<0)
725 ec
.error(TTCN_EncDec::ET_INCOMPL_MSG
,
726 "Can not decode type '%s', because invalid or incomplete"
727 " message was received"
729 p_buf
.set_pos(tok
.get_buf_pos());
732 TTCN_error("Unknown coding method requested to decode type '%s'",
738 void BITSTRING::BER_encode_putbits(unsigned char *target
,
739 unsigned int bitnum_start
,
740 unsigned int bit_count
) const
742 unsigned int nof_bits
, nof_octets
, i
, j
;
745 nof_bits
=val_ptr
->n_bits
;
746 if(bitnum_start
>nof_bits
747 || bitnum_start
+bit_count
>nof_bits
)
748 TTCN_EncDec_ErrorContext::error_internal
749 ("In BITSTRING::BER_encode_putbits(): Index overflow.");
750 nof_octets
=(bit_count
+7)/8;
755 target
[0]=(unsigned char)(nof_octets
*8-bit_count
);
756 for(i
=0; i
<nof_octets
-1; i
++) {
760 if(get_bit(bitnum_start
+8*i
+j
)) c
|=0x01;
768 if(get_bit(bitnum_start
+8*i
+j
)) c
|=0x01;
774 BITSTRING::BER_encode_TLV(const TTCN_Typedescriptor_t
& p_td
,
775 unsigned p_coding
) const
778 ASN_BER_TLV_t
*new_tlv
=BER_encode_chk_bound(is_bound());
780 unsigned char *V_ptr
;
782 unsigned int nof_bits
=val_ptr
->n_bits
;
783 unsigned int nof_octets
=(nof_bits
+7)/8;
784 unsigned int nof_fragments
=0;
785 if(p_coding
==BER_ENCODE_CER
) {
786 nof_fragments
=(nof_octets
+998)/999;
787 if(!nof_fragments
) nof_fragments
=1;
789 else /*if(coding==BER_ENCODE_DER)*/ {
793 boolean is_constructed
=nof_fragments
>1;
794 if(!is_constructed
) {
796 V_ptr
=(unsigned char*)Malloc(V_len
);
797 BER_encode_putbits(V_ptr
, 0, nof_bits
);
798 new_tlv
=ASN_BER_TLV_t::construct(V_len
, V_ptr
);
800 else { // is constructed
801 ASN_BER_TLV_t
*tmp_tlv
=NULL
;
802 new_tlv
=ASN_BER_TLV_t::construct(NULL
);
803 unsigned int rest_octets
=nof_octets
-(nof_fragments
-1)*999;
805 V_len=(nof_fragments-1)*1004;
806 V_len+=rest_octets<128?2:4;
807 V_len+=rest_octets+1;
808 V_ptr=(unsigned char*)Malloc(V_len);
811 unsigned int nof_bits_curr
=8*999;
812 for(unsigned int i
=0; i
<nof_fragments
; i
++) {
813 if(i
==nof_fragments
-1) {
815 nof_bits_curr
=nof_bits
-i
*8*999;
817 V_ptr
=(unsigned char*)Malloc(V_len
+1); // because of unused bits-octet
824 BER_encode_putbits(V_ptr
, i
*8*999, nof_bits_curr
);
828 tmp_tlv
=ASN_BER_TLV_t::construct(V_len
+1, V_ptr
);
829 tmp_tlv
=ASN_BER_V2TLV(tmp_tlv
, BITSTRING_descr_
, p_coding
);
830 new_tlv
->add_TLV(tmp_tlv
);
834 if(rest_octets<128) {
835 V_ptr[1]=(rest_octets+1) & '\x7F';
840 V_ptr[2]=((rest_octets+1)/256) & 0xFF;
841 V_ptr[3]=(rest_octets+1) & 0xFF;
844 BER_encode_putbits(V_ptr, i*8*999, nof_bits-i*8*999);
848 new_tlv
=ASN_BER_V2TLV(new_tlv
, p_td
, p_coding
);
852 void BITSTRING::BER_decode_getbits(const unsigned char *source
,
853 size_t s_len
, unsigned int& bitnum_start
)
858 TTCN_EncDec_ErrorContext::error
859 (TTCN_EncDec::ET_INVAL_MSG
, "Length of V-part of bitstring"
863 unsigned int nof_octets
=s_len
-1;
864 unsigned int nof_restbits
=8-source
[0];
867 TTCN_EncDec_ErrorContext::error
868 (TTCN_EncDec::ET_INVAL_MSG
,
869 "If the bitstring is empty,"
870 " the initial octet shall be 0, not %u [see X.690 clause 8.6.2.3].",
875 TTCN_EncDec_ErrorContext::error
876 (TTCN_EncDec::ET_INVAL_MSG
, "The number of unused bits in bitstring"
877 " cannot be %u (should be less than 8) [see X.690 clause 8.6.2.2].",
881 // And what about overflow? :)
882 i
= (nof_octets
- 1) * 8 + nof_restbits
;
884 if (val_ptr
->ref_count
> 1) {
885 bitstring_struct
*old_ptr
= val_ptr
;
886 old_ptr
->ref_count
--;
887 init_struct(bitnum_start
+ i
);
888 memcpy(val_ptr
->bits_ptr
, old_ptr
->bits_ptr
, (old_ptr
->n_bits
+ 7) / 8);
890 if ((bitnum_start
+ i
+ 7) / 8 > ((unsigned int)val_ptr
->n_bits
+ 7) / 8)
891 val_ptr
= (bitstring_struct
*)Realloc(val_ptr
,
892 MEMORY_SIZE(bitnum_start
+ i
));
893 val_ptr
->n_bits
= bitnum_start
+ i
;
896 for(i
=0; i
<nof_octets
-1; i
++) {
899 set_bit(bitnum_start
+8*i
+j
, c
& 0x80?TRUE
:FALSE
);
904 for(j
=0; j
<nof_restbits
; j
++) {
905 set_bit(bitnum_start
+8*i
+j
, c
& 0x80?TRUE
:FALSE
);
908 bitnum_start
+=(nof_octets
-1)*8+nof_restbits
;
911 void BITSTRING::BER_decode_TLV_(const ASN_BER_TLV_t
& p_tlv
, unsigned L_form
,
912 unsigned int& bitnum_start
)
914 if(!p_tlv
.isConstructed
) {
915 if (p_tlv
.isComplete
|| p_tlv
.V
.str
.Vlen
> 0)
916 BER_decode_getbits(p_tlv
.V
.str
.Vstr
, p_tlv
.V
.str
.Vlen
, bitnum_start
);
918 else { // is constructed
923 if(!ASN_BER_str2TLV(p_tlv
.V
.str
.Vlen
-V_pos
, p_tlv
.V
.str
.Vstr
+V_pos
,
925 TTCN_EncDec_ErrorContext::error
926 (TTCN_EncDec::ET_INCOMPL_MSG
,
927 "Incomplete TLV in a constructed BITSTRING TLV.");
930 if(!p_tlv
.isLenDefinite
&& tlv2
.tagnumber
==0
931 && tlv2
.tagclass
==ASN_TAG_UNIV
)
932 doit
=FALSE
; // End-of-contents
934 ASN_BER_TLV_t stripped_tlv
;
935 BER_decode_strip_tags(BITSTRING_ber_
, tlv2
, L_form
, stripped_tlv
);
936 BER_decode_TLV_(tlv2
, L_form
, bitnum_start
);
937 V_pos
+=tlv2
.get_len();
938 if(V_pos
>=p_tlv
.V
.str
.Vlen
) doit
=FALSE
;
941 } // else / is constructed
944 boolean
BITSTRING::BER_decode_TLV(const TTCN_Typedescriptor_t
& p_td
,
945 const ASN_BER_TLV_t
& p_tlv
,
950 ASN_BER_TLV_t stripped_tlv
;
951 BER_decode_strip_tags(*p_td
.ber
, p_tlv
, L_form
, stripped_tlv
);
952 TTCN_EncDec_ErrorContext
ec("While decoding BITSTRING type: ");
954 unsigned int bitnum_start
= 0;
955 BER_decode_TLV_(stripped_tlv
, L_form
, bitnum_start
);
959 int BITSTRING::RAW_encode(const TTCN_Typedescriptor_t
& p_td
, RAW_enc_tree
& myleaf
) const
962 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND
,
963 "Encoding an unbound value.");
965 int bl
= val_ptr
->n_bits
;
966 int align_length
= p_td
.raw
->fieldlength
? p_td
.raw
->fieldlength
- bl
: 0;
967 if ((bl
+ align_length
) < val_ptr
->n_bits
) {
968 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_LEN_ERR
,
969 "There is no sufficient bits to encode '%s': ", p_td
.name
);
970 bl
= p_td
.raw
->fieldlength
;
973 // myleaf.ext_bit=EXT_BIT_NO;
974 if (myleaf
.must_free
) Free(myleaf
.body
.leaf
.data_ptr
);
975 myleaf
.must_free
= false;
976 myleaf
.data_ptr_used
= true;
977 myleaf
.body
.leaf
.data_ptr
= val_ptr
->bits_ptr
;
979 if (p_td
.raw
->byteorder
== ORDER_MSB
) orders
= true;
980 if (p_td
.raw
->bitorderinfield
== ORDER_LSB
) orders
= !orders
;
981 myleaf
.coding_par
.byteorder
= orders
? ORDER_MSB
: ORDER_LSB
;
983 if (p_td
.raw
->bitorderinoctet
== ORDER_MSB
) orders
= true;
984 if (p_td
.raw
->bitorderinfield
== ORDER_LSB
) orders
= !orders
;
985 myleaf
.coding_par
.bitorder
= orders
? ORDER_MSB
: ORDER_LSB
;
987 if (p_td
.raw
->endianness
== ORDER_MSB
) myleaf
.align
= align_length
;
988 else myleaf
.align
= -align_length
;
990 return myleaf
.length
= bl
+ align_length
;
993 int BITSTRING::RAW_decode(const TTCN_Typedescriptor_t
& p_td
, TTCN_Buffer
& buff
,
994 int limit
, raw_order_t top_bit_ord
, boolean no_err
, int /*sel_field*/,
995 boolean
/*first_call*/)
997 int prepaddlength
= buff
.increase_pos_padd(p_td
.raw
->prepadding
);
998 limit
-= prepaddlength
;
999 int decode_length
= p_td
.raw
->fieldlength
== 0
1000 ? limit
: p_td
.raw
->fieldlength
;
1001 if ( p_td
.raw
->fieldlength
> limit
1002 || p_td
.raw
->fieldlength
> (int) buff
.unread_len_bit()) {
1003 if (no_err
) return -TTCN_EncDec::ET_LEN_ERR
;
1004 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_LEN_ERR
,
1005 "There is not enough bits in the buffer to decode type %s.", p_td
.name
);
1006 decode_length
= limit
> (int) buff
.unread_len_bit()
1007 ? buff
.unread_len_bit() : limit
;
1010 init_struct(decode_length
);
1012 bool orders
= false;
1013 if (p_td
.raw
->bitorderinoctet
== ORDER_MSB
) orders
= true;
1014 if (p_td
.raw
->bitorderinfield
== ORDER_LSB
) orders
= !orders
;
1015 cp
.bitorder
= orders
? ORDER_MSB
: ORDER_LSB
;
1017 if (p_td
.raw
->byteorder
== ORDER_MSB
) orders
= true;
1018 if (p_td
.raw
->bitorderinfield
== ORDER_LSB
) orders
= !orders
;
1019 cp
.byteorder
= orders
? ORDER_MSB
: ORDER_LSB
;
1020 cp
.fieldorder
= p_td
.raw
->fieldorder
;
1021 cp
.hexorder
= ORDER_LSB
;
1022 buff
.get_b((size_t) decode_length
, val_ptr
->bits_ptr
, cp
, top_bit_ord
);
1023 if (p_td
.raw
->length_restrition
!= -1) {
1024 val_ptr
->n_bits
= p_td
.raw
->length_restrition
;
1025 if (p_td
.raw
->endianness
== ORDER_LSB
) {
1026 if ((decode_length
- val_ptr
->n_bits
) % 8) {
1027 int bound
= (decode_length
- val_ptr
->n_bits
) % 8;
1028 int maxindex
= (decode_length
- 1) / 8;
1029 for (int a
= 0, b
= (decode_length
- val_ptr
->n_bits
- 1) / 8;
1030 a
< (val_ptr
->n_bits
+ 7) / 8; a
++, b
++) {
1031 val_ptr
->bits_ptr
[a
] = val_ptr
->bits_ptr
[b
] >> bound
;
1033 val_ptr
->bits_ptr
[a
] = val_ptr
->bits_ptr
[b
+ 1] << (8 - bound
);
1037 else memmove(val_ptr
->bits_ptr
,
1038 val_ptr
->bits_ptr
+ (decode_length
- val_ptr
->n_bits
) / 8,
1039 val_ptr
->n_bits
/ 8 * sizeof(unsigned char));
1042 decode_length
+= buff
.increase_pos_padd(p_td
.raw
->padding
);
1043 clear_unused_bits();
1044 return decode_length
+ prepaddlength
;
1047 int BITSTRING::XER_encode(const XERdescriptor_t
& p_td
,
1048 TTCN_Buffer
& p_buf
, unsigned int flavor
, int indent
, embed_values_enc_struct_t
*) const
1051 TTCN_EncDec_ErrorContext::error
1052 (TTCN_EncDec::ET_UNBOUND
, "Encoding an unbound bitstring value.");
1055 int encoded_length
=(int)p_buf
.get_len();
1056 int empty_element
= val_ptr
==NULL
|| val_ptr
->n_bits
== 0;
1057 flavor
|= SIMPLE_TYPE
;
1058 flavor
&= ~XER_RECOF
; // bitstring doesn't care
1060 begin_xml(p_td
, p_buf
, flavor
, indent
, empty_element
);
1062 if (!empty_element
) {
1063 for (int bit_count
= 0; bit_count
< val_ptr
->n_bits
; bit_count
++)
1064 p_buf
.put_c(get_bit(bit_count
) ? '1' : '0');
1067 end_xml(p_td
, p_buf
, flavor
, indent
, empty_element
);
1068 return (int)p_buf
.get_len() - encoded_length
;
1071 int BITSTRING::XER_decode(const XERdescriptor_t
& p_td
, XmlReaderWrap
& reader
,
1072 unsigned int flavor
, embed_values_dec_struct_t
*)
1074 int exer
= is_exer(flavor
);
1075 int success
= reader
.Ok(), depth
= -1, type
;
1076 boolean own_tag
= !is_exerlist(flavor
) && !(exer
&& (p_td
.xer_bits
& UNTAGGED
));
1078 if (exer
&& (p_td
.xer_bits
& XER_ATTRIBUTE
)) {
1079 const char * name
= verify_name(reader
, p_td
, exer
);
1083 for (; success
== 1; success
= reader
.Read()) {
1084 type
= reader
.NodeType();
1085 if (XML_READER_TYPE_ELEMENT
== type
) {
1086 verify_name(reader
, p_td
, exer
);
1087 depth
= reader
.Depth();
1088 if (reader
.IsEmptyElement()) {
1094 else if (XML_READER_TYPE_TEXT
== type
&& depth
!= -1) break;
1095 else if (XML_READER_TYPE_END_ELEMENT
== type
) {
1096 // End tag without intervening #text == empty content
1097 verify_end(reader
, p_td
, depth
, exer
);
1105 type
= reader
.NodeType();
1106 if (success
== 1 && (XML_READER_TYPE_TEXT
== type
|| XML_READER_TYPE_ATTRIBUTE
== type
)) {
1107 const char* value
= (const char *)reader
.Value();
1108 size_t num_bits
= strlen(value
);
1109 init_struct(num_bits
);
1110 for (size_t i
= 0; i
< num_bits
; ++i
) {
1111 if (value
[i
] < '0' || value
[i
] > '1') {
1112 if (exer
&& (flavor
& EXIT_ON_ERROR
)) {
1116 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG
,
1117 "The bitstring value may only contain ones and zeros.");
1120 set_bit(i
, value
[i
] - '0');
1124 if (exer
&& (p_td
.xer_bits
& XER_ATTRIBUTE
)) {
1125 // Let the caller do reader.AdvanceAttribute();
1128 for (success
= reader
.Read(); success
== 1; success
= reader
.Read()) {
1129 type
= reader
.NodeType();
1130 if (XML_READER_TYPE_END_ELEMENT
== type
) {
1131 verify_end(reader
, p_td
, depth
, exer
);
1132 reader
.Read(); // one last time
1140 int BITSTRING::JSON_encode(const TTCN_Typedescriptor_t
&, JSON_Tokenizer
& p_tok
) const
1143 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND
,
1144 "Encoding an unbound bitstring value.");
1148 char* tmp_str
= (char*)Malloc(val_ptr
->n_bits
+ 3);
1150 tmp_str
[val_ptr
->n_bits
+ 1] = '\"';
1151 for (int i
= 0; i
< val_ptr
->n_bits
; ++i
) {
1152 tmp_str
[i
+ 1] = get_bit(i
) ? '1' : '0';
1154 tmp_str
[val_ptr
->n_bits
+ 2] = 0;
1155 int enc_len
= p_tok
.put_next_token(JSON_TOKEN_STRING
, tmp_str
);
1160 int BITSTRING::JSON_decode(const TTCN_Typedescriptor_t
& p_td
, JSON_Tokenizer
& p_tok
, boolean p_silent
)
1162 json_token_t token
= JSON_TOKEN_NONE
;
1164 size_t value_len
= 0;
1165 boolean error
= false;
1167 boolean use_default
= p_td
.json
->default_value
&& 0 == p_tok
.get_buffer_length();
1169 // No JSON data in the buffer -> use default value
1170 value
= (char*)p_td
.json
->default_value
;
1171 value_len
= strlen(value
);
1173 dec_len
= p_tok
.get_next_token(&token
, &value
, &value_len
);
1175 if (JSON_TOKEN_ERROR
== token
) {
1176 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG
, JSON_DEC_BAD_TOKEN_ERROR
, "");
1177 return JSON_ERROR_FATAL
;
1179 else if (JSON_TOKEN_STRING
== token
|| use_default
) {
1180 if (use_default
|| (value_len
> 2 && value
[0] == '\"' && value
[value_len
- 1] == '\"')) {
1182 // The default value doesn't have quotes around it
1186 init_struct(value_len
);
1187 for (size_t i
= 0; i
< value_len
; ++i
) {
1188 if ('0' <= value
[i
] && '1' >= value
[i
]) {
1189 set_bit(i
, value
[i
] - '0');
1199 return JSON_ERROR_INVALID_TOKEN
;
1203 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG
, JSON_DEC_FORMAT_ERROR
, "string", "bitstring");
1207 return JSON_ERROR_FATAL
;
1213 // bitstring element class
1215 BITSTRING_ELEMENT::BITSTRING_ELEMENT(boolean par_bound_flag
,
1216 BITSTRING
& par_str_val
, int par_bit_pos
)
1217 : bound_flag(par_bound_flag
), str_val(par_str_val
), bit_pos(par_bit_pos
)
1221 BITSTRING_ELEMENT
& BITSTRING_ELEMENT::operator=(const BITSTRING
& other_value
)
1223 other_value
.must_bound("Assignment of an unbound bitstring value.");
1224 if(other_value
.val_ptr
->n_bits
!= 1)
1225 TTCN_error("Assignment of a bitstring "
1226 "value with length other than 1 to a bitstring element.");
1228 str_val
.copy_value();
1229 str_val
.set_bit(bit_pos
, other_value
.get_bit(0));
1233 BITSTRING_ELEMENT
& BITSTRING_ELEMENT::operator=
1234 (const BITSTRING_ELEMENT
& other_value
)
1236 other_value
.must_bound("Assignment of an unbound bitstring element.");
1238 str_val
.copy_value();
1239 str_val
.set_bit(bit_pos
, other_value
.str_val
.get_bit(other_value
.bit_pos
));
1243 boolean
BITSTRING_ELEMENT::operator==(const BITSTRING
& other_value
) const
1245 must_bound("Unbound left operand of bitstring element comparison.");
1246 other_value
.must_bound("Unbound right operand of bitstring comparison.");
1247 if(other_value
.val_ptr
->n_bits
!= 1) return FALSE
;
1248 return str_val
.get_bit(bit_pos
) == other_value
.get_bit(0);
1251 boolean
BITSTRING_ELEMENT::operator==
1252 (const BITSTRING_ELEMENT
& other_value
) const
1254 must_bound("Unbound left operand of bitstring element comparison.");
1255 other_value
.must_bound("Unbound right operand of bitstring element "
1257 return str_val
.get_bit(bit_pos
) ==
1258 other_value
.str_val
.get_bit(other_value
.bit_pos
);
1261 BITSTRING
BITSTRING_ELEMENT::operator+(const BITSTRING
& other_value
) const
1263 must_bound("Unbound left operand of bitstring element concatenation.");
1264 other_value
.must_bound("Unbound right operand of bitstring concatenation.");
1265 int n_bits
= other_value
.val_ptr
->n_bits
;
1266 BITSTRING
ret_val(n_bits
+ 1);
1267 ret_val
.val_ptr
->bits_ptr
[0] = str_val
.get_bit(bit_pos
) ? 1 : 0;
1268 int n_bytes
= (n_bits
+ 7) / 8;
1269 for (int byte_count
= 0; byte_count
< n_bytes
; byte_count
++) {
1270 ret_val
.val_ptr
->bits_ptr
[byte_count
] |=
1271 other_value
.val_ptr
->bits_ptr
[byte_count
] << 1;
1272 if (n_bits
> byte_count
* 8 + 7)
1273 ret_val
.val_ptr
->bits_ptr
[byte_count
+ 1] =
1274 other_value
.val_ptr
->bits_ptr
[byte_count
] >> 7;
1276 ret_val
.clear_unused_bits();
1280 BITSTRING
BITSTRING_ELEMENT::operator+(const BITSTRING_ELEMENT
& other_value
)
1283 must_bound("Unbound left operand of bitstring element concatenation.");
1284 other_value
.must_bound("Unbound right operand of bitstring element "
1286 unsigned char result
= str_val
.get_bit(bit_pos
) ? 1 : 0;
1287 if (other_value
.str_val
.get_bit(other_value
.bit_pos
)) result
|= 2;
1288 return BITSTRING(2, &result
);
1291 BITSTRING
BITSTRING_ELEMENT::operator~() const
1293 must_bound("Unbound bitstring element operand of operator not4b.");
1294 unsigned char result
= str_val
.get_bit(bit_pos
) ? 0 : 1;
1295 return BITSTRING(1, &result
);
1298 BITSTRING
BITSTRING_ELEMENT::operator&(const BITSTRING
& other_value
) const
1300 must_bound("Left operand of operator and4b is an unbound bitstring element.");
1301 other_value
.must_bound("Right operand of operator and4b is an unbound "
1302 "bitstring value.");
1303 if (other_value
.val_ptr
->n_bits
!= 1)
1304 TTCN_error("The bitstring operands "
1305 "of operator and4b must have the same length.");
1306 unsigned char result
= str_val
.get_bit(bit_pos
) && other_value
.get_bit(0) ?
1308 return BITSTRING(1, &result
);
1311 BITSTRING
BITSTRING_ELEMENT::operator&
1312 (const BITSTRING_ELEMENT
& other_value
) const
1314 must_bound("Left operand of operator and4b is an unbound bitstring element.");
1315 other_value
.must_bound("Right operand of operator and4b is an unbound "
1316 "bitstring element.");
1317 unsigned char result
= str_val
.get_bit(bit_pos
) &&
1318 other_value
.str_val
.get_bit(other_value
.bit_pos
) ? 1 : 0;
1319 return BITSTRING(1, &result
);
1322 BITSTRING
BITSTRING_ELEMENT::operator|(const BITSTRING
& other_value
) const
1324 must_bound("Left operand of operator or4b is an unbound bitstring element.");
1325 other_value
.must_bound("Right operand of operator or4b is an unbound "
1326 "bitstring value.");
1327 if (other_value
.val_ptr
->n_bits
!= 1)
1328 TTCN_error("The bitstring operands "
1329 "of operator or4b must have the same length.");
1330 unsigned char result
= str_val
.get_bit(bit_pos
) || other_value
.get_bit(0) ?
1332 return BITSTRING(1, &result
);
1335 BITSTRING
BITSTRING_ELEMENT::operator|
1336 (const BITSTRING_ELEMENT
& other_value
) const
1338 must_bound("Left operand of operator or4b is an unbound bitstring element.");
1339 other_value
.must_bound("Right operand of operator or4b is an unbound "
1340 "bitstring element.");
1341 unsigned char result
= str_val
.get_bit(bit_pos
) ||
1342 other_value
.str_val
.get_bit(other_value
.bit_pos
) ? 1 : 0;
1343 return BITSTRING(1, &result
);
1346 BITSTRING
BITSTRING_ELEMENT::operator^(const BITSTRING
& other_value
) const
1348 must_bound("Left operand of operator xor4b is an unbound bitstring element.");
1349 other_value
.must_bound("Right operand of operator xor4b is an unbound "
1350 "bitstring value.");
1351 if (other_value
.val_ptr
->n_bits
!= 1)
1352 TTCN_error("The bitstring operands "
1353 "of operator xor4b must have the same length.");
1354 unsigned char result
= str_val
.get_bit(bit_pos
) != other_value
.get_bit(0) ?
1356 return BITSTRING(1, &result
);
1359 BITSTRING
BITSTRING_ELEMENT::operator^
1360 (const BITSTRING_ELEMENT
& other_value
) const
1362 must_bound("Left operand of operator xor4b is an unbound bitstring element.");
1363 other_value
.must_bound("Right operand of operator xor4b is an unbound "
1364 "bitstring element.");
1365 unsigned char result
= str_val
.get_bit(bit_pos
) !=
1366 other_value
.str_val
.get_bit(other_value
.bit_pos
) ? 1 : 0;
1367 return BITSTRING(1, &result
);
1370 boolean
BITSTRING_ELEMENT::get_bit() const
1372 return str_val
.get_bit(bit_pos
);
1375 void BITSTRING_ELEMENT::log() const
1377 if (bound_flag
) TTCN_Logger::log_event("'%c'B", str_val
.get_bit(bit_pos
) ?
1379 else TTCN_Logger::log_event_unbound();
1382 // bitstring template class
1384 void BITSTRING_template::clean_up()
1386 switch (template_selection
) {
1388 case COMPLEMENTED_LIST
:
1389 delete [] value_list
.list_value
;
1391 case STRING_PATTERN
:
1392 if (pattern_value
->ref_count
> 1) pattern_value
->ref_count
--;
1393 else if (pattern_value
->ref_count
== 1) Free(pattern_value
);
1394 else TTCN_error("Internal error: Invalid reference counter in a bitstring "
1400 template_selection
= UNINITIALIZED_TEMPLATE
;
1403 void BITSTRING_template::copy_template(const BITSTRING_template
& other_value
)
1405 switch (other_value
.template_selection
) {
1406 case SPECIFIC_VALUE
:
1407 single_value
= other_value
.single_value
;
1414 case COMPLEMENTED_LIST
:
1415 value_list
.n_values
= other_value
.value_list
.n_values
;
1416 value_list
.list_value
= new BITSTRING_template
[value_list
.n_values
];
1417 for (unsigned int i
= 0; i
< value_list
.n_values
; i
++)
1418 value_list
.list_value
[i
].copy_template(
1419 other_value
.value_list
.list_value
[i
]);
1421 case STRING_PATTERN
:
1422 pattern_value
= other_value
.pattern_value
;
1423 pattern_value
->ref_count
++;
1426 TTCN_error("Copying an uninitialized/unsupported bitstring template.");
1428 set_selection(other_value
);
1432 This is the same algorithm that match_array uses
1433 to match 'record of' types.
1434 The only differences are: how two elements are matched and
1435 how an asterisk or ? is identified in the template
1437 boolean
BITSTRING_template::match_pattern(
1438 const bitstring_pattern_struct
*string_pattern
,
1439 const BITSTRING::bitstring_struct
*string_value
)
1441 if(string_pattern
->n_elements
== 0) return string_value
->n_bits
== 0;
1443 int value_index
= 0;
1444 unsigned int template_index
= 0;
1445 int last_asterisk
= -1;
1446 int last_value_to_asterisk
= -1;
1450 switch(string_pattern
->elements_ptr
[template_index
]) {
1452 if (!(string_value
->bits_ptr
[value_index
/ 8] &
1453 (1 << (value_index
% 8))))
1458 if(last_asterisk
== -1) return FALSE
;
1459 template_index
= last_asterisk
+1;
1460 value_index
= ++last_value_to_asterisk
;
1464 if (string_value
->bits_ptr
[value_index
/ 8] & (1 << (value_index
% 8)))
1469 if(last_asterisk
== -1) return FALSE
;
1470 template_index
= last_asterisk
+1;
1471 value_index
= ++last_value_to_asterisk
;
1475 //we found a ? element, it matches anything
1480 //we found an asterisk
1481 last_asterisk
= template_index
++;
1482 last_value_to_asterisk
= value_index
;
1485 TTCN_error("Internal error: invalid element in bitstring pattern.");
1488 if(value_index
== string_value
->n_bits
1489 && template_index
== string_pattern
->n_elements
)
1492 }else if(template_index
== string_pattern
->n_elements
)
1494 if(string_pattern
->elements_ptr
[template_index
-1] == 3)
1497 } else if (last_asterisk
== -1){
1500 template_index
= last_asterisk
+1;
1501 value_index
= ++last_value_to_asterisk
;
1503 } else if(value_index
== string_value
->n_bits
)
1505 while(template_index
< string_pattern
->n_elements
&&
1506 string_pattern
->elements_ptr
[template_index
] == 3)
1509 return template_index
== string_pattern
->n_elements
;
1514 BITSTRING_template::BITSTRING_template()
1518 BITSTRING_template::BITSTRING_template(template_sel other_value
)
1519 : Restricted_Length_Template(other_value
)
1521 check_single_selection(other_value
);
1524 BITSTRING_template::BITSTRING_template(const BITSTRING
& other_value
)
1525 : Restricted_Length_Template(SPECIFIC_VALUE
), single_value(other_value
)
1529 BITSTRING_template::BITSTRING_template(const BITSTRING_ELEMENT
& other_value
)
1530 : Restricted_Length_Template(SPECIFIC_VALUE
), single_value(other_value
)
1534 BITSTRING_template::~BITSTRING_template()
1539 BITSTRING_template::BITSTRING_template(const OPTIONAL
<BITSTRING
>& other_value
)
1541 switch (other_value
.get_selection()) {
1542 case OPTIONAL_PRESENT
:
1543 set_selection(SPECIFIC_VALUE
);
1544 single_value
= (const BITSTRING
&)other_value
;
1547 set_selection(OMIT_VALUE
);
1550 TTCN_error("Creating a bitstring template from an unbound optional field.");
1554 BITSTRING_template::BITSTRING_template(unsigned int n_elements
,
1555 const unsigned char *pattern_elements
)
1556 : Restricted_Length_Template(STRING_PATTERN
)
1558 pattern_value
= (bitstring_pattern_struct
*)
1559 Malloc(sizeof(bitstring_pattern_struct
) + n_elements
- 1);
1560 pattern_value
->ref_count
= 1;
1561 pattern_value
->n_elements
= n_elements
;
1562 memcpy(pattern_value
->elements_ptr
, pattern_elements
, n_elements
);
1565 BITSTRING_template::BITSTRING_template(const BITSTRING_template
& other_value
)
1566 : Restricted_Length_Template()
1568 copy_template(other_value
);
1571 BITSTRING_template
& BITSTRING_template::operator=(template_sel other_value
)
1573 check_single_selection(other_value
);
1575 set_selection(other_value
);
1579 BITSTRING_template
& BITSTRING_template::operator=(const BITSTRING
& other_value
)
1581 other_value
.must_bound("Assignment of an unbound bitstring value to a "
1584 set_selection(SPECIFIC_VALUE
);
1585 single_value
= other_value
;
1589 BITSTRING_template
& BITSTRING_template::operator=
1590 (const BITSTRING_ELEMENT
& other_value
)
1592 other_value
.must_bound("Assignment of an unbound bitstring element to a "
1595 set_selection(SPECIFIC_VALUE
);
1596 single_value
= other_value
;
1600 BITSTRING_template
& BITSTRING_template::operator=
1601 (const OPTIONAL
<BITSTRING
>& other_value
)
1604 switch (other_value
.get_selection()) {
1605 case OPTIONAL_PRESENT
:
1606 set_selection(SPECIFIC_VALUE
);
1607 single_value
= (const BITSTRING
&)other_value
;
1610 set_selection(OMIT_VALUE
);
1613 TTCN_error("Assignment of an unbound optional field to a bitstring "
1619 BITSTRING_template
& BITSTRING_template::operator=
1620 (const BITSTRING_template
& other_value
)
1622 if (&other_value
!= this) {
1624 copy_template(other_value
);
1629 BITSTRING_ELEMENT
BITSTRING_template::operator[](int index_value
)
1631 if (template_selection
!= SPECIFIC_VALUE
|| is_ifpresent
)
1632 TTCN_error("Accessing a bitstring element of a non-specific bitstring "
1634 return single_value
[index_value
];
1637 BITSTRING_ELEMENT
BITSTRING_template::operator[](const INTEGER
& index_value
)
1639 index_value
.must_bound("Indexing a bitstring template with an unbound "
1641 return (*this)[(int)index_value
];
1644 const BITSTRING_ELEMENT
BITSTRING_template::operator[](int index_value
) const
1646 if (template_selection
!= SPECIFIC_VALUE
|| is_ifpresent
)
1647 TTCN_error("Accessing a bitstring element of a non-specific bitstring "
1649 return single_value
[index_value
];
1652 const BITSTRING_ELEMENT
BITSTRING_template::operator[](const INTEGER
& index_value
) const
1654 index_value
.must_bound("Indexing a bitstring template with an unbound "
1656 return (*this)[(int)index_value
];
1659 boolean
BITSTRING_template::match(const BITSTRING
& other_value
,
1660 boolean
/* legacy */) const
1662 if (!other_value
.is_bound()) return FALSE
;
1663 if (!match_length(other_value
.val_ptr
->n_bits
)) return FALSE
;
1664 switch (template_selection
) {
1665 case SPECIFIC_VALUE
:
1666 return single_value
== other_value
;
1673 case COMPLEMENTED_LIST
:
1674 for (unsigned int i
= 0; i
< value_list
.n_values
; i
++)
1675 if (value_list
.list_value
[i
].match(other_value
))
1676 return template_selection
== VALUE_LIST
;
1677 return template_selection
== COMPLEMENTED_LIST
;
1678 case STRING_PATTERN
:
1679 return match_pattern(pattern_value
, other_value
.val_ptr
);
1681 TTCN_error("Matching an uninitialized/unsupported bitstring template.");
1686 const BITSTRING
& BITSTRING_template::valueof() const
1688 if (template_selection
!= SPECIFIC_VALUE
|| is_ifpresent
)
1689 TTCN_error("Performing a valueof or send operation on a non-specific "
1690 "bitstring template.");
1691 return single_value
;
1694 int BITSTRING_template::lengthof() const
1697 boolean has_any_or_none
;
1699 TTCN_error("Performing lengthof() operation on a bitstring template "
1700 "which has an ifpresent attribute.");
1701 switch (template_selection
)
1703 case SPECIFIC_VALUE
:
1704 min_length
= single_value
.lengthof();
1705 has_any_or_none
= FALSE
;
1708 TTCN_error("Performing lengthof() operation on a bitstring template "
1709 "containing omit value.");
1713 has_any_or_none
= TRUE
; // max. length is infinity
1717 // error if any element does not have length or the lengths differ
1718 if (value_list
.n_values
<1)
1719 TTCN_error("Internal error: "
1720 "Performing lengthof() operation on a bitstring template "
1721 "containing an empty list.");
1722 int item_length
= value_list
.list_value
[0].lengthof();
1723 for (unsigned int i
= 1; i
< value_list
.n_values
; i
++) {
1724 if (value_list
.list_value
[i
].lengthof()!=item_length
)
1725 TTCN_error("Performing lengthof() operation on a bitstring template "
1726 "containing a value list with different lengths.");
1728 min_length
= item_length
;
1729 has_any_or_none
= FALSE
;
1732 case COMPLEMENTED_LIST
:
1733 TTCN_error("Performing lengthof() operation on a bitstring template "
1734 "containing complemented list.");
1735 case STRING_PATTERN
:
1737 has_any_or_none
= FALSE
; // TRUE if * chars in the pattern
1738 for (unsigned int i
= 0; i
< pattern_value
->n_elements
; i
++)
1740 if (pattern_value
->elements_ptr
[i
] < 3) min_length
++; // case of 1, 0, ?
1741 else has_any_or_none
= TRUE
; // case of * character
1745 TTCN_error("Performing lengthof() operation on an "
1746 "uninitialized/unsupported bitstring template.");
1748 return check_section_is_single(min_length
, has_any_or_none
,
1749 "length", "a", "bitstring template");
1752 void BITSTRING_template::set_type(template_sel template_type
,
1753 unsigned int list_length
)
1755 if (template_type
!= VALUE_LIST
&& template_type
!= COMPLEMENTED_LIST
)
1756 TTCN_error("Setting an invalid list type for a bitstring template.");
1758 set_selection(template_type
);
1759 value_list
.n_values
= list_length
;
1760 value_list
.list_value
= new BITSTRING_template
[list_length
];
1763 BITSTRING_template
& BITSTRING_template::list_item(unsigned int list_index
)
1765 if (template_selection
!= VALUE_LIST
&&
1766 template_selection
!= COMPLEMENTED_LIST
)
1767 TTCN_error("Accessing a list element of a non-list bitstring template.");
1768 if (list_index
>= value_list
.n_values
)
1769 TTCN_error("Index overflow in a bitstring value list template.");
1770 return value_list
.list_value
[list_index
];
1773 static const char patterns
[] = { '0', '1', '?', '*' };
1775 void BITSTRING_template::log() const
1777 switch (template_selection
) {
1778 case SPECIFIC_VALUE
:
1781 case COMPLEMENTED_LIST
:
1782 TTCN_Logger::log_event_str("complement ");
1785 TTCN_Logger::log_char('(');
1786 for (unsigned int i
= 0; i
< value_list
.n_values
; i
++) {
1787 if (i
> 0) TTCN_Logger::log_event_str(", ");
1788 value_list
.list_value
[i
].log();
1790 TTCN_Logger::log_char(')');
1792 case STRING_PATTERN
:
1793 TTCN_Logger::log_char('\'');
1794 for (unsigned int i
= 0; i
< pattern_value
->n_elements
; i
++) {
1795 unsigned char pattern
= pattern_value
->elements_ptr
[i
];
1796 if (pattern
< 4) TTCN_Logger::log_char(patterns
[pattern
]);
1797 else TTCN_Logger::log_event_str("<unknown>");
1799 TTCN_Logger::log_event_str("'B");
1809 void BITSTRING_template::log_match(const BITSTRING
& match_value
,
1810 boolean
/* legacy */) const
1812 if (TTCN_Logger::VERBOSITY_COMPACT
== TTCN_Logger::get_matching_verbosity()
1813 && TTCN_Logger::get_logmatch_buffer_len() != 0) {
1814 TTCN_Logger::print_logmatch_buffer();
1815 TTCN_Logger::log_event_str(" := ");
1818 TTCN_Logger::log_event_str(" with ");
1820 if (match(match_value
)) TTCN_Logger::log_event_str(" matched");
1821 else TTCN_Logger::log_event_str(" unmatched");
1824 void BITSTRING_template::set_param(Module_Param
& param
) {
1825 param
.basic_check(Module_Param::BC_TEMPLATE
|Module_Param::BC_LIST
, "bitstring template");
1826 Module_Param_Ptr mp
= ¶m
;
1827 if (param
.get_type() == Module_Param::MP_Reference
) {
1828 mp
= param
.get_referenced_param();
1830 switch (mp
->get_type()) {
1831 case Module_Param::MP_Omit
:
1834 case Module_Param::MP_Any
:
1837 case Module_Param::MP_AnyOrNone
:
1838 *this = ANY_OR_OMIT
;
1840 case Module_Param::MP_List_Template
:
1841 case Module_Param::MP_ComplementList_Template
: {
1842 BITSTRING_template temp
;
1843 temp
.set_type(mp
->get_type() == Module_Param::MP_List_Template
?
1844 VALUE_LIST
: COMPLEMENTED_LIST
, mp
->get_size());
1845 for (size_t i
=0; i
<mp
->get_size(); i
++) {
1846 temp
.list_item(i
).set_param(*mp
->get_elem(i
));
1850 case Module_Param::MP_Bitstring
:
1851 *this = BITSTRING(mp
->get_string_size(), (unsigned char*)mp
->get_string_data());
1853 case Module_Param::MP_Bitstring_Template
:
1854 *this = BITSTRING_template(mp
->get_string_size(), (unsigned char*)mp
->get_string_data());
1856 case Module_Param::MP_Expression
:
1857 if (mp
->get_expr_type() == Module_Param::EXPR_CONCATENATE
) {
1858 BITSTRING operand1
, operand2
;
1859 operand1
.set_param(*mp
->get_operand1());
1860 operand2
.set_param(*mp
->get_operand2());
1861 *this = operand1
+ operand2
;
1864 param
.expr_type_error("a bitstring");
1868 param
.type_error("bitstring template");
1870 is_ifpresent
= param
.get_ifpresent() || mp
->get_ifpresent();
1871 if (param
.get_length_restriction() != NULL
) {
1872 set_length_range(param
);
1875 set_length_range(*mp
);
1879 Module_Param
* BITSTRING_template::get_param(Module_Param_Name
& param_name
) const
1881 Module_Param
* mp
= NULL
;
1882 switch (template_selection
) {
1883 case UNINITIALIZED_TEMPLATE
:
1884 mp
= new Module_Param_Unbound();
1887 mp
= new Module_Param_Omit();
1890 mp
= new Module_Param_Any();
1893 mp
= new Module_Param_AnyOrNone();
1895 case SPECIFIC_VALUE
:
1896 mp
= single_value
.get_param(param_name
);
1899 case COMPLEMENTED_LIST
: {
1900 if (template_selection
== VALUE_LIST
) {
1901 mp
= new Module_Param_List_Template();
1904 mp
= new Module_Param_ComplementList_Template();
1906 for (size_t i
= 0; i
< value_list
.n_values
; ++i
) {
1907 mp
->add_elem(value_list
.list_value
[i
].get_param(param_name
));
1910 case STRING_PATTERN
: {
1911 unsigned char* val_cpy
= (unsigned char*)Malloc(pattern_value
->n_elements
);
1912 memcpy(val_cpy
, pattern_value
->elements_ptr
, pattern_value
->n_elements
);
1913 mp
= new Module_Param_Bitstring_Template(pattern_value
->n_elements
, val_cpy
);
1919 mp
->set_ifpresent();
1921 mp
->set_length_restriction(get_length_range());
1925 void BITSTRING_template::encode_text(Text_Buf
& text_buf
) const
1927 encode_text_restricted(text_buf
);
1928 switch (template_selection
) {
1933 case SPECIFIC_VALUE
:
1934 single_value
.encode_text(text_buf
);
1937 case COMPLEMENTED_LIST
:
1938 text_buf
.push_int(value_list
.n_values
);
1939 for (unsigned int i
= 0; i
< value_list
.n_values
; i
++)
1940 value_list
.list_value
[i
].encode_text(text_buf
);
1942 case STRING_PATTERN
:
1943 text_buf
.push_int(pattern_value
->n_elements
);
1944 text_buf
.push_raw(pattern_value
->n_elements
, pattern_value
->elements_ptr
);
1947 TTCN_error("Text encoder: Encoding an uninitialized/unsupported "
1948 "bitstring template.");
1952 void BITSTRING_template::decode_text(Text_Buf
& text_buf
)
1955 decode_text_restricted(text_buf
);
1956 switch (template_selection
) {
1961 case SPECIFIC_VALUE
:
1962 single_value
.decode_text(text_buf
);
1965 case COMPLEMENTED_LIST
:
1966 value_list
.n_values
= text_buf
.pull_int().get_val();
1967 value_list
.list_value
= new BITSTRING_template
[value_list
.n_values
];
1968 for (unsigned int i
= 0; i
< value_list
.n_values
; i
++)
1969 value_list
.list_value
[i
].decode_text(text_buf
);
1971 case STRING_PATTERN
: {
1972 unsigned int n_elements
= text_buf
.pull_int().get_val();
1973 pattern_value
= (bitstring_pattern_struct
*)
1974 Malloc(sizeof(bitstring_pattern_struct
) + n_elements
- 1);
1975 pattern_value
->ref_count
= 1;
1976 pattern_value
->n_elements
= n_elements
;
1977 text_buf
.pull_raw(n_elements
, pattern_value
->elements_ptr
);
1980 TTCN_error("Text decoder: An unknown/unsupported selection was "
1981 "received for a bitstring template.");
1985 boolean
BITSTRING_template::is_present(boolean legacy
/* = FALSE */) const
1987 if (template_selection
==UNINITIALIZED_TEMPLATE
) return FALSE
;
1988 return !match_omit(legacy
);
1991 boolean
BITSTRING_template::match_omit(boolean legacy
/* = FALSE */) const
1993 if (is_ifpresent
) return TRUE
;
1994 switch (template_selection
) {
1999 case COMPLEMENTED_LIST
:
2001 // legacy behavior: 'omit' can appear in the value/complement list
2002 for (unsigned int i
=0; i
<value_list
.n_values
; i
++)
2003 if (value_list
.list_value
[i
].match_omit())
2004 return template_selection
==VALUE_LIST
;
2005 return template_selection
==COMPLEMENTED_LIST
;
2007 // else fall through
2014 #ifndef TITAN_RUNTIME_2
2015 void BITSTRING_template::check_restriction(template_res t_res
, const char* t_name
,
2016 boolean legacy
/* = FALSE */) const
2018 if (template_selection
==UNINITIALIZED_TEMPLATE
) return;
2019 switch ((t_name
&&(t_res
==TR_VALUE
))?TR_OMIT
:t_res
) {
2021 if (!is_ifpresent
&& template_selection
==SPECIFIC_VALUE
) return;
2024 if (!is_ifpresent
&& (template_selection
==OMIT_VALUE
||
2025 template_selection
==SPECIFIC_VALUE
)) return;
2028 if (!match_omit(legacy
)) return;
2033 TTCN_error("Restriction `%s' on template of type %s violated.",
2034 get_res_name(t_res
), t_name
? t_name
: "bitstring");
2037 int BITSTRING::RAW_encode_negtest_raw(RAW_enc_tree
& p_myleaf
) const
2039 if (p_myleaf
.must_free
)
2040 Free(p_myleaf
.body
.leaf
.data_ptr
);
2041 p_myleaf
.must_free
= false;
2042 p_myleaf
.data_ptr_used
= true;
2043 p_myleaf
.body
.leaf
.data_ptr
= val_ptr
->bits_ptr
;
2044 return p_myleaf
.length
= val_ptr
->n_bits
;