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