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