55c0090fb24b1a81807c537b9f8f6d97344116a9
[deliverable/titan.core.git] / core / Octetstring.cc
1 ///////////////////////////////////////////////////////////////////////////////
2 // Copyright (c) 2000-2015 Ericsson Telecom AB
3 // All rights reserved. This program and the accompanying materials
4 // are made available under the terms of the Eclipse Public License v1.0
5 // which accompanies this distribution, and is available at
6 // http://www.eclipse.org/legal/epl-v10.html
7 ///////////////////////////////////////////////////////////////////////////////
8 #include "Octetstring.hh"
9 #include "../common/memory.h"
10 #include "Integer.hh"
11 #include "String_struct.hh"
12 #include "Param_Types.hh"
13 #include "Error.hh"
14 #include "Logger.hh"
15 #include "Encdec.hh"
16 #include "RAW.hh"
17 #include "BER.hh"
18 #include "TEXT.hh"
19 #include "Addfunc.hh"
20
21 #include "../common/dbgnew.hh"
22 #include <string.h>
23
24 // octetstring value class
25
26 /** The amount of memory needed for a string containing n octets. */
27 #define MEMORY_SIZE(n) (sizeof(octetstring_struct) - sizeof(int) + (n))
28
29 static const Token_Match
30 octetstring_value_match("^(([0-9A-Fa-f]{2})+).*$", TRUE);
31
32 void OCTETSTRING::init_struct(int n_octets)
33 {
34 if (n_octets < 0) {
35 val_ptr = NULL;
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.
40 */
41 static octetstring_struct empty_string = { 1, 0, "" };
42 val_ptr = &empty_string;
43 empty_string.ref_count++;
44 } else {
45 val_ptr = (octetstring_struct*)Malloc(MEMORY_SIZE(n_octets));
46 val_ptr->ref_count = 1;
47 val_ptr->n_octets = n_octets;
48 }
49 }
50
51 void OCTETSTRING::copy_value()
52 {
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;
58 old_ptr->ref_count--;
59 init_struct(old_ptr->n_octets);
60 memcpy(val_ptr->octets_ptr, old_ptr->octets_ptr, old_ptr->n_octets);
61 }
62 }
63
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)
68 {
69 init_struct(n_octets);
70 }
71
72 OCTETSTRING::OCTETSTRING()
73 {
74 val_ptr = NULL;
75 }
76
77 OCTETSTRING::OCTETSTRING(int n_octets, const unsigned char* octets_ptr)
78 {
79 init_struct(n_octets);
80 memcpy(val_ptr->octets_ptr, octets_ptr, n_octets);
81 }
82
83 OCTETSTRING::OCTETSTRING(const OCTETSTRING& other_value)
84 : Base_Type(other_value)
85 {
86 other_value.must_bound("Copying an unbound octetstring value.");
87 val_ptr = other_value.val_ptr;
88 val_ptr->ref_count++;
89 }
90
91 OCTETSTRING::OCTETSTRING(const OCTETSTRING_ELEMENT& other_value)
92 {
93 other_value.must_bound("Copying an unbound octetstring element.");
94 init_struct(1);
95 val_ptr->octets_ptr[0] = other_value.get_octet();
96 }
97
98 OCTETSTRING::~OCTETSTRING()
99 {
100 clean_up();
101 }
102
103 OCTETSTRING& OCTETSTRING::operator=(const OCTETSTRING& other_value)
104 {
105 other_value.must_bound("Assignment of an unbound octetstring value.");
106 if (&other_value != this) {
107 clean_up();
108 val_ptr = other_value.val_ptr;
109 val_ptr->ref_count++;
110 }
111 return *this;
112 }
113
114 OCTETSTRING& OCTETSTRING::operator=(const OCTETSTRING_ELEMENT& other_value)
115 {
116 other_value.must_bound("Assignment of an unbound octetstring element to an "
117 "octetstring.");
118 unsigned char octet_value = other_value.get_octet();
119 clean_up();
120 init_struct(1);
121 val_ptr->octets_ptr[0] = octet_value;
122 return *this;
123 }
124
125 boolean OCTETSTRING::operator==(const OCTETSTRING& other_value) const
126 {
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,
131 val_ptr->n_octets);
132 }
133
134 boolean OCTETSTRING::operator==(const OCTETSTRING_ELEMENT& other_value) const
135 {
136 must_bound("Unbound left operand of octetstring comparison.");
137 other_value.must_bound("Unbound right operand of octetstring element "
138 "comparison.");
139 if (val_ptr->n_octets != 1) return FALSE;
140 return val_ptr->octets_ptr[0] == other_value.get_octet();
141 }
142
143 OCTETSTRING OCTETSTRING::operator+(const OCTETSTRING& other_value) const
144 {
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);
155 return ret_val;
156 }
157
158 OCTETSTRING OCTETSTRING::operator+(const OCTETSTRING_ELEMENT& other_value) const
159 {
160 must_bound("Unbound left operand of octetstring concatenation.");
161 other_value.must_bound("Unbound right operand of octetstring element "
162 "concatenation.");
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();
166 return ret_val;
167 }
168
169 OCTETSTRING& OCTETSTRING::operator+=(const OCTETSTRING& other_value)
170 {
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) {
177 clean_up();
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);
187 } else {
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;
193 }
194 }
195 return *this;
196 }
197
198 OCTETSTRING& OCTETSTRING::operator+=(const OCTETSTRING_ELEMENT& other_value)
199 {
200 must_bound("Appending an octetstring element to an unbound octetstring "
201 "value.");
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();
210 } else {
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();
214 val_ptr->n_octets++;
215 }
216 return *this;
217 }
218
219 OCTETSTRING OCTETSTRING::operator~() const
220 {
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];
225 return ret_val;
226 }
227
228 OCTETSTRING OCTETSTRING::operator&(const OCTETSTRING& other_value) const
229 {
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 "
235 "same length.");
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];
240 return ret_val;
241 }
242
243 OCTETSTRING OCTETSTRING::operator&(const OCTETSTRING_ELEMENT& other_value) const
244 {
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);
253 }
254
255 OCTETSTRING OCTETSTRING::operator|(const OCTETSTRING& other_value) const
256 {
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 "
262 "same length.");
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];
267 return ret_val;
268 }
269
270 OCTETSTRING OCTETSTRING::operator|(const OCTETSTRING_ELEMENT& other_value) const
271 {
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);
280 }
281
282 OCTETSTRING OCTETSTRING::operator^(const OCTETSTRING& other_value) const
283 {
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 "
289 "same length.");
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];
294 return ret_val;
295 }
296
297 OCTETSTRING OCTETSTRING::operator^(const OCTETSTRING_ELEMENT& other_value) const
298 {
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);
307 }
308
309 OCTETSTRING OCTETSTRING::operator<<(int shift_count) const
310 {
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,
319 0, shift_count);
320 return ret_val;
321 } else if (shift_count == 0) return *this;
322 else return *this >> (-shift_count);
323 }
324
325 OCTETSTRING OCTETSTRING::operator<<(const INTEGER& shift_count) const
326 {
327 shift_count.must_bound("Unbound right operand of octetstring shift left "
328 "operator.");
329 return *this << (int)shift_count;
330 }
331
332 OCTETSTRING OCTETSTRING::operator>>(int shift_count) const
333 {
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);
342 return ret_val;
343 } else if (shift_count == 0) return *this;
344 else return *this << (-shift_count);
345 }
346
347 OCTETSTRING OCTETSTRING::operator>>(const INTEGER& shift_count) const
348 {
349 shift_count.must_bound("Unbound right operand of octetstring shift right "
350 "operator.");
351 return *this >> (int)shift_count;
352 }
353
354 OCTETSTRING OCTETSTRING::operator<<=(int rotate_count) const
355 {
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);
366 return ret_val;
367 } else return *this >>= (-rotate_count);
368 }
369
370 OCTETSTRING OCTETSTRING::operator<<=(const INTEGER& rotate_count) const
371 {
372 rotate_count.must_bound("Unbound right operand of octetstring rotate left "
373 "operator.");
374 return *this <<= (int)rotate_count;
375 }
376
377 OCTETSTRING OCTETSTRING::operator>>=(int rotate_count) const
378 {
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);
389 return ret_val;
390 } else return *this <<= (-rotate_count);
391 }
392
393 OCTETSTRING OCTETSTRING::operator>>=(const INTEGER& rotate_count) const
394 {
395 rotate_count.must_bound("Unbound right operand of octetstring rotate right "
396 "operator.");
397 return *this >>= (int)rotate_count;
398 }
399
400 OCTETSTRING_ELEMENT OCTETSTRING::operator[](int index_value)
401 {
402 if (val_ptr == NULL && index_value == 0) {
403 init_struct(1);
404 return OCTETSTRING_ELEMENT(FALSE, *this, 0);
405 } else {
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));
417 val_ptr->n_octets++;
418 } else {
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);
423 }
424 return OCTETSTRING_ELEMENT(FALSE, *this, index_value);
425 } else return OCTETSTRING_ELEMENT(TRUE, *this, index_value);
426 }
427 }
428
429 OCTETSTRING_ELEMENT OCTETSTRING::operator[](const INTEGER& index_value)
430 {
431 index_value.must_bound("Indexing a octetstring value with an unbound integer "
432 "value.");
433 return (*this)[(int)index_value];
434 }
435
436 const OCTETSTRING_ELEMENT OCTETSTRING::operator[](int index_value) const
437 {
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),
445 index_value);
446 }
447
448 const OCTETSTRING_ELEMENT OCTETSTRING::operator[](const INTEGER& index_value)
449 const
450 {
451 index_value.must_bound("Indexing a octetstring value with an unbound integer "
452 "value.");
453 return (*this)[(int)index_value];
454 }
455
456 void OCTETSTRING::clean_up()
457 {
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.");
463 val_ptr = NULL;
464 }
465 }
466
467 int OCTETSTRING::lengthof() const
468 {
469 must_bound("Getting the length of an unbound octetstring value.");
470 return val_ptr->n_octets;
471 }
472
473 OCTETSTRING::operator const unsigned char*() const
474 {
475 must_bound("Casting an unbound octetstring value to const unsigned char*.");
476 return val_ptr->octets_ptr;
477 }
478
479 void OCTETSTRING::log() const
480 {
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;
489 }
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("\")");
496 }
497 } else TTCN_Logger::log_event_unbound();
498 }
499
500 void OCTETSTRING::set_param(Module_Param& param) {
501 param.basic_check(Module_Param::BC_VALUE|Module_Param::BC_LIST, "octetstring value");
502 Module_Param_Ptr mp = &param;
503 if (param.get_type() == Module_Param::MP_Reference) {
504 mp = param.get_referenced_param();
505 }
506 switch (mp->get_type()) {
507 case Module_Param::MP_Octetstring:
508 switch (param.get_operation_type()) {
509 case Module_Param::OT_ASSIGN:
510 clean_up();
511 init_struct(mp->get_string_size());
512 memcpy(val_ptr->octets_ptr, mp->get_string_data(), val_ptr->n_octets);
513 break;
514 case Module_Param::OT_CONCAT:
515 if (is_bound()) {
516 *this += OCTETSTRING(mp->get_string_size(), (unsigned char*)mp->get_string_data());
517 } else {
518 *this = OCTETSTRING(mp->get_string_size(), (unsigned char*)mp->get_string_data());
519 }
520 break;
521 default:
522 TTCN_error("Internal error: OCTETSTRING::set_param()");
523 }
524 break;
525 case Module_Param::MP_Expression:
526 if (mp->get_expr_type() == Module_Param::EXPR_CONCATENATE) {
527 OCTETSTRING operand1, operand2;
528 operand1.set_param(*mp->get_operand1());
529 operand2.set_param(*mp->get_operand2());
530 if (param.get_operation_type() == Module_Param::OT_CONCAT) {
531 *this = *this + operand1 + operand2;
532 }
533 else {
534 *this = operand1 + operand2;
535 }
536 }
537 else {
538 param.expr_type_error("a octetstring");
539 }
540 break;
541 default:
542 param.type_error("octetstring value");
543 break;
544 }
545 }
546
547 Module_Param* OCTETSTRING::get_param(Module_Param_Name& /* param_name */) const
548 {
549 if (!is_bound()) {
550 return new Module_Param_Unbound();
551 }
552 unsigned char* val_cpy = (unsigned char *)Malloc(val_ptr->n_octets);
553 memcpy(val_cpy, val_ptr->octets_ptr, val_ptr->n_octets);
554 return new Module_Param_Octetstring(val_ptr->n_octets, val_cpy);
555 }
556
557 void OCTETSTRING::encode_text(Text_Buf& text_buf) const
558 {
559 must_bound("Text encoder: Encoding an unbound octetstring value.");
560 text_buf.push_int(val_ptr->n_octets);
561 if(val_ptr->n_octets > 0)
562 text_buf.push_raw(val_ptr->n_octets, val_ptr->octets_ptr);
563 }
564
565 void OCTETSTRING::decode_text(Text_Buf& text_buf)
566 {
567 int n_octets = text_buf.pull_int().get_val();
568 if (n_octets < 0)
569 TTCN_error("Text decoder: Invalid length was received for an octetstring.");
570 clean_up();
571 init_struct(n_octets);
572 if (n_octets > 0) text_buf.pull_raw(n_octets, val_ptr->octets_ptr);
573 }
574
575 void OCTETSTRING::encode(const TTCN_Typedescriptor_t& p_td,
576 TTCN_Buffer& p_buf,
577 TTCN_EncDec::coding_t p_coding, ...) const
578 {
579 va_list pvar;
580 va_start(pvar, p_coding);
581 switch(p_coding) {
582 case TTCN_EncDec::CT_BER: {
583 TTCN_EncDec_ErrorContext ec("While BER-encoding type '%s': ", p_td.name);
584 unsigned BER_coding=va_arg(pvar, unsigned);
585 BER_encode_chk_coding(BER_coding);
586 ASN_BER_TLV_t *tlv=BER_encode_TLV(p_td, BER_coding);
587 tlv->put_in_buffer(p_buf);
588 ASN_BER_TLV_t::destruct(tlv);
589 break;}
590 case TTCN_EncDec::CT_RAW: {
591 TTCN_EncDec_ErrorContext ec("While RAW-encoding type '%s': ", p_td.name);
592 if(!p_td.raw)
593 TTCN_EncDec_ErrorContext::error_internal
594 ("No RAW descriptor available for type '%s'.", p_td.name);
595 RAW_enc_tr_pos rp;
596 rp.level=0;
597 rp.pos=NULL;
598 RAW_enc_tree root(true,NULL,&rp,1,p_td.raw);
599 RAW_encode(p_td, root);
600 root.put_to_buf(p_buf);
601 break;}
602 case TTCN_EncDec::CT_TEXT: {
603 TTCN_EncDec_ErrorContext ec("While TEXT-encoding type '%s': ", p_td.name);
604 if(!p_td.text)
605 TTCN_EncDec_ErrorContext::error_internal
606 ("No TEXT descriptor available for type '%s'.", p_td.name);
607 TEXT_encode(p_td,p_buf);
608 break;}
609 case TTCN_EncDec::CT_XER: {
610 TTCN_EncDec_ErrorContext ec("While XER-encoding type '%s': ", p_td.name);
611 unsigned XER_coding=va_arg(pvar, unsigned);
612 XER_encode(*p_td.xer, p_buf, XER_coding, 0, 0);
613 break;}
614 case TTCN_EncDec::CT_JSON: {
615 TTCN_EncDec_ErrorContext ec("While TEXT-encoding type '%s': ", p_td.name);
616 if(!p_td.json)
617 TTCN_EncDec_ErrorContext::error_internal
618 ("No JSON descriptor available for type '%s'.", p_td.name);
619 JSON_Tokenizer tok(va_arg(pvar, int) != 0);
620 JSON_encode(p_td, tok);
621 p_buf.put_s(tok.get_buffer_length(), (const unsigned char*)tok.get_buffer());
622 break;}
623 default:
624 TTCN_error("Unknown coding method requested to encode type '%s'",
625 p_td.name);
626 }
627 va_end(pvar);
628 }
629
630 void OCTETSTRING::decode(const TTCN_Typedescriptor_t& p_td,
631 TTCN_Buffer& p_buf,
632 TTCN_EncDec::coding_t p_coding, ...)
633 {
634 va_list pvar;
635 va_start(pvar, p_coding);
636 switch(p_coding) {
637 case TTCN_EncDec::CT_BER: {
638 TTCN_EncDec_ErrorContext ec("While BER-decoding type '%s': ", p_td.name);
639 unsigned L_form=va_arg(pvar, unsigned);
640 ASN_BER_TLV_t tlv;
641 BER_decode_str2TLV(p_buf, tlv, L_form);
642 BER_decode_TLV(p_td, tlv, L_form);
643 if(tlv.isComplete) p_buf.increase_pos(tlv.get_len());
644 break;}
645 case TTCN_EncDec::CT_RAW: {
646 TTCN_EncDec_ErrorContext ec("While RAW-decoding type '%s': ", p_td.name);
647 if(!p_td.raw)
648 TTCN_EncDec_ErrorContext::error_internal
649 ("No RAW descriptor available for type '%s'.", p_td.name);
650 raw_order_t order;
651 switch(p_td.raw->top_bit_order){
652 case TOP_BIT_LEFT:
653 order=ORDER_LSB;
654 break;
655 case TOP_BIT_RIGHT:
656 default:
657 order=ORDER_MSB;
658 }
659 if(RAW_decode(p_td, p_buf, p_buf.get_len()*8, order)<0)
660 ec.error(TTCN_EncDec::ET_INCOMPL_MSG,
661 "Can not decode type '%s', because invalid or incomplete"
662 " message was received"
663 , p_td.name);
664 break;}
665 case TTCN_EncDec::CT_TEXT: {
666 Limit_Token_List limit;
667 TTCN_EncDec_ErrorContext ec("While TEXT-decoding type '%s': ", p_td.name);
668 if(!p_td.text)
669 TTCN_EncDec_ErrorContext::error_internal
670 ("No TEXT descriptor available for type '%s'.", p_td.name);
671 const unsigned char *b=p_buf.get_data();
672 if(b[p_buf.get_len()-1]!='\0'){
673 p_buf.set_pos(p_buf.get_len());
674 p_buf.put_zero(8,ORDER_LSB);
675 p_buf.rewind();
676 }
677 if(TEXT_decode(p_td,p_buf,limit)<0)
678 ec.error(TTCN_EncDec::ET_INCOMPL_MSG,
679 "Can not decode type '%s', because invalid or incomplete"
680 " message was received"
681 , p_td.name);
682 break;}
683 case TTCN_EncDec::CT_XER: {
684 TTCN_EncDec_ErrorContext ec("While XER-decoding type '%s': ", p_td.name);
685 unsigned XER_coding=va_arg(pvar, unsigned);
686 XmlReaderWrap reader(p_buf);
687 int success = reader.Read();
688 for (; success==1; success=reader.Read()) {
689 int type = reader.NodeType();
690 if (type==XML_READER_TYPE_ELEMENT)
691 break;
692 }
693 XER_decode(*p_td.xer, reader, XER_coding, 0);
694 size_t bytes = reader.ByteConsumed();
695 p_buf.set_pos(bytes);
696 break;}
697 case TTCN_EncDec::CT_JSON: {
698 TTCN_EncDec_ErrorContext ec("While JSON-decoding type '%s': ", p_td.name);
699 if(!p_td.json)
700 TTCN_EncDec_ErrorContext::error_internal
701 ("No JSON descriptor available for type '%s'.", p_td.name);
702 JSON_Tokenizer tok((const char*)p_buf.get_data(), p_buf.get_len());
703 if(JSON_decode(p_td, tok, false)<0)
704 ec.error(TTCN_EncDec::ET_INCOMPL_MSG,
705 "Can not decode type '%s', because invalid or incomplete"
706 " message was received"
707 , p_td.name);
708 p_buf.set_pos(tok.get_buf_pos());
709 break;}
710 default:
711 TTCN_error("Unknown coding method requested to decode type '%s'",
712 p_td.name);
713 }
714 va_end(pvar);
715 }
716
717 ASN_BER_TLV_t*
718 OCTETSTRING::BER_encode_TLV(const TTCN_Typedescriptor_t& p_td,
719 unsigned p_coding) const
720 {
721 BER_chk_descr(p_td);
722 ASN_BER_TLV_t *new_tlv=BER_encode_chk_bound(is_bound());
723 if(!new_tlv) {
724 new_tlv=BER_encode_TLV_OCTETSTRING
725 (p_coding, val_ptr->n_octets, val_ptr->octets_ptr);
726 }
727 new_tlv=ASN_BER_V2TLV(new_tlv, p_td, p_coding);
728 return new_tlv;
729 }
730
731 #ifdef TITAN_RUNTIME_2
732 ASN_BER_TLV_t* OCTETSTRING::BER_encode_negtest_raw() const
733 {
734 unsigned char *p_Vstr = (unsigned char *)Malloc(val_ptr->n_octets);
735 memcpy(p_Vstr, val_ptr->octets_ptr, val_ptr->n_octets);
736 ASN_BER_TLV_t* new_tlv = ASN_BER_TLV_t::construct(val_ptr->n_octets, p_Vstr);
737 return new_tlv;
738 }
739
740 int OCTETSTRING::encode_raw(TTCN_Buffer& p_buf) const
741 {
742 p_buf.put_string(*this);
743 return val_ptr ? val_ptr->n_octets : 0;
744 }
745
746 int OCTETSTRING::RAW_encode_negtest_raw(RAW_enc_tree& p_myleaf) const
747 {
748 if (p_myleaf.must_free)
749 Free(p_myleaf.body.leaf.data_ptr);
750 p_myleaf.must_free = false;
751 p_myleaf.data_ptr_used = true;
752 p_myleaf.body.leaf.data_ptr = val_ptr->octets_ptr;
753 return p_myleaf.length = val_ptr->n_octets * 8;
754 }
755 #endif
756
757 boolean OCTETSTRING::BER_decode_TLV(const TTCN_Typedescriptor_t& p_td,
758 const ASN_BER_TLV_t& p_tlv,
759 unsigned L_form)
760 {
761 clean_up();
762 BER_chk_descr(p_td);
763 ASN_BER_TLV_t stripped_tlv;
764 BER_decode_strip_tags(*p_td.ber, p_tlv, L_form, stripped_tlv);
765 TTCN_EncDec_ErrorContext ec("While decoding OCTETSTRING type: ");
766 /* Upper estimation for the length. */
767 size_t stripped_tlv_len = stripped_tlv.get_len();
768 if (stripped_tlv_len < 2) return FALSE;
769 int max_len = stripped_tlv_len - 2;
770 init_struct(max_len);
771 unsigned int octetnum_start = 0;
772 BER_decode_TLV_OCTETSTRING(stripped_tlv, L_form, octetnum_start,
773 val_ptr->n_octets, val_ptr->octets_ptr);
774 if (val_ptr->n_octets < max_len) {
775 if (val_ptr->n_octets == 0) {
776 clean_up();
777 init_struct(0);
778 } else {
779 val_ptr = (octetstring_struct*)
780 Realloc(val_ptr, MEMORY_SIZE(val_ptr->n_octets));
781 }
782 }
783 return TRUE;
784 }
785
786 int OCTETSTRING::TEXT_decode(const TTCN_Typedescriptor_t& p_td,
787 TTCN_Buffer& buff, Limit_Token_List& limit,
788 boolean no_err, boolean /*first_call*/)
789 {
790 int decoded_length=0;
791 int str_len=0;
792 clean_up();
793 if(p_td.text->begin_decode){
794 int tl;
795 if((tl=p_td.text->begin_decode->match_begin(buff))<0){
796 if(no_err)return -1;
797 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR,
798 "The specified token '%s' not found for '%s': ",
799 (const char*)*(p_td.text->begin_decode), p_td.name);
800 return 0;
801 }
802 decoded_length+=tl;
803 buff.increase_pos(tl);
804 }
805 // never returns "too short"
806 // if(buff.get_read_len()<=1 && no_err) return -TTCN_EncDec::ET_LEN_ERR;
807
808 if(p_td.text->select_token){
809 int tl;
810 if((tl=p_td.text->select_token->match_begin(buff))<0) {
811 if(no_err) return -1;
812 else tl=0;
813 }
814 str_len=tl;
815 } else
816 if( p_td.text->val.parameters
817 && p_td.text->val.parameters->decoding_params.min_length!=-1){
818 str_len=p_td.text->val.parameters->decoding_params.min_length*2;
819 } else if(p_td.text->end_decode){
820 int tl;
821 if((tl=p_td.text->end_decode->match_first(buff))<0) {
822 if(no_err) return -1;
823 else tl=0;
824 }
825 str_len=tl;
826 } else if (limit.has_token()){
827 int tl;
828 if((tl=limit.match(buff))<0)
829 tl=buff.get_read_len()-1;;
830 str_len=tl;
831 } else {
832 int tl;
833 if((tl=octetstring_value_match.match_begin(buff))<0) {
834 if(no_err) {return -1; }
835 else tl=0;
836 }
837 str_len=tl;
838 }
839 str_len=(str_len/2)*2;
840 //printf("HALI chr:%d ",str_len);
841 int n_octets = str_len / 2;
842 init_struct(n_octets);
843 unsigned char *octets_ptr = val_ptr->octets_ptr;
844 const char *value=(const char*)buff.get_read_data();
845 for (int i = 0; i < n_octets; i++) {
846 unsigned char upper_nibble = char_to_hexdigit(value[2 * i]);
847 unsigned char lower_nibble = char_to_hexdigit(value[2 * i + 1]);
848 if (upper_nibble > 0x0F){
849 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG,
850 "The octetstring value may contain hexadecimal digits only. "
851 "Character \"%c\" was found.", value[2 * i]);
852 upper_nibble=0;
853 }
854 if (lower_nibble > 0x0F){
855 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG,
856 "The octetstring value str2oct() may contain hexadecimal digits only. "
857 "Character \"%c\" was found.", value[2 * i + 1]);
858 lower_nibble=0;
859 }
860 octets_ptr[i] = (upper_nibble << 4) | lower_nibble;
861 }
862
863 //printf("%s\n\r",val_ptr->chars_ptr);
864 decoded_length+=str_len;
865 buff.increase_pos(str_len);
866
867 if(p_td.text->end_decode){
868 int tl;
869 if((tl=p_td.text->end_decode->match_begin(buff))<0){
870 if(no_err)return -1;
871 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR,
872 "The specified token '%s' not found for '%s': ",
873 (const char*)*(p_td.text->end_decode), p_td.name);
874 return 0;
875 }
876 decoded_length+=tl;
877 buff.increase_pos(tl);
878 }
879 return decoded_length;
880 }
881
882 // From Charstring.cc
883 extern char base64_decoder_table[256];
884 extern unsigned int xlate(cbyte* in, int phase, unsigned char* dest);
885 extern const char cb64[];
886
887 int OCTETSTRING::XER_encode(const XERdescriptor_t& p_td,
888 TTCN_Buffer& p_buf, unsigned int flavor, int indent, embed_values_enc_struct_t*) const
889 {
890 if(!is_bound()) {
891 TTCN_EncDec_ErrorContext::error
892 (TTCN_EncDec::ET_UNBOUND, "Encoding an unbound octetstring value.");
893 }
894 int exer = is_exer(flavor |= SIMPLE_TYPE);
895 // SIMPLE_TYPE has no influence on is_exer, we set it for later
896 int encoded_length=(int)p_buf.get_len();
897 int empty_element = val_ptr==NULL || val_ptr->n_octets == 0;
898
899 flavor &= ~XER_RECOF; // octetstring doesn't care
900 begin_xml(p_td, p_buf, flavor, indent, empty_element);
901
902 if (exer && (p_td.xer_bits & BASE_64)) {
903 // bit more work
904 size_t clear_len = lengthof();
905 const unsigned char * in = operator const unsigned char*();
906
907 /* Encode 3 bytes of cleartext into 4 bytes of Base64.
908 * Note that the algorithm is slightly different from Charstring.cc:
909 * we can't pad the source because it's const (this),
910 * so we need to check the indexes i+1 and i+2 before dereferencing */
911 for (size_t i = 0; i < clear_len; i += 3) {
912 p_buf.put_c( cb64[ in[i] >> 2 ] );
913 p_buf.put_c( cb64[ ((in[i] & 0x03) << 4) | (i+1 < clear_len
914 ? ((in[i+1] & 0xf0) >> 4)
915 :-0) ] );
916 p_buf.put_c( i+1 < clear_len
917 ? cb64[ ((in[i+1] & 0x0f) << 2) | (i+2 < clear_len ? ((in[i+2] & 0xc0) >> 6) :-0) ]
918 :'=');
919 p_buf.put_c( i+2 < clear_len ? cb64[ in[i+2] & 0x3f ] : '=' );
920 } // next i
921 }
922 else {
923 CHARSTRING val = oct2str(*this);
924 p_buf.put_string(val);
925 }
926
927 end_xml(p_td, p_buf, flavor, indent, empty_element);
928
929 return (int)p_buf.get_len() - encoded_length;
930 }
931
932 int OCTETSTRING::XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& reader,
933 unsigned int flavor, embed_values_dec_struct_t*)
934 {
935 int exer = is_exer(flavor);
936 int success = reader.Ok(), depth = -1, type;
937 boolean own_tag = !is_exerlist(flavor) && !(exer && (p_td.xer_bits & UNTAGGED));
938
939 const char * value = 0;
940 if (exer && (p_td.xer_bits & XER_ATTRIBUTE)) {
941 const char * name = verify_name(reader, p_td, exer);
942 (void)name;
943 }
944 else
945 if (own_tag) for (; success == 1; success = reader.Read()) {
946 type = reader.NodeType();
947 if (XML_READER_TYPE_ELEMENT == type) {
948 verify_name(reader, p_td, exer);
949 depth = reader.Depth();
950 if (reader.IsEmptyElement()) {
951 if (exer && p_td.dfeValue != 0) {
952 *this = *static_cast<const OCTETSTRING*> (p_td.dfeValue);
953 }
954 else init_struct(0);
955 reader.Read();
956 goto finished;
957 }
958 }
959 else if (XML_READER_TYPE_TEXT == type && depth != -1) break;
960 else if (XML_READER_TYPE_END_ELEMENT == type) {
961 // End tag without intervening #text == empty content
962 verify_end(reader, p_td, depth, exer);
963 if (exer && p_td.dfeValue != 0) {
964 *this = *static_cast<const OCTETSTRING*>(p_td.dfeValue);
965 }
966 else init_struct(0);
967 reader.Read();
968 goto finished;
969 }
970 }
971
972 type = reader.NodeType();
973 if (success == 1 && (XML_READER_TYPE_TEXT == type || XML_READER_TYPE_ATTRIBUTE == type)) {
974 value = (const char *)reader.Value();
975 size_t len = value ? strlen(value) : 0;
976
977 if (exer && (p_td.xer_bits & BASE_64)) {
978 xmlChar in[4];
979
980 int phase = 0;
981 init_struct(len * 3 / 4);
982 unsigned char * dest = val_ptr->octets_ptr;
983
984 for (size_t o=0; o<len; ++o) {
985 xmlChar c = value[o];
986 if(c == '=') { // padding starts
987 dest += xlate(in, phase, dest);
988 break;
989 }
990
991 int val = base64_decoder_table[c];
992 if(val >= 0) {
993 in[phase] = val;
994 phase = (phase + 1) % 4;
995 if(phase == 0) {
996 dest += xlate(in,phase, dest);
997 in[0]=in[1]=in[2]=in[3]=0;
998 }
999 }
1000 else if (exer && (flavor & EXIT_ON_ERROR)) {
1001 clean_up();
1002 return -1;
1003 } else {
1004 TTCN_EncDec_ErrorContext::warning(
1005 /* if this was an error... TTCN_EncDec::ET_INVAL_MSG,*/
1006 "Invalid character for Base64 '%02X'", c);
1007 }
1008 } // while
1009 // adjust
1010 val_ptr->n_octets = dest - val_ptr->octets_ptr;
1011
1012 }
1013 else { // not base64
1014 if (len & 1) { // that's odd...
1015 if (exer && (flavor & EXIT_ON_ERROR)) {
1016 clean_up();
1017 return -1;
1018 } else {
1019 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG,
1020 "Odd number of characters in octetstring");
1021 len &= ~1; // make it even
1022 }
1023 }
1024 size_t n_octets = len / 2;
1025 init_struct(n_octets);
1026
1027 len = 0; // will act as 2*i
1028 for (size_t i = 0; i < n_octets; ++i, ++++len) {
1029 unsigned char upper_nibble = char_to_hexdigit(value[len]);
1030 unsigned char lower_nibble = char_to_hexdigit(value[len+1]);
1031 if (upper_nibble > 0x0F) {
1032 if (exer && (flavor & EXIT_ON_ERROR)) {
1033 clean_up();
1034 return -1;
1035 } else {
1036 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG,
1037 "The octetstring value may contain hexadecimal digits only. "
1038 "Character \"%c\" was found.", value[len]);
1039 upper_nibble=0;
1040 }
1041 }
1042 if (lower_nibble > 0x0F) {
1043 if (exer && (flavor & EXIT_ON_ERROR)) {
1044 clean_up();
1045 return -1;
1046 } else {
1047 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG,
1048 "The octetstring value may contain hexadecimal digits only. "
1049 "Character \"%c\" was found.", value[len+1]);
1050 lower_nibble=0;
1051 }
1052 }
1053 val_ptr->octets_ptr[i] = (upper_nibble << 4) | lower_nibble;
1054 } // next
1055 } // if base64
1056 } // if success
1057
1058 if (exer && (p_td.xer_bits & XER_ATTRIBUTE)) {
1059 // Let the caller do reader.AdvanceAttribute();
1060 }
1061 else
1062 if (own_tag) for (success = reader.Read(); success == 1; success = reader.Read()) {
1063 type = reader.NodeType();
1064 if (XML_READER_TYPE_END_ELEMENT == type) {
1065 verify_end(reader, p_td, depth, exer);
1066 if (val_ptr == 0 && p_td.dfeValue != 0) {
1067 // The end tag must have followed the start tag
1068 *this = *static_cast<const OCTETSTRING*>(p_td.dfeValue);
1069 }
1070 reader.Read(); // one last time
1071 break;
1072 }
1073 }
1074 finished:
1075 return 1; // decode successful
1076 }
1077
1078 int OCTETSTRING::TEXT_encode(const TTCN_Typedescriptor_t& p_td,
1079 TTCN_Buffer& buff) const{
1080 int encoded_length=0;
1081 if(p_td.text->begin_encode){
1082 buff.put_cs(*p_td.text->begin_encode);
1083 encoded_length+=p_td.text->begin_encode->lengthof();
1084 }
1085 if(!is_bound()) {
1086 TTCN_EncDec_ErrorContext::error
1087 (TTCN_EncDec::ET_UNBOUND, "Encoding an unbound value.");
1088 if(p_td.text->end_encode){
1089 buff.put_cs(*p_td.text->end_encode);
1090 encoded_length+=p_td.text->end_encode->lengthof();
1091 }
1092 return encoded_length;
1093 }
1094
1095 int chars_before=0;
1096
1097 if(p_td.text->val.parameters){
1098 if(val_ptr->n_octets<p_td.text->val.parameters->coding_params.min_length){
1099 chars_before=(p_td.text->
1100 val.parameters->coding_params.min_length-val_ptr->n_octets)*2;
1101 }
1102 }
1103
1104 if(chars_before){
1105 unsigned char* p=NULL;
1106 size_t len=chars_before;
1107 buff.get_end(p,len);
1108 for(int a=0;a<chars_before;a++) p[a]=(unsigned char)'0';
1109 buff.increase_length(chars_before);
1110 encoded_length+=chars_before;
1111 }
1112
1113 if(val_ptr->n_octets){
1114 unsigned char* p=NULL;
1115 size_t len=val_ptr->n_octets*2;
1116 buff.get_end(p,len);
1117 len=val_ptr->n_octets;
1118 for(size_t i=0;i<len;i++){
1119 p[2 * i] = hexdigit_to_char(val_ptr->octets_ptr[i] >> 4);
1120 p[2 * i + 1] = hexdigit_to_char(val_ptr->octets_ptr[i] & 0x0F);
1121 }
1122 buff.increase_length(len*2);
1123 encoded_length+=len*2;
1124 }
1125
1126
1127 if(p_td.text->end_encode){
1128 buff.put_cs(*p_td.text->end_encode);
1129 encoded_length+=p_td.text->end_encode->lengthof();
1130 }
1131 return encoded_length;
1132 }
1133
1134 int OCTETSTRING::RAW_encode(const TTCN_Typedescriptor_t& p_td,
1135 RAW_enc_tree& myleaf) const
1136 {
1137 if (!is_bound()) {
1138 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND,
1139 "Encoding an unbound value.");
1140 }
1141 unsigned char *bc;
1142 int bl = val_ptr->n_octets * 8;
1143 int align_length = p_td.raw->fieldlength ? p_td.raw->fieldlength - bl : 0;
1144 int blength = val_ptr->n_octets;
1145 if ((bl + align_length) < val_ptr->n_octets * 8) {
1146 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_LEN_ERR,
1147 "There are insufficient bits to encode '%s': ", p_td.name);
1148 blength = p_td.raw->fieldlength / 8;
1149 bl = p_td.raw->fieldlength;
1150 align_length = 0;
1151 }
1152 if (myleaf.must_free) Free(myleaf.body.leaf.data_ptr);
1153 myleaf.must_free = false;
1154 myleaf.data_ptr_used = true;
1155 if (p_td.raw->extension_bit != EXT_BIT_NO
1156 && myleaf.coding_par.bitorder == ORDER_MSB) {
1157 if (blength > RAW_INT_ENC_LENGTH) {
1158 myleaf.body.leaf.data_ptr = bc = (unsigned char*)Malloc(blength*sizeof(*bc));
1159 myleaf.must_free = true;
1160 myleaf.data_ptr_used = true;
1161 }
1162 else {
1163 bc = myleaf.body.leaf.data_array;
1164 myleaf.data_ptr_used = false;
1165 }
1166 for (int a = 0; a < blength; a++) bc[a] = val_ptr->octets_ptr[a] << 1;
1167 }
1168 else myleaf.body.leaf.data_ptr = val_ptr->octets_ptr;
1169 if (p_td.raw->endianness == ORDER_MSB) myleaf.align = -align_length;
1170 else myleaf.align = align_length;
1171 return myleaf.length = bl + align_length;
1172 }
1173
1174 int OCTETSTRING::RAW_decode(const TTCN_Typedescriptor_t& p_td,
1175 TTCN_Buffer& buff, int limit, raw_order_t top_bit_ord, boolean no_err,
1176 int /*sel_field*/, boolean /*first_call*/)
1177 {
1178 int prepaddlength = buff.increase_pos_padd(p_td.raw->prepadding);
1179 limit -= prepaddlength;
1180 int decode_length = p_td.raw->fieldlength == 0
1181 ? (limit / 8) * 8 : p_td.raw->fieldlength;
1182 if (decode_length > limit || decode_length > (int) buff.unread_len_bit()) {
1183 if (no_err) return -TTCN_EncDec::ET_LEN_ERR;
1184 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_LEN_ERR,
1185 "There is not enough bits in the buffer to decode type %s.", p_td.name);
1186 decode_length = ((limit > (int) buff.unread_len_bit()
1187 ? (int)buff.unread_len_bit() : limit) / 8) * 8;
1188 }
1189 RAW_coding_par cp;
1190 bool orders = false;
1191 if (p_td.raw->bitorderinoctet == ORDER_MSB) orders = true;
1192 if (p_td.raw->bitorderinfield == ORDER_MSB) orders = !orders;
1193 cp.bitorder = orders ? ORDER_MSB : ORDER_LSB;
1194 orders = false;
1195 if (p_td.raw->byteorder == ORDER_MSB) orders = true;
1196 if (p_td.raw->bitorderinfield == ORDER_MSB) orders = !orders;
1197 cp.byteorder = orders ? ORDER_MSB : ORDER_LSB;
1198 cp.fieldorder = p_td.raw->fieldorder;
1199 cp.hexorder = ORDER_LSB;
1200 if (p_td.raw->extension_bit != EXT_BIT_NO) {
1201 const unsigned char* data = buff.get_read_data();
1202 int count = 1;
1203 int rot = top_bit_ord == ORDER_LSB ? 0 : 7;
1204 if (p_td.raw->extension_bit == EXT_BIT_YES) {
1205 while (((data[count - 1] >> rot) & 0x01) == 0 && count * 8 < decode_length)
1206 count++;
1207 }
1208 else {
1209 while (((data[count - 1] >> rot) & 0x01) == 1 && count * 8 < decode_length)
1210 count++;
1211 }
1212 decode_length = count * 8;
1213 }
1214 clean_up();
1215 init_struct(decode_length / 8);
1216 buff.get_b((size_t) decode_length, val_ptr->octets_ptr, cp, top_bit_ord);
1217
1218 if (p_td.raw->length_restrition != -1) {
1219 val_ptr->n_octets = p_td.raw->length_restrition;
1220 if (p_td.raw->endianness == ORDER_MSB) memmove(val_ptr->octets_ptr,
1221 val_ptr->octets_ptr + (decode_length / 8 - val_ptr->n_octets),
1222 val_ptr->n_octets * sizeof(unsigned char));
1223 }
1224 if (p_td.raw->extension_bit != EXT_BIT_NO && cp.bitorder == ORDER_MSB) {
1225 for (int a = 0; a < decode_length / 8; a++)
1226 val_ptr->octets_ptr[a] = val_ptr->octets_ptr[a] >> 1 | val_ptr->octets_ptr[a] << 7;
1227 }
1228 decode_length += buff.increase_pos_padd(p_td.raw->padding);
1229 return decode_length + prepaddlength;
1230 }
1231
1232 void OCTETSTRING::dump () const
1233 {
1234 if (val_ptr != NULL) {
1235 printf("octetstring(%d) :\n", val_ptr->n_octets);
1236 for (int i = 0; i < val_ptr->n_octets; i++) {
1237 printf("%02X ", val_ptr->octets_ptr[i]);
1238 }
1239 printf("\n");
1240 }
1241 }
1242
1243 int OCTETSTRING::JSON_encode(const TTCN_Typedescriptor_t&, JSON_Tokenizer& p_tok) const
1244 {
1245 if (!is_bound()) {
1246 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND,
1247 "Encoding an unbound octetstring value.");
1248 return -1;
1249 }
1250
1251 char* tmp_str = (char*)Malloc(val_ptr->n_octets * 2 + 3);
1252 tmp_str[0] = '\"';
1253 tmp_str[val_ptr->n_octets * 2 + 1] = '\"';
1254 for(int i = 0; i < val_ptr->n_octets; ++i) {
1255 tmp_str[2 * i + 1] = hexdigit_to_char(val_ptr->octets_ptr[i] >> 4);
1256 tmp_str[2 * i + 2] = hexdigit_to_char(val_ptr->octets_ptr[i] & 0x0F);
1257 }
1258 tmp_str[val_ptr->n_octets * 2 + 2] = 0;
1259 int enc_len = p_tok.put_next_token(JSON_TOKEN_STRING, tmp_str);
1260 Free(tmp_str);
1261 return enc_len;
1262 }
1263
1264 int OCTETSTRING::JSON_decode(const TTCN_Typedescriptor_t& p_td, JSON_Tokenizer& p_tok, boolean p_silent)
1265 {
1266 json_token_t token = JSON_TOKEN_NONE;
1267 char* value = 0;
1268 size_t value_len = 0;
1269 boolean error = false;
1270 int dec_len = 0;
1271 boolean use_default = p_td.json->default_value && 0 == p_tok.get_buffer_length();
1272 if (use_default) {
1273 // No JSON data in the buffer -> use default value
1274 value = (char*)p_td.json->default_value;
1275 value_len = strlen(value);
1276 } else {
1277 dec_len = p_tok.get_next_token(&token, &value, &value_len);
1278 }
1279 if (JSON_TOKEN_ERROR == token) {
1280 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_BAD_TOKEN_ERROR, "");
1281 return JSON_ERROR_FATAL;
1282 }
1283 else if (JSON_TOKEN_STRING == token || use_default) {
1284 if (0 == value_len % 2 && (use_default ||
1285 (value_len > 2 && value[0] == '\"' && value[value_len - 1] == '\"'))) {
1286 if (!use_default) {
1287 // The default value doesn't have quotes around it
1288 value_len -= 2;
1289 ++value;
1290 }
1291 size_t octets = value_len / 2;
1292 init_struct(octets);
1293 for (size_t i = 0; i < octets; ++i) {
1294 unsigned char upper_nibble = char_to_hexdigit(value[2 * i]);
1295 unsigned char lower_nibble = char_to_hexdigit(value[2 * i + 1]);
1296 if (upper_nibble <= 0x0F && lower_nibble <= 0x0F) {
1297 val_ptr->octets_ptr[i] = (upper_nibble << 4) | lower_nibble;
1298 } else {
1299 error = true;
1300 }
1301 }
1302 } else {
1303 error = true;
1304 }
1305 } else {
1306 return JSON_ERROR_INVALID_TOKEN;
1307 }
1308
1309 if (error) {
1310 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_FORMAT_ERROR, "string", "octetstring");
1311 if (p_silent) {
1312 clean_up();
1313 }
1314 return JSON_ERROR_FATAL;
1315 }
1316 return dec_len;
1317 }
1318
1319 // octetstring element class
1320
1321 OCTETSTRING_ELEMENT::OCTETSTRING_ELEMENT(boolean par_bound_flag,
1322 OCTETSTRING& par_str_val, int par_octet_pos)
1323 : bound_flag(par_bound_flag), str_val(par_str_val), octet_pos(par_octet_pos)
1324 {
1325 }
1326
1327 OCTETSTRING_ELEMENT& OCTETSTRING_ELEMENT::operator=
1328 (const OCTETSTRING& other_value)
1329 {
1330 other_value.must_bound("Assignment of an unbound octetstring value.");
1331 if(other_value.val_ptr->n_octets != 1)
1332 TTCN_error("Assignment of an octetstring "
1333 "with length other than 1 to an octetstring element.");
1334 bound_flag = TRUE;
1335 str_val.copy_value();
1336 str_val.val_ptr->octets_ptr[octet_pos] = other_value.val_ptr->octets_ptr[0];
1337 return *this;
1338 }
1339
1340 OCTETSTRING_ELEMENT& OCTETSTRING_ELEMENT::operator=
1341 (const OCTETSTRING_ELEMENT& other_value)
1342 {
1343 other_value.must_bound("Assignment of an unbound octetstring element.");
1344 if (&other_value != this) {
1345 bound_flag = TRUE;
1346 str_val.copy_value();
1347 str_val.val_ptr->octets_ptr[octet_pos] =
1348 other_value.str_val.val_ptr->octets_ptr[other_value.octet_pos];
1349 }
1350 return *this;
1351 }
1352
1353 boolean OCTETSTRING_ELEMENT::operator==(const OCTETSTRING& other_value) const
1354 {
1355 must_bound("Unbound left operand of octetstring element comparison.");
1356 other_value.must_bound("Unbound right operand of octetstring comparison.");
1357 if(other_value.val_ptr->n_octets != 1) return FALSE;
1358 return str_val.val_ptr->octets_ptr[octet_pos] ==
1359 other_value.val_ptr->octets_ptr[0];
1360 }
1361
1362 boolean OCTETSTRING_ELEMENT::operator==
1363 (const OCTETSTRING_ELEMENT& other_value) const
1364 {
1365 must_bound("Unbound left operand of octetstring element comparison.");
1366 other_value.must_bound("Unbound right operand of octetstring element "
1367 "comparison.");
1368 return str_val.val_ptr->octets_ptr[octet_pos] ==
1369 other_value.str_val.val_ptr->octets_ptr[other_value.octet_pos];
1370 }
1371
1372 OCTETSTRING OCTETSTRING_ELEMENT::operator+(const OCTETSTRING& other_value) const
1373 {
1374 must_bound("Unbound left operand of octetstring element concatenation.");
1375 other_value.must_bound("Unbound right operand of octetstring concatenation.");
1376 OCTETSTRING ret_val(other_value.val_ptr->n_octets + 1);
1377 ret_val.val_ptr->octets_ptr[0] = str_val.val_ptr->octets_ptr[octet_pos];
1378 memcpy(ret_val.val_ptr->octets_ptr + 1,
1379 other_value.val_ptr->octets_ptr, other_value.val_ptr->n_octets);
1380 return ret_val;
1381 }
1382
1383 OCTETSTRING OCTETSTRING_ELEMENT::operator+
1384 (const OCTETSTRING_ELEMENT& other_value) const
1385 {
1386 must_bound("Unbound left operand of octetstring element concatenation.");
1387 other_value.must_bound("Unbound right operand of octetstring element "
1388 "concatenation.");
1389 unsigned char result[2];
1390 result[0] = str_val.val_ptr->octets_ptr[octet_pos];
1391 result[1] = other_value.str_val.val_ptr->octets_ptr[other_value.octet_pos];
1392 return OCTETSTRING(2, result);
1393 }
1394
1395 OCTETSTRING OCTETSTRING_ELEMENT::operator~() const
1396 {
1397 must_bound("Unbound octetstring element operand of operator not4b.");
1398 unsigned char result = ~str_val.val_ptr->octets_ptr[octet_pos];
1399 return OCTETSTRING(1, &result);
1400 }
1401
1402 OCTETSTRING OCTETSTRING_ELEMENT::operator&(const OCTETSTRING& other_value) const
1403 {
1404 must_bound("Left operand of operator and4b is an unbound octetstring "
1405 "element.");
1406 other_value.must_bound("Right operand of operator and4b is an unbound "
1407 "octetstring value.");
1408 if (other_value.val_ptr->n_octets != 1)
1409 TTCN_error("The octetstring "
1410 "operands of operator and4b must have the same length.");
1411 unsigned char result = str_val.val_ptr->octets_ptr[octet_pos] &
1412 other_value.val_ptr->octets_ptr[0];
1413 return OCTETSTRING(1, &result);
1414 }
1415
1416 OCTETSTRING OCTETSTRING_ELEMENT::operator&
1417 (const OCTETSTRING_ELEMENT& other_value) const
1418 {
1419 must_bound("Left operand of operator and4b is an unbound octetstring "
1420 "element.");
1421 other_value.must_bound("Right operand of operator and4b is an unbound "
1422 "octetstring element.");
1423 unsigned char result = str_val.val_ptr->octets_ptr[octet_pos] &
1424 other_value.str_val.val_ptr->octets_ptr[other_value.octet_pos];
1425 return OCTETSTRING(1, &result);
1426 }
1427
1428 OCTETSTRING OCTETSTRING_ELEMENT::operator|(const OCTETSTRING& other_value) const
1429 {
1430 must_bound("Left operand of operator or4b is an unbound octetstring "
1431 "element.");
1432 other_value.must_bound("Right operand of operator or4b is an unbound "
1433 "octetstring value.");
1434 if (other_value.val_ptr->n_octets != 1)
1435 TTCN_error("The octetstring "
1436 "operands of operator or4b must have the same length.");
1437 unsigned char result = str_val.val_ptr->octets_ptr[octet_pos] |
1438 other_value.val_ptr->octets_ptr[0];
1439 return OCTETSTRING(1, &result);
1440 }
1441
1442 OCTETSTRING OCTETSTRING_ELEMENT::operator|
1443 (const OCTETSTRING_ELEMENT& other_value) const
1444 {
1445 must_bound("Left operand of operator or4b is an unbound octetstring "
1446 "element.");
1447 other_value.must_bound("Right operand of operator or4b is an unbound "
1448 "octetstring element.");
1449 unsigned char result = str_val.val_ptr->octets_ptr[octet_pos] |
1450 other_value.str_val.val_ptr->octets_ptr[other_value.octet_pos];
1451 return OCTETSTRING(1, &result);
1452 }
1453
1454 OCTETSTRING OCTETSTRING_ELEMENT::operator^(const OCTETSTRING& other_value) const
1455 {
1456 must_bound("Left operand of operator xor4b is an unbound octetstring "
1457 "element.");
1458 other_value.must_bound("Right operand of operator xor4b is an unbound "
1459 "octetstring value.");
1460 if (other_value.val_ptr->n_octets != 1)
1461 TTCN_error("The octetstring "
1462 "operands of operator xor4b must have the same length.");
1463 unsigned char result = str_val.val_ptr->octets_ptr[octet_pos] ^
1464 other_value.val_ptr->octets_ptr[0];
1465 return OCTETSTRING(1, &result);
1466 }
1467
1468 OCTETSTRING OCTETSTRING_ELEMENT::operator^
1469 (const OCTETSTRING_ELEMENT& other_value) const
1470 {
1471 must_bound("Left operand of operator xor4b is an unbound octetstring "
1472 "element.");
1473 other_value.must_bound("Right operand of operator xor4b is an unbound "
1474 "octetstring element.");
1475 unsigned char result = str_val.val_ptr->octets_ptr[octet_pos] ^
1476 other_value.str_val.val_ptr->octets_ptr[other_value.octet_pos];
1477 return OCTETSTRING(1, &result);
1478 }
1479
1480 unsigned char OCTETSTRING_ELEMENT::get_octet() const
1481 {
1482 return str_val.val_ptr->octets_ptr[octet_pos];
1483 }
1484
1485 void OCTETSTRING_ELEMENT::log() const
1486 {
1487 if (bound_flag) {
1488 unsigned char octet = str_val.val_ptr->octets_ptr[octet_pos];
1489 TTCN_Logger::log_char('\'');
1490 TTCN_Logger::log_octet(octet);
1491 TTCN_Logger::log_event_str("'O");
1492 if (TTCN_Logger::is_printable(octet)) {
1493 TTCN_Logger::log_event_str(" (\"");
1494 TTCN_Logger::log_char_escaped(octet);
1495 TTCN_Logger::log_event_str("\")");
1496 }
1497 } else TTCN_Logger::log_event_unbound();
1498 }
1499
1500 // octetstring template class
1501
1502 void OCTETSTRING_template::clean_up()
1503 {
1504 switch (template_selection) {
1505 case VALUE_LIST:
1506 case COMPLEMENTED_LIST:
1507 delete [] value_list.list_value;
1508 break;
1509 case STRING_PATTERN:
1510 if (pattern_value->ref_count > 1) pattern_value->ref_count--;
1511 else if (pattern_value->ref_count == 1) Free(pattern_value);
1512 else TTCN_error("Internal error: Invalid reference counter in an "
1513 "octetstring pattern.");
1514 break;
1515 default:
1516 break;
1517 }
1518 template_selection = UNINITIALIZED_TEMPLATE;
1519 }
1520
1521 void OCTETSTRING_template::copy_template
1522 (const OCTETSTRING_template& other_value)
1523 {
1524 switch (other_value.template_selection) {
1525 case SPECIFIC_VALUE:
1526 single_value = other_value.single_value;
1527 break;
1528 case OMIT_VALUE:
1529 case ANY_VALUE:
1530 case ANY_OR_OMIT:
1531 break;
1532 case VALUE_LIST:
1533 case COMPLEMENTED_LIST:
1534 value_list.n_values = other_value.value_list.n_values;
1535 value_list.list_value = new OCTETSTRING_template[value_list.n_values];
1536 for (unsigned int i = 0; i < value_list.n_values; i++)
1537 value_list.list_value[i].copy_template(
1538 other_value.value_list.list_value[i]);
1539 break;
1540 case STRING_PATTERN:
1541 pattern_value = other_value.pattern_value;
1542 pattern_value->ref_count++;
1543 break;
1544 default:
1545 TTCN_error("Copying an uninitialized/unsupported octetstring template.");
1546 }
1547 set_selection(other_value);
1548 }
1549
1550 /*
1551 This is the same algorithm that match_array uses
1552 to match 'record of' types.
1553 The only differences are: how two elements are matched and
1554 how an asterisk or ? is identified in the template
1555 */
1556 boolean OCTETSTRING_template::match_pattern(
1557 const octetstring_pattern_struct *string_pattern,
1558 const OCTETSTRING::octetstring_struct *string_value)
1559 {
1560 // the empty pattern matches the empty octetstring only
1561 if (string_pattern->n_elements == 0) return string_value->n_octets == 0;
1562
1563 int value_index = 0;
1564 unsigned int template_index = 0;
1565 int last_asterisk = -1;
1566 int last_value_to_asterisk = -1;
1567 //this variable is used to speed up the function
1568 unsigned short pattern_element;
1569
1570 for(;;)
1571 {
1572 pattern_element = string_pattern->elements_ptr[template_index];
1573 if( pattern_element < 256){
1574 if(string_value->octets_ptr[value_index] == pattern_element)
1575 {
1576 value_index++;
1577 template_index++;
1578 }else{
1579 if(last_asterisk == -1) return FALSE;
1580 template_index = last_asterisk +1;
1581 value_index = ++last_value_to_asterisk;
1582 }
1583 } else if(pattern_element == 256)
1584 {//? found
1585 value_index++;
1586 template_index++;
1587 }else if(pattern_element == 257)
1588 {//* found
1589 last_asterisk = template_index++;
1590 last_value_to_asterisk = value_index;
1591 } else TTCN_error("Internal error: invalid element in an octetstring "
1592 "pattern.");
1593
1594 if(value_index == string_value->n_octets
1595 && template_index == string_pattern->n_elements)
1596 {
1597 return TRUE;
1598 }else if (template_index == string_pattern->n_elements)
1599 {
1600 if(string_pattern->elements_ptr[template_index - 1] == 257)
1601 {
1602 return TRUE;
1603 }else if(last_asterisk == -1)
1604 {
1605 return FALSE;
1606 }else{
1607 template_index = last_asterisk+1;
1608 value_index = ++last_value_to_asterisk;
1609 }
1610 }else if(value_index == string_value->n_octets)
1611 {
1612 while(template_index < string_pattern->n_elements
1613 && string_pattern->elements_ptr[template_index] == 257)
1614 template_index++;
1615
1616 return template_index == string_pattern->n_elements;
1617 }
1618 }
1619 }
1620
1621 OCTETSTRING_template::OCTETSTRING_template()
1622 {
1623 }
1624
1625 OCTETSTRING_template::OCTETSTRING_template(template_sel other_value)
1626 : Restricted_Length_Template(other_value)
1627 {
1628 check_single_selection(other_value);
1629 }
1630
1631 OCTETSTRING_template::OCTETSTRING_template(const OCTETSTRING& other_value)
1632 : Restricted_Length_Template(SPECIFIC_VALUE), single_value(other_value)
1633 {
1634 }
1635
1636 OCTETSTRING_template::OCTETSTRING_template
1637 (const OCTETSTRING_ELEMENT& other_value)
1638 : Restricted_Length_Template(SPECIFIC_VALUE), single_value(other_value)
1639 {
1640 }
1641
1642 OCTETSTRING_template::OCTETSTRING_template
1643 (const OPTIONAL<OCTETSTRING>& other_value)
1644 {
1645 switch (other_value.get_selection()) {
1646 case OPTIONAL_PRESENT:
1647 set_selection(SPECIFIC_VALUE);
1648 single_value = (const OCTETSTRING&)other_value;
1649 break;
1650 case OPTIONAL_OMIT:
1651 set_selection(OMIT_VALUE);
1652 break;
1653 default:
1654 TTCN_error("Creating an octetstring template from an unbound optional "
1655 "field.");
1656 }
1657 }
1658
1659 OCTETSTRING_template::OCTETSTRING_template(unsigned int n_elements,
1660 const unsigned short *pattern_elements)
1661 : Restricted_Length_Template(STRING_PATTERN)
1662 {
1663 pattern_value = (octetstring_pattern_struct*)
1664 Malloc(sizeof(octetstring_pattern_struct) +
1665 (n_elements - 1) * sizeof(unsigned short));
1666 pattern_value->ref_count = 1;
1667 pattern_value->n_elements = n_elements;
1668 memcpy(pattern_value->elements_ptr, pattern_elements,
1669 n_elements * sizeof(unsigned short));
1670 }
1671
1672 OCTETSTRING_template::OCTETSTRING_template
1673 (const OCTETSTRING_template& other_value)
1674 : Restricted_Length_Template()
1675 {
1676 copy_template(other_value);
1677 }
1678
1679 OCTETSTRING_template::~OCTETSTRING_template()
1680 {
1681 clean_up();
1682 }
1683
1684 OCTETSTRING_template& OCTETSTRING_template::operator=(template_sel other_value)
1685 {
1686 check_single_selection(other_value);
1687 clean_up();
1688 set_selection(other_value);
1689 return *this;
1690 }
1691
1692 OCTETSTRING_template& OCTETSTRING_template::operator=
1693 (const OCTETSTRING& other_value)
1694 {
1695 other_value.must_bound("Assignment of an unbound octetstring value to a "
1696 "template.");
1697 clean_up();
1698 set_selection(SPECIFIC_VALUE);
1699 single_value = other_value;
1700 return *this;
1701 }
1702
1703 OCTETSTRING_template& OCTETSTRING_template::operator=
1704 (const OCTETSTRING_ELEMENT& other_value)
1705 {
1706 other_value.must_bound("Assignment of an unbound octetstring element to a "
1707 "template.");
1708 clean_up();
1709 set_selection(SPECIFIC_VALUE);
1710 single_value = other_value;
1711 return *this;
1712 }
1713
1714 OCTETSTRING_template& OCTETSTRING_template::operator=
1715 (const OPTIONAL<OCTETSTRING>& other_value)
1716 {
1717 clean_up();
1718 switch (other_value.get_selection()) {
1719 case OPTIONAL_PRESENT:
1720 set_selection(SPECIFIC_VALUE);
1721 single_value = (const OCTETSTRING&)other_value;
1722 break;
1723 case OPTIONAL_OMIT:
1724 set_selection(OMIT_VALUE);
1725 break;
1726 default:
1727 TTCN_error("Assignment of an unbound optional field to an octetstring "
1728 "template.");
1729 }
1730 return *this;
1731 }
1732
1733 OCTETSTRING_template& OCTETSTRING_template::operator=
1734 (const OCTETSTRING_template& other_value)
1735 {
1736 if (&other_value != this) {
1737 clean_up();
1738 copy_template(other_value);
1739 }
1740 return *this;
1741 }
1742
1743 OCTETSTRING_ELEMENT OCTETSTRING_template::operator[](int index_value)
1744 {
1745 if (template_selection != SPECIFIC_VALUE || is_ifpresent)
1746 TTCN_error("Accessing an octetstring element of a non-specific "
1747 "octetstring template.");
1748 return single_value[index_value];
1749 }
1750
1751 OCTETSTRING_ELEMENT OCTETSTRING_template::operator[](const INTEGER& index_value)
1752 {
1753 index_value.must_bound("Indexing a octetstring value with an unbound "
1754 "integer value.");
1755 return (*this)[(int)index_value];
1756 }
1757
1758 const OCTETSTRING_ELEMENT OCTETSTRING_template::operator[](int index_value) const
1759 {
1760 if (template_selection != SPECIFIC_VALUE || is_ifpresent)
1761 TTCN_error("Accessing an octetstring element of a non-specific "
1762 "octetstring template.");
1763 return single_value[index_value];
1764 }
1765
1766 const OCTETSTRING_ELEMENT OCTETSTRING_template::operator[](const INTEGER& index_value) const
1767 {
1768 index_value.must_bound("Indexing a octetstring template with an unbound "
1769 "integer value.");
1770 return (*this)[(int)index_value];
1771 }
1772
1773 boolean OCTETSTRING_template::match(const OCTETSTRING& other_value,
1774 boolean /* legacy */) const
1775 {
1776 if (!other_value.is_bound()) return FALSE;
1777 if (!match_length(other_value.val_ptr->n_octets)) return FALSE;
1778 switch (template_selection) {
1779 case SPECIFIC_VALUE:
1780 return single_value == other_value;
1781 case OMIT_VALUE:
1782 return FALSE;
1783 case ANY_VALUE:
1784 case ANY_OR_OMIT:
1785 return TRUE;
1786 case VALUE_LIST:
1787 case COMPLEMENTED_LIST:
1788 for(unsigned int i = 0; i < value_list.n_values; i++)
1789 if (value_list.list_value[i].match(other_value))
1790 return template_selection == VALUE_LIST;
1791 return template_selection == COMPLEMENTED_LIST;
1792 case STRING_PATTERN:
1793 return match_pattern(pattern_value, other_value.val_ptr);
1794 default:
1795 TTCN_error("Matching an uninitialized/unsupported octetstring template.");
1796 }
1797 return FALSE;
1798 }
1799
1800 const OCTETSTRING& OCTETSTRING_template::valueof() const
1801 {
1802 if (template_selection != SPECIFIC_VALUE || is_ifpresent)
1803 TTCN_error("Performing a valueof or send operation on a non-specific "
1804 "octetstring template.");
1805 return single_value;
1806 }
1807
1808 int OCTETSTRING_template::lengthof() const
1809 {
1810 int min_length;
1811 boolean has_any_or_none;
1812 if (is_ifpresent)
1813 TTCN_error("Performing lengthof() operation on a octetstring template "
1814 "which has an ifpresent attribute.");
1815 switch (template_selection)
1816 {
1817 case SPECIFIC_VALUE:
1818 min_length = single_value.lengthof();
1819 has_any_or_none = FALSE;
1820 break;
1821 case OMIT_VALUE:
1822 TTCN_error("Performing lengthof() operation on an octetstring template "
1823 "containing omit value.");
1824 case ANY_VALUE:
1825 case ANY_OR_OMIT:
1826 min_length = 0;
1827 has_any_or_none = TRUE; // max. length is infinity
1828 break;
1829 case VALUE_LIST:
1830 {
1831 // error if any element does not have length or the lengths differ
1832 if (value_list.n_values<1)
1833 TTCN_error("Internal error: "
1834 "Performing lengthof() operation on an octetstring template "
1835 "containing an empty list.");
1836 int item_length = value_list.list_value[0].lengthof();
1837 for (unsigned int i = 1; i < value_list.n_values; i++) {
1838 if (value_list.list_value[i].lengthof()!=item_length)
1839 TTCN_error("Performing lengthof() operation on an octetstring template "
1840 "containing a value list with different lengths.");
1841 }
1842 min_length = item_length;
1843 has_any_or_none = FALSE;
1844 break;
1845 }
1846 case COMPLEMENTED_LIST:
1847 TTCN_error("Performing lengthof() operation on an octetstring template "
1848 "containing complemented list.");
1849 case STRING_PATTERN:
1850 min_length = 0;
1851 has_any_or_none = FALSE; // TRUE if * chars in the pattern
1852 for (unsigned int i = 0; i < pattern_value->n_elements; i++)
1853 {
1854 if (pattern_value->elements_ptr[i] < 257) min_length++;
1855 else has_any_or_none = TRUE; // case of * character
1856 }
1857 break;
1858 default:
1859 TTCN_error("Performing lengthof() operation on an "
1860 "uninitialized/unsupported octetstring template.");
1861 }
1862 return check_section_is_single(min_length, has_any_or_none,
1863 "length", "an", "octetstring template");
1864 }
1865
1866 void OCTETSTRING_template::set_type(template_sel template_type,
1867 unsigned int list_length)
1868 {
1869 if (template_type != VALUE_LIST && template_type != COMPLEMENTED_LIST)
1870 TTCN_error("Setting an invalid list type for an octetstring template.");
1871 clean_up();
1872 set_selection(template_type);
1873 value_list.n_values = list_length;
1874 value_list.list_value = new OCTETSTRING_template[list_length];
1875 }
1876
1877 OCTETSTRING_template& OCTETSTRING_template::list_item(unsigned int list_index)
1878 {
1879 if (template_selection != VALUE_LIST &&
1880 template_selection != COMPLEMENTED_LIST)
1881 TTCN_error("Accessing a list element of a non-list octetstring template.");
1882 if (list_index >= value_list.n_values)
1883 TTCN_error("Index overflow in an octetstring value list template.");
1884 return value_list.list_value[list_index];
1885 }
1886
1887 void OCTETSTRING_template::log() const
1888 {
1889 switch (template_selection) {
1890 case SPECIFIC_VALUE:
1891 single_value.log();
1892 break;
1893 case COMPLEMENTED_LIST:
1894 TTCN_Logger::log_event_str("complement ");
1895 // no break
1896 case VALUE_LIST:
1897 TTCN_Logger::log_char('(');
1898 for(unsigned int i = 0; i < value_list.n_values; i++) {
1899 if (i > 0) TTCN_Logger::log_event_str(", ");
1900 value_list.list_value[i].log();
1901 }
1902 TTCN_Logger::log_char(')');
1903 break;
1904 case STRING_PATTERN:
1905 TTCN_Logger::log_char('\'');
1906 for (unsigned int i = 0; i < pattern_value->n_elements; i++) {
1907 unsigned short pattern = pattern_value->elements_ptr[i];
1908 if (pattern < 256) TTCN_Logger::log_octet(pattern);
1909 else if (pattern == 256) TTCN_Logger::log_char('?');
1910 else if (pattern == 257) TTCN_Logger::log_char('*');
1911 else TTCN_Logger::log_event_str("<unknown>");
1912 }
1913 TTCN_Logger::log_event_str("'O");
1914 break;
1915 default:
1916 log_generic();
1917 break;
1918 }
1919 log_restricted();
1920 log_ifpresent();
1921 }
1922
1923 void OCTETSTRING_template::log_match(const OCTETSTRING& match_value,
1924 boolean /* legacy */) const
1925 {
1926 if (TTCN_Logger::VERBOSITY_COMPACT == TTCN_Logger::get_matching_verbosity()
1927 && TTCN_Logger::get_logmatch_buffer_len() != 0) {
1928 TTCN_Logger::print_logmatch_buffer();
1929 TTCN_Logger::log_event_str(" := ");
1930 }
1931 match_value.log();
1932 TTCN_Logger::log_event_str(" with ");
1933 log();
1934 if (match(match_value)) TTCN_Logger::log_event_str(" matched");
1935 else TTCN_Logger::log_event_str(" unmatched");
1936 }
1937
1938 void OCTETSTRING_template::set_param(Module_Param& param) {
1939 param.basic_check(Module_Param::BC_TEMPLATE|Module_Param::BC_LIST, "octetstring template");
1940 Module_Param_Ptr mp = &param;
1941 if (param.get_type() == Module_Param::MP_Reference) {
1942 mp = param.get_referenced_param();
1943 }
1944 switch (mp->get_type()) {
1945 case Module_Param::MP_Omit:
1946 *this = OMIT_VALUE;
1947 break;
1948 case Module_Param::MP_Any:
1949 *this = ANY_VALUE;
1950 break;
1951 case Module_Param::MP_AnyOrNone:
1952 *this = ANY_OR_OMIT;
1953 break;
1954 case Module_Param::MP_List_Template:
1955 case Module_Param::MP_ComplementList_Template: {
1956 OCTETSTRING_template temp;
1957 temp.set_type(mp->get_type() == Module_Param::MP_List_Template ?
1958 VALUE_LIST : COMPLEMENTED_LIST, mp->get_size());
1959 for (size_t i=0; i<mp->get_size(); i++) {
1960 temp.list_item(i).set_param(*mp->get_elem(i));
1961 }
1962 *this = temp;
1963 break; }
1964 case Module_Param::MP_Octetstring:
1965 *this = OCTETSTRING(mp->get_string_size(), (unsigned char*)mp->get_string_data());
1966 break;
1967 case Module_Param::MP_Octetstring_Template:
1968 *this = OCTETSTRING_template(mp->get_string_size(), (unsigned short*)mp->get_string_data());
1969 break;
1970 case Module_Param::MP_Expression:
1971 if (mp->get_expr_type() == Module_Param::EXPR_CONCATENATE) {
1972 OCTETSTRING operand1, operand2;
1973 operand1.set_param(*mp->get_operand1());
1974 operand2.set_param(*mp->get_operand2());
1975 *this = operand1 + operand2;
1976 }
1977 else {
1978 param.expr_type_error("a bitstring");
1979 }
1980 break;
1981 default:
1982 param.type_error("octetstring template");
1983 }
1984 is_ifpresent = param.get_ifpresent() || mp->get_ifpresent();
1985 if (param.get_length_restriction() != NULL) {
1986 set_length_range(param);
1987 }
1988 else {
1989 set_length_range(*mp);
1990 }
1991 }
1992
1993 Module_Param* OCTETSTRING_template::get_param(Module_Param_Name& param_name) const
1994 {
1995 Module_Param* mp = NULL;
1996 switch (template_selection) {
1997 case UNINITIALIZED_TEMPLATE:
1998 mp = new Module_Param_Unbound();
1999 break;
2000 case OMIT_VALUE:
2001 mp = new Module_Param_Omit();
2002 break;
2003 case ANY_VALUE:
2004 mp = new Module_Param_Any();
2005 break;
2006 case ANY_OR_OMIT:
2007 mp = new Module_Param_AnyOrNone();
2008 break;
2009 case SPECIFIC_VALUE:
2010 mp = single_value.get_param(param_name);
2011 break;
2012 case VALUE_LIST:
2013 case COMPLEMENTED_LIST: {
2014 if (template_selection == VALUE_LIST) {
2015 mp = new Module_Param_List_Template();
2016 }
2017 else {
2018 mp = new Module_Param_ComplementList_Template();
2019 }
2020 for (size_t i = 0; i < value_list.n_values; ++i) {
2021 mp->add_elem(value_list.list_value[i].get_param(param_name));
2022 }
2023 break; }
2024 case STRING_PATTERN: {
2025 unsigned short* val_cpy = (unsigned short*)Malloc(pattern_value->n_elements *
2026 sizeof(unsigned short));
2027 memcpy(val_cpy, pattern_value->elements_ptr, pattern_value->n_elements *
2028 sizeof(unsigned short));
2029 mp = new Module_Param_Octetstring_Template(pattern_value->n_elements, val_cpy);
2030 break; }
2031 default:
2032 break;
2033 }
2034 if (is_ifpresent) {
2035 mp->set_ifpresent();
2036 }
2037 mp->set_length_restriction(get_length_range());
2038 return mp;
2039 }
2040
2041 void OCTETSTRING_template::encode_text(Text_Buf& text_buf) const
2042 {
2043 encode_text_restricted(text_buf);
2044 switch (template_selection) {
2045 case OMIT_VALUE:
2046 case ANY_VALUE:
2047 case ANY_OR_OMIT:
2048 break;
2049 case SPECIFIC_VALUE:
2050 single_value.encode_text(text_buf);
2051 break;
2052 case VALUE_LIST:
2053 case COMPLEMENTED_LIST:
2054 text_buf.push_int(value_list.n_values);
2055 for (unsigned int i = 0; i < value_list.n_values; i++)
2056 value_list.list_value[i].encode_text(text_buf);
2057 break;
2058 case STRING_PATTERN:
2059 text_buf.push_int(pattern_value->n_elements);
2060 for (unsigned int i = 0; i < pattern_value->n_elements; i++)
2061 text_buf.push_int(pattern_value->elements_ptr[i]);
2062 break;
2063 default:
2064 TTCN_error("Text encoder: Encoding an uninitialized/unsupported "
2065 "octetstring template.");
2066 }
2067 }
2068
2069 void OCTETSTRING_template::decode_text(Text_Buf& text_buf)
2070 {
2071 clean_up();
2072 decode_text_restricted(text_buf);
2073 switch (template_selection) {
2074 case OMIT_VALUE:
2075 case ANY_VALUE:
2076 case ANY_OR_OMIT:
2077 break;
2078 case SPECIFIC_VALUE:
2079 single_value.decode_text(text_buf);
2080 break;
2081 case VALUE_LIST:
2082 case COMPLEMENTED_LIST:
2083 value_list.n_values = text_buf.pull_int().get_val();
2084 value_list.list_value = new OCTETSTRING_template[value_list.n_values];
2085 for (unsigned int i = 0; i < value_list.n_values; i++)
2086 value_list.list_value[i].decode_text(text_buf);
2087 break;
2088 case STRING_PATTERN: {
2089 unsigned int n_elements = text_buf.pull_int().get_val();
2090 pattern_value = (octetstring_pattern_struct*)
2091 Malloc(sizeof(octetstring_pattern_struct) + (n_elements - 1) *
2092 sizeof(unsigned short));
2093 pattern_value->ref_count = 1;
2094 pattern_value->n_elements = n_elements;
2095 for (unsigned int i = 0; i < n_elements; i++)
2096 pattern_value->elements_ptr[i] = text_buf.pull_int().get_val();
2097 break;}
2098 default:
2099 TTCN_error("Text decoder: An unknown/unsupported selection was "
2100 "received for an octetstring template.");
2101 }
2102 }
2103
2104 boolean OCTETSTRING_template::is_present(boolean legacy /* = FALSE */) const
2105 {
2106 if (template_selection==UNINITIALIZED_TEMPLATE) return FALSE;
2107 return !match_omit(legacy);
2108 }
2109
2110 boolean OCTETSTRING_template::match_omit(boolean legacy /* = FALSE */) const
2111 {
2112 if (is_ifpresent) return TRUE;
2113 switch (template_selection) {
2114 case OMIT_VALUE:
2115 case ANY_OR_OMIT:
2116 return TRUE;
2117 case VALUE_LIST:
2118 case COMPLEMENTED_LIST:
2119 if (legacy) {
2120 // legacy behavior: 'omit' can appear in the value/complement list
2121 for (unsigned int i=0; i<value_list.n_values; i++)
2122 if (value_list.list_value[i].match_omit())
2123 return template_selection==VALUE_LIST;
2124 return template_selection==COMPLEMENTED_LIST;
2125 }
2126 // else fall through
2127 default:
2128 return FALSE;
2129 }
2130 return FALSE;
2131 }
2132
2133 #ifndef TITAN_RUNTIME_2
2134 void OCTETSTRING_template::check_restriction(template_res t_res, const char* t_name,
2135 boolean legacy /* = FALSE */) const
2136 {
2137 if (template_selection==UNINITIALIZED_TEMPLATE) return;
2138 switch ((t_name&&(t_res==TR_VALUE))?TR_OMIT:t_res) {
2139 case TR_VALUE:
2140 if (!is_ifpresent && template_selection==SPECIFIC_VALUE) return;
2141 break;
2142 case TR_OMIT:
2143 if (!is_ifpresent && (template_selection==OMIT_VALUE ||
2144 template_selection==SPECIFIC_VALUE)) return;
2145 break;
2146 case TR_PRESENT:
2147 if (!match_omit(legacy)) return;
2148 break;
2149 default:
2150 return;
2151 }
2152 TTCN_error("Restriction `%s' on template of type %s violated.",
2153 get_res_name(t_res), t_name ? t_name : "octetstring");
2154 }
2155 #endif
This page took 0.086616 seconds and 5 git commands to generate.