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
= p_td
.oftype_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
,*p_td
.oftype_descr
,buff
);
947 encoded_length
+= get_at(a
)->TEXT_encode(*p_td
.oftype_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(*p_td
.oftype_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(*p_td
.oftype_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
, *p_td
.oftype_descr
, p_coding
));
1161 new_tlv
->add_TLV(get_at(elem_i
)->BER_encode_TLV(
1162 *p_td
.oftype_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(*p_td
.oftype_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
= *p_td
.oftype_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;
1254 start_of_field
= buff
.get_pos_bit();
1255 Base_Type
* field_bt
= get_at(a
); // non-const, extend the record-of
1256 decoded_field_length
= field_bt
->RAW_decode(elem_descr
, buff
, limit
,
1258 if (decoded_field_length
< 0) { // decoding failed, shorten the record-of
1259 set_size(get_nof_elements() - 1);
1260 buff
.set_pos_bit(start_of_field
);
1261 if (a
> start_field
) {
1264 else return decoded_field_length
;
1266 decoded_length
+= decoded_field_length
;
1267 limit
-= decoded_field_length
;
1269 if (EXT_BIT_NO
!= p_td
.raw
->extension_bit
) {
1270 // (EXT_BIT_YES != p_td.raw->extension_bit) is 0 or 1
1271 // This is the opposite value of what the bit needs to be to signal
1272 // the end of decoding, because x-or is the equivalent of !=
1273 if ((EXT_BIT_YES
!= p_td
.raw
->extension_bit
) ^ buff
.get_last_bit()) {
1280 return decoded_length
+ buff
.increase_pos_padd(p_td
.raw
->padding
) + prepaddlength
;
1283 int Record_Of_Type::RAW_encode(const TTCN_Typedescriptor_t
& p_td
, RAW_enc_tree
& myleaf
) const
1285 if (err_descr
) return RAW_encode_negtest(err_descr
, p_td
, myleaf
);
1286 int encoded_length
= 0;
1287 int nof_elements
= get_nof_elements();
1288 int encoded_num_of_records
=
1289 p_td
.raw
->fieldlength
? (nof_elements
< p_td
.raw
->fieldlength
? nof_elements
: p_td
.raw
->fieldlength
)
1291 myleaf
.isleaf
= FALSE
;
1292 myleaf
.rec_of
= TRUE
;
1293 myleaf
.body
.node
.num_of_nodes
= encoded_num_of_records
;
1294 myleaf
.body
.node
.nodes
= init_nodes_of_enc_tree(encoded_num_of_records
);
1295 TTCN_Typedescriptor_t
const& elem_descr
= *p_td
.oftype_descr
;
1296 for (int a
= 0; a
< encoded_num_of_records
; a
++) {
1297 const Base_Type
*field_bt
= get_at(a
);
1298 myleaf
.body
.node
.nodes
[a
] = new RAW_enc_tree(TRUE
, &myleaf
, &(myleaf
.curr_pos
), a
, elem_descr
.raw
);
1299 encoded_length
+= field_bt
->RAW_encode(elem_descr
, *myleaf
.body
.node
.nodes
[a
]);
1301 return myleaf
.length
= encoded_length
;
1304 int Record_Of_Type::RAW_encode_negtest(const Erroneous_descriptor_t
*p_err_descr
,
1305 const TTCN_Typedescriptor_t
& p_td
, RAW_enc_tree
& myleaf
) const
1309 int nof_elements
= get_nof_elements();
1310 // It can be more, of course...
1311 int encoded_num_of_records
=
1312 p_td
.raw
->fieldlength
? (nof_elements
< p_td
.raw
->fieldlength
? nof_elements
: p_td
.raw
->fieldlength
)
1314 for (int i
= 0; i
< nof_elements
; ++i
) {
1315 if ((p_err_descr
->omit_before
!= -1) && (i
< p_err_descr
->omit_before
)) {
1316 --encoded_num_of_records
;
1319 const Erroneous_values_t
*err_vals
=
1320 p_err_descr
->next_field_err_values(i
, values_idx
);
1321 // Not checking any further, `internal error' will be given anyway in the
1322 // next round. Please note that elements can be removed, `omitted'.
1323 if (err_vals
&& err_vals
->before
)
1324 ++encoded_num_of_records
;
1325 if (err_vals
&& err_vals
->value
&& !err_vals
->value
->errval
)
1326 --encoded_num_of_records
;
1327 if (err_vals
&& err_vals
->after
)
1328 ++encoded_num_of_records
;
1329 if ((p_err_descr
->omit_after
!= -1) && (i
>= p_err_descr
->omit_after
)) {
1330 encoded_num_of_records
= encoded_num_of_records
- (nof_elements
- i
) + 1;
1334 myleaf
.body
.node
.num_of_nodes
= encoded_num_of_records
;
1335 myleaf
.body
.node
.nodes
= init_nodes_of_enc_tree(encoded_num_of_records
);
1336 int encoded_length
= 0;
1337 myleaf
.isleaf
= FALSE
;
1338 myleaf
.rec_of
= TRUE
;
1341 for (int i
= 0; i
< nof_elements
; ++i
) {
1342 if ((p_err_descr
->omit_before
!= -1) && (i
< p_err_descr
->omit_before
))
1344 const Erroneous_values_t
*err_vals
= p_err_descr
->next_field_err_values(i
, values_idx
);
1345 const Erroneous_descriptor_t
*emb_descr
= p_err_descr
->next_field_emb_descr(i
, edescr_idx
);
1346 TTCN_Typedescriptor_t
const& elem_descr
= *p_td
.oftype_descr
;
1347 if (err_vals
&& err_vals
->before
) {
1348 if (err_vals
->before
->errval
== NULL
)
1349 TTCN_error("internal error: erroneous before value missing");
1350 if (err_vals
->before
->raw
) {
1351 myleaf
.body
.node
.nodes
[node_pos
] = new RAW_enc_tree(true, &myleaf
,
1352 &(myleaf
.curr_pos
), node_pos
,
1353 err_vals
->before
->errval
->get_descriptor()->raw
);
1354 encoded_length
+= err_vals
->before
->errval
->
1355 RAW_encode_negtest_raw(*myleaf
.body
.node
.nodes
[node_pos
++]);
1357 if (err_vals
->before
->type_descr
== NULL
)
1358 TTCN_error("internal error: erroneous before typedescriptor missing");
1359 myleaf
.body
.node
.nodes
[node_pos
] = new RAW_enc_tree(TRUE
, &myleaf
,
1360 &(myleaf
.curr_pos
), node_pos
, elem_descr
.raw
);
1361 encoded_length
+= err_vals
->before
->errval
->
1362 RAW_encode(*(err_vals
->before
->type_descr
),
1363 *myleaf
.body
.node
.nodes
[node_pos
++]);
1366 if (err_vals
&& err_vals
->value
) {
1367 if (err_vals
->value
->errval
) {
1368 if (err_vals
->value
->raw
) {
1369 myleaf
.body
.node
.nodes
[node_pos
] = new RAW_enc_tree(true, &myleaf
,
1370 &(myleaf
.curr_pos
), node_pos
,
1371 err_vals
->value
->errval
->get_descriptor()->raw
);
1372 encoded_length
+= err_vals
->value
->errval
->
1373 RAW_encode_negtest_raw(*myleaf
.body
.node
.nodes
[node_pos
++]);
1375 if (err_vals
->value
->type_descr
== NULL
)
1376 TTCN_error("internal error: erroneous value typedescriptor missing");
1377 myleaf
.body
.node
.nodes
[node_pos
] = new RAW_enc_tree(TRUE
, &myleaf
,
1378 &(myleaf
.curr_pos
), node_pos
, elem_descr
.raw
);
1379 encoded_length
+= err_vals
->value
->errval
->
1380 RAW_encode(*(err_vals
->value
->type_descr
),
1381 *myleaf
.body
.node
.nodes
[node_pos
++]);
1386 myleaf
.body
.node
.nodes
[node_pos
] = new RAW_enc_tree(TRUE
, &myleaf
,
1387 &(myleaf
.curr_pos
), node_pos
, elem_descr
.raw
);
1388 encoded_length
+= get_at(i
)->RAW_encode_negtest(emb_descr
,
1389 *p_td
.oftype_descr
, *myleaf
.body
.node
.nodes
[node_pos
++]);
1391 myleaf
.body
.node
.nodes
[node_pos
] = new RAW_enc_tree(TRUE
, &myleaf
,
1392 &(myleaf
.curr_pos
), node_pos
, elem_descr
.raw
);
1393 encoded_length
+= get_at(i
)->RAW_encode(*p_td
.oftype_descr
,
1394 *myleaf
.body
.node
.nodes
[node_pos
++]);
1397 if (err_vals
&& err_vals
->after
) {
1398 if (err_vals
->after
->errval
== NULL
)
1399 TTCN_error("internal error: erroneous after value missing");
1400 if (err_vals
->after
->raw
) {
1401 myleaf
.body
.node
.nodes
[node_pos
] = new RAW_enc_tree(true, &myleaf
,
1402 &(myleaf
.curr_pos
), node_pos
,
1403 err_vals
->after
->errval
->get_descriptor()->raw
);
1404 encoded_length
+= err_vals
->after
->errval
->
1405 RAW_encode_negtest_raw(*myleaf
.body
.node
.nodes
[node_pos
++]);
1407 if (err_vals
->after
->type_descr
== NULL
)
1408 TTCN_error("internal error: erroneous after typedescriptor missing");
1409 myleaf
.body
.node
.nodes
[node_pos
] = new RAW_enc_tree(TRUE
, &myleaf
,
1410 &(myleaf
.curr_pos
), node_pos
, elem_descr
.raw
);
1411 encoded_length
+= err_vals
->after
->errval
->
1412 RAW_encode(*(err_vals
->after
->type_descr
),
1413 *myleaf
.body
.node
.nodes
[node_pos
++]);
1416 if ((p_err_descr
->omit_after
!= -1) && (i
>= p_err_descr
->omit_after
))
1419 return myleaf
.length
= encoded_length
;
1422 int Record_Of_Type::JSON_encode(const TTCN_Typedescriptor_t
& p_td
, JSON_Tokenizer
& p_tok
) const
1425 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND
,
1426 "Encoding an unbound %s of value.", is_set() ? "set" : "record");
1430 int enc_len
= p_tok
.put_next_token(JSON_TOKEN_ARRAY_START
, NULL
);
1432 for(int i
= 0; i
< get_nof_elements(); ++i
) {
1433 int ret_val
= get_at(i
)->JSON_encode(*p_td
.oftype_descr
, p_tok
);
1434 if (0 > ret_val
) break;
1438 enc_len
+= p_tok
.put_next_token(JSON_TOKEN_ARRAY_END
, NULL
);
1442 int Record_Of_Type::JSON_decode(const TTCN_Typedescriptor_t
& p_td
, JSON_Tokenizer
& p_tok
, boolean p_silent
)
1444 json_token_t token
= JSON_TOKEN_NONE
;
1445 int dec_len
= p_tok
.get_next_token(&token
, NULL
, NULL
);
1446 if (JSON_TOKEN_ERROR
== token
) {
1447 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG
, JSON_DEC_BAD_TOKEN_ERROR
, "");
1448 return JSON_ERROR_FATAL
;
1450 else if (JSON_TOKEN_ARRAY_START
!= token
) {
1451 return JSON_ERROR_INVALID_TOKEN
;
1456 // Read value tokens until we reach some other token
1457 size_t buf_pos
= p_tok
.get_buf_pos();
1458 Base_Type
* val
= create_elem();
1459 int ret_val
= val
->JSON_decode(*p_td
.oftype_descr
, p_tok
, p_silent
);
1460 if (JSON_ERROR_INVALID_TOKEN
== ret_val
) {
1461 // undo the last action on the buffer
1462 p_tok
.set_buf_pos(buf_pos
);
1466 else if (JSON_ERROR_FATAL
== ret_val
) {
1471 return JSON_ERROR_FATAL
;
1473 if (NULL
== refd_ind_ptr
) {
1474 val_ptr
->value_elements
= (Base_Type
**)reallocate_pointers(
1475 (void**)val_ptr
->value_elements
, val_ptr
->n_elements
, val_ptr
->n_elements
+ 1);
1476 val_ptr
->value_elements
[val_ptr
->n_elements
] = val
;
1477 val_ptr
->n_elements
++;
1480 get_at(get_nof_elements())->set_value(val
);
1486 dec_len
+= p_tok
.get_next_token(&token
, NULL
, NULL
);
1487 if (JSON_TOKEN_ARRAY_END
!= token
) {
1488 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG
, JSON_DEC_REC_OF_END_TOKEN_ERROR
, "");
1492 return JSON_ERROR_FATAL
;
1498 void Record_Of_Type::encode(const TTCN_Typedescriptor_t
& p_td
,
1499 TTCN_Buffer
& p_buf
, TTCN_EncDec::coding_t p_coding
, ...) const
1502 va_start(pvar
, p_coding
);
1504 case TTCN_EncDec::CT_BER
: {
1505 TTCN_EncDec_ErrorContext
ec("While BER-encoding type '%s': ", p_td
.name
);
1506 unsigned BER_coding
=va_arg(pvar
, unsigned);
1507 BER_encode_chk_coding(BER_coding
);
1508 ASN_BER_TLV_t
*tlv
=BER_encode_TLV(p_td
, BER_coding
);
1509 tlv
->put_in_buffer(p_buf
);
1510 ASN_BER_TLV_t::destruct(tlv
);
1512 case TTCN_EncDec::CT_RAW
: {
1513 TTCN_EncDec_ErrorContext
ec("While RAW-encoding type '%s': ", p_td
.name
);
1515 TTCN_EncDec_ErrorContext::error_internal("No RAW descriptor available for type '%s'.", p_td
.name
);
1519 RAW_enc_tree
root(FALSE
, NULL
, &rp
, 1, p_td
.raw
);
1520 RAW_encode(p_td
, root
);
1521 root
.put_to_buf(p_buf
);
1523 case TTCN_EncDec::CT_TEXT
: {
1524 TTCN_EncDec_ErrorContext
ec("While TEXT-encoding type '%s': ", p_td
.name
);
1525 if(!p_td
.text
) TTCN_EncDec_ErrorContext::error_internal
1526 ("No TEXT descriptor available for type '%s'.", p_td
.name
);
1527 TEXT_encode(p_td
,p_buf
);
1529 case TTCN_EncDec::CT_XER
: {
1530 TTCN_EncDec_ErrorContext
ec("While XER-encoding type '%s': ", p_td
.name
);
1531 unsigned XER_coding
=va_arg(pvar
, unsigned);
1532 XER_encode(*(p_td
.xer
),p_buf
, XER_coding
, 0, 0);
1535 case TTCN_EncDec::CT_JSON
: {
1536 TTCN_EncDec_ErrorContext
ec("While JSON-encoding type '%s': ", p_td
.name
);
1537 if(!p_td
.json
) TTCN_EncDec_ErrorContext::error_internal
1538 ("No JSON descriptor available for type '%s'.", p_td
.name
);
1539 JSON_Tokenizer
tok(va_arg(pvar
, int) != 0);
1540 JSON_encode(p_td
, tok
);
1541 p_buf
.put_s(tok
.get_buffer_length(), (const unsigned char*)tok
.get_buffer());
1544 TTCN_error("Unknown coding method requested to encode type '%s'", p_td
.name
);
1549 void Record_Of_Type::decode(const TTCN_Typedescriptor_t
& p_td
,
1550 TTCN_Buffer
& p_buf
, TTCN_EncDec::coding_t p_coding
, ...)
1553 va_start(pvar
, p_coding
);
1555 case TTCN_EncDec::CT_BER
: {
1556 TTCN_EncDec_ErrorContext
ec("While BER-decoding type '%s': ", p_td
.name
);
1557 unsigned L_form
=va_arg(pvar
, unsigned);
1559 BER_decode_str2TLV(p_buf
, tlv
, L_form
);
1560 BER_decode_TLV(p_td
, tlv
, L_form
);
1561 if(tlv
.isComplete
) p_buf
.increase_pos(tlv
.get_len());
1563 case TTCN_EncDec::CT_RAW
: {
1564 TTCN_EncDec_ErrorContext
ec("While RAW-decoding type '%s': ", p_td
.name
);
1565 if(!p_td
.raw
) TTCN_EncDec_ErrorContext::error_internal
1566 ("No RAW descriptor available for type '%s'.", p_td
.name
);
1568 switch(p_td
.raw
->top_bit_order
) {
1576 if(RAW_decode(p_td
, p_buf
, p_buf
.get_len()*8, order
)<0)
1577 ec
.error(TTCN_EncDec::ET_INCOMPL_MSG
,"Can not decode type '%s', "
1578 "because invalid or incomplete message was received", p_td
.name
);
1580 case TTCN_EncDec::CT_TEXT
: {
1581 Limit_Token_List limit
;
1582 TTCN_EncDec_ErrorContext
ec("While TEXT-decoding type '%s': ", p_td
.name
);
1583 if(!p_td
.text
) TTCN_EncDec_ErrorContext::error_internal
1584 ("No TEXT descriptor available for type '%s'.", p_td
.name
);
1585 const unsigned char *b
=p_buf
.get_data();
1586 if(b
[p_buf
.get_len()-1]!='\0'){
1587 p_buf
.set_pos(p_buf
.get_len());
1588 p_buf
.put_zero(8,ORDER_LSB
);
1591 if(TEXT_decode(p_td
,p_buf
,limit
)<0)
1592 ec
.error(TTCN_EncDec::ET_INCOMPL_MSG
,"Can not decode type '%s', "
1593 "because invalid or incomplete message was received", p_td
.name
);
1595 case TTCN_EncDec::CT_XER
: {
1596 TTCN_EncDec_ErrorContext
ec("While XER-decoding type '%s': ", p_td
.name
);
1597 unsigned XER_coding
=va_arg(pvar
, unsigned);
1598 XmlReaderWrap
reader(p_buf
);
1599 for (int success
=reader
.Read(); success
==1; success
=reader
.Read()) {
1600 if (reader
.NodeType() == XML_READER_TYPE_ELEMENT
) break;
1602 XER_decode(*(p_td
.xer
), reader
, XER_coding
| XER_TOPLEVEL
, 0);
1603 size_t bytes
= reader
.ByteConsumed();
1604 p_buf
.set_pos(bytes
);
1606 case TTCN_EncDec::CT_JSON
: {
1607 TTCN_EncDec_ErrorContext
ec("While JSON-decoding type '%s': ", p_td
.name
);
1608 if(!p_td
.json
) TTCN_EncDec_ErrorContext::error_internal
1609 ("No JSON descriptor available for type '%s'.", p_td
.name
);
1610 JSON_Tokenizer
tok((const char*)p_buf
.get_data(), p_buf
.get_len());
1611 if(JSON_decode(p_td
, tok
, false)<0)
1612 ec
.error(TTCN_EncDec::ET_INCOMPL_MSG
,"Can not decode type '%s', "
1613 "because invalid or incomplete message was received", p_td
.name
);
1614 p_buf
.set_pos(tok
.get_buf_pos());
1617 TTCN_error("Unknown coding method requested to decode type '%s'", p_td
.name
);
1622 char **Record_Of_Type::collect_ns(const XERdescriptor_t
& p_td
, size_t& num
, bool& def_ns
) const
1624 size_t num_collected
= 0;
1625 // First, our own namespace. Sets num_collected to 0 or 1.
1626 // If it throws, nothing was allocated.
1627 char **collected_ns
= Base_Type::collect_ns(p_td
, num_collected
, def_ns
);
1629 // Then the embedded type
1631 bool def_ns_1
= false;
1632 if (val_ptr
) for (int i
= 0; i
< get_nof_elements(); ++i
) {
1634 char **new_namespaces
= get_at(i
)->collect_ns(
1635 *p_td
.oftype_descr
, num_new
, def_ns_1
);
1636 merge_ns(collected_ns
, num_collected
, new_namespaces
, num_new
);
1637 def_ns
= def_ns
|| def_ns_1
; // alas, no ||=
1641 // Probably a TC_Error thrown from the element's collect_ns(),
1642 // e.g. if encoding an unbound value.
1643 while (num_collected
> 0) Free(collected_ns
[--num_collected
]);
1648 num
= num_collected
;
1649 return collected_ns
;
1652 static const universal_char sp
= { 0,0,0,' ' };
1653 static const universal_char tb
= { 0,0,0,9 };
1655 int Record_Of_Type::XER_encode(const XERdescriptor_t
& p_td
, TTCN_Buffer
& p_buf
,
1656 unsigned int flavor
, int indent
, embed_values_enc_struct_t
* emb_val
) const
1659 return XER_encode_negtest(err_descr
, p_td
, p_buf
, flavor
, indent
, emb_val
);
1662 if (val_ptr
== 0) TTCN_error(
1663 "Attempt to XER-encode an unbound record of type %s", get_descriptor()->name
);
1664 int encoded_length
= (int)p_buf
.get_len();
1666 const int exer
= is_exer(flavor
);
1667 const boolean own_tag
=
1668 !(exer
&& indent
&& (p_td
.xer_bits
& (ANY_ELEMENT
|ANY_ATTRIBUTES
|UNTAGGED
)));
1670 const int indenting
= !is_canonical(flavor
) && own_tag
;
1671 const boolean xmlValueList
= isXmlValueList();
1674 | ( (exer
&& (p_td
.xer_bits
& XER_LIST
))
1675 || is_exerlist(flavor
) ? SIMPLE_TYPE
: 0);
1676 flavor
&= ~XER_RECOF
; // record-of doesn't care
1677 int nof_elements
= get_nof_elements();
1678 Base_Type::begin_xml(p_td
, p_buf
, flavor
, indent
, !nof_elements
,
1679 (collector_fn
)&Record_Of_Type::collect_ns
);
1681 if (xmlValueList
&& nof_elements
&& indenting
&& !exer
) { /* !exer or GDMO */
1682 do_indent(p_buf
, indent
+1);
1685 if (exer
&& (p_td
.xer_bits
& ANY_ATTRIBUTES
)) {
1686 // Back up over the '>' and the '\n' that may follow it
1687 size_t buf_len
= p_buf
.get_len(), shorter
= 0;
1688 const unsigned char * const buf_data
= p_buf
.get_data();
1689 if (buf_data
[buf_len
- 1 - shorter
] == '\n') ++shorter
;
1690 if (buf_data
[buf_len
- 1 - shorter
] == '>' ) ++shorter
;
1692 unsigned char saved
[4];
1694 memcpy(saved
, buf_data
+ (buf_len
- shorter
), shorter
);
1695 p_buf
.increase_length(-shorter
);
1698 // ANY_ATTRIBUTES means it's a record of universal charstring.
1699 // They are in AnyAttributeFormat (X.693/2008 18.2.6):
1700 // "URI(optional), space, NCName, equals, \"xmlcstring\""
1701 // They need to be written as an XML attribute and namespace declaration:
1702 // xmlns:b0="URI" b0:NCName="xmlcstring"
1704 for (int i
= 0; i
< nof_elements
; ++i
) {
1705 TTCN_EncDec_ErrorContext
ec_0("Attribute %d: ", i
);
1706 if (!is_elem_bound(i
)) {
1707 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND
,
1708 "Encoding an unbound universal charstring value.");
1711 const UNIVERSAL_CHARSTRING
*elem
1712 = static_cast<const UNIVERSAL_CHARSTRING
*>(val_ptr
->value_elements
[i
]);
1713 size_t len
= elem
->lengthof();
1715 const UNIVERSAL_CHARSTRING_ELEMENT
& ue
= (*elem
)[len
- 1];
1716 if (sp
== ue
|| tb
== ue
) --len
;
1719 // sp_at: indexes the first space
1720 // j is left to point at where the attribute name begins (just past the space)
1721 size_t j
, sp_at
= 0;
1722 for (j
= 0; j
< len
; j
++) {
1723 const UNIVERSAL_CHARSTRING_ELEMENT
& ue
= (*elem
)[j
];
1724 if (sp_at
) { // already found a space
1725 if (sp
== ue
|| tb
== ue
) {} // another space, do nothing
1726 else break; // found a non-space after a space
1729 if (sp
== ue
|| tb
== ue
) sp_at
= j
;
1733 size_t buf_start
= p_buf
.get_len();
1735 char * ns
= mprintf(" xmlns:b%d='", i
);
1736 size_t ns_len
= mstrlen(ns
);
1737 p_buf
.put_s(ns_len
, (cbyte
*)ns
);
1739 UNIVERSAL_CHARSTRING
before(sp_at
, (const universal_char
*)(*elem
));
1740 if (p_td
.xer_bits
& (ANY_FROM
| ANY_EXCEPT
)) {
1741 // Ensure the namespace abides to its restrictions
1743 before
.encode_utf8(ns_buf
);
1745 ns_buf
.get_string(cs
);
1746 check_namespace_restrictions(p_td
, (const char*)cs
);
1748 before
.XER_encode(UNIVERSAL_CHARSTRING_xer_
, p_buf
,
1749 flavor
| ANY_ATTRIBUTES
, indent
, 0);
1754 // Keep just the "b%d" part from ns
1755 p_buf
.put_s(ns_len
- 9, (cbyte
*)ns
+ 7);
1763 if (p_td
.xer_bits
& (ANY_FROM
| ANY_EXCEPT
)) {
1764 // Make sure the unqualified namespace is allowed
1765 check_namespace_restrictions(p_td
, NULL
);
1769 UNIVERSAL_CHARSTRING
after(len
- j
, (const universal_char
*)(*elem
) + j
);
1770 after
.XER_encode(UNIVERSAL_CHARSTRING_xer_
, p_buf
,
1771 flavor
| ANY_ATTRIBUTES
, indent
, 0);
1773 // Put this attribute in a dummy element and walk through it to check its validity
1774 TTCN_Buffer check_buf
;
1775 check_buf
.put_s(2, (unsigned char*)"<a");
1776 check_buf
.put_s(p_buf
.get_len() - buf_start
, p_buf
.get_data() + buf_start
);
1777 check_buf
.put_s(2, (unsigned char*)"/>");
1778 XmlReaderWrap
checker(check_buf
);
1779 while (1 == checker
.Read());
1782 p_buf
.put_s(shorter
, saved
); // restore the '>' and anything after
1785 else { // not ANY-ATTRIBUTES
1786 unsigned int sub_flavor
= flavor
| XER_RECOF
| (p_td
.xer_bits
& (XER_LIST
));
1787 TTCN_EncDec_ErrorContext
ec_0("Index ");
1788 TTCN_EncDec_ErrorContext ec_1
;
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 ec_1
.set_msg("%d: ", i
);
1798 if (exer
&& (p_td
.xer_bits
& XER_LIST
) && i
>0) p_buf
.put_c(' ');
1799 get_at(i
)->XER_encode(*p_td
.oftype_descr
, p_buf
,
1800 sub_flavor
, indent
+own_tag
, emb_val
);
1803 if (indenting
&& nof_elements
&& !is_exerlist(flavor
)) {
1804 if (xmlValueList
&& !exer
) p_buf
.put_c('\n'); /* !exer or GDMO */
1805 //do_indent(p_buf, indent);
1809 Base_Type::end_xml(p_td
, p_buf
, flavor
, indent
, !nof_elements
);
1810 return (int)p_buf
.get_len() - encoded_length
;
1813 // XERSTUFF Record_Of_Type::encode_element
1814 /** Helper for Record_Of_Type::XER_encode_negtest
1816 * The main purpose of this method is to allow another type to request
1817 * encoding of a single element of the record-of. Used by Record_Type
1818 * to encode individual strings of the EMBED-VALUES member.
1820 * @param i index of the element
1821 * @param ev erroneous descriptor for the element itself
1822 * @param ed deeper erroneous values
1823 * @param p_buf buffer containing the encoded value
1824 * @param sub_flavor flags
1825 * @param indent indentation level
1826 * @return number of bytes generated
1828 int Record_Of_Type::encode_element(int i
, const XERdescriptor_t
& p_td
,
1829 const Erroneous_values_t
* ev
, const Erroneous_descriptor_t
* ed
,
1830 TTCN_Buffer
& p_buf
, unsigned int sub_flavor
, int indent
, embed_values_enc_struct_t
* emb_val
) const
1832 int enc_len
= p_buf
.get_len();
1833 TTCN_EncDec_ErrorContext ec
;
1834 const int exer
= is_exer(sub_flavor
);
1836 if (ev
&& ev
->before
) {
1837 if (ev
->before
->errval
==NULL
) {
1838 TTCN_error("internal error: erroneous before value missing");
1840 ec
.set_msg("Erroneous value before component #%d: ", i
);
1841 if (ev
->before
->raw
) {
1842 ev
->before
->errval
->encode_raw(p_buf
);
1844 if (ev
->before
->type_descr
==NULL
) TTCN_error(
1845 "internal error: erroneous before type descriptor missing");
1846 ev
->before
->errval
->XER_encode(*ev
->before
->type_descr
->xer
,
1847 p_buf
, sub_flavor
, indent
, 0);
1851 if (exer
&& (sub_flavor
& XER_LIST
)
1852 && (i
> 0 || (ev
&& ev
->before
&& !ev
->before
->raw
))){
1853 // Ensure a separator is written after the "erroneous before"
1854 // of the first element (except for "raw before").
1858 if (ev
&& ev
->value
) {
1859 if (ev
->value
->errval
) { // replace
1860 ec
.set_msg("Erroneous value for component #%d: ", i
);
1861 if (ev
->value
->raw
) {
1862 ev
->value
->errval
->encode_raw(p_buf
);
1864 if (ev
->value
->type_descr
==NULL
) TTCN_error(
1865 "internal error: erroneous value type descriptor missing");
1866 ev
->value
->errval
->XER_encode(*ev
->value
->type_descr
->xer
,
1867 p_buf
, sub_flavor
, indent
, 0);
1871 ec
.set_msg("Component #%d: ", i
);
1873 get_at(i
)->XER_encode_negtest(ed
, p_td
, p_buf
, sub_flavor
, indent
, emb_val
);
1875 // the "real" encoder
1876 get_at(i
)->XER_encode(p_td
, p_buf
, sub_flavor
, indent
, emb_val
);
1880 if (ev
&& ev
->after
) {
1881 if (ev
->after
->errval
==NULL
) {
1882 TTCN_error("internal error: erroneous after value missing");
1884 ec
.set_msg("Erroneous value after component #%d: ", i
);
1885 if (ev
->after
->raw
) {
1886 ev
->after
->errval
->encode_raw(p_buf
);
1888 if (ev
->after
->type_descr
==NULL
) TTCN_error(
1889 "internal error: erroneous after type descriptor missing");
1890 ev
->after
->errval
->XER_encode(*ev
->after
->type_descr
->xer
,
1891 p_buf
, sub_flavor
, indent
, 0);
1898 // XERSTUFF Record_Of_Type::XER_encode_negtest
1899 int Record_Of_Type::XER_encode_negtest(const Erroneous_descriptor_t
* p_err_descr
,
1900 const XERdescriptor_t
& p_td
, TTCN_Buffer
& p_buf
, unsigned flavor
, int indent
,
1901 embed_values_enc_struct_t
* emb_val
) const
1903 if (val_ptr
== 0) TTCN_error(
1904 "Attempt to XER-encode an unbound record of type %s", get_descriptor()->name
);
1905 int encoded_length
= (int)p_buf
.get_len();
1907 const int exer
= is_exer(flavor
);
1908 const boolean own_tag
=
1909 !(exer
&& indent
&& (p_td
.xer_bits
& (ANY_ELEMENT
|ANY_ATTRIBUTES
|UNTAGGED
)));
1911 const int indenting
= !is_canonical(flavor
) && own_tag
;
1912 const boolean xmlValueList
= isXmlValueList();
1915 | ( (exer
&& (p_td
.xer_bits
& XER_LIST
))
1916 || is_exerlist(flavor
) ? SIMPLE_TYPE
: 0);
1917 flavor
&= ~XER_RECOF
; // record-of doesn't care
1918 int nof_elements
= get_nof_elements();
1919 Base_Type::begin_xml(p_td
, p_buf
, flavor
, indent
, !nof_elements
,
1920 (collector_fn
)&Record_Of_Type::collect_ns
);
1922 if (xmlValueList
&& nof_elements
&& indenting
&& !exer
) { /* !exer or GDMO */
1923 do_indent(p_buf
, indent
+1);
1928 if (exer
&& (p_td
.xer_bits
& ANY_ATTRIBUTES
)) {
1929 // Back up over the '>' and the '\n' that may follow it
1930 size_t buf_len
= p_buf
.get_len(), shorter
= 0;
1931 const unsigned char * const buf_data
= p_buf
.get_data();
1932 if (buf_data
[buf_len
- 1 - shorter
] == '\n') ++shorter
;
1933 if (buf_data
[buf_len
- 1 - shorter
] == '>' ) ++shorter
;
1935 unsigned char * saved
= 0;
1937 saved
= new unsigned char[shorter
];
1938 memcpy(saved
, buf_data
+ (buf_len
- shorter
), shorter
);
1939 p_buf
.increase_length(-shorter
);
1942 // ANY_ATTRIBUTES means it's a record of universal charstring.
1943 // They are in AnyAttributeFormat (X.693/2008 18.2.6):
1944 // "URI(optional), space, NCName, equals, \"xmlcstring\""
1945 // They need to be written as an XML attribute and namespace declaration:
1946 // xmlns:b0="URI" b0:NCName="xmlcstring"
1948 for (int i
= 0; i
< nof_elements
; ++i
) {
1949 if (i
< p_err_descr
->omit_before
) continue;
1951 const Erroneous_values_t
*ev
= p_err_descr
->next_field_err_values(i
, values_idx
);
1952 const Erroneous_descriptor_t
*ed
= p_err_descr
->next_field_emb_descr(i
, edescr_idx
);
1954 if (ev
&& ev
->before
) {
1955 if (ev
->before
->errval
==NULL
) TTCN_error("internal error: erroneous value missing");
1958 if (ev
->before
->raw
) ev
->before
->errval
->encode_raw(p_buf
);
1960 if (ev
->before
->type_descr
==NULL
) TTCN_error(
1961 "internal error: erroneous before type descriptor missing");
1962 else ev
->before
->errval
->XER_encode(*ev
->before
->type_descr
->xer
,
1963 p_buf
, flavor
, indent
, 0);
1967 if (ev
&& ev
->value
) { //value replacement
1968 if (ev
->value
->errval
) {
1969 if (ev
->value
->raw
) ev
->value
->errval
->encode_raw(p_buf
);
1971 if (ev
->value
->type_descr
==NULL
) TTCN_error(
1972 "internal error: erroneous value type descriptor missing");
1973 else ev
->value
->errval
->XER_encode(*ev
->value
->type_descr
->xer
,
1974 p_buf
, flavor
, indent
, 0);
1980 // embedded descr.. call negtest (except UNIVERSAL_CHARSTRING
1981 // doesn't have XER_encode_negtest)
1982 TTCN_error("internal error: embedded descriptor for scalar");
1985 // the original encoding
1986 const UNIVERSAL_CHARSTRING
*elem
1987 = static_cast<const UNIVERSAL_CHARSTRING
*>(get_at(i
));
1988 size_t len
= elem
->lengthof();
1990 const UNIVERSAL_CHARSTRING_ELEMENT
& ue
= (*elem
)[len
- 1];
1991 if (sp
== ue
|| tb
== ue
) --len
;
1994 // sp_at: indexes the first space
1995 // j is left to point at where the attribute name begins (just past the space)
1996 size_t j
, sp_at
= 0;
1997 for (j
= 0; j
< len
; j
++) {
1998 const UNIVERSAL_CHARSTRING_ELEMENT
& ue
= (*elem
)[j
];
1999 if (sp_at
) { // already found a space
2000 if (sp
== ue
|| tb
== ue
) {} // another space, do nothing
2001 else break; // found a non-space after a space
2004 if (sp
== ue
|| tb
== ue
) sp_at
= j
;
2009 char * ns
= mprintf(" xmlns:b%d='", i
);
2010 size_t ns_len
= mstrlen(ns
);
2011 p_buf
.put_s(ns_len
, (cbyte
*)ns
);
2013 UNIVERSAL_CHARSTRING
before(sp_at
, (const universal_char
*)(*elem
));
2014 before
.XER_encode(UNIVERSAL_CHARSTRING_xer_
, p_buf
,
2015 flavor
| ANY_ATTRIBUTES
, indent
, 0);
2020 // Keep just the "b%d" part from ns
2021 p_buf
.put_s(ns_len
- 9, (cbyte
*)ns
+ 7);
2030 UNIVERSAL_CHARSTRING
after(len
- j
, (const universal_char
*)(*elem
) + j
);
2031 after
.XER_encode(UNIVERSAL_CHARSTRING_xer_
, p_buf
,
2032 flavor
| ANY_ATTRIBUTES
, indent
, 0);
2036 if (ev
&& ev
->after
) {
2037 if (ev
->after
->errval
==NULL
) TTCN_error(
2038 "internal error: erroneous after value missing");
2040 if (ev
->after
->raw
) ev
->after
->errval
->encode_raw(p_buf
);
2042 if (ev
->after
->type_descr
==NULL
) TTCN_error(
2043 "internal error: erroneous after type descriptor missing");
2044 else ev
->after
->errval
->XER_encode(*ev
->after
->type_descr
->xer
,
2045 p_buf
, flavor
, indent
, 0);
2049 // omit_after value -1 becomes "very big"
2050 if ((unsigned int)i
>= (unsigned int)p_err_descr
->omit_after
) break;
2053 p_buf
.put_s(shorter
, saved
); // restore the '>' and anything after
2057 else { // not ANY-ATTRIBUTES
2058 unsigned int sub_flavor
= flavor
| XER_RECOF
| (p_td
.xer_bits
& (XER_LIST
|ANY_ATTRIBUTES
));
2060 TTCN_EncDec_ErrorContext ec
;
2062 for (int i
= 0; i
< nof_elements
; ++i
) {
2063 if (i
< p_err_descr
->omit_before
) continue;
2065 if (0 != emb_val
&& i
> 0 && !own_tag
&&
2066 emb_val
->embval_index
< emb_val
->embval_array
->size_of()) {
2067 const Erroneous_values_t
* ev0_i
= NULL
;
2068 const Erroneous_descriptor_t
* ed0_i
= NULL
;
2069 if (emb_val
->embval_err
) {
2070 ev0_i
= emb_val
->embval_err
->next_field_err_values(emb_val
->embval_index
, emb_val
->embval_err_val_idx
);
2071 ed0_i
= emb_val
->embval_err
->next_field_emb_descr (emb_val
->embval_index
, emb_val
->embval_err_descr_idx
);
2073 emb_val
->embval_array
->encode_element(emb_val
->embval_index
, UNIVERSAL_CHARSTRING_xer_
,
2074 ev0_i
, ed0_i
, p_buf
, flavor
| EMBED_VALUES
, indent
+ own_tag
, 0);
2075 ++emb_val
->embval_index
;
2078 const Erroneous_values_t
* err_vals
=
2079 p_err_descr
->next_field_err_values(i
, values_idx
);
2080 const Erroneous_descriptor_t
* emb_descr
=
2081 p_err_descr
->next_field_emb_descr (i
, edescr_idx
);
2083 encode_element(i
, *p_td
.oftype_descr
, err_vals
, emb_descr
, p_buf
, sub_flavor
, indent
+own_tag
, emb_val
);
2085 // omit_after value -1 becomes "very big"
2086 if ((unsigned int)i
>= (unsigned int)p_err_descr
->omit_after
) break;
2089 if (indenting
&& nof_elements
&& !is_exerlist(flavor
)) {
2090 if (xmlValueList
&& !exer
) p_buf
.put_c('\n'); /* !exer or GDMO */
2091 //do_indent(p_buf, indent);
2095 Base_Type::end_xml(p_td
, p_buf
, flavor
, indent
, !nof_elements
);
2096 return (int)p_buf
.get_len() - encoded_length
;
2099 int Record_Of_Type::XER_decode(const XERdescriptor_t
& p_td
,
2100 XmlReaderWrap
& reader
, unsigned int flavor
, embed_values_dec_struct_t
* emb_val
)
2102 int exer
= is_exer(flavor
);
2103 int xerbits
= p_td
.xer_bits
;
2104 if (flavor
& XER_TOPLEVEL
) xerbits
&= ~UNTAGGED
;
2106 !(exer
&& ((xerbits
& (ANY_ELEMENT
| ANY_ATTRIBUTES
| UNTAGGED
))
2107 || (flavor
& USE_TYPE_ATTR
))); /* incase the parent has USE-UNION */
2108 /* not toplevel anymore and remove the flags for USE-UNION the oftype doesn't need them */
2109 flavor
&= ~XER_TOPLEVEL
& ~XER_LIST
& ~USE_TYPE_ATTR
;
2110 int success
=1, depth
=-1;
2111 set_val(NULL_VALUE
); // empty but initialized array, val_ptr != NULL
2113 if (own_tag
) for (success
= 1; success
== 1; success
= reader
.Read()) {
2114 type
= reader
.NodeType();
2115 if (exer
&& (p_td
.xer_bits
& XER_ATTRIBUTE
)) {
2116 if (XML_READER_TYPE_ATTRIBUTE
== type
) break;
2118 if (exer
&& (p_td
.xer_bits
& XER_LIST
)) {
2119 if (XML_READER_TYPE_TEXT
== type
) break;
2122 if (XML_READER_TYPE_ELEMENT
== type
) {
2123 verify_name(reader
, p_td
, exer
);
2124 depth
= reader
.Depth();
2127 } /* endif(exer && list) */
2129 else depth
= reader
.Depth();
2130 TTCN_EncDec_ErrorContext
ec_0("Index ");
2131 TTCN_EncDec_ErrorContext ec_1
;
2132 flavor
|= XER_RECOF
;
2133 if (exer
&& (p_td
.xer_bits
& ANY_ATTRIBUTES
)) {
2134 // The enclosing type should handle the decoding.
2135 TTCN_error("Incorrect decoding of ANY-ATTRIBUTES");
2137 else if (exer
&& (p_td
.xer_bits
& XER_LIST
)) { /* LIST decoding*/
2138 char *val
= (char*)reader
.NewValue(); /* we own it */
2140 size_t len
= strlen(val
);
2141 /* The string contains a bunch of values separated by whitespace.
2142 * Tokenize the string and create a new buffer which looks like
2143 * an XML element (<ns:name xmlns:ns='uri'>value</ns:name>), then use that
2144 * to decode the value. */
2145 for(char * str
= strtok(val
, " \t\x0A\x0D"); str
!= 0; str
= strtok(val
+ pos
, " \t\x0A\x0D")) {
2146 // Calling strtok with NULL won't work here, since the decoded element can have strtok calls aswell
2147 pos
+= strlen(str
) + 1;
2148 // Construct a new XML Reader with the current token.
2150 const XERdescriptor_t
& sub_xer
= *p_td
.oftype_descr
;
2152 write_ns_prefix(sub_xer
, buf2
);
2154 boolean i_can_has_ns
= sub_xer
.my_module
!= 0 && sub_xer
.ns_index
!= -1;
2155 const char * const exer_name
= sub_xer
.names
[1];
2156 buf2
.put_s((size_t)sub_xer
.namelens
[1]-1-i_can_has_ns
, (cbyte
*)exer_name
);
2158 const namespace_t
* const pns
= sub_xer
.my_module
->get_ns(sub_xer
.ns_index
);
2159 buf2
.put_s(7 - (*pns
->px
== 0), (cbyte
*)" xmlns:");
2160 buf2
.put_s(strlen(pns
->px
), (cbyte
*)pns
->px
);
2161 buf2
.put_s(2, (cbyte
*)"='");
2162 buf2
.put_s(strlen(pns
->ns
), (cbyte
*)pns
->ns
);
2163 buf2
.put_s(2, (cbyte
*)"'>");
2165 // start tag completed
2166 buf2
.put_s(strlen(str
), (cbyte
*)str
);
2170 write_ns_prefix(sub_xer
, buf2
);
2171 buf2
.put_s((size_t)sub_xer
.namelens
[1], (cbyte
*)exer_name
);
2172 XmlReaderWrap
reader2(buf2
);
2173 reader2
.Read(); // Move to the start element.
2174 // Don't move to the #text, that's the callee's responsibility.
2175 ec_1
.set_msg("%d: ", get_nof_elements());
2176 // The call to the non-const operator[], I mean get_at(), creates
2177 // a new element (because it is indexing one past the last element).
2178 // Then we call its XER_decode with the temporary XML reader.
2179 get_at(get_nof_elements())->XER_decode(sub_xer
, reader2
, flavor
, 0);
2180 if (flavor
& EXIT_ON_ERROR
&& !is_elem_bound(get_nof_elements() - 1)) {
2181 if (1 == get_nof_elements()) {
2182 // Failed to decode even the first element
2185 // Some elements were successfully decoded -> only delete the last one
2186 set_size(get_nof_elements() - 1);
2191 if (pos
>= len
) break;
2194 if (p_td
.xer_bits
& XER_ATTRIBUTE
) {
2195 //Let the caller do reader.AdvanceAttribute();
2198 reader
.Read(); // on closing tag
2199 reader
.Read(); // past it
2203 if (flavor
& PARENT_CLOSED
) {
2204 // Nothing to do. We are probably untagged; do not advance in the XML
2205 // because it would move past the parent.
2207 else if (own_tag
&& reader
.IsEmptyElement()) { // Nothing to do
2208 reader
.Read(); // This is our own empty tag, move past it
2211 /* Note: there is no reader.Read() at the end of the loop below.
2212 * Each element is supposed to consume enough to leave the next element
2213 * well-positioned. */
2214 for (success
= own_tag
? reader
.Read() : reader
.Ok(); success
== 1; ) {
2215 type
= reader
.NodeType();
2216 if (XML_READER_TYPE_ELEMENT
== type
)
2218 if (exer
&& (p_td
.xer_bits
& ANY_ELEMENT
)) {
2219 /* This is a (record-of UNIVERSAL_CHARSTRING) with ANY-ELEMENT.
2220 * The ANY-ELEMENT is really meant for the element type,
2221 * so behave like a record-of (string with ANY-ELEMENT):
2222 * call the non-const operator[], I mean get_at(), to create
2223 * a new element, then read the entire XML element into it. */
2224 UNIVERSAL_CHARSTRING
* uc
=
2225 static_cast<UNIVERSAL_CHARSTRING
*>(get_at(val_ptr
->n_elements
));
2226 const xmlChar
* outer
= reader
.ReadOuterXml();
2227 uc
->decode_utf8(strlen((const char*)outer
), outer
);
2228 // consume the element
2229 for (success
= reader
.Read(); success
== 1 && reader
.Depth() > depth
; success
= reader
.Read()) {}
2230 if (reader
.NodeType() != XML_READER_TYPE_ELEMENT
) success
= reader
.Read(); // one last time
2233 /* If this is an untagged record-of and the start element does not
2234 * belong to the embedded type, the record-of has already ended. */
2235 if (!own_tag
&& !can_start_v(
2236 (const char*)reader
.LocalName(), (const char*)reader
.NamespaceUri(),
2237 p_td
, flavor
| UNTAGGED
))
2239 for (; success
== 1 && reader
.Depth() > depth
; success
= reader
.Read()) ;
2240 // We should now be back at the same depth as we started.
2243 ec_1
.set_msg("%d: ", get_nof_elements());
2244 /* The call to the non-const get_at() creates the element */
2245 get_at(get_nof_elements())->XER_decode(*p_td
.oftype_descr
, reader
, flavor
, emb_val
);
2246 if (0 != emb_val
&& !own_tag
&& get_nof_elements() > 1) {
2247 ++emb_val
->embval_index
;
2251 else if (XML_READER_TYPE_END_ELEMENT
== type
) {
2252 for (; success
== 1 && reader
.Depth() > depth
; success
= reader
.Read()) ;
2253 // If the depth just decreased, this must be an end element
2254 // (but a different one from what we had before the loop)
2256 verify_end(reader
, p_td
, depth
, exer
);
2257 reader
.Read(); // move forward one last time
2261 else if (XML_READER_TYPE_TEXT
== type
&& 0 != emb_val
&& !own_tag
&& get_nof_elements() > 0) {
2262 UNIVERSAL_CHARSTRING
emb_ustr((const char*)reader
.Value());
2263 emb_val
->embval_array
->get_at(emb_val
->embval_index
)->set_value(&emb_ustr
);
2264 success
= reader
.Read();
2267 success
= reader
.Read();
2270 } /* if not empty element */
2272 return 1; // decode successful
2275 void Record_Of_Type::set_param(Module_Param
& param
) {
2276 if (dynamic_cast<Module_Param_Name
*>(param
.get_id()) != NULL
&&
2277 param
.get_id()->next_name()) {
2278 // Haven't reached the end of the module parameter name
2279 // => the name refers to one of the elements, not to the whole record of
2280 char* param_field
= param
.get_id()->get_current_name();
2281 if (param_field
[0] < '0' || param_field
[0] > '9') {
2282 param
.error("Unexpected record field name in module parameter, expected a valid"
2283 " index for %s type `%s'", is_set() ? "set of" : "record of", get_descriptor()->name
);
2285 int param_index
= -1;
2286 sscanf(param_field
, "%d", ¶m_index
);
2287 get_at(param_index
)->set_param(param
);
2291 param
.basic_check(Module_Param::BC_VALUE
|Module_Param::BC_LIST
, is_set()?"set of value":"record of value");
2292 switch (param
.get_operation_type()) {
2293 case Module_Param::OT_ASSIGN
:
2294 if (param
.get_type()==Module_Param::MP_Value_List
&& param
.get_size()==0) {
2295 set_val(NULL_VALUE
);
2298 switch (param
.get_type()) {
2299 case Module_Param::MP_Value_List
:
2300 set_size(param
.get_size());
2301 for (size_t i
=0; i
<param
.get_size(); ++i
) {
2302 Module_Param
* const curr
= param
.get_elem(i
);
2303 if (curr
->get_type()!=Module_Param::MP_NotUsed
) {
2304 get_at(i
)->set_param(*curr
);
2308 case Module_Param::MP_Indexed_List
:
2309 for (size_t i
=0; i
<param
.get_size(); ++i
) {
2310 Module_Param
* const current
= param
.get_elem(i
);
2311 get_at(current
->get_id()->get_index())->set_param(*current
);
2315 param
.type_error(is_set()?"set of value":"record of value", get_descriptor()->name
);
2318 case Module_Param::OT_CONCAT
:
2319 switch (param
.get_type()) {
2320 case Module_Param::MP_Value_List
: {
2321 if (!is_bound()) set_val(NULL_VALUE
);
2322 int start_idx
= lengthof();
2323 for (size_t i
=0; i
<param
.get_size(); ++i
) {
2324 Module_Param
* const curr
= param
.get_elem(i
);
2325 if ((curr
->get_type()!=Module_Param::MP_NotUsed
)) {
2326 get_at(start_idx
+(int)i
)->set_param(*curr
);
2330 case Module_Param::MP_Indexed_List
:
2331 param
.error("Cannot concatenate an indexed value list");
2334 param
.type_error(is_set()?"set of value":"record of value", get_descriptor()->name
);
2338 TTCN_error("Internal error: Record_Of_Type::set_param()");
2342 void Record_Of_Type::set_implicit_omit()
2344 for (int i
= 0; i
< get_nof_elements(); ++i
) {
2345 if (is_elem_bound(i
))
2346 val_ptr
->value_elements
[i
]->set_implicit_omit();
2350 void Record_Of_Type::add_refd_index(int index
)
2352 if (NULL
== refd_ind_ptr
) {
2353 refd_ind_ptr
= new refd_index_struct
;
2354 refd_ind_ptr
->max_refd_index
= -1;
2356 refd_ind_ptr
->refd_indices
.push_back(index
);
2357 if (index
> get_max_refd_index()) {
2358 refd_ind_ptr
->max_refd_index
= index
;
2362 void Record_Of_Type::remove_refd_index(int index
)
2364 for (size_t i
= refd_ind_ptr
->refd_indices
.size(); i
> 0; --i
) {
2365 if (refd_ind_ptr
->refd_indices
[i
- 1] == index
) {
2366 refd_ind_ptr
->refd_indices
.erase_at(i
- 1);
2370 if (refd_ind_ptr
->refd_indices
.empty()) {
2371 delete refd_ind_ptr
;
2372 refd_ind_ptr
= NULL
;
2374 else if (get_max_refd_index() == index
) {
2375 refd_ind_ptr
->max_refd_index
= -1;
2379 boolean
operator==(null_type
/*null_value*/, const Record_Of_Type
& other_value
)
2381 if (other_value
.val_ptr
== NULL
)
2382 TTCN_error("The right operand of comparison is an unbound value of type %s.",
2383 other_value
.get_descriptor()->name
);
2384 return other_value
.get_nof_elements() == 0;
2387 boolean
operator!=(null_type null_value
,
2388 const Record_Of_Type
& other_value
)
2390 return !(null_value
== other_value
);
2393 ////////////////////////////////////////////////////////////////////////////////
2395 boolean
Record_Type::is_bound() const
2397 if (bound_flag
) return TRUE
;
2398 int field_cnt
= get_count();
2399 for (int field_idx
=0; field_idx
<field_cnt
; field_idx
++) {
2400 const Base_Type
* temp
= get_at(field_idx
);
2401 if(temp
->is_optional()) {
2402 if(temp
->is_present() && temp
->get_opt_value()->is_bound()) return TRUE
;
2404 if(temp
->is_bound()) return TRUE
;
2409 boolean
Record_Type::is_value() const
2414 int field_cnt
= get_count();
2415 for (int field_idx
=0; field_idx
<field_cnt
; field_idx
++) {
2416 const Base_Type
* temp
= get_at(field_idx
);
2417 if(temp
->is_optional()) {
2418 if(!temp
->is_bound()) return FALSE
;
2419 if(temp
->is_present() && !temp
->is_value()) return FALSE
;
2421 if(!temp
->is_value()) return FALSE
;
2427 void Record_Type::clean_up()
2429 int field_cnt
= get_count();
2430 for (int field_idx
=0; field_idx
<field_cnt
; field_idx
++) {
2431 get_at(field_idx
)->clean_up();
2436 void Record_Type::log() const
2439 TTCN_Logger::log_event_unbound();
2442 TTCN_Logger::log_event_str("{ ");
2443 int field_cnt
= get_count();
2444 for (int field_idx
=0; field_idx
<field_cnt
; field_idx
++) {
2445 if (field_idx
) TTCN_Logger::log_event_str(", ");
2446 TTCN_Logger::log_event_str(fld_name(field_idx
));
2447 TTCN_Logger::log_event_str(" := ");
2448 get_at(field_idx
)->log();
2450 TTCN_Logger::log_event_str(" }");
2451 if (err_descr
) err_descr
->log();
2454 void Record_Type::set_param(Module_Param
& param
) {
2456 if (dynamic_cast<Module_Param_Name
*>(param
.get_id()) != NULL
&&
2457 param
.get_id()->next_name()) {
2458 // Haven't reached the end of the module parameter name
2459 // => the name refers to one of the fields, not to the whole record
2460 char* param_field
= param
.get_id()->get_current_name();
2461 if (param_field
[0] >= '0' && param_field
[0] <= '9') {
2462 param
.error("Unexpected array index in module parameter, expected a valid field"
2463 " name for %s type `%s'", is_set() ? "set" : "record", get_descriptor()->name
);
2465 int field_cnt
= get_count();
2466 for (int field_idx
= 0; field_idx
< field_cnt
; field_idx
++) {
2467 if (strcmp(fld_name(field_idx
), param_field
) == 0) {
2468 get_at(field_idx
)->set_param(param
);
2472 param
.error("Field `%s' not found in %s type `%s'",
2473 param_field
, is_set() ? "set" : "record", get_descriptor()->name
);
2476 param
.basic_check(Module_Param::BC_VALUE
, is_set()?"set value":"record value");
2477 switch (param
.get_type()) {
2478 case Module_Param::MP_Value_List
:
2479 if (get_count()<(int)param
.get_size()) {
2480 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());
2482 for (size_t i
=0; i
<param
.get_size(); i
++) {
2483 Module_Param
* mp
= param
.get_elem(i
);
2484 if (mp
->get_type()!=Module_Param::MP_NotUsed
) {
2485 get_at((int)i
)->set_param(*mp
);
2489 case Module_Param::MP_Assignment_List
:
2490 for (size_t i
=0; i
<param
.get_size(); ++i
) {
2491 Module_Param
* const current
= param
.get_elem(i
);
2493 for (int j
=0; j
<get_count(); ++j
) {
2494 if (!strcmp(fld_name(j
), current
->get_id()->get_name())) {
2495 if (current
->get_type()!=Module_Param::MP_NotUsed
) {
2496 get_at(j
)->set_param(*current
);
2503 current
->error("Non existent field name in type %s: %s.", get_descriptor()->name
, current
->get_id()->get_name());
2508 param
.type_error(is_set()?"set value":"record value", get_descriptor()->name
);
2512 void Record_Type::set_implicit_omit()
2514 int field_cnt
= get_count();
2515 for (int field_idx
= 0; field_idx
< field_cnt
; field_idx
++) {
2516 Base_Type
*temp
= get_at(field_idx
);
2517 if (temp
->is_optional()) {
2518 if (temp
->is_bound()) temp
->set_implicit_omit();
2519 else temp
->set_to_omit();
2520 } else if (temp
->is_bound()) {
2521 temp
->set_implicit_omit();
2526 int Record_Type::size_of() const
2529 TTCN_error("Calculating the size of an unbound record/set value of type %s",
2530 get_descriptor()->name
);
2532 int opt_count
= optional_count();
2533 if (opt_count
==0) return get_count();
2534 const int* optional_indexes
= get_optional_indexes();
2535 int my_size
= get_count();
2536 for (int i
=0; i
<opt_count
; i
++) {
2537 if (!get_at(optional_indexes
[i
])->ispresent()) my_size
--;
2542 void Record_Type::encode_text(Text_Buf
& text_buf
) const
2545 TTCN_error("Text encoder: Encoding an unbound record/set value of type %s.",
2546 get_descriptor()->name
);
2548 int field_cnt
= get_count();
2549 for (int field_idx
=0; field_idx
<field_cnt
; field_idx
++)
2550 get_at(field_idx
)->encode_text(text_buf
);
2553 void Record_Type::decode_text(Text_Buf
& text_buf
)
2556 int field_cnt
= get_count();
2557 for (int field_idx
=0; field_idx
<field_cnt
; field_idx
++)
2558 get_at(field_idx
)->decode_text(text_buf
);
2561 boolean
Record_Type::is_equal(const Base_Type
* other_value
) const
2563 const Record_Type
* other_record
= static_cast<const Record_Type
*>(other_value
);
2564 if (!is_bound() && !other_record
->is_bound()) {
2567 int field_cnt
= get_count();
2568 for (int field_idx
=0; field_idx
<field_cnt
; field_idx
++) {
2569 const Base_Type
* elem
= get_at(field_idx
);
2570 const Base_Type
* other_elem
= other_record
->get_at(field_idx
);
2571 if (elem
->is_bound()) {
2572 if (other_elem
->is_bound()) {
2573 if (!elem
->is_equal(other_elem
))
2575 } else return FALSE
;
2576 } else if (other_elem
->is_bound()) return FALSE
;
2581 void Record_Type::set_value(const Base_Type
* other_value
)
2583 if (this==other_value
) return;
2584 if (!other_value
->is_bound())
2585 TTCN_error("Copying an unbound record/set value of type %s.",
2586 other_value
->get_descriptor()->name
);
2587 const Record_Type
* other_record
= static_cast<const Record_Type
*>(other_value
);
2588 int field_cnt
= get_count();
2589 for (int field_idx
=0; field_idx
<field_cnt
; field_idx
++) {
2590 const Base_Type
* elem
= other_record
->get_at(field_idx
);
2591 if (elem
->is_bound()) {
2592 get_at(field_idx
)->set_value(elem
);
2594 get_at(field_idx
)->clean_up();
2597 err_descr
= other_record
->err_descr
;
2601 void Record_Type::encode(const TTCN_Typedescriptor_t
& p_td
,
2602 TTCN_Buffer
& p_buf
, TTCN_EncDec::coding_t p_coding
, ...) const
2605 va_start(pvar
, p_coding
);
2607 case TTCN_EncDec::CT_BER
: {
2608 TTCN_EncDec_ErrorContext
ec("While BER-encoding type '%s': ", p_td
.name
);
2609 unsigned BER_coding
=va_arg(pvar
, unsigned);
2610 BER_encode_chk_coding(BER_coding
);
2611 ASN_BER_TLV_t
*tlv
=BER_encode_TLV(p_td
, BER_coding
);
2612 tlv
->put_in_buffer(p_buf
);
2613 ASN_BER_TLV_t::destruct(tlv
);
2615 case TTCN_EncDec::CT_RAW
: {
2616 TTCN_EncDec_ErrorContext
ec("While RAW-encoding type '%s': ", p_td
.name
);
2617 if(!p_td
.raw
) TTCN_EncDec_ErrorContext::error_internal
2618 ("No RAW descriptor available for type '%s'.", p_td
.name
);
2622 RAW_enc_tree
root(FALSE
, NULL
, &rp
, 1, p_td
.raw
);
2623 RAW_encode(p_td
, root
);
2624 root
.put_to_buf(p_buf
);
2626 case TTCN_EncDec::CT_TEXT
: {
2627 TTCN_EncDec_ErrorContext
ec("While TEXT-encoding type '%s': ", p_td
.name
);
2628 if(!p_td
.text
) TTCN_EncDec_ErrorContext::error_internal
2629 ("No TEXT descriptor available for type '%s'.", p_td
.name
);
2630 TEXT_encode(p_td
,p_buf
);
2632 case TTCN_EncDec::CT_XER
: {
2633 TTCN_EncDec_ErrorContext
ec("While XER-encoding type '%s': ", p_td
.name
);
2634 unsigned XER_coding
=va_arg(pvar
, unsigned);
2635 XER_encode(*(p_td
.xer
),p_buf
, XER_coding
, 0, 0);
2638 case TTCN_EncDec::CT_JSON
: {
2639 TTCN_EncDec_ErrorContext
ec("While JSON-encoding type '%s': ", p_td
.name
);
2640 if(!p_td
.json
) TTCN_EncDec_ErrorContext::error_internal
2641 ("No JSON descriptor available for type '%s'.", p_td
.name
);
2642 JSON_Tokenizer
tok(va_arg(pvar
, int) != 0);
2643 JSON_encode(p_td
, tok
);
2644 p_buf
.put_s(tok
.get_buffer_length(), (const unsigned char*)tok
.get_buffer());
2647 TTCN_error("Unknown coding method requested to encode type '%s'", p_td
.name
);
2652 void Record_Type::decode(const TTCN_Typedescriptor_t
& p_td
,
2653 TTCN_Buffer
& p_buf
, TTCN_EncDec::coding_t p_coding
, ...)
2656 va_start(pvar
, p_coding
);
2658 case TTCN_EncDec::CT_BER
: {
2659 TTCN_EncDec_ErrorContext
ec("While BER-decoding type '%s': ", p_td
.name
);
2660 unsigned L_form
=va_arg(pvar
, unsigned);
2662 BER_decode_str2TLV(p_buf
, tlv
, L_form
);
2663 BER_decode_TLV(p_td
, tlv
, L_form
);
2664 if(tlv
.isComplete
) p_buf
.increase_pos(tlv
.get_len());
2666 case TTCN_EncDec::CT_RAW
: {
2667 TTCN_EncDec_ErrorContext
ec("While RAW-decoding type '%s': ", p_td
.name
);
2669 TTCN_EncDec_ErrorContext::error_internal
2670 ("No RAW descriptor available for type '%s'.", p_td
.name
);
2672 switch(p_td
.raw
->top_bit_order
) {
2680 int rawr
= RAW_decode(p_td
, p_buf
, p_buf
.get_len()*8, order
);
2681 if (rawr
< 0) switch (-rawr
) {
2682 case TTCN_EncDec::ET_INCOMPL_MSG
:
2683 case TTCN_EncDec::ET_LEN_ERR
:
2684 ec
.error(TTCN_EncDec::ET_INCOMPL_MSG
,
2685 "Can not decode type '%s', because incomplete"
2686 " message was received", p_td
.name
);
2689 // The RAW/TEXT decoders return -1 for anything not a length error.
2690 // This is the value for ET_UNBOUND, which can't happen in decoding.
2692 ec
.error(TTCN_EncDec::ET_INVAL_MSG
,
2693 "Can not decode type '%s', because invalid"
2694 " message was received", p_td
.name
);
2698 case TTCN_EncDec::CT_TEXT
: {
2699 Limit_Token_List limit
;
2700 TTCN_EncDec_ErrorContext
ec("While TEXT-decoding type '%s': ", p_td
.name
);
2701 if(!p_td
.text
) TTCN_EncDec_ErrorContext::error_internal
2702 ("No TEXT descriptor available for type '%s'.", p_td
.name
);
2703 const unsigned char *b
=p_buf
.get_data();
2704 if(b
[p_buf
.get_len()-1]!='\0'){
2705 p_buf
.set_pos(p_buf
.get_len());
2706 p_buf
.put_zero(8,ORDER_LSB
);
2709 if(TEXT_decode(p_td
,p_buf
,limit
)<0)
2710 ec
.error(TTCN_EncDec::ET_INCOMPL_MSG
,
2711 "Can not decode type '%s', because invalid or incomplete"
2712 " message was received", p_td
.name
);
2714 case TTCN_EncDec::CT_XER
: {
2715 TTCN_EncDec_ErrorContext
ec("While XER-decoding type '%s': ", p_td
.name
);
2716 unsigned XER_coding
=va_arg(pvar
, unsigned);
2717 XmlReaderWrap
reader(p_buf
);
2718 for (int success
=reader
.Read(); success
==1; success
=reader
.Read()) {
2719 if (reader
.NodeType() == XML_READER_TYPE_ELEMENT
) break;
2721 XER_decode(*(p_td
.xer
), reader
, XER_coding
| XER_TOPLEVEL
, 0);
2722 size_t bytes
= reader
.ByteConsumed();
2723 p_buf
.set_pos(bytes
);
2725 case TTCN_EncDec::CT_JSON
: {
2726 TTCN_EncDec_ErrorContext
ec("While JSON-decoding type '%s': ", p_td
.name
);
2727 if(!p_td
.json
) TTCN_EncDec_ErrorContext::error_internal
2728 ("No JSON descriptor available for type '%s'.", p_td
.name
);
2729 JSON_Tokenizer
tok((const char*)p_buf
.get_data(), p_buf
.get_len());
2730 if(JSON_decode(p_td
, tok
, false)<0)
2731 ec
.error(TTCN_EncDec::ET_INCOMPL_MSG
,
2732 "Can not decode type '%s', because invalid or incomplete"
2733 " message was received", p_td
.name
);
2734 p_buf
.set_pos(tok
.get_buf_pos());
2737 TTCN_error("Unknown coding method requested to decode type '%s'", p_td
.name
);
2742 ASN_BER_TLV_t
* Record_Type::BER_encode_TLV(const TTCN_Typedescriptor_t
& p_td
, unsigned p_coding
) const
2745 return BER_encode_TLV_negtest(err_descr
, p_td
, p_coding
);
2748 TTCN_EncDec_ErrorContext::error
2749 (TTCN_EncDec::ET_UNBOUND
, "Encoding an unbound value.");
2751 BER_chk_descr(p_td
);
2752 ASN_BER_TLV_t
*new_tlv
=ASN_BER_TLV_t::construct(NULL
);
2753 TTCN_EncDec_ErrorContext
ec_0("Component '");
2754 TTCN_EncDec_ErrorContext ec_1
;
2755 int next_default_idx
= 0;
2756 const default_struct
* default_indexes
= get_default_indexes();
2757 int field_cnt
= get_count();
2758 for(int i
=0; i
<field_cnt
; i
++) {
2759 boolean is_default_field
= default_indexes
&& (default_indexes
[next_default_idx
].index
==i
);
2760 if (!default_as_optional() && is_default_field
) {
2761 if (!get_at(i
)->is_equal(default_indexes
[next_default_idx
].value
)) {
2762 ec_1
.set_msg("%s': ", fld_name(i
));
2763 new_tlv
->add_TLV(get_at(i
)->BER_encode_TLV(*fld_descr(i
), p_coding
));
2765 } else { /* is not DEFAULT */
2766 ec_1
.set_msg("%s': ", fld_name(i
));
2767 new_tlv
->add_TLV(get_at(i
)->BER_encode_TLV(*fld_descr(i
), p_coding
));
2769 if (is_default_field
) next_default_idx
++;
2772 if (p_coding
==BER_ENCODE_DER
) new_tlv
->sort_tlvs_tag();
2773 new_tlv
=ASN_BER_V2TLV(new_tlv
, p_td
, p_coding
);
2777 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
2780 TTCN_EncDec_ErrorContext::error
2781 (TTCN_EncDec::ET_UNBOUND
, "Encoding an unbound value.");
2783 BER_chk_descr(p_td
);
2784 ASN_BER_TLV_t
*new_tlv
=ASN_BER_TLV_t::construct(NULL
);
2785 TTCN_EncDec_ErrorContext
ec_0("Component '");
2786 TTCN_EncDec_ErrorContext ec_1
;
2787 int next_default_idx
= 0;
2788 const default_struct
* default_indexes
= get_default_indexes();
2789 int field_cnt
= get_count();
2794 for (int i
=0; i
<field_cnt
; i
++) {
2795 boolean is_default_field
= default_indexes
&& (default_indexes
[next_default_idx
].index
==i
);
2796 // the first condition is not needed, kept for ease of understanding
2797 if ( (p_err_descr
->omit_before
!=-1) && (i
<p_err_descr
->omit_before
) ) {
2798 if (is_default_field
) next_default_idx
++;
2801 const Erroneous_values_t
* err_vals
= p_err_descr
->next_field_err_values(i
, values_idx
);
2802 const Erroneous_descriptor_t
* emb_descr
= p_err_descr
->next_field_emb_descr(i
, edescr_idx
);
2804 if (err_vals
&& err_vals
->before
) {
2805 if (err_vals
->before
->errval
==NULL
) TTCN_error(
2806 "internal error: erroneous before value missing");
2807 ec_1
.set_msg("%s'(erroneous before): ", fld_name(i
));
2808 if (err_vals
->before
->raw
) {
2809 new_tlv
->add_TLV(err_vals
->before
->errval
->BER_encode_negtest_raw());
2811 if (err_vals
->before
->type_descr
==NULL
) TTCN_error(
2812 "internal error: erroneous before typedescriptor missing");
2813 new_tlv
->add_TLV(err_vals
->before
->errval
->BER_encode_TLV(
2814 *err_vals
->before
->type_descr
, p_coding
));
2818 if (err_vals
&& err_vals
->value
) {
2819 if (err_vals
->value
->errval
) { // replace
2820 ec_1
.set_msg("%s'(erroneous value): ", fld_name(i
));
2821 if (err_vals
->value
->raw
) {
2822 new_tlv
->add_TLV(err_vals
->value
->errval
->BER_encode_negtest_raw());
2824 if (err_vals
->value
->type_descr
==NULL
) TTCN_error(
2825 "internal error: erroneous value typedescriptor missing");
2826 new_tlv
->add_TLV(err_vals
->value
->errval
->BER_encode_TLV(
2827 *err_vals
->value
->type_descr
, p_coding
));
2831 if (!default_as_optional() && is_default_field
) {
2832 if (!get_at(i
)->is_equal(default_indexes
[next_default_idx
].value
)) {
2833 ec_1
.set_msg("'%s': ", fld_name(i
));
2835 new_tlv
->add_TLV(get_at(i
)->BER_encode_TLV_negtest(emb_descr
,
2836 *fld_descr(i
), p_coding
));
2838 new_tlv
->add_TLV(get_at(i
)->BER_encode_TLV(*fld_descr(i
), p_coding
));
2841 } else { /* is not DEFAULT */
2842 ec_1
.set_msg("'%s': ", fld_name(i
));
2844 new_tlv
->add_TLV(get_at(i
)->BER_encode_TLV_negtest(emb_descr
,
2845 *fld_descr(i
), p_coding
));
2847 new_tlv
->add_TLV(get_at(i
)->BER_encode_TLV(*fld_descr(i
), p_coding
));
2852 if (err_vals
&& err_vals
->after
) {
2853 if (err_vals
->after
->errval
==NULL
) TTCN_error(
2854 "internal error: erroneous after value missing");
2855 ec_1
.set_msg("%s'(erroneous after): ", fld_name(i
));
2856 if (err_vals
->after
->raw
) {
2857 new_tlv
->add_TLV(err_vals
->after
->errval
->BER_encode_negtest_raw());
2859 if (err_vals
->after
->type_descr
==NULL
) TTCN_error(
2860 "internal error: erroneous after typedescriptor missing");
2861 new_tlv
->add_TLV(err_vals
->after
->errval
->BER_encode_TLV(
2862 *err_vals
->after
->type_descr
, p_coding
));
2866 if (is_default_field
) next_default_idx
++;
2867 if ( (p_err_descr
->omit_after
!=-1) && (i
>=p_err_descr
->omit_after
) ) break;
2871 if (p_coding
==BER_ENCODE_DER
) new_tlv
->sort_tlvs_tag();
2872 new_tlv
=ASN_BER_V2TLV(new_tlv
, p_td
, p_coding
);
2876 boolean
Record_Type::BER_decode_TLV(const TTCN_Typedescriptor_t
& p_td
,
2877 const ASN_BER_TLV_t
& p_tlv
, unsigned L_form
)
2880 BER_chk_descr(p_td
);
2881 ASN_BER_TLV_t stripped_tlv
;
2882 BER_decode_strip_tags(*p_td
.ber
, p_tlv
, L_form
, stripped_tlv
);
2883 TTCN_EncDec_ErrorContext
ec_0("While decoding '%s' type: ", get_descriptor()->name
);
2884 stripped_tlv
.chk_constructed_flag(TRUE
);
2886 ASN_BER_TLV_t tmp_tlv
;
2888 { /* SEQUENCE decoding */
2889 boolean tlv_present
=FALSE
;
2891 TTCN_EncDec_ErrorContext
ec_1("Component '");
2892 TTCN_EncDec_ErrorContext ec_2
;
2893 int next_default_idx
= 0;
2894 int next_optional_idx
= 0;
2895 const default_struct
* default_indexes
= get_default_indexes();
2896 const int* optional_indexes
= get_optional_indexes();
2897 int field_cnt
= get_count();
2898 for(int i
=0; i
<field_cnt
; i
++) {
2899 boolean is_default_field
= default_indexes
&& (default_indexes
[next_default_idx
].index
==i
);
2900 boolean is_optional_field
= optional_indexes
&& (optional_indexes
[next_optional_idx
]==i
);
2901 ec_2
.set_msg("%s': ", fld_descr(i
)->name
);
2902 if (!tlv_present
) tlv_present
=BER_decode_constdTLV_next(stripped_tlv
, V_pos
, L_form
, tmp_tlv
);
2903 if (is_default_field
) { /* is DEFAULT */
2904 if (!tlv_present
|| !get_at(i
)->BER_decode_isMyMsg(*fld_descr(i
), tmp_tlv
)) {
2905 get_at(i
)->set_value(default_indexes
[next_default_idx
].value
);
2907 get_at(i
)->BER_decode_TLV(*fld_descr(i
), tmp_tlv
, L_form
);
2911 else if (is_optional_field
) { /* is OPTIONAL */
2912 if (!tlv_present
) get_at(i
)->set_to_omit();
2914 get_at(i
)->BER_decode_TLV(*fld_descr(i
), tmp_tlv
, L_form
);
2915 if (get_at(i
)->ispresent()) tlv_present
=FALSE
;
2918 else { /* is not DEFAULT OPTIONAL */
2920 ec_2
.error(TTCN_EncDec::ET_INCOMPL_MSG
,"Invalid or incomplete message was received.");
2923 get_at(i
)->BER_decode_TLV(*fld_descr(i
), tmp_tlv
, L_form
);
2926 if (is_default_field
) next_default_idx
++;
2927 if (is_optional_field
) next_optional_idx
++;
2930 BER_decode_constdTLV_end(stripped_tlv
, V_pos
, L_form
, tmp_tlv
, tlv_present
);
2931 } /* SEQUENCE decoding */
2933 { /* SET decoding */
2935 * 0x01: value arrived
2936 * 0x02: is optional / not used :)
2937 * 0x04: has default / not used :)
2939 int field_cnt
= get_count();
2940 unsigned char* fld_indctr
= new unsigned char[field_cnt
];
2941 for (int i
=0; i
<field_cnt
; i
++) fld_indctr
[i
] = 0;
2942 int fld_curr
= -1; /* ellipsis or error... */
2943 while (BER_decode_constdTLV_next(stripped_tlv
, V_pos
, L_form
, tmp_tlv
)) {
2944 for (int i
=0; i
<field_cnt
; i
++) {
2945 if (get_at(i
)->BER_decode_isMyMsg(*fld_descr(i
), tmp_tlv
)) {
2947 TTCN_EncDec_ErrorContext
ec_1("Component '%s': ", fld_name(i
));
2948 get_at(i
)->BER_decode_TLV(*fld_descr(i
), tmp_tlv
, L_form
);
2953 if (fld_indctr
[fld_curr
])
2954 ec_0
.error(TTCN_EncDec::ET_DEC_DUPFLD
, "Duplicated value for component '%s'.", fld_name(fld_curr
));
2955 fld_indctr
[fld_curr
]=1;
2958 int next_default_idx
= 0;
2959 int next_optional_idx
= 0;
2960 const default_struct
* default_indexes
= get_default_indexes();
2961 const int* optional_indexes
= get_optional_indexes();
2962 for (fld_curr
=0; fld_curr
<field_cnt
; fld_curr
++) {
2963 boolean is_default_field
= default_indexes
&& (default_indexes
[next_default_idx
].index
==fld_curr
);
2964 boolean is_optional_field
= optional_indexes
&& (optional_indexes
[next_optional_idx
]==fld_curr
);
2965 if (!fld_indctr
[fld_curr
]) {
2966 if (is_default_field
) get_at(fld_curr
)->set_value(default_indexes
[next_default_idx
].value
);
2967 else if (is_optional_field
) get_at(fld_curr
)->set_to_omit();
2968 else ec_0
.error(TTCN_EncDec::ET_DEC_MISSFLD
, "Missing value for component '%s'.", fld_name(fld_curr
));
2970 if (is_default_field
) next_default_idx
++;
2971 if (is_optional_field
) next_optional_idx
++;
2973 delete[] fld_indctr
;
2974 } /* SET decoding */
2976 if (is_opentype_outermost()) {
2977 TTCN_EncDec_ErrorContext
ec_1("While decoding opentypes: ");
2978 TTCN_Type_list p_typelist
;
2979 BER_decode_opentypes(p_typelist
, L_form
);
2980 } /* if sdef->opentype_outermost */
2984 void Record_Type::BER_decode_opentypes(TTCN_Type_list
& p_typelist
, unsigned L_form
)
2987 p_typelist
.push(this);
2988 TTCN_EncDec_ErrorContext
ec_0("Component '");
2989 TTCN_EncDec_ErrorContext ec_1
;
2990 int field_cnt
= get_count();
2991 for(int i
=0; i
<field_cnt
; i
++) {
2992 ec_1
.set_msg("%s': ", fld_name(i
));
2993 get_at(i
)->BER_decode_opentypes(p_typelist
, L_form
);
2998 int Record_Type::RAW_encode(const TTCN_Typedescriptor_t
& p_td
,
2999 RAW_enc_tree
& myleaf
) const
3001 if (err_descr
) return RAW_encode_negtest(err_descr
, p_td
, myleaf
);
3003 TTCN_EncDec_ErrorContext::error
3004 (TTCN_EncDec::ET_UNBOUND
, "Encoding an unbound value.");
3006 int encoded_length
= 0;
3007 int field_cnt
= get_count();
3008 myleaf
.isleaf
= false;
3009 myleaf
.body
.node
.num_of_nodes
= field_cnt
;
3010 myleaf
.body
.node
.nodes
= init_nodes_of_enc_tree(field_cnt
);
3012 int next_optional_idx
= 0;
3013 const int* optional_indexes
= get_optional_indexes();
3014 for (int i
= 0; i
< field_cnt
; i
++) {
3015 boolean is_optional_field
= optional_indexes
3016 && (optional_indexes
[next_optional_idx
] == i
);
3017 if (!is_optional_field
|| get_at(i
)->ispresent()) {
3018 myleaf
.body
.node
.nodes
[i
] = new RAW_enc_tree(true, &myleaf
,
3019 &(myleaf
.curr_pos
), i
, fld_descr(i
)->raw
);
3022 myleaf
.body
.node
.nodes
[i
] = NULL
;
3024 if (is_optional_field
) next_optional_idx
++;
3026 next_optional_idx
= 0;
3027 for (int i
= 0; i
< field_cnt
; i
++) { /*encoding fields*/
3028 boolean is_optional_field
= optional_indexes
3029 && (optional_indexes
[next_optional_idx
] == i
);
3030 /* encoding of normal fields*/
3031 const Base_Type
*field
= get_at(i
);
3032 if (is_optional_field
) {
3033 next_optional_idx
++;
3034 if (!field
->ispresent())
3035 continue; // do not encode
3037 field
= field
->get_opt_value(); // "reach into" the optional
3039 encoded_length
+= field
->RAW_encode(*fld_descr(i
),
3040 *myleaf
.body
.node
.nodes
[i
]);
3042 return myleaf
.length
= encoded_length
;
3045 // In some cases (e.g. LENGTHTO, POINTERTO, CROSSTAG) it is not generated.
3046 int Record_Type::RAW_encode_negtest(const Erroneous_descriptor_t
*p_err_descr
,
3047 const TTCN_Typedescriptor_t
& /*p_td*/, RAW_enc_tree
& myleaf
) const
3050 TTCN_EncDec_ErrorContext::error
3051 (TTCN_EncDec::ET_UNBOUND
, "Encoding an unbound value.");
3053 int encoded_length
= 0;
3054 int num_fields
= get_count();
3055 myleaf
.isleaf
= false;
3056 myleaf
.body
.node
.num_of_nodes
= 0;
3057 for (int field_idx
= 0; field_idx
< num_fields
; ++field_idx
) {
3058 if ((p_err_descr
->omit_before
!= -1) &&
3059 (field_idx
< p_err_descr
->omit_before
))
3061 else ++myleaf
.body
.node
.num_of_nodes
;
3062 const Erroneous_values_t
*err_vals
= p_err_descr
->get_field_err_values(field_idx
);
3063 if (err_vals
&& err_vals
->before
)
3064 ++myleaf
.body
.node
.num_of_nodes
;
3065 if (err_vals
&& err_vals
->value
&& !err_vals
->value
->errval
)
3066 --myleaf
.body
.node
.num_of_nodes
;
3067 if (err_vals
&& err_vals
->after
)
3068 ++myleaf
.body
.node
.num_of_nodes
;
3069 if ((p_err_descr
->omit_after
!= -1) &&
3070 (field_idx
>= p_err_descr
->omit_after
))
3073 myleaf
.body
.node
.nodes
= init_nodes_of_enc_tree(myleaf
.body
.node
.num_of_nodes
);
3074 TTCN_EncDec_ErrorContext ec
;
3075 int next_optional_idx
= 0;
3076 const int *my_optional_indexes
= get_optional_indexes();
3077 // Counter for fields and additional before/after fields.
3079 for (int field_idx
= 0; field_idx
< num_fields
; ++field_idx
) {
3080 boolean is_optional_field
= my_optional_indexes
&&
3081 (my_optional_indexes
[next_optional_idx
] == field_idx
);
3082 if ((p_err_descr
->omit_before
!= -1) &&
3083 (field_idx
< p_err_descr
->omit_before
)) {
3084 if (is_optional_field
) ++next_optional_idx
;
3087 const Erroneous_values_t
*err_vals
= p_err_descr
->get_field_err_values(field_idx
);
3088 const Erroneous_descriptor_t
*emb_descr
= p_err_descr
->get_field_emb_descr(field_idx
);
3089 if (err_vals
&& err_vals
->before
) {
3090 if (err_vals
->before
->errval
== NULL
)
3091 TTCN_error("internal error: erroneous before value missing");
3092 if (err_vals
->before
->raw
) {
3093 myleaf
.body
.node
.nodes
[node_pos
] =
3094 new RAW_enc_tree(true, &myleaf
, &(myleaf
.curr_pos
), node_pos
,
3095 err_vals
->before
->errval
->get_descriptor()->raw
);
3096 encoded_length
+= err_vals
->before
->errval
->
3097 RAW_encode_negtest_raw(*myleaf
.body
.node
.nodes
[node_pos
++]);
3099 if (err_vals
->before
->type_descr
== NULL
)
3100 TTCN_error("internal error: erroneous before typedescriptor missing");
3101 myleaf
.body
.node
.nodes
[node_pos
] =
3102 new RAW_enc_tree(true, &myleaf
, &(myleaf
.curr_pos
), node_pos
,
3103 err_vals
->before
->type_descr
->raw
);
3104 encoded_length
+= err_vals
->before
->errval
->
3105 RAW_encode(*(err_vals
->before
->type_descr
),
3106 *myleaf
.body
.node
.nodes
[node_pos
++]);
3109 if (err_vals
&& err_vals
->value
) {
3110 if (err_vals
->value
->errval
) {
3111 ec
.set_msg("'%s'(erroneous value): ", fld_name(field_idx
));
3112 if (err_vals
->value
->raw
) {
3113 myleaf
.body
.node
.nodes
[node_pos
] =
3114 new RAW_enc_tree(true, &myleaf
, &(myleaf
.curr_pos
), node_pos
,
3115 err_vals
->value
->errval
->get_descriptor()->raw
);
3116 encoded_length
+= err_vals
->value
->errval
->
3117 RAW_encode_negtest_raw(*myleaf
.body
.node
.nodes
[node_pos
++]);
3119 if (err_vals
->value
->type_descr
== NULL
)
3120 TTCN_error("internal error: erroneous value typedescriptor missing");
3121 myleaf
.body
.node
.nodes
[node_pos
] =
3122 new RAW_enc_tree(true, &myleaf
, &(myleaf
.curr_pos
), node_pos
,
3123 err_vals
->value
->type_descr
->raw
);
3124 encoded_length
+= err_vals
->value
->errval
->
3125 RAW_encode(*(err_vals
->value
->type_descr
),
3126 *myleaf
.body
.node
.nodes
[node_pos
++]);
3130 ec
.set_msg("'%s': ", fld_name(field_idx
));
3131 if (!is_optional_field
|| get_at(field_idx
)->ispresent()) {
3132 const Base_Type
*field
=
3133 is_optional_field
? get_at(field_idx
)->get_opt_value()
3134 : get_at(field_idx
);
3135 myleaf
.body
.node
.nodes
[node_pos
] =
3136 new RAW_enc_tree(true, &myleaf
, &(myleaf
.curr_pos
), node_pos
,
3137 fld_descr(field_idx
)->raw
);
3140 field
->RAW_encode_negtest(emb_descr
, *fld_descr(field_idx
),
3141 *myleaf
.body
.node
.nodes
[node_pos
++]);
3144 field
->RAW_encode(*fld_descr(field_idx
),
3145 *myleaf
.body
.node
.nodes
[node_pos
++]);
3149 myleaf
.body
.node
.nodes
[node_pos
++] = NULL
;
3152 if (err_vals
&& err_vals
->after
) {
3153 if (err_vals
->after
->errval
== NULL
)
3154 TTCN_error("internal error: erroneous before value missing");
3155 if (err_vals
->after
->raw
) {
3156 myleaf
.body
.node
.nodes
[node_pos
] =
3157 new RAW_enc_tree(true, &myleaf
, &(myleaf
.curr_pos
), node_pos
,
3158 err_vals
->after
->errval
->get_descriptor()->raw
);
3159 encoded_length
+= err_vals
->after
->errval
->
3160 RAW_encode_negtest_raw(*myleaf
.body
.node
.nodes
[node_pos
++]);
3162 if (err_vals
->after
->type_descr
== NULL
)
3163 TTCN_error("internal error: erroneous after typedescriptor missing");
3164 myleaf
.body
.node
.nodes
[node_pos
] =
3165 new RAW_enc_tree(true, &myleaf
, &(myleaf
.curr_pos
), node_pos
,
3166 err_vals
->after
->type_descr
->raw
);
3167 encoded_length
+= err_vals
->after
->errval
->
3168 RAW_encode(*(err_vals
->after
->type_descr
),
3169 *myleaf
.body
.node
.nodes
[node_pos
++]);
3172 if (is_optional_field
) ++next_optional_idx
;
3173 if ((p_err_descr
->omit_after
!= -1) &&
3174 (field_idx
>= p_err_descr
->omit_after
))
3177 return myleaf
.length
= encoded_length
;
3180 int Record_Type::RAW_decode(const TTCN_Typedescriptor_t
& p_td
, TTCN_Buffer
& buff
,
3181 int limit
, raw_order_t top_bit_ord
, boolean no_err
, int, boolean
)
3184 int field_cnt
= get_count();
3185 int opt_cnt
= optional_count();
3186 int mand_num
= field_cnt
- opt_cnt
; // expected mandatory fields
3188 raw_order_t local_top_order
;
3189 if (p_td
.raw
->top_bit_order
== TOP_BIT_INHERITED
) local_top_order
= top_bit_ord
;
3190 else if (p_td
.raw
->top_bit_order
== TOP_BIT_RIGHT
) local_top_order
= ORDER_MSB
;
3191 else local_top_order
= ORDER_LSB
;
3193 if (is_set()) { /* set decoder start*/
3194 int prepaddlength
= buff
.increase_pos_padd(p_td
.raw
->prepadding
);
3195 limit
-= prepaddlength
;
3196 int decoded_length
= 0;
3197 int * const field_map
= new int[field_cnt
];
3198 memset(field_map
, 0, field_cnt
* sizeof(int));
3199 int nof_mand_fields
= 0; // mandatory fields actually decoded
3201 const int* optional_indexes
= get_optional_indexes();
3202 for (int i
=0; i
<opt_cnt
; i
++) get_at(optional_indexes
[i
])->set_to_omit();
3205 size_t fl_start_pos
= buff
.get_pos_bit();
3206 int next_optional_idx
= 0;
3207 const int* optional_indexes
= get_optional_indexes();
3208 for (int i
=0; i
<field_cnt
; i
++) { /* decoding fields without TAG */
3209 boolean is_optional_field
= optional_indexes
&& (optional_indexes
[next_optional_idx
]==i
);
3210 if (field_map
[i
] == 0) {
3211 Base_Type
* field_ptr
= get_at(i
);
3212 if (is_optional_field
) {
3213 field_ptr
->set_to_present();
3214 field_ptr
=field_ptr
->get_opt_value();
3216 int decoded_field_length
= field_ptr
->RAW_decode(*fld_descr(i
), buff
,
3217 limit
, local_top_order
, TRUE
);
3218 if ( (is_optional_field
&& (decoded_field_length
>0)) ||
3219 (!is_optional_field
&& (decoded_field_length
>=0)) ) {
3220 decoded_length
+= decoded_field_length
;
3221 limit
-= decoded_field_length
;
3222 if (!is_optional_field
) nof_mand_fields
++;
3224 goto continue_while
;
3226 buff
.set_pos_bit(fl_start_pos
);
3227 if (is_optional_field
) get_at(i
)->set_to_omit();
3230 if (is_optional_field
) next_optional_idx
++;
3232 break; // no field could be decoded successfully, quit
3236 if (mand_num
> 0 && nof_mand_fields
!= mand_num
) {
3237 /* Not all required fields were decoded. If there are no bits left,
3238 * that means that the last field was decoded successfully but used up
3239 * the buffer. Signal "incomplete". If there were bits left, that means
3240 * no field could be decoded from them; signal an error. */
3241 return limit
? -1 : -TTCN_EncDec::ET_INCOMPL_MSG
;
3243 return decoded_length
+ prepaddlength
+ buff
.increase_pos_padd(p_td
.raw
->padding
);
3244 } else { /* record decoder start */
3245 int prepaddlength
= buff
.increase_pos_padd(p_td
.raw
->prepadding
);
3246 limit
-= prepaddlength
;
3247 size_t last_decoded_pos
= buff
.get_pos_bit();
3248 size_t fl_start_pos
;
3249 int decoded_length
= 0;
3250 int decoded_field_length
= 0;
3251 if (raw_has_ext_bit()) {
3252 const unsigned char* data
=buff
.get_read_data();
3254 unsigned mask
= 1 << (local_top_order
==ORDER_LSB
? 0 : 7);
3255 if (p_td
.raw
->extension_bit
==EXT_BIT_YES
) {
3256 while((data
[count
-1] & mask
) == 0 && count
* 8 < (int)limit
) count
++;
3259 while((data
[count
-1] & mask
) != 0 && count
* 8 < (int)limit
) count
++;
3261 if(limit
) limit
=count
*8;
3264 int next_optional_idx
= 0;
3265 const int* optional_indexes
= get_optional_indexes();
3266 for (int i
=0; i
<field_cnt
; i
++) { /* decoding fields */
3267 boolean is_optional_field
= optional_indexes
&& (optional_indexes
[next_optional_idx
]==i
);
3268 /* check if enough bits to decode the field*/
3269 if (!is_optional_field
|| (limit
>0)) {
3270 /* decoding of normal field */
3271 fl_start_pos
= buff
.get_pos_bit();
3272 Base_Type
* field_ptr
= get_at(i
);
3273 if (is_optional_field
) {
3274 field_ptr
->set_to_present();
3275 field_ptr
=field_ptr
->get_opt_value();
3277 decoded_field_length
= field_ptr
->RAW_decode(*fld_descr(i
), buff
, limit
,
3278 local_top_order
, is_optional_field
? TRUE
: no_err
);
3279 boolean field_present
= TRUE
;
3280 if (is_optional_field
) {
3281 if (decoded_field_length
< 1) { // swallow any error and become omit
3282 field_present
= FALSE
;
3283 get_at(i
)->set_to_omit();
3284 buff
.set_pos_bit(fl_start_pos
);
3287 if (decoded_field_length
< 0) return decoded_field_length
;
3289 if (field_present
) {
3290 decoded_length
+=decoded_field_length
;
3291 limit
-=decoded_field_length
;
3292 last_decoded_pos
=last_decoded_pos
<buff
.get_pos_bit()?buff
.get_pos_bit():last_decoded_pos
;
3295 get_at(i
)->set_to_omit();
3297 if (is_optional_field
) next_optional_idx
++;
3298 } /* decoding fields*/
3300 buff
.set_pos_bit(last_decoded_pos
);
3301 return decoded_length
+prepaddlength
+buff
.increase_pos_padd(p_td
.raw
->padding
);
3302 } /* record decoder end*/
3305 int Record_Type::TEXT_encode(const TTCN_Typedescriptor_t
& p_td
, TTCN_Buffer
& buff
) const
3308 return TEXT_encode_negtest(err_descr
, p_td
, buff
);
3311 TTCN_EncDec_ErrorContext::error
3312 (TTCN_EncDec::ET_UNBOUND
, "Encoding an unbound value.");
3314 bool need_separator
=false;
3315 int encoded_length
=0;
3316 if (p_td
.text
->begin_encode
) {
3317 buff
.put_cs(*p_td
.text
->begin_encode
);
3318 encoded_length
+=p_td
.text
->begin_encode
->lengthof();
3320 int next_optional_idx
= 0;
3321 const int* optional_indexes
= get_optional_indexes();
3322 int field_cnt
= get_count();
3323 for(int i
=0;i
<field_cnt
;i
++) {
3324 boolean is_optional_field
= optional_indexes
&& (optional_indexes
[next_optional_idx
]==i
);
3325 if (!is_optional_field
|| get_at(i
)->ispresent()) {
3326 if (need_separator
&& p_td
.text
->separator_encode
) {
3327 buff
.put_cs(*p_td
.text
->separator_encode
);
3328 encoded_length
+=p_td
.text
->separator_encode
->lengthof();
3330 encoded_length
+= get_at(i
)->TEXT_encode(*fld_descr(i
),buff
);
3331 need_separator
=true;
3333 if (is_optional_field
) next_optional_idx
++;
3335 if (p_td
.text
->end_encode
) {
3336 buff
.put_cs(*p_td
.text
->end_encode
);
3337 encoded_length
+=p_td
.text
->end_encode
->lengthof();
3339 return encoded_length
;
3343 * TEXT encode negative testing
3345 int Record_Type::TEXT_encode_negtest(const Erroneous_descriptor_t
* p_err_descr
, const TTCN_Typedescriptor_t
& p_td
, TTCN_Buffer
& buff
) const
3348 TTCN_EncDec_ErrorContext::error
3349 (TTCN_EncDec::ET_UNBOUND
, "Encoding an unbound value.");
3351 bool need_separator
=false;
3352 int encoded_length
=0;
3353 if (p_td
.text
->begin_encode
) {
3354 buff
.put_cs(*p_td
.text
->begin_encode
);
3355 encoded_length
+=p_td
.text
->begin_encode
->lengthof();
3357 int next_optional_idx
= 0;
3358 const int* optional_indexes
= get_optional_indexes();
3359 int field_cnt
= get_count();
3364 for(int i
=0;i
<field_cnt
;i
++) {
3365 boolean is_optional_field
= optional_indexes
&& (optional_indexes
[next_optional_idx
]==i
);
3367 if ( (p_err_descr
->omit_before
!=-1) && (i
<p_err_descr
->omit_before
) ) {
3368 if (is_optional_field
) next_optional_idx
++;
3372 const Erroneous_values_t
* err_vals
= p_err_descr
->next_field_err_values(i
, values_idx
);
3373 const Erroneous_descriptor_t
* emb_descr
= p_err_descr
->next_field_emb_descr(i
, edescr_idx
);
3375 if (err_vals
&& err_vals
->before
) {
3376 if (err_vals
->before
->errval
==NULL
) TTCN_error(
3377 "internal error: erroneous before value missing");
3379 if (need_separator
&& p_td
.text
->separator_encode
) {
3380 buff
.put_cs(*p_td
.text
->separator_encode
);
3381 encoded_length
+=p_td
.text
->separator_encode
->lengthof();
3383 if (err_vals
->before
->raw
) {
3384 encoded_length
+= err_vals
->before
->errval
->encode_raw(buff
);
3386 if (err_vals
->before
->type_descr
==NULL
) TTCN_error(
3387 "internal error: erroneous before typedescriptor missing");
3388 encoded_length
+= err_vals
->before
->errval
->TEXT_encode(
3389 *(err_vals
->before
->type_descr
),buff
);
3391 need_separator
=true;
3394 if (err_vals
&& err_vals
->value
) {
3395 if (err_vals
->value
->errval
) {
3396 if (need_separator
&& p_td
.text
->separator_encode
) {
3397 buff
.put_cs(*p_td
.text
->separator_encode
);
3398 encoded_length
+=p_td
.text
->separator_encode
->lengthof();
3400 if (err_vals
->value
->raw
) {
3401 encoded_length
+= err_vals
->value
->errval
->encode_raw(buff
);
3403 if (err_vals
->value
->type_descr
==NULL
) TTCN_error(
3404 "internal error: erroneous value typedescriptor missing");
3405 encoded_length
+= err_vals
->value
->errval
->TEXT_encode(
3406 *(err_vals
->value
->type_descr
),buff
);
3408 need_separator
=true;
3411 if (!is_optional_field
|| get_at(i
)->ispresent()) {
3412 if (need_separator
&& p_td
.text
->separator_encode
) {
3413 buff
.put_cs(*p_td
.text
->separator_encode
);
3414 encoded_length
+=p_td
.text
->separator_encode
->lengthof();
3417 encoded_length
+= get_at(i
)->TEXT_encode_negtest(emb_descr
, *fld_descr(i
),buff
);
3419 encoded_length
+= get_at(i
)->TEXT_encode(*fld_descr(i
),buff
);
3421 need_separator
=true;
3425 if (err_vals
&& err_vals
->after
) {
3426 if (err_vals
->after
->errval
==NULL
) TTCN_error(
3427 "internal error: erroneous after value missing");
3428 if (need_separator
&& p_td
.text
->separator_encode
) {
3429 buff
.put_cs(*p_td
.text
->separator_encode
);
3430 encoded_length
+=p_td
.text
->separator_encode
->lengthof();
3432 if (err_vals
->after
->raw
) {
3433 encoded_length
+= err_vals
->after
->errval
->encode_raw(buff
);
3435 if (err_vals
->after
->type_descr
==NULL
) TTCN_error(
3436 "internal error: erroneous after typedescriptor missing");
3437 encoded_length
+= err_vals
->after
->errval
->TEXT_encode(
3438 *(err_vals
->after
->type_descr
),buff
);
3440 need_separator
=true;
3443 if (is_optional_field
) next_optional_idx
++;
3445 if ( (p_err_descr
->omit_after
!=-1) && (i
>=p_err_descr
->omit_after
) ) break;
3447 if (p_td
.text
->end_encode
) {
3448 buff
.put_cs(*p_td
.text
->end_encode
);
3449 encoded_length
+=p_td
.text
->end_encode
->lengthof();
3451 return encoded_length
;
3454 int Record_Type::TEXT_decode(const TTCN_Typedescriptor_t
& p_td
, TTCN_Buffer
& buff
,
3455 Limit_Token_List
& limit
, boolean no_err
, boolean
/*first_call*/)
3459 int decoded_length
=0;
3460 int decoded_field_length
=0;
3461 size_t pos
=buff
.get_pos();
3462 boolean sep_found
=FALSE
;
3465 int loop_detector
=1;
3466 int last_field_num
=-1;
3467 if (p_td
.text
->begin_decode
) {
3469 if ((tl
=p_td
.text
->begin_decode
->match_begin(buff
))<0) {
3470 if(no_err
) return -1;
3471 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR
,
3472 "The specified token '%s' not found for '%s': ",
3473 (const char*)*(p_td
.text
->begin_decode
), p_td
.name
);
3477 buff
.increase_pos(tl
);
3479 if (p_td
.text
->end_decode
) {
3480 limit
.add_token(p_td
.text
->end_decode
);
3483 if(p_td
.text
->separator_decode
){
3484 limit
.add_token(p_td
.text
->separator_decode
);
3488 int field_cnt
= get_count();
3489 int * const field_map
= new int[field_cnt
];
3490 memset(field_map
, 0, field_cnt
* sizeof(int));
3492 int mand_field_num
= 0;
3493 int opt_field_num
= 0;
3495 int has_repeatable
=0;
3496 boolean repeatable
= TRUE
;
3498 int next_optional_idx
= 0;
3499 const int* optional_indexes
= get_optional_indexes();
3500 for (int i
=0;i
<field_cnt
;i
++) {
3501 boolean is_optional_field
= optional_indexes
&& (optional_indexes
[next_optional_idx
]==i
);
3502 if (is_optional_field
) {
3503 get_at(i
)->set_to_omit();
3508 if (get_at(i
)->is_seof()) {
3510 repeatable
= repeatable
&& fld_descr(i
)->text
->val
.parameters
->decoding_params
.repeatable
;
3512 if (is_optional_field
) next_optional_idx
++;
3514 boolean has_optinals
= opt_field_num
> 0;
3515 if ((seof
>0) && repeatable
) has_repeatable
=1;
3517 while (mand_field_num
+opt_field_num
+has_repeatable
) {
3521 next_optional_idx
= 0;
3522 for (int i
=0;i
<field_cnt
;i
++) {
3523 boolean is_optional_field
= optional_indexes
&& (optional_indexes
[next_optional_idx
]==i
);
3524 if (get_at(i
)->is_seof()) {
3525 if ( (fld_descr(i
)->text
->val
.parameters
->decoding_params
.repeatable
&& field_map
[i
]<3)
3526 || !field_map
[i
] ) {
3528 decoded_field_length
= get_at(i
)->TEXT_decode(*fld_descr(i
),buff
, limit
, true,!field_map
[i
]);
3529 if (decoded_field_length
<0) {
3531 if (is_optional_field
&& !field_map
[i
]) get_at(i
)->set_to_omit();
3534 if (!field_map
[i
]) {
3535 if (is_optional_field
) opt_field_num
--;
3536 else mand_field_num
--;
3538 } else field_map
[i
]=2;
3543 } else { // !...->is_seof
3544 if (!field_map
[i
]) {
3546 decoded_field_length
= get_at(i
)->TEXT_decode(*fld_descr(i
),buff
,limit
,true);
3547 if (decoded_field_length
<0) {
3549 if (is_optional_field
) get_at(i
)->set_to_omit();
3553 if (is_optional_field
) opt_field_num
--;
3554 else mand_field_num
--;
3560 if (is_optional_field
) next_optional_idx
++;
3564 if (loop_detector
) break;
3565 if (p_td
.text
->separator_decode
) {
3567 if ((tl
=p_td
.text
->separator_decode
->match_begin(buff
))<0) {
3568 if (p_td
.text
->end_decode
) {
3570 if ((tl2
=p_td
.text
->end_decode
->match_begin(buff
))!=-1) {
3574 } else if (limit
.has_token(ml
)) {
3576 if ((tl2
=limit
.match(buff
,ml
))==0) {
3582 decoded_length
-=decoded_field_length
;
3583 field_map
[last_field_num
]+=2;
3586 if (last_field_num
>=0 && last_field_num
<field_cnt
) {
3587 if (get_at(last_field_num
)->is_seof()) {
3588 if (get_at(last_field_num
)->is_optional()) {
3589 if (field_map
[last_field_num
]==3) {
3590 get_at(last_field_num
)->set_to_omit();
3594 if (field_map
[last_field_num
]==3) {
3598 } else if (get_at(last_field_num
)->is_optional()) {
3599 get_at(last_field_num
)->set_to_omit();
3607 } // if (has_optinals)
3611 buff
.increase_pos(tl
);
3612 for (int a
=0;a
<field_cnt
;a
++) if(field_map
[a
]>2) field_map
[a
]-=3;
3615 } else if (p_td
.text
->end_decode
) {
3617 if ((tl
=p_td
.text
->end_decode
->match_begin(buff
))!=-1) {
3619 buff
.increase_pos(tl
);
3620 limit
.remove_tokens(ml
);
3621 if (mand_field_num
) decoded_length
= -1;
3624 } else if(limit
.has_token(ml
)){
3626 if ((tl
=limit
.match(buff
,ml
))==0) {
3632 limit
.remove_tokens(ml
);
3634 if (mand_field_num
) {
3635 if (no_err
) decoded_length
= -1;
3636 else TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR
,
3637 "Error during decoding '%s': ", p_td
.name
);
3640 decoded_length
-=sep_length
;
3641 buff
.set_pos(buff
.get_pos()-sep_length
);
3644 if (p_td
.text
->end_decode
) {
3646 if ((tl
=p_td
.text
->end_decode
->match_begin(buff
))<0) {
3647 if (no_err
) decoded_length
= -1;
3648 else TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR
,
3649 "The specified token '%s' not found for '%s': ",
3650 (const char*)*(p_td
.text
->end_decode
),p_td
.name
);
3654 buff
.increase_pos(tl
);
3656 if (mand_field_num
) decoded_length
= -1;
3659 return decoded_length
;
3660 } else { // record decoder
3661 int decoded_length
=0;
3662 int decoded_field_length
=0;
3663 size_t pos
=buff
.get_pos();
3664 boolean sep_found
=FALSE
;
3667 if (p_td
.text
->begin_decode
) {
3669 if ((tl
=p_td
.text
->begin_decode
->match_begin(buff
))<0) {
3670 if(no_err
)return -1;
3671 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR
,
3672 "The specified token '%s' not found for '%s': ",
3673 (const char*)*(p_td
.text
->begin_decode
), p_td
.name
);
3677 buff
.increase_pos(tl
);
3679 if (p_td
.text
->end_decode
) {
3680 limit
.add_token(p_td
.text
->end_decode
);
3683 if (p_td
.text
->separator_decode
) {
3684 limit
.add_token(p_td
.text
->separator_decode
);
3688 int mand_field_num
= 0;
3689 int opt_field_num
= 0;
3690 int last_man_index
= 0;
3692 int field_cnt
= get_count();
3693 int next_optional_idx
= 0;
3694 const int* optional_indexes
= get_optional_indexes();
3695 for (int i
=0;i
<field_cnt
;i
++) {
3696 boolean is_optional_field
= optional_indexes
&& (optional_indexes
[next_optional_idx
]==i
);
3697 if (is_optional_field
) {
3698 get_at(i
)->set_to_omit();
3704 if (is_optional_field
) next_optional_idx
++;
3707 next_optional_idx
= 0;
3708 for(int i
=0;i
<field_cnt
;i
++) {
3709 boolean is_optional_field
= optional_indexes
&& (optional_indexes
[next_optional_idx
]==i
);
3710 if (is_optional_field
) {
3713 decoded_field_length
= get_at(i
)->TEXT_decode(*fld_descr(i
),buff
,limit
,TRUE
);
3714 if (decoded_field_length
<0) {
3715 if (is_optional_field
) {
3716 get_at(i
)->set_to_omit();
3719 limit
.remove_tokens(ml
);
3720 if (no_err
) return -1;
3721 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR
,
3722 "Error during decoding field '%s' for '%s': ",
3723 fld_descr(i
)->name
, p_td
.name
);
3724 return decoded_length
;
3727 decoded_length
+=decoded_field_length
;
3728 if (last_man_index
>(i
+1)) {
3729 if (p_td
.text
->separator_decode
) {
3731 if ((tl
=p_td
.text
->separator_decode
->match_begin(buff
))<0) {
3732 if(is_optional_field
) {
3733 get_at(i
)->set_to_omit();
3735 decoded_length
-=decoded_field_length
;
3737 limit
.remove_tokens(ml
);
3738 if(no_err
)return -1;
3739 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR
,
3740 "The specified token '%s' not found for '%s': ",
3741 (const char*)*(p_td
.text
->separator_decode
),p_td
.name
);
3742 return decoded_length
;
3746 buff
.increase_pos(tl
);
3750 } else sep_found
=FALSE
;
3752 } else if (i
==(field_cnt
-1)) {
3755 if (p_td
.text
->separator_decode
) {
3757 if ((tl
=p_td
.text
->separator_decode
->match_begin(buff
))<0) {
3758 if (is_optional_field
) {
3759 if (p_td
.text
->end_decode
) {
3760 if ((tl
=p_td
.text
->end_decode
->match_begin(buff
))!=-1) {
3762 buff
.increase_pos(tl
);
3763 limit
.remove_tokens(ml
);
3764 return decoded_length
;
3766 } else if (limit
.has_token(ml
)) {
3767 if ((tl
=limit
.match(buff
,ml
))==0) {
3772 get_at(i
)->set_to_omit();
3774 decoded_length
-=decoded_field_length
;
3781 buff
.increase_pos(tl
);
3788 if (p_td
.text
->end_decode
) {
3789 if ((tl
=p_td
.text
->end_decode
->match_begin(buff
))!=-1) {
3791 buff
.increase_pos(tl
);
3792 limit
.remove_tokens(ml
);
3793 return decoded_length
;
3795 } else if (limit
.has_token(ml
)) {
3796 if ((tl
=limit
.match(buff
,ml
))==0) {
3804 if (is_optional_field
) next_optional_idx
++;
3806 limit
.remove_tokens(ml
);
3808 buff
.set_pos(buff
.get_pos()-sep_length
);
3809 decoded_length
-=sep_length
;
3811 if (p_td
.text
->end_decode
) {
3813 if ((tl
=p_td
.text
->end_decode
->match_begin(buff
))<0) {
3814 if(no_err
)return -1;
3815 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR
,
3816 "The specified token '%s' not found for '%s': ",
3817 (const char*)*(p_td
.text
->end_decode
),p_td
.name
);
3818 return decoded_length
;
3821 buff
.increase_pos(tl
);
3823 return decoded_length
;
3827 const XERdescriptor_t
* Record_Type::xer_descr(int /*field_index*/) const
3829 TTCN_error("Internal error: Record_Type::xer_descr() called.");
3833 char ** Record_Type::collect_ns(const XERdescriptor_t
& p_td
, size_t& num
, bool& def_ns
) const
3835 const int field_cnt
= get_count();
3836 // The USE-ORDER member is first, unless preempted by EMBED-VALUES
3837 const int uo_index
= ((p_td
.xer_bits
& EMBED_VALUES
) !=0);
3838 // Index of the first "normal" member (after E-V and U-O)
3839 const int start_at
= uo_index
+ ((p_td
.xer_bits
& USE_ORDER
) != 0);
3841 size_t num_collected
= 0;
3842 // First, our own namespace. Sets num_collected to 0 or 1.
3843 // If it throws, nothing was allocated.
3844 char **collected_ns
= Base_Type::collect_ns(p_td
, num_collected
, def_ns
);
3847 // If the nil attribute will be written, add the control namespace
3848 boolean nil_attribute
= (p_td
.xer_bits
& USE_NIL
)
3849 && !get_at(field_cnt
-1)->ispresent();
3851 if (nil_attribute
) {
3852 collected_ns
= (char**)Realloc(collected_ns
, sizeof(char*) * ++num_collected
);
3853 const namespace_t
*c_ns
= p_td
.my_module
->get_controlns();
3855 collected_ns
[num_collected
-1] = mprintf(" xmlns:%s='%s'", c_ns
->px
, c_ns
->ns
);
3858 // Collect namespace declarations from all components (recursively).
3859 // This is extremely nasty, but we can't prosecute you for that.
3860 // (Monty Python - Crunchy Frog sketch). This whole thing is O(n^3). Yuck.
3861 for (int a
= start_at
; a
< field_cnt
; ++a
) {
3863 bool def_ns_1
= false;
3864 char **new_namespaces
= get_at(a
)->collect_ns(*xer_descr(a
), num_new
, def_ns_1
);
3865 merge_ns(collected_ns
, num_collected
, new_namespaces
, num_new
);
3866 def_ns
= def_ns
|| def_ns_1
;
3867 // merge_ns freed new_namespaces
3871 // Probably a TC_Error thrown from the element's collect_ns(),
3872 // e.g. if encoding an unbound value.
3873 while (num_collected
> 0) Free(collected_ns
[--num_collected
]);
3878 num
= num_collected
;
3879 return collected_ns
;
3882 // FIXME some hashing should be implemented
3883 int Record_Type::get_index_byname(const char *name
, const char *uri
) const {
3884 int num_fields
= get_count();
3885 for (int i
= 0; i
< num_fields
; ++i
) {
3886 const XERdescriptor_t
& xer
= *xer_descr(i
);
3887 if (check_name(name
, xer
, TRUE
)
3888 && check_namespace(uri
, xer
)) return i
;
3893 int Record_Type::XER_encode(const XERdescriptor_t
& p_td
, TTCN_Buffer
& p_buf
,
3894 unsigned int flavor
, int indent
, embed_values_enc_struct_t
*) const
3897 return XER_encode_negtest(err_descr
, p_td
, p_buf
, flavor
, indent
, 0);
3900 TTCN_EncDec_ErrorContext::error
3901 (TTCN_EncDec::ET_UNBOUND
, "Encoding an unbound value.");
3904 TTCN_EncDec_ErrorContext
ec_0("Component '");
3905 TTCN_EncDec_ErrorContext ec_1
;
3906 int encoded_length
=(int)p_buf
.get_len(); // how much is already in the buffer
3908 int exer
= is_exer(flavor
);
3909 if (exer
&& (p_td
.xer_bits
& EMBED_VALUES
)) flavor
|= XER_CANONICAL
;
3910 const boolean indenting
= !is_canonical(flavor
);
3911 const int field_cnt
= get_count();
3912 const int num_attributes
= get_xer_num_attr();
3913 // The USE-ORDER member is first, unless preempted by EMBED-VALUES
3914 const int uo_index
= ((p_td
.xer_bits
& EMBED_VALUES
) !=0);
3915 // Index of the first "normal" member (after E-V and U-O)
3916 const int start_at
= uo_index
+ ((p_td
.xer_bits
& USE_ORDER
) != 0);
3917 const int first_nonattr
= start_at
+ num_attributes
;
3918 // start_tag_len is keeping track of how much was written at the end of the
3919 // start tag, i.e. the ">\n". This is used later to "back up" over it.
3920 int start_tag_len
= 1 + indenting
;
3921 // The EMBED-VALUES member, if applicable
3922 const Record_Of_Type
* const embed_values
= (p_td
.xer_bits
& EMBED_VALUES
)
3923 ? static_cast<const Record_Of_Type
*>(get_at(0)) : 0;
3924 // The USE-ORDER member, if applicable
3925 const Record_Of_Type
* const use_order
= (p_td
.xer_bits
& USE_ORDER
)
3926 ? static_cast<const Record_Of_Type
*>(get_at(uo_index
)) : 0;
3928 size_t num_collected
= 0; // we use this to compute delay_close
3929 char **collected_ns
= NULL
;
3930 bool def_ns
= false;
3932 if (indent
== 0) { // top-level type
3933 collected_ns
= collect_ns(p_td
, num_collected
, def_ns
);
3935 else if ((flavor
& DEF_NS_SQUASHED
) && p_td
.my_module
&& p_td
.ns_index
!= -1) {
3936 const namespace_t
* ns
= p_td
.my_module
->get_ns(p_td
.ns_index
);
3937 // The default namespace has been squashed.
3938 // If we are in the default namespace, restore it.
3939 if (*ns
->px
== '\0') {
3940 collected_ns
= Base_Type::collect_ns(p_td
, num_collected
, def_ns
);
3945 // The type's own tag is omitted if we're doing E-XER,
3946 // and it's not the top-level type (XML must have a root element)
3947 // and it's either UNTAGGED or got USE_NIL or USE_TYPE or USE_UNION.
3948 boolean omit_tag
= exer
&& (indent
> 0)
3949 && ( (p_td
.xer_bits
& (UNTAGGED
|XER_ATTRIBUTE
))
3950 || (flavor
& (USE_NIL
|USE_TYPE_ATTR
)));
3952 // If a default namespace is in effect (uri but no prefix) and the type
3953 // is unqualified, the default namespace must be canceled; otherwise
3954 // an XML tag without a ns prefix looks like it belongs to the def.namespace
3955 const boolean empty_ns_hack
= exer
&& !omit_tag
&& (indent
> 0)
3956 && (p_td
.xer_bits
& FORM_UNQUALIFIED
)
3957 && (flavor
& DEF_NS_PRESENT
);
3959 // delay_close=true if there is stuff before the '>' of the start tag
3960 // (prevents writing the '>' which is built into the name).
3961 // This can only happen for EXER: if there are attributes or namespaces,
3962 // or either USE-NIL or USE-QNAME is set.
3963 boolean delay_close
= exer
&& (num_attributes
3964 || empty_ns_hack
// counts as having a namespace
3965 || (num_collected
!= 0)
3966 || (p_td
.xer_bits
& (USE_NIL
|USE_QNAME
))
3967 || (flavor
& USE_NIL
));
3971 if (!omit_tag
) { /* write start tag */
3972 if (indenting
) do_indent(p_buf
, indent
);
3973 /* name looks like this: "tagname>\n"
3974 * lose the \n if : not indenting or (single untagged(*) or attributes (*)) AND exer
3975 * lose the > if attributes are present (*) AND exer
3978 if (exer
) write_ns_prefix(p_td
, p_buf
);
3979 p_buf
.put_s((size_t)p_td
.namelens
[exer
] - delay_close
3980 - (!indenting
|| delay_close
|| (exer
&& (p_td
.xer_bits
& HAS_1UNTAGGED
))),
3981 (cbyte
*)p_td
.names
[exer
]);
3983 else if (flavor
& USE_TYPE_ATTR
) {
3984 // reopen the parent's start tag by overwriting the '>'
3985 size_t buf_len
= p_buf
.get_len();
3986 const unsigned char * const buf_data
= p_buf
.get_data();
3987 if (buf_data
[buf_len
- 1 - shorter
] == '\n') ++shorter
;
3988 if (buf_data
[buf_len
- 1 - shorter
] == '>' ) ++shorter
;
3991 p_buf
.increase_length(-shorter
);
3997 // mask out extra flags we received, do not send them to the fields
4000 if (exer
&& (p_td
.xer_bits
& USE_QNAME
)) { // QName trumps everything
4001 const Base_Type
* const q_uri
= get_at(0);
4002 if (q_uri
->is_present()) {
4003 p_buf
.put_s(11, (cbyte
*)" xmlns:b0='");
4004 q_uri
->XER_encode(*xer_descr(0), p_buf
, flavor
| XER_LIST
, indent
+1, 0);
4008 if (p_td
.xer_bits
& XER_ATTRIBUTE
) begin_attribute(p_td
, p_buf
);
4009 else p_buf
.put_c('>');
4011 if (q_uri
->is_present()) {
4012 p_buf
.put_s(3, (cbyte
*)"b0:");
4015 const Base_Type
* const q_name
= get_at(1);
4016 sub_len
+= q_name
->XER_encode(*xer_descr(1), p_buf
, flavor
| XER_LIST
, indent
+1, 0);
4017 if (p_td
.xer_bits
& XER_ATTRIBUTE
) p_buf
.put_c('\'');
4019 else { // not USE-QNAME
4020 if (!exer
&& (p_td
.xer_bits
& EMBED_VALUES
)) {
4021 // The EMBED-VALUES member as an ordinary record of string
4022 sub_len
+= embed_values
->XER_encode(*xer_descr(0), p_buf
, flavor
, indent
+1, 0);
4025 if (!exer
&& (p_td
.xer_bits
& USE_ORDER
)) {
4026 // The USE-ORDER member as an ordinary record of enumerated
4027 sub_len
+= use_order
->XER_encode(*xer_descr(uo_index
), p_buf
, flavor
, indent
+1, 0);
4030 if (exer
&& (indent
==0 || (flavor
& DEF_NS_SQUASHED
))) // write namespaces for toplevel only
4032 for (size_t cur_coll
= 0; cur_coll
< num_collected
; ++cur_coll
) {
4033 p_buf
.put_s(strlen(collected_ns
[cur_coll
]), (cbyte
*)collected_ns
[cur_coll
]);
4034 Free(collected_ns
[cur_coll
]); // job done
4040 flavor
&= ~DEF_NS_SQUASHED
;
4041 flavor
|= DEF_NS_PRESENT
;
4043 else if (empty_ns_hack
) {
4044 p_buf
.put_s(9, (cbyte
*)" xmlns=''");
4045 flavor
&= ~DEF_NS_PRESENT
;
4046 flavor
|= DEF_NS_SQUASHED
;
4049 /* First all the attributes (not added to sub_len) */
4051 for (i
= start_at
; i
< first_nonattr
; ++i
) {
4052 boolean is_xer_attr_field
= xer_descr(i
)->xer_bits
& XER_ATTRIBUTE
;
4053 ec_1
.set_msg("%s': ", fld_name(i
)); // attr
4054 int tmp_len
= get_at(i
)->XER_encode(*xer_descr(i
), p_buf
, flavor
, indent
+1, 0);
4055 if (is_xer_attr_field
&& !exer
) sub_len
+= tmp_len
; /* do not add if attribute and EXER */
4058 // True if the "nil" attribute needs to be written.
4059 boolean nil_attribute
= exer
&& (p_td
.xer_bits
& USE_NIL
)
4060 && !get_at(field_cnt
-1)->ispresent();
4062 // True if USE_ORDER is in effect and the "nil" attribute was written.
4063 // Then the record-of-enum for USE-ORDER will be empty.
4064 boolean early_to_bed
= FALSE
;
4066 if (nil_attribute
) { // req. exer and USE_NIL
4067 const namespace_t
*control_ns
= p_td
.my_module
->get_controlns();
4069 p_buf
.put_s(strlen(control_ns
->px
),
4070 (cbyte
*)control_ns
->px
);
4072 p_buf
.put_s(10, (cbyte
*)"nil='true'");
4073 if ((p_td
.xer_bits
& USE_ORDER
)) early_to_bed
= TRUE
;
4074 // The whole content was omitted; nothing to do (and if we tried
4075 // to do it, we'd get an error for over-indexing a 0-length record-of).
4078 if (delay_close
&& (!omit_tag
|| shorter
)) {
4079 // Close the start tag left open. If indenting, also write a newline
4080 // unless USE-NIL in effect or there is a single untagged component.
4082 ((p_td
.xer_bits
& (/*USE_NIL|*/HAS_1UNTAGGED
)) ? 0 : indenting
);
4083 p_buf
.put_s(start_tag_len
, (cbyte
*)">\n");
4086 if (exer
&& (p_td
.xer_bits
& EMBED_VALUES
)) {
4087 /* write the first string */
4088 if (embed_values
->size_of() > 0) {
4089 sub_len
+= embed_values
->get_at(0)->XER_encode(UNIVERSAL_CHARSTRING_xer_
,
4090 p_buf
, flavor
| EMBED_VALUES
, indent
+1, 0);
4094 const Record_Type
*ordered
= this; // the record affected by USE-ORDER
4096 // Index of the first non-attribute field of the record pointed to by
4097 // ordered, that is, the first field affected by USE-ORDER.
4098 size_t useorder_base
= first_nonattr
;
4101 int end
= field_cnt
;
4102 if (exer
&& (p_td
.xer_bits
& USE_ORDER
)) {
4103 const int to_send
= use_order
->size_of();
4104 // the length of the loop is determined by the length of use_order
4108 // Count the non-attribute optionals
4109 int n_optionals
= 0;
4110 for (int B
= optional_count() - 1; B
>=+0; B
--) {
4111 int oi
= get_optional_indexes()[B
];
4112 if (oi
< first_nonattr
) break;
4116 int expected_min
= field_cnt
- first_nonattr
- n_optionals
;
4117 int expected_max
= field_cnt
- first_nonattr
;
4120 if ((p_td
.xer_bits
& USE_NIL
) && get_at(field_cnt
-1)->ispresent()) {
4121 // The special case when USE_ORDER refers to the fields of a field,
4123 const Base_Type
*last_optional
= get_at(field_cnt
-1);
4124 const Base_Type
* inner
= last_optional
->get_opt_value();
4125 // it absolutely, positively has to be (derived from) Record_Type
4126 ordered
= static_cast<const Record_Type
*>(inner
);
4127 useorder_base
= ordered
->get_xer_num_attr();
4128 begin
= useorder_base
;
4129 end
= ordered
->get_count();
4131 expected_min
= expected_max
= ordered
->get_count();
4134 if (to_send
> expected_max
4135 ||to_send
< expected_min
) {
4136 ec_1
.set_msg("%s': ", fld_name(uo_index
));
4137 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_CONSTRAINT
,
4138 "Wrong number of USE-ORDER %d, must be %d..%d", to_send
, expected_min
, expected_max
);
4139 begin
= end
= 0; // don't bother sending anything
4141 else { // check no duplicates
4142 int *seen
= new int [to_send
];
4144 for (int ei
= 0; ei
< to_send
; ++ei
) {
4145 const Base_Type
*uoe
= use_order
->get_at(ei
);
4146 const Enum_Type
*enm
= static_cast<const Enum_Type
*>(uoe
);
4147 int val
= enm
->as_int();
4148 for (int x
= 0; x
< num_seen
; ++x
) {
4149 if (val
== seen
[x
]) { // complain
4150 ec_1
.set_msg("%s': ", fld_name(uo_index
));
4151 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_CONSTRAINT
,
4152 "Duplicate value for USE-ORDER");
4153 begin
= end
= 0; // don't bother sending anything
4157 seen
[num_seen
++] = val
;
4161 // If the number is right and there are no duplicates, then carry on
4165 /* Then, all the non-attributes. Structuring the code like this depends on
4166 * all attributes appearing before all non-attributes (excluding
4167 * pseudo-members for USE-ORDER, etc.) */
4169 // early_to_bed can only be true if exer is true (transitive through nil_attribute)
4170 if (!early_to_bed
) {
4171 embed_values_enc_struct_t
* emb_val
= 0;
4172 if (exer
&& (p_td
.xer_bits
& EMBED_VALUES
) && embed_values
->size_of() > 1) {
4173 emb_val
= new embed_values_enc_struct_t
;
4174 emb_val
->embval_array
= embed_values
;
4175 emb_val
->embval_index
= 1;
4176 emb_val
->embval_err
= 0;
4179 for ( i
= begin
; i
< end
; ++i
) {
4180 const Base_Type
*uoe
= 0; // "useOrder enum"
4181 const Enum_Type
*enm
= 0; // the enum value selecting the field
4182 if (exer
&& use_order
) {
4183 uoe
= use_order
->get_at(i
- begin
);
4184 enm
= static_cast<const Enum_Type
*>(uoe
);
4187 // "actual" index, may be perturbed by USE-ORDER
4188 int ai
= !(exer
&& (p_td
.xer_bits
& USE_ORDER
)) ? i
:
4189 enm
->as_int() + useorder_base
;
4190 ec_1
.set_msg("%s': ", ordered
->fld_name(ai
)); // non-attr
4192 const XERdescriptor_t
& descr
= *ordered
->xer_descr(ai
);
4193 sub_len
+= ordered
->get_at(ai
)->XER_encode(descr
, p_buf
,
4194 // Pass USE-NIL to the last field (except when USE-ORDER is also in effect,
4195 // because the tag-stripping effect of USE-NIL has been achieved
4196 // by encoding the sub-fields directly).
4197 flavor
| ((exer
&& !use_order
&& (i
== field_cnt
-1)) ? (p_td
.xer_bits
& USE_NIL
) : 0),
4198 indent
+!omit_tag
, emb_val
);
4200 // Now the next embed-values string (NOT affected by USE-ORDER!)
4201 if (exer
&& (p_td
.xer_bits
& EMBED_VALUES
) && 0 != emb_val
&&
4202 emb_val
->embval_index
< embed_values
->size_of()) {
4203 embed_values
->get_at(emb_val
->embval_index
)->XER_encode(UNIVERSAL_CHARSTRING_xer_
4204 , p_buf
, flavor
| EMBED_VALUES
, indent
+1, 0);
4205 ++emb_val
->embval_index
;
4210 if (emb_val
->embval_index
< embed_values
->size_of()) {
4211 ec_1
.set_msg("%s': ", fld_name(0));
4212 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_CONSTRAINT
,
4213 "Too many EMBED-VALUEs specified: %d (expected %d or less)",
4214 embed_values
->size_of(), emb_val
->embval_index
);
4218 } // if (!early_to_bed)
4222 if (sub_len
) { // something was written, now an end tag
4223 if (indenting
&& !(exer
&& (p_td
.xer_bits
& (HAS_1UNTAGGED
| USE_QNAME
)))) {
4224 // The tags of the last optional member involved with USE_NIL
4225 // have been removed. If it was a simple type, the content was probably
4226 // written on a single line without anything resembling a close tag.
4227 // Do not indent our end tag in this case.
4228 switch ((int)(exer
&& (p_td
.xer_bits
& USE_NIL
))) {
4230 const unsigned char *buf_end
= p_buf
.get_data() + (p_buf
.get_len()-1);
4231 if (buf_end
[-1] != '>' || *buf_end
!= '\n') break;
4232 // If it does not look like an end tag, skip the indenting,
4233 // else fall through.
4236 do_indent(p_buf
, indent
);
4242 if (exer
) write_ns_prefix(p_td
, p_buf
);
4243 p_buf
.put_s((size_t)p_td
.namelens
[exer
]-!indenting
, (cbyte
*)p_td
.names
[exer
]);
4245 else { // need to generate an empty element tag
4246 p_buf
.increase_length(-start_tag_len
); // decrease length
4247 p_buf
.put_s((size_t)2+indenting
, (cbyte
*)"/>\n");
4251 return (int)p_buf
.get_len() - encoded_length
;
4254 // XERSTUFF Record_Type::encode_field
4255 /** Helper for Record_Type::XER_encode_negtest
4257 * Factored out because Record_Type::XER_encode (on which XER_encode_negtest
4258 * is based) calls the XER_encode method of the field in two places:
4259 * one for attributes, the other for elements.
4261 * @param i index of the field
4262 * @param err_vals erroneous descriptor for the field
4263 * @param emb_descr deeper erroneous values
4264 * @param p_buf buffer containing the encoded value
4265 * @param sub_flavor flags
4266 * @param indent indentation level
4267 * @return the number of bytes generated
4269 int Record_Type::encode_field(int i
,
4270 const Erroneous_values_t
* err_vals
, const Erroneous_descriptor_t
* emb_descr
,
4271 TTCN_Buffer
& p_buf
, unsigned int sub_flavor
, int indent
, embed_values_enc_struct_t
* emb_val
) const
4274 TTCN_EncDec_ErrorContext ec
;
4275 if (err_vals
&& err_vals
->before
) {
4276 if (err_vals
->before
->errval
==NULL
) TTCN_error(
4277 "internal error: erroneous before value missing");
4278 ec
.set_msg("Erroneous value before component %s: ", fld_name(i
));
4279 if (err_vals
->before
->raw
) {
4280 enc_len
+= err_vals
->before
->errval
->encode_raw(p_buf
);
4282 if (err_vals
->before
->type_descr
==NULL
) TTCN_error(
4283 "internal error: erroneous before typedescriptor missing");
4284 enc_len
+= err_vals
->before
->errval
->XER_encode(
4285 *err_vals
->before
->type_descr
->xer
, p_buf
, sub_flavor
, indent
, 0);
4289 if (err_vals
&& err_vals
->value
) {
4290 if (err_vals
->value
->errval
) { // replace
4291 ec
.set_msg("Erroneous value for component %s: ", fld_name(i
));
4292 if (err_vals
->value
->raw
) {
4293 enc_len
+= err_vals
->value
->errval
->encode_raw(p_buf
);
4295 if (err_vals
->value
->type_descr
==NULL
) TTCN_error(
4296 "internal error: erroneous value typedescriptor missing");
4297 enc_len
+= err_vals
->value
->errval
->XER_encode(
4298 *err_vals
->value
->type_descr
->xer
, p_buf
, sub_flavor
, indent
, 0);
4302 ec
.set_msg("Component %s: ", fld_name(i
));
4304 enc_len
+= get_at(i
)->XER_encode_negtest(emb_descr
, *xer_descr(i
), p_buf
,
4305 sub_flavor
, indent
, emb_val
);
4307 // the "real" encoder
4308 enc_len
+= get_at(i
)->XER_encode(*xer_descr(i
), p_buf
,
4309 sub_flavor
, indent
, emb_val
);
4313 if (err_vals
&& err_vals
->after
) {
4314 if (err_vals
->after
->errval
==NULL
) TTCN_error(
4315 "internal error: erroneous after value missing");
4316 ec
.set_msg("Erroneous value after component %s: ", fld_name(i
));
4317 if (err_vals
->after
->raw
) {
4318 enc_len
+= err_vals
->after
->errval
->encode_raw(p_buf
);
4320 if (err_vals
->after
->type_descr
==NULL
) TTCN_error(
4321 "internal error: erroneous after typedescriptor missing");
4322 enc_len
+= err_vals
->after
->errval
->XER_encode(
4323 *err_vals
->after
->type_descr
->xer
, p_buf
, sub_flavor
, indent
, 0);
4330 // XERSTUFF Record_Type::XER_encode_negtest
4331 int Record_Type::XER_encode_negtest(const Erroneous_descriptor_t
* p_err_descr
,
4332 const XERdescriptor_t
& p_td
, TTCN_Buffer
& p_buf
, unsigned int flavor
, int indent
,
4333 embed_values_enc_struct_t
*) const
4336 TTCN_EncDec_ErrorContext::error
4337 (TTCN_EncDec::ET_UNBOUND
, "Encoding an unbound value.");
4339 TTCN_EncDec_ErrorContext
ec_0("Component '");
4340 TTCN_EncDec_ErrorContext ec_1
;
4341 int encoded_length
=(int)p_buf
.get_len(); // how much is already in the buffer
4343 int exer
= is_exer(flavor
);
4344 if (exer
&& (p_td
.xer_bits
& EMBED_VALUES
)) flavor
|= XER_CANONICAL
;
4345 const boolean indenting
= !is_canonical(flavor
);
4346 const int field_cnt
= get_count();
4347 const int num_attributes
= get_xer_num_attr();
4348 // The USE-ORDER member is first, unless preempted by EMBED-VALUES
4349 const int uo_index
= ((p_td
.xer_bits
& EMBED_VALUES
) !=0);
4350 // Index of the first "normal" member (after E-V and U-O)
4351 const int start_at
= uo_index
+ ((p_td
.xer_bits
& USE_ORDER
) != 0);
4352 const int first_nonattr
= start_at
+ num_attributes
;
4353 // start_tag_len is keeping track of how much was written at the end of the
4354 // start tag, i.e. the ">\n". This is used later to "back up" over it.
4355 int start_tag_len
= 1 + indenting
;
4356 // The EMBED-VALUES member, if applicable (always first)
4357 const Record_Of_Type
* const embed_values
= (p_td
.xer_bits
& EMBED_VALUES
)
4358 ? static_cast<const Record_Of_Type
*>(get_at(0)) : 0;
4359 // The USE-ORDER member, if applicable (first unless preempted by embed_vals)
4360 const Record_Of_Type
* const use_order
= (p_td
.xer_bits
& USE_ORDER
)
4361 ? static_cast<const Record_Of_Type
*>(get_at(uo_index
)) : 0;
4366 size_t num_collected
= 0; // we use this to compute delay_close
4367 char **collected_ns
= NULL
;
4368 bool def_ns
= false;
4370 if (indent
== 0) { // top-level type
4371 collected_ns
= collect_ns(p_td
, num_collected
, def_ns
);
4373 else if ((flavor
& DEF_NS_SQUASHED
) && p_td
.my_module
&& p_td
.ns_index
!= -1) {
4374 const namespace_t
* ns
= p_td
.my_module
->get_ns(p_td
.ns_index
);
4375 // The default namespace has been squashed.
4376 // If we are in the default namespace, restore it.
4377 if (*ns
->px
== '\0') {
4378 collected_ns
= Base_Type::collect_ns(p_td
, num_collected
, def_ns
);
4383 // The type's own tag is omitted if we're doing E-XER,
4384 // and it's not the top-level type (XML must have a root element)
4385 // and it's either UNTAGGED or got USE_NIL.
4386 boolean omit_tag
= exer
&& indent
4387 && ( (p_td
.xer_bits
& (UNTAGGED
|XER_ATTRIBUTE
))
4388 || (flavor
& (USE_NIL
|USE_TYPE_ATTR
)));
4390 // If a default namespace is in effect (uri but no prefix) and the type
4391 // is unqualified, the default namespace must be canceled; otherwise
4392 // an XML tag without a ns prefix looks like it belongs to the def.namespace
4393 const boolean empty_ns_hack
= exer
&& !omit_tag
&& (indent
> 0)
4394 && (p_td
.xer_bits
& FORM_UNQUALIFIED
)
4395 && (flavor
& DEF_NS_PRESENT
);
4397 // delay_close=true if there is stuff before the '>' of the start tag
4398 // (prevents writing the '>' which is built into the name).
4399 // This can only happen for EXER: if there are attributes or namespaces,
4400 // or either USE-NIL or USE-QNAME is set.
4401 boolean delay_close
= exer
&& (num_attributes
4402 || empty_ns_hack
// counts as having a namespace
4403 || (num_collected
!= 0)
4404 || (p_td
.xer_bits
& (USE_NIL
|USE_QNAME
))
4405 || (flavor
& USE_NIL
));
4408 if (!omit_tag
) { /* write start tag */
4409 if (indenting
) do_indent(p_buf
, indent
);
4410 /* name looks like this: "tagname>\n"
4411 * lose the \n if : not indenting or (single untagged(*) or attributes (*)) AND exer
4412 * lose the > if attributes are present (*) AND exer
4415 if (exer
) write_ns_prefix(p_td
, p_buf
);
4416 p_buf
.put_s((size_t)p_td
.namelens
[exer
] - delay_close
4417 - (!indenting
|| delay_close
|| (exer
&& (p_td
.xer_bits
& HAS_1UNTAGGED
))),
4418 (cbyte
*)p_td
.names
[exer
]);
4420 else if (flavor
& USE_TYPE_ATTR
) {
4421 // reopen the parent's tag
4422 size_t buf_len
= p_buf
.get_len();
4423 const unsigned char * const buf_data
= p_buf
.get_data();
4424 if (buf_data
[buf_len
- 1 - shorter
] == '\n') ++shorter
;
4425 if (buf_data
[buf_len
- 1 - shorter
] == '>' ) ++shorter
;
4428 p_buf
.increase_length(-shorter
);
4433 int sub_len
=0, tmp_len
;
4434 // mask out extra flags we received, do not send them to the fields
4437 if (exer
&& (p_td
.xer_bits
& USE_QNAME
)) {
4438 const Erroneous_values_t
* ev
=
4439 p_err_descr
->next_field_err_values(0, values_idx
);
4440 const Erroneous_descriptor_t
* ed
=
4441 p_err_descr
->next_field_emb_descr (0, edescr_idx
);
4442 // At first, erroneous info for the first component (uri)
4444 TTCN_EncDec_ErrorContext ec
;
4445 const Base_Type
* const q_uri
= get_at(0);
4447 if (ev
&& ev
->before
) {
4448 if (ev
->before
->errval
==NULL
) TTCN_error(
4449 "internal error: erroneous before value missing");
4450 ec
.set_msg("Erroneous value before component #0: ");
4451 if (ev
->before
->raw
) {
4452 sub_len
+= ev
->before
->errval
->encode_raw(p_buf
);
4454 if (ev
->before
->type_descr
==NULL
) TTCN_error(
4455 "internal error: erroneous before typedescriptor missing");
4456 sub_len
+= ev
->before
->errval
->XER_encode(
4457 *ev
->before
->type_descr
->xer
, p_buf
, flavor
, indent
, 0);
4461 if (ev
&& ev
->value
) {
4462 if (ev
->value
->errval
) { // replace
4463 ec
.set_msg("Erroneous value for component #0: ");
4464 if (ev
->value
->raw
) {
4465 sub_len
+= ev
->value
->errval
->encode_raw(p_buf
);
4467 if (ev
->value
->type_descr
==NULL
) TTCN_error(
4468 "internal error: erroneous value typedescriptor missing");
4469 sub_len
+= ev
->value
->errval
->XER_encode(
4470 *ev
->value
->type_descr
->xer
, p_buf
, flavor
, indent
, 0);
4474 ec
.set_msg("Component #0: ");
4476 // universal charstring does not have components.
4477 // TTCN code which could have generated embedded erroneous descriptor
4478 // should have failed semantic analysis.
4479 TTCN_error("internal error: embedded descriptor unexpected");
4481 // the "real" encoder
4482 if (q_uri
->is_present()) {
4483 p_buf
.put_s(11, (cbyte
*)" xmlns:b0='");
4484 sub_len
+= q_uri
->XER_encode(*xer_descr(0), p_buf
, flavor
| XER_LIST
, indent
+1, 0);
4490 if (ev
&& ev
->after
) {
4491 if (ev
->after
->errval
==NULL
) TTCN_error(
4492 "internal error: erroneous after value missing");
4493 ec
.set_msg("Erroneous value after component #0: ");
4494 if (ev
->after
->raw
) {
4495 sub_len
+= ev
->after
->errval
->encode_raw(p_buf
);
4497 if (ev
->after
->type_descr
==NULL
) TTCN_error(
4498 "internal error: erroneous after typedescriptor missing");
4499 sub_len
+= ev
->after
->errval
->XER_encode(
4500 *ev
->after
->type_descr
->xer
, p_buf
, flavor
, indent
, 0);
4504 if (p_td
.xer_bits
& XER_ATTRIBUTE
) begin_attribute(p_td
, p_buf
);
4505 else p_buf
.put_c('>');
4507 // Now switch to the second field (name)
4508 ev
= p_err_descr
->next_field_err_values(1, values_idx
);
4509 ed
= p_err_descr
->next_field_emb_descr (1, edescr_idx
);
4511 if (ev
&& ev
->before
) {
4512 if (ev
->before
->errval
==NULL
) TTCN_error(
4513 "internal error: erroneous before value missing");
4514 ec
.set_msg("Erroneous value before component #1: ");
4515 if (ev
->before
->raw
) {
4516 sub_len
+= ev
->before
->errval
->encode_raw(p_buf
);
4518 if (ev
->before
->type_descr
==NULL
) TTCN_error(
4519 "internal error: erroneous before typedescriptor missing");
4520 sub_len
+= ev
->before
->errval
->XER_encode(
4521 *ev
->before
->type_descr
->xer
, p_buf
, flavor
, indent
, 0);
4525 if (ev
&& ev
->value
) {
4526 if (ev
->value
->errval
) { // replace
4527 ec
.set_msg("Erroneous value for component #1: ");
4528 if (ev
->value
->raw
) {
4529 sub_len
+= ev
->value
->errval
->encode_raw(p_buf
);
4531 if (ev
->value
->type_descr
==NULL
) TTCN_error(
4532 "internal error: erroneous value typedescriptor missing");
4533 sub_len
+= ev
->value
->errval
->XER_encode(
4534 *ev
->value
->type_descr
->xer
, p_buf
, flavor
, indent
, 0);
4538 ec
.set_msg("Component #1: ");
4540 // universal charstring does not have components
4541 TTCN_error("internal error: embedded descriptor unexpected");
4543 // the "real" encoder
4544 if (q_uri
->is_present()) {
4545 p_buf
.put_s(3, (cbyte
*)"b0:");
4549 sub_len
+= get_at(1)->XER_encode(*xer_descr(1), p_buf
, flavor
| XER_LIST
, indent
+1, 0);
4553 if (ev
&& ev
->after
) {
4554 if (ev
->after
->errval
==NULL
) TTCN_error(
4555 "internal error: erroneous after value missing");
4556 ec
.set_msg("Erroneous value after component #1: ");
4557 if (ev
->after
->raw
) {
4558 sub_len
+= ev
->after
->errval
->encode_raw(p_buf
);
4560 if (ev
->after
->type_descr
==NULL
) TTCN_error(
4561 "internal error: erroneous after typedescriptor missing");
4562 sub_len
+= ev
->after
->errval
->XER_encode(
4563 *ev
->after
->type_descr
->xer
, p_buf
, flavor
, indent
, 0);
4567 if (p_td
.xer_bits
& XER_ATTRIBUTE
) p_buf
.put_c('\'');
4569 else { // not USE-QNAME
4570 if (!exer
&& (p_td
.xer_bits
& EMBED_VALUES
)) {
4571 // The EMBED-VALUES member as an ordinary record of string
4572 sub_len
+= embed_values
->XER_encode(*xer_descr(0), p_buf
, flavor
, indent
+1, 0);
4575 if (!exer
&& (p_td
.xer_bits
& USE_ORDER
)) {
4576 // The USE-ORDER member as an ordinary record of enumerated
4577 sub_len
+= use_order
->XER_encode(*xer_descr(uo_index
), p_buf
, flavor
, indent
+1, 0);
4580 if (exer
&& (indent
==0 || (flavor
& DEF_NS_SQUASHED
))) // write namespaces for toplevel only
4582 for (size_t cur_coll
= 0; cur_coll
< num_collected
; ++cur_coll
) {
4583 p_buf
.put_s(strlen(collected_ns
[cur_coll
]), (cbyte
*)collected_ns
[cur_coll
]);
4584 Free(collected_ns
[cur_coll
]); // job done
4590 flavor
&= ~DEF_NS_SQUASHED
;
4591 flavor
|= DEF_NS_PRESENT
;
4593 else if (empty_ns_hack
) {
4594 p_buf
.put_s(9, (cbyte
*)" xmlns=''");
4595 flavor
&= ~DEF_NS_PRESENT
;
4596 flavor
|= DEF_NS_SQUASHED
;
4599 // True if the non-attribute fields need to be omitted;
4600 // e.g. if USE_ORDER is in effect and the "nil" attribute was written
4601 // (then the record-of-enum for USE-ORDER will be empty),
4602 // or "omit all after" was hit while processing attributes.
4603 boolean early_to_bed
= FALSE
;
4605 // First all the attributes (not added to sub_len)
4607 for (i
= start_at
; i
< first_nonattr
; ++i
) {
4608 const Erroneous_values_t
* ev
=
4609 p_err_descr
->next_field_err_values(i
, values_idx
);
4610 const Erroneous_descriptor_t
* ed
=
4611 p_err_descr
->next_field_emb_descr(i
, edescr_idx
);
4613 if (i
< p_err_descr
->omit_before
) continue;
4615 boolean is_xer_attr_field
= xer_descr(i
)->xer_bits
& XER_ATTRIBUTE
;
4616 ec_1
.set_msg("%s': ", fld_name(i
)); // attr
4618 tmp_len
= encode_field(i
, ev
, ed
, p_buf
, flavor
, indent
+ !omit_tag
, 0);
4620 if (is_xer_attr_field
&& !exer
) sub_len
+= tmp_len
; // do not add if attribute and EXER
4622 // omit_after value -1 becomes "very big"
4623 if ((unsigned int)i
>= (unsigned int)p_err_descr
->omit_after
) {
4624 early_to_bed
= TRUE
; // no more fields to write
4629 // True if the "nil" attribute needs to be written.
4630 boolean nil_attribute
= FALSE
;
4631 // nil attribute unaffected by erroneous
4632 boolean nil_attribute_simple
= FALSE
;
4633 if (exer
&& (p_td
.xer_bits
& USE_NIL
)) {
4634 nil_attribute
= nil_attribute_simple
= !get_at(field_cnt
-1)->ispresent();
4636 if (p_err_descr
->values_size
> 0) // there is an erroneous "value := ..."
4638 const Erroneous_values_t
*ev_nil
=
4639 p_err_descr
->get_field_err_values(field_cnt
-1);
4640 if (ev_nil
&& ev_nil
->value
) // value override for the last field
4642 nil_attribute
= (ev_nil
->value
->errval
== NULL
);
4647 if (nil_attribute
) { // req. exer and USE_NIL
4648 const namespace_t
*control_ns
= p_td
.my_module
->get_controlns();
4650 if (!nil_attribute_simple
) {
4651 // It is likely that the declaration for namespace "xsi"
4652 // was not written. Do it now.
4653 p_buf
.put_s(7, (cbyte
*)" xmlns:");
4654 p_buf
.put_s(strlen(control_ns
->px
), (cbyte
*)control_ns
->px
);
4655 p_buf
.put_s(2, (cbyte
*)"='");
4656 p_buf
.put_s(strlen(control_ns
->ns
), (cbyte
*)control_ns
->ns
);
4661 p_buf
.put_s(strlen(control_ns
->px
), (cbyte
*)control_ns
->px
);
4663 p_buf
.put_s(10, (cbyte
*)"nil='true'");
4664 if ((p_td
.xer_bits
& USE_ORDER
)) early_to_bed
= TRUE
;
4665 // The whole content was omitted; nothing to do (and if we tried
4666 // to do it, we'd get an error for over-indexing a 0-length record-of).
4669 if (delay_close
&& (!omit_tag
|| shorter
)) {
4670 // Close the start tag left open. If indenting, also write a newline
4671 // unless USE-NIL in effect or there is a single untagged component.
4673 ((p_td
.xer_bits
& (/*USE_NIL|*/HAS_1UNTAGGED
)) ? 0 : indenting
);
4674 p_buf
.put_s(start_tag_len
, (cbyte
*)">\n");
4677 // Erroneous values for the embed_values member (if any).
4678 // Collected once but referenced multiple times.
4679 const Erroneous_descriptor_t
* ed0
= NULL
;
4680 int embed_values_val_idx
= 0;
4681 int embed_values_descr_idx
= 0;
4683 if (exer
&& (p_td
.xer_bits
& EMBED_VALUES
)) {
4684 ed0
= p_err_descr
->next_field_emb_descr(0, edescr_idx
);
4686 // write the first string
4687 if (embed_values
->size_of() > 0) {
4688 const Erroneous_values_t
* ev0_0
= NULL
;
4689 const Erroneous_descriptor_t
* ed0_0
= NULL
;
4691 ev0_0
= ed0
->next_field_err_values(0, embed_values_val_idx
);
4692 ed0_0
= ed0
->next_field_emb_descr (0, embed_values_descr_idx
);
4694 sub_len
+= embed_values
->encode_element(0, UNIVERSAL_CHARSTRING_xer_
,
4695 ev0_0
, ed0_0
, p_buf
, flavor
| EMBED_VALUES
, indent
+!omit_tag
, 0);
4699 const Record_Type
*ordered
= this; // the record affected by USE-ORDER
4700 // By default it's this record, unless USE_NIL is _also_ in effect,
4701 // in which case it's the last member of this.
4703 // Index of the first non-attribute field of the record pointed to by
4704 // ordered, that is, the first field affected by USE-ORDER.
4705 size_t useorder_base
= first_nonattr
;
4708 int end
= field_cnt
; // "one past", do not touch
4709 // by default, continue from the current field until the end, indexing this
4711 if (exer
&& (p_td
.xer_bits
& USE_ORDER
)) {
4712 // the length of the loop is determined by the length of use_order
4713 const int to_send
= use_order
->size_of();
4715 // i will index all elements of the use_order member
4719 // Count the non-attribute optionals
4720 int n_optionals
= 0;
4721 for (int B
= optional_count() - 1; B
>=+0; B
--) {
4722 int oi
= get_optional_indexes()[B
];
4723 if (oi
< first_nonattr
) break;
4727 int expected_min
= field_cnt
- first_nonattr
- n_optionals
;
4728 int expected_max
= field_cnt
- first_nonattr
;
4730 if ((p_td
.xer_bits
& USE_NIL
) && get_at(field_cnt
-1)->ispresent()) {
4731 // The special case when USE_ORDER refers to the fields of a field,
4733 const Base_Type
*last_optional
= get_at(field_cnt
-1);
4734 const Base_Type
* inner
= last_optional
->get_opt_value();
4735 // it absolutely, positively has to be (derived from) Record_Type
4736 ordered
= static_cast<const Record_Type
*>(inner
);
4737 useorder_base
= ordered
->get_xer_num_attr();
4738 begin
= useorder_base
;
4739 end
= ordered
->get_count();
4741 expected_min
= expected_max
= ordered
->get_count();
4744 if (to_send
> expected_max
4745 ||to_send
< expected_min
) {
4746 ec_1
.set_msg("%s': ", fld_name(uo_index
));
4747 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_CONSTRAINT
,
4748 "Wrong number of USE-ORDER %d, must be %d..%d", to_send
, expected_min
, expected_max
);
4749 early_to_bed
= TRUE
; // don't bother sending anything
4751 else { // check no duplicates
4752 int *seen
= new int [to_send
];
4754 for (int ei
= 0; ei
< to_send
; ++ei
) {
4755 const Base_Type
*uoe
= use_order
->get_at(ei
);
4756 const Enum_Type
*enm
= static_cast<const Enum_Type
*>(uoe
);
4757 int val
= enm
->as_int();
4758 for (int x
= 0; x
< num_seen
; ++x
) {
4759 if (val
== seen
[x
]) { // complain
4760 ec_1
.set_msg("%s': ", fld_name(uo_index
));
4761 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_CONSTRAINT
,
4762 "Duplicate value for USE-ORDER");
4763 early_to_bed
= TRUE
; // don't bother sending anything
4767 seen
[num_seen
++] = val
;
4771 // If the number is right and there are no duplicates, then carry on
4773 } // endif(USE_ORDER)
4775 // Then, all the non-attributes. Structuring the code like this depends on
4776 // all attributes appearing before all non-attributes (excluding
4777 // pseudo-members for USE-ORDER, etc.)
4779 // This loop handles both the normal case (no USE_ORDER) when i indexes
4780 // fields of this record; and the USE_ORDER case (with or without USE-NIL).
4782 // early_to_bed can only be true if exer is true (transitive through nil_attribute)
4783 if (!early_to_bed
) {
4784 embed_values_enc_struct_t
* emb_val
= 0;
4785 if (exer
&& (p_td
.xer_bits
& EMBED_VALUES
) && embed_values
->size_of() > 1) {
4786 emb_val
= new embed_values_enc_struct_t
;
4787 emb_val
->embval_array
= embed_values
;
4788 emb_val
->embval_index
= 1;
4789 emb_val
->embval_err
= ed0
;
4790 emb_val
->embval_err_val_idx
= embed_values_val_idx
;
4791 emb_val
->embval_err_descr_idx
= embed_values_descr_idx
;
4794 for ( i
= begin
; i
< end
; ++i
) {
4796 const Base_Type
*uoe
= 0; // "useOrder enum"
4797 const Enum_Type
*enm
= 0; // the enum value selecting the field
4799 // "actual" index, may be perturbed by USE-ORDER.
4800 // We use this value to index the appropriate record.
4803 const Erroneous_values_t
* ev
= NULL
;
4804 const Erroneous_descriptor_t
* ed
= NULL
;
4805 if (exer
&& use_order
) {
4806 // If USE-ORDER is in effect, it introduces a level of indirection
4807 // into the indexing of fields: "i" is used to select an element
4808 // of the use_order member (an enum), whose value is used to select
4809 // the field being encoded.
4810 uoe
= use_order
->get_at(i
- begin
);
4811 enm
= static_cast<const Enum_Type
*>(uoe
);
4812 ai
= enm
->as_int() + useorder_base
;
4814 // Because it is not guaranteed that ai will increase monotonically,
4815 // we can't use next_field_...().
4816 ev
= p_err_descr
->get_field_err_values(ai
);
4817 ed
= p_err_descr
->get_field_emb_descr (ai
);
4819 else { // not USE-ORDER, sequential access
4820 ev
= p_err_descr
->next_field_err_values(ai
, values_idx
);
4821 ed
= p_err_descr
->next_field_emb_descr (ai
, edescr_idx
);
4823 ec_1
.set_msg("%s': ", ordered
->fld_name(ai
)); // non-attr
4825 if (ai
< p_err_descr
->omit_before
) continue;
4827 // omit_after value -1 becomes "very big".
4828 if ((unsigned int)ai
> (unsigned int)p_err_descr
->omit_after
) continue;
4829 // We can't skip all fields with break, because the next ai may be lower
4832 sub_len
+= ordered
->encode_field(ai
, ev
, ed
, p_buf
,
4833 // Pass USE-NIL to the last field (except when USE-ORDER is also in effect,
4834 // because the tag-stripping effect of USE-NIL has been achieved
4835 // by encoding the sub-fields directly).
4836 flavor
| ((exer
&& !use_order
&& (i
== field_cnt
-1)) ? (p_td
.xer_bits
& USE_NIL
) : 0),
4837 indent
+ !omit_tag
, emb_val
);
4839 // Now the next embed-values string (NOT affected by USE-ORDER!)
4840 if (exer
&& (p_td
.xer_bits
& EMBED_VALUES
) && 0 != emb_val
&&
4841 emb_val
->embval_index
< embed_values
->size_of()) {
4842 const Erroneous_values_t
* ev0_i
= NULL
;
4843 const Erroneous_descriptor_t
* ed0_i
= NULL
;
4845 ev0_i
= ed0
->next_field_err_values(emb_val
->embval_index
, emb_val
->embval_err_val_idx
);
4846 ed0_i
= ed0
->next_field_emb_descr (emb_val
->embval_index
, emb_val
->embval_err_descr_idx
);
4848 embed_values
->encode_element(emb_val
->embval_index
, UNIVERSAL_CHARSTRING_xer_
,
4849 ev0_i
, ed0_i
, p_buf
, flavor
| EMBED_VALUES
, indent
+ !omit_tag
, 0);
4850 ++emb_val
->embval_index
;
4854 if (emb_val
->embval_index
< embed_values
->size_of()) {
4855 ec_1
.set_msg("%s': ", fld_name(0));
4856 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_CONSTRAINT
,
4857 "Too many EMBED-VALUEs specified: %d (expected %d or less)",
4858 embed_values
->size_of(), emb_val
->embval_index
);
4862 } // if (!early_to_bed)
4867 if (sub_len
) { // something was written, now an end tag
4868 if (indenting
&& !(exer
&& (p_td
.xer_bits
& (HAS_1UNTAGGED
| USE_QNAME
))))
4869 // The tags of the last optional member involved with USE_NIL
4870 // have been removed. If it was a simple type, the content was probably
4871 // written on a single line without anything resembling a close tag.
4872 // Do not indent our end tag in this case.
4873 switch ((int)(exer
&& (p_td
.xer_bits
& USE_NIL
))) {
4875 const unsigned char *buf_end
= p_buf
.get_data() + (p_buf
.get_len()-1);
4876 if (buf_end
[-1] != '>' || *buf_end
!= '\n') break;
4877 // If it does not look like an end tag, skip the indenting,
4878 // else fall through.
4881 do_indent(p_buf
, indent
);
4886 if (exer
) write_ns_prefix(p_td
, p_buf
);
4887 p_buf
.put_s((size_t)p_td
.namelens
[exer
]-!indenting
, (cbyte
*)p_td
.names
[exer
]);
4889 else { // need to generate an empty element tag
4890 p_buf
.increase_length(-start_tag_len
); // decrease length
4891 p_buf
.put_s((size_t)2+indenting
, (cbyte
*)"/>\n");
4895 return (int)p_buf
.get_len() - encoded_length
;
4898 int Record_Type::XER_decode(const XERdescriptor_t
& p_td
, XmlReaderWrap
& reader
,
4899 unsigned int flavor
, embed_values_dec_struct_t
*)
4902 int exer
= is_exer(flavor
);
4904 int depth
=-1; // depth of the start tag
4905 int xerbits
= p_td
.xer_bits
;
4906 if (flavor
& XER_TOPLEVEL
) xerbits
&= ~UNTAGGED
;
4907 const boolean own_tag
= !(exer
4908 && ( (xerbits
& (ANY_ELEMENT
| UNTAGGED
| XER_ATTRIBUTE
))
4909 || (flavor
& (USE_NIL
| USE_TYPE_ATTR
))));
4910 boolean tag_closed
= (flavor
& PARENT_CLOSED
) != 0;
4911 // If the parent has USE-TYPE, our ATTRIBUTE members can be found
4912 // in the parent's tag (the reader is sitting on it).
4913 const boolean parent_tag
= exer
&& (flavor
& (/*USE_NIL|*/ USE_TYPE_ATTR
));
4915 // Filter out flags passed by our parent. These are not for the fields.
4916 flavor
&= XER_MASK
; // also removes XER_TOPLEVEL
4918 const int field_cnt
= get_count();
4919 const int num_attributes
= get_xer_num_attr();
4921 // The index of potential "order" field, regardless of whether USE_ORDER
4922 // is in use or not.
4923 const int uo_index
= ((p_td
.xer_bits
& EMBED_VALUES
) !=0);
4925 // The first "non-special" field (skipping the USE-ORDER and EMBED-VALUES
4926 // fields); normal processing start at this field.
4927 const int start_at
= uo_index
+ ((p_td
.xer_bits
& USE_ORDER
) != 0);
4928 const int first_nonattr
= start_at
+ num_attributes
;
4930 // The index of the ANY-ATTRIBUTES member, if any
4932 for (int k
= 0; k
< first_nonattr
; ++k
) {
4933 if (xer_descr(k
)->xer_bits
& ANY_ATTRIBUTES
) {
4935 if (!get_at(aa_index
)->is_optional()) {
4936 static_cast<Record_Of_Type
*>(get_at(aa_index
))->set_size(0);
4938 break; // there can be only one, 18.2.2
4942 if (own_tag
) for (success
=reader
.Ok(); success
==1; success
=reader
.Read()) {
4943 type
= reader
.NodeType();
4944 if (type
==XML_READER_TYPE_ELEMENT
) {
4945 verify_name(reader
, p_td
, exer
);
4946 depth
= reader
.Depth();
4947 tag_closed
= reader
.IsEmptyElement();
4954 if (exer
&& (p_td
.xer_bits
& USE_QNAME
)) { // QName trumps everything !
4955 // If element, it looks like this:
4956 // <name xmlns:b0="http://www.furniture.com">b0:table</name>
4957 // If attribute, it looks like this:
4960 if (p_td
.xer_bits
& XER_ATTRIBUTE
) success
= 1; // do nothing
4961 else for (success
= reader
.Read(); success
== 1; success
= reader
.Read()) {
4962 type
= reader
.NodeType();
4963 if (type
== XML_READER_TYPE_TEXT
) break;
4967 xmlChar
*val
= reader
.NewValue();
4968 xmlChar
*npfx
= (xmlChar
*)strchr((char*)val
, ':');
4971 *npfx
++ = '\0'; // cut the string into two
4979 xmlChar
*nsu
= reader
.LookupNamespace(pfx
);
4981 OPTIONAL
<UNIVERSAL_CHARSTRING
> *q_prefix2
=
4982 static_cast<OPTIONAL
<UNIVERSAL_CHARSTRING
>*>(get_at(0));
4983 if (nsu
) *q_prefix2
= (const char*)nsu
;
4984 else q_prefix2
->set_to_omit(); // public in RT2 only
4986 UNIVERSAL_CHARSTRING
*q_name2
= static_cast<UNIVERSAL_CHARSTRING
*>(get_at(1));
4987 *q_name2
= (const char*)npfx
;
4993 else { // not use-qname
4994 TTCN_EncDec_ErrorContext
ec_0("Component '");
4995 TTCN_EncDec_ErrorContext ec_1
;
4996 boolean usenil_attribute
= FALSE
; // true if found and said yes
4998 if (!reader
.IsEmptyElement()) reader
.Read();
4999 // First, the (would-be) attributes (unaffected by USE-ORDER)
5000 for (i
= 0; i
< first_nonattr
; i
++) {
5001 ec_1
.set_msg("%s': ", fld_name(i
));
5002 get_at(i
)->XER_decode(*xer_descr(i
), reader
, flavor
, 0);
5005 else if (own_tag
|| parent_tag
) { // EXER and not UNTAGGED: do attributes
5006 // Prepare for lack of attributes.
5007 // Fields with defaultForEmpty get the D-F-E value, optional get omit.
5008 for (i
= start_at
; i
< first_nonattr
; i
++) {
5009 Base_Type
&fld
= *get_at(i
);
5010 const XERdescriptor_t
& xd
= *xer_descr(i
);
5012 if (fld
.is_optional()) {
5013 fld
.set_to_present();
5014 fld
.get_opt_value()->set_value(xd
.dfeValue
);
5016 else fld
.set_value(xd
.dfeValue
);
5018 else if (fld
.is_optional()) fld
.set_to_omit();
5021 int num_aa
= 0; // index into the ANY-ATTRIBUTE member
5023 const namespace_t
*control_ns
= 0;
5024 if (parent_tag
|| (p_td
.xer_bits
& USE_NIL
)) {
5025 // xsi:type or xsi:nil
5026 control_ns
= p_td
.my_module
->get_controlns();
5029 /* * * * * * * * * Attributes * * * * * * * * * * * * * */
5030 for (success
= reader
.MoveToFirstAttribute();
5031 success
== 1 && reader
.NodeType() == XML_READER_TYPE_ATTRIBUTE
;
5032 success
= reader
.AdvanceAttribute())
5034 if (reader
.IsNamespaceDecl()) {
5035 continue; // namespace declarations are handled for us by libxml2
5038 const char *attr_name
= (const char*)reader
.LocalName();
5039 const char *ns_uri
= (const char*)reader
.NamespaceUri();
5040 int field_index
= get_index_byname(attr_name
, ns_uri
);
5041 if (field_index
!= -1) {
5042 // There is a field. Let it decode the attribute.
5043 ec_1
.set_msg("%s': ", fld_name(field_index
));
5044 get_at(field_index
)->XER_decode(*xer_descr(field_index
), reader
, flavor
, 0);
5048 // Attribute not found. It could be the "nil" attribute
5049 if (p_td
.xer_bits
& USE_NIL
) {
5050 const char *prefix
= (const char*)reader
.Prefix();
5051 // prefix may be NULL, control_ns->px is never NULL or empty
5052 if (prefix
&& !strcmp(prefix
, control_ns
->px
)
5053 && !strcmp((const char*)reader
.LocalName(), "nil"))
5054 { // It is the "nil" attribute
5055 const char *value
= (const char*)reader
.Value();
5057 if (!strcmp(value
, "1") || !strcmp(value
, "true")) {
5058 // The field affected by USE-NIL is always the last one
5059 get_at(field_cnt
-1)->set_to_omit();
5060 usenil_attribute
= TRUE
;
5065 } // it is the "nil" attribute
5066 } // type has USE-NIL
5069 const char *prefix
= (const char*)reader
.Prefix();
5070 // prefix may be NULL, control_ns->px is never NULL or empty
5071 if (prefix
&& !strcmp(prefix
, control_ns
->px
)
5072 && !strcmp((const char*)reader
.LocalName(), "type")) {
5073 continue; // xsi:type has been processed by the parent
5077 if (aa_index
>= 0) {
5078 ec_1
.set_msg("%s': ", fld_name(aa_index
));
5079 TTCN_EncDec_ErrorContext
ec_2("Attribute %d: ", num_aa
);
5080 // We have a component with ANY-ATTRIBUTE. It must be a record of
5081 // UNIVERSAL_CHARSTRING. Add the attribute to it.
5082 Record_Of_Type
*aa
= 0;
5083 if (get_at(aa_index
)->is_optional()) {
5085 get_at(aa_index
)->set_to_present();
5087 aa
= static_cast<Record_Of_Type
*>(get_at(aa_index
)->get_opt_value());
5090 aa
= static_cast<Record_Of_Type
*>(get_at(aa_index
));
5092 UNIVERSAL_CHARSTRING
*new_elem
= static_cast<UNIVERSAL_CHARSTRING
*>
5093 (aa
->get_at(num_aa
++));
5095 // Construct the AnyAttributeFormat (X.693amd1, 18.2.6)
5097 const xmlChar
*name
= reader
.LocalName();
5098 const xmlChar
*val
= reader
.Value();
5099 const xmlChar
*uri
= reader
.NamespaceUri();
5101 if (xer_descr(aa_index
)->xer_bits
& (ANY_FROM
| ANY_EXCEPT
)) {
5102 check_namespace_restrictions(*xer_descr(aa_index
), (const char*)uri
);
5104 // We don't care about reader.Prefix()
5105 // Using strlen to count UTF8 bytes, not characters
5106 aabuf
.put_s(uri
? strlen((const char*)uri
) : 0, uri
);
5107 if (uri
&& *uri
) aabuf
.put_c(' ');
5108 aabuf
.put_s(name
? strlen((const char*)name
) : 0, name
);
5111 aabuf
.put_s(val
? strlen((const char*)val
) : 0, val
);
5113 new_elem
->decode_utf8(aabuf
.get_len(), aabuf
.get_data());
5118 // Lastly check for the xsi:schemaLocation attribute, this does not
5119 // affect TTCN-3, but it shouldn't cause a DTE
5120 if (reader
.LocalName() && !strcmp((const char*)reader
.LocalName(), "schemaLocation")) {
5122 control_ns
= p_td
.my_module
->get_controlns();
5124 if (reader
.Prefix() && !strcmp((const char*)reader
.Prefix(), control_ns
->px
)) {
5129 // Nobody wanted the attribute. That is an error.
5130 ec_0
.set_msg(" "); ec_1
.set_msg(" ");
5131 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG
,
5132 "Unexpected attribute '%s', ns '%s'", attr_name
,
5133 ns_uri
? ns_uri
: "");
5136 // Now check that all mandatory attributes have been set
5137 for (i
= start_at
; i
< first_nonattr
; ++i
) {
5138 Base_Type
* fld
= get_at(i
);
5139 if (fld
->is_optional()) continue; // field is allowed to be unset
5140 if (!fld
->is_bound()) {
5141 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG
,
5142 "Missing attribute '%s'", this->fld_name(i
));
5146 i
= first_nonattr
; // finished with attributes
5147 // AdvanceAttribute did MoveToElement. Move into the content (if any).
5148 if (!reader
.IsEmptyElement()) reader
.Read();
5149 } // end if (own_tag)
5151 /* * * * * * * * Non-attributes (elements) * * * * * * * * * * * */
5152 embed_values_dec_struct_t
* emb_val
= 0;
5153 if (exer
&& (p_td
.xer_bits
& EMBED_VALUES
)) {
5154 emb_val
= new embed_values_dec_struct_t
;
5155 emb_val
->embval_array
= static_cast<Record_Of_Type
*>(get_at(0));
5156 emb_val
->embval_array
->set_size(0);
5157 emb_val
->embval_index
= 0;
5160 if (exer
&& (p_td
.xer_bits
& USE_ORDER
)) {
5161 // Set all optional fields to omit because their respective XER_decode
5162 // will not be run (and will stay unbound) if the value is missing.
5163 int n_optionals
= 0;
5164 for (int B
= optional_count() - 1; B
>=+0; B
--) {
5165 int oi
= get_optional_indexes()[B
];
5166 if (oi
< first_nonattr
) break;
5167 get_at(oi
)->set_to_omit();
5170 Record_Of_Type
*use_order
= static_cast<Record_Of_Type
*>(get_at(uo_index
));
5171 // Initialize the use_order field to empty. Let it grow on demand.
5172 // (setting it to the minimum acceptable size may leave unbound elements
5173 // if the XML was incomplete).
5174 use_order
->set_size(0);
5176 Record_Type
*jumbled
= this; // the record affected by USE_ORDER
5177 int begin
= first_nonattr
;
5178 int end
= field_cnt
; // "one past"
5179 if (p_td
.xer_bits
& USE_NIL
) {
5180 Base_Type
*last_optional
= get_at(field_cnt
-1);
5181 if (!usenil_attribute
) { // exer known true
5182 last_optional
->set_to_present();
5183 jumbled
= static_cast<Record_Type
*>(last_optional
->get_opt_value());
5184 // We will operate on the members of last_optional,
5185 // effectively bypassing last_optional->XER_decode() itself.
5187 end
= jumbled
->get_count();
5188 ec_1
.set_msg("%s': ", fld_name(field_cnt
-1));
5191 if (num_attributes
> 0
5192 && first_nonattr
!= field_cnt
5193 && i
== first_nonattr
- 1) { // exer known true
5194 // If there were attributes and their processing just finished,
5195 // the reader is positioned on the start tag of the record.
5196 // Move ahead, unless there are no non-attribute fields.
5199 // Then, the non-attributes
5201 // The index runs over the members affected by USE-ORDER.
5202 // This is [first_nonattr,field_cnt) unless USE-NIL is involved,
5203 // in which case it's [0,optional_sequence::field_cnt)
5204 int *seen
= new int[end
-begin
];
5206 int last_any_elem
= begin
- 1;
5207 // The index of the latest embedded value can change outside of this function
5208 // (if the field is a untagged record of), in this case the next value should
5209 // be ignored, as it's already been handled by the record of
5210 int last_embval_index
= 0;
5211 for (i
= begin
; i
< end
; i
++) {
5212 for (success
= reader
.Ok(); success
== 1; success
= reader
.Read()) {
5213 type
= reader
.NodeType();
5214 if (0 != emb_val
&& reader
.NodeType()==XML_READER_TYPE_TEXT
) {
5215 UNIVERSAL_CHARSTRING
emb_ustr((const char*)reader
.Value());
5216 emb_val
->embval_array
->get_at(emb_val
->embval_index
)->set_value(&emb_ustr
);
5218 // The non-attribute components must not be UNTAGGED
5219 if (type
== XML_READER_TYPE_ELEMENT
) break;
5220 // else if (type==XML_READER_TYPE_END_ELEMENT) panic?
5223 if (last_embval_index
== emb_val
->embval_index
) {
5224 ++emb_val
->embval_index
;
5226 last_embval_index
= emb_val
->embval_index
;
5228 if (success
!= 1) break;
5229 const char *name
= (const char *)reader
.LocalName();
5230 boolean field_name_found
= false;
5231 // Find out which member it is.
5232 // FIXME some hashing should be implemented
5233 for (int k
= begin
; k
< end
; k
++) {
5234 if (!(jumbled
->xer_descr(k
)->xer_bits
& ANY_ELEMENT
) &&
5235 check_name(name
, *jumbled
->xer_descr(k
), 1)) {
5236 ec_1
.set_msg("%s': ", jumbled
->fld_name(k
));
5238 // Check for the same field being decoded twice.
5239 // We can't use the field's is_bound()/is_present(),
5240 // because the field may be bound on input, e.g. for
5241 // prototype(fast) or prototype(backtrack).
5242 int in_dex
= k
- begin
;
5243 for (int o
= 0; o
< num_seen
;++o
) {
5244 if (in_dex
== seen
[o
]) TTCN_EncDec_ErrorContext::error(
5245 TTCN_EncDec::ET_INVAL_MSG
, "Duplicate element");
5247 seen
[num_seen
++] = in_dex
;
5248 // Set the next use-order member.
5249 // Non-const get_at creates the object in the record-of.
5250 static_cast<Enum_Type
*>(use_order
->get_at(i
- begin
))
5252 Base_Type
*b
= jumbled
->get_at(k
);
5253 b
->XER_decode(*jumbled
->xer_descr(k
), reader
, flavor
, emb_val
);
5254 field_name_found
= true;
5258 if (!field_name_found
) {
5259 // Check the anyElement fields
5260 for (int k
= last_any_elem
+ 1; k
< end
; k
++) {
5261 if (jumbled
->xer_descr(k
)->xer_bits
& ANY_ELEMENT
) {
5262 ec_1
.set_msg("%s': ", jumbled
->fld_name(k
));
5264 // Check for the same field being decoded twice.
5265 // We can't use the field's is_bound()/is_present(),
5266 // because the field may be bound on input, e.g. for
5267 // prototype(fast) or prototype(backtrack).
5268 int in_dex
= k
- begin
;
5269 for (int o
= 0; o
< num_seen
;++o
) {
5270 if (in_dex
== seen
[o
]) TTCN_EncDec_ErrorContext::error(
5271 TTCN_EncDec::ET_INVAL_MSG
, "Duplicate element");
5273 seen
[num_seen
++] = in_dex
;
5274 // Set the next use-order member.
5275 // Non-const get_at creates the object in the record-of.
5276 static_cast<Enum_Type
*>(use_order
->get_at(i
- begin
))
5278 Base_Type
*b
= jumbled
->get_at(k
);
5279 b
->XER_decode(*jumbled
->xer_descr(k
), reader
, flavor
, emb_val
);
5287 if (reader
.NodeType()==XML_READER_TYPE_TEXT
) {
5288 UNIVERSAL_CHARSTRING
emb_ustr((const char*)reader
.Value());
5289 emb_val
->embval_array
->get_at(emb_val
->embval_index
)->set_value(&emb_ustr
);
5291 if (last_embval_index
== emb_val
->embval_index
) {
5292 ++emb_val
->embval_index
;
5296 ec_1
.set_msg(" "); // no active component
5299 // Check that we collected the required number of children
5300 int num_collected
= use_order
->size_of();
5301 if (p_td
.xer_bits
& USE_NIL
) {
5302 int expected
= usenil_attribute
? 0 : jumbled
->get_count();
5303 if (num_collected
!= expected
) {
5304 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INCOMPL_MSG
,
5305 "Incorrect number of fields %d, expected %d",
5306 num_collected
, expected
);
5310 if (num_collected
< field_cnt
- first_nonattr
- n_optionals
5311 ||num_collected
> field_cnt
- first_nonattr
) {
5312 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INCOMPL_MSG
,
5313 "Wrong number of fields! size = %d, expected %d..%d",
5314 use_order
->size_of(), field_cnt
- first_nonattr
- n_optionals
,
5315 field_cnt
- first_nonattr
);
5319 else { // not USE-ORDER, simpler code
5320 if (usenil_attribute
) {
5321 reader
.MoveToElement(); // value absent, nothing more to do
5323 // The index of the latest embedded value can change outside of this function
5324 // (if the field is a untagged record of), in this case the next value should
5325 // be ignored, as it's already been handled by the record of
5326 // Omitted fields can also reset this value
5327 int last_embval_index
= 0;
5328 for (; i
<field_cnt
; i
++) {
5330 if (reader
.NodeType()==XML_READER_TYPE_TEXT
) {
5331 UNIVERSAL_CHARSTRING
emb_ustr((const char*)reader
.Value());
5332 emb_val
->embval_array
->get_at(emb_val
->embval_index
)->set_value(&emb_ustr
);
5334 if (last_embval_index
== emb_val
->embval_index
) {
5335 ++emb_val
->embval_index
;
5337 last_embval_index
= emb_val
->embval_index
;
5339 ec_1
.set_msg("%s': ", fld_name(i
));
5340 if (exer
&& i
==field_cnt
-1 && p_td
.dfeValue
&& reader
.IsEmptyElement()) {
5341 get_at(i
)->set_value(p_td
.dfeValue
);
5344 // In case the field is an optional anyElement -> check if it should be omitted
5345 bool optional_any_elem_check
= true;
5346 if (get_at(i
)->is_optional() && (xer_descr(i
)->xer_bits
& ANY_ELEMENT
)) {
5347 // The "anyElement" coding instruction can only be applied to a universal charstring field
5348 OPTIONAL
<UNIVERSAL_CHARSTRING
>* opt_field
= dynamic_cast<OPTIONAL
<UNIVERSAL_CHARSTRING
>*>(get_at(i
));
5350 const char* next_field_name
= NULL
;
5351 if (i
< field_cnt
- 1) {
5352 next_field_name
= fld_name(i
+ 1);
5354 optional_any_elem_check
= opt_field
->XER_check_any_elem(reader
, next_field_name
, tag_closed
);
5357 if (optional_any_elem_check
) {
5358 int new_flavor
= flavor
;
5359 if (i
== field_cnt
-1) new_flavor
|= (p_td
.xer_bits
& USE_NIL
);
5360 if (tag_closed
) new_flavor
|= PARENT_CLOSED
;
5362 get_at(i
)->XER_decode(*xer_descr(i
), reader
, new_flavor
, emb_val
);
5365 if (!get_at(i
)->is_present()) {
5366 // there was no new element, the last embedded value is for the next field
5367 // (or the end of the record if this is the last field)
5368 last_embval_index
= -1;
5372 if (reader
.NodeType()==XML_READER_TYPE_TEXT
) {
5373 UNIVERSAL_CHARSTRING
emb_ustr((const char*)reader
.Value());
5374 emb_val
->embval_array
->get_at(emb_val
->embval_index
)->set_value(&emb_ustr
);
5376 if (last_embval_index
== emb_val
->embval_index
) {
5377 ++emb_val
->embval_index
;
5384 static const UNIVERSAL_CHARSTRING
emptystring(0, (const char*)NULL
);
5385 for (int j
= 0; j
< emb_val
->embval_index
; ++j
) {
5386 if (!emb_val
->embval_array
->get_at(j
)->is_bound()) {
5387 emb_val
->embval_array
->get_at(j
)->set_value(&emptystring
);
5391 } // if embed-values
5396 // We had our start tag. Then our fields did their thing.
5397 // Now we expect the end tag. And it better be our end tag!
5399 for (success
= reader
.Ok(); success
== 1; success
= reader
.Read()) {
5400 type
= reader
.NodeType();
5401 current_depth
= reader
.Depth();
5402 if (current_depth
> depth
) {
5403 if (XML_READER_TYPE_ELEMENT
== type
) {
5404 // We found a deeper start tag; it was not processed at all.
5405 // That is an error (maybe we should report error for all node types
5406 // except TEXT and WHITESPACE, not just ELEMENT).
5407 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TAG
,
5408 "Unprocessed XML tag `%s'", (const char *)reader
.Name());
5411 continue; // go past hoping that our end tag will arrive eventually
5413 else if (current_depth
== depth
) { // at our level
5414 if (XML_READER_TYPE_ELEMENT
== type
) {
5415 verify_name(reader
, p_td
, exer
);
5416 if (reader
.IsEmptyElement()) {
5417 // FIXME this shouldn't really be possible;
5418 // only an empty record should be encoded as an empty element,
5419 // but those are implemented by Empty_Record_Type, not Record_Type.
5420 reader
.Read(); // one last time
5424 // If we find an end tag at the right depth, it must be ours
5425 else if (XML_READER_TYPE_END_ELEMENT
== type
) {
5426 verify_end(reader
, p_td
, depth
, exer
);
5431 else { //current_depth < depth; something has gone horribly wrong
5432 break; // better quit before we do further damage
5433 // Don't report an error; every enclosing type would do so,
5434 // spewing the same message over and over.
5438 return 1; // decode successful
5441 int Record_Type::JSON_encode(const TTCN_Typedescriptor_t
&, JSON_Tokenizer
& p_tok
) const
5444 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND
,
5445 "Encoding an unbound %s value.", is_set() ? "set" : "record");
5449 int enc_len
= p_tok
.put_next_token(JSON_TOKEN_OBJECT_START
, NULL
);
5451 int field_count
= get_count();
5452 for(int i
= 0; i
< field_count
; ++i
) {
5453 if ((NULL
!= fld_descr(i
)->json
&& fld_descr(i
)->json
->omit_as_null
) ||
5454 !get_at(i
)->is_optional() || get_at(i
)->is_present()) {
5455 if (NULL
!= fld_descr(i
)->json
&& NULL
!= fld_descr(i
)->json
->alias
) {
5456 enc_len
+= p_tok
.put_next_token(JSON_TOKEN_NAME
, fld_descr(i
)->json
->alias
);
5458 enc_len
+= p_tok
.put_next_token(JSON_TOKEN_NAME
, fld_name(i
));
5460 enc_len
+= get_at(i
)->JSON_encode(*fld_descr(i
), p_tok
);
5464 enc_len
+= p_tok
.put_next_token(JSON_TOKEN_OBJECT_END
, NULL
);
5468 int Record_Type::JSON_decode(const TTCN_Typedescriptor_t
& p_td
, JSON_Tokenizer
& p_tok
, boolean p_silent
)
5470 json_token_t token
= JSON_TOKEN_NONE
;
5471 int dec_len
= p_tok
.get_next_token(&token
, NULL
, NULL
);
5472 if (JSON_TOKEN_ERROR
== token
) {
5473 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG
, JSON_DEC_BAD_TOKEN_ERROR
, "");
5474 return JSON_ERROR_FATAL
;
5476 else if (JSON_TOKEN_OBJECT_START
!= token
) {
5477 return JSON_ERROR_INVALID_TOKEN
;
5481 const int field_count
= get_count();
5484 // Read name - value token pairs until we reach some other token
5486 size_t name_len
= 0;
5487 size_t buf_pos
= p_tok
.get_buf_pos();
5488 dec_len
+= p_tok
.get_next_token(&token
, &name
, &name_len
);
5489 if (JSON_TOKEN_ERROR
== token
) {
5490 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG
, JSON_DEC_BAD_TOKEN_ERROR
, "");
5491 return JSON_ERROR_FATAL
;
5493 else if (JSON_TOKEN_NAME
!= token
) {
5494 // undo the last action on the buffer
5495 p_tok
.set_buf_pos(buf_pos
);
5501 for (field_idx
= 0; field_idx
< field_count
; ++field_idx
) {
5502 const char* expected_name
= 0;
5503 if (NULL
!= fld_descr(field_idx
)->json
&& NULL
!= fld_descr(field_idx
)->json
->alias
) {
5504 expected_name
= fld_descr(field_idx
)->json
->alias
;
5506 expected_name
= fld_name(field_idx
);
5508 if (strlen(expected_name
) == name_len
&&
5509 0 == strncmp(expected_name
, name
, name_len
)) {
5513 if (field_count
== field_idx
) {
5514 // invalid field name
5515 char* name2
= mcopystrn(name
, name_len
);
5516 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG
, JSON_DEC_INVALID_NAME_ERROR
, name2
);
5517 // if this is set to a warning, skip the value of the field
5518 dec_len
+= p_tok
.get_next_token(&token
, NULL
, NULL
);
5519 if (JSON_TOKEN_NUMBER
!= token
&& JSON_TOKEN_STRING
!= token
&&
5520 JSON_TOKEN_LITERAL_TRUE
!= token
&& JSON_TOKEN_LITERAL_FALSE
!= token
&&
5521 JSON_TOKEN_LITERAL_NULL
!= token
) {
5522 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG
, JSON_DEC_FIELD_TOKEN_ERROR
, name2
);
5524 return JSON_ERROR_FATAL
;
5530 int ret_val
= get_at(field_idx
)->JSON_decode(*fld_descr(field_idx
), p_tok
, p_silent
);
5532 if (JSON_ERROR_INVALID_TOKEN
) {
5533 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG
, JSON_DEC_FIELD_TOKEN_ERROR
, fld_name(field_idx
));
5535 return JSON_ERROR_FATAL
;
5541 dec_len
+= p_tok
.get_next_token(&token
, NULL
, NULL
);
5542 if (JSON_TOKEN_OBJECT_END
!= token
) {
5543 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG
, JSON_DEC_OBJECT_END_TOKEN_ERROR
, "");
5544 return JSON_ERROR_FATAL
;
5547 // Check if every field has been set
5548 for (int field_idx
= 0; field_idx
< field_count
; ++field_idx
) {
5549 Base_Type
* field
= get_at(field_idx
);
5550 if (!field
->is_bound()) {
5551 if (NULL
!= fld_descr(field_idx
)->json
&& NULL
!= fld_descr(field_idx
)->json
->default_value
) {
5552 get_at(field_idx
)->JSON_decode(*fld_descr(field_idx
), DUMMY_BUFFER
, p_silent
);
5554 else if (field
->is_optional()) {
5555 field
->set_to_omit();
5557 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG
, JSON_DEC_MISSING_FIELD_ERROR
, fld_name(field_idx
));
5558 return JSON_ERROR_FATAL
;
5566 ////////////////////////////////////////////////////////////////////////////////
5568 Empty_Record_Type::Empty_Record_Type(): bound_flag(FALSE
)
5572 Empty_Record_Type::Empty_Record_Type(const Empty_Record_Type
& other_value
)
5573 : Base_Type(other_value
), bound_flag(other_value
.bound_flag
)
5575 if (!other_value
.bound_flag
)
5576 TTCN_error("Copying an unbound value of type %s.",
5577 other_value
.get_descriptor()->name
);
5580 boolean
Empty_Record_Type::operator==(null_type
) const
5583 TTCN_error("Comparison of an unbound value of type %s.",
5584 get_descriptor()->name
);
5588 void Empty_Record_Type::log() const
5590 if (bound_flag
) TTCN_Logger::log_event_str("{ }");
5591 else TTCN_Logger::log_event_unbound();
5594 void Empty_Record_Type::set_param(Module_Param
& param
) {
5595 param
.basic_check(Module_Param::BC_VALUE
, "empty record/set value (i.e. { })");
5596 if (param
.get_type()!=Module_Param::MP_Value_List
|| param
.get_size()>0) {
5597 param
.type_error("empty record/set value (i.e. { })", get_descriptor()->name
);
5602 void Empty_Record_Type::encode_text(Text_Buf
& /*text_buf*/) const
5605 TTCN_error("Text encoder: Encoding an unbound value of type %s.",
5606 get_descriptor()->name
);
5609 void Empty_Record_Type::decode_text(Text_Buf
& /*text_buf*/)
5614 boolean
Empty_Record_Type::is_equal(const Base_Type
* other_value
) const
5616 const Empty_Record_Type
* r2
= static_cast<const Empty_Record_Type
*>(other_value
);
5617 if ((bound_flag
&& r2
->bound_flag
) || (!bound_flag
&& !r2
->bound_flag
))
5619 if (!bound_flag
|| !r2
->bound_flag
)
5620 TTCN_error("Comparison of an unbound value of type %s.", get_descriptor()->name
);
5624 void Empty_Record_Type::set_value(const Base_Type
* other_value
)
5626 if (!static_cast<const Empty_Record_Type
*>(other_value
)->is_bound())
5627 TTCN_error("Assignment of an unbound value of type %s.",
5628 other_value
->get_descriptor()->name
);
5632 void Empty_Record_Type::encode(const TTCN_Typedescriptor_t
& p_td
,
5633 TTCN_Buffer
& p_buf
, TTCN_EncDec::coding_t p_coding
, ...) const
5636 va_start(pvar
, p_coding
);
5638 case TTCN_EncDec::CT_BER
: {
5639 TTCN_EncDec_ErrorContext
ec("While BER-encoding type '%s': ", p_td
.name
);
5640 unsigned BER_coding
=va_arg(pvar
, unsigned);
5641 BER_encode_chk_coding(BER_coding
);
5642 ASN_BER_TLV_t
*tlv
=BER_encode_TLV(p_td
, BER_coding
);
5643 tlv
->put_in_buffer(p_buf
);
5644 ASN_BER_TLV_t::destruct(tlv
);
5646 case TTCN_EncDec::CT_RAW
: {
5647 TTCN_EncDec_ErrorContext
ec("While RAW-encoding type '%s': ", p_td
.name
);
5648 if(!p_td
.raw
) TTCN_EncDec_ErrorContext::error_internal
5649 ("No RAW descriptor available for type '%s'.", p_td
.name
);
5653 RAW_enc_tree
root(FALSE
, NULL
, &rp
, 1, p_td
.raw
);
5654 RAW_encode(p_td
, root
);
5655 root
.put_to_buf(p_buf
);
5657 case TTCN_EncDec::CT_TEXT
: {
5658 TTCN_EncDec_ErrorContext
ec("While TEXT-encoding type '%s': ", p_td
.name
);
5659 if(!p_td
.text
) TTCN_EncDec_ErrorContext::error_internal
5660 ("No TEXT descriptor available for type '%s'.", p_td
.name
);
5661 TEXT_encode(p_td
,p_buf
);
5663 case TTCN_EncDec::CT_XER
: {
5664 TTCN_EncDec_ErrorContext
ec("While XER-encoding type '%s': ", p_td
.name
);
5665 unsigned XER_coding
=va_arg(pvar
, unsigned);
5666 XER_encode(*(p_td
.xer
),p_buf
, XER_coding
, 0, 0);
5669 case TTCN_EncDec::CT_JSON
: {
5670 TTCN_EncDec_ErrorContext
ec("While JSON-encoding type '%s': ", p_td
.name
);
5671 if(!p_td
.json
) TTCN_EncDec_ErrorContext::error_internal
5672 ("No JSON descriptor available for type '%s'.", p_td
.name
);
5673 JSON_Tokenizer
tok(va_arg(pvar
, int) != 0);
5674 JSON_encode(p_td
, tok
);
5675 p_buf
.put_s(tok
.get_buffer_length(), (const unsigned char*)tok
.get_buffer());
5678 TTCN_error("Unknown coding method requested to encode type '%s'", p_td
.name
);
5683 void Empty_Record_Type::decode(const TTCN_Typedescriptor_t
& p_td
,
5684 TTCN_Buffer
& p_buf
, TTCN_EncDec::coding_t p_coding
, ...)
5687 va_start(pvar
, p_coding
);
5689 case TTCN_EncDec::CT_BER
: {
5690 TTCN_EncDec_ErrorContext
ec("While BER-decoding type '%s': ", p_td
.name
);
5691 unsigned L_form
=va_arg(pvar
, unsigned);
5693 BER_decode_str2TLV(p_buf
, tlv
, L_form
);
5694 BER_decode_TLV(p_td
, tlv
, L_form
);
5695 if(tlv
.isComplete
) p_buf
.increase_pos(tlv
.get_len());
5697 case TTCN_EncDec::CT_RAW
: {
5698 TTCN_EncDec_ErrorContext
ec("While RAW-decoding type '%s': ", p_td
.name
);
5700 TTCN_EncDec_ErrorContext::error_internal
5701 ("No RAW descriptor available for type '%s'.", p_td
.name
);
5703 switch(p_td
.raw
->top_bit_order
) {
5711 if(RAW_decode(p_td
, p_buf
, p_buf
.get_len()*8, order
)<0)
5712 ec
.error(TTCN_EncDec::ET_INCOMPL_MSG
,
5713 "Can not decode type '%s', because invalid or incomplete"
5714 " message was received", p_td
.name
);
5716 case TTCN_EncDec::CT_TEXT
: {
5717 Limit_Token_List limit
;
5718 TTCN_EncDec_ErrorContext
ec("While TEXT-decoding type '%s': ", p_td
.name
);
5719 if(!p_td
.text
) TTCN_EncDec_ErrorContext::error_internal
5720 ("No TEXT descriptor available for type '%s'.", p_td
.name
);
5721 const unsigned char *b
=p_buf
.get_data();
5722 if(b
[p_buf
.get_len()-1]!='\0'){
5723 p_buf
.set_pos(p_buf
.get_len());
5724 p_buf
.put_zero(8,ORDER_LSB
);
5727 if(TEXT_decode(p_td
,p_buf
,limit
)<0)
5728 ec
.error(TTCN_EncDec::ET_INCOMPL_MSG
,
5729 "Can not decode type '%s', because invalid or incomplete"
5730 " message was received", p_td
.name
);
5732 case TTCN_EncDec::CT_XER
: {
5733 TTCN_EncDec_ErrorContext
ec("While XER-decoding type '%s': ", p_td
.name
);
5734 unsigned XER_coding
=va_arg(pvar
, unsigned);
5735 XmlReaderWrap
reader(p_buf
);
5736 for (int success
=reader
.Read(); success
==1; success
=reader
.Read()) {
5737 if (reader
.NodeType() == XML_READER_TYPE_ELEMENT
) break;
5739 XER_decode(*(p_td
.xer
), reader
, XER_coding
| XER_TOPLEVEL
, 0);
5740 size_t bytes
= reader
.ByteConsumed();
5741 p_buf
.set_pos(bytes
);
5743 case TTCN_EncDec::CT_JSON
: {
5744 TTCN_EncDec_ErrorContext
ec("While JSON-decoding type '%s': ", p_td
.name
);
5745 if(!p_td
.json
) TTCN_EncDec_ErrorContext::error_internal
5746 ("No JSON descriptor available for type '%s'.", p_td
.name
);
5747 JSON_Tokenizer
tok((const char*)p_buf
.get_data(), p_buf
.get_len());
5748 if(JSON_decode(p_td
, tok
, false)<0)
5749 ec
.error(TTCN_EncDec::ET_INCOMPL_MSG
,
5750 "Can not decode type '%s', because invalid or incomplete"
5751 " message was received", p_td
.name
);
5752 p_buf
.set_pos(tok
.get_buf_pos());
5755 TTCN_error("Unknown coding method requested to decode type '%s'", p_td
.name
);
5760 ASN_BER_TLV_t
* Empty_Record_Type::BER_encode_TLV(const TTCN_Typedescriptor_t
& p_td
,
5761 unsigned p_coding
) const
5763 BER_chk_descr(p_td
);
5764 ASN_BER_TLV_t
*new_tlv
=ASN_BER_TLV_t::construct(NULL
);
5765 new_tlv
=ASN_BER_V2TLV(new_tlv
, p_td
, p_coding
);
5769 boolean
Empty_Record_Type::BER_decode_TLV(const TTCN_Typedescriptor_t
& p_td
,
5770 const ASN_BER_TLV_t
& p_tlv
, unsigned L_form
)
5772 BER_chk_descr(p_td
);
5773 ASN_BER_TLV_t stripped_tlv
;
5774 BER_decode_strip_tags(*p_td
.ber
, p_tlv
, L_form
, stripped_tlv
);
5775 TTCN_EncDec_ErrorContext
ec_0("While decoding '%s' type: ", get_descriptor()->name
);
5776 stripped_tlv
.chk_constructed_flag(TRUE
);
5781 int Empty_Record_Type::RAW_encode(const TTCN_Typedescriptor_t
& p_td
,
5782 RAW_enc_tree
& /*myleaf*/) const
5784 if (!bound_flag
) TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND
,
5785 "Encoding an unbound value of type %s.", p_td
.name
);
5789 int Empty_Record_Type::RAW_decode(const TTCN_Typedescriptor_t
& p_td
,
5790 TTCN_Buffer
& buff
, int /*limit*/, raw_order_t
/*top_bit_ord*/,
5791 boolean
/*no_err*/, int /*sel_field*/, boolean
/*first_call*/)
5794 return buff
.increase_pos_padd(p_td
.raw
->prepadding
)
5795 + buff
.increase_pos_padd(p_td
.raw
->padding
);
5798 int Empty_Record_Type::TEXT_encode(const TTCN_Typedescriptor_t
& p_td
, TTCN_Buffer
& buff
) const
5800 int encoded_length
=0;
5801 if(p_td
.text
->begin_encode
) {
5802 buff
.put_cs(*p_td
.text
->begin_encode
);
5803 encoded_length
+=p_td
.text
->begin_encode
->lengthof();
5806 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND
, "Encoding an unbound value.");
5808 if(p_td
.text
->end_encode
) {
5809 buff
.put_cs(*p_td
.text
->end_encode
);
5810 encoded_length
+=p_td
.text
->end_encode
->lengthof();
5812 return encoded_length
;
5815 int Empty_Record_Type::TEXT_decode(const TTCN_Typedescriptor_t
& p_td
,
5816 TTCN_Buffer
& buff
, Limit_Token_List
& /*limit*/, boolean no_err
, boolean
/*first_call*/)
5818 int decoded_length
=0;
5819 if(p_td
.text
->begin_decode
) {
5821 if((tl
=p_td
.text
->begin_decode
->match_begin(buff
))<0) {
5822 if(no_err
)return -1;
5823 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR
,
5824 "The specified token '%s' not found for '%s': ",
5825 (const char*)*(p_td
.text
->begin_decode
), p_td
.name
);
5829 buff
.increase_pos(tl
);
5831 if(p_td
.text
->end_decode
) {
5833 if((tl
=p_td
.text
->end_decode
->match_begin(buff
))<0) {
5834 if(no_err
)return -1;
5835 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR
,
5836 "The specified token '%s' not found for '%s': ",
5837 (const char*)*(p_td
.text
->end_decode
), p_td
.name
);
5841 buff
.increase_pos(tl
);
5844 return decoded_length
;
5847 int Empty_Record_Type::XER_encode(const XERdescriptor_t
& p_td
,
5848 TTCN_Buffer
& p_buf
, unsigned int flavor
, int indent
, embed_values_enc_struct_t
*) const
5850 int encoded_length
=(int)p_buf
.get_len();
5851 int indenting
= !is_canonical(flavor
);
5852 int exer
= is_exer(flavor
);
5853 if (indenting
) do_indent(p_buf
, indent
);
5855 if (exer
) write_ns_prefix(p_td
, p_buf
);
5856 p_buf
.put_s((size_t)p_td
.namelens
[exer
]-2, (cbyte
*)p_td
.names
[exer
]);
5857 p_buf
.put_s(2 + indenting
, (cbyte
*)"/>\n");
5858 return (int)p_buf
.get_len() - encoded_length
;
5861 int Empty_Record_Type::XER_decode(const XERdescriptor_t
& p_td
,
5862 XmlReaderWrap
& reader
, unsigned int flavor
, embed_values_dec_struct_t
*)
5864 int exer
= is_exer(flavor
);
5866 int success
, depth
= -1;
5867 for (success
=reader
.Ok(); success
==1; success
=reader
.Read()) {
5868 int type
= reader
.NodeType();
5869 if (type
==XML_READER_TYPE_ELEMENT
) {
5870 verify_name(reader
, p_td
, exer
);
5871 depth
= reader
.Depth();
5873 if (reader
.IsEmptyElement()) {
5874 reader
.Read(); break;
5876 else if ((flavor
& XER_MASK
) == XER_CANONICAL
) {
5877 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG
,
5878 "Expected an empty element tag");
5879 // Stay in the loop and look for the end element, in case the error
5880 // was ignored or reduced to warning.
5883 else if (type
== XML_READER_TYPE_END_ELEMENT
&& depth
!= -1) {
5884 verify_end(reader
, p_td
, depth
, exer
);
5889 return 1; // decode successful
5892 int Empty_Record_Type::JSON_encode(const TTCN_Typedescriptor_t
&, JSON_Tokenizer
& p_tok
) const
5895 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND
,
5896 "Encoding an unbound empty %s value.", is_set() ? "set" : "record");
5900 return p_tok
.put_next_token(JSON_TOKEN_OBJECT_START
, NULL
) +
5901 p_tok
.put_next_token(JSON_TOKEN_OBJECT_END
, NULL
);
5904 int Empty_Record_Type::JSON_decode(const TTCN_Typedescriptor_t
&, JSON_Tokenizer
& p_tok
, boolean p_silent
)
5906 json_token_t token
= JSON_TOKEN_NONE
;
5907 int dec_len
= p_tok
.get_next_token(&token
, NULL
, NULL
);
5908 if (JSON_TOKEN_ERROR
== token
) {
5909 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG
, JSON_DEC_BAD_TOKEN_ERROR
, "");
5910 return JSON_ERROR_FATAL
;
5912 else if (JSON_TOKEN_OBJECT_START
!= token
) {
5913 return JSON_ERROR_INVALID_TOKEN
;
5916 dec_len
+= p_tok
.get_next_token(&token
, NULL
, NULL
);
5917 if (JSON_TOKEN_OBJECT_END
!= token
) {
5918 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG
, JSON_DEC_STATIC_OBJECT_END_TOKEN_ERROR
, "");
5919 return JSON_ERROR_FATAL
;
5927 boolean
operator==(null_type
/*null_value*/, const Empty_Record_Type
& other_value
)
5929 if (!other_value
.is_bound())
5930 TTCN_error("Comparison of an unbound value of type %s.",
5931 other_value
.get_descriptor()->name
);
5935 boolean
operator!=(null_type
/*null_value*/, const Empty_Record_Type
& other_value
)
5937 if (!other_value
.is_bound())
5938 TTCN_error("Comparison of an unbound value of type %s.",
5939 other_value
.get_descriptor()->name
);