1 ///////////////////////////////////////////////////////////////////////////////
2 // Copyright (c) 2000-2014 Ericsson Telecom AB
3 // All rights reserved. This program and the accompanying materials
4 // are made available under the terms of the Eclipse Public License v1.0
5 // which accompanies this distribution, and is available at
6 // http://www.eclipse.org/legal/epl-v10.html
7 ///////////////////////////////////////////////////////////////////////////////
8 #include "Octetstring.hh"
9 #include "../common/memory.h"
11 #include "String_struct.hh"
12 #include "Param_Types.hh"
21 #include "../common/dbgnew.hh"
24 // octetstring value class
26 /** The amount of memory needed for a string containing n octets. */
27 #define MEMORY_SIZE(n) (sizeof(octetstring_struct) - sizeof(int) + (n))
29 static const Token_Match
30 octetstring_value_match("^(([0-9A-Fa-f]{2})+).*$", TRUE
);
32 void OCTETSTRING::init_struct(int n_octets
)
36 TTCN_error("Initializing an octetstring with a negative length.");
37 } else if (n_octets
== 0) {
38 /* This will represent the empty strings so they won't need allocated
39 * memory, this delays the memory allocation until it is really needed.
41 static octetstring_struct empty_string
= { 1, 0, "" };
42 val_ptr
= &empty_string
;
43 empty_string
.ref_count
++;
45 val_ptr
= (octetstring_struct
*)Malloc(MEMORY_SIZE(n_octets
));
46 val_ptr
->ref_count
= 1;
47 val_ptr
->n_octets
= n_octets
;
51 void OCTETSTRING::copy_value()
53 if (val_ptr
== NULL
|| val_ptr
->n_octets
<= 0)
54 TTCN_error("Internal error: Invalid internal data structure when copying "
55 "the memory area of an octetstring value.");
56 if (val_ptr
->ref_count
> 1) {
57 octetstring_struct
*old_ptr
= val_ptr
;
59 init_struct(old_ptr
->n_octets
);
60 memcpy(val_ptr
->octets_ptr
, old_ptr
->octets_ptr
, old_ptr
->n_octets
);
64 // Called by operator+, operator~, operator&, operator|
65 // to initialize the return value to the appropriate capacity
66 // without copying bytes (which will be altered).
67 OCTETSTRING::OCTETSTRING(int n_octets
)
69 init_struct(n_octets
);
72 OCTETSTRING::OCTETSTRING()
77 OCTETSTRING::OCTETSTRING(int n_octets
, const unsigned char* octets_ptr
)
79 init_struct(n_octets
);
80 memcpy(val_ptr
->octets_ptr
, octets_ptr
, n_octets
);
83 OCTETSTRING::OCTETSTRING(const OCTETSTRING
& other_value
)
84 : Base_Type(other_value
)
86 other_value
.must_bound("Copying an unbound octetstring value.");
87 val_ptr
= other_value
.val_ptr
;
91 OCTETSTRING::OCTETSTRING(const OCTETSTRING_ELEMENT
& other_value
)
93 other_value
.must_bound("Copying an unbound octetstring element.");
95 val_ptr
->octets_ptr
[0] = other_value
.get_octet();
98 OCTETSTRING::~OCTETSTRING()
103 OCTETSTRING
& OCTETSTRING::operator=(const OCTETSTRING
& other_value
)
105 other_value
.must_bound("Assignment of an unbound octetstring value.");
106 if (&other_value
!= this) {
108 val_ptr
= other_value
.val_ptr
;
109 val_ptr
->ref_count
++;
114 OCTETSTRING
& OCTETSTRING::operator=(const OCTETSTRING_ELEMENT
& other_value
)
116 other_value
.must_bound("Assignment of an unbound octetstring element to an "
118 unsigned char octet_value
= other_value
.get_octet();
121 val_ptr
->octets_ptr
[0] = octet_value
;
125 boolean
OCTETSTRING::operator==(const OCTETSTRING
& other_value
) const
127 must_bound("Unbound left operand of octetstring comparison.");
128 other_value
.must_bound("Unbound right operand of octetstring comparison.");
129 if (val_ptr
->n_octets
!= other_value
.val_ptr
->n_octets
) return FALSE
;
130 return !memcmp(val_ptr
->octets_ptr
, other_value
.val_ptr
->octets_ptr
,
134 boolean
OCTETSTRING::operator==(const OCTETSTRING_ELEMENT
& other_value
) const
136 must_bound("Unbound left operand of octetstring comparison.");
137 other_value
.must_bound("Unbound right operand of octetstring element "
139 if (val_ptr
->n_octets
!= 1) return FALSE
;
140 return val_ptr
->octets_ptr
[0] == other_value
.get_octet();
143 OCTETSTRING
OCTETSTRING::operator+(const OCTETSTRING
& other_value
) const
145 must_bound("Unbound left operand of octetstring concatenation.");
146 other_value
.must_bound("Unbound right operand of octetstring concatenation.");
147 int left_n_octets
= val_ptr
->n_octets
;
148 if (left_n_octets
== 0) return other_value
;
149 int right_n_octets
= other_value
.val_ptr
->n_octets
;
150 if (right_n_octets
== 0) return *this;
151 OCTETSTRING
ret_val(left_n_octets
+ right_n_octets
);
152 memcpy(ret_val
.val_ptr
->octets_ptr
, val_ptr
->octets_ptr
, left_n_octets
);
153 memcpy(ret_val
.val_ptr
->octets_ptr
+ left_n_octets
,
154 other_value
.val_ptr
->octets_ptr
, right_n_octets
);
158 OCTETSTRING
OCTETSTRING::operator+(const OCTETSTRING_ELEMENT
& other_value
) const
160 must_bound("Unbound left operand of octetstring concatenation.");
161 other_value
.must_bound("Unbound right operand of octetstring element "
163 OCTETSTRING
ret_val(val_ptr
->n_octets
+ 1);
164 memcpy(ret_val
.val_ptr
->octets_ptr
, val_ptr
->octets_ptr
, val_ptr
->n_octets
);
165 ret_val
.val_ptr
->octets_ptr
[val_ptr
->n_octets
] = other_value
.get_octet();
169 OCTETSTRING
& OCTETSTRING::operator+=(const OCTETSTRING
& other_value
)
171 must_bound("Appending an octetstring value to an unbound octetstring value.");
172 other_value
.must_bound("Appending an unbound octetstring value to another "
173 "octetstring value.");
174 int other_n_octets
= other_value
.val_ptr
->n_octets
;
175 if (other_n_octets
> 0) {
176 if (val_ptr
->n_octets
== 0) {
178 val_ptr
= other_value
.val_ptr
;
179 val_ptr
->ref_count
++;
180 } else if (val_ptr
->ref_count
> 1) {
181 octetstring_struct
*old_ptr
= val_ptr
;
182 old_ptr
->ref_count
--;
183 init_struct(old_ptr
->n_octets
+ other_n_octets
);
184 memcpy(val_ptr
->octets_ptr
, old_ptr
->octets_ptr
, old_ptr
->n_octets
);
185 memcpy(val_ptr
->octets_ptr
+ old_ptr
->n_octets
,
186 other_value
.val_ptr
->octets_ptr
, other_n_octets
);
188 val_ptr
= (octetstring_struct
*)
189 Realloc(val_ptr
, MEMORY_SIZE(val_ptr
->n_octets
+ other_n_octets
));
190 memcpy(val_ptr
->octets_ptr
+ val_ptr
->n_octets
,
191 other_value
.val_ptr
->octets_ptr
, other_n_octets
);
192 val_ptr
->n_octets
+= other_n_octets
;
198 OCTETSTRING
& OCTETSTRING::operator+=(const OCTETSTRING_ELEMENT
& other_value
)
200 must_bound("Appending an octetstring element to an unbound octetstring "
202 other_value
.must_bound("Appending an unbound octetstring element to an "
203 "octetstring value.");
204 if (val_ptr
->ref_count
> 1) {
205 octetstring_struct
*old_ptr
= val_ptr
;
206 old_ptr
->ref_count
--;
207 init_struct(old_ptr
->n_octets
+ 1);
208 memcpy(val_ptr
->octets_ptr
, old_ptr
->octets_ptr
, old_ptr
->n_octets
);
209 val_ptr
->octets_ptr
[old_ptr
->n_octets
] = other_value
.get_octet();
211 val_ptr
= (octetstring_struct
*)
212 Realloc(val_ptr
, MEMORY_SIZE(val_ptr
->n_octets
+ 1));
213 val_ptr
->octets_ptr
[val_ptr
->n_octets
] = other_value
.get_octet();
219 OCTETSTRING
OCTETSTRING::operator~() const
221 must_bound("Unbound octetstring operand of operator not4b.");
222 OCTETSTRING
ret_val(val_ptr
->n_octets
);
223 for (int i
= 0; i
< val_ptr
->n_octets
; i
++)
224 ret_val
.val_ptr
->octets_ptr
[i
] = ~val_ptr
->octets_ptr
[i
];
228 OCTETSTRING
OCTETSTRING::operator&(const OCTETSTRING
& other_value
) const
230 must_bound("Left operand of operator and4b is an unbound octetstring value.");
231 other_value
.must_bound("Right operand of operator and4b is an unbound "
232 "octetstring value.");
233 if (val_ptr
->n_octets
!= other_value
.val_ptr
->n_octets
)
234 TTCN_error("The octetstring operands of operator and4b must have the "
236 OCTETSTRING
ret_val(val_ptr
->n_octets
);
237 for (int i
= 0; i
< val_ptr
->n_octets
; i
++)
238 ret_val
.val_ptr
->octets_ptr
[i
] =
239 val_ptr
->octets_ptr
[i
] & other_value
.val_ptr
->octets_ptr
[i
];
243 OCTETSTRING
OCTETSTRING::operator&(const OCTETSTRING_ELEMENT
& other_value
) const
245 must_bound("Left operand of operator and4b is an unbound octetstring value.");
246 other_value
.must_bound("Right operand of operator and4b is an unbound "
247 "octetstring element.");
248 if (val_ptr
->n_octets
!= 1)
249 TTCN_error("The octetstring operands of "
250 "operator and4b must have the same length.");
251 unsigned char result
= val_ptr
->octets_ptr
[0] & other_value
.get_octet();
252 return OCTETSTRING(1, &result
);
255 OCTETSTRING
OCTETSTRING::operator|(const OCTETSTRING
& other_value
) const
257 must_bound("Left operand of operator or4b is an unbound octetstring value.");
258 other_value
.must_bound("Right operand of operator or4b is an unbound "
259 "octetstring value.");
260 if (val_ptr
->n_octets
!= other_value
.val_ptr
->n_octets
)
261 TTCN_error("The octetstring operands of operator or4b must have the "
263 OCTETSTRING
ret_val(val_ptr
->n_octets
);
264 for (int i
= 0; i
< val_ptr
->n_octets
; i
++)
265 ret_val
.val_ptr
->octets_ptr
[i
] =
266 val_ptr
->octets_ptr
[i
] | other_value
.val_ptr
->octets_ptr
[i
];
270 OCTETSTRING
OCTETSTRING::operator|(const OCTETSTRING_ELEMENT
& other_value
) const
272 must_bound("Left operand of operator or4b is an unbound octetstring value.");
273 other_value
.must_bound("Right operand of operator or4b is an unbound "
274 "octetstring element.");
275 if (val_ptr
->n_octets
!= 1)
276 TTCN_error("The octetstring operands of "
277 "operator or4b must have the same length.");
278 unsigned char result
= val_ptr
->octets_ptr
[0] | other_value
.get_octet();
279 return OCTETSTRING(1, &result
);
282 OCTETSTRING
OCTETSTRING::operator^(const OCTETSTRING
& other_value
) const
284 must_bound("Left operand of operator xor4b is an unbound octetstring value.");
285 other_value
.must_bound("Right operand of operator xor4b is an unbound "
286 "octetstring value.");
287 if (val_ptr
->n_octets
!= other_value
.val_ptr
->n_octets
)
288 TTCN_error("The octetstring operands of operator xor4b must have the "
290 OCTETSTRING
ret_val(val_ptr
->n_octets
);
291 for (int i
= 0; i
< val_ptr
->n_octets
; i
++)
292 ret_val
.val_ptr
->octets_ptr
[i
] =
293 val_ptr
->octets_ptr
[i
] ^ other_value
.val_ptr
->octets_ptr
[i
];
297 OCTETSTRING
OCTETSTRING::operator^(const OCTETSTRING_ELEMENT
& other_value
) const
299 must_bound("Left operand of operator xor4b is an unbound octetstring value.");
300 other_value
.must_bound("Right operand of operator xor4b is an unbound "
301 "octetstring element.");
302 if (val_ptr
->n_octets
!= 1)
303 TTCN_error("The octetstring operands of "
304 "operator xor4b must have the same length.");
305 unsigned char result
= val_ptr
->octets_ptr
[0] ^ other_value
.get_octet();
306 return OCTETSTRING(1, &result
);
309 OCTETSTRING
OCTETSTRING::operator<<(int shift_count
) const
311 must_bound("Unbound octetstring operand of shift left operator.");
312 if (shift_count
> 0) {
313 if (val_ptr
->n_octets
== 0) return *this;
314 OCTETSTRING
ret_val(val_ptr
->n_octets
);
315 if (shift_count
> val_ptr
->n_octets
) shift_count
= val_ptr
->n_octets
;
316 memcpy(ret_val
.val_ptr
->octets_ptr
, val_ptr
->octets_ptr
+ shift_count
,
317 val_ptr
->n_octets
- shift_count
);
318 memset(ret_val
.val_ptr
->octets_ptr
+ val_ptr
->n_octets
- shift_count
,
321 } else if (shift_count
== 0) return *this;
322 else return *this >> (-shift_count
);
325 OCTETSTRING
OCTETSTRING::operator<<(const INTEGER
& shift_count
) const
327 shift_count
.must_bound("Unbound right operand of octetstring shift left "
329 return *this << (int)shift_count
;
332 OCTETSTRING
OCTETSTRING::operator>>(int shift_count
) const
334 must_bound("Unbound octetstring operand of shift right operator.");
335 if (shift_count
> 0) {
336 if (val_ptr
->n_octets
== 0) return *this;
337 OCTETSTRING
ret_val(val_ptr
->n_octets
);
338 if (shift_count
> val_ptr
->n_octets
) shift_count
= val_ptr
->n_octets
;
339 memset(ret_val
.val_ptr
->octets_ptr
, 0, shift_count
);
340 memcpy(ret_val
.val_ptr
->octets_ptr
+ shift_count
, val_ptr
->octets_ptr
,
341 val_ptr
->n_octets
- shift_count
);
343 } else if (shift_count
== 0) return *this;
344 else return *this << (-shift_count
);
347 OCTETSTRING
OCTETSTRING::operator>>(const INTEGER
& shift_count
) const
349 shift_count
.must_bound("Unbound right operand of octetstring shift right "
351 return *this >> (int)shift_count
;
354 OCTETSTRING
OCTETSTRING::operator<<=(int rotate_count
) const
356 must_bound("Unbound octetstring operand of rotate left operator.");
357 if (val_ptr
->n_octets
== 0) return *this;
358 if (rotate_count
>= 0) {
359 rotate_count
%= val_ptr
->n_octets
;
360 if (rotate_count
== 0) return *this;
361 OCTETSTRING
ret_val(val_ptr
->n_octets
);
362 memcpy(ret_val
.val_ptr
->octets_ptr
, val_ptr
->octets_ptr
+
363 rotate_count
, val_ptr
->n_octets
- rotate_count
);
364 memcpy(ret_val
.val_ptr
->octets_ptr
+ val_ptr
->n_octets
- rotate_count
,
365 val_ptr
->octets_ptr
, rotate_count
);
367 } else return *this >>= (-rotate_count
);
370 OCTETSTRING
OCTETSTRING::operator<<=(const INTEGER
& rotate_count
) const
372 rotate_count
.must_bound("Unbound right operand of octetstring rotate left "
374 return *this <<= (int)rotate_count
;
377 OCTETSTRING
OCTETSTRING::operator>>=(int rotate_count
) const
379 must_bound("Unbound octetstring operand of rotate right operator.");
380 if (val_ptr
->n_octets
== 0) return *this;
381 if (rotate_count
>= 0) {
382 rotate_count
%= val_ptr
->n_octets
;
383 if (rotate_count
== 0) return *this;
384 OCTETSTRING
ret_val(val_ptr
->n_octets
);
385 memcpy(ret_val
.val_ptr
->octets_ptr
, val_ptr
->octets_ptr
+
386 val_ptr
->n_octets
- rotate_count
, rotate_count
);
387 memcpy(ret_val
.val_ptr
->octets_ptr
+ rotate_count
,
388 val_ptr
->octets_ptr
, val_ptr
->n_octets
- rotate_count
);
390 } else return *this <<= (-rotate_count
);
393 OCTETSTRING
OCTETSTRING::operator>>=(const INTEGER
& rotate_count
) const
395 rotate_count
.must_bound("Unbound right operand of octetstring rotate right "
397 return *this >>= (int)rotate_count
;
400 OCTETSTRING_ELEMENT
OCTETSTRING::operator[](int index_value
)
402 if (val_ptr
== NULL
&& index_value
== 0) {
404 return OCTETSTRING_ELEMENT(FALSE
, *this, 0);
406 must_bound("Accessing an element of an unbound octetstring value.");
407 if (index_value
< 0) TTCN_error("Accessing an octetstring element using "
408 "a negative index (%d).", index_value
);
409 int n_octets
= val_ptr
->n_octets
;
410 if (index_value
> n_octets
) TTCN_error("Index overflow when accessing a "
411 "octetstring element: The index is %d, but the string has only %d "
412 "octets.", index_value
, n_octets
);
413 if (index_value
== n_octets
) {
414 if (val_ptr
->ref_count
== 1) {
415 val_ptr
= (octetstring_struct
*)
416 Realloc(val_ptr
, MEMORY_SIZE(n_octets
+ 1));
419 octetstring_struct
*old_ptr
= val_ptr
;
420 old_ptr
->ref_count
--;
421 init_struct(n_octets
+ 1);
422 memcpy(val_ptr
->octets_ptr
, old_ptr
->octets_ptr
, n_octets
);
424 return OCTETSTRING_ELEMENT(FALSE
, *this, index_value
);
425 } else return OCTETSTRING_ELEMENT(TRUE
, *this, index_value
);
429 OCTETSTRING_ELEMENT
OCTETSTRING::operator[](const INTEGER
& index_value
)
431 index_value
.must_bound("Indexing a octetstring value with an unbound integer "
433 return (*this)[(int)index_value
];
436 const OCTETSTRING_ELEMENT
OCTETSTRING::operator[](int index_value
) const
438 must_bound("Accessing an element of an unbound octetstring value.");
439 if (index_value
< 0) TTCN_error("Accessing an octetstring element using a "
440 "negative index (%d).", index_value
);
441 if (index_value
>= val_ptr
->n_octets
) TTCN_error("Index overflow when "
442 "accessing a octetstring element: The index is %d, but the string has "
443 "only %d octets.", index_value
, val_ptr
->n_octets
);
444 return OCTETSTRING_ELEMENT(TRUE
, const_cast<OCTETSTRING
&>(*this),
448 const OCTETSTRING_ELEMENT
OCTETSTRING::operator[](const INTEGER
& index_value
)
451 index_value
.must_bound("Indexing a octetstring value with an unbound integer "
453 return (*this)[(int)index_value
];
456 void OCTETSTRING::clean_up()
458 if (val_ptr
!= NULL
) {
459 if (val_ptr
->ref_count
> 1) val_ptr
->ref_count
--;
460 else if (val_ptr
->ref_count
== 1) Free(val_ptr
);
461 else TTCN_error("Internal error: Invalid reference counter in an "
462 "octetstring value.");
467 int OCTETSTRING::lengthof() const
469 must_bound("Getting the length of an unbound octetstring value.");
470 return val_ptr
->n_octets
;
473 OCTETSTRING::operator const unsigned char*() const
475 must_bound("Casting an unbound octetstring value to const unsigned char*.");
476 return val_ptr
->octets_ptr
;
479 void OCTETSTRING::log() const
481 if (val_ptr
!= NULL
) {
482 boolean only_printable
= TRUE
;
483 TTCN_Logger::log_char('\'');
484 for (int i
= 0; i
< val_ptr
->n_octets
; i
++) {
485 unsigned char octet
= val_ptr
->octets_ptr
[i
];
486 TTCN_Logger::log_octet(octet
);
487 if (only_printable
&& !TTCN_Logger::is_printable(octet
))
488 only_printable
= FALSE
;
490 TTCN_Logger::log_event_str("'O");
491 if (only_printable
&& val_ptr
->n_octets
> 0) {
492 TTCN_Logger::log_event_str(" (\"");
493 for (int i
= 0; i
< val_ptr
->n_octets
; i
++)
494 TTCN_Logger::log_char_escaped(val_ptr
->octets_ptr
[i
]);
495 TTCN_Logger::log_event_str("\")");
497 } else TTCN_Logger::log_event_unbound();
500 void OCTETSTRING::set_param(Module_Param
& param
) {
501 param
.basic_check(Module_Param::BC_VALUE
|Module_Param::BC_LIST
, "octetstring value");
502 if (param
.get_type()!=Module_Param::MP_Octetstring
) param
.type_error("octetstring value");
503 switch (param
.get_operation_type()) {
504 case Module_Param::OT_ASSIGN
:
506 init_struct(param
.get_string_size());
507 memcpy(val_ptr
->octets_ptr
, param
.get_string_data(), val_ptr
->n_octets
);
509 case Module_Param::OT_CONCAT
:
511 *this += OCTETSTRING(param
.get_string_size(), (unsigned char*)param
.get_string_data());
513 *this = OCTETSTRING(param
.get_string_size(), (unsigned char*)param
.get_string_data());
517 TTCN_error("Internal error: OCTETSTRING::set_param()");
521 void OCTETSTRING::encode_text(Text_Buf
& text_buf
) const
523 must_bound("Text encoder: Encoding an unbound octetstring value.");
524 text_buf
.push_int(val_ptr
->n_octets
);
525 if(val_ptr
->n_octets
> 0)
526 text_buf
.push_raw(val_ptr
->n_octets
, val_ptr
->octets_ptr
);
529 void OCTETSTRING::decode_text(Text_Buf
& text_buf
)
531 int n_octets
= text_buf
.pull_int().get_val();
533 TTCN_error("Text decoder: Invalid length was received for an octetstring.");
535 init_struct(n_octets
);
536 if (n_octets
> 0) text_buf
.pull_raw(n_octets
, val_ptr
->octets_ptr
);
539 void OCTETSTRING::encode(const TTCN_Typedescriptor_t
& p_td
,
541 TTCN_EncDec::coding_t p_coding
, ...) const
544 va_start(pvar
, p_coding
);
546 case TTCN_EncDec::CT_BER
: {
547 TTCN_EncDec_ErrorContext
ec("While BER-encoding type '%s': ", p_td
.name
);
548 unsigned BER_coding
=va_arg(pvar
, unsigned);
549 BER_encode_chk_coding(BER_coding
);
550 ASN_BER_TLV_t
*tlv
=BER_encode_TLV(p_td
, BER_coding
);
551 tlv
->put_in_buffer(p_buf
);
552 ASN_BER_TLV_t::destruct(tlv
);
554 case TTCN_EncDec::CT_RAW
: {
555 TTCN_EncDec_ErrorContext
ec("While RAW-encoding type '%s': ", p_td
.name
);
557 TTCN_EncDec_ErrorContext::error_internal
558 ("No RAW descriptor available for type '%s'.", p_td
.name
);
562 RAW_enc_tree
root(true,NULL
,&rp
,1,p_td
.raw
);
563 RAW_encode(p_td
, root
);
564 root
.put_to_buf(p_buf
);
566 case TTCN_EncDec::CT_TEXT
: {
567 TTCN_EncDec_ErrorContext
ec("While TEXT-encoding type '%s': ", p_td
.name
);
569 TTCN_EncDec_ErrorContext::error_internal
570 ("No TEXT descriptor available for type '%s'.", p_td
.name
);
571 TEXT_encode(p_td
,p_buf
);
573 case TTCN_EncDec::CT_XER
: {
574 TTCN_EncDec_ErrorContext
ec("While XER-encoding type '%s': ", p_td
.name
);
575 unsigned XER_coding
=va_arg(pvar
, unsigned);
576 XER_encode(*p_td
.xer
, p_buf
, XER_coding
, 0, 0);
578 case TTCN_EncDec::CT_JSON
: {
579 TTCN_EncDec_ErrorContext
ec("While TEXT-encoding type '%s': ", p_td
.name
);
581 TTCN_EncDec_ErrorContext::error_internal
582 ("No JSON descriptor available for type '%s'.", p_td
.name
);
583 JSON_Tokenizer
tok(va_arg(pvar
, int) != 0);
584 JSON_encode(p_td
, tok
);
585 p_buf
.put_s(tok
.get_buffer_length(), (const unsigned char*)tok
.get_buffer());
588 TTCN_error("Unknown coding method requested to encode type '%s'",
594 void OCTETSTRING::decode(const TTCN_Typedescriptor_t
& p_td
,
596 TTCN_EncDec::coding_t p_coding
, ...)
599 va_start(pvar
, p_coding
);
601 case TTCN_EncDec::CT_BER
: {
602 TTCN_EncDec_ErrorContext
ec("While BER-decoding type '%s': ", p_td
.name
);
603 unsigned L_form
=va_arg(pvar
, unsigned);
605 BER_decode_str2TLV(p_buf
, tlv
, L_form
);
606 BER_decode_TLV(p_td
, tlv
, L_form
);
607 if(tlv
.isComplete
) p_buf
.increase_pos(tlv
.get_len());
609 case TTCN_EncDec::CT_RAW
: {
610 TTCN_EncDec_ErrorContext
ec("While RAW-decoding type '%s': ", p_td
.name
);
612 TTCN_EncDec_ErrorContext::error_internal
613 ("No RAW descriptor available for type '%s'.", p_td
.name
);
615 switch(p_td
.raw
->top_bit_order
){
623 if(RAW_decode(p_td
, p_buf
, p_buf
.get_len()*8, order
)<0)
624 ec
.error(TTCN_EncDec::ET_INCOMPL_MSG
,
625 "Can not decode type '%s', because invalid or incomplete"
626 " message was received"
629 case TTCN_EncDec::CT_TEXT
: {
630 Limit_Token_List limit
;
631 TTCN_EncDec_ErrorContext
ec("While TEXT-decoding type '%s': ", p_td
.name
);
633 TTCN_EncDec_ErrorContext::error_internal
634 ("No TEXT descriptor available for type '%s'.", p_td
.name
);
635 const unsigned char *b
=p_buf
.get_data();
636 if(b
[p_buf
.get_len()-1]!='\0'){
637 p_buf
.set_pos(p_buf
.get_len());
638 p_buf
.put_zero(8,ORDER_LSB
);
641 if(TEXT_decode(p_td
,p_buf
,limit
)<0)
642 ec
.error(TTCN_EncDec::ET_INCOMPL_MSG
,
643 "Can not decode type '%s', because invalid or incomplete"
644 " message was received"
647 case TTCN_EncDec::CT_XER
: {
648 TTCN_EncDec_ErrorContext
ec("While XER-decoding type '%s': ", p_td
.name
);
649 unsigned XER_coding
=va_arg(pvar
, unsigned);
650 XmlReaderWrap
reader(p_buf
);
651 int success
= reader
.Read();
652 for (; success
==1; success
=reader
.Read()) {
653 int type
= reader
.NodeType();
654 if (type
==XML_READER_TYPE_ELEMENT
)
657 XER_decode(*p_td
.xer
, reader
, XER_coding
, 0);
658 size_t bytes
= reader
.ByteConsumed();
659 p_buf
.set_pos(bytes
);
661 case TTCN_EncDec::CT_JSON
: {
662 TTCN_EncDec_ErrorContext
ec("While JSON-decoding type '%s': ", p_td
.name
);
664 TTCN_EncDec_ErrorContext::error_internal
665 ("No JSON descriptor available for type '%s'.", p_td
.name
);
666 JSON_Tokenizer
tok((const char*)p_buf
.get_data(), p_buf
.get_len());
667 if(JSON_decode(p_td
, tok
, false)<0)
668 ec
.error(TTCN_EncDec::ET_INCOMPL_MSG
,
669 "Can not decode type '%s', because invalid or incomplete"
670 " message was received"
672 p_buf
.set_pos(tok
.get_buf_pos());
675 TTCN_error("Unknown coding method requested to decode type '%s'",
682 OCTETSTRING::BER_encode_TLV(const TTCN_Typedescriptor_t
& p_td
,
683 unsigned p_coding
) const
686 ASN_BER_TLV_t
*new_tlv
=BER_encode_chk_bound(is_bound());
688 new_tlv
=BER_encode_TLV_OCTETSTRING
689 (p_coding
, val_ptr
->n_octets
, val_ptr
->octets_ptr
);
691 new_tlv
=ASN_BER_V2TLV(new_tlv
, p_td
, p_coding
);
695 #ifdef TITAN_RUNTIME_2
696 ASN_BER_TLV_t
* OCTETSTRING::BER_encode_negtest_raw() const
698 unsigned char *p_Vstr
= (unsigned char *)Malloc(val_ptr
->n_octets
);
699 memcpy(p_Vstr
, val_ptr
->octets_ptr
, val_ptr
->n_octets
);
700 ASN_BER_TLV_t
* new_tlv
= ASN_BER_TLV_t::construct(val_ptr
->n_octets
, p_Vstr
);
704 int OCTETSTRING::encode_raw(TTCN_Buffer
& p_buf
) const
706 p_buf
.put_string(*this);
707 return val_ptr
? val_ptr
->n_octets
: 0;
710 int OCTETSTRING::RAW_encode_negtest_raw(RAW_enc_tree
& p_myleaf
) const
712 if (p_myleaf
.must_free
)
713 Free(p_myleaf
.body
.leaf
.data_ptr
);
714 p_myleaf
.must_free
= false;
715 p_myleaf
.data_ptr_used
= true;
716 p_myleaf
.body
.leaf
.data_ptr
= val_ptr
->octets_ptr
;
717 return p_myleaf
.length
= val_ptr
->n_octets
* 8;
721 boolean
OCTETSTRING::BER_decode_TLV(const TTCN_Typedescriptor_t
& p_td
,
722 const ASN_BER_TLV_t
& p_tlv
,
727 ASN_BER_TLV_t stripped_tlv
;
728 BER_decode_strip_tags(*p_td
.ber
, p_tlv
, L_form
, stripped_tlv
);
729 TTCN_EncDec_ErrorContext
ec("While decoding OCTETSTRING type: ");
730 /* Upper estimation for the length. */
731 size_t stripped_tlv_len
= stripped_tlv
.get_len();
732 if (stripped_tlv_len
< 2) return FALSE
;
733 int max_len
= stripped_tlv_len
- 2;
734 init_struct(max_len
);
735 unsigned int octetnum_start
= 0;
736 BER_decode_TLV_OCTETSTRING(stripped_tlv
, L_form
, octetnum_start
,
737 val_ptr
->n_octets
, val_ptr
->octets_ptr
);
738 if (val_ptr
->n_octets
< max_len
) {
739 if (val_ptr
->n_octets
== 0) {
743 val_ptr
= (octetstring_struct
*)
744 Realloc(val_ptr
, MEMORY_SIZE(val_ptr
->n_octets
));
750 int OCTETSTRING::TEXT_decode(const TTCN_Typedescriptor_t
& p_td
,
751 TTCN_Buffer
& buff
, Limit_Token_List
& limit
,
752 boolean no_err
, boolean
/*first_call*/)
754 int decoded_length
=0;
757 if(p_td
.text
->begin_decode
){
759 if((tl
=p_td
.text
->begin_decode
->match_begin(buff
))<0){
761 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR
,
762 "The specified token '%s' not found for '%s': ",
763 (const char*)*(p_td
.text
->begin_decode
), p_td
.name
);
767 buff
.increase_pos(tl
);
769 // never returns "too short"
770 // if(buff.get_read_len()<=1 && no_err) return -TTCN_EncDec::ET_LEN_ERR;
772 if(p_td
.text
->select_token
){
774 if((tl
=p_td
.text
->select_token
->match_begin(buff
))<0) {
775 if(no_err
) return -1;
780 if( p_td
.text
->val
.parameters
781 && p_td
.text
->val
.parameters
->decoding_params
.min_length
!=-1){
782 str_len
=p_td
.text
->val
.parameters
->decoding_params
.min_length
*2;
783 } else if(p_td
.text
->end_decode
){
785 if((tl
=p_td
.text
->end_decode
->match_first(buff
))<0) {
786 if(no_err
) return -1;
790 } else if (limit
.has_token()){
792 if((tl
=limit
.match(buff
))<0)
793 tl
=buff
.get_read_len()-1;;
797 if((tl
=octetstring_value_match
.match_begin(buff
))<0) {
798 if(no_err
) {return -1; }
803 str_len
=(str_len
/2)*2;
804 //printf("HALI chr:%d ",str_len);
805 int n_octets
= str_len
/ 2;
806 init_struct(n_octets
);
807 unsigned char *octets_ptr
= val_ptr
->octets_ptr
;
808 const char *value
=(const char*)buff
.get_read_data();
809 for (int i
= 0; i
< n_octets
; i
++) {
810 unsigned char upper_nibble
= char_to_hexdigit(value
[2 * i
]);
811 unsigned char lower_nibble
= char_to_hexdigit(value
[2 * i
+ 1]);
812 if (upper_nibble
> 0x0F){
813 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG
,
814 "The octetstring value may contain hexadecimal digits only. "
815 "Character \"%c\" was found.", value
[2 * i
]);
818 if (lower_nibble
> 0x0F){
819 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG
,
820 "The octetstring value str2oct() may contain hexadecimal digits only. "
821 "Character \"%c\" was found.", value
[2 * i
+ 1]);
824 octets_ptr
[i
] = (upper_nibble
<< 4) | lower_nibble
;
827 //printf("%s\n\r",val_ptr->chars_ptr);
828 decoded_length
+=str_len
;
829 buff
.increase_pos(str_len
);
831 if(p_td
.text
->end_decode
){
833 if((tl
=p_td
.text
->end_decode
->match_begin(buff
))<0){
835 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR
,
836 "The specified token '%s' not found for '%s': ",
837 (const char*)*(p_td
.text
->end_decode
), p_td
.name
);
841 buff
.increase_pos(tl
);
843 return decoded_length
;
846 // From Charstring.cc
847 extern char base64_decoder_table
[256];
848 extern unsigned int xlate(cbyte
* in
, int phase
, unsigned char* dest
);
849 extern const char cb64
[];
851 int OCTETSTRING::XER_encode(const XERdescriptor_t
& p_td
,
852 TTCN_Buffer
& p_buf
, unsigned int flavor
, int indent
, embed_values_enc_struct_t
*) const
855 TTCN_EncDec_ErrorContext::error
856 (TTCN_EncDec::ET_UNBOUND
, "Encoding an unbound octetstring value.");
858 int exer
= is_exer(flavor
|= SIMPLE_TYPE
);
859 // SIMPLE_TYPE has no influence on is_exer, we set it for later
860 int encoded_length
=(int)p_buf
.get_len();
861 int empty_element
= val_ptr
==NULL
|| val_ptr
->n_octets
== 0;
863 flavor
&= ~XER_RECOF
; // octetstring doesn't care
864 begin_xml(p_td
, p_buf
, flavor
, indent
, empty_element
);
866 if (exer
&& (p_td
.xer_bits
& BASE_64
)) {
868 size_t clear_len
= lengthof();
869 const unsigned char * in
= operator const unsigned char*();
871 /* Encode 3 bytes of cleartext into 4 bytes of Base64.
872 * Note that the algorithm is slightly different from Charstring.cc:
873 * we can't pad the source because it's const (this),
874 * so we need to check the indexes i+1 and i+2 before dereferencing */
875 for (size_t i
= 0; i
< clear_len
; i
+= 3) {
876 p_buf
.put_c( cb64
[ in
[i
] >> 2 ] );
877 p_buf
.put_c( cb64
[ ((in
[i
] & 0x03) << 4) | (i
+1 < clear_len
878 ? ((in
[i
+1] & 0xf0) >> 4)
880 p_buf
.put_c( i
+1 < clear_len
881 ? cb64
[ ((in
[i
+1] & 0x0f) << 2) | (i
+2 < clear_len
? ((in
[i
+2] & 0xc0) >> 6) :-0) ]
883 p_buf
.put_c( i
+2 < clear_len
? cb64
[ in
[i
+2] & 0x3f ] : '=' );
887 CHARSTRING val
= oct2str(*this);
888 p_buf
.put_string(val
);
891 end_xml(p_td
, p_buf
, flavor
, indent
, empty_element
);
893 return (int)p_buf
.get_len() - encoded_length
;
896 int OCTETSTRING::XER_decode(const XERdescriptor_t
& p_td
, XmlReaderWrap
& reader
,
897 unsigned int flavor
, embed_values_dec_struct_t
*)
899 int exer
= is_exer(flavor
);
900 int success
= reader
.Ok(), depth
= -1, type
;
901 boolean own_tag
= !is_exerlist(flavor
) && !(exer
&& (p_td
.xer_bits
& UNTAGGED
));
903 const char * value
= 0;
904 if (exer
&& (p_td
.xer_bits
& XER_ATTRIBUTE
)) {
905 const char * name
= verify_name(reader
, p_td
, exer
);
909 if (own_tag
) for (; success
== 1; success
= reader
.Read()) {
910 type
= reader
.NodeType();
911 if (XML_READER_TYPE_ELEMENT
== type
) {
912 verify_name(reader
, p_td
, exer
);
913 depth
= reader
.Depth();
914 if (reader
.IsEmptyElement()) {
915 if (exer
&& p_td
.dfeValue
!= 0) {
916 *this = *static_cast<const OCTETSTRING
*> (p_td
.dfeValue
);
923 else if (XML_READER_TYPE_TEXT
== type
&& depth
!= -1) break;
924 else if (XML_READER_TYPE_END_ELEMENT
== type
) {
925 // End tag without intervening #text == empty content
926 verify_end(reader
, p_td
, depth
, exer
);
927 if (exer
&& p_td
.dfeValue
!= 0) {
928 *this = *static_cast<const OCTETSTRING
*>(p_td
.dfeValue
);
936 type
= reader
.NodeType();
937 if (success
== 1 && (XML_READER_TYPE_TEXT
== type
|| XML_READER_TYPE_ATTRIBUTE
== type
)) {
938 value
= (const char *)reader
.Value();
939 size_t len
= value
? strlen(value
) : 0;
941 if (exer
&& (p_td
.xer_bits
& BASE_64
)) {
945 init_struct(len
* 3 / 4);
946 unsigned char * dest
= val_ptr
->octets_ptr
;
948 for (size_t o
=0; o
<len
; ++o
) {
949 xmlChar c
= value
[o
];
950 if(c
== '=') { // padding starts
951 dest
+= xlate(in
, phase
, dest
);
955 int val
= base64_decoder_table
[c
];
958 phase
= (phase
+ 1) % 4;
960 dest
+= xlate(in
,phase
, dest
);
961 in
[0]=in
[1]=in
[2]=in
[3]=0;
964 else if (exer
&& (flavor
& EXIT_ON_ERROR
)) {
968 TTCN_EncDec_ErrorContext::warning(
969 /* if this was an error... TTCN_EncDec::ET_INVAL_MSG,*/
970 "Invalid character for Base64 '%02X'", c
);
974 val_ptr
->n_octets
= dest
- val_ptr
->octets_ptr
;
978 if (len
& 1) { // that's odd...
979 if (exer
&& (flavor
& EXIT_ON_ERROR
)) {
983 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG
,
984 "Odd number of characters in octetstring");
985 len
&= ~1; // make it even
988 size_t n_octets
= len
/ 2;
989 init_struct(n_octets
);
991 len
= 0; // will act as 2*i
992 for (size_t i
= 0; i
< n_octets
; ++i
, ++++len
) {
993 unsigned char upper_nibble
= char_to_hexdigit(value
[len
]);
994 unsigned char lower_nibble
= char_to_hexdigit(value
[len
+1]);
995 if (upper_nibble
> 0x0F) {
996 if (exer
&& (flavor
& EXIT_ON_ERROR
)) {
1000 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG
,
1001 "The octetstring value may contain hexadecimal digits only. "
1002 "Character \"%c\" was found.", value
[len
]);
1006 if (lower_nibble
> 0x0F) {
1007 if (exer
&& (flavor
& EXIT_ON_ERROR
)) {
1011 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG
,
1012 "The octetstring value may contain hexadecimal digits only. "
1013 "Character \"%c\" was found.", value
[len
+1]);
1017 val_ptr
->octets_ptr
[i
] = (upper_nibble
<< 4) | lower_nibble
;
1022 if (exer
&& (p_td
.xer_bits
& XER_ATTRIBUTE
)) {
1023 // Let the caller do reader.AdvanceAttribute();
1026 if (own_tag
) for (success
= reader
.Read(); success
== 1; success
= reader
.Read()) {
1027 type
= reader
.NodeType();
1028 if (XML_READER_TYPE_END_ELEMENT
== type
) {
1029 verify_end(reader
, p_td
, depth
, exer
);
1030 if (val_ptr
== 0 && p_td
.dfeValue
!= 0) {
1031 // The end tag must have followed the start tag
1032 *this = *static_cast<const OCTETSTRING
*>(p_td
.dfeValue
);
1034 reader
.Read(); // one last time
1039 return 1; // decode successful
1042 int OCTETSTRING::TEXT_encode(const TTCN_Typedescriptor_t
& p_td
,
1043 TTCN_Buffer
& buff
) const{
1044 int encoded_length
=0;
1045 if(p_td
.text
->begin_encode
){
1046 buff
.put_cs(*p_td
.text
->begin_encode
);
1047 encoded_length
+=p_td
.text
->begin_encode
->lengthof();
1050 TTCN_EncDec_ErrorContext::error
1051 (TTCN_EncDec::ET_UNBOUND
, "Encoding an unbound value.");
1052 if(p_td
.text
->end_encode
){
1053 buff
.put_cs(*p_td
.text
->end_encode
);
1054 encoded_length
+=p_td
.text
->end_encode
->lengthof();
1056 return encoded_length
;
1061 if(p_td
.text
->val
.parameters
){
1062 if(val_ptr
->n_octets
<p_td
.text
->val
.parameters
->coding_params
.min_length
){
1063 chars_before
=(p_td
.text
->
1064 val
.parameters
->coding_params
.min_length
-val_ptr
->n_octets
)*2;
1069 unsigned char* p
=NULL
;
1070 size_t len
=chars_before
;
1071 buff
.get_end(p
,len
);
1072 for(int a
=0;a
<chars_before
;a
++) p
[a
]=(unsigned char)'0';
1073 buff
.increase_length(chars_before
);
1074 encoded_length
+=chars_before
;
1077 if(val_ptr
->n_octets
){
1078 unsigned char* p
=NULL
;
1079 size_t len
=val_ptr
->n_octets
*2;
1080 buff
.get_end(p
,len
);
1081 len
=val_ptr
->n_octets
;
1082 for(size_t i
=0;i
<len
;i
++){
1083 p
[2 * i
] = hexdigit_to_char(val_ptr
->octets_ptr
[i
] >> 4);
1084 p
[2 * i
+ 1] = hexdigit_to_char(val_ptr
->octets_ptr
[i
] & 0x0F);
1086 buff
.increase_length(len
*2);
1087 encoded_length
+=len
*2;
1091 if(p_td
.text
->end_encode
){
1092 buff
.put_cs(*p_td
.text
->end_encode
);
1093 encoded_length
+=p_td
.text
->end_encode
->lengthof();
1095 return encoded_length
;
1098 int OCTETSTRING::RAW_encode(const TTCN_Typedescriptor_t
& p_td
,
1099 RAW_enc_tree
& myleaf
) const
1102 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND
,
1103 "Encoding an unbound value.");
1106 int bl
= val_ptr
->n_octets
* 8;
1107 int align_length
= p_td
.raw
->fieldlength
? p_td
.raw
->fieldlength
- bl
: 0;
1108 int blength
= val_ptr
->n_octets
;
1109 if ((bl
+ align_length
) < val_ptr
->n_octets
* 8) {
1110 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_LEN_ERR
,
1111 "There are insufficient bits to encode '%s': ", p_td
.name
);
1112 blength
= p_td
.raw
->fieldlength
/ 8;
1113 bl
= p_td
.raw
->fieldlength
;
1116 if (myleaf
.must_free
) Free(myleaf
.body
.leaf
.data_ptr
);
1117 myleaf
.must_free
= false;
1118 myleaf
.data_ptr_used
= true;
1119 if (p_td
.raw
->extension_bit
!= EXT_BIT_NO
1120 && myleaf
.coding_par
.bitorder
== ORDER_MSB
) {
1121 if (blength
> RAW_INT_ENC_LENGTH
) {
1122 myleaf
.body
.leaf
.data_ptr
= bc
= (unsigned char*)Malloc(blength
*sizeof(*bc
));
1123 myleaf
.must_free
= true;
1124 myleaf
.data_ptr_used
= true;
1127 bc
= myleaf
.body
.leaf
.data_array
;
1128 myleaf
.data_ptr_used
= false;
1130 for (int a
= 0; a
< blength
; a
++) bc
[a
] = val_ptr
->octets_ptr
[a
] << 1;
1132 else myleaf
.body
.leaf
.data_ptr
= val_ptr
->octets_ptr
;
1133 if (p_td
.raw
->endianness
== ORDER_MSB
) myleaf
.align
= -align_length
;
1134 else myleaf
.align
= align_length
;
1135 return myleaf
.length
= bl
+ align_length
;
1138 int OCTETSTRING::RAW_decode(const TTCN_Typedescriptor_t
& p_td
,
1139 TTCN_Buffer
& buff
, int limit
, raw_order_t top_bit_ord
, boolean no_err
,
1140 int /*sel_field*/, boolean
/*first_call*/)
1142 int prepaddlength
= buff
.increase_pos_padd(p_td
.raw
->prepadding
);
1143 limit
-= prepaddlength
;
1144 int decode_length
= p_td
.raw
->fieldlength
== 0
1145 ? (limit
/ 8) * 8 : p_td
.raw
->fieldlength
;
1146 if (decode_length
> limit
|| decode_length
> (int) buff
.unread_len_bit()) {
1147 if (no_err
) return -TTCN_EncDec::ET_LEN_ERR
;
1148 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_LEN_ERR
,
1149 "There is not enough bits in the buffer to decode type %s.", p_td
.name
);
1150 decode_length
= ((limit
> (int) buff
.unread_len_bit()
1151 ? (int)buff
.unread_len_bit() : limit
) / 8) * 8;
1154 bool orders
= false;
1155 if (p_td
.raw
->bitorderinoctet
== ORDER_MSB
) orders
= true;
1156 if (p_td
.raw
->bitorderinfield
== ORDER_MSB
) orders
= !orders
;
1157 cp
.bitorder
= orders
? ORDER_MSB
: ORDER_LSB
;
1159 if (p_td
.raw
->byteorder
== ORDER_MSB
) orders
= true;
1160 if (p_td
.raw
->bitorderinfield
== ORDER_MSB
) orders
= !orders
;
1161 cp
.byteorder
= orders
? ORDER_MSB
: ORDER_LSB
;
1162 cp
.fieldorder
= p_td
.raw
->fieldorder
;
1163 cp
.hexorder
= ORDER_LSB
;
1164 if (p_td
.raw
->extension_bit
!= EXT_BIT_NO
) {
1165 const unsigned char* data
= buff
.get_read_data();
1167 int rot
= top_bit_ord
== ORDER_LSB
? 0 : 7;
1168 if (p_td
.raw
->extension_bit
== EXT_BIT_YES
) {
1169 while (((data
[count
- 1] >> rot
) & 0x01) == 0 && count
* 8 < decode_length
)
1173 while (((data
[count
- 1] >> rot
) & 0x01) == 1 && count
* 8 < decode_length
)
1176 decode_length
= count
* 8;
1179 init_struct(decode_length
/ 8);
1180 buff
.get_b((size_t) decode_length
, val_ptr
->octets_ptr
, cp
, top_bit_ord
);
1182 if (p_td
.raw
->length_restrition
!= -1) {
1183 val_ptr
->n_octets
= p_td
.raw
->length_restrition
;
1184 if (p_td
.raw
->endianness
== ORDER_MSB
) memmove(val_ptr
->octets_ptr
,
1185 val_ptr
->octets_ptr
+ (decode_length
/ 8 - val_ptr
->n_octets
),
1186 val_ptr
->n_octets
* sizeof(unsigned char));
1188 if (p_td
.raw
->extension_bit
!= EXT_BIT_NO
&& cp
.bitorder
== ORDER_MSB
) {
1189 for (int a
= 0; a
< decode_length
/ 8; a
++)
1190 val_ptr
->octets_ptr
[a
] = val_ptr
->octets_ptr
[a
] >> 1 | val_ptr
->octets_ptr
[a
] << 7;
1192 decode_length
+= buff
.increase_pos_padd(p_td
.raw
->padding
);
1193 return decode_length
+ prepaddlength
;
1196 void OCTETSTRING::dump () const
1198 if (val_ptr
!= NULL
) {
1199 printf("octetstring(%d) :\n", val_ptr
->n_octets
);
1200 for (int i
= 0; i
< val_ptr
->n_octets
; i
++) {
1201 printf("%02X ", val_ptr
->octets_ptr
[i
]);
1207 int OCTETSTRING::JSON_encode(const TTCN_Typedescriptor_t
&, JSON_Tokenizer
& p_tok
) const
1210 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND
,
1211 "Encoding an unbound octetstring value.");
1215 char* tmp_str
= (char*)Malloc(val_ptr
->n_octets
* 2 + 3);
1217 tmp_str
[val_ptr
->n_octets
* 2 + 1] = '\"';
1218 for(int i
= 0; i
< val_ptr
->n_octets
; ++i
) {
1219 tmp_str
[2 * i
+ 1] = hexdigit_to_char(val_ptr
->octets_ptr
[i
] >> 4);
1220 tmp_str
[2 * i
+ 2] = hexdigit_to_char(val_ptr
->octets_ptr
[i
] & 0x0F);
1222 tmp_str
[val_ptr
->n_octets
* 2 + 2] = 0;
1223 int enc_len
= p_tok
.put_next_token(JSON_TOKEN_STRING
, tmp_str
);
1228 int OCTETSTRING::JSON_decode(const TTCN_Typedescriptor_t
& p_td
, JSON_Tokenizer
& p_tok
, boolean p_silent
)
1230 json_token_t token
= JSON_TOKEN_NONE
;
1232 size_t value_len
= 0;
1233 boolean error
= false;
1235 boolean use_default
= p_td
.json
->default_value
&& 0 == p_tok
.get_buffer_length();
1237 // No JSON data in the buffer -> use default value
1238 value
= (char*)p_td
.json
->default_value
;
1239 value_len
= strlen(value
);
1241 dec_len
= p_tok
.get_next_token(&token
, &value
, &value_len
);
1243 if (JSON_TOKEN_ERROR
== token
) {
1244 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG
, JSON_DEC_BAD_TOKEN_ERROR
, "");
1245 return JSON_ERROR_FATAL
;
1247 else if (JSON_TOKEN_STRING
== token
|| use_default
) {
1248 if (0 == value_len
% 2 && (use_default
||
1249 (value_len
> 2 && value
[0] == '\"' && value
[value_len
- 1] == '\"'))) {
1251 // The default value doesn't have quotes around it
1255 size_t octets
= value_len
/ 2;
1256 init_struct(octets
);
1257 for (size_t i
= 0; i
< octets
; ++i
) {
1258 unsigned char upper_nibble
= char_to_hexdigit(value
[2 * i
]);
1259 unsigned char lower_nibble
= char_to_hexdigit(value
[2 * i
+ 1]);
1260 if (upper_nibble
<= 0x0F && lower_nibble
<= 0x0F) {
1261 val_ptr
->octets_ptr
[i
] = (upper_nibble
<< 4) | lower_nibble
;
1270 return JSON_ERROR_INVALID_TOKEN
;
1274 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG
, JSON_DEC_FORMAT_ERROR
, "string", "octetstring");
1278 return JSON_ERROR_FATAL
;
1283 // octetstring element class
1285 OCTETSTRING_ELEMENT::OCTETSTRING_ELEMENT(boolean par_bound_flag
,
1286 OCTETSTRING
& par_str_val
, int par_octet_pos
)
1287 : bound_flag(par_bound_flag
), str_val(par_str_val
), octet_pos(par_octet_pos
)
1291 OCTETSTRING_ELEMENT
& OCTETSTRING_ELEMENT::operator=
1292 (const OCTETSTRING
& other_value
)
1294 other_value
.must_bound("Assignment of an unbound octetstring value.");
1295 if(other_value
.val_ptr
->n_octets
!= 1)
1296 TTCN_error("Assignment of an octetstring "
1297 "with length other than 1 to an octetstring element.");
1299 str_val
.copy_value();
1300 str_val
.val_ptr
->octets_ptr
[octet_pos
] = other_value
.val_ptr
->octets_ptr
[0];
1304 OCTETSTRING_ELEMENT
& OCTETSTRING_ELEMENT::operator=
1305 (const OCTETSTRING_ELEMENT
& other_value
)
1307 other_value
.must_bound("Assignment of an unbound octetstring element.");
1308 if (&other_value
!= this) {
1310 str_val
.copy_value();
1311 str_val
.val_ptr
->octets_ptr
[octet_pos
] =
1312 other_value
.str_val
.val_ptr
->octets_ptr
[other_value
.octet_pos
];
1317 boolean
OCTETSTRING_ELEMENT::operator==(const OCTETSTRING
& other_value
) const
1319 must_bound("Unbound left operand of octetstring element comparison.");
1320 other_value
.must_bound("Unbound right operand of octetstring comparison.");
1321 if(other_value
.val_ptr
->n_octets
!= 1) return FALSE
;
1322 return str_val
.val_ptr
->octets_ptr
[octet_pos
] ==
1323 other_value
.val_ptr
->octets_ptr
[0];
1326 boolean
OCTETSTRING_ELEMENT::operator==
1327 (const OCTETSTRING_ELEMENT
& other_value
) const
1329 must_bound("Unbound left operand of octetstring element comparison.");
1330 other_value
.must_bound("Unbound right operand of octetstring element "
1332 return str_val
.val_ptr
->octets_ptr
[octet_pos
] ==
1333 other_value
.str_val
.val_ptr
->octets_ptr
[other_value
.octet_pos
];
1336 OCTETSTRING
OCTETSTRING_ELEMENT::operator+(const OCTETSTRING
& other_value
) const
1338 must_bound("Unbound left operand of octetstring element concatenation.");
1339 other_value
.must_bound("Unbound right operand of octetstring concatenation.");
1340 OCTETSTRING
ret_val(other_value
.val_ptr
->n_octets
+ 1);
1341 ret_val
.val_ptr
->octets_ptr
[0] = str_val
.val_ptr
->octets_ptr
[octet_pos
];
1342 memcpy(ret_val
.val_ptr
->octets_ptr
+ 1,
1343 other_value
.val_ptr
->octets_ptr
, other_value
.val_ptr
->n_octets
);
1347 OCTETSTRING
OCTETSTRING_ELEMENT::operator+
1348 (const OCTETSTRING_ELEMENT
& other_value
) const
1350 must_bound("Unbound left operand of octetstring element concatenation.");
1351 other_value
.must_bound("Unbound right operand of octetstring element "
1353 unsigned char result
[2];
1354 result
[0] = str_val
.val_ptr
->octets_ptr
[octet_pos
];
1355 result
[1] = other_value
.str_val
.val_ptr
->octets_ptr
[other_value
.octet_pos
];
1356 return OCTETSTRING(2, result
);
1359 OCTETSTRING
OCTETSTRING_ELEMENT::operator~() const
1361 must_bound("Unbound octetstring element operand of operator not4b.");
1362 unsigned char result
= ~str_val
.val_ptr
->octets_ptr
[octet_pos
];
1363 return OCTETSTRING(1, &result
);
1366 OCTETSTRING
OCTETSTRING_ELEMENT::operator&(const OCTETSTRING
& other_value
) const
1368 must_bound("Left operand of operator and4b is an unbound octetstring "
1370 other_value
.must_bound("Right operand of operator and4b is an unbound "
1371 "octetstring value.");
1372 if (other_value
.val_ptr
->n_octets
!= 1)
1373 TTCN_error("The octetstring "
1374 "operands of operator and4b must have the same length.");
1375 unsigned char result
= str_val
.val_ptr
->octets_ptr
[octet_pos
] &
1376 other_value
.val_ptr
->octets_ptr
[0];
1377 return OCTETSTRING(1, &result
);
1380 OCTETSTRING
OCTETSTRING_ELEMENT::operator&
1381 (const OCTETSTRING_ELEMENT
& other_value
) const
1383 must_bound("Left operand of operator and4b is an unbound octetstring "
1385 other_value
.must_bound("Right operand of operator and4b is an unbound "
1386 "octetstring element.");
1387 unsigned char result
= str_val
.val_ptr
->octets_ptr
[octet_pos
] &
1388 other_value
.str_val
.val_ptr
->octets_ptr
[other_value
.octet_pos
];
1389 return OCTETSTRING(1, &result
);
1392 OCTETSTRING
OCTETSTRING_ELEMENT::operator|(const OCTETSTRING
& other_value
) const
1394 must_bound("Left operand of operator or4b is an unbound octetstring "
1396 other_value
.must_bound("Right operand of operator or4b is an unbound "
1397 "octetstring value.");
1398 if (other_value
.val_ptr
->n_octets
!= 1)
1399 TTCN_error("The octetstring "
1400 "operands of operator or4b must have the same length.");
1401 unsigned char result
= str_val
.val_ptr
->octets_ptr
[octet_pos
] |
1402 other_value
.val_ptr
->octets_ptr
[0];
1403 return OCTETSTRING(1, &result
);
1406 OCTETSTRING
OCTETSTRING_ELEMENT::operator|
1407 (const OCTETSTRING_ELEMENT
& other_value
) const
1409 must_bound("Left operand of operator or4b is an unbound octetstring "
1411 other_value
.must_bound("Right operand of operator or4b is an unbound "
1412 "octetstring element.");
1413 unsigned char result
= str_val
.val_ptr
->octets_ptr
[octet_pos
] |
1414 other_value
.str_val
.val_ptr
->octets_ptr
[other_value
.octet_pos
];
1415 return OCTETSTRING(1, &result
);
1418 OCTETSTRING
OCTETSTRING_ELEMENT::operator^(const OCTETSTRING
& other_value
) const
1420 must_bound("Left operand of operator xor4b is an unbound octetstring "
1422 other_value
.must_bound("Right operand of operator xor4b is an unbound "
1423 "octetstring value.");
1424 if (other_value
.val_ptr
->n_octets
!= 1)
1425 TTCN_error("The octetstring "
1426 "operands of operator xor4b must have the same length.");
1427 unsigned char result
= str_val
.val_ptr
->octets_ptr
[octet_pos
] ^
1428 other_value
.val_ptr
->octets_ptr
[0];
1429 return OCTETSTRING(1, &result
);
1432 OCTETSTRING
OCTETSTRING_ELEMENT::operator^
1433 (const OCTETSTRING_ELEMENT
& other_value
) const
1435 must_bound("Left operand of operator xor4b is an unbound octetstring "
1437 other_value
.must_bound("Right operand of operator xor4b is an unbound "
1438 "octetstring element.");
1439 unsigned char result
= str_val
.val_ptr
->octets_ptr
[octet_pos
] ^
1440 other_value
.str_val
.val_ptr
->octets_ptr
[other_value
.octet_pos
];
1441 return OCTETSTRING(1, &result
);
1444 unsigned char OCTETSTRING_ELEMENT::get_octet() const
1446 return str_val
.val_ptr
->octets_ptr
[octet_pos
];
1449 void OCTETSTRING_ELEMENT::log() const
1452 unsigned char octet
= str_val
.val_ptr
->octets_ptr
[octet_pos
];
1453 TTCN_Logger::log_char('\'');
1454 TTCN_Logger::log_octet(octet
);
1455 TTCN_Logger::log_event_str("'O");
1456 if (TTCN_Logger::is_printable(octet
)) {
1457 TTCN_Logger::log_event_str(" (\"");
1458 TTCN_Logger::log_char_escaped(octet
);
1459 TTCN_Logger::log_event_str("\")");
1461 } else TTCN_Logger::log_event_unbound();
1464 // octetstring template class
1466 void OCTETSTRING_template::clean_up()
1468 switch (template_selection
) {
1470 case COMPLEMENTED_LIST
:
1471 delete [] value_list
.list_value
;
1473 case STRING_PATTERN
:
1474 if (pattern_value
->ref_count
> 1) pattern_value
->ref_count
--;
1475 else if (pattern_value
->ref_count
== 1) Free(pattern_value
);
1476 else TTCN_error("Internal error: Invalid reference counter in an "
1477 "octetstring pattern.");
1482 template_selection
= UNINITIALIZED_TEMPLATE
;
1485 void OCTETSTRING_template::copy_template
1486 (const OCTETSTRING_template
& other_value
)
1488 switch (other_value
.template_selection
) {
1489 case SPECIFIC_VALUE
:
1490 single_value
= other_value
.single_value
;
1497 case COMPLEMENTED_LIST
:
1498 value_list
.n_values
= other_value
.value_list
.n_values
;
1499 value_list
.list_value
= new OCTETSTRING_template
[value_list
.n_values
];
1500 for (unsigned int i
= 0; i
< value_list
.n_values
; i
++)
1501 value_list
.list_value
[i
].copy_template(
1502 other_value
.value_list
.list_value
[i
]);
1504 case STRING_PATTERN
:
1505 pattern_value
= other_value
.pattern_value
;
1506 pattern_value
->ref_count
++;
1509 TTCN_error("Copying an uninitialized/unsupported octetstring template.");
1511 set_selection(other_value
);
1515 This is the same algorithm that match_array uses
1516 to match 'record of' types.
1517 The only differences are: how two elements are matched and
1518 how an asterisk or ? is identified in the template
1520 boolean
OCTETSTRING_template::match_pattern(
1521 const octetstring_pattern_struct
*string_pattern
,
1522 const OCTETSTRING::octetstring_struct
*string_value
)
1524 // the empty pattern matches the empty octetstring only
1525 if (string_pattern
->n_elements
== 0) return string_value
->n_octets
== 0;
1527 int value_index
= 0;
1528 unsigned int template_index
= 0;
1529 int last_asterisk
= -1;
1530 int last_value_to_asterisk
= -1;
1531 //this variable is used to speed up the function
1532 unsigned short pattern_element
;
1536 pattern_element
= string_pattern
->elements_ptr
[template_index
];
1537 if( pattern_element
< 256){
1538 if(string_value
->octets_ptr
[value_index
] == pattern_element
)
1543 if(last_asterisk
== -1) return FALSE
;
1544 template_index
= last_asterisk
+1;
1545 value_index
= ++last_value_to_asterisk
;
1547 } else if(pattern_element
== 256)
1551 }else if(pattern_element
== 257)
1553 last_asterisk
= template_index
++;
1554 last_value_to_asterisk
= value_index
;
1555 } else TTCN_error("Internal error: invalid element in an octetstring "
1558 if(value_index
== string_value
->n_octets
1559 && template_index
== string_pattern
->n_elements
)
1562 }else if (template_index
== string_pattern
->n_elements
)
1564 if(string_pattern
->elements_ptr
[template_index
- 1] == 257)
1567 }else if(last_asterisk
== -1)
1571 template_index
= last_asterisk
+1;
1572 value_index
= ++last_value_to_asterisk
;
1574 }else if(value_index
== string_value
->n_octets
)
1576 while(template_index
< string_pattern
->n_elements
1577 && string_pattern
->elements_ptr
[template_index
] == 257)
1580 return template_index
== string_pattern
->n_elements
;
1585 OCTETSTRING_template::OCTETSTRING_template()
1589 OCTETSTRING_template::OCTETSTRING_template(template_sel other_value
)
1590 : Restricted_Length_Template(other_value
)
1592 check_single_selection(other_value
);
1595 OCTETSTRING_template::OCTETSTRING_template(const OCTETSTRING
& other_value
)
1596 : Restricted_Length_Template(SPECIFIC_VALUE
), single_value(other_value
)
1600 OCTETSTRING_template::OCTETSTRING_template
1601 (const OCTETSTRING_ELEMENT
& other_value
)
1602 : Restricted_Length_Template(SPECIFIC_VALUE
), single_value(other_value
)
1606 OCTETSTRING_template::OCTETSTRING_template
1607 (const OPTIONAL
<OCTETSTRING
>& other_value
)
1609 switch (other_value
.get_selection()) {
1610 case OPTIONAL_PRESENT
:
1611 set_selection(SPECIFIC_VALUE
);
1612 single_value
= (const OCTETSTRING
&)other_value
;
1615 set_selection(OMIT_VALUE
);
1618 TTCN_error("Creating an octetstring template from an unbound optional "
1623 OCTETSTRING_template::OCTETSTRING_template(unsigned int n_elements
,
1624 const unsigned short *pattern_elements
)
1625 : Restricted_Length_Template(STRING_PATTERN
)
1627 pattern_value
= (octetstring_pattern_struct
*)
1628 Malloc(sizeof(octetstring_pattern_struct
) +
1629 (n_elements
- 1) * sizeof(unsigned short));
1630 pattern_value
->ref_count
= 1;
1631 pattern_value
->n_elements
= n_elements
;
1632 memcpy(pattern_value
->elements_ptr
, pattern_elements
,
1633 n_elements
* sizeof(unsigned short));
1636 OCTETSTRING_template::OCTETSTRING_template
1637 (const OCTETSTRING_template
& other_value
)
1638 : Restricted_Length_Template()
1640 copy_template(other_value
);
1643 OCTETSTRING_template::~OCTETSTRING_template()
1648 OCTETSTRING_template
& OCTETSTRING_template::operator=(template_sel other_value
)
1650 check_single_selection(other_value
);
1652 set_selection(other_value
);
1656 OCTETSTRING_template
& OCTETSTRING_template::operator=
1657 (const OCTETSTRING
& other_value
)
1659 other_value
.must_bound("Assignment of an unbound octetstring value to a "
1662 set_selection(SPECIFIC_VALUE
);
1663 single_value
= other_value
;
1667 OCTETSTRING_template
& OCTETSTRING_template::operator=
1668 (const OCTETSTRING_ELEMENT
& other_value
)
1670 other_value
.must_bound("Assignment of an unbound octetstring element to a "
1673 set_selection(SPECIFIC_VALUE
);
1674 single_value
= other_value
;
1678 OCTETSTRING_template
& OCTETSTRING_template::operator=
1679 (const OPTIONAL
<OCTETSTRING
>& other_value
)
1682 switch (other_value
.get_selection()) {
1683 case OPTIONAL_PRESENT
:
1684 set_selection(SPECIFIC_VALUE
);
1685 single_value
= (const OCTETSTRING
&)other_value
;
1688 set_selection(OMIT_VALUE
);
1691 TTCN_error("Assignment of an unbound optional field to an octetstring "
1697 OCTETSTRING_template
& OCTETSTRING_template::operator=
1698 (const OCTETSTRING_template
& other_value
)
1700 if (&other_value
!= this) {
1702 copy_template(other_value
);
1707 OCTETSTRING_ELEMENT
OCTETSTRING_template::operator[](int index_value
)
1709 if (template_selection
!= SPECIFIC_VALUE
|| is_ifpresent
)
1710 TTCN_error("Accessing an octetstring element of a non-specific "
1711 "octetstring template.");
1712 return single_value
[index_value
];
1715 OCTETSTRING_ELEMENT
OCTETSTRING_template::operator[](const INTEGER
& index_value
)
1717 index_value
.must_bound("Indexing a octetstring value with an unbound "
1719 return (*this)[(int)index_value
];
1722 const OCTETSTRING_ELEMENT
OCTETSTRING_template::operator[](int index_value
) const
1724 if (template_selection
!= SPECIFIC_VALUE
|| is_ifpresent
)
1725 TTCN_error("Accessing an octetstring element of a non-specific "
1726 "octetstring template.");
1727 return single_value
[index_value
];
1730 const OCTETSTRING_ELEMENT
OCTETSTRING_template::operator[](const INTEGER
& index_value
) const
1732 index_value
.must_bound("Indexing a octetstring template with an unbound "
1734 return (*this)[(int)index_value
];
1737 boolean
OCTETSTRING_template::match(const OCTETSTRING
& other_value
) const
1739 if (!other_value
.is_bound()) return FALSE
;
1740 if (!match_length(other_value
.val_ptr
->n_octets
)) return FALSE
;
1741 switch (template_selection
) {
1742 case SPECIFIC_VALUE
:
1743 return single_value
== other_value
;
1750 case COMPLEMENTED_LIST
:
1751 for(unsigned int i
= 0; i
< value_list
.n_values
; i
++)
1752 if (value_list
.list_value
[i
].match(other_value
))
1753 return template_selection
== VALUE_LIST
;
1754 return template_selection
== COMPLEMENTED_LIST
;
1755 case STRING_PATTERN
:
1756 return match_pattern(pattern_value
, other_value
.val_ptr
);
1758 TTCN_error("Matching an uninitialized/unsupported octetstring template.");
1763 const OCTETSTRING
& OCTETSTRING_template::valueof() const
1765 if (template_selection
!= SPECIFIC_VALUE
|| is_ifpresent
)
1766 TTCN_error("Performing a valueof or send operation on a non-specific "
1767 "octetstring template.");
1768 return single_value
;
1771 int OCTETSTRING_template::lengthof() const
1774 boolean has_any_or_none
;
1776 TTCN_error("Performing lengthof() operation on a octetstring template "
1777 "which has an ifpresent attribute.");
1778 switch (template_selection
)
1780 case SPECIFIC_VALUE
:
1781 min_length
= single_value
.lengthof();
1782 has_any_or_none
= FALSE
;
1785 TTCN_error("Performing lengthof() operation on an octetstring template "
1786 "containing omit value.");
1790 has_any_or_none
= TRUE
; // max. length is infinity
1794 // error if any element does not have length or the lengths differ
1795 if (value_list
.n_values
<1)
1796 TTCN_error("Internal error: "
1797 "Performing lengthof() operation on an octetstring template "
1798 "containing an empty list.");
1799 int item_length
= value_list
.list_value
[0].lengthof();
1800 for (unsigned int i
= 1; i
< value_list
.n_values
; i
++) {
1801 if (value_list
.list_value
[i
].lengthof()!=item_length
)
1802 TTCN_error("Performing lengthof() operation on an octetstring template "
1803 "containing a value list with different lengths.");
1805 min_length
= item_length
;
1806 has_any_or_none
= FALSE
;
1809 case COMPLEMENTED_LIST
:
1810 TTCN_error("Performing lengthof() operation on an octetstring template "
1811 "containing complemented list.");
1812 case STRING_PATTERN
:
1814 has_any_or_none
= FALSE
; // TRUE if * chars in the pattern
1815 for (unsigned int i
= 0; i
< pattern_value
->n_elements
; i
++)
1817 if (pattern_value
->elements_ptr
[i
] < 257) min_length
++;
1818 else has_any_or_none
= TRUE
; // case of * character
1822 TTCN_error("Performing lengthof() operation on an "
1823 "uninitialized/unsupported octetstring template.");
1825 return check_section_is_single(min_length
, has_any_or_none
,
1826 "length", "an", "octetstring template");
1829 void OCTETSTRING_template::set_type(template_sel template_type
,
1830 unsigned int list_length
)
1832 if (template_type
!= VALUE_LIST
&& template_type
!= COMPLEMENTED_LIST
)
1833 TTCN_error("Setting an invalid list type for an octetstring template.");
1835 set_selection(template_type
);
1836 value_list
.n_values
= list_length
;
1837 value_list
.list_value
= new OCTETSTRING_template
[list_length
];
1840 OCTETSTRING_template
& OCTETSTRING_template::list_item(unsigned int list_index
)
1842 if (template_selection
!= VALUE_LIST
&&
1843 template_selection
!= COMPLEMENTED_LIST
)
1844 TTCN_error("Accessing a list element of a non-list octetstring template.");
1845 if (list_index
>= value_list
.n_values
)
1846 TTCN_error("Index overflow in an octetstring value list template.");
1847 return value_list
.list_value
[list_index
];
1850 void OCTETSTRING_template::log() const
1852 switch (template_selection
) {
1853 case SPECIFIC_VALUE
:
1856 case COMPLEMENTED_LIST
:
1857 TTCN_Logger::log_event_str("complement ");
1860 TTCN_Logger::log_char('(');
1861 for(unsigned int i
= 0; i
< value_list
.n_values
; i
++) {
1862 if (i
> 0) TTCN_Logger::log_event_str(", ");
1863 value_list
.list_value
[i
].log();
1865 TTCN_Logger::log_char(')');
1867 case STRING_PATTERN
:
1868 TTCN_Logger::log_char('\'');
1869 for (unsigned int i
= 0; i
< pattern_value
->n_elements
; i
++) {
1870 unsigned short pattern
= pattern_value
->elements_ptr
[i
];
1871 if (pattern
< 256) TTCN_Logger::log_octet(pattern
);
1872 else if (pattern
== 256) TTCN_Logger::log_char('?');
1873 else if (pattern
== 257) TTCN_Logger::log_char('*');
1874 else TTCN_Logger::log_event_str("<unknown>");
1876 TTCN_Logger::log_event_str("'O");
1886 void OCTETSTRING_template::log_match(const OCTETSTRING
& match_value
) const
1888 if (TTCN_Logger::VERBOSITY_COMPACT
== TTCN_Logger::get_matching_verbosity()
1889 && TTCN_Logger::get_logmatch_buffer_len() != 0) {
1890 TTCN_Logger::print_logmatch_buffer();
1891 TTCN_Logger::log_event_str(" := ");
1894 TTCN_Logger::log_event_str(" with ");
1896 if (match(match_value
)) TTCN_Logger::log_event_str(" matched");
1897 else TTCN_Logger::log_event_str(" unmatched");
1900 void OCTETSTRING_template::set_param(Module_Param
& param
) {
1901 param
.basic_check(Module_Param::BC_TEMPLATE
|Module_Param::BC_LIST
, "octetstring template");
1902 switch (param
.get_type()) {
1903 case Module_Param::MP_Omit
:
1906 case Module_Param::MP_Any
:
1909 case Module_Param::MP_AnyOrNone
:
1910 *this = ANY_OR_OMIT
;
1912 case Module_Param::MP_List_Template
:
1913 case Module_Param::MP_ComplementList_Template
:
1914 set_type(param
.get_type()==Module_Param::MP_List_Template
? VALUE_LIST
: COMPLEMENTED_LIST
, param
.get_size());
1915 for (size_t i
=0; i
<param
.get_size(); i
++) {
1916 list_item(i
).set_param(*param
.get_elem(i
));
1919 case Module_Param::MP_Octetstring
:
1920 *this = OCTETSTRING(param
.get_string_size(), (unsigned char*)param
.get_string_data());
1922 case Module_Param::MP_Octetstring_Template
:
1923 *this = OCTETSTRING_template(param
.get_string_size(), (unsigned short*)param
.get_string_data());
1926 param
.type_error("octetstring template");
1928 is_ifpresent
= param
.get_ifpresent();
1929 set_length_range(param
);
1932 void OCTETSTRING_template::encode_text(Text_Buf
& text_buf
) const
1934 encode_text_restricted(text_buf
);
1935 switch (template_selection
) {
1940 case SPECIFIC_VALUE
:
1941 single_value
.encode_text(text_buf
);
1944 case COMPLEMENTED_LIST
:
1945 text_buf
.push_int(value_list
.n_values
);
1946 for (unsigned int i
= 0; i
< value_list
.n_values
; i
++)
1947 value_list
.list_value
[i
].encode_text(text_buf
);
1949 case STRING_PATTERN
:
1950 text_buf
.push_int(pattern_value
->n_elements
);
1951 for (unsigned int i
= 0; i
< pattern_value
->n_elements
; i
++)
1952 text_buf
.push_int(pattern_value
->elements_ptr
[i
]);
1955 TTCN_error("Text encoder: Encoding an uninitialized/unsupported "
1956 "octetstring template.");
1960 void OCTETSTRING_template::decode_text(Text_Buf
& text_buf
)
1963 decode_text_restricted(text_buf
);
1964 switch (template_selection
) {
1969 case SPECIFIC_VALUE
:
1970 single_value
.decode_text(text_buf
);
1973 case COMPLEMENTED_LIST
:
1974 value_list
.n_values
= text_buf
.pull_int().get_val();
1975 value_list
.list_value
= new OCTETSTRING_template
[value_list
.n_values
];
1976 for (unsigned int i
= 0; i
< value_list
.n_values
; i
++)
1977 value_list
.list_value
[i
].decode_text(text_buf
);
1979 case STRING_PATTERN
: {
1980 unsigned int n_elements
= text_buf
.pull_int().get_val();
1981 pattern_value
= (octetstring_pattern_struct
*)
1982 Malloc(sizeof(octetstring_pattern_struct
) + (n_elements
- 1) *
1983 sizeof(unsigned short));
1984 pattern_value
->ref_count
= 1;
1985 pattern_value
->n_elements
= n_elements
;
1986 for (unsigned int i
= 0; i
< n_elements
; i
++)
1987 pattern_value
->elements_ptr
[i
] = text_buf
.pull_int().get_val();
1990 TTCN_error("Text decoder: An unknown/unsupported selection was "
1991 "received for an octetstring template.");
1995 boolean
OCTETSTRING_template::is_present() const
1997 if (template_selection
==UNINITIALIZED_TEMPLATE
) return FALSE
;
1998 return !match_omit();
2001 boolean
OCTETSTRING_template::match_omit() const
2003 if (is_ifpresent
) return TRUE
;
2004 switch (template_selection
) {
2009 case COMPLEMENTED_LIST
:
2010 for (unsigned int i
=0; i
<value_list
.n_values
; i
++)
2011 if (value_list
.list_value
[i
].match_omit())
2012 return template_selection
==VALUE_LIST
;
2013 return template_selection
==COMPLEMENTED_LIST
;
2020 #ifndef TITAN_RUNTIME_2
2021 void OCTETSTRING_template::check_restriction(template_res t_res
, const char* t_name
) const
2023 if (template_selection
==UNINITIALIZED_TEMPLATE
) return;
2024 switch ((t_name
&&(t_res
==TR_VALUE
))?TR_OMIT
:t_res
) {
2026 if (!is_ifpresent
&& template_selection
==SPECIFIC_VALUE
) return;
2029 if (!is_ifpresent
&& (template_selection
==OMIT_VALUE
||
2030 template_selection
==SPECIFIC_VALUE
)) return;
2033 if (!match_omit()) return;
2038 TTCN_error("Restriction `%s' on template of type %s violated.",
2039 get_res_name(t_res
), t_name
? t_name
: "octetstring");