Use LTTngUSTLogger logger plugin in logtest regression test
[deliverable/titan.core.git] / core2 / Basetype2.cc
CommitLineData
d44e3c4f 1/******************************************************************************
2 * Copyright (c) 2000-2016 Ericsson Telecom AB
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
7 *
8 * Contributors:
9 * Baji, Laszlo
10 * Balasko, Jeno
11 * Baranyi, Botond
12 * Beres, Szabolcs
13 * Delic, Adam
14 * Kovacs, Ferenc
15 * Raduly, Csaba
16 * Szabados, Kristof
17 * Szabo, Bence Janos
18 * Pandi, Krisztian
19 *
20 ******************************************************************************/
970ed795
EL
21#include "Basetype.hh"
22#include "TEXT.hh"
23#include "BER.hh"
24#include "XER.hh"
25#include "RAW.hh"
26#include "memory.h"
27#include "Module_list.hh"
28#include "Vector.hh"
29#include "JSON.hh"
30
31#ifdef TITAN_RUNTIME_2
32
33#include "Integer.hh"
34#include "Charstring.hh"
35#include "Universal_charstring.hh"
36#include "Addfunc.hh"
3f84031e 37#include "PreGenRecordOf.hh"
970ed795
EL
38
39////////////////////////////////////////////////////////////////////////////////
40
41const Erroneous_values_t* Erroneous_descriptor_t::get_field_err_values(int field_idx) const
42{
43 for (int i=0; i<values_size; i++) {
44 if (values_vec[i].field_index==field_idx) return (values_vec+i);
45 if (values_vec[i].field_index>field_idx) return NULL;
46 }
47 return NULL;
48}
49
50const Erroneous_values_t* Erroneous_descriptor_t::next_field_err_values(
51 const int field_idx, int& values_idx) const
52{
53 const Erroneous_values_t* err_vals = NULL;
54 if ( (values_idx<values_size) && (values_vec[values_idx].field_index==field_idx) ) {
55 err_vals = values_vec+values_idx;
56 values_idx++;
57 }
58 return err_vals;
59}
60
61const Erroneous_descriptor_t* Erroneous_descriptor_t::get_field_emb_descr(int field_idx) const
62{
63 for (int i=0; i<embedded_size; i++) {
64 if (embedded_vec[i].field_index==field_idx) return (embedded_vec+i);
65 if (embedded_vec[i].field_index>field_idx) return NULL;
66 }
67 return NULL;
68}
69
70const Erroneous_descriptor_t* Erroneous_descriptor_t::next_field_emb_descr(
71 const int field_idx, int& edescr_idx) const
72{
73 const Erroneous_descriptor_t* emb_descr = NULL;
74 if ( (edescr_idx<embedded_size) && (embedded_vec[edescr_idx].field_index==field_idx) ) {
75 emb_descr = embedded_vec+edescr_idx;
76 edescr_idx++;
77 }
78 return emb_descr;
79}
80
81void Erroneous_descriptor_t::log() const
82{
83 TTCN_Logger::log_event_str(" with erroneous { ");
84 log_();
85 TTCN_Logger::log_event_str("}");
86}
87
88void Erroneous_descriptor_t::log_() const
89{
90 if (omit_before!=-1) {
91 if (omit_before_qualifier==NULL) TTCN_error(
92 "internal error: Erroneous_descriptor_t::log()");
93 TTCN_Logger::log_event("{ before %s := omit all } ", omit_before_qualifier);
94 }
95 if (omit_after!=-1) {
96 if (omit_after_qualifier==NULL) TTCN_error(
97 "internal error: Erroneous_descriptor_t::log()");
98 TTCN_Logger::log_event("{ after %s := omit all } ", omit_after_qualifier);
99 }
100 for (int i=0; i<values_size; i++) {
101 if (values_vec[i].field_qualifier==NULL) TTCN_error(
102 "internal error: Erroneous_descriptor_t::log()");
103 if (values_vec[i].before) {
104 TTCN_Logger::log_event("{ before%s %s := ",
105 values_vec[i].before->raw ? "(raw)" : "", values_vec[i].field_qualifier);
106 if (values_vec[i].before->errval) values_vec[i].before->errval->log();
107 else TTCN_Logger::log_event_str("omit");
108 TTCN_Logger::log_event_str(" } ");
109 }
110 if (values_vec[i].value) {
111 TTCN_Logger::log_event("{ value%s %s := ",
112 values_vec[i].value->raw ? "(raw)" : "", values_vec[i].field_qualifier);
113 if (values_vec[i].value->errval) values_vec[i].value->errval->log();
114 else TTCN_Logger::log_event_str("omit");
115 TTCN_Logger::log_event_str(" } ");
116 }
117 if (values_vec[i].after) {
118 TTCN_Logger::log_event("{ after%s %s := ",
119 values_vec[i].after->raw ? "(raw)" : "", values_vec[i].field_qualifier);
120 if (values_vec[i].after->errval) values_vec[i].after->errval->log();
121 else TTCN_Logger::log_event_str("omit");
122 TTCN_Logger::log_event_str(" } ");
123 }
124 }
125 for (int i=0; i<embedded_size; i++) {
126 embedded_vec[i].log_();
127 }
128}
129
130void Base_Type::set_to_omit()
131{
132 TTCN_error("Internal error: trying to set a non-optional field to OMIT.");
133}
134
135void Base_Type::set_to_present()
136{
137 TTCN_error("Internal error: calling set_to_present() on a non-optional value.");
138}
139
140boolean Base_Type::is_present() const
141{
142 return is_bound();
143}
144
145Base_Type* Base_Type::get_opt_value()
146{
147 TTCN_error("Internal error: calling get_opt_value() on a non-optional value.");
148 return NULL;
149}
150
151const Base_Type* Base_Type::get_opt_value() const
152{
153 TTCN_error("Internal error: calling get_opt_value() const on a non-optional value.");
154 return NULL;
155}
156
157ASN_BER_TLV_t* Base_Type::BER_encode_TLV_negtest(const Erroneous_descriptor_t* /*p_err_descr*/,
158 const TTCN_Typedescriptor_t& /*p_td*/, unsigned /*p_coding*/) const
159{
160 TTCN_error("Internal error: calling Base_Type::BER_encode_TLV_negtest().");
161 return NULL;
162}
163
164int Base_Type::TEXT_encode_negtest(const Erroneous_descriptor_t* /*p_err_descr*/,
165 const TTCN_Typedescriptor_t& /*p_td*/, TTCN_Buffer& /*p_buf*/) const
166{
167 TTCN_error("Internal error: calling Base_Type::TEXT_encode_negtest().");
168 return 0;
169}
170
171ASN_BER_TLV_t* Base_Type::BER_encode_negtest_raw() const
172{
173 TTCN_error("A value of type %s cannot be used as erroneous raw value for BER encoding.",
174 get_descriptor()->name);
175 return NULL;
176}
177
178int Base_Type::encode_raw(TTCN_Buffer&) const
179{
180 TTCN_error("A value of type %s cannot be used as erroneous raw value for encoding.",
181 get_descriptor()->name);
182 return 0;
183}
184
185int Base_Type::RAW_encode_negtest_raw(RAW_enc_tree&) const
186{
187 TTCN_error("A value of type %s cannot be used as erroneous raw value for encoding.",
188 get_descriptor()->name);
189 return 0;
190}
191
3f84031e 192int Base_Type::JSON_encode_negtest_raw(JSON_Tokenizer&) const
193{
194 TTCN_error("A value of type %s cannot be used as erroneous raw value for JSON encoding.",
195 get_descriptor()->name);
196 return 0;
197}
198
970ed795 199int Base_Type::XER_encode_negtest(const Erroneous_descriptor_t* /*p_err_descr*/,
af710487 200 const XERdescriptor_t& p_td, TTCN_Buffer& p_buf, unsigned int flavor, int indent, embed_values_enc_struct_t*) const
970ed795 201{
af710487 202 return XER_encode(p_td, p_buf, flavor, indent, 0); // ignore erroneous
970ed795
EL
203}
204
205int Base_Type::RAW_encode_negtest(const Erroneous_descriptor_t *,
206 const TTCN_Typedescriptor_t&, RAW_enc_tree&) const
207{
208 TTCN_error("Internal error: calling Base_Type::RAW_encode_negtest().");
209 return 0;
210}
211
3f84031e 212int Base_Type::JSON_encode_negtest(const Erroneous_descriptor_t* /*p_err_descr*/,
213 const TTCN_Typedescriptor_t& /*p_td*/, JSON_Tokenizer& /*p_tok*/) const
214{
215 TTCN_error("Internal error: calling Base_Type::JSON_encode_negtest().");
216 return 0;
217}
218
970ed795
EL
219#else
220#error this is for RT2 only
221#endif
222
223#ifdef TITAN_RUNTIME_2
224
225boolean Record_Of_Type::compare_function(const Record_Of_Type *left_ptr,
226 int left_index, const Record_Of_Type *right_ptr, int right_index)
227{
228 if (left_ptr->val_ptr == NULL)
229 TTCN_error("The left operand of comparison is an unbound value of type %s.",
230 left_ptr->get_descriptor()->name);
231 if (right_ptr->val_ptr == NULL)
232 TTCN_error("The right operand of comparison is an unbound value of type %s.",
233 right_ptr->get_descriptor()->name);
234
235 const Base_Type* elem = left_ptr->val_ptr->value_elements[left_index];
236 const Base_Type* other_elem = right_ptr->val_ptr->value_elements[right_index];
237 if (elem != NULL) {
238 if (other_elem != NULL) { // both are bound, compare them
239 return elem->is_equal(other_elem);
240 }
241 else return FALSE;
242 }
243 else { // elem unbound, they can be equal only if other_elem is unbound too
244 return other_elem == NULL;
245 }
246}
247
248void Record_Of_Type::clean_up()
249{
250 if (val_ptr != NULL) {
251 if (val_ptr->ref_count > 1) {
252 val_ptr->ref_count--;
253 val_ptr = NULL;
254 }
255 else if (val_ptr->ref_count == 1) {
af710487 256 if (NULL == refd_ind_ptr) {
970ed795
EL
257 for (int elem_count = 0; elem_count < val_ptr->n_elements; elem_count++) {
258 if (val_ptr->value_elements[elem_count] != NULL) {
259 delete val_ptr->value_elements[elem_count];
260 }
261 }
262 free_pointers((void**)val_ptr->value_elements);
263 delete val_ptr;
264 val_ptr = NULL;
265 }
266 else {
267 set_size(0);
268 }
269 }
270 else {
271 TTCN_error("Internal error: Invalid reference counter in "
272 "a record of/set of value.");
273 }
274 }
275}
276
277Record_Of_Type::Record_Of_Type(null_type /*other_value*/)
af710487 278: Base_Type(), val_ptr(new recordof_setof_struct), err_descr(NULL), refd_ind_ptr(NULL)
970ed795
EL
279{
280 val_ptr->ref_count = 1;
281 val_ptr->n_elements = 0;
282 val_ptr->value_elements = NULL;
283}
284
285Record_Of_Type::Record_Of_Type(const Record_Of_Type& other_value)
3abe9331 286: Base_Type(other_value), RefdIndexInterface(other_value)
287, val_ptr(NULL), err_descr(other_value.err_descr), refd_ind_ptr(NULL)
970ed795
EL
288{
289 if (!other_value.is_bound())
290 TTCN_error("Copying an unbound record of/set of value.");
291 // Increment ref_count only if val_ptr is not NULL
292 if (other_value.val_ptr != NULL) {
af710487 293 if (NULL == other_value.refd_ind_ptr) {
970ed795
EL
294 val_ptr = other_value.val_ptr;
295 val_ptr->ref_count++;
296 }
297 else {
298 // there are references to at least one element => the array must be copied
299 int nof_elements = other_value.get_nof_elements();
300 set_size(nof_elements);
301 for (int i = 0; i < nof_elements; ++i) {
302 if (other_value.is_elem_bound(i)) {
303 val_ptr->value_elements[i] = other_value.val_ptr->value_elements[i]->clone();
304 }
305 }
306 }
307 }
308}
309
310int Record_Of_Type::get_nof_elements() const
311{
312 int nof_elements = (val_ptr != NULL) ? val_ptr->n_elements : 0;
af710487 313 if (NULL != refd_ind_ptr) {
970ed795
EL
314 while (nof_elements > 0) {
315 if (is_elem_bound(nof_elements - 1)) {
316 break;
317 }
318 --nof_elements;
319 }
320 }
321 return nof_elements;
322}
323
324bool Record_Of_Type::is_elem_bound(int index) const
325{
326 return val_ptr->value_elements[index] != NULL &&
327 val_ptr->value_elements[index]->is_bound();
328}
329
330int Record_Of_Type::get_max_refd_index()
331{
af710487 332 if (NULL == refd_ind_ptr) {
970ed795
EL
333 return -1;
334 }
af710487 335 if (-1 == refd_ind_ptr->max_refd_index) {
336 for (size_t i = 0; i < refd_ind_ptr->refd_indices.size(); ++i) {
337 if (refd_ind_ptr->refd_indices[i] > refd_ind_ptr->max_refd_index) {
338 refd_ind_ptr->max_refd_index = refd_ind_ptr->refd_indices[i];
970ed795
EL
339 }
340 }
341 }
af710487 342 return refd_ind_ptr->max_refd_index;
970ed795
EL
343}
344
345bool Record_Of_Type::is_index_refd(int index)
346{
af710487 347 if (NULL == refd_ind_ptr) {
348 return false;
349 }
350 for (size_t i = 0; i < refd_ind_ptr->refd_indices.size(); ++i) {
351 if (index == refd_ind_ptr->refd_indices[i]) {
970ed795
EL
352 return true;
353 }
354 }
355 return false;
356}
357
358void Record_Of_Type::set_val(null_type)
359{
360 set_size(0);
361}
362
363boolean Record_Of_Type::is_equal(const Base_Type* other_value) const
364{
365 const Record_Of_Type* other_recof = static_cast<const Record_Of_Type*>(other_value);
366 if (val_ptr == NULL)
367 TTCN_error("The left operand of comparison is an unbound value of type %s.",
368 get_descriptor()->name);
369 if (other_recof->val_ptr == NULL)
370 TTCN_error("The right operand of comparison is an unbound value of type %s.",
371 other_value->get_descriptor()->name);
372 if (val_ptr == other_recof->val_ptr) return TRUE;
373 if (is_set()) {
374 return compare_set_of(this, get_nof_elements(), other_recof,
375 other_recof->get_nof_elements(), compare_function);
376 } else {
377 if (get_nof_elements() != other_recof->get_nof_elements()) return FALSE;
378 for (int elem_count = 0; elem_count < get_nof_elements(); elem_count++) {
379 if (is_elem_bound(elem_count)) {
380 if (other_recof->is_elem_bound(elem_count)) {
381 if (!val_ptr->value_elements[elem_count]->is_equal(other_recof->val_ptr->value_elements[elem_count]))
382 return FALSE;
383 } else return FALSE;
384 } else if (other_recof->is_elem_bound(elem_count)) return FALSE;
385 }
386 return TRUE;
387 }
388}
389
390void Record_Of_Type::set_value(const Base_Type* other_value)
391{
392 const Record_Of_Type* other_recof = static_cast<const Record_Of_Type*>(other_value);
393 if (!other_recof->is_bound())
394 TTCN_error("Assigning an unbound value of type %s.",
395 other_value->get_descriptor()->name);
396 if (this != other_recof) {
af710487 397 if (NULL == refd_ind_ptr && NULL == other_recof->refd_ind_ptr) {
970ed795
EL
398 clean_up();
399 val_ptr = other_recof->val_ptr;
400 val_ptr->ref_count++;
401 }
402 else {
403 // there are references to at least one element => the array must be copied
404 int nof_elements = other_recof->get_nof_elements();
405 set_size(nof_elements);
406 for (int i = 0; i < nof_elements; ++i) {
407 if (other_recof->is_elem_bound(i)) {
408 if (val_ptr->value_elements[i] == NULL) {
409 val_ptr->value_elements[i] = create_elem();
410 }
411 val_ptr->value_elements[i]->set_value(other_recof->val_ptr->value_elements[i]);
412 }
413 else if (val_ptr->value_elements[i] != NULL) {
414 if (is_index_refd(i)) {
415 val_ptr->value_elements[i]->clean_up();
416 }
417 else {
418 delete val_ptr->value_elements[i];
419 val_ptr->value_elements[i] = NULL;
420 }
421 }
422 }
423 }
424 }
425 err_descr = other_recof->err_descr;
426}
427
428boolean Record_Of_Type::operator!=(null_type other_value) const
429{
430 return !(*this == other_value);
431}
432
433Base_Type* Record_Of_Type::get_at(int index_value)
434{
435 if (index_value < 0)
436 TTCN_error("Accessing an element of type %s using a negative index: %d.",
437 get_descriptor()->name, index_value);
438 if (val_ptr == NULL) {
439 val_ptr = new recordof_setof_struct;
440 val_ptr->ref_count = 1;
441 val_ptr->n_elements = 0;
442 val_ptr->value_elements = NULL;
443 } else if (val_ptr->ref_count > 1) {
444 struct recordof_setof_struct *new_val_ptr = new recordof_setof_struct;
445 new_val_ptr->ref_count = 1;
446 new_val_ptr->n_elements = (index_value >= val_ptr->n_elements) ?
447 index_value + 1 : val_ptr->n_elements;
448 new_val_ptr->value_elements =
449 (Base_Type**)allocate_pointers(new_val_ptr->n_elements);
450 for (int elem_count = 0; elem_count < val_ptr->n_elements; elem_count++)
451 {
452 if (val_ptr->value_elements[elem_count] != NULL) {
453 new_val_ptr->value_elements[elem_count] =
454 val_ptr->value_elements[elem_count]->clone();
455 }
456 }
457 val_ptr->ref_count--;
458 val_ptr = new_val_ptr;
459 }
460 if (index_value >= val_ptr->n_elements) set_size(index_value + 1);
461 if (val_ptr->value_elements[index_value] == NULL) {
462 val_ptr->value_elements[index_value] = create_elem();
463 }
464 return val_ptr->value_elements[index_value];
465}
466
467Base_Type* Record_Of_Type::get_at(const INTEGER& index_value)
468{
469 if (!index_value.is_bound())
470 TTCN_error("Using an unbound integer value for indexing a value "
471 "of type %s.", get_descriptor()->name);
472 return get_at((int)index_value);
473}
474
475const Base_Type* Record_Of_Type::get_at(int index_value) const
476{
477 if (val_ptr == NULL)
478 TTCN_error("Accessing an element in an unbound value of type %s.",
479 get_descriptor()->name);
480 if (index_value < 0)
481 TTCN_error("Accessing an element of type %s using a negative index: %d.",
482 get_descriptor()->name, index_value);
483 if (index_value >= get_nof_elements())
484 TTCN_error("Index overflow in a value of type %s: The index is %d, but the "
485 "value has only %d elements.", get_descriptor()->name, index_value,
486 get_nof_elements());
487 return (val_ptr->value_elements[index_value] != NULL) ?
488 val_ptr->value_elements[index_value] : get_unbound_elem();
489}
490
491const Base_Type* Record_Of_Type::get_at(const INTEGER& index_value) const
492{
493 if (!index_value.is_bound())
494 TTCN_error("Using an unbound integer value for indexing a value "
495 "of type %s.", get_descriptor()->name);
496 return get_at((int)index_value);
497}
498
499Record_Of_Type* Record_Of_Type::rotl(const INTEGER& rotate_count, Record_Of_Type* rec_of) const
500{
501 if (!rotate_count.is_bound())
502 TTCN_error("Unbound integer operand of rotate left operator of type %s.",
503 get_descriptor()->name);
504 return rotr((int)(-rotate_count), rec_of);
505}
506
507Record_Of_Type* Record_Of_Type::rotr(const INTEGER& rotate_count, Record_Of_Type* rec_of) const
508{
509 if (!rotate_count.is_bound())
510 TTCN_error("Unbound integer operand of rotate right operator of type %s.",
511 get_descriptor()->name);
512 return rotr((int)rotate_count, rec_of);
513}
514
515Record_Of_Type* Record_Of_Type::rotr(int rotate_count, Record_Of_Type* rec_of) const
516{
517 if (val_ptr == NULL)
518 TTCN_error("Performing rotation operation on an unbound value of type %s.",
519 get_descriptor()->name);
520 int nof_elements = get_nof_elements();
521 if (nof_elements == 0) return const_cast<Record_Of_Type*>(this);
522 int rc;
523 if (rotate_count>=0) rc = rotate_count % nof_elements;
524 else rc = nof_elements - ((-rotate_count) % nof_elements);
525 if (rc == 0) return const_cast<Record_Of_Type*>(this);
526 rec_of->set_size(nof_elements);
527 int rot_i;
528 for (int i=0; i<nof_elements; i++) {
529 rot_i = (i+rc) % nof_elements;
530 if (is_elem_bound(i)) {
531 if (rec_of->val_ptr->value_elements[rot_i] == NULL) {
532 rec_of->val_ptr->value_elements[rot_i] = rec_of->create_elem();
533 }
534 rec_of->val_ptr->value_elements[rot_i]->set_value(val_ptr->value_elements[i]);
535 } else if (rec_of->is_elem_bound(rot_i)) {
536 delete rec_of->val_ptr->value_elements[rot_i];
537 rec_of->val_ptr->value_elements[rot_i] = NULL;
538 }
539 }
540 return rec_of;
541}
542
543Record_Of_Type* Record_Of_Type::concat(const Record_Of_Type* other_value,
544 Record_Of_Type* rec_of) const
545{
546 if (val_ptr == NULL || other_value->val_ptr == NULL)
547 TTCN_error("Unbound operand of %s concatenation.", get_descriptor()->name);
548 int nof_elements = get_nof_elements();
549 if (nof_elements == 0) return const_cast<Record_Of_Type*>(other_value);
550 int other_value_nof_elements = other_value->get_nof_elements();
551 if (other_value_nof_elements == 0) return const_cast<Record_Of_Type*>(this);
552 rec_of->set_size(nof_elements + other_value_nof_elements);
553 for (int i=0; i<nof_elements; i++) {
554 if (is_elem_bound(i)) {
555 if (rec_of->val_ptr->value_elements[i] == NULL) {
556 rec_of->val_ptr->value_elements[i] = rec_of->create_elem();
557 }
558 rec_of->val_ptr->value_elements[i]->set_value(val_ptr->value_elements[i]);
559 } else if (rec_of->val_ptr->value_elements[i] != NULL) {
560 if (rec_of->is_index_refd(i)) {
561 rec_of->val_ptr->value_elements[i]->clean_up();
562 }
563 else {
564 delete rec_of->val_ptr->value_elements[i];
565 rec_of->val_ptr->value_elements[i] = NULL;
566 }
567 }
568 }
569 int cat_i;
570 for (int i=0; i<other_value_nof_elements; i++) {
571 cat_i = i + nof_elements;
572 if (other_value->is_elem_bound(i)) {
573 if (rec_of->val_ptr->value_elements[cat_i] == NULL) {
574 rec_of->val_ptr->value_elements[cat_i] = rec_of->create_elem();
575 }
576 rec_of->val_ptr->value_elements[cat_i]->
577 set_value(other_value->val_ptr->value_elements[i]);
578 } else if (rec_of->val_ptr->value_elements[cat_i] != NULL) {
579 if (rec_of->is_index_refd(cat_i)) {
580 rec_of->val_ptr->value_elements[cat_i]->clean_up();
581 }
582 else {
583 delete rec_of->val_ptr->value_elements[cat_i];
584 rec_of->val_ptr->value_elements[cat_i] = NULL;
585 }
586 }
587 }
588 return rec_of;
589}
590
591void Record_Of_Type::substr_(int index, int returncount,
592 Record_Of_Type* rec_of) const
593{
594 if (val_ptr == NULL)
595 TTCN_error("The first argument of substr() is an unbound value of type %s.",
596 get_descriptor()->name);
597 check_substr_arguments(get_nof_elements(), index, returncount,
598 get_descriptor()->name, "element");
599 rec_of->set_size(returncount);
600 for (int i=0; i<returncount; i++) {
601 if (is_elem_bound(i + index)) {
602 if (rec_of->val_ptr->value_elements[i] == NULL) {
603 rec_of->val_ptr->value_elements[i] = rec_of->create_elem();
604 }
605 rec_of->val_ptr->value_elements[i]->
606 set_value(val_ptr->value_elements[i+index]);
607 } else if (rec_of->val_ptr->value_elements[i] != NULL) {
608 if (rec_of->is_index_refd(i)) {
609 rec_of->val_ptr->value_elements[i]->clean_up();
610 }
611 else {
612 delete rec_of->val_ptr->value_elements[i];
613 rec_of->val_ptr->value_elements[i] = NULL;
614 }
615 }
616 }
617}
618
619void Record_Of_Type::replace_(int index, int len,
620 const Record_Of_Type* repl, Record_Of_Type* rec_of) const
621{
622 if (val_ptr == NULL)
623 TTCN_error("The first argument of replace() is an unbound value "
624 "of type %s.", get_descriptor()->name);
625 if (repl->val_ptr == NULL)
626 TTCN_error("The fourth argument of replace() is an unbound value of "
627 "type %s.", get_descriptor()->name);
628 int nof_elements = get_nof_elements();
629 check_replace_arguments(nof_elements, index, len,
630 get_descriptor()->name, "element");
631 int repl_nof_elements = repl->get_nof_elements();
632 rec_of->set_size(nof_elements + repl_nof_elements - len);
633 for (int i = 0; i < index; i++) {
634 if (is_elem_bound(i)) {
635 if (rec_of->val_ptr->value_elements[i] == NULL) {
636 rec_of->val_ptr->value_elements[i] = rec_of->create_elem();
637 }
638 rec_of->val_ptr->value_elements[i]->set_value(val_ptr->value_elements[i]);
639 } else if (rec_of->val_ptr->value_elements[i] != NULL) {
640 if (rec_of->is_index_refd(i)) {
641 rec_of->val_ptr->value_elements[i]->clean_up();
642 }
643 else {
644 delete rec_of->val_ptr->value_elements[i];
645 rec_of->val_ptr->value_elements[i] = NULL;
646 }
647 }
648 }
649 for (int i = 0; i < repl_nof_elements; i++) {
650 if (repl->is_elem_bound(i)) {
651 if (rec_of->val_ptr->value_elements[i+index] == NULL) {
652 rec_of->val_ptr->value_elements[i+index] = rec_of->create_elem();
653 }
654 rec_of->val_ptr->value_elements[i+index]->
655 set_value(repl->val_ptr->value_elements[i]);
656 } else if (rec_of->val_ptr->value_elements[i+index] != NULL) {
657 if (rec_of->is_index_refd(i+index)) {
658 rec_of->val_ptr->value_elements[i+index]->clean_up();
659 }
660 else {
661 delete rec_of->val_ptr->value_elements[i+index];
662 rec_of->val_ptr->value_elements[i+index] = NULL;
663 }
664 }
665 }
666 int repl_i;
667 for (int i = 0; i < nof_elements - index - len; i++) {
668 repl_i = index+i+repl_nof_elements;
669 if (is_elem_bound(index+i+len)) {
670 if (rec_of->val_ptr->value_elements[repl_i] == NULL) {
671 rec_of->val_ptr->value_elements[repl_i] = rec_of->create_elem();
672 }
673 rec_of->val_ptr->value_elements[repl_i]->
674 set_value(val_ptr->value_elements[index+i+len]);
675 } else if (rec_of->val_ptr->value_elements[repl_i] != NULL) {
676 if (rec_of->is_index_refd(repl_i)) {
677 rec_of->val_ptr->value_elements[repl_i]->clean_up();
678 }
679 else {
680 delete rec_of->val_ptr->value_elements[repl_i];
681 rec_of->val_ptr->value_elements[repl_i] = NULL;
682 }
683 }
684 }
685}
686
687void Record_Of_Type::replace_(int index, int len,
688 const Record_Of_Template* repl, Record_Of_Type* rec_of) const
689{
690 if (!repl->is_value())
691 TTCN_error("The fourth argument of function replace() is a template "
692 "of type %s with non-specific value.", get_descriptor()->name);
693 rec_of->set_val(NULL_VALUE);
694 Base_Type* repl_value = rec_of->clone();
695 repl->valueofv(repl_value);
696 replace_(index, len, static_cast<Record_Of_Type*>(repl_value), rec_of);
697 delete repl_value;
698}
699
700void Record_Of_Type::replace_(int index, int len,
701 const Set_Of_Template* repl, Record_Of_Type* rec_of) const
702{
703 if (!repl->is_value())
704 TTCN_error("The fourth argument of function replace() is a template "
705 "of type %s with non-specific value.", get_descriptor()->name);
706 rec_of->set_val(NULL_VALUE);
707 Base_Type* repl_value = rec_of->clone();
708 repl->valueofv(repl_value);
709 replace_(index, len, static_cast<Record_Of_Type*>(repl_value), rec_of);
710 delete repl_value;
711}
712
713void Record_Of_Type::set_size(int new_size)
714{
715 if (new_size < 0)
716 TTCN_error("Internal error: Setting a negative size for a value of "
717 "type %s.", get_descriptor()->name);
718 if (val_ptr == NULL) {
719 val_ptr = new recordof_setof_struct;
720 val_ptr->ref_count = 1;
721 val_ptr->n_elements = 0;
722 val_ptr->value_elements = NULL;
723 } else if (val_ptr->ref_count > 1) {
724 struct recordof_setof_struct *new_val_ptr = new recordof_setof_struct;
725 new_val_ptr->ref_count = 1;
726 new_val_ptr->n_elements = (new_size < val_ptr->n_elements) ?
727 new_size : val_ptr->n_elements;
728 new_val_ptr->value_elements =
729 (Base_Type**)allocate_pointers(new_val_ptr->n_elements);
730 for (int elem_count = 0; elem_count < new_val_ptr->n_elements; elem_count++) {
731 if (val_ptr->value_elements[elem_count] != NULL) {
732 new_val_ptr->value_elements[elem_count] =
733 val_ptr->value_elements[elem_count]->clone();
734 }
735 }
736 clean_up();
737 val_ptr = new_val_ptr;
738 }
739 if (new_size > val_ptr->n_elements) {
740 val_ptr->value_elements = (Base_Type**)
741 reallocate_pointers((void**)val_ptr->value_elements, val_ptr->n_elements, new_size);
742 val_ptr->n_elements = new_size;
743 } else if (new_size < val_ptr->n_elements) {
744 for (int elem_count = new_size; elem_count < val_ptr->n_elements; elem_count++) {
745 if (val_ptr->value_elements[elem_count] != NULL) {
746 if (is_index_refd(elem_count)) {
747 val_ptr->value_elements[elem_count]->clean_up();
748 }
749 else {
750 delete val_ptr->value_elements[elem_count];
751 val_ptr->value_elements[elem_count] = 0;
752 }
753 }
754 }
755 if (new_size <= get_max_refd_index()) {
756 new_size = get_max_refd_index() + 1;
757 }
758 if (new_size < val_ptr->n_elements) {
759 val_ptr->value_elements = (Base_Type**)
760 reallocate_pointers((void**)val_ptr->value_elements, val_ptr->n_elements, new_size);
761 val_ptr->n_elements = new_size;
762 }
763 }
764}
765
766boolean Record_Of_Type::is_bound() const
767{
af710487 768 if (NULL == refd_ind_ptr) {
970ed795
EL
769 return (val_ptr != NULL);
770 }
771 return (get_nof_elements() != 0);
772}
773
774boolean Record_Of_Type::is_value() const
775{
776 if (val_ptr == NULL) return FALSE;
777 for (int i=0; i < get_nof_elements(); ++i)
778 if (!is_elem_bound(i) ||
779 !val_ptr->value_elements[i]->is_value()) return FALSE;
780 return TRUE;
781}
782
783int Record_Of_Type::size_of() const
784{
785 if (val_ptr == NULL)
786 TTCN_error("Performing sizeof operation on an unbound value of type %s.",
787 get_descriptor()->name);
788 return get_nof_elements();
789}
790
791int Record_Of_Type::lengthof() const
792{
793 if (val_ptr == NULL)
794 TTCN_error("Performing lengthof operation on an unbound value of "
795 "type %s.", get_descriptor()->name);
796 for (int my_length=get_nof_elements(); my_length>0; my_length--)
797 if (is_elem_bound(my_length - 1)) return my_length;
798 return 0;
799}
800
801void Record_Of_Type::log() const
802{
803 if (val_ptr == NULL) {
804 TTCN_Logger::log_event_unbound();
805 return;
806 }
807 if (get_nof_elements()==0) {
808 TTCN_Logger::log_event_str("{ }");
809 } else {
810 TTCN_Logger::log_event_str("{ ");
811 for (int elem_count = 0; elem_count < get_nof_elements(); elem_count++) {
812 if (elem_count > 0) TTCN_Logger::log_event_str(", ");
813 get_at(elem_count)->log();
814 }
815 TTCN_Logger::log_event_str(" }");
816 }
817 if (err_descr) err_descr->log();
818}
819
820void Record_Of_Type::encode_text(Text_Buf& text_buf) const
821{
822 if (val_ptr == NULL)
823 TTCN_error("Text encoder: Encoding an unbound value of type %s.",
824 get_descriptor()->name);
825 text_buf.push_int(get_nof_elements());
826 for (int elem_count = 0; elem_count < get_nof_elements(); elem_count++)
827 get_at(elem_count)->encode_text(text_buf);
828}
829
830void Record_Of_Type::decode_text(Text_Buf& text_buf)
831{
832 int new_size = text_buf.pull_int().get_val();
833 if (new_size < 0)
834 TTCN_error("Text decoder: Negative size was received for a value of "
835 "type %s.", get_descriptor()->name);
836 set_size(new_size);
837 for (int elem_count = 0; elem_count < new_size; elem_count++) {
838 if (val_ptr->value_elements[elem_count] == NULL) {
839 val_ptr->value_elements[elem_count] = create_elem();
840 }
841 val_ptr->value_elements[elem_count]->decode_text(text_buf);
842 }
843}
844
845boolean Record_Of_Type::operator==(null_type /*other_value*/) const
846{
847 if (val_ptr == NULL)
848 TTCN_error("The left operand of comparison is an unbound value of type %s.",
849 get_descriptor()->name);
850 return get_nof_elements() == 0;
851}
852
853int Record_Of_Type::rawdec_ebv() const
854{
855 TTCN_error("Internal error: Record_Of_Type::rawdec_ebv() called.");
856}
857
858boolean Record_Of_Type::isXerAttribute() const
859{
860 TTCN_error("Internal error: Record_Of_Type::isXerAttribute() called.");
861}
862
863boolean Record_Of_Type::isXmlValueList() const
864{
865 TTCN_error("Internal error: Record_Of_Type::isXmlValueList() called.");
866}
867
868int Record_Of_Type::TEXT_encode(const TTCN_Typedescriptor_t& p_td,
869 TTCN_Buffer& buff) const
870{
871 if(err_descr){
872 return TEXT_encode_negtest(err_descr, p_td, buff);
873 }
874 int encoded_length=0;
875 if(p_td.text->begin_encode) {
876 buff.put_cs(*p_td.text->begin_encode);
877 encoded_length+=p_td.text->begin_encode->lengthof();
878 }
879 if(val_ptr==NULL) {
880 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND,
881 "Encoding an unbound value.");
882 if(p_td.text->end_encode) {
883 buff.put_cs(*p_td.text->end_encode);
884 encoded_length+=p_td.text->end_encode->lengthof();
885 }
886 return encoded_length;
887 }
a38c6d4c 888 const TTCN_Typedescriptor_t* elem_descr = p_td.oftype_descr;
970ed795
EL
889 for(int a=0;a<get_nof_elements();a++) {
890 if(a!=0 && p_td.text->separator_encode) {
891 buff.put_cs(*p_td.text->separator_encode);
892 encoded_length+=p_td.text->separator_encode->lengthof();
893 }
894 encoded_length+=get_at(a)->TEXT_encode(*elem_descr,buff);
895 }
896 if(p_td.text->end_encode) {
897 buff.put_cs(*p_td.text->end_encode);
898 encoded_length+=p_td.text->end_encode->lengthof();
899 }
900 return encoded_length;
901}
902
903/**
904 * TEXT encode for negative testing
905 */
906int Record_Of_Type::TEXT_encode_negtest(const Erroneous_descriptor_t* p_err_descr, const TTCN_Typedescriptor_t& p_td,
907 TTCN_Buffer& buff) const
908{
909 bool need_separator=false;
910 int encoded_length=0;
911 if(p_td.text->begin_encode) {
912 buff.put_cs(*p_td.text->begin_encode);
913 encoded_length+=p_td.text->begin_encode->lengthof();
914 }
915 if(val_ptr==NULL) {
916 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND,
917 "Encoding an unbound value.");
918 if(p_td.text->end_encode) {
919 buff.put_cs(*p_td.text->end_encode);
920 encoded_length+=p_td.text->end_encode->lengthof();
921 }
922 return encoded_length;
923 }
924
925 int values_idx = 0;
926 int edescr_idx = 0;
927
928 for(int a=0;a<get_nof_elements();a++) {
929 if ( (p_err_descr->omit_before!=-1) && (a<p_err_descr->omit_before) ) continue;
930 const Erroneous_values_t* err_vals = p_err_descr->next_field_err_values(a, values_idx);
931 const Erroneous_descriptor_t* emb_descr = p_err_descr->next_field_emb_descr(a, edescr_idx);
932
933 if (err_vals && err_vals->before) {
934 if (err_vals->before->errval==NULL) TTCN_error(
935 "internal error: erroneous before value missing");
936 if (need_separator && p_td.text->separator_encode) {
937 buff.put_cs(*p_td.text->separator_encode);
938 encoded_length+=p_td.text->separator_encode->lengthof();
939 }
940 if (err_vals->before->raw) {
941 encoded_length += err_vals->before->errval->encode_raw(buff);
942 } else {
943 if (err_vals->before->type_descr==NULL) TTCN_error(
944 "internal error: erroneous before typedescriptor missing");
945 encoded_length += err_vals->before->errval->TEXT_encode(
946 *(err_vals->before->type_descr),buff);
947 }
948 need_separator=true;
949 }
950
951 if (err_vals && err_vals->value) {
952 if (err_vals->value->errval) {
953 if (need_separator && p_td.text->separator_encode) {
954 buff.put_cs(*p_td.text->separator_encode);
955 encoded_length+=p_td.text->separator_encode->lengthof();
956 }
957 if (err_vals->value->raw) {
958 encoded_length += err_vals->value->errval->encode_raw(buff);
959 } else {
960 if (err_vals->value->type_descr==NULL) TTCN_error(
961 "internal error: erroneous value typedescriptor missing");
962 encoded_length += err_vals->value->errval->TEXT_encode(
963 *(err_vals->value->type_descr),buff);
964 }
965 need_separator=true;
966 } // else -> omit
967 } else {
968 if (need_separator && p_td.text->separator_encode) {
969 buff.put_cs(*p_td.text->separator_encode);
970 encoded_length+=p_td.text->separator_encode->lengthof();
971 }
972 if (emb_descr) {
973 encoded_length += get_at(a)->TEXT_encode_negtest(
a38c6d4c 974 emb_descr,*p_td.oftype_descr,buff);
970ed795 975 } else {
a38c6d4c 976 encoded_length += get_at(a)->TEXT_encode(*p_td.oftype_descr,buff);
970ed795
EL
977 }
978 need_separator=true;
979 }
980
981 if (err_vals && err_vals->after) {
982 if (err_vals->after->errval==NULL) TTCN_error(
983 "internal error: erroneous after value missing");
984 if (need_separator && p_td.text->separator_encode) {
985 buff.put_cs(*p_td.text->separator_encode);
986 encoded_length+=p_td.text->separator_encode->lengthof();
987 }
988 if (err_vals->after->raw) {
989 encoded_length += err_vals->after->errval->encode_raw(buff);
990 } else {
991 if (err_vals->after->type_descr==NULL) TTCN_error(
992 "internal error: erroneous after typedescriptor missing");
993 encoded_length += err_vals->after->errval->TEXT_encode(
994 *(err_vals->after->type_descr),buff);
995 }
996 need_separator=true;
997 }
998
999 if ( (p_err_descr->omit_after!=-1) && (a>=p_err_descr->omit_after) ) break;
1000 }
1001 if(p_td.text->end_encode) {
1002 buff.put_cs(*p_td.text->end_encode);
1003 encoded_length+=p_td.text->end_encode->lengthof();
1004 }
1005 return encoded_length;
1006}
1007
1008int Record_Of_Type::TEXT_decode(const TTCN_Typedescriptor_t& p_td,
1009 TTCN_Buffer& buff, Limit_Token_List& limit, boolean no_err,
1010 boolean first_call)
1011{
1012 int decoded_length=0;
1013 size_t pos;
1014 boolean sep_found=FALSE;
1015 int sep_length=0;
1016 int ml=0;
1017 if(p_td.text->begin_decode){
1018 int tl;
1019 if((tl=p_td.text->begin_decode->match_begin(buff))<0){
1020 if(no_err)return -1;
1021 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR,
1022 "The specified token '%s' not found for '%s': ",
1023 (const char*)*(p_td.text->begin_decode), p_td.name);
1024 return 0;
1025 }
1026 decoded_length+=tl;
1027 buff.increase_pos(tl);
1028 }
1029 if(p_td.text->end_decode){
1030 limit.add_token(p_td.text->end_decode);
1031 ml++;
1032 }
1033 if(p_td.text->separator_decode){
1034 limit.add_token(p_td.text->separator_decode);
1035 ml++;
1036 }
1037 if(first_call) {
1038 set_size(0);
1039 }
1040 int more=get_nof_elements();
1041 while(TRUE){
1042 Base_Type* val = create_elem();
1043 pos=buff.get_pos();
a38c6d4c 1044 int len = val->TEXT_decode(*p_td.oftype_descr,buff,limit,TRUE);
970ed795
EL
1045 if(len==-1 || (len==0 && !limit.has_token())){
1046 buff.set_pos(pos);
1047 delete val;
1048 if(sep_found){
1049 buff.set_pos(buff.get_pos()-sep_length);
1050 decoded_length-=sep_length;
1051 }
1052 break;
1053 }
1054 sep_found=FALSE;
af710487 1055 if (NULL == refd_ind_ptr) {
970ed795
EL
1056 val_ptr->value_elements = (Base_Type**)reallocate_pointers(
1057 (void**)val_ptr->value_elements, val_ptr->n_elements, val_ptr->n_elements + 1);
1058 val_ptr->value_elements[val_ptr->n_elements]=val;
1059 val_ptr->n_elements++;
1060 }
1061 else {
1062 get_at(get_nof_elements())->set_value(val);
1063 delete val;
1064 }
1065 decoded_length+=len;
1066 if(p_td.text->separator_decode){
1067 int tl;
1068 if((tl=p_td.text->separator_decode->match_begin(buff))<0){
1069 break;
1070 }
1071 decoded_length+=tl;
1072 buff.increase_pos(tl);
1073 sep_length=tl;
1074 sep_found=TRUE;
1075 } else if(p_td.text->end_decode){
1076 int tl;
1077 if((tl=p_td.text->end_decode->match_begin(buff))!=-1){
1078 decoded_length+=tl;
1079 buff.increase_pos(tl);
1080 limit.remove_tokens(ml);
1081 return decoded_length;
1082 }
1083 } else if(limit.has_token(ml)){
1084 int tl;
1085 if((tl=limit.match(buff,ml))==0){
1086 //sep_found=FALSE;
1087 break;
1088 }
1089 }
1090 }
1091 limit.remove_tokens(ml);
1092 if(p_td.text->end_decode){
1093 int tl;
1094 if((tl=p_td.text->end_decode->match_begin(buff))<0){
1095 if(no_err){
1096 if(!first_call){
1097 set_size(more);
1098 }
1099 return -1;
1100 }
1101 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR,
1102 "The specified token '%s' not found for '%s': ",
1103 (const char*)*(p_td.text->end_decode), p_td.name);
1104 return decoded_length;
1105 }
1106 decoded_length+=tl;
1107 buff.increase_pos(tl);
1108 }
1109 if(get_nof_elements()==0){
1110 if (!p_td.text->end_decode && !p_td.text->begin_decode) {
1111 if(no_err)return -1;
1112 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR,
1113 "No record/set of member found.");
1114 return decoded_length;
1115 }
1116 }
1117 if(!first_call && more==get_nof_elements() &&
1118 !(p_td.text->end_decode || p_td.text->begin_decode)) return -1;
1119 return decoded_length;
1120}
1121
1122ASN_BER_TLV_t* Record_Of_Type::BER_encode_TLV(const TTCN_Typedescriptor_t& p_td,
1123 unsigned p_coding) const
1124{
1125 if (err_descr) {
1126 return BER_encode_TLV_negtest(err_descr, p_td, p_coding);
1127 }
1128 BER_chk_descr(p_td);
1129 ASN_BER_TLV_t *new_tlv=BER_encode_chk_bound(is_bound());
1130 if(!new_tlv) {
1131 new_tlv=ASN_BER_TLV_t::construct(NULL);
1132 TTCN_EncDec_ErrorContext ec;
1133 for(int elem_i=0; elem_i<get_nof_elements(); elem_i++) {
1134 ec.set_msg("Component #%d: ", elem_i);
a38c6d4c 1135 new_tlv->add_TLV(get_at(elem_i)->BER_encode_TLV(*p_td.oftype_descr, p_coding));
970ed795
EL
1136 }
1137 if (is_set()) new_tlv->sort_tlvs();
1138 }
1139 new_tlv=ASN_BER_V2TLV(new_tlv, p_td, p_coding);
1140 return new_tlv;
1141}
1142
1143ASN_BER_TLV_t* Record_Of_Type::BER_encode_TLV_negtest(const Erroneous_descriptor_t* p_err_descr,
1144 const TTCN_Typedescriptor_t& p_td, unsigned p_coding) const
1145{
1146 BER_chk_descr(p_td);
1147 ASN_BER_TLV_t *new_tlv=BER_encode_chk_bound(is_bound());
1148 if(!new_tlv) {
1149 new_tlv=ASN_BER_TLV_t::construct(NULL);
1150 TTCN_EncDec_ErrorContext ec;
1151 int values_idx = 0;
1152 int edescr_idx = 0;
1153 for (int elem_i=0; elem_i<get_nof_elements(); elem_i++) {
1154 if ( (p_err_descr->omit_before!=-1) && (elem_i<p_err_descr->omit_before) ) continue;
1155 const Erroneous_values_t* err_vals = p_err_descr->next_field_err_values(elem_i, values_idx);
1156 const Erroneous_descriptor_t* emb_descr = p_err_descr->next_field_emb_descr(elem_i, edescr_idx);
1157
1158 if (err_vals && err_vals->before) {
1159 if (err_vals->before->errval==NULL) TTCN_error(
1160 "internal error: erroneous before value missing");
1161 ec.set_msg("Erroneous value before component #%d: ", elem_i);
1162 if (err_vals->before->raw) {
1163 new_tlv->add_TLV(err_vals->before->errval->BER_encode_negtest_raw());
1164 } else {
1165 if (err_vals->before->type_descr==NULL) TTCN_error(
1166 "internal error: erroneous before typedescriptor missing");
1167 new_tlv->add_TLV(err_vals->before->errval->BER_encode_TLV(
1168 *err_vals->before->type_descr, p_coding));
1169 }
1170 }
1171
1172 if (err_vals && err_vals->value) {
1173 if (err_vals->value->errval) { // replace
1174 ec.set_msg("Erroneous value for component #%d: ", elem_i);
1175 if (err_vals->value->raw) {
1176 new_tlv->add_TLV(err_vals->value->errval->BER_encode_negtest_raw());
1177 } else {
1178 if (err_vals->value->type_descr==NULL) TTCN_error(
1179 "internal error: erroneous value typedescriptor missing");
1180 new_tlv->add_TLV(err_vals->value->errval->BER_encode_TLV(
1181 *err_vals->value->type_descr, p_coding));
1182 }
1183 } // else -> omit
1184 } else {
1185 ec.set_msg("Component #%d: ", elem_i);
1186 if (emb_descr) {
1187 new_tlv->add_TLV(get_at(elem_i)->BER_encode_TLV_negtest(
a38c6d4c 1188 emb_descr, *p_td.oftype_descr, p_coding));
970ed795
EL
1189 } else {
1190 new_tlv->add_TLV(get_at(elem_i)->BER_encode_TLV(
a38c6d4c 1191 *p_td.oftype_descr, p_coding));
970ed795
EL
1192 }
1193 }
1194
1195 if (err_vals && err_vals->after) {
1196 if (err_vals->after->errval==NULL) TTCN_error(
1197 "internal error: erroneous after value missing");
1198 ec.set_msg("Erroneous value after component #%d: ", elem_i);
1199 if (err_vals->after->raw) {
1200 new_tlv->add_TLV(err_vals->after->errval->BER_encode_negtest_raw());
1201 } else {
1202 if (err_vals->after->type_descr==NULL) TTCN_error(
1203 "internal error: erroneous after typedescriptor missing");
1204 new_tlv->add_TLV(err_vals->after->errval->BER_encode_TLV(
1205 *err_vals->after->type_descr, p_coding));
1206 }
1207 }
1208
1209 if ( (p_err_descr->omit_after!=-1) && (elem_i>=p_err_descr->omit_after) ) break;
1210 }
1211 if (is_set()) new_tlv->sort_tlvs();
1212 }
1213 new_tlv=ASN_BER_V2TLV(new_tlv, p_td, p_coding);
1214 return new_tlv;
1215}
1216
1217boolean Record_Of_Type::BER_decode_TLV(const TTCN_Typedescriptor_t& p_td,
1218 const ASN_BER_TLV_t& p_tlv, unsigned L_form)
1219{
1220 BER_chk_descr(p_td);
1221 ASN_BER_TLV_t stripped_tlv;
1222 BER_decode_strip_tags(*p_td.ber, p_tlv, L_form, stripped_tlv);
1223 TTCN_EncDec_ErrorContext ec_0("While decoding '%s' type: ", p_td.name);
1224 stripped_tlv.chk_constructed_flag(TRUE);
1225 set_size(0);
1226 size_t V_pos=0;
1227 ASN_BER_TLV_t tmp_tlv;
1228 TTCN_EncDec_ErrorContext ec_1("Component #");
1229 TTCN_EncDec_ErrorContext ec_2("0: ");
1230 while(BER_decode_constdTLV_next(stripped_tlv, V_pos, L_form, tmp_tlv)) {
a38c6d4c 1231 get_at(get_nof_elements())->BER_decode_TLV(*p_td.oftype_descr, tmp_tlv, L_form);
970ed795
EL
1232 ec_2.set_msg("%d: ", val_ptr->n_elements);
1233 }
1234 return TRUE;
1235}
1236
1237void Record_Of_Type::BER_decode_opentypes(TTCN_Type_list& p_typelist,
1238 unsigned L_form)
1239{
1240 p_typelist.push(this);
1241 TTCN_EncDec_ErrorContext ec_0("Component #");
1242 TTCN_EncDec_ErrorContext ec_1;
1243 for(int elem_i=0; elem_i<get_nof_elements(); elem_i++) {
1244 ec_1.set_msg("%d: ", elem_i);
1245 get_at(elem_i)->BER_decode_opentypes(p_typelist, L_form);
1246 }
1247 p_typelist.pop();
1248}
1249
1250
1251int Record_Of_Type::RAW_decode(const TTCN_Typedescriptor_t& p_td,
1252 TTCN_Buffer& buff, int limit, raw_order_t top_bit_ord, boolean /*no_err*/,
1253 int sel_field, boolean first_call)
1254{
1255 int prepaddlength = buff.increase_pos_padd(p_td.raw->prepadding);
1256 limit -= prepaddlength;
1257 int decoded_length = 0;
1258 int decoded_field_length = 0;
1259 size_t start_of_field = 0;
1260 if (first_call) {
1261 set_size(0);
1262 }
1263 int start_field = get_nof_elements(); // append at the end
a38c6d4c 1264 TTCN_Typedescriptor_t const& elem_descr = *p_td.oftype_descr;
970ed795
EL
1265 if (p_td.raw->fieldlength || sel_field != -1) {
1266 if (sel_field == -1) sel_field = p_td.raw->fieldlength;
1267 for (int a = 0; a < sel_field; a++) {
1268 Base_Type* field_bt = get_at(a + start_field);
1269 decoded_field_length = field_bt->RAW_decode(elem_descr, buff, limit,
1270 top_bit_ord, TRUE);
1271 if (decoded_field_length < 0) return decoded_field_length;
1272 decoded_length += decoded_field_length;
1273 limit -= decoded_field_length;
1274 }
1275 }
1276 else {
1277 int a = start_field;
1278 if (limit == 0) {
1279 if (!first_call) return -1;
1280 goto finished;
1281 }
970ed795
EL
1282 while (limit > 0) {
1283 start_of_field = buff.get_pos_bit();
1284 Base_Type* field_bt = get_at(a); // non-const, extend the record-of
1285 decoded_field_length = field_bt->RAW_decode(elem_descr, buff, limit,
1286 top_bit_ord, TRUE);
1287 if (decoded_field_length < 0) { // decoding failed, shorten the record-of
1288 set_size(get_nof_elements() - 1);
1289 buff.set_pos_bit(start_of_field);
1290 if (a > start_field) {
1291 goto finished;
1292 }
1293 else return decoded_field_length;
1294 }
1295 decoded_length += decoded_field_length;
1296 limit -= decoded_field_length;
1297 a++;
a38c6d4c 1298 if (EXT_BIT_NO != p_td.raw->extension_bit) {
1299 // (EXT_BIT_YES != p_td.raw->extension_bit) is 0 or 1
970ed795
EL
1300 // This is the opposite value of what the bit needs to be to signal
1301 // the end of decoding, because x-or is the equivalent of !=
a38c6d4c 1302 if ((EXT_BIT_YES != p_td.raw->extension_bit) ^ buff.get_last_bit()) {
970ed795
EL
1303 goto finished;
1304 }
1305 }
1306 }
1307 }
1308finished:
1309 return decoded_length + buff.increase_pos_padd(p_td.raw->padding) + prepaddlength;
1310}
1311
1312int Record_Of_Type::RAW_encode(const TTCN_Typedescriptor_t& p_td, RAW_enc_tree& myleaf) const
1313{
1314 if (err_descr) return RAW_encode_negtest(err_descr, p_td, myleaf);
1315 int encoded_length = 0;
1316 int nof_elements = get_nof_elements();
1317 int encoded_num_of_records =
1318 p_td.raw->fieldlength ? (nof_elements < p_td.raw->fieldlength ? nof_elements : p_td.raw->fieldlength)
1319 : nof_elements;
1320 myleaf.isleaf = FALSE;
1321 myleaf.rec_of = TRUE;
1322 myleaf.body.node.num_of_nodes = encoded_num_of_records;
1323 myleaf.body.node.nodes = init_nodes_of_enc_tree(encoded_num_of_records);
a38c6d4c 1324 TTCN_Typedescriptor_t const& elem_descr = *p_td.oftype_descr;
970ed795
EL
1325 for (int a = 0; a < encoded_num_of_records; a++) {
1326 const Base_Type *field_bt = get_at(a);
1327 myleaf.body.node.nodes[a] = new RAW_enc_tree(TRUE, &myleaf, &(myleaf.curr_pos), a, elem_descr.raw);
1328 encoded_length += field_bt->RAW_encode(elem_descr, *myleaf.body.node.nodes[a]);
1329 }
1330 return myleaf.length = encoded_length;
1331}
1332
1333int Record_Of_Type::RAW_encode_negtest(const Erroneous_descriptor_t *p_err_descr,
1334 const TTCN_Typedescriptor_t& p_td, RAW_enc_tree& myleaf) const
1335{
1336 int values_idx = 0;
1337 int edescr_idx = 0;
1338 int nof_elements = get_nof_elements();
1339 // It can be more, of course...
1340 int encoded_num_of_records =
1341 p_td.raw->fieldlength ? (nof_elements < p_td.raw->fieldlength ? nof_elements : p_td.raw->fieldlength)
1342 : nof_elements;
1343 for (int i = 0; i < nof_elements; ++i) {
1344 if ((p_err_descr->omit_before != -1) && (i < p_err_descr->omit_before)) {
1345 --encoded_num_of_records;
1346 continue;
1347 }
1348 const Erroneous_values_t *err_vals =
1349 p_err_descr->next_field_err_values(i, values_idx);
1350 // Not checking any further, `internal error' will be given anyway in the
1351 // next round. Please note that elements can be removed, `omitted'.
1352 if (err_vals && err_vals->before)
1353 ++encoded_num_of_records;
1354 if (err_vals && err_vals->value && !err_vals->value->errval)
1355 --encoded_num_of_records;
1356 if (err_vals && err_vals->after)
1357 ++encoded_num_of_records;
1358 if ((p_err_descr->omit_after != -1) && (i >= p_err_descr->omit_after)) {
1359 encoded_num_of_records = encoded_num_of_records - (nof_elements - i) + 1;
1360 break;
1361 }
1362 }
1363 myleaf.body.node.num_of_nodes = encoded_num_of_records;
1364 myleaf.body.node.nodes = init_nodes_of_enc_tree(encoded_num_of_records);
1365 int encoded_length = 0;
1366 myleaf.isleaf = FALSE;
1367 myleaf.rec_of = TRUE;
1368 int node_pos = 0;
1369 values_idx = 0;
1370 for (int i = 0; i < nof_elements; ++i) {
1371 if ((p_err_descr->omit_before != -1) && (i < p_err_descr->omit_before))
1372 continue;
1373 const Erroneous_values_t *err_vals = p_err_descr->next_field_err_values(i, values_idx);
1374 const Erroneous_descriptor_t *emb_descr = p_err_descr->next_field_emb_descr(i, edescr_idx);
a38c6d4c 1375 TTCN_Typedescriptor_t const& elem_descr = *p_td.oftype_descr;
970ed795
EL
1376 if (err_vals && err_vals->before) {
1377 if (err_vals->before->errval == NULL)
1378 TTCN_error("internal error: erroneous before value missing");
1379 if (err_vals->before->raw) {
1380 myleaf.body.node.nodes[node_pos] = new RAW_enc_tree(true, &myleaf,
1381 &(myleaf.curr_pos), node_pos,
1382 err_vals->before->errval->get_descriptor()->raw);
1383 encoded_length += err_vals->before->errval->
1384 RAW_encode_negtest_raw(*myleaf.body.node.nodes[node_pos++]);
1385 } else {
1386 if (err_vals->before->type_descr == NULL)
1387 TTCN_error("internal error: erroneous before typedescriptor missing");
1388 myleaf.body.node.nodes[node_pos] = new RAW_enc_tree(TRUE, &myleaf,
1389 &(myleaf.curr_pos), node_pos, elem_descr.raw);
1390 encoded_length += err_vals->before->errval->
1391 RAW_encode(*(err_vals->before->type_descr),
1392 *myleaf.body.node.nodes[node_pos++]);
1393 }
1394 }
1395 if (err_vals && err_vals->value) {
1396 if (err_vals->value->errval) {
1397 if (err_vals->value->raw) {
1398 myleaf.body.node.nodes[node_pos] = new RAW_enc_tree(true, &myleaf,
1399 &(myleaf.curr_pos), node_pos,
1400 err_vals->value->errval->get_descriptor()->raw);
1401 encoded_length += err_vals->value->errval->
1402 RAW_encode_negtest_raw(*myleaf.body.node.nodes[node_pos++]);
1403 } else {
1404 if (err_vals->value->type_descr == NULL)
1405 TTCN_error("internal error: erroneous value typedescriptor missing");
1406 myleaf.body.node.nodes[node_pos] = new RAW_enc_tree(TRUE, &myleaf,
1407 &(myleaf.curr_pos), node_pos, elem_descr.raw);
1408 encoded_length += err_vals->value->errval->
1409 RAW_encode(*(err_vals->value->type_descr),
1410 *myleaf.body.node.nodes[node_pos++]);
1411 }
1412 } // else -> omit
1413 } else {
1414 if (emb_descr) {
1415 myleaf.body.node.nodes[node_pos] = new RAW_enc_tree(TRUE, &myleaf,
1416 &(myleaf.curr_pos), node_pos, elem_descr.raw);
1417 encoded_length += get_at(i)->RAW_encode_negtest(emb_descr,
a38c6d4c 1418 *p_td.oftype_descr, *myleaf.body.node.nodes[node_pos++]);
970ed795
EL
1419 } else {
1420 myleaf.body.node.nodes[node_pos] = new RAW_enc_tree(TRUE, &myleaf,
1421 &(myleaf.curr_pos), node_pos, elem_descr.raw);
a38c6d4c 1422 encoded_length += get_at(i)->RAW_encode(*p_td.oftype_descr,
970ed795
EL
1423 *myleaf.body.node.nodes[node_pos++]);
1424 }
1425 }
1426 if (err_vals && err_vals->after) {
1427 if (err_vals->after->errval == NULL)
1428 TTCN_error("internal error: erroneous after value missing");
1429 if (err_vals->after->raw) {
1430 myleaf.body.node.nodes[node_pos] = new RAW_enc_tree(true, &myleaf,
1431 &(myleaf.curr_pos), node_pos,
1432 err_vals->after->errval->get_descriptor()->raw);
1433 encoded_length += err_vals->after->errval->
1434 RAW_encode_negtest_raw(*myleaf.body.node.nodes[node_pos++]);
1435 } else {
1436 if (err_vals->after->type_descr == NULL)
1437 TTCN_error("internal error: erroneous after typedescriptor missing");
1438 myleaf.body.node.nodes[node_pos] = new RAW_enc_tree(TRUE, &myleaf,
1439 &(myleaf.curr_pos), node_pos, elem_descr.raw);
1440 encoded_length += err_vals->after->errval->
1441 RAW_encode(*(err_vals->after->type_descr),
1442 *myleaf.body.node.nodes[node_pos++]);
1443 }
1444 }
1445 if ((p_err_descr->omit_after != -1) && (i >= p_err_descr->omit_after))
1446 break;
1447 }
1448 return myleaf.length = encoded_length;
1449}
1450
a38c6d4c 1451int Record_Of_Type::JSON_encode(const TTCN_Typedescriptor_t& p_td, JSON_Tokenizer& p_tok) const
970ed795 1452{
3f84031e 1453 if (err_descr) {
1454 return JSON_encode_negtest(err_descr, p_td, p_tok);
1455 }
1456
970ed795
EL
1457 if (!is_bound()) {
1458 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND,
1459 "Encoding an unbound %s of value.", is_set() ? "set" : "record");
1460 return -1;
1461 }
1462
1463 int enc_len = p_tok.put_next_token(JSON_TOKEN_ARRAY_START, NULL);
1464
3f84031e 1465 for (int i = 0; i < get_nof_elements(); ++i) {
feade998 1466 if (NULL != p_td.json && p_td.json->metainfo_unbound && !get_at(i)->is_bound()) {
1467 // unbound elements are encoded as { "metainfo []" : "unbound" }
1468 enc_len += p_tok.put_next_token(JSON_TOKEN_OBJECT_START, NULL);
1469 enc_len += p_tok.put_next_token(JSON_TOKEN_NAME, "metainfo []");
1470 enc_len += p_tok.put_next_token(JSON_TOKEN_STRING, "\"unbound\"");
1471 enc_len += p_tok.put_next_token(JSON_TOKEN_OBJECT_END, NULL);
1472 }
1473 else {
1474 int ret_val = get_at(i)->JSON_encode(*p_td.oftype_descr, p_tok);
1475 if (0 > ret_val) break;
1476 enc_len += ret_val;
1477 }
970ed795
EL
1478 }
1479
1480 enc_len += p_tok.put_next_token(JSON_TOKEN_ARRAY_END, NULL);
1481 return enc_len;
1482}
1483
3f84031e 1484int Record_Of_Type::JSON_encode_negtest(const Erroneous_descriptor_t* p_err_descr,
1485 const TTCN_Typedescriptor_t& p_td,
1486 JSON_Tokenizer& p_tok) const
1487{
1488 if (!is_bound()) {
1489 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND,
1490 "Encoding an unbound %s of value.", is_set() ? "set" : "record");
1491 return -1;
1492 }
1493
1494 int enc_len = p_tok.put_next_token(JSON_TOKEN_ARRAY_START, NULL);
1495
1496 int values_idx = 0;
1497 int edescr_idx = 0;
1498
1499 for (int i = 0; i < get_nof_elements(); ++i) {
1500 if (-1 != p_err_descr->omit_before && p_err_descr->omit_before > i) {
1501 continue;
1502 }
1503
1504 const Erroneous_values_t* err_vals = p_err_descr->next_field_err_values(i, values_idx);
1505 const Erroneous_descriptor_t* emb_descr = p_err_descr->next_field_emb_descr(i, edescr_idx);
1506
1507 if (NULL != err_vals && NULL != err_vals->before) {
1508 if (NULL == err_vals->before->errval) {
1509 TTCN_error("internal error: erroneous before value missing");
1510 }
1511 if (err_vals->before->raw) {
1512 enc_len += err_vals->before->errval->JSON_encode_negtest_raw(p_tok);
1513 } else {
1514 if (NULL == err_vals->before->type_descr) {
1515 TTCN_error("internal error: erroneous before typedescriptor missing");
1516 }
1517 enc_len += err_vals->before->errval->JSON_encode(*(err_vals->before->type_descr), p_tok);
1518 }
1519 }
1520
1521 if (NULL != err_vals && NULL != err_vals->value) {
1522 if (NULL != err_vals->value->errval) {
1523 if (err_vals->value->raw) {
1524 enc_len += err_vals->value->errval->JSON_encode_negtest_raw(p_tok);
1525 } else {
1526 if (NULL == err_vals->value->type_descr) {
1527 TTCN_error("internal error: erroneous before typedescriptor missing");
1528 }
1529 enc_len += err_vals->value->errval->JSON_encode(*(err_vals->value->type_descr), p_tok);
1530 }
1531 }
feade998 1532 }
1533 else if (NULL != p_td.json && p_td.json->metainfo_unbound && !get_at(i)->is_bound()) {
1534 // unbound elements are encoded as { "metainfo []" : "unbound" }
1535 enc_len += p_tok.put_next_token(JSON_TOKEN_OBJECT_START, NULL);
1536 enc_len += p_tok.put_next_token(JSON_TOKEN_NAME, "metainfo []");
1537 enc_len += p_tok.put_next_token(JSON_TOKEN_STRING, "\"unbound\"");
1538 enc_len += p_tok.put_next_token(JSON_TOKEN_OBJECT_END, NULL);
1539 }
1540 else {
3f84031e 1541 int ret_val;
1542 if (NULL != emb_descr) {
1543 ret_val = get_at(i)->JSON_encode_negtest(emb_descr, *p_td.oftype_descr, p_tok);
1544 } else {
1545 ret_val = get_at(i)->JSON_encode(*p_td.oftype_descr, p_tok);
1546 }
1547 if (0 > ret_val) break;
1548 enc_len += ret_val;
1549 }
1550
1551 if (NULL != err_vals && NULL != err_vals->after) {
1552 if (NULL == err_vals->after->errval) {
1553 TTCN_error("internal error: erroneous after value missing");
1554 }
1555 if (err_vals->after->raw) {
1556 enc_len += err_vals->after->errval->JSON_encode_negtest_raw(p_tok);
1557 } else {
1558 if (NULL == err_vals->after->type_descr) {
1559 TTCN_error("internal error: erroneous before typedescriptor missing");
1560 }
1561 enc_len += err_vals->after->errval->JSON_encode(*(err_vals->after->type_descr), p_tok);
1562 }
1563 }
1564
1565 if (-1 != p_err_descr->omit_after && p_err_descr->omit_after <= i) {
1566 break;
1567 }
1568 }
1569
1570 enc_len += p_tok.put_next_token(JSON_TOKEN_ARRAY_END, NULL);
1571 return enc_len;
1572}
1573
970ed795
EL
1574int Record_Of_Type::JSON_decode(const TTCN_Typedescriptor_t& p_td, JSON_Tokenizer& p_tok, boolean p_silent)
1575{
1576 json_token_t token = JSON_TOKEN_NONE;
1577 int dec_len = p_tok.get_next_token(&token, NULL, NULL);
1578 if (JSON_TOKEN_ERROR == token) {
1579 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_BAD_TOKEN_ERROR, "");
1580 return JSON_ERROR_FATAL;
1581 }
1582 else if (JSON_TOKEN_ARRAY_START != token) {
1583 return JSON_ERROR_INVALID_TOKEN;
1584 }
1585
1586 set_size(0);
feade998 1587 for (int nof_elements = 0; true; ++nof_elements) {
970ed795
EL
1588 // Read value tokens until we reach some other token
1589 size_t buf_pos = p_tok.get_buf_pos();
feade998 1590 int ret_val;
1591 if (NULL != p_td.json && p_td.json->metainfo_unbound) {
1592 // check for metainfo object
1593 ret_val = p_tok.get_next_token(&token, NULL, NULL);
1594 if (JSON_TOKEN_OBJECT_START == token) {
1595 char* value = NULL;
1596 size_t value_len = 0;
1597 ret_val += p_tok.get_next_token(&token, &value, &value_len);
1598 if (JSON_TOKEN_NAME == token && 11 == value_len &&
1599 0 == strncmp(value, "metainfo []", 11)) {
1600 ret_val += p_tok.get_next_token(&token, &value, &value_len);
1601 if (JSON_TOKEN_STRING == token && 9 == value_len &&
1602 0 == strncmp(value, "\"unbound\"", 9)) {
1603 ret_val = p_tok.get_next_token(&token, NULL, NULL);
1604 if (JSON_TOKEN_OBJECT_END == token) {
1605 dec_len += ret_val;
1606 continue;
1607 }
1608 }
1609 }
1610 }
1611 // metainfo object not found, jump back and let the element type decode it
1612 p_tok.set_buf_pos(buf_pos);
1613 }
970ed795 1614 Base_Type* val = create_elem();
feade998 1615 ret_val = val->JSON_decode(*p_td.oftype_descr, p_tok, p_silent);
970ed795
EL
1616 if (JSON_ERROR_INVALID_TOKEN == ret_val) {
1617 // undo the last action on the buffer
1618 p_tok.set_buf_pos(buf_pos);
1619 delete val;
1620 break;
1621 }
1622 else if (JSON_ERROR_FATAL == ret_val) {
1623 delete val;
1624 if (p_silent) {
1625 clean_up();
1626 }
1627 return JSON_ERROR_FATAL;
1628 }
af710487 1629 if (NULL == refd_ind_ptr) {
970ed795 1630 val_ptr->value_elements = (Base_Type**)reallocate_pointers(
feade998 1631 (void**)val_ptr->value_elements, val_ptr->n_elements, nof_elements + 1);
1632 val_ptr->value_elements[nof_elements] = val;
1633 val_ptr->n_elements = nof_elements + 1;
970ed795
EL
1634 }
1635 else {
feade998 1636 get_at(nof_elements)->set_value(val);
970ed795
EL
1637 delete val;
1638 }
1639 dec_len += ret_val;
1640 }
1641
1642 dec_len += p_tok.get_next_token(&token, NULL, NULL);
1643 if (JSON_TOKEN_ARRAY_END != token) {
1644 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_REC_OF_END_TOKEN_ERROR, "");
1645 if (p_silent) {
1646 clean_up();
1647 }
1648 return JSON_ERROR_FATAL;
1649 }
1650
1651 return dec_len;
1652}
1653
1654void Record_Of_Type::encode(const TTCN_Typedescriptor_t& p_td,
1655 TTCN_Buffer& p_buf, TTCN_EncDec::coding_t p_coding, ...) const
1656{
1657 va_list pvar;
1658 va_start(pvar, p_coding);
1659 switch(p_coding) {
1660 case TTCN_EncDec::CT_BER: {
1661 TTCN_EncDec_ErrorContext ec("While BER-encoding type '%s': ", p_td.name);
1662 unsigned BER_coding=va_arg(pvar, unsigned);
1663 BER_encode_chk_coding(BER_coding);
1664 ASN_BER_TLV_t *tlv=BER_encode_TLV(p_td, BER_coding);
1665 tlv->put_in_buffer(p_buf);
1666 ASN_BER_TLV_t::destruct(tlv);
1667 break;}
1668 case TTCN_EncDec::CT_RAW: {
1669 TTCN_EncDec_ErrorContext ec("While RAW-encoding type '%s': ", p_td.name);
1670 if (!p_td.raw)
1671 TTCN_EncDec_ErrorContext::error_internal("No RAW descriptor available for type '%s'.", p_td.name);
1672 RAW_enc_tr_pos rp;
1673 rp.level = 0;
1674 rp.pos = NULL;
1675 RAW_enc_tree root(FALSE, NULL, &rp, 1, p_td.raw);
1676 RAW_encode(p_td, root);
1677 root.put_to_buf(p_buf);
1678 break; }
1679 case TTCN_EncDec::CT_TEXT: {
1680 TTCN_EncDec_ErrorContext ec("While TEXT-encoding type '%s': ", p_td.name);
1681 if(!p_td.text) TTCN_EncDec_ErrorContext::error_internal
1682 ("No TEXT descriptor available for type '%s'.", p_td.name);
1683 TEXT_encode(p_td,p_buf);
1684 break;}
1685 case TTCN_EncDec::CT_XER: {
1686 TTCN_EncDec_ErrorContext ec("While XER-encoding type '%s': ", p_td.name);
1687 unsigned XER_coding=va_arg(pvar, unsigned);
af710487 1688 XER_encode(*(p_td.xer),p_buf, XER_coding, 0, 0);
970ed795
EL
1689 p_buf.put_c('\n');
1690 break;}
1691 case TTCN_EncDec::CT_JSON: {
1692 TTCN_EncDec_ErrorContext ec("While JSON-encoding type '%s': ", p_td.name);
1693 if(!p_td.json) TTCN_EncDec_ErrorContext::error_internal
1694 ("No JSON descriptor available for type '%s'.", p_td.name);
1695 JSON_Tokenizer tok(va_arg(pvar, int) != 0);
1696 JSON_encode(p_td, tok);
1697 p_buf.put_s(tok.get_buffer_length(), (const unsigned char*)tok.get_buffer());
1698 break;}
1699 default:
1700 TTCN_error("Unknown coding method requested to encode type '%s'", p_td.name);
1701 }
1702 va_end(pvar);
1703}
1704
1705void Record_Of_Type::decode(const TTCN_Typedescriptor_t& p_td,
1706 TTCN_Buffer& p_buf, TTCN_EncDec::coding_t p_coding, ...)
1707{
1708 va_list pvar;
1709 va_start(pvar, p_coding);
1710 switch(p_coding) {
1711 case TTCN_EncDec::CT_BER: {
1712 TTCN_EncDec_ErrorContext ec("While BER-decoding type '%s': ", p_td.name);
1713 unsigned L_form=va_arg(pvar, unsigned);
1714 ASN_BER_TLV_t tlv;
1715 BER_decode_str2TLV(p_buf, tlv, L_form);
1716 BER_decode_TLV(p_td, tlv, L_form);
1717 if(tlv.isComplete) p_buf.increase_pos(tlv.get_len());
1718 break;}
1719 case TTCN_EncDec::CT_RAW: {
1720 TTCN_EncDec_ErrorContext ec("While RAW-decoding type '%s': ", p_td.name);
1721 if(!p_td.raw) TTCN_EncDec_ErrorContext::error_internal
1722 ("No RAW descriptor available for type '%s'.", p_td.name);
1723 raw_order_t order;
1724 switch(p_td.raw->top_bit_order) {
1725 case TOP_BIT_LEFT:
1726 order=ORDER_LSB;
1727 break;
1728 case TOP_BIT_RIGHT:
1729 default:
1730 order=ORDER_MSB;
1731 }
1732 if(RAW_decode(p_td, p_buf, p_buf.get_len()*8, order)<0)
1733 ec.error(TTCN_EncDec::ET_INCOMPL_MSG,"Can not decode type '%s', "
1734 "because invalid or incomplete message was received", p_td.name);
1735 break;}
1736 case TTCN_EncDec::CT_TEXT: {
1737 Limit_Token_List limit;
1738 TTCN_EncDec_ErrorContext ec("While TEXT-decoding type '%s': ", p_td.name);
1739 if(!p_td.text) TTCN_EncDec_ErrorContext::error_internal
1740 ("No TEXT descriptor available for type '%s'.", p_td.name);
1741 const unsigned char *b=p_buf.get_data();
1742 if(b[p_buf.get_len()-1]!='\0'){
1743 p_buf.set_pos(p_buf.get_len());
1744 p_buf.put_zero(8,ORDER_LSB);
1745 p_buf.rewind();
1746 }
1747 if(TEXT_decode(p_td,p_buf,limit)<0)
1748 ec.error(TTCN_EncDec::ET_INCOMPL_MSG,"Can not decode type '%s', "
1749 "because invalid or incomplete message was received", p_td.name);
1750 break;}
1751 case TTCN_EncDec::CT_XER: {
1752 TTCN_EncDec_ErrorContext ec("While XER-decoding type '%s': ", p_td.name);
1753 unsigned XER_coding=va_arg(pvar, unsigned);
1754 XmlReaderWrap reader(p_buf);
1755 for (int success=reader.Read(); success==1; success=reader.Read()) {
1756 if (reader.NodeType() == XML_READER_TYPE_ELEMENT) break;
1757 }
feade998 1758 XER_decode(*(p_td.xer), reader, XER_coding | XER_TOPLEVEL, XER_NONE, 0);
970ed795
EL
1759 size_t bytes = reader.ByteConsumed();
1760 p_buf.set_pos(bytes);
1761 break;}
1762 case TTCN_EncDec::CT_JSON: {
1763 TTCN_EncDec_ErrorContext ec("While JSON-decoding type '%s': ", p_td.name);
1764 if(!p_td.json) TTCN_EncDec_ErrorContext::error_internal
1765 ("No JSON descriptor available for type '%s'.", p_td.name);
1766 JSON_Tokenizer tok((const char*)p_buf.get_data(), p_buf.get_len());
1767 if(JSON_decode(p_td, tok, false)<0)
1768 ec.error(TTCN_EncDec::ET_INCOMPL_MSG,"Can not decode type '%s', "
1769 "because invalid or incomplete message was received", p_td.name);
1770 p_buf.set_pos(tok.get_buf_pos());
1771 break;}
1772 default:
1773 TTCN_error("Unknown coding method requested to decode type '%s'", p_td.name);
1774 }
1775 va_end(pvar);
1776}
1777
1778char **Record_Of_Type::collect_ns(const XERdescriptor_t& p_td, size_t& num, bool& def_ns) const
1779{
1780 size_t num_collected = 0;
1781 // First, our own namespace. Sets num_collected to 0 or 1.
1782 // If it throws, nothing was allocated.
1783 char **collected_ns = Base_Type::collect_ns(p_td, num_collected, def_ns);
1784
1785 // Then the embedded type
1786 try {
1787 bool def_ns_1 = false;
1788 if (val_ptr) for (int i = 0; i < get_nof_elements(); ++i) {
1789 size_t num_new = 0;
1790 char **new_namespaces = get_at(i)->collect_ns(
a38c6d4c 1791 *p_td.oftype_descr, num_new, def_ns_1);
970ed795
EL
1792 merge_ns(collected_ns, num_collected, new_namespaces, num_new);
1793 def_ns = def_ns || def_ns_1; // alas, no ||=
1794 }
1795 }
1796 catch (...) {
1797 // Probably a TC_Error thrown from the element's collect_ns(),
1798 // e.g. if encoding an unbound value.
1799 while (num_collected > 0) Free(collected_ns[--num_collected]);
1800 Free(collected_ns);
1801 throw;
1802 }
1803
1804 num = num_collected;
1805 return collected_ns;
1806}
1807
1808static const universal_char sp = { 0,0,0,' ' };
1809static const universal_char tb = { 0,0,0,9 };
1810
1811int Record_Of_Type::XER_encode(const XERdescriptor_t& p_td, TTCN_Buffer& p_buf,
af710487 1812 unsigned int flavor, int indent, embed_values_enc_struct_t* emb_val) const
970ed795
EL
1813{
1814 if (err_descr) {
af710487 1815 return XER_encode_negtest(err_descr, p_td, p_buf, flavor, indent, emb_val);
970ed795
EL
1816 }
1817
1818 if (val_ptr == 0) TTCN_error(
1819 "Attempt to XER-encode an unbound record of type %s", get_descriptor()->name);
1820 int encoded_length = (int)p_buf.get_len();
1821
1822 const int exer = is_exer(flavor);
1823 const boolean own_tag =
1824 !(exer && indent && (p_td.xer_bits & (ANY_ELEMENT|ANY_ATTRIBUTES|UNTAGGED)));
1825
1826 const int indenting = !is_canonical(flavor) && own_tag;
1827 const boolean xmlValueList = isXmlValueList();
1828
1829 flavor = flavor
1830 | ( (exer && (p_td.xer_bits & XER_LIST))
1831 || is_exerlist(flavor) ? SIMPLE_TYPE : 0);
1832 flavor &= ~XER_RECOF; // record-of doesn't care
1833 int nof_elements = get_nof_elements();
1834 Base_Type::begin_xml(p_td, p_buf, flavor, indent, !nof_elements,
1835 (collector_fn)&Record_Of_Type::collect_ns);
1836
1837 if (xmlValueList && nof_elements && indenting && !exer) { /* !exer or GDMO */
1838 do_indent(p_buf, indent+1);
1839 }
1840
1841 if (exer && (p_td.xer_bits & ANY_ATTRIBUTES)) {
1842 // Back up over the '>' and the '\n' that may follow it
1843 size_t buf_len = p_buf.get_len(), shorter = 0;
1844 const unsigned char * const buf_data = p_buf.get_data();
1845 if (buf_data[buf_len - 1 - shorter] == '\n') ++shorter;
1846 if (buf_data[buf_len - 1 - shorter] == '>' ) ++shorter;
1847
1848 unsigned char saved [4];
1849 if (shorter) {
1850 memcpy(saved, buf_data + (buf_len - shorter), shorter);
1851 p_buf.increase_length(-shorter);
1852 }
1853
1854 // ANY_ATTRIBUTES means it's a record of universal charstring.
1855 // They are in AnyAttributeFormat (X.693/2008 18.2.6):
1856 // "URI(optional), space, NCName, equals, \"xmlcstring\""
1857 // They need to be written as an XML attribute and namespace declaration:
1858 // xmlns:b0="URI" b0:NCName="xmlcstring"
1859 //
1860 for (int i = 0; i < nof_elements; ++i) {
1861 TTCN_EncDec_ErrorContext ec_0("Attribute %d: ", i);
1862 if (!is_elem_bound(i)) {
1863 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND,
1864 "Encoding an unbound universal charstring value.");
1865 continue;
1866 }
1867 const UNIVERSAL_CHARSTRING *elem
1868 = static_cast<const UNIVERSAL_CHARSTRING *>(val_ptr->value_elements[i]);
1869 size_t len = elem->lengthof();
1870 for (;;) {
1871 const UNIVERSAL_CHARSTRING_ELEMENT& ue = (*elem)[len - 1];
1872 if (sp == ue || tb == ue) --len;
1873 else break;
1874 }
1875 // sp_at: indexes the first space
1876 // j is left to point at where the attribute name begins (just past the space)
1877 size_t j, sp_at = 0;
1878 for (j = 0; j < len; j++) {
1879 const UNIVERSAL_CHARSTRING_ELEMENT& ue = (*elem)[j];
1880 if (sp_at) { // already found a space
1881 if (sp == ue || tb == ue) {} // another space, do nothing
1882 else break; // found a non-space after a space
1883 }
1884 else {
1885 if (sp == ue || tb == ue) sp_at = j;
1886 }
1887 } // next j
1888
1889 size_t buf_start = p_buf.get_len();
1890 if (sp_at > 0) {
1891 char * ns = mprintf(" xmlns:b%d='", i);
1892 size_t ns_len = mstrlen(ns);
1893 p_buf.put_s(ns_len, (cbyte*)ns);
1894
1895 UNIVERSAL_CHARSTRING before(sp_at, (const universal_char*)(*elem));
1896 if (p_td.xer_bits & (ANY_FROM | ANY_EXCEPT)) {
1897 // Ensure the namespace abides to its restrictions
1898 TTCN_Buffer ns_buf;
1899 before.encode_utf8(ns_buf);
1900 CHARSTRING cs;
1901 ns_buf.get_string(cs);
1902 check_namespace_restrictions(p_td, (const char*)cs);
1903 }
1904 before.XER_encode(UNIVERSAL_CHARSTRING_xer_, p_buf,
af710487 1905 flavor | ANY_ATTRIBUTES, indent, 0);
970ed795
EL
1906
1907 p_buf.put_c('\'');
1908 p_buf.put_c(' ');
1909
1910 // Keep just the "b%d" part from ns
1911 p_buf.put_s(ns_len - 9, (cbyte*)ns + 7);
1912 p_buf.put_c(':');
1913 Free(ns);
1914 }
1915 else {
1916 p_buf.put_c(' ');
1917 j = 0;
1918
1919 if (p_td.xer_bits & (ANY_FROM | ANY_EXCEPT)) {
1920 // Make sure the unqualified namespace is allowed
1921 check_namespace_restrictions(p_td, NULL);
1922 }
1923 }
1924
1925 UNIVERSAL_CHARSTRING after(len - j, (const universal_char*)(*elem) + j);
1926 after.XER_encode(UNIVERSAL_CHARSTRING_xer_, p_buf,
af710487 1927 flavor | ANY_ATTRIBUTES, indent, 0);
970ed795
EL
1928
1929 // Put this attribute in a dummy element and walk through it to check its validity
1930 TTCN_Buffer check_buf;
1931 check_buf.put_s(2, (unsigned char*)"<a");
1932 check_buf.put_s(p_buf.get_len() - buf_start, p_buf.get_data() + buf_start);
1933 check_buf.put_s(2, (unsigned char*)"/>");
1934 XmlReaderWrap checker(check_buf);
1935 while (1 == checker.Read());
1936 }
1937 if (shorter) {
1938 p_buf.put_s(shorter, saved); // restore the '>' and anything after
1939 }
1940 }
1941 else { // not ANY-ATTRIBUTES
1942 unsigned int sub_flavor = flavor | XER_RECOF | (p_td.xer_bits & (XER_LIST));
a38c6d4c 1943 TTCN_EncDec_ErrorContext ec_0("Index ");
1944 TTCN_EncDec_ErrorContext ec_1;
970ed795
EL
1945
1946 for (int i = 0; i < nof_elements; ++i) {
af710487 1947 if (i > 0 && !own_tag && 0 != emb_val &&
1948 emb_val->embval_index < emb_val->embval_array->size_of()) {
1949 emb_val->embval_array->get_at(emb_val->embval_index)->XER_encode(
1950 UNIVERSAL_CHARSTRING_xer_, p_buf, flavor | EMBED_VALUES, indent+1, 0);
1951 ++emb_val->embval_index;
1952 }
a38c6d4c 1953 ec_1.set_msg("%d: ", i);
970ed795 1954 if (exer && (p_td.xer_bits & XER_LIST) && i>0) p_buf.put_c(' ');
a38c6d4c 1955 get_at(i)->XER_encode(*p_td.oftype_descr, p_buf,
af710487 1956 sub_flavor, indent+own_tag, emb_val);
970ed795
EL
1957 }
1958
1959 if (indenting && nof_elements && !is_exerlist(flavor)) {
1960 if (xmlValueList && !exer) p_buf.put_c('\n'); /* !exer or GDMO */
1961 //do_indent(p_buf, indent);
1962 }
1963 }
1964
1965 Base_Type::end_xml(p_td, p_buf, flavor, indent, !nof_elements);
1966 return (int)p_buf.get_len() - encoded_length;
1967}
1968
1969// XERSTUFF Record_Of_Type::encode_element
1970/** Helper for Record_Of_Type::XER_encode_negtest
1971 *
1972 * The main purpose of this method is to allow another type to request
1973 * encoding of a single element of the record-of. Used by Record_Type
1974 * to encode individual strings of the EMBED-VALUES member.
1975 *
1976 * @param i index of the element
1977 * @param ev erroneous descriptor for the element itself
1978 * @param ed deeper erroneous values
1979 * @param p_buf buffer containing the encoded value
1980 * @param sub_flavor flags
1981 * @param indent indentation level
1982 * @return number of bytes generated
1983 */
a38c6d4c 1984int Record_Of_Type::encode_element(int i, const XERdescriptor_t& p_td,
970ed795 1985 const Erroneous_values_t* ev, const Erroneous_descriptor_t* ed,
af710487 1986 TTCN_Buffer& p_buf, unsigned int sub_flavor, int indent, embed_values_enc_struct_t* emb_val) const
970ed795
EL
1987{
1988 int enc_len = p_buf.get_len();
1989 TTCN_EncDec_ErrorContext ec;
1990 const int exer = is_exer(sub_flavor);
1991
1992 if (ev && ev->before) {
1993 if (ev->before->errval==NULL) {
1994 TTCN_error("internal error: erroneous before value missing");
1995 }
1996 ec.set_msg("Erroneous value before component #%d: ", i);
1997 if (ev->before->raw) {
1998 ev->before->errval->encode_raw(p_buf);
1999 } else {
2000 if (ev->before->type_descr==NULL) TTCN_error(
2001 "internal error: erroneous before type descriptor missing");
2002 ev->before->errval->XER_encode(*ev->before->type_descr->xer,
af710487 2003 p_buf, sub_flavor, indent, 0);
970ed795
EL
2004 }
2005 }
2006
2007 if (exer && (sub_flavor & XER_LIST)
2008 && (i > 0 || (ev && ev->before && !ev->before->raw))){
2009 // Ensure a separator is written after the "erroneous before"
2010 // of the first element (except for "raw before").
2011 p_buf.put_c(' ');
2012 }
2013
2014 if (ev && ev->value) {
2015 if (ev->value->errval) { // replace
2016 ec.set_msg("Erroneous value for component #%d: ", i);
2017 if (ev->value->raw) {
2018 ev->value->errval->encode_raw(p_buf);
2019 } else {
2020 if (ev->value->type_descr==NULL) TTCN_error(
2021 "internal error: erroneous value type descriptor missing");
2022 ev->value->errval->XER_encode(*ev->value->type_descr->xer,
af710487 2023 p_buf, sub_flavor, indent, 0);
970ed795
EL
2024 }
2025 } // else -> omit
2026 } else {
2027 ec.set_msg("Component #%d: ", i);
2028 if (ed) {
a38c6d4c 2029 get_at(i)->XER_encode_negtest(ed, p_td, p_buf, sub_flavor, indent, emb_val);
970ed795
EL
2030 } else {
2031 // the "real" encoder
a38c6d4c 2032 get_at(i)->XER_encode(p_td, p_buf, sub_flavor, indent, emb_val);
970ed795
EL
2033 }
2034 }
2035
2036 if (ev && ev->after) {
2037 if (ev->after->errval==NULL) {
2038 TTCN_error("internal error: erroneous after value missing");
2039 }
2040 ec.set_msg("Erroneous value after component #%d: ", i);
2041 if (ev->after->raw) {
2042 ev->after->errval->encode_raw(p_buf);
2043 } else {
2044 if (ev->after->type_descr==NULL) TTCN_error(
2045 "internal error: erroneous after type descriptor missing");
2046 ev->after->errval->XER_encode(*ev->after->type_descr->xer,
af710487 2047 p_buf, sub_flavor, indent, 0);
970ed795
EL
2048 }
2049 }
2050
2051 return enc_len;
2052}
2053
2054// XERSTUFF Record_Of_Type::XER_encode_negtest
2055int Record_Of_Type::XER_encode_negtest(const Erroneous_descriptor_t* p_err_descr,
af710487 2056 const XERdescriptor_t& p_td, TTCN_Buffer& p_buf, unsigned flavor, int indent,
2057 embed_values_enc_struct_t* emb_val) const
970ed795
EL
2058{
2059 if (val_ptr == 0) TTCN_error(
2060 "Attempt to XER-encode an unbound record of type %s", get_descriptor()->name);
2061 int encoded_length = (int)p_buf.get_len();
2062
2063 const int exer = is_exer(flavor);
2064 const boolean own_tag =
2065 !(exer && indent && (p_td.xer_bits & (ANY_ELEMENT|ANY_ATTRIBUTES|UNTAGGED)));
2066
2067 const int indenting = !is_canonical(flavor) && own_tag;
2068 const boolean xmlValueList = isXmlValueList();
2069
2070 flavor = flavor
2071 | ( (exer && (p_td.xer_bits & XER_LIST))
2072 || is_exerlist(flavor) ? SIMPLE_TYPE : 0);
2073 flavor &= ~XER_RECOF; // record-of doesn't care
2074 int nof_elements = get_nof_elements();
2075 Base_Type::begin_xml(p_td, p_buf, flavor, indent, !nof_elements,
2076 (collector_fn)&Record_Of_Type::collect_ns);
2077
2078 if (xmlValueList && nof_elements && indenting && !exer) { /* !exer or GDMO */
2079 do_indent(p_buf, indent+1);
2080 }
2081
2082 int values_idx = 0;
2083 int edescr_idx = 0;
2084 if (exer && (p_td.xer_bits & ANY_ATTRIBUTES)) {
2085 // Back up over the '>' and the '\n' that may follow it
2086 size_t buf_len = p_buf.get_len(), shorter = 0;
2087 const unsigned char * const buf_data = p_buf.get_data();
2088 if (buf_data[buf_len - 1 - shorter] == '\n') ++shorter;
2089 if (buf_data[buf_len - 1 - shorter] == '>' ) ++shorter;
2090
2091 unsigned char * saved = 0;
2092 if (shorter) {
2093 saved = new unsigned char[shorter];
2094 memcpy(saved, buf_data + (buf_len - shorter), shorter);
2095 p_buf.increase_length(-shorter);
2096 }
2097
2098 // ANY_ATTRIBUTES means it's a record of universal charstring.
2099 // They are in AnyAttributeFormat (X.693/2008 18.2.6):
2100 // "URI(optional), space, NCName, equals, \"xmlcstring\""
2101 // They need to be written as an XML attribute and namespace declaration:
2102 // xmlns:b0="URI" b0:NCName="xmlcstring"
2103 //
2104 for (int i = 0; i < nof_elements; ++i) {
2105 if (i < p_err_descr->omit_before) continue;
2106
2107 const Erroneous_values_t *ev = p_err_descr->next_field_err_values(i, values_idx);
2108 const Erroneous_descriptor_t *ed = p_err_descr->next_field_emb_descr(i, edescr_idx);
2109
2110 if (ev && ev->before) {
2111 if (ev->before->errval==NULL) TTCN_error("internal error: erroneous value missing");
2112
2113 // ec.set_msg
2114 if (ev->before->raw) ev->before->errval->encode_raw(p_buf);
2115 else {
2116 if (ev->before->type_descr==NULL) TTCN_error(
2117 "internal error: erroneous before type descriptor missing");
2118 else ev->before->errval->XER_encode(*ev->before->type_descr->xer,
af710487 2119 p_buf, flavor, indent, 0);
970ed795
EL
2120 }
2121 }
2122
2123 if (ev && ev->value) { //value replacement
2124 if (ev->value->errval) {
2125 if (ev->value->raw) ev->value->errval->encode_raw(p_buf);
2126 else {
2127 if (ev->value->type_descr==NULL) TTCN_error(
2128 "internal error: erroneous value type descriptor missing");
2129 else ev->value->errval->XER_encode(*ev->value->type_descr->xer,
af710487 2130 p_buf, flavor, indent, 0);
970ed795
EL
2131 }
2132 }
2133 }
2134 else {
2135 if (ed) {
2136 // embedded descr.. call negtest (except UNIVERSAL_CHARSTRING
2137 // doesn't have XER_encode_negtest)
2138 TTCN_error("internal error: embedded descriptor for scalar");
2139 }
2140 else {
2141 // the original encoding
2142 const UNIVERSAL_CHARSTRING *elem
2143 = static_cast<const UNIVERSAL_CHARSTRING *>(get_at(i));
2144 size_t len = elem->lengthof();
2145 for (;;) {
2146 const UNIVERSAL_CHARSTRING_ELEMENT& ue = (*elem)[len - 1];
2147 if (sp == ue || tb == ue) --len;
2148 else break;
2149 }
2150 // sp_at: indexes the first space
2151 // j is left to point at where the attribute name begins (just past the space)
2152 size_t j, sp_at = 0;
2153 for (j = 0; j < len; j++) {
2154 const UNIVERSAL_CHARSTRING_ELEMENT& ue = (*elem)[j];
2155 if (sp_at) { // already found a space
2156 if (sp == ue || tb == ue) {} // another space, do nothing
2157 else break; // found a non-space after a space
2158 }
2159 else {
2160 if (sp == ue || tb == ue) sp_at = j;
2161 }
2162 } // next j
2163
2164 if (sp_at > 0) {
2165 char * ns = mprintf(" xmlns:b%d='", i);
2166 size_t ns_len = mstrlen(ns);
2167 p_buf.put_s(ns_len, (cbyte*)ns);
2168
2169 UNIVERSAL_CHARSTRING before(sp_at, (const universal_char*)(*elem));
2170 before.XER_encode(UNIVERSAL_CHARSTRING_xer_, p_buf,
af710487 2171 flavor | ANY_ATTRIBUTES, indent, 0);
970ed795
EL
2172
2173 p_buf.put_c('\'');
2174 p_buf.put_c(' ');
2175
2176 // Keep just the "b%d" part from ns
2177 p_buf.put_s(ns_len - 9, (cbyte*)ns + 7);
2178 p_buf.put_c(':');
2179 Free(ns);
2180 }
2181 else {
2182 p_buf.put_c(' ');
2183 j = 0;
2184 }
2185
2186 UNIVERSAL_CHARSTRING after(len - j, (const universal_char*)(*elem) + j);
2187 after.XER_encode(UNIVERSAL_CHARSTRING_xer_, p_buf,
af710487 2188 flavor | ANY_ATTRIBUTES, indent, 0);
970ed795
EL
2189 }
2190 }
2191
2192 if (ev && ev->after) {
2193 if (ev->after->errval==NULL) TTCN_error(
2194 "internal error: erroneous after value missing");
2195 else {
2196 if (ev->after->raw) ev->after->errval->encode_raw(p_buf);
2197 else {
2198 if (ev->after->type_descr==NULL) TTCN_error(
2199 "internal error: erroneous after type descriptor missing");
2200 else ev->after->errval->XER_encode(*ev->after->type_descr->xer,
af710487 2201 p_buf, flavor, indent, 0);
970ed795
EL
2202 }
2203 }
2204 }
2205 // omit_after value -1 becomes "very big"
2206 if ((unsigned int)i >= (unsigned int)p_err_descr->omit_after) break;
2207 }
2208 if (shorter) {
2209 p_buf.put_s(shorter, saved); // restore the '>' and anything after
2210 delete[] saved;
2211 }
2212 }
2213 else { // not ANY-ATTRIBUTES
2214 unsigned int sub_flavor = flavor | XER_RECOF | (p_td.xer_bits & (XER_LIST|ANY_ATTRIBUTES));
2215
2216 TTCN_EncDec_ErrorContext ec;
2217
2218 for (int i = 0; i < nof_elements; ++i) {
2219 if (i < p_err_descr->omit_before) continue;
af710487 2220
2221 if (0 != emb_val && i > 0 && !own_tag &&
2222 emb_val->embval_index < emb_val->embval_array->size_of()) {
2223 const Erroneous_values_t * ev0_i = NULL;
2224 const Erroneous_descriptor_t* ed0_i = NULL;
2225 if (emb_val->embval_err) {
2226 ev0_i = emb_val->embval_err->next_field_err_values(emb_val->embval_index, emb_val->embval_err_val_idx);
2227 ed0_i = emb_val->embval_err->next_field_emb_descr (emb_val->embval_index, emb_val->embval_err_descr_idx);
2228 }
a38c6d4c 2229 emb_val->embval_array->encode_element(emb_val->embval_index, UNIVERSAL_CHARSTRING_xer_,
2230 ev0_i, ed0_i, p_buf, flavor | EMBED_VALUES, indent + own_tag, 0);
af710487 2231 ++emb_val->embval_index;
2232 }
970ed795
EL
2233
2234 const Erroneous_values_t* err_vals =
2235 p_err_descr->next_field_err_values(i, values_idx);
2236 const Erroneous_descriptor_t* emb_descr =
2237 p_err_descr->next_field_emb_descr (i, edescr_idx);
2238
a38c6d4c 2239 encode_element(i, *p_td.oftype_descr, err_vals, emb_descr, p_buf, sub_flavor, indent+own_tag, emb_val);
970ed795
EL
2240
2241 // omit_after value -1 becomes "very big"
2242 if ((unsigned int)i >= (unsigned int)p_err_descr->omit_after) break;
2243 }
2244
2245 if (indenting && nof_elements && !is_exerlist(flavor)) {
2246 if (xmlValueList && !exer) p_buf.put_c('\n'); /* !exer or GDMO */
2247 //do_indent(p_buf, indent);
2248 }
2249 }
2250
2251 Base_Type::end_xml(p_td, p_buf, flavor, indent, !nof_elements);
2252 return (int)p_buf.get_len() - encoded_length;
2253}
2254
2255int Record_Of_Type::XER_decode(const XERdescriptor_t& p_td,
feade998 2256 XmlReaderWrap& reader, unsigned int flavor, unsigned int flavor2, embed_values_dec_struct_t* emb_val)
970ed795
EL
2257{
2258 int exer = is_exer(flavor);
2259 int xerbits = p_td.xer_bits;
2260 if (flavor & XER_TOPLEVEL) xerbits &= ~UNTAGGED;
2261 boolean own_tag =
2262 !(exer && ((xerbits & (ANY_ELEMENT | ANY_ATTRIBUTES | UNTAGGED))
2263 || (flavor & USE_TYPE_ATTR))); /* incase the parent has USE-UNION */
2264 /* not toplevel anymore and remove the flags for USE-UNION the oftype doesn't need them */
2265 flavor &= ~XER_TOPLEVEL & ~XER_LIST & ~USE_TYPE_ATTR;
2266 int success=1, depth=-1;
2267 set_val(NULL_VALUE); // empty but initialized array, val_ptr != NULL
2268 int type;
2269 if (own_tag) for (success = 1; success == 1; success = reader.Read()) {
2270 type = reader.NodeType();
2271 if (exer && (p_td.xer_bits & XER_ATTRIBUTE)) {
2272 if (XML_READER_TYPE_ATTRIBUTE == type) break;
2273 }
2274 if (exer && (p_td.xer_bits & XER_LIST)) {
2275 if (XML_READER_TYPE_TEXT == type) break;
2276 }
2277 else {
2278 if (XML_READER_TYPE_ELEMENT == type) {
2279 verify_name(reader, p_td, exer);
2280 depth = reader.Depth();
2281 break;
2282 }
2283 } /* endif(exer && list) */
2284 } /* next read */
2285 else depth = reader.Depth();
2286 TTCN_EncDec_ErrorContext ec_0("Index ");
2287 TTCN_EncDec_ErrorContext ec_1;
2288 flavor |= XER_RECOF;
2289 if (exer && (p_td.xer_bits & ANY_ATTRIBUTES)) {
2290 // The enclosing type should handle the decoding.
2291 TTCN_error("Incorrect decoding of ANY-ATTRIBUTES");
2292 }
2293 else if (exer && (p_td.xer_bits & XER_LIST)) { /* LIST decoding*/
2294 char *val = (char*)reader.NewValue(); /* we own it */
2295 size_t pos = 0;
2296 size_t len = strlen(val);
2297 /* The string contains a bunch of values separated by whitespace.
2298 * Tokenize the string and create a new buffer which looks like
2299 * an XML element (<ns:name xmlns:ns='uri'>value</ns:name>), then use that
2300 * to decode the value. */
2301 for(char * str = strtok(val, " \t\x0A\x0D"); str != 0; str = strtok(val + pos, " \t\x0A\x0D")) {
2302 // Calling strtok with NULL won't work here, since the decoded element can have strtok calls aswell
2303 pos += strlen(str) + 1;
2304 // Construct a new XML Reader with the current token.
2305 TTCN_Buffer buf2;
a38c6d4c 2306 const XERdescriptor_t& sub_xer = *p_td.oftype_descr;
970ed795
EL
2307 buf2.put_c('<');
2308 write_ns_prefix(sub_xer, buf2);
2309
2310 boolean i_can_has_ns = sub_xer.my_module != 0 && sub_xer.ns_index != -1;
2311 const char * const exer_name = sub_xer.names[1];
2312 buf2.put_s((size_t)sub_xer.namelens[1]-1-i_can_has_ns, (cbyte*)exer_name);
2313 if (i_can_has_ns) {
2314 const namespace_t * const pns = sub_xer.my_module->get_ns(sub_xer.ns_index);
2315 buf2.put_s(7 - (*pns->px == 0), (cbyte*)" xmlns:");
2316 buf2.put_s(strlen(pns->px), (cbyte*)pns->px);
2317 buf2.put_s(2, (cbyte*)"='");
2318 buf2.put_s(strlen(pns->ns), (cbyte*)pns->ns);
2319 buf2.put_s(2, (cbyte*)"'>");
2320 }
2321 // start tag completed
2322 buf2.put_s(strlen(str), (cbyte*)str);
2323
2324 buf2.put_c('<');
2325 buf2.put_c('/');
2326 write_ns_prefix(sub_xer, buf2);
2327 buf2.put_s((size_t)sub_xer.namelens[1], (cbyte*)exer_name);
2328 XmlReaderWrap reader2(buf2);
2329 reader2.Read(); // Move to the start element.
2330 // Don't move to the #text, that's the callee's responsibility.
2331 ec_1.set_msg("%d: ", get_nof_elements());
2332 // The call to the non-const operator[], I mean get_at(), creates
2333 // a new element (because it is indexing one past the last element).
2334 // Then we call its XER_decode with the temporary XML reader.
feade998 2335 get_at(get_nof_elements())->XER_decode(sub_xer, reader2, flavor, flavor2, 0);
970ed795
EL
2336 if (flavor & EXIT_ON_ERROR && !is_elem_bound(get_nof_elements() - 1)) {
2337 if (1 == get_nof_elements()) {
2338 // Failed to decode even the first element
2339 clean_up();
2340 } else {
2341 // Some elements were successfully decoded -> only delete the last one
2342 set_size(get_nof_elements() - 1);
2343 }
2344 xmlFree(val);
2345 return -1;
2346 }
2347 if (pos >= len) break;
2348 }
2349 xmlFree(val);
2350 if (p_td.xer_bits & XER_ATTRIBUTE) {
2351 //Let the caller do reader.AdvanceAttribute();
2352 }
2353 else if (own_tag) {
2354 reader.Read(); // on closing tag
2355 reader.Read(); // past it
2356 }
2357 }
2358 else { // not LIST
2359 if (flavor & PARENT_CLOSED) {
2360 // Nothing to do. We are probably untagged; do not advance in the XML
2361 // because it would move past the parent.
2362 }
2363 else if (own_tag && reader.IsEmptyElement()) { // Nothing to do
2364 reader.Read(); // This is our own empty tag, move past it
2365 }
2366 else {
2367 /* Note: there is no reader.Read() at the end of the loop below.
2368 * Each element is supposed to consume enough to leave the next element
2369 * well-positioned. */
2370 for (success = own_tag ? reader.Read() : reader.Ok(); success == 1; ) {
2371 type = reader.NodeType();
2372 if (XML_READER_TYPE_ELEMENT == type)
2373 {
2374 if (exer && (p_td.xer_bits & ANY_ELEMENT)) {
2375 /* This is a (record-of UNIVERSAL_CHARSTRING) with ANY-ELEMENT.
2376 * The ANY-ELEMENT is really meant for the element type,
2377 * so behave like a record-of (string with ANY-ELEMENT):
2378 * call the non-const operator[], I mean get_at(), to create
2379 * a new element, then read the entire XML element into it. */
2380 UNIVERSAL_CHARSTRING* uc =
2381 static_cast<UNIVERSAL_CHARSTRING*>(get_at(val_ptr->n_elements));
2382 const xmlChar* outer = reader.ReadOuterXml();
2383 uc->decode_utf8(strlen((const char*)outer), outer);
2384 // consume the element
2385 for (success = reader.Read(); success == 1 && reader.Depth() > depth; success = reader.Read()) {}
2386 if (reader.NodeType() != XML_READER_TYPE_ELEMENT) success = reader.Read(); // one last time
2387 }
2388 else {
2389 /* If this is an untagged record-of and the start element does not
2390 * belong to the embedded type, the record-of has already ended. */
2391 if (!own_tag && !can_start_v(
2392 (const char*)reader.LocalName(), (const char*)reader.NamespaceUri(),
a38c6d4c 2393 p_td, flavor | UNTAGGED))
970ed795
EL
2394 {
2395 for (; success == 1 && reader.Depth() > depth; success = reader.Read()) ;
2396 // We should now be back at the same depth as we started.
2397 break;
2398 }
2399 ec_1.set_msg("%d: ", get_nof_elements());
2400 /* The call to the non-const get_at() creates the element */
feade998 2401 get_at(get_nof_elements())->XER_decode(*p_td.oftype_descr, reader, flavor, flavor2, emb_val);
2402 }
2403 if (0 != emb_val && !own_tag && get_nof_elements() > 1) {
2404 ++emb_val->embval_index;
970ed795
EL
2405 }
2406 }
2407 else if (XML_READER_TYPE_END_ELEMENT == type) {
2408 for (; success == 1 && reader.Depth() > depth; success = reader.Read()) ;
2409 // If the depth just decreased, this must be an end element
2410 // (but a different one from what we had before the loop)
2411 if (own_tag) {
2412 verify_end(reader, p_td, depth, exer);
2413 reader.Read(); // move forward one last time
2414 }
2415 break;
2416 }
af710487 2417 else if (XML_READER_TYPE_TEXT == type && 0 != emb_val && !own_tag && get_nof_elements() > 0) {
2418 UNIVERSAL_CHARSTRING emb_ustr((const char*)reader.Value());
2419 emb_val->embval_array->get_at(emb_val->embval_index)->set_value(&emb_ustr);
2420 success = reader.Read();
2421 }
970ed795
EL
2422 else {
2423 success = reader.Read();
2424 }
2425 } /* next read */
2426 } /* if not empty element */
2427 } /* if not LIST */
51fa56b9 2428 if (!own_tag && exer && (p_td.xer_bits & XER_OPTIONAL) && get_nof_elements() == 0) {
2429 // set it to unbound, so the OPTIONAL class sets it to omit
2430 clean_up();
2431 }
970ed795
EL
2432 return 1; // decode successful
2433}
2434
2435void Record_Of_Type::set_param(Module_Param& param) {
2436 if (dynamic_cast<Module_Param_Name*>(param.get_id()) != NULL &&
2437 param.get_id()->next_name()) {
2438 // Haven't reached the end of the module parameter name
2439 // => the name refers to one of the elements, not to the whole record of
2440 char* param_field = param.get_id()->get_current_name();
2441 if (param_field[0] < '0' || param_field[0] > '9') {
2442 param.error("Unexpected record field name in module parameter, expected a valid"
2443 " index for %s type `%s'", is_set() ? "set of" : "record of", get_descriptor()->name);
2444 }
2445 int param_index = -1;
2446 sscanf(param_field, "%d", &param_index);
2447 get_at(param_index)->set_param(param);
2448 return;
2449 }
2450
2451 param.basic_check(Module_Param::BC_VALUE|Module_Param::BC_LIST, is_set()?"set of value":"record of value");
3abe9331 2452
2453 Module_Param_Ptr mp = &param;
2454 if (param.get_type() == Module_Param::MP_Reference) {
2455 mp = param.get_referenced_param();
2456 }
2457
970ed795
EL
2458 switch (param.get_operation_type()) {
2459 case Module_Param::OT_ASSIGN:
3abe9331 2460 if (mp->get_type()==Module_Param::MP_Value_List && mp->get_size()==0) {
970ed795
EL
2461 set_val(NULL_VALUE);
2462 return;
2463 }
3abe9331 2464 switch (mp->get_type()) {
970ed795 2465 case Module_Param::MP_Value_List:
3abe9331 2466 set_size(mp->get_size());
2467 for (size_t i=0; i<mp->get_size(); ++i) {
2468 Module_Param* const curr = mp->get_elem(i);
970ed795
EL
2469 if (curr->get_type()!=Module_Param::MP_NotUsed) {
2470 get_at(i)->set_param(*curr);
9e3e25dc
BB
2471 if (!get_at(i)->is_bound()) {
2472 // use null pointers for unbound elements
2473 delete val_ptr->value_elements[i];
2474 val_ptr->value_elements[i] = NULL;
2475 }
970ed795
EL
2476 }
2477 }
2478 break;
2479 case Module_Param::MP_Indexed_List:
3abe9331 2480 for (size_t i=0; i<mp->get_size(); ++i) {
2481 Module_Param* const current = mp->get_elem(i);
970ed795 2482 get_at(current->get_id()->get_index())->set_param(*current);
9e3e25dc
BB
2483 if (!get_at(current->get_id()->get_index())->is_bound()) {
2484 // use null pointers for unbound elements
2485 delete val_ptr->value_elements[current->get_id()->get_index()];
2486 val_ptr->value_elements[current->get_id()->get_index()] = NULL;
2487 }
970ed795
EL
2488 }
2489 break;
2490 default:
2491 param.type_error(is_set()?"set of value":"record of value", get_descriptor()->name);
2492 }
2493 break;
2494 case Module_Param::OT_CONCAT:
3abe9331 2495 switch (mp->get_type()) {
970ed795
EL
2496 case Module_Param::MP_Value_List: {
2497 if (!is_bound()) set_val(NULL_VALUE);
2498 int start_idx = lengthof();
3abe9331 2499 for (size_t i=0; i<mp->get_size(); ++i) {
2500 Module_Param* const curr = mp->get_elem(i);
970ed795
EL
2501 if ((curr->get_type()!=Module_Param::MP_NotUsed)) {
2502 get_at(start_idx+(int)i)->set_param(*curr);
2503 }
2504 }
2505 } break;
2506 case Module_Param::MP_Indexed_List:
2507 param.error("Cannot concatenate an indexed value list");
2508 break;
2509 default:
2510 param.type_error(is_set()?"set of value":"record of value", get_descriptor()->name);
2511 }
2512 break;
2513 default:
2514 TTCN_error("Internal error: Record_Of_Type::set_param()");
2515 }
2516}
2517
3abe9331 2518Module_Param* Record_Of_Type::get_param(Module_Param_Name& param_name) const
2519{
2520 if (!is_bound()) {
2521 return new Module_Param_Unbound();
2522 }
2523 if (param_name.next_name()) {
2524 // Haven't reached the end of the module parameter name
2525 // => the name refers to one of the elements, not to the whole record of
2526 char* param_field = param_name.get_current_name();
2527 if (param_field[0] < '0' || param_field[0] > '9') {
2528 TTCN_error("Unexpected record field name in module parameter reference, "
2529 "expected a valid index for %s type `%s'",
2530 is_set() ? "set of" : "record of", get_descriptor()->name);
2531 }
2532 int param_index = -1;
2533 sscanf(param_field, "%d", &param_index);
2534 return get_at(param_index)->get_param(param_name);
2535 }
2536 Vector<Module_Param*> values;
2537 for (int i = 0; i < val_ptr->n_elements; ++i) {
2538 values.push_back(val_ptr->value_elements[i]->get_param(param_name));
2539 }
2540 Module_Param_Value_List* mp = new Module_Param_Value_List();
2541 mp->add_list_with_implicit_ids(&values);
2542 values.clear();
2543 return mp;
2544}
2545
970ed795
EL
2546void Record_Of_Type::set_implicit_omit()
2547{
2548 for (int i = 0; i < get_nof_elements(); ++i) {
2549 if (is_elem_bound(i))
2550 val_ptr->value_elements[i]->set_implicit_omit();
2551 }
2552}
2553
2554void Record_Of_Type::add_refd_index(int index)
2555{
af710487 2556 if (NULL == refd_ind_ptr) {
2557 refd_ind_ptr = new refd_index_struct;
2558 refd_ind_ptr->max_refd_index = -1;
2559 }
2560 refd_ind_ptr->refd_indices.push_back(index);
970ed795 2561 if (index > get_max_refd_index()) {
af710487 2562 refd_ind_ptr->max_refd_index = index;
970ed795
EL
2563 }
2564}
2565
2566void Record_Of_Type::remove_refd_index(int index)
2567{
af710487 2568 for (size_t i = refd_ind_ptr->refd_indices.size(); i > 0; --i) {
2569 if (refd_ind_ptr->refd_indices[i - 1] == index) {
2570 refd_ind_ptr->refd_indices.erase_at(i - 1);
970ed795
EL
2571 break;
2572 }
2573 }
af710487 2574 if (refd_ind_ptr->refd_indices.empty()) {
2575 delete refd_ind_ptr;
2576 refd_ind_ptr = NULL;
2577 }
2578 else if (get_max_refd_index() == index) {
2579 refd_ind_ptr->max_refd_index = -1;
970ed795
EL
2580 }
2581}
2582
2583boolean operator==(null_type /*null_value*/, const Record_Of_Type& other_value)
2584{
2585 if (other_value.val_ptr == NULL)
2586 TTCN_error("The right operand of comparison is an unbound value of type %s.",
2587 other_value.get_descriptor()->name);
2588 return other_value.get_nof_elements() == 0;
2589}
2590
2591boolean operator!=(null_type null_value,
2592 const Record_Of_Type& other_value)
2593{
2594 return !(null_value == other_value);
2595}
2596
2597////////////////////////////////////////////////////////////////////////////////
2598
2599boolean Record_Type::is_bound() const
2600{
970ed795
EL
2601 int field_cnt = get_count();
2602 for (int field_idx=0; field_idx<field_cnt; field_idx++) {
2603 const Base_Type* temp = get_at(field_idx);
2604 if(temp->is_optional()) {
2605 if(temp->is_present() && temp->get_opt_value()->is_bound()) return TRUE;
2606 }
2607 if(temp->is_bound()) return TRUE;
2608 }
2609 return FALSE;
2610}
2611
2612boolean Record_Type::is_value() const
2613{
970ed795
EL
2614 int field_cnt = get_count();
2615 for (int field_idx=0; field_idx<field_cnt; field_idx++) {
2616 const Base_Type* temp = get_at(field_idx);
2617 if(temp->is_optional()) {
2618 if(!temp->is_bound()) return FALSE;
2619 if(temp->is_present() && !temp->is_value()) return FALSE;
2620 } else {
2621 if(!temp->is_value()) return FALSE;
2622 }
2623 }
2624 return TRUE;
2625}
2626
2627void Record_Type::clean_up()
2628{
2629 int field_cnt = get_count();
2630 for (int field_idx=0; field_idx<field_cnt; field_idx++) {
2631 get_at(field_idx)->clean_up();
2632 }
970ed795
EL
2633}
2634
2635void Record_Type::log() const
2636{
2637 if (!is_bound()) {
2638 TTCN_Logger::log_event_unbound();
2639 return;
2640 }
2641 TTCN_Logger::log_event_str("{ ");
2642 int field_cnt = get_count();
2643 for (int field_idx=0; field_idx<field_cnt; field_idx++) {
2644 if (field_idx) TTCN_Logger::log_event_str(", ");
2645 TTCN_Logger::log_event_str(fld_name(field_idx));
2646 TTCN_Logger::log_event_str(" := ");
2647 get_at(field_idx)->log();
2648 }
2649 TTCN_Logger::log_event_str(" }");
2650 if (err_descr) err_descr->log();
2651}
2652
2653void Record_Type::set_param(Module_Param& param) {
970ed795
EL
2654 if (dynamic_cast<Module_Param_Name*>(param.get_id()) != NULL &&
2655 param.get_id()->next_name()) {
2656 // Haven't reached the end of the module parameter name
2657 // => the name refers to one of the fields, not to the whole record
2658 char* param_field = param.get_id()->get_current_name();
2659 if (param_field[0] >= '0' && param_field[0] <= '9') {
2660 param.error("Unexpected array index in module parameter, expected a valid field"
2661 " name for %s type `%s'", is_set() ? "set" : "record", get_descriptor()->name);
2662 }
2663 int field_cnt = get_count();
2664 for (int field_idx = 0; field_idx < field_cnt; field_idx++) {
2665 if (strcmp(fld_name(field_idx), param_field) == 0) {
2666 get_at(field_idx)->set_param(param);
2667 return;
2668 }
2669 }
2670 param.error("Field `%s' not found in %s type `%s'",
2671 param_field, is_set() ? "set" : "record", get_descriptor()->name);
2672 }
2673
2674 param.basic_check(Module_Param::BC_VALUE, is_set()?"set value":"record value");
3abe9331 2675
2676 Module_Param_Ptr mp = &param;
2677 if (param.get_type() == Module_Param::MP_Reference) {
2678 mp = param.get_referenced_param();
2679 }
2680
2681 switch (mp->get_type()) {
970ed795 2682 case Module_Param::MP_Value_List:
3abe9331 2683 if (get_count()<(int)mp->get_size()) {
2684 param.error("%s value of type %s has %d fields but list value has %d fields", is_set()?"Set":"Record", get_descriptor()->name, get_count(), (int)mp->get_size());
970ed795 2685 }
3abe9331 2686 for (size_t i=0; i<mp->get_size(); i++) {
2687 Module_Param* mp_elem = mp->get_elem(i);
2688 if (mp_elem->get_type()!=Module_Param::MP_NotUsed) {
2689 get_at((int)i)->set_param(*mp_elem);
970ed795
EL
2690 }
2691 }
2692 break;
2693 case Module_Param::MP_Assignment_List:
3abe9331 2694 for (size_t i=0; i<mp->get_size(); ++i) {
2695 Module_Param* const current = mp->get_elem(i);
970ed795
EL
2696 bool found = false;
2697 for (int j=0; j<get_count(); ++j) {
2698 if (!strcmp(fld_name(j), current->get_id()->get_name())) {
2699 if (current->get_type()!=Module_Param::MP_NotUsed) {
2700 get_at(j)->set_param(*current);
2701 }
2702 found = true;
2703 break;
2704 }
2705 }
2706 if (!found) {
2707 current->error("Non existent field name in type %s: %s.", get_descriptor()->name, current->get_id()->get_name());
2708 }
2709 }
2710 break;
2711 default:
2712 param.type_error(is_set()?"set value":"record value", get_descriptor()->name);
2713 }
2714}
2715
3abe9331 2716Module_Param* Record_Type::get_param(Module_Param_Name& param_name) const
2717{
2718 if (!is_bound()) {
2719 return new Module_Param_Unbound();
2720 }
2721 if (param_name.next_name()) {
2722 // Haven't reached the end of the module parameter name
2723 // => the name refers to one of the fields, not to the whole record
2724 char* param_field = param_name.get_current_name();
2725 if (param_field[0] >= '0' && param_field[0] <= '9') {
2726 TTCN_error("Unexpected array index in module parameter reference, "
2727 "expected a valid field name for %s type `%s'",
2728 is_set() ? "set" : "record", get_descriptor()->name);
2729 }
2730 int field_cnt = get_count();
2731 for (int field_idx = 0; field_idx < field_cnt; field_idx++) {
2732 if (strcmp(fld_name(field_idx), param_field) == 0) {
2733 return get_at(field_idx)->get_param(param_name);
2734 }
2735 }
2736 TTCN_error("Field `%s' not found in %s type `%s'",
2737 param_field, is_set() ? "set" : "record", get_descriptor()->name);
2738 }
2739 Module_Param_Assignment_List* mp = new Module_Param_Assignment_List();
2740 for (int i = 0; i < get_count(); ++i) {
2741 Module_Param* mp_field = get_at(i)->get_param(param_name);
2742 mp_field->set_id(new Module_Param_FieldName(mcopystr(fld_name(i))));
2743 mp->add_elem(mp_field);
2744 }
2745 return mp;
2746}
2747
970ed795
EL
2748void Record_Type::set_implicit_omit()
2749{
2750 int field_cnt = get_count();
2751 for (int field_idx = 0; field_idx < field_cnt; field_idx++) {
2752 Base_Type *temp = get_at(field_idx);
2753 if (temp->is_optional()) {
2754 if (temp->is_bound()) temp->set_implicit_omit();
2755 else temp->set_to_omit();
2756 } else if (temp->is_bound()) {
2757 temp->set_implicit_omit();
2758 }
2759 }
2760}
2761
2762int Record_Type::size_of() const
2763{
970ed795
EL
2764 int opt_count = optional_count();
2765 if (opt_count==0) return get_count();
2766 const int* optional_indexes = get_optional_indexes();
2767 int my_size = get_count();
2768 for (int i=0; i<opt_count; i++) {
2769 if (!get_at(optional_indexes[i])->ispresent()) my_size--;
2770 }
2771 return my_size;
2772}
2773
2774void Record_Type::encode_text(Text_Buf& text_buf) const
2775{
2776 if (!is_bound()) {
2777 TTCN_error("Text encoder: Encoding an unbound record/set value of type %s.",
2778 get_descriptor()->name);
2779 }
2780 int field_cnt = get_count();
2781 for (int field_idx=0; field_idx<field_cnt; field_idx++)
2782 get_at(field_idx)->encode_text(text_buf);
2783}
2784
2785void Record_Type::decode_text(Text_Buf& text_buf)
2786{
970ed795
EL
2787 int field_cnt = get_count();
2788 for (int field_idx=0; field_idx<field_cnt; field_idx++)
2789 get_at(field_idx)->decode_text(text_buf);
2790}
2791
2792boolean Record_Type::is_equal(const Base_Type* other_value) const
2793{
2794 const Record_Type* other_record = static_cast<const Record_Type*>(other_value);
970ed795
EL
2795 int field_cnt = get_count();
2796 for (int field_idx=0; field_idx<field_cnt; field_idx++) {
2797 const Base_Type* elem = get_at(field_idx);
2798 const Base_Type* other_elem = other_record->get_at(field_idx);
2799 if (elem->is_bound()) {
2800 if (other_elem->is_bound()) {
2801 if (!elem->is_equal(other_elem))
2802 return FALSE;
2803 } else return FALSE;
2804 } else if (other_elem->is_bound()) return FALSE;
2805 }
2806 return TRUE;
2807}
2808
2809void Record_Type::set_value(const Base_Type* other_value)
2810{
2811 if (this==other_value) return;
2812 if (!other_value->is_bound())
2813 TTCN_error("Copying an unbound record/set value of type %s.",
2814 other_value->get_descriptor()->name);
2815 const Record_Type* other_record = static_cast<const Record_Type*>(other_value);
2816 int field_cnt = get_count();
2817 for (int field_idx=0; field_idx<field_cnt; field_idx++) {
2818 const Base_Type* elem = other_record->get_at(field_idx);
2819 if (elem->is_bound()) {
2820 get_at(field_idx)->set_value(elem);
2821 } else {
2822 get_at(field_idx)->clean_up();
2823 }
2824 }
2825 err_descr = other_record->err_descr;
970ed795
EL
2826}
2827
2828void Record_Type::encode(const TTCN_Typedescriptor_t& p_td,
2829 TTCN_Buffer& p_buf, TTCN_EncDec::coding_t p_coding, ...) const
2830{
2831 va_list pvar;
2832 va_start(pvar, p_coding);
2833 switch(p_coding) {
2834 case TTCN_EncDec::CT_BER: {
2835 TTCN_EncDec_ErrorContext ec("While BER-encoding type '%s': ", p_td.name);
2836 unsigned BER_coding=va_arg(pvar, unsigned);
2837 BER_encode_chk_coding(BER_coding);
2838 ASN_BER_TLV_t *tlv=BER_encode_TLV(p_td, BER_coding);
2839 tlv->put_in_buffer(p_buf);
2840 ASN_BER_TLV_t::destruct(tlv);
2841 break;}
2842 case TTCN_EncDec::CT_RAW: {
2843 TTCN_EncDec_ErrorContext ec("While RAW-encoding type '%s': ", p_td.name);
2844 if(!p_td.raw) TTCN_EncDec_ErrorContext::error_internal
2845 ("No RAW descriptor available for type '%s'.", p_td.name);
2846 RAW_enc_tr_pos rp;
2847 rp.level=0;
2848 rp.pos=NULL;
2849 RAW_enc_tree root(FALSE, NULL, &rp, 1, p_td.raw);
2850 RAW_encode(p_td, root);
2851 root.put_to_buf(p_buf);
2852 break;}
2853 case TTCN_EncDec::CT_TEXT: {
2854 TTCN_EncDec_ErrorContext ec("While TEXT-encoding type '%s': ", p_td.name);
2855 if(!p_td.text) TTCN_EncDec_ErrorContext::error_internal
2856 ("No TEXT descriptor available for type '%s'.", p_td.name);
2857 TEXT_encode(p_td,p_buf);
2858 break;}
2859 case TTCN_EncDec::CT_XER: {
2860 TTCN_EncDec_ErrorContext ec("While XER-encoding type '%s': ", p_td.name);
2861 unsigned XER_coding=va_arg(pvar, unsigned);
af710487 2862 XER_encode(*(p_td.xer),p_buf, XER_coding, 0, 0);
970ed795
EL
2863 p_buf.put_c('\n');
2864 break;}
2865 case TTCN_EncDec::CT_JSON: {
2866 TTCN_EncDec_ErrorContext ec("While JSON-encoding type '%s': ", p_td.name);
2867 if(!p_td.json) TTCN_EncDec_ErrorContext::error_internal
2868 ("No JSON descriptor available for type '%s'.", p_td.name);
2869 JSON_Tokenizer tok(va_arg(pvar, int) != 0);
2870 JSON_encode(p_td, tok);
2871 p_buf.put_s(tok.get_buffer_length(), (const unsigned char*)tok.get_buffer());
2872 break;}
2873 default:
2874 TTCN_error("Unknown coding method requested to encode type '%s'", p_td.name);
2875 }
2876 va_end(pvar);
2877}
2878
2879void Record_Type::decode(const TTCN_Typedescriptor_t& p_td,
2880 TTCN_Buffer& p_buf, TTCN_EncDec::coding_t p_coding, ...)
2881{
2882 va_list pvar;
2883 va_start(pvar, p_coding);
2884 switch(p_coding) {
2885 case TTCN_EncDec::CT_BER: {
2886 TTCN_EncDec_ErrorContext ec("While BER-decoding type '%s': ", p_td.name);
2887 unsigned L_form=va_arg(pvar, unsigned);
2888 ASN_BER_TLV_t tlv;
2889 BER_decode_str2TLV(p_buf, tlv, L_form);
2890 BER_decode_TLV(p_td, tlv, L_form);
2891 if(tlv.isComplete) p_buf.increase_pos(tlv.get_len());
2892 break;}
2893 case TTCN_EncDec::CT_RAW: {
2894 TTCN_EncDec_ErrorContext ec("While RAW-decoding type '%s': ", p_td.name);
2895 if(!p_td.raw)
2896 TTCN_EncDec_ErrorContext::error_internal
2897 ("No RAW descriptor available for type '%s'.", p_td.name);
2898 raw_order_t order;
2899 switch(p_td.raw->top_bit_order) {
2900 case TOP_BIT_LEFT:
2901 order=ORDER_LSB;
2902 break;
2903 case TOP_BIT_RIGHT:
2904 default:
2905 order=ORDER_MSB;
2906 }
2907 int rawr = RAW_decode(p_td, p_buf, p_buf.get_len()*8, order);
2908 if (rawr < 0) switch (-rawr) {
2909 case TTCN_EncDec::ET_INCOMPL_MSG:
2910 case TTCN_EncDec::ET_LEN_ERR:
2911 ec.error(TTCN_EncDec::ET_INCOMPL_MSG,
2912 "Can not decode type '%s', because incomplete"
2913 " message was received", p_td.name);
2914 break;
2915 case 1:
2916 // The RAW/TEXT decoders return -1 for anything not a length error.
2917 // This is the value for ET_UNBOUND, which can't happen in decoding.
2918 default:
2919 ec.error(TTCN_EncDec::ET_INVAL_MSG,
2920 "Can not decode type '%s', because invalid"
2921 " message was received", p_td.name);
2922 break;
2923 }
2924 break;}
2925 case TTCN_EncDec::CT_TEXT: {
2926 Limit_Token_List limit;
2927 TTCN_EncDec_ErrorContext ec("While TEXT-decoding type '%s': ", p_td.name);
2928 if(!p_td.text) TTCN_EncDec_ErrorContext::error_internal
2929 ("No TEXT descriptor available for type '%s'.", p_td.name);
2930 const unsigned char *b=p_buf.get_data();
2931 if(b[p_buf.get_len()-1]!='\0'){
2932 p_buf.set_pos(p_buf.get_len());
2933 p_buf.put_zero(8,ORDER_LSB);
2934 p_buf.rewind();
2935 }
2936 if(TEXT_decode(p_td,p_buf,limit)<0)
2937 ec.error(TTCN_EncDec::ET_INCOMPL_MSG,
2938 "Can not decode type '%s', because invalid or incomplete"
2939 " message was received", p_td.name);
2940 break;}
2941 case TTCN_EncDec::CT_XER: {
2942 TTCN_EncDec_ErrorContext ec("While XER-decoding type '%s': ", p_td.name);
2943 unsigned XER_coding=va_arg(pvar, unsigned);
2944 XmlReaderWrap reader(p_buf);
2945 for (int success=reader.Read(); success==1; success=reader.Read()) {
2946 if (reader.NodeType() == XML_READER_TYPE_ELEMENT) break;
2947 }
feade998 2948 XER_decode(*(p_td.xer), reader, XER_coding | XER_TOPLEVEL, XER_NONE, 0);
970ed795
EL
2949 size_t bytes = reader.ByteConsumed();
2950 p_buf.set_pos(bytes);
2951 break;}
2952 case TTCN_EncDec::CT_JSON: {
2953 TTCN_EncDec_ErrorContext ec("While JSON-decoding type '%s': ", p_td.name);
2954 if(!p_td.json) TTCN_EncDec_ErrorContext::error_internal
2955 ("No JSON descriptor available for type '%s'.", p_td.name);
2956 JSON_Tokenizer tok((const char*)p_buf.get_data(), p_buf.get_len());
2957 if(JSON_decode(p_td, tok, false)<0)
2958 ec.error(TTCN_EncDec::ET_INCOMPL_MSG,
2959 "Can not decode type '%s', because invalid or incomplete"
2960 " message was received", p_td.name);
2961 p_buf.set_pos(tok.get_buf_pos());
2962 break;}
2963 default:
2964 TTCN_error("Unknown coding method requested to decode type '%s'", p_td.name);
2965 }
2966 va_end(pvar);
2967}
2968
2969ASN_BER_TLV_t* Record_Type::BER_encode_TLV(const TTCN_Typedescriptor_t& p_td, unsigned p_coding) const
2970{
2971 if (err_descr) {
2972 return BER_encode_TLV_negtest(err_descr, p_td, p_coding);
2973 }
2974 if (!is_bound()) {
2975 TTCN_EncDec_ErrorContext::error
2976 (TTCN_EncDec::ET_UNBOUND, "Encoding an unbound value.");
2977 }
2978 BER_chk_descr(p_td);
2979 ASN_BER_TLV_t *new_tlv=ASN_BER_TLV_t::construct(NULL);
2980 TTCN_EncDec_ErrorContext ec_0("Component '");
2981 TTCN_EncDec_ErrorContext ec_1;
2982 int next_default_idx = 0;
2983 const default_struct* default_indexes = get_default_indexes();
2984 int field_cnt = get_count();
2985 for(int i=0; i<field_cnt; i++) {
2986 boolean is_default_field = default_indexes && (default_indexes[next_default_idx].index==i);
2987 if (!default_as_optional() && is_default_field) {
2988 if (!get_at(i)->is_equal(default_indexes[next_default_idx].value)) {
2989 ec_1.set_msg("%s': ", fld_name(i));
2990 new_tlv->add_TLV(get_at(i)->BER_encode_TLV(*fld_descr(i), p_coding));
2991 }
2992 } else { /* is not DEFAULT */
2993 ec_1.set_msg("%s': ", fld_name(i));
2994 new_tlv->add_TLV(get_at(i)->BER_encode_TLV(*fld_descr(i), p_coding));
2995 } /* !isDefault */
2996 if (is_default_field) next_default_idx++;
2997 } /* for i */
2998 if (is_set())
2999 if (p_coding==BER_ENCODE_DER) new_tlv->sort_tlvs_tag();
3000 new_tlv=ASN_BER_V2TLV(new_tlv, p_td, p_coding);
3001 return new_tlv;
3002}
3003
3004ASN_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
3005{
3006 if (!is_bound()) {
3007 TTCN_EncDec_ErrorContext::error
3008 (TTCN_EncDec::ET_UNBOUND, "Encoding an unbound value.");
3009 }
3010 BER_chk_descr(p_td);
3011 ASN_BER_TLV_t *new_tlv=ASN_BER_TLV_t::construct(NULL);
3012 TTCN_EncDec_ErrorContext ec_0("Component '");
3013 TTCN_EncDec_ErrorContext ec_1;
3014 int next_default_idx = 0;
3015 const default_struct* default_indexes = get_default_indexes();
3016 int field_cnt = get_count();
3017
3018 int values_idx = 0;
3019 int edescr_idx = 0;
3020
3021 for (int i=0; i<field_cnt; i++) {
3022 boolean is_default_field = default_indexes && (default_indexes[next_default_idx].index==i);
3023 // the first condition is not needed, kept for ease of understanding
3024 if ( (p_err_descr->omit_before!=-1) && (i<p_err_descr->omit_before) ) {
3025 if (is_default_field) next_default_idx++;
3026 continue;
3027 }
3028 const Erroneous_values_t* err_vals = p_err_descr->next_field_err_values(i, values_idx);
3029 const Erroneous_descriptor_t* emb_descr = p_err_descr->next_field_emb_descr(i, edescr_idx);
3030
3031 if (err_vals && err_vals->before) {
3032 if (err_vals->before->errval==NULL) TTCN_error(
3033 "internal error: erroneous before value missing");
3034 ec_1.set_msg("%s'(erroneous before): ", fld_name(i));
3035 if (err_vals->before->raw) {
3036 new_tlv->add_TLV(err_vals->before->errval->BER_encode_negtest_raw());
3037 } else {
3038 if (err_vals->before->type_descr==NULL) TTCN_error(
3039 "internal error: erroneous before typedescriptor missing");
3040 new_tlv->add_TLV(err_vals->before->errval->BER_encode_TLV(
3041 *err_vals->before->type_descr, p_coding));
3042 }
3043 }
3044
3045 if (err_vals && err_vals->value) {
3046 if (err_vals->value->errval) { // replace
3047 ec_1.set_msg("%s'(erroneous value): ", fld_name(i));
3048 if (err_vals->value->raw) {
3049 new_tlv->add_TLV(err_vals->value->errval->BER_encode_negtest_raw());
3050 } else {
3051 if (err_vals->value->type_descr==NULL) TTCN_error(
3052 "internal error: erroneous value typedescriptor missing");
3053 new_tlv->add_TLV(err_vals->value->errval->BER_encode_TLV(
3054 *err_vals->value->type_descr, p_coding));
3055 }
3056 } // else -> omit
3057 } else {
3058 if (!default_as_optional() && is_default_field) {
3059 if (!get_at(i)->is_equal(default_indexes[next_default_idx].value)) {
3060 ec_1.set_msg("'%s': ", fld_name(i));
3061 if (emb_descr) {
3062 new_tlv->add_TLV(get_at(i)->BER_encode_TLV_negtest(emb_descr,
3063 *fld_descr(i), p_coding));
3064 } else {
3065 new_tlv->add_TLV(get_at(i)->BER_encode_TLV(*fld_descr(i), p_coding));
3066 }
3067 }
3068 } else { /* is not DEFAULT */
3069 ec_1.set_msg("'%s': ", fld_name(i));
3070 if (emb_descr) {
3071 new_tlv->add_TLV(get_at(i)->BER_encode_TLV_negtest(emb_descr,
3072 *fld_descr(i), p_coding));
3073 } else {
3074 new_tlv->add_TLV(get_at(i)->BER_encode_TLV(*fld_descr(i), p_coding));
3075 }
3076 } /* !isDefault */
3077 }
3078
3079 if (err_vals && err_vals->after) {
3080 if (err_vals->after->errval==NULL) TTCN_error(
3081 "internal error: erroneous after value missing");
3082 ec_1.set_msg("%s'(erroneous after): ", fld_name(i));
3083 if (err_vals->after->raw) {
3084 new_tlv->add_TLV(err_vals->after->errval->BER_encode_negtest_raw());
3085 } else {
3086 if (err_vals->after->type_descr==NULL) TTCN_error(
3087 "internal error: erroneous after typedescriptor missing");
3088 new_tlv->add_TLV(err_vals->after->errval->BER_encode_TLV(
3089 *err_vals->after->type_descr, p_coding));
3090 }
3091 }
3092
3093 if (is_default_field) next_default_idx++;
3094 if ( (p_err_descr->omit_after!=-1) && (i>=p_err_descr->omit_after) ) break;
3095 } /* for i */
3096
3097 if (is_set())
3098 if (p_coding==BER_ENCODE_DER) new_tlv->sort_tlvs_tag();
3099 new_tlv=ASN_BER_V2TLV(new_tlv, p_td, p_coding);
3100 return new_tlv;
3101}
3102
3103boolean Record_Type::BER_decode_TLV(const TTCN_Typedescriptor_t& p_td,
3104 const ASN_BER_TLV_t& p_tlv, unsigned L_form)
3105{
970ed795
EL
3106 BER_chk_descr(p_td);
3107 ASN_BER_TLV_t stripped_tlv;
3108 BER_decode_strip_tags(*p_td.ber, p_tlv, L_form, stripped_tlv);
3109 TTCN_EncDec_ErrorContext ec_0("While decoding '%s' type: ", get_descriptor()->name);
3110 stripped_tlv.chk_constructed_flag(TRUE);
3111 size_t V_pos=0;
3112 ASN_BER_TLV_t tmp_tlv;
3113 if (!is_set())
3114 { /* SEQUENCE decoding */
3115 boolean tlv_present=FALSE;
3116 {
3117 TTCN_EncDec_ErrorContext ec_1("Component '");
3118 TTCN_EncDec_ErrorContext ec_2;
3119 int next_default_idx = 0;
3120 int next_optional_idx = 0;
3121 const default_struct* default_indexes = get_default_indexes();
3122 const int* optional_indexes = get_optional_indexes();
3123 int field_cnt = get_count();
3124 for(int i=0; i<field_cnt; i++) {
3125 boolean is_default_field = default_indexes && (default_indexes[next_default_idx].index==i);
3126 boolean is_optional_field = optional_indexes && (optional_indexes[next_optional_idx]==i);
3127 ec_2.set_msg("%s': ", fld_descr(i)->name);
3128 if (!tlv_present) tlv_present=BER_decode_constdTLV_next(stripped_tlv, V_pos, L_form, tmp_tlv);
3129 if (is_default_field) { /* is DEFAULT */
3130 if (!tlv_present || !get_at(i)->BER_decode_isMyMsg(*fld_descr(i), tmp_tlv)) {
3131 get_at(i)->set_value(default_indexes[next_default_idx].value);
3132 } else {
3133 get_at(i)->BER_decode_TLV(*fld_descr(i), tmp_tlv, L_form);
3134 tlv_present=FALSE;
3135 }
3136 }
3137 else if (is_optional_field) { /* is OPTIONAL */
3138 if (!tlv_present) get_at(i)->set_to_omit();
3139 else {
3140 get_at(i)->BER_decode_TLV(*fld_descr(i), tmp_tlv, L_form);
3141 if (get_at(i)->ispresent()) tlv_present=FALSE;
3142 }
3143 }
3144 else { /* is not DEFAULT OPTIONAL */
3145 if(!tlv_present){
3146 ec_2.error(TTCN_EncDec::ET_INCOMPL_MSG,"Invalid or incomplete message was received.");
3147 return FALSE;
3148 }
3149 get_at(i)->BER_decode_TLV(*fld_descr(i), tmp_tlv, L_form);
3150 tlv_present=FALSE;
3151 } /* !isDefault */
3152 if (is_default_field) next_default_idx++;
3153 if (is_optional_field) next_optional_idx++;
3154 } /* for i */
3155 }
3156 BER_decode_constdTLV_end(stripped_tlv, V_pos, L_form, tmp_tlv, tlv_present);
3157 } /* SEQUENCE decoding */
3158 else
3159 { /* SET decoding */
3160 /* field indicator:
3161 * 0x01: value arrived
3162 * 0x02: is optional / not used :)
3163 * 0x04: has default / not used :)
3164 */
3165 int field_cnt = get_count();
3166 unsigned char* fld_indctr = new unsigned char[field_cnt];
3167 for (int i=0; i<field_cnt; i++) fld_indctr[i] = 0;
3168 int fld_curr = -1; /* ellipsis or error... */
3169 while (BER_decode_constdTLV_next(stripped_tlv, V_pos, L_form, tmp_tlv)) {
3170 for (int i=0; i<field_cnt; i++) {
3171 if (get_at(i)->BER_decode_isMyMsg(*fld_descr(i), tmp_tlv)) {
3172 fld_curr=i;
3173 TTCN_EncDec_ErrorContext ec_1("Component '%s': ", fld_name(i));
3174 get_at(i)->BER_decode_TLV(*fld_descr(i), tmp_tlv, L_form);
3175 break;
3176 }
3177 }
3178 if (fld_curr!=-1) {
3179 if (fld_indctr[fld_curr])
3180 ec_0.error(TTCN_EncDec::ET_DEC_DUPFLD, "Duplicated value for component '%s'.", fld_name(fld_curr));
3181 fld_indctr[fld_curr]=1;
3182 } /* if != -1 */
3183 } /* while */
3184 int next_default_idx = 0;
3185 int next_optional_idx = 0;
3186 const default_struct* default_indexes = get_default_indexes();
3187 const int* optional_indexes = get_optional_indexes();
3188 for (fld_curr=0; fld_curr<field_cnt; fld_curr++) {
3189 boolean is_default_field = default_indexes && (default_indexes[next_default_idx].index==fld_curr);
3190 boolean is_optional_field = optional_indexes && (optional_indexes[next_optional_idx]==fld_curr);
3191 if (!fld_indctr[fld_curr]) {
3192 if (is_default_field) get_at(fld_curr)->set_value(default_indexes[next_default_idx].value);
3193 else if (is_optional_field) get_at(fld_curr)->set_to_omit();
3194 else ec_0.error(TTCN_EncDec::ET_DEC_MISSFLD, "Missing value for component '%s'.", fld_name(fld_curr));
3195 }
3196 if (is_default_field) next_default_idx++;
3197 if (is_optional_field) next_optional_idx++;
3198 }
3199 delete[] fld_indctr;
3200 } /* SET decoding */
3201
3202 if (is_opentype_outermost()) {
3203 TTCN_EncDec_ErrorContext ec_1("While decoding opentypes: ");
3204 TTCN_Type_list p_typelist;
3205 BER_decode_opentypes(p_typelist, L_form);
3206 } /* if sdef->opentype_outermost */
3207 return TRUE;
3208}
3209
3210void Record_Type::BER_decode_opentypes(TTCN_Type_list& p_typelist, unsigned L_form)
3211{
970ed795
EL
3212 p_typelist.push(this);
3213 TTCN_EncDec_ErrorContext ec_0("Component '");
3214 TTCN_EncDec_ErrorContext ec_1;
3215 int field_cnt = get_count();
3216 for(int i=0; i<field_cnt; i++) {
3217 ec_1.set_msg("%s': ", fld_name(i));
3218 get_at(i)->BER_decode_opentypes(p_typelist, L_form);
3219 } /* for i */
3220 p_typelist.pop();
3221}
3222
3223int Record_Type::RAW_encode(const TTCN_Typedescriptor_t& p_td,
3224 RAW_enc_tree& myleaf) const
3225{
3226 if (err_descr) return RAW_encode_negtest(err_descr, p_td, myleaf);
3227 if (!is_bound()) {
3228 TTCN_EncDec_ErrorContext::error
3229 (TTCN_EncDec::ET_UNBOUND, "Encoding an unbound value.");
3230 }
3231 int encoded_length = 0;
3232 int field_cnt = get_count();
3233 myleaf.isleaf = false;
3234 myleaf.body.node.num_of_nodes = field_cnt;
3235 myleaf.body.node.nodes = init_nodes_of_enc_tree(field_cnt);
3236 /* init nodes */
3237 int next_optional_idx = 0;
3238 const int* optional_indexes = get_optional_indexes();
3239 for (int i = 0; i < field_cnt; i++) {
3240 boolean is_optional_field = optional_indexes
3241 && (optional_indexes[next_optional_idx] == i);
3242 if (!is_optional_field || get_at(i)->ispresent()) {
3243 myleaf.body.node.nodes[i] = new RAW_enc_tree(true, &myleaf,
3244 &(myleaf.curr_pos), i, fld_descr(i)->raw);
3245 }
3246 else {
3247 myleaf.body.node.nodes[i] = NULL;
3248 }
3249 if (is_optional_field) next_optional_idx++;
3250 }
3251 next_optional_idx = 0;
3252 for (int i = 0; i < field_cnt; i++) { /*encoding fields*/
3253 boolean is_optional_field = optional_indexes
3254 && (optional_indexes[next_optional_idx] == i);
3255 /* encoding of normal fields*/
3256 const Base_Type *field = get_at(i);
3257 if (is_optional_field) {
3258 next_optional_idx++;
3259 if (!field->ispresent())
3260 continue; // do not encode
3261 else
3262 field = field->get_opt_value(); // "reach into" the optional
3263 }
3264 encoded_length += field->RAW_encode(*fld_descr(i),
3265 *myleaf.body.node.nodes[i]);
3266 }
3267 return myleaf.length = encoded_length;
3268}
3269
3270// In some cases (e.g. LENGTHTO, POINTERTO, CROSSTAG) it is not generated.
3271int Record_Type::RAW_encode_negtest(const Erroneous_descriptor_t *p_err_descr,
3272 const TTCN_Typedescriptor_t& /*p_td*/, RAW_enc_tree& myleaf) const
3273{
3274 if (!is_bound()) {
3275 TTCN_EncDec_ErrorContext::error
3276 (TTCN_EncDec::ET_UNBOUND, "Encoding an unbound value.");
3277 }
3278 int encoded_length = 0;
3279 int num_fields = get_count();
3280 myleaf.isleaf = false;
3281 myleaf.body.node.num_of_nodes = 0;
3282 for (int field_idx = 0; field_idx < num_fields; ++field_idx) {
3283 if ((p_err_descr->omit_before != -1) &&
3284 (field_idx < p_err_descr->omit_before))
3285 continue;
3286 else ++myleaf.body.node.num_of_nodes;
3287 const Erroneous_values_t *err_vals = p_err_descr->get_field_err_values(field_idx);
3288 if (err_vals && err_vals->before)
3289 ++myleaf.body.node.num_of_nodes;
3290 if (err_vals && err_vals->value && !err_vals->value->errval)
3291 --myleaf.body.node.num_of_nodes;
3292 if (err_vals && err_vals->after)
3293 ++myleaf.body.node.num_of_nodes;
3294 if ((p_err_descr->omit_after != -1) &&
3295 (field_idx >= p_err_descr->omit_after))
3296 break;
3297 }
3298 myleaf.body.node.nodes = init_nodes_of_enc_tree(myleaf.body.node.num_of_nodes);
3299 TTCN_EncDec_ErrorContext ec;
3300 int next_optional_idx = 0;
3301 const int *my_optional_indexes = get_optional_indexes();
3302 // Counter for fields and additional before/after fields.
3303 int node_pos = 0;
3304 for (int field_idx = 0; field_idx < num_fields; ++field_idx) {
3305 boolean is_optional_field = my_optional_indexes &&
3306 (my_optional_indexes[next_optional_idx] == field_idx);
3307 if ((p_err_descr->omit_before != -1) &&
3308 (field_idx < p_err_descr->omit_before)) {
3309 if (is_optional_field) ++next_optional_idx;
3310 continue;
3311 }
3312 const Erroneous_values_t *err_vals = p_err_descr->get_field_err_values(field_idx);
3313 const Erroneous_descriptor_t *emb_descr = p_err_descr->get_field_emb_descr(field_idx);
3314 if (err_vals && err_vals->before) {
3315 if (err_vals->before->errval == NULL)
3316 TTCN_error("internal error: erroneous before value missing");
3317 if (err_vals->before->raw) {
3318 myleaf.body.node.nodes[node_pos] =
3319 new RAW_enc_tree(true, &myleaf, &(myleaf.curr_pos), node_pos,
3320 err_vals->before->errval->get_descriptor()->raw);
3321 encoded_length += err_vals->before->errval->
3322 RAW_encode_negtest_raw(*myleaf.body.node.nodes[node_pos++]);
3323 } else {
3324 if (err_vals->before->type_descr == NULL)
3325 TTCN_error("internal error: erroneous before typedescriptor missing");
3326 myleaf.body.node.nodes[node_pos] =
3327 new RAW_enc_tree(true, &myleaf, &(myleaf.curr_pos), node_pos,
3328 err_vals->before->type_descr->raw);
3329 encoded_length += err_vals->before->errval->
3330 RAW_encode(*(err_vals->before->type_descr),
3331 *myleaf.body.node.nodes[node_pos++]);
3332 }
3333 }
3334 if (err_vals && err_vals->value) {
3335 if (err_vals->value->errval) {
3336 ec.set_msg("'%s'(erroneous value): ", fld_name(field_idx));
3337 if (err_vals->value->raw) {
3338 myleaf.body.node.nodes[node_pos] =
3339 new RAW_enc_tree(true, &myleaf, &(myleaf.curr_pos), node_pos,
3340 err_vals->value->errval->get_descriptor()->raw);
3341 encoded_length += err_vals->value->errval->
3342 RAW_encode_negtest_raw(*myleaf.body.node.nodes[node_pos++]);
3343 } else {
3344 if (err_vals->value->type_descr == NULL)
3345 TTCN_error("internal error: erroneous value typedescriptor missing");
3346 myleaf.body.node.nodes[node_pos] =
3347 new RAW_enc_tree(true, &myleaf, &(myleaf.curr_pos), node_pos,
3348 err_vals->value->type_descr->raw);
3349 encoded_length += err_vals->value->errval->
3350 RAW_encode(*(err_vals->value->type_descr),
3351 *myleaf.body.node.nodes[node_pos++]);
3352 }
3353 }
3354 } else {
3355 ec.set_msg("'%s': ", fld_name(field_idx));
3356 if (!is_optional_field || get_at(field_idx)->ispresent()) {
3357 const Base_Type *field =
3358 is_optional_field ? get_at(field_idx)->get_opt_value()
3359 : get_at(field_idx);
3360 myleaf.body.node.nodes[node_pos] =
3361 new RAW_enc_tree(true, &myleaf, &(myleaf.curr_pos), node_pos,
3362 fld_descr(field_idx)->raw);
3363 if (emb_descr) {
3364 encoded_length +=
3365 field->RAW_encode_negtest(emb_descr, *fld_descr(field_idx),
3366 *myleaf.body.node.nodes[node_pos++]);
3367 } else {
3368 encoded_length +=
3369 field->RAW_encode(*fld_descr(field_idx),
3370 *myleaf.body.node.nodes[node_pos++]);
3371 }
3372 } else {
3373 // `omitted' field.
3374 myleaf.body.node.nodes[node_pos++] = NULL;
3375 }
3376 }
3377 if (err_vals && err_vals->after) {
3378 if (err_vals->after->errval == NULL)
3379 TTCN_error("internal error: erroneous before value missing");
3380 if (err_vals->after->raw) {
3381 myleaf.body.node.nodes[node_pos] =
3382 new RAW_enc_tree(true, &myleaf, &(myleaf.curr_pos), node_pos,
3383 err_vals->after->errval->get_descriptor()->raw);
3384 encoded_length += err_vals->after->errval->
3385 RAW_encode_negtest_raw(*myleaf.body.node.nodes[node_pos++]);
3386 } else {
3387 if (err_vals->after->type_descr == NULL)
3388 TTCN_error("internal error: erroneous after typedescriptor missing");
3389 myleaf.body.node.nodes[node_pos] =
3390 new RAW_enc_tree(true, &myleaf, &(myleaf.curr_pos), node_pos,
3391 err_vals->after->type_descr->raw);
3392 encoded_length += err_vals->after->errval->
3393 RAW_encode(*(err_vals->after->type_descr),
3394 *myleaf.body.node.nodes[node_pos++]);
3395 }
3396 }
3397 if (is_optional_field) ++next_optional_idx;
3398 if ((p_err_descr->omit_after != -1) &&
3399 (field_idx >= p_err_descr->omit_after))
3400 break;
3401 }
3402 return myleaf.length = encoded_length;
3403}
3404
3405int Record_Type::RAW_decode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& buff,
3406 int limit, raw_order_t top_bit_ord, boolean no_err, int, boolean)
3407{
970ed795
EL
3408 int field_cnt = get_count();
3409 int opt_cnt = optional_count();
3410 int mand_num = field_cnt - opt_cnt; // expected mandatory fields
3411
3412 raw_order_t local_top_order;
3413 if (p_td.raw->top_bit_order == TOP_BIT_INHERITED) local_top_order = top_bit_ord;
3414 else if (p_td.raw->top_bit_order == TOP_BIT_RIGHT) local_top_order = ORDER_MSB;
3415 else local_top_order = ORDER_LSB;
3416
3417 if (is_set()) { /* set decoder start*/
3418 int prepaddlength = buff.increase_pos_padd(p_td.raw->prepadding);
3419 limit -= prepaddlength;
3420 int decoded_length = 0;
3421 int * const field_map = new int[field_cnt];
3422 memset(field_map, 0, field_cnt * sizeof(int));
3423 int nof_mand_fields = 0; // mandatory fields actually decoded
3424 if (opt_cnt>0) {
3425 const int* optional_indexes = get_optional_indexes();
3426 for (int i=0; i<opt_cnt; i++) get_at(optional_indexes[i])->set_to_omit();
3427 }
3428 while (limit > 0) {
3429 size_t fl_start_pos = buff.get_pos_bit();
3430 int next_optional_idx = 0;
3431 const int* optional_indexes = get_optional_indexes();
3432 for (int i=0; i<field_cnt; i++) { /* decoding fields without TAG */
3433 boolean is_optional_field = optional_indexes && (optional_indexes[next_optional_idx]==i);
3434 if (field_map[i] == 0) {
3435 Base_Type* field_ptr = get_at(i);
3436 if (is_optional_field) {
3437 field_ptr->set_to_present();
3438 field_ptr=field_ptr->get_opt_value();
3439 }
3440 int decoded_field_length = field_ptr->RAW_decode(*fld_descr(i), buff,
3441 limit, local_top_order, TRUE);
3442 if ( (is_optional_field && (decoded_field_length>0)) ||
3443 (!is_optional_field && (decoded_field_length>=0)) ) {
3444 decoded_length += decoded_field_length;
3445 limit -= decoded_field_length;
3446 if (!is_optional_field) nof_mand_fields++;
3447 field_map[i] = 1;
3448 goto continue_while;
3449 } else {
3450 buff.set_pos_bit(fl_start_pos);
3451 if (is_optional_field) get_at(i)->set_to_omit();
3452 }
3453 }
3454 if (is_optional_field) next_optional_idx++;
3455 }//for i
3456 break; // no field could be decoded successfully, quit
3457continue_while: ;
3458 }
3459 delete[] field_map;
3460 if (mand_num > 0 && nof_mand_fields != mand_num) {
3461 /* Not all required fields were decoded. If there are no bits left,
3462 * that means that the last field was decoded successfully but used up
3463 * the buffer. Signal "incomplete". If there were bits left, that means
3464 * no field could be decoded from them; signal an error. */
3465 return limit ? -1 : -TTCN_EncDec::ET_INCOMPL_MSG;
3466 }
3467 return decoded_length + prepaddlength + buff.increase_pos_padd(p_td.raw->padding);
3468 } else { /* record decoder start */
3469 int prepaddlength = buff.increase_pos_padd(p_td.raw->prepadding);
3470 limit -= prepaddlength;
3471 size_t last_decoded_pos = buff.get_pos_bit();
3472 size_t fl_start_pos;
3473 int decoded_length = 0;
3474 int decoded_field_length = 0;
3475 if (raw_has_ext_bit()) {
3476 const unsigned char* data=buff.get_read_data();
3477 int count=1;
3478 unsigned mask = 1 << (local_top_order==ORDER_LSB ? 0 : 7);
3479 if (p_td.raw->extension_bit==EXT_BIT_YES) {
3480 while((data[count-1] & mask) == 0 && count * 8 < (int)limit) count++;
3481 }
3482 else {
3483 while((data[count-1] & mask) != 0 && count * 8 < (int)limit) count++;
3484 }
3485 if(limit) limit=count*8;
3486 }
3487
3488 int next_optional_idx = 0;
3489 const int* optional_indexes = get_optional_indexes();
3490 for (int i=0; i<field_cnt; i++) { /* decoding fields */
3491 boolean is_optional_field = optional_indexes && (optional_indexes[next_optional_idx]==i);
3492 /* check if enough bits to decode the field*/
3493 if (!is_optional_field || (limit>0)) {
3494 /* decoding of normal field */
3495 fl_start_pos = buff.get_pos_bit();
3496 Base_Type* field_ptr = get_at(i);
3497 if (is_optional_field) {
3498 field_ptr->set_to_present();
3499 field_ptr=field_ptr->get_opt_value();
3500 }
3501 decoded_field_length = field_ptr->RAW_decode(*fld_descr(i), buff, limit,
3502 local_top_order, is_optional_field ? TRUE : no_err);
3503 boolean field_present = TRUE;
3504 if (is_optional_field) {
3505 if (decoded_field_length < 1) { // swallow any error and become omit
3506 field_present = FALSE;
3507 get_at(i)->set_to_omit();
3508 buff.set_pos_bit(fl_start_pos);
3509 }
3510 } else {
3511 if (decoded_field_length < 0) return decoded_field_length;
3512 }
3513 if (field_present) {
3514 decoded_length+=decoded_field_length;
3515 limit-=decoded_field_length;
3516 last_decoded_pos=last_decoded_pos<buff.get_pos_bit()?buff.get_pos_bit():last_decoded_pos;
3517 }
3518 } else {
3519 get_at(i)->set_to_omit();
3520 }
3521 if (is_optional_field) next_optional_idx++;
3522 } /* decoding fields*/
3523
3524 buff.set_pos_bit(last_decoded_pos);
3525 return decoded_length+prepaddlength+buff.increase_pos_padd(p_td.raw->padding);
3526 } /* record decoder end*/
3527}
3528
3529int Record_Type::TEXT_encode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& buff) const
3530{
3531 if (err_descr) {
3532 return TEXT_encode_negtest(err_descr, p_td, buff);
3533 }
3534 if (!is_bound()) {
3535 TTCN_EncDec_ErrorContext::error
3536 (TTCN_EncDec::ET_UNBOUND, "Encoding an unbound value.");
3537 }
3538 bool need_separator=false;
3539 int encoded_length=0;
3540 if (p_td.text->begin_encode) {
3541 buff.put_cs(*p_td.text->begin_encode);
3542 encoded_length+=p_td.text->begin_encode->lengthof();
3543 }
3544 int next_optional_idx = 0;
3545 const int* optional_indexes = get_optional_indexes();
3546 int field_cnt = get_count();
3547 for(int i=0;i<field_cnt;i++) {
3548 boolean is_optional_field = optional_indexes && (optional_indexes[next_optional_idx]==i);
3549 if (!is_optional_field || get_at(i)->ispresent()) {
3550 if (need_separator && p_td.text->separator_encode) {
3551 buff.put_cs(*p_td.text->separator_encode);
3552 encoded_length+=p_td.text->separator_encode->lengthof();
3553 }
3554 encoded_length += get_at(i)->TEXT_encode(*fld_descr(i),buff);
3555 need_separator=true;
3556 }
3557 if (is_optional_field) next_optional_idx++;
3558 }
3559 if (p_td.text->end_encode) {
3560 buff.put_cs(*p_td.text->end_encode);
3561 encoded_length+=p_td.text->end_encode->lengthof();
3562 }
3563 return encoded_length;
3564}
3565
3566/**
3567 * TEXT encode negative testing
3568 */
3569int Record_Type::TEXT_encode_negtest(const Erroneous_descriptor_t* p_err_descr, const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& buff) const
3570{
3571 if (!is_bound()) {
3572 TTCN_EncDec_ErrorContext::error
3573 (TTCN_EncDec::ET_UNBOUND, "Encoding an unbound value.");
3574 }
3575 bool need_separator=false;
3576 int encoded_length=0;
3577 if (p_td.text->begin_encode) {
3578 buff.put_cs(*p_td.text->begin_encode);
3579 encoded_length+=p_td.text->begin_encode->lengthof();
3580 }
3581 int next_optional_idx = 0;
3582 const int* optional_indexes = get_optional_indexes();
3583 int field_cnt = get_count();
3584
3585 int values_idx = 0;
3586 int edescr_idx = 0;
3587
3588 for(int i=0;i<field_cnt;i++) {
3589 boolean is_optional_field = optional_indexes && (optional_indexes[next_optional_idx]==i);
3590
3591 if ( (p_err_descr->omit_before!=-1) && (i<p_err_descr->omit_before) ) {
3592 if (is_optional_field) next_optional_idx++;
3593 continue;
3594 }
3595
3596 const Erroneous_values_t* err_vals = p_err_descr->next_field_err_values(i, values_idx);
3597 const Erroneous_descriptor_t* emb_descr = p_err_descr->next_field_emb_descr(i, edescr_idx);
3598
3599 if (err_vals && err_vals->before) {
3600 if (err_vals->before->errval==NULL) TTCN_error(
3601 "internal error: erroneous before value missing");
3602
3603 if (need_separator && p_td.text->separator_encode) {
3604 buff.put_cs(*p_td.text->separator_encode);
3605 encoded_length+=p_td.text->separator_encode->lengthof();
3606 }
3607 if (err_vals->before->raw) {
3608 encoded_length += err_vals->before->errval->encode_raw(buff);
3609 } else {
3610 if (err_vals->before->type_descr==NULL) TTCN_error(
3611 "internal error: erroneous before typedescriptor missing");
3612 encoded_length += err_vals->before->errval->TEXT_encode(
3613 *(err_vals->before->type_descr),buff);
3614 }
3615 need_separator=true;
3616 }
3617
3618 if (err_vals && err_vals->value) {
3619 if (err_vals->value->errval) {
3620 if (need_separator && p_td.text->separator_encode) {
3621 buff.put_cs(*p_td.text->separator_encode);
3622 encoded_length+=p_td.text->separator_encode->lengthof();
3623 }
3624 if (err_vals->value->raw) {
3625 encoded_length += err_vals->value->errval->encode_raw(buff);
3626 } else {
3627 if (err_vals->value->type_descr==NULL) TTCN_error(
3628 "internal error: erroneous value typedescriptor missing");
3629 encoded_length += err_vals->value->errval->TEXT_encode(
3630 *(err_vals->value->type_descr),buff);
3631 }
3632 need_separator=true;
3633 } // else -> omit
3634 } else {
3635 if (!is_optional_field || get_at(i)->ispresent()) {
3636 if (need_separator && p_td.text->separator_encode) {
3637 buff.put_cs(*p_td.text->separator_encode);
3638 encoded_length+=p_td.text->separator_encode->lengthof();
3639 }
3640 if (emb_descr) {
3641 encoded_length += get_at(i)->TEXT_encode_negtest(emb_descr, *fld_descr(i),buff);
3642 } else {
3643 encoded_length += get_at(i)->TEXT_encode(*fld_descr(i),buff);
3644 }
3645 need_separator=true;
3646 }
3647 }
3648
3649 if (err_vals && err_vals->after) {
3650 if (err_vals->after->errval==NULL) TTCN_error(
3651 "internal error: erroneous after value missing");
3652 if (need_separator && p_td.text->separator_encode) {
3653 buff.put_cs(*p_td.text->separator_encode);
3654 encoded_length+=p_td.text->separator_encode->lengthof();
3655 }
3656 if (err_vals->after->raw) {
3657 encoded_length += err_vals->after->errval->encode_raw(buff);
3658 } else {
3659 if (err_vals->after->type_descr==NULL) TTCN_error(
3660 "internal error: erroneous after typedescriptor missing");
3661 encoded_length += err_vals->after->errval->TEXT_encode(
3662 *(err_vals->after->type_descr),buff);
3663 }
3664 need_separator=true;
3665 }
3666
3667 if (is_optional_field) next_optional_idx++;
3668
3669 if ( (p_err_descr->omit_after!=-1) && (i>=p_err_descr->omit_after) ) break;
3670 }
3671 if (p_td.text->end_encode) {
3672 buff.put_cs(*p_td.text->end_encode);
3673 encoded_length+=p_td.text->end_encode->lengthof();
3674 }
3675 return encoded_length;
3676}
3677
3678int Record_Type::TEXT_decode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& buff,
3679 Limit_Token_List& limit, boolean no_err, boolean /*first_call*/)
3680{
970ed795
EL
3681 if (is_set()) {
3682 int decoded_length=0;
3683 int decoded_field_length=0;
3684 size_t pos=buff.get_pos();
3685 boolean sep_found=FALSE;
3686 int ml=0;
3687 int sep_length=0;
3688 int loop_detector=1;
3689 int last_field_num=-1;
3690 if (p_td.text->begin_decode) {
3691 int tl;
3692 if ((tl=p_td.text->begin_decode->match_begin(buff))<0) {
3693 if(no_err) return -1;
3694 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR,
3695 "The specified token '%s' not found for '%s': ",
3696 (const char*)*(p_td.text->begin_decode), p_td.name);
3697 return 0;
3698 }
3699 decoded_length+=tl;
3700 buff.increase_pos(tl);
3701 }
3702 if (p_td.text->end_decode) {
3703 limit.add_token(p_td.text->end_decode);
3704 ml++;
3705 }
3706 if(p_td.text->separator_decode){
3707 limit.add_token(p_td.text->separator_decode);
3708 ml++;
3709 }
3710
3711 int field_cnt = get_count();
3712 int * const field_map = new int[field_cnt];
3713 memset(field_map, 0, field_cnt * sizeof(int));
3714
3715 int mand_field_num = 0;
3716 int opt_field_num = 0;
3717 int seof = 0;
3718 int has_repeatable=0;
3719 boolean repeatable = TRUE;
3720
3721 int next_optional_idx = 0;
3722 const int* optional_indexes = get_optional_indexes();
3723 for (int i=0;i<field_cnt;i++) {
3724 boolean is_optional_field = optional_indexes && (optional_indexes[next_optional_idx]==i);
3725 if (is_optional_field) {
3726 get_at(i)->set_to_omit();
3727 opt_field_num++;
3728 } else {
3729 mand_field_num++;
3730 }
3731 if (get_at(i)->is_seof()) {
3732 seof++;
3733 repeatable = repeatable && fld_descr(i)->text->val.parameters->decoding_params.repeatable;
3734 }
3735 if (is_optional_field) next_optional_idx++;
3736 }
3737 boolean has_optinals = opt_field_num > 0;
3738 if ((seof>0) && repeatable) has_repeatable=1;
3739
3740 while (mand_field_num+opt_field_num+has_repeatable) {
3741 loop_detector=1;
3742 /*while (TRUE)*/
3743 {
3744 next_optional_idx = 0;
3745 for (int i=0;i<field_cnt;i++) {
3746 boolean is_optional_field = optional_indexes && (optional_indexes[next_optional_idx]==i);
3747 if (get_at(i)->is_seof()) {
3748 if ( (fld_descr(i)->text->val.parameters->decoding_params.repeatable && field_map[i]<3)
3749 || !field_map[i] ) {
3750 pos=buff.get_pos();
3751 decoded_field_length = get_at(i)->TEXT_decode(*fld_descr(i),buff, limit, true,!field_map[i]);
3752 if (decoded_field_length<0) {
3753 buff.set_pos(pos);
3754 if (is_optional_field && !field_map[i]) get_at(i)->set_to_omit();
3755 } else {
3756 loop_detector=0;
3757 if (!field_map[i]) {
3758 if (is_optional_field) opt_field_num--;
3759 else mand_field_num--;
3760 field_map[i]=1;
3761 } else field_map[i]=2;
3762 last_field_num=i;
3763 break;
3764 }
3765 }
3766 } else { // !...->is_seof
3767 if (!field_map[i]) {
3768 pos=buff.get_pos();
3769 decoded_field_length = get_at(i)->TEXT_decode(*fld_descr(i),buff,limit,true);
3770 if (decoded_field_length<0) {
3771 buff.set_pos(pos);
3772 if (is_optional_field) get_at(i)->set_to_omit();
3773 } else {
3774 loop_detector=0;
3775 field_map[i]=1;
3776 if (is_optional_field) opt_field_num--;
3777 else mand_field_num--;
3778 last_field_num=i;
3779 break;
3780 }
3781 }
3782 } // !...->is_seof
3783 if (is_optional_field) next_optional_idx++;
3784 } // for i
3785 /* break*/
3786 }
3787 if (loop_detector) break;
3788 if (p_td.text->separator_decode) {
3789 int tl;
3790 if ((tl=p_td.text->separator_decode->match_begin(buff))<0) {
3791 if (p_td.text->end_decode) {
3792 int tl2;
3793 if ((tl2=p_td.text->end_decode->match_begin(buff))!=-1) {
3794 sep_found=FALSE;
3795 break;
3796 }
3797 } else if (limit.has_token(ml)) {
3798 int tl2;
3799 if ((tl2=limit.match(buff,ml))==0) {
3800 sep_found=FALSE;
3801 break;
3802 }
3803 } else break;
3804 buff.set_pos(pos);
3805 decoded_length-=decoded_field_length;
3806 field_map[last_field_num]+=2;
3807
3808 if (has_optinals) {
3809 if (last_field_num>=0 && last_field_num<field_cnt) {
3810 if (get_at(last_field_num)->is_seof()) {
3811 if (get_at(last_field_num)->is_optional()) {
3812 if (field_map[last_field_num]==3) {
3813 get_at(last_field_num)->set_to_omit();
3814 opt_field_num++;
3815 }
3816 } else {
3817 if (field_map[last_field_num]==3) {
3818 mand_field_num++;
3819 }
3820 }
3821 } else if (get_at(last_field_num)->is_optional()) {
3822 get_at(last_field_num)->set_to_omit();
3823 opt_field_num++;
3824 } else {
3825 mand_field_num++;
3826 }
3827 } else {
3828 mand_field_num++;
3829 }
3830 } // if (has_optinals)
3831 } else {
3832 sep_length=tl;
3833 decoded_length+=tl;
3834 buff.increase_pos(tl);
3835 for (int a=0;a<field_cnt;a++) if(field_map[a]>2) field_map[a]-=3;
3836 sep_found=TRUE;
3837 }
3838 } else if (p_td.text->end_decode) {
3839 int tl;
3840 if ((tl=p_td.text->end_decode->match_begin(buff))!=-1) {
3841 decoded_length+=tl;
3842 buff.increase_pos(tl);
3843 limit.remove_tokens(ml);
3844 if (mand_field_num) decoded_length = -1;
3845 goto bail;
3846 }
3847 } else if(limit.has_token(ml)){
3848 int tl;
3849 if ((tl=limit.match(buff,ml))==0) {
3850 sep_found=FALSE;
3851 break;
3852 }
3853 }
3854 } // while ( + + )
3855 limit.remove_tokens(ml);
3856 if (sep_found) {
3857 if (mand_field_num) {
3858 if (no_err) decoded_length = -1;
3859 else TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR,
3860 "Error during decoding '%s': ", p_td.name);
3861 goto bail;
3862 } else {
3863 decoded_length-=sep_length;
3864 buff.set_pos(buff.get_pos()-sep_length);
3865 }
3866 }
3867 if (p_td.text->end_decode) {
3868 int tl;
3869 if ((tl=p_td.text->end_decode->match_begin(buff))<0) {
3870 if (no_err) decoded_length = -1;
3871 else TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR,
3872 "The specified token '%s' not found for '%s': ",
3873 (const char*)*(p_td.text->end_decode),p_td.name);
3874 goto bail;
3875 }
3876 decoded_length+=tl;
3877 buff.increase_pos(tl);
3878 }
3879 if (mand_field_num) decoded_length = -1;
3880bail:
3881 delete[] field_map;
3882 return decoded_length;
3883 } else { // record decoder
3884 int decoded_length=0;
3885 int decoded_field_length=0;
3886 size_t pos=buff.get_pos();
3887 boolean sep_found=FALSE;
3888 int sep_length=0;
3889 int ml=0;
3890 if (p_td.text->begin_decode) {
3891 int tl;
3892 if ((tl=p_td.text->begin_decode->match_begin(buff))<0) {
3893 if(no_err)return -1;
3894 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR,
3895 "The specified token '%s' not found for '%s': ",
3896 (const char*)*(p_td.text->begin_decode), p_td.name);
3897 return 0;
3898 }
3899 decoded_length+=tl;
3900 buff.increase_pos(tl);
3901 }
3902 if (p_td.text->end_decode) {
3903 limit.add_token(p_td.text->end_decode);
3904 ml++;
3905 }
3906 if (p_td.text->separator_decode) {
3907 limit.add_token(p_td.text->separator_decode);
3908 ml++;
3909 }
3910
3911 int mand_field_num = 0;
3912 int opt_field_num = 0;
3913 int last_man_index = 0;
3914
3915 int field_cnt = get_count();
3916 int next_optional_idx = 0;
3917 const int* optional_indexes = get_optional_indexes();
3918 for (int i=0;i<field_cnt;i++) {
3919 boolean is_optional_field = optional_indexes && (optional_indexes[next_optional_idx]==i);
3920 if (is_optional_field) {
3921 get_at(i)->set_to_omit();
3922 opt_field_num++;
3923 } else {
3924 last_man_index=i+1;
3925 mand_field_num++;
3926 }
3927 if (is_optional_field) next_optional_idx++;
3928 }
3929
3930 next_optional_idx = 0;
3931 for(int i=0;i<field_cnt;i++) {
3932 boolean is_optional_field = optional_indexes && (optional_indexes[next_optional_idx]==i);
3933 if (is_optional_field) {
3934 pos=buff.get_pos();
3935 }
3936 decoded_field_length = get_at(i)->TEXT_decode(*fld_descr(i),buff,limit,TRUE);
3937 if (decoded_field_length<0) {
3938 if (is_optional_field) {
3939 get_at(i)->set_to_omit();
3940 buff.set_pos(pos);
3941 } else {
3942 limit.remove_tokens(ml);
3943 if (no_err) return -1;
3944 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR,
3945 "Error during decoding field '%s' for '%s': ",
3946 fld_descr(i)->name, p_td.name);
3947 return decoded_length;
3948 }
3949 } else {
3950 decoded_length+=decoded_field_length;
3951 if (last_man_index>(i+1)) {
3952 if (p_td.text->separator_decode) {
3953 int tl;
3954 if ((tl=p_td.text->separator_decode->match_begin(buff))<0) {
3955 if(is_optional_field) {
3956 get_at(i)->set_to_omit();
3957 buff.set_pos(pos);
3958 decoded_length-=decoded_field_length;
3959 } else {
3960 limit.remove_tokens(ml);
3961 if(no_err)return -1;
3962 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR,
3963 "The specified token '%s' not found for '%s': ",
3964 (const char*)*(p_td.text->separator_decode),p_td.name);
3965 return decoded_length;
3966 }
3967 } else {
3968 decoded_length+=tl;
3969 buff.increase_pos(tl);
3970 sep_length=tl;
3971 sep_found=TRUE;
3972 }
3973 } else sep_found=FALSE;
3974
3975 } else if (i==(field_cnt-1)) {
3976 sep_found=FALSE;
3977 } else {
3978 if (p_td.text->separator_decode) {
3979 int tl;
3980 if ((tl=p_td.text->separator_decode->match_begin(buff))<0) {
3981 if (is_optional_field) {
3982 if (p_td.text->end_decode) {
3983 if ((tl=p_td.text->end_decode->match_begin(buff))!=-1) {
3984 decoded_length+=tl;
3985 buff.increase_pos(tl);
3986 limit.remove_tokens(ml);
3987 return decoded_length;
3988 }
3989 } else if (limit.has_token(ml)) {
3990 if ((tl=limit.match(buff,ml))==0) {
3991 sep_found=FALSE;
3992 break;
3993 }
3994 } else break;
3995 get_at(i)->set_to_omit();
3996 buff.set_pos(pos);
3997 decoded_length-=decoded_field_length;
3998 } else {
3999 sep_found=FALSE;
4000 break;
4001 }
4002 } else {
4003 decoded_length+=tl;
4004 buff.increase_pos(tl);
4005 sep_length=tl;
4006 sep_found=TRUE;
4007 }
4008 } else {
4009 sep_found=FALSE;
4010 int tl;
4011 if (p_td.text->end_decode) {
4012 if ((tl=p_td.text->end_decode->match_begin(buff))!=-1) {
4013 decoded_length+=tl;
4014 buff.increase_pos(tl);
4015 limit.remove_tokens(ml);
4016 return decoded_length;
4017 }
4018 } else if (limit.has_token(ml)) {
4019 if ((tl=limit.match(buff,ml))==0) {
4020 sep_found=FALSE;
4021 break;
4022 }
4023 }
4024 }
4025 }
4026 }
4027 if (is_optional_field) next_optional_idx++;
4028 } // for i
4029 limit.remove_tokens(ml);
4030 if (sep_found) {
4031 buff.set_pos(buff.get_pos()-sep_length);
4032 decoded_length-=sep_length;
4033 }
4034 if (p_td.text->end_decode) {
4035 int tl;
4036 if ((tl=p_td.text->end_decode->match_begin(buff))<0) {
4037 if(no_err)return -1;
4038 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR,
4039 "The specified token '%s' not found for '%s': ",
4040 (const char*)*(p_td.text->end_decode),p_td.name);
4041 return decoded_length;
4042 }
4043 decoded_length+=tl;
4044 buff.increase_pos(tl);
4045 }
4046 return decoded_length;
4047 } // record decoder
4048}
4049
4050const XERdescriptor_t* Record_Type::xer_descr(int /*field_index*/) const
4051{
4052 TTCN_error("Internal error: Record_Type::xer_descr() called.");
4053 return NULL;
4054}
4055
4056char ** Record_Type::collect_ns(const XERdescriptor_t& p_td, size_t& num, bool& def_ns) const
4057{
4058 const int field_cnt = get_count();
4059 // The USE-ORDER member is first, unless preempted by EMBED-VALUES
4060 const int uo_index = ((p_td.xer_bits & EMBED_VALUES) !=0);
4061 // Index of the first "normal" member (after E-V and U-O)
4062 const int start_at = uo_index + ((p_td.xer_bits & USE_ORDER) != 0);
4063
4064 size_t num_collected = 0;
4065 // First, our own namespace. Sets num_collected to 0 or 1.
4066 // If it throws, nothing was allocated.
4067 char **collected_ns = Base_Type::collect_ns(p_td, num_collected, def_ns);
4068
4069 try{
4070 // If the nil attribute will be written, add the control namespace
4071 boolean nil_attribute = (p_td.xer_bits & USE_NIL)
4072 && !get_at(field_cnt-1)->ispresent();
4073
4074 if (nil_attribute) {
4075 collected_ns = (char**)Realloc(collected_ns, sizeof(char*) * ++num_collected);
4076 const namespace_t *c_ns = p_td.my_module->get_controlns();
4077
4078 collected_ns[num_collected-1] = mprintf(" xmlns:%s='%s'", c_ns->px, c_ns->ns);
4079 }
4080
4081 // Collect namespace declarations from all components (recursively).
4082 // This is extremely nasty, but we can't prosecute you for that.
4083 // (Monty Python - Crunchy Frog sketch). This whole thing is O(n^3). Yuck.
4084 for (int a = start_at; a < field_cnt; ++a) {
4085 size_t num_new = 0;
4086 bool def_ns_1 = false;
4087 char **new_namespaces = get_at(a)->collect_ns(*xer_descr(a), num_new, def_ns_1);
4088 merge_ns(collected_ns, num_collected, new_namespaces, num_new);
4089 def_ns = def_ns || def_ns_1;
4090 // merge_ns freed new_namespaces
4091 } // next field
4092 }
4093 catch (...) {
4094 // Probably a TC_Error thrown from the element's collect_ns(),
4095 // e.g. if encoding an unbound value.
4096 while (num_collected > 0) Free(collected_ns[--num_collected]);
4097 Free(collected_ns);
4098 throw;
4099 }
4100
4101 num = num_collected;
4102 return collected_ns;
4103}
4104
4105// FIXME some hashing should be implemented
4106int Record_Type::get_index_byname(const char *name, const char *uri) const {
4107 int num_fields = get_count();
4108 for (int i = 0; i < num_fields; ++i) {
4109 const XERdescriptor_t& xer = *xer_descr(i);
4110 if (check_name(name, xer, TRUE)
4111 && check_namespace(uri, xer)) return i;
4112 }
4113 return -1;
4114}
4115
4116int Record_Type::XER_encode(const XERdescriptor_t& p_td, TTCN_Buffer& p_buf,
af710487 4117 unsigned int flavor, int indent, embed_values_enc_struct_t*) const
970ed795
EL
4118{
4119 if (err_descr) {
af710487 4120 return XER_encode_negtest(err_descr, p_td, p_buf, flavor, indent, 0);
970ed795
EL
4121 }
4122 if (!is_bound()) {
4123 TTCN_EncDec_ErrorContext::error
4124 (TTCN_EncDec::ET_UNBOUND, "Encoding an unbound value.");
4125 }
4126
4127 TTCN_EncDec_ErrorContext ec_0("Component '");
4128 TTCN_EncDec_ErrorContext ec_1;
4129 int encoded_length=(int)p_buf.get_len(); // how much is already in the buffer
4130
4131 int exer = is_exer(flavor);
4132 if (exer && (p_td.xer_bits & EMBED_VALUES)) flavor |= XER_CANONICAL;
4133 const boolean indenting = !is_canonical(flavor);
4134 const int field_cnt = get_count();
4135 const int num_attributes = get_xer_num_attr();
4136 // The USE-ORDER member is first, unless preempted by EMBED-VALUES
4137 const int uo_index = ((p_td.xer_bits & EMBED_VALUES) !=0);
4138 // Index of the first "normal" member (after E-V and U-O)
4139 const int start_at = uo_index + ((p_td.xer_bits & USE_ORDER) != 0);
4140 const int first_nonattr = start_at + num_attributes;
4141 // start_tag_len is keeping track of how much was written at the end of the
4142 // start tag, i.e. the ">\n". This is used later to "back up" over it.
4143 int start_tag_len = 1 + indenting;
4144 // The EMBED-VALUES member, if applicable
3f84031e 4145 const Record_Of_Type* embed_values = 0;
4146 if (p_td.xer_bits & EMBED_VALUES) {
4147 embed_values = dynamic_cast<const Record_Of_Type*>(get_at(0));
4148 if (NULL == embed_values) {
4149 const OPTIONAL<Record_Of_Type>* const embed_opt = static_cast<const OPTIONAL<Record_Of_Type>*>(get_at(0));
4150 if(embed_opt->is_present()) {
4151 embed_values = &(*embed_opt)();
4152 }
4153 }
4154 }
970ed795
EL
4155 // The USE-ORDER member, if applicable
4156 const Record_Of_Type* const use_order = (p_td.xer_bits & USE_ORDER)
4157 ? static_cast<const Record_Of_Type*>(get_at(uo_index)) : 0;
4158
4159 size_t num_collected = 0; // we use this to compute delay_close
4160 char **collected_ns = NULL;
4161 bool def_ns = false;
4162 if (exer) {
4163 if (indent == 0) { // top-level type
4164 collected_ns = collect_ns(p_td, num_collected, def_ns);
4165 }
4166 else if ((flavor & DEF_NS_SQUASHED) && p_td.my_module && p_td.ns_index != -1) {
4167 const namespace_t * ns = p_td.my_module->get_ns(p_td.ns_index);
4168 // The default namespace has been squashed.
4169 // If we are in the default namespace, restore it.
4170 if (*ns->px == '\0') {
4171 collected_ns = Base_Type::collect_ns(p_td, num_collected, def_ns);
4172 }
4173 }
4174 }
4175
4176 // The type's own tag is omitted if we're doing E-XER,
4177 // and it's not the top-level type (XML must have a root element)
4178 // and it's either UNTAGGED or got USE_NIL or USE_TYPE or USE_UNION.
4179 boolean omit_tag = exer && (indent > 0)
4180 && ( (p_td.xer_bits & (UNTAGGED|XER_ATTRIBUTE))
4181 || (flavor & (USE_NIL|USE_TYPE_ATTR)));
4182
4183 // If a default namespace is in effect (uri but no prefix) and the type
4184 // is unqualified, the default namespace must be canceled; otherwise
4185 // an XML tag without a ns prefix looks like it belongs to the def.namespace
4186 const boolean empty_ns_hack = exer && !omit_tag && (indent > 0)
4187 && (p_td.xer_bits & FORM_UNQUALIFIED)
4188 && (flavor & DEF_NS_PRESENT);
4189
4190 // delay_close=true if there is stuff before the '>' of the start tag
4191 // (prevents writing the '>' which is built into the name).
4192 // This can only happen for EXER: if there are attributes or namespaces,
4193 // or either USE-NIL or USE-QNAME is set.
4194 boolean delay_close = exer && (num_attributes
4195 || empty_ns_hack // counts as having a namespace
4196 || (num_collected != 0)
4197 || (p_td.xer_bits & (USE_NIL|USE_QNAME))
4198 || (flavor & USE_NIL));
4199
4200 size_t shorter = 0;
4201
4202 if (!omit_tag) { /* write start tag */
4203 if (indenting) do_indent(p_buf, indent);
4204 /* name looks like this: "tagname>\n"
4205 * lose the \n if : not indenting or (single untagged(*) or attributes (*)) AND exer
4206 * lose the > if attributes are present (*) AND exer
4207 */
4208 p_buf.put_c('<');
4209 if (exer) write_ns_prefix(p_td, p_buf);
4210 p_buf.put_s((size_t)p_td.namelens[exer] - delay_close
4211 - (!indenting || delay_close || (exer && (p_td.xer_bits & HAS_1UNTAGGED))),
4212 (cbyte*)p_td.names[exer]);
4213 }
feade998 4214 else if (flavor & (USE_NIL|USE_TYPE_ATTR)) {
970ed795
EL
4215 // reopen the parent's start tag by overwriting the '>'
4216 size_t buf_len = p_buf.get_len();
4217 const unsigned char * const buf_data = p_buf.get_data();
4218 if (buf_data[buf_len - 1 - shorter] == '\n') ++shorter;
4219 if (buf_data[buf_len - 1 - shorter] == '>' ) ++shorter;
4220
4221 if (shorter) {
4222 p_buf.increase_length(-shorter);
4223 }
4224 delay_close = TRUE;
4225 }
4226
4227 int sub_len=0;
4228 // mask out extra flags we received, do not send them to the fields
4229 flavor &= XER_MASK;
4230
4231 if (exer && (p_td.xer_bits & USE_QNAME)) { // QName trumps everything
4232 const Base_Type * const q_uri = get_at(0);
4233 if (q_uri->is_present()) {
4234 p_buf.put_s(11, (cbyte*)" xmlns:b0='");
af710487 4235 q_uri->XER_encode(*xer_descr(0), p_buf, flavor | XER_LIST, indent+1, 0);
970ed795
EL
4236 p_buf.put_c('\'');
4237 }
4238
4239 if (p_td.xer_bits & XER_ATTRIBUTE) begin_attribute(p_td, p_buf);
4240 else p_buf.put_c('>');
4241
4242 if (q_uri->is_present()) {
4243 p_buf.put_s(3, (cbyte*)"b0:");
4244 sub_len += 3;
4245 }
4246 const Base_Type* const q_name = get_at(1);
af710487 4247 sub_len += q_name->XER_encode(*xer_descr(1), p_buf, flavor | XER_LIST, indent+1, 0);
970ed795
EL
4248 if (p_td.xer_bits & XER_ATTRIBUTE) p_buf.put_c('\'');
4249 }
4250 else { // not USE-QNAME
3f84031e 4251 if (!exer && (p_td.xer_bits & EMBED_VALUES) && embed_values != NULL) {
970ed795 4252 // The EMBED-VALUES member as an ordinary record of string
af710487 4253 sub_len += embed_values->XER_encode(*xer_descr(0), p_buf, flavor, indent+1, 0);
970ed795
EL
4254 }
4255
4256 if (!exer && (p_td.xer_bits & USE_ORDER)) {
4257 // The USE-ORDER member as an ordinary record of enumerated
af710487 4258 sub_len += use_order->XER_encode(*xer_descr(uo_index), p_buf, flavor, indent+1, 0);
970ed795
EL
4259 }
4260
4261 if (exer && (indent==0 || (flavor & DEF_NS_SQUASHED))) // write namespaces for toplevel only
4262 {
4263 for (size_t cur_coll = 0; cur_coll < num_collected; ++cur_coll) {
4264 p_buf.put_s(strlen(collected_ns[cur_coll]), (cbyte*)collected_ns[cur_coll]);
4265 Free(collected_ns[cur_coll]); // job done
4266 }
4267 Free(collected_ns);
4268 }
4269
4270 if (def_ns) {
4271 flavor &= ~DEF_NS_SQUASHED;
4272 flavor |= DEF_NS_PRESENT;
4273 }
4274 else if (empty_ns_hack) {
4275 p_buf.put_s(9, (cbyte*)" xmlns=''");
4276 flavor &= ~DEF_NS_PRESENT;
4277 flavor |= DEF_NS_SQUASHED;
4278 }
4279
4280 /* First all the attributes (not added to sub_len) */
4281 int i;
4282 for (i = start_at; i < first_nonattr; ++i) {
4283 boolean is_xer_attr_field = xer_descr(i)->xer_bits & XER_ATTRIBUTE;
4284 ec_1.set_msg("%s': ", fld_name(i)); // attr
af710487 4285 int tmp_len = get_at(i)->XER_encode(*xer_descr(i), p_buf, flavor, indent+1, 0);
970ed795
EL
4286 if (is_xer_attr_field && !exer) sub_len += tmp_len; /* do not add if attribute and EXER */
4287 }
4288
4289 // True if the "nil" attribute needs to be written.
4290 boolean nil_attribute = exer && (p_td.xer_bits & USE_NIL)
4291 && !get_at(field_cnt-1)->ispresent();
4292
4293 // True if USE_ORDER is in effect and the "nil" attribute was written.
4294 // Then the record-of-enum for USE-ORDER will be empty.
4295 boolean early_to_bed = FALSE;
4296
4297 if (nil_attribute) { // req. exer and USE_NIL
4298 const namespace_t *control_ns = p_td.my_module->get_controlns();
4299 p_buf.put_c(' ');
4300 p_buf.put_s(strlen(control_ns->px),
4301 (cbyte*)control_ns->px);
4302 p_buf.put_c(':');
4303 p_buf.put_s(10, (cbyte*)"nil='true'");
4304 if ((p_td.xer_bits & USE_ORDER)) early_to_bed = TRUE;
4305 // The whole content was omitted; nothing to do (and if we tried
4306 // to do it, we'd get an error for over-indexing a 0-length record-of).
4307 }
4308
4309 if (delay_close && (!omit_tag || shorter)) {
4310 // Close the start tag left open. If indenting, also write a newline
4311 // unless USE-NIL in effect or there is a single untagged component.
4312 start_tag_len = 1 +
4313 ((p_td.xer_bits & (/*USE_NIL|*/HAS_1UNTAGGED)) ? 0 : indenting);
4314 p_buf.put_s(start_tag_len , (cbyte*)">\n");
4315 }
4316
970ed795 4317 if (exer && (p_td.xer_bits & EMBED_VALUES)) {
970ed795 4318 /* write the first string */
3f84031e 4319 if (embed_values != NULL && embed_values->size_of() > 0) {
970ed795 4320 sub_len += embed_values->get_at(0)->XER_encode(UNIVERSAL_CHARSTRING_xer_,
af710487 4321 p_buf, flavor | EMBED_VALUES, indent+1, 0);
970ed795
EL
4322 }
4323 }
4324
4325 const Record_Type *ordered = this; // the record affected by USE-ORDER
4326
4327 // Index of the first non-attribute field of the record pointed to by
4328 // ordered, that is, the first field affected by USE-ORDER.
4329 size_t useorder_base = first_nonattr;
4330
4331 int begin = i;
4332 int end = field_cnt;
4333 if (exer && (p_td.xer_bits & USE_ORDER)) {
4334 const int to_send = use_order->size_of();
4335 // the length of the loop is determined by the length of use_order
4336 begin = 0;
4337 end = to_send;
4338
4339 // Count the non-attribute optionals
4340 int n_optionals = 0;
4341 for (int B = optional_count() - 1; B >=+0; B--) {
4342 int oi = get_optional_indexes()[B];
4343 if (oi < first_nonattr) break;
4344 ++n_optionals;
4345 }
4346
970ed795 4347 int expected_max = field_cnt - first_nonattr;
3f84031e 4348 int expected_min = expected_max - n_optionals;
970ed795
EL
4349
4350 if ((p_td.xer_bits & USE_NIL) && get_at(field_cnt-1)->ispresent()) {
4351 // The special case when USE_ORDER refers to the fields of a field,
4352 // not this record
4353 const Base_Type *last_optional = get_at(field_cnt-1);
4354 const Base_Type* inner = last_optional->get_opt_value();
4355 // it absolutely, positively has to be (derived from) Record_Type
4356 ordered = static_cast<const Record_Type*>(inner);
4357 useorder_base = ordered->get_xer_num_attr();
4358 begin = useorder_base;
4359 end = ordered->get_count();
4360
4361 expected_min = expected_max = ordered->get_count();
4362 }
4363
4364 if (to_send > expected_max
4365 ||to_send < expected_min) {
4366 ec_1.set_msg("%s': ", fld_name(uo_index));
4367 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_CONSTRAINT,
4368 "Wrong number of USE-ORDER %d, must be %d..%d", to_send, expected_min, expected_max);
4369 begin = end = 0; // don't bother sending anything
4370 }
4371 else { // check no duplicates
4372 int *seen = new int [to_send];
4373 int num_seen = 0;
4374 for (int ei = 0; ei < to_send; ++ei) {
4375 const Base_Type *uoe = use_order->get_at(ei);
4376 const Enum_Type *enm = static_cast<const Enum_Type *>(uoe);
4377 int val = enm->as_int();
4378 for (int x = 0; x < num_seen; ++x) {
4379 if (val == seen[x]) { // complain
4380 ec_1.set_msg("%s': ", fld_name(uo_index));
4381 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_CONSTRAINT,
4382 "Duplicate value for USE-ORDER");
4383 begin = end = 0; // don't bother sending anything
4384 goto trouble;
4385 }
4386 }
4387 seen[num_seen++] = val;
4388 }
4389 trouble:
4390 delete [] seen;
4391 // If the number is right and there are no duplicates, then carry on
4392 }
4393 }
4394
4395 /* Then, all the non-attributes. Structuring the code like this depends on
4396 * all attributes appearing before all non-attributes (excluding
4397 * pseudo-members for USE-ORDER, etc.) */
4398
4399 // early_to_bed can only be true if exer is true (transitive through nil_attribute)
af710487 4400 if (!early_to_bed) {
4401 embed_values_enc_struct_t* emb_val = 0;
3f84031e 4402 if (exer && (p_td.xer_bits & EMBED_VALUES) &&
4403 embed_values != NULL && embed_values->size_of() > 1) {
af710487 4404 emb_val = new embed_values_enc_struct_t;
4405 emb_val->embval_array = embed_values;
4406 emb_val->embval_index = 1;
4407 emb_val->embval_err = 0;
4408 }
4409
4410 for ( i = begin; i < end; ++i ) {
4411 const Base_Type *uoe = 0; // "useOrder enum"
4412 const Enum_Type *enm = 0; // the enum value selecting the field
4413 if (exer && use_order) {
4414 uoe = use_order->get_at(i - begin);
4415 enm = static_cast<const Enum_Type *>(uoe);
4416 }
4417
4418 // "actual" index, may be perturbed by USE-ORDER
4419 int ai = !(exer && (p_td.xer_bits & USE_ORDER)) ? i :
4420 enm->as_int() + useorder_base;
4421 ec_1.set_msg("%s': ", ordered->fld_name(ai)); // non-attr
4422
4423 const XERdescriptor_t& descr = *ordered->xer_descr(ai);
4424 sub_len += ordered->get_at(ai)->XER_encode(descr, p_buf,
4425 // Pass USE-NIL to the last field (except when USE-ORDER is also in effect,
4426 // because the tag-stripping effect of USE-NIL has been achieved
4427 // by encoding the sub-fields directly).
4428 flavor | ((exer && !use_order && (i == field_cnt-1)) ? (p_td.xer_bits & USE_NIL) : 0),
4429 indent+!omit_tag, emb_val);
4430
4431 // Now the next embed-values string (NOT affected by USE-ORDER!)
4432 if (exer && (p_td.xer_bits & EMBED_VALUES) && 0 != emb_val &&
3f84031e 4433 embed_values != NULL && emb_val->embval_index < embed_values->size_of()) {
af710487 4434 embed_values->get_at(emb_val->embval_index)->XER_encode(UNIVERSAL_CHARSTRING_xer_
4435 , p_buf, flavor | EMBED_VALUES, indent+1, 0);
4436 ++emb_val->embval_index;
4437 }
4438 } //for
4439
4440 if (0 != emb_val) {
3f84031e 4441 if (embed_values != NULL && emb_val->embval_index < embed_values->size_of()) {
af710487 4442 ec_1.set_msg("%s': ", fld_name(0));
4443 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_CONSTRAINT,
4444 "Too many EMBED-VALUEs specified: %d (expected %d or less)",
4445 embed_values->size_of(), emb_val->embval_index);
4446 }
4447 delete emb_val;
4448 }
4449 } // if (!early_to_bed)
970ed795
EL
4450 } // if (QNAME)
4451
4452 if (!omit_tag) {
4453 if (sub_len) { // something was written, now an end tag
4454 if (indenting && !(exer && (p_td.xer_bits & (HAS_1UNTAGGED | USE_QNAME)))) {
4455 // The tags of the last optional member involved with USE_NIL
4456 // have been removed. If it was a simple type, the content was probably
4457 // written on a single line without anything resembling a close tag.
4458 // Do not indent our end tag in this case.
4459 switch ((int)(exer && (p_td.xer_bits & USE_NIL))) {
4460 case 1: {
4461 const unsigned char *buf_end = p_buf.get_data() + (p_buf.get_len()-1);
4462 if (buf_end[-1] != '>' || *buf_end != '\n') break;
4463 // If it does not look like an end tag, skip the indenting,
4464 // else fall through.
4465 }
4466 case 0:
4467 do_indent(p_buf, indent);
4468 break;
4469 }
4470 }
4471 p_buf.put_c('<');
4472 p_buf.put_c('/');
4473 if (exer) write_ns_prefix(p_td, p_buf);
4474 p_buf.put_s((size_t)p_td.namelens[exer]-!indenting, (cbyte*)p_td.names[exer]);
4475 }
4476 else { // need to generate an empty element tag
4477 p_buf.increase_length(-start_tag_len); // decrease length
4478 p_buf.put_s((size_t)2+indenting, (cbyte*)"/>\n");
4479 }
4480 }
4481
4482 return (int)p_buf.get_len() - encoded_length;
4483}
4484
4485// XERSTUFF Record_Type::encode_field
4486/** Helper for Record_Type::XER_encode_negtest
4487 *
4488 * Factored out because Record_Type::XER_encode (on which XER_encode_negtest
4489 * is based) calls the XER_encode method of the field in two places:
4490 * one for attributes, the other for elements.
4491 *
4492 * @param i index of the field
4493 * @param err_vals erroneous descriptor for the field
4494 * @param emb_descr deeper erroneous values
4495 * @param p_buf buffer containing the encoded value
4496 * @param sub_flavor flags
4497 * @param indent indentation level
4498 * @return the number of bytes generated
4499 */
4500int Record_Type::encode_field(int i,
4501 const Erroneous_values_t* err_vals, const Erroneous_descriptor_t* emb_descr,
af710487 4502 TTCN_Buffer& p_buf, unsigned int sub_flavor, int indent, embed_values_enc_struct_t* emb_val) const
970ed795
EL
4503{
4504 int enc_len = 0;
4505 TTCN_EncDec_ErrorContext ec;
4506 if (err_vals && err_vals->before) {
4507 if (err_vals->before->errval==NULL) TTCN_error(
4508 "internal error: erroneous before value missing");
4509 ec.set_msg("Erroneous value before component %s: ", fld_name(i));
4510 if (err_vals->before->raw) {
4511 enc_len += err_vals->before->errval->encode_raw(p_buf);
4512 } else {
4513 if (err_vals->before->type_descr==NULL) TTCN_error(
4514 "internal error: erroneous before typedescriptor missing");
4515 enc_len += err_vals->before->errval->XER_encode(
af710487 4516 *err_vals->before->type_descr->xer, p_buf, sub_flavor, indent, 0);
970ed795
EL
4517 }
4518 }
4519
4520 if (err_vals && err_vals->value) {
4521 if (err_vals->value->errval) { // replace
4522 ec.set_msg("Erroneous value for component %s: ", fld_name(i));
4523 if (err_vals->value->raw) {
4524 enc_len += err_vals->value->errval->encode_raw(p_buf);
4525 } else {
4526 if (err_vals->value->type_descr==NULL) TTCN_error(
4527 "internal error: erroneous value typedescriptor missing");
4528 enc_len += err_vals->value->errval->XER_encode(
af710487 4529 *err_vals->value->type_descr->xer, p_buf, sub_flavor, indent, 0);
970ed795
EL
4530 }
4531 } // else -> omit
4532 } else {
4533 ec.set_msg("Component %s: ", fld_name(i));
4534 if (emb_descr) {
4535 enc_len += get_at(i)->XER_encode_negtest(emb_descr, *xer_descr(i), p_buf,
af710487 4536 sub_flavor, indent, emb_val);
970ed795
EL
4537 } else {
4538 // the "real" encoder
4539 enc_len += get_at(i)->XER_encode(*xer_descr(i), p_buf,
af710487 4540 sub_flavor, indent, emb_val);
970ed795
EL
4541 }
4542 }
4543
4544 if (err_vals && err_vals->after) {
4545 if (err_vals->after->errval==NULL) TTCN_error(
4546 "internal error: erroneous after value missing");
4547 ec.set_msg("Erroneous value after component %s: ", fld_name(i));
4548 if (err_vals->after->raw) {
4549 enc_len += err_vals->after->errval->encode_raw(p_buf);
4550 } else {
4551 if (err_vals->after->type_descr==NULL) TTCN_error(
4552 "internal error: erroneous after typedescriptor missing");
4553 enc_len += err_vals->after->errval->XER_encode(
af710487 4554 *err_vals->after->type_descr->xer, p_buf, sub_flavor, indent, 0);
970ed795
EL
4555 }
4556 }
4557
4558 return enc_len;
4559}
4560
4561// XERSTUFF Record_Type::XER_encode_negtest
4562int Record_Type::XER_encode_negtest(const Erroneous_descriptor_t* p_err_descr,
af710487 4563 const XERdescriptor_t& p_td, TTCN_Buffer& p_buf, unsigned int flavor, int indent,
4564 embed_values_enc_struct_t*) const
970ed795
EL
4565{
4566 if (!is_bound()) {
4567 TTCN_EncDec_ErrorContext::error
4568 (TTCN_EncDec::ET_UNBOUND, "Encoding an unbound value.");
4569 }
4570 TTCN_EncDec_ErrorContext ec_0("Component '");
4571 TTCN_EncDec_ErrorContext ec_1;
4572 int encoded_length=(int)p_buf.get_len(); // how much is already in the buffer
4573
4574 int exer = is_exer(flavor);
4575 if (exer && (p_td.xer_bits & EMBED_VALUES)) flavor |= XER_CANONICAL;
4576 const boolean indenting = !is_canonical(flavor);
4577 const int field_cnt = get_count();
4578 const int num_attributes = get_xer_num_attr();
4579 // The USE-ORDER member is first, unless preempted by EMBED-VALUES
4580 const int uo_index = ((p_td.xer_bits & EMBED_VALUES) !=0);
4581 // Index of the first "normal" member (after E-V and U-O)
4582 const int start_at = uo_index + ((p_td.xer_bits & USE_ORDER) != 0);
4583 const int first_nonattr = start_at + num_attributes;
4584 // start_tag_len is keeping track of how much was written at the end of the
4585 // start tag, i.e. the ">\n". This is used later to "back up" over it.
4586 int start_tag_len = 1 + indenting;
4587 // The EMBED-VALUES member, if applicable (always first)
4588 const Record_Of_Type* const embed_values = (p_td.xer_bits & EMBED_VALUES)
4589 ? static_cast<const Record_Of_Type*>(get_at(0)) : 0;
4590 // The USE-ORDER member, if applicable (first unless preempted by embed_vals)
4591 const Record_Of_Type* const use_order = (p_td.xer_bits & USE_ORDER)
4592 ? static_cast<const Record_Of_Type*>(get_at(uo_index)) : 0;
4593
4594 int values_idx = 0;
4595 int edescr_idx = 0;
4596
4597 size_t num_collected = 0; // we use this to compute delay_close
4598 char **collected_ns = NULL;
4599 bool def_ns = false;
4600 if (exer) {
4601 if (indent == 0) { // top-level type
4602 collected_ns = collect_ns(p_td, num_collected, def_ns);
4603 }
4604 else if ((flavor & DEF_NS_SQUASHED) && p_td.my_module && p_td.ns_index != -1) {
4605 const namespace_t * ns = p_td.my_module->get_ns(p_td.ns_index);
4606 // The default namespace has been squashed.
4607 // If we are in the default namespace, restore it.
4608 if (*ns->px == '\0') {
4609 collected_ns = Base_Type::collect_ns(p_td, num_collected, def_ns);
4610 }
4611 }
4612 }
4613
4614 // The type's own tag is omitted if we're doing E-XER,
4615 // and it's not the top-level type (XML must have a root element)
4616 // and it's either UNTAGGED or got USE_NIL.
4617 boolean omit_tag = exer && indent
4618 && ( (p_td.xer_bits & (UNTAGGED|XER_ATTRIBUTE))
4619 || (flavor & (USE_NIL|USE_TYPE_ATTR)));
4620
4621 // If a default namespace is in effect (uri but no prefix) and the type
4622 // is unqualified, the default namespace must be canceled; otherwise
4623 // an XML tag without a ns prefix looks like it belongs to the def.namespace
4624 const boolean empty_ns_hack = exer && !omit_tag && (indent > 0)
4625 && (p_td.xer_bits & FORM_UNQUALIFIED)
4626 && (flavor & DEF_NS_PRESENT);
4627
4628 // delay_close=true if there is stuff before the '>' of the start tag
4629 // (prevents writing the '>' which is built into the name).
4630 // This can only happen for EXER: if there are attributes or namespaces,
4631 // or either USE-NIL or USE-QNAME is set.
4632 boolean delay_close = exer && (num_attributes
4633 || empty_ns_hack // counts as having a namespace
4634 || (num_collected != 0)
4635 || (p_td.xer_bits & (USE_NIL|USE_QNAME))
4636 || (flavor & USE_NIL));
4637
4638 size_t shorter = 0;
4639 if (!omit_tag) { /* write start tag */
4640 if (indenting) do_indent(p_buf, indent);
4641 /* name looks like this: "tagname>\n"
4642 * lose the \n if : not indenting or (single untagged(*) or attributes (*)) AND exer
4643 * lose the > if attributes are present (*) AND exer
4644 */
4645 p_buf.put_c('<');
4646 if (exer) write_ns_prefix(p_td, p_buf);
4647 p_buf.put_s((size_t)p_td.namelens[exer] - delay_close
4648 - (!indenting || delay_close || (exer && (p_td.xer_bits & HAS_1UNTAGGED))),
4649 (cbyte*)p_td.names[exer]);
4650 }
4651 else if (flavor & USE_TYPE_ATTR) {
4652 // reopen the parent's tag
4653 size_t buf_len = p_buf.get_len();
4654 const unsigned char * const buf_data = p_buf.get_data();
4655 if (buf_data[buf_len - 1 - shorter] == '\n') ++shorter;
4656 if (buf_data[buf_len - 1 - shorter] == '>' ) ++shorter;
4657
4658 if (shorter) {
4659 p_buf.increase_length(-shorter);
4660 }
4661 delay_close = TRUE;
4662 }
4663
4664 int sub_len=0, tmp_len;
4665 // mask out extra flags we received, do not send them to the fields
4666 flavor &= XER_MASK;
4667
4668 if (exer && (p_td.xer_bits & USE_QNAME)) {
4669 const Erroneous_values_t * ev =
4670 p_err_descr->next_field_err_values(0, values_idx);
4671 const Erroneous_descriptor_t* ed =
4672 p_err_descr->next_field_emb_descr (0, edescr_idx);
4673 // At first, erroneous info for the first component (uri)
4674
4675 TTCN_EncDec_ErrorContext ec;
4676 const Base_Type * const q_uri = get_at(0);
4677
4678 if (ev && ev->before) {
4679 if (ev->before->errval==NULL) TTCN_error(
4680 "internal error: erroneous before value missing");
4681 ec.set_msg("Erroneous value before component #0: ");
4682 if (ev->before->raw) {
4683 sub_len += ev->before->errval->encode_raw(p_buf);
4684 } else {
4685 if (ev->before->type_descr==NULL) TTCN_error(
4686 "internal error: erroneous before typedescriptor missing");
4687 sub_len += ev->before->errval->XER_encode(
af710487 4688 *ev->before->type_descr->xer, p_buf, flavor, indent, 0);
970ed795
EL
4689 }
4690 }
4691
4692 if (ev && ev->value) {
4693 if (ev->value->errval) { // replace
4694 ec.set_msg("Erroneous value for component #0: ");
4695 if (ev->value->raw) {
4696 sub_len += ev->value->errval->encode_raw(p_buf);
4697 } else {
4698 if (ev->value->type_descr==NULL) TTCN_error(
4699 "internal error: erroneous value typedescriptor missing");
4700 sub_len += ev->value->errval->XER_encode(
af710487 4701 *ev->value->type_descr->xer, p_buf, flavor, indent, 0);
970ed795
EL
4702 }
4703 } // else -> omit
4704 } else {
4705 ec.set_msg("Component #0: ");
4706 if (ed) {
4707 // universal charstring does not have components.
4708 // TTCN code which could have generated embedded erroneous descriptor
4709 // should have failed semantic analysis.
4710 TTCN_error("internal error: embedded descriptor unexpected");
4711 } else {
4712 // the "real" encoder
4713 if (q_uri->is_present()) {
4714 p_buf.put_s(11, (cbyte*)" xmlns:b0='");
af710487 4715 sub_len += q_uri->XER_encode(*xer_descr(0), p_buf, flavor | XER_LIST, indent+1, 0);
970ed795
EL
4716 p_buf.put_c('\'');
4717 }
4718 }
4719 }
4720
4721 if (ev && ev->after) {
4722 if (ev->after->errval==NULL) TTCN_error(
4723 "internal error: erroneous after value missing");
4724 ec.set_msg("Erroneous value after component #0: ");
4725 if (ev->after->raw) {
4726 sub_len += ev->after->errval->encode_raw(p_buf);
4727 } else {
4728 if (ev->after->type_descr==NULL) TTCN_error(
4729 "internal error: erroneous after typedescriptor missing");
4730 sub_len += ev->after->errval->XER_encode(
af710487 4731 *ev->after->type_descr->xer, p_buf, flavor, indent, 0);
970ed795
EL
4732 }
4733 }
4734
4735 if (p_td.xer_bits & XER_ATTRIBUTE) begin_attribute(p_td, p_buf);
4736 else p_buf.put_c('>');
4737
4738 // Now switch to the second field (name)
4739 ev = p_err_descr->next_field_err_values(1, values_idx);
4740 ed = p_err_descr->next_field_emb_descr (1, edescr_idx);
4741
4742 if (ev && ev->before) {
4743 if (ev->before->errval==NULL) TTCN_error(
4744 "internal error: erroneous before value missing");
4745 ec.set_msg("Erroneous value before component #1: ");
4746 if (ev->before->raw) {
4747 sub_len += ev->before->errval->encode_raw(p_buf);
4748 } else {
4749 if (ev->before->type_descr==NULL) TTCN_error(
4750 "internal error: erroneous before typedescriptor missing");
4751 sub_len += ev->before->errval->XER_encode(
af710487 4752 *ev->before->type_descr->xer, p_buf, flavor, indent, 0);
970ed795
EL
4753 }
4754 }
4755
4756 if (ev && ev->value) {
4757 if (ev->value->errval) { // replace
4758 ec.set_msg("Erroneous value for component #1: ");
4759 if (ev->value->raw) {
4760 sub_len += ev->value->errval->encode_raw(p_buf);
4761 } else {
4762 if (ev->value->type_descr==NULL) TTCN_error(
4763 "internal error: erroneous value typedescriptor missing");
4764 sub_len += ev->value->errval->XER_encode(
af710487 4765 *ev->value->type_descr->xer, p_buf, flavor, indent, 0);
970ed795
EL
4766 }
4767 } // else -> omit
4768 } else {
4769 ec.set_msg("Component #1: ");
4770 if (ed) {
4771 // universal charstring does not have components
4772 TTCN_error("internal error: embedded descriptor unexpected");
4773 } else {
4774 // the "real" encoder
4775 if (q_uri->is_present()) {
4776 p_buf.put_s(3, (cbyte*)"b0:");
4777 sub_len += 3;
4778 }
4779
af710487 4780 sub_len += get_at(1)->XER_encode(*xer_descr(1), p_buf, flavor | XER_LIST, indent+1, 0);
970ed795
EL
4781 }
4782 }
4783
4784 if (ev && ev->after) {
4785 if (ev->after->errval==NULL) TTCN_error(
4786 "internal error: erroneous after value missing");
4787 ec.set_msg("Erroneous value after component #1: ");
4788 if (ev->after->raw) {
4789 sub_len += ev->after->errval->encode_raw(p_buf);
4790 } else {
4791 if (ev->after->type_descr==NULL) TTCN_error(
4792 "internal error: erroneous after typedescriptor missing");
4793 sub_len += ev->after->errval->XER_encode(
af710487 4794 *ev->after->type_descr->xer, p_buf, flavor, indent, 0);
970ed795
EL
4795 }
4796 }
4797
4798 if (p_td.xer_bits & XER_ATTRIBUTE) p_buf.put_c('\'');
4799 }
4800 else { // not USE-QNAME
4801 if (!exer && (p_td.xer_bits & EMBED_VALUES)) {
4802 // The EMBED-VALUES member as an ordinary record of string
af710487 4803 sub_len += embed_values->XER_encode(*xer_descr(0), p_buf, flavor, indent+1, 0);
970ed795
EL
4804 }
4805
4806 if (!exer && (p_td.xer_bits & USE_ORDER)) {
4807 // The USE-ORDER member as an ordinary record of enumerated
af710487 4808 sub_len += use_order->XER_encode(*xer_descr(uo_index), p_buf, flavor, indent+1, 0);
970ed795
EL
4809 }
4810
4811 if (exer && (indent==0 || (flavor & DEF_NS_SQUASHED))) // write namespaces for toplevel only
4812 {
4813 for (size_t cur_coll = 0; cur_coll < num_collected; ++cur_coll) {
4814 p_buf.put_s(strlen(collected_ns[cur_coll]), (cbyte*)collected_ns[cur_coll]);
4815 Free(collected_ns[cur_coll]); // job done
4816 }
4817 Free(collected_ns);
4818 }
4819
4820 if (def_ns) {
4821 flavor &= ~DEF_NS_SQUASHED;
4822 flavor |= DEF_NS_PRESENT;
4823 }
4824 else if (empty_ns_hack) {
4825 p_buf.put_s(9, (cbyte*)" xmlns=''");
4826 flavor &= ~DEF_NS_PRESENT;
4827 flavor |= DEF_NS_SQUASHED;
4828 }
4829
4830 // True if the non-attribute fields need to be omitted;
4831 // e.g. if USE_ORDER is in effect and the "nil" attribute was written
4832 // (then the record-of-enum for USE-ORDER will be empty),
4833 // or "omit all after" was hit while processing attributes.
4834 boolean early_to_bed = FALSE;
4835
4836 // First all the attributes (not added to sub_len)
4837 int i;
4838 for (i = start_at; i < first_nonattr; ++i) {
4839 const Erroneous_values_t * ev =
4840 p_err_descr->next_field_err_values(i, values_idx);
4841 const Erroneous_descriptor_t* ed =
4842 p_err_descr->next_field_emb_descr(i, edescr_idx);
4843
4844 if (i < p_err_descr->omit_before) continue;
4845
4846 boolean is_xer_attr_field = xer_descr(i)->xer_bits & XER_ATTRIBUTE;
4847 ec_1.set_msg("%s': ", fld_name(i)); // attr
4848
af710487 4849 tmp_len = encode_field(i, ev, ed, p_buf, flavor, indent + !omit_tag, 0);
970ed795
EL
4850
4851 if (is_xer_attr_field && !exer) sub_len += tmp_len; // do not add if attribute and EXER
4852
4853 // omit_after value -1 becomes "very big"
4854 if ((unsigned int)i >= (unsigned int)p_err_descr->omit_after) {
4855 early_to_bed = TRUE; // no more fields to write
4856 break;
4857 }
4858 }
4859
4860 // True if the "nil" attribute needs to be written.
4861 boolean nil_attribute = FALSE;
4862 // nil attribute unaffected by erroneous
4863 boolean nil_attribute_simple = FALSE;
4864 if (exer && (p_td.xer_bits & USE_NIL)) {
4865 nil_attribute = nil_attribute_simple = !get_at(field_cnt-1)->ispresent();
4866
4867 if (p_err_descr->values_size > 0) // there is an erroneous "value := ..."
4868 {
4869 const Erroneous_values_t *ev_nil =
4870 p_err_descr->get_field_err_values(field_cnt-1);
4871 if (ev_nil && ev_nil->value) // value override for the last field
4872 {
4873 nil_attribute = (ev_nil->value->errval == NULL);
4874 }
4875 }
4876 }
4877
4878 if (nil_attribute) { // req. exer and USE_NIL
4879 const namespace_t *control_ns = p_td.my_module->get_controlns();
4880
4881 if (!nil_attribute_simple) {
4882 // It is likely that the declaration for namespace "xsi"
4883 // was not written. Do it now.
4884 p_buf.put_s(7, (cbyte*)" xmlns:");
4885 p_buf.put_s(strlen(control_ns->px), (cbyte*)control_ns->px);
4886 p_buf.put_s(2, (cbyte*)"='");
4887 p_buf.put_s(strlen(control_ns->ns), (cbyte*)control_ns->ns);
4888 p_buf.put_c('\'');
4889 }
4890
4891 p_buf.put_c(' ');
4892 p_buf.put_s(strlen(control_ns->px), (cbyte*)control_ns->px);
4893 p_buf.put_c(':');
4894 p_buf.put_s(10, (cbyte*)"nil='true'");
4895 if ((p_td.xer_bits & USE_ORDER)) early_to_bed = TRUE;
4896 // The whole content was omitted; nothing to do (and if we tried
4897 // to do it, we'd get an error for over-indexing a 0-length record-of).
4898 }
4899
4900 if (delay_close && (!omit_tag || shorter)) {
4901 // Close the start tag left open. If indenting, also write a newline
4902 // unless USE-NIL in effect or there is a single untagged component.
4903 start_tag_len = 1 +
4904 ((p_td.xer_bits & (/*USE_NIL|*/HAS_1UNTAGGED)) ? 0 : indenting);
4905 p_buf.put_s(start_tag_len , (cbyte*)">\n");
4906 }
4907
4908 // Erroneous values for the embed_values member (if any).
4909 // Collected once but referenced multiple times.
4910 const Erroneous_descriptor_t* ed0 = NULL;
4911 int embed_values_val_idx = 0;
4912 int embed_values_descr_idx = 0;
4913
970ed795
EL
4914 if (exer && (p_td.xer_bits & EMBED_VALUES)) {
4915 ed0 = p_err_descr->next_field_emb_descr(0, edescr_idx);
4916
970ed795 4917 // write the first string
af710487 4918 if (embed_values->size_of() > 0) {
970ed795
EL
4919 const Erroneous_values_t * ev0_0 = NULL;
4920 const Erroneous_descriptor_t* ed0_0 = NULL;
4921 if (ed0) {
4922 ev0_0 = ed0->next_field_err_values(0, embed_values_val_idx);
4923 ed0_0 = ed0->next_field_emb_descr (0, embed_values_descr_idx);
4924 }
a38c6d4c 4925 sub_len += embed_values->encode_element(0, UNIVERSAL_CHARSTRING_xer_,
4926 ev0_0, ed0_0, p_buf, flavor | EMBED_VALUES, indent+!omit_tag, 0);
970ed795
EL
4927 }
4928 }
4929
4930 const Record_Type *ordered = this; // the record affected by USE-ORDER
4931 // By default it's this record, unless USE_NIL is _also_ in effect,
4932 // in which case it's the last member of this.
4933
4934 // Index of the first non-attribute field of the record pointed to by
4935 // ordered, that is, the first field affected by USE-ORDER.
4936 size_t useorder_base = first_nonattr;
4937
4938 int begin = i;
4939 int end = field_cnt; // "one past", do not touch
4940 // by default, continue from the current field until the end, indexing this
4941
4942 if (exer && (p_td.xer_bits & USE_ORDER)) {
4943 // the length of the loop is determined by the length of use_order
4944 const int to_send = use_order->size_of();
4945
4946 // i will index all elements of the use_order member
4947 begin = 0;
4948 end = to_send;
4949
4950 // Count the non-attribute optionals
4951 int n_optionals = 0;
4952 for (int B = optional_count() - 1; B >=+0; B--) {
4953 int oi = get_optional_indexes()[B];
4954 if (oi < first_nonattr) break;
4955 ++n_optionals;
4956 }
4957
4958 int expected_min = field_cnt - first_nonattr - n_optionals;
4959 int expected_max = field_cnt - first_nonattr;
4960
4961 if ((p_td.xer_bits & USE_NIL) && get_at(field_cnt-1)->ispresent()) {
4962 // The special case when USE_ORDER refers to the fields of a field,
4963 // not this record
4964 const Base_Type *last_optional = get_at(field_cnt-1);
4965 const Base_Type* inner = last_optional->get_opt_value();
4966 // it absolutely, positively has to be (derived from) Record_Type
4967 ordered = static_cast<const Record_Type*>(inner);
4968 useorder_base = ordered->get_xer_num_attr();
4969 begin = useorder_base;
4970 end = ordered->get_count();
4971
4972 expected_min = expected_max = ordered->get_count();
4973 }
4974
4975 if (to_send > expected_max
4976 ||to_send < expected_min) {
4977 ec_1.set_msg("%s': ", fld_name(uo_index));
4978 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_CONSTRAINT,
4979 "Wrong number of USE-ORDER %d, must be %d..%d", to_send, expected_min, expected_max);
4980 early_to_bed = TRUE; // don't bother sending anything
4981 }
4982 else { // check no duplicates
4983 int *seen = new int [to_send];
4984 int num_seen = 0;
4985 for (int ei = 0; ei < to_send; ++ei) {
4986 const Base_Type *uoe = use_order->get_at(ei);
4987 const Enum_Type *enm = static_cast<const Enum_Type *>(uoe);
4988 int val = enm->as_int();
4989 for (int x = 0; x < num_seen; ++x) {
4990 if (val == seen[x]) { // complain
4991 ec_1.set_msg("%s': ", fld_name(uo_index));
4992 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_CONSTRAINT,
4993 "Duplicate value for USE-ORDER");
4994 early_to_bed = TRUE; // don't bother sending anything
4995 goto trouble;
4996 }
4997 }
4998 seen[num_seen++] = val;
4999 }
5000 trouble:
5001 delete [] seen;
5002 // If the number is right and there are no duplicates, then carry on
5003 }
5004 } // endif(USE_ORDER)
5005
5006 // Then, all the non-attributes. Structuring the code like this depends on
5007 // all attributes appearing before all non-attributes (excluding
5008 // pseudo-members for USE-ORDER, etc.)
5009
5010 // This loop handles both the normal case (no USE_ORDER) when i indexes
5011 // fields of this record; and the USE_ORDER case (with or without USE-NIL).
5012 //
5013 // early_to_bed can only be true if exer is true (transitive through nil_attribute)
af710487 5014 if (!early_to_bed) {
5015 embed_values_enc_struct_t* emb_val = 0;
5016 if (exer && (p_td.xer_bits & EMBED_VALUES) && embed_values->size_of() > 1) {
5017 emb_val = new embed_values_enc_struct_t;
5018 emb_val->embval_array = embed_values;
5019 emb_val->embval_index = 1;
5020 emb_val->embval_err = ed0;
5021 emb_val->embval_err_val_idx = embed_values_val_idx;
5022 emb_val->embval_err_descr_idx = embed_values_descr_idx;
5023 }
5024
5025 for ( i = begin; i < end; ++i ) {
5026
5027 const Base_Type *uoe = 0; // "useOrder enum"
5028 const Enum_Type *enm = 0; // the enum value selecting the field
5029
5030 // "actual" index, may be perturbed by USE-ORDER.
5031 // We use this value to index the appropriate record.
5032 int ai = i;
5033
5034 const Erroneous_values_t * ev = NULL;
5035 const Erroneous_descriptor_t* ed = NULL;
5036 if (exer && use_order) {
5037 // If USE-ORDER is in effect, it introduces a level of indirection
5038 // into the indexing of fields: "i" is used to select an element
5039 // of the use_order member (an enum), whose value is used to select
5040 // the field being encoded.
5041 uoe = use_order->get_at(i - begin);
5042 enm = static_cast<const Enum_Type *>(uoe);
5043 ai = enm->as_int() + useorder_base;
5044
5045 // Because it is not guaranteed that ai will increase monotonically,
5046 // we can't use next_field_...().
5047 ev = p_err_descr->get_field_err_values(ai);
5048 ed = p_err_descr->get_field_emb_descr (ai);
5049 }
5050 else { // not USE-ORDER, sequential access
5051 ev = p_err_descr->next_field_err_values(ai, values_idx);
5052 ed = p_err_descr->next_field_emb_descr (ai, edescr_idx);
5053 }
5054 ec_1.set_msg("%s': ", ordered->fld_name(ai)); // non-attr
5055
5056 if (ai < p_err_descr->omit_before) continue;
5057
5058 // omit_after value -1 becomes "very big".
5059 if ((unsigned int)ai > (unsigned int)p_err_descr->omit_after) continue;
5060 // We can't skip all fields with break, because the next ai may be lower
5061 // than omit_after.
5062
5063 sub_len += ordered->encode_field(ai, ev, ed, p_buf,
5064 // Pass USE-NIL to the last field (except when USE-ORDER is also in effect,
5065 // because the tag-stripping effect of USE-NIL has been achieved
5066 // by encoding the sub-fields directly).
5067 flavor | ((exer && !use_order && (i == field_cnt-1)) ? (p_td.xer_bits & USE_NIL) : 0),
5068 indent + !omit_tag, emb_val);
5069
5070 // Now the next embed-values string (NOT affected by USE-ORDER!)
5071 if (exer && (p_td.xer_bits & EMBED_VALUES) && 0 != emb_val &&
5072 emb_val->embval_index < embed_values->size_of()) {
5073 const Erroneous_values_t * ev0_i = NULL;
5074 const Erroneous_descriptor_t* ed0_i = NULL;
5075 if (ed0) {
5076 ev0_i = ed0->next_field_err_values(emb_val->embval_index, emb_val->embval_err_val_idx);
5077 ed0_i = ed0->next_field_emb_descr (emb_val->embval_index, emb_val->embval_err_descr_idx);
5078 }
a38c6d4c 5079 embed_values->encode_element(emb_val->embval_index, UNIVERSAL_CHARSTRING_xer_,
5080 ev0_i, ed0_i, p_buf, flavor | EMBED_VALUES, indent + !omit_tag, 0);
af710487 5081 ++emb_val->embval_index;
5082 }
5083 } //for
5084 if (0 != emb_val) {
5085 if (emb_val->embval_index < embed_values->size_of()) {
5086 ec_1.set_msg("%s': ", fld_name(0));
5087 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_CONSTRAINT,
5088 "Too many EMBED-VALUEs specified: %d (expected %d or less)",
5089 embed_values->size_of(), emb_val->embval_index);
970ed795 5090 }
af710487 5091 delete emb_val;
970ed795 5092 }
af710487 5093 } // if (!early_to_bed)
970ed795
EL
5094 } // if (QNAME)
5095
5096
5097 if (!omit_tag) {
5098 if (sub_len) { // something was written, now an end tag
5099 if (indenting && !(exer && (p_td.xer_bits & (HAS_1UNTAGGED | USE_QNAME))))
5100 // The tags of the last optional member involved with USE_NIL
5101 // have been removed. If it was a simple type, the content was probably
5102 // written on a single line without anything resembling a close tag.
5103 // Do not indent our end tag in this case.
5104 switch ((int)(exer && (p_td.xer_bits & USE_NIL))) {
5105 case 1: {
5106 const unsigned char *buf_end = p_buf.get_data() + (p_buf.get_len()-1);
5107 if (buf_end[-1] != '>' || *buf_end != '\n') break;
5108 // If it does not look like an end tag, skip the indenting,
5109 // else fall through.
5110 }
5111 case 0:
5112 do_indent(p_buf, indent);
5113 break;
5114 }
5115 p_buf.put_c('<');
5116 p_buf.put_c('/');
5117 if (exer) write_ns_prefix(p_td, p_buf);
5118 p_buf.put_s((size_t)p_td.namelens[exer]-!indenting, (cbyte*)p_td.names[exer]);
5119 }
5120 else { // need to generate an empty element tag
5121 p_buf.increase_length(-start_tag_len); // decrease length
5122 p_buf.put_s((size_t)2+indenting, (cbyte*)"/>\n");
5123 }
5124 }
5125
5126 return (int)p_buf.get_len() - encoded_length;
5127}
5128
af710487 5129int Record_Type::XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& reader,
feade998 5130 unsigned int flavor, unsigned int flavor2, embed_values_dec_struct_t*)
970ed795 5131{
970ed795
EL
5132 int exer = is_exer(flavor);
5133 int success, type;
5134 int depth=-1; // depth of the start tag
5135 int xerbits = p_td.xer_bits;
5136 if (flavor & XER_TOPLEVEL) xerbits &= ~UNTAGGED;
5137 const boolean own_tag = !(exer
5138 && ( (xerbits & (ANY_ELEMENT | UNTAGGED | XER_ATTRIBUTE))
5139 || (flavor & (USE_NIL | USE_TYPE_ATTR))));
5140 boolean tag_closed = (flavor & PARENT_CLOSED) != 0;
5141 // If the parent has USE-TYPE, our ATTRIBUTE members can be found
5142 // in the parent's tag (the reader is sitting on it).
feade998 5143 const boolean parent_tag = exer && ((flavor & USE_TYPE_ATTR) || (flavor2 & USE_NIL_PARENT_TAG));
970ed795
EL
5144
5145 // Filter out flags passed by our parent. These are not for the fields.
5146 flavor &= XER_MASK; // also removes XER_TOPLEVEL
feade998 5147 flavor2 = XER_NONE; // Remove only bit: USE_NIL_PARENT_TAG (for now)
970ed795
EL
5148
5149 const int field_cnt = get_count();
5150 const int num_attributes = get_xer_num_attr();
5151
5152 // The index of potential "order" field, regardless of whether USE_ORDER
5153 // is in use or not.
5154 const int uo_index = ((p_td.xer_bits & EMBED_VALUES) !=0);
5155
5156 // The first "non-special" field (skipping the USE-ORDER and EMBED-VALUES
5157 // fields); normal processing start at this field.
5158 const int start_at = uo_index + ((p_td.xer_bits & USE_ORDER) != 0);
5159 const int first_nonattr = start_at + num_attributes;
feade998 5160
970ed795
EL
5161 // The index of the ANY-ATTRIBUTES member, if any
5162 int aa_index = -1;
5163 for (int k = 0; k < first_nonattr; ++k) {
5164 if (xer_descr(k)->xer_bits & ANY_ATTRIBUTES) {
5165 aa_index = k;
af710487 5166 if (!get_at(aa_index)->is_optional()) {
5167 static_cast<Record_Of_Type*>(get_at(aa_index))->set_size(0);
5168 }
970ed795
EL
5169 break; // there can be only one, 18.2.2
5170 }
5171 }
5172
5173 if (own_tag) for (success=reader.Ok(); success==1; success=reader.Read()) {
5174 type = reader.NodeType();
5175 if (type==XML_READER_TYPE_ELEMENT) {
5176 verify_name(reader, p_td, exer);
5177 depth = reader.Depth();
5178 tag_closed = reader.IsEmptyElement();
5179 break;
5180 }
5181 }//for
5182
5183 int i = 0;
5184
5185 if (exer && (p_td.xer_bits & USE_QNAME)) { // QName trumps everything !
5186 // If element, it looks like this:
5187 // <name xmlns:b0="http://www.furniture.com">b0:table</name>
5188 // If attribute, it looks like this:
5189 // name='b0:table'
5190
5191 if (p_td.xer_bits & XER_ATTRIBUTE) success = 1; // do nothing
5192 else for (success = reader.Read(); success == 1; success = reader.Read()) {
5193 type = reader.NodeType();
5194 if (type == XML_READER_TYPE_TEXT) break;
5195 }
5196
5197 if (success == 1) {
5198 xmlChar *val = reader.NewValue();
5199 xmlChar *npfx = (xmlChar*)strchr((char*)val, ':');
5200 xmlChar *pfx;
5201 if (npfx != NULL) {
5202 *npfx++ = '\0'; // cut the string into two
5203 pfx = val;
5204 }
5205 else {
5206 npfx = val;
5207 pfx = NULL;
5208 }
5209
5210 xmlChar *nsu = reader.LookupNamespace(pfx);
5211
5212 OPTIONAL<UNIVERSAL_CHARSTRING> *q_prefix2 =
5213 static_cast<OPTIONAL<UNIVERSAL_CHARSTRING>*>(get_at(0));
5214 if (nsu) *q_prefix2 = (const char*)nsu;
5215 else q_prefix2->set_to_omit(); // public in RT2 only
5216
5217 UNIVERSAL_CHARSTRING *q_name2 = static_cast<UNIVERSAL_CHARSTRING*>(get_at(1));
5218 *q_name2 = (const char*)npfx;
5219
5220 xmlFree(nsu);
5221 xmlFree(val);
5222 }
5223 }
5224 else { // not use-qname
5225 TTCN_EncDec_ErrorContext ec_0("Component '");
5226 TTCN_EncDec_ErrorContext ec_1;
5227 boolean usenil_attribute = FALSE; // true if found and said yes
feade998 5228 // If nillable and the nillable field is a record type, that has attributes
5229 // then it will become true, and skips the processing of the fields after
5230 boolean already_processed = FALSE;
970ed795
EL
5231 if (!exer) {
5232 if (!reader.IsEmptyElement()) reader.Read();
5233 // First, the (would-be) attributes (unaffected by USE-ORDER)
5234 for (i = 0; i < first_nonattr; i++) {
5235 ec_1.set_msg("%s': ", fld_name(i));
feade998 5236 get_at(i)->XER_decode(*xer_descr(i), reader, flavor, flavor2, 0);
970ed795
EL
5237 } // next field
5238 }
5239 else if (own_tag || parent_tag) { // EXER and not UNTAGGED: do attributes
5240 // Prepare for lack of attributes.
5241 // Fields with defaultForEmpty get the D-F-E value, optional get omit.
5242 for (i = start_at; i < first_nonattr; i++) {
5243 Base_Type &fld = *get_at(i);
5244 const XERdescriptor_t& xd = *xer_descr(i);
5245 if (xd.dfeValue) {
5246 if (fld.is_optional()) {
5247 fld.set_to_present();
5248 fld.get_opt_value()->set_value(xd.dfeValue);
5249 }
5250 else fld.set_value(xd.dfeValue);
5251 }
5252 else if (fld.is_optional()) fld.set_to_omit();
5253 }
5254
5255 int num_aa = 0; // index into the ANY-ATTRIBUTE member
5256
5257 const namespace_t *control_ns = 0;
5258 if (parent_tag || (p_td.xer_bits & USE_NIL)) {
5259 // xsi:type or xsi:nil
5260 control_ns = p_td.my_module->get_controlns();
5261 }
5262
5263 /* * * * * * * * * Attributes * * * * * * * * * * * * * */
feade998 5264 if(parent_tag && reader.NodeType() == XML_READER_TYPE_ATTRIBUTE) {
5265 success = reader.Ok();
5266 } else {
5267 success = reader.MoveToFirstAttribute();
5268 }
5269 for (;
970ed795
EL
5270 success == 1 && reader.NodeType() == XML_READER_TYPE_ATTRIBUTE;
5271 success = reader.AdvanceAttribute())
5272 {
5273 if (reader.IsNamespaceDecl()) {
5274 continue; // namespace declarations are handled for us by libxml2
5275 }
5276
5277 const char *attr_name = (const char*)reader.LocalName();
5278 const char *ns_uri = (const char*)reader.NamespaceUri();
5279 int field_index = get_index_byname(attr_name, ns_uri);
5280 if (field_index != -1) {
5281 // There is a field. Let it decode the attribute.
5282 ec_1.set_msg("%s': ", fld_name(field_index));
feade998 5283 get_at(field_index)->XER_decode(*xer_descr(field_index), reader, flavor, flavor2, 0);
970ed795
EL
5284 continue;
5285 }
5286
5287 // Attribute not found. It could be the "nil" attribute
5288 if (p_td.xer_bits & USE_NIL) {
5289 const char *prefix = (const char*)reader.Prefix();
5290 // prefix may be NULL, control_ns->px is never NULL or empty
5291 if (prefix && !strcmp(prefix, control_ns->px)
5292 && !strcmp((const char*)reader.LocalName(), "nil"))
5293 { // It is the "nil" attribute
5294 const char *value = (const char*)reader.Value();
5295 if (value) {
5296 if (!strcmp(value, "1") || !strcmp(value, "true")) {
5297 // The field affected by USE-NIL is always the last one
5298 get_at(field_cnt-1)->set_to_omit();
5299 usenil_attribute = TRUE;
5300 } // true
5301 } // if value
5302
5303 continue;
5304 } // it is the "nil" attribute
feade998 5305 // else, let the nillable field decode the next attributes, it is possible
5306 // that it belongs to him
5307 get_at(field_cnt-1)->XER_decode(*xer_descr(field_cnt-1), reader, flavor | USE_NIL, flavor2 | USE_NIL_PARENT_TAG, 0);
5308 already_processed = TRUE;
d44e3c4f 5309 break;
970ed795 5310 } // type has USE-NIL
feade998 5311
970ed795
EL
5312 if (parent_tag) {
5313 const char *prefix = (const char*)reader.Prefix();
5314 // prefix may be NULL, control_ns->px is never NULL or empty
5315 if (prefix && !strcmp(prefix, control_ns->px)
5316 && !strcmp((const char*)reader.LocalName(), "type")) {
5317 continue; // xsi:type has been processed by the parent
5318 }
5319 }
5320
5321 if (aa_index >= 0) {
5322 ec_1.set_msg("%s': ", fld_name(aa_index));
5323 TTCN_EncDec_ErrorContext ec_2("Attribute %d: ", num_aa);
5324 // We have a component with ANY-ATTRIBUTE. It must be a record of
5325 // UNIVERSAL_CHARSTRING. Add the attribute to it.
af710487 5326 Record_Of_Type *aa = 0;
5327 if (get_at(aa_index)->is_optional()) {
5328 if (num_aa == 0) {
5329 get_at(aa_index)->set_to_present();
5330 }
5331 aa = static_cast<Record_Of_Type*>(get_at(aa_index)->get_opt_value());
5332 }
5333 else {
5334 aa = static_cast<Record_Of_Type*>(get_at(aa_index));
5335 }
970ed795
EL
5336 UNIVERSAL_CHARSTRING *new_elem = static_cast<UNIVERSAL_CHARSTRING *>
5337 (aa->get_at(num_aa++));
5338
5339 // Construct the AnyAttributeFormat (X.693amd1, 18.2.6)
5340 TTCN_Buffer aabuf;
5341 const xmlChar *name = reader.LocalName();
5342 const xmlChar *val = reader.Value();
5343 const xmlChar *uri = reader.NamespaceUri();
5344
5345 if (xer_descr(aa_index)->xer_bits & (ANY_FROM | ANY_EXCEPT)) {
5346 check_namespace_restrictions(*xer_descr(aa_index), (const char*)uri);
5347 }
5348 // We don't care about reader.Prefix()
5349 // Using strlen to count UTF8 bytes, not characters
5350 aabuf.put_s(uri ? strlen((const char*)uri) : 0, uri);
5351 if (uri && *uri) aabuf.put_c(' ');
5352 aabuf.put_s(name ? strlen((const char*)name) : 0, name);
5353 aabuf.put_c('=');
5354 aabuf.put_c('"');
5355 aabuf.put_s(val ? strlen((const char*)val) : 0, val);
5356 aabuf.put_c('"');
5357 new_elem->decode_utf8(aabuf.get_len(), aabuf.get_data());
5358
5359 continue;
5360 }
5361
5362 // Lastly check for the xsi:schemaLocation attribute, this does not
5363 // affect TTCN-3, but it shouldn't cause a DTE
5364 if (reader.LocalName() && !strcmp((const char*)reader.LocalName(), "schemaLocation")) {
5365 if (!control_ns) {
5366 control_ns = p_td.my_module->get_controlns();
5367 }
5368 if (reader.Prefix() && !strcmp((const char*)reader.Prefix(), control_ns->px)) {
5369 continue;
5370 }
5371 }
feade998 5372
970ed795
EL
5373 // Nobody wanted the attribute. That is an error.
5374 ec_0.set_msg(" "); ec_1.set_msg(" ");
5375 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG,
5376 "Unexpected attribute '%s', ns '%s'", attr_name,
5377 ns_uri ? ns_uri : "");
5378 } // next attribute
5379
5380 // Now check that all mandatory attributes have been set
5381 for (i = start_at; i < first_nonattr; ++i) {
5382 Base_Type * fld = get_at(i);
5383 if (fld->is_optional()) continue; // field is allowed to be unset
5384 if (!fld->is_bound()) {
5385 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG,
5386 "Missing attribute '%s'", this->fld_name(i));
5387 }
5388 }
5389
5390 i = first_nonattr; // finished with attributes
d44e3c4f 5391 // AdvanceAttribute did MoveToElement. Move into the content (if any),
5392 // except when the reader is already moved in(already_processed).
5393 if (!reader.IsEmptyElement() && !already_processed) reader.Read();
970ed795 5394 } // end if (own_tag)
feade998 5395
970ed795 5396 /* * * * * * * * Non-attributes (elements) * * * * * * * * * * * */
af710487 5397 embed_values_dec_struct_t* emb_val = 0;
3f84031e 5398 bool emb_val_optional = false;
970ed795 5399 if (exer && (p_td.xer_bits & EMBED_VALUES)) {
af710487 5400 emb_val = new embed_values_dec_struct_t;
3f84031e 5401 emb_val->embval_array = dynamic_cast<Record_Of_Type*>(get_at(0));
5402 if (NULL == emb_val->embval_array) {
5403 OPTIONAL<PreGenRecordOf::PREGEN__RECORD__OF__UNIVERSAL__CHARSTRING>* embed_value = static_cast<OPTIONAL<PreGenRecordOf::PREGEN__RECORD__OF__UNIVERSAL__CHARSTRING>*>(get_at(0));
5404 embed_value->set_to_present();
5405 emb_val->embval_array = static_cast<Record_Of_Type*>((*embed_value).get_opt_value());
5406 emb_val_optional = true;
5407 }
af710487 5408 emb_val->embval_array->set_size(0);
5409 emb_val->embval_index = 0;
970ed795
EL
5410 }
5411
5412 if (exer && (p_td.xer_bits & USE_ORDER)) {
5413 // Set all optional fields to omit because their respective XER_decode
5414 // will not be run (and will stay unbound) if the value is missing.
5415 int n_optionals = 0;
5416 for (int B = optional_count() - 1; B >=+0; B--) {
5417 int oi = get_optional_indexes()[B];
5418 if (oi < first_nonattr) break;
5419 get_at(oi)->set_to_omit();
5420 ++n_optionals;
5421 }
3abe9331 5422
970ed795
EL
5423 Record_Of_Type *use_order = static_cast<Record_Of_Type*>(get_at(uo_index));
5424 // Initialize the use_order field to empty. Let it grow on demand.
5425 // (setting it to the minimum acceptable size may leave unbound elements
5426 // if the XML was incomplete).
5427 use_order->set_size(0);
5428
3abe9331 5429 // Nothing to order if there are no child elements
5430 if (!tag_closed) {
5431 Record_Type *jumbled = this; // the record affected by USE_ORDER
5432 int begin = first_nonattr;
5433 int end = field_cnt; // "one past"
5434 if (p_td.xer_bits & USE_NIL) {
5435 Base_Type *last_optional = get_at(field_cnt-1);
5436 if (!usenil_attribute) { // exer known true
5437 last_optional->set_to_present();
5438 jumbled = static_cast<Record_Type*>(last_optional->get_opt_value());
5439 // We will operate on the members of last_optional,
5440 // effectively bypassing last_optional->XER_decode() itself.
5441 begin = 0;
5442 end = jumbled->get_count();
5443 ec_1.set_msg("%s': ", fld_name(field_cnt-1));
970ed795 5444 }
970ed795 5445 }
3abe9331 5446 if (num_attributes > 0
5447 && first_nonattr != field_cnt
5448 && i == first_nonattr - 1) { // exer known true
5449 // If there were attributes and their processing just finished,
5450 // the reader is positioned on the start tag of the record.
5451 // Move ahead, unless there are no non-attribute fields.
5452 reader.Read();
af710487 5453 }
3abe9331 5454 // Then, the non-attributes
5455
5456 // The index runs over the members affected by USE-ORDER.
5457 // This is [first_nonattr,field_cnt) unless USE-NIL is involved,
5458 // in which case it's [0,optional_sequence::field_cnt)
5459 int *seen = new int[end-begin];
5460 int num_seen = 0;
5461 int last_any_elem = begin - 1;
5462 // The index of the latest embedded value can change outside of this function
5463 // (if the field is an untagged record of), in this case the next value should
5464 // be ignored, as it's already been handled by the record of
5465 int last_embval_index = 0;
5466 bool early_exit = false;
5467 for (i = begin; i < end; i++) {
5468 for (success = reader.Ok(); success == 1; success = reader.Read()) {
5469 type = reader.NodeType();
5470 if (0 != emb_val && reader.NodeType()==XML_READER_TYPE_TEXT) {
5471 UNIVERSAL_CHARSTRING emb_ustr((const char*)reader.Value());
5472 emb_val->embval_array->get_at(emb_val->embval_index)->set_value(&emb_ustr);
5473 }
5474 // The non-attribute components must not be UNTAGGED
5475 if (type == XML_READER_TYPE_ELEMENT) break;
5476 if (type == XML_READER_TYPE_END_ELEMENT) {
5477 early_exit = true;
5478 break;
970ed795 5479 }
970ed795 5480 }
3abe9331 5481 if (0 != emb_val) {
5482 if (last_embval_index == emb_val->embval_index) {
5483 ++emb_val->embval_index;
5484 }
5485 last_embval_index = emb_val->embval_index;
5486 }
5487 if (success != 1 || early_exit) break;
5488 const char *name = (const char *)reader.LocalName();
5489 bool field_name_found = false;
5490 // Find out which member it is.
5491 // FIXME some hashing should be implemented
5492 for (int k = begin; k < end; k++) {
5493 if (!(jumbled->xer_descr(k)->xer_bits & ANY_ELEMENT) &&
5494 check_name(name, *jumbled->xer_descr(k), 1)) {
970ed795
EL
5495 ec_1.set_msg("%s': ", jumbled->fld_name(k));
5496
5497 // Check for the same field being decoded twice.
5498 // We can't use the field's is_bound()/is_present(),
5499 // because the field may be bound on input, e.g. for
5500 // prototype(fast) or prototype(backtrack).
5501 int in_dex = k - begin;
5502 for (int o = 0; o < num_seen ;++o) {
5503 if (in_dex == seen[o]) TTCN_EncDec_ErrorContext::error(
5504 TTCN_EncDec::ET_INVAL_MSG, "Duplicate element");
5505 }
5506 seen[num_seen++] = in_dex;
5507 // Set the next use-order member.
5508 // Non-const get_at creates the object in the record-of.
5509 static_cast<Enum_Type*>(use_order->get_at(i - begin))
5510 ->from_int(in_dex);
5511 Base_Type *b = jumbled->get_at(k);
feade998 5512 b->XER_decode(*jumbled->xer_descr(k), reader, flavor, flavor2, emb_val);
3abe9331 5513 field_name_found = true;
970ed795
EL
5514 break;
5515 }
5516 }
3abe9331 5517 if (!field_name_found) {
5518 // Check the anyElement fields
5519 for (int k = last_any_elem + 1; k < end; k++) {
5520 if (jumbled->xer_descr(k)->xer_bits & ANY_ELEMENT) {
5521 ec_1.set_msg("%s': ", jumbled->fld_name(k));
5522
5523 // Check for the same field being decoded twice.
5524 // We can't use the field's is_bound()/is_present(),
5525 // because the field may be bound on input, e.g. for
5526 // prototype(fast) or prototype(backtrack).
5527 int in_dex = k - begin;
5528 for (int o = 0; o < num_seen ;++o) {
5529 if (in_dex == seen[o]) TTCN_EncDec_ErrorContext::error(
5530 TTCN_EncDec::ET_INVAL_MSG, "Duplicate element");
5531 }
5532 seen[num_seen++] = in_dex;
5533 // Set the next use-order member.
5534 // Non-const get_at creates the object in the record-of.
5535 static_cast<Enum_Type*>(use_order->get_at(i - begin))
5536 ->from_int(in_dex);
5537 Base_Type *b = jumbled->get_at(k);
feade998 5538 b->XER_decode(*jumbled->xer_descr(k), reader, flavor, flavor2, emb_val);
3abe9331 5539 last_any_elem = k;
5540 field_name_found = true;
5541 break;
5542 }
5543 }
5544 }
5545 if (!field_name_found) {
5546 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG,
5547 "Bad XML tag '%s' instead of a valid field", name);
5548 break;
5549 }
5550 } // next field
5551 if (0 != emb_val) {
5552 if (reader.NodeType()==XML_READER_TYPE_TEXT) {
5553 UNIVERSAL_CHARSTRING emb_ustr((const char*)reader.Value());
5554 emb_val->embval_array->get_at(emb_val->embval_index)->set_value(&emb_ustr);
5555 }
5556 if (last_embval_index == emb_val->embval_index) {
5557 ++emb_val->embval_index;
5558 }
970ed795 5559 }
3abe9331 5560 delete [] seen;
5561 ec_1.set_msg(" "); // no active component
5562 ec_0.set_msg(" ");
5563
5564 // Check that we collected the required number of children
5565 int num_collected = use_order->size_of();
5566 if (p_td.xer_bits & USE_NIL) {
5567 int expected = usenil_attribute ? 0 : jumbled->get_count();
5568 if (num_collected != expected) {
5569 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INCOMPL_MSG,
5570 "Incorrect number of fields %d, expected %d",
5571 num_collected, expected);
5572 }
970ed795 5573 }
3abe9331 5574 else {
5575 if (num_collected < field_cnt - first_nonattr - n_optionals
5576 ||num_collected > field_cnt - first_nonattr) {
5577 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INCOMPL_MSG,
5578 "Wrong number of fields! size = %d, expected %d..%d",
5579 use_order->size_of(), field_cnt - first_nonattr - n_optionals,
5580 field_cnt - first_nonattr);
5581 }
970ed795 5582 }
3abe9331 5583 } // not empty element
970ed795
EL
5584 }
5585 else { // not USE-ORDER, simpler code
5586 if (usenil_attribute) {
5587 reader.MoveToElement(); // value absent, nothing more to do
5588 } else {
af710487 5589 // The index of the latest embedded value can change outside of this function
5590 // (if the field is a untagged record of), in this case the next value should
5591 // be ignored, as it's already been handled by the record of
5592 // Omitted fields can also reset this value
5593 int last_embval_index = 0;
970ed795 5594 for (; i<field_cnt; i++) {
af710487 5595 if (0 != emb_val) {
970ed795
EL
5596 if (reader.NodeType()==XML_READER_TYPE_TEXT) {
5597 UNIVERSAL_CHARSTRING emb_ustr((const char*)reader.Value());
af710487 5598 emb_val->embval_array->get_at(emb_val->embval_index)->set_value(&emb_ustr);
970ed795 5599 }
af710487 5600 if (last_embval_index == emb_val->embval_index) {
5601 ++emb_val->embval_index;
5602 }
5603 last_embval_index = emb_val->embval_index;
970ed795
EL
5604 }
5605 ec_1.set_msg("%s': ", fld_name(i));
5606 if (exer && i==field_cnt-1 && p_td.dfeValue && reader.IsEmptyElement()) {
5607 get_at(i)->set_value(p_td.dfeValue);
5608 }
5609 else {
5610 // In case the field is an optional anyElement -> check if it should be omitted
5611 bool optional_any_elem_check = true;
5612 if (get_at(i)->is_optional() && (xer_descr(i)->xer_bits & ANY_ELEMENT)) {
5613 // The "anyElement" coding instruction can only be applied to a universal charstring field
5614 OPTIONAL<UNIVERSAL_CHARSTRING>* opt_field = dynamic_cast<OPTIONAL<UNIVERSAL_CHARSTRING>*>(get_at(i));
5615 if (opt_field) {
5616 const char* next_field_name = NULL;
5617 if (i < field_cnt - 1) {
5618 next_field_name = fld_name(i + 1);
5619 }
5620 optional_any_elem_check = opt_field->XER_check_any_elem(reader, next_field_name, tag_closed);
5621 }
5622 }
feade998 5623 if (optional_any_elem_check && !already_processed) {
970ed795
EL
5624 int new_flavor = flavor ;
5625 if (i == field_cnt-1) new_flavor |= (p_td.xer_bits & USE_NIL);
5626 if (tag_closed) new_flavor |= PARENT_CLOSED;
5627
feade998 5628 get_at(i)->XER_decode(*xer_descr(i), reader, new_flavor, flavor2, emb_val);
970ed795
EL
5629 }
5630 }
af710487 5631 if (!get_at(i)->is_present()) {
5632 // there was no new element, the last embedded value is for the next field
5633 // (or the end of the record if this is the last field)
5634 last_embval_index = -1;
5635 }
970ed795 5636 } // next field
af710487 5637 if (0 != emb_val) {
970ed795
EL
5638 if (reader.NodeType()==XML_READER_TYPE_TEXT) {
5639 UNIVERSAL_CHARSTRING emb_ustr((const char*)reader.Value());
af710487 5640 emb_val->embval_array->get_at(emb_val->embval_index)->set_value(&emb_ustr);
5641 }
5642 if (last_embval_index == emb_val->embval_index) {
5643 ++emb_val->embval_index;
970ed795
EL
5644 }
5645 }
5646 }
5647 } // if use-order
5648
af710487 5649 if (0 != emb_val) {
3f84031e 5650 bool all_unbound = true;
970ed795 5651 static const UNIVERSAL_CHARSTRING emptystring(0, (const char*)NULL);
af710487 5652 for (int j = 0; j < emb_val->embval_index; ++j) {
5653 if (!emb_val->embval_array->get_at(j)->is_bound()) {
5654 emb_val->embval_array->get_at(j)->set_value(&emptystring);
3f84031e 5655 }else if((static_cast<const UNIVERSAL_CHARSTRING*>(emb_val->embval_array->get_at(j)))->lengthof() !=0) {
5656 all_unbound = false;
af710487 5657 }
970ed795 5658 }
3f84031e 5659 if(emb_val_optional && all_unbound){
5660 static_cast<OPTIONAL<PreGenRecordOf::PREGEN__RECORD__OF__UNIVERSAL__CHARSTRING>*>(get_at(0))->set_to_omit();
5661 }
af710487 5662 delete emb_val;
970ed795
EL
5663 } // if embed-values
5664
5665 } // if use-qname
3abe9331 5666
5667 // Check if every non-optional field has been set
5668 for (i = 0; i < field_cnt; ++i) {
5669 if (!get_at(i)->is_optional() && !get_at(i)->is_bound()) {
5670 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INCOMPL_MSG,
5671 "No data found for non-optional field '%s'", fld_name(i));
5672 }
5673 }
5674
970ed795
EL
5675 if (own_tag) {
5676 // We had our start tag. Then our fields did their thing.
5677 // Now we expect the end tag. And it better be our end tag!
5678 int current_depth;
5679 for (success = reader.Ok(); success == 1; success = reader.Read()) {
5680 type = reader.NodeType();
5681 current_depth = reader.Depth();
5682 if (current_depth > depth) {
5683 if (XML_READER_TYPE_ELEMENT == type) {
5684 // We found a deeper start tag; it was not processed at all.
5685 // That is an error (maybe we should report error for all node types
5686 // except TEXT and WHITESPACE, not just ELEMENT).
5687 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TAG,
5688 "Unprocessed XML tag `%s'", (const char *)reader.Name());
5689 }
5690
5691 continue; // go past hoping that our end tag will arrive eventually
5692 }
5693 else if (current_depth == depth) { // at our level
5694 if (XML_READER_TYPE_ELEMENT == type) {
5695 verify_name(reader, p_td, exer);
5696 if (reader.IsEmptyElement()) {
5697 // FIXME this shouldn't really be possible;
5698 // only an empty record should be encoded as an empty element,
5699 // but those are implemented by Empty_Record_Type, not Record_Type.
5700 reader.Read(); // one last time
5701 break;
5702 }
5703 }
5704 // If we find an end tag at the right depth, it must be ours
5705 else if (XML_READER_TYPE_END_ELEMENT == type) {
5706 verify_end(reader, p_td, depth, exer);
5707 reader.Read();
5708 break;
5709 }
5710 }
5711 else { //current_depth < depth; something has gone horribly wrong
5712 break; // better quit before we do further damage
5713 // Don't report an error; every enclosing type would do so,
5714 // spewing the same message over and over.
5715 }
5716 } // next
5717 }
5718 return 1; // decode successful
5719}
5720
3f84031e 5721int Record_Type::JSON_encode(const TTCN_Typedescriptor_t& p_td, JSON_Tokenizer& p_tok) const
970ed795 5722{
3f84031e 5723 if (err_descr) {
5724 return JSON_encode_negtest(err_descr, p_td, p_tok);
5725 }
5726
970ed795
EL
5727 if (!is_bound()) {
5728 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND,
5729 "Encoding an unbound %s value.", is_set() ? "set" : "record");
5730 return -1;
5731 }
5732
5733 int enc_len = p_tok.put_next_token(JSON_TOKEN_OBJECT_START, NULL);
5734
5735 int field_count = get_count();
3f84031e 5736 for (int i = 0; i < field_count; ++i) {
3abe9331 5737 boolean metainfo_unbound = NULL != fld_descr(i)->json && fld_descr(i)->json->metainfo_unbound;
970ed795 5738 if ((NULL != fld_descr(i)->json && fld_descr(i)->json->omit_as_null) ||
3abe9331 5739 get_at(i)->is_present() || metainfo_unbound) {
5740 const char* field_name = (NULL != fld_descr(i)->json && NULL != fld_descr(i)->json->alias) ?
5741 fld_descr(i)->json->alias : fld_name(i);
5742 enc_len += p_tok.put_next_token(JSON_TOKEN_NAME, field_name);
5743 if (metainfo_unbound && !get_at(i)->is_bound()) {
5744 enc_len += p_tok.put_next_token(JSON_TOKEN_LITERAL_NULL);
5745 char* metainfo_str = mprintf("metainfo %s", field_name);
5746 enc_len += p_tok.put_next_token(JSON_TOKEN_NAME, metainfo_str);
5747 Free(metainfo_str);
5748 enc_len += p_tok.put_next_token(JSON_TOKEN_STRING, "\"unbound\"");
5749 }
5750 else {
5751 enc_len += get_at(i)->JSON_encode(*fld_descr(i), p_tok);
970ed795 5752 }
970ed795
EL
5753 }
5754 }
5755
5756 enc_len += p_tok.put_next_token(JSON_TOKEN_OBJECT_END, NULL);
5757 return enc_len;
5758}
5759
3f84031e 5760int Record_Type::JSON_encode_negtest(const Erroneous_descriptor_t* p_err_descr,
5761 const TTCN_Typedescriptor_t& p_td,
5762 JSON_Tokenizer& p_tok) const
5763{
5764 if (!is_bound()) {
5765 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND,
5766 "Encoding an unbound %s value.", is_set() ? "set" : "record");
5767 return -1;
5768 }
5769
5770 int enc_len = p_tok.put_next_token(JSON_TOKEN_OBJECT_START, NULL);
5771
5772 int values_idx = 0;
5773 int edescr_idx = 0;
5774
5775 int field_count = get_count();
5776 for (int i = 0; i < field_count; ++i) {
5777 if (-1 != p_err_descr->omit_before && p_err_descr->omit_before > i) {
5778 continue;
5779 }
5780
5781 const Erroneous_values_t* err_vals = p_err_descr->next_field_err_values(i, values_idx);
5782 const Erroneous_descriptor_t* emb_descr = p_err_descr->next_field_emb_descr(i, edescr_idx);
5783
5784 if (NULL != err_vals && NULL != err_vals->before) {
5785 if (NULL == err_vals->before->errval) {
5786 TTCN_error("internal error: erroneous before value missing");
5787 }
5788 if (err_vals->before->raw) {
5789 enc_len += err_vals->before->errval->JSON_encode_negtest_raw(p_tok);
5790 } else {
5791 if (NULL == err_vals->before->type_descr) {
5792 TTCN_error("internal error: erroneous before typedescriptor missing");
5793 }
5794 // it's an extra field, so use the erroneous type's name as the field name
5795 enc_len += p_tok.put_next_token(JSON_TOKEN_NAME, err_vals->before->type_descr->name);
5796 enc_len += err_vals->before->errval->JSON_encode(*(err_vals->before->type_descr), p_tok);
5797 }
5798 }
5799
5800 const char* field_name = (NULL != fld_descr(i)->json && NULL != fld_descr(i)->json->alias) ?
5801 fld_descr(i)->json->alias : fld_name(i);
5802 if (NULL != err_vals && NULL != err_vals->value) {
5803 if (NULL != err_vals->value->errval) {
5804 if (err_vals->value->raw) {
5805 enc_len += err_vals->value->errval->JSON_encode_negtest_raw(p_tok);
5806 } else {
5807 if (NULL == err_vals->value->type_descr) {
5808 TTCN_error("internal error: erroneous before typedescriptor missing");
5809 }
5810 // only replace the field's value, keep the field name
5811 enc_len += p_tok.put_next_token(JSON_TOKEN_NAME, field_name);
5812 enc_len += err_vals->value->errval->JSON_encode(*(err_vals->value->type_descr), p_tok);
5813 }
5814 }
5815 } else {
5816 boolean metainfo_unbound = NULL != fld_descr(i)->json && fld_descr(i)->json->metainfo_unbound;
5817 if ((NULL != fld_descr(i)->json && fld_descr(i)->json->omit_as_null) ||
5818 get_at(i)->is_present() || metainfo_unbound) {
5819 enc_len += p_tok.put_next_token(JSON_TOKEN_NAME, field_name);
5820 if (metainfo_unbound && !get_at(i)->is_bound()) {
5821 enc_len += p_tok.put_next_token(JSON_TOKEN_LITERAL_NULL);
5822 char* metainfo_str = mprintf("metainfo %s", field_name);
5823 enc_len += p_tok.put_next_token(JSON_TOKEN_NAME, metainfo_str);
5824 Free(metainfo_str);
5825 enc_len += p_tok.put_next_token(JSON_TOKEN_STRING, "\"unbound\"");
5826 }
5827 else if (NULL != emb_descr) {
5828 enc_len += get_at(i)->JSON_encode_negtest(emb_descr, *fld_descr(i), p_tok);
5829 } else {
5830 enc_len += get_at(i)->JSON_encode(*fld_descr(i), p_tok);
5831 }
5832 }
5833 }
5834
5835 if (NULL != err_vals && NULL != err_vals->after) {
5836 if (NULL == err_vals->after->errval) {
5837 TTCN_error("internal error: erroneous after value missing");
5838 }
5839 if (err_vals->after->raw) {
5840 enc_len += err_vals->after->errval->JSON_encode_negtest_raw(p_tok);
5841 } else {
5842 if (NULL == err_vals->after->type_descr) {
5843 TTCN_error("internal error: erroneous before typedescriptor missing");
5844 }
5845 // it's an extra field, so use the erroneous type's name as the field name
5846 enc_len += p_tok.put_next_token(JSON_TOKEN_NAME, err_vals->after->type_descr->name);
5847 enc_len += err_vals->after->errval->JSON_encode(*(err_vals->after->type_descr), p_tok);
5848 }
5849 }
5850
5851 if (-1 != p_err_descr->omit_after && p_err_descr->omit_after <= i) {
5852 break;
5853 }
5854 }
5855
5856 enc_len += p_tok.put_next_token(JSON_TOKEN_OBJECT_END, NULL);
5857 return enc_len;
5858}
5859
970ed795
EL
5860int Record_Type::JSON_decode(const TTCN_Typedescriptor_t& p_td, JSON_Tokenizer& p_tok, boolean p_silent)
5861{
5862 json_token_t token = JSON_TOKEN_NONE;
5863 int dec_len = p_tok.get_next_token(&token, NULL, NULL);
5864 if (JSON_TOKEN_ERROR == token) {
5865 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_BAD_TOKEN_ERROR, "");
5866 return JSON_ERROR_FATAL;
5867 }
5868 else if (JSON_TOKEN_OBJECT_START != token) {
5869 return JSON_ERROR_INVALID_TOKEN;
feade998 5870 }
970ed795
EL
5871
5872 const int field_count = get_count();
5873
3abe9331 5874 // initialize meta info states
5875 int* metainfo = new int[field_count];
feade998 5876 boolean* field_found = new boolean[field_count];
3abe9331 5877 for (int i = 0; i < field_count; ++i) {
feade998 5878 field_found[i] = FALSE;
3abe9331 5879 metainfo[i] = (NULL != fld_descr(i)->json && fld_descr(i)->json->metainfo_unbound) ?
5880 JSON_METAINFO_NONE : JSON_METAINFO_NOT_APPLICABLE;
5881 }
5882
970ed795
EL
5883 while (true) {
5884 // Read name - value token pairs until we reach some other token
5885 char* name = 0;
5886 size_t name_len = 0;
5887 size_t buf_pos = p_tok.get_buf_pos();
5888 dec_len += p_tok.get_next_token(&token, &name, &name_len);
5889 if (JSON_TOKEN_ERROR == token) {
5890 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_BAD_TOKEN_ERROR, "");
5891 return JSON_ERROR_FATAL;
5892 }
5893 else if (JSON_TOKEN_NAME != token) {
5894 // undo the last action on the buffer
5895 p_tok.set_buf_pos(buf_pos);
5896 break;
5897 }
5898 else {
3abe9331 5899 // check for meta info
5900 boolean is_metainfo = FALSE;
5901 if (name_len > 9 && 0 == strncmp(name, "metainfo ", 9)) {
5902 name += 9;
5903 name_len -= 9;
5904 is_metainfo = TRUE;
5905 }
5906
970ed795
EL
5907 // check field name
5908 int field_idx;
5909 for (field_idx = 0; field_idx < field_count; ++field_idx) {
5910 const char* expected_name = 0;
5911 if (NULL != fld_descr(field_idx)->json && NULL != fld_descr(field_idx)->json->alias) {
5912 expected_name = fld_descr(field_idx)->json->alias;
5913 } else {
5914 expected_name = fld_name(field_idx);
5915 }
5916 if (strlen(expected_name) == name_len &&
5917 0 == strncmp(expected_name, name, name_len)) {
feade998 5918 field_found[field_idx] = TRUE;
970ed795
EL
5919 break;
5920 }
5921 }
5922 if (field_count == field_idx) {
5923 // invalid field name
5924 char* name2 = mcopystrn(name, name_len);
3abe9331 5925 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, is_metainfo ?
5926 JSON_DEC_METAINFO_NAME_ERROR : JSON_DEC_INVALID_NAME_ERROR, name2);
970ed795
EL
5927 // if this is set to a warning, skip the value of the field
5928 dec_len += p_tok.get_next_token(&token, NULL, NULL);
5929 if (JSON_TOKEN_NUMBER != token && JSON_TOKEN_STRING != token &&
5930 JSON_TOKEN_LITERAL_TRUE != token && JSON_TOKEN_LITERAL_FALSE != token &&
5931 JSON_TOKEN_LITERAL_NULL != token) {
5932 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_FIELD_TOKEN_ERROR, name2);
5933 Free(name2);
5934 return JSON_ERROR_FATAL;
5935 }
5936 Free(name2);
5937 continue;
5938 }
5939
3abe9331 5940 if (is_metainfo) {
5941 if (JSON_METAINFO_NOT_APPLICABLE != metainfo[field_idx]) {
5942 // check meta info
5943 char* info_value = 0;
5944 size_t info_len = 0;
5945 dec_len += p_tok.get_next_token(&token, &info_value, &info_len);
5946 if (JSON_TOKEN_STRING == token && 9 == info_len &&
5947 0 == strncmp(info_value, "\"unbound\"", 9)) {
5948 metainfo[field_idx] = JSON_METAINFO_UNBOUND;
5949 }
5950 else {
5951 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_METAINFO_VALUE_ERROR,
5952 fld_name(field_idx));
5953 return JSON_ERROR_FATAL;
5954 }
5955 }
5956 else {
5957 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_METAINFO_NOT_APPLICABLE,
5958 fld_name(field_idx));
5959 return JSON_ERROR_FATAL;
970ed795 5960 }
970ed795 5961 }
3abe9331 5962 else {
5963 buf_pos = p_tok.get_buf_pos();
5964 int ret_val = get_at(field_idx)->JSON_decode(*fld_descr(field_idx), p_tok, p_silent);
5965 if (0 > ret_val) {
5966 if (JSON_ERROR_INVALID_TOKEN == ret_val) {
5967 // undo the last action on the buffer, check if the invalid token was a null token
5968 p_tok.set_buf_pos(buf_pos);
5969 p_tok.get_next_token(&token, NULL, NULL);
5970 if (JSON_TOKEN_LITERAL_NULL == token) {
5971 if (JSON_METAINFO_NONE == metainfo[field_idx]) {
5972 // delay reporting an error for now, there might be meta info later
5973 metainfo[field_idx] = JSON_METAINFO_NEEDED;
5974 continue;
5975 }
5976 else if (JSON_METAINFO_UNBOUND == metainfo[field_idx]) {
5977 // meta info already found
5978 continue;
5979 }
5980 }
5981 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_FIELD_TOKEN_ERROR, fld_name(field_idx));
5982 }
5983 return JSON_ERROR_FATAL;
5984 }
5985 dec_len += ret_val;
5986 }
970ed795
EL
5987 }
5988 }
5989
5990 dec_len += p_tok.get_next_token(&token, NULL, NULL);
5991 if (JSON_TOKEN_OBJECT_END != token) {
5992 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_OBJECT_END_TOKEN_ERROR, "");
5993 return JSON_ERROR_FATAL;
5994 }
5995
3abe9331 5996 // Check if every field has been set and handle meta info
970ed795
EL
5997 for (int field_idx = 0; field_idx < field_count; ++field_idx) {
5998 Base_Type* field = get_at(field_idx);
3abe9331 5999 if (JSON_METAINFO_UNBOUND == metainfo[field_idx]) {
6000 field->clean_up();
6001 }
6002 else if (JSON_METAINFO_NEEDED == metainfo[field_idx]) {
6003 // no meta info was found for this field, report the delayed error
6004 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_FIELD_TOKEN_ERROR, fld_name(field_idx));
6005 }
feade998 6006 else if (!field_found[field_idx]) {
970ed795
EL
6007 if (NULL != fld_descr(field_idx)->json && NULL != fld_descr(field_idx)->json->default_value) {
6008 get_at(field_idx)->JSON_decode(*fld_descr(field_idx), DUMMY_BUFFER, p_silent);
6009 }
6010 else if (field->is_optional()) {
6011 field->set_to_omit();
6012 } else {
6013 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_MISSING_FIELD_ERROR, fld_name(field_idx));
6014 return JSON_ERROR_FATAL;
6015 }
6016 }
6017 }
6018
86be9305 6019 delete[] metainfo;
3abe9331 6020
970ed795
EL
6021 return dec_len;
6022}
6023
6024////////////////////////////////////////////////////////////////////////////////
6025
6026Empty_Record_Type::Empty_Record_Type(): bound_flag(FALSE)
6027{
6028}
6029
6030Empty_Record_Type::Empty_Record_Type(const Empty_Record_Type& other_value)
6031: Base_Type(other_value), bound_flag(other_value.bound_flag)
6032{
6033 if (!other_value.bound_flag)
6034 TTCN_error("Copying an unbound value of type %s.",
6035 other_value.get_descriptor()->name);
6036}
6037
6038boolean Empty_Record_Type::operator==(null_type) const
6039{
6040 if (!bound_flag)
6041 TTCN_error("Comparison of an unbound value of type %s.",
6042 get_descriptor()->name);
6043 return TRUE;
6044}
6045
6046void Empty_Record_Type::log() const
6047{
6048 if (bound_flag) TTCN_Logger::log_event_str("{ }");
6049 else TTCN_Logger::log_event_unbound();
6050}
6051
6052void Empty_Record_Type::set_param(Module_Param& param) {
6053 param.basic_check(Module_Param::BC_VALUE, "empty record/set value (i.e. { })");
3abe9331 6054 Module_Param_Ptr mp = &param;
6055 if (param.get_type() == Module_Param::MP_Reference) {
6056 mp = param.get_referenced_param();
6057 }
6058 if (mp->get_type()!=Module_Param::MP_Value_List || mp->get_size()>0) {
970ed795
EL
6059 param.type_error("empty record/set value (i.e. { })", get_descriptor()->name);
6060 }
6061 bound_flag = TRUE;
6062}
6063
3abe9331 6064Module_Param* Empty_Record_Type::get_param(Module_Param_Name& /* param_name */) const
6065{
6066 if (!is_bound()) {
6067 return new Module_Param_Unbound();
6068 }
6069 return new Module_Param_Value_List();
6070}
6071
970ed795
EL
6072void Empty_Record_Type::encode_text(Text_Buf& /*text_buf*/) const
6073{
6074 if (!bound_flag)
6075 TTCN_error("Text encoder: Encoding an unbound value of type %s.",
6076 get_descriptor()->name);
6077}
6078
6079void Empty_Record_Type::decode_text(Text_Buf& /*text_buf*/)
6080{
6081 bound_flag = TRUE;
6082}
6083
6084boolean Empty_Record_Type::is_equal(const Base_Type* other_value) const
6085{
6086 const Empty_Record_Type* r2 = static_cast<const Empty_Record_Type*>(other_value);
6087 if ((bound_flag && r2->bound_flag) || (!bound_flag && !r2->bound_flag))
6088 return TRUE;
6089 if (!bound_flag || !r2->bound_flag)
6090 TTCN_error("Comparison of an unbound value of type %s.", get_descriptor()->name);
6091 return FALSE;
6092}
6093
6094void Empty_Record_Type::set_value(const Base_Type* other_value)
6095{
6096 if (!static_cast<const Empty_Record_Type*>(other_value)->is_bound())
6097 TTCN_error("Assignment of an unbound value of type %s.",
6098 other_value->get_descriptor()->name);
6099 bound_flag = TRUE;
6100}
6101
6102void Empty_Record_Type::encode(const TTCN_Typedescriptor_t& p_td,
6103 TTCN_Buffer& p_buf, TTCN_EncDec::coding_t p_coding, ...) const
6104{
6105 va_list pvar;
6106 va_start(pvar, p_coding);
6107 switch(p_coding) {
6108 case TTCN_EncDec::CT_BER: {
6109 TTCN_EncDec_ErrorContext ec("While BER-encoding type '%s': ", p_td.name);
6110 unsigned BER_coding=va_arg(pvar, unsigned);
6111 BER_encode_chk_coding(BER_coding);
6112 ASN_BER_TLV_t *tlv=BER_encode_TLV(p_td, BER_coding);
6113 tlv->put_in_buffer(p_buf);
6114 ASN_BER_TLV_t::destruct(tlv);
6115 break;}
6116 case TTCN_EncDec::CT_RAW: {
6117 TTCN_EncDec_ErrorContext ec("While RAW-encoding type '%s': ", p_td.name);
6118 if(!p_td.raw) TTCN_EncDec_ErrorContext::error_internal
6119 ("No RAW descriptor available for type '%s'.", p_td.name);
6120 RAW_enc_tr_pos rp;
6121 rp.level=0;
6122 rp.pos=NULL;
6123 RAW_enc_tree root(FALSE, NULL, &rp, 1, p_td.raw);
6124 RAW_encode(p_td, root);
6125 root.put_to_buf(p_buf);
6126 break;}
6127 case TTCN_EncDec::CT_TEXT: {
6128 TTCN_EncDec_ErrorContext ec("While TEXT-encoding type '%s': ", p_td.name);
6129 if(!p_td.text) TTCN_EncDec_ErrorContext::error_internal
6130 ("No TEXT descriptor available for type '%s'.", p_td.name);
6131 TEXT_encode(p_td,p_buf);
6132 break;}
6133 case TTCN_EncDec::CT_XER: {
6134 TTCN_EncDec_ErrorContext ec("While XER-encoding type '%s': ", p_td.name);
6135 unsigned XER_coding=va_arg(pvar, unsigned);
af710487 6136 XER_encode(*(p_td.xer),p_buf, XER_coding, 0, 0);
970ed795
EL
6137 p_buf.put_c('\n');
6138 break;}
6139 case TTCN_EncDec::CT_JSON: {
6140 TTCN_EncDec_ErrorContext ec("While JSON-encoding type '%s': ", p_td.name);
6141 if(!p_td.json) TTCN_EncDec_ErrorContext::error_internal
6142 ("No JSON descriptor available for type '%s'.", p_td.name);
6143 JSON_Tokenizer tok(va_arg(pvar, int) != 0);
6144 JSON_encode(p_td, tok);
6145 p_buf.put_s(tok.get_buffer_length(), (const unsigned char*)tok.get_buffer());
6146 break;}
6147 default:
6148 TTCN_error("Unknown coding method requested to encode type '%s'", p_td.name);
6149 }
6150 va_end(pvar);
6151}
6152
6153void Empty_Record_Type::decode(const TTCN_Typedescriptor_t& p_td,
6154 TTCN_Buffer& p_buf, TTCN_EncDec::coding_t p_coding, ...)
6155{
6156 va_list pvar;
6157 va_start(pvar, p_coding);
6158 switch(p_coding) {
6159 case TTCN_EncDec::CT_BER: {
6160 TTCN_EncDec_ErrorContext ec("While BER-decoding type '%s': ", p_td.name);
6161 unsigned L_form=va_arg(pvar, unsigned);
6162 ASN_BER_TLV_t tlv;
6163 BER_decode_str2TLV(p_buf, tlv, L_form);
6164 BER_decode_TLV(p_td, tlv, L_form);
6165 if(tlv.isComplete) p_buf.increase_pos(tlv.get_len());
6166 break;}
6167 case TTCN_EncDec::CT_RAW: {
6168 TTCN_EncDec_ErrorContext ec("While RAW-decoding type '%s': ", p_td.name);
6169 if(!p_td.raw)
6170 TTCN_EncDec_ErrorContext::error_internal
6171 ("No RAW descriptor available for type '%s'.", p_td.name);
6172 raw_order_t order;
6173 switch(p_td.raw->top_bit_order) {
6174 case TOP_BIT_LEFT:
6175 order=ORDER_LSB;
6176 break;
6177 case TOP_BIT_RIGHT:
6178 default:
6179 order=ORDER_MSB;
6180 }
6181 if(RAW_decode(p_td, p_buf, p_buf.get_len()*8, order)<0)
6182 ec.error(TTCN_EncDec::ET_INCOMPL_MSG,
6183 "Can not decode type '%s', because invalid or incomplete"
6184 " message was received", p_td.name);
6185 break;}
6186 case TTCN_EncDec::CT_TEXT: {
6187 Limit_Token_List limit;
6188 TTCN_EncDec_ErrorContext ec("While TEXT-decoding type '%s': ", p_td.name);
6189 if(!p_td.text) TTCN_EncDec_ErrorContext::error_internal
6190 ("No TEXT descriptor available for type '%s'.", p_td.name);
6191 const unsigned char *b=p_buf.get_data();
6192 if(b[p_buf.get_len()-1]!='\0'){
6193 p_buf.set_pos(p_buf.get_len());
6194 p_buf.put_zero(8,ORDER_LSB);
6195 p_buf.rewind();
6196 }
6197 if(TEXT_decode(p_td,p_buf,limit)<0)
6198 ec.error(TTCN_EncDec::ET_INCOMPL_MSG,
6199 "Can not decode type '%s', because invalid or incomplete"
6200 " message was received", p_td.name);
6201 break;}
6202 case TTCN_EncDec::CT_XER: {
6203 TTCN_EncDec_ErrorContext ec("While XER-decoding type '%s': ", p_td.name);
6204 unsigned XER_coding=va_arg(pvar, unsigned);
6205 XmlReaderWrap reader(p_buf);
6206 for (int success=reader.Read(); success==1; success=reader.Read()) {
6207 if (reader.NodeType() == XML_READER_TYPE_ELEMENT) break;
6208 }
feade998 6209 XER_decode(*(p_td.xer), reader, XER_coding | XER_TOPLEVEL, XER_NONE, 0);
970ed795
EL
6210 size_t bytes = reader.ByteConsumed();
6211 p_buf.set_pos(bytes);
6212 break;}
6213 case TTCN_EncDec::CT_JSON: {
6214 TTCN_EncDec_ErrorContext ec("While JSON-decoding type '%s': ", p_td.name);
6215 if(!p_td.json) TTCN_EncDec_ErrorContext::error_internal
6216 ("No JSON descriptor available for type '%s'.", p_td.name);
6217 JSON_Tokenizer tok((const char*)p_buf.get_data(), p_buf.get_len());
6218 if(JSON_decode(p_td, tok, false)<0)
6219 ec.error(TTCN_EncDec::ET_INCOMPL_MSG,
6220 "Can not decode type '%s', because invalid or incomplete"
6221 " message was received", p_td.name);
6222 p_buf.set_pos(tok.get_buf_pos());
6223 break;}
6224 default:
6225 TTCN_error("Unknown coding method requested to decode type '%s'", p_td.name);
6226 }
6227 va_end(pvar);
6228}
6229
6230ASN_BER_TLV_t* Empty_Record_Type::BER_encode_TLV(const TTCN_Typedescriptor_t& p_td,
6231 unsigned p_coding) const
6232{
6233 BER_chk_descr(p_td);
6234 ASN_BER_TLV_t *new_tlv=ASN_BER_TLV_t::construct(NULL);
6235 new_tlv=ASN_BER_V2TLV(new_tlv, p_td, p_coding);
6236 return new_tlv;
6237}
6238
6239boolean Empty_Record_Type::BER_decode_TLV(const TTCN_Typedescriptor_t& p_td,
6240 const ASN_BER_TLV_t& p_tlv, unsigned L_form)
6241{
6242 BER_chk_descr(p_td);
6243 ASN_BER_TLV_t stripped_tlv;
6244 BER_decode_strip_tags(*p_td.ber, p_tlv, L_form, stripped_tlv);
6245 TTCN_EncDec_ErrorContext ec_0("While decoding '%s' type: ", get_descriptor()->name);
6246 stripped_tlv.chk_constructed_flag(TRUE);
6247 bound_flag=TRUE;
6248 return TRUE;
6249}
6250
6251int Empty_Record_Type::RAW_encode(const TTCN_Typedescriptor_t& p_td,
6252 RAW_enc_tree& /*myleaf*/) const
6253{
6254 if (!bound_flag) TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND,
6255 "Encoding an unbound value of type %s.", p_td.name);
6256 return 0;
6257}
6258
6259int Empty_Record_Type::RAW_decode(const TTCN_Typedescriptor_t& p_td,
6260 TTCN_Buffer& buff, int /*limit*/, raw_order_t /*top_bit_ord*/,
6261 boolean /*no_err*/, int /*sel_field*/, boolean /*first_call*/)
6262{
6263 bound_flag = TRUE;
6264 return buff.increase_pos_padd(p_td.raw->prepadding)
6265 + buff.increase_pos_padd(p_td.raw->padding);
6266}
6267
6268int Empty_Record_Type::TEXT_encode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& buff) const
6269{
6270 int encoded_length=0;
6271 if(p_td.text->begin_encode) {
6272 buff.put_cs(*p_td.text->begin_encode);
6273 encoded_length+=p_td.text->begin_encode->lengthof();
6274 }
6275 if (!bound_flag) {
6276 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND, "Encoding an unbound value.");
6277 }
6278 if(p_td.text->end_encode) {
6279 buff.put_cs(*p_td.text->end_encode);
6280 encoded_length+=p_td.text->end_encode->lengthof();
6281 }
6282 return encoded_length;
6283}
6284
6285int Empty_Record_Type::TEXT_decode(const TTCN_Typedescriptor_t& p_td,
6286 TTCN_Buffer& buff, Limit_Token_List& /*limit*/, boolean no_err, boolean /*first_call*/)
6287{
6288 int decoded_length=0;
6289 if(p_td.text->begin_decode) {
6290 int tl;
6291 if((tl=p_td.text->begin_decode->match_begin(buff))<0) {
6292 if(no_err)return -1;
6293 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR,
6294 "The specified token '%s' not found for '%s': ",
6295 (const char*)*(p_td.text->begin_decode), p_td.name);
6296 return 0;
6297 }
6298 decoded_length+=tl;
6299 buff.increase_pos(tl);
6300 }
6301 if(p_td.text->end_decode) {
6302 int tl;
6303 if((tl=p_td.text->end_decode->match_begin(buff))<0) {
6304 if(no_err)return -1;
6305 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR,
6306 "The specified token '%s' not found for '%s': ",
6307 (const char*)*(p_td.text->end_decode), p_td.name);
6308 return 0;
6309 }
6310 decoded_length+=tl;
6311 buff.increase_pos(tl);
6312 }
6313 bound_flag = TRUE;
6314 return decoded_length;
6315}
6316
6317int Empty_Record_Type::XER_encode(const XERdescriptor_t& p_td,
af710487 6318 TTCN_Buffer& p_buf, unsigned int flavor, int indent, embed_values_enc_struct_t*) const
970ed795
EL
6319{
6320 int encoded_length=(int)p_buf.get_len();
6321 int indenting = !is_canonical(flavor);
6322 int exer = is_exer(flavor);
6323 if (indenting) do_indent(p_buf, indent);
6324 p_buf.put_c('<');
6325 if (exer) write_ns_prefix(p_td, p_buf);
6326 p_buf.put_s((size_t)p_td.namelens[exer]-2, (cbyte*)p_td.names[exer]);
6327 p_buf.put_s(2 + indenting, (cbyte*)"/>\n");
6328 return (int)p_buf.get_len() - encoded_length;
6329}
6330
6331int Empty_Record_Type::XER_decode(const XERdescriptor_t& p_td,
feade998 6332 XmlReaderWrap& reader, unsigned int flavor, unsigned int /*flavor2*/, embed_values_dec_struct_t*)
970ed795
EL
6333{
6334 int exer = is_exer(flavor);
6335 bound_flag = true;
6336 int success, depth = -1;
6337 for (success=reader.Ok(); success==1; success=reader.Read()) {
6338 int type = reader.NodeType();
6339 if (type==XML_READER_TYPE_ELEMENT) {
6340 verify_name(reader, p_td, exer);
6341 depth = reader.Depth();
6342
6343 if (reader.IsEmptyElement()) {
6344 reader.Read(); break;
6345 }
6346 else if ((flavor & XER_MASK) == XER_CANONICAL) {
6347 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG,
6348 "Expected an empty element tag");
6349 // Stay in the loop and look for the end element, in case the error
6350 // was ignored or reduced to warning.
6351 } // if(empty)
6352 }
6353 else if (type == XML_READER_TYPE_END_ELEMENT && depth != -1) {
6354 verify_end(reader, p_td, depth, exer);
6355 reader.Read();
6356 break;
6357 }
6358 }
6359 return 1; // decode successful
6360}
6361
6362int Empty_Record_Type::JSON_encode(const TTCN_Typedescriptor_t&, JSON_Tokenizer& p_tok) const
6363{
6364 if (!is_bound()) {
6365 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND,
6366 "Encoding an unbound empty %s value.", is_set() ? "set" : "record");
6367 return -1;
6368 }
6369
6370 return p_tok.put_next_token(JSON_TOKEN_OBJECT_START, NULL) +
6371 p_tok.put_next_token(JSON_TOKEN_OBJECT_END, NULL);
6372}
6373
6374int Empty_Record_Type::JSON_decode(const TTCN_Typedescriptor_t&, JSON_Tokenizer& p_tok, boolean p_silent)
6375{
6376 json_token_t token = JSON_TOKEN_NONE;
6377 int dec_len = p_tok.get_next_token(&token, NULL, NULL);
6378 if (JSON_TOKEN_ERROR == token) {
6379 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_BAD_TOKEN_ERROR, "");
6380 return JSON_ERROR_FATAL;
6381 }
6382 else if (JSON_TOKEN_OBJECT_START != token) {
6383 return JSON_ERROR_INVALID_TOKEN;
6384 }
6385
6386 dec_len += p_tok.get_next_token(&token, NULL, NULL);
6387 if (JSON_TOKEN_OBJECT_END != token) {
6388 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_STATIC_OBJECT_END_TOKEN_ERROR, "");
6389 return JSON_ERROR_FATAL;
6390 }
6391
6392 bound_flag = true;
6393
6394 return dec_len;
6395}
6396
6397boolean operator==(null_type /*null_value*/, const Empty_Record_Type& other_value)
6398{
6399 if (!other_value.is_bound())
6400 TTCN_error("Comparison of an unbound value of type %s.",
6401 other_value.get_descriptor()->name);
6402 return TRUE;
6403}
6404
6405boolean operator!=(null_type /*null_value*/, const Empty_Record_Type& other_value)
6406{
6407 if (!other_value.is_bound())
6408 TTCN_error("Comparison of an unbound value of type %s.",
6409 other_value.get_descriptor()->name);
6410 return FALSE;
6411}
6412#endif
This page took 0.276823 seconds and 5 git commands to generate.