1 /******************************************************************************
2 * Copyright (c) 2000-2016 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
20 ******************************************************************************/
21 #include "Basetype.hh"
27 #include "Module_list.hh"
31 #ifdef TITAN_RUNTIME_2
34 #include "Charstring.hh"
35 #include "Universal_charstring.hh"
37 #include "PreGenRecordOf.hh"
39 ////////////////////////////////////////////////////////////////////////////////
41 const Erroneous_values_t
* Erroneous_descriptor_t::get_field_err_values(int field_idx
) const
43 for (int i
=0; i
<values_size
; i
++) {
44 if (values_vec
[i
].field_index
==field_idx
) return (values_vec
+i
);
45 if (values_vec
[i
].field_index
>field_idx
) return NULL
;
50 const Erroneous_values_t
* Erroneous_descriptor_t::next_field_err_values(
51 const int field_idx
, int& values_idx
) const
53 const Erroneous_values_t
* err_vals
= NULL
;
54 if ( (values_idx
<values_size
) && (values_vec
[values_idx
].field_index
==field_idx
) ) {
55 err_vals
= values_vec
+values_idx
;
61 const Erroneous_descriptor_t
* Erroneous_descriptor_t::get_field_emb_descr(int field_idx
) const
63 for (int i
=0; i
<embedded_size
; i
++) {
64 if (embedded_vec
[i
].field_index
==field_idx
) return (embedded_vec
+i
);
65 if (embedded_vec
[i
].field_index
>field_idx
) return NULL
;
70 const Erroneous_descriptor_t
* Erroneous_descriptor_t::next_field_emb_descr(
71 const int field_idx
, int& edescr_idx
) const
73 const Erroneous_descriptor_t
* emb_descr
= NULL
;
74 if ( (edescr_idx
<embedded_size
) && (embedded_vec
[edescr_idx
].field_index
==field_idx
) ) {
75 emb_descr
= embedded_vec
+edescr_idx
;
81 void Erroneous_descriptor_t::log() const
83 TTCN_Logger::log_event_str(" with erroneous { ");
85 TTCN_Logger::log_event_str("}");
88 void Erroneous_descriptor_t::log_() const
90 if (omit_before
!=-1) {
91 if (omit_before_qualifier
==NULL
) TTCN_error(
92 "internal error: Erroneous_descriptor_t::log()");
93 TTCN_Logger::log_event("{ before %s := omit all } ", omit_before_qualifier
);
96 if (omit_after_qualifier
==NULL
) TTCN_error(
97 "internal error: Erroneous_descriptor_t::log()");
98 TTCN_Logger::log_event("{ after %s := omit all } ", omit_after_qualifier
);
100 for (int i
=0; i
<values_size
; i
++) {
101 if (values_vec
[i
].field_qualifier
==NULL
) TTCN_error(
102 "internal error: Erroneous_descriptor_t::log()");
103 if (values_vec
[i
].before
) {
104 TTCN_Logger::log_event("{ before%s %s := ",
105 values_vec
[i
].before
->raw
? "(raw)" : "", values_vec
[i
].field_qualifier
);
106 if (values_vec
[i
].before
->errval
) values_vec
[i
].before
->errval
->log();
107 else TTCN_Logger::log_event_str("omit");
108 TTCN_Logger::log_event_str(" } ");
110 if (values_vec
[i
].value
) {
111 TTCN_Logger::log_event("{ value%s %s := ",
112 values_vec
[i
].value
->raw
? "(raw)" : "", values_vec
[i
].field_qualifier
);
113 if (values_vec
[i
].value
->errval
) values_vec
[i
].value
->errval
->log();
114 else TTCN_Logger::log_event_str("omit");
115 TTCN_Logger::log_event_str(" } ");
117 if (values_vec
[i
].after
) {
118 TTCN_Logger::log_event("{ after%s %s := ",
119 values_vec
[i
].after
->raw
? "(raw)" : "", values_vec
[i
].field_qualifier
);
120 if (values_vec
[i
].after
->errval
) values_vec
[i
].after
->errval
->log();
121 else TTCN_Logger::log_event_str("omit");
122 TTCN_Logger::log_event_str(" } ");
125 for (int i
=0; i
<embedded_size
; i
++) {
126 embedded_vec
[i
].log_();
130 void Base_Type::set_to_omit()
132 TTCN_error("Internal error: trying to set a non-optional field to OMIT.");
135 void Base_Type::set_to_present()
137 TTCN_error("Internal error: calling set_to_present() on a non-optional value.");
140 boolean
Base_Type::is_present() const
145 Base_Type
* Base_Type::get_opt_value()
147 TTCN_error("Internal error: calling get_opt_value() on a non-optional value.");
151 const Base_Type
* Base_Type::get_opt_value() const
153 TTCN_error("Internal error: calling get_opt_value() const on a non-optional value.");
157 ASN_BER_TLV_t
* Base_Type::BER_encode_TLV_negtest(const Erroneous_descriptor_t
* /*p_err_descr*/,
158 const TTCN_Typedescriptor_t
& /*p_td*/, unsigned /*p_coding*/) const
160 TTCN_error("Internal error: calling Base_Type::BER_encode_TLV_negtest().");
164 int Base_Type::TEXT_encode_negtest(const Erroneous_descriptor_t
* /*p_err_descr*/,
165 const TTCN_Typedescriptor_t
& /*p_td*/, TTCN_Buffer
& /*p_buf*/) const
167 TTCN_error("Internal error: calling Base_Type::TEXT_encode_negtest().");
171 ASN_BER_TLV_t
* Base_Type::BER_encode_negtest_raw() const
173 TTCN_error("A value of type %s cannot be used as erroneous raw value for BER encoding.",
174 get_descriptor()->name
);
178 int Base_Type::encode_raw(TTCN_Buffer
&) const
180 TTCN_error("A value of type %s cannot be used as erroneous raw value for encoding.",
181 get_descriptor()->name
);
185 int Base_Type::RAW_encode_negtest_raw(RAW_enc_tree
&) const
187 TTCN_error("A value of type %s cannot be used as erroneous raw value for encoding.",
188 get_descriptor()->name
);
192 int Base_Type::JSON_encode_negtest_raw(JSON_Tokenizer
&) const
194 TTCN_error("A value of type %s cannot be used as erroneous raw value for JSON encoding.",
195 get_descriptor()->name
);
199 int Base_Type::XER_encode_negtest(const Erroneous_descriptor_t
* /*p_err_descr*/,
200 const XERdescriptor_t
& p_td
, TTCN_Buffer
& p_buf
, unsigned int flavor
, int indent
, embed_values_enc_struct_t
*) const
202 return XER_encode(p_td
, p_buf
, flavor
, indent
, 0); // ignore erroneous
205 int Base_Type::RAW_encode_negtest(const Erroneous_descriptor_t
*,
206 const TTCN_Typedescriptor_t
&, RAW_enc_tree
&) const
208 TTCN_error("Internal error: calling Base_Type::RAW_encode_negtest().");
212 int Base_Type::JSON_encode_negtest(const Erroneous_descriptor_t
* /*p_err_descr*/,
213 const TTCN_Typedescriptor_t
& /*p_td*/, JSON_Tokenizer
& /*p_tok*/) const
215 TTCN_error("Internal error: calling Base_Type::JSON_encode_negtest().");
220 #error this is for RT2 only
223 #ifdef TITAN_RUNTIME_2
225 boolean
Record_Of_Type::compare_function(const Record_Of_Type
*left_ptr
,
226 int left_index
, const Record_Of_Type
*right_ptr
, int right_index
)
228 if (left_ptr
->val_ptr
== NULL
)
229 TTCN_error("The left operand of comparison is an unbound value of type %s.",
230 left_ptr
->get_descriptor()->name
);
231 if (right_ptr
->val_ptr
== NULL
)
232 TTCN_error("The right operand of comparison is an unbound value of type %s.",
233 right_ptr
->get_descriptor()->name
);
235 const Base_Type
* elem
= left_ptr
->val_ptr
->value_elements
[left_index
];
236 const Base_Type
* other_elem
= right_ptr
->val_ptr
->value_elements
[right_index
];
238 if (other_elem
!= NULL
) { // both are bound, compare them
239 return elem
->is_equal(other_elem
);
243 else { // elem unbound, they can be equal only if other_elem is unbound too
244 return other_elem
== NULL
;
248 void Record_Of_Type::clean_up()
250 if (val_ptr
!= NULL
) {
251 if (val_ptr
->ref_count
> 1) {
252 val_ptr
->ref_count
--;
255 else if (val_ptr
->ref_count
== 1) {
256 if (NULL
== refd_ind_ptr
) {
257 for (int elem_count
= 0; elem_count
< val_ptr
->n_elements
; elem_count
++) {
258 if (val_ptr
->value_elements
[elem_count
] != NULL
) {
259 delete val_ptr
->value_elements
[elem_count
];
262 free_pointers((void**)val_ptr
->value_elements
);
271 TTCN_error("Internal error: Invalid reference counter in "
272 "a record of/set of value.");
277 Record_Of_Type::Record_Of_Type(null_type
/*other_value*/)
278 : Base_Type(), val_ptr(new recordof_setof_struct
), err_descr(NULL
), refd_ind_ptr(NULL
)
280 val_ptr
->ref_count
= 1;
281 val_ptr
->n_elements
= 0;
282 val_ptr
->value_elements
= NULL
;
285 Record_Of_Type::Record_Of_Type(const Record_Of_Type
& other_value
)
286 : Base_Type(other_value
), RefdIndexInterface(other_value
)
287 , val_ptr(NULL
), err_descr(other_value
.err_descr
), refd_ind_ptr(NULL
)
289 if (!other_value
.is_bound())
290 TTCN_error("Copying an unbound record of/set of value.");
291 // Increment ref_count only if val_ptr is not NULL
292 if (other_value
.val_ptr
!= NULL
) {
293 if (NULL
== other_value
.refd_ind_ptr
) {
294 val_ptr
= other_value
.val_ptr
;
295 val_ptr
->ref_count
++;
298 // there are references to at least one element => the array must be copied
299 int nof_elements
= other_value
.get_nof_elements();
300 set_size(nof_elements
);
301 for (int i
= 0; i
< nof_elements
; ++i
) {
302 if (other_value
.is_elem_bound(i
)) {
303 val_ptr
->value_elements
[i
] = other_value
.val_ptr
->value_elements
[i
]->clone();
310 int Record_Of_Type::get_nof_elements() const
312 int nof_elements
= (val_ptr
!= NULL
) ? val_ptr
->n_elements
: 0;
313 if (NULL
!= refd_ind_ptr
) {
314 while (nof_elements
> 0) {
315 if (is_elem_bound(nof_elements
- 1)) {
324 bool Record_Of_Type::is_elem_bound(int index
) const
326 return val_ptr
->value_elements
[index
] != NULL
&&
327 val_ptr
->value_elements
[index
]->is_bound();
330 int Record_Of_Type::get_max_refd_index()
332 if (NULL
== refd_ind_ptr
) {
335 if (-1 == refd_ind_ptr
->max_refd_index
) {
336 for (size_t i
= 0; i
< refd_ind_ptr
->refd_indices
.size(); ++i
) {
337 if (refd_ind_ptr
->refd_indices
[i
] > refd_ind_ptr
->max_refd_index
) {
338 refd_ind_ptr
->max_refd_index
= refd_ind_ptr
->refd_indices
[i
];
342 return refd_ind_ptr
->max_refd_index
;
345 bool Record_Of_Type::is_index_refd(int index
)
347 if (NULL
== refd_ind_ptr
) {
350 for (size_t i
= 0; i
< refd_ind_ptr
->refd_indices
.size(); ++i
) {
351 if (index
== refd_ind_ptr
->refd_indices
[i
]) {
358 void Record_Of_Type::set_val(null_type
)
363 boolean
Record_Of_Type::is_equal(const Base_Type
* other_value
) const
365 const Record_Of_Type
* other_recof
= static_cast<const Record_Of_Type
*>(other_value
);
367 TTCN_error("The left operand of comparison is an unbound value of type %s.",
368 get_descriptor()->name
);
369 if (other_recof
->val_ptr
== NULL
)
370 TTCN_error("The right operand of comparison is an unbound value of type %s.",
371 other_value
->get_descriptor()->name
);
372 if (val_ptr
== other_recof
->val_ptr
) return TRUE
;
374 return compare_set_of(this, get_nof_elements(), other_recof
,
375 other_recof
->get_nof_elements(), compare_function
);
377 if (get_nof_elements() != other_recof
->get_nof_elements()) return FALSE
;
378 for (int elem_count
= 0; elem_count
< get_nof_elements(); elem_count
++) {
379 if (is_elem_bound(elem_count
)) {
380 if (other_recof
->is_elem_bound(elem_count
)) {
381 if (!val_ptr
->value_elements
[elem_count
]->is_equal(other_recof
->val_ptr
->value_elements
[elem_count
]))
384 } else if (other_recof
->is_elem_bound(elem_count
)) return FALSE
;
390 void Record_Of_Type::set_value(const Base_Type
* other_value
)
392 const Record_Of_Type
* other_recof
= static_cast<const Record_Of_Type
*>(other_value
);
393 if (!other_recof
->is_bound())
394 TTCN_error("Assigning an unbound value of type %s.",
395 other_value
->get_descriptor()->name
);
396 if (this != other_recof
) {
397 if (NULL
== refd_ind_ptr
&& NULL
== other_recof
->refd_ind_ptr
) {
399 val_ptr
= other_recof
->val_ptr
;
400 val_ptr
->ref_count
++;
403 // there are references to at least one element => the array must be copied
404 int nof_elements
= other_recof
->get_nof_elements();
405 set_size(nof_elements
);
406 for (int i
= 0; i
< nof_elements
; ++i
) {
407 if (other_recof
->is_elem_bound(i
)) {
408 if (val_ptr
->value_elements
[i
] == NULL
) {
409 val_ptr
->value_elements
[i
] = create_elem();
411 val_ptr
->value_elements
[i
]->set_value(other_recof
->val_ptr
->value_elements
[i
]);
413 else if (val_ptr
->value_elements
[i
] != NULL
) {
414 if (is_index_refd(i
)) {
415 val_ptr
->value_elements
[i
]->clean_up();
418 delete val_ptr
->value_elements
[i
];
419 val_ptr
->value_elements
[i
] = NULL
;
425 err_descr
= other_recof
->err_descr
;
428 boolean
Record_Of_Type::operator!=(null_type other_value
) const
430 return !(*this == other_value
);
433 Base_Type
* Record_Of_Type::get_at(int index_value
)
436 TTCN_error("Accessing an element of type %s using a negative index: %d.",
437 get_descriptor()->name
, index_value
);
438 if (val_ptr
== NULL
) {
439 val_ptr
= new recordof_setof_struct
;
440 val_ptr
->ref_count
= 1;
441 val_ptr
->n_elements
= 0;
442 val_ptr
->value_elements
= NULL
;
443 } else if (val_ptr
->ref_count
> 1) {
444 struct recordof_setof_struct
*new_val_ptr
= new recordof_setof_struct
;
445 new_val_ptr
->ref_count
= 1;
446 new_val_ptr
->n_elements
= (index_value
>= val_ptr
->n_elements
) ?
447 index_value
+ 1 : val_ptr
->n_elements
;
448 new_val_ptr
->value_elements
=
449 (Base_Type
**)allocate_pointers(new_val_ptr
->n_elements
);
450 for (int elem_count
= 0; elem_count
< val_ptr
->n_elements
; elem_count
++)
452 if (val_ptr
->value_elements
[elem_count
] != NULL
) {
453 new_val_ptr
->value_elements
[elem_count
] =
454 val_ptr
->value_elements
[elem_count
]->clone();
457 val_ptr
->ref_count
--;
458 val_ptr
= new_val_ptr
;
460 if (index_value
>= val_ptr
->n_elements
) set_size(index_value
+ 1);
461 if (val_ptr
->value_elements
[index_value
] == NULL
) {
462 val_ptr
->value_elements
[index_value
] = create_elem();
464 return val_ptr
->value_elements
[index_value
];
467 Base_Type
* Record_Of_Type::get_at(const INTEGER
& index_value
)
469 if (!index_value
.is_bound())
470 TTCN_error("Using an unbound integer value for indexing a value "
471 "of type %s.", get_descriptor()->name
);
472 return get_at((int)index_value
);
475 const Base_Type
* Record_Of_Type::get_at(int index_value
) const
478 TTCN_error("Accessing an element in an unbound value of type %s.",
479 get_descriptor()->name
);
481 TTCN_error("Accessing an element of type %s using a negative index: %d.",
482 get_descriptor()->name
, index_value
);
483 if (index_value
>= get_nof_elements())
484 TTCN_error("Index overflow in a value of type %s: The index is %d, but the "
485 "value has only %d elements.", get_descriptor()->name
, index_value
,
487 return (val_ptr
->value_elements
[index_value
] != NULL
) ?
488 val_ptr
->value_elements
[index_value
] : get_unbound_elem();
491 const Base_Type
* Record_Of_Type::get_at(const INTEGER
& index_value
) const
493 if (!index_value
.is_bound())
494 TTCN_error("Using an unbound integer value for indexing a value "
495 "of type %s.", get_descriptor()->name
);
496 return get_at((int)index_value
);
499 Record_Of_Type
* Record_Of_Type::rotl(const INTEGER
& rotate_count
, Record_Of_Type
* rec_of
) const
501 if (!rotate_count
.is_bound())
502 TTCN_error("Unbound integer operand of rotate left operator of type %s.",
503 get_descriptor()->name
);
504 return rotr((int)(-rotate_count
), rec_of
);
507 Record_Of_Type
* Record_Of_Type::rotr(const INTEGER
& rotate_count
, Record_Of_Type
* rec_of
) const
509 if (!rotate_count
.is_bound())
510 TTCN_error("Unbound integer operand of rotate right operator of type %s.",
511 get_descriptor()->name
);
512 return rotr((int)rotate_count
, rec_of
);
515 Record_Of_Type
* Record_Of_Type::rotr(int rotate_count
, Record_Of_Type
* rec_of
) const
518 TTCN_error("Performing rotation operation on an unbound value of type %s.",
519 get_descriptor()->name
);
520 int nof_elements
= get_nof_elements();
521 if (nof_elements
== 0) return const_cast<Record_Of_Type
*>(this);
523 if (rotate_count
>=0) rc
= rotate_count
% nof_elements
;
524 else rc
= nof_elements
- ((-rotate_count
) % nof_elements
);
525 if (rc
== 0) return const_cast<Record_Of_Type
*>(this);
526 rec_of
->set_size(nof_elements
);
528 for (int i
=0; i
<nof_elements
; i
++) {
529 rot_i
= (i
+rc
) % nof_elements
;
530 if (is_elem_bound(i
)) {
531 if (rec_of
->val_ptr
->value_elements
[rot_i
] == NULL
) {
532 rec_of
->val_ptr
->value_elements
[rot_i
] = rec_of
->create_elem();
534 rec_of
->val_ptr
->value_elements
[rot_i
]->set_value(val_ptr
->value_elements
[i
]);
535 } else if (rec_of
->is_elem_bound(rot_i
)) {
536 delete rec_of
->val_ptr
->value_elements
[rot_i
];
537 rec_of
->val_ptr
->value_elements
[rot_i
] = NULL
;
543 Record_Of_Type
* Record_Of_Type::concat(const Record_Of_Type
* other_value
,
544 Record_Of_Type
* rec_of
) const
546 if (val_ptr
== NULL
|| other_value
->val_ptr
== NULL
)
547 TTCN_error("Unbound operand of %s concatenation.", get_descriptor()->name
);
548 int nof_elements
= get_nof_elements();
549 if (nof_elements
== 0) return const_cast<Record_Of_Type
*>(other_value
);
550 int other_value_nof_elements
= other_value
->get_nof_elements();
551 if (other_value_nof_elements
== 0) return const_cast<Record_Of_Type
*>(this);
552 rec_of
->set_size(nof_elements
+ other_value_nof_elements
);
553 for (int i
=0; i
<nof_elements
; i
++) {
554 if (is_elem_bound(i
)) {
555 if (rec_of
->val_ptr
->value_elements
[i
] == NULL
) {
556 rec_of
->val_ptr
->value_elements
[i
] = rec_of
->create_elem();
558 rec_of
->val_ptr
->value_elements
[i
]->set_value(val_ptr
->value_elements
[i
]);
559 } else if (rec_of
->val_ptr
->value_elements
[i
] != NULL
) {
560 if (rec_of
->is_index_refd(i
)) {
561 rec_of
->val_ptr
->value_elements
[i
]->clean_up();
564 delete rec_of
->val_ptr
->value_elements
[i
];
565 rec_of
->val_ptr
->value_elements
[i
] = NULL
;
570 for (int i
=0; i
<other_value_nof_elements
; i
++) {
571 cat_i
= i
+ nof_elements
;
572 if (other_value
->is_elem_bound(i
)) {
573 if (rec_of
->val_ptr
->value_elements
[cat_i
] == NULL
) {
574 rec_of
->val_ptr
->value_elements
[cat_i
] = rec_of
->create_elem();
576 rec_of
->val_ptr
->value_elements
[cat_i
]->
577 set_value(other_value
->val_ptr
->value_elements
[i
]);
578 } else if (rec_of
->val_ptr
->value_elements
[cat_i
] != NULL
) {
579 if (rec_of
->is_index_refd(cat_i
)) {
580 rec_of
->val_ptr
->value_elements
[cat_i
]->clean_up();
583 delete rec_of
->val_ptr
->value_elements
[cat_i
];
584 rec_of
->val_ptr
->value_elements
[cat_i
] = NULL
;
591 void Record_Of_Type::substr_(int index
, int returncount
,
592 Record_Of_Type
* rec_of
) const
595 TTCN_error("The first argument of substr() is an unbound value of type %s.",
596 get_descriptor()->name
);
597 check_substr_arguments(get_nof_elements(), index
, returncount
,
598 get_descriptor()->name
, "element");
599 rec_of
->set_size(returncount
);
600 for (int i
=0; i
<returncount
; i
++) {
601 if (is_elem_bound(i
+ index
)) {
602 if (rec_of
->val_ptr
->value_elements
[i
] == NULL
) {
603 rec_of
->val_ptr
->value_elements
[i
] = rec_of
->create_elem();
605 rec_of
->val_ptr
->value_elements
[i
]->
606 set_value(val_ptr
->value_elements
[i
+index
]);
607 } else if (rec_of
->val_ptr
->value_elements
[i
] != NULL
) {
608 if (rec_of
->is_index_refd(i
)) {
609 rec_of
->val_ptr
->value_elements
[i
]->clean_up();
612 delete rec_of
->val_ptr
->value_elements
[i
];
613 rec_of
->val_ptr
->value_elements
[i
] = NULL
;
619 void Record_Of_Type::replace_(int index
, int len
,
620 const Record_Of_Type
* repl
, Record_Of_Type
* rec_of
) const
623 TTCN_error("The first argument of replace() is an unbound value "
624 "of type %s.", get_descriptor()->name
);
625 if (repl
->val_ptr
== NULL
)
626 TTCN_error("The fourth argument of replace() is an unbound value of "
627 "type %s.", get_descriptor()->name
);
628 int nof_elements
= get_nof_elements();
629 check_replace_arguments(nof_elements
, index
, len
,
630 get_descriptor()->name
, "element");
631 int repl_nof_elements
= repl
->get_nof_elements();
632 rec_of
->set_size(nof_elements
+ repl_nof_elements
- len
);
633 for (int i
= 0; i
< index
; i
++) {
634 if (is_elem_bound(i
)) {
635 if (rec_of
->val_ptr
->value_elements
[i
] == NULL
) {
636 rec_of
->val_ptr
->value_elements
[i
] = rec_of
->create_elem();
638 rec_of
->val_ptr
->value_elements
[i
]->set_value(val_ptr
->value_elements
[i
]);
639 } else if (rec_of
->val_ptr
->value_elements
[i
] != NULL
) {
640 if (rec_of
->is_index_refd(i
)) {
641 rec_of
->val_ptr
->value_elements
[i
]->clean_up();
644 delete rec_of
->val_ptr
->value_elements
[i
];
645 rec_of
->val_ptr
->value_elements
[i
] = NULL
;
649 for (int i
= 0; i
< repl_nof_elements
; i
++) {
650 if (repl
->is_elem_bound(i
)) {
651 if (rec_of
->val_ptr
->value_elements
[i
+index
] == NULL
) {
652 rec_of
->val_ptr
->value_elements
[i
+index
] = rec_of
->create_elem();
654 rec_of
->val_ptr
->value_elements
[i
+index
]->
655 set_value(repl
->val_ptr
->value_elements
[i
]);
656 } else if (rec_of
->val_ptr
->value_elements
[i
+index
] != NULL
) {
657 if (rec_of
->is_index_refd(i
+index
)) {
658 rec_of
->val_ptr
->value_elements
[i
+index
]->clean_up();
661 delete rec_of
->val_ptr
->value_elements
[i
+index
];
662 rec_of
->val_ptr
->value_elements
[i
+index
] = NULL
;
667 for (int i
= 0; i
< nof_elements
- index
- len
; i
++) {
668 repl_i
= index
+i
+repl_nof_elements
;
669 if (is_elem_bound(index
+i
+len
)) {
670 if (rec_of
->val_ptr
->value_elements
[repl_i
] == NULL
) {
671 rec_of
->val_ptr
->value_elements
[repl_i
] = rec_of
->create_elem();
673 rec_of
->val_ptr
->value_elements
[repl_i
]->
674 set_value(val_ptr
->value_elements
[index
+i
+len
]);
675 } else if (rec_of
->val_ptr
->value_elements
[repl_i
] != NULL
) {
676 if (rec_of
->is_index_refd(repl_i
)) {
677 rec_of
->val_ptr
->value_elements
[repl_i
]->clean_up();
680 delete rec_of
->val_ptr
->value_elements
[repl_i
];
681 rec_of
->val_ptr
->value_elements
[repl_i
] = NULL
;
687 void Record_Of_Type::replace_(int index
, int len
,
688 const Record_Of_Template
* repl
, Record_Of_Type
* rec_of
) const
690 if (!repl
->is_value())
691 TTCN_error("The fourth argument of function replace() is a template "
692 "of type %s with non-specific value.", get_descriptor()->name
);
693 rec_of
->set_val(NULL_VALUE
);
694 Base_Type
* repl_value
= rec_of
->clone();
695 repl
->valueofv(repl_value
);
696 replace_(index
, len
, static_cast<Record_Of_Type
*>(repl_value
), rec_of
);
700 void Record_Of_Type::replace_(int index
, int len
,
701 const Set_Of_Template
* repl
, Record_Of_Type
* rec_of
) const
703 if (!repl
->is_value())
704 TTCN_error("The fourth argument of function replace() is a template "
705 "of type %s with non-specific value.", get_descriptor()->name
);
706 rec_of
->set_val(NULL_VALUE
);
707 Base_Type
* repl_value
= rec_of
->clone();
708 repl
->valueofv(repl_value
);
709 replace_(index
, len
, static_cast<Record_Of_Type
*>(repl_value
), rec_of
);
713 void Record_Of_Type::set_size(int new_size
)
716 TTCN_error("Internal error: Setting a negative size for a value of "
717 "type %s.", get_descriptor()->name
);
718 if (val_ptr
== NULL
) {
719 val_ptr
= new recordof_setof_struct
;
720 val_ptr
->ref_count
= 1;
721 val_ptr
->n_elements
= 0;
722 val_ptr
->value_elements
= NULL
;
723 } else if (val_ptr
->ref_count
> 1) {
724 struct recordof_setof_struct
*new_val_ptr
= new recordof_setof_struct
;
725 new_val_ptr
->ref_count
= 1;
726 new_val_ptr
->n_elements
= (new_size
< val_ptr
->n_elements
) ?
727 new_size
: val_ptr
->n_elements
;
728 new_val_ptr
->value_elements
=
729 (Base_Type
**)allocate_pointers(new_val_ptr
->n_elements
);
730 for (int elem_count
= 0; elem_count
< new_val_ptr
->n_elements
; elem_count
++) {
731 if (val_ptr
->value_elements
[elem_count
] != NULL
) {
732 new_val_ptr
->value_elements
[elem_count
] =
733 val_ptr
->value_elements
[elem_count
]->clone();
737 val_ptr
= new_val_ptr
;
739 if (new_size
> val_ptr
->n_elements
) {
740 val_ptr
->value_elements
= (Base_Type
**)
741 reallocate_pointers((void**)val_ptr
->value_elements
, val_ptr
->n_elements
, new_size
);
742 val_ptr
->n_elements
= new_size
;
743 } else if (new_size
< val_ptr
->n_elements
) {
744 for (int elem_count
= new_size
; elem_count
< val_ptr
->n_elements
; elem_count
++) {
745 if (val_ptr
->value_elements
[elem_count
] != NULL
) {
746 if (is_index_refd(elem_count
)) {
747 val_ptr
->value_elements
[elem_count
]->clean_up();
750 delete val_ptr
->value_elements
[elem_count
];
751 val_ptr
->value_elements
[elem_count
] = 0;
755 if (new_size
<= get_max_refd_index()) {
756 new_size
= get_max_refd_index() + 1;
758 if (new_size
< val_ptr
->n_elements
) {
759 val_ptr
->value_elements
= (Base_Type
**)
760 reallocate_pointers((void**)val_ptr
->value_elements
, val_ptr
->n_elements
, new_size
);
761 val_ptr
->n_elements
= new_size
;
766 boolean
Record_Of_Type::is_bound() const
768 if (NULL
== refd_ind_ptr
) {
769 return (val_ptr
!= NULL
);
771 return (get_nof_elements() != 0);
774 boolean
Record_Of_Type::is_value() const
776 if (val_ptr
== NULL
) return FALSE
;
777 for (int i
=0; i
< get_nof_elements(); ++i
)
778 if (!is_elem_bound(i
) ||
779 !val_ptr
->value_elements
[i
]->is_value()) return FALSE
;
783 int Record_Of_Type::size_of() const
786 TTCN_error("Performing sizeof operation on an unbound value of type %s.",
787 get_descriptor()->name
);
788 return get_nof_elements();
791 int Record_Of_Type::lengthof() const
794 TTCN_error("Performing lengthof operation on an unbound value of "
795 "type %s.", get_descriptor()->name
);
796 for (int my_length
=get_nof_elements(); my_length
>0; my_length
--)
797 if (is_elem_bound(my_length
- 1)) return my_length
;
801 void Record_Of_Type::log() const
803 if (val_ptr
== NULL
) {
804 TTCN_Logger::log_event_unbound();
807 if (get_nof_elements()==0) {
808 TTCN_Logger::log_event_str("{ }");
810 TTCN_Logger::log_event_str("{ ");
811 for (int elem_count
= 0; elem_count
< get_nof_elements(); elem_count
++) {
812 if (elem_count
> 0) TTCN_Logger::log_event_str(", ");
813 get_at(elem_count
)->log();
815 TTCN_Logger::log_event_str(" }");
817 if (err_descr
) err_descr
->log();
820 void Record_Of_Type::encode_text(Text_Buf
& text_buf
) const
823 TTCN_error("Text encoder: Encoding an unbound value of type %s.",
824 get_descriptor()->name
);
825 text_buf
.push_int(get_nof_elements());
826 for (int elem_count
= 0; elem_count
< get_nof_elements(); elem_count
++)
827 get_at(elem_count
)->encode_text(text_buf
);
830 void Record_Of_Type::decode_text(Text_Buf
& text_buf
)
832 int new_size
= text_buf
.pull_int().get_val();
834 TTCN_error("Text decoder: Negative size was received for a value of "
835 "type %s.", get_descriptor()->name
);
837 for (int elem_count
= 0; elem_count
< new_size
; elem_count
++) {
838 if (val_ptr
->value_elements
[elem_count
] == NULL
) {
839 val_ptr
->value_elements
[elem_count
] = create_elem();
841 val_ptr
->value_elements
[elem_count
]->decode_text(text_buf
);
845 boolean
Record_Of_Type::operator==(null_type
/*other_value*/) const
848 TTCN_error("The left operand of comparison is an unbound value of type %s.",
849 get_descriptor()->name
);
850 return get_nof_elements() == 0;
853 int Record_Of_Type::rawdec_ebv() const
855 TTCN_error("Internal error: Record_Of_Type::rawdec_ebv() called.");
858 boolean
Record_Of_Type::isXerAttribute() const
860 TTCN_error("Internal error: Record_Of_Type::isXerAttribute() called.");
863 boolean
Record_Of_Type::isXmlValueList() const
865 TTCN_error("Internal error: Record_Of_Type::isXmlValueList() called.");
868 int Record_Of_Type::TEXT_encode(const TTCN_Typedescriptor_t
& p_td
,
869 TTCN_Buffer
& buff
) const
872 return TEXT_encode_negtest(err_descr
, p_td
, buff
);
874 int encoded_length
=0;
875 if(p_td
.text
->begin_encode
) {
876 buff
.put_cs(*p_td
.text
->begin_encode
);
877 encoded_length
+=p_td
.text
->begin_encode
->lengthof();
880 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND
,
881 "Encoding an unbound value.");
882 if(p_td
.text
->end_encode
) {
883 buff
.put_cs(*p_td
.text
->end_encode
);
884 encoded_length
+=p_td
.text
->end_encode
->lengthof();
886 return encoded_length
;
888 const TTCN_Typedescriptor_t
* elem_descr
= p_td
.oftype_descr
;
889 for(int a
=0;a
<get_nof_elements();a
++) {
890 if(a
!=0 && p_td
.text
->separator_encode
) {
891 buff
.put_cs(*p_td
.text
->separator_encode
);
892 encoded_length
+=p_td
.text
->separator_encode
->lengthof();
894 encoded_length
+=get_at(a
)->TEXT_encode(*elem_descr
,buff
);
896 if(p_td
.text
->end_encode
) {
897 buff
.put_cs(*p_td
.text
->end_encode
);
898 encoded_length
+=p_td
.text
->end_encode
->lengthof();
900 return encoded_length
;
904 * TEXT encode for negative testing
906 int Record_Of_Type::TEXT_encode_negtest(const Erroneous_descriptor_t
* p_err_descr
, const TTCN_Typedescriptor_t
& p_td
,
907 TTCN_Buffer
& buff
) const
909 bool need_separator
=false;
910 int encoded_length
=0;
911 if(p_td
.text
->begin_encode
) {
912 buff
.put_cs(*p_td
.text
->begin_encode
);
913 encoded_length
+=p_td
.text
->begin_encode
->lengthof();
916 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND
,
917 "Encoding an unbound value.");
918 if(p_td
.text
->end_encode
) {
919 buff
.put_cs(*p_td
.text
->end_encode
);
920 encoded_length
+=p_td
.text
->end_encode
->lengthof();
922 return encoded_length
;
928 for(int a
=0;a
<get_nof_elements();a
++) {
929 if ( (p_err_descr
->omit_before
!=-1) && (a
<p_err_descr
->omit_before
) ) continue;
930 const Erroneous_values_t
* err_vals
= p_err_descr
->next_field_err_values(a
, values_idx
);
931 const Erroneous_descriptor_t
* emb_descr
= p_err_descr
->next_field_emb_descr(a
, edescr_idx
);
933 if (err_vals
&& err_vals
->before
) {
934 if (err_vals
->before
->errval
==NULL
) TTCN_error(
935 "internal error: erroneous before value missing");
936 if (need_separator
&& p_td
.text
->separator_encode
) {
937 buff
.put_cs(*p_td
.text
->separator_encode
);
938 encoded_length
+=p_td
.text
->separator_encode
->lengthof();
940 if (err_vals
->before
->raw
) {
941 encoded_length
+= err_vals
->before
->errval
->encode_raw(buff
);
943 if (err_vals
->before
->type_descr
==NULL
) TTCN_error(
944 "internal error: erroneous before typedescriptor missing");
945 encoded_length
+= err_vals
->before
->errval
->TEXT_encode(
946 *(err_vals
->before
->type_descr
),buff
);
951 if (err_vals
&& err_vals
->value
) {
952 if (err_vals
->value
->errval
) {
953 if (need_separator
&& p_td
.text
->separator_encode
) {
954 buff
.put_cs(*p_td
.text
->separator_encode
);
955 encoded_length
+=p_td
.text
->separator_encode
->lengthof();
957 if (err_vals
->value
->raw
) {
958 encoded_length
+= err_vals
->value
->errval
->encode_raw(buff
);
960 if (err_vals
->value
->type_descr
==NULL
) TTCN_error(
961 "internal error: erroneous value typedescriptor missing");
962 encoded_length
+= err_vals
->value
->errval
->TEXT_encode(
963 *(err_vals
->value
->type_descr
),buff
);
968 if (need_separator
&& p_td
.text
->separator_encode
) {
969 buff
.put_cs(*p_td
.text
->separator_encode
);
970 encoded_length
+=p_td
.text
->separator_encode
->lengthof();
973 encoded_length
+= get_at(a
)->TEXT_encode_negtest(
974 emb_descr
,*p_td
.oftype_descr
,buff
);
976 encoded_length
+= get_at(a
)->TEXT_encode(*p_td
.oftype_descr
,buff
);
981 if (err_vals
&& err_vals
->after
) {
982 if (err_vals
->after
->errval
==NULL
) TTCN_error(
983 "internal error: erroneous after value missing");
984 if (need_separator
&& p_td
.text
->separator_encode
) {
985 buff
.put_cs(*p_td
.text
->separator_encode
);
986 encoded_length
+=p_td
.text
->separator_encode
->lengthof();
988 if (err_vals
->after
->raw
) {
989 encoded_length
+= err_vals
->after
->errval
->encode_raw(buff
);
991 if (err_vals
->after
->type_descr
==NULL
) TTCN_error(
992 "internal error: erroneous after typedescriptor missing");
993 encoded_length
+= err_vals
->after
->errval
->TEXT_encode(
994 *(err_vals
->after
->type_descr
),buff
);
999 if ( (p_err_descr
->omit_after
!=-1) && (a
>=p_err_descr
->omit_after
) ) break;
1001 if(p_td
.text
->end_encode
) {
1002 buff
.put_cs(*p_td
.text
->end_encode
);
1003 encoded_length
+=p_td
.text
->end_encode
->lengthof();
1005 return encoded_length
;
1008 int Record_Of_Type::TEXT_decode(const TTCN_Typedescriptor_t
& p_td
,
1009 TTCN_Buffer
& buff
, Limit_Token_List
& limit
, boolean no_err
,
1012 int decoded_length
=0;
1014 boolean sep_found
=FALSE
;
1017 if(p_td
.text
->begin_decode
){
1019 if((tl
=p_td
.text
->begin_decode
->match_begin(buff
))<0){
1020 if(no_err
)return -1;
1021 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR
,
1022 "The specified token '%s' not found for '%s': ",
1023 (const char*)*(p_td
.text
->begin_decode
), p_td
.name
);
1027 buff
.increase_pos(tl
);
1029 if(p_td
.text
->end_decode
){
1030 limit
.add_token(p_td
.text
->end_decode
);
1033 if(p_td
.text
->separator_decode
){
1034 limit
.add_token(p_td
.text
->separator_decode
);
1040 int more
=get_nof_elements();
1042 Base_Type
* val
= create_elem();
1044 int len
= val
->TEXT_decode(*p_td
.oftype_descr
,buff
,limit
,TRUE
);
1045 if(len
==-1 || (len
==0 && !limit
.has_token())){
1049 buff
.set_pos(buff
.get_pos()-sep_length
);
1050 decoded_length
-=sep_length
;
1055 if (NULL
== refd_ind_ptr
) {
1056 val_ptr
->value_elements
= (Base_Type
**)reallocate_pointers(
1057 (void**)val_ptr
->value_elements
, val_ptr
->n_elements
, val_ptr
->n_elements
+ 1);
1058 val_ptr
->value_elements
[val_ptr
->n_elements
]=val
;
1059 val_ptr
->n_elements
++;
1062 get_at(get_nof_elements())->set_value(val
);
1065 decoded_length
+=len
;
1066 if(p_td
.text
->separator_decode
){
1068 if((tl
=p_td
.text
->separator_decode
->match_begin(buff
))<0){
1072 buff
.increase_pos(tl
);
1075 } else if(p_td
.text
->end_decode
){
1077 if((tl
=p_td
.text
->end_decode
->match_begin(buff
))!=-1){
1079 buff
.increase_pos(tl
);
1080 limit
.remove_tokens(ml
);
1081 return decoded_length
;
1083 } else if(limit
.has_token(ml
)){
1085 if((tl
=limit
.match(buff
,ml
))==0){
1091 limit
.remove_tokens(ml
);
1092 if(p_td
.text
->end_decode
){
1094 if((tl
=p_td
.text
->end_decode
->match_begin(buff
))<0){
1101 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR
,
1102 "The specified token '%s' not found for '%s': ",
1103 (const char*)*(p_td
.text
->end_decode
), p_td
.name
);
1104 return decoded_length
;
1107 buff
.increase_pos(tl
);
1109 if(get_nof_elements()==0){
1110 if (!p_td
.text
->end_decode
&& !p_td
.text
->begin_decode
) {
1111 if(no_err
)return -1;
1112 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR
,
1113 "No record/set of member found.");
1114 return decoded_length
;
1117 if(!first_call
&& more
==get_nof_elements() &&
1118 !(p_td
.text
->end_decode
|| p_td
.text
->begin_decode
)) return -1;
1119 return decoded_length
;
1122 ASN_BER_TLV_t
* Record_Of_Type::BER_encode_TLV(const TTCN_Typedescriptor_t
& p_td
,
1123 unsigned p_coding
) const
1126 return BER_encode_TLV_negtest(err_descr
, p_td
, p_coding
);
1128 BER_chk_descr(p_td
);
1129 ASN_BER_TLV_t
*new_tlv
=BER_encode_chk_bound(is_bound());
1131 new_tlv
=ASN_BER_TLV_t::construct(NULL
);
1132 TTCN_EncDec_ErrorContext ec
;
1133 for(int elem_i
=0; elem_i
<get_nof_elements(); elem_i
++) {
1134 ec
.set_msg("Component #%d: ", elem_i
);
1135 new_tlv
->add_TLV(get_at(elem_i
)->BER_encode_TLV(*p_td
.oftype_descr
, p_coding
));
1137 if (is_set()) new_tlv
->sort_tlvs();
1139 new_tlv
=ASN_BER_V2TLV(new_tlv
, p_td
, p_coding
);
1143 ASN_BER_TLV_t
* Record_Of_Type::BER_encode_TLV_negtest(const Erroneous_descriptor_t
* p_err_descr
,
1144 const TTCN_Typedescriptor_t
& p_td
, unsigned p_coding
) const
1146 BER_chk_descr(p_td
);
1147 ASN_BER_TLV_t
*new_tlv
=BER_encode_chk_bound(is_bound());
1149 new_tlv
=ASN_BER_TLV_t::construct(NULL
);
1150 TTCN_EncDec_ErrorContext ec
;
1153 for (int elem_i
=0; elem_i
<get_nof_elements(); elem_i
++) {
1154 if ( (p_err_descr
->omit_before
!=-1) && (elem_i
<p_err_descr
->omit_before
) ) continue;
1155 const Erroneous_values_t
* err_vals
= p_err_descr
->next_field_err_values(elem_i
, values_idx
);
1156 const Erroneous_descriptor_t
* emb_descr
= p_err_descr
->next_field_emb_descr(elem_i
, edescr_idx
);
1158 if (err_vals
&& err_vals
->before
) {
1159 if (err_vals
->before
->errval
==NULL
) TTCN_error(
1160 "internal error: erroneous before value missing");
1161 ec
.set_msg("Erroneous value before component #%d: ", elem_i
);
1162 if (err_vals
->before
->raw
) {
1163 new_tlv
->add_TLV(err_vals
->before
->errval
->BER_encode_negtest_raw());
1165 if (err_vals
->before
->type_descr
==NULL
) TTCN_error(
1166 "internal error: erroneous before typedescriptor missing");
1167 new_tlv
->add_TLV(err_vals
->before
->errval
->BER_encode_TLV(
1168 *err_vals
->before
->type_descr
, p_coding
));
1172 if (err_vals
&& err_vals
->value
) {
1173 if (err_vals
->value
->errval
) { // replace
1174 ec
.set_msg("Erroneous value for component #%d: ", elem_i
);
1175 if (err_vals
->value
->raw
) {
1176 new_tlv
->add_TLV(err_vals
->value
->errval
->BER_encode_negtest_raw());
1178 if (err_vals
->value
->type_descr
==NULL
) TTCN_error(
1179 "internal error: erroneous value typedescriptor missing");
1180 new_tlv
->add_TLV(err_vals
->value
->errval
->BER_encode_TLV(
1181 *err_vals
->value
->type_descr
, p_coding
));
1185 ec
.set_msg("Component #%d: ", elem_i
);
1187 new_tlv
->add_TLV(get_at(elem_i
)->BER_encode_TLV_negtest(
1188 emb_descr
, *p_td
.oftype_descr
, p_coding
));
1190 new_tlv
->add_TLV(get_at(elem_i
)->BER_encode_TLV(
1191 *p_td
.oftype_descr
, p_coding
));
1195 if (err_vals
&& err_vals
->after
) {
1196 if (err_vals
->after
->errval
==NULL
) TTCN_error(
1197 "internal error: erroneous after value missing");
1198 ec
.set_msg("Erroneous value after component #%d: ", elem_i
);
1199 if (err_vals
->after
->raw
) {
1200 new_tlv
->add_TLV(err_vals
->after
->errval
->BER_encode_negtest_raw());
1202 if (err_vals
->after
->type_descr
==NULL
) TTCN_error(
1203 "internal error: erroneous after typedescriptor missing");
1204 new_tlv
->add_TLV(err_vals
->after
->errval
->BER_encode_TLV(
1205 *err_vals
->after
->type_descr
, p_coding
));
1209 if ( (p_err_descr
->omit_after
!=-1) && (elem_i
>=p_err_descr
->omit_after
) ) break;
1211 if (is_set()) new_tlv
->sort_tlvs();
1213 new_tlv
=ASN_BER_V2TLV(new_tlv
, p_td
, p_coding
);
1217 boolean
Record_Of_Type::BER_decode_TLV(const TTCN_Typedescriptor_t
& p_td
,
1218 const ASN_BER_TLV_t
& p_tlv
, unsigned L_form
)
1220 BER_chk_descr(p_td
);
1221 ASN_BER_TLV_t stripped_tlv
;
1222 BER_decode_strip_tags(*p_td
.ber
, p_tlv
, L_form
, stripped_tlv
);
1223 TTCN_EncDec_ErrorContext
ec_0("While decoding '%s' type: ", p_td
.name
);
1224 stripped_tlv
.chk_constructed_flag(TRUE
);
1227 ASN_BER_TLV_t tmp_tlv
;
1228 TTCN_EncDec_ErrorContext
ec_1("Component #");
1229 TTCN_EncDec_ErrorContext
ec_2("0: ");
1230 while(BER_decode_constdTLV_next(stripped_tlv
, V_pos
, L_form
, tmp_tlv
)) {
1231 get_at(get_nof_elements())->BER_decode_TLV(*p_td
.oftype_descr
, tmp_tlv
, L_form
);
1232 ec_2
.set_msg("%d: ", val_ptr
->n_elements
);
1237 void Record_Of_Type::BER_decode_opentypes(TTCN_Type_list
& p_typelist
,
1240 p_typelist
.push(this);
1241 TTCN_EncDec_ErrorContext
ec_0("Component #");
1242 TTCN_EncDec_ErrorContext ec_1
;
1243 for(int elem_i
=0; elem_i
<get_nof_elements(); elem_i
++) {
1244 ec_1
.set_msg("%d: ", elem_i
);
1245 get_at(elem_i
)->BER_decode_opentypes(p_typelist
, L_form
);
1251 int Record_Of_Type::RAW_decode(const TTCN_Typedescriptor_t
& p_td
,
1252 TTCN_Buffer
& buff
, int limit
, raw_order_t top_bit_ord
, boolean
/*no_err*/,
1253 int sel_field
, boolean first_call
)
1255 int prepaddlength
= buff
.increase_pos_padd(p_td
.raw
->prepadding
);
1256 limit
-= prepaddlength
;
1257 int decoded_length
= 0;
1258 int decoded_field_length
= 0;
1259 size_t start_of_field
= 0;
1263 int start_field
= get_nof_elements(); // append at the end
1264 TTCN_Typedescriptor_t
const& elem_descr
= *p_td
.oftype_descr
;
1265 if (p_td
.raw
->fieldlength
|| sel_field
!= -1) {
1266 if (sel_field
== -1) sel_field
= p_td
.raw
->fieldlength
;
1267 for (int a
= 0; a
< sel_field
; a
++) {
1268 Base_Type
* field_bt
= get_at(a
+ start_field
);
1269 decoded_field_length
= field_bt
->RAW_decode(elem_descr
, buff
, limit
,
1271 if (decoded_field_length
< 0) return decoded_field_length
;
1272 decoded_length
+= decoded_field_length
;
1273 limit
-= decoded_field_length
;
1277 int a
= start_field
;
1279 if (!first_call
) return -1;
1283 start_of_field
= buff
.get_pos_bit();
1284 Base_Type
* field_bt
= get_at(a
); // non-const, extend the record-of
1285 decoded_field_length
= field_bt
->RAW_decode(elem_descr
, buff
, limit
,
1287 if (decoded_field_length
< 0) { // decoding failed, shorten the record-of
1288 set_size(get_nof_elements() - 1);
1289 buff
.set_pos_bit(start_of_field
);
1290 if (a
> start_field
) {
1293 else return decoded_field_length
;
1295 decoded_length
+= decoded_field_length
;
1296 limit
-= decoded_field_length
;
1298 if (EXT_BIT_NO
!= p_td
.raw
->extension_bit
) {
1299 // (EXT_BIT_YES != p_td.raw->extension_bit) is 0 or 1
1300 // This is the opposite value of what the bit needs to be to signal
1301 // the end of decoding, because x-or is the equivalent of !=
1302 if ((EXT_BIT_YES
!= p_td
.raw
->extension_bit
) ^ buff
.get_last_bit()) {
1309 return decoded_length
+ buff
.increase_pos_padd(p_td
.raw
->padding
) + prepaddlength
;
1312 int Record_Of_Type::RAW_encode(const TTCN_Typedescriptor_t
& p_td
, RAW_enc_tree
& myleaf
) const
1314 if (err_descr
) return RAW_encode_negtest(err_descr
, p_td
, myleaf
);
1315 int encoded_length
= 0;
1316 int nof_elements
= get_nof_elements();
1317 int encoded_num_of_records
=
1318 p_td
.raw
->fieldlength
? (nof_elements
< p_td
.raw
->fieldlength
? nof_elements
: p_td
.raw
->fieldlength
)
1320 myleaf
.isleaf
= FALSE
;
1321 myleaf
.rec_of
= TRUE
;
1322 myleaf
.body
.node
.num_of_nodes
= encoded_num_of_records
;
1323 myleaf
.body
.node
.nodes
= init_nodes_of_enc_tree(encoded_num_of_records
);
1324 TTCN_Typedescriptor_t
const& elem_descr
= *p_td
.oftype_descr
;
1325 for (int a
= 0; a
< encoded_num_of_records
; a
++) {
1326 const Base_Type
*field_bt
= get_at(a
);
1327 myleaf
.body
.node
.nodes
[a
] = new RAW_enc_tree(TRUE
, &myleaf
, &(myleaf
.curr_pos
), a
, elem_descr
.raw
);
1328 encoded_length
+= field_bt
->RAW_encode(elem_descr
, *myleaf
.body
.node
.nodes
[a
]);
1330 return myleaf
.length
= encoded_length
;
1333 int Record_Of_Type::RAW_encode_negtest(const Erroneous_descriptor_t
*p_err_descr
,
1334 const TTCN_Typedescriptor_t
& p_td
, RAW_enc_tree
& myleaf
) const
1338 int nof_elements
= get_nof_elements();
1339 // It can be more, of course...
1340 int encoded_num_of_records
=
1341 p_td
.raw
->fieldlength
? (nof_elements
< p_td
.raw
->fieldlength
? nof_elements
: p_td
.raw
->fieldlength
)
1343 for (int i
= 0; i
< nof_elements
; ++i
) {
1344 if ((p_err_descr
->omit_before
!= -1) && (i
< p_err_descr
->omit_before
)) {
1345 --encoded_num_of_records
;
1348 const Erroneous_values_t
*err_vals
=
1349 p_err_descr
->next_field_err_values(i
, values_idx
);
1350 // Not checking any further, `internal error' will be given anyway in the
1351 // next round. Please note that elements can be removed, `omitted'.
1352 if (err_vals
&& err_vals
->before
)
1353 ++encoded_num_of_records
;
1354 if (err_vals
&& err_vals
->value
&& !err_vals
->value
->errval
)
1355 --encoded_num_of_records
;
1356 if (err_vals
&& err_vals
->after
)
1357 ++encoded_num_of_records
;
1358 if ((p_err_descr
->omit_after
!= -1) && (i
>= p_err_descr
->omit_after
)) {
1359 encoded_num_of_records
= encoded_num_of_records
- (nof_elements
- i
) + 1;
1363 myleaf
.body
.node
.num_of_nodes
= encoded_num_of_records
;
1364 myleaf
.body
.node
.nodes
= init_nodes_of_enc_tree(encoded_num_of_records
);
1365 int encoded_length
= 0;
1366 myleaf
.isleaf
= FALSE
;
1367 myleaf
.rec_of
= TRUE
;
1370 for (int i
= 0; i
< nof_elements
; ++i
) {
1371 if ((p_err_descr
->omit_before
!= -1) && (i
< p_err_descr
->omit_before
))
1373 const Erroneous_values_t
*err_vals
= p_err_descr
->next_field_err_values(i
, values_idx
);
1374 const Erroneous_descriptor_t
*emb_descr
= p_err_descr
->next_field_emb_descr(i
, edescr_idx
);
1375 TTCN_Typedescriptor_t
const& elem_descr
= *p_td
.oftype_descr
;
1376 if (err_vals
&& err_vals
->before
) {
1377 if (err_vals
->before
->errval
== NULL
)
1378 TTCN_error("internal error: erroneous before value missing");
1379 if (err_vals
->before
->raw
) {
1380 myleaf
.body
.node
.nodes
[node_pos
] = new RAW_enc_tree(true, &myleaf
,
1381 &(myleaf
.curr_pos
), node_pos
,
1382 err_vals
->before
->errval
->get_descriptor()->raw
);
1383 encoded_length
+= err_vals
->before
->errval
->
1384 RAW_encode_negtest_raw(*myleaf
.body
.node
.nodes
[node_pos
++]);
1386 if (err_vals
->before
->type_descr
== NULL
)
1387 TTCN_error("internal error: erroneous before typedescriptor missing");
1388 myleaf
.body
.node
.nodes
[node_pos
] = new RAW_enc_tree(TRUE
, &myleaf
,
1389 &(myleaf
.curr_pos
), node_pos
, elem_descr
.raw
);
1390 encoded_length
+= err_vals
->before
->errval
->
1391 RAW_encode(*(err_vals
->before
->type_descr
),
1392 *myleaf
.body
.node
.nodes
[node_pos
++]);
1395 if (err_vals
&& err_vals
->value
) {
1396 if (err_vals
->value
->errval
) {
1397 if (err_vals
->value
->raw
) {
1398 myleaf
.body
.node
.nodes
[node_pos
] = new RAW_enc_tree(true, &myleaf
,
1399 &(myleaf
.curr_pos
), node_pos
,
1400 err_vals
->value
->errval
->get_descriptor()->raw
);
1401 encoded_length
+= err_vals
->value
->errval
->
1402 RAW_encode_negtest_raw(*myleaf
.body
.node
.nodes
[node_pos
++]);
1404 if (err_vals
->value
->type_descr
== NULL
)
1405 TTCN_error("internal error: erroneous value typedescriptor missing");
1406 myleaf
.body
.node
.nodes
[node_pos
] = new RAW_enc_tree(TRUE
, &myleaf
,
1407 &(myleaf
.curr_pos
), node_pos
, elem_descr
.raw
);
1408 encoded_length
+= err_vals
->value
->errval
->
1409 RAW_encode(*(err_vals
->value
->type_descr
),
1410 *myleaf
.body
.node
.nodes
[node_pos
++]);
1415 myleaf
.body
.node
.nodes
[node_pos
] = new RAW_enc_tree(TRUE
, &myleaf
,
1416 &(myleaf
.curr_pos
), node_pos
, elem_descr
.raw
);
1417 encoded_length
+= get_at(i
)->RAW_encode_negtest(emb_descr
,
1418 *p_td
.oftype_descr
, *myleaf
.body
.node
.nodes
[node_pos
++]);
1420 myleaf
.body
.node
.nodes
[node_pos
] = new RAW_enc_tree(TRUE
, &myleaf
,
1421 &(myleaf
.curr_pos
), node_pos
, elem_descr
.raw
);
1422 encoded_length
+= get_at(i
)->RAW_encode(*p_td
.oftype_descr
,
1423 *myleaf
.body
.node
.nodes
[node_pos
++]);
1426 if (err_vals
&& err_vals
->after
) {
1427 if (err_vals
->after
->errval
== NULL
)
1428 TTCN_error("internal error: erroneous after value missing");
1429 if (err_vals
->after
->raw
) {
1430 myleaf
.body
.node
.nodes
[node_pos
] = new RAW_enc_tree(true, &myleaf
,
1431 &(myleaf
.curr_pos
), node_pos
,
1432 err_vals
->after
->errval
->get_descriptor()->raw
);
1433 encoded_length
+= err_vals
->after
->errval
->
1434 RAW_encode_negtest_raw(*myleaf
.body
.node
.nodes
[node_pos
++]);
1436 if (err_vals
->after
->type_descr
== NULL
)
1437 TTCN_error("internal error: erroneous after typedescriptor missing");
1438 myleaf
.body
.node
.nodes
[node_pos
] = new RAW_enc_tree(TRUE
, &myleaf
,
1439 &(myleaf
.curr_pos
), node_pos
, elem_descr
.raw
);
1440 encoded_length
+= err_vals
->after
->errval
->
1441 RAW_encode(*(err_vals
->after
->type_descr
),
1442 *myleaf
.body
.node
.nodes
[node_pos
++]);
1445 if ((p_err_descr
->omit_after
!= -1) && (i
>= p_err_descr
->omit_after
))
1448 return myleaf
.length
= encoded_length
;
1451 int Record_Of_Type::JSON_encode(const TTCN_Typedescriptor_t
& p_td
, JSON_Tokenizer
& p_tok
) const
1454 return JSON_encode_negtest(err_descr
, p_td
, p_tok
);
1458 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND
,
1459 "Encoding an unbound %s of value.", is_set() ? "set" : "record");
1463 int enc_len
= p_tok
.put_next_token(JSON_TOKEN_ARRAY_START
, NULL
);
1465 for (int i
= 0; i
< get_nof_elements(); ++i
) {
1466 if (NULL
!= p_td
.json
&& p_td
.json
->metainfo_unbound
&& !get_at(i
)->is_bound()) {
1467 // unbound elements are encoded as { "metainfo []" : "unbound" }
1468 enc_len
+= p_tok
.put_next_token(JSON_TOKEN_OBJECT_START
, NULL
);
1469 enc_len
+= p_tok
.put_next_token(JSON_TOKEN_NAME
, "metainfo []");
1470 enc_len
+= p_tok
.put_next_token(JSON_TOKEN_STRING
, "\"unbound\"");
1471 enc_len
+= p_tok
.put_next_token(JSON_TOKEN_OBJECT_END
, NULL
);
1474 int ret_val
= get_at(i
)->JSON_encode(*p_td
.oftype_descr
, p_tok
);
1475 if (0 > ret_val
) break;
1480 enc_len
+= p_tok
.put_next_token(JSON_TOKEN_ARRAY_END
, NULL
);
1484 int Record_Of_Type::JSON_encode_negtest(const Erroneous_descriptor_t
* p_err_descr
,
1485 const TTCN_Typedescriptor_t
& p_td
,
1486 JSON_Tokenizer
& p_tok
) const
1489 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND
,
1490 "Encoding an unbound %s of value.", is_set() ? "set" : "record");
1494 int enc_len
= p_tok
.put_next_token(JSON_TOKEN_ARRAY_START
, NULL
);
1499 for (int i
= 0; i
< get_nof_elements(); ++i
) {
1500 if (-1 != p_err_descr
->omit_before
&& p_err_descr
->omit_before
> i
) {
1504 const Erroneous_values_t
* err_vals
= p_err_descr
->next_field_err_values(i
, values_idx
);
1505 const Erroneous_descriptor_t
* emb_descr
= p_err_descr
->next_field_emb_descr(i
, edescr_idx
);
1507 if (NULL
!= err_vals
&& NULL
!= err_vals
->before
) {
1508 if (NULL
== err_vals
->before
->errval
) {
1509 TTCN_error("internal error: erroneous before value missing");
1511 if (err_vals
->before
->raw
) {
1512 enc_len
+= err_vals
->before
->errval
->JSON_encode_negtest_raw(p_tok
);
1514 if (NULL
== err_vals
->before
->type_descr
) {
1515 TTCN_error("internal error: erroneous before typedescriptor missing");
1517 enc_len
+= err_vals
->before
->errval
->JSON_encode(*(err_vals
->before
->type_descr
), p_tok
);
1521 if (NULL
!= err_vals
&& NULL
!= err_vals
->value
) {
1522 if (NULL
!= err_vals
->value
->errval
) {
1523 if (err_vals
->value
->raw
) {
1524 enc_len
+= err_vals
->value
->errval
->JSON_encode_negtest_raw(p_tok
);
1526 if (NULL
== err_vals
->value
->type_descr
) {
1527 TTCN_error("internal error: erroneous before typedescriptor missing");
1529 enc_len
+= err_vals
->value
->errval
->JSON_encode(*(err_vals
->value
->type_descr
), p_tok
);
1533 else if (NULL
!= p_td
.json
&& p_td
.json
->metainfo_unbound
&& !get_at(i
)->is_bound()) {
1534 // unbound elements are encoded as { "metainfo []" : "unbound" }
1535 enc_len
+= p_tok
.put_next_token(JSON_TOKEN_OBJECT_START
, NULL
);
1536 enc_len
+= p_tok
.put_next_token(JSON_TOKEN_NAME
, "metainfo []");
1537 enc_len
+= p_tok
.put_next_token(JSON_TOKEN_STRING
, "\"unbound\"");
1538 enc_len
+= p_tok
.put_next_token(JSON_TOKEN_OBJECT_END
, NULL
);
1542 if (NULL
!= emb_descr
) {
1543 ret_val
= get_at(i
)->JSON_encode_negtest(emb_descr
, *p_td
.oftype_descr
, p_tok
);
1545 ret_val
= get_at(i
)->JSON_encode(*p_td
.oftype_descr
, p_tok
);
1547 if (0 > ret_val
) break;
1551 if (NULL
!= err_vals
&& NULL
!= err_vals
->after
) {
1552 if (NULL
== err_vals
->after
->errval
) {
1553 TTCN_error("internal error: erroneous after value missing");
1555 if (err_vals
->after
->raw
) {
1556 enc_len
+= err_vals
->after
->errval
->JSON_encode_negtest_raw(p_tok
);
1558 if (NULL
== err_vals
->after
->type_descr
) {
1559 TTCN_error("internal error: erroneous before typedescriptor missing");
1561 enc_len
+= err_vals
->after
->errval
->JSON_encode(*(err_vals
->after
->type_descr
), p_tok
);
1565 if (-1 != p_err_descr
->omit_after
&& p_err_descr
->omit_after
<= i
) {
1570 enc_len
+= p_tok
.put_next_token(JSON_TOKEN_ARRAY_END
, NULL
);
1574 int Record_Of_Type::JSON_decode(const TTCN_Typedescriptor_t
& p_td
, JSON_Tokenizer
& p_tok
, boolean p_silent
)
1576 json_token_t token
= JSON_TOKEN_NONE
;
1577 int dec_len
= p_tok
.get_next_token(&token
, NULL
, NULL
);
1578 if (JSON_TOKEN_ERROR
== token
) {
1579 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG
, JSON_DEC_BAD_TOKEN_ERROR
, "");
1580 return JSON_ERROR_FATAL
;
1582 else if (JSON_TOKEN_ARRAY_START
!= token
) {
1583 return JSON_ERROR_INVALID_TOKEN
;
1587 for (int nof_elements
= 0; true; ++nof_elements
) {
1588 // Read value tokens until we reach some other token
1589 size_t buf_pos
= p_tok
.get_buf_pos();
1591 if (NULL
!= p_td
.json
&& p_td
.json
->metainfo_unbound
) {
1592 // check for metainfo object
1593 ret_val
= p_tok
.get_next_token(&token
, NULL
, NULL
);
1594 if (JSON_TOKEN_OBJECT_START
== token
) {
1596 size_t value_len
= 0;
1597 ret_val
+= p_tok
.get_next_token(&token
, &value
, &value_len
);
1598 if (JSON_TOKEN_NAME
== token
&& 11 == value_len
&&
1599 0 == strncmp(value
, "metainfo []", 11)) {
1600 ret_val
+= p_tok
.get_next_token(&token
, &value
, &value_len
);
1601 if (JSON_TOKEN_STRING
== token
&& 9 == value_len
&&
1602 0 == strncmp(value
, "\"unbound\"", 9)) {
1603 ret_val
= p_tok
.get_next_token(&token
, NULL
, NULL
);
1604 if (JSON_TOKEN_OBJECT_END
== token
) {
1611 // metainfo object not found, jump back and let the element type decode it
1612 p_tok
.set_buf_pos(buf_pos
);
1614 Base_Type
* val
= create_elem();
1615 ret_val
= val
->JSON_decode(*p_td
.oftype_descr
, p_tok
, p_silent
);
1616 if (JSON_ERROR_INVALID_TOKEN
== ret_val
) {
1617 // undo the last action on the buffer
1618 p_tok
.set_buf_pos(buf_pos
);
1622 else if (JSON_ERROR_FATAL
== ret_val
) {
1627 return JSON_ERROR_FATAL
;
1629 if (NULL
== refd_ind_ptr
) {
1630 val_ptr
->value_elements
= (Base_Type
**)reallocate_pointers(
1631 (void**)val_ptr
->value_elements
, val_ptr
->n_elements
, nof_elements
+ 1);
1632 val_ptr
->value_elements
[nof_elements
] = val
;
1633 val_ptr
->n_elements
= nof_elements
+ 1;
1636 get_at(nof_elements
)->set_value(val
);
1642 dec_len
+= p_tok
.get_next_token(&token
, NULL
, NULL
);
1643 if (JSON_TOKEN_ARRAY_END
!= token
) {
1644 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG
, JSON_DEC_REC_OF_END_TOKEN_ERROR
, "");
1648 return JSON_ERROR_FATAL
;
1654 void Record_Of_Type::encode(const TTCN_Typedescriptor_t
& p_td
,
1655 TTCN_Buffer
& p_buf
, TTCN_EncDec::coding_t p_coding
, ...) const
1658 va_start(pvar
, p_coding
);
1660 case TTCN_EncDec::CT_BER
: {
1661 TTCN_EncDec_ErrorContext
ec("While BER-encoding type '%s': ", p_td
.name
);
1662 unsigned BER_coding
=va_arg(pvar
, unsigned);
1663 BER_encode_chk_coding(BER_coding
);
1664 ASN_BER_TLV_t
*tlv
=BER_encode_TLV(p_td
, BER_coding
);
1665 tlv
->put_in_buffer(p_buf
);
1666 ASN_BER_TLV_t::destruct(tlv
);
1668 case TTCN_EncDec::CT_RAW
: {
1669 TTCN_EncDec_ErrorContext
ec("While RAW-encoding type '%s': ", p_td
.name
);
1671 TTCN_EncDec_ErrorContext::error_internal("No RAW descriptor available for type '%s'.", p_td
.name
);
1675 RAW_enc_tree
root(FALSE
, NULL
, &rp
, 1, p_td
.raw
);
1676 RAW_encode(p_td
, root
);
1677 root
.put_to_buf(p_buf
);
1679 case TTCN_EncDec::CT_TEXT
: {
1680 TTCN_EncDec_ErrorContext
ec("While TEXT-encoding type '%s': ", p_td
.name
);
1681 if(!p_td
.text
) TTCN_EncDec_ErrorContext::error_internal
1682 ("No TEXT descriptor available for type '%s'.", p_td
.name
);
1683 TEXT_encode(p_td
,p_buf
);
1685 case TTCN_EncDec::CT_XER
: {
1686 TTCN_EncDec_ErrorContext
ec("While XER-encoding type '%s': ", p_td
.name
);
1687 unsigned XER_coding
=va_arg(pvar
, unsigned);
1688 XER_encode(*(p_td
.xer
),p_buf
, XER_coding
, 0, 0);
1691 case TTCN_EncDec::CT_JSON
: {
1692 TTCN_EncDec_ErrorContext
ec("While JSON-encoding type '%s': ", p_td
.name
);
1693 if(!p_td
.json
) TTCN_EncDec_ErrorContext::error_internal
1694 ("No JSON descriptor available for type '%s'.", p_td
.name
);
1695 JSON_Tokenizer
tok(va_arg(pvar
, int) != 0);
1696 JSON_encode(p_td
, tok
);
1697 p_buf
.put_s(tok
.get_buffer_length(), (const unsigned char*)tok
.get_buffer());
1700 TTCN_error("Unknown coding method requested to encode type '%s'", p_td
.name
);
1705 void Record_Of_Type::decode(const TTCN_Typedescriptor_t
& p_td
,
1706 TTCN_Buffer
& p_buf
, TTCN_EncDec::coding_t p_coding
, ...)
1709 va_start(pvar
, p_coding
);
1711 case TTCN_EncDec::CT_BER
: {
1712 TTCN_EncDec_ErrorContext
ec("While BER-decoding type '%s': ", p_td
.name
);
1713 unsigned L_form
=va_arg(pvar
, unsigned);
1715 BER_decode_str2TLV(p_buf
, tlv
, L_form
);
1716 BER_decode_TLV(p_td
, tlv
, L_form
);
1717 if(tlv
.isComplete
) p_buf
.increase_pos(tlv
.get_len());
1719 case TTCN_EncDec::CT_RAW
: {
1720 TTCN_EncDec_ErrorContext
ec("While RAW-decoding type '%s': ", p_td
.name
);
1721 if(!p_td
.raw
) TTCN_EncDec_ErrorContext::error_internal
1722 ("No RAW descriptor available for type '%s'.", p_td
.name
);
1724 switch(p_td
.raw
->top_bit_order
) {
1732 if(RAW_decode(p_td
, p_buf
, p_buf
.get_len()*8, order
)<0)
1733 ec
.error(TTCN_EncDec::ET_INCOMPL_MSG
,"Can not decode type '%s', "
1734 "because invalid or incomplete message was received", p_td
.name
);
1736 case TTCN_EncDec::CT_TEXT
: {
1737 Limit_Token_List limit
;
1738 TTCN_EncDec_ErrorContext
ec("While TEXT-decoding type '%s': ", p_td
.name
);
1739 if(!p_td
.text
) TTCN_EncDec_ErrorContext::error_internal
1740 ("No TEXT descriptor available for type '%s'.", p_td
.name
);
1741 const unsigned char *b
=p_buf
.get_data();
1742 if(b
[p_buf
.get_len()-1]!='\0'){
1743 p_buf
.set_pos(p_buf
.get_len());
1744 p_buf
.put_zero(8,ORDER_LSB
);
1747 if(TEXT_decode(p_td
,p_buf
,limit
)<0)
1748 ec
.error(TTCN_EncDec::ET_INCOMPL_MSG
,"Can not decode type '%s', "
1749 "because invalid or incomplete message was received", p_td
.name
);
1751 case TTCN_EncDec::CT_XER
: {
1752 TTCN_EncDec_ErrorContext
ec("While XER-decoding type '%s': ", p_td
.name
);
1753 unsigned XER_coding
=va_arg(pvar
, unsigned);
1754 XmlReaderWrap
reader(p_buf
);
1755 for (int success
=reader
.Read(); success
==1; success
=reader
.Read()) {
1756 if (reader
.NodeType() == XML_READER_TYPE_ELEMENT
) break;
1758 XER_decode(*(p_td
.xer
), reader
, XER_coding
| XER_TOPLEVEL
, XER_NONE
, 0);
1759 size_t bytes
= reader
.ByteConsumed();
1760 p_buf
.set_pos(bytes
);
1762 case TTCN_EncDec::CT_JSON
: {
1763 TTCN_EncDec_ErrorContext
ec("While JSON-decoding type '%s': ", p_td
.name
);
1764 if(!p_td
.json
) TTCN_EncDec_ErrorContext::error_internal
1765 ("No JSON descriptor available for type '%s'.", p_td
.name
);
1766 JSON_Tokenizer
tok((const char*)p_buf
.get_data(), p_buf
.get_len());
1767 if(JSON_decode(p_td
, tok
, false)<0)
1768 ec
.error(TTCN_EncDec::ET_INCOMPL_MSG
,"Can not decode type '%s', "
1769 "because invalid or incomplete message was received", p_td
.name
);
1770 p_buf
.set_pos(tok
.get_buf_pos());
1773 TTCN_error("Unknown coding method requested to decode type '%s'", p_td
.name
);
1778 char **Record_Of_Type::collect_ns(const XERdescriptor_t
& p_td
, size_t& num
, bool& def_ns
) const
1780 size_t num_collected
= 0;
1781 // First, our own namespace. Sets num_collected to 0 or 1.
1782 // If it throws, nothing was allocated.
1783 char **collected_ns
= Base_Type::collect_ns(p_td
, num_collected
, def_ns
);
1785 // Then the embedded type
1787 bool def_ns_1
= false;
1788 if (val_ptr
) for (int i
= 0; i
< get_nof_elements(); ++i
) {
1790 char **new_namespaces
= get_at(i
)->collect_ns(
1791 *p_td
.oftype_descr
, num_new
, def_ns_1
);
1792 merge_ns(collected_ns
, num_collected
, new_namespaces
, num_new
);
1793 def_ns
= def_ns
|| def_ns_1
; // alas, no ||=
1797 // Probably a TC_Error thrown from the element's collect_ns(),
1798 // e.g. if encoding an unbound value.
1799 while (num_collected
> 0) Free(collected_ns
[--num_collected
]);
1804 num
= num_collected
;
1805 return collected_ns
;
1808 static const universal_char sp
= { 0,0,0,' ' };
1809 static const universal_char tb
= { 0,0,0,9 };
1811 int Record_Of_Type::XER_encode(const XERdescriptor_t
& p_td
, TTCN_Buffer
& p_buf
,
1812 unsigned int flavor
, int indent
, embed_values_enc_struct_t
* emb_val
) const
1815 return XER_encode_negtest(err_descr
, p_td
, p_buf
, flavor
, indent
, emb_val
);
1818 if (val_ptr
== 0) TTCN_error(
1819 "Attempt to XER-encode an unbound record of type %s", get_descriptor()->name
);
1820 int encoded_length
= (int)p_buf
.get_len();
1822 const int exer
= is_exer(flavor
);
1823 const boolean own_tag
=
1824 !(exer
&& indent
&& (p_td
.xer_bits
& (ANY_ELEMENT
|ANY_ATTRIBUTES
|UNTAGGED
)));
1826 const int indenting
= !is_canonical(flavor
) && own_tag
;
1827 const boolean xmlValueList
= isXmlValueList();
1830 | ( (exer
&& (p_td
.xer_bits
& XER_LIST
))
1831 || is_exerlist(flavor
) ? SIMPLE_TYPE
: 0);
1832 flavor
&= ~XER_RECOF
; // record-of doesn't care
1833 int nof_elements
= get_nof_elements();
1834 Base_Type::begin_xml(p_td
, p_buf
, flavor
, indent
, !nof_elements
,
1835 (collector_fn
)&Record_Of_Type::collect_ns
);
1837 if (xmlValueList
&& nof_elements
&& indenting
&& !exer
) { /* !exer or GDMO */
1838 do_indent(p_buf
, indent
+1);
1841 if (exer
&& (p_td
.xer_bits
& ANY_ATTRIBUTES
)) {
1842 // Back up over the '>' and the '\n' that may follow it
1843 size_t buf_len
= p_buf
.get_len(), shorter
= 0;
1844 const unsigned char * const buf_data
= p_buf
.get_data();
1845 if (buf_data
[buf_len
- 1 - shorter
] == '\n') ++shorter
;
1846 if (buf_data
[buf_len
- 1 - shorter
] == '>' ) ++shorter
;
1848 unsigned char saved
[4];
1850 memcpy(saved
, buf_data
+ (buf_len
- shorter
), shorter
);
1851 p_buf
.increase_length(-shorter
);
1854 // ANY_ATTRIBUTES means it's a record of universal charstring.
1855 // They are in AnyAttributeFormat (X.693/2008 18.2.6):
1856 // "URI(optional), space, NCName, equals, \"xmlcstring\""
1857 // They need to be written as an XML attribute and namespace declaration:
1858 // xmlns:b0="URI" b0:NCName="xmlcstring"
1860 for (int i
= 0; i
< nof_elements
; ++i
) {
1861 TTCN_EncDec_ErrorContext
ec_0("Attribute %d: ", i
);
1862 if (!is_elem_bound(i
)) {
1863 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND
,
1864 "Encoding an unbound universal charstring value.");
1867 const UNIVERSAL_CHARSTRING
*elem
1868 = static_cast<const UNIVERSAL_CHARSTRING
*>(val_ptr
->value_elements
[i
]);
1869 size_t len
= elem
->lengthof();
1871 const UNIVERSAL_CHARSTRING_ELEMENT
& ue
= (*elem
)[len
- 1];
1872 if (sp
== ue
|| tb
== ue
) --len
;
1875 // sp_at: indexes the first space
1876 // j is left to point at where the attribute name begins (just past the space)
1877 size_t j
, sp_at
= 0;
1878 for (j
= 0; j
< len
; j
++) {
1879 const UNIVERSAL_CHARSTRING_ELEMENT
& ue
= (*elem
)[j
];
1880 if (sp_at
) { // already found a space
1881 if (sp
== ue
|| tb
== ue
) {} // another space, do nothing
1882 else break; // found a non-space after a space
1885 if (sp
== ue
|| tb
== ue
) sp_at
= j
;
1889 size_t buf_start
= p_buf
.get_len();
1891 char * ns
= mprintf(" xmlns:b%d='", i
);
1892 size_t ns_len
= mstrlen(ns
);
1893 p_buf
.put_s(ns_len
, (cbyte
*)ns
);
1895 UNIVERSAL_CHARSTRING
before(sp_at
, (const universal_char
*)(*elem
));
1896 if (p_td
.xer_bits
& (ANY_FROM
| ANY_EXCEPT
)) {
1897 // Ensure the namespace abides to its restrictions
1899 before
.encode_utf8(ns_buf
);
1901 ns_buf
.get_string(cs
);
1902 check_namespace_restrictions(p_td
, (const char*)cs
);
1904 before
.XER_encode(UNIVERSAL_CHARSTRING_xer_
, p_buf
,
1905 flavor
| ANY_ATTRIBUTES
, indent
, 0);
1910 // Keep just the "b%d" part from ns
1911 p_buf
.put_s(ns_len
- 9, (cbyte
*)ns
+ 7);
1919 if (p_td
.xer_bits
& (ANY_FROM
| ANY_EXCEPT
)) {
1920 // Make sure the unqualified namespace is allowed
1921 check_namespace_restrictions(p_td
, NULL
);
1925 UNIVERSAL_CHARSTRING
after(len
- j
, (const universal_char
*)(*elem
) + j
);
1926 after
.XER_encode(UNIVERSAL_CHARSTRING_xer_
, p_buf
,
1927 flavor
| ANY_ATTRIBUTES
, indent
, 0);
1929 // Put this attribute in a dummy element and walk through it to check its validity
1930 TTCN_Buffer check_buf
;
1931 check_buf
.put_s(2, (unsigned char*)"<a");
1932 check_buf
.put_s(p_buf
.get_len() - buf_start
, p_buf
.get_data() + buf_start
);
1933 check_buf
.put_s(2, (unsigned char*)"/>");
1934 XmlReaderWrap
checker(check_buf
);
1935 while (1 == checker
.Read());
1938 p_buf
.put_s(shorter
, saved
); // restore the '>' and anything after
1941 else { // not ANY-ATTRIBUTES
1942 unsigned int sub_flavor
= flavor
| XER_RECOF
| (p_td
.xer_bits
& (XER_LIST
));
1943 TTCN_EncDec_ErrorContext
ec_0("Index ");
1944 TTCN_EncDec_ErrorContext ec_1
;
1946 for (int i
= 0; i
< nof_elements
; ++i
) {
1947 if (i
> 0 && !own_tag
&& 0 != emb_val
&&
1948 emb_val
->embval_index
< emb_val
->embval_array
->size_of()) {
1949 emb_val
->embval_array
->get_at(emb_val
->embval_index
)->XER_encode(
1950 UNIVERSAL_CHARSTRING_xer_
, p_buf
, flavor
| EMBED_VALUES
, indent
+1, 0);
1951 ++emb_val
->embval_index
;
1953 ec_1
.set_msg("%d: ", i
);
1954 if (exer
&& (p_td
.xer_bits
& XER_LIST
) && i
>0) p_buf
.put_c(' ');
1955 get_at(i
)->XER_encode(*p_td
.oftype_descr
, p_buf
,
1956 sub_flavor
, indent
+own_tag
, emb_val
);
1959 if (indenting
&& nof_elements
&& !is_exerlist(flavor
)) {
1960 if (xmlValueList
&& !exer
) p_buf
.put_c('\n'); /* !exer or GDMO */
1961 //do_indent(p_buf, indent);
1965 Base_Type::end_xml(p_td
, p_buf
, flavor
, indent
, !nof_elements
);
1966 return (int)p_buf
.get_len() - encoded_length
;
1969 // XERSTUFF Record_Of_Type::encode_element
1970 /** Helper for Record_Of_Type::XER_encode_negtest
1972 * The main purpose of this method is to allow another type to request
1973 * encoding of a single element of the record-of. Used by Record_Type
1974 * to encode individual strings of the EMBED-VALUES member.
1976 * @param i index of the element
1977 * @param ev erroneous descriptor for the element itself
1978 * @param ed deeper erroneous values
1979 * @param p_buf buffer containing the encoded value
1980 * @param sub_flavor flags
1981 * @param indent indentation level
1982 * @return number of bytes generated
1984 int Record_Of_Type::encode_element(int i
, const XERdescriptor_t
& p_td
,
1985 const Erroneous_values_t
* ev
, const Erroneous_descriptor_t
* ed
,
1986 TTCN_Buffer
& p_buf
, unsigned int sub_flavor
, int indent
, embed_values_enc_struct_t
* emb_val
) const
1988 int enc_len
= p_buf
.get_len();
1989 TTCN_EncDec_ErrorContext ec
;
1990 const int exer
= is_exer(sub_flavor
);
1992 if (ev
&& ev
->before
) {
1993 if (ev
->before
->errval
==NULL
) {
1994 TTCN_error("internal error: erroneous before value missing");
1996 ec
.set_msg("Erroneous value before component #%d: ", i
);
1997 if (ev
->before
->raw
) {
1998 ev
->before
->errval
->encode_raw(p_buf
);
2000 if (ev
->before
->type_descr
==NULL
) TTCN_error(
2001 "internal error: erroneous before type descriptor missing");
2002 ev
->before
->errval
->XER_encode(*ev
->before
->type_descr
->xer
,
2003 p_buf
, sub_flavor
, indent
, 0);
2007 if (exer
&& (sub_flavor
& XER_LIST
)
2008 && (i
> 0 || (ev
&& ev
->before
&& !ev
->before
->raw
))){
2009 // Ensure a separator is written after the "erroneous before"
2010 // of the first element (except for "raw before").
2014 if (ev
&& ev
->value
) {
2015 if (ev
->value
->errval
) { // replace
2016 ec
.set_msg("Erroneous value for component #%d: ", i
);
2017 if (ev
->value
->raw
) {
2018 ev
->value
->errval
->encode_raw(p_buf
);
2020 if (ev
->value
->type_descr
==NULL
) TTCN_error(
2021 "internal error: erroneous value type descriptor missing");
2022 ev
->value
->errval
->XER_encode(*ev
->value
->type_descr
->xer
,
2023 p_buf
, sub_flavor
, indent
, 0);
2027 ec
.set_msg("Component #%d: ", i
);
2029 get_at(i
)->XER_encode_negtest(ed
, p_td
, p_buf
, sub_flavor
, indent
, emb_val
);
2031 // the "real" encoder
2032 get_at(i
)->XER_encode(p_td
, p_buf
, sub_flavor
, indent
, emb_val
);
2036 if (ev
&& ev
->after
) {
2037 if (ev
->after
->errval
==NULL
) {
2038 TTCN_error("internal error: erroneous after value missing");
2040 ec
.set_msg("Erroneous value after component #%d: ", i
);
2041 if (ev
->after
->raw
) {
2042 ev
->after
->errval
->encode_raw(p_buf
);
2044 if (ev
->after
->type_descr
==NULL
) TTCN_error(
2045 "internal error: erroneous after type descriptor missing");
2046 ev
->after
->errval
->XER_encode(*ev
->after
->type_descr
->xer
,
2047 p_buf
, sub_flavor
, indent
, 0);
2054 // XERSTUFF Record_Of_Type::XER_encode_negtest
2055 int Record_Of_Type::XER_encode_negtest(const Erroneous_descriptor_t
* p_err_descr
,
2056 const XERdescriptor_t
& p_td
, TTCN_Buffer
& p_buf
, unsigned flavor
, int indent
,
2057 embed_values_enc_struct_t
* emb_val
) const
2059 if (val_ptr
== 0) TTCN_error(
2060 "Attempt to XER-encode an unbound record of type %s", get_descriptor()->name
);
2061 int encoded_length
= (int)p_buf
.get_len();
2063 const int exer
= is_exer(flavor
);
2064 const boolean own_tag
=
2065 !(exer
&& indent
&& (p_td
.xer_bits
& (ANY_ELEMENT
|ANY_ATTRIBUTES
|UNTAGGED
)));
2067 const int indenting
= !is_canonical(flavor
) && own_tag
;
2068 const boolean xmlValueList
= isXmlValueList();
2071 | ( (exer
&& (p_td
.xer_bits
& XER_LIST
))
2072 || is_exerlist(flavor
) ? SIMPLE_TYPE
: 0);
2073 flavor
&= ~XER_RECOF
; // record-of doesn't care
2074 int nof_elements
= get_nof_elements();
2075 Base_Type::begin_xml(p_td
, p_buf
, flavor
, indent
, !nof_elements
,
2076 (collector_fn
)&Record_Of_Type::collect_ns
);
2078 if (xmlValueList
&& nof_elements
&& indenting
&& !exer
) { /* !exer or GDMO */
2079 do_indent(p_buf
, indent
+1);
2084 if (exer
&& (p_td
.xer_bits
& ANY_ATTRIBUTES
)) {
2085 // Back up over the '>' and the '\n' that may follow it
2086 size_t buf_len
= p_buf
.get_len(), shorter
= 0;
2087 const unsigned char * const buf_data
= p_buf
.get_data();
2088 if (buf_data
[buf_len
- 1 - shorter
] == '\n') ++shorter
;
2089 if (buf_data
[buf_len
- 1 - shorter
] == '>' ) ++shorter
;
2091 unsigned char * saved
= 0;
2093 saved
= new unsigned char[shorter
];
2094 memcpy(saved
, buf_data
+ (buf_len
- shorter
), shorter
);
2095 p_buf
.increase_length(-shorter
);
2098 // ANY_ATTRIBUTES means it's a record of universal charstring.
2099 // They are in AnyAttributeFormat (X.693/2008 18.2.6):
2100 // "URI(optional), space, NCName, equals, \"xmlcstring\""
2101 // They need to be written as an XML attribute and namespace declaration:
2102 // xmlns:b0="URI" b0:NCName="xmlcstring"
2104 for (int i
= 0; i
< nof_elements
; ++i
) {
2105 if (i
< p_err_descr
->omit_before
) continue;
2107 const Erroneous_values_t
*ev
= p_err_descr
->next_field_err_values(i
, values_idx
);
2108 const Erroneous_descriptor_t
*ed
= p_err_descr
->next_field_emb_descr(i
, edescr_idx
);
2110 if (ev
&& ev
->before
) {
2111 if (ev
->before
->errval
==NULL
) TTCN_error("internal error: erroneous value missing");
2114 if (ev
->before
->raw
) ev
->before
->errval
->encode_raw(p_buf
);
2116 if (ev
->before
->type_descr
==NULL
) TTCN_error(
2117 "internal error: erroneous before type descriptor missing");
2118 else ev
->before
->errval
->XER_encode(*ev
->before
->type_descr
->xer
,
2119 p_buf
, flavor
, indent
, 0);
2123 if (ev
&& ev
->value
) { //value replacement
2124 if (ev
->value
->errval
) {
2125 if (ev
->value
->raw
) ev
->value
->errval
->encode_raw(p_buf
);
2127 if (ev
->value
->type_descr
==NULL
) TTCN_error(
2128 "internal error: erroneous value type descriptor missing");
2129 else ev
->value
->errval
->XER_encode(*ev
->value
->type_descr
->xer
,
2130 p_buf
, flavor
, indent
, 0);
2136 // embedded descr.. call negtest (except UNIVERSAL_CHARSTRING
2137 // doesn't have XER_encode_negtest)
2138 TTCN_error("internal error: embedded descriptor for scalar");
2141 // the original encoding
2142 const UNIVERSAL_CHARSTRING
*elem
2143 = static_cast<const UNIVERSAL_CHARSTRING
*>(get_at(i
));
2144 size_t len
= elem
->lengthof();
2146 const UNIVERSAL_CHARSTRING_ELEMENT
& ue
= (*elem
)[len
- 1];
2147 if (sp
== ue
|| tb
== ue
) --len
;
2150 // sp_at: indexes the first space
2151 // j is left to point at where the attribute name begins (just past the space)
2152 size_t j
, sp_at
= 0;
2153 for (j
= 0; j
< len
; j
++) {
2154 const UNIVERSAL_CHARSTRING_ELEMENT
& ue
= (*elem
)[j
];
2155 if (sp_at
) { // already found a space
2156 if (sp
== ue
|| tb
== ue
) {} // another space, do nothing
2157 else break; // found a non-space after a space
2160 if (sp
== ue
|| tb
== ue
) sp_at
= j
;
2165 char * ns
= mprintf(" xmlns:b%d='", i
);
2166 size_t ns_len
= mstrlen(ns
);
2167 p_buf
.put_s(ns_len
, (cbyte
*)ns
);
2169 UNIVERSAL_CHARSTRING
before(sp_at
, (const universal_char
*)(*elem
));
2170 before
.XER_encode(UNIVERSAL_CHARSTRING_xer_
, p_buf
,
2171 flavor
| ANY_ATTRIBUTES
, indent
, 0);
2176 // Keep just the "b%d" part from ns
2177 p_buf
.put_s(ns_len
- 9, (cbyte
*)ns
+ 7);
2186 UNIVERSAL_CHARSTRING
after(len
- j
, (const universal_char
*)(*elem
) + j
);
2187 after
.XER_encode(UNIVERSAL_CHARSTRING_xer_
, p_buf
,
2188 flavor
| ANY_ATTRIBUTES
, indent
, 0);
2192 if (ev
&& ev
->after
) {
2193 if (ev
->after
->errval
==NULL
) TTCN_error(
2194 "internal error: erroneous after value missing");
2196 if (ev
->after
->raw
) ev
->after
->errval
->encode_raw(p_buf
);
2198 if (ev
->after
->type_descr
==NULL
) TTCN_error(
2199 "internal error: erroneous after type descriptor missing");
2200 else ev
->after
->errval
->XER_encode(*ev
->after
->type_descr
->xer
,
2201 p_buf
, flavor
, indent
, 0);
2205 // omit_after value -1 becomes "very big"
2206 if ((unsigned int)i
>= (unsigned int)p_err_descr
->omit_after
) break;
2209 p_buf
.put_s(shorter
, saved
); // restore the '>' and anything after
2213 else { // not ANY-ATTRIBUTES
2214 unsigned int sub_flavor
= flavor
| XER_RECOF
| (p_td
.xer_bits
& (XER_LIST
|ANY_ATTRIBUTES
));
2216 TTCN_EncDec_ErrorContext ec
;
2218 for (int i
= 0; i
< nof_elements
; ++i
) {
2219 if (i
< p_err_descr
->omit_before
) continue;
2221 if (0 != emb_val
&& i
> 0 && !own_tag
&&
2222 emb_val
->embval_index
< emb_val
->embval_array
->size_of()) {
2223 const Erroneous_values_t
* ev0_i
= NULL
;
2224 const Erroneous_descriptor_t
* ed0_i
= NULL
;
2225 if (emb_val
->embval_err
) {
2226 ev0_i
= emb_val
->embval_err
->next_field_err_values(emb_val
->embval_index
, emb_val
->embval_err_val_idx
);
2227 ed0_i
= emb_val
->embval_err
->next_field_emb_descr (emb_val
->embval_index
, emb_val
->embval_err_descr_idx
);
2229 emb_val
->embval_array
->encode_element(emb_val
->embval_index
, UNIVERSAL_CHARSTRING_xer_
,
2230 ev0_i
, ed0_i
, p_buf
, flavor
| EMBED_VALUES
, indent
+ own_tag
, 0);
2231 ++emb_val
->embval_index
;
2234 const Erroneous_values_t
* err_vals
=
2235 p_err_descr
->next_field_err_values(i
, values_idx
);
2236 const Erroneous_descriptor_t
* emb_descr
=
2237 p_err_descr
->next_field_emb_descr (i
, edescr_idx
);
2239 encode_element(i
, *p_td
.oftype_descr
, err_vals
, emb_descr
, p_buf
, sub_flavor
, indent
+own_tag
, emb_val
);
2241 // omit_after value -1 becomes "very big"
2242 if ((unsigned int)i
>= (unsigned int)p_err_descr
->omit_after
) break;
2245 if (indenting
&& nof_elements
&& !is_exerlist(flavor
)) {
2246 if (xmlValueList
&& !exer
) p_buf
.put_c('\n'); /* !exer or GDMO */
2247 //do_indent(p_buf, indent);
2251 Base_Type::end_xml(p_td
, p_buf
, flavor
, indent
, !nof_elements
);
2252 return (int)p_buf
.get_len() - encoded_length
;
2255 int Record_Of_Type::XER_decode(const XERdescriptor_t
& p_td
,
2256 XmlReaderWrap
& reader
, unsigned int flavor
, unsigned int flavor2
, embed_values_dec_struct_t
* emb_val
)
2258 int exer
= is_exer(flavor
);
2259 int xerbits
= p_td
.xer_bits
;
2260 if (flavor
& XER_TOPLEVEL
) xerbits
&= ~UNTAGGED
;
2262 !(exer
&& ((xerbits
& (ANY_ELEMENT
| ANY_ATTRIBUTES
| UNTAGGED
))
2263 || (flavor
& USE_TYPE_ATTR
))); /* incase the parent has USE-UNION */
2264 /* not toplevel anymore and remove the flags for USE-UNION the oftype doesn't need them */
2265 flavor
&= ~XER_TOPLEVEL
& ~XER_LIST
& ~USE_TYPE_ATTR
;
2266 int success
=1, depth
=-1;
2267 set_val(NULL_VALUE
); // empty but initialized array, val_ptr != NULL
2269 if (own_tag
) for (success
= 1; success
== 1; success
= reader
.Read()) {
2270 type
= reader
.NodeType();
2271 if (exer
&& (p_td
.xer_bits
& XER_ATTRIBUTE
)) {
2272 if (XML_READER_TYPE_ATTRIBUTE
== type
) break;
2274 if (exer
&& (p_td
.xer_bits
& XER_LIST
)) {
2275 if (XML_READER_TYPE_TEXT
== type
) break;
2278 if (XML_READER_TYPE_ELEMENT
== type
) {
2279 verify_name(reader
, p_td
, exer
);
2280 depth
= reader
.Depth();
2283 } /* endif(exer && list) */
2285 else depth
= reader
.Depth();
2286 TTCN_EncDec_ErrorContext
ec_0("Index ");
2287 TTCN_EncDec_ErrorContext ec_1
;
2288 flavor
|= XER_RECOF
;
2289 if (exer
&& (p_td
.xer_bits
& ANY_ATTRIBUTES
)) {
2290 // The enclosing type should handle the decoding.
2291 TTCN_error("Incorrect decoding of ANY-ATTRIBUTES");
2293 else if (exer
&& (p_td
.xer_bits
& XER_LIST
)) { /* LIST decoding*/
2294 char *val
= (char*)reader
.NewValue(); /* we own it */
2296 size_t len
= strlen(val
);
2297 /* The string contains a bunch of values separated by whitespace.
2298 * Tokenize the string and create a new buffer which looks like
2299 * an XML element (<ns:name xmlns:ns='uri'>value</ns:name>), then use that
2300 * to decode the value. */
2301 for(char * str
= strtok(val
, " \t\x0A\x0D"); str
!= 0; str
= strtok(val
+ pos
, " \t\x0A\x0D")) {
2302 // Calling strtok with NULL won't work here, since the decoded element can have strtok calls aswell
2303 pos
+= strlen(str
) + 1;
2304 // Construct a new XML Reader with the current token.
2306 const XERdescriptor_t
& sub_xer
= *p_td
.oftype_descr
;
2308 write_ns_prefix(sub_xer
, buf2
);
2310 boolean i_can_has_ns
= sub_xer
.my_module
!= 0 && sub_xer
.ns_index
!= -1;
2311 const char * const exer_name
= sub_xer
.names
[1];
2312 buf2
.put_s((size_t)sub_xer
.namelens
[1]-1-i_can_has_ns
, (cbyte
*)exer_name
);
2314 const namespace_t
* const pns
= sub_xer
.my_module
->get_ns(sub_xer
.ns_index
);
2315 buf2
.put_s(7 - (*pns
->px
== 0), (cbyte
*)" xmlns:");
2316 buf2
.put_s(strlen(pns
->px
), (cbyte
*)pns
->px
);
2317 buf2
.put_s(2, (cbyte
*)"='");
2318 buf2
.put_s(strlen(pns
->ns
), (cbyte
*)pns
->ns
);
2319 buf2
.put_s(2, (cbyte
*)"'>");
2321 // start tag completed
2322 buf2
.put_s(strlen(str
), (cbyte
*)str
);
2326 write_ns_prefix(sub_xer
, buf2
);
2327 buf2
.put_s((size_t)sub_xer
.namelens
[1], (cbyte
*)exer_name
);
2328 XmlReaderWrap
reader2(buf2
);
2329 reader2
.Read(); // Move to the start element.
2330 // Don't move to the #text, that's the callee's responsibility.
2331 ec_1
.set_msg("%d: ", get_nof_elements());
2332 // The call to the non-const operator[], I mean get_at(), creates
2333 // a new element (because it is indexing one past the last element).
2334 // Then we call its XER_decode with the temporary XML reader.
2335 get_at(get_nof_elements())->XER_decode(sub_xer
, reader2
, flavor
, flavor2
, 0);
2336 if (flavor
& EXIT_ON_ERROR
&& !is_elem_bound(get_nof_elements() - 1)) {
2337 if (1 == get_nof_elements()) {
2338 // Failed to decode even the first element
2341 // Some elements were successfully decoded -> only delete the last one
2342 set_size(get_nof_elements() - 1);
2347 if (pos
>= len
) break;
2350 if (p_td
.xer_bits
& XER_ATTRIBUTE
) {
2351 //Let the caller do reader.AdvanceAttribute();
2354 reader
.Read(); // on closing tag
2355 reader
.Read(); // past it
2359 if (flavor
& PARENT_CLOSED
) {
2360 // Nothing to do. We are probably untagged; do not advance in the XML
2361 // because it would move past the parent.
2363 else if (own_tag
&& reader
.IsEmptyElement()) { // Nothing to do
2364 reader
.Read(); // This is our own empty tag, move past it
2367 /* Note: there is no reader.Read() at the end of the loop below.
2368 * Each element is supposed to consume enough to leave the next element
2369 * well-positioned. */
2370 for (success
= own_tag
? reader
.Read() : reader
.Ok(); success
== 1; ) {
2371 type
= reader
.NodeType();
2372 if (XML_READER_TYPE_ELEMENT
== type
)
2374 if (exer
&& (p_td
.xer_bits
& ANY_ELEMENT
)) {
2375 /* This is a (record-of UNIVERSAL_CHARSTRING) with ANY-ELEMENT.
2376 * The ANY-ELEMENT is really meant for the element type,
2377 * so behave like a record-of (string with ANY-ELEMENT):
2378 * call the non-const operator[], I mean get_at(), to create
2379 * a new element, then read the entire XML element into it. */
2380 UNIVERSAL_CHARSTRING
* uc
=
2381 static_cast<UNIVERSAL_CHARSTRING
*>(get_at(val_ptr
->n_elements
));
2382 const xmlChar
* outer
= reader
.ReadOuterXml();
2383 uc
->decode_utf8(strlen((const char*)outer
), outer
);
2384 // consume the element
2385 for (success
= reader
.Read(); success
== 1 && reader
.Depth() > depth
; success
= reader
.Read()) {}
2386 if (reader
.NodeType() != XML_READER_TYPE_ELEMENT
) success
= reader
.Read(); // one last time
2389 /* If this is an untagged record-of and the start element does not
2390 * belong to the embedded type, the record-of has already ended. */
2391 if (!own_tag
&& !can_start_v(
2392 (const char*)reader
.LocalName(), (const char*)reader
.NamespaceUri(),
2393 p_td
, flavor
| UNTAGGED
))
2395 for (; success
== 1 && reader
.Depth() > depth
; success
= reader
.Read()) ;
2396 // We should now be back at the same depth as we started.
2399 ec_1
.set_msg("%d: ", get_nof_elements());
2400 /* The call to the non-const get_at() creates the element */
2401 get_at(get_nof_elements())->XER_decode(*p_td
.oftype_descr
, reader
, flavor
, flavor2
, emb_val
);
2403 if (0 != emb_val
&& !own_tag
&& get_nof_elements() > 1) {
2404 ++emb_val
->embval_index
;
2407 else if (XML_READER_TYPE_END_ELEMENT
== type
) {
2408 for (; success
== 1 && reader
.Depth() > depth
; success
= reader
.Read()) ;
2409 // If the depth just decreased, this must be an end element
2410 // (but a different one from what we had before the loop)
2412 verify_end(reader
, p_td
, depth
, exer
);
2413 reader
.Read(); // move forward one last time
2417 else if (XML_READER_TYPE_TEXT
== type
&& 0 != emb_val
&& !own_tag
&& get_nof_elements() > 0) {
2418 UNIVERSAL_CHARSTRING
emb_ustr((const char*)reader
.Value());
2419 emb_val
->embval_array
->get_at(emb_val
->embval_index
)->set_value(&emb_ustr
);
2420 success
= reader
.Read();
2423 success
= reader
.Read();
2426 } /* if not empty element */
2428 if (!own_tag
&& exer
&& (p_td
.xer_bits
& XER_OPTIONAL
) && get_nof_elements() == 0) {
2429 // set it to unbound, so the OPTIONAL class sets it to omit
2432 return 1; // decode successful
2435 void Record_Of_Type::set_param(Module_Param
& param
) {
2436 if (dynamic_cast<Module_Param_Name
*>(param
.get_id()) != NULL
&&
2437 param
.get_id()->next_name()) {
2438 // Haven't reached the end of the module parameter name
2439 // => the name refers to one of the elements, not to the whole record of
2440 char* param_field
= param
.get_id()->get_current_name();
2441 if (param_field
[0] < '0' || param_field
[0] > '9') {
2442 param
.error("Unexpected record field name in module parameter, expected a valid"
2443 " index for %s type `%s'", is_set() ? "set of" : "record of", get_descriptor()->name
);
2445 int param_index
= -1;
2446 sscanf(param_field
, "%d", ¶m_index
);
2447 get_at(param_index
)->set_param(param
);
2451 param
.basic_check(Module_Param::BC_VALUE
|Module_Param::BC_LIST
, is_set()?"set of value":"record of value");
2453 Module_Param_Ptr mp
= ¶m
;
2454 if (param
.get_type() == Module_Param::MP_Reference
) {
2455 mp
= param
.get_referenced_param();
2458 switch (param
.get_operation_type()) {
2459 case Module_Param::OT_ASSIGN
:
2460 if (mp
->get_type()==Module_Param::MP_Value_List
&& mp
->get_size()==0) {
2461 set_val(NULL_VALUE
);
2464 switch (mp
->get_type()) {
2465 case Module_Param::MP_Value_List
:
2466 set_size(mp
->get_size());
2467 for (size_t i
=0; i
<mp
->get_size(); ++i
) {
2468 Module_Param
* const curr
= mp
->get_elem(i
);
2469 if (curr
->get_type()!=Module_Param::MP_NotUsed
) {
2470 get_at(i
)->set_param(*curr
);
2474 case Module_Param::MP_Indexed_List
:
2475 for (size_t i
=0; i
<mp
->get_size(); ++i
) {
2476 Module_Param
* const current
= mp
->get_elem(i
);
2477 get_at(current
->get_id()->get_index())->set_param(*current
);
2481 param
.type_error(is_set()?"set of value":"record of value", get_descriptor()->name
);
2484 case Module_Param::OT_CONCAT
:
2485 switch (mp
->get_type()) {
2486 case Module_Param::MP_Value_List
: {
2487 if (!is_bound()) set_val(NULL_VALUE
);
2488 int start_idx
= lengthof();
2489 for (size_t i
=0; i
<mp
->get_size(); ++i
) {
2490 Module_Param
* const curr
= mp
->get_elem(i
);
2491 if ((curr
->get_type()!=Module_Param::MP_NotUsed
)) {
2492 get_at(start_idx
+(int)i
)->set_param(*curr
);
2496 case Module_Param::MP_Indexed_List
:
2497 param
.error("Cannot concatenate an indexed value list");
2500 param
.type_error(is_set()?"set of value":"record of value", get_descriptor()->name
);
2504 TTCN_error("Internal error: Record_Of_Type::set_param()");
2508 Module_Param
* Record_Of_Type::get_param(Module_Param_Name
& param_name
) const
2511 return new Module_Param_Unbound();
2513 if (param_name
.next_name()) {
2514 // Haven't reached the end of the module parameter name
2515 // => the name refers to one of the elements, not to the whole record of
2516 char* param_field
= param_name
.get_current_name();
2517 if (param_field
[0] < '0' || param_field
[0] > '9') {
2518 TTCN_error("Unexpected record field name in module parameter reference, "
2519 "expected a valid index for %s type `%s'",
2520 is_set() ? "set of" : "record of", get_descriptor()->name
);
2522 int param_index
= -1;
2523 sscanf(param_field
, "%d", ¶m_index
);
2524 return get_at(param_index
)->get_param(param_name
);
2526 Vector
<Module_Param
*> values
;
2527 for (int i
= 0; i
< val_ptr
->n_elements
; ++i
) {
2528 values
.push_back(val_ptr
->value_elements
[i
]->get_param(param_name
));
2530 Module_Param_Value_List
* mp
= new Module_Param_Value_List();
2531 mp
->add_list_with_implicit_ids(&values
);
2536 void Record_Of_Type::set_implicit_omit()
2538 for (int i
= 0; i
< get_nof_elements(); ++i
) {
2539 if (is_elem_bound(i
))
2540 val_ptr
->value_elements
[i
]->set_implicit_omit();
2544 void Record_Of_Type::add_refd_index(int index
)
2546 if (NULL
== refd_ind_ptr
) {
2547 refd_ind_ptr
= new refd_index_struct
;
2548 refd_ind_ptr
->max_refd_index
= -1;
2550 refd_ind_ptr
->refd_indices
.push_back(index
);
2551 if (index
> get_max_refd_index()) {
2552 refd_ind_ptr
->max_refd_index
= index
;
2556 void Record_Of_Type::remove_refd_index(int index
)
2558 for (size_t i
= refd_ind_ptr
->refd_indices
.size(); i
> 0; --i
) {
2559 if (refd_ind_ptr
->refd_indices
[i
- 1] == index
) {
2560 refd_ind_ptr
->refd_indices
.erase_at(i
- 1);
2564 if (refd_ind_ptr
->refd_indices
.empty()) {
2565 delete refd_ind_ptr
;
2566 refd_ind_ptr
= NULL
;
2568 else if (get_max_refd_index() == index
) {
2569 refd_ind_ptr
->max_refd_index
= -1;
2573 boolean
operator==(null_type
/*null_value*/, const Record_Of_Type
& other_value
)
2575 if (other_value
.val_ptr
== NULL
)
2576 TTCN_error("The right operand of comparison is an unbound value of type %s.",
2577 other_value
.get_descriptor()->name
);
2578 return other_value
.get_nof_elements() == 0;
2581 boolean
operator!=(null_type null_value
,
2582 const Record_Of_Type
& other_value
)
2584 return !(null_value
== other_value
);
2587 ////////////////////////////////////////////////////////////////////////////////
2589 boolean
Record_Type::is_bound() const
2591 int field_cnt
= get_count();
2592 for (int field_idx
=0; field_idx
<field_cnt
; field_idx
++) {
2593 const Base_Type
* temp
= get_at(field_idx
);
2594 if(temp
->is_optional()) {
2595 if(temp
->is_present() && temp
->get_opt_value()->is_bound()) return TRUE
;
2597 if(temp
->is_bound()) return TRUE
;
2602 boolean
Record_Type::is_value() const
2604 int field_cnt
= get_count();
2605 for (int field_idx
=0; field_idx
<field_cnt
; field_idx
++) {
2606 const Base_Type
* temp
= get_at(field_idx
);
2607 if(temp
->is_optional()) {
2608 if(!temp
->is_bound()) return FALSE
;
2609 if(temp
->is_present() && !temp
->is_value()) return FALSE
;
2611 if(!temp
->is_value()) return FALSE
;
2617 void Record_Type::clean_up()
2619 int field_cnt
= get_count();
2620 for (int field_idx
=0; field_idx
<field_cnt
; field_idx
++) {
2621 get_at(field_idx
)->clean_up();
2625 void Record_Type::log() const
2628 TTCN_Logger::log_event_unbound();
2631 TTCN_Logger::log_event_str("{ ");
2632 int field_cnt
= get_count();
2633 for (int field_idx
=0; field_idx
<field_cnt
; field_idx
++) {
2634 if (field_idx
) TTCN_Logger::log_event_str(", ");
2635 TTCN_Logger::log_event_str(fld_name(field_idx
));
2636 TTCN_Logger::log_event_str(" := ");
2637 get_at(field_idx
)->log();
2639 TTCN_Logger::log_event_str(" }");
2640 if (err_descr
) err_descr
->log();
2643 void Record_Type::set_param(Module_Param
& param
) {
2644 if (dynamic_cast<Module_Param_Name
*>(param
.get_id()) != NULL
&&
2645 param
.get_id()->next_name()) {
2646 // Haven't reached the end of the module parameter name
2647 // => the name refers to one of the fields, not to the whole record
2648 char* param_field
= param
.get_id()->get_current_name();
2649 if (param_field
[0] >= '0' && param_field
[0] <= '9') {
2650 param
.error("Unexpected array index in module parameter, expected a valid field"
2651 " name for %s type `%s'", is_set() ? "set" : "record", get_descriptor()->name
);
2653 int field_cnt
= get_count();
2654 for (int field_idx
= 0; field_idx
< field_cnt
; field_idx
++) {
2655 if (strcmp(fld_name(field_idx
), param_field
) == 0) {
2656 get_at(field_idx
)->set_param(param
);
2660 param
.error("Field `%s' not found in %s type `%s'",
2661 param_field
, is_set() ? "set" : "record", get_descriptor()->name
);
2664 param
.basic_check(Module_Param::BC_VALUE
, is_set()?"set value":"record value");
2666 Module_Param_Ptr mp
= ¶m
;
2667 if (param
.get_type() == Module_Param::MP_Reference
) {
2668 mp
= param
.get_referenced_param();
2671 switch (mp
->get_type()) {
2672 case Module_Param::MP_Value_List
:
2673 if (get_count()<(int)mp
->get_size()) {
2674 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)mp
->get_size());
2676 for (size_t i
=0; i
<mp
->get_size(); i
++) {
2677 Module_Param
* mp_elem
= mp
->get_elem(i
);
2678 if (mp_elem
->get_type()!=Module_Param::MP_NotUsed
) {
2679 get_at((int)i
)->set_param(*mp_elem
);
2683 case Module_Param::MP_Assignment_List
:
2684 for (size_t i
=0; i
<mp
->get_size(); ++i
) {
2685 Module_Param
* const current
= mp
->get_elem(i
);
2687 for (int j
=0; j
<get_count(); ++j
) {
2688 if (!strcmp(fld_name(j
), current
->get_id()->get_name())) {
2689 if (current
->get_type()!=Module_Param::MP_NotUsed
) {
2690 get_at(j
)->set_param(*current
);
2697 current
->error("Non existent field name in type %s: %s.", get_descriptor()->name
, current
->get_id()->get_name());
2702 param
.type_error(is_set()?"set value":"record value", get_descriptor()->name
);
2706 Module_Param
* Record_Type::get_param(Module_Param_Name
& param_name
) const
2709 return new Module_Param_Unbound();
2711 if (param_name
.next_name()) {
2712 // Haven't reached the end of the module parameter name
2713 // => the name refers to one of the fields, not to the whole record
2714 char* param_field
= param_name
.get_current_name();
2715 if (param_field
[0] >= '0' && param_field
[0] <= '9') {
2716 TTCN_error("Unexpected array index in module parameter reference, "
2717 "expected a valid field name for %s type `%s'",
2718 is_set() ? "set" : "record", get_descriptor()->name
);
2720 int field_cnt
= get_count();
2721 for (int field_idx
= 0; field_idx
< field_cnt
; field_idx
++) {
2722 if (strcmp(fld_name(field_idx
), param_field
) == 0) {
2723 return get_at(field_idx
)->get_param(param_name
);
2726 TTCN_error("Field `%s' not found in %s type `%s'",
2727 param_field
, is_set() ? "set" : "record", get_descriptor()->name
);
2729 Module_Param_Assignment_List
* mp
= new Module_Param_Assignment_List();
2730 for (int i
= 0; i
< get_count(); ++i
) {
2731 Module_Param
* mp_field
= get_at(i
)->get_param(param_name
);
2732 mp_field
->set_id(new Module_Param_FieldName(mcopystr(fld_name(i
))));
2733 mp
->add_elem(mp_field
);
2738 void Record_Type::set_implicit_omit()
2740 int field_cnt
= get_count();
2741 for (int field_idx
= 0; field_idx
< field_cnt
; field_idx
++) {
2742 Base_Type
*temp
= get_at(field_idx
);
2743 if (temp
->is_optional()) {
2744 if (temp
->is_bound()) temp
->set_implicit_omit();
2745 else temp
->set_to_omit();
2746 } else if (temp
->is_bound()) {
2747 temp
->set_implicit_omit();
2752 int Record_Type::size_of() const
2754 int opt_count
= optional_count();
2755 if (opt_count
==0) return get_count();
2756 const int* optional_indexes
= get_optional_indexes();
2757 int my_size
= get_count();
2758 for (int i
=0; i
<opt_count
; i
++) {
2759 if (!get_at(optional_indexes
[i
])->ispresent()) my_size
--;
2764 void Record_Type::encode_text(Text_Buf
& text_buf
) const
2767 TTCN_error("Text encoder: Encoding an unbound record/set value of type %s.",
2768 get_descriptor()->name
);
2770 int field_cnt
= get_count();
2771 for (int field_idx
=0; field_idx
<field_cnt
; field_idx
++)
2772 get_at(field_idx
)->encode_text(text_buf
);
2775 void Record_Type::decode_text(Text_Buf
& text_buf
)
2777 int field_cnt
= get_count();
2778 for (int field_idx
=0; field_idx
<field_cnt
; field_idx
++)
2779 get_at(field_idx
)->decode_text(text_buf
);
2782 boolean
Record_Type::is_equal(const Base_Type
* other_value
) const
2784 const Record_Type
* other_record
= static_cast<const Record_Type
*>(other_value
);
2785 int field_cnt
= get_count();
2786 for (int field_idx
=0; field_idx
<field_cnt
; field_idx
++) {
2787 const Base_Type
* elem
= get_at(field_idx
);
2788 const Base_Type
* other_elem
= other_record
->get_at(field_idx
);
2789 if (elem
->is_bound()) {
2790 if (other_elem
->is_bound()) {
2791 if (!elem
->is_equal(other_elem
))
2793 } else return FALSE
;
2794 } else if (other_elem
->is_bound()) return FALSE
;
2799 void Record_Type::set_value(const Base_Type
* other_value
)
2801 if (this==other_value
) return;
2802 if (!other_value
->is_bound())
2803 TTCN_error("Copying an unbound record/set value of type %s.",
2804 other_value
->get_descriptor()->name
);
2805 const Record_Type
* other_record
= static_cast<const Record_Type
*>(other_value
);
2806 int field_cnt
= get_count();
2807 for (int field_idx
=0; field_idx
<field_cnt
; field_idx
++) {
2808 const Base_Type
* elem
= other_record
->get_at(field_idx
);
2809 if (elem
->is_bound()) {
2810 get_at(field_idx
)->set_value(elem
);
2812 get_at(field_idx
)->clean_up();
2815 err_descr
= other_record
->err_descr
;
2818 void Record_Type::encode(const TTCN_Typedescriptor_t
& p_td
,
2819 TTCN_Buffer
& p_buf
, TTCN_EncDec::coding_t p_coding
, ...) const
2822 va_start(pvar
, p_coding
);
2824 case TTCN_EncDec::CT_BER
: {
2825 TTCN_EncDec_ErrorContext
ec("While BER-encoding type '%s': ", p_td
.name
);
2826 unsigned BER_coding
=va_arg(pvar
, unsigned);
2827 BER_encode_chk_coding(BER_coding
);
2828 ASN_BER_TLV_t
*tlv
=BER_encode_TLV(p_td
, BER_coding
);
2829 tlv
->put_in_buffer(p_buf
);
2830 ASN_BER_TLV_t::destruct(tlv
);
2832 case TTCN_EncDec::CT_RAW
: {
2833 TTCN_EncDec_ErrorContext
ec("While RAW-encoding type '%s': ", p_td
.name
);
2834 if(!p_td
.raw
) TTCN_EncDec_ErrorContext::error_internal
2835 ("No RAW descriptor available for type '%s'.", p_td
.name
);
2839 RAW_enc_tree
root(FALSE
, NULL
, &rp
, 1, p_td
.raw
);
2840 RAW_encode(p_td
, root
);
2841 root
.put_to_buf(p_buf
);
2843 case TTCN_EncDec::CT_TEXT
: {
2844 TTCN_EncDec_ErrorContext
ec("While TEXT-encoding type '%s': ", p_td
.name
);
2845 if(!p_td
.text
) TTCN_EncDec_ErrorContext::error_internal
2846 ("No TEXT descriptor available for type '%s'.", p_td
.name
);
2847 TEXT_encode(p_td
,p_buf
);
2849 case TTCN_EncDec::CT_XER
: {
2850 TTCN_EncDec_ErrorContext
ec("While XER-encoding type '%s': ", p_td
.name
);
2851 unsigned XER_coding
=va_arg(pvar
, unsigned);
2852 XER_encode(*(p_td
.xer
),p_buf
, XER_coding
, 0, 0);
2855 case TTCN_EncDec::CT_JSON
: {
2856 TTCN_EncDec_ErrorContext
ec("While JSON-encoding type '%s': ", p_td
.name
);
2857 if(!p_td
.json
) TTCN_EncDec_ErrorContext::error_internal
2858 ("No JSON descriptor available for type '%s'.", p_td
.name
);
2859 JSON_Tokenizer
tok(va_arg(pvar
, int) != 0);
2860 JSON_encode(p_td
, tok
);
2861 p_buf
.put_s(tok
.get_buffer_length(), (const unsigned char*)tok
.get_buffer());
2864 TTCN_error("Unknown coding method requested to encode type '%s'", p_td
.name
);
2869 void Record_Type::decode(const TTCN_Typedescriptor_t
& p_td
,
2870 TTCN_Buffer
& p_buf
, TTCN_EncDec::coding_t p_coding
, ...)
2873 va_start(pvar
, p_coding
);
2875 case TTCN_EncDec::CT_BER
: {
2876 TTCN_EncDec_ErrorContext
ec("While BER-decoding type '%s': ", p_td
.name
);
2877 unsigned L_form
=va_arg(pvar
, unsigned);
2879 BER_decode_str2TLV(p_buf
, tlv
, L_form
);
2880 BER_decode_TLV(p_td
, tlv
, L_form
);
2881 if(tlv
.isComplete
) p_buf
.increase_pos(tlv
.get_len());
2883 case TTCN_EncDec::CT_RAW
: {
2884 TTCN_EncDec_ErrorContext
ec("While RAW-decoding type '%s': ", p_td
.name
);
2886 TTCN_EncDec_ErrorContext::error_internal
2887 ("No RAW descriptor available for type '%s'.", p_td
.name
);
2889 switch(p_td
.raw
->top_bit_order
) {
2897 int rawr
= RAW_decode(p_td
, p_buf
, p_buf
.get_len()*8, order
);
2898 if (rawr
< 0) switch (-rawr
) {
2899 case TTCN_EncDec::ET_INCOMPL_MSG
:
2900 case TTCN_EncDec::ET_LEN_ERR
:
2901 ec
.error(TTCN_EncDec::ET_INCOMPL_MSG
,
2902 "Can not decode type '%s', because incomplete"
2903 " message was received", p_td
.name
);
2906 // The RAW/TEXT decoders return -1 for anything not a length error.
2907 // This is the value for ET_UNBOUND, which can't happen in decoding.
2909 ec
.error(TTCN_EncDec::ET_INVAL_MSG
,
2910 "Can not decode type '%s', because invalid"
2911 " message was received", p_td
.name
);
2915 case TTCN_EncDec::CT_TEXT
: {
2916 Limit_Token_List limit
;
2917 TTCN_EncDec_ErrorContext
ec("While TEXT-decoding type '%s': ", p_td
.name
);
2918 if(!p_td
.text
) TTCN_EncDec_ErrorContext::error_internal
2919 ("No TEXT descriptor available for type '%s'.", p_td
.name
);
2920 const unsigned char *b
=p_buf
.get_data();
2921 if(b
[p_buf
.get_len()-1]!='\0'){
2922 p_buf
.set_pos(p_buf
.get_len());
2923 p_buf
.put_zero(8,ORDER_LSB
);
2926 if(TEXT_decode(p_td
,p_buf
,limit
)<0)
2927 ec
.error(TTCN_EncDec::ET_INCOMPL_MSG
,
2928 "Can not decode type '%s', because invalid or incomplete"
2929 " message was received", p_td
.name
);
2931 case TTCN_EncDec::CT_XER
: {
2932 TTCN_EncDec_ErrorContext
ec("While XER-decoding type '%s': ", p_td
.name
);
2933 unsigned XER_coding
=va_arg(pvar
, unsigned);
2934 XmlReaderWrap
reader(p_buf
);
2935 for (int success
=reader
.Read(); success
==1; success
=reader
.Read()) {
2936 if (reader
.NodeType() == XML_READER_TYPE_ELEMENT
) break;
2938 XER_decode(*(p_td
.xer
), reader
, XER_coding
| XER_TOPLEVEL
, XER_NONE
, 0);
2939 size_t bytes
= reader
.ByteConsumed();
2940 p_buf
.set_pos(bytes
);
2942 case TTCN_EncDec::CT_JSON
: {
2943 TTCN_EncDec_ErrorContext
ec("While JSON-decoding type '%s': ", p_td
.name
);
2944 if(!p_td
.json
) TTCN_EncDec_ErrorContext::error_internal
2945 ("No JSON descriptor available for type '%s'.", p_td
.name
);
2946 JSON_Tokenizer
tok((const char*)p_buf
.get_data(), p_buf
.get_len());
2947 if(JSON_decode(p_td
, tok
, false)<0)
2948 ec
.error(TTCN_EncDec::ET_INCOMPL_MSG
,
2949 "Can not decode type '%s', because invalid or incomplete"
2950 " message was received", p_td
.name
);
2951 p_buf
.set_pos(tok
.get_buf_pos());
2954 TTCN_error("Unknown coding method requested to decode type '%s'", p_td
.name
);
2959 ASN_BER_TLV_t
* Record_Type::BER_encode_TLV(const TTCN_Typedescriptor_t
& p_td
, unsigned p_coding
) const
2962 return BER_encode_TLV_negtest(err_descr
, p_td
, p_coding
);
2965 TTCN_EncDec_ErrorContext::error
2966 (TTCN_EncDec::ET_UNBOUND
, "Encoding an unbound value.");
2968 BER_chk_descr(p_td
);
2969 ASN_BER_TLV_t
*new_tlv
=ASN_BER_TLV_t::construct(NULL
);
2970 TTCN_EncDec_ErrorContext
ec_0("Component '");
2971 TTCN_EncDec_ErrorContext ec_1
;
2972 int next_default_idx
= 0;
2973 const default_struct
* default_indexes
= get_default_indexes();
2974 int field_cnt
= get_count();
2975 for(int i
=0; i
<field_cnt
; i
++) {
2976 boolean is_default_field
= default_indexes
&& (default_indexes
[next_default_idx
].index
==i
);
2977 if (!default_as_optional() && is_default_field
) {
2978 if (!get_at(i
)->is_equal(default_indexes
[next_default_idx
].value
)) {
2979 ec_1
.set_msg("%s': ", fld_name(i
));
2980 new_tlv
->add_TLV(get_at(i
)->BER_encode_TLV(*fld_descr(i
), p_coding
));
2982 } else { /* is not DEFAULT */
2983 ec_1
.set_msg("%s': ", fld_name(i
));
2984 new_tlv
->add_TLV(get_at(i
)->BER_encode_TLV(*fld_descr(i
), p_coding
));
2986 if (is_default_field
) next_default_idx
++;
2989 if (p_coding
==BER_ENCODE_DER
) new_tlv
->sort_tlvs_tag();
2990 new_tlv
=ASN_BER_V2TLV(new_tlv
, p_td
, p_coding
);
2994 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
2997 TTCN_EncDec_ErrorContext::error
2998 (TTCN_EncDec::ET_UNBOUND
, "Encoding an unbound value.");
3000 BER_chk_descr(p_td
);
3001 ASN_BER_TLV_t
*new_tlv
=ASN_BER_TLV_t::construct(NULL
);
3002 TTCN_EncDec_ErrorContext
ec_0("Component '");
3003 TTCN_EncDec_ErrorContext ec_1
;
3004 int next_default_idx
= 0;
3005 const default_struct
* default_indexes
= get_default_indexes();
3006 int field_cnt
= get_count();
3011 for (int i
=0; i
<field_cnt
; i
++) {
3012 boolean is_default_field
= default_indexes
&& (default_indexes
[next_default_idx
].index
==i
);
3013 // the first condition is not needed, kept for ease of understanding
3014 if ( (p_err_descr
->omit_before
!=-1) && (i
<p_err_descr
->omit_before
) ) {
3015 if (is_default_field
) next_default_idx
++;
3018 const Erroneous_values_t
* err_vals
= p_err_descr
->next_field_err_values(i
, values_idx
);
3019 const Erroneous_descriptor_t
* emb_descr
= p_err_descr
->next_field_emb_descr(i
, edescr_idx
);
3021 if (err_vals
&& err_vals
->before
) {
3022 if (err_vals
->before
->errval
==NULL
) TTCN_error(
3023 "internal error: erroneous before value missing");
3024 ec_1
.set_msg("%s'(erroneous before): ", fld_name(i
));
3025 if (err_vals
->before
->raw
) {
3026 new_tlv
->add_TLV(err_vals
->before
->errval
->BER_encode_negtest_raw());
3028 if (err_vals
->before
->type_descr
==NULL
) TTCN_error(
3029 "internal error: erroneous before typedescriptor missing");
3030 new_tlv
->add_TLV(err_vals
->before
->errval
->BER_encode_TLV(
3031 *err_vals
->before
->type_descr
, p_coding
));
3035 if (err_vals
&& err_vals
->value
) {
3036 if (err_vals
->value
->errval
) { // replace
3037 ec_1
.set_msg("%s'(erroneous value): ", fld_name(i
));
3038 if (err_vals
->value
->raw
) {
3039 new_tlv
->add_TLV(err_vals
->value
->errval
->BER_encode_negtest_raw());
3041 if (err_vals
->value
->type_descr
==NULL
) TTCN_error(
3042 "internal error: erroneous value typedescriptor missing");
3043 new_tlv
->add_TLV(err_vals
->value
->errval
->BER_encode_TLV(
3044 *err_vals
->value
->type_descr
, p_coding
));
3048 if (!default_as_optional() && is_default_field
) {
3049 if (!get_at(i
)->is_equal(default_indexes
[next_default_idx
].value
)) {
3050 ec_1
.set_msg("'%s': ", fld_name(i
));
3052 new_tlv
->add_TLV(get_at(i
)->BER_encode_TLV_negtest(emb_descr
,
3053 *fld_descr(i
), p_coding
));
3055 new_tlv
->add_TLV(get_at(i
)->BER_encode_TLV(*fld_descr(i
), p_coding
));
3058 } else { /* is not DEFAULT */
3059 ec_1
.set_msg("'%s': ", fld_name(i
));
3061 new_tlv
->add_TLV(get_at(i
)->BER_encode_TLV_negtest(emb_descr
,
3062 *fld_descr(i
), p_coding
));
3064 new_tlv
->add_TLV(get_at(i
)->BER_encode_TLV(*fld_descr(i
), p_coding
));
3069 if (err_vals
&& err_vals
->after
) {
3070 if (err_vals
->after
->errval
==NULL
) TTCN_error(
3071 "internal error: erroneous after value missing");
3072 ec_1
.set_msg("%s'(erroneous after): ", fld_name(i
));
3073 if (err_vals
->after
->raw
) {
3074 new_tlv
->add_TLV(err_vals
->after
->errval
->BER_encode_negtest_raw());
3076 if (err_vals
->after
->type_descr
==NULL
) TTCN_error(
3077 "internal error: erroneous after typedescriptor missing");
3078 new_tlv
->add_TLV(err_vals
->after
->errval
->BER_encode_TLV(
3079 *err_vals
->after
->type_descr
, p_coding
));
3083 if (is_default_field
) next_default_idx
++;
3084 if ( (p_err_descr
->omit_after
!=-1) && (i
>=p_err_descr
->omit_after
) ) break;
3088 if (p_coding
==BER_ENCODE_DER
) new_tlv
->sort_tlvs_tag();
3089 new_tlv
=ASN_BER_V2TLV(new_tlv
, p_td
, p_coding
);
3093 boolean
Record_Type::BER_decode_TLV(const TTCN_Typedescriptor_t
& p_td
,
3094 const ASN_BER_TLV_t
& p_tlv
, unsigned L_form
)
3096 BER_chk_descr(p_td
);
3097 ASN_BER_TLV_t stripped_tlv
;
3098 BER_decode_strip_tags(*p_td
.ber
, p_tlv
, L_form
, stripped_tlv
);
3099 TTCN_EncDec_ErrorContext
ec_0("While decoding '%s' type: ", get_descriptor()->name
);
3100 stripped_tlv
.chk_constructed_flag(TRUE
);
3102 ASN_BER_TLV_t tmp_tlv
;
3104 { /* SEQUENCE decoding */
3105 boolean tlv_present
=FALSE
;
3107 TTCN_EncDec_ErrorContext
ec_1("Component '");
3108 TTCN_EncDec_ErrorContext ec_2
;
3109 int next_default_idx
= 0;
3110 int next_optional_idx
= 0;
3111 const default_struct
* default_indexes
= get_default_indexes();
3112 const int* optional_indexes
= get_optional_indexes();
3113 int field_cnt
= get_count();
3114 for(int i
=0; i
<field_cnt
; i
++) {
3115 boolean is_default_field
= default_indexes
&& (default_indexes
[next_default_idx
].index
==i
);
3116 boolean is_optional_field
= optional_indexes
&& (optional_indexes
[next_optional_idx
]==i
);
3117 ec_2
.set_msg("%s': ", fld_descr(i
)->name
);
3118 if (!tlv_present
) tlv_present
=BER_decode_constdTLV_next(stripped_tlv
, V_pos
, L_form
, tmp_tlv
);
3119 if (is_default_field
) { /* is DEFAULT */
3120 if (!tlv_present
|| !get_at(i
)->BER_decode_isMyMsg(*fld_descr(i
), tmp_tlv
)) {
3121 get_at(i
)->set_value(default_indexes
[next_default_idx
].value
);
3123 get_at(i
)->BER_decode_TLV(*fld_descr(i
), tmp_tlv
, L_form
);
3127 else if (is_optional_field
) { /* is OPTIONAL */
3128 if (!tlv_present
) get_at(i
)->set_to_omit();
3130 get_at(i
)->BER_decode_TLV(*fld_descr(i
), tmp_tlv
, L_form
);
3131 if (get_at(i
)->ispresent()) tlv_present
=FALSE
;
3134 else { /* is not DEFAULT OPTIONAL */
3136 ec_2
.error(TTCN_EncDec::ET_INCOMPL_MSG
,"Invalid or incomplete message was received.");
3139 get_at(i
)->BER_decode_TLV(*fld_descr(i
), tmp_tlv
, L_form
);
3142 if (is_default_field
) next_default_idx
++;
3143 if (is_optional_field
) next_optional_idx
++;
3146 BER_decode_constdTLV_end(stripped_tlv
, V_pos
, L_form
, tmp_tlv
, tlv_present
);
3147 } /* SEQUENCE decoding */
3149 { /* SET decoding */
3151 * 0x01: value arrived
3152 * 0x02: is optional / not used :)
3153 * 0x04: has default / not used :)
3155 int field_cnt
= get_count();
3156 unsigned char* fld_indctr
= new unsigned char[field_cnt
];
3157 for (int i
=0; i
<field_cnt
; i
++) fld_indctr
[i
] = 0;
3158 int fld_curr
= -1; /* ellipsis or error... */
3159 while (BER_decode_constdTLV_next(stripped_tlv
, V_pos
, L_form
, tmp_tlv
)) {
3160 for (int i
=0; i
<field_cnt
; i
++) {
3161 if (get_at(i
)->BER_decode_isMyMsg(*fld_descr(i
), tmp_tlv
)) {
3163 TTCN_EncDec_ErrorContext
ec_1("Component '%s': ", fld_name(i
));
3164 get_at(i
)->BER_decode_TLV(*fld_descr(i
), tmp_tlv
, L_form
);
3169 if (fld_indctr
[fld_curr
])
3170 ec_0
.error(TTCN_EncDec::ET_DEC_DUPFLD
, "Duplicated value for component '%s'.", fld_name(fld_curr
));
3171 fld_indctr
[fld_curr
]=1;
3174 int next_default_idx
= 0;
3175 int next_optional_idx
= 0;
3176 const default_struct
* default_indexes
= get_default_indexes();
3177 const int* optional_indexes
= get_optional_indexes();
3178 for (fld_curr
=0; fld_curr
<field_cnt
; fld_curr
++) {
3179 boolean is_default_field
= default_indexes
&& (default_indexes
[next_default_idx
].index
==fld_curr
);
3180 boolean is_optional_field
= optional_indexes
&& (optional_indexes
[next_optional_idx
]==fld_curr
);
3181 if (!fld_indctr
[fld_curr
]) {
3182 if (is_default_field
) get_at(fld_curr
)->set_value(default_indexes
[next_default_idx
].value
);
3183 else if (is_optional_field
) get_at(fld_curr
)->set_to_omit();
3184 else ec_0
.error(TTCN_EncDec::ET_DEC_MISSFLD
, "Missing value for component '%s'.", fld_name(fld_curr
));
3186 if (is_default_field
) next_default_idx
++;
3187 if (is_optional_field
) next_optional_idx
++;
3189 delete[] fld_indctr
;
3190 } /* SET decoding */
3192 if (is_opentype_outermost()) {
3193 TTCN_EncDec_ErrorContext
ec_1("While decoding opentypes: ");
3194 TTCN_Type_list p_typelist
;
3195 BER_decode_opentypes(p_typelist
, L_form
);
3196 } /* if sdef->opentype_outermost */
3200 void Record_Type::BER_decode_opentypes(TTCN_Type_list
& p_typelist
, unsigned L_form
)
3202 p_typelist
.push(this);
3203 TTCN_EncDec_ErrorContext
ec_0("Component '");
3204 TTCN_EncDec_ErrorContext ec_1
;
3205 int field_cnt
= get_count();
3206 for(int i
=0; i
<field_cnt
; i
++) {
3207 ec_1
.set_msg("%s': ", fld_name(i
));
3208 get_at(i
)->BER_decode_opentypes(p_typelist
, L_form
);
3213 int Record_Type::RAW_encode(const TTCN_Typedescriptor_t
& p_td
,
3214 RAW_enc_tree
& myleaf
) const
3216 if (err_descr
) return RAW_encode_negtest(err_descr
, p_td
, myleaf
);
3218 TTCN_EncDec_ErrorContext::error
3219 (TTCN_EncDec::ET_UNBOUND
, "Encoding an unbound value.");
3221 int encoded_length
= 0;
3222 int field_cnt
= get_count();
3223 myleaf
.isleaf
= false;
3224 myleaf
.body
.node
.num_of_nodes
= field_cnt
;
3225 myleaf
.body
.node
.nodes
= init_nodes_of_enc_tree(field_cnt
);
3227 int next_optional_idx
= 0;
3228 const int* optional_indexes
= get_optional_indexes();
3229 for (int i
= 0; i
< field_cnt
; i
++) {
3230 boolean is_optional_field
= optional_indexes
3231 && (optional_indexes
[next_optional_idx
] == i
);
3232 if (!is_optional_field
|| get_at(i
)->ispresent()) {
3233 myleaf
.body
.node
.nodes
[i
] = new RAW_enc_tree(true, &myleaf
,
3234 &(myleaf
.curr_pos
), i
, fld_descr(i
)->raw
);
3237 myleaf
.body
.node
.nodes
[i
] = NULL
;
3239 if (is_optional_field
) next_optional_idx
++;
3241 next_optional_idx
= 0;
3242 for (int i
= 0; i
< field_cnt
; i
++) { /*encoding fields*/
3243 boolean is_optional_field
= optional_indexes
3244 && (optional_indexes
[next_optional_idx
] == i
);
3245 /* encoding of normal fields*/
3246 const Base_Type
*field
= get_at(i
);
3247 if (is_optional_field
) {
3248 next_optional_idx
++;
3249 if (!field
->ispresent())
3250 continue; // do not encode
3252 field
= field
->get_opt_value(); // "reach into" the optional
3254 encoded_length
+= field
->RAW_encode(*fld_descr(i
),
3255 *myleaf
.body
.node
.nodes
[i
]);
3257 return myleaf
.length
= encoded_length
;
3260 // In some cases (e.g. LENGTHTO, POINTERTO, CROSSTAG) it is not generated.
3261 int Record_Type::RAW_encode_negtest(const Erroneous_descriptor_t
*p_err_descr
,
3262 const TTCN_Typedescriptor_t
& /*p_td*/, RAW_enc_tree
& myleaf
) const
3265 TTCN_EncDec_ErrorContext::error
3266 (TTCN_EncDec::ET_UNBOUND
, "Encoding an unbound value.");
3268 int encoded_length
= 0;
3269 int num_fields
= get_count();
3270 myleaf
.isleaf
= false;
3271 myleaf
.body
.node
.num_of_nodes
= 0;
3272 for (int field_idx
= 0; field_idx
< num_fields
; ++field_idx
) {
3273 if ((p_err_descr
->omit_before
!= -1) &&
3274 (field_idx
< p_err_descr
->omit_before
))
3276 else ++myleaf
.body
.node
.num_of_nodes
;
3277 const Erroneous_values_t
*err_vals
= p_err_descr
->get_field_err_values(field_idx
);
3278 if (err_vals
&& err_vals
->before
)
3279 ++myleaf
.body
.node
.num_of_nodes
;
3280 if (err_vals
&& err_vals
->value
&& !err_vals
->value
->errval
)
3281 --myleaf
.body
.node
.num_of_nodes
;
3282 if (err_vals
&& err_vals
->after
)
3283 ++myleaf
.body
.node
.num_of_nodes
;
3284 if ((p_err_descr
->omit_after
!= -1) &&
3285 (field_idx
>= p_err_descr
->omit_after
))
3288 myleaf
.body
.node
.nodes
= init_nodes_of_enc_tree(myleaf
.body
.node
.num_of_nodes
);
3289 TTCN_EncDec_ErrorContext ec
;
3290 int next_optional_idx
= 0;
3291 const int *my_optional_indexes
= get_optional_indexes();
3292 // Counter for fields and additional before/after fields.
3294 for (int field_idx
= 0; field_idx
< num_fields
; ++field_idx
) {
3295 boolean is_optional_field
= my_optional_indexes
&&
3296 (my_optional_indexes
[next_optional_idx
] == field_idx
);
3297 if ((p_err_descr
->omit_before
!= -1) &&
3298 (field_idx
< p_err_descr
->omit_before
)) {
3299 if (is_optional_field
) ++next_optional_idx
;
3302 const Erroneous_values_t
*err_vals
= p_err_descr
->get_field_err_values(field_idx
);
3303 const Erroneous_descriptor_t
*emb_descr
= p_err_descr
->get_field_emb_descr(field_idx
);
3304 if (err_vals
&& err_vals
->before
) {
3305 if (err_vals
->before
->errval
== NULL
)
3306 TTCN_error("internal error: erroneous before value missing");
3307 if (err_vals
->before
->raw
) {
3308 myleaf
.body
.node
.nodes
[node_pos
] =
3309 new RAW_enc_tree(true, &myleaf
, &(myleaf
.curr_pos
), node_pos
,
3310 err_vals
->before
->errval
->get_descriptor()->raw
);
3311 encoded_length
+= err_vals
->before
->errval
->
3312 RAW_encode_negtest_raw(*myleaf
.body
.node
.nodes
[node_pos
++]);
3314 if (err_vals
->before
->type_descr
== NULL
)
3315 TTCN_error("internal error: erroneous before typedescriptor missing");
3316 myleaf
.body
.node
.nodes
[node_pos
] =
3317 new RAW_enc_tree(true, &myleaf
, &(myleaf
.curr_pos
), node_pos
,
3318 err_vals
->before
->type_descr
->raw
);
3319 encoded_length
+= err_vals
->before
->errval
->
3320 RAW_encode(*(err_vals
->before
->type_descr
),
3321 *myleaf
.body
.node
.nodes
[node_pos
++]);
3324 if (err_vals
&& err_vals
->value
) {
3325 if (err_vals
->value
->errval
) {
3326 ec
.set_msg("'%s'(erroneous value): ", fld_name(field_idx
));
3327 if (err_vals
->value
->raw
) {
3328 myleaf
.body
.node
.nodes
[node_pos
] =
3329 new RAW_enc_tree(true, &myleaf
, &(myleaf
.curr_pos
), node_pos
,
3330 err_vals
->value
->errval
->get_descriptor()->raw
);
3331 encoded_length
+= err_vals
->value
->errval
->
3332 RAW_encode_negtest_raw(*myleaf
.body
.node
.nodes
[node_pos
++]);
3334 if (err_vals
->value
->type_descr
== NULL
)
3335 TTCN_error("internal error: erroneous value typedescriptor missing");
3336 myleaf
.body
.node
.nodes
[node_pos
] =
3337 new RAW_enc_tree(true, &myleaf
, &(myleaf
.curr_pos
), node_pos
,
3338 err_vals
->value
->type_descr
->raw
);
3339 encoded_length
+= err_vals
->value
->errval
->
3340 RAW_encode(*(err_vals
->value
->type_descr
),
3341 *myleaf
.body
.node
.nodes
[node_pos
++]);
3345 ec
.set_msg("'%s': ", fld_name(field_idx
));
3346 if (!is_optional_field
|| get_at(field_idx
)->ispresent()) {
3347 const Base_Type
*field
=
3348 is_optional_field
? get_at(field_idx
)->get_opt_value()
3349 : get_at(field_idx
);
3350 myleaf
.body
.node
.nodes
[node_pos
] =
3351 new RAW_enc_tree(true, &myleaf
, &(myleaf
.curr_pos
), node_pos
,
3352 fld_descr(field_idx
)->raw
);
3355 field
->RAW_encode_negtest(emb_descr
, *fld_descr(field_idx
),
3356 *myleaf
.body
.node
.nodes
[node_pos
++]);
3359 field
->RAW_encode(*fld_descr(field_idx
),
3360 *myleaf
.body
.node
.nodes
[node_pos
++]);
3364 myleaf
.body
.node
.nodes
[node_pos
++] = NULL
;
3367 if (err_vals
&& err_vals
->after
) {
3368 if (err_vals
->after
->errval
== NULL
)
3369 TTCN_error("internal error: erroneous before value missing");
3370 if (err_vals
->after
->raw
) {
3371 myleaf
.body
.node
.nodes
[node_pos
] =
3372 new RAW_enc_tree(true, &myleaf
, &(myleaf
.curr_pos
), node_pos
,
3373 err_vals
->after
->errval
->get_descriptor()->raw
);
3374 encoded_length
+= err_vals
->after
->errval
->
3375 RAW_encode_negtest_raw(*myleaf
.body
.node
.nodes
[node_pos
++]);
3377 if (err_vals
->after
->type_descr
== NULL
)
3378 TTCN_error("internal error: erroneous after typedescriptor missing");
3379 myleaf
.body
.node
.nodes
[node_pos
] =
3380 new RAW_enc_tree(true, &myleaf
, &(myleaf
.curr_pos
), node_pos
,
3381 err_vals
->after
->type_descr
->raw
);
3382 encoded_length
+= err_vals
->after
->errval
->
3383 RAW_encode(*(err_vals
->after
->type_descr
),
3384 *myleaf
.body
.node
.nodes
[node_pos
++]);
3387 if (is_optional_field
) ++next_optional_idx
;
3388 if ((p_err_descr
->omit_after
!= -1) &&
3389 (field_idx
>= p_err_descr
->omit_after
))
3392 return myleaf
.length
= encoded_length
;
3395 int Record_Type::RAW_decode(const TTCN_Typedescriptor_t
& p_td
, TTCN_Buffer
& buff
,
3396 int limit
, raw_order_t top_bit_ord
, boolean no_err
, int, boolean
)
3398 int field_cnt
= get_count();
3399 int opt_cnt
= optional_count();
3400 int mand_num
= field_cnt
- opt_cnt
; // expected mandatory fields
3402 raw_order_t local_top_order
;
3403 if (p_td
.raw
->top_bit_order
== TOP_BIT_INHERITED
) local_top_order
= top_bit_ord
;
3404 else if (p_td
.raw
->top_bit_order
== TOP_BIT_RIGHT
) local_top_order
= ORDER_MSB
;
3405 else local_top_order
= ORDER_LSB
;
3407 if (is_set()) { /* set decoder start*/
3408 int prepaddlength
= buff
.increase_pos_padd(p_td
.raw
->prepadding
);
3409 limit
-= prepaddlength
;
3410 int decoded_length
= 0;
3411 int * const field_map
= new int[field_cnt
];
3412 memset(field_map
, 0, field_cnt
* sizeof(int));
3413 int nof_mand_fields
= 0; // mandatory fields actually decoded
3415 const int* optional_indexes
= get_optional_indexes();
3416 for (int i
=0; i
<opt_cnt
; i
++) get_at(optional_indexes
[i
])->set_to_omit();
3419 size_t fl_start_pos
= buff
.get_pos_bit();
3420 int next_optional_idx
= 0;
3421 const int* optional_indexes
= get_optional_indexes();
3422 for (int i
=0; i
<field_cnt
; i
++) { /* decoding fields without TAG */
3423 boolean is_optional_field
= optional_indexes
&& (optional_indexes
[next_optional_idx
]==i
);
3424 if (field_map
[i
] == 0) {
3425 Base_Type
* field_ptr
= get_at(i
);
3426 if (is_optional_field
) {
3427 field_ptr
->set_to_present();
3428 field_ptr
=field_ptr
->get_opt_value();
3430 int decoded_field_length
= field_ptr
->RAW_decode(*fld_descr(i
), buff
,
3431 limit
, local_top_order
, TRUE
);
3432 if ( (is_optional_field
&& (decoded_field_length
>0)) ||
3433 (!is_optional_field
&& (decoded_field_length
>=0)) ) {
3434 decoded_length
+= decoded_field_length
;
3435 limit
-= decoded_field_length
;
3436 if (!is_optional_field
) nof_mand_fields
++;
3438 goto continue_while
;
3440 buff
.set_pos_bit(fl_start_pos
);
3441 if (is_optional_field
) get_at(i
)->set_to_omit();
3444 if (is_optional_field
) next_optional_idx
++;
3446 break; // no field could be decoded successfully, quit
3450 if (mand_num
> 0 && nof_mand_fields
!= mand_num
) {
3451 /* Not all required fields were decoded. If there are no bits left,
3452 * that means that the last field was decoded successfully but used up
3453 * the buffer. Signal "incomplete". If there were bits left, that means
3454 * no field could be decoded from them; signal an error. */
3455 return limit
? -1 : -TTCN_EncDec::ET_INCOMPL_MSG
;
3457 return decoded_length
+ prepaddlength
+ buff
.increase_pos_padd(p_td
.raw
->padding
);
3458 } else { /* record decoder start */
3459 int prepaddlength
= buff
.increase_pos_padd(p_td
.raw
->prepadding
);
3460 limit
-= prepaddlength
;
3461 size_t last_decoded_pos
= buff
.get_pos_bit();
3462 size_t fl_start_pos
;
3463 int decoded_length
= 0;
3464 int decoded_field_length
= 0;
3465 if (raw_has_ext_bit()) {
3466 const unsigned char* data
=buff
.get_read_data();
3468 unsigned mask
= 1 << (local_top_order
==ORDER_LSB
? 0 : 7);
3469 if (p_td
.raw
->extension_bit
==EXT_BIT_YES
) {
3470 while((data
[count
-1] & mask
) == 0 && count
* 8 < (int)limit
) count
++;
3473 while((data
[count
-1] & mask
) != 0 && count
* 8 < (int)limit
) count
++;
3475 if(limit
) limit
=count
*8;
3478 int next_optional_idx
= 0;
3479 const int* optional_indexes
= get_optional_indexes();
3480 for (int i
=0; i
<field_cnt
; i
++) { /* decoding fields */
3481 boolean is_optional_field
= optional_indexes
&& (optional_indexes
[next_optional_idx
]==i
);
3482 /* check if enough bits to decode the field*/
3483 if (!is_optional_field
|| (limit
>0)) {
3484 /* decoding of normal field */
3485 fl_start_pos
= buff
.get_pos_bit();
3486 Base_Type
* field_ptr
= get_at(i
);
3487 if (is_optional_field
) {
3488 field_ptr
->set_to_present();
3489 field_ptr
=field_ptr
->get_opt_value();
3491 decoded_field_length
= field_ptr
->RAW_decode(*fld_descr(i
), buff
, limit
,
3492 local_top_order
, is_optional_field
? TRUE
: no_err
);
3493 boolean field_present
= TRUE
;
3494 if (is_optional_field
) {
3495 if (decoded_field_length
< 1) { // swallow any error and become omit
3496 field_present
= FALSE
;
3497 get_at(i
)->set_to_omit();
3498 buff
.set_pos_bit(fl_start_pos
);
3501 if (decoded_field_length
< 0) return decoded_field_length
;
3503 if (field_present
) {
3504 decoded_length
+=decoded_field_length
;
3505 limit
-=decoded_field_length
;
3506 last_decoded_pos
=last_decoded_pos
<buff
.get_pos_bit()?buff
.get_pos_bit():last_decoded_pos
;
3509 get_at(i
)->set_to_omit();
3511 if (is_optional_field
) next_optional_idx
++;
3512 } /* decoding fields*/
3514 buff
.set_pos_bit(last_decoded_pos
);
3515 return decoded_length
+prepaddlength
+buff
.increase_pos_padd(p_td
.raw
->padding
);
3516 } /* record decoder end*/
3519 int Record_Type::TEXT_encode(const TTCN_Typedescriptor_t
& p_td
, TTCN_Buffer
& buff
) const
3522 return TEXT_encode_negtest(err_descr
, p_td
, buff
);
3525 TTCN_EncDec_ErrorContext::error
3526 (TTCN_EncDec::ET_UNBOUND
, "Encoding an unbound value.");
3528 bool need_separator
=false;
3529 int encoded_length
=0;
3530 if (p_td
.text
->begin_encode
) {
3531 buff
.put_cs(*p_td
.text
->begin_encode
);
3532 encoded_length
+=p_td
.text
->begin_encode
->lengthof();
3534 int next_optional_idx
= 0;
3535 const int* optional_indexes
= get_optional_indexes();
3536 int field_cnt
= get_count();
3537 for(int i
=0;i
<field_cnt
;i
++) {
3538 boolean is_optional_field
= optional_indexes
&& (optional_indexes
[next_optional_idx
]==i
);
3539 if (!is_optional_field
|| get_at(i
)->ispresent()) {
3540 if (need_separator
&& p_td
.text
->separator_encode
) {
3541 buff
.put_cs(*p_td
.text
->separator_encode
);
3542 encoded_length
+=p_td
.text
->separator_encode
->lengthof();
3544 encoded_length
+= get_at(i
)->TEXT_encode(*fld_descr(i
),buff
);
3545 need_separator
=true;
3547 if (is_optional_field
) next_optional_idx
++;
3549 if (p_td
.text
->end_encode
) {
3550 buff
.put_cs(*p_td
.text
->end_encode
);
3551 encoded_length
+=p_td
.text
->end_encode
->lengthof();
3553 return encoded_length
;
3557 * TEXT encode negative testing
3559 int Record_Type::TEXT_encode_negtest(const Erroneous_descriptor_t
* p_err_descr
, const TTCN_Typedescriptor_t
& p_td
, TTCN_Buffer
& buff
) const
3562 TTCN_EncDec_ErrorContext::error
3563 (TTCN_EncDec::ET_UNBOUND
, "Encoding an unbound value.");
3565 bool need_separator
=false;
3566 int encoded_length
=0;
3567 if (p_td
.text
->begin_encode
) {
3568 buff
.put_cs(*p_td
.text
->begin_encode
);
3569 encoded_length
+=p_td
.text
->begin_encode
->lengthof();
3571 int next_optional_idx
= 0;
3572 const int* optional_indexes
= get_optional_indexes();
3573 int field_cnt
= get_count();
3578 for(int i
=0;i
<field_cnt
;i
++) {
3579 boolean is_optional_field
= optional_indexes
&& (optional_indexes
[next_optional_idx
]==i
);
3581 if ( (p_err_descr
->omit_before
!=-1) && (i
<p_err_descr
->omit_before
) ) {
3582 if (is_optional_field
) next_optional_idx
++;
3586 const Erroneous_values_t
* err_vals
= p_err_descr
->next_field_err_values(i
, values_idx
);
3587 const Erroneous_descriptor_t
* emb_descr
= p_err_descr
->next_field_emb_descr(i
, edescr_idx
);
3589 if (err_vals
&& err_vals
->before
) {
3590 if (err_vals
->before
->errval
==NULL
) TTCN_error(
3591 "internal error: erroneous before value missing");
3593 if (need_separator
&& p_td
.text
->separator_encode
) {
3594 buff
.put_cs(*p_td
.text
->separator_encode
);
3595 encoded_length
+=p_td
.text
->separator_encode
->lengthof();
3597 if (err_vals
->before
->raw
) {
3598 encoded_length
+= err_vals
->before
->errval
->encode_raw(buff
);
3600 if (err_vals
->before
->type_descr
==NULL
) TTCN_error(
3601 "internal error: erroneous before typedescriptor missing");
3602 encoded_length
+= err_vals
->before
->errval
->TEXT_encode(
3603 *(err_vals
->before
->type_descr
),buff
);
3605 need_separator
=true;
3608 if (err_vals
&& err_vals
->value
) {
3609 if (err_vals
->value
->errval
) {
3610 if (need_separator
&& p_td
.text
->separator_encode
) {
3611 buff
.put_cs(*p_td
.text
->separator_encode
);
3612 encoded_length
+=p_td
.text
->separator_encode
->lengthof();
3614 if (err_vals
->value
->raw
) {
3615 encoded_length
+= err_vals
->value
->errval
->encode_raw(buff
);
3617 if (err_vals
->value
->type_descr
==NULL
) TTCN_error(
3618 "internal error: erroneous value typedescriptor missing");
3619 encoded_length
+= err_vals
->value
->errval
->TEXT_encode(
3620 *(err_vals
->value
->type_descr
),buff
);
3622 need_separator
=true;
3625 if (!is_optional_field
|| get_at(i
)->ispresent()) {
3626 if (need_separator
&& p_td
.text
->separator_encode
) {
3627 buff
.put_cs(*p_td
.text
->separator_encode
);
3628 encoded_length
+=p_td
.text
->separator_encode
->lengthof();
3631 encoded_length
+= get_at(i
)->TEXT_encode_negtest(emb_descr
, *fld_descr(i
),buff
);
3633 encoded_length
+= get_at(i
)->TEXT_encode(*fld_descr(i
),buff
);
3635 need_separator
=true;
3639 if (err_vals
&& err_vals
->after
) {
3640 if (err_vals
->after
->errval
==NULL
) TTCN_error(
3641 "internal error: erroneous after value missing");
3642 if (need_separator
&& p_td
.text
->separator_encode
) {
3643 buff
.put_cs(*p_td
.text
->separator_encode
);
3644 encoded_length
+=p_td
.text
->separator_encode
->lengthof();
3646 if (err_vals
->after
->raw
) {
3647 encoded_length
+= err_vals
->after
->errval
->encode_raw(buff
);
3649 if (err_vals
->after
->type_descr
==NULL
) TTCN_error(
3650 "internal error: erroneous after typedescriptor missing");
3651 encoded_length
+= err_vals
->after
->errval
->TEXT_encode(
3652 *(err_vals
->after
->type_descr
),buff
);
3654 need_separator
=true;
3657 if (is_optional_field
) next_optional_idx
++;
3659 if ( (p_err_descr
->omit_after
!=-1) && (i
>=p_err_descr
->omit_after
) ) break;
3661 if (p_td
.text
->end_encode
) {
3662 buff
.put_cs(*p_td
.text
->end_encode
);
3663 encoded_length
+=p_td
.text
->end_encode
->lengthof();
3665 return encoded_length
;
3668 int Record_Type::TEXT_decode(const TTCN_Typedescriptor_t
& p_td
, TTCN_Buffer
& buff
,
3669 Limit_Token_List
& limit
, boolean no_err
, boolean
/*first_call*/)
3672 int decoded_length
=0;
3673 int decoded_field_length
=0;
3674 size_t pos
=buff
.get_pos();
3675 boolean sep_found
=FALSE
;
3678 int loop_detector
=1;
3679 int last_field_num
=-1;
3680 if (p_td
.text
->begin_decode
) {
3682 if ((tl
=p_td
.text
->begin_decode
->match_begin(buff
))<0) {
3683 if(no_err
) return -1;
3684 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR
,
3685 "The specified token '%s' not found for '%s': ",
3686 (const char*)*(p_td
.text
->begin_decode
), p_td
.name
);
3690 buff
.increase_pos(tl
);
3692 if (p_td
.text
->end_decode
) {
3693 limit
.add_token(p_td
.text
->end_decode
);
3696 if(p_td
.text
->separator_decode
){
3697 limit
.add_token(p_td
.text
->separator_decode
);
3701 int field_cnt
= get_count();
3702 int * const field_map
= new int[field_cnt
];
3703 memset(field_map
, 0, field_cnt
* sizeof(int));
3705 int mand_field_num
= 0;
3706 int opt_field_num
= 0;
3708 int has_repeatable
=0;
3709 boolean repeatable
= TRUE
;
3711 int next_optional_idx
= 0;
3712 const int* optional_indexes
= get_optional_indexes();
3713 for (int i
=0;i
<field_cnt
;i
++) {
3714 boolean is_optional_field
= optional_indexes
&& (optional_indexes
[next_optional_idx
]==i
);
3715 if (is_optional_field
) {
3716 get_at(i
)->set_to_omit();
3721 if (get_at(i
)->is_seof()) {
3723 repeatable
= repeatable
&& fld_descr(i
)->text
->val
.parameters
->decoding_params
.repeatable
;
3725 if (is_optional_field
) next_optional_idx
++;
3727 boolean has_optinals
= opt_field_num
> 0;
3728 if ((seof
>0) && repeatable
) has_repeatable
=1;
3730 while (mand_field_num
+opt_field_num
+has_repeatable
) {
3734 next_optional_idx
= 0;
3735 for (int i
=0;i
<field_cnt
;i
++) {
3736 boolean is_optional_field
= optional_indexes
&& (optional_indexes
[next_optional_idx
]==i
);
3737 if (get_at(i
)->is_seof()) {
3738 if ( (fld_descr(i
)->text
->val
.parameters
->decoding_params
.repeatable
&& field_map
[i
]<3)
3739 || !field_map
[i
] ) {
3741 decoded_field_length
= get_at(i
)->TEXT_decode(*fld_descr(i
),buff
, limit
, true,!field_map
[i
]);
3742 if (decoded_field_length
<0) {
3744 if (is_optional_field
&& !field_map
[i
]) get_at(i
)->set_to_omit();
3747 if (!field_map
[i
]) {
3748 if (is_optional_field
) opt_field_num
--;
3749 else mand_field_num
--;
3751 } else field_map
[i
]=2;
3756 } else { // !...->is_seof
3757 if (!field_map
[i
]) {
3759 decoded_field_length
= get_at(i
)->TEXT_decode(*fld_descr(i
),buff
,limit
,true);
3760 if (decoded_field_length
<0) {
3762 if (is_optional_field
) get_at(i
)->set_to_omit();
3766 if (is_optional_field
) opt_field_num
--;
3767 else mand_field_num
--;
3773 if (is_optional_field
) next_optional_idx
++;
3777 if (loop_detector
) break;
3778 if (p_td
.text
->separator_decode
) {
3780 if ((tl
=p_td
.text
->separator_decode
->match_begin(buff
))<0) {
3781 if (p_td
.text
->end_decode
) {
3783 if ((tl2
=p_td
.text
->end_decode
->match_begin(buff
))!=-1) {
3787 } else if (limit
.has_token(ml
)) {
3789 if ((tl2
=limit
.match(buff
,ml
))==0) {
3795 decoded_length
-=decoded_field_length
;
3796 field_map
[last_field_num
]+=2;
3799 if (last_field_num
>=0 && last_field_num
<field_cnt
) {
3800 if (get_at(last_field_num
)->is_seof()) {
3801 if (get_at(last_field_num
)->is_optional()) {
3802 if (field_map
[last_field_num
]==3) {
3803 get_at(last_field_num
)->set_to_omit();
3807 if (field_map
[last_field_num
]==3) {
3811 } else if (get_at(last_field_num
)->is_optional()) {
3812 get_at(last_field_num
)->set_to_omit();
3820 } // if (has_optinals)
3824 buff
.increase_pos(tl
);
3825 for (int a
=0;a
<field_cnt
;a
++) if(field_map
[a
]>2) field_map
[a
]-=3;
3828 } else if (p_td
.text
->end_decode
) {
3830 if ((tl
=p_td
.text
->end_decode
->match_begin(buff
))!=-1) {
3832 buff
.increase_pos(tl
);
3833 limit
.remove_tokens(ml
);
3834 if (mand_field_num
) decoded_length
= -1;
3837 } else if(limit
.has_token(ml
)){
3839 if ((tl
=limit
.match(buff
,ml
))==0) {
3845 limit
.remove_tokens(ml
);
3847 if (mand_field_num
) {
3848 if (no_err
) decoded_length
= -1;
3849 else TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR
,
3850 "Error during decoding '%s': ", p_td
.name
);
3853 decoded_length
-=sep_length
;
3854 buff
.set_pos(buff
.get_pos()-sep_length
);
3857 if (p_td
.text
->end_decode
) {
3859 if ((tl
=p_td
.text
->end_decode
->match_begin(buff
))<0) {
3860 if (no_err
) decoded_length
= -1;
3861 else TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR
,
3862 "The specified token '%s' not found for '%s': ",
3863 (const char*)*(p_td
.text
->end_decode
),p_td
.name
);
3867 buff
.increase_pos(tl
);
3869 if (mand_field_num
) decoded_length
= -1;
3872 return decoded_length
;
3873 } else { // record decoder
3874 int decoded_length
=0;
3875 int decoded_field_length
=0;
3876 size_t pos
=buff
.get_pos();
3877 boolean sep_found
=FALSE
;
3880 if (p_td
.text
->begin_decode
) {
3882 if ((tl
=p_td
.text
->begin_decode
->match_begin(buff
))<0) {
3883 if(no_err
)return -1;
3884 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR
,
3885 "The specified token '%s' not found for '%s': ",
3886 (const char*)*(p_td
.text
->begin_decode
), p_td
.name
);
3890 buff
.increase_pos(tl
);
3892 if (p_td
.text
->end_decode
) {
3893 limit
.add_token(p_td
.text
->end_decode
);
3896 if (p_td
.text
->separator_decode
) {
3897 limit
.add_token(p_td
.text
->separator_decode
);
3901 int mand_field_num
= 0;
3902 int opt_field_num
= 0;
3903 int last_man_index
= 0;
3905 int field_cnt
= get_count();
3906 int next_optional_idx
= 0;
3907 const int* optional_indexes
= get_optional_indexes();
3908 for (int i
=0;i
<field_cnt
;i
++) {
3909 boolean is_optional_field
= optional_indexes
&& (optional_indexes
[next_optional_idx
]==i
);
3910 if (is_optional_field
) {
3911 get_at(i
)->set_to_omit();
3917 if (is_optional_field
) next_optional_idx
++;
3920 next_optional_idx
= 0;
3921 for(int i
=0;i
<field_cnt
;i
++) {
3922 boolean is_optional_field
= optional_indexes
&& (optional_indexes
[next_optional_idx
]==i
);
3923 if (is_optional_field
) {
3926 decoded_field_length
= get_at(i
)->TEXT_decode(*fld_descr(i
),buff
,limit
,TRUE
);
3927 if (decoded_field_length
<0) {
3928 if (is_optional_field
) {
3929 get_at(i
)->set_to_omit();
3932 limit
.remove_tokens(ml
);
3933 if (no_err
) return -1;
3934 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR
,
3935 "Error during decoding field '%s' for '%s': ",
3936 fld_descr(i
)->name
, p_td
.name
);
3937 return decoded_length
;
3940 decoded_length
+=decoded_field_length
;
3941 if (last_man_index
>(i
+1)) {
3942 if (p_td
.text
->separator_decode
) {
3944 if ((tl
=p_td
.text
->separator_decode
->match_begin(buff
))<0) {
3945 if(is_optional_field
) {
3946 get_at(i
)->set_to_omit();
3948 decoded_length
-=decoded_field_length
;
3950 limit
.remove_tokens(ml
);
3951 if(no_err
)return -1;
3952 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR
,
3953 "The specified token '%s' not found for '%s': ",
3954 (const char*)*(p_td
.text
->separator_decode
),p_td
.name
);
3955 return decoded_length
;
3959 buff
.increase_pos(tl
);
3963 } else sep_found
=FALSE
;
3965 } else if (i
==(field_cnt
-1)) {
3968 if (p_td
.text
->separator_decode
) {
3970 if ((tl
=p_td
.text
->separator_decode
->match_begin(buff
))<0) {
3971 if (is_optional_field
) {
3972 if (p_td
.text
->end_decode
) {
3973 if ((tl
=p_td
.text
->end_decode
->match_begin(buff
))!=-1) {
3975 buff
.increase_pos(tl
);
3976 limit
.remove_tokens(ml
);
3977 return decoded_length
;
3979 } else if (limit
.has_token(ml
)) {
3980 if ((tl
=limit
.match(buff
,ml
))==0) {
3985 get_at(i
)->set_to_omit();
3987 decoded_length
-=decoded_field_length
;
3994 buff
.increase_pos(tl
);
4001 if (p_td
.text
->end_decode
) {
4002 if ((tl
=p_td
.text
->end_decode
->match_begin(buff
))!=-1) {
4004 buff
.increase_pos(tl
);
4005 limit
.remove_tokens(ml
);
4006 return decoded_length
;
4008 } else if (limit
.has_token(ml
)) {
4009 if ((tl
=limit
.match(buff
,ml
))==0) {
4017 if (is_optional_field
) next_optional_idx
++;
4019 limit
.remove_tokens(ml
);
4021 buff
.set_pos(buff
.get_pos()-sep_length
);
4022 decoded_length
-=sep_length
;
4024 if (p_td
.text
->end_decode
) {
4026 if ((tl
=p_td
.text
->end_decode
->match_begin(buff
))<0) {
4027 if(no_err
)return -1;
4028 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR
,
4029 "The specified token '%s' not found for '%s': ",
4030 (const char*)*(p_td
.text
->end_decode
),p_td
.name
);
4031 return decoded_length
;
4034 buff
.increase_pos(tl
);
4036 return decoded_length
;
4040 const XERdescriptor_t
* Record_Type::xer_descr(int /*field_index*/) const
4042 TTCN_error("Internal error: Record_Type::xer_descr() called.");
4046 char ** Record_Type::collect_ns(const XERdescriptor_t
& p_td
, size_t& num
, bool& def_ns
) const
4048 const int field_cnt
= get_count();
4049 // The USE-ORDER member is first, unless preempted by EMBED-VALUES
4050 const int uo_index
= ((p_td
.xer_bits
& EMBED_VALUES
) !=0);
4051 // Index of the first "normal" member (after E-V and U-O)
4052 const int start_at
= uo_index
+ ((p_td
.xer_bits
& USE_ORDER
) != 0);
4054 size_t num_collected
= 0;
4055 // First, our own namespace. Sets num_collected to 0 or 1.
4056 // If it throws, nothing was allocated.
4057 char **collected_ns
= Base_Type::collect_ns(p_td
, num_collected
, def_ns
);
4060 // If the nil attribute will be written, add the control namespace
4061 boolean nil_attribute
= (p_td
.xer_bits
& USE_NIL
)
4062 && !get_at(field_cnt
-1)->ispresent();
4064 if (nil_attribute
) {
4065 collected_ns
= (char**)Realloc(collected_ns
, sizeof(char*) * ++num_collected
);
4066 const namespace_t
*c_ns
= p_td
.my_module
->get_controlns();
4068 collected_ns
[num_collected
-1] = mprintf(" xmlns:%s='%s'", c_ns
->px
, c_ns
->ns
);
4071 // Collect namespace declarations from all components (recursively).
4072 // This is extremely nasty, but we can't prosecute you for that.
4073 // (Monty Python - Crunchy Frog sketch). This whole thing is O(n^3). Yuck.
4074 for (int a
= start_at
; a
< field_cnt
; ++a
) {
4076 bool def_ns_1
= false;
4077 char **new_namespaces
= get_at(a
)->collect_ns(*xer_descr(a
), num_new
, def_ns_1
);
4078 merge_ns(collected_ns
, num_collected
, new_namespaces
, num_new
);
4079 def_ns
= def_ns
|| def_ns_1
;
4080 // merge_ns freed new_namespaces
4084 // Probably a TC_Error thrown from the element's collect_ns(),
4085 // e.g. if encoding an unbound value.
4086 while (num_collected
> 0) Free(collected_ns
[--num_collected
]);
4091 num
= num_collected
;
4092 return collected_ns
;
4095 // FIXME some hashing should be implemented
4096 int Record_Type::get_index_byname(const char *name
, const char *uri
) const {
4097 int num_fields
= get_count();
4098 for (int i
= 0; i
< num_fields
; ++i
) {
4099 const XERdescriptor_t
& xer
= *xer_descr(i
);
4100 if (check_name(name
, xer
, TRUE
)
4101 && check_namespace(uri
, xer
)) return i
;
4106 int Record_Type::XER_encode(const XERdescriptor_t
& p_td
, TTCN_Buffer
& p_buf
,
4107 unsigned int flavor
, int indent
, embed_values_enc_struct_t
*) const
4110 return XER_encode_negtest(err_descr
, p_td
, p_buf
, flavor
, indent
, 0);
4113 TTCN_EncDec_ErrorContext::error
4114 (TTCN_EncDec::ET_UNBOUND
, "Encoding an unbound value.");
4117 TTCN_EncDec_ErrorContext
ec_0("Component '");
4118 TTCN_EncDec_ErrorContext ec_1
;
4119 int encoded_length
=(int)p_buf
.get_len(); // how much is already in the buffer
4121 int exer
= is_exer(flavor
);
4122 if (exer
&& (p_td
.xer_bits
& EMBED_VALUES
)) flavor
|= XER_CANONICAL
;
4123 const boolean indenting
= !is_canonical(flavor
);
4124 const int field_cnt
= get_count();
4125 const int num_attributes
= get_xer_num_attr();
4126 // The USE-ORDER member is first, unless preempted by EMBED-VALUES
4127 const int uo_index
= ((p_td
.xer_bits
& EMBED_VALUES
) !=0);
4128 // Index of the first "normal" member (after E-V and U-O)
4129 const int start_at
= uo_index
+ ((p_td
.xer_bits
& USE_ORDER
) != 0);
4130 const int first_nonattr
= start_at
+ num_attributes
;
4131 // start_tag_len is keeping track of how much was written at the end of the
4132 // start tag, i.e. the ">\n". This is used later to "back up" over it.
4133 int start_tag_len
= 1 + indenting
;
4134 // The EMBED-VALUES member, if applicable
4135 const Record_Of_Type
* embed_values
= 0;
4136 if (p_td
.xer_bits
& EMBED_VALUES
) {
4137 embed_values
= dynamic_cast<const Record_Of_Type
*>(get_at(0));
4138 if (NULL
== embed_values
) {
4139 const OPTIONAL
<Record_Of_Type
>* const embed_opt
= static_cast<const OPTIONAL
<Record_Of_Type
>*>(get_at(0));
4140 if(embed_opt
->is_present()) {
4141 embed_values
= &(*embed_opt
)();
4145 // The USE-ORDER member, if applicable
4146 const Record_Of_Type
* const use_order
= (p_td
.xer_bits
& USE_ORDER
)
4147 ? static_cast<const Record_Of_Type
*>(get_at(uo_index
)) : 0;
4149 size_t num_collected
= 0; // we use this to compute delay_close
4150 char **collected_ns
= NULL
;
4151 bool def_ns
= false;
4153 if (indent
== 0) { // top-level type
4154 collected_ns
= collect_ns(p_td
, num_collected
, def_ns
);
4156 else if ((flavor
& DEF_NS_SQUASHED
) && p_td
.my_module
&& p_td
.ns_index
!= -1) {
4157 const namespace_t
* ns
= p_td
.my_module
->get_ns(p_td
.ns_index
);
4158 // The default namespace has been squashed.
4159 // If we are in the default namespace, restore it.
4160 if (*ns
->px
== '\0') {
4161 collected_ns
= Base_Type::collect_ns(p_td
, num_collected
, def_ns
);
4166 // The type's own tag is omitted if we're doing E-XER,
4167 // and it's not the top-level type (XML must have a root element)
4168 // and it's either UNTAGGED or got USE_NIL or USE_TYPE or USE_UNION.
4169 boolean omit_tag
= exer
&& (indent
> 0)
4170 && ( (p_td
.xer_bits
& (UNTAGGED
|XER_ATTRIBUTE
))
4171 || (flavor
& (USE_NIL
|USE_TYPE_ATTR
)));
4173 // If a default namespace is in effect (uri but no prefix) and the type
4174 // is unqualified, the default namespace must be canceled; otherwise
4175 // an XML tag without a ns prefix looks like it belongs to the def.namespace
4176 const boolean empty_ns_hack
= exer
&& !omit_tag
&& (indent
> 0)
4177 && (p_td
.xer_bits
& FORM_UNQUALIFIED
)
4178 && (flavor
& DEF_NS_PRESENT
);
4180 // delay_close=true if there is stuff before the '>' of the start tag
4181 // (prevents writing the '>' which is built into the name).
4182 // This can only happen for EXER: if there are attributes or namespaces,
4183 // or either USE-NIL or USE-QNAME is set.
4184 boolean delay_close
= exer
&& (num_attributes
4185 || empty_ns_hack
// counts as having a namespace
4186 || (num_collected
!= 0)
4187 || (p_td
.xer_bits
& (USE_NIL
|USE_QNAME
))
4188 || (flavor
& USE_NIL
));
4192 if (!omit_tag
) { /* write start tag */
4193 if (indenting
) do_indent(p_buf
, indent
);
4194 /* name looks like this: "tagname>\n"
4195 * lose the \n if : not indenting or (single untagged(*) or attributes (*)) AND exer
4196 * lose the > if attributes are present (*) AND exer
4199 if (exer
) write_ns_prefix(p_td
, p_buf
);
4200 p_buf
.put_s((size_t)p_td
.namelens
[exer
] - delay_close
4201 - (!indenting
|| delay_close
|| (exer
&& (p_td
.xer_bits
& HAS_1UNTAGGED
))),
4202 (cbyte
*)p_td
.names
[exer
]);
4204 else if (flavor
& (USE_NIL
|USE_TYPE_ATTR
)) {
4205 // reopen the parent's start tag by overwriting the '>'
4206 size_t buf_len
= p_buf
.get_len();
4207 const unsigned char * const buf_data
= p_buf
.get_data();
4208 if (buf_data
[buf_len
- 1 - shorter
] == '\n') ++shorter
;
4209 if (buf_data
[buf_len
- 1 - shorter
] == '>' ) ++shorter
;
4212 p_buf
.increase_length(-shorter
);
4218 // mask out extra flags we received, do not send them to the fields
4221 if (exer
&& (p_td
.xer_bits
& USE_QNAME
)) { // QName trumps everything
4222 const Base_Type
* const q_uri
= get_at(0);
4223 if (q_uri
->is_present()) {
4224 p_buf
.put_s(11, (cbyte
*)" xmlns:b0='");
4225 q_uri
->XER_encode(*xer_descr(0), p_buf
, flavor
| XER_LIST
, indent
+1, 0);
4229 if (p_td
.xer_bits
& XER_ATTRIBUTE
) begin_attribute(p_td
, p_buf
);
4230 else p_buf
.put_c('>');
4232 if (q_uri
->is_present()) {
4233 p_buf
.put_s(3, (cbyte
*)"b0:");
4236 const Base_Type
* const q_name
= get_at(1);
4237 sub_len
+= q_name
->XER_encode(*xer_descr(1), p_buf
, flavor
| XER_LIST
, indent
+1, 0);
4238 if (p_td
.xer_bits
& XER_ATTRIBUTE
) p_buf
.put_c('\'');
4240 else { // not USE-QNAME
4241 if (!exer
&& (p_td
.xer_bits
& EMBED_VALUES
) && embed_values
!= NULL
) {
4242 // The EMBED-VALUES member as an ordinary record of string
4243 sub_len
+= embed_values
->XER_encode(*xer_descr(0), p_buf
, flavor
, indent
+1, 0);
4246 if (!exer
&& (p_td
.xer_bits
& USE_ORDER
)) {
4247 // The USE-ORDER member as an ordinary record of enumerated
4248 sub_len
+= use_order
->XER_encode(*xer_descr(uo_index
), p_buf
, flavor
, indent
+1, 0);
4251 if (exer
&& (indent
==0 || (flavor
& DEF_NS_SQUASHED
))) // write namespaces for toplevel only
4253 for (size_t cur_coll
= 0; cur_coll
< num_collected
; ++cur_coll
) {
4254 p_buf
.put_s(strlen(collected_ns
[cur_coll
]), (cbyte
*)collected_ns
[cur_coll
]);
4255 Free(collected_ns
[cur_coll
]); // job done
4261 flavor
&= ~DEF_NS_SQUASHED
;
4262 flavor
|= DEF_NS_PRESENT
;
4264 else if (empty_ns_hack
) {
4265 p_buf
.put_s(9, (cbyte
*)" xmlns=''");
4266 flavor
&= ~DEF_NS_PRESENT
;
4267 flavor
|= DEF_NS_SQUASHED
;
4270 /* First all the attributes (not added to sub_len) */
4272 for (i
= start_at
; i
< first_nonattr
; ++i
) {
4273 boolean is_xer_attr_field
= xer_descr(i
)->xer_bits
& XER_ATTRIBUTE
;
4274 ec_1
.set_msg("%s': ", fld_name(i
)); // attr
4275 int tmp_len
= get_at(i
)->XER_encode(*xer_descr(i
), p_buf
, flavor
, indent
+1, 0);
4276 if (is_xer_attr_field
&& !exer
) sub_len
+= tmp_len
; /* do not add if attribute and EXER */
4279 // True if the "nil" attribute needs to be written.
4280 boolean nil_attribute
= exer
&& (p_td
.xer_bits
& USE_NIL
)
4281 && !get_at(field_cnt
-1)->ispresent();
4283 // True if USE_ORDER is in effect and the "nil" attribute was written.
4284 // Then the record-of-enum for USE-ORDER will be empty.
4285 boolean early_to_bed
= FALSE
;
4287 if (nil_attribute
) { // req. exer and USE_NIL
4288 const namespace_t
*control_ns
= p_td
.my_module
->get_controlns();
4290 p_buf
.put_s(strlen(control_ns
->px
),
4291 (cbyte
*)control_ns
->px
);
4293 p_buf
.put_s(10, (cbyte
*)"nil='true'");
4294 if ((p_td
.xer_bits
& USE_ORDER
)) early_to_bed
= TRUE
;
4295 // The whole content was omitted; nothing to do (and if we tried
4296 // to do it, we'd get an error for over-indexing a 0-length record-of).
4299 if (delay_close
&& (!omit_tag
|| shorter
)) {
4300 // Close the start tag left open. If indenting, also write a newline
4301 // unless USE-NIL in effect or there is a single untagged component.
4303 ((p_td
.xer_bits
& (/*USE_NIL|*/HAS_1UNTAGGED
)) ? 0 : indenting
);
4304 p_buf
.put_s(start_tag_len
, (cbyte
*)">\n");
4307 if (exer
&& (p_td
.xer_bits
& EMBED_VALUES
)) {
4308 /* write the first string */
4309 if (embed_values
!= NULL
&& embed_values
->size_of() > 0) {
4310 sub_len
+= embed_values
->get_at(0)->XER_encode(UNIVERSAL_CHARSTRING_xer_
,
4311 p_buf
, flavor
| EMBED_VALUES
, indent
+1, 0);
4315 const Record_Type
*ordered
= this; // the record affected by USE-ORDER
4317 // Index of the first non-attribute field of the record pointed to by
4318 // ordered, that is, the first field affected by USE-ORDER.
4319 size_t useorder_base
= first_nonattr
;
4322 int end
= field_cnt
;
4323 if (exer
&& (p_td
.xer_bits
& USE_ORDER
)) {
4324 const int to_send
= use_order
->size_of();
4325 // the length of the loop is determined by the length of use_order
4329 // Count the non-attribute optionals
4330 int n_optionals
= 0;
4331 for (int B
= optional_count() - 1; B
>=+0; B
--) {
4332 int oi
= get_optional_indexes()[B
];
4333 if (oi
< first_nonattr
) break;
4337 int expected_max
= field_cnt
- first_nonattr
;
4338 int expected_min
= expected_max
- n_optionals
;
4340 if ((p_td
.xer_bits
& USE_NIL
) && get_at(field_cnt
-1)->ispresent()) {
4341 // The special case when USE_ORDER refers to the fields of a field,
4343 const Base_Type
*last_optional
= get_at(field_cnt
-1);
4344 const Base_Type
* inner
= last_optional
->get_opt_value();
4345 // it absolutely, positively has to be (derived from) Record_Type
4346 ordered
= static_cast<const Record_Type
*>(inner
);
4347 useorder_base
= ordered
->get_xer_num_attr();
4348 begin
= useorder_base
;
4349 end
= ordered
->get_count();
4351 expected_min
= expected_max
= ordered
->get_count();
4354 if (to_send
> expected_max
4355 ||to_send
< expected_min
) {
4356 ec_1
.set_msg("%s': ", fld_name(uo_index
));
4357 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_CONSTRAINT
,
4358 "Wrong number of USE-ORDER %d, must be %d..%d", to_send
, expected_min
, expected_max
);
4359 begin
= end
= 0; // don't bother sending anything
4361 else { // check no duplicates
4362 int *seen
= new int [to_send
];
4364 for (int ei
= 0; ei
< to_send
; ++ei
) {
4365 const Base_Type
*uoe
= use_order
->get_at(ei
);
4366 const Enum_Type
*enm
= static_cast<const Enum_Type
*>(uoe
);
4367 int val
= enm
->as_int();
4368 for (int x
= 0; x
< num_seen
; ++x
) {
4369 if (val
== seen
[x
]) { // complain
4370 ec_1
.set_msg("%s': ", fld_name(uo_index
));
4371 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_CONSTRAINT
,
4372 "Duplicate value for USE-ORDER");
4373 begin
= end
= 0; // don't bother sending anything
4377 seen
[num_seen
++] = val
;
4381 // If the number is right and there are no duplicates, then carry on
4385 /* Then, all the non-attributes. Structuring the code like this depends on
4386 * all attributes appearing before all non-attributes (excluding
4387 * pseudo-members for USE-ORDER, etc.) */
4389 // early_to_bed can only be true if exer is true (transitive through nil_attribute)
4390 if (!early_to_bed
) {
4391 embed_values_enc_struct_t
* emb_val
= 0;
4392 if (exer
&& (p_td
.xer_bits
& EMBED_VALUES
) &&
4393 embed_values
!= NULL
&& embed_values
->size_of() > 1) {
4394 emb_val
= new embed_values_enc_struct_t
;
4395 emb_val
->embval_array
= embed_values
;
4396 emb_val
->embval_index
= 1;
4397 emb_val
->embval_err
= 0;
4400 for ( i
= begin
; i
< end
; ++i
) {
4401 const Base_Type
*uoe
= 0; // "useOrder enum"
4402 const Enum_Type
*enm
= 0; // the enum value selecting the field
4403 if (exer
&& use_order
) {
4404 uoe
= use_order
->get_at(i
- begin
);
4405 enm
= static_cast<const Enum_Type
*>(uoe
);
4408 // "actual" index, may be perturbed by USE-ORDER
4409 int ai
= !(exer
&& (p_td
.xer_bits
& USE_ORDER
)) ? i
:
4410 enm
->as_int() + useorder_base
;
4411 ec_1
.set_msg("%s': ", ordered
->fld_name(ai
)); // non-attr
4413 const XERdescriptor_t
& descr
= *ordered
->xer_descr(ai
);
4414 sub_len
+= ordered
->get_at(ai
)->XER_encode(descr
, p_buf
,
4415 // Pass USE-NIL to the last field (except when USE-ORDER is also in effect,
4416 // because the tag-stripping effect of USE-NIL has been achieved
4417 // by encoding the sub-fields directly).
4418 flavor
| ((exer
&& !use_order
&& (i
== field_cnt
-1)) ? (p_td
.xer_bits
& USE_NIL
) : 0),
4419 indent
+!omit_tag
, emb_val
);
4421 // Now the next embed-values string (NOT affected by USE-ORDER!)
4422 if (exer
&& (p_td
.xer_bits
& EMBED_VALUES
) && 0 != emb_val
&&
4423 embed_values
!= NULL
&& emb_val
->embval_index
< embed_values
->size_of()) {
4424 embed_values
->get_at(emb_val
->embval_index
)->XER_encode(UNIVERSAL_CHARSTRING_xer_
4425 , p_buf
, flavor
| EMBED_VALUES
, indent
+1, 0);
4426 ++emb_val
->embval_index
;
4431 if (embed_values
!= NULL
&& emb_val
->embval_index
< embed_values
->size_of()) {
4432 ec_1
.set_msg("%s': ", fld_name(0));
4433 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_CONSTRAINT
,
4434 "Too many EMBED-VALUEs specified: %d (expected %d or less)",
4435 embed_values
->size_of(), emb_val
->embval_index
);
4439 } // if (!early_to_bed)
4443 if (sub_len
) { // something was written, now an end tag
4444 if (indenting
&& !(exer
&& (p_td
.xer_bits
& (HAS_1UNTAGGED
| USE_QNAME
)))) {
4445 // The tags of the last optional member involved with USE_NIL
4446 // have been removed. If it was a simple type, the content was probably
4447 // written on a single line without anything resembling a close tag.
4448 // Do not indent our end tag in this case.
4449 switch ((int)(exer
&& (p_td
.xer_bits
& USE_NIL
))) {
4451 const unsigned char *buf_end
= p_buf
.get_data() + (p_buf
.get_len()-1);
4452 if (buf_end
[-1] != '>' || *buf_end
!= '\n') break;
4453 // If it does not look like an end tag, skip the indenting,
4454 // else fall through.
4457 do_indent(p_buf
, indent
);
4463 if (exer
) write_ns_prefix(p_td
, p_buf
);
4464 p_buf
.put_s((size_t)p_td
.namelens
[exer
]-!indenting
, (cbyte
*)p_td
.names
[exer
]);
4466 else { // need to generate an empty element tag
4467 p_buf
.increase_length(-start_tag_len
); // decrease length
4468 p_buf
.put_s((size_t)2+indenting
, (cbyte
*)"/>\n");
4472 return (int)p_buf
.get_len() - encoded_length
;
4475 // XERSTUFF Record_Type::encode_field
4476 /** Helper for Record_Type::XER_encode_negtest
4478 * Factored out because Record_Type::XER_encode (on which XER_encode_negtest
4479 * is based) calls the XER_encode method of the field in two places:
4480 * one for attributes, the other for elements.
4482 * @param i index of the field
4483 * @param err_vals erroneous descriptor for the field
4484 * @param emb_descr deeper erroneous values
4485 * @param p_buf buffer containing the encoded value
4486 * @param sub_flavor flags
4487 * @param indent indentation level
4488 * @return the number of bytes generated
4490 int Record_Type::encode_field(int i
,
4491 const Erroneous_values_t
* err_vals
, const Erroneous_descriptor_t
* emb_descr
,
4492 TTCN_Buffer
& p_buf
, unsigned int sub_flavor
, int indent
, embed_values_enc_struct_t
* emb_val
) const
4495 TTCN_EncDec_ErrorContext ec
;
4496 if (err_vals
&& err_vals
->before
) {
4497 if (err_vals
->before
->errval
==NULL
) TTCN_error(
4498 "internal error: erroneous before value missing");
4499 ec
.set_msg("Erroneous value before component %s: ", fld_name(i
));
4500 if (err_vals
->before
->raw
) {
4501 enc_len
+= err_vals
->before
->errval
->encode_raw(p_buf
);
4503 if (err_vals
->before
->type_descr
==NULL
) TTCN_error(
4504 "internal error: erroneous before typedescriptor missing");
4505 enc_len
+= err_vals
->before
->errval
->XER_encode(
4506 *err_vals
->before
->type_descr
->xer
, p_buf
, sub_flavor
, indent
, 0);
4510 if (err_vals
&& err_vals
->value
) {
4511 if (err_vals
->value
->errval
) { // replace
4512 ec
.set_msg("Erroneous value for component %s: ", fld_name(i
));
4513 if (err_vals
->value
->raw
) {
4514 enc_len
+= err_vals
->value
->errval
->encode_raw(p_buf
);
4516 if (err_vals
->value
->type_descr
==NULL
) TTCN_error(
4517 "internal error: erroneous value typedescriptor missing");
4518 enc_len
+= err_vals
->value
->errval
->XER_encode(
4519 *err_vals
->value
->type_descr
->xer
, p_buf
, sub_flavor
, indent
, 0);
4523 ec
.set_msg("Component %s: ", fld_name(i
));
4525 enc_len
+= get_at(i
)->XER_encode_negtest(emb_descr
, *xer_descr(i
), p_buf
,
4526 sub_flavor
, indent
, emb_val
);
4528 // the "real" encoder
4529 enc_len
+= get_at(i
)->XER_encode(*xer_descr(i
), p_buf
,
4530 sub_flavor
, indent
, emb_val
);
4534 if (err_vals
&& err_vals
->after
) {
4535 if (err_vals
->after
->errval
==NULL
) TTCN_error(
4536 "internal error: erroneous after value missing");
4537 ec
.set_msg("Erroneous value after component %s: ", fld_name(i
));
4538 if (err_vals
->after
->raw
) {
4539 enc_len
+= err_vals
->after
->errval
->encode_raw(p_buf
);
4541 if (err_vals
->after
->type_descr
==NULL
) TTCN_error(
4542 "internal error: erroneous after typedescriptor missing");
4543 enc_len
+= err_vals
->after
->errval
->XER_encode(
4544 *err_vals
->after
->type_descr
->xer
, p_buf
, sub_flavor
, indent
, 0);
4551 // XERSTUFF Record_Type::XER_encode_negtest
4552 int Record_Type::XER_encode_negtest(const Erroneous_descriptor_t
* p_err_descr
,
4553 const XERdescriptor_t
& p_td
, TTCN_Buffer
& p_buf
, unsigned int flavor
, int indent
,
4554 embed_values_enc_struct_t
*) const
4557 TTCN_EncDec_ErrorContext::error
4558 (TTCN_EncDec::ET_UNBOUND
, "Encoding an unbound value.");
4560 TTCN_EncDec_ErrorContext
ec_0("Component '");
4561 TTCN_EncDec_ErrorContext ec_1
;
4562 int encoded_length
=(int)p_buf
.get_len(); // how much is already in the buffer
4564 int exer
= is_exer(flavor
);
4565 if (exer
&& (p_td
.xer_bits
& EMBED_VALUES
)) flavor
|= XER_CANONICAL
;
4566 const boolean indenting
= !is_canonical(flavor
);
4567 const int field_cnt
= get_count();
4568 const int num_attributes
= get_xer_num_attr();
4569 // The USE-ORDER member is first, unless preempted by EMBED-VALUES
4570 const int uo_index
= ((p_td
.xer_bits
& EMBED_VALUES
) !=0);
4571 // Index of the first "normal" member (after E-V and U-O)
4572 const int start_at
= uo_index
+ ((p_td
.xer_bits
& USE_ORDER
) != 0);
4573 const int first_nonattr
= start_at
+ num_attributes
;
4574 // start_tag_len is keeping track of how much was written at the end of the
4575 // start tag, i.e. the ">\n". This is used later to "back up" over it.
4576 int start_tag_len
= 1 + indenting
;
4577 // The EMBED-VALUES member, if applicable (always first)
4578 const Record_Of_Type
* const embed_values
= (p_td
.xer_bits
& EMBED_VALUES
)
4579 ? static_cast<const Record_Of_Type
*>(get_at(0)) : 0;
4580 // The USE-ORDER member, if applicable (first unless preempted by embed_vals)
4581 const Record_Of_Type
* const use_order
= (p_td
.xer_bits
& USE_ORDER
)
4582 ? static_cast<const Record_Of_Type
*>(get_at(uo_index
)) : 0;
4587 size_t num_collected
= 0; // we use this to compute delay_close
4588 char **collected_ns
= NULL
;
4589 bool def_ns
= false;
4591 if (indent
== 0) { // top-level type
4592 collected_ns
= collect_ns(p_td
, num_collected
, def_ns
);
4594 else if ((flavor
& DEF_NS_SQUASHED
) && p_td
.my_module
&& p_td
.ns_index
!= -1) {
4595 const namespace_t
* ns
= p_td
.my_module
->get_ns(p_td
.ns_index
);
4596 // The default namespace has been squashed.
4597 // If we are in the default namespace, restore it.
4598 if (*ns
->px
== '\0') {
4599 collected_ns
= Base_Type::collect_ns(p_td
, num_collected
, def_ns
);
4604 // The type's own tag is omitted if we're doing E-XER,
4605 // and it's not the top-level type (XML must have a root element)
4606 // and it's either UNTAGGED or got USE_NIL.
4607 boolean omit_tag
= exer
&& indent
4608 && ( (p_td
.xer_bits
& (UNTAGGED
|XER_ATTRIBUTE
))
4609 || (flavor
& (USE_NIL
|USE_TYPE_ATTR
)));
4611 // If a default namespace is in effect (uri but no prefix) and the type
4612 // is unqualified, the default namespace must be canceled; otherwise
4613 // an XML tag without a ns prefix looks like it belongs to the def.namespace
4614 const boolean empty_ns_hack
= exer
&& !omit_tag
&& (indent
> 0)
4615 && (p_td
.xer_bits
& FORM_UNQUALIFIED
)
4616 && (flavor
& DEF_NS_PRESENT
);
4618 // delay_close=true if there is stuff before the '>' of the start tag
4619 // (prevents writing the '>' which is built into the name).
4620 // This can only happen for EXER: if there are attributes or namespaces,
4621 // or either USE-NIL or USE-QNAME is set.
4622 boolean delay_close
= exer
&& (num_attributes
4623 || empty_ns_hack
// counts as having a namespace
4624 || (num_collected
!= 0)
4625 || (p_td
.xer_bits
& (USE_NIL
|USE_QNAME
))
4626 || (flavor
& USE_NIL
));
4629 if (!omit_tag
) { /* write start tag */
4630 if (indenting
) do_indent(p_buf
, indent
);
4631 /* name looks like this: "tagname>\n"
4632 * lose the \n if : not indenting or (single untagged(*) or attributes (*)) AND exer
4633 * lose the > if attributes are present (*) AND exer
4636 if (exer
) write_ns_prefix(p_td
, p_buf
);
4637 p_buf
.put_s((size_t)p_td
.namelens
[exer
] - delay_close
4638 - (!indenting
|| delay_close
|| (exer
&& (p_td
.xer_bits
& HAS_1UNTAGGED
))),
4639 (cbyte
*)p_td
.names
[exer
]);
4641 else if (flavor
& USE_TYPE_ATTR
) {
4642 // reopen the parent's tag
4643 size_t buf_len
= p_buf
.get_len();
4644 const unsigned char * const buf_data
= p_buf
.get_data();
4645 if (buf_data
[buf_len
- 1 - shorter
] == '\n') ++shorter
;
4646 if (buf_data
[buf_len
- 1 - shorter
] == '>' ) ++shorter
;
4649 p_buf
.increase_length(-shorter
);
4654 int sub_len
=0, tmp_len
;
4655 // mask out extra flags we received, do not send them to the fields
4658 if (exer
&& (p_td
.xer_bits
& USE_QNAME
)) {
4659 const Erroneous_values_t
* ev
=
4660 p_err_descr
->next_field_err_values(0, values_idx
);
4661 const Erroneous_descriptor_t
* ed
=
4662 p_err_descr
->next_field_emb_descr (0, edescr_idx
);
4663 // At first, erroneous info for the first component (uri)
4665 TTCN_EncDec_ErrorContext ec
;
4666 const Base_Type
* const q_uri
= get_at(0);
4668 if (ev
&& ev
->before
) {
4669 if (ev
->before
->errval
==NULL
) TTCN_error(
4670 "internal error: erroneous before value missing");
4671 ec
.set_msg("Erroneous value before component #0: ");
4672 if (ev
->before
->raw
) {
4673 sub_len
+= ev
->before
->errval
->encode_raw(p_buf
);
4675 if (ev
->before
->type_descr
==NULL
) TTCN_error(
4676 "internal error: erroneous before typedescriptor missing");
4677 sub_len
+= ev
->before
->errval
->XER_encode(
4678 *ev
->before
->type_descr
->xer
, p_buf
, flavor
, indent
, 0);
4682 if (ev
&& ev
->value
) {
4683 if (ev
->value
->errval
) { // replace
4684 ec
.set_msg("Erroneous value for component #0: ");
4685 if (ev
->value
->raw
) {
4686 sub_len
+= ev
->value
->errval
->encode_raw(p_buf
);
4688 if (ev
->value
->type_descr
==NULL
) TTCN_error(
4689 "internal error: erroneous value typedescriptor missing");
4690 sub_len
+= ev
->value
->errval
->XER_encode(
4691 *ev
->value
->type_descr
->xer
, p_buf
, flavor
, indent
, 0);
4695 ec
.set_msg("Component #0: ");
4697 // universal charstring does not have components.
4698 // TTCN code which could have generated embedded erroneous descriptor
4699 // should have failed semantic analysis.
4700 TTCN_error("internal error: embedded descriptor unexpected");
4702 // the "real" encoder
4703 if (q_uri
->is_present()) {
4704 p_buf
.put_s(11, (cbyte
*)" xmlns:b0='");
4705 sub_len
+= q_uri
->XER_encode(*xer_descr(0), p_buf
, flavor
| XER_LIST
, indent
+1, 0);
4711 if (ev
&& ev
->after
) {
4712 if (ev
->after
->errval
==NULL
) TTCN_error(
4713 "internal error: erroneous after value missing");
4714 ec
.set_msg("Erroneous value after component #0: ");
4715 if (ev
->after
->raw
) {
4716 sub_len
+= ev
->after
->errval
->encode_raw(p_buf
);
4718 if (ev
->after
->type_descr
==NULL
) TTCN_error(
4719 "internal error: erroneous after typedescriptor missing");
4720 sub_len
+= ev
->after
->errval
->XER_encode(
4721 *ev
->after
->type_descr
->xer
, p_buf
, flavor
, indent
, 0);
4725 if (p_td
.xer_bits
& XER_ATTRIBUTE
) begin_attribute(p_td
, p_buf
);
4726 else p_buf
.put_c('>');
4728 // Now switch to the second field (name)
4729 ev
= p_err_descr
->next_field_err_values(1, values_idx
);
4730 ed
= p_err_descr
->next_field_emb_descr (1, edescr_idx
);
4732 if (ev
&& ev
->before
) {
4733 if (ev
->before
->errval
==NULL
) TTCN_error(
4734 "internal error: erroneous before value missing");
4735 ec
.set_msg("Erroneous value before component #1: ");
4736 if (ev
->before
->raw
) {
4737 sub_len
+= ev
->before
->errval
->encode_raw(p_buf
);
4739 if (ev
->before
->type_descr
==NULL
) TTCN_error(
4740 "internal error: erroneous before typedescriptor missing");
4741 sub_len
+= ev
->before
->errval
->XER_encode(
4742 *ev
->before
->type_descr
->xer
, p_buf
, flavor
, indent
, 0);
4746 if (ev
&& ev
->value
) {
4747 if (ev
->value
->errval
) { // replace
4748 ec
.set_msg("Erroneous value for component #1: ");
4749 if (ev
->value
->raw
) {
4750 sub_len
+= ev
->value
->errval
->encode_raw(p_buf
);
4752 if (ev
->value
->type_descr
==NULL
) TTCN_error(
4753 "internal error: erroneous value typedescriptor missing");
4754 sub_len
+= ev
->value
->errval
->XER_encode(
4755 *ev
->value
->type_descr
->xer
, p_buf
, flavor
, indent
, 0);
4759 ec
.set_msg("Component #1: ");
4761 // universal charstring does not have components
4762 TTCN_error("internal error: embedded descriptor unexpected");
4764 // the "real" encoder
4765 if (q_uri
->is_present()) {
4766 p_buf
.put_s(3, (cbyte
*)"b0:");
4770 sub_len
+= get_at(1)->XER_encode(*xer_descr(1), p_buf
, flavor
| XER_LIST
, indent
+1, 0);
4774 if (ev
&& ev
->after
) {
4775 if (ev
->after
->errval
==NULL
) TTCN_error(
4776 "internal error: erroneous after value missing");
4777 ec
.set_msg("Erroneous value after component #1: ");
4778 if (ev
->after
->raw
) {
4779 sub_len
+= ev
->after
->errval
->encode_raw(p_buf
);
4781 if (ev
->after
->type_descr
==NULL
) TTCN_error(
4782 "internal error: erroneous after typedescriptor missing");
4783 sub_len
+= ev
->after
->errval
->XER_encode(
4784 *ev
->after
->type_descr
->xer
, p_buf
, flavor
, indent
, 0);
4788 if (p_td
.xer_bits
& XER_ATTRIBUTE
) p_buf
.put_c('\'');
4790 else { // not USE-QNAME
4791 if (!exer
&& (p_td
.xer_bits
& EMBED_VALUES
)) {
4792 // The EMBED-VALUES member as an ordinary record of string
4793 sub_len
+= embed_values
->XER_encode(*xer_descr(0), p_buf
, flavor
, indent
+1, 0);
4796 if (!exer
&& (p_td
.xer_bits
& USE_ORDER
)) {
4797 // The USE-ORDER member as an ordinary record of enumerated
4798 sub_len
+= use_order
->XER_encode(*xer_descr(uo_index
), p_buf
, flavor
, indent
+1, 0);
4801 if (exer
&& (indent
==0 || (flavor
& DEF_NS_SQUASHED
))) // write namespaces for toplevel only
4803 for (size_t cur_coll
= 0; cur_coll
< num_collected
; ++cur_coll
) {
4804 p_buf
.put_s(strlen(collected_ns
[cur_coll
]), (cbyte
*)collected_ns
[cur_coll
]);
4805 Free(collected_ns
[cur_coll
]); // job done
4811 flavor
&= ~DEF_NS_SQUASHED
;
4812 flavor
|= DEF_NS_PRESENT
;
4814 else if (empty_ns_hack
) {
4815 p_buf
.put_s(9, (cbyte
*)" xmlns=''");
4816 flavor
&= ~DEF_NS_PRESENT
;
4817 flavor
|= DEF_NS_SQUASHED
;
4820 // True if the non-attribute fields need to be omitted;
4821 // e.g. if USE_ORDER is in effect and the "nil" attribute was written
4822 // (then the record-of-enum for USE-ORDER will be empty),
4823 // or "omit all after" was hit while processing attributes.
4824 boolean early_to_bed
= FALSE
;
4826 // First all the attributes (not added to sub_len)
4828 for (i
= start_at
; i
< first_nonattr
; ++i
) {
4829 const Erroneous_values_t
* ev
=
4830 p_err_descr
->next_field_err_values(i
, values_idx
);
4831 const Erroneous_descriptor_t
* ed
=
4832 p_err_descr
->next_field_emb_descr(i
, edescr_idx
);
4834 if (i
< p_err_descr
->omit_before
) continue;
4836 boolean is_xer_attr_field
= xer_descr(i
)->xer_bits
& XER_ATTRIBUTE
;
4837 ec_1
.set_msg("%s': ", fld_name(i
)); // attr
4839 tmp_len
= encode_field(i
, ev
, ed
, p_buf
, flavor
, indent
+ !omit_tag
, 0);
4841 if (is_xer_attr_field
&& !exer
) sub_len
+= tmp_len
; // do not add if attribute and EXER
4843 // omit_after value -1 becomes "very big"
4844 if ((unsigned int)i
>= (unsigned int)p_err_descr
->omit_after
) {
4845 early_to_bed
= TRUE
; // no more fields to write
4850 // True if the "nil" attribute needs to be written.
4851 boolean nil_attribute
= FALSE
;
4852 // nil attribute unaffected by erroneous
4853 boolean nil_attribute_simple
= FALSE
;
4854 if (exer
&& (p_td
.xer_bits
& USE_NIL
)) {
4855 nil_attribute
= nil_attribute_simple
= !get_at(field_cnt
-1)->ispresent();
4857 if (p_err_descr
->values_size
> 0) // there is an erroneous "value := ..."
4859 const Erroneous_values_t
*ev_nil
=
4860 p_err_descr
->get_field_err_values(field_cnt
-1);
4861 if (ev_nil
&& ev_nil
->value
) // value override for the last field
4863 nil_attribute
= (ev_nil
->value
->errval
== NULL
);
4868 if (nil_attribute
) { // req. exer and USE_NIL
4869 const namespace_t
*control_ns
= p_td
.my_module
->get_controlns();
4871 if (!nil_attribute_simple
) {
4872 // It is likely that the declaration for namespace "xsi"
4873 // was not written. Do it now.
4874 p_buf
.put_s(7, (cbyte
*)" xmlns:");
4875 p_buf
.put_s(strlen(control_ns
->px
), (cbyte
*)control_ns
->px
);
4876 p_buf
.put_s(2, (cbyte
*)"='");
4877 p_buf
.put_s(strlen(control_ns
->ns
), (cbyte
*)control_ns
->ns
);
4882 p_buf
.put_s(strlen(control_ns
->px
), (cbyte
*)control_ns
->px
);
4884 p_buf
.put_s(10, (cbyte
*)"nil='true'");
4885 if ((p_td
.xer_bits
& USE_ORDER
)) early_to_bed
= TRUE
;
4886 // The whole content was omitted; nothing to do (and if we tried
4887 // to do it, we'd get an error for over-indexing a 0-length record-of).
4890 if (delay_close
&& (!omit_tag
|| shorter
)) {
4891 // Close the start tag left open. If indenting, also write a newline
4892 // unless USE-NIL in effect or there is a single untagged component.
4894 ((p_td
.xer_bits
& (/*USE_NIL|*/HAS_1UNTAGGED
)) ? 0 : indenting
);
4895 p_buf
.put_s(start_tag_len
, (cbyte
*)">\n");
4898 // Erroneous values for the embed_values member (if any).
4899 // Collected once but referenced multiple times.
4900 const Erroneous_descriptor_t
* ed0
= NULL
;
4901 int embed_values_val_idx
= 0;
4902 int embed_values_descr_idx
= 0;
4904 if (exer
&& (p_td
.xer_bits
& EMBED_VALUES
)) {
4905 ed0
= p_err_descr
->next_field_emb_descr(0, edescr_idx
);
4907 // write the first string
4908 if (embed_values
->size_of() > 0) {
4909 const Erroneous_values_t
* ev0_0
= NULL
;
4910 const Erroneous_descriptor_t
* ed0_0
= NULL
;
4912 ev0_0
= ed0
->next_field_err_values(0, embed_values_val_idx
);
4913 ed0_0
= ed0
->next_field_emb_descr (0, embed_values_descr_idx
);
4915 sub_len
+= embed_values
->encode_element(0, UNIVERSAL_CHARSTRING_xer_
,
4916 ev0_0
, ed0_0
, p_buf
, flavor
| EMBED_VALUES
, indent
+!omit_tag
, 0);
4920 const Record_Type
*ordered
= this; // the record affected by USE-ORDER
4921 // By default it's this record, unless USE_NIL is _also_ in effect,
4922 // in which case it's the last member of this.
4924 // Index of the first non-attribute field of the record pointed to by
4925 // ordered, that is, the first field affected by USE-ORDER.
4926 size_t useorder_base
= first_nonattr
;
4929 int end
= field_cnt
; // "one past", do not touch
4930 // by default, continue from the current field until the end, indexing this
4932 if (exer
&& (p_td
.xer_bits
& USE_ORDER
)) {
4933 // the length of the loop is determined by the length of use_order
4934 const int to_send
= use_order
->size_of();
4936 // i will index all elements of the use_order member
4940 // Count the non-attribute optionals
4941 int n_optionals
= 0;
4942 for (int B
= optional_count() - 1; B
>=+0; B
--) {
4943 int oi
= get_optional_indexes()[B
];
4944 if (oi
< first_nonattr
) break;
4948 int expected_min
= field_cnt
- first_nonattr
- n_optionals
;
4949 int expected_max
= field_cnt
- first_nonattr
;
4951 if ((p_td
.xer_bits
& USE_NIL
) && get_at(field_cnt
-1)->ispresent()) {
4952 // The special case when USE_ORDER refers to the fields of a field,
4954 const Base_Type
*last_optional
= get_at(field_cnt
-1);
4955 const Base_Type
* inner
= last_optional
->get_opt_value();
4956 // it absolutely, positively has to be (derived from) Record_Type
4957 ordered
= static_cast<const Record_Type
*>(inner
);
4958 useorder_base
= ordered
->get_xer_num_attr();
4959 begin
= useorder_base
;
4960 end
= ordered
->get_count();
4962 expected_min
= expected_max
= ordered
->get_count();
4965 if (to_send
> expected_max
4966 ||to_send
< expected_min
) {
4967 ec_1
.set_msg("%s': ", fld_name(uo_index
));
4968 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_CONSTRAINT
,
4969 "Wrong number of USE-ORDER %d, must be %d..%d", to_send
, expected_min
, expected_max
);
4970 early_to_bed
= TRUE
; // don't bother sending anything
4972 else { // check no duplicates
4973 int *seen
= new int [to_send
];
4975 for (int ei
= 0; ei
< to_send
; ++ei
) {
4976 const Base_Type
*uoe
= use_order
->get_at(ei
);
4977 const Enum_Type
*enm
= static_cast<const Enum_Type
*>(uoe
);
4978 int val
= enm
->as_int();
4979 for (int x
= 0; x
< num_seen
; ++x
) {
4980 if (val
== seen
[x
]) { // complain
4981 ec_1
.set_msg("%s': ", fld_name(uo_index
));
4982 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_CONSTRAINT
,
4983 "Duplicate value for USE-ORDER");
4984 early_to_bed
= TRUE
; // don't bother sending anything
4988 seen
[num_seen
++] = val
;
4992 // If the number is right and there are no duplicates, then carry on
4994 } // endif(USE_ORDER)
4996 // Then, all the non-attributes. Structuring the code like this depends on
4997 // all attributes appearing before all non-attributes (excluding
4998 // pseudo-members for USE-ORDER, etc.)
5000 // This loop handles both the normal case (no USE_ORDER) when i indexes
5001 // fields of this record; and the USE_ORDER case (with or without USE-NIL).
5003 // early_to_bed can only be true if exer is true (transitive through nil_attribute)
5004 if (!early_to_bed
) {
5005 embed_values_enc_struct_t
* emb_val
= 0;
5006 if (exer
&& (p_td
.xer_bits
& EMBED_VALUES
) && embed_values
->size_of() > 1) {
5007 emb_val
= new embed_values_enc_struct_t
;
5008 emb_val
->embval_array
= embed_values
;
5009 emb_val
->embval_index
= 1;
5010 emb_val
->embval_err
= ed0
;
5011 emb_val
->embval_err_val_idx
= embed_values_val_idx
;
5012 emb_val
->embval_err_descr_idx
= embed_values_descr_idx
;
5015 for ( i
= begin
; i
< end
; ++i
) {
5017 const Base_Type
*uoe
= 0; // "useOrder enum"
5018 const Enum_Type
*enm
= 0; // the enum value selecting the field
5020 // "actual" index, may be perturbed by USE-ORDER.
5021 // We use this value to index the appropriate record.
5024 const Erroneous_values_t
* ev
= NULL
;
5025 const Erroneous_descriptor_t
* ed
= NULL
;
5026 if (exer
&& use_order
) {
5027 // If USE-ORDER is in effect, it introduces a level of indirection
5028 // into the indexing of fields: "i" is used to select an element
5029 // of the use_order member (an enum), whose value is used to select
5030 // the field being encoded.
5031 uoe
= use_order
->get_at(i
- begin
);
5032 enm
= static_cast<const Enum_Type
*>(uoe
);
5033 ai
= enm
->as_int() + useorder_base
;
5035 // Because it is not guaranteed that ai will increase monotonically,
5036 // we can't use next_field_...().
5037 ev
= p_err_descr
->get_field_err_values(ai
);
5038 ed
= p_err_descr
->get_field_emb_descr (ai
);
5040 else { // not USE-ORDER, sequential access
5041 ev
= p_err_descr
->next_field_err_values(ai
, values_idx
);
5042 ed
= p_err_descr
->next_field_emb_descr (ai
, edescr_idx
);
5044 ec_1
.set_msg("%s': ", ordered
->fld_name(ai
)); // non-attr
5046 if (ai
< p_err_descr
->omit_before
) continue;
5048 // omit_after value -1 becomes "very big".
5049 if ((unsigned int)ai
> (unsigned int)p_err_descr
->omit_after
) continue;
5050 // We can't skip all fields with break, because the next ai may be lower
5053 sub_len
+= ordered
->encode_field(ai
, ev
, ed
, p_buf
,
5054 // Pass USE-NIL to the last field (except when USE-ORDER is also in effect,
5055 // because the tag-stripping effect of USE-NIL has been achieved
5056 // by encoding the sub-fields directly).
5057 flavor
| ((exer
&& !use_order
&& (i
== field_cnt
-1)) ? (p_td
.xer_bits
& USE_NIL
) : 0),
5058 indent
+ !omit_tag
, emb_val
);
5060 // Now the next embed-values string (NOT affected by USE-ORDER!)
5061 if (exer
&& (p_td
.xer_bits
& EMBED_VALUES
) && 0 != emb_val
&&
5062 emb_val
->embval_index
< embed_values
->size_of()) {
5063 const Erroneous_values_t
* ev0_i
= NULL
;
5064 const Erroneous_descriptor_t
* ed0_i
= NULL
;
5066 ev0_i
= ed0
->next_field_err_values(emb_val
->embval_index
, emb_val
->embval_err_val_idx
);
5067 ed0_i
= ed0
->next_field_emb_descr (emb_val
->embval_index
, emb_val
->embval_err_descr_idx
);
5069 embed_values
->encode_element(emb_val
->embval_index
, UNIVERSAL_CHARSTRING_xer_
,
5070 ev0_i
, ed0_i
, p_buf
, flavor
| EMBED_VALUES
, indent
+ !omit_tag
, 0);
5071 ++emb_val
->embval_index
;
5075 if (emb_val
->embval_index
< embed_values
->size_of()) {
5076 ec_1
.set_msg("%s': ", fld_name(0));
5077 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_CONSTRAINT
,
5078 "Too many EMBED-VALUEs specified: %d (expected %d or less)",
5079 embed_values
->size_of(), emb_val
->embval_index
);
5083 } // if (!early_to_bed)
5088 if (sub_len
) { // something was written, now an end tag
5089 if (indenting
&& !(exer
&& (p_td
.xer_bits
& (HAS_1UNTAGGED
| USE_QNAME
))))
5090 // The tags of the last optional member involved with USE_NIL
5091 // have been removed. If it was a simple type, the content was probably
5092 // written on a single line without anything resembling a close tag.
5093 // Do not indent our end tag in this case.
5094 switch ((int)(exer
&& (p_td
.xer_bits
& USE_NIL
))) {
5096 const unsigned char *buf_end
= p_buf
.get_data() + (p_buf
.get_len()-1);
5097 if (buf_end
[-1] != '>' || *buf_end
!= '\n') break;
5098 // If it does not look like an end tag, skip the indenting,
5099 // else fall through.
5102 do_indent(p_buf
, indent
);
5107 if (exer
) write_ns_prefix(p_td
, p_buf
);
5108 p_buf
.put_s((size_t)p_td
.namelens
[exer
]-!indenting
, (cbyte
*)p_td
.names
[exer
]);
5110 else { // need to generate an empty element tag
5111 p_buf
.increase_length(-start_tag_len
); // decrease length
5112 p_buf
.put_s((size_t)2+indenting
, (cbyte
*)"/>\n");
5116 return (int)p_buf
.get_len() - encoded_length
;
5119 int Record_Type::XER_decode(const XERdescriptor_t
& p_td
, XmlReaderWrap
& reader
,
5120 unsigned int flavor
, unsigned int flavor2
, embed_values_dec_struct_t
*)
5122 int exer
= is_exer(flavor
);
5124 int depth
=-1; // depth of the start tag
5125 int xerbits
= p_td
.xer_bits
;
5126 if (flavor
& XER_TOPLEVEL
) xerbits
&= ~UNTAGGED
;
5127 const boolean own_tag
= !(exer
5128 && ( (xerbits
& (ANY_ELEMENT
| UNTAGGED
| XER_ATTRIBUTE
))
5129 || (flavor
& (USE_NIL
| USE_TYPE_ATTR
))));
5130 boolean tag_closed
= (flavor
& PARENT_CLOSED
) != 0;
5131 // If the parent has USE-TYPE, our ATTRIBUTE members can be found
5132 // in the parent's tag (the reader is sitting on it).
5133 const boolean parent_tag
= exer
&& ((flavor
& USE_TYPE_ATTR
) || (flavor2
& USE_NIL_PARENT_TAG
));
5135 // Filter out flags passed by our parent. These are not for the fields.
5136 flavor
&= XER_MASK
; // also removes XER_TOPLEVEL
5137 flavor2
= XER_NONE
; // Remove only bit: USE_NIL_PARENT_TAG (for now)
5139 const int field_cnt
= get_count();
5140 const int num_attributes
= get_xer_num_attr();
5142 // The index of potential "order" field, regardless of whether USE_ORDER
5143 // is in use or not.
5144 const int uo_index
= ((p_td
.xer_bits
& EMBED_VALUES
) !=0);
5146 // The first "non-special" field (skipping the USE-ORDER and EMBED-VALUES
5147 // fields); normal processing start at this field.
5148 const int start_at
= uo_index
+ ((p_td
.xer_bits
& USE_ORDER
) != 0);
5149 const int first_nonattr
= start_at
+ num_attributes
;
5151 // The index of the ANY-ATTRIBUTES member, if any
5153 for (int k
= 0; k
< first_nonattr
; ++k
) {
5154 if (xer_descr(k
)->xer_bits
& ANY_ATTRIBUTES
) {
5156 if (!get_at(aa_index
)->is_optional()) {
5157 static_cast<Record_Of_Type
*>(get_at(aa_index
))->set_size(0);
5159 break; // there can be only one, 18.2.2
5163 if (own_tag
) for (success
=reader
.Ok(); success
==1; success
=reader
.Read()) {
5164 type
= reader
.NodeType();
5165 if (type
==XML_READER_TYPE_ELEMENT
) {
5166 verify_name(reader
, p_td
, exer
);
5167 depth
= reader
.Depth();
5168 tag_closed
= reader
.IsEmptyElement();
5175 if (exer
&& (p_td
.xer_bits
& USE_QNAME
)) { // QName trumps everything !
5176 // If element, it looks like this:
5177 // <name xmlns:b0="http://www.furniture.com">b0:table</name>
5178 // If attribute, it looks like this:
5181 if (p_td
.xer_bits
& XER_ATTRIBUTE
) success
= 1; // do nothing
5182 else for (success
= reader
.Read(); success
== 1; success
= reader
.Read()) {
5183 type
= reader
.NodeType();
5184 if (type
== XML_READER_TYPE_TEXT
) break;
5188 xmlChar
*val
= reader
.NewValue();
5189 xmlChar
*npfx
= (xmlChar
*)strchr((char*)val
, ':');
5192 *npfx
++ = '\0'; // cut the string into two
5200 xmlChar
*nsu
= reader
.LookupNamespace(pfx
);
5202 OPTIONAL
<UNIVERSAL_CHARSTRING
> *q_prefix2
=
5203 static_cast<OPTIONAL
<UNIVERSAL_CHARSTRING
>*>(get_at(0));
5204 if (nsu
) *q_prefix2
= (const char*)nsu
;
5205 else q_prefix2
->set_to_omit(); // public in RT2 only
5207 UNIVERSAL_CHARSTRING
*q_name2
= static_cast<UNIVERSAL_CHARSTRING
*>(get_at(1));
5208 *q_name2
= (const char*)npfx
;
5214 else { // not use-qname
5215 TTCN_EncDec_ErrorContext
ec_0("Component '");
5216 TTCN_EncDec_ErrorContext ec_1
;
5217 boolean usenil_attribute
= FALSE
; // true if found and said yes
5218 // If nillable and the nillable field is a record type, that has attributes
5219 // then it will become true, and skips the processing of the fields after
5220 boolean already_processed
= FALSE
;
5222 if (!reader
.IsEmptyElement()) reader
.Read();
5223 // First, the (would-be) attributes (unaffected by USE-ORDER)
5224 for (i
= 0; i
< first_nonattr
; i
++) {
5225 ec_1
.set_msg("%s': ", fld_name(i
));
5226 get_at(i
)->XER_decode(*xer_descr(i
), reader
, flavor
, flavor2
, 0);
5229 else if (own_tag
|| parent_tag
) { // EXER and not UNTAGGED: do attributes
5230 // Prepare for lack of attributes.
5231 // Fields with defaultForEmpty get the D-F-E value, optional get omit.
5232 for (i
= start_at
; i
< first_nonattr
; i
++) {
5233 Base_Type
&fld
= *get_at(i
);
5234 const XERdescriptor_t
& xd
= *xer_descr(i
);
5236 if (fld
.is_optional()) {
5237 fld
.set_to_present();
5238 fld
.get_opt_value()->set_value(xd
.dfeValue
);
5240 else fld
.set_value(xd
.dfeValue
);
5242 else if (fld
.is_optional()) fld
.set_to_omit();
5245 int num_aa
= 0; // index into the ANY-ATTRIBUTE member
5247 const namespace_t
*control_ns
= 0;
5248 if (parent_tag
|| (p_td
.xer_bits
& USE_NIL
)) {
5249 // xsi:type or xsi:nil
5250 control_ns
= p_td
.my_module
->get_controlns();
5253 /* * * * * * * * * Attributes * * * * * * * * * * * * * */
5254 if(parent_tag
&& reader
.NodeType() == XML_READER_TYPE_ATTRIBUTE
) {
5255 success
= reader
.Ok();
5257 success
= reader
.MoveToFirstAttribute();
5260 success
== 1 && reader
.NodeType() == XML_READER_TYPE_ATTRIBUTE
;
5261 success
= reader
.AdvanceAttribute())
5263 if (reader
.IsNamespaceDecl()) {
5264 continue; // namespace declarations are handled for us by libxml2
5267 const char *attr_name
= (const char*)reader
.LocalName();
5268 const char *ns_uri
= (const char*)reader
.NamespaceUri();
5269 int field_index
= get_index_byname(attr_name
, ns_uri
);
5270 if (field_index
!= -1) {
5271 // There is a field. Let it decode the attribute.
5272 ec_1
.set_msg("%s': ", fld_name(field_index
));
5273 get_at(field_index
)->XER_decode(*xer_descr(field_index
), reader
, flavor
, flavor2
, 0);
5277 // Attribute not found. It could be the "nil" attribute
5278 if (p_td
.xer_bits
& USE_NIL
) {
5279 const char *prefix
= (const char*)reader
.Prefix();
5280 // prefix may be NULL, control_ns->px is never NULL or empty
5281 if (prefix
&& !strcmp(prefix
, control_ns
->px
)
5282 && !strcmp((const char*)reader
.LocalName(), "nil"))
5283 { // It is the "nil" attribute
5284 const char *value
= (const char*)reader
.Value();
5286 if (!strcmp(value
, "1") || !strcmp(value
, "true")) {
5287 // The field affected by USE-NIL is always the last one
5288 get_at(field_cnt
-1)->set_to_omit();
5289 usenil_attribute
= TRUE
;
5294 } // it is the "nil" attribute
5295 // else, let the nillable field decode the next attributes, it is possible
5296 // that it belongs to him
5297 get_at(field_cnt
-1)->XER_decode(*xer_descr(field_cnt
-1), reader
, flavor
| USE_NIL
, flavor2
| USE_NIL_PARENT_TAG
, 0);
5298 already_processed
= TRUE
;
5300 } // type has USE-NIL
5303 const char *prefix
= (const char*)reader
.Prefix();
5304 // prefix may be NULL, control_ns->px is never NULL or empty
5305 if (prefix
&& !strcmp(prefix
, control_ns
->px
)
5306 && !strcmp((const char*)reader
.LocalName(), "type")) {
5307 continue; // xsi:type has been processed by the parent
5311 if (aa_index
>= 0) {
5312 ec_1
.set_msg("%s': ", fld_name(aa_index
));
5313 TTCN_EncDec_ErrorContext
ec_2("Attribute %d: ", num_aa
);
5314 // We have a component with ANY-ATTRIBUTE. It must be a record of
5315 // UNIVERSAL_CHARSTRING. Add the attribute to it.
5316 Record_Of_Type
*aa
= 0;
5317 if (get_at(aa_index
)->is_optional()) {
5319 get_at(aa_index
)->set_to_present();
5321 aa
= static_cast<Record_Of_Type
*>(get_at(aa_index
)->get_opt_value());
5324 aa
= static_cast<Record_Of_Type
*>(get_at(aa_index
));
5326 UNIVERSAL_CHARSTRING
*new_elem
= static_cast<UNIVERSAL_CHARSTRING
*>
5327 (aa
->get_at(num_aa
++));
5329 // Construct the AnyAttributeFormat (X.693amd1, 18.2.6)
5331 const xmlChar
*name
= reader
.LocalName();
5332 const xmlChar
*val
= reader
.Value();
5333 const xmlChar
*uri
= reader
.NamespaceUri();
5335 if (xer_descr(aa_index
)->xer_bits
& (ANY_FROM
| ANY_EXCEPT
)) {
5336 check_namespace_restrictions(*xer_descr(aa_index
), (const char*)uri
);
5338 // We don't care about reader.Prefix()
5339 // Using strlen to count UTF8 bytes, not characters
5340 aabuf
.put_s(uri
? strlen((const char*)uri
) : 0, uri
);
5341 if (uri
&& *uri
) aabuf
.put_c(' ');
5342 aabuf
.put_s(name
? strlen((const char*)name
) : 0, name
);
5345 aabuf
.put_s(val
? strlen((const char*)val
) : 0, val
);
5347 new_elem
->decode_utf8(aabuf
.get_len(), aabuf
.get_data());
5352 // Lastly check for the xsi:schemaLocation attribute, this does not
5353 // affect TTCN-3, but it shouldn't cause a DTE
5354 if (reader
.LocalName() && !strcmp((const char*)reader
.LocalName(), "schemaLocation")) {
5356 control_ns
= p_td
.my_module
->get_controlns();
5358 if (reader
.Prefix() && !strcmp((const char*)reader
.Prefix(), control_ns
->px
)) {
5363 // Nobody wanted the attribute. That is an error.
5364 ec_0
.set_msg(" "); ec_1
.set_msg(" ");
5365 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG
,
5366 "Unexpected attribute '%s', ns '%s'", attr_name
,
5367 ns_uri
? ns_uri
: "");
5370 // Now check that all mandatory attributes have been set
5371 for (i
= start_at
; i
< first_nonattr
; ++i
) {
5372 Base_Type
* fld
= get_at(i
);
5373 if (fld
->is_optional()) continue; // field is allowed to be unset
5374 if (!fld
->is_bound()) {
5375 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG
,
5376 "Missing attribute '%s'", this->fld_name(i
));
5380 i
= first_nonattr
; // finished with attributes
5381 // AdvanceAttribute did MoveToElement. Move into the content (if any),
5382 // except when the reader is already moved in(already_processed).
5383 if (!reader
.IsEmptyElement() && !already_processed
) reader
.Read();
5384 } // end if (own_tag)
5386 /* * * * * * * * Non-attributes (elements) * * * * * * * * * * * */
5387 embed_values_dec_struct_t
* emb_val
= 0;
5388 bool emb_val_optional
= false;
5389 if (exer
&& (p_td
.xer_bits
& EMBED_VALUES
)) {
5390 emb_val
= new embed_values_dec_struct_t
;
5391 emb_val
->embval_array
= dynamic_cast<Record_Of_Type
*>(get_at(0));
5392 if (NULL
== emb_val
->embval_array
) {
5393 OPTIONAL
<PreGenRecordOf::PREGEN__RECORD__OF__UNIVERSAL__CHARSTRING
>* embed_value
= static_cast<OPTIONAL
<PreGenRecordOf::PREGEN__RECORD__OF__UNIVERSAL__CHARSTRING
>*>(get_at(0));
5394 embed_value
->set_to_present();
5395 emb_val
->embval_array
= static_cast<Record_Of_Type
*>((*embed_value
).get_opt_value());
5396 emb_val_optional
= true;
5398 emb_val
->embval_array
->set_size(0);
5399 emb_val
->embval_index
= 0;
5402 if (exer
&& (p_td
.xer_bits
& USE_ORDER
)) {
5403 // Set all optional fields to omit because their respective XER_decode
5404 // will not be run (and will stay unbound) if the value is missing.
5405 int n_optionals
= 0;
5406 for (int B
= optional_count() - 1; B
>=+0; B
--) {
5407 int oi
= get_optional_indexes()[B
];
5408 if (oi
< first_nonattr
) break;
5409 get_at(oi
)->set_to_omit();
5413 Record_Of_Type
*use_order
= static_cast<Record_Of_Type
*>(get_at(uo_index
));
5414 // Initialize the use_order field to empty. Let it grow on demand.
5415 // (setting it to the minimum acceptable size may leave unbound elements
5416 // if the XML was incomplete).
5417 use_order
->set_size(0);
5419 // Nothing to order if there are no child elements
5421 Record_Type
*jumbled
= this; // the record affected by USE_ORDER
5422 int begin
= first_nonattr
;
5423 int end
= field_cnt
; // "one past"
5424 if (p_td
.xer_bits
& USE_NIL
) {
5425 Base_Type
*last_optional
= get_at(field_cnt
-1);
5426 if (!usenil_attribute
) { // exer known true
5427 last_optional
->set_to_present();
5428 jumbled
= static_cast<Record_Type
*>(last_optional
->get_opt_value());
5429 // We will operate on the members of last_optional,
5430 // effectively bypassing last_optional->XER_decode() itself.
5432 end
= jumbled
->get_count();
5433 ec_1
.set_msg("%s': ", fld_name(field_cnt
-1));
5436 if (num_attributes
> 0
5437 && first_nonattr
!= field_cnt
5438 && i
== first_nonattr
- 1) { // exer known true
5439 // If there were attributes and their processing just finished,
5440 // the reader is positioned on the start tag of the record.
5441 // Move ahead, unless there are no non-attribute fields.
5444 // Then, the non-attributes
5446 // The index runs over the members affected by USE-ORDER.
5447 // This is [first_nonattr,field_cnt) unless USE-NIL is involved,
5448 // in which case it's [0,optional_sequence::field_cnt)
5449 int *seen
= new int[end
-begin
];
5451 int last_any_elem
= begin
- 1;
5452 // The index of the latest embedded value can change outside of this function
5453 // (if the field is an untagged record of), in this case the next value should
5454 // be ignored, as it's already been handled by the record of
5455 int last_embval_index
= 0;
5456 bool early_exit
= false;
5457 for (i
= begin
; i
< end
; i
++) {
5458 for (success
= reader
.Ok(); success
== 1; success
= reader
.Read()) {
5459 type
= reader
.NodeType();
5460 if (0 != emb_val
&& reader
.NodeType()==XML_READER_TYPE_TEXT
) {
5461 UNIVERSAL_CHARSTRING
emb_ustr((const char*)reader
.Value());
5462 emb_val
->embval_array
->get_at(emb_val
->embval_index
)->set_value(&emb_ustr
);
5464 // The non-attribute components must not be UNTAGGED
5465 if (type
== XML_READER_TYPE_ELEMENT
) break;
5466 if (type
== XML_READER_TYPE_END_ELEMENT
) {
5472 if (last_embval_index
== emb_val
->embval_index
) {
5473 ++emb_val
->embval_index
;
5475 last_embval_index
= emb_val
->embval_index
;
5477 if (success
!= 1 || early_exit
) break;
5478 const char *name
= (const char *)reader
.LocalName();
5479 bool field_name_found
= false;
5480 // Find out which member it is.
5481 // FIXME some hashing should be implemented
5482 for (int k
= begin
; k
< end
; k
++) {
5483 if (!(jumbled
->xer_descr(k
)->xer_bits
& ANY_ELEMENT
) &&
5484 check_name(name
, *jumbled
->xer_descr(k
), 1)) {
5485 ec_1
.set_msg("%s': ", jumbled
->fld_name(k
));
5487 // Check for the same field being decoded twice.
5488 // We can't use the field's is_bound()/is_present(),
5489 // because the field may be bound on input, e.g. for
5490 // prototype(fast) or prototype(backtrack).
5491 int in_dex
= k
- begin
;
5492 for (int o
= 0; o
< num_seen
;++o
) {
5493 if (in_dex
== seen
[o
]) TTCN_EncDec_ErrorContext::error(
5494 TTCN_EncDec::ET_INVAL_MSG
, "Duplicate element");
5496 seen
[num_seen
++] = in_dex
;
5497 // Set the next use-order member.
5498 // Non-const get_at creates the object in the record-of.
5499 static_cast<Enum_Type
*>(use_order
->get_at(i
- begin
))
5501 Base_Type
*b
= jumbled
->get_at(k
);
5502 b
->XER_decode(*jumbled
->xer_descr(k
), reader
, flavor
, flavor2
, emb_val
);
5503 field_name_found
= true;
5507 if (!field_name_found
) {
5508 // Check the anyElement fields
5509 for (int k
= last_any_elem
+ 1; k
< end
; k
++) {
5510 if (jumbled
->xer_descr(k
)->xer_bits
& ANY_ELEMENT
) {
5511 ec_1
.set_msg("%s': ", jumbled
->fld_name(k
));
5513 // Check for the same field being decoded twice.
5514 // We can't use the field's is_bound()/is_present(),
5515 // because the field may be bound on input, e.g. for
5516 // prototype(fast) or prototype(backtrack).
5517 int in_dex
= k
- begin
;
5518 for (int o
= 0; o
< num_seen
;++o
) {
5519 if (in_dex
== seen
[o
]) TTCN_EncDec_ErrorContext::error(
5520 TTCN_EncDec::ET_INVAL_MSG
, "Duplicate element");
5522 seen
[num_seen
++] = in_dex
;
5523 // Set the next use-order member.
5524 // Non-const get_at creates the object in the record-of.
5525 static_cast<Enum_Type
*>(use_order
->get_at(i
- begin
))
5527 Base_Type
*b
= jumbled
->get_at(k
);
5528 b
->XER_decode(*jumbled
->xer_descr(k
), reader
, flavor
, flavor2
, emb_val
);
5530 field_name_found
= true;
5535 if (!field_name_found
) {
5536 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG
,
5537 "Bad XML tag '%s' instead of a valid field", name
);
5542 if (reader
.NodeType()==XML_READER_TYPE_TEXT
) {
5543 UNIVERSAL_CHARSTRING
emb_ustr((const char*)reader
.Value());
5544 emb_val
->embval_array
->get_at(emb_val
->embval_index
)->set_value(&emb_ustr
);
5546 if (last_embval_index
== emb_val
->embval_index
) {
5547 ++emb_val
->embval_index
;
5551 ec_1
.set_msg(" "); // no active component
5554 // Check that we collected the required number of children
5555 int num_collected
= use_order
->size_of();
5556 if (p_td
.xer_bits
& USE_NIL
) {
5557 int expected
= usenil_attribute
? 0 : jumbled
->get_count();
5558 if (num_collected
!= expected
) {
5559 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INCOMPL_MSG
,
5560 "Incorrect number of fields %d, expected %d",
5561 num_collected
, expected
);
5565 if (num_collected
< field_cnt
- first_nonattr
- n_optionals
5566 ||num_collected
> field_cnt
- first_nonattr
) {
5567 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INCOMPL_MSG
,
5568 "Wrong number of fields! size = %d, expected %d..%d",
5569 use_order
->size_of(), field_cnt
- first_nonattr
- n_optionals
,
5570 field_cnt
- first_nonattr
);
5573 } // not empty element
5575 else { // not USE-ORDER, simpler code
5576 if (usenil_attribute
) {
5577 reader
.MoveToElement(); // value absent, nothing more to do
5579 // The index of the latest embedded value can change outside of this function
5580 // (if the field is a untagged record of), in this case the next value should
5581 // be ignored, as it's already been handled by the record of
5582 // Omitted fields can also reset this value
5583 int last_embval_index
= 0;
5584 for (; i
<field_cnt
; i
++) {
5586 if (reader
.NodeType()==XML_READER_TYPE_TEXT
) {
5587 UNIVERSAL_CHARSTRING
emb_ustr((const char*)reader
.Value());
5588 emb_val
->embval_array
->get_at(emb_val
->embval_index
)->set_value(&emb_ustr
);
5590 if (last_embval_index
== emb_val
->embval_index
) {
5591 ++emb_val
->embval_index
;
5593 last_embval_index
= emb_val
->embval_index
;
5595 ec_1
.set_msg("%s': ", fld_name(i
));
5596 if (exer
&& i
==field_cnt
-1 && p_td
.dfeValue
&& reader
.IsEmptyElement()) {
5597 get_at(i
)->set_value(p_td
.dfeValue
);
5600 // In case the field is an optional anyElement -> check if it should be omitted
5601 bool optional_any_elem_check
= true;
5602 if (get_at(i
)->is_optional() && (xer_descr(i
)->xer_bits
& ANY_ELEMENT
)) {
5603 // The "anyElement" coding instruction can only be applied to a universal charstring field
5604 OPTIONAL
<UNIVERSAL_CHARSTRING
>* opt_field
= dynamic_cast<OPTIONAL
<UNIVERSAL_CHARSTRING
>*>(get_at(i
));
5606 const char* next_field_name
= NULL
;
5607 if (i
< field_cnt
- 1) {
5608 next_field_name
= fld_name(i
+ 1);
5610 optional_any_elem_check
= opt_field
->XER_check_any_elem(reader
, next_field_name
, tag_closed
);
5613 if (optional_any_elem_check
&& !already_processed
) {
5614 int new_flavor
= flavor
;
5615 if (i
== field_cnt
-1) new_flavor
|= (p_td
.xer_bits
& USE_NIL
);
5616 if (tag_closed
) new_flavor
|= PARENT_CLOSED
;
5618 get_at(i
)->XER_decode(*xer_descr(i
), reader
, new_flavor
, flavor2
, emb_val
);
5621 if (!get_at(i
)->is_present()) {
5622 // there was no new element, the last embedded value is for the next field
5623 // (or the end of the record if this is the last field)
5624 last_embval_index
= -1;
5628 if (reader
.NodeType()==XML_READER_TYPE_TEXT
) {
5629 UNIVERSAL_CHARSTRING
emb_ustr((const char*)reader
.Value());
5630 emb_val
->embval_array
->get_at(emb_val
->embval_index
)->set_value(&emb_ustr
);
5632 if (last_embval_index
== emb_val
->embval_index
) {
5633 ++emb_val
->embval_index
;
5640 bool all_unbound
= true;
5641 static const UNIVERSAL_CHARSTRING
emptystring(0, (const char*)NULL
);
5642 for (int j
= 0; j
< emb_val
->embval_index
; ++j
) {
5643 if (!emb_val
->embval_array
->get_at(j
)->is_bound()) {
5644 emb_val
->embval_array
->get_at(j
)->set_value(&emptystring
);
5645 }else if((static_cast<const UNIVERSAL_CHARSTRING
*>(emb_val
->embval_array
->get_at(j
)))->lengthof() !=0) {
5646 all_unbound
= false;
5649 if(emb_val_optional
&& all_unbound
){
5650 static_cast<OPTIONAL
<PreGenRecordOf::PREGEN__RECORD__OF__UNIVERSAL__CHARSTRING
>*>(get_at(0))->set_to_omit();
5653 } // if embed-values
5657 // Check if every non-optional field has been set
5658 for (i
= 0; i
< field_cnt
; ++i
) {
5659 if (!get_at(i
)->is_optional() && !get_at(i
)->is_bound()) {
5660 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INCOMPL_MSG
,
5661 "No data found for non-optional field '%s'", fld_name(i
));
5666 // We had our start tag. Then our fields did their thing.
5667 // Now we expect the end tag. And it better be our end tag!
5669 for (success
= reader
.Ok(); success
== 1; success
= reader
.Read()) {
5670 type
= reader
.NodeType();
5671 current_depth
= reader
.Depth();
5672 if (current_depth
> depth
) {
5673 if (XML_READER_TYPE_ELEMENT
== type
) {
5674 // We found a deeper start tag; it was not processed at all.
5675 // That is an error (maybe we should report error for all node types
5676 // except TEXT and WHITESPACE, not just ELEMENT).
5677 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TAG
,
5678 "Unprocessed XML tag `%s'", (const char *)reader
.Name());
5681 continue; // go past hoping that our end tag will arrive eventually
5683 else if (current_depth
== depth
) { // at our level
5684 if (XML_READER_TYPE_ELEMENT
== type
) {
5685 verify_name(reader
, p_td
, exer
);
5686 if (reader
.IsEmptyElement()) {
5687 // FIXME this shouldn't really be possible;
5688 // only an empty record should be encoded as an empty element,
5689 // but those are implemented by Empty_Record_Type, not Record_Type.
5690 reader
.Read(); // one last time
5694 // If we find an end tag at the right depth, it must be ours
5695 else if (XML_READER_TYPE_END_ELEMENT
== type
) {
5696 verify_end(reader
, p_td
, depth
, exer
);
5701 else { //current_depth < depth; something has gone horribly wrong
5702 break; // better quit before we do further damage
5703 // Don't report an error; every enclosing type would do so,
5704 // spewing the same message over and over.
5708 return 1; // decode successful
5711 int Record_Type::JSON_encode(const TTCN_Typedescriptor_t
& p_td
, JSON_Tokenizer
& p_tok
) const
5714 return JSON_encode_negtest(err_descr
, p_td
, p_tok
);
5718 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND
,
5719 "Encoding an unbound %s value.", is_set() ? "set" : "record");
5723 int enc_len
= p_tok
.put_next_token(JSON_TOKEN_OBJECT_START
, NULL
);
5725 int field_count
= get_count();
5726 for (int i
= 0; i
< field_count
; ++i
) {
5727 boolean metainfo_unbound
= NULL
!= fld_descr(i
)->json
&& fld_descr(i
)->json
->metainfo_unbound
;
5728 if ((NULL
!= fld_descr(i
)->json
&& fld_descr(i
)->json
->omit_as_null
) ||
5729 get_at(i
)->is_present() || metainfo_unbound
) {
5730 const char* field_name
= (NULL
!= fld_descr(i
)->json
&& NULL
!= fld_descr(i
)->json
->alias
) ?
5731 fld_descr(i
)->json
->alias
: fld_name(i
);
5732 enc_len
+= p_tok
.put_next_token(JSON_TOKEN_NAME
, field_name
);
5733 if (metainfo_unbound
&& !get_at(i
)->is_bound()) {
5734 enc_len
+= p_tok
.put_next_token(JSON_TOKEN_LITERAL_NULL
);
5735 char* metainfo_str
= mprintf("metainfo %s", field_name
);
5736 enc_len
+= p_tok
.put_next_token(JSON_TOKEN_NAME
, metainfo_str
);
5738 enc_len
+= p_tok
.put_next_token(JSON_TOKEN_STRING
, "\"unbound\"");
5741 enc_len
+= get_at(i
)->JSON_encode(*fld_descr(i
), p_tok
);
5746 enc_len
+= p_tok
.put_next_token(JSON_TOKEN_OBJECT_END
, NULL
);
5750 int Record_Type::JSON_encode_negtest(const Erroneous_descriptor_t
* p_err_descr
,
5751 const TTCN_Typedescriptor_t
& p_td
,
5752 JSON_Tokenizer
& p_tok
) const
5755 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND
,
5756 "Encoding an unbound %s value.", is_set() ? "set" : "record");
5760 int enc_len
= p_tok
.put_next_token(JSON_TOKEN_OBJECT_START
, NULL
);
5765 int field_count
= get_count();
5766 for (int i
= 0; i
< field_count
; ++i
) {
5767 if (-1 != p_err_descr
->omit_before
&& p_err_descr
->omit_before
> i
) {
5771 const Erroneous_values_t
* err_vals
= p_err_descr
->next_field_err_values(i
, values_idx
);
5772 const Erroneous_descriptor_t
* emb_descr
= p_err_descr
->next_field_emb_descr(i
, edescr_idx
);
5774 if (NULL
!= err_vals
&& NULL
!= err_vals
->before
) {
5775 if (NULL
== err_vals
->before
->errval
) {
5776 TTCN_error("internal error: erroneous before value missing");
5778 if (err_vals
->before
->raw
) {
5779 enc_len
+= err_vals
->before
->errval
->JSON_encode_negtest_raw(p_tok
);
5781 if (NULL
== err_vals
->before
->type_descr
) {
5782 TTCN_error("internal error: erroneous before typedescriptor missing");
5784 // it's an extra field, so use the erroneous type's name as the field name
5785 enc_len
+= p_tok
.put_next_token(JSON_TOKEN_NAME
, err_vals
->before
->type_descr
->name
);
5786 enc_len
+= err_vals
->before
->errval
->JSON_encode(*(err_vals
->before
->type_descr
), p_tok
);
5790 const char* field_name
= (NULL
!= fld_descr(i
)->json
&& NULL
!= fld_descr(i
)->json
->alias
) ?
5791 fld_descr(i
)->json
->alias
: fld_name(i
);
5792 if (NULL
!= err_vals
&& NULL
!= err_vals
->value
) {
5793 if (NULL
!= err_vals
->value
->errval
) {
5794 if (err_vals
->value
->raw
) {
5795 enc_len
+= err_vals
->value
->errval
->JSON_encode_negtest_raw(p_tok
);
5797 if (NULL
== err_vals
->value
->type_descr
) {
5798 TTCN_error("internal error: erroneous before typedescriptor missing");
5800 // only replace the field's value, keep the field name
5801 enc_len
+= p_tok
.put_next_token(JSON_TOKEN_NAME
, field_name
);
5802 enc_len
+= err_vals
->value
->errval
->JSON_encode(*(err_vals
->value
->type_descr
), p_tok
);
5806 boolean metainfo_unbound
= NULL
!= fld_descr(i
)->json
&& fld_descr(i
)->json
->metainfo_unbound
;
5807 if ((NULL
!= fld_descr(i
)->json
&& fld_descr(i
)->json
->omit_as_null
) ||
5808 get_at(i
)->is_present() || metainfo_unbound
) {
5809 enc_len
+= p_tok
.put_next_token(JSON_TOKEN_NAME
, field_name
);
5810 if (metainfo_unbound
&& !get_at(i
)->is_bound()) {
5811 enc_len
+= p_tok
.put_next_token(JSON_TOKEN_LITERAL_NULL
);
5812 char* metainfo_str
= mprintf("metainfo %s", field_name
);
5813 enc_len
+= p_tok
.put_next_token(JSON_TOKEN_NAME
, metainfo_str
);
5815 enc_len
+= p_tok
.put_next_token(JSON_TOKEN_STRING
, "\"unbound\"");
5817 else if (NULL
!= emb_descr
) {
5818 enc_len
+= get_at(i
)->JSON_encode_negtest(emb_descr
, *fld_descr(i
), p_tok
);
5820 enc_len
+= get_at(i
)->JSON_encode(*fld_descr(i
), p_tok
);
5825 if (NULL
!= err_vals
&& NULL
!= err_vals
->after
) {
5826 if (NULL
== err_vals
->after
->errval
) {
5827 TTCN_error("internal error: erroneous after value missing");
5829 if (err_vals
->after
->raw
) {
5830 enc_len
+= err_vals
->after
->errval
->JSON_encode_negtest_raw(p_tok
);
5832 if (NULL
== err_vals
->after
->type_descr
) {
5833 TTCN_error("internal error: erroneous before typedescriptor missing");
5835 // it's an extra field, so use the erroneous type's name as the field name
5836 enc_len
+= p_tok
.put_next_token(JSON_TOKEN_NAME
, err_vals
->after
->type_descr
->name
);
5837 enc_len
+= err_vals
->after
->errval
->JSON_encode(*(err_vals
->after
->type_descr
), p_tok
);
5841 if (-1 != p_err_descr
->omit_after
&& p_err_descr
->omit_after
<= i
) {
5846 enc_len
+= p_tok
.put_next_token(JSON_TOKEN_OBJECT_END
, NULL
);
5850 int Record_Type::JSON_decode(const TTCN_Typedescriptor_t
& p_td
, JSON_Tokenizer
& p_tok
, boolean p_silent
)
5852 json_token_t token
= JSON_TOKEN_NONE
;
5853 int dec_len
= p_tok
.get_next_token(&token
, NULL
, NULL
);
5854 if (JSON_TOKEN_ERROR
== token
) {
5855 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG
, JSON_DEC_BAD_TOKEN_ERROR
, "");
5856 return JSON_ERROR_FATAL
;
5858 else if (JSON_TOKEN_OBJECT_START
!= token
) {
5859 return JSON_ERROR_INVALID_TOKEN
;
5862 const int field_count
= get_count();
5864 // initialize meta info states
5865 int* metainfo
= new int[field_count
];
5866 boolean
* field_found
= new boolean
[field_count
];
5867 for (int i
= 0; i
< field_count
; ++i
) {
5868 field_found
[i
] = FALSE
;
5869 metainfo
[i
] = (NULL
!= fld_descr(i
)->json
&& fld_descr(i
)->json
->metainfo_unbound
) ?
5870 JSON_METAINFO_NONE
: JSON_METAINFO_NOT_APPLICABLE
;
5874 // Read name - value token pairs until we reach some other token
5876 size_t name_len
= 0;
5877 size_t buf_pos
= p_tok
.get_buf_pos();
5878 dec_len
+= p_tok
.get_next_token(&token
, &name
, &name_len
);
5879 if (JSON_TOKEN_ERROR
== token
) {
5880 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG
, JSON_DEC_BAD_TOKEN_ERROR
, "");
5881 return JSON_ERROR_FATAL
;
5883 else if (JSON_TOKEN_NAME
!= token
) {
5884 // undo the last action on the buffer
5885 p_tok
.set_buf_pos(buf_pos
);
5889 // check for meta info
5890 boolean is_metainfo
= FALSE
;
5891 if (name_len
> 9 && 0 == strncmp(name
, "metainfo ", 9)) {
5899 for (field_idx
= 0; field_idx
< field_count
; ++field_idx
) {
5900 const char* expected_name
= 0;
5901 if (NULL
!= fld_descr(field_idx
)->json
&& NULL
!= fld_descr(field_idx
)->json
->alias
) {
5902 expected_name
= fld_descr(field_idx
)->json
->alias
;
5904 expected_name
= fld_name(field_idx
);
5906 if (strlen(expected_name
) == name_len
&&
5907 0 == strncmp(expected_name
, name
, name_len
)) {
5908 field_found
[field_idx
] = TRUE
;
5912 if (field_count
== field_idx
) {
5913 // invalid field name
5914 char* name2
= mcopystrn(name
, name_len
);
5915 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG
, is_metainfo
?
5916 JSON_DEC_METAINFO_NAME_ERROR
: JSON_DEC_INVALID_NAME_ERROR
, name2
);
5917 // if this is set to a warning, skip the value of the field
5918 dec_len
+= p_tok
.get_next_token(&token
, NULL
, NULL
);
5919 if (JSON_TOKEN_NUMBER
!= token
&& JSON_TOKEN_STRING
!= token
&&
5920 JSON_TOKEN_LITERAL_TRUE
!= token
&& JSON_TOKEN_LITERAL_FALSE
!= token
&&
5921 JSON_TOKEN_LITERAL_NULL
!= token
) {
5922 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG
, JSON_DEC_FIELD_TOKEN_ERROR
, name2
);
5924 return JSON_ERROR_FATAL
;
5931 if (JSON_METAINFO_NOT_APPLICABLE
!= metainfo
[field_idx
]) {
5933 char* info_value
= 0;
5934 size_t info_len
= 0;
5935 dec_len
+= p_tok
.get_next_token(&token
, &info_value
, &info_len
);
5936 if (JSON_TOKEN_STRING
== token
&& 9 == info_len
&&
5937 0 == strncmp(info_value
, "\"unbound\"", 9)) {
5938 metainfo
[field_idx
] = JSON_METAINFO_UNBOUND
;
5941 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG
, JSON_DEC_METAINFO_VALUE_ERROR
,
5942 fld_name(field_idx
));
5943 return JSON_ERROR_FATAL
;
5947 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG
, JSON_DEC_METAINFO_NOT_APPLICABLE
,
5948 fld_name(field_idx
));
5949 return JSON_ERROR_FATAL
;
5953 buf_pos
= p_tok
.get_buf_pos();
5954 int ret_val
= get_at(field_idx
)->JSON_decode(*fld_descr(field_idx
), p_tok
, p_silent
);
5956 if (JSON_ERROR_INVALID_TOKEN
== ret_val
) {
5957 // undo the last action on the buffer, check if the invalid token was a null token
5958 p_tok
.set_buf_pos(buf_pos
);
5959 p_tok
.get_next_token(&token
, NULL
, NULL
);
5960 if (JSON_TOKEN_LITERAL_NULL
== token
) {
5961 if (JSON_METAINFO_NONE
== metainfo
[field_idx
]) {
5962 // delay reporting an error for now, there might be meta info later
5963 metainfo
[field_idx
] = JSON_METAINFO_NEEDED
;
5966 else if (JSON_METAINFO_UNBOUND
== metainfo
[field_idx
]) {
5967 // meta info already found
5971 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG
, JSON_DEC_FIELD_TOKEN_ERROR
, fld_name(field_idx
));
5973 return JSON_ERROR_FATAL
;
5980 dec_len
+= p_tok
.get_next_token(&token
, NULL
, NULL
);
5981 if (JSON_TOKEN_OBJECT_END
!= token
) {
5982 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG
, JSON_DEC_OBJECT_END_TOKEN_ERROR
, "");
5983 return JSON_ERROR_FATAL
;
5986 // Check if every field has been set and handle meta info
5987 for (int field_idx
= 0; field_idx
< field_count
; ++field_idx
) {
5988 Base_Type
* field
= get_at(field_idx
);
5989 if (JSON_METAINFO_UNBOUND
== metainfo
[field_idx
]) {
5992 else if (JSON_METAINFO_NEEDED
== metainfo
[field_idx
]) {
5993 // no meta info was found for this field, report the delayed error
5994 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG
, JSON_DEC_FIELD_TOKEN_ERROR
, fld_name(field_idx
));
5996 else if (!field_found
[field_idx
]) {
5997 if (NULL
!= fld_descr(field_idx
)->json
&& NULL
!= fld_descr(field_idx
)->json
->default_value
) {
5998 get_at(field_idx
)->JSON_decode(*fld_descr(field_idx
), DUMMY_BUFFER
, p_silent
);
6000 else if (field
->is_optional()) {
6001 field
->set_to_omit();
6003 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG
, JSON_DEC_MISSING_FIELD_ERROR
, fld_name(field_idx
));
6004 return JSON_ERROR_FATAL
;
6014 ////////////////////////////////////////////////////////////////////////////////
6016 Empty_Record_Type::Empty_Record_Type(): bound_flag(FALSE
)
6020 Empty_Record_Type::Empty_Record_Type(const Empty_Record_Type
& other_value
)
6021 : Base_Type(other_value
), bound_flag(other_value
.bound_flag
)
6023 if (!other_value
.bound_flag
)
6024 TTCN_error("Copying an unbound value of type %s.",
6025 other_value
.get_descriptor()->name
);
6028 boolean
Empty_Record_Type::operator==(null_type
) const
6031 TTCN_error("Comparison of an unbound value of type %s.",
6032 get_descriptor()->name
);
6036 void Empty_Record_Type::log() const
6038 if (bound_flag
) TTCN_Logger::log_event_str("{ }");
6039 else TTCN_Logger::log_event_unbound();
6042 void Empty_Record_Type::set_param(Module_Param
& param
) {
6043 param
.basic_check(Module_Param::BC_VALUE
, "empty record/set value (i.e. { })");
6044 Module_Param_Ptr mp
= ¶m
;
6045 if (param
.get_type() == Module_Param::MP_Reference
) {
6046 mp
= param
.get_referenced_param();
6048 if (mp
->get_type()!=Module_Param::MP_Value_List
|| mp
->get_size()>0) {
6049 param
.type_error("empty record/set value (i.e. { })", get_descriptor()->name
);
6054 Module_Param
* Empty_Record_Type::get_param(Module_Param_Name
& /* param_name */) const
6057 return new Module_Param_Unbound();
6059 return new Module_Param_Value_List();
6062 void Empty_Record_Type::encode_text(Text_Buf
& /*text_buf*/) const
6065 TTCN_error("Text encoder: Encoding an unbound value of type %s.",
6066 get_descriptor()->name
);
6069 void Empty_Record_Type::decode_text(Text_Buf
& /*text_buf*/)
6074 boolean
Empty_Record_Type::is_equal(const Base_Type
* other_value
) const
6076 const Empty_Record_Type
* r2
= static_cast<const Empty_Record_Type
*>(other_value
);
6077 if ((bound_flag
&& r2
->bound_flag
) || (!bound_flag
&& !r2
->bound_flag
))
6079 if (!bound_flag
|| !r2
->bound_flag
)
6080 TTCN_error("Comparison of an unbound value of type %s.", get_descriptor()->name
);
6084 void Empty_Record_Type::set_value(const Base_Type
* other_value
)
6086 if (!static_cast<const Empty_Record_Type
*>(other_value
)->is_bound())
6087 TTCN_error("Assignment of an unbound value of type %s.",
6088 other_value
->get_descriptor()->name
);
6092 void Empty_Record_Type::encode(const TTCN_Typedescriptor_t
& p_td
,
6093 TTCN_Buffer
& p_buf
, TTCN_EncDec::coding_t p_coding
, ...) const
6096 va_start(pvar
, p_coding
);
6098 case TTCN_EncDec::CT_BER
: {
6099 TTCN_EncDec_ErrorContext
ec("While BER-encoding type '%s': ", p_td
.name
);
6100 unsigned BER_coding
=va_arg(pvar
, unsigned);
6101 BER_encode_chk_coding(BER_coding
);
6102 ASN_BER_TLV_t
*tlv
=BER_encode_TLV(p_td
, BER_coding
);
6103 tlv
->put_in_buffer(p_buf
);
6104 ASN_BER_TLV_t::destruct(tlv
);
6106 case TTCN_EncDec::CT_RAW
: {
6107 TTCN_EncDec_ErrorContext
ec("While RAW-encoding type '%s': ", p_td
.name
);
6108 if(!p_td
.raw
) TTCN_EncDec_ErrorContext::error_internal
6109 ("No RAW descriptor available for type '%s'.", p_td
.name
);
6113 RAW_enc_tree
root(FALSE
, NULL
, &rp
, 1, p_td
.raw
);
6114 RAW_encode(p_td
, root
);
6115 root
.put_to_buf(p_buf
);
6117 case TTCN_EncDec::CT_TEXT
: {
6118 TTCN_EncDec_ErrorContext
ec("While TEXT-encoding type '%s': ", p_td
.name
);
6119 if(!p_td
.text
) TTCN_EncDec_ErrorContext::error_internal
6120 ("No TEXT descriptor available for type '%s'.", p_td
.name
);
6121 TEXT_encode(p_td
,p_buf
);
6123 case TTCN_EncDec::CT_XER
: {
6124 TTCN_EncDec_ErrorContext
ec("While XER-encoding type '%s': ", p_td
.name
);
6125 unsigned XER_coding
=va_arg(pvar
, unsigned);
6126 XER_encode(*(p_td
.xer
),p_buf
, XER_coding
, 0, 0);
6129 case TTCN_EncDec::CT_JSON
: {
6130 TTCN_EncDec_ErrorContext
ec("While JSON-encoding type '%s': ", p_td
.name
);
6131 if(!p_td
.json
) TTCN_EncDec_ErrorContext::error_internal
6132 ("No JSON descriptor available for type '%s'.", p_td
.name
);
6133 JSON_Tokenizer
tok(va_arg(pvar
, int) != 0);
6134 JSON_encode(p_td
, tok
);
6135 p_buf
.put_s(tok
.get_buffer_length(), (const unsigned char*)tok
.get_buffer());
6138 TTCN_error("Unknown coding method requested to encode type '%s'", p_td
.name
);
6143 void Empty_Record_Type::decode(const TTCN_Typedescriptor_t
& p_td
,
6144 TTCN_Buffer
& p_buf
, TTCN_EncDec::coding_t p_coding
, ...)
6147 va_start(pvar
, p_coding
);
6149 case TTCN_EncDec::CT_BER
: {
6150 TTCN_EncDec_ErrorContext
ec("While BER-decoding type '%s': ", p_td
.name
);
6151 unsigned L_form
=va_arg(pvar
, unsigned);
6153 BER_decode_str2TLV(p_buf
, tlv
, L_form
);
6154 BER_decode_TLV(p_td
, tlv
, L_form
);
6155 if(tlv
.isComplete
) p_buf
.increase_pos(tlv
.get_len());
6157 case TTCN_EncDec::CT_RAW
: {
6158 TTCN_EncDec_ErrorContext
ec("While RAW-decoding type '%s': ", p_td
.name
);
6160 TTCN_EncDec_ErrorContext::error_internal
6161 ("No RAW descriptor available for type '%s'.", p_td
.name
);
6163 switch(p_td
.raw
->top_bit_order
) {
6171 if(RAW_decode(p_td
, p_buf
, p_buf
.get_len()*8, order
)<0)
6172 ec
.error(TTCN_EncDec::ET_INCOMPL_MSG
,
6173 "Can not decode type '%s', because invalid or incomplete"
6174 " message was received", p_td
.name
);
6176 case TTCN_EncDec::CT_TEXT
: {
6177 Limit_Token_List limit
;
6178 TTCN_EncDec_ErrorContext
ec("While TEXT-decoding type '%s': ", p_td
.name
);
6179 if(!p_td
.text
) TTCN_EncDec_ErrorContext::error_internal
6180 ("No TEXT descriptor available for type '%s'.", p_td
.name
);
6181 const unsigned char *b
=p_buf
.get_data();
6182 if(b
[p_buf
.get_len()-1]!='\0'){
6183 p_buf
.set_pos(p_buf
.get_len());
6184 p_buf
.put_zero(8,ORDER_LSB
);
6187 if(TEXT_decode(p_td
,p_buf
,limit
)<0)
6188 ec
.error(TTCN_EncDec::ET_INCOMPL_MSG
,
6189 "Can not decode type '%s', because invalid or incomplete"
6190 " message was received", p_td
.name
);
6192 case TTCN_EncDec::CT_XER
: {
6193 TTCN_EncDec_ErrorContext
ec("While XER-decoding type '%s': ", p_td
.name
);
6194 unsigned XER_coding
=va_arg(pvar
, unsigned);
6195 XmlReaderWrap
reader(p_buf
);
6196 for (int success
=reader
.Read(); success
==1; success
=reader
.Read()) {
6197 if (reader
.NodeType() == XML_READER_TYPE_ELEMENT
) break;
6199 XER_decode(*(p_td
.xer
), reader
, XER_coding
| XER_TOPLEVEL
, XER_NONE
, 0);
6200 size_t bytes
= reader
.ByteConsumed();
6201 p_buf
.set_pos(bytes
);
6203 case TTCN_EncDec::CT_JSON
: {
6204 TTCN_EncDec_ErrorContext
ec("While JSON-decoding type '%s': ", p_td
.name
);
6205 if(!p_td
.json
) TTCN_EncDec_ErrorContext::error_internal
6206 ("No JSON descriptor available for type '%s'.", p_td
.name
);
6207 JSON_Tokenizer
tok((const char*)p_buf
.get_data(), p_buf
.get_len());
6208 if(JSON_decode(p_td
, tok
, false)<0)
6209 ec
.error(TTCN_EncDec::ET_INCOMPL_MSG
,
6210 "Can not decode type '%s', because invalid or incomplete"
6211 " message was received", p_td
.name
);
6212 p_buf
.set_pos(tok
.get_buf_pos());
6215 TTCN_error("Unknown coding method requested to decode type '%s'", p_td
.name
);
6220 ASN_BER_TLV_t
* Empty_Record_Type::BER_encode_TLV(const TTCN_Typedescriptor_t
& p_td
,
6221 unsigned p_coding
) const
6223 BER_chk_descr(p_td
);
6224 ASN_BER_TLV_t
*new_tlv
=ASN_BER_TLV_t::construct(NULL
);
6225 new_tlv
=ASN_BER_V2TLV(new_tlv
, p_td
, p_coding
);
6229 boolean
Empty_Record_Type::BER_decode_TLV(const TTCN_Typedescriptor_t
& p_td
,
6230 const ASN_BER_TLV_t
& p_tlv
, unsigned L_form
)
6232 BER_chk_descr(p_td
);
6233 ASN_BER_TLV_t stripped_tlv
;
6234 BER_decode_strip_tags(*p_td
.ber
, p_tlv
, L_form
, stripped_tlv
);
6235 TTCN_EncDec_ErrorContext
ec_0("While decoding '%s' type: ", get_descriptor()->name
);
6236 stripped_tlv
.chk_constructed_flag(TRUE
);
6241 int Empty_Record_Type::RAW_encode(const TTCN_Typedescriptor_t
& p_td
,
6242 RAW_enc_tree
& /*myleaf*/) const
6244 if (!bound_flag
) TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND
,
6245 "Encoding an unbound value of type %s.", p_td
.name
);
6249 int Empty_Record_Type::RAW_decode(const TTCN_Typedescriptor_t
& p_td
,
6250 TTCN_Buffer
& buff
, int /*limit*/, raw_order_t
/*top_bit_ord*/,
6251 boolean
/*no_err*/, int /*sel_field*/, boolean
/*first_call*/)
6254 return buff
.increase_pos_padd(p_td
.raw
->prepadding
)
6255 + buff
.increase_pos_padd(p_td
.raw
->padding
);
6258 int Empty_Record_Type::TEXT_encode(const TTCN_Typedescriptor_t
& p_td
, TTCN_Buffer
& buff
) const
6260 int encoded_length
=0;
6261 if(p_td
.text
->begin_encode
) {
6262 buff
.put_cs(*p_td
.text
->begin_encode
);
6263 encoded_length
+=p_td
.text
->begin_encode
->lengthof();
6266 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND
, "Encoding an unbound value.");
6268 if(p_td
.text
->end_encode
) {
6269 buff
.put_cs(*p_td
.text
->end_encode
);
6270 encoded_length
+=p_td
.text
->end_encode
->lengthof();
6272 return encoded_length
;
6275 int Empty_Record_Type::TEXT_decode(const TTCN_Typedescriptor_t
& p_td
,
6276 TTCN_Buffer
& buff
, Limit_Token_List
& /*limit*/, boolean no_err
, boolean
/*first_call*/)
6278 int decoded_length
=0;
6279 if(p_td
.text
->begin_decode
) {
6281 if((tl
=p_td
.text
->begin_decode
->match_begin(buff
))<0) {
6282 if(no_err
)return -1;
6283 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR
,
6284 "The specified token '%s' not found for '%s': ",
6285 (const char*)*(p_td
.text
->begin_decode
), p_td
.name
);
6289 buff
.increase_pos(tl
);
6291 if(p_td
.text
->end_decode
) {
6293 if((tl
=p_td
.text
->end_decode
->match_begin(buff
))<0) {
6294 if(no_err
)return -1;
6295 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR
,
6296 "The specified token '%s' not found for '%s': ",
6297 (const char*)*(p_td
.text
->end_decode
), p_td
.name
);
6301 buff
.increase_pos(tl
);
6304 return decoded_length
;
6307 int Empty_Record_Type::XER_encode(const XERdescriptor_t
& p_td
,
6308 TTCN_Buffer
& p_buf
, unsigned int flavor
, int indent
, embed_values_enc_struct_t
*) const
6310 int encoded_length
=(int)p_buf
.get_len();
6311 int indenting
= !is_canonical(flavor
);
6312 int exer
= is_exer(flavor
);
6313 if (indenting
) do_indent(p_buf
, indent
);
6315 if (exer
) write_ns_prefix(p_td
, p_buf
);
6316 p_buf
.put_s((size_t)p_td
.namelens
[exer
]-2, (cbyte
*)p_td
.names
[exer
]);
6317 p_buf
.put_s(2 + indenting
, (cbyte
*)"/>\n");
6318 return (int)p_buf
.get_len() - encoded_length
;
6321 int Empty_Record_Type::XER_decode(const XERdescriptor_t
& p_td
,
6322 XmlReaderWrap
& reader
, unsigned int flavor
, unsigned int /*flavor2*/, embed_values_dec_struct_t
*)
6324 int exer
= is_exer(flavor
);
6326 int success
, depth
= -1;
6327 for (success
=reader
.Ok(); success
==1; success
=reader
.Read()) {
6328 int type
= reader
.NodeType();
6329 if (type
==XML_READER_TYPE_ELEMENT
) {
6330 verify_name(reader
, p_td
, exer
);
6331 depth
= reader
.Depth();
6333 if (reader
.IsEmptyElement()) {
6334 reader
.Read(); break;
6336 else if ((flavor
& XER_MASK
) == XER_CANONICAL
) {
6337 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG
,
6338 "Expected an empty element tag");
6339 // Stay in the loop and look for the end element, in case the error
6340 // was ignored or reduced to warning.
6343 else if (type
== XML_READER_TYPE_END_ELEMENT
&& depth
!= -1) {
6344 verify_end(reader
, p_td
, depth
, exer
);
6349 return 1; // decode successful
6352 int Empty_Record_Type::JSON_encode(const TTCN_Typedescriptor_t
&, JSON_Tokenizer
& p_tok
) const
6355 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND
,
6356 "Encoding an unbound empty %s value.", is_set() ? "set" : "record");
6360 return p_tok
.put_next_token(JSON_TOKEN_OBJECT_START
, NULL
) +
6361 p_tok
.put_next_token(JSON_TOKEN_OBJECT_END
, NULL
);
6364 int Empty_Record_Type::JSON_decode(const TTCN_Typedescriptor_t
&, JSON_Tokenizer
& p_tok
, boolean p_silent
)
6366 json_token_t token
= JSON_TOKEN_NONE
;
6367 int dec_len
= p_tok
.get_next_token(&token
, NULL
, NULL
);
6368 if (JSON_TOKEN_ERROR
== token
) {
6369 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG
, JSON_DEC_BAD_TOKEN_ERROR
, "");
6370 return JSON_ERROR_FATAL
;
6372 else if (JSON_TOKEN_OBJECT_START
!= token
) {
6373 return JSON_ERROR_INVALID_TOKEN
;
6376 dec_len
+= p_tok
.get_next_token(&token
, NULL
, NULL
);
6377 if (JSON_TOKEN_OBJECT_END
!= token
) {
6378 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG
, JSON_DEC_STATIC_OBJECT_END_TOKEN_ERROR
, "");
6379 return JSON_ERROR_FATAL
;
6387 boolean
operator==(null_type
/*null_value*/, const Empty_Record_Type
& other_value
)
6389 if (!other_value
.is_bound())
6390 TTCN_error("Comparison of an unbound value of type %s.",
6391 other_value
.get_descriptor()->name
);
6395 boolean
operator!=(null_type
/*null_value*/, const Empty_Record_Type
& other_value
)
6397 if (!other_value
.is_bound())
6398 TTCN_error("Comparison of an unbound value of type %s.",
6399 other_value
.get_descriptor()->name
);