1 ///////////////////////////////////////////////////////////////////////////////
2 // Copyright (c) 2000-2015 Ericsson Telecom AB
3 // All rights reserved. This program and the accompanying materials
4 // are made available under the terms of the Eclipse Public License v1.0
5 // which accompanies this distribution, and is available at
6 // http://www.eclipse.org/legal/epl-v10.html
7 ///////////////////////////////////////////////////////////////////////////////
14 #include "Module_list.hh"
18 #ifdef TITAN_RUNTIME_2
21 #include "Charstring.hh"
22 #include "Universal_charstring.hh"
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
, embed_values_enc_struct_t
*) const
181 return XER_encode(p_td
, p_buf
, flavor
, indent
, 0); // 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 (NULL
== refd_ind_ptr
) {
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
), refd_ind_ptr(NULL
)
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
), RefdIndexInterface(other_value
)
259 , val_ptr(NULL
), err_descr(other_value
.err_descr
), refd_ind_ptr(NULL
)
261 if (!other_value
.is_bound())
262 TTCN_error("Copying an unbound record of/set of value.");
263 // Increment ref_count only if val_ptr is not NULL
264 if (other_value
.val_ptr
!= NULL
) {
265 if (NULL
== other_value
.refd_ind_ptr
) {
266 val_ptr
= other_value
.val_ptr
;
267 val_ptr
->ref_count
++;
270 // there are references to at least one element => the array must be copied
271 int nof_elements
= other_value
.get_nof_elements();
272 set_size(nof_elements
);
273 for (int i
= 0; i
< nof_elements
; ++i
) {
274 if (other_value
.is_elem_bound(i
)) {
275 val_ptr
->value_elements
[i
] = other_value
.val_ptr
->value_elements
[i
]->clone();
282 int Record_Of_Type::get_nof_elements() const
284 int nof_elements
= (val_ptr
!= NULL
) ? val_ptr
->n_elements
: 0;
285 if (NULL
!= refd_ind_ptr
) {
286 while (nof_elements
> 0) {
287 if (is_elem_bound(nof_elements
- 1)) {
296 bool Record_Of_Type::is_elem_bound(int index
) const
298 return val_ptr
->value_elements
[index
] != NULL
&&
299 val_ptr
->value_elements
[index
]->is_bound();
302 int Record_Of_Type::get_max_refd_index()
304 if (NULL
== refd_ind_ptr
) {
307 if (-1 == refd_ind_ptr
->max_refd_index
) {
308 for (size_t i
= 0; i
< refd_ind_ptr
->refd_indices
.size(); ++i
) {
309 if (refd_ind_ptr
->refd_indices
[i
] > refd_ind_ptr
->max_refd_index
) {
310 refd_ind_ptr
->max_refd_index
= refd_ind_ptr
->refd_indices
[i
];
314 return refd_ind_ptr
->max_refd_index
;
317 bool Record_Of_Type::is_index_refd(int index
)
319 if (NULL
== refd_ind_ptr
) {
322 for (size_t i
= 0; i
< refd_ind_ptr
->refd_indices
.size(); ++i
) {
323 if (index
== refd_ind_ptr
->refd_indices
[i
]) {
330 void Record_Of_Type::set_val(null_type
)
335 boolean
Record_Of_Type::is_equal(const Base_Type
* other_value
) const
337 const Record_Of_Type
* other_recof
= static_cast<const Record_Of_Type
*>(other_value
);
339 TTCN_error("The left operand of comparison is an unbound value of type %s.",
340 get_descriptor()->name
);
341 if (other_recof
->val_ptr
== NULL
)
342 TTCN_error("The right operand of comparison is an unbound value of type %s.",
343 other_value
->get_descriptor()->name
);
344 if (val_ptr
== other_recof
->val_ptr
) return TRUE
;
346 return compare_set_of(this, get_nof_elements(), other_recof
,
347 other_recof
->get_nof_elements(), compare_function
);
349 if (get_nof_elements() != other_recof
->get_nof_elements()) return FALSE
;
350 for (int elem_count
= 0; elem_count
< get_nof_elements(); elem_count
++) {
351 if (is_elem_bound(elem_count
)) {
352 if (other_recof
->is_elem_bound(elem_count
)) {
353 if (!val_ptr
->value_elements
[elem_count
]->is_equal(other_recof
->val_ptr
->value_elements
[elem_count
]))
356 } else if (other_recof
->is_elem_bound(elem_count
)) return FALSE
;
362 void Record_Of_Type::set_value(const Base_Type
* other_value
)
364 const Record_Of_Type
* other_recof
= static_cast<const Record_Of_Type
*>(other_value
);
365 if (!other_recof
->is_bound())
366 TTCN_error("Assigning an unbound value of type %s.",
367 other_value
->get_descriptor()->name
);
368 if (this != other_recof
) {
369 if (NULL
== refd_ind_ptr
&& NULL
== other_recof
->refd_ind_ptr
) {
371 val_ptr
= other_recof
->val_ptr
;
372 val_ptr
->ref_count
++;
375 // there are references to at least one element => the array must be copied
376 int nof_elements
= other_recof
->get_nof_elements();
377 set_size(nof_elements
);
378 for (int i
= 0; i
< nof_elements
; ++i
) {
379 if (other_recof
->is_elem_bound(i
)) {
380 if (val_ptr
->value_elements
[i
] == NULL
) {
381 val_ptr
->value_elements
[i
] = create_elem();
383 val_ptr
->value_elements
[i
]->set_value(other_recof
->val_ptr
->value_elements
[i
]);
385 else if (val_ptr
->value_elements
[i
] != NULL
) {
386 if (is_index_refd(i
)) {
387 val_ptr
->value_elements
[i
]->clean_up();
390 delete val_ptr
->value_elements
[i
];
391 val_ptr
->value_elements
[i
] = NULL
;
397 err_descr
= other_recof
->err_descr
;
400 boolean
Record_Of_Type::operator!=(null_type other_value
) const
402 return !(*this == other_value
);
405 Base_Type
* Record_Of_Type::get_at(int index_value
)
408 TTCN_error("Accessing an element of type %s using a negative index: %d.",
409 get_descriptor()->name
, index_value
);
410 if (val_ptr
== NULL
) {
411 val_ptr
= new recordof_setof_struct
;
412 val_ptr
->ref_count
= 1;
413 val_ptr
->n_elements
= 0;
414 val_ptr
->value_elements
= NULL
;
415 } else if (val_ptr
->ref_count
> 1) {
416 struct recordof_setof_struct
*new_val_ptr
= new recordof_setof_struct
;
417 new_val_ptr
->ref_count
= 1;
418 new_val_ptr
->n_elements
= (index_value
>= val_ptr
->n_elements
) ?
419 index_value
+ 1 : val_ptr
->n_elements
;
420 new_val_ptr
->value_elements
=
421 (Base_Type
**)allocate_pointers(new_val_ptr
->n_elements
);
422 for (int elem_count
= 0; elem_count
< val_ptr
->n_elements
; elem_count
++)
424 if (val_ptr
->value_elements
[elem_count
] != NULL
) {
425 new_val_ptr
->value_elements
[elem_count
] =
426 val_ptr
->value_elements
[elem_count
]->clone();
429 val_ptr
->ref_count
--;
430 val_ptr
= new_val_ptr
;
432 if (index_value
>= val_ptr
->n_elements
) set_size(index_value
+ 1);
433 if (val_ptr
->value_elements
[index_value
] == NULL
) {
434 val_ptr
->value_elements
[index_value
] = create_elem();
436 return val_ptr
->value_elements
[index_value
];
439 Base_Type
* Record_Of_Type::get_at(const INTEGER
& index_value
)
441 if (!index_value
.is_bound())
442 TTCN_error("Using an unbound integer value for indexing a value "
443 "of type %s.", get_descriptor()->name
);
444 return get_at((int)index_value
);
447 const Base_Type
* Record_Of_Type::get_at(int index_value
) const
450 TTCN_error("Accessing an element in an unbound value of type %s.",
451 get_descriptor()->name
);
453 TTCN_error("Accessing an element of type %s using a negative index: %d.",
454 get_descriptor()->name
, index_value
);
455 if (index_value
>= get_nof_elements())
456 TTCN_error("Index overflow in a value of type %s: The index is %d, but the "
457 "value has only %d elements.", get_descriptor()->name
, index_value
,
459 return (val_ptr
->value_elements
[index_value
] != NULL
) ?
460 val_ptr
->value_elements
[index_value
] : get_unbound_elem();
463 const Base_Type
* Record_Of_Type::get_at(const INTEGER
& index_value
) const
465 if (!index_value
.is_bound())
466 TTCN_error("Using an unbound integer value for indexing a value "
467 "of type %s.", get_descriptor()->name
);
468 return get_at((int)index_value
);
471 Record_Of_Type
* Record_Of_Type::rotl(const INTEGER
& rotate_count
, Record_Of_Type
* rec_of
) const
473 if (!rotate_count
.is_bound())
474 TTCN_error("Unbound integer operand of rotate left operator of type %s.",
475 get_descriptor()->name
);
476 return rotr((int)(-rotate_count
), rec_of
);
479 Record_Of_Type
* Record_Of_Type::rotr(const INTEGER
& rotate_count
, Record_Of_Type
* rec_of
) const
481 if (!rotate_count
.is_bound())
482 TTCN_error("Unbound integer operand of rotate right operator of type %s.",
483 get_descriptor()->name
);
484 return rotr((int)rotate_count
, rec_of
);
487 Record_Of_Type
* Record_Of_Type::rotr(int rotate_count
, Record_Of_Type
* rec_of
) const
490 TTCN_error("Performing rotation operation on an unbound value of type %s.",
491 get_descriptor()->name
);
492 int nof_elements
= get_nof_elements();
493 if (nof_elements
== 0) return const_cast<Record_Of_Type
*>(this);
495 if (rotate_count
>=0) rc
= rotate_count
% nof_elements
;
496 else rc
= nof_elements
- ((-rotate_count
) % nof_elements
);
497 if (rc
== 0) return const_cast<Record_Of_Type
*>(this);
498 rec_of
->set_size(nof_elements
);
500 for (int i
=0; i
<nof_elements
; i
++) {
501 rot_i
= (i
+rc
) % nof_elements
;
502 if (is_elem_bound(i
)) {
503 if (rec_of
->val_ptr
->value_elements
[rot_i
] == NULL
) {
504 rec_of
->val_ptr
->value_elements
[rot_i
] = rec_of
->create_elem();
506 rec_of
->val_ptr
->value_elements
[rot_i
]->set_value(val_ptr
->value_elements
[i
]);
507 } else if (rec_of
->is_elem_bound(rot_i
)) {
508 delete rec_of
->val_ptr
->value_elements
[rot_i
];
509 rec_of
->val_ptr
->value_elements
[rot_i
] = NULL
;
515 Record_Of_Type
* Record_Of_Type::concat(const Record_Of_Type
* other_value
,
516 Record_Of_Type
* rec_of
) const
518 if (val_ptr
== NULL
|| other_value
->val_ptr
== NULL
)
519 TTCN_error("Unbound operand of %s concatenation.", get_descriptor()->name
);
520 int nof_elements
= get_nof_elements();
521 if (nof_elements
== 0) return const_cast<Record_Of_Type
*>(other_value
);
522 int other_value_nof_elements
= other_value
->get_nof_elements();
523 if (other_value_nof_elements
== 0) return const_cast<Record_Of_Type
*>(this);
524 rec_of
->set_size(nof_elements
+ other_value_nof_elements
);
525 for (int i
=0; i
<nof_elements
; i
++) {
526 if (is_elem_bound(i
)) {
527 if (rec_of
->val_ptr
->value_elements
[i
] == NULL
) {
528 rec_of
->val_ptr
->value_elements
[i
] = rec_of
->create_elem();
530 rec_of
->val_ptr
->value_elements
[i
]->set_value(val_ptr
->value_elements
[i
]);
531 } else if (rec_of
->val_ptr
->value_elements
[i
] != NULL
) {
532 if (rec_of
->is_index_refd(i
)) {
533 rec_of
->val_ptr
->value_elements
[i
]->clean_up();
536 delete rec_of
->val_ptr
->value_elements
[i
];
537 rec_of
->val_ptr
->value_elements
[i
] = NULL
;
542 for (int i
=0; i
<other_value_nof_elements
; i
++) {
543 cat_i
= i
+ nof_elements
;
544 if (other_value
->is_elem_bound(i
)) {
545 if (rec_of
->val_ptr
->value_elements
[cat_i
] == NULL
) {
546 rec_of
->val_ptr
->value_elements
[cat_i
] = rec_of
->create_elem();
548 rec_of
->val_ptr
->value_elements
[cat_i
]->
549 set_value(other_value
->val_ptr
->value_elements
[i
]);
550 } else if (rec_of
->val_ptr
->value_elements
[cat_i
] != NULL
) {
551 if (rec_of
->is_index_refd(cat_i
)) {
552 rec_of
->val_ptr
->value_elements
[cat_i
]->clean_up();
555 delete rec_of
->val_ptr
->value_elements
[cat_i
];
556 rec_of
->val_ptr
->value_elements
[cat_i
] = NULL
;
563 void Record_Of_Type::substr_(int index
, int returncount
,
564 Record_Of_Type
* rec_of
) const
567 TTCN_error("The first argument of substr() is an unbound value of type %s.",
568 get_descriptor()->name
);
569 check_substr_arguments(get_nof_elements(), index
, returncount
,
570 get_descriptor()->name
, "element");
571 rec_of
->set_size(returncount
);
572 for (int i
=0; i
<returncount
; i
++) {
573 if (is_elem_bound(i
+ index
)) {
574 if (rec_of
->val_ptr
->value_elements
[i
] == NULL
) {
575 rec_of
->val_ptr
->value_elements
[i
] = rec_of
->create_elem();
577 rec_of
->val_ptr
->value_elements
[i
]->
578 set_value(val_ptr
->value_elements
[i
+index
]);
579 } else if (rec_of
->val_ptr
->value_elements
[i
] != NULL
) {
580 if (rec_of
->is_index_refd(i
)) {
581 rec_of
->val_ptr
->value_elements
[i
]->clean_up();
584 delete rec_of
->val_ptr
->value_elements
[i
];
585 rec_of
->val_ptr
->value_elements
[i
] = NULL
;
591 void Record_Of_Type::replace_(int index
, int len
,
592 const Record_Of_Type
* repl
, Record_Of_Type
* rec_of
) const
595 TTCN_error("The first argument of replace() is an unbound value "
596 "of type %s.", get_descriptor()->name
);
597 if (repl
->val_ptr
== NULL
)
598 TTCN_error("The fourth argument of replace() is an unbound value of "
599 "type %s.", get_descriptor()->name
);
600 int nof_elements
= get_nof_elements();
601 check_replace_arguments(nof_elements
, index
, len
,
602 get_descriptor()->name
, "element");
603 int repl_nof_elements
= repl
->get_nof_elements();
604 rec_of
->set_size(nof_elements
+ repl_nof_elements
- len
);
605 for (int i
= 0; i
< index
; i
++) {
606 if (is_elem_bound(i
)) {
607 if (rec_of
->val_ptr
->value_elements
[i
] == NULL
) {
608 rec_of
->val_ptr
->value_elements
[i
] = rec_of
->create_elem();
610 rec_of
->val_ptr
->value_elements
[i
]->set_value(val_ptr
->value_elements
[i
]);
611 } else if (rec_of
->val_ptr
->value_elements
[i
] != NULL
) {
612 if (rec_of
->is_index_refd(i
)) {
613 rec_of
->val_ptr
->value_elements
[i
]->clean_up();
616 delete rec_of
->val_ptr
->value_elements
[i
];
617 rec_of
->val_ptr
->value_elements
[i
] = NULL
;
621 for (int i
= 0; i
< repl_nof_elements
; i
++) {
622 if (repl
->is_elem_bound(i
)) {
623 if (rec_of
->val_ptr
->value_elements
[i
+index
] == NULL
) {
624 rec_of
->val_ptr
->value_elements
[i
+index
] = rec_of
->create_elem();
626 rec_of
->val_ptr
->value_elements
[i
+index
]->
627 set_value(repl
->val_ptr
->value_elements
[i
]);
628 } else if (rec_of
->val_ptr
->value_elements
[i
+index
] != NULL
) {
629 if (rec_of
->is_index_refd(i
+index
)) {
630 rec_of
->val_ptr
->value_elements
[i
+index
]->clean_up();
633 delete rec_of
->val_ptr
->value_elements
[i
+index
];
634 rec_of
->val_ptr
->value_elements
[i
+index
] = NULL
;
639 for (int i
= 0; i
< nof_elements
- index
- len
; i
++) {
640 repl_i
= index
+i
+repl_nof_elements
;
641 if (is_elem_bound(index
+i
+len
)) {
642 if (rec_of
->val_ptr
->value_elements
[repl_i
] == NULL
) {
643 rec_of
->val_ptr
->value_elements
[repl_i
] = rec_of
->create_elem();
645 rec_of
->val_ptr
->value_elements
[repl_i
]->
646 set_value(val_ptr
->value_elements
[index
+i
+len
]);
647 } else if (rec_of
->val_ptr
->value_elements
[repl_i
] != NULL
) {
648 if (rec_of
->is_index_refd(repl_i
)) {
649 rec_of
->val_ptr
->value_elements
[repl_i
]->clean_up();
652 delete rec_of
->val_ptr
->value_elements
[repl_i
];
653 rec_of
->val_ptr
->value_elements
[repl_i
] = NULL
;
659 void Record_Of_Type::replace_(int index
, int len
,
660 const Record_Of_Template
* repl
, Record_Of_Type
* rec_of
) const
662 if (!repl
->is_value())
663 TTCN_error("The fourth argument of function replace() is a template "
664 "of type %s with non-specific value.", get_descriptor()->name
);
665 rec_of
->set_val(NULL_VALUE
);
666 Base_Type
* repl_value
= rec_of
->clone();
667 repl
->valueofv(repl_value
);
668 replace_(index
, len
, static_cast<Record_Of_Type
*>(repl_value
), rec_of
);
672 void Record_Of_Type::replace_(int index
, int len
,
673 const Set_Of_Template
* repl
, Record_Of_Type
* rec_of
) const
675 if (!repl
->is_value())
676 TTCN_error("The fourth argument of function replace() is a template "
677 "of type %s with non-specific value.", get_descriptor()->name
);
678 rec_of
->set_val(NULL_VALUE
);
679 Base_Type
* repl_value
= rec_of
->clone();
680 repl
->valueofv(repl_value
);
681 replace_(index
, len
, static_cast<Record_Of_Type
*>(repl_value
), rec_of
);
685 void Record_Of_Type::set_size(int new_size
)
688 TTCN_error("Internal error: Setting a negative size for a value of "
689 "type %s.", get_descriptor()->name
);
690 if (val_ptr
== NULL
) {
691 val_ptr
= new recordof_setof_struct
;
692 val_ptr
->ref_count
= 1;
693 val_ptr
->n_elements
= 0;
694 val_ptr
->value_elements
= NULL
;
695 } else if (val_ptr
->ref_count
> 1) {
696 struct recordof_setof_struct
*new_val_ptr
= new recordof_setof_struct
;
697 new_val_ptr
->ref_count
= 1;
698 new_val_ptr
->n_elements
= (new_size
< val_ptr
->n_elements
) ?
699 new_size
: val_ptr
->n_elements
;
700 new_val_ptr
->value_elements
=
701 (Base_Type
**)allocate_pointers(new_val_ptr
->n_elements
);
702 for (int elem_count
= 0; elem_count
< new_val_ptr
->n_elements
; elem_count
++) {
703 if (val_ptr
->value_elements
[elem_count
] != NULL
) {
704 new_val_ptr
->value_elements
[elem_count
] =
705 val_ptr
->value_elements
[elem_count
]->clone();
709 val_ptr
= new_val_ptr
;
711 if (new_size
> val_ptr
->n_elements
) {
712 val_ptr
->value_elements
= (Base_Type
**)
713 reallocate_pointers((void**)val_ptr
->value_elements
, val_ptr
->n_elements
, new_size
);
714 val_ptr
->n_elements
= new_size
;
715 } else if (new_size
< val_ptr
->n_elements
) {
716 for (int elem_count
= new_size
; elem_count
< val_ptr
->n_elements
; elem_count
++) {
717 if (val_ptr
->value_elements
[elem_count
] != NULL
) {
718 if (is_index_refd(elem_count
)) {
719 val_ptr
->value_elements
[elem_count
]->clean_up();
722 delete val_ptr
->value_elements
[elem_count
];
723 val_ptr
->value_elements
[elem_count
] = 0;
727 if (new_size
<= get_max_refd_index()) {
728 new_size
= get_max_refd_index() + 1;
730 if (new_size
< val_ptr
->n_elements
) {
731 val_ptr
->value_elements
= (Base_Type
**)
732 reallocate_pointers((void**)val_ptr
->value_elements
, val_ptr
->n_elements
, new_size
);
733 val_ptr
->n_elements
= new_size
;
738 boolean
Record_Of_Type::is_bound() const
740 if (NULL
== refd_ind_ptr
) {
741 return (val_ptr
!= NULL
);
743 return (get_nof_elements() != 0);
746 boolean
Record_Of_Type::is_value() const
748 if (val_ptr
== NULL
) return FALSE
;
749 for (int i
=0; i
< get_nof_elements(); ++i
)
750 if (!is_elem_bound(i
) ||
751 !val_ptr
->value_elements
[i
]->is_value()) return FALSE
;
755 int Record_Of_Type::size_of() const
758 TTCN_error("Performing sizeof operation on an unbound value of type %s.",
759 get_descriptor()->name
);
760 return get_nof_elements();
763 int Record_Of_Type::lengthof() const
766 TTCN_error("Performing lengthof operation on an unbound value of "
767 "type %s.", get_descriptor()->name
);
768 for (int my_length
=get_nof_elements(); my_length
>0; my_length
--)
769 if (is_elem_bound(my_length
- 1)) return my_length
;
773 void Record_Of_Type::log() const
775 if (val_ptr
== NULL
) {
776 TTCN_Logger::log_event_unbound();
779 if (get_nof_elements()==0) {
780 TTCN_Logger::log_event_str("{ }");
782 TTCN_Logger::log_event_str("{ ");
783 for (int elem_count
= 0; elem_count
< get_nof_elements(); elem_count
++) {
784 if (elem_count
> 0) TTCN_Logger::log_event_str(", ");
785 get_at(elem_count
)->log();
787 TTCN_Logger::log_event_str(" }");
789 if (err_descr
) err_descr
->log();
792 void Record_Of_Type::encode_text(Text_Buf
& text_buf
) const
795 TTCN_error("Text encoder: Encoding an unbound value of type %s.",
796 get_descriptor()->name
);
797 text_buf
.push_int(get_nof_elements());
798 for (int elem_count
= 0; elem_count
< get_nof_elements(); elem_count
++)
799 get_at(elem_count
)->encode_text(text_buf
);
802 void Record_Of_Type::decode_text(Text_Buf
& text_buf
)
804 int new_size
= text_buf
.pull_int().get_val();
806 TTCN_error("Text decoder: Negative size was received for a value of "
807 "type %s.", get_descriptor()->name
);
809 for (int elem_count
= 0; elem_count
< new_size
; elem_count
++) {
810 if (val_ptr
->value_elements
[elem_count
] == NULL
) {
811 val_ptr
->value_elements
[elem_count
] = create_elem();
813 val_ptr
->value_elements
[elem_count
]->decode_text(text_buf
);
817 boolean
Record_Of_Type::operator==(null_type
/*other_value*/) const
820 TTCN_error("The left operand of comparison is an unbound value of type %s.",
821 get_descriptor()->name
);
822 return get_nof_elements() == 0;
825 int Record_Of_Type::rawdec_ebv() const
827 TTCN_error("Internal error: Record_Of_Type::rawdec_ebv() called.");
830 boolean
Record_Of_Type::isXerAttribute() const
832 TTCN_error("Internal error: Record_Of_Type::isXerAttribute() called.");
835 boolean
Record_Of_Type::isXmlValueList() const
837 TTCN_error("Internal error: Record_Of_Type::isXmlValueList() called.");
840 int Record_Of_Type::TEXT_encode(const TTCN_Typedescriptor_t
& p_td
,
841 TTCN_Buffer
& buff
) const
844 return TEXT_encode_negtest(err_descr
, p_td
, buff
);
846 int encoded_length
=0;
847 if(p_td
.text
->begin_encode
) {
848 buff
.put_cs(*p_td
.text
->begin_encode
);
849 encoded_length
+=p_td
.text
->begin_encode
->lengthof();
852 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND
,
853 "Encoding an unbound value.");
854 if(p_td
.text
->end_encode
) {
855 buff
.put_cs(*p_td
.text
->end_encode
);
856 encoded_length
+=p_td
.text
->end_encode
->lengthof();
858 return encoded_length
;
860 const TTCN_Typedescriptor_t
* elem_descr
= p_td
.oftype_descr
;
861 for(int a
=0;a
<get_nof_elements();a
++) {
862 if(a
!=0 && p_td
.text
->separator_encode
) {
863 buff
.put_cs(*p_td
.text
->separator_encode
);
864 encoded_length
+=p_td
.text
->separator_encode
->lengthof();
866 encoded_length
+=get_at(a
)->TEXT_encode(*elem_descr
,buff
);
868 if(p_td
.text
->end_encode
) {
869 buff
.put_cs(*p_td
.text
->end_encode
);
870 encoded_length
+=p_td
.text
->end_encode
->lengthof();
872 return encoded_length
;
876 * TEXT encode for negative testing
878 int Record_Of_Type::TEXT_encode_negtest(const Erroneous_descriptor_t
* p_err_descr
, const TTCN_Typedescriptor_t
& p_td
,
879 TTCN_Buffer
& buff
) const
881 bool need_separator
=false;
882 int encoded_length
=0;
883 if(p_td
.text
->begin_encode
) {
884 buff
.put_cs(*p_td
.text
->begin_encode
);
885 encoded_length
+=p_td
.text
->begin_encode
->lengthof();
888 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND
,
889 "Encoding an unbound value.");
890 if(p_td
.text
->end_encode
) {
891 buff
.put_cs(*p_td
.text
->end_encode
);
892 encoded_length
+=p_td
.text
->end_encode
->lengthof();
894 return encoded_length
;
900 for(int a
=0;a
<get_nof_elements();a
++) {
901 if ( (p_err_descr
->omit_before
!=-1) && (a
<p_err_descr
->omit_before
) ) continue;
902 const Erroneous_values_t
* err_vals
= p_err_descr
->next_field_err_values(a
, values_idx
);
903 const Erroneous_descriptor_t
* emb_descr
= p_err_descr
->next_field_emb_descr(a
, edescr_idx
);
905 if (err_vals
&& err_vals
->before
) {
906 if (err_vals
->before
->errval
==NULL
) TTCN_error(
907 "internal error: erroneous before value missing");
908 if (need_separator
&& p_td
.text
->separator_encode
) {
909 buff
.put_cs(*p_td
.text
->separator_encode
);
910 encoded_length
+=p_td
.text
->separator_encode
->lengthof();
912 if (err_vals
->before
->raw
) {
913 encoded_length
+= err_vals
->before
->errval
->encode_raw(buff
);
915 if (err_vals
->before
->type_descr
==NULL
) TTCN_error(
916 "internal error: erroneous before typedescriptor missing");
917 encoded_length
+= err_vals
->before
->errval
->TEXT_encode(
918 *(err_vals
->before
->type_descr
),buff
);
923 if (err_vals
&& err_vals
->value
) {
924 if (err_vals
->value
->errval
) {
925 if (need_separator
&& p_td
.text
->separator_encode
) {
926 buff
.put_cs(*p_td
.text
->separator_encode
);
927 encoded_length
+=p_td
.text
->separator_encode
->lengthof();
929 if (err_vals
->value
->raw
) {
930 encoded_length
+= err_vals
->value
->errval
->encode_raw(buff
);
932 if (err_vals
->value
->type_descr
==NULL
) TTCN_error(
933 "internal error: erroneous value typedescriptor missing");
934 encoded_length
+= err_vals
->value
->errval
->TEXT_encode(
935 *(err_vals
->value
->type_descr
),buff
);
940 if (need_separator
&& p_td
.text
->separator_encode
) {
941 buff
.put_cs(*p_td
.text
->separator_encode
);
942 encoded_length
+=p_td
.text
->separator_encode
->lengthof();
945 encoded_length
+= get_at(a
)->TEXT_encode_negtest(
946 emb_descr
,*p_td
.oftype_descr
,buff
);
948 encoded_length
+= get_at(a
)->TEXT_encode(*p_td
.oftype_descr
,buff
);
953 if (err_vals
&& err_vals
->after
) {
954 if (err_vals
->after
->errval
==NULL
) TTCN_error(
955 "internal error: erroneous after value missing");
956 if (need_separator
&& p_td
.text
->separator_encode
) {
957 buff
.put_cs(*p_td
.text
->separator_encode
);
958 encoded_length
+=p_td
.text
->separator_encode
->lengthof();
960 if (err_vals
->after
->raw
) {
961 encoded_length
+= err_vals
->after
->errval
->encode_raw(buff
);
963 if (err_vals
->after
->type_descr
==NULL
) TTCN_error(
964 "internal error: erroneous after typedescriptor missing");
965 encoded_length
+= err_vals
->after
->errval
->TEXT_encode(
966 *(err_vals
->after
->type_descr
),buff
);
971 if ( (p_err_descr
->omit_after
!=-1) && (a
>=p_err_descr
->omit_after
) ) break;
973 if(p_td
.text
->end_encode
) {
974 buff
.put_cs(*p_td
.text
->end_encode
);
975 encoded_length
+=p_td
.text
->end_encode
->lengthof();
977 return encoded_length
;
980 int Record_Of_Type::TEXT_decode(const TTCN_Typedescriptor_t
& p_td
,
981 TTCN_Buffer
& buff
, Limit_Token_List
& limit
, boolean no_err
,
984 int decoded_length
=0;
986 boolean sep_found
=FALSE
;
989 if(p_td
.text
->begin_decode
){
991 if((tl
=p_td
.text
->begin_decode
->match_begin(buff
))<0){
993 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR
,
994 "The specified token '%s' not found for '%s': ",
995 (const char*)*(p_td
.text
->begin_decode
), p_td
.name
);
999 buff
.increase_pos(tl
);
1001 if(p_td
.text
->end_decode
){
1002 limit
.add_token(p_td
.text
->end_decode
);
1005 if(p_td
.text
->separator_decode
){
1006 limit
.add_token(p_td
.text
->separator_decode
);
1012 int more
=get_nof_elements();
1014 Base_Type
* val
= create_elem();
1016 int len
= val
->TEXT_decode(*p_td
.oftype_descr
,buff
,limit
,TRUE
);
1017 if(len
==-1 || (len
==0 && !limit
.has_token())){
1021 buff
.set_pos(buff
.get_pos()-sep_length
);
1022 decoded_length
-=sep_length
;
1027 if (NULL
== refd_ind_ptr
) {
1028 val_ptr
->value_elements
= (Base_Type
**)reallocate_pointers(
1029 (void**)val_ptr
->value_elements
, val_ptr
->n_elements
, val_ptr
->n_elements
+ 1);
1030 val_ptr
->value_elements
[val_ptr
->n_elements
]=val
;
1031 val_ptr
->n_elements
++;
1034 get_at(get_nof_elements())->set_value(val
);
1037 decoded_length
+=len
;
1038 if(p_td
.text
->separator_decode
){
1040 if((tl
=p_td
.text
->separator_decode
->match_begin(buff
))<0){
1044 buff
.increase_pos(tl
);
1047 } else if(p_td
.text
->end_decode
){
1049 if((tl
=p_td
.text
->end_decode
->match_begin(buff
))!=-1){
1051 buff
.increase_pos(tl
);
1052 limit
.remove_tokens(ml
);
1053 return decoded_length
;
1055 } else if(limit
.has_token(ml
)){
1057 if((tl
=limit
.match(buff
,ml
))==0){
1063 limit
.remove_tokens(ml
);
1064 if(p_td
.text
->end_decode
){
1066 if((tl
=p_td
.text
->end_decode
->match_begin(buff
))<0){
1073 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR
,
1074 "The specified token '%s' not found for '%s': ",
1075 (const char*)*(p_td
.text
->end_decode
), p_td
.name
);
1076 return decoded_length
;
1079 buff
.increase_pos(tl
);
1081 if(get_nof_elements()==0){
1082 if (!p_td
.text
->end_decode
&& !p_td
.text
->begin_decode
) {
1083 if(no_err
)return -1;
1084 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR
,
1085 "No record/set of member found.");
1086 return decoded_length
;
1089 if(!first_call
&& more
==get_nof_elements() &&
1090 !(p_td
.text
->end_decode
|| p_td
.text
->begin_decode
)) return -1;
1091 return decoded_length
;
1094 ASN_BER_TLV_t
* Record_Of_Type::BER_encode_TLV(const TTCN_Typedescriptor_t
& p_td
,
1095 unsigned p_coding
) const
1098 return BER_encode_TLV_negtest(err_descr
, p_td
, p_coding
);
1100 BER_chk_descr(p_td
);
1101 ASN_BER_TLV_t
*new_tlv
=BER_encode_chk_bound(is_bound());
1103 new_tlv
=ASN_BER_TLV_t::construct(NULL
);
1104 TTCN_EncDec_ErrorContext ec
;
1105 for(int elem_i
=0; elem_i
<get_nof_elements(); elem_i
++) {
1106 ec
.set_msg("Component #%d: ", elem_i
);
1107 new_tlv
->add_TLV(get_at(elem_i
)->BER_encode_TLV(*p_td
.oftype_descr
, p_coding
));
1109 if (is_set()) new_tlv
->sort_tlvs();
1111 new_tlv
=ASN_BER_V2TLV(new_tlv
, p_td
, p_coding
);
1115 ASN_BER_TLV_t
* Record_Of_Type::BER_encode_TLV_negtest(const Erroneous_descriptor_t
* p_err_descr
,
1116 const TTCN_Typedescriptor_t
& p_td
, unsigned p_coding
) const
1118 BER_chk_descr(p_td
);
1119 ASN_BER_TLV_t
*new_tlv
=BER_encode_chk_bound(is_bound());
1121 new_tlv
=ASN_BER_TLV_t::construct(NULL
);
1122 TTCN_EncDec_ErrorContext ec
;
1125 for (int elem_i
=0; elem_i
<get_nof_elements(); elem_i
++) {
1126 if ( (p_err_descr
->omit_before
!=-1) && (elem_i
<p_err_descr
->omit_before
) ) continue;
1127 const Erroneous_values_t
* err_vals
= p_err_descr
->next_field_err_values(elem_i
, values_idx
);
1128 const Erroneous_descriptor_t
* emb_descr
= p_err_descr
->next_field_emb_descr(elem_i
, edescr_idx
);
1130 if (err_vals
&& err_vals
->before
) {
1131 if (err_vals
->before
->errval
==NULL
) TTCN_error(
1132 "internal error: erroneous before value missing");
1133 ec
.set_msg("Erroneous value before component #%d: ", elem_i
);
1134 if (err_vals
->before
->raw
) {
1135 new_tlv
->add_TLV(err_vals
->before
->errval
->BER_encode_negtest_raw());
1137 if (err_vals
->before
->type_descr
==NULL
) TTCN_error(
1138 "internal error: erroneous before typedescriptor missing");
1139 new_tlv
->add_TLV(err_vals
->before
->errval
->BER_encode_TLV(
1140 *err_vals
->before
->type_descr
, p_coding
));
1144 if (err_vals
&& err_vals
->value
) {
1145 if (err_vals
->value
->errval
) { // replace
1146 ec
.set_msg("Erroneous value for component #%d: ", elem_i
);
1147 if (err_vals
->value
->raw
) {
1148 new_tlv
->add_TLV(err_vals
->value
->errval
->BER_encode_negtest_raw());
1150 if (err_vals
->value
->type_descr
==NULL
) TTCN_error(
1151 "internal error: erroneous value typedescriptor missing");
1152 new_tlv
->add_TLV(err_vals
->value
->errval
->BER_encode_TLV(
1153 *err_vals
->value
->type_descr
, p_coding
));
1157 ec
.set_msg("Component #%d: ", elem_i
);
1159 new_tlv
->add_TLV(get_at(elem_i
)->BER_encode_TLV_negtest(
1160 emb_descr
, *p_td
.oftype_descr
, p_coding
));
1162 new_tlv
->add_TLV(get_at(elem_i
)->BER_encode_TLV(
1163 *p_td
.oftype_descr
, p_coding
));
1167 if (err_vals
&& err_vals
->after
) {
1168 if (err_vals
->after
->errval
==NULL
) TTCN_error(
1169 "internal error: erroneous after value missing");
1170 ec
.set_msg("Erroneous value after component #%d: ", elem_i
);
1171 if (err_vals
->after
->raw
) {
1172 new_tlv
->add_TLV(err_vals
->after
->errval
->BER_encode_negtest_raw());
1174 if (err_vals
->after
->type_descr
==NULL
) TTCN_error(
1175 "internal error: erroneous after typedescriptor missing");
1176 new_tlv
->add_TLV(err_vals
->after
->errval
->BER_encode_TLV(
1177 *err_vals
->after
->type_descr
, p_coding
));
1181 if ( (p_err_descr
->omit_after
!=-1) && (elem_i
>=p_err_descr
->omit_after
) ) break;
1183 if (is_set()) new_tlv
->sort_tlvs();
1185 new_tlv
=ASN_BER_V2TLV(new_tlv
, p_td
, p_coding
);
1189 boolean
Record_Of_Type::BER_decode_TLV(const TTCN_Typedescriptor_t
& p_td
,
1190 const ASN_BER_TLV_t
& p_tlv
, unsigned L_form
)
1192 BER_chk_descr(p_td
);
1193 ASN_BER_TLV_t stripped_tlv
;
1194 BER_decode_strip_tags(*p_td
.ber
, p_tlv
, L_form
, stripped_tlv
);
1195 TTCN_EncDec_ErrorContext
ec_0("While decoding '%s' type: ", p_td
.name
);
1196 stripped_tlv
.chk_constructed_flag(TRUE
);
1199 ASN_BER_TLV_t tmp_tlv
;
1200 TTCN_EncDec_ErrorContext
ec_1("Component #");
1201 TTCN_EncDec_ErrorContext
ec_2("0: ");
1202 while(BER_decode_constdTLV_next(stripped_tlv
, V_pos
, L_form
, tmp_tlv
)) {
1203 get_at(get_nof_elements())->BER_decode_TLV(*p_td
.oftype_descr
, tmp_tlv
, L_form
);
1204 ec_2
.set_msg("%d: ", val_ptr
->n_elements
);
1209 void Record_Of_Type::BER_decode_opentypes(TTCN_Type_list
& p_typelist
,
1212 p_typelist
.push(this);
1213 TTCN_EncDec_ErrorContext
ec_0("Component #");
1214 TTCN_EncDec_ErrorContext ec_1
;
1215 for(int elem_i
=0; elem_i
<get_nof_elements(); elem_i
++) {
1216 ec_1
.set_msg("%d: ", elem_i
);
1217 get_at(elem_i
)->BER_decode_opentypes(p_typelist
, L_form
);
1223 int Record_Of_Type::RAW_decode(const TTCN_Typedescriptor_t
& p_td
,
1224 TTCN_Buffer
& buff
, int limit
, raw_order_t top_bit_ord
, boolean
/*no_err*/,
1225 int sel_field
, boolean first_call
)
1227 int prepaddlength
= buff
.increase_pos_padd(p_td
.raw
->prepadding
);
1228 limit
-= prepaddlength
;
1229 int decoded_length
= 0;
1230 int decoded_field_length
= 0;
1231 size_t start_of_field
= 0;
1235 int start_field
= get_nof_elements(); // append at the end
1236 TTCN_Typedescriptor_t
const& elem_descr
= *p_td
.oftype_descr
;
1237 if (p_td
.raw
->fieldlength
|| sel_field
!= -1) {
1238 if (sel_field
== -1) sel_field
= p_td
.raw
->fieldlength
;
1239 for (int a
= 0; a
< sel_field
; a
++) {
1240 Base_Type
* field_bt
= get_at(a
+ start_field
);
1241 decoded_field_length
= field_bt
->RAW_decode(elem_descr
, buff
, limit
,
1243 if (decoded_field_length
< 0) return decoded_field_length
;
1244 decoded_length
+= decoded_field_length
;
1245 limit
-= decoded_field_length
;
1249 int a
= start_field
;
1251 if (!first_call
) return -1;
1255 start_of_field
= buff
.get_pos_bit();
1256 Base_Type
* field_bt
= get_at(a
); // non-const, extend the record-of
1257 decoded_field_length
= field_bt
->RAW_decode(elem_descr
, buff
, limit
,
1259 if (decoded_field_length
< 0) { // decoding failed, shorten the record-of
1260 set_size(get_nof_elements() - 1);
1261 buff
.set_pos_bit(start_of_field
);
1262 if (a
> start_field
) {
1265 else return decoded_field_length
;
1267 decoded_length
+= decoded_field_length
;
1268 limit
-= decoded_field_length
;
1270 if (EXT_BIT_NO
!= p_td
.raw
->extension_bit
) {
1271 // (EXT_BIT_YES != p_td.raw->extension_bit) is 0 or 1
1272 // This is the opposite value of what the bit needs to be to signal
1273 // the end of decoding, because x-or is the equivalent of !=
1274 if ((EXT_BIT_YES
!= p_td
.raw
->extension_bit
) ^ buff
.get_last_bit()) {
1281 return decoded_length
+ buff
.increase_pos_padd(p_td
.raw
->padding
) + prepaddlength
;
1284 int Record_Of_Type::RAW_encode(const TTCN_Typedescriptor_t
& p_td
, RAW_enc_tree
& myleaf
) const
1286 if (err_descr
) return RAW_encode_negtest(err_descr
, p_td
, myleaf
);
1287 int encoded_length
= 0;
1288 int nof_elements
= get_nof_elements();
1289 int encoded_num_of_records
=
1290 p_td
.raw
->fieldlength
? (nof_elements
< p_td
.raw
->fieldlength
? nof_elements
: p_td
.raw
->fieldlength
)
1292 myleaf
.isleaf
= FALSE
;
1293 myleaf
.rec_of
= TRUE
;
1294 myleaf
.body
.node
.num_of_nodes
= encoded_num_of_records
;
1295 myleaf
.body
.node
.nodes
= init_nodes_of_enc_tree(encoded_num_of_records
);
1296 TTCN_Typedescriptor_t
const& elem_descr
= *p_td
.oftype_descr
;
1297 for (int a
= 0; a
< encoded_num_of_records
; a
++) {
1298 const Base_Type
*field_bt
= get_at(a
);
1299 myleaf
.body
.node
.nodes
[a
] = new RAW_enc_tree(TRUE
, &myleaf
, &(myleaf
.curr_pos
), a
, elem_descr
.raw
);
1300 encoded_length
+= field_bt
->RAW_encode(elem_descr
, *myleaf
.body
.node
.nodes
[a
]);
1302 return myleaf
.length
= encoded_length
;
1305 int Record_Of_Type::RAW_encode_negtest(const Erroneous_descriptor_t
*p_err_descr
,
1306 const TTCN_Typedescriptor_t
& p_td
, RAW_enc_tree
& myleaf
) const
1310 int nof_elements
= get_nof_elements();
1311 // It can be more, of course...
1312 int encoded_num_of_records
=
1313 p_td
.raw
->fieldlength
? (nof_elements
< p_td
.raw
->fieldlength
? nof_elements
: p_td
.raw
->fieldlength
)
1315 for (int i
= 0; i
< nof_elements
; ++i
) {
1316 if ((p_err_descr
->omit_before
!= -1) && (i
< p_err_descr
->omit_before
)) {
1317 --encoded_num_of_records
;
1320 const Erroneous_values_t
*err_vals
=
1321 p_err_descr
->next_field_err_values(i
, values_idx
);
1322 // Not checking any further, `internal error' will be given anyway in the
1323 // next round. Please note that elements can be removed, `omitted'.
1324 if (err_vals
&& err_vals
->before
)
1325 ++encoded_num_of_records
;
1326 if (err_vals
&& err_vals
->value
&& !err_vals
->value
->errval
)
1327 --encoded_num_of_records
;
1328 if (err_vals
&& err_vals
->after
)
1329 ++encoded_num_of_records
;
1330 if ((p_err_descr
->omit_after
!= -1) && (i
>= p_err_descr
->omit_after
)) {
1331 encoded_num_of_records
= encoded_num_of_records
- (nof_elements
- i
) + 1;
1335 myleaf
.body
.node
.num_of_nodes
= encoded_num_of_records
;
1336 myleaf
.body
.node
.nodes
= init_nodes_of_enc_tree(encoded_num_of_records
);
1337 int encoded_length
= 0;
1338 myleaf
.isleaf
= FALSE
;
1339 myleaf
.rec_of
= TRUE
;
1342 for (int i
= 0; i
< nof_elements
; ++i
) {
1343 if ((p_err_descr
->omit_before
!= -1) && (i
< p_err_descr
->omit_before
))
1345 const Erroneous_values_t
*err_vals
= p_err_descr
->next_field_err_values(i
, values_idx
);
1346 const Erroneous_descriptor_t
*emb_descr
= p_err_descr
->next_field_emb_descr(i
, edescr_idx
);
1347 TTCN_Typedescriptor_t
const& elem_descr
= *p_td
.oftype_descr
;
1348 if (err_vals
&& err_vals
->before
) {
1349 if (err_vals
->before
->errval
== NULL
)
1350 TTCN_error("internal error: erroneous before value missing");
1351 if (err_vals
->before
->raw
) {
1352 myleaf
.body
.node
.nodes
[node_pos
] = new RAW_enc_tree(true, &myleaf
,
1353 &(myleaf
.curr_pos
), node_pos
,
1354 err_vals
->before
->errval
->get_descriptor()->raw
);
1355 encoded_length
+= err_vals
->before
->errval
->
1356 RAW_encode_negtest_raw(*myleaf
.body
.node
.nodes
[node_pos
++]);
1358 if (err_vals
->before
->type_descr
== NULL
)
1359 TTCN_error("internal error: erroneous before typedescriptor missing");
1360 myleaf
.body
.node
.nodes
[node_pos
] = new RAW_enc_tree(TRUE
, &myleaf
,
1361 &(myleaf
.curr_pos
), node_pos
, elem_descr
.raw
);
1362 encoded_length
+= err_vals
->before
->errval
->
1363 RAW_encode(*(err_vals
->before
->type_descr
),
1364 *myleaf
.body
.node
.nodes
[node_pos
++]);
1367 if (err_vals
&& err_vals
->value
) {
1368 if (err_vals
->value
->errval
) {
1369 if (err_vals
->value
->raw
) {
1370 myleaf
.body
.node
.nodes
[node_pos
] = new RAW_enc_tree(true, &myleaf
,
1371 &(myleaf
.curr_pos
), node_pos
,
1372 err_vals
->value
->errval
->get_descriptor()->raw
);
1373 encoded_length
+= err_vals
->value
->errval
->
1374 RAW_encode_negtest_raw(*myleaf
.body
.node
.nodes
[node_pos
++]);
1376 if (err_vals
->value
->type_descr
== NULL
)
1377 TTCN_error("internal error: erroneous value typedescriptor missing");
1378 myleaf
.body
.node
.nodes
[node_pos
] = new RAW_enc_tree(TRUE
, &myleaf
,
1379 &(myleaf
.curr_pos
), node_pos
, elem_descr
.raw
);
1380 encoded_length
+= err_vals
->value
->errval
->
1381 RAW_encode(*(err_vals
->value
->type_descr
),
1382 *myleaf
.body
.node
.nodes
[node_pos
++]);
1387 myleaf
.body
.node
.nodes
[node_pos
] = new RAW_enc_tree(TRUE
, &myleaf
,
1388 &(myleaf
.curr_pos
), node_pos
, elem_descr
.raw
);
1389 encoded_length
+= get_at(i
)->RAW_encode_negtest(emb_descr
,
1390 *p_td
.oftype_descr
, *myleaf
.body
.node
.nodes
[node_pos
++]);
1392 myleaf
.body
.node
.nodes
[node_pos
] = new RAW_enc_tree(TRUE
, &myleaf
,
1393 &(myleaf
.curr_pos
), node_pos
, elem_descr
.raw
);
1394 encoded_length
+= get_at(i
)->RAW_encode(*p_td
.oftype_descr
,
1395 *myleaf
.body
.node
.nodes
[node_pos
++]);
1398 if (err_vals
&& err_vals
->after
) {
1399 if (err_vals
->after
->errval
== NULL
)
1400 TTCN_error("internal error: erroneous after value missing");
1401 if (err_vals
->after
->raw
) {
1402 myleaf
.body
.node
.nodes
[node_pos
] = new RAW_enc_tree(true, &myleaf
,
1403 &(myleaf
.curr_pos
), node_pos
,
1404 err_vals
->after
->errval
->get_descriptor()->raw
);
1405 encoded_length
+= err_vals
->after
->errval
->
1406 RAW_encode_negtest_raw(*myleaf
.body
.node
.nodes
[node_pos
++]);
1408 if (err_vals
->after
->type_descr
== NULL
)
1409 TTCN_error("internal error: erroneous after typedescriptor missing");
1410 myleaf
.body
.node
.nodes
[node_pos
] = new RAW_enc_tree(TRUE
, &myleaf
,
1411 &(myleaf
.curr_pos
), node_pos
, elem_descr
.raw
);
1412 encoded_length
+= err_vals
->after
->errval
->
1413 RAW_encode(*(err_vals
->after
->type_descr
),
1414 *myleaf
.body
.node
.nodes
[node_pos
++]);
1417 if ((p_err_descr
->omit_after
!= -1) && (i
>= p_err_descr
->omit_after
))
1420 return myleaf
.length
= encoded_length
;
1423 int Record_Of_Type::JSON_encode(const TTCN_Typedescriptor_t
& p_td
, JSON_Tokenizer
& p_tok
) const
1426 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND
,
1427 "Encoding an unbound %s of value.", is_set() ? "set" : "record");
1431 int enc_len
= p_tok
.put_next_token(JSON_TOKEN_ARRAY_START
, NULL
);
1433 for(int i
= 0; i
< get_nof_elements(); ++i
) {
1434 int ret_val
= get_at(i
)->JSON_encode(*p_td
.oftype_descr
, p_tok
);
1435 if (0 > ret_val
) break;
1439 enc_len
+= p_tok
.put_next_token(JSON_TOKEN_ARRAY_END
, NULL
);
1443 int Record_Of_Type::JSON_decode(const TTCN_Typedescriptor_t
& p_td
, JSON_Tokenizer
& p_tok
, boolean p_silent
)
1445 json_token_t token
= JSON_TOKEN_NONE
;
1446 int dec_len
= p_tok
.get_next_token(&token
, NULL
, NULL
);
1447 if (JSON_TOKEN_ERROR
== token
) {
1448 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG
, JSON_DEC_BAD_TOKEN_ERROR
, "");
1449 return JSON_ERROR_FATAL
;
1451 else if (JSON_TOKEN_ARRAY_START
!= token
) {
1452 return JSON_ERROR_INVALID_TOKEN
;
1457 // Read value tokens until we reach some other token
1458 size_t buf_pos
= p_tok
.get_buf_pos();
1459 Base_Type
* val
= create_elem();
1460 int ret_val
= val
->JSON_decode(*p_td
.oftype_descr
, p_tok
, p_silent
);
1461 if (JSON_ERROR_INVALID_TOKEN
== ret_val
) {
1462 // undo the last action on the buffer
1463 p_tok
.set_buf_pos(buf_pos
);
1467 else if (JSON_ERROR_FATAL
== ret_val
) {
1472 return JSON_ERROR_FATAL
;
1474 if (NULL
== refd_ind_ptr
) {
1475 val_ptr
->value_elements
= (Base_Type
**)reallocate_pointers(
1476 (void**)val_ptr
->value_elements
, val_ptr
->n_elements
, val_ptr
->n_elements
+ 1);
1477 val_ptr
->value_elements
[val_ptr
->n_elements
] = val
;
1478 val_ptr
->n_elements
++;
1481 get_at(get_nof_elements())->set_value(val
);
1487 dec_len
+= p_tok
.get_next_token(&token
, NULL
, NULL
);
1488 if (JSON_TOKEN_ARRAY_END
!= token
) {
1489 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG
, JSON_DEC_REC_OF_END_TOKEN_ERROR
, "");
1493 return JSON_ERROR_FATAL
;
1499 void Record_Of_Type::encode(const TTCN_Typedescriptor_t
& p_td
,
1500 TTCN_Buffer
& p_buf
, TTCN_EncDec::coding_t p_coding
, ...) const
1503 va_start(pvar
, p_coding
);
1505 case TTCN_EncDec::CT_BER
: {
1506 TTCN_EncDec_ErrorContext
ec("While BER-encoding type '%s': ", p_td
.name
);
1507 unsigned BER_coding
=va_arg(pvar
, unsigned);
1508 BER_encode_chk_coding(BER_coding
);
1509 ASN_BER_TLV_t
*tlv
=BER_encode_TLV(p_td
, BER_coding
);
1510 tlv
->put_in_buffer(p_buf
);
1511 ASN_BER_TLV_t::destruct(tlv
);
1513 case TTCN_EncDec::CT_RAW
: {
1514 TTCN_EncDec_ErrorContext
ec("While RAW-encoding type '%s': ", p_td
.name
);
1516 TTCN_EncDec_ErrorContext::error_internal("No RAW descriptor available for type '%s'.", p_td
.name
);
1520 RAW_enc_tree
root(FALSE
, NULL
, &rp
, 1, p_td
.raw
);
1521 RAW_encode(p_td
, root
);
1522 root
.put_to_buf(p_buf
);
1524 case TTCN_EncDec::CT_TEXT
: {
1525 TTCN_EncDec_ErrorContext
ec("While TEXT-encoding type '%s': ", p_td
.name
);
1526 if(!p_td
.text
) TTCN_EncDec_ErrorContext::error_internal
1527 ("No TEXT descriptor available for type '%s'.", p_td
.name
);
1528 TEXT_encode(p_td
,p_buf
);
1530 case TTCN_EncDec::CT_XER
: {
1531 TTCN_EncDec_ErrorContext
ec("While XER-encoding type '%s': ", p_td
.name
);
1532 unsigned XER_coding
=va_arg(pvar
, unsigned);
1533 XER_encode(*(p_td
.xer
),p_buf
, XER_coding
, 0, 0);
1536 case TTCN_EncDec::CT_JSON
: {
1537 TTCN_EncDec_ErrorContext
ec("While JSON-encoding type '%s': ", p_td
.name
);
1538 if(!p_td
.json
) TTCN_EncDec_ErrorContext::error_internal
1539 ("No JSON descriptor available for type '%s'.", p_td
.name
);
1540 JSON_Tokenizer
tok(va_arg(pvar
, int) != 0);
1541 JSON_encode(p_td
, tok
);
1542 p_buf
.put_s(tok
.get_buffer_length(), (const unsigned char*)tok
.get_buffer());
1545 TTCN_error("Unknown coding method requested to encode type '%s'", p_td
.name
);
1550 void Record_Of_Type::decode(const TTCN_Typedescriptor_t
& p_td
,
1551 TTCN_Buffer
& p_buf
, TTCN_EncDec::coding_t p_coding
, ...)
1554 va_start(pvar
, p_coding
);
1556 case TTCN_EncDec::CT_BER
: {
1557 TTCN_EncDec_ErrorContext
ec("While BER-decoding type '%s': ", p_td
.name
);
1558 unsigned L_form
=va_arg(pvar
, unsigned);
1560 BER_decode_str2TLV(p_buf
, tlv
, L_form
);
1561 BER_decode_TLV(p_td
, tlv
, L_form
);
1562 if(tlv
.isComplete
) p_buf
.increase_pos(tlv
.get_len());
1564 case TTCN_EncDec::CT_RAW
: {
1565 TTCN_EncDec_ErrorContext
ec("While RAW-decoding type '%s': ", p_td
.name
);
1566 if(!p_td
.raw
) TTCN_EncDec_ErrorContext::error_internal
1567 ("No RAW descriptor available for type '%s'.", p_td
.name
);
1569 switch(p_td
.raw
->top_bit_order
) {
1577 if(RAW_decode(p_td
, p_buf
, p_buf
.get_len()*8, order
)<0)
1578 ec
.error(TTCN_EncDec::ET_INCOMPL_MSG
,"Can not decode type '%s', "
1579 "because invalid or incomplete message was received", p_td
.name
);
1581 case TTCN_EncDec::CT_TEXT
: {
1582 Limit_Token_List limit
;
1583 TTCN_EncDec_ErrorContext
ec("While TEXT-decoding type '%s': ", p_td
.name
);
1584 if(!p_td
.text
) TTCN_EncDec_ErrorContext::error_internal
1585 ("No TEXT descriptor available for type '%s'.", p_td
.name
);
1586 const unsigned char *b
=p_buf
.get_data();
1587 if(b
[p_buf
.get_len()-1]!='\0'){
1588 p_buf
.set_pos(p_buf
.get_len());
1589 p_buf
.put_zero(8,ORDER_LSB
);
1592 if(TEXT_decode(p_td
,p_buf
,limit
)<0)
1593 ec
.error(TTCN_EncDec::ET_INCOMPL_MSG
,"Can not decode type '%s', "
1594 "because invalid or incomplete message was received", p_td
.name
);
1596 case TTCN_EncDec::CT_XER
: {
1597 TTCN_EncDec_ErrorContext
ec("While XER-decoding type '%s': ", p_td
.name
);
1598 unsigned XER_coding
=va_arg(pvar
, unsigned);
1599 XmlReaderWrap
reader(p_buf
);
1600 for (int success
=reader
.Read(); success
==1; success
=reader
.Read()) {
1601 if (reader
.NodeType() == XML_READER_TYPE_ELEMENT
) break;
1603 XER_decode(*(p_td
.xer
), reader
, XER_coding
| XER_TOPLEVEL
, 0);
1604 size_t bytes
= reader
.ByteConsumed();
1605 p_buf
.set_pos(bytes
);
1607 case TTCN_EncDec::CT_JSON
: {
1608 TTCN_EncDec_ErrorContext
ec("While JSON-decoding type '%s': ", p_td
.name
);
1609 if(!p_td
.json
) TTCN_EncDec_ErrorContext::error_internal
1610 ("No JSON descriptor available for type '%s'.", p_td
.name
);
1611 JSON_Tokenizer
tok((const char*)p_buf
.get_data(), p_buf
.get_len());
1612 if(JSON_decode(p_td
, tok
, false)<0)
1613 ec
.error(TTCN_EncDec::ET_INCOMPL_MSG
,"Can not decode type '%s', "
1614 "because invalid or incomplete message was received", p_td
.name
);
1615 p_buf
.set_pos(tok
.get_buf_pos());
1618 TTCN_error("Unknown coding method requested to decode type '%s'", p_td
.name
);
1623 char **Record_Of_Type::collect_ns(const XERdescriptor_t
& p_td
, size_t& num
, bool& def_ns
) const
1625 size_t num_collected
= 0;
1626 // First, our own namespace. Sets num_collected to 0 or 1.
1627 // If it throws, nothing was allocated.
1628 char **collected_ns
= Base_Type::collect_ns(p_td
, num_collected
, def_ns
);
1630 // Then the embedded type
1632 bool def_ns_1
= false;
1633 if (val_ptr
) for (int i
= 0; i
< get_nof_elements(); ++i
) {
1635 char **new_namespaces
= get_at(i
)->collect_ns(
1636 *p_td
.oftype_descr
, num_new
, def_ns_1
);
1637 merge_ns(collected_ns
, num_collected
, new_namespaces
, num_new
);
1638 def_ns
= def_ns
|| def_ns_1
; // alas, no ||=
1642 // Probably a TC_Error thrown from the element's collect_ns(),
1643 // e.g. if encoding an unbound value.
1644 while (num_collected
> 0) Free(collected_ns
[--num_collected
]);
1649 num
= num_collected
;
1650 return collected_ns
;
1653 static const universal_char sp
= { 0,0,0,' ' };
1654 static const universal_char tb
= { 0,0,0,9 };
1656 int Record_Of_Type::XER_encode(const XERdescriptor_t
& p_td
, TTCN_Buffer
& p_buf
,
1657 unsigned int flavor
, int indent
, embed_values_enc_struct_t
* emb_val
) const
1660 return XER_encode_negtest(err_descr
, p_td
, p_buf
, flavor
, indent
, emb_val
);
1663 if (val_ptr
== 0) TTCN_error(
1664 "Attempt to XER-encode an unbound record of type %s", get_descriptor()->name
);
1665 int encoded_length
= (int)p_buf
.get_len();
1667 const int exer
= is_exer(flavor
);
1668 const boolean own_tag
=
1669 !(exer
&& indent
&& (p_td
.xer_bits
& (ANY_ELEMENT
|ANY_ATTRIBUTES
|UNTAGGED
)));
1671 const int indenting
= !is_canonical(flavor
) && own_tag
;
1672 const boolean xmlValueList
= isXmlValueList();
1675 | ( (exer
&& (p_td
.xer_bits
& XER_LIST
))
1676 || is_exerlist(flavor
) ? SIMPLE_TYPE
: 0);
1677 flavor
&= ~XER_RECOF
; // record-of doesn't care
1678 int nof_elements
= get_nof_elements();
1679 Base_Type::begin_xml(p_td
, p_buf
, flavor
, indent
, !nof_elements
,
1680 (collector_fn
)&Record_Of_Type::collect_ns
);
1682 if (xmlValueList
&& nof_elements
&& indenting
&& !exer
) { /* !exer or GDMO */
1683 do_indent(p_buf
, indent
+1);
1686 if (exer
&& (p_td
.xer_bits
& ANY_ATTRIBUTES
)) {
1687 // Back up over the '>' and the '\n' that may follow it
1688 size_t buf_len
= p_buf
.get_len(), shorter
= 0;
1689 const unsigned char * const buf_data
= p_buf
.get_data();
1690 if (buf_data
[buf_len
- 1 - shorter
] == '\n') ++shorter
;
1691 if (buf_data
[buf_len
- 1 - shorter
] == '>' ) ++shorter
;
1693 unsigned char saved
[4];
1695 memcpy(saved
, buf_data
+ (buf_len
- shorter
), shorter
);
1696 p_buf
.increase_length(-shorter
);
1699 // ANY_ATTRIBUTES means it's a record of universal charstring.
1700 // They are in AnyAttributeFormat (X.693/2008 18.2.6):
1701 // "URI(optional), space, NCName, equals, \"xmlcstring\""
1702 // They need to be written as an XML attribute and namespace declaration:
1703 // xmlns:b0="URI" b0:NCName="xmlcstring"
1705 for (int i
= 0; i
< nof_elements
; ++i
) {
1706 TTCN_EncDec_ErrorContext
ec_0("Attribute %d: ", i
);
1707 if (!is_elem_bound(i
)) {
1708 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND
,
1709 "Encoding an unbound universal charstring value.");
1712 const UNIVERSAL_CHARSTRING
*elem
1713 = static_cast<const UNIVERSAL_CHARSTRING
*>(val_ptr
->value_elements
[i
]);
1714 size_t len
= elem
->lengthof();
1716 const UNIVERSAL_CHARSTRING_ELEMENT
& ue
= (*elem
)[len
- 1];
1717 if (sp
== ue
|| tb
== ue
) --len
;
1720 // sp_at: indexes the first space
1721 // j is left to point at where the attribute name begins (just past the space)
1722 size_t j
, sp_at
= 0;
1723 for (j
= 0; j
< len
; j
++) {
1724 const UNIVERSAL_CHARSTRING_ELEMENT
& ue
= (*elem
)[j
];
1725 if (sp_at
) { // already found a space
1726 if (sp
== ue
|| tb
== ue
) {} // another space, do nothing
1727 else break; // found a non-space after a space
1730 if (sp
== ue
|| tb
== ue
) sp_at
= j
;
1734 size_t buf_start
= p_buf
.get_len();
1736 char * ns
= mprintf(" xmlns:b%d='", i
);
1737 size_t ns_len
= mstrlen(ns
);
1738 p_buf
.put_s(ns_len
, (cbyte
*)ns
);
1740 UNIVERSAL_CHARSTRING
before(sp_at
, (const universal_char
*)(*elem
));
1741 if (p_td
.xer_bits
& (ANY_FROM
| ANY_EXCEPT
)) {
1742 // Ensure the namespace abides to its restrictions
1744 before
.encode_utf8(ns_buf
);
1746 ns_buf
.get_string(cs
);
1747 check_namespace_restrictions(p_td
, (const char*)cs
);
1749 before
.XER_encode(UNIVERSAL_CHARSTRING_xer_
, p_buf
,
1750 flavor
| ANY_ATTRIBUTES
, indent
, 0);
1755 // Keep just the "b%d" part from ns
1756 p_buf
.put_s(ns_len
- 9, (cbyte
*)ns
+ 7);
1764 if (p_td
.xer_bits
& (ANY_FROM
| ANY_EXCEPT
)) {
1765 // Make sure the unqualified namespace is allowed
1766 check_namespace_restrictions(p_td
, NULL
);
1770 UNIVERSAL_CHARSTRING
after(len
- j
, (const universal_char
*)(*elem
) + j
);
1771 after
.XER_encode(UNIVERSAL_CHARSTRING_xer_
, p_buf
,
1772 flavor
| ANY_ATTRIBUTES
, indent
, 0);
1774 // Put this attribute in a dummy element and walk through it to check its validity
1775 TTCN_Buffer check_buf
;
1776 check_buf
.put_s(2, (unsigned char*)"<a");
1777 check_buf
.put_s(p_buf
.get_len() - buf_start
, p_buf
.get_data() + buf_start
);
1778 check_buf
.put_s(2, (unsigned char*)"/>");
1779 XmlReaderWrap
checker(check_buf
);
1780 while (1 == checker
.Read());
1783 p_buf
.put_s(shorter
, saved
); // restore the '>' and anything after
1786 else { // not ANY-ATTRIBUTES
1787 unsigned int sub_flavor
= flavor
| XER_RECOF
| (p_td
.xer_bits
& (XER_LIST
));
1788 TTCN_EncDec_ErrorContext
ec_0("Index ");
1789 TTCN_EncDec_ErrorContext ec_1
;
1791 for (int i
= 0; i
< nof_elements
; ++i
) {
1792 if (i
> 0 && !own_tag
&& 0 != emb_val
&&
1793 emb_val
->embval_index
< emb_val
->embval_array
->size_of()) {
1794 emb_val
->embval_array
->get_at(emb_val
->embval_index
)->XER_encode(
1795 UNIVERSAL_CHARSTRING_xer_
, p_buf
, flavor
| EMBED_VALUES
, indent
+1, 0);
1796 ++emb_val
->embval_index
;
1798 ec_1
.set_msg("%d: ", i
);
1799 if (exer
&& (p_td
.xer_bits
& XER_LIST
) && i
>0) p_buf
.put_c(' ');
1800 get_at(i
)->XER_encode(*p_td
.oftype_descr
, p_buf
,
1801 sub_flavor
, indent
+own_tag
, emb_val
);
1804 if (indenting
&& nof_elements
&& !is_exerlist(flavor
)) {
1805 if (xmlValueList
&& !exer
) p_buf
.put_c('\n'); /* !exer or GDMO */
1806 //do_indent(p_buf, indent);
1810 Base_Type::end_xml(p_td
, p_buf
, flavor
, indent
, !nof_elements
);
1811 return (int)p_buf
.get_len() - encoded_length
;
1814 // XERSTUFF Record_Of_Type::encode_element
1815 /** Helper for Record_Of_Type::XER_encode_negtest
1817 * The main purpose of this method is to allow another type to request
1818 * encoding of a single element of the record-of. Used by Record_Type
1819 * to encode individual strings of the EMBED-VALUES member.
1821 * @param i index of the element
1822 * @param ev erroneous descriptor for the element itself
1823 * @param ed deeper erroneous values
1824 * @param p_buf buffer containing the encoded value
1825 * @param sub_flavor flags
1826 * @param indent indentation level
1827 * @return number of bytes generated
1829 int Record_Of_Type::encode_element(int i
, const XERdescriptor_t
& p_td
,
1830 const Erroneous_values_t
* ev
, const Erroneous_descriptor_t
* ed
,
1831 TTCN_Buffer
& p_buf
, unsigned int sub_flavor
, int indent
, embed_values_enc_struct_t
* emb_val
) const
1833 int enc_len
= p_buf
.get_len();
1834 TTCN_EncDec_ErrorContext ec
;
1835 const int exer
= is_exer(sub_flavor
);
1837 if (ev
&& ev
->before
) {
1838 if (ev
->before
->errval
==NULL
) {
1839 TTCN_error("internal error: erroneous before value missing");
1841 ec
.set_msg("Erroneous value before component #%d: ", i
);
1842 if (ev
->before
->raw
) {
1843 ev
->before
->errval
->encode_raw(p_buf
);
1845 if (ev
->before
->type_descr
==NULL
) TTCN_error(
1846 "internal error: erroneous before type descriptor missing");
1847 ev
->before
->errval
->XER_encode(*ev
->before
->type_descr
->xer
,
1848 p_buf
, sub_flavor
, indent
, 0);
1852 if (exer
&& (sub_flavor
& XER_LIST
)
1853 && (i
> 0 || (ev
&& ev
->before
&& !ev
->before
->raw
))){
1854 // Ensure a separator is written after the "erroneous before"
1855 // of the first element (except for "raw before").
1859 if (ev
&& ev
->value
) {
1860 if (ev
->value
->errval
) { // replace
1861 ec
.set_msg("Erroneous value for component #%d: ", i
);
1862 if (ev
->value
->raw
) {
1863 ev
->value
->errval
->encode_raw(p_buf
);
1865 if (ev
->value
->type_descr
==NULL
) TTCN_error(
1866 "internal error: erroneous value type descriptor missing");
1867 ev
->value
->errval
->XER_encode(*ev
->value
->type_descr
->xer
,
1868 p_buf
, sub_flavor
, indent
, 0);
1872 ec
.set_msg("Component #%d: ", i
);
1874 get_at(i
)->XER_encode_negtest(ed
, p_td
, p_buf
, sub_flavor
, indent
, emb_val
);
1876 // the "real" encoder
1877 get_at(i
)->XER_encode(p_td
, p_buf
, sub_flavor
, indent
, emb_val
);
1881 if (ev
&& ev
->after
) {
1882 if (ev
->after
->errval
==NULL
) {
1883 TTCN_error("internal error: erroneous after value missing");
1885 ec
.set_msg("Erroneous value after component #%d: ", i
);
1886 if (ev
->after
->raw
) {
1887 ev
->after
->errval
->encode_raw(p_buf
);
1889 if (ev
->after
->type_descr
==NULL
) TTCN_error(
1890 "internal error: erroneous after type descriptor missing");
1891 ev
->after
->errval
->XER_encode(*ev
->after
->type_descr
->xer
,
1892 p_buf
, sub_flavor
, indent
, 0);
1899 // XERSTUFF Record_Of_Type::XER_encode_negtest
1900 int Record_Of_Type::XER_encode_negtest(const Erroneous_descriptor_t
* p_err_descr
,
1901 const XERdescriptor_t
& p_td
, TTCN_Buffer
& p_buf
, unsigned flavor
, int indent
,
1902 embed_values_enc_struct_t
* emb_val
) const
1904 if (val_ptr
== 0) TTCN_error(
1905 "Attempt to XER-encode an unbound record of type %s", get_descriptor()->name
);
1906 int encoded_length
= (int)p_buf
.get_len();
1908 const int exer
= is_exer(flavor
);
1909 const boolean own_tag
=
1910 !(exer
&& indent
&& (p_td
.xer_bits
& (ANY_ELEMENT
|ANY_ATTRIBUTES
|UNTAGGED
)));
1912 const int indenting
= !is_canonical(flavor
) && own_tag
;
1913 const boolean xmlValueList
= isXmlValueList();
1916 | ( (exer
&& (p_td
.xer_bits
& XER_LIST
))
1917 || is_exerlist(flavor
) ? SIMPLE_TYPE
: 0);
1918 flavor
&= ~XER_RECOF
; // record-of doesn't care
1919 int nof_elements
= get_nof_elements();
1920 Base_Type::begin_xml(p_td
, p_buf
, flavor
, indent
, !nof_elements
,
1921 (collector_fn
)&Record_Of_Type::collect_ns
);
1923 if (xmlValueList
&& nof_elements
&& indenting
&& !exer
) { /* !exer or GDMO */
1924 do_indent(p_buf
, indent
+1);
1929 if (exer
&& (p_td
.xer_bits
& ANY_ATTRIBUTES
)) {
1930 // Back up over the '>' and the '\n' that may follow it
1931 size_t buf_len
= p_buf
.get_len(), shorter
= 0;
1932 const unsigned char * const buf_data
= p_buf
.get_data();
1933 if (buf_data
[buf_len
- 1 - shorter
] == '\n') ++shorter
;
1934 if (buf_data
[buf_len
- 1 - shorter
] == '>' ) ++shorter
;
1936 unsigned char * saved
= 0;
1938 saved
= new unsigned char[shorter
];
1939 memcpy(saved
, buf_data
+ (buf_len
- shorter
), shorter
);
1940 p_buf
.increase_length(-shorter
);
1943 // ANY_ATTRIBUTES means it's a record of universal charstring.
1944 // They are in AnyAttributeFormat (X.693/2008 18.2.6):
1945 // "URI(optional), space, NCName, equals, \"xmlcstring\""
1946 // They need to be written as an XML attribute and namespace declaration:
1947 // xmlns:b0="URI" b0:NCName="xmlcstring"
1949 for (int i
= 0; i
< nof_elements
; ++i
) {
1950 if (i
< p_err_descr
->omit_before
) continue;
1952 const Erroneous_values_t
*ev
= p_err_descr
->next_field_err_values(i
, values_idx
);
1953 const Erroneous_descriptor_t
*ed
= p_err_descr
->next_field_emb_descr(i
, edescr_idx
);
1955 if (ev
&& ev
->before
) {
1956 if (ev
->before
->errval
==NULL
) TTCN_error("internal error: erroneous value missing");
1959 if (ev
->before
->raw
) ev
->before
->errval
->encode_raw(p_buf
);
1961 if (ev
->before
->type_descr
==NULL
) TTCN_error(
1962 "internal error: erroneous before type descriptor missing");
1963 else ev
->before
->errval
->XER_encode(*ev
->before
->type_descr
->xer
,
1964 p_buf
, flavor
, indent
, 0);
1968 if (ev
&& ev
->value
) { //value replacement
1969 if (ev
->value
->errval
) {
1970 if (ev
->value
->raw
) ev
->value
->errval
->encode_raw(p_buf
);
1972 if (ev
->value
->type_descr
==NULL
) TTCN_error(
1973 "internal error: erroneous value type descriptor missing");
1974 else ev
->value
->errval
->XER_encode(*ev
->value
->type_descr
->xer
,
1975 p_buf
, flavor
, indent
, 0);
1981 // embedded descr.. call negtest (except UNIVERSAL_CHARSTRING
1982 // doesn't have XER_encode_negtest)
1983 TTCN_error("internal error: embedded descriptor for scalar");
1986 // the original encoding
1987 const UNIVERSAL_CHARSTRING
*elem
1988 = static_cast<const UNIVERSAL_CHARSTRING
*>(get_at(i
));
1989 size_t len
= elem
->lengthof();
1991 const UNIVERSAL_CHARSTRING_ELEMENT
& ue
= (*elem
)[len
- 1];
1992 if (sp
== ue
|| tb
== ue
) --len
;
1995 // sp_at: indexes the first space
1996 // j is left to point at where the attribute name begins (just past the space)
1997 size_t j
, sp_at
= 0;
1998 for (j
= 0; j
< len
; j
++) {
1999 const UNIVERSAL_CHARSTRING_ELEMENT
& ue
= (*elem
)[j
];
2000 if (sp_at
) { // already found a space
2001 if (sp
== ue
|| tb
== ue
) {} // another space, do nothing
2002 else break; // found a non-space after a space
2005 if (sp
== ue
|| tb
== ue
) sp_at
= j
;
2010 char * ns
= mprintf(" xmlns:b%d='", i
);
2011 size_t ns_len
= mstrlen(ns
);
2012 p_buf
.put_s(ns_len
, (cbyte
*)ns
);
2014 UNIVERSAL_CHARSTRING
before(sp_at
, (const universal_char
*)(*elem
));
2015 before
.XER_encode(UNIVERSAL_CHARSTRING_xer_
, p_buf
,
2016 flavor
| ANY_ATTRIBUTES
, indent
, 0);
2021 // Keep just the "b%d" part from ns
2022 p_buf
.put_s(ns_len
- 9, (cbyte
*)ns
+ 7);
2031 UNIVERSAL_CHARSTRING
after(len
- j
, (const universal_char
*)(*elem
) + j
);
2032 after
.XER_encode(UNIVERSAL_CHARSTRING_xer_
, p_buf
,
2033 flavor
| ANY_ATTRIBUTES
, indent
, 0);
2037 if (ev
&& ev
->after
) {
2038 if (ev
->after
->errval
==NULL
) TTCN_error(
2039 "internal error: erroneous after value missing");
2041 if (ev
->after
->raw
) ev
->after
->errval
->encode_raw(p_buf
);
2043 if (ev
->after
->type_descr
==NULL
) TTCN_error(
2044 "internal error: erroneous after type descriptor missing");
2045 else ev
->after
->errval
->XER_encode(*ev
->after
->type_descr
->xer
,
2046 p_buf
, flavor
, indent
, 0);
2050 // omit_after value -1 becomes "very big"
2051 if ((unsigned int)i
>= (unsigned int)p_err_descr
->omit_after
) break;
2054 p_buf
.put_s(shorter
, saved
); // restore the '>' and anything after
2058 else { // not ANY-ATTRIBUTES
2059 unsigned int sub_flavor
= flavor
| XER_RECOF
| (p_td
.xer_bits
& (XER_LIST
|ANY_ATTRIBUTES
));
2061 TTCN_EncDec_ErrorContext ec
;
2063 for (int i
= 0; i
< nof_elements
; ++i
) {
2064 if (i
< p_err_descr
->omit_before
) continue;
2066 if (0 != emb_val
&& i
> 0 && !own_tag
&&
2067 emb_val
->embval_index
< emb_val
->embval_array
->size_of()) {
2068 const Erroneous_values_t
* ev0_i
= NULL
;
2069 const Erroneous_descriptor_t
* ed0_i
= NULL
;
2070 if (emb_val
->embval_err
) {
2071 ev0_i
= emb_val
->embval_err
->next_field_err_values(emb_val
->embval_index
, emb_val
->embval_err_val_idx
);
2072 ed0_i
= emb_val
->embval_err
->next_field_emb_descr (emb_val
->embval_index
, emb_val
->embval_err_descr_idx
);
2074 emb_val
->embval_array
->encode_element(emb_val
->embval_index
, UNIVERSAL_CHARSTRING_xer_
,
2075 ev0_i
, ed0_i
, p_buf
, flavor
| EMBED_VALUES
, indent
+ own_tag
, 0);
2076 ++emb_val
->embval_index
;
2079 const Erroneous_values_t
* err_vals
=
2080 p_err_descr
->next_field_err_values(i
, values_idx
);
2081 const Erroneous_descriptor_t
* emb_descr
=
2082 p_err_descr
->next_field_emb_descr (i
, edescr_idx
);
2084 encode_element(i
, *p_td
.oftype_descr
, err_vals
, emb_descr
, p_buf
, sub_flavor
, indent
+own_tag
, emb_val
);
2086 // omit_after value -1 becomes "very big"
2087 if ((unsigned int)i
>= (unsigned int)p_err_descr
->omit_after
) break;
2090 if (indenting
&& nof_elements
&& !is_exerlist(flavor
)) {
2091 if (xmlValueList
&& !exer
) p_buf
.put_c('\n'); /* !exer or GDMO */
2092 //do_indent(p_buf, indent);
2096 Base_Type::end_xml(p_td
, p_buf
, flavor
, indent
, !nof_elements
);
2097 return (int)p_buf
.get_len() - encoded_length
;
2100 int Record_Of_Type::XER_decode(const XERdescriptor_t
& p_td
,
2101 XmlReaderWrap
& reader
, unsigned int flavor
, embed_values_dec_struct_t
* emb_val
)
2103 int exer
= is_exer(flavor
);
2104 int xerbits
= p_td
.xer_bits
;
2105 if (flavor
& XER_TOPLEVEL
) xerbits
&= ~UNTAGGED
;
2107 !(exer
&& ((xerbits
& (ANY_ELEMENT
| ANY_ATTRIBUTES
| UNTAGGED
))
2108 || (flavor
& USE_TYPE_ATTR
))); /* incase the parent has USE-UNION */
2109 /* not toplevel anymore and remove the flags for USE-UNION the oftype doesn't need them */
2110 flavor
&= ~XER_TOPLEVEL
& ~XER_LIST
& ~USE_TYPE_ATTR
;
2111 int success
=1, depth
=-1;
2112 set_val(NULL_VALUE
); // empty but initialized array, val_ptr != NULL
2114 if (own_tag
) for (success
= 1; success
== 1; success
= reader
.Read()) {
2115 type
= reader
.NodeType();
2116 if (exer
&& (p_td
.xer_bits
& XER_ATTRIBUTE
)) {
2117 if (XML_READER_TYPE_ATTRIBUTE
== type
) break;
2119 if (exer
&& (p_td
.xer_bits
& XER_LIST
)) {
2120 if (XML_READER_TYPE_TEXT
== type
) break;
2123 if (XML_READER_TYPE_ELEMENT
== type
) {
2124 verify_name(reader
, p_td
, exer
);
2125 depth
= reader
.Depth();
2128 } /* endif(exer && list) */
2130 else depth
= reader
.Depth();
2131 TTCN_EncDec_ErrorContext
ec_0("Index ");
2132 TTCN_EncDec_ErrorContext ec_1
;
2133 flavor
|= XER_RECOF
;
2134 if (exer
&& (p_td
.xer_bits
& ANY_ATTRIBUTES
)) {
2135 // The enclosing type should handle the decoding.
2136 TTCN_error("Incorrect decoding of ANY-ATTRIBUTES");
2138 else if (exer
&& (p_td
.xer_bits
& XER_LIST
)) { /* LIST decoding*/
2139 char *val
= (char*)reader
.NewValue(); /* we own it */
2141 size_t len
= strlen(val
);
2142 /* The string contains a bunch of values separated by whitespace.
2143 * Tokenize the string and create a new buffer which looks like
2144 * an XML element (<ns:name xmlns:ns='uri'>value</ns:name>), then use that
2145 * to decode the value. */
2146 for(char * str
= strtok(val
, " \t\x0A\x0D"); str
!= 0; str
= strtok(val
+ pos
, " \t\x0A\x0D")) {
2147 // Calling strtok with NULL won't work here, since the decoded element can have strtok calls aswell
2148 pos
+= strlen(str
) + 1;
2149 // Construct a new XML Reader with the current token.
2151 const XERdescriptor_t
& sub_xer
= *p_td
.oftype_descr
;
2153 write_ns_prefix(sub_xer
, buf2
);
2155 boolean i_can_has_ns
= sub_xer
.my_module
!= 0 && sub_xer
.ns_index
!= -1;
2156 const char * const exer_name
= sub_xer
.names
[1];
2157 buf2
.put_s((size_t)sub_xer
.namelens
[1]-1-i_can_has_ns
, (cbyte
*)exer_name
);
2159 const namespace_t
* const pns
= sub_xer
.my_module
->get_ns(sub_xer
.ns_index
);
2160 buf2
.put_s(7 - (*pns
->px
== 0), (cbyte
*)" xmlns:");
2161 buf2
.put_s(strlen(pns
->px
), (cbyte
*)pns
->px
);
2162 buf2
.put_s(2, (cbyte
*)"='");
2163 buf2
.put_s(strlen(pns
->ns
), (cbyte
*)pns
->ns
);
2164 buf2
.put_s(2, (cbyte
*)"'>");
2166 // start tag completed
2167 buf2
.put_s(strlen(str
), (cbyte
*)str
);
2171 write_ns_prefix(sub_xer
, buf2
);
2172 buf2
.put_s((size_t)sub_xer
.namelens
[1], (cbyte
*)exer_name
);
2173 XmlReaderWrap
reader2(buf2
);
2174 reader2
.Read(); // Move to the start element.
2175 // Don't move to the #text, that's the callee's responsibility.
2176 ec_1
.set_msg("%d: ", get_nof_elements());
2177 // The call to the non-const operator[], I mean get_at(), creates
2178 // a new element (because it is indexing one past the last element).
2179 // Then we call its XER_decode with the temporary XML reader.
2180 get_at(get_nof_elements())->XER_decode(sub_xer
, reader2
, flavor
, 0);
2181 if (flavor
& EXIT_ON_ERROR
&& !is_elem_bound(get_nof_elements() - 1)) {
2182 if (1 == get_nof_elements()) {
2183 // Failed to decode even the first element
2186 // Some elements were successfully decoded -> only delete the last one
2187 set_size(get_nof_elements() - 1);
2192 if (pos
>= len
) break;
2195 if (p_td
.xer_bits
& XER_ATTRIBUTE
) {
2196 //Let the caller do reader.AdvanceAttribute();
2199 reader
.Read(); // on closing tag
2200 reader
.Read(); // past it
2204 if (flavor
& PARENT_CLOSED
) {
2205 // Nothing to do. We are probably untagged; do not advance in the XML
2206 // because it would move past the parent.
2208 else if (own_tag
&& reader
.IsEmptyElement()) { // Nothing to do
2209 reader
.Read(); // This is our own empty tag, move past it
2212 /* Note: there is no reader.Read() at the end of the loop below.
2213 * Each element is supposed to consume enough to leave the next element
2214 * well-positioned. */
2215 for (success
= own_tag
? reader
.Read() : reader
.Ok(); success
== 1; ) {
2216 type
= reader
.NodeType();
2217 if (XML_READER_TYPE_ELEMENT
== type
)
2219 if (exer
&& (p_td
.xer_bits
& ANY_ELEMENT
)) {
2220 /* This is a (record-of UNIVERSAL_CHARSTRING) with ANY-ELEMENT.
2221 * The ANY-ELEMENT is really meant for the element type,
2222 * so behave like a record-of (string with ANY-ELEMENT):
2223 * call the non-const operator[], I mean get_at(), to create
2224 * a new element, then read the entire XML element into it. */
2225 UNIVERSAL_CHARSTRING
* uc
=
2226 static_cast<UNIVERSAL_CHARSTRING
*>(get_at(val_ptr
->n_elements
));
2227 const xmlChar
* outer
= reader
.ReadOuterXml();
2228 uc
->decode_utf8(strlen((const char*)outer
), outer
);
2229 // consume the element
2230 for (success
= reader
.Read(); success
== 1 && reader
.Depth() > depth
; success
= reader
.Read()) {}
2231 if (reader
.NodeType() != XML_READER_TYPE_ELEMENT
) success
= reader
.Read(); // one last time
2234 /* If this is an untagged record-of and the start element does not
2235 * belong to the embedded type, the record-of has already ended. */
2236 if (!own_tag
&& !can_start_v(
2237 (const char*)reader
.LocalName(), (const char*)reader
.NamespaceUri(),
2238 p_td
, flavor
| UNTAGGED
))
2240 for (; success
== 1 && reader
.Depth() > depth
; success
= reader
.Read()) ;
2241 // We should now be back at the same depth as we started.
2244 ec_1
.set_msg("%d: ", get_nof_elements());
2245 /* The call to the non-const get_at() creates the element */
2246 get_at(get_nof_elements())->XER_decode(*p_td
.oftype_descr
, reader
, flavor
, emb_val
);
2247 if (0 != emb_val
&& !own_tag
&& get_nof_elements() > 1) {
2248 ++emb_val
->embval_index
;
2252 else if (XML_READER_TYPE_END_ELEMENT
== type
) {
2253 for (; success
== 1 && reader
.Depth() > depth
; success
= reader
.Read()) ;
2254 // If the depth just decreased, this must be an end element
2255 // (but a different one from what we had before the loop)
2257 verify_end(reader
, p_td
, depth
, exer
);
2258 reader
.Read(); // move forward one last time
2262 else if (XML_READER_TYPE_TEXT
== type
&& 0 != emb_val
&& !own_tag
&& get_nof_elements() > 0) {
2263 UNIVERSAL_CHARSTRING
emb_ustr((const char*)reader
.Value());
2264 emb_val
->embval_array
->get_at(emb_val
->embval_index
)->set_value(&emb_ustr
);
2265 success
= reader
.Read();
2268 success
= reader
.Read();
2271 } /* if not empty element */
2273 return 1; // decode successful
2276 void Record_Of_Type::set_param(Module_Param
& param
) {
2277 if (dynamic_cast<Module_Param_Name
*>(param
.get_id()) != NULL
&&
2278 param
.get_id()->next_name()) {
2279 // Haven't reached the end of the module parameter name
2280 // => the name refers to one of the elements, not to the whole record of
2281 char* param_field
= param
.get_id()->get_current_name();
2282 if (param_field
[0] < '0' || param_field
[0] > '9') {
2283 param
.error("Unexpected record field name in module parameter, expected a valid"
2284 " index for %s type `%s'", is_set() ? "set of" : "record of", get_descriptor()->name
);
2286 int param_index
= -1;
2287 sscanf(param_field
, "%d", ¶m_index
);
2288 get_at(param_index
)->set_param(param
);
2292 param
.basic_check(Module_Param::BC_VALUE
|Module_Param::BC_LIST
, is_set()?"set of value":"record of value");
2294 Module_Param_Ptr mp
= ¶m
;
2295 if (param
.get_type() == Module_Param::MP_Reference
) {
2296 mp
= param
.get_referenced_param();
2299 switch (param
.get_operation_type()) {
2300 case Module_Param::OT_ASSIGN
:
2301 if (mp
->get_type()==Module_Param::MP_Value_List
&& mp
->get_size()==0) {
2302 set_val(NULL_VALUE
);
2305 switch (mp
->get_type()) {
2306 case Module_Param::MP_Value_List
:
2307 set_size(mp
->get_size());
2308 for (size_t i
=0; i
<mp
->get_size(); ++i
) {
2309 Module_Param
* const curr
= mp
->get_elem(i
);
2310 if (curr
->get_type()!=Module_Param::MP_NotUsed
) {
2311 get_at(i
)->set_param(*curr
);
2315 case Module_Param::MP_Indexed_List
:
2316 for (size_t i
=0; i
<mp
->get_size(); ++i
) {
2317 Module_Param
* const current
= mp
->get_elem(i
);
2318 get_at(current
->get_id()->get_index())->set_param(*current
);
2322 param
.type_error(is_set()?"set of value":"record of value", get_descriptor()->name
);
2325 case Module_Param::OT_CONCAT
:
2326 switch (mp
->get_type()) {
2327 case Module_Param::MP_Value_List
: {
2328 if (!is_bound()) set_val(NULL_VALUE
);
2329 int start_idx
= lengthof();
2330 for (size_t i
=0; i
<mp
->get_size(); ++i
) {
2331 Module_Param
* const curr
= mp
->get_elem(i
);
2332 if ((curr
->get_type()!=Module_Param::MP_NotUsed
)) {
2333 get_at(start_idx
+(int)i
)->set_param(*curr
);
2337 case Module_Param::MP_Indexed_List
:
2338 param
.error("Cannot concatenate an indexed value list");
2341 param
.type_error(is_set()?"set of value":"record of value", get_descriptor()->name
);
2345 TTCN_error("Internal error: Record_Of_Type::set_param()");
2349 Module_Param
* Record_Of_Type::get_param(Module_Param_Name
& param_name
) const
2352 return new Module_Param_Unbound();
2354 if (param_name
.next_name()) {
2355 // Haven't reached the end of the module parameter name
2356 // => the name refers to one of the elements, not to the whole record of
2357 char* param_field
= param_name
.get_current_name();
2358 if (param_field
[0] < '0' || param_field
[0] > '9') {
2359 TTCN_error("Unexpected record field name in module parameter reference, "
2360 "expected a valid index for %s type `%s'",
2361 is_set() ? "set of" : "record of", get_descriptor()->name
);
2363 int param_index
= -1;
2364 sscanf(param_field
, "%d", ¶m_index
);
2365 return get_at(param_index
)->get_param(param_name
);
2367 Vector
<Module_Param
*> values
;
2368 for (int i
= 0; i
< val_ptr
->n_elements
; ++i
) {
2369 values
.push_back(val_ptr
->value_elements
[i
]->get_param(param_name
));
2371 Module_Param_Value_List
* mp
= new Module_Param_Value_List();
2372 mp
->add_list_with_implicit_ids(&values
);
2377 void Record_Of_Type::set_implicit_omit()
2379 for (int i
= 0; i
< get_nof_elements(); ++i
) {
2380 if (is_elem_bound(i
))
2381 val_ptr
->value_elements
[i
]->set_implicit_omit();
2385 void Record_Of_Type::add_refd_index(int index
)
2387 if (NULL
== refd_ind_ptr
) {
2388 refd_ind_ptr
= new refd_index_struct
;
2389 refd_ind_ptr
->max_refd_index
= -1;
2391 refd_ind_ptr
->refd_indices
.push_back(index
);
2392 if (index
> get_max_refd_index()) {
2393 refd_ind_ptr
->max_refd_index
= index
;
2397 void Record_Of_Type::remove_refd_index(int index
)
2399 for (size_t i
= refd_ind_ptr
->refd_indices
.size(); i
> 0; --i
) {
2400 if (refd_ind_ptr
->refd_indices
[i
- 1] == index
) {
2401 refd_ind_ptr
->refd_indices
.erase_at(i
- 1);
2405 if (refd_ind_ptr
->refd_indices
.empty()) {
2406 delete refd_ind_ptr
;
2407 refd_ind_ptr
= NULL
;
2409 else if (get_max_refd_index() == index
) {
2410 refd_ind_ptr
->max_refd_index
= -1;
2414 boolean
operator==(null_type
/*null_value*/, const Record_Of_Type
& other_value
)
2416 if (other_value
.val_ptr
== NULL
)
2417 TTCN_error("The right operand of comparison is an unbound value of type %s.",
2418 other_value
.get_descriptor()->name
);
2419 return other_value
.get_nof_elements() == 0;
2422 boolean
operator!=(null_type null_value
,
2423 const Record_Of_Type
& other_value
)
2425 return !(null_value
== other_value
);
2428 ////////////////////////////////////////////////////////////////////////////////
2430 boolean
Record_Type::is_bound() const
2432 if (bound_flag
) return TRUE
;
2433 int field_cnt
= get_count();
2434 for (int field_idx
=0; field_idx
<field_cnt
; field_idx
++) {
2435 const Base_Type
* temp
= get_at(field_idx
);
2436 if(temp
->is_optional()) {
2437 if(temp
->is_present() && temp
->get_opt_value()->is_bound()) return TRUE
;
2439 if(temp
->is_bound()) return TRUE
;
2444 boolean
Record_Type::is_value() const
2449 int field_cnt
= get_count();
2450 for (int field_idx
=0; field_idx
<field_cnt
; field_idx
++) {
2451 const Base_Type
* temp
= get_at(field_idx
);
2452 if(temp
->is_optional()) {
2453 if(!temp
->is_bound()) return FALSE
;
2454 if(temp
->is_present() && !temp
->is_value()) return FALSE
;
2456 if(!temp
->is_value()) return FALSE
;
2462 void Record_Type::clean_up()
2464 int field_cnt
= get_count();
2465 for (int field_idx
=0; field_idx
<field_cnt
; field_idx
++) {
2466 get_at(field_idx
)->clean_up();
2471 void Record_Type::log() const
2474 TTCN_Logger::log_event_unbound();
2477 TTCN_Logger::log_event_str("{ ");
2478 int field_cnt
= get_count();
2479 for (int field_idx
=0; field_idx
<field_cnt
; field_idx
++) {
2480 if (field_idx
) TTCN_Logger::log_event_str(", ");
2481 TTCN_Logger::log_event_str(fld_name(field_idx
));
2482 TTCN_Logger::log_event_str(" := ");
2483 get_at(field_idx
)->log();
2485 TTCN_Logger::log_event_str(" }");
2486 if (err_descr
) err_descr
->log();
2489 void Record_Type::set_param(Module_Param
& param
) {
2491 if (dynamic_cast<Module_Param_Name
*>(param
.get_id()) != NULL
&&
2492 param
.get_id()->next_name()) {
2493 // Haven't reached the end of the module parameter name
2494 // => the name refers to one of the fields, not to the whole record
2495 char* param_field
= param
.get_id()->get_current_name();
2496 if (param_field
[0] >= '0' && param_field
[0] <= '9') {
2497 param
.error("Unexpected array index in module parameter, expected a valid field"
2498 " name for %s type `%s'", is_set() ? "set" : "record", get_descriptor()->name
);
2500 int field_cnt
= get_count();
2501 for (int field_idx
= 0; field_idx
< field_cnt
; field_idx
++) {
2502 if (strcmp(fld_name(field_idx
), param_field
) == 0) {
2503 get_at(field_idx
)->set_param(param
);
2507 param
.error("Field `%s' not found in %s type `%s'",
2508 param_field
, is_set() ? "set" : "record", get_descriptor()->name
);
2511 param
.basic_check(Module_Param::BC_VALUE
, is_set()?"set value":"record value");
2513 Module_Param_Ptr mp
= ¶m
;
2514 if (param
.get_type() == Module_Param::MP_Reference
) {
2515 mp
= param
.get_referenced_param();
2518 switch (mp
->get_type()) {
2519 case Module_Param::MP_Value_List
:
2520 if (get_count()<(int)mp
->get_size()) {
2521 param
.error("%s value of type %s has %d fields but list value has %d fields", is_set()?"Set":"Record", get_descriptor()->name
, get_count(), (int)mp
->get_size());
2523 for (size_t i
=0; i
<mp
->get_size(); i
++) {
2524 Module_Param
* mp_elem
= mp
->get_elem(i
);
2525 if (mp_elem
->get_type()!=Module_Param::MP_NotUsed
) {
2526 get_at((int)i
)->set_param(*mp_elem
);
2530 case Module_Param::MP_Assignment_List
:
2531 for (size_t i
=0; i
<mp
->get_size(); ++i
) {
2532 Module_Param
* const current
= mp
->get_elem(i
);
2534 for (int j
=0; j
<get_count(); ++j
) {
2535 if (!strcmp(fld_name(j
), current
->get_id()->get_name())) {
2536 if (current
->get_type()!=Module_Param::MP_NotUsed
) {
2537 get_at(j
)->set_param(*current
);
2544 current
->error("Non existent field name in type %s: %s.", get_descriptor()->name
, current
->get_id()->get_name());
2549 param
.type_error(is_set()?"set value":"record value", get_descriptor()->name
);
2553 Module_Param
* Record_Type::get_param(Module_Param_Name
& param_name
) const
2556 return new Module_Param_Unbound();
2558 if (param_name
.next_name()) {
2559 // Haven't reached the end of the module parameter name
2560 // => the name refers to one of the fields, not to the whole record
2561 char* param_field
= param_name
.get_current_name();
2562 if (param_field
[0] >= '0' && param_field
[0] <= '9') {
2563 TTCN_error("Unexpected array index in module parameter reference, "
2564 "expected a valid field name for %s type `%s'",
2565 is_set() ? "set" : "record", get_descriptor()->name
);
2567 int field_cnt
= get_count();
2568 for (int field_idx
= 0; field_idx
< field_cnt
; field_idx
++) {
2569 if (strcmp(fld_name(field_idx
), param_field
) == 0) {
2570 return get_at(field_idx
)->get_param(param_name
);
2573 TTCN_error("Field `%s' not found in %s type `%s'",
2574 param_field
, is_set() ? "set" : "record", get_descriptor()->name
);
2576 Module_Param_Assignment_List
* mp
= new Module_Param_Assignment_List();
2577 for (int i
= 0; i
< get_count(); ++i
) {
2578 Module_Param
* mp_field
= get_at(i
)->get_param(param_name
);
2579 mp_field
->set_id(new Module_Param_FieldName(mcopystr(fld_name(i
))));
2580 mp
->add_elem(mp_field
);
2585 void Record_Type::set_implicit_omit()
2587 int field_cnt
= get_count();
2588 for (int field_idx
= 0; field_idx
< field_cnt
; field_idx
++) {
2589 Base_Type
*temp
= get_at(field_idx
);
2590 if (temp
->is_optional()) {
2591 if (temp
->is_bound()) temp
->set_implicit_omit();
2592 else temp
->set_to_omit();
2593 } else if (temp
->is_bound()) {
2594 temp
->set_implicit_omit();
2599 int Record_Type::size_of() const
2602 TTCN_error("Calculating the size of an unbound record/set value of type %s",
2603 get_descriptor()->name
);
2605 int opt_count
= optional_count();
2606 if (opt_count
==0) return get_count();
2607 const int* optional_indexes
= get_optional_indexes();
2608 int my_size
= get_count();
2609 for (int i
=0; i
<opt_count
; i
++) {
2610 if (!get_at(optional_indexes
[i
])->ispresent()) my_size
--;
2615 void Record_Type::encode_text(Text_Buf
& text_buf
) const
2618 TTCN_error("Text encoder: Encoding an unbound record/set value of type %s.",
2619 get_descriptor()->name
);
2621 int field_cnt
= get_count();
2622 for (int field_idx
=0; field_idx
<field_cnt
; field_idx
++)
2623 get_at(field_idx
)->encode_text(text_buf
);
2626 void Record_Type::decode_text(Text_Buf
& text_buf
)
2629 int field_cnt
= get_count();
2630 for (int field_idx
=0; field_idx
<field_cnt
; field_idx
++)
2631 get_at(field_idx
)->decode_text(text_buf
);
2634 boolean
Record_Type::is_equal(const Base_Type
* other_value
) const
2636 const Record_Type
* other_record
= static_cast<const Record_Type
*>(other_value
);
2637 if (!is_bound() && !other_record
->is_bound()) {
2640 int field_cnt
= get_count();
2641 for (int field_idx
=0; field_idx
<field_cnt
; field_idx
++) {
2642 const Base_Type
* elem
= get_at(field_idx
);
2643 const Base_Type
* other_elem
= other_record
->get_at(field_idx
);
2644 if (elem
->is_bound()) {
2645 if (other_elem
->is_bound()) {
2646 if (!elem
->is_equal(other_elem
))
2648 } else return FALSE
;
2649 } else if (other_elem
->is_bound()) return FALSE
;
2654 void Record_Type::set_value(const Base_Type
* other_value
)
2656 if (this==other_value
) return;
2657 if (!other_value
->is_bound())
2658 TTCN_error("Copying an unbound record/set value of type %s.",
2659 other_value
->get_descriptor()->name
);
2660 const Record_Type
* other_record
= static_cast<const Record_Type
*>(other_value
);
2661 int field_cnt
= get_count();
2662 for (int field_idx
=0; field_idx
<field_cnt
; field_idx
++) {
2663 const Base_Type
* elem
= other_record
->get_at(field_idx
);
2664 if (elem
->is_bound()) {
2665 get_at(field_idx
)->set_value(elem
);
2667 get_at(field_idx
)->clean_up();
2670 err_descr
= other_record
->err_descr
;
2674 void Record_Type::encode(const TTCN_Typedescriptor_t
& p_td
,
2675 TTCN_Buffer
& p_buf
, TTCN_EncDec::coding_t p_coding
, ...) const
2678 va_start(pvar
, p_coding
);
2680 case TTCN_EncDec::CT_BER
: {
2681 TTCN_EncDec_ErrorContext
ec("While BER-encoding type '%s': ", p_td
.name
);
2682 unsigned BER_coding
=va_arg(pvar
, unsigned);
2683 BER_encode_chk_coding(BER_coding
);
2684 ASN_BER_TLV_t
*tlv
=BER_encode_TLV(p_td
, BER_coding
);
2685 tlv
->put_in_buffer(p_buf
);
2686 ASN_BER_TLV_t::destruct(tlv
);
2688 case TTCN_EncDec::CT_RAW
: {
2689 TTCN_EncDec_ErrorContext
ec("While RAW-encoding type '%s': ", p_td
.name
);
2690 if(!p_td
.raw
) TTCN_EncDec_ErrorContext::error_internal
2691 ("No RAW descriptor available for type '%s'.", p_td
.name
);
2695 RAW_enc_tree
root(FALSE
, NULL
, &rp
, 1, p_td
.raw
);
2696 RAW_encode(p_td
, root
);
2697 root
.put_to_buf(p_buf
);
2699 case TTCN_EncDec::CT_TEXT
: {
2700 TTCN_EncDec_ErrorContext
ec("While TEXT-encoding type '%s': ", p_td
.name
);
2701 if(!p_td
.text
) TTCN_EncDec_ErrorContext::error_internal
2702 ("No TEXT descriptor available for type '%s'.", p_td
.name
);
2703 TEXT_encode(p_td
,p_buf
);
2705 case TTCN_EncDec::CT_XER
: {
2706 TTCN_EncDec_ErrorContext
ec("While XER-encoding type '%s': ", p_td
.name
);
2707 unsigned XER_coding
=va_arg(pvar
, unsigned);
2708 XER_encode(*(p_td
.xer
),p_buf
, XER_coding
, 0, 0);
2711 case TTCN_EncDec::CT_JSON
: {
2712 TTCN_EncDec_ErrorContext
ec("While JSON-encoding type '%s': ", p_td
.name
);
2713 if(!p_td
.json
) TTCN_EncDec_ErrorContext::error_internal
2714 ("No JSON descriptor available for type '%s'.", p_td
.name
);
2715 JSON_Tokenizer
tok(va_arg(pvar
, int) != 0);
2716 JSON_encode(p_td
, tok
);
2717 p_buf
.put_s(tok
.get_buffer_length(), (const unsigned char*)tok
.get_buffer());
2720 TTCN_error("Unknown coding method requested to encode type '%s'", p_td
.name
);
2725 void Record_Type::decode(const TTCN_Typedescriptor_t
& p_td
,
2726 TTCN_Buffer
& p_buf
, TTCN_EncDec::coding_t p_coding
, ...)
2729 va_start(pvar
, p_coding
);
2731 case TTCN_EncDec::CT_BER
: {
2732 TTCN_EncDec_ErrorContext
ec("While BER-decoding type '%s': ", p_td
.name
);
2733 unsigned L_form
=va_arg(pvar
, unsigned);
2735 BER_decode_str2TLV(p_buf
, tlv
, L_form
);
2736 BER_decode_TLV(p_td
, tlv
, L_form
);
2737 if(tlv
.isComplete
) p_buf
.increase_pos(tlv
.get_len());
2739 case TTCN_EncDec::CT_RAW
: {
2740 TTCN_EncDec_ErrorContext
ec("While RAW-decoding type '%s': ", p_td
.name
);
2742 TTCN_EncDec_ErrorContext::error_internal
2743 ("No RAW descriptor available for type '%s'.", p_td
.name
);
2745 switch(p_td
.raw
->top_bit_order
) {
2753 int rawr
= RAW_decode(p_td
, p_buf
, p_buf
.get_len()*8, order
);
2754 if (rawr
< 0) switch (-rawr
) {
2755 case TTCN_EncDec::ET_INCOMPL_MSG
:
2756 case TTCN_EncDec::ET_LEN_ERR
:
2757 ec
.error(TTCN_EncDec::ET_INCOMPL_MSG
,
2758 "Can not decode type '%s', because incomplete"
2759 " message was received", p_td
.name
);
2762 // The RAW/TEXT decoders return -1 for anything not a length error.
2763 // This is the value for ET_UNBOUND, which can't happen in decoding.
2765 ec
.error(TTCN_EncDec::ET_INVAL_MSG
,
2766 "Can not decode type '%s', because invalid"
2767 " message was received", p_td
.name
);
2771 case TTCN_EncDec::CT_TEXT
: {
2772 Limit_Token_List limit
;
2773 TTCN_EncDec_ErrorContext
ec("While TEXT-decoding type '%s': ", p_td
.name
);
2774 if(!p_td
.text
) TTCN_EncDec_ErrorContext::error_internal
2775 ("No TEXT descriptor available for type '%s'.", p_td
.name
);
2776 const unsigned char *b
=p_buf
.get_data();
2777 if(b
[p_buf
.get_len()-1]!='\0'){
2778 p_buf
.set_pos(p_buf
.get_len());
2779 p_buf
.put_zero(8,ORDER_LSB
);
2782 if(TEXT_decode(p_td
,p_buf
,limit
)<0)
2783 ec
.error(TTCN_EncDec::ET_INCOMPL_MSG
,
2784 "Can not decode type '%s', because invalid or incomplete"
2785 " message was received", p_td
.name
);
2787 case TTCN_EncDec::CT_XER
: {
2788 TTCN_EncDec_ErrorContext
ec("While XER-decoding type '%s': ", p_td
.name
);
2789 unsigned XER_coding
=va_arg(pvar
, unsigned);
2790 XmlReaderWrap
reader(p_buf
);
2791 for (int success
=reader
.Read(); success
==1; success
=reader
.Read()) {
2792 if (reader
.NodeType() == XML_READER_TYPE_ELEMENT
) break;
2794 XER_decode(*(p_td
.xer
), reader
, XER_coding
| XER_TOPLEVEL
, 0);
2795 size_t bytes
= reader
.ByteConsumed();
2796 p_buf
.set_pos(bytes
);
2798 case TTCN_EncDec::CT_JSON
: {
2799 TTCN_EncDec_ErrorContext
ec("While JSON-decoding type '%s': ", p_td
.name
);
2800 if(!p_td
.json
) TTCN_EncDec_ErrorContext::error_internal
2801 ("No JSON descriptor available for type '%s'.", p_td
.name
);
2802 JSON_Tokenizer
tok((const char*)p_buf
.get_data(), p_buf
.get_len());
2803 if(JSON_decode(p_td
, tok
, false)<0)
2804 ec
.error(TTCN_EncDec::ET_INCOMPL_MSG
,
2805 "Can not decode type '%s', because invalid or incomplete"
2806 " message was received", p_td
.name
);
2807 p_buf
.set_pos(tok
.get_buf_pos());
2810 TTCN_error("Unknown coding method requested to decode type '%s'", p_td
.name
);
2815 ASN_BER_TLV_t
* Record_Type::BER_encode_TLV(const TTCN_Typedescriptor_t
& p_td
, unsigned p_coding
) const
2818 return BER_encode_TLV_negtest(err_descr
, p_td
, p_coding
);
2821 TTCN_EncDec_ErrorContext::error
2822 (TTCN_EncDec::ET_UNBOUND
, "Encoding an unbound value.");
2824 BER_chk_descr(p_td
);
2825 ASN_BER_TLV_t
*new_tlv
=ASN_BER_TLV_t::construct(NULL
);
2826 TTCN_EncDec_ErrorContext
ec_0("Component '");
2827 TTCN_EncDec_ErrorContext ec_1
;
2828 int next_default_idx
= 0;
2829 const default_struct
* default_indexes
= get_default_indexes();
2830 int field_cnt
= get_count();
2831 for(int i
=0; i
<field_cnt
; i
++) {
2832 boolean is_default_field
= default_indexes
&& (default_indexes
[next_default_idx
].index
==i
);
2833 if (!default_as_optional() && is_default_field
) {
2834 if (!get_at(i
)->is_equal(default_indexes
[next_default_idx
].value
)) {
2835 ec_1
.set_msg("%s': ", fld_name(i
));
2836 new_tlv
->add_TLV(get_at(i
)->BER_encode_TLV(*fld_descr(i
), p_coding
));
2838 } else { /* is not DEFAULT */
2839 ec_1
.set_msg("%s': ", fld_name(i
));
2840 new_tlv
->add_TLV(get_at(i
)->BER_encode_TLV(*fld_descr(i
), p_coding
));
2842 if (is_default_field
) next_default_idx
++;
2845 if (p_coding
==BER_ENCODE_DER
) new_tlv
->sort_tlvs_tag();
2846 new_tlv
=ASN_BER_V2TLV(new_tlv
, p_td
, p_coding
);
2850 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
2853 TTCN_EncDec_ErrorContext::error
2854 (TTCN_EncDec::ET_UNBOUND
, "Encoding an unbound value.");
2856 BER_chk_descr(p_td
);
2857 ASN_BER_TLV_t
*new_tlv
=ASN_BER_TLV_t::construct(NULL
);
2858 TTCN_EncDec_ErrorContext
ec_0("Component '");
2859 TTCN_EncDec_ErrorContext ec_1
;
2860 int next_default_idx
= 0;
2861 const default_struct
* default_indexes
= get_default_indexes();
2862 int field_cnt
= get_count();
2867 for (int i
=0; i
<field_cnt
; i
++) {
2868 boolean is_default_field
= default_indexes
&& (default_indexes
[next_default_idx
].index
==i
);
2869 // the first condition is not needed, kept for ease of understanding
2870 if ( (p_err_descr
->omit_before
!=-1) && (i
<p_err_descr
->omit_before
) ) {
2871 if (is_default_field
) next_default_idx
++;
2874 const Erroneous_values_t
* err_vals
= p_err_descr
->next_field_err_values(i
, values_idx
);
2875 const Erroneous_descriptor_t
* emb_descr
= p_err_descr
->next_field_emb_descr(i
, edescr_idx
);
2877 if (err_vals
&& err_vals
->before
) {
2878 if (err_vals
->before
->errval
==NULL
) TTCN_error(
2879 "internal error: erroneous before value missing");
2880 ec_1
.set_msg("%s'(erroneous before): ", fld_name(i
));
2881 if (err_vals
->before
->raw
) {
2882 new_tlv
->add_TLV(err_vals
->before
->errval
->BER_encode_negtest_raw());
2884 if (err_vals
->before
->type_descr
==NULL
) TTCN_error(
2885 "internal error: erroneous before typedescriptor missing");
2886 new_tlv
->add_TLV(err_vals
->before
->errval
->BER_encode_TLV(
2887 *err_vals
->before
->type_descr
, p_coding
));
2891 if (err_vals
&& err_vals
->value
) {
2892 if (err_vals
->value
->errval
) { // replace
2893 ec_1
.set_msg("%s'(erroneous value): ", fld_name(i
));
2894 if (err_vals
->value
->raw
) {
2895 new_tlv
->add_TLV(err_vals
->value
->errval
->BER_encode_negtest_raw());
2897 if (err_vals
->value
->type_descr
==NULL
) TTCN_error(
2898 "internal error: erroneous value typedescriptor missing");
2899 new_tlv
->add_TLV(err_vals
->value
->errval
->BER_encode_TLV(
2900 *err_vals
->value
->type_descr
, p_coding
));
2904 if (!default_as_optional() && is_default_field
) {
2905 if (!get_at(i
)->is_equal(default_indexes
[next_default_idx
].value
)) {
2906 ec_1
.set_msg("'%s': ", fld_name(i
));
2908 new_tlv
->add_TLV(get_at(i
)->BER_encode_TLV_negtest(emb_descr
,
2909 *fld_descr(i
), p_coding
));
2911 new_tlv
->add_TLV(get_at(i
)->BER_encode_TLV(*fld_descr(i
), p_coding
));
2914 } else { /* is not DEFAULT */
2915 ec_1
.set_msg("'%s': ", fld_name(i
));
2917 new_tlv
->add_TLV(get_at(i
)->BER_encode_TLV_negtest(emb_descr
,
2918 *fld_descr(i
), p_coding
));
2920 new_tlv
->add_TLV(get_at(i
)->BER_encode_TLV(*fld_descr(i
), p_coding
));
2925 if (err_vals
&& err_vals
->after
) {
2926 if (err_vals
->after
->errval
==NULL
) TTCN_error(
2927 "internal error: erroneous after value missing");
2928 ec_1
.set_msg("%s'(erroneous after): ", fld_name(i
));
2929 if (err_vals
->after
->raw
) {
2930 new_tlv
->add_TLV(err_vals
->after
->errval
->BER_encode_negtest_raw());
2932 if (err_vals
->after
->type_descr
==NULL
) TTCN_error(
2933 "internal error: erroneous after typedescriptor missing");
2934 new_tlv
->add_TLV(err_vals
->after
->errval
->BER_encode_TLV(
2935 *err_vals
->after
->type_descr
, p_coding
));
2939 if (is_default_field
) next_default_idx
++;
2940 if ( (p_err_descr
->omit_after
!=-1) && (i
>=p_err_descr
->omit_after
) ) break;
2944 if (p_coding
==BER_ENCODE_DER
) new_tlv
->sort_tlvs_tag();
2945 new_tlv
=ASN_BER_V2TLV(new_tlv
, p_td
, p_coding
);
2949 boolean
Record_Type::BER_decode_TLV(const TTCN_Typedescriptor_t
& p_td
,
2950 const ASN_BER_TLV_t
& p_tlv
, unsigned L_form
)
2953 BER_chk_descr(p_td
);
2954 ASN_BER_TLV_t stripped_tlv
;
2955 BER_decode_strip_tags(*p_td
.ber
, p_tlv
, L_form
, stripped_tlv
);
2956 TTCN_EncDec_ErrorContext
ec_0("While decoding '%s' type: ", get_descriptor()->name
);
2957 stripped_tlv
.chk_constructed_flag(TRUE
);
2959 ASN_BER_TLV_t tmp_tlv
;
2961 { /* SEQUENCE decoding */
2962 boolean tlv_present
=FALSE
;
2964 TTCN_EncDec_ErrorContext
ec_1("Component '");
2965 TTCN_EncDec_ErrorContext ec_2
;
2966 int next_default_idx
= 0;
2967 int next_optional_idx
= 0;
2968 const default_struct
* default_indexes
= get_default_indexes();
2969 const int* optional_indexes
= get_optional_indexes();
2970 int field_cnt
= get_count();
2971 for(int i
=0; i
<field_cnt
; i
++) {
2972 boolean is_default_field
= default_indexes
&& (default_indexes
[next_default_idx
].index
==i
);
2973 boolean is_optional_field
= optional_indexes
&& (optional_indexes
[next_optional_idx
]==i
);
2974 ec_2
.set_msg("%s': ", fld_descr(i
)->name
);
2975 if (!tlv_present
) tlv_present
=BER_decode_constdTLV_next(stripped_tlv
, V_pos
, L_form
, tmp_tlv
);
2976 if (is_default_field
) { /* is DEFAULT */
2977 if (!tlv_present
|| !get_at(i
)->BER_decode_isMyMsg(*fld_descr(i
), tmp_tlv
)) {
2978 get_at(i
)->set_value(default_indexes
[next_default_idx
].value
);
2980 get_at(i
)->BER_decode_TLV(*fld_descr(i
), tmp_tlv
, L_form
);
2984 else if (is_optional_field
) { /* is OPTIONAL */
2985 if (!tlv_present
) get_at(i
)->set_to_omit();
2987 get_at(i
)->BER_decode_TLV(*fld_descr(i
), tmp_tlv
, L_form
);
2988 if (get_at(i
)->ispresent()) tlv_present
=FALSE
;
2991 else { /* is not DEFAULT OPTIONAL */
2993 ec_2
.error(TTCN_EncDec::ET_INCOMPL_MSG
,"Invalid or incomplete message was received.");
2996 get_at(i
)->BER_decode_TLV(*fld_descr(i
), tmp_tlv
, L_form
);
2999 if (is_default_field
) next_default_idx
++;
3000 if (is_optional_field
) next_optional_idx
++;
3003 BER_decode_constdTLV_end(stripped_tlv
, V_pos
, L_form
, tmp_tlv
, tlv_present
);
3004 } /* SEQUENCE decoding */
3006 { /* SET decoding */
3008 * 0x01: value arrived
3009 * 0x02: is optional / not used :)
3010 * 0x04: has default / not used :)
3012 int field_cnt
= get_count();
3013 unsigned char* fld_indctr
= new unsigned char[field_cnt
];
3014 for (int i
=0; i
<field_cnt
; i
++) fld_indctr
[i
] = 0;
3015 int fld_curr
= -1; /* ellipsis or error... */
3016 while (BER_decode_constdTLV_next(stripped_tlv
, V_pos
, L_form
, tmp_tlv
)) {
3017 for (int i
=0; i
<field_cnt
; i
++) {
3018 if (get_at(i
)->BER_decode_isMyMsg(*fld_descr(i
), tmp_tlv
)) {
3020 TTCN_EncDec_ErrorContext
ec_1("Component '%s': ", fld_name(i
));
3021 get_at(i
)->BER_decode_TLV(*fld_descr(i
), tmp_tlv
, L_form
);
3026 if (fld_indctr
[fld_curr
])
3027 ec_0
.error(TTCN_EncDec::ET_DEC_DUPFLD
, "Duplicated value for component '%s'.", fld_name(fld_curr
));
3028 fld_indctr
[fld_curr
]=1;
3031 int next_default_idx
= 0;
3032 int next_optional_idx
= 0;
3033 const default_struct
* default_indexes
= get_default_indexes();
3034 const int* optional_indexes
= get_optional_indexes();
3035 for (fld_curr
=0; fld_curr
<field_cnt
; fld_curr
++) {
3036 boolean is_default_field
= default_indexes
&& (default_indexes
[next_default_idx
].index
==fld_curr
);
3037 boolean is_optional_field
= optional_indexes
&& (optional_indexes
[next_optional_idx
]==fld_curr
);
3038 if (!fld_indctr
[fld_curr
]) {
3039 if (is_default_field
) get_at(fld_curr
)->set_value(default_indexes
[next_default_idx
].value
);
3040 else if (is_optional_field
) get_at(fld_curr
)->set_to_omit();
3041 else ec_0
.error(TTCN_EncDec::ET_DEC_MISSFLD
, "Missing value for component '%s'.", fld_name(fld_curr
));
3043 if (is_default_field
) next_default_idx
++;
3044 if (is_optional_field
) next_optional_idx
++;
3046 delete[] fld_indctr
;
3047 } /* SET decoding */
3049 if (is_opentype_outermost()) {
3050 TTCN_EncDec_ErrorContext
ec_1("While decoding opentypes: ");
3051 TTCN_Type_list p_typelist
;
3052 BER_decode_opentypes(p_typelist
, L_form
);
3053 } /* if sdef->opentype_outermost */
3057 void Record_Type::BER_decode_opentypes(TTCN_Type_list
& p_typelist
, unsigned L_form
)
3060 p_typelist
.push(this);
3061 TTCN_EncDec_ErrorContext
ec_0("Component '");
3062 TTCN_EncDec_ErrorContext ec_1
;
3063 int field_cnt
= get_count();
3064 for(int i
=0; i
<field_cnt
; i
++) {
3065 ec_1
.set_msg("%s': ", fld_name(i
));
3066 get_at(i
)->BER_decode_opentypes(p_typelist
, L_form
);
3071 int Record_Type::RAW_encode(const TTCN_Typedescriptor_t
& p_td
,
3072 RAW_enc_tree
& myleaf
) const
3074 if (err_descr
) return RAW_encode_negtest(err_descr
, p_td
, myleaf
);
3076 TTCN_EncDec_ErrorContext::error
3077 (TTCN_EncDec::ET_UNBOUND
, "Encoding an unbound value.");
3079 int encoded_length
= 0;
3080 int field_cnt
= get_count();
3081 myleaf
.isleaf
= false;
3082 myleaf
.body
.node
.num_of_nodes
= field_cnt
;
3083 myleaf
.body
.node
.nodes
= init_nodes_of_enc_tree(field_cnt
);
3085 int next_optional_idx
= 0;
3086 const int* optional_indexes
= get_optional_indexes();
3087 for (int i
= 0; i
< field_cnt
; i
++) {
3088 boolean is_optional_field
= optional_indexes
3089 && (optional_indexes
[next_optional_idx
] == i
);
3090 if (!is_optional_field
|| get_at(i
)->ispresent()) {
3091 myleaf
.body
.node
.nodes
[i
] = new RAW_enc_tree(true, &myleaf
,
3092 &(myleaf
.curr_pos
), i
, fld_descr(i
)->raw
);
3095 myleaf
.body
.node
.nodes
[i
] = NULL
;
3097 if (is_optional_field
) next_optional_idx
++;
3099 next_optional_idx
= 0;
3100 for (int i
= 0; i
< field_cnt
; i
++) { /*encoding fields*/
3101 boolean is_optional_field
= optional_indexes
3102 && (optional_indexes
[next_optional_idx
] == i
);
3103 /* encoding of normal fields*/
3104 const Base_Type
*field
= get_at(i
);
3105 if (is_optional_field
) {
3106 next_optional_idx
++;
3107 if (!field
->ispresent())
3108 continue; // do not encode
3110 field
= field
->get_opt_value(); // "reach into" the optional
3112 encoded_length
+= field
->RAW_encode(*fld_descr(i
),
3113 *myleaf
.body
.node
.nodes
[i
]);
3115 return myleaf
.length
= encoded_length
;
3118 // In some cases (e.g. LENGTHTO, POINTERTO, CROSSTAG) it is not generated.
3119 int Record_Type::RAW_encode_negtest(const Erroneous_descriptor_t
*p_err_descr
,
3120 const TTCN_Typedescriptor_t
& /*p_td*/, RAW_enc_tree
& myleaf
) const
3123 TTCN_EncDec_ErrorContext::error
3124 (TTCN_EncDec::ET_UNBOUND
, "Encoding an unbound value.");
3126 int encoded_length
= 0;
3127 int num_fields
= get_count();
3128 myleaf
.isleaf
= false;
3129 myleaf
.body
.node
.num_of_nodes
= 0;
3130 for (int field_idx
= 0; field_idx
< num_fields
; ++field_idx
) {
3131 if ((p_err_descr
->omit_before
!= -1) &&
3132 (field_idx
< p_err_descr
->omit_before
))
3134 else ++myleaf
.body
.node
.num_of_nodes
;
3135 const Erroneous_values_t
*err_vals
= p_err_descr
->get_field_err_values(field_idx
);
3136 if (err_vals
&& err_vals
->before
)
3137 ++myleaf
.body
.node
.num_of_nodes
;
3138 if (err_vals
&& err_vals
->value
&& !err_vals
->value
->errval
)
3139 --myleaf
.body
.node
.num_of_nodes
;
3140 if (err_vals
&& err_vals
->after
)
3141 ++myleaf
.body
.node
.num_of_nodes
;
3142 if ((p_err_descr
->omit_after
!= -1) &&
3143 (field_idx
>= p_err_descr
->omit_after
))
3146 myleaf
.body
.node
.nodes
= init_nodes_of_enc_tree(myleaf
.body
.node
.num_of_nodes
);
3147 TTCN_EncDec_ErrorContext ec
;
3148 int next_optional_idx
= 0;
3149 const int *my_optional_indexes
= get_optional_indexes();
3150 // Counter for fields and additional before/after fields.
3152 for (int field_idx
= 0; field_idx
< num_fields
; ++field_idx
) {
3153 boolean is_optional_field
= my_optional_indexes
&&
3154 (my_optional_indexes
[next_optional_idx
] == field_idx
);
3155 if ((p_err_descr
->omit_before
!= -1) &&
3156 (field_idx
< p_err_descr
->omit_before
)) {
3157 if (is_optional_field
) ++next_optional_idx
;
3160 const Erroneous_values_t
*err_vals
= p_err_descr
->get_field_err_values(field_idx
);
3161 const Erroneous_descriptor_t
*emb_descr
= p_err_descr
->get_field_emb_descr(field_idx
);
3162 if (err_vals
&& err_vals
->before
) {
3163 if (err_vals
->before
->errval
== NULL
)
3164 TTCN_error("internal error: erroneous before value missing");
3165 if (err_vals
->before
->raw
) {
3166 myleaf
.body
.node
.nodes
[node_pos
] =
3167 new RAW_enc_tree(true, &myleaf
, &(myleaf
.curr_pos
), node_pos
,
3168 err_vals
->before
->errval
->get_descriptor()->raw
);
3169 encoded_length
+= err_vals
->before
->errval
->
3170 RAW_encode_negtest_raw(*myleaf
.body
.node
.nodes
[node_pos
++]);
3172 if (err_vals
->before
->type_descr
== NULL
)
3173 TTCN_error("internal error: erroneous before typedescriptor missing");
3174 myleaf
.body
.node
.nodes
[node_pos
] =
3175 new RAW_enc_tree(true, &myleaf
, &(myleaf
.curr_pos
), node_pos
,
3176 err_vals
->before
->type_descr
->raw
);
3177 encoded_length
+= err_vals
->before
->errval
->
3178 RAW_encode(*(err_vals
->before
->type_descr
),
3179 *myleaf
.body
.node
.nodes
[node_pos
++]);
3182 if (err_vals
&& err_vals
->value
) {
3183 if (err_vals
->value
->errval
) {
3184 ec
.set_msg("'%s'(erroneous value): ", fld_name(field_idx
));
3185 if (err_vals
->value
->raw
) {
3186 myleaf
.body
.node
.nodes
[node_pos
] =
3187 new RAW_enc_tree(true, &myleaf
, &(myleaf
.curr_pos
), node_pos
,
3188 err_vals
->value
->errval
->get_descriptor()->raw
);
3189 encoded_length
+= err_vals
->value
->errval
->
3190 RAW_encode_negtest_raw(*myleaf
.body
.node
.nodes
[node_pos
++]);
3192 if (err_vals
->value
->type_descr
== NULL
)
3193 TTCN_error("internal error: erroneous value typedescriptor missing");
3194 myleaf
.body
.node
.nodes
[node_pos
] =
3195 new RAW_enc_tree(true, &myleaf
, &(myleaf
.curr_pos
), node_pos
,
3196 err_vals
->value
->type_descr
->raw
);
3197 encoded_length
+= err_vals
->value
->errval
->
3198 RAW_encode(*(err_vals
->value
->type_descr
),
3199 *myleaf
.body
.node
.nodes
[node_pos
++]);
3203 ec
.set_msg("'%s': ", fld_name(field_idx
));
3204 if (!is_optional_field
|| get_at(field_idx
)->ispresent()) {
3205 const Base_Type
*field
=
3206 is_optional_field
? get_at(field_idx
)->get_opt_value()
3207 : get_at(field_idx
);
3208 myleaf
.body
.node
.nodes
[node_pos
] =
3209 new RAW_enc_tree(true, &myleaf
, &(myleaf
.curr_pos
), node_pos
,
3210 fld_descr(field_idx
)->raw
);
3213 field
->RAW_encode_negtest(emb_descr
, *fld_descr(field_idx
),
3214 *myleaf
.body
.node
.nodes
[node_pos
++]);
3217 field
->RAW_encode(*fld_descr(field_idx
),
3218 *myleaf
.body
.node
.nodes
[node_pos
++]);
3222 myleaf
.body
.node
.nodes
[node_pos
++] = NULL
;
3225 if (err_vals
&& err_vals
->after
) {
3226 if (err_vals
->after
->errval
== NULL
)
3227 TTCN_error("internal error: erroneous before value missing");
3228 if (err_vals
->after
->raw
) {
3229 myleaf
.body
.node
.nodes
[node_pos
] =
3230 new RAW_enc_tree(true, &myleaf
, &(myleaf
.curr_pos
), node_pos
,
3231 err_vals
->after
->errval
->get_descriptor()->raw
);
3232 encoded_length
+= err_vals
->after
->errval
->
3233 RAW_encode_negtest_raw(*myleaf
.body
.node
.nodes
[node_pos
++]);
3235 if (err_vals
->after
->type_descr
== NULL
)
3236 TTCN_error("internal error: erroneous after typedescriptor missing");
3237 myleaf
.body
.node
.nodes
[node_pos
] =
3238 new RAW_enc_tree(true, &myleaf
, &(myleaf
.curr_pos
), node_pos
,
3239 err_vals
->after
->type_descr
->raw
);
3240 encoded_length
+= err_vals
->after
->errval
->
3241 RAW_encode(*(err_vals
->after
->type_descr
),
3242 *myleaf
.body
.node
.nodes
[node_pos
++]);
3245 if (is_optional_field
) ++next_optional_idx
;
3246 if ((p_err_descr
->omit_after
!= -1) &&
3247 (field_idx
>= p_err_descr
->omit_after
))
3250 return myleaf
.length
= encoded_length
;
3253 int Record_Type::RAW_decode(const TTCN_Typedescriptor_t
& p_td
, TTCN_Buffer
& buff
,
3254 int limit
, raw_order_t top_bit_ord
, boolean no_err
, int, boolean
)
3257 int field_cnt
= get_count();
3258 int opt_cnt
= optional_count();
3259 int mand_num
= field_cnt
- opt_cnt
; // expected mandatory fields
3261 raw_order_t local_top_order
;
3262 if (p_td
.raw
->top_bit_order
== TOP_BIT_INHERITED
) local_top_order
= top_bit_ord
;
3263 else if (p_td
.raw
->top_bit_order
== TOP_BIT_RIGHT
) local_top_order
= ORDER_MSB
;
3264 else local_top_order
= ORDER_LSB
;
3266 if (is_set()) { /* set decoder start*/
3267 int prepaddlength
= buff
.increase_pos_padd(p_td
.raw
->prepadding
);
3268 limit
-= prepaddlength
;
3269 int decoded_length
= 0;
3270 int * const field_map
= new int[field_cnt
];
3271 memset(field_map
, 0, field_cnt
* sizeof(int));
3272 int nof_mand_fields
= 0; // mandatory fields actually decoded
3274 const int* optional_indexes
= get_optional_indexes();
3275 for (int i
=0; i
<opt_cnt
; i
++) get_at(optional_indexes
[i
])->set_to_omit();
3278 size_t fl_start_pos
= buff
.get_pos_bit();
3279 int next_optional_idx
= 0;
3280 const int* optional_indexes
= get_optional_indexes();
3281 for (int i
=0; i
<field_cnt
; i
++) { /* decoding fields without TAG */
3282 boolean is_optional_field
= optional_indexes
&& (optional_indexes
[next_optional_idx
]==i
);
3283 if (field_map
[i
] == 0) {
3284 Base_Type
* field_ptr
= get_at(i
);
3285 if (is_optional_field
) {
3286 field_ptr
->set_to_present();
3287 field_ptr
=field_ptr
->get_opt_value();
3289 int decoded_field_length
= field_ptr
->RAW_decode(*fld_descr(i
), buff
,
3290 limit
, local_top_order
, TRUE
);
3291 if ( (is_optional_field
&& (decoded_field_length
>0)) ||
3292 (!is_optional_field
&& (decoded_field_length
>=0)) ) {
3293 decoded_length
+= decoded_field_length
;
3294 limit
-= decoded_field_length
;
3295 if (!is_optional_field
) nof_mand_fields
++;
3297 goto continue_while
;
3299 buff
.set_pos_bit(fl_start_pos
);
3300 if (is_optional_field
) get_at(i
)->set_to_omit();
3303 if (is_optional_field
) next_optional_idx
++;
3305 break; // no field could be decoded successfully, quit
3309 if (mand_num
> 0 && nof_mand_fields
!= mand_num
) {
3310 /* Not all required fields were decoded. If there are no bits left,
3311 * that means that the last field was decoded successfully but used up
3312 * the buffer. Signal "incomplete". If there were bits left, that means
3313 * no field could be decoded from them; signal an error. */
3314 return limit
? -1 : -TTCN_EncDec::ET_INCOMPL_MSG
;
3316 return decoded_length
+ prepaddlength
+ buff
.increase_pos_padd(p_td
.raw
->padding
);
3317 } else { /* record decoder start */
3318 int prepaddlength
= buff
.increase_pos_padd(p_td
.raw
->prepadding
);
3319 limit
-= prepaddlength
;
3320 size_t last_decoded_pos
= buff
.get_pos_bit();
3321 size_t fl_start_pos
;
3322 int decoded_length
= 0;
3323 int decoded_field_length
= 0;
3324 if (raw_has_ext_bit()) {
3325 const unsigned char* data
=buff
.get_read_data();
3327 unsigned mask
= 1 << (local_top_order
==ORDER_LSB
? 0 : 7);
3328 if (p_td
.raw
->extension_bit
==EXT_BIT_YES
) {
3329 while((data
[count
-1] & mask
) == 0 && count
* 8 < (int)limit
) count
++;
3332 while((data
[count
-1] & mask
) != 0 && count
* 8 < (int)limit
) count
++;
3334 if(limit
) limit
=count
*8;
3337 int next_optional_idx
= 0;
3338 const int* optional_indexes
= get_optional_indexes();
3339 for (int i
=0; i
<field_cnt
; i
++) { /* decoding fields */
3340 boolean is_optional_field
= optional_indexes
&& (optional_indexes
[next_optional_idx
]==i
);
3341 /* check if enough bits to decode the field*/
3342 if (!is_optional_field
|| (limit
>0)) {
3343 /* decoding of normal field */
3344 fl_start_pos
= buff
.get_pos_bit();
3345 Base_Type
* field_ptr
= get_at(i
);
3346 if (is_optional_field
) {
3347 field_ptr
->set_to_present();
3348 field_ptr
=field_ptr
->get_opt_value();
3350 decoded_field_length
= field_ptr
->RAW_decode(*fld_descr(i
), buff
, limit
,
3351 local_top_order
, is_optional_field
? TRUE
: no_err
);
3352 boolean field_present
= TRUE
;
3353 if (is_optional_field
) {
3354 if (decoded_field_length
< 1) { // swallow any error and become omit
3355 field_present
= FALSE
;
3356 get_at(i
)->set_to_omit();
3357 buff
.set_pos_bit(fl_start_pos
);
3360 if (decoded_field_length
< 0) return decoded_field_length
;
3362 if (field_present
) {
3363 decoded_length
+=decoded_field_length
;
3364 limit
-=decoded_field_length
;
3365 last_decoded_pos
=last_decoded_pos
<buff
.get_pos_bit()?buff
.get_pos_bit():last_decoded_pos
;
3368 get_at(i
)->set_to_omit();
3370 if (is_optional_field
) next_optional_idx
++;
3371 } /* decoding fields*/
3373 buff
.set_pos_bit(last_decoded_pos
);
3374 return decoded_length
+prepaddlength
+buff
.increase_pos_padd(p_td
.raw
->padding
);
3375 } /* record decoder end*/
3378 int Record_Type::TEXT_encode(const TTCN_Typedescriptor_t
& p_td
, TTCN_Buffer
& buff
) const
3381 return TEXT_encode_negtest(err_descr
, p_td
, buff
);
3384 TTCN_EncDec_ErrorContext::error
3385 (TTCN_EncDec::ET_UNBOUND
, "Encoding an unbound value.");
3387 bool need_separator
=false;
3388 int encoded_length
=0;
3389 if (p_td
.text
->begin_encode
) {
3390 buff
.put_cs(*p_td
.text
->begin_encode
);
3391 encoded_length
+=p_td
.text
->begin_encode
->lengthof();
3393 int next_optional_idx
= 0;
3394 const int* optional_indexes
= get_optional_indexes();
3395 int field_cnt
= get_count();
3396 for(int i
=0;i
<field_cnt
;i
++) {
3397 boolean is_optional_field
= optional_indexes
&& (optional_indexes
[next_optional_idx
]==i
);
3398 if (!is_optional_field
|| get_at(i
)->ispresent()) {
3399 if (need_separator
&& p_td
.text
->separator_encode
) {
3400 buff
.put_cs(*p_td
.text
->separator_encode
);
3401 encoded_length
+=p_td
.text
->separator_encode
->lengthof();
3403 encoded_length
+= get_at(i
)->TEXT_encode(*fld_descr(i
),buff
);
3404 need_separator
=true;
3406 if (is_optional_field
) next_optional_idx
++;
3408 if (p_td
.text
->end_encode
) {
3409 buff
.put_cs(*p_td
.text
->end_encode
);
3410 encoded_length
+=p_td
.text
->end_encode
->lengthof();
3412 return encoded_length
;
3416 * TEXT encode negative testing
3418 int Record_Type::TEXT_encode_negtest(const Erroneous_descriptor_t
* p_err_descr
, const TTCN_Typedescriptor_t
& p_td
, TTCN_Buffer
& buff
) const
3421 TTCN_EncDec_ErrorContext::error
3422 (TTCN_EncDec::ET_UNBOUND
, "Encoding an unbound value.");
3424 bool need_separator
=false;
3425 int encoded_length
=0;
3426 if (p_td
.text
->begin_encode
) {
3427 buff
.put_cs(*p_td
.text
->begin_encode
);
3428 encoded_length
+=p_td
.text
->begin_encode
->lengthof();
3430 int next_optional_idx
= 0;
3431 const int* optional_indexes
= get_optional_indexes();
3432 int field_cnt
= get_count();
3437 for(int i
=0;i
<field_cnt
;i
++) {
3438 boolean is_optional_field
= optional_indexes
&& (optional_indexes
[next_optional_idx
]==i
);
3440 if ( (p_err_descr
->omit_before
!=-1) && (i
<p_err_descr
->omit_before
) ) {
3441 if (is_optional_field
) next_optional_idx
++;
3445 const Erroneous_values_t
* err_vals
= p_err_descr
->next_field_err_values(i
, values_idx
);
3446 const Erroneous_descriptor_t
* emb_descr
= p_err_descr
->next_field_emb_descr(i
, edescr_idx
);
3448 if (err_vals
&& err_vals
->before
) {
3449 if (err_vals
->before
->errval
==NULL
) TTCN_error(
3450 "internal error: erroneous before value missing");
3452 if (need_separator
&& p_td
.text
->separator_encode
) {
3453 buff
.put_cs(*p_td
.text
->separator_encode
);
3454 encoded_length
+=p_td
.text
->separator_encode
->lengthof();
3456 if (err_vals
->before
->raw
) {
3457 encoded_length
+= err_vals
->before
->errval
->encode_raw(buff
);
3459 if (err_vals
->before
->type_descr
==NULL
) TTCN_error(
3460 "internal error: erroneous before typedescriptor missing");
3461 encoded_length
+= err_vals
->before
->errval
->TEXT_encode(
3462 *(err_vals
->before
->type_descr
),buff
);
3464 need_separator
=true;
3467 if (err_vals
&& err_vals
->value
) {
3468 if (err_vals
->value
->errval
) {
3469 if (need_separator
&& p_td
.text
->separator_encode
) {
3470 buff
.put_cs(*p_td
.text
->separator_encode
);
3471 encoded_length
+=p_td
.text
->separator_encode
->lengthof();
3473 if (err_vals
->value
->raw
) {
3474 encoded_length
+= err_vals
->value
->errval
->encode_raw(buff
);
3476 if (err_vals
->value
->type_descr
==NULL
) TTCN_error(
3477 "internal error: erroneous value typedescriptor missing");
3478 encoded_length
+= err_vals
->value
->errval
->TEXT_encode(
3479 *(err_vals
->value
->type_descr
),buff
);
3481 need_separator
=true;
3484 if (!is_optional_field
|| get_at(i
)->ispresent()) {
3485 if (need_separator
&& p_td
.text
->separator_encode
) {
3486 buff
.put_cs(*p_td
.text
->separator_encode
);
3487 encoded_length
+=p_td
.text
->separator_encode
->lengthof();
3490 encoded_length
+= get_at(i
)->TEXT_encode_negtest(emb_descr
, *fld_descr(i
),buff
);
3492 encoded_length
+= get_at(i
)->TEXT_encode(*fld_descr(i
),buff
);
3494 need_separator
=true;
3498 if (err_vals
&& err_vals
->after
) {
3499 if (err_vals
->after
->errval
==NULL
) TTCN_error(
3500 "internal error: erroneous after value missing");
3501 if (need_separator
&& p_td
.text
->separator_encode
) {
3502 buff
.put_cs(*p_td
.text
->separator_encode
);
3503 encoded_length
+=p_td
.text
->separator_encode
->lengthof();
3505 if (err_vals
->after
->raw
) {
3506 encoded_length
+= err_vals
->after
->errval
->encode_raw(buff
);
3508 if (err_vals
->after
->type_descr
==NULL
) TTCN_error(
3509 "internal error: erroneous after typedescriptor missing");
3510 encoded_length
+= err_vals
->after
->errval
->TEXT_encode(
3511 *(err_vals
->after
->type_descr
),buff
);
3513 need_separator
=true;
3516 if (is_optional_field
) next_optional_idx
++;
3518 if ( (p_err_descr
->omit_after
!=-1) && (i
>=p_err_descr
->omit_after
) ) break;
3520 if (p_td
.text
->end_encode
) {
3521 buff
.put_cs(*p_td
.text
->end_encode
);
3522 encoded_length
+=p_td
.text
->end_encode
->lengthof();
3524 return encoded_length
;
3527 int Record_Type::TEXT_decode(const TTCN_Typedescriptor_t
& p_td
, TTCN_Buffer
& buff
,
3528 Limit_Token_List
& limit
, boolean no_err
, boolean
/*first_call*/)
3532 int decoded_length
=0;
3533 int decoded_field_length
=0;
3534 size_t pos
=buff
.get_pos();
3535 boolean sep_found
=FALSE
;
3538 int loop_detector
=1;
3539 int last_field_num
=-1;
3540 if (p_td
.text
->begin_decode
) {
3542 if ((tl
=p_td
.text
->begin_decode
->match_begin(buff
))<0) {
3543 if(no_err
) return -1;
3544 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR
,
3545 "The specified token '%s' not found for '%s': ",
3546 (const char*)*(p_td
.text
->begin_decode
), p_td
.name
);
3550 buff
.increase_pos(tl
);
3552 if (p_td
.text
->end_decode
) {
3553 limit
.add_token(p_td
.text
->end_decode
);
3556 if(p_td
.text
->separator_decode
){
3557 limit
.add_token(p_td
.text
->separator_decode
);
3561 int field_cnt
= get_count();
3562 int * const field_map
= new int[field_cnt
];
3563 memset(field_map
, 0, field_cnt
* sizeof(int));
3565 int mand_field_num
= 0;
3566 int opt_field_num
= 0;
3568 int has_repeatable
=0;
3569 boolean repeatable
= TRUE
;
3571 int next_optional_idx
= 0;
3572 const int* optional_indexes
= get_optional_indexes();
3573 for (int i
=0;i
<field_cnt
;i
++) {
3574 boolean is_optional_field
= optional_indexes
&& (optional_indexes
[next_optional_idx
]==i
);
3575 if (is_optional_field
) {
3576 get_at(i
)->set_to_omit();
3581 if (get_at(i
)->is_seof()) {
3583 repeatable
= repeatable
&& fld_descr(i
)->text
->val
.parameters
->decoding_params
.repeatable
;
3585 if (is_optional_field
) next_optional_idx
++;
3587 boolean has_optinals
= opt_field_num
> 0;
3588 if ((seof
>0) && repeatable
) has_repeatable
=1;
3590 while (mand_field_num
+opt_field_num
+has_repeatable
) {
3594 next_optional_idx
= 0;
3595 for (int i
=0;i
<field_cnt
;i
++) {
3596 boolean is_optional_field
= optional_indexes
&& (optional_indexes
[next_optional_idx
]==i
);
3597 if (get_at(i
)->is_seof()) {
3598 if ( (fld_descr(i
)->text
->val
.parameters
->decoding_params
.repeatable
&& field_map
[i
]<3)
3599 || !field_map
[i
] ) {
3601 decoded_field_length
= get_at(i
)->TEXT_decode(*fld_descr(i
),buff
, limit
, true,!field_map
[i
]);
3602 if (decoded_field_length
<0) {
3604 if (is_optional_field
&& !field_map
[i
]) get_at(i
)->set_to_omit();
3607 if (!field_map
[i
]) {
3608 if (is_optional_field
) opt_field_num
--;
3609 else mand_field_num
--;
3611 } else field_map
[i
]=2;
3616 } else { // !...->is_seof
3617 if (!field_map
[i
]) {
3619 decoded_field_length
= get_at(i
)->TEXT_decode(*fld_descr(i
),buff
,limit
,true);
3620 if (decoded_field_length
<0) {
3622 if (is_optional_field
) get_at(i
)->set_to_omit();
3626 if (is_optional_field
) opt_field_num
--;
3627 else mand_field_num
--;
3633 if (is_optional_field
) next_optional_idx
++;
3637 if (loop_detector
) break;
3638 if (p_td
.text
->separator_decode
) {
3640 if ((tl
=p_td
.text
->separator_decode
->match_begin(buff
))<0) {
3641 if (p_td
.text
->end_decode
) {
3643 if ((tl2
=p_td
.text
->end_decode
->match_begin(buff
))!=-1) {
3647 } else if (limit
.has_token(ml
)) {
3649 if ((tl2
=limit
.match(buff
,ml
))==0) {
3655 decoded_length
-=decoded_field_length
;
3656 field_map
[last_field_num
]+=2;
3659 if (last_field_num
>=0 && last_field_num
<field_cnt
) {
3660 if (get_at(last_field_num
)->is_seof()) {
3661 if (get_at(last_field_num
)->is_optional()) {
3662 if (field_map
[last_field_num
]==3) {
3663 get_at(last_field_num
)->set_to_omit();
3667 if (field_map
[last_field_num
]==3) {
3671 } else if (get_at(last_field_num
)->is_optional()) {
3672 get_at(last_field_num
)->set_to_omit();
3680 } // if (has_optinals)
3684 buff
.increase_pos(tl
);
3685 for (int a
=0;a
<field_cnt
;a
++) if(field_map
[a
]>2) field_map
[a
]-=3;
3688 } else if (p_td
.text
->end_decode
) {
3690 if ((tl
=p_td
.text
->end_decode
->match_begin(buff
))!=-1) {
3692 buff
.increase_pos(tl
);
3693 limit
.remove_tokens(ml
);
3694 if (mand_field_num
) decoded_length
= -1;
3697 } else if(limit
.has_token(ml
)){
3699 if ((tl
=limit
.match(buff
,ml
))==0) {
3705 limit
.remove_tokens(ml
);
3707 if (mand_field_num
) {
3708 if (no_err
) decoded_length
= -1;
3709 else TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR
,
3710 "Error during decoding '%s': ", p_td
.name
);
3713 decoded_length
-=sep_length
;
3714 buff
.set_pos(buff
.get_pos()-sep_length
);
3717 if (p_td
.text
->end_decode
) {
3719 if ((tl
=p_td
.text
->end_decode
->match_begin(buff
))<0) {
3720 if (no_err
) decoded_length
= -1;
3721 else TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR
,
3722 "The specified token '%s' not found for '%s': ",
3723 (const char*)*(p_td
.text
->end_decode
),p_td
.name
);
3727 buff
.increase_pos(tl
);
3729 if (mand_field_num
) decoded_length
= -1;
3732 return decoded_length
;
3733 } else { // record decoder
3734 int decoded_length
=0;
3735 int decoded_field_length
=0;
3736 size_t pos
=buff
.get_pos();
3737 boolean sep_found
=FALSE
;
3740 if (p_td
.text
->begin_decode
) {
3742 if ((tl
=p_td
.text
->begin_decode
->match_begin(buff
))<0) {
3743 if(no_err
)return -1;
3744 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR
,
3745 "The specified token '%s' not found for '%s': ",
3746 (const char*)*(p_td
.text
->begin_decode
), p_td
.name
);
3750 buff
.increase_pos(tl
);
3752 if (p_td
.text
->end_decode
) {
3753 limit
.add_token(p_td
.text
->end_decode
);
3756 if (p_td
.text
->separator_decode
) {
3757 limit
.add_token(p_td
.text
->separator_decode
);
3761 int mand_field_num
= 0;
3762 int opt_field_num
= 0;
3763 int last_man_index
= 0;
3765 int field_cnt
= get_count();
3766 int next_optional_idx
= 0;
3767 const int* optional_indexes
= get_optional_indexes();
3768 for (int i
=0;i
<field_cnt
;i
++) {
3769 boolean is_optional_field
= optional_indexes
&& (optional_indexes
[next_optional_idx
]==i
);
3770 if (is_optional_field
) {
3771 get_at(i
)->set_to_omit();
3777 if (is_optional_field
) next_optional_idx
++;
3780 next_optional_idx
= 0;
3781 for(int i
=0;i
<field_cnt
;i
++) {
3782 boolean is_optional_field
= optional_indexes
&& (optional_indexes
[next_optional_idx
]==i
);
3783 if (is_optional_field
) {
3786 decoded_field_length
= get_at(i
)->TEXT_decode(*fld_descr(i
),buff
,limit
,TRUE
);
3787 if (decoded_field_length
<0) {
3788 if (is_optional_field
) {
3789 get_at(i
)->set_to_omit();
3792 limit
.remove_tokens(ml
);
3793 if (no_err
) return -1;
3794 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR
,
3795 "Error during decoding field '%s' for '%s': ",
3796 fld_descr(i
)->name
, p_td
.name
);
3797 return decoded_length
;
3800 decoded_length
+=decoded_field_length
;
3801 if (last_man_index
>(i
+1)) {
3802 if (p_td
.text
->separator_decode
) {
3804 if ((tl
=p_td
.text
->separator_decode
->match_begin(buff
))<0) {
3805 if(is_optional_field
) {
3806 get_at(i
)->set_to_omit();
3808 decoded_length
-=decoded_field_length
;
3810 limit
.remove_tokens(ml
);
3811 if(no_err
)return -1;
3812 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR
,
3813 "The specified token '%s' not found for '%s': ",
3814 (const char*)*(p_td
.text
->separator_decode
),p_td
.name
);
3815 return decoded_length
;
3819 buff
.increase_pos(tl
);
3823 } else sep_found
=FALSE
;
3825 } else if (i
==(field_cnt
-1)) {
3828 if (p_td
.text
->separator_decode
) {
3830 if ((tl
=p_td
.text
->separator_decode
->match_begin(buff
))<0) {
3831 if (is_optional_field
) {
3832 if (p_td
.text
->end_decode
) {
3833 if ((tl
=p_td
.text
->end_decode
->match_begin(buff
))!=-1) {
3835 buff
.increase_pos(tl
);
3836 limit
.remove_tokens(ml
);
3837 return decoded_length
;
3839 } else if (limit
.has_token(ml
)) {
3840 if ((tl
=limit
.match(buff
,ml
))==0) {
3845 get_at(i
)->set_to_omit();
3847 decoded_length
-=decoded_field_length
;
3854 buff
.increase_pos(tl
);
3861 if (p_td
.text
->end_decode
) {
3862 if ((tl
=p_td
.text
->end_decode
->match_begin(buff
))!=-1) {
3864 buff
.increase_pos(tl
);
3865 limit
.remove_tokens(ml
);
3866 return decoded_length
;
3868 } else if (limit
.has_token(ml
)) {
3869 if ((tl
=limit
.match(buff
,ml
))==0) {
3877 if (is_optional_field
) next_optional_idx
++;
3879 limit
.remove_tokens(ml
);
3881 buff
.set_pos(buff
.get_pos()-sep_length
);
3882 decoded_length
-=sep_length
;
3884 if (p_td
.text
->end_decode
) {
3886 if ((tl
=p_td
.text
->end_decode
->match_begin(buff
))<0) {
3887 if(no_err
)return -1;
3888 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR
,
3889 "The specified token '%s' not found for '%s': ",
3890 (const char*)*(p_td
.text
->end_decode
),p_td
.name
);
3891 return decoded_length
;
3894 buff
.increase_pos(tl
);
3896 return decoded_length
;
3900 const XERdescriptor_t
* Record_Type::xer_descr(int /*field_index*/) const
3902 TTCN_error("Internal error: Record_Type::xer_descr() called.");
3906 char ** Record_Type::collect_ns(const XERdescriptor_t
& p_td
, size_t& num
, bool& def_ns
) const
3908 const int field_cnt
= get_count();
3909 // The USE-ORDER member is first, unless preempted by EMBED-VALUES
3910 const int uo_index
= ((p_td
.xer_bits
& EMBED_VALUES
) !=0);
3911 // Index of the first "normal" member (after E-V and U-O)
3912 const int start_at
= uo_index
+ ((p_td
.xer_bits
& USE_ORDER
) != 0);
3914 size_t num_collected
= 0;
3915 // First, our own namespace. Sets num_collected to 0 or 1.
3916 // If it throws, nothing was allocated.
3917 char **collected_ns
= Base_Type::collect_ns(p_td
, num_collected
, def_ns
);
3920 // If the nil attribute will be written, add the control namespace
3921 boolean nil_attribute
= (p_td
.xer_bits
& USE_NIL
)
3922 && !get_at(field_cnt
-1)->ispresent();
3924 if (nil_attribute
) {
3925 collected_ns
= (char**)Realloc(collected_ns
, sizeof(char*) * ++num_collected
);
3926 const namespace_t
*c_ns
= p_td
.my_module
->get_controlns();
3928 collected_ns
[num_collected
-1] = mprintf(" xmlns:%s='%s'", c_ns
->px
, c_ns
->ns
);
3931 // Collect namespace declarations from all components (recursively).
3932 // This is extremely nasty, but we can't prosecute you for that.
3933 // (Monty Python - Crunchy Frog sketch). This whole thing is O(n^3). Yuck.
3934 for (int a
= start_at
; a
< field_cnt
; ++a
) {
3936 bool def_ns_1
= false;
3937 char **new_namespaces
= get_at(a
)->collect_ns(*xer_descr(a
), num_new
, def_ns_1
);
3938 merge_ns(collected_ns
, num_collected
, new_namespaces
, num_new
);
3939 def_ns
= def_ns
|| def_ns_1
;
3940 // merge_ns freed new_namespaces
3944 // Probably a TC_Error thrown from the element's collect_ns(),
3945 // e.g. if encoding an unbound value.
3946 while (num_collected
> 0) Free(collected_ns
[--num_collected
]);
3951 num
= num_collected
;
3952 return collected_ns
;
3955 // FIXME some hashing should be implemented
3956 int Record_Type::get_index_byname(const char *name
, const char *uri
) const {
3957 int num_fields
= get_count();
3958 for (int i
= 0; i
< num_fields
; ++i
) {
3959 const XERdescriptor_t
& xer
= *xer_descr(i
);
3960 if (check_name(name
, xer
, TRUE
)
3961 && check_namespace(uri
, xer
)) return i
;
3966 int Record_Type::XER_encode(const XERdescriptor_t
& p_td
, TTCN_Buffer
& p_buf
,
3967 unsigned int flavor
, int indent
, embed_values_enc_struct_t
*) const
3970 return XER_encode_negtest(err_descr
, p_td
, p_buf
, flavor
, indent
, 0);
3973 TTCN_EncDec_ErrorContext::error
3974 (TTCN_EncDec::ET_UNBOUND
, "Encoding an unbound value.");
3977 TTCN_EncDec_ErrorContext
ec_0("Component '");
3978 TTCN_EncDec_ErrorContext ec_1
;
3979 int encoded_length
=(int)p_buf
.get_len(); // how much is already in the buffer
3981 int exer
= is_exer(flavor
);
3982 if (exer
&& (p_td
.xer_bits
& EMBED_VALUES
)) flavor
|= XER_CANONICAL
;
3983 const boolean indenting
= !is_canonical(flavor
);
3984 const int field_cnt
= get_count();
3985 const int num_attributes
= get_xer_num_attr();
3986 // The USE-ORDER member is first, unless preempted by EMBED-VALUES
3987 const int uo_index
= ((p_td
.xer_bits
& EMBED_VALUES
) !=0);
3988 // Index of the first "normal" member (after E-V and U-O)
3989 const int start_at
= uo_index
+ ((p_td
.xer_bits
& USE_ORDER
) != 0);
3990 const int first_nonattr
= start_at
+ num_attributes
;
3991 // start_tag_len is keeping track of how much was written at the end of the
3992 // start tag, i.e. the ">\n". This is used later to "back up" over it.
3993 int start_tag_len
= 1 + indenting
;
3994 // The EMBED-VALUES member, if applicable
3995 const Record_Of_Type
* const embed_values
= (p_td
.xer_bits
& EMBED_VALUES
)
3996 ? static_cast<const Record_Of_Type
*>(get_at(0)) : 0;
3997 // The USE-ORDER member, if applicable
3998 const Record_Of_Type
* const use_order
= (p_td
.xer_bits
& USE_ORDER
)
3999 ? static_cast<const Record_Of_Type
*>(get_at(uo_index
)) : 0;
4001 size_t num_collected
= 0; // we use this to compute delay_close
4002 char **collected_ns
= NULL
;
4003 bool def_ns
= false;
4005 if (indent
== 0) { // top-level type
4006 collected_ns
= collect_ns(p_td
, num_collected
, def_ns
);
4008 else if ((flavor
& DEF_NS_SQUASHED
) && p_td
.my_module
&& p_td
.ns_index
!= -1) {
4009 const namespace_t
* ns
= p_td
.my_module
->get_ns(p_td
.ns_index
);
4010 // The default namespace has been squashed.
4011 // If we are in the default namespace, restore it.
4012 if (*ns
->px
== '\0') {
4013 collected_ns
= Base_Type::collect_ns(p_td
, num_collected
, def_ns
);
4018 // The type's own tag is omitted if we're doing E-XER,
4019 // and it's not the top-level type (XML must have a root element)
4020 // and it's either UNTAGGED or got USE_NIL or USE_TYPE or USE_UNION.
4021 boolean omit_tag
= exer
&& (indent
> 0)
4022 && ( (p_td
.xer_bits
& (UNTAGGED
|XER_ATTRIBUTE
))
4023 || (flavor
& (USE_NIL
|USE_TYPE_ATTR
)));
4025 // If a default namespace is in effect (uri but no prefix) and the type
4026 // is unqualified, the default namespace must be canceled; otherwise
4027 // an XML tag without a ns prefix looks like it belongs to the def.namespace
4028 const boolean empty_ns_hack
= exer
&& !omit_tag
&& (indent
> 0)
4029 && (p_td
.xer_bits
& FORM_UNQUALIFIED
)
4030 && (flavor
& DEF_NS_PRESENT
);
4032 // delay_close=true if there is stuff before the '>' of the start tag
4033 // (prevents writing the '>' which is built into the name).
4034 // This can only happen for EXER: if there are attributes or namespaces,
4035 // or either USE-NIL or USE-QNAME is set.
4036 boolean delay_close
= exer
&& (num_attributes
4037 || empty_ns_hack
// counts as having a namespace
4038 || (num_collected
!= 0)
4039 || (p_td
.xer_bits
& (USE_NIL
|USE_QNAME
))
4040 || (flavor
& USE_NIL
));
4044 if (!omit_tag
) { /* write start tag */
4045 if (indenting
) do_indent(p_buf
, indent
);
4046 /* name looks like this: "tagname>\n"
4047 * lose the \n if : not indenting or (single untagged(*) or attributes (*)) AND exer
4048 * lose the > if attributes are present (*) AND exer
4051 if (exer
) write_ns_prefix(p_td
, p_buf
);
4052 p_buf
.put_s((size_t)p_td
.namelens
[exer
] - delay_close
4053 - (!indenting
|| delay_close
|| (exer
&& (p_td
.xer_bits
& HAS_1UNTAGGED
))),
4054 (cbyte
*)p_td
.names
[exer
]);
4056 else if (flavor
& USE_TYPE_ATTR
) {
4057 // reopen the parent's start tag by overwriting the '>'
4058 size_t buf_len
= p_buf
.get_len();
4059 const unsigned char * const buf_data
= p_buf
.get_data();
4060 if (buf_data
[buf_len
- 1 - shorter
] == '\n') ++shorter
;
4061 if (buf_data
[buf_len
- 1 - shorter
] == '>' ) ++shorter
;
4064 p_buf
.increase_length(-shorter
);
4070 // mask out extra flags we received, do not send them to the fields
4073 if (exer
&& (p_td
.xer_bits
& USE_QNAME
)) { // QName trumps everything
4074 const Base_Type
* const q_uri
= get_at(0);
4075 if (q_uri
->is_present()) {
4076 p_buf
.put_s(11, (cbyte
*)" xmlns:b0='");
4077 q_uri
->XER_encode(*xer_descr(0), p_buf
, flavor
| XER_LIST
, indent
+1, 0);
4081 if (p_td
.xer_bits
& XER_ATTRIBUTE
) begin_attribute(p_td
, p_buf
);
4082 else p_buf
.put_c('>');
4084 if (q_uri
->is_present()) {
4085 p_buf
.put_s(3, (cbyte
*)"b0:");
4088 const Base_Type
* const q_name
= get_at(1);
4089 sub_len
+= q_name
->XER_encode(*xer_descr(1), p_buf
, flavor
| XER_LIST
, indent
+1, 0);
4090 if (p_td
.xer_bits
& XER_ATTRIBUTE
) p_buf
.put_c('\'');
4092 else { // not USE-QNAME
4093 if (!exer
&& (p_td
.xer_bits
& EMBED_VALUES
)) {
4094 // The EMBED-VALUES member as an ordinary record of string
4095 sub_len
+= embed_values
->XER_encode(*xer_descr(0), p_buf
, flavor
, indent
+1, 0);
4098 if (!exer
&& (p_td
.xer_bits
& USE_ORDER
)) {
4099 // The USE-ORDER member as an ordinary record of enumerated
4100 sub_len
+= use_order
->XER_encode(*xer_descr(uo_index
), p_buf
, flavor
, indent
+1, 0);
4103 if (exer
&& (indent
==0 || (flavor
& DEF_NS_SQUASHED
))) // write namespaces for toplevel only
4105 for (size_t cur_coll
= 0; cur_coll
< num_collected
; ++cur_coll
) {
4106 p_buf
.put_s(strlen(collected_ns
[cur_coll
]), (cbyte
*)collected_ns
[cur_coll
]);
4107 Free(collected_ns
[cur_coll
]); // job done
4113 flavor
&= ~DEF_NS_SQUASHED
;
4114 flavor
|= DEF_NS_PRESENT
;
4116 else if (empty_ns_hack
) {
4117 p_buf
.put_s(9, (cbyte
*)" xmlns=''");
4118 flavor
&= ~DEF_NS_PRESENT
;
4119 flavor
|= DEF_NS_SQUASHED
;
4122 /* First all the attributes (not added to sub_len) */
4124 for (i
= start_at
; i
< first_nonattr
; ++i
) {
4125 boolean is_xer_attr_field
= xer_descr(i
)->xer_bits
& XER_ATTRIBUTE
;
4126 ec_1
.set_msg("%s': ", fld_name(i
)); // attr
4127 int tmp_len
= get_at(i
)->XER_encode(*xer_descr(i
), p_buf
, flavor
, indent
+1, 0);
4128 if (is_xer_attr_field
&& !exer
) sub_len
+= tmp_len
; /* do not add if attribute and EXER */
4131 // True if the "nil" attribute needs to be written.
4132 boolean nil_attribute
= exer
&& (p_td
.xer_bits
& USE_NIL
)
4133 && !get_at(field_cnt
-1)->ispresent();
4135 // True if USE_ORDER is in effect and the "nil" attribute was written.
4136 // Then the record-of-enum for USE-ORDER will be empty.
4137 boolean early_to_bed
= FALSE
;
4139 if (nil_attribute
) { // req. exer and USE_NIL
4140 const namespace_t
*control_ns
= p_td
.my_module
->get_controlns();
4142 p_buf
.put_s(strlen(control_ns
->px
),
4143 (cbyte
*)control_ns
->px
);
4145 p_buf
.put_s(10, (cbyte
*)"nil='true'");
4146 if ((p_td
.xer_bits
& USE_ORDER
)) early_to_bed
= TRUE
;
4147 // The whole content was omitted; nothing to do (and if we tried
4148 // to do it, we'd get an error for over-indexing a 0-length record-of).
4151 if (delay_close
&& (!omit_tag
|| shorter
)) {
4152 // Close the start tag left open. If indenting, also write a newline
4153 // unless USE-NIL in effect or there is a single untagged component.
4155 ((p_td
.xer_bits
& (/*USE_NIL|*/HAS_1UNTAGGED
)) ? 0 : indenting
);
4156 p_buf
.put_s(start_tag_len
, (cbyte
*)">\n");
4159 if (exer
&& (p_td
.xer_bits
& EMBED_VALUES
)) {
4160 /* write the first string */
4161 if (embed_values
->size_of() > 0) {
4162 sub_len
+= embed_values
->get_at(0)->XER_encode(UNIVERSAL_CHARSTRING_xer_
,
4163 p_buf
, flavor
| EMBED_VALUES
, indent
+1, 0);
4167 const Record_Type
*ordered
= this; // the record affected by USE-ORDER
4169 // Index of the first non-attribute field of the record pointed to by
4170 // ordered, that is, the first field affected by USE-ORDER.
4171 size_t useorder_base
= first_nonattr
;
4174 int end
= field_cnt
;
4175 if (exer
&& (p_td
.xer_bits
& USE_ORDER
)) {
4176 const int to_send
= use_order
->size_of();
4177 // the length of the loop is determined by the length of use_order
4181 // Count the non-attribute optionals
4182 int n_optionals
= 0;
4183 for (int B
= optional_count() - 1; B
>=+0; B
--) {
4184 int oi
= get_optional_indexes()[B
];
4185 if (oi
< first_nonattr
) break;
4189 int expected_min
= field_cnt
- first_nonattr
- n_optionals
;
4190 int expected_max
= field_cnt
- first_nonattr
;
4193 if ((p_td
.xer_bits
& USE_NIL
) && get_at(field_cnt
-1)->ispresent()) {
4194 // The special case when USE_ORDER refers to the fields of a field,
4196 const Base_Type
*last_optional
= get_at(field_cnt
-1);
4197 const Base_Type
* inner
= last_optional
->get_opt_value();
4198 // it absolutely, positively has to be (derived from) Record_Type
4199 ordered
= static_cast<const Record_Type
*>(inner
);
4200 useorder_base
= ordered
->get_xer_num_attr();
4201 begin
= useorder_base
;
4202 end
= ordered
->get_count();
4204 expected_min
= expected_max
= ordered
->get_count();
4207 if (to_send
> expected_max
4208 ||to_send
< expected_min
) {
4209 ec_1
.set_msg("%s': ", fld_name(uo_index
));
4210 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_CONSTRAINT
,
4211 "Wrong number of USE-ORDER %d, must be %d..%d", to_send
, expected_min
, expected_max
);
4212 begin
= end
= 0; // don't bother sending anything
4214 else { // check no duplicates
4215 int *seen
= new int [to_send
];
4217 for (int ei
= 0; ei
< to_send
; ++ei
) {
4218 const Base_Type
*uoe
= use_order
->get_at(ei
);
4219 const Enum_Type
*enm
= static_cast<const Enum_Type
*>(uoe
);
4220 int val
= enm
->as_int();
4221 for (int x
= 0; x
< num_seen
; ++x
) {
4222 if (val
== seen
[x
]) { // complain
4223 ec_1
.set_msg("%s': ", fld_name(uo_index
));
4224 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_CONSTRAINT
,
4225 "Duplicate value for USE-ORDER");
4226 begin
= end
= 0; // don't bother sending anything
4230 seen
[num_seen
++] = val
;
4234 // If the number is right and there are no duplicates, then carry on
4238 /* Then, all the non-attributes. Structuring the code like this depends on
4239 * all attributes appearing before all non-attributes (excluding
4240 * pseudo-members for USE-ORDER, etc.) */
4242 // early_to_bed can only be true if exer is true (transitive through nil_attribute)
4243 if (!early_to_bed
) {
4244 embed_values_enc_struct_t
* emb_val
= 0;
4245 if (exer
&& (p_td
.xer_bits
& EMBED_VALUES
) && embed_values
->size_of() > 1) {
4246 emb_val
= new embed_values_enc_struct_t
;
4247 emb_val
->embval_array
= embed_values
;
4248 emb_val
->embval_index
= 1;
4249 emb_val
->embval_err
= 0;
4252 for ( i
= begin
; i
< end
; ++i
) {
4253 const Base_Type
*uoe
= 0; // "useOrder enum"
4254 const Enum_Type
*enm
= 0; // the enum value selecting the field
4255 if (exer
&& use_order
) {
4256 uoe
= use_order
->get_at(i
- begin
);
4257 enm
= static_cast<const Enum_Type
*>(uoe
);
4260 // "actual" index, may be perturbed by USE-ORDER
4261 int ai
= !(exer
&& (p_td
.xer_bits
& USE_ORDER
)) ? i
:
4262 enm
->as_int() + useorder_base
;
4263 ec_1
.set_msg("%s': ", ordered
->fld_name(ai
)); // non-attr
4265 const XERdescriptor_t
& descr
= *ordered
->xer_descr(ai
);
4266 sub_len
+= ordered
->get_at(ai
)->XER_encode(descr
, p_buf
,
4267 // Pass USE-NIL to the last field (except when USE-ORDER is also in effect,
4268 // because the tag-stripping effect of USE-NIL has been achieved
4269 // by encoding the sub-fields directly).
4270 flavor
| ((exer
&& !use_order
&& (i
== field_cnt
-1)) ? (p_td
.xer_bits
& USE_NIL
) : 0),
4271 indent
+!omit_tag
, emb_val
);
4273 // Now the next embed-values string (NOT affected by USE-ORDER!)
4274 if (exer
&& (p_td
.xer_bits
& EMBED_VALUES
) && 0 != emb_val
&&
4275 emb_val
->embval_index
< embed_values
->size_of()) {
4276 embed_values
->get_at(emb_val
->embval_index
)->XER_encode(UNIVERSAL_CHARSTRING_xer_
4277 , p_buf
, flavor
| EMBED_VALUES
, indent
+1, 0);
4278 ++emb_val
->embval_index
;
4283 if (emb_val
->embval_index
< embed_values
->size_of()) {
4284 ec_1
.set_msg("%s': ", fld_name(0));
4285 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_CONSTRAINT
,
4286 "Too many EMBED-VALUEs specified: %d (expected %d or less)",
4287 embed_values
->size_of(), emb_val
->embval_index
);
4291 } // if (!early_to_bed)
4295 if (sub_len
) { // something was written, now an end tag
4296 if (indenting
&& !(exer
&& (p_td
.xer_bits
& (HAS_1UNTAGGED
| USE_QNAME
)))) {
4297 // The tags of the last optional member involved with USE_NIL
4298 // have been removed. If it was a simple type, the content was probably
4299 // written on a single line without anything resembling a close tag.
4300 // Do not indent our end tag in this case.
4301 switch ((int)(exer
&& (p_td
.xer_bits
& USE_NIL
))) {
4303 const unsigned char *buf_end
= p_buf
.get_data() + (p_buf
.get_len()-1);
4304 if (buf_end
[-1] != '>' || *buf_end
!= '\n') break;
4305 // If it does not look like an end tag, skip the indenting,
4306 // else fall through.
4309 do_indent(p_buf
, indent
);
4315 if (exer
) write_ns_prefix(p_td
, p_buf
);
4316 p_buf
.put_s((size_t)p_td
.namelens
[exer
]-!indenting
, (cbyte
*)p_td
.names
[exer
]);
4318 else { // need to generate an empty element tag
4319 p_buf
.increase_length(-start_tag_len
); // decrease length
4320 p_buf
.put_s((size_t)2+indenting
, (cbyte
*)"/>\n");
4324 return (int)p_buf
.get_len() - encoded_length
;
4327 // XERSTUFF Record_Type::encode_field
4328 /** Helper for Record_Type::XER_encode_negtest
4330 * Factored out because Record_Type::XER_encode (on which XER_encode_negtest
4331 * is based) calls the XER_encode method of the field in two places:
4332 * one for attributes, the other for elements.
4334 * @param i index of the field
4335 * @param err_vals erroneous descriptor for the field
4336 * @param emb_descr deeper erroneous values
4337 * @param p_buf buffer containing the encoded value
4338 * @param sub_flavor flags
4339 * @param indent indentation level
4340 * @return the number of bytes generated
4342 int Record_Type::encode_field(int i
,
4343 const Erroneous_values_t
* err_vals
, const Erroneous_descriptor_t
* emb_descr
,
4344 TTCN_Buffer
& p_buf
, unsigned int sub_flavor
, int indent
, embed_values_enc_struct_t
* emb_val
) const
4347 TTCN_EncDec_ErrorContext ec
;
4348 if (err_vals
&& err_vals
->before
) {
4349 if (err_vals
->before
->errval
==NULL
) TTCN_error(
4350 "internal error: erroneous before value missing");
4351 ec
.set_msg("Erroneous value before component %s: ", fld_name(i
));
4352 if (err_vals
->before
->raw
) {
4353 enc_len
+= err_vals
->before
->errval
->encode_raw(p_buf
);
4355 if (err_vals
->before
->type_descr
==NULL
) TTCN_error(
4356 "internal error: erroneous before typedescriptor missing");
4357 enc_len
+= err_vals
->before
->errval
->XER_encode(
4358 *err_vals
->before
->type_descr
->xer
, p_buf
, sub_flavor
, indent
, 0);
4362 if (err_vals
&& err_vals
->value
) {
4363 if (err_vals
->value
->errval
) { // replace
4364 ec
.set_msg("Erroneous value for component %s: ", fld_name(i
));
4365 if (err_vals
->value
->raw
) {
4366 enc_len
+= err_vals
->value
->errval
->encode_raw(p_buf
);
4368 if (err_vals
->value
->type_descr
==NULL
) TTCN_error(
4369 "internal error: erroneous value typedescriptor missing");
4370 enc_len
+= err_vals
->value
->errval
->XER_encode(
4371 *err_vals
->value
->type_descr
->xer
, p_buf
, sub_flavor
, indent
, 0);
4375 ec
.set_msg("Component %s: ", fld_name(i
));
4377 enc_len
+= get_at(i
)->XER_encode_negtest(emb_descr
, *xer_descr(i
), p_buf
,
4378 sub_flavor
, indent
, emb_val
);
4380 // the "real" encoder
4381 enc_len
+= get_at(i
)->XER_encode(*xer_descr(i
), p_buf
,
4382 sub_flavor
, indent
, emb_val
);
4386 if (err_vals
&& err_vals
->after
) {
4387 if (err_vals
->after
->errval
==NULL
) TTCN_error(
4388 "internal error: erroneous after value missing");
4389 ec
.set_msg("Erroneous value after component %s: ", fld_name(i
));
4390 if (err_vals
->after
->raw
) {
4391 enc_len
+= err_vals
->after
->errval
->encode_raw(p_buf
);
4393 if (err_vals
->after
->type_descr
==NULL
) TTCN_error(
4394 "internal error: erroneous after typedescriptor missing");
4395 enc_len
+= err_vals
->after
->errval
->XER_encode(
4396 *err_vals
->after
->type_descr
->xer
, p_buf
, sub_flavor
, indent
, 0);
4403 // XERSTUFF Record_Type::XER_encode_negtest
4404 int Record_Type::XER_encode_negtest(const Erroneous_descriptor_t
* p_err_descr
,
4405 const XERdescriptor_t
& p_td
, TTCN_Buffer
& p_buf
, unsigned int flavor
, int indent
,
4406 embed_values_enc_struct_t
*) const
4409 TTCN_EncDec_ErrorContext::error
4410 (TTCN_EncDec::ET_UNBOUND
, "Encoding an unbound value.");
4412 TTCN_EncDec_ErrorContext
ec_0("Component '");
4413 TTCN_EncDec_ErrorContext ec_1
;
4414 int encoded_length
=(int)p_buf
.get_len(); // how much is already in the buffer
4416 int exer
= is_exer(flavor
);
4417 if (exer
&& (p_td
.xer_bits
& EMBED_VALUES
)) flavor
|= XER_CANONICAL
;
4418 const boolean indenting
= !is_canonical(flavor
);
4419 const int field_cnt
= get_count();
4420 const int num_attributes
= get_xer_num_attr();
4421 // The USE-ORDER member is first, unless preempted by EMBED-VALUES
4422 const int uo_index
= ((p_td
.xer_bits
& EMBED_VALUES
) !=0);
4423 // Index of the first "normal" member (after E-V and U-O)
4424 const int start_at
= uo_index
+ ((p_td
.xer_bits
& USE_ORDER
) != 0);
4425 const int first_nonattr
= start_at
+ num_attributes
;
4426 // start_tag_len is keeping track of how much was written at the end of the
4427 // start tag, i.e. the ">\n". This is used later to "back up" over it.
4428 int start_tag_len
= 1 + indenting
;
4429 // The EMBED-VALUES member, if applicable (always first)
4430 const Record_Of_Type
* const embed_values
= (p_td
.xer_bits
& EMBED_VALUES
)
4431 ? static_cast<const Record_Of_Type
*>(get_at(0)) : 0;
4432 // The USE-ORDER member, if applicable (first unless preempted by embed_vals)
4433 const Record_Of_Type
* const use_order
= (p_td
.xer_bits
& USE_ORDER
)
4434 ? static_cast<const Record_Of_Type
*>(get_at(uo_index
)) : 0;
4439 size_t num_collected
= 0; // we use this to compute delay_close
4440 char **collected_ns
= NULL
;
4441 bool def_ns
= false;
4443 if (indent
== 0) { // top-level type
4444 collected_ns
= collect_ns(p_td
, num_collected
, def_ns
);
4446 else if ((flavor
& DEF_NS_SQUASHED
) && p_td
.my_module
&& p_td
.ns_index
!= -1) {
4447 const namespace_t
* ns
= p_td
.my_module
->get_ns(p_td
.ns_index
);
4448 // The default namespace has been squashed.
4449 // If we are in the default namespace, restore it.
4450 if (*ns
->px
== '\0') {
4451 collected_ns
= Base_Type::collect_ns(p_td
, num_collected
, def_ns
);
4456 // The type's own tag is omitted if we're doing E-XER,
4457 // and it's not the top-level type (XML must have a root element)
4458 // and it's either UNTAGGED or got USE_NIL.
4459 boolean omit_tag
= exer
&& indent
4460 && ( (p_td
.xer_bits
& (UNTAGGED
|XER_ATTRIBUTE
))
4461 || (flavor
& (USE_NIL
|USE_TYPE_ATTR
)));
4463 // If a default namespace is in effect (uri but no prefix) and the type
4464 // is unqualified, the default namespace must be canceled; otherwise
4465 // an XML tag without a ns prefix looks like it belongs to the def.namespace
4466 const boolean empty_ns_hack
= exer
&& !omit_tag
&& (indent
> 0)
4467 && (p_td
.xer_bits
& FORM_UNQUALIFIED
)
4468 && (flavor
& DEF_NS_PRESENT
);
4470 // delay_close=true if there is stuff before the '>' of the start tag
4471 // (prevents writing the '>' which is built into the name).
4472 // This can only happen for EXER: if there are attributes or namespaces,
4473 // or either USE-NIL or USE-QNAME is set.
4474 boolean delay_close
= exer
&& (num_attributes
4475 || empty_ns_hack
// counts as having a namespace
4476 || (num_collected
!= 0)
4477 || (p_td
.xer_bits
& (USE_NIL
|USE_QNAME
))
4478 || (flavor
& USE_NIL
));
4481 if (!omit_tag
) { /* write start tag */
4482 if (indenting
) do_indent(p_buf
, indent
);
4483 /* name looks like this: "tagname>\n"
4484 * lose the \n if : not indenting or (single untagged(*) or attributes (*)) AND exer
4485 * lose the > if attributes are present (*) AND exer
4488 if (exer
) write_ns_prefix(p_td
, p_buf
);
4489 p_buf
.put_s((size_t)p_td
.namelens
[exer
] - delay_close
4490 - (!indenting
|| delay_close
|| (exer
&& (p_td
.xer_bits
& HAS_1UNTAGGED
))),
4491 (cbyte
*)p_td
.names
[exer
]);
4493 else if (flavor
& USE_TYPE_ATTR
) {
4494 // reopen the parent's tag
4495 size_t buf_len
= p_buf
.get_len();
4496 const unsigned char * const buf_data
= p_buf
.get_data();
4497 if (buf_data
[buf_len
- 1 - shorter
] == '\n') ++shorter
;
4498 if (buf_data
[buf_len
- 1 - shorter
] == '>' ) ++shorter
;
4501 p_buf
.increase_length(-shorter
);
4506 int sub_len
=0, tmp_len
;
4507 // mask out extra flags we received, do not send them to the fields
4510 if (exer
&& (p_td
.xer_bits
& USE_QNAME
)) {
4511 const Erroneous_values_t
* ev
=
4512 p_err_descr
->next_field_err_values(0, values_idx
);
4513 const Erroneous_descriptor_t
* ed
=
4514 p_err_descr
->next_field_emb_descr (0, edescr_idx
);
4515 // At first, erroneous info for the first component (uri)
4517 TTCN_EncDec_ErrorContext ec
;
4518 const Base_Type
* const q_uri
= get_at(0);
4520 if (ev
&& ev
->before
) {
4521 if (ev
->before
->errval
==NULL
) TTCN_error(
4522 "internal error: erroneous before value missing");
4523 ec
.set_msg("Erroneous value before component #0: ");
4524 if (ev
->before
->raw
) {
4525 sub_len
+= ev
->before
->errval
->encode_raw(p_buf
);
4527 if (ev
->before
->type_descr
==NULL
) TTCN_error(
4528 "internal error: erroneous before typedescriptor missing");
4529 sub_len
+= ev
->before
->errval
->XER_encode(
4530 *ev
->before
->type_descr
->xer
, p_buf
, flavor
, indent
, 0);
4534 if (ev
&& ev
->value
) {
4535 if (ev
->value
->errval
) { // replace
4536 ec
.set_msg("Erroneous value for component #0: ");
4537 if (ev
->value
->raw
) {
4538 sub_len
+= ev
->value
->errval
->encode_raw(p_buf
);
4540 if (ev
->value
->type_descr
==NULL
) TTCN_error(
4541 "internal error: erroneous value typedescriptor missing");
4542 sub_len
+= ev
->value
->errval
->XER_encode(
4543 *ev
->value
->type_descr
->xer
, p_buf
, flavor
, indent
, 0);
4547 ec
.set_msg("Component #0: ");
4549 // universal charstring does not have components.
4550 // TTCN code which could have generated embedded erroneous descriptor
4551 // should have failed semantic analysis.
4552 TTCN_error("internal error: embedded descriptor unexpected");
4554 // the "real" encoder
4555 if (q_uri
->is_present()) {
4556 p_buf
.put_s(11, (cbyte
*)" xmlns:b0='");
4557 sub_len
+= q_uri
->XER_encode(*xer_descr(0), p_buf
, flavor
| XER_LIST
, indent
+1, 0);
4563 if (ev
&& ev
->after
) {
4564 if (ev
->after
->errval
==NULL
) TTCN_error(
4565 "internal error: erroneous after value missing");
4566 ec
.set_msg("Erroneous value after component #0: ");
4567 if (ev
->after
->raw
) {
4568 sub_len
+= ev
->after
->errval
->encode_raw(p_buf
);
4570 if (ev
->after
->type_descr
==NULL
) TTCN_error(
4571 "internal error: erroneous after typedescriptor missing");
4572 sub_len
+= ev
->after
->errval
->XER_encode(
4573 *ev
->after
->type_descr
->xer
, p_buf
, flavor
, indent
, 0);
4577 if (p_td
.xer_bits
& XER_ATTRIBUTE
) begin_attribute(p_td
, p_buf
);
4578 else p_buf
.put_c('>');
4580 // Now switch to the second field (name)
4581 ev
= p_err_descr
->next_field_err_values(1, values_idx
);
4582 ed
= p_err_descr
->next_field_emb_descr (1, edescr_idx
);
4584 if (ev
&& ev
->before
) {
4585 if (ev
->before
->errval
==NULL
) TTCN_error(
4586 "internal error: erroneous before value missing");
4587 ec
.set_msg("Erroneous value before component #1: ");
4588 if (ev
->before
->raw
) {
4589 sub_len
+= ev
->before
->errval
->encode_raw(p_buf
);
4591 if (ev
->before
->type_descr
==NULL
) TTCN_error(
4592 "internal error: erroneous before typedescriptor missing");
4593 sub_len
+= ev
->before
->errval
->XER_encode(
4594 *ev
->before
->type_descr
->xer
, p_buf
, flavor
, indent
, 0);
4598 if (ev
&& ev
->value
) {
4599 if (ev
->value
->errval
) { // replace
4600 ec
.set_msg("Erroneous value for component #1: ");
4601 if (ev
->value
->raw
) {
4602 sub_len
+= ev
->value
->errval
->encode_raw(p_buf
);
4604 if (ev
->value
->type_descr
==NULL
) TTCN_error(
4605 "internal error: erroneous value typedescriptor missing");
4606 sub_len
+= ev
->value
->errval
->XER_encode(
4607 *ev
->value
->type_descr
->xer
, p_buf
, flavor
, indent
, 0);
4611 ec
.set_msg("Component #1: ");
4613 // universal charstring does not have components
4614 TTCN_error("internal error: embedded descriptor unexpected");
4616 // the "real" encoder
4617 if (q_uri
->is_present()) {
4618 p_buf
.put_s(3, (cbyte
*)"b0:");
4622 sub_len
+= get_at(1)->XER_encode(*xer_descr(1), p_buf
, flavor
| XER_LIST
, indent
+1, 0);
4626 if (ev
&& ev
->after
) {
4627 if (ev
->after
->errval
==NULL
) TTCN_error(
4628 "internal error: erroneous after value missing");
4629 ec
.set_msg("Erroneous value after component #1: ");
4630 if (ev
->after
->raw
) {
4631 sub_len
+= ev
->after
->errval
->encode_raw(p_buf
);
4633 if (ev
->after
->type_descr
==NULL
) TTCN_error(
4634 "internal error: erroneous after typedescriptor missing");
4635 sub_len
+= ev
->after
->errval
->XER_encode(
4636 *ev
->after
->type_descr
->xer
, p_buf
, flavor
, indent
, 0);
4640 if (p_td
.xer_bits
& XER_ATTRIBUTE
) p_buf
.put_c('\'');
4642 else { // not USE-QNAME
4643 if (!exer
&& (p_td
.xer_bits
& EMBED_VALUES
)) {
4644 // The EMBED-VALUES member as an ordinary record of string
4645 sub_len
+= embed_values
->XER_encode(*xer_descr(0), p_buf
, flavor
, indent
+1, 0);
4648 if (!exer
&& (p_td
.xer_bits
& USE_ORDER
)) {
4649 // The USE-ORDER member as an ordinary record of enumerated
4650 sub_len
+= use_order
->XER_encode(*xer_descr(uo_index
), p_buf
, flavor
, indent
+1, 0);
4653 if (exer
&& (indent
==0 || (flavor
& DEF_NS_SQUASHED
))) // write namespaces for toplevel only
4655 for (size_t cur_coll
= 0; cur_coll
< num_collected
; ++cur_coll
) {
4656 p_buf
.put_s(strlen(collected_ns
[cur_coll
]), (cbyte
*)collected_ns
[cur_coll
]);
4657 Free(collected_ns
[cur_coll
]); // job done
4663 flavor
&= ~DEF_NS_SQUASHED
;
4664 flavor
|= DEF_NS_PRESENT
;
4666 else if (empty_ns_hack
) {
4667 p_buf
.put_s(9, (cbyte
*)" xmlns=''");
4668 flavor
&= ~DEF_NS_PRESENT
;
4669 flavor
|= DEF_NS_SQUASHED
;
4672 // True if the non-attribute fields need to be omitted;
4673 // e.g. if USE_ORDER is in effect and the "nil" attribute was written
4674 // (then the record-of-enum for USE-ORDER will be empty),
4675 // or "omit all after" was hit while processing attributes.
4676 boolean early_to_bed
= FALSE
;
4678 // First all the attributes (not added to sub_len)
4680 for (i
= start_at
; i
< first_nonattr
; ++i
) {
4681 const Erroneous_values_t
* ev
=
4682 p_err_descr
->next_field_err_values(i
, values_idx
);
4683 const Erroneous_descriptor_t
* ed
=
4684 p_err_descr
->next_field_emb_descr(i
, edescr_idx
);
4686 if (i
< p_err_descr
->omit_before
) continue;
4688 boolean is_xer_attr_field
= xer_descr(i
)->xer_bits
& XER_ATTRIBUTE
;
4689 ec_1
.set_msg("%s': ", fld_name(i
)); // attr
4691 tmp_len
= encode_field(i
, ev
, ed
, p_buf
, flavor
, indent
+ !omit_tag
, 0);
4693 if (is_xer_attr_field
&& !exer
) sub_len
+= tmp_len
; // do not add if attribute and EXER
4695 // omit_after value -1 becomes "very big"
4696 if ((unsigned int)i
>= (unsigned int)p_err_descr
->omit_after
) {
4697 early_to_bed
= TRUE
; // no more fields to write
4702 // True if the "nil" attribute needs to be written.
4703 boolean nil_attribute
= FALSE
;
4704 // nil attribute unaffected by erroneous
4705 boolean nil_attribute_simple
= FALSE
;
4706 if (exer
&& (p_td
.xer_bits
& USE_NIL
)) {
4707 nil_attribute
= nil_attribute_simple
= !get_at(field_cnt
-1)->ispresent();
4709 if (p_err_descr
->values_size
> 0) // there is an erroneous "value := ..."
4711 const Erroneous_values_t
*ev_nil
=
4712 p_err_descr
->get_field_err_values(field_cnt
-1);
4713 if (ev_nil
&& ev_nil
->value
) // value override for the last field
4715 nil_attribute
= (ev_nil
->value
->errval
== NULL
);
4720 if (nil_attribute
) { // req. exer and USE_NIL
4721 const namespace_t
*control_ns
= p_td
.my_module
->get_controlns();
4723 if (!nil_attribute_simple
) {
4724 // It is likely that the declaration for namespace "xsi"
4725 // was not written. Do it now.
4726 p_buf
.put_s(7, (cbyte
*)" xmlns:");
4727 p_buf
.put_s(strlen(control_ns
->px
), (cbyte
*)control_ns
->px
);
4728 p_buf
.put_s(2, (cbyte
*)"='");
4729 p_buf
.put_s(strlen(control_ns
->ns
), (cbyte
*)control_ns
->ns
);
4734 p_buf
.put_s(strlen(control_ns
->px
), (cbyte
*)control_ns
->px
);
4736 p_buf
.put_s(10, (cbyte
*)"nil='true'");
4737 if ((p_td
.xer_bits
& USE_ORDER
)) early_to_bed
= TRUE
;
4738 // The whole content was omitted; nothing to do (and if we tried
4739 // to do it, we'd get an error for over-indexing a 0-length record-of).
4742 if (delay_close
&& (!omit_tag
|| shorter
)) {
4743 // Close the start tag left open. If indenting, also write a newline
4744 // unless USE-NIL in effect or there is a single untagged component.
4746 ((p_td
.xer_bits
& (/*USE_NIL|*/HAS_1UNTAGGED
)) ? 0 : indenting
);
4747 p_buf
.put_s(start_tag_len
, (cbyte
*)">\n");
4750 // Erroneous values for the embed_values member (if any).
4751 // Collected once but referenced multiple times.
4752 const Erroneous_descriptor_t
* ed0
= NULL
;
4753 int embed_values_val_idx
= 0;
4754 int embed_values_descr_idx
= 0;
4756 if (exer
&& (p_td
.xer_bits
& EMBED_VALUES
)) {
4757 ed0
= p_err_descr
->next_field_emb_descr(0, edescr_idx
);
4759 // write the first string
4760 if (embed_values
->size_of() > 0) {
4761 const Erroneous_values_t
* ev0_0
= NULL
;
4762 const Erroneous_descriptor_t
* ed0_0
= NULL
;
4764 ev0_0
= ed0
->next_field_err_values(0, embed_values_val_idx
);
4765 ed0_0
= ed0
->next_field_emb_descr (0, embed_values_descr_idx
);
4767 sub_len
+= embed_values
->encode_element(0, UNIVERSAL_CHARSTRING_xer_
,
4768 ev0_0
, ed0_0
, p_buf
, flavor
| EMBED_VALUES
, indent
+!omit_tag
, 0);
4772 const Record_Type
*ordered
= this; // the record affected by USE-ORDER
4773 // By default it's this record, unless USE_NIL is _also_ in effect,
4774 // in which case it's the last member of this.
4776 // Index of the first non-attribute field of the record pointed to by
4777 // ordered, that is, the first field affected by USE-ORDER.
4778 size_t useorder_base
= first_nonattr
;
4781 int end
= field_cnt
; // "one past", do not touch
4782 // by default, continue from the current field until the end, indexing this
4784 if (exer
&& (p_td
.xer_bits
& USE_ORDER
)) {
4785 // the length of the loop is determined by the length of use_order
4786 const int to_send
= use_order
->size_of();
4788 // i will index all elements of the use_order member
4792 // Count the non-attribute optionals
4793 int n_optionals
= 0;
4794 for (int B
= optional_count() - 1; B
>=+0; B
--) {
4795 int oi
= get_optional_indexes()[B
];
4796 if (oi
< first_nonattr
) break;
4800 int expected_min
= field_cnt
- first_nonattr
- n_optionals
;
4801 int expected_max
= field_cnt
- first_nonattr
;
4803 if ((p_td
.xer_bits
& USE_NIL
) && get_at(field_cnt
-1)->ispresent()) {
4804 // The special case when USE_ORDER refers to the fields of a field,
4806 const Base_Type
*last_optional
= get_at(field_cnt
-1);
4807 const Base_Type
* inner
= last_optional
->get_opt_value();
4808 // it absolutely, positively has to be (derived from) Record_Type
4809 ordered
= static_cast<const Record_Type
*>(inner
);
4810 useorder_base
= ordered
->get_xer_num_attr();
4811 begin
= useorder_base
;
4812 end
= ordered
->get_count();
4814 expected_min
= expected_max
= ordered
->get_count();
4817 if (to_send
> expected_max
4818 ||to_send
< expected_min
) {
4819 ec_1
.set_msg("%s': ", fld_name(uo_index
));
4820 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_CONSTRAINT
,
4821 "Wrong number of USE-ORDER %d, must be %d..%d", to_send
, expected_min
, expected_max
);
4822 early_to_bed
= TRUE
; // don't bother sending anything
4824 else { // check no duplicates
4825 int *seen
= new int [to_send
];
4827 for (int ei
= 0; ei
< to_send
; ++ei
) {
4828 const Base_Type
*uoe
= use_order
->get_at(ei
);
4829 const Enum_Type
*enm
= static_cast<const Enum_Type
*>(uoe
);
4830 int val
= enm
->as_int();
4831 for (int x
= 0; x
< num_seen
; ++x
) {
4832 if (val
== seen
[x
]) { // complain
4833 ec_1
.set_msg("%s': ", fld_name(uo_index
));
4834 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_CONSTRAINT
,
4835 "Duplicate value for USE-ORDER");
4836 early_to_bed
= TRUE
; // don't bother sending anything
4840 seen
[num_seen
++] = val
;
4844 // If the number is right and there are no duplicates, then carry on
4846 } // endif(USE_ORDER)
4848 // Then, all the non-attributes. Structuring the code like this depends on
4849 // all attributes appearing before all non-attributes (excluding
4850 // pseudo-members for USE-ORDER, etc.)
4852 // This loop handles both the normal case (no USE_ORDER) when i indexes
4853 // fields of this record; and the USE_ORDER case (with or without USE-NIL).
4855 // early_to_bed can only be true if exer is true (transitive through nil_attribute)
4856 if (!early_to_bed
) {
4857 embed_values_enc_struct_t
* emb_val
= 0;
4858 if (exer
&& (p_td
.xer_bits
& EMBED_VALUES
) && embed_values
->size_of() > 1) {
4859 emb_val
= new embed_values_enc_struct_t
;
4860 emb_val
->embval_array
= embed_values
;
4861 emb_val
->embval_index
= 1;
4862 emb_val
->embval_err
= ed0
;
4863 emb_val
->embval_err_val_idx
= embed_values_val_idx
;
4864 emb_val
->embval_err_descr_idx
= embed_values_descr_idx
;
4867 for ( i
= begin
; i
< end
; ++i
) {
4869 const Base_Type
*uoe
= 0; // "useOrder enum"
4870 const Enum_Type
*enm
= 0; // the enum value selecting the field
4872 // "actual" index, may be perturbed by USE-ORDER.
4873 // We use this value to index the appropriate record.
4876 const Erroneous_values_t
* ev
= NULL
;
4877 const Erroneous_descriptor_t
* ed
= NULL
;
4878 if (exer
&& use_order
) {
4879 // If USE-ORDER is in effect, it introduces a level of indirection
4880 // into the indexing of fields: "i" is used to select an element
4881 // of the use_order member (an enum), whose value is used to select
4882 // the field being encoded.
4883 uoe
= use_order
->get_at(i
- begin
);
4884 enm
= static_cast<const Enum_Type
*>(uoe
);
4885 ai
= enm
->as_int() + useorder_base
;
4887 // Because it is not guaranteed that ai will increase monotonically,
4888 // we can't use next_field_...().
4889 ev
= p_err_descr
->get_field_err_values(ai
);
4890 ed
= p_err_descr
->get_field_emb_descr (ai
);
4892 else { // not USE-ORDER, sequential access
4893 ev
= p_err_descr
->next_field_err_values(ai
, values_idx
);
4894 ed
= p_err_descr
->next_field_emb_descr (ai
, edescr_idx
);
4896 ec_1
.set_msg("%s': ", ordered
->fld_name(ai
)); // non-attr
4898 if (ai
< p_err_descr
->omit_before
) continue;
4900 // omit_after value -1 becomes "very big".
4901 if ((unsigned int)ai
> (unsigned int)p_err_descr
->omit_after
) continue;
4902 // We can't skip all fields with break, because the next ai may be lower
4905 sub_len
+= ordered
->encode_field(ai
, ev
, ed
, p_buf
,
4906 // Pass USE-NIL to the last field (except when USE-ORDER is also in effect,
4907 // because the tag-stripping effect of USE-NIL has been achieved
4908 // by encoding the sub-fields directly).
4909 flavor
| ((exer
&& !use_order
&& (i
== field_cnt
-1)) ? (p_td
.xer_bits
& USE_NIL
) : 0),
4910 indent
+ !omit_tag
, emb_val
);
4912 // Now the next embed-values string (NOT affected by USE-ORDER!)
4913 if (exer
&& (p_td
.xer_bits
& EMBED_VALUES
) && 0 != emb_val
&&
4914 emb_val
->embval_index
< embed_values
->size_of()) {
4915 const Erroneous_values_t
* ev0_i
= NULL
;
4916 const Erroneous_descriptor_t
* ed0_i
= NULL
;
4918 ev0_i
= ed0
->next_field_err_values(emb_val
->embval_index
, emb_val
->embval_err_val_idx
);
4919 ed0_i
= ed0
->next_field_emb_descr (emb_val
->embval_index
, emb_val
->embval_err_descr_idx
);
4921 embed_values
->encode_element(emb_val
->embval_index
, UNIVERSAL_CHARSTRING_xer_
,
4922 ev0_i
, ed0_i
, p_buf
, flavor
| EMBED_VALUES
, indent
+ !omit_tag
, 0);
4923 ++emb_val
->embval_index
;
4927 if (emb_val
->embval_index
< embed_values
->size_of()) {
4928 ec_1
.set_msg("%s': ", fld_name(0));
4929 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_CONSTRAINT
,
4930 "Too many EMBED-VALUEs specified: %d (expected %d or less)",
4931 embed_values
->size_of(), emb_val
->embval_index
);
4935 } // if (!early_to_bed)
4940 if (sub_len
) { // something was written, now an end tag
4941 if (indenting
&& !(exer
&& (p_td
.xer_bits
& (HAS_1UNTAGGED
| USE_QNAME
))))
4942 // The tags of the last optional member involved with USE_NIL
4943 // have been removed. If it was a simple type, the content was probably
4944 // written on a single line without anything resembling a close tag.
4945 // Do not indent our end tag in this case.
4946 switch ((int)(exer
&& (p_td
.xer_bits
& USE_NIL
))) {
4948 const unsigned char *buf_end
= p_buf
.get_data() + (p_buf
.get_len()-1);
4949 if (buf_end
[-1] != '>' || *buf_end
!= '\n') break;
4950 // If it does not look like an end tag, skip the indenting,
4951 // else fall through.
4954 do_indent(p_buf
, indent
);
4959 if (exer
) write_ns_prefix(p_td
, p_buf
);
4960 p_buf
.put_s((size_t)p_td
.namelens
[exer
]-!indenting
, (cbyte
*)p_td
.names
[exer
]);
4962 else { // need to generate an empty element tag
4963 p_buf
.increase_length(-start_tag_len
); // decrease length
4964 p_buf
.put_s((size_t)2+indenting
, (cbyte
*)"/>\n");
4968 return (int)p_buf
.get_len() - encoded_length
;
4971 int Record_Type::XER_decode(const XERdescriptor_t
& p_td
, XmlReaderWrap
& reader
,
4972 unsigned int flavor
, embed_values_dec_struct_t
*)
4975 int exer
= is_exer(flavor
);
4977 int depth
=-1; // depth of the start tag
4978 int xerbits
= p_td
.xer_bits
;
4979 if (flavor
& XER_TOPLEVEL
) xerbits
&= ~UNTAGGED
;
4980 const boolean own_tag
= !(exer
4981 && ( (xerbits
& (ANY_ELEMENT
| UNTAGGED
| XER_ATTRIBUTE
))
4982 || (flavor
& (USE_NIL
| USE_TYPE_ATTR
))));
4983 boolean tag_closed
= (flavor
& PARENT_CLOSED
) != 0;
4984 // If the parent has USE-TYPE, our ATTRIBUTE members can be found
4985 // in the parent's tag (the reader is sitting on it).
4986 const boolean parent_tag
= exer
&& (flavor
& (/*USE_NIL|*/ USE_TYPE_ATTR
));
4988 // Filter out flags passed by our parent. These are not for the fields.
4989 flavor
&= XER_MASK
; // also removes XER_TOPLEVEL
4991 const int field_cnt
= get_count();
4992 const int num_attributes
= get_xer_num_attr();
4994 // The index of potential "order" field, regardless of whether USE_ORDER
4995 // is in use or not.
4996 const int uo_index
= ((p_td
.xer_bits
& EMBED_VALUES
) !=0);
4998 // The first "non-special" field (skipping the USE-ORDER and EMBED-VALUES
4999 // fields); normal processing start at this field.
5000 const int start_at
= uo_index
+ ((p_td
.xer_bits
& USE_ORDER
) != 0);
5001 const int first_nonattr
= start_at
+ num_attributes
;
5003 // The index of the ANY-ATTRIBUTES member, if any
5005 for (int k
= 0; k
< first_nonattr
; ++k
) {
5006 if (xer_descr(k
)->xer_bits
& ANY_ATTRIBUTES
) {
5008 if (!get_at(aa_index
)->is_optional()) {
5009 static_cast<Record_Of_Type
*>(get_at(aa_index
))->set_size(0);
5011 break; // there can be only one, 18.2.2
5015 if (own_tag
) for (success
=reader
.Ok(); success
==1; success
=reader
.Read()) {
5016 type
= reader
.NodeType();
5017 if (type
==XML_READER_TYPE_ELEMENT
) {
5018 verify_name(reader
, p_td
, exer
);
5019 depth
= reader
.Depth();
5020 tag_closed
= reader
.IsEmptyElement();
5027 if (exer
&& (p_td
.xer_bits
& USE_QNAME
)) { // QName trumps everything !
5028 // If element, it looks like this:
5029 // <name xmlns:b0="http://www.furniture.com">b0:table</name>
5030 // If attribute, it looks like this:
5033 if (p_td
.xer_bits
& XER_ATTRIBUTE
) success
= 1; // do nothing
5034 else for (success
= reader
.Read(); success
== 1; success
= reader
.Read()) {
5035 type
= reader
.NodeType();
5036 if (type
== XML_READER_TYPE_TEXT
) break;
5040 xmlChar
*val
= reader
.NewValue();
5041 xmlChar
*npfx
= (xmlChar
*)strchr((char*)val
, ':');
5044 *npfx
++ = '\0'; // cut the string into two
5052 xmlChar
*nsu
= reader
.LookupNamespace(pfx
);
5054 OPTIONAL
<UNIVERSAL_CHARSTRING
> *q_prefix2
=
5055 static_cast<OPTIONAL
<UNIVERSAL_CHARSTRING
>*>(get_at(0));
5056 if (nsu
) *q_prefix2
= (const char*)nsu
;
5057 else q_prefix2
->set_to_omit(); // public in RT2 only
5059 UNIVERSAL_CHARSTRING
*q_name2
= static_cast<UNIVERSAL_CHARSTRING
*>(get_at(1));
5060 *q_name2
= (const char*)npfx
;
5066 else { // not use-qname
5067 TTCN_EncDec_ErrorContext
ec_0("Component '");
5068 TTCN_EncDec_ErrorContext ec_1
;
5069 boolean usenil_attribute
= FALSE
; // true if found and said yes
5071 if (!reader
.IsEmptyElement()) reader
.Read();
5072 // First, the (would-be) attributes (unaffected by USE-ORDER)
5073 for (i
= 0; i
< first_nonattr
; i
++) {
5074 ec_1
.set_msg("%s': ", fld_name(i
));
5075 get_at(i
)->XER_decode(*xer_descr(i
), reader
, flavor
, 0);
5078 else if (own_tag
|| parent_tag
) { // EXER and not UNTAGGED: do attributes
5079 // Prepare for lack of attributes.
5080 // Fields with defaultForEmpty get the D-F-E value, optional get omit.
5081 for (i
= start_at
; i
< first_nonattr
; i
++) {
5082 Base_Type
&fld
= *get_at(i
);
5083 const XERdescriptor_t
& xd
= *xer_descr(i
);
5085 if (fld
.is_optional()) {
5086 fld
.set_to_present();
5087 fld
.get_opt_value()->set_value(xd
.dfeValue
);
5089 else fld
.set_value(xd
.dfeValue
);
5091 else if (fld
.is_optional()) fld
.set_to_omit();
5094 int num_aa
= 0; // index into the ANY-ATTRIBUTE member
5096 const namespace_t
*control_ns
= 0;
5097 if (parent_tag
|| (p_td
.xer_bits
& USE_NIL
)) {
5098 // xsi:type or xsi:nil
5099 control_ns
= p_td
.my_module
->get_controlns();
5102 /* * * * * * * * * Attributes * * * * * * * * * * * * * */
5103 for (success
= reader
.MoveToFirstAttribute();
5104 success
== 1 && reader
.NodeType() == XML_READER_TYPE_ATTRIBUTE
;
5105 success
= reader
.AdvanceAttribute())
5107 if (reader
.IsNamespaceDecl()) {
5108 continue; // namespace declarations are handled for us by libxml2
5111 const char *attr_name
= (const char*)reader
.LocalName();
5112 const char *ns_uri
= (const char*)reader
.NamespaceUri();
5113 int field_index
= get_index_byname(attr_name
, ns_uri
);
5114 if (field_index
!= -1) {
5115 // There is a field. Let it decode the attribute.
5116 ec_1
.set_msg("%s': ", fld_name(field_index
));
5117 get_at(field_index
)->XER_decode(*xer_descr(field_index
), reader
, flavor
, 0);
5121 // Attribute not found. It could be the "nil" attribute
5122 if (p_td
.xer_bits
& USE_NIL
) {
5123 const char *prefix
= (const char*)reader
.Prefix();
5124 // prefix may be NULL, control_ns->px is never NULL or empty
5125 if (prefix
&& !strcmp(prefix
, control_ns
->px
)
5126 && !strcmp((const char*)reader
.LocalName(), "nil"))
5127 { // It is the "nil" attribute
5128 const char *value
= (const char*)reader
.Value();
5130 if (!strcmp(value
, "1") || !strcmp(value
, "true")) {
5131 // The field affected by USE-NIL is always the last one
5132 get_at(field_cnt
-1)->set_to_omit();
5133 usenil_attribute
= TRUE
;
5138 } // it is the "nil" attribute
5139 } // type has USE-NIL
5142 const char *prefix
= (const char*)reader
.Prefix();
5143 // prefix may be NULL, control_ns->px is never NULL or empty
5144 if (prefix
&& !strcmp(prefix
, control_ns
->px
)
5145 && !strcmp((const char*)reader
.LocalName(), "type")) {
5146 continue; // xsi:type has been processed by the parent
5150 if (aa_index
>= 0) {
5151 ec_1
.set_msg("%s': ", fld_name(aa_index
));
5152 TTCN_EncDec_ErrorContext
ec_2("Attribute %d: ", num_aa
);
5153 // We have a component with ANY-ATTRIBUTE. It must be a record of
5154 // UNIVERSAL_CHARSTRING. Add the attribute to it.
5155 Record_Of_Type
*aa
= 0;
5156 if (get_at(aa_index
)->is_optional()) {
5158 get_at(aa_index
)->set_to_present();
5160 aa
= static_cast<Record_Of_Type
*>(get_at(aa_index
)->get_opt_value());
5163 aa
= static_cast<Record_Of_Type
*>(get_at(aa_index
));
5165 UNIVERSAL_CHARSTRING
*new_elem
= static_cast<UNIVERSAL_CHARSTRING
*>
5166 (aa
->get_at(num_aa
++));
5168 // Construct the AnyAttributeFormat (X.693amd1, 18.2.6)
5170 const xmlChar
*name
= reader
.LocalName();
5171 const xmlChar
*val
= reader
.Value();
5172 const xmlChar
*uri
= reader
.NamespaceUri();
5174 if (xer_descr(aa_index
)->xer_bits
& (ANY_FROM
| ANY_EXCEPT
)) {
5175 check_namespace_restrictions(*xer_descr(aa_index
), (const char*)uri
);
5177 // We don't care about reader.Prefix()
5178 // Using strlen to count UTF8 bytes, not characters
5179 aabuf
.put_s(uri
? strlen((const char*)uri
) : 0, uri
);
5180 if (uri
&& *uri
) aabuf
.put_c(' ');
5181 aabuf
.put_s(name
? strlen((const char*)name
) : 0, name
);
5184 aabuf
.put_s(val
? strlen((const char*)val
) : 0, val
);
5186 new_elem
->decode_utf8(aabuf
.get_len(), aabuf
.get_data());
5191 // Lastly check for the xsi:schemaLocation attribute, this does not
5192 // affect TTCN-3, but it shouldn't cause a DTE
5193 if (reader
.LocalName() && !strcmp((const char*)reader
.LocalName(), "schemaLocation")) {
5195 control_ns
= p_td
.my_module
->get_controlns();
5197 if (reader
.Prefix() && !strcmp((const char*)reader
.Prefix(), control_ns
->px
)) {
5202 // Nobody wanted the attribute. That is an error.
5203 ec_0
.set_msg(" "); ec_1
.set_msg(" ");
5204 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG
,
5205 "Unexpected attribute '%s', ns '%s'", attr_name
,
5206 ns_uri
? ns_uri
: "");
5209 // Now check that all mandatory attributes have been set
5210 for (i
= start_at
; i
< first_nonattr
; ++i
) {
5211 Base_Type
* fld
= get_at(i
);
5212 if (fld
->is_optional()) continue; // field is allowed to be unset
5213 if (!fld
->is_bound()) {
5214 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG
,
5215 "Missing attribute '%s'", this->fld_name(i
));
5219 i
= first_nonattr
; // finished with attributes
5220 // AdvanceAttribute did MoveToElement. Move into the content (if any).
5221 if (!reader
.IsEmptyElement()) reader
.Read();
5222 } // end if (own_tag)
5224 /* * * * * * * * Non-attributes (elements) * * * * * * * * * * * */
5225 embed_values_dec_struct_t
* emb_val
= 0;
5226 if (exer
&& (p_td
.xer_bits
& EMBED_VALUES
)) {
5227 emb_val
= new embed_values_dec_struct_t
;
5228 emb_val
->embval_array
= static_cast<Record_Of_Type
*>(get_at(0));
5229 emb_val
->embval_array
->set_size(0);
5230 emb_val
->embval_index
= 0;
5233 if (exer
&& (p_td
.xer_bits
& USE_ORDER
)) {
5234 // Set all optional fields to omit because their respective XER_decode
5235 // will not be run (and will stay unbound) if the value is missing.
5236 int n_optionals
= 0;
5237 for (int B
= optional_count() - 1; B
>=+0; B
--) {
5238 int oi
= get_optional_indexes()[B
];
5239 if (oi
< first_nonattr
) break;
5240 get_at(oi
)->set_to_omit();
5244 Record_Of_Type
*use_order
= static_cast<Record_Of_Type
*>(get_at(uo_index
));
5245 // Initialize the use_order field to empty. Let it grow on demand.
5246 // (setting it to the minimum acceptable size may leave unbound elements
5247 // if the XML was incomplete).
5248 use_order
->set_size(0);
5250 // Nothing to order if there are no child elements
5252 Record_Type
*jumbled
= this; // the record affected by USE_ORDER
5253 int begin
= first_nonattr
;
5254 int end
= field_cnt
; // "one past"
5255 if (p_td
.xer_bits
& USE_NIL
) {
5256 Base_Type
*last_optional
= get_at(field_cnt
-1);
5257 if (!usenil_attribute
) { // exer known true
5258 last_optional
->set_to_present();
5259 jumbled
= static_cast<Record_Type
*>(last_optional
->get_opt_value());
5260 // We will operate on the members of last_optional,
5261 // effectively bypassing last_optional->XER_decode() itself.
5263 end
= jumbled
->get_count();
5264 ec_1
.set_msg("%s': ", fld_name(field_cnt
-1));
5267 if (num_attributes
> 0
5268 && first_nonattr
!= field_cnt
5269 && i
== first_nonattr
- 1) { // exer known true
5270 // If there were attributes and their processing just finished,
5271 // the reader is positioned on the start tag of the record.
5272 // Move ahead, unless there are no non-attribute fields.
5275 // Then, the non-attributes
5277 // The index runs over the members affected by USE-ORDER.
5278 // This is [first_nonattr,field_cnt) unless USE-NIL is involved,
5279 // in which case it's [0,optional_sequence::field_cnt)
5280 int *seen
= new int[end
-begin
];
5282 int last_any_elem
= begin
- 1;
5283 // The index of the latest embedded value can change outside of this function
5284 // (if the field is an untagged record of), in this case the next value should
5285 // be ignored, as it's already been handled by the record of
5286 int last_embval_index
= 0;
5287 bool early_exit
= false;
5288 for (i
= begin
; i
< end
; i
++) {
5289 for (success
= reader
.Ok(); success
== 1; success
= reader
.Read()) {
5290 type
= reader
.NodeType();
5291 if (0 != emb_val
&& reader
.NodeType()==XML_READER_TYPE_TEXT
) {
5292 UNIVERSAL_CHARSTRING
emb_ustr((const char*)reader
.Value());
5293 emb_val
->embval_array
->get_at(emb_val
->embval_index
)->set_value(&emb_ustr
);
5295 // The non-attribute components must not be UNTAGGED
5296 if (type
== XML_READER_TYPE_ELEMENT
) break;
5297 if (type
== XML_READER_TYPE_END_ELEMENT
) {
5303 if (last_embval_index
== emb_val
->embval_index
) {
5304 ++emb_val
->embval_index
;
5306 last_embval_index
= emb_val
->embval_index
;
5308 if (success
!= 1 || early_exit
) break;
5309 const char *name
= (const char *)reader
.LocalName();
5310 bool field_name_found
= false;
5311 // Find out which member it is.
5312 // FIXME some hashing should be implemented
5313 for (int k
= begin
; k
< end
; k
++) {
5314 if (!(jumbled
->xer_descr(k
)->xer_bits
& ANY_ELEMENT
) &&
5315 check_name(name
, *jumbled
->xer_descr(k
), 1)) {
5316 ec_1
.set_msg("%s': ", jumbled
->fld_name(k
));
5318 // Check for the same field being decoded twice.
5319 // We can't use the field's is_bound()/is_present(),
5320 // because the field may be bound on input, e.g. for
5321 // prototype(fast) or prototype(backtrack).
5322 int in_dex
= k
- begin
;
5323 for (int o
= 0; o
< num_seen
;++o
) {
5324 if (in_dex
== seen
[o
]) TTCN_EncDec_ErrorContext::error(
5325 TTCN_EncDec::ET_INVAL_MSG
, "Duplicate element");
5327 seen
[num_seen
++] = in_dex
;
5328 // Set the next use-order member.
5329 // Non-const get_at creates the object in the record-of.
5330 static_cast<Enum_Type
*>(use_order
->get_at(i
- begin
))
5332 Base_Type
*b
= jumbled
->get_at(k
);
5333 b
->XER_decode(*jumbled
->xer_descr(k
), reader
, flavor
, emb_val
);
5334 field_name_found
= true;
5338 if (!field_name_found
) {
5339 // Check the anyElement fields
5340 for (int k
= last_any_elem
+ 1; k
< end
; k
++) {
5341 if (jumbled
->xer_descr(k
)->xer_bits
& ANY_ELEMENT
) {
5342 ec_1
.set_msg("%s': ", jumbled
->fld_name(k
));
5344 // Check for the same field being decoded twice.
5345 // We can't use the field's is_bound()/is_present(),
5346 // because the field may be bound on input, e.g. for
5347 // prototype(fast) or prototype(backtrack).
5348 int in_dex
= k
- begin
;
5349 for (int o
= 0; o
< num_seen
;++o
) {
5350 if (in_dex
== seen
[o
]) TTCN_EncDec_ErrorContext::error(
5351 TTCN_EncDec::ET_INVAL_MSG
, "Duplicate element");
5353 seen
[num_seen
++] = in_dex
;
5354 // Set the next use-order member.
5355 // Non-const get_at creates the object in the record-of.
5356 static_cast<Enum_Type
*>(use_order
->get_at(i
- begin
))
5358 Base_Type
*b
= jumbled
->get_at(k
);
5359 b
->XER_decode(*jumbled
->xer_descr(k
), reader
, flavor
, emb_val
);
5361 field_name_found
= true;
5366 if (!field_name_found
) {
5367 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG
,
5368 "Bad XML tag '%s' instead of a valid field", name
);
5373 if (reader
.NodeType()==XML_READER_TYPE_TEXT
) {
5374 UNIVERSAL_CHARSTRING
emb_ustr((const char*)reader
.Value());
5375 emb_val
->embval_array
->get_at(emb_val
->embval_index
)->set_value(&emb_ustr
);
5377 if (last_embval_index
== emb_val
->embval_index
) {
5378 ++emb_val
->embval_index
;
5382 ec_1
.set_msg(" "); // no active component
5385 // Check that we collected the required number of children
5386 int num_collected
= use_order
->size_of();
5387 if (p_td
.xer_bits
& USE_NIL
) {
5388 int expected
= usenil_attribute
? 0 : jumbled
->get_count();
5389 if (num_collected
!= expected
) {
5390 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INCOMPL_MSG
,
5391 "Incorrect number of fields %d, expected %d",
5392 num_collected
, expected
);
5396 if (num_collected
< field_cnt
- first_nonattr
- n_optionals
5397 ||num_collected
> field_cnt
- first_nonattr
) {
5398 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INCOMPL_MSG
,
5399 "Wrong number of fields! size = %d, expected %d..%d",
5400 use_order
->size_of(), field_cnt
- first_nonattr
- n_optionals
,
5401 field_cnt
- first_nonattr
);
5404 } // not empty element
5406 else { // not USE-ORDER, simpler code
5407 if (usenil_attribute
) {
5408 reader
.MoveToElement(); // value absent, nothing more to do
5410 // The index of the latest embedded value can change outside of this function
5411 // (if the field is a untagged record of), in this case the next value should
5412 // be ignored, as it's already been handled by the record of
5413 // Omitted fields can also reset this value
5414 int last_embval_index
= 0;
5415 for (; i
<field_cnt
; i
++) {
5417 if (reader
.NodeType()==XML_READER_TYPE_TEXT
) {
5418 UNIVERSAL_CHARSTRING
emb_ustr((const char*)reader
.Value());
5419 emb_val
->embval_array
->get_at(emb_val
->embval_index
)->set_value(&emb_ustr
);
5421 if (last_embval_index
== emb_val
->embval_index
) {
5422 ++emb_val
->embval_index
;
5424 last_embval_index
= emb_val
->embval_index
;
5426 ec_1
.set_msg("%s': ", fld_name(i
));
5427 if (exer
&& i
==field_cnt
-1 && p_td
.dfeValue
&& reader
.IsEmptyElement()) {
5428 get_at(i
)->set_value(p_td
.dfeValue
);
5431 // In case the field is an optional anyElement -> check if it should be omitted
5432 bool optional_any_elem_check
= true;
5433 if (get_at(i
)->is_optional() && (xer_descr(i
)->xer_bits
& ANY_ELEMENT
)) {
5434 // The "anyElement" coding instruction can only be applied to a universal charstring field
5435 OPTIONAL
<UNIVERSAL_CHARSTRING
>* opt_field
= dynamic_cast<OPTIONAL
<UNIVERSAL_CHARSTRING
>*>(get_at(i
));
5437 const char* next_field_name
= NULL
;
5438 if (i
< field_cnt
- 1) {
5439 next_field_name
= fld_name(i
+ 1);
5441 optional_any_elem_check
= opt_field
->XER_check_any_elem(reader
, next_field_name
, tag_closed
);
5444 if (optional_any_elem_check
) {
5445 int new_flavor
= flavor
;
5446 if (i
== field_cnt
-1) new_flavor
|= (p_td
.xer_bits
& USE_NIL
);
5447 if (tag_closed
) new_flavor
|= PARENT_CLOSED
;
5449 get_at(i
)->XER_decode(*xer_descr(i
), reader
, new_flavor
, emb_val
);
5452 if (!get_at(i
)->is_present()) {
5453 // there was no new element, the last embedded value is for the next field
5454 // (or the end of the record if this is the last field)
5455 last_embval_index
= -1;
5459 if (reader
.NodeType()==XML_READER_TYPE_TEXT
) {
5460 UNIVERSAL_CHARSTRING
emb_ustr((const char*)reader
.Value());
5461 emb_val
->embval_array
->get_at(emb_val
->embval_index
)->set_value(&emb_ustr
);
5463 if (last_embval_index
== emb_val
->embval_index
) {
5464 ++emb_val
->embval_index
;
5471 static const UNIVERSAL_CHARSTRING
emptystring(0, (const char*)NULL
);
5472 for (int j
= 0; j
< emb_val
->embval_index
; ++j
) {
5473 if (!emb_val
->embval_array
->get_at(j
)->is_bound()) {
5474 emb_val
->embval_array
->get_at(j
)->set_value(&emptystring
);
5478 } // if embed-values
5482 // Check if every non-optional field has been set
5483 for (i
= 0; i
< field_cnt
; ++i
) {
5484 if (!get_at(i
)->is_optional() && !get_at(i
)->is_bound()) {
5485 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INCOMPL_MSG
,
5486 "No data found for non-optional field '%s'", fld_name(i
));
5491 // We had our start tag. Then our fields did their thing.
5492 // Now we expect the end tag. And it better be our end tag!
5494 for (success
= reader
.Ok(); success
== 1; success
= reader
.Read()) {
5495 type
= reader
.NodeType();
5496 current_depth
= reader
.Depth();
5497 if (current_depth
> depth
) {
5498 if (XML_READER_TYPE_ELEMENT
== type
) {
5499 // We found a deeper start tag; it was not processed at all.
5500 // That is an error (maybe we should report error for all node types
5501 // except TEXT and WHITESPACE, not just ELEMENT).
5502 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TAG
,
5503 "Unprocessed XML tag `%s'", (const char *)reader
.Name());
5506 continue; // go past hoping that our end tag will arrive eventually
5508 else if (current_depth
== depth
) { // at our level
5509 if (XML_READER_TYPE_ELEMENT
== type
) {
5510 verify_name(reader
, p_td
, exer
);
5511 if (reader
.IsEmptyElement()) {
5512 // FIXME this shouldn't really be possible;
5513 // only an empty record should be encoded as an empty element,
5514 // but those are implemented by Empty_Record_Type, not Record_Type.
5515 reader
.Read(); // one last time
5519 // If we find an end tag at the right depth, it must be ours
5520 else if (XML_READER_TYPE_END_ELEMENT
== type
) {
5521 verify_end(reader
, p_td
, depth
, exer
);
5526 else { //current_depth < depth; something has gone horribly wrong
5527 break; // better quit before we do further damage
5528 // Don't report an error; every enclosing type would do so,
5529 // spewing the same message over and over.
5533 return 1; // decode successful
5536 int Record_Type::JSON_encode(const TTCN_Typedescriptor_t
&, JSON_Tokenizer
& p_tok
) const
5539 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND
,
5540 "Encoding an unbound %s value.", is_set() ? "set" : "record");
5544 int enc_len
= p_tok
.put_next_token(JSON_TOKEN_OBJECT_START
, NULL
);
5546 int field_count
= get_count();
5547 for(int i
= 0; i
< field_count
; ++i
) {
5548 boolean metainfo_unbound
= NULL
!= fld_descr(i
)->json
&& fld_descr(i
)->json
->metainfo_unbound
;
5549 if ((NULL
!= fld_descr(i
)->json
&& fld_descr(i
)->json
->omit_as_null
) ||
5550 get_at(i
)->is_present() || metainfo_unbound
) {
5551 const char* field_name
= (NULL
!= fld_descr(i
)->json
&& NULL
!= fld_descr(i
)->json
->alias
) ?
5552 fld_descr(i
)->json
->alias
: fld_name(i
);
5553 enc_len
+= p_tok
.put_next_token(JSON_TOKEN_NAME
, field_name
);
5554 if (metainfo_unbound
&& !get_at(i
)->is_bound()) {
5555 enc_len
+= p_tok
.put_next_token(JSON_TOKEN_LITERAL_NULL
);
5556 char* metainfo_str
= mprintf("metainfo %s", field_name
);
5557 enc_len
+= p_tok
.put_next_token(JSON_TOKEN_NAME
, metainfo_str
);
5559 enc_len
+= p_tok
.put_next_token(JSON_TOKEN_STRING
, "\"unbound\"");
5562 enc_len
+= get_at(i
)->JSON_encode(*fld_descr(i
), p_tok
);
5567 enc_len
+= p_tok
.put_next_token(JSON_TOKEN_OBJECT_END
, NULL
);
5571 int Record_Type::JSON_decode(const TTCN_Typedescriptor_t
& p_td
, JSON_Tokenizer
& p_tok
, boolean p_silent
)
5573 json_token_t token
= JSON_TOKEN_NONE
;
5574 int dec_len
= p_tok
.get_next_token(&token
, NULL
, NULL
);
5575 if (JSON_TOKEN_ERROR
== token
) {
5576 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG
, JSON_DEC_BAD_TOKEN_ERROR
, "");
5577 return JSON_ERROR_FATAL
;
5579 else if (JSON_TOKEN_OBJECT_START
!= token
) {
5580 return JSON_ERROR_INVALID_TOKEN
;
5584 const int field_count
= get_count();
5586 // initialize meta info states
5587 int* metainfo
= new int[field_count
];
5588 for (int i
= 0; i
< field_count
; ++i
) {
5589 metainfo
[i
] = (NULL
!= fld_descr(i
)->json
&& fld_descr(i
)->json
->metainfo_unbound
) ?
5590 JSON_METAINFO_NONE
: JSON_METAINFO_NOT_APPLICABLE
;
5594 // Read name - value token pairs until we reach some other token
5596 size_t name_len
= 0;
5597 size_t buf_pos
= p_tok
.get_buf_pos();
5598 dec_len
+= p_tok
.get_next_token(&token
, &name
, &name_len
);
5599 if (JSON_TOKEN_ERROR
== token
) {
5600 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG
, JSON_DEC_BAD_TOKEN_ERROR
, "");
5601 return JSON_ERROR_FATAL
;
5603 else if (JSON_TOKEN_NAME
!= token
) {
5604 // undo the last action on the buffer
5605 p_tok
.set_buf_pos(buf_pos
);
5609 // check for meta info
5610 boolean is_metainfo
= FALSE
;
5611 if (name_len
> 9 && 0 == strncmp(name
, "metainfo ", 9)) {
5619 for (field_idx
= 0; field_idx
< field_count
; ++field_idx
) {
5620 const char* expected_name
= 0;
5621 if (NULL
!= fld_descr(field_idx
)->json
&& NULL
!= fld_descr(field_idx
)->json
->alias
) {
5622 expected_name
= fld_descr(field_idx
)->json
->alias
;
5624 expected_name
= fld_name(field_idx
);
5626 if (strlen(expected_name
) == name_len
&&
5627 0 == strncmp(expected_name
, name
, name_len
)) {
5631 if (field_count
== field_idx
) {
5632 // invalid field name
5633 char* name2
= mcopystrn(name
, name_len
);
5634 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG
, is_metainfo
?
5635 JSON_DEC_METAINFO_NAME_ERROR
: JSON_DEC_INVALID_NAME_ERROR
, name2
);
5636 // if this is set to a warning, skip the value of the field
5637 dec_len
+= p_tok
.get_next_token(&token
, NULL
, NULL
);
5638 if (JSON_TOKEN_NUMBER
!= token
&& JSON_TOKEN_STRING
!= token
&&
5639 JSON_TOKEN_LITERAL_TRUE
!= token
&& JSON_TOKEN_LITERAL_FALSE
!= token
&&
5640 JSON_TOKEN_LITERAL_NULL
!= token
) {
5641 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG
, JSON_DEC_FIELD_TOKEN_ERROR
, name2
);
5643 return JSON_ERROR_FATAL
;
5650 if (JSON_METAINFO_NOT_APPLICABLE
!= metainfo
[field_idx
]) {
5652 char* info_value
= 0;
5653 size_t info_len
= 0;
5654 dec_len
+= p_tok
.get_next_token(&token
, &info_value
, &info_len
);
5655 if (JSON_TOKEN_STRING
== token
&& 9 == info_len
&&
5656 0 == strncmp(info_value
, "\"unbound\"", 9)) {
5657 metainfo
[field_idx
] = JSON_METAINFO_UNBOUND
;
5660 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG
, JSON_DEC_METAINFO_VALUE_ERROR
,
5661 fld_name(field_idx
));
5662 return JSON_ERROR_FATAL
;
5666 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG
, JSON_DEC_METAINFO_NOT_APPLICABLE
,
5667 fld_name(field_idx
));
5668 return JSON_ERROR_FATAL
;
5672 buf_pos
= p_tok
.get_buf_pos();
5673 int ret_val
= get_at(field_idx
)->JSON_decode(*fld_descr(field_idx
), p_tok
, p_silent
);
5675 if (JSON_ERROR_INVALID_TOKEN
== ret_val
) {
5676 // undo the last action on the buffer, check if the invalid token was a null token
5677 p_tok
.set_buf_pos(buf_pos
);
5678 p_tok
.get_next_token(&token
, NULL
, NULL
);
5679 if (JSON_TOKEN_LITERAL_NULL
== token
) {
5680 if (JSON_METAINFO_NONE
== metainfo
[field_idx
]) {
5681 // delay reporting an error for now, there might be meta info later
5682 metainfo
[field_idx
] = JSON_METAINFO_NEEDED
;
5685 else if (JSON_METAINFO_UNBOUND
== metainfo
[field_idx
]) {
5686 // meta info already found
5690 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG
, JSON_DEC_FIELD_TOKEN_ERROR
, fld_name(field_idx
));
5692 return JSON_ERROR_FATAL
;
5699 dec_len
+= p_tok
.get_next_token(&token
, NULL
, NULL
);
5700 if (JSON_TOKEN_OBJECT_END
!= token
) {
5701 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG
, JSON_DEC_OBJECT_END_TOKEN_ERROR
, "");
5702 return JSON_ERROR_FATAL
;
5705 // Check if every field has been set and handle meta info
5706 for (int field_idx
= 0; field_idx
< field_count
; ++field_idx
) {
5707 Base_Type
* field
= get_at(field_idx
);
5708 if (JSON_METAINFO_UNBOUND
== metainfo
[field_idx
]) {
5711 else if (JSON_METAINFO_NEEDED
== metainfo
[field_idx
]) {
5712 // no meta info was found for this field, report the delayed error
5713 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG
, JSON_DEC_FIELD_TOKEN_ERROR
, fld_name(field_idx
));
5715 else if (!field
->is_bound()) {
5716 if (NULL
!= fld_descr(field_idx
)->json
&& NULL
!= fld_descr(field_idx
)->json
->default_value
) {
5717 get_at(field_idx
)->JSON_decode(*fld_descr(field_idx
), DUMMY_BUFFER
, p_silent
);
5719 else if (field
->is_optional()) {
5720 field
->set_to_omit();
5722 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG
, JSON_DEC_MISSING_FIELD_ERROR
, fld_name(field_idx
));
5723 return JSON_ERROR_FATAL
;
5733 ////////////////////////////////////////////////////////////////////////////////
5735 Empty_Record_Type::Empty_Record_Type(): bound_flag(FALSE
)
5739 Empty_Record_Type::Empty_Record_Type(const Empty_Record_Type
& other_value
)
5740 : Base_Type(other_value
), bound_flag(other_value
.bound_flag
)
5742 if (!other_value
.bound_flag
)
5743 TTCN_error("Copying an unbound value of type %s.",
5744 other_value
.get_descriptor()->name
);
5747 boolean
Empty_Record_Type::operator==(null_type
) const
5750 TTCN_error("Comparison of an unbound value of type %s.",
5751 get_descriptor()->name
);
5755 void Empty_Record_Type::log() const
5757 if (bound_flag
) TTCN_Logger::log_event_str("{ }");
5758 else TTCN_Logger::log_event_unbound();
5761 void Empty_Record_Type::set_param(Module_Param
& param
) {
5762 param
.basic_check(Module_Param::BC_VALUE
, "empty record/set value (i.e. { })");
5763 Module_Param_Ptr mp
= ¶m
;
5764 if (param
.get_type() == Module_Param::MP_Reference
) {
5765 mp
= param
.get_referenced_param();
5767 if (mp
->get_type()!=Module_Param::MP_Value_List
|| mp
->get_size()>0) {
5768 param
.type_error("empty record/set value (i.e. { })", get_descriptor()->name
);
5773 Module_Param
* Empty_Record_Type::get_param(Module_Param_Name
& /* param_name */) const
5776 return new Module_Param_Unbound();
5778 return new Module_Param_Value_List();
5781 void Empty_Record_Type::encode_text(Text_Buf
& /*text_buf*/) const
5784 TTCN_error("Text encoder: Encoding an unbound value of type %s.",
5785 get_descriptor()->name
);
5788 void Empty_Record_Type::decode_text(Text_Buf
& /*text_buf*/)
5793 boolean
Empty_Record_Type::is_equal(const Base_Type
* other_value
) const
5795 const Empty_Record_Type
* r2
= static_cast<const Empty_Record_Type
*>(other_value
);
5796 if ((bound_flag
&& r2
->bound_flag
) || (!bound_flag
&& !r2
->bound_flag
))
5798 if (!bound_flag
|| !r2
->bound_flag
)
5799 TTCN_error("Comparison of an unbound value of type %s.", get_descriptor()->name
);
5803 void Empty_Record_Type::set_value(const Base_Type
* other_value
)
5805 if (!static_cast<const Empty_Record_Type
*>(other_value
)->is_bound())
5806 TTCN_error("Assignment of an unbound value of type %s.",
5807 other_value
->get_descriptor()->name
);
5811 void Empty_Record_Type::encode(const TTCN_Typedescriptor_t
& p_td
,
5812 TTCN_Buffer
& p_buf
, TTCN_EncDec::coding_t p_coding
, ...) const
5815 va_start(pvar
, p_coding
);
5817 case TTCN_EncDec::CT_BER
: {
5818 TTCN_EncDec_ErrorContext
ec("While BER-encoding type '%s': ", p_td
.name
);
5819 unsigned BER_coding
=va_arg(pvar
, unsigned);
5820 BER_encode_chk_coding(BER_coding
);
5821 ASN_BER_TLV_t
*tlv
=BER_encode_TLV(p_td
, BER_coding
);
5822 tlv
->put_in_buffer(p_buf
);
5823 ASN_BER_TLV_t::destruct(tlv
);
5825 case TTCN_EncDec::CT_RAW
: {
5826 TTCN_EncDec_ErrorContext
ec("While RAW-encoding type '%s': ", p_td
.name
);
5827 if(!p_td
.raw
) TTCN_EncDec_ErrorContext::error_internal
5828 ("No RAW descriptor available for type '%s'.", p_td
.name
);
5832 RAW_enc_tree
root(FALSE
, NULL
, &rp
, 1, p_td
.raw
);
5833 RAW_encode(p_td
, root
);
5834 root
.put_to_buf(p_buf
);
5836 case TTCN_EncDec::CT_TEXT
: {
5837 TTCN_EncDec_ErrorContext
ec("While TEXT-encoding type '%s': ", p_td
.name
);
5838 if(!p_td
.text
) TTCN_EncDec_ErrorContext::error_internal
5839 ("No TEXT descriptor available for type '%s'.", p_td
.name
);
5840 TEXT_encode(p_td
,p_buf
);
5842 case TTCN_EncDec::CT_XER
: {
5843 TTCN_EncDec_ErrorContext
ec("While XER-encoding type '%s': ", p_td
.name
);
5844 unsigned XER_coding
=va_arg(pvar
, unsigned);
5845 XER_encode(*(p_td
.xer
),p_buf
, XER_coding
, 0, 0);
5848 case TTCN_EncDec::CT_JSON
: {
5849 TTCN_EncDec_ErrorContext
ec("While JSON-encoding type '%s': ", p_td
.name
);
5850 if(!p_td
.json
) TTCN_EncDec_ErrorContext::error_internal
5851 ("No JSON descriptor available for type '%s'.", p_td
.name
);
5852 JSON_Tokenizer
tok(va_arg(pvar
, int) != 0);
5853 JSON_encode(p_td
, tok
);
5854 p_buf
.put_s(tok
.get_buffer_length(), (const unsigned char*)tok
.get_buffer());
5857 TTCN_error("Unknown coding method requested to encode type '%s'", p_td
.name
);
5862 void Empty_Record_Type::decode(const TTCN_Typedescriptor_t
& p_td
,
5863 TTCN_Buffer
& p_buf
, TTCN_EncDec::coding_t p_coding
, ...)
5866 va_start(pvar
, p_coding
);
5868 case TTCN_EncDec::CT_BER
: {
5869 TTCN_EncDec_ErrorContext
ec("While BER-decoding type '%s': ", p_td
.name
);
5870 unsigned L_form
=va_arg(pvar
, unsigned);
5872 BER_decode_str2TLV(p_buf
, tlv
, L_form
);
5873 BER_decode_TLV(p_td
, tlv
, L_form
);
5874 if(tlv
.isComplete
) p_buf
.increase_pos(tlv
.get_len());
5876 case TTCN_EncDec::CT_RAW
: {
5877 TTCN_EncDec_ErrorContext
ec("While RAW-decoding type '%s': ", p_td
.name
);
5879 TTCN_EncDec_ErrorContext::error_internal
5880 ("No RAW descriptor available for type '%s'.", p_td
.name
);
5882 switch(p_td
.raw
->top_bit_order
) {
5890 if(RAW_decode(p_td
, p_buf
, p_buf
.get_len()*8, order
)<0)
5891 ec
.error(TTCN_EncDec::ET_INCOMPL_MSG
,
5892 "Can not decode type '%s', because invalid or incomplete"
5893 " message was received", p_td
.name
);
5895 case TTCN_EncDec::CT_TEXT
: {
5896 Limit_Token_List limit
;
5897 TTCN_EncDec_ErrorContext
ec("While TEXT-decoding type '%s': ", p_td
.name
);
5898 if(!p_td
.text
) TTCN_EncDec_ErrorContext::error_internal
5899 ("No TEXT descriptor available for type '%s'.", p_td
.name
);
5900 const unsigned char *b
=p_buf
.get_data();
5901 if(b
[p_buf
.get_len()-1]!='\0'){
5902 p_buf
.set_pos(p_buf
.get_len());
5903 p_buf
.put_zero(8,ORDER_LSB
);
5906 if(TEXT_decode(p_td
,p_buf
,limit
)<0)
5907 ec
.error(TTCN_EncDec::ET_INCOMPL_MSG
,
5908 "Can not decode type '%s', because invalid or incomplete"
5909 " message was received", p_td
.name
);
5911 case TTCN_EncDec::CT_XER
: {
5912 TTCN_EncDec_ErrorContext
ec("While XER-decoding type '%s': ", p_td
.name
);
5913 unsigned XER_coding
=va_arg(pvar
, unsigned);
5914 XmlReaderWrap
reader(p_buf
);
5915 for (int success
=reader
.Read(); success
==1; success
=reader
.Read()) {
5916 if (reader
.NodeType() == XML_READER_TYPE_ELEMENT
) break;
5918 XER_decode(*(p_td
.xer
), reader
, XER_coding
| XER_TOPLEVEL
, 0);
5919 size_t bytes
= reader
.ByteConsumed();
5920 p_buf
.set_pos(bytes
);
5922 case TTCN_EncDec::CT_JSON
: {
5923 TTCN_EncDec_ErrorContext
ec("While JSON-decoding type '%s': ", p_td
.name
);
5924 if(!p_td
.json
) TTCN_EncDec_ErrorContext::error_internal
5925 ("No JSON descriptor available for type '%s'.", p_td
.name
);
5926 JSON_Tokenizer
tok((const char*)p_buf
.get_data(), p_buf
.get_len());
5927 if(JSON_decode(p_td
, tok
, false)<0)
5928 ec
.error(TTCN_EncDec::ET_INCOMPL_MSG
,
5929 "Can not decode type '%s', because invalid or incomplete"
5930 " message was received", p_td
.name
);
5931 p_buf
.set_pos(tok
.get_buf_pos());
5934 TTCN_error("Unknown coding method requested to decode type '%s'", p_td
.name
);
5939 ASN_BER_TLV_t
* Empty_Record_Type::BER_encode_TLV(const TTCN_Typedescriptor_t
& p_td
,
5940 unsigned p_coding
) const
5942 BER_chk_descr(p_td
);
5943 ASN_BER_TLV_t
*new_tlv
=ASN_BER_TLV_t::construct(NULL
);
5944 new_tlv
=ASN_BER_V2TLV(new_tlv
, p_td
, p_coding
);
5948 boolean
Empty_Record_Type::BER_decode_TLV(const TTCN_Typedescriptor_t
& p_td
,
5949 const ASN_BER_TLV_t
& p_tlv
, unsigned L_form
)
5951 BER_chk_descr(p_td
);
5952 ASN_BER_TLV_t stripped_tlv
;
5953 BER_decode_strip_tags(*p_td
.ber
, p_tlv
, L_form
, stripped_tlv
);
5954 TTCN_EncDec_ErrorContext
ec_0("While decoding '%s' type: ", get_descriptor()->name
);
5955 stripped_tlv
.chk_constructed_flag(TRUE
);
5960 int Empty_Record_Type::RAW_encode(const TTCN_Typedescriptor_t
& p_td
,
5961 RAW_enc_tree
& /*myleaf*/) const
5963 if (!bound_flag
) TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND
,
5964 "Encoding an unbound value of type %s.", p_td
.name
);
5968 int Empty_Record_Type::RAW_decode(const TTCN_Typedescriptor_t
& p_td
,
5969 TTCN_Buffer
& buff
, int /*limit*/, raw_order_t
/*top_bit_ord*/,
5970 boolean
/*no_err*/, int /*sel_field*/, boolean
/*first_call*/)
5973 return buff
.increase_pos_padd(p_td
.raw
->prepadding
)
5974 + buff
.increase_pos_padd(p_td
.raw
->padding
);
5977 int Empty_Record_Type::TEXT_encode(const TTCN_Typedescriptor_t
& p_td
, TTCN_Buffer
& buff
) const
5979 int encoded_length
=0;
5980 if(p_td
.text
->begin_encode
) {
5981 buff
.put_cs(*p_td
.text
->begin_encode
);
5982 encoded_length
+=p_td
.text
->begin_encode
->lengthof();
5985 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND
, "Encoding an unbound value.");
5987 if(p_td
.text
->end_encode
) {
5988 buff
.put_cs(*p_td
.text
->end_encode
);
5989 encoded_length
+=p_td
.text
->end_encode
->lengthof();
5991 return encoded_length
;
5994 int Empty_Record_Type::TEXT_decode(const TTCN_Typedescriptor_t
& p_td
,
5995 TTCN_Buffer
& buff
, Limit_Token_List
& /*limit*/, boolean no_err
, boolean
/*first_call*/)
5997 int decoded_length
=0;
5998 if(p_td
.text
->begin_decode
) {
6000 if((tl
=p_td
.text
->begin_decode
->match_begin(buff
))<0) {
6001 if(no_err
)return -1;
6002 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR
,
6003 "The specified token '%s' not found for '%s': ",
6004 (const char*)*(p_td
.text
->begin_decode
), p_td
.name
);
6008 buff
.increase_pos(tl
);
6010 if(p_td
.text
->end_decode
) {
6012 if((tl
=p_td
.text
->end_decode
->match_begin(buff
))<0) {
6013 if(no_err
)return -1;
6014 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR
,
6015 "The specified token '%s' not found for '%s': ",
6016 (const char*)*(p_td
.text
->end_decode
), p_td
.name
);
6020 buff
.increase_pos(tl
);
6023 return decoded_length
;
6026 int Empty_Record_Type::XER_encode(const XERdescriptor_t
& p_td
,
6027 TTCN_Buffer
& p_buf
, unsigned int flavor
, int indent
, embed_values_enc_struct_t
*) const
6029 int encoded_length
=(int)p_buf
.get_len();
6030 int indenting
= !is_canonical(flavor
);
6031 int exer
= is_exer(flavor
);
6032 if (indenting
) do_indent(p_buf
, indent
);
6034 if (exer
) write_ns_prefix(p_td
, p_buf
);
6035 p_buf
.put_s((size_t)p_td
.namelens
[exer
]-2, (cbyte
*)p_td
.names
[exer
]);
6036 p_buf
.put_s(2 + indenting
, (cbyte
*)"/>\n");
6037 return (int)p_buf
.get_len() - encoded_length
;
6040 int Empty_Record_Type::XER_decode(const XERdescriptor_t
& p_td
,
6041 XmlReaderWrap
& reader
, unsigned int flavor
, embed_values_dec_struct_t
*)
6043 int exer
= is_exer(flavor
);
6045 int success
, depth
= -1;
6046 for (success
=reader
.Ok(); success
==1; success
=reader
.Read()) {
6047 int type
= reader
.NodeType();
6048 if (type
==XML_READER_TYPE_ELEMENT
) {
6049 verify_name(reader
, p_td
, exer
);
6050 depth
= reader
.Depth();
6052 if (reader
.IsEmptyElement()) {
6053 reader
.Read(); break;
6055 else if ((flavor
& XER_MASK
) == XER_CANONICAL
) {
6056 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG
,
6057 "Expected an empty element tag");
6058 // Stay in the loop and look for the end element, in case the error
6059 // was ignored or reduced to warning.
6062 else if (type
== XML_READER_TYPE_END_ELEMENT
&& depth
!= -1) {
6063 verify_end(reader
, p_td
, depth
, exer
);
6068 return 1; // decode successful
6071 int Empty_Record_Type::JSON_encode(const TTCN_Typedescriptor_t
&, JSON_Tokenizer
& p_tok
) const
6074 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND
,
6075 "Encoding an unbound empty %s value.", is_set() ? "set" : "record");
6079 return p_tok
.put_next_token(JSON_TOKEN_OBJECT_START
, NULL
) +
6080 p_tok
.put_next_token(JSON_TOKEN_OBJECT_END
, NULL
);
6083 int Empty_Record_Type::JSON_decode(const TTCN_Typedescriptor_t
&, JSON_Tokenizer
& p_tok
, boolean p_silent
)
6085 json_token_t token
= JSON_TOKEN_NONE
;
6086 int dec_len
= p_tok
.get_next_token(&token
, NULL
, NULL
);
6087 if (JSON_TOKEN_ERROR
== token
) {
6088 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG
, JSON_DEC_BAD_TOKEN_ERROR
, "");
6089 return JSON_ERROR_FATAL
;
6091 else if (JSON_TOKEN_OBJECT_START
!= token
) {
6092 return JSON_ERROR_INVALID_TOKEN
;
6095 dec_len
+= p_tok
.get_next_token(&token
, NULL
, NULL
);
6096 if (JSON_TOKEN_OBJECT_END
!= token
) {
6097 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG
, JSON_DEC_STATIC_OBJECT_END_TOKEN_ERROR
, "");
6098 return JSON_ERROR_FATAL
;
6106 boolean
operator==(null_type
/*null_value*/, const Empty_Record_Type
& other_value
)
6108 if (!other_value
.is_bound())
6109 TTCN_error("Comparison of an unbound value of type %s.",
6110 other_value
.get_descriptor()->name
);
6114 boolean
operator!=(null_type
/*null_value*/, const Empty_Record_Type
& other_value
)
6116 if (!other_value
.is_bound())
6117 TTCN_error("Comparison of an unbound value of type %s.",
6118 other_value
.get_descriptor()->name
);