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 int ret_val
= get_at(i
)->JSON_encode(*p_td
.oftype_descr
, p_tok
);
1454 if (0 > ret_val
) break;
1458 enc_len
+= p_tok
.put_next_token(JSON_TOKEN_ARRAY_END
, NULL
);
1462 int Record_Of_Type::JSON_encode_negtest(const Erroneous_descriptor_t
* p_err_descr
,
1463 const TTCN_Typedescriptor_t
& p_td
,
1464 JSON_Tokenizer
& p_tok
) const
1467 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND
,
1468 "Encoding an unbound %s of value.", is_set() ? "set" : "record");
1472 int enc_len
= p_tok
.put_next_token(JSON_TOKEN_ARRAY_START
, NULL
);
1477 for (int i
= 0; i
< get_nof_elements(); ++i
) {
1478 if (-1 != p_err_descr
->omit_before
&& p_err_descr
->omit_before
> i
) {
1482 const Erroneous_values_t
* err_vals
= p_err_descr
->next_field_err_values(i
, values_idx
);
1483 const Erroneous_descriptor_t
* emb_descr
= p_err_descr
->next_field_emb_descr(i
, edescr_idx
);
1485 if (NULL
!= err_vals
&& NULL
!= err_vals
->before
) {
1486 if (NULL
== err_vals
->before
->errval
) {
1487 TTCN_error("internal error: erroneous before value missing");
1489 if (err_vals
->before
->raw
) {
1490 enc_len
+= err_vals
->before
->errval
->JSON_encode_negtest_raw(p_tok
);
1492 if (NULL
== err_vals
->before
->type_descr
) {
1493 TTCN_error("internal error: erroneous before typedescriptor missing");
1495 enc_len
+= err_vals
->before
->errval
->JSON_encode(*(err_vals
->before
->type_descr
), p_tok
);
1499 if (NULL
!= err_vals
&& NULL
!= err_vals
->value
) {
1500 if (NULL
!= err_vals
->value
->errval
) {
1501 if (err_vals
->value
->raw
) {
1502 enc_len
+= err_vals
->value
->errval
->JSON_encode_negtest_raw(p_tok
);
1504 if (NULL
== err_vals
->value
->type_descr
) {
1505 TTCN_error("internal error: erroneous before typedescriptor missing");
1507 enc_len
+= err_vals
->value
->errval
->JSON_encode(*(err_vals
->value
->type_descr
), p_tok
);
1512 if (NULL
!= emb_descr
) {
1513 ret_val
= get_at(i
)->JSON_encode_negtest(emb_descr
, *p_td
.oftype_descr
, p_tok
);
1515 ret_val
= get_at(i
)->JSON_encode(*p_td
.oftype_descr
, p_tok
);
1517 if (0 > ret_val
) break;
1521 if (NULL
!= err_vals
&& NULL
!= err_vals
->after
) {
1522 if (NULL
== err_vals
->after
->errval
) {
1523 TTCN_error("internal error: erroneous after value missing");
1525 if (err_vals
->after
->raw
) {
1526 enc_len
+= err_vals
->after
->errval
->JSON_encode_negtest_raw(p_tok
);
1528 if (NULL
== err_vals
->after
->type_descr
) {
1529 TTCN_error("internal error: erroneous before typedescriptor missing");
1531 enc_len
+= err_vals
->after
->errval
->JSON_encode(*(err_vals
->after
->type_descr
), p_tok
);
1535 if (-1 != p_err_descr
->omit_after
&& p_err_descr
->omit_after
<= i
) {
1540 enc_len
+= p_tok
.put_next_token(JSON_TOKEN_ARRAY_END
, NULL
);
1544 int Record_Of_Type::JSON_decode(const TTCN_Typedescriptor_t
& p_td
, JSON_Tokenizer
& p_tok
, boolean p_silent
)
1546 json_token_t token
= JSON_TOKEN_NONE
;
1547 int dec_len
= p_tok
.get_next_token(&token
, NULL
, NULL
);
1548 if (JSON_TOKEN_ERROR
== token
) {
1549 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG
, JSON_DEC_BAD_TOKEN_ERROR
, "");
1550 return JSON_ERROR_FATAL
;
1552 else if (JSON_TOKEN_ARRAY_START
!= token
) {
1553 return JSON_ERROR_INVALID_TOKEN
;
1558 // Read value tokens until we reach some other token
1559 size_t buf_pos
= p_tok
.get_buf_pos();
1560 Base_Type
* val
= create_elem();
1561 int ret_val
= val
->JSON_decode(*p_td
.oftype_descr
, p_tok
, p_silent
);
1562 if (JSON_ERROR_INVALID_TOKEN
== ret_val
) {
1563 // undo the last action on the buffer
1564 p_tok
.set_buf_pos(buf_pos
);
1568 else if (JSON_ERROR_FATAL
== ret_val
) {
1573 return JSON_ERROR_FATAL
;
1575 if (NULL
== refd_ind_ptr
) {
1576 val_ptr
->value_elements
= (Base_Type
**)reallocate_pointers(
1577 (void**)val_ptr
->value_elements
, val_ptr
->n_elements
, val_ptr
->n_elements
+ 1);
1578 val_ptr
->value_elements
[val_ptr
->n_elements
] = val
;
1579 val_ptr
->n_elements
++;
1582 get_at(get_nof_elements())->set_value(val
);
1588 dec_len
+= p_tok
.get_next_token(&token
, NULL
, NULL
);
1589 if (JSON_TOKEN_ARRAY_END
!= token
) {
1590 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG
, JSON_DEC_REC_OF_END_TOKEN_ERROR
, "");
1594 return JSON_ERROR_FATAL
;
1600 void Record_Of_Type::encode(const TTCN_Typedescriptor_t
& p_td
,
1601 TTCN_Buffer
& p_buf
, TTCN_EncDec::coding_t p_coding
, ...) const
1604 va_start(pvar
, p_coding
);
1606 case TTCN_EncDec::CT_BER
: {
1607 TTCN_EncDec_ErrorContext
ec("While BER-encoding type '%s': ", p_td
.name
);
1608 unsigned BER_coding
=va_arg(pvar
, unsigned);
1609 BER_encode_chk_coding(BER_coding
);
1610 ASN_BER_TLV_t
*tlv
=BER_encode_TLV(p_td
, BER_coding
);
1611 tlv
->put_in_buffer(p_buf
);
1612 ASN_BER_TLV_t::destruct(tlv
);
1614 case TTCN_EncDec::CT_RAW
: {
1615 TTCN_EncDec_ErrorContext
ec("While RAW-encoding type '%s': ", p_td
.name
);
1617 TTCN_EncDec_ErrorContext::error_internal("No RAW descriptor available for type '%s'.", p_td
.name
);
1621 RAW_enc_tree
root(FALSE
, NULL
, &rp
, 1, p_td
.raw
);
1622 RAW_encode(p_td
, root
);
1623 root
.put_to_buf(p_buf
);
1625 case TTCN_EncDec::CT_TEXT
: {
1626 TTCN_EncDec_ErrorContext
ec("While TEXT-encoding type '%s': ", p_td
.name
);
1627 if(!p_td
.text
) TTCN_EncDec_ErrorContext::error_internal
1628 ("No TEXT descriptor available for type '%s'.", p_td
.name
);
1629 TEXT_encode(p_td
,p_buf
);
1631 case TTCN_EncDec::CT_XER
: {
1632 TTCN_EncDec_ErrorContext
ec("While XER-encoding type '%s': ", p_td
.name
);
1633 unsigned XER_coding
=va_arg(pvar
, unsigned);
1634 XER_encode(*(p_td
.xer
),p_buf
, XER_coding
, 0, 0);
1637 case TTCN_EncDec::CT_JSON
: {
1638 TTCN_EncDec_ErrorContext
ec("While JSON-encoding type '%s': ", p_td
.name
);
1639 if(!p_td
.json
) TTCN_EncDec_ErrorContext::error_internal
1640 ("No JSON descriptor available for type '%s'.", p_td
.name
);
1641 JSON_Tokenizer
tok(va_arg(pvar
, int) != 0);
1642 JSON_encode(p_td
, tok
);
1643 p_buf
.put_s(tok
.get_buffer_length(), (const unsigned char*)tok
.get_buffer());
1646 TTCN_error("Unknown coding method requested to encode type '%s'", p_td
.name
);
1651 void Record_Of_Type::decode(const TTCN_Typedescriptor_t
& p_td
,
1652 TTCN_Buffer
& p_buf
, TTCN_EncDec::coding_t p_coding
, ...)
1655 va_start(pvar
, p_coding
);
1657 case TTCN_EncDec::CT_BER
: {
1658 TTCN_EncDec_ErrorContext
ec("While BER-decoding type '%s': ", p_td
.name
);
1659 unsigned L_form
=va_arg(pvar
, unsigned);
1661 BER_decode_str2TLV(p_buf
, tlv
, L_form
);
1662 BER_decode_TLV(p_td
, tlv
, L_form
);
1663 if(tlv
.isComplete
) p_buf
.increase_pos(tlv
.get_len());
1665 case TTCN_EncDec::CT_RAW
: {
1666 TTCN_EncDec_ErrorContext
ec("While RAW-decoding type '%s': ", p_td
.name
);
1667 if(!p_td
.raw
) TTCN_EncDec_ErrorContext::error_internal
1668 ("No RAW descriptor available for type '%s'.", p_td
.name
);
1670 switch(p_td
.raw
->top_bit_order
) {
1678 if(RAW_decode(p_td
, p_buf
, p_buf
.get_len()*8, order
)<0)
1679 ec
.error(TTCN_EncDec::ET_INCOMPL_MSG
,"Can not decode type '%s', "
1680 "because invalid or incomplete message was received", p_td
.name
);
1682 case TTCN_EncDec::CT_TEXT
: {
1683 Limit_Token_List limit
;
1684 TTCN_EncDec_ErrorContext
ec("While TEXT-decoding type '%s': ", p_td
.name
);
1685 if(!p_td
.text
) TTCN_EncDec_ErrorContext::error_internal
1686 ("No TEXT descriptor available for type '%s'.", p_td
.name
);
1687 const unsigned char *b
=p_buf
.get_data();
1688 if(b
[p_buf
.get_len()-1]!='\0'){
1689 p_buf
.set_pos(p_buf
.get_len());
1690 p_buf
.put_zero(8,ORDER_LSB
);
1693 if(TEXT_decode(p_td
,p_buf
,limit
)<0)
1694 ec
.error(TTCN_EncDec::ET_INCOMPL_MSG
,"Can not decode type '%s', "
1695 "because invalid or incomplete message was received", p_td
.name
);
1697 case TTCN_EncDec::CT_XER
: {
1698 TTCN_EncDec_ErrorContext
ec("While XER-decoding type '%s': ", p_td
.name
);
1699 unsigned XER_coding
=va_arg(pvar
, unsigned);
1700 XmlReaderWrap
reader(p_buf
);
1701 for (int success
=reader
.Read(); success
==1; success
=reader
.Read()) {
1702 if (reader
.NodeType() == XML_READER_TYPE_ELEMENT
) break;
1704 XER_decode(*(p_td
.xer
), reader
, XER_coding
| XER_TOPLEVEL
, 0);
1705 size_t bytes
= reader
.ByteConsumed();
1706 p_buf
.set_pos(bytes
);
1708 case TTCN_EncDec::CT_JSON
: {
1709 TTCN_EncDec_ErrorContext
ec("While JSON-decoding type '%s': ", p_td
.name
);
1710 if(!p_td
.json
) TTCN_EncDec_ErrorContext::error_internal
1711 ("No JSON descriptor available for type '%s'.", p_td
.name
);
1712 JSON_Tokenizer
tok((const char*)p_buf
.get_data(), p_buf
.get_len());
1713 if(JSON_decode(p_td
, tok
, false)<0)
1714 ec
.error(TTCN_EncDec::ET_INCOMPL_MSG
,"Can not decode type '%s', "
1715 "because invalid or incomplete message was received", p_td
.name
);
1716 p_buf
.set_pos(tok
.get_buf_pos());
1719 TTCN_error("Unknown coding method requested to decode type '%s'", p_td
.name
);
1724 char **Record_Of_Type::collect_ns(const XERdescriptor_t
& p_td
, size_t& num
, bool& def_ns
) const
1726 size_t num_collected
= 0;
1727 // First, our own namespace. Sets num_collected to 0 or 1.
1728 // If it throws, nothing was allocated.
1729 char **collected_ns
= Base_Type::collect_ns(p_td
, num_collected
, def_ns
);
1731 // Then the embedded type
1733 bool def_ns_1
= false;
1734 if (val_ptr
) for (int i
= 0; i
< get_nof_elements(); ++i
) {
1736 char **new_namespaces
= get_at(i
)->collect_ns(
1737 *p_td
.oftype_descr
, num_new
, def_ns_1
);
1738 merge_ns(collected_ns
, num_collected
, new_namespaces
, num_new
);
1739 def_ns
= def_ns
|| def_ns_1
; // alas, no ||=
1743 // Probably a TC_Error thrown from the element's collect_ns(),
1744 // e.g. if encoding an unbound value.
1745 while (num_collected
> 0) Free(collected_ns
[--num_collected
]);
1750 num
= num_collected
;
1751 return collected_ns
;
1754 static const universal_char sp
= { 0,0,0,' ' };
1755 static const universal_char tb
= { 0,0,0,9 };
1757 int Record_Of_Type::XER_encode(const XERdescriptor_t
& p_td
, TTCN_Buffer
& p_buf
,
1758 unsigned int flavor
, int indent
, embed_values_enc_struct_t
* emb_val
) const
1761 return XER_encode_negtest(err_descr
, p_td
, p_buf
, flavor
, indent
, emb_val
);
1764 if (val_ptr
== 0) TTCN_error(
1765 "Attempt to XER-encode an unbound record of type %s", get_descriptor()->name
);
1766 int encoded_length
= (int)p_buf
.get_len();
1768 const int exer
= is_exer(flavor
);
1769 const boolean own_tag
=
1770 !(exer
&& indent
&& (p_td
.xer_bits
& (ANY_ELEMENT
|ANY_ATTRIBUTES
|UNTAGGED
)));
1772 const int indenting
= !is_canonical(flavor
) && own_tag
;
1773 const boolean xmlValueList
= isXmlValueList();
1776 | ( (exer
&& (p_td
.xer_bits
& XER_LIST
))
1777 || is_exerlist(flavor
) ? SIMPLE_TYPE
: 0);
1778 flavor
&= ~XER_RECOF
; // record-of doesn't care
1779 int nof_elements
= get_nof_elements();
1780 Base_Type::begin_xml(p_td
, p_buf
, flavor
, indent
, !nof_elements
,
1781 (collector_fn
)&Record_Of_Type::collect_ns
);
1783 if (xmlValueList
&& nof_elements
&& indenting
&& !exer
) { /* !exer or GDMO */
1784 do_indent(p_buf
, indent
+1);
1787 if (exer
&& (p_td
.xer_bits
& ANY_ATTRIBUTES
)) {
1788 // Back up over the '>' and the '\n' that may follow it
1789 size_t buf_len
= p_buf
.get_len(), shorter
= 0;
1790 const unsigned char * const buf_data
= p_buf
.get_data();
1791 if (buf_data
[buf_len
- 1 - shorter
] == '\n') ++shorter
;
1792 if (buf_data
[buf_len
- 1 - shorter
] == '>' ) ++shorter
;
1794 unsigned char saved
[4];
1796 memcpy(saved
, buf_data
+ (buf_len
- shorter
), shorter
);
1797 p_buf
.increase_length(-shorter
);
1800 // ANY_ATTRIBUTES means it's a record of universal charstring.
1801 // They are in AnyAttributeFormat (X.693/2008 18.2.6):
1802 // "URI(optional), space, NCName, equals, \"xmlcstring\""
1803 // They need to be written as an XML attribute and namespace declaration:
1804 // xmlns:b0="URI" b0:NCName="xmlcstring"
1806 for (int i
= 0; i
< nof_elements
; ++i
) {
1807 TTCN_EncDec_ErrorContext
ec_0("Attribute %d: ", i
);
1808 if (!is_elem_bound(i
)) {
1809 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND
,
1810 "Encoding an unbound universal charstring value.");
1813 const UNIVERSAL_CHARSTRING
*elem
1814 = static_cast<const UNIVERSAL_CHARSTRING
*>(val_ptr
->value_elements
[i
]);
1815 size_t len
= elem
->lengthof();
1817 const UNIVERSAL_CHARSTRING_ELEMENT
& ue
= (*elem
)[len
- 1];
1818 if (sp
== ue
|| tb
== ue
) --len
;
1821 // sp_at: indexes the first space
1822 // j is left to point at where the attribute name begins (just past the space)
1823 size_t j
, sp_at
= 0;
1824 for (j
= 0; j
< len
; j
++) {
1825 const UNIVERSAL_CHARSTRING_ELEMENT
& ue
= (*elem
)[j
];
1826 if (sp_at
) { // already found a space
1827 if (sp
== ue
|| tb
== ue
) {} // another space, do nothing
1828 else break; // found a non-space after a space
1831 if (sp
== ue
|| tb
== ue
) sp_at
= j
;
1835 size_t buf_start
= p_buf
.get_len();
1837 char * ns
= mprintf(" xmlns:b%d='", i
);
1838 size_t ns_len
= mstrlen(ns
);
1839 p_buf
.put_s(ns_len
, (cbyte
*)ns
);
1841 UNIVERSAL_CHARSTRING
before(sp_at
, (const universal_char
*)(*elem
));
1842 if (p_td
.xer_bits
& (ANY_FROM
| ANY_EXCEPT
)) {
1843 // Ensure the namespace abides to its restrictions
1845 before
.encode_utf8(ns_buf
);
1847 ns_buf
.get_string(cs
);
1848 check_namespace_restrictions(p_td
, (const char*)cs
);
1850 before
.XER_encode(UNIVERSAL_CHARSTRING_xer_
, p_buf
,
1851 flavor
| ANY_ATTRIBUTES
, indent
, 0);
1856 // Keep just the "b%d" part from ns
1857 p_buf
.put_s(ns_len
- 9, (cbyte
*)ns
+ 7);
1865 if (p_td
.xer_bits
& (ANY_FROM
| ANY_EXCEPT
)) {
1866 // Make sure the unqualified namespace is allowed
1867 check_namespace_restrictions(p_td
, NULL
);
1871 UNIVERSAL_CHARSTRING
after(len
- j
, (const universal_char
*)(*elem
) + j
);
1872 after
.XER_encode(UNIVERSAL_CHARSTRING_xer_
, p_buf
,
1873 flavor
| ANY_ATTRIBUTES
, indent
, 0);
1875 // Put this attribute in a dummy element and walk through it to check its validity
1876 TTCN_Buffer check_buf
;
1877 check_buf
.put_s(2, (unsigned char*)"<a");
1878 check_buf
.put_s(p_buf
.get_len() - buf_start
, p_buf
.get_data() + buf_start
);
1879 check_buf
.put_s(2, (unsigned char*)"/>");
1880 XmlReaderWrap
checker(check_buf
);
1881 while (1 == checker
.Read());
1884 p_buf
.put_s(shorter
, saved
); // restore the '>' and anything after
1887 else { // not ANY-ATTRIBUTES
1888 unsigned int sub_flavor
= flavor
| XER_RECOF
| (p_td
.xer_bits
& (XER_LIST
));
1889 TTCN_EncDec_ErrorContext
ec_0("Index ");
1890 TTCN_EncDec_ErrorContext ec_1
;
1892 for (int i
= 0; i
< nof_elements
; ++i
) {
1893 if (i
> 0 && !own_tag
&& 0 != emb_val
&&
1894 emb_val
->embval_index
< emb_val
->embval_array
->size_of()) {
1895 emb_val
->embval_array
->get_at(emb_val
->embval_index
)->XER_encode(
1896 UNIVERSAL_CHARSTRING_xer_
, p_buf
, flavor
| EMBED_VALUES
, indent
+1, 0);
1897 ++emb_val
->embval_index
;
1899 ec_1
.set_msg("%d: ", i
);
1900 if (exer
&& (p_td
.xer_bits
& XER_LIST
) && i
>0) p_buf
.put_c(' ');
1901 get_at(i
)->XER_encode(*p_td
.oftype_descr
, p_buf
,
1902 sub_flavor
, indent
+own_tag
, emb_val
);
1905 if (indenting
&& nof_elements
&& !is_exerlist(flavor
)) {
1906 if (xmlValueList
&& !exer
) p_buf
.put_c('\n'); /* !exer or GDMO */
1907 //do_indent(p_buf, indent);
1911 Base_Type::end_xml(p_td
, p_buf
, flavor
, indent
, !nof_elements
);
1912 return (int)p_buf
.get_len() - encoded_length
;
1915 // XERSTUFF Record_Of_Type::encode_element
1916 /** Helper for Record_Of_Type::XER_encode_negtest
1918 * The main purpose of this method is to allow another type to request
1919 * encoding of a single element of the record-of. Used by Record_Type
1920 * to encode individual strings of the EMBED-VALUES member.
1922 * @param i index of the element
1923 * @param ev erroneous descriptor for the element itself
1924 * @param ed deeper erroneous values
1925 * @param p_buf buffer containing the encoded value
1926 * @param sub_flavor flags
1927 * @param indent indentation level
1928 * @return number of bytes generated
1930 int Record_Of_Type::encode_element(int i
, const XERdescriptor_t
& p_td
,
1931 const Erroneous_values_t
* ev
, const Erroneous_descriptor_t
* ed
,
1932 TTCN_Buffer
& p_buf
, unsigned int sub_flavor
, int indent
, embed_values_enc_struct_t
* emb_val
) const
1934 int enc_len
= p_buf
.get_len();
1935 TTCN_EncDec_ErrorContext ec
;
1936 const int exer
= is_exer(sub_flavor
);
1938 if (ev
&& ev
->before
) {
1939 if (ev
->before
->errval
==NULL
) {
1940 TTCN_error("internal error: erroneous before value missing");
1942 ec
.set_msg("Erroneous value before component #%d: ", i
);
1943 if (ev
->before
->raw
) {
1944 ev
->before
->errval
->encode_raw(p_buf
);
1946 if (ev
->before
->type_descr
==NULL
) TTCN_error(
1947 "internal error: erroneous before type descriptor missing");
1948 ev
->before
->errval
->XER_encode(*ev
->before
->type_descr
->xer
,
1949 p_buf
, sub_flavor
, indent
, 0);
1953 if (exer
&& (sub_flavor
& XER_LIST
)
1954 && (i
> 0 || (ev
&& ev
->before
&& !ev
->before
->raw
))){
1955 // Ensure a separator is written after the "erroneous before"
1956 // of the first element (except for "raw before").
1960 if (ev
&& ev
->value
) {
1961 if (ev
->value
->errval
) { // replace
1962 ec
.set_msg("Erroneous value for component #%d: ", i
);
1963 if (ev
->value
->raw
) {
1964 ev
->value
->errval
->encode_raw(p_buf
);
1966 if (ev
->value
->type_descr
==NULL
) TTCN_error(
1967 "internal error: erroneous value type descriptor missing");
1968 ev
->value
->errval
->XER_encode(*ev
->value
->type_descr
->xer
,
1969 p_buf
, sub_flavor
, indent
, 0);
1973 ec
.set_msg("Component #%d: ", i
);
1975 get_at(i
)->XER_encode_negtest(ed
, p_td
, p_buf
, sub_flavor
, indent
, emb_val
);
1977 // the "real" encoder
1978 get_at(i
)->XER_encode(p_td
, p_buf
, sub_flavor
, indent
, emb_val
);
1982 if (ev
&& ev
->after
) {
1983 if (ev
->after
->errval
==NULL
) {
1984 TTCN_error("internal error: erroneous after value missing");
1986 ec
.set_msg("Erroneous value after component #%d: ", i
);
1987 if (ev
->after
->raw
) {
1988 ev
->after
->errval
->encode_raw(p_buf
);
1990 if (ev
->after
->type_descr
==NULL
) TTCN_error(
1991 "internal error: erroneous after type descriptor missing");
1992 ev
->after
->errval
->XER_encode(*ev
->after
->type_descr
->xer
,
1993 p_buf
, sub_flavor
, indent
, 0);
2000 // XERSTUFF Record_Of_Type::XER_encode_negtest
2001 int Record_Of_Type::XER_encode_negtest(const Erroneous_descriptor_t
* p_err_descr
,
2002 const XERdescriptor_t
& p_td
, TTCN_Buffer
& p_buf
, unsigned flavor
, int indent
,
2003 embed_values_enc_struct_t
* emb_val
) const
2005 if (val_ptr
== 0) TTCN_error(
2006 "Attempt to XER-encode an unbound record of type %s", get_descriptor()->name
);
2007 int encoded_length
= (int)p_buf
.get_len();
2009 const int exer
= is_exer(flavor
);
2010 const boolean own_tag
=
2011 !(exer
&& indent
&& (p_td
.xer_bits
& (ANY_ELEMENT
|ANY_ATTRIBUTES
|UNTAGGED
)));
2013 const int indenting
= !is_canonical(flavor
) && own_tag
;
2014 const boolean xmlValueList
= isXmlValueList();
2017 | ( (exer
&& (p_td
.xer_bits
& XER_LIST
))
2018 || is_exerlist(flavor
) ? SIMPLE_TYPE
: 0);
2019 flavor
&= ~XER_RECOF
; // record-of doesn't care
2020 int nof_elements
= get_nof_elements();
2021 Base_Type::begin_xml(p_td
, p_buf
, flavor
, indent
, !nof_elements
,
2022 (collector_fn
)&Record_Of_Type::collect_ns
);
2024 if (xmlValueList
&& nof_elements
&& indenting
&& !exer
) { /* !exer or GDMO */
2025 do_indent(p_buf
, indent
+1);
2030 if (exer
&& (p_td
.xer_bits
& ANY_ATTRIBUTES
)) {
2031 // Back up over the '>' and the '\n' that may follow it
2032 size_t buf_len
= p_buf
.get_len(), shorter
= 0;
2033 const unsigned char * const buf_data
= p_buf
.get_data();
2034 if (buf_data
[buf_len
- 1 - shorter
] == '\n') ++shorter
;
2035 if (buf_data
[buf_len
- 1 - shorter
] == '>' ) ++shorter
;
2037 unsigned char * saved
= 0;
2039 saved
= new unsigned char[shorter
];
2040 memcpy(saved
, buf_data
+ (buf_len
- shorter
), shorter
);
2041 p_buf
.increase_length(-shorter
);
2044 // ANY_ATTRIBUTES means it's a record of universal charstring.
2045 // They are in AnyAttributeFormat (X.693/2008 18.2.6):
2046 // "URI(optional), space, NCName, equals, \"xmlcstring\""
2047 // They need to be written as an XML attribute and namespace declaration:
2048 // xmlns:b0="URI" b0:NCName="xmlcstring"
2050 for (int i
= 0; i
< nof_elements
; ++i
) {
2051 if (i
< p_err_descr
->omit_before
) continue;
2053 const Erroneous_values_t
*ev
= p_err_descr
->next_field_err_values(i
, values_idx
);
2054 const Erroneous_descriptor_t
*ed
= p_err_descr
->next_field_emb_descr(i
, edescr_idx
);
2056 if (ev
&& ev
->before
) {
2057 if (ev
->before
->errval
==NULL
) TTCN_error("internal error: erroneous value missing");
2060 if (ev
->before
->raw
) ev
->before
->errval
->encode_raw(p_buf
);
2062 if (ev
->before
->type_descr
==NULL
) TTCN_error(
2063 "internal error: erroneous before type descriptor missing");
2064 else ev
->before
->errval
->XER_encode(*ev
->before
->type_descr
->xer
,
2065 p_buf
, flavor
, indent
, 0);
2069 if (ev
&& ev
->value
) { //value replacement
2070 if (ev
->value
->errval
) {
2071 if (ev
->value
->raw
) ev
->value
->errval
->encode_raw(p_buf
);
2073 if (ev
->value
->type_descr
==NULL
) TTCN_error(
2074 "internal error: erroneous value type descriptor missing");
2075 else ev
->value
->errval
->XER_encode(*ev
->value
->type_descr
->xer
,
2076 p_buf
, flavor
, indent
, 0);
2082 // embedded descr.. call negtest (except UNIVERSAL_CHARSTRING
2083 // doesn't have XER_encode_negtest)
2084 TTCN_error("internal error: embedded descriptor for scalar");
2087 // the original encoding
2088 const UNIVERSAL_CHARSTRING
*elem
2089 = static_cast<const UNIVERSAL_CHARSTRING
*>(get_at(i
));
2090 size_t len
= elem
->lengthof();
2092 const UNIVERSAL_CHARSTRING_ELEMENT
& ue
= (*elem
)[len
- 1];
2093 if (sp
== ue
|| tb
== ue
) --len
;
2096 // sp_at: indexes the first space
2097 // j is left to point at where the attribute name begins (just past the space)
2098 size_t j
, sp_at
= 0;
2099 for (j
= 0; j
< len
; j
++) {
2100 const UNIVERSAL_CHARSTRING_ELEMENT
& ue
= (*elem
)[j
];
2101 if (sp_at
) { // already found a space
2102 if (sp
== ue
|| tb
== ue
) {} // another space, do nothing
2103 else break; // found a non-space after a space
2106 if (sp
== ue
|| tb
== ue
) sp_at
= j
;
2111 char * ns
= mprintf(" xmlns:b%d='", i
);
2112 size_t ns_len
= mstrlen(ns
);
2113 p_buf
.put_s(ns_len
, (cbyte
*)ns
);
2115 UNIVERSAL_CHARSTRING
before(sp_at
, (const universal_char
*)(*elem
));
2116 before
.XER_encode(UNIVERSAL_CHARSTRING_xer_
, p_buf
,
2117 flavor
| ANY_ATTRIBUTES
, indent
, 0);
2122 // Keep just the "b%d" part from ns
2123 p_buf
.put_s(ns_len
- 9, (cbyte
*)ns
+ 7);
2132 UNIVERSAL_CHARSTRING
after(len
- j
, (const universal_char
*)(*elem
) + j
);
2133 after
.XER_encode(UNIVERSAL_CHARSTRING_xer_
, p_buf
,
2134 flavor
| ANY_ATTRIBUTES
, indent
, 0);
2138 if (ev
&& ev
->after
) {
2139 if (ev
->after
->errval
==NULL
) TTCN_error(
2140 "internal error: erroneous after value missing");
2142 if (ev
->after
->raw
) ev
->after
->errval
->encode_raw(p_buf
);
2144 if (ev
->after
->type_descr
==NULL
) TTCN_error(
2145 "internal error: erroneous after type descriptor missing");
2146 else ev
->after
->errval
->XER_encode(*ev
->after
->type_descr
->xer
,
2147 p_buf
, flavor
, indent
, 0);
2151 // omit_after value -1 becomes "very big"
2152 if ((unsigned int)i
>= (unsigned int)p_err_descr
->omit_after
) break;
2155 p_buf
.put_s(shorter
, saved
); // restore the '>' and anything after
2159 else { // not ANY-ATTRIBUTES
2160 unsigned int sub_flavor
= flavor
| XER_RECOF
| (p_td
.xer_bits
& (XER_LIST
|ANY_ATTRIBUTES
));
2162 TTCN_EncDec_ErrorContext ec
;
2164 for (int i
= 0; i
< nof_elements
; ++i
) {
2165 if (i
< p_err_descr
->omit_before
) continue;
2167 if (0 != emb_val
&& i
> 0 && !own_tag
&&
2168 emb_val
->embval_index
< emb_val
->embval_array
->size_of()) {
2169 const Erroneous_values_t
* ev0_i
= NULL
;
2170 const Erroneous_descriptor_t
* ed0_i
= NULL
;
2171 if (emb_val
->embval_err
) {
2172 ev0_i
= emb_val
->embval_err
->next_field_err_values(emb_val
->embval_index
, emb_val
->embval_err_val_idx
);
2173 ed0_i
= emb_val
->embval_err
->next_field_emb_descr (emb_val
->embval_index
, emb_val
->embval_err_descr_idx
);
2175 emb_val
->embval_array
->encode_element(emb_val
->embval_index
, UNIVERSAL_CHARSTRING_xer_
,
2176 ev0_i
, ed0_i
, p_buf
, flavor
| EMBED_VALUES
, indent
+ own_tag
, 0);
2177 ++emb_val
->embval_index
;
2180 const Erroneous_values_t
* err_vals
=
2181 p_err_descr
->next_field_err_values(i
, values_idx
);
2182 const Erroneous_descriptor_t
* emb_descr
=
2183 p_err_descr
->next_field_emb_descr (i
, edescr_idx
);
2185 encode_element(i
, *p_td
.oftype_descr
, err_vals
, emb_descr
, p_buf
, sub_flavor
, indent
+own_tag
, emb_val
);
2187 // omit_after value -1 becomes "very big"
2188 if ((unsigned int)i
>= (unsigned int)p_err_descr
->omit_after
) break;
2191 if (indenting
&& nof_elements
&& !is_exerlist(flavor
)) {
2192 if (xmlValueList
&& !exer
) p_buf
.put_c('\n'); /* !exer or GDMO */
2193 //do_indent(p_buf, indent);
2197 Base_Type::end_xml(p_td
, p_buf
, flavor
, indent
, !nof_elements
);
2198 return (int)p_buf
.get_len() - encoded_length
;
2201 int Record_Of_Type::XER_decode(const XERdescriptor_t
& p_td
,
2202 XmlReaderWrap
& reader
, unsigned int flavor
, embed_values_dec_struct_t
* emb_val
)
2204 int exer
= is_exer(flavor
);
2205 int xerbits
= p_td
.xer_bits
;
2206 if (flavor
& XER_TOPLEVEL
) xerbits
&= ~UNTAGGED
;
2208 !(exer
&& ((xerbits
& (ANY_ELEMENT
| ANY_ATTRIBUTES
| UNTAGGED
))
2209 || (flavor
& USE_TYPE_ATTR
))); /* incase the parent has USE-UNION */
2210 /* not toplevel anymore and remove the flags for USE-UNION the oftype doesn't need them */
2211 flavor
&= ~XER_TOPLEVEL
& ~XER_LIST
& ~USE_TYPE_ATTR
;
2212 int success
=1, depth
=-1;
2213 set_val(NULL_VALUE
); // empty but initialized array, val_ptr != NULL
2215 if (own_tag
) for (success
= 1; success
== 1; success
= reader
.Read()) {
2216 type
= reader
.NodeType();
2217 if (exer
&& (p_td
.xer_bits
& XER_ATTRIBUTE
)) {
2218 if (XML_READER_TYPE_ATTRIBUTE
== type
) break;
2220 if (exer
&& (p_td
.xer_bits
& XER_LIST
)) {
2221 if (XML_READER_TYPE_TEXT
== type
) break;
2224 if (XML_READER_TYPE_ELEMENT
== type
) {
2225 verify_name(reader
, p_td
, exer
);
2226 depth
= reader
.Depth();
2229 } /* endif(exer && list) */
2231 else depth
= reader
.Depth();
2232 TTCN_EncDec_ErrorContext
ec_0("Index ");
2233 TTCN_EncDec_ErrorContext ec_1
;
2234 flavor
|= XER_RECOF
;
2235 if (exer
&& (p_td
.xer_bits
& ANY_ATTRIBUTES
)) {
2236 // The enclosing type should handle the decoding.
2237 TTCN_error("Incorrect decoding of ANY-ATTRIBUTES");
2239 else if (exer
&& (p_td
.xer_bits
& XER_LIST
)) { /* LIST decoding*/
2240 char *val
= (char*)reader
.NewValue(); /* we own it */
2242 size_t len
= strlen(val
);
2243 /* The string contains a bunch of values separated by whitespace.
2244 * Tokenize the string and create a new buffer which looks like
2245 * an XML element (<ns:name xmlns:ns='uri'>value</ns:name>), then use that
2246 * to decode the value. */
2247 for(char * str
= strtok(val
, " \t\x0A\x0D"); str
!= 0; str
= strtok(val
+ pos
, " \t\x0A\x0D")) {
2248 // Calling strtok with NULL won't work here, since the decoded element can have strtok calls aswell
2249 pos
+= strlen(str
) + 1;
2250 // Construct a new XML Reader with the current token.
2252 const XERdescriptor_t
& sub_xer
= *p_td
.oftype_descr
;
2254 write_ns_prefix(sub_xer
, buf2
);
2256 boolean i_can_has_ns
= sub_xer
.my_module
!= 0 && sub_xer
.ns_index
!= -1;
2257 const char * const exer_name
= sub_xer
.names
[1];
2258 buf2
.put_s((size_t)sub_xer
.namelens
[1]-1-i_can_has_ns
, (cbyte
*)exer_name
);
2260 const namespace_t
* const pns
= sub_xer
.my_module
->get_ns(sub_xer
.ns_index
);
2261 buf2
.put_s(7 - (*pns
->px
== 0), (cbyte
*)" xmlns:");
2262 buf2
.put_s(strlen(pns
->px
), (cbyte
*)pns
->px
);
2263 buf2
.put_s(2, (cbyte
*)"='");
2264 buf2
.put_s(strlen(pns
->ns
), (cbyte
*)pns
->ns
);
2265 buf2
.put_s(2, (cbyte
*)"'>");
2267 // start tag completed
2268 buf2
.put_s(strlen(str
), (cbyte
*)str
);
2272 write_ns_prefix(sub_xer
, buf2
);
2273 buf2
.put_s((size_t)sub_xer
.namelens
[1], (cbyte
*)exer_name
);
2274 XmlReaderWrap
reader2(buf2
);
2275 reader2
.Read(); // Move to the start element.
2276 // Don't move to the #text, that's the callee's responsibility.
2277 ec_1
.set_msg("%d: ", get_nof_elements());
2278 // The call to the non-const operator[], I mean get_at(), creates
2279 // a new element (because it is indexing one past the last element).
2280 // Then we call its XER_decode with the temporary XML reader.
2281 get_at(get_nof_elements())->XER_decode(sub_xer
, reader2
, flavor
, 0);
2282 if (flavor
& EXIT_ON_ERROR
&& !is_elem_bound(get_nof_elements() - 1)) {
2283 if (1 == get_nof_elements()) {
2284 // Failed to decode even the first element
2287 // Some elements were successfully decoded -> only delete the last one
2288 set_size(get_nof_elements() - 1);
2293 if (pos
>= len
) break;
2296 if (p_td
.xer_bits
& XER_ATTRIBUTE
) {
2297 //Let the caller do reader.AdvanceAttribute();
2300 reader
.Read(); // on closing tag
2301 reader
.Read(); // past it
2305 if (flavor
& PARENT_CLOSED
) {
2306 // Nothing to do. We are probably untagged; do not advance in the XML
2307 // because it would move past the parent.
2309 else if (own_tag
&& reader
.IsEmptyElement()) { // Nothing to do
2310 reader
.Read(); // This is our own empty tag, move past it
2313 /* Note: there is no reader.Read() at the end of the loop below.
2314 * Each element is supposed to consume enough to leave the next element
2315 * well-positioned. */
2316 for (success
= own_tag
? reader
.Read() : reader
.Ok(); success
== 1; ) {
2317 type
= reader
.NodeType();
2318 if (XML_READER_TYPE_ELEMENT
== type
)
2320 if (exer
&& (p_td
.xer_bits
& ANY_ELEMENT
)) {
2321 /* This is a (record-of UNIVERSAL_CHARSTRING) with ANY-ELEMENT.
2322 * The ANY-ELEMENT is really meant for the element type,
2323 * so behave like a record-of (string with ANY-ELEMENT):
2324 * call the non-const operator[], I mean get_at(), to create
2325 * a new element, then read the entire XML element into it. */
2326 UNIVERSAL_CHARSTRING
* uc
=
2327 static_cast<UNIVERSAL_CHARSTRING
*>(get_at(val_ptr
->n_elements
));
2328 const xmlChar
* outer
= reader
.ReadOuterXml();
2329 uc
->decode_utf8(strlen((const char*)outer
), outer
);
2330 // consume the element
2331 for (success
= reader
.Read(); success
== 1 && reader
.Depth() > depth
; success
= reader
.Read()) {}
2332 if (reader
.NodeType() != XML_READER_TYPE_ELEMENT
) success
= reader
.Read(); // one last time
2335 /* If this is an untagged record-of and the start element does not
2336 * belong to the embedded type, the record-of has already ended. */
2337 if (!own_tag
&& !can_start_v(
2338 (const char*)reader
.LocalName(), (const char*)reader
.NamespaceUri(),
2339 p_td
, flavor
| UNTAGGED
))
2341 for (; success
== 1 && reader
.Depth() > depth
; success
= reader
.Read()) ;
2342 // We should now be back at the same depth as we started.
2345 ec_1
.set_msg("%d: ", get_nof_elements());
2346 /* The call to the non-const get_at() creates the element */
2347 get_at(get_nof_elements())->XER_decode(*p_td
.oftype_descr
, reader
, flavor
, emb_val
);
2348 if (0 != emb_val
&& !own_tag
&& get_nof_elements() > 1) {
2349 ++emb_val
->embval_index
;
2353 else if (XML_READER_TYPE_END_ELEMENT
== type
) {
2354 for (; success
== 1 && reader
.Depth() > depth
; success
= reader
.Read()) ;
2355 // If the depth just decreased, this must be an end element
2356 // (but a different one from what we had before the loop)
2358 verify_end(reader
, p_td
, depth
, exer
);
2359 reader
.Read(); // move forward one last time
2363 else if (XML_READER_TYPE_TEXT
== type
&& 0 != emb_val
&& !own_tag
&& get_nof_elements() > 0) {
2364 UNIVERSAL_CHARSTRING
emb_ustr((const char*)reader
.Value());
2365 emb_val
->embval_array
->get_at(emb_val
->embval_index
)->set_value(&emb_ustr
);
2366 success
= reader
.Read();
2369 success
= reader
.Read();
2372 } /* if not empty element */
2374 if (!own_tag
&& exer
&& (p_td
.xer_bits
& XER_OPTIONAL
) && get_nof_elements() == 0) {
2375 // set it to unbound, so the OPTIONAL class sets it to omit
2378 return 1; // decode successful
2381 void Record_Of_Type::set_param(Module_Param
& param
) {
2382 if (dynamic_cast<Module_Param_Name
*>(param
.get_id()) != NULL
&&
2383 param
.get_id()->next_name()) {
2384 // Haven't reached the end of the module parameter name
2385 // => the name refers to one of the elements, not to the whole record of
2386 char* param_field
= param
.get_id()->get_current_name();
2387 if (param_field
[0] < '0' || param_field
[0] > '9') {
2388 param
.error("Unexpected record field name in module parameter, expected a valid"
2389 " index for %s type `%s'", is_set() ? "set of" : "record of", get_descriptor()->name
);
2391 int param_index
= -1;
2392 sscanf(param_field
, "%d", ¶m_index
);
2393 get_at(param_index
)->set_param(param
);
2397 param
.basic_check(Module_Param::BC_VALUE
|Module_Param::BC_LIST
, is_set()?"set of value":"record of value");
2399 Module_Param_Ptr mp
= ¶m
;
2400 if (param
.get_type() == Module_Param::MP_Reference
) {
2401 mp
= param
.get_referenced_param();
2404 switch (param
.get_operation_type()) {
2405 case Module_Param::OT_ASSIGN
:
2406 if (mp
->get_type()==Module_Param::MP_Value_List
&& mp
->get_size()==0) {
2407 set_val(NULL_VALUE
);
2410 switch (mp
->get_type()) {
2411 case Module_Param::MP_Value_List
:
2412 set_size(mp
->get_size());
2413 for (size_t i
=0; i
<mp
->get_size(); ++i
) {
2414 Module_Param
* const curr
= mp
->get_elem(i
);
2415 if (curr
->get_type()!=Module_Param::MP_NotUsed
) {
2416 get_at(i
)->set_param(*curr
);
2420 case Module_Param::MP_Indexed_List
:
2421 for (size_t i
=0; i
<mp
->get_size(); ++i
) {
2422 Module_Param
* const current
= mp
->get_elem(i
);
2423 get_at(current
->get_id()->get_index())->set_param(*current
);
2427 param
.type_error(is_set()?"set of value":"record of value", get_descriptor()->name
);
2430 case Module_Param::OT_CONCAT
:
2431 switch (mp
->get_type()) {
2432 case Module_Param::MP_Value_List
: {
2433 if (!is_bound()) set_val(NULL_VALUE
);
2434 int start_idx
= lengthof();
2435 for (size_t i
=0; i
<mp
->get_size(); ++i
) {
2436 Module_Param
* const curr
= mp
->get_elem(i
);
2437 if ((curr
->get_type()!=Module_Param::MP_NotUsed
)) {
2438 get_at(start_idx
+(int)i
)->set_param(*curr
);
2442 case Module_Param::MP_Indexed_List
:
2443 param
.error("Cannot concatenate an indexed value list");
2446 param
.type_error(is_set()?"set of value":"record of value", get_descriptor()->name
);
2450 TTCN_error("Internal error: Record_Of_Type::set_param()");
2454 Module_Param
* Record_Of_Type::get_param(Module_Param_Name
& param_name
) const
2457 return new Module_Param_Unbound();
2459 if (param_name
.next_name()) {
2460 // Haven't reached the end of the module parameter name
2461 // => the name refers to one of the elements, not to the whole record of
2462 char* param_field
= param_name
.get_current_name();
2463 if (param_field
[0] < '0' || param_field
[0] > '9') {
2464 TTCN_error("Unexpected record field name in module parameter reference, "
2465 "expected a valid index for %s type `%s'",
2466 is_set() ? "set of" : "record of", get_descriptor()->name
);
2468 int param_index
= -1;
2469 sscanf(param_field
, "%d", ¶m_index
);
2470 return get_at(param_index
)->get_param(param_name
);
2472 Vector
<Module_Param
*> values
;
2473 for (int i
= 0; i
< val_ptr
->n_elements
; ++i
) {
2474 values
.push_back(val_ptr
->value_elements
[i
]->get_param(param_name
));
2476 Module_Param_Value_List
* mp
= new Module_Param_Value_List();
2477 mp
->add_list_with_implicit_ids(&values
);
2482 void Record_Of_Type::set_implicit_omit()
2484 for (int i
= 0; i
< get_nof_elements(); ++i
) {
2485 if (is_elem_bound(i
))
2486 val_ptr
->value_elements
[i
]->set_implicit_omit();
2490 void Record_Of_Type::add_refd_index(int index
)
2492 if (NULL
== refd_ind_ptr
) {
2493 refd_ind_ptr
= new refd_index_struct
;
2494 refd_ind_ptr
->max_refd_index
= -1;
2496 refd_ind_ptr
->refd_indices
.push_back(index
);
2497 if (index
> get_max_refd_index()) {
2498 refd_ind_ptr
->max_refd_index
= index
;
2502 void Record_Of_Type::remove_refd_index(int index
)
2504 for (size_t i
= refd_ind_ptr
->refd_indices
.size(); i
> 0; --i
) {
2505 if (refd_ind_ptr
->refd_indices
[i
- 1] == index
) {
2506 refd_ind_ptr
->refd_indices
.erase_at(i
- 1);
2510 if (refd_ind_ptr
->refd_indices
.empty()) {
2511 delete refd_ind_ptr
;
2512 refd_ind_ptr
= NULL
;
2514 else if (get_max_refd_index() == index
) {
2515 refd_ind_ptr
->max_refd_index
= -1;
2519 boolean
operator==(null_type
/*null_value*/, const Record_Of_Type
& other_value
)
2521 if (other_value
.val_ptr
== NULL
)
2522 TTCN_error("The right operand of comparison is an unbound value of type %s.",
2523 other_value
.get_descriptor()->name
);
2524 return other_value
.get_nof_elements() == 0;
2527 boolean
operator!=(null_type null_value
,
2528 const Record_Of_Type
& other_value
)
2530 return !(null_value
== other_value
);
2533 ////////////////////////////////////////////////////////////////////////////////
2535 boolean
Record_Type::is_bound() const
2537 if (bound_flag
) return TRUE
;
2538 int field_cnt
= get_count();
2539 for (int field_idx
=0; field_idx
<field_cnt
; field_idx
++) {
2540 const Base_Type
* temp
= get_at(field_idx
);
2541 if(temp
->is_optional()) {
2542 if(temp
->is_present() && temp
->get_opt_value()->is_bound()) return TRUE
;
2544 if(temp
->is_bound()) return TRUE
;
2549 boolean
Record_Type::is_value() const
2554 int field_cnt
= get_count();
2555 for (int field_idx
=0; field_idx
<field_cnt
; field_idx
++) {
2556 const Base_Type
* temp
= get_at(field_idx
);
2557 if(temp
->is_optional()) {
2558 if(!temp
->is_bound()) return FALSE
;
2559 if(temp
->is_present() && !temp
->is_value()) return FALSE
;
2561 if(!temp
->is_value()) return FALSE
;
2567 void Record_Type::clean_up()
2569 int field_cnt
= get_count();
2570 for (int field_idx
=0; field_idx
<field_cnt
; field_idx
++) {
2571 get_at(field_idx
)->clean_up();
2576 void Record_Type::log() const
2579 TTCN_Logger::log_event_unbound();
2582 TTCN_Logger::log_event_str("{ ");
2583 int field_cnt
= get_count();
2584 for (int field_idx
=0; field_idx
<field_cnt
; field_idx
++) {
2585 if (field_idx
) TTCN_Logger::log_event_str(", ");
2586 TTCN_Logger::log_event_str(fld_name(field_idx
));
2587 TTCN_Logger::log_event_str(" := ");
2588 get_at(field_idx
)->log();
2590 TTCN_Logger::log_event_str(" }");
2591 if (err_descr
) err_descr
->log();
2594 void Record_Type::set_param(Module_Param
& param
) {
2596 if (dynamic_cast<Module_Param_Name
*>(param
.get_id()) != NULL
&&
2597 param
.get_id()->next_name()) {
2598 // Haven't reached the end of the module parameter name
2599 // => the name refers to one of the fields, not to the whole record
2600 char* param_field
= param
.get_id()->get_current_name();
2601 if (param_field
[0] >= '0' && param_field
[0] <= '9') {
2602 param
.error("Unexpected array index in module parameter, expected a valid field"
2603 " name for %s type `%s'", is_set() ? "set" : "record", get_descriptor()->name
);
2605 int field_cnt
= get_count();
2606 for (int field_idx
= 0; field_idx
< field_cnt
; field_idx
++) {
2607 if (strcmp(fld_name(field_idx
), param_field
) == 0) {
2608 get_at(field_idx
)->set_param(param
);
2612 param
.error("Field `%s' not found in %s type `%s'",
2613 param_field
, is_set() ? "set" : "record", get_descriptor()->name
);
2616 param
.basic_check(Module_Param::BC_VALUE
, is_set()?"set value":"record value");
2618 Module_Param_Ptr mp
= ¶m
;
2619 if (param
.get_type() == Module_Param::MP_Reference
) {
2620 mp
= param
.get_referenced_param();
2623 switch (mp
->get_type()) {
2624 case Module_Param::MP_Value_List
:
2625 if (get_count()<(int)mp
->get_size()) {
2626 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());
2628 for (size_t i
=0; i
<mp
->get_size(); i
++) {
2629 Module_Param
* mp_elem
= mp
->get_elem(i
);
2630 if (mp_elem
->get_type()!=Module_Param::MP_NotUsed
) {
2631 get_at((int)i
)->set_param(*mp_elem
);
2635 case Module_Param::MP_Assignment_List
:
2636 for (size_t i
=0; i
<mp
->get_size(); ++i
) {
2637 Module_Param
* const current
= mp
->get_elem(i
);
2639 for (int j
=0; j
<get_count(); ++j
) {
2640 if (!strcmp(fld_name(j
), current
->get_id()->get_name())) {
2641 if (current
->get_type()!=Module_Param::MP_NotUsed
) {
2642 get_at(j
)->set_param(*current
);
2649 current
->error("Non existent field name in type %s: %s.", get_descriptor()->name
, current
->get_id()->get_name());
2654 param
.type_error(is_set()?"set value":"record value", get_descriptor()->name
);
2658 Module_Param
* Record_Type::get_param(Module_Param_Name
& param_name
) const
2661 return new Module_Param_Unbound();
2663 if (param_name
.next_name()) {
2664 // Haven't reached the end of the module parameter name
2665 // => the name refers to one of the fields, not to the whole record
2666 char* param_field
= param_name
.get_current_name();
2667 if (param_field
[0] >= '0' && param_field
[0] <= '9') {
2668 TTCN_error("Unexpected array index in module parameter reference, "
2669 "expected a valid field name for %s type `%s'",
2670 is_set() ? "set" : "record", get_descriptor()->name
);
2672 int field_cnt
= get_count();
2673 for (int field_idx
= 0; field_idx
< field_cnt
; field_idx
++) {
2674 if (strcmp(fld_name(field_idx
), param_field
) == 0) {
2675 return get_at(field_idx
)->get_param(param_name
);
2678 TTCN_error("Field `%s' not found in %s type `%s'",
2679 param_field
, is_set() ? "set" : "record", get_descriptor()->name
);
2681 Module_Param_Assignment_List
* mp
= new Module_Param_Assignment_List();
2682 for (int i
= 0; i
< get_count(); ++i
) {
2683 Module_Param
* mp_field
= get_at(i
)->get_param(param_name
);
2684 mp_field
->set_id(new Module_Param_FieldName(mcopystr(fld_name(i
))));
2685 mp
->add_elem(mp_field
);
2690 void Record_Type::set_implicit_omit()
2692 int field_cnt
= get_count();
2693 for (int field_idx
= 0; field_idx
< field_cnt
; field_idx
++) {
2694 Base_Type
*temp
= get_at(field_idx
);
2695 if (temp
->is_optional()) {
2696 if (temp
->is_bound()) temp
->set_implicit_omit();
2697 else temp
->set_to_omit();
2698 } else if (temp
->is_bound()) {
2699 temp
->set_implicit_omit();
2704 int Record_Type::size_of() const
2707 TTCN_error("Calculating the size of an unbound record/set value of type %s",
2708 get_descriptor()->name
);
2710 int opt_count
= optional_count();
2711 if (opt_count
==0) return get_count();
2712 const int* optional_indexes
= get_optional_indexes();
2713 int my_size
= get_count();
2714 for (int i
=0; i
<opt_count
; i
++) {
2715 if (!get_at(optional_indexes
[i
])->ispresent()) my_size
--;
2720 void Record_Type::encode_text(Text_Buf
& text_buf
) const
2723 TTCN_error("Text encoder: Encoding an unbound record/set value of type %s.",
2724 get_descriptor()->name
);
2726 int field_cnt
= get_count();
2727 for (int field_idx
=0; field_idx
<field_cnt
; field_idx
++)
2728 get_at(field_idx
)->encode_text(text_buf
);
2731 void Record_Type::decode_text(Text_Buf
& text_buf
)
2734 int field_cnt
= get_count();
2735 for (int field_idx
=0; field_idx
<field_cnt
; field_idx
++)
2736 get_at(field_idx
)->decode_text(text_buf
);
2739 boolean
Record_Type::is_equal(const Base_Type
* other_value
) const
2741 const Record_Type
* other_record
= static_cast<const Record_Type
*>(other_value
);
2742 if (!is_bound() && !other_record
->is_bound()) {
2745 int field_cnt
= get_count();
2746 for (int field_idx
=0; field_idx
<field_cnt
; field_idx
++) {
2747 const Base_Type
* elem
= get_at(field_idx
);
2748 const Base_Type
* other_elem
= other_record
->get_at(field_idx
);
2749 if (elem
->is_bound()) {
2750 if (other_elem
->is_bound()) {
2751 if (!elem
->is_equal(other_elem
))
2753 } else return FALSE
;
2754 } else if (other_elem
->is_bound()) return FALSE
;
2759 void Record_Type::set_value(const Base_Type
* other_value
)
2761 if (this==other_value
) return;
2762 if (!other_value
->is_bound())
2763 TTCN_error("Copying an unbound record/set value of type %s.",
2764 other_value
->get_descriptor()->name
);
2765 const Record_Type
* other_record
= static_cast<const Record_Type
*>(other_value
);
2766 int field_cnt
= get_count();
2767 for (int field_idx
=0; field_idx
<field_cnt
; field_idx
++) {
2768 const Base_Type
* elem
= other_record
->get_at(field_idx
);
2769 if (elem
->is_bound()) {
2770 get_at(field_idx
)->set_value(elem
);
2772 get_at(field_idx
)->clean_up();
2775 err_descr
= other_record
->err_descr
;
2779 void Record_Type::encode(const TTCN_Typedescriptor_t
& p_td
,
2780 TTCN_Buffer
& p_buf
, TTCN_EncDec::coding_t p_coding
, ...) const
2783 va_start(pvar
, p_coding
);
2785 case TTCN_EncDec::CT_BER
: {
2786 TTCN_EncDec_ErrorContext
ec("While BER-encoding type '%s': ", p_td
.name
);
2787 unsigned BER_coding
=va_arg(pvar
, unsigned);
2788 BER_encode_chk_coding(BER_coding
);
2789 ASN_BER_TLV_t
*tlv
=BER_encode_TLV(p_td
, BER_coding
);
2790 tlv
->put_in_buffer(p_buf
);
2791 ASN_BER_TLV_t::destruct(tlv
);
2793 case TTCN_EncDec::CT_RAW
: {
2794 TTCN_EncDec_ErrorContext
ec("While RAW-encoding type '%s': ", p_td
.name
);
2795 if(!p_td
.raw
) TTCN_EncDec_ErrorContext::error_internal
2796 ("No RAW descriptor available for type '%s'.", p_td
.name
);
2800 RAW_enc_tree
root(FALSE
, NULL
, &rp
, 1, p_td
.raw
);
2801 RAW_encode(p_td
, root
);
2802 root
.put_to_buf(p_buf
);
2804 case TTCN_EncDec::CT_TEXT
: {
2805 TTCN_EncDec_ErrorContext
ec("While TEXT-encoding type '%s': ", p_td
.name
);
2806 if(!p_td
.text
) TTCN_EncDec_ErrorContext::error_internal
2807 ("No TEXT descriptor available for type '%s'.", p_td
.name
);
2808 TEXT_encode(p_td
,p_buf
);
2810 case TTCN_EncDec::CT_XER
: {
2811 TTCN_EncDec_ErrorContext
ec("While XER-encoding type '%s': ", p_td
.name
);
2812 unsigned XER_coding
=va_arg(pvar
, unsigned);
2813 XER_encode(*(p_td
.xer
),p_buf
, XER_coding
, 0, 0);
2816 case TTCN_EncDec::CT_JSON
: {
2817 TTCN_EncDec_ErrorContext
ec("While JSON-encoding type '%s': ", p_td
.name
);
2818 if(!p_td
.json
) TTCN_EncDec_ErrorContext::error_internal
2819 ("No JSON descriptor available for type '%s'.", p_td
.name
);
2820 JSON_Tokenizer
tok(va_arg(pvar
, int) != 0);
2821 JSON_encode(p_td
, tok
);
2822 p_buf
.put_s(tok
.get_buffer_length(), (const unsigned char*)tok
.get_buffer());
2825 TTCN_error("Unknown coding method requested to encode type '%s'", p_td
.name
);
2830 void Record_Type::decode(const TTCN_Typedescriptor_t
& p_td
,
2831 TTCN_Buffer
& p_buf
, TTCN_EncDec::coding_t p_coding
, ...)
2834 va_start(pvar
, p_coding
);
2836 case TTCN_EncDec::CT_BER
: {
2837 TTCN_EncDec_ErrorContext
ec("While BER-decoding type '%s': ", p_td
.name
);
2838 unsigned L_form
=va_arg(pvar
, unsigned);
2840 BER_decode_str2TLV(p_buf
, tlv
, L_form
);
2841 BER_decode_TLV(p_td
, tlv
, L_form
);
2842 if(tlv
.isComplete
) p_buf
.increase_pos(tlv
.get_len());
2844 case TTCN_EncDec::CT_RAW
: {
2845 TTCN_EncDec_ErrorContext
ec("While RAW-decoding type '%s': ", p_td
.name
);
2847 TTCN_EncDec_ErrorContext::error_internal
2848 ("No RAW descriptor available for type '%s'.", p_td
.name
);
2850 switch(p_td
.raw
->top_bit_order
) {
2858 int rawr
= RAW_decode(p_td
, p_buf
, p_buf
.get_len()*8, order
);
2859 if (rawr
< 0) switch (-rawr
) {
2860 case TTCN_EncDec::ET_INCOMPL_MSG
:
2861 case TTCN_EncDec::ET_LEN_ERR
:
2862 ec
.error(TTCN_EncDec::ET_INCOMPL_MSG
,
2863 "Can not decode type '%s', because incomplete"
2864 " message was received", p_td
.name
);
2867 // The RAW/TEXT decoders return -1 for anything not a length error.
2868 // This is the value for ET_UNBOUND, which can't happen in decoding.
2870 ec
.error(TTCN_EncDec::ET_INVAL_MSG
,
2871 "Can not decode type '%s', because invalid"
2872 " message was received", p_td
.name
);
2876 case TTCN_EncDec::CT_TEXT
: {
2877 Limit_Token_List limit
;
2878 TTCN_EncDec_ErrorContext
ec("While TEXT-decoding type '%s': ", p_td
.name
);
2879 if(!p_td
.text
) TTCN_EncDec_ErrorContext::error_internal
2880 ("No TEXT descriptor available for type '%s'.", p_td
.name
);
2881 const unsigned char *b
=p_buf
.get_data();
2882 if(b
[p_buf
.get_len()-1]!='\0'){
2883 p_buf
.set_pos(p_buf
.get_len());
2884 p_buf
.put_zero(8,ORDER_LSB
);
2887 if(TEXT_decode(p_td
,p_buf
,limit
)<0)
2888 ec
.error(TTCN_EncDec::ET_INCOMPL_MSG
,
2889 "Can not decode type '%s', because invalid or incomplete"
2890 " message was received", p_td
.name
);
2892 case TTCN_EncDec::CT_XER
: {
2893 TTCN_EncDec_ErrorContext
ec("While XER-decoding type '%s': ", p_td
.name
);
2894 unsigned XER_coding
=va_arg(pvar
, unsigned);
2895 XmlReaderWrap
reader(p_buf
);
2896 for (int success
=reader
.Read(); success
==1; success
=reader
.Read()) {
2897 if (reader
.NodeType() == XML_READER_TYPE_ELEMENT
) break;
2899 XER_decode(*(p_td
.xer
), reader
, XER_coding
| XER_TOPLEVEL
, 0);
2900 size_t bytes
= reader
.ByteConsumed();
2901 p_buf
.set_pos(bytes
);
2903 case TTCN_EncDec::CT_JSON
: {
2904 TTCN_EncDec_ErrorContext
ec("While JSON-decoding type '%s': ", p_td
.name
);
2905 if(!p_td
.json
) TTCN_EncDec_ErrorContext::error_internal
2906 ("No JSON descriptor available for type '%s'.", p_td
.name
);
2907 JSON_Tokenizer
tok((const char*)p_buf
.get_data(), p_buf
.get_len());
2908 if(JSON_decode(p_td
, tok
, false)<0)
2909 ec
.error(TTCN_EncDec::ET_INCOMPL_MSG
,
2910 "Can not decode type '%s', because invalid or incomplete"
2911 " message was received", p_td
.name
);
2912 p_buf
.set_pos(tok
.get_buf_pos());
2915 TTCN_error("Unknown coding method requested to decode type '%s'", p_td
.name
);
2920 ASN_BER_TLV_t
* Record_Type::BER_encode_TLV(const TTCN_Typedescriptor_t
& p_td
, unsigned p_coding
) const
2923 return BER_encode_TLV_negtest(err_descr
, p_td
, p_coding
);
2926 TTCN_EncDec_ErrorContext::error
2927 (TTCN_EncDec::ET_UNBOUND
, "Encoding an unbound value.");
2929 BER_chk_descr(p_td
);
2930 ASN_BER_TLV_t
*new_tlv
=ASN_BER_TLV_t::construct(NULL
);
2931 TTCN_EncDec_ErrorContext
ec_0("Component '");
2932 TTCN_EncDec_ErrorContext ec_1
;
2933 int next_default_idx
= 0;
2934 const default_struct
* default_indexes
= get_default_indexes();
2935 int field_cnt
= get_count();
2936 for(int i
=0; i
<field_cnt
; i
++) {
2937 boolean is_default_field
= default_indexes
&& (default_indexes
[next_default_idx
].index
==i
);
2938 if (!default_as_optional() && is_default_field
) {
2939 if (!get_at(i
)->is_equal(default_indexes
[next_default_idx
].value
)) {
2940 ec_1
.set_msg("%s': ", fld_name(i
));
2941 new_tlv
->add_TLV(get_at(i
)->BER_encode_TLV(*fld_descr(i
), p_coding
));
2943 } else { /* is not DEFAULT */
2944 ec_1
.set_msg("%s': ", fld_name(i
));
2945 new_tlv
->add_TLV(get_at(i
)->BER_encode_TLV(*fld_descr(i
), p_coding
));
2947 if (is_default_field
) next_default_idx
++;
2950 if (p_coding
==BER_ENCODE_DER
) new_tlv
->sort_tlvs_tag();
2951 new_tlv
=ASN_BER_V2TLV(new_tlv
, p_td
, p_coding
);
2955 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
2958 TTCN_EncDec_ErrorContext::error
2959 (TTCN_EncDec::ET_UNBOUND
, "Encoding an unbound value.");
2961 BER_chk_descr(p_td
);
2962 ASN_BER_TLV_t
*new_tlv
=ASN_BER_TLV_t::construct(NULL
);
2963 TTCN_EncDec_ErrorContext
ec_0("Component '");
2964 TTCN_EncDec_ErrorContext ec_1
;
2965 int next_default_idx
= 0;
2966 const default_struct
* default_indexes
= get_default_indexes();
2967 int field_cnt
= get_count();
2972 for (int i
=0; i
<field_cnt
; i
++) {
2973 boolean is_default_field
= default_indexes
&& (default_indexes
[next_default_idx
].index
==i
);
2974 // the first condition is not needed, kept for ease of understanding
2975 if ( (p_err_descr
->omit_before
!=-1) && (i
<p_err_descr
->omit_before
) ) {
2976 if (is_default_field
) next_default_idx
++;
2979 const Erroneous_values_t
* err_vals
= p_err_descr
->next_field_err_values(i
, values_idx
);
2980 const Erroneous_descriptor_t
* emb_descr
= p_err_descr
->next_field_emb_descr(i
, edescr_idx
);
2982 if (err_vals
&& err_vals
->before
) {
2983 if (err_vals
->before
->errval
==NULL
) TTCN_error(
2984 "internal error: erroneous before value missing");
2985 ec_1
.set_msg("%s'(erroneous before): ", fld_name(i
));
2986 if (err_vals
->before
->raw
) {
2987 new_tlv
->add_TLV(err_vals
->before
->errval
->BER_encode_negtest_raw());
2989 if (err_vals
->before
->type_descr
==NULL
) TTCN_error(
2990 "internal error: erroneous before typedescriptor missing");
2991 new_tlv
->add_TLV(err_vals
->before
->errval
->BER_encode_TLV(
2992 *err_vals
->before
->type_descr
, p_coding
));
2996 if (err_vals
&& err_vals
->value
) {
2997 if (err_vals
->value
->errval
) { // replace
2998 ec_1
.set_msg("%s'(erroneous value): ", fld_name(i
));
2999 if (err_vals
->value
->raw
) {
3000 new_tlv
->add_TLV(err_vals
->value
->errval
->BER_encode_negtest_raw());
3002 if (err_vals
->value
->type_descr
==NULL
) TTCN_error(
3003 "internal error: erroneous value typedescriptor missing");
3004 new_tlv
->add_TLV(err_vals
->value
->errval
->BER_encode_TLV(
3005 *err_vals
->value
->type_descr
, p_coding
));
3009 if (!default_as_optional() && is_default_field
) {
3010 if (!get_at(i
)->is_equal(default_indexes
[next_default_idx
].value
)) {
3011 ec_1
.set_msg("'%s': ", fld_name(i
));
3013 new_tlv
->add_TLV(get_at(i
)->BER_encode_TLV_negtest(emb_descr
,
3014 *fld_descr(i
), p_coding
));
3016 new_tlv
->add_TLV(get_at(i
)->BER_encode_TLV(*fld_descr(i
), p_coding
));
3019 } else { /* is not DEFAULT */
3020 ec_1
.set_msg("'%s': ", fld_name(i
));
3022 new_tlv
->add_TLV(get_at(i
)->BER_encode_TLV_negtest(emb_descr
,
3023 *fld_descr(i
), p_coding
));
3025 new_tlv
->add_TLV(get_at(i
)->BER_encode_TLV(*fld_descr(i
), p_coding
));
3030 if (err_vals
&& err_vals
->after
) {
3031 if (err_vals
->after
->errval
==NULL
) TTCN_error(
3032 "internal error: erroneous after value missing");
3033 ec_1
.set_msg("%s'(erroneous after): ", fld_name(i
));
3034 if (err_vals
->after
->raw
) {
3035 new_tlv
->add_TLV(err_vals
->after
->errval
->BER_encode_negtest_raw());
3037 if (err_vals
->after
->type_descr
==NULL
) TTCN_error(
3038 "internal error: erroneous after typedescriptor missing");
3039 new_tlv
->add_TLV(err_vals
->after
->errval
->BER_encode_TLV(
3040 *err_vals
->after
->type_descr
, p_coding
));
3044 if (is_default_field
) next_default_idx
++;
3045 if ( (p_err_descr
->omit_after
!=-1) && (i
>=p_err_descr
->omit_after
) ) break;
3049 if (p_coding
==BER_ENCODE_DER
) new_tlv
->sort_tlvs_tag();
3050 new_tlv
=ASN_BER_V2TLV(new_tlv
, p_td
, p_coding
);
3054 boolean
Record_Type::BER_decode_TLV(const TTCN_Typedescriptor_t
& p_td
,
3055 const ASN_BER_TLV_t
& p_tlv
, unsigned L_form
)
3058 BER_chk_descr(p_td
);
3059 ASN_BER_TLV_t stripped_tlv
;
3060 BER_decode_strip_tags(*p_td
.ber
, p_tlv
, L_form
, stripped_tlv
);
3061 TTCN_EncDec_ErrorContext
ec_0("While decoding '%s' type: ", get_descriptor()->name
);
3062 stripped_tlv
.chk_constructed_flag(TRUE
);
3064 ASN_BER_TLV_t tmp_tlv
;
3066 { /* SEQUENCE decoding */
3067 boolean tlv_present
=FALSE
;
3069 TTCN_EncDec_ErrorContext
ec_1("Component '");
3070 TTCN_EncDec_ErrorContext ec_2
;
3071 int next_default_idx
= 0;
3072 int next_optional_idx
= 0;
3073 const default_struct
* default_indexes
= get_default_indexes();
3074 const int* optional_indexes
= get_optional_indexes();
3075 int field_cnt
= get_count();
3076 for(int i
=0; i
<field_cnt
; i
++) {
3077 boolean is_default_field
= default_indexes
&& (default_indexes
[next_default_idx
].index
==i
);
3078 boolean is_optional_field
= optional_indexes
&& (optional_indexes
[next_optional_idx
]==i
);
3079 ec_2
.set_msg("%s': ", fld_descr(i
)->name
);
3080 if (!tlv_present
) tlv_present
=BER_decode_constdTLV_next(stripped_tlv
, V_pos
, L_form
, tmp_tlv
);
3081 if (is_default_field
) { /* is DEFAULT */
3082 if (!tlv_present
|| !get_at(i
)->BER_decode_isMyMsg(*fld_descr(i
), tmp_tlv
)) {
3083 get_at(i
)->set_value(default_indexes
[next_default_idx
].value
);
3085 get_at(i
)->BER_decode_TLV(*fld_descr(i
), tmp_tlv
, L_form
);
3089 else if (is_optional_field
) { /* is OPTIONAL */
3090 if (!tlv_present
) get_at(i
)->set_to_omit();
3092 get_at(i
)->BER_decode_TLV(*fld_descr(i
), tmp_tlv
, L_form
);
3093 if (get_at(i
)->ispresent()) tlv_present
=FALSE
;
3096 else { /* is not DEFAULT OPTIONAL */
3098 ec_2
.error(TTCN_EncDec::ET_INCOMPL_MSG
,"Invalid or incomplete message was received.");
3101 get_at(i
)->BER_decode_TLV(*fld_descr(i
), tmp_tlv
, L_form
);
3104 if (is_default_field
) next_default_idx
++;
3105 if (is_optional_field
) next_optional_idx
++;
3108 BER_decode_constdTLV_end(stripped_tlv
, V_pos
, L_form
, tmp_tlv
, tlv_present
);
3109 } /* SEQUENCE decoding */
3111 { /* SET decoding */
3113 * 0x01: value arrived
3114 * 0x02: is optional / not used :)
3115 * 0x04: has default / not used :)
3117 int field_cnt
= get_count();
3118 unsigned char* fld_indctr
= new unsigned char[field_cnt
];
3119 for (int i
=0; i
<field_cnt
; i
++) fld_indctr
[i
] = 0;
3120 int fld_curr
= -1; /* ellipsis or error... */
3121 while (BER_decode_constdTLV_next(stripped_tlv
, V_pos
, L_form
, tmp_tlv
)) {
3122 for (int i
=0; i
<field_cnt
; i
++) {
3123 if (get_at(i
)->BER_decode_isMyMsg(*fld_descr(i
), tmp_tlv
)) {
3125 TTCN_EncDec_ErrorContext
ec_1("Component '%s': ", fld_name(i
));
3126 get_at(i
)->BER_decode_TLV(*fld_descr(i
), tmp_tlv
, L_form
);
3131 if (fld_indctr
[fld_curr
])
3132 ec_0
.error(TTCN_EncDec::ET_DEC_DUPFLD
, "Duplicated value for component '%s'.", fld_name(fld_curr
));
3133 fld_indctr
[fld_curr
]=1;
3136 int next_default_idx
= 0;
3137 int next_optional_idx
= 0;
3138 const default_struct
* default_indexes
= get_default_indexes();
3139 const int* optional_indexes
= get_optional_indexes();
3140 for (fld_curr
=0; fld_curr
<field_cnt
; fld_curr
++) {
3141 boolean is_default_field
= default_indexes
&& (default_indexes
[next_default_idx
].index
==fld_curr
);
3142 boolean is_optional_field
= optional_indexes
&& (optional_indexes
[next_optional_idx
]==fld_curr
);
3143 if (!fld_indctr
[fld_curr
]) {
3144 if (is_default_field
) get_at(fld_curr
)->set_value(default_indexes
[next_default_idx
].value
);
3145 else if (is_optional_field
) get_at(fld_curr
)->set_to_omit();
3146 else ec_0
.error(TTCN_EncDec::ET_DEC_MISSFLD
, "Missing value for component '%s'.", fld_name(fld_curr
));
3148 if (is_default_field
) next_default_idx
++;
3149 if (is_optional_field
) next_optional_idx
++;
3151 delete[] fld_indctr
;
3152 } /* SET decoding */
3154 if (is_opentype_outermost()) {
3155 TTCN_EncDec_ErrorContext
ec_1("While decoding opentypes: ");
3156 TTCN_Type_list p_typelist
;
3157 BER_decode_opentypes(p_typelist
, L_form
);
3158 } /* if sdef->opentype_outermost */
3162 void Record_Type::BER_decode_opentypes(TTCN_Type_list
& p_typelist
, unsigned L_form
)
3165 p_typelist
.push(this);
3166 TTCN_EncDec_ErrorContext
ec_0("Component '");
3167 TTCN_EncDec_ErrorContext ec_1
;
3168 int field_cnt
= get_count();
3169 for(int i
=0; i
<field_cnt
; i
++) {
3170 ec_1
.set_msg("%s': ", fld_name(i
));
3171 get_at(i
)->BER_decode_opentypes(p_typelist
, L_form
);
3176 int Record_Type::RAW_encode(const TTCN_Typedescriptor_t
& p_td
,
3177 RAW_enc_tree
& myleaf
) const
3179 if (err_descr
) return RAW_encode_negtest(err_descr
, p_td
, myleaf
);
3181 TTCN_EncDec_ErrorContext::error
3182 (TTCN_EncDec::ET_UNBOUND
, "Encoding an unbound value.");
3184 int encoded_length
= 0;
3185 int field_cnt
= get_count();
3186 myleaf
.isleaf
= false;
3187 myleaf
.body
.node
.num_of_nodes
= field_cnt
;
3188 myleaf
.body
.node
.nodes
= init_nodes_of_enc_tree(field_cnt
);
3190 int next_optional_idx
= 0;
3191 const int* optional_indexes
= get_optional_indexes();
3192 for (int i
= 0; i
< field_cnt
; i
++) {
3193 boolean is_optional_field
= optional_indexes
3194 && (optional_indexes
[next_optional_idx
] == i
);
3195 if (!is_optional_field
|| get_at(i
)->ispresent()) {
3196 myleaf
.body
.node
.nodes
[i
] = new RAW_enc_tree(true, &myleaf
,
3197 &(myleaf
.curr_pos
), i
, fld_descr(i
)->raw
);
3200 myleaf
.body
.node
.nodes
[i
] = NULL
;
3202 if (is_optional_field
) next_optional_idx
++;
3204 next_optional_idx
= 0;
3205 for (int i
= 0; i
< field_cnt
; i
++) { /*encoding fields*/
3206 boolean is_optional_field
= optional_indexes
3207 && (optional_indexes
[next_optional_idx
] == i
);
3208 /* encoding of normal fields*/
3209 const Base_Type
*field
= get_at(i
);
3210 if (is_optional_field
) {
3211 next_optional_idx
++;
3212 if (!field
->ispresent())
3213 continue; // do not encode
3215 field
= field
->get_opt_value(); // "reach into" the optional
3217 encoded_length
+= field
->RAW_encode(*fld_descr(i
),
3218 *myleaf
.body
.node
.nodes
[i
]);
3220 return myleaf
.length
= encoded_length
;
3223 // In some cases (e.g. LENGTHTO, POINTERTO, CROSSTAG) it is not generated.
3224 int Record_Type::RAW_encode_negtest(const Erroneous_descriptor_t
*p_err_descr
,
3225 const TTCN_Typedescriptor_t
& /*p_td*/, RAW_enc_tree
& myleaf
) const
3228 TTCN_EncDec_ErrorContext::error
3229 (TTCN_EncDec::ET_UNBOUND
, "Encoding an unbound value.");
3231 int encoded_length
= 0;
3232 int num_fields
= get_count();
3233 myleaf
.isleaf
= false;
3234 myleaf
.body
.node
.num_of_nodes
= 0;
3235 for (int field_idx
= 0; field_idx
< num_fields
; ++field_idx
) {
3236 if ((p_err_descr
->omit_before
!= -1) &&
3237 (field_idx
< p_err_descr
->omit_before
))
3239 else ++myleaf
.body
.node
.num_of_nodes
;
3240 const Erroneous_values_t
*err_vals
= p_err_descr
->get_field_err_values(field_idx
);
3241 if (err_vals
&& err_vals
->before
)
3242 ++myleaf
.body
.node
.num_of_nodes
;
3243 if (err_vals
&& err_vals
->value
&& !err_vals
->value
->errval
)
3244 --myleaf
.body
.node
.num_of_nodes
;
3245 if (err_vals
&& err_vals
->after
)
3246 ++myleaf
.body
.node
.num_of_nodes
;
3247 if ((p_err_descr
->omit_after
!= -1) &&
3248 (field_idx
>= p_err_descr
->omit_after
))
3251 myleaf
.body
.node
.nodes
= init_nodes_of_enc_tree(myleaf
.body
.node
.num_of_nodes
);
3252 TTCN_EncDec_ErrorContext ec
;
3253 int next_optional_idx
= 0;
3254 const int *my_optional_indexes
= get_optional_indexes();
3255 // Counter for fields and additional before/after fields.
3257 for (int field_idx
= 0; field_idx
< num_fields
; ++field_idx
) {
3258 boolean is_optional_field
= my_optional_indexes
&&
3259 (my_optional_indexes
[next_optional_idx
] == field_idx
);
3260 if ((p_err_descr
->omit_before
!= -1) &&
3261 (field_idx
< p_err_descr
->omit_before
)) {
3262 if (is_optional_field
) ++next_optional_idx
;
3265 const Erroneous_values_t
*err_vals
= p_err_descr
->get_field_err_values(field_idx
);
3266 const Erroneous_descriptor_t
*emb_descr
= p_err_descr
->get_field_emb_descr(field_idx
);
3267 if (err_vals
&& err_vals
->before
) {
3268 if (err_vals
->before
->errval
== NULL
)
3269 TTCN_error("internal error: erroneous before value missing");
3270 if (err_vals
->before
->raw
) {
3271 myleaf
.body
.node
.nodes
[node_pos
] =
3272 new RAW_enc_tree(true, &myleaf
, &(myleaf
.curr_pos
), node_pos
,
3273 err_vals
->before
->errval
->get_descriptor()->raw
);
3274 encoded_length
+= err_vals
->before
->errval
->
3275 RAW_encode_negtest_raw(*myleaf
.body
.node
.nodes
[node_pos
++]);
3277 if (err_vals
->before
->type_descr
== NULL
)
3278 TTCN_error("internal error: erroneous before typedescriptor missing");
3279 myleaf
.body
.node
.nodes
[node_pos
] =
3280 new RAW_enc_tree(true, &myleaf
, &(myleaf
.curr_pos
), node_pos
,
3281 err_vals
->before
->type_descr
->raw
);
3282 encoded_length
+= err_vals
->before
->errval
->
3283 RAW_encode(*(err_vals
->before
->type_descr
),
3284 *myleaf
.body
.node
.nodes
[node_pos
++]);
3287 if (err_vals
&& err_vals
->value
) {
3288 if (err_vals
->value
->errval
) {
3289 ec
.set_msg("'%s'(erroneous value): ", fld_name(field_idx
));
3290 if (err_vals
->value
->raw
) {
3291 myleaf
.body
.node
.nodes
[node_pos
] =
3292 new RAW_enc_tree(true, &myleaf
, &(myleaf
.curr_pos
), node_pos
,
3293 err_vals
->value
->errval
->get_descriptor()->raw
);
3294 encoded_length
+= err_vals
->value
->errval
->
3295 RAW_encode_negtest_raw(*myleaf
.body
.node
.nodes
[node_pos
++]);
3297 if (err_vals
->value
->type_descr
== NULL
)
3298 TTCN_error("internal error: erroneous value typedescriptor missing");
3299 myleaf
.body
.node
.nodes
[node_pos
] =
3300 new RAW_enc_tree(true, &myleaf
, &(myleaf
.curr_pos
), node_pos
,
3301 err_vals
->value
->type_descr
->raw
);
3302 encoded_length
+= err_vals
->value
->errval
->
3303 RAW_encode(*(err_vals
->value
->type_descr
),
3304 *myleaf
.body
.node
.nodes
[node_pos
++]);
3308 ec
.set_msg("'%s': ", fld_name(field_idx
));
3309 if (!is_optional_field
|| get_at(field_idx
)->ispresent()) {
3310 const Base_Type
*field
=
3311 is_optional_field
? get_at(field_idx
)->get_opt_value()
3312 : get_at(field_idx
);
3313 myleaf
.body
.node
.nodes
[node_pos
] =
3314 new RAW_enc_tree(true, &myleaf
, &(myleaf
.curr_pos
), node_pos
,
3315 fld_descr(field_idx
)->raw
);
3318 field
->RAW_encode_negtest(emb_descr
, *fld_descr(field_idx
),
3319 *myleaf
.body
.node
.nodes
[node_pos
++]);
3322 field
->RAW_encode(*fld_descr(field_idx
),
3323 *myleaf
.body
.node
.nodes
[node_pos
++]);
3327 myleaf
.body
.node
.nodes
[node_pos
++] = NULL
;
3330 if (err_vals
&& err_vals
->after
) {
3331 if (err_vals
->after
->errval
== NULL
)
3332 TTCN_error("internal error: erroneous before value missing");
3333 if (err_vals
->after
->raw
) {
3334 myleaf
.body
.node
.nodes
[node_pos
] =
3335 new RAW_enc_tree(true, &myleaf
, &(myleaf
.curr_pos
), node_pos
,
3336 err_vals
->after
->errval
->get_descriptor()->raw
);
3337 encoded_length
+= err_vals
->after
->errval
->
3338 RAW_encode_negtest_raw(*myleaf
.body
.node
.nodes
[node_pos
++]);
3340 if (err_vals
->after
->type_descr
== NULL
)
3341 TTCN_error("internal error: erroneous after typedescriptor missing");
3342 myleaf
.body
.node
.nodes
[node_pos
] =
3343 new RAW_enc_tree(true, &myleaf
, &(myleaf
.curr_pos
), node_pos
,
3344 err_vals
->after
->type_descr
->raw
);
3345 encoded_length
+= err_vals
->after
->errval
->
3346 RAW_encode(*(err_vals
->after
->type_descr
),
3347 *myleaf
.body
.node
.nodes
[node_pos
++]);
3350 if (is_optional_field
) ++next_optional_idx
;
3351 if ((p_err_descr
->omit_after
!= -1) &&
3352 (field_idx
>= p_err_descr
->omit_after
))
3355 return myleaf
.length
= encoded_length
;
3358 int Record_Type::RAW_decode(const TTCN_Typedescriptor_t
& p_td
, TTCN_Buffer
& buff
,
3359 int limit
, raw_order_t top_bit_ord
, boolean no_err
, int, boolean
)
3362 int field_cnt
= get_count();
3363 int opt_cnt
= optional_count();
3364 int mand_num
= field_cnt
- opt_cnt
; // expected mandatory fields
3366 raw_order_t local_top_order
;
3367 if (p_td
.raw
->top_bit_order
== TOP_BIT_INHERITED
) local_top_order
= top_bit_ord
;
3368 else if (p_td
.raw
->top_bit_order
== TOP_BIT_RIGHT
) local_top_order
= ORDER_MSB
;
3369 else local_top_order
= ORDER_LSB
;
3371 if (is_set()) { /* set decoder start*/
3372 int prepaddlength
= buff
.increase_pos_padd(p_td
.raw
->prepadding
);
3373 limit
-= prepaddlength
;
3374 int decoded_length
= 0;
3375 int * const field_map
= new int[field_cnt
];
3376 memset(field_map
, 0, field_cnt
* sizeof(int));
3377 int nof_mand_fields
= 0; // mandatory fields actually decoded
3379 const int* optional_indexes
= get_optional_indexes();
3380 for (int i
=0; i
<opt_cnt
; i
++) get_at(optional_indexes
[i
])->set_to_omit();
3383 size_t fl_start_pos
= buff
.get_pos_bit();
3384 int next_optional_idx
= 0;
3385 const int* optional_indexes
= get_optional_indexes();
3386 for (int i
=0; i
<field_cnt
; i
++) { /* decoding fields without TAG */
3387 boolean is_optional_field
= optional_indexes
&& (optional_indexes
[next_optional_idx
]==i
);
3388 if (field_map
[i
] == 0) {
3389 Base_Type
* field_ptr
= get_at(i
);
3390 if (is_optional_field
) {
3391 field_ptr
->set_to_present();
3392 field_ptr
=field_ptr
->get_opt_value();
3394 int decoded_field_length
= field_ptr
->RAW_decode(*fld_descr(i
), buff
,
3395 limit
, local_top_order
, TRUE
);
3396 if ( (is_optional_field
&& (decoded_field_length
>0)) ||
3397 (!is_optional_field
&& (decoded_field_length
>=0)) ) {
3398 decoded_length
+= decoded_field_length
;
3399 limit
-= decoded_field_length
;
3400 if (!is_optional_field
) nof_mand_fields
++;
3402 goto continue_while
;
3404 buff
.set_pos_bit(fl_start_pos
);
3405 if (is_optional_field
) get_at(i
)->set_to_omit();
3408 if (is_optional_field
) next_optional_idx
++;
3410 break; // no field could be decoded successfully, quit
3414 if (mand_num
> 0 && nof_mand_fields
!= mand_num
) {
3415 /* Not all required fields were decoded. If there are no bits left,
3416 * that means that the last field was decoded successfully but used up
3417 * the buffer. Signal "incomplete". If there were bits left, that means
3418 * no field could be decoded from them; signal an error. */
3419 return limit
? -1 : -TTCN_EncDec::ET_INCOMPL_MSG
;
3421 return decoded_length
+ prepaddlength
+ buff
.increase_pos_padd(p_td
.raw
->padding
);
3422 } else { /* record decoder start */
3423 int prepaddlength
= buff
.increase_pos_padd(p_td
.raw
->prepadding
);
3424 limit
-= prepaddlength
;
3425 size_t last_decoded_pos
= buff
.get_pos_bit();
3426 size_t fl_start_pos
;
3427 int decoded_length
= 0;
3428 int decoded_field_length
= 0;
3429 if (raw_has_ext_bit()) {
3430 const unsigned char* data
=buff
.get_read_data();
3432 unsigned mask
= 1 << (local_top_order
==ORDER_LSB
? 0 : 7);
3433 if (p_td
.raw
->extension_bit
==EXT_BIT_YES
) {
3434 while((data
[count
-1] & mask
) == 0 && count
* 8 < (int)limit
) count
++;
3437 while((data
[count
-1] & mask
) != 0 && count
* 8 < (int)limit
) count
++;
3439 if(limit
) limit
=count
*8;
3442 int next_optional_idx
= 0;
3443 const int* optional_indexes
= get_optional_indexes();
3444 for (int i
=0; i
<field_cnt
; i
++) { /* decoding fields */
3445 boolean is_optional_field
= optional_indexes
&& (optional_indexes
[next_optional_idx
]==i
);
3446 /* check if enough bits to decode the field*/
3447 if (!is_optional_field
|| (limit
>0)) {
3448 /* decoding of normal field */
3449 fl_start_pos
= buff
.get_pos_bit();
3450 Base_Type
* field_ptr
= get_at(i
);
3451 if (is_optional_field
) {
3452 field_ptr
->set_to_present();
3453 field_ptr
=field_ptr
->get_opt_value();
3455 decoded_field_length
= field_ptr
->RAW_decode(*fld_descr(i
), buff
, limit
,
3456 local_top_order
, is_optional_field
? TRUE
: no_err
);
3457 boolean field_present
= TRUE
;
3458 if (is_optional_field
) {
3459 if (decoded_field_length
< 1) { // swallow any error and become omit
3460 field_present
= FALSE
;
3461 get_at(i
)->set_to_omit();
3462 buff
.set_pos_bit(fl_start_pos
);
3465 if (decoded_field_length
< 0) return decoded_field_length
;
3467 if (field_present
) {
3468 decoded_length
+=decoded_field_length
;
3469 limit
-=decoded_field_length
;
3470 last_decoded_pos
=last_decoded_pos
<buff
.get_pos_bit()?buff
.get_pos_bit():last_decoded_pos
;
3473 get_at(i
)->set_to_omit();
3475 if (is_optional_field
) next_optional_idx
++;
3476 } /* decoding fields*/
3478 buff
.set_pos_bit(last_decoded_pos
);
3479 return decoded_length
+prepaddlength
+buff
.increase_pos_padd(p_td
.raw
->padding
);
3480 } /* record decoder end*/
3483 int Record_Type::TEXT_encode(const TTCN_Typedescriptor_t
& p_td
, TTCN_Buffer
& buff
) const
3486 return TEXT_encode_negtest(err_descr
, p_td
, buff
);
3489 TTCN_EncDec_ErrorContext::error
3490 (TTCN_EncDec::ET_UNBOUND
, "Encoding an unbound value.");
3492 bool need_separator
=false;
3493 int encoded_length
=0;
3494 if (p_td
.text
->begin_encode
) {
3495 buff
.put_cs(*p_td
.text
->begin_encode
);
3496 encoded_length
+=p_td
.text
->begin_encode
->lengthof();
3498 int next_optional_idx
= 0;
3499 const int* optional_indexes
= get_optional_indexes();
3500 int field_cnt
= get_count();
3501 for(int i
=0;i
<field_cnt
;i
++) {
3502 boolean is_optional_field
= optional_indexes
&& (optional_indexes
[next_optional_idx
]==i
);
3503 if (!is_optional_field
|| get_at(i
)->ispresent()) {
3504 if (need_separator
&& p_td
.text
->separator_encode
) {
3505 buff
.put_cs(*p_td
.text
->separator_encode
);
3506 encoded_length
+=p_td
.text
->separator_encode
->lengthof();
3508 encoded_length
+= get_at(i
)->TEXT_encode(*fld_descr(i
),buff
);
3509 need_separator
=true;
3511 if (is_optional_field
) next_optional_idx
++;
3513 if (p_td
.text
->end_encode
) {
3514 buff
.put_cs(*p_td
.text
->end_encode
);
3515 encoded_length
+=p_td
.text
->end_encode
->lengthof();
3517 return encoded_length
;
3521 * TEXT encode negative testing
3523 int Record_Type::TEXT_encode_negtest(const Erroneous_descriptor_t
* p_err_descr
, const TTCN_Typedescriptor_t
& p_td
, TTCN_Buffer
& buff
) const
3526 TTCN_EncDec_ErrorContext::error
3527 (TTCN_EncDec::ET_UNBOUND
, "Encoding an unbound value.");
3529 bool need_separator
=false;
3530 int encoded_length
=0;
3531 if (p_td
.text
->begin_encode
) {
3532 buff
.put_cs(*p_td
.text
->begin_encode
);
3533 encoded_length
+=p_td
.text
->begin_encode
->lengthof();
3535 int next_optional_idx
= 0;
3536 const int* optional_indexes
= get_optional_indexes();
3537 int field_cnt
= get_count();
3542 for(int i
=0;i
<field_cnt
;i
++) {
3543 boolean is_optional_field
= optional_indexes
&& (optional_indexes
[next_optional_idx
]==i
);
3545 if ( (p_err_descr
->omit_before
!=-1) && (i
<p_err_descr
->omit_before
) ) {
3546 if (is_optional_field
) next_optional_idx
++;
3550 const Erroneous_values_t
* err_vals
= p_err_descr
->next_field_err_values(i
, values_idx
);
3551 const Erroneous_descriptor_t
* emb_descr
= p_err_descr
->next_field_emb_descr(i
, edescr_idx
);
3553 if (err_vals
&& err_vals
->before
) {
3554 if (err_vals
->before
->errval
==NULL
) TTCN_error(
3555 "internal error: erroneous before value missing");
3557 if (need_separator
&& p_td
.text
->separator_encode
) {
3558 buff
.put_cs(*p_td
.text
->separator_encode
);
3559 encoded_length
+=p_td
.text
->separator_encode
->lengthof();
3561 if (err_vals
->before
->raw
) {
3562 encoded_length
+= err_vals
->before
->errval
->encode_raw(buff
);
3564 if (err_vals
->before
->type_descr
==NULL
) TTCN_error(
3565 "internal error: erroneous before typedescriptor missing");
3566 encoded_length
+= err_vals
->before
->errval
->TEXT_encode(
3567 *(err_vals
->before
->type_descr
),buff
);
3569 need_separator
=true;
3572 if (err_vals
&& err_vals
->value
) {
3573 if (err_vals
->value
->errval
) {
3574 if (need_separator
&& p_td
.text
->separator_encode
) {
3575 buff
.put_cs(*p_td
.text
->separator_encode
);
3576 encoded_length
+=p_td
.text
->separator_encode
->lengthof();
3578 if (err_vals
->value
->raw
) {
3579 encoded_length
+= err_vals
->value
->errval
->encode_raw(buff
);
3581 if (err_vals
->value
->type_descr
==NULL
) TTCN_error(
3582 "internal error: erroneous value typedescriptor missing");
3583 encoded_length
+= err_vals
->value
->errval
->TEXT_encode(
3584 *(err_vals
->value
->type_descr
),buff
);
3586 need_separator
=true;
3589 if (!is_optional_field
|| get_at(i
)->ispresent()) {
3590 if (need_separator
&& p_td
.text
->separator_encode
) {
3591 buff
.put_cs(*p_td
.text
->separator_encode
);
3592 encoded_length
+=p_td
.text
->separator_encode
->lengthof();
3595 encoded_length
+= get_at(i
)->TEXT_encode_negtest(emb_descr
, *fld_descr(i
),buff
);
3597 encoded_length
+= get_at(i
)->TEXT_encode(*fld_descr(i
),buff
);
3599 need_separator
=true;
3603 if (err_vals
&& err_vals
->after
) {
3604 if (err_vals
->after
->errval
==NULL
) TTCN_error(
3605 "internal error: erroneous after value missing");
3606 if (need_separator
&& p_td
.text
->separator_encode
) {
3607 buff
.put_cs(*p_td
.text
->separator_encode
);
3608 encoded_length
+=p_td
.text
->separator_encode
->lengthof();
3610 if (err_vals
->after
->raw
) {
3611 encoded_length
+= err_vals
->after
->errval
->encode_raw(buff
);
3613 if (err_vals
->after
->type_descr
==NULL
) TTCN_error(
3614 "internal error: erroneous after typedescriptor missing");
3615 encoded_length
+= err_vals
->after
->errval
->TEXT_encode(
3616 *(err_vals
->after
->type_descr
),buff
);
3618 need_separator
=true;
3621 if (is_optional_field
) next_optional_idx
++;
3623 if ( (p_err_descr
->omit_after
!=-1) && (i
>=p_err_descr
->omit_after
) ) break;
3625 if (p_td
.text
->end_encode
) {
3626 buff
.put_cs(*p_td
.text
->end_encode
);
3627 encoded_length
+=p_td
.text
->end_encode
->lengthof();
3629 return encoded_length
;
3632 int Record_Type::TEXT_decode(const TTCN_Typedescriptor_t
& p_td
, TTCN_Buffer
& buff
,
3633 Limit_Token_List
& limit
, boolean no_err
, boolean
/*first_call*/)
3637 int decoded_length
=0;
3638 int decoded_field_length
=0;
3639 size_t pos
=buff
.get_pos();
3640 boolean sep_found
=FALSE
;
3643 int loop_detector
=1;
3644 int last_field_num
=-1;
3645 if (p_td
.text
->begin_decode
) {
3647 if ((tl
=p_td
.text
->begin_decode
->match_begin(buff
))<0) {
3648 if(no_err
) return -1;
3649 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR
,
3650 "The specified token '%s' not found for '%s': ",
3651 (const char*)*(p_td
.text
->begin_decode
), p_td
.name
);
3655 buff
.increase_pos(tl
);
3657 if (p_td
.text
->end_decode
) {
3658 limit
.add_token(p_td
.text
->end_decode
);
3661 if(p_td
.text
->separator_decode
){
3662 limit
.add_token(p_td
.text
->separator_decode
);
3666 int field_cnt
= get_count();
3667 int * const field_map
= new int[field_cnt
];
3668 memset(field_map
, 0, field_cnt
* sizeof(int));
3670 int mand_field_num
= 0;
3671 int opt_field_num
= 0;
3673 int has_repeatable
=0;
3674 boolean repeatable
= TRUE
;
3676 int next_optional_idx
= 0;
3677 const int* optional_indexes
= get_optional_indexes();
3678 for (int i
=0;i
<field_cnt
;i
++) {
3679 boolean is_optional_field
= optional_indexes
&& (optional_indexes
[next_optional_idx
]==i
);
3680 if (is_optional_field
) {
3681 get_at(i
)->set_to_omit();
3686 if (get_at(i
)->is_seof()) {
3688 repeatable
= repeatable
&& fld_descr(i
)->text
->val
.parameters
->decoding_params
.repeatable
;
3690 if (is_optional_field
) next_optional_idx
++;
3692 boolean has_optinals
= opt_field_num
> 0;
3693 if ((seof
>0) && repeatable
) has_repeatable
=1;
3695 while (mand_field_num
+opt_field_num
+has_repeatable
) {
3699 next_optional_idx
= 0;
3700 for (int i
=0;i
<field_cnt
;i
++) {
3701 boolean is_optional_field
= optional_indexes
&& (optional_indexes
[next_optional_idx
]==i
);
3702 if (get_at(i
)->is_seof()) {
3703 if ( (fld_descr(i
)->text
->val
.parameters
->decoding_params
.repeatable
&& field_map
[i
]<3)
3704 || !field_map
[i
] ) {
3706 decoded_field_length
= get_at(i
)->TEXT_decode(*fld_descr(i
),buff
, limit
, true,!field_map
[i
]);
3707 if (decoded_field_length
<0) {
3709 if (is_optional_field
&& !field_map
[i
]) get_at(i
)->set_to_omit();
3712 if (!field_map
[i
]) {
3713 if (is_optional_field
) opt_field_num
--;
3714 else mand_field_num
--;
3716 } else field_map
[i
]=2;
3721 } else { // !...->is_seof
3722 if (!field_map
[i
]) {
3724 decoded_field_length
= get_at(i
)->TEXT_decode(*fld_descr(i
),buff
,limit
,true);
3725 if (decoded_field_length
<0) {
3727 if (is_optional_field
) get_at(i
)->set_to_omit();
3731 if (is_optional_field
) opt_field_num
--;
3732 else mand_field_num
--;
3738 if (is_optional_field
) next_optional_idx
++;
3742 if (loop_detector
) break;
3743 if (p_td
.text
->separator_decode
) {
3745 if ((tl
=p_td
.text
->separator_decode
->match_begin(buff
))<0) {
3746 if (p_td
.text
->end_decode
) {
3748 if ((tl2
=p_td
.text
->end_decode
->match_begin(buff
))!=-1) {
3752 } else if (limit
.has_token(ml
)) {
3754 if ((tl2
=limit
.match(buff
,ml
))==0) {
3760 decoded_length
-=decoded_field_length
;
3761 field_map
[last_field_num
]+=2;
3764 if (last_field_num
>=0 && last_field_num
<field_cnt
) {
3765 if (get_at(last_field_num
)->is_seof()) {
3766 if (get_at(last_field_num
)->is_optional()) {
3767 if (field_map
[last_field_num
]==3) {
3768 get_at(last_field_num
)->set_to_omit();
3772 if (field_map
[last_field_num
]==3) {
3776 } else if (get_at(last_field_num
)->is_optional()) {
3777 get_at(last_field_num
)->set_to_omit();
3785 } // if (has_optinals)
3789 buff
.increase_pos(tl
);
3790 for (int a
=0;a
<field_cnt
;a
++) if(field_map
[a
]>2) field_map
[a
]-=3;
3793 } else if (p_td
.text
->end_decode
) {
3795 if ((tl
=p_td
.text
->end_decode
->match_begin(buff
))!=-1) {
3797 buff
.increase_pos(tl
);
3798 limit
.remove_tokens(ml
);
3799 if (mand_field_num
) decoded_length
= -1;
3802 } else if(limit
.has_token(ml
)){
3804 if ((tl
=limit
.match(buff
,ml
))==0) {
3810 limit
.remove_tokens(ml
);
3812 if (mand_field_num
) {
3813 if (no_err
) decoded_length
= -1;
3814 else TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR
,
3815 "Error during decoding '%s': ", p_td
.name
);
3818 decoded_length
-=sep_length
;
3819 buff
.set_pos(buff
.get_pos()-sep_length
);
3822 if (p_td
.text
->end_decode
) {
3824 if ((tl
=p_td
.text
->end_decode
->match_begin(buff
))<0) {
3825 if (no_err
) decoded_length
= -1;
3826 else TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR
,
3827 "The specified token '%s' not found for '%s': ",
3828 (const char*)*(p_td
.text
->end_decode
),p_td
.name
);
3832 buff
.increase_pos(tl
);
3834 if (mand_field_num
) decoded_length
= -1;
3837 return decoded_length
;
3838 } else { // record decoder
3839 int decoded_length
=0;
3840 int decoded_field_length
=0;
3841 size_t pos
=buff
.get_pos();
3842 boolean sep_found
=FALSE
;
3845 if (p_td
.text
->begin_decode
) {
3847 if ((tl
=p_td
.text
->begin_decode
->match_begin(buff
))<0) {
3848 if(no_err
)return -1;
3849 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR
,
3850 "The specified token '%s' not found for '%s': ",
3851 (const char*)*(p_td
.text
->begin_decode
), p_td
.name
);
3855 buff
.increase_pos(tl
);
3857 if (p_td
.text
->end_decode
) {
3858 limit
.add_token(p_td
.text
->end_decode
);
3861 if (p_td
.text
->separator_decode
) {
3862 limit
.add_token(p_td
.text
->separator_decode
);
3866 int mand_field_num
= 0;
3867 int opt_field_num
= 0;
3868 int last_man_index
= 0;
3870 int field_cnt
= get_count();
3871 int next_optional_idx
= 0;
3872 const int* optional_indexes
= get_optional_indexes();
3873 for (int i
=0;i
<field_cnt
;i
++) {
3874 boolean is_optional_field
= optional_indexes
&& (optional_indexes
[next_optional_idx
]==i
);
3875 if (is_optional_field
) {
3876 get_at(i
)->set_to_omit();
3882 if (is_optional_field
) next_optional_idx
++;
3885 next_optional_idx
= 0;
3886 for(int i
=0;i
<field_cnt
;i
++) {
3887 boolean is_optional_field
= optional_indexes
&& (optional_indexes
[next_optional_idx
]==i
);
3888 if (is_optional_field
) {
3891 decoded_field_length
= get_at(i
)->TEXT_decode(*fld_descr(i
),buff
,limit
,TRUE
);
3892 if (decoded_field_length
<0) {
3893 if (is_optional_field
) {
3894 get_at(i
)->set_to_omit();
3897 limit
.remove_tokens(ml
);
3898 if (no_err
) return -1;
3899 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR
,
3900 "Error during decoding field '%s' for '%s': ",
3901 fld_descr(i
)->name
, p_td
.name
);
3902 return decoded_length
;
3905 decoded_length
+=decoded_field_length
;
3906 if (last_man_index
>(i
+1)) {
3907 if (p_td
.text
->separator_decode
) {
3909 if ((tl
=p_td
.text
->separator_decode
->match_begin(buff
))<0) {
3910 if(is_optional_field
) {
3911 get_at(i
)->set_to_omit();
3913 decoded_length
-=decoded_field_length
;
3915 limit
.remove_tokens(ml
);
3916 if(no_err
)return -1;
3917 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR
,
3918 "The specified token '%s' not found for '%s': ",
3919 (const char*)*(p_td
.text
->separator_decode
),p_td
.name
);
3920 return decoded_length
;
3924 buff
.increase_pos(tl
);
3928 } else sep_found
=FALSE
;
3930 } else if (i
==(field_cnt
-1)) {
3933 if (p_td
.text
->separator_decode
) {
3935 if ((tl
=p_td
.text
->separator_decode
->match_begin(buff
))<0) {
3936 if (is_optional_field
) {
3937 if (p_td
.text
->end_decode
) {
3938 if ((tl
=p_td
.text
->end_decode
->match_begin(buff
))!=-1) {
3940 buff
.increase_pos(tl
);
3941 limit
.remove_tokens(ml
);
3942 return decoded_length
;
3944 } else if (limit
.has_token(ml
)) {
3945 if ((tl
=limit
.match(buff
,ml
))==0) {
3950 get_at(i
)->set_to_omit();
3952 decoded_length
-=decoded_field_length
;
3959 buff
.increase_pos(tl
);
3966 if (p_td
.text
->end_decode
) {
3967 if ((tl
=p_td
.text
->end_decode
->match_begin(buff
))!=-1) {
3969 buff
.increase_pos(tl
);
3970 limit
.remove_tokens(ml
);
3971 return decoded_length
;
3973 } else if (limit
.has_token(ml
)) {
3974 if ((tl
=limit
.match(buff
,ml
))==0) {
3982 if (is_optional_field
) next_optional_idx
++;
3984 limit
.remove_tokens(ml
);
3986 buff
.set_pos(buff
.get_pos()-sep_length
);
3987 decoded_length
-=sep_length
;
3989 if (p_td
.text
->end_decode
) {
3991 if ((tl
=p_td
.text
->end_decode
->match_begin(buff
))<0) {
3992 if(no_err
)return -1;
3993 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR
,
3994 "The specified token '%s' not found for '%s': ",
3995 (const char*)*(p_td
.text
->end_decode
),p_td
.name
);
3996 return decoded_length
;
3999 buff
.increase_pos(tl
);
4001 return decoded_length
;
4005 const XERdescriptor_t
* Record_Type::xer_descr(int /*field_index*/) const
4007 TTCN_error("Internal error: Record_Type::xer_descr() called.");
4011 char ** Record_Type::collect_ns(const XERdescriptor_t
& p_td
, size_t& num
, bool& def_ns
) const
4013 const int field_cnt
= get_count();
4014 // The USE-ORDER member is first, unless preempted by EMBED-VALUES
4015 const int uo_index
= ((p_td
.xer_bits
& EMBED_VALUES
) !=0);
4016 // Index of the first "normal" member (after E-V and U-O)
4017 const int start_at
= uo_index
+ ((p_td
.xer_bits
& USE_ORDER
) != 0);
4019 size_t num_collected
= 0;
4020 // First, our own namespace. Sets num_collected to 0 or 1.
4021 // If it throws, nothing was allocated.
4022 char **collected_ns
= Base_Type::collect_ns(p_td
, num_collected
, def_ns
);
4025 // If the nil attribute will be written, add the control namespace
4026 boolean nil_attribute
= (p_td
.xer_bits
& USE_NIL
)
4027 && !get_at(field_cnt
-1)->ispresent();
4029 if (nil_attribute
) {
4030 collected_ns
= (char**)Realloc(collected_ns
, sizeof(char*) * ++num_collected
);
4031 const namespace_t
*c_ns
= p_td
.my_module
->get_controlns();
4033 collected_ns
[num_collected
-1] = mprintf(" xmlns:%s='%s'", c_ns
->px
, c_ns
->ns
);
4036 // Collect namespace declarations from all components (recursively).
4037 // This is extremely nasty, but we can't prosecute you for that.
4038 // (Monty Python - Crunchy Frog sketch). This whole thing is O(n^3). Yuck.
4039 for (int a
= start_at
; a
< field_cnt
; ++a
) {
4041 bool def_ns_1
= false;
4042 char **new_namespaces
= get_at(a
)->collect_ns(*xer_descr(a
), num_new
, def_ns_1
);
4043 merge_ns(collected_ns
, num_collected
, new_namespaces
, num_new
);
4044 def_ns
= def_ns
|| def_ns_1
;
4045 // merge_ns freed new_namespaces
4049 // Probably a TC_Error thrown from the element's collect_ns(),
4050 // e.g. if encoding an unbound value.
4051 while (num_collected
> 0) Free(collected_ns
[--num_collected
]);
4056 num
= num_collected
;
4057 return collected_ns
;
4060 // FIXME some hashing should be implemented
4061 int Record_Type::get_index_byname(const char *name
, const char *uri
) const {
4062 int num_fields
= get_count();
4063 for (int i
= 0; i
< num_fields
; ++i
) {
4064 const XERdescriptor_t
& xer
= *xer_descr(i
);
4065 if (check_name(name
, xer
, TRUE
)
4066 && check_namespace(uri
, xer
)) return i
;
4071 int Record_Type::XER_encode(const XERdescriptor_t
& p_td
, TTCN_Buffer
& p_buf
,
4072 unsigned int flavor
, int indent
, embed_values_enc_struct_t
*) const
4075 return XER_encode_negtest(err_descr
, p_td
, p_buf
, flavor
, indent
, 0);
4078 TTCN_EncDec_ErrorContext::error
4079 (TTCN_EncDec::ET_UNBOUND
, "Encoding an unbound value.");
4082 TTCN_EncDec_ErrorContext
ec_0("Component '");
4083 TTCN_EncDec_ErrorContext ec_1
;
4084 int encoded_length
=(int)p_buf
.get_len(); // how much is already in the buffer
4086 int exer
= is_exer(flavor
);
4087 if (exer
&& (p_td
.xer_bits
& EMBED_VALUES
)) flavor
|= XER_CANONICAL
;
4088 const boolean indenting
= !is_canonical(flavor
);
4089 const int field_cnt
= get_count();
4090 const int num_attributes
= get_xer_num_attr();
4091 // The USE-ORDER member is first, unless preempted by EMBED-VALUES
4092 const int uo_index
= ((p_td
.xer_bits
& EMBED_VALUES
) !=0);
4093 // Index of the first "normal" member (after E-V and U-O)
4094 const int start_at
= uo_index
+ ((p_td
.xer_bits
& USE_ORDER
) != 0);
4095 const int first_nonattr
= start_at
+ num_attributes
;
4096 // start_tag_len is keeping track of how much was written at the end of the
4097 // start tag, i.e. the ">\n". This is used later to "back up" over it.
4098 int start_tag_len
= 1 + indenting
;
4099 // The EMBED-VALUES member, if applicable
4100 const Record_Of_Type
* embed_values
= 0;
4101 if (p_td
.xer_bits
& EMBED_VALUES
) {
4102 embed_values
= dynamic_cast<const Record_Of_Type
*>(get_at(0));
4103 if (NULL
== embed_values
) {
4104 const OPTIONAL
<Record_Of_Type
>* const embed_opt
= static_cast<const OPTIONAL
<Record_Of_Type
>*>(get_at(0));
4105 if(embed_opt
->is_present()) {
4106 embed_values
= &(*embed_opt
)();
4110 // The USE-ORDER member, if applicable
4111 const Record_Of_Type
* const use_order
= (p_td
.xer_bits
& USE_ORDER
)
4112 ? static_cast<const Record_Of_Type
*>(get_at(uo_index
)) : 0;
4114 size_t num_collected
= 0; // we use this to compute delay_close
4115 char **collected_ns
= NULL
;
4116 bool def_ns
= false;
4118 if (indent
== 0) { // top-level type
4119 collected_ns
= collect_ns(p_td
, num_collected
, def_ns
);
4121 else if ((flavor
& DEF_NS_SQUASHED
) && p_td
.my_module
&& p_td
.ns_index
!= -1) {
4122 const namespace_t
* ns
= p_td
.my_module
->get_ns(p_td
.ns_index
);
4123 // The default namespace has been squashed.
4124 // If we are in the default namespace, restore it.
4125 if (*ns
->px
== '\0') {
4126 collected_ns
= Base_Type::collect_ns(p_td
, num_collected
, def_ns
);
4131 // The type's own tag is omitted if we're doing E-XER,
4132 // and it's not the top-level type (XML must have a root element)
4133 // and it's either UNTAGGED or got USE_NIL or USE_TYPE or USE_UNION.
4134 boolean omit_tag
= exer
&& (indent
> 0)
4135 && ( (p_td
.xer_bits
& (UNTAGGED
|XER_ATTRIBUTE
))
4136 || (flavor
& (USE_NIL
|USE_TYPE_ATTR
)));
4138 // If a default namespace is in effect (uri but no prefix) and the type
4139 // is unqualified, the default namespace must be canceled; otherwise
4140 // an XML tag without a ns prefix looks like it belongs to the def.namespace
4141 const boolean empty_ns_hack
= exer
&& !omit_tag
&& (indent
> 0)
4142 && (p_td
.xer_bits
& FORM_UNQUALIFIED
)
4143 && (flavor
& DEF_NS_PRESENT
);
4145 // delay_close=true if there is stuff before the '>' of the start tag
4146 // (prevents writing the '>' which is built into the name).
4147 // This can only happen for EXER: if there are attributes or namespaces,
4148 // or either USE-NIL or USE-QNAME is set.
4149 boolean delay_close
= exer
&& (num_attributes
4150 || empty_ns_hack
// counts as having a namespace
4151 || (num_collected
!= 0)
4152 || (p_td
.xer_bits
& (USE_NIL
|USE_QNAME
))
4153 || (flavor
& USE_NIL
));
4157 if (!omit_tag
) { /* write start tag */
4158 if (indenting
) do_indent(p_buf
, indent
);
4159 /* name looks like this: "tagname>\n"
4160 * lose the \n if : not indenting or (single untagged(*) or attributes (*)) AND exer
4161 * lose the > if attributes are present (*) AND exer
4164 if (exer
) write_ns_prefix(p_td
, p_buf
);
4165 p_buf
.put_s((size_t)p_td
.namelens
[exer
] - delay_close
4166 - (!indenting
|| delay_close
|| (exer
&& (p_td
.xer_bits
& HAS_1UNTAGGED
))),
4167 (cbyte
*)p_td
.names
[exer
]);
4169 else if (flavor
& USE_TYPE_ATTR
) {
4170 // reopen the parent's start tag by overwriting the '>'
4171 size_t buf_len
= p_buf
.get_len();
4172 const unsigned char * const buf_data
= p_buf
.get_data();
4173 if (buf_data
[buf_len
- 1 - shorter
] == '\n') ++shorter
;
4174 if (buf_data
[buf_len
- 1 - shorter
] == '>' ) ++shorter
;
4177 p_buf
.increase_length(-shorter
);
4183 // mask out extra flags we received, do not send them to the fields
4186 if (exer
&& (p_td
.xer_bits
& USE_QNAME
)) { // QName trumps everything
4187 const Base_Type
* const q_uri
= get_at(0);
4188 if (q_uri
->is_present()) {
4189 p_buf
.put_s(11, (cbyte
*)" xmlns:b0='");
4190 q_uri
->XER_encode(*xer_descr(0), p_buf
, flavor
| XER_LIST
, indent
+1, 0);
4194 if (p_td
.xer_bits
& XER_ATTRIBUTE
) begin_attribute(p_td
, p_buf
);
4195 else p_buf
.put_c('>');
4197 if (q_uri
->is_present()) {
4198 p_buf
.put_s(3, (cbyte
*)"b0:");
4201 const Base_Type
* const q_name
= get_at(1);
4202 sub_len
+= q_name
->XER_encode(*xer_descr(1), p_buf
, flavor
| XER_LIST
, indent
+1, 0);
4203 if (p_td
.xer_bits
& XER_ATTRIBUTE
) p_buf
.put_c('\'');
4205 else { // not USE-QNAME
4206 if (!exer
&& (p_td
.xer_bits
& EMBED_VALUES
) && embed_values
!= NULL
) {
4207 // The EMBED-VALUES member as an ordinary record of string
4208 sub_len
+= embed_values
->XER_encode(*xer_descr(0), p_buf
, flavor
, indent
+1, 0);
4211 if (!exer
&& (p_td
.xer_bits
& USE_ORDER
)) {
4212 // The USE-ORDER member as an ordinary record of enumerated
4213 sub_len
+= use_order
->XER_encode(*xer_descr(uo_index
), p_buf
, flavor
, indent
+1, 0);
4216 if (exer
&& (indent
==0 || (flavor
& DEF_NS_SQUASHED
))) // write namespaces for toplevel only
4218 for (size_t cur_coll
= 0; cur_coll
< num_collected
; ++cur_coll
) {
4219 p_buf
.put_s(strlen(collected_ns
[cur_coll
]), (cbyte
*)collected_ns
[cur_coll
]);
4220 Free(collected_ns
[cur_coll
]); // job done
4226 flavor
&= ~DEF_NS_SQUASHED
;
4227 flavor
|= DEF_NS_PRESENT
;
4229 else if (empty_ns_hack
) {
4230 p_buf
.put_s(9, (cbyte
*)" xmlns=''");
4231 flavor
&= ~DEF_NS_PRESENT
;
4232 flavor
|= DEF_NS_SQUASHED
;
4235 /* First all the attributes (not added to sub_len) */
4237 for (i
= start_at
; i
< first_nonattr
; ++i
) {
4238 boolean is_xer_attr_field
= xer_descr(i
)->xer_bits
& XER_ATTRIBUTE
;
4239 ec_1
.set_msg("%s': ", fld_name(i
)); // attr
4240 int tmp_len
= get_at(i
)->XER_encode(*xer_descr(i
), p_buf
, flavor
, indent
+1, 0);
4241 if (is_xer_attr_field
&& !exer
) sub_len
+= tmp_len
; /* do not add if attribute and EXER */
4244 // True if the "nil" attribute needs to be written.
4245 boolean nil_attribute
= exer
&& (p_td
.xer_bits
& USE_NIL
)
4246 && !get_at(field_cnt
-1)->ispresent();
4248 // True if USE_ORDER is in effect and the "nil" attribute was written.
4249 // Then the record-of-enum for USE-ORDER will be empty.
4250 boolean early_to_bed
= FALSE
;
4252 if (nil_attribute
) { // req. exer and USE_NIL
4253 const namespace_t
*control_ns
= p_td
.my_module
->get_controlns();
4255 p_buf
.put_s(strlen(control_ns
->px
),
4256 (cbyte
*)control_ns
->px
);
4258 p_buf
.put_s(10, (cbyte
*)"nil='true'");
4259 if ((p_td
.xer_bits
& USE_ORDER
)) early_to_bed
= TRUE
;
4260 // The whole content was omitted; nothing to do (and if we tried
4261 // to do it, we'd get an error for over-indexing a 0-length record-of).
4264 if (delay_close
&& (!omit_tag
|| shorter
)) {
4265 // Close the start tag left open. If indenting, also write a newline
4266 // unless USE-NIL in effect or there is a single untagged component.
4268 ((p_td
.xer_bits
& (/*USE_NIL|*/HAS_1UNTAGGED
)) ? 0 : indenting
);
4269 p_buf
.put_s(start_tag_len
, (cbyte
*)">\n");
4272 if (exer
&& (p_td
.xer_bits
& EMBED_VALUES
)) {
4273 /* write the first string */
4274 if (embed_values
!= NULL
&& embed_values
->size_of() > 0) {
4275 sub_len
+= embed_values
->get_at(0)->XER_encode(UNIVERSAL_CHARSTRING_xer_
,
4276 p_buf
, flavor
| EMBED_VALUES
, indent
+1, 0);
4280 const Record_Type
*ordered
= this; // the record affected by USE-ORDER
4282 // Index of the first non-attribute field of the record pointed to by
4283 // ordered, that is, the first field affected by USE-ORDER.
4284 size_t useorder_base
= first_nonattr
;
4287 int end
= field_cnt
;
4288 if (exer
&& (p_td
.xer_bits
& USE_ORDER
)) {
4289 const int to_send
= use_order
->size_of();
4290 // the length of the loop is determined by the length of use_order
4294 // Count the non-attribute optionals
4295 int n_optionals
= 0;
4296 for (int B
= optional_count() - 1; B
>=+0; B
--) {
4297 int oi
= get_optional_indexes()[B
];
4298 if (oi
< first_nonattr
) break;
4302 int expected_max
= field_cnt
- first_nonattr
;
4303 int expected_min
= expected_max
- n_optionals
;
4305 if ((p_td
.xer_bits
& USE_NIL
) && get_at(field_cnt
-1)->ispresent()) {
4306 // The special case when USE_ORDER refers to the fields of a field,
4308 const Base_Type
*last_optional
= get_at(field_cnt
-1);
4309 const Base_Type
* inner
= last_optional
->get_opt_value();
4310 // it absolutely, positively has to be (derived from) Record_Type
4311 ordered
= static_cast<const Record_Type
*>(inner
);
4312 useorder_base
= ordered
->get_xer_num_attr();
4313 begin
= useorder_base
;
4314 end
= ordered
->get_count();
4316 expected_min
= expected_max
= ordered
->get_count();
4319 if (to_send
> expected_max
4320 ||to_send
< expected_min
) {
4321 ec_1
.set_msg("%s': ", fld_name(uo_index
));
4322 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_CONSTRAINT
,
4323 "Wrong number of USE-ORDER %d, must be %d..%d", to_send
, expected_min
, expected_max
);
4324 begin
= end
= 0; // don't bother sending anything
4326 else { // check no duplicates
4327 int *seen
= new int [to_send
];
4329 for (int ei
= 0; ei
< to_send
; ++ei
) {
4330 const Base_Type
*uoe
= use_order
->get_at(ei
);
4331 const Enum_Type
*enm
= static_cast<const Enum_Type
*>(uoe
);
4332 int val
= enm
->as_int();
4333 for (int x
= 0; x
< num_seen
; ++x
) {
4334 if (val
== seen
[x
]) { // complain
4335 ec_1
.set_msg("%s': ", fld_name(uo_index
));
4336 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_CONSTRAINT
,
4337 "Duplicate value for USE-ORDER");
4338 begin
= end
= 0; // don't bother sending anything
4342 seen
[num_seen
++] = val
;
4346 // If the number is right and there are no duplicates, then carry on
4350 /* Then, all the non-attributes. Structuring the code like this depends on
4351 * all attributes appearing before all non-attributes (excluding
4352 * pseudo-members for USE-ORDER, etc.) */
4354 // early_to_bed can only be true if exer is true (transitive through nil_attribute)
4355 if (!early_to_bed
) {
4356 embed_values_enc_struct_t
* emb_val
= 0;
4357 if (exer
&& (p_td
.xer_bits
& EMBED_VALUES
) &&
4358 embed_values
!= NULL
&& embed_values
->size_of() > 1) {
4359 emb_val
= new embed_values_enc_struct_t
;
4360 emb_val
->embval_array
= embed_values
;
4361 emb_val
->embval_index
= 1;
4362 emb_val
->embval_err
= 0;
4365 for ( i
= begin
; i
< end
; ++i
) {
4366 const Base_Type
*uoe
= 0; // "useOrder enum"
4367 const Enum_Type
*enm
= 0; // the enum value selecting the field
4368 if (exer
&& use_order
) {
4369 uoe
= use_order
->get_at(i
- begin
);
4370 enm
= static_cast<const Enum_Type
*>(uoe
);
4373 // "actual" index, may be perturbed by USE-ORDER
4374 int ai
= !(exer
&& (p_td
.xer_bits
& USE_ORDER
)) ? i
:
4375 enm
->as_int() + useorder_base
;
4376 ec_1
.set_msg("%s': ", ordered
->fld_name(ai
)); // non-attr
4378 const XERdescriptor_t
& descr
= *ordered
->xer_descr(ai
);
4379 sub_len
+= ordered
->get_at(ai
)->XER_encode(descr
, p_buf
,
4380 // Pass USE-NIL to the last field (except when USE-ORDER is also in effect,
4381 // because the tag-stripping effect of USE-NIL has been achieved
4382 // by encoding the sub-fields directly).
4383 flavor
| ((exer
&& !use_order
&& (i
== field_cnt
-1)) ? (p_td
.xer_bits
& USE_NIL
) : 0),
4384 indent
+!omit_tag
, emb_val
);
4386 // Now the next embed-values string (NOT affected by USE-ORDER!)
4387 if (exer
&& (p_td
.xer_bits
& EMBED_VALUES
) && 0 != emb_val
&&
4388 embed_values
!= NULL
&& emb_val
->embval_index
< embed_values
->size_of()) {
4389 embed_values
->get_at(emb_val
->embval_index
)->XER_encode(UNIVERSAL_CHARSTRING_xer_
4390 , p_buf
, flavor
| EMBED_VALUES
, indent
+1, 0);
4391 ++emb_val
->embval_index
;
4396 if (embed_values
!= NULL
&& emb_val
->embval_index
< embed_values
->size_of()) {
4397 ec_1
.set_msg("%s': ", fld_name(0));
4398 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_CONSTRAINT
,
4399 "Too many EMBED-VALUEs specified: %d (expected %d or less)",
4400 embed_values
->size_of(), emb_val
->embval_index
);
4404 } // if (!early_to_bed)
4408 if (sub_len
) { // something was written, now an end tag
4409 if (indenting
&& !(exer
&& (p_td
.xer_bits
& (HAS_1UNTAGGED
| USE_QNAME
)))) {
4410 // The tags of the last optional member involved with USE_NIL
4411 // have been removed. If it was a simple type, the content was probably
4412 // written on a single line without anything resembling a close tag.
4413 // Do not indent our end tag in this case.
4414 switch ((int)(exer
&& (p_td
.xer_bits
& USE_NIL
))) {
4416 const unsigned char *buf_end
= p_buf
.get_data() + (p_buf
.get_len()-1);
4417 if (buf_end
[-1] != '>' || *buf_end
!= '\n') break;
4418 // If it does not look like an end tag, skip the indenting,
4419 // else fall through.
4422 do_indent(p_buf
, indent
);
4428 if (exer
) write_ns_prefix(p_td
, p_buf
);
4429 p_buf
.put_s((size_t)p_td
.namelens
[exer
]-!indenting
, (cbyte
*)p_td
.names
[exer
]);
4431 else { // need to generate an empty element tag
4432 p_buf
.increase_length(-start_tag_len
); // decrease length
4433 p_buf
.put_s((size_t)2+indenting
, (cbyte
*)"/>\n");
4437 return (int)p_buf
.get_len() - encoded_length
;
4440 // XERSTUFF Record_Type::encode_field
4441 /** Helper for Record_Type::XER_encode_negtest
4443 * Factored out because Record_Type::XER_encode (on which XER_encode_negtest
4444 * is based) calls the XER_encode method of the field in two places:
4445 * one for attributes, the other for elements.
4447 * @param i index of the field
4448 * @param err_vals erroneous descriptor for the field
4449 * @param emb_descr deeper erroneous values
4450 * @param p_buf buffer containing the encoded value
4451 * @param sub_flavor flags
4452 * @param indent indentation level
4453 * @return the number of bytes generated
4455 int Record_Type::encode_field(int i
,
4456 const Erroneous_values_t
* err_vals
, const Erroneous_descriptor_t
* emb_descr
,
4457 TTCN_Buffer
& p_buf
, unsigned int sub_flavor
, int indent
, embed_values_enc_struct_t
* emb_val
) const
4460 TTCN_EncDec_ErrorContext ec
;
4461 if (err_vals
&& err_vals
->before
) {
4462 if (err_vals
->before
->errval
==NULL
) TTCN_error(
4463 "internal error: erroneous before value missing");
4464 ec
.set_msg("Erroneous value before component %s: ", fld_name(i
));
4465 if (err_vals
->before
->raw
) {
4466 enc_len
+= err_vals
->before
->errval
->encode_raw(p_buf
);
4468 if (err_vals
->before
->type_descr
==NULL
) TTCN_error(
4469 "internal error: erroneous before typedescriptor missing");
4470 enc_len
+= err_vals
->before
->errval
->XER_encode(
4471 *err_vals
->before
->type_descr
->xer
, p_buf
, sub_flavor
, indent
, 0);
4475 if (err_vals
&& err_vals
->value
) {
4476 if (err_vals
->value
->errval
) { // replace
4477 ec
.set_msg("Erroneous value for component %s: ", fld_name(i
));
4478 if (err_vals
->value
->raw
) {
4479 enc_len
+= err_vals
->value
->errval
->encode_raw(p_buf
);
4481 if (err_vals
->value
->type_descr
==NULL
) TTCN_error(
4482 "internal error: erroneous value typedescriptor missing");
4483 enc_len
+= err_vals
->value
->errval
->XER_encode(
4484 *err_vals
->value
->type_descr
->xer
, p_buf
, sub_flavor
, indent
, 0);
4488 ec
.set_msg("Component %s: ", fld_name(i
));
4490 enc_len
+= get_at(i
)->XER_encode_negtest(emb_descr
, *xer_descr(i
), p_buf
,
4491 sub_flavor
, indent
, emb_val
);
4493 // the "real" encoder
4494 enc_len
+= get_at(i
)->XER_encode(*xer_descr(i
), p_buf
,
4495 sub_flavor
, indent
, emb_val
);
4499 if (err_vals
&& err_vals
->after
) {
4500 if (err_vals
->after
->errval
==NULL
) TTCN_error(
4501 "internal error: erroneous after value missing");
4502 ec
.set_msg("Erroneous value after component %s: ", fld_name(i
));
4503 if (err_vals
->after
->raw
) {
4504 enc_len
+= err_vals
->after
->errval
->encode_raw(p_buf
);
4506 if (err_vals
->after
->type_descr
==NULL
) TTCN_error(
4507 "internal error: erroneous after typedescriptor missing");
4508 enc_len
+= err_vals
->after
->errval
->XER_encode(
4509 *err_vals
->after
->type_descr
->xer
, p_buf
, sub_flavor
, indent
, 0);
4516 // XERSTUFF Record_Type::XER_encode_negtest
4517 int Record_Type::XER_encode_negtest(const Erroneous_descriptor_t
* p_err_descr
,
4518 const XERdescriptor_t
& p_td
, TTCN_Buffer
& p_buf
, unsigned int flavor
, int indent
,
4519 embed_values_enc_struct_t
*) const
4522 TTCN_EncDec_ErrorContext::error
4523 (TTCN_EncDec::ET_UNBOUND
, "Encoding an unbound value.");
4525 TTCN_EncDec_ErrorContext
ec_0("Component '");
4526 TTCN_EncDec_ErrorContext ec_1
;
4527 int encoded_length
=(int)p_buf
.get_len(); // how much is already in the buffer
4529 int exer
= is_exer(flavor
);
4530 if (exer
&& (p_td
.xer_bits
& EMBED_VALUES
)) flavor
|= XER_CANONICAL
;
4531 const boolean indenting
= !is_canonical(flavor
);
4532 const int field_cnt
= get_count();
4533 const int num_attributes
= get_xer_num_attr();
4534 // The USE-ORDER member is first, unless preempted by EMBED-VALUES
4535 const int uo_index
= ((p_td
.xer_bits
& EMBED_VALUES
) !=0);
4536 // Index of the first "normal" member (after E-V and U-O)
4537 const int start_at
= uo_index
+ ((p_td
.xer_bits
& USE_ORDER
) != 0);
4538 const int first_nonattr
= start_at
+ num_attributes
;
4539 // start_tag_len is keeping track of how much was written at the end of the
4540 // start tag, i.e. the ">\n". This is used later to "back up" over it.
4541 int start_tag_len
= 1 + indenting
;
4542 // The EMBED-VALUES member, if applicable (always first)
4543 const Record_Of_Type
* const embed_values
= (p_td
.xer_bits
& EMBED_VALUES
)
4544 ? static_cast<const Record_Of_Type
*>(get_at(0)) : 0;
4545 // The USE-ORDER member, if applicable (first unless preempted by embed_vals)
4546 const Record_Of_Type
* const use_order
= (p_td
.xer_bits
& USE_ORDER
)
4547 ? static_cast<const Record_Of_Type
*>(get_at(uo_index
)) : 0;
4552 size_t num_collected
= 0; // we use this to compute delay_close
4553 char **collected_ns
= NULL
;
4554 bool def_ns
= false;
4556 if (indent
== 0) { // top-level type
4557 collected_ns
= collect_ns(p_td
, num_collected
, def_ns
);
4559 else if ((flavor
& DEF_NS_SQUASHED
) && p_td
.my_module
&& p_td
.ns_index
!= -1) {
4560 const namespace_t
* ns
= p_td
.my_module
->get_ns(p_td
.ns_index
);
4561 // The default namespace has been squashed.
4562 // If we are in the default namespace, restore it.
4563 if (*ns
->px
== '\0') {
4564 collected_ns
= Base_Type::collect_ns(p_td
, num_collected
, def_ns
);
4569 // The type's own tag is omitted if we're doing E-XER,
4570 // and it's not the top-level type (XML must have a root element)
4571 // and it's either UNTAGGED or got USE_NIL.
4572 boolean omit_tag
= exer
&& indent
4573 && ( (p_td
.xer_bits
& (UNTAGGED
|XER_ATTRIBUTE
))
4574 || (flavor
& (USE_NIL
|USE_TYPE_ATTR
)));
4576 // If a default namespace is in effect (uri but no prefix) and the type
4577 // is unqualified, the default namespace must be canceled; otherwise
4578 // an XML tag without a ns prefix looks like it belongs to the def.namespace
4579 const boolean empty_ns_hack
= exer
&& !omit_tag
&& (indent
> 0)
4580 && (p_td
.xer_bits
& FORM_UNQUALIFIED
)
4581 && (flavor
& DEF_NS_PRESENT
);
4583 // delay_close=true if there is stuff before the '>' of the start tag
4584 // (prevents writing the '>' which is built into the name).
4585 // This can only happen for EXER: if there are attributes or namespaces,
4586 // or either USE-NIL or USE-QNAME is set.
4587 boolean delay_close
= exer
&& (num_attributes
4588 || empty_ns_hack
// counts as having a namespace
4589 || (num_collected
!= 0)
4590 || (p_td
.xer_bits
& (USE_NIL
|USE_QNAME
))
4591 || (flavor
& USE_NIL
));
4594 if (!omit_tag
) { /* write start tag */
4595 if (indenting
) do_indent(p_buf
, indent
);
4596 /* name looks like this: "tagname>\n"
4597 * lose the \n if : not indenting or (single untagged(*) or attributes (*)) AND exer
4598 * lose the > if attributes are present (*) AND exer
4601 if (exer
) write_ns_prefix(p_td
, p_buf
);
4602 p_buf
.put_s((size_t)p_td
.namelens
[exer
] - delay_close
4603 - (!indenting
|| delay_close
|| (exer
&& (p_td
.xer_bits
& HAS_1UNTAGGED
))),
4604 (cbyte
*)p_td
.names
[exer
]);
4606 else if (flavor
& USE_TYPE_ATTR
) {
4607 // reopen the parent's tag
4608 size_t buf_len
= p_buf
.get_len();
4609 const unsigned char * const buf_data
= p_buf
.get_data();
4610 if (buf_data
[buf_len
- 1 - shorter
] == '\n') ++shorter
;
4611 if (buf_data
[buf_len
- 1 - shorter
] == '>' ) ++shorter
;
4614 p_buf
.increase_length(-shorter
);
4619 int sub_len
=0, tmp_len
;
4620 // mask out extra flags we received, do not send them to the fields
4623 if (exer
&& (p_td
.xer_bits
& USE_QNAME
)) {
4624 const Erroneous_values_t
* ev
=
4625 p_err_descr
->next_field_err_values(0, values_idx
);
4626 const Erroneous_descriptor_t
* ed
=
4627 p_err_descr
->next_field_emb_descr (0, edescr_idx
);
4628 // At first, erroneous info for the first component (uri)
4630 TTCN_EncDec_ErrorContext ec
;
4631 const Base_Type
* const q_uri
= get_at(0);
4633 if (ev
&& ev
->before
) {
4634 if (ev
->before
->errval
==NULL
) TTCN_error(
4635 "internal error: erroneous before value missing");
4636 ec
.set_msg("Erroneous value before component #0: ");
4637 if (ev
->before
->raw
) {
4638 sub_len
+= ev
->before
->errval
->encode_raw(p_buf
);
4640 if (ev
->before
->type_descr
==NULL
) TTCN_error(
4641 "internal error: erroneous before typedescriptor missing");
4642 sub_len
+= ev
->before
->errval
->XER_encode(
4643 *ev
->before
->type_descr
->xer
, p_buf
, flavor
, indent
, 0);
4647 if (ev
&& ev
->value
) {
4648 if (ev
->value
->errval
) { // replace
4649 ec
.set_msg("Erroneous value for component #0: ");
4650 if (ev
->value
->raw
) {
4651 sub_len
+= ev
->value
->errval
->encode_raw(p_buf
);
4653 if (ev
->value
->type_descr
==NULL
) TTCN_error(
4654 "internal error: erroneous value typedescriptor missing");
4655 sub_len
+= ev
->value
->errval
->XER_encode(
4656 *ev
->value
->type_descr
->xer
, p_buf
, flavor
, indent
, 0);
4660 ec
.set_msg("Component #0: ");
4662 // universal charstring does not have components.
4663 // TTCN code which could have generated embedded erroneous descriptor
4664 // should have failed semantic analysis.
4665 TTCN_error("internal error: embedded descriptor unexpected");
4667 // the "real" encoder
4668 if (q_uri
->is_present()) {
4669 p_buf
.put_s(11, (cbyte
*)" xmlns:b0='");
4670 sub_len
+= q_uri
->XER_encode(*xer_descr(0), p_buf
, flavor
| XER_LIST
, indent
+1, 0);
4676 if (ev
&& ev
->after
) {
4677 if (ev
->after
->errval
==NULL
) TTCN_error(
4678 "internal error: erroneous after value missing");
4679 ec
.set_msg("Erroneous value after component #0: ");
4680 if (ev
->after
->raw
) {
4681 sub_len
+= ev
->after
->errval
->encode_raw(p_buf
);
4683 if (ev
->after
->type_descr
==NULL
) TTCN_error(
4684 "internal error: erroneous after typedescriptor missing");
4685 sub_len
+= ev
->after
->errval
->XER_encode(
4686 *ev
->after
->type_descr
->xer
, p_buf
, flavor
, indent
, 0);
4690 if (p_td
.xer_bits
& XER_ATTRIBUTE
) begin_attribute(p_td
, p_buf
);
4691 else p_buf
.put_c('>');
4693 // Now switch to the second field (name)
4694 ev
= p_err_descr
->next_field_err_values(1, values_idx
);
4695 ed
= p_err_descr
->next_field_emb_descr (1, edescr_idx
);
4697 if (ev
&& ev
->before
) {
4698 if (ev
->before
->errval
==NULL
) TTCN_error(
4699 "internal error: erroneous before value missing");
4700 ec
.set_msg("Erroneous value before component #1: ");
4701 if (ev
->before
->raw
) {
4702 sub_len
+= ev
->before
->errval
->encode_raw(p_buf
);
4704 if (ev
->before
->type_descr
==NULL
) TTCN_error(
4705 "internal error: erroneous before typedescriptor missing");
4706 sub_len
+= ev
->before
->errval
->XER_encode(
4707 *ev
->before
->type_descr
->xer
, p_buf
, flavor
, indent
, 0);
4711 if (ev
&& ev
->value
) {
4712 if (ev
->value
->errval
) { // replace
4713 ec
.set_msg("Erroneous value for component #1: ");
4714 if (ev
->value
->raw
) {
4715 sub_len
+= ev
->value
->errval
->encode_raw(p_buf
);
4717 if (ev
->value
->type_descr
==NULL
) TTCN_error(
4718 "internal error: erroneous value typedescriptor missing");
4719 sub_len
+= ev
->value
->errval
->XER_encode(
4720 *ev
->value
->type_descr
->xer
, p_buf
, flavor
, indent
, 0);
4724 ec
.set_msg("Component #1: ");
4726 // universal charstring does not have components
4727 TTCN_error("internal error: embedded descriptor unexpected");
4729 // the "real" encoder
4730 if (q_uri
->is_present()) {
4731 p_buf
.put_s(3, (cbyte
*)"b0:");
4735 sub_len
+= get_at(1)->XER_encode(*xer_descr(1), p_buf
, flavor
| XER_LIST
, indent
+1, 0);
4739 if (ev
&& ev
->after
) {
4740 if (ev
->after
->errval
==NULL
) TTCN_error(
4741 "internal error: erroneous after value missing");
4742 ec
.set_msg("Erroneous value after component #1: ");
4743 if (ev
->after
->raw
) {
4744 sub_len
+= ev
->after
->errval
->encode_raw(p_buf
);
4746 if (ev
->after
->type_descr
==NULL
) TTCN_error(
4747 "internal error: erroneous after typedescriptor missing");
4748 sub_len
+= ev
->after
->errval
->XER_encode(
4749 *ev
->after
->type_descr
->xer
, p_buf
, flavor
, indent
, 0);
4753 if (p_td
.xer_bits
& XER_ATTRIBUTE
) p_buf
.put_c('\'');
4755 else { // not USE-QNAME
4756 if (!exer
&& (p_td
.xer_bits
& EMBED_VALUES
)) {
4757 // The EMBED-VALUES member as an ordinary record of string
4758 sub_len
+= embed_values
->XER_encode(*xer_descr(0), p_buf
, flavor
, indent
+1, 0);
4761 if (!exer
&& (p_td
.xer_bits
& USE_ORDER
)) {
4762 // The USE-ORDER member as an ordinary record of enumerated
4763 sub_len
+= use_order
->XER_encode(*xer_descr(uo_index
), p_buf
, flavor
, indent
+1, 0);
4766 if (exer
&& (indent
==0 || (flavor
& DEF_NS_SQUASHED
))) // write namespaces for toplevel only
4768 for (size_t cur_coll
= 0; cur_coll
< num_collected
; ++cur_coll
) {
4769 p_buf
.put_s(strlen(collected_ns
[cur_coll
]), (cbyte
*)collected_ns
[cur_coll
]);
4770 Free(collected_ns
[cur_coll
]); // job done
4776 flavor
&= ~DEF_NS_SQUASHED
;
4777 flavor
|= DEF_NS_PRESENT
;
4779 else if (empty_ns_hack
) {
4780 p_buf
.put_s(9, (cbyte
*)" xmlns=''");
4781 flavor
&= ~DEF_NS_PRESENT
;
4782 flavor
|= DEF_NS_SQUASHED
;
4785 // True if the non-attribute fields need to be omitted;
4786 // e.g. if USE_ORDER is in effect and the "nil" attribute was written
4787 // (then the record-of-enum for USE-ORDER will be empty),
4788 // or "omit all after" was hit while processing attributes.
4789 boolean early_to_bed
= FALSE
;
4791 // First all the attributes (not added to sub_len)
4793 for (i
= start_at
; i
< first_nonattr
; ++i
) {
4794 const Erroneous_values_t
* ev
=
4795 p_err_descr
->next_field_err_values(i
, values_idx
);
4796 const Erroneous_descriptor_t
* ed
=
4797 p_err_descr
->next_field_emb_descr(i
, edescr_idx
);
4799 if (i
< p_err_descr
->omit_before
) continue;
4801 boolean is_xer_attr_field
= xer_descr(i
)->xer_bits
& XER_ATTRIBUTE
;
4802 ec_1
.set_msg("%s': ", fld_name(i
)); // attr
4804 tmp_len
= encode_field(i
, ev
, ed
, p_buf
, flavor
, indent
+ !omit_tag
, 0);
4806 if (is_xer_attr_field
&& !exer
) sub_len
+= tmp_len
; // do not add if attribute and EXER
4808 // omit_after value -1 becomes "very big"
4809 if ((unsigned int)i
>= (unsigned int)p_err_descr
->omit_after
) {
4810 early_to_bed
= TRUE
; // no more fields to write
4815 // True if the "nil" attribute needs to be written.
4816 boolean nil_attribute
= FALSE
;
4817 // nil attribute unaffected by erroneous
4818 boolean nil_attribute_simple
= FALSE
;
4819 if (exer
&& (p_td
.xer_bits
& USE_NIL
)) {
4820 nil_attribute
= nil_attribute_simple
= !get_at(field_cnt
-1)->ispresent();
4822 if (p_err_descr
->values_size
> 0) // there is an erroneous "value := ..."
4824 const Erroneous_values_t
*ev_nil
=
4825 p_err_descr
->get_field_err_values(field_cnt
-1);
4826 if (ev_nil
&& ev_nil
->value
) // value override for the last field
4828 nil_attribute
= (ev_nil
->value
->errval
== NULL
);
4833 if (nil_attribute
) { // req. exer and USE_NIL
4834 const namespace_t
*control_ns
= p_td
.my_module
->get_controlns();
4836 if (!nil_attribute_simple
) {
4837 // It is likely that the declaration for namespace "xsi"
4838 // was not written. Do it now.
4839 p_buf
.put_s(7, (cbyte
*)" xmlns:");
4840 p_buf
.put_s(strlen(control_ns
->px
), (cbyte
*)control_ns
->px
);
4841 p_buf
.put_s(2, (cbyte
*)"='");
4842 p_buf
.put_s(strlen(control_ns
->ns
), (cbyte
*)control_ns
->ns
);
4847 p_buf
.put_s(strlen(control_ns
->px
), (cbyte
*)control_ns
->px
);
4849 p_buf
.put_s(10, (cbyte
*)"nil='true'");
4850 if ((p_td
.xer_bits
& USE_ORDER
)) early_to_bed
= TRUE
;
4851 // The whole content was omitted; nothing to do (and if we tried
4852 // to do it, we'd get an error for over-indexing a 0-length record-of).
4855 if (delay_close
&& (!omit_tag
|| shorter
)) {
4856 // Close the start tag left open. If indenting, also write a newline
4857 // unless USE-NIL in effect or there is a single untagged component.
4859 ((p_td
.xer_bits
& (/*USE_NIL|*/HAS_1UNTAGGED
)) ? 0 : indenting
);
4860 p_buf
.put_s(start_tag_len
, (cbyte
*)">\n");
4863 // Erroneous values for the embed_values member (if any).
4864 // Collected once but referenced multiple times.
4865 const Erroneous_descriptor_t
* ed0
= NULL
;
4866 int embed_values_val_idx
= 0;
4867 int embed_values_descr_idx
= 0;
4869 if (exer
&& (p_td
.xer_bits
& EMBED_VALUES
)) {
4870 ed0
= p_err_descr
->next_field_emb_descr(0, edescr_idx
);
4872 // write the first string
4873 if (embed_values
->size_of() > 0) {
4874 const Erroneous_values_t
* ev0_0
= NULL
;
4875 const Erroneous_descriptor_t
* ed0_0
= NULL
;
4877 ev0_0
= ed0
->next_field_err_values(0, embed_values_val_idx
);
4878 ed0_0
= ed0
->next_field_emb_descr (0, embed_values_descr_idx
);
4880 sub_len
+= embed_values
->encode_element(0, UNIVERSAL_CHARSTRING_xer_
,
4881 ev0_0
, ed0_0
, p_buf
, flavor
| EMBED_VALUES
, indent
+!omit_tag
, 0);
4885 const Record_Type
*ordered
= this; // the record affected by USE-ORDER
4886 // By default it's this record, unless USE_NIL is _also_ in effect,
4887 // in which case it's the last member of this.
4889 // Index of the first non-attribute field of the record pointed to by
4890 // ordered, that is, the first field affected by USE-ORDER.
4891 size_t useorder_base
= first_nonattr
;
4894 int end
= field_cnt
; // "one past", do not touch
4895 // by default, continue from the current field until the end, indexing this
4897 if (exer
&& (p_td
.xer_bits
& USE_ORDER
)) {
4898 // the length of the loop is determined by the length of use_order
4899 const int to_send
= use_order
->size_of();
4901 // i will index all elements of the use_order member
4905 // Count the non-attribute optionals
4906 int n_optionals
= 0;
4907 for (int B
= optional_count() - 1; B
>=+0; B
--) {
4908 int oi
= get_optional_indexes()[B
];
4909 if (oi
< first_nonattr
) break;
4913 int expected_min
= field_cnt
- first_nonattr
- n_optionals
;
4914 int expected_max
= field_cnt
- first_nonattr
;
4916 if ((p_td
.xer_bits
& USE_NIL
) && get_at(field_cnt
-1)->ispresent()) {
4917 // The special case when USE_ORDER refers to the fields of a field,
4919 const Base_Type
*last_optional
= get_at(field_cnt
-1);
4920 const Base_Type
* inner
= last_optional
->get_opt_value();
4921 // it absolutely, positively has to be (derived from) Record_Type
4922 ordered
= static_cast<const Record_Type
*>(inner
);
4923 useorder_base
= ordered
->get_xer_num_attr();
4924 begin
= useorder_base
;
4925 end
= ordered
->get_count();
4927 expected_min
= expected_max
= ordered
->get_count();
4930 if (to_send
> expected_max
4931 ||to_send
< expected_min
) {
4932 ec_1
.set_msg("%s': ", fld_name(uo_index
));
4933 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_CONSTRAINT
,
4934 "Wrong number of USE-ORDER %d, must be %d..%d", to_send
, expected_min
, expected_max
);
4935 early_to_bed
= TRUE
; // don't bother sending anything
4937 else { // check no duplicates
4938 int *seen
= new int [to_send
];
4940 for (int ei
= 0; ei
< to_send
; ++ei
) {
4941 const Base_Type
*uoe
= use_order
->get_at(ei
);
4942 const Enum_Type
*enm
= static_cast<const Enum_Type
*>(uoe
);
4943 int val
= enm
->as_int();
4944 for (int x
= 0; x
< num_seen
; ++x
) {
4945 if (val
== seen
[x
]) { // complain
4946 ec_1
.set_msg("%s': ", fld_name(uo_index
));
4947 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_CONSTRAINT
,
4948 "Duplicate value for USE-ORDER");
4949 early_to_bed
= TRUE
; // don't bother sending anything
4953 seen
[num_seen
++] = val
;
4957 // If the number is right and there are no duplicates, then carry on
4959 } // endif(USE_ORDER)
4961 // Then, all the non-attributes. Structuring the code like this depends on
4962 // all attributes appearing before all non-attributes (excluding
4963 // pseudo-members for USE-ORDER, etc.)
4965 // This loop handles both the normal case (no USE_ORDER) when i indexes
4966 // fields of this record; and the USE_ORDER case (with or without USE-NIL).
4968 // early_to_bed can only be true if exer is true (transitive through nil_attribute)
4969 if (!early_to_bed
) {
4970 embed_values_enc_struct_t
* emb_val
= 0;
4971 if (exer
&& (p_td
.xer_bits
& EMBED_VALUES
) && embed_values
->size_of() > 1) {
4972 emb_val
= new embed_values_enc_struct_t
;
4973 emb_val
->embval_array
= embed_values
;
4974 emb_val
->embval_index
= 1;
4975 emb_val
->embval_err
= ed0
;
4976 emb_val
->embval_err_val_idx
= embed_values_val_idx
;
4977 emb_val
->embval_err_descr_idx
= embed_values_descr_idx
;
4980 for ( i
= begin
; i
< end
; ++i
) {
4982 const Base_Type
*uoe
= 0; // "useOrder enum"
4983 const Enum_Type
*enm
= 0; // the enum value selecting the field
4985 // "actual" index, may be perturbed by USE-ORDER.
4986 // We use this value to index the appropriate record.
4989 const Erroneous_values_t
* ev
= NULL
;
4990 const Erroneous_descriptor_t
* ed
= NULL
;
4991 if (exer
&& use_order
) {
4992 // If USE-ORDER is in effect, it introduces a level of indirection
4993 // into the indexing of fields: "i" is used to select an element
4994 // of the use_order member (an enum), whose value is used to select
4995 // the field being encoded.
4996 uoe
= use_order
->get_at(i
- begin
);
4997 enm
= static_cast<const Enum_Type
*>(uoe
);
4998 ai
= enm
->as_int() + useorder_base
;
5000 // Because it is not guaranteed that ai will increase monotonically,
5001 // we can't use next_field_...().
5002 ev
= p_err_descr
->get_field_err_values(ai
);
5003 ed
= p_err_descr
->get_field_emb_descr (ai
);
5005 else { // not USE-ORDER, sequential access
5006 ev
= p_err_descr
->next_field_err_values(ai
, values_idx
);
5007 ed
= p_err_descr
->next_field_emb_descr (ai
, edescr_idx
);
5009 ec_1
.set_msg("%s': ", ordered
->fld_name(ai
)); // non-attr
5011 if (ai
< p_err_descr
->omit_before
) continue;
5013 // omit_after value -1 becomes "very big".
5014 if ((unsigned int)ai
> (unsigned int)p_err_descr
->omit_after
) continue;
5015 // We can't skip all fields with break, because the next ai may be lower
5018 sub_len
+= ordered
->encode_field(ai
, ev
, ed
, p_buf
,
5019 // Pass USE-NIL to the last field (except when USE-ORDER is also in effect,
5020 // because the tag-stripping effect of USE-NIL has been achieved
5021 // by encoding the sub-fields directly).
5022 flavor
| ((exer
&& !use_order
&& (i
== field_cnt
-1)) ? (p_td
.xer_bits
& USE_NIL
) : 0),
5023 indent
+ !omit_tag
, emb_val
);
5025 // Now the next embed-values string (NOT affected by USE-ORDER!)
5026 if (exer
&& (p_td
.xer_bits
& EMBED_VALUES
) && 0 != emb_val
&&
5027 emb_val
->embval_index
< embed_values
->size_of()) {
5028 const Erroneous_values_t
* ev0_i
= NULL
;
5029 const Erroneous_descriptor_t
* ed0_i
= NULL
;
5031 ev0_i
= ed0
->next_field_err_values(emb_val
->embval_index
, emb_val
->embval_err_val_idx
);
5032 ed0_i
= ed0
->next_field_emb_descr (emb_val
->embval_index
, emb_val
->embval_err_descr_idx
);
5034 embed_values
->encode_element(emb_val
->embval_index
, UNIVERSAL_CHARSTRING_xer_
,
5035 ev0_i
, ed0_i
, p_buf
, flavor
| EMBED_VALUES
, indent
+ !omit_tag
, 0);
5036 ++emb_val
->embval_index
;
5040 if (emb_val
->embval_index
< embed_values
->size_of()) {
5041 ec_1
.set_msg("%s': ", fld_name(0));
5042 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_CONSTRAINT
,
5043 "Too many EMBED-VALUEs specified: %d (expected %d or less)",
5044 embed_values
->size_of(), emb_val
->embval_index
);
5048 } // if (!early_to_bed)
5053 if (sub_len
) { // something was written, now an end tag
5054 if (indenting
&& !(exer
&& (p_td
.xer_bits
& (HAS_1UNTAGGED
| USE_QNAME
))))
5055 // The tags of the last optional member involved with USE_NIL
5056 // have been removed. If it was a simple type, the content was probably
5057 // written on a single line without anything resembling a close tag.
5058 // Do not indent our end tag in this case.
5059 switch ((int)(exer
&& (p_td
.xer_bits
& USE_NIL
))) {
5061 const unsigned char *buf_end
= p_buf
.get_data() + (p_buf
.get_len()-1);
5062 if (buf_end
[-1] != '>' || *buf_end
!= '\n') break;
5063 // If it does not look like an end tag, skip the indenting,
5064 // else fall through.
5067 do_indent(p_buf
, indent
);
5072 if (exer
) write_ns_prefix(p_td
, p_buf
);
5073 p_buf
.put_s((size_t)p_td
.namelens
[exer
]-!indenting
, (cbyte
*)p_td
.names
[exer
]);
5075 else { // need to generate an empty element tag
5076 p_buf
.increase_length(-start_tag_len
); // decrease length
5077 p_buf
.put_s((size_t)2+indenting
, (cbyte
*)"/>\n");
5081 return (int)p_buf
.get_len() - encoded_length
;
5084 int Record_Type::XER_decode(const XERdescriptor_t
& p_td
, XmlReaderWrap
& reader
,
5085 unsigned int flavor
, embed_values_dec_struct_t
*)
5088 int exer
= is_exer(flavor
);
5090 int depth
=-1; // depth of the start tag
5091 int xerbits
= p_td
.xer_bits
;
5092 if (flavor
& XER_TOPLEVEL
) xerbits
&= ~UNTAGGED
;
5093 const boolean own_tag
= !(exer
5094 && ( (xerbits
& (ANY_ELEMENT
| UNTAGGED
| XER_ATTRIBUTE
))
5095 || (flavor
& (USE_NIL
| USE_TYPE_ATTR
))));
5096 boolean tag_closed
= (flavor
& PARENT_CLOSED
) != 0;
5097 // If the parent has USE-TYPE, our ATTRIBUTE members can be found
5098 // in the parent's tag (the reader is sitting on it).
5099 const boolean parent_tag
= exer
&& (flavor
& (/*USE_NIL|*/ USE_TYPE_ATTR
));
5101 // Filter out flags passed by our parent. These are not for the fields.
5102 flavor
&= XER_MASK
; // also removes XER_TOPLEVEL
5104 const int field_cnt
= get_count();
5105 const int num_attributes
= get_xer_num_attr();
5107 // The index of potential "order" field, regardless of whether USE_ORDER
5108 // is in use or not.
5109 const int uo_index
= ((p_td
.xer_bits
& EMBED_VALUES
) !=0);
5111 // The first "non-special" field (skipping the USE-ORDER and EMBED-VALUES
5112 // fields); normal processing start at this field.
5113 const int start_at
= uo_index
+ ((p_td
.xer_bits
& USE_ORDER
) != 0);
5114 const int first_nonattr
= start_at
+ num_attributes
;
5116 // The index of the ANY-ATTRIBUTES member, if any
5118 for (int k
= 0; k
< first_nonattr
; ++k
) {
5119 if (xer_descr(k
)->xer_bits
& ANY_ATTRIBUTES
) {
5121 if (!get_at(aa_index
)->is_optional()) {
5122 static_cast<Record_Of_Type
*>(get_at(aa_index
))->set_size(0);
5124 break; // there can be only one, 18.2.2
5128 if (own_tag
) for (success
=reader
.Ok(); success
==1; success
=reader
.Read()) {
5129 type
= reader
.NodeType();
5130 if (type
==XML_READER_TYPE_ELEMENT
) {
5131 verify_name(reader
, p_td
, exer
);
5132 depth
= reader
.Depth();
5133 tag_closed
= reader
.IsEmptyElement();
5140 if (exer
&& (p_td
.xer_bits
& USE_QNAME
)) { // QName trumps everything !
5141 // If element, it looks like this:
5142 // <name xmlns:b0="http://www.furniture.com">b0:table</name>
5143 // If attribute, it looks like this:
5146 if (p_td
.xer_bits
& XER_ATTRIBUTE
) success
= 1; // do nothing
5147 else for (success
= reader
.Read(); success
== 1; success
= reader
.Read()) {
5148 type
= reader
.NodeType();
5149 if (type
== XML_READER_TYPE_TEXT
) break;
5153 xmlChar
*val
= reader
.NewValue();
5154 xmlChar
*npfx
= (xmlChar
*)strchr((char*)val
, ':');
5157 *npfx
++ = '\0'; // cut the string into two
5165 xmlChar
*nsu
= reader
.LookupNamespace(pfx
);
5167 OPTIONAL
<UNIVERSAL_CHARSTRING
> *q_prefix2
=
5168 static_cast<OPTIONAL
<UNIVERSAL_CHARSTRING
>*>(get_at(0));
5169 if (nsu
) *q_prefix2
= (const char*)nsu
;
5170 else q_prefix2
->set_to_omit(); // public in RT2 only
5172 UNIVERSAL_CHARSTRING
*q_name2
= static_cast<UNIVERSAL_CHARSTRING
*>(get_at(1));
5173 *q_name2
= (const char*)npfx
;
5179 else { // not use-qname
5180 TTCN_EncDec_ErrorContext
ec_0("Component '");
5181 TTCN_EncDec_ErrorContext ec_1
;
5182 boolean usenil_attribute
= FALSE
; // true if found and said yes
5184 if (!reader
.IsEmptyElement()) reader
.Read();
5185 // First, the (would-be) attributes (unaffected by USE-ORDER)
5186 for (i
= 0; i
< first_nonattr
; i
++) {
5187 ec_1
.set_msg("%s': ", fld_name(i
));
5188 get_at(i
)->XER_decode(*xer_descr(i
), reader
, flavor
, 0);
5191 else if (own_tag
|| parent_tag
) { // EXER and not UNTAGGED: do attributes
5192 // Prepare for lack of attributes.
5193 // Fields with defaultForEmpty get the D-F-E value, optional get omit.
5194 for (i
= start_at
; i
< first_nonattr
; i
++) {
5195 Base_Type
&fld
= *get_at(i
);
5196 const XERdescriptor_t
& xd
= *xer_descr(i
);
5198 if (fld
.is_optional()) {
5199 fld
.set_to_present();
5200 fld
.get_opt_value()->set_value(xd
.dfeValue
);
5202 else fld
.set_value(xd
.dfeValue
);
5204 else if (fld
.is_optional()) fld
.set_to_omit();
5207 int num_aa
= 0; // index into the ANY-ATTRIBUTE member
5209 const namespace_t
*control_ns
= 0;
5210 if (parent_tag
|| (p_td
.xer_bits
& USE_NIL
)) {
5211 // xsi:type or xsi:nil
5212 control_ns
= p_td
.my_module
->get_controlns();
5215 /* * * * * * * * * Attributes * * * * * * * * * * * * * */
5216 for (success
= reader
.MoveToFirstAttribute();
5217 success
== 1 && reader
.NodeType() == XML_READER_TYPE_ATTRIBUTE
;
5218 success
= reader
.AdvanceAttribute())
5220 if (reader
.IsNamespaceDecl()) {
5221 continue; // namespace declarations are handled for us by libxml2
5224 const char *attr_name
= (const char*)reader
.LocalName();
5225 const char *ns_uri
= (const char*)reader
.NamespaceUri();
5226 int field_index
= get_index_byname(attr_name
, ns_uri
);
5227 if (field_index
!= -1) {
5228 // There is a field. Let it decode the attribute.
5229 ec_1
.set_msg("%s': ", fld_name(field_index
));
5230 get_at(field_index
)->XER_decode(*xer_descr(field_index
), reader
, flavor
, 0);
5234 // Attribute not found. It could be the "nil" attribute
5235 if (p_td
.xer_bits
& USE_NIL
) {
5236 const char *prefix
= (const char*)reader
.Prefix();
5237 // prefix may be NULL, control_ns->px is never NULL or empty
5238 if (prefix
&& !strcmp(prefix
, control_ns
->px
)
5239 && !strcmp((const char*)reader
.LocalName(), "nil"))
5240 { // It is the "nil" attribute
5241 const char *value
= (const char*)reader
.Value();
5243 if (!strcmp(value
, "1") || !strcmp(value
, "true")) {
5244 // The field affected by USE-NIL is always the last one
5245 get_at(field_cnt
-1)->set_to_omit();
5246 usenil_attribute
= TRUE
;
5251 } // it is the "nil" attribute
5252 } // type has USE-NIL
5255 const char *prefix
= (const char*)reader
.Prefix();
5256 // prefix may be NULL, control_ns->px is never NULL or empty
5257 if (prefix
&& !strcmp(prefix
, control_ns
->px
)
5258 && !strcmp((const char*)reader
.LocalName(), "type")) {
5259 continue; // xsi:type has been processed by the parent
5263 if (aa_index
>= 0) {
5264 ec_1
.set_msg("%s': ", fld_name(aa_index
));
5265 TTCN_EncDec_ErrorContext
ec_2("Attribute %d: ", num_aa
);
5266 // We have a component with ANY-ATTRIBUTE. It must be a record of
5267 // UNIVERSAL_CHARSTRING. Add the attribute to it.
5268 Record_Of_Type
*aa
= 0;
5269 if (get_at(aa_index
)->is_optional()) {
5271 get_at(aa_index
)->set_to_present();
5273 aa
= static_cast<Record_Of_Type
*>(get_at(aa_index
)->get_opt_value());
5276 aa
= static_cast<Record_Of_Type
*>(get_at(aa_index
));
5278 UNIVERSAL_CHARSTRING
*new_elem
= static_cast<UNIVERSAL_CHARSTRING
*>
5279 (aa
->get_at(num_aa
++));
5281 // Construct the AnyAttributeFormat (X.693amd1, 18.2.6)
5283 const xmlChar
*name
= reader
.LocalName();
5284 const xmlChar
*val
= reader
.Value();
5285 const xmlChar
*uri
= reader
.NamespaceUri();
5287 if (xer_descr(aa_index
)->xer_bits
& (ANY_FROM
| ANY_EXCEPT
)) {
5288 check_namespace_restrictions(*xer_descr(aa_index
), (const char*)uri
);
5290 // We don't care about reader.Prefix()
5291 // Using strlen to count UTF8 bytes, not characters
5292 aabuf
.put_s(uri
? strlen((const char*)uri
) : 0, uri
);
5293 if (uri
&& *uri
) aabuf
.put_c(' ');
5294 aabuf
.put_s(name
? strlen((const char*)name
) : 0, name
);
5297 aabuf
.put_s(val
? strlen((const char*)val
) : 0, val
);
5299 new_elem
->decode_utf8(aabuf
.get_len(), aabuf
.get_data());
5304 // Lastly check for the xsi:schemaLocation attribute, this does not
5305 // affect TTCN-3, but it shouldn't cause a DTE
5306 if (reader
.LocalName() && !strcmp((const char*)reader
.LocalName(), "schemaLocation")) {
5308 control_ns
= p_td
.my_module
->get_controlns();
5310 if (reader
.Prefix() && !strcmp((const char*)reader
.Prefix(), control_ns
->px
)) {
5315 // Nobody wanted the attribute. That is an error.
5316 ec_0
.set_msg(" "); ec_1
.set_msg(" ");
5317 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG
,
5318 "Unexpected attribute '%s', ns '%s'", attr_name
,
5319 ns_uri
? ns_uri
: "");
5322 // Now check that all mandatory attributes have been set
5323 for (i
= start_at
; i
< first_nonattr
; ++i
) {
5324 Base_Type
* fld
= get_at(i
);
5325 if (fld
->is_optional()) continue; // field is allowed to be unset
5326 if (!fld
->is_bound()) {
5327 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG
,
5328 "Missing attribute '%s'", this->fld_name(i
));
5332 i
= first_nonattr
; // finished with attributes
5333 // AdvanceAttribute did MoveToElement. Move into the content (if any).
5334 if (!reader
.IsEmptyElement()) reader
.Read();
5335 } // end if (own_tag)
5337 /* * * * * * * * Non-attributes (elements) * * * * * * * * * * * */
5338 embed_values_dec_struct_t
* emb_val
= 0;
5339 bool emb_val_optional
= false;
5340 if (exer
&& (p_td
.xer_bits
& EMBED_VALUES
)) {
5341 emb_val
= new embed_values_dec_struct_t
;
5342 emb_val
->embval_array
= dynamic_cast<Record_Of_Type
*>(get_at(0));
5343 if (NULL
== emb_val
->embval_array
) {
5344 OPTIONAL
<PreGenRecordOf::PREGEN__RECORD__OF__UNIVERSAL__CHARSTRING
>* embed_value
= static_cast<OPTIONAL
<PreGenRecordOf::PREGEN__RECORD__OF__UNIVERSAL__CHARSTRING
>*>(get_at(0));
5345 embed_value
->set_to_present();
5346 emb_val
->embval_array
= static_cast<Record_Of_Type
*>((*embed_value
).get_opt_value());
5347 emb_val_optional
= true;
5349 emb_val
->embval_array
->set_size(0);
5350 emb_val
->embval_index
= 0;
5353 if (exer
&& (p_td
.xer_bits
& USE_ORDER
)) {
5354 // Set all optional fields to omit because their respective XER_decode
5355 // will not be run (and will stay unbound) if the value is missing.
5356 int n_optionals
= 0;
5357 for (int B
= optional_count() - 1; B
>=+0; B
--) {
5358 int oi
= get_optional_indexes()[B
];
5359 if (oi
< first_nonattr
) break;
5360 get_at(oi
)->set_to_omit();
5364 Record_Of_Type
*use_order
= static_cast<Record_Of_Type
*>(get_at(uo_index
));
5365 // Initialize the use_order field to empty. Let it grow on demand.
5366 // (setting it to the minimum acceptable size may leave unbound elements
5367 // if the XML was incomplete).
5368 use_order
->set_size(0);
5370 // Nothing to order if there are no child elements
5372 Record_Type
*jumbled
= this; // the record affected by USE_ORDER
5373 int begin
= first_nonattr
;
5374 int end
= field_cnt
; // "one past"
5375 if (p_td
.xer_bits
& USE_NIL
) {
5376 Base_Type
*last_optional
= get_at(field_cnt
-1);
5377 if (!usenil_attribute
) { // exer known true
5378 last_optional
->set_to_present();
5379 jumbled
= static_cast<Record_Type
*>(last_optional
->get_opt_value());
5380 // We will operate on the members of last_optional,
5381 // effectively bypassing last_optional->XER_decode() itself.
5383 end
= jumbled
->get_count();
5384 ec_1
.set_msg("%s': ", fld_name(field_cnt
-1));
5387 if (num_attributes
> 0
5388 && first_nonattr
!= field_cnt
5389 && i
== first_nonattr
- 1) { // exer known true
5390 // If there were attributes and their processing just finished,
5391 // the reader is positioned on the start tag of the record.
5392 // Move ahead, unless there are no non-attribute fields.
5395 // Then, the non-attributes
5397 // The index runs over the members affected by USE-ORDER.
5398 // This is [first_nonattr,field_cnt) unless USE-NIL is involved,
5399 // in which case it's [0,optional_sequence::field_cnt)
5400 int *seen
= new int[end
-begin
];
5402 int last_any_elem
= begin
- 1;
5403 // The index of the latest embedded value can change outside of this function
5404 // (if the field is an untagged record of), in this case the next value should
5405 // be ignored, as it's already been handled by the record of
5406 int last_embval_index
= 0;
5407 bool early_exit
= false;
5408 for (i
= begin
; i
< end
; i
++) {
5409 for (success
= reader
.Ok(); success
== 1; success
= reader
.Read()) {
5410 type
= reader
.NodeType();
5411 if (0 != emb_val
&& reader
.NodeType()==XML_READER_TYPE_TEXT
) {
5412 UNIVERSAL_CHARSTRING
emb_ustr((const char*)reader
.Value());
5413 emb_val
->embval_array
->get_at(emb_val
->embval_index
)->set_value(&emb_ustr
);
5415 // The non-attribute components must not be UNTAGGED
5416 if (type
== XML_READER_TYPE_ELEMENT
) break;
5417 if (type
== XML_READER_TYPE_END_ELEMENT
) {
5423 if (last_embval_index
== emb_val
->embval_index
) {
5424 ++emb_val
->embval_index
;
5426 last_embval_index
= emb_val
->embval_index
;
5428 if (success
!= 1 || early_exit
) break;
5429 const char *name
= (const char *)reader
.LocalName();
5430 bool field_name_found
= false;
5431 // Find out which member it is.
5432 // FIXME some hashing should be implemented
5433 for (int k
= begin
; k
< end
; k
++) {
5434 if (!(jumbled
->xer_descr(k
)->xer_bits
& ANY_ELEMENT
) &&
5435 check_name(name
, *jumbled
->xer_descr(k
), 1)) {
5436 ec_1
.set_msg("%s': ", jumbled
->fld_name(k
));
5438 // Check for the same field being decoded twice.
5439 // We can't use the field's is_bound()/is_present(),
5440 // because the field may be bound on input, e.g. for
5441 // prototype(fast) or prototype(backtrack).
5442 int in_dex
= k
- begin
;
5443 for (int o
= 0; o
< num_seen
;++o
) {
5444 if (in_dex
== seen
[o
]) TTCN_EncDec_ErrorContext::error(
5445 TTCN_EncDec::ET_INVAL_MSG
, "Duplicate element");
5447 seen
[num_seen
++] = in_dex
;
5448 // Set the next use-order member.
5449 // Non-const get_at creates the object in the record-of.
5450 static_cast<Enum_Type
*>(use_order
->get_at(i
- begin
))
5452 Base_Type
*b
= jumbled
->get_at(k
);
5453 b
->XER_decode(*jumbled
->xer_descr(k
), reader
, flavor
, emb_val
);
5454 field_name_found
= true;
5458 if (!field_name_found
) {
5459 // Check the anyElement fields
5460 for (int k
= last_any_elem
+ 1; k
< end
; k
++) {
5461 if (jumbled
->xer_descr(k
)->xer_bits
& ANY_ELEMENT
) {
5462 ec_1
.set_msg("%s': ", jumbled
->fld_name(k
));
5464 // Check for the same field being decoded twice.
5465 // We can't use the field's is_bound()/is_present(),
5466 // because the field may be bound on input, e.g. for
5467 // prototype(fast) or prototype(backtrack).
5468 int in_dex
= k
- begin
;
5469 for (int o
= 0; o
< num_seen
;++o
) {
5470 if (in_dex
== seen
[o
]) TTCN_EncDec_ErrorContext::error(
5471 TTCN_EncDec::ET_INVAL_MSG
, "Duplicate element");
5473 seen
[num_seen
++] = in_dex
;
5474 // Set the next use-order member.
5475 // Non-const get_at creates the object in the record-of.
5476 static_cast<Enum_Type
*>(use_order
->get_at(i
- begin
))
5478 Base_Type
*b
= jumbled
->get_at(k
);
5479 b
->XER_decode(*jumbled
->xer_descr(k
), reader
, flavor
, emb_val
);
5481 field_name_found
= true;
5486 if (!field_name_found
) {
5487 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG
,
5488 "Bad XML tag '%s' instead of a valid field", name
);
5493 if (reader
.NodeType()==XML_READER_TYPE_TEXT
) {
5494 UNIVERSAL_CHARSTRING
emb_ustr((const char*)reader
.Value());
5495 emb_val
->embval_array
->get_at(emb_val
->embval_index
)->set_value(&emb_ustr
);
5497 if (last_embval_index
== emb_val
->embval_index
) {
5498 ++emb_val
->embval_index
;
5502 ec_1
.set_msg(" "); // no active component
5505 // Check that we collected the required number of children
5506 int num_collected
= use_order
->size_of();
5507 if (p_td
.xer_bits
& USE_NIL
) {
5508 int expected
= usenil_attribute
? 0 : jumbled
->get_count();
5509 if (num_collected
!= expected
) {
5510 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INCOMPL_MSG
,
5511 "Incorrect number of fields %d, expected %d",
5512 num_collected
, expected
);
5516 if (num_collected
< field_cnt
- first_nonattr
- n_optionals
5517 ||num_collected
> field_cnt
- first_nonattr
) {
5518 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INCOMPL_MSG
,
5519 "Wrong number of fields! size = %d, expected %d..%d",
5520 use_order
->size_of(), field_cnt
- first_nonattr
- n_optionals
,
5521 field_cnt
- first_nonattr
);
5524 } // not empty element
5526 else { // not USE-ORDER, simpler code
5527 if (usenil_attribute
) {
5528 reader
.MoveToElement(); // value absent, nothing more to do
5530 // The index of the latest embedded value can change outside of this function
5531 // (if the field is a untagged record of), in this case the next value should
5532 // be ignored, as it's already been handled by the record of
5533 // Omitted fields can also reset this value
5534 int last_embval_index
= 0;
5535 for (; i
<field_cnt
; i
++) {
5537 if (reader
.NodeType()==XML_READER_TYPE_TEXT
) {
5538 UNIVERSAL_CHARSTRING
emb_ustr((const char*)reader
.Value());
5539 emb_val
->embval_array
->get_at(emb_val
->embval_index
)->set_value(&emb_ustr
);
5541 if (last_embval_index
== emb_val
->embval_index
) {
5542 ++emb_val
->embval_index
;
5544 last_embval_index
= emb_val
->embval_index
;
5546 ec_1
.set_msg("%s': ", fld_name(i
));
5547 if (exer
&& i
==field_cnt
-1 && p_td
.dfeValue
&& reader
.IsEmptyElement()) {
5548 get_at(i
)->set_value(p_td
.dfeValue
);
5551 // In case the field is an optional anyElement -> check if it should be omitted
5552 bool optional_any_elem_check
= true;
5553 if (get_at(i
)->is_optional() && (xer_descr(i
)->xer_bits
& ANY_ELEMENT
)) {
5554 // The "anyElement" coding instruction can only be applied to a universal charstring field
5555 OPTIONAL
<UNIVERSAL_CHARSTRING
>* opt_field
= dynamic_cast<OPTIONAL
<UNIVERSAL_CHARSTRING
>*>(get_at(i
));
5557 const char* next_field_name
= NULL
;
5558 if (i
< field_cnt
- 1) {
5559 next_field_name
= fld_name(i
+ 1);
5561 optional_any_elem_check
= opt_field
->XER_check_any_elem(reader
, next_field_name
, tag_closed
);
5564 if (optional_any_elem_check
) {
5565 int new_flavor
= flavor
;
5566 if (i
== field_cnt
-1) new_flavor
|= (p_td
.xer_bits
& USE_NIL
);
5567 if (tag_closed
) new_flavor
|= PARENT_CLOSED
;
5569 get_at(i
)->XER_decode(*xer_descr(i
), reader
, new_flavor
, emb_val
);
5572 if (!get_at(i
)->is_present()) {
5573 // there was no new element, the last embedded value is for the next field
5574 // (or the end of the record if this is the last field)
5575 last_embval_index
= -1;
5579 if (reader
.NodeType()==XML_READER_TYPE_TEXT
) {
5580 UNIVERSAL_CHARSTRING
emb_ustr((const char*)reader
.Value());
5581 emb_val
->embval_array
->get_at(emb_val
->embval_index
)->set_value(&emb_ustr
);
5583 if (last_embval_index
== emb_val
->embval_index
) {
5584 ++emb_val
->embval_index
;
5591 bool all_unbound
= true;
5592 static const UNIVERSAL_CHARSTRING
emptystring(0, (const char*)NULL
);
5593 for (int j
= 0; j
< emb_val
->embval_index
; ++j
) {
5594 if (!emb_val
->embval_array
->get_at(j
)->is_bound()) {
5595 emb_val
->embval_array
->get_at(j
)->set_value(&emptystring
);
5596 }else if((static_cast<const UNIVERSAL_CHARSTRING
*>(emb_val
->embval_array
->get_at(j
)))->lengthof() !=0) {
5597 all_unbound
= false;
5600 if(emb_val_optional
&& all_unbound
){
5601 static_cast<OPTIONAL
<PreGenRecordOf::PREGEN__RECORD__OF__UNIVERSAL__CHARSTRING
>*>(get_at(0))->set_to_omit();
5604 } // if embed-values
5608 // Check if every non-optional field has been set
5609 for (i
= 0; i
< field_cnt
; ++i
) {
5610 if (!get_at(i
)->is_optional() && !get_at(i
)->is_bound()) {
5611 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INCOMPL_MSG
,
5612 "No data found for non-optional field '%s'", fld_name(i
));
5617 // We had our start tag. Then our fields did their thing.
5618 // Now we expect the end tag. And it better be our end tag!
5620 for (success
= reader
.Ok(); success
== 1; success
= reader
.Read()) {
5621 type
= reader
.NodeType();
5622 current_depth
= reader
.Depth();
5623 if (current_depth
> depth
) {
5624 if (XML_READER_TYPE_ELEMENT
== type
) {
5625 // We found a deeper start tag; it was not processed at all.
5626 // That is an error (maybe we should report error for all node types
5627 // except TEXT and WHITESPACE, not just ELEMENT).
5628 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TAG
,
5629 "Unprocessed XML tag `%s'", (const char *)reader
.Name());
5632 continue; // go past hoping that our end tag will arrive eventually
5634 else if (current_depth
== depth
) { // at our level
5635 if (XML_READER_TYPE_ELEMENT
== type
) {
5636 verify_name(reader
, p_td
, exer
);
5637 if (reader
.IsEmptyElement()) {
5638 // FIXME this shouldn't really be possible;
5639 // only an empty record should be encoded as an empty element,
5640 // but those are implemented by Empty_Record_Type, not Record_Type.
5641 reader
.Read(); // one last time
5645 // If we find an end tag at the right depth, it must be ours
5646 else if (XML_READER_TYPE_END_ELEMENT
== type
) {
5647 verify_end(reader
, p_td
, depth
, exer
);
5652 else { //current_depth < depth; something has gone horribly wrong
5653 break; // better quit before we do further damage
5654 // Don't report an error; every enclosing type would do so,
5655 // spewing the same message over and over.
5659 return 1; // decode successful
5662 int Record_Type::JSON_encode(const TTCN_Typedescriptor_t
& p_td
, JSON_Tokenizer
& p_tok
) const
5665 return JSON_encode_negtest(err_descr
, p_td
, p_tok
);
5669 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND
,
5670 "Encoding an unbound %s value.", is_set() ? "set" : "record");
5674 int enc_len
= p_tok
.put_next_token(JSON_TOKEN_OBJECT_START
, NULL
);
5676 int field_count
= get_count();
5677 for (int i
= 0; i
< field_count
; ++i
) {
5678 boolean metainfo_unbound
= NULL
!= fld_descr(i
)->json
&& fld_descr(i
)->json
->metainfo_unbound
;
5679 if ((NULL
!= fld_descr(i
)->json
&& fld_descr(i
)->json
->omit_as_null
) ||
5680 get_at(i
)->is_present() || metainfo_unbound
) {
5681 const char* field_name
= (NULL
!= fld_descr(i
)->json
&& NULL
!= fld_descr(i
)->json
->alias
) ?
5682 fld_descr(i
)->json
->alias
: fld_name(i
);
5683 enc_len
+= p_tok
.put_next_token(JSON_TOKEN_NAME
, field_name
);
5684 if (metainfo_unbound
&& !get_at(i
)->is_bound()) {
5685 enc_len
+= p_tok
.put_next_token(JSON_TOKEN_LITERAL_NULL
);
5686 char* metainfo_str
= mprintf("metainfo %s", field_name
);
5687 enc_len
+= p_tok
.put_next_token(JSON_TOKEN_NAME
, metainfo_str
);
5689 enc_len
+= p_tok
.put_next_token(JSON_TOKEN_STRING
, "\"unbound\"");
5692 enc_len
+= get_at(i
)->JSON_encode(*fld_descr(i
), p_tok
);
5697 enc_len
+= p_tok
.put_next_token(JSON_TOKEN_OBJECT_END
, NULL
);
5701 int Record_Type::JSON_encode_negtest(const Erroneous_descriptor_t
* p_err_descr
,
5702 const TTCN_Typedescriptor_t
& p_td
,
5703 JSON_Tokenizer
& p_tok
) const
5706 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND
,
5707 "Encoding an unbound %s value.", is_set() ? "set" : "record");
5711 int enc_len
= p_tok
.put_next_token(JSON_TOKEN_OBJECT_START
, NULL
);
5716 int field_count
= get_count();
5717 for (int i
= 0; i
< field_count
; ++i
) {
5718 if (-1 != p_err_descr
->omit_before
&& p_err_descr
->omit_before
> i
) {
5722 const Erroneous_values_t
* err_vals
= p_err_descr
->next_field_err_values(i
, values_idx
);
5723 const Erroneous_descriptor_t
* emb_descr
= p_err_descr
->next_field_emb_descr(i
, edescr_idx
);
5725 if (NULL
!= err_vals
&& NULL
!= err_vals
->before
) {
5726 if (NULL
== err_vals
->before
->errval
) {
5727 TTCN_error("internal error: erroneous before value missing");
5729 if (err_vals
->before
->raw
) {
5730 enc_len
+= err_vals
->before
->errval
->JSON_encode_negtest_raw(p_tok
);
5732 if (NULL
== err_vals
->before
->type_descr
) {
5733 TTCN_error("internal error: erroneous before typedescriptor missing");
5735 // it's an extra field, so use the erroneous type's name as the field name
5736 enc_len
+= p_tok
.put_next_token(JSON_TOKEN_NAME
, err_vals
->before
->type_descr
->name
);
5737 enc_len
+= err_vals
->before
->errval
->JSON_encode(*(err_vals
->before
->type_descr
), p_tok
);
5741 const char* field_name
= (NULL
!= fld_descr(i
)->json
&& NULL
!= fld_descr(i
)->json
->alias
) ?
5742 fld_descr(i
)->json
->alias
: fld_name(i
);
5743 if (NULL
!= err_vals
&& NULL
!= err_vals
->value
) {
5744 if (NULL
!= err_vals
->value
->errval
) {
5745 if (err_vals
->value
->raw
) {
5746 enc_len
+= err_vals
->value
->errval
->JSON_encode_negtest_raw(p_tok
);
5748 if (NULL
== err_vals
->value
->type_descr
) {
5749 TTCN_error("internal error: erroneous before typedescriptor missing");
5751 // only replace the field's value, keep the field name
5752 enc_len
+= p_tok
.put_next_token(JSON_TOKEN_NAME
, field_name
);
5753 enc_len
+= err_vals
->value
->errval
->JSON_encode(*(err_vals
->value
->type_descr
), p_tok
);
5757 boolean metainfo_unbound
= NULL
!= fld_descr(i
)->json
&& fld_descr(i
)->json
->metainfo_unbound
;
5758 if ((NULL
!= fld_descr(i
)->json
&& fld_descr(i
)->json
->omit_as_null
) ||
5759 get_at(i
)->is_present() || metainfo_unbound
) {
5760 enc_len
+= p_tok
.put_next_token(JSON_TOKEN_NAME
, field_name
);
5761 if (metainfo_unbound
&& !get_at(i
)->is_bound()) {
5762 enc_len
+= p_tok
.put_next_token(JSON_TOKEN_LITERAL_NULL
);
5763 char* metainfo_str
= mprintf("metainfo %s", field_name
);
5764 enc_len
+= p_tok
.put_next_token(JSON_TOKEN_NAME
, metainfo_str
);
5766 enc_len
+= p_tok
.put_next_token(JSON_TOKEN_STRING
, "\"unbound\"");
5768 else if (NULL
!= emb_descr
) {
5769 enc_len
+= get_at(i
)->JSON_encode_negtest(emb_descr
, *fld_descr(i
), p_tok
);
5771 enc_len
+= get_at(i
)->JSON_encode(*fld_descr(i
), p_tok
);
5776 if (NULL
!= err_vals
&& NULL
!= err_vals
->after
) {
5777 if (NULL
== err_vals
->after
->errval
) {
5778 TTCN_error("internal error: erroneous after value missing");
5780 if (err_vals
->after
->raw
) {
5781 enc_len
+= err_vals
->after
->errval
->JSON_encode_negtest_raw(p_tok
);
5783 if (NULL
== err_vals
->after
->type_descr
) {
5784 TTCN_error("internal error: erroneous before typedescriptor missing");
5786 // it's an extra field, so use the erroneous type's name as the field name
5787 enc_len
+= p_tok
.put_next_token(JSON_TOKEN_NAME
, err_vals
->after
->type_descr
->name
);
5788 enc_len
+= err_vals
->after
->errval
->JSON_encode(*(err_vals
->after
->type_descr
), p_tok
);
5792 if (-1 != p_err_descr
->omit_after
&& p_err_descr
->omit_after
<= i
) {
5797 enc_len
+= p_tok
.put_next_token(JSON_TOKEN_OBJECT_END
, NULL
);
5801 int Record_Type::JSON_decode(const TTCN_Typedescriptor_t
& p_td
, JSON_Tokenizer
& p_tok
, boolean p_silent
)
5803 json_token_t token
= JSON_TOKEN_NONE
;
5804 int dec_len
= p_tok
.get_next_token(&token
, NULL
, NULL
);
5805 if (JSON_TOKEN_ERROR
== token
) {
5806 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG
, JSON_DEC_BAD_TOKEN_ERROR
, "");
5807 return JSON_ERROR_FATAL
;
5809 else if (JSON_TOKEN_OBJECT_START
!= token
) {
5810 return JSON_ERROR_INVALID_TOKEN
;
5814 const int field_count
= get_count();
5816 // initialize meta info states
5817 int* metainfo
= new int[field_count
];
5818 for (int i
= 0; i
< field_count
; ++i
) {
5819 metainfo
[i
] = (NULL
!= fld_descr(i
)->json
&& fld_descr(i
)->json
->metainfo_unbound
) ?
5820 JSON_METAINFO_NONE
: JSON_METAINFO_NOT_APPLICABLE
;
5824 // Read name - value token pairs until we reach some other token
5826 size_t name_len
= 0;
5827 size_t buf_pos
= p_tok
.get_buf_pos();
5828 dec_len
+= p_tok
.get_next_token(&token
, &name
, &name_len
);
5829 if (JSON_TOKEN_ERROR
== token
) {
5830 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG
, JSON_DEC_BAD_TOKEN_ERROR
, "");
5831 return JSON_ERROR_FATAL
;
5833 else if (JSON_TOKEN_NAME
!= token
) {
5834 // undo the last action on the buffer
5835 p_tok
.set_buf_pos(buf_pos
);
5839 // check for meta info
5840 boolean is_metainfo
= FALSE
;
5841 if (name_len
> 9 && 0 == strncmp(name
, "metainfo ", 9)) {
5849 for (field_idx
= 0; field_idx
< field_count
; ++field_idx
) {
5850 const char* expected_name
= 0;
5851 if (NULL
!= fld_descr(field_idx
)->json
&& NULL
!= fld_descr(field_idx
)->json
->alias
) {
5852 expected_name
= fld_descr(field_idx
)->json
->alias
;
5854 expected_name
= fld_name(field_idx
);
5856 if (strlen(expected_name
) == name_len
&&
5857 0 == strncmp(expected_name
, name
, name_len
)) {
5861 if (field_count
== field_idx
) {
5862 // invalid field name
5863 char* name2
= mcopystrn(name
, name_len
);
5864 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG
, is_metainfo
?
5865 JSON_DEC_METAINFO_NAME_ERROR
: JSON_DEC_INVALID_NAME_ERROR
, name2
);
5866 // if this is set to a warning, skip the value of the field
5867 dec_len
+= p_tok
.get_next_token(&token
, NULL
, NULL
);
5868 if (JSON_TOKEN_NUMBER
!= token
&& JSON_TOKEN_STRING
!= token
&&
5869 JSON_TOKEN_LITERAL_TRUE
!= token
&& JSON_TOKEN_LITERAL_FALSE
!= token
&&
5870 JSON_TOKEN_LITERAL_NULL
!= token
) {
5871 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG
, JSON_DEC_FIELD_TOKEN_ERROR
, name2
);
5873 return JSON_ERROR_FATAL
;
5880 if (JSON_METAINFO_NOT_APPLICABLE
!= metainfo
[field_idx
]) {
5882 char* info_value
= 0;
5883 size_t info_len
= 0;
5884 dec_len
+= p_tok
.get_next_token(&token
, &info_value
, &info_len
);
5885 if (JSON_TOKEN_STRING
== token
&& 9 == info_len
&&
5886 0 == strncmp(info_value
, "\"unbound\"", 9)) {
5887 metainfo
[field_idx
] = JSON_METAINFO_UNBOUND
;
5890 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG
, JSON_DEC_METAINFO_VALUE_ERROR
,
5891 fld_name(field_idx
));
5892 return JSON_ERROR_FATAL
;
5896 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG
, JSON_DEC_METAINFO_NOT_APPLICABLE
,
5897 fld_name(field_idx
));
5898 return JSON_ERROR_FATAL
;
5902 buf_pos
= p_tok
.get_buf_pos();
5903 int ret_val
= get_at(field_idx
)->JSON_decode(*fld_descr(field_idx
), p_tok
, p_silent
);
5905 if (JSON_ERROR_INVALID_TOKEN
== ret_val
) {
5906 // undo the last action on the buffer, check if the invalid token was a null token
5907 p_tok
.set_buf_pos(buf_pos
);
5908 p_tok
.get_next_token(&token
, NULL
, NULL
);
5909 if (JSON_TOKEN_LITERAL_NULL
== token
) {
5910 if (JSON_METAINFO_NONE
== metainfo
[field_idx
]) {
5911 // delay reporting an error for now, there might be meta info later
5912 metainfo
[field_idx
] = JSON_METAINFO_NEEDED
;
5915 else if (JSON_METAINFO_UNBOUND
== metainfo
[field_idx
]) {
5916 // meta info already found
5920 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG
, JSON_DEC_FIELD_TOKEN_ERROR
, fld_name(field_idx
));
5922 return JSON_ERROR_FATAL
;
5929 dec_len
+= p_tok
.get_next_token(&token
, NULL
, NULL
);
5930 if (JSON_TOKEN_OBJECT_END
!= token
) {
5931 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG
, JSON_DEC_OBJECT_END_TOKEN_ERROR
, "");
5932 return JSON_ERROR_FATAL
;
5935 // Check if every field has been set and handle meta info
5936 for (int field_idx
= 0; field_idx
< field_count
; ++field_idx
) {
5937 Base_Type
* field
= get_at(field_idx
);
5938 if (JSON_METAINFO_UNBOUND
== metainfo
[field_idx
]) {
5941 else if (JSON_METAINFO_NEEDED
== metainfo
[field_idx
]) {
5942 // no meta info was found for this field, report the delayed error
5943 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG
, JSON_DEC_FIELD_TOKEN_ERROR
, fld_name(field_idx
));
5945 else if (!field
->is_bound()) {
5946 if (NULL
!= fld_descr(field_idx
)->json
&& NULL
!= fld_descr(field_idx
)->json
->default_value
) {
5947 get_at(field_idx
)->JSON_decode(*fld_descr(field_idx
), DUMMY_BUFFER
, p_silent
);
5949 else if (field
->is_optional()) {
5950 field
->set_to_omit();
5952 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG
, JSON_DEC_MISSING_FIELD_ERROR
, fld_name(field_idx
));
5953 return JSON_ERROR_FATAL
;
5963 ////////////////////////////////////////////////////////////////////////////////
5965 Empty_Record_Type::Empty_Record_Type(): bound_flag(FALSE
)
5969 Empty_Record_Type::Empty_Record_Type(const Empty_Record_Type
& other_value
)
5970 : Base_Type(other_value
), bound_flag(other_value
.bound_flag
)
5972 if (!other_value
.bound_flag
)
5973 TTCN_error("Copying an unbound value of type %s.",
5974 other_value
.get_descriptor()->name
);
5977 boolean
Empty_Record_Type::operator==(null_type
) const
5980 TTCN_error("Comparison of an unbound value of type %s.",
5981 get_descriptor()->name
);
5985 void Empty_Record_Type::log() const
5987 if (bound_flag
) TTCN_Logger::log_event_str("{ }");
5988 else TTCN_Logger::log_event_unbound();
5991 void Empty_Record_Type::set_param(Module_Param
& param
) {
5992 param
.basic_check(Module_Param::BC_VALUE
, "empty record/set value (i.e. { })");
5993 Module_Param_Ptr mp
= ¶m
;
5994 if (param
.get_type() == Module_Param::MP_Reference
) {
5995 mp
= param
.get_referenced_param();
5997 if (mp
->get_type()!=Module_Param::MP_Value_List
|| mp
->get_size()>0) {
5998 param
.type_error("empty record/set value (i.e. { })", get_descriptor()->name
);
6003 Module_Param
* Empty_Record_Type::get_param(Module_Param_Name
& /* param_name */) const
6006 return new Module_Param_Unbound();
6008 return new Module_Param_Value_List();
6011 void Empty_Record_Type::encode_text(Text_Buf
& /*text_buf*/) const
6014 TTCN_error("Text encoder: Encoding an unbound value of type %s.",
6015 get_descriptor()->name
);
6018 void Empty_Record_Type::decode_text(Text_Buf
& /*text_buf*/)
6023 boolean
Empty_Record_Type::is_equal(const Base_Type
* other_value
) const
6025 const Empty_Record_Type
* r2
= static_cast<const Empty_Record_Type
*>(other_value
);
6026 if ((bound_flag
&& r2
->bound_flag
) || (!bound_flag
&& !r2
->bound_flag
))
6028 if (!bound_flag
|| !r2
->bound_flag
)
6029 TTCN_error("Comparison of an unbound value of type %s.", get_descriptor()->name
);
6033 void Empty_Record_Type::set_value(const Base_Type
* other_value
)
6035 if (!static_cast<const Empty_Record_Type
*>(other_value
)->is_bound())
6036 TTCN_error("Assignment of an unbound value of type %s.",
6037 other_value
->get_descriptor()->name
);
6041 void Empty_Record_Type::encode(const TTCN_Typedescriptor_t
& p_td
,
6042 TTCN_Buffer
& p_buf
, TTCN_EncDec::coding_t p_coding
, ...) const
6045 va_start(pvar
, p_coding
);
6047 case TTCN_EncDec::CT_BER
: {
6048 TTCN_EncDec_ErrorContext
ec("While BER-encoding type '%s': ", p_td
.name
);
6049 unsigned BER_coding
=va_arg(pvar
, unsigned);
6050 BER_encode_chk_coding(BER_coding
);
6051 ASN_BER_TLV_t
*tlv
=BER_encode_TLV(p_td
, BER_coding
);
6052 tlv
->put_in_buffer(p_buf
);
6053 ASN_BER_TLV_t::destruct(tlv
);
6055 case TTCN_EncDec::CT_RAW
: {
6056 TTCN_EncDec_ErrorContext
ec("While RAW-encoding type '%s': ", p_td
.name
);
6057 if(!p_td
.raw
) TTCN_EncDec_ErrorContext::error_internal
6058 ("No RAW descriptor available for type '%s'.", p_td
.name
);
6062 RAW_enc_tree
root(FALSE
, NULL
, &rp
, 1, p_td
.raw
);
6063 RAW_encode(p_td
, root
);
6064 root
.put_to_buf(p_buf
);
6066 case TTCN_EncDec::CT_TEXT
: {
6067 TTCN_EncDec_ErrorContext
ec("While TEXT-encoding type '%s': ", p_td
.name
);
6068 if(!p_td
.text
) TTCN_EncDec_ErrorContext::error_internal
6069 ("No TEXT descriptor available for type '%s'.", p_td
.name
);
6070 TEXT_encode(p_td
,p_buf
);
6072 case TTCN_EncDec::CT_XER
: {
6073 TTCN_EncDec_ErrorContext
ec("While XER-encoding type '%s': ", p_td
.name
);
6074 unsigned XER_coding
=va_arg(pvar
, unsigned);
6075 XER_encode(*(p_td
.xer
),p_buf
, XER_coding
, 0, 0);
6078 case TTCN_EncDec::CT_JSON
: {
6079 TTCN_EncDec_ErrorContext
ec("While JSON-encoding type '%s': ", p_td
.name
);
6080 if(!p_td
.json
) TTCN_EncDec_ErrorContext::error_internal
6081 ("No JSON descriptor available for type '%s'.", p_td
.name
);
6082 JSON_Tokenizer
tok(va_arg(pvar
, int) != 0);
6083 JSON_encode(p_td
, tok
);
6084 p_buf
.put_s(tok
.get_buffer_length(), (const unsigned char*)tok
.get_buffer());
6087 TTCN_error("Unknown coding method requested to encode type '%s'", p_td
.name
);
6092 void Empty_Record_Type::decode(const TTCN_Typedescriptor_t
& p_td
,
6093 TTCN_Buffer
& p_buf
, TTCN_EncDec::coding_t p_coding
, ...)
6096 va_start(pvar
, p_coding
);
6098 case TTCN_EncDec::CT_BER
: {
6099 TTCN_EncDec_ErrorContext
ec("While BER-decoding type '%s': ", p_td
.name
);
6100 unsigned L_form
=va_arg(pvar
, unsigned);
6102 BER_decode_str2TLV(p_buf
, tlv
, L_form
);
6103 BER_decode_TLV(p_td
, tlv
, L_form
);
6104 if(tlv
.isComplete
) p_buf
.increase_pos(tlv
.get_len());
6106 case TTCN_EncDec::CT_RAW
: {
6107 TTCN_EncDec_ErrorContext
ec("While RAW-decoding type '%s': ", p_td
.name
);
6109 TTCN_EncDec_ErrorContext::error_internal
6110 ("No RAW descriptor available for type '%s'.", p_td
.name
);
6112 switch(p_td
.raw
->top_bit_order
) {
6120 if(RAW_decode(p_td
, p_buf
, p_buf
.get_len()*8, order
)<0)
6121 ec
.error(TTCN_EncDec::ET_INCOMPL_MSG
,
6122 "Can not decode type '%s', because invalid or incomplete"
6123 " message was received", p_td
.name
);
6125 case TTCN_EncDec::CT_TEXT
: {
6126 Limit_Token_List limit
;
6127 TTCN_EncDec_ErrorContext
ec("While TEXT-decoding type '%s': ", p_td
.name
);
6128 if(!p_td
.text
) TTCN_EncDec_ErrorContext::error_internal
6129 ("No TEXT descriptor available for type '%s'.", p_td
.name
);
6130 const unsigned char *b
=p_buf
.get_data();
6131 if(b
[p_buf
.get_len()-1]!='\0'){
6132 p_buf
.set_pos(p_buf
.get_len());
6133 p_buf
.put_zero(8,ORDER_LSB
);
6136 if(TEXT_decode(p_td
,p_buf
,limit
)<0)
6137 ec
.error(TTCN_EncDec::ET_INCOMPL_MSG
,
6138 "Can not decode type '%s', because invalid or incomplete"
6139 " message was received", p_td
.name
);
6141 case TTCN_EncDec::CT_XER
: {
6142 TTCN_EncDec_ErrorContext
ec("While XER-decoding type '%s': ", p_td
.name
);
6143 unsigned XER_coding
=va_arg(pvar
, unsigned);
6144 XmlReaderWrap
reader(p_buf
);
6145 for (int success
=reader
.Read(); success
==1; success
=reader
.Read()) {
6146 if (reader
.NodeType() == XML_READER_TYPE_ELEMENT
) break;
6148 XER_decode(*(p_td
.xer
), reader
, XER_coding
| XER_TOPLEVEL
, 0);
6149 size_t bytes
= reader
.ByteConsumed();
6150 p_buf
.set_pos(bytes
);
6152 case TTCN_EncDec::CT_JSON
: {
6153 TTCN_EncDec_ErrorContext
ec("While JSON-decoding type '%s': ", p_td
.name
);
6154 if(!p_td
.json
) TTCN_EncDec_ErrorContext::error_internal
6155 ("No JSON descriptor available for type '%s'.", p_td
.name
);
6156 JSON_Tokenizer
tok((const char*)p_buf
.get_data(), p_buf
.get_len());
6157 if(JSON_decode(p_td
, tok
, false)<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
);
6161 p_buf
.set_pos(tok
.get_buf_pos());
6164 TTCN_error("Unknown coding method requested to decode type '%s'", p_td
.name
);
6169 ASN_BER_TLV_t
* Empty_Record_Type::BER_encode_TLV(const TTCN_Typedescriptor_t
& p_td
,
6170 unsigned p_coding
) const
6172 BER_chk_descr(p_td
);
6173 ASN_BER_TLV_t
*new_tlv
=ASN_BER_TLV_t::construct(NULL
);
6174 new_tlv
=ASN_BER_V2TLV(new_tlv
, p_td
, p_coding
);
6178 boolean
Empty_Record_Type::BER_decode_TLV(const TTCN_Typedescriptor_t
& p_td
,
6179 const ASN_BER_TLV_t
& p_tlv
, unsigned L_form
)
6181 BER_chk_descr(p_td
);
6182 ASN_BER_TLV_t stripped_tlv
;
6183 BER_decode_strip_tags(*p_td
.ber
, p_tlv
, L_form
, stripped_tlv
);
6184 TTCN_EncDec_ErrorContext
ec_0("While decoding '%s' type: ", get_descriptor()->name
);
6185 stripped_tlv
.chk_constructed_flag(TRUE
);
6190 int Empty_Record_Type::RAW_encode(const TTCN_Typedescriptor_t
& p_td
,
6191 RAW_enc_tree
& /*myleaf*/) const
6193 if (!bound_flag
) TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND
,
6194 "Encoding an unbound value of type %s.", p_td
.name
);
6198 int Empty_Record_Type::RAW_decode(const TTCN_Typedescriptor_t
& p_td
,
6199 TTCN_Buffer
& buff
, int /*limit*/, raw_order_t
/*top_bit_ord*/,
6200 boolean
/*no_err*/, int /*sel_field*/, boolean
/*first_call*/)
6203 return buff
.increase_pos_padd(p_td
.raw
->prepadding
)
6204 + buff
.increase_pos_padd(p_td
.raw
->padding
);
6207 int Empty_Record_Type::TEXT_encode(const TTCN_Typedescriptor_t
& p_td
, TTCN_Buffer
& buff
) const
6209 int encoded_length
=0;
6210 if(p_td
.text
->begin_encode
) {
6211 buff
.put_cs(*p_td
.text
->begin_encode
);
6212 encoded_length
+=p_td
.text
->begin_encode
->lengthof();
6215 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND
, "Encoding an unbound value.");
6217 if(p_td
.text
->end_encode
) {
6218 buff
.put_cs(*p_td
.text
->end_encode
);
6219 encoded_length
+=p_td
.text
->end_encode
->lengthof();
6221 return encoded_length
;
6224 int Empty_Record_Type::TEXT_decode(const TTCN_Typedescriptor_t
& p_td
,
6225 TTCN_Buffer
& buff
, Limit_Token_List
& /*limit*/, boolean no_err
, boolean
/*first_call*/)
6227 int decoded_length
=0;
6228 if(p_td
.text
->begin_decode
) {
6230 if((tl
=p_td
.text
->begin_decode
->match_begin(buff
))<0) {
6231 if(no_err
)return -1;
6232 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR
,
6233 "The specified token '%s' not found for '%s': ",
6234 (const char*)*(p_td
.text
->begin_decode
), p_td
.name
);
6238 buff
.increase_pos(tl
);
6240 if(p_td
.text
->end_decode
) {
6242 if((tl
=p_td
.text
->end_decode
->match_begin(buff
))<0) {
6243 if(no_err
)return -1;
6244 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR
,
6245 "The specified token '%s' not found for '%s': ",
6246 (const char*)*(p_td
.text
->end_decode
), p_td
.name
);
6250 buff
.increase_pos(tl
);
6253 return decoded_length
;
6256 int Empty_Record_Type::XER_encode(const XERdescriptor_t
& p_td
,
6257 TTCN_Buffer
& p_buf
, unsigned int flavor
, int indent
, embed_values_enc_struct_t
*) const
6259 int encoded_length
=(int)p_buf
.get_len();
6260 int indenting
= !is_canonical(flavor
);
6261 int exer
= is_exer(flavor
);
6262 if (indenting
) do_indent(p_buf
, indent
);
6264 if (exer
) write_ns_prefix(p_td
, p_buf
);
6265 p_buf
.put_s((size_t)p_td
.namelens
[exer
]-2, (cbyte
*)p_td
.names
[exer
]);
6266 p_buf
.put_s(2 + indenting
, (cbyte
*)"/>\n");
6267 return (int)p_buf
.get_len() - encoded_length
;
6270 int Empty_Record_Type::XER_decode(const XERdescriptor_t
& p_td
,
6271 XmlReaderWrap
& reader
, unsigned int flavor
, embed_values_dec_struct_t
*)
6273 int exer
= is_exer(flavor
);
6275 int success
, depth
= -1;
6276 for (success
=reader
.Ok(); success
==1; success
=reader
.Read()) {
6277 int type
= reader
.NodeType();
6278 if (type
==XML_READER_TYPE_ELEMENT
) {
6279 verify_name(reader
, p_td
, exer
);
6280 depth
= reader
.Depth();
6282 if (reader
.IsEmptyElement()) {
6283 reader
.Read(); break;
6285 else if ((flavor
& XER_MASK
) == XER_CANONICAL
) {
6286 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG
,
6287 "Expected an empty element tag");
6288 // Stay in the loop and look for the end element, in case the error
6289 // was ignored or reduced to warning.
6292 else if (type
== XML_READER_TYPE_END_ELEMENT
&& depth
!= -1) {
6293 verify_end(reader
, p_td
, depth
, exer
);
6298 return 1; // decode successful
6301 int Empty_Record_Type::JSON_encode(const TTCN_Typedescriptor_t
&, JSON_Tokenizer
& p_tok
) const
6304 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND
,
6305 "Encoding an unbound empty %s value.", is_set() ? "set" : "record");
6309 return p_tok
.put_next_token(JSON_TOKEN_OBJECT_START
, NULL
) +
6310 p_tok
.put_next_token(JSON_TOKEN_OBJECT_END
, NULL
);
6313 int Empty_Record_Type::JSON_decode(const TTCN_Typedescriptor_t
&, JSON_Tokenizer
& p_tok
, boolean p_silent
)
6315 json_token_t token
= JSON_TOKEN_NONE
;
6316 int dec_len
= p_tok
.get_next_token(&token
, NULL
, NULL
);
6317 if (JSON_TOKEN_ERROR
== token
) {
6318 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG
, JSON_DEC_BAD_TOKEN_ERROR
, "");
6319 return JSON_ERROR_FATAL
;
6321 else if (JSON_TOKEN_OBJECT_START
!= token
) {
6322 return JSON_ERROR_INVALID_TOKEN
;
6325 dec_len
+= p_tok
.get_next_token(&token
, NULL
, NULL
);
6326 if (JSON_TOKEN_OBJECT_END
!= token
) {
6327 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG
, JSON_DEC_STATIC_OBJECT_END_TOKEN_ERROR
, "");
6328 return JSON_ERROR_FATAL
;
6336 boolean
operator==(null_type
/*null_value*/, const Empty_Record_Type
& other_value
)
6338 if (!other_value
.is_bound())
6339 TTCN_error("Comparison of an unbound value of type %s.",
6340 other_value
.get_descriptor()->name
);
6344 boolean
operator!=(null_type
/*null_value*/, const Empty_Record_Type
& other_value
)
6346 if (!other_value
.is_bound())
6347 TTCN_error("Comparison of an unbound value of type %s.",
6348 other_value
.get_descriptor()->name
);