1 ///////////////////////////////////////////////////////////////////////////////
2 // Copyright (c) 2000-2015 Ericsson Telecom AB
3 // All rights reserved. This program and the accompanying materials
4 // are made available under the terms of the Eclipse Public License v1.0
5 // which accompanies this distribution, and is available at
6 // http://www.eclipse.org/legal/epl-v10.html
7 ///////////////////////////////////////////////////////////////////////////////
14 #include "Module_list.hh"
18 #ifdef TITAN_RUNTIME_2
21 #include "Charstring.hh"
22 #include "Universal_charstring.hh"
24 #include "PreGenRecordOf.hh"
26 ////////////////////////////////////////////////////////////////////////////////
28 const Erroneous_values_t
* Erroneous_descriptor_t::get_field_err_values(int field_idx
) const
30 for (int i
=0; i
<values_size
; i
++) {
31 if (values_vec
[i
].field_index
==field_idx
) return (values_vec
+i
);
32 if (values_vec
[i
].field_index
>field_idx
) return NULL
;
37 const Erroneous_values_t
* Erroneous_descriptor_t::next_field_err_values(
38 const int field_idx
, int& values_idx
) const
40 const Erroneous_values_t
* err_vals
= NULL
;
41 if ( (values_idx
<values_size
) && (values_vec
[values_idx
].field_index
==field_idx
) ) {
42 err_vals
= values_vec
+values_idx
;
48 const Erroneous_descriptor_t
* Erroneous_descriptor_t::get_field_emb_descr(int field_idx
) const
50 for (int i
=0; i
<embedded_size
; i
++) {
51 if (embedded_vec
[i
].field_index
==field_idx
) return (embedded_vec
+i
);
52 if (embedded_vec
[i
].field_index
>field_idx
) return NULL
;
57 const Erroneous_descriptor_t
* Erroneous_descriptor_t::next_field_emb_descr(
58 const int field_idx
, int& edescr_idx
) const
60 const Erroneous_descriptor_t
* emb_descr
= NULL
;
61 if ( (edescr_idx
<embedded_size
) && (embedded_vec
[edescr_idx
].field_index
==field_idx
) ) {
62 emb_descr
= embedded_vec
+edescr_idx
;
68 void Erroneous_descriptor_t::log() const
70 TTCN_Logger::log_event_str(" with erroneous { ");
72 TTCN_Logger::log_event_str("}");
75 void Erroneous_descriptor_t::log_() const
77 if (omit_before
!=-1) {
78 if (omit_before_qualifier
==NULL
) TTCN_error(
79 "internal error: Erroneous_descriptor_t::log()");
80 TTCN_Logger::log_event("{ before %s := omit all } ", omit_before_qualifier
);
83 if (omit_after_qualifier
==NULL
) TTCN_error(
84 "internal error: Erroneous_descriptor_t::log()");
85 TTCN_Logger::log_event("{ after %s := omit all } ", omit_after_qualifier
);
87 for (int i
=0; i
<values_size
; i
++) {
88 if (values_vec
[i
].field_qualifier
==NULL
) TTCN_error(
89 "internal error: Erroneous_descriptor_t::log()");
90 if (values_vec
[i
].before
) {
91 TTCN_Logger::log_event("{ before%s %s := ",
92 values_vec
[i
].before
->raw
? "(raw)" : "", values_vec
[i
].field_qualifier
);
93 if (values_vec
[i
].before
->errval
) values_vec
[i
].before
->errval
->log();
94 else TTCN_Logger::log_event_str("omit");
95 TTCN_Logger::log_event_str(" } ");
97 if (values_vec
[i
].value
) {
98 TTCN_Logger::log_event("{ value%s %s := ",
99 values_vec
[i
].value
->raw
? "(raw)" : "", values_vec
[i
].field_qualifier
);
100 if (values_vec
[i
].value
->errval
) values_vec
[i
].value
->errval
->log();
101 else TTCN_Logger::log_event_str("omit");
102 TTCN_Logger::log_event_str(" } ");
104 if (values_vec
[i
].after
) {
105 TTCN_Logger::log_event("{ after%s %s := ",
106 values_vec
[i
].after
->raw
? "(raw)" : "", values_vec
[i
].field_qualifier
);
107 if (values_vec
[i
].after
->errval
) values_vec
[i
].after
->errval
->log();
108 else TTCN_Logger::log_event_str("omit");
109 TTCN_Logger::log_event_str(" } ");
112 for (int i
=0; i
<embedded_size
; i
++) {
113 embedded_vec
[i
].log_();
117 void Base_Type::set_to_omit()
119 TTCN_error("Internal error: trying to set a non-optional field to OMIT.");
122 void Base_Type::set_to_present()
124 TTCN_error("Internal error: calling set_to_present() on a non-optional value.");
127 boolean
Base_Type::is_present() const
132 Base_Type
* Base_Type::get_opt_value()
134 TTCN_error("Internal error: calling get_opt_value() on a non-optional value.");
138 const Base_Type
* Base_Type::get_opt_value() const
140 TTCN_error("Internal error: calling get_opt_value() const on a non-optional value.");
144 ASN_BER_TLV_t
* Base_Type::BER_encode_TLV_negtest(const Erroneous_descriptor_t
* /*p_err_descr*/,
145 const TTCN_Typedescriptor_t
& /*p_td*/, unsigned /*p_coding*/) const
147 TTCN_error("Internal error: calling Base_Type::BER_encode_TLV_negtest().");
151 int Base_Type::TEXT_encode_negtest(const Erroneous_descriptor_t
* /*p_err_descr*/,
152 const TTCN_Typedescriptor_t
& /*p_td*/, TTCN_Buffer
& /*p_buf*/) const
154 TTCN_error("Internal error: calling Base_Type::TEXT_encode_negtest().");
158 ASN_BER_TLV_t
* Base_Type::BER_encode_negtest_raw() const
160 TTCN_error("A value of type %s cannot be used as erroneous raw value for BER encoding.",
161 get_descriptor()->name
);
165 int Base_Type::encode_raw(TTCN_Buffer
&) const
167 TTCN_error("A value of type %s cannot be used as erroneous raw value for encoding.",
168 get_descriptor()->name
);
172 int Base_Type::RAW_encode_negtest_raw(RAW_enc_tree
&) const
174 TTCN_error("A value of type %s cannot be used as erroneous raw value for encoding.",
175 get_descriptor()->name
);
179 int Base_Type::JSON_encode_negtest_raw(JSON_Tokenizer
&) const
181 TTCN_error("A value of type %s cannot be used as erroneous raw value for JSON encoding.",
182 get_descriptor()->name
);
186 int Base_Type::XER_encode_negtest(const Erroneous_descriptor_t
* /*p_err_descr*/,
187 const XERdescriptor_t
& p_td
, TTCN_Buffer
& p_buf
, unsigned int flavor
, int indent
, embed_values_enc_struct_t
*) const
189 return XER_encode(p_td
, p_buf
, flavor
, indent
, 0); // ignore erroneous
192 int Base_Type::RAW_encode_negtest(const Erroneous_descriptor_t
*,
193 const TTCN_Typedescriptor_t
&, RAW_enc_tree
&) const
195 TTCN_error("Internal error: calling Base_Type::RAW_encode_negtest().");
199 int Base_Type::JSON_encode_negtest(const Erroneous_descriptor_t
* /*p_err_descr*/,
200 const TTCN_Typedescriptor_t
& /*p_td*/, JSON_Tokenizer
& /*p_tok*/) const
202 TTCN_error("Internal error: calling Base_Type::JSON_encode_negtest().");
207 #error this is for RT2 only
210 #ifdef TITAN_RUNTIME_2
212 boolean
Record_Of_Type::compare_function(const Record_Of_Type
*left_ptr
,
213 int left_index
, const Record_Of_Type
*right_ptr
, int right_index
)
215 if (left_ptr
->val_ptr
== NULL
)
216 TTCN_error("The left operand of comparison is an unbound value of type %s.",
217 left_ptr
->get_descriptor()->name
);
218 if (right_ptr
->val_ptr
== NULL
)
219 TTCN_error("The right operand of comparison is an unbound value of type %s.",
220 right_ptr
->get_descriptor()->name
);
222 const Base_Type
* elem
= left_ptr
->val_ptr
->value_elements
[left_index
];
223 const Base_Type
* other_elem
= right_ptr
->val_ptr
->value_elements
[right_index
];
225 if (other_elem
!= NULL
) { // both are bound, compare them
226 return elem
->is_equal(other_elem
);
230 else { // elem unbound, they can be equal only if other_elem is unbound too
231 return other_elem
== NULL
;
235 void Record_Of_Type::clean_up()
237 if (val_ptr
!= NULL
) {
238 if (val_ptr
->ref_count
> 1) {
239 val_ptr
->ref_count
--;
242 else if (val_ptr
->ref_count
== 1) {
243 if (NULL
== refd_ind_ptr
) {
244 for (int elem_count
= 0; elem_count
< val_ptr
->n_elements
; elem_count
++) {
245 if (val_ptr
->value_elements
[elem_count
] != NULL
) {
246 delete val_ptr
->value_elements
[elem_count
];
249 free_pointers((void**)val_ptr
->value_elements
);
258 TTCN_error("Internal error: Invalid reference counter in "
259 "a record of/set of value.");
264 Record_Of_Type::Record_Of_Type(null_type
/*other_value*/)
265 : Base_Type(), val_ptr(new recordof_setof_struct
), err_descr(NULL
), refd_ind_ptr(NULL
)
267 val_ptr
->ref_count
= 1;
268 val_ptr
->n_elements
= 0;
269 val_ptr
->value_elements
= NULL
;
272 Record_Of_Type::Record_Of_Type(const Record_Of_Type
& other_value
)
273 : Base_Type(other_value
), RefdIndexInterface(other_value
)
274 , val_ptr(NULL
), err_descr(other_value
.err_descr
), refd_ind_ptr(NULL
)
276 if (!other_value
.is_bound())
277 TTCN_error("Copying an unbound record of/set of value.");
278 // Increment ref_count only if val_ptr is not NULL
279 if (other_value
.val_ptr
!= NULL
) {
280 if (NULL
== other_value
.refd_ind_ptr
) {
281 val_ptr
= other_value
.val_ptr
;
282 val_ptr
->ref_count
++;
285 // there are references to at least one element => the array must be copied
286 int nof_elements
= other_value
.get_nof_elements();
287 set_size(nof_elements
);
288 for (int i
= 0; i
< nof_elements
; ++i
) {
289 if (other_value
.is_elem_bound(i
)) {
290 val_ptr
->value_elements
[i
] = other_value
.val_ptr
->value_elements
[i
]->clone();
297 int Record_Of_Type::get_nof_elements() const
299 int nof_elements
= (val_ptr
!= NULL
) ? val_ptr
->n_elements
: 0;
300 if (NULL
!= refd_ind_ptr
) {
301 while (nof_elements
> 0) {
302 if (is_elem_bound(nof_elements
- 1)) {
311 bool Record_Of_Type::is_elem_bound(int index
) const
313 return val_ptr
->value_elements
[index
] != NULL
&&
314 val_ptr
->value_elements
[index
]->is_bound();
317 int Record_Of_Type::get_max_refd_index()
319 if (NULL
== refd_ind_ptr
) {
322 if (-1 == refd_ind_ptr
->max_refd_index
) {
323 for (size_t i
= 0; i
< refd_ind_ptr
->refd_indices
.size(); ++i
) {
324 if (refd_ind_ptr
->refd_indices
[i
] > refd_ind_ptr
->max_refd_index
) {
325 refd_ind_ptr
->max_refd_index
= refd_ind_ptr
->refd_indices
[i
];
329 return refd_ind_ptr
->max_refd_index
;
332 bool Record_Of_Type::is_index_refd(int index
)
334 if (NULL
== refd_ind_ptr
) {
337 for (size_t i
= 0; i
< refd_ind_ptr
->refd_indices
.size(); ++i
) {
338 if (index
== refd_ind_ptr
->refd_indices
[i
]) {
345 void Record_Of_Type::set_val(null_type
)
350 boolean
Record_Of_Type::is_equal(const Base_Type
* other_value
) const
352 const Record_Of_Type
* other_recof
= static_cast<const Record_Of_Type
*>(other_value
);
354 TTCN_error("The left operand of comparison is an unbound value of type %s.",
355 get_descriptor()->name
);
356 if (other_recof
->val_ptr
== NULL
)
357 TTCN_error("The right operand of comparison is an unbound value of type %s.",
358 other_value
->get_descriptor()->name
);
359 if (val_ptr
== other_recof
->val_ptr
) return TRUE
;
361 return compare_set_of(this, get_nof_elements(), other_recof
,
362 other_recof
->get_nof_elements(), compare_function
);
364 if (get_nof_elements() != other_recof
->get_nof_elements()) return FALSE
;
365 for (int elem_count
= 0; elem_count
< get_nof_elements(); elem_count
++) {
366 if (is_elem_bound(elem_count
)) {
367 if (other_recof
->is_elem_bound(elem_count
)) {
368 if (!val_ptr
->value_elements
[elem_count
]->is_equal(other_recof
->val_ptr
->value_elements
[elem_count
]))
371 } else if (other_recof
->is_elem_bound(elem_count
)) return FALSE
;
377 void Record_Of_Type::set_value(const Base_Type
* other_value
)
379 const Record_Of_Type
* other_recof
= static_cast<const Record_Of_Type
*>(other_value
);
380 if (!other_recof
->is_bound())
381 TTCN_error("Assigning an unbound value of type %s.",
382 other_value
->get_descriptor()->name
);
383 if (this != other_recof
) {
384 if (NULL
== refd_ind_ptr
&& NULL
== other_recof
->refd_ind_ptr
) {
386 val_ptr
= other_recof
->val_ptr
;
387 val_ptr
->ref_count
++;
390 // there are references to at least one element => the array must be copied
391 int nof_elements
= other_recof
->get_nof_elements();
392 set_size(nof_elements
);
393 for (int i
= 0; i
< nof_elements
; ++i
) {
394 if (other_recof
->is_elem_bound(i
)) {
395 if (val_ptr
->value_elements
[i
] == NULL
) {
396 val_ptr
->value_elements
[i
] = create_elem();
398 val_ptr
->value_elements
[i
]->set_value(other_recof
->val_ptr
->value_elements
[i
]);
400 else if (val_ptr
->value_elements
[i
] != NULL
) {
401 if (is_index_refd(i
)) {
402 val_ptr
->value_elements
[i
]->clean_up();
405 delete val_ptr
->value_elements
[i
];
406 val_ptr
->value_elements
[i
] = NULL
;
412 err_descr
= other_recof
->err_descr
;
415 boolean
Record_Of_Type::operator!=(null_type other_value
) const
417 return !(*this == other_value
);
420 Base_Type
* Record_Of_Type::get_at(int index_value
)
423 TTCN_error("Accessing an element of type %s using a negative index: %d.",
424 get_descriptor()->name
, index_value
);
425 if (val_ptr
== NULL
) {
426 val_ptr
= new recordof_setof_struct
;
427 val_ptr
->ref_count
= 1;
428 val_ptr
->n_elements
= 0;
429 val_ptr
->value_elements
= NULL
;
430 } else if (val_ptr
->ref_count
> 1) {
431 struct recordof_setof_struct
*new_val_ptr
= new recordof_setof_struct
;
432 new_val_ptr
->ref_count
= 1;
433 new_val_ptr
->n_elements
= (index_value
>= val_ptr
->n_elements
) ?
434 index_value
+ 1 : val_ptr
->n_elements
;
435 new_val_ptr
->value_elements
=
436 (Base_Type
**)allocate_pointers(new_val_ptr
->n_elements
);
437 for (int elem_count
= 0; elem_count
< val_ptr
->n_elements
; elem_count
++)
439 if (val_ptr
->value_elements
[elem_count
] != NULL
) {
440 new_val_ptr
->value_elements
[elem_count
] =
441 val_ptr
->value_elements
[elem_count
]->clone();
444 val_ptr
->ref_count
--;
445 val_ptr
= new_val_ptr
;
447 if (index_value
>= val_ptr
->n_elements
) set_size(index_value
+ 1);
448 if (val_ptr
->value_elements
[index_value
] == NULL
) {
449 val_ptr
->value_elements
[index_value
] = create_elem();
451 return val_ptr
->value_elements
[index_value
];
454 Base_Type
* Record_Of_Type::get_at(const INTEGER
& index_value
)
456 if (!index_value
.is_bound())
457 TTCN_error("Using an unbound integer value for indexing a value "
458 "of type %s.", get_descriptor()->name
);
459 return get_at((int)index_value
);
462 const Base_Type
* Record_Of_Type::get_at(int index_value
) const
465 TTCN_error("Accessing an element in an unbound value of type %s.",
466 get_descriptor()->name
);
468 TTCN_error("Accessing an element of type %s using a negative index: %d.",
469 get_descriptor()->name
, index_value
);
470 if (index_value
>= get_nof_elements())
471 TTCN_error("Index overflow in a value of type %s: The index is %d, but the "
472 "value has only %d elements.", get_descriptor()->name
, index_value
,
474 return (val_ptr
->value_elements
[index_value
] != NULL
) ?
475 val_ptr
->value_elements
[index_value
] : get_unbound_elem();
478 const Base_Type
* Record_Of_Type::get_at(const INTEGER
& index_value
) const
480 if (!index_value
.is_bound())
481 TTCN_error("Using an unbound integer value for indexing a value "
482 "of type %s.", get_descriptor()->name
);
483 return get_at((int)index_value
);
486 Record_Of_Type
* Record_Of_Type::rotl(const INTEGER
& rotate_count
, Record_Of_Type
* rec_of
) const
488 if (!rotate_count
.is_bound())
489 TTCN_error("Unbound integer operand of rotate left operator of type %s.",
490 get_descriptor()->name
);
491 return rotr((int)(-rotate_count
), rec_of
);
494 Record_Of_Type
* Record_Of_Type::rotr(const INTEGER
& rotate_count
, Record_Of_Type
* rec_of
) const
496 if (!rotate_count
.is_bound())
497 TTCN_error("Unbound integer operand of rotate right operator of type %s.",
498 get_descriptor()->name
);
499 return rotr((int)rotate_count
, rec_of
);
502 Record_Of_Type
* Record_Of_Type::rotr(int rotate_count
, Record_Of_Type
* rec_of
) const
505 TTCN_error("Performing rotation operation on an unbound value of type %s.",
506 get_descriptor()->name
);
507 int nof_elements
= get_nof_elements();
508 if (nof_elements
== 0) return const_cast<Record_Of_Type
*>(this);
510 if (rotate_count
>=0) rc
= rotate_count
% nof_elements
;
511 else rc
= nof_elements
- ((-rotate_count
) % nof_elements
);
512 if (rc
== 0) return const_cast<Record_Of_Type
*>(this);
513 rec_of
->set_size(nof_elements
);
515 for (int i
=0; i
<nof_elements
; i
++) {
516 rot_i
= (i
+rc
) % nof_elements
;
517 if (is_elem_bound(i
)) {
518 if (rec_of
->val_ptr
->value_elements
[rot_i
] == NULL
) {
519 rec_of
->val_ptr
->value_elements
[rot_i
] = rec_of
->create_elem();
521 rec_of
->val_ptr
->value_elements
[rot_i
]->set_value(val_ptr
->value_elements
[i
]);
522 } else if (rec_of
->is_elem_bound(rot_i
)) {
523 delete rec_of
->val_ptr
->value_elements
[rot_i
];
524 rec_of
->val_ptr
->value_elements
[rot_i
] = NULL
;
530 Record_Of_Type
* Record_Of_Type::concat(const Record_Of_Type
* other_value
,
531 Record_Of_Type
* rec_of
) const
533 if (val_ptr
== NULL
|| other_value
->val_ptr
== NULL
)
534 TTCN_error("Unbound operand of %s concatenation.", get_descriptor()->name
);
535 int nof_elements
= get_nof_elements();
536 if (nof_elements
== 0) return const_cast<Record_Of_Type
*>(other_value
);
537 int other_value_nof_elements
= other_value
->get_nof_elements();
538 if (other_value_nof_elements
== 0) return const_cast<Record_Of_Type
*>(this);
539 rec_of
->set_size(nof_elements
+ other_value_nof_elements
);
540 for (int i
=0; i
<nof_elements
; i
++) {
541 if (is_elem_bound(i
)) {
542 if (rec_of
->val_ptr
->value_elements
[i
] == NULL
) {
543 rec_of
->val_ptr
->value_elements
[i
] = rec_of
->create_elem();
545 rec_of
->val_ptr
->value_elements
[i
]->set_value(val_ptr
->value_elements
[i
]);
546 } else if (rec_of
->val_ptr
->value_elements
[i
] != NULL
) {
547 if (rec_of
->is_index_refd(i
)) {
548 rec_of
->val_ptr
->value_elements
[i
]->clean_up();
551 delete rec_of
->val_ptr
->value_elements
[i
];
552 rec_of
->val_ptr
->value_elements
[i
] = NULL
;
557 for (int i
=0; i
<other_value_nof_elements
; i
++) {
558 cat_i
= i
+ nof_elements
;
559 if (other_value
->is_elem_bound(i
)) {
560 if (rec_of
->val_ptr
->value_elements
[cat_i
] == NULL
) {
561 rec_of
->val_ptr
->value_elements
[cat_i
] = rec_of
->create_elem();
563 rec_of
->val_ptr
->value_elements
[cat_i
]->
564 set_value(other_value
->val_ptr
->value_elements
[i
]);
565 } else if (rec_of
->val_ptr
->value_elements
[cat_i
] != NULL
) {
566 if (rec_of
->is_index_refd(cat_i
)) {
567 rec_of
->val_ptr
->value_elements
[cat_i
]->clean_up();
570 delete rec_of
->val_ptr
->value_elements
[cat_i
];
571 rec_of
->val_ptr
->value_elements
[cat_i
] = NULL
;
578 void Record_Of_Type::substr_(int index
, int returncount
,
579 Record_Of_Type
* rec_of
) const
582 TTCN_error("The first argument of substr() is an unbound value of type %s.",
583 get_descriptor()->name
);
584 check_substr_arguments(get_nof_elements(), index
, returncount
,
585 get_descriptor()->name
, "element");
586 rec_of
->set_size(returncount
);
587 for (int i
=0; i
<returncount
; i
++) {
588 if (is_elem_bound(i
+ index
)) {
589 if (rec_of
->val_ptr
->value_elements
[i
] == NULL
) {
590 rec_of
->val_ptr
->value_elements
[i
] = rec_of
->create_elem();
592 rec_of
->val_ptr
->value_elements
[i
]->
593 set_value(val_ptr
->value_elements
[i
+index
]);
594 } else if (rec_of
->val_ptr
->value_elements
[i
] != NULL
) {
595 if (rec_of
->is_index_refd(i
)) {
596 rec_of
->val_ptr
->value_elements
[i
]->clean_up();
599 delete rec_of
->val_ptr
->value_elements
[i
];
600 rec_of
->val_ptr
->value_elements
[i
] = NULL
;
606 void Record_Of_Type::replace_(int index
, int len
,
607 const Record_Of_Type
* repl
, Record_Of_Type
* rec_of
) const
610 TTCN_error("The first argument of replace() is an unbound value "
611 "of type %s.", get_descriptor()->name
);
612 if (repl
->val_ptr
== NULL
)
613 TTCN_error("The fourth argument of replace() is an unbound value of "
614 "type %s.", get_descriptor()->name
);
615 int nof_elements
= get_nof_elements();
616 check_replace_arguments(nof_elements
, index
, len
,
617 get_descriptor()->name
, "element");
618 int repl_nof_elements
= repl
->get_nof_elements();
619 rec_of
->set_size(nof_elements
+ repl_nof_elements
- len
);
620 for (int i
= 0; i
< index
; i
++) {
621 if (is_elem_bound(i
)) {
622 if (rec_of
->val_ptr
->value_elements
[i
] == NULL
) {
623 rec_of
->val_ptr
->value_elements
[i
] = rec_of
->create_elem();
625 rec_of
->val_ptr
->value_elements
[i
]->set_value(val_ptr
->value_elements
[i
]);
626 } else if (rec_of
->val_ptr
->value_elements
[i
] != NULL
) {
627 if (rec_of
->is_index_refd(i
)) {
628 rec_of
->val_ptr
->value_elements
[i
]->clean_up();
631 delete rec_of
->val_ptr
->value_elements
[i
];
632 rec_of
->val_ptr
->value_elements
[i
] = NULL
;
636 for (int i
= 0; i
< repl_nof_elements
; i
++) {
637 if (repl
->is_elem_bound(i
)) {
638 if (rec_of
->val_ptr
->value_elements
[i
+index
] == NULL
) {
639 rec_of
->val_ptr
->value_elements
[i
+index
] = rec_of
->create_elem();
641 rec_of
->val_ptr
->value_elements
[i
+index
]->
642 set_value(repl
->val_ptr
->value_elements
[i
]);
643 } else if (rec_of
->val_ptr
->value_elements
[i
+index
] != NULL
) {
644 if (rec_of
->is_index_refd(i
+index
)) {
645 rec_of
->val_ptr
->value_elements
[i
+index
]->clean_up();
648 delete rec_of
->val_ptr
->value_elements
[i
+index
];
649 rec_of
->val_ptr
->value_elements
[i
+index
] = NULL
;
654 for (int i
= 0; i
< nof_elements
- index
- len
; i
++) {
655 repl_i
= index
+i
+repl_nof_elements
;
656 if (is_elem_bound(index
+i
+len
)) {
657 if (rec_of
->val_ptr
->value_elements
[repl_i
] == NULL
) {
658 rec_of
->val_ptr
->value_elements
[repl_i
] = rec_of
->create_elem();
660 rec_of
->val_ptr
->value_elements
[repl_i
]->
661 set_value(val_ptr
->value_elements
[index
+i
+len
]);
662 } else if (rec_of
->val_ptr
->value_elements
[repl_i
] != NULL
) {
663 if (rec_of
->is_index_refd(repl_i
)) {
664 rec_of
->val_ptr
->value_elements
[repl_i
]->clean_up();
667 delete rec_of
->val_ptr
->value_elements
[repl_i
];
668 rec_of
->val_ptr
->value_elements
[repl_i
] = NULL
;
674 void Record_Of_Type::replace_(int index
, int len
,
675 const Record_Of_Template
* repl
, Record_Of_Type
* rec_of
) const
677 if (!repl
->is_value())
678 TTCN_error("The fourth argument of function replace() is a template "
679 "of type %s with non-specific value.", get_descriptor()->name
);
680 rec_of
->set_val(NULL_VALUE
);
681 Base_Type
* repl_value
= rec_of
->clone();
682 repl
->valueofv(repl_value
);
683 replace_(index
, len
, static_cast<Record_Of_Type
*>(repl_value
), rec_of
);
687 void Record_Of_Type::replace_(int index
, int len
,
688 const Set_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::set_size(int new_size
)
703 TTCN_error("Internal error: Setting a negative size for a value of "
704 "type %s.", get_descriptor()->name
);
705 if (val_ptr
== NULL
) {
706 val_ptr
= new recordof_setof_struct
;
707 val_ptr
->ref_count
= 1;
708 val_ptr
->n_elements
= 0;
709 val_ptr
->value_elements
= NULL
;
710 } else if (val_ptr
->ref_count
> 1) {
711 struct recordof_setof_struct
*new_val_ptr
= new recordof_setof_struct
;
712 new_val_ptr
->ref_count
= 1;
713 new_val_ptr
->n_elements
= (new_size
< val_ptr
->n_elements
) ?
714 new_size
: val_ptr
->n_elements
;
715 new_val_ptr
->value_elements
=
716 (Base_Type
**)allocate_pointers(new_val_ptr
->n_elements
);
717 for (int elem_count
= 0; elem_count
< new_val_ptr
->n_elements
; elem_count
++) {
718 if (val_ptr
->value_elements
[elem_count
] != NULL
) {
719 new_val_ptr
->value_elements
[elem_count
] =
720 val_ptr
->value_elements
[elem_count
]->clone();
724 val_ptr
= new_val_ptr
;
726 if (new_size
> val_ptr
->n_elements
) {
727 val_ptr
->value_elements
= (Base_Type
**)
728 reallocate_pointers((void**)val_ptr
->value_elements
, val_ptr
->n_elements
, new_size
);
729 val_ptr
->n_elements
= new_size
;
730 } else if (new_size
< val_ptr
->n_elements
) {
731 for (int elem_count
= new_size
; elem_count
< val_ptr
->n_elements
; elem_count
++) {
732 if (val_ptr
->value_elements
[elem_count
] != NULL
) {
733 if (is_index_refd(elem_count
)) {
734 val_ptr
->value_elements
[elem_count
]->clean_up();
737 delete val_ptr
->value_elements
[elem_count
];
738 val_ptr
->value_elements
[elem_count
] = 0;
742 if (new_size
<= get_max_refd_index()) {
743 new_size
= get_max_refd_index() + 1;
745 if (new_size
< val_ptr
->n_elements
) {
746 val_ptr
->value_elements
= (Base_Type
**)
747 reallocate_pointers((void**)val_ptr
->value_elements
, val_ptr
->n_elements
, new_size
);
748 val_ptr
->n_elements
= new_size
;
753 boolean
Record_Of_Type::is_bound() const
755 if (NULL
== refd_ind_ptr
) {
756 return (val_ptr
!= NULL
);
758 return (get_nof_elements() != 0);
761 boolean
Record_Of_Type::is_value() const
763 if (val_ptr
== NULL
) return FALSE
;
764 for (int i
=0; i
< get_nof_elements(); ++i
)
765 if (!is_elem_bound(i
) ||
766 !val_ptr
->value_elements
[i
]->is_value()) return FALSE
;
770 int Record_Of_Type::size_of() const
773 TTCN_error("Performing sizeof operation on an unbound value of type %s.",
774 get_descriptor()->name
);
775 return get_nof_elements();
778 int Record_Of_Type::lengthof() const
781 TTCN_error("Performing lengthof operation on an unbound value of "
782 "type %s.", get_descriptor()->name
);
783 for (int my_length
=get_nof_elements(); my_length
>0; my_length
--)
784 if (is_elem_bound(my_length
- 1)) return my_length
;
788 void Record_Of_Type::log() const
790 if (val_ptr
== NULL
) {
791 TTCN_Logger::log_event_unbound();
794 if (get_nof_elements()==0) {
795 TTCN_Logger::log_event_str("{ }");
797 TTCN_Logger::log_event_str("{ ");
798 for (int elem_count
= 0; elem_count
< get_nof_elements(); elem_count
++) {
799 if (elem_count
> 0) TTCN_Logger::log_event_str(", ");
800 get_at(elem_count
)->log();
802 TTCN_Logger::log_event_str(" }");
804 if (err_descr
) err_descr
->log();
807 void Record_Of_Type::encode_text(Text_Buf
& text_buf
) const
810 TTCN_error("Text encoder: Encoding an unbound value of type %s.",
811 get_descriptor()->name
);
812 text_buf
.push_int(get_nof_elements());
813 for (int elem_count
= 0; elem_count
< get_nof_elements(); elem_count
++)
814 get_at(elem_count
)->encode_text(text_buf
);
817 void Record_Of_Type::decode_text(Text_Buf
& text_buf
)
819 int new_size
= text_buf
.pull_int().get_val();
821 TTCN_error("Text decoder: Negative size was received for a value of "
822 "type %s.", get_descriptor()->name
);
824 for (int elem_count
= 0; elem_count
< new_size
; elem_count
++) {
825 if (val_ptr
->value_elements
[elem_count
] == NULL
) {
826 val_ptr
->value_elements
[elem_count
] = create_elem();
828 val_ptr
->value_elements
[elem_count
]->decode_text(text_buf
);
832 boolean
Record_Of_Type::operator==(null_type
/*other_value*/) const
835 TTCN_error("The left operand of comparison is an unbound value of type %s.",
836 get_descriptor()->name
);
837 return get_nof_elements() == 0;
840 int Record_Of_Type::rawdec_ebv() const
842 TTCN_error("Internal error: Record_Of_Type::rawdec_ebv() called.");
845 boolean
Record_Of_Type::isXerAttribute() const
847 TTCN_error("Internal error: Record_Of_Type::isXerAttribute() called.");
850 boolean
Record_Of_Type::isXmlValueList() const
852 TTCN_error("Internal error: Record_Of_Type::isXmlValueList() called.");
855 int Record_Of_Type::TEXT_encode(const TTCN_Typedescriptor_t
& p_td
,
856 TTCN_Buffer
& buff
) const
859 return TEXT_encode_negtest(err_descr
, p_td
, buff
);
861 int encoded_length
=0;
862 if(p_td
.text
->begin_encode
) {
863 buff
.put_cs(*p_td
.text
->begin_encode
);
864 encoded_length
+=p_td
.text
->begin_encode
->lengthof();
867 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND
,
868 "Encoding an unbound value.");
869 if(p_td
.text
->end_encode
) {
870 buff
.put_cs(*p_td
.text
->end_encode
);
871 encoded_length
+=p_td
.text
->end_encode
->lengthof();
873 return encoded_length
;
875 const TTCN_Typedescriptor_t
* elem_descr
= p_td
.oftype_descr
;
876 for(int a
=0;a
<get_nof_elements();a
++) {
877 if(a
!=0 && p_td
.text
->separator_encode
) {
878 buff
.put_cs(*p_td
.text
->separator_encode
);
879 encoded_length
+=p_td
.text
->separator_encode
->lengthof();
881 encoded_length
+=get_at(a
)->TEXT_encode(*elem_descr
,buff
);
883 if(p_td
.text
->end_encode
) {
884 buff
.put_cs(*p_td
.text
->end_encode
);
885 encoded_length
+=p_td
.text
->end_encode
->lengthof();
887 return encoded_length
;
891 * TEXT encode for negative testing
893 int Record_Of_Type::TEXT_encode_negtest(const Erroneous_descriptor_t
* p_err_descr
, const TTCN_Typedescriptor_t
& p_td
,
894 TTCN_Buffer
& buff
) const
896 bool need_separator
=false;
897 int encoded_length
=0;
898 if(p_td
.text
->begin_encode
) {
899 buff
.put_cs(*p_td
.text
->begin_encode
);
900 encoded_length
+=p_td
.text
->begin_encode
->lengthof();
903 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND
,
904 "Encoding an unbound value.");
905 if(p_td
.text
->end_encode
) {
906 buff
.put_cs(*p_td
.text
->end_encode
);
907 encoded_length
+=p_td
.text
->end_encode
->lengthof();
909 return encoded_length
;
915 for(int a
=0;a
<get_nof_elements();a
++) {
916 if ( (p_err_descr
->omit_before
!=-1) && (a
<p_err_descr
->omit_before
) ) continue;
917 const Erroneous_values_t
* err_vals
= p_err_descr
->next_field_err_values(a
, values_idx
);
918 const Erroneous_descriptor_t
* emb_descr
= p_err_descr
->next_field_emb_descr(a
, edescr_idx
);
920 if (err_vals
&& err_vals
->before
) {
921 if (err_vals
->before
->errval
==NULL
) TTCN_error(
922 "internal error: erroneous before value missing");
923 if (need_separator
&& p_td
.text
->separator_encode
) {
924 buff
.put_cs(*p_td
.text
->separator_encode
);
925 encoded_length
+=p_td
.text
->separator_encode
->lengthof();
927 if (err_vals
->before
->raw
) {
928 encoded_length
+= err_vals
->before
->errval
->encode_raw(buff
);
930 if (err_vals
->before
->type_descr
==NULL
) TTCN_error(
931 "internal error: erroneous before typedescriptor missing");
932 encoded_length
+= err_vals
->before
->errval
->TEXT_encode(
933 *(err_vals
->before
->type_descr
),buff
);
938 if (err_vals
&& err_vals
->value
) {
939 if (err_vals
->value
->errval
) {
940 if (need_separator
&& p_td
.text
->separator_encode
) {
941 buff
.put_cs(*p_td
.text
->separator_encode
);
942 encoded_length
+=p_td
.text
->separator_encode
->lengthof();
944 if (err_vals
->value
->raw
) {
945 encoded_length
+= err_vals
->value
->errval
->encode_raw(buff
);
947 if (err_vals
->value
->type_descr
==NULL
) TTCN_error(
948 "internal error: erroneous value typedescriptor missing");
949 encoded_length
+= err_vals
->value
->errval
->TEXT_encode(
950 *(err_vals
->value
->type_descr
),buff
);
955 if (need_separator
&& p_td
.text
->separator_encode
) {
956 buff
.put_cs(*p_td
.text
->separator_encode
);
957 encoded_length
+=p_td
.text
->separator_encode
->lengthof();
960 encoded_length
+= get_at(a
)->TEXT_encode_negtest(
961 emb_descr
,*p_td
.oftype_descr
,buff
);
963 encoded_length
+= get_at(a
)->TEXT_encode(*p_td
.oftype_descr
,buff
);
968 if (err_vals
&& err_vals
->after
) {
969 if (err_vals
->after
->errval
==NULL
) TTCN_error(
970 "internal error: erroneous after value missing");
971 if (need_separator
&& p_td
.text
->separator_encode
) {
972 buff
.put_cs(*p_td
.text
->separator_encode
);
973 encoded_length
+=p_td
.text
->separator_encode
->lengthof();
975 if (err_vals
->after
->raw
) {
976 encoded_length
+= err_vals
->after
->errval
->encode_raw(buff
);
978 if (err_vals
->after
->type_descr
==NULL
) TTCN_error(
979 "internal error: erroneous after typedescriptor missing");
980 encoded_length
+= err_vals
->after
->errval
->TEXT_encode(
981 *(err_vals
->after
->type_descr
),buff
);
986 if ( (p_err_descr
->omit_after
!=-1) && (a
>=p_err_descr
->omit_after
) ) break;
988 if(p_td
.text
->end_encode
) {
989 buff
.put_cs(*p_td
.text
->end_encode
);
990 encoded_length
+=p_td
.text
->end_encode
->lengthof();
992 return encoded_length
;
995 int Record_Of_Type::TEXT_decode(const TTCN_Typedescriptor_t
& p_td
,
996 TTCN_Buffer
& buff
, Limit_Token_List
& limit
, boolean no_err
,
999 int decoded_length
=0;
1001 boolean sep_found
=FALSE
;
1004 if(p_td
.text
->begin_decode
){
1006 if((tl
=p_td
.text
->begin_decode
->match_begin(buff
))<0){
1007 if(no_err
)return -1;
1008 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR
,
1009 "The specified token '%s' not found for '%s': ",
1010 (const char*)*(p_td
.text
->begin_decode
), p_td
.name
);
1014 buff
.increase_pos(tl
);
1016 if(p_td
.text
->end_decode
){
1017 limit
.add_token(p_td
.text
->end_decode
);
1020 if(p_td
.text
->separator_decode
){
1021 limit
.add_token(p_td
.text
->separator_decode
);
1027 int more
=get_nof_elements();
1029 Base_Type
* val
= create_elem();
1031 int len
= val
->TEXT_decode(*p_td
.oftype_descr
,buff
,limit
,TRUE
);
1032 if(len
==-1 || (len
==0 && !limit
.has_token())){
1036 buff
.set_pos(buff
.get_pos()-sep_length
);
1037 decoded_length
-=sep_length
;
1042 if (NULL
== refd_ind_ptr
) {
1043 val_ptr
->value_elements
= (Base_Type
**)reallocate_pointers(
1044 (void**)val_ptr
->value_elements
, val_ptr
->n_elements
, val_ptr
->n_elements
+ 1);
1045 val_ptr
->value_elements
[val_ptr
->n_elements
]=val
;
1046 val_ptr
->n_elements
++;
1049 get_at(get_nof_elements())->set_value(val
);
1052 decoded_length
+=len
;
1053 if(p_td
.text
->separator_decode
){
1055 if((tl
=p_td
.text
->separator_decode
->match_begin(buff
))<0){
1059 buff
.increase_pos(tl
);
1062 } else if(p_td
.text
->end_decode
){
1064 if((tl
=p_td
.text
->end_decode
->match_begin(buff
))!=-1){
1066 buff
.increase_pos(tl
);
1067 limit
.remove_tokens(ml
);
1068 return decoded_length
;
1070 } else if(limit
.has_token(ml
)){
1072 if((tl
=limit
.match(buff
,ml
))==0){
1078 limit
.remove_tokens(ml
);
1079 if(p_td
.text
->end_decode
){
1081 if((tl
=p_td
.text
->end_decode
->match_begin(buff
))<0){
1088 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR
,
1089 "The specified token '%s' not found for '%s': ",
1090 (const char*)*(p_td
.text
->end_decode
), p_td
.name
);
1091 return decoded_length
;
1094 buff
.increase_pos(tl
);
1096 if(get_nof_elements()==0){
1097 if (!p_td
.text
->end_decode
&& !p_td
.text
->begin_decode
) {
1098 if(no_err
)return -1;
1099 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR
,
1100 "No record/set of member found.");
1101 return decoded_length
;
1104 if(!first_call
&& more
==get_nof_elements() &&
1105 !(p_td
.text
->end_decode
|| p_td
.text
->begin_decode
)) return -1;
1106 return decoded_length
;
1109 ASN_BER_TLV_t
* Record_Of_Type::BER_encode_TLV(const TTCN_Typedescriptor_t
& p_td
,
1110 unsigned p_coding
) const
1113 return BER_encode_TLV_negtest(err_descr
, p_td
, p_coding
);
1115 BER_chk_descr(p_td
);
1116 ASN_BER_TLV_t
*new_tlv
=BER_encode_chk_bound(is_bound());
1118 new_tlv
=ASN_BER_TLV_t::construct(NULL
);
1119 TTCN_EncDec_ErrorContext ec
;
1120 for(int elem_i
=0; elem_i
<get_nof_elements(); elem_i
++) {
1121 ec
.set_msg("Component #%d: ", elem_i
);
1122 new_tlv
->add_TLV(get_at(elem_i
)->BER_encode_TLV(*p_td
.oftype_descr
, p_coding
));
1124 if (is_set()) new_tlv
->sort_tlvs();
1126 new_tlv
=ASN_BER_V2TLV(new_tlv
, p_td
, p_coding
);
1130 ASN_BER_TLV_t
* Record_Of_Type::BER_encode_TLV_negtest(const Erroneous_descriptor_t
* p_err_descr
,
1131 const TTCN_Typedescriptor_t
& p_td
, unsigned p_coding
) const
1133 BER_chk_descr(p_td
);
1134 ASN_BER_TLV_t
*new_tlv
=BER_encode_chk_bound(is_bound());
1136 new_tlv
=ASN_BER_TLV_t::construct(NULL
);
1137 TTCN_EncDec_ErrorContext ec
;
1140 for (int elem_i
=0; elem_i
<get_nof_elements(); elem_i
++) {
1141 if ( (p_err_descr
->omit_before
!=-1) && (elem_i
<p_err_descr
->omit_before
) ) continue;
1142 const Erroneous_values_t
* err_vals
= p_err_descr
->next_field_err_values(elem_i
, values_idx
);
1143 const Erroneous_descriptor_t
* emb_descr
= p_err_descr
->next_field_emb_descr(elem_i
, edescr_idx
);
1145 if (err_vals
&& err_vals
->before
) {
1146 if (err_vals
->before
->errval
==NULL
) TTCN_error(
1147 "internal error: erroneous before value missing");
1148 ec
.set_msg("Erroneous value before component #%d: ", elem_i
);
1149 if (err_vals
->before
->raw
) {
1150 new_tlv
->add_TLV(err_vals
->before
->errval
->BER_encode_negtest_raw());
1152 if (err_vals
->before
->type_descr
==NULL
) TTCN_error(
1153 "internal error: erroneous before typedescriptor missing");
1154 new_tlv
->add_TLV(err_vals
->before
->errval
->BER_encode_TLV(
1155 *err_vals
->before
->type_descr
, p_coding
));
1159 if (err_vals
&& err_vals
->value
) {
1160 if (err_vals
->value
->errval
) { // replace
1161 ec
.set_msg("Erroneous value for component #%d: ", elem_i
);
1162 if (err_vals
->value
->raw
) {
1163 new_tlv
->add_TLV(err_vals
->value
->errval
->BER_encode_negtest_raw());
1165 if (err_vals
->value
->type_descr
==NULL
) TTCN_error(
1166 "internal error: erroneous value typedescriptor missing");
1167 new_tlv
->add_TLV(err_vals
->value
->errval
->BER_encode_TLV(
1168 *err_vals
->value
->type_descr
, p_coding
));
1172 ec
.set_msg("Component #%d: ", elem_i
);
1174 new_tlv
->add_TLV(get_at(elem_i
)->BER_encode_TLV_negtest(
1175 emb_descr
, *p_td
.oftype_descr
, p_coding
));
1177 new_tlv
->add_TLV(get_at(elem_i
)->BER_encode_TLV(
1178 *p_td
.oftype_descr
, p_coding
));
1182 if (err_vals
&& err_vals
->after
) {
1183 if (err_vals
->after
->errval
==NULL
) TTCN_error(
1184 "internal error: erroneous after value missing");
1185 ec
.set_msg("Erroneous value after component #%d: ", elem_i
);
1186 if (err_vals
->after
->raw
) {
1187 new_tlv
->add_TLV(err_vals
->after
->errval
->BER_encode_negtest_raw());
1189 if (err_vals
->after
->type_descr
==NULL
) TTCN_error(
1190 "internal error: erroneous after typedescriptor missing");
1191 new_tlv
->add_TLV(err_vals
->after
->errval
->BER_encode_TLV(
1192 *err_vals
->after
->type_descr
, p_coding
));
1196 if ( (p_err_descr
->omit_after
!=-1) && (elem_i
>=p_err_descr
->omit_after
) ) break;
1198 if (is_set()) new_tlv
->sort_tlvs();
1200 new_tlv
=ASN_BER_V2TLV(new_tlv
, p_td
, p_coding
);
1204 boolean
Record_Of_Type::BER_decode_TLV(const TTCN_Typedescriptor_t
& p_td
,
1205 const ASN_BER_TLV_t
& p_tlv
, unsigned L_form
)
1207 BER_chk_descr(p_td
);
1208 ASN_BER_TLV_t stripped_tlv
;
1209 BER_decode_strip_tags(*p_td
.ber
, p_tlv
, L_form
, stripped_tlv
);
1210 TTCN_EncDec_ErrorContext
ec_0("While decoding '%s' type: ", p_td
.name
);
1211 stripped_tlv
.chk_constructed_flag(TRUE
);
1214 ASN_BER_TLV_t tmp_tlv
;
1215 TTCN_EncDec_ErrorContext
ec_1("Component #");
1216 TTCN_EncDec_ErrorContext
ec_2("0: ");
1217 while(BER_decode_constdTLV_next(stripped_tlv
, V_pos
, L_form
, tmp_tlv
)) {
1218 get_at(get_nof_elements())->BER_decode_TLV(*p_td
.oftype_descr
, tmp_tlv
, L_form
);
1219 ec_2
.set_msg("%d: ", val_ptr
->n_elements
);
1224 void Record_Of_Type::BER_decode_opentypes(TTCN_Type_list
& p_typelist
,
1227 p_typelist
.push(this);
1228 TTCN_EncDec_ErrorContext
ec_0("Component #");
1229 TTCN_EncDec_ErrorContext ec_1
;
1230 for(int elem_i
=0; elem_i
<get_nof_elements(); elem_i
++) {
1231 ec_1
.set_msg("%d: ", elem_i
);
1232 get_at(elem_i
)->BER_decode_opentypes(p_typelist
, L_form
);
1238 int Record_Of_Type::RAW_decode(const TTCN_Typedescriptor_t
& p_td
,
1239 TTCN_Buffer
& buff
, int limit
, raw_order_t top_bit_ord
, boolean
/*no_err*/,
1240 int sel_field
, boolean first_call
)
1242 int prepaddlength
= buff
.increase_pos_padd(p_td
.raw
->prepadding
);
1243 limit
-= prepaddlength
;
1244 int decoded_length
= 0;
1245 int decoded_field_length
= 0;
1246 size_t start_of_field
= 0;
1250 int start_field
= get_nof_elements(); // append at the end
1251 TTCN_Typedescriptor_t
const& elem_descr
= *p_td
.oftype_descr
;
1252 if (p_td
.raw
->fieldlength
|| sel_field
!= -1) {
1253 if (sel_field
== -1) sel_field
= p_td
.raw
->fieldlength
;
1254 for (int a
= 0; a
< sel_field
; a
++) {
1255 Base_Type
* field_bt
= get_at(a
+ start_field
);
1256 decoded_field_length
= field_bt
->RAW_decode(elem_descr
, buff
, limit
,
1258 if (decoded_field_length
< 0) return decoded_field_length
;
1259 decoded_length
+= decoded_field_length
;
1260 limit
-= decoded_field_length
;
1264 int a
= start_field
;
1266 if (!first_call
) return -1;
1270 start_of_field
= buff
.get_pos_bit();
1271 Base_Type
* field_bt
= get_at(a
); // non-const, extend the record-of
1272 decoded_field_length
= field_bt
->RAW_decode(elem_descr
, buff
, limit
,
1274 if (decoded_field_length
< 0) { // decoding failed, shorten the record-of
1275 set_size(get_nof_elements() - 1);
1276 buff
.set_pos_bit(start_of_field
);
1277 if (a
> start_field
) {
1280 else return decoded_field_length
;
1282 decoded_length
+= decoded_field_length
;
1283 limit
-= decoded_field_length
;
1285 if (EXT_BIT_NO
!= p_td
.raw
->extension_bit
) {
1286 // (EXT_BIT_YES != p_td.raw->extension_bit) is 0 or 1
1287 // This is the opposite value of what the bit needs to be to signal
1288 // the end of decoding, because x-or is the equivalent of !=
1289 if ((EXT_BIT_YES
!= p_td
.raw
->extension_bit
) ^ buff
.get_last_bit()) {
1296 return decoded_length
+ buff
.increase_pos_padd(p_td
.raw
->padding
) + prepaddlength
;
1299 int Record_Of_Type::RAW_encode(const TTCN_Typedescriptor_t
& p_td
, RAW_enc_tree
& myleaf
) const
1301 if (err_descr
) return RAW_encode_negtest(err_descr
, p_td
, myleaf
);
1302 int encoded_length
= 0;
1303 int nof_elements
= get_nof_elements();
1304 int encoded_num_of_records
=
1305 p_td
.raw
->fieldlength
? (nof_elements
< p_td
.raw
->fieldlength
? nof_elements
: p_td
.raw
->fieldlength
)
1307 myleaf
.isleaf
= FALSE
;
1308 myleaf
.rec_of
= TRUE
;
1309 myleaf
.body
.node
.num_of_nodes
= encoded_num_of_records
;
1310 myleaf
.body
.node
.nodes
= init_nodes_of_enc_tree(encoded_num_of_records
);
1311 TTCN_Typedescriptor_t
const& elem_descr
= *p_td
.oftype_descr
;
1312 for (int a
= 0; a
< encoded_num_of_records
; a
++) {
1313 const Base_Type
*field_bt
= get_at(a
);
1314 myleaf
.body
.node
.nodes
[a
] = new RAW_enc_tree(TRUE
, &myleaf
, &(myleaf
.curr_pos
), a
, elem_descr
.raw
);
1315 encoded_length
+= field_bt
->RAW_encode(elem_descr
, *myleaf
.body
.node
.nodes
[a
]);
1317 return myleaf
.length
= encoded_length
;
1320 int Record_Of_Type::RAW_encode_negtest(const Erroneous_descriptor_t
*p_err_descr
,
1321 const TTCN_Typedescriptor_t
& p_td
, RAW_enc_tree
& myleaf
) const
1325 int nof_elements
= get_nof_elements();
1326 // It can be more, of course...
1327 int encoded_num_of_records
=
1328 p_td
.raw
->fieldlength
? (nof_elements
< p_td
.raw
->fieldlength
? nof_elements
: p_td
.raw
->fieldlength
)
1330 for (int i
= 0; i
< nof_elements
; ++i
) {
1331 if ((p_err_descr
->omit_before
!= -1) && (i
< p_err_descr
->omit_before
)) {
1332 --encoded_num_of_records
;
1335 const Erroneous_values_t
*err_vals
=
1336 p_err_descr
->next_field_err_values(i
, values_idx
);
1337 // Not checking any further, `internal error' will be given anyway in the
1338 // next round. Please note that elements can be removed, `omitted'.
1339 if (err_vals
&& err_vals
->before
)
1340 ++encoded_num_of_records
;
1341 if (err_vals
&& err_vals
->value
&& !err_vals
->value
->errval
)
1342 --encoded_num_of_records
;
1343 if (err_vals
&& err_vals
->after
)
1344 ++encoded_num_of_records
;
1345 if ((p_err_descr
->omit_after
!= -1) && (i
>= p_err_descr
->omit_after
)) {
1346 encoded_num_of_records
= encoded_num_of_records
- (nof_elements
- i
) + 1;
1350 myleaf
.body
.node
.num_of_nodes
= encoded_num_of_records
;
1351 myleaf
.body
.node
.nodes
= init_nodes_of_enc_tree(encoded_num_of_records
);
1352 int encoded_length
= 0;
1353 myleaf
.isleaf
= FALSE
;
1354 myleaf
.rec_of
= TRUE
;
1357 for (int i
= 0; i
< nof_elements
; ++i
) {
1358 if ((p_err_descr
->omit_before
!= -1) && (i
< p_err_descr
->omit_before
))
1360 const Erroneous_values_t
*err_vals
= p_err_descr
->next_field_err_values(i
, values_idx
);
1361 const Erroneous_descriptor_t
*emb_descr
= p_err_descr
->next_field_emb_descr(i
, edescr_idx
);
1362 TTCN_Typedescriptor_t
const& elem_descr
= *p_td
.oftype_descr
;
1363 if (err_vals
&& err_vals
->before
) {
1364 if (err_vals
->before
->errval
== NULL
)
1365 TTCN_error("internal error: erroneous before value missing");
1366 if (err_vals
->before
->raw
) {
1367 myleaf
.body
.node
.nodes
[node_pos
] = new RAW_enc_tree(true, &myleaf
,
1368 &(myleaf
.curr_pos
), node_pos
,
1369 err_vals
->before
->errval
->get_descriptor()->raw
);
1370 encoded_length
+= err_vals
->before
->errval
->
1371 RAW_encode_negtest_raw(*myleaf
.body
.node
.nodes
[node_pos
++]);
1373 if (err_vals
->before
->type_descr
== NULL
)
1374 TTCN_error("internal error: erroneous before typedescriptor missing");
1375 myleaf
.body
.node
.nodes
[node_pos
] = new RAW_enc_tree(TRUE
, &myleaf
,
1376 &(myleaf
.curr_pos
), node_pos
, elem_descr
.raw
);
1377 encoded_length
+= err_vals
->before
->errval
->
1378 RAW_encode(*(err_vals
->before
->type_descr
),
1379 *myleaf
.body
.node
.nodes
[node_pos
++]);
1382 if (err_vals
&& err_vals
->value
) {
1383 if (err_vals
->value
->errval
) {
1384 if (err_vals
->value
->raw
) {
1385 myleaf
.body
.node
.nodes
[node_pos
] = new RAW_enc_tree(true, &myleaf
,
1386 &(myleaf
.curr_pos
), node_pos
,
1387 err_vals
->value
->errval
->get_descriptor()->raw
);
1388 encoded_length
+= err_vals
->value
->errval
->
1389 RAW_encode_negtest_raw(*myleaf
.body
.node
.nodes
[node_pos
++]);
1391 if (err_vals
->value
->type_descr
== NULL
)
1392 TTCN_error("internal error: erroneous value typedescriptor missing");
1393 myleaf
.body
.node
.nodes
[node_pos
] = new RAW_enc_tree(TRUE
, &myleaf
,
1394 &(myleaf
.curr_pos
), node_pos
, elem_descr
.raw
);
1395 encoded_length
+= err_vals
->value
->errval
->
1396 RAW_encode(*(err_vals
->value
->type_descr
),
1397 *myleaf
.body
.node
.nodes
[node_pos
++]);
1402 myleaf
.body
.node
.nodes
[node_pos
] = new RAW_enc_tree(TRUE
, &myleaf
,
1403 &(myleaf
.curr_pos
), node_pos
, elem_descr
.raw
);
1404 encoded_length
+= get_at(i
)->RAW_encode_negtest(emb_descr
,
1405 *p_td
.oftype_descr
, *myleaf
.body
.node
.nodes
[node_pos
++]);
1407 myleaf
.body
.node
.nodes
[node_pos
] = new RAW_enc_tree(TRUE
, &myleaf
,
1408 &(myleaf
.curr_pos
), node_pos
, elem_descr
.raw
);
1409 encoded_length
+= get_at(i
)->RAW_encode(*p_td
.oftype_descr
,
1410 *myleaf
.body
.node
.nodes
[node_pos
++]);
1413 if (err_vals
&& err_vals
->after
) {
1414 if (err_vals
->after
->errval
== NULL
)
1415 TTCN_error("internal error: erroneous after value missing");
1416 if (err_vals
->after
->raw
) {
1417 myleaf
.body
.node
.nodes
[node_pos
] = new RAW_enc_tree(true, &myleaf
,
1418 &(myleaf
.curr_pos
), node_pos
,
1419 err_vals
->after
->errval
->get_descriptor()->raw
);
1420 encoded_length
+= err_vals
->after
->errval
->
1421 RAW_encode_negtest_raw(*myleaf
.body
.node
.nodes
[node_pos
++]);
1423 if (err_vals
->after
->type_descr
== NULL
)
1424 TTCN_error("internal error: erroneous after typedescriptor missing");
1425 myleaf
.body
.node
.nodes
[node_pos
] = new RAW_enc_tree(TRUE
, &myleaf
,
1426 &(myleaf
.curr_pos
), node_pos
, elem_descr
.raw
);
1427 encoded_length
+= err_vals
->after
->errval
->
1428 RAW_encode(*(err_vals
->after
->type_descr
),
1429 *myleaf
.body
.node
.nodes
[node_pos
++]);
1432 if ((p_err_descr
->omit_after
!= -1) && (i
>= p_err_descr
->omit_after
))
1435 return myleaf
.length
= encoded_length
;
1438 int Record_Of_Type::JSON_encode(const TTCN_Typedescriptor_t
& p_td
, JSON_Tokenizer
& p_tok
) const
1441 return JSON_encode_negtest(err_descr
, p_td
, p_tok
);
1445 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND
,
1446 "Encoding an unbound %s of value.", is_set() ? "set" : "record");
1450 int enc_len
= p_tok
.put_next_token(JSON_TOKEN_ARRAY_START
, NULL
);
1452 for (int i
= 0; i
< get_nof_elements(); ++i
) {
1453 if (NULL
!= p_td
.json
&& p_td
.json
->metainfo_unbound
&& !get_at(i
)->is_bound()) {
1454 // unbound elements are encoded as { "metainfo []" : "unbound" }
1455 enc_len
+= p_tok
.put_next_token(JSON_TOKEN_OBJECT_START
, NULL
);
1456 enc_len
+= p_tok
.put_next_token(JSON_TOKEN_NAME
, "metainfo []");
1457 enc_len
+= p_tok
.put_next_token(JSON_TOKEN_STRING
, "\"unbound\"");
1458 enc_len
+= p_tok
.put_next_token(JSON_TOKEN_OBJECT_END
, NULL
);
1461 int ret_val
= get_at(i
)->JSON_encode(*p_td
.oftype_descr
, p_tok
);
1462 if (0 > ret_val
) break;
1467 enc_len
+= p_tok
.put_next_token(JSON_TOKEN_ARRAY_END
, NULL
);
1471 int Record_Of_Type::JSON_encode_negtest(const Erroneous_descriptor_t
* p_err_descr
,
1472 const TTCN_Typedescriptor_t
& p_td
,
1473 JSON_Tokenizer
& p_tok
) const
1476 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND
,
1477 "Encoding an unbound %s of value.", is_set() ? "set" : "record");
1481 int enc_len
= p_tok
.put_next_token(JSON_TOKEN_ARRAY_START
, NULL
);
1486 for (int i
= 0; i
< get_nof_elements(); ++i
) {
1487 if (-1 != p_err_descr
->omit_before
&& p_err_descr
->omit_before
> i
) {
1491 const Erroneous_values_t
* err_vals
= p_err_descr
->next_field_err_values(i
, values_idx
);
1492 const Erroneous_descriptor_t
* emb_descr
= p_err_descr
->next_field_emb_descr(i
, edescr_idx
);
1494 if (NULL
!= err_vals
&& NULL
!= err_vals
->before
) {
1495 if (NULL
== err_vals
->before
->errval
) {
1496 TTCN_error("internal error: erroneous before value missing");
1498 if (err_vals
->before
->raw
) {
1499 enc_len
+= err_vals
->before
->errval
->JSON_encode_negtest_raw(p_tok
);
1501 if (NULL
== err_vals
->before
->type_descr
) {
1502 TTCN_error("internal error: erroneous before typedescriptor missing");
1504 enc_len
+= err_vals
->before
->errval
->JSON_encode(*(err_vals
->before
->type_descr
), p_tok
);
1508 if (NULL
!= err_vals
&& NULL
!= err_vals
->value
) {
1509 if (NULL
!= err_vals
->value
->errval
) {
1510 if (err_vals
->value
->raw
) {
1511 enc_len
+= err_vals
->value
->errval
->JSON_encode_negtest_raw(p_tok
);
1513 if (NULL
== err_vals
->value
->type_descr
) {
1514 TTCN_error("internal error: erroneous before typedescriptor missing");
1516 enc_len
+= err_vals
->value
->errval
->JSON_encode(*(err_vals
->value
->type_descr
), p_tok
);
1520 else if (NULL
!= p_td
.json
&& p_td
.json
->metainfo_unbound
&& !get_at(i
)->is_bound()) {
1521 // unbound elements are encoded as { "metainfo []" : "unbound" }
1522 enc_len
+= p_tok
.put_next_token(JSON_TOKEN_OBJECT_START
, NULL
);
1523 enc_len
+= p_tok
.put_next_token(JSON_TOKEN_NAME
, "metainfo []");
1524 enc_len
+= p_tok
.put_next_token(JSON_TOKEN_STRING
, "\"unbound\"");
1525 enc_len
+= p_tok
.put_next_token(JSON_TOKEN_OBJECT_END
, NULL
);
1529 if (NULL
!= emb_descr
) {
1530 ret_val
= get_at(i
)->JSON_encode_negtest(emb_descr
, *p_td
.oftype_descr
, p_tok
);
1532 ret_val
= get_at(i
)->JSON_encode(*p_td
.oftype_descr
, p_tok
);
1534 if (0 > ret_val
) break;
1538 if (NULL
!= err_vals
&& NULL
!= err_vals
->after
) {
1539 if (NULL
== err_vals
->after
->errval
) {
1540 TTCN_error("internal error: erroneous after value missing");
1542 if (err_vals
->after
->raw
) {
1543 enc_len
+= err_vals
->after
->errval
->JSON_encode_negtest_raw(p_tok
);
1545 if (NULL
== err_vals
->after
->type_descr
) {
1546 TTCN_error("internal error: erroneous before typedescriptor missing");
1548 enc_len
+= err_vals
->after
->errval
->JSON_encode(*(err_vals
->after
->type_descr
), p_tok
);
1552 if (-1 != p_err_descr
->omit_after
&& p_err_descr
->omit_after
<= i
) {
1557 enc_len
+= p_tok
.put_next_token(JSON_TOKEN_ARRAY_END
, NULL
);
1561 int Record_Of_Type::JSON_decode(const TTCN_Typedescriptor_t
& p_td
, JSON_Tokenizer
& p_tok
, boolean p_silent
)
1563 json_token_t token
= JSON_TOKEN_NONE
;
1564 int dec_len
= p_tok
.get_next_token(&token
, NULL
, NULL
);
1565 if (JSON_TOKEN_ERROR
== token
) {
1566 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG
, JSON_DEC_BAD_TOKEN_ERROR
, "");
1567 return JSON_ERROR_FATAL
;
1569 else if (JSON_TOKEN_ARRAY_START
!= token
) {
1570 return JSON_ERROR_INVALID_TOKEN
;
1574 for (int nof_elements
= 0; true; ++nof_elements
) {
1575 // Read value tokens until we reach some other token
1576 size_t buf_pos
= p_tok
.get_buf_pos();
1578 if (NULL
!= p_td
.json
&& p_td
.json
->metainfo_unbound
) {
1579 // check for metainfo object
1580 ret_val
= p_tok
.get_next_token(&token
, NULL
, NULL
);
1581 if (JSON_TOKEN_OBJECT_START
== token
) {
1583 size_t value_len
= 0;
1584 ret_val
+= p_tok
.get_next_token(&token
, &value
, &value_len
);
1585 if (JSON_TOKEN_NAME
== token
&& 11 == value_len
&&
1586 0 == strncmp(value
, "metainfo []", 11)) {
1587 ret_val
+= p_tok
.get_next_token(&token
, &value
, &value_len
);
1588 if (JSON_TOKEN_STRING
== token
&& 9 == value_len
&&
1589 0 == strncmp(value
, "\"unbound\"", 9)) {
1590 ret_val
= p_tok
.get_next_token(&token
, NULL
, NULL
);
1591 if (JSON_TOKEN_OBJECT_END
== token
) {
1598 // metainfo object not found, jump back and let the element type decode it
1599 p_tok
.set_buf_pos(buf_pos
);
1601 Base_Type
* val
= create_elem();
1602 ret_val
= val
->JSON_decode(*p_td
.oftype_descr
, p_tok
, p_silent
);
1603 if (JSON_ERROR_INVALID_TOKEN
== ret_val
) {
1604 // undo the last action on the buffer
1605 p_tok
.set_buf_pos(buf_pos
);
1609 else if (JSON_ERROR_FATAL
== ret_val
) {
1614 return JSON_ERROR_FATAL
;
1616 if (NULL
== refd_ind_ptr
) {
1617 val_ptr
->value_elements
= (Base_Type
**)reallocate_pointers(
1618 (void**)val_ptr
->value_elements
, val_ptr
->n_elements
, nof_elements
+ 1);
1619 val_ptr
->value_elements
[nof_elements
] = val
;
1620 val_ptr
->n_elements
= nof_elements
+ 1;
1623 get_at(nof_elements
)->set_value(val
);
1629 dec_len
+= p_tok
.get_next_token(&token
, NULL
, NULL
);
1630 if (JSON_TOKEN_ARRAY_END
!= token
) {
1631 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG
, JSON_DEC_REC_OF_END_TOKEN_ERROR
, "");
1635 return JSON_ERROR_FATAL
;
1641 void Record_Of_Type::encode(const TTCN_Typedescriptor_t
& p_td
,
1642 TTCN_Buffer
& p_buf
, TTCN_EncDec::coding_t p_coding
, ...) const
1645 va_start(pvar
, p_coding
);
1647 case TTCN_EncDec::CT_BER
: {
1648 TTCN_EncDec_ErrorContext
ec("While BER-encoding type '%s': ", p_td
.name
);
1649 unsigned BER_coding
=va_arg(pvar
, unsigned);
1650 BER_encode_chk_coding(BER_coding
);
1651 ASN_BER_TLV_t
*tlv
=BER_encode_TLV(p_td
, BER_coding
);
1652 tlv
->put_in_buffer(p_buf
);
1653 ASN_BER_TLV_t::destruct(tlv
);
1655 case TTCN_EncDec::CT_RAW
: {
1656 TTCN_EncDec_ErrorContext
ec("While RAW-encoding type '%s': ", p_td
.name
);
1658 TTCN_EncDec_ErrorContext::error_internal("No RAW descriptor available for type '%s'.", p_td
.name
);
1662 RAW_enc_tree
root(FALSE
, NULL
, &rp
, 1, p_td
.raw
);
1663 RAW_encode(p_td
, root
);
1664 root
.put_to_buf(p_buf
);
1666 case TTCN_EncDec::CT_TEXT
: {
1667 TTCN_EncDec_ErrorContext
ec("While TEXT-encoding type '%s': ", p_td
.name
);
1668 if(!p_td
.text
) TTCN_EncDec_ErrorContext::error_internal
1669 ("No TEXT descriptor available for type '%s'.", p_td
.name
);
1670 TEXT_encode(p_td
,p_buf
);
1672 case TTCN_EncDec::CT_XER
: {
1673 TTCN_EncDec_ErrorContext
ec("While XER-encoding type '%s': ", p_td
.name
);
1674 unsigned XER_coding
=va_arg(pvar
, unsigned);
1675 XER_encode(*(p_td
.xer
),p_buf
, XER_coding
, 0, 0);
1678 case TTCN_EncDec::CT_JSON
: {
1679 TTCN_EncDec_ErrorContext
ec("While JSON-encoding type '%s': ", p_td
.name
);
1680 if(!p_td
.json
) TTCN_EncDec_ErrorContext::error_internal
1681 ("No JSON descriptor available for type '%s'.", p_td
.name
);
1682 JSON_Tokenizer
tok(va_arg(pvar
, int) != 0);
1683 JSON_encode(p_td
, tok
);
1684 p_buf
.put_s(tok
.get_buffer_length(), (const unsigned char*)tok
.get_buffer());
1687 TTCN_error("Unknown coding method requested to encode type '%s'", p_td
.name
);
1692 void Record_Of_Type::decode(const TTCN_Typedescriptor_t
& p_td
,
1693 TTCN_Buffer
& p_buf
, TTCN_EncDec::coding_t p_coding
, ...)
1696 va_start(pvar
, p_coding
);
1698 case TTCN_EncDec::CT_BER
: {
1699 TTCN_EncDec_ErrorContext
ec("While BER-decoding type '%s': ", p_td
.name
);
1700 unsigned L_form
=va_arg(pvar
, unsigned);
1702 BER_decode_str2TLV(p_buf
, tlv
, L_form
);
1703 BER_decode_TLV(p_td
, tlv
, L_form
);
1704 if(tlv
.isComplete
) p_buf
.increase_pos(tlv
.get_len());
1706 case TTCN_EncDec::CT_RAW
: {
1707 TTCN_EncDec_ErrorContext
ec("While RAW-decoding type '%s': ", p_td
.name
);
1708 if(!p_td
.raw
) TTCN_EncDec_ErrorContext::error_internal
1709 ("No RAW descriptor available for type '%s'.", p_td
.name
);
1711 switch(p_td
.raw
->top_bit_order
) {
1719 if(RAW_decode(p_td
, p_buf
, p_buf
.get_len()*8, order
)<0)
1720 ec
.error(TTCN_EncDec::ET_INCOMPL_MSG
,"Can not decode type '%s', "
1721 "because invalid or incomplete message was received", p_td
.name
);
1723 case TTCN_EncDec::CT_TEXT
: {
1724 Limit_Token_List limit
;
1725 TTCN_EncDec_ErrorContext
ec("While TEXT-decoding type '%s': ", p_td
.name
);
1726 if(!p_td
.text
) TTCN_EncDec_ErrorContext::error_internal
1727 ("No TEXT descriptor available for type '%s'.", p_td
.name
);
1728 const unsigned char *b
=p_buf
.get_data();
1729 if(b
[p_buf
.get_len()-1]!='\0'){
1730 p_buf
.set_pos(p_buf
.get_len());
1731 p_buf
.put_zero(8,ORDER_LSB
);
1734 if(TEXT_decode(p_td
,p_buf
,limit
)<0)
1735 ec
.error(TTCN_EncDec::ET_INCOMPL_MSG
,"Can not decode type '%s', "
1736 "because invalid or incomplete message was received", p_td
.name
);
1738 case TTCN_EncDec::CT_XER
: {
1739 TTCN_EncDec_ErrorContext
ec("While XER-decoding type '%s': ", p_td
.name
);
1740 unsigned XER_coding
=va_arg(pvar
, unsigned);
1741 XmlReaderWrap
reader(p_buf
);
1742 for (int success
=reader
.Read(); success
==1; success
=reader
.Read()) {
1743 if (reader
.NodeType() == XML_READER_TYPE_ELEMENT
) break;
1745 XER_decode(*(p_td
.xer
), reader
, XER_coding
| XER_TOPLEVEL
, XER_NONE
, 0);
1746 size_t bytes
= reader
.ByteConsumed();
1747 p_buf
.set_pos(bytes
);
1749 case TTCN_EncDec::CT_JSON
: {
1750 TTCN_EncDec_ErrorContext
ec("While JSON-decoding type '%s': ", p_td
.name
);
1751 if(!p_td
.json
) TTCN_EncDec_ErrorContext::error_internal
1752 ("No JSON descriptor available for type '%s'.", p_td
.name
);
1753 JSON_Tokenizer
tok((const char*)p_buf
.get_data(), p_buf
.get_len());
1754 if(JSON_decode(p_td
, tok
, false)<0)
1755 ec
.error(TTCN_EncDec::ET_INCOMPL_MSG
,"Can not decode type '%s', "
1756 "because invalid or incomplete message was received", p_td
.name
);
1757 p_buf
.set_pos(tok
.get_buf_pos());
1760 TTCN_error("Unknown coding method requested to decode type '%s'", p_td
.name
);
1765 char **Record_Of_Type::collect_ns(const XERdescriptor_t
& p_td
, size_t& num
, bool& def_ns
) const
1767 size_t num_collected
= 0;
1768 // First, our own namespace. Sets num_collected to 0 or 1.
1769 // If it throws, nothing was allocated.
1770 char **collected_ns
= Base_Type::collect_ns(p_td
, num_collected
, def_ns
);
1772 // Then the embedded type
1774 bool def_ns_1
= false;
1775 if (val_ptr
) for (int i
= 0; i
< get_nof_elements(); ++i
) {
1777 char **new_namespaces
= get_at(i
)->collect_ns(
1778 *p_td
.oftype_descr
, num_new
, def_ns_1
);
1779 merge_ns(collected_ns
, num_collected
, new_namespaces
, num_new
);
1780 def_ns
= def_ns
|| def_ns_1
; // alas, no ||=
1784 // Probably a TC_Error thrown from the element's collect_ns(),
1785 // e.g. if encoding an unbound value.
1786 while (num_collected
> 0) Free(collected_ns
[--num_collected
]);
1791 num
= num_collected
;
1792 return collected_ns
;
1795 static const universal_char sp
= { 0,0,0,' ' };
1796 static const universal_char tb
= { 0,0,0,9 };
1798 int Record_Of_Type::XER_encode(const XERdescriptor_t
& p_td
, TTCN_Buffer
& p_buf
,
1799 unsigned int flavor
, int indent
, embed_values_enc_struct_t
* emb_val
) const
1802 return XER_encode_negtest(err_descr
, p_td
, p_buf
, flavor
, indent
, emb_val
);
1805 if (val_ptr
== 0) TTCN_error(
1806 "Attempt to XER-encode an unbound record of type %s", get_descriptor()->name
);
1807 int encoded_length
= (int)p_buf
.get_len();
1809 const int exer
= is_exer(flavor
);
1810 const boolean own_tag
=
1811 !(exer
&& indent
&& (p_td
.xer_bits
& (ANY_ELEMENT
|ANY_ATTRIBUTES
|UNTAGGED
)));
1813 const int indenting
= !is_canonical(flavor
) && own_tag
;
1814 const boolean xmlValueList
= isXmlValueList();
1817 | ( (exer
&& (p_td
.xer_bits
& XER_LIST
))
1818 || is_exerlist(flavor
) ? SIMPLE_TYPE
: 0);
1819 flavor
&= ~XER_RECOF
; // record-of doesn't care
1820 int nof_elements
= get_nof_elements();
1821 Base_Type::begin_xml(p_td
, p_buf
, flavor
, indent
, !nof_elements
,
1822 (collector_fn
)&Record_Of_Type::collect_ns
);
1824 if (xmlValueList
&& nof_elements
&& indenting
&& !exer
) { /* !exer or GDMO */
1825 do_indent(p_buf
, indent
+1);
1828 if (exer
&& (p_td
.xer_bits
& ANY_ATTRIBUTES
)) {
1829 // Back up over the '>' and the '\n' that may follow it
1830 size_t buf_len
= p_buf
.get_len(), shorter
= 0;
1831 const unsigned char * const buf_data
= p_buf
.get_data();
1832 if (buf_data
[buf_len
- 1 - shorter
] == '\n') ++shorter
;
1833 if (buf_data
[buf_len
- 1 - shorter
] == '>' ) ++shorter
;
1835 unsigned char saved
[4];
1837 memcpy(saved
, buf_data
+ (buf_len
- shorter
), shorter
);
1838 p_buf
.increase_length(-shorter
);
1841 // ANY_ATTRIBUTES means it's a record of universal charstring.
1842 // They are in AnyAttributeFormat (X.693/2008 18.2.6):
1843 // "URI(optional), space, NCName, equals, \"xmlcstring\""
1844 // They need to be written as an XML attribute and namespace declaration:
1845 // xmlns:b0="URI" b0:NCName="xmlcstring"
1847 for (int i
= 0; i
< nof_elements
; ++i
) {
1848 TTCN_EncDec_ErrorContext
ec_0("Attribute %d: ", i
);
1849 if (!is_elem_bound(i
)) {
1850 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND
,
1851 "Encoding an unbound universal charstring value.");
1854 const UNIVERSAL_CHARSTRING
*elem
1855 = static_cast<const UNIVERSAL_CHARSTRING
*>(val_ptr
->value_elements
[i
]);
1856 size_t len
= elem
->lengthof();
1858 const UNIVERSAL_CHARSTRING_ELEMENT
& ue
= (*elem
)[len
- 1];
1859 if (sp
== ue
|| tb
== ue
) --len
;
1862 // sp_at: indexes the first space
1863 // j is left to point at where the attribute name begins (just past the space)
1864 size_t j
, sp_at
= 0;
1865 for (j
= 0; j
< len
; j
++) {
1866 const UNIVERSAL_CHARSTRING_ELEMENT
& ue
= (*elem
)[j
];
1867 if (sp_at
) { // already found a space
1868 if (sp
== ue
|| tb
== ue
) {} // another space, do nothing
1869 else break; // found a non-space after a space
1872 if (sp
== ue
|| tb
== ue
) sp_at
= j
;
1876 size_t buf_start
= p_buf
.get_len();
1878 char * ns
= mprintf(" xmlns:b%d='", i
);
1879 size_t ns_len
= mstrlen(ns
);
1880 p_buf
.put_s(ns_len
, (cbyte
*)ns
);
1882 UNIVERSAL_CHARSTRING
before(sp_at
, (const universal_char
*)(*elem
));
1883 if (p_td
.xer_bits
& (ANY_FROM
| ANY_EXCEPT
)) {
1884 // Ensure the namespace abides to its restrictions
1886 before
.encode_utf8(ns_buf
);
1888 ns_buf
.get_string(cs
);
1889 check_namespace_restrictions(p_td
, (const char*)cs
);
1891 before
.XER_encode(UNIVERSAL_CHARSTRING_xer_
, p_buf
,
1892 flavor
| ANY_ATTRIBUTES
, indent
, 0);
1897 // Keep just the "b%d" part from ns
1898 p_buf
.put_s(ns_len
- 9, (cbyte
*)ns
+ 7);
1906 if (p_td
.xer_bits
& (ANY_FROM
| ANY_EXCEPT
)) {
1907 // Make sure the unqualified namespace is allowed
1908 check_namespace_restrictions(p_td
, NULL
);
1912 UNIVERSAL_CHARSTRING
after(len
- j
, (const universal_char
*)(*elem
) + j
);
1913 after
.XER_encode(UNIVERSAL_CHARSTRING_xer_
, p_buf
,
1914 flavor
| ANY_ATTRIBUTES
, indent
, 0);
1916 // Put this attribute in a dummy element and walk through it to check its validity
1917 TTCN_Buffer check_buf
;
1918 check_buf
.put_s(2, (unsigned char*)"<a");
1919 check_buf
.put_s(p_buf
.get_len() - buf_start
, p_buf
.get_data() + buf_start
);
1920 check_buf
.put_s(2, (unsigned char*)"/>");
1921 XmlReaderWrap
checker(check_buf
);
1922 while (1 == checker
.Read());
1925 p_buf
.put_s(shorter
, saved
); // restore the '>' and anything after
1928 else { // not ANY-ATTRIBUTES
1929 unsigned int sub_flavor
= flavor
| XER_RECOF
| (p_td
.xer_bits
& (XER_LIST
));
1930 TTCN_EncDec_ErrorContext
ec_0("Index ");
1931 TTCN_EncDec_ErrorContext ec_1
;
1933 for (int i
= 0; i
< nof_elements
; ++i
) {
1934 if (i
> 0 && !own_tag
&& 0 != emb_val
&&
1935 emb_val
->embval_index
< emb_val
->embval_array
->size_of()) {
1936 emb_val
->embval_array
->get_at(emb_val
->embval_index
)->XER_encode(
1937 UNIVERSAL_CHARSTRING_xer_
, p_buf
, flavor
| EMBED_VALUES
, indent
+1, 0);
1938 ++emb_val
->embval_index
;
1940 ec_1
.set_msg("%d: ", i
);
1941 if (exer
&& (p_td
.xer_bits
& XER_LIST
) && i
>0) p_buf
.put_c(' ');
1942 get_at(i
)->XER_encode(*p_td
.oftype_descr
, p_buf
,
1943 sub_flavor
, indent
+own_tag
, emb_val
);
1946 if (indenting
&& nof_elements
&& !is_exerlist(flavor
)) {
1947 if (xmlValueList
&& !exer
) p_buf
.put_c('\n'); /* !exer or GDMO */
1948 //do_indent(p_buf, indent);
1952 Base_Type::end_xml(p_td
, p_buf
, flavor
, indent
, !nof_elements
);
1953 return (int)p_buf
.get_len() - encoded_length
;
1956 // XERSTUFF Record_Of_Type::encode_element
1957 /** Helper for Record_Of_Type::XER_encode_negtest
1959 * The main purpose of this method is to allow another type to request
1960 * encoding of a single element of the record-of. Used by Record_Type
1961 * to encode individual strings of the EMBED-VALUES member.
1963 * @param i index of the element
1964 * @param ev erroneous descriptor for the element itself
1965 * @param ed deeper erroneous values
1966 * @param p_buf buffer containing the encoded value
1967 * @param sub_flavor flags
1968 * @param indent indentation level
1969 * @return number of bytes generated
1971 int Record_Of_Type::encode_element(int i
, const XERdescriptor_t
& p_td
,
1972 const Erroneous_values_t
* ev
, const Erroneous_descriptor_t
* ed
,
1973 TTCN_Buffer
& p_buf
, unsigned int sub_flavor
, int indent
, embed_values_enc_struct_t
* emb_val
) const
1975 int enc_len
= p_buf
.get_len();
1976 TTCN_EncDec_ErrorContext ec
;
1977 const int exer
= is_exer(sub_flavor
);
1979 if (ev
&& ev
->before
) {
1980 if (ev
->before
->errval
==NULL
) {
1981 TTCN_error("internal error: erroneous before value missing");
1983 ec
.set_msg("Erroneous value before component #%d: ", i
);
1984 if (ev
->before
->raw
) {
1985 ev
->before
->errval
->encode_raw(p_buf
);
1987 if (ev
->before
->type_descr
==NULL
) TTCN_error(
1988 "internal error: erroneous before type descriptor missing");
1989 ev
->before
->errval
->XER_encode(*ev
->before
->type_descr
->xer
,
1990 p_buf
, sub_flavor
, indent
, 0);
1994 if (exer
&& (sub_flavor
& XER_LIST
)
1995 && (i
> 0 || (ev
&& ev
->before
&& !ev
->before
->raw
))){
1996 // Ensure a separator is written after the "erroneous before"
1997 // of the first element (except for "raw before").
2001 if (ev
&& ev
->value
) {
2002 if (ev
->value
->errval
) { // replace
2003 ec
.set_msg("Erroneous value for component #%d: ", i
);
2004 if (ev
->value
->raw
) {
2005 ev
->value
->errval
->encode_raw(p_buf
);
2007 if (ev
->value
->type_descr
==NULL
) TTCN_error(
2008 "internal error: erroneous value type descriptor missing");
2009 ev
->value
->errval
->XER_encode(*ev
->value
->type_descr
->xer
,
2010 p_buf
, sub_flavor
, indent
, 0);
2014 ec
.set_msg("Component #%d: ", i
);
2016 get_at(i
)->XER_encode_negtest(ed
, p_td
, p_buf
, sub_flavor
, indent
, emb_val
);
2018 // the "real" encoder
2019 get_at(i
)->XER_encode(p_td
, p_buf
, sub_flavor
, indent
, emb_val
);
2023 if (ev
&& ev
->after
) {
2024 if (ev
->after
->errval
==NULL
) {
2025 TTCN_error("internal error: erroneous after value missing");
2027 ec
.set_msg("Erroneous value after component #%d: ", i
);
2028 if (ev
->after
->raw
) {
2029 ev
->after
->errval
->encode_raw(p_buf
);
2031 if (ev
->after
->type_descr
==NULL
) TTCN_error(
2032 "internal error: erroneous after type descriptor missing");
2033 ev
->after
->errval
->XER_encode(*ev
->after
->type_descr
->xer
,
2034 p_buf
, sub_flavor
, indent
, 0);
2041 // XERSTUFF Record_Of_Type::XER_encode_negtest
2042 int Record_Of_Type::XER_encode_negtest(const Erroneous_descriptor_t
* p_err_descr
,
2043 const XERdescriptor_t
& p_td
, TTCN_Buffer
& p_buf
, unsigned flavor
, int indent
,
2044 embed_values_enc_struct_t
* emb_val
) const
2046 if (val_ptr
== 0) TTCN_error(
2047 "Attempt to XER-encode an unbound record of type %s", get_descriptor()->name
);
2048 int encoded_length
= (int)p_buf
.get_len();
2050 const int exer
= is_exer(flavor
);
2051 const boolean own_tag
=
2052 !(exer
&& indent
&& (p_td
.xer_bits
& (ANY_ELEMENT
|ANY_ATTRIBUTES
|UNTAGGED
)));
2054 const int indenting
= !is_canonical(flavor
) && own_tag
;
2055 const boolean xmlValueList
= isXmlValueList();
2058 | ( (exer
&& (p_td
.xer_bits
& XER_LIST
))
2059 || is_exerlist(flavor
) ? SIMPLE_TYPE
: 0);
2060 flavor
&= ~XER_RECOF
; // record-of doesn't care
2061 int nof_elements
= get_nof_elements();
2062 Base_Type::begin_xml(p_td
, p_buf
, flavor
, indent
, !nof_elements
,
2063 (collector_fn
)&Record_Of_Type::collect_ns
);
2065 if (xmlValueList
&& nof_elements
&& indenting
&& !exer
) { /* !exer or GDMO */
2066 do_indent(p_buf
, indent
+1);
2071 if (exer
&& (p_td
.xer_bits
& ANY_ATTRIBUTES
)) {
2072 // Back up over the '>' and the '\n' that may follow it
2073 size_t buf_len
= p_buf
.get_len(), shorter
= 0;
2074 const unsigned char * const buf_data
= p_buf
.get_data();
2075 if (buf_data
[buf_len
- 1 - shorter
] == '\n') ++shorter
;
2076 if (buf_data
[buf_len
- 1 - shorter
] == '>' ) ++shorter
;
2078 unsigned char * saved
= 0;
2080 saved
= new unsigned char[shorter
];
2081 memcpy(saved
, buf_data
+ (buf_len
- shorter
), shorter
);
2082 p_buf
.increase_length(-shorter
);
2085 // ANY_ATTRIBUTES means it's a record of universal charstring.
2086 // They are in AnyAttributeFormat (X.693/2008 18.2.6):
2087 // "URI(optional), space, NCName, equals, \"xmlcstring\""
2088 // They need to be written as an XML attribute and namespace declaration:
2089 // xmlns:b0="URI" b0:NCName="xmlcstring"
2091 for (int i
= 0; i
< nof_elements
; ++i
) {
2092 if (i
< p_err_descr
->omit_before
) continue;
2094 const Erroneous_values_t
*ev
= p_err_descr
->next_field_err_values(i
, values_idx
);
2095 const Erroneous_descriptor_t
*ed
= p_err_descr
->next_field_emb_descr(i
, edescr_idx
);
2097 if (ev
&& ev
->before
) {
2098 if (ev
->before
->errval
==NULL
) TTCN_error("internal error: erroneous value missing");
2101 if (ev
->before
->raw
) ev
->before
->errval
->encode_raw(p_buf
);
2103 if (ev
->before
->type_descr
==NULL
) TTCN_error(
2104 "internal error: erroneous before type descriptor missing");
2105 else ev
->before
->errval
->XER_encode(*ev
->before
->type_descr
->xer
,
2106 p_buf
, flavor
, indent
, 0);
2110 if (ev
&& ev
->value
) { //value replacement
2111 if (ev
->value
->errval
) {
2112 if (ev
->value
->raw
) ev
->value
->errval
->encode_raw(p_buf
);
2114 if (ev
->value
->type_descr
==NULL
) TTCN_error(
2115 "internal error: erroneous value type descriptor missing");
2116 else ev
->value
->errval
->XER_encode(*ev
->value
->type_descr
->xer
,
2117 p_buf
, flavor
, indent
, 0);
2123 // embedded descr.. call negtest (except UNIVERSAL_CHARSTRING
2124 // doesn't have XER_encode_negtest)
2125 TTCN_error("internal error: embedded descriptor for scalar");
2128 // the original encoding
2129 const UNIVERSAL_CHARSTRING
*elem
2130 = static_cast<const UNIVERSAL_CHARSTRING
*>(get_at(i
));
2131 size_t len
= elem
->lengthof();
2133 const UNIVERSAL_CHARSTRING_ELEMENT
& ue
= (*elem
)[len
- 1];
2134 if (sp
== ue
|| tb
== ue
) --len
;
2137 // sp_at: indexes the first space
2138 // j is left to point at where the attribute name begins (just past the space)
2139 size_t j
, sp_at
= 0;
2140 for (j
= 0; j
< len
; j
++) {
2141 const UNIVERSAL_CHARSTRING_ELEMENT
& ue
= (*elem
)[j
];
2142 if (sp_at
) { // already found a space
2143 if (sp
== ue
|| tb
== ue
) {} // another space, do nothing
2144 else break; // found a non-space after a space
2147 if (sp
== ue
|| tb
== ue
) sp_at
= j
;
2152 char * ns
= mprintf(" xmlns:b%d='", i
);
2153 size_t ns_len
= mstrlen(ns
);
2154 p_buf
.put_s(ns_len
, (cbyte
*)ns
);
2156 UNIVERSAL_CHARSTRING
before(sp_at
, (const universal_char
*)(*elem
));
2157 before
.XER_encode(UNIVERSAL_CHARSTRING_xer_
, p_buf
,
2158 flavor
| ANY_ATTRIBUTES
, indent
, 0);
2163 // Keep just the "b%d" part from ns
2164 p_buf
.put_s(ns_len
- 9, (cbyte
*)ns
+ 7);
2173 UNIVERSAL_CHARSTRING
after(len
- j
, (const universal_char
*)(*elem
) + j
);
2174 after
.XER_encode(UNIVERSAL_CHARSTRING_xer_
, p_buf
,
2175 flavor
| ANY_ATTRIBUTES
, indent
, 0);
2179 if (ev
&& ev
->after
) {
2180 if (ev
->after
->errval
==NULL
) TTCN_error(
2181 "internal error: erroneous after value missing");
2183 if (ev
->after
->raw
) ev
->after
->errval
->encode_raw(p_buf
);
2185 if (ev
->after
->type_descr
==NULL
) TTCN_error(
2186 "internal error: erroneous after type descriptor missing");
2187 else ev
->after
->errval
->XER_encode(*ev
->after
->type_descr
->xer
,
2188 p_buf
, flavor
, indent
, 0);
2192 // omit_after value -1 becomes "very big"
2193 if ((unsigned int)i
>= (unsigned int)p_err_descr
->omit_after
) break;
2196 p_buf
.put_s(shorter
, saved
); // restore the '>' and anything after
2200 else { // not ANY-ATTRIBUTES
2201 unsigned int sub_flavor
= flavor
| XER_RECOF
| (p_td
.xer_bits
& (XER_LIST
|ANY_ATTRIBUTES
));
2203 TTCN_EncDec_ErrorContext ec
;
2205 for (int i
= 0; i
< nof_elements
; ++i
) {
2206 if (i
< p_err_descr
->omit_before
) continue;
2208 if (0 != emb_val
&& i
> 0 && !own_tag
&&
2209 emb_val
->embval_index
< emb_val
->embval_array
->size_of()) {
2210 const Erroneous_values_t
* ev0_i
= NULL
;
2211 const Erroneous_descriptor_t
* ed0_i
= NULL
;
2212 if (emb_val
->embval_err
) {
2213 ev0_i
= emb_val
->embval_err
->next_field_err_values(emb_val
->embval_index
, emb_val
->embval_err_val_idx
);
2214 ed0_i
= emb_val
->embval_err
->next_field_emb_descr (emb_val
->embval_index
, emb_val
->embval_err_descr_idx
);
2216 emb_val
->embval_array
->encode_element(emb_val
->embval_index
, UNIVERSAL_CHARSTRING_xer_
,
2217 ev0_i
, ed0_i
, p_buf
, flavor
| EMBED_VALUES
, indent
+ own_tag
, 0);
2218 ++emb_val
->embval_index
;
2221 const Erroneous_values_t
* err_vals
=
2222 p_err_descr
->next_field_err_values(i
, values_idx
);
2223 const Erroneous_descriptor_t
* emb_descr
=
2224 p_err_descr
->next_field_emb_descr (i
, edescr_idx
);
2226 encode_element(i
, *p_td
.oftype_descr
, err_vals
, emb_descr
, p_buf
, sub_flavor
, indent
+own_tag
, emb_val
);
2228 // omit_after value -1 becomes "very big"
2229 if ((unsigned int)i
>= (unsigned int)p_err_descr
->omit_after
) break;
2232 if (indenting
&& nof_elements
&& !is_exerlist(flavor
)) {
2233 if (xmlValueList
&& !exer
) p_buf
.put_c('\n'); /* !exer or GDMO */
2234 //do_indent(p_buf, indent);
2238 Base_Type::end_xml(p_td
, p_buf
, flavor
, indent
, !nof_elements
);
2239 return (int)p_buf
.get_len() - encoded_length
;
2242 int Record_Of_Type::XER_decode(const XERdescriptor_t
& p_td
,
2243 XmlReaderWrap
& reader
, unsigned int flavor
, unsigned int flavor2
, embed_values_dec_struct_t
* emb_val
)
2245 int exer
= is_exer(flavor
);
2246 int xerbits
= p_td
.xer_bits
;
2247 if (flavor
& XER_TOPLEVEL
) xerbits
&= ~UNTAGGED
;
2249 !(exer
&& ((xerbits
& (ANY_ELEMENT
| ANY_ATTRIBUTES
| UNTAGGED
))
2250 || (flavor
& USE_TYPE_ATTR
))); /* incase the parent has USE-UNION */
2251 /* not toplevel anymore and remove the flags for USE-UNION the oftype doesn't need them */
2252 flavor
&= ~XER_TOPLEVEL
& ~XER_LIST
& ~USE_TYPE_ATTR
;
2253 int success
=1, depth
=-1;
2254 set_val(NULL_VALUE
); // empty but initialized array, val_ptr != NULL
2256 if (own_tag
) for (success
= 1; success
== 1; success
= reader
.Read()) {
2257 type
= reader
.NodeType();
2258 if (exer
&& (p_td
.xer_bits
& XER_ATTRIBUTE
)) {
2259 if (XML_READER_TYPE_ATTRIBUTE
== type
) break;
2261 if (exer
&& (p_td
.xer_bits
& XER_LIST
)) {
2262 if (XML_READER_TYPE_TEXT
== type
) break;
2265 if (XML_READER_TYPE_ELEMENT
== type
) {
2266 verify_name(reader
, p_td
, exer
);
2267 depth
= reader
.Depth();
2270 } /* endif(exer && list) */
2272 else depth
= reader
.Depth();
2273 TTCN_EncDec_ErrorContext
ec_0("Index ");
2274 TTCN_EncDec_ErrorContext ec_1
;
2275 flavor
|= XER_RECOF
;
2276 if (exer
&& (p_td
.xer_bits
& ANY_ATTRIBUTES
)) {
2277 // The enclosing type should handle the decoding.
2278 TTCN_error("Incorrect decoding of ANY-ATTRIBUTES");
2280 else if (exer
&& (p_td
.xer_bits
& XER_LIST
)) { /* LIST decoding*/
2281 char *val
= (char*)reader
.NewValue(); /* we own it */
2283 size_t len
= strlen(val
);
2284 /* The string contains a bunch of values separated by whitespace.
2285 * Tokenize the string and create a new buffer which looks like
2286 * an XML element (<ns:name xmlns:ns='uri'>value</ns:name>), then use that
2287 * to decode the value. */
2288 for(char * str
= strtok(val
, " \t\x0A\x0D"); str
!= 0; str
= strtok(val
+ pos
, " \t\x0A\x0D")) {
2289 // Calling strtok with NULL won't work here, since the decoded element can have strtok calls aswell
2290 pos
+= strlen(str
) + 1;
2291 // Construct a new XML Reader with the current token.
2293 const XERdescriptor_t
& sub_xer
= *p_td
.oftype_descr
;
2295 write_ns_prefix(sub_xer
, buf2
);
2297 boolean i_can_has_ns
= sub_xer
.my_module
!= 0 && sub_xer
.ns_index
!= -1;
2298 const char * const exer_name
= sub_xer
.names
[1];
2299 buf2
.put_s((size_t)sub_xer
.namelens
[1]-1-i_can_has_ns
, (cbyte
*)exer_name
);
2301 const namespace_t
* const pns
= sub_xer
.my_module
->get_ns(sub_xer
.ns_index
);
2302 buf2
.put_s(7 - (*pns
->px
== 0), (cbyte
*)" xmlns:");
2303 buf2
.put_s(strlen(pns
->px
), (cbyte
*)pns
->px
);
2304 buf2
.put_s(2, (cbyte
*)"='");
2305 buf2
.put_s(strlen(pns
->ns
), (cbyte
*)pns
->ns
);
2306 buf2
.put_s(2, (cbyte
*)"'>");
2308 // start tag completed
2309 buf2
.put_s(strlen(str
), (cbyte
*)str
);
2313 write_ns_prefix(sub_xer
, buf2
);
2314 buf2
.put_s((size_t)sub_xer
.namelens
[1], (cbyte
*)exer_name
);
2315 XmlReaderWrap
reader2(buf2
);
2316 reader2
.Read(); // Move to the start element.
2317 // Don't move to the #text, that's the callee's responsibility.
2318 ec_1
.set_msg("%d: ", get_nof_elements());
2319 // The call to the non-const operator[], I mean get_at(), creates
2320 // a new element (because it is indexing one past the last element).
2321 // Then we call its XER_decode with the temporary XML reader.
2322 get_at(get_nof_elements())->XER_decode(sub_xer
, reader2
, flavor
, flavor2
, 0);
2323 if (flavor
& EXIT_ON_ERROR
&& !is_elem_bound(get_nof_elements() - 1)) {
2324 if (1 == get_nof_elements()) {
2325 // Failed to decode even the first element
2328 // Some elements were successfully decoded -> only delete the last one
2329 set_size(get_nof_elements() - 1);
2334 if (pos
>= len
) break;
2337 if (p_td
.xer_bits
& XER_ATTRIBUTE
) {
2338 //Let the caller do reader.AdvanceAttribute();
2341 reader
.Read(); // on closing tag
2342 reader
.Read(); // past it
2346 if (flavor
& PARENT_CLOSED
) {
2347 // Nothing to do. We are probably untagged; do not advance in the XML
2348 // because it would move past the parent.
2350 else if (own_tag
&& reader
.IsEmptyElement()) { // Nothing to do
2351 reader
.Read(); // This is our own empty tag, move past it
2354 /* Note: there is no reader.Read() at the end of the loop below.
2355 * Each element is supposed to consume enough to leave the next element
2356 * well-positioned. */
2357 for (success
= own_tag
? reader
.Read() : reader
.Ok(); success
== 1; ) {
2358 type
= reader
.NodeType();
2359 if (XML_READER_TYPE_ELEMENT
== type
)
2361 if (exer
&& (p_td
.xer_bits
& ANY_ELEMENT
)) {
2362 /* This is a (record-of UNIVERSAL_CHARSTRING) with ANY-ELEMENT.
2363 * The ANY-ELEMENT is really meant for the element type,
2364 * so behave like a record-of (string with ANY-ELEMENT):
2365 * call the non-const operator[], I mean get_at(), to create
2366 * a new element, then read the entire XML element into it. */
2367 UNIVERSAL_CHARSTRING
* uc
=
2368 static_cast<UNIVERSAL_CHARSTRING
*>(get_at(val_ptr
->n_elements
));
2369 const xmlChar
* outer
= reader
.ReadOuterXml();
2370 uc
->decode_utf8(strlen((const char*)outer
), outer
);
2371 // consume the element
2372 for (success
= reader
.Read(); success
== 1 && reader
.Depth() > depth
; success
= reader
.Read()) {}
2373 if (reader
.NodeType() != XML_READER_TYPE_ELEMENT
) success
= reader
.Read(); // one last time
2376 /* If this is an untagged record-of and the start element does not
2377 * belong to the embedded type, the record-of has already ended. */
2378 if (!own_tag
&& !can_start_v(
2379 (const char*)reader
.LocalName(), (const char*)reader
.NamespaceUri(),
2380 p_td
, flavor
| UNTAGGED
))
2382 for (; success
== 1 && reader
.Depth() > depth
; success
= reader
.Read()) ;
2383 // We should now be back at the same depth as we started.
2386 ec_1
.set_msg("%d: ", get_nof_elements());
2387 /* The call to the non-const get_at() creates the element */
2388 get_at(get_nof_elements())->XER_decode(*p_td
.oftype_descr
, reader
, flavor
, flavor2
, emb_val
);
2390 if (0 != emb_val
&& !own_tag
&& get_nof_elements() > 1) {
2391 ++emb_val
->embval_index
;
2394 else if (XML_READER_TYPE_END_ELEMENT
== type
) {
2395 for (; success
== 1 && reader
.Depth() > depth
; success
= reader
.Read()) ;
2396 // If the depth just decreased, this must be an end element
2397 // (but a different one from what we had before the loop)
2399 verify_end(reader
, p_td
, depth
, exer
);
2400 reader
.Read(); // move forward one last time
2404 else if (XML_READER_TYPE_TEXT
== type
&& 0 != emb_val
&& !own_tag
&& get_nof_elements() > 0) {
2405 UNIVERSAL_CHARSTRING
emb_ustr((const char*)reader
.Value());
2406 emb_val
->embval_array
->get_at(emb_val
->embval_index
)->set_value(&emb_ustr
);
2407 success
= reader
.Read();
2410 success
= reader
.Read();
2413 } /* if not empty element */
2415 if (!own_tag
&& exer
&& (p_td
.xer_bits
& XER_OPTIONAL
) && get_nof_elements() == 0) {
2416 // set it to unbound, so the OPTIONAL class sets it to omit
2419 return 1; // decode successful
2422 void Record_Of_Type::set_param(Module_Param
& param
) {
2423 if (dynamic_cast<Module_Param_Name
*>(param
.get_id()) != NULL
&&
2424 param
.get_id()->next_name()) {
2425 // Haven't reached the end of the module parameter name
2426 // => the name refers to one of the elements, not to the whole record of
2427 char* param_field
= param
.get_id()->get_current_name();
2428 if (param_field
[0] < '0' || param_field
[0] > '9') {
2429 param
.error("Unexpected record field name in module parameter, expected a valid"
2430 " index for %s type `%s'", is_set() ? "set of" : "record of", get_descriptor()->name
);
2432 int param_index
= -1;
2433 sscanf(param_field
, "%d", ¶m_index
);
2434 get_at(param_index
)->set_param(param
);
2438 param
.basic_check(Module_Param::BC_VALUE
|Module_Param::BC_LIST
, is_set()?"set of value":"record of value");
2440 Module_Param_Ptr mp
= ¶m
;
2441 if (param
.get_type() == Module_Param::MP_Reference
) {
2442 mp
= param
.get_referenced_param();
2445 switch (param
.get_operation_type()) {
2446 case Module_Param::OT_ASSIGN
:
2447 if (mp
->get_type()==Module_Param::MP_Value_List
&& mp
->get_size()==0) {
2448 set_val(NULL_VALUE
);
2451 switch (mp
->get_type()) {
2452 case Module_Param::MP_Value_List
:
2453 set_size(mp
->get_size());
2454 for (size_t i
=0; i
<mp
->get_size(); ++i
) {
2455 Module_Param
* const curr
= mp
->get_elem(i
);
2456 if (curr
->get_type()!=Module_Param::MP_NotUsed
) {
2457 get_at(i
)->set_param(*curr
);
2461 case Module_Param::MP_Indexed_List
:
2462 for (size_t i
=0; i
<mp
->get_size(); ++i
) {
2463 Module_Param
* const current
= mp
->get_elem(i
);
2464 get_at(current
->get_id()->get_index())->set_param(*current
);
2468 param
.type_error(is_set()?"set of value":"record of value", get_descriptor()->name
);
2471 case Module_Param::OT_CONCAT
:
2472 switch (mp
->get_type()) {
2473 case Module_Param::MP_Value_List
: {
2474 if (!is_bound()) set_val(NULL_VALUE
);
2475 int start_idx
= lengthof();
2476 for (size_t i
=0; i
<mp
->get_size(); ++i
) {
2477 Module_Param
* const curr
= mp
->get_elem(i
);
2478 if ((curr
->get_type()!=Module_Param::MP_NotUsed
)) {
2479 get_at(start_idx
+(int)i
)->set_param(*curr
);
2483 case Module_Param::MP_Indexed_List
:
2484 param
.error("Cannot concatenate an indexed value list");
2487 param
.type_error(is_set()?"set of value":"record of value", get_descriptor()->name
);
2491 TTCN_error("Internal error: Record_Of_Type::set_param()");
2495 Module_Param
* Record_Of_Type::get_param(Module_Param_Name
& param_name
) const
2498 return new Module_Param_Unbound();
2500 if (param_name
.next_name()) {
2501 // Haven't reached the end of the module parameter name
2502 // => the name refers to one of the elements, not to the whole record of
2503 char* param_field
= param_name
.get_current_name();
2504 if (param_field
[0] < '0' || param_field
[0] > '9') {
2505 TTCN_error("Unexpected record field name in module parameter reference, "
2506 "expected a valid index for %s type `%s'",
2507 is_set() ? "set of" : "record of", get_descriptor()->name
);
2509 int param_index
= -1;
2510 sscanf(param_field
, "%d", ¶m_index
);
2511 return get_at(param_index
)->get_param(param_name
);
2513 Vector
<Module_Param
*> values
;
2514 for (int i
= 0; i
< val_ptr
->n_elements
; ++i
) {
2515 values
.push_back(val_ptr
->value_elements
[i
]->get_param(param_name
));
2517 Module_Param_Value_List
* mp
= new Module_Param_Value_List();
2518 mp
->add_list_with_implicit_ids(&values
);
2523 void Record_Of_Type::set_implicit_omit()
2525 for (int i
= 0; i
< get_nof_elements(); ++i
) {
2526 if (is_elem_bound(i
))
2527 val_ptr
->value_elements
[i
]->set_implicit_omit();
2531 void Record_Of_Type::add_refd_index(int index
)
2533 if (NULL
== refd_ind_ptr
) {
2534 refd_ind_ptr
= new refd_index_struct
;
2535 refd_ind_ptr
->max_refd_index
= -1;
2537 refd_ind_ptr
->refd_indices
.push_back(index
);
2538 if (index
> get_max_refd_index()) {
2539 refd_ind_ptr
->max_refd_index
= index
;
2543 void Record_Of_Type::remove_refd_index(int index
)
2545 for (size_t i
= refd_ind_ptr
->refd_indices
.size(); i
> 0; --i
) {
2546 if (refd_ind_ptr
->refd_indices
[i
- 1] == index
) {
2547 refd_ind_ptr
->refd_indices
.erase_at(i
- 1);
2551 if (refd_ind_ptr
->refd_indices
.empty()) {
2552 delete refd_ind_ptr
;
2553 refd_ind_ptr
= NULL
;
2555 else if (get_max_refd_index() == index
) {
2556 refd_ind_ptr
->max_refd_index
= -1;
2560 boolean
operator==(null_type
/*null_value*/, const Record_Of_Type
& other_value
)
2562 if (other_value
.val_ptr
== NULL
)
2563 TTCN_error("The right operand of comparison is an unbound value of type %s.",
2564 other_value
.get_descriptor()->name
);
2565 return other_value
.get_nof_elements() == 0;
2568 boolean
operator!=(null_type null_value
,
2569 const Record_Of_Type
& other_value
)
2571 return !(null_value
== other_value
);
2574 ////////////////////////////////////////////////////////////////////////////////
2576 boolean
Record_Type::is_bound() const
2578 int field_cnt
= get_count();
2579 for (int field_idx
=0; field_idx
<field_cnt
; field_idx
++) {
2580 const Base_Type
* temp
= get_at(field_idx
);
2581 if(temp
->is_optional()) {
2582 if(temp
->is_present() && temp
->get_opt_value()->is_bound()) return TRUE
;
2584 if(temp
->is_bound()) return TRUE
;
2589 boolean
Record_Type::is_value() const
2591 int field_cnt
= get_count();
2592 for (int field_idx
=0; field_idx
<field_cnt
; field_idx
++) {
2593 const Base_Type
* temp
= get_at(field_idx
);
2594 if(temp
->is_optional()) {
2595 if(!temp
->is_bound()) return FALSE
;
2596 if(temp
->is_present() && !temp
->is_value()) return FALSE
;
2598 if(!temp
->is_value()) return FALSE
;
2604 void Record_Type::clean_up()
2606 int field_cnt
= get_count();
2607 for (int field_idx
=0; field_idx
<field_cnt
; field_idx
++) {
2608 get_at(field_idx
)->clean_up();
2612 void Record_Type::log() const
2615 TTCN_Logger::log_event_unbound();
2618 TTCN_Logger::log_event_str("{ ");
2619 int field_cnt
= get_count();
2620 for (int field_idx
=0; field_idx
<field_cnt
; field_idx
++) {
2621 if (field_idx
) TTCN_Logger::log_event_str(", ");
2622 TTCN_Logger::log_event_str(fld_name(field_idx
));
2623 TTCN_Logger::log_event_str(" := ");
2624 get_at(field_idx
)->log();
2626 TTCN_Logger::log_event_str(" }");
2627 if (err_descr
) err_descr
->log();
2630 void Record_Type::set_param(Module_Param
& param
) {
2631 if (dynamic_cast<Module_Param_Name
*>(param
.get_id()) != NULL
&&
2632 param
.get_id()->next_name()) {
2633 // Haven't reached the end of the module parameter name
2634 // => the name refers to one of the fields, not to the whole record
2635 char* param_field
= param
.get_id()->get_current_name();
2636 if (param_field
[0] >= '0' && param_field
[0] <= '9') {
2637 param
.error("Unexpected array index in module parameter, expected a valid field"
2638 " name for %s type `%s'", is_set() ? "set" : "record", get_descriptor()->name
);
2640 int field_cnt
= get_count();
2641 for (int field_idx
= 0; field_idx
< field_cnt
; field_idx
++) {
2642 if (strcmp(fld_name(field_idx
), param_field
) == 0) {
2643 get_at(field_idx
)->set_param(param
);
2647 param
.error("Field `%s' not found in %s type `%s'",
2648 param_field
, is_set() ? "set" : "record", get_descriptor()->name
);
2651 param
.basic_check(Module_Param::BC_VALUE
, is_set()?"set value":"record value");
2653 Module_Param_Ptr mp
= ¶m
;
2654 if (param
.get_type() == Module_Param::MP_Reference
) {
2655 mp
= param
.get_referenced_param();
2658 switch (mp
->get_type()) {
2659 case Module_Param::MP_Value_List
:
2660 if (get_count()<(int)mp
->get_size()) {
2661 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());
2663 for (size_t i
=0; i
<mp
->get_size(); i
++) {
2664 Module_Param
* mp_elem
= mp
->get_elem(i
);
2665 if (mp_elem
->get_type()!=Module_Param::MP_NotUsed
) {
2666 get_at((int)i
)->set_param(*mp_elem
);
2670 case Module_Param::MP_Assignment_List
:
2671 for (size_t i
=0; i
<mp
->get_size(); ++i
) {
2672 Module_Param
* const current
= mp
->get_elem(i
);
2674 for (int j
=0; j
<get_count(); ++j
) {
2675 if (!strcmp(fld_name(j
), current
->get_id()->get_name())) {
2676 if (current
->get_type()!=Module_Param::MP_NotUsed
) {
2677 get_at(j
)->set_param(*current
);
2684 current
->error("Non existent field name in type %s: %s.", get_descriptor()->name
, current
->get_id()->get_name());
2689 param
.type_error(is_set()?"set value":"record value", get_descriptor()->name
);
2693 Module_Param
* Record_Type::get_param(Module_Param_Name
& param_name
) const
2696 return new Module_Param_Unbound();
2698 if (param_name
.next_name()) {
2699 // Haven't reached the end of the module parameter name
2700 // => the name refers to one of the fields, not to the whole record
2701 char* param_field
= param_name
.get_current_name();
2702 if (param_field
[0] >= '0' && param_field
[0] <= '9') {
2703 TTCN_error("Unexpected array index in module parameter reference, "
2704 "expected a valid field name for %s type `%s'",
2705 is_set() ? "set" : "record", get_descriptor()->name
);
2707 int field_cnt
= get_count();
2708 for (int field_idx
= 0; field_idx
< field_cnt
; field_idx
++) {
2709 if (strcmp(fld_name(field_idx
), param_field
) == 0) {
2710 return get_at(field_idx
)->get_param(param_name
);
2713 TTCN_error("Field `%s' not found in %s type `%s'",
2714 param_field
, is_set() ? "set" : "record", get_descriptor()->name
);
2716 Module_Param_Assignment_List
* mp
= new Module_Param_Assignment_List();
2717 for (int i
= 0; i
< get_count(); ++i
) {
2718 Module_Param
* mp_field
= get_at(i
)->get_param(param_name
);
2719 mp_field
->set_id(new Module_Param_FieldName(mcopystr(fld_name(i
))));
2720 mp
->add_elem(mp_field
);
2725 void Record_Type::set_implicit_omit()
2727 int field_cnt
= get_count();
2728 for (int field_idx
= 0; field_idx
< field_cnt
; field_idx
++) {
2729 Base_Type
*temp
= get_at(field_idx
);
2730 if (temp
->is_optional()) {
2731 if (temp
->is_bound()) temp
->set_implicit_omit();
2732 else temp
->set_to_omit();
2733 } else if (temp
->is_bound()) {
2734 temp
->set_implicit_omit();
2739 int Record_Type::size_of() const
2741 int opt_count
= optional_count();
2742 if (opt_count
==0) return get_count();
2743 const int* optional_indexes
= get_optional_indexes();
2744 int my_size
= get_count();
2745 for (int i
=0; i
<opt_count
; i
++) {
2746 if (!get_at(optional_indexes
[i
])->ispresent()) my_size
--;
2751 void Record_Type::encode_text(Text_Buf
& text_buf
) const
2754 TTCN_error("Text encoder: Encoding an unbound record/set value of type %s.",
2755 get_descriptor()->name
);
2757 int field_cnt
= get_count();
2758 for (int field_idx
=0; field_idx
<field_cnt
; field_idx
++)
2759 get_at(field_idx
)->encode_text(text_buf
);
2762 void Record_Type::decode_text(Text_Buf
& text_buf
)
2764 int field_cnt
= get_count();
2765 for (int field_idx
=0; field_idx
<field_cnt
; field_idx
++)
2766 get_at(field_idx
)->decode_text(text_buf
);
2769 boolean
Record_Type::is_equal(const Base_Type
* other_value
) const
2771 const Record_Type
* other_record
= static_cast<const Record_Type
*>(other_value
);
2772 int field_cnt
= get_count();
2773 for (int field_idx
=0; field_idx
<field_cnt
; field_idx
++) {
2774 const Base_Type
* elem
= get_at(field_idx
);
2775 const Base_Type
* other_elem
= other_record
->get_at(field_idx
);
2776 if (elem
->is_bound()) {
2777 if (other_elem
->is_bound()) {
2778 if (!elem
->is_equal(other_elem
))
2780 } else return FALSE
;
2781 } else if (other_elem
->is_bound()) return FALSE
;
2786 void Record_Type::set_value(const Base_Type
* other_value
)
2788 if (this==other_value
) return;
2789 if (!other_value
->is_bound())
2790 TTCN_error("Copying an unbound record/set value of type %s.",
2791 other_value
->get_descriptor()->name
);
2792 const Record_Type
* other_record
= static_cast<const Record_Type
*>(other_value
);
2793 int field_cnt
= get_count();
2794 for (int field_idx
=0; field_idx
<field_cnt
; field_idx
++) {
2795 const Base_Type
* elem
= other_record
->get_at(field_idx
);
2796 if (elem
->is_bound()) {
2797 get_at(field_idx
)->set_value(elem
);
2799 get_at(field_idx
)->clean_up();
2802 err_descr
= other_record
->err_descr
;
2805 void Record_Type::encode(const TTCN_Typedescriptor_t
& p_td
,
2806 TTCN_Buffer
& p_buf
, TTCN_EncDec::coding_t p_coding
, ...) const
2809 va_start(pvar
, p_coding
);
2811 case TTCN_EncDec::CT_BER
: {
2812 TTCN_EncDec_ErrorContext
ec("While BER-encoding type '%s': ", p_td
.name
);
2813 unsigned BER_coding
=va_arg(pvar
, unsigned);
2814 BER_encode_chk_coding(BER_coding
);
2815 ASN_BER_TLV_t
*tlv
=BER_encode_TLV(p_td
, BER_coding
);
2816 tlv
->put_in_buffer(p_buf
);
2817 ASN_BER_TLV_t::destruct(tlv
);
2819 case TTCN_EncDec::CT_RAW
: {
2820 TTCN_EncDec_ErrorContext
ec("While RAW-encoding type '%s': ", p_td
.name
);
2821 if(!p_td
.raw
) TTCN_EncDec_ErrorContext::error_internal
2822 ("No RAW descriptor available for type '%s'.", p_td
.name
);
2826 RAW_enc_tree
root(FALSE
, NULL
, &rp
, 1, p_td
.raw
);
2827 RAW_encode(p_td
, root
);
2828 root
.put_to_buf(p_buf
);
2830 case TTCN_EncDec::CT_TEXT
: {
2831 TTCN_EncDec_ErrorContext
ec("While TEXT-encoding type '%s': ", p_td
.name
);
2832 if(!p_td
.text
) TTCN_EncDec_ErrorContext::error_internal
2833 ("No TEXT descriptor available for type '%s'.", p_td
.name
);
2834 TEXT_encode(p_td
,p_buf
);
2836 case TTCN_EncDec::CT_XER
: {
2837 TTCN_EncDec_ErrorContext
ec("While XER-encoding type '%s': ", p_td
.name
);
2838 unsigned XER_coding
=va_arg(pvar
, unsigned);
2839 XER_encode(*(p_td
.xer
),p_buf
, XER_coding
, 0, 0);
2842 case TTCN_EncDec::CT_JSON
: {
2843 TTCN_EncDec_ErrorContext
ec("While JSON-encoding type '%s': ", p_td
.name
);
2844 if(!p_td
.json
) TTCN_EncDec_ErrorContext::error_internal
2845 ("No JSON descriptor available for type '%s'.", p_td
.name
);
2846 JSON_Tokenizer
tok(va_arg(pvar
, int) != 0);
2847 JSON_encode(p_td
, tok
);
2848 p_buf
.put_s(tok
.get_buffer_length(), (const unsigned char*)tok
.get_buffer());
2851 TTCN_error("Unknown coding method requested to encode type '%s'", p_td
.name
);
2856 void Record_Type::decode(const TTCN_Typedescriptor_t
& p_td
,
2857 TTCN_Buffer
& p_buf
, TTCN_EncDec::coding_t p_coding
, ...)
2860 va_start(pvar
, p_coding
);
2862 case TTCN_EncDec::CT_BER
: {
2863 TTCN_EncDec_ErrorContext
ec("While BER-decoding type '%s': ", p_td
.name
);
2864 unsigned L_form
=va_arg(pvar
, unsigned);
2866 BER_decode_str2TLV(p_buf
, tlv
, L_form
);
2867 BER_decode_TLV(p_td
, tlv
, L_form
);
2868 if(tlv
.isComplete
) p_buf
.increase_pos(tlv
.get_len());
2870 case TTCN_EncDec::CT_RAW
: {
2871 TTCN_EncDec_ErrorContext
ec("While RAW-decoding type '%s': ", p_td
.name
);
2873 TTCN_EncDec_ErrorContext::error_internal
2874 ("No RAW descriptor available for type '%s'.", p_td
.name
);
2876 switch(p_td
.raw
->top_bit_order
) {
2884 int rawr
= RAW_decode(p_td
, p_buf
, p_buf
.get_len()*8, order
);
2885 if (rawr
< 0) switch (-rawr
) {
2886 case TTCN_EncDec::ET_INCOMPL_MSG
:
2887 case TTCN_EncDec::ET_LEN_ERR
:
2888 ec
.error(TTCN_EncDec::ET_INCOMPL_MSG
,
2889 "Can not decode type '%s', because incomplete"
2890 " message was received", p_td
.name
);
2893 // The RAW/TEXT decoders return -1 for anything not a length error.
2894 // This is the value for ET_UNBOUND, which can't happen in decoding.
2896 ec
.error(TTCN_EncDec::ET_INVAL_MSG
,
2897 "Can not decode type '%s', because invalid"
2898 " message was received", p_td
.name
);
2902 case TTCN_EncDec::CT_TEXT
: {
2903 Limit_Token_List limit
;
2904 TTCN_EncDec_ErrorContext
ec("While TEXT-decoding type '%s': ", p_td
.name
);
2905 if(!p_td
.text
) TTCN_EncDec_ErrorContext::error_internal
2906 ("No TEXT descriptor available for type '%s'.", p_td
.name
);
2907 const unsigned char *b
=p_buf
.get_data();
2908 if(b
[p_buf
.get_len()-1]!='\0'){
2909 p_buf
.set_pos(p_buf
.get_len());
2910 p_buf
.put_zero(8,ORDER_LSB
);
2913 if(TEXT_decode(p_td
,p_buf
,limit
)<0)
2914 ec
.error(TTCN_EncDec::ET_INCOMPL_MSG
,
2915 "Can not decode type '%s', because invalid or incomplete"
2916 " message was received", p_td
.name
);
2918 case TTCN_EncDec::CT_XER
: {
2919 TTCN_EncDec_ErrorContext
ec("While XER-decoding type '%s': ", p_td
.name
);
2920 unsigned XER_coding
=va_arg(pvar
, unsigned);
2921 XmlReaderWrap
reader(p_buf
);
2922 for (int success
=reader
.Read(); success
==1; success
=reader
.Read()) {
2923 if (reader
.NodeType() == XML_READER_TYPE_ELEMENT
) break;
2925 XER_decode(*(p_td
.xer
), reader
, XER_coding
| XER_TOPLEVEL
, XER_NONE
, 0);
2926 size_t bytes
= reader
.ByteConsumed();
2927 p_buf
.set_pos(bytes
);
2929 case TTCN_EncDec::CT_JSON
: {
2930 TTCN_EncDec_ErrorContext
ec("While JSON-decoding type '%s': ", p_td
.name
);
2931 if(!p_td
.json
) TTCN_EncDec_ErrorContext::error_internal
2932 ("No JSON descriptor available for type '%s'.", p_td
.name
);
2933 JSON_Tokenizer
tok((const char*)p_buf
.get_data(), p_buf
.get_len());
2934 if(JSON_decode(p_td
, tok
, false)<0)
2935 ec
.error(TTCN_EncDec::ET_INCOMPL_MSG
,
2936 "Can not decode type '%s', because invalid or incomplete"
2937 " message was received", p_td
.name
);
2938 p_buf
.set_pos(tok
.get_buf_pos());
2941 TTCN_error("Unknown coding method requested to decode type '%s'", p_td
.name
);
2946 ASN_BER_TLV_t
* Record_Type::BER_encode_TLV(const TTCN_Typedescriptor_t
& p_td
, unsigned p_coding
) const
2949 return BER_encode_TLV_negtest(err_descr
, p_td
, p_coding
);
2952 TTCN_EncDec_ErrorContext::error
2953 (TTCN_EncDec::ET_UNBOUND
, "Encoding an unbound value.");
2955 BER_chk_descr(p_td
);
2956 ASN_BER_TLV_t
*new_tlv
=ASN_BER_TLV_t::construct(NULL
);
2957 TTCN_EncDec_ErrorContext
ec_0("Component '");
2958 TTCN_EncDec_ErrorContext ec_1
;
2959 int next_default_idx
= 0;
2960 const default_struct
* default_indexes
= get_default_indexes();
2961 int field_cnt
= get_count();
2962 for(int i
=0; i
<field_cnt
; i
++) {
2963 boolean is_default_field
= default_indexes
&& (default_indexes
[next_default_idx
].index
==i
);
2964 if (!default_as_optional() && is_default_field
) {
2965 if (!get_at(i
)->is_equal(default_indexes
[next_default_idx
].value
)) {
2966 ec_1
.set_msg("%s': ", fld_name(i
));
2967 new_tlv
->add_TLV(get_at(i
)->BER_encode_TLV(*fld_descr(i
), p_coding
));
2969 } else { /* is not DEFAULT */
2970 ec_1
.set_msg("%s': ", fld_name(i
));
2971 new_tlv
->add_TLV(get_at(i
)->BER_encode_TLV(*fld_descr(i
), p_coding
));
2973 if (is_default_field
) next_default_idx
++;
2976 if (p_coding
==BER_ENCODE_DER
) new_tlv
->sort_tlvs_tag();
2977 new_tlv
=ASN_BER_V2TLV(new_tlv
, p_td
, p_coding
);
2981 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
2984 TTCN_EncDec_ErrorContext::error
2985 (TTCN_EncDec::ET_UNBOUND
, "Encoding an unbound value.");
2987 BER_chk_descr(p_td
);
2988 ASN_BER_TLV_t
*new_tlv
=ASN_BER_TLV_t::construct(NULL
);
2989 TTCN_EncDec_ErrorContext
ec_0("Component '");
2990 TTCN_EncDec_ErrorContext ec_1
;
2991 int next_default_idx
= 0;
2992 const default_struct
* default_indexes
= get_default_indexes();
2993 int field_cnt
= get_count();
2998 for (int i
=0; i
<field_cnt
; i
++) {
2999 boolean is_default_field
= default_indexes
&& (default_indexes
[next_default_idx
].index
==i
);
3000 // the first condition is not needed, kept for ease of understanding
3001 if ( (p_err_descr
->omit_before
!=-1) && (i
<p_err_descr
->omit_before
) ) {
3002 if (is_default_field
) next_default_idx
++;
3005 const Erroneous_values_t
* err_vals
= p_err_descr
->next_field_err_values(i
, values_idx
);
3006 const Erroneous_descriptor_t
* emb_descr
= p_err_descr
->next_field_emb_descr(i
, edescr_idx
);
3008 if (err_vals
&& err_vals
->before
) {
3009 if (err_vals
->before
->errval
==NULL
) TTCN_error(
3010 "internal error: erroneous before value missing");
3011 ec_1
.set_msg("%s'(erroneous before): ", fld_name(i
));
3012 if (err_vals
->before
->raw
) {
3013 new_tlv
->add_TLV(err_vals
->before
->errval
->BER_encode_negtest_raw());
3015 if (err_vals
->before
->type_descr
==NULL
) TTCN_error(
3016 "internal error: erroneous before typedescriptor missing");
3017 new_tlv
->add_TLV(err_vals
->before
->errval
->BER_encode_TLV(
3018 *err_vals
->before
->type_descr
, p_coding
));
3022 if (err_vals
&& err_vals
->value
) {
3023 if (err_vals
->value
->errval
) { // replace
3024 ec_1
.set_msg("%s'(erroneous value): ", fld_name(i
));
3025 if (err_vals
->value
->raw
) {
3026 new_tlv
->add_TLV(err_vals
->value
->errval
->BER_encode_negtest_raw());
3028 if (err_vals
->value
->type_descr
==NULL
) TTCN_error(
3029 "internal error: erroneous value typedescriptor missing");
3030 new_tlv
->add_TLV(err_vals
->value
->errval
->BER_encode_TLV(
3031 *err_vals
->value
->type_descr
, p_coding
));
3035 if (!default_as_optional() && is_default_field
) {
3036 if (!get_at(i
)->is_equal(default_indexes
[next_default_idx
].value
)) {
3037 ec_1
.set_msg("'%s': ", fld_name(i
));
3039 new_tlv
->add_TLV(get_at(i
)->BER_encode_TLV_negtest(emb_descr
,
3040 *fld_descr(i
), p_coding
));
3042 new_tlv
->add_TLV(get_at(i
)->BER_encode_TLV(*fld_descr(i
), p_coding
));
3045 } else { /* is not DEFAULT */
3046 ec_1
.set_msg("'%s': ", fld_name(i
));
3048 new_tlv
->add_TLV(get_at(i
)->BER_encode_TLV_negtest(emb_descr
,
3049 *fld_descr(i
), p_coding
));
3051 new_tlv
->add_TLV(get_at(i
)->BER_encode_TLV(*fld_descr(i
), p_coding
));
3056 if (err_vals
&& err_vals
->after
) {
3057 if (err_vals
->after
->errval
==NULL
) TTCN_error(
3058 "internal error: erroneous after value missing");
3059 ec_1
.set_msg("%s'(erroneous after): ", fld_name(i
));
3060 if (err_vals
->after
->raw
) {
3061 new_tlv
->add_TLV(err_vals
->after
->errval
->BER_encode_negtest_raw());
3063 if (err_vals
->after
->type_descr
==NULL
) TTCN_error(
3064 "internal error: erroneous after typedescriptor missing");
3065 new_tlv
->add_TLV(err_vals
->after
->errval
->BER_encode_TLV(
3066 *err_vals
->after
->type_descr
, p_coding
));
3070 if (is_default_field
) next_default_idx
++;
3071 if ( (p_err_descr
->omit_after
!=-1) && (i
>=p_err_descr
->omit_after
) ) break;
3075 if (p_coding
==BER_ENCODE_DER
) new_tlv
->sort_tlvs_tag();
3076 new_tlv
=ASN_BER_V2TLV(new_tlv
, p_td
, p_coding
);
3080 boolean
Record_Type::BER_decode_TLV(const TTCN_Typedescriptor_t
& p_td
,
3081 const ASN_BER_TLV_t
& p_tlv
, unsigned L_form
)
3083 BER_chk_descr(p_td
);
3084 ASN_BER_TLV_t stripped_tlv
;
3085 BER_decode_strip_tags(*p_td
.ber
, p_tlv
, L_form
, stripped_tlv
);
3086 TTCN_EncDec_ErrorContext
ec_0("While decoding '%s' type: ", get_descriptor()->name
);
3087 stripped_tlv
.chk_constructed_flag(TRUE
);
3089 ASN_BER_TLV_t tmp_tlv
;
3091 { /* SEQUENCE decoding */
3092 boolean tlv_present
=FALSE
;
3094 TTCN_EncDec_ErrorContext
ec_1("Component '");
3095 TTCN_EncDec_ErrorContext ec_2
;
3096 int next_default_idx
= 0;
3097 int next_optional_idx
= 0;
3098 const default_struct
* default_indexes
= get_default_indexes();
3099 const int* optional_indexes
= get_optional_indexes();
3100 int field_cnt
= get_count();
3101 for(int i
=0; i
<field_cnt
; i
++) {
3102 boolean is_default_field
= default_indexes
&& (default_indexes
[next_default_idx
].index
==i
);
3103 boolean is_optional_field
= optional_indexes
&& (optional_indexes
[next_optional_idx
]==i
);
3104 ec_2
.set_msg("%s': ", fld_descr(i
)->name
);
3105 if (!tlv_present
) tlv_present
=BER_decode_constdTLV_next(stripped_tlv
, V_pos
, L_form
, tmp_tlv
);
3106 if (is_default_field
) { /* is DEFAULT */
3107 if (!tlv_present
|| !get_at(i
)->BER_decode_isMyMsg(*fld_descr(i
), tmp_tlv
)) {
3108 get_at(i
)->set_value(default_indexes
[next_default_idx
].value
);
3110 get_at(i
)->BER_decode_TLV(*fld_descr(i
), tmp_tlv
, L_form
);
3114 else if (is_optional_field
) { /* is OPTIONAL */
3115 if (!tlv_present
) get_at(i
)->set_to_omit();
3117 get_at(i
)->BER_decode_TLV(*fld_descr(i
), tmp_tlv
, L_form
);
3118 if (get_at(i
)->ispresent()) tlv_present
=FALSE
;
3121 else { /* is not DEFAULT OPTIONAL */
3123 ec_2
.error(TTCN_EncDec::ET_INCOMPL_MSG
,"Invalid or incomplete message was received.");
3126 get_at(i
)->BER_decode_TLV(*fld_descr(i
), tmp_tlv
, L_form
);
3129 if (is_default_field
) next_default_idx
++;
3130 if (is_optional_field
) next_optional_idx
++;
3133 BER_decode_constdTLV_end(stripped_tlv
, V_pos
, L_form
, tmp_tlv
, tlv_present
);
3134 } /* SEQUENCE decoding */
3136 { /* SET decoding */
3138 * 0x01: value arrived
3139 * 0x02: is optional / not used :)
3140 * 0x04: has default / not used :)
3142 int field_cnt
= get_count();
3143 unsigned char* fld_indctr
= new unsigned char[field_cnt
];
3144 for (int i
=0; i
<field_cnt
; i
++) fld_indctr
[i
] = 0;
3145 int fld_curr
= -1; /* ellipsis or error... */
3146 while (BER_decode_constdTLV_next(stripped_tlv
, V_pos
, L_form
, tmp_tlv
)) {
3147 for (int i
=0; i
<field_cnt
; i
++) {
3148 if (get_at(i
)->BER_decode_isMyMsg(*fld_descr(i
), tmp_tlv
)) {
3150 TTCN_EncDec_ErrorContext
ec_1("Component '%s': ", fld_name(i
));
3151 get_at(i
)->BER_decode_TLV(*fld_descr(i
), tmp_tlv
, L_form
);
3156 if (fld_indctr
[fld_curr
])
3157 ec_0
.error(TTCN_EncDec::ET_DEC_DUPFLD
, "Duplicated value for component '%s'.", fld_name(fld_curr
));
3158 fld_indctr
[fld_curr
]=1;
3161 int next_default_idx
= 0;
3162 int next_optional_idx
= 0;
3163 const default_struct
* default_indexes
= get_default_indexes();
3164 const int* optional_indexes
= get_optional_indexes();
3165 for (fld_curr
=0; fld_curr
<field_cnt
; fld_curr
++) {
3166 boolean is_default_field
= default_indexes
&& (default_indexes
[next_default_idx
].index
==fld_curr
);
3167 boolean is_optional_field
= optional_indexes
&& (optional_indexes
[next_optional_idx
]==fld_curr
);
3168 if (!fld_indctr
[fld_curr
]) {
3169 if (is_default_field
) get_at(fld_curr
)->set_value(default_indexes
[next_default_idx
].value
);
3170 else if (is_optional_field
) get_at(fld_curr
)->set_to_omit();
3171 else ec_0
.error(TTCN_EncDec::ET_DEC_MISSFLD
, "Missing value for component '%s'.", fld_name(fld_curr
));
3173 if (is_default_field
) next_default_idx
++;
3174 if (is_optional_field
) next_optional_idx
++;
3176 delete[] fld_indctr
;
3177 } /* SET decoding */
3179 if (is_opentype_outermost()) {
3180 TTCN_EncDec_ErrorContext
ec_1("While decoding opentypes: ");
3181 TTCN_Type_list p_typelist
;
3182 BER_decode_opentypes(p_typelist
, L_form
);
3183 } /* if sdef->opentype_outermost */
3187 void Record_Type::BER_decode_opentypes(TTCN_Type_list
& p_typelist
, unsigned L_form
)
3189 p_typelist
.push(this);
3190 TTCN_EncDec_ErrorContext
ec_0("Component '");
3191 TTCN_EncDec_ErrorContext ec_1
;
3192 int field_cnt
= get_count();
3193 for(int i
=0; i
<field_cnt
; i
++) {
3194 ec_1
.set_msg("%s': ", fld_name(i
));
3195 get_at(i
)->BER_decode_opentypes(p_typelist
, L_form
);
3200 int Record_Type::RAW_encode(const TTCN_Typedescriptor_t
& p_td
,
3201 RAW_enc_tree
& myleaf
) const
3203 if (err_descr
) return RAW_encode_negtest(err_descr
, p_td
, myleaf
);
3205 TTCN_EncDec_ErrorContext::error
3206 (TTCN_EncDec::ET_UNBOUND
, "Encoding an unbound value.");
3208 int encoded_length
= 0;
3209 int field_cnt
= get_count();
3210 myleaf
.isleaf
= false;
3211 myleaf
.body
.node
.num_of_nodes
= field_cnt
;
3212 myleaf
.body
.node
.nodes
= init_nodes_of_enc_tree(field_cnt
);
3214 int next_optional_idx
= 0;
3215 const int* optional_indexes
= get_optional_indexes();
3216 for (int i
= 0; i
< field_cnt
; i
++) {
3217 boolean is_optional_field
= optional_indexes
3218 && (optional_indexes
[next_optional_idx
] == i
);
3219 if (!is_optional_field
|| get_at(i
)->ispresent()) {
3220 myleaf
.body
.node
.nodes
[i
] = new RAW_enc_tree(true, &myleaf
,
3221 &(myleaf
.curr_pos
), i
, fld_descr(i
)->raw
);
3224 myleaf
.body
.node
.nodes
[i
] = NULL
;
3226 if (is_optional_field
) next_optional_idx
++;
3228 next_optional_idx
= 0;
3229 for (int i
= 0; i
< field_cnt
; i
++) { /*encoding fields*/
3230 boolean is_optional_field
= optional_indexes
3231 && (optional_indexes
[next_optional_idx
] == i
);
3232 /* encoding of normal fields*/
3233 const Base_Type
*field
= get_at(i
);
3234 if (is_optional_field
) {
3235 next_optional_idx
++;
3236 if (!field
->ispresent())
3237 continue; // do not encode
3239 field
= field
->get_opt_value(); // "reach into" the optional
3241 encoded_length
+= field
->RAW_encode(*fld_descr(i
),
3242 *myleaf
.body
.node
.nodes
[i
]);
3244 return myleaf
.length
= encoded_length
;
3247 // In some cases (e.g. LENGTHTO, POINTERTO, CROSSTAG) it is not generated.
3248 int Record_Type::RAW_encode_negtest(const Erroneous_descriptor_t
*p_err_descr
,
3249 const TTCN_Typedescriptor_t
& /*p_td*/, RAW_enc_tree
& myleaf
) const
3252 TTCN_EncDec_ErrorContext::error
3253 (TTCN_EncDec::ET_UNBOUND
, "Encoding an unbound value.");
3255 int encoded_length
= 0;
3256 int num_fields
= get_count();
3257 myleaf
.isleaf
= false;
3258 myleaf
.body
.node
.num_of_nodes
= 0;
3259 for (int field_idx
= 0; field_idx
< num_fields
; ++field_idx
) {
3260 if ((p_err_descr
->omit_before
!= -1) &&
3261 (field_idx
< p_err_descr
->omit_before
))
3263 else ++myleaf
.body
.node
.num_of_nodes
;
3264 const Erroneous_values_t
*err_vals
= p_err_descr
->get_field_err_values(field_idx
);
3265 if (err_vals
&& err_vals
->before
)
3266 ++myleaf
.body
.node
.num_of_nodes
;
3267 if (err_vals
&& err_vals
->value
&& !err_vals
->value
->errval
)
3268 --myleaf
.body
.node
.num_of_nodes
;
3269 if (err_vals
&& err_vals
->after
)
3270 ++myleaf
.body
.node
.num_of_nodes
;
3271 if ((p_err_descr
->omit_after
!= -1) &&
3272 (field_idx
>= p_err_descr
->omit_after
))
3275 myleaf
.body
.node
.nodes
= init_nodes_of_enc_tree(myleaf
.body
.node
.num_of_nodes
);
3276 TTCN_EncDec_ErrorContext ec
;
3277 int next_optional_idx
= 0;
3278 const int *my_optional_indexes
= get_optional_indexes();
3279 // Counter for fields and additional before/after fields.
3281 for (int field_idx
= 0; field_idx
< num_fields
; ++field_idx
) {
3282 boolean is_optional_field
= my_optional_indexes
&&
3283 (my_optional_indexes
[next_optional_idx
] == field_idx
);
3284 if ((p_err_descr
->omit_before
!= -1) &&
3285 (field_idx
< p_err_descr
->omit_before
)) {
3286 if (is_optional_field
) ++next_optional_idx
;
3289 const Erroneous_values_t
*err_vals
= p_err_descr
->get_field_err_values(field_idx
);
3290 const Erroneous_descriptor_t
*emb_descr
= p_err_descr
->get_field_emb_descr(field_idx
);
3291 if (err_vals
&& err_vals
->before
) {
3292 if (err_vals
->before
->errval
== NULL
)
3293 TTCN_error("internal error: erroneous before value missing");
3294 if (err_vals
->before
->raw
) {
3295 myleaf
.body
.node
.nodes
[node_pos
] =
3296 new RAW_enc_tree(true, &myleaf
, &(myleaf
.curr_pos
), node_pos
,
3297 err_vals
->before
->errval
->get_descriptor()->raw
);
3298 encoded_length
+= err_vals
->before
->errval
->
3299 RAW_encode_negtest_raw(*myleaf
.body
.node
.nodes
[node_pos
++]);
3301 if (err_vals
->before
->type_descr
== NULL
)
3302 TTCN_error("internal error: erroneous before typedescriptor missing");
3303 myleaf
.body
.node
.nodes
[node_pos
] =
3304 new RAW_enc_tree(true, &myleaf
, &(myleaf
.curr_pos
), node_pos
,
3305 err_vals
->before
->type_descr
->raw
);
3306 encoded_length
+= err_vals
->before
->errval
->
3307 RAW_encode(*(err_vals
->before
->type_descr
),
3308 *myleaf
.body
.node
.nodes
[node_pos
++]);
3311 if (err_vals
&& err_vals
->value
) {
3312 if (err_vals
->value
->errval
) {
3313 ec
.set_msg("'%s'(erroneous value): ", fld_name(field_idx
));
3314 if (err_vals
->value
->raw
) {
3315 myleaf
.body
.node
.nodes
[node_pos
] =
3316 new RAW_enc_tree(true, &myleaf
, &(myleaf
.curr_pos
), node_pos
,
3317 err_vals
->value
->errval
->get_descriptor()->raw
);
3318 encoded_length
+= err_vals
->value
->errval
->
3319 RAW_encode_negtest_raw(*myleaf
.body
.node
.nodes
[node_pos
++]);
3321 if (err_vals
->value
->type_descr
== NULL
)
3322 TTCN_error("internal error: erroneous value typedescriptor missing");
3323 myleaf
.body
.node
.nodes
[node_pos
] =
3324 new RAW_enc_tree(true, &myleaf
, &(myleaf
.curr_pos
), node_pos
,
3325 err_vals
->value
->type_descr
->raw
);
3326 encoded_length
+= err_vals
->value
->errval
->
3327 RAW_encode(*(err_vals
->value
->type_descr
),
3328 *myleaf
.body
.node
.nodes
[node_pos
++]);
3332 ec
.set_msg("'%s': ", fld_name(field_idx
));
3333 if (!is_optional_field
|| get_at(field_idx
)->ispresent()) {
3334 const Base_Type
*field
=
3335 is_optional_field
? get_at(field_idx
)->get_opt_value()
3336 : get_at(field_idx
);
3337 myleaf
.body
.node
.nodes
[node_pos
] =
3338 new RAW_enc_tree(true, &myleaf
, &(myleaf
.curr_pos
), node_pos
,
3339 fld_descr(field_idx
)->raw
);
3342 field
->RAW_encode_negtest(emb_descr
, *fld_descr(field_idx
),
3343 *myleaf
.body
.node
.nodes
[node_pos
++]);
3346 field
->RAW_encode(*fld_descr(field_idx
),
3347 *myleaf
.body
.node
.nodes
[node_pos
++]);
3351 myleaf
.body
.node
.nodes
[node_pos
++] = NULL
;
3354 if (err_vals
&& err_vals
->after
) {
3355 if (err_vals
->after
->errval
== NULL
)
3356 TTCN_error("internal error: erroneous before value missing");
3357 if (err_vals
->after
->raw
) {
3358 myleaf
.body
.node
.nodes
[node_pos
] =
3359 new RAW_enc_tree(true, &myleaf
, &(myleaf
.curr_pos
), node_pos
,
3360 err_vals
->after
->errval
->get_descriptor()->raw
);
3361 encoded_length
+= err_vals
->after
->errval
->
3362 RAW_encode_negtest_raw(*myleaf
.body
.node
.nodes
[node_pos
++]);
3364 if (err_vals
->after
->type_descr
== NULL
)
3365 TTCN_error("internal error: erroneous after typedescriptor missing");
3366 myleaf
.body
.node
.nodes
[node_pos
] =
3367 new RAW_enc_tree(true, &myleaf
, &(myleaf
.curr_pos
), node_pos
,
3368 err_vals
->after
->type_descr
->raw
);
3369 encoded_length
+= err_vals
->after
->errval
->
3370 RAW_encode(*(err_vals
->after
->type_descr
),
3371 *myleaf
.body
.node
.nodes
[node_pos
++]);
3374 if (is_optional_field
) ++next_optional_idx
;
3375 if ((p_err_descr
->omit_after
!= -1) &&
3376 (field_idx
>= p_err_descr
->omit_after
))
3379 return myleaf
.length
= encoded_length
;
3382 int Record_Type::RAW_decode(const TTCN_Typedescriptor_t
& p_td
, TTCN_Buffer
& buff
,
3383 int limit
, raw_order_t top_bit_ord
, boolean no_err
, int, boolean
)
3385 int field_cnt
= get_count();
3386 int opt_cnt
= optional_count();
3387 int mand_num
= field_cnt
- opt_cnt
; // expected mandatory fields
3389 raw_order_t local_top_order
;
3390 if (p_td
.raw
->top_bit_order
== TOP_BIT_INHERITED
) local_top_order
= top_bit_ord
;
3391 else if (p_td
.raw
->top_bit_order
== TOP_BIT_RIGHT
) local_top_order
= ORDER_MSB
;
3392 else local_top_order
= ORDER_LSB
;
3394 if (is_set()) { /* set decoder start*/
3395 int prepaddlength
= buff
.increase_pos_padd(p_td
.raw
->prepadding
);
3396 limit
-= prepaddlength
;
3397 int decoded_length
= 0;
3398 int * const field_map
= new int[field_cnt
];
3399 memset(field_map
, 0, field_cnt
* sizeof(int));
3400 int nof_mand_fields
= 0; // mandatory fields actually decoded
3402 const int* optional_indexes
= get_optional_indexes();
3403 for (int i
=0; i
<opt_cnt
; i
++) get_at(optional_indexes
[i
])->set_to_omit();
3406 size_t fl_start_pos
= buff
.get_pos_bit();
3407 int next_optional_idx
= 0;
3408 const int* optional_indexes
= get_optional_indexes();
3409 for (int i
=0; i
<field_cnt
; i
++) { /* decoding fields without TAG */
3410 boolean is_optional_field
= optional_indexes
&& (optional_indexes
[next_optional_idx
]==i
);
3411 if (field_map
[i
] == 0) {
3412 Base_Type
* field_ptr
= get_at(i
);
3413 if (is_optional_field
) {
3414 field_ptr
->set_to_present();
3415 field_ptr
=field_ptr
->get_opt_value();
3417 int decoded_field_length
= field_ptr
->RAW_decode(*fld_descr(i
), buff
,
3418 limit
, local_top_order
, TRUE
);
3419 if ( (is_optional_field
&& (decoded_field_length
>0)) ||
3420 (!is_optional_field
&& (decoded_field_length
>=0)) ) {
3421 decoded_length
+= decoded_field_length
;
3422 limit
-= decoded_field_length
;
3423 if (!is_optional_field
) nof_mand_fields
++;
3425 goto continue_while
;
3427 buff
.set_pos_bit(fl_start_pos
);
3428 if (is_optional_field
) get_at(i
)->set_to_omit();
3431 if (is_optional_field
) next_optional_idx
++;
3433 break; // no field could be decoded successfully, quit
3437 if (mand_num
> 0 && nof_mand_fields
!= mand_num
) {
3438 /* Not all required fields were decoded. If there are no bits left,
3439 * that means that the last field was decoded successfully but used up
3440 * the buffer. Signal "incomplete". If there were bits left, that means
3441 * no field could be decoded from them; signal an error. */
3442 return limit
? -1 : -TTCN_EncDec::ET_INCOMPL_MSG
;
3444 return decoded_length
+ prepaddlength
+ buff
.increase_pos_padd(p_td
.raw
->padding
);
3445 } else { /* record decoder start */
3446 int prepaddlength
= buff
.increase_pos_padd(p_td
.raw
->prepadding
);
3447 limit
-= prepaddlength
;
3448 size_t last_decoded_pos
= buff
.get_pos_bit();
3449 size_t fl_start_pos
;
3450 int decoded_length
= 0;
3451 int decoded_field_length
= 0;
3452 if (raw_has_ext_bit()) {
3453 const unsigned char* data
=buff
.get_read_data();
3455 unsigned mask
= 1 << (local_top_order
==ORDER_LSB
? 0 : 7);
3456 if (p_td
.raw
->extension_bit
==EXT_BIT_YES
) {
3457 while((data
[count
-1] & mask
) == 0 && count
* 8 < (int)limit
) count
++;
3460 while((data
[count
-1] & mask
) != 0 && count
* 8 < (int)limit
) count
++;
3462 if(limit
) limit
=count
*8;
3465 int next_optional_idx
= 0;
3466 const int* optional_indexes
= get_optional_indexes();
3467 for (int i
=0; i
<field_cnt
; i
++) { /* decoding fields */
3468 boolean is_optional_field
= optional_indexes
&& (optional_indexes
[next_optional_idx
]==i
);
3469 /* check if enough bits to decode the field*/
3470 if (!is_optional_field
|| (limit
>0)) {
3471 /* decoding of normal field */
3472 fl_start_pos
= buff
.get_pos_bit();
3473 Base_Type
* field_ptr
= get_at(i
);
3474 if (is_optional_field
) {
3475 field_ptr
->set_to_present();
3476 field_ptr
=field_ptr
->get_opt_value();
3478 decoded_field_length
= field_ptr
->RAW_decode(*fld_descr(i
), buff
, limit
,
3479 local_top_order
, is_optional_field
? TRUE
: no_err
);
3480 boolean field_present
= TRUE
;
3481 if (is_optional_field
) {
3482 if (decoded_field_length
< 1) { // swallow any error and become omit
3483 field_present
= FALSE
;
3484 get_at(i
)->set_to_omit();
3485 buff
.set_pos_bit(fl_start_pos
);
3488 if (decoded_field_length
< 0) return decoded_field_length
;
3490 if (field_present
) {
3491 decoded_length
+=decoded_field_length
;
3492 limit
-=decoded_field_length
;
3493 last_decoded_pos
=last_decoded_pos
<buff
.get_pos_bit()?buff
.get_pos_bit():last_decoded_pos
;
3496 get_at(i
)->set_to_omit();
3498 if (is_optional_field
) next_optional_idx
++;
3499 } /* decoding fields*/
3501 buff
.set_pos_bit(last_decoded_pos
);
3502 return decoded_length
+prepaddlength
+buff
.increase_pos_padd(p_td
.raw
->padding
);
3503 } /* record decoder end*/
3506 int Record_Type::TEXT_encode(const TTCN_Typedescriptor_t
& p_td
, TTCN_Buffer
& buff
) const
3509 return TEXT_encode_negtest(err_descr
, p_td
, buff
);
3512 TTCN_EncDec_ErrorContext::error
3513 (TTCN_EncDec::ET_UNBOUND
, "Encoding an unbound value.");
3515 bool need_separator
=false;
3516 int encoded_length
=0;
3517 if (p_td
.text
->begin_encode
) {
3518 buff
.put_cs(*p_td
.text
->begin_encode
);
3519 encoded_length
+=p_td
.text
->begin_encode
->lengthof();
3521 int next_optional_idx
= 0;
3522 const int* optional_indexes
= get_optional_indexes();
3523 int field_cnt
= get_count();
3524 for(int i
=0;i
<field_cnt
;i
++) {
3525 boolean is_optional_field
= optional_indexes
&& (optional_indexes
[next_optional_idx
]==i
);
3526 if (!is_optional_field
|| get_at(i
)->ispresent()) {
3527 if (need_separator
&& p_td
.text
->separator_encode
) {
3528 buff
.put_cs(*p_td
.text
->separator_encode
);
3529 encoded_length
+=p_td
.text
->separator_encode
->lengthof();
3531 encoded_length
+= get_at(i
)->TEXT_encode(*fld_descr(i
),buff
);
3532 need_separator
=true;
3534 if (is_optional_field
) next_optional_idx
++;
3536 if (p_td
.text
->end_encode
) {
3537 buff
.put_cs(*p_td
.text
->end_encode
);
3538 encoded_length
+=p_td
.text
->end_encode
->lengthof();
3540 return encoded_length
;
3544 * TEXT encode negative testing
3546 int Record_Type::TEXT_encode_negtest(const Erroneous_descriptor_t
* p_err_descr
, const TTCN_Typedescriptor_t
& p_td
, TTCN_Buffer
& buff
) const
3549 TTCN_EncDec_ErrorContext::error
3550 (TTCN_EncDec::ET_UNBOUND
, "Encoding an unbound value.");
3552 bool need_separator
=false;
3553 int encoded_length
=0;
3554 if (p_td
.text
->begin_encode
) {
3555 buff
.put_cs(*p_td
.text
->begin_encode
);
3556 encoded_length
+=p_td
.text
->begin_encode
->lengthof();
3558 int next_optional_idx
= 0;
3559 const int* optional_indexes
= get_optional_indexes();
3560 int field_cnt
= get_count();
3565 for(int i
=0;i
<field_cnt
;i
++) {
3566 boolean is_optional_field
= optional_indexes
&& (optional_indexes
[next_optional_idx
]==i
);
3568 if ( (p_err_descr
->omit_before
!=-1) && (i
<p_err_descr
->omit_before
) ) {
3569 if (is_optional_field
) next_optional_idx
++;
3573 const Erroneous_values_t
* err_vals
= p_err_descr
->next_field_err_values(i
, values_idx
);
3574 const Erroneous_descriptor_t
* emb_descr
= p_err_descr
->next_field_emb_descr(i
, edescr_idx
);
3576 if (err_vals
&& err_vals
->before
) {
3577 if (err_vals
->before
->errval
==NULL
) TTCN_error(
3578 "internal error: erroneous before value missing");
3580 if (need_separator
&& p_td
.text
->separator_encode
) {
3581 buff
.put_cs(*p_td
.text
->separator_encode
);
3582 encoded_length
+=p_td
.text
->separator_encode
->lengthof();
3584 if (err_vals
->before
->raw
) {
3585 encoded_length
+= err_vals
->before
->errval
->encode_raw(buff
);
3587 if (err_vals
->before
->type_descr
==NULL
) TTCN_error(
3588 "internal error: erroneous before typedescriptor missing");
3589 encoded_length
+= err_vals
->before
->errval
->TEXT_encode(
3590 *(err_vals
->before
->type_descr
),buff
);
3592 need_separator
=true;
3595 if (err_vals
&& err_vals
->value
) {
3596 if (err_vals
->value
->errval
) {
3597 if (need_separator
&& p_td
.text
->separator_encode
) {
3598 buff
.put_cs(*p_td
.text
->separator_encode
);
3599 encoded_length
+=p_td
.text
->separator_encode
->lengthof();
3601 if (err_vals
->value
->raw
) {
3602 encoded_length
+= err_vals
->value
->errval
->encode_raw(buff
);
3604 if (err_vals
->value
->type_descr
==NULL
) TTCN_error(
3605 "internal error: erroneous value typedescriptor missing");
3606 encoded_length
+= err_vals
->value
->errval
->TEXT_encode(
3607 *(err_vals
->value
->type_descr
),buff
);
3609 need_separator
=true;
3612 if (!is_optional_field
|| get_at(i
)->ispresent()) {
3613 if (need_separator
&& p_td
.text
->separator_encode
) {
3614 buff
.put_cs(*p_td
.text
->separator_encode
);
3615 encoded_length
+=p_td
.text
->separator_encode
->lengthof();
3618 encoded_length
+= get_at(i
)->TEXT_encode_negtest(emb_descr
, *fld_descr(i
),buff
);
3620 encoded_length
+= get_at(i
)->TEXT_encode(*fld_descr(i
),buff
);
3622 need_separator
=true;
3626 if (err_vals
&& err_vals
->after
) {
3627 if (err_vals
->after
->errval
==NULL
) TTCN_error(
3628 "internal error: erroneous after value missing");
3629 if (need_separator
&& p_td
.text
->separator_encode
) {
3630 buff
.put_cs(*p_td
.text
->separator_encode
);
3631 encoded_length
+=p_td
.text
->separator_encode
->lengthof();
3633 if (err_vals
->after
->raw
) {
3634 encoded_length
+= err_vals
->after
->errval
->encode_raw(buff
);
3636 if (err_vals
->after
->type_descr
==NULL
) TTCN_error(
3637 "internal error: erroneous after typedescriptor missing");
3638 encoded_length
+= err_vals
->after
->errval
->TEXT_encode(
3639 *(err_vals
->after
->type_descr
),buff
);
3641 need_separator
=true;
3644 if (is_optional_field
) next_optional_idx
++;
3646 if ( (p_err_descr
->omit_after
!=-1) && (i
>=p_err_descr
->omit_after
) ) break;
3648 if (p_td
.text
->end_encode
) {
3649 buff
.put_cs(*p_td
.text
->end_encode
);
3650 encoded_length
+=p_td
.text
->end_encode
->lengthof();
3652 return encoded_length
;
3655 int Record_Type::TEXT_decode(const TTCN_Typedescriptor_t
& p_td
, TTCN_Buffer
& buff
,
3656 Limit_Token_List
& limit
, boolean no_err
, boolean
/*first_call*/)
3659 int decoded_length
=0;
3660 int decoded_field_length
=0;
3661 size_t pos
=buff
.get_pos();
3662 boolean sep_found
=FALSE
;
3665 int loop_detector
=1;
3666 int last_field_num
=-1;
3667 if (p_td
.text
->begin_decode
) {
3669 if ((tl
=p_td
.text
->begin_decode
->match_begin(buff
))<0) {
3670 if(no_err
) return -1;
3671 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR
,
3672 "The specified token '%s' not found for '%s': ",
3673 (const char*)*(p_td
.text
->begin_decode
), p_td
.name
);
3677 buff
.increase_pos(tl
);
3679 if (p_td
.text
->end_decode
) {
3680 limit
.add_token(p_td
.text
->end_decode
);
3683 if(p_td
.text
->separator_decode
){
3684 limit
.add_token(p_td
.text
->separator_decode
);
3688 int field_cnt
= get_count();
3689 int * const field_map
= new int[field_cnt
];
3690 memset(field_map
, 0, field_cnt
* sizeof(int));
3692 int mand_field_num
= 0;
3693 int opt_field_num
= 0;
3695 int has_repeatable
=0;
3696 boolean repeatable
= TRUE
;
3698 int next_optional_idx
= 0;
3699 const int* optional_indexes
= get_optional_indexes();
3700 for (int i
=0;i
<field_cnt
;i
++) {
3701 boolean is_optional_field
= optional_indexes
&& (optional_indexes
[next_optional_idx
]==i
);
3702 if (is_optional_field
) {
3703 get_at(i
)->set_to_omit();
3708 if (get_at(i
)->is_seof()) {
3710 repeatable
= repeatable
&& fld_descr(i
)->text
->val
.parameters
->decoding_params
.repeatable
;
3712 if (is_optional_field
) next_optional_idx
++;
3714 boolean has_optinals
= opt_field_num
> 0;
3715 if ((seof
>0) && repeatable
) has_repeatable
=1;
3717 while (mand_field_num
+opt_field_num
+has_repeatable
) {
3721 next_optional_idx
= 0;
3722 for (int i
=0;i
<field_cnt
;i
++) {
3723 boolean is_optional_field
= optional_indexes
&& (optional_indexes
[next_optional_idx
]==i
);
3724 if (get_at(i
)->is_seof()) {
3725 if ( (fld_descr(i
)->text
->val
.parameters
->decoding_params
.repeatable
&& field_map
[i
]<3)
3726 || !field_map
[i
] ) {
3728 decoded_field_length
= get_at(i
)->TEXT_decode(*fld_descr(i
),buff
, limit
, true,!field_map
[i
]);
3729 if (decoded_field_length
<0) {
3731 if (is_optional_field
&& !field_map
[i
]) get_at(i
)->set_to_omit();
3734 if (!field_map
[i
]) {
3735 if (is_optional_field
) opt_field_num
--;
3736 else mand_field_num
--;
3738 } else field_map
[i
]=2;
3743 } else { // !...->is_seof
3744 if (!field_map
[i
]) {
3746 decoded_field_length
= get_at(i
)->TEXT_decode(*fld_descr(i
),buff
,limit
,true);
3747 if (decoded_field_length
<0) {
3749 if (is_optional_field
) get_at(i
)->set_to_omit();
3753 if (is_optional_field
) opt_field_num
--;
3754 else mand_field_num
--;
3760 if (is_optional_field
) next_optional_idx
++;
3764 if (loop_detector
) break;
3765 if (p_td
.text
->separator_decode
) {
3767 if ((tl
=p_td
.text
->separator_decode
->match_begin(buff
))<0) {
3768 if (p_td
.text
->end_decode
) {
3770 if ((tl2
=p_td
.text
->end_decode
->match_begin(buff
))!=-1) {
3774 } else if (limit
.has_token(ml
)) {
3776 if ((tl2
=limit
.match(buff
,ml
))==0) {
3782 decoded_length
-=decoded_field_length
;
3783 field_map
[last_field_num
]+=2;
3786 if (last_field_num
>=0 && last_field_num
<field_cnt
) {
3787 if (get_at(last_field_num
)->is_seof()) {
3788 if (get_at(last_field_num
)->is_optional()) {
3789 if (field_map
[last_field_num
]==3) {
3790 get_at(last_field_num
)->set_to_omit();
3794 if (field_map
[last_field_num
]==3) {
3798 } else if (get_at(last_field_num
)->is_optional()) {
3799 get_at(last_field_num
)->set_to_omit();
3807 } // if (has_optinals)
3811 buff
.increase_pos(tl
);
3812 for (int a
=0;a
<field_cnt
;a
++) if(field_map
[a
]>2) field_map
[a
]-=3;
3815 } else if (p_td
.text
->end_decode
) {
3817 if ((tl
=p_td
.text
->end_decode
->match_begin(buff
))!=-1) {
3819 buff
.increase_pos(tl
);
3820 limit
.remove_tokens(ml
);
3821 if (mand_field_num
) decoded_length
= -1;
3824 } else if(limit
.has_token(ml
)){
3826 if ((tl
=limit
.match(buff
,ml
))==0) {
3832 limit
.remove_tokens(ml
);
3834 if (mand_field_num
) {
3835 if (no_err
) decoded_length
= -1;
3836 else TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR
,
3837 "Error during decoding '%s': ", p_td
.name
);
3840 decoded_length
-=sep_length
;
3841 buff
.set_pos(buff
.get_pos()-sep_length
);
3844 if (p_td
.text
->end_decode
) {
3846 if ((tl
=p_td
.text
->end_decode
->match_begin(buff
))<0) {
3847 if (no_err
) decoded_length
= -1;
3848 else TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR
,
3849 "The specified token '%s' not found for '%s': ",
3850 (const char*)*(p_td
.text
->end_decode
),p_td
.name
);
3854 buff
.increase_pos(tl
);
3856 if (mand_field_num
) decoded_length
= -1;
3859 return decoded_length
;
3860 } else { // record decoder
3861 int decoded_length
=0;
3862 int decoded_field_length
=0;
3863 size_t pos
=buff
.get_pos();
3864 boolean sep_found
=FALSE
;
3867 if (p_td
.text
->begin_decode
) {
3869 if ((tl
=p_td
.text
->begin_decode
->match_begin(buff
))<0) {
3870 if(no_err
)return -1;
3871 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR
,
3872 "The specified token '%s' not found for '%s': ",
3873 (const char*)*(p_td
.text
->begin_decode
), p_td
.name
);
3877 buff
.increase_pos(tl
);
3879 if (p_td
.text
->end_decode
) {
3880 limit
.add_token(p_td
.text
->end_decode
);
3883 if (p_td
.text
->separator_decode
) {
3884 limit
.add_token(p_td
.text
->separator_decode
);
3888 int mand_field_num
= 0;
3889 int opt_field_num
= 0;
3890 int last_man_index
= 0;
3892 int field_cnt
= get_count();
3893 int next_optional_idx
= 0;
3894 const int* optional_indexes
= get_optional_indexes();
3895 for (int i
=0;i
<field_cnt
;i
++) {
3896 boolean is_optional_field
= optional_indexes
&& (optional_indexes
[next_optional_idx
]==i
);
3897 if (is_optional_field
) {
3898 get_at(i
)->set_to_omit();
3904 if (is_optional_field
) next_optional_idx
++;
3907 next_optional_idx
= 0;
3908 for(int i
=0;i
<field_cnt
;i
++) {
3909 boolean is_optional_field
= optional_indexes
&& (optional_indexes
[next_optional_idx
]==i
);
3910 if (is_optional_field
) {
3913 decoded_field_length
= get_at(i
)->TEXT_decode(*fld_descr(i
),buff
,limit
,TRUE
);
3914 if (decoded_field_length
<0) {
3915 if (is_optional_field
) {
3916 get_at(i
)->set_to_omit();
3919 limit
.remove_tokens(ml
);
3920 if (no_err
) return -1;
3921 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR
,
3922 "Error during decoding field '%s' for '%s': ",
3923 fld_descr(i
)->name
, p_td
.name
);
3924 return decoded_length
;
3927 decoded_length
+=decoded_field_length
;
3928 if (last_man_index
>(i
+1)) {
3929 if (p_td
.text
->separator_decode
) {
3931 if ((tl
=p_td
.text
->separator_decode
->match_begin(buff
))<0) {
3932 if(is_optional_field
) {
3933 get_at(i
)->set_to_omit();
3935 decoded_length
-=decoded_field_length
;
3937 limit
.remove_tokens(ml
);
3938 if(no_err
)return -1;
3939 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR
,
3940 "The specified token '%s' not found for '%s': ",
3941 (const char*)*(p_td
.text
->separator_decode
),p_td
.name
);
3942 return decoded_length
;
3946 buff
.increase_pos(tl
);
3950 } else sep_found
=FALSE
;
3952 } else if (i
==(field_cnt
-1)) {
3955 if (p_td
.text
->separator_decode
) {
3957 if ((tl
=p_td
.text
->separator_decode
->match_begin(buff
))<0) {
3958 if (is_optional_field
) {
3959 if (p_td
.text
->end_decode
) {
3960 if ((tl
=p_td
.text
->end_decode
->match_begin(buff
))!=-1) {
3962 buff
.increase_pos(tl
);
3963 limit
.remove_tokens(ml
);
3964 return decoded_length
;
3966 } else if (limit
.has_token(ml
)) {
3967 if ((tl
=limit
.match(buff
,ml
))==0) {
3972 get_at(i
)->set_to_omit();
3974 decoded_length
-=decoded_field_length
;
3981 buff
.increase_pos(tl
);
3988 if (p_td
.text
->end_decode
) {
3989 if ((tl
=p_td
.text
->end_decode
->match_begin(buff
))!=-1) {
3991 buff
.increase_pos(tl
);
3992 limit
.remove_tokens(ml
);
3993 return decoded_length
;
3995 } else if (limit
.has_token(ml
)) {
3996 if ((tl
=limit
.match(buff
,ml
))==0) {
4004 if (is_optional_field
) next_optional_idx
++;
4006 limit
.remove_tokens(ml
);
4008 buff
.set_pos(buff
.get_pos()-sep_length
);
4009 decoded_length
-=sep_length
;
4011 if (p_td
.text
->end_decode
) {
4013 if ((tl
=p_td
.text
->end_decode
->match_begin(buff
))<0) {
4014 if(no_err
)return -1;
4015 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR
,
4016 "The specified token '%s' not found for '%s': ",
4017 (const char*)*(p_td
.text
->end_decode
),p_td
.name
);
4018 return decoded_length
;
4021 buff
.increase_pos(tl
);
4023 return decoded_length
;
4027 const XERdescriptor_t
* Record_Type::xer_descr(int /*field_index*/) const
4029 TTCN_error("Internal error: Record_Type::xer_descr() called.");
4033 char ** Record_Type::collect_ns(const XERdescriptor_t
& p_td
, size_t& num
, bool& def_ns
) const
4035 const int field_cnt
= get_count();
4036 // The USE-ORDER member is first, unless preempted by EMBED-VALUES
4037 const int uo_index
= ((p_td
.xer_bits
& EMBED_VALUES
) !=0);
4038 // Index of the first "normal" member (after E-V and U-O)
4039 const int start_at
= uo_index
+ ((p_td
.xer_bits
& USE_ORDER
) != 0);
4041 size_t num_collected
= 0;
4042 // First, our own namespace. Sets num_collected to 0 or 1.
4043 // If it throws, nothing was allocated.
4044 char **collected_ns
= Base_Type::collect_ns(p_td
, num_collected
, def_ns
);
4047 // If the nil attribute will be written, add the control namespace
4048 boolean nil_attribute
= (p_td
.xer_bits
& USE_NIL
)
4049 && !get_at(field_cnt
-1)->ispresent();
4051 if (nil_attribute
) {
4052 collected_ns
= (char**)Realloc(collected_ns
, sizeof(char*) * ++num_collected
);
4053 const namespace_t
*c_ns
= p_td
.my_module
->get_controlns();
4055 collected_ns
[num_collected
-1] = mprintf(" xmlns:%s='%s'", c_ns
->px
, c_ns
->ns
);
4058 // Collect namespace declarations from all components (recursively).
4059 // This is extremely nasty, but we can't prosecute you for that.
4060 // (Monty Python - Crunchy Frog sketch). This whole thing is O(n^3). Yuck.
4061 for (int a
= start_at
; a
< field_cnt
; ++a
) {
4063 bool def_ns_1
= false;
4064 char **new_namespaces
= get_at(a
)->collect_ns(*xer_descr(a
), num_new
, def_ns_1
);
4065 merge_ns(collected_ns
, num_collected
, new_namespaces
, num_new
);
4066 def_ns
= def_ns
|| def_ns_1
;
4067 // merge_ns freed new_namespaces
4071 // Probably a TC_Error thrown from the element's collect_ns(),
4072 // e.g. if encoding an unbound value.
4073 while (num_collected
> 0) Free(collected_ns
[--num_collected
]);
4078 num
= num_collected
;
4079 return collected_ns
;
4082 // FIXME some hashing should be implemented
4083 int Record_Type::get_index_byname(const char *name
, const char *uri
) const {
4084 int num_fields
= get_count();
4085 for (int i
= 0; i
< num_fields
; ++i
) {
4086 const XERdescriptor_t
& xer
= *xer_descr(i
);
4087 if (check_name(name
, xer
, TRUE
)
4088 && check_namespace(uri
, xer
)) return i
;
4093 int Record_Type::XER_encode(const XERdescriptor_t
& p_td
, TTCN_Buffer
& p_buf
,
4094 unsigned int flavor
, int indent
, embed_values_enc_struct_t
*) const
4097 return XER_encode_negtest(err_descr
, p_td
, p_buf
, flavor
, indent
, 0);
4100 TTCN_EncDec_ErrorContext::error
4101 (TTCN_EncDec::ET_UNBOUND
, "Encoding an unbound value.");
4104 TTCN_EncDec_ErrorContext
ec_0("Component '");
4105 TTCN_EncDec_ErrorContext ec_1
;
4106 int encoded_length
=(int)p_buf
.get_len(); // how much is already in the buffer
4108 int exer
= is_exer(flavor
);
4109 if (exer
&& (p_td
.xer_bits
& EMBED_VALUES
)) flavor
|= XER_CANONICAL
;
4110 const boolean indenting
= !is_canonical(flavor
);
4111 const int field_cnt
= get_count();
4112 const int num_attributes
= get_xer_num_attr();
4113 // The USE-ORDER member is first, unless preempted by EMBED-VALUES
4114 const int uo_index
= ((p_td
.xer_bits
& EMBED_VALUES
) !=0);
4115 // Index of the first "normal" member (after E-V and U-O)
4116 const int start_at
= uo_index
+ ((p_td
.xer_bits
& USE_ORDER
) != 0);
4117 const int first_nonattr
= start_at
+ num_attributes
;
4118 // start_tag_len is keeping track of how much was written at the end of the
4119 // start tag, i.e. the ">\n". This is used later to "back up" over it.
4120 int start_tag_len
= 1 + indenting
;
4121 // The EMBED-VALUES member, if applicable
4122 const Record_Of_Type
* embed_values
= 0;
4123 if (p_td
.xer_bits
& EMBED_VALUES
) {
4124 embed_values
= dynamic_cast<const Record_Of_Type
*>(get_at(0));
4125 if (NULL
== embed_values
) {
4126 const OPTIONAL
<Record_Of_Type
>* const embed_opt
= static_cast<const OPTIONAL
<Record_Of_Type
>*>(get_at(0));
4127 if(embed_opt
->is_present()) {
4128 embed_values
= &(*embed_opt
)();
4132 // The USE-ORDER member, if applicable
4133 const Record_Of_Type
* const use_order
= (p_td
.xer_bits
& USE_ORDER
)
4134 ? static_cast<const Record_Of_Type
*>(get_at(uo_index
)) : 0;
4136 size_t num_collected
= 0; // we use this to compute delay_close
4137 char **collected_ns
= NULL
;
4138 bool def_ns
= false;
4140 if (indent
== 0) { // top-level type
4141 collected_ns
= collect_ns(p_td
, num_collected
, def_ns
);
4143 else if ((flavor
& DEF_NS_SQUASHED
) && p_td
.my_module
&& p_td
.ns_index
!= -1) {
4144 const namespace_t
* ns
= p_td
.my_module
->get_ns(p_td
.ns_index
);
4145 // The default namespace has been squashed.
4146 // If we are in the default namespace, restore it.
4147 if (*ns
->px
== '\0') {
4148 collected_ns
= Base_Type::collect_ns(p_td
, num_collected
, def_ns
);
4153 // The type's own tag is omitted if we're doing E-XER,
4154 // and it's not the top-level type (XML must have a root element)
4155 // and it's either UNTAGGED or got USE_NIL or USE_TYPE or USE_UNION.
4156 boolean omit_tag
= exer
&& (indent
> 0)
4157 && ( (p_td
.xer_bits
& (UNTAGGED
|XER_ATTRIBUTE
))
4158 || (flavor
& (USE_NIL
|USE_TYPE_ATTR
)));
4160 // If a default namespace is in effect (uri but no prefix) and the type
4161 // is unqualified, the default namespace must be canceled; otherwise
4162 // an XML tag without a ns prefix looks like it belongs to the def.namespace
4163 const boolean empty_ns_hack
= exer
&& !omit_tag
&& (indent
> 0)
4164 && (p_td
.xer_bits
& FORM_UNQUALIFIED
)
4165 && (flavor
& DEF_NS_PRESENT
);
4167 // delay_close=true if there is stuff before the '>' of the start tag
4168 // (prevents writing the '>' which is built into the name).
4169 // This can only happen for EXER: if there are attributes or namespaces,
4170 // or either USE-NIL or USE-QNAME is set.
4171 boolean delay_close
= exer
&& (num_attributes
4172 || empty_ns_hack
// counts as having a namespace
4173 || (num_collected
!= 0)
4174 || (p_td
.xer_bits
& (USE_NIL
|USE_QNAME
))
4175 || (flavor
& USE_NIL
));
4179 if (!omit_tag
) { /* write start tag */
4180 if (indenting
) do_indent(p_buf
, indent
);
4181 /* name looks like this: "tagname>\n"
4182 * lose the \n if : not indenting or (single untagged(*) or attributes (*)) AND exer
4183 * lose the > if attributes are present (*) AND exer
4186 if (exer
) write_ns_prefix(p_td
, p_buf
);
4187 p_buf
.put_s((size_t)p_td
.namelens
[exer
] - delay_close
4188 - (!indenting
|| delay_close
|| (exer
&& (p_td
.xer_bits
& HAS_1UNTAGGED
))),
4189 (cbyte
*)p_td
.names
[exer
]);
4191 else if (flavor
& (USE_NIL
|USE_TYPE_ATTR
)) {
4192 // reopen the parent's start tag by overwriting the '>'
4193 size_t buf_len
= p_buf
.get_len();
4194 const unsigned char * const buf_data
= p_buf
.get_data();
4195 if (buf_data
[buf_len
- 1 - shorter
] == '\n') ++shorter
;
4196 if (buf_data
[buf_len
- 1 - shorter
] == '>' ) ++shorter
;
4199 p_buf
.increase_length(-shorter
);
4205 // mask out extra flags we received, do not send them to the fields
4208 if (exer
&& (p_td
.xer_bits
& USE_QNAME
)) { // QName trumps everything
4209 const Base_Type
* const q_uri
= get_at(0);
4210 if (q_uri
->is_present()) {
4211 p_buf
.put_s(11, (cbyte
*)" xmlns:b0='");
4212 q_uri
->XER_encode(*xer_descr(0), p_buf
, flavor
| XER_LIST
, indent
+1, 0);
4216 if (p_td
.xer_bits
& XER_ATTRIBUTE
) begin_attribute(p_td
, p_buf
);
4217 else p_buf
.put_c('>');
4219 if (q_uri
->is_present()) {
4220 p_buf
.put_s(3, (cbyte
*)"b0:");
4223 const Base_Type
* const q_name
= get_at(1);
4224 sub_len
+= q_name
->XER_encode(*xer_descr(1), p_buf
, flavor
| XER_LIST
, indent
+1, 0);
4225 if (p_td
.xer_bits
& XER_ATTRIBUTE
) p_buf
.put_c('\'');
4227 else { // not USE-QNAME
4228 if (!exer
&& (p_td
.xer_bits
& EMBED_VALUES
) && embed_values
!= NULL
) {
4229 // The EMBED-VALUES member as an ordinary record of string
4230 sub_len
+= embed_values
->XER_encode(*xer_descr(0), p_buf
, flavor
, indent
+1, 0);
4233 if (!exer
&& (p_td
.xer_bits
& USE_ORDER
)) {
4234 // The USE-ORDER member as an ordinary record of enumerated
4235 sub_len
+= use_order
->XER_encode(*xer_descr(uo_index
), p_buf
, flavor
, indent
+1, 0);
4238 if (exer
&& (indent
==0 || (flavor
& DEF_NS_SQUASHED
))) // write namespaces for toplevel only
4240 for (size_t cur_coll
= 0; cur_coll
< num_collected
; ++cur_coll
) {
4241 p_buf
.put_s(strlen(collected_ns
[cur_coll
]), (cbyte
*)collected_ns
[cur_coll
]);
4242 Free(collected_ns
[cur_coll
]); // job done
4248 flavor
&= ~DEF_NS_SQUASHED
;
4249 flavor
|= DEF_NS_PRESENT
;
4251 else if (empty_ns_hack
) {
4252 p_buf
.put_s(9, (cbyte
*)" xmlns=''");
4253 flavor
&= ~DEF_NS_PRESENT
;
4254 flavor
|= DEF_NS_SQUASHED
;
4257 /* First all the attributes (not added to sub_len) */
4259 for (i
= start_at
; i
< first_nonattr
; ++i
) {
4260 boolean is_xer_attr_field
= xer_descr(i
)->xer_bits
& XER_ATTRIBUTE
;
4261 ec_1
.set_msg("%s': ", fld_name(i
)); // attr
4262 int tmp_len
= get_at(i
)->XER_encode(*xer_descr(i
), p_buf
, flavor
, indent
+1, 0);
4263 if (is_xer_attr_field
&& !exer
) sub_len
+= tmp_len
; /* do not add if attribute and EXER */
4266 // True if the "nil" attribute needs to be written.
4267 boolean nil_attribute
= exer
&& (p_td
.xer_bits
& USE_NIL
)
4268 && !get_at(field_cnt
-1)->ispresent();
4270 // True if USE_ORDER is in effect and the "nil" attribute was written.
4271 // Then the record-of-enum for USE-ORDER will be empty.
4272 boolean early_to_bed
= FALSE
;
4274 if (nil_attribute
) { // req. exer and USE_NIL
4275 const namespace_t
*control_ns
= p_td
.my_module
->get_controlns();
4277 p_buf
.put_s(strlen(control_ns
->px
),
4278 (cbyte
*)control_ns
->px
);
4280 p_buf
.put_s(10, (cbyte
*)"nil='true'");
4281 if ((p_td
.xer_bits
& USE_ORDER
)) early_to_bed
= TRUE
;
4282 // The whole content was omitted; nothing to do (and if we tried
4283 // to do it, we'd get an error for over-indexing a 0-length record-of).
4286 if (delay_close
&& (!omit_tag
|| shorter
)) {
4287 // Close the start tag left open. If indenting, also write a newline
4288 // unless USE-NIL in effect or there is a single untagged component.
4290 ((p_td
.xer_bits
& (/*USE_NIL|*/HAS_1UNTAGGED
)) ? 0 : indenting
);
4291 p_buf
.put_s(start_tag_len
, (cbyte
*)">\n");
4294 if (exer
&& (p_td
.xer_bits
& EMBED_VALUES
)) {
4295 /* write the first string */
4296 if (embed_values
!= NULL
&& embed_values
->size_of() > 0) {
4297 sub_len
+= embed_values
->get_at(0)->XER_encode(UNIVERSAL_CHARSTRING_xer_
,
4298 p_buf
, flavor
| EMBED_VALUES
, indent
+1, 0);
4302 const Record_Type
*ordered
= this; // the record affected by USE-ORDER
4304 // Index of the first non-attribute field of the record pointed to by
4305 // ordered, that is, the first field affected by USE-ORDER.
4306 size_t useorder_base
= first_nonattr
;
4309 int end
= field_cnt
;
4310 if (exer
&& (p_td
.xer_bits
& USE_ORDER
)) {
4311 const int to_send
= use_order
->size_of();
4312 // the length of the loop is determined by the length of use_order
4316 // Count the non-attribute optionals
4317 int n_optionals
= 0;
4318 for (int B
= optional_count() - 1; B
>=+0; B
--) {
4319 int oi
= get_optional_indexes()[B
];
4320 if (oi
< first_nonattr
) break;
4324 int expected_max
= field_cnt
- first_nonattr
;
4325 int expected_min
= expected_max
- n_optionals
;
4327 if ((p_td
.xer_bits
& USE_NIL
) && get_at(field_cnt
-1)->ispresent()) {
4328 // The special case when USE_ORDER refers to the fields of a field,
4330 const Base_Type
*last_optional
= get_at(field_cnt
-1);
4331 const Base_Type
* inner
= last_optional
->get_opt_value();
4332 // it absolutely, positively has to be (derived from) Record_Type
4333 ordered
= static_cast<const Record_Type
*>(inner
);
4334 useorder_base
= ordered
->get_xer_num_attr();
4335 begin
= useorder_base
;
4336 end
= ordered
->get_count();
4338 expected_min
= expected_max
= ordered
->get_count();
4341 if (to_send
> expected_max
4342 ||to_send
< expected_min
) {
4343 ec_1
.set_msg("%s': ", fld_name(uo_index
));
4344 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_CONSTRAINT
,
4345 "Wrong number of USE-ORDER %d, must be %d..%d", to_send
, expected_min
, expected_max
);
4346 begin
= end
= 0; // don't bother sending anything
4348 else { // check no duplicates
4349 int *seen
= new int [to_send
];
4351 for (int ei
= 0; ei
< to_send
; ++ei
) {
4352 const Base_Type
*uoe
= use_order
->get_at(ei
);
4353 const Enum_Type
*enm
= static_cast<const Enum_Type
*>(uoe
);
4354 int val
= enm
->as_int();
4355 for (int x
= 0; x
< num_seen
; ++x
) {
4356 if (val
== seen
[x
]) { // complain
4357 ec_1
.set_msg("%s': ", fld_name(uo_index
));
4358 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_CONSTRAINT
,
4359 "Duplicate value for USE-ORDER");
4360 begin
= end
= 0; // don't bother sending anything
4364 seen
[num_seen
++] = val
;
4368 // If the number is right and there are no duplicates, then carry on
4372 /* Then, all the non-attributes. Structuring the code like this depends on
4373 * all attributes appearing before all non-attributes (excluding
4374 * pseudo-members for USE-ORDER, etc.) */
4376 // early_to_bed can only be true if exer is true (transitive through nil_attribute)
4377 if (!early_to_bed
) {
4378 embed_values_enc_struct_t
* emb_val
= 0;
4379 if (exer
&& (p_td
.xer_bits
& EMBED_VALUES
) &&
4380 embed_values
!= NULL
&& embed_values
->size_of() > 1) {
4381 emb_val
= new embed_values_enc_struct_t
;
4382 emb_val
->embval_array
= embed_values
;
4383 emb_val
->embval_index
= 1;
4384 emb_val
->embval_err
= 0;
4387 for ( i
= begin
; i
< end
; ++i
) {
4388 const Base_Type
*uoe
= 0; // "useOrder enum"
4389 const Enum_Type
*enm
= 0; // the enum value selecting the field
4390 if (exer
&& use_order
) {
4391 uoe
= use_order
->get_at(i
- begin
);
4392 enm
= static_cast<const Enum_Type
*>(uoe
);
4395 // "actual" index, may be perturbed by USE-ORDER
4396 int ai
= !(exer
&& (p_td
.xer_bits
& USE_ORDER
)) ? i
:
4397 enm
->as_int() + useorder_base
;
4398 ec_1
.set_msg("%s': ", ordered
->fld_name(ai
)); // non-attr
4400 const XERdescriptor_t
& descr
= *ordered
->xer_descr(ai
);
4401 sub_len
+= ordered
->get_at(ai
)->XER_encode(descr
, p_buf
,
4402 // Pass USE-NIL to the last field (except when USE-ORDER is also in effect,
4403 // because the tag-stripping effect of USE-NIL has been achieved
4404 // by encoding the sub-fields directly).
4405 flavor
| ((exer
&& !use_order
&& (i
== field_cnt
-1)) ? (p_td
.xer_bits
& USE_NIL
) : 0),
4406 indent
+!omit_tag
, emb_val
);
4408 // Now the next embed-values string (NOT affected by USE-ORDER!)
4409 if (exer
&& (p_td
.xer_bits
& EMBED_VALUES
) && 0 != emb_val
&&
4410 embed_values
!= NULL
&& emb_val
->embval_index
< embed_values
->size_of()) {
4411 embed_values
->get_at(emb_val
->embval_index
)->XER_encode(UNIVERSAL_CHARSTRING_xer_
4412 , p_buf
, flavor
| EMBED_VALUES
, indent
+1, 0);
4413 ++emb_val
->embval_index
;
4418 if (embed_values
!= NULL
&& emb_val
->embval_index
< embed_values
->size_of()) {
4419 ec_1
.set_msg("%s': ", fld_name(0));
4420 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_CONSTRAINT
,
4421 "Too many EMBED-VALUEs specified: %d (expected %d or less)",
4422 embed_values
->size_of(), emb_val
->embval_index
);
4426 } // if (!early_to_bed)
4430 if (sub_len
) { // something was written, now an end tag
4431 if (indenting
&& !(exer
&& (p_td
.xer_bits
& (HAS_1UNTAGGED
| USE_QNAME
)))) {
4432 // The tags of the last optional member involved with USE_NIL
4433 // have been removed. If it was a simple type, the content was probably
4434 // written on a single line without anything resembling a close tag.
4435 // Do not indent our end tag in this case.
4436 switch ((int)(exer
&& (p_td
.xer_bits
& USE_NIL
))) {
4438 const unsigned char *buf_end
= p_buf
.get_data() + (p_buf
.get_len()-1);
4439 if (buf_end
[-1] != '>' || *buf_end
!= '\n') break;
4440 // If it does not look like an end tag, skip the indenting,
4441 // else fall through.
4444 do_indent(p_buf
, indent
);
4450 if (exer
) write_ns_prefix(p_td
, p_buf
);
4451 p_buf
.put_s((size_t)p_td
.namelens
[exer
]-!indenting
, (cbyte
*)p_td
.names
[exer
]);
4453 else { // need to generate an empty element tag
4454 p_buf
.increase_length(-start_tag_len
); // decrease length
4455 p_buf
.put_s((size_t)2+indenting
, (cbyte
*)"/>\n");
4459 return (int)p_buf
.get_len() - encoded_length
;
4462 // XERSTUFF Record_Type::encode_field
4463 /** Helper for Record_Type::XER_encode_negtest
4465 * Factored out because Record_Type::XER_encode (on which XER_encode_negtest
4466 * is based) calls the XER_encode method of the field in two places:
4467 * one for attributes, the other for elements.
4469 * @param i index of the field
4470 * @param err_vals erroneous descriptor for the field
4471 * @param emb_descr deeper erroneous values
4472 * @param p_buf buffer containing the encoded value
4473 * @param sub_flavor flags
4474 * @param indent indentation level
4475 * @return the number of bytes generated
4477 int Record_Type::encode_field(int i
,
4478 const Erroneous_values_t
* err_vals
, const Erroneous_descriptor_t
* emb_descr
,
4479 TTCN_Buffer
& p_buf
, unsigned int sub_flavor
, int indent
, embed_values_enc_struct_t
* emb_val
) const
4482 TTCN_EncDec_ErrorContext ec
;
4483 if (err_vals
&& err_vals
->before
) {
4484 if (err_vals
->before
->errval
==NULL
) TTCN_error(
4485 "internal error: erroneous before value missing");
4486 ec
.set_msg("Erroneous value before component %s: ", fld_name(i
));
4487 if (err_vals
->before
->raw
) {
4488 enc_len
+= err_vals
->before
->errval
->encode_raw(p_buf
);
4490 if (err_vals
->before
->type_descr
==NULL
) TTCN_error(
4491 "internal error: erroneous before typedescriptor missing");
4492 enc_len
+= err_vals
->before
->errval
->XER_encode(
4493 *err_vals
->before
->type_descr
->xer
, p_buf
, sub_flavor
, indent
, 0);
4497 if (err_vals
&& err_vals
->value
) {
4498 if (err_vals
->value
->errval
) { // replace
4499 ec
.set_msg("Erroneous value for component %s: ", fld_name(i
));
4500 if (err_vals
->value
->raw
) {
4501 enc_len
+= err_vals
->value
->errval
->encode_raw(p_buf
);
4503 if (err_vals
->value
->type_descr
==NULL
) TTCN_error(
4504 "internal error: erroneous value typedescriptor missing");
4505 enc_len
+= err_vals
->value
->errval
->XER_encode(
4506 *err_vals
->value
->type_descr
->xer
, p_buf
, sub_flavor
, indent
, 0);
4510 ec
.set_msg("Component %s: ", fld_name(i
));
4512 enc_len
+= get_at(i
)->XER_encode_negtest(emb_descr
, *xer_descr(i
), p_buf
,
4513 sub_flavor
, indent
, emb_val
);
4515 // the "real" encoder
4516 enc_len
+= get_at(i
)->XER_encode(*xer_descr(i
), p_buf
,
4517 sub_flavor
, indent
, emb_val
);
4521 if (err_vals
&& err_vals
->after
) {
4522 if (err_vals
->after
->errval
==NULL
) TTCN_error(
4523 "internal error: erroneous after value missing");
4524 ec
.set_msg("Erroneous value after component %s: ", fld_name(i
));
4525 if (err_vals
->after
->raw
) {
4526 enc_len
+= err_vals
->after
->errval
->encode_raw(p_buf
);
4528 if (err_vals
->after
->type_descr
==NULL
) TTCN_error(
4529 "internal error: erroneous after typedescriptor missing");
4530 enc_len
+= err_vals
->after
->errval
->XER_encode(
4531 *err_vals
->after
->type_descr
->xer
, p_buf
, sub_flavor
, indent
, 0);
4538 // XERSTUFF Record_Type::XER_encode_negtest
4539 int Record_Type::XER_encode_negtest(const Erroneous_descriptor_t
* p_err_descr
,
4540 const XERdescriptor_t
& p_td
, TTCN_Buffer
& p_buf
, unsigned int flavor
, int indent
,
4541 embed_values_enc_struct_t
*) const
4544 TTCN_EncDec_ErrorContext::error
4545 (TTCN_EncDec::ET_UNBOUND
, "Encoding an unbound value.");
4547 TTCN_EncDec_ErrorContext
ec_0("Component '");
4548 TTCN_EncDec_ErrorContext ec_1
;
4549 int encoded_length
=(int)p_buf
.get_len(); // how much is already in the buffer
4551 int exer
= is_exer(flavor
);
4552 if (exer
&& (p_td
.xer_bits
& EMBED_VALUES
)) flavor
|= XER_CANONICAL
;
4553 const boolean indenting
= !is_canonical(flavor
);
4554 const int field_cnt
= get_count();
4555 const int num_attributes
= get_xer_num_attr();
4556 // The USE-ORDER member is first, unless preempted by EMBED-VALUES
4557 const int uo_index
= ((p_td
.xer_bits
& EMBED_VALUES
) !=0);
4558 // Index of the first "normal" member (after E-V and U-O)
4559 const int start_at
= uo_index
+ ((p_td
.xer_bits
& USE_ORDER
) != 0);
4560 const int first_nonattr
= start_at
+ num_attributes
;
4561 // start_tag_len is keeping track of how much was written at the end of the
4562 // start tag, i.e. the ">\n". This is used later to "back up" over it.
4563 int start_tag_len
= 1 + indenting
;
4564 // The EMBED-VALUES member, if applicable (always first)
4565 const Record_Of_Type
* const embed_values
= (p_td
.xer_bits
& EMBED_VALUES
)
4566 ? static_cast<const Record_Of_Type
*>(get_at(0)) : 0;
4567 // The USE-ORDER member, if applicable (first unless preempted by embed_vals)
4568 const Record_Of_Type
* const use_order
= (p_td
.xer_bits
& USE_ORDER
)
4569 ? static_cast<const Record_Of_Type
*>(get_at(uo_index
)) : 0;
4574 size_t num_collected
= 0; // we use this to compute delay_close
4575 char **collected_ns
= NULL
;
4576 bool def_ns
= false;
4578 if (indent
== 0) { // top-level type
4579 collected_ns
= collect_ns(p_td
, num_collected
, def_ns
);
4581 else if ((flavor
& DEF_NS_SQUASHED
) && p_td
.my_module
&& p_td
.ns_index
!= -1) {
4582 const namespace_t
* ns
= p_td
.my_module
->get_ns(p_td
.ns_index
);
4583 // The default namespace has been squashed.
4584 // If we are in the default namespace, restore it.
4585 if (*ns
->px
== '\0') {
4586 collected_ns
= Base_Type::collect_ns(p_td
, num_collected
, def_ns
);
4591 // The type's own tag is omitted if we're doing E-XER,
4592 // and it's not the top-level type (XML must have a root element)
4593 // and it's either UNTAGGED or got USE_NIL.
4594 boolean omit_tag
= exer
&& indent
4595 && ( (p_td
.xer_bits
& (UNTAGGED
|XER_ATTRIBUTE
))
4596 || (flavor
& (USE_NIL
|USE_TYPE_ATTR
)));
4598 // If a default namespace is in effect (uri but no prefix) and the type
4599 // is unqualified, the default namespace must be canceled; otherwise
4600 // an XML tag without a ns prefix looks like it belongs to the def.namespace
4601 const boolean empty_ns_hack
= exer
&& !omit_tag
&& (indent
> 0)
4602 && (p_td
.xer_bits
& FORM_UNQUALIFIED
)
4603 && (flavor
& DEF_NS_PRESENT
);
4605 // delay_close=true if there is stuff before the '>' of the start tag
4606 // (prevents writing the '>' which is built into the name).
4607 // This can only happen for EXER: if there are attributes or namespaces,
4608 // or either USE-NIL or USE-QNAME is set.
4609 boolean delay_close
= exer
&& (num_attributes
4610 || empty_ns_hack
// counts as having a namespace
4611 || (num_collected
!= 0)
4612 || (p_td
.xer_bits
& (USE_NIL
|USE_QNAME
))
4613 || (flavor
& USE_NIL
));
4616 if (!omit_tag
) { /* write start tag */
4617 if (indenting
) do_indent(p_buf
, indent
);
4618 /* name looks like this: "tagname>\n"
4619 * lose the \n if : not indenting or (single untagged(*) or attributes (*)) AND exer
4620 * lose the > if attributes are present (*) AND exer
4623 if (exer
) write_ns_prefix(p_td
, p_buf
);
4624 p_buf
.put_s((size_t)p_td
.namelens
[exer
] - delay_close
4625 - (!indenting
|| delay_close
|| (exer
&& (p_td
.xer_bits
& HAS_1UNTAGGED
))),
4626 (cbyte
*)p_td
.names
[exer
]);
4628 else if (flavor
& USE_TYPE_ATTR
) {
4629 // reopen the parent's tag
4630 size_t buf_len
= p_buf
.get_len();
4631 const unsigned char * const buf_data
= p_buf
.get_data();
4632 if (buf_data
[buf_len
- 1 - shorter
] == '\n') ++shorter
;
4633 if (buf_data
[buf_len
- 1 - shorter
] == '>' ) ++shorter
;
4636 p_buf
.increase_length(-shorter
);
4641 int sub_len
=0, tmp_len
;
4642 // mask out extra flags we received, do not send them to the fields
4645 if (exer
&& (p_td
.xer_bits
& USE_QNAME
)) {
4646 const Erroneous_values_t
* ev
=
4647 p_err_descr
->next_field_err_values(0, values_idx
);
4648 const Erroneous_descriptor_t
* ed
=
4649 p_err_descr
->next_field_emb_descr (0, edescr_idx
);
4650 // At first, erroneous info for the first component (uri)
4652 TTCN_EncDec_ErrorContext ec
;
4653 const Base_Type
* const q_uri
= get_at(0);
4655 if (ev
&& ev
->before
) {
4656 if (ev
->before
->errval
==NULL
) TTCN_error(
4657 "internal error: erroneous before value missing");
4658 ec
.set_msg("Erroneous value before component #0: ");
4659 if (ev
->before
->raw
) {
4660 sub_len
+= ev
->before
->errval
->encode_raw(p_buf
);
4662 if (ev
->before
->type_descr
==NULL
) TTCN_error(
4663 "internal error: erroneous before typedescriptor missing");
4664 sub_len
+= ev
->before
->errval
->XER_encode(
4665 *ev
->before
->type_descr
->xer
, p_buf
, flavor
, indent
, 0);
4669 if (ev
&& ev
->value
) {
4670 if (ev
->value
->errval
) { // replace
4671 ec
.set_msg("Erroneous value for component #0: ");
4672 if (ev
->value
->raw
) {
4673 sub_len
+= ev
->value
->errval
->encode_raw(p_buf
);
4675 if (ev
->value
->type_descr
==NULL
) TTCN_error(
4676 "internal error: erroneous value typedescriptor missing");
4677 sub_len
+= ev
->value
->errval
->XER_encode(
4678 *ev
->value
->type_descr
->xer
, p_buf
, flavor
, indent
, 0);
4682 ec
.set_msg("Component #0: ");
4684 // universal charstring does not have components.
4685 // TTCN code which could have generated embedded erroneous descriptor
4686 // should have failed semantic analysis.
4687 TTCN_error("internal error: embedded descriptor unexpected");
4689 // the "real" encoder
4690 if (q_uri
->is_present()) {
4691 p_buf
.put_s(11, (cbyte
*)" xmlns:b0='");
4692 sub_len
+= q_uri
->XER_encode(*xer_descr(0), p_buf
, flavor
| XER_LIST
, indent
+1, 0);
4698 if (ev
&& ev
->after
) {
4699 if (ev
->after
->errval
==NULL
) TTCN_error(
4700 "internal error: erroneous after value missing");
4701 ec
.set_msg("Erroneous value after component #0: ");
4702 if (ev
->after
->raw
) {
4703 sub_len
+= ev
->after
->errval
->encode_raw(p_buf
);
4705 if (ev
->after
->type_descr
==NULL
) TTCN_error(
4706 "internal error: erroneous after typedescriptor missing");
4707 sub_len
+= ev
->after
->errval
->XER_encode(
4708 *ev
->after
->type_descr
->xer
, p_buf
, flavor
, indent
, 0);
4712 if (p_td
.xer_bits
& XER_ATTRIBUTE
) begin_attribute(p_td
, p_buf
);
4713 else p_buf
.put_c('>');
4715 // Now switch to the second field (name)
4716 ev
= p_err_descr
->next_field_err_values(1, values_idx
);
4717 ed
= p_err_descr
->next_field_emb_descr (1, edescr_idx
);
4719 if (ev
&& ev
->before
) {
4720 if (ev
->before
->errval
==NULL
) TTCN_error(
4721 "internal error: erroneous before value missing");
4722 ec
.set_msg("Erroneous value before component #1: ");
4723 if (ev
->before
->raw
) {
4724 sub_len
+= ev
->before
->errval
->encode_raw(p_buf
);
4726 if (ev
->before
->type_descr
==NULL
) TTCN_error(
4727 "internal error: erroneous before typedescriptor missing");
4728 sub_len
+= ev
->before
->errval
->XER_encode(
4729 *ev
->before
->type_descr
->xer
, p_buf
, flavor
, indent
, 0);
4733 if (ev
&& ev
->value
) {
4734 if (ev
->value
->errval
) { // replace
4735 ec
.set_msg("Erroneous value for component #1: ");
4736 if (ev
->value
->raw
) {
4737 sub_len
+= ev
->value
->errval
->encode_raw(p_buf
);
4739 if (ev
->value
->type_descr
==NULL
) TTCN_error(
4740 "internal error: erroneous value typedescriptor missing");
4741 sub_len
+= ev
->value
->errval
->XER_encode(
4742 *ev
->value
->type_descr
->xer
, p_buf
, flavor
, indent
, 0);
4746 ec
.set_msg("Component #1: ");
4748 // universal charstring does not have components
4749 TTCN_error("internal error: embedded descriptor unexpected");
4751 // the "real" encoder
4752 if (q_uri
->is_present()) {
4753 p_buf
.put_s(3, (cbyte
*)"b0:");
4757 sub_len
+= get_at(1)->XER_encode(*xer_descr(1), p_buf
, flavor
| XER_LIST
, indent
+1, 0);
4761 if (ev
&& ev
->after
) {
4762 if (ev
->after
->errval
==NULL
) TTCN_error(
4763 "internal error: erroneous after value missing");
4764 ec
.set_msg("Erroneous value after component #1: ");
4765 if (ev
->after
->raw
) {
4766 sub_len
+= ev
->after
->errval
->encode_raw(p_buf
);
4768 if (ev
->after
->type_descr
==NULL
) TTCN_error(
4769 "internal error: erroneous after typedescriptor missing");
4770 sub_len
+= ev
->after
->errval
->XER_encode(
4771 *ev
->after
->type_descr
->xer
, p_buf
, flavor
, indent
, 0);
4775 if (p_td
.xer_bits
& XER_ATTRIBUTE
) p_buf
.put_c('\'');
4777 else { // not USE-QNAME
4778 if (!exer
&& (p_td
.xer_bits
& EMBED_VALUES
)) {
4779 // The EMBED-VALUES member as an ordinary record of string
4780 sub_len
+= embed_values
->XER_encode(*xer_descr(0), p_buf
, flavor
, indent
+1, 0);
4783 if (!exer
&& (p_td
.xer_bits
& USE_ORDER
)) {
4784 // The USE-ORDER member as an ordinary record of enumerated
4785 sub_len
+= use_order
->XER_encode(*xer_descr(uo_index
), p_buf
, flavor
, indent
+1, 0);
4788 if (exer
&& (indent
==0 || (flavor
& DEF_NS_SQUASHED
))) // write namespaces for toplevel only
4790 for (size_t cur_coll
= 0; cur_coll
< num_collected
; ++cur_coll
) {
4791 p_buf
.put_s(strlen(collected_ns
[cur_coll
]), (cbyte
*)collected_ns
[cur_coll
]);
4792 Free(collected_ns
[cur_coll
]); // job done
4798 flavor
&= ~DEF_NS_SQUASHED
;
4799 flavor
|= DEF_NS_PRESENT
;
4801 else if (empty_ns_hack
) {
4802 p_buf
.put_s(9, (cbyte
*)" xmlns=''");
4803 flavor
&= ~DEF_NS_PRESENT
;
4804 flavor
|= DEF_NS_SQUASHED
;
4807 // True if the non-attribute fields need to be omitted;
4808 // e.g. if USE_ORDER is in effect and the "nil" attribute was written
4809 // (then the record-of-enum for USE-ORDER will be empty),
4810 // or "omit all after" was hit while processing attributes.
4811 boolean early_to_bed
= FALSE
;
4813 // First all the attributes (not added to sub_len)
4815 for (i
= start_at
; i
< first_nonattr
; ++i
) {
4816 const Erroneous_values_t
* ev
=
4817 p_err_descr
->next_field_err_values(i
, values_idx
);
4818 const Erroneous_descriptor_t
* ed
=
4819 p_err_descr
->next_field_emb_descr(i
, edescr_idx
);
4821 if (i
< p_err_descr
->omit_before
) continue;
4823 boolean is_xer_attr_field
= xer_descr(i
)->xer_bits
& XER_ATTRIBUTE
;
4824 ec_1
.set_msg("%s': ", fld_name(i
)); // attr
4826 tmp_len
= encode_field(i
, ev
, ed
, p_buf
, flavor
, indent
+ !omit_tag
, 0);
4828 if (is_xer_attr_field
&& !exer
) sub_len
+= tmp_len
; // do not add if attribute and EXER
4830 // omit_after value -1 becomes "very big"
4831 if ((unsigned int)i
>= (unsigned int)p_err_descr
->omit_after
) {
4832 early_to_bed
= TRUE
; // no more fields to write
4837 // True if the "nil" attribute needs to be written.
4838 boolean nil_attribute
= FALSE
;
4839 // nil attribute unaffected by erroneous
4840 boolean nil_attribute_simple
= FALSE
;
4841 if (exer
&& (p_td
.xer_bits
& USE_NIL
)) {
4842 nil_attribute
= nil_attribute_simple
= !get_at(field_cnt
-1)->ispresent();
4844 if (p_err_descr
->values_size
> 0) // there is an erroneous "value := ..."
4846 const Erroneous_values_t
*ev_nil
=
4847 p_err_descr
->get_field_err_values(field_cnt
-1);
4848 if (ev_nil
&& ev_nil
->value
) // value override for the last field
4850 nil_attribute
= (ev_nil
->value
->errval
== NULL
);
4855 if (nil_attribute
) { // req. exer and USE_NIL
4856 const namespace_t
*control_ns
= p_td
.my_module
->get_controlns();
4858 if (!nil_attribute_simple
) {
4859 // It is likely that the declaration for namespace "xsi"
4860 // was not written. Do it now.
4861 p_buf
.put_s(7, (cbyte
*)" xmlns:");
4862 p_buf
.put_s(strlen(control_ns
->px
), (cbyte
*)control_ns
->px
);
4863 p_buf
.put_s(2, (cbyte
*)"='");
4864 p_buf
.put_s(strlen(control_ns
->ns
), (cbyte
*)control_ns
->ns
);
4869 p_buf
.put_s(strlen(control_ns
->px
), (cbyte
*)control_ns
->px
);
4871 p_buf
.put_s(10, (cbyte
*)"nil='true'");
4872 if ((p_td
.xer_bits
& USE_ORDER
)) early_to_bed
= TRUE
;
4873 // The whole content was omitted; nothing to do (and if we tried
4874 // to do it, we'd get an error for over-indexing a 0-length record-of).
4877 if (delay_close
&& (!omit_tag
|| shorter
)) {
4878 // Close the start tag left open. If indenting, also write a newline
4879 // unless USE-NIL in effect or there is a single untagged component.
4881 ((p_td
.xer_bits
& (/*USE_NIL|*/HAS_1UNTAGGED
)) ? 0 : indenting
);
4882 p_buf
.put_s(start_tag_len
, (cbyte
*)">\n");
4885 // Erroneous values for the embed_values member (if any).
4886 // Collected once but referenced multiple times.
4887 const Erroneous_descriptor_t
* ed0
= NULL
;
4888 int embed_values_val_idx
= 0;
4889 int embed_values_descr_idx
= 0;
4891 if (exer
&& (p_td
.xer_bits
& EMBED_VALUES
)) {
4892 ed0
= p_err_descr
->next_field_emb_descr(0, edescr_idx
);
4894 // write the first string
4895 if (embed_values
->size_of() > 0) {
4896 const Erroneous_values_t
* ev0_0
= NULL
;
4897 const Erroneous_descriptor_t
* ed0_0
= NULL
;
4899 ev0_0
= ed0
->next_field_err_values(0, embed_values_val_idx
);
4900 ed0_0
= ed0
->next_field_emb_descr (0, embed_values_descr_idx
);
4902 sub_len
+= embed_values
->encode_element(0, UNIVERSAL_CHARSTRING_xer_
,
4903 ev0_0
, ed0_0
, p_buf
, flavor
| EMBED_VALUES
, indent
+!omit_tag
, 0);
4907 const Record_Type
*ordered
= this; // the record affected by USE-ORDER
4908 // By default it's this record, unless USE_NIL is _also_ in effect,
4909 // in which case it's the last member of this.
4911 // Index of the first non-attribute field of the record pointed to by
4912 // ordered, that is, the first field affected by USE-ORDER.
4913 size_t useorder_base
= first_nonattr
;
4916 int end
= field_cnt
; // "one past", do not touch
4917 // by default, continue from the current field until the end, indexing this
4919 if (exer
&& (p_td
.xer_bits
& USE_ORDER
)) {
4920 // the length of the loop is determined by the length of use_order
4921 const int to_send
= use_order
->size_of();
4923 // i will index all elements of the use_order member
4927 // Count the non-attribute optionals
4928 int n_optionals
= 0;
4929 for (int B
= optional_count() - 1; B
>=+0; B
--) {
4930 int oi
= get_optional_indexes()[B
];
4931 if (oi
< first_nonattr
) break;
4935 int expected_min
= field_cnt
- first_nonattr
- n_optionals
;
4936 int expected_max
= field_cnt
- first_nonattr
;
4938 if ((p_td
.xer_bits
& USE_NIL
) && get_at(field_cnt
-1)->ispresent()) {
4939 // The special case when USE_ORDER refers to the fields of a field,
4941 const Base_Type
*last_optional
= get_at(field_cnt
-1);
4942 const Base_Type
* inner
= last_optional
->get_opt_value();
4943 // it absolutely, positively has to be (derived from) Record_Type
4944 ordered
= static_cast<const Record_Type
*>(inner
);
4945 useorder_base
= ordered
->get_xer_num_attr();
4946 begin
= useorder_base
;
4947 end
= ordered
->get_count();
4949 expected_min
= expected_max
= ordered
->get_count();
4952 if (to_send
> expected_max
4953 ||to_send
< expected_min
) {
4954 ec_1
.set_msg("%s': ", fld_name(uo_index
));
4955 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_CONSTRAINT
,
4956 "Wrong number of USE-ORDER %d, must be %d..%d", to_send
, expected_min
, expected_max
);
4957 early_to_bed
= TRUE
; // don't bother sending anything
4959 else { // check no duplicates
4960 int *seen
= new int [to_send
];
4962 for (int ei
= 0; ei
< to_send
; ++ei
) {
4963 const Base_Type
*uoe
= use_order
->get_at(ei
);
4964 const Enum_Type
*enm
= static_cast<const Enum_Type
*>(uoe
);
4965 int val
= enm
->as_int();
4966 for (int x
= 0; x
< num_seen
; ++x
) {
4967 if (val
== seen
[x
]) { // complain
4968 ec_1
.set_msg("%s': ", fld_name(uo_index
));
4969 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_CONSTRAINT
,
4970 "Duplicate value for USE-ORDER");
4971 early_to_bed
= TRUE
; // don't bother sending anything
4975 seen
[num_seen
++] = val
;
4979 // If the number is right and there are no duplicates, then carry on
4981 } // endif(USE_ORDER)
4983 // Then, all the non-attributes. Structuring the code like this depends on
4984 // all attributes appearing before all non-attributes (excluding
4985 // pseudo-members for USE-ORDER, etc.)
4987 // This loop handles both the normal case (no USE_ORDER) when i indexes
4988 // fields of this record; and the USE_ORDER case (with or without USE-NIL).
4990 // early_to_bed can only be true if exer is true (transitive through nil_attribute)
4991 if (!early_to_bed
) {
4992 embed_values_enc_struct_t
* emb_val
= 0;
4993 if (exer
&& (p_td
.xer_bits
& EMBED_VALUES
) && embed_values
->size_of() > 1) {
4994 emb_val
= new embed_values_enc_struct_t
;
4995 emb_val
->embval_array
= embed_values
;
4996 emb_val
->embval_index
= 1;
4997 emb_val
->embval_err
= ed0
;
4998 emb_val
->embval_err_val_idx
= embed_values_val_idx
;
4999 emb_val
->embval_err_descr_idx
= embed_values_descr_idx
;
5002 for ( i
= begin
; i
< end
; ++i
) {
5004 const Base_Type
*uoe
= 0; // "useOrder enum"
5005 const Enum_Type
*enm
= 0; // the enum value selecting the field
5007 // "actual" index, may be perturbed by USE-ORDER.
5008 // We use this value to index the appropriate record.
5011 const Erroneous_values_t
* ev
= NULL
;
5012 const Erroneous_descriptor_t
* ed
= NULL
;
5013 if (exer
&& use_order
) {
5014 // If USE-ORDER is in effect, it introduces a level of indirection
5015 // into the indexing of fields: "i" is used to select an element
5016 // of the use_order member (an enum), whose value is used to select
5017 // the field being encoded.
5018 uoe
= use_order
->get_at(i
- begin
);
5019 enm
= static_cast<const Enum_Type
*>(uoe
);
5020 ai
= enm
->as_int() + useorder_base
;
5022 // Because it is not guaranteed that ai will increase monotonically,
5023 // we can't use next_field_...().
5024 ev
= p_err_descr
->get_field_err_values(ai
);
5025 ed
= p_err_descr
->get_field_emb_descr (ai
);
5027 else { // not USE-ORDER, sequential access
5028 ev
= p_err_descr
->next_field_err_values(ai
, values_idx
);
5029 ed
= p_err_descr
->next_field_emb_descr (ai
, edescr_idx
);
5031 ec_1
.set_msg("%s': ", ordered
->fld_name(ai
)); // non-attr
5033 if (ai
< p_err_descr
->omit_before
) continue;
5035 // omit_after value -1 becomes "very big".
5036 if ((unsigned int)ai
> (unsigned int)p_err_descr
->omit_after
) continue;
5037 // We can't skip all fields with break, because the next ai may be lower
5040 sub_len
+= ordered
->encode_field(ai
, ev
, ed
, p_buf
,
5041 // Pass USE-NIL to the last field (except when USE-ORDER is also in effect,
5042 // because the tag-stripping effect of USE-NIL has been achieved
5043 // by encoding the sub-fields directly).
5044 flavor
| ((exer
&& !use_order
&& (i
== field_cnt
-1)) ? (p_td
.xer_bits
& USE_NIL
) : 0),
5045 indent
+ !omit_tag
, emb_val
);
5047 // Now the next embed-values string (NOT affected by USE-ORDER!)
5048 if (exer
&& (p_td
.xer_bits
& EMBED_VALUES
) && 0 != emb_val
&&
5049 emb_val
->embval_index
< embed_values
->size_of()) {
5050 const Erroneous_values_t
* ev0_i
= NULL
;
5051 const Erroneous_descriptor_t
* ed0_i
= NULL
;
5053 ev0_i
= ed0
->next_field_err_values(emb_val
->embval_index
, emb_val
->embval_err_val_idx
);
5054 ed0_i
= ed0
->next_field_emb_descr (emb_val
->embval_index
, emb_val
->embval_err_descr_idx
);
5056 embed_values
->encode_element(emb_val
->embval_index
, UNIVERSAL_CHARSTRING_xer_
,
5057 ev0_i
, ed0_i
, p_buf
, flavor
| EMBED_VALUES
, indent
+ !omit_tag
, 0);
5058 ++emb_val
->embval_index
;
5062 if (emb_val
->embval_index
< embed_values
->size_of()) {
5063 ec_1
.set_msg("%s': ", fld_name(0));
5064 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_CONSTRAINT
,
5065 "Too many EMBED-VALUEs specified: %d (expected %d or less)",
5066 embed_values
->size_of(), emb_val
->embval_index
);
5070 } // if (!early_to_bed)
5075 if (sub_len
) { // something was written, now an end tag
5076 if (indenting
&& !(exer
&& (p_td
.xer_bits
& (HAS_1UNTAGGED
| USE_QNAME
))))
5077 // The tags of the last optional member involved with USE_NIL
5078 // have been removed. If it was a simple type, the content was probably
5079 // written on a single line without anything resembling a close tag.
5080 // Do not indent our end tag in this case.
5081 switch ((int)(exer
&& (p_td
.xer_bits
& USE_NIL
))) {
5083 const unsigned char *buf_end
= p_buf
.get_data() + (p_buf
.get_len()-1);
5084 if (buf_end
[-1] != '>' || *buf_end
!= '\n') break;
5085 // If it does not look like an end tag, skip the indenting,
5086 // else fall through.
5089 do_indent(p_buf
, indent
);
5094 if (exer
) write_ns_prefix(p_td
, p_buf
);
5095 p_buf
.put_s((size_t)p_td
.namelens
[exer
]-!indenting
, (cbyte
*)p_td
.names
[exer
]);
5097 else { // need to generate an empty element tag
5098 p_buf
.increase_length(-start_tag_len
); // decrease length
5099 p_buf
.put_s((size_t)2+indenting
, (cbyte
*)"/>\n");
5103 return (int)p_buf
.get_len() - encoded_length
;
5106 int Record_Type::XER_decode(const XERdescriptor_t
& p_td
, XmlReaderWrap
& reader
,
5107 unsigned int flavor
, unsigned int flavor2
, embed_values_dec_struct_t
*)
5109 int exer
= is_exer(flavor
);
5111 int depth
=-1; // depth of the start tag
5112 int xerbits
= p_td
.xer_bits
;
5113 if (flavor
& XER_TOPLEVEL
) xerbits
&= ~UNTAGGED
;
5114 const boolean own_tag
= !(exer
5115 && ( (xerbits
& (ANY_ELEMENT
| UNTAGGED
| XER_ATTRIBUTE
))
5116 || (flavor
& (USE_NIL
| USE_TYPE_ATTR
))));
5117 boolean tag_closed
= (flavor
& PARENT_CLOSED
) != 0;
5118 // If the parent has USE-TYPE, our ATTRIBUTE members can be found
5119 // in the parent's tag (the reader is sitting on it).
5120 const boolean parent_tag
= exer
&& ((flavor
& USE_TYPE_ATTR
) || (flavor2
& USE_NIL_PARENT_TAG
));
5122 // Filter out flags passed by our parent. These are not for the fields.
5123 flavor
&= XER_MASK
; // also removes XER_TOPLEVEL
5124 flavor2
= XER_NONE
; // Remove only bit: USE_NIL_PARENT_TAG (for now)
5126 const int field_cnt
= get_count();
5127 const int num_attributes
= get_xer_num_attr();
5129 // The index of potential "order" field, regardless of whether USE_ORDER
5130 // is in use or not.
5131 const int uo_index
= ((p_td
.xer_bits
& EMBED_VALUES
) !=0);
5133 // The first "non-special" field (skipping the USE-ORDER and EMBED-VALUES
5134 // fields); normal processing start at this field.
5135 const int start_at
= uo_index
+ ((p_td
.xer_bits
& USE_ORDER
) != 0);
5136 const int first_nonattr
= start_at
+ num_attributes
;
5138 // The index of the ANY-ATTRIBUTES member, if any
5140 for (int k
= 0; k
< first_nonattr
; ++k
) {
5141 if (xer_descr(k
)->xer_bits
& ANY_ATTRIBUTES
) {
5143 if (!get_at(aa_index
)->is_optional()) {
5144 static_cast<Record_Of_Type
*>(get_at(aa_index
))->set_size(0);
5146 break; // there can be only one, 18.2.2
5150 if (own_tag
) for (success
=reader
.Ok(); success
==1; success
=reader
.Read()) {
5151 type
= reader
.NodeType();
5152 if (type
==XML_READER_TYPE_ELEMENT
) {
5153 verify_name(reader
, p_td
, exer
);
5154 depth
= reader
.Depth();
5155 tag_closed
= reader
.IsEmptyElement();
5162 if (exer
&& (p_td
.xer_bits
& USE_QNAME
)) { // QName trumps everything !
5163 // If element, it looks like this:
5164 // <name xmlns:b0="http://www.furniture.com">b0:table</name>
5165 // If attribute, it looks like this:
5168 if (p_td
.xer_bits
& XER_ATTRIBUTE
) success
= 1; // do nothing
5169 else for (success
= reader
.Read(); success
== 1; success
= reader
.Read()) {
5170 type
= reader
.NodeType();
5171 if (type
== XML_READER_TYPE_TEXT
) break;
5175 xmlChar
*val
= reader
.NewValue();
5176 xmlChar
*npfx
= (xmlChar
*)strchr((char*)val
, ':');
5179 *npfx
++ = '\0'; // cut the string into two
5187 xmlChar
*nsu
= reader
.LookupNamespace(pfx
);
5189 OPTIONAL
<UNIVERSAL_CHARSTRING
> *q_prefix2
=
5190 static_cast<OPTIONAL
<UNIVERSAL_CHARSTRING
>*>(get_at(0));
5191 if (nsu
) *q_prefix2
= (const char*)nsu
;
5192 else q_prefix2
->set_to_omit(); // public in RT2 only
5194 UNIVERSAL_CHARSTRING
*q_name2
= static_cast<UNIVERSAL_CHARSTRING
*>(get_at(1));
5195 *q_name2
= (const char*)npfx
;
5201 else { // not use-qname
5202 TTCN_EncDec_ErrorContext
ec_0("Component '");
5203 TTCN_EncDec_ErrorContext ec_1
;
5204 boolean usenil_attribute
= FALSE
; // true if found and said yes
5205 // If nillable and the nillable field is a record type, that has attributes
5206 // then it will become true, and skips the processing of the fields after
5207 boolean already_processed
= FALSE
;
5209 if (!reader
.IsEmptyElement()) reader
.Read();
5210 // First, the (would-be) attributes (unaffected by USE-ORDER)
5211 for (i
= 0; i
< first_nonattr
; i
++) {
5212 ec_1
.set_msg("%s': ", fld_name(i
));
5213 get_at(i
)->XER_decode(*xer_descr(i
), reader
, flavor
, flavor2
, 0);
5216 else if (own_tag
|| parent_tag
) { // EXER and not UNTAGGED: do attributes
5217 // Prepare for lack of attributes.
5218 // Fields with defaultForEmpty get the D-F-E value, optional get omit.
5219 for (i
= start_at
; i
< first_nonattr
; i
++) {
5220 Base_Type
&fld
= *get_at(i
);
5221 const XERdescriptor_t
& xd
= *xer_descr(i
);
5223 if (fld
.is_optional()) {
5224 fld
.set_to_present();
5225 fld
.get_opt_value()->set_value(xd
.dfeValue
);
5227 else fld
.set_value(xd
.dfeValue
);
5229 else if (fld
.is_optional()) fld
.set_to_omit();
5232 int num_aa
= 0; // index into the ANY-ATTRIBUTE member
5234 const namespace_t
*control_ns
= 0;
5235 if (parent_tag
|| (p_td
.xer_bits
& USE_NIL
)) {
5236 // xsi:type or xsi:nil
5237 control_ns
= p_td
.my_module
->get_controlns();
5240 /* * * * * * * * * Attributes * * * * * * * * * * * * * */
5241 if(parent_tag
&& reader
.NodeType() == XML_READER_TYPE_ATTRIBUTE
) {
5242 success
= reader
.Ok();
5244 success
= reader
.MoveToFirstAttribute();
5247 success
== 1 && reader
.NodeType() == XML_READER_TYPE_ATTRIBUTE
;
5248 success
= reader
.AdvanceAttribute())
5250 if (reader
.IsNamespaceDecl()) {
5251 continue; // namespace declarations are handled for us by libxml2
5254 const char *attr_name
= (const char*)reader
.LocalName();
5255 const char *ns_uri
= (const char*)reader
.NamespaceUri();
5256 int field_index
= get_index_byname(attr_name
, ns_uri
);
5257 if (field_index
!= -1) {
5258 // There is a field. Let it decode the attribute.
5259 ec_1
.set_msg("%s': ", fld_name(field_index
));
5260 get_at(field_index
)->XER_decode(*xer_descr(field_index
), reader
, flavor
, flavor2
, 0);
5264 // Attribute not found. It could be the "nil" attribute
5265 if (p_td
.xer_bits
& USE_NIL
) {
5266 const char *prefix
= (const char*)reader
.Prefix();
5267 // prefix may be NULL, control_ns->px is never NULL or empty
5268 if (prefix
&& !strcmp(prefix
, control_ns
->px
)
5269 && !strcmp((const char*)reader
.LocalName(), "nil"))
5270 { // It is the "nil" attribute
5271 const char *value
= (const char*)reader
.Value();
5273 if (!strcmp(value
, "1") || !strcmp(value
, "true")) {
5274 // The field affected by USE-NIL is always the last one
5275 get_at(field_cnt
-1)->set_to_omit();
5276 usenil_attribute
= TRUE
;
5281 } // it is the "nil" attribute
5282 // else, let the nillable field decode the next attributes, it is possible
5283 // that it belongs to him
5284 get_at(field_cnt
-1)->XER_decode(*xer_descr(field_cnt
-1), reader
, flavor
| USE_NIL
, flavor2
| USE_NIL_PARENT_TAG
, 0);
5285 already_processed
= TRUE
;
5287 } // type has USE-NIL
5290 const char *prefix
= (const char*)reader
.Prefix();
5291 // prefix may be NULL, control_ns->px is never NULL or empty
5292 if (prefix
&& !strcmp(prefix
, control_ns
->px
)
5293 && !strcmp((const char*)reader
.LocalName(), "type")) {
5294 continue; // xsi:type has been processed by the parent
5298 if (aa_index
>= 0) {
5299 ec_1
.set_msg("%s': ", fld_name(aa_index
));
5300 TTCN_EncDec_ErrorContext
ec_2("Attribute %d: ", num_aa
);
5301 // We have a component with ANY-ATTRIBUTE. It must be a record of
5302 // UNIVERSAL_CHARSTRING. Add the attribute to it.
5303 Record_Of_Type
*aa
= 0;
5304 if (get_at(aa_index
)->is_optional()) {
5306 get_at(aa_index
)->set_to_present();
5308 aa
= static_cast<Record_Of_Type
*>(get_at(aa_index
)->get_opt_value());
5311 aa
= static_cast<Record_Of_Type
*>(get_at(aa_index
));
5313 UNIVERSAL_CHARSTRING
*new_elem
= static_cast<UNIVERSAL_CHARSTRING
*>
5314 (aa
->get_at(num_aa
++));
5316 // Construct the AnyAttributeFormat (X.693amd1, 18.2.6)
5318 const xmlChar
*name
= reader
.LocalName();
5319 const xmlChar
*val
= reader
.Value();
5320 const xmlChar
*uri
= reader
.NamespaceUri();
5322 if (xer_descr(aa_index
)->xer_bits
& (ANY_FROM
| ANY_EXCEPT
)) {
5323 check_namespace_restrictions(*xer_descr(aa_index
), (const char*)uri
);
5325 // We don't care about reader.Prefix()
5326 // Using strlen to count UTF8 bytes, not characters
5327 aabuf
.put_s(uri
? strlen((const char*)uri
) : 0, uri
);
5328 if (uri
&& *uri
) aabuf
.put_c(' ');
5329 aabuf
.put_s(name
? strlen((const char*)name
) : 0, name
);
5332 aabuf
.put_s(val
? strlen((const char*)val
) : 0, val
);
5334 new_elem
->decode_utf8(aabuf
.get_len(), aabuf
.get_data());
5339 // Lastly check for the xsi:schemaLocation attribute, this does not
5340 // affect TTCN-3, but it shouldn't cause a DTE
5341 if (reader
.LocalName() && !strcmp((const char*)reader
.LocalName(), "schemaLocation")) {
5343 control_ns
= p_td
.my_module
->get_controlns();
5345 if (reader
.Prefix() && !strcmp((const char*)reader
.Prefix(), control_ns
->px
)) {
5350 // Nobody wanted the attribute. That is an error.
5351 ec_0
.set_msg(" "); ec_1
.set_msg(" ");
5352 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG
,
5353 "Unexpected attribute '%s', ns '%s'", attr_name
,
5354 ns_uri
? ns_uri
: "");
5357 // Now check that all mandatory attributes have been set
5358 for (i
= start_at
; i
< first_nonattr
; ++i
) {
5359 Base_Type
* fld
= get_at(i
);
5360 if (fld
->is_optional()) continue; // field is allowed to be unset
5361 if (!fld
->is_bound()) {
5362 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG
,
5363 "Missing attribute '%s'", this->fld_name(i
));
5367 i
= first_nonattr
; // finished with attributes
5368 // AdvanceAttribute did MoveToElement. Move into the content (if any).
5369 if (!reader
.IsEmptyElement()) reader
.Read();
5370 } // end if (own_tag)
5372 /* * * * * * * * Non-attributes (elements) * * * * * * * * * * * */
5373 embed_values_dec_struct_t
* emb_val
= 0;
5374 bool emb_val_optional
= false;
5375 if (exer
&& (p_td
.xer_bits
& EMBED_VALUES
)) {
5376 emb_val
= new embed_values_dec_struct_t
;
5377 emb_val
->embval_array
= dynamic_cast<Record_Of_Type
*>(get_at(0));
5378 if (NULL
== emb_val
->embval_array
) {
5379 OPTIONAL
<PreGenRecordOf::PREGEN__RECORD__OF__UNIVERSAL__CHARSTRING
>* embed_value
= static_cast<OPTIONAL
<PreGenRecordOf::PREGEN__RECORD__OF__UNIVERSAL__CHARSTRING
>*>(get_at(0));
5380 embed_value
->set_to_present();
5381 emb_val
->embval_array
= static_cast<Record_Of_Type
*>((*embed_value
).get_opt_value());
5382 emb_val_optional
= true;
5384 emb_val
->embval_array
->set_size(0);
5385 emb_val
->embval_index
= 0;
5388 if (exer
&& (p_td
.xer_bits
& USE_ORDER
)) {
5389 // Set all optional fields to omit because their respective XER_decode
5390 // will not be run (and will stay unbound) if the value is missing.
5391 int n_optionals
= 0;
5392 for (int B
= optional_count() - 1; B
>=+0; B
--) {
5393 int oi
= get_optional_indexes()[B
];
5394 if (oi
< first_nonattr
) break;
5395 get_at(oi
)->set_to_omit();
5399 Record_Of_Type
*use_order
= static_cast<Record_Of_Type
*>(get_at(uo_index
));
5400 // Initialize the use_order field to empty. Let it grow on demand.
5401 // (setting it to the minimum acceptable size may leave unbound elements
5402 // if the XML was incomplete).
5403 use_order
->set_size(0);
5405 // Nothing to order if there are no child elements
5407 Record_Type
*jumbled
= this; // the record affected by USE_ORDER
5408 int begin
= first_nonattr
;
5409 int end
= field_cnt
; // "one past"
5410 if (p_td
.xer_bits
& USE_NIL
) {
5411 Base_Type
*last_optional
= get_at(field_cnt
-1);
5412 if (!usenil_attribute
) { // exer known true
5413 last_optional
->set_to_present();
5414 jumbled
= static_cast<Record_Type
*>(last_optional
->get_opt_value());
5415 // We will operate on the members of last_optional,
5416 // effectively bypassing last_optional->XER_decode() itself.
5418 end
= jumbled
->get_count();
5419 ec_1
.set_msg("%s': ", fld_name(field_cnt
-1));
5422 if (num_attributes
> 0
5423 && first_nonattr
!= field_cnt
5424 && i
== first_nonattr
- 1) { // exer known true
5425 // If there were attributes and their processing just finished,
5426 // the reader is positioned on the start tag of the record.
5427 // Move ahead, unless there are no non-attribute fields.
5430 // Then, the non-attributes
5432 // The index runs over the members affected by USE-ORDER.
5433 // This is [first_nonattr,field_cnt) unless USE-NIL is involved,
5434 // in which case it's [0,optional_sequence::field_cnt)
5435 int *seen
= new int[end
-begin
];
5437 int last_any_elem
= begin
- 1;
5438 // The index of the latest embedded value can change outside of this function
5439 // (if the field is an untagged record of), in this case the next value should
5440 // be ignored, as it's already been handled by the record of
5441 int last_embval_index
= 0;
5442 bool early_exit
= false;
5443 for (i
= begin
; i
< end
; i
++) {
5444 for (success
= reader
.Ok(); success
== 1; success
= reader
.Read()) {
5445 type
= reader
.NodeType();
5446 if (0 != emb_val
&& reader
.NodeType()==XML_READER_TYPE_TEXT
) {
5447 UNIVERSAL_CHARSTRING
emb_ustr((const char*)reader
.Value());
5448 emb_val
->embval_array
->get_at(emb_val
->embval_index
)->set_value(&emb_ustr
);
5450 // The non-attribute components must not be UNTAGGED
5451 if (type
== XML_READER_TYPE_ELEMENT
) break;
5452 if (type
== XML_READER_TYPE_END_ELEMENT
) {
5458 if (last_embval_index
== emb_val
->embval_index
) {
5459 ++emb_val
->embval_index
;
5461 last_embval_index
= emb_val
->embval_index
;
5463 if (success
!= 1 || early_exit
) break;
5464 const char *name
= (const char *)reader
.LocalName();
5465 bool field_name_found
= false;
5466 // Find out which member it is.
5467 // FIXME some hashing should be implemented
5468 for (int k
= begin
; k
< end
; k
++) {
5469 if (!(jumbled
->xer_descr(k
)->xer_bits
& ANY_ELEMENT
) &&
5470 check_name(name
, *jumbled
->xer_descr(k
), 1)) {
5471 ec_1
.set_msg("%s': ", jumbled
->fld_name(k
));
5473 // Check for the same field being decoded twice.
5474 // We can't use the field's is_bound()/is_present(),
5475 // because the field may be bound on input, e.g. for
5476 // prototype(fast) or prototype(backtrack).
5477 int in_dex
= k
- begin
;
5478 for (int o
= 0; o
< num_seen
;++o
) {
5479 if (in_dex
== seen
[o
]) TTCN_EncDec_ErrorContext::error(
5480 TTCN_EncDec::ET_INVAL_MSG
, "Duplicate element");
5482 seen
[num_seen
++] = in_dex
;
5483 // Set the next use-order member.
5484 // Non-const get_at creates the object in the record-of.
5485 static_cast<Enum_Type
*>(use_order
->get_at(i
- begin
))
5487 Base_Type
*b
= jumbled
->get_at(k
);
5488 b
->XER_decode(*jumbled
->xer_descr(k
), reader
, flavor
, flavor2
, emb_val
);
5489 field_name_found
= true;
5493 if (!field_name_found
) {
5494 // Check the anyElement fields
5495 for (int k
= last_any_elem
+ 1; k
< end
; k
++) {
5496 if (jumbled
->xer_descr(k
)->xer_bits
& ANY_ELEMENT
) {
5497 ec_1
.set_msg("%s': ", jumbled
->fld_name(k
));
5499 // Check for the same field being decoded twice.
5500 // We can't use the field's is_bound()/is_present(),
5501 // because the field may be bound on input, e.g. for
5502 // prototype(fast) or prototype(backtrack).
5503 int in_dex
= k
- begin
;
5504 for (int o
= 0; o
< num_seen
;++o
) {
5505 if (in_dex
== seen
[o
]) TTCN_EncDec_ErrorContext::error(
5506 TTCN_EncDec::ET_INVAL_MSG
, "Duplicate element");
5508 seen
[num_seen
++] = in_dex
;
5509 // Set the next use-order member.
5510 // Non-const get_at creates the object in the record-of.
5511 static_cast<Enum_Type
*>(use_order
->get_at(i
- begin
))
5513 Base_Type
*b
= jumbled
->get_at(k
);
5514 b
->XER_decode(*jumbled
->xer_descr(k
), reader
, flavor
, flavor2
, emb_val
);
5516 field_name_found
= true;
5521 if (!field_name_found
) {
5522 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG
,
5523 "Bad XML tag '%s' instead of a valid field", name
);
5528 if (reader
.NodeType()==XML_READER_TYPE_TEXT
) {
5529 UNIVERSAL_CHARSTRING
emb_ustr((const char*)reader
.Value());
5530 emb_val
->embval_array
->get_at(emb_val
->embval_index
)->set_value(&emb_ustr
);
5532 if (last_embval_index
== emb_val
->embval_index
) {
5533 ++emb_val
->embval_index
;
5537 ec_1
.set_msg(" "); // no active component
5540 // Check that we collected the required number of children
5541 int num_collected
= use_order
->size_of();
5542 if (p_td
.xer_bits
& USE_NIL
) {
5543 int expected
= usenil_attribute
? 0 : jumbled
->get_count();
5544 if (num_collected
!= expected
) {
5545 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INCOMPL_MSG
,
5546 "Incorrect number of fields %d, expected %d",
5547 num_collected
, expected
);
5551 if (num_collected
< field_cnt
- first_nonattr
- n_optionals
5552 ||num_collected
> field_cnt
- first_nonattr
) {
5553 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INCOMPL_MSG
,
5554 "Wrong number of fields! size = %d, expected %d..%d",
5555 use_order
->size_of(), field_cnt
- first_nonattr
- n_optionals
,
5556 field_cnt
- first_nonattr
);
5559 } // not empty element
5561 else { // not USE-ORDER, simpler code
5562 if (usenil_attribute
) {
5563 reader
.MoveToElement(); // value absent, nothing more to do
5565 // The index of the latest embedded value can change outside of this function
5566 // (if the field is a untagged record of), in this case the next value should
5567 // be ignored, as it's already been handled by the record of
5568 // Omitted fields can also reset this value
5569 int last_embval_index
= 0;
5570 for (; i
<field_cnt
; i
++) {
5572 if (reader
.NodeType()==XML_READER_TYPE_TEXT
) {
5573 UNIVERSAL_CHARSTRING
emb_ustr((const char*)reader
.Value());
5574 emb_val
->embval_array
->get_at(emb_val
->embval_index
)->set_value(&emb_ustr
);
5576 if (last_embval_index
== emb_val
->embval_index
) {
5577 ++emb_val
->embval_index
;
5579 last_embval_index
= emb_val
->embval_index
;
5581 ec_1
.set_msg("%s': ", fld_name(i
));
5582 if (exer
&& i
==field_cnt
-1 && p_td
.dfeValue
&& reader
.IsEmptyElement()) {
5583 get_at(i
)->set_value(p_td
.dfeValue
);
5586 // In case the field is an optional anyElement -> check if it should be omitted
5587 bool optional_any_elem_check
= true;
5588 if (get_at(i
)->is_optional() && (xer_descr(i
)->xer_bits
& ANY_ELEMENT
)) {
5589 // The "anyElement" coding instruction can only be applied to a universal charstring field
5590 OPTIONAL
<UNIVERSAL_CHARSTRING
>* opt_field
= dynamic_cast<OPTIONAL
<UNIVERSAL_CHARSTRING
>*>(get_at(i
));
5592 const char* next_field_name
= NULL
;
5593 if (i
< field_cnt
- 1) {
5594 next_field_name
= fld_name(i
+ 1);
5596 optional_any_elem_check
= opt_field
->XER_check_any_elem(reader
, next_field_name
, tag_closed
);
5599 if (optional_any_elem_check
&& !already_processed
) {
5600 int new_flavor
= flavor
;
5601 if (i
== field_cnt
-1) new_flavor
|= (p_td
.xer_bits
& USE_NIL
);
5602 if (tag_closed
) new_flavor
|= PARENT_CLOSED
;
5604 get_at(i
)->XER_decode(*xer_descr(i
), reader
, new_flavor
, flavor2
, emb_val
);
5607 if (!get_at(i
)->is_present()) {
5608 // there was no new element, the last embedded value is for the next field
5609 // (or the end of the record if this is the last field)
5610 last_embval_index
= -1;
5614 if (reader
.NodeType()==XML_READER_TYPE_TEXT
) {
5615 UNIVERSAL_CHARSTRING
emb_ustr((const char*)reader
.Value());
5616 emb_val
->embval_array
->get_at(emb_val
->embval_index
)->set_value(&emb_ustr
);
5618 if (last_embval_index
== emb_val
->embval_index
) {
5619 ++emb_val
->embval_index
;
5626 bool all_unbound
= true;
5627 static const UNIVERSAL_CHARSTRING
emptystring(0, (const char*)NULL
);
5628 for (int j
= 0; j
< emb_val
->embval_index
; ++j
) {
5629 if (!emb_val
->embval_array
->get_at(j
)->is_bound()) {
5630 emb_val
->embval_array
->get_at(j
)->set_value(&emptystring
);
5631 }else if((static_cast<const UNIVERSAL_CHARSTRING
*>(emb_val
->embval_array
->get_at(j
)))->lengthof() !=0) {
5632 all_unbound
= false;
5635 if(emb_val_optional
&& all_unbound
){
5636 static_cast<OPTIONAL
<PreGenRecordOf::PREGEN__RECORD__OF__UNIVERSAL__CHARSTRING
>*>(get_at(0))->set_to_omit();
5639 } // if embed-values
5643 // Check if every non-optional field has been set
5644 for (i
= 0; i
< field_cnt
; ++i
) {
5645 if (!get_at(i
)->is_optional() && !get_at(i
)->is_bound()) {
5646 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INCOMPL_MSG
,
5647 "No data found for non-optional field '%s'", fld_name(i
));
5652 // We had our start tag. Then our fields did their thing.
5653 // Now we expect the end tag. And it better be our end tag!
5655 for (success
= reader
.Ok(); success
== 1; success
= reader
.Read()) {
5656 type
= reader
.NodeType();
5657 current_depth
= reader
.Depth();
5658 if (current_depth
> depth
) {
5659 if (XML_READER_TYPE_ELEMENT
== type
) {
5660 // We found a deeper start tag; it was not processed at all.
5661 // That is an error (maybe we should report error for all node types
5662 // except TEXT and WHITESPACE, not just ELEMENT).
5663 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TAG
,
5664 "Unprocessed XML tag `%s'", (const char *)reader
.Name());
5667 continue; // go past hoping that our end tag will arrive eventually
5669 else if (current_depth
== depth
) { // at our level
5670 if (XML_READER_TYPE_ELEMENT
== type
) {
5671 verify_name(reader
, p_td
, exer
);
5672 if (reader
.IsEmptyElement()) {
5673 // FIXME this shouldn't really be possible;
5674 // only an empty record should be encoded as an empty element,
5675 // but those are implemented by Empty_Record_Type, not Record_Type.
5676 reader
.Read(); // one last time
5680 // If we find an end tag at the right depth, it must be ours
5681 else if (XML_READER_TYPE_END_ELEMENT
== type
) {
5682 verify_end(reader
, p_td
, depth
, exer
);
5687 else { //current_depth < depth; something has gone horribly wrong
5688 break; // better quit before we do further damage
5689 // Don't report an error; every enclosing type would do so,
5690 // spewing the same message over and over.
5694 return 1; // decode successful
5697 int Record_Type::JSON_encode(const TTCN_Typedescriptor_t
& p_td
, JSON_Tokenizer
& p_tok
) const
5700 return JSON_encode_negtest(err_descr
, p_td
, p_tok
);
5704 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND
,
5705 "Encoding an unbound %s value.", is_set() ? "set" : "record");
5709 int enc_len
= p_tok
.put_next_token(JSON_TOKEN_OBJECT_START
, NULL
);
5711 int field_count
= get_count();
5712 for (int i
= 0; i
< field_count
; ++i
) {
5713 boolean metainfo_unbound
= NULL
!= fld_descr(i
)->json
&& fld_descr(i
)->json
->metainfo_unbound
;
5714 if ((NULL
!= fld_descr(i
)->json
&& fld_descr(i
)->json
->omit_as_null
) ||
5715 get_at(i
)->is_present() || metainfo_unbound
) {
5716 const char* field_name
= (NULL
!= fld_descr(i
)->json
&& NULL
!= fld_descr(i
)->json
->alias
) ?
5717 fld_descr(i
)->json
->alias
: fld_name(i
);
5718 enc_len
+= p_tok
.put_next_token(JSON_TOKEN_NAME
, field_name
);
5719 if (metainfo_unbound
&& !get_at(i
)->is_bound()) {
5720 enc_len
+= p_tok
.put_next_token(JSON_TOKEN_LITERAL_NULL
);
5721 char* metainfo_str
= mprintf("metainfo %s", field_name
);
5722 enc_len
+= p_tok
.put_next_token(JSON_TOKEN_NAME
, metainfo_str
);
5724 enc_len
+= p_tok
.put_next_token(JSON_TOKEN_STRING
, "\"unbound\"");
5727 enc_len
+= get_at(i
)->JSON_encode(*fld_descr(i
), p_tok
);
5732 enc_len
+= p_tok
.put_next_token(JSON_TOKEN_OBJECT_END
, NULL
);
5736 int Record_Type::JSON_encode_negtest(const Erroneous_descriptor_t
* p_err_descr
,
5737 const TTCN_Typedescriptor_t
& p_td
,
5738 JSON_Tokenizer
& p_tok
) const
5741 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND
,
5742 "Encoding an unbound %s value.", is_set() ? "set" : "record");
5746 int enc_len
= p_tok
.put_next_token(JSON_TOKEN_OBJECT_START
, NULL
);
5751 int field_count
= get_count();
5752 for (int i
= 0; i
< field_count
; ++i
) {
5753 if (-1 != p_err_descr
->omit_before
&& p_err_descr
->omit_before
> i
) {
5757 const Erroneous_values_t
* err_vals
= p_err_descr
->next_field_err_values(i
, values_idx
);
5758 const Erroneous_descriptor_t
* emb_descr
= p_err_descr
->next_field_emb_descr(i
, edescr_idx
);
5760 if (NULL
!= err_vals
&& NULL
!= err_vals
->before
) {
5761 if (NULL
== err_vals
->before
->errval
) {
5762 TTCN_error("internal error: erroneous before value missing");
5764 if (err_vals
->before
->raw
) {
5765 enc_len
+= err_vals
->before
->errval
->JSON_encode_negtest_raw(p_tok
);
5767 if (NULL
== err_vals
->before
->type_descr
) {
5768 TTCN_error("internal error: erroneous before typedescriptor missing");
5770 // it's an extra field, so use the erroneous type's name as the field name
5771 enc_len
+= p_tok
.put_next_token(JSON_TOKEN_NAME
, err_vals
->before
->type_descr
->name
);
5772 enc_len
+= err_vals
->before
->errval
->JSON_encode(*(err_vals
->before
->type_descr
), p_tok
);
5776 const char* field_name
= (NULL
!= fld_descr(i
)->json
&& NULL
!= fld_descr(i
)->json
->alias
) ?
5777 fld_descr(i
)->json
->alias
: fld_name(i
);
5778 if (NULL
!= err_vals
&& NULL
!= err_vals
->value
) {
5779 if (NULL
!= err_vals
->value
->errval
) {
5780 if (err_vals
->value
->raw
) {
5781 enc_len
+= err_vals
->value
->errval
->JSON_encode_negtest_raw(p_tok
);
5783 if (NULL
== err_vals
->value
->type_descr
) {
5784 TTCN_error("internal error: erroneous before typedescriptor missing");
5786 // only replace the field's value, keep the field name
5787 enc_len
+= p_tok
.put_next_token(JSON_TOKEN_NAME
, field_name
);
5788 enc_len
+= err_vals
->value
->errval
->JSON_encode(*(err_vals
->value
->type_descr
), p_tok
);
5792 boolean metainfo_unbound
= NULL
!= fld_descr(i
)->json
&& fld_descr(i
)->json
->metainfo_unbound
;
5793 if ((NULL
!= fld_descr(i
)->json
&& fld_descr(i
)->json
->omit_as_null
) ||
5794 get_at(i
)->is_present() || metainfo_unbound
) {
5795 enc_len
+= p_tok
.put_next_token(JSON_TOKEN_NAME
, field_name
);
5796 if (metainfo_unbound
&& !get_at(i
)->is_bound()) {
5797 enc_len
+= p_tok
.put_next_token(JSON_TOKEN_LITERAL_NULL
);
5798 char* metainfo_str
= mprintf("metainfo %s", field_name
);
5799 enc_len
+= p_tok
.put_next_token(JSON_TOKEN_NAME
, metainfo_str
);
5801 enc_len
+= p_tok
.put_next_token(JSON_TOKEN_STRING
, "\"unbound\"");
5803 else if (NULL
!= emb_descr
) {
5804 enc_len
+= get_at(i
)->JSON_encode_negtest(emb_descr
, *fld_descr(i
), p_tok
);
5806 enc_len
+= get_at(i
)->JSON_encode(*fld_descr(i
), p_tok
);
5811 if (NULL
!= err_vals
&& NULL
!= err_vals
->after
) {
5812 if (NULL
== err_vals
->after
->errval
) {
5813 TTCN_error("internal error: erroneous after value missing");
5815 if (err_vals
->after
->raw
) {
5816 enc_len
+= err_vals
->after
->errval
->JSON_encode_negtest_raw(p_tok
);
5818 if (NULL
== err_vals
->after
->type_descr
) {
5819 TTCN_error("internal error: erroneous before typedescriptor missing");
5821 // it's an extra field, so use the erroneous type's name as the field name
5822 enc_len
+= p_tok
.put_next_token(JSON_TOKEN_NAME
, err_vals
->after
->type_descr
->name
);
5823 enc_len
+= err_vals
->after
->errval
->JSON_encode(*(err_vals
->after
->type_descr
), p_tok
);
5827 if (-1 != p_err_descr
->omit_after
&& p_err_descr
->omit_after
<= i
) {
5832 enc_len
+= p_tok
.put_next_token(JSON_TOKEN_OBJECT_END
, NULL
);
5836 int Record_Type::JSON_decode(const TTCN_Typedescriptor_t
& p_td
, JSON_Tokenizer
& p_tok
, boolean p_silent
)
5838 json_token_t token
= JSON_TOKEN_NONE
;
5839 int dec_len
= p_tok
.get_next_token(&token
, NULL
, NULL
);
5840 if (JSON_TOKEN_ERROR
== token
) {
5841 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG
, JSON_DEC_BAD_TOKEN_ERROR
, "");
5842 return JSON_ERROR_FATAL
;
5844 else if (JSON_TOKEN_OBJECT_START
!= token
) {
5845 return JSON_ERROR_INVALID_TOKEN
;
5848 const int field_count
= get_count();
5850 // initialize meta info states
5851 int* metainfo
= new int[field_count
];
5852 boolean
* field_found
= new boolean
[field_count
];
5853 for (int i
= 0; i
< field_count
; ++i
) {
5854 field_found
[i
] = FALSE
;
5855 metainfo
[i
] = (NULL
!= fld_descr(i
)->json
&& fld_descr(i
)->json
->metainfo_unbound
) ?
5856 JSON_METAINFO_NONE
: JSON_METAINFO_NOT_APPLICABLE
;
5860 // Read name - value token pairs until we reach some other token
5862 size_t name_len
= 0;
5863 size_t buf_pos
= p_tok
.get_buf_pos();
5864 dec_len
+= p_tok
.get_next_token(&token
, &name
, &name_len
);
5865 if (JSON_TOKEN_ERROR
== token
) {
5866 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG
, JSON_DEC_BAD_TOKEN_ERROR
, "");
5867 return JSON_ERROR_FATAL
;
5869 else if (JSON_TOKEN_NAME
!= token
) {
5870 // undo the last action on the buffer
5871 p_tok
.set_buf_pos(buf_pos
);
5875 // check for meta info
5876 boolean is_metainfo
= FALSE
;
5877 if (name_len
> 9 && 0 == strncmp(name
, "metainfo ", 9)) {
5885 for (field_idx
= 0; field_idx
< field_count
; ++field_idx
) {
5886 const char* expected_name
= 0;
5887 if (NULL
!= fld_descr(field_idx
)->json
&& NULL
!= fld_descr(field_idx
)->json
->alias
) {
5888 expected_name
= fld_descr(field_idx
)->json
->alias
;
5890 expected_name
= fld_name(field_idx
);
5892 if (strlen(expected_name
) == name_len
&&
5893 0 == strncmp(expected_name
, name
, name_len
)) {
5894 field_found
[field_idx
] = TRUE
;
5898 if (field_count
== field_idx
) {
5899 // invalid field name
5900 char* name2
= mcopystrn(name
, name_len
);
5901 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG
, is_metainfo
?
5902 JSON_DEC_METAINFO_NAME_ERROR
: JSON_DEC_INVALID_NAME_ERROR
, name2
);
5903 // if this is set to a warning, skip the value of the field
5904 dec_len
+= p_tok
.get_next_token(&token
, NULL
, NULL
);
5905 if (JSON_TOKEN_NUMBER
!= token
&& JSON_TOKEN_STRING
!= token
&&
5906 JSON_TOKEN_LITERAL_TRUE
!= token
&& JSON_TOKEN_LITERAL_FALSE
!= token
&&
5907 JSON_TOKEN_LITERAL_NULL
!= token
) {
5908 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG
, JSON_DEC_FIELD_TOKEN_ERROR
, name2
);
5910 return JSON_ERROR_FATAL
;
5917 if (JSON_METAINFO_NOT_APPLICABLE
!= metainfo
[field_idx
]) {
5919 char* info_value
= 0;
5920 size_t info_len
= 0;
5921 dec_len
+= p_tok
.get_next_token(&token
, &info_value
, &info_len
);
5922 if (JSON_TOKEN_STRING
== token
&& 9 == info_len
&&
5923 0 == strncmp(info_value
, "\"unbound\"", 9)) {
5924 metainfo
[field_idx
] = JSON_METAINFO_UNBOUND
;
5927 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG
, JSON_DEC_METAINFO_VALUE_ERROR
,
5928 fld_name(field_idx
));
5929 return JSON_ERROR_FATAL
;
5933 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG
, JSON_DEC_METAINFO_NOT_APPLICABLE
,
5934 fld_name(field_idx
));
5935 return JSON_ERROR_FATAL
;
5939 buf_pos
= p_tok
.get_buf_pos();
5940 int ret_val
= get_at(field_idx
)->JSON_decode(*fld_descr(field_idx
), p_tok
, p_silent
);
5942 if (JSON_ERROR_INVALID_TOKEN
== ret_val
) {
5943 // undo the last action on the buffer, check if the invalid token was a null token
5944 p_tok
.set_buf_pos(buf_pos
);
5945 p_tok
.get_next_token(&token
, NULL
, NULL
);
5946 if (JSON_TOKEN_LITERAL_NULL
== token
) {
5947 if (JSON_METAINFO_NONE
== metainfo
[field_idx
]) {
5948 // delay reporting an error for now, there might be meta info later
5949 metainfo
[field_idx
] = JSON_METAINFO_NEEDED
;
5952 else if (JSON_METAINFO_UNBOUND
== metainfo
[field_idx
]) {
5953 // meta info already found
5957 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG
, JSON_DEC_FIELD_TOKEN_ERROR
, fld_name(field_idx
));
5959 return JSON_ERROR_FATAL
;
5966 dec_len
+= p_tok
.get_next_token(&token
, NULL
, NULL
);
5967 if (JSON_TOKEN_OBJECT_END
!= token
) {
5968 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG
, JSON_DEC_OBJECT_END_TOKEN_ERROR
, "");
5969 return JSON_ERROR_FATAL
;
5972 // Check if every field has been set and handle meta info
5973 for (int field_idx
= 0; field_idx
< field_count
; ++field_idx
) {
5974 Base_Type
* field
= get_at(field_idx
);
5975 if (JSON_METAINFO_UNBOUND
== metainfo
[field_idx
]) {
5978 else if (JSON_METAINFO_NEEDED
== metainfo
[field_idx
]) {
5979 // no meta info was found for this field, report the delayed error
5980 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG
, JSON_DEC_FIELD_TOKEN_ERROR
, fld_name(field_idx
));
5982 else if (!field_found
[field_idx
]) {
5983 if (NULL
!= fld_descr(field_idx
)->json
&& NULL
!= fld_descr(field_idx
)->json
->default_value
) {
5984 get_at(field_idx
)->JSON_decode(*fld_descr(field_idx
), DUMMY_BUFFER
, p_silent
);
5986 else if (field
->is_optional()) {
5987 field
->set_to_omit();
5989 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG
, JSON_DEC_MISSING_FIELD_ERROR
, fld_name(field_idx
));
5990 return JSON_ERROR_FATAL
;
6000 ////////////////////////////////////////////////////////////////////////////////
6002 Empty_Record_Type::Empty_Record_Type(): bound_flag(FALSE
)
6006 Empty_Record_Type::Empty_Record_Type(const Empty_Record_Type
& other_value
)
6007 : Base_Type(other_value
), bound_flag(other_value
.bound_flag
)
6009 if (!other_value
.bound_flag
)
6010 TTCN_error("Copying an unbound value of type %s.",
6011 other_value
.get_descriptor()->name
);
6014 boolean
Empty_Record_Type::operator==(null_type
) const
6017 TTCN_error("Comparison of an unbound value of type %s.",
6018 get_descriptor()->name
);
6022 void Empty_Record_Type::log() const
6024 if (bound_flag
) TTCN_Logger::log_event_str("{ }");
6025 else TTCN_Logger::log_event_unbound();
6028 void Empty_Record_Type::set_param(Module_Param
& param
) {
6029 param
.basic_check(Module_Param::BC_VALUE
, "empty record/set value (i.e. { })");
6030 Module_Param_Ptr mp
= ¶m
;
6031 if (param
.get_type() == Module_Param::MP_Reference
) {
6032 mp
= param
.get_referenced_param();
6034 if (mp
->get_type()!=Module_Param::MP_Value_List
|| mp
->get_size()>0) {
6035 param
.type_error("empty record/set value (i.e. { })", get_descriptor()->name
);
6040 Module_Param
* Empty_Record_Type::get_param(Module_Param_Name
& /* param_name */) const
6043 return new Module_Param_Unbound();
6045 return new Module_Param_Value_List();
6048 void Empty_Record_Type::encode_text(Text_Buf
& /*text_buf*/) const
6051 TTCN_error("Text encoder: Encoding an unbound value of type %s.",
6052 get_descriptor()->name
);
6055 void Empty_Record_Type::decode_text(Text_Buf
& /*text_buf*/)
6060 boolean
Empty_Record_Type::is_equal(const Base_Type
* other_value
) const
6062 const Empty_Record_Type
* r2
= static_cast<const Empty_Record_Type
*>(other_value
);
6063 if ((bound_flag
&& r2
->bound_flag
) || (!bound_flag
&& !r2
->bound_flag
))
6065 if (!bound_flag
|| !r2
->bound_flag
)
6066 TTCN_error("Comparison of an unbound value of type %s.", get_descriptor()->name
);
6070 void Empty_Record_Type::set_value(const Base_Type
* other_value
)
6072 if (!static_cast<const Empty_Record_Type
*>(other_value
)->is_bound())
6073 TTCN_error("Assignment of an unbound value of type %s.",
6074 other_value
->get_descriptor()->name
);
6078 void Empty_Record_Type::encode(const TTCN_Typedescriptor_t
& p_td
,
6079 TTCN_Buffer
& p_buf
, TTCN_EncDec::coding_t p_coding
, ...) const
6082 va_start(pvar
, p_coding
);
6084 case TTCN_EncDec::CT_BER
: {
6085 TTCN_EncDec_ErrorContext
ec("While BER-encoding type '%s': ", p_td
.name
);
6086 unsigned BER_coding
=va_arg(pvar
, unsigned);
6087 BER_encode_chk_coding(BER_coding
);
6088 ASN_BER_TLV_t
*tlv
=BER_encode_TLV(p_td
, BER_coding
);
6089 tlv
->put_in_buffer(p_buf
);
6090 ASN_BER_TLV_t::destruct(tlv
);
6092 case TTCN_EncDec::CT_RAW
: {
6093 TTCN_EncDec_ErrorContext
ec("While RAW-encoding type '%s': ", p_td
.name
);
6094 if(!p_td
.raw
) TTCN_EncDec_ErrorContext::error_internal
6095 ("No RAW descriptor available for type '%s'.", p_td
.name
);
6099 RAW_enc_tree
root(FALSE
, NULL
, &rp
, 1, p_td
.raw
);
6100 RAW_encode(p_td
, root
);
6101 root
.put_to_buf(p_buf
);
6103 case TTCN_EncDec::CT_TEXT
: {
6104 TTCN_EncDec_ErrorContext
ec("While TEXT-encoding type '%s': ", p_td
.name
);
6105 if(!p_td
.text
) TTCN_EncDec_ErrorContext::error_internal
6106 ("No TEXT descriptor available for type '%s'.", p_td
.name
);
6107 TEXT_encode(p_td
,p_buf
);
6109 case TTCN_EncDec::CT_XER
: {
6110 TTCN_EncDec_ErrorContext
ec("While XER-encoding type '%s': ", p_td
.name
);
6111 unsigned XER_coding
=va_arg(pvar
, unsigned);
6112 XER_encode(*(p_td
.xer
),p_buf
, XER_coding
, 0, 0);
6115 case TTCN_EncDec::CT_JSON
: {
6116 TTCN_EncDec_ErrorContext
ec("While JSON-encoding type '%s': ", p_td
.name
);
6117 if(!p_td
.json
) TTCN_EncDec_ErrorContext::error_internal
6118 ("No JSON descriptor available for type '%s'.", p_td
.name
);
6119 JSON_Tokenizer
tok(va_arg(pvar
, int) != 0);
6120 JSON_encode(p_td
, tok
);
6121 p_buf
.put_s(tok
.get_buffer_length(), (const unsigned char*)tok
.get_buffer());
6124 TTCN_error("Unknown coding method requested to encode type '%s'", p_td
.name
);
6129 void Empty_Record_Type::decode(const TTCN_Typedescriptor_t
& p_td
,
6130 TTCN_Buffer
& p_buf
, TTCN_EncDec::coding_t p_coding
, ...)
6133 va_start(pvar
, p_coding
);
6135 case TTCN_EncDec::CT_BER
: {
6136 TTCN_EncDec_ErrorContext
ec("While BER-decoding type '%s': ", p_td
.name
);
6137 unsigned L_form
=va_arg(pvar
, unsigned);
6139 BER_decode_str2TLV(p_buf
, tlv
, L_form
);
6140 BER_decode_TLV(p_td
, tlv
, L_form
);
6141 if(tlv
.isComplete
) p_buf
.increase_pos(tlv
.get_len());
6143 case TTCN_EncDec::CT_RAW
: {
6144 TTCN_EncDec_ErrorContext
ec("While RAW-decoding type '%s': ", p_td
.name
);
6146 TTCN_EncDec_ErrorContext::error_internal
6147 ("No RAW descriptor available for type '%s'.", p_td
.name
);
6149 switch(p_td
.raw
->top_bit_order
) {
6157 if(RAW_decode(p_td
, p_buf
, p_buf
.get_len()*8, order
)<0)
6158 ec
.error(TTCN_EncDec::ET_INCOMPL_MSG
,
6159 "Can not decode type '%s', because invalid or incomplete"
6160 " message was received", p_td
.name
);
6162 case TTCN_EncDec::CT_TEXT
: {
6163 Limit_Token_List limit
;
6164 TTCN_EncDec_ErrorContext
ec("While TEXT-decoding type '%s': ", p_td
.name
);
6165 if(!p_td
.text
) TTCN_EncDec_ErrorContext::error_internal
6166 ("No TEXT descriptor available for type '%s'.", p_td
.name
);
6167 const unsigned char *b
=p_buf
.get_data();
6168 if(b
[p_buf
.get_len()-1]!='\0'){
6169 p_buf
.set_pos(p_buf
.get_len());
6170 p_buf
.put_zero(8,ORDER_LSB
);
6173 if(TEXT_decode(p_td
,p_buf
,limit
)<0)
6174 ec
.error(TTCN_EncDec::ET_INCOMPL_MSG
,
6175 "Can not decode type '%s', because invalid or incomplete"
6176 " message was received", p_td
.name
);
6178 case TTCN_EncDec::CT_XER
: {
6179 TTCN_EncDec_ErrorContext
ec("While XER-decoding type '%s': ", p_td
.name
);
6180 unsigned XER_coding
=va_arg(pvar
, unsigned);
6181 XmlReaderWrap
reader(p_buf
);
6182 for (int success
=reader
.Read(); success
==1; success
=reader
.Read()) {
6183 if (reader
.NodeType() == XML_READER_TYPE_ELEMENT
) break;
6185 XER_decode(*(p_td
.xer
), reader
, XER_coding
| XER_TOPLEVEL
, XER_NONE
, 0);
6186 size_t bytes
= reader
.ByteConsumed();
6187 p_buf
.set_pos(bytes
);
6189 case TTCN_EncDec::CT_JSON
: {
6190 TTCN_EncDec_ErrorContext
ec("While JSON-decoding type '%s': ", p_td
.name
);
6191 if(!p_td
.json
) TTCN_EncDec_ErrorContext::error_internal
6192 ("No JSON descriptor available for type '%s'.", p_td
.name
);
6193 JSON_Tokenizer
tok((const char*)p_buf
.get_data(), p_buf
.get_len());
6194 if(JSON_decode(p_td
, tok
, false)<0)
6195 ec
.error(TTCN_EncDec::ET_INCOMPL_MSG
,
6196 "Can not decode type '%s', because invalid or incomplete"
6197 " message was received", p_td
.name
);
6198 p_buf
.set_pos(tok
.get_buf_pos());
6201 TTCN_error("Unknown coding method requested to decode type '%s'", p_td
.name
);
6206 ASN_BER_TLV_t
* Empty_Record_Type::BER_encode_TLV(const TTCN_Typedescriptor_t
& p_td
,
6207 unsigned p_coding
) const
6209 BER_chk_descr(p_td
);
6210 ASN_BER_TLV_t
*new_tlv
=ASN_BER_TLV_t::construct(NULL
);
6211 new_tlv
=ASN_BER_V2TLV(new_tlv
, p_td
, p_coding
);
6215 boolean
Empty_Record_Type::BER_decode_TLV(const TTCN_Typedescriptor_t
& p_td
,
6216 const ASN_BER_TLV_t
& p_tlv
, unsigned L_form
)
6218 BER_chk_descr(p_td
);
6219 ASN_BER_TLV_t stripped_tlv
;
6220 BER_decode_strip_tags(*p_td
.ber
, p_tlv
, L_form
, stripped_tlv
);
6221 TTCN_EncDec_ErrorContext
ec_0("While decoding '%s' type: ", get_descriptor()->name
);
6222 stripped_tlv
.chk_constructed_flag(TRUE
);
6227 int Empty_Record_Type::RAW_encode(const TTCN_Typedescriptor_t
& p_td
,
6228 RAW_enc_tree
& /*myleaf*/) const
6230 if (!bound_flag
) TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND
,
6231 "Encoding an unbound value of type %s.", p_td
.name
);
6235 int Empty_Record_Type::RAW_decode(const TTCN_Typedescriptor_t
& p_td
,
6236 TTCN_Buffer
& buff
, int /*limit*/, raw_order_t
/*top_bit_ord*/,
6237 boolean
/*no_err*/, int /*sel_field*/, boolean
/*first_call*/)
6240 return buff
.increase_pos_padd(p_td
.raw
->prepadding
)
6241 + buff
.increase_pos_padd(p_td
.raw
->padding
);
6244 int Empty_Record_Type::TEXT_encode(const TTCN_Typedescriptor_t
& p_td
, TTCN_Buffer
& buff
) const
6246 int encoded_length
=0;
6247 if(p_td
.text
->begin_encode
) {
6248 buff
.put_cs(*p_td
.text
->begin_encode
);
6249 encoded_length
+=p_td
.text
->begin_encode
->lengthof();
6252 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND
, "Encoding an unbound value.");
6254 if(p_td
.text
->end_encode
) {
6255 buff
.put_cs(*p_td
.text
->end_encode
);
6256 encoded_length
+=p_td
.text
->end_encode
->lengthof();
6258 return encoded_length
;
6261 int Empty_Record_Type::TEXT_decode(const TTCN_Typedescriptor_t
& p_td
,
6262 TTCN_Buffer
& buff
, Limit_Token_List
& /*limit*/, boolean no_err
, boolean
/*first_call*/)
6264 int decoded_length
=0;
6265 if(p_td
.text
->begin_decode
) {
6267 if((tl
=p_td
.text
->begin_decode
->match_begin(buff
))<0) {
6268 if(no_err
)return -1;
6269 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR
,
6270 "The specified token '%s' not found for '%s': ",
6271 (const char*)*(p_td
.text
->begin_decode
), p_td
.name
);
6275 buff
.increase_pos(tl
);
6277 if(p_td
.text
->end_decode
) {
6279 if((tl
=p_td
.text
->end_decode
->match_begin(buff
))<0) {
6280 if(no_err
)return -1;
6281 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR
,
6282 "The specified token '%s' not found for '%s': ",
6283 (const char*)*(p_td
.text
->end_decode
), p_td
.name
);
6287 buff
.increase_pos(tl
);
6290 return decoded_length
;
6293 int Empty_Record_Type::XER_encode(const XERdescriptor_t
& p_td
,
6294 TTCN_Buffer
& p_buf
, unsigned int flavor
, int indent
, embed_values_enc_struct_t
*) const
6296 int encoded_length
=(int)p_buf
.get_len();
6297 int indenting
= !is_canonical(flavor
);
6298 int exer
= is_exer(flavor
);
6299 if (indenting
) do_indent(p_buf
, indent
);
6301 if (exer
) write_ns_prefix(p_td
, p_buf
);
6302 p_buf
.put_s((size_t)p_td
.namelens
[exer
]-2, (cbyte
*)p_td
.names
[exer
]);
6303 p_buf
.put_s(2 + indenting
, (cbyte
*)"/>\n");
6304 return (int)p_buf
.get_len() - encoded_length
;
6307 int Empty_Record_Type::XER_decode(const XERdescriptor_t
& p_td
,
6308 XmlReaderWrap
& reader
, unsigned int flavor
, unsigned int /*flavor2*/, embed_values_dec_struct_t
*)
6310 int exer
= is_exer(flavor
);
6312 int success
, depth
= -1;
6313 for (success
=reader
.Ok(); success
==1; success
=reader
.Read()) {
6314 int type
= reader
.NodeType();
6315 if (type
==XML_READER_TYPE_ELEMENT
) {
6316 verify_name(reader
, p_td
, exer
);
6317 depth
= reader
.Depth();
6319 if (reader
.IsEmptyElement()) {
6320 reader
.Read(); break;
6322 else if ((flavor
& XER_MASK
) == XER_CANONICAL
) {
6323 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG
,
6324 "Expected an empty element tag");
6325 // Stay in the loop and look for the end element, in case the error
6326 // was ignored or reduced to warning.
6329 else if (type
== XML_READER_TYPE_END_ELEMENT
&& depth
!= -1) {
6330 verify_end(reader
, p_td
, depth
, exer
);
6335 return 1; // decode successful
6338 int Empty_Record_Type::JSON_encode(const TTCN_Typedescriptor_t
&, JSON_Tokenizer
& p_tok
) const
6341 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND
,
6342 "Encoding an unbound empty %s value.", is_set() ? "set" : "record");
6346 return p_tok
.put_next_token(JSON_TOKEN_OBJECT_START
, NULL
) +
6347 p_tok
.put_next_token(JSON_TOKEN_OBJECT_END
, NULL
);
6350 int Empty_Record_Type::JSON_decode(const TTCN_Typedescriptor_t
&, JSON_Tokenizer
& p_tok
, boolean p_silent
)
6352 json_token_t token
= JSON_TOKEN_NONE
;
6353 int dec_len
= p_tok
.get_next_token(&token
, NULL
, NULL
);
6354 if (JSON_TOKEN_ERROR
== token
) {
6355 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG
, JSON_DEC_BAD_TOKEN_ERROR
, "");
6356 return JSON_ERROR_FATAL
;
6358 else if (JSON_TOKEN_OBJECT_START
!= token
) {
6359 return JSON_ERROR_INVALID_TOKEN
;
6362 dec_len
+= p_tok
.get_next_token(&token
, NULL
, NULL
);
6363 if (JSON_TOKEN_OBJECT_END
!= token
) {
6364 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG
, JSON_DEC_STATIC_OBJECT_END_TOKEN_ERROR
, "");
6365 return JSON_ERROR_FATAL
;
6373 boolean
operator==(null_type
/*null_value*/, const Empty_Record_Type
& other_value
)
6375 if (!other_value
.is_bound())
6376 TTCN_error("Comparison of an unbound value of type %s.",
6377 other_value
.get_descriptor()->name
);
6381 boolean
operator!=(null_type
/*null_value*/, const Empty_Record_Type
& other_value
)
6383 if (!other_value
.is_bound())
6384 TTCN_error("Comparison of an unbound value of type %s.",
6385 other_value
.get_descriptor()->name
);