1 ///////////////////////////////////////////////////////////////////////////////
2 // Copyright (c) 2000-2014 Ericsson Telecom AB
3 // All rights reserved. This program and the accompanying materials
4 // are made available under the terms of the Eclipse Public License v1.0
5 // which accompanies this distribution, and is available at
6 // http://www.eclipse.org/legal/epl-v10.html
7 ///////////////////////////////////////////////////////////////////////////////
14 #include "Module_list.hh"
18 #ifdef TITAN_RUNTIME_2
21 #include "Charstring.hh"
22 #include "Universal_charstring.hh"
25 ////////////////////////////////////////////////////////////////////////////////
27 const Erroneous_values_t
* Erroneous_descriptor_t::get_field_err_values(int field_idx
) const
29 for (int i
=0; i
<values_size
; i
++) {
30 if (values_vec
[i
].field_index
==field_idx
) return (values_vec
+i
);
31 if (values_vec
[i
].field_index
>field_idx
) return NULL
;
36 const Erroneous_values_t
* Erroneous_descriptor_t::next_field_err_values(
37 const int field_idx
, int& values_idx
) const
39 const Erroneous_values_t
* err_vals
= NULL
;
40 if ( (values_idx
<values_size
) && (values_vec
[values_idx
].field_index
==field_idx
) ) {
41 err_vals
= values_vec
+values_idx
;
47 const Erroneous_descriptor_t
* Erroneous_descriptor_t::get_field_emb_descr(int field_idx
) const
49 for (int i
=0; i
<embedded_size
; i
++) {
50 if (embedded_vec
[i
].field_index
==field_idx
) return (embedded_vec
+i
);
51 if (embedded_vec
[i
].field_index
>field_idx
) return NULL
;
56 const Erroneous_descriptor_t
* Erroneous_descriptor_t::next_field_emb_descr(
57 const int field_idx
, int& edescr_idx
) const
59 const Erroneous_descriptor_t
* emb_descr
= NULL
;
60 if ( (edescr_idx
<embedded_size
) && (embedded_vec
[edescr_idx
].field_index
==field_idx
) ) {
61 emb_descr
= embedded_vec
+edescr_idx
;
67 void Erroneous_descriptor_t::log() const
69 TTCN_Logger::log_event_str(" with erroneous { ");
71 TTCN_Logger::log_event_str("}");
74 void Erroneous_descriptor_t::log_() const
76 if (omit_before
!=-1) {
77 if (omit_before_qualifier
==NULL
) TTCN_error(
78 "internal error: Erroneous_descriptor_t::log()");
79 TTCN_Logger::log_event("{ before %s := omit all } ", omit_before_qualifier
);
82 if (omit_after_qualifier
==NULL
) TTCN_error(
83 "internal error: Erroneous_descriptor_t::log()");
84 TTCN_Logger::log_event("{ after %s := omit all } ", omit_after_qualifier
);
86 for (int i
=0; i
<values_size
; i
++) {
87 if (values_vec
[i
].field_qualifier
==NULL
) TTCN_error(
88 "internal error: Erroneous_descriptor_t::log()");
89 if (values_vec
[i
].before
) {
90 TTCN_Logger::log_event("{ before%s %s := ",
91 values_vec
[i
].before
->raw
? "(raw)" : "", values_vec
[i
].field_qualifier
);
92 if (values_vec
[i
].before
->errval
) values_vec
[i
].before
->errval
->log();
93 else TTCN_Logger::log_event_str("omit");
94 TTCN_Logger::log_event_str(" } ");
96 if (values_vec
[i
].value
) {
97 TTCN_Logger::log_event("{ value%s %s := ",
98 values_vec
[i
].value
->raw
? "(raw)" : "", values_vec
[i
].field_qualifier
);
99 if (values_vec
[i
].value
->errval
) values_vec
[i
].value
->errval
->log();
100 else TTCN_Logger::log_event_str("omit");
101 TTCN_Logger::log_event_str(" } ");
103 if (values_vec
[i
].after
) {
104 TTCN_Logger::log_event("{ after%s %s := ",
105 values_vec
[i
].after
->raw
? "(raw)" : "", values_vec
[i
].field_qualifier
);
106 if (values_vec
[i
].after
->errval
) values_vec
[i
].after
->errval
->log();
107 else TTCN_Logger::log_event_str("omit");
108 TTCN_Logger::log_event_str(" } ");
111 for (int i
=0; i
<embedded_size
; i
++) {
112 embedded_vec
[i
].log_();
116 void Base_Type::set_to_omit()
118 TTCN_error("Internal error: trying to set a non-optional field to OMIT.");
121 void Base_Type::set_to_present()
123 TTCN_error("Internal error: calling set_to_present() on a non-optional value.");
126 boolean
Base_Type::is_present() const
131 Base_Type
* Base_Type::get_opt_value()
133 TTCN_error("Internal error: calling get_opt_value() on a non-optional value.");
137 const Base_Type
* Base_Type::get_opt_value() const
139 TTCN_error("Internal error: calling get_opt_value() const on a non-optional value.");
143 ASN_BER_TLV_t
* Base_Type::BER_encode_TLV_negtest(const Erroneous_descriptor_t
* /*p_err_descr*/,
144 const TTCN_Typedescriptor_t
& /*p_td*/, unsigned /*p_coding*/) const
146 TTCN_error("Internal error: calling Base_Type::BER_encode_TLV_negtest().");
150 int Base_Type::TEXT_encode_negtest(const Erroneous_descriptor_t
* /*p_err_descr*/,
151 const TTCN_Typedescriptor_t
& /*p_td*/, TTCN_Buffer
& /*p_buf*/) const
153 TTCN_error("Internal error: calling Base_Type::TEXT_encode_negtest().");
157 ASN_BER_TLV_t
* Base_Type::BER_encode_negtest_raw() const
159 TTCN_error("A value of type %s cannot be used as erroneous raw value for BER encoding.",
160 get_descriptor()->name
);
164 int Base_Type::encode_raw(TTCN_Buffer
&) const
166 TTCN_error("A value of type %s cannot be used as erroneous raw value for encoding.",
167 get_descriptor()->name
);
171 int Base_Type::RAW_encode_negtest_raw(RAW_enc_tree
&) const
173 TTCN_error("A value of type %s cannot be used as erroneous raw value for encoding.",
174 get_descriptor()->name
);
178 int Base_Type::XER_encode_negtest(const Erroneous_descriptor_t
* /*p_err_descr*/,
179 const XERdescriptor_t
& p_td
, TTCN_Buffer
& p_buf
, unsigned int flavor
, int indent
) const
181 return XER_encode(p_td
, p_buf
, flavor
, indent
); // ignore erroneous
184 int Base_Type::RAW_encode_negtest(const Erroneous_descriptor_t
*,
185 const TTCN_Typedescriptor_t
&, RAW_enc_tree
&) const
187 TTCN_error("Internal error: calling Base_Type::RAW_encode_negtest().");
192 #error this is for RT2 only
195 #ifdef TITAN_RUNTIME_2
197 boolean
Record_Of_Type::compare_function(const Record_Of_Type
*left_ptr
,
198 int left_index
, const Record_Of_Type
*right_ptr
, int right_index
)
200 if (left_ptr
->val_ptr
== NULL
)
201 TTCN_error("The left operand of comparison is an unbound value of type %s.",
202 left_ptr
->get_descriptor()->name
);
203 if (right_ptr
->val_ptr
== NULL
)
204 TTCN_error("The right operand of comparison is an unbound value of type %s.",
205 right_ptr
->get_descriptor()->name
);
207 const Base_Type
* elem
= left_ptr
->val_ptr
->value_elements
[left_index
];
208 const Base_Type
* other_elem
= right_ptr
->val_ptr
->value_elements
[right_index
];
210 if (other_elem
!= NULL
) { // both are bound, compare them
211 return elem
->is_equal(other_elem
);
215 else { // elem unbound, they can be equal only if other_elem is unbound too
216 return other_elem
== NULL
;
220 void Record_Of_Type::clean_up()
222 if (val_ptr
!= NULL
) {
223 if (val_ptr
->ref_count
> 1) {
224 val_ptr
->ref_count
--;
227 else if (val_ptr
->ref_count
== 1) {
228 if (refd_indices
.empty()) {
229 for (int elem_count
= 0; elem_count
< val_ptr
->n_elements
; elem_count
++) {
230 if (val_ptr
->value_elements
[elem_count
] != NULL
) {
231 delete val_ptr
->value_elements
[elem_count
];
234 free_pointers((void**)val_ptr
->value_elements
);
243 TTCN_error("Internal error: Invalid reference counter in "
244 "a record of/set of value.");
249 Record_Of_Type::Record_Of_Type(null_type
/*other_value*/)
250 : Base_Type(), val_ptr(new recordof_setof_struct
), err_descr(NULL
), max_refd_index(-1)
252 val_ptr
->ref_count
= 1;
253 val_ptr
->n_elements
= 0;
254 val_ptr
->value_elements
= NULL
;
257 Record_Of_Type::Record_Of_Type(const Record_Of_Type
& other_value
)
258 : Base_Type(other_value
), val_ptr(NULL
), err_descr(other_value
.err_descr
), max_refd_index(-1)
260 if (!other_value
.is_bound())
261 TTCN_error("Copying an unbound record of/set of value.");
262 // Increment ref_count only if val_ptr is not NULL
263 if (other_value
.val_ptr
!= NULL
) {
264 if (other_value
.refd_indices
.empty()) {
265 val_ptr
= other_value
.val_ptr
;
266 val_ptr
->ref_count
++;
269 // there are references to at least one element => the array must be copied
270 int nof_elements
= other_value
.get_nof_elements();
271 set_size(nof_elements
);
272 for (int i
= 0; i
< nof_elements
; ++i
) {
273 if (other_value
.is_elem_bound(i
)) {
274 val_ptr
->value_elements
[i
] = other_value
.val_ptr
->value_elements
[i
]->clone();
281 int Record_Of_Type::get_nof_elements() const
283 int nof_elements
= (val_ptr
!= NULL
) ? val_ptr
->n_elements
: 0;
284 if (!refd_indices
.empty()) {
285 while (nof_elements
> 0) {
286 if (is_elem_bound(nof_elements
- 1)) {
295 bool Record_Of_Type::is_elem_bound(int index
) const
297 return val_ptr
->value_elements
[index
] != NULL
&&
298 val_ptr
->value_elements
[index
]->is_bound();
301 int Record_Of_Type::get_max_refd_index()
303 if (refd_indices
.empty()) {
306 if (-1 == max_refd_index
) {
307 for (size_t i
= 0; i
< refd_indices
.size(); ++i
) {
308 if (refd_indices
[i
] > max_refd_index
) {
309 max_refd_index
= refd_indices
[i
];
313 return max_refd_index
;
316 bool Record_Of_Type::is_index_refd(int index
)
318 for (size_t i
= 0; i
< refd_indices
.size(); ++i
) {
319 if (index
== refd_indices
[i
]) {
326 void Record_Of_Type::set_val(null_type
)
331 boolean
Record_Of_Type::is_equal(const Base_Type
* other_value
) const
333 const Record_Of_Type
* other_recof
= static_cast<const Record_Of_Type
*>(other_value
);
335 TTCN_error("The left operand of comparison is an unbound value of type %s.",
336 get_descriptor()->name
);
337 if (other_recof
->val_ptr
== NULL
)
338 TTCN_error("The right operand of comparison is an unbound value of type %s.",
339 other_value
->get_descriptor()->name
);
340 if (val_ptr
== other_recof
->val_ptr
) return TRUE
;
342 return compare_set_of(this, get_nof_elements(), other_recof
,
343 other_recof
->get_nof_elements(), compare_function
);
345 if (get_nof_elements() != other_recof
->get_nof_elements()) return FALSE
;
346 for (int elem_count
= 0; elem_count
< get_nof_elements(); elem_count
++) {
347 if (is_elem_bound(elem_count
)) {
348 if (other_recof
->is_elem_bound(elem_count
)) {
349 if (!val_ptr
->value_elements
[elem_count
]->is_equal(other_recof
->val_ptr
->value_elements
[elem_count
]))
352 } else if (other_recof
->is_elem_bound(elem_count
)) return FALSE
;
358 void Record_Of_Type::set_value(const Base_Type
* other_value
)
360 const Record_Of_Type
* other_recof
= static_cast<const Record_Of_Type
*>(other_value
);
361 if (!other_recof
->is_bound())
362 TTCN_error("Assigning an unbound value of type %s.",
363 other_value
->get_descriptor()->name
);
364 if (this != other_recof
) {
365 if (refd_indices
.empty() && other_recof
->refd_indices
.empty()) {
367 val_ptr
= other_recof
->val_ptr
;
368 val_ptr
->ref_count
++;
371 // there are references to at least one element => the array must be copied
372 int nof_elements
= other_recof
->get_nof_elements();
373 set_size(nof_elements
);
374 for (int i
= 0; i
< nof_elements
; ++i
) {
375 if (other_recof
->is_elem_bound(i
)) {
376 if (val_ptr
->value_elements
[i
] == NULL
) {
377 val_ptr
->value_elements
[i
] = create_elem();
379 val_ptr
->value_elements
[i
]->set_value(other_recof
->val_ptr
->value_elements
[i
]);
381 else if (val_ptr
->value_elements
[i
] != NULL
) {
382 if (is_index_refd(i
)) {
383 val_ptr
->value_elements
[i
]->clean_up();
386 delete val_ptr
->value_elements
[i
];
387 val_ptr
->value_elements
[i
] = NULL
;
393 err_descr
= other_recof
->err_descr
;
396 boolean
Record_Of_Type::operator!=(null_type other_value
) const
398 return !(*this == other_value
);
401 Base_Type
* Record_Of_Type::get_at(int index_value
)
404 TTCN_error("Accessing an element of type %s using a negative index: %d.",
405 get_descriptor()->name
, index_value
);
406 if (val_ptr
== NULL
) {
407 val_ptr
= new recordof_setof_struct
;
408 val_ptr
->ref_count
= 1;
409 val_ptr
->n_elements
= 0;
410 val_ptr
->value_elements
= NULL
;
411 } else if (val_ptr
->ref_count
> 1) {
412 struct recordof_setof_struct
*new_val_ptr
= new recordof_setof_struct
;
413 new_val_ptr
->ref_count
= 1;
414 new_val_ptr
->n_elements
= (index_value
>= val_ptr
->n_elements
) ?
415 index_value
+ 1 : val_ptr
->n_elements
;
416 new_val_ptr
->value_elements
=
417 (Base_Type
**)allocate_pointers(new_val_ptr
->n_elements
);
418 for (int elem_count
= 0; elem_count
< val_ptr
->n_elements
; elem_count
++)
420 if (val_ptr
->value_elements
[elem_count
] != NULL
) {
421 new_val_ptr
->value_elements
[elem_count
] =
422 val_ptr
->value_elements
[elem_count
]->clone();
425 val_ptr
->ref_count
--;
426 val_ptr
= new_val_ptr
;
428 if (index_value
>= val_ptr
->n_elements
) set_size(index_value
+ 1);
429 if (val_ptr
->value_elements
[index_value
] == NULL
) {
430 val_ptr
->value_elements
[index_value
] = create_elem();
432 return val_ptr
->value_elements
[index_value
];
435 Base_Type
* Record_Of_Type::get_at(const INTEGER
& index_value
)
437 if (!index_value
.is_bound())
438 TTCN_error("Using an unbound integer value for indexing a value "
439 "of type %s.", get_descriptor()->name
);
440 return get_at((int)index_value
);
443 const Base_Type
* Record_Of_Type::get_at(int index_value
) const
446 TTCN_error("Accessing an element in an unbound value of type %s.",
447 get_descriptor()->name
);
449 TTCN_error("Accessing an element of type %s using a negative index: %d.",
450 get_descriptor()->name
, index_value
);
451 if (index_value
>= get_nof_elements())
452 TTCN_error("Index overflow in a value of type %s: The index is %d, but the "
453 "value has only %d elements.", get_descriptor()->name
, index_value
,
455 return (val_ptr
->value_elements
[index_value
] != NULL
) ?
456 val_ptr
->value_elements
[index_value
] : get_unbound_elem();
459 const Base_Type
* Record_Of_Type::get_at(const INTEGER
& index_value
) const
461 if (!index_value
.is_bound())
462 TTCN_error("Using an unbound integer value for indexing a value "
463 "of type %s.", get_descriptor()->name
);
464 return get_at((int)index_value
);
467 Record_Of_Type
* Record_Of_Type::rotl(const INTEGER
& rotate_count
, Record_Of_Type
* rec_of
) const
469 if (!rotate_count
.is_bound())
470 TTCN_error("Unbound integer operand of rotate left operator of type %s.",
471 get_descriptor()->name
);
472 return rotr((int)(-rotate_count
), rec_of
);
475 Record_Of_Type
* Record_Of_Type::rotr(const INTEGER
& rotate_count
, Record_Of_Type
* rec_of
) const
477 if (!rotate_count
.is_bound())
478 TTCN_error("Unbound integer operand of rotate right operator of type %s.",
479 get_descriptor()->name
);
480 return rotr((int)rotate_count
, rec_of
);
483 Record_Of_Type
* Record_Of_Type::rotr(int rotate_count
, Record_Of_Type
* rec_of
) const
486 TTCN_error("Performing rotation operation on an unbound value of type %s.",
487 get_descriptor()->name
);
488 int nof_elements
= get_nof_elements();
489 if (nof_elements
== 0) return const_cast<Record_Of_Type
*>(this);
491 if (rotate_count
>=0) rc
= rotate_count
% nof_elements
;
492 else rc
= nof_elements
- ((-rotate_count
) % nof_elements
);
493 if (rc
== 0) return const_cast<Record_Of_Type
*>(this);
494 rec_of
->set_size(nof_elements
);
496 for (int i
=0; i
<nof_elements
; i
++) {
497 rot_i
= (i
+rc
) % nof_elements
;
498 if (is_elem_bound(i
)) {
499 if (rec_of
->val_ptr
->value_elements
[rot_i
] == NULL
) {
500 rec_of
->val_ptr
->value_elements
[rot_i
] = rec_of
->create_elem();
502 rec_of
->val_ptr
->value_elements
[rot_i
]->set_value(val_ptr
->value_elements
[i
]);
503 } else if (rec_of
->is_elem_bound(rot_i
)) {
504 delete rec_of
->val_ptr
->value_elements
[rot_i
];
505 rec_of
->val_ptr
->value_elements
[rot_i
] = NULL
;
511 Record_Of_Type
* Record_Of_Type::concat(const Record_Of_Type
* other_value
,
512 Record_Of_Type
* rec_of
) const
514 if (val_ptr
== NULL
|| other_value
->val_ptr
== NULL
)
515 TTCN_error("Unbound operand of %s concatenation.", get_descriptor()->name
);
516 int nof_elements
= get_nof_elements();
517 if (nof_elements
== 0) return const_cast<Record_Of_Type
*>(other_value
);
518 int other_value_nof_elements
= other_value
->get_nof_elements();
519 if (other_value_nof_elements
== 0) return const_cast<Record_Of_Type
*>(this);
520 rec_of
->set_size(nof_elements
+ other_value_nof_elements
);
521 for (int i
=0; i
<nof_elements
; i
++) {
522 if (is_elem_bound(i
)) {
523 if (rec_of
->val_ptr
->value_elements
[i
] == NULL
) {
524 rec_of
->val_ptr
->value_elements
[i
] = rec_of
->create_elem();
526 rec_of
->val_ptr
->value_elements
[i
]->set_value(val_ptr
->value_elements
[i
]);
527 } else if (rec_of
->val_ptr
->value_elements
[i
] != NULL
) {
528 if (rec_of
->is_index_refd(i
)) {
529 rec_of
->val_ptr
->value_elements
[i
]->clean_up();
532 delete rec_of
->val_ptr
->value_elements
[i
];
533 rec_of
->val_ptr
->value_elements
[i
] = NULL
;
538 for (int i
=0; i
<other_value_nof_elements
; i
++) {
539 cat_i
= i
+ nof_elements
;
540 if (other_value
->is_elem_bound(i
)) {
541 if (rec_of
->val_ptr
->value_elements
[cat_i
] == NULL
) {
542 rec_of
->val_ptr
->value_elements
[cat_i
] = rec_of
->create_elem();
544 rec_of
->val_ptr
->value_elements
[cat_i
]->
545 set_value(other_value
->val_ptr
->value_elements
[i
]);
546 } else if (rec_of
->val_ptr
->value_elements
[cat_i
] != NULL
) {
547 if (rec_of
->is_index_refd(cat_i
)) {
548 rec_of
->val_ptr
->value_elements
[cat_i
]->clean_up();
551 delete rec_of
->val_ptr
->value_elements
[cat_i
];
552 rec_of
->val_ptr
->value_elements
[cat_i
] = NULL
;
559 void Record_Of_Type::substr_(int index
, int returncount
,
560 Record_Of_Type
* rec_of
) const
563 TTCN_error("The first argument of substr() is an unbound value of type %s.",
564 get_descriptor()->name
);
565 check_substr_arguments(get_nof_elements(), index
, returncount
,
566 get_descriptor()->name
, "element");
567 rec_of
->set_size(returncount
);
568 for (int i
=0; i
<returncount
; i
++) {
569 if (is_elem_bound(i
+ index
)) {
570 if (rec_of
->val_ptr
->value_elements
[i
] == NULL
) {
571 rec_of
->val_ptr
->value_elements
[i
] = rec_of
->create_elem();
573 rec_of
->val_ptr
->value_elements
[i
]->
574 set_value(val_ptr
->value_elements
[i
+index
]);
575 } else if (rec_of
->val_ptr
->value_elements
[i
] != NULL
) {
576 if (rec_of
->is_index_refd(i
)) {
577 rec_of
->val_ptr
->value_elements
[i
]->clean_up();
580 delete rec_of
->val_ptr
->value_elements
[i
];
581 rec_of
->val_ptr
->value_elements
[i
] = NULL
;
587 void Record_Of_Type::replace_(int index
, int len
,
588 const Record_Of_Type
* repl
, Record_Of_Type
* rec_of
) const
591 TTCN_error("The first argument of replace() is an unbound value "
592 "of type %s.", get_descriptor()->name
);
593 if (repl
->val_ptr
== NULL
)
594 TTCN_error("The fourth argument of replace() is an unbound value of "
595 "type %s.", get_descriptor()->name
);
596 int nof_elements
= get_nof_elements();
597 check_replace_arguments(nof_elements
, index
, len
,
598 get_descriptor()->name
, "element");
599 int repl_nof_elements
= repl
->get_nof_elements();
600 rec_of
->set_size(nof_elements
+ repl_nof_elements
- len
);
601 for (int i
= 0; i
< index
; i
++) {
602 if (is_elem_bound(i
)) {
603 if (rec_of
->val_ptr
->value_elements
[i
] == NULL
) {
604 rec_of
->val_ptr
->value_elements
[i
] = rec_of
->create_elem();
606 rec_of
->val_ptr
->value_elements
[i
]->set_value(val_ptr
->value_elements
[i
]);
607 } else if (rec_of
->val_ptr
->value_elements
[i
] != NULL
) {
608 if (rec_of
->is_index_refd(i
)) {
609 rec_of
->val_ptr
->value_elements
[i
]->clean_up();
612 delete rec_of
->val_ptr
->value_elements
[i
];
613 rec_of
->val_ptr
->value_elements
[i
] = NULL
;
617 for (int i
= 0; i
< repl_nof_elements
; i
++) {
618 if (repl
->is_elem_bound(i
)) {
619 if (rec_of
->val_ptr
->value_elements
[i
+index
] == NULL
) {
620 rec_of
->val_ptr
->value_elements
[i
+index
] = rec_of
->create_elem();
622 rec_of
->val_ptr
->value_elements
[i
+index
]->
623 set_value(repl
->val_ptr
->value_elements
[i
]);
624 } else if (rec_of
->val_ptr
->value_elements
[i
+index
] != NULL
) {
625 if (rec_of
->is_index_refd(i
+index
)) {
626 rec_of
->val_ptr
->value_elements
[i
+index
]->clean_up();
629 delete rec_of
->val_ptr
->value_elements
[i
+index
];
630 rec_of
->val_ptr
->value_elements
[i
+index
] = NULL
;
635 for (int i
= 0; i
< nof_elements
- index
- len
; i
++) {
636 repl_i
= index
+i
+repl_nof_elements
;
637 if (is_elem_bound(index
+i
+len
)) {
638 if (rec_of
->val_ptr
->value_elements
[repl_i
] == NULL
) {
639 rec_of
->val_ptr
->value_elements
[repl_i
] = rec_of
->create_elem();
641 rec_of
->val_ptr
->value_elements
[repl_i
]->
642 set_value(val_ptr
->value_elements
[index
+i
+len
]);
643 } else if (rec_of
->val_ptr
->value_elements
[repl_i
] != NULL
) {
644 if (rec_of
->is_index_refd(repl_i
)) {
645 rec_of
->val_ptr
->value_elements
[repl_i
]->clean_up();
648 delete rec_of
->val_ptr
->value_elements
[repl_i
];
649 rec_of
->val_ptr
->value_elements
[repl_i
] = NULL
;
655 void Record_Of_Type::replace_(int index
, int len
,
656 const Record_Of_Template
* repl
, Record_Of_Type
* rec_of
) const
658 if (!repl
->is_value())
659 TTCN_error("The fourth argument of function replace() is a template "
660 "of type %s with non-specific value.", get_descriptor()->name
);
661 rec_of
->set_val(NULL_VALUE
);
662 Base_Type
* repl_value
= rec_of
->clone();
663 repl
->valueofv(repl_value
);
664 replace_(index
, len
, static_cast<Record_Of_Type
*>(repl_value
), rec_of
);
668 void Record_Of_Type::replace_(int index
, int len
,
669 const Set_Of_Template
* repl
, Record_Of_Type
* rec_of
) const
671 if (!repl
->is_value())
672 TTCN_error("The fourth argument of function replace() is a template "
673 "of type %s with non-specific value.", get_descriptor()->name
);
674 rec_of
->set_val(NULL_VALUE
);
675 Base_Type
* repl_value
= rec_of
->clone();
676 repl
->valueofv(repl_value
);
677 replace_(index
, len
, static_cast<Record_Of_Type
*>(repl_value
), rec_of
);
681 void Record_Of_Type::set_size(int new_size
)
684 TTCN_error("Internal error: Setting a negative size for a value of "
685 "type %s.", get_descriptor()->name
);
686 if (val_ptr
== NULL
) {
687 val_ptr
= new recordof_setof_struct
;
688 val_ptr
->ref_count
= 1;
689 val_ptr
->n_elements
= 0;
690 val_ptr
->value_elements
= NULL
;
691 } else if (val_ptr
->ref_count
> 1) {
692 struct recordof_setof_struct
*new_val_ptr
= new recordof_setof_struct
;
693 new_val_ptr
->ref_count
= 1;
694 new_val_ptr
->n_elements
= (new_size
< val_ptr
->n_elements
) ?
695 new_size
: val_ptr
->n_elements
;
696 new_val_ptr
->value_elements
=
697 (Base_Type
**)allocate_pointers(new_val_ptr
->n_elements
);
698 for (int elem_count
= 0; elem_count
< new_val_ptr
->n_elements
; elem_count
++) {
699 if (val_ptr
->value_elements
[elem_count
] != NULL
) {
700 new_val_ptr
->value_elements
[elem_count
] =
701 val_ptr
->value_elements
[elem_count
]->clone();
705 val_ptr
= new_val_ptr
;
707 if (new_size
> val_ptr
->n_elements
) {
708 val_ptr
->value_elements
= (Base_Type
**)
709 reallocate_pointers((void**)val_ptr
->value_elements
, val_ptr
->n_elements
, new_size
);
710 val_ptr
->n_elements
= new_size
;
711 } else if (new_size
< val_ptr
->n_elements
) {
712 for (int elem_count
= new_size
; elem_count
< val_ptr
->n_elements
; elem_count
++) {
713 if (val_ptr
->value_elements
[elem_count
] != NULL
) {
714 if (is_index_refd(elem_count
)) {
715 val_ptr
->value_elements
[elem_count
]->clean_up();
718 delete val_ptr
->value_elements
[elem_count
];
719 val_ptr
->value_elements
[elem_count
] = 0;
723 if (new_size
<= get_max_refd_index()) {
724 new_size
= get_max_refd_index() + 1;
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
;
734 boolean
Record_Of_Type::is_bound() const
736 if (refd_indices
.empty()) {
737 return (val_ptr
!= NULL
);
739 return (get_nof_elements() != 0);
742 boolean
Record_Of_Type::is_value() const
744 if (val_ptr
== NULL
) return FALSE
;
745 for (int i
=0; i
< get_nof_elements(); ++i
)
746 if (!is_elem_bound(i
) ||
747 !val_ptr
->value_elements
[i
]->is_value()) return FALSE
;
751 int Record_Of_Type::size_of() const
754 TTCN_error("Performing sizeof operation on an unbound value of type %s.",
755 get_descriptor()->name
);
756 return get_nof_elements();
759 int Record_Of_Type::lengthof() const
762 TTCN_error("Performing lengthof operation on an unbound value of "
763 "type %s.", get_descriptor()->name
);
764 for (int my_length
=get_nof_elements(); my_length
>0; my_length
--)
765 if (is_elem_bound(my_length
- 1)) return my_length
;
769 void Record_Of_Type::log() const
771 if (val_ptr
== NULL
) {
772 TTCN_Logger::log_event_unbound();
775 if (get_nof_elements()==0) {
776 TTCN_Logger::log_event_str("{ }");
778 TTCN_Logger::log_event_str("{ ");
779 for (int elem_count
= 0; elem_count
< get_nof_elements(); elem_count
++) {
780 if (elem_count
> 0) TTCN_Logger::log_event_str(", ");
781 get_at(elem_count
)->log();
783 TTCN_Logger::log_event_str(" }");
785 if (err_descr
) err_descr
->log();
788 void Record_Of_Type::encode_text(Text_Buf
& text_buf
) const
791 TTCN_error("Text encoder: Encoding an unbound value of type %s.",
792 get_descriptor()->name
);
793 text_buf
.push_int(get_nof_elements());
794 for (int elem_count
= 0; elem_count
< get_nof_elements(); elem_count
++)
795 get_at(elem_count
)->encode_text(text_buf
);
798 void Record_Of_Type::decode_text(Text_Buf
& text_buf
)
800 int new_size
= text_buf
.pull_int().get_val();
802 TTCN_error("Text decoder: Negative size was received for a value of "
803 "type %s.", get_descriptor()->name
);
805 for (int elem_count
= 0; elem_count
< new_size
; elem_count
++) {
806 if (val_ptr
->value_elements
[elem_count
] == NULL
) {
807 val_ptr
->value_elements
[elem_count
] = create_elem();
809 val_ptr
->value_elements
[elem_count
]->decode_text(text_buf
);
813 boolean
Record_Of_Type::operator==(null_type
/*other_value*/) const
816 TTCN_error("The left operand of comparison is an unbound value of type %s.",
817 get_descriptor()->name
);
818 return get_nof_elements() == 0;
821 int Record_Of_Type::rawdec_ebv() const
823 TTCN_error("Internal error: Record_Of_Type::rawdec_ebv() called.");
826 boolean
Record_Of_Type::isXerAttribute() const
828 TTCN_error("Internal error: Record_Of_Type::isXerAttribute() called.");
831 boolean
Record_Of_Type::isXmlValueList() const
833 TTCN_error("Internal error: Record_Of_Type::isXmlValueList() called.");
836 int Record_Of_Type::TEXT_encode(const TTCN_Typedescriptor_t
& p_td
,
837 TTCN_Buffer
& buff
) const
840 return TEXT_encode_negtest(err_descr
, p_td
, buff
);
842 int encoded_length
=0;
843 if(p_td
.text
->begin_encode
) {
844 buff
.put_cs(*p_td
.text
->begin_encode
);
845 encoded_length
+=p_td
.text
->begin_encode
->lengthof();
848 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND
,
849 "Encoding an unbound value.");
850 if(p_td
.text
->end_encode
) {
851 buff
.put_cs(*p_td
.text
->end_encode
);
852 encoded_length
+=p_td
.text
->end_encode
->lengthof();
854 return encoded_length
;
856 const TTCN_Typedescriptor_t
* elem_descr
= get_elem_descr();
857 for(int a
=0;a
<get_nof_elements();a
++) {
858 if(a
!=0 && p_td
.text
->separator_encode
) {
859 buff
.put_cs(*p_td
.text
->separator_encode
);
860 encoded_length
+=p_td
.text
->separator_encode
->lengthof();
862 encoded_length
+=get_at(a
)->TEXT_encode(*elem_descr
,buff
);
864 if(p_td
.text
->end_encode
) {
865 buff
.put_cs(*p_td
.text
->end_encode
);
866 encoded_length
+=p_td
.text
->end_encode
->lengthof();
868 return encoded_length
;
872 * TEXT encode for negative testing
874 int Record_Of_Type::TEXT_encode_negtest(const Erroneous_descriptor_t
* p_err_descr
, const TTCN_Typedescriptor_t
& p_td
,
875 TTCN_Buffer
& buff
) const
877 bool need_separator
=false;
878 int encoded_length
=0;
879 if(p_td
.text
->begin_encode
) {
880 buff
.put_cs(*p_td
.text
->begin_encode
);
881 encoded_length
+=p_td
.text
->begin_encode
->lengthof();
884 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND
,
885 "Encoding an unbound value.");
886 if(p_td
.text
->end_encode
) {
887 buff
.put_cs(*p_td
.text
->end_encode
);
888 encoded_length
+=p_td
.text
->end_encode
->lengthof();
890 return encoded_length
;
896 for(int a
=0;a
<get_nof_elements();a
++) {
897 if ( (p_err_descr
->omit_before
!=-1) && (a
<p_err_descr
->omit_before
) ) continue;
898 const Erroneous_values_t
* err_vals
= p_err_descr
->next_field_err_values(a
, values_idx
);
899 const Erroneous_descriptor_t
* emb_descr
= p_err_descr
->next_field_emb_descr(a
, edescr_idx
);
901 if (err_vals
&& err_vals
->before
) {
902 if (err_vals
->before
->errval
==NULL
) TTCN_error(
903 "internal error: erroneous before value missing");
904 if (need_separator
&& p_td
.text
->separator_encode
) {
905 buff
.put_cs(*p_td
.text
->separator_encode
);
906 encoded_length
+=p_td
.text
->separator_encode
->lengthof();
908 if (err_vals
->before
->raw
) {
909 encoded_length
+= err_vals
->before
->errval
->encode_raw(buff
);
911 if (err_vals
->before
->type_descr
==NULL
) TTCN_error(
912 "internal error: erroneous before typedescriptor missing");
913 encoded_length
+= err_vals
->before
->errval
->TEXT_encode(
914 *(err_vals
->before
->type_descr
),buff
);
919 if (err_vals
&& err_vals
->value
) {
920 if (err_vals
->value
->errval
) {
921 if (need_separator
&& p_td
.text
->separator_encode
) {
922 buff
.put_cs(*p_td
.text
->separator_encode
);
923 encoded_length
+=p_td
.text
->separator_encode
->lengthof();
925 if (err_vals
->value
->raw
) {
926 encoded_length
+= err_vals
->value
->errval
->encode_raw(buff
);
928 if (err_vals
->value
->type_descr
==NULL
) TTCN_error(
929 "internal error: erroneous value typedescriptor missing");
930 encoded_length
+= err_vals
->value
->errval
->TEXT_encode(
931 *(err_vals
->value
->type_descr
),buff
);
936 if (need_separator
&& p_td
.text
->separator_encode
) {
937 buff
.put_cs(*p_td
.text
->separator_encode
);
938 encoded_length
+=p_td
.text
->separator_encode
->lengthof();
941 encoded_length
+= get_at(a
)->TEXT_encode_negtest(
942 emb_descr
,*get_elem_descr(),buff
);
944 encoded_length
+= get_at(a
)->TEXT_encode(*get_elem_descr(),buff
);
949 if (err_vals
&& err_vals
->after
) {
950 if (err_vals
->after
->errval
==NULL
) TTCN_error(
951 "internal error: erroneous after value missing");
952 if (need_separator
&& p_td
.text
->separator_encode
) {
953 buff
.put_cs(*p_td
.text
->separator_encode
);
954 encoded_length
+=p_td
.text
->separator_encode
->lengthof();
956 if (err_vals
->after
->raw
) {
957 encoded_length
+= err_vals
->after
->errval
->encode_raw(buff
);
959 if (err_vals
->after
->type_descr
==NULL
) TTCN_error(
960 "internal error: erroneous after typedescriptor missing");
961 encoded_length
+= err_vals
->after
->errval
->TEXT_encode(
962 *(err_vals
->after
->type_descr
),buff
);
967 if ( (p_err_descr
->omit_after
!=-1) && (a
>=p_err_descr
->omit_after
) ) break;
969 if(p_td
.text
->end_encode
) {
970 buff
.put_cs(*p_td
.text
->end_encode
);
971 encoded_length
+=p_td
.text
->end_encode
->lengthof();
973 return encoded_length
;
976 int Record_Of_Type::TEXT_decode(const TTCN_Typedescriptor_t
& p_td
,
977 TTCN_Buffer
& buff
, Limit_Token_List
& limit
, boolean no_err
,
980 int decoded_length
=0;
982 boolean sep_found
=FALSE
;
985 if(p_td
.text
->begin_decode
){
987 if((tl
=p_td
.text
->begin_decode
->match_begin(buff
))<0){
989 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR
,
990 "The specified token '%s' not found for '%s': ",
991 (const char*)*(p_td
.text
->begin_decode
), p_td
.name
);
995 buff
.increase_pos(tl
);
997 if(p_td
.text
->end_decode
){
998 limit
.add_token(p_td
.text
->end_decode
);
1001 if(p_td
.text
->separator_decode
){
1002 limit
.add_token(p_td
.text
->separator_decode
);
1008 int more
=get_nof_elements();
1010 Base_Type
* val
= create_elem();
1012 int len
= val
->TEXT_decode(*get_elem_descr(),buff
,limit
,TRUE
);
1013 if(len
==-1 || (len
==0 && !limit
.has_token())){
1017 buff
.set_pos(buff
.get_pos()-sep_length
);
1018 decoded_length
-=sep_length
;
1023 if (refd_indices
.empty()) {
1024 val_ptr
->value_elements
= (Base_Type
**)reallocate_pointers(
1025 (void**)val_ptr
->value_elements
, val_ptr
->n_elements
, val_ptr
->n_elements
+ 1);
1026 val_ptr
->value_elements
[val_ptr
->n_elements
]=val
;
1027 val_ptr
->n_elements
++;
1030 get_at(get_nof_elements())->set_value(val
);
1033 decoded_length
+=len
;
1034 if(p_td
.text
->separator_decode
){
1036 if((tl
=p_td
.text
->separator_decode
->match_begin(buff
))<0){
1040 buff
.increase_pos(tl
);
1043 } else if(p_td
.text
->end_decode
){
1045 if((tl
=p_td
.text
->end_decode
->match_begin(buff
))!=-1){
1047 buff
.increase_pos(tl
);
1048 limit
.remove_tokens(ml
);
1049 return decoded_length
;
1051 } else if(limit
.has_token(ml
)){
1053 if((tl
=limit
.match(buff
,ml
))==0){
1059 limit
.remove_tokens(ml
);
1060 if(p_td
.text
->end_decode
){
1062 if((tl
=p_td
.text
->end_decode
->match_begin(buff
))<0){
1069 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR
,
1070 "The specified token '%s' not found for '%s': ",
1071 (const char*)*(p_td
.text
->end_decode
), p_td
.name
);
1072 return decoded_length
;
1075 buff
.increase_pos(tl
);
1077 if(get_nof_elements()==0){
1078 if (!p_td
.text
->end_decode
&& !p_td
.text
->begin_decode
) {
1079 if(no_err
)return -1;
1080 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR
,
1081 "No record/set of member found.");
1082 return decoded_length
;
1085 if(!first_call
&& more
==get_nof_elements() &&
1086 !(p_td
.text
->end_decode
|| p_td
.text
->begin_decode
)) return -1;
1087 return decoded_length
;
1090 ASN_BER_TLV_t
* Record_Of_Type::BER_encode_TLV(const TTCN_Typedescriptor_t
& p_td
,
1091 unsigned p_coding
) const
1094 return BER_encode_TLV_negtest(err_descr
, p_td
, p_coding
);
1096 BER_chk_descr(p_td
);
1097 ASN_BER_TLV_t
*new_tlv
=BER_encode_chk_bound(is_bound());
1099 new_tlv
=ASN_BER_TLV_t::construct(NULL
);
1100 TTCN_EncDec_ErrorContext ec
;
1101 for(int elem_i
=0; elem_i
<get_nof_elements(); elem_i
++) {
1102 ec
.set_msg("Component #%d: ", elem_i
);
1103 new_tlv
->add_TLV(get_at(elem_i
)->BER_encode_TLV(*get_elem_descr(), p_coding
));
1105 if (is_set()) new_tlv
->sort_tlvs();
1107 new_tlv
=ASN_BER_V2TLV(new_tlv
, p_td
, p_coding
);
1111 ASN_BER_TLV_t
* Record_Of_Type::BER_encode_TLV_negtest(const Erroneous_descriptor_t
* p_err_descr
,
1112 const TTCN_Typedescriptor_t
& p_td
, unsigned p_coding
) const
1114 BER_chk_descr(p_td
);
1115 ASN_BER_TLV_t
*new_tlv
=BER_encode_chk_bound(is_bound());
1117 new_tlv
=ASN_BER_TLV_t::construct(NULL
);
1118 TTCN_EncDec_ErrorContext ec
;
1121 for (int elem_i
=0; elem_i
<get_nof_elements(); elem_i
++) {
1122 if ( (p_err_descr
->omit_before
!=-1) && (elem_i
<p_err_descr
->omit_before
) ) continue;
1123 const Erroneous_values_t
* err_vals
= p_err_descr
->next_field_err_values(elem_i
, values_idx
);
1124 const Erroneous_descriptor_t
* emb_descr
= p_err_descr
->next_field_emb_descr(elem_i
, edescr_idx
);
1126 if (err_vals
&& err_vals
->before
) {
1127 if (err_vals
->before
->errval
==NULL
) TTCN_error(
1128 "internal error: erroneous before value missing");
1129 ec
.set_msg("Erroneous value before component #%d: ", elem_i
);
1130 if (err_vals
->before
->raw
) {
1131 new_tlv
->add_TLV(err_vals
->before
->errval
->BER_encode_negtest_raw());
1133 if (err_vals
->before
->type_descr
==NULL
) TTCN_error(
1134 "internal error: erroneous before typedescriptor missing");
1135 new_tlv
->add_TLV(err_vals
->before
->errval
->BER_encode_TLV(
1136 *err_vals
->before
->type_descr
, p_coding
));
1140 if (err_vals
&& err_vals
->value
) {
1141 if (err_vals
->value
->errval
) { // replace
1142 ec
.set_msg("Erroneous value for component #%d: ", elem_i
);
1143 if (err_vals
->value
->raw
) {
1144 new_tlv
->add_TLV(err_vals
->value
->errval
->BER_encode_negtest_raw());
1146 if (err_vals
->value
->type_descr
==NULL
) TTCN_error(
1147 "internal error: erroneous value typedescriptor missing");
1148 new_tlv
->add_TLV(err_vals
->value
->errval
->BER_encode_TLV(
1149 *err_vals
->value
->type_descr
, p_coding
));
1153 ec
.set_msg("Component #%d: ", elem_i
);
1155 new_tlv
->add_TLV(get_at(elem_i
)->BER_encode_TLV_negtest(
1156 emb_descr
, *get_elem_descr(), p_coding
));
1158 new_tlv
->add_TLV(get_at(elem_i
)->BER_encode_TLV(
1159 *get_elem_descr(), p_coding
));
1163 if (err_vals
&& err_vals
->after
) {
1164 if (err_vals
->after
->errval
==NULL
) TTCN_error(
1165 "internal error: erroneous after value missing");
1166 ec
.set_msg("Erroneous value after component #%d: ", elem_i
);
1167 if (err_vals
->after
->raw
) {
1168 new_tlv
->add_TLV(err_vals
->after
->errval
->BER_encode_negtest_raw());
1170 if (err_vals
->after
->type_descr
==NULL
) TTCN_error(
1171 "internal error: erroneous after typedescriptor missing");
1172 new_tlv
->add_TLV(err_vals
->after
->errval
->BER_encode_TLV(
1173 *err_vals
->after
->type_descr
, p_coding
));
1177 if ( (p_err_descr
->omit_after
!=-1) && (elem_i
>=p_err_descr
->omit_after
) ) break;
1179 if (is_set()) new_tlv
->sort_tlvs();
1181 new_tlv
=ASN_BER_V2TLV(new_tlv
, p_td
, p_coding
);
1185 boolean
Record_Of_Type::BER_decode_TLV(const TTCN_Typedescriptor_t
& p_td
,
1186 const ASN_BER_TLV_t
& p_tlv
, unsigned L_form
)
1188 BER_chk_descr(p_td
);
1189 ASN_BER_TLV_t stripped_tlv
;
1190 BER_decode_strip_tags(*p_td
.ber
, p_tlv
, L_form
, stripped_tlv
);
1191 TTCN_EncDec_ErrorContext
ec_0("While decoding '%s' type: ", p_td
.name
);
1192 stripped_tlv
.chk_constructed_flag(TRUE
);
1195 ASN_BER_TLV_t tmp_tlv
;
1196 TTCN_EncDec_ErrorContext
ec_1("Component #");
1197 TTCN_EncDec_ErrorContext
ec_2("0: ");
1198 while(BER_decode_constdTLV_next(stripped_tlv
, V_pos
, L_form
, tmp_tlv
)) {
1199 get_at(get_nof_elements())->BER_decode_TLV(*get_elem_descr(), tmp_tlv
, L_form
);
1200 ec_2
.set_msg("%d: ", val_ptr
->n_elements
);
1205 void Record_Of_Type::BER_decode_opentypes(TTCN_Type_list
& p_typelist
,
1208 p_typelist
.push(this);
1209 TTCN_EncDec_ErrorContext
ec_0("Component #");
1210 TTCN_EncDec_ErrorContext ec_1
;
1211 for(int elem_i
=0; elem_i
<get_nof_elements(); elem_i
++) {
1212 ec_1
.set_msg("%d: ", elem_i
);
1213 get_at(elem_i
)->BER_decode_opentypes(p_typelist
, L_form
);
1219 int Record_Of_Type::RAW_decode(const TTCN_Typedescriptor_t
& p_td
,
1220 TTCN_Buffer
& buff
, int limit
, raw_order_t top_bit_ord
, boolean
/*no_err*/,
1221 int sel_field
, boolean first_call
)
1223 int prepaddlength
= buff
.increase_pos_padd(p_td
.raw
->prepadding
);
1224 limit
-= prepaddlength
;
1225 int decoded_length
= 0;
1226 int decoded_field_length
= 0;
1227 size_t start_of_field
= 0;
1231 int start_field
= get_nof_elements(); // append at the end
1232 TTCN_Typedescriptor_t
const& elem_descr
= *get_elem_descr();
1233 if (p_td
.raw
->fieldlength
|| sel_field
!= -1) {
1234 if (sel_field
== -1) sel_field
= p_td
.raw
->fieldlength
;
1235 for (int a
= 0; a
< sel_field
; a
++) {
1236 Base_Type
* field_bt
= get_at(a
+ start_field
);
1237 decoded_field_length
= field_bt
->RAW_decode(elem_descr
, buff
, limit
,
1239 if (decoded_field_length
< 0) return decoded_field_length
;
1240 decoded_length
+= decoded_field_length
;
1241 limit
-= decoded_field_length
;
1245 int a
= start_field
;
1247 if (!first_call
) return -1;
1250 int ext_bit
= rawdec_ebv();
1252 start_of_field
= buff
.get_pos_bit();
1253 Base_Type
* field_bt
= get_at(a
); // non-const, extend the record-of
1254 decoded_field_length
= field_bt
->RAW_decode(elem_descr
, buff
, limit
,
1256 if (decoded_field_length
< 0) { // decoding failed, shorten the record-of
1257 set_size(get_nof_elements() - 1);
1258 buff
.set_pos_bit(start_of_field
);
1259 if (a
> start_field
) {
1262 else return decoded_field_length
;
1264 decoded_length
+= decoded_field_length
;
1265 limit
-= decoded_field_length
;
1267 if (ext_bit
!= 1/*XDEFNO*/&& ext_bit
!= -1/*XDEFDEFAULT*/) {
1268 // ext_bit here may be 2 (XDEFYES) or 3 (XDEFREVERSE).
1269 // (ext_bit != 2) is 0 or 1
1270 // This is the opposite value of what the bit needs to be to signal
1271 // the end of decoding, because x-or is the equivalent of !=
1272 if ((ext_bit
!= 2/*XDEFYES*/) ^ buff
.get_last_bit()) {
1279 return decoded_length
+ buff
.increase_pos_padd(p_td
.raw
->padding
) + prepaddlength
;
1282 int Record_Of_Type::RAW_encode(const TTCN_Typedescriptor_t
& p_td
, RAW_enc_tree
& myleaf
) const
1284 if (err_descr
) return RAW_encode_negtest(err_descr
, p_td
, myleaf
);
1285 int encoded_length
= 0;
1286 int nof_elements
= get_nof_elements();
1287 int encoded_num_of_records
=
1288 p_td
.raw
->fieldlength
? (nof_elements
< p_td
.raw
->fieldlength
? nof_elements
: p_td
.raw
->fieldlength
)
1290 myleaf
.isleaf
= FALSE
;
1291 myleaf
.rec_of
= TRUE
;
1292 myleaf
.body
.node
.num_of_nodes
= encoded_num_of_records
;
1293 myleaf
.body
.node
.nodes
= init_nodes_of_enc_tree(encoded_num_of_records
);
1294 TTCN_Typedescriptor_t
const& elem_descr
= *get_elem_descr();
1295 for (int a
= 0; a
< encoded_num_of_records
; a
++) {
1296 const Base_Type
*field_bt
= get_at(a
);
1297 myleaf
.body
.node
.nodes
[a
] = new RAW_enc_tree(TRUE
, &myleaf
, &(myleaf
.curr_pos
), a
, elem_descr
.raw
);
1298 encoded_length
+= field_bt
->RAW_encode(elem_descr
, *myleaf
.body
.node
.nodes
[a
]);
1300 return myleaf
.length
= encoded_length
;
1303 int Record_Of_Type::RAW_encode_negtest(const Erroneous_descriptor_t
*p_err_descr
,
1304 const TTCN_Typedescriptor_t
& p_td
, RAW_enc_tree
& myleaf
) const
1308 int nof_elements
= get_nof_elements();
1309 // It can be more, of course...
1310 int encoded_num_of_records
=
1311 p_td
.raw
->fieldlength
? (nof_elements
< p_td
.raw
->fieldlength
? nof_elements
: p_td
.raw
->fieldlength
)
1313 for (int i
= 0; i
< nof_elements
; ++i
) {
1314 if ((p_err_descr
->omit_before
!= -1) && (i
< p_err_descr
->omit_before
)) {
1315 --encoded_num_of_records
;
1318 const Erroneous_values_t
*err_vals
=
1319 p_err_descr
->next_field_err_values(i
, values_idx
);
1320 // Not checking any further, `internal error' will be given anyway in the
1321 // next round. Please note that elements can be removed, `omitted'.
1322 if (err_vals
&& err_vals
->before
)
1323 ++encoded_num_of_records
;
1324 if (err_vals
&& err_vals
->value
&& !err_vals
->value
->errval
)
1325 --encoded_num_of_records
;
1326 if (err_vals
&& err_vals
->after
)
1327 ++encoded_num_of_records
;
1328 if ((p_err_descr
->omit_after
!= -1) && (i
>= p_err_descr
->omit_after
)) {
1329 encoded_num_of_records
= encoded_num_of_records
- (nof_elements
- i
) + 1;
1333 myleaf
.body
.node
.num_of_nodes
= encoded_num_of_records
;
1334 myleaf
.body
.node
.nodes
= init_nodes_of_enc_tree(encoded_num_of_records
);
1335 int encoded_length
= 0;
1336 myleaf
.isleaf
= FALSE
;
1337 myleaf
.rec_of
= TRUE
;
1340 for (int i
= 0; i
< nof_elements
; ++i
) {
1341 if ((p_err_descr
->omit_before
!= -1) && (i
< p_err_descr
->omit_before
))
1343 const Erroneous_values_t
*err_vals
= p_err_descr
->next_field_err_values(i
, values_idx
);
1344 const Erroneous_descriptor_t
*emb_descr
= p_err_descr
->next_field_emb_descr(i
, edescr_idx
);
1345 TTCN_Typedescriptor_t
const& elem_descr
= *get_elem_descr();
1346 if (err_vals
&& err_vals
->before
) {
1347 if (err_vals
->before
->errval
== NULL
)
1348 TTCN_error("internal error: erroneous before value missing");
1349 if (err_vals
->before
->raw
) {
1350 myleaf
.body
.node
.nodes
[node_pos
] = new RAW_enc_tree(true, &myleaf
,
1351 &(myleaf
.curr_pos
), node_pos
,
1352 err_vals
->before
->errval
->get_descriptor()->raw
);
1353 encoded_length
+= err_vals
->before
->errval
->
1354 RAW_encode_negtest_raw(*myleaf
.body
.node
.nodes
[node_pos
++]);
1356 if (err_vals
->before
->type_descr
== NULL
)
1357 TTCN_error("internal error: erroneous before typedescriptor missing");
1358 myleaf
.body
.node
.nodes
[node_pos
] = new RAW_enc_tree(TRUE
, &myleaf
,
1359 &(myleaf
.curr_pos
), node_pos
, elem_descr
.raw
);
1360 encoded_length
+= err_vals
->before
->errval
->
1361 RAW_encode(*(err_vals
->before
->type_descr
),
1362 *myleaf
.body
.node
.nodes
[node_pos
++]);
1365 if (err_vals
&& err_vals
->value
) {
1366 if (err_vals
->value
->errval
) {
1367 if (err_vals
->value
->raw
) {
1368 myleaf
.body
.node
.nodes
[node_pos
] = new RAW_enc_tree(true, &myleaf
,
1369 &(myleaf
.curr_pos
), node_pos
,
1370 err_vals
->value
->errval
->get_descriptor()->raw
);
1371 encoded_length
+= err_vals
->value
->errval
->
1372 RAW_encode_negtest_raw(*myleaf
.body
.node
.nodes
[node_pos
++]);
1374 if (err_vals
->value
->type_descr
== NULL
)
1375 TTCN_error("internal error: erroneous value typedescriptor missing");
1376 myleaf
.body
.node
.nodes
[node_pos
] = new RAW_enc_tree(TRUE
, &myleaf
,
1377 &(myleaf
.curr_pos
), node_pos
, elem_descr
.raw
);
1378 encoded_length
+= err_vals
->value
->errval
->
1379 RAW_encode(*(err_vals
->value
->type_descr
),
1380 *myleaf
.body
.node
.nodes
[node_pos
++]);
1385 myleaf
.body
.node
.nodes
[node_pos
] = new RAW_enc_tree(TRUE
, &myleaf
,
1386 &(myleaf
.curr_pos
), node_pos
, elem_descr
.raw
);
1387 encoded_length
+= get_at(i
)->RAW_encode_negtest(emb_descr
,
1388 *get_elem_descr(), *myleaf
.body
.node
.nodes
[node_pos
++]);
1390 myleaf
.body
.node
.nodes
[node_pos
] = new RAW_enc_tree(TRUE
, &myleaf
,
1391 &(myleaf
.curr_pos
), node_pos
, elem_descr
.raw
);
1392 encoded_length
+= get_at(i
)->RAW_encode(*get_elem_descr(),
1393 *myleaf
.body
.node
.nodes
[node_pos
++]);
1396 if (err_vals
&& err_vals
->after
) {
1397 if (err_vals
->after
->errval
== NULL
)
1398 TTCN_error("internal error: erroneous after value missing");
1399 if (err_vals
->after
->raw
) {
1400 myleaf
.body
.node
.nodes
[node_pos
] = new RAW_enc_tree(true, &myleaf
,
1401 &(myleaf
.curr_pos
), node_pos
,
1402 err_vals
->after
->errval
->get_descriptor()->raw
);
1403 encoded_length
+= err_vals
->after
->errval
->
1404 RAW_encode_negtest_raw(*myleaf
.body
.node
.nodes
[node_pos
++]);
1406 if (err_vals
->after
->type_descr
== NULL
)
1407 TTCN_error("internal error: erroneous after typedescriptor missing");
1408 myleaf
.body
.node
.nodes
[node_pos
] = new RAW_enc_tree(TRUE
, &myleaf
,
1409 &(myleaf
.curr_pos
), node_pos
, elem_descr
.raw
);
1410 encoded_length
+= err_vals
->after
->errval
->
1411 RAW_encode(*(err_vals
->after
->type_descr
),
1412 *myleaf
.body
.node
.nodes
[node_pos
++]);
1415 if ((p_err_descr
->omit_after
!= -1) && (i
>= p_err_descr
->omit_after
))
1418 return myleaf
.length
= encoded_length
;
1421 int Record_Of_Type::JSON_encode(const TTCN_Typedescriptor_t
&, JSON_Tokenizer
& p_tok
) const
1424 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND
,
1425 "Encoding an unbound %s of value.", is_set() ? "set" : "record");
1429 int enc_len
= p_tok
.put_next_token(JSON_TOKEN_ARRAY_START
, NULL
);
1431 for(int i
= 0; i
< get_nof_elements(); ++i
) {
1432 int ret_val
= get_at(i
)->JSON_encode(*get_elem_descr(), p_tok
);
1433 if (0 > ret_val
) break;
1437 enc_len
+= p_tok
.put_next_token(JSON_TOKEN_ARRAY_END
, NULL
);
1441 int Record_Of_Type::JSON_decode(const TTCN_Typedescriptor_t
& p_td
, JSON_Tokenizer
& p_tok
, boolean p_silent
)
1443 json_token_t token
= JSON_TOKEN_NONE
;
1444 int dec_len
= p_tok
.get_next_token(&token
, NULL
, NULL
);
1445 if (JSON_TOKEN_ERROR
== token
) {
1446 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG
, JSON_DEC_BAD_TOKEN_ERROR
, "");
1447 return JSON_ERROR_FATAL
;
1449 else if (JSON_TOKEN_ARRAY_START
!= token
) {
1450 return JSON_ERROR_INVALID_TOKEN
;
1455 // Read value tokens until we reach some other token
1456 size_t buf_pos
= p_tok
.get_buf_pos();
1457 Base_Type
* val
= create_elem();
1458 int ret_val
= val
->JSON_decode(*get_elem_descr(), p_tok
, p_silent
);
1459 if (JSON_ERROR_INVALID_TOKEN
== ret_val
) {
1460 // undo the last action on the buffer
1461 p_tok
.set_buf_pos(buf_pos
);
1465 else if (JSON_ERROR_FATAL
== ret_val
) {
1470 return JSON_ERROR_FATAL
;
1472 if (refd_indices
.empty()) {
1473 val_ptr
->value_elements
= (Base_Type
**)reallocate_pointers(
1474 (void**)val_ptr
->value_elements
, val_ptr
->n_elements
, val_ptr
->n_elements
+ 1);
1475 val_ptr
->value_elements
[val_ptr
->n_elements
] = val
;
1476 val_ptr
->n_elements
++;
1479 get_at(get_nof_elements())->set_value(val
);
1485 dec_len
+= p_tok
.get_next_token(&token
, NULL
, NULL
);
1486 if (JSON_TOKEN_ARRAY_END
!= token
) {
1487 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG
, JSON_DEC_REC_OF_END_TOKEN_ERROR
, "");
1491 return JSON_ERROR_FATAL
;
1497 void Record_Of_Type::encode(const TTCN_Typedescriptor_t
& p_td
,
1498 TTCN_Buffer
& p_buf
, TTCN_EncDec::coding_t p_coding
, ...) const
1501 va_start(pvar
, p_coding
);
1503 case TTCN_EncDec::CT_BER
: {
1504 TTCN_EncDec_ErrorContext
ec("While BER-encoding type '%s': ", p_td
.name
);
1505 unsigned BER_coding
=va_arg(pvar
, unsigned);
1506 BER_encode_chk_coding(BER_coding
);
1507 ASN_BER_TLV_t
*tlv
=BER_encode_TLV(p_td
, BER_coding
);
1508 tlv
->put_in_buffer(p_buf
);
1509 ASN_BER_TLV_t::destruct(tlv
);
1511 case TTCN_EncDec::CT_RAW
: {
1512 TTCN_EncDec_ErrorContext
ec("While RAW-encoding type '%s': ", p_td
.name
);
1514 TTCN_EncDec_ErrorContext::error_internal("No RAW descriptor available for type '%s'.", p_td
.name
);
1518 RAW_enc_tree
root(FALSE
, NULL
, &rp
, 1, p_td
.raw
);
1519 RAW_encode(p_td
, root
);
1520 root
.put_to_buf(p_buf
);
1522 case TTCN_EncDec::CT_TEXT
: {
1523 TTCN_EncDec_ErrorContext
ec("While TEXT-encoding type '%s': ", p_td
.name
);
1524 if(!p_td
.text
) TTCN_EncDec_ErrorContext::error_internal
1525 ("No TEXT descriptor available for type '%s'.", p_td
.name
);
1526 TEXT_encode(p_td
,p_buf
);
1528 case TTCN_EncDec::CT_XER
: {
1529 TTCN_EncDec_ErrorContext
ec("While XER-encoding type '%s': ", p_td
.name
);
1530 unsigned XER_coding
=va_arg(pvar
, unsigned);
1531 XER_encode(*(p_td
.xer
),p_buf
, XER_coding
, 0);
1534 case TTCN_EncDec::CT_JSON
: {
1535 TTCN_EncDec_ErrorContext
ec("While JSON-encoding type '%s': ", p_td
.name
);
1536 if(!p_td
.json
) TTCN_EncDec_ErrorContext::error_internal
1537 ("No JSON descriptor available for type '%s'.", p_td
.name
);
1538 JSON_Tokenizer
tok(va_arg(pvar
, int) != 0);
1539 JSON_encode(p_td
, tok
);
1540 p_buf
.put_s(tok
.get_buffer_length(), (const unsigned char*)tok
.get_buffer());
1543 TTCN_error("Unknown coding method requested to encode type '%s'", p_td
.name
);
1548 void Record_Of_Type::decode(const TTCN_Typedescriptor_t
& p_td
,
1549 TTCN_Buffer
& p_buf
, TTCN_EncDec::coding_t p_coding
, ...)
1552 va_start(pvar
, p_coding
);
1554 case TTCN_EncDec::CT_BER
: {
1555 TTCN_EncDec_ErrorContext
ec("While BER-decoding type '%s': ", p_td
.name
);
1556 unsigned L_form
=va_arg(pvar
, unsigned);
1558 BER_decode_str2TLV(p_buf
, tlv
, L_form
);
1559 BER_decode_TLV(p_td
, tlv
, L_form
);
1560 if(tlv
.isComplete
) p_buf
.increase_pos(tlv
.get_len());
1562 case TTCN_EncDec::CT_RAW
: {
1563 TTCN_EncDec_ErrorContext
ec("While RAW-decoding type '%s': ", p_td
.name
);
1564 if(!p_td
.raw
) TTCN_EncDec_ErrorContext::error_internal
1565 ("No RAW descriptor available for type '%s'.", p_td
.name
);
1567 switch(p_td
.raw
->top_bit_order
) {
1575 if(RAW_decode(p_td
, p_buf
, p_buf
.get_len()*8, order
)<0)
1576 ec
.error(TTCN_EncDec::ET_INCOMPL_MSG
,"Can not decode type '%s', "
1577 "because invalid or incomplete message was received", p_td
.name
);
1579 case TTCN_EncDec::CT_TEXT
: {
1580 Limit_Token_List limit
;
1581 TTCN_EncDec_ErrorContext
ec("While TEXT-decoding type '%s': ", p_td
.name
);
1582 if(!p_td
.text
) TTCN_EncDec_ErrorContext::error_internal
1583 ("No TEXT descriptor available for type '%s'.", p_td
.name
);
1584 const unsigned char *b
=p_buf
.get_data();
1585 if(b
[p_buf
.get_len()-1]!='\0'){
1586 p_buf
.set_pos(p_buf
.get_len());
1587 p_buf
.put_zero(8,ORDER_LSB
);
1590 if(TEXT_decode(p_td
,p_buf
,limit
)<0)
1591 ec
.error(TTCN_EncDec::ET_INCOMPL_MSG
,"Can not decode type '%s', "
1592 "because invalid or incomplete message was received", p_td
.name
);
1594 case TTCN_EncDec::CT_XER
: {
1595 TTCN_EncDec_ErrorContext
ec("While XER-decoding type '%s': ", p_td
.name
);
1596 unsigned XER_coding
=va_arg(pvar
, unsigned);
1597 XmlReaderWrap
reader(p_buf
);
1598 for (int success
=reader
.Read(); success
==1; success
=reader
.Read()) {
1599 if (reader
.NodeType() == XML_READER_TYPE_ELEMENT
) break;
1601 XER_decode(*(p_td
.xer
), reader
, XER_coding
| XER_TOPLEVEL
);
1602 size_t bytes
= reader
.ByteConsumed();
1603 p_buf
.set_pos(bytes
);
1605 case TTCN_EncDec::CT_JSON
: {
1606 TTCN_EncDec_ErrorContext
ec("While JSON-decoding type '%s': ", p_td
.name
);
1607 if(!p_td
.json
) TTCN_EncDec_ErrorContext::error_internal
1608 ("No JSON descriptor available for type '%s'.", p_td
.name
);
1609 JSON_Tokenizer
tok((const char*)p_buf
.get_data(), p_buf
.get_len());
1610 if(JSON_decode(p_td
, tok
, false)<0)
1611 ec
.error(TTCN_EncDec::ET_INCOMPL_MSG
,"Can not decode type '%s', "
1612 "because invalid or incomplete message was received", p_td
.name
);
1613 p_buf
.set_pos(tok
.get_buf_pos());
1616 TTCN_error("Unknown coding method requested to decode type '%s'", p_td
.name
);
1621 char **Record_Of_Type::collect_ns(const XERdescriptor_t
& p_td
, size_t& num
, bool& def_ns
) const
1623 size_t num_collected
= 0;
1624 // First, our own namespace. Sets num_collected to 0 or 1.
1625 // If it throws, nothing was allocated.
1626 char **collected_ns
= Base_Type::collect_ns(p_td
, num_collected
, def_ns
);
1628 // Then the embedded type
1630 bool def_ns_1
= false;
1631 if (val_ptr
) for (int i
= 0; i
< get_nof_elements(); ++i
) {
1633 char **new_namespaces
= get_at(i
)->collect_ns(
1634 *get_elem_descr()->xer
, num_new
, def_ns_1
);
1635 merge_ns(collected_ns
, num_collected
, new_namespaces
, num_new
);
1636 def_ns
= def_ns
|| def_ns_1
; // alas, no ||=
1640 // Probably a TC_Error thrown from the element's collect_ns(),
1641 // e.g. if encoding an unbound value.
1642 while (num_collected
> 0) Free(collected_ns
[--num_collected
]);
1647 num
= num_collected
;
1648 return collected_ns
;
1651 static const universal_char sp
= { 0,0,0,' ' };
1652 static const universal_char tb
= { 0,0,0,9 };
1654 int Record_Of_Type::XER_encode(const XERdescriptor_t
& p_td
, TTCN_Buffer
& p_buf
,
1655 unsigned int flavor
, int indent
) const
1658 return XER_encode_negtest(err_descr
, p_td
, p_buf
, flavor
, indent
);
1661 if (val_ptr
== 0) TTCN_error(
1662 "Attempt to XER-encode an unbound record of type %s", get_descriptor()->name
);
1663 int encoded_length
= (int)p_buf
.get_len();
1665 const int exer
= is_exer(flavor
);
1666 const boolean own_tag
=
1667 !(exer
&& indent
&& (p_td
.xer_bits
& (ANY_ELEMENT
|ANY_ATTRIBUTES
|UNTAGGED
)));
1669 const int indenting
= !is_canonical(flavor
) && own_tag
;
1670 const boolean xmlValueList
= isXmlValueList();
1673 | ( (exer
&& (p_td
.xer_bits
& XER_LIST
))
1674 || is_exerlist(flavor
) ? SIMPLE_TYPE
: 0);
1675 flavor
&= ~XER_RECOF
; // record-of doesn't care
1676 int nof_elements
= get_nof_elements();
1677 Base_Type::begin_xml(p_td
, p_buf
, flavor
, indent
, !nof_elements
,
1678 (collector_fn
)&Record_Of_Type::collect_ns
);
1680 if (xmlValueList
&& nof_elements
&& indenting
&& !exer
) { /* !exer or GDMO */
1681 do_indent(p_buf
, indent
+1);
1684 if (exer
&& (p_td
.xer_bits
& ANY_ATTRIBUTES
)) {
1685 // Back up over the '>' and the '\n' that may follow it
1686 size_t buf_len
= p_buf
.get_len(), shorter
= 0;
1687 const unsigned char * const buf_data
= p_buf
.get_data();
1688 if (buf_data
[buf_len
- 1 - shorter
] == '\n') ++shorter
;
1689 if (buf_data
[buf_len
- 1 - shorter
] == '>' ) ++shorter
;
1691 unsigned char saved
[4];
1693 memcpy(saved
, buf_data
+ (buf_len
- shorter
), shorter
);
1694 p_buf
.increase_length(-shorter
);
1697 // ANY_ATTRIBUTES means it's a record of universal charstring.
1698 // They are in AnyAttributeFormat (X.693/2008 18.2.6):
1699 // "URI(optional), space, NCName, equals, \"xmlcstring\""
1700 // They need to be written as an XML attribute and namespace declaration:
1701 // xmlns:b0="URI" b0:NCName="xmlcstring"
1703 for (int i
= 0; i
< nof_elements
; ++i
) {
1704 TTCN_EncDec_ErrorContext
ec_0("Attribute %d: ", i
);
1705 if (!is_elem_bound(i
)) {
1706 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND
,
1707 "Encoding an unbound universal charstring value.");
1710 const UNIVERSAL_CHARSTRING
*elem
1711 = static_cast<const UNIVERSAL_CHARSTRING
*>(val_ptr
->value_elements
[i
]);
1712 size_t len
= elem
->lengthof();
1714 const UNIVERSAL_CHARSTRING_ELEMENT
& ue
= (*elem
)[len
- 1];
1715 if (sp
== ue
|| tb
== ue
) --len
;
1718 // sp_at: indexes the first space
1719 // j is left to point at where the attribute name begins (just past the space)
1720 size_t j
, sp_at
= 0;
1721 for (j
= 0; j
< len
; j
++) {
1722 const UNIVERSAL_CHARSTRING_ELEMENT
& ue
= (*elem
)[j
];
1723 if (sp_at
) { // already found a space
1724 if (sp
== ue
|| tb
== ue
) {} // another space, do nothing
1725 else break; // found a non-space after a space
1728 if (sp
== ue
|| tb
== ue
) sp_at
= j
;
1732 size_t buf_start
= p_buf
.get_len();
1734 char * ns
= mprintf(" xmlns:b%d='", i
);
1735 size_t ns_len
= mstrlen(ns
);
1736 p_buf
.put_s(ns_len
, (cbyte
*)ns
);
1738 UNIVERSAL_CHARSTRING
before(sp_at
, (const universal_char
*)(*elem
));
1739 if (p_td
.xer_bits
& (ANY_FROM
| ANY_EXCEPT
)) {
1740 // Ensure the namespace abides to its restrictions
1742 before
.encode_utf8(ns_buf
);
1744 ns_buf
.get_string(cs
);
1745 check_namespace_restrictions(p_td
, (const char*)cs
);
1747 before
.XER_encode(UNIVERSAL_CHARSTRING_xer_
, p_buf
,
1748 flavor
| ANY_ATTRIBUTES
, indent
);
1753 // Keep just the "b%d" part from ns
1754 p_buf
.put_s(ns_len
- 9, (cbyte
*)ns
+ 7);
1762 if (p_td
.xer_bits
& (ANY_FROM
| ANY_EXCEPT
)) {
1763 // Make sure the unqualified namespace is allowed
1764 check_namespace_restrictions(p_td
, NULL
);
1768 UNIVERSAL_CHARSTRING
after(len
- j
, (const universal_char
*)(*elem
) + j
);
1769 after
.XER_encode(UNIVERSAL_CHARSTRING_xer_
, p_buf
,
1770 flavor
| ANY_ATTRIBUTES
, indent
);
1772 // Put this attribute in a dummy element and walk through it to check its validity
1773 TTCN_Buffer check_buf
;
1774 check_buf
.put_s(2, (unsigned char*)"<a");
1775 check_buf
.put_s(p_buf
.get_len() - buf_start
, p_buf
.get_data() + buf_start
);
1776 check_buf
.put_s(2, (unsigned char*)"/>");
1777 XmlReaderWrap
checker(check_buf
);
1778 while (1 == checker
.Read());
1781 p_buf
.put_s(shorter
, saved
); // restore the '>' and anything after
1784 else { // not ANY-ATTRIBUTES
1785 unsigned int sub_flavor
= flavor
| XER_RECOF
| (p_td
.xer_bits
& (XER_LIST
));
1787 for (int i
= 0; i
< nof_elements
; ++i
) {
1788 if (exer
&& (p_td
.xer_bits
& XER_LIST
) && i
>0) p_buf
.put_c(' ');
1789 get_at(i
)->XER_encode(*get_elem_descr()->xer
, p_buf
,
1790 sub_flavor
, indent
+own_tag
);
1793 if (indenting
&& nof_elements
&& !is_exerlist(flavor
)) {
1794 if (xmlValueList
&& !exer
) p_buf
.put_c('\n'); /* !exer or GDMO */
1795 //do_indent(p_buf, indent);
1799 Base_Type::end_xml(p_td
, p_buf
, flavor
, indent
, !nof_elements
);
1800 return (int)p_buf
.get_len() - encoded_length
;
1803 // XERSTUFF Record_Of_Type::encode_element
1804 /** Helper for Record_Of_Type::XER_encode_negtest
1806 * The main purpose of this method is to allow another type to request
1807 * encoding of a single element of the record-of. Used by Record_Type
1808 * to encode individual strings of the EMBED-VALUES member.
1810 * @param i index of the element
1811 * @param ev erroneous descriptor for the element itself
1812 * @param ed deeper erroneous values
1813 * @param p_buf buffer containing the encoded value
1814 * @param sub_flavor flags
1815 * @param indent indentation level
1816 * @return number of bytes generated
1818 int Record_Of_Type::encode_element(int i
,
1819 const Erroneous_values_t
* ev
, const Erroneous_descriptor_t
* ed
,
1820 TTCN_Buffer
& p_buf
, unsigned int sub_flavor
, int indent
) const
1822 int enc_len
= p_buf
.get_len();
1823 TTCN_EncDec_ErrorContext ec
;
1824 const int exer
= is_exer(sub_flavor
);
1826 if (ev
&& ev
->before
) {
1827 if (ev
->before
->errval
==NULL
) {
1828 TTCN_error("internal error: erroneous before value missing");
1830 ec
.set_msg("Erroneous value before component #%d: ", i
);
1831 if (ev
->before
->raw
) {
1832 ev
->before
->errval
->encode_raw(p_buf
);
1834 if (ev
->before
->type_descr
==NULL
) TTCN_error(
1835 "internal error: erroneous before type descriptor missing");
1836 ev
->before
->errval
->XER_encode(*ev
->before
->type_descr
->xer
,
1837 p_buf
, sub_flavor
, indent
);
1841 if (exer
&& (sub_flavor
& XER_LIST
)
1842 && (i
> 0 || (ev
&& ev
->before
&& !ev
->before
->raw
))){
1843 // Ensure a separator is written after the "erroneous before"
1844 // of the first element (except for "raw before").
1848 if (ev
&& ev
->value
) {
1849 if (ev
->value
->errval
) { // replace
1850 ec
.set_msg("Erroneous value for component #%d: ", i
);
1851 if (ev
->value
->raw
) {
1852 ev
->value
->errval
->encode_raw(p_buf
);
1854 if (ev
->value
->type_descr
==NULL
) TTCN_error(
1855 "internal error: erroneous value type descriptor missing");
1856 ev
->value
->errval
->XER_encode(*ev
->value
->type_descr
->xer
,
1857 p_buf
, sub_flavor
, indent
);
1861 ec
.set_msg("Component #%d: ", i
);
1863 get_at(i
)->XER_encode_negtest(ed
, *get_elem_descr()->xer
, p_buf
, sub_flavor
, indent
);
1865 // the "real" encoder
1866 get_at(i
)->XER_encode(*get_elem_descr()->xer
, p_buf
, sub_flavor
, indent
);
1870 if (ev
&& ev
->after
) {
1871 if (ev
->after
->errval
==NULL
) {
1872 TTCN_error("internal error: erroneous after value missing");
1874 ec
.set_msg("Erroneous value after component #%d: ", i
);
1875 if (ev
->after
->raw
) {
1876 ev
->after
->errval
->encode_raw(p_buf
);
1878 if (ev
->after
->type_descr
==NULL
) TTCN_error(
1879 "internal error: erroneous after type descriptor missing");
1880 ev
->after
->errval
->XER_encode(*ev
->after
->type_descr
->xer
,
1881 p_buf
, sub_flavor
, indent
);
1888 // XERSTUFF Record_Of_Type::XER_encode_negtest
1889 int Record_Of_Type::XER_encode_negtest(const Erroneous_descriptor_t
* p_err_descr
,
1890 const XERdescriptor_t
& p_td
, TTCN_Buffer
& p_buf
, unsigned flavor
, int indent
) const
1892 if (val_ptr
== 0) TTCN_error(
1893 "Attempt to XER-encode an unbound record of type %s", get_descriptor()->name
);
1894 int encoded_length
= (int)p_buf
.get_len();
1896 const int exer
= is_exer(flavor
);
1897 const boolean own_tag
=
1898 !(exer
&& indent
&& (p_td
.xer_bits
& (ANY_ELEMENT
|ANY_ATTRIBUTES
|UNTAGGED
)));
1900 const int indenting
= !is_canonical(flavor
) && own_tag
;
1901 const boolean xmlValueList
= isXmlValueList();
1904 | ( (exer
&& (p_td
.xer_bits
& XER_LIST
))
1905 || is_exerlist(flavor
) ? SIMPLE_TYPE
: 0);
1906 flavor
&= ~XER_RECOF
; // record-of doesn't care
1907 int nof_elements
= get_nof_elements();
1908 Base_Type::begin_xml(p_td
, p_buf
, flavor
, indent
, !nof_elements
,
1909 (collector_fn
)&Record_Of_Type::collect_ns
);
1911 if (xmlValueList
&& nof_elements
&& indenting
&& !exer
) { /* !exer or GDMO */
1912 do_indent(p_buf
, indent
+1);
1917 if (exer
&& (p_td
.xer_bits
& ANY_ATTRIBUTES
)) {
1918 // Back up over the '>' and the '\n' that may follow it
1919 size_t buf_len
= p_buf
.get_len(), shorter
= 0;
1920 const unsigned char * const buf_data
= p_buf
.get_data();
1921 if (buf_data
[buf_len
- 1 - shorter
] == '\n') ++shorter
;
1922 if (buf_data
[buf_len
- 1 - shorter
] == '>' ) ++shorter
;
1924 unsigned char * saved
= 0;
1926 saved
= new unsigned char[shorter
];
1927 memcpy(saved
, buf_data
+ (buf_len
- shorter
), shorter
);
1928 p_buf
.increase_length(-shorter
);
1931 // ANY_ATTRIBUTES means it's a record of universal charstring.
1932 // They are in AnyAttributeFormat (X.693/2008 18.2.6):
1933 // "URI(optional), space, NCName, equals, \"xmlcstring\""
1934 // They need to be written as an XML attribute and namespace declaration:
1935 // xmlns:b0="URI" b0:NCName="xmlcstring"
1937 for (int i
= 0; i
< nof_elements
; ++i
) {
1938 if (i
< p_err_descr
->omit_before
) continue;
1940 const Erroneous_values_t
*ev
= p_err_descr
->next_field_err_values(i
, values_idx
);
1941 const Erroneous_descriptor_t
*ed
= p_err_descr
->next_field_emb_descr(i
, edescr_idx
);
1943 if (ev
&& ev
->before
) {
1944 if (ev
->before
->errval
==NULL
) TTCN_error("internal error: erroneous value missing");
1947 if (ev
->before
->raw
) ev
->before
->errval
->encode_raw(p_buf
);
1949 if (ev
->before
->type_descr
==NULL
) TTCN_error(
1950 "internal error: erroneous before type descriptor missing");
1951 else ev
->before
->errval
->XER_encode(*ev
->before
->type_descr
->xer
,
1952 p_buf
, flavor
, indent
);
1956 if (ev
&& ev
->value
) { //value replacement
1957 if (ev
->value
->errval
) {
1958 if (ev
->value
->raw
) ev
->value
->errval
->encode_raw(p_buf
);
1960 if (ev
->value
->type_descr
==NULL
) TTCN_error(
1961 "internal error: erroneous value type descriptor missing");
1962 else ev
->value
->errval
->XER_encode(*ev
->value
->type_descr
->xer
,
1963 p_buf
, flavor
, indent
);
1969 // embedded descr.. call negtest (except UNIVERSAL_CHARSTRING
1970 // doesn't have XER_encode_negtest)
1971 TTCN_error("internal error: embedded descriptor for scalar");
1974 // the original encoding
1975 const UNIVERSAL_CHARSTRING
*elem
1976 = static_cast<const UNIVERSAL_CHARSTRING
*>(get_at(i
));
1977 size_t len
= elem
->lengthof();
1979 const UNIVERSAL_CHARSTRING_ELEMENT
& ue
= (*elem
)[len
- 1];
1980 if (sp
== ue
|| tb
== ue
) --len
;
1983 // sp_at: indexes the first space
1984 // j is left to point at where the attribute name begins (just past the space)
1985 size_t j
, sp_at
= 0;
1986 for (j
= 0; j
< len
; j
++) {
1987 const UNIVERSAL_CHARSTRING_ELEMENT
& ue
= (*elem
)[j
];
1988 if (sp_at
) { // already found a space
1989 if (sp
== ue
|| tb
== ue
) {} // another space, do nothing
1990 else break; // found a non-space after a space
1993 if (sp
== ue
|| tb
== ue
) sp_at
= j
;
1998 char * ns
= mprintf(" xmlns:b%d='", i
);
1999 size_t ns_len
= mstrlen(ns
);
2000 p_buf
.put_s(ns_len
, (cbyte
*)ns
);
2002 UNIVERSAL_CHARSTRING
before(sp_at
, (const universal_char
*)(*elem
));
2003 before
.XER_encode(UNIVERSAL_CHARSTRING_xer_
, p_buf
,
2004 flavor
| ANY_ATTRIBUTES
, indent
);
2009 // Keep just the "b%d" part from ns
2010 p_buf
.put_s(ns_len
- 9, (cbyte
*)ns
+ 7);
2019 UNIVERSAL_CHARSTRING
after(len
- j
, (const universal_char
*)(*elem
) + j
);
2020 after
.XER_encode(UNIVERSAL_CHARSTRING_xer_
, p_buf
,
2021 flavor
| ANY_ATTRIBUTES
, indent
);
2025 if (ev
&& ev
->after
) {
2026 if (ev
->after
->errval
==NULL
) TTCN_error(
2027 "internal error: erroneous after value missing");
2029 if (ev
->after
->raw
) ev
->after
->errval
->encode_raw(p_buf
);
2031 if (ev
->after
->type_descr
==NULL
) TTCN_error(
2032 "internal error: erroneous after type descriptor missing");
2033 else ev
->after
->errval
->XER_encode(*ev
->after
->type_descr
->xer
,
2034 p_buf
, flavor
, indent
);
2038 // omit_after value -1 becomes "very big"
2039 if ((unsigned int)i
>= (unsigned int)p_err_descr
->omit_after
) break;
2042 p_buf
.put_s(shorter
, saved
); // restore the '>' and anything after
2046 else { // not ANY-ATTRIBUTES
2047 unsigned int sub_flavor
= flavor
| XER_RECOF
| (p_td
.xer_bits
& (XER_LIST
|ANY_ATTRIBUTES
));
2049 TTCN_EncDec_ErrorContext ec
;
2051 for (int i
= 0; i
< nof_elements
; ++i
) {
2052 if (i
< p_err_descr
->omit_before
) continue;
2054 const Erroneous_values_t
* err_vals
=
2055 p_err_descr
->next_field_err_values(i
, values_idx
);
2056 const Erroneous_descriptor_t
* emb_descr
=
2057 p_err_descr
->next_field_emb_descr (i
, edescr_idx
);
2059 encode_element(i
, err_vals
, emb_descr
, p_buf
, sub_flavor
, indent
+own_tag
);
2061 // omit_after value -1 becomes "very big"
2062 if ((unsigned int)i
>= (unsigned int)p_err_descr
->omit_after
) break;
2065 if (indenting
&& nof_elements
&& !is_exerlist(flavor
)) {
2066 if (xmlValueList
&& !exer
) p_buf
.put_c('\n'); /* !exer or GDMO */
2067 //do_indent(p_buf, indent);
2071 Base_Type::end_xml(p_td
, p_buf
, flavor
, indent
, !nof_elements
);
2072 return (int)p_buf
.get_len() - encoded_length
;
2075 int Record_Of_Type::XER_decode(const XERdescriptor_t
& p_td
,
2076 XmlReaderWrap
& reader
, unsigned int flavor
)
2078 int exer
= is_exer(flavor
);
2079 int xerbits
= p_td
.xer_bits
;
2080 if (flavor
& XER_TOPLEVEL
) xerbits
&= ~UNTAGGED
;
2082 !(exer
&& ((xerbits
& (ANY_ELEMENT
| ANY_ATTRIBUTES
| UNTAGGED
))
2083 || (flavor
& USE_TYPE_ATTR
))); /* incase the parent has USE-UNION */
2084 /* not toplevel anymore and remove the flags for USE-UNION the oftype doesn't need them */
2085 flavor
&= ~XER_TOPLEVEL
& ~XER_LIST
& ~USE_TYPE_ATTR
;
2086 int success
=1, depth
=-1;
2087 set_val(NULL_VALUE
); // empty but initialized array, val_ptr != NULL
2089 if (own_tag
) for (success
= 1; success
== 1; success
= reader
.Read()) {
2090 type
= reader
.NodeType();
2091 if (exer
&& (p_td
.xer_bits
& XER_ATTRIBUTE
)) {
2092 if (XML_READER_TYPE_ATTRIBUTE
== type
) break;
2094 if (exer
&& (p_td
.xer_bits
& XER_LIST
)) {
2095 if (XML_READER_TYPE_TEXT
== type
) break;
2098 if (XML_READER_TYPE_ELEMENT
== type
) {
2099 verify_name(reader
, p_td
, exer
);
2100 depth
= reader
.Depth();
2103 } /* endif(exer && list) */
2105 else depth
= reader
.Depth();
2106 TTCN_EncDec_ErrorContext
ec_0("Index ");
2107 TTCN_EncDec_ErrorContext ec_1
;
2108 flavor
|= XER_RECOF
;
2109 if (exer
&& (p_td
.xer_bits
& ANY_ATTRIBUTES
)) {
2110 // The enclosing type should handle the decoding.
2111 TTCN_error("Incorrect decoding of ANY-ATTRIBUTES");
2113 else if (exer
&& (p_td
.xer_bits
& XER_LIST
)) { /* LIST decoding*/
2114 char *val
= (char*)reader
.NewValue(); /* we own it */
2116 size_t len
= strlen(val
);
2117 /* The string contains a bunch of values separated by whitespace.
2118 * Tokenize the string and create a new buffer which looks like
2119 * an XML element (<ns:name xmlns:ns='uri'>value</ns:name>), then use that
2120 * to decode the value. */
2121 for(char * str
= strtok(val
, " \t\x0A\x0D"); str
!= 0; str
= strtok(val
+ pos
, " \t\x0A\x0D")) {
2122 // Calling strtok with NULL won't work here, since the decoded element can have strtok calls aswell
2123 pos
+= strlen(str
) + 1;
2124 // Construct a new XML Reader with the current token.
2126 const XERdescriptor_t
& sub_xer
= *get_elem_descr()->xer
;
2128 write_ns_prefix(sub_xer
, buf2
);
2130 boolean i_can_has_ns
= sub_xer
.my_module
!= 0 && sub_xer
.ns_index
!= -1;
2131 const char * const exer_name
= sub_xer
.names
[1];
2132 buf2
.put_s((size_t)sub_xer
.namelens
[1]-1-i_can_has_ns
, (cbyte
*)exer_name
);
2134 const namespace_t
* const pns
= sub_xer
.my_module
->get_ns(sub_xer
.ns_index
);
2135 buf2
.put_s(7 - (*pns
->px
== 0), (cbyte
*)" xmlns:");
2136 buf2
.put_s(strlen(pns
->px
), (cbyte
*)pns
->px
);
2137 buf2
.put_s(2, (cbyte
*)"='");
2138 buf2
.put_s(strlen(pns
->ns
), (cbyte
*)pns
->ns
);
2139 buf2
.put_s(2, (cbyte
*)"'>");
2141 // start tag completed
2142 buf2
.put_s(strlen(str
), (cbyte
*)str
);
2146 write_ns_prefix(sub_xer
, buf2
);
2147 buf2
.put_s((size_t)sub_xer
.namelens
[1], (cbyte
*)exer_name
);
2148 XmlReaderWrap
reader2(buf2
);
2149 reader2
.Read(); // Move to the start element.
2150 // Don't move to the #text, that's the callee's responsibility.
2151 ec_1
.set_msg("%d: ", get_nof_elements());
2152 // The call to the non-const operator[], I mean get_at(), creates
2153 // a new element (because it is indexing one past the last element).
2154 // Then we call its XER_decode with the temporary XML reader.
2155 get_at(get_nof_elements())->XER_decode(sub_xer
, reader2
, flavor
);
2156 if (flavor
& EXIT_ON_ERROR
&& !is_elem_bound(get_nof_elements() - 1)) {
2157 if (1 == get_nof_elements()) {
2158 // Failed to decode even the first element
2161 // Some elements were successfully decoded -> only delete the last one
2162 set_size(get_nof_elements() - 1);
2167 if (pos
>= len
) break;
2170 if (p_td
.xer_bits
& XER_ATTRIBUTE
) {
2171 //Let the caller do reader.AdvanceAttribute();
2174 reader
.Read(); // on closing tag
2175 reader
.Read(); // past it
2179 if (flavor
& PARENT_CLOSED
) {
2180 // Nothing to do. We are probably untagged; do not advance in the XML
2181 // because it would move past the parent.
2183 else if (own_tag
&& reader
.IsEmptyElement()) { // Nothing to do
2184 reader
.Read(); // This is our own empty tag, move past it
2187 /* Note: there is no reader.Read() at the end of the loop below.
2188 * Each element is supposed to consume enough to leave the next element
2189 * well-positioned. */
2190 for (success
= own_tag
? reader
.Read() : reader
.Ok(); success
== 1; ) {
2191 type
= reader
.NodeType();
2192 if (XML_READER_TYPE_ELEMENT
== type
)
2194 if (exer
&& (p_td
.xer_bits
& ANY_ELEMENT
)) {
2195 /* This is a (record-of UNIVERSAL_CHARSTRING) with ANY-ELEMENT.
2196 * The ANY-ELEMENT is really meant for the element type,
2197 * so behave like a record-of (string with ANY-ELEMENT):
2198 * call the non-const operator[], I mean get_at(), to create
2199 * a new element, then read the entire XML element into it. */
2200 UNIVERSAL_CHARSTRING
* uc
=
2201 static_cast<UNIVERSAL_CHARSTRING
*>(get_at(val_ptr
->n_elements
));
2202 const xmlChar
* outer
= reader
.ReadOuterXml();
2203 uc
->decode_utf8(strlen((const char*)outer
), outer
);
2204 // consume the element
2205 for (success
= reader
.Read(); success
== 1 && reader
.Depth() > depth
; success
= reader
.Read()) {}
2206 if (reader
.NodeType() != XML_READER_TYPE_ELEMENT
) success
= reader
.Read(); // one last time
2209 /* If this is an untagged record-of and the start element does not
2210 * belong to the embedded type, the record-of has already ended. */
2211 if (!own_tag
&& !can_start_v(
2212 (const char*)reader
.LocalName(), (const char*)reader
.NamespaceUri(),
2213 *get_elem_descr()->xer
, flavor
| UNTAGGED
))
2215 for (; success
== 1 && reader
.Depth() > depth
; success
= reader
.Read()) ;
2216 // We should now be back at the same depth as we started.
2219 ec_1
.set_msg("%d: ", get_nof_elements());
2220 /* The call to the non-const get_at() creates the element */
2221 get_at(get_nof_elements())->XER_decode(*get_elem_descr()->xer
, reader
, flavor
);
2224 else if (XML_READER_TYPE_END_ELEMENT
== type
) {
2225 for (; success
== 1 && reader
.Depth() > depth
; success
= reader
.Read()) ;
2226 // If the depth just decreased, this must be an end element
2227 // (but a different one from what we had before the loop)
2229 verify_end(reader
, p_td
, depth
, exer
);
2230 reader
.Read(); // move forward one last time
2235 success
= reader
.Read();
2238 } /* if not empty element */
2240 return 1; // decode successful
2243 void Record_Of_Type::set_param(Module_Param
& param
) {
2244 if (dynamic_cast<Module_Param_Name
*>(param
.get_id()) != NULL
&&
2245 param
.get_id()->next_name()) {
2246 // Haven't reached the end of the module parameter name
2247 // => the name refers to one of the elements, not to the whole record of
2248 char* param_field
= param
.get_id()->get_current_name();
2249 if (param_field
[0] < '0' || param_field
[0] > '9') {
2250 param
.error("Unexpected record field name in module parameter, expected a valid"
2251 " index for %s type `%s'", is_set() ? "set of" : "record of", get_descriptor()->name
);
2253 int param_index
= -1;
2254 sscanf(param_field
, "%d", ¶m_index
);
2255 get_at(param_index
)->set_param(param
);
2259 param
.basic_check(Module_Param::BC_VALUE
|Module_Param::BC_LIST
, is_set()?"set of value":"record of value");
2260 switch (param
.get_operation_type()) {
2261 case Module_Param::OT_ASSIGN
:
2262 if (param
.get_type()==Module_Param::MP_Value_List
&& param
.get_size()==0) {
2263 set_val(NULL_VALUE
);
2266 switch (param
.get_type()) {
2267 case Module_Param::MP_Value_List
:
2268 set_size(param
.get_size());
2269 for (size_t i
=0; i
<param
.get_size(); ++i
) {
2270 Module_Param
* const curr
= param
.get_elem(i
);
2271 if (curr
->get_type()!=Module_Param::MP_NotUsed
) {
2272 get_at(i
)->set_param(*curr
);
2276 case Module_Param::MP_Indexed_List
:
2277 for (size_t i
=0; i
<param
.get_size(); ++i
) {
2278 Module_Param
* const current
= param
.get_elem(i
);
2279 get_at(current
->get_id()->get_index())->set_param(*current
);
2283 param
.type_error(is_set()?"set of value":"record of value", get_descriptor()->name
);
2286 case Module_Param::OT_CONCAT
:
2287 switch (param
.get_type()) {
2288 case Module_Param::MP_Value_List
: {
2289 if (!is_bound()) set_val(NULL_VALUE
);
2290 int start_idx
= lengthof();
2291 for (size_t i
=0; i
<param
.get_size(); ++i
) {
2292 Module_Param
* const curr
= param
.get_elem(i
);
2293 if ((curr
->get_type()!=Module_Param::MP_NotUsed
)) {
2294 get_at(start_idx
+(int)i
)->set_param(*curr
);
2298 case Module_Param::MP_Indexed_List
:
2299 param
.error("Cannot concatenate an indexed value list");
2302 param
.type_error(is_set()?"set of value":"record of value", get_descriptor()->name
);
2306 TTCN_error("Internal error: Record_Of_Type::set_param()");
2310 void Record_Of_Type::set_implicit_omit()
2312 for (int i
= 0; i
< get_nof_elements(); ++i
) {
2313 if (is_elem_bound(i
))
2314 val_ptr
->value_elements
[i
]->set_implicit_omit();
2318 void Record_Of_Type::add_refd_index(int index
)
2320 refd_indices
.push_back(index
);
2321 if (index
> get_max_refd_index()) {
2322 max_refd_index
= index
;
2326 void Record_Of_Type::remove_refd_index(int index
)
2328 for (size_t i
= refd_indices
.size(); i
> 0; --i
) {
2329 if (refd_indices
[i
- 1] == index
) {
2330 refd_indices
.erase_at(i
- 1);
2334 if (get_max_refd_index() == index
) {
2335 max_refd_index
= -1;
2339 boolean
operator==(null_type
/*null_value*/, const Record_Of_Type
& other_value
)
2341 if (other_value
.val_ptr
== NULL
)
2342 TTCN_error("The right operand of comparison is an unbound value of type %s.",
2343 other_value
.get_descriptor()->name
);
2344 return other_value
.get_nof_elements() == 0;
2347 boolean
operator!=(null_type null_value
,
2348 const Record_Of_Type
& other_value
)
2350 return !(null_value
== other_value
);
2353 ////////////////////////////////////////////////////////////////////////////////
2355 boolean
Record_Type::is_bound() const
2357 if (bound_flag
) return TRUE
;
2358 int field_cnt
= get_count();
2359 for (int field_idx
=0; field_idx
<field_cnt
; field_idx
++) {
2360 const Base_Type
* temp
= get_at(field_idx
);
2361 if(temp
->is_optional()) {
2362 if(temp
->is_present() && temp
->get_opt_value()->is_bound()) return TRUE
;
2364 if(temp
->is_bound()) return TRUE
;
2369 boolean
Record_Type::is_value() const
2374 int field_cnt
= get_count();
2375 for (int field_idx
=0; field_idx
<field_cnt
; field_idx
++) {
2376 const Base_Type
* temp
= get_at(field_idx
);
2377 if(temp
->is_optional()) {
2378 if(!temp
->is_bound()) return FALSE
;
2379 if(temp
->is_present() && !temp
->is_value()) return FALSE
;
2381 if(!temp
->is_value()) return FALSE
;
2387 void Record_Type::clean_up()
2389 int field_cnt
= get_count();
2390 for (int field_idx
=0; field_idx
<field_cnt
; field_idx
++) {
2391 get_at(field_idx
)->clean_up();
2396 void Record_Type::log() const
2399 TTCN_Logger::log_event_unbound();
2402 TTCN_Logger::log_event_str("{ ");
2403 int field_cnt
= get_count();
2404 for (int field_idx
=0; field_idx
<field_cnt
; field_idx
++) {
2405 if (field_idx
) TTCN_Logger::log_event_str(", ");
2406 TTCN_Logger::log_event_str(fld_name(field_idx
));
2407 TTCN_Logger::log_event_str(" := ");
2408 get_at(field_idx
)->log();
2410 TTCN_Logger::log_event_str(" }");
2411 if (err_descr
) err_descr
->log();
2414 void Record_Type::set_param(Module_Param
& param
) {
2416 if (dynamic_cast<Module_Param_Name
*>(param
.get_id()) != NULL
&&
2417 param
.get_id()->next_name()) {
2418 // Haven't reached the end of the module parameter name
2419 // => the name refers to one of the fields, not to the whole record
2420 char* param_field
= param
.get_id()->get_current_name();
2421 if (param_field
[0] >= '0' && param_field
[0] <= '9') {
2422 param
.error("Unexpected array index in module parameter, expected a valid field"
2423 " name for %s type `%s'", is_set() ? "set" : "record", get_descriptor()->name
);
2425 int field_cnt
= get_count();
2426 for (int field_idx
= 0; field_idx
< field_cnt
; field_idx
++) {
2427 if (strcmp(fld_name(field_idx
), param_field
) == 0) {
2428 get_at(field_idx
)->set_param(param
);
2432 param
.error("Field `%s' not found in %s type `%s'",
2433 param_field
, is_set() ? "set" : "record", get_descriptor()->name
);
2436 param
.basic_check(Module_Param::BC_VALUE
, is_set()?"set value":"record value");
2437 switch (param
.get_type()) {
2438 case Module_Param::MP_Value_List
:
2439 if (get_count()<(int)param
.get_size()) {
2440 param
.error("%s value of type %s has %d fields but list value has %d fields", is_set()?"Set":"Record", get_descriptor()->name
, get_count(), (int)param
.get_size());
2442 for (size_t i
=0; i
<param
.get_size(); i
++) {
2443 Module_Param
* mp
= param
.get_elem(i
);
2444 if (mp
->get_type()!=Module_Param::MP_NotUsed
) {
2445 get_at((int)i
)->set_param(*mp
);
2449 case Module_Param::MP_Assignment_List
:
2450 for (size_t i
=0; i
<param
.get_size(); ++i
) {
2451 Module_Param
* const current
= param
.get_elem(i
);
2453 for (int j
=0; j
<get_count(); ++j
) {
2454 if (!strcmp(fld_name(j
), current
->get_id()->get_name())) {
2455 if (current
->get_type()!=Module_Param::MP_NotUsed
) {
2456 get_at(j
)->set_param(*current
);
2463 current
->error("Non existent field name in type %s: %s.", get_descriptor()->name
, current
->get_id()->get_name());
2468 param
.type_error(is_set()?"set value":"record value", get_descriptor()->name
);
2472 void Record_Type::set_implicit_omit()
2474 int field_cnt
= get_count();
2475 for (int field_idx
= 0; field_idx
< field_cnt
; field_idx
++) {
2476 Base_Type
*temp
= get_at(field_idx
);
2477 if (temp
->is_optional()) {
2478 if (temp
->is_bound()) temp
->set_implicit_omit();
2479 else temp
->set_to_omit();
2480 } else if (temp
->is_bound()) {
2481 temp
->set_implicit_omit();
2486 int Record_Type::size_of() const
2489 TTCN_error("Calculating the size of an unbound record/set value of type %s",
2490 get_descriptor()->name
);
2492 int opt_count
= optional_count();
2493 if (opt_count
==0) return get_count();
2494 const int* optional_indexes
= get_optional_indexes();
2495 int my_size
= get_count();
2496 for (int i
=0; i
<opt_count
; i
++) {
2497 if (!get_at(optional_indexes
[i
])->ispresent()) my_size
--;
2502 void Record_Type::encode_text(Text_Buf
& text_buf
) const
2505 TTCN_error("Text encoder: Encoding an unbound record/set value of type %s.",
2506 get_descriptor()->name
);
2508 int field_cnt
= get_count();
2509 for (int field_idx
=0; field_idx
<field_cnt
; field_idx
++)
2510 get_at(field_idx
)->encode_text(text_buf
);
2513 void Record_Type::decode_text(Text_Buf
& text_buf
)
2516 int field_cnt
= get_count();
2517 for (int field_idx
=0; field_idx
<field_cnt
; field_idx
++)
2518 get_at(field_idx
)->decode_text(text_buf
);
2521 boolean
Record_Type::is_equal(const Base_Type
* other_value
) const
2523 const Record_Type
* other_record
= static_cast<const Record_Type
*>(other_value
);
2524 if (!is_bound() && !other_record
->is_bound()) {
2527 int field_cnt
= get_count();
2528 for (int field_idx
=0; field_idx
<field_cnt
; field_idx
++) {
2529 const Base_Type
* elem
= get_at(field_idx
);
2530 const Base_Type
* other_elem
= other_record
->get_at(field_idx
);
2531 if (elem
->is_bound()) {
2532 if (other_elem
->is_bound()) {
2533 if (!elem
->is_equal(other_elem
))
2535 } else return FALSE
;
2536 } else if (other_elem
->is_bound()) return FALSE
;
2541 void Record_Type::set_value(const Base_Type
* other_value
)
2543 if (this==other_value
) return;
2544 if (!other_value
->is_bound())
2545 TTCN_error("Copying an unbound record/set value of type %s.",
2546 other_value
->get_descriptor()->name
);
2547 const Record_Type
* other_record
= static_cast<const Record_Type
*>(other_value
);
2548 int field_cnt
= get_count();
2549 for (int field_idx
=0; field_idx
<field_cnt
; field_idx
++) {
2550 const Base_Type
* elem
= other_record
->get_at(field_idx
);
2551 if (elem
->is_bound()) {
2552 get_at(field_idx
)->set_value(elem
);
2554 get_at(field_idx
)->clean_up();
2557 err_descr
= other_record
->err_descr
;
2561 void Record_Type::encode(const TTCN_Typedescriptor_t
& p_td
,
2562 TTCN_Buffer
& p_buf
, TTCN_EncDec::coding_t p_coding
, ...) const
2565 va_start(pvar
, p_coding
);
2567 case TTCN_EncDec::CT_BER
: {
2568 TTCN_EncDec_ErrorContext
ec("While BER-encoding type '%s': ", p_td
.name
);
2569 unsigned BER_coding
=va_arg(pvar
, unsigned);
2570 BER_encode_chk_coding(BER_coding
);
2571 ASN_BER_TLV_t
*tlv
=BER_encode_TLV(p_td
, BER_coding
);
2572 tlv
->put_in_buffer(p_buf
);
2573 ASN_BER_TLV_t::destruct(tlv
);
2575 case TTCN_EncDec::CT_RAW
: {
2576 TTCN_EncDec_ErrorContext
ec("While RAW-encoding type '%s': ", p_td
.name
);
2577 if(!p_td
.raw
) TTCN_EncDec_ErrorContext::error_internal
2578 ("No RAW descriptor available for type '%s'.", p_td
.name
);
2582 RAW_enc_tree
root(FALSE
, NULL
, &rp
, 1, p_td
.raw
);
2583 RAW_encode(p_td
, root
);
2584 root
.put_to_buf(p_buf
);
2586 case TTCN_EncDec::CT_TEXT
: {
2587 TTCN_EncDec_ErrorContext
ec("While TEXT-encoding type '%s': ", p_td
.name
);
2588 if(!p_td
.text
) TTCN_EncDec_ErrorContext::error_internal
2589 ("No TEXT descriptor available for type '%s'.", p_td
.name
);
2590 TEXT_encode(p_td
,p_buf
);
2592 case TTCN_EncDec::CT_XER
: {
2593 TTCN_EncDec_ErrorContext
ec("While XER-encoding type '%s': ", p_td
.name
);
2594 unsigned XER_coding
=va_arg(pvar
, unsigned);
2595 XER_encode(*(p_td
.xer
),p_buf
, XER_coding
, 0);
2598 case TTCN_EncDec::CT_JSON
: {
2599 TTCN_EncDec_ErrorContext
ec("While JSON-encoding type '%s': ", p_td
.name
);
2600 if(!p_td
.json
) TTCN_EncDec_ErrorContext::error_internal
2601 ("No JSON descriptor available for type '%s'.", p_td
.name
);
2602 JSON_Tokenizer
tok(va_arg(pvar
, int) != 0);
2603 JSON_encode(p_td
, tok
);
2604 p_buf
.put_s(tok
.get_buffer_length(), (const unsigned char*)tok
.get_buffer());
2607 TTCN_error("Unknown coding method requested to encode type '%s'", p_td
.name
);
2612 void Record_Type::decode(const TTCN_Typedescriptor_t
& p_td
,
2613 TTCN_Buffer
& p_buf
, TTCN_EncDec::coding_t p_coding
, ...)
2616 va_start(pvar
, p_coding
);
2618 case TTCN_EncDec::CT_BER
: {
2619 TTCN_EncDec_ErrorContext
ec("While BER-decoding type '%s': ", p_td
.name
);
2620 unsigned L_form
=va_arg(pvar
, unsigned);
2622 BER_decode_str2TLV(p_buf
, tlv
, L_form
);
2623 BER_decode_TLV(p_td
, tlv
, L_form
);
2624 if(tlv
.isComplete
) p_buf
.increase_pos(tlv
.get_len());
2626 case TTCN_EncDec::CT_RAW
: {
2627 TTCN_EncDec_ErrorContext
ec("While RAW-decoding type '%s': ", p_td
.name
);
2629 TTCN_EncDec_ErrorContext::error_internal
2630 ("No RAW descriptor available for type '%s'.", p_td
.name
);
2632 switch(p_td
.raw
->top_bit_order
) {
2640 int rawr
= RAW_decode(p_td
, p_buf
, p_buf
.get_len()*8, order
);
2641 if (rawr
< 0) switch (-rawr
) {
2642 case TTCN_EncDec::ET_INCOMPL_MSG
:
2643 case TTCN_EncDec::ET_LEN_ERR
:
2644 ec
.error(TTCN_EncDec::ET_INCOMPL_MSG
,
2645 "Can not decode type '%s', because incomplete"
2646 " message was received", p_td
.name
);
2649 // The RAW/TEXT decoders return -1 for anything not a length error.
2650 // This is the value for ET_UNBOUND, which can't happen in decoding.
2652 ec
.error(TTCN_EncDec::ET_INVAL_MSG
,
2653 "Can not decode type '%s', because invalid"
2654 " message was received", p_td
.name
);
2658 case TTCN_EncDec::CT_TEXT
: {
2659 Limit_Token_List limit
;
2660 TTCN_EncDec_ErrorContext
ec("While TEXT-decoding type '%s': ", p_td
.name
);
2661 if(!p_td
.text
) TTCN_EncDec_ErrorContext::error_internal
2662 ("No TEXT descriptor available for type '%s'.", p_td
.name
);
2663 const unsigned char *b
=p_buf
.get_data();
2664 if(b
[p_buf
.get_len()-1]!='\0'){
2665 p_buf
.set_pos(p_buf
.get_len());
2666 p_buf
.put_zero(8,ORDER_LSB
);
2669 if(TEXT_decode(p_td
,p_buf
,limit
)<0)
2670 ec
.error(TTCN_EncDec::ET_INCOMPL_MSG
,
2671 "Can not decode type '%s', because invalid or incomplete"
2672 " message was received", p_td
.name
);
2674 case TTCN_EncDec::CT_XER
: {
2675 TTCN_EncDec_ErrorContext
ec("While XER-decoding type '%s': ", p_td
.name
);
2676 unsigned XER_coding
=va_arg(pvar
, unsigned);
2677 XmlReaderWrap
reader(p_buf
);
2678 for (int success
=reader
.Read(); success
==1; success
=reader
.Read()) {
2679 if (reader
.NodeType() == XML_READER_TYPE_ELEMENT
) break;
2681 XER_decode(*(p_td
.xer
), reader
, XER_coding
| XER_TOPLEVEL
);
2682 size_t bytes
= reader
.ByteConsumed();
2683 p_buf
.set_pos(bytes
);
2685 case TTCN_EncDec::CT_JSON
: {
2686 TTCN_EncDec_ErrorContext
ec("While JSON-decoding type '%s': ", p_td
.name
);
2687 if(!p_td
.json
) TTCN_EncDec_ErrorContext::error_internal
2688 ("No JSON descriptor available for type '%s'.", p_td
.name
);
2689 JSON_Tokenizer
tok((const char*)p_buf
.get_data(), p_buf
.get_len());
2690 if(JSON_decode(p_td
, tok
, false)<0)
2691 ec
.error(TTCN_EncDec::ET_INCOMPL_MSG
,
2692 "Can not decode type '%s', because invalid or incomplete"
2693 " message was received", p_td
.name
);
2694 p_buf
.set_pos(tok
.get_buf_pos());
2697 TTCN_error("Unknown coding method requested to decode type '%s'", p_td
.name
);
2702 ASN_BER_TLV_t
* Record_Type::BER_encode_TLV(const TTCN_Typedescriptor_t
& p_td
, unsigned p_coding
) const
2705 return BER_encode_TLV_negtest(err_descr
, p_td
, p_coding
);
2708 TTCN_EncDec_ErrorContext::error
2709 (TTCN_EncDec::ET_UNBOUND
, "Encoding an unbound value.");
2711 BER_chk_descr(p_td
);
2712 ASN_BER_TLV_t
*new_tlv
=ASN_BER_TLV_t::construct(NULL
);
2713 TTCN_EncDec_ErrorContext
ec_0("Component '");
2714 TTCN_EncDec_ErrorContext ec_1
;
2715 int next_default_idx
= 0;
2716 const default_struct
* default_indexes
= get_default_indexes();
2717 int field_cnt
= get_count();
2718 for(int i
=0; i
<field_cnt
; i
++) {
2719 boolean is_default_field
= default_indexes
&& (default_indexes
[next_default_idx
].index
==i
);
2720 if (!default_as_optional() && is_default_field
) {
2721 if (!get_at(i
)->is_equal(default_indexes
[next_default_idx
].value
)) {
2722 ec_1
.set_msg("%s': ", fld_name(i
));
2723 new_tlv
->add_TLV(get_at(i
)->BER_encode_TLV(*fld_descr(i
), p_coding
));
2725 } else { /* is not DEFAULT */
2726 ec_1
.set_msg("%s': ", fld_name(i
));
2727 new_tlv
->add_TLV(get_at(i
)->BER_encode_TLV(*fld_descr(i
), p_coding
));
2729 if (is_default_field
) next_default_idx
++;
2732 if (p_coding
==BER_ENCODE_DER
) new_tlv
->sort_tlvs_tag();
2733 new_tlv
=ASN_BER_V2TLV(new_tlv
, p_td
, p_coding
);
2737 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
2740 TTCN_EncDec_ErrorContext::error
2741 (TTCN_EncDec::ET_UNBOUND
, "Encoding an unbound value.");
2743 BER_chk_descr(p_td
);
2744 ASN_BER_TLV_t
*new_tlv
=ASN_BER_TLV_t::construct(NULL
);
2745 TTCN_EncDec_ErrorContext
ec_0("Component '");
2746 TTCN_EncDec_ErrorContext ec_1
;
2747 int next_default_idx
= 0;
2748 const default_struct
* default_indexes
= get_default_indexes();
2749 int field_cnt
= get_count();
2754 for (int i
=0; i
<field_cnt
; i
++) {
2755 boolean is_default_field
= default_indexes
&& (default_indexes
[next_default_idx
].index
==i
);
2756 // the first condition is not needed, kept for ease of understanding
2757 if ( (p_err_descr
->omit_before
!=-1) && (i
<p_err_descr
->omit_before
) ) {
2758 if (is_default_field
) next_default_idx
++;
2761 const Erroneous_values_t
* err_vals
= p_err_descr
->next_field_err_values(i
, values_idx
);
2762 const Erroneous_descriptor_t
* emb_descr
= p_err_descr
->next_field_emb_descr(i
, edescr_idx
);
2764 if (err_vals
&& err_vals
->before
) {
2765 if (err_vals
->before
->errval
==NULL
) TTCN_error(
2766 "internal error: erroneous before value missing");
2767 ec_1
.set_msg("%s'(erroneous before): ", fld_name(i
));
2768 if (err_vals
->before
->raw
) {
2769 new_tlv
->add_TLV(err_vals
->before
->errval
->BER_encode_negtest_raw());
2771 if (err_vals
->before
->type_descr
==NULL
) TTCN_error(
2772 "internal error: erroneous before typedescriptor missing");
2773 new_tlv
->add_TLV(err_vals
->before
->errval
->BER_encode_TLV(
2774 *err_vals
->before
->type_descr
, p_coding
));
2778 if (err_vals
&& err_vals
->value
) {
2779 if (err_vals
->value
->errval
) { // replace
2780 ec_1
.set_msg("%s'(erroneous value): ", fld_name(i
));
2781 if (err_vals
->value
->raw
) {
2782 new_tlv
->add_TLV(err_vals
->value
->errval
->BER_encode_negtest_raw());
2784 if (err_vals
->value
->type_descr
==NULL
) TTCN_error(
2785 "internal error: erroneous value typedescriptor missing");
2786 new_tlv
->add_TLV(err_vals
->value
->errval
->BER_encode_TLV(
2787 *err_vals
->value
->type_descr
, p_coding
));
2791 if (!default_as_optional() && is_default_field
) {
2792 if (!get_at(i
)->is_equal(default_indexes
[next_default_idx
].value
)) {
2793 ec_1
.set_msg("'%s': ", fld_name(i
));
2795 new_tlv
->add_TLV(get_at(i
)->BER_encode_TLV_negtest(emb_descr
,
2796 *fld_descr(i
), p_coding
));
2798 new_tlv
->add_TLV(get_at(i
)->BER_encode_TLV(*fld_descr(i
), p_coding
));
2801 } else { /* is not DEFAULT */
2802 ec_1
.set_msg("'%s': ", fld_name(i
));
2804 new_tlv
->add_TLV(get_at(i
)->BER_encode_TLV_negtest(emb_descr
,
2805 *fld_descr(i
), p_coding
));
2807 new_tlv
->add_TLV(get_at(i
)->BER_encode_TLV(*fld_descr(i
), p_coding
));
2812 if (err_vals
&& err_vals
->after
) {
2813 if (err_vals
->after
->errval
==NULL
) TTCN_error(
2814 "internal error: erroneous after value missing");
2815 ec_1
.set_msg("%s'(erroneous after): ", fld_name(i
));
2816 if (err_vals
->after
->raw
) {
2817 new_tlv
->add_TLV(err_vals
->after
->errval
->BER_encode_negtest_raw());
2819 if (err_vals
->after
->type_descr
==NULL
) TTCN_error(
2820 "internal error: erroneous after typedescriptor missing");
2821 new_tlv
->add_TLV(err_vals
->after
->errval
->BER_encode_TLV(
2822 *err_vals
->after
->type_descr
, p_coding
));
2826 if (is_default_field
) next_default_idx
++;
2827 if ( (p_err_descr
->omit_after
!=-1) && (i
>=p_err_descr
->omit_after
) ) break;
2831 if (p_coding
==BER_ENCODE_DER
) new_tlv
->sort_tlvs_tag();
2832 new_tlv
=ASN_BER_V2TLV(new_tlv
, p_td
, p_coding
);
2836 boolean
Record_Type::BER_decode_TLV(const TTCN_Typedescriptor_t
& p_td
,
2837 const ASN_BER_TLV_t
& p_tlv
, unsigned L_form
)
2840 BER_chk_descr(p_td
);
2841 ASN_BER_TLV_t stripped_tlv
;
2842 BER_decode_strip_tags(*p_td
.ber
, p_tlv
, L_form
, stripped_tlv
);
2843 TTCN_EncDec_ErrorContext
ec_0("While decoding '%s' type: ", get_descriptor()->name
);
2844 stripped_tlv
.chk_constructed_flag(TRUE
);
2846 ASN_BER_TLV_t tmp_tlv
;
2848 { /* SEQUENCE decoding */
2849 boolean tlv_present
=FALSE
;
2851 TTCN_EncDec_ErrorContext
ec_1("Component '");
2852 TTCN_EncDec_ErrorContext ec_2
;
2853 int next_default_idx
= 0;
2854 int next_optional_idx
= 0;
2855 const default_struct
* default_indexes
= get_default_indexes();
2856 const int* optional_indexes
= get_optional_indexes();
2857 int field_cnt
= get_count();
2858 for(int i
=0; i
<field_cnt
; i
++) {
2859 boolean is_default_field
= default_indexes
&& (default_indexes
[next_default_idx
].index
==i
);
2860 boolean is_optional_field
= optional_indexes
&& (optional_indexes
[next_optional_idx
]==i
);
2861 ec_2
.set_msg("%s': ", fld_descr(i
)->name
);
2862 if (!tlv_present
) tlv_present
=BER_decode_constdTLV_next(stripped_tlv
, V_pos
, L_form
, tmp_tlv
);
2863 if (is_default_field
) { /* is DEFAULT */
2864 if (!tlv_present
|| !get_at(i
)->BER_decode_isMyMsg(*fld_descr(i
), tmp_tlv
)) {
2865 get_at(i
)->set_value(default_indexes
[next_default_idx
].value
);
2867 get_at(i
)->BER_decode_TLV(*fld_descr(i
), tmp_tlv
, L_form
);
2871 else if (is_optional_field
) { /* is OPTIONAL */
2872 if (!tlv_present
) get_at(i
)->set_to_omit();
2874 get_at(i
)->BER_decode_TLV(*fld_descr(i
), tmp_tlv
, L_form
);
2875 if (get_at(i
)->ispresent()) tlv_present
=FALSE
;
2878 else { /* is not DEFAULT OPTIONAL */
2880 ec_2
.error(TTCN_EncDec::ET_INCOMPL_MSG
,"Invalid or incomplete message was received.");
2883 get_at(i
)->BER_decode_TLV(*fld_descr(i
), tmp_tlv
, L_form
);
2886 if (is_default_field
) next_default_idx
++;
2887 if (is_optional_field
) next_optional_idx
++;
2890 BER_decode_constdTLV_end(stripped_tlv
, V_pos
, L_form
, tmp_tlv
, tlv_present
);
2891 } /* SEQUENCE decoding */
2893 { /* SET decoding */
2895 * 0x01: value arrived
2896 * 0x02: is optional / not used :)
2897 * 0x04: has default / not used :)
2899 int field_cnt
= get_count();
2900 unsigned char* fld_indctr
= new unsigned char[field_cnt
];
2901 for (int i
=0; i
<field_cnt
; i
++) fld_indctr
[i
] = 0;
2902 int fld_curr
= -1; /* ellipsis or error... */
2903 while (BER_decode_constdTLV_next(stripped_tlv
, V_pos
, L_form
, tmp_tlv
)) {
2904 for (int i
=0; i
<field_cnt
; i
++) {
2905 if (get_at(i
)->BER_decode_isMyMsg(*fld_descr(i
), tmp_tlv
)) {
2907 TTCN_EncDec_ErrorContext
ec_1("Component '%s': ", fld_name(i
));
2908 get_at(i
)->BER_decode_TLV(*fld_descr(i
), tmp_tlv
, L_form
);
2913 if (fld_indctr
[fld_curr
])
2914 ec_0
.error(TTCN_EncDec::ET_DEC_DUPFLD
, "Duplicated value for component '%s'.", fld_name(fld_curr
));
2915 fld_indctr
[fld_curr
]=1;
2918 int next_default_idx
= 0;
2919 int next_optional_idx
= 0;
2920 const default_struct
* default_indexes
= get_default_indexes();
2921 const int* optional_indexes
= get_optional_indexes();
2922 for (fld_curr
=0; fld_curr
<field_cnt
; fld_curr
++) {
2923 boolean is_default_field
= default_indexes
&& (default_indexes
[next_default_idx
].index
==fld_curr
);
2924 boolean is_optional_field
= optional_indexes
&& (optional_indexes
[next_optional_idx
]==fld_curr
);
2925 if (!fld_indctr
[fld_curr
]) {
2926 if (is_default_field
) get_at(fld_curr
)->set_value(default_indexes
[next_default_idx
].value
);
2927 else if (is_optional_field
) get_at(fld_curr
)->set_to_omit();
2928 else ec_0
.error(TTCN_EncDec::ET_DEC_MISSFLD
, "Missing value for component '%s'.", fld_name(fld_curr
));
2930 if (is_default_field
) next_default_idx
++;
2931 if (is_optional_field
) next_optional_idx
++;
2933 delete[] fld_indctr
;
2934 } /* SET decoding */
2936 if (is_opentype_outermost()) {
2937 TTCN_EncDec_ErrorContext
ec_1("While decoding opentypes: ");
2938 TTCN_Type_list p_typelist
;
2939 BER_decode_opentypes(p_typelist
, L_form
);
2940 } /* if sdef->opentype_outermost */
2944 void Record_Type::BER_decode_opentypes(TTCN_Type_list
& p_typelist
, unsigned L_form
)
2947 p_typelist
.push(this);
2948 TTCN_EncDec_ErrorContext
ec_0("Component '");
2949 TTCN_EncDec_ErrorContext ec_1
;
2950 int field_cnt
= get_count();
2951 for(int i
=0; i
<field_cnt
; i
++) {
2952 ec_1
.set_msg("%s': ", fld_name(i
));
2953 get_at(i
)->BER_decode_opentypes(p_typelist
, L_form
);
2958 int Record_Type::RAW_encode(const TTCN_Typedescriptor_t
& p_td
,
2959 RAW_enc_tree
& myleaf
) const
2961 if (err_descr
) return RAW_encode_negtest(err_descr
, p_td
, myleaf
);
2963 TTCN_EncDec_ErrorContext::error
2964 (TTCN_EncDec::ET_UNBOUND
, "Encoding an unbound value.");
2966 int encoded_length
= 0;
2967 int field_cnt
= get_count();
2968 myleaf
.isleaf
= false;
2969 myleaf
.body
.node
.num_of_nodes
= field_cnt
;
2970 myleaf
.body
.node
.nodes
= init_nodes_of_enc_tree(field_cnt
);
2972 int next_optional_idx
= 0;
2973 const int* optional_indexes
= get_optional_indexes();
2974 for (int i
= 0; i
< field_cnt
; i
++) {
2975 boolean is_optional_field
= optional_indexes
2976 && (optional_indexes
[next_optional_idx
] == i
);
2977 if (!is_optional_field
|| get_at(i
)->ispresent()) {
2978 myleaf
.body
.node
.nodes
[i
] = new RAW_enc_tree(true, &myleaf
,
2979 &(myleaf
.curr_pos
), i
, fld_descr(i
)->raw
);
2982 myleaf
.body
.node
.nodes
[i
] = NULL
;
2984 if (is_optional_field
) next_optional_idx
++;
2986 next_optional_idx
= 0;
2987 for (int i
= 0; i
< field_cnt
; i
++) { /*encoding fields*/
2988 boolean is_optional_field
= optional_indexes
2989 && (optional_indexes
[next_optional_idx
] == i
);
2990 /* encoding of normal fields*/
2991 const Base_Type
*field
= get_at(i
);
2992 if (is_optional_field
) {
2993 next_optional_idx
++;
2994 if (!field
->ispresent())
2995 continue; // do not encode
2997 field
= field
->get_opt_value(); // "reach into" the optional
2999 encoded_length
+= field
->RAW_encode(*fld_descr(i
),
3000 *myleaf
.body
.node
.nodes
[i
]);
3002 return myleaf
.length
= encoded_length
;
3005 // In some cases (e.g. LENGTHTO, POINTERTO, CROSSTAG) it is not generated.
3006 int Record_Type::RAW_encode_negtest(const Erroneous_descriptor_t
*p_err_descr
,
3007 const TTCN_Typedescriptor_t
& /*p_td*/, RAW_enc_tree
& myleaf
) const
3010 TTCN_EncDec_ErrorContext::error
3011 (TTCN_EncDec::ET_UNBOUND
, "Encoding an unbound value.");
3013 int encoded_length
= 0;
3014 int num_fields
= get_count();
3015 myleaf
.isleaf
= false;
3016 myleaf
.body
.node
.num_of_nodes
= 0;
3017 for (int field_idx
= 0; field_idx
< num_fields
; ++field_idx
) {
3018 if ((p_err_descr
->omit_before
!= -1) &&
3019 (field_idx
< p_err_descr
->omit_before
))
3021 else ++myleaf
.body
.node
.num_of_nodes
;
3022 const Erroneous_values_t
*err_vals
= p_err_descr
->get_field_err_values(field_idx
);
3023 if (err_vals
&& err_vals
->before
)
3024 ++myleaf
.body
.node
.num_of_nodes
;
3025 if (err_vals
&& err_vals
->value
&& !err_vals
->value
->errval
)
3026 --myleaf
.body
.node
.num_of_nodes
;
3027 if (err_vals
&& err_vals
->after
)
3028 ++myleaf
.body
.node
.num_of_nodes
;
3029 if ((p_err_descr
->omit_after
!= -1) &&
3030 (field_idx
>= p_err_descr
->omit_after
))
3033 myleaf
.body
.node
.nodes
= init_nodes_of_enc_tree(myleaf
.body
.node
.num_of_nodes
);
3034 TTCN_EncDec_ErrorContext ec
;
3035 int next_optional_idx
= 0;
3036 const int *my_optional_indexes
= get_optional_indexes();
3037 // Counter for fields and additional before/after fields.
3039 for (int field_idx
= 0; field_idx
< num_fields
; ++field_idx
) {
3040 boolean is_optional_field
= my_optional_indexes
&&
3041 (my_optional_indexes
[next_optional_idx
] == field_idx
);
3042 if ((p_err_descr
->omit_before
!= -1) &&
3043 (field_idx
< p_err_descr
->omit_before
)) {
3044 if (is_optional_field
) ++next_optional_idx
;
3047 const Erroneous_values_t
*err_vals
= p_err_descr
->get_field_err_values(field_idx
);
3048 const Erroneous_descriptor_t
*emb_descr
= p_err_descr
->get_field_emb_descr(field_idx
);
3049 if (err_vals
&& err_vals
->before
) {
3050 if (err_vals
->before
->errval
== NULL
)
3051 TTCN_error("internal error: erroneous before value missing");
3052 if (err_vals
->before
->raw
) {
3053 myleaf
.body
.node
.nodes
[node_pos
] =
3054 new RAW_enc_tree(true, &myleaf
, &(myleaf
.curr_pos
), node_pos
,
3055 err_vals
->before
->errval
->get_descriptor()->raw
);
3056 encoded_length
+= err_vals
->before
->errval
->
3057 RAW_encode_negtest_raw(*myleaf
.body
.node
.nodes
[node_pos
++]);
3059 if (err_vals
->before
->type_descr
== NULL
)
3060 TTCN_error("internal error: erroneous before typedescriptor missing");
3061 myleaf
.body
.node
.nodes
[node_pos
] =
3062 new RAW_enc_tree(true, &myleaf
, &(myleaf
.curr_pos
), node_pos
,
3063 err_vals
->before
->type_descr
->raw
);
3064 encoded_length
+= err_vals
->before
->errval
->
3065 RAW_encode(*(err_vals
->before
->type_descr
),
3066 *myleaf
.body
.node
.nodes
[node_pos
++]);
3069 if (err_vals
&& err_vals
->value
) {
3070 if (err_vals
->value
->errval
) {
3071 ec
.set_msg("'%s'(erroneous value): ", fld_name(field_idx
));
3072 if (err_vals
->value
->raw
) {
3073 myleaf
.body
.node
.nodes
[node_pos
] =
3074 new RAW_enc_tree(true, &myleaf
, &(myleaf
.curr_pos
), node_pos
,
3075 err_vals
->value
->errval
->get_descriptor()->raw
);
3076 encoded_length
+= err_vals
->value
->errval
->
3077 RAW_encode_negtest_raw(*myleaf
.body
.node
.nodes
[node_pos
++]);
3079 if (err_vals
->value
->type_descr
== NULL
)
3080 TTCN_error("internal error: erroneous value typedescriptor missing");
3081 myleaf
.body
.node
.nodes
[node_pos
] =
3082 new RAW_enc_tree(true, &myleaf
, &(myleaf
.curr_pos
), node_pos
,
3083 err_vals
->value
->type_descr
->raw
);
3084 encoded_length
+= err_vals
->value
->errval
->
3085 RAW_encode(*(err_vals
->value
->type_descr
),
3086 *myleaf
.body
.node
.nodes
[node_pos
++]);
3090 ec
.set_msg("'%s': ", fld_name(field_idx
));
3091 if (!is_optional_field
|| get_at(field_idx
)->ispresent()) {
3092 const Base_Type
*field
=
3093 is_optional_field
? get_at(field_idx
)->get_opt_value()
3094 : get_at(field_idx
);
3095 myleaf
.body
.node
.nodes
[node_pos
] =
3096 new RAW_enc_tree(true, &myleaf
, &(myleaf
.curr_pos
), node_pos
,
3097 fld_descr(field_idx
)->raw
);
3100 field
->RAW_encode_negtest(emb_descr
, *fld_descr(field_idx
),
3101 *myleaf
.body
.node
.nodes
[node_pos
++]);
3104 field
->RAW_encode(*fld_descr(field_idx
),
3105 *myleaf
.body
.node
.nodes
[node_pos
++]);
3109 myleaf
.body
.node
.nodes
[node_pos
++] = NULL
;
3112 if (err_vals
&& err_vals
->after
) {
3113 if (err_vals
->after
->errval
== NULL
)
3114 TTCN_error("internal error: erroneous before value missing");
3115 if (err_vals
->after
->raw
) {
3116 myleaf
.body
.node
.nodes
[node_pos
] =
3117 new RAW_enc_tree(true, &myleaf
, &(myleaf
.curr_pos
), node_pos
,
3118 err_vals
->after
->errval
->get_descriptor()->raw
);
3119 encoded_length
+= err_vals
->after
->errval
->
3120 RAW_encode_negtest_raw(*myleaf
.body
.node
.nodes
[node_pos
++]);
3122 if (err_vals
->after
->type_descr
== NULL
)
3123 TTCN_error("internal error: erroneous after typedescriptor missing");
3124 myleaf
.body
.node
.nodes
[node_pos
] =
3125 new RAW_enc_tree(true, &myleaf
, &(myleaf
.curr_pos
), node_pos
,
3126 err_vals
->after
->type_descr
->raw
);
3127 encoded_length
+= err_vals
->after
->errval
->
3128 RAW_encode(*(err_vals
->after
->type_descr
),
3129 *myleaf
.body
.node
.nodes
[node_pos
++]);
3132 if (is_optional_field
) ++next_optional_idx
;
3133 if ((p_err_descr
->omit_after
!= -1) &&
3134 (field_idx
>= p_err_descr
->omit_after
))
3137 return myleaf
.length
= encoded_length
;
3140 int Record_Type::RAW_decode(const TTCN_Typedescriptor_t
& p_td
, TTCN_Buffer
& buff
,
3141 int limit
, raw_order_t top_bit_ord
, boolean no_err
, int, boolean
)
3144 int field_cnt
= get_count();
3145 int opt_cnt
= optional_count();
3146 int mand_num
= field_cnt
- opt_cnt
; // expected mandatory fields
3148 raw_order_t local_top_order
;
3149 if (p_td
.raw
->top_bit_order
== TOP_BIT_INHERITED
) local_top_order
= top_bit_ord
;
3150 else if (p_td
.raw
->top_bit_order
== TOP_BIT_RIGHT
) local_top_order
= ORDER_MSB
;
3151 else local_top_order
= ORDER_LSB
;
3153 if (is_set()) { /* set decoder start*/
3154 int prepaddlength
= buff
.increase_pos_padd(p_td
.raw
->prepadding
);
3155 limit
-= prepaddlength
;
3156 int decoded_length
= 0;
3157 int * const field_map
= new int[field_cnt
];
3158 memset(field_map
, 0, field_cnt
* sizeof(int));
3159 int nof_mand_fields
= 0; // mandatory fields actually decoded
3161 const int* optional_indexes
= get_optional_indexes();
3162 for (int i
=0; i
<opt_cnt
; i
++) get_at(optional_indexes
[i
])->set_to_omit();
3165 size_t fl_start_pos
= buff
.get_pos_bit();
3166 int next_optional_idx
= 0;
3167 const int* optional_indexes
= get_optional_indexes();
3168 for (int i
=0; i
<field_cnt
; i
++) { /* decoding fields without TAG */
3169 boolean is_optional_field
= optional_indexes
&& (optional_indexes
[next_optional_idx
]==i
);
3170 if (field_map
[i
] == 0) {
3171 Base_Type
* field_ptr
= get_at(i
);
3172 if (is_optional_field
) {
3173 field_ptr
->set_to_present();
3174 field_ptr
=field_ptr
->get_opt_value();
3176 int decoded_field_length
= field_ptr
->RAW_decode(*fld_descr(i
), buff
,
3177 limit
, local_top_order
, TRUE
);
3178 if ( (is_optional_field
&& (decoded_field_length
>0)) ||
3179 (!is_optional_field
&& (decoded_field_length
>=0)) ) {
3180 decoded_length
+= decoded_field_length
;
3181 limit
-= decoded_field_length
;
3182 if (!is_optional_field
) nof_mand_fields
++;
3184 goto continue_while
;
3186 buff
.set_pos_bit(fl_start_pos
);
3187 if (is_optional_field
) get_at(i
)->set_to_omit();
3190 if (is_optional_field
) next_optional_idx
++;
3192 break; // no field could be decoded successfully, quit
3196 if (mand_num
> 0 && nof_mand_fields
!= mand_num
) {
3197 /* Not all required fields were decoded. If there are no bits left,
3198 * that means that the last field was decoded successfully but used up
3199 * the buffer. Signal "incomplete". If there were bits left, that means
3200 * no field could be decoded from them; signal an error. */
3201 return limit
? -1 : -TTCN_EncDec::ET_INCOMPL_MSG
;
3203 return decoded_length
+ prepaddlength
+ buff
.increase_pos_padd(p_td
.raw
->padding
);
3204 } else { /* record decoder start */
3205 int prepaddlength
= buff
.increase_pos_padd(p_td
.raw
->prepadding
);
3206 limit
-= prepaddlength
;
3207 size_t last_decoded_pos
= buff
.get_pos_bit();
3208 size_t fl_start_pos
;
3209 int decoded_length
= 0;
3210 int decoded_field_length
= 0;
3211 if (raw_has_ext_bit()) {
3212 const unsigned char* data
=buff
.get_read_data();
3214 unsigned mask
= 1 << (local_top_order
==ORDER_LSB
? 0 : 7);
3215 if (p_td
.raw
->extension_bit
==EXT_BIT_YES
) {
3216 while((data
[count
-1] & mask
) == 0 && count
* 8 < (int)limit
) count
++;
3219 while((data
[count
-1] & mask
) != 0 && count
* 8 < (int)limit
) count
++;
3221 if(limit
) limit
=count
*8;
3224 int next_optional_idx
= 0;
3225 const int* optional_indexes
= get_optional_indexes();
3226 for (int i
=0; i
<field_cnt
; i
++) { /* decoding fields */
3227 boolean is_optional_field
= optional_indexes
&& (optional_indexes
[next_optional_idx
]==i
);
3228 /* check if enough bits to decode the field*/
3229 if (!is_optional_field
|| (limit
>0)) {
3230 /* decoding of normal field */
3231 fl_start_pos
= buff
.get_pos_bit();
3232 Base_Type
* field_ptr
= get_at(i
);
3233 if (is_optional_field
) {
3234 field_ptr
->set_to_present();
3235 field_ptr
=field_ptr
->get_opt_value();
3237 decoded_field_length
= field_ptr
->RAW_decode(*fld_descr(i
), buff
, limit
,
3238 local_top_order
, is_optional_field
? TRUE
: no_err
);
3239 boolean field_present
= TRUE
;
3240 if (is_optional_field
) {
3241 if (decoded_field_length
< 1) { // swallow any error and become omit
3242 field_present
= FALSE
;
3243 get_at(i
)->set_to_omit();
3244 buff
.set_pos_bit(fl_start_pos
);
3247 if (decoded_field_length
< 0) return decoded_field_length
;
3249 if (field_present
) {
3250 decoded_length
+=decoded_field_length
;
3251 limit
-=decoded_field_length
;
3252 last_decoded_pos
=last_decoded_pos
<buff
.get_pos_bit()?buff
.get_pos_bit():last_decoded_pos
;
3255 get_at(i
)->set_to_omit();
3257 if (is_optional_field
) next_optional_idx
++;
3258 } /* decoding fields*/
3260 buff
.set_pos_bit(last_decoded_pos
);
3261 return decoded_length
+prepaddlength
+buff
.increase_pos_padd(p_td
.raw
->padding
);
3262 } /* record decoder end*/
3265 int Record_Type::TEXT_encode(const TTCN_Typedescriptor_t
& p_td
, TTCN_Buffer
& buff
) const
3268 return TEXT_encode_negtest(err_descr
, p_td
, buff
);
3271 TTCN_EncDec_ErrorContext::error
3272 (TTCN_EncDec::ET_UNBOUND
, "Encoding an unbound value.");
3274 bool need_separator
=false;
3275 int encoded_length
=0;
3276 if (p_td
.text
->begin_encode
) {
3277 buff
.put_cs(*p_td
.text
->begin_encode
);
3278 encoded_length
+=p_td
.text
->begin_encode
->lengthof();
3280 int next_optional_idx
= 0;
3281 const int* optional_indexes
= get_optional_indexes();
3282 int field_cnt
= get_count();
3283 for(int i
=0;i
<field_cnt
;i
++) {
3284 boolean is_optional_field
= optional_indexes
&& (optional_indexes
[next_optional_idx
]==i
);
3285 if (!is_optional_field
|| get_at(i
)->ispresent()) {
3286 if (need_separator
&& p_td
.text
->separator_encode
) {
3287 buff
.put_cs(*p_td
.text
->separator_encode
);
3288 encoded_length
+=p_td
.text
->separator_encode
->lengthof();
3290 encoded_length
+= get_at(i
)->TEXT_encode(*fld_descr(i
),buff
);
3291 need_separator
=true;
3293 if (is_optional_field
) next_optional_idx
++;
3295 if (p_td
.text
->end_encode
) {
3296 buff
.put_cs(*p_td
.text
->end_encode
);
3297 encoded_length
+=p_td
.text
->end_encode
->lengthof();
3299 return encoded_length
;
3303 * TEXT encode negative testing
3305 int Record_Type::TEXT_encode_negtest(const Erroneous_descriptor_t
* p_err_descr
, const TTCN_Typedescriptor_t
& p_td
, TTCN_Buffer
& buff
) const
3308 TTCN_EncDec_ErrorContext::error
3309 (TTCN_EncDec::ET_UNBOUND
, "Encoding an unbound value.");
3311 bool need_separator
=false;
3312 int encoded_length
=0;
3313 if (p_td
.text
->begin_encode
) {
3314 buff
.put_cs(*p_td
.text
->begin_encode
);
3315 encoded_length
+=p_td
.text
->begin_encode
->lengthof();
3317 int next_optional_idx
= 0;
3318 const int* optional_indexes
= get_optional_indexes();
3319 int field_cnt
= get_count();
3324 for(int i
=0;i
<field_cnt
;i
++) {
3325 boolean is_optional_field
= optional_indexes
&& (optional_indexes
[next_optional_idx
]==i
);
3327 if ( (p_err_descr
->omit_before
!=-1) && (i
<p_err_descr
->omit_before
) ) {
3328 if (is_optional_field
) next_optional_idx
++;
3332 const Erroneous_values_t
* err_vals
= p_err_descr
->next_field_err_values(i
, values_idx
);
3333 const Erroneous_descriptor_t
* emb_descr
= p_err_descr
->next_field_emb_descr(i
, edescr_idx
);
3335 if (err_vals
&& err_vals
->before
) {
3336 if (err_vals
->before
->errval
==NULL
) TTCN_error(
3337 "internal error: erroneous before value missing");
3339 if (need_separator
&& p_td
.text
->separator_encode
) {
3340 buff
.put_cs(*p_td
.text
->separator_encode
);
3341 encoded_length
+=p_td
.text
->separator_encode
->lengthof();
3343 if (err_vals
->before
->raw
) {
3344 encoded_length
+= err_vals
->before
->errval
->encode_raw(buff
);
3346 if (err_vals
->before
->type_descr
==NULL
) TTCN_error(
3347 "internal error: erroneous before typedescriptor missing");
3348 encoded_length
+= err_vals
->before
->errval
->TEXT_encode(
3349 *(err_vals
->before
->type_descr
),buff
);
3351 need_separator
=true;
3354 if (err_vals
&& err_vals
->value
) {
3355 if (err_vals
->value
->errval
) {
3356 if (need_separator
&& p_td
.text
->separator_encode
) {
3357 buff
.put_cs(*p_td
.text
->separator_encode
);
3358 encoded_length
+=p_td
.text
->separator_encode
->lengthof();
3360 if (err_vals
->value
->raw
) {
3361 encoded_length
+= err_vals
->value
->errval
->encode_raw(buff
);
3363 if (err_vals
->value
->type_descr
==NULL
) TTCN_error(
3364 "internal error: erroneous value typedescriptor missing");
3365 encoded_length
+= err_vals
->value
->errval
->TEXT_encode(
3366 *(err_vals
->value
->type_descr
),buff
);
3368 need_separator
=true;
3371 if (!is_optional_field
|| get_at(i
)->ispresent()) {
3372 if (need_separator
&& p_td
.text
->separator_encode
) {
3373 buff
.put_cs(*p_td
.text
->separator_encode
);
3374 encoded_length
+=p_td
.text
->separator_encode
->lengthof();
3377 encoded_length
+= get_at(i
)->TEXT_encode_negtest(emb_descr
, *fld_descr(i
),buff
);
3379 encoded_length
+= get_at(i
)->TEXT_encode(*fld_descr(i
),buff
);
3381 need_separator
=true;
3385 if (err_vals
&& err_vals
->after
) {
3386 if (err_vals
->after
->errval
==NULL
) TTCN_error(
3387 "internal error: erroneous after value missing");
3388 if (need_separator
&& p_td
.text
->separator_encode
) {
3389 buff
.put_cs(*p_td
.text
->separator_encode
);
3390 encoded_length
+=p_td
.text
->separator_encode
->lengthof();
3392 if (err_vals
->after
->raw
) {
3393 encoded_length
+= err_vals
->after
->errval
->encode_raw(buff
);
3395 if (err_vals
->after
->type_descr
==NULL
) TTCN_error(
3396 "internal error: erroneous after typedescriptor missing");
3397 encoded_length
+= err_vals
->after
->errval
->TEXT_encode(
3398 *(err_vals
->after
->type_descr
),buff
);
3400 need_separator
=true;
3403 if (is_optional_field
) next_optional_idx
++;
3405 if ( (p_err_descr
->omit_after
!=-1) && (i
>=p_err_descr
->omit_after
) ) break;
3407 if (p_td
.text
->end_encode
) {
3408 buff
.put_cs(*p_td
.text
->end_encode
);
3409 encoded_length
+=p_td
.text
->end_encode
->lengthof();
3411 return encoded_length
;
3414 int Record_Type::TEXT_decode(const TTCN_Typedescriptor_t
& p_td
, TTCN_Buffer
& buff
,
3415 Limit_Token_List
& limit
, boolean no_err
, boolean
/*first_call*/)
3419 int decoded_length
=0;
3420 int decoded_field_length
=0;
3421 size_t pos
=buff
.get_pos();
3422 boolean sep_found
=FALSE
;
3425 int loop_detector
=1;
3426 int last_field_num
=-1;
3427 if (p_td
.text
->begin_decode
) {
3429 if ((tl
=p_td
.text
->begin_decode
->match_begin(buff
))<0) {
3430 if(no_err
) return -1;
3431 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR
,
3432 "The specified token '%s' not found for '%s': ",
3433 (const char*)*(p_td
.text
->begin_decode
), p_td
.name
);
3437 buff
.increase_pos(tl
);
3439 if (p_td
.text
->end_decode
) {
3440 limit
.add_token(p_td
.text
->end_decode
);
3443 if(p_td
.text
->separator_decode
){
3444 limit
.add_token(p_td
.text
->separator_decode
);
3448 int field_cnt
= get_count();
3449 int * const field_map
= new int[field_cnt
];
3450 memset(field_map
, 0, field_cnt
* sizeof(int));
3452 int mand_field_num
= 0;
3453 int opt_field_num
= 0;
3455 int has_repeatable
=0;
3456 boolean repeatable
= TRUE
;
3458 int next_optional_idx
= 0;
3459 const int* optional_indexes
= get_optional_indexes();
3460 for (int i
=0;i
<field_cnt
;i
++) {
3461 boolean is_optional_field
= optional_indexes
&& (optional_indexes
[next_optional_idx
]==i
);
3462 if (is_optional_field
) {
3463 get_at(i
)->set_to_omit();
3468 if (get_at(i
)->is_seof()) {
3470 repeatable
= repeatable
&& fld_descr(i
)->text
->val
.parameters
->decoding_params
.repeatable
;
3472 if (is_optional_field
) next_optional_idx
++;
3474 boolean has_optinals
= opt_field_num
> 0;
3475 if ((seof
>0) && repeatable
) has_repeatable
=1;
3477 while (mand_field_num
+opt_field_num
+has_repeatable
) {
3481 next_optional_idx
= 0;
3482 for (int i
=0;i
<field_cnt
;i
++) {
3483 boolean is_optional_field
= optional_indexes
&& (optional_indexes
[next_optional_idx
]==i
);
3484 if (get_at(i
)->is_seof()) {
3485 if ( (fld_descr(i
)->text
->val
.parameters
->decoding_params
.repeatable
&& field_map
[i
]<3)
3486 || !field_map
[i
] ) {
3488 decoded_field_length
= get_at(i
)->TEXT_decode(*fld_descr(i
),buff
, limit
, true,!field_map
[i
]);
3489 if (decoded_field_length
<0) {
3491 if (is_optional_field
&& !field_map
[i
]) get_at(i
)->set_to_omit();
3494 if (!field_map
[i
]) {
3495 if (is_optional_field
) opt_field_num
--;
3496 else mand_field_num
--;
3498 } else field_map
[i
]=2;
3503 } else { // !...->is_seof
3504 if (!field_map
[i
]) {
3506 decoded_field_length
= get_at(i
)->TEXT_decode(*fld_descr(i
),buff
,limit
,true);
3507 if (decoded_field_length
<0) {
3509 if (is_optional_field
) get_at(i
)->set_to_omit();
3513 if (is_optional_field
) opt_field_num
--;
3514 else mand_field_num
--;
3520 if (is_optional_field
) next_optional_idx
++;
3524 if (loop_detector
) break;
3525 if (p_td
.text
->separator_decode
) {
3527 if ((tl
=p_td
.text
->separator_decode
->match_begin(buff
))<0) {
3528 if (p_td
.text
->end_decode
) {
3530 if ((tl2
=p_td
.text
->end_decode
->match_begin(buff
))!=-1) {
3534 } else if (limit
.has_token(ml
)) {
3536 if ((tl2
=limit
.match(buff
,ml
))==0) {
3542 decoded_length
-=decoded_field_length
;
3543 field_map
[last_field_num
]+=2;
3546 if (last_field_num
>=0 && last_field_num
<field_cnt
) {
3547 if (get_at(last_field_num
)->is_seof()) {
3548 if (get_at(last_field_num
)->is_optional()) {
3549 if (field_map
[last_field_num
]==3) {
3550 get_at(last_field_num
)->set_to_omit();
3554 if (field_map
[last_field_num
]==3) {
3558 } else if (get_at(last_field_num
)->is_optional()) {
3559 get_at(last_field_num
)->set_to_omit();
3567 } // if (has_optinals)
3571 buff
.increase_pos(tl
);
3572 for (int a
=0;a
<field_cnt
;a
++) if(field_map
[a
]>2) field_map
[a
]-=3;
3575 } else if (p_td
.text
->end_decode
) {
3577 if ((tl
=p_td
.text
->end_decode
->match_begin(buff
))!=-1) {
3579 buff
.increase_pos(tl
);
3580 limit
.remove_tokens(ml
);
3581 if (mand_field_num
) decoded_length
= -1;
3584 } else if(limit
.has_token(ml
)){
3586 if ((tl
=limit
.match(buff
,ml
))==0) {
3592 limit
.remove_tokens(ml
);
3594 if (mand_field_num
) {
3595 if (no_err
) decoded_length
= -1;
3596 else TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR
,
3597 "Error during decoding '%s': ", p_td
.name
);
3600 decoded_length
-=sep_length
;
3601 buff
.set_pos(buff
.get_pos()-sep_length
);
3604 if (p_td
.text
->end_decode
) {
3606 if ((tl
=p_td
.text
->end_decode
->match_begin(buff
))<0) {
3607 if (no_err
) decoded_length
= -1;
3608 else TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR
,
3609 "The specified token '%s' not found for '%s': ",
3610 (const char*)*(p_td
.text
->end_decode
),p_td
.name
);
3614 buff
.increase_pos(tl
);
3616 if (mand_field_num
) decoded_length
= -1;
3619 return decoded_length
;
3620 } else { // record decoder
3621 int decoded_length
=0;
3622 int decoded_field_length
=0;
3623 size_t pos
=buff
.get_pos();
3624 boolean sep_found
=FALSE
;
3627 if (p_td
.text
->begin_decode
) {
3629 if ((tl
=p_td
.text
->begin_decode
->match_begin(buff
))<0) {
3630 if(no_err
)return -1;
3631 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR
,
3632 "The specified token '%s' not found for '%s': ",
3633 (const char*)*(p_td
.text
->begin_decode
), p_td
.name
);
3637 buff
.increase_pos(tl
);
3639 if (p_td
.text
->end_decode
) {
3640 limit
.add_token(p_td
.text
->end_decode
);
3643 if (p_td
.text
->separator_decode
) {
3644 limit
.add_token(p_td
.text
->separator_decode
);
3648 int mand_field_num
= 0;
3649 int opt_field_num
= 0;
3650 int last_man_index
= 0;
3652 int field_cnt
= get_count();
3653 int next_optional_idx
= 0;
3654 const int* optional_indexes
= get_optional_indexes();
3655 for (int i
=0;i
<field_cnt
;i
++) {
3656 boolean is_optional_field
= optional_indexes
&& (optional_indexes
[next_optional_idx
]==i
);
3657 if (is_optional_field
) {
3658 get_at(i
)->set_to_omit();
3664 if (is_optional_field
) next_optional_idx
++;
3667 next_optional_idx
= 0;
3668 for(int i
=0;i
<field_cnt
;i
++) {
3669 boolean is_optional_field
= optional_indexes
&& (optional_indexes
[next_optional_idx
]==i
);
3670 if (is_optional_field
) {
3673 decoded_field_length
= get_at(i
)->TEXT_decode(*fld_descr(i
),buff
,limit
,TRUE
);
3674 if (decoded_field_length
<0) {
3675 if (is_optional_field
) {
3676 get_at(i
)->set_to_omit();
3679 limit
.remove_tokens(ml
);
3680 if (no_err
) return -1;
3681 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR
,
3682 "Error during decoding field '%s' for '%s': ",
3683 fld_descr(i
)->name
, p_td
.name
);
3684 return decoded_length
;
3687 decoded_length
+=decoded_field_length
;
3688 if (last_man_index
>(i
+1)) {
3689 if (p_td
.text
->separator_decode
) {
3691 if ((tl
=p_td
.text
->separator_decode
->match_begin(buff
))<0) {
3692 if(is_optional_field
) {
3693 get_at(i
)->set_to_omit();
3695 decoded_length
-=decoded_field_length
;
3697 limit
.remove_tokens(ml
);
3698 if(no_err
)return -1;
3699 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR
,
3700 "The specified token '%s' not found for '%s': ",
3701 (const char*)*(p_td
.text
->separator_decode
),p_td
.name
);
3702 return decoded_length
;
3706 buff
.increase_pos(tl
);
3710 } else sep_found
=FALSE
;
3712 } else if (i
==(field_cnt
-1)) {
3715 if (p_td
.text
->separator_decode
) {
3717 if ((tl
=p_td
.text
->separator_decode
->match_begin(buff
))<0) {
3718 if (is_optional_field
) {
3719 if (p_td
.text
->end_decode
) {
3720 if ((tl
=p_td
.text
->end_decode
->match_begin(buff
))!=-1) {
3722 buff
.increase_pos(tl
);
3723 limit
.remove_tokens(ml
);
3724 return decoded_length
;
3726 } else if (limit
.has_token(ml
)) {
3727 if ((tl
=limit
.match(buff
,ml
))==0) {
3732 get_at(i
)->set_to_omit();
3734 decoded_length
-=decoded_field_length
;
3741 buff
.increase_pos(tl
);
3748 if (p_td
.text
->end_decode
) {
3749 if ((tl
=p_td
.text
->end_decode
->match_begin(buff
))!=-1) {
3751 buff
.increase_pos(tl
);
3752 limit
.remove_tokens(ml
);
3753 return decoded_length
;
3755 } else if (limit
.has_token(ml
)) {
3756 if ((tl
=limit
.match(buff
,ml
))==0) {
3764 if (is_optional_field
) next_optional_idx
++;
3766 limit
.remove_tokens(ml
);
3768 buff
.set_pos(buff
.get_pos()-sep_length
);
3769 decoded_length
-=sep_length
;
3771 if (p_td
.text
->end_decode
) {
3773 if ((tl
=p_td
.text
->end_decode
->match_begin(buff
))<0) {
3774 if(no_err
)return -1;
3775 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR
,
3776 "The specified token '%s' not found for '%s': ",
3777 (const char*)*(p_td
.text
->end_decode
),p_td
.name
);
3778 return decoded_length
;
3781 buff
.increase_pos(tl
);
3783 return decoded_length
;
3787 const XERdescriptor_t
* Record_Type::xer_descr(int /*field_index*/) const
3789 TTCN_error("Internal error: Record_Type::xer_descr() called.");
3793 char ** Record_Type::collect_ns(const XERdescriptor_t
& p_td
, size_t& num
, bool& def_ns
) const
3795 const int field_cnt
= get_count();
3796 // The USE-ORDER member is first, unless preempted by EMBED-VALUES
3797 const int uo_index
= ((p_td
.xer_bits
& EMBED_VALUES
) !=0);
3798 // Index of the first "normal" member (after E-V and U-O)
3799 const int start_at
= uo_index
+ ((p_td
.xer_bits
& USE_ORDER
) != 0);
3801 size_t num_collected
= 0;
3802 // First, our own namespace. Sets num_collected to 0 or 1.
3803 // If it throws, nothing was allocated.
3804 char **collected_ns
= Base_Type::collect_ns(p_td
, num_collected
, def_ns
);
3807 // If the nil attribute will be written, add the control namespace
3808 boolean nil_attribute
= (p_td
.xer_bits
& USE_NIL
)
3809 && !get_at(field_cnt
-1)->ispresent();
3811 if (nil_attribute
) {
3812 collected_ns
= (char**)Realloc(collected_ns
, sizeof(char*) * ++num_collected
);
3813 const namespace_t
*c_ns
= p_td
.my_module
->get_controlns();
3815 collected_ns
[num_collected
-1] = mprintf(" xmlns:%s='%s'", c_ns
->px
, c_ns
->ns
);
3818 // Collect namespace declarations from all components (recursively).
3819 // This is extremely nasty, but we can't prosecute you for that.
3820 // (Monty Python - Crunchy Frog sketch). This whole thing is O(n^3). Yuck.
3821 for (int a
= start_at
; a
< field_cnt
; ++a
) {
3823 bool def_ns_1
= false;
3824 char **new_namespaces
= get_at(a
)->collect_ns(*xer_descr(a
), num_new
, def_ns_1
);
3825 merge_ns(collected_ns
, num_collected
, new_namespaces
, num_new
);
3826 def_ns
= def_ns
|| def_ns_1
;
3827 // merge_ns freed new_namespaces
3831 // Probably a TC_Error thrown from the element's collect_ns(),
3832 // e.g. if encoding an unbound value.
3833 while (num_collected
> 0) Free(collected_ns
[--num_collected
]);
3838 num
= num_collected
;
3839 return collected_ns
;
3842 // FIXME some hashing should be implemented
3843 int Record_Type::get_index_byname(const char *name
, const char *uri
) const {
3844 int num_fields
= get_count();
3845 for (int i
= 0; i
< num_fields
; ++i
) {
3846 const XERdescriptor_t
& xer
= *xer_descr(i
);
3847 if (check_name(name
, xer
, TRUE
)
3848 && check_namespace(uri
, xer
)) return i
;
3853 int Record_Type::XER_encode(const XERdescriptor_t
& p_td
, TTCN_Buffer
& p_buf
,
3854 unsigned int flavor
, int indent
) const
3857 return XER_encode_negtest(err_descr
, p_td
, p_buf
, flavor
, indent
);
3860 TTCN_EncDec_ErrorContext::error
3861 (TTCN_EncDec::ET_UNBOUND
, "Encoding an unbound value.");
3864 TTCN_EncDec_ErrorContext
ec_0("Component '");
3865 TTCN_EncDec_ErrorContext ec_1
;
3866 int encoded_length
=(int)p_buf
.get_len(); // how much is already in the buffer
3868 int exer
= is_exer(flavor
);
3869 if (exer
&& (p_td
.xer_bits
& EMBED_VALUES
)) flavor
|= XER_CANONICAL
;
3870 const boolean indenting
= !is_canonical(flavor
);
3871 const int field_cnt
= get_count();
3872 const int num_attributes
= get_xer_num_attr();
3873 // The USE-ORDER member is first, unless preempted by EMBED-VALUES
3874 const int uo_index
= ((p_td
.xer_bits
& EMBED_VALUES
) !=0);
3875 // Index of the first "normal" member (after E-V and U-O)
3876 const int start_at
= uo_index
+ ((p_td
.xer_bits
& USE_ORDER
) != 0);
3877 const int first_nonattr
= start_at
+ num_attributes
;
3878 // start_tag_len is keeping track of how much was written at the end of the
3879 // start tag, i.e. the ">\n". This is used later to "back up" over it.
3880 int start_tag_len
= 1 + indenting
;
3881 // The EMBED-VALUES member, if applicable
3882 const Record_Of_Type
* const embed_values
= (p_td
.xer_bits
& EMBED_VALUES
)
3883 ? static_cast<const Record_Of_Type
*>(get_at(0)) : 0;
3884 // The USE-ORDER member, if applicable
3885 const Record_Of_Type
* const use_order
= (p_td
.xer_bits
& USE_ORDER
)
3886 ? static_cast<const Record_Of_Type
*>(get_at(uo_index
)) : 0;
3888 size_t num_collected
= 0; // we use this to compute delay_close
3889 char **collected_ns
= NULL
;
3890 bool def_ns
= false;
3892 if (indent
== 0) { // top-level type
3893 collected_ns
= collect_ns(p_td
, num_collected
, def_ns
);
3895 else if ((flavor
& DEF_NS_SQUASHED
) && p_td
.my_module
&& p_td
.ns_index
!= -1) {
3896 const namespace_t
* ns
= p_td
.my_module
->get_ns(p_td
.ns_index
);
3897 // The default namespace has been squashed.
3898 // If we are in the default namespace, restore it.
3899 if (*ns
->px
== '\0') {
3900 collected_ns
= Base_Type::collect_ns(p_td
, num_collected
, def_ns
);
3905 // The type's own tag is omitted if we're doing E-XER,
3906 // and it's not the top-level type (XML must have a root element)
3907 // and it's either UNTAGGED or got USE_NIL or USE_TYPE or USE_UNION.
3908 boolean omit_tag
= exer
&& (indent
> 0)
3909 && ( (p_td
.xer_bits
& (UNTAGGED
|XER_ATTRIBUTE
))
3910 || (flavor
& (USE_NIL
|USE_TYPE_ATTR
)));
3912 // If a default namespace is in effect (uri but no prefix) and the type
3913 // is unqualified, the default namespace must be canceled; otherwise
3914 // an XML tag without a ns prefix looks like it belongs to the def.namespace
3915 const boolean empty_ns_hack
= exer
&& !omit_tag
&& (indent
> 0)
3916 && (p_td
.xer_bits
& FORM_UNQUALIFIED
)
3917 && (flavor
& DEF_NS_PRESENT
);
3919 // delay_close=true if there is stuff before the '>' of the start tag
3920 // (prevents writing the '>' which is built into the name).
3921 // This can only happen for EXER: if there are attributes or namespaces,
3922 // or either USE-NIL or USE-QNAME is set.
3923 boolean delay_close
= exer
&& (num_attributes
3924 || empty_ns_hack
// counts as having a namespace
3925 || (num_collected
!= 0)
3926 || (p_td
.xer_bits
& (USE_NIL
|USE_QNAME
))
3927 || (flavor
& USE_NIL
));
3931 if (!omit_tag
) { /* write start tag */
3932 if (indenting
) do_indent(p_buf
, indent
);
3933 /* name looks like this: "tagname>\n"
3934 * lose the \n if : not indenting or (single untagged(*) or attributes (*)) AND exer
3935 * lose the > if attributes are present (*) AND exer
3938 if (exer
) write_ns_prefix(p_td
, p_buf
);
3939 p_buf
.put_s((size_t)p_td
.namelens
[exer
] - delay_close
3940 - (!indenting
|| delay_close
|| (exer
&& (p_td
.xer_bits
& HAS_1UNTAGGED
))),
3941 (cbyte
*)p_td
.names
[exer
]);
3943 else if (flavor
& USE_TYPE_ATTR
) {
3944 // reopen the parent's start tag by overwriting the '>'
3945 size_t buf_len
= p_buf
.get_len();
3946 const unsigned char * const buf_data
= p_buf
.get_data();
3947 if (buf_data
[buf_len
- 1 - shorter
] == '\n') ++shorter
;
3948 if (buf_data
[buf_len
- 1 - shorter
] == '>' ) ++shorter
;
3951 p_buf
.increase_length(-shorter
);
3957 // mask out extra flags we received, do not send them to the fields
3960 if (exer
&& (p_td
.xer_bits
& USE_QNAME
)) { // QName trumps everything
3961 const Base_Type
* const q_uri
= get_at(0);
3962 if (q_uri
->is_present()) {
3963 p_buf
.put_s(11, (cbyte
*)" xmlns:b0='");
3964 q_uri
->XER_encode(*xer_descr(0), p_buf
, flavor
| XER_LIST
, indent
+1);
3968 if (p_td
.xer_bits
& XER_ATTRIBUTE
) begin_attribute(p_td
, p_buf
);
3969 else p_buf
.put_c('>');
3971 if (q_uri
->is_present()) {
3972 p_buf
.put_s(3, (cbyte
*)"b0:");
3975 const Base_Type
* const q_name
= get_at(1);
3976 sub_len
+= q_name
->XER_encode(*xer_descr(1), p_buf
, flavor
| XER_LIST
, indent
+1);
3977 if (p_td
.xer_bits
& XER_ATTRIBUTE
) p_buf
.put_c('\'');
3979 else { // not USE-QNAME
3980 if (!exer
&& (p_td
.xer_bits
& EMBED_VALUES
)) {
3981 // The EMBED-VALUES member as an ordinary record of string
3982 sub_len
+= embed_values
->XER_encode(*xer_descr(0), p_buf
, flavor
, indent
+1);
3985 if (!exer
&& (p_td
.xer_bits
& USE_ORDER
)) {
3986 // The USE-ORDER member as an ordinary record of enumerated
3987 sub_len
+= use_order
->XER_encode(*xer_descr(uo_index
), p_buf
, flavor
, indent
+1);
3990 if (exer
&& (indent
==0 || (flavor
& DEF_NS_SQUASHED
))) // write namespaces for toplevel only
3992 for (size_t cur_coll
= 0; cur_coll
< num_collected
; ++cur_coll
) {
3993 p_buf
.put_s(strlen(collected_ns
[cur_coll
]), (cbyte
*)collected_ns
[cur_coll
]);
3994 Free(collected_ns
[cur_coll
]); // job done
4000 flavor
&= ~DEF_NS_SQUASHED
;
4001 flavor
|= DEF_NS_PRESENT
;
4003 else if (empty_ns_hack
) {
4004 p_buf
.put_s(9, (cbyte
*)" xmlns=''");
4005 flavor
&= ~DEF_NS_PRESENT
;
4006 flavor
|= DEF_NS_SQUASHED
;
4009 /* First all the attributes (not added to sub_len) */
4011 for (i
= start_at
; i
< first_nonattr
; ++i
) {
4012 boolean is_xer_attr_field
= xer_descr(i
)->xer_bits
& XER_ATTRIBUTE
;
4013 ec_1
.set_msg("%s': ", fld_name(i
)); // attr
4014 int tmp_len
= get_at(i
)->XER_encode(*xer_descr(i
), p_buf
, flavor
, indent
+1);
4015 if (is_xer_attr_field
&& !exer
) sub_len
+= tmp_len
; /* do not add if attribute and EXER */
4018 // True if the "nil" attribute needs to be written.
4019 boolean nil_attribute
= exer
&& (p_td
.xer_bits
& USE_NIL
)
4020 && !get_at(field_cnt
-1)->ispresent();
4022 // True if USE_ORDER is in effect and the "nil" attribute was written.
4023 // Then the record-of-enum for USE-ORDER will be empty.
4024 boolean early_to_bed
= FALSE
;
4026 if (nil_attribute
) { // req. exer and USE_NIL
4027 const namespace_t
*control_ns
= p_td
.my_module
->get_controlns();
4029 p_buf
.put_s(strlen(control_ns
->px
),
4030 (cbyte
*)control_ns
->px
);
4032 p_buf
.put_s(10, (cbyte
*)"nil='true'");
4033 if ((p_td
.xer_bits
& USE_ORDER
)) early_to_bed
= TRUE
;
4034 // The whole content was omitted; nothing to do (and if we tried
4035 // to do it, we'd get an error for over-indexing a 0-length record-of).
4038 if (delay_close
&& (!omit_tag
|| shorter
)) {
4039 // Close the start tag left open. If indenting, also write a newline
4040 // unless USE-NIL in effect or there is a single untagged component.
4042 ((p_td
.xer_bits
& (/*USE_NIL|*/HAS_1UNTAGGED
)) ? 0 : indenting
);
4043 p_buf
.put_s(start_tag_len
, (cbyte
*)">\n");
4046 int expected_embed
= (field_cnt
- first_nonattr
+ 1);
4047 if (exer
&& (p_td
.xer_bits
& EMBED_VALUES
)) {
4048 ec_1
.set_msg("%s': ", fld_name(0));
4050 if ((p_td
.xer_bits
& USE_NIL
) && !get_at(field_cnt
-1)->ispresent()) {
4051 expected_embed
= 0; //25.2.6 a
4053 else if ((num_opt
= optional_count())) {
4054 const int * optionals
= get_optional_indexes();
4055 for (int opt_idx
= 0; opt_idx
< num_opt
; ++opt_idx
) {
4056 // skip optional attributes
4057 if (optionals
[opt_idx
] < start_at
+ num_attributes
) continue;
4058 // reduce for each omitted member
4059 if (!get_at(optionals
[opt_idx
])->is_present()) --expected_embed
;
4062 // Check the correct number of EMBED-VALUES (regular non-attributes + 1)
4063 if (embed_values
->size_of() != expected_embed
)
4064 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_CONSTRAINT
,
4065 "Wrong number %d of EMBED-VALUEs, expected %d",
4066 embed_values
->size_of(), expected_embed
);
4067 /* write the first string */
4068 if (expected_embed
> 0) {
4069 sub_len
+= embed_values
->get_at(0)->XER_encode(UNIVERSAL_CHARSTRING_xer_
,
4070 p_buf
, flavor
| EMBED_VALUES
, indent
+1);
4074 const Record_Type
*ordered
= this; // the record affected by USE-ORDER
4076 // Index of the first non-attribute field of the record pointed to by
4077 // ordered, that is, the first field affected by USE-ORDER.
4078 size_t useorder_base
= first_nonattr
;
4081 int end
= field_cnt
;
4082 if (exer
&& (p_td
.xer_bits
& USE_ORDER
)) {
4083 const int to_send
= use_order
->size_of();
4084 // the length of the loop is determined by the length of use_order
4088 // Count the non-attribute optionals
4089 int n_optionals
= 0;
4090 for (int B
= optional_count() - 1; B
>=+0; B
--) {
4091 int oi
= get_optional_indexes()[B
];
4092 if (oi
< first_nonattr
) break;
4096 int expected_min
= field_cnt
- first_nonattr
- n_optionals
;
4097 int expected_max
= field_cnt
- first_nonattr
;
4100 if ((p_td
.xer_bits
& USE_NIL
) && get_at(field_cnt
-1)->ispresent()) {
4101 // The special case when USE_ORDER refers to the fields of a field,
4103 const Base_Type
*last_optional
= get_at(field_cnt
-1);
4104 const Base_Type
* inner
= last_optional
->get_opt_value();
4105 // it absolutely, positively has to be (derived from) Record_Type
4106 ordered
= static_cast<const Record_Type
*>(inner
);
4107 useorder_base
= ordered
->get_xer_num_attr();
4108 begin
= useorder_base
;
4109 end
= ordered
->get_count();
4111 expected_min
= expected_max
= ordered
->get_count();
4114 if (to_send
> expected_max
4115 ||to_send
< expected_min
) {
4116 ec_1
.set_msg("%s': ", fld_name(uo_index
));
4117 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_CONSTRAINT
,
4118 "Wrong number of USE-ORDER %d, must be %d..%d", to_send
, expected_min
, expected_max
);
4119 begin
= end
= 0; // don't bother sending anything
4121 else { // check no duplicates
4122 int *seen
= new int [to_send
];
4124 for (int ei
= 0; ei
< to_send
; ++ei
) {
4125 const Base_Type
*uoe
= use_order
->get_at(ei
);
4126 const Enum_Type
*enm
= static_cast<const Enum_Type
*>(uoe
);
4127 int val
= enm
->as_int();
4128 for (int x
= 0; x
< num_seen
; ++x
) {
4129 if (val
== seen
[x
]) { // complain
4130 ec_1
.set_msg("%s': ", fld_name(uo_index
));
4131 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_CONSTRAINT
,
4132 "Duplicate value for USE-ORDER");
4133 begin
= end
= 0; // don't bother sending anything
4137 seen
[num_seen
++] = val
;
4141 // If the number is right and there are no duplicates, then carry on
4145 /* Then, all the non-attributes. Structuring the code like this depends on
4146 * all attributes appearing before all non-attributes (excluding
4147 * pseudo-members for USE-ORDER, etc.) */
4149 // early_to_bed can only be true if exer is true (transitive through nil_attribute)
4150 if (!early_to_bed
) for ( i
= begin
; i
< end
; ++i
) {
4151 const Base_Type
*uoe
= 0; // "useOrder enum"
4152 const Enum_Type
*enm
= 0; // the enum value selecting the field
4153 if (exer
&& use_order
) {
4154 uoe
= use_order
->get_at(i
- begin
);
4155 enm
= static_cast<const Enum_Type
*>(uoe
);
4158 // "actual" index, may be perturbed by USE-ORDER
4159 int ai
= !(exer
&& (p_td
.xer_bits
& USE_ORDER
)) ? i
:
4160 enm
->as_int() + useorder_base
;
4161 ec_1
.set_msg("%s': ", ordered
->fld_name(ai
)); // non-attr
4163 const XERdescriptor_t
& descr
= *ordered
->xer_descr(ai
);
4164 sub_len
+= ordered
->get_at(ai
)->XER_encode(descr
, p_buf
,
4165 // Pass USE-NIL to the last field (except when USE-ORDER is also in effect,
4166 // because the tag-stripping effect of USE-NIL has been achieved
4167 // by encoding the sub-fields directly).
4168 flavor
| ((exer
&& !use_order
&& (i
== field_cnt
-1)) ? (p_td
.xer_bits
& USE_NIL
) : 0),
4171 // Now the next embed-values string (NOT affected by USE-ORDER!)
4172 if (exer
&& (p_td
.xer_bits
& EMBED_VALUES
) && (i
- begin
+ 1) < expected_embed
) {
4173 embed_values
->get_at(i
- begin
+ 1)->XER_encode(UNIVERSAL_CHARSTRING_xer_
4174 , p_buf
, flavor
| EMBED_VALUES
, indent
+1);
4180 if (sub_len
) { // something was written, now an end tag
4181 if (indenting
&& !(exer
&& (p_td
.xer_bits
& (HAS_1UNTAGGED
| USE_QNAME
)))) {
4182 // The tags of the last optional member involved with USE_NIL
4183 // have been removed. If it was a simple type, the content was probably
4184 // written on a single line without anything resembling a close tag.
4185 // Do not indent our end tag in this case.
4186 switch ((int)(exer
&& (p_td
.xer_bits
& USE_NIL
))) {
4188 const unsigned char *buf_end
= p_buf
.get_data() + (p_buf
.get_len()-1);
4189 if (buf_end
[-1] != '>' || *buf_end
!= '\n') break;
4190 // If it does not look like an end tag, skip the indenting,
4191 // else fall through.
4194 do_indent(p_buf
, indent
);
4200 if (exer
) write_ns_prefix(p_td
, p_buf
);
4201 p_buf
.put_s((size_t)p_td
.namelens
[exer
]-!indenting
, (cbyte
*)p_td
.names
[exer
]);
4203 else { // need to generate an empty element tag
4204 p_buf
.increase_length(-start_tag_len
); // decrease length
4205 p_buf
.put_s((size_t)2+indenting
, (cbyte
*)"/>\n");
4209 return (int)p_buf
.get_len() - encoded_length
;
4212 // XERSTUFF Record_Type::encode_field
4213 /** Helper for Record_Type::XER_encode_negtest
4215 * Factored out because Record_Type::XER_encode (on which XER_encode_negtest
4216 * is based) calls the XER_encode method of the field in two places:
4217 * one for attributes, the other for elements.
4219 * @param i index of the field
4220 * @param err_vals erroneous descriptor for the field
4221 * @param emb_descr deeper erroneous values
4222 * @param p_buf buffer containing the encoded value
4223 * @param sub_flavor flags
4224 * @param indent indentation level
4225 * @return the number of bytes generated
4227 int Record_Type::encode_field(int i
,
4228 const Erroneous_values_t
* err_vals
, const Erroneous_descriptor_t
* emb_descr
,
4229 TTCN_Buffer
& p_buf
, unsigned int sub_flavor
, int indent
) const
4232 TTCN_EncDec_ErrorContext ec
;
4233 if (err_vals
&& err_vals
->before
) {
4234 if (err_vals
->before
->errval
==NULL
) TTCN_error(
4235 "internal error: erroneous before value missing");
4236 ec
.set_msg("Erroneous value before component %s: ", fld_name(i
));
4237 if (err_vals
->before
->raw
) {
4238 enc_len
+= err_vals
->before
->errval
->encode_raw(p_buf
);
4240 if (err_vals
->before
->type_descr
==NULL
) TTCN_error(
4241 "internal error: erroneous before typedescriptor missing");
4242 enc_len
+= err_vals
->before
->errval
->XER_encode(
4243 *err_vals
->before
->type_descr
->xer
, p_buf
, sub_flavor
, indent
);
4247 if (err_vals
&& err_vals
->value
) {
4248 if (err_vals
->value
->errval
) { // replace
4249 ec
.set_msg("Erroneous value for component %s: ", fld_name(i
));
4250 if (err_vals
->value
->raw
) {
4251 enc_len
+= err_vals
->value
->errval
->encode_raw(p_buf
);
4253 if (err_vals
->value
->type_descr
==NULL
) TTCN_error(
4254 "internal error: erroneous value typedescriptor missing");
4255 enc_len
+= err_vals
->value
->errval
->XER_encode(
4256 *err_vals
->value
->type_descr
->xer
, p_buf
, sub_flavor
, indent
);
4260 ec
.set_msg("Component %s: ", fld_name(i
));
4262 enc_len
+= get_at(i
)->XER_encode_negtest(emb_descr
, *xer_descr(i
), p_buf
,
4263 sub_flavor
, indent
);
4265 // the "real" encoder
4266 enc_len
+= get_at(i
)->XER_encode(*xer_descr(i
), p_buf
,
4267 sub_flavor
, indent
);
4271 if (err_vals
&& err_vals
->after
) {
4272 if (err_vals
->after
->errval
==NULL
) TTCN_error(
4273 "internal error: erroneous after value missing");
4274 ec
.set_msg("Erroneous value after component %s: ", fld_name(i
));
4275 if (err_vals
->after
->raw
) {
4276 enc_len
+= err_vals
->after
->errval
->encode_raw(p_buf
);
4278 if (err_vals
->after
->type_descr
==NULL
) TTCN_error(
4279 "internal error: erroneous after typedescriptor missing");
4280 enc_len
+= err_vals
->after
->errval
->XER_encode(
4281 *err_vals
->after
->type_descr
->xer
, p_buf
, sub_flavor
, indent
);
4288 // XERSTUFF Record_Type::XER_encode_negtest
4289 int Record_Type::XER_encode_negtest(const Erroneous_descriptor_t
* p_err_descr
,
4290 const XERdescriptor_t
& p_td
, TTCN_Buffer
& p_buf
, unsigned int flavor
, int indent
) const
4293 TTCN_EncDec_ErrorContext::error
4294 (TTCN_EncDec::ET_UNBOUND
, "Encoding an unbound value.");
4296 TTCN_EncDec_ErrorContext
ec_0("Component '");
4297 TTCN_EncDec_ErrorContext ec_1
;
4298 int encoded_length
=(int)p_buf
.get_len(); // how much is already in the buffer
4300 int exer
= is_exer(flavor
);
4301 if (exer
&& (p_td
.xer_bits
& EMBED_VALUES
)) flavor
|= XER_CANONICAL
;
4302 const boolean indenting
= !is_canonical(flavor
);
4303 const int field_cnt
= get_count();
4304 const int num_attributes
= get_xer_num_attr();
4305 // The USE-ORDER member is first, unless preempted by EMBED-VALUES
4306 const int uo_index
= ((p_td
.xer_bits
& EMBED_VALUES
) !=0);
4307 // Index of the first "normal" member (after E-V and U-O)
4308 const int start_at
= uo_index
+ ((p_td
.xer_bits
& USE_ORDER
) != 0);
4309 const int first_nonattr
= start_at
+ num_attributes
;
4310 // start_tag_len is keeping track of how much was written at the end of the
4311 // start tag, i.e. the ">\n". This is used later to "back up" over it.
4312 int start_tag_len
= 1 + indenting
;
4313 // The EMBED-VALUES member, if applicable (always first)
4314 const Record_Of_Type
* const embed_values
= (p_td
.xer_bits
& EMBED_VALUES
)
4315 ? static_cast<const Record_Of_Type
*>(get_at(0)) : 0;
4316 // The USE-ORDER member, if applicable (first unless preempted by embed_vals)
4317 const Record_Of_Type
* const use_order
= (p_td
.xer_bits
& USE_ORDER
)
4318 ? static_cast<const Record_Of_Type
*>(get_at(uo_index
)) : 0;
4323 size_t num_collected
= 0; // we use this to compute delay_close
4324 char **collected_ns
= NULL
;
4325 bool def_ns
= false;
4327 if (indent
== 0) { // top-level type
4328 collected_ns
= collect_ns(p_td
, num_collected
, def_ns
);
4330 else if ((flavor
& DEF_NS_SQUASHED
) && p_td
.my_module
&& p_td
.ns_index
!= -1) {
4331 const namespace_t
* ns
= p_td
.my_module
->get_ns(p_td
.ns_index
);
4332 // The default namespace has been squashed.
4333 // If we are in the default namespace, restore it.
4334 if (*ns
->px
== '\0') {
4335 collected_ns
= Base_Type::collect_ns(p_td
, num_collected
, def_ns
);
4340 // The type's own tag is omitted if we're doing E-XER,
4341 // and it's not the top-level type (XML must have a root element)
4342 // and it's either UNTAGGED or got USE_NIL.
4343 boolean omit_tag
= exer
&& indent
4344 && ( (p_td
.xer_bits
& (UNTAGGED
|XER_ATTRIBUTE
))
4345 || (flavor
& (USE_NIL
|USE_TYPE_ATTR
)));
4347 // If a default namespace is in effect (uri but no prefix) and the type
4348 // is unqualified, the default namespace must be canceled; otherwise
4349 // an XML tag without a ns prefix looks like it belongs to the def.namespace
4350 const boolean empty_ns_hack
= exer
&& !omit_tag
&& (indent
> 0)
4351 && (p_td
.xer_bits
& FORM_UNQUALIFIED
)
4352 && (flavor
& DEF_NS_PRESENT
);
4354 // delay_close=true if there is stuff before the '>' of the start tag
4355 // (prevents writing the '>' which is built into the name).
4356 // This can only happen for EXER: if there are attributes or namespaces,
4357 // or either USE-NIL or USE-QNAME is set.
4358 boolean delay_close
= exer
&& (num_attributes
4359 || empty_ns_hack
// counts as having a namespace
4360 || (num_collected
!= 0)
4361 || (p_td
.xer_bits
& (USE_NIL
|USE_QNAME
))
4362 || (flavor
& USE_NIL
));
4365 if (!omit_tag
) { /* write start tag */
4366 if (indenting
) do_indent(p_buf
, indent
);
4367 /* name looks like this: "tagname>\n"
4368 * lose the \n if : not indenting or (single untagged(*) or attributes (*)) AND exer
4369 * lose the > if attributes are present (*) AND exer
4372 if (exer
) write_ns_prefix(p_td
, p_buf
);
4373 p_buf
.put_s((size_t)p_td
.namelens
[exer
] - delay_close
4374 - (!indenting
|| delay_close
|| (exer
&& (p_td
.xer_bits
& HAS_1UNTAGGED
))),
4375 (cbyte
*)p_td
.names
[exer
]);
4377 else if (flavor
& USE_TYPE_ATTR
) {
4378 // reopen the parent's tag
4379 size_t buf_len
= p_buf
.get_len();
4380 const unsigned char * const buf_data
= p_buf
.get_data();
4381 if (buf_data
[buf_len
- 1 - shorter
] == '\n') ++shorter
;
4382 if (buf_data
[buf_len
- 1 - shorter
] == '>' ) ++shorter
;
4385 p_buf
.increase_length(-shorter
);
4390 int sub_len
=0, tmp_len
;
4391 // mask out extra flags we received, do not send them to the fields
4394 if (exer
&& (p_td
.xer_bits
& USE_QNAME
)) {
4395 const Erroneous_values_t
* ev
=
4396 p_err_descr
->next_field_err_values(0, values_idx
);
4397 const Erroneous_descriptor_t
* ed
=
4398 p_err_descr
->next_field_emb_descr (0, edescr_idx
);
4399 // At first, erroneous info for the first component (uri)
4401 TTCN_EncDec_ErrorContext ec
;
4402 const Base_Type
* const q_uri
= get_at(0);
4404 if (ev
&& ev
->before
) {
4405 if (ev
->before
->errval
==NULL
) TTCN_error(
4406 "internal error: erroneous before value missing");
4407 ec
.set_msg("Erroneous value before component #0: ");
4408 if (ev
->before
->raw
) {
4409 sub_len
+= ev
->before
->errval
->encode_raw(p_buf
);
4411 if (ev
->before
->type_descr
==NULL
) TTCN_error(
4412 "internal error: erroneous before typedescriptor missing");
4413 sub_len
+= ev
->before
->errval
->XER_encode(
4414 *ev
->before
->type_descr
->xer
, p_buf
, flavor
, indent
);
4418 if (ev
&& ev
->value
) {
4419 if (ev
->value
->errval
) { // replace
4420 ec
.set_msg("Erroneous value for component #0: ");
4421 if (ev
->value
->raw
) {
4422 sub_len
+= ev
->value
->errval
->encode_raw(p_buf
);
4424 if (ev
->value
->type_descr
==NULL
) TTCN_error(
4425 "internal error: erroneous value typedescriptor missing");
4426 sub_len
+= ev
->value
->errval
->XER_encode(
4427 *ev
->value
->type_descr
->xer
, p_buf
, flavor
, indent
);
4431 ec
.set_msg("Component #0: ");
4433 // universal charstring does not have components.
4434 // TTCN code which could have generated embedded erroneous descriptor
4435 // should have failed semantic analysis.
4436 TTCN_error("internal error: embedded descriptor unexpected");
4438 // the "real" encoder
4439 if (q_uri
->is_present()) {
4440 p_buf
.put_s(11, (cbyte
*)" xmlns:b0='");
4441 sub_len
+= q_uri
->XER_encode(*xer_descr(0), p_buf
, flavor
| XER_LIST
, indent
+1);
4447 if (ev
&& ev
->after
) {
4448 if (ev
->after
->errval
==NULL
) TTCN_error(
4449 "internal error: erroneous after value missing");
4450 ec
.set_msg("Erroneous value after component #0: ");
4451 if (ev
->after
->raw
) {
4452 sub_len
+= ev
->after
->errval
->encode_raw(p_buf
);
4454 if (ev
->after
->type_descr
==NULL
) TTCN_error(
4455 "internal error: erroneous after typedescriptor missing");
4456 sub_len
+= ev
->after
->errval
->XER_encode(
4457 *ev
->after
->type_descr
->xer
, p_buf
, flavor
, indent
);
4461 if (p_td
.xer_bits
& XER_ATTRIBUTE
) begin_attribute(p_td
, p_buf
);
4462 else p_buf
.put_c('>');
4464 // Now switch to the second field (name)
4465 ev
= p_err_descr
->next_field_err_values(1, values_idx
);
4466 ed
= p_err_descr
->next_field_emb_descr (1, edescr_idx
);
4468 if (ev
&& ev
->before
) {
4469 if (ev
->before
->errval
==NULL
) TTCN_error(
4470 "internal error: erroneous before value missing");
4471 ec
.set_msg("Erroneous value before component #1: ");
4472 if (ev
->before
->raw
) {
4473 sub_len
+= ev
->before
->errval
->encode_raw(p_buf
);
4475 if (ev
->before
->type_descr
==NULL
) TTCN_error(
4476 "internal error: erroneous before typedescriptor missing");
4477 sub_len
+= ev
->before
->errval
->XER_encode(
4478 *ev
->before
->type_descr
->xer
, p_buf
, flavor
, indent
);
4482 if (ev
&& ev
->value
) {
4483 if (ev
->value
->errval
) { // replace
4484 ec
.set_msg("Erroneous value for component #1: ");
4485 if (ev
->value
->raw
) {
4486 sub_len
+= ev
->value
->errval
->encode_raw(p_buf
);
4488 if (ev
->value
->type_descr
==NULL
) TTCN_error(
4489 "internal error: erroneous value typedescriptor missing");
4490 sub_len
+= ev
->value
->errval
->XER_encode(
4491 *ev
->value
->type_descr
->xer
, p_buf
, flavor
, indent
);
4495 ec
.set_msg("Component #1: ");
4497 // universal charstring does not have components
4498 TTCN_error("internal error: embedded descriptor unexpected");
4500 // the "real" encoder
4501 if (q_uri
->is_present()) {
4502 p_buf
.put_s(3, (cbyte
*)"b0:");
4506 sub_len
+= get_at(1)->XER_encode(*xer_descr(1), p_buf
, flavor
| XER_LIST
, indent
+1);
4510 if (ev
&& ev
->after
) {
4511 if (ev
->after
->errval
==NULL
) TTCN_error(
4512 "internal error: erroneous after value missing");
4513 ec
.set_msg("Erroneous value after component #1: ");
4514 if (ev
->after
->raw
) {
4515 sub_len
+= ev
->after
->errval
->encode_raw(p_buf
);
4517 if (ev
->after
->type_descr
==NULL
) TTCN_error(
4518 "internal error: erroneous after typedescriptor missing");
4519 sub_len
+= ev
->after
->errval
->XER_encode(
4520 *ev
->after
->type_descr
->xer
, p_buf
, flavor
, indent
);
4524 if (p_td
.xer_bits
& XER_ATTRIBUTE
) p_buf
.put_c('\'');
4526 else { // not USE-QNAME
4527 if (!exer
&& (p_td
.xer_bits
& EMBED_VALUES
)) {
4528 // The EMBED-VALUES member as an ordinary record of string
4529 sub_len
+= embed_values
->XER_encode(*xer_descr(0), p_buf
, flavor
, indent
+1);
4532 if (!exer
&& (p_td
.xer_bits
& USE_ORDER
)) {
4533 // The USE-ORDER member as an ordinary record of enumerated
4534 sub_len
+= use_order
->XER_encode(*xer_descr(uo_index
), p_buf
, flavor
, indent
+1);
4537 if (exer
&& (indent
==0 || (flavor
& DEF_NS_SQUASHED
))) // write namespaces for toplevel only
4539 for (size_t cur_coll
= 0; cur_coll
< num_collected
; ++cur_coll
) {
4540 p_buf
.put_s(strlen(collected_ns
[cur_coll
]), (cbyte
*)collected_ns
[cur_coll
]);
4541 Free(collected_ns
[cur_coll
]); // job done
4547 flavor
&= ~DEF_NS_SQUASHED
;
4548 flavor
|= DEF_NS_PRESENT
;
4550 else if (empty_ns_hack
) {
4551 p_buf
.put_s(9, (cbyte
*)" xmlns=''");
4552 flavor
&= ~DEF_NS_PRESENT
;
4553 flavor
|= DEF_NS_SQUASHED
;
4556 // True if the non-attribute fields need to be omitted;
4557 // e.g. if USE_ORDER is in effect and the "nil" attribute was written
4558 // (then the record-of-enum for USE-ORDER will be empty),
4559 // or "omit all after" was hit while processing attributes.
4560 boolean early_to_bed
= FALSE
;
4562 // First all the attributes (not added to sub_len)
4564 for (i
= start_at
; i
< first_nonattr
; ++i
) {
4565 const Erroneous_values_t
* ev
=
4566 p_err_descr
->next_field_err_values(i
, values_idx
);
4567 const Erroneous_descriptor_t
* ed
=
4568 p_err_descr
->next_field_emb_descr(i
, edescr_idx
);
4570 if (i
< p_err_descr
->omit_before
) continue;
4572 boolean is_xer_attr_field
= xer_descr(i
)->xer_bits
& XER_ATTRIBUTE
;
4573 ec_1
.set_msg("%s': ", fld_name(i
)); // attr
4575 tmp_len
= encode_field(i
, ev
, ed
, p_buf
, flavor
, indent
+ !omit_tag
);
4577 if (is_xer_attr_field
&& !exer
) sub_len
+= tmp_len
; // do not add if attribute and EXER
4579 // omit_after value -1 becomes "very big"
4580 if ((unsigned int)i
>= (unsigned int)p_err_descr
->omit_after
) {
4581 early_to_bed
= TRUE
; // no more fields to write
4586 // True if the "nil" attribute needs to be written.
4587 boolean nil_attribute
= FALSE
;
4588 // nil attribute unaffected by erroneous
4589 boolean nil_attribute_simple
= FALSE
;
4590 if (exer
&& (p_td
.xer_bits
& USE_NIL
)) {
4591 nil_attribute
= nil_attribute_simple
= !get_at(field_cnt
-1)->ispresent();
4593 if (p_err_descr
->values_size
> 0) // there is an erroneous "value := ..."
4595 const Erroneous_values_t
*ev_nil
=
4596 p_err_descr
->get_field_err_values(field_cnt
-1);
4597 if (ev_nil
&& ev_nil
->value
) // value override for the last field
4599 nil_attribute
= (ev_nil
->value
->errval
== NULL
);
4604 if (nil_attribute
) { // req. exer and USE_NIL
4605 const namespace_t
*control_ns
= p_td
.my_module
->get_controlns();
4607 if (!nil_attribute_simple
) {
4608 // It is likely that the declaration for namespace "xsi"
4609 // was not written. Do it now.
4610 p_buf
.put_s(7, (cbyte
*)" xmlns:");
4611 p_buf
.put_s(strlen(control_ns
->px
), (cbyte
*)control_ns
->px
);
4612 p_buf
.put_s(2, (cbyte
*)"='");
4613 p_buf
.put_s(strlen(control_ns
->ns
), (cbyte
*)control_ns
->ns
);
4618 p_buf
.put_s(strlen(control_ns
->px
), (cbyte
*)control_ns
->px
);
4620 p_buf
.put_s(10, (cbyte
*)"nil='true'");
4621 if ((p_td
.xer_bits
& USE_ORDER
)) early_to_bed
= TRUE
;
4622 // The whole content was omitted; nothing to do (and if we tried
4623 // to do it, we'd get an error for over-indexing a 0-length record-of).
4626 if (delay_close
&& (!omit_tag
|| shorter
)) {
4627 // Close the start tag left open. If indenting, also write a newline
4628 // unless USE-NIL in effect or there is a single untagged component.
4630 ((p_td
.xer_bits
& (/*USE_NIL|*/HAS_1UNTAGGED
)) ? 0 : indenting
);
4631 p_buf
.put_s(start_tag_len
, (cbyte
*)">\n");
4634 // Erroneous values for the embed_values member (if any).
4635 // Collected once but referenced multiple times.
4636 const Erroneous_descriptor_t
* ed0
= NULL
;
4637 int embed_values_val_idx
= 0;
4638 int embed_values_descr_idx
= 0;
4640 int expected_embed
= (field_cnt
- first_nonattr
+ 1);
4641 if (exer
&& (p_td
.xer_bits
& EMBED_VALUES
)) {
4642 ed0
= p_err_descr
->next_field_emb_descr(0, edescr_idx
);
4644 ec_1
.set_msg("%s': ", fld_name(0));
4646 if ((p_td
.xer_bits
& USE_NIL
) && !get_at(field_cnt
-1)->ispresent()) {
4647 expected_embed
= 0; //25.2.6 a
4649 else if ((num_opt
= optional_count()) > 0) {
4650 const int * optionals
= get_optional_indexes();
4651 for (int opt_idx
= 0; opt_idx
< num_opt
; ++opt_idx
) {
4652 // skip optional attributes
4653 if (optionals
[opt_idx
] < start_at
+ num_attributes
) continue;
4654 // reduce for each omitted member
4655 if (!get_at(optionals
[opt_idx
])->is_present()) --expected_embed
;
4658 // Check the correct number of EMBED-VALUES (regular non-attributes + 1)
4659 if (embed_values
->size_of() != expected_embed
)
4660 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_CONSTRAINT
,
4661 "Wrong number %d of EMBED-VALUEs, expected %d",
4662 embed_values
->size_of(), expected_embed
);
4663 // write the first string
4664 if (expected_embed
> 0) {
4665 const Erroneous_values_t
* ev0_0
= NULL
;
4666 const Erroneous_descriptor_t
* ed0_0
= NULL
;
4668 ev0_0
= ed0
->next_field_err_values(0, embed_values_val_idx
);
4669 ed0_0
= ed0
->next_field_emb_descr (0, embed_values_descr_idx
);
4671 sub_len
+= embed_values
->encode_element(0, ev0_0
, ed0_0
,
4672 p_buf
, flavor
| EMBED_VALUES
, indent
+!omit_tag
);
4676 const Record_Type
*ordered
= this; // the record affected by USE-ORDER
4677 // By default it's this record, unless USE_NIL is _also_ in effect,
4678 // in which case it's the last member of this.
4680 // Index of the first non-attribute field of the record pointed to by
4681 // ordered, that is, the first field affected by USE-ORDER.
4682 size_t useorder_base
= first_nonattr
;
4685 int end
= field_cnt
; // "one past", do not touch
4686 // by default, continue from the current field until the end, indexing this
4688 if (exer
&& (p_td
.xer_bits
& USE_ORDER
)) {
4689 // the length of the loop is determined by the length of use_order
4690 const int to_send
= use_order
->size_of();
4692 // i will index all elements of the use_order member
4696 // Count the non-attribute optionals
4697 int n_optionals
= 0;
4698 for (int B
= optional_count() - 1; B
>=+0; B
--) {
4699 int oi
= get_optional_indexes()[B
];
4700 if (oi
< first_nonattr
) break;
4704 int expected_min
= field_cnt
- first_nonattr
- n_optionals
;
4705 int expected_max
= field_cnt
- first_nonattr
;
4707 if ((p_td
.xer_bits
& USE_NIL
) && get_at(field_cnt
-1)->ispresent()) {
4708 // The special case when USE_ORDER refers to the fields of a field,
4710 const Base_Type
*last_optional
= get_at(field_cnt
-1);
4711 const Base_Type
* inner
= last_optional
->get_opt_value();
4712 // it absolutely, positively has to be (derived from) Record_Type
4713 ordered
= static_cast<const Record_Type
*>(inner
);
4714 useorder_base
= ordered
->get_xer_num_attr();
4715 begin
= useorder_base
;
4716 end
= ordered
->get_count();
4718 expected_min
= expected_max
= ordered
->get_count();
4721 if (to_send
> expected_max
4722 ||to_send
< expected_min
) {
4723 ec_1
.set_msg("%s': ", fld_name(uo_index
));
4724 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_CONSTRAINT
,
4725 "Wrong number of USE-ORDER %d, must be %d..%d", to_send
, expected_min
, expected_max
);
4726 early_to_bed
= TRUE
; // don't bother sending anything
4728 else { // check no duplicates
4729 int *seen
= new int [to_send
];
4731 for (int ei
= 0; ei
< to_send
; ++ei
) {
4732 const Base_Type
*uoe
= use_order
->get_at(ei
);
4733 const Enum_Type
*enm
= static_cast<const Enum_Type
*>(uoe
);
4734 int val
= enm
->as_int();
4735 for (int x
= 0; x
< num_seen
; ++x
) {
4736 if (val
== seen
[x
]) { // complain
4737 ec_1
.set_msg("%s': ", fld_name(uo_index
));
4738 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_CONSTRAINT
,
4739 "Duplicate value for USE-ORDER");
4740 early_to_bed
= TRUE
; // don't bother sending anything
4744 seen
[num_seen
++] = val
;
4748 // If the number is right and there are no duplicates, then carry on
4750 } // endif(USE_ORDER)
4752 // Then, all the non-attributes. Structuring the code like this depends on
4753 // all attributes appearing before all non-attributes (excluding
4754 // pseudo-members for USE-ORDER, etc.)
4756 // This loop handles both the normal case (no USE_ORDER) when i indexes
4757 // fields of this record; and the USE_ORDER case (with or without USE-NIL).
4759 // early_to_bed can only be true if exer is true (transitive through nil_attribute)
4760 if (!early_to_bed
) for ( i
= begin
; i
< end
; ++i
) {
4762 const Base_Type
*uoe
= 0; // "useOrder enum"
4763 const Enum_Type
*enm
= 0; // the enum value selecting the field
4765 // "actual" index, may be perturbed by USE-ORDER.
4766 // We use this value to index the appropriate record.
4769 const Erroneous_values_t
* ev
= NULL
;
4770 const Erroneous_descriptor_t
* ed
= NULL
;
4771 if (exer
&& use_order
) {
4772 // If USE-ORDER is in effect, it introduces a level of indirection
4773 // into the indexing of fields: "i" is used to select an element
4774 // of the use_order member (an enum), whose value is used to select
4775 // the field being encoded.
4776 uoe
= use_order
->get_at(i
- begin
);
4777 enm
= static_cast<const Enum_Type
*>(uoe
);
4778 ai
= enm
->as_int() + useorder_base
;
4780 // Because it is not guaranteed that ai will increase monotonically,
4781 // we can't use next_field_...().
4782 ev
= p_err_descr
->get_field_err_values(ai
);
4783 ed
= p_err_descr
->get_field_emb_descr (ai
);
4785 else { // not USE-ORDER, sequential access
4786 ev
= p_err_descr
->next_field_err_values(ai
, values_idx
);
4787 ed
= p_err_descr
->next_field_emb_descr (ai
, edescr_idx
);
4789 ec_1
.set_msg("%s': ", ordered
->fld_name(ai
)); // non-attr
4791 if (ai
< p_err_descr
->omit_before
) continue;
4793 // omit_after value -1 becomes "very big".
4794 if ((unsigned int)ai
> (unsigned int)p_err_descr
->omit_after
) continue;
4795 // We can't skip all fields with break, because the next ai may be lower
4798 sub_len
+= ordered
->encode_field(ai
, ev
, ed
, p_buf
,
4799 // Pass USE-NIL to the last field (except when USE-ORDER is also in effect,
4800 // because the tag-stripping effect of USE-NIL has been achieved
4801 // by encoding the sub-fields directly).
4802 flavor
| ((exer
&& !use_order
&& (i
== field_cnt
-1)) ? (p_td
.xer_bits
& USE_NIL
) : 0),
4803 indent
+ !omit_tag
);
4805 // Now the next embed-values string (NOT affected by USE-ORDER!)
4806 int i1
= i
- begin
+ 1;
4807 if (exer
&& (p_td
.xer_bits
& EMBED_VALUES
) && i1
< expected_embed
) {
4808 const Erroneous_values_t
* ev0_i
= NULL
;
4809 const Erroneous_descriptor_t
* ed0_i
= NULL
;
4811 ev0_i
= ed0
->next_field_err_values(i1
, embed_values_val_idx
);
4812 ed0_i
= ed0
->next_field_emb_descr (i1
, embed_values_descr_idx
);
4814 embed_values
->encode_element(i1
, ev0_i
, ed0_i
,
4815 p_buf
, flavor
| EMBED_VALUES
, indent
+ !omit_tag
);
4822 if (sub_len
) { // something was written, now an end tag
4823 if (indenting
&& !(exer
&& (p_td
.xer_bits
& (HAS_1UNTAGGED
| USE_QNAME
))))
4824 // The tags of the last optional member involved with USE_NIL
4825 // have been removed. If it was a simple type, the content was probably
4826 // written on a single line without anything resembling a close tag.
4827 // Do not indent our end tag in this case.
4828 switch ((int)(exer
&& (p_td
.xer_bits
& USE_NIL
))) {
4830 const unsigned char *buf_end
= p_buf
.get_data() + (p_buf
.get_len()-1);
4831 if (buf_end
[-1] != '>' || *buf_end
!= '\n') break;
4832 // If it does not look like an end tag, skip the indenting,
4833 // else fall through.
4836 do_indent(p_buf
, indent
);
4841 if (exer
) write_ns_prefix(p_td
, p_buf
);
4842 p_buf
.put_s((size_t)p_td
.namelens
[exer
]-!indenting
, (cbyte
*)p_td
.names
[exer
]);
4844 else { // need to generate an empty element tag
4845 p_buf
.increase_length(-start_tag_len
); // decrease length
4846 p_buf
.put_s((size_t)2+indenting
, (cbyte
*)"/>\n");
4850 return (int)p_buf
.get_len() - encoded_length
;
4853 int Record_Type::XER_decode(const XERdescriptor_t
& p_td
, XmlReaderWrap
& reader
, unsigned int flavor
)
4856 int exer
= is_exer(flavor
);
4858 int depth
=-1; // depth of the start tag
4859 int xerbits
= p_td
.xer_bits
;
4860 if (flavor
& XER_TOPLEVEL
) xerbits
&= ~UNTAGGED
;
4861 const boolean own_tag
= !(exer
4862 && ( (xerbits
& (ANY_ELEMENT
| UNTAGGED
| XER_ATTRIBUTE
))
4863 || (flavor
& (USE_NIL
| USE_TYPE_ATTR
))));
4864 boolean tag_closed
= (flavor
& PARENT_CLOSED
) != 0;
4865 // If the parent has USE-TYPE, our ATTRIBUTE members can be found
4866 // in the parent's tag (the reader is sitting on it).
4867 const boolean parent_tag
= exer
&& (flavor
& (/*USE_NIL|*/ USE_TYPE_ATTR
));
4869 // Filter out flags passed by our parent. These are not for the fields.
4870 flavor
&= XER_MASK
; // also removes XER_TOPLEVEL
4872 const int field_cnt
= get_count();
4873 const int num_attributes
= get_xer_num_attr();
4875 // The index of potential "order" field, regardless of whether USE_ORDER
4876 // is in use or not.
4877 const int uo_index
= ((p_td
.xer_bits
& EMBED_VALUES
) !=0);
4879 // The first "non-special" field (skipping the USE-ORDER and EMBED-VALUES
4880 // fields); normal processing start at this field.
4881 const int start_at
= uo_index
+ ((p_td
.xer_bits
& USE_ORDER
) != 0);
4882 const int first_nonattr
= start_at
+ num_attributes
;
4884 // The index of the ANY-ATTRIBUTES member, if any
4886 for (int k
= 0; k
< first_nonattr
; ++k
) {
4887 if (xer_descr(k
)->xer_bits
& ANY_ATTRIBUTES
) {
4889 static_cast<Record_Of_Type
*>(get_at(aa_index
))->set_size(0);
4890 break; // there can be only one, 18.2.2
4894 if (own_tag
) for (success
=reader
.Ok(); success
==1; success
=reader
.Read()) {
4895 type
= reader
.NodeType();
4896 if (type
==XML_READER_TYPE_ELEMENT
) {
4897 verify_name(reader
, p_td
, exer
);
4898 depth
= reader
.Depth();
4899 tag_closed
= reader
.IsEmptyElement();
4906 if (exer
&& (p_td
.xer_bits
& USE_QNAME
)) { // QName trumps everything !
4907 // If element, it looks like this:
4908 // <name xmlns:b0="http://www.furniture.com">b0:table</name>
4909 // If attribute, it looks like this:
4912 if (p_td
.xer_bits
& XER_ATTRIBUTE
) success
= 1; // do nothing
4913 else for (success
= reader
.Read(); success
== 1; success
= reader
.Read()) {
4914 type
= reader
.NodeType();
4915 if (type
== XML_READER_TYPE_TEXT
) break;
4919 xmlChar
*val
= reader
.NewValue();
4920 xmlChar
*npfx
= (xmlChar
*)strchr((char*)val
, ':');
4923 *npfx
++ = '\0'; // cut the string into two
4931 xmlChar
*nsu
= reader
.LookupNamespace(pfx
);
4933 OPTIONAL
<UNIVERSAL_CHARSTRING
> *q_prefix2
=
4934 static_cast<OPTIONAL
<UNIVERSAL_CHARSTRING
>*>(get_at(0));
4935 if (nsu
) *q_prefix2
= (const char*)nsu
;
4936 else q_prefix2
->set_to_omit(); // public in RT2 only
4938 UNIVERSAL_CHARSTRING
*q_name2
= static_cast<UNIVERSAL_CHARSTRING
*>(get_at(1));
4939 *q_name2
= (const char*)npfx
;
4945 else { // not use-qname
4946 TTCN_EncDec_ErrorContext
ec_0("Component '");
4947 TTCN_EncDec_ErrorContext ec_1
;
4948 boolean usenil_attribute
= FALSE
; // true if found and said yes
4950 if (!reader
.IsEmptyElement()) reader
.Read();
4951 // First, the (would-be) attributes (unaffected by USE-ORDER)
4952 for (i
= 0; i
< first_nonattr
; i
++) {
4953 ec_1
.set_msg("%s': ", fld_name(i
));
4954 get_at(i
)->XER_decode(*xer_descr(i
), reader
, flavor
);
4957 else if (own_tag
|| parent_tag
) { // EXER and not UNTAGGED: do attributes
4958 // Prepare for lack of attributes.
4959 // Fields with defaultForEmpty get the D-F-E value, optional get omit.
4960 for (i
= start_at
; i
< first_nonattr
; i
++) {
4961 Base_Type
&fld
= *get_at(i
);
4962 const XERdescriptor_t
& xd
= *xer_descr(i
);
4964 if (fld
.is_optional()) {
4965 fld
.set_to_present();
4966 fld
.get_opt_value()->set_value(xd
.dfeValue
);
4968 else fld
.set_value(xd
.dfeValue
);
4970 else if (fld
.is_optional()) fld
.set_to_omit();
4973 int num_aa
= 0; // index into the ANY-ATTRIBUTE member
4975 const namespace_t
*control_ns
= 0;
4976 if (parent_tag
|| (p_td
.xer_bits
& USE_NIL
)) {
4977 // xsi:type or xsi:nil
4978 control_ns
= p_td
.my_module
->get_controlns();
4981 /* * * * * * * * * Attributes * * * * * * * * * * * * * */
4982 for (success
= reader
.MoveToFirstAttribute();
4983 success
== 1 && reader
.NodeType() == XML_READER_TYPE_ATTRIBUTE
;
4984 success
= reader
.AdvanceAttribute())
4986 if (reader
.IsNamespaceDecl()) {
4987 continue; // namespace declarations are handled for us by libxml2
4990 const char *attr_name
= (const char*)reader
.LocalName();
4991 const char *ns_uri
= (const char*)reader
.NamespaceUri();
4992 int field_index
= get_index_byname(attr_name
, ns_uri
);
4993 if (field_index
!= -1) {
4994 // There is a field. Let it decode the attribute.
4995 ec_1
.set_msg("%s': ", fld_name(field_index
));
4996 get_at(field_index
)->XER_decode(*xer_descr(field_index
), reader
, flavor
);
5000 // Attribute not found. It could be the "nil" attribute
5001 if (p_td
.xer_bits
& USE_NIL
) {
5002 const char *prefix
= (const char*)reader
.Prefix();
5003 // prefix may be NULL, control_ns->px is never NULL or empty
5004 if (prefix
&& !strcmp(prefix
, control_ns
->px
)
5005 && !strcmp((const char*)reader
.LocalName(), "nil"))
5006 { // It is the "nil" attribute
5007 const char *value
= (const char*)reader
.Value();
5009 if (!strcmp(value
, "1") || !strcmp(value
, "true")) {
5010 // The field affected by USE-NIL is always the last one
5011 get_at(field_cnt
-1)->set_to_omit();
5012 usenil_attribute
= TRUE
;
5017 } // it is the "nil" attribute
5018 } // type has USE-NIL
5021 const char *prefix
= (const char*)reader
.Prefix();
5022 // prefix may be NULL, control_ns->px is never NULL or empty
5023 if (prefix
&& !strcmp(prefix
, control_ns
->px
)
5024 && !strcmp((const char*)reader
.LocalName(), "type")) {
5025 continue; // xsi:type has been processed by the parent
5029 if (aa_index
>= 0) {
5030 ec_1
.set_msg("%s': ", fld_name(aa_index
));
5031 TTCN_EncDec_ErrorContext
ec_2("Attribute %d: ", num_aa
);
5032 // We have a component with ANY-ATTRIBUTE. It must be a record of
5033 // UNIVERSAL_CHARSTRING. Add the attribute to it.
5034 Record_Of_Type
*aa
= static_cast<Record_Of_Type
*>(get_at(aa_index
));
5035 UNIVERSAL_CHARSTRING
*new_elem
= static_cast<UNIVERSAL_CHARSTRING
*>
5036 (aa
->get_at(num_aa
++));
5038 // Construct the AnyAttributeFormat (X.693amd1, 18.2.6)
5040 const xmlChar
*name
= reader
.LocalName();
5041 const xmlChar
*val
= reader
.Value();
5042 const xmlChar
*uri
= reader
.NamespaceUri();
5044 if (xer_descr(aa_index
)->xer_bits
& (ANY_FROM
| ANY_EXCEPT
)) {
5045 check_namespace_restrictions(*xer_descr(aa_index
), (const char*)uri
);
5047 // We don't care about reader.Prefix()
5048 // Using strlen to count UTF8 bytes, not characters
5049 aabuf
.put_s(uri
? strlen((const char*)uri
) : 0, uri
);
5050 if (uri
&& *uri
) aabuf
.put_c(' ');
5051 aabuf
.put_s(name
? strlen((const char*)name
) : 0, name
);
5054 aabuf
.put_s(val
? strlen((const char*)val
) : 0, val
);
5056 new_elem
->decode_utf8(aabuf
.get_len(), aabuf
.get_data());
5061 // Lastly check for the xsi:schemaLocation attribute, this does not
5062 // affect TTCN-3, but it shouldn't cause a DTE
5063 if (reader
.LocalName() && !strcmp((const char*)reader
.LocalName(), "schemaLocation")) {
5065 control_ns
= p_td
.my_module
->get_controlns();
5067 if (reader
.Prefix() && !strcmp((const char*)reader
.Prefix(), control_ns
->px
)) {
5072 // Nobody wanted the attribute. That is an error.
5073 ec_0
.set_msg(" "); ec_1
.set_msg(" ");
5074 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG
,
5075 "Unexpected attribute '%s', ns '%s'", attr_name
,
5076 ns_uri
? ns_uri
: "");
5079 // Now check that all mandatory attributes have been set
5080 for (i
= start_at
; i
< first_nonattr
; ++i
) {
5081 Base_Type
* fld
= get_at(i
);
5082 if (fld
->is_optional()) continue; // field is allowed to be unset
5083 if (!fld
->is_bound()) {
5084 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG
,
5085 "Missing attribute '%s'", this->fld_name(i
));
5089 i
= first_nonattr
; // finished with attributes
5090 // AdvanceAttribute did MoveToElement. Move into the content (if any).
5091 if (!reader
.IsEmptyElement()) reader
.Read();
5092 } // end if (own_tag)
5094 /* * * * * * * * Non-attributes (elements) * * * * * * * * * * * */
5095 Record_Of_Type
* embed_values
= 0;
5096 if (exer
&& (p_td
.xer_bits
& EMBED_VALUES
)) {
5097 embed_values
= static_cast<Record_Of_Type
*>(get_at(0));
5100 if (exer
&& (p_td
.xer_bits
& USE_ORDER
)) {
5101 // Set all optional fields to omit because their respective XER_decode
5102 // will not be run (and will stay unbound) if the value is missing.
5103 int n_optionals
= 0;
5104 for (int B
= optional_count() - 1; B
>=+0; B
--) {
5105 int oi
= get_optional_indexes()[B
];
5106 if (oi
< first_nonattr
) break;
5107 get_at(oi
)->set_to_omit();
5110 Record_Of_Type
*use_order
= static_cast<Record_Of_Type
*>(get_at(uo_index
));
5111 // Initialize the use_order field to empty. Let it grow on demand.
5112 // (setting it to the minimum acceptable size may leave unbound elements
5113 // if the XML was incomplete).
5114 use_order
->set_size(0);
5116 Record_Type
*jumbled
= this; // the record affected by USE_ORDER
5117 int begin
= first_nonattr
;
5118 int end
= field_cnt
; // "one past"
5119 if (p_td
.xer_bits
& USE_NIL
) {
5120 Base_Type
*last_optional
= get_at(field_cnt
-1);
5121 if (!usenil_attribute
) { // exer known true
5122 last_optional
->set_to_present();
5123 jumbled
= static_cast<Record_Type
*>(last_optional
->get_opt_value());
5124 // We will operate on the members of last_optional,
5125 // effectively bypassing last_optional->XER_decode() itself.
5127 end
= jumbled
->get_count();
5128 ec_1
.set_msg("%s': ", fld_name(field_cnt
-1));
5131 if (num_attributes
> 0
5132 && first_nonattr
!= field_cnt
5133 && i
== first_nonattr
- 1) { // exer known true
5134 // If there were attributes and their processing just finished,
5135 // the reader is positioned on the start tag of the record.
5136 // Move ahead, unless there are no non-attribute fields.
5139 // Then, the non-attributes
5141 // The index runs over the members affected by USE-ORDER.
5142 // This is [first_nonattr,field_cnt) unless USE-NIL is involved,
5143 // in which case it's [0,optional_sequence::field_cnt)
5144 int *seen
= new int[end
-begin
];
5146 int last_any_elem
= begin
- 1;
5147 for (i
= begin
; i
< end
; i
++) {
5148 for (success
= reader
.Ok(); success
== 1; success
= reader
.Read()) {
5149 type
= reader
.NodeType();
5151 if (reader
.NodeType()==XML_READER_TYPE_TEXT
) {
5152 UNIVERSAL_CHARSTRING
emb_ustr((const char*)reader
.Value());
5153 embed_values
->get_at(i
-begin
)->set_value(&emb_ustr
);
5156 // The non-attribute components must not be UNTAGGED
5157 if (type
== XML_READER_TYPE_ELEMENT
) break;
5158 // else if (type==XML_READER_TYPE_END_ELEMENT) panic?
5160 if (success
!= 1) break;
5161 const char *name
= (const char *)reader
.LocalName();
5162 boolean field_name_found
= false;
5163 // Find out which member it is.
5164 // FIXME some hashing should be implemented
5165 for (int k
= begin
; k
< end
; k
++) {
5166 if (!(jumbled
->xer_descr(k
)->xer_bits
& ANY_ELEMENT
) &&
5167 check_name(name
, *jumbled
->xer_descr(k
), 1)) {
5168 ec_1
.set_msg("%s': ", jumbled
->fld_name(k
));
5170 // Check for the same field being decoded twice.
5171 // We can't use the field's is_bound()/is_present(),
5172 // because the field may be bound on input, e.g. for
5173 // prototype(fast) or prototype(backtrack).
5174 int in_dex
= k
- begin
;
5175 for (int o
= 0; o
< num_seen
;++o
) {
5176 if (in_dex
== seen
[o
]) TTCN_EncDec_ErrorContext::error(
5177 TTCN_EncDec::ET_INVAL_MSG
, "Duplicate element");
5179 seen
[num_seen
++] = in_dex
;
5180 // Set the next use-order member.
5181 // Non-const get_at creates the object in the record-of.
5182 static_cast<Enum_Type
*>(use_order
->get_at(i
- begin
))
5184 Base_Type
*b
= jumbled
->get_at(k
);
5185 b
->XER_decode(*jumbled
->xer_descr(k
), reader
, flavor
);
5186 field_name_found
= true;
5190 if (!field_name_found
) {
5191 // Check the anyElement fields
5192 for (int k
= last_any_elem
+ 1; k
< end
; k
++) {
5193 if (jumbled
->xer_descr(k
)->xer_bits
& ANY_ELEMENT
) {
5194 ec_1
.set_msg("%s': ", jumbled
->fld_name(k
));
5196 // Check for the same field being decoded twice.
5197 // We can't use the field's is_bound()/is_present(),
5198 // because the field may be bound on input, e.g. for
5199 // prototype(fast) or prototype(backtrack).
5200 int in_dex
= k
- begin
;
5201 for (int o
= 0; o
< num_seen
;++o
) {
5202 if (in_dex
== seen
[o
]) TTCN_EncDec_ErrorContext::error(
5203 TTCN_EncDec::ET_INVAL_MSG
, "Duplicate element");
5205 seen
[num_seen
++] = in_dex
;
5206 // Set the next use-order member.
5207 // Non-const get_at creates the object in the record-of.
5208 static_cast<Enum_Type
*>(use_order
->get_at(i
- begin
))
5210 Base_Type
*b
= jumbled
->get_at(k
);
5211 b
->XER_decode(*jumbled
->xer_descr(k
), reader
, flavor
);
5219 if (reader
.NodeType()==XML_READER_TYPE_TEXT
) {
5220 UNIVERSAL_CHARSTRING
emb_ustr((const char*)reader
.Value());
5221 embed_values
->get_at(i
-begin
)->set_value(&emb_ustr
);
5225 ec_1
.set_msg(" "); // no active component
5228 // Check that we collected the required number of children
5229 int num_collected
= use_order
->size_of();
5230 if (p_td
.xer_bits
& USE_NIL
) {
5231 int expected
= usenil_attribute
? 0 : jumbled
->get_count();
5232 if (num_collected
!= expected
) {
5233 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INCOMPL_MSG
,
5234 "Incorrect number of fields %d, expected %d",
5235 num_collected
, expected
);
5239 if (num_collected
< field_cnt
- first_nonattr
- n_optionals
5240 ||num_collected
> field_cnt
- first_nonattr
) {
5241 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INCOMPL_MSG
,
5242 "Wrong number of fields! size = %d, expected %d..%d",
5243 use_order
->size_of(), field_cnt
- first_nonattr
- n_optionals
,
5244 field_cnt
- first_nonattr
);
5248 else { // not USE-ORDER, simpler code
5249 if (usenil_attribute
) {
5250 reader
.MoveToElement(); // value absent, nothing more to do
5253 for (; i
<field_cnt
; i
++) {
5255 if (reader
.NodeType()==XML_READER_TYPE_TEXT
) {
5256 UNIVERSAL_CHARSTRING
emb_ustr((const char*)reader
.Value());
5257 embed_values
->get_at(emb_idx
)->set_value(&emb_ustr
);
5261 ec_1
.set_msg("%s': ", fld_name(i
));
5262 if (exer
&& i
==field_cnt
-1 && p_td
.dfeValue
&& reader
.IsEmptyElement()) {
5263 get_at(i
)->set_value(p_td
.dfeValue
);
5266 // In case the field is an optional anyElement -> check if it should be omitted
5267 bool optional_any_elem_check
= true;
5268 if (get_at(i
)->is_optional() && (xer_descr(i
)->xer_bits
& ANY_ELEMENT
)) {
5269 // The "anyElement" coding instruction can only be applied to a universal charstring field
5270 OPTIONAL
<UNIVERSAL_CHARSTRING
>* opt_field
= dynamic_cast<OPTIONAL
<UNIVERSAL_CHARSTRING
>*>(get_at(i
));
5272 const char* next_field_name
= NULL
;
5273 if (i
< field_cnt
- 1) {
5274 next_field_name
= fld_name(i
+ 1);
5276 optional_any_elem_check
= opt_field
->XER_check_any_elem(reader
, next_field_name
, tag_closed
);
5279 if (optional_any_elem_check
) {
5280 int new_flavor
= flavor
;
5281 if (i
== field_cnt
-1) new_flavor
|= (p_td
.xer_bits
& USE_NIL
);
5282 if (tag_closed
) new_flavor
|= PARENT_CLOSED
;
5284 get_at(i
)->XER_decode(*xer_descr(i
), reader
, new_flavor
);
5289 if (reader
.NodeType()==XML_READER_TYPE_TEXT
) {
5290 UNIVERSAL_CHARSTRING
emb_ustr((const char*)reader
.Value());
5291 embed_values
->get_at(emb_idx
)->set_value(&emb_ustr
);
5298 // Set the embed_values member to the correct number of strings
5299 int num_embedded
= 0; // if usenil_attribute
5300 if (!usenil_attribute
) {
5301 num_embedded
= field_cnt
- first_nonattr
+ 1;
5302 const int num_opt
= optional_count();
5303 const int * optionals
= get_optional_indexes();
5304 for (int opt_idx
= 0; opt_idx
< num_opt
; ++opt_idx
) {
5305 // skip optional attributes
5306 if (optionals
[opt_idx
] < start_at
+ num_attributes
) continue;
5307 // reduce for each omitted member
5308 if (!get_at(optionals
[opt_idx
])->is_present()) --num_embedded
;
5311 embed_values
->set_size(num_embedded
);
5312 static const UNIVERSAL_CHARSTRING
emptystring(0, (const char*)NULL
);
5313 for (int j
= 0; j
< num_embedded
; ++j
) {
5314 if (!embed_values
->get_at(j
)->is_bound()) embed_values
->get_at(j
)->set_value(&emptystring
);
5316 } // if embed-values
5321 // We had our start tag. Then our fields did their thing.
5322 // Now we expect the end tag. And it better be our end tag!
5324 for (success
= reader
.Ok(); success
== 1; success
= reader
.Read()) {
5325 type
= reader
.NodeType();
5326 current_depth
= reader
.Depth();
5327 if (current_depth
> depth
) {
5328 if (XML_READER_TYPE_ELEMENT
== type
) {
5329 // We found a deeper start tag; it was not processed at all.
5330 // That is an error (maybe we should report error for all node types
5331 // except TEXT and WHITESPACE, not just ELEMENT).
5332 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TAG
,
5333 "Unprocessed XML tag `%s'", (const char *)reader
.Name());
5336 continue; // go past hoping that our end tag will arrive eventually
5338 else if (current_depth
== depth
) { // at our level
5339 if (XML_READER_TYPE_ELEMENT
== type
) {
5340 verify_name(reader
, p_td
, exer
);
5341 if (reader
.IsEmptyElement()) {
5342 // FIXME this shouldn't really be possible;
5343 // only an empty record should be encoded as an empty element,
5344 // but those are implemented by Empty_Record_Type, not Record_Type.
5345 reader
.Read(); // one last time
5349 // If we find an end tag at the right depth, it must be ours
5350 else if (XML_READER_TYPE_END_ELEMENT
== type
) {
5351 verify_end(reader
, p_td
, depth
, exer
);
5356 else { //current_depth < depth; something has gone horribly wrong
5357 break; // better quit before we do further damage
5358 // Don't report an error; every enclosing type would do so,
5359 // spewing the same message over and over.
5363 return 1; // decode successful
5366 int Record_Type::JSON_encode(const TTCN_Typedescriptor_t
&, JSON_Tokenizer
& p_tok
) const
5369 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND
,
5370 "Encoding an unbound %s value.", is_set() ? "set" : "record");
5374 int enc_len
= p_tok
.put_next_token(JSON_TOKEN_OBJECT_START
, NULL
);
5376 int field_count
= get_count();
5377 for(int i
= 0; i
< field_count
; ++i
) {
5378 if ((NULL
!= fld_descr(i
)->json
&& fld_descr(i
)->json
->omit_as_null
) ||
5379 !get_at(i
)->is_optional() || get_at(i
)->is_present()) {
5380 if (NULL
!= fld_descr(i
)->json
&& NULL
!= fld_descr(i
)->json
->alias
) {
5381 enc_len
+= p_tok
.put_next_token(JSON_TOKEN_NAME
, fld_descr(i
)->json
->alias
);
5383 enc_len
+= p_tok
.put_next_token(JSON_TOKEN_NAME
, fld_name(i
));
5385 enc_len
+= get_at(i
)->JSON_encode(*fld_descr(i
), p_tok
);
5389 enc_len
+= p_tok
.put_next_token(JSON_TOKEN_OBJECT_END
, NULL
);
5393 int Record_Type::JSON_decode(const TTCN_Typedescriptor_t
& p_td
, JSON_Tokenizer
& p_tok
, boolean p_silent
)
5395 json_token_t token
= JSON_TOKEN_NONE
;
5396 int dec_len
= p_tok
.get_next_token(&token
, NULL
, NULL
);
5397 if (JSON_TOKEN_ERROR
== token
) {
5398 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG
, JSON_DEC_BAD_TOKEN_ERROR
, "");
5399 return JSON_ERROR_FATAL
;
5401 else if (JSON_TOKEN_OBJECT_START
!= token
) {
5402 return JSON_ERROR_INVALID_TOKEN
;
5406 const int field_count
= get_count();
5409 // Read name - value token pairs until we reach some other token
5411 size_t name_len
= 0;
5412 size_t buf_pos
= p_tok
.get_buf_pos();
5413 dec_len
+= p_tok
.get_next_token(&token
, &name
, &name_len
);
5414 if (JSON_TOKEN_ERROR
== token
) {
5415 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG
, JSON_DEC_BAD_TOKEN_ERROR
, "");
5416 return JSON_ERROR_FATAL
;
5418 else if (JSON_TOKEN_NAME
!= token
) {
5419 // undo the last action on the buffer
5420 p_tok
.set_buf_pos(buf_pos
);
5426 for (field_idx
= 0; field_idx
< field_count
; ++field_idx
) {
5427 const char* expected_name
= 0;
5428 if (NULL
!= fld_descr(field_idx
)->json
&& NULL
!= fld_descr(field_idx
)->json
->alias
) {
5429 expected_name
= fld_descr(field_idx
)->json
->alias
;
5431 expected_name
= fld_name(field_idx
);
5433 if (strlen(expected_name
) == name_len
&&
5434 0 == strncmp(expected_name
, name
, name_len
)) {
5438 if (field_count
== field_idx
) {
5439 // invalid field name
5440 char* name2
= mcopystrn(name
, name_len
);
5441 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG
, JSON_DEC_INVALID_NAME_ERROR
, name2
);
5442 // if this is set to a warning, skip the value of the field
5443 dec_len
+= p_tok
.get_next_token(&token
, NULL
, NULL
);
5444 if (JSON_TOKEN_NUMBER
!= token
&& JSON_TOKEN_STRING
!= token
&&
5445 JSON_TOKEN_LITERAL_TRUE
!= token
&& JSON_TOKEN_LITERAL_FALSE
!= token
&&
5446 JSON_TOKEN_LITERAL_NULL
!= token
) {
5447 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG
, JSON_DEC_FIELD_TOKEN_ERROR
, name2
);
5449 return JSON_ERROR_FATAL
;
5455 int ret_val
= get_at(field_idx
)->JSON_decode(*fld_descr(field_idx
), p_tok
, p_silent
);
5457 if (JSON_ERROR_INVALID_TOKEN
) {
5458 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG
, JSON_DEC_FIELD_TOKEN_ERROR
, fld_name(field_idx
));
5460 return JSON_ERROR_FATAL
;
5466 dec_len
+= p_tok
.get_next_token(&token
, NULL
, NULL
);
5467 if (JSON_TOKEN_OBJECT_END
!= token
) {
5468 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG
, JSON_DEC_OBJECT_END_TOKEN_ERROR
, "");
5469 return JSON_ERROR_FATAL
;
5472 // Check if every field has been set
5473 for (int field_idx
= 0; field_idx
< field_count
; ++field_idx
) {
5474 Base_Type
* field
= get_at(field_idx
);
5475 if (!field
->is_bound()) {
5476 if (NULL
!= fld_descr(field_idx
)->json
&& NULL
!= fld_descr(field_idx
)->json
->default_value
) {
5477 get_at(field_idx
)->JSON_decode(*fld_descr(field_idx
), DUMMY_BUFFER
, p_silent
);
5479 else if (field
->is_optional()) {
5480 field
->set_to_omit();
5482 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG
, JSON_DEC_MISSING_FIELD_ERROR
, fld_name(field_idx
));
5483 return JSON_ERROR_FATAL
;
5491 ////////////////////////////////////////////////////////////////////////////////
5493 Empty_Record_Type::Empty_Record_Type(): bound_flag(FALSE
)
5497 Empty_Record_Type::Empty_Record_Type(const Empty_Record_Type
& other_value
)
5498 : Base_Type(other_value
), bound_flag(other_value
.bound_flag
)
5500 if (!other_value
.bound_flag
)
5501 TTCN_error("Copying an unbound value of type %s.",
5502 other_value
.get_descriptor()->name
);
5505 boolean
Empty_Record_Type::operator==(null_type
) const
5508 TTCN_error("Comparison of an unbound value of type %s.",
5509 get_descriptor()->name
);
5513 void Empty_Record_Type::log() const
5515 if (bound_flag
) TTCN_Logger::log_event_str("{ }");
5516 else TTCN_Logger::log_event_unbound();
5519 void Empty_Record_Type::set_param(Module_Param
& param
) {
5520 param
.basic_check(Module_Param::BC_VALUE
, "empty record/set value (i.e. { })");
5521 if (param
.get_type()!=Module_Param::MP_Value_List
|| param
.get_size()>0) {
5522 param
.type_error("empty record/set value (i.e. { })", get_descriptor()->name
);
5527 void Empty_Record_Type::encode_text(Text_Buf
& /*text_buf*/) const
5530 TTCN_error("Text encoder: Encoding an unbound value of type %s.",
5531 get_descriptor()->name
);
5534 void Empty_Record_Type::decode_text(Text_Buf
& /*text_buf*/)
5539 boolean
Empty_Record_Type::is_equal(const Base_Type
* other_value
) const
5541 const Empty_Record_Type
* r2
= static_cast<const Empty_Record_Type
*>(other_value
);
5542 if ((bound_flag
&& r2
->bound_flag
) || (!bound_flag
&& !r2
->bound_flag
))
5544 if (!bound_flag
|| !r2
->bound_flag
)
5545 TTCN_error("Comparison of an unbound value of type %s.", get_descriptor()->name
);
5549 void Empty_Record_Type::set_value(const Base_Type
* other_value
)
5551 if (!static_cast<const Empty_Record_Type
*>(other_value
)->is_bound())
5552 TTCN_error("Assignment of an unbound value of type %s.",
5553 other_value
->get_descriptor()->name
);
5557 void Empty_Record_Type::encode(const TTCN_Typedescriptor_t
& p_td
,
5558 TTCN_Buffer
& p_buf
, TTCN_EncDec::coding_t p_coding
, ...) const
5561 va_start(pvar
, p_coding
);
5563 case TTCN_EncDec::CT_BER
: {
5564 TTCN_EncDec_ErrorContext
ec("While BER-encoding type '%s': ", p_td
.name
);
5565 unsigned BER_coding
=va_arg(pvar
, unsigned);
5566 BER_encode_chk_coding(BER_coding
);
5567 ASN_BER_TLV_t
*tlv
=BER_encode_TLV(p_td
, BER_coding
);
5568 tlv
->put_in_buffer(p_buf
);
5569 ASN_BER_TLV_t::destruct(tlv
);
5571 case TTCN_EncDec::CT_RAW
: {
5572 TTCN_EncDec_ErrorContext
ec("While RAW-encoding type '%s': ", p_td
.name
);
5573 if(!p_td
.raw
) TTCN_EncDec_ErrorContext::error_internal
5574 ("No RAW descriptor available for type '%s'.", p_td
.name
);
5578 RAW_enc_tree
root(FALSE
, NULL
, &rp
, 1, p_td
.raw
);
5579 RAW_encode(p_td
, root
);
5580 root
.put_to_buf(p_buf
);
5582 case TTCN_EncDec::CT_TEXT
: {
5583 TTCN_EncDec_ErrorContext
ec("While TEXT-encoding type '%s': ", p_td
.name
);
5584 if(!p_td
.text
) TTCN_EncDec_ErrorContext::error_internal
5585 ("No TEXT descriptor available for type '%s'.", p_td
.name
);
5586 TEXT_encode(p_td
,p_buf
);
5588 case TTCN_EncDec::CT_XER
: {
5589 TTCN_EncDec_ErrorContext
ec("While XER-encoding type '%s': ", p_td
.name
);
5590 unsigned XER_coding
=va_arg(pvar
, unsigned);
5591 XER_encode(*(p_td
.xer
),p_buf
, XER_coding
, 0);
5594 case TTCN_EncDec::CT_JSON
: {
5595 TTCN_EncDec_ErrorContext
ec("While JSON-encoding type '%s': ", p_td
.name
);
5596 if(!p_td
.json
) TTCN_EncDec_ErrorContext::error_internal
5597 ("No JSON descriptor available for type '%s'.", p_td
.name
);
5598 JSON_Tokenizer
tok(va_arg(pvar
, int) != 0);
5599 JSON_encode(p_td
, tok
);
5600 p_buf
.put_s(tok
.get_buffer_length(), (const unsigned char*)tok
.get_buffer());
5603 TTCN_error("Unknown coding method requested to encode type '%s'", p_td
.name
);
5608 void Empty_Record_Type::decode(const TTCN_Typedescriptor_t
& p_td
,
5609 TTCN_Buffer
& p_buf
, TTCN_EncDec::coding_t p_coding
, ...)
5612 va_start(pvar
, p_coding
);
5614 case TTCN_EncDec::CT_BER
: {
5615 TTCN_EncDec_ErrorContext
ec("While BER-decoding type '%s': ", p_td
.name
);
5616 unsigned L_form
=va_arg(pvar
, unsigned);
5618 BER_decode_str2TLV(p_buf
, tlv
, L_form
);
5619 BER_decode_TLV(p_td
, tlv
, L_form
);
5620 if(tlv
.isComplete
) p_buf
.increase_pos(tlv
.get_len());
5622 case TTCN_EncDec::CT_RAW
: {
5623 TTCN_EncDec_ErrorContext
ec("While RAW-decoding type '%s': ", p_td
.name
);
5625 TTCN_EncDec_ErrorContext::error_internal
5626 ("No RAW descriptor available for type '%s'.", p_td
.name
);
5628 switch(p_td
.raw
->top_bit_order
) {
5636 if(RAW_decode(p_td
, p_buf
, p_buf
.get_len()*8, order
)<0)
5637 ec
.error(TTCN_EncDec::ET_INCOMPL_MSG
,
5638 "Can not decode type '%s', because invalid or incomplete"
5639 " message was received", p_td
.name
);
5641 case TTCN_EncDec::CT_TEXT
: {
5642 Limit_Token_List limit
;
5643 TTCN_EncDec_ErrorContext
ec("While TEXT-decoding type '%s': ", p_td
.name
);
5644 if(!p_td
.text
) TTCN_EncDec_ErrorContext::error_internal
5645 ("No TEXT descriptor available for type '%s'.", p_td
.name
);
5646 const unsigned char *b
=p_buf
.get_data();
5647 if(b
[p_buf
.get_len()-1]!='\0'){
5648 p_buf
.set_pos(p_buf
.get_len());
5649 p_buf
.put_zero(8,ORDER_LSB
);
5652 if(TEXT_decode(p_td
,p_buf
,limit
)<0)
5653 ec
.error(TTCN_EncDec::ET_INCOMPL_MSG
,
5654 "Can not decode type '%s', because invalid or incomplete"
5655 " message was received", p_td
.name
);
5657 case TTCN_EncDec::CT_XER
: {
5658 TTCN_EncDec_ErrorContext
ec("While XER-decoding type '%s': ", p_td
.name
);
5659 unsigned XER_coding
=va_arg(pvar
, unsigned);
5660 XmlReaderWrap
reader(p_buf
);
5661 for (int success
=reader
.Read(); success
==1; success
=reader
.Read()) {
5662 if (reader
.NodeType() == XML_READER_TYPE_ELEMENT
) break;
5664 XER_decode(*(p_td
.xer
), reader
, XER_coding
| XER_TOPLEVEL
);
5665 size_t bytes
= reader
.ByteConsumed();
5666 p_buf
.set_pos(bytes
);
5668 case TTCN_EncDec::CT_JSON
: {
5669 TTCN_EncDec_ErrorContext
ec("While JSON-decoding type '%s': ", p_td
.name
);
5670 if(!p_td
.json
) TTCN_EncDec_ErrorContext::error_internal
5671 ("No JSON descriptor available for type '%s'.", p_td
.name
);
5672 JSON_Tokenizer
tok((const char*)p_buf
.get_data(), p_buf
.get_len());
5673 if(JSON_decode(p_td
, tok
, false)<0)
5674 ec
.error(TTCN_EncDec::ET_INCOMPL_MSG
,
5675 "Can not decode type '%s', because invalid or incomplete"
5676 " message was received", p_td
.name
);
5677 p_buf
.set_pos(tok
.get_buf_pos());
5680 TTCN_error("Unknown coding method requested to decode type '%s'", p_td
.name
);
5685 ASN_BER_TLV_t
* Empty_Record_Type::BER_encode_TLV(const TTCN_Typedescriptor_t
& p_td
,
5686 unsigned p_coding
) const
5688 BER_chk_descr(p_td
);
5689 ASN_BER_TLV_t
*new_tlv
=ASN_BER_TLV_t::construct(NULL
);
5690 new_tlv
=ASN_BER_V2TLV(new_tlv
, p_td
, p_coding
);
5694 boolean
Empty_Record_Type::BER_decode_TLV(const TTCN_Typedescriptor_t
& p_td
,
5695 const ASN_BER_TLV_t
& p_tlv
, unsigned L_form
)
5697 BER_chk_descr(p_td
);
5698 ASN_BER_TLV_t stripped_tlv
;
5699 BER_decode_strip_tags(*p_td
.ber
, p_tlv
, L_form
, stripped_tlv
);
5700 TTCN_EncDec_ErrorContext
ec_0("While decoding '%s' type: ", get_descriptor()->name
);
5701 stripped_tlv
.chk_constructed_flag(TRUE
);
5706 int Empty_Record_Type::RAW_encode(const TTCN_Typedescriptor_t
& p_td
,
5707 RAW_enc_tree
& /*myleaf*/) const
5709 if (!bound_flag
) TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND
,
5710 "Encoding an unbound value of type %s.", p_td
.name
);
5714 int Empty_Record_Type::RAW_decode(const TTCN_Typedescriptor_t
& p_td
,
5715 TTCN_Buffer
& buff
, int /*limit*/, raw_order_t
/*top_bit_ord*/,
5716 boolean
/*no_err*/, int /*sel_field*/, boolean
/*first_call*/)
5719 return buff
.increase_pos_padd(p_td
.raw
->prepadding
)
5720 + buff
.increase_pos_padd(p_td
.raw
->padding
);
5723 int Empty_Record_Type::TEXT_encode(const TTCN_Typedescriptor_t
& p_td
, TTCN_Buffer
& buff
) const
5725 int encoded_length
=0;
5726 if(p_td
.text
->begin_encode
) {
5727 buff
.put_cs(*p_td
.text
->begin_encode
);
5728 encoded_length
+=p_td
.text
->begin_encode
->lengthof();
5731 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND
, "Encoding an unbound value.");
5733 if(p_td
.text
->end_encode
) {
5734 buff
.put_cs(*p_td
.text
->end_encode
);
5735 encoded_length
+=p_td
.text
->end_encode
->lengthof();
5737 return encoded_length
;
5740 int Empty_Record_Type::TEXT_decode(const TTCN_Typedescriptor_t
& p_td
,
5741 TTCN_Buffer
& buff
, Limit_Token_List
& /*limit*/, boolean no_err
, boolean
/*first_call*/)
5743 int decoded_length
=0;
5744 if(p_td
.text
->begin_decode
) {
5746 if((tl
=p_td
.text
->begin_decode
->match_begin(buff
))<0) {
5747 if(no_err
)return -1;
5748 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR
,
5749 "The specified token '%s' not found for '%s': ",
5750 (const char*)*(p_td
.text
->begin_decode
), p_td
.name
);
5754 buff
.increase_pos(tl
);
5756 if(p_td
.text
->end_decode
) {
5758 if((tl
=p_td
.text
->end_decode
->match_begin(buff
))<0) {
5759 if(no_err
)return -1;
5760 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR
,
5761 "The specified token '%s' not found for '%s': ",
5762 (const char*)*(p_td
.text
->end_decode
), p_td
.name
);
5766 buff
.increase_pos(tl
);
5769 return decoded_length
;
5772 int Empty_Record_Type::XER_encode(const XERdescriptor_t
& p_td
,
5773 TTCN_Buffer
& p_buf
, unsigned int flavor
, int indent
) const
5775 int encoded_length
=(int)p_buf
.get_len();
5776 int indenting
= !is_canonical(flavor
);
5777 int exer
= is_exer(flavor
);
5778 if (indenting
) do_indent(p_buf
, indent
);
5780 if (exer
) write_ns_prefix(p_td
, p_buf
);
5781 p_buf
.put_s((size_t)p_td
.namelens
[exer
]-2, (cbyte
*)p_td
.names
[exer
]);
5782 p_buf
.put_s(2 + indenting
, (cbyte
*)"/>\n");
5783 return (int)p_buf
.get_len() - encoded_length
;
5786 int Empty_Record_Type::XER_decode(const XERdescriptor_t
& p_td
,
5787 XmlReaderWrap
& reader
, unsigned int flavor
)
5789 int exer
= is_exer(flavor
);
5791 int success
, depth
= -1;
5792 for (success
=reader
.Ok(); success
==1; success
=reader
.Read()) {
5793 int type
= reader
.NodeType();
5794 if (type
==XML_READER_TYPE_ELEMENT
) {
5795 verify_name(reader
, p_td
, exer
);
5796 depth
= reader
.Depth();
5798 if (reader
.IsEmptyElement()) {
5799 reader
.Read(); break;
5801 else if ((flavor
& XER_MASK
) == XER_CANONICAL
) {
5802 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG
,
5803 "Expected an empty element tag");
5804 // Stay in the loop and look for the end element, in case the error
5805 // was ignored or reduced to warning.
5808 else if (type
== XML_READER_TYPE_END_ELEMENT
&& depth
!= -1) {
5809 verify_end(reader
, p_td
, depth
, exer
);
5814 return 1; // decode successful
5817 int Empty_Record_Type::JSON_encode(const TTCN_Typedescriptor_t
&, JSON_Tokenizer
& p_tok
) const
5820 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND
,
5821 "Encoding an unbound empty %s value.", is_set() ? "set" : "record");
5825 return p_tok
.put_next_token(JSON_TOKEN_OBJECT_START
, NULL
) +
5826 p_tok
.put_next_token(JSON_TOKEN_OBJECT_END
, NULL
);
5829 int Empty_Record_Type::JSON_decode(const TTCN_Typedescriptor_t
&, JSON_Tokenizer
& p_tok
, boolean p_silent
)
5831 json_token_t token
= JSON_TOKEN_NONE
;
5832 int dec_len
= p_tok
.get_next_token(&token
, NULL
, NULL
);
5833 if (JSON_TOKEN_ERROR
== token
) {
5834 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG
, JSON_DEC_BAD_TOKEN_ERROR
, "");
5835 return JSON_ERROR_FATAL
;
5837 else if (JSON_TOKEN_OBJECT_START
!= token
) {
5838 return JSON_ERROR_INVALID_TOKEN
;
5841 dec_len
+= p_tok
.get_next_token(&token
, NULL
, NULL
);
5842 if (JSON_TOKEN_OBJECT_END
!= token
) {
5843 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG
, JSON_DEC_STATIC_OBJECT_END_TOKEN_ERROR
, "");
5844 return JSON_ERROR_FATAL
;
5852 boolean
operator==(null_type
/*null_value*/, const Empty_Record_Type
& other_value
)
5854 if (!other_value
.is_bound())
5855 TTCN_error("Comparison of an unbound value of type %s.",
5856 other_value
.get_descriptor()->name
);
5860 boolean
operator!=(null_type
/*null_value*/, const Empty_Record_Type
& other_value
)
5862 if (!other_value
.is_bound())
5863 TTCN_error("Comparison of an unbound value of type %s.",
5864 other_value
.get_descriptor()->name
);