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
);
2471 if (!get_at(i
)->is_bound()) {
2472 // use null pointers for unbound elements
2473 delete val_ptr
->value_elements
[i
];
2474 val_ptr
->value_elements
[i
] = NULL
;
2479 case Module_Param::MP_Indexed_List
:
2480 for (size_t i
=0; i
<mp
->get_size(); ++i
) {
2481 Module_Param
* const current
= mp
->get_elem(i
);
2482 get_at(current
->get_id()->get_index())->set_param(*current
);
2483 if (!get_at(current
->get_id()->get_index())->is_bound()) {
2484 // use null pointers for unbound elements
2485 delete val_ptr
->value_elements
[current
->get_id()->get_index()];
2486 val_ptr
->value_elements
[current
->get_id()->get_index()] = NULL
;
2491 param
.type_error(is_set()?"set of value":"record of value", get_descriptor()->name
);
2494 case Module_Param::OT_CONCAT
:
2495 switch (mp
->get_type()) {
2496 case Module_Param::MP_Value_List
: {
2497 if (!is_bound()) set_val(NULL_VALUE
);
2498 int start_idx
= lengthof();
2499 for (size_t i
=0; i
<mp
->get_size(); ++i
) {
2500 Module_Param
* const curr
= mp
->get_elem(i
);
2501 if ((curr
->get_type()!=Module_Param::MP_NotUsed
)) {
2502 get_at(start_idx
+(int)i
)->set_param(*curr
);
2506 case Module_Param::MP_Indexed_List
:
2507 param
.error("Cannot concatenate an indexed value list");
2510 param
.type_error(is_set()?"set of value":"record of value", get_descriptor()->name
);
2514 TTCN_error("Internal error: Record_Of_Type::set_param()");
2518 Module_Param
* Record_Of_Type::get_param(Module_Param_Name
& param_name
) const
2521 return new Module_Param_Unbound();
2523 if (param_name
.next_name()) {
2524 // Haven't reached the end of the module parameter name
2525 // => the name refers to one of the elements, not to the whole record of
2526 char* param_field
= param_name
.get_current_name();
2527 if (param_field
[0] < '0' || param_field
[0] > '9') {
2528 TTCN_error("Unexpected record field name in module parameter reference, "
2529 "expected a valid index for %s type `%s'",
2530 is_set() ? "set of" : "record of", get_descriptor()->name
);
2532 int param_index
= -1;
2533 sscanf(param_field
, "%d", ¶m_index
);
2534 return get_at(param_index
)->get_param(param_name
);
2536 Vector
<Module_Param
*> values
;
2537 for (int i
= 0; i
< val_ptr
->n_elements
; ++i
) {
2538 values
.push_back(val_ptr
->value_elements
[i
]->get_param(param_name
));
2540 Module_Param_Value_List
* mp
= new Module_Param_Value_List();
2541 mp
->add_list_with_implicit_ids(&values
);
2546 void Record_Of_Type::set_implicit_omit()
2548 for (int i
= 0; i
< get_nof_elements(); ++i
) {
2549 if (is_elem_bound(i
))
2550 val_ptr
->value_elements
[i
]->set_implicit_omit();
2554 void Record_Of_Type::add_refd_index(int index
)
2556 if (NULL
== refd_ind_ptr
) {
2557 refd_ind_ptr
= new refd_index_struct
;
2558 refd_ind_ptr
->max_refd_index
= -1;
2560 refd_ind_ptr
->refd_indices
.push_back(index
);
2561 if (index
> get_max_refd_index()) {
2562 refd_ind_ptr
->max_refd_index
= index
;
2566 void Record_Of_Type::remove_refd_index(int index
)
2568 for (size_t i
= refd_ind_ptr
->refd_indices
.size(); i
> 0; --i
) {
2569 if (refd_ind_ptr
->refd_indices
[i
- 1] == index
) {
2570 refd_ind_ptr
->refd_indices
.erase_at(i
- 1);
2574 if (refd_ind_ptr
->refd_indices
.empty()) {
2575 delete refd_ind_ptr
;
2576 refd_ind_ptr
= NULL
;
2578 else if (get_max_refd_index() == index
) {
2579 refd_ind_ptr
->max_refd_index
= -1;
2583 boolean
operator==(null_type
/*null_value*/, const Record_Of_Type
& other_value
)
2585 if (other_value
.val_ptr
== NULL
)
2586 TTCN_error("The right operand of comparison is an unbound value of type %s.",
2587 other_value
.get_descriptor()->name
);
2588 return other_value
.get_nof_elements() == 0;
2591 boolean
operator!=(null_type null_value
,
2592 const Record_Of_Type
& other_value
)
2594 return !(null_value
== other_value
);
2597 ////////////////////////////////////////////////////////////////////////////////
2599 boolean
Record_Type::is_bound() const
2601 int field_cnt
= get_count();
2602 for (int field_idx
=0; field_idx
<field_cnt
; field_idx
++) {
2603 const Base_Type
* temp
= get_at(field_idx
);
2604 if(temp
->is_optional()) {
2605 if(temp
->is_present() && temp
->get_opt_value()->is_bound()) return TRUE
;
2607 if(temp
->is_bound()) return TRUE
;
2612 boolean
Record_Type::is_value() const
2614 int field_cnt
= get_count();
2615 for (int field_idx
=0; field_idx
<field_cnt
; field_idx
++) {
2616 const Base_Type
* temp
= get_at(field_idx
);
2617 if(temp
->is_optional()) {
2618 if(!temp
->is_bound()) return FALSE
;
2619 if(temp
->is_present() && !temp
->is_value()) return FALSE
;
2621 if(!temp
->is_value()) return FALSE
;
2627 void Record_Type::clean_up()
2629 int field_cnt
= get_count();
2630 for (int field_idx
=0; field_idx
<field_cnt
; field_idx
++) {
2631 get_at(field_idx
)->clean_up();
2635 void Record_Type::log() const
2638 TTCN_Logger::log_event_unbound();
2641 TTCN_Logger::log_event_str("{ ");
2642 int field_cnt
= get_count();
2643 for (int field_idx
=0; field_idx
<field_cnt
; field_idx
++) {
2644 if (field_idx
) TTCN_Logger::log_event_str(", ");
2645 TTCN_Logger::log_event_str(fld_name(field_idx
));
2646 TTCN_Logger::log_event_str(" := ");
2647 get_at(field_idx
)->log();
2649 TTCN_Logger::log_event_str(" }");
2650 if (err_descr
) err_descr
->log();
2653 void Record_Type::set_param(Module_Param
& param
) {
2654 if (dynamic_cast<Module_Param_Name
*>(param
.get_id()) != NULL
&&
2655 param
.get_id()->next_name()) {
2656 // Haven't reached the end of the module parameter name
2657 // => the name refers to one of the fields, not to the whole record
2658 char* param_field
= param
.get_id()->get_current_name();
2659 if (param_field
[0] >= '0' && param_field
[0] <= '9') {
2660 param
.error("Unexpected array index in module parameter, expected a valid field"
2661 " name for %s type `%s'", is_set() ? "set" : "record", get_descriptor()->name
);
2663 int field_cnt
= get_count();
2664 for (int field_idx
= 0; field_idx
< field_cnt
; field_idx
++) {
2665 if (strcmp(fld_name(field_idx
), param_field
) == 0) {
2666 get_at(field_idx
)->set_param(param
);
2670 param
.error("Field `%s' not found in %s type `%s'",
2671 param_field
, is_set() ? "set" : "record", get_descriptor()->name
);
2674 param
.basic_check(Module_Param::BC_VALUE
, is_set()?"set value":"record value");
2676 Module_Param_Ptr mp
= ¶m
;
2677 if (param
.get_type() == Module_Param::MP_Reference
) {
2678 mp
= param
.get_referenced_param();
2681 switch (mp
->get_type()) {
2682 case Module_Param::MP_Value_List
:
2683 if (get_count()<(int)mp
->get_size()) {
2684 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());
2686 for (size_t i
=0; i
<mp
->get_size(); i
++) {
2687 Module_Param
* mp_elem
= mp
->get_elem(i
);
2688 if (mp_elem
->get_type()!=Module_Param::MP_NotUsed
) {
2689 get_at((int)i
)->set_param(*mp_elem
);
2693 case Module_Param::MP_Assignment_List
:
2694 for (size_t i
=0; i
<mp
->get_size(); ++i
) {
2695 Module_Param
* const current
= mp
->get_elem(i
);
2697 for (int j
=0; j
<get_count(); ++j
) {
2698 if (!strcmp(fld_name(j
), current
->get_id()->get_name())) {
2699 if (current
->get_type()!=Module_Param::MP_NotUsed
) {
2700 get_at(j
)->set_param(*current
);
2707 current
->error("Non existent field name in type %s: %s.", get_descriptor()->name
, current
->get_id()->get_name());
2712 param
.type_error(is_set()?"set value":"record value", get_descriptor()->name
);
2716 Module_Param
* Record_Type::get_param(Module_Param_Name
& param_name
) const
2719 return new Module_Param_Unbound();
2721 if (param_name
.next_name()) {
2722 // Haven't reached the end of the module parameter name
2723 // => the name refers to one of the fields, not to the whole record
2724 char* param_field
= param_name
.get_current_name();
2725 if (param_field
[0] >= '0' && param_field
[0] <= '9') {
2726 TTCN_error("Unexpected array index in module parameter reference, "
2727 "expected a valid field name for %s type `%s'",
2728 is_set() ? "set" : "record", get_descriptor()->name
);
2730 int field_cnt
= get_count();
2731 for (int field_idx
= 0; field_idx
< field_cnt
; field_idx
++) {
2732 if (strcmp(fld_name(field_idx
), param_field
) == 0) {
2733 return get_at(field_idx
)->get_param(param_name
);
2736 TTCN_error("Field `%s' not found in %s type `%s'",
2737 param_field
, is_set() ? "set" : "record", get_descriptor()->name
);
2739 Module_Param_Assignment_List
* mp
= new Module_Param_Assignment_List();
2740 for (int i
= 0; i
< get_count(); ++i
) {
2741 Module_Param
* mp_field
= get_at(i
)->get_param(param_name
);
2742 mp_field
->set_id(new Module_Param_FieldName(mcopystr(fld_name(i
))));
2743 mp
->add_elem(mp_field
);
2748 void Record_Type::set_implicit_omit()
2750 int field_cnt
= get_count();
2751 for (int field_idx
= 0; field_idx
< field_cnt
; field_idx
++) {
2752 Base_Type
*temp
= get_at(field_idx
);
2753 if (temp
->is_optional()) {
2754 if (temp
->is_bound()) temp
->set_implicit_omit();
2755 else temp
->set_to_omit();
2756 } else if (temp
->is_bound()) {
2757 temp
->set_implicit_omit();
2762 int Record_Type::size_of() const
2764 int opt_count
= optional_count();
2765 if (opt_count
==0) return get_count();
2766 const int* optional_indexes
= get_optional_indexes();
2767 int my_size
= get_count();
2768 for (int i
=0; i
<opt_count
; i
++) {
2769 if (!get_at(optional_indexes
[i
])->ispresent()) my_size
--;
2774 void Record_Type::encode_text(Text_Buf
& text_buf
) const
2777 TTCN_error("Text encoder: Encoding an unbound record/set value of type %s.",
2778 get_descriptor()->name
);
2780 int field_cnt
= get_count();
2781 for (int field_idx
=0; field_idx
<field_cnt
; field_idx
++)
2782 get_at(field_idx
)->encode_text(text_buf
);
2785 void Record_Type::decode_text(Text_Buf
& text_buf
)
2787 int field_cnt
= get_count();
2788 for (int field_idx
=0; field_idx
<field_cnt
; field_idx
++)
2789 get_at(field_idx
)->decode_text(text_buf
);
2792 boolean
Record_Type::is_equal(const Base_Type
* other_value
) const
2794 const Record_Type
* other_record
= static_cast<const Record_Type
*>(other_value
);
2795 int field_cnt
= get_count();
2796 for (int field_idx
=0; field_idx
<field_cnt
; field_idx
++) {
2797 const Base_Type
* elem
= get_at(field_idx
);
2798 const Base_Type
* other_elem
= other_record
->get_at(field_idx
);
2799 if (elem
->is_bound()) {
2800 if (other_elem
->is_bound()) {
2801 if (!elem
->is_equal(other_elem
))
2803 } else return FALSE
;
2804 } else if (other_elem
->is_bound()) return FALSE
;
2809 void Record_Type::set_value(const Base_Type
* other_value
)
2811 if (this==other_value
) return;
2812 if (!other_value
->is_bound())
2813 TTCN_error("Copying an unbound record/set value of type %s.",
2814 other_value
->get_descriptor()->name
);
2815 const Record_Type
* other_record
= static_cast<const Record_Type
*>(other_value
);
2816 int field_cnt
= get_count();
2817 for (int field_idx
=0; field_idx
<field_cnt
; field_idx
++) {
2818 const Base_Type
* elem
= other_record
->get_at(field_idx
);
2819 if (elem
->is_bound()) {
2820 get_at(field_idx
)->set_value(elem
);
2822 get_at(field_idx
)->clean_up();
2825 err_descr
= other_record
->err_descr
;
2828 void Record_Type::encode(const TTCN_Typedescriptor_t
& p_td
,
2829 TTCN_Buffer
& p_buf
, TTCN_EncDec::coding_t p_coding
, ...) const
2832 va_start(pvar
, p_coding
);
2834 case TTCN_EncDec::CT_BER
: {
2835 TTCN_EncDec_ErrorContext
ec("While BER-encoding type '%s': ", p_td
.name
);
2836 unsigned BER_coding
=va_arg(pvar
, unsigned);
2837 BER_encode_chk_coding(BER_coding
);
2838 ASN_BER_TLV_t
*tlv
=BER_encode_TLV(p_td
, BER_coding
);
2839 tlv
->put_in_buffer(p_buf
);
2840 ASN_BER_TLV_t::destruct(tlv
);
2842 case TTCN_EncDec::CT_RAW
: {
2843 TTCN_EncDec_ErrorContext
ec("While RAW-encoding type '%s': ", p_td
.name
);
2844 if(!p_td
.raw
) TTCN_EncDec_ErrorContext::error_internal
2845 ("No RAW descriptor available for type '%s'.", p_td
.name
);
2849 RAW_enc_tree
root(FALSE
, NULL
, &rp
, 1, p_td
.raw
);
2850 RAW_encode(p_td
, root
);
2851 root
.put_to_buf(p_buf
);
2853 case TTCN_EncDec::CT_TEXT
: {
2854 TTCN_EncDec_ErrorContext
ec("While TEXT-encoding type '%s': ", p_td
.name
);
2855 if(!p_td
.text
) TTCN_EncDec_ErrorContext::error_internal
2856 ("No TEXT descriptor available for type '%s'.", p_td
.name
);
2857 TEXT_encode(p_td
,p_buf
);
2859 case TTCN_EncDec::CT_XER
: {
2860 TTCN_EncDec_ErrorContext
ec("While XER-encoding type '%s': ", p_td
.name
);
2861 unsigned XER_coding
=va_arg(pvar
, unsigned);
2862 XER_encode(*(p_td
.xer
),p_buf
, XER_coding
, 0, 0);
2865 case TTCN_EncDec::CT_JSON
: {
2866 TTCN_EncDec_ErrorContext
ec("While JSON-encoding type '%s': ", p_td
.name
);
2867 if(!p_td
.json
) TTCN_EncDec_ErrorContext::error_internal
2868 ("No JSON descriptor available for type '%s'.", p_td
.name
);
2869 JSON_Tokenizer
tok(va_arg(pvar
, int) != 0);
2870 JSON_encode(p_td
, tok
);
2871 p_buf
.put_s(tok
.get_buffer_length(), (const unsigned char*)tok
.get_buffer());
2874 TTCN_error("Unknown coding method requested to encode type '%s'", p_td
.name
);
2879 void Record_Type::decode(const TTCN_Typedescriptor_t
& p_td
,
2880 TTCN_Buffer
& p_buf
, TTCN_EncDec::coding_t p_coding
, ...)
2883 va_start(pvar
, p_coding
);
2885 case TTCN_EncDec::CT_BER
: {
2886 TTCN_EncDec_ErrorContext
ec("While BER-decoding type '%s': ", p_td
.name
);
2887 unsigned L_form
=va_arg(pvar
, unsigned);
2889 BER_decode_str2TLV(p_buf
, tlv
, L_form
);
2890 BER_decode_TLV(p_td
, tlv
, L_form
);
2891 if(tlv
.isComplete
) p_buf
.increase_pos(tlv
.get_len());
2893 case TTCN_EncDec::CT_RAW
: {
2894 TTCN_EncDec_ErrorContext
ec("While RAW-decoding type '%s': ", p_td
.name
);
2896 TTCN_EncDec_ErrorContext::error_internal
2897 ("No RAW descriptor available for type '%s'.", p_td
.name
);
2899 switch(p_td
.raw
->top_bit_order
) {
2907 int rawr
= RAW_decode(p_td
, p_buf
, p_buf
.get_len()*8, order
);
2908 if (rawr
< 0) switch (-rawr
) {
2909 case TTCN_EncDec::ET_INCOMPL_MSG
:
2910 case TTCN_EncDec::ET_LEN_ERR
:
2911 ec
.error(TTCN_EncDec::ET_INCOMPL_MSG
,
2912 "Can not decode type '%s', because incomplete"
2913 " message was received", p_td
.name
);
2916 // The RAW/TEXT decoders return -1 for anything not a length error.
2917 // This is the value for ET_UNBOUND, which can't happen in decoding.
2919 ec
.error(TTCN_EncDec::ET_INVAL_MSG
,
2920 "Can not decode type '%s', because invalid"
2921 " message was received", p_td
.name
);
2925 case TTCN_EncDec::CT_TEXT
: {
2926 Limit_Token_List limit
;
2927 TTCN_EncDec_ErrorContext
ec("While TEXT-decoding type '%s': ", p_td
.name
);
2928 if(!p_td
.text
) TTCN_EncDec_ErrorContext::error_internal
2929 ("No TEXT descriptor available for type '%s'.", p_td
.name
);
2930 const unsigned char *b
=p_buf
.get_data();
2931 if(b
[p_buf
.get_len()-1]!='\0'){
2932 p_buf
.set_pos(p_buf
.get_len());
2933 p_buf
.put_zero(8,ORDER_LSB
);
2936 if(TEXT_decode(p_td
,p_buf
,limit
)<0)
2937 ec
.error(TTCN_EncDec::ET_INCOMPL_MSG
,
2938 "Can not decode type '%s', because invalid or incomplete"
2939 " message was received", p_td
.name
);
2941 case TTCN_EncDec::CT_XER
: {
2942 TTCN_EncDec_ErrorContext
ec("While XER-decoding type '%s': ", p_td
.name
);
2943 unsigned XER_coding
=va_arg(pvar
, unsigned);
2944 XmlReaderWrap
reader(p_buf
);
2945 for (int success
=reader
.Read(); success
==1; success
=reader
.Read()) {
2946 if (reader
.NodeType() == XML_READER_TYPE_ELEMENT
) break;
2948 XER_decode(*(p_td
.xer
), reader
, XER_coding
| XER_TOPLEVEL
, XER_NONE
, 0);
2949 size_t bytes
= reader
.ByteConsumed();
2950 p_buf
.set_pos(bytes
);
2952 case TTCN_EncDec::CT_JSON
: {
2953 TTCN_EncDec_ErrorContext
ec("While JSON-decoding type '%s': ", p_td
.name
);
2954 if(!p_td
.json
) TTCN_EncDec_ErrorContext::error_internal
2955 ("No JSON descriptor available for type '%s'.", p_td
.name
);
2956 JSON_Tokenizer
tok((const char*)p_buf
.get_data(), p_buf
.get_len());
2957 if(JSON_decode(p_td
, tok
, false)<0)
2958 ec
.error(TTCN_EncDec::ET_INCOMPL_MSG
,
2959 "Can not decode type '%s', because invalid or incomplete"
2960 " message was received", p_td
.name
);
2961 p_buf
.set_pos(tok
.get_buf_pos());
2964 TTCN_error("Unknown coding method requested to decode type '%s'", p_td
.name
);
2969 ASN_BER_TLV_t
* Record_Type::BER_encode_TLV(const TTCN_Typedescriptor_t
& p_td
, unsigned p_coding
) const
2972 return BER_encode_TLV_negtest(err_descr
, p_td
, p_coding
);
2975 TTCN_EncDec_ErrorContext::error
2976 (TTCN_EncDec::ET_UNBOUND
, "Encoding an unbound value.");
2978 BER_chk_descr(p_td
);
2979 ASN_BER_TLV_t
*new_tlv
=ASN_BER_TLV_t::construct(NULL
);
2980 TTCN_EncDec_ErrorContext
ec_0("Component '");
2981 TTCN_EncDec_ErrorContext ec_1
;
2982 int next_default_idx
= 0;
2983 const default_struct
* default_indexes
= get_default_indexes();
2984 int field_cnt
= get_count();
2985 for(int i
=0; i
<field_cnt
; i
++) {
2986 boolean is_default_field
= default_indexes
&& (default_indexes
[next_default_idx
].index
==i
);
2987 if (!default_as_optional() && is_default_field
) {
2988 if (!get_at(i
)->is_equal(default_indexes
[next_default_idx
].value
)) {
2989 ec_1
.set_msg("%s': ", fld_name(i
));
2990 new_tlv
->add_TLV(get_at(i
)->BER_encode_TLV(*fld_descr(i
), p_coding
));
2992 } else { /* is not DEFAULT */
2993 ec_1
.set_msg("%s': ", fld_name(i
));
2994 new_tlv
->add_TLV(get_at(i
)->BER_encode_TLV(*fld_descr(i
), p_coding
));
2996 if (is_default_field
) next_default_idx
++;
2999 if (p_coding
==BER_ENCODE_DER
) new_tlv
->sort_tlvs_tag();
3000 new_tlv
=ASN_BER_V2TLV(new_tlv
, p_td
, p_coding
);
3004 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
3007 TTCN_EncDec_ErrorContext::error
3008 (TTCN_EncDec::ET_UNBOUND
, "Encoding an unbound value.");
3010 BER_chk_descr(p_td
);
3011 ASN_BER_TLV_t
*new_tlv
=ASN_BER_TLV_t::construct(NULL
);
3012 TTCN_EncDec_ErrorContext
ec_0("Component '");
3013 TTCN_EncDec_ErrorContext ec_1
;
3014 int next_default_idx
= 0;
3015 const default_struct
* default_indexes
= get_default_indexes();
3016 int field_cnt
= get_count();
3021 for (int i
=0; i
<field_cnt
; i
++) {
3022 boolean is_default_field
= default_indexes
&& (default_indexes
[next_default_idx
].index
==i
);
3023 // the first condition is not needed, kept for ease of understanding
3024 if ( (p_err_descr
->omit_before
!=-1) && (i
<p_err_descr
->omit_before
) ) {
3025 if (is_default_field
) next_default_idx
++;
3028 const Erroneous_values_t
* err_vals
= p_err_descr
->next_field_err_values(i
, values_idx
);
3029 const Erroneous_descriptor_t
* emb_descr
= p_err_descr
->next_field_emb_descr(i
, edescr_idx
);
3031 if (err_vals
&& err_vals
->before
) {
3032 if (err_vals
->before
->errval
==NULL
) TTCN_error(
3033 "internal error: erroneous before value missing");
3034 ec_1
.set_msg("%s'(erroneous before): ", fld_name(i
));
3035 if (err_vals
->before
->raw
) {
3036 new_tlv
->add_TLV(err_vals
->before
->errval
->BER_encode_negtest_raw());
3038 if (err_vals
->before
->type_descr
==NULL
) TTCN_error(
3039 "internal error: erroneous before typedescriptor missing");
3040 new_tlv
->add_TLV(err_vals
->before
->errval
->BER_encode_TLV(
3041 *err_vals
->before
->type_descr
, p_coding
));
3045 if (err_vals
&& err_vals
->value
) {
3046 if (err_vals
->value
->errval
) { // replace
3047 ec_1
.set_msg("%s'(erroneous value): ", fld_name(i
));
3048 if (err_vals
->value
->raw
) {
3049 new_tlv
->add_TLV(err_vals
->value
->errval
->BER_encode_negtest_raw());
3051 if (err_vals
->value
->type_descr
==NULL
) TTCN_error(
3052 "internal error: erroneous value typedescriptor missing");
3053 new_tlv
->add_TLV(err_vals
->value
->errval
->BER_encode_TLV(
3054 *err_vals
->value
->type_descr
, p_coding
));
3058 if (!default_as_optional() && is_default_field
) {
3059 if (!get_at(i
)->is_equal(default_indexes
[next_default_idx
].value
)) {
3060 ec_1
.set_msg("'%s': ", fld_name(i
));
3062 new_tlv
->add_TLV(get_at(i
)->BER_encode_TLV_negtest(emb_descr
,
3063 *fld_descr(i
), p_coding
));
3065 new_tlv
->add_TLV(get_at(i
)->BER_encode_TLV(*fld_descr(i
), p_coding
));
3068 } else { /* is not DEFAULT */
3069 ec_1
.set_msg("'%s': ", fld_name(i
));
3071 new_tlv
->add_TLV(get_at(i
)->BER_encode_TLV_negtest(emb_descr
,
3072 *fld_descr(i
), p_coding
));
3074 new_tlv
->add_TLV(get_at(i
)->BER_encode_TLV(*fld_descr(i
), p_coding
));
3079 if (err_vals
&& err_vals
->after
) {
3080 if (err_vals
->after
->errval
==NULL
) TTCN_error(
3081 "internal error: erroneous after value missing");
3082 ec_1
.set_msg("%s'(erroneous after): ", fld_name(i
));
3083 if (err_vals
->after
->raw
) {
3084 new_tlv
->add_TLV(err_vals
->after
->errval
->BER_encode_negtest_raw());
3086 if (err_vals
->after
->type_descr
==NULL
) TTCN_error(
3087 "internal error: erroneous after typedescriptor missing");
3088 new_tlv
->add_TLV(err_vals
->after
->errval
->BER_encode_TLV(
3089 *err_vals
->after
->type_descr
, p_coding
));
3093 if (is_default_field
) next_default_idx
++;
3094 if ( (p_err_descr
->omit_after
!=-1) && (i
>=p_err_descr
->omit_after
) ) break;
3098 if (p_coding
==BER_ENCODE_DER
) new_tlv
->sort_tlvs_tag();
3099 new_tlv
=ASN_BER_V2TLV(new_tlv
, p_td
, p_coding
);
3103 boolean
Record_Type::BER_decode_TLV(const TTCN_Typedescriptor_t
& p_td
,
3104 const ASN_BER_TLV_t
& p_tlv
, unsigned L_form
)
3106 BER_chk_descr(p_td
);
3107 ASN_BER_TLV_t stripped_tlv
;
3108 BER_decode_strip_tags(*p_td
.ber
, p_tlv
, L_form
, stripped_tlv
);
3109 TTCN_EncDec_ErrorContext
ec_0("While decoding '%s' type: ", get_descriptor()->name
);
3110 stripped_tlv
.chk_constructed_flag(TRUE
);
3112 ASN_BER_TLV_t tmp_tlv
;
3114 { /* SEQUENCE decoding */
3115 boolean tlv_present
=FALSE
;
3117 TTCN_EncDec_ErrorContext
ec_1("Component '");
3118 TTCN_EncDec_ErrorContext ec_2
;
3119 int next_default_idx
= 0;
3120 int next_optional_idx
= 0;
3121 const default_struct
* default_indexes
= get_default_indexes();
3122 const int* optional_indexes
= get_optional_indexes();
3123 int field_cnt
= get_count();
3124 for(int i
=0; i
<field_cnt
; i
++) {
3125 boolean is_default_field
= default_indexes
&& (default_indexes
[next_default_idx
].index
==i
);
3126 boolean is_optional_field
= optional_indexes
&& (optional_indexes
[next_optional_idx
]==i
);
3127 ec_2
.set_msg("%s': ", fld_descr(i
)->name
);
3128 if (!tlv_present
) tlv_present
=BER_decode_constdTLV_next(stripped_tlv
, V_pos
, L_form
, tmp_tlv
);
3129 if (is_default_field
) { /* is DEFAULT */
3130 if (!tlv_present
|| !get_at(i
)->BER_decode_isMyMsg(*fld_descr(i
), tmp_tlv
)) {
3131 get_at(i
)->set_value(default_indexes
[next_default_idx
].value
);
3133 get_at(i
)->BER_decode_TLV(*fld_descr(i
), tmp_tlv
, L_form
);
3137 else if (is_optional_field
) { /* is OPTIONAL */
3138 if (!tlv_present
) get_at(i
)->set_to_omit();
3140 get_at(i
)->BER_decode_TLV(*fld_descr(i
), tmp_tlv
, L_form
);
3141 if (get_at(i
)->ispresent()) tlv_present
=FALSE
;
3144 else { /* is not DEFAULT OPTIONAL */
3146 ec_2
.error(TTCN_EncDec::ET_INCOMPL_MSG
,"Invalid or incomplete message was received.");
3149 get_at(i
)->BER_decode_TLV(*fld_descr(i
), tmp_tlv
, L_form
);
3152 if (is_default_field
) next_default_idx
++;
3153 if (is_optional_field
) next_optional_idx
++;
3156 BER_decode_constdTLV_end(stripped_tlv
, V_pos
, L_form
, tmp_tlv
, tlv_present
);
3157 } /* SEQUENCE decoding */
3159 { /* SET decoding */
3161 * 0x01: value arrived
3162 * 0x02: is optional / not used :)
3163 * 0x04: has default / not used :)
3165 int field_cnt
= get_count();
3166 unsigned char* fld_indctr
= new unsigned char[field_cnt
];
3167 for (int i
=0; i
<field_cnt
; i
++) fld_indctr
[i
] = 0;
3168 int fld_curr
= -1; /* ellipsis or error... */
3169 while (BER_decode_constdTLV_next(stripped_tlv
, V_pos
, L_form
, tmp_tlv
)) {
3170 for (int i
=0; i
<field_cnt
; i
++) {
3171 if (get_at(i
)->BER_decode_isMyMsg(*fld_descr(i
), tmp_tlv
)) {
3173 TTCN_EncDec_ErrorContext
ec_1("Component '%s': ", fld_name(i
));
3174 get_at(i
)->BER_decode_TLV(*fld_descr(i
), tmp_tlv
, L_form
);
3179 if (fld_indctr
[fld_curr
])
3180 ec_0
.error(TTCN_EncDec::ET_DEC_DUPFLD
, "Duplicated value for component '%s'.", fld_name(fld_curr
));
3181 fld_indctr
[fld_curr
]=1;
3184 int next_default_idx
= 0;
3185 int next_optional_idx
= 0;
3186 const default_struct
* default_indexes
= get_default_indexes();
3187 const int* optional_indexes
= get_optional_indexes();
3188 for (fld_curr
=0; fld_curr
<field_cnt
; fld_curr
++) {
3189 boolean is_default_field
= default_indexes
&& (default_indexes
[next_default_idx
].index
==fld_curr
);
3190 boolean is_optional_field
= optional_indexes
&& (optional_indexes
[next_optional_idx
]==fld_curr
);
3191 if (!fld_indctr
[fld_curr
]) {
3192 if (is_default_field
) get_at(fld_curr
)->set_value(default_indexes
[next_default_idx
].value
);
3193 else if (is_optional_field
) get_at(fld_curr
)->set_to_omit();
3194 else ec_0
.error(TTCN_EncDec::ET_DEC_MISSFLD
, "Missing value for component '%s'.", fld_name(fld_curr
));
3196 if (is_default_field
) next_default_idx
++;
3197 if (is_optional_field
) next_optional_idx
++;
3199 delete[] fld_indctr
;
3200 } /* SET decoding */
3202 if (is_opentype_outermost()) {
3203 TTCN_EncDec_ErrorContext
ec_1("While decoding opentypes: ");
3204 TTCN_Type_list p_typelist
;
3205 BER_decode_opentypes(p_typelist
, L_form
);
3206 } /* if sdef->opentype_outermost */
3210 void Record_Type::BER_decode_opentypes(TTCN_Type_list
& p_typelist
, unsigned L_form
)
3212 p_typelist
.push(this);
3213 TTCN_EncDec_ErrorContext
ec_0("Component '");
3214 TTCN_EncDec_ErrorContext ec_1
;
3215 int field_cnt
= get_count();
3216 for(int i
=0; i
<field_cnt
; i
++) {
3217 ec_1
.set_msg("%s': ", fld_name(i
));
3218 get_at(i
)->BER_decode_opentypes(p_typelist
, L_form
);
3223 int Record_Type::RAW_encode(const TTCN_Typedescriptor_t
& p_td
,
3224 RAW_enc_tree
& myleaf
) const
3226 if (err_descr
) return RAW_encode_negtest(err_descr
, p_td
, myleaf
);
3228 TTCN_EncDec_ErrorContext::error
3229 (TTCN_EncDec::ET_UNBOUND
, "Encoding an unbound value.");
3231 int encoded_length
= 0;
3232 int field_cnt
= get_count();
3233 myleaf
.isleaf
= false;
3234 myleaf
.body
.node
.num_of_nodes
= field_cnt
;
3235 myleaf
.body
.node
.nodes
= init_nodes_of_enc_tree(field_cnt
);
3237 int next_optional_idx
= 0;
3238 const int* optional_indexes
= get_optional_indexes();
3239 for (int i
= 0; i
< field_cnt
; i
++) {
3240 boolean is_optional_field
= optional_indexes
3241 && (optional_indexes
[next_optional_idx
] == i
);
3242 if (!is_optional_field
|| get_at(i
)->ispresent()) {
3243 myleaf
.body
.node
.nodes
[i
] = new RAW_enc_tree(true, &myleaf
,
3244 &(myleaf
.curr_pos
), i
, fld_descr(i
)->raw
);
3247 myleaf
.body
.node
.nodes
[i
] = NULL
;
3249 if (is_optional_field
) next_optional_idx
++;
3251 next_optional_idx
= 0;
3252 for (int i
= 0; i
< field_cnt
; i
++) { /*encoding fields*/
3253 boolean is_optional_field
= optional_indexes
3254 && (optional_indexes
[next_optional_idx
] == i
);
3255 /* encoding of normal fields*/
3256 const Base_Type
*field
= get_at(i
);
3257 if (is_optional_field
) {
3258 next_optional_idx
++;
3259 if (!field
->ispresent())
3260 continue; // do not encode
3262 field
= field
->get_opt_value(); // "reach into" the optional
3264 encoded_length
+= field
->RAW_encode(*fld_descr(i
),
3265 *myleaf
.body
.node
.nodes
[i
]);
3267 return myleaf
.length
= encoded_length
;
3270 // In some cases (e.g. LENGTHTO, POINTERTO, CROSSTAG) it is not generated.
3271 int Record_Type::RAW_encode_negtest(const Erroneous_descriptor_t
*p_err_descr
,
3272 const TTCN_Typedescriptor_t
& /*p_td*/, RAW_enc_tree
& myleaf
) const
3275 TTCN_EncDec_ErrorContext::error
3276 (TTCN_EncDec::ET_UNBOUND
, "Encoding an unbound value.");
3278 int encoded_length
= 0;
3279 int num_fields
= get_count();
3280 myleaf
.isleaf
= false;
3281 myleaf
.body
.node
.num_of_nodes
= 0;
3282 for (int field_idx
= 0; field_idx
< num_fields
; ++field_idx
) {
3283 if ((p_err_descr
->omit_before
!= -1) &&
3284 (field_idx
< p_err_descr
->omit_before
))
3286 else ++myleaf
.body
.node
.num_of_nodes
;
3287 const Erroneous_values_t
*err_vals
= p_err_descr
->get_field_err_values(field_idx
);
3288 if (err_vals
&& err_vals
->before
)
3289 ++myleaf
.body
.node
.num_of_nodes
;
3290 if (err_vals
&& err_vals
->value
&& !err_vals
->value
->errval
)
3291 --myleaf
.body
.node
.num_of_nodes
;
3292 if (err_vals
&& err_vals
->after
)
3293 ++myleaf
.body
.node
.num_of_nodes
;
3294 if ((p_err_descr
->omit_after
!= -1) &&
3295 (field_idx
>= p_err_descr
->omit_after
))
3298 myleaf
.body
.node
.nodes
= init_nodes_of_enc_tree(myleaf
.body
.node
.num_of_nodes
);
3299 TTCN_EncDec_ErrorContext ec
;
3300 int next_optional_idx
= 0;
3301 const int *my_optional_indexes
= get_optional_indexes();
3302 // Counter for fields and additional before/after fields.
3304 for (int field_idx
= 0; field_idx
< num_fields
; ++field_idx
) {
3305 boolean is_optional_field
= my_optional_indexes
&&
3306 (my_optional_indexes
[next_optional_idx
] == field_idx
);
3307 if ((p_err_descr
->omit_before
!= -1) &&
3308 (field_idx
< p_err_descr
->omit_before
)) {
3309 if (is_optional_field
) ++next_optional_idx
;
3312 const Erroneous_values_t
*err_vals
= p_err_descr
->get_field_err_values(field_idx
);
3313 const Erroneous_descriptor_t
*emb_descr
= p_err_descr
->get_field_emb_descr(field_idx
);
3314 if (err_vals
&& err_vals
->before
) {
3315 if (err_vals
->before
->errval
== NULL
)
3316 TTCN_error("internal error: erroneous before value missing");
3317 if (err_vals
->before
->raw
) {
3318 myleaf
.body
.node
.nodes
[node_pos
] =
3319 new RAW_enc_tree(true, &myleaf
, &(myleaf
.curr_pos
), node_pos
,
3320 err_vals
->before
->errval
->get_descriptor()->raw
);
3321 encoded_length
+= err_vals
->before
->errval
->
3322 RAW_encode_negtest_raw(*myleaf
.body
.node
.nodes
[node_pos
++]);
3324 if (err_vals
->before
->type_descr
== NULL
)
3325 TTCN_error("internal error: erroneous before typedescriptor missing");
3326 myleaf
.body
.node
.nodes
[node_pos
] =
3327 new RAW_enc_tree(true, &myleaf
, &(myleaf
.curr_pos
), node_pos
,
3328 err_vals
->before
->type_descr
->raw
);
3329 encoded_length
+= err_vals
->before
->errval
->
3330 RAW_encode(*(err_vals
->before
->type_descr
),
3331 *myleaf
.body
.node
.nodes
[node_pos
++]);
3334 if (err_vals
&& err_vals
->value
) {
3335 if (err_vals
->value
->errval
) {
3336 ec
.set_msg("'%s'(erroneous value): ", fld_name(field_idx
));
3337 if (err_vals
->value
->raw
) {
3338 myleaf
.body
.node
.nodes
[node_pos
] =
3339 new RAW_enc_tree(true, &myleaf
, &(myleaf
.curr_pos
), node_pos
,
3340 err_vals
->value
->errval
->get_descriptor()->raw
);
3341 encoded_length
+= err_vals
->value
->errval
->
3342 RAW_encode_negtest_raw(*myleaf
.body
.node
.nodes
[node_pos
++]);
3344 if (err_vals
->value
->type_descr
== NULL
)
3345 TTCN_error("internal error: erroneous value typedescriptor missing");
3346 myleaf
.body
.node
.nodes
[node_pos
] =
3347 new RAW_enc_tree(true, &myleaf
, &(myleaf
.curr_pos
), node_pos
,
3348 err_vals
->value
->type_descr
->raw
);
3349 encoded_length
+= err_vals
->value
->errval
->
3350 RAW_encode(*(err_vals
->value
->type_descr
),
3351 *myleaf
.body
.node
.nodes
[node_pos
++]);
3355 ec
.set_msg("'%s': ", fld_name(field_idx
));
3356 if (!is_optional_field
|| get_at(field_idx
)->ispresent()) {
3357 const Base_Type
*field
=
3358 is_optional_field
? get_at(field_idx
)->get_opt_value()
3359 : get_at(field_idx
);
3360 myleaf
.body
.node
.nodes
[node_pos
] =
3361 new RAW_enc_tree(true, &myleaf
, &(myleaf
.curr_pos
), node_pos
,
3362 fld_descr(field_idx
)->raw
);
3365 field
->RAW_encode_negtest(emb_descr
, *fld_descr(field_idx
),
3366 *myleaf
.body
.node
.nodes
[node_pos
++]);
3369 field
->RAW_encode(*fld_descr(field_idx
),
3370 *myleaf
.body
.node
.nodes
[node_pos
++]);
3374 myleaf
.body
.node
.nodes
[node_pos
++] = NULL
;
3377 if (err_vals
&& err_vals
->after
) {
3378 if (err_vals
->after
->errval
== NULL
)
3379 TTCN_error("internal error: erroneous before value missing");
3380 if (err_vals
->after
->raw
) {
3381 myleaf
.body
.node
.nodes
[node_pos
] =
3382 new RAW_enc_tree(true, &myleaf
, &(myleaf
.curr_pos
), node_pos
,
3383 err_vals
->after
->errval
->get_descriptor()->raw
);
3384 encoded_length
+= err_vals
->after
->errval
->
3385 RAW_encode_negtest_raw(*myleaf
.body
.node
.nodes
[node_pos
++]);
3387 if (err_vals
->after
->type_descr
== NULL
)
3388 TTCN_error("internal error: erroneous after typedescriptor missing");
3389 myleaf
.body
.node
.nodes
[node_pos
] =
3390 new RAW_enc_tree(true, &myleaf
, &(myleaf
.curr_pos
), node_pos
,
3391 err_vals
->after
->type_descr
->raw
);
3392 encoded_length
+= err_vals
->after
->errval
->
3393 RAW_encode(*(err_vals
->after
->type_descr
),
3394 *myleaf
.body
.node
.nodes
[node_pos
++]);
3397 if (is_optional_field
) ++next_optional_idx
;
3398 if ((p_err_descr
->omit_after
!= -1) &&
3399 (field_idx
>= p_err_descr
->omit_after
))
3402 return myleaf
.length
= encoded_length
;
3405 int Record_Type::RAW_decode(const TTCN_Typedescriptor_t
& p_td
, TTCN_Buffer
& buff
,
3406 int limit
, raw_order_t top_bit_ord
, boolean no_err
, int, boolean
)
3408 int field_cnt
= get_count();
3409 int opt_cnt
= optional_count();
3410 int mand_num
= field_cnt
- opt_cnt
; // expected mandatory fields
3412 raw_order_t local_top_order
;
3413 if (p_td
.raw
->top_bit_order
== TOP_BIT_INHERITED
) local_top_order
= top_bit_ord
;
3414 else if (p_td
.raw
->top_bit_order
== TOP_BIT_RIGHT
) local_top_order
= ORDER_MSB
;
3415 else local_top_order
= ORDER_LSB
;
3417 if (is_set()) { /* set decoder start*/
3418 int prepaddlength
= buff
.increase_pos_padd(p_td
.raw
->prepadding
);
3419 limit
-= prepaddlength
;
3420 int decoded_length
= 0;
3421 int * const field_map
= new int[field_cnt
];
3422 memset(field_map
, 0, field_cnt
* sizeof(int));
3423 int nof_mand_fields
= 0; // mandatory fields actually decoded
3425 const int* optional_indexes
= get_optional_indexes();
3426 for (int i
=0; i
<opt_cnt
; i
++) get_at(optional_indexes
[i
])->set_to_omit();
3429 size_t fl_start_pos
= buff
.get_pos_bit();
3430 int next_optional_idx
= 0;
3431 const int* optional_indexes
= get_optional_indexes();
3432 for (int i
=0; i
<field_cnt
; i
++) { /* decoding fields without TAG */
3433 boolean is_optional_field
= optional_indexes
&& (optional_indexes
[next_optional_idx
]==i
);
3434 if (field_map
[i
] == 0) {
3435 Base_Type
* field_ptr
= get_at(i
);
3436 if (is_optional_field
) {
3437 field_ptr
->set_to_present();
3438 field_ptr
=field_ptr
->get_opt_value();
3440 int decoded_field_length
= field_ptr
->RAW_decode(*fld_descr(i
), buff
,
3441 limit
, local_top_order
, TRUE
);
3442 if ( (is_optional_field
&& (decoded_field_length
>0)) ||
3443 (!is_optional_field
&& (decoded_field_length
>=0)) ) {
3444 decoded_length
+= decoded_field_length
;
3445 limit
-= decoded_field_length
;
3446 if (!is_optional_field
) nof_mand_fields
++;
3448 goto continue_while
;
3450 buff
.set_pos_bit(fl_start_pos
);
3451 if (is_optional_field
) get_at(i
)->set_to_omit();
3454 if (is_optional_field
) next_optional_idx
++;
3456 break; // no field could be decoded successfully, quit
3460 if (mand_num
> 0 && nof_mand_fields
!= mand_num
) {
3461 /* Not all required fields were decoded. If there are no bits left,
3462 * that means that the last field was decoded successfully but used up
3463 * the buffer. Signal "incomplete". If there were bits left, that means
3464 * no field could be decoded from them; signal an error. */
3465 return limit
? -1 : -TTCN_EncDec::ET_INCOMPL_MSG
;
3467 return decoded_length
+ prepaddlength
+ buff
.increase_pos_padd(p_td
.raw
->padding
);
3468 } else { /* record decoder start */
3469 int prepaddlength
= buff
.increase_pos_padd(p_td
.raw
->prepadding
);
3470 limit
-= prepaddlength
;
3471 size_t last_decoded_pos
= buff
.get_pos_bit();
3472 size_t fl_start_pos
;
3473 int decoded_length
= 0;
3474 int decoded_field_length
= 0;
3475 if (raw_has_ext_bit()) {
3476 const unsigned char* data
=buff
.get_read_data();
3478 unsigned mask
= 1 << (local_top_order
==ORDER_LSB
? 0 : 7);
3479 if (p_td
.raw
->extension_bit
==EXT_BIT_YES
) {
3480 while((data
[count
-1] & mask
) == 0 && count
* 8 < (int)limit
) count
++;
3483 while((data
[count
-1] & mask
) != 0 && count
* 8 < (int)limit
) count
++;
3485 if(limit
) limit
=count
*8;
3488 int next_optional_idx
= 0;
3489 const int* optional_indexes
= get_optional_indexes();
3490 for (int i
=0; i
<field_cnt
; i
++) { /* decoding fields */
3491 boolean is_optional_field
= optional_indexes
&& (optional_indexes
[next_optional_idx
]==i
);
3492 /* check if enough bits to decode the field*/
3493 if (!is_optional_field
|| (limit
>0)) {
3494 /* decoding of normal field */
3495 fl_start_pos
= buff
.get_pos_bit();
3496 Base_Type
* field_ptr
= get_at(i
);
3497 if (is_optional_field
) {
3498 field_ptr
->set_to_present();
3499 field_ptr
=field_ptr
->get_opt_value();
3501 decoded_field_length
= field_ptr
->RAW_decode(*fld_descr(i
), buff
, limit
,
3502 local_top_order
, is_optional_field
? TRUE
: no_err
);
3503 boolean field_present
= TRUE
;
3504 if (is_optional_field
) {
3505 if (decoded_field_length
< 1) { // swallow any error and become omit
3506 field_present
= FALSE
;
3507 get_at(i
)->set_to_omit();
3508 buff
.set_pos_bit(fl_start_pos
);
3511 if (decoded_field_length
< 0) return decoded_field_length
;
3513 if (field_present
) {
3514 decoded_length
+=decoded_field_length
;
3515 limit
-=decoded_field_length
;
3516 last_decoded_pos
=last_decoded_pos
<buff
.get_pos_bit()?buff
.get_pos_bit():last_decoded_pos
;
3519 get_at(i
)->set_to_omit();
3521 if (is_optional_field
) next_optional_idx
++;
3522 } /* decoding fields*/
3524 buff
.set_pos_bit(last_decoded_pos
);
3525 return decoded_length
+prepaddlength
+buff
.increase_pos_padd(p_td
.raw
->padding
);
3526 } /* record decoder end*/
3529 int Record_Type::TEXT_encode(const TTCN_Typedescriptor_t
& p_td
, TTCN_Buffer
& buff
) const
3532 return TEXT_encode_negtest(err_descr
, p_td
, buff
);
3535 TTCN_EncDec_ErrorContext::error
3536 (TTCN_EncDec::ET_UNBOUND
, "Encoding an unbound value.");
3538 bool need_separator
=false;
3539 int encoded_length
=0;
3540 if (p_td
.text
->begin_encode
) {
3541 buff
.put_cs(*p_td
.text
->begin_encode
);
3542 encoded_length
+=p_td
.text
->begin_encode
->lengthof();
3544 int next_optional_idx
= 0;
3545 const int* optional_indexes
= get_optional_indexes();
3546 int field_cnt
= get_count();
3547 for(int i
=0;i
<field_cnt
;i
++) {
3548 boolean is_optional_field
= optional_indexes
&& (optional_indexes
[next_optional_idx
]==i
);
3549 if (!is_optional_field
|| get_at(i
)->ispresent()) {
3550 if (need_separator
&& p_td
.text
->separator_encode
) {
3551 buff
.put_cs(*p_td
.text
->separator_encode
);
3552 encoded_length
+=p_td
.text
->separator_encode
->lengthof();
3554 encoded_length
+= get_at(i
)->TEXT_encode(*fld_descr(i
),buff
);
3555 need_separator
=true;
3557 if (is_optional_field
) next_optional_idx
++;
3559 if (p_td
.text
->end_encode
) {
3560 buff
.put_cs(*p_td
.text
->end_encode
);
3561 encoded_length
+=p_td
.text
->end_encode
->lengthof();
3563 return encoded_length
;
3567 * TEXT encode negative testing
3569 int Record_Type::TEXT_encode_negtest(const Erroneous_descriptor_t
* p_err_descr
, const TTCN_Typedescriptor_t
& p_td
, TTCN_Buffer
& buff
) const
3572 TTCN_EncDec_ErrorContext::error
3573 (TTCN_EncDec::ET_UNBOUND
, "Encoding an unbound value.");
3575 bool need_separator
=false;
3576 int encoded_length
=0;
3577 if (p_td
.text
->begin_encode
) {
3578 buff
.put_cs(*p_td
.text
->begin_encode
);
3579 encoded_length
+=p_td
.text
->begin_encode
->lengthof();
3581 int next_optional_idx
= 0;
3582 const int* optional_indexes
= get_optional_indexes();
3583 int field_cnt
= get_count();
3588 for(int i
=0;i
<field_cnt
;i
++) {
3589 boolean is_optional_field
= optional_indexes
&& (optional_indexes
[next_optional_idx
]==i
);
3591 if ( (p_err_descr
->omit_before
!=-1) && (i
<p_err_descr
->omit_before
) ) {
3592 if (is_optional_field
) next_optional_idx
++;
3596 const Erroneous_values_t
* err_vals
= p_err_descr
->next_field_err_values(i
, values_idx
);
3597 const Erroneous_descriptor_t
* emb_descr
= p_err_descr
->next_field_emb_descr(i
, edescr_idx
);
3599 if (err_vals
&& err_vals
->before
) {
3600 if (err_vals
->before
->errval
==NULL
) TTCN_error(
3601 "internal error: erroneous before value missing");
3603 if (need_separator
&& p_td
.text
->separator_encode
) {
3604 buff
.put_cs(*p_td
.text
->separator_encode
);
3605 encoded_length
+=p_td
.text
->separator_encode
->lengthof();
3607 if (err_vals
->before
->raw
) {
3608 encoded_length
+= err_vals
->before
->errval
->encode_raw(buff
);
3610 if (err_vals
->before
->type_descr
==NULL
) TTCN_error(
3611 "internal error: erroneous before typedescriptor missing");
3612 encoded_length
+= err_vals
->before
->errval
->TEXT_encode(
3613 *(err_vals
->before
->type_descr
),buff
);
3615 need_separator
=true;
3618 if (err_vals
&& err_vals
->value
) {
3619 if (err_vals
->value
->errval
) {
3620 if (need_separator
&& p_td
.text
->separator_encode
) {
3621 buff
.put_cs(*p_td
.text
->separator_encode
);
3622 encoded_length
+=p_td
.text
->separator_encode
->lengthof();
3624 if (err_vals
->value
->raw
) {
3625 encoded_length
+= err_vals
->value
->errval
->encode_raw(buff
);
3627 if (err_vals
->value
->type_descr
==NULL
) TTCN_error(
3628 "internal error: erroneous value typedescriptor missing");
3629 encoded_length
+= err_vals
->value
->errval
->TEXT_encode(
3630 *(err_vals
->value
->type_descr
),buff
);
3632 need_separator
=true;
3635 if (!is_optional_field
|| get_at(i
)->ispresent()) {
3636 if (need_separator
&& p_td
.text
->separator_encode
) {
3637 buff
.put_cs(*p_td
.text
->separator_encode
);
3638 encoded_length
+=p_td
.text
->separator_encode
->lengthof();
3641 encoded_length
+= get_at(i
)->TEXT_encode_negtest(emb_descr
, *fld_descr(i
),buff
);
3643 encoded_length
+= get_at(i
)->TEXT_encode(*fld_descr(i
),buff
);
3645 need_separator
=true;
3649 if (err_vals
&& err_vals
->after
) {
3650 if (err_vals
->after
->errval
==NULL
) TTCN_error(
3651 "internal error: erroneous after value missing");
3652 if (need_separator
&& p_td
.text
->separator_encode
) {
3653 buff
.put_cs(*p_td
.text
->separator_encode
);
3654 encoded_length
+=p_td
.text
->separator_encode
->lengthof();
3656 if (err_vals
->after
->raw
) {
3657 encoded_length
+= err_vals
->after
->errval
->encode_raw(buff
);
3659 if (err_vals
->after
->type_descr
==NULL
) TTCN_error(
3660 "internal error: erroneous after typedescriptor missing");
3661 encoded_length
+= err_vals
->after
->errval
->TEXT_encode(
3662 *(err_vals
->after
->type_descr
),buff
);
3664 need_separator
=true;
3667 if (is_optional_field
) next_optional_idx
++;
3669 if ( (p_err_descr
->omit_after
!=-1) && (i
>=p_err_descr
->omit_after
) ) break;
3671 if (p_td
.text
->end_encode
) {
3672 buff
.put_cs(*p_td
.text
->end_encode
);
3673 encoded_length
+=p_td
.text
->end_encode
->lengthof();
3675 return encoded_length
;
3678 int Record_Type::TEXT_decode(const TTCN_Typedescriptor_t
& p_td
, TTCN_Buffer
& buff
,
3679 Limit_Token_List
& limit
, boolean no_err
, boolean
/*first_call*/)
3682 int decoded_length
=0;
3683 int decoded_field_length
=0;
3684 size_t pos
=buff
.get_pos();
3685 boolean sep_found
=FALSE
;
3688 int loop_detector
=1;
3689 int last_field_num
=-1;
3690 if (p_td
.text
->begin_decode
) {
3692 if ((tl
=p_td
.text
->begin_decode
->match_begin(buff
))<0) {
3693 if(no_err
) return -1;
3694 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR
,
3695 "The specified token '%s' not found for '%s': ",
3696 (const char*)*(p_td
.text
->begin_decode
), p_td
.name
);
3700 buff
.increase_pos(tl
);
3702 if (p_td
.text
->end_decode
) {
3703 limit
.add_token(p_td
.text
->end_decode
);
3706 if(p_td
.text
->separator_decode
){
3707 limit
.add_token(p_td
.text
->separator_decode
);
3711 int field_cnt
= get_count();
3712 int * const field_map
= new int[field_cnt
];
3713 memset(field_map
, 0, field_cnt
* sizeof(int));
3715 int mand_field_num
= 0;
3716 int opt_field_num
= 0;
3718 int has_repeatable
=0;
3719 boolean repeatable
= TRUE
;
3721 int next_optional_idx
= 0;
3722 const int* optional_indexes
= get_optional_indexes();
3723 for (int i
=0;i
<field_cnt
;i
++) {
3724 boolean is_optional_field
= optional_indexes
&& (optional_indexes
[next_optional_idx
]==i
);
3725 if (is_optional_field
) {
3726 get_at(i
)->set_to_omit();
3731 if (get_at(i
)->is_seof()) {
3733 repeatable
= repeatable
&& fld_descr(i
)->text
->val
.parameters
->decoding_params
.repeatable
;
3735 if (is_optional_field
) next_optional_idx
++;
3737 boolean has_optinals
= opt_field_num
> 0;
3738 if ((seof
>0) && repeatable
) has_repeatable
=1;
3740 while (mand_field_num
+opt_field_num
+has_repeatable
) {
3744 next_optional_idx
= 0;
3745 for (int i
=0;i
<field_cnt
;i
++) {
3746 boolean is_optional_field
= optional_indexes
&& (optional_indexes
[next_optional_idx
]==i
);
3747 if (get_at(i
)->is_seof()) {
3748 if ( (fld_descr(i
)->text
->val
.parameters
->decoding_params
.repeatable
&& field_map
[i
]<3)
3749 || !field_map
[i
] ) {
3751 decoded_field_length
= get_at(i
)->TEXT_decode(*fld_descr(i
),buff
, limit
, true,!field_map
[i
]);
3752 if (decoded_field_length
<0) {
3754 if (is_optional_field
&& !field_map
[i
]) get_at(i
)->set_to_omit();
3757 if (!field_map
[i
]) {
3758 if (is_optional_field
) opt_field_num
--;
3759 else mand_field_num
--;
3761 } else field_map
[i
]=2;
3766 } else { // !...->is_seof
3767 if (!field_map
[i
]) {
3769 decoded_field_length
= get_at(i
)->TEXT_decode(*fld_descr(i
),buff
,limit
,true);
3770 if (decoded_field_length
<0) {
3772 if (is_optional_field
) get_at(i
)->set_to_omit();
3776 if (is_optional_field
) opt_field_num
--;
3777 else mand_field_num
--;
3783 if (is_optional_field
) next_optional_idx
++;
3787 if (loop_detector
) break;
3788 if (p_td
.text
->separator_decode
) {
3790 if ((tl
=p_td
.text
->separator_decode
->match_begin(buff
))<0) {
3791 if (p_td
.text
->end_decode
) {
3793 if ((tl2
=p_td
.text
->end_decode
->match_begin(buff
))!=-1) {
3797 } else if (limit
.has_token(ml
)) {
3799 if ((tl2
=limit
.match(buff
,ml
))==0) {
3805 decoded_length
-=decoded_field_length
;
3806 field_map
[last_field_num
]+=2;
3809 if (last_field_num
>=0 && last_field_num
<field_cnt
) {
3810 if (get_at(last_field_num
)->is_seof()) {
3811 if (get_at(last_field_num
)->is_optional()) {
3812 if (field_map
[last_field_num
]==3) {
3813 get_at(last_field_num
)->set_to_omit();
3817 if (field_map
[last_field_num
]==3) {
3821 } else if (get_at(last_field_num
)->is_optional()) {
3822 get_at(last_field_num
)->set_to_omit();
3830 } // if (has_optinals)
3834 buff
.increase_pos(tl
);
3835 for (int a
=0;a
<field_cnt
;a
++) if(field_map
[a
]>2) field_map
[a
]-=3;
3838 } else if (p_td
.text
->end_decode
) {
3840 if ((tl
=p_td
.text
->end_decode
->match_begin(buff
))!=-1) {
3842 buff
.increase_pos(tl
);
3843 limit
.remove_tokens(ml
);
3844 if (mand_field_num
) decoded_length
= -1;
3847 } else if(limit
.has_token(ml
)){
3849 if ((tl
=limit
.match(buff
,ml
))==0) {
3855 limit
.remove_tokens(ml
);
3857 if (mand_field_num
) {
3858 if (no_err
) decoded_length
= -1;
3859 else TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR
,
3860 "Error during decoding '%s': ", p_td
.name
);
3863 decoded_length
-=sep_length
;
3864 buff
.set_pos(buff
.get_pos()-sep_length
);
3867 if (p_td
.text
->end_decode
) {
3869 if ((tl
=p_td
.text
->end_decode
->match_begin(buff
))<0) {
3870 if (no_err
) decoded_length
= -1;
3871 else TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR
,
3872 "The specified token '%s' not found for '%s': ",
3873 (const char*)*(p_td
.text
->end_decode
),p_td
.name
);
3877 buff
.increase_pos(tl
);
3879 if (mand_field_num
) decoded_length
= -1;
3882 return decoded_length
;
3883 } else { // record decoder
3884 int decoded_length
=0;
3885 int decoded_field_length
=0;
3886 size_t pos
=buff
.get_pos();
3887 boolean sep_found
=FALSE
;
3890 if (p_td
.text
->begin_decode
) {
3892 if ((tl
=p_td
.text
->begin_decode
->match_begin(buff
))<0) {
3893 if(no_err
)return -1;
3894 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR
,
3895 "The specified token '%s' not found for '%s': ",
3896 (const char*)*(p_td
.text
->begin_decode
), p_td
.name
);
3900 buff
.increase_pos(tl
);
3902 if (p_td
.text
->end_decode
) {
3903 limit
.add_token(p_td
.text
->end_decode
);
3906 if (p_td
.text
->separator_decode
) {
3907 limit
.add_token(p_td
.text
->separator_decode
);
3911 int mand_field_num
= 0;
3912 int opt_field_num
= 0;
3913 int last_man_index
= 0;
3915 int field_cnt
= get_count();
3916 int next_optional_idx
= 0;
3917 const int* optional_indexes
= get_optional_indexes();
3918 for (int i
=0;i
<field_cnt
;i
++) {
3919 boolean is_optional_field
= optional_indexes
&& (optional_indexes
[next_optional_idx
]==i
);
3920 if (is_optional_field
) {
3921 get_at(i
)->set_to_omit();
3927 if (is_optional_field
) next_optional_idx
++;
3930 next_optional_idx
= 0;
3931 for(int i
=0;i
<field_cnt
;i
++) {
3932 boolean is_optional_field
= optional_indexes
&& (optional_indexes
[next_optional_idx
]==i
);
3933 if (is_optional_field
) {
3936 decoded_field_length
= get_at(i
)->TEXT_decode(*fld_descr(i
),buff
,limit
,TRUE
);
3937 if (decoded_field_length
<0) {
3938 if (is_optional_field
) {
3939 get_at(i
)->set_to_omit();
3942 limit
.remove_tokens(ml
);
3943 if (no_err
) return -1;
3944 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR
,
3945 "Error during decoding field '%s' for '%s': ",
3946 fld_descr(i
)->name
, p_td
.name
);
3947 return decoded_length
;
3950 decoded_length
+=decoded_field_length
;
3951 if (last_man_index
>(i
+1)) {
3952 if (p_td
.text
->separator_decode
) {
3954 if ((tl
=p_td
.text
->separator_decode
->match_begin(buff
))<0) {
3955 if(is_optional_field
) {
3956 get_at(i
)->set_to_omit();
3958 decoded_length
-=decoded_field_length
;
3960 limit
.remove_tokens(ml
);
3961 if(no_err
)return -1;
3962 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR
,
3963 "The specified token '%s' not found for '%s': ",
3964 (const char*)*(p_td
.text
->separator_decode
),p_td
.name
);
3965 return decoded_length
;
3969 buff
.increase_pos(tl
);
3973 } else sep_found
=FALSE
;
3975 } else if (i
==(field_cnt
-1)) {
3978 if (p_td
.text
->separator_decode
) {
3980 if ((tl
=p_td
.text
->separator_decode
->match_begin(buff
))<0) {
3981 if (is_optional_field
) {
3982 if (p_td
.text
->end_decode
) {
3983 if ((tl
=p_td
.text
->end_decode
->match_begin(buff
))!=-1) {
3985 buff
.increase_pos(tl
);
3986 limit
.remove_tokens(ml
);
3987 return decoded_length
;
3989 } else if (limit
.has_token(ml
)) {
3990 if ((tl
=limit
.match(buff
,ml
))==0) {
3995 get_at(i
)->set_to_omit();
3997 decoded_length
-=decoded_field_length
;
4004 buff
.increase_pos(tl
);
4011 if (p_td
.text
->end_decode
) {
4012 if ((tl
=p_td
.text
->end_decode
->match_begin(buff
))!=-1) {
4014 buff
.increase_pos(tl
);
4015 limit
.remove_tokens(ml
);
4016 return decoded_length
;
4018 } else if (limit
.has_token(ml
)) {
4019 if ((tl
=limit
.match(buff
,ml
))==0) {
4027 if (is_optional_field
) next_optional_idx
++;
4029 limit
.remove_tokens(ml
);
4031 buff
.set_pos(buff
.get_pos()-sep_length
);
4032 decoded_length
-=sep_length
;
4034 if (p_td
.text
->end_decode
) {
4036 if ((tl
=p_td
.text
->end_decode
->match_begin(buff
))<0) {
4037 if(no_err
)return -1;
4038 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR
,
4039 "The specified token '%s' not found for '%s': ",
4040 (const char*)*(p_td
.text
->end_decode
),p_td
.name
);
4041 return decoded_length
;
4044 buff
.increase_pos(tl
);
4046 return decoded_length
;
4050 const XERdescriptor_t
* Record_Type::xer_descr(int /*field_index*/) const
4052 TTCN_error("Internal error: Record_Type::xer_descr() called.");
4056 char ** Record_Type::collect_ns(const XERdescriptor_t
& p_td
, size_t& num
, bool& def_ns
) const
4058 const int field_cnt
= get_count();
4059 // The USE-ORDER member is first, unless preempted by EMBED-VALUES
4060 const int uo_index
= ((p_td
.xer_bits
& EMBED_VALUES
) !=0);
4061 // Index of the first "normal" member (after E-V and U-O)
4062 const int start_at
= uo_index
+ ((p_td
.xer_bits
& USE_ORDER
) != 0);
4064 size_t num_collected
= 0;
4065 // First, our own namespace. Sets num_collected to 0 or 1.
4066 // If it throws, nothing was allocated.
4067 char **collected_ns
= Base_Type::collect_ns(p_td
, num_collected
, def_ns
);
4070 // If the nil attribute will be written, add the control namespace
4071 boolean nil_attribute
= (p_td
.xer_bits
& USE_NIL
)
4072 && !get_at(field_cnt
-1)->ispresent();
4074 if (nil_attribute
) {
4075 collected_ns
= (char**)Realloc(collected_ns
, sizeof(char*) * ++num_collected
);
4076 const namespace_t
*c_ns
= p_td
.my_module
->get_controlns();
4078 collected_ns
[num_collected
-1] = mprintf(" xmlns:%s='%s'", c_ns
->px
, c_ns
->ns
);
4081 // Collect namespace declarations from all components (recursively).
4082 // This is extremely nasty, but we can't prosecute you for that.
4083 // (Monty Python - Crunchy Frog sketch). This whole thing is O(n^3). Yuck.
4084 for (int a
= start_at
; a
< field_cnt
; ++a
) {
4086 bool def_ns_1
= false;
4087 char **new_namespaces
= get_at(a
)->collect_ns(*xer_descr(a
), num_new
, def_ns_1
);
4088 merge_ns(collected_ns
, num_collected
, new_namespaces
, num_new
);
4089 def_ns
= def_ns
|| def_ns_1
;
4090 // merge_ns freed new_namespaces
4094 // Probably a TC_Error thrown from the element's collect_ns(),
4095 // e.g. if encoding an unbound value.
4096 while (num_collected
> 0) Free(collected_ns
[--num_collected
]);
4101 num
= num_collected
;
4102 return collected_ns
;
4105 // FIXME some hashing should be implemented
4106 int Record_Type::get_index_byname(const char *name
, const char *uri
) const {
4107 int num_fields
= get_count();
4108 for (int i
= 0; i
< num_fields
; ++i
) {
4109 const XERdescriptor_t
& xer
= *xer_descr(i
);
4110 if (check_name(name
, xer
, TRUE
)
4111 && check_namespace(uri
, xer
)) return i
;
4116 int Record_Type::XER_encode(const XERdescriptor_t
& p_td
, TTCN_Buffer
& p_buf
,
4117 unsigned int flavor
, int indent
, embed_values_enc_struct_t
*) const
4120 return XER_encode_negtest(err_descr
, p_td
, p_buf
, flavor
, indent
, 0);
4123 TTCN_EncDec_ErrorContext::error
4124 (TTCN_EncDec::ET_UNBOUND
, "Encoding an unbound value.");
4127 TTCN_EncDec_ErrorContext
ec_0("Component '");
4128 TTCN_EncDec_ErrorContext ec_1
;
4129 int encoded_length
=(int)p_buf
.get_len(); // how much is already in the buffer
4131 int exer
= is_exer(flavor
);
4132 if (exer
&& (p_td
.xer_bits
& EMBED_VALUES
)) flavor
|= XER_CANONICAL
;
4133 const boolean indenting
= !is_canonical(flavor
);
4134 const int field_cnt
= get_count();
4135 const int num_attributes
= get_xer_num_attr();
4136 // The USE-ORDER member is first, unless preempted by EMBED-VALUES
4137 const int uo_index
= ((p_td
.xer_bits
& EMBED_VALUES
) !=0);
4138 // Index of the first "normal" member (after E-V and U-O)
4139 const int start_at
= uo_index
+ ((p_td
.xer_bits
& USE_ORDER
) != 0);
4140 const int first_nonattr
= start_at
+ num_attributes
;
4141 // start_tag_len is keeping track of how much was written at the end of the
4142 // start tag, i.e. the ">\n". This is used later to "back up" over it.
4143 int start_tag_len
= 1 + indenting
;
4144 // The EMBED-VALUES member, if applicable
4145 const Record_Of_Type
* embed_values
= 0;
4146 if (p_td
.xer_bits
& EMBED_VALUES
) {
4147 embed_values
= dynamic_cast<const Record_Of_Type
*>(get_at(0));
4148 if (NULL
== embed_values
) {
4149 const OPTIONAL
<Record_Of_Type
>* const embed_opt
= static_cast<const OPTIONAL
<Record_Of_Type
>*>(get_at(0));
4150 if(embed_opt
->is_present()) {
4151 embed_values
= &(*embed_opt
)();
4155 // The USE-ORDER member, if applicable
4156 const Record_Of_Type
* const use_order
= (p_td
.xer_bits
& USE_ORDER
)
4157 ? static_cast<const Record_Of_Type
*>(get_at(uo_index
)) : 0;
4159 size_t num_collected
= 0; // we use this to compute delay_close
4160 char **collected_ns
= NULL
;
4161 bool def_ns
= false;
4163 if (indent
== 0) { // top-level type
4164 collected_ns
= collect_ns(p_td
, num_collected
, def_ns
);
4166 else if ((flavor
& DEF_NS_SQUASHED
) && p_td
.my_module
&& p_td
.ns_index
!= -1) {
4167 const namespace_t
* ns
= p_td
.my_module
->get_ns(p_td
.ns_index
);
4168 // The default namespace has been squashed.
4169 // If we are in the default namespace, restore it.
4170 if (*ns
->px
== '\0') {
4171 collected_ns
= Base_Type::collect_ns(p_td
, num_collected
, def_ns
);
4176 // The type's own tag is omitted if we're doing E-XER,
4177 // and it's not the top-level type (XML must have a root element)
4178 // and it's either UNTAGGED or got USE_NIL or USE_TYPE or USE_UNION.
4179 boolean omit_tag
= exer
&& (indent
> 0)
4180 && ( (p_td
.xer_bits
& (UNTAGGED
|XER_ATTRIBUTE
))
4181 || (flavor
& (USE_NIL
|USE_TYPE_ATTR
)));
4183 // If a default namespace is in effect (uri but no prefix) and the type
4184 // is unqualified, the default namespace must be canceled; otherwise
4185 // an XML tag without a ns prefix looks like it belongs to the def.namespace
4186 const boolean empty_ns_hack
= exer
&& !omit_tag
&& (indent
> 0)
4187 && (p_td
.xer_bits
& FORM_UNQUALIFIED
)
4188 && (flavor
& DEF_NS_PRESENT
);
4190 // delay_close=true if there is stuff before the '>' of the start tag
4191 // (prevents writing the '>' which is built into the name).
4192 // This can only happen for EXER: if there are attributes or namespaces,
4193 // or either USE-NIL or USE-QNAME is set.
4194 boolean delay_close
= exer
&& (num_attributes
4195 || empty_ns_hack
// counts as having a namespace
4196 || (num_collected
!= 0)
4197 || (p_td
.xer_bits
& (USE_NIL
|USE_QNAME
))
4198 || (flavor
& USE_NIL
));
4202 if (!omit_tag
) { /* write start tag */
4203 if (indenting
) do_indent(p_buf
, indent
);
4204 /* name looks like this: "tagname>\n"
4205 * lose the \n if : not indenting or (single untagged(*) or attributes (*)) AND exer
4206 * lose the > if attributes are present (*) AND exer
4209 if (exer
) write_ns_prefix(p_td
, p_buf
);
4210 p_buf
.put_s((size_t)p_td
.namelens
[exer
] - delay_close
4211 - (!indenting
|| delay_close
|| (exer
&& (p_td
.xer_bits
& HAS_1UNTAGGED
))),
4212 (cbyte
*)p_td
.names
[exer
]);
4214 else if (flavor
& (USE_NIL
|USE_TYPE_ATTR
)) {
4215 // reopen the parent's start tag by overwriting the '>'
4216 size_t buf_len
= p_buf
.get_len();
4217 const unsigned char * const buf_data
= p_buf
.get_data();
4218 if (buf_data
[buf_len
- 1 - shorter
] == '\n') ++shorter
;
4219 if (buf_data
[buf_len
- 1 - shorter
] == '>' ) ++shorter
;
4222 p_buf
.increase_length(-shorter
);
4228 // mask out extra flags we received, do not send them to the fields
4231 if (exer
&& (p_td
.xer_bits
& USE_QNAME
)) { // QName trumps everything
4232 const Base_Type
* const q_uri
= get_at(0);
4233 if (q_uri
->is_present()) {
4234 p_buf
.put_s(11, (cbyte
*)" xmlns:b0='");
4235 q_uri
->XER_encode(*xer_descr(0), p_buf
, flavor
| XER_LIST
, indent
+1, 0);
4239 if (p_td
.xer_bits
& XER_ATTRIBUTE
) begin_attribute(p_td
, p_buf
);
4240 else p_buf
.put_c('>');
4242 if (q_uri
->is_present()) {
4243 p_buf
.put_s(3, (cbyte
*)"b0:");
4246 const Base_Type
* const q_name
= get_at(1);
4247 sub_len
+= q_name
->XER_encode(*xer_descr(1), p_buf
, flavor
| XER_LIST
, indent
+1, 0);
4248 if (p_td
.xer_bits
& XER_ATTRIBUTE
) p_buf
.put_c('\'');
4250 else { // not USE-QNAME
4251 if (!exer
&& (p_td
.xer_bits
& EMBED_VALUES
) && embed_values
!= NULL
) {
4252 // The EMBED-VALUES member as an ordinary record of string
4253 sub_len
+= embed_values
->XER_encode(*xer_descr(0), p_buf
, flavor
, indent
+1, 0);
4256 if (!exer
&& (p_td
.xer_bits
& USE_ORDER
)) {
4257 // The USE-ORDER member as an ordinary record of enumerated
4258 sub_len
+= use_order
->XER_encode(*xer_descr(uo_index
), p_buf
, flavor
, indent
+1, 0);
4261 if (exer
&& (indent
==0 || (flavor
& DEF_NS_SQUASHED
))) // write namespaces for toplevel only
4263 for (size_t cur_coll
= 0; cur_coll
< num_collected
; ++cur_coll
) {
4264 p_buf
.put_s(strlen(collected_ns
[cur_coll
]), (cbyte
*)collected_ns
[cur_coll
]);
4265 Free(collected_ns
[cur_coll
]); // job done
4271 flavor
&= ~DEF_NS_SQUASHED
;
4272 flavor
|= DEF_NS_PRESENT
;
4274 else if (empty_ns_hack
) {
4275 p_buf
.put_s(9, (cbyte
*)" xmlns=''");
4276 flavor
&= ~DEF_NS_PRESENT
;
4277 flavor
|= DEF_NS_SQUASHED
;
4280 /* First all the attributes (not added to sub_len) */
4282 for (i
= start_at
; i
< first_nonattr
; ++i
) {
4283 boolean is_xer_attr_field
= xer_descr(i
)->xer_bits
& XER_ATTRIBUTE
;
4284 ec_1
.set_msg("%s': ", fld_name(i
)); // attr
4285 int tmp_len
= get_at(i
)->XER_encode(*xer_descr(i
), p_buf
, flavor
, indent
+1, 0);
4286 if (is_xer_attr_field
&& !exer
) sub_len
+= tmp_len
; /* do not add if attribute and EXER */
4289 // True if the "nil" attribute needs to be written.
4290 boolean nil_attribute
= exer
&& (p_td
.xer_bits
& USE_NIL
)
4291 && !get_at(field_cnt
-1)->ispresent();
4293 // True if USE_ORDER is in effect and the "nil" attribute was written.
4294 // Then the record-of-enum for USE-ORDER will be empty.
4295 boolean early_to_bed
= FALSE
;
4297 if (nil_attribute
) { // req. exer and USE_NIL
4298 const namespace_t
*control_ns
= p_td
.my_module
->get_controlns();
4300 p_buf
.put_s(strlen(control_ns
->px
),
4301 (cbyte
*)control_ns
->px
);
4303 p_buf
.put_s(10, (cbyte
*)"nil='true'");
4304 if ((p_td
.xer_bits
& USE_ORDER
)) early_to_bed
= TRUE
;
4305 // The whole content was omitted; nothing to do (and if we tried
4306 // to do it, we'd get an error for over-indexing a 0-length record-of).
4309 if (delay_close
&& (!omit_tag
|| shorter
)) {
4310 // Close the start tag left open. If indenting, also write a newline
4311 // unless USE-NIL in effect or there is a single untagged component.
4313 ((p_td
.xer_bits
& (/*USE_NIL|*/HAS_1UNTAGGED
)) ? 0 : indenting
);
4314 p_buf
.put_s(start_tag_len
, (cbyte
*)">\n");
4317 if (exer
&& (p_td
.xer_bits
& EMBED_VALUES
)) {
4318 /* write the first string */
4319 if (embed_values
!= NULL
&& embed_values
->size_of() > 0) {
4320 sub_len
+= embed_values
->get_at(0)->XER_encode(UNIVERSAL_CHARSTRING_xer_
,
4321 p_buf
, flavor
| EMBED_VALUES
, indent
+1, 0);
4325 const Record_Type
*ordered
= this; // the record affected by USE-ORDER
4327 // Index of the first non-attribute field of the record pointed to by
4328 // ordered, that is, the first field affected by USE-ORDER.
4329 size_t useorder_base
= first_nonattr
;
4332 int end
= field_cnt
;
4333 if (exer
&& (p_td
.xer_bits
& USE_ORDER
)) {
4334 const int to_send
= use_order
->size_of();
4335 // the length of the loop is determined by the length of use_order
4339 // Count the non-attribute optionals
4340 int n_optionals
= 0;
4341 for (int B
= optional_count() - 1; B
>=+0; B
--) {
4342 int oi
= get_optional_indexes()[B
];
4343 if (oi
< first_nonattr
) break;
4347 int expected_max
= field_cnt
- first_nonattr
;
4348 int expected_min
= expected_max
- n_optionals
;
4350 if ((p_td
.xer_bits
& USE_NIL
) && get_at(field_cnt
-1)->ispresent()) {
4351 // The special case when USE_ORDER refers to the fields of a field,
4353 const Base_Type
*last_optional
= get_at(field_cnt
-1);
4354 const Base_Type
* inner
= last_optional
->get_opt_value();
4355 // it absolutely, positively has to be (derived from) Record_Type
4356 ordered
= static_cast<const Record_Type
*>(inner
);
4357 useorder_base
= ordered
->get_xer_num_attr();
4358 begin
= useorder_base
;
4359 end
= ordered
->get_count();
4361 expected_min
= expected_max
= ordered
->get_count();
4364 if (to_send
> expected_max
4365 ||to_send
< expected_min
) {
4366 ec_1
.set_msg("%s': ", fld_name(uo_index
));
4367 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_CONSTRAINT
,
4368 "Wrong number of USE-ORDER %d, must be %d..%d", to_send
, expected_min
, expected_max
);
4369 begin
= end
= 0; // don't bother sending anything
4371 else { // check no duplicates
4372 int *seen
= new int [to_send
];
4374 for (int ei
= 0; ei
< to_send
; ++ei
) {
4375 const Base_Type
*uoe
= use_order
->get_at(ei
);
4376 const Enum_Type
*enm
= static_cast<const Enum_Type
*>(uoe
);
4377 int val
= enm
->as_int();
4378 for (int x
= 0; x
< num_seen
; ++x
) {
4379 if (val
== seen
[x
]) { // complain
4380 ec_1
.set_msg("%s': ", fld_name(uo_index
));
4381 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_CONSTRAINT
,
4382 "Duplicate value for USE-ORDER");
4383 begin
= end
= 0; // don't bother sending anything
4387 seen
[num_seen
++] = val
;
4391 // If the number is right and there are no duplicates, then carry on
4395 /* Then, all the non-attributes. Structuring the code like this depends on
4396 * all attributes appearing before all non-attributes (excluding
4397 * pseudo-members for USE-ORDER, etc.) */
4399 // early_to_bed can only be true if exer is true (transitive through nil_attribute)
4400 if (!early_to_bed
) {
4401 embed_values_enc_struct_t
* emb_val
= 0;
4402 if (exer
&& (p_td
.xer_bits
& EMBED_VALUES
) &&
4403 embed_values
!= NULL
&& embed_values
->size_of() > 1) {
4404 emb_val
= new embed_values_enc_struct_t
;
4405 emb_val
->embval_array
= embed_values
;
4406 emb_val
->embval_index
= 1;
4407 emb_val
->embval_err
= 0;
4410 for ( i
= begin
; i
< end
; ++i
) {
4411 const Base_Type
*uoe
= 0; // "useOrder enum"
4412 const Enum_Type
*enm
= 0; // the enum value selecting the field
4413 if (exer
&& use_order
) {
4414 uoe
= use_order
->get_at(i
- begin
);
4415 enm
= static_cast<const Enum_Type
*>(uoe
);
4418 // "actual" index, may be perturbed by USE-ORDER
4419 int ai
= !(exer
&& (p_td
.xer_bits
& USE_ORDER
)) ? i
:
4420 enm
->as_int() + useorder_base
;
4421 ec_1
.set_msg("%s': ", ordered
->fld_name(ai
)); // non-attr
4423 const XERdescriptor_t
& descr
= *ordered
->xer_descr(ai
);
4424 sub_len
+= ordered
->get_at(ai
)->XER_encode(descr
, p_buf
,
4425 // Pass USE-NIL to the last field (except when USE-ORDER is also in effect,
4426 // because the tag-stripping effect of USE-NIL has been achieved
4427 // by encoding the sub-fields directly).
4428 flavor
| ((exer
&& !use_order
&& (i
== field_cnt
-1)) ? (p_td
.xer_bits
& USE_NIL
) : 0),
4429 indent
+!omit_tag
, emb_val
);
4431 // Now the next embed-values string (NOT affected by USE-ORDER!)
4432 if (exer
&& (p_td
.xer_bits
& EMBED_VALUES
) && 0 != emb_val
&&
4433 embed_values
!= NULL
&& emb_val
->embval_index
< embed_values
->size_of()) {
4434 embed_values
->get_at(emb_val
->embval_index
)->XER_encode(UNIVERSAL_CHARSTRING_xer_
4435 , p_buf
, flavor
| EMBED_VALUES
, indent
+1, 0);
4436 ++emb_val
->embval_index
;
4441 if (embed_values
!= NULL
&& emb_val
->embval_index
< embed_values
->size_of()) {
4442 ec_1
.set_msg("%s': ", fld_name(0));
4443 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_CONSTRAINT
,
4444 "Too many EMBED-VALUEs specified: %d (expected %d or less)",
4445 embed_values
->size_of(), emb_val
->embval_index
);
4449 } // if (!early_to_bed)
4453 if (sub_len
) { // something was written, now an end tag
4454 if (indenting
&& !(exer
&& (p_td
.xer_bits
& (HAS_1UNTAGGED
| USE_QNAME
)))) {
4455 // The tags of the last optional member involved with USE_NIL
4456 // have been removed. If it was a simple type, the content was probably
4457 // written on a single line without anything resembling a close tag.
4458 // Do not indent our end tag in this case.
4459 switch ((int)(exer
&& (p_td
.xer_bits
& USE_NIL
))) {
4461 const unsigned char *buf_end
= p_buf
.get_data() + (p_buf
.get_len()-1);
4462 if (buf_end
[-1] != '>' || *buf_end
!= '\n') break;
4463 // If it does not look like an end tag, skip the indenting,
4464 // else fall through.
4467 do_indent(p_buf
, indent
);
4473 if (exer
) write_ns_prefix(p_td
, p_buf
);
4474 p_buf
.put_s((size_t)p_td
.namelens
[exer
]-!indenting
, (cbyte
*)p_td
.names
[exer
]);
4476 else { // need to generate an empty element tag
4477 p_buf
.increase_length(-start_tag_len
); // decrease length
4478 p_buf
.put_s((size_t)2+indenting
, (cbyte
*)"/>\n");
4482 return (int)p_buf
.get_len() - encoded_length
;
4485 // XERSTUFF Record_Type::encode_field
4486 /** Helper for Record_Type::XER_encode_negtest
4488 * Factored out because Record_Type::XER_encode (on which XER_encode_negtest
4489 * is based) calls the XER_encode method of the field in two places:
4490 * one for attributes, the other for elements.
4492 * @param i index of the field
4493 * @param err_vals erroneous descriptor for the field
4494 * @param emb_descr deeper erroneous values
4495 * @param p_buf buffer containing the encoded value
4496 * @param sub_flavor flags
4497 * @param indent indentation level
4498 * @return the number of bytes generated
4500 int Record_Type::encode_field(int i
,
4501 const Erroneous_values_t
* err_vals
, const Erroneous_descriptor_t
* emb_descr
,
4502 TTCN_Buffer
& p_buf
, unsigned int sub_flavor
, int indent
, embed_values_enc_struct_t
* emb_val
) const
4505 TTCN_EncDec_ErrorContext ec
;
4506 if (err_vals
&& err_vals
->before
) {
4507 if (err_vals
->before
->errval
==NULL
) TTCN_error(
4508 "internal error: erroneous before value missing");
4509 ec
.set_msg("Erroneous value before component %s: ", fld_name(i
));
4510 if (err_vals
->before
->raw
) {
4511 enc_len
+= err_vals
->before
->errval
->encode_raw(p_buf
);
4513 if (err_vals
->before
->type_descr
==NULL
) TTCN_error(
4514 "internal error: erroneous before typedescriptor missing");
4515 enc_len
+= err_vals
->before
->errval
->XER_encode(
4516 *err_vals
->before
->type_descr
->xer
, p_buf
, sub_flavor
, indent
, 0);
4520 if (err_vals
&& err_vals
->value
) {
4521 if (err_vals
->value
->errval
) { // replace
4522 ec
.set_msg("Erroneous value for component %s: ", fld_name(i
));
4523 if (err_vals
->value
->raw
) {
4524 enc_len
+= err_vals
->value
->errval
->encode_raw(p_buf
);
4526 if (err_vals
->value
->type_descr
==NULL
) TTCN_error(
4527 "internal error: erroneous value typedescriptor missing");
4528 enc_len
+= err_vals
->value
->errval
->XER_encode(
4529 *err_vals
->value
->type_descr
->xer
, p_buf
, sub_flavor
, indent
, 0);
4533 ec
.set_msg("Component %s: ", fld_name(i
));
4535 enc_len
+= get_at(i
)->XER_encode_negtest(emb_descr
, *xer_descr(i
), p_buf
,
4536 sub_flavor
, indent
, emb_val
);
4538 // the "real" encoder
4539 enc_len
+= get_at(i
)->XER_encode(*xer_descr(i
), p_buf
,
4540 sub_flavor
, indent
, emb_val
);
4544 if (err_vals
&& err_vals
->after
) {
4545 if (err_vals
->after
->errval
==NULL
) TTCN_error(
4546 "internal error: erroneous after value missing");
4547 ec
.set_msg("Erroneous value after component %s: ", fld_name(i
));
4548 if (err_vals
->after
->raw
) {
4549 enc_len
+= err_vals
->after
->errval
->encode_raw(p_buf
);
4551 if (err_vals
->after
->type_descr
==NULL
) TTCN_error(
4552 "internal error: erroneous after typedescriptor missing");
4553 enc_len
+= err_vals
->after
->errval
->XER_encode(
4554 *err_vals
->after
->type_descr
->xer
, p_buf
, sub_flavor
, indent
, 0);
4561 // XERSTUFF Record_Type::XER_encode_negtest
4562 int Record_Type::XER_encode_negtest(const Erroneous_descriptor_t
* p_err_descr
,
4563 const XERdescriptor_t
& p_td
, TTCN_Buffer
& p_buf
, unsigned int flavor
, int indent
,
4564 embed_values_enc_struct_t
*) const
4567 TTCN_EncDec_ErrorContext::error
4568 (TTCN_EncDec::ET_UNBOUND
, "Encoding an unbound value.");
4570 TTCN_EncDec_ErrorContext
ec_0("Component '");
4571 TTCN_EncDec_ErrorContext ec_1
;
4572 int encoded_length
=(int)p_buf
.get_len(); // how much is already in the buffer
4574 int exer
= is_exer(flavor
);
4575 if (exer
&& (p_td
.xer_bits
& EMBED_VALUES
)) flavor
|= XER_CANONICAL
;
4576 const boolean indenting
= !is_canonical(flavor
);
4577 const int field_cnt
= get_count();
4578 const int num_attributes
= get_xer_num_attr();
4579 // The USE-ORDER member is first, unless preempted by EMBED-VALUES
4580 const int uo_index
= ((p_td
.xer_bits
& EMBED_VALUES
) !=0);
4581 // Index of the first "normal" member (after E-V and U-O)
4582 const int start_at
= uo_index
+ ((p_td
.xer_bits
& USE_ORDER
) != 0);
4583 const int first_nonattr
= start_at
+ num_attributes
;
4584 // start_tag_len is keeping track of how much was written at the end of the
4585 // start tag, i.e. the ">\n". This is used later to "back up" over it.
4586 int start_tag_len
= 1 + indenting
;
4587 // The EMBED-VALUES member, if applicable (always first)
4588 const Record_Of_Type
* const embed_values
= (p_td
.xer_bits
& EMBED_VALUES
)
4589 ? static_cast<const Record_Of_Type
*>(get_at(0)) : 0;
4590 // The USE-ORDER member, if applicable (first unless preempted by embed_vals)
4591 const Record_Of_Type
* const use_order
= (p_td
.xer_bits
& USE_ORDER
)
4592 ? static_cast<const Record_Of_Type
*>(get_at(uo_index
)) : 0;
4597 size_t num_collected
= 0; // we use this to compute delay_close
4598 char **collected_ns
= NULL
;
4599 bool def_ns
= false;
4601 if (indent
== 0) { // top-level type
4602 collected_ns
= collect_ns(p_td
, num_collected
, def_ns
);
4604 else if ((flavor
& DEF_NS_SQUASHED
) && p_td
.my_module
&& p_td
.ns_index
!= -1) {
4605 const namespace_t
* ns
= p_td
.my_module
->get_ns(p_td
.ns_index
);
4606 // The default namespace has been squashed.
4607 // If we are in the default namespace, restore it.
4608 if (*ns
->px
== '\0') {
4609 collected_ns
= Base_Type::collect_ns(p_td
, num_collected
, def_ns
);
4614 // The type's own tag is omitted if we're doing E-XER,
4615 // and it's not the top-level type (XML must have a root element)
4616 // and it's either UNTAGGED or got USE_NIL.
4617 boolean omit_tag
= exer
&& indent
4618 && ( (p_td
.xer_bits
& (UNTAGGED
|XER_ATTRIBUTE
))
4619 || (flavor
& (USE_NIL
|USE_TYPE_ATTR
)));
4621 // If a default namespace is in effect (uri but no prefix) and the type
4622 // is unqualified, the default namespace must be canceled; otherwise
4623 // an XML tag without a ns prefix looks like it belongs to the def.namespace
4624 const boolean empty_ns_hack
= exer
&& !omit_tag
&& (indent
> 0)
4625 && (p_td
.xer_bits
& FORM_UNQUALIFIED
)
4626 && (flavor
& DEF_NS_PRESENT
);
4628 // delay_close=true if there is stuff before the '>' of the start tag
4629 // (prevents writing the '>' which is built into the name).
4630 // This can only happen for EXER: if there are attributes or namespaces,
4631 // or either USE-NIL or USE-QNAME is set.
4632 boolean delay_close
= exer
&& (num_attributes
4633 || empty_ns_hack
// counts as having a namespace
4634 || (num_collected
!= 0)
4635 || (p_td
.xer_bits
& (USE_NIL
|USE_QNAME
))
4636 || (flavor
& USE_NIL
));
4639 if (!omit_tag
) { /* write start tag */
4640 if (indenting
) do_indent(p_buf
, indent
);
4641 /* name looks like this: "tagname>\n"
4642 * lose the \n if : not indenting or (single untagged(*) or attributes (*)) AND exer
4643 * lose the > if attributes are present (*) AND exer
4646 if (exer
) write_ns_prefix(p_td
, p_buf
);
4647 p_buf
.put_s((size_t)p_td
.namelens
[exer
] - delay_close
4648 - (!indenting
|| delay_close
|| (exer
&& (p_td
.xer_bits
& HAS_1UNTAGGED
))),
4649 (cbyte
*)p_td
.names
[exer
]);
4651 else if (flavor
& USE_TYPE_ATTR
) {
4652 // reopen the parent's tag
4653 size_t buf_len
= p_buf
.get_len();
4654 const unsigned char * const buf_data
= p_buf
.get_data();
4655 if (buf_data
[buf_len
- 1 - shorter
] == '\n') ++shorter
;
4656 if (buf_data
[buf_len
- 1 - shorter
] == '>' ) ++shorter
;
4659 p_buf
.increase_length(-shorter
);
4664 int sub_len
=0, tmp_len
;
4665 // mask out extra flags we received, do not send them to the fields
4668 if (exer
&& (p_td
.xer_bits
& USE_QNAME
)) {
4669 const Erroneous_values_t
* ev
=
4670 p_err_descr
->next_field_err_values(0, values_idx
);
4671 const Erroneous_descriptor_t
* ed
=
4672 p_err_descr
->next_field_emb_descr (0, edescr_idx
);
4673 // At first, erroneous info for the first component (uri)
4675 TTCN_EncDec_ErrorContext ec
;
4676 const Base_Type
* const q_uri
= get_at(0);
4678 if (ev
&& ev
->before
) {
4679 if (ev
->before
->errval
==NULL
) TTCN_error(
4680 "internal error: erroneous before value missing");
4681 ec
.set_msg("Erroneous value before component #0: ");
4682 if (ev
->before
->raw
) {
4683 sub_len
+= ev
->before
->errval
->encode_raw(p_buf
);
4685 if (ev
->before
->type_descr
==NULL
) TTCN_error(
4686 "internal error: erroneous before typedescriptor missing");
4687 sub_len
+= ev
->before
->errval
->XER_encode(
4688 *ev
->before
->type_descr
->xer
, p_buf
, flavor
, indent
, 0);
4692 if (ev
&& ev
->value
) {
4693 if (ev
->value
->errval
) { // replace
4694 ec
.set_msg("Erroneous value for component #0: ");
4695 if (ev
->value
->raw
) {
4696 sub_len
+= ev
->value
->errval
->encode_raw(p_buf
);
4698 if (ev
->value
->type_descr
==NULL
) TTCN_error(
4699 "internal error: erroneous value typedescriptor missing");
4700 sub_len
+= ev
->value
->errval
->XER_encode(
4701 *ev
->value
->type_descr
->xer
, p_buf
, flavor
, indent
, 0);
4705 ec
.set_msg("Component #0: ");
4707 // universal charstring does not have components.
4708 // TTCN code which could have generated embedded erroneous descriptor
4709 // should have failed semantic analysis.
4710 TTCN_error("internal error: embedded descriptor unexpected");
4712 // the "real" encoder
4713 if (q_uri
->is_present()) {
4714 p_buf
.put_s(11, (cbyte
*)" xmlns:b0='");
4715 sub_len
+= q_uri
->XER_encode(*xer_descr(0), p_buf
, flavor
| XER_LIST
, indent
+1, 0);
4721 if (ev
&& ev
->after
) {
4722 if (ev
->after
->errval
==NULL
) TTCN_error(
4723 "internal error: erroneous after value missing");
4724 ec
.set_msg("Erroneous value after component #0: ");
4725 if (ev
->after
->raw
) {
4726 sub_len
+= ev
->after
->errval
->encode_raw(p_buf
);
4728 if (ev
->after
->type_descr
==NULL
) TTCN_error(
4729 "internal error: erroneous after typedescriptor missing");
4730 sub_len
+= ev
->after
->errval
->XER_encode(
4731 *ev
->after
->type_descr
->xer
, p_buf
, flavor
, indent
, 0);
4735 if (p_td
.xer_bits
& XER_ATTRIBUTE
) begin_attribute(p_td
, p_buf
);
4736 else p_buf
.put_c('>');
4738 // Now switch to the second field (name)
4739 ev
= p_err_descr
->next_field_err_values(1, values_idx
);
4740 ed
= p_err_descr
->next_field_emb_descr (1, edescr_idx
);
4742 if (ev
&& ev
->before
) {
4743 if (ev
->before
->errval
==NULL
) TTCN_error(
4744 "internal error: erroneous before value missing");
4745 ec
.set_msg("Erroneous value before component #1: ");
4746 if (ev
->before
->raw
) {
4747 sub_len
+= ev
->before
->errval
->encode_raw(p_buf
);
4749 if (ev
->before
->type_descr
==NULL
) TTCN_error(
4750 "internal error: erroneous before typedescriptor missing");
4751 sub_len
+= ev
->before
->errval
->XER_encode(
4752 *ev
->before
->type_descr
->xer
, p_buf
, flavor
, indent
, 0);
4756 if (ev
&& ev
->value
) {
4757 if (ev
->value
->errval
) { // replace
4758 ec
.set_msg("Erroneous value for component #1: ");
4759 if (ev
->value
->raw
) {
4760 sub_len
+= ev
->value
->errval
->encode_raw(p_buf
);
4762 if (ev
->value
->type_descr
==NULL
) TTCN_error(
4763 "internal error: erroneous value typedescriptor missing");
4764 sub_len
+= ev
->value
->errval
->XER_encode(
4765 *ev
->value
->type_descr
->xer
, p_buf
, flavor
, indent
, 0);
4769 ec
.set_msg("Component #1: ");
4771 // universal charstring does not have components
4772 TTCN_error("internal error: embedded descriptor unexpected");
4774 // the "real" encoder
4775 if (q_uri
->is_present()) {
4776 p_buf
.put_s(3, (cbyte
*)"b0:");
4780 sub_len
+= get_at(1)->XER_encode(*xer_descr(1), p_buf
, flavor
| XER_LIST
, indent
+1, 0);
4784 if (ev
&& ev
->after
) {
4785 if (ev
->after
->errval
==NULL
) TTCN_error(
4786 "internal error: erroneous after value missing");
4787 ec
.set_msg("Erroneous value after component #1: ");
4788 if (ev
->after
->raw
) {
4789 sub_len
+= ev
->after
->errval
->encode_raw(p_buf
);
4791 if (ev
->after
->type_descr
==NULL
) TTCN_error(
4792 "internal error: erroneous after typedescriptor missing");
4793 sub_len
+= ev
->after
->errval
->XER_encode(
4794 *ev
->after
->type_descr
->xer
, p_buf
, flavor
, indent
, 0);
4798 if (p_td
.xer_bits
& XER_ATTRIBUTE
) p_buf
.put_c('\'');
4800 else { // not USE-QNAME
4801 if (!exer
&& (p_td
.xer_bits
& EMBED_VALUES
)) {
4802 // The EMBED-VALUES member as an ordinary record of string
4803 sub_len
+= embed_values
->XER_encode(*xer_descr(0), p_buf
, flavor
, indent
+1, 0);
4806 if (!exer
&& (p_td
.xer_bits
& USE_ORDER
)) {
4807 // The USE-ORDER member as an ordinary record of enumerated
4808 sub_len
+= use_order
->XER_encode(*xer_descr(uo_index
), p_buf
, flavor
, indent
+1, 0);
4811 if (exer
&& (indent
==0 || (flavor
& DEF_NS_SQUASHED
))) // write namespaces for toplevel only
4813 for (size_t cur_coll
= 0; cur_coll
< num_collected
; ++cur_coll
) {
4814 p_buf
.put_s(strlen(collected_ns
[cur_coll
]), (cbyte
*)collected_ns
[cur_coll
]);
4815 Free(collected_ns
[cur_coll
]); // job done
4821 flavor
&= ~DEF_NS_SQUASHED
;
4822 flavor
|= DEF_NS_PRESENT
;
4824 else if (empty_ns_hack
) {
4825 p_buf
.put_s(9, (cbyte
*)" xmlns=''");
4826 flavor
&= ~DEF_NS_PRESENT
;
4827 flavor
|= DEF_NS_SQUASHED
;
4830 // True if the non-attribute fields need to be omitted;
4831 // e.g. if USE_ORDER is in effect and the "nil" attribute was written
4832 // (then the record-of-enum for USE-ORDER will be empty),
4833 // or "omit all after" was hit while processing attributes.
4834 boolean early_to_bed
= FALSE
;
4836 // First all the attributes (not added to sub_len)
4838 for (i
= start_at
; i
< first_nonattr
; ++i
) {
4839 const Erroneous_values_t
* ev
=
4840 p_err_descr
->next_field_err_values(i
, values_idx
);
4841 const Erroneous_descriptor_t
* ed
=
4842 p_err_descr
->next_field_emb_descr(i
, edescr_idx
);
4844 if (i
< p_err_descr
->omit_before
) continue;
4846 boolean is_xer_attr_field
= xer_descr(i
)->xer_bits
& XER_ATTRIBUTE
;
4847 ec_1
.set_msg("%s': ", fld_name(i
)); // attr
4849 tmp_len
= encode_field(i
, ev
, ed
, p_buf
, flavor
, indent
+ !omit_tag
, 0);
4851 if (is_xer_attr_field
&& !exer
) sub_len
+= tmp_len
; // do not add if attribute and EXER
4853 // omit_after value -1 becomes "very big"
4854 if ((unsigned int)i
>= (unsigned int)p_err_descr
->omit_after
) {
4855 early_to_bed
= TRUE
; // no more fields to write
4860 // True if the "nil" attribute needs to be written.
4861 boolean nil_attribute
= FALSE
;
4862 // nil attribute unaffected by erroneous
4863 boolean nil_attribute_simple
= FALSE
;
4864 if (exer
&& (p_td
.xer_bits
& USE_NIL
)) {
4865 nil_attribute
= nil_attribute_simple
= !get_at(field_cnt
-1)->ispresent();
4867 if (p_err_descr
->values_size
> 0) // there is an erroneous "value := ..."
4869 const Erroneous_values_t
*ev_nil
=
4870 p_err_descr
->get_field_err_values(field_cnt
-1);
4871 if (ev_nil
&& ev_nil
->value
) // value override for the last field
4873 nil_attribute
= (ev_nil
->value
->errval
== NULL
);
4878 if (nil_attribute
) { // req. exer and USE_NIL
4879 const namespace_t
*control_ns
= p_td
.my_module
->get_controlns();
4881 if (!nil_attribute_simple
) {
4882 // It is likely that the declaration for namespace "xsi"
4883 // was not written. Do it now.
4884 p_buf
.put_s(7, (cbyte
*)" xmlns:");
4885 p_buf
.put_s(strlen(control_ns
->px
), (cbyte
*)control_ns
->px
);
4886 p_buf
.put_s(2, (cbyte
*)"='");
4887 p_buf
.put_s(strlen(control_ns
->ns
), (cbyte
*)control_ns
->ns
);
4892 p_buf
.put_s(strlen(control_ns
->px
), (cbyte
*)control_ns
->px
);
4894 p_buf
.put_s(10, (cbyte
*)"nil='true'");
4895 if ((p_td
.xer_bits
& USE_ORDER
)) early_to_bed
= TRUE
;
4896 // The whole content was omitted; nothing to do (and if we tried
4897 // to do it, we'd get an error for over-indexing a 0-length record-of).
4900 if (delay_close
&& (!omit_tag
|| shorter
)) {
4901 // Close the start tag left open. If indenting, also write a newline
4902 // unless USE-NIL in effect or there is a single untagged component.
4904 ((p_td
.xer_bits
& (/*USE_NIL|*/HAS_1UNTAGGED
)) ? 0 : indenting
);
4905 p_buf
.put_s(start_tag_len
, (cbyte
*)">\n");
4908 // Erroneous values for the embed_values member (if any).
4909 // Collected once but referenced multiple times.
4910 const Erroneous_descriptor_t
* ed0
= NULL
;
4911 int embed_values_val_idx
= 0;
4912 int embed_values_descr_idx
= 0;
4914 if (exer
&& (p_td
.xer_bits
& EMBED_VALUES
)) {
4915 ed0
= p_err_descr
->next_field_emb_descr(0, edescr_idx
);
4917 // write the first string
4918 if (embed_values
->size_of() > 0) {
4919 const Erroneous_values_t
* ev0_0
= NULL
;
4920 const Erroneous_descriptor_t
* ed0_0
= NULL
;
4922 ev0_0
= ed0
->next_field_err_values(0, embed_values_val_idx
);
4923 ed0_0
= ed0
->next_field_emb_descr (0, embed_values_descr_idx
);
4925 sub_len
+= embed_values
->encode_element(0, UNIVERSAL_CHARSTRING_xer_
,
4926 ev0_0
, ed0_0
, p_buf
, flavor
| EMBED_VALUES
, indent
+!omit_tag
, 0);
4930 const Record_Type
*ordered
= this; // the record affected by USE-ORDER
4931 // By default it's this record, unless USE_NIL is _also_ in effect,
4932 // in which case it's the last member of this.
4934 // Index of the first non-attribute field of the record pointed to by
4935 // ordered, that is, the first field affected by USE-ORDER.
4936 size_t useorder_base
= first_nonattr
;
4939 int end
= field_cnt
; // "one past", do not touch
4940 // by default, continue from the current field until the end, indexing this
4942 if (exer
&& (p_td
.xer_bits
& USE_ORDER
)) {
4943 // the length of the loop is determined by the length of use_order
4944 const int to_send
= use_order
->size_of();
4946 // i will index all elements of the use_order member
4950 // Count the non-attribute optionals
4951 int n_optionals
= 0;
4952 for (int B
= optional_count() - 1; B
>=+0; B
--) {
4953 int oi
= get_optional_indexes()[B
];
4954 if (oi
< first_nonattr
) break;
4958 int expected_min
= field_cnt
- first_nonattr
- n_optionals
;
4959 int expected_max
= field_cnt
- first_nonattr
;
4961 if ((p_td
.xer_bits
& USE_NIL
) && get_at(field_cnt
-1)->ispresent()) {
4962 // The special case when USE_ORDER refers to the fields of a field,
4964 const Base_Type
*last_optional
= get_at(field_cnt
-1);
4965 const Base_Type
* inner
= last_optional
->get_opt_value();
4966 // it absolutely, positively has to be (derived from) Record_Type
4967 ordered
= static_cast<const Record_Type
*>(inner
);
4968 useorder_base
= ordered
->get_xer_num_attr();
4969 begin
= useorder_base
;
4970 end
= ordered
->get_count();
4972 expected_min
= expected_max
= ordered
->get_count();
4975 if (to_send
> expected_max
4976 ||to_send
< expected_min
) {
4977 ec_1
.set_msg("%s': ", fld_name(uo_index
));
4978 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_CONSTRAINT
,
4979 "Wrong number of USE-ORDER %d, must be %d..%d", to_send
, expected_min
, expected_max
);
4980 early_to_bed
= TRUE
; // don't bother sending anything
4982 else { // check no duplicates
4983 int *seen
= new int [to_send
];
4985 for (int ei
= 0; ei
< to_send
; ++ei
) {
4986 const Base_Type
*uoe
= use_order
->get_at(ei
);
4987 const Enum_Type
*enm
= static_cast<const Enum_Type
*>(uoe
);
4988 int val
= enm
->as_int();
4989 for (int x
= 0; x
< num_seen
; ++x
) {
4990 if (val
== seen
[x
]) { // complain
4991 ec_1
.set_msg("%s': ", fld_name(uo_index
));
4992 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_CONSTRAINT
,
4993 "Duplicate value for USE-ORDER");
4994 early_to_bed
= TRUE
; // don't bother sending anything
4998 seen
[num_seen
++] = val
;
5002 // If the number is right and there are no duplicates, then carry on
5004 } // endif(USE_ORDER)
5006 // Then, all the non-attributes. Structuring the code like this depends on
5007 // all attributes appearing before all non-attributes (excluding
5008 // pseudo-members for USE-ORDER, etc.)
5010 // This loop handles both the normal case (no USE_ORDER) when i indexes
5011 // fields of this record; and the USE_ORDER case (with or without USE-NIL).
5013 // early_to_bed can only be true if exer is true (transitive through nil_attribute)
5014 if (!early_to_bed
) {
5015 embed_values_enc_struct_t
* emb_val
= 0;
5016 if (exer
&& (p_td
.xer_bits
& EMBED_VALUES
) && embed_values
->size_of() > 1) {
5017 emb_val
= new embed_values_enc_struct_t
;
5018 emb_val
->embval_array
= embed_values
;
5019 emb_val
->embval_index
= 1;
5020 emb_val
->embval_err
= ed0
;
5021 emb_val
->embval_err_val_idx
= embed_values_val_idx
;
5022 emb_val
->embval_err_descr_idx
= embed_values_descr_idx
;
5025 for ( i
= begin
; i
< end
; ++i
) {
5027 const Base_Type
*uoe
= 0; // "useOrder enum"
5028 const Enum_Type
*enm
= 0; // the enum value selecting the field
5030 // "actual" index, may be perturbed by USE-ORDER.
5031 // We use this value to index the appropriate record.
5034 const Erroneous_values_t
* ev
= NULL
;
5035 const Erroneous_descriptor_t
* ed
= NULL
;
5036 if (exer
&& use_order
) {
5037 // If USE-ORDER is in effect, it introduces a level of indirection
5038 // into the indexing of fields: "i" is used to select an element
5039 // of the use_order member (an enum), whose value is used to select
5040 // the field being encoded.
5041 uoe
= use_order
->get_at(i
- begin
);
5042 enm
= static_cast<const Enum_Type
*>(uoe
);
5043 ai
= enm
->as_int() + useorder_base
;
5045 // Because it is not guaranteed that ai will increase monotonically,
5046 // we can't use next_field_...().
5047 ev
= p_err_descr
->get_field_err_values(ai
);
5048 ed
= p_err_descr
->get_field_emb_descr (ai
);
5050 else { // not USE-ORDER, sequential access
5051 ev
= p_err_descr
->next_field_err_values(ai
, values_idx
);
5052 ed
= p_err_descr
->next_field_emb_descr (ai
, edescr_idx
);
5054 ec_1
.set_msg("%s': ", ordered
->fld_name(ai
)); // non-attr
5056 if (ai
< p_err_descr
->omit_before
) continue;
5058 // omit_after value -1 becomes "very big".
5059 if ((unsigned int)ai
> (unsigned int)p_err_descr
->omit_after
) continue;
5060 // We can't skip all fields with break, because the next ai may be lower
5063 sub_len
+= ordered
->encode_field(ai
, ev
, ed
, p_buf
,
5064 // Pass USE-NIL to the last field (except when USE-ORDER is also in effect,
5065 // because the tag-stripping effect of USE-NIL has been achieved
5066 // by encoding the sub-fields directly).
5067 flavor
| ((exer
&& !use_order
&& (i
== field_cnt
-1)) ? (p_td
.xer_bits
& USE_NIL
) : 0),
5068 indent
+ !omit_tag
, emb_val
);
5070 // Now the next embed-values string (NOT affected by USE-ORDER!)
5071 if (exer
&& (p_td
.xer_bits
& EMBED_VALUES
) && 0 != emb_val
&&
5072 emb_val
->embval_index
< embed_values
->size_of()) {
5073 const Erroneous_values_t
* ev0_i
= NULL
;
5074 const Erroneous_descriptor_t
* ed0_i
= NULL
;
5076 ev0_i
= ed0
->next_field_err_values(emb_val
->embval_index
, emb_val
->embval_err_val_idx
);
5077 ed0_i
= ed0
->next_field_emb_descr (emb_val
->embval_index
, emb_val
->embval_err_descr_idx
);
5079 embed_values
->encode_element(emb_val
->embval_index
, UNIVERSAL_CHARSTRING_xer_
,
5080 ev0_i
, ed0_i
, p_buf
, flavor
| EMBED_VALUES
, indent
+ !omit_tag
, 0);
5081 ++emb_val
->embval_index
;
5085 if (emb_val
->embval_index
< embed_values
->size_of()) {
5086 ec_1
.set_msg("%s': ", fld_name(0));
5087 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_CONSTRAINT
,
5088 "Too many EMBED-VALUEs specified: %d (expected %d or less)",
5089 embed_values
->size_of(), emb_val
->embval_index
);
5093 } // if (!early_to_bed)
5098 if (sub_len
) { // something was written, now an end tag
5099 if (indenting
&& !(exer
&& (p_td
.xer_bits
& (HAS_1UNTAGGED
| USE_QNAME
))))
5100 // The tags of the last optional member involved with USE_NIL
5101 // have been removed. If it was a simple type, the content was probably
5102 // written on a single line without anything resembling a close tag.
5103 // Do not indent our end tag in this case.
5104 switch ((int)(exer
&& (p_td
.xer_bits
& USE_NIL
))) {
5106 const unsigned char *buf_end
= p_buf
.get_data() + (p_buf
.get_len()-1);
5107 if (buf_end
[-1] != '>' || *buf_end
!= '\n') break;
5108 // If it does not look like an end tag, skip the indenting,
5109 // else fall through.
5112 do_indent(p_buf
, indent
);
5117 if (exer
) write_ns_prefix(p_td
, p_buf
);
5118 p_buf
.put_s((size_t)p_td
.namelens
[exer
]-!indenting
, (cbyte
*)p_td
.names
[exer
]);
5120 else { // need to generate an empty element tag
5121 p_buf
.increase_length(-start_tag_len
); // decrease length
5122 p_buf
.put_s((size_t)2+indenting
, (cbyte
*)"/>\n");
5126 return (int)p_buf
.get_len() - encoded_length
;
5129 int Record_Type::XER_decode(const XERdescriptor_t
& p_td
, XmlReaderWrap
& reader
,
5130 unsigned int flavor
, unsigned int flavor2
, embed_values_dec_struct_t
*)
5132 int exer
= is_exer(flavor
);
5134 int depth
=-1; // depth of the start tag
5135 int xerbits
= p_td
.xer_bits
;
5136 if (flavor
& XER_TOPLEVEL
) xerbits
&= ~UNTAGGED
;
5137 const boolean own_tag
= !(exer
5138 && ( (xerbits
& (ANY_ELEMENT
| UNTAGGED
| XER_ATTRIBUTE
))
5139 || (flavor
& (USE_NIL
| USE_TYPE_ATTR
))));
5140 boolean tag_closed
= (flavor
& PARENT_CLOSED
) != 0;
5141 // If the parent has USE-TYPE, our ATTRIBUTE members can be found
5142 // in the parent's tag (the reader is sitting on it).
5143 const boolean parent_tag
= exer
&& ((flavor
& USE_TYPE_ATTR
) || (flavor2
& USE_NIL_PARENT_TAG
));
5145 // Filter out flags passed by our parent. These are not for the fields.
5146 flavor
&= XER_MASK
; // also removes XER_TOPLEVEL
5147 flavor2
= XER_NONE
; // Remove only bit: USE_NIL_PARENT_TAG (for now)
5149 const int field_cnt
= get_count();
5150 const int num_attributes
= get_xer_num_attr();
5152 // The index of potential "order" field, regardless of whether USE_ORDER
5153 // is in use or not.
5154 const int uo_index
= ((p_td
.xer_bits
& EMBED_VALUES
) !=0);
5156 // The first "non-special" field (skipping the USE-ORDER and EMBED-VALUES
5157 // fields); normal processing start at this field.
5158 const int start_at
= uo_index
+ ((p_td
.xer_bits
& USE_ORDER
) != 0);
5159 const int first_nonattr
= start_at
+ num_attributes
;
5161 // The index of the ANY-ATTRIBUTES member, if any
5163 for (int k
= 0; k
< first_nonattr
; ++k
) {
5164 if (xer_descr(k
)->xer_bits
& ANY_ATTRIBUTES
) {
5166 if (!get_at(aa_index
)->is_optional()) {
5167 static_cast<Record_Of_Type
*>(get_at(aa_index
))->set_size(0);
5169 break; // there can be only one, 18.2.2
5173 if (own_tag
) for (success
=reader
.Ok(); success
==1; success
=reader
.Read()) {
5174 type
= reader
.NodeType();
5175 if (type
==XML_READER_TYPE_ELEMENT
) {
5176 verify_name(reader
, p_td
, exer
);
5177 depth
= reader
.Depth();
5178 tag_closed
= reader
.IsEmptyElement();
5185 if (exer
&& (p_td
.xer_bits
& USE_QNAME
)) { // QName trumps everything !
5186 // If element, it looks like this:
5187 // <name xmlns:b0="http://www.furniture.com">b0:table</name>
5188 // If attribute, it looks like this:
5191 if (p_td
.xer_bits
& XER_ATTRIBUTE
) success
= 1; // do nothing
5192 else for (success
= reader
.Read(); success
== 1; success
= reader
.Read()) {
5193 type
= reader
.NodeType();
5194 if (type
== XML_READER_TYPE_TEXT
) break;
5198 xmlChar
*val
= reader
.NewValue();
5199 xmlChar
*npfx
= (xmlChar
*)strchr((char*)val
, ':');
5202 *npfx
++ = '\0'; // cut the string into two
5210 xmlChar
*nsu
= reader
.LookupNamespace(pfx
);
5212 OPTIONAL
<UNIVERSAL_CHARSTRING
> *q_prefix2
=
5213 static_cast<OPTIONAL
<UNIVERSAL_CHARSTRING
>*>(get_at(0));
5214 if (nsu
) *q_prefix2
= (const char*)nsu
;
5215 else q_prefix2
->set_to_omit(); // public in RT2 only
5217 UNIVERSAL_CHARSTRING
*q_name2
= static_cast<UNIVERSAL_CHARSTRING
*>(get_at(1));
5218 *q_name2
= (const char*)npfx
;
5224 else { // not use-qname
5225 TTCN_EncDec_ErrorContext
ec_0("Component '");
5226 TTCN_EncDec_ErrorContext ec_1
;
5227 boolean usenil_attribute
= FALSE
; // true if found and said yes
5228 // If nillable and the nillable field is a record type, that has attributes
5229 // then it will become true, and skips the processing of the fields after
5230 boolean already_processed
= FALSE
;
5232 if (!reader
.IsEmptyElement()) reader
.Read();
5233 // First, the (would-be) attributes (unaffected by USE-ORDER)
5234 for (i
= 0; i
< first_nonattr
; i
++) {
5235 ec_1
.set_msg("%s': ", fld_name(i
));
5236 get_at(i
)->XER_decode(*xer_descr(i
), reader
, flavor
, flavor2
, 0);
5239 else if (own_tag
|| parent_tag
) { // EXER and not UNTAGGED: do attributes
5240 // Prepare for lack of attributes.
5241 // Fields with defaultForEmpty get the D-F-E value, optional get omit.
5242 for (i
= start_at
; i
< first_nonattr
; i
++) {
5243 Base_Type
&fld
= *get_at(i
);
5244 const XERdescriptor_t
& xd
= *xer_descr(i
);
5246 if (fld
.is_optional()) {
5247 fld
.set_to_present();
5248 fld
.get_opt_value()->set_value(xd
.dfeValue
);
5250 else fld
.set_value(xd
.dfeValue
);
5252 else if (fld
.is_optional()) fld
.set_to_omit();
5255 int num_aa
= 0; // index into the ANY-ATTRIBUTE member
5257 const namespace_t
*control_ns
= 0;
5258 if (parent_tag
|| (p_td
.xer_bits
& USE_NIL
)) {
5259 // xsi:type or xsi:nil
5260 control_ns
= p_td
.my_module
->get_controlns();
5263 /* * * * * * * * * Attributes * * * * * * * * * * * * * */
5264 if(parent_tag
&& reader
.NodeType() == XML_READER_TYPE_ATTRIBUTE
) {
5265 success
= reader
.Ok();
5267 success
= reader
.MoveToFirstAttribute();
5270 success
== 1 && reader
.NodeType() == XML_READER_TYPE_ATTRIBUTE
;
5271 success
= reader
.AdvanceAttribute())
5273 if (reader
.IsNamespaceDecl()) {
5274 continue; // namespace declarations are handled for us by libxml2
5277 const char *attr_name
= (const char*)reader
.LocalName();
5278 const char *ns_uri
= (const char*)reader
.NamespaceUri();
5279 int field_index
= get_index_byname(attr_name
, ns_uri
);
5280 if (field_index
!= -1) {
5281 // There is a field. Let it decode the attribute.
5282 ec_1
.set_msg("%s': ", fld_name(field_index
));
5283 get_at(field_index
)->XER_decode(*xer_descr(field_index
), reader
, flavor
, flavor2
, 0);
5287 // Attribute not found. It could be the "nil" attribute
5288 if (p_td
.xer_bits
& USE_NIL
) {
5289 const char *prefix
= (const char*)reader
.Prefix();
5290 // prefix may be NULL, control_ns->px is never NULL or empty
5291 if (prefix
&& !strcmp(prefix
, control_ns
->px
)
5292 && !strcmp((const char*)reader
.LocalName(), "nil"))
5293 { // It is the "nil" attribute
5294 const char *value
= (const char*)reader
.Value();
5296 if (!strcmp(value
, "1") || !strcmp(value
, "true")) {
5297 // The field affected by USE-NIL is always the last one
5298 get_at(field_cnt
-1)->set_to_omit();
5299 usenil_attribute
= TRUE
;
5304 } // it is the "nil" attribute
5305 // else, let the nillable field decode the next attributes, it is possible
5306 // that it belongs to him
5307 get_at(field_cnt
-1)->XER_decode(*xer_descr(field_cnt
-1), reader
, flavor
| USE_NIL
, flavor2
| USE_NIL_PARENT_TAG
, 0);
5308 already_processed
= TRUE
;
5310 } // type has USE-NIL
5313 const char *prefix
= (const char*)reader
.Prefix();
5314 // prefix may be NULL, control_ns->px is never NULL or empty
5315 if (prefix
&& !strcmp(prefix
, control_ns
->px
)
5316 && !strcmp((const char*)reader
.LocalName(), "type")) {
5317 continue; // xsi:type has been processed by the parent
5321 if (aa_index
>= 0) {
5322 ec_1
.set_msg("%s': ", fld_name(aa_index
));
5323 TTCN_EncDec_ErrorContext
ec_2("Attribute %d: ", num_aa
);
5324 // We have a component with ANY-ATTRIBUTE. It must be a record of
5325 // UNIVERSAL_CHARSTRING. Add the attribute to it.
5326 Record_Of_Type
*aa
= 0;
5327 if (get_at(aa_index
)->is_optional()) {
5329 get_at(aa_index
)->set_to_present();
5331 aa
= static_cast<Record_Of_Type
*>(get_at(aa_index
)->get_opt_value());
5334 aa
= static_cast<Record_Of_Type
*>(get_at(aa_index
));
5336 UNIVERSAL_CHARSTRING
*new_elem
= static_cast<UNIVERSAL_CHARSTRING
*>
5337 (aa
->get_at(num_aa
++));
5339 // Construct the AnyAttributeFormat (X.693amd1, 18.2.6)
5341 const xmlChar
*name
= reader
.LocalName();
5342 const xmlChar
*val
= reader
.Value();
5343 const xmlChar
*uri
= reader
.NamespaceUri();
5345 if (xer_descr(aa_index
)->xer_bits
& (ANY_FROM
| ANY_EXCEPT
)) {
5346 check_namespace_restrictions(*xer_descr(aa_index
), (const char*)uri
);
5348 // We don't care about reader.Prefix()
5349 // Using strlen to count UTF8 bytes, not characters
5350 aabuf
.put_s(uri
? strlen((const char*)uri
) : 0, uri
);
5351 if (uri
&& *uri
) aabuf
.put_c(' ');
5352 aabuf
.put_s(name
? strlen((const char*)name
) : 0, name
);
5355 aabuf
.put_s(val
? strlen((const char*)val
) : 0, val
);
5357 new_elem
->decode_utf8(aabuf
.get_len(), aabuf
.get_data());
5362 // Lastly check for the xsi:schemaLocation attribute, this does not
5363 // affect TTCN-3, but it shouldn't cause a DTE
5364 if (reader
.LocalName() && !strcmp((const char*)reader
.LocalName(), "schemaLocation")) {
5366 control_ns
= p_td
.my_module
->get_controlns();
5368 if (reader
.Prefix() && !strcmp((const char*)reader
.Prefix(), control_ns
->px
)) {
5373 // Nobody wanted the attribute. That is an error.
5374 ec_0
.set_msg(" "); ec_1
.set_msg(" ");
5375 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG
,
5376 "Unexpected attribute '%s', ns '%s'", attr_name
,
5377 ns_uri
? ns_uri
: "");
5380 // Now check that all mandatory attributes have been set
5381 for (i
= start_at
; i
< first_nonattr
; ++i
) {
5382 Base_Type
* fld
= get_at(i
);
5383 if (fld
->is_optional()) continue; // field is allowed to be unset
5384 if (!fld
->is_bound()) {
5385 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG
,
5386 "Missing attribute '%s'", this->fld_name(i
));
5390 i
= first_nonattr
; // finished with attributes
5391 // AdvanceAttribute did MoveToElement. Move into the content (if any),
5392 // except when the reader is already moved in(already_processed).
5393 if (!reader
.IsEmptyElement() && !already_processed
) reader
.Read();
5394 } // end if (own_tag)
5396 /* * * * * * * * Non-attributes (elements) * * * * * * * * * * * */
5397 embed_values_dec_struct_t
* emb_val
= 0;
5398 bool emb_val_optional
= false;
5399 if (exer
&& (p_td
.xer_bits
& EMBED_VALUES
)) {
5400 emb_val
= new embed_values_dec_struct_t
;
5401 emb_val
->embval_array
= dynamic_cast<Record_Of_Type
*>(get_at(0));
5402 if (NULL
== emb_val
->embval_array
) {
5403 OPTIONAL
<PreGenRecordOf::PREGEN__RECORD__OF__UNIVERSAL__CHARSTRING
>* embed_value
= static_cast<OPTIONAL
<PreGenRecordOf::PREGEN__RECORD__OF__UNIVERSAL__CHARSTRING
>*>(get_at(0));
5404 embed_value
->set_to_present();
5405 emb_val
->embval_array
= static_cast<Record_Of_Type
*>((*embed_value
).get_opt_value());
5406 emb_val_optional
= true;
5408 emb_val
->embval_array
->set_size(0);
5409 emb_val
->embval_index
= 0;
5412 if (exer
&& (p_td
.xer_bits
& USE_ORDER
)) {
5413 // Set all optional fields to omit because their respective XER_decode
5414 // will not be run (and will stay unbound) if the value is missing.
5415 int n_optionals
= 0;
5416 for (int B
= optional_count() - 1; B
>=+0; B
--) {
5417 int oi
= get_optional_indexes()[B
];
5418 if (oi
< first_nonattr
) break;
5419 get_at(oi
)->set_to_omit();
5423 Record_Of_Type
*use_order
= static_cast<Record_Of_Type
*>(get_at(uo_index
));
5424 // Initialize the use_order field to empty. Let it grow on demand.
5425 // (setting it to the minimum acceptable size may leave unbound elements
5426 // if the XML was incomplete).
5427 use_order
->set_size(0);
5429 // Nothing to order if there are no child elements
5431 Record_Type
*jumbled
= this; // the record affected by USE_ORDER
5432 int begin
= first_nonattr
;
5433 int end
= field_cnt
; // "one past"
5434 if (p_td
.xer_bits
& USE_NIL
) {
5435 Base_Type
*last_optional
= get_at(field_cnt
-1);
5436 if (!usenil_attribute
) { // exer known true
5437 last_optional
->set_to_present();
5438 jumbled
= static_cast<Record_Type
*>(last_optional
->get_opt_value());
5439 // We will operate on the members of last_optional,
5440 // effectively bypassing last_optional->XER_decode() itself.
5442 end
= jumbled
->get_count();
5443 ec_1
.set_msg("%s': ", fld_name(field_cnt
-1));
5446 if (num_attributes
> 0
5447 && first_nonattr
!= field_cnt
5448 && i
== first_nonattr
- 1) { // exer known true
5449 // If there were attributes and their processing just finished,
5450 // the reader is positioned on the start tag of the record.
5451 // Move ahead, unless there are no non-attribute fields.
5454 // Then, the non-attributes
5456 // The index runs over the members affected by USE-ORDER.
5457 // This is [first_nonattr,field_cnt) unless USE-NIL is involved,
5458 // in which case it's [0,optional_sequence::field_cnt)
5459 int *seen
= new int[end
-begin
];
5461 int last_any_elem
= begin
- 1;
5462 // The index of the latest embedded value can change outside of this function
5463 // (if the field is an untagged record of), in this case the next value should
5464 // be ignored, as it's already been handled by the record of
5465 int last_embval_index
= 0;
5466 bool early_exit
= false;
5467 for (i
= begin
; i
< end
; i
++) {
5468 for (success
= reader
.Ok(); success
== 1; success
= reader
.Read()) {
5469 type
= reader
.NodeType();
5470 if (0 != emb_val
&& reader
.NodeType()==XML_READER_TYPE_TEXT
) {
5471 UNIVERSAL_CHARSTRING
emb_ustr((const char*)reader
.Value());
5472 emb_val
->embval_array
->get_at(emb_val
->embval_index
)->set_value(&emb_ustr
);
5474 // The non-attribute components must not be UNTAGGED
5475 if (type
== XML_READER_TYPE_ELEMENT
) break;
5476 if (type
== XML_READER_TYPE_END_ELEMENT
) {
5482 if (last_embval_index
== emb_val
->embval_index
) {
5483 ++emb_val
->embval_index
;
5485 last_embval_index
= emb_val
->embval_index
;
5487 if (success
!= 1 || early_exit
) break;
5488 const char *name
= (const char *)reader
.LocalName();
5489 bool field_name_found
= false;
5490 // Find out which member it is.
5491 // FIXME some hashing should be implemented
5492 for (int k
= begin
; k
< end
; k
++) {
5493 if (!(jumbled
->xer_descr(k
)->xer_bits
& ANY_ELEMENT
) &&
5494 check_name(name
, *jumbled
->xer_descr(k
), 1)) {
5495 ec_1
.set_msg("%s': ", jumbled
->fld_name(k
));
5497 // Check for the same field being decoded twice.
5498 // We can't use the field's is_bound()/is_present(),
5499 // because the field may be bound on input, e.g. for
5500 // prototype(fast) or prototype(backtrack).
5501 int in_dex
= k
- begin
;
5502 for (int o
= 0; o
< num_seen
;++o
) {
5503 if (in_dex
== seen
[o
]) TTCN_EncDec_ErrorContext::error(
5504 TTCN_EncDec::ET_INVAL_MSG
, "Duplicate element");
5506 seen
[num_seen
++] = in_dex
;
5507 // Set the next use-order member.
5508 // Non-const get_at creates the object in the record-of.
5509 static_cast<Enum_Type
*>(use_order
->get_at(i
- begin
))
5511 Base_Type
*b
= jumbled
->get_at(k
);
5512 b
->XER_decode(*jumbled
->xer_descr(k
), reader
, flavor
, flavor2
, emb_val
);
5513 field_name_found
= true;
5517 if (!field_name_found
) {
5518 // Check the anyElement fields
5519 for (int k
= last_any_elem
+ 1; k
< end
; k
++) {
5520 if (jumbled
->xer_descr(k
)->xer_bits
& ANY_ELEMENT
) {
5521 ec_1
.set_msg("%s': ", jumbled
->fld_name(k
));
5523 // Check for the same field being decoded twice.
5524 // We can't use the field's is_bound()/is_present(),
5525 // because the field may be bound on input, e.g. for
5526 // prototype(fast) or prototype(backtrack).
5527 int in_dex
= k
- begin
;
5528 for (int o
= 0; o
< num_seen
;++o
) {
5529 if (in_dex
== seen
[o
]) TTCN_EncDec_ErrorContext::error(
5530 TTCN_EncDec::ET_INVAL_MSG
, "Duplicate element");
5532 seen
[num_seen
++] = in_dex
;
5533 // Set the next use-order member.
5534 // Non-const get_at creates the object in the record-of.
5535 static_cast<Enum_Type
*>(use_order
->get_at(i
- begin
))
5537 Base_Type
*b
= jumbled
->get_at(k
);
5538 b
->XER_decode(*jumbled
->xer_descr(k
), reader
, flavor
, flavor2
, emb_val
);
5540 field_name_found
= true;
5545 if (!field_name_found
) {
5546 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG
,
5547 "Bad XML tag '%s' instead of a valid field", name
);
5552 if (reader
.NodeType()==XML_READER_TYPE_TEXT
) {
5553 UNIVERSAL_CHARSTRING
emb_ustr((const char*)reader
.Value());
5554 emb_val
->embval_array
->get_at(emb_val
->embval_index
)->set_value(&emb_ustr
);
5556 if (last_embval_index
== emb_val
->embval_index
) {
5557 ++emb_val
->embval_index
;
5561 ec_1
.set_msg(" "); // no active component
5564 // Check that we collected the required number of children
5565 int num_collected
= use_order
->size_of();
5566 if (p_td
.xer_bits
& USE_NIL
) {
5567 int expected
= usenil_attribute
? 0 : jumbled
->get_count();
5568 if (num_collected
!= expected
) {
5569 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INCOMPL_MSG
,
5570 "Incorrect number of fields %d, expected %d",
5571 num_collected
, expected
);
5575 if (num_collected
< field_cnt
- first_nonattr
- n_optionals
5576 ||num_collected
> field_cnt
- first_nonattr
) {
5577 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INCOMPL_MSG
,
5578 "Wrong number of fields! size = %d, expected %d..%d",
5579 use_order
->size_of(), field_cnt
- first_nonattr
- n_optionals
,
5580 field_cnt
- first_nonattr
);
5583 } // not empty element
5585 else { // not USE-ORDER, simpler code
5586 if (usenil_attribute
) {
5587 reader
.MoveToElement(); // value absent, nothing more to do
5589 // The index of the latest embedded value can change outside of this function
5590 // (if the field is a untagged record of), in this case the next value should
5591 // be ignored, as it's already been handled by the record of
5592 // Omitted fields can also reset this value
5593 int last_embval_index
= 0;
5594 for (; i
<field_cnt
; i
++) {
5596 if (reader
.NodeType()==XML_READER_TYPE_TEXT
) {
5597 UNIVERSAL_CHARSTRING
emb_ustr((const char*)reader
.Value());
5598 emb_val
->embval_array
->get_at(emb_val
->embval_index
)->set_value(&emb_ustr
);
5600 if (last_embval_index
== emb_val
->embval_index
) {
5601 ++emb_val
->embval_index
;
5603 last_embval_index
= emb_val
->embval_index
;
5605 ec_1
.set_msg("%s': ", fld_name(i
));
5606 if (exer
&& i
==field_cnt
-1 && p_td
.dfeValue
&& reader
.IsEmptyElement()) {
5607 get_at(i
)->set_value(p_td
.dfeValue
);
5610 // In case the field is an optional anyElement -> check if it should be omitted
5611 bool optional_any_elem_check
= true;
5612 if (get_at(i
)->is_optional() && (xer_descr(i
)->xer_bits
& ANY_ELEMENT
)) {
5613 // The "anyElement" coding instruction can only be applied to a universal charstring field
5614 OPTIONAL
<UNIVERSAL_CHARSTRING
>* opt_field
= dynamic_cast<OPTIONAL
<UNIVERSAL_CHARSTRING
>*>(get_at(i
));
5616 const char* next_field_name
= NULL
;
5617 if (i
< field_cnt
- 1) {
5618 next_field_name
= fld_name(i
+ 1);
5620 optional_any_elem_check
= opt_field
->XER_check_any_elem(reader
, next_field_name
, tag_closed
);
5623 if (optional_any_elem_check
&& !already_processed
) {
5624 int new_flavor
= flavor
;
5625 if (i
== field_cnt
-1) new_flavor
|= (p_td
.xer_bits
& USE_NIL
);
5626 if (tag_closed
) new_flavor
|= PARENT_CLOSED
;
5628 get_at(i
)->XER_decode(*xer_descr(i
), reader
, new_flavor
, flavor2
, emb_val
);
5631 if (!get_at(i
)->is_present()) {
5632 // there was no new element, the last embedded value is for the next field
5633 // (or the end of the record if this is the last field)
5634 last_embval_index
= -1;
5638 if (reader
.NodeType()==XML_READER_TYPE_TEXT
) {
5639 UNIVERSAL_CHARSTRING
emb_ustr((const char*)reader
.Value());
5640 emb_val
->embval_array
->get_at(emb_val
->embval_index
)->set_value(&emb_ustr
);
5642 if (last_embval_index
== emb_val
->embval_index
) {
5643 ++emb_val
->embval_index
;
5650 bool all_unbound
= true;
5651 static const UNIVERSAL_CHARSTRING
emptystring(0, (const char*)NULL
);
5652 for (int j
= 0; j
< emb_val
->embval_index
; ++j
) {
5653 if (!emb_val
->embval_array
->get_at(j
)->is_bound()) {
5654 emb_val
->embval_array
->get_at(j
)->set_value(&emptystring
);
5655 }else if((static_cast<const UNIVERSAL_CHARSTRING
*>(emb_val
->embval_array
->get_at(j
)))->lengthof() !=0) {
5656 all_unbound
= false;
5659 if(emb_val_optional
&& all_unbound
){
5660 static_cast<OPTIONAL
<PreGenRecordOf::PREGEN__RECORD__OF__UNIVERSAL__CHARSTRING
>*>(get_at(0))->set_to_omit();
5663 } // if embed-values
5667 // Check if every non-optional field has been set
5668 for (i
= 0; i
< field_cnt
; ++i
) {
5669 if (!get_at(i
)->is_optional() && !get_at(i
)->is_bound()) {
5670 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INCOMPL_MSG
,
5671 "No data found for non-optional field '%s'", fld_name(i
));
5676 // We had our start tag. Then our fields did their thing.
5677 // Now we expect the end tag. And it better be our end tag!
5679 for (success
= reader
.Ok(); success
== 1; success
= reader
.Read()) {
5680 type
= reader
.NodeType();
5681 current_depth
= reader
.Depth();
5682 if (current_depth
> depth
) {
5683 if (XML_READER_TYPE_ELEMENT
== type
) {
5684 // We found a deeper start tag; it was not processed at all.
5685 // That is an error (maybe we should report error for all node types
5686 // except TEXT and WHITESPACE, not just ELEMENT).
5687 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TAG
,
5688 "Unprocessed XML tag `%s'", (const char *)reader
.Name());
5691 continue; // go past hoping that our end tag will arrive eventually
5693 else if (current_depth
== depth
) { // at our level
5694 if (XML_READER_TYPE_ELEMENT
== type
) {
5695 verify_name(reader
, p_td
, exer
);
5696 if (reader
.IsEmptyElement()) {
5697 // FIXME this shouldn't really be possible;
5698 // only an empty record should be encoded as an empty element,
5699 // but those are implemented by Empty_Record_Type, not Record_Type.
5700 reader
.Read(); // one last time
5704 // If we find an end tag at the right depth, it must be ours
5705 else if (XML_READER_TYPE_END_ELEMENT
== type
) {
5706 verify_end(reader
, p_td
, depth
, exer
);
5711 else { //current_depth < depth; something has gone horribly wrong
5712 break; // better quit before we do further damage
5713 // Don't report an error; every enclosing type would do so,
5714 // spewing the same message over and over.
5718 return 1; // decode successful
5721 int Record_Type::JSON_encode(const TTCN_Typedescriptor_t
& p_td
, JSON_Tokenizer
& p_tok
) const
5724 return JSON_encode_negtest(err_descr
, p_td
, p_tok
);
5728 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND
,
5729 "Encoding an unbound %s value.", is_set() ? "set" : "record");
5733 int enc_len
= p_tok
.put_next_token(JSON_TOKEN_OBJECT_START
, NULL
);
5735 int field_count
= get_count();
5736 for (int i
= 0; i
< field_count
; ++i
) {
5737 boolean metainfo_unbound
= NULL
!= fld_descr(i
)->json
&& fld_descr(i
)->json
->metainfo_unbound
;
5738 if ((NULL
!= fld_descr(i
)->json
&& fld_descr(i
)->json
->omit_as_null
) ||
5739 get_at(i
)->is_present() || metainfo_unbound
) {
5740 const char* field_name
= (NULL
!= fld_descr(i
)->json
&& NULL
!= fld_descr(i
)->json
->alias
) ?
5741 fld_descr(i
)->json
->alias
: fld_name(i
);
5742 enc_len
+= p_tok
.put_next_token(JSON_TOKEN_NAME
, field_name
);
5743 if (metainfo_unbound
&& !get_at(i
)->is_bound()) {
5744 enc_len
+= p_tok
.put_next_token(JSON_TOKEN_LITERAL_NULL
);
5745 char* metainfo_str
= mprintf("metainfo %s", field_name
);
5746 enc_len
+= p_tok
.put_next_token(JSON_TOKEN_NAME
, metainfo_str
);
5748 enc_len
+= p_tok
.put_next_token(JSON_TOKEN_STRING
, "\"unbound\"");
5751 enc_len
+= get_at(i
)->JSON_encode(*fld_descr(i
), p_tok
);
5756 enc_len
+= p_tok
.put_next_token(JSON_TOKEN_OBJECT_END
, NULL
);
5760 int Record_Type::JSON_encode_negtest(const Erroneous_descriptor_t
* p_err_descr
,
5761 const TTCN_Typedescriptor_t
& p_td
,
5762 JSON_Tokenizer
& p_tok
) const
5765 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND
,
5766 "Encoding an unbound %s value.", is_set() ? "set" : "record");
5770 int enc_len
= p_tok
.put_next_token(JSON_TOKEN_OBJECT_START
, NULL
);
5775 int field_count
= get_count();
5776 for (int i
= 0; i
< field_count
; ++i
) {
5777 if (-1 != p_err_descr
->omit_before
&& p_err_descr
->omit_before
> i
) {
5781 const Erroneous_values_t
* err_vals
= p_err_descr
->next_field_err_values(i
, values_idx
);
5782 const Erroneous_descriptor_t
* emb_descr
= p_err_descr
->next_field_emb_descr(i
, edescr_idx
);
5784 if (NULL
!= err_vals
&& NULL
!= err_vals
->before
) {
5785 if (NULL
== err_vals
->before
->errval
) {
5786 TTCN_error("internal error: erroneous before value missing");
5788 if (err_vals
->before
->raw
) {
5789 enc_len
+= err_vals
->before
->errval
->JSON_encode_negtest_raw(p_tok
);
5791 if (NULL
== err_vals
->before
->type_descr
) {
5792 TTCN_error("internal error: erroneous before typedescriptor missing");
5794 // it's an extra field, so use the erroneous type's name as the field name
5795 enc_len
+= p_tok
.put_next_token(JSON_TOKEN_NAME
, err_vals
->before
->type_descr
->name
);
5796 enc_len
+= err_vals
->before
->errval
->JSON_encode(*(err_vals
->before
->type_descr
), p_tok
);
5800 const char* field_name
= (NULL
!= fld_descr(i
)->json
&& NULL
!= fld_descr(i
)->json
->alias
) ?
5801 fld_descr(i
)->json
->alias
: fld_name(i
);
5802 if (NULL
!= err_vals
&& NULL
!= err_vals
->value
) {
5803 if (NULL
!= err_vals
->value
->errval
) {
5804 if (err_vals
->value
->raw
) {
5805 enc_len
+= err_vals
->value
->errval
->JSON_encode_negtest_raw(p_tok
);
5807 if (NULL
== err_vals
->value
->type_descr
) {
5808 TTCN_error("internal error: erroneous before typedescriptor missing");
5810 // only replace the field's value, keep the field name
5811 enc_len
+= p_tok
.put_next_token(JSON_TOKEN_NAME
, field_name
);
5812 enc_len
+= err_vals
->value
->errval
->JSON_encode(*(err_vals
->value
->type_descr
), p_tok
);
5816 boolean metainfo_unbound
= NULL
!= fld_descr(i
)->json
&& fld_descr(i
)->json
->metainfo_unbound
;
5817 if ((NULL
!= fld_descr(i
)->json
&& fld_descr(i
)->json
->omit_as_null
) ||
5818 get_at(i
)->is_present() || metainfo_unbound
) {
5819 enc_len
+= p_tok
.put_next_token(JSON_TOKEN_NAME
, field_name
);
5820 if (metainfo_unbound
&& !get_at(i
)->is_bound()) {
5821 enc_len
+= p_tok
.put_next_token(JSON_TOKEN_LITERAL_NULL
);
5822 char* metainfo_str
= mprintf("metainfo %s", field_name
);
5823 enc_len
+= p_tok
.put_next_token(JSON_TOKEN_NAME
, metainfo_str
);
5825 enc_len
+= p_tok
.put_next_token(JSON_TOKEN_STRING
, "\"unbound\"");
5827 else if (NULL
!= emb_descr
) {
5828 enc_len
+= get_at(i
)->JSON_encode_negtest(emb_descr
, *fld_descr(i
), p_tok
);
5830 enc_len
+= get_at(i
)->JSON_encode(*fld_descr(i
), p_tok
);
5835 if (NULL
!= err_vals
&& NULL
!= err_vals
->after
) {
5836 if (NULL
== err_vals
->after
->errval
) {
5837 TTCN_error("internal error: erroneous after value missing");
5839 if (err_vals
->after
->raw
) {
5840 enc_len
+= err_vals
->after
->errval
->JSON_encode_negtest_raw(p_tok
);
5842 if (NULL
== err_vals
->after
->type_descr
) {
5843 TTCN_error("internal error: erroneous before typedescriptor missing");
5845 // it's an extra field, so use the erroneous type's name as the field name
5846 enc_len
+= p_tok
.put_next_token(JSON_TOKEN_NAME
, err_vals
->after
->type_descr
->name
);
5847 enc_len
+= err_vals
->after
->errval
->JSON_encode(*(err_vals
->after
->type_descr
), p_tok
);
5851 if (-1 != p_err_descr
->omit_after
&& p_err_descr
->omit_after
<= i
) {
5856 enc_len
+= p_tok
.put_next_token(JSON_TOKEN_OBJECT_END
, NULL
);
5860 int Record_Type::JSON_decode(const TTCN_Typedescriptor_t
& p_td
, JSON_Tokenizer
& p_tok
, boolean p_silent
)
5862 json_token_t token
= JSON_TOKEN_NONE
;
5863 int dec_len
= p_tok
.get_next_token(&token
, NULL
, NULL
);
5864 if (JSON_TOKEN_ERROR
== token
) {
5865 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG
, JSON_DEC_BAD_TOKEN_ERROR
, "");
5866 return JSON_ERROR_FATAL
;
5868 else if (JSON_TOKEN_OBJECT_START
!= token
) {
5869 return JSON_ERROR_INVALID_TOKEN
;
5872 const int field_count
= get_count();
5874 // initialize meta info states
5875 int* metainfo
= new int[field_count
];
5876 boolean
* field_found
= new boolean
[field_count
];
5877 for (int i
= 0; i
< field_count
; ++i
) {
5878 field_found
[i
] = FALSE
;
5879 metainfo
[i
] = (NULL
!= fld_descr(i
)->json
&& fld_descr(i
)->json
->metainfo_unbound
) ?
5880 JSON_METAINFO_NONE
: JSON_METAINFO_NOT_APPLICABLE
;
5884 // Read name - value token pairs until we reach some other token
5886 size_t name_len
= 0;
5887 size_t buf_pos
= p_tok
.get_buf_pos();
5888 dec_len
+= p_tok
.get_next_token(&token
, &name
, &name_len
);
5889 if (JSON_TOKEN_ERROR
== token
) {
5890 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG
, JSON_DEC_BAD_TOKEN_ERROR
, "");
5891 return JSON_ERROR_FATAL
;
5893 else if (JSON_TOKEN_NAME
!= token
) {
5894 // undo the last action on the buffer
5895 p_tok
.set_buf_pos(buf_pos
);
5899 // check for meta info
5900 boolean is_metainfo
= FALSE
;
5901 if (name_len
> 9 && 0 == strncmp(name
, "metainfo ", 9)) {
5909 for (field_idx
= 0; field_idx
< field_count
; ++field_idx
) {
5910 const char* expected_name
= 0;
5911 if (NULL
!= fld_descr(field_idx
)->json
&& NULL
!= fld_descr(field_idx
)->json
->alias
) {
5912 expected_name
= fld_descr(field_idx
)->json
->alias
;
5914 expected_name
= fld_name(field_idx
);
5916 if (strlen(expected_name
) == name_len
&&
5917 0 == strncmp(expected_name
, name
, name_len
)) {
5918 field_found
[field_idx
] = TRUE
;
5922 if (field_count
== field_idx
) {
5923 // invalid field name
5924 char* name2
= mcopystrn(name
, name_len
);
5925 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG
, is_metainfo
?
5926 JSON_DEC_METAINFO_NAME_ERROR
: JSON_DEC_INVALID_NAME_ERROR
, name2
);
5927 // if this is set to a warning, skip the value of the field
5928 dec_len
+= p_tok
.get_next_token(&token
, NULL
, NULL
);
5929 if (JSON_TOKEN_NUMBER
!= token
&& JSON_TOKEN_STRING
!= token
&&
5930 JSON_TOKEN_LITERAL_TRUE
!= token
&& JSON_TOKEN_LITERAL_FALSE
!= token
&&
5931 JSON_TOKEN_LITERAL_NULL
!= token
) {
5932 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG
, JSON_DEC_FIELD_TOKEN_ERROR
, name2
);
5934 return JSON_ERROR_FATAL
;
5941 if (JSON_METAINFO_NOT_APPLICABLE
!= metainfo
[field_idx
]) {
5943 char* info_value
= 0;
5944 size_t info_len
= 0;
5945 dec_len
+= p_tok
.get_next_token(&token
, &info_value
, &info_len
);
5946 if (JSON_TOKEN_STRING
== token
&& 9 == info_len
&&
5947 0 == strncmp(info_value
, "\"unbound\"", 9)) {
5948 metainfo
[field_idx
] = JSON_METAINFO_UNBOUND
;
5951 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG
, JSON_DEC_METAINFO_VALUE_ERROR
,
5952 fld_name(field_idx
));
5953 return JSON_ERROR_FATAL
;
5957 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG
, JSON_DEC_METAINFO_NOT_APPLICABLE
,
5958 fld_name(field_idx
));
5959 return JSON_ERROR_FATAL
;
5963 buf_pos
= p_tok
.get_buf_pos();
5964 int ret_val
= get_at(field_idx
)->JSON_decode(*fld_descr(field_idx
), p_tok
, p_silent
);
5966 if (JSON_ERROR_INVALID_TOKEN
== ret_val
) {
5967 // undo the last action on the buffer, check if the invalid token was a null token
5968 p_tok
.set_buf_pos(buf_pos
);
5969 p_tok
.get_next_token(&token
, NULL
, NULL
);
5970 if (JSON_TOKEN_LITERAL_NULL
== token
) {
5971 if (JSON_METAINFO_NONE
== metainfo
[field_idx
]) {
5972 // delay reporting an error for now, there might be meta info later
5973 metainfo
[field_idx
] = JSON_METAINFO_NEEDED
;
5976 else if (JSON_METAINFO_UNBOUND
== metainfo
[field_idx
]) {
5977 // meta info already found
5981 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG
, JSON_DEC_FIELD_TOKEN_ERROR
, fld_name(field_idx
));
5983 return JSON_ERROR_FATAL
;
5990 dec_len
+= p_tok
.get_next_token(&token
, NULL
, NULL
);
5991 if (JSON_TOKEN_OBJECT_END
!= token
) {
5992 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG
, JSON_DEC_OBJECT_END_TOKEN_ERROR
, "");
5993 return JSON_ERROR_FATAL
;
5996 // Check if every field has been set and handle meta info
5997 for (int field_idx
= 0; field_idx
< field_count
; ++field_idx
) {
5998 Base_Type
* field
= get_at(field_idx
);
5999 if (JSON_METAINFO_UNBOUND
== metainfo
[field_idx
]) {
6002 else if (JSON_METAINFO_NEEDED
== metainfo
[field_idx
]) {
6003 // no meta info was found for this field, report the delayed error
6004 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG
, JSON_DEC_FIELD_TOKEN_ERROR
, fld_name(field_idx
));
6006 else if (!field_found
[field_idx
]) {
6007 if (NULL
!= fld_descr(field_idx
)->json
&& NULL
!= fld_descr(field_idx
)->json
->default_value
) {
6008 get_at(field_idx
)->JSON_decode(*fld_descr(field_idx
), DUMMY_BUFFER
, p_silent
);
6010 else if (field
->is_optional()) {
6011 field
->set_to_omit();
6013 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG
, JSON_DEC_MISSING_FIELD_ERROR
, fld_name(field_idx
));
6014 return JSON_ERROR_FATAL
;
6024 ////////////////////////////////////////////////////////////////////////////////
6026 Empty_Record_Type::Empty_Record_Type(): bound_flag(FALSE
)
6030 Empty_Record_Type::Empty_Record_Type(const Empty_Record_Type
& other_value
)
6031 : Base_Type(other_value
), bound_flag(other_value
.bound_flag
)
6033 if (!other_value
.bound_flag
)
6034 TTCN_error("Copying an unbound value of type %s.",
6035 other_value
.get_descriptor()->name
);
6038 boolean
Empty_Record_Type::operator==(null_type
) const
6041 TTCN_error("Comparison of an unbound value of type %s.",
6042 get_descriptor()->name
);
6046 void Empty_Record_Type::log() const
6048 if (bound_flag
) TTCN_Logger::log_event_str("{ }");
6049 else TTCN_Logger::log_event_unbound();
6052 void Empty_Record_Type::set_param(Module_Param
& param
) {
6053 param
.basic_check(Module_Param::BC_VALUE
, "empty record/set value (i.e. { })");
6054 Module_Param_Ptr mp
= ¶m
;
6055 if (param
.get_type() == Module_Param::MP_Reference
) {
6056 mp
= param
.get_referenced_param();
6058 if (mp
->get_type()!=Module_Param::MP_Value_List
|| mp
->get_size()>0) {
6059 param
.type_error("empty record/set value (i.e. { })", get_descriptor()->name
);
6064 Module_Param
* Empty_Record_Type::get_param(Module_Param_Name
& /* param_name */) const
6067 return new Module_Param_Unbound();
6069 return new Module_Param_Value_List();
6072 void Empty_Record_Type::encode_text(Text_Buf
& /*text_buf*/) const
6075 TTCN_error("Text encoder: Encoding an unbound value of type %s.",
6076 get_descriptor()->name
);
6079 void Empty_Record_Type::decode_text(Text_Buf
& /*text_buf*/)
6084 boolean
Empty_Record_Type::is_equal(const Base_Type
* other_value
) const
6086 const Empty_Record_Type
* r2
= static_cast<const Empty_Record_Type
*>(other_value
);
6087 if ((bound_flag
&& r2
->bound_flag
) || (!bound_flag
&& !r2
->bound_flag
))
6089 if (!bound_flag
|| !r2
->bound_flag
)
6090 TTCN_error("Comparison of an unbound value of type %s.", get_descriptor()->name
);
6094 void Empty_Record_Type::set_value(const Base_Type
* other_value
)
6096 if (!static_cast<const Empty_Record_Type
*>(other_value
)->is_bound())
6097 TTCN_error("Assignment of an unbound value of type %s.",
6098 other_value
->get_descriptor()->name
);
6102 void Empty_Record_Type::encode(const TTCN_Typedescriptor_t
& p_td
,
6103 TTCN_Buffer
& p_buf
, TTCN_EncDec::coding_t p_coding
, ...) const
6106 va_start(pvar
, p_coding
);
6108 case TTCN_EncDec::CT_BER
: {
6109 TTCN_EncDec_ErrorContext
ec("While BER-encoding type '%s': ", p_td
.name
);
6110 unsigned BER_coding
=va_arg(pvar
, unsigned);
6111 BER_encode_chk_coding(BER_coding
);
6112 ASN_BER_TLV_t
*tlv
=BER_encode_TLV(p_td
, BER_coding
);
6113 tlv
->put_in_buffer(p_buf
);
6114 ASN_BER_TLV_t::destruct(tlv
);
6116 case TTCN_EncDec::CT_RAW
: {
6117 TTCN_EncDec_ErrorContext
ec("While RAW-encoding type '%s': ", p_td
.name
);
6118 if(!p_td
.raw
) TTCN_EncDec_ErrorContext::error_internal
6119 ("No RAW descriptor available for type '%s'.", p_td
.name
);
6123 RAW_enc_tree
root(FALSE
, NULL
, &rp
, 1, p_td
.raw
);
6124 RAW_encode(p_td
, root
);
6125 root
.put_to_buf(p_buf
);
6127 case TTCN_EncDec::CT_TEXT
: {
6128 TTCN_EncDec_ErrorContext
ec("While TEXT-encoding type '%s': ", p_td
.name
);
6129 if(!p_td
.text
) TTCN_EncDec_ErrorContext::error_internal
6130 ("No TEXT descriptor available for type '%s'.", p_td
.name
);
6131 TEXT_encode(p_td
,p_buf
);
6133 case TTCN_EncDec::CT_XER
: {
6134 TTCN_EncDec_ErrorContext
ec("While XER-encoding type '%s': ", p_td
.name
);
6135 unsigned XER_coding
=va_arg(pvar
, unsigned);
6136 XER_encode(*(p_td
.xer
),p_buf
, XER_coding
, 0, 0);
6139 case TTCN_EncDec::CT_JSON
: {
6140 TTCN_EncDec_ErrorContext
ec("While JSON-encoding type '%s': ", p_td
.name
);
6141 if(!p_td
.json
) TTCN_EncDec_ErrorContext::error_internal
6142 ("No JSON descriptor available for type '%s'.", p_td
.name
);
6143 JSON_Tokenizer
tok(va_arg(pvar
, int) != 0);
6144 JSON_encode(p_td
, tok
);
6145 p_buf
.put_s(tok
.get_buffer_length(), (const unsigned char*)tok
.get_buffer());
6148 TTCN_error("Unknown coding method requested to encode type '%s'", p_td
.name
);
6153 void Empty_Record_Type::decode(const TTCN_Typedescriptor_t
& p_td
,
6154 TTCN_Buffer
& p_buf
, TTCN_EncDec::coding_t p_coding
, ...)
6157 va_start(pvar
, p_coding
);
6159 case TTCN_EncDec::CT_BER
: {
6160 TTCN_EncDec_ErrorContext
ec("While BER-decoding type '%s': ", p_td
.name
);
6161 unsigned L_form
=va_arg(pvar
, unsigned);
6163 BER_decode_str2TLV(p_buf
, tlv
, L_form
);
6164 BER_decode_TLV(p_td
, tlv
, L_form
);
6165 if(tlv
.isComplete
) p_buf
.increase_pos(tlv
.get_len());
6167 case TTCN_EncDec::CT_RAW
: {
6168 TTCN_EncDec_ErrorContext
ec("While RAW-decoding type '%s': ", p_td
.name
);
6170 TTCN_EncDec_ErrorContext::error_internal
6171 ("No RAW descriptor available for type '%s'.", p_td
.name
);
6173 switch(p_td
.raw
->top_bit_order
) {
6181 if(RAW_decode(p_td
, p_buf
, p_buf
.get_len()*8, order
)<0)
6182 ec
.error(TTCN_EncDec::ET_INCOMPL_MSG
,
6183 "Can not decode type '%s', because invalid or incomplete"
6184 " message was received", p_td
.name
);
6186 case TTCN_EncDec::CT_TEXT
: {
6187 Limit_Token_List limit
;
6188 TTCN_EncDec_ErrorContext
ec("While TEXT-decoding type '%s': ", p_td
.name
);
6189 if(!p_td
.text
) TTCN_EncDec_ErrorContext::error_internal
6190 ("No TEXT descriptor available for type '%s'.", p_td
.name
);
6191 const unsigned char *b
=p_buf
.get_data();
6192 if(b
[p_buf
.get_len()-1]!='\0'){
6193 p_buf
.set_pos(p_buf
.get_len());
6194 p_buf
.put_zero(8,ORDER_LSB
);
6197 if(TEXT_decode(p_td
,p_buf
,limit
)<0)
6198 ec
.error(TTCN_EncDec::ET_INCOMPL_MSG
,
6199 "Can not decode type '%s', because invalid or incomplete"
6200 " message was received", p_td
.name
);
6202 case TTCN_EncDec::CT_XER
: {
6203 TTCN_EncDec_ErrorContext
ec("While XER-decoding type '%s': ", p_td
.name
);
6204 unsigned XER_coding
=va_arg(pvar
, unsigned);
6205 XmlReaderWrap
reader(p_buf
);
6206 for (int success
=reader
.Read(); success
==1; success
=reader
.Read()) {
6207 if (reader
.NodeType() == XML_READER_TYPE_ELEMENT
) break;
6209 XER_decode(*(p_td
.xer
), reader
, XER_coding
| XER_TOPLEVEL
, XER_NONE
, 0);
6210 size_t bytes
= reader
.ByteConsumed();
6211 p_buf
.set_pos(bytes
);
6213 case TTCN_EncDec::CT_JSON
: {
6214 TTCN_EncDec_ErrorContext
ec("While JSON-decoding type '%s': ", p_td
.name
);
6215 if(!p_td
.json
) TTCN_EncDec_ErrorContext::error_internal
6216 ("No JSON descriptor available for type '%s'.", p_td
.name
);
6217 JSON_Tokenizer
tok((const char*)p_buf
.get_data(), p_buf
.get_len());
6218 if(JSON_decode(p_td
, tok
, false)<0)
6219 ec
.error(TTCN_EncDec::ET_INCOMPL_MSG
,
6220 "Can not decode type '%s', because invalid or incomplete"
6221 " message was received", p_td
.name
);
6222 p_buf
.set_pos(tok
.get_buf_pos());
6225 TTCN_error("Unknown coding method requested to decode type '%s'", p_td
.name
);
6230 ASN_BER_TLV_t
* Empty_Record_Type::BER_encode_TLV(const TTCN_Typedescriptor_t
& p_td
,
6231 unsigned p_coding
) const
6233 BER_chk_descr(p_td
);
6234 ASN_BER_TLV_t
*new_tlv
=ASN_BER_TLV_t::construct(NULL
);
6235 new_tlv
=ASN_BER_V2TLV(new_tlv
, p_td
, p_coding
);
6239 boolean
Empty_Record_Type::BER_decode_TLV(const TTCN_Typedescriptor_t
& p_td
,
6240 const ASN_BER_TLV_t
& p_tlv
, unsigned L_form
)
6242 BER_chk_descr(p_td
);
6243 ASN_BER_TLV_t stripped_tlv
;
6244 BER_decode_strip_tags(*p_td
.ber
, p_tlv
, L_form
, stripped_tlv
);
6245 TTCN_EncDec_ErrorContext
ec_0("While decoding '%s' type: ", get_descriptor()->name
);
6246 stripped_tlv
.chk_constructed_flag(TRUE
);
6251 int Empty_Record_Type::RAW_encode(const TTCN_Typedescriptor_t
& p_td
,
6252 RAW_enc_tree
& /*myleaf*/) const
6254 if (!bound_flag
) TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND
,
6255 "Encoding an unbound value of type %s.", p_td
.name
);
6259 int Empty_Record_Type::RAW_decode(const TTCN_Typedescriptor_t
& p_td
,
6260 TTCN_Buffer
& buff
, int /*limit*/, raw_order_t
/*top_bit_ord*/,
6261 boolean
/*no_err*/, int /*sel_field*/, boolean
/*first_call*/)
6264 return buff
.increase_pos_padd(p_td
.raw
->prepadding
)
6265 + buff
.increase_pos_padd(p_td
.raw
->padding
);
6268 int Empty_Record_Type::TEXT_encode(const TTCN_Typedescriptor_t
& p_td
, TTCN_Buffer
& buff
) const
6270 int encoded_length
=0;
6271 if(p_td
.text
->begin_encode
) {
6272 buff
.put_cs(*p_td
.text
->begin_encode
);
6273 encoded_length
+=p_td
.text
->begin_encode
->lengthof();
6276 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND
, "Encoding an unbound value.");
6278 if(p_td
.text
->end_encode
) {
6279 buff
.put_cs(*p_td
.text
->end_encode
);
6280 encoded_length
+=p_td
.text
->end_encode
->lengthof();
6282 return encoded_length
;
6285 int Empty_Record_Type::TEXT_decode(const TTCN_Typedescriptor_t
& p_td
,
6286 TTCN_Buffer
& buff
, Limit_Token_List
& /*limit*/, boolean no_err
, boolean
/*first_call*/)
6288 int decoded_length
=0;
6289 if(p_td
.text
->begin_decode
) {
6291 if((tl
=p_td
.text
->begin_decode
->match_begin(buff
))<0) {
6292 if(no_err
)return -1;
6293 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR
,
6294 "The specified token '%s' not found for '%s': ",
6295 (const char*)*(p_td
.text
->begin_decode
), p_td
.name
);
6299 buff
.increase_pos(tl
);
6301 if(p_td
.text
->end_decode
) {
6303 if((tl
=p_td
.text
->end_decode
->match_begin(buff
))<0) {
6304 if(no_err
)return -1;
6305 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR
,
6306 "The specified token '%s' not found for '%s': ",
6307 (const char*)*(p_td
.text
->end_decode
), p_td
.name
);
6311 buff
.increase_pos(tl
);
6314 return decoded_length
;
6317 int Empty_Record_Type::XER_encode(const XERdescriptor_t
& p_td
,
6318 TTCN_Buffer
& p_buf
, unsigned int flavor
, int indent
, embed_values_enc_struct_t
*) const
6320 int encoded_length
=(int)p_buf
.get_len();
6321 int indenting
= !is_canonical(flavor
);
6322 int exer
= is_exer(flavor
);
6323 if (indenting
) do_indent(p_buf
, indent
);
6325 if (exer
) write_ns_prefix(p_td
, p_buf
);
6326 p_buf
.put_s((size_t)p_td
.namelens
[exer
]-2, (cbyte
*)p_td
.names
[exer
]);
6327 p_buf
.put_s(2 + indenting
, (cbyte
*)"/>\n");
6328 return (int)p_buf
.get_len() - encoded_length
;
6331 int Empty_Record_Type::XER_decode(const XERdescriptor_t
& p_td
,
6332 XmlReaderWrap
& reader
, unsigned int flavor
, unsigned int /*flavor2*/, embed_values_dec_struct_t
*)
6334 int exer
= is_exer(flavor
);
6336 int success
, depth
= -1;
6337 for (success
=reader
.Ok(); success
==1; success
=reader
.Read()) {
6338 int type
= reader
.NodeType();
6339 if (type
==XML_READER_TYPE_ELEMENT
) {
6340 verify_name(reader
, p_td
, exer
);
6341 depth
= reader
.Depth();
6343 if (reader
.IsEmptyElement()) {
6344 reader
.Read(); break;
6346 else if ((flavor
& XER_MASK
) == XER_CANONICAL
) {
6347 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG
,
6348 "Expected an empty element tag");
6349 // Stay in the loop and look for the end element, in case the error
6350 // was ignored or reduced to warning.
6353 else if (type
== XML_READER_TYPE_END_ELEMENT
&& depth
!= -1) {
6354 verify_end(reader
, p_td
, depth
, exer
);
6359 return 1; // decode successful
6362 int Empty_Record_Type::JSON_encode(const TTCN_Typedescriptor_t
&, JSON_Tokenizer
& p_tok
) const
6365 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND
,
6366 "Encoding an unbound empty %s value.", is_set() ? "set" : "record");
6370 return p_tok
.put_next_token(JSON_TOKEN_OBJECT_START
, NULL
) +
6371 p_tok
.put_next_token(JSON_TOKEN_OBJECT_END
, NULL
);
6374 int Empty_Record_Type::JSON_decode(const TTCN_Typedescriptor_t
&, JSON_Tokenizer
& p_tok
, boolean p_silent
)
6376 json_token_t token
= JSON_TOKEN_NONE
;
6377 int dec_len
= p_tok
.get_next_token(&token
, NULL
, NULL
);
6378 if (JSON_TOKEN_ERROR
== token
) {
6379 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG
, JSON_DEC_BAD_TOKEN_ERROR
, "");
6380 return JSON_ERROR_FATAL
;
6382 else if (JSON_TOKEN_OBJECT_START
!= token
) {
6383 return JSON_ERROR_INVALID_TOKEN
;
6386 dec_len
+= p_tok
.get_next_token(&token
, NULL
, NULL
);
6387 if (JSON_TOKEN_OBJECT_END
!= token
) {
6388 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG
, JSON_DEC_STATIC_OBJECT_END_TOKEN_ERROR
, "");
6389 return JSON_ERROR_FATAL
;
6397 boolean
operator==(null_type
/*null_value*/, const Empty_Record_Type
& other_value
)
6399 if (!other_value
.is_bound())
6400 TTCN_error("Comparison of an unbound value of type %s.",
6401 other_value
.get_descriptor()->name
);
6405 boolean
operator!=(null_type
/*null_value*/, const Empty_Record_Type
& other_value
)
6407 if (!other_value
.is_bound())
6408 TTCN_error("Comparison of an unbound value of type %s.",
6409 other_value
.get_descriptor()->name
);