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