1 /******************************************************************************
2 * Copyright (c) 2000-2016 Ericsson Telecom AB
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
19 * Szabo, Janos Zoltan – initial implementation
23 ******************************************************************************/
26 #include "Bitstring.hh"
27 #include "../common/memory.h"
29 #include "String_struct.hh"
30 #include "Parameters.h"
31 #include "Param_Types.hh"
37 #include "../common/dbgnew.hh"
39 // bitstring value class
41 /** The amount of memory needed for a bitstring containing n bits. */
42 #define MEMORY_SIZE(n) (sizeof(bitstring_struct) - sizeof(int) + ((n) + 7) / 8)
44 void BITSTRING::init_struct(int n_bits
)
48 TTCN_error("Initializing a bitstring with a negative length.");
49 } else if (n_bits
== 0) {
50 /** This will represent the empty strings so they won't need allocated
51 * memory, this delays the memory allocation until it is really needed.
53 static bitstring_struct empty_string
= { 1, 0, "" };
54 val_ptr
= &empty_string
;
55 empty_string
.ref_count
++;
57 val_ptr
= (bitstring_struct
*)Malloc(MEMORY_SIZE(n_bits
));
58 val_ptr
->ref_count
= 1;
59 val_ptr
->n_bits
= n_bits
;
63 boolean
BITSTRING::get_bit(int bit_index
) const
65 return val_ptr
->bits_ptr
[bit_index
/ 8] & (1 << (bit_index
% 8));
68 void BITSTRING::set_bit(int bit_index
, boolean new_value
)
70 unsigned char mask
= 1 << (bit_index
% 8);
71 if (new_value
) val_ptr
->bits_ptr
[bit_index
/ 8] |= mask
;
72 else val_ptr
->bits_ptr
[bit_index
/ 8] &= ~mask
;
75 void BITSTRING::copy_value()
77 if (val_ptr
== NULL
|| val_ptr
->n_bits
<= 0)
78 TTCN_error("Internal error: Invalid internal data structure when copying "
79 "the memory area of a bitstring value.");
80 if (val_ptr
->ref_count
> 1) {
81 bitstring_struct
*old_ptr
= val_ptr
;
83 init_struct(old_ptr
->n_bits
);
84 memcpy(val_ptr
->bits_ptr
, old_ptr
->bits_ptr
, (old_ptr
->n_bits
+ 7) / 8);
88 void BITSTRING::clear_unused_bits() const
90 int n_bits
= val_ptr
->n_bits
;
91 if (n_bits
% 8 != 0) val_ptr
->bits_ptr
[(n_bits
- 1) / 8] &=
92 (unsigned char)'\377' >> (7 - (n_bits
- 1) % 8);
95 BITSTRING::BITSTRING(int n_bits
)
100 BITSTRING::BITSTRING()
105 BITSTRING::BITSTRING(int n_bits
, const unsigned char *bits_ptr
)
108 memcpy(val_ptr
->bits_ptr
, bits_ptr
, (n_bits
+ 7) / 8);
112 BITSTRING::BITSTRING(const BITSTRING
& other_value
)
113 : Base_Type(other_value
)
115 other_value
.must_bound("Copying an unbound bitstring value.");
116 val_ptr
= other_value
.val_ptr
;
117 val_ptr
->ref_count
++;
120 BITSTRING::BITSTRING(const BITSTRING_ELEMENT
& other_value
)
122 other_value
.must_bound("Copying an unbound bitstring element.");
124 val_ptr
->bits_ptr
[0] = other_value
.get_bit() ? 1 : 0;
127 BITSTRING::~BITSTRING()
132 void BITSTRING::clean_up()
134 if (val_ptr
!= NULL
) {
135 if (val_ptr
->ref_count
> 1) val_ptr
->ref_count
--;
136 else if (val_ptr
->ref_count
== 1) Free(val_ptr
);
137 else TTCN_error("Internal error: Invalid reference counter in a bitstring "
143 BITSTRING
& BITSTRING::operator=(const BITSTRING
& other_value
)
145 other_value
.must_bound("Assignment of an unbound bitstring value.");
146 if (&other_value
!= this) {
148 val_ptr
= other_value
.val_ptr
;
149 val_ptr
->ref_count
++;
154 BITSTRING
& BITSTRING::operator=(const BITSTRING_ELEMENT
& other_value
)
156 other_value
.must_bound("Assignment of an unbound bitstring element to a "
158 boolean bit_value
= other_value
.get_bit();
161 val_ptr
->bits_ptr
[0] = bit_value
? 1 : 0;
165 boolean
BITSTRING::operator==(const BITSTRING
& other_value
) const
167 must_bound("Unbound left operand of bitstring comparison.");
168 other_value
.must_bound("Unbound right operand of bitstring comparison.");
169 int n_bits
= val_ptr
->n_bits
;
170 if (n_bits
!= other_value
.val_ptr
->n_bits
) return FALSE
;
171 if (n_bits
== 0) return TRUE
;
173 other_value
.clear_unused_bits();
174 return !memcmp(val_ptr
->bits_ptr
, other_value
.val_ptr
->bits_ptr
,
178 boolean
BITSTRING::operator==(const BITSTRING_ELEMENT
& other_value
) const
180 must_bound("Unbound left operand of bitstring comparison.");
181 other_value
.must_bound("Unbound right operand of bitstring element "
183 if (val_ptr
->n_bits
!= 1) return FALSE
;
184 return get_bit(0) == other_value
.get_bit();
187 BITSTRING
BITSTRING::operator+(const BITSTRING
& other_value
) const
189 must_bound("Unbound left operand of bitstring concatenation.");
190 other_value
.must_bound("Unbound right operand of bitstring concatenation.");
192 int left_n_bits
= val_ptr
->n_bits
;
193 if (left_n_bits
== 0) return other_value
;
195 int right_n_bits
= other_value
.val_ptr
->n_bits
;
196 if (right_n_bits
== 0) return *this;
198 // the length of result
199 int n_bits
= left_n_bits
+ right_n_bits
;
201 // the number of bytes used
202 int left_n_bytes
= (left_n_bits
+ 7) / 8;
203 int right_n_bytes
= (right_n_bits
+ 7) / 8;
205 // the number of bits used in the last incomplete octet of the left operand
206 int left_empty_bits
= left_n_bits
% 8;
209 BITSTRING
ret_val(n_bits
);
211 // pointers to the data areas
212 const unsigned char *left_ptr
= val_ptr
->bits_ptr
;
213 const unsigned char *right_ptr
= other_value
.val_ptr
->bits_ptr
;
214 unsigned char *dest_ptr
= ret_val
.val_ptr
->bits_ptr
;
216 // copying the left fragment into the result
217 memcpy(dest_ptr
, left_ptr
, left_n_bytes
);
219 if (left_empty_bits
!= 0) {
220 // non-trivial case: the length of left fragment is not a multiply of 8
221 // the bytes used in the result
222 int n_bytes
= (n_bits
+ 7) / 8;
223 // placing the bytes from the right fragment until the result is filled
224 for (int i
= left_n_bytes
; i
< n_bytes
; i
++) {
225 unsigned char right_byte
= right_ptr
[i
- left_n_bytes
];
226 // finish filling the previous byte
227 dest_ptr
[i
- 1] |= right_byte
<< left_empty_bits
;
228 // start filling the actual byte
229 dest_ptr
[i
] = right_byte
>> (8 - left_empty_bits
);
231 if (left_n_bytes
+ right_n_bytes
> n_bytes
) {
232 // if the result data area is shorter than the two operands together
233 // the last bits of right fragment were not placed into the result
234 // in the previous for loop
235 dest_ptr
[n_bytes
- 1] |= right_ptr
[right_n_bytes
- 1] << left_empty_bits
;
238 // trivial case: just append the bytes of the right fragment
239 memcpy(dest_ptr
+ left_n_bytes
, right_ptr
, right_n_bytes
);
241 ret_val
.clear_unused_bits();
245 BITSTRING
BITSTRING::operator+(const BITSTRING_ELEMENT
& other_value
) const
247 must_bound("Unbound left operand of bitstring concatenation.");
248 other_value
.must_bound("Unbound right operand of bitstring element "
251 int n_bits
= val_ptr
->n_bits
;
252 BITSTRING
ret_val(n_bits
+ 1);
253 memcpy(ret_val
.val_ptr
->bits_ptr
, val_ptr
->bits_ptr
, (n_bits
+ 7) / 8);
254 ret_val
.set_bit(n_bits
, other_value
.get_bit());
258 BITSTRING
BITSTRING::operator~() const
260 must_bound("Unbound bitstring operand of operator not4b.");
261 int n_bytes
= (val_ptr
->n_bits
+ 7) / 8;
262 if (n_bytes
== 0) return *this;
263 BITSTRING
ret_val(val_ptr
->n_bits
);
264 for (int i
= 0; i
< n_bytes
; i
++)
265 ret_val
.val_ptr
->bits_ptr
[i
] = ~val_ptr
->bits_ptr
[i
];
266 ret_val
.clear_unused_bits();
270 BITSTRING
BITSTRING::operator&(const BITSTRING
& other_value
) const
272 must_bound("Left operand of operator and4b is an unbound bitstring value.");
273 other_value
.must_bound("Right operand of operator and4b is an unbound "
275 int n_bits
= val_ptr
->n_bits
;
276 if (n_bits
!= other_value
.val_ptr
->n_bits
)
277 TTCN_error("The bitstring operands of operator and4b must have the "
279 if (n_bits
== 0) return *this;
280 BITSTRING
ret_val(n_bits
);
281 int n_bytes
= (n_bits
+ 7) / 8;
282 for (int i
= 0; i
< n_bytes
; i
++)
283 ret_val
.val_ptr
->bits_ptr
[i
] = val_ptr
->bits_ptr
[i
] &
284 other_value
.val_ptr
->bits_ptr
[i
];
285 ret_val
.clear_unused_bits();
289 BITSTRING
BITSTRING::operator&(const BITSTRING_ELEMENT
& other_value
) const
291 must_bound("Left operand of operator and4b is an unbound bitstring value.");
292 other_value
.must_bound("Right operand of operator and4b is an unbound "
293 "bitstring element.");
294 if (val_ptr
->n_bits
!= 1)
295 TTCN_error("The bitstring operands of "
296 "operator and4b must have the same length.");
297 unsigned char result
= get_bit(0) && other_value
.get_bit() ? 1 : 0;
298 return BITSTRING(1, &result
);
301 BITSTRING
BITSTRING::operator|(const BITSTRING
& other_value
) const
303 must_bound("Left operand of operator or4b is an unbound bitstring value.");
304 other_value
.must_bound("Right operand of operator or4b is an unbound "
306 int n_bits
= val_ptr
->n_bits
;
307 if (n_bits
!= other_value
.val_ptr
->n_bits
)
308 TTCN_error("The bitstring operands of operator or4b must have the "
310 if (n_bits
== 0) return *this;
311 BITSTRING
ret_val(n_bits
);
312 int n_bytes
= (n_bits
+ 7) / 8;
313 for (int i
= 0; i
< n_bytes
; i
++)
314 ret_val
.val_ptr
->bits_ptr
[i
] = val_ptr
->bits_ptr
[i
] |
315 other_value
.val_ptr
->bits_ptr
[i
];
316 ret_val
.clear_unused_bits();
320 BITSTRING
BITSTRING::operator|(const BITSTRING_ELEMENT
& other_value
) const
322 must_bound("Left operand of operator or4b is an unbound bitstring value.");
323 other_value
.must_bound("Right operand of operator or4b is an unbound "
324 "bitstring element.");
325 if (val_ptr
->n_bits
!= 1)
326 TTCN_error("The bitstring operands of "
327 "operator or4b must have the same length.");
328 unsigned char result
= get_bit(0) || other_value
.get_bit() ? 1 : 0;
329 return BITSTRING(1, &result
);
332 BITSTRING
BITSTRING::operator^(const BITSTRING
& other_value
) const
334 must_bound("Left operand of operator xor4b is an unbound bitstring value.");
335 other_value
.must_bound("Right operand of operator xor4b is an unbound "
337 int n_bits
= val_ptr
->n_bits
;
338 if (n_bits
!= other_value
.val_ptr
->n_bits
)
339 TTCN_error("The bitstring operands of operator xor4b must have the "
341 if (n_bits
== 0) return *this;
342 BITSTRING
ret_val(n_bits
);
343 int n_bytes
= (n_bits
+ 7) / 8;
344 for (int i
= 0; i
< n_bytes
; i
++)
345 ret_val
.val_ptr
->bits_ptr
[i
] = val_ptr
->bits_ptr
[i
] ^
346 other_value
.val_ptr
->bits_ptr
[i
];
347 ret_val
.clear_unused_bits();
351 BITSTRING
BITSTRING::operator^(const BITSTRING_ELEMENT
& other_value
) const
353 must_bound("Left operand of operator xor4b is an unbound bitstring value.");
354 other_value
.must_bound("Right operand of operator xor4b is an unbound "
355 "bitstring element.");
356 if (val_ptr
->n_bits
!= 1)
357 TTCN_error("The bitstring operands of "
358 "operator xor4b must have the same length.");
359 unsigned char result
= get_bit(0) != other_value
.get_bit() ? 1 : 0;
360 return BITSTRING(1, &result
);
363 BITSTRING
BITSTRING::operator<<(int shift_count
) const
365 must_bound("Unbound bitstring operand of shift left operator.");
366 if (shift_count
> 0) {
367 int n_bits
= val_ptr
->n_bits
;
368 if (n_bits
== 0) return *this;
369 BITSTRING
ret_val(n_bits
);
370 int n_bytes
= (n_bits
+ 7) / 8;
372 if (shift_count
> n_bits
) shift_count
= n_bits
;
373 int shift_bytes
= shift_count
/ 8,
374 shift_bits
= shift_count
% 8;
375 if (shift_bits
!= 0) {
377 for ( ; byte_count
< n_bytes
- shift_bytes
- 1; byte_count
++) {
378 ret_val
.val_ptr
->bits_ptr
[byte_count
] =
379 (val_ptr
->bits_ptr
[byte_count
+ shift_bytes
] >> shift_bits
)|
380 (val_ptr
->bits_ptr
[byte_count
+ shift_bytes
+ 1] <<
383 ret_val
.val_ptr
->bits_ptr
[n_bytes
- shift_bytes
- 1] =
384 val_ptr
->bits_ptr
[n_bytes
- 1] >> shift_bits
;
386 memcpy(ret_val
.val_ptr
->bits_ptr
, val_ptr
->bits_ptr
+ shift_bytes
,
387 n_bytes
- shift_bytes
);
389 memset(ret_val
.val_ptr
->bits_ptr
+ n_bytes
- shift_bytes
, 0,
391 ret_val
.clear_unused_bits();
393 } else if (shift_count
== 0) return *this;
394 else return *this >> (-shift_count
);
397 BITSTRING
BITSTRING::operator<<(const INTEGER
& shift_count
) const
399 shift_count
.must_bound("Unbound right operand of bitstring shift left "
401 return *this << (int)shift_count
;
404 BITSTRING
BITSTRING::operator>>(int shift_count
) const
406 must_bound("Unbound bitstring operand of shift right operator.");
407 if (shift_count
> 0) {
408 int n_bits
= val_ptr
->n_bits
;
409 if (n_bits
== 0) return *this;
410 BITSTRING
ret_val(n_bits
);
411 int n_bytes
= (n_bits
+ 7) / 8;
413 if (shift_count
> n_bits
) shift_count
= n_bits
;
414 int shift_bytes
= shift_count
/ 8, shift_bits
= shift_count
% 8;
415 memset(ret_val
.val_ptr
->bits_ptr
, 0, shift_bytes
);
416 if (shift_bits
!= 0) {
417 ret_val
.val_ptr
->bits_ptr
[shift_bytes
] =
418 val_ptr
->bits_ptr
[0] << shift_bits
;
419 for (int byte_count
= shift_bytes
+ 1; byte_count
< n_bytes
; byte_count
++)
421 ret_val
.val_ptr
->bits_ptr
[byte_count
] =
422 (val_ptr
->bits_ptr
[byte_count
- shift_bytes
- 1] >> (8 - shift_bits
))
423 | (val_ptr
->bits_ptr
[byte_count
- shift_bytes
] << shift_bits
);
426 memcpy(ret_val
.val_ptr
->bits_ptr
+ shift_bytes
, val_ptr
->bits_ptr
,
427 n_bytes
- shift_bytes
);
429 ret_val
.clear_unused_bits();
431 } else if (shift_count
== 0) return *this;
432 else return *this << (-shift_count
);
435 BITSTRING
BITSTRING::operator>>(const INTEGER
& shift_count
) const
437 shift_count
.must_bound("Unbound right operand of bitstring shift right "
439 return *this >> (int)shift_count
;
442 BITSTRING
BITSTRING::operator<<=(int rotate_count
) const
444 must_bound("Unbound bistring operand of rotate left operator.");
445 int n_bits
= val_ptr
->n_bits
;
446 if (n_bits
== 0) return *this;
447 if (rotate_count
>= 0) {
448 rotate_count
%= n_bits
;
449 if (rotate_count
== 0) return *this;
450 else return (*this << rotate_count
) |
451 (*this >> (n_bits
- rotate_count
));
452 } else return *this >>= (-rotate_count
);
455 BITSTRING
BITSTRING::operator<<=(const INTEGER
& rotate_count
) const
457 rotate_count
.must_bound("Unbound right operand of bitstring rotate left "
459 return *this <<= (int)rotate_count
;
462 BITSTRING
BITSTRING::operator>>=(int rotate_count
) const
464 must_bound("Unbound bistring operand of rotate right operator.");
465 int n_bits
= val_ptr
->n_bits
;
466 if (n_bits
== 0) return *this;
467 if (rotate_count
>= 0) {
468 rotate_count
%= n_bits
;
469 if (rotate_count
== 0) return *this;
470 else return (*this >> rotate_count
) |
471 (*this << (n_bits
- rotate_count
));
472 } else return *this <<= (-rotate_count
);
475 BITSTRING
BITSTRING::operator>>=(const INTEGER
& rotate_count
) const
477 rotate_count
.must_bound("Unbound right operand of bitstring rotate right "
479 return *this >>= (int)rotate_count
;
482 BITSTRING_ELEMENT
BITSTRING::operator[](int index_value
)
484 if (val_ptr
== NULL
&& index_value
== 0) {
487 return BITSTRING_ELEMENT(FALSE
, *this, 0);
489 must_bound("Accessing an element of an unbound bitstring value.");
490 if (index_value
< 0) TTCN_error("Accessing an bitstring element using "
491 "a negative index (%d).", index_value
);
492 int n_bits
= val_ptr
->n_bits
;
493 if (index_value
> n_bits
) TTCN_error("Index overflow when accessing a "
494 "bitstring element: The index is %d, but the string has only %d bits.",
495 index_value
, n_bits
);
496 if (index_value
== n_bits
) {
497 if (val_ptr
->ref_count
== 1) {
498 if (n_bits
% 8 == 0) val_ptr
= (bitstring_struct
*)
499 Realloc(val_ptr
, MEMORY_SIZE(n_bits
+ 1));
502 bitstring_struct
*old_ptr
= val_ptr
;
503 old_ptr
->ref_count
--;
504 init_struct(n_bits
+ 1);
505 memcpy(val_ptr
->bits_ptr
, old_ptr
->bits_ptr
, (n_bits
+ 7) / 8);
508 return BITSTRING_ELEMENT(FALSE
, *this, index_value
);
509 } else return BITSTRING_ELEMENT(TRUE
, *this, index_value
);
513 BITSTRING_ELEMENT
BITSTRING::operator[](const INTEGER
& index_value
)
515 index_value
.must_bound("Indexing a bitstring value with an unbound integer "
517 return (*this)[(int)index_value
];
520 const BITSTRING_ELEMENT
BITSTRING::operator[](int index_value
) const
522 must_bound("Accessing an element of an unbound bitstring value.");
523 if (index_value
< 0) TTCN_error("Accessing an bitstring element using a "
524 "negative index (%d).", index_value
);
525 if (index_value
>= val_ptr
->n_bits
) TTCN_error("Index overflow when "
526 "accessing a bitstring element: The index is %d, but the string has only "
527 "%d bits.", index_value
, val_ptr
->n_bits
);
528 return BITSTRING_ELEMENT(TRUE
, const_cast<BITSTRING
&>(*this), index_value
);
531 const BITSTRING_ELEMENT
BITSTRING::operator[](const INTEGER
& index_value
) const
533 index_value
.must_bound("Indexing a bitstring value with an unbound integer "
535 return (*this)[(int)index_value
];
538 int BITSTRING::lengthof() const
540 must_bound("Getting the length of an unbound bitstring value.");
541 return val_ptr
->n_bits
;
544 BITSTRING::operator const unsigned char*() const
546 must_bound("Casting an unbound bitstring value to const unsigned char*.");
547 return val_ptr
->bits_ptr
;
550 void BITSTRING::log() const
552 if (val_ptr
!= NULL
) {
553 TTCN_Logger::log_char('\'');
554 for (int bit_count
= 0; bit_count
< val_ptr
->n_bits
; bit_count
++)
555 TTCN_Logger::log_char(get_bit(bit_count
) ? '1' : '0');
556 TTCN_Logger::log_event_str("'B");
557 } else TTCN_Logger::log_event_unbound();
560 void BITSTRING::set_param(Module_Param
& param
) {
561 param
.basic_check(Module_Param::BC_VALUE
|Module_Param::BC_LIST
, "bitstring value");
562 Module_Param_Ptr mp
= ¶m
;
563 if (param
.get_type() == Module_Param::MP_Reference
) {
564 mp
= param
.get_referenced_param();
566 switch (mp
->get_type()) {
567 case Module_Param::MP_Bitstring
:
568 switch (param
.get_operation_type()) {
569 case Module_Param::OT_ASSIGN
:
571 init_struct(mp
->get_string_size());
572 memcpy(val_ptr
->bits_ptr
, mp
->get_string_data(), (val_ptr
->n_bits
+ 7) / 8);
575 case Module_Param::OT_CONCAT
:
577 *this = *this + BITSTRING(mp
->get_string_size(), (unsigned char*)mp
->get_string_data());
579 *this = BITSTRING(mp
->get_string_size(), (unsigned char*)mp
->get_string_data());
583 TTCN_error("Internal error: BITSTRING::set_param()");
586 case Module_Param::MP_Expression
:
587 if (mp
->get_expr_type() == Module_Param::EXPR_CONCATENATE
) {
588 BITSTRING operand1
, operand2
;
589 operand1
.set_param(*mp
->get_operand1());
590 operand2
.set_param(*mp
->get_operand2());
591 if (param
.get_operation_type() == Module_Param::OT_CONCAT
) {
592 *this = *this + operand1
+ operand2
;
595 *this = operand1
+ operand2
;
599 param
.expr_type_error("a bitstring");
603 param
.type_error("bitstring value");
608 Module_Param
* BITSTRING::get_param(Module_Param_Name
& /* param_name */) const
611 return new Module_Param_Unbound();
613 int n_bytes
= (val_ptr
->n_bits
+ 7) / 8;
614 unsigned char* val_cpy
= (unsigned char *)Malloc(n_bytes
);
615 memcpy(val_cpy
, val_ptr
->bits_ptr
, n_bytes
);
616 return new Module_Param_Bitstring(val_ptr
->n_bits
, val_cpy
);
619 void BITSTRING::encode_text(Text_Buf
& text_buf
) const
621 must_bound("Text encoder: Encoding an unbound bitstring value.");
622 int n_bits
= val_ptr
->n_bits
;
623 text_buf
.push_int(n_bits
);
624 if (n_bits
> 0) text_buf
.push_raw((n_bits
+ 7) / 8, val_ptr
->bits_ptr
);
627 void BITSTRING::decode_text(Text_Buf
& text_buf
)
629 int n_bits
= text_buf
.pull_int().get_val();
631 TTCN_error("Text decoder: Invalid length was received for a bitstring.");
635 text_buf
.pull_raw((n_bits
+ 7) / 8, val_ptr
->bits_ptr
);
640 void BITSTRING::encode(const TTCN_Typedescriptor_t
& p_td
, TTCN_Buffer
& p_buf
,
641 TTCN_EncDec::coding_t p_coding
, ...) const
644 va_start(pvar
, p_coding
);
646 case TTCN_EncDec::CT_BER
: {
647 TTCN_EncDec_ErrorContext
ec("While BER-encoding type '%s': ", p_td
.name
);
648 unsigned BER_coding
=va_arg(pvar
, unsigned);
649 BER_encode_chk_coding(BER_coding
);
650 ASN_BER_TLV_t
*tlv
=BER_encode_TLV(p_td
, BER_coding
);
651 tlv
->put_in_buffer(p_buf
);
652 ASN_BER_TLV_t::destruct(tlv
);
654 case TTCN_EncDec::CT_RAW
: {
655 TTCN_EncDec_ErrorContext
ec("While RAW-encoding type '%s': ", p_td
.name
);
657 TTCN_EncDec_ErrorContext::error_internal
658 ("No RAW descriptor available for type '%s'.", p_td
.name
);
662 RAW_enc_tree
root(true,NULL
,&rp
,1,p_td
.raw
);
663 RAW_encode(p_td
, root
);
664 root
.put_to_buf(p_buf
);
666 case TTCN_EncDec::CT_XER
: {
667 TTCN_EncDec_ErrorContext
ec("While XER-encoding type '%s': ", p_td
.name
);
668 unsigned XER_coding
=va_arg(pvar
, unsigned);
669 XER_encode(*p_td
.xer
, p_buf
, XER_coding
, 0, 0);
671 case TTCN_EncDec::CT_JSON
: {
672 TTCN_EncDec_ErrorContext
ec("While JSON-encoding type '%s': ", p_td
.name
);
674 TTCN_EncDec_ErrorContext::error_internal
675 ("No JSON descriptor available for type '%s'.", p_td
.name
);
676 JSON_Tokenizer
tok(va_arg(pvar
, int) != 0);
677 JSON_encode(p_td
, tok
);
678 p_buf
.put_s(tok
.get_buffer_length(), (const unsigned char*)tok
.get_buffer());
681 TTCN_error("Unknown coding method requested to encode type '%s'",
687 void BITSTRING::decode(const TTCN_Typedescriptor_t
& p_td
, TTCN_Buffer
& p_buf
,
688 TTCN_EncDec::coding_t p_coding
, ...)
691 va_start(pvar
, p_coding
);
693 case TTCN_EncDec::CT_BER
: {
694 TTCN_EncDec_ErrorContext
ec("While BER-decoding type '%s': ", p_td
.name
);
695 unsigned L_form
=va_arg(pvar
, unsigned);
697 BER_decode_str2TLV(p_buf
, tlv
, L_form
);
698 BER_decode_TLV(p_td
, tlv
, L_form
);
699 if(tlv
.isComplete
) p_buf
.increase_pos(tlv
.get_len());
701 case TTCN_EncDec::CT_RAW
: {
702 TTCN_EncDec_ErrorContext
ec("While RAW-decoding type '%s': ", p_td
.name
);
704 TTCN_EncDec_ErrorContext::error_internal
705 ("No RAW descriptor available for type '%s'.", p_td
.name
);
707 switch(p_td
.raw
->top_bit_order
){
715 if(RAW_decode(p_td
, p_buf
, p_buf
.get_len()*8, order
)<0)
716 ec
.error(TTCN_EncDec::ET_INCOMPL_MSG
,
717 "Can not decode type '%s', because invalid or incomplete"
718 " message was received"
721 case TTCN_EncDec::CT_XER
: {
722 TTCN_EncDec_ErrorContext
ec("While XER-decoding type '%s': ", p_td
.name
);
723 unsigned XER_coding
=va_arg(pvar
, unsigned);
724 XmlReaderWrap
reader(p_buf
);
725 int success
= reader
.Read();
726 for (; success
==1; success
=reader
.Read()) {
727 int type
= reader
.NodeType();
728 if (type
==XML_READER_TYPE_ELEMENT
)
731 XER_decode(*p_td
.xer
, reader
, XER_coding
, XER_NONE
, 0);
732 size_t bytes
= reader
.ByteConsumed();
733 p_buf
.set_pos(bytes
);
735 case TTCN_EncDec::CT_JSON
: {
736 TTCN_EncDec_ErrorContext
ec("While JSON-decoding type '%s': ", p_td
.name
);
738 TTCN_EncDec_ErrorContext::error_internal
739 ("No JSON descriptor available for type '%s'.", p_td
.name
);
740 JSON_Tokenizer
tok((const char*)p_buf
.get_data(), p_buf
.get_len());
741 if(JSON_decode(p_td
, tok
, false)<0)
742 ec
.error(TTCN_EncDec::ET_INCOMPL_MSG
,
743 "Can not decode type '%s', because invalid or incomplete"
744 " message was received"
746 p_buf
.set_pos(tok
.get_buf_pos());
749 TTCN_error("Unknown coding method requested to decode type '%s'",
755 void BITSTRING::BER_encode_putbits(unsigned char *target
,
756 unsigned int bitnum_start
,
757 unsigned int bit_count
) const
759 unsigned int nof_bits
, nof_octets
, i
, j
;
762 nof_bits
=val_ptr
->n_bits
;
763 if(bitnum_start
>nof_bits
764 || bitnum_start
+bit_count
>nof_bits
)
765 TTCN_EncDec_ErrorContext::error_internal
766 ("In BITSTRING::BER_encode_putbits(): Index overflow.");
767 nof_octets
=(bit_count
+7)/8;
772 target
[0]=(unsigned char)(nof_octets
*8-bit_count
);
773 for(i
=0; i
<nof_octets
-1; i
++) {
777 if(get_bit(bitnum_start
+8*i
+j
)) c
|=0x01;
785 if(get_bit(bitnum_start
+8*i
+j
)) c
|=0x01;
791 BITSTRING::BER_encode_TLV(const TTCN_Typedescriptor_t
& p_td
,
792 unsigned p_coding
) const
795 ASN_BER_TLV_t
*new_tlv
=BER_encode_chk_bound(is_bound());
797 unsigned char *V_ptr
;
799 unsigned int nof_bits
=val_ptr
->n_bits
;
800 unsigned int nof_octets
=(nof_bits
+7)/8;
801 unsigned int nof_fragments
=0;
802 if(p_coding
==BER_ENCODE_CER
) {
803 nof_fragments
=(nof_octets
+998)/999;
804 if(!nof_fragments
) nof_fragments
=1;
806 else /*if(coding==BER_ENCODE_DER)*/ {
810 boolean is_constructed
=nof_fragments
>1;
811 if(!is_constructed
) {
813 V_ptr
=(unsigned char*)Malloc(V_len
);
814 BER_encode_putbits(V_ptr
, 0, nof_bits
);
815 new_tlv
=ASN_BER_TLV_t::construct(V_len
, V_ptr
);
817 else { // is constructed
818 ASN_BER_TLV_t
*tmp_tlv
=NULL
;
819 new_tlv
=ASN_BER_TLV_t::construct(NULL
);
820 unsigned int rest_octets
=nof_octets
-(nof_fragments
-1)*999;
822 V_len=(nof_fragments-1)*1004;
823 V_len+=rest_octets<128?2:4;
824 V_len+=rest_octets+1;
825 V_ptr=(unsigned char*)Malloc(V_len);
828 unsigned int nof_bits_curr
=8*999;
829 for(unsigned int i
=0; i
<nof_fragments
; i
++) {
830 if(i
==nof_fragments
-1) {
832 nof_bits_curr
=nof_bits
-i
*8*999;
834 V_ptr
=(unsigned char*)Malloc(V_len
+1); // because of unused bits-octet
841 BER_encode_putbits(V_ptr
, i
*8*999, nof_bits_curr
);
845 tmp_tlv
=ASN_BER_TLV_t::construct(V_len
+1, V_ptr
);
846 tmp_tlv
=ASN_BER_V2TLV(tmp_tlv
, BITSTRING_descr_
, p_coding
);
847 new_tlv
->add_TLV(tmp_tlv
);
851 if(rest_octets<128) {
852 V_ptr[1]=(rest_octets+1) & '\x7F';
857 V_ptr[2]=((rest_octets+1)/256) & 0xFF;
858 V_ptr[3]=(rest_octets+1) & 0xFF;
861 BER_encode_putbits(V_ptr, i*8*999, nof_bits-i*8*999);
865 new_tlv
=ASN_BER_V2TLV(new_tlv
, p_td
, p_coding
);
869 void BITSTRING::BER_decode_getbits(const unsigned char *source
,
870 size_t s_len
, unsigned int& bitnum_start
)
875 TTCN_EncDec_ErrorContext::error
876 (TTCN_EncDec::ET_INVAL_MSG
, "Length of V-part of bitstring"
880 unsigned int nof_octets
=s_len
-1;
881 unsigned int nof_restbits
=8-source
[0];
884 TTCN_EncDec_ErrorContext::error
885 (TTCN_EncDec::ET_INVAL_MSG
,
886 "If the bitstring is empty,"
887 " the initial octet shall be 0, not %u [see X.690 clause 8.6.2.3].",
892 TTCN_EncDec_ErrorContext::error
893 (TTCN_EncDec::ET_INVAL_MSG
, "The number of unused bits in bitstring"
894 " cannot be %u (should be less than 8) [see X.690 clause 8.6.2.2].",
898 // And what about overflow? :)
899 i
= (nof_octets
- 1) * 8 + nof_restbits
;
901 if (val_ptr
->ref_count
> 1) {
902 bitstring_struct
*old_ptr
= val_ptr
;
903 old_ptr
->ref_count
--;
904 init_struct(bitnum_start
+ i
);
905 memcpy(val_ptr
->bits_ptr
, old_ptr
->bits_ptr
, (old_ptr
->n_bits
+ 7) / 8);
907 if ((bitnum_start
+ i
+ 7) / 8 > ((unsigned int)val_ptr
->n_bits
+ 7) / 8)
908 val_ptr
= (bitstring_struct
*)Realloc(val_ptr
,
909 MEMORY_SIZE(bitnum_start
+ i
));
910 val_ptr
->n_bits
= bitnum_start
+ i
;
913 for(i
=0; i
<nof_octets
-1; i
++) {
916 set_bit(bitnum_start
+8*i
+j
, c
& 0x80?TRUE
:FALSE
);
921 for(j
=0; j
<nof_restbits
; j
++) {
922 set_bit(bitnum_start
+8*i
+j
, c
& 0x80?TRUE
:FALSE
);
925 bitnum_start
+=(nof_octets
-1)*8+nof_restbits
;
928 void BITSTRING::BER_decode_TLV_(const ASN_BER_TLV_t
& p_tlv
, unsigned L_form
,
929 unsigned int& bitnum_start
)
931 if(!p_tlv
.isConstructed
) {
932 if (p_tlv
.isComplete
|| p_tlv
.V
.str
.Vlen
> 0)
933 BER_decode_getbits(p_tlv
.V
.str
.Vstr
, p_tlv
.V
.str
.Vlen
, bitnum_start
);
935 else { // is constructed
940 if(!ASN_BER_str2TLV(p_tlv
.V
.str
.Vlen
-V_pos
, p_tlv
.V
.str
.Vstr
+V_pos
,
942 TTCN_EncDec_ErrorContext::error
943 (TTCN_EncDec::ET_INCOMPL_MSG
,
944 "Incomplete TLV in a constructed BITSTRING TLV.");
947 if(!p_tlv
.isLenDefinite
&& tlv2
.tagnumber
==0
948 && tlv2
.tagclass
==ASN_TAG_UNIV
)
949 doit
=FALSE
; // End-of-contents
951 ASN_BER_TLV_t stripped_tlv
;
952 BER_decode_strip_tags(BITSTRING_ber_
, tlv2
, L_form
, stripped_tlv
);
953 BER_decode_TLV_(tlv2
, L_form
, bitnum_start
);
954 V_pos
+=tlv2
.get_len();
955 if(V_pos
>=p_tlv
.V
.str
.Vlen
) doit
=FALSE
;
958 } // else / is constructed
961 boolean
BITSTRING::BER_decode_TLV(const TTCN_Typedescriptor_t
& p_td
,
962 const ASN_BER_TLV_t
& p_tlv
,
967 ASN_BER_TLV_t stripped_tlv
;
968 BER_decode_strip_tags(*p_td
.ber
, p_tlv
, L_form
, stripped_tlv
);
969 TTCN_EncDec_ErrorContext
ec("While decoding BITSTRING type: ");
971 unsigned int bitnum_start
= 0;
972 BER_decode_TLV_(stripped_tlv
, L_form
, bitnum_start
);
976 int BITSTRING::RAW_encode(const TTCN_Typedescriptor_t
& p_td
, RAW_enc_tree
& myleaf
) const
979 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND
,
980 "Encoding an unbound value.");
982 int bl
= val_ptr
->n_bits
;
983 int align_length
= p_td
.raw
->fieldlength
? p_td
.raw
->fieldlength
- bl
: 0;
984 if ((bl
+ align_length
) < val_ptr
->n_bits
) {
985 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_LEN_ERR
,
986 "There is no sufficient bits to encode '%s': ", p_td
.name
);
987 bl
= p_td
.raw
->fieldlength
;
990 // myleaf.ext_bit=EXT_BIT_NO;
991 if (myleaf
.must_free
) Free(myleaf
.body
.leaf
.data_ptr
);
992 myleaf
.must_free
= false;
993 myleaf
.data_ptr_used
= true;
994 myleaf
.body
.leaf
.data_ptr
= val_ptr
->bits_ptr
;
996 if (p_td
.raw
->byteorder
== ORDER_MSB
) orders
= true;
997 if (p_td
.raw
->bitorderinfield
== ORDER_LSB
) orders
= !orders
;
998 myleaf
.coding_par
.byteorder
= orders
? ORDER_MSB
: ORDER_LSB
;
1000 if (p_td
.raw
->bitorderinoctet
== ORDER_MSB
) orders
= true;
1001 if (p_td
.raw
->bitorderinfield
== ORDER_LSB
) orders
= !orders
;
1002 myleaf
.coding_par
.bitorder
= orders
? ORDER_MSB
: ORDER_LSB
;
1004 if (p_td
.raw
->endianness
== ORDER_MSB
) myleaf
.align
= align_length
;
1005 else myleaf
.align
= -align_length
;
1007 return myleaf
.length
= bl
+ align_length
;
1010 int BITSTRING::RAW_decode(const TTCN_Typedescriptor_t
& p_td
, TTCN_Buffer
& buff
,
1011 int limit
, raw_order_t top_bit_ord
, boolean no_err
, int /*sel_field*/,
1012 boolean
/*first_call*/)
1014 int prepaddlength
= buff
.increase_pos_padd(p_td
.raw
->prepadding
);
1015 limit
-= prepaddlength
;
1016 int decode_length
= p_td
.raw
->fieldlength
== 0
1017 ? limit
: p_td
.raw
->fieldlength
;
1018 if ( p_td
.raw
->fieldlength
> limit
1019 || p_td
.raw
->fieldlength
> (int) buff
.unread_len_bit()) {
1020 if (no_err
) return -TTCN_EncDec::ET_LEN_ERR
;
1021 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_LEN_ERR
,
1022 "There is not enough bits in the buffer to decode type %s.", p_td
.name
);
1023 decode_length
= limit
> (int) buff
.unread_len_bit()
1024 ? buff
.unread_len_bit() : limit
;
1027 init_struct(decode_length
);
1029 bool orders
= false;
1030 if (p_td
.raw
->bitorderinoctet
== ORDER_MSB
) orders
= true;
1031 if (p_td
.raw
->bitorderinfield
== ORDER_LSB
) orders
= !orders
;
1032 cp
.bitorder
= orders
? ORDER_MSB
: ORDER_LSB
;
1034 if (p_td
.raw
->byteorder
== ORDER_MSB
) orders
= true;
1035 if (p_td
.raw
->bitorderinfield
== ORDER_LSB
) orders
= !orders
;
1036 cp
.byteorder
= orders
? ORDER_MSB
: ORDER_LSB
;
1037 cp
.fieldorder
= p_td
.raw
->fieldorder
;
1038 cp
.hexorder
= ORDER_LSB
;
1039 buff
.get_b((size_t) decode_length
, val_ptr
->bits_ptr
, cp
, top_bit_ord
);
1040 if (p_td
.raw
->length_restrition
!= -1) {
1041 val_ptr
->n_bits
= p_td
.raw
->length_restrition
;
1042 if (p_td
.raw
->endianness
== ORDER_LSB
) {
1043 if ((decode_length
- val_ptr
->n_bits
) % 8) {
1044 int bound
= (decode_length
- val_ptr
->n_bits
) % 8;
1045 int maxindex
= (decode_length
- 1) / 8;
1046 for (int a
= 0, b
= (decode_length
- val_ptr
->n_bits
- 1) / 8;
1047 a
< (val_ptr
->n_bits
+ 7) / 8; a
++, b
++) {
1048 val_ptr
->bits_ptr
[a
] = val_ptr
->bits_ptr
[b
] >> bound
;
1050 val_ptr
->bits_ptr
[a
] = val_ptr
->bits_ptr
[b
+ 1] << (8 - bound
);
1054 else memmove(val_ptr
->bits_ptr
,
1055 val_ptr
->bits_ptr
+ (decode_length
- val_ptr
->n_bits
) / 8,
1056 val_ptr
->n_bits
/ 8 * sizeof(unsigned char));
1059 decode_length
+= buff
.increase_pos_padd(p_td
.raw
->padding
);
1060 clear_unused_bits();
1061 return decode_length
+ prepaddlength
;
1064 int BITSTRING::XER_encode(const XERdescriptor_t
& p_td
,
1065 TTCN_Buffer
& p_buf
, unsigned int flavor
, int indent
, embed_values_enc_struct_t
*) const
1068 TTCN_EncDec_ErrorContext::error
1069 (TTCN_EncDec::ET_UNBOUND
, "Encoding an unbound bitstring value.");
1072 int encoded_length
=(int)p_buf
.get_len();
1073 int empty_element
= val_ptr
==NULL
|| val_ptr
->n_bits
== 0;
1074 flavor
|= SIMPLE_TYPE
;
1075 flavor
&= ~XER_RECOF
; // bitstring doesn't care
1077 begin_xml(p_td
, p_buf
, flavor
, indent
, empty_element
);
1079 if (!empty_element
) {
1080 for (int bit_count
= 0; bit_count
< val_ptr
->n_bits
; bit_count
++)
1081 p_buf
.put_c(get_bit(bit_count
) ? '1' : '0');
1084 end_xml(p_td
, p_buf
, flavor
, indent
, empty_element
);
1085 return (int)p_buf
.get_len() - encoded_length
;
1088 int BITSTRING::XER_decode(const XERdescriptor_t
& p_td
, XmlReaderWrap
& reader
,
1089 unsigned int flavor
, unsigned int /*flavor2*/, embed_values_dec_struct_t
*)
1091 int exer
= is_exer(flavor
);
1092 int success
= reader
.Ok(), depth
= -1, type
;
1093 boolean own_tag
= !is_exerlist(flavor
) && !(exer
&& (p_td
.xer_bits
& UNTAGGED
));
1095 if (exer
&& (p_td
.xer_bits
& XER_ATTRIBUTE
)) {
1096 const char * name
= verify_name(reader
, p_td
, exer
);
1100 for (; success
== 1; success
= reader
.Read()) {
1101 type
= reader
.NodeType();
1102 if (XML_READER_TYPE_ELEMENT
== type
) {
1103 verify_name(reader
, p_td
, exer
);
1104 depth
= reader
.Depth();
1105 if (reader
.IsEmptyElement()) {
1111 else if (XML_READER_TYPE_TEXT
== type
&& depth
!= -1) break;
1112 else if (XML_READER_TYPE_END_ELEMENT
== type
) {
1113 // End tag without intervening #text == empty content
1114 verify_end(reader
, p_td
, depth
, exer
);
1122 type
= reader
.NodeType();
1123 if (success
== 1 && (XML_READER_TYPE_TEXT
== type
|| XML_READER_TYPE_ATTRIBUTE
== type
)) {
1124 const char* value
= (const char *)reader
.Value();
1125 size_t num_bits
= strlen(value
);
1126 init_struct(num_bits
);
1127 for (size_t i
= 0; i
< num_bits
; ++i
) {
1128 if (value
[i
] < '0' || value
[i
] > '1') {
1129 if (exer
&& (flavor
& EXIT_ON_ERROR
)) {
1133 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG
,
1134 "The bitstring value may only contain ones and zeros.");
1137 set_bit(i
, value
[i
] - '0');
1141 if (exer
&& (p_td
.xer_bits
& XER_ATTRIBUTE
)) {
1142 // Let the caller do reader.AdvanceAttribute();
1145 for (success
= reader
.Read(); success
== 1; success
= reader
.Read()) {
1146 type
= reader
.NodeType();
1147 if (XML_READER_TYPE_END_ELEMENT
== type
) {
1148 verify_end(reader
, p_td
, depth
, exer
);
1149 reader
.Read(); // one last time
1157 int BITSTRING::JSON_encode(const TTCN_Typedescriptor_t
&, JSON_Tokenizer
& p_tok
) const
1160 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND
,
1161 "Encoding an unbound bitstring value.");
1165 char* tmp_str
= (char*)Malloc(val_ptr
->n_bits
+ 3);
1167 tmp_str
[val_ptr
->n_bits
+ 1] = '\"';
1168 for (int i
= 0; i
< val_ptr
->n_bits
; ++i
) {
1169 tmp_str
[i
+ 1] = get_bit(i
) ? '1' : '0';
1171 tmp_str
[val_ptr
->n_bits
+ 2] = 0;
1172 int enc_len
= p_tok
.put_next_token(JSON_TOKEN_STRING
, tmp_str
);
1177 int BITSTRING::JSON_decode(const TTCN_Typedescriptor_t
& p_td
, JSON_Tokenizer
& p_tok
, boolean p_silent
)
1179 json_token_t token
= JSON_TOKEN_NONE
;
1181 size_t value_len
= 0;
1182 boolean error
= false;
1184 boolean use_default
= p_td
.json
->default_value
&& 0 == p_tok
.get_buffer_length();
1186 // No JSON data in the buffer -> use default value
1187 value
= (char*)p_td
.json
->default_value
;
1188 value_len
= strlen(value
);
1190 dec_len
= p_tok
.get_next_token(&token
, &value
, &value_len
);
1192 if (JSON_TOKEN_ERROR
== token
) {
1193 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG
, JSON_DEC_BAD_TOKEN_ERROR
, "");
1194 return JSON_ERROR_FATAL
;
1196 else if (JSON_TOKEN_STRING
== token
|| use_default
) {
1197 if (use_default
|| (value_len
> 2 && value
[0] == '\"' && value
[value_len
- 1] == '\"')) {
1199 // The default value doesn't have quotes around it
1203 init_struct(value_len
);
1204 for (size_t i
= 0; i
< value_len
; ++i
) {
1205 if ('0' <= value
[i
] && '1' >= value
[i
]) {
1206 set_bit(i
, value
[i
] - '0');
1216 return JSON_ERROR_INVALID_TOKEN
;
1220 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG
, JSON_DEC_FORMAT_ERROR
, "string", "bitstring");
1224 return JSON_ERROR_FATAL
;
1230 // bitstring element class
1232 BITSTRING_ELEMENT::BITSTRING_ELEMENT(boolean par_bound_flag
,
1233 BITSTRING
& par_str_val
, int par_bit_pos
)
1234 : bound_flag(par_bound_flag
), str_val(par_str_val
), bit_pos(par_bit_pos
)
1238 BITSTRING_ELEMENT
& BITSTRING_ELEMENT::operator=(const BITSTRING
& other_value
)
1240 other_value
.must_bound("Assignment of an unbound bitstring value.");
1241 if(other_value
.val_ptr
->n_bits
!= 1)
1242 TTCN_error("Assignment of a bitstring "
1243 "value with length other than 1 to a bitstring element.");
1245 str_val
.copy_value();
1246 str_val
.set_bit(bit_pos
, other_value
.get_bit(0));
1250 BITSTRING_ELEMENT
& BITSTRING_ELEMENT::operator=
1251 (const BITSTRING_ELEMENT
& other_value
)
1253 other_value
.must_bound("Assignment of an unbound bitstring element.");
1255 str_val
.copy_value();
1256 str_val
.set_bit(bit_pos
, other_value
.str_val
.get_bit(other_value
.bit_pos
));
1260 boolean
BITSTRING_ELEMENT::operator==(const BITSTRING
& other_value
) const
1262 must_bound("Unbound left operand of bitstring element comparison.");
1263 other_value
.must_bound("Unbound right operand of bitstring comparison.");
1264 if(other_value
.val_ptr
->n_bits
!= 1) return FALSE
;
1265 return str_val
.get_bit(bit_pos
) == other_value
.get_bit(0);
1268 boolean
BITSTRING_ELEMENT::operator==
1269 (const BITSTRING_ELEMENT
& other_value
) const
1271 must_bound("Unbound left operand of bitstring element comparison.");
1272 other_value
.must_bound("Unbound right operand of bitstring element "
1274 return str_val
.get_bit(bit_pos
) ==
1275 other_value
.str_val
.get_bit(other_value
.bit_pos
);
1278 BITSTRING
BITSTRING_ELEMENT::operator+(const BITSTRING
& other_value
) const
1280 must_bound("Unbound left operand of bitstring element concatenation.");
1281 other_value
.must_bound("Unbound right operand of bitstring concatenation.");
1282 int n_bits
= other_value
.val_ptr
->n_bits
;
1283 BITSTRING
ret_val(n_bits
+ 1);
1284 ret_val
.val_ptr
->bits_ptr
[0] = str_val
.get_bit(bit_pos
) ? 1 : 0;
1285 int n_bytes
= (n_bits
+ 7) / 8;
1286 for (int byte_count
= 0; byte_count
< n_bytes
; byte_count
++) {
1287 ret_val
.val_ptr
->bits_ptr
[byte_count
] |=
1288 other_value
.val_ptr
->bits_ptr
[byte_count
] << 1;
1289 if (n_bits
> byte_count
* 8 + 7)
1290 ret_val
.val_ptr
->bits_ptr
[byte_count
+ 1] =
1291 other_value
.val_ptr
->bits_ptr
[byte_count
] >> 7;
1293 ret_val
.clear_unused_bits();
1297 BITSTRING
BITSTRING_ELEMENT::operator+(const BITSTRING_ELEMENT
& other_value
)
1300 must_bound("Unbound left operand of bitstring element concatenation.");
1301 other_value
.must_bound("Unbound right operand of bitstring element "
1303 unsigned char result
= str_val
.get_bit(bit_pos
) ? 1 : 0;
1304 if (other_value
.str_val
.get_bit(other_value
.bit_pos
)) result
|= 2;
1305 return BITSTRING(2, &result
);
1308 BITSTRING
BITSTRING_ELEMENT::operator~() const
1310 must_bound("Unbound bitstring element operand of operator not4b.");
1311 unsigned char result
= str_val
.get_bit(bit_pos
) ? 0 : 1;
1312 return BITSTRING(1, &result
);
1315 BITSTRING
BITSTRING_ELEMENT::operator&(const BITSTRING
& other_value
) const
1317 must_bound("Left operand of operator and4b is an unbound bitstring element.");
1318 other_value
.must_bound("Right operand of operator and4b is an unbound "
1319 "bitstring value.");
1320 if (other_value
.val_ptr
->n_bits
!= 1)
1321 TTCN_error("The bitstring operands "
1322 "of operator and4b must have the same length.");
1323 unsigned char result
= str_val
.get_bit(bit_pos
) && other_value
.get_bit(0) ?
1325 return BITSTRING(1, &result
);
1328 BITSTRING
BITSTRING_ELEMENT::operator&
1329 (const BITSTRING_ELEMENT
& other_value
) const
1331 must_bound("Left operand of operator and4b is an unbound bitstring element.");
1332 other_value
.must_bound("Right operand of operator and4b is an unbound "
1333 "bitstring element.");
1334 unsigned char result
= str_val
.get_bit(bit_pos
) &&
1335 other_value
.str_val
.get_bit(other_value
.bit_pos
) ? 1 : 0;
1336 return BITSTRING(1, &result
);
1339 BITSTRING
BITSTRING_ELEMENT::operator|(const BITSTRING
& other_value
) const
1341 must_bound("Left operand of operator or4b is an unbound bitstring element.");
1342 other_value
.must_bound("Right operand of operator or4b is an unbound "
1343 "bitstring value.");
1344 if (other_value
.val_ptr
->n_bits
!= 1)
1345 TTCN_error("The bitstring operands "
1346 "of operator or4b must have the same length.");
1347 unsigned char result
= str_val
.get_bit(bit_pos
) || other_value
.get_bit(0) ?
1349 return BITSTRING(1, &result
);
1352 BITSTRING
BITSTRING_ELEMENT::operator|
1353 (const BITSTRING_ELEMENT
& other_value
) const
1355 must_bound("Left operand of operator or4b is an unbound bitstring element.");
1356 other_value
.must_bound("Right operand of operator or4b is an unbound "
1357 "bitstring element.");
1358 unsigned char result
= str_val
.get_bit(bit_pos
) ||
1359 other_value
.str_val
.get_bit(other_value
.bit_pos
) ? 1 : 0;
1360 return BITSTRING(1, &result
);
1363 BITSTRING
BITSTRING_ELEMENT::operator^(const BITSTRING
& other_value
) const
1365 must_bound("Left operand of operator xor4b is an unbound bitstring element.");
1366 other_value
.must_bound("Right operand of operator xor4b is an unbound "
1367 "bitstring value.");
1368 if (other_value
.val_ptr
->n_bits
!= 1)
1369 TTCN_error("The bitstring operands "
1370 "of operator xor4b must have the same length.");
1371 unsigned char result
= str_val
.get_bit(bit_pos
) != other_value
.get_bit(0) ?
1373 return BITSTRING(1, &result
);
1376 BITSTRING
BITSTRING_ELEMENT::operator^
1377 (const BITSTRING_ELEMENT
& other_value
) const
1379 must_bound("Left operand of operator xor4b is an unbound bitstring element.");
1380 other_value
.must_bound("Right operand of operator xor4b is an unbound "
1381 "bitstring element.");
1382 unsigned char result
= str_val
.get_bit(bit_pos
) !=
1383 other_value
.str_val
.get_bit(other_value
.bit_pos
) ? 1 : 0;
1384 return BITSTRING(1, &result
);
1387 boolean
BITSTRING_ELEMENT::get_bit() const
1389 return str_val
.get_bit(bit_pos
);
1392 void BITSTRING_ELEMENT::log() const
1394 if (bound_flag
) TTCN_Logger::log_event("'%c'B", str_val
.get_bit(bit_pos
) ?
1396 else TTCN_Logger::log_event_unbound();
1399 // bitstring template class
1401 void BITSTRING_template::clean_up()
1403 switch (template_selection
) {
1405 case COMPLEMENTED_LIST
:
1406 delete [] value_list
.list_value
;
1408 case STRING_PATTERN
:
1409 if (pattern_value
->ref_count
> 1) pattern_value
->ref_count
--;
1410 else if (pattern_value
->ref_count
== 1) Free(pattern_value
);
1411 else TTCN_error("Internal error: Invalid reference counter in a bitstring "
1415 if (dec_match
->ref_count
> 1) {
1416 dec_match
->ref_count
--;
1418 else if (dec_match
->ref_count
== 1) {
1419 delete dec_match
->instance
;
1423 TTCN_error("Internal error: Invalid reference counter in a "
1424 "decoded content match.");
1430 template_selection
= UNINITIALIZED_TEMPLATE
;
1433 void BITSTRING_template::copy_template(const BITSTRING_template
& other_value
)
1435 switch (other_value
.template_selection
) {
1436 case SPECIFIC_VALUE
:
1437 single_value
= other_value
.single_value
;
1444 case COMPLEMENTED_LIST
:
1445 value_list
.n_values
= other_value
.value_list
.n_values
;
1446 value_list
.list_value
= new BITSTRING_template
[value_list
.n_values
];
1447 for (unsigned int i
= 0; i
< value_list
.n_values
; i
++)
1448 value_list
.list_value
[i
].copy_template(
1449 other_value
.value_list
.list_value
[i
]);
1451 case STRING_PATTERN
:
1452 pattern_value
= other_value
.pattern_value
;
1453 pattern_value
->ref_count
++;
1456 dec_match
= other_value
.dec_match
;
1457 dec_match
->ref_count
++;
1460 TTCN_error("Copying an uninitialized/unsupported bitstring template.");
1462 set_selection(other_value
);
1466 This is the same algorithm that match_array uses
1467 to match 'record of' types.
1468 The only differences are: how two elements are matched and
1469 how an asterisk or ? is identified in the template
1471 boolean
BITSTRING_template::match_pattern(
1472 const bitstring_pattern_struct
*string_pattern
,
1473 const BITSTRING::bitstring_struct
*string_value
)
1475 if(string_pattern
->n_elements
== 0) return string_value
->n_bits
== 0;
1477 int value_index
= 0;
1478 unsigned int template_index
= 0;
1479 int last_asterisk
= -1;
1480 int last_value_to_asterisk
= -1;
1484 switch(string_pattern
->elements_ptr
[template_index
]) {
1486 if (!(string_value
->bits_ptr
[value_index
/ 8] &
1487 (1 << (value_index
% 8))))
1492 if(last_asterisk
== -1) return FALSE
;
1493 template_index
= last_asterisk
+1;
1494 value_index
= ++last_value_to_asterisk
;
1498 if (string_value
->bits_ptr
[value_index
/ 8] & (1 << (value_index
% 8)))
1503 if(last_asterisk
== -1) return FALSE
;
1504 template_index
= last_asterisk
+1;
1505 value_index
= ++last_value_to_asterisk
;
1509 //we found a ? element, it matches anything
1514 //we found an asterisk
1515 last_asterisk
= template_index
++;
1516 last_value_to_asterisk
= value_index
;
1519 TTCN_error("Internal error: invalid element in bitstring pattern.");
1522 if(value_index
== string_value
->n_bits
1523 && template_index
== string_pattern
->n_elements
)
1526 }else if(template_index
== string_pattern
->n_elements
)
1528 if(string_pattern
->elements_ptr
[template_index
-1] == 3)
1531 } else if (last_asterisk
== -1){
1534 template_index
= last_asterisk
+1;
1535 value_index
= ++last_value_to_asterisk
;
1537 } else if(value_index
== string_value
->n_bits
)
1539 while(template_index
< string_pattern
->n_elements
&&
1540 string_pattern
->elements_ptr
[template_index
] == 3)
1543 return template_index
== string_pattern
->n_elements
;
1548 BITSTRING_template::BITSTRING_template()
1552 BITSTRING_template::BITSTRING_template(template_sel other_value
)
1553 : Restricted_Length_Template(other_value
)
1555 check_single_selection(other_value
);
1558 BITSTRING_template::BITSTRING_template(const BITSTRING
& other_value
)
1559 : Restricted_Length_Template(SPECIFIC_VALUE
), single_value(other_value
)
1563 BITSTRING_template::BITSTRING_template(const BITSTRING_ELEMENT
& other_value
)
1564 : Restricted_Length_Template(SPECIFIC_VALUE
), single_value(other_value
)
1568 BITSTRING_template::~BITSTRING_template()
1573 BITSTRING_template::BITSTRING_template(const OPTIONAL
<BITSTRING
>& other_value
)
1575 switch (other_value
.get_selection()) {
1576 case OPTIONAL_PRESENT
:
1577 set_selection(SPECIFIC_VALUE
);
1578 single_value
= (const BITSTRING
&)other_value
;
1581 set_selection(OMIT_VALUE
);
1584 TTCN_error("Creating a bitstring template from an unbound optional field.");
1588 BITSTRING_template::BITSTRING_template(unsigned int n_elements
,
1589 const unsigned char *pattern_elements
)
1590 : Restricted_Length_Template(STRING_PATTERN
)
1592 pattern_value
= (bitstring_pattern_struct
*)
1593 Malloc(sizeof(bitstring_pattern_struct
) + n_elements
- 1);
1594 pattern_value
->ref_count
= 1;
1595 pattern_value
->n_elements
= n_elements
;
1596 memcpy(pattern_value
->elements_ptr
, pattern_elements
, n_elements
);
1599 BITSTRING_template::BITSTRING_template(const BITSTRING_template
& other_value
)
1600 : Restricted_Length_Template()
1602 copy_template(other_value
);
1605 BITSTRING_template
& BITSTRING_template::operator=(template_sel other_value
)
1607 check_single_selection(other_value
);
1609 set_selection(other_value
);
1613 BITSTRING_template
& BITSTRING_template::operator=(const BITSTRING
& other_value
)
1615 other_value
.must_bound("Assignment of an unbound bitstring value to a "
1618 set_selection(SPECIFIC_VALUE
);
1619 single_value
= other_value
;
1623 BITSTRING_template
& BITSTRING_template::operator=
1624 (const BITSTRING_ELEMENT
& other_value
)
1626 other_value
.must_bound("Assignment of an unbound bitstring element to a "
1629 set_selection(SPECIFIC_VALUE
);
1630 single_value
= other_value
;
1634 BITSTRING_template
& BITSTRING_template::operator=
1635 (const OPTIONAL
<BITSTRING
>& other_value
)
1638 switch (other_value
.get_selection()) {
1639 case OPTIONAL_PRESENT
:
1640 set_selection(SPECIFIC_VALUE
);
1641 single_value
= (const BITSTRING
&)other_value
;
1644 set_selection(OMIT_VALUE
);
1647 TTCN_error("Assignment of an unbound optional field to a bitstring "
1653 BITSTRING_template
& BITSTRING_template::operator=
1654 (const BITSTRING_template
& other_value
)
1656 if (&other_value
!= this) {
1658 copy_template(other_value
);
1663 BITSTRING_ELEMENT
BITSTRING_template::operator[](int index_value
)
1665 if (template_selection
!= SPECIFIC_VALUE
|| is_ifpresent
)
1666 TTCN_error("Accessing a bitstring element of a non-specific bitstring "
1668 return single_value
[index_value
];
1671 BITSTRING_ELEMENT
BITSTRING_template::operator[](const INTEGER
& index_value
)
1673 index_value
.must_bound("Indexing a bitstring template with an unbound "
1675 return (*this)[(int)index_value
];
1678 const BITSTRING_ELEMENT
BITSTRING_template::operator[](int index_value
) const
1680 if (template_selection
!= SPECIFIC_VALUE
|| is_ifpresent
)
1681 TTCN_error("Accessing a bitstring element of a non-specific bitstring "
1683 return single_value
[index_value
];
1686 const BITSTRING_ELEMENT
BITSTRING_template::operator[](const INTEGER
& index_value
) const
1688 index_value
.must_bound("Indexing a bitstring template with an unbound "
1690 return (*this)[(int)index_value
];
1693 boolean
BITSTRING_template::match(const BITSTRING
& other_value
,
1694 boolean
/* legacy */) const
1696 if (!other_value
.is_bound()) return FALSE
;
1697 if (!match_length(other_value
.val_ptr
->n_bits
)) return FALSE
;
1698 switch (template_selection
) {
1699 case SPECIFIC_VALUE
:
1700 return single_value
== other_value
;
1707 case COMPLEMENTED_LIST
:
1708 for (unsigned int i
= 0; i
< value_list
.n_values
; i
++)
1709 if (value_list
.list_value
[i
].match(other_value
))
1710 return template_selection
== VALUE_LIST
;
1711 return template_selection
== COMPLEMENTED_LIST
;
1712 case STRING_PATTERN
:
1713 return match_pattern(pattern_value
, other_value
.val_ptr
);
1714 case DECODE_MATCH
: {
1715 TTCN_EncDec::set_error_behavior(TTCN_EncDec::ET_ALL
, TTCN_EncDec::EB_WARNING
);
1716 TTCN_EncDec::clear_error();
1717 OCTETSTRING
os(bit2oct(other_value
));
1718 TTCN_Buffer
buff(os
);
1719 boolean ret_val
= dec_match
->instance
->match(buff
);
1720 TTCN_EncDec::set_error_behavior(TTCN_EncDec::ET_ALL
,TTCN_EncDec::EB_DEFAULT
);
1721 TTCN_EncDec::clear_error();
1724 TTCN_error("Matching an uninitialized/unsupported bitstring template.");
1729 const BITSTRING
& BITSTRING_template::valueof() const
1731 if (template_selection
!= SPECIFIC_VALUE
|| is_ifpresent
)
1732 TTCN_error("Performing a valueof or send operation on a non-specific "
1733 "bitstring template.");
1734 return single_value
;
1737 int BITSTRING_template::lengthof() const
1740 boolean has_any_or_none
;
1742 TTCN_error("Performing lengthof() operation on a bitstring template "
1743 "which has an ifpresent attribute.");
1744 switch (template_selection
)
1746 case SPECIFIC_VALUE
:
1747 min_length
= single_value
.lengthof();
1748 has_any_or_none
= FALSE
;
1751 TTCN_error("Performing lengthof() operation on a bitstring template "
1752 "containing omit value.");
1756 has_any_or_none
= TRUE
; // max. length is infinity
1760 // error if any element does not have length or the lengths differ
1761 if (value_list
.n_values
<1)
1762 TTCN_error("Internal error: "
1763 "Performing lengthof() operation on a bitstring template "
1764 "containing an empty list.");
1765 int item_length
= value_list
.list_value
[0].lengthof();
1766 for (unsigned int i
= 1; i
< value_list
.n_values
; i
++) {
1767 if (value_list
.list_value
[i
].lengthof()!=item_length
)
1768 TTCN_error("Performing lengthof() operation on a bitstring template "
1769 "containing a value list with different lengths.");
1771 min_length
= item_length
;
1772 has_any_or_none
= FALSE
;
1775 case COMPLEMENTED_LIST
:
1776 TTCN_error("Performing lengthof() operation on a bitstring template "
1777 "containing complemented list.");
1778 case STRING_PATTERN
:
1780 has_any_or_none
= FALSE
; // TRUE if * chars in the pattern
1781 for (unsigned int i
= 0; i
< pattern_value
->n_elements
; i
++)
1783 if (pattern_value
->elements_ptr
[i
] < 3) min_length
++; // case of 1, 0, ?
1784 else has_any_or_none
= TRUE
; // case of * character
1788 TTCN_error("Performing lengthof() operation on an "
1789 "uninitialized/unsupported bitstring template.");
1791 return check_section_is_single(min_length
, has_any_or_none
,
1792 "length", "a", "bitstring template");
1795 void BITSTRING_template::set_type(template_sel template_type
,
1796 unsigned int list_length
/* = 0 */)
1798 if (template_type
!= VALUE_LIST
&& template_type
!= COMPLEMENTED_LIST
&&
1799 template_type
!= DECODE_MATCH
)
1800 TTCN_error("Setting an invalid list type for a bitstring template.");
1802 set_selection(template_type
);
1803 if (template_type
!= DECODE_MATCH
) {
1804 value_list
.n_values
= list_length
;
1805 value_list
.list_value
= new BITSTRING_template
[list_length
];
1809 BITSTRING_template
& BITSTRING_template::list_item(unsigned int list_index
)
1811 if (template_selection
!= VALUE_LIST
&&
1812 template_selection
!= COMPLEMENTED_LIST
)
1813 TTCN_error("Accessing a list element of a non-list bitstring template.");
1814 if (list_index
>= value_list
.n_values
)
1815 TTCN_error("Index overflow in a bitstring value list template.");
1816 return value_list
.list_value
[list_index
];
1819 void BITSTRING_template::set_decmatch(Dec_Match_Interface
* new_instance
)
1821 if (template_selection
!= DECODE_MATCH
) {
1822 TTCN_error("Setting the decoded content matching mechanism of a non-decmatch "
1823 "bitstring template.");
1825 dec_match
= new decmatch_struct
;
1826 dec_match
->ref_count
= 1;
1827 dec_match
->instance
= new_instance
;
1830 static const char patterns
[] = { '0', '1', '?', '*' };
1832 void BITSTRING_template::log() const
1834 switch (template_selection
) {
1835 case SPECIFIC_VALUE
:
1838 case COMPLEMENTED_LIST
:
1839 TTCN_Logger::log_event_str("complement ");
1842 TTCN_Logger::log_char('(');
1843 for (unsigned int i
= 0; i
< value_list
.n_values
; i
++) {
1844 if (i
> 0) TTCN_Logger::log_event_str(", ");
1845 value_list
.list_value
[i
].log();
1847 TTCN_Logger::log_char(')');
1849 case STRING_PATTERN
:
1850 TTCN_Logger::log_char('\'');
1851 for (unsigned int i
= 0; i
< pattern_value
->n_elements
; i
++) {
1852 unsigned char pattern
= pattern_value
->elements_ptr
[i
];
1853 if (pattern
< 4) TTCN_Logger::log_char(patterns
[pattern
]);
1854 else TTCN_Logger::log_event_str("<unknown>");
1856 TTCN_Logger::log_event_str("'B");
1859 TTCN_Logger::log_event_str("decmatch ");
1860 dec_match
->instance
->log();
1870 void BITSTRING_template::log_match(const BITSTRING
& match_value
,
1871 boolean
/* legacy */) const
1873 if (TTCN_Logger::VERBOSITY_COMPACT
== TTCN_Logger::get_matching_verbosity()
1874 && TTCN_Logger::get_logmatch_buffer_len() != 0) {
1875 TTCN_Logger::print_logmatch_buffer();
1876 TTCN_Logger::log_event_str(" := ");
1879 TTCN_Logger::log_event_str(" with ");
1881 if (match(match_value
)) TTCN_Logger::log_event_str(" matched");
1882 else TTCN_Logger::log_event_str(" unmatched");
1885 void BITSTRING_template::set_param(Module_Param
& param
) {
1886 param
.basic_check(Module_Param::BC_TEMPLATE
|Module_Param::BC_LIST
, "bitstring template");
1887 Module_Param_Ptr mp
= ¶m
;
1888 if (param
.get_type() == Module_Param::MP_Reference
) {
1889 mp
= param
.get_referenced_param();
1891 switch (mp
->get_type()) {
1892 case Module_Param::MP_Omit
:
1895 case Module_Param::MP_Any
:
1898 case Module_Param::MP_AnyOrNone
:
1899 *this = ANY_OR_OMIT
;
1901 case Module_Param::MP_List_Template
:
1902 case Module_Param::MP_ComplementList_Template
: {
1903 BITSTRING_template temp
;
1904 temp
.set_type(mp
->get_type() == Module_Param::MP_List_Template
?
1905 VALUE_LIST
: COMPLEMENTED_LIST
, mp
->get_size());
1906 for (size_t i
=0; i
<mp
->get_size(); i
++) {
1907 temp
.list_item(i
).set_param(*mp
->get_elem(i
));
1911 case Module_Param::MP_Bitstring
:
1912 *this = BITSTRING(mp
->get_string_size(), (unsigned char*)mp
->get_string_data());
1914 case Module_Param::MP_Bitstring_Template
:
1915 *this = BITSTRING_template(mp
->get_string_size(), (unsigned char*)mp
->get_string_data());
1917 case Module_Param::MP_Expression
:
1918 if (mp
->get_expr_type() == Module_Param::EXPR_CONCATENATE
) {
1919 BITSTRING operand1
, operand2
;
1920 operand1
.set_param(*mp
->get_operand1());
1921 operand2
.set_param(*mp
->get_operand2());
1922 *this = operand1
+ operand2
;
1925 param
.expr_type_error("a bitstring");
1929 param
.type_error("bitstring template");
1931 is_ifpresent
= param
.get_ifpresent() || mp
->get_ifpresent();
1932 if (param
.get_length_restriction() != NULL
) {
1933 set_length_range(param
);
1936 set_length_range(*mp
);
1940 Module_Param
* BITSTRING_template::get_param(Module_Param_Name
& param_name
) const
1942 Module_Param
* mp
= NULL
;
1943 switch (template_selection
) {
1944 case UNINITIALIZED_TEMPLATE
:
1945 mp
= new Module_Param_Unbound();
1948 mp
= new Module_Param_Omit();
1951 mp
= new Module_Param_Any();
1954 mp
= new Module_Param_AnyOrNone();
1956 case SPECIFIC_VALUE
:
1957 mp
= single_value
.get_param(param_name
);
1960 case COMPLEMENTED_LIST
: {
1961 if (template_selection
== VALUE_LIST
) {
1962 mp
= new Module_Param_List_Template();
1965 mp
= new Module_Param_ComplementList_Template();
1967 for (size_t i
= 0; i
< value_list
.n_values
; ++i
) {
1968 mp
->add_elem(value_list
.list_value
[i
].get_param(param_name
));
1971 case STRING_PATTERN
: {
1972 unsigned char* val_cpy
= (unsigned char*)Malloc(pattern_value
->n_elements
);
1973 memcpy(val_cpy
, pattern_value
->elements_ptr
, pattern_value
->n_elements
);
1974 mp
= new Module_Param_Bitstring_Template(pattern_value
->n_elements
, val_cpy
);
1977 mp
->error("Referencing a decoded content matching template is not supported.");
1983 mp
->set_ifpresent();
1985 mp
->set_length_restriction(get_length_range());
1989 void BITSTRING_template::encode_text(Text_Buf
& text_buf
) const
1991 encode_text_restricted(text_buf
);
1992 switch (template_selection
) {
1997 case SPECIFIC_VALUE
:
1998 single_value
.encode_text(text_buf
);
2001 case COMPLEMENTED_LIST
:
2002 text_buf
.push_int(value_list
.n_values
);
2003 for (unsigned int i
= 0; i
< value_list
.n_values
; i
++)
2004 value_list
.list_value
[i
].encode_text(text_buf
);
2006 case STRING_PATTERN
:
2007 text_buf
.push_int(pattern_value
->n_elements
);
2008 text_buf
.push_raw(pattern_value
->n_elements
, pattern_value
->elements_ptr
);
2011 TTCN_error("Text encoder: Encoding an uninitialized/unsupported "
2012 "bitstring template.");
2016 void BITSTRING_template::decode_text(Text_Buf
& text_buf
)
2019 decode_text_restricted(text_buf
);
2020 switch (template_selection
) {
2025 case SPECIFIC_VALUE
:
2026 single_value
.decode_text(text_buf
);
2029 case COMPLEMENTED_LIST
:
2030 value_list
.n_values
= text_buf
.pull_int().get_val();
2031 value_list
.list_value
= new BITSTRING_template
[value_list
.n_values
];
2032 for (unsigned int i
= 0; i
< value_list
.n_values
; i
++)
2033 value_list
.list_value
[i
].decode_text(text_buf
);
2035 case STRING_PATTERN
: {
2036 unsigned int n_elements
= text_buf
.pull_int().get_val();
2037 pattern_value
= (bitstring_pattern_struct
*)
2038 Malloc(sizeof(bitstring_pattern_struct
) + n_elements
- 1);
2039 pattern_value
->ref_count
= 1;
2040 pattern_value
->n_elements
= n_elements
;
2041 text_buf
.pull_raw(n_elements
, pattern_value
->elements_ptr
);
2044 TTCN_error("Text decoder: An unknown/unsupported selection was "
2045 "received for a bitstring template.");
2049 boolean
BITSTRING_template::is_present(boolean legacy
/* = FALSE */) const
2051 if (template_selection
==UNINITIALIZED_TEMPLATE
) return FALSE
;
2052 return !match_omit(legacy
);
2055 boolean
BITSTRING_template::match_omit(boolean legacy
/* = FALSE */) const
2057 if (is_ifpresent
) return TRUE
;
2058 switch (template_selection
) {
2063 case COMPLEMENTED_LIST
:
2065 // legacy behavior: 'omit' can appear in the value/complement list
2066 for (unsigned int i
=0; i
<value_list
.n_values
; i
++)
2067 if (value_list
.list_value
[i
].match_omit())
2068 return template_selection
==VALUE_LIST
;
2069 return template_selection
==COMPLEMENTED_LIST
;
2071 // else fall through
2078 #ifndef TITAN_RUNTIME_2
2079 void BITSTRING_template::check_restriction(template_res t_res
, const char* t_name
,
2080 boolean legacy
/* = FALSE */) const
2082 if (template_selection
==UNINITIALIZED_TEMPLATE
) return;
2083 switch ((t_name
&&(t_res
==TR_VALUE
))?TR_OMIT
:t_res
) {
2085 if (!is_ifpresent
&& template_selection
==SPECIFIC_VALUE
) return;
2088 if (!is_ifpresent
&& (template_selection
==OMIT_VALUE
||
2089 template_selection
==SPECIFIC_VALUE
)) return;
2092 if (!match_omit(legacy
)) return;
2097 TTCN_error("Restriction `%s' on template of type %s violated.",
2098 get_res_name(t_res
), t_name
? t_name
: "bitstring");
2101 int BITSTRING::RAW_encode_negtest_raw(RAW_enc_tree
& p_myleaf
) const
2103 if (p_myleaf
.must_free
)
2104 Free(p_myleaf
.body
.leaf
.data_ptr
);
2105 p_myleaf
.must_free
= false;
2106 p_myleaf
.data_ptr_used
= true;
2107 p_myleaf
.body
.leaf
.data_ptr
= val_ptr
->bits_ptr
;
2108 return p_myleaf
.length
= val_ptr
->n_bits
;