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 ///////////////////////////////////////////////////////////////////////////////
14 #include "Module_list.hh"
18 #ifdef TITAN_RUNTIME_2
21 #include "Charstring.hh"
22 #include "Universal_charstring.hh"
25 ////////////////////////////////////////////////////////////////////////////////
27 const Erroneous_values_t
* Erroneous_descriptor_t::get_field_err_values(int field_idx
) const
29 for (int i
=0; i
<values_size
; i
++) {
30 if (values_vec
[i
].field_index
==field_idx
) return (values_vec
+i
);
31 if (values_vec
[i
].field_index
>field_idx
) return NULL
;
36 const Erroneous_values_t
* Erroneous_descriptor_t::next_field_err_values(
37 const int field_idx
, int& values_idx
) const
39 const Erroneous_values_t
* err_vals
= NULL
;
40 if ( (values_idx
<values_size
) && (values_vec
[values_idx
].field_index
==field_idx
) ) {
41 err_vals
= values_vec
+values_idx
;
47 const Erroneous_descriptor_t
* Erroneous_descriptor_t::get_field_emb_descr(int field_idx
) const
49 for (int i
=0; i
<embedded_size
; i
++) {
50 if (embedded_vec
[i
].field_index
==field_idx
) return (embedded_vec
+i
);
51 if (embedded_vec
[i
].field_index
>field_idx
) return NULL
;
56 const Erroneous_descriptor_t
* Erroneous_descriptor_t::next_field_emb_descr(
57 const int field_idx
, int& edescr_idx
) const
59 const Erroneous_descriptor_t
* emb_descr
= NULL
;
60 if ( (edescr_idx
<embedded_size
) && (embedded_vec
[edescr_idx
].field_index
==field_idx
) ) {
61 emb_descr
= embedded_vec
+edescr_idx
;
67 void Erroneous_descriptor_t::log() const
69 TTCN_Logger::log_event_str(" with erroneous { ");
71 TTCN_Logger::log_event_str("}");
74 void Erroneous_descriptor_t::log_() const
76 if (omit_before
!=-1) {
77 if (omit_before_qualifier
==NULL
) TTCN_error(
78 "internal error: Erroneous_descriptor_t::log()");
79 TTCN_Logger::log_event("{ before %s := omit all } ", omit_before_qualifier
);
82 if (omit_after_qualifier
==NULL
) TTCN_error(
83 "internal error: Erroneous_descriptor_t::log()");
84 TTCN_Logger::log_event("{ after %s := omit all } ", omit_after_qualifier
);
86 for (int i
=0; i
<values_size
; i
++) {
87 if (values_vec
[i
].field_qualifier
==NULL
) TTCN_error(
88 "internal error: Erroneous_descriptor_t::log()");
89 if (values_vec
[i
].before
) {
90 TTCN_Logger::log_event("{ before%s %s := ",
91 values_vec
[i
].before
->raw
? "(raw)" : "", values_vec
[i
].field_qualifier
);
92 if (values_vec
[i
].before
->errval
) values_vec
[i
].before
->errval
->log();
93 else TTCN_Logger::log_event_str("omit");
94 TTCN_Logger::log_event_str(" } ");
96 if (values_vec
[i
].value
) {
97 TTCN_Logger::log_event("{ value%s %s := ",
98 values_vec
[i
].value
->raw
? "(raw)" : "", values_vec
[i
].field_qualifier
);
99 if (values_vec
[i
].value
->errval
) values_vec
[i
].value
->errval
->log();
100 else TTCN_Logger::log_event_str("omit");
101 TTCN_Logger::log_event_str(" } ");
103 if (values_vec
[i
].after
) {
104 TTCN_Logger::log_event("{ after%s %s := ",
105 values_vec
[i
].after
->raw
? "(raw)" : "", values_vec
[i
].field_qualifier
);
106 if (values_vec
[i
].after
->errval
) values_vec
[i
].after
->errval
->log();
107 else TTCN_Logger::log_event_str("omit");
108 TTCN_Logger::log_event_str(" } ");
111 for (int i
=0; i
<embedded_size
; i
++) {
112 embedded_vec
[i
].log_();
116 void Base_Type::set_to_omit()
118 TTCN_error("Internal error: trying to set a non-optional field to OMIT.");
121 void Base_Type::set_to_present()
123 TTCN_error("Internal error: calling set_to_present() on a non-optional value.");
126 boolean
Base_Type::is_present() const
131 Base_Type
* Base_Type::get_opt_value()
133 TTCN_error("Internal error: calling get_opt_value() on a non-optional value.");
137 const Base_Type
* Base_Type::get_opt_value() const
139 TTCN_error("Internal error: calling get_opt_value() const on a non-optional value.");
143 ASN_BER_TLV_t
* Base_Type::BER_encode_TLV_negtest(const Erroneous_descriptor_t
* /*p_err_descr*/,
144 const TTCN_Typedescriptor_t
& /*p_td*/, unsigned /*p_coding*/) const
146 TTCN_error("Internal error: calling Base_Type::BER_encode_TLV_negtest().");
150 int Base_Type::TEXT_encode_negtest(const Erroneous_descriptor_t
* /*p_err_descr*/,
151 const TTCN_Typedescriptor_t
& /*p_td*/, TTCN_Buffer
& /*p_buf*/) const
153 TTCN_error("Internal error: calling Base_Type::TEXT_encode_negtest().");
157 ASN_BER_TLV_t
* Base_Type::BER_encode_negtest_raw() const
159 TTCN_error("A value of type %s cannot be used as erroneous raw value for BER encoding.",
160 get_descriptor()->name
);
164 int Base_Type::encode_raw(TTCN_Buffer
&) const
166 TTCN_error("A value of type %s cannot be used as erroneous raw value for encoding.",
167 get_descriptor()->name
);
171 int Base_Type::RAW_encode_negtest_raw(RAW_enc_tree
&) const
173 TTCN_error("A value of type %s cannot be used as erroneous raw value for encoding.",
174 get_descriptor()->name
);
178 int Base_Type::XER_encode_negtest(const Erroneous_descriptor_t
* /*p_err_descr*/,
179 const XERdescriptor_t
& p_td
, TTCN_Buffer
& p_buf
, unsigned int flavor
, int indent
, embed_values_enc_struct_t
*) const
181 return XER_encode(p_td
, p_buf
, flavor
, indent
, 0); // ignore erroneous
184 int Base_Type::RAW_encode_negtest(const Erroneous_descriptor_t
*,
185 const TTCN_Typedescriptor_t
&, RAW_enc_tree
&) const
187 TTCN_error("Internal error: calling Base_Type::RAW_encode_negtest().");
192 #error this is for RT2 only
195 #ifdef TITAN_RUNTIME_2
197 boolean
Record_Of_Type::compare_function(const Record_Of_Type
*left_ptr
,
198 int left_index
, const Record_Of_Type
*right_ptr
, int right_index
)
200 if (left_ptr
->val_ptr
== NULL
)
201 TTCN_error("The left operand of comparison is an unbound value of type %s.",
202 left_ptr
->get_descriptor()->name
);
203 if (right_ptr
->val_ptr
== NULL
)
204 TTCN_error("The right operand of comparison is an unbound value of type %s.",
205 right_ptr
->get_descriptor()->name
);
207 const Base_Type
* elem
= left_ptr
->val_ptr
->value_elements
[left_index
];
208 const Base_Type
* other_elem
= right_ptr
->val_ptr
->value_elements
[right_index
];
210 if (other_elem
!= NULL
) { // both are bound, compare them
211 return elem
->is_equal(other_elem
);
215 else { // elem unbound, they can be equal only if other_elem is unbound too
216 return other_elem
== NULL
;
220 void Record_Of_Type::clean_up()
222 if (val_ptr
!= NULL
) {
223 if (val_ptr
->ref_count
> 1) {
224 val_ptr
->ref_count
--;
227 else if (val_ptr
->ref_count
== 1) {
228 if (NULL
== refd_ind_ptr
) {
229 for (int elem_count
= 0; elem_count
< val_ptr
->n_elements
; elem_count
++) {
230 if (val_ptr
->value_elements
[elem_count
] != NULL
) {
231 delete val_ptr
->value_elements
[elem_count
];
234 free_pointers((void**)val_ptr
->value_elements
);
243 TTCN_error("Internal error: Invalid reference counter in "
244 "a record of/set of value.");
249 Record_Of_Type::Record_Of_Type(null_type
/*other_value*/)
250 : Base_Type(), val_ptr(new recordof_setof_struct
), err_descr(NULL
), refd_ind_ptr(NULL
)
252 val_ptr
->ref_count
= 1;
253 val_ptr
->n_elements
= 0;
254 val_ptr
->value_elements
= NULL
;
257 Record_Of_Type::Record_Of_Type(const Record_Of_Type
& other_value
)
258 : Base_Type(other_value
), val_ptr(NULL
), err_descr(other_value
.err_descr
), refd_ind_ptr(NULL
)
260 if (!other_value
.is_bound())
261 TTCN_error("Copying an unbound record of/set of value.");
262 // Increment ref_count only if val_ptr is not NULL
263 if (other_value
.val_ptr
!= NULL
) {
264 if (NULL
== other_value
.refd_ind_ptr
) {
265 val_ptr
= other_value
.val_ptr
;
266 val_ptr
->ref_count
++;
269 // there are references to at least one element => the array must be copied
270 int nof_elements
= other_value
.get_nof_elements();
271 set_size(nof_elements
);
272 for (int i
= 0; i
< nof_elements
; ++i
) {
273 if (other_value
.is_elem_bound(i
)) {
274 val_ptr
->value_elements
[i
] = other_value
.val_ptr
->value_elements
[i
]->clone();
281 int Record_Of_Type::get_nof_elements() const
283 int nof_elements
= (val_ptr
!= NULL
) ? val_ptr
->n_elements
: 0;
284 if (NULL
!= refd_ind_ptr
) {
285 while (nof_elements
> 0) {
286 if (is_elem_bound(nof_elements
- 1)) {
295 bool Record_Of_Type::is_elem_bound(int index
) const
297 return val_ptr
->value_elements
[index
] != NULL
&&
298 val_ptr
->value_elements
[index
]->is_bound();
301 int Record_Of_Type::get_max_refd_index()
303 if (NULL
== refd_ind_ptr
) {
306 if (-1 == refd_ind_ptr
->max_refd_index
) {
307 for (size_t i
= 0; i
< refd_ind_ptr
->refd_indices
.size(); ++i
) {
308 if (refd_ind_ptr
->refd_indices
[i
] > refd_ind_ptr
->max_refd_index
) {
309 refd_ind_ptr
->max_refd_index
= refd_ind_ptr
->refd_indices
[i
];
313 return refd_ind_ptr
->max_refd_index
;
316 bool Record_Of_Type::is_index_refd(int index
)
318 if (NULL
== refd_ind_ptr
) {
321 for (size_t i
= 0; i
< refd_ind_ptr
->refd_indices
.size(); ++i
) {
322 if (index
== refd_ind_ptr
->refd_indices
[i
]) {
329 void Record_Of_Type::set_val(null_type
)
334 boolean
Record_Of_Type::is_equal(const Base_Type
* other_value
) const
336 const Record_Of_Type
* other_recof
= static_cast<const Record_Of_Type
*>(other_value
);
338 TTCN_error("The left operand of comparison is an unbound value of type %s.",
339 get_descriptor()->name
);
340 if (other_recof
->val_ptr
== NULL
)
341 TTCN_error("The right operand of comparison is an unbound value of type %s.",
342 other_value
->get_descriptor()->name
);
343 if (val_ptr
== other_recof
->val_ptr
) return TRUE
;
345 return compare_set_of(this, get_nof_elements(), other_recof
,
346 other_recof
->get_nof_elements(), compare_function
);
348 if (get_nof_elements() != other_recof
->get_nof_elements()) return FALSE
;
349 for (int elem_count
= 0; elem_count
< get_nof_elements(); elem_count
++) {
350 if (is_elem_bound(elem_count
)) {
351 if (other_recof
->is_elem_bound(elem_count
)) {
352 if (!val_ptr
->value_elements
[elem_count
]->is_equal(other_recof
->val_ptr
->value_elements
[elem_count
]))
355 } else if (other_recof
->is_elem_bound(elem_count
)) return FALSE
;
361 void Record_Of_Type::set_value(const Base_Type
* other_value
)
363 const Record_Of_Type
* other_recof
= static_cast<const Record_Of_Type
*>(other_value
);
364 if (!other_recof
->is_bound())
365 TTCN_error("Assigning an unbound value of type %s.",
366 other_value
->get_descriptor()->name
);
367 if (this != other_recof
) {
368 if (NULL
== refd_ind_ptr
&& NULL
== other_recof
->refd_ind_ptr
) {
370 val_ptr
= other_recof
->val_ptr
;
371 val_ptr
->ref_count
++;
374 // there are references to at least one element => the array must be copied
375 int nof_elements
= other_recof
->get_nof_elements();
376 set_size(nof_elements
);
377 for (int i
= 0; i
< nof_elements
; ++i
) {
378 if (other_recof
->is_elem_bound(i
)) {
379 if (val_ptr
->value_elements
[i
] == NULL
) {
380 val_ptr
->value_elements
[i
] = create_elem();
382 val_ptr
->value_elements
[i
]->set_value(other_recof
->val_ptr
->value_elements
[i
]);
384 else if (val_ptr
->value_elements
[i
] != NULL
) {
385 if (is_index_refd(i
)) {
386 val_ptr
->value_elements
[i
]->clean_up();
389 delete val_ptr
->value_elements
[i
];
390 val_ptr
->value_elements
[i
] = NULL
;
396 err_descr
= other_recof
->err_descr
;
399 boolean
Record_Of_Type::operator!=(null_type other_value
) const
401 return !(*this == other_value
);
404 Base_Type
* Record_Of_Type::get_at(int index_value
)
407 TTCN_error("Accessing an element of type %s using a negative index: %d.",
408 get_descriptor()->name
, index_value
);
409 if (val_ptr
== NULL
) {
410 val_ptr
= new recordof_setof_struct
;
411 val_ptr
->ref_count
= 1;
412 val_ptr
->n_elements
= 0;
413 val_ptr
->value_elements
= NULL
;
414 } else if (val_ptr
->ref_count
> 1) {
415 struct recordof_setof_struct
*new_val_ptr
= new recordof_setof_struct
;
416 new_val_ptr
->ref_count
= 1;
417 new_val_ptr
->n_elements
= (index_value
>= val_ptr
->n_elements
) ?
418 index_value
+ 1 : val_ptr
->n_elements
;
419 new_val_ptr
->value_elements
=
420 (Base_Type
**)allocate_pointers(new_val_ptr
->n_elements
);
421 for (int elem_count
= 0; elem_count
< val_ptr
->n_elements
; elem_count
++)
423 if (val_ptr
->value_elements
[elem_count
] != NULL
) {
424 new_val_ptr
->value_elements
[elem_count
] =
425 val_ptr
->value_elements
[elem_count
]->clone();
428 val_ptr
->ref_count
--;
429 val_ptr
= new_val_ptr
;
431 if (index_value
>= val_ptr
->n_elements
) set_size(index_value
+ 1);
432 if (val_ptr
->value_elements
[index_value
] == NULL
) {
433 val_ptr
->value_elements
[index_value
] = create_elem();
435 return val_ptr
->value_elements
[index_value
];
438 Base_Type
* Record_Of_Type::get_at(const INTEGER
& index_value
)
440 if (!index_value
.is_bound())
441 TTCN_error("Using an unbound integer value for indexing a value "
442 "of type %s.", get_descriptor()->name
);
443 return get_at((int)index_value
);
446 const Base_Type
* Record_Of_Type::get_at(int index_value
) const
449 TTCN_error("Accessing an element in an unbound value of type %s.",
450 get_descriptor()->name
);
452 TTCN_error("Accessing an element of type %s using a negative index: %d.",
453 get_descriptor()->name
, index_value
);
454 if (index_value
>= get_nof_elements())
455 TTCN_error("Index overflow in a value of type %s: The index is %d, but the "
456 "value has only %d elements.", get_descriptor()->name
, index_value
,
458 return (val_ptr
->value_elements
[index_value
] != NULL
) ?
459 val_ptr
->value_elements
[index_value
] : get_unbound_elem();
462 const Base_Type
* Record_Of_Type::get_at(const INTEGER
& index_value
) const
464 if (!index_value
.is_bound())
465 TTCN_error("Using an unbound integer value for indexing a value "
466 "of type %s.", get_descriptor()->name
);
467 return get_at((int)index_value
);
470 Record_Of_Type
* Record_Of_Type::rotl(const INTEGER
& rotate_count
, Record_Of_Type
* rec_of
) const
472 if (!rotate_count
.is_bound())
473 TTCN_error("Unbound integer operand of rotate left operator of type %s.",
474 get_descriptor()->name
);
475 return rotr((int)(-rotate_count
), rec_of
);
478 Record_Of_Type
* Record_Of_Type::rotr(const INTEGER
& rotate_count
, Record_Of_Type
* rec_of
) const
480 if (!rotate_count
.is_bound())
481 TTCN_error("Unbound integer operand of rotate right operator of type %s.",
482 get_descriptor()->name
);
483 return rotr((int)rotate_count
, rec_of
);
486 Record_Of_Type
* Record_Of_Type::rotr(int rotate_count
, Record_Of_Type
* rec_of
) const
489 TTCN_error("Performing rotation operation on an unbound value of type %s.",
490 get_descriptor()->name
);
491 int nof_elements
= get_nof_elements();
492 if (nof_elements
== 0) return const_cast<Record_Of_Type
*>(this);
494 if (rotate_count
>=0) rc
= rotate_count
% nof_elements
;
495 else rc
= nof_elements
- ((-rotate_count
) % nof_elements
);
496 if (rc
== 0) return const_cast<Record_Of_Type
*>(this);
497 rec_of
->set_size(nof_elements
);
499 for (int i
=0; i
<nof_elements
; i
++) {
500 rot_i
= (i
+rc
) % nof_elements
;
501 if (is_elem_bound(i
)) {
502 if (rec_of
->val_ptr
->value_elements
[rot_i
] == NULL
) {
503 rec_of
->val_ptr
->value_elements
[rot_i
] = rec_of
->create_elem();
505 rec_of
->val_ptr
->value_elements
[rot_i
]->set_value(val_ptr
->value_elements
[i
]);
506 } else if (rec_of
->is_elem_bound(rot_i
)) {
507 delete rec_of
->val_ptr
->value_elements
[rot_i
];
508 rec_of
->val_ptr
->value_elements
[rot_i
] = NULL
;
514 Record_Of_Type
* Record_Of_Type::concat(const Record_Of_Type
* other_value
,
515 Record_Of_Type
* rec_of
) const
517 if (val_ptr
== NULL
|| other_value
->val_ptr
== NULL
)
518 TTCN_error("Unbound operand of %s concatenation.", get_descriptor()->name
);
519 int nof_elements
= get_nof_elements();
520 if (nof_elements
== 0) return const_cast<Record_Of_Type
*>(other_value
);
521 int other_value_nof_elements
= other_value
->get_nof_elements();
522 if (other_value_nof_elements
== 0) return const_cast<Record_Of_Type
*>(this);
523 rec_of
->set_size(nof_elements
+ other_value_nof_elements
);
524 for (int i
=0; i
<nof_elements
; i
++) {
525 if (is_elem_bound(i
)) {
526 if (rec_of
->val_ptr
->value_elements
[i
] == NULL
) {
527 rec_of
->val_ptr
->value_elements
[i
] = rec_of
->create_elem();
529 rec_of
->val_ptr
->value_elements
[i
]->set_value(val_ptr
->value_elements
[i
]);
530 } else if (rec_of
->val_ptr
->value_elements
[i
] != NULL
) {
531 if (rec_of
->is_index_refd(i
)) {
532 rec_of
->val_ptr
->value_elements
[i
]->clean_up();
535 delete rec_of
->val_ptr
->value_elements
[i
];
536 rec_of
->val_ptr
->value_elements
[i
] = NULL
;
541 for (int i
=0; i
<other_value_nof_elements
; i
++) {
542 cat_i
= i
+ nof_elements
;
543 if (other_value
->is_elem_bound(i
)) {
544 if (rec_of
->val_ptr
->value_elements
[cat_i
] == NULL
) {
545 rec_of
->val_ptr
->value_elements
[cat_i
] = rec_of
->create_elem();
547 rec_of
->val_ptr
->value_elements
[cat_i
]->
548 set_value(other_value
->val_ptr
->value_elements
[i
]);
549 } else if (rec_of
->val_ptr
->value_elements
[cat_i
] != NULL
) {
550 if (rec_of
->is_index_refd(cat_i
)) {
551 rec_of
->val_ptr
->value_elements
[cat_i
]->clean_up();
554 delete rec_of
->val_ptr
->value_elements
[cat_i
];
555 rec_of
->val_ptr
->value_elements
[cat_i
] = NULL
;
562 void Record_Of_Type::substr_(int index
, int returncount
,
563 Record_Of_Type
* rec_of
) const
566 TTCN_error("The first argument of substr() is an unbound value of type %s.",
567 get_descriptor()->name
);
568 check_substr_arguments(get_nof_elements(), index
, returncount
,
569 get_descriptor()->name
, "element");
570 rec_of
->set_size(returncount
);
571 for (int i
=0; i
<returncount
; i
++) {
572 if (is_elem_bound(i
+ index
)) {
573 if (rec_of
->val_ptr
->value_elements
[i
] == NULL
) {
574 rec_of
->val_ptr
->value_elements
[i
] = rec_of
->create_elem();
576 rec_of
->val_ptr
->value_elements
[i
]->
577 set_value(val_ptr
->value_elements
[i
+index
]);
578 } else if (rec_of
->val_ptr
->value_elements
[i
] != NULL
) {
579 if (rec_of
->is_index_refd(i
)) {
580 rec_of
->val_ptr
->value_elements
[i
]->clean_up();
583 delete rec_of
->val_ptr
->value_elements
[i
];
584 rec_of
->val_ptr
->value_elements
[i
] = NULL
;
590 void Record_Of_Type::replace_(int index
, int len
,
591 const Record_Of_Type
* repl
, Record_Of_Type
* rec_of
) const
594 TTCN_error("The first argument of replace() is an unbound value "
595 "of type %s.", get_descriptor()->name
);
596 if (repl
->val_ptr
== NULL
)
597 TTCN_error("The fourth argument of replace() is an unbound value of "
598 "type %s.", get_descriptor()->name
);
599 int nof_elements
= get_nof_elements();
600 check_replace_arguments(nof_elements
, index
, len
,
601 get_descriptor()->name
, "element");
602 int repl_nof_elements
= repl
->get_nof_elements();
603 rec_of
->set_size(nof_elements
+ repl_nof_elements
- len
);
604 for (int i
= 0; i
< index
; i
++) {
605 if (is_elem_bound(i
)) {
606 if (rec_of
->val_ptr
->value_elements
[i
] == NULL
) {
607 rec_of
->val_ptr
->value_elements
[i
] = rec_of
->create_elem();
609 rec_of
->val_ptr
->value_elements
[i
]->set_value(val_ptr
->value_elements
[i
]);
610 } else if (rec_of
->val_ptr
->value_elements
[i
] != NULL
) {
611 if (rec_of
->is_index_refd(i
)) {
612 rec_of
->val_ptr
->value_elements
[i
]->clean_up();
615 delete rec_of
->val_ptr
->value_elements
[i
];
616 rec_of
->val_ptr
->value_elements
[i
] = NULL
;
620 for (int i
= 0; i
< repl_nof_elements
; i
++) {
621 if (repl
->is_elem_bound(i
)) {
622 if (rec_of
->val_ptr
->value_elements
[i
+index
] == NULL
) {
623 rec_of
->val_ptr
->value_elements
[i
+index
] = rec_of
->create_elem();
625 rec_of
->val_ptr
->value_elements
[i
+index
]->
626 set_value(repl
->val_ptr
->value_elements
[i
]);
627 } else if (rec_of
->val_ptr
->value_elements
[i
+index
] != NULL
) {
628 if (rec_of
->is_index_refd(i
+index
)) {
629 rec_of
->val_ptr
->value_elements
[i
+index
]->clean_up();
632 delete rec_of
->val_ptr
->value_elements
[i
+index
];
633 rec_of
->val_ptr
->value_elements
[i
+index
] = NULL
;
638 for (int i
= 0; i
< nof_elements
- index
- len
; i
++) {
639 repl_i
= index
+i
+repl_nof_elements
;
640 if (is_elem_bound(index
+i
+len
)) {
641 if (rec_of
->val_ptr
->value_elements
[repl_i
] == NULL
) {
642 rec_of
->val_ptr
->value_elements
[repl_i
] = rec_of
->create_elem();
644 rec_of
->val_ptr
->value_elements
[repl_i
]->
645 set_value(val_ptr
->value_elements
[index
+i
+len
]);
646 } else if (rec_of
->val_ptr
->value_elements
[repl_i
] != NULL
) {
647 if (rec_of
->is_index_refd(repl_i
)) {
648 rec_of
->val_ptr
->value_elements
[repl_i
]->clean_up();
651 delete rec_of
->val_ptr
->value_elements
[repl_i
];
652 rec_of
->val_ptr
->value_elements
[repl_i
] = NULL
;
658 void Record_Of_Type::replace_(int index
, int len
,
659 const Record_Of_Template
* repl
, Record_Of_Type
* rec_of
) const
661 if (!repl
->is_value())
662 TTCN_error("The fourth argument of function replace() is a template "
663 "of type %s with non-specific value.", get_descriptor()->name
);
664 rec_of
->set_val(NULL_VALUE
);
665 Base_Type
* repl_value
= rec_of
->clone();
666 repl
->valueofv(repl_value
);
667 replace_(index
, len
, static_cast<Record_Of_Type
*>(repl_value
), rec_of
);
671 void Record_Of_Type::replace_(int index
, int len
,
672 const Set_Of_Template
* repl
, Record_Of_Type
* rec_of
) const
674 if (!repl
->is_value())
675 TTCN_error("The fourth argument of function replace() is a template "
676 "of type %s with non-specific value.", get_descriptor()->name
);
677 rec_of
->set_val(NULL_VALUE
);
678 Base_Type
* repl_value
= rec_of
->clone();
679 repl
->valueofv(repl_value
);
680 replace_(index
, len
, static_cast<Record_Of_Type
*>(repl_value
), rec_of
);
684 void Record_Of_Type::set_size(int new_size
)
687 TTCN_error("Internal error: Setting a negative size for a value of "
688 "type %s.", get_descriptor()->name
);
689 if (val_ptr
== NULL
) {
690 val_ptr
= new recordof_setof_struct
;
691 val_ptr
->ref_count
= 1;
692 val_ptr
->n_elements
= 0;
693 val_ptr
->value_elements
= NULL
;
694 } else if (val_ptr
->ref_count
> 1) {
695 struct recordof_setof_struct
*new_val_ptr
= new recordof_setof_struct
;
696 new_val_ptr
->ref_count
= 1;
697 new_val_ptr
->n_elements
= (new_size
< val_ptr
->n_elements
) ?
698 new_size
: val_ptr
->n_elements
;
699 new_val_ptr
->value_elements
=
700 (Base_Type
**)allocate_pointers(new_val_ptr
->n_elements
);
701 for (int elem_count
= 0; elem_count
< new_val_ptr
->n_elements
; elem_count
++) {
702 if (val_ptr
->value_elements
[elem_count
] != NULL
) {
703 new_val_ptr
->value_elements
[elem_count
] =
704 val_ptr
->value_elements
[elem_count
]->clone();
708 val_ptr
= new_val_ptr
;
710 if (new_size
> val_ptr
->n_elements
) {
711 val_ptr
->value_elements
= (Base_Type
**)
712 reallocate_pointers((void**)val_ptr
->value_elements
, val_ptr
->n_elements
, new_size
);
713 val_ptr
->n_elements
= new_size
;
714 } else if (new_size
< val_ptr
->n_elements
) {
715 for (int elem_count
= new_size
; elem_count
< val_ptr
->n_elements
; elem_count
++) {
716 if (val_ptr
->value_elements
[elem_count
] != NULL
) {
717 if (is_index_refd(elem_count
)) {
718 val_ptr
->value_elements
[elem_count
]->clean_up();
721 delete val_ptr
->value_elements
[elem_count
];
722 val_ptr
->value_elements
[elem_count
] = 0;
726 if (new_size
<= get_max_refd_index()) {
727 new_size
= get_max_refd_index() + 1;
729 if (new_size
< val_ptr
->n_elements
) {
730 val_ptr
->value_elements
= (Base_Type
**)
731 reallocate_pointers((void**)val_ptr
->value_elements
, val_ptr
->n_elements
, new_size
);
732 val_ptr
->n_elements
= new_size
;
737 boolean
Record_Of_Type::is_bound() const
739 if (NULL
== refd_ind_ptr
) {
740 return (val_ptr
!= NULL
);
742 return (get_nof_elements() != 0);
745 boolean
Record_Of_Type::is_value() const
747 if (val_ptr
== NULL
) return FALSE
;
748 for (int i
=0; i
< get_nof_elements(); ++i
)
749 if (!is_elem_bound(i
) ||
750 !val_ptr
->value_elements
[i
]->is_value()) return FALSE
;
754 int Record_Of_Type::size_of() const
757 TTCN_error("Performing sizeof operation on an unbound value of type %s.",
758 get_descriptor()->name
);
759 return get_nof_elements();
762 int Record_Of_Type::lengthof() const
765 TTCN_error("Performing lengthof operation on an unbound value of "
766 "type %s.", get_descriptor()->name
);
767 for (int my_length
=get_nof_elements(); my_length
>0; my_length
--)
768 if (is_elem_bound(my_length
- 1)) return my_length
;
772 void Record_Of_Type::log() const
774 if (val_ptr
== NULL
) {
775 TTCN_Logger::log_event_unbound();
778 if (get_nof_elements()==0) {
779 TTCN_Logger::log_event_str("{ }");
781 TTCN_Logger::log_event_str("{ ");
782 for (int elem_count
= 0; elem_count
< get_nof_elements(); elem_count
++) {
783 if (elem_count
> 0) TTCN_Logger::log_event_str(", ");
784 get_at(elem_count
)->log();
786 TTCN_Logger::log_event_str(" }");
788 if (err_descr
) err_descr
->log();
791 void Record_Of_Type::encode_text(Text_Buf
& text_buf
) const
794 TTCN_error("Text encoder: Encoding an unbound value of type %s.",
795 get_descriptor()->name
);
796 text_buf
.push_int(get_nof_elements());
797 for (int elem_count
= 0; elem_count
< get_nof_elements(); elem_count
++)
798 get_at(elem_count
)->encode_text(text_buf
);
801 void Record_Of_Type::decode_text(Text_Buf
& text_buf
)
803 int new_size
= text_buf
.pull_int().get_val();
805 TTCN_error("Text decoder: Negative size was received for a value of "
806 "type %s.", get_descriptor()->name
);
808 for (int elem_count
= 0; elem_count
< new_size
; elem_count
++) {
809 if (val_ptr
->value_elements
[elem_count
] == NULL
) {
810 val_ptr
->value_elements
[elem_count
] = create_elem();
812 val_ptr
->value_elements
[elem_count
]->decode_text(text_buf
);
816 boolean
Record_Of_Type::operator==(null_type
/*other_value*/) const
819 TTCN_error("The left operand of comparison is an unbound value of type %s.",
820 get_descriptor()->name
);
821 return get_nof_elements() == 0;
824 int Record_Of_Type::rawdec_ebv() const
826 TTCN_error("Internal error: Record_Of_Type::rawdec_ebv() called.");
829 boolean
Record_Of_Type::isXerAttribute() const
831 TTCN_error("Internal error: Record_Of_Type::isXerAttribute() called.");
834 boolean
Record_Of_Type::isXmlValueList() const
836 TTCN_error("Internal error: Record_Of_Type::isXmlValueList() called.");
839 int Record_Of_Type::TEXT_encode(const TTCN_Typedescriptor_t
& p_td
,
840 TTCN_Buffer
& buff
) const
843 return TEXT_encode_negtest(err_descr
, p_td
, buff
);
845 int encoded_length
=0;
846 if(p_td
.text
->begin_encode
) {
847 buff
.put_cs(*p_td
.text
->begin_encode
);
848 encoded_length
+=p_td
.text
->begin_encode
->lengthof();
851 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND
,
852 "Encoding an unbound value.");
853 if(p_td
.text
->end_encode
) {
854 buff
.put_cs(*p_td
.text
->end_encode
);
855 encoded_length
+=p_td
.text
->end_encode
->lengthof();
857 return encoded_length
;
859 const TTCN_Typedescriptor_t
* elem_descr
= get_elem_descr();
860 for(int a
=0;a
<get_nof_elements();a
++) {
861 if(a
!=0 && p_td
.text
->separator_encode
) {
862 buff
.put_cs(*p_td
.text
->separator_encode
);
863 encoded_length
+=p_td
.text
->separator_encode
->lengthof();
865 encoded_length
+=get_at(a
)->TEXT_encode(*elem_descr
,buff
);
867 if(p_td
.text
->end_encode
) {
868 buff
.put_cs(*p_td
.text
->end_encode
);
869 encoded_length
+=p_td
.text
->end_encode
->lengthof();
871 return encoded_length
;
875 * TEXT encode for negative testing
877 int Record_Of_Type::TEXT_encode_negtest(const Erroneous_descriptor_t
* p_err_descr
, const TTCN_Typedescriptor_t
& p_td
,
878 TTCN_Buffer
& buff
) const
880 bool need_separator
=false;
881 int encoded_length
=0;
882 if(p_td
.text
->begin_encode
) {
883 buff
.put_cs(*p_td
.text
->begin_encode
);
884 encoded_length
+=p_td
.text
->begin_encode
->lengthof();
887 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND
,
888 "Encoding an unbound value.");
889 if(p_td
.text
->end_encode
) {
890 buff
.put_cs(*p_td
.text
->end_encode
);
891 encoded_length
+=p_td
.text
->end_encode
->lengthof();
893 return encoded_length
;
899 for(int a
=0;a
<get_nof_elements();a
++) {
900 if ( (p_err_descr
->omit_before
!=-1) && (a
<p_err_descr
->omit_before
) ) continue;
901 const Erroneous_values_t
* err_vals
= p_err_descr
->next_field_err_values(a
, values_idx
);
902 const Erroneous_descriptor_t
* emb_descr
= p_err_descr
->next_field_emb_descr(a
, edescr_idx
);
904 if (err_vals
&& err_vals
->before
) {
905 if (err_vals
->before
->errval
==NULL
) TTCN_error(
906 "internal error: erroneous before value missing");
907 if (need_separator
&& p_td
.text
->separator_encode
) {
908 buff
.put_cs(*p_td
.text
->separator_encode
);
909 encoded_length
+=p_td
.text
->separator_encode
->lengthof();
911 if (err_vals
->before
->raw
) {
912 encoded_length
+= err_vals
->before
->errval
->encode_raw(buff
);
914 if (err_vals
->before
->type_descr
==NULL
) TTCN_error(
915 "internal error: erroneous before typedescriptor missing");
916 encoded_length
+= err_vals
->before
->errval
->TEXT_encode(
917 *(err_vals
->before
->type_descr
),buff
);
922 if (err_vals
&& err_vals
->value
) {
923 if (err_vals
->value
->errval
) {
924 if (need_separator
&& p_td
.text
->separator_encode
) {
925 buff
.put_cs(*p_td
.text
->separator_encode
);
926 encoded_length
+=p_td
.text
->separator_encode
->lengthof();
928 if (err_vals
->value
->raw
) {
929 encoded_length
+= err_vals
->value
->errval
->encode_raw(buff
);
931 if (err_vals
->value
->type_descr
==NULL
) TTCN_error(
932 "internal error: erroneous value typedescriptor missing");
933 encoded_length
+= err_vals
->value
->errval
->TEXT_encode(
934 *(err_vals
->value
->type_descr
),buff
);
939 if (need_separator
&& p_td
.text
->separator_encode
) {
940 buff
.put_cs(*p_td
.text
->separator_encode
);
941 encoded_length
+=p_td
.text
->separator_encode
->lengthof();
944 encoded_length
+= get_at(a
)->TEXT_encode_negtest(
945 emb_descr
,*get_elem_descr(),buff
);
947 encoded_length
+= get_at(a
)->TEXT_encode(*get_elem_descr(),buff
);
952 if (err_vals
&& err_vals
->after
) {
953 if (err_vals
->after
->errval
==NULL
) TTCN_error(
954 "internal error: erroneous after value missing");
955 if (need_separator
&& p_td
.text
->separator_encode
) {
956 buff
.put_cs(*p_td
.text
->separator_encode
);
957 encoded_length
+=p_td
.text
->separator_encode
->lengthof();
959 if (err_vals
->after
->raw
) {
960 encoded_length
+= err_vals
->after
->errval
->encode_raw(buff
);
962 if (err_vals
->after
->type_descr
==NULL
) TTCN_error(
963 "internal error: erroneous after typedescriptor missing");
964 encoded_length
+= err_vals
->after
->errval
->TEXT_encode(
965 *(err_vals
->after
->type_descr
),buff
);
970 if ( (p_err_descr
->omit_after
!=-1) && (a
>=p_err_descr
->omit_after
) ) break;
972 if(p_td
.text
->end_encode
) {
973 buff
.put_cs(*p_td
.text
->end_encode
);
974 encoded_length
+=p_td
.text
->end_encode
->lengthof();
976 return encoded_length
;
979 int Record_Of_Type::TEXT_decode(const TTCN_Typedescriptor_t
& p_td
,
980 TTCN_Buffer
& buff
, Limit_Token_List
& limit
, boolean no_err
,
983 int decoded_length
=0;
985 boolean sep_found
=FALSE
;
988 if(p_td
.text
->begin_decode
){
990 if((tl
=p_td
.text
->begin_decode
->match_begin(buff
))<0){
992 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR
,
993 "The specified token '%s' not found for '%s': ",
994 (const char*)*(p_td
.text
->begin_decode
), p_td
.name
);
998 buff
.increase_pos(tl
);
1000 if(p_td
.text
->end_decode
){
1001 limit
.add_token(p_td
.text
->end_decode
);
1004 if(p_td
.text
->separator_decode
){
1005 limit
.add_token(p_td
.text
->separator_decode
);
1011 int more
=get_nof_elements();
1013 Base_Type
* val
= create_elem();
1015 int len
= val
->TEXT_decode(*get_elem_descr(),buff
,limit
,TRUE
);
1016 if(len
==-1 || (len
==0 && !limit
.has_token())){
1020 buff
.set_pos(buff
.get_pos()-sep_length
);
1021 decoded_length
-=sep_length
;
1026 if (NULL
== refd_ind_ptr
) {
1027 val_ptr
->value_elements
= (Base_Type
**)reallocate_pointers(
1028 (void**)val_ptr
->value_elements
, val_ptr
->n_elements
, val_ptr
->n_elements
+ 1);
1029 val_ptr
->value_elements
[val_ptr
->n_elements
]=val
;
1030 val_ptr
->n_elements
++;
1033 get_at(get_nof_elements())->set_value(val
);
1036 decoded_length
+=len
;
1037 if(p_td
.text
->separator_decode
){
1039 if((tl
=p_td
.text
->separator_decode
->match_begin(buff
))<0){
1043 buff
.increase_pos(tl
);
1046 } else if(p_td
.text
->end_decode
){
1048 if((tl
=p_td
.text
->end_decode
->match_begin(buff
))!=-1){
1050 buff
.increase_pos(tl
);
1051 limit
.remove_tokens(ml
);
1052 return decoded_length
;
1054 } else if(limit
.has_token(ml
)){
1056 if((tl
=limit
.match(buff
,ml
))==0){
1062 limit
.remove_tokens(ml
);
1063 if(p_td
.text
->end_decode
){
1065 if((tl
=p_td
.text
->end_decode
->match_begin(buff
))<0){
1072 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR
,
1073 "The specified token '%s' not found for '%s': ",
1074 (const char*)*(p_td
.text
->end_decode
), p_td
.name
);
1075 return decoded_length
;
1078 buff
.increase_pos(tl
);
1080 if(get_nof_elements()==0){
1081 if (!p_td
.text
->end_decode
&& !p_td
.text
->begin_decode
) {
1082 if(no_err
)return -1;
1083 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR
,
1084 "No record/set of member found.");
1085 return decoded_length
;
1088 if(!first_call
&& more
==get_nof_elements() &&
1089 !(p_td
.text
->end_decode
|| p_td
.text
->begin_decode
)) return -1;
1090 return decoded_length
;
1093 ASN_BER_TLV_t
* Record_Of_Type::BER_encode_TLV(const TTCN_Typedescriptor_t
& p_td
,
1094 unsigned p_coding
) const
1097 return BER_encode_TLV_negtest(err_descr
, p_td
, p_coding
);
1099 BER_chk_descr(p_td
);
1100 ASN_BER_TLV_t
*new_tlv
=BER_encode_chk_bound(is_bound());
1102 new_tlv
=ASN_BER_TLV_t::construct(NULL
);
1103 TTCN_EncDec_ErrorContext ec
;
1104 for(int elem_i
=0; elem_i
<get_nof_elements(); elem_i
++) {
1105 ec
.set_msg("Component #%d: ", elem_i
);
1106 new_tlv
->add_TLV(get_at(elem_i
)->BER_encode_TLV(*get_elem_descr(), p_coding
));
1108 if (is_set()) new_tlv
->sort_tlvs();
1110 new_tlv
=ASN_BER_V2TLV(new_tlv
, p_td
, p_coding
);
1114 ASN_BER_TLV_t
* Record_Of_Type::BER_encode_TLV_negtest(const Erroneous_descriptor_t
* p_err_descr
,
1115 const TTCN_Typedescriptor_t
& p_td
, unsigned p_coding
) const
1117 BER_chk_descr(p_td
);
1118 ASN_BER_TLV_t
*new_tlv
=BER_encode_chk_bound(is_bound());
1120 new_tlv
=ASN_BER_TLV_t::construct(NULL
);
1121 TTCN_EncDec_ErrorContext ec
;
1124 for (int elem_i
=0; elem_i
<get_nof_elements(); elem_i
++) {
1125 if ( (p_err_descr
->omit_before
!=-1) && (elem_i
<p_err_descr
->omit_before
) ) continue;
1126 const Erroneous_values_t
* err_vals
= p_err_descr
->next_field_err_values(elem_i
, values_idx
);
1127 const Erroneous_descriptor_t
* emb_descr
= p_err_descr
->next_field_emb_descr(elem_i
, edescr_idx
);
1129 if (err_vals
&& err_vals
->before
) {
1130 if (err_vals
->before
->errval
==NULL
) TTCN_error(
1131 "internal error: erroneous before value missing");
1132 ec
.set_msg("Erroneous value before component #%d: ", elem_i
);
1133 if (err_vals
->before
->raw
) {
1134 new_tlv
->add_TLV(err_vals
->before
->errval
->BER_encode_negtest_raw());
1136 if (err_vals
->before
->type_descr
==NULL
) TTCN_error(
1137 "internal error: erroneous before typedescriptor missing");
1138 new_tlv
->add_TLV(err_vals
->before
->errval
->BER_encode_TLV(
1139 *err_vals
->before
->type_descr
, p_coding
));
1143 if (err_vals
&& err_vals
->value
) {
1144 if (err_vals
->value
->errval
) { // replace
1145 ec
.set_msg("Erroneous value for component #%d: ", elem_i
);
1146 if (err_vals
->value
->raw
) {
1147 new_tlv
->add_TLV(err_vals
->value
->errval
->BER_encode_negtest_raw());
1149 if (err_vals
->value
->type_descr
==NULL
) TTCN_error(
1150 "internal error: erroneous value typedescriptor missing");
1151 new_tlv
->add_TLV(err_vals
->value
->errval
->BER_encode_TLV(
1152 *err_vals
->value
->type_descr
, p_coding
));
1156 ec
.set_msg("Component #%d: ", elem_i
);
1158 new_tlv
->add_TLV(get_at(elem_i
)->BER_encode_TLV_negtest(
1159 emb_descr
, *get_elem_descr(), p_coding
));
1161 new_tlv
->add_TLV(get_at(elem_i
)->BER_encode_TLV(
1162 *get_elem_descr(), p_coding
));
1166 if (err_vals
&& err_vals
->after
) {
1167 if (err_vals
->after
->errval
==NULL
) TTCN_error(
1168 "internal error: erroneous after value missing");
1169 ec
.set_msg("Erroneous value after component #%d: ", elem_i
);
1170 if (err_vals
->after
->raw
) {
1171 new_tlv
->add_TLV(err_vals
->after
->errval
->BER_encode_negtest_raw());
1173 if (err_vals
->after
->type_descr
==NULL
) TTCN_error(
1174 "internal error: erroneous after typedescriptor missing");
1175 new_tlv
->add_TLV(err_vals
->after
->errval
->BER_encode_TLV(
1176 *err_vals
->after
->type_descr
, p_coding
));
1180 if ( (p_err_descr
->omit_after
!=-1) && (elem_i
>=p_err_descr
->omit_after
) ) break;
1182 if (is_set()) new_tlv
->sort_tlvs();
1184 new_tlv
=ASN_BER_V2TLV(new_tlv
, p_td
, p_coding
);
1188 boolean
Record_Of_Type::BER_decode_TLV(const TTCN_Typedescriptor_t
& p_td
,
1189 const ASN_BER_TLV_t
& p_tlv
, unsigned L_form
)
1191 BER_chk_descr(p_td
);
1192 ASN_BER_TLV_t stripped_tlv
;
1193 BER_decode_strip_tags(*p_td
.ber
, p_tlv
, L_form
, stripped_tlv
);
1194 TTCN_EncDec_ErrorContext
ec_0("While decoding '%s' type: ", p_td
.name
);
1195 stripped_tlv
.chk_constructed_flag(TRUE
);
1198 ASN_BER_TLV_t tmp_tlv
;
1199 TTCN_EncDec_ErrorContext
ec_1("Component #");
1200 TTCN_EncDec_ErrorContext
ec_2("0: ");
1201 while(BER_decode_constdTLV_next(stripped_tlv
, V_pos
, L_form
, tmp_tlv
)) {
1202 get_at(get_nof_elements())->BER_decode_TLV(*get_elem_descr(), tmp_tlv
, L_form
);
1203 ec_2
.set_msg("%d: ", val_ptr
->n_elements
);
1208 void Record_Of_Type::BER_decode_opentypes(TTCN_Type_list
& p_typelist
,
1211 p_typelist
.push(this);
1212 TTCN_EncDec_ErrorContext
ec_0("Component #");
1213 TTCN_EncDec_ErrorContext ec_1
;
1214 for(int elem_i
=0; elem_i
<get_nof_elements(); elem_i
++) {
1215 ec_1
.set_msg("%d: ", elem_i
);
1216 get_at(elem_i
)->BER_decode_opentypes(p_typelist
, L_form
);
1222 int Record_Of_Type::RAW_decode(const TTCN_Typedescriptor_t
& p_td
,
1223 TTCN_Buffer
& buff
, int limit
, raw_order_t top_bit_ord
, boolean
/*no_err*/,
1224 int sel_field
, boolean first_call
)
1226 int prepaddlength
= buff
.increase_pos_padd(p_td
.raw
->prepadding
);
1227 limit
-= prepaddlength
;
1228 int decoded_length
= 0;
1229 int decoded_field_length
= 0;
1230 size_t start_of_field
= 0;
1234 int start_field
= get_nof_elements(); // append at the end
1235 TTCN_Typedescriptor_t
const& elem_descr
= *get_elem_descr();
1236 if (p_td
.raw
->fieldlength
|| sel_field
!= -1) {
1237 if (sel_field
== -1) sel_field
= p_td
.raw
->fieldlength
;
1238 for (int a
= 0; a
< sel_field
; a
++) {
1239 Base_Type
* field_bt
= get_at(a
+ start_field
);
1240 decoded_field_length
= field_bt
->RAW_decode(elem_descr
, buff
, limit
,
1242 if (decoded_field_length
< 0) return decoded_field_length
;
1243 decoded_length
+= decoded_field_length
;
1244 limit
-= decoded_field_length
;
1248 int a
= start_field
;
1250 if (!first_call
) return -1;
1253 int ext_bit
= rawdec_ebv();
1255 start_of_field
= buff
.get_pos_bit();
1256 Base_Type
* field_bt
= get_at(a
); // non-const, extend the record-of
1257 decoded_field_length
= field_bt
->RAW_decode(elem_descr
, buff
, limit
,
1259 if (decoded_field_length
< 0) { // decoding failed, shorten the record-of
1260 set_size(get_nof_elements() - 1);
1261 buff
.set_pos_bit(start_of_field
);
1262 if (a
> start_field
) {
1265 else return decoded_field_length
;
1267 decoded_length
+= decoded_field_length
;
1268 limit
-= decoded_field_length
;
1270 if (ext_bit
!= 1/*XDEFNO*/&& ext_bit
!= -1/*XDEFDEFAULT*/) {
1271 // ext_bit here may be 2 (XDEFYES) or 3 (XDEFREVERSE).
1272 // (ext_bit != 2) is 0 or 1
1273 // This is the opposite value of what the bit needs to be to signal
1274 // the end of decoding, because x-or is the equivalent of !=
1275 if ((ext_bit
!= 2/*XDEFYES*/) ^ buff
.get_last_bit()) {
1282 return decoded_length
+ buff
.increase_pos_padd(p_td
.raw
->padding
) + prepaddlength
;
1285 int Record_Of_Type::RAW_encode(const TTCN_Typedescriptor_t
& p_td
, RAW_enc_tree
& myleaf
) const
1287 if (err_descr
) return RAW_encode_negtest(err_descr
, p_td
, myleaf
);
1288 int encoded_length
= 0;
1289 int nof_elements
= get_nof_elements();
1290 int encoded_num_of_records
=
1291 p_td
.raw
->fieldlength
? (nof_elements
< p_td
.raw
->fieldlength
? nof_elements
: p_td
.raw
->fieldlength
)
1293 myleaf
.isleaf
= FALSE
;
1294 myleaf
.rec_of
= TRUE
;
1295 myleaf
.body
.node
.num_of_nodes
= encoded_num_of_records
;
1296 myleaf
.body
.node
.nodes
= init_nodes_of_enc_tree(encoded_num_of_records
);
1297 TTCN_Typedescriptor_t
const& elem_descr
= *get_elem_descr();
1298 for (int a
= 0; a
< encoded_num_of_records
; a
++) {
1299 const Base_Type
*field_bt
= get_at(a
);
1300 myleaf
.body
.node
.nodes
[a
] = new RAW_enc_tree(TRUE
, &myleaf
, &(myleaf
.curr_pos
), a
, elem_descr
.raw
);
1301 encoded_length
+= field_bt
->RAW_encode(elem_descr
, *myleaf
.body
.node
.nodes
[a
]);
1303 return myleaf
.length
= encoded_length
;
1306 int Record_Of_Type::RAW_encode_negtest(const Erroneous_descriptor_t
*p_err_descr
,
1307 const TTCN_Typedescriptor_t
& p_td
, RAW_enc_tree
& myleaf
) const
1311 int nof_elements
= get_nof_elements();
1312 // It can be more, of course...
1313 int encoded_num_of_records
=
1314 p_td
.raw
->fieldlength
? (nof_elements
< p_td
.raw
->fieldlength
? nof_elements
: p_td
.raw
->fieldlength
)
1316 for (int i
= 0; i
< nof_elements
; ++i
) {
1317 if ((p_err_descr
->omit_before
!= -1) && (i
< p_err_descr
->omit_before
)) {
1318 --encoded_num_of_records
;
1321 const Erroneous_values_t
*err_vals
=
1322 p_err_descr
->next_field_err_values(i
, values_idx
);
1323 // Not checking any further, `internal error' will be given anyway in the
1324 // next round. Please note that elements can be removed, `omitted'.
1325 if (err_vals
&& err_vals
->before
)
1326 ++encoded_num_of_records
;
1327 if (err_vals
&& err_vals
->value
&& !err_vals
->value
->errval
)
1328 --encoded_num_of_records
;
1329 if (err_vals
&& err_vals
->after
)
1330 ++encoded_num_of_records
;
1331 if ((p_err_descr
->omit_after
!= -1) && (i
>= p_err_descr
->omit_after
)) {
1332 encoded_num_of_records
= encoded_num_of_records
- (nof_elements
- i
) + 1;
1336 myleaf
.body
.node
.num_of_nodes
= encoded_num_of_records
;
1337 myleaf
.body
.node
.nodes
= init_nodes_of_enc_tree(encoded_num_of_records
);
1338 int encoded_length
= 0;
1339 myleaf
.isleaf
= FALSE
;
1340 myleaf
.rec_of
= TRUE
;
1343 for (int i
= 0; i
< nof_elements
; ++i
) {
1344 if ((p_err_descr
->omit_before
!= -1) && (i
< p_err_descr
->omit_before
))
1346 const Erroneous_values_t
*err_vals
= p_err_descr
->next_field_err_values(i
, values_idx
);
1347 const Erroneous_descriptor_t
*emb_descr
= p_err_descr
->next_field_emb_descr(i
, edescr_idx
);
1348 TTCN_Typedescriptor_t
const& elem_descr
= *get_elem_descr();
1349 if (err_vals
&& err_vals
->before
) {
1350 if (err_vals
->before
->errval
== NULL
)
1351 TTCN_error("internal error: erroneous before value missing");
1352 if (err_vals
->before
->raw
) {
1353 myleaf
.body
.node
.nodes
[node_pos
] = new RAW_enc_tree(true, &myleaf
,
1354 &(myleaf
.curr_pos
), node_pos
,
1355 err_vals
->before
->errval
->get_descriptor()->raw
);
1356 encoded_length
+= err_vals
->before
->errval
->
1357 RAW_encode_negtest_raw(*myleaf
.body
.node
.nodes
[node_pos
++]);
1359 if (err_vals
->before
->type_descr
== NULL
)
1360 TTCN_error("internal error: erroneous before typedescriptor missing");
1361 myleaf
.body
.node
.nodes
[node_pos
] = new RAW_enc_tree(TRUE
, &myleaf
,
1362 &(myleaf
.curr_pos
), node_pos
, elem_descr
.raw
);
1363 encoded_length
+= err_vals
->before
->errval
->
1364 RAW_encode(*(err_vals
->before
->type_descr
),
1365 *myleaf
.body
.node
.nodes
[node_pos
++]);
1368 if (err_vals
&& err_vals
->value
) {
1369 if (err_vals
->value
->errval
) {
1370 if (err_vals
->value
->raw
) {
1371 myleaf
.body
.node
.nodes
[node_pos
] = new RAW_enc_tree(true, &myleaf
,
1372 &(myleaf
.curr_pos
), node_pos
,
1373 err_vals
->value
->errval
->get_descriptor()->raw
);
1374 encoded_length
+= err_vals
->value
->errval
->
1375 RAW_encode_negtest_raw(*myleaf
.body
.node
.nodes
[node_pos
++]);
1377 if (err_vals
->value
->type_descr
== NULL
)
1378 TTCN_error("internal error: erroneous value typedescriptor missing");
1379 myleaf
.body
.node
.nodes
[node_pos
] = new RAW_enc_tree(TRUE
, &myleaf
,
1380 &(myleaf
.curr_pos
), node_pos
, elem_descr
.raw
);
1381 encoded_length
+= err_vals
->value
->errval
->
1382 RAW_encode(*(err_vals
->value
->type_descr
),
1383 *myleaf
.body
.node
.nodes
[node_pos
++]);
1388 myleaf
.body
.node
.nodes
[node_pos
] = new RAW_enc_tree(TRUE
, &myleaf
,
1389 &(myleaf
.curr_pos
), node_pos
, elem_descr
.raw
);
1390 encoded_length
+= get_at(i
)->RAW_encode_negtest(emb_descr
,
1391 *get_elem_descr(), *myleaf
.body
.node
.nodes
[node_pos
++]);
1393 myleaf
.body
.node
.nodes
[node_pos
] = new RAW_enc_tree(TRUE
, &myleaf
,
1394 &(myleaf
.curr_pos
), node_pos
, elem_descr
.raw
);
1395 encoded_length
+= get_at(i
)->RAW_encode(*get_elem_descr(),
1396 *myleaf
.body
.node
.nodes
[node_pos
++]);
1399 if (err_vals
&& err_vals
->after
) {
1400 if (err_vals
->after
->errval
== NULL
)
1401 TTCN_error("internal error: erroneous after value missing");
1402 if (err_vals
->after
->raw
) {
1403 myleaf
.body
.node
.nodes
[node_pos
] = new RAW_enc_tree(true, &myleaf
,
1404 &(myleaf
.curr_pos
), node_pos
,
1405 err_vals
->after
->errval
->get_descriptor()->raw
);
1406 encoded_length
+= err_vals
->after
->errval
->
1407 RAW_encode_negtest_raw(*myleaf
.body
.node
.nodes
[node_pos
++]);
1409 if (err_vals
->after
->type_descr
== NULL
)
1410 TTCN_error("internal error: erroneous after typedescriptor missing");
1411 myleaf
.body
.node
.nodes
[node_pos
] = new RAW_enc_tree(TRUE
, &myleaf
,
1412 &(myleaf
.curr_pos
), node_pos
, elem_descr
.raw
);
1413 encoded_length
+= err_vals
->after
->errval
->
1414 RAW_encode(*(err_vals
->after
->type_descr
),
1415 *myleaf
.body
.node
.nodes
[node_pos
++]);
1418 if ((p_err_descr
->omit_after
!= -1) && (i
>= p_err_descr
->omit_after
))
1421 return myleaf
.length
= encoded_length
;
1424 int Record_Of_Type::JSON_encode(const TTCN_Typedescriptor_t
&, JSON_Tokenizer
& p_tok
) const
1427 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND
,
1428 "Encoding an unbound %s of value.", is_set() ? "set" : "record");
1432 int enc_len
= p_tok
.put_next_token(JSON_TOKEN_ARRAY_START
, NULL
);
1434 for(int i
= 0; i
< get_nof_elements(); ++i
) {
1435 int ret_val
= get_at(i
)->JSON_encode(*get_elem_descr(), p_tok
);
1436 if (0 > ret_val
) break;
1440 enc_len
+= p_tok
.put_next_token(JSON_TOKEN_ARRAY_END
, NULL
);
1444 int Record_Of_Type::JSON_decode(const TTCN_Typedescriptor_t
& p_td
, JSON_Tokenizer
& p_tok
, boolean p_silent
)
1446 json_token_t token
= JSON_TOKEN_NONE
;
1447 int dec_len
= p_tok
.get_next_token(&token
, NULL
, NULL
);
1448 if (JSON_TOKEN_ERROR
== token
) {
1449 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG
, JSON_DEC_BAD_TOKEN_ERROR
, "");
1450 return JSON_ERROR_FATAL
;
1452 else if (JSON_TOKEN_ARRAY_START
!= token
) {
1453 return JSON_ERROR_INVALID_TOKEN
;
1458 // Read value tokens until we reach some other token
1459 size_t buf_pos
= p_tok
.get_buf_pos();
1460 Base_Type
* val
= create_elem();
1461 int ret_val
= val
->JSON_decode(*get_elem_descr(), p_tok
, p_silent
);
1462 if (JSON_ERROR_INVALID_TOKEN
== ret_val
) {
1463 // undo the last action on the buffer
1464 p_tok
.set_buf_pos(buf_pos
);
1468 else if (JSON_ERROR_FATAL
== ret_val
) {
1473 return JSON_ERROR_FATAL
;
1475 if (NULL
== refd_ind_ptr
) {
1476 val_ptr
->value_elements
= (Base_Type
**)reallocate_pointers(
1477 (void**)val_ptr
->value_elements
, val_ptr
->n_elements
, val_ptr
->n_elements
+ 1);
1478 val_ptr
->value_elements
[val_ptr
->n_elements
] = val
;
1479 val_ptr
->n_elements
++;
1482 get_at(get_nof_elements())->set_value(val
);
1488 dec_len
+= p_tok
.get_next_token(&token
, NULL
, NULL
);
1489 if (JSON_TOKEN_ARRAY_END
!= token
) {
1490 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG
, JSON_DEC_REC_OF_END_TOKEN_ERROR
, "");
1494 return JSON_ERROR_FATAL
;
1500 void Record_Of_Type::encode(const TTCN_Typedescriptor_t
& p_td
,
1501 TTCN_Buffer
& p_buf
, TTCN_EncDec::coding_t p_coding
, ...) const
1504 va_start(pvar
, p_coding
);
1506 case TTCN_EncDec::CT_BER
: {
1507 TTCN_EncDec_ErrorContext
ec("While BER-encoding type '%s': ", p_td
.name
);
1508 unsigned BER_coding
=va_arg(pvar
, unsigned);
1509 BER_encode_chk_coding(BER_coding
);
1510 ASN_BER_TLV_t
*tlv
=BER_encode_TLV(p_td
, BER_coding
);
1511 tlv
->put_in_buffer(p_buf
);
1512 ASN_BER_TLV_t::destruct(tlv
);
1514 case TTCN_EncDec::CT_RAW
: {
1515 TTCN_EncDec_ErrorContext
ec("While RAW-encoding type '%s': ", p_td
.name
);
1517 TTCN_EncDec_ErrorContext::error_internal("No RAW descriptor available for type '%s'.", p_td
.name
);
1521 RAW_enc_tree
root(FALSE
, NULL
, &rp
, 1, p_td
.raw
);
1522 RAW_encode(p_td
, root
);
1523 root
.put_to_buf(p_buf
);
1525 case TTCN_EncDec::CT_TEXT
: {
1526 TTCN_EncDec_ErrorContext
ec("While TEXT-encoding type '%s': ", p_td
.name
);
1527 if(!p_td
.text
) TTCN_EncDec_ErrorContext::error_internal
1528 ("No TEXT descriptor available for type '%s'.", p_td
.name
);
1529 TEXT_encode(p_td
,p_buf
);
1531 case TTCN_EncDec::CT_XER
: {
1532 TTCN_EncDec_ErrorContext
ec("While XER-encoding type '%s': ", p_td
.name
);
1533 unsigned XER_coding
=va_arg(pvar
, unsigned);
1534 XER_encode(*(p_td
.xer
),p_buf
, XER_coding
, 0, 0);
1537 case TTCN_EncDec::CT_JSON
: {
1538 TTCN_EncDec_ErrorContext
ec("While JSON-encoding type '%s': ", p_td
.name
);
1539 if(!p_td
.json
) TTCN_EncDec_ErrorContext::error_internal
1540 ("No JSON descriptor available for type '%s'.", p_td
.name
);
1541 JSON_Tokenizer
tok(va_arg(pvar
, int) != 0);
1542 JSON_encode(p_td
, tok
);
1543 p_buf
.put_s(tok
.get_buffer_length(), (const unsigned char*)tok
.get_buffer());
1546 TTCN_error("Unknown coding method requested to encode type '%s'", p_td
.name
);
1551 void Record_Of_Type::decode(const TTCN_Typedescriptor_t
& p_td
,
1552 TTCN_Buffer
& p_buf
, TTCN_EncDec::coding_t p_coding
, ...)
1555 va_start(pvar
, p_coding
);
1557 case TTCN_EncDec::CT_BER
: {
1558 TTCN_EncDec_ErrorContext
ec("While BER-decoding type '%s': ", p_td
.name
);
1559 unsigned L_form
=va_arg(pvar
, unsigned);
1561 BER_decode_str2TLV(p_buf
, tlv
, L_form
);
1562 BER_decode_TLV(p_td
, tlv
, L_form
);
1563 if(tlv
.isComplete
) p_buf
.increase_pos(tlv
.get_len());
1565 case TTCN_EncDec::CT_RAW
: {
1566 TTCN_EncDec_ErrorContext
ec("While RAW-decoding type '%s': ", p_td
.name
);
1567 if(!p_td
.raw
) TTCN_EncDec_ErrorContext::error_internal
1568 ("No RAW descriptor available for type '%s'.", p_td
.name
);
1570 switch(p_td
.raw
->top_bit_order
) {
1578 if(RAW_decode(p_td
, p_buf
, p_buf
.get_len()*8, order
)<0)
1579 ec
.error(TTCN_EncDec::ET_INCOMPL_MSG
,"Can not decode type '%s', "
1580 "because invalid or incomplete message was received", p_td
.name
);
1582 case TTCN_EncDec::CT_TEXT
: {
1583 Limit_Token_List limit
;
1584 TTCN_EncDec_ErrorContext
ec("While TEXT-decoding type '%s': ", p_td
.name
);
1585 if(!p_td
.text
) TTCN_EncDec_ErrorContext::error_internal
1586 ("No TEXT descriptor available for type '%s'.", p_td
.name
);
1587 const unsigned char *b
=p_buf
.get_data();
1588 if(b
[p_buf
.get_len()-1]!='\0'){
1589 p_buf
.set_pos(p_buf
.get_len());
1590 p_buf
.put_zero(8,ORDER_LSB
);
1593 if(TEXT_decode(p_td
,p_buf
,limit
)<0)
1594 ec
.error(TTCN_EncDec::ET_INCOMPL_MSG
,"Can not decode type '%s', "
1595 "because invalid or incomplete message was received", p_td
.name
);
1597 case TTCN_EncDec::CT_XER
: {
1598 TTCN_EncDec_ErrorContext
ec("While XER-decoding type '%s': ", p_td
.name
);
1599 unsigned XER_coding
=va_arg(pvar
, unsigned);
1600 XmlReaderWrap
reader(p_buf
);
1601 for (int success
=reader
.Read(); success
==1; success
=reader
.Read()) {
1602 if (reader
.NodeType() == XML_READER_TYPE_ELEMENT
) break;
1604 XER_decode(*(p_td
.xer
), reader
, XER_coding
| XER_TOPLEVEL
, 0);
1605 size_t bytes
= reader
.ByteConsumed();
1606 p_buf
.set_pos(bytes
);
1608 case TTCN_EncDec::CT_JSON
: {
1609 TTCN_EncDec_ErrorContext
ec("While JSON-decoding type '%s': ", p_td
.name
);
1610 if(!p_td
.json
) TTCN_EncDec_ErrorContext::error_internal
1611 ("No JSON descriptor available for type '%s'.", p_td
.name
);
1612 JSON_Tokenizer
tok((const char*)p_buf
.get_data(), p_buf
.get_len());
1613 if(JSON_decode(p_td
, tok
, false)<0)
1614 ec
.error(TTCN_EncDec::ET_INCOMPL_MSG
,"Can not decode type '%s', "
1615 "because invalid or incomplete message was received", p_td
.name
);
1616 p_buf
.set_pos(tok
.get_buf_pos());
1619 TTCN_error("Unknown coding method requested to decode type '%s'", p_td
.name
);
1624 char **Record_Of_Type::collect_ns(const XERdescriptor_t
& p_td
, size_t& num
, bool& def_ns
) const
1626 size_t num_collected
= 0;
1627 // First, our own namespace. Sets num_collected to 0 or 1.
1628 // If it throws, nothing was allocated.
1629 char **collected_ns
= Base_Type::collect_ns(p_td
, num_collected
, def_ns
);
1631 // Then the embedded type
1633 bool def_ns_1
= false;
1634 if (val_ptr
) for (int i
= 0; i
< get_nof_elements(); ++i
) {
1636 char **new_namespaces
= get_at(i
)->collect_ns(
1637 *get_elem_descr()->xer
, num_new
, def_ns_1
);
1638 merge_ns(collected_ns
, num_collected
, new_namespaces
, num_new
);
1639 def_ns
= def_ns
|| def_ns_1
; // alas, no ||=
1643 // Probably a TC_Error thrown from the element's collect_ns(),
1644 // e.g. if encoding an unbound value.
1645 while (num_collected
> 0) Free(collected_ns
[--num_collected
]);
1650 num
= num_collected
;
1651 return collected_ns
;
1654 static const universal_char sp
= { 0,0,0,' ' };
1655 static const universal_char tb
= { 0,0,0,9 };
1657 int Record_Of_Type::XER_encode(const XERdescriptor_t
& p_td
, TTCN_Buffer
& p_buf
,
1658 unsigned int flavor
, int indent
, embed_values_enc_struct_t
* emb_val
) const
1661 return XER_encode_negtest(err_descr
, p_td
, p_buf
, flavor
, indent
, emb_val
);
1664 if (val_ptr
== 0) TTCN_error(
1665 "Attempt to XER-encode an unbound record of type %s", get_descriptor()->name
);
1666 int encoded_length
= (int)p_buf
.get_len();
1668 const int exer
= is_exer(flavor
);
1669 const boolean own_tag
=
1670 !(exer
&& indent
&& (p_td
.xer_bits
& (ANY_ELEMENT
|ANY_ATTRIBUTES
|UNTAGGED
)));
1672 const int indenting
= !is_canonical(flavor
) && own_tag
;
1673 const boolean xmlValueList
= isXmlValueList();
1676 | ( (exer
&& (p_td
.xer_bits
& XER_LIST
))
1677 || is_exerlist(flavor
) ? SIMPLE_TYPE
: 0);
1678 flavor
&= ~XER_RECOF
; // record-of doesn't care
1679 int nof_elements
= get_nof_elements();
1680 Base_Type::begin_xml(p_td
, p_buf
, flavor
, indent
, !nof_elements
,
1681 (collector_fn
)&Record_Of_Type::collect_ns
);
1683 if (xmlValueList
&& nof_elements
&& indenting
&& !exer
) { /* !exer or GDMO */
1684 do_indent(p_buf
, indent
+1);
1687 if (exer
&& (p_td
.xer_bits
& ANY_ATTRIBUTES
)) {
1688 // Back up over the '>' and the '\n' that may follow it
1689 size_t buf_len
= p_buf
.get_len(), shorter
= 0;
1690 const unsigned char * const buf_data
= p_buf
.get_data();
1691 if (buf_data
[buf_len
- 1 - shorter
] == '\n') ++shorter
;
1692 if (buf_data
[buf_len
- 1 - shorter
] == '>' ) ++shorter
;
1694 unsigned char saved
[4];
1696 memcpy(saved
, buf_data
+ (buf_len
- shorter
), shorter
);
1697 p_buf
.increase_length(-shorter
);
1700 // ANY_ATTRIBUTES means it's a record of universal charstring.
1701 // They are in AnyAttributeFormat (X.693/2008 18.2.6):
1702 // "URI(optional), space, NCName, equals, \"xmlcstring\""
1703 // They need to be written as an XML attribute and namespace declaration:
1704 // xmlns:b0="URI" b0:NCName="xmlcstring"
1706 for (int i
= 0; i
< nof_elements
; ++i
) {
1707 TTCN_EncDec_ErrorContext
ec_0("Attribute %d: ", i
);
1708 if (!is_elem_bound(i
)) {
1709 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND
,
1710 "Encoding an unbound universal charstring value.");
1713 const UNIVERSAL_CHARSTRING
*elem
1714 = static_cast<const UNIVERSAL_CHARSTRING
*>(val_ptr
->value_elements
[i
]);
1715 size_t len
= elem
->lengthof();
1717 const UNIVERSAL_CHARSTRING_ELEMENT
& ue
= (*elem
)[len
- 1];
1718 if (sp
== ue
|| tb
== ue
) --len
;
1721 // sp_at: indexes the first space
1722 // j is left to point at where the attribute name begins (just past the space)
1723 size_t j
, sp_at
= 0;
1724 for (j
= 0; j
< len
; j
++) {
1725 const UNIVERSAL_CHARSTRING_ELEMENT
& ue
= (*elem
)[j
];
1726 if (sp_at
) { // already found a space
1727 if (sp
== ue
|| tb
== ue
) {} // another space, do nothing
1728 else break; // found a non-space after a space
1731 if (sp
== ue
|| tb
== ue
) sp_at
= j
;
1735 size_t buf_start
= p_buf
.get_len();
1737 char * ns
= mprintf(" xmlns:b%d='", i
);
1738 size_t ns_len
= mstrlen(ns
);
1739 p_buf
.put_s(ns_len
, (cbyte
*)ns
);
1741 UNIVERSAL_CHARSTRING
before(sp_at
, (const universal_char
*)(*elem
));
1742 if (p_td
.xer_bits
& (ANY_FROM
| ANY_EXCEPT
)) {
1743 // Ensure the namespace abides to its restrictions
1745 before
.encode_utf8(ns_buf
);
1747 ns_buf
.get_string(cs
);
1748 check_namespace_restrictions(p_td
, (const char*)cs
);
1750 before
.XER_encode(UNIVERSAL_CHARSTRING_xer_
, p_buf
,
1751 flavor
| ANY_ATTRIBUTES
, indent
, 0);
1756 // Keep just the "b%d" part from ns
1757 p_buf
.put_s(ns_len
- 9, (cbyte
*)ns
+ 7);
1765 if (p_td
.xer_bits
& (ANY_FROM
| ANY_EXCEPT
)) {
1766 // Make sure the unqualified namespace is allowed
1767 check_namespace_restrictions(p_td
, NULL
);
1771 UNIVERSAL_CHARSTRING
after(len
- j
, (const universal_char
*)(*elem
) + j
);
1772 after
.XER_encode(UNIVERSAL_CHARSTRING_xer_
, p_buf
,
1773 flavor
| ANY_ATTRIBUTES
, indent
, 0);
1775 // Put this attribute in a dummy element and walk through it to check its validity
1776 TTCN_Buffer check_buf
;
1777 check_buf
.put_s(2, (unsigned char*)"<a");
1778 check_buf
.put_s(p_buf
.get_len() - buf_start
, p_buf
.get_data() + buf_start
);
1779 check_buf
.put_s(2, (unsigned char*)"/>");
1780 XmlReaderWrap
checker(check_buf
);
1781 while (1 == checker
.Read());
1784 p_buf
.put_s(shorter
, saved
); // restore the '>' and anything after
1787 else { // not ANY-ATTRIBUTES
1788 unsigned int sub_flavor
= flavor
| XER_RECOF
| (p_td
.xer_bits
& (XER_LIST
));
1790 for (int i
= 0; i
< nof_elements
; ++i
) {
1791 if (i
> 0 && !own_tag
&& 0 != emb_val
&&
1792 emb_val
->embval_index
< emb_val
->embval_array
->size_of()) {
1793 emb_val
->embval_array
->get_at(emb_val
->embval_index
)->XER_encode(
1794 UNIVERSAL_CHARSTRING_xer_
, p_buf
, flavor
| EMBED_VALUES
, indent
+1, 0);
1795 ++emb_val
->embval_index
;
1797 if (exer
&& (p_td
.xer_bits
& XER_LIST
) && i
>0) p_buf
.put_c(' ');
1798 get_at(i
)->XER_encode(*get_elem_descr()->xer
, p_buf
,
1799 sub_flavor
, indent
+own_tag
, emb_val
);
1802 if (indenting
&& nof_elements
&& !is_exerlist(flavor
)) {
1803 if (xmlValueList
&& !exer
) p_buf
.put_c('\n'); /* !exer or GDMO */
1804 //do_indent(p_buf, indent);
1808 Base_Type::end_xml(p_td
, p_buf
, flavor
, indent
, !nof_elements
);
1809 return (int)p_buf
.get_len() - encoded_length
;
1812 // XERSTUFF Record_Of_Type::encode_element
1813 /** Helper for Record_Of_Type::XER_encode_negtest
1815 * The main purpose of this method is to allow another type to request
1816 * encoding of a single element of the record-of. Used by Record_Type
1817 * to encode individual strings of the EMBED-VALUES member.
1819 * @param i index of the element
1820 * @param ev erroneous descriptor for the element itself
1821 * @param ed deeper erroneous values
1822 * @param p_buf buffer containing the encoded value
1823 * @param sub_flavor flags
1824 * @param indent indentation level
1825 * @return number of bytes generated
1827 int Record_Of_Type::encode_element(int i
,
1828 const Erroneous_values_t
* ev
, const Erroneous_descriptor_t
* ed
,
1829 TTCN_Buffer
& p_buf
, unsigned int sub_flavor
, int indent
, embed_values_enc_struct_t
* emb_val
) const
1831 int enc_len
= p_buf
.get_len();
1832 TTCN_EncDec_ErrorContext ec
;
1833 const int exer
= is_exer(sub_flavor
);
1835 if (ev
&& ev
->before
) {
1836 if (ev
->before
->errval
==NULL
) {
1837 TTCN_error("internal error: erroneous before value missing");
1839 ec
.set_msg("Erroneous value before component #%d: ", i
);
1840 if (ev
->before
->raw
) {
1841 ev
->before
->errval
->encode_raw(p_buf
);
1843 if (ev
->before
->type_descr
==NULL
) TTCN_error(
1844 "internal error: erroneous before type descriptor missing");
1845 ev
->before
->errval
->XER_encode(*ev
->before
->type_descr
->xer
,
1846 p_buf
, sub_flavor
, indent
, 0);
1850 if (exer
&& (sub_flavor
& XER_LIST
)
1851 && (i
> 0 || (ev
&& ev
->before
&& !ev
->before
->raw
))){
1852 // Ensure a separator is written after the "erroneous before"
1853 // of the first element (except for "raw before").
1857 if (ev
&& ev
->value
) {
1858 if (ev
->value
->errval
) { // replace
1859 ec
.set_msg("Erroneous value for component #%d: ", i
);
1860 if (ev
->value
->raw
) {
1861 ev
->value
->errval
->encode_raw(p_buf
);
1863 if (ev
->value
->type_descr
==NULL
) TTCN_error(
1864 "internal error: erroneous value type descriptor missing");
1865 ev
->value
->errval
->XER_encode(*ev
->value
->type_descr
->xer
,
1866 p_buf
, sub_flavor
, indent
, 0);
1870 ec
.set_msg("Component #%d: ", i
);
1872 get_at(i
)->XER_encode_negtest(ed
, *get_elem_descr()->xer
, p_buf
, sub_flavor
, indent
, emb_val
);
1874 // the "real" encoder
1875 get_at(i
)->XER_encode(*get_elem_descr()->xer
, p_buf
, sub_flavor
, indent
, emb_val
);
1879 if (ev
&& ev
->after
) {
1880 if (ev
->after
->errval
==NULL
) {
1881 TTCN_error("internal error: erroneous after value missing");
1883 ec
.set_msg("Erroneous value after component #%d: ", i
);
1884 if (ev
->after
->raw
) {
1885 ev
->after
->errval
->encode_raw(p_buf
);
1887 if (ev
->after
->type_descr
==NULL
) TTCN_error(
1888 "internal error: erroneous after type descriptor missing");
1889 ev
->after
->errval
->XER_encode(*ev
->after
->type_descr
->xer
,
1890 p_buf
, sub_flavor
, indent
, 0);
1897 // XERSTUFF Record_Of_Type::XER_encode_negtest
1898 int Record_Of_Type::XER_encode_negtest(const Erroneous_descriptor_t
* p_err_descr
,
1899 const XERdescriptor_t
& p_td
, TTCN_Buffer
& p_buf
, unsigned flavor
, int indent
,
1900 embed_values_enc_struct_t
* emb_val
) const
1902 if (val_ptr
== 0) TTCN_error(
1903 "Attempt to XER-encode an unbound record of type %s", get_descriptor()->name
);
1904 int encoded_length
= (int)p_buf
.get_len();
1906 const int exer
= is_exer(flavor
);
1907 const boolean own_tag
=
1908 !(exer
&& indent
&& (p_td
.xer_bits
& (ANY_ELEMENT
|ANY_ATTRIBUTES
|UNTAGGED
)));
1910 const int indenting
= !is_canonical(flavor
) && own_tag
;
1911 const boolean xmlValueList
= isXmlValueList();
1914 | ( (exer
&& (p_td
.xer_bits
& XER_LIST
))
1915 || is_exerlist(flavor
) ? SIMPLE_TYPE
: 0);
1916 flavor
&= ~XER_RECOF
; // record-of doesn't care
1917 int nof_elements
= get_nof_elements();
1918 Base_Type::begin_xml(p_td
, p_buf
, flavor
, indent
, !nof_elements
,
1919 (collector_fn
)&Record_Of_Type::collect_ns
);
1921 if (xmlValueList
&& nof_elements
&& indenting
&& !exer
) { /* !exer or GDMO */
1922 do_indent(p_buf
, indent
+1);
1927 if (exer
&& (p_td
.xer_bits
& ANY_ATTRIBUTES
)) {
1928 // Back up over the '>' and the '\n' that may follow it
1929 size_t buf_len
= p_buf
.get_len(), shorter
= 0;
1930 const unsigned char * const buf_data
= p_buf
.get_data();
1931 if (buf_data
[buf_len
- 1 - shorter
] == '\n') ++shorter
;
1932 if (buf_data
[buf_len
- 1 - shorter
] == '>' ) ++shorter
;
1934 unsigned char * saved
= 0;
1936 saved
= new unsigned char[shorter
];
1937 memcpy(saved
, buf_data
+ (buf_len
- shorter
), shorter
);
1938 p_buf
.increase_length(-shorter
);
1941 // ANY_ATTRIBUTES means it's a record of universal charstring.
1942 // They are in AnyAttributeFormat (X.693/2008 18.2.6):
1943 // "URI(optional), space, NCName, equals, \"xmlcstring\""
1944 // They need to be written as an XML attribute and namespace declaration:
1945 // xmlns:b0="URI" b0:NCName="xmlcstring"
1947 for (int i
= 0; i
< nof_elements
; ++i
) {
1948 if (i
< p_err_descr
->omit_before
) continue;
1950 const Erroneous_values_t
*ev
= p_err_descr
->next_field_err_values(i
, values_idx
);
1951 const Erroneous_descriptor_t
*ed
= p_err_descr
->next_field_emb_descr(i
, edescr_idx
);
1953 if (ev
&& ev
->before
) {
1954 if (ev
->before
->errval
==NULL
) TTCN_error("internal error: erroneous value missing");
1957 if (ev
->before
->raw
) ev
->before
->errval
->encode_raw(p_buf
);
1959 if (ev
->before
->type_descr
==NULL
) TTCN_error(
1960 "internal error: erroneous before type descriptor missing");
1961 else ev
->before
->errval
->XER_encode(*ev
->before
->type_descr
->xer
,
1962 p_buf
, flavor
, indent
, 0);
1966 if (ev
&& ev
->value
) { //value replacement
1967 if (ev
->value
->errval
) {
1968 if (ev
->value
->raw
) ev
->value
->errval
->encode_raw(p_buf
);
1970 if (ev
->value
->type_descr
==NULL
) TTCN_error(
1971 "internal error: erroneous value type descriptor missing");
1972 else ev
->value
->errval
->XER_encode(*ev
->value
->type_descr
->xer
,
1973 p_buf
, flavor
, indent
, 0);
1979 // embedded descr.. call negtest (except UNIVERSAL_CHARSTRING
1980 // doesn't have XER_encode_negtest)
1981 TTCN_error("internal error: embedded descriptor for scalar");
1984 // the original encoding
1985 const UNIVERSAL_CHARSTRING
*elem
1986 = static_cast<const UNIVERSAL_CHARSTRING
*>(get_at(i
));
1987 size_t len
= elem
->lengthof();
1989 const UNIVERSAL_CHARSTRING_ELEMENT
& ue
= (*elem
)[len
- 1];
1990 if (sp
== ue
|| tb
== ue
) --len
;
1993 // sp_at: indexes the first space
1994 // j is left to point at where the attribute name begins (just past the space)
1995 size_t j
, sp_at
= 0;
1996 for (j
= 0; j
< len
; j
++) {
1997 const UNIVERSAL_CHARSTRING_ELEMENT
& ue
= (*elem
)[j
];
1998 if (sp_at
) { // already found a space
1999 if (sp
== ue
|| tb
== ue
) {} // another space, do nothing
2000 else break; // found a non-space after a space
2003 if (sp
== ue
|| tb
== ue
) sp_at
= j
;
2008 char * ns
= mprintf(" xmlns:b%d='", i
);
2009 size_t ns_len
= mstrlen(ns
);
2010 p_buf
.put_s(ns_len
, (cbyte
*)ns
);
2012 UNIVERSAL_CHARSTRING
before(sp_at
, (const universal_char
*)(*elem
));
2013 before
.XER_encode(UNIVERSAL_CHARSTRING_xer_
, p_buf
,
2014 flavor
| ANY_ATTRIBUTES
, indent
, 0);
2019 // Keep just the "b%d" part from ns
2020 p_buf
.put_s(ns_len
- 9, (cbyte
*)ns
+ 7);
2029 UNIVERSAL_CHARSTRING
after(len
- j
, (const universal_char
*)(*elem
) + j
);
2030 after
.XER_encode(UNIVERSAL_CHARSTRING_xer_
, p_buf
,
2031 flavor
| ANY_ATTRIBUTES
, indent
, 0);
2035 if (ev
&& ev
->after
) {
2036 if (ev
->after
->errval
==NULL
) TTCN_error(
2037 "internal error: erroneous after value missing");
2039 if (ev
->after
->raw
) ev
->after
->errval
->encode_raw(p_buf
);
2041 if (ev
->after
->type_descr
==NULL
) TTCN_error(
2042 "internal error: erroneous after type descriptor missing");
2043 else ev
->after
->errval
->XER_encode(*ev
->after
->type_descr
->xer
,
2044 p_buf
, flavor
, indent
, 0);
2048 // omit_after value -1 becomes "very big"
2049 if ((unsigned int)i
>= (unsigned int)p_err_descr
->omit_after
) break;
2052 p_buf
.put_s(shorter
, saved
); // restore the '>' and anything after
2056 else { // not ANY-ATTRIBUTES
2057 unsigned int sub_flavor
= flavor
| XER_RECOF
| (p_td
.xer_bits
& (XER_LIST
|ANY_ATTRIBUTES
));
2059 TTCN_EncDec_ErrorContext ec
;
2061 for (int i
= 0; i
< nof_elements
; ++i
) {
2062 if (i
< p_err_descr
->omit_before
) continue;
2064 if (0 != emb_val
&& i
> 0 && !own_tag
&&
2065 emb_val
->embval_index
< emb_val
->embval_array
->size_of()) {
2066 const Erroneous_values_t
* ev0_i
= NULL
;
2067 const Erroneous_descriptor_t
* ed0_i
= NULL
;
2068 if (emb_val
->embval_err
) {
2069 ev0_i
= emb_val
->embval_err
->next_field_err_values(emb_val
->embval_index
, emb_val
->embval_err_val_idx
);
2070 ed0_i
= emb_val
->embval_err
->next_field_emb_descr (emb_val
->embval_index
, emb_val
->embval_err_descr_idx
);
2072 emb_val
->embval_array
->encode_element(emb_val
->embval_index
, ev0_i
, ed0_i
,
2073 p_buf
, flavor
| EMBED_VALUES
, indent
+ own_tag
, 0);
2074 ++emb_val
->embval_index
;
2077 const Erroneous_values_t
* err_vals
=
2078 p_err_descr
->next_field_err_values(i
, values_idx
);
2079 const Erroneous_descriptor_t
* emb_descr
=
2080 p_err_descr
->next_field_emb_descr (i
, edescr_idx
);
2082 encode_element(i
, err_vals
, emb_descr
, p_buf
, sub_flavor
, indent
+own_tag
, emb_val
);
2084 // omit_after value -1 becomes "very big"
2085 if ((unsigned int)i
>= (unsigned int)p_err_descr
->omit_after
) break;
2088 if (indenting
&& nof_elements
&& !is_exerlist(flavor
)) {
2089 if (xmlValueList
&& !exer
) p_buf
.put_c('\n'); /* !exer or GDMO */
2090 //do_indent(p_buf, indent);
2094 Base_Type::end_xml(p_td
, p_buf
, flavor
, indent
, !nof_elements
);
2095 return (int)p_buf
.get_len() - encoded_length
;
2098 int Record_Of_Type::XER_decode(const XERdescriptor_t
& p_td
,
2099 XmlReaderWrap
& reader
, unsigned int flavor
, embed_values_dec_struct_t
* emb_val
)
2101 int exer
= is_exer(flavor
);
2102 int xerbits
= p_td
.xer_bits
;
2103 if (flavor
& XER_TOPLEVEL
) xerbits
&= ~UNTAGGED
;
2105 !(exer
&& ((xerbits
& (ANY_ELEMENT
| ANY_ATTRIBUTES
| UNTAGGED
))
2106 || (flavor
& USE_TYPE_ATTR
))); /* incase the parent has USE-UNION */
2107 /* not toplevel anymore and remove the flags for USE-UNION the oftype doesn't need them */
2108 flavor
&= ~XER_TOPLEVEL
& ~XER_LIST
& ~USE_TYPE_ATTR
;
2109 int success
=1, depth
=-1;
2110 set_val(NULL_VALUE
); // empty but initialized array, val_ptr != NULL
2112 if (own_tag
) for (success
= 1; success
== 1; success
= reader
.Read()) {
2113 type
= reader
.NodeType();
2114 if (exer
&& (p_td
.xer_bits
& XER_ATTRIBUTE
)) {
2115 if (XML_READER_TYPE_ATTRIBUTE
== type
) break;
2117 if (exer
&& (p_td
.xer_bits
& XER_LIST
)) {
2118 if (XML_READER_TYPE_TEXT
== type
) break;
2121 if (XML_READER_TYPE_ELEMENT
== type
) {
2122 verify_name(reader
, p_td
, exer
);
2123 depth
= reader
.Depth();
2126 } /* endif(exer && list) */
2128 else depth
= reader
.Depth();
2129 TTCN_EncDec_ErrorContext
ec_0("Index ");
2130 TTCN_EncDec_ErrorContext ec_1
;
2131 flavor
|= XER_RECOF
;
2132 if (exer
&& (p_td
.xer_bits
& ANY_ATTRIBUTES
)) {
2133 // The enclosing type should handle the decoding.
2134 TTCN_error("Incorrect decoding of ANY-ATTRIBUTES");
2136 else if (exer
&& (p_td
.xer_bits
& XER_LIST
)) { /* LIST decoding*/
2137 char *val
= (char*)reader
.NewValue(); /* we own it */
2139 size_t len
= strlen(val
);
2140 /* The string contains a bunch of values separated by whitespace.
2141 * Tokenize the string and create a new buffer which looks like
2142 * an XML element (<ns:name xmlns:ns='uri'>value</ns:name>), then use that
2143 * to decode the value. */
2144 for(char * str
= strtok(val
, " \t\x0A\x0D"); str
!= 0; str
= strtok(val
+ pos
, " \t\x0A\x0D")) {
2145 // Calling strtok with NULL won't work here, since the decoded element can have strtok calls aswell
2146 pos
+= strlen(str
) + 1;
2147 // Construct a new XML Reader with the current token.
2149 const XERdescriptor_t
& sub_xer
= *get_elem_descr()->xer
;
2151 write_ns_prefix(sub_xer
, buf2
);
2153 boolean i_can_has_ns
= sub_xer
.my_module
!= 0 && sub_xer
.ns_index
!= -1;
2154 const char * const exer_name
= sub_xer
.names
[1];
2155 buf2
.put_s((size_t)sub_xer
.namelens
[1]-1-i_can_has_ns
, (cbyte
*)exer_name
);
2157 const namespace_t
* const pns
= sub_xer
.my_module
->get_ns(sub_xer
.ns_index
);
2158 buf2
.put_s(7 - (*pns
->px
== 0), (cbyte
*)" xmlns:");
2159 buf2
.put_s(strlen(pns
->px
), (cbyte
*)pns
->px
);
2160 buf2
.put_s(2, (cbyte
*)"='");
2161 buf2
.put_s(strlen(pns
->ns
), (cbyte
*)pns
->ns
);
2162 buf2
.put_s(2, (cbyte
*)"'>");
2164 // start tag completed
2165 buf2
.put_s(strlen(str
), (cbyte
*)str
);
2169 write_ns_prefix(sub_xer
, buf2
);
2170 buf2
.put_s((size_t)sub_xer
.namelens
[1], (cbyte
*)exer_name
);
2171 XmlReaderWrap
reader2(buf2
);
2172 reader2
.Read(); // Move to the start element.
2173 // Don't move to the #text, that's the callee's responsibility.
2174 ec_1
.set_msg("%d: ", get_nof_elements());
2175 // The call to the non-const operator[], I mean get_at(), creates
2176 // a new element (because it is indexing one past the last element).
2177 // Then we call its XER_decode with the temporary XML reader.
2178 get_at(get_nof_elements())->XER_decode(sub_xer
, reader2
, flavor
, 0);
2179 if (flavor
& EXIT_ON_ERROR
&& !is_elem_bound(get_nof_elements() - 1)) {
2180 if (1 == get_nof_elements()) {
2181 // Failed to decode even the first element
2184 // Some elements were successfully decoded -> only delete the last one
2185 set_size(get_nof_elements() - 1);
2190 if (pos
>= len
) break;
2193 if (p_td
.xer_bits
& XER_ATTRIBUTE
) {
2194 //Let the caller do reader.AdvanceAttribute();
2197 reader
.Read(); // on closing tag
2198 reader
.Read(); // past it
2202 if (flavor
& PARENT_CLOSED
) {
2203 // Nothing to do. We are probably untagged; do not advance in the XML
2204 // because it would move past the parent.
2206 else if (own_tag
&& reader
.IsEmptyElement()) { // Nothing to do
2207 reader
.Read(); // This is our own empty tag, move past it
2210 /* Note: there is no reader.Read() at the end of the loop below.
2211 * Each element is supposed to consume enough to leave the next element
2212 * well-positioned. */
2213 for (success
= own_tag
? reader
.Read() : reader
.Ok(); success
== 1; ) {
2214 type
= reader
.NodeType();
2215 if (XML_READER_TYPE_ELEMENT
== type
)
2217 if (exer
&& (p_td
.xer_bits
& ANY_ELEMENT
)) {
2218 /* This is a (record-of UNIVERSAL_CHARSTRING) with ANY-ELEMENT.
2219 * The ANY-ELEMENT is really meant for the element type,
2220 * so behave like a record-of (string with ANY-ELEMENT):
2221 * call the non-const operator[], I mean get_at(), to create
2222 * a new element, then read the entire XML element into it. */
2223 UNIVERSAL_CHARSTRING
* uc
=
2224 static_cast<UNIVERSAL_CHARSTRING
*>(get_at(val_ptr
->n_elements
));
2225 const xmlChar
* outer
= reader
.ReadOuterXml();
2226 uc
->decode_utf8(strlen((const char*)outer
), outer
);
2227 // consume the element
2228 for (success
= reader
.Read(); success
== 1 && reader
.Depth() > depth
; success
= reader
.Read()) {}
2229 if (reader
.NodeType() != XML_READER_TYPE_ELEMENT
) success
= reader
.Read(); // one last time
2232 /* If this is an untagged record-of and the start element does not
2233 * belong to the embedded type, the record-of has already ended. */
2234 if (!own_tag
&& !can_start_v(
2235 (const char*)reader
.LocalName(), (const char*)reader
.NamespaceUri(),
2236 *get_elem_descr()->xer
, flavor
| UNTAGGED
))
2238 for (; success
== 1 && reader
.Depth() > depth
; success
= reader
.Read()) ;
2239 // We should now be back at the same depth as we started.
2242 ec_1
.set_msg("%d: ", get_nof_elements());
2243 /* The call to the non-const get_at() creates the element */
2244 get_at(get_nof_elements())->XER_decode(*get_elem_descr()->xer
, reader
, flavor
, emb_val
);
2245 if (0 != emb_val
&& !own_tag
&& get_nof_elements() > 1) {
2246 ++emb_val
->embval_index
;
2250 else if (XML_READER_TYPE_END_ELEMENT
== type
) {
2251 for (; success
== 1 && reader
.Depth() > depth
; success
= reader
.Read()) ;
2252 // If the depth just decreased, this must be an end element
2253 // (but a different one from what we had before the loop)
2255 verify_end(reader
, p_td
, depth
, exer
);
2256 reader
.Read(); // move forward one last time
2260 else if (XML_READER_TYPE_TEXT
== type
&& 0 != emb_val
&& !own_tag
&& get_nof_elements() > 0) {
2261 UNIVERSAL_CHARSTRING
emb_ustr((const char*)reader
.Value());
2262 emb_val
->embval_array
->get_at(emb_val
->embval_index
)->set_value(&emb_ustr
);
2263 success
= reader
.Read();
2266 success
= reader
.Read();
2269 } /* if not empty element */
2271 return 1; // decode successful
2274 void Record_Of_Type::set_param(Module_Param
& param
) {
2275 if (dynamic_cast<Module_Param_Name
*>(param
.get_id()) != NULL
&&
2276 param
.get_id()->next_name()) {
2277 // Haven't reached the end of the module parameter name
2278 // => the name refers to one of the elements, not to the whole record of
2279 char* param_field
= param
.get_id()->get_current_name();
2280 if (param_field
[0] < '0' || param_field
[0] > '9') {
2281 param
.error("Unexpected record field name in module parameter, expected a valid"
2282 " index for %s type `%s'", is_set() ? "set of" : "record of", get_descriptor()->name
);
2284 int param_index
= -1;
2285 sscanf(param_field
, "%d", ¶m_index
);
2286 get_at(param_index
)->set_param(param
);
2290 param
.basic_check(Module_Param::BC_VALUE
|Module_Param::BC_LIST
, is_set()?"set of value":"record of value");
2291 switch (param
.get_operation_type()) {
2292 case Module_Param::OT_ASSIGN
:
2293 if (param
.get_type()==Module_Param::MP_Value_List
&& param
.get_size()==0) {
2294 set_val(NULL_VALUE
);
2297 switch (param
.get_type()) {
2298 case Module_Param::MP_Value_List
:
2299 set_size(param
.get_size());
2300 for (size_t i
=0; i
<param
.get_size(); ++i
) {
2301 Module_Param
* const curr
= param
.get_elem(i
);
2302 if (curr
->get_type()!=Module_Param::MP_NotUsed
) {
2303 get_at(i
)->set_param(*curr
);
2307 case Module_Param::MP_Indexed_List
:
2308 for (size_t i
=0; i
<param
.get_size(); ++i
) {
2309 Module_Param
* const current
= param
.get_elem(i
);
2310 get_at(current
->get_id()->get_index())->set_param(*current
);
2314 param
.type_error(is_set()?"set of value":"record of value", get_descriptor()->name
);
2317 case Module_Param::OT_CONCAT
:
2318 switch (param
.get_type()) {
2319 case Module_Param::MP_Value_List
: {
2320 if (!is_bound()) set_val(NULL_VALUE
);
2321 int start_idx
= lengthof();
2322 for (size_t i
=0; i
<param
.get_size(); ++i
) {
2323 Module_Param
* const curr
= param
.get_elem(i
);
2324 if ((curr
->get_type()!=Module_Param::MP_NotUsed
)) {
2325 get_at(start_idx
+(int)i
)->set_param(*curr
);
2329 case Module_Param::MP_Indexed_List
:
2330 param
.error("Cannot concatenate an indexed value list");
2333 param
.type_error(is_set()?"set of value":"record of value", get_descriptor()->name
);
2337 TTCN_error("Internal error: Record_Of_Type::set_param()");
2341 void Record_Of_Type::set_implicit_omit()
2343 for (int i
= 0; i
< get_nof_elements(); ++i
) {
2344 if (is_elem_bound(i
))
2345 val_ptr
->value_elements
[i
]->set_implicit_omit();
2349 void Record_Of_Type::add_refd_index(int index
)
2351 if (NULL
== refd_ind_ptr
) {
2352 refd_ind_ptr
= new refd_index_struct
;
2353 refd_ind_ptr
->max_refd_index
= -1;
2355 refd_ind_ptr
->refd_indices
.push_back(index
);
2356 if (index
> get_max_refd_index()) {
2357 refd_ind_ptr
->max_refd_index
= index
;
2361 void Record_Of_Type::remove_refd_index(int index
)
2363 for (size_t i
= refd_ind_ptr
->refd_indices
.size(); i
> 0; --i
) {
2364 if (refd_ind_ptr
->refd_indices
[i
- 1] == index
) {
2365 refd_ind_ptr
->refd_indices
.erase_at(i
- 1);
2369 if (refd_ind_ptr
->refd_indices
.empty()) {
2370 delete refd_ind_ptr
;
2371 refd_ind_ptr
= NULL
;
2373 else if (get_max_refd_index() == index
) {
2374 refd_ind_ptr
->max_refd_index
= -1;
2378 boolean
operator==(null_type
/*null_value*/, const Record_Of_Type
& other_value
)
2380 if (other_value
.val_ptr
== NULL
)
2381 TTCN_error("The right operand of comparison is an unbound value of type %s.",
2382 other_value
.get_descriptor()->name
);
2383 return other_value
.get_nof_elements() == 0;
2386 boolean
operator!=(null_type null_value
,
2387 const Record_Of_Type
& other_value
)
2389 return !(null_value
== other_value
);
2392 ////////////////////////////////////////////////////////////////////////////////
2394 boolean
Record_Type::is_bound() const
2396 if (bound_flag
) return TRUE
;
2397 int field_cnt
= get_count();
2398 for (int field_idx
=0; field_idx
<field_cnt
; field_idx
++) {
2399 const Base_Type
* temp
= get_at(field_idx
);
2400 if(temp
->is_optional()) {
2401 if(temp
->is_present() && temp
->get_opt_value()->is_bound()) return TRUE
;
2403 if(temp
->is_bound()) return TRUE
;
2408 boolean
Record_Type::is_value() const
2413 int field_cnt
= get_count();
2414 for (int field_idx
=0; field_idx
<field_cnt
; field_idx
++) {
2415 const Base_Type
* temp
= get_at(field_idx
);
2416 if(temp
->is_optional()) {
2417 if(!temp
->is_bound()) return FALSE
;
2418 if(temp
->is_present() && !temp
->is_value()) return FALSE
;
2420 if(!temp
->is_value()) return FALSE
;
2426 void Record_Type::clean_up()
2428 int field_cnt
= get_count();
2429 for (int field_idx
=0; field_idx
<field_cnt
; field_idx
++) {
2430 get_at(field_idx
)->clean_up();
2435 void Record_Type::log() const
2438 TTCN_Logger::log_event_unbound();
2441 TTCN_Logger::log_event_str("{ ");
2442 int field_cnt
= get_count();
2443 for (int field_idx
=0; field_idx
<field_cnt
; field_idx
++) {
2444 if (field_idx
) TTCN_Logger::log_event_str(", ");
2445 TTCN_Logger::log_event_str(fld_name(field_idx
));
2446 TTCN_Logger::log_event_str(" := ");
2447 get_at(field_idx
)->log();
2449 TTCN_Logger::log_event_str(" }");
2450 if (err_descr
) err_descr
->log();
2453 void Record_Type::set_param(Module_Param
& param
) {
2455 if (dynamic_cast<Module_Param_Name
*>(param
.get_id()) != NULL
&&
2456 param
.get_id()->next_name()) {
2457 // Haven't reached the end of the module parameter name
2458 // => the name refers to one of the fields, not to the whole record
2459 char* param_field
= param
.get_id()->get_current_name();
2460 if (param_field
[0] >= '0' && param_field
[0] <= '9') {
2461 param
.error("Unexpected array index in module parameter, expected a valid field"
2462 " name for %s type `%s'", is_set() ? "set" : "record", get_descriptor()->name
);
2464 int field_cnt
= get_count();
2465 for (int field_idx
= 0; field_idx
< field_cnt
; field_idx
++) {
2466 if (strcmp(fld_name(field_idx
), param_field
) == 0) {
2467 get_at(field_idx
)->set_param(param
);
2471 param
.error("Field `%s' not found in %s type `%s'",
2472 param_field
, is_set() ? "set" : "record", get_descriptor()->name
);
2475 param
.basic_check(Module_Param::BC_VALUE
, is_set()?"set value":"record value");
2476 switch (param
.get_type()) {
2477 case Module_Param::MP_Value_List
:
2478 if (get_count()<(int)param
.get_size()) {
2479 param
.error("%s value of type %s has %d fields but list value has %d fields", is_set()?"Set":"Record", get_descriptor()->name
, get_count(), (int)param
.get_size());
2481 for (size_t i
=0; i
<param
.get_size(); i
++) {
2482 Module_Param
* mp
= param
.get_elem(i
);
2483 if (mp
->get_type()!=Module_Param::MP_NotUsed
) {
2484 get_at((int)i
)->set_param(*mp
);
2488 case Module_Param::MP_Assignment_List
:
2489 for (size_t i
=0; i
<param
.get_size(); ++i
) {
2490 Module_Param
* const current
= param
.get_elem(i
);
2492 for (int j
=0; j
<get_count(); ++j
) {
2493 if (!strcmp(fld_name(j
), current
->get_id()->get_name())) {
2494 if (current
->get_type()!=Module_Param::MP_NotUsed
) {
2495 get_at(j
)->set_param(*current
);
2502 current
->error("Non existent field name in type %s: %s.", get_descriptor()->name
, current
->get_id()->get_name());
2507 param
.type_error(is_set()?"set value":"record value", get_descriptor()->name
);
2511 void Record_Type::set_implicit_omit()
2513 int field_cnt
= get_count();
2514 for (int field_idx
= 0; field_idx
< field_cnt
; field_idx
++) {
2515 Base_Type
*temp
= get_at(field_idx
);
2516 if (temp
->is_optional()) {
2517 if (temp
->is_bound()) temp
->set_implicit_omit();
2518 else temp
->set_to_omit();
2519 } else if (temp
->is_bound()) {
2520 temp
->set_implicit_omit();
2525 int Record_Type::size_of() const
2528 TTCN_error("Calculating the size of an unbound record/set value of type %s",
2529 get_descriptor()->name
);
2531 int opt_count
= optional_count();
2532 if (opt_count
==0) return get_count();
2533 const int* optional_indexes
= get_optional_indexes();
2534 int my_size
= get_count();
2535 for (int i
=0; i
<opt_count
; i
++) {
2536 if (!get_at(optional_indexes
[i
])->ispresent()) my_size
--;
2541 void Record_Type::encode_text(Text_Buf
& text_buf
) const
2544 TTCN_error("Text encoder: Encoding an unbound record/set value of type %s.",
2545 get_descriptor()->name
);
2547 int field_cnt
= get_count();
2548 for (int field_idx
=0; field_idx
<field_cnt
; field_idx
++)
2549 get_at(field_idx
)->encode_text(text_buf
);
2552 void Record_Type::decode_text(Text_Buf
& text_buf
)
2555 int field_cnt
= get_count();
2556 for (int field_idx
=0; field_idx
<field_cnt
; field_idx
++)
2557 get_at(field_idx
)->decode_text(text_buf
);
2560 boolean
Record_Type::is_equal(const Base_Type
* other_value
) const
2562 const Record_Type
* other_record
= static_cast<const Record_Type
*>(other_value
);
2563 if (!is_bound() && !other_record
->is_bound()) {
2566 int field_cnt
= get_count();
2567 for (int field_idx
=0; field_idx
<field_cnt
; field_idx
++) {
2568 const Base_Type
* elem
= get_at(field_idx
);
2569 const Base_Type
* other_elem
= other_record
->get_at(field_idx
);
2570 if (elem
->is_bound()) {
2571 if (other_elem
->is_bound()) {
2572 if (!elem
->is_equal(other_elem
))
2574 } else return FALSE
;
2575 } else if (other_elem
->is_bound()) return FALSE
;
2580 void Record_Type::set_value(const Base_Type
* other_value
)
2582 if (this==other_value
) return;
2583 if (!other_value
->is_bound())
2584 TTCN_error("Copying an unbound record/set value of type %s.",
2585 other_value
->get_descriptor()->name
);
2586 const Record_Type
* other_record
= static_cast<const Record_Type
*>(other_value
);
2587 int field_cnt
= get_count();
2588 for (int field_idx
=0; field_idx
<field_cnt
; field_idx
++) {
2589 const Base_Type
* elem
= other_record
->get_at(field_idx
);
2590 if (elem
->is_bound()) {
2591 get_at(field_idx
)->set_value(elem
);
2593 get_at(field_idx
)->clean_up();
2596 err_descr
= other_record
->err_descr
;
2600 void Record_Type::encode(const TTCN_Typedescriptor_t
& p_td
,
2601 TTCN_Buffer
& p_buf
, TTCN_EncDec::coding_t p_coding
, ...) const
2604 va_start(pvar
, p_coding
);
2606 case TTCN_EncDec::CT_BER
: {
2607 TTCN_EncDec_ErrorContext
ec("While BER-encoding type '%s': ", p_td
.name
);
2608 unsigned BER_coding
=va_arg(pvar
, unsigned);
2609 BER_encode_chk_coding(BER_coding
);
2610 ASN_BER_TLV_t
*tlv
=BER_encode_TLV(p_td
, BER_coding
);
2611 tlv
->put_in_buffer(p_buf
);
2612 ASN_BER_TLV_t::destruct(tlv
);
2614 case TTCN_EncDec::CT_RAW
: {
2615 TTCN_EncDec_ErrorContext
ec("While RAW-encoding type '%s': ", p_td
.name
);
2616 if(!p_td
.raw
) TTCN_EncDec_ErrorContext::error_internal
2617 ("No RAW descriptor available for type '%s'.", p_td
.name
);
2621 RAW_enc_tree
root(FALSE
, NULL
, &rp
, 1, p_td
.raw
);
2622 RAW_encode(p_td
, root
);
2623 root
.put_to_buf(p_buf
);
2625 case TTCN_EncDec::CT_TEXT
: {
2626 TTCN_EncDec_ErrorContext
ec("While TEXT-encoding type '%s': ", p_td
.name
);
2627 if(!p_td
.text
) TTCN_EncDec_ErrorContext::error_internal
2628 ("No TEXT descriptor available for type '%s'.", p_td
.name
);
2629 TEXT_encode(p_td
,p_buf
);
2631 case TTCN_EncDec::CT_XER
: {
2632 TTCN_EncDec_ErrorContext
ec("While XER-encoding type '%s': ", p_td
.name
);
2633 unsigned XER_coding
=va_arg(pvar
, unsigned);
2634 XER_encode(*(p_td
.xer
),p_buf
, XER_coding
, 0, 0);
2637 case TTCN_EncDec::CT_JSON
: {
2638 TTCN_EncDec_ErrorContext
ec("While JSON-encoding type '%s': ", p_td
.name
);
2639 if(!p_td
.json
) TTCN_EncDec_ErrorContext::error_internal
2640 ("No JSON descriptor available for type '%s'.", p_td
.name
);
2641 JSON_Tokenizer
tok(va_arg(pvar
, int) != 0);
2642 JSON_encode(p_td
, tok
);
2643 p_buf
.put_s(tok
.get_buffer_length(), (const unsigned char*)tok
.get_buffer());
2646 TTCN_error("Unknown coding method requested to encode type '%s'", p_td
.name
);
2651 void Record_Type::decode(const TTCN_Typedescriptor_t
& p_td
,
2652 TTCN_Buffer
& p_buf
, TTCN_EncDec::coding_t p_coding
, ...)
2655 va_start(pvar
, p_coding
);
2657 case TTCN_EncDec::CT_BER
: {
2658 TTCN_EncDec_ErrorContext
ec("While BER-decoding type '%s': ", p_td
.name
);
2659 unsigned L_form
=va_arg(pvar
, unsigned);
2661 BER_decode_str2TLV(p_buf
, tlv
, L_form
);
2662 BER_decode_TLV(p_td
, tlv
, L_form
);
2663 if(tlv
.isComplete
) p_buf
.increase_pos(tlv
.get_len());
2665 case TTCN_EncDec::CT_RAW
: {
2666 TTCN_EncDec_ErrorContext
ec("While RAW-decoding type '%s': ", p_td
.name
);
2668 TTCN_EncDec_ErrorContext::error_internal
2669 ("No RAW descriptor available for type '%s'.", p_td
.name
);
2671 switch(p_td
.raw
->top_bit_order
) {
2679 int rawr
= RAW_decode(p_td
, p_buf
, p_buf
.get_len()*8, order
);
2680 if (rawr
< 0) switch (-rawr
) {
2681 case TTCN_EncDec::ET_INCOMPL_MSG
:
2682 case TTCN_EncDec::ET_LEN_ERR
:
2683 ec
.error(TTCN_EncDec::ET_INCOMPL_MSG
,
2684 "Can not decode type '%s', because incomplete"
2685 " message was received", p_td
.name
);
2688 // The RAW/TEXT decoders return -1 for anything not a length error.
2689 // This is the value for ET_UNBOUND, which can't happen in decoding.
2691 ec
.error(TTCN_EncDec::ET_INVAL_MSG
,
2692 "Can not decode type '%s', because invalid"
2693 " message was received", p_td
.name
);
2697 case TTCN_EncDec::CT_TEXT
: {
2698 Limit_Token_List limit
;
2699 TTCN_EncDec_ErrorContext
ec("While TEXT-decoding type '%s': ", p_td
.name
);
2700 if(!p_td
.text
) TTCN_EncDec_ErrorContext::error_internal
2701 ("No TEXT descriptor available for type '%s'.", p_td
.name
);
2702 const unsigned char *b
=p_buf
.get_data();
2703 if(b
[p_buf
.get_len()-1]!='\0'){
2704 p_buf
.set_pos(p_buf
.get_len());
2705 p_buf
.put_zero(8,ORDER_LSB
);
2708 if(TEXT_decode(p_td
,p_buf
,limit
)<0)
2709 ec
.error(TTCN_EncDec::ET_INCOMPL_MSG
,
2710 "Can not decode type '%s', because invalid or incomplete"
2711 " message was received", p_td
.name
);
2713 case TTCN_EncDec::CT_XER
: {
2714 TTCN_EncDec_ErrorContext
ec("While XER-decoding type '%s': ", p_td
.name
);
2715 unsigned XER_coding
=va_arg(pvar
, unsigned);
2716 XmlReaderWrap
reader(p_buf
);
2717 for (int success
=reader
.Read(); success
==1; success
=reader
.Read()) {
2718 if (reader
.NodeType() == XML_READER_TYPE_ELEMENT
) break;
2720 XER_decode(*(p_td
.xer
), reader
, XER_coding
| XER_TOPLEVEL
, 0);
2721 size_t bytes
= reader
.ByteConsumed();
2722 p_buf
.set_pos(bytes
);
2724 case TTCN_EncDec::CT_JSON
: {
2725 TTCN_EncDec_ErrorContext
ec("While JSON-decoding type '%s': ", p_td
.name
);
2726 if(!p_td
.json
) TTCN_EncDec_ErrorContext::error_internal
2727 ("No JSON descriptor available for type '%s'.", p_td
.name
);
2728 JSON_Tokenizer
tok((const char*)p_buf
.get_data(), p_buf
.get_len());
2729 if(JSON_decode(p_td
, tok
, false)<0)
2730 ec
.error(TTCN_EncDec::ET_INCOMPL_MSG
,
2731 "Can not decode type '%s', because invalid or incomplete"
2732 " message was received", p_td
.name
);
2733 p_buf
.set_pos(tok
.get_buf_pos());
2736 TTCN_error("Unknown coding method requested to decode type '%s'", p_td
.name
);
2741 ASN_BER_TLV_t
* Record_Type::BER_encode_TLV(const TTCN_Typedescriptor_t
& p_td
, unsigned p_coding
) const
2744 return BER_encode_TLV_negtest(err_descr
, p_td
, p_coding
);
2747 TTCN_EncDec_ErrorContext::error
2748 (TTCN_EncDec::ET_UNBOUND
, "Encoding an unbound value.");
2750 BER_chk_descr(p_td
);
2751 ASN_BER_TLV_t
*new_tlv
=ASN_BER_TLV_t::construct(NULL
);
2752 TTCN_EncDec_ErrorContext
ec_0("Component '");
2753 TTCN_EncDec_ErrorContext ec_1
;
2754 int next_default_idx
= 0;
2755 const default_struct
* default_indexes
= get_default_indexes();
2756 int field_cnt
= get_count();
2757 for(int i
=0; i
<field_cnt
; i
++) {
2758 boolean is_default_field
= default_indexes
&& (default_indexes
[next_default_idx
].index
==i
);
2759 if (!default_as_optional() && is_default_field
) {
2760 if (!get_at(i
)->is_equal(default_indexes
[next_default_idx
].value
)) {
2761 ec_1
.set_msg("%s': ", fld_name(i
));
2762 new_tlv
->add_TLV(get_at(i
)->BER_encode_TLV(*fld_descr(i
), p_coding
));
2764 } else { /* is not DEFAULT */
2765 ec_1
.set_msg("%s': ", fld_name(i
));
2766 new_tlv
->add_TLV(get_at(i
)->BER_encode_TLV(*fld_descr(i
), p_coding
));
2768 if (is_default_field
) next_default_idx
++;
2771 if (p_coding
==BER_ENCODE_DER
) new_tlv
->sort_tlvs_tag();
2772 new_tlv
=ASN_BER_V2TLV(new_tlv
, p_td
, p_coding
);
2776 ASN_BER_TLV_t
* Record_Type::BER_encode_TLV_negtest(const Erroneous_descriptor_t
* p_err_descr
, const TTCN_Typedescriptor_t
& p_td
, unsigned p_coding
) const
2779 TTCN_EncDec_ErrorContext::error
2780 (TTCN_EncDec::ET_UNBOUND
, "Encoding an unbound value.");
2782 BER_chk_descr(p_td
);
2783 ASN_BER_TLV_t
*new_tlv
=ASN_BER_TLV_t::construct(NULL
);
2784 TTCN_EncDec_ErrorContext
ec_0("Component '");
2785 TTCN_EncDec_ErrorContext ec_1
;
2786 int next_default_idx
= 0;
2787 const default_struct
* default_indexes
= get_default_indexes();
2788 int field_cnt
= get_count();
2793 for (int i
=0; i
<field_cnt
; i
++) {
2794 boolean is_default_field
= default_indexes
&& (default_indexes
[next_default_idx
].index
==i
);
2795 // the first condition is not needed, kept for ease of understanding
2796 if ( (p_err_descr
->omit_before
!=-1) && (i
<p_err_descr
->omit_before
) ) {
2797 if (is_default_field
) next_default_idx
++;
2800 const Erroneous_values_t
* err_vals
= p_err_descr
->next_field_err_values(i
, values_idx
);
2801 const Erroneous_descriptor_t
* emb_descr
= p_err_descr
->next_field_emb_descr(i
, edescr_idx
);
2803 if (err_vals
&& err_vals
->before
) {
2804 if (err_vals
->before
->errval
==NULL
) TTCN_error(
2805 "internal error: erroneous before value missing");
2806 ec_1
.set_msg("%s'(erroneous before): ", fld_name(i
));
2807 if (err_vals
->before
->raw
) {
2808 new_tlv
->add_TLV(err_vals
->before
->errval
->BER_encode_negtest_raw());
2810 if (err_vals
->before
->type_descr
==NULL
) TTCN_error(
2811 "internal error: erroneous before typedescriptor missing");
2812 new_tlv
->add_TLV(err_vals
->before
->errval
->BER_encode_TLV(
2813 *err_vals
->before
->type_descr
, p_coding
));
2817 if (err_vals
&& err_vals
->value
) {
2818 if (err_vals
->value
->errval
) { // replace
2819 ec_1
.set_msg("%s'(erroneous value): ", fld_name(i
));
2820 if (err_vals
->value
->raw
) {
2821 new_tlv
->add_TLV(err_vals
->value
->errval
->BER_encode_negtest_raw());
2823 if (err_vals
->value
->type_descr
==NULL
) TTCN_error(
2824 "internal error: erroneous value typedescriptor missing");
2825 new_tlv
->add_TLV(err_vals
->value
->errval
->BER_encode_TLV(
2826 *err_vals
->value
->type_descr
, p_coding
));
2830 if (!default_as_optional() && is_default_field
) {
2831 if (!get_at(i
)->is_equal(default_indexes
[next_default_idx
].value
)) {
2832 ec_1
.set_msg("'%s': ", fld_name(i
));
2834 new_tlv
->add_TLV(get_at(i
)->BER_encode_TLV_negtest(emb_descr
,
2835 *fld_descr(i
), p_coding
));
2837 new_tlv
->add_TLV(get_at(i
)->BER_encode_TLV(*fld_descr(i
), p_coding
));
2840 } else { /* is not DEFAULT */
2841 ec_1
.set_msg("'%s': ", fld_name(i
));
2843 new_tlv
->add_TLV(get_at(i
)->BER_encode_TLV_negtest(emb_descr
,
2844 *fld_descr(i
), p_coding
));
2846 new_tlv
->add_TLV(get_at(i
)->BER_encode_TLV(*fld_descr(i
), p_coding
));
2851 if (err_vals
&& err_vals
->after
) {
2852 if (err_vals
->after
->errval
==NULL
) TTCN_error(
2853 "internal error: erroneous after value missing");
2854 ec_1
.set_msg("%s'(erroneous after): ", fld_name(i
));
2855 if (err_vals
->after
->raw
) {
2856 new_tlv
->add_TLV(err_vals
->after
->errval
->BER_encode_negtest_raw());
2858 if (err_vals
->after
->type_descr
==NULL
) TTCN_error(
2859 "internal error: erroneous after typedescriptor missing");
2860 new_tlv
->add_TLV(err_vals
->after
->errval
->BER_encode_TLV(
2861 *err_vals
->after
->type_descr
, p_coding
));
2865 if (is_default_field
) next_default_idx
++;
2866 if ( (p_err_descr
->omit_after
!=-1) && (i
>=p_err_descr
->omit_after
) ) break;
2870 if (p_coding
==BER_ENCODE_DER
) new_tlv
->sort_tlvs_tag();
2871 new_tlv
=ASN_BER_V2TLV(new_tlv
, p_td
, p_coding
);
2875 boolean
Record_Type::BER_decode_TLV(const TTCN_Typedescriptor_t
& p_td
,
2876 const ASN_BER_TLV_t
& p_tlv
, unsigned L_form
)
2879 BER_chk_descr(p_td
);
2880 ASN_BER_TLV_t stripped_tlv
;
2881 BER_decode_strip_tags(*p_td
.ber
, p_tlv
, L_form
, stripped_tlv
);
2882 TTCN_EncDec_ErrorContext
ec_0("While decoding '%s' type: ", get_descriptor()->name
);
2883 stripped_tlv
.chk_constructed_flag(TRUE
);
2885 ASN_BER_TLV_t tmp_tlv
;
2887 { /* SEQUENCE decoding */
2888 boolean tlv_present
=FALSE
;
2890 TTCN_EncDec_ErrorContext
ec_1("Component '");
2891 TTCN_EncDec_ErrorContext ec_2
;
2892 int next_default_idx
= 0;
2893 int next_optional_idx
= 0;
2894 const default_struct
* default_indexes
= get_default_indexes();
2895 const int* optional_indexes
= get_optional_indexes();
2896 int field_cnt
= get_count();
2897 for(int i
=0; i
<field_cnt
; i
++) {
2898 boolean is_default_field
= default_indexes
&& (default_indexes
[next_default_idx
].index
==i
);
2899 boolean is_optional_field
= optional_indexes
&& (optional_indexes
[next_optional_idx
]==i
);
2900 ec_2
.set_msg("%s': ", fld_descr(i
)->name
);
2901 if (!tlv_present
) tlv_present
=BER_decode_constdTLV_next(stripped_tlv
, V_pos
, L_form
, tmp_tlv
);
2902 if (is_default_field
) { /* is DEFAULT */
2903 if (!tlv_present
|| !get_at(i
)->BER_decode_isMyMsg(*fld_descr(i
), tmp_tlv
)) {
2904 get_at(i
)->set_value(default_indexes
[next_default_idx
].value
);
2906 get_at(i
)->BER_decode_TLV(*fld_descr(i
), tmp_tlv
, L_form
);
2910 else if (is_optional_field
) { /* is OPTIONAL */
2911 if (!tlv_present
) get_at(i
)->set_to_omit();
2913 get_at(i
)->BER_decode_TLV(*fld_descr(i
), tmp_tlv
, L_form
);
2914 if (get_at(i
)->ispresent()) tlv_present
=FALSE
;
2917 else { /* is not DEFAULT OPTIONAL */
2919 ec_2
.error(TTCN_EncDec::ET_INCOMPL_MSG
,"Invalid or incomplete message was received.");
2922 get_at(i
)->BER_decode_TLV(*fld_descr(i
), tmp_tlv
, L_form
);
2925 if (is_default_field
) next_default_idx
++;
2926 if (is_optional_field
) next_optional_idx
++;
2929 BER_decode_constdTLV_end(stripped_tlv
, V_pos
, L_form
, tmp_tlv
, tlv_present
);
2930 } /* SEQUENCE decoding */
2932 { /* SET decoding */
2934 * 0x01: value arrived
2935 * 0x02: is optional / not used :)
2936 * 0x04: has default / not used :)
2938 int field_cnt
= get_count();
2939 unsigned char* fld_indctr
= new unsigned char[field_cnt
];
2940 for (int i
=0; i
<field_cnt
; i
++) fld_indctr
[i
] = 0;
2941 int fld_curr
= -1; /* ellipsis or error... */
2942 while (BER_decode_constdTLV_next(stripped_tlv
, V_pos
, L_form
, tmp_tlv
)) {
2943 for (int i
=0; i
<field_cnt
; i
++) {
2944 if (get_at(i
)->BER_decode_isMyMsg(*fld_descr(i
), tmp_tlv
)) {
2946 TTCN_EncDec_ErrorContext
ec_1("Component '%s': ", fld_name(i
));
2947 get_at(i
)->BER_decode_TLV(*fld_descr(i
), tmp_tlv
, L_form
);
2952 if (fld_indctr
[fld_curr
])
2953 ec_0
.error(TTCN_EncDec::ET_DEC_DUPFLD
, "Duplicated value for component '%s'.", fld_name(fld_curr
));
2954 fld_indctr
[fld_curr
]=1;
2957 int next_default_idx
= 0;
2958 int next_optional_idx
= 0;
2959 const default_struct
* default_indexes
= get_default_indexes();
2960 const int* optional_indexes
= get_optional_indexes();
2961 for (fld_curr
=0; fld_curr
<field_cnt
; fld_curr
++) {
2962 boolean is_default_field
= default_indexes
&& (default_indexes
[next_default_idx
].index
==fld_curr
);
2963 boolean is_optional_field
= optional_indexes
&& (optional_indexes
[next_optional_idx
]==fld_curr
);
2964 if (!fld_indctr
[fld_curr
]) {
2965 if (is_default_field
) get_at(fld_curr
)->set_value(default_indexes
[next_default_idx
].value
);
2966 else if (is_optional_field
) get_at(fld_curr
)->set_to_omit();
2967 else ec_0
.error(TTCN_EncDec::ET_DEC_MISSFLD
, "Missing value for component '%s'.", fld_name(fld_curr
));
2969 if (is_default_field
) next_default_idx
++;
2970 if (is_optional_field
) next_optional_idx
++;
2972 delete[] fld_indctr
;
2973 } /* SET decoding */
2975 if (is_opentype_outermost()) {
2976 TTCN_EncDec_ErrorContext
ec_1("While decoding opentypes: ");
2977 TTCN_Type_list p_typelist
;
2978 BER_decode_opentypes(p_typelist
, L_form
);
2979 } /* if sdef->opentype_outermost */
2983 void Record_Type::BER_decode_opentypes(TTCN_Type_list
& p_typelist
, unsigned L_form
)
2986 p_typelist
.push(this);
2987 TTCN_EncDec_ErrorContext
ec_0("Component '");
2988 TTCN_EncDec_ErrorContext ec_1
;
2989 int field_cnt
= get_count();
2990 for(int i
=0; i
<field_cnt
; i
++) {
2991 ec_1
.set_msg("%s': ", fld_name(i
));
2992 get_at(i
)->BER_decode_opentypes(p_typelist
, L_form
);
2997 int Record_Type::RAW_encode(const TTCN_Typedescriptor_t
& p_td
,
2998 RAW_enc_tree
& myleaf
) const
3000 if (err_descr
) return RAW_encode_negtest(err_descr
, p_td
, myleaf
);
3002 TTCN_EncDec_ErrorContext::error
3003 (TTCN_EncDec::ET_UNBOUND
, "Encoding an unbound value.");
3005 int encoded_length
= 0;
3006 int field_cnt
= get_count();
3007 myleaf
.isleaf
= false;
3008 myleaf
.body
.node
.num_of_nodes
= field_cnt
;
3009 myleaf
.body
.node
.nodes
= init_nodes_of_enc_tree(field_cnt
);
3011 int next_optional_idx
= 0;
3012 const int* optional_indexes
= get_optional_indexes();
3013 for (int i
= 0; i
< field_cnt
; i
++) {
3014 boolean is_optional_field
= optional_indexes
3015 && (optional_indexes
[next_optional_idx
] == i
);
3016 if (!is_optional_field
|| get_at(i
)->ispresent()) {
3017 myleaf
.body
.node
.nodes
[i
] = new RAW_enc_tree(true, &myleaf
,
3018 &(myleaf
.curr_pos
), i
, fld_descr(i
)->raw
);
3021 myleaf
.body
.node
.nodes
[i
] = NULL
;
3023 if (is_optional_field
) next_optional_idx
++;
3025 next_optional_idx
= 0;
3026 for (int i
= 0; i
< field_cnt
; i
++) { /*encoding fields*/
3027 boolean is_optional_field
= optional_indexes
3028 && (optional_indexes
[next_optional_idx
] == i
);
3029 /* encoding of normal fields*/
3030 const Base_Type
*field
= get_at(i
);
3031 if (is_optional_field
) {
3032 next_optional_idx
++;
3033 if (!field
->ispresent())
3034 continue; // do not encode
3036 field
= field
->get_opt_value(); // "reach into" the optional
3038 encoded_length
+= field
->RAW_encode(*fld_descr(i
),
3039 *myleaf
.body
.node
.nodes
[i
]);
3041 return myleaf
.length
= encoded_length
;
3044 // In some cases (e.g. LENGTHTO, POINTERTO, CROSSTAG) it is not generated.
3045 int Record_Type::RAW_encode_negtest(const Erroneous_descriptor_t
*p_err_descr
,
3046 const TTCN_Typedescriptor_t
& /*p_td*/, RAW_enc_tree
& myleaf
) const
3049 TTCN_EncDec_ErrorContext::error
3050 (TTCN_EncDec::ET_UNBOUND
, "Encoding an unbound value.");
3052 int encoded_length
= 0;
3053 int num_fields
= get_count();
3054 myleaf
.isleaf
= false;
3055 myleaf
.body
.node
.num_of_nodes
= 0;
3056 for (int field_idx
= 0; field_idx
< num_fields
; ++field_idx
) {
3057 if ((p_err_descr
->omit_before
!= -1) &&
3058 (field_idx
< p_err_descr
->omit_before
))
3060 else ++myleaf
.body
.node
.num_of_nodes
;
3061 const Erroneous_values_t
*err_vals
= p_err_descr
->get_field_err_values(field_idx
);
3062 if (err_vals
&& err_vals
->before
)
3063 ++myleaf
.body
.node
.num_of_nodes
;
3064 if (err_vals
&& err_vals
->value
&& !err_vals
->value
->errval
)
3065 --myleaf
.body
.node
.num_of_nodes
;
3066 if (err_vals
&& err_vals
->after
)
3067 ++myleaf
.body
.node
.num_of_nodes
;
3068 if ((p_err_descr
->omit_after
!= -1) &&
3069 (field_idx
>= p_err_descr
->omit_after
))
3072 myleaf
.body
.node
.nodes
= init_nodes_of_enc_tree(myleaf
.body
.node
.num_of_nodes
);
3073 TTCN_EncDec_ErrorContext ec
;
3074 int next_optional_idx
= 0;
3075 const int *my_optional_indexes
= get_optional_indexes();
3076 // Counter for fields and additional before/after fields.
3078 for (int field_idx
= 0; field_idx
< num_fields
; ++field_idx
) {
3079 boolean is_optional_field
= my_optional_indexes
&&
3080 (my_optional_indexes
[next_optional_idx
] == field_idx
);
3081 if ((p_err_descr
->omit_before
!= -1) &&
3082 (field_idx
< p_err_descr
->omit_before
)) {
3083 if (is_optional_field
) ++next_optional_idx
;
3086 const Erroneous_values_t
*err_vals
= p_err_descr
->get_field_err_values(field_idx
);
3087 const Erroneous_descriptor_t
*emb_descr
= p_err_descr
->get_field_emb_descr(field_idx
);
3088 if (err_vals
&& err_vals
->before
) {
3089 if (err_vals
->before
->errval
== NULL
)
3090 TTCN_error("internal error: erroneous before value missing");
3091 if (err_vals
->before
->raw
) {
3092 myleaf
.body
.node
.nodes
[node_pos
] =
3093 new RAW_enc_tree(true, &myleaf
, &(myleaf
.curr_pos
), node_pos
,
3094 err_vals
->before
->errval
->get_descriptor()->raw
);
3095 encoded_length
+= err_vals
->before
->errval
->
3096 RAW_encode_negtest_raw(*myleaf
.body
.node
.nodes
[node_pos
++]);
3098 if (err_vals
->before
->type_descr
== NULL
)
3099 TTCN_error("internal error: erroneous before typedescriptor missing");
3100 myleaf
.body
.node
.nodes
[node_pos
] =
3101 new RAW_enc_tree(true, &myleaf
, &(myleaf
.curr_pos
), node_pos
,
3102 err_vals
->before
->type_descr
->raw
);
3103 encoded_length
+= err_vals
->before
->errval
->
3104 RAW_encode(*(err_vals
->before
->type_descr
),
3105 *myleaf
.body
.node
.nodes
[node_pos
++]);
3108 if (err_vals
&& err_vals
->value
) {
3109 if (err_vals
->value
->errval
) {
3110 ec
.set_msg("'%s'(erroneous value): ", fld_name(field_idx
));
3111 if (err_vals
->value
->raw
) {
3112 myleaf
.body
.node
.nodes
[node_pos
] =
3113 new RAW_enc_tree(true, &myleaf
, &(myleaf
.curr_pos
), node_pos
,
3114 err_vals
->value
->errval
->get_descriptor()->raw
);
3115 encoded_length
+= err_vals
->value
->errval
->
3116 RAW_encode_negtest_raw(*myleaf
.body
.node
.nodes
[node_pos
++]);
3118 if (err_vals
->value
->type_descr
== NULL
)
3119 TTCN_error("internal error: erroneous value typedescriptor missing");
3120 myleaf
.body
.node
.nodes
[node_pos
] =
3121 new RAW_enc_tree(true, &myleaf
, &(myleaf
.curr_pos
), node_pos
,
3122 err_vals
->value
->type_descr
->raw
);
3123 encoded_length
+= err_vals
->value
->errval
->
3124 RAW_encode(*(err_vals
->value
->type_descr
),
3125 *myleaf
.body
.node
.nodes
[node_pos
++]);
3129 ec
.set_msg("'%s': ", fld_name(field_idx
));
3130 if (!is_optional_field
|| get_at(field_idx
)->ispresent()) {
3131 const Base_Type
*field
=
3132 is_optional_field
? get_at(field_idx
)->get_opt_value()
3133 : get_at(field_idx
);
3134 myleaf
.body
.node
.nodes
[node_pos
] =
3135 new RAW_enc_tree(true, &myleaf
, &(myleaf
.curr_pos
), node_pos
,
3136 fld_descr(field_idx
)->raw
);
3139 field
->RAW_encode_negtest(emb_descr
, *fld_descr(field_idx
),
3140 *myleaf
.body
.node
.nodes
[node_pos
++]);
3143 field
->RAW_encode(*fld_descr(field_idx
),
3144 *myleaf
.body
.node
.nodes
[node_pos
++]);
3148 myleaf
.body
.node
.nodes
[node_pos
++] = NULL
;
3151 if (err_vals
&& err_vals
->after
) {
3152 if (err_vals
->after
->errval
== NULL
)
3153 TTCN_error("internal error: erroneous before value missing");
3154 if (err_vals
->after
->raw
) {
3155 myleaf
.body
.node
.nodes
[node_pos
] =
3156 new RAW_enc_tree(true, &myleaf
, &(myleaf
.curr_pos
), node_pos
,
3157 err_vals
->after
->errval
->get_descriptor()->raw
);
3158 encoded_length
+= err_vals
->after
->errval
->
3159 RAW_encode_negtest_raw(*myleaf
.body
.node
.nodes
[node_pos
++]);
3161 if (err_vals
->after
->type_descr
== NULL
)
3162 TTCN_error("internal error: erroneous after typedescriptor missing");
3163 myleaf
.body
.node
.nodes
[node_pos
] =
3164 new RAW_enc_tree(true, &myleaf
, &(myleaf
.curr_pos
), node_pos
,
3165 err_vals
->after
->type_descr
->raw
);
3166 encoded_length
+= err_vals
->after
->errval
->
3167 RAW_encode(*(err_vals
->after
->type_descr
),
3168 *myleaf
.body
.node
.nodes
[node_pos
++]);
3171 if (is_optional_field
) ++next_optional_idx
;
3172 if ((p_err_descr
->omit_after
!= -1) &&
3173 (field_idx
>= p_err_descr
->omit_after
))
3176 return myleaf
.length
= encoded_length
;
3179 int Record_Type::RAW_decode(const TTCN_Typedescriptor_t
& p_td
, TTCN_Buffer
& buff
,
3180 int limit
, raw_order_t top_bit_ord
, boolean no_err
, int, boolean
)
3183 int field_cnt
= get_count();
3184 int opt_cnt
= optional_count();
3185 int mand_num
= field_cnt
- opt_cnt
; // expected mandatory fields
3187 raw_order_t local_top_order
;
3188 if (p_td
.raw
->top_bit_order
== TOP_BIT_INHERITED
) local_top_order
= top_bit_ord
;
3189 else if (p_td
.raw
->top_bit_order
== TOP_BIT_RIGHT
) local_top_order
= ORDER_MSB
;
3190 else local_top_order
= ORDER_LSB
;
3192 if (is_set()) { /* set decoder start*/
3193 int prepaddlength
= buff
.increase_pos_padd(p_td
.raw
->prepadding
);
3194 limit
-= prepaddlength
;
3195 int decoded_length
= 0;
3196 int * const field_map
= new int[field_cnt
];
3197 memset(field_map
, 0, field_cnt
* sizeof(int));
3198 int nof_mand_fields
= 0; // mandatory fields actually decoded
3200 const int* optional_indexes
= get_optional_indexes();
3201 for (int i
=0; i
<opt_cnt
; i
++) get_at(optional_indexes
[i
])->set_to_omit();
3204 size_t fl_start_pos
= buff
.get_pos_bit();
3205 int next_optional_idx
= 0;
3206 const int* optional_indexes
= get_optional_indexes();
3207 for (int i
=0; i
<field_cnt
; i
++) { /* decoding fields without TAG */
3208 boolean is_optional_field
= optional_indexes
&& (optional_indexes
[next_optional_idx
]==i
);
3209 if (field_map
[i
] == 0) {
3210 Base_Type
* field_ptr
= get_at(i
);
3211 if (is_optional_field
) {
3212 field_ptr
->set_to_present();
3213 field_ptr
=field_ptr
->get_opt_value();
3215 int decoded_field_length
= field_ptr
->RAW_decode(*fld_descr(i
), buff
,
3216 limit
, local_top_order
, TRUE
);
3217 if ( (is_optional_field
&& (decoded_field_length
>0)) ||
3218 (!is_optional_field
&& (decoded_field_length
>=0)) ) {
3219 decoded_length
+= decoded_field_length
;
3220 limit
-= decoded_field_length
;
3221 if (!is_optional_field
) nof_mand_fields
++;
3223 goto continue_while
;
3225 buff
.set_pos_bit(fl_start_pos
);
3226 if (is_optional_field
) get_at(i
)->set_to_omit();
3229 if (is_optional_field
) next_optional_idx
++;
3231 break; // no field could be decoded successfully, quit
3235 if (mand_num
> 0 && nof_mand_fields
!= mand_num
) {
3236 /* Not all required fields were decoded. If there are no bits left,
3237 * that means that the last field was decoded successfully but used up
3238 * the buffer. Signal "incomplete". If there were bits left, that means
3239 * no field could be decoded from them; signal an error. */
3240 return limit
? -1 : -TTCN_EncDec::ET_INCOMPL_MSG
;
3242 return decoded_length
+ prepaddlength
+ buff
.increase_pos_padd(p_td
.raw
->padding
);
3243 } else { /* record decoder start */
3244 int prepaddlength
= buff
.increase_pos_padd(p_td
.raw
->prepadding
);
3245 limit
-= prepaddlength
;
3246 size_t last_decoded_pos
= buff
.get_pos_bit();
3247 size_t fl_start_pos
;
3248 int decoded_length
= 0;
3249 int decoded_field_length
= 0;
3250 if (raw_has_ext_bit()) {
3251 const unsigned char* data
=buff
.get_read_data();
3253 unsigned mask
= 1 << (local_top_order
==ORDER_LSB
? 0 : 7);
3254 if (p_td
.raw
->extension_bit
==EXT_BIT_YES
) {
3255 while((data
[count
-1] & mask
) == 0 && count
* 8 < (int)limit
) count
++;
3258 while((data
[count
-1] & mask
) != 0 && count
* 8 < (int)limit
) count
++;
3260 if(limit
) limit
=count
*8;
3263 int next_optional_idx
= 0;
3264 const int* optional_indexes
= get_optional_indexes();
3265 for (int i
=0; i
<field_cnt
; i
++) { /* decoding fields */
3266 boolean is_optional_field
= optional_indexes
&& (optional_indexes
[next_optional_idx
]==i
);
3267 /* check if enough bits to decode the field*/
3268 if (!is_optional_field
|| (limit
>0)) {
3269 /* decoding of normal field */
3270 fl_start_pos
= buff
.get_pos_bit();
3271 Base_Type
* field_ptr
= get_at(i
);
3272 if (is_optional_field
) {
3273 field_ptr
->set_to_present();
3274 field_ptr
=field_ptr
->get_opt_value();
3276 decoded_field_length
= field_ptr
->RAW_decode(*fld_descr(i
), buff
, limit
,
3277 local_top_order
, is_optional_field
? TRUE
: no_err
);
3278 boolean field_present
= TRUE
;
3279 if (is_optional_field
) {
3280 if (decoded_field_length
< 1) { // swallow any error and become omit
3281 field_present
= FALSE
;
3282 get_at(i
)->set_to_omit();
3283 buff
.set_pos_bit(fl_start_pos
);
3286 if (decoded_field_length
< 0) return decoded_field_length
;
3288 if (field_present
) {
3289 decoded_length
+=decoded_field_length
;
3290 limit
-=decoded_field_length
;
3291 last_decoded_pos
=last_decoded_pos
<buff
.get_pos_bit()?buff
.get_pos_bit():last_decoded_pos
;
3294 get_at(i
)->set_to_omit();
3296 if (is_optional_field
) next_optional_idx
++;
3297 } /* decoding fields*/
3299 buff
.set_pos_bit(last_decoded_pos
);
3300 return decoded_length
+prepaddlength
+buff
.increase_pos_padd(p_td
.raw
->padding
);
3301 } /* record decoder end*/
3304 int Record_Type::TEXT_encode(const TTCN_Typedescriptor_t
& p_td
, TTCN_Buffer
& buff
) const
3307 return TEXT_encode_negtest(err_descr
, p_td
, buff
);
3310 TTCN_EncDec_ErrorContext::error
3311 (TTCN_EncDec::ET_UNBOUND
, "Encoding an unbound value.");
3313 bool need_separator
=false;
3314 int encoded_length
=0;
3315 if (p_td
.text
->begin_encode
) {
3316 buff
.put_cs(*p_td
.text
->begin_encode
);
3317 encoded_length
+=p_td
.text
->begin_encode
->lengthof();
3319 int next_optional_idx
= 0;
3320 const int* optional_indexes
= get_optional_indexes();
3321 int field_cnt
= get_count();
3322 for(int i
=0;i
<field_cnt
;i
++) {
3323 boolean is_optional_field
= optional_indexes
&& (optional_indexes
[next_optional_idx
]==i
);
3324 if (!is_optional_field
|| get_at(i
)->ispresent()) {
3325 if (need_separator
&& p_td
.text
->separator_encode
) {
3326 buff
.put_cs(*p_td
.text
->separator_encode
);
3327 encoded_length
+=p_td
.text
->separator_encode
->lengthof();
3329 encoded_length
+= get_at(i
)->TEXT_encode(*fld_descr(i
),buff
);
3330 need_separator
=true;
3332 if (is_optional_field
) next_optional_idx
++;
3334 if (p_td
.text
->end_encode
) {
3335 buff
.put_cs(*p_td
.text
->end_encode
);
3336 encoded_length
+=p_td
.text
->end_encode
->lengthof();
3338 return encoded_length
;
3342 * TEXT encode negative testing
3344 int Record_Type::TEXT_encode_negtest(const Erroneous_descriptor_t
* p_err_descr
, const TTCN_Typedescriptor_t
& p_td
, TTCN_Buffer
& buff
) const
3347 TTCN_EncDec_ErrorContext::error
3348 (TTCN_EncDec::ET_UNBOUND
, "Encoding an unbound value.");
3350 bool need_separator
=false;
3351 int encoded_length
=0;
3352 if (p_td
.text
->begin_encode
) {
3353 buff
.put_cs(*p_td
.text
->begin_encode
);
3354 encoded_length
+=p_td
.text
->begin_encode
->lengthof();
3356 int next_optional_idx
= 0;
3357 const int* optional_indexes
= get_optional_indexes();
3358 int field_cnt
= get_count();
3363 for(int i
=0;i
<field_cnt
;i
++) {
3364 boolean is_optional_field
= optional_indexes
&& (optional_indexes
[next_optional_idx
]==i
);
3366 if ( (p_err_descr
->omit_before
!=-1) && (i
<p_err_descr
->omit_before
) ) {
3367 if (is_optional_field
) next_optional_idx
++;
3371 const Erroneous_values_t
* err_vals
= p_err_descr
->next_field_err_values(i
, values_idx
);
3372 const Erroneous_descriptor_t
* emb_descr
= p_err_descr
->next_field_emb_descr(i
, edescr_idx
);
3374 if (err_vals
&& err_vals
->before
) {
3375 if (err_vals
->before
->errval
==NULL
) TTCN_error(
3376 "internal error: erroneous before value missing");
3378 if (need_separator
&& p_td
.text
->separator_encode
) {
3379 buff
.put_cs(*p_td
.text
->separator_encode
);
3380 encoded_length
+=p_td
.text
->separator_encode
->lengthof();
3382 if (err_vals
->before
->raw
) {
3383 encoded_length
+= err_vals
->before
->errval
->encode_raw(buff
);
3385 if (err_vals
->before
->type_descr
==NULL
) TTCN_error(
3386 "internal error: erroneous before typedescriptor missing");
3387 encoded_length
+= err_vals
->before
->errval
->TEXT_encode(
3388 *(err_vals
->before
->type_descr
),buff
);
3390 need_separator
=true;
3393 if (err_vals
&& err_vals
->value
) {
3394 if (err_vals
->value
->errval
) {
3395 if (need_separator
&& p_td
.text
->separator_encode
) {
3396 buff
.put_cs(*p_td
.text
->separator_encode
);
3397 encoded_length
+=p_td
.text
->separator_encode
->lengthof();
3399 if (err_vals
->value
->raw
) {
3400 encoded_length
+= err_vals
->value
->errval
->encode_raw(buff
);
3402 if (err_vals
->value
->type_descr
==NULL
) TTCN_error(
3403 "internal error: erroneous value typedescriptor missing");
3404 encoded_length
+= err_vals
->value
->errval
->TEXT_encode(
3405 *(err_vals
->value
->type_descr
),buff
);
3407 need_separator
=true;
3410 if (!is_optional_field
|| get_at(i
)->ispresent()) {
3411 if (need_separator
&& p_td
.text
->separator_encode
) {
3412 buff
.put_cs(*p_td
.text
->separator_encode
);
3413 encoded_length
+=p_td
.text
->separator_encode
->lengthof();
3416 encoded_length
+= get_at(i
)->TEXT_encode_negtest(emb_descr
, *fld_descr(i
),buff
);
3418 encoded_length
+= get_at(i
)->TEXT_encode(*fld_descr(i
),buff
);
3420 need_separator
=true;
3424 if (err_vals
&& err_vals
->after
) {
3425 if (err_vals
->after
->errval
==NULL
) TTCN_error(
3426 "internal error: erroneous after value missing");
3427 if (need_separator
&& p_td
.text
->separator_encode
) {
3428 buff
.put_cs(*p_td
.text
->separator_encode
);
3429 encoded_length
+=p_td
.text
->separator_encode
->lengthof();
3431 if (err_vals
->after
->raw
) {
3432 encoded_length
+= err_vals
->after
->errval
->encode_raw(buff
);
3434 if (err_vals
->after
->type_descr
==NULL
) TTCN_error(
3435 "internal error: erroneous after typedescriptor missing");
3436 encoded_length
+= err_vals
->after
->errval
->TEXT_encode(
3437 *(err_vals
->after
->type_descr
),buff
);
3439 need_separator
=true;
3442 if (is_optional_field
) next_optional_idx
++;
3444 if ( (p_err_descr
->omit_after
!=-1) && (i
>=p_err_descr
->omit_after
) ) break;
3446 if (p_td
.text
->end_encode
) {
3447 buff
.put_cs(*p_td
.text
->end_encode
);
3448 encoded_length
+=p_td
.text
->end_encode
->lengthof();
3450 return encoded_length
;
3453 int Record_Type::TEXT_decode(const TTCN_Typedescriptor_t
& p_td
, TTCN_Buffer
& buff
,
3454 Limit_Token_List
& limit
, boolean no_err
, boolean
/*first_call*/)
3458 int decoded_length
=0;
3459 int decoded_field_length
=0;
3460 size_t pos
=buff
.get_pos();
3461 boolean sep_found
=FALSE
;
3464 int loop_detector
=1;
3465 int last_field_num
=-1;
3466 if (p_td
.text
->begin_decode
) {
3468 if ((tl
=p_td
.text
->begin_decode
->match_begin(buff
))<0) {
3469 if(no_err
) return -1;
3470 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR
,
3471 "The specified token '%s' not found for '%s': ",
3472 (const char*)*(p_td
.text
->begin_decode
), p_td
.name
);
3476 buff
.increase_pos(tl
);
3478 if (p_td
.text
->end_decode
) {
3479 limit
.add_token(p_td
.text
->end_decode
);
3482 if(p_td
.text
->separator_decode
){
3483 limit
.add_token(p_td
.text
->separator_decode
);
3487 int field_cnt
= get_count();
3488 int * const field_map
= new int[field_cnt
];
3489 memset(field_map
, 0, field_cnt
* sizeof(int));
3491 int mand_field_num
= 0;
3492 int opt_field_num
= 0;
3494 int has_repeatable
=0;
3495 boolean repeatable
= TRUE
;
3497 int next_optional_idx
= 0;
3498 const int* optional_indexes
= get_optional_indexes();
3499 for (int i
=0;i
<field_cnt
;i
++) {
3500 boolean is_optional_field
= optional_indexes
&& (optional_indexes
[next_optional_idx
]==i
);
3501 if (is_optional_field
) {
3502 get_at(i
)->set_to_omit();
3507 if (get_at(i
)->is_seof()) {
3509 repeatable
= repeatable
&& fld_descr(i
)->text
->val
.parameters
->decoding_params
.repeatable
;
3511 if (is_optional_field
) next_optional_idx
++;
3513 boolean has_optinals
= opt_field_num
> 0;
3514 if ((seof
>0) && repeatable
) has_repeatable
=1;
3516 while (mand_field_num
+opt_field_num
+has_repeatable
) {
3520 next_optional_idx
= 0;
3521 for (int i
=0;i
<field_cnt
;i
++) {
3522 boolean is_optional_field
= optional_indexes
&& (optional_indexes
[next_optional_idx
]==i
);
3523 if (get_at(i
)->is_seof()) {
3524 if ( (fld_descr(i
)->text
->val
.parameters
->decoding_params
.repeatable
&& field_map
[i
]<3)
3525 || !field_map
[i
] ) {
3527 decoded_field_length
= get_at(i
)->TEXT_decode(*fld_descr(i
),buff
, limit
, true,!field_map
[i
]);
3528 if (decoded_field_length
<0) {
3530 if (is_optional_field
&& !field_map
[i
]) get_at(i
)->set_to_omit();
3533 if (!field_map
[i
]) {
3534 if (is_optional_field
) opt_field_num
--;
3535 else mand_field_num
--;
3537 } else field_map
[i
]=2;
3542 } else { // !...->is_seof
3543 if (!field_map
[i
]) {
3545 decoded_field_length
= get_at(i
)->TEXT_decode(*fld_descr(i
),buff
,limit
,true);
3546 if (decoded_field_length
<0) {
3548 if (is_optional_field
) get_at(i
)->set_to_omit();
3552 if (is_optional_field
) opt_field_num
--;
3553 else mand_field_num
--;
3559 if (is_optional_field
) next_optional_idx
++;
3563 if (loop_detector
) break;
3564 if (p_td
.text
->separator_decode
) {
3566 if ((tl
=p_td
.text
->separator_decode
->match_begin(buff
))<0) {
3567 if (p_td
.text
->end_decode
) {
3569 if ((tl2
=p_td
.text
->end_decode
->match_begin(buff
))!=-1) {
3573 } else if (limit
.has_token(ml
)) {
3575 if ((tl2
=limit
.match(buff
,ml
))==0) {
3581 decoded_length
-=decoded_field_length
;
3582 field_map
[last_field_num
]+=2;
3585 if (last_field_num
>=0 && last_field_num
<field_cnt
) {
3586 if (get_at(last_field_num
)->is_seof()) {
3587 if (get_at(last_field_num
)->is_optional()) {
3588 if (field_map
[last_field_num
]==3) {
3589 get_at(last_field_num
)->set_to_omit();
3593 if (field_map
[last_field_num
]==3) {
3597 } else if (get_at(last_field_num
)->is_optional()) {
3598 get_at(last_field_num
)->set_to_omit();
3606 } // if (has_optinals)
3610 buff
.increase_pos(tl
);
3611 for (int a
=0;a
<field_cnt
;a
++) if(field_map
[a
]>2) field_map
[a
]-=3;
3614 } else if (p_td
.text
->end_decode
) {
3616 if ((tl
=p_td
.text
->end_decode
->match_begin(buff
))!=-1) {
3618 buff
.increase_pos(tl
);
3619 limit
.remove_tokens(ml
);
3620 if (mand_field_num
) decoded_length
= -1;
3623 } else if(limit
.has_token(ml
)){
3625 if ((tl
=limit
.match(buff
,ml
))==0) {
3631 limit
.remove_tokens(ml
);
3633 if (mand_field_num
) {
3634 if (no_err
) decoded_length
= -1;
3635 else TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR
,
3636 "Error during decoding '%s': ", p_td
.name
);
3639 decoded_length
-=sep_length
;
3640 buff
.set_pos(buff
.get_pos()-sep_length
);
3643 if (p_td
.text
->end_decode
) {
3645 if ((tl
=p_td
.text
->end_decode
->match_begin(buff
))<0) {
3646 if (no_err
) decoded_length
= -1;
3647 else TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR
,
3648 "The specified token '%s' not found for '%s': ",
3649 (const char*)*(p_td
.text
->end_decode
),p_td
.name
);
3653 buff
.increase_pos(tl
);
3655 if (mand_field_num
) decoded_length
= -1;
3658 return decoded_length
;
3659 } else { // record decoder
3660 int decoded_length
=0;
3661 int decoded_field_length
=0;
3662 size_t pos
=buff
.get_pos();
3663 boolean sep_found
=FALSE
;
3666 if (p_td
.text
->begin_decode
) {
3668 if ((tl
=p_td
.text
->begin_decode
->match_begin(buff
))<0) {
3669 if(no_err
)return -1;
3670 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR
,
3671 "The specified token '%s' not found for '%s': ",
3672 (const char*)*(p_td
.text
->begin_decode
), p_td
.name
);
3676 buff
.increase_pos(tl
);
3678 if (p_td
.text
->end_decode
) {
3679 limit
.add_token(p_td
.text
->end_decode
);
3682 if (p_td
.text
->separator_decode
) {
3683 limit
.add_token(p_td
.text
->separator_decode
);
3687 int mand_field_num
= 0;
3688 int opt_field_num
= 0;
3689 int last_man_index
= 0;
3691 int field_cnt
= get_count();
3692 int next_optional_idx
= 0;
3693 const int* optional_indexes
= get_optional_indexes();
3694 for (int i
=0;i
<field_cnt
;i
++) {
3695 boolean is_optional_field
= optional_indexes
&& (optional_indexes
[next_optional_idx
]==i
);
3696 if (is_optional_field
) {
3697 get_at(i
)->set_to_omit();
3703 if (is_optional_field
) next_optional_idx
++;
3706 next_optional_idx
= 0;
3707 for(int i
=0;i
<field_cnt
;i
++) {
3708 boolean is_optional_field
= optional_indexes
&& (optional_indexes
[next_optional_idx
]==i
);
3709 if (is_optional_field
) {
3712 decoded_field_length
= get_at(i
)->TEXT_decode(*fld_descr(i
),buff
,limit
,TRUE
);
3713 if (decoded_field_length
<0) {
3714 if (is_optional_field
) {
3715 get_at(i
)->set_to_omit();
3718 limit
.remove_tokens(ml
);
3719 if (no_err
) return -1;
3720 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR
,
3721 "Error during decoding field '%s' for '%s': ",
3722 fld_descr(i
)->name
, p_td
.name
);
3723 return decoded_length
;
3726 decoded_length
+=decoded_field_length
;
3727 if (last_man_index
>(i
+1)) {
3728 if (p_td
.text
->separator_decode
) {
3730 if ((tl
=p_td
.text
->separator_decode
->match_begin(buff
))<0) {
3731 if(is_optional_field
) {
3732 get_at(i
)->set_to_omit();
3734 decoded_length
-=decoded_field_length
;
3736 limit
.remove_tokens(ml
);
3737 if(no_err
)return -1;
3738 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR
,
3739 "The specified token '%s' not found for '%s': ",
3740 (const char*)*(p_td
.text
->separator_decode
),p_td
.name
);
3741 return decoded_length
;
3745 buff
.increase_pos(tl
);
3749 } else sep_found
=FALSE
;
3751 } else if (i
==(field_cnt
-1)) {
3754 if (p_td
.text
->separator_decode
) {
3756 if ((tl
=p_td
.text
->separator_decode
->match_begin(buff
))<0) {
3757 if (is_optional_field
) {
3758 if (p_td
.text
->end_decode
) {
3759 if ((tl
=p_td
.text
->end_decode
->match_begin(buff
))!=-1) {
3761 buff
.increase_pos(tl
);
3762 limit
.remove_tokens(ml
);
3763 return decoded_length
;
3765 } else if (limit
.has_token(ml
)) {
3766 if ((tl
=limit
.match(buff
,ml
))==0) {
3771 get_at(i
)->set_to_omit();
3773 decoded_length
-=decoded_field_length
;
3780 buff
.increase_pos(tl
);
3787 if (p_td
.text
->end_decode
) {
3788 if ((tl
=p_td
.text
->end_decode
->match_begin(buff
))!=-1) {
3790 buff
.increase_pos(tl
);
3791 limit
.remove_tokens(ml
);
3792 return decoded_length
;
3794 } else if (limit
.has_token(ml
)) {
3795 if ((tl
=limit
.match(buff
,ml
))==0) {
3803 if (is_optional_field
) next_optional_idx
++;
3805 limit
.remove_tokens(ml
);
3807 buff
.set_pos(buff
.get_pos()-sep_length
);
3808 decoded_length
-=sep_length
;
3810 if (p_td
.text
->end_decode
) {
3812 if ((tl
=p_td
.text
->end_decode
->match_begin(buff
))<0) {
3813 if(no_err
)return -1;
3814 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR
,
3815 "The specified token '%s' not found for '%s': ",
3816 (const char*)*(p_td
.text
->end_decode
),p_td
.name
);
3817 return decoded_length
;
3820 buff
.increase_pos(tl
);
3822 return decoded_length
;
3826 const XERdescriptor_t
* Record_Type::xer_descr(int /*field_index*/) const
3828 TTCN_error("Internal error: Record_Type::xer_descr() called.");
3832 char ** Record_Type::collect_ns(const XERdescriptor_t
& p_td
, size_t& num
, bool& def_ns
) const
3834 const int field_cnt
= get_count();
3835 // The USE-ORDER member is first, unless preempted by EMBED-VALUES
3836 const int uo_index
= ((p_td
.xer_bits
& EMBED_VALUES
) !=0);
3837 // Index of the first "normal" member (after E-V and U-O)
3838 const int start_at
= uo_index
+ ((p_td
.xer_bits
& USE_ORDER
) != 0);
3840 size_t num_collected
= 0;
3841 // First, our own namespace. Sets num_collected to 0 or 1.
3842 // If it throws, nothing was allocated.
3843 char **collected_ns
= Base_Type::collect_ns(p_td
, num_collected
, def_ns
);
3846 // If the nil attribute will be written, add the control namespace
3847 boolean nil_attribute
= (p_td
.xer_bits
& USE_NIL
)
3848 && !get_at(field_cnt
-1)->ispresent();
3850 if (nil_attribute
) {
3851 collected_ns
= (char**)Realloc(collected_ns
, sizeof(char*) * ++num_collected
);
3852 const namespace_t
*c_ns
= p_td
.my_module
->get_controlns();
3854 collected_ns
[num_collected
-1] = mprintf(" xmlns:%s='%s'", c_ns
->px
, c_ns
->ns
);
3857 // Collect namespace declarations from all components (recursively).
3858 // This is extremely nasty, but we can't prosecute you for that.
3859 // (Monty Python - Crunchy Frog sketch). This whole thing is O(n^3). Yuck.
3860 for (int a
= start_at
; a
< field_cnt
; ++a
) {
3862 bool def_ns_1
= false;
3863 char **new_namespaces
= get_at(a
)->collect_ns(*xer_descr(a
), num_new
, def_ns_1
);
3864 merge_ns(collected_ns
, num_collected
, new_namespaces
, num_new
);
3865 def_ns
= def_ns
|| def_ns_1
;
3866 // merge_ns freed new_namespaces
3870 // Probably a TC_Error thrown from the element's collect_ns(),
3871 // e.g. if encoding an unbound value.
3872 while (num_collected
> 0) Free(collected_ns
[--num_collected
]);
3877 num
= num_collected
;
3878 return collected_ns
;
3881 // FIXME some hashing should be implemented
3882 int Record_Type::get_index_byname(const char *name
, const char *uri
) const {
3883 int num_fields
= get_count();
3884 for (int i
= 0; i
< num_fields
; ++i
) {
3885 const XERdescriptor_t
& xer
= *xer_descr(i
);
3886 if (check_name(name
, xer
, TRUE
)
3887 && check_namespace(uri
, xer
)) return i
;
3892 int Record_Type::XER_encode(const XERdescriptor_t
& p_td
, TTCN_Buffer
& p_buf
,
3893 unsigned int flavor
, int indent
, embed_values_enc_struct_t
*) const
3896 return XER_encode_negtest(err_descr
, p_td
, p_buf
, flavor
, indent
, 0);
3899 TTCN_EncDec_ErrorContext::error
3900 (TTCN_EncDec::ET_UNBOUND
, "Encoding an unbound value.");
3903 TTCN_EncDec_ErrorContext
ec_0("Component '");
3904 TTCN_EncDec_ErrorContext ec_1
;
3905 int encoded_length
=(int)p_buf
.get_len(); // how much is already in the buffer
3907 int exer
= is_exer(flavor
);
3908 if (exer
&& (p_td
.xer_bits
& EMBED_VALUES
)) flavor
|= XER_CANONICAL
;
3909 const boolean indenting
= !is_canonical(flavor
);
3910 const int field_cnt
= get_count();
3911 const int num_attributes
= get_xer_num_attr();
3912 // The USE-ORDER member is first, unless preempted by EMBED-VALUES
3913 const int uo_index
= ((p_td
.xer_bits
& EMBED_VALUES
) !=0);
3914 // Index of the first "normal" member (after E-V and U-O)
3915 const int start_at
= uo_index
+ ((p_td
.xer_bits
& USE_ORDER
) != 0);
3916 const int first_nonattr
= start_at
+ num_attributes
;
3917 // start_tag_len is keeping track of how much was written at the end of the
3918 // start tag, i.e. the ">\n". This is used later to "back up" over it.
3919 int start_tag_len
= 1 + indenting
;
3920 // The EMBED-VALUES member, if applicable
3921 const Record_Of_Type
* const embed_values
= (p_td
.xer_bits
& EMBED_VALUES
)
3922 ? static_cast<const Record_Of_Type
*>(get_at(0)) : 0;
3923 // The USE-ORDER member, if applicable
3924 const Record_Of_Type
* const use_order
= (p_td
.xer_bits
& USE_ORDER
)
3925 ? static_cast<const Record_Of_Type
*>(get_at(uo_index
)) : 0;
3927 size_t num_collected
= 0; // we use this to compute delay_close
3928 char **collected_ns
= NULL
;
3929 bool def_ns
= false;
3931 if (indent
== 0) { // top-level type
3932 collected_ns
= collect_ns(p_td
, num_collected
, def_ns
);
3934 else if ((flavor
& DEF_NS_SQUASHED
) && p_td
.my_module
&& p_td
.ns_index
!= -1) {
3935 const namespace_t
* ns
= p_td
.my_module
->get_ns(p_td
.ns_index
);
3936 // The default namespace has been squashed.
3937 // If we are in the default namespace, restore it.
3938 if (*ns
->px
== '\0') {
3939 collected_ns
= Base_Type::collect_ns(p_td
, num_collected
, def_ns
);
3944 // The type's own tag is omitted if we're doing E-XER,
3945 // and it's not the top-level type (XML must have a root element)
3946 // and it's either UNTAGGED or got USE_NIL or USE_TYPE or USE_UNION.
3947 boolean omit_tag
= exer
&& (indent
> 0)
3948 && ( (p_td
.xer_bits
& (UNTAGGED
|XER_ATTRIBUTE
))
3949 || (flavor
& (USE_NIL
|USE_TYPE_ATTR
)));
3951 // If a default namespace is in effect (uri but no prefix) and the type
3952 // is unqualified, the default namespace must be canceled; otherwise
3953 // an XML tag without a ns prefix looks like it belongs to the def.namespace
3954 const boolean empty_ns_hack
= exer
&& !omit_tag
&& (indent
> 0)
3955 && (p_td
.xer_bits
& FORM_UNQUALIFIED
)
3956 && (flavor
& DEF_NS_PRESENT
);
3958 // delay_close=true if there is stuff before the '>' of the start tag
3959 // (prevents writing the '>' which is built into the name).
3960 // This can only happen for EXER: if there are attributes or namespaces,
3961 // or either USE-NIL or USE-QNAME is set.
3962 boolean delay_close
= exer
&& (num_attributes
3963 || empty_ns_hack
// counts as having a namespace
3964 || (num_collected
!= 0)
3965 || (p_td
.xer_bits
& (USE_NIL
|USE_QNAME
))
3966 || (flavor
& USE_NIL
));
3970 if (!omit_tag
) { /* write start tag */
3971 if (indenting
) do_indent(p_buf
, indent
);
3972 /* name looks like this: "tagname>\n"
3973 * lose the \n if : not indenting or (single untagged(*) or attributes (*)) AND exer
3974 * lose the > if attributes are present (*) AND exer
3977 if (exer
) write_ns_prefix(p_td
, p_buf
);
3978 p_buf
.put_s((size_t)p_td
.namelens
[exer
] - delay_close
3979 - (!indenting
|| delay_close
|| (exer
&& (p_td
.xer_bits
& HAS_1UNTAGGED
))),
3980 (cbyte
*)p_td
.names
[exer
]);
3982 else if (flavor
& USE_TYPE_ATTR
) {
3983 // reopen the parent's start tag by overwriting the '>'
3984 size_t buf_len
= p_buf
.get_len();
3985 const unsigned char * const buf_data
= p_buf
.get_data();
3986 if (buf_data
[buf_len
- 1 - shorter
] == '\n') ++shorter
;
3987 if (buf_data
[buf_len
- 1 - shorter
] == '>' ) ++shorter
;
3990 p_buf
.increase_length(-shorter
);
3996 // mask out extra flags we received, do not send them to the fields
3999 if (exer
&& (p_td
.xer_bits
& USE_QNAME
)) { // QName trumps everything
4000 const Base_Type
* const q_uri
= get_at(0);
4001 if (q_uri
->is_present()) {
4002 p_buf
.put_s(11, (cbyte
*)" xmlns:b0='");
4003 q_uri
->XER_encode(*xer_descr(0), p_buf
, flavor
| XER_LIST
, indent
+1, 0);
4007 if (p_td
.xer_bits
& XER_ATTRIBUTE
) begin_attribute(p_td
, p_buf
);
4008 else p_buf
.put_c('>');
4010 if (q_uri
->is_present()) {
4011 p_buf
.put_s(3, (cbyte
*)"b0:");
4014 const Base_Type
* const q_name
= get_at(1);
4015 sub_len
+= q_name
->XER_encode(*xer_descr(1), p_buf
, flavor
| XER_LIST
, indent
+1, 0);
4016 if (p_td
.xer_bits
& XER_ATTRIBUTE
) p_buf
.put_c('\'');
4018 else { // not USE-QNAME
4019 if (!exer
&& (p_td
.xer_bits
& EMBED_VALUES
)) {
4020 // The EMBED-VALUES member as an ordinary record of string
4021 sub_len
+= embed_values
->XER_encode(*xer_descr(0), p_buf
, flavor
, indent
+1, 0);
4024 if (!exer
&& (p_td
.xer_bits
& USE_ORDER
)) {
4025 // The USE-ORDER member as an ordinary record of enumerated
4026 sub_len
+= use_order
->XER_encode(*xer_descr(uo_index
), p_buf
, flavor
, indent
+1, 0);
4029 if (exer
&& (indent
==0 || (flavor
& DEF_NS_SQUASHED
))) // write namespaces for toplevel only
4031 for (size_t cur_coll
= 0; cur_coll
< num_collected
; ++cur_coll
) {
4032 p_buf
.put_s(strlen(collected_ns
[cur_coll
]), (cbyte
*)collected_ns
[cur_coll
]);
4033 Free(collected_ns
[cur_coll
]); // job done
4039 flavor
&= ~DEF_NS_SQUASHED
;
4040 flavor
|= DEF_NS_PRESENT
;
4042 else if (empty_ns_hack
) {
4043 p_buf
.put_s(9, (cbyte
*)" xmlns=''");
4044 flavor
&= ~DEF_NS_PRESENT
;
4045 flavor
|= DEF_NS_SQUASHED
;
4048 /* First all the attributes (not added to sub_len) */
4050 for (i
= start_at
; i
< first_nonattr
; ++i
) {
4051 boolean is_xer_attr_field
= xer_descr(i
)->xer_bits
& XER_ATTRIBUTE
;
4052 ec_1
.set_msg("%s': ", fld_name(i
)); // attr
4053 int tmp_len
= get_at(i
)->XER_encode(*xer_descr(i
), p_buf
, flavor
, indent
+1, 0);
4054 if (is_xer_attr_field
&& !exer
) sub_len
+= tmp_len
; /* do not add if attribute and EXER */
4057 // True if the "nil" attribute needs to be written.
4058 boolean nil_attribute
= exer
&& (p_td
.xer_bits
& USE_NIL
)
4059 && !get_at(field_cnt
-1)->ispresent();
4061 // True if USE_ORDER is in effect and the "nil" attribute was written.
4062 // Then the record-of-enum for USE-ORDER will be empty.
4063 boolean early_to_bed
= FALSE
;
4065 if (nil_attribute
) { // req. exer and USE_NIL
4066 const namespace_t
*control_ns
= p_td
.my_module
->get_controlns();
4068 p_buf
.put_s(strlen(control_ns
->px
),
4069 (cbyte
*)control_ns
->px
);
4071 p_buf
.put_s(10, (cbyte
*)"nil='true'");
4072 if ((p_td
.xer_bits
& USE_ORDER
)) early_to_bed
= TRUE
;
4073 // The whole content was omitted; nothing to do (and if we tried
4074 // to do it, we'd get an error for over-indexing a 0-length record-of).
4077 if (delay_close
&& (!omit_tag
|| shorter
)) {
4078 // Close the start tag left open. If indenting, also write a newline
4079 // unless USE-NIL in effect or there is a single untagged component.
4081 ((p_td
.xer_bits
& (/*USE_NIL|*/HAS_1UNTAGGED
)) ? 0 : indenting
);
4082 p_buf
.put_s(start_tag_len
, (cbyte
*)">\n");
4085 if (exer
&& (p_td
.xer_bits
& EMBED_VALUES
)) {
4086 /* write the first string */
4087 if (embed_values
->size_of() > 0) {
4088 sub_len
+= embed_values
->get_at(0)->XER_encode(UNIVERSAL_CHARSTRING_xer_
,
4089 p_buf
, flavor
| EMBED_VALUES
, indent
+1, 0);
4093 const Record_Type
*ordered
= this; // the record affected by USE-ORDER
4095 // Index of the first non-attribute field of the record pointed to by
4096 // ordered, that is, the first field affected by USE-ORDER.
4097 size_t useorder_base
= first_nonattr
;
4100 int end
= field_cnt
;
4101 if (exer
&& (p_td
.xer_bits
& USE_ORDER
)) {
4102 const int to_send
= use_order
->size_of();
4103 // the length of the loop is determined by the length of use_order
4107 // Count the non-attribute optionals
4108 int n_optionals
= 0;
4109 for (int B
= optional_count() - 1; B
>=+0; B
--) {
4110 int oi
= get_optional_indexes()[B
];
4111 if (oi
< first_nonattr
) break;
4115 int expected_min
= field_cnt
- first_nonattr
- n_optionals
;
4116 int expected_max
= field_cnt
- first_nonattr
;
4119 if ((p_td
.xer_bits
& USE_NIL
) && get_at(field_cnt
-1)->ispresent()) {
4120 // The special case when USE_ORDER refers to the fields of a field,
4122 const Base_Type
*last_optional
= get_at(field_cnt
-1);
4123 const Base_Type
* inner
= last_optional
->get_opt_value();
4124 // it absolutely, positively has to be (derived from) Record_Type
4125 ordered
= static_cast<const Record_Type
*>(inner
);
4126 useorder_base
= ordered
->get_xer_num_attr();
4127 begin
= useorder_base
;
4128 end
= ordered
->get_count();
4130 expected_min
= expected_max
= ordered
->get_count();
4133 if (to_send
> expected_max
4134 ||to_send
< expected_min
) {
4135 ec_1
.set_msg("%s': ", fld_name(uo_index
));
4136 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_CONSTRAINT
,
4137 "Wrong number of USE-ORDER %d, must be %d..%d", to_send
, expected_min
, expected_max
);
4138 begin
= end
= 0; // don't bother sending anything
4140 else { // check no duplicates
4141 int *seen
= new int [to_send
];
4143 for (int ei
= 0; ei
< to_send
; ++ei
) {
4144 const Base_Type
*uoe
= use_order
->get_at(ei
);
4145 const Enum_Type
*enm
= static_cast<const Enum_Type
*>(uoe
);
4146 int val
= enm
->as_int();
4147 for (int x
= 0; x
< num_seen
; ++x
) {
4148 if (val
== seen
[x
]) { // complain
4149 ec_1
.set_msg("%s': ", fld_name(uo_index
));
4150 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_CONSTRAINT
,
4151 "Duplicate value for USE-ORDER");
4152 begin
= end
= 0; // don't bother sending anything
4156 seen
[num_seen
++] = val
;
4160 // If the number is right and there are no duplicates, then carry on
4164 /* Then, all the non-attributes. Structuring the code like this depends on
4165 * all attributes appearing before all non-attributes (excluding
4166 * pseudo-members for USE-ORDER, etc.) */
4168 // early_to_bed can only be true if exer is true (transitive through nil_attribute)
4169 if (!early_to_bed
) {
4170 embed_values_enc_struct_t
* emb_val
= 0;
4171 if (exer
&& (p_td
.xer_bits
& EMBED_VALUES
) && embed_values
->size_of() > 1) {
4172 emb_val
= new embed_values_enc_struct_t
;
4173 emb_val
->embval_array
= embed_values
;
4174 emb_val
->embval_index
= 1;
4175 emb_val
->embval_err
= 0;
4178 for ( i
= begin
; i
< end
; ++i
) {
4179 const Base_Type
*uoe
= 0; // "useOrder enum"
4180 const Enum_Type
*enm
= 0; // the enum value selecting the field
4181 if (exer
&& use_order
) {
4182 uoe
= use_order
->get_at(i
- begin
);
4183 enm
= static_cast<const Enum_Type
*>(uoe
);
4186 // "actual" index, may be perturbed by USE-ORDER
4187 int ai
= !(exer
&& (p_td
.xer_bits
& USE_ORDER
)) ? i
:
4188 enm
->as_int() + useorder_base
;
4189 ec_1
.set_msg("%s': ", ordered
->fld_name(ai
)); // non-attr
4191 const XERdescriptor_t
& descr
= *ordered
->xer_descr(ai
);
4192 sub_len
+= ordered
->get_at(ai
)->XER_encode(descr
, p_buf
,
4193 // Pass USE-NIL to the last field (except when USE-ORDER is also in effect,
4194 // because the tag-stripping effect of USE-NIL has been achieved
4195 // by encoding the sub-fields directly).
4196 flavor
| ((exer
&& !use_order
&& (i
== field_cnt
-1)) ? (p_td
.xer_bits
& USE_NIL
) : 0),
4197 indent
+!omit_tag
, emb_val
);
4199 // Now the next embed-values string (NOT affected by USE-ORDER!)
4200 if (exer
&& (p_td
.xer_bits
& EMBED_VALUES
) && 0 != emb_val
&&
4201 emb_val
->embval_index
< embed_values
->size_of()) {
4202 embed_values
->get_at(emb_val
->embval_index
)->XER_encode(UNIVERSAL_CHARSTRING_xer_
4203 , p_buf
, flavor
| EMBED_VALUES
, indent
+1, 0);
4204 ++emb_val
->embval_index
;
4209 if (emb_val
->embval_index
< embed_values
->size_of()) {
4210 ec_1
.set_msg("%s': ", fld_name(0));
4211 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_CONSTRAINT
,
4212 "Too many EMBED-VALUEs specified: %d (expected %d or less)",
4213 embed_values
->size_of(), emb_val
->embval_index
);
4217 } // if (!early_to_bed)
4221 if (sub_len
) { // something was written, now an end tag
4222 if (indenting
&& !(exer
&& (p_td
.xer_bits
& (HAS_1UNTAGGED
| USE_QNAME
)))) {
4223 // The tags of the last optional member involved with USE_NIL
4224 // have been removed. If it was a simple type, the content was probably
4225 // written on a single line without anything resembling a close tag.
4226 // Do not indent our end tag in this case.
4227 switch ((int)(exer
&& (p_td
.xer_bits
& USE_NIL
))) {
4229 const unsigned char *buf_end
= p_buf
.get_data() + (p_buf
.get_len()-1);
4230 if (buf_end
[-1] != '>' || *buf_end
!= '\n') break;
4231 // If it does not look like an end tag, skip the indenting,
4232 // else fall through.
4235 do_indent(p_buf
, indent
);
4241 if (exer
) write_ns_prefix(p_td
, p_buf
);
4242 p_buf
.put_s((size_t)p_td
.namelens
[exer
]-!indenting
, (cbyte
*)p_td
.names
[exer
]);
4244 else { // need to generate an empty element tag
4245 p_buf
.increase_length(-start_tag_len
); // decrease length
4246 p_buf
.put_s((size_t)2+indenting
, (cbyte
*)"/>\n");
4250 return (int)p_buf
.get_len() - encoded_length
;
4253 // XERSTUFF Record_Type::encode_field
4254 /** Helper for Record_Type::XER_encode_negtest
4256 * Factored out because Record_Type::XER_encode (on which XER_encode_negtest
4257 * is based) calls the XER_encode method of the field in two places:
4258 * one for attributes, the other for elements.
4260 * @param i index of the field
4261 * @param err_vals erroneous descriptor for the field
4262 * @param emb_descr deeper erroneous values
4263 * @param p_buf buffer containing the encoded value
4264 * @param sub_flavor flags
4265 * @param indent indentation level
4266 * @return the number of bytes generated
4268 int Record_Type::encode_field(int i
,
4269 const Erroneous_values_t
* err_vals
, const Erroneous_descriptor_t
* emb_descr
,
4270 TTCN_Buffer
& p_buf
, unsigned int sub_flavor
, int indent
, embed_values_enc_struct_t
* emb_val
) const
4273 TTCN_EncDec_ErrorContext ec
;
4274 if (err_vals
&& err_vals
->before
) {
4275 if (err_vals
->before
->errval
==NULL
) TTCN_error(
4276 "internal error: erroneous before value missing");
4277 ec
.set_msg("Erroneous value before component %s: ", fld_name(i
));
4278 if (err_vals
->before
->raw
) {
4279 enc_len
+= err_vals
->before
->errval
->encode_raw(p_buf
);
4281 if (err_vals
->before
->type_descr
==NULL
) TTCN_error(
4282 "internal error: erroneous before typedescriptor missing");
4283 enc_len
+= err_vals
->before
->errval
->XER_encode(
4284 *err_vals
->before
->type_descr
->xer
, p_buf
, sub_flavor
, indent
, 0);
4288 if (err_vals
&& err_vals
->value
) {
4289 if (err_vals
->value
->errval
) { // replace
4290 ec
.set_msg("Erroneous value for component %s: ", fld_name(i
));
4291 if (err_vals
->value
->raw
) {
4292 enc_len
+= err_vals
->value
->errval
->encode_raw(p_buf
);
4294 if (err_vals
->value
->type_descr
==NULL
) TTCN_error(
4295 "internal error: erroneous value typedescriptor missing");
4296 enc_len
+= err_vals
->value
->errval
->XER_encode(
4297 *err_vals
->value
->type_descr
->xer
, p_buf
, sub_flavor
, indent
, 0);
4301 ec
.set_msg("Component %s: ", fld_name(i
));
4303 enc_len
+= get_at(i
)->XER_encode_negtest(emb_descr
, *xer_descr(i
), p_buf
,
4304 sub_flavor
, indent
, emb_val
);
4306 // the "real" encoder
4307 enc_len
+= get_at(i
)->XER_encode(*xer_descr(i
), p_buf
,
4308 sub_flavor
, indent
, emb_val
);
4312 if (err_vals
&& err_vals
->after
) {
4313 if (err_vals
->after
->errval
==NULL
) TTCN_error(
4314 "internal error: erroneous after value missing");
4315 ec
.set_msg("Erroneous value after component %s: ", fld_name(i
));
4316 if (err_vals
->after
->raw
) {
4317 enc_len
+= err_vals
->after
->errval
->encode_raw(p_buf
);
4319 if (err_vals
->after
->type_descr
==NULL
) TTCN_error(
4320 "internal error: erroneous after typedescriptor missing");
4321 enc_len
+= err_vals
->after
->errval
->XER_encode(
4322 *err_vals
->after
->type_descr
->xer
, p_buf
, sub_flavor
, indent
, 0);
4329 // XERSTUFF Record_Type::XER_encode_negtest
4330 int Record_Type::XER_encode_negtest(const Erroneous_descriptor_t
* p_err_descr
,
4331 const XERdescriptor_t
& p_td
, TTCN_Buffer
& p_buf
, unsigned int flavor
, int indent
,
4332 embed_values_enc_struct_t
*) const
4335 TTCN_EncDec_ErrorContext::error
4336 (TTCN_EncDec::ET_UNBOUND
, "Encoding an unbound value.");
4338 TTCN_EncDec_ErrorContext
ec_0("Component '");
4339 TTCN_EncDec_ErrorContext ec_1
;
4340 int encoded_length
=(int)p_buf
.get_len(); // how much is already in the buffer
4342 int exer
= is_exer(flavor
);
4343 if (exer
&& (p_td
.xer_bits
& EMBED_VALUES
)) flavor
|= XER_CANONICAL
;
4344 const boolean indenting
= !is_canonical(flavor
);
4345 const int field_cnt
= get_count();
4346 const int num_attributes
= get_xer_num_attr();
4347 // The USE-ORDER member is first, unless preempted by EMBED-VALUES
4348 const int uo_index
= ((p_td
.xer_bits
& EMBED_VALUES
) !=0);
4349 // Index of the first "normal" member (after E-V and U-O)
4350 const int start_at
= uo_index
+ ((p_td
.xer_bits
& USE_ORDER
) != 0);
4351 const int first_nonattr
= start_at
+ num_attributes
;
4352 // start_tag_len is keeping track of how much was written at the end of the
4353 // start tag, i.e. the ">\n". This is used later to "back up" over it.
4354 int start_tag_len
= 1 + indenting
;
4355 // The EMBED-VALUES member, if applicable (always first)
4356 const Record_Of_Type
* const embed_values
= (p_td
.xer_bits
& EMBED_VALUES
)
4357 ? static_cast<const Record_Of_Type
*>(get_at(0)) : 0;
4358 // The USE-ORDER member, if applicable (first unless preempted by embed_vals)
4359 const Record_Of_Type
* const use_order
= (p_td
.xer_bits
& USE_ORDER
)
4360 ? static_cast<const Record_Of_Type
*>(get_at(uo_index
)) : 0;
4365 size_t num_collected
= 0; // we use this to compute delay_close
4366 char **collected_ns
= NULL
;
4367 bool def_ns
= false;
4369 if (indent
== 0) { // top-level type
4370 collected_ns
= collect_ns(p_td
, num_collected
, def_ns
);
4372 else if ((flavor
& DEF_NS_SQUASHED
) && p_td
.my_module
&& p_td
.ns_index
!= -1) {
4373 const namespace_t
* ns
= p_td
.my_module
->get_ns(p_td
.ns_index
);
4374 // The default namespace has been squashed.
4375 // If we are in the default namespace, restore it.
4376 if (*ns
->px
== '\0') {
4377 collected_ns
= Base_Type::collect_ns(p_td
, num_collected
, def_ns
);
4382 // The type's own tag is omitted if we're doing E-XER,
4383 // and it's not the top-level type (XML must have a root element)
4384 // and it's either UNTAGGED or got USE_NIL.
4385 boolean omit_tag
= exer
&& indent
4386 && ( (p_td
.xer_bits
& (UNTAGGED
|XER_ATTRIBUTE
))
4387 || (flavor
& (USE_NIL
|USE_TYPE_ATTR
)));
4389 // If a default namespace is in effect (uri but no prefix) and the type
4390 // is unqualified, the default namespace must be canceled; otherwise
4391 // an XML tag without a ns prefix looks like it belongs to the def.namespace
4392 const boolean empty_ns_hack
= exer
&& !omit_tag
&& (indent
> 0)
4393 && (p_td
.xer_bits
& FORM_UNQUALIFIED
)
4394 && (flavor
& DEF_NS_PRESENT
);
4396 // delay_close=true if there is stuff before the '>' of the start tag
4397 // (prevents writing the '>' which is built into the name).
4398 // This can only happen for EXER: if there are attributes or namespaces,
4399 // or either USE-NIL or USE-QNAME is set.
4400 boolean delay_close
= exer
&& (num_attributes
4401 || empty_ns_hack
// counts as having a namespace
4402 || (num_collected
!= 0)
4403 || (p_td
.xer_bits
& (USE_NIL
|USE_QNAME
))
4404 || (flavor
& USE_NIL
));
4407 if (!omit_tag
) { /* write start tag */
4408 if (indenting
) do_indent(p_buf
, indent
);
4409 /* name looks like this: "tagname>\n"
4410 * lose the \n if : not indenting or (single untagged(*) or attributes (*)) AND exer
4411 * lose the > if attributes are present (*) AND exer
4414 if (exer
) write_ns_prefix(p_td
, p_buf
);
4415 p_buf
.put_s((size_t)p_td
.namelens
[exer
] - delay_close
4416 - (!indenting
|| delay_close
|| (exer
&& (p_td
.xer_bits
& HAS_1UNTAGGED
))),
4417 (cbyte
*)p_td
.names
[exer
]);
4419 else if (flavor
& USE_TYPE_ATTR
) {
4420 // reopen the parent's tag
4421 size_t buf_len
= p_buf
.get_len();
4422 const unsigned char * const buf_data
= p_buf
.get_data();
4423 if (buf_data
[buf_len
- 1 - shorter
] == '\n') ++shorter
;
4424 if (buf_data
[buf_len
- 1 - shorter
] == '>' ) ++shorter
;
4427 p_buf
.increase_length(-shorter
);
4432 int sub_len
=0, tmp_len
;
4433 // mask out extra flags we received, do not send them to the fields
4436 if (exer
&& (p_td
.xer_bits
& USE_QNAME
)) {
4437 const Erroneous_values_t
* ev
=
4438 p_err_descr
->next_field_err_values(0, values_idx
);
4439 const Erroneous_descriptor_t
* ed
=
4440 p_err_descr
->next_field_emb_descr (0, edescr_idx
);
4441 // At first, erroneous info for the first component (uri)
4443 TTCN_EncDec_ErrorContext ec
;
4444 const Base_Type
* const q_uri
= get_at(0);
4446 if (ev
&& ev
->before
) {
4447 if (ev
->before
->errval
==NULL
) TTCN_error(
4448 "internal error: erroneous before value missing");
4449 ec
.set_msg("Erroneous value before component #0: ");
4450 if (ev
->before
->raw
) {
4451 sub_len
+= ev
->before
->errval
->encode_raw(p_buf
);
4453 if (ev
->before
->type_descr
==NULL
) TTCN_error(
4454 "internal error: erroneous before typedescriptor missing");
4455 sub_len
+= ev
->before
->errval
->XER_encode(
4456 *ev
->before
->type_descr
->xer
, p_buf
, flavor
, indent
, 0);
4460 if (ev
&& ev
->value
) {
4461 if (ev
->value
->errval
) { // replace
4462 ec
.set_msg("Erroneous value for component #0: ");
4463 if (ev
->value
->raw
) {
4464 sub_len
+= ev
->value
->errval
->encode_raw(p_buf
);
4466 if (ev
->value
->type_descr
==NULL
) TTCN_error(
4467 "internal error: erroneous value typedescriptor missing");
4468 sub_len
+= ev
->value
->errval
->XER_encode(
4469 *ev
->value
->type_descr
->xer
, p_buf
, flavor
, indent
, 0);
4473 ec
.set_msg("Component #0: ");
4475 // universal charstring does not have components.
4476 // TTCN code which could have generated embedded erroneous descriptor
4477 // should have failed semantic analysis.
4478 TTCN_error("internal error: embedded descriptor unexpected");
4480 // the "real" encoder
4481 if (q_uri
->is_present()) {
4482 p_buf
.put_s(11, (cbyte
*)" xmlns:b0='");
4483 sub_len
+= q_uri
->XER_encode(*xer_descr(0), p_buf
, flavor
| XER_LIST
, indent
+1, 0);
4489 if (ev
&& ev
->after
) {
4490 if (ev
->after
->errval
==NULL
) TTCN_error(
4491 "internal error: erroneous after value missing");
4492 ec
.set_msg("Erroneous value after component #0: ");
4493 if (ev
->after
->raw
) {
4494 sub_len
+= ev
->after
->errval
->encode_raw(p_buf
);
4496 if (ev
->after
->type_descr
==NULL
) TTCN_error(
4497 "internal error: erroneous after typedescriptor missing");
4498 sub_len
+= ev
->after
->errval
->XER_encode(
4499 *ev
->after
->type_descr
->xer
, p_buf
, flavor
, indent
, 0);
4503 if (p_td
.xer_bits
& XER_ATTRIBUTE
) begin_attribute(p_td
, p_buf
);
4504 else p_buf
.put_c('>');
4506 // Now switch to the second field (name)
4507 ev
= p_err_descr
->next_field_err_values(1, values_idx
);
4508 ed
= p_err_descr
->next_field_emb_descr (1, edescr_idx
);
4510 if (ev
&& ev
->before
) {
4511 if (ev
->before
->errval
==NULL
) TTCN_error(
4512 "internal error: erroneous before value missing");
4513 ec
.set_msg("Erroneous value before component #1: ");
4514 if (ev
->before
->raw
) {
4515 sub_len
+= ev
->before
->errval
->encode_raw(p_buf
);
4517 if (ev
->before
->type_descr
==NULL
) TTCN_error(
4518 "internal error: erroneous before typedescriptor missing");
4519 sub_len
+= ev
->before
->errval
->XER_encode(
4520 *ev
->before
->type_descr
->xer
, p_buf
, flavor
, indent
, 0);
4524 if (ev
&& ev
->value
) {
4525 if (ev
->value
->errval
) { // replace
4526 ec
.set_msg("Erroneous value for component #1: ");
4527 if (ev
->value
->raw
) {
4528 sub_len
+= ev
->value
->errval
->encode_raw(p_buf
);
4530 if (ev
->value
->type_descr
==NULL
) TTCN_error(
4531 "internal error: erroneous value typedescriptor missing");
4532 sub_len
+= ev
->value
->errval
->XER_encode(
4533 *ev
->value
->type_descr
->xer
, p_buf
, flavor
, indent
, 0);
4537 ec
.set_msg("Component #1: ");
4539 // universal charstring does not have components
4540 TTCN_error("internal error: embedded descriptor unexpected");
4542 // the "real" encoder
4543 if (q_uri
->is_present()) {
4544 p_buf
.put_s(3, (cbyte
*)"b0:");
4548 sub_len
+= get_at(1)->XER_encode(*xer_descr(1), p_buf
, flavor
| XER_LIST
, indent
+1, 0);
4552 if (ev
&& ev
->after
) {
4553 if (ev
->after
->errval
==NULL
) TTCN_error(
4554 "internal error: erroneous after value missing");
4555 ec
.set_msg("Erroneous value after component #1: ");
4556 if (ev
->after
->raw
) {
4557 sub_len
+= ev
->after
->errval
->encode_raw(p_buf
);
4559 if (ev
->after
->type_descr
==NULL
) TTCN_error(
4560 "internal error: erroneous after typedescriptor missing");
4561 sub_len
+= ev
->after
->errval
->XER_encode(
4562 *ev
->after
->type_descr
->xer
, p_buf
, flavor
, indent
, 0);
4566 if (p_td
.xer_bits
& XER_ATTRIBUTE
) p_buf
.put_c('\'');
4568 else { // not USE-QNAME
4569 if (!exer
&& (p_td
.xer_bits
& EMBED_VALUES
)) {
4570 // The EMBED-VALUES member as an ordinary record of string
4571 sub_len
+= embed_values
->XER_encode(*xer_descr(0), p_buf
, flavor
, indent
+1, 0);
4574 if (!exer
&& (p_td
.xer_bits
& USE_ORDER
)) {
4575 // The USE-ORDER member as an ordinary record of enumerated
4576 sub_len
+= use_order
->XER_encode(*xer_descr(uo_index
), p_buf
, flavor
, indent
+1, 0);
4579 if (exer
&& (indent
==0 || (flavor
& DEF_NS_SQUASHED
))) // write namespaces for toplevel only
4581 for (size_t cur_coll
= 0; cur_coll
< num_collected
; ++cur_coll
) {
4582 p_buf
.put_s(strlen(collected_ns
[cur_coll
]), (cbyte
*)collected_ns
[cur_coll
]);
4583 Free(collected_ns
[cur_coll
]); // job done
4589 flavor
&= ~DEF_NS_SQUASHED
;
4590 flavor
|= DEF_NS_PRESENT
;
4592 else if (empty_ns_hack
) {
4593 p_buf
.put_s(9, (cbyte
*)" xmlns=''");
4594 flavor
&= ~DEF_NS_PRESENT
;
4595 flavor
|= DEF_NS_SQUASHED
;
4598 // True if the non-attribute fields need to be omitted;
4599 // e.g. if USE_ORDER is in effect and the "nil" attribute was written
4600 // (then the record-of-enum for USE-ORDER will be empty),
4601 // or "omit all after" was hit while processing attributes.
4602 boolean early_to_bed
= FALSE
;
4604 // First all the attributes (not added to sub_len)
4606 for (i
= start_at
; i
< first_nonattr
; ++i
) {
4607 const Erroneous_values_t
* ev
=
4608 p_err_descr
->next_field_err_values(i
, values_idx
);
4609 const Erroneous_descriptor_t
* ed
=
4610 p_err_descr
->next_field_emb_descr(i
, edescr_idx
);
4612 if (i
< p_err_descr
->omit_before
) continue;
4614 boolean is_xer_attr_field
= xer_descr(i
)->xer_bits
& XER_ATTRIBUTE
;
4615 ec_1
.set_msg("%s': ", fld_name(i
)); // attr
4617 tmp_len
= encode_field(i
, ev
, ed
, p_buf
, flavor
, indent
+ !omit_tag
, 0);
4619 if (is_xer_attr_field
&& !exer
) sub_len
+= tmp_len
; // do not add if attribute and EXER
4621 // omit_after value -1 becomes "very big"
4622 if ((unsigned int)i
>= (unsigned int)p_err_descr
->omit_after
) {
4623 early_to_bed
= TRUE
; // no more fields to write
4628 // True if the "nil" attribute needs to be written.
4629 boolean nil_attribute
= FALSE
;
4630 // nil attribute unaffected by erroneous
4631 boolean nil_attribute_simple
= FALSE
;
4632 if (exer
&& (p_td
.xer_bits
& USE_NIL
)) {
4633 nil_attribute
= nil_attribute_simple
= !get_at(field_cnt
-1)->ispresent();
4635 if (p_err_descr
->values_size
> 0) // there is an erroneous "value := ..."
4637 const Erroneous_values_t
*ev_nil
=
4638 p_err_descr
->get_field_err_values(field_cnt
-1);
4639 if (ev_nil
&& ev_nil
->value
) // value override for the last field
4641 nil_attribute
= (ev_nil
->value
->errval
== NULL
);
4646 if (nil_attribute
) { // req. exer and USE_NIL
4647 const namespace_t
*control_ns
= p_td
.my_module
->get_controlns();
4649 if (!nil_attribute_simple
) {
4650 // It is likely that the declaration for namespace "xsi"
4651 // was not written. Do it now.
4652 p_buf
.put_s(7, (cbyte
*)" xmlns:");
4653 p_buf
.put_s(strlen(control_ns
->px
), (cbyte
*)control_ns
->px
);
4654 p_buf
.put_s(2, (cbyte
*)"='");
4655 p_buf
.put_s(strlen(control_ns
->ns
), (cbyte
*)control_ns
->ns
);
4660 p_buf
.put_s(strlen(control_ns
->px
), (cbyte
*)control_ns
->px
);
4662 p_buf
.put_s(10, (cbyte
*)"nil='true'");
4663 if ((p_td
.xer_bits
& USE_ORDER
)) early_to_bed
= TRUE
;
4664 // The whole content was omitted; nothing to do (and if we tried
4665 // to do it, we'd get an error for over-indexing a 0-length record-of).
4668 if (delay_close
&& (!omit_tag
|| shorter
)) {
4669 // Close the start tag left open. If indenting, also write a newline
4670 // unless USE-NIL in effect or there is a single untagged component.
4672 ((p_td
.xer_bits
& (/*USE_NIL|*/HAS_1UNTAGGED
)) ? 0 : indenting
);
4673 p_buf
.put_s(start_tag_len
, (cbyte
*)">\n");
4676 // Erroneous values for the embed_values member (if any).
4677 // Collected once but referenced multiple times.
4678 const Erroneous_descriptor_t
* ed0
= NULL
;
4679 int embed_values_val_idx
= 0;
4680 int embed_values_descr_idx
= 0;
4682 if (exer
&& (p_td
.xer_bits
& EMBED_VALUES
)) {
4683 ed0
= p_err_descr
->next_field_emb_descr(0, edescr_idx
);
4685 // write the first string
4686 if (embed_values
->size_of() > 0) {
4687 const Erroneous_values_t
* ev0_0
= NULL
;
4688 const Erroneous_descriptor_t
* ed0_0
= NULL
;
4690 ev0_0
= ed0
->next_field_err_values(0, embed_values_val_idx
);
4691 ed0_0
= ed0
->next_field_emb_descr (0, embed_values_descr_idx
);
4693 sub_len
+= embed_values
->encode_element(0, ev0_0
, ed0_0
,
4694 p_buf
, flavor
| EMBED_VALUES
, indent
+!omit_tag
, 0);
4698 const Record_Type
*ordered
= this; // the record affected by USE-ORDER
4699 // By default it's this record, unless USE_NIL is _also_ in effect,
4700 // in which case it's the last member of this.
4702 // Index of the first non-attribute field of the record pointed to by
4703 // ordered, that is, the first field affected by USE-ORDER.
4704 size_t useorder_base
= first_nonattr
;
4707 int end
= field_cnt
; // "one past", do not touch
4708 // by default, continue from the current field until the end, indexing this
4710 if (exer
&& (p_td
.xer_bits
& USE_ORDER
)) {
4711 // the length of the loop is determined by the length of use_order
4712 const int to_send
= use_order
->size_of();
4714 // i will index all elements of the use_order member
4718 // Count the non-attribute optionals
4719 int n_optionals
= 0;
4720 for (int B
= optional_count() - 1; B
>=+0; B
--) {
4721 int oi
= get_optional_indexes()[B
];
4722 if (oi
< first_nonattr
) break;
4726 int expected_min
= field_cnt
- first_nonattr
- n_optionals
;
4727 int expected_max
= field_cnt
- first_nonattr
;
4729 if ((p_td
.xer_bits
& USE_NIL
) && get_at(field_cnt
-1)->ispresent()) {
4730 // The special case when USE_ORDER refers to the fields of a field,
4732 const Base_Type
*last_optional
= get_at(field_cnt
-1);
4733 const Base_Type
* inner
= last_optional
->get_opt_value();
4734 // it absolutely, positively has to be (derived from) Record_Type
4735 ordered
= static_cast<const Record_Type
*>(inner
);
4736 useorder_base
= ordered
->get_xer_num_attr();
4737 begin
= useorder_base
;
4738 end
= ordered
->get_count();
4740 expected_min
= expected_max
= ordered
->get_count();
4743 if (to_send
> expected_max
4744 ||to_send
< expected_min
) {
4745 ec_1
.set_msg("%s': ", fld_name(uo_index
));
4746 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_CONSTRAINT
,
4747 "Wrong number of USE-ORDER %d, must be %d..%d", to_send
, expected_min
, expected_max
);
4748 early_to_bed
= TRUE
; // don't bother sending anything
4750 else { // check no duplicates
4751 int *seen
= new int [to_send
];
4753 for (int ei
= 0; ei
< to_send
; ++ei
) {
4754 const Base_Type
*uoe
= use_order
->get_at(ei
);
4755 const Enum_Type
*enm
= static_cast<const Enum_Type
*>(uoe
);
4756 int val
= enm
->as_int();
4757 for (int x
= 0; x
< num_seen
; ++x
) {
4758 if (val
== seen
[x
]) { // complain
4759 ec_1
.set_msg("%s': ", fld_name(uo_index
));
4760 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_CONSTRAINT
,
4761 "Duplicate value for USE-ORDER");
4762 early_to_bed
= TRUE
; // don't bother sending anything
4766 seen
[num_seen
++] = val
;
4770 // If the number is right and there are no duplicates, then carry on
4772 } // endif(USE_ORDER)
4774 // Then, all the non-attributes. Structuring the code like this depends on
4775 // all attributes appearing before all non-attributes (excluding
4776 // pseudo-members for USE-ORDER, etc.)
4778 // This loop handles both the normal case (no USE_ORDER) when i indexes
4779 // fields of this record; and the USE_ORDER case (with or without USE-NIL).
4781 // early_to_bed can only be true if exer is true (transitive through nil_attribute)
4782 if (!early_to_bed
) {
4783 embed_values_enc_struct_t
* emb_val
= 0;
4784 if (exer
&& (p_td
.xer_bits
& EMBED_VALUES
) && embed_values
->size_of() > 1) {
4785 emb_val
= new embed_values_enc_struct_t
;
4786 emb_val
->embval_array
= embed_values
;
4787 emb_val
->embval_index
= 1;
4788 emb_val
->embval_err
= ed0
;
4789 emb_val
->embval_err_val_idx
= embed_values_val_idx
;
4790 emb_val
->embval_err_descr_idx
= embed_values_descr_idx
;
4793 for ( i
= begin
; i
< end
; ++i
) {
4795 const Base_Type
*uoe
= 0; // "useOrder enum"
4796 const Enum_Type
*enm
= 0; // the enum value selecting the field
4798 // "actual" index, may be perturbed by USE-ORDER.
4799 // We use this value to index the appropriate record.
4802 const Erroneous_values_t
* ev
= NULL
;
4803 const Erroneous_descriptor_t
* ed
= NULL
;
4804 if (exer
&& use_order
) {
4805 // If USE-ORDER is in effect, it introduces a level of indirection
4806 // into the indexing of fields: "i" is used to select an element
4807 // of the use_order member (an enum), whose value is used to select
4808 // the field being encoded.
4809 uoe
= use_order
->get_at(i
- begin
);
4810 enm
= static_cast<const Enum_Type
*>(uoe
);
4811 ai
= enm
->as_int() + useorder_base
;
4813 // Because it is not guaranteed that ai will increase monotonically,
4814 // we can't use next_field_...().
4815 ev
= p_err_descr
->get_field_err_values(ai
);
4816 ed
= p_err_descr
->get_field_emb_descr (ai
);
4818 else { // not USE-ORDER, sequential access
4819 ev
= p_err_descr
->next_field_err_values(ai
, values_idx
);
4820 ed
= p_err_descr
->next_field_emb_descr (ai
, edescr_idx
);
4822 ec_1
.set_msg("%s': ", ordered
->fld_name(ai
)); // non-attr
4824 if (ai
< p_err_descr
->omit_before
) continue;
4826 // omit_after value -1 becomes "very big".
4827 if ((unsigned int)ai
> (unsigned int)p_err_descr
->omit_after
) continue;
4828 // We can't skip all fields with break, because the next ai may be lower
4831 sub_len
+= ordered
->encode_field(ai
, ev
, ed
, p_buf
,
4832 // Pass USE-NIL to the last field (except when USE-ORDER is also in effect,
4833 // because the tag-stripping effect of USE-NIL has been achieved
4834 // by encoding the sub-fields directly).
4835 flavor
| ((exer
&& !use_order
&& (i
== field_cnt
-1)) ? (p_td
.xer_bits
& USE_NIL
) : 0),
4836 indent
+ !omit_tag
, emb_val
);
4838 // Now the next embed-values string (NOT affected by USE-ORDER!)
4839 if (exer
&& (p_td
.xer_bits
& EMBED_VALUES
) && 0 != emb_val
&&
4840 emb_val
->embval_index
< embed_values
->size_of()) {
4841 const Erroneous_values_t
* ev0_i
= NULL
;
4842 const Erroneous_descriptor_t
* ed0_i
= NULL
;
4844 ev0_i
= ed0
->next_field_err_values(emb_val
->embval_index
, emb_val
->embval_err_val_idx
);
4845 ed0_i
= ed0
->next_field_emb_descr (emb_val
->embval_index
, emb_val
->embval_err_descr_idx
);
4847 embed_values
->encode_element(emb_val
->embval_index
, ev0_i
, ed0_i
,
4848 p_buf
, flavor
| EMBED_VALUES
, indent
+ !omit_tag
, 0);
4849 ++emb_val
->embval_index
;
4853 if (emb_val
->embval_index
< embed_values
->size_of()) {
4854 ec_1
.set_msg("%s': ", fld_name(0));
4855 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_CONSTRAINT
,
4856 "Too many EMBED-VALUEs specified: %d (expected %d or less)",
4857 embed_values
->size_of(), emb_val
->embval_index
);
4861 } // if (!early_to_bed)
4866 if (sub_len
) { // something was written, now an end tag
4867 if (indenting
&& !(exer
&& (p_td
.xer_bits
& (HAS_1UNTAGGED
| USE_QNAME
))))
4868 // The tags of the last optional member involved with USE_NIL
4869 // have been removed. If it was a simple type, the content was probably
4870 // written on a single line without anything resembling a close tag.
4871 // Do not indent our end tag in this case.
4872 switch ((int)(exer
&& (p_td
.xer_bits
& USE_NIL
))) {
4874 const unsigned char *buf_end
= p_buf
.get_data() + (p_buf
.get_len()-1);
4875 if (buf_end
[-1] != '>' || *buf_end
!= '\n') break;
4876 // If it does not look like an end tag, skip the indenting,
4877 // else fall through.
4880 do_indent(p_buf
, indent
);
4885 if (exer
) write_ns_prefix(p_td
, p_buf
);
4886 p_buf
.put_s((size_t)p_td
.namelens
[exer
]-!indenting
, (cbyte
*)p_td
.names
[exer
]);
4888 else { // need to generate an empty element tag
4889 p_buf
.increase_length(-start_tag_len
); // decrease length
4890 p_buf
.put_s((size_t)2+indenting
, (cbyte
*)"/>\n");
4894 return (int)p_buf
.get_len() - encoded_length
;
4897 int Record_Type::XER_decode(const XERdescriptor_t
& p_td
, XmlReaderWrap
& reader
,
4898 unsigned int flavor
, embed_values_dec_struct_t
*)
4901 int exer
= is_exer(flavor
);
4903 int depth
=-1; // depth of the start tag
4904 int xerbits
= p_td
.xer_bits
;
4905 if (flavor
& XER_TOPLEVEL
) xerbits
&= ~UNTAGGED
;
4906 const boolean own_tag
= !(exer
4907 && ( (xerbits
& (ANY_ELEMENT
| UNTAGGED
| XER_ATTRIBUTE
))
4908 || (flavor
& (USE_NIL
| USE_TYPE_ATTR
))));
4909 boolean tag_closed
= (flavor
& PARENT_CLOSED
) != 0;
4910 // If the parent has USE-TYPE, our ATTRIBUTE members can be found
4911 // in the parent's tag (the reader is sitting on it).
4912 const boolean parent_tag
= exer
&& (flavor
& (/*USE_NIL|*/ USE_TYPE_ATTR
));
4914 // Filter out flags passed by our parent. These are not for the fields.
4915 flavor
&= XER_MASK
; // also removes XER_TOPLEVEL
4917 const int field_cnt
= get_count();
4918 const int num_attributes
= get_xer_num_attr();
4920 // The index of potential "order" field, regardless of whether USE_ORDER
4921 // is in use or not.
4922 const int uo_index
= ((p_td
.xer_bits
& EMBED_VALUES
) !=0);
4924 // The first "non-special" field (skipping the USE-ORDER and EMBED-VALUES
4925 // fields); normal processing start at this field.
4926 const int start_at
= uo_index
+ ((p_td
.xer_bits
& USE_ORDER
) != 0);
4927 const int first_nonattr
= start_at
+ num_attributes
;
4929 // The index of the ANY-ATTRIBUTES member, if any
4931 for (int k
= 0; k
< first_nonattr
; ++k
) {
4932 if (xer_descr(k
)->xer_bits
& ANY_ATTRIBUTES
) {
4934 if (!get_at(aa_index
)->is_optional()) {
4935 static_cast<Record_Of_Type
*>(get_at(aa_index
))->set_size(0);
4937 break; // there can be only one, 18.2.2
4941 if (own_tag
) for (success
=reader
.Ok(); success
==1; success
=reader
.Read()) {
4942 type
= reader
.NodeType();
4943 if (type
==XML_READER_TYPE_ELEMENT
) {
4944 verify_name(reader
, p_td
, exer
);
4945 depth
= reader
.Depth();
4946 tag_closed
= reader
.IsEmptyElement();
4953 if (exer
&& (p_td
.xer_bits
& USE_QNAME
)) { // QName trumps everything !
4954 // If element, it looks like this:
4955 // <name xmlns:b0="http://www.furniture.com">b0:table</name>
4956 // If attribute, it looks like this:
4959 if (p_td
.xer_bits
& XER_ATTRIBUTE
) success
= 1; // do nothing
4960 else for (success
= reader
.Read(); success
== 1; success
= reader
.Read()) {
4961 type
= reader
.NodeType();
4962 if (type
== XML_READER_TYPE_TEXT
) break;
4966 xmlChar
*val
= reader
.NewValue();
4967 xmlChar
*npfx
= (xmlChar
*)strchr((char*)val
, ':');
4970 *npfx
++ = '\0'; // cut the string into two
4978 xmlChar
*nsu
= reader
.LookupNamespace(pfx
);
4980 OPTIONAL
<UNIVERSAL_CHARSTRING
> *q_prefix2
=
4981 static_cast<OPTIONAL
<UNIVERSAL_CHARSTRING
>*>(get_at(0));
4982 if (nsu
) *q_prefix2
= (const char*)nsu
;
4983 else q_prefix2
->set_to_omit(); // public in RT2 only
4985 UNIVERSAL_CHARSTRING
*q_name2
= static_cast<UNIVERSAL_CHARSTRING
*>(get_at(1));
4986 *q_name2
= (const char*)npfx
;
4992 else { // not use-qname
4993 TTCN_EncDec_ErrorContext
ec_0("Component '");
4994 TTCN_EncDec_ErrorContext ec_1
;
4995 boolean usenil_attribute
= FALSE
; // true if found and said yes
4997 if (!reader
.IsEmptyElement()) reader
.Read();
4998 // First, the (would-be) attributes (unaffected by USE-ORDER)
4999 for (i
= 0; i
< first_nonattr
; i
++) {
5000 ec_1
.set_msg("%s': ", fld_name(i
));
5001 get_at(i
)->XER_decode(*xer_descr(i
), reader
, flavor
, 0);
5004 else if (own_tag
|| parent_tag
) { // EXER and not UNTAGGED: do attributes
5005 // Prepare for lack of attributes.
5006 // Fields with defaultForEmpty get the D-F-E value, optional get omit.
5007 for (i
= start_at
; i
< first_nonattr
; i
++) {
5008 Base_Type
&fld
= *get_at(i
);
5009 const XERdescriptor_t
& xd
= *xer_descr(i
);
5011 if (fld
.is_optional()) {
5012 fld
.set_to_present();
5013 fld
.get_opt_value()->set_value(xd
.dfeValue
);
5015 else fld
.set_value(xd
.dfeValue
);
5017 else if (fld
.is_optional()) fld
.set_to_omit();
5020 int num_aa
= 0; // index into the ANY-ATTRIBUTE member
5022 const namespace_t
*control_ns
= 0;
5023 if (parent_tag
|| (p_td
.xer_bits
& USE_NIL
)) {
5024 // xsi:type or xsi:nil
5025 control_ns
= p_td
.my_module
->get_controlns();
5028 /* * * * * * * * * Attributes * * * * * * * * * * * * * */
5029 for (success
= reader
.MoveToFirstAttribute();
5030 success
== 1 && reader
.NodeType() == XML_READER_TYPE_ATTRIBUTE
;
5031 success
= reader
.AdvanceAttribute())
5033 if (reader
.IsNamespaceDecl()) {
5034 continue; // namespace declarations are handled for us by libxml2
5037 const char *attr_name
= (const char*)reader
.LocalName();
5038 const char *ns_uri
= (const char*)reader
.NamespaceUri();
5039 int field_index
= get_index_byname(attr_name
, ns_uri
);
5040 if (field_index
!= -1) {
5041 // There is a field. Let it decode the attribute.
5042 ec_1
.set_msg("%s': ", fld_name(field_index
));
5043 get_at(field_index
)->XER_decode(*xer_descr(field_index
), reader
, flavor
, 0);
5047 // Attribute not found. It could be the "nil" attribute
5048 if (p_td
.xer_bits
& USE_NIL
) {
5049 const char *prefix
= (const char*)reader
.Prefix();
5050 // prefix may be NULL, control_ns->px is never NULL or empty
5051 if (prefix
&& !strcmp(prefix
, control_ns
->px
)
5052 && !strcmp((const char*)reader
.LocalName(), "nil"))
5053 { // It is the "nil" attribute
5054 const char *value
= (const char*)reader
.Value();
5056 if (!strcmp(value
, "1") || !strcmp(value
, "true")) {
5057 // The field affected by USE-NIL is always the last one
5058 get_at(field_cnt
-1)->set_to_omit();
5059 usenil_attribute
= TRUE
;
5064 } // it is the "nil" attribute
5065 } // type has USE-NIL
5068 const char *prefix
= (const char*)reader
.Prefix();
5069 // prefix may be NULL, control_ns->px is never NULL or empty
5070 if (prefix
&& !strcmp(prefix
, control_ns
->px
)
5071 && !strcmp((const char*)reader
.LocalName(), "type")) {
5072 continue; // xsi:type has been processed by the parent
5076 if (aa_index
>= 0) {
5077 ec_1
.set_msg("%s': ", fld_name(aa_index
));
5078 TTCN_EncDec_ErrorContext
ec_2("Attribute %d: ", num_aa
);
5079 // We have a component with ANY-ATTRIBUTE. It must be a record of
5080 // UNIVERSAL_CHARSTRING. Add the attribute to it.
5081 Record_Of_Type
*aa
= 0;
5082 if (get_at(aa_index
)->is_optional()) {
5084 get_at(aa_index
)->set_to_present();
5086 aa
= static_cast<Record_Of_Type
*>(get_at(aa_index
)->get_opt_value());
5089 aa
= static_cast<Record_Of_Type
*>(get_at(aa_index
));
5091 UNIVERSAL_CHARSTRING
*new_elem
= static_cast<UNIVERSAL_CHARSTRING
*>
5092 (aa
->get_at(num_aa
++));
5094 // Construct the AnyAttributeFormat (X.693amd1, 18.2.6)
5096 const xmlChar
*name
= reader
.LocalName();
5097 const xmlChar
*val
= reader
.Value();
5098 const xmlChar
*uri
= reader
.NamespaceUri();
5100 if (xer_descr(aa_index
)->xer_bits
& (ANY_FROM
| ANY_EXCEPT
)) {
5101 check_namespace_restrictions(*xer_descr(aa_index
), (const char*)uri
);
5103 // We don't care about reader.Prefix()
5104 // Using strlen to count UTF8 bytes, not characters
5105 aabuf
.put_s(uri
? strlen((const char*)uri
) : 0, uri
);
5106 if (uri
&& *uri
) aabuf
.put_c(' ');
5107 aabuf
.put_s(name
? strlen((const char*)name
) : 0, name
);
5110 aabuf
.put_s(val
? strlen((const char*)val
) : 0, val
);
5112 new_elem
->decode_utf8(aabuf
.get_len(), aabuf
.get_data());
5117 // Lastly check for the xsi:schemaLocation attribute, this does not
5118 // affect TTCN-3, but it shouldn't cause a DTE
5119 if (reader
.LocalName() && !strcmp((const char*)reader
.LocalName(), "schemaLocation")) {
5121 control_ns
= p_td
.my_module
->get_controlns();
5123 if (reader
.Prefix() && !strcmp((const char*)reader
.Prefix(), control_ns
->px
)) {
5128 // Nobody wanted the attribute. That is an error.
5129 ec_0
.set_msg(" "); ec_1
.set_msg(" ");
5130 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG
,
5131 "Unexpected attribute '%s', ns '%s'", attr_name
,
5132 ns_uri
? ns_uri
: "");
5135 // Now check that all mandatory attributes have been set
5136 for (i
= start_at
; i
< first_nonattr
; ++i
) {
5137 Base_Type
* fld
= get_at(i
);
5138 if (fld
->is_optional()) continue; // field is allowed to be unset
5139 if (!fld
->is_bound()) {
5140 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG
,
5141 "Missing attribute '%s'", this->fld_name(i
));
5145 i
= first_nonattr
; // finished with attributes
5146 // AdvanceAttribute did MoveToElement. Move into the content (if any).
5147 if (!reader
.IsEmptyElement()) reader
.Read();
5148 } // end if (own_tag)
5150 /* * * * * * * * Non-attributes (elements) * * * * * * * * * * * */
5151 embed_values_dec_struct_t
* emb_val
= 0;
5152 if (exer
&& (p_td
.xer_bits
& EMBED_VALUES
)) {
5153 emb_val
= new embed_values_dec_struct_t
;
5154 emb_val
->embval_array
= static_cast<Record_Of_Type
*>(get_at(0));
5155 emb_val
->embval_array
->set_size(0);
5156 emb_val
->embval_index
= 0;
5159 if (exer
&& (p_td
.xer_bits
& USE_ORDER
)) {
5160 // Set all optional fields to omit because their respective XER_decode
5161 // will not be run (and will stay unbound) if the value is missing.
5162 int n_optionals
= 0;
5163 for (int B
= optional_count() - 1; B
>=+0; B
--) {
5164 int oi
= get_optional_indexes()[B
];
5165 if (oi
< first_nonattr
) break;
5166 get_at(oi
)->set_to_omit();
5169 Record_Of_Type
*use_order
= static_cast<Record_Of_Type
*>(get_at(uo_index
));
5170 // Initialize the use_order field to empty. Let it grow on demand.
5171 // (setting it to the minimum acceptable size may leave unbound elements
5172 // if the XML was incomplete).
5173 use_order
->set_size(0);
5175 Record_Type
*jumbled
= this; // the record affected by USE_ORDER
5176 int begin
= first_nonattr
;
5177 int end
= field_cnt
; // "one past"
5178 if (p_td
.xer_bits
& USE_NIL
) {
5179 Base_Type
*last_optional
= get_at(field_cnt
-1);
5180 if (!usenil_attribute
) { // exer known true
5181 last_optional
->set_to_present();
5182 jumbled
= static_cast<Record_Type
*>(last_optional
->get_opt_value());
5183 // We will operate on the members of last_optional,
5184 // effectively bypassing last_optional->XER_decode() itself.
5186 end
= jumbled
->get_count();
5187 ec_1
.set_msg("%s': ", fld_name(field_cnt
-1));
5190 if (num_attributes
> 0
5191 && first_nonattr
!= field_cnt
5192 && i
== first_nonattr
- 1) { // exer known true
5193 // If there were attributes and their processing just finished,
5194 // the reader is positioned on the start tag of the record.
5195 // Move ahead, unless there are no non-attribute fields.
5198 // Then, the non-attributes
5200 // The index runs over the members affected by USE-ORDER.
5201 // This is [first_nonattr,field_cnt) unless USE-NIL is involved,
5202 // in which case it's [0,optional_sequence::field_cnt)
5203 int *seen
= new int[end
-begin
];
5205 int last_any_elem
= begin
- 1;
5206 // The index of the latest embedded value can change outside of this function
5207 // (if the field is a untagged record of), in this case the next value should
5208 // be ignored, as it's already been handled by the record of
5209 int last_embval_index
= 0;
5210 for (i
= begin
; i
< end
; i
++) {
5211 for (success
= reader
.Ok(); success
== 1; success
= reader
.Read()) {
5212 type
= reader
.NodeType();
5213 if (0 != emb_val
&& reader
.NodeType()==XML_READER_TYPE_TEXT
) {
5214 UNIVERSAL_CHARSTRING
emb_ustr((const char*)reader
.Value());
5215 emb_val
->embval_array
->get_at(emb_val
->embval_index
)->set_value(&emb_ustr
);
5217 // The non-attribute components must not be UNTAGGED
5218 if (type
== XML_READER_TYPE_ELEMENT
) break;
5219 // else if (type==XML_READER_TYPE_END_ELEMENT) panic?
5222 if (last_embval_index
== emb_val
->embval_index
) {
5223 ++emb_val
->embval_index
;
5225 last_embval_index
= emb_val
->embval_index
;
5227 if (success
!= 1) break;
5228 const char *name
= (const char *)reader
.LocalName();
5229 boolean field_name_found
= false;
5230 // Find out which member it is.
5231 // FIXME some hashing should be implemented
5232 for (int k
= begin
; k
< end
; k
++) {
5233 if (!(jumbled
->xer_descr(k
)->xer_bits
& ANY_ELEMENT
) &&
5234 check_name(name
, *jumbled
->xer_descr(k
), 1)) {
5235 ec_1
.set_msg("%s': ", jumbled
->fld_name(k
));
5237 // Check for the same field being decoded twice.
5238 // We can't use the field's is_bound()/is_present(),
5239 // because the field may be bound on input, e.g. for
5240 // prototype(fast) or prototype(backtrack).
5241 int in_dex
= k
- begin
;
5242 for (int o
= 0; o
< num_seen
;++o
) {
5243 if (in_dex
== seen
[o
]) TTCN_EncDec_ErrorContext::error(
5244 TTCN_EncDec::ET_INVAL_MSG
, "Duplicate element");
5246 seen
[num_seen
++] = in_dex
;
5247 // Set the next use-order member.
5248 // Non-const get_at creates the object in the record-of.
5249 static_cast<Enum_Type
*>(use_order
->get_at(i
- begin
))
5251 Base_Type
*b
= jumbled
->get_at(k
);
5252 b
->XER_decode(*jumbled
->xer_descr(k
), reader
, flavor
, emb_val
);
5253 field_name_found
= true;
5257 if (!field_name_found
) {
5258 // Check the anyElement fields
5259 for (int k
= last_any_elem
+ 1; k
< end
; k
++) {
5260 if (jumbled
->xer_descr(k
)->xer_bits
& ANY_ELEMENT
) {
5261 ec_1
.set_msg("%s': ", jumbled
->fld_name(k
));
5263 // Check for the same field being decoded twice.
5264 // We can't use the field's is_bound()/is_present(),
5265 // because the field may be bound on input, e.g. for
5266 // prototype(fast) or prototype(backtrack).
5267 int in_dex
= k
- begin
;
5268 for (int o
= 0; o
< num_seen
;++o
) {
5269 if (in_dex
== seen
[o
]) TTCN_EncDec_ErrorContext::error(
5270 TTCN_EncDec::ET_INVAL_MSG
, "Duplicate element");
5272 seen
[num_seen
++] = in_dex
;
5273 // Set the next use-order member.
5274 // Non-const get_at creates the object in the record-of.
5275 static_cast<Enum_Type
*>(use_order
->get_at(i
- begin
))
5277 Base_Type
*b
= jumbled
->get_at(k
);
5278 b
->XER_decode(*jumbled
->xer_descr(k
), reader
, flavor
, emb_val
);
5286 if (reader
.NodeType()==XML_READER_TYPE_TEXT
) {
5287 UNIVERSAL_CHARSTRING
emb_ustr((const char*)reader
.Value());
5288 emb_val
->embval_array
->get_at(emb_val
->embval_index
)->set_value(&emb_ustr
);
5290 if (last_embval_index
== emb_val
->embval_index
) {
5291 ++emb_val
->embval_index
;
5295 ec_1
.set_msg(" "); // no active component
5298 // Check that we collected the required number of children
5299 int num_collected
= use_order
->size_of();
5300 if (p_td
.xer_bits
& USE_NIL
) {
5301 int expected
= usenil_attribute
? 0 : jumbled
->get_count();
5302 if (num_collected
!= expected
) {
5303 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INCOMPL_MSG
,
5304 "Incorrect number of fields %d, expected %d",
5305 num_collected
, expected
);
5309 if (num_collected
< field_cnt
- first_nonattr
- n_optionals
5310 ||num_collected
> field_cnt
- first_nonattr
) {
5311 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INCOMPL_MSG
,
5312 "Wrong number of fields! size = %d, expected %d..%d",
5313 use_order
->size_of(), field_cnt
- first_nonattr
- n_optionals
,
5314 field_cnt
- first_nonattr
);
5318 else { // not USE-ORDER, simpler code
5319 if (usenil_attribute
) {
5320 reader
.MoveToElement(); // value absent, nothing more to do
5322 // The index of the latest embedded value can change outside of this function
5323 // (if the field is a untagged record of), in this case the next value should
5324 // be ignored, as it's already been handled by the record of
5325 // Omitted fields can also reset this value
5326 int last_embval_index
= 0;
5327 for (; i
<field_cnt
; i
++) {
5329 if (reader
.NodeType()==XML_READER_TYPE_TEXT
) {
5330 UNIVERSAL_CHARSTRING
emb_ustr((const char*)reader
.Value());
5331 emb_val
->embval_array
->get_at(emb_val
->embval_index
)->set_value(&emb_ustr
);
5333 if (last_embval_index
== emb_val
->embval_index
) {
5334 ++emb_val
->embval_index
;
5336 last_embval_index
= emb_val
->embval_index
;
5338 ec_1
.set_msg("%s': ", fld_name(i
));
5339 if (exer
&& i
==field_cnt
-1 && p_td
.dfeValue
&& reader
.IsEmptyElement()) {
5340 get_at(i
)->set_value(p_td
.dfeValue
);
5343 // In case the field is an optional anyElement -> check if it should be omitted
5344 bool optional_any_elem_check
= true;
5345 if (get_at(i
)->is_optional() && (xer_descr(i
)->xer_bits
& ANY_ELEMENT
)) {
5346 // The "anyElement" coding instruction can only be applied to a universal charstring field
5347 OPTIONAL
<UNIVERSAL_CHARSTRING
>* opt_field
= dynamic_cast<OPTIONAL
<UNIVERSAL_CHARSTRING
>*>(get_at(i
));
5349 const char* next_field_name
= NULL
;
5350 if (i
< field_cnt
- 1) {
5351 next_field_name
= fld_name(i
+ 1);
5353 optional_any_elem_check
= opt_field
->XER_check_any_elem(reader
, next_field_name
, tag_closed
);
5356 if (optional_any_elem_check
) {
5357 int new_flavor
= flavor
;
5358 if (i
== field_cnt
-1) new_flavor
|= (p_td
.xer_bits
& USE_NIL
);
5359 if (tag_closed
) new_flavor
|= PARENT_CLOSED
;
5361 get_at(i
)->XER_decode(*xer_descr(i
), reader
, new_flavor
, emb_val
);
5364 if (!get_at(i
)->is_present()) {
5365 // there was no new element, the last embedded value is for the next field
5366 // (or the end of the record if this is the last field)
5367 last_embval_index
= -1;
5371 if (reader
.NodeType()==XML_READER_TYPE_TEXT
) {
5372 UNIVERSAL_CHARSTRING
emb_ustr((const char*)reader
.Value());
5373 emb_val
->embval_array
->get_at(emb_val
->embval_index
)->set_value(&emb_ustr
);
5375 if (last_embval_index
== emb_val
->embval_index
) {
5376 ++emb_val
->embval_index
;
5383 static const UNIVERSAL_CHARSTRING
emptystring(0, (const char*)NULL
);
5384 for (int j
= 0; j
< emb_val
->embval_index
; ++j
) {
5385 if (!emb_val
->embval_array
->get_at(j
)->is_bound()) {
5386 emb_val
->embval_array
->get_at(j
)->set_value(&emptystring
);
5390 } // if embed-values
5395 // We had our start tag. Then our fields did their thing.
5396 // Now we expect the end tag. And it better be our end tag!
5398 for (success
= reader
.Ok(); success
== 1; success
= reader
.Read()) {
5399 type
= reader
.NodeType();
5400 current_depth
= reader
.Depth();
5401 if (current_depth
> depth
) {
5402 if (XML_READER_TYPE_ELEMENT
== type
) {
5403 // We found a deeper start tag; it was not processed at all.
5404 // That is an error (maybe we should report error for all node types
5405 // except TEXT and WHITESPACE, not just ELEMENT).
5406 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TAG
,
5407 "Unprocessed XML tag `%s'", (const char *)reader
.Name());
5410 continue; // go past hoping that our end tag will arrive eventually
5412 else if (current_depth
== depth
) { // at our level
5413 if (XML_READER_TYPE_ELEMENT
== type
) {
5414 verify_name(reader
, p_td
, exer
);
5415 if (reader
.IsEmptyElement()) {
5416 // FIXME this shouldn't really be possible;
5417 // only an empty record should be encoded as an empty element,
5418 // but those are implemented by Empty_Record_Type, not Record_Type.
5419 reader
.Read(); // one last time
5423 // If we find an end tag at the right depth, it must be ours
5424 else if (XML_READER_TYPE_END_ELEMENT
== type
) {
5425 verify_end(reader
, p_td
, depth
, exer
);
5430 else { //current_depth < depth; something has gone horribly wrong
5431 break; // better quit before we do further damage
5432 // Don't report an error; every enclosing type would do so,
5433 // spewing the same message over and over.
5437 return 1; // decode successful
5440 int Record_Type::JSON_encode(const TTCN_Typedescriptor_t
&, JSON_Tokenizer
& p_tok
) const
5443 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND
,
5444 "Encoding an unbound %s value.", is_set() ? "set" : "record");
5448 int enc_len
= p_tok
.put_next_token(JSON_TOKEN_OBJECT_START
, NULL
);
5450 int field_count
= get_count();
5451 for(int i
= 0; i
< field_count
; ++i
) {
5452 if ((NULL
!= fld_descr(i
)->json
&& fld_descr(i
)->json
->omit_as_null
) ||
5453 !get_at(i
)->is_optional() || get_at(i
)->is_present()) {
5454 if (NULL
!= fld_descr(i
)->json
&& NULL
!= fld_descr(i
)->json
->alias
) {
5455 enc_len
+= p_tok
.put_next_token(JSON_TOKEN_NAME
, fld_descr(i
)->json
->alias
);
5457 enc_len
+= p_tok
.put_next_token(JSON_TOKEN_NAME
, fld_name(i
));
5459 enc_len
+= get_at(i
)->JSON_encode(*fld_descr(i
), p_tok
);
5463 enc_len
+= p_tok
.put_next_token(JSON_TOKEN_OBJECT_END
, NULL
);
5467 int Record_Type::JSON_decode(const TTCN_Typedescriptor_t
& p_td
, JSON_Tokenizer
& p_tok
, boolean p_silent
)
5469 json_token_t token
= JSON_TOKEN_NONE
;
5470 int dec_len
= p_tok
.get_next_token(&token
, NULL
, NULL
);
5471 if (JSON_TOKEN_ERROR
== token
) {
5472 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG
, JSON_DEC_BAD_TOKEN_ERROR
, "");
5473 return JSON_ERROR_FATAL
;
5475 else if (JSON_TOKEN_OBJECT_START
!= token
) {
5476 return JSON_ERROR_INVALID_TOKEN
;
5480 const int field_count
= get_count();
5483 // Read name - value token pairs until we reach some other token
5485 size_t name_len
= 0;
5486 size_t buf_pos
= p_tok
.get_buf_pos();
5487 dec_len
+= p_tok
.get_next_token(&token
, &name
, &name_len
);
5488 if (JSON_TOKEN_ERROR
== token
) {
5489 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG
, JSON_DEC_BAD_TOKEN_ERROR
, "");
5490 return JSON_ERROR_FATAL
;
5492 else if (JSON_TOKEN_NAME
!= token
) {
5493 // undo the last action on the buffer
5494 p_tok
.set_buf_pos(buf_pos
);
5500 for (field_idx
= 0; field_idx
< field_count
; ++field_idx
) {
5501 const char* expected_name
= 0;
5502 if (NULL
!= fld_descr(field_idx
)->json
&& NULL
!= fld_descr(field_idx
)->json
->alias
) {
5503 expected_name
= fld_descr(field_idx
)->json
->alias
;
5505 expected_name
= fld_name(field_idx
);
5507 if (strlen(expected_name
) == name_len
&&
5508 0 == strncmp(expected_name
, name
, name_len
)) {
5512 if (field_count
== field_idx
) {
5513 // invalid field name
5514 char* name2
= mcopystrn(name
, name_len
);
5515 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG
, JSON_DEC_INVALID_NAME_ERROR
, name2
);
5516 // if this is set to a warning, skip the value of the field
5517 dec_len
+= p_tok
.get_next_token(&token
, NULL
, NULL
);
5518 if (JSON_TOKEN_NUMBER
!= token
&& JSON_TOKEN_STRING
!= token
&&
5519 JSON_TOKEN_LITERAL_TRUE
!= token
&& JSON_TOKEN_LITERAL_FALSE
!= token
&&
5520 JSON_TOKEN_LITERAL_NULL
!= token
) {
5521 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG
, JSON_DEC_FIELD_TOKEN_ERROR
, name2
);
5523 return JSON_ERROR_FATAL
;
5529 int ret_val
= get_at(field_idx
)->JSON_decode(*fld_descr(field_idx
), p_tok
, p_silent
);
5531 if (JSON_ERROR_INVALID_TOKEN
) {
5532 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG
, JSON_DEC_FIELD_TOKEN_ERROR
, fld_name(field_idx
));
5534 return JSON_ERROR_FATAL
;
5540 dec_len
+= p_tok
.get_next_token(&token
, NULL
, NULL
);
5541 if (JSON_TOKEN_OBJECT_END
!= token
) {
5542 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG
, JSON_DEC_OBJECT_END_TOKEN_ERROR
, "");
5543 return JSON_ERROR_FATAL
;
5546 // Check if every field has been set
5547 for (int field_idx
= 0; field_idx
< field_count
; ++field_idx
) {
5548 Base_Type
* field
= get_at(field_idx
);
5549 if (!field
->is_bound()) {
5550 if (NULL
!= fld_descr(field_idx
)->json
&& NULL
!= fld_descr(field_idx
)->json
->default_value
) {
5551 get_at(field_idx
)->JSON_decode(*fld_descr(field_idx
), DUMMY_BUFFER
, p_silent
);
5553 else if (field
->is_optional()) {
5554 field
->set_to_omit();
5556 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG
, JSON_DEC_MISSING_FIELD_ERROR
, fld_name(field_idx
));
5557 return JSON_ERROR_FATAL
;
5565 ////////////////////////////////////////////////////////////////////////////////
5567 Empty_Record_Type::Empty_Record_Type(): bound_flag(FALSE
)
5571 Empty_Record_Type::Empty_Record_Type(const Empty_Record_Type
& other_value
)
5572 : Base_Type(other_value
), bound_flag(other_value
.bound_flag
)
5574 if (!other_value
.bound_flag
)
5575 TTCN_error("Copying an unbound value of type %s.",
5576 other_value
.get_descriptor()->name
);
5579 boolean
Empty_Record_Type::operator==(null_type
) const
5582 TTCN_error("Comparison of an unbound value of type %s.",
5583 get_descriptor()->name
);
5587 void Empty_Record_Type::log() const
5589 if (bound_flag
) TTCN_Logger::log_event_str("{ }");
5590 else TTCN_Logger::log_event_unbound();
5593 void Empty_Record_Type::set_param(Module_Param
& param
) {
5594 param
.basic_check(Module_Param::BC_VALUE
, "empty record/set value (i.e. { })");
5595 if (param
.get_type()!=Module_Param::MP_Value_List
|| param
.get_size()>0) {
5596 param
.type_error("empty record/set value (i.e. { })", get_descriptor()->name
);
5601 void Empty_Record_Type::encode_text(Text_Buf
& /*text_buf*/) const
5604 TTCN_error("Text encoder: Encoding an unbound value of type %s.",
5605 get_descriptor()->name
);
5608 void Empty_Record_Type::decode_text(Text_Buf
& /*text_buf*/)
5613 boolean
Empty_Record_Type::is_equal(const Base_Type
* other_value
) const
5615 const Empty_Record_Type
* r2
= static_cast<const Empty_Record_Type
*>(other_value
);
5616 if ((bound_flag
&& r2
->bound_flag
) || (!bound_flag
&& !r2
->bound_flag
))
5618 if (!bound_flag
|| !r2
->bound_flag
)
5619 TTCN_error("Comparison of an unbound value of type %s.", get_descriptor()->name
);
5623 void Empty_Record_Type::set_value(const Base_Type
* other_value
)
5625 if (!static_cast<const Empty_Record_Type
*>(other_value
)->is_bound())
5626 TTCN_error("Assignment of an unbound value of type %s.",
5627 other_value
->get_descriptor()->name
);
5631 void Empty_Record_Type::encode(const TTCN_Typedescriptor_t
& p_td
,
5632 TTCN_Buffer
& p_buf
, TTCN_EncDec::coding_t p_coding
, ...) const
5635 va_start(pvar
, p_coding
);
5637 case TTCN_EncDec::CT_BER
: {
5638 TTCN_EncDec_ErrorContext
ec("While BER-encoding type '%s': ", p_td
.name
);
5639 unsigned BER_coding
=va_arg(pvar
, unsigned);
5640 BER_encode_chk_coding(BER_coding
);
5641 ASN_BER_TLV_t
*tlv
=BER_encode_TLV(p_td
, BER_coding
);
5642 tlv
->put_in_buffer(p_buf
);
5643 ASN_BER_TLV_t::destruct(tlv
);
5645 case TTCN_EncDec::CT_RAW
: {
5646 TTCN_EncDec_ErrorContext
ec("While RAW-encoding type '%s': ", p_td
.name
);
5647 if(!p_td
.raw
) TTCN_EncDec_ErrorContext::error_internal
5648 ("No RAW descriptor available for type '%s'.", p_td
.name
);
5652 RAW_enc_tree
root(FALSE
, NULL
, &rp
, 1, p_td
.raw
);
5653 RAW_encode(p_td
, root
);
5654 root
.put_to_buf(p_buf
);
5656 case TTCN_EncDec::CT_TEXT
: {
5657 TTCN_EncDec_ErrorContext
ec("While TEXT-encoding type '%s': ", p_td
.name
);
5658 if(!p_td
.text
) TTCN_EncDec_ErrorContext::error_internal
5659 ("No TEXT descriptor available for type '%s'.", p_td
.name
);
5660 TEXT_encode(p_td
,p_buf
);
5662 case TTCN_EncDec::CT_XER
: {
5663 TTCN_EncDec_ErrorContext
ec("While XER-encoding type '%s': ", p_td
.name
);
5664 unsigned XER_coding
=va_arg(pvar
, unsigned);
5665 XER_encode(*(p_td
.xer
),p_buf
, XER_coding
, 0, 0);
5668 case TTCN_EncDec::CT_JSON
: {
5669 TTCN_EncDec_ErrorContext
ec("While JSON-encoding type '%s': ", p_td
.name
);
5670 if(!p_td
.json
) TTCN_EncDec_ErrorContext::error_internal
5671 ("No JSON descriptor available for type '%s'.", p_td
.name
);
5672 JSON_Tokenizer
tok(va_arg(pvar
, int) != 0);
5673 JSON_encode(p_td
, tok
);
5674 p_buf
.put_s(tok
.get_buffer_length(), (const unsigned char*)tok
.get_buffer());
5677 TTCN_error("Unknown coding method requested to encode type '%s'", p_td
.name
);
5682 void Empty_Record_Type::decode(const TTCN_Typedescriptor_t
& p_td
,
5683 TTCN_Buffer
& p_buf
, TTCN_EncDec::coding_t p_coding
, ...)
5686 va_start(pvar
, p_coding
);
5688 case TTCN_EncDec::CT_BER
: {
5689 TTCN_EncDec_ErrorContext
ec("While BER-decoding type '%s': ", p_td
.name
);
5690 unsigned L_form
=va_arg(pvar
, unsigned);
5692 BER_decode_str2TLV(p_buf
, tlv
, L_form
);
5693 BER_decode_TLV(p_td
, tlv
, L_form
);
5694 if(tlv
.isComplete
) p_buf
.increase_pos(tlv
.get_len());
5696 case TTCN_EncDec::CT_RAW
: {
5697 TTCN_EncDec_ErrorContext
ec("While RAW-decoding type '%s': ", p_td
.name
);
5699 TTCN_EncDec_ErrorContext::error_internal
5700 ("No RAW descriptor available for type '%s'.", p_td
.name
);
5702 switch(p_td
.raw
->top_bit_order
) {
5710 if(RAW_decode(p_td
, p_buf
, p_buf
.get_len()*8, order
)<0)
5711 ec
.error(TTCN_EncDec::ET_INCOMPL_MSG
,
5712 "Can not decode type '%s', because invalid or incomplete"
5713 " message was received", p_td
.name
);
5715 case TTCN_EncDec::CT_TEXT
: {
5716 Limit_Token_List limit
;
5717 TTCN_EncDec_ErrorContext
ec("While TEXT-decoding type '%s': ", p_td
.name
);
5718 if(!p_td
.text
) TTCN_EncDec_ErrorContext::error_internal
5719 ("No TEXT descriptor available for type '%s'.", p_td
.name
);
5720 const unsigned char *b
=p_buf
.get_data();
5721 if(b
[p_buf
.get_len()-1]!='\0'){
5722 p_buf
.set_pos(p_buf
.get_len());
5723 p_buf
.put_zero(8,ORDER_LSB
);
5726 if(TEXT_decode(p_td
,p_buf
,limit
)<0)
5727 ec
.error(TTCN_EncDec::ET_INCOMPL_MSG
,
5728 "Can not decode type '%s', because invalid or incomplete"
5729 " message was received", p_td
.name
);
5731 case TTCN_EncDec::CT_XER
: {
5732 TTCN_EncDec_ErrorContext
ec("While XER-decoding type '%s': ", p_td
.name
);
5733 unsigned XER_coding
=va_arg(pvar
, unsigned);
5734 XmlReaderWrap
reader(p_buf
);
5735 for (int success
=reader
.Read(); success
==1; success
=reader
.Read()) {
5736 if (reader
.NodeType() == XML_READER_TYPE_ELEMENT
) break;
5738 XER_decode(*(p_td
.xer
), reader
, XER_coding
| XER_TOPLEVEL
, 0);
5739 size_t bytes
= reader
.ByteConsumed();
5740 p_buf
.set_pos(bytes
);
5742 case TTCN_EncDec::CT_JSON
: {
5743 TTCN_EncDec_ErrorContext
ec("While JSON-decoding type '%s': ", p_td
.name
);
5744 if(!p_td
.json
) TTCN_EncDec_ErrorContext::error_internal
5745 ("No JSON descriptor available for type '%s'.", p_td
.name
);
5746 JSON_Tokenizer
tok((const char*)p_buf
.get_data(), p_buf
.get_len());
5747 if(JSON_decode(p_td
, tok
, false)<0)
5748 ec
.error(TTCN_EncDec::ET_INCOMPL_MSG
,
5749 "Can not decode type '%s', because invalid or incomplete"
5750 " message was received", p_td
.name
);
5751 p_buf
.set_pos(tok
.get_buf_pos());
5754 TTCN_error("Unknown coding method requested to decode type '%s'", p_td
.name
);
5759 ASN_BER_TLV_t
* Empty_Record_Type::BER_encode_TLV(const TTCN_Typedescriptor_t
& p_td
,
5760 unsigned p_coding
) const
5762 BER_chk_descr(p_td
);
5763 ASN_BER_TLV_t
*new_tlv
=ASN_BER_TLV_t::construct(NULL
);
5764 new_tlv
=ASN_BER_V2TLV(new_tlv
, p_td
, p_coding
);
5768 boolean
Empty_Record_Type::BER_decode_TLV(const TTCN_Typedescriptor_t
& p_td
,
5769 const ASN_BER_TLV_t
& p_tlv
, unsigned L_form
)
5771 BER_chk_descr(p_td
);
5772 ASN_BER_TLV_t stripped_tlv
;
5773 BER_decode_strip_tags(*p_td
.ber
, p_tlv
, L_form
, stripped_tlv
);
5774 TTCN_EncDec_ErrorContext
ec_0("While decoding '%s' type: ", get_descriptor()->name
);
5775 stripped_tlv
.chk_constructed_flag(TRUE
);
5780 int Empty_Record_Type::RAW_encode(const TTCN_Typedescriptor_t
& p_td
,
5781 RAW_enc_tree
& /*myleaf*/) const
5783 if (!bound_flag
) TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND
,
5784 "Encoding an unbound value of type %s.", p_td
.name
);
5788 int Empty_Record_Type::RAW_decode(const TTCN_Typedescriptor_t
& p_td
,
5789 TTCN_Buffer
& buff
, int /*limit*/, raw_order_t
/*top_bit_ord*/,
5790 boolean
/*no_err*/, int /*sel_field*/, boolean
/*first_call*/)
5793 return buff
.increase_pos_padd(p_td
.raw
->prepadding
)
5794 + buff
.increase_pos_padd(p_td
.raw
->padding
);
5797 int Empty_Record_Type::TEXT_encode(const TTCN_Typedescriptor_t
& p_td
, TTCN_Buffer
& buff
) const
5799 int encoded_length
=0;
5800 if(p_td
.text
->begin_encode
) {
5801 buff
.put_cs(*p_td
.text
->begin_encode
);
5802 encoded_length
+=p_td
.text
->begin_encode
->lengthof();
5805 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND
, "Encoding an unbound value.");
5807 if(p_td
.text
->end_encode
) {
5808 buff
.put_cs(*p_td
.text
->end_encode
);
5809 encoded_length
+=p_td
.text
->end_encode
->lengthof();
5811 return encoded_length
;
5814 int Empty_Record_Type::TEXT_decode(const TTCN_Typedescriptor_t
& p_td
,
5815 TTCN_Buffer
& buff
, Limit_Token_List
& /*limit*/, boolean no_err
, boolean
/*first_call*/)
5817 int decoded_length
=0;
5818 if(p_td
.text
->begin_decode
) {
5820 if((tl
=p_td
.text
->begin_decode
->match_begin(buff
))<0) {
5821 if(no_err
)return -1;
5822 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR
,
5823 "The specified token '%s' not found for '%s': ",
5824 (const char*)*(p_td
.text
->begin_decode
), p_td
.name
);
5828 buff
.increase_pos(tl
);
5830 if(p_td
.text
->end_decode
) {
5832 if((tl
=p_td
.text
->end_decode
->match_begin(buff
))<0) {
5833 if(no_err
)return -1;
5834 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR
,
5835 "The specified token '%s' not found for '%s': ",
5836 (const char*)*(p_td
.text
->end_decode
), p_td
.name
);
5840 buff
.increase_pos(tl
);
5843 return decoded_length
;
5846 int Empty_Record_Type::XER_encode(const XERdescriptor_t
& p_td
,
5847 TTCN_Buffer
& p_buf
, unsigned int flavor
, int indent
, embed_values_enc_struct_t
*) const
5849 int encoded_length
=(int)p_buf
.get_len();
5850 int indenting
= !is_canonical(flavor
);
5851 int exer
= is_exer(flavor
);
5852 if (indenting
) do_indent(p_buf
, indent
);
5854 if (exer
) write_ns_prefix(p_td
, p_buf
);
5855 p_buf
.put_s((size_t)p_td
.namelens
[exer
]-2, (cbyte
*)p_td
.names
[exer
]);
5856 p_buf
.put_s(2 + indenting
, (cbyte
*)"/>\n");
5857 return (int)p_buf
.get_len() - encoded_length
;
5860 int Empty_Record_Type::XER_decode(const XERdescriptor_t
& p_td
,
5861 XmlReaderWrap
& reader
, unsigned int flavor
, embed_values_dec_struct_t
*)
5863 int exer
= is_exer(flavor
);
5865 int success
, depth
= -1;
5866 for (success
=reader
.Ok(); success
==1; success
=reader
.Read()) {
5867 int type
= reader
.NodeType();
5868 if (type
==XML_READER_TYPE_ELEMENT
) {
5869 verify_name(reader
, p_td
, exer
);
5870 depth
= reader
.Depth();
5872 if (reader
.IsEmptyElement()) {
5873 reader
.Read(); break;
5875 else if ((flavor
& XER_MASK
) == XER_CANONICAL
) {
5876 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG
,
5877 "Expected an empty element tag");
5878 // Stay in the loop and look for the end element, in case the error
5879 // was ignored or reduced to warning.
5882 else if (type
== XML_READER_TYPE_END_ELEMENT
&& depth
!= -1) {
5883 verify_end(reader
, p_td
, depth
, exer
);
5888 return 1; // decode successful
5891 int Empty_Record_Type::JSON_encode(const TTCN_Typedescriptor_t
&, JSON_Tokenizer
& p_tok
) const
5894 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND
,
5895 "Encoding an unbound empty %s value.", is_set() ? "set" : "record");
5899 return p_tok
.put_next_token(JSON_TOKEN_OBJECT_START
, NULL
) +
5900 p_tok
.put_next_token(JSON_TOKEN_OBJECT_END
, NULL
);
5903 int Empty_Record_Type::JSON_decode(const TTCN_Typedescriptor_t
&, JSON_Tokenizer
& p_tok
, boolean p_silent
)
5905 json_token_t token
= JSON_TOKEN_NONE
;
5906 int dec_len
= p_tok
.get_next_token(&token
, NULL
, NULL
);
5907 if (JSON_TOKEN_ERROR
== token
) {
5908 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG
, JSON_DEC_BAD_TOKEN_ERROR
, "");
5909 return JSON_ERROR_FATAL
;
5911 else if (JSON_TOKEN_OBJECT_START
!= token
) {
5912 return JSON_ERROR_INVALID_TOKEN
;
5915 dec_len
+= p_tok
.get_next_token(&token
, NULL
, NULL
);
5916 if (JSON_TOKEN_OBJECT_END
!= token
) {
5917 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG
, JSON_DEC_STATIC_OBJECT_END_TOKEN_ERROR
, "");
5918 return JSON_ERROR_FATAL
;
5926 boolean
operator==(null_type
/*null_value*/, const Empty_Record_Type
& other_value
)
5928 if (!other_value
.is_bound())
5929 TTCN_error("Comparison of an unbound value of type %s.",
5930 other_value
.get_descriptor()->name
);
5934 boolean
operator!=(null_type
/*null_value*/, const Empty_Record_Type
& other_value
)
5936 if (!other_value
.is_bound())
5937 TTCN_error("Comparison of an unbound value of type %s.",
5938 other_value
.get_descriptor()->name
);