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 ///////////////////////////////////////////////////////////////////////////////
10 #include "../common/dbgnew.hh"
13 #include "../common/static_check.h"
16 static const size_t MIN_COMPONENTS
= 2;
18 struct OBJID::objid_struct
{
19 unsigned int ref_count
;
20 int n_components
; ///< number of elements in \a components_ptr (min. 2)
21 int overflow_idx
; ///< index of the first overflow, or -1
22 objid_element components_ptr
[MIN_COMPONENTS
];
25 #define OBJID_FMT "%u"
26 //#define OBJID_FMT "%lu"
28 void OBJID::init_struct(int n_components
)
30 if (n_components
< 0) {
32 TTCN_error("Initializing an objid value with a negative number of "
35 // TODO check n_components >= 2
36 val_ptr
= (objid_struct
*)Malloc(sizeof(objid_struct
)
37 + (n_components
- MIN_COMPONENTS
) * sizeof(objid_element
));
38 val_ptr
->ref_count
= 1;
39 val_ptr
->n_components
= n_components
;
40 val_ptr
->overflow_idx
= -1;
43 void OBJID::copy_value()
45 if (val_ptr
!= NULL
&& val_ptr
->ref_count
> 1) {
46 objid_struct
*old_ptr
= val_ptr
;
48 init_struct(old_ptr
->n_components
); // val_ptr reallocated
49 memcpy(val_ptr
->components_ptr
, old_ptr
->components_ptr
,
50 old_ptr
->n_components
* sizeof(objid_element
));
51 val_ptr
->overflow_idx
= old_ptr
->overflow_idx
;
55 void OBJID::clean_up()
57 if (val_ptr
!= NULL
) {
58 if (val_ptr
->ref_count
> 1) val_ptr
->ref_count
--;
59 else if (val_ptr
->ref_count
== 1) Free(val_ptr
);
60 else TTCN_error("Internal error: Invalid reference counter in an objid "
68 val_ptr
= NULL
; // unbound
71 OBJID::OBJID(int init_n_components
, ...)
73 init_struct(init_n_components
);
75 va_start(ap
, init_n_components
);
76 for (int i
= 0; i
< init_n_components
; i
++) {
77 val_ptr
->components_ptr
[i
] = va_arg(ap
, objid_element
);
83 OBJID::OBJID(int init_n_components
, const objid_element
*init_components
)
85 init_struct(init_n_components
);
86 memcpy(val_ptr
->components_ptr
, init_components
, init_n_components
*
87 sizeof(objid_element
));
90 OBJID::OBJID(const OBJID
& other_value
)
91 : Base_Type(other_value
)
93 if (other_value
.val_ptr
== NULL
)
94 TTCN_error("Copying an unbound objid value.");
95 val_ptr
= other_value
.val_ptr
;
104 OBJID
& OBJID::operator=(const OBJID
& other_value
)
106 if (other_value
.val_ptr
== NULL
)
107 TTCN_error("Assignment of an unbound objid value.");
108 if (&other_value
!= this) {
110 val_ptr
= other_value
.val_ptr
;
111 val_ptr
->ref_count
++;
116 boolean
OBJID::operator==(const OBJID
& other_value
) const
118 if (val_ptr
== NULL
) TTCN_error("The left operand of comparison is an "
119 "unbound objid value.");
120 if (other_value
.val_ptr
== NULL
) TTCN_error("The right operand of comparison "
121 "is an unbound objid value.");
122 if (val_ptr
->n_components
!= other_value
.val_ptr
->n_components
) return FALSE
;
123 if (val_ptr
->overflow_idx
!= other_value
.val_ptr
->overflow_idx
) return FALSE
;
124 return !memcmp(val_ptr
->components_ptr
,
125 other_value
.val_ptr
->components_ptr
,
126 val_ptr
->n_components
* sizeof(objid_element
));
129 OBJID::objid_element
& OBJID::operator[](int index_value
)
131 if (val_ptr
== NULL
) {
132 if (index_value
!= 0)
133 TTCN_error("Accessing a component of an unbound objid value.");
135 return val_ptr
->components_ptr
[0];
137 if (index_value
< 0) TTCN_error("Accessing an objid component using "
138 "a negative index (%d).", index_value
);
139 int n_components
= val_ptr
->n_components
;
140 if (index_value
> n_components
) TTCN_error("Index overflow when accessing "
141 "an objid component: the index is %d, but the value has only %d "
142 "components.", index_value
, n_components
);
143 else if (index_value
== n_components
) {
144 if (val_ptr
->ref_count
== 1) {
145 val_ptr
= (objid_struct
*)
146 Realloc(val_ptr
, sizeof(objid_struct
)
147 + n_components
* sizeof(objid_element
));
148 val_ptr
->n_components
++;
150 objid_struct
*old_ptr
= val_ptr
;
151 old_ptr
->ref_count
--;
152 init_struct(n_components
+ 1);
153 memcpy(val_ptr
->components_ptr
, old_ptr
->components_ptr
,
154 n_components
* sizeof(objid_element
));
157 return val_ptr
->components_ptr
[index_value
];
161 OBJID::objid_element
OBJID::operator[](int index_value
) const
164 TTCN_error("Accessing a component of an unbound objid value.");
166 TTCN_error("Accessing an objid component using a negative index (%d).",
168 if (index_value
>= val_ptr
->n_components
) TTCN_error("Index overflow when "
169 "accessing an objid component: the index is %d, but the value has only %d "
170 "components.", index_value
, val_ptr
->n_components
);
171 return val_ptr
->components_ptr
[index_value
];
174 int OBJID::size_of() const
177 TTCN_error("Getting the size of an unbound objid value.");
178 return val_ptr
->n_components
;
181 OBJID::operator const objid_element
*() const
184 TTCN_error("Casting an unbound objid value to const int*.");
185 return val_ptr
->components_ptr
;
188 OBJID::objid_element
OBJID::from_INTEGER(const INTEGER
& p_int
)
190 int_val_t i_val
= p_int
.get_val();
191 if (i_val
.is_negative()) {
192 TTCN_error("An OBJECT IDENTIFIER component cannot be negative");
194 if (!i_val
.is_native()) {
195 TTCN_error("The value of an OBJECT IDENTIFIER component cannot exceed %u",
198 return (OBJID::objid_element
)i_val
.get_val();
201 void OBJID::log() const
203 if (val_ptr
!= NULL
) {
204 TTCN_Logger::log_event_str("objid { ");
205 for (int i
= 0; i
< val_ptr
->n_components
; i
++) {
206 if (i
== val_ptr
->overflow_idx
) {
207 TTCN_Logger::log_event_str("overflow:");
210 TTCN_Logger::log_event(OBJID_FMT
" ", val_ptr
->components_ptr
[i
]);
212 TTCN_Logger::log_char('}');
213 } else TTCN_Logger::log_event_unbound();
216 void OBJID::set_param(Module_Param
& param
) {
217 param
.basic_check(Module_Param::BC_VALUE
, "objid value");
218 if (param
.get_type()!=Module_Param::MP_Objid
) param
.type_error("objid value");
219 if (sizeof(objid_element
)!=sizeof(int)) TTCN_error("Internal error: OBJID::set_param()");
221 init_struct(param
.get_string_size());
222 memcpy(val_ptr
->components_ptr
, param
.get_string_data(), val_ptr
->n_components
* sizeof(objid_element
));
225 void OBJID::encode_text(Text_Buf
& text_buf
) const
228 TTCN_error("Text encoder: Encoding an unbound objid value.");
229 text_buf
.push_int(val_ptr
->n_components
);
230 for (int i
= 0; i
< val_ptr
->n_components
; i
++)
231 text_buf
.push_int(val_ptr
->components_ptr
[i
]);
234 void OBJID::decode_text(Text_Buf
& text_buf
)
236 int n_components
= text_buf
.pull_int().get_val();
237 if (n_components
< 0) TTCN_error("Text decoder: Negative number of "
238 "components was received for an objid value.");
240 init_struct(n_components
);
241 for (int i
= 0; i
< n_components
; i
++)
242 val_ptr
->components_ptr
[i
] = text_buf
.pull_int().get_val();
245 void OBJID::encode(const TTCN_Typedescriptor_t
& p_td
, TTCN_Buffer
& p_buf
,
246 TTCN_EncDec::coding_t p_coding
, ...) const
249 va_start(pvar
, p_coding
);
251 case TTCN_EncDec::CT_BER
: {
252 TTCN_EncDec_ErrorContext
ec("While BER-encoding type '%s': ", p_td
.name
);
253 unsigned BER_coding
=va_arg(pvar
, unsigned);
254 BER_encode_chk_coding(BER_coding
);
255 ASN_BER_TLV_t
*tlv
=BER_encode_TLV(p_td
, BER_coding
);
256 tlv
->put_in_buffer(p_buf
);
257 ASN_BER_TLV_t::destruct(tlv
);
259 case TTCN_EncDec::CT_RAW
: {
260 TTCN_EncDec_ErrorContext
ec("While RAW-encoding type '%s': ", p_td
.name
);
261 TTCN_EncDec_ErrorContext::error_internal
262 ("No RAW descriptor available for type '%s'.", p_td
.name
);
264 case TTCN_EncDec::CT_XER
: {
265 TTCN_EncDec_ErrorContext
ec("While XER-encoding type '%s': ", p_td
.name
);
266 unsigned XER_coding
=va_arg(pvar
, unsigned);
267 XER_encode(*p_td
.xer
, p_buf
, XER_coding
, 0);
270 TTCN_error("Unknown coding method requested to encode type '%s'",
276 void OBJID::decode(const TTCN_Typedescriptor_t
& p_td
, TTCN_Buffer
& p_buf
,
277 TTCN_EncDec::coding_t p_coding
, ...)
280 va_start(pvar
, p_coding
);
282 case TTCN_EncDec::CT_BER
: {
283 TTCN_EncDec_ErrorContext
ec("While BER-decoding type '%s': ", p_td
.name
);
284 unsigned L_form
=va_arg(pvar
, unsigned);
286 BER_decode_str2TLV(p_buf
, tlv
, L_form
);
287 BER_decode_TLV(p_td
, tlv
, L_form
);
288 if(tlv
.isComplete
) p_buf
.increase_pos(tlv
.get_len());
290 case TTCN_EncDec::CT_RAW
: {
291 TTCN_EncDec_ErrorContext
ec("While RAW-decoding type '%s': ", p_td
.name
);
292 TTCN_EncDec_ErrorContext::error_internal
293 ("No RAW descriptor available for type '%s'.", p_td
.name
);
295 case TTCN_EncDec::CT_XER
: {
296 TTCN_EncDec_ErrorContext
ec("While XER-encoding type '%s': ", p_td
.name
);
297 unsigned XER_coding
=va_arg(pvar
, unsigned);
298 XmlReaderWrap
reader(p_buf
);
299 int success
= reader
.Read();
300 for (; success
==1; success
=reader
.Read()) {
301 int type
= reader
.NodeType();
302 if (type
==XML_READER_TYPE_ELEMENT
)
305 XER_decode(*p_td
.xer
, reader
, XER_coding
);
306 size_t bytes
= reader
.ByteConsumed();
307 p_buf
.set_pos(bytes
);
310 TTCN_error("Unknown coding method requested to decode type '%s'",
317 OBJID::BER_encode_TLV(const TTCN_Typedescriptor_t
& p_td
,
318 unsigned p_coding
) const
321 ASN_BER_TLV_t
*new_tlv
=BER_encode_chk_bound(is_bound());
324 switch(p_td
.asnbasetype
) {
325 case TTCN_Typedescriptor_t::OBJID
:
326 if(val_ptr
->n_components
<2)
327 TTCN_EncDec_ErrorContext::error_internal
328 ("OBJID must have at least 2 components.");
329 V_len
=(min_needed_bits(val_ptr
->components_ptr
[0]*40
330 +val_ptr
->components_ptr
[1])+6)/7;
331 for(int i
=2; i
<val_ptr
->n_components
; i
++)
332 V_len
+=(min_needed_bits(val_ptr
->components_ptr
[i
])+6)/7;
334 case TTCN_Typedescriptor_t::ROID
:
335 for(int i
=0; i
<val_ptr
->n_components
; i
++)
336 V_len
+=(min_needed_bits(val_ptr
->components_ptr
[i
])+6)/7;
339 TTCN_EncDec_ErrorContext::error_internal
340 ("Missing/wrong basetype info for type '%s'.", p_td
.name
);
342 new_tlv
=ASN_BER_TLV_t::construct(V_len
, NULL
);
343 unsigned char *Vptr
=new_tlv
->V
.str
.Vstr
;
344 for(int i
=0; i
<val_ptr
->n_components
; i
++) {
346 if(i
==0 && p_td
.asnbasetype
==TTCN_Typedescriptor_t::OBJID
) {
347 ul
=val_ptr
->components_ptr
[0]*40+val_ptr
->components_ptr
[1];
350 else ul
=val_ptr
->components_ptr
[i
];
351 size_t noo
=(min_needed_bits(ul
)+6)/7;
352 for(size_t j
=noo
; j
>0; j
--) {
353 Vptr
[j
-1]=(ul
& 0x7F) | 0x80;
360 new_tlv
=ASN_BER_V2TLV(new_tlv
, p_td
, p_coding
);
365 boolean
OBJID::BER_decode_TLV(const TTCN_Typedescriptor_t
& p_td
,
366 const ASN_BER_TLV_t
& p_tlv
,
371 ASN_BER_TLV_t stripped_tlv
;
372 BER_decode_strip_tags(*p_td
.ber
, p_tlv
, L_form
, stripped_tlv
);
373 TTCN_EncDec_ErrorContext
ec("While decoding OBJID type: ");
374 stripped_tlv
.chk_constructed_flag(FALSE
);
375 if (!stripped_tlv
.isComplete
) return FALSE
;
376 if (!stripped_tlv
.V_tlvs_selected
&& stripped_tlv
.V
.str
.Vlen
==0) {
377 ec
.error(TTCN_EncDec::ET_INVAL_MSG
, "Length of V-part is 0.");
380 switch(p_td
.asnbasetype
) {
381 case TTCN_Typedescriptor_t::OBJID
:
382 case TTCN_Typedescriptor_t::ROID
:
385 TTCN_EncDec_ErrorContext::error_internal
386 ("Missing/wrong basetype info for type '%s'.", p_td
.name
);
388 unsigned char *Vptr
=stripped_tlv
.V
.str
.Vstr
;
389 boolean eoc
=FALSE
; // end-of-component
391 unsigned long long ull
=0;
392 STATIC_ASSERT(sizeof(ull
) > sizeof(objid_element
));
394 boolean err_repr
=FALSE
;
395 while (Vptr
< stripped_tlv
.V
.str
.Vstr
+ stripped_tlv
.V
.str
.Vlen
) {
397 if ((*Vptr
& 0x80) && err_repr
==FALSE
) { // not-eoc
398 if (ull
& unsigned_llong_7msb
) {
399 ec
.error(TTCN_EncDec::ET_REPR
,
400 "Value of the #%d component is too big.", i
+1);
407 if (i
==0 && p_td
.asnbasetype
==TTCN_Typedescriptor_t::OBJID
) {
408 // first two component of objid
417 (*this)[1]=(int)(ull
-40*(*this)[0]);
420 else { // other components (>2)
421 // objid_element is UINT/ULONG; the result of the cast is Uxxx_MAX.
422 // It's computed at compile time.
423 if(ull
> ((objid_element
)-1)) {
425 ec
.error(TTCN_EncDec::ET_REPR
,
426 "Value of the #%d component is too big.", i
+1);
427 (*this)[i
]=(objid_element
)-1;
428 // remember the first overflow
429 if (val_ptr
->overflow_idx
< 0) val_ptr
->overflow_idx
= i
;
432 (*this)[i
]=(objid_element
)ull
;
442 ec
.error(TTCN_EncDec::ET_INVAL_MSG
,
443 "The last component (#%d) is unterminated.", i
+1);
448 int OBJID::XER_encode(const XERdescriptor_t
& p_td
,
449 TTCN_Buffer
& p_buf
, unsigned int flavor
, int indent
) const
452 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND
,
453 "Encoding an unbound object identifier value.");
455 int encoded_length
=(int)p_buf
.get_len();
457 flavor
|= SIMPLE_TYPE
;
458 flavor
&= ~XER_RECOF
; // object identifier doesn't care
459 begin_xml(p_td
, p_buf
, flavor
, indent
, false);
461 static char str_buf
[64];
462 for (int i
= 0; i
< val_ptr
->n_components
; ++i
) {
463 // output dot before the second and subsequent components
464 if (i
> 0) p_buf
.put_c('.');
465 // output current component
466 int str_len
= snprintf(str_buf
, sizeof(str_buf
), OBJID_FMT
,
467 val_ptr
->components_ptr
[i
]);
468 if (str_len
< 0 || str_len
>= (int)sizeof(str_buf
)) {
469 TTCN_error("Internal error: system call snprintf() returned "
470 "unexpected status code %d when converting value " OBJID_FMT
,
471 str_len
, val_ptr
->components_ptr
[i
]);
473 else p_buf
.put_s(str_len
, (const unsigned char*)str_buf
);
476 end_xml(p_td
, p_buf
, flavor
, indent
, false);
478 return (int)p_buf
.get_len() - encoded_length
;
481 int OBJID::XER_decode(const XERdescriptor_t
& p_td
, XmlReaderWrap
& reader
,
484 int exer
= is_exer(flavor
);
485 int success
= reader
.Ok(), depth
= -1;
486 for (; success
== 1; success
= reader
.Read()) {
487 int type
= reader
.NodeType();
488 if (XML_READER_TYPE_ELEMENT
== type
) {
489 verify_name(reader
, p_td
, exer
);
490 depth
= reader
.Depth();
495 char * val
= (char *)reader
.ReadString(); // We own this (writable) string
497 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG
, "Bogus object identifier");
500 // Count dots to find number of components. (1 dot = 2 components, etc.)
503 for (p
= val
; *p
!= 0; ++p
) {
504 if (*p
== '.') ++comps
;
506 // p now points at the end of the string. If it was empty, then there were
507 // no components; compensate the fact that we started at 1.
508 init_struct((p
!= val
) ? comps
: 0);
512 for (beg
= val
; beg
< p
; ++beg
) {
514 long ret
= strtol(beg
, &end
, 10);
517 // TODO check value for too big ?
518 (*this)[comps
++] = ret
;
519 beg
= end
; // move to the dot; will move past it when incremented
524 for (success
= reader
.Read(); success
== 1; success
= reader
.Read()) {
525 int type
= reader
.NodeType();
526 if (XML_READER_TYPE_END_ELEMENT
== type
) {
527 verify_end(reader
, p_td
, depth
, exer
);
532 return 1; // decode successful
536 void OBJID_template::clean_up()
538 if (template_selection
== VALUE_LIST
||
539 template_selection
== COMPLEMENTED_LIST
) delete [] value_list
.list_value
;
540 template_selection
= UNINITIALIZED_TEMPLATE
;
543 void OBJID_template::copy_template(const OBJID_template
& other_value
)
545 switch (other_value
.template_selection
) {
547 single_value
= other_value
.single_value
;
554 case COMPLEMENTED_LIST
:
555 value_list
.n_values
= other_value
.value_list
.n_values
;
556 value_list
.list_value
= new OBJID_template
[value_list
.n_values
];
557 for (unsigned int i
= 0; i
< value_list
.n_values
; i
++)
558 value_list
.list_value
[i
].copy_template(
559 other_value
.value_list
.list_value
[i
]);
562 TTCN_error("Copying an uninitialized/unsupported objid template.");
564 set_selection(other_value
);
567 OBJID_template::OBJID_template()
572 OBJID_template::OBJID_template(template_sel other_value
)
573 : Base_Template(other_value
)
575 check_single_selection(other_value
);
578 OBJID_template::OBJID_template(const OBJID
& other_value
)
579 : Base_Template(SPECIFIC_VALUE
), single_value(other_value
)
584 OBJID_template::OBJID_template(const OPTIONAL
<OBJID
>& other_value
)
586 switch (other_value
.get_selection()) {
587 case OPTIONAL_PRESENT
:
588 set_selection(SPECIFIC_VALUE
);
589 single_value
= (const OBJID
&)other_value
;
592 set_selection(OMIT_VALUE
);
595 TTCN_error("Creating an objid template from an unbound optional field.");
599 OBJID_template::OBJID_template(const OBJID_template
& other_value
)
602 copy_template(other_value
);
605 OBJID_template::~OBJID_template()
610 OBJID_template
& OBJID_template::operator=(template_sel other_value
)
612 check_single_selection(other_value
);
614 set_selection(other_value
);
618 OBJID_template
& OBJID_template::operator=(const OBJID
& other_value
)
620 if (!other_value
.is_bound())
621 TTCN_error("Assignment of an unbound objid value to a template.");
623 set_selection(SPECIFIC_VALUE
);
624 single_value
= other_value
;
628 OBJID_template
& OBJID_template::operator=(const OPTIONAL
<OBJID
>& other_value
)
631 switch (other_value
.get_selection()) {
632 case OPTIONAL_PRESENT
:
633 set_selection(SPECIFIC_VALUE
);
634 single_value
= (const OBJID
&)other_value
;
637 set_selection(OMIT_VALUE
);
640 TTCN_error("Assignment of an unbound optional field to an objid template.");
645 OBJID_template
& OBJID_template::operator=(const OBJID_template
& other_value
)
647 if (&other_value
!= this) {
649 copy_template(other_value
);
654 boolean
OBJID_template::match(const OBJID
& other_value
) const
656 if (!other_value
.is_bound()) return FALSE
;
657 switch (template_selection
) {
659 return single_value
== other_value
;
666 case COMPLEMENTED_LIST
:
667 for (unsigned int i
= 0; i
< value_list
.n_values
; i
++)
668 if (value_list
.list_value
[i
].match(other_value
))
669 return template_selection
== VALUE_LIST
;
670 return template_selection
== COMPLEMENTED_LIST
;
672 TTCN_error("Matching with an uninitialized/unsupported objid template.");
677 const OBJID
& OBJID_template::valueof() const
679 if (template_selection
!= SPECIFIC_VALUE
|| is_ifpresent
)
680 TTCN_error("Performing a valueof "
681 "or send operation on a non-specific objid template.");
685 int OBJID_template::size_of() const
687 switch (template_selection
)
690 return single_value
.size_of();
692 TTCN_error("Performing sizeof() operation on an objid template "
693 "containing omit value.");
696 TTCN_error("Performing sizeof() operation on a */? objid template.");
699 if (value_list
.n_values
<1)
700 TTCN_error("Internal error: "
701 "Performing sizeof() operation on an objid template "
702 "containing an empty list.");
703 int item_size
= value_list
.list_value
[0].size_of();
704 for (unsigned int i
= 1; i
< value_list
.n_values
; i
++) {
705 if (value_list
.list_value
[i
].size_of()!=item_size
)
706 TTCN_error("Performing sizeof() operation on an objid template "
707 "containing a value list with different sizes.");
711 case COMPLEMENTED_LIST
:
712 TTCN_error("Performing sizeof() operation on an objid template "
713 "containing complemented list.");
715 TTCN_error("Performing sizeof() operation on an "
716 "uninitialized/unsupported objid template.");
721 void OBJID_template::set_type(template_sel template_type
,
722 unsigned int list_length
)
724 if (template_type
!= VALUE_LIST
&& template_type
!= COMPLEMENTED_LIST
)
725 TTCN_error("Setting an invalid list type for an objid template.");
727 set_selection(template_type
);
728 value_list
.n_values
= list_length
;
729 value_list
.list_value
= new OBJID_template
[list_length
];
732 OBJID_template
& OBJID_template::list_item(unsigned int list_index
)
734 if (template_selection
!= VALUE_LIST
&&
735 template_selection
!= COMPLEMENTED_LIST
)
736 TTCN_error("Accessing a list element of a non-list objid template.");
737 if (list_index
>= value_list
.n_values
)
738 TTCN_error("Index overflow in an objid value list template.");
739 return value_list
.list_value
[list_index
];
742 void OBJID_template::log() const
744 switch (template_selection
) {
748 case COMPLEMENTED_LIST
:
749 TTCN_Logger::log_event_str("complement ");
752 TTCN_Logger::log_char('(');
753 for(unsigned int i
= 0; i
< value_list
.n_values
; i
++) {
754 if (i
> 0) TTCN_Logger::log_event_str(", ");
755 value_list
.list_value
[i
].log();
757 TTCN_Logger::log_char(')');
766 void OBJID_template::log_match(const OBJID
& match_value
) const
768 if (TTCN_Logger::VERBOSITY_COMPACT
== TTCN_Logger::get_matching_verbosity()
769 && TTCN_Logger::get_logmatch_buffer_len() != 0) {
770 TTCN_Logger::print_logmatch_buffer();
771 TTCN_Logger::log_event_str(" := ");
774 TTCN_Logger::log_event_str(" with ");
776 if (match(match_value
)) TTCN_Logger::log_event_str(" matched");
777 else TTCN_Logger::log_event_str(" unmatched");
780 void OBJID_template::set_param(Module_Param
& param
) {
781 param
.basic_check(Module_Param::BC_TEMPLATE
, "objid template");
782 switch (param
.get_type()) {
783 case Module_Param::MP_Omit
:
786 case Module_Param::MP_Any
:
789 case Module_Param::MP_AnyOrNone
:
792 case Module_Param::MP_List_Template
:
793 case Module_Param::MP_ComplementList_Template
:
794 set_type(param
.get_type()==Module_Param::MP_List_Template
? VALUE_LIST
: COMPLEMENTED_LIST
, param
.get_size());
795 for (size_t i
=0; i
<param
.get_size(); i
++) {
796 list_item(i
).set_param(*param
.get_elem(i
));
799 case Module_Param::MP_Objid
:
800 if (sizeof(OBJID::objid_element
)!=sizeof(int)) TTCN_error("Internal error: OBJID_template::set_param()");
801 *this = OBJID(param
.get_string_size(), (OBJID::objid_element
*)param
.get_string_data());
803 //case Module_Param::MP_Objid_Template:
807 param
.type_error("objid template");
809 is_ifpresent
= param
.get_ifpresent();
812 void OBJID_template::encode_text(Text_Buf
& text_buf
) const
814 encode_text_base(text_buf
);
815 switch (template_selection
) {
821 single_value
.encode_text(text_buf
);
824 case COMPLEMENTED_LIST
:
825 text_buf
.push_int(value_list
.n_values
);
826 for (unsigned int i
= 0; i
< value_list
.n_values
; i
++)
827 value_list
.list_value
[i
].encode_text(text_buf
);
830 TTCN_error("Text encoder: Encoding an undefined/unsupported objid "
835 void OBJID_template::decode_text(Text_Buf
& text_buf
)
838 decode_text_base(text_buf
);
839 switch (template_selection
) {
845 single_value
.decode_text(text_buf
);
848 case COMPLEMENTED_LIST
:
849 value_list
.n_values
= text_buf
.pull_int().get_val();
850 value_list
.list_value
= new OBJID_template
[value_list
.n_values
];
851 for (unsigned int i
= 0; i
< value_list
.n_values
; i
++)
852 value_list
.list_value
[i
].decode_text(text_buf
);
855 TTCN_error("Text decoder: An unknown/unsupported selection was "
856 "received for an objid template.");
860 boolean
OBJID_template::is_present() const
862 if (template_selection
==UNINITIALIZED_TEMPLATE
) return FALSE
;
863 return !match_omit();
866 boolean
OBJID_template::match_omit() const
868 if (is_ifpresent
) return TRUE
;
869 switch (template_selection
) {
874 case COMPLEMENTED_LIST
:
875 for (unsigned int i
=0; i
<value_list
.n_values
; i
++)
876 if (value_list
.list_value
[i
].match_omit())
877 return template_selection
==VALUE_LIST
;
878 return template_selection
==COMPLEMENTED_LIST
;
885 #ifndef TITAN_RUNTIME_2
886 void OBJID_template::check_restriction(template_res t_res
, const char* t_name
) const
888 if (template_selection
==UNINITIALIZED_TEMPLATE
) return;
889 switch ((t_name
&&(t_res
==TR_VALUE
))?TR_OMIT
:t_res
) {
891 if (!is_ifpresent
&& template_selection
==SPECIFIC_VALUE
) return;
894 if (!is_ifpresent
&& (template_selection
==OMIT_VALUE
||
895 template_selection
==SPECIFIC_VALUE
)) return;
898 if (!match_omit()) return;
903 TTCN_error("Restriction `%s' on template of type %s violated.",
904 get_res_name(t_res
), t_name
? t_name
: "objid");