Sync with 5.4.3
[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 if (NULL != p_td.json && p_td.json->metainfo_unbound && !get_at(i)->is_bound()) {
1454 // unbound elements are encoded as { "metainfo []" : "unbound" }
1455 enc_len += p_tok.put_next_token(JSON_TOKEN_OBJECT_START, NULL);
1456 enc_len += p_tok.put_next_token(JSON_TOKEN_NAME, "metainfo []");
1457 enc_len += p_tok.put_next_token(JSON_TOKEN_STRING, "\"unbound\"");
1458 enc_len += p_tok.put_next_token(JSON_TOKEN_OBJECT_END, NULL);
1459 }
1460 else {
1461 int ret_val = get_at(i)->JSON_encode(*p_td.oftype_descr, p_tok);
1462 if (0 > ret_val) break;
1463 enc_len += ret_val;
1464 }
1465 }
1466
1467 enc_len += p_tok.put_next_token(JSON_TOKEN_ARRAY_END, NULL);
1468 return enc_len;
1469 }
1470
1471 int Record_Of_Type::JSON_encode_negtest(const Erroneous_descriptor_t* p_err_descr,
1472 const TTCN_Typedescriptor_t& p_td,
1473 JSON_Tokenizer& p_tok) const
1474 {
1475 if (!is_bound()) {
1476 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND,
1477 "Encoding an unbound %s of value.", is_set() ? "set" : "record");
1478 return -1;
1479 }
1480
1481 int enc_len = p_tok.put_next_token(JSON_TOKEN_ARRAY_START, NULL);
1482
1483 int values_idx = 0;
1484 int edescr_idx = 0;
1485
1486 for (int i = 0; i < get_nof_elements(); ++i) {
1487 if (-1 != p_err_descr->omit_before && p_err_descr->omit_before > i) {
1488 continue;
1489 }
1490
1491 const Erroneous_values_t* err_vals = p_err_descr->next_field_err_values(i, values_idx);
1492 const Erroneous_descriptor_t* emb_descr = p_err_descr->next_field_emb_descr(i, edescr_idx);
1493
1494 if (NULL != err_vals && NULL != err_vals->before) {
1495 if (NULL == err_vals->before->errval) {
1496 TTCN_error("internal error: erroneous before value missing");
1497 }
1498 if (err_vals->before->raw) {
1499 enc_len += err_vals->before->errval->JSON_encode_negtest_raw(p_tok);
1500 } else {
1501 if (NULL == err_vals->before->type_descr) {
1502 TTCN_error("internal error: erroneous before typedescriptor missing");
1503 }
1504 enc_len += err_vals->before->errval->JSON_encode(*(err_vals->before->type_descr), p_tok);
1505 }
1506 }
1507
1508 if (NULL != err_vals && NULL != err_vals->value) {
1509 if (NULL != err_vals->value->errval) {
1510 if (err_vals->value->raw) {
1511 enc_len += err_vals->value->errval->JSON_encode_negtest_raw(p_tok);
1512 } else {
1513 if (NULL == err_vals->value->type_descr) {
1514 TTCN_error("internal error: erroneous before typedescriptor missing");
1515 }
1516 enc_len += err_vals->value->errval->JSON_encode(*(err_vals->value->type_descr), p_tok);
1517 }
1518 }
1519 }
1520 else if (NULL != p_td.json && p_td.json->metainfo_unbound && !get_at(i)->is_bound()) {
1521 // unbound elements are encoded as { "metainfo []" : "unbound" }
1522 enc_len += p_tok.put_next_token(JSON_TOKEN_OBJECT_START, NULL);
1523 enc_len += p_tok.put_next_token(JSON_TOKEN_NAME, "metainfo []");
1524 enc_len += p_tok.put_next_token(JSON_TOKEN_STRING, "\"unbound\"");
1525 enc_len += p_tok.put_next_token(JSON_TOKEN_OBJECT_END, NULL);
1526 }
1527 else {
1528 int ret_val;
1529 if (NULL != emb_descr) {
1530 ret_val = get_at(i)->JSON_encode_negtest(emb_descr, *p_td.oftype_descr, p_tok);
1531 } else {
1532 ret_val = get_at(i)->JSON_encode(*p_td.oftype_descr, p_tok);
1533 }
1534 if (0 > ret_val) break;
1535 enc_len += ret_val;
1536 }
1537
1538 if (NULL != err_vals && NULL != err_vals->after) {
1539 if (NULL == err_vals->after->errval) {
1540 TTCN_error("internal error: erroneous after value missing");
1541 }
1542 if (err_vals->after->raw) {
1543 enc_len += err_vals->after->errval->JSON_encode_negtest_raw(p_tok);
1544 } else {
1545 if (NULL == err_vals->after->type_descr) {
1546 TTCN_error("internal error: erroneous before typedescriptor missing");
1547 }
1548 enc_len += err_vals->after->errval->JSON_encode(*(err_vals->after->type_descr), p_tok);
1549 }
1550 }
1551
1552 if (-1 != p_err_descr->omit_after && p_err_descr->omit_after <= i) {
1553 break;
1554 }
1555 }
1556
1557 enc_len += p_tok.put_next_token(JSON_TOKEN_ARRAY_END, NULL);
1558 return enc_len;
1559 }
1560
1561 int Record_Of_Type::JSON_decode(const TTCN_Typedescriptor_t& p_td, JSON_Tokenizer& p_tok, boolean p_silent)
1562 {
1563 json_token_t token = JSON_TOKEN_NONE;
1564 int dec_len = p_tok.get_next_token(&token, NULL, NULL);
1565 if (JSON_TOKEN_ERROR == token) {
1566 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_BAD_TOKEN_ERROR, "");
1567 return JSON_ERROR_FATAL;
1568 }
1569 else if (JSON_TOKEN_ARRAY_START != token) {
1570 return JSON_ERROR_INVALID_TOKEN;
1571 }
1572
1573 set_size(0);
1574 for (int nof_elements = 0; true; ++nof_elements) {
1575 // Read value tokens until we reach some other token
1576 size_t buf_pos = p_tok.get_buf_pos();
1577 int ret_val;
1578 if (NULL != p_td.json && p_td.json->metainfo_unbound) {
1579 // check for metainfo object
1580 ret_val = p_tok.get_next_token(&token, NULL, NULL);
1581 if (JSON_TOKEN_OBJECT_START == token) {
1582 char* value = NULL;
1583 size_t value_len = 0;
1584 ret_val += p_tok.get_next_token(&token, &value, &value_len);
1585 if (JSON_TOKEN_NAME == token && 11 == value_len &&
1586 0 == strncmp(value, "metainfo []", 11)) {
1587 ret_val += p_tok.get_next_token(&token, &value, &value_len);
1588 if (JSON_TOKEN_STRING == token && 9 == value_len &&
1589 0 == strncmp(value, "\"unbound\"", 9)) {
1590 ret_val = p_tok.get_next_token(&token, NULL, NULL);
1591 if (JSON_TOKEN_OBJECT_END == token) {
1592 dec_len += ret_val;
1593 continue;
1594 }
1595 }
1596 }
1597 }
1598 // metainfo object not found, jump back and let the element type decode it
1599 p_tok.set_buf_pos(buf_pos);
1600 }
1601 Base_Type* val = create_elem();
1602 ret_val = val->JSON_decode(*p_td.oftype_descr, p_tok, p_silent);
1603 if (JSON_ERROR_INVALID_TOKEN == ret_val) {
1604 // undo the last action on the buffer
1605 p_tok.set_buf_pos(buf_pos);
1606 delete val;
1607 break;
1608 }
1609 else if (JSON_ERROR_FATAL == ret_val) {
1610 delete val;
1611 if (p_silent) {
1612 clean_up();
1613 }
1614 return JSON_ERROR_FATAL;
1615 }
1616 if (NULL == refd_ind_ptr) {
1617 val_ptr->value_elements = (Base_Type**)reallocate_pointers(
1618 (void**)val_ptr->value_elements, val_ptr->n_elements, nof_elements + 1);
1619 val_ptr->value_elements[nof_elements] = val;
1620 val_ptr->n_elements = nof_elements + 1;
1621 }
1622 else {
1623 get_at(nof_elements)->set_value(val);
1624 delete val;
1625 }
1626 dec_len += ret_val;
1627 }
1628
1629 dec_len += p_tok.get_next_token(&token, NULL, NULL);
1630 if (JSON_TOKEN_ARRAY_END != token) {
1631 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_REC_OF_END_TOKEN_ERROR, "");
1632 if (p_silent) {
1633 clean_up();
1634 }
1635 return JSON_ERROR_FATAL;
1636 }
1637
1638 return dec_len;
1639 }
1640
1641 void Record_Of_Type::encode(const TTCN_Typedescriptor_t& p_td,
1642 TTCN_Buffer& p_buf, TTCN_EncDec::coding_t p_coding, ...) const
1643 {
1644 va_list pvar;
1645 va_start(pvar, p_coding);
1646 switch(p_coding) {
1647 case TTCN_EncDec::CT_BER: {
1648 TTCN_EncDec_ErrorContext ec("While BER-encoding type '%s': ", p_td.name);
1649 unsigned BER_coding=va_arg(pvar, unsigned);
1650 BER_encode_chk_coding(BER_coding);
1651 ASN_BER_TLV_t *tlv=BER_encode_TLV(p_td, BER_coding);
1652 tlv->put_in_buffer(p_buf);
1653 ASN_BER_TLV_t::destruct(tlv);
1654 break;}
1655 case TTCN_EncDec::CT_RAW: {
1656 TTCN_EncDec_ErrorContext ec("While RAW-encoding type '%s': ", p_td.name);
1657 if (!p_td.raw)
1658 TTCN_EncDec_ErrorContext::error_internal("No RAW descriptor available for type '%s'.", p_td.name);
1659 RAW_enc_tr_pos rp;
1660 rp.level = 0;
1661 rp.pos = NULL;
1662 RAW_enc_tree root(FALSE, NULL, &rp, 1, p_td.raw);
1663 RAW_encode(p_td, root);
1664 root.put_to_buf(p_buf);
1665 break; }
1666 case TTCN_EncDec::CT_TEXT: {
1667 TTCN_EncDec_ErrorContext ec("While TEXT-encoding type '%s': ", p_td.name);
1668 if(!p_td.text) TTCN_EncDec_ErrorContext::error_internal
1669 ("No TEXT descriptor available for type '%s'.", p_td.name);
1670 TEXT_encode(p_td,p_buf);
1671 break;}
1672 case TTCN_EncDec::CT_XER: {
1673 TTCN_EncDec_ErrorContext ec("While XER-encoding type '%s': ", p_td.name);
1674 unsigned XER_coding=va_arg(pvar, unsigned);
1675 XER_encode(*(p_td.xer),p_buf, XER_coding, 0, 0);
1676 p_buf.put_c('\n');
1677 break;}
1678 case TTCN_EncDec::CT_JSON: {
1679 TTCN_EncDec_ErrorContext ec("While JSON-encoding type '%s': ", p_td.name);
1680 if(!p_td.json) TTCN_EncDec_ErrorContext::error_internal
1681 ("No JSON descriptor available for type '%s'.", p_td.name);
1682 JSON_Tokenizer tok(va_arg(pvar, int) != 0);
1683 JSON_encode(p_td, tok);
1684 p_buf.put_s(tok.get_buffer_length(), (const unsigned char*)tok.get_buffer());
1685 break;}
1686 default:
1687 TTCN_error("Unknown coding method requested to encode type '%s'", p_td.name);
1688 }
1689 va_end(pvar);
1690 }
1691
1692 void Record_Of_Type::decode(const TTCN_Typedescriptor_t& p_td,
1693 TTCN_Buffer& p_buf, TTCN_EncDec::coding_t p_coding, ...)
1694 {
1695 va_list pvar;
1696 va_start(pvar, p_coding);
1697 switch(p_coding) {
1698 case TTCN_EncDec::CT_BER: {
1699 TTCN_EncDec_ErrorContext ec("While BER-decoding type '%s': ", p_td.name);
1700 unsigned L_form=va_arg(pvar, unsigned);
1701 ASN_BER_TLV_t tlv;
1702 BER_decode_str2TLV(p_buf, tlv, L_form);
1703 BER_decode_TLV(p_td, tlv, L_form);
1704 if(tlv.isComplete) p_buf.increase_pos(tlv.get_len());
1705 break;}
1706 case TTCN_EncDec::CT_RAW: {
1707 TTCN_EncDec_ErrorContext ec("While RAW-decoding type '%s': ", p_td.name);
1708 if(!p_td.raw) TTCN_EncDec_ErrorContext::error_internal
1709 ("No RAW descriptor available for type '%s'.", p_td.name);
1710 raw_order_t order;
1711 switch(p_td.raw->top_bit_order) {
1712 case TOP_BIT_LEFT:
1713 order=ORDER_LSB;
1714 break;
1715 case TOP_BIT_RIGHT:
1716 default:
1717 order=ORDER_MSB;
1718 }
1719 if(RAW_decode(p_td, p_buf, p_buf.get_len()*8, order)<0)
1720 ec.error(TTCN_EncDec::ET_INCOMPL_MSG,"Can not decode type '%s', "
1721 "because invalid or incomplete message was received", p_td.name);
1722 break;}
1723 case TTCN_EncDec::CT_TEXT: {
1724 Limit_Token_List limit;
1725 TTCN_EncDec_ErrorContext ec("While TEXT-decoding type '%s': ", p_td.name);
1726 if(!p_td.text) TTCN_EncDec_ErrorContext::error_internal
1727 ("No TEXT descriptor available for type '%s'.", p_td.name);
1728 const unsigned char *b=p_buf.get_data();
1729 if(b[p_buf.get_len()-1]!='\0'){
1730 p_buf.set_pos(p_buf.get_len());
1731 p_buf.put_zero(8,ORDER_LSB);
1732 p_buf.rewind();
1733 }
1734 if(TEXT_decode(p_td,p_buf,limit)<0)
1735 ec.error(TTCN_EncDec::ET_INCOMPL_MSG,"Can not decode type '%s', "
1736 "because invalid or incomplete message was received", p_td.name);
1737 break;}
1738 case TTCN_EncDec::CT_XER: {
1739 TTCN_EncDec_ErrorContext ec("While XER-decoding type '%s': ", p_td.name);
1740 unsigned XER_coding=va_arg(pvar, unsigned);
1741 XmlReaderWrap reader(p_buf);
1742 for (int success=reader.Read(); success==1; success=reader.Read()) {
1743 if (reader.NodeType() == XML_READER_TYPE_ELEMENT) break;
1744 }
1745 XER_decode(*(p_td.xer), reader, XER_coding | XER_TOPLEVEL, XER_NONE, 0);
1746 size_t bytes = reader.ByteConsumed();
1747 p_buf.set_pos(bytes);
1748 break;}
1749 case TTCN_EncDec::CT_JSON: {
1750 TTCN_EncDec_ErrorContext ec("While JSON-decoding type '%s': ", p_td.name);
1751 if(!p_td.json) TTCN_EncDec_ErrorContext::error_internal
1752 ("No JSON descriptor available for type '%s'.", p_td.name);
1753 JSON_Tokenizer tok((const char*)p_buf.get_data(), p_buf.get_len());
1754 if(JSON_decode(p_td, tok, false)<0)
1755 ec.error(TTCN_EncDec::ET_INCOMPL_MSG,"Can not decode type '%s', "
1756 "because invalid or incomplete message was received", p_td.name);
1757 p_buf.set_pos(tok.get_buf_pos());
1758 break;}
1759 default:
1760 TTCN_error("Unknown coding method requested to decode type '%s'", p_td.name);
1761 }
1762 va_end(pvar);
1763 }
1764
1765 char **Record_Of_Type::collect_ns(const XERdescriptor_t& p_td, size_t& num, bool& def_ns) const
1766 {
1767 size_t num_collected = 0;
1768 // First, our own namespace. Sets num_collected to 0 or 1.
1769 // If it throws, nothing was allocated.
1770 char **collected_ns = Base_Type::collect_ns(p_td, num_collected, def_ns);
1771
1772 // Then the embedded type
1773 try {
1774 bool def_ns_1 = false;
1775 if (val_ptr) for (int i = 0; i < get_nof_elements(); ++i) {
1776 size_t num_new = 0;
1777 char **new_namespaces = get_at(i)->collect_ns(
1778 *p_td.oftype_descr, num_new, def_ns_1);
1779 merge_ns(collected_ns, num_collected, new_namespaces, num_new);
1780 def_ns = def_ns || def_ns_1; // alas, no ||=
1781 }
1782 }
1783 catch (...) {
1784 // Probably a TC_Error thrown from the element's collect_ns(),
1785 // e.g. if encoding an unbound value.
1786 while (num_collected > 0) Free(collected_ns[--num_collected]);
1787 Free(collected_ns);
1788 throw;
1789 }
1790
1791 num = num_collected;
1792 return collected_ns;
1793 }
1794
1795 static const universal_char sp = { 0,0,0,' ' };
1796 static const universal_char tb = { 0,0,0,9 };
1797
1798 int Record_Of_Type::XER_encode(const XERdescriptor_t& p_td, TTCN_Buffer& p_buf,
1799 unsigned int flavor, int indent, embed_values_enc_struct_t* emb_val) const
1800 {
1801 if (err_descr) {
1802 return XER_encode_negtest(err_descr, p_td, p_buf, flavor, indent, emb_val);
1803 }
1804
1805 if (val_ptr == 0) TTCN_error(
1806 "Attempt to XER-encode an unbound record of type %s", get_descriptor()->name);
1807 int encoded_length = (int)p_buf.get_len();
1808
1809 const int exer = is_exer(flavor);
1810 const boolean own_tag =
1811 !(exer && indent && (p_td.xer_bits & (ANY_ELEMENT|ANY_ATTRIBUTES|UNTAGGED)));
1812
1813 const int indenting = !is_canonical(flavor) && own_tag;
1814 const boolean xmlValueList = isXmlValueList();
1815
1816 flavor = flavor
1817 | ( (exer && (p_td.xer_bits & XER_LIST))
1818 || is_exerlist(flavor) ? SIMPLE_TYPE : 0);
1819 flavor &= ~XER_RECOF; // record-of doesn't care
1820 int nof_elements = get_nof_elements();
1821 Base_Type::begin_xml(p_td, p_buf, flavor, indent, !nof_elements,
1822 (collector_fn)&Record_Of_Type::collect_ns);
1823
1824 if (xmlValueList && nof_elements && indenting && !exer) { /* !exer or GDMO */
1825 do_indent(p_buf, indent+1);
1826 }
1827
1828 if (exer && (p_td.xer_bits & ANY_ATTRIBUTES)) {
1829 // Back up over the '>' and the '\n' that may follow it
1830 size_t buf_len = p_buf.get_len(), shorter = 0;
1831 const unsigned char * const buf_data = p_buf.get_data();
1832 if (buf_data[buf_len - 1 - shorter] == '\n') ++shorter;
1833 if (buf_data[buf_len - 1 - shorter] == '>' ) ++shorter;
1834
1835 unsigned char saved [4];
1836 if (shorter) {
1837 memcpy(saved, buf_data + (buf_len - shorter), shorter);
1838 p_buf.increase_length(-shorter);
1839 }
1840
1841 // ANY_ATTRIBUTES means it's a record of universal charstring.
1842 // They are in AnyAttributeFormat (X.693/2008 18.2.6):
1843 // "URI(optional), space, NCName, equals, \"xmlcstring\""
1844 // They need to be written as an XML attribute and namespace declaration:
1845 // xmlns:b0="URI" b0:NCName="xmlcstring"
1846 //
1847 for (int i = 0; i < nof_elements; ++i) {
1848 TTCN_EncDec_ErrorContext ec_0("Attribute %d: ", i);
1849 if (!is_elem_bound(i)) {
1850 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND,
1851 "Encoding an unbound universal charstring value.");
1852 continue;
1853 }
1854 const UNIVERSAL_CHARSTRING *elem
1855 = static_cast<const UNIVERSAL_CHARSTRING *>(val_ptr->value_elements[i]);
1856 size_t len = elem->lengthof();
1857 for (;;) {
1858 const UNIVERSAL_CHARSTRING_ELEMENT& ue = (*elem)[len - 1];
1859 if (sp == ue || tb == ue) --len;
1860 else break;
1861 }
1862 // sp_at: indexes the first space
1863 // j is left to point at where the attribute name begins (just past the space)
1864 size_t j, sp_at = 0;
1865 for (j = 0; j < len; j++) {
1866 const UNIVERSAL_CHARSTRING_ELEMENT& ue = (*elem)[j];
1867 if (sp_at) { // already found a space
1868 if (sp == ue || tb == ue) {} // another space, do nothing
1869 else break; // found a non-space after a space
1870 }
1871 else {
1872 if (sp == ue || tb == ue) sp_at = j;
1873 }
1874 } // next j
1875
1876 size_t buf_start = p_buf.get_len();
1877 if (sp_at > 0) {
1878 char * ns = mprintf(" xmlns:b%d='", i);
1879 size_t ns_len = mstrlen(ns);
1880 p_buf.put_s(ns_len, (cbyte*)ns);
1881
1882 UNIVERSAL_CHARSTRING before(sp_at, (const universal_char*)(*elem));
1883 if (p_td.xer_bits & (ANY_FROM | ANY_EXCEPT)) {
1884 // Ensure the namespace abides to its restrictions
1885 TTCN_Buffer ns_buf;
1886 before.encode_utf8(ns_buf);
1887 CHARSTRING cs;
1888 ns_buf.get_string(cs);
1889 check_namespace_restrictions(p_td, (const char*)cs);
1890 }
1891 before.XER_encode(UNIVERSAL_CHARSTRING_xer_, p_buf,
1892 flavor | ANY_ATTRIBUTES, indent, 0);
1893
1894 p_buf.put_c('\'');
1895 p_buf.put_c(' ');
1896
1897 // Keep just the "b%d" part from ns
1898 p_buf.put_s(ns_len - 9, (cbyte*)ns + 7);
1899 p_buf.put_c(':');
1900 Free(ns);
1901 }
1902 else {
1903 p_buf.put_c(' ');
1904 j = 0;
1905
1906 if (p_td.xer_bits & (ANY_FROM | ANY_EXCEPT)) {
1907 // Make sure the unqualified namespace is allowed
1908 check_namespace_restrictions(p_td, NULL);
1909 }
1910 }
1911
1912 UNIVERSAL_CHARSTRING after(len - j, (const universal_char*)(*elem) + j);
1913 after.XER_encode(UNIVERSAL_CHARSTRING_xer_, p_buf,
1914 flavor | ANY_ATTRIBUTES, indent, 0);
1915
1916 // Put this attribute in a dummy element and walk through it to check its validity
1917 TTCN_Buffer check_buf;
1918 check_buf.put_s(2, (unsigned char*)"<a");
1919 check_buf.put_s(p_buf.get_len() - buf_start, p_buf.get_data() + buf_start);
1920 check_buf.put_s(2, (unsigned char*)"/>");
1921 XmlReaderWrap checker(check_buf);
1922 while (1 == checker.Read());
1923 }
1924 if (shorter) {
1925 p_buf.put_s(shorter, saved); // restore the '>' and anything after
1926 }
1927 }
1928 else { // not ANY-ATTRIBUTES
1929 unsigned int sub_flavor = flavor | XER_RECOF | (p_td.xer_bits & (XER_LIST));
1930 TTCN_EncDec_ErrorContext ec_0("Index ");
1931 TTCN_EncDec_ErrorContext ec_1;
1932
1933 for (int i = 0; i < nof_elements; ++i) {
1934 if (i > 0 && !own_tag && 0 != emb_val &&
1935 emb_val->embval_index < emb_val->embval_array->size_of()) {
1936 emb_val->embval_array->get_at(emb_val->embval_index)->XER_encode(
1937 UNIVERSAL_CHARSTRING_xer_, p_buf, flavor | EMBED_VALUES, indent+1, 0);
1938 ++emb_val->embval_index;
1939 }
1940 ec_1.set_msg("%d: ", i);
1941 if (exer && (p_td.xer_bits & XER_LIST) && i>0) p_buf.put_c(' ');
1942 get_at(i)->XER_encode(*p_td.oftype_descr, p_buf,
1943 sub_flavor, indent+own_tag, emb_val);
1944 }
1945
1946 if (indenting && nof_elements && !is_exerlist(flavor)) {
1947 if (xmlValueList && !exer) p_buf.put_c('\n'); /* !exer or GDMO */
1948 //do_indent(p_buf, indent);
1949 }
1950 }
1951
1952 Base_Type::end_xml(p_td, p_buf, flavor, indent, !nof_elements);
1953 return (int)p_buf.get_len() - encoded_length;
1954 }
1955
1956 // XERSTUFF Record_Of_Type::encode_element
1957 /** Helper for Record_Of_Type::XER_encode_negtest
1958 *
1959 * The main purpose of this method is to allow another type to request
1960 * encoding of a single element of the record-of. Used by Record_Type
1961 * to encode individual strings of the EMBED-VALUES member.
1962 *
1963 * @param i index of the element
1964 * @param ev erroneous descriptor for the element itself
1965 * @param ed deeper erroneous values
1966 * @param p_buf buffer containing the encoded value
1967 * @param sub_flavor flags
1968 * @param indent indentation level
1969 * @return number of bytes generated
1970 */
1971 int Record_Of_Type::encode_element(int i, const XERdescriptor_t& p_td,
1972 const Erroneous_values_t* ev, const Erroneous_descriptor_t* ed,
1973 TTCN_Buffer& p_buf, unsigned int sub_flavor, int indent, embed_values_enc_struct_t* emb_val) const
1974 {
1975 int enc_len = p_buf.get_len();
1976 TTCN_EncDec_ErrorContext ec;
1977 const int exer = is_exer(sub_flavor);
1978
1979 if (ev && ev->before) {
1980 if (ev->before->errval==NULL) {
1981 TTCN_error("internal error: erroneous before value missing");
1982 }
1983 ec.set_msg("Erroneous value before component #%d: ", i);
1984 if (ev->before->raw) {
1985 ev->before->errval->encode_raw(p_buf);
1986 } else {
1987 if (ev->before->type_descr==NULL) TTCN_error(
1988 "internal error: erroneous before type descriptor missing");
1989 ev->before->errval->XER_encode(*ev->before->type_descr->xer,
1990 p_buf, sub_flavor, indent, 0);
1991 }
1992 }
1993
1994 if (exer && (sub_flavor & XER_LIST)
1995 && (i > 0 || (ev && ev->before && !ev->before->raw))){
1996 // Ensure a separator is written after the "erroneous before"
1997 // of the first element (except for "raw before").
1998 p_buf.put_c(' ');
1999 }
2000
2001 if (ev && ev->value) {
2002 if (ev->value->errval) { // replace
2003 ec.set_msg("Erroneous value for component #%d: ", i);
2004 if (ev->value->raw) {
2005 ev->value->errval->encode_raw(p_buf);
2006 } else {
2007 if (ev->value->type_descr==NULL) TTCN_error(
2008 "internal error: erroneous value type descriptor missing");
2009 ev->value->errval->XER_encode(*ev->value->type_descr->xer,
2010 p_buf, sub_flavor, indent, 0);
2011 }
2012 } // else -> omit
2013 } else {
2014 ec.set_msg("Component #%d: ", i);
2015 if (ed) {
2016 get_at(i)->XER_encode_negtest(ed, p_td, p_buf, sub_flavor, indent, emb_val);
2017 } else {
2018 // the "real" encoder
2019 get_at(i)->XER_encode(p_td, p_buf, sub_flavor, indent, emb_val);
2020 }
2021 }
2022
2023 if (ev && ev->after) {
2024 if (ev->after->errval==NULL) {
2025 TTCN_error("internal error: erroneous after value missing");
2026 }
2027 ec.set_msg("Erroneous value after component #%d: ", i);
2028 if (ev->after->raw) {
2029 ev->after->errval->encode_raw(p_buf);
2030 } else {
2031 if (ev->after->type_descr==NULL) TTCN_error(
2032 "internal error: erroneous after type descriptor missing");
2033 ev->after->errval->XER_encode(*ev->after->type_descr->xer,
2034 p_buf, sub_flavor, indent, 0);
2035 }
2036 }
2037
2038 return enc_len;
2039 }
2040
2041 // XERSTUFF Record_Of_Type::XER_encode_negtest
2042 int Record_Of_Type::XER_encode_negtest(const Erroneous_descriptor_t* p_err_descr,
2043 const XERdescriptor_t& p_td, TTCN_Buffer& p_buf, unsigned flavor, int indent,
2044 embed_values_enc_struct_t* emb_val) const
2045 {
2046 if (val_ptr == 0) TTCN_error(
2047 "Attempt to XER-encode an unbound record of type %s", get_descriptor()->name);
2048 int encoded_length = (int)p_buf.get_len();
2049
2050 const int exer = is_exer(flavor);
2051 const boolean own_tag =
2052 !(exer && indent && (p_td.xer_bits & (ANY_ELEMENT|ANY_ATTRIBUTES|UNTAGGED)));
2053
2054 const int indenting = !is_canonical(flavor) && own_tag;
2055 const boolean xmlValueList = isXmlValueList();
2056
2057 flavor = flavor
2058 | ( (exer && (p_td.xer_bits & XER_LIST))
2059 || is_exerlist(flavor) ? SIMPLE_TYPE : 0);
2060 flavor &= ~XER_RECOF; // record-of doesn't care
2061 int nof_elements = get_nof_elements();
2062 Base_Type::begin_xml(p_td, p_buf, flavor, indent, !nof_elements,
2063 (collector_fn)&Record_Of_Type::collect_ns);
2064
2065 if (xmlValueList && nof_elements && indenting && !exer) { /* !exer or GDMO */
2066 do_indent(p_buf, indent+1);
2067 }
2068
2069 int values_idx = 0;
2070 int edescr_idx = 0;
2071 if (exer && (p_td.xer_bits & ANY_ATTRIBUTES)) {
2072 // Back up over the '>' and the '\n' that may follow it
2073 size_t buf_len = p_buf.get_len(), shorter = 0;
2074 const unsigned char * const buf_data = p_buf.get_data();
2075 if (buf_data[buf_len - 1 - shorter] == '\n') ++shorter;
2076 if (buf_data[buf_len - 1 - shorter] == '>' ) ++shorter;
2077
2078 unsigned char * saved = 0;
2079 if (shorter) {
2080 saved = new unsigned char[shorter];
2081 memcpy(saved, buf_data + (buf_len - shorter), shorter);
2082 p_buf.increase_length(-shorter);
2083 }
2084
2085 // ANY_ATTRIBUTES means it's a record of universal charstring.
2086 // They are in AnyAttributeFormat (X.693/2008 18.2.6):
2087 // "URI(optional), space, NCName, equals, \"xmlcstring\""
2088 // They need to be written as an XML attribute and namespace declaration:
2089 // xmlns:b0="URI" b0:NCName="xmlcstring"
2090 //
2091 for (int i = 0; i < nof_elements; ++i) {
2092 if (i < p_err_descr->omit_before) continue;
2093
2094 const Erroneous_values_t *ev = p_err_descr->next_field_err_values(i, values_idx);
2095 const Erroneous_descriptor_t *ed = p_err_descr->next_field_emb_descr(i, edescr_idx);
2096
2097 if (ev && ev->before) {
2098 if (ev->before->errval==NULL) TTCN_error("internal error: erroneous value missing");
2099
2100 // ec.set_msg
2101 if (ev->before->raw) ev->before->errval->encode_raw(p_buf);
2102 else {
2103 if (ev->before->type_descr==NULL) TTCN_error(
2104 "internal error: erroneous before type descriptor missing");
2105 else ev->before->errval->XER_encode(*ev->before->type_descr->xer,
2106 p_buf, flavor, indent, 0);
2107 }
2108 }
2109
2110 if (ev && ev->value) { //value replacement
2111 if (ev->value->errval) {
2112 if (ev->value->raw) ev->value->errval->encode_raw(p_buf);
2113 else {
2114 if (ev->value->type_descr==NULL) TTCN_error(
2115 "internal error: erroneous value type descriptor missing");
2116 else ev->value->errval->XER_encode(*ev->value->type_descr->xer,
2117 p_buf, flavor, indent, 0);
2118 }
2119 }
2120 }
2121 else {
2122 if (ed) {
2123 // embedded descr.. call negtest (except UNIVERSAL_CHARSTRING
2124 // doesn't have XER_encode_negtest)
2125 TTCN_error("internal error: embedded descriptor for scalar");
2126 }
2127 else {
2128 // the original encoding
2129 const UNIVERSAL_CHARSTRING *elem
2130 = static_cast<const UNIVERSAL_CHARSTRING *>(get_at(i));
2131 size_t len = elem->lengthof();
2132 for (;;) {
2133 const UNIVERSAL_CHARSTRING_ELEMENT& ue = (*elem)[len - 1];
2134 if (sp == ue || tb == ue) --len;
2135 else break;
2136 }
2137 // sp_at: indexes the first space
2138 // j is left to point at where the attribute name begins (just past the space)
2139 size_t j, sp_at = 0;
2140 for (j = 0; j < len; j++) {
2141 const UNIVERSAL_CHARSTRING_ELEMENT& ue = (*elem)[j];
2142 if (sp_at) { // already found a space
2143 if (sp == ue || tb == ue) {} // another space, do nothing
2144 else break; // found a non-space after a space
2145 }
2146 else {
2147 if (sp == ue || tb == ue) sp_at = j;
2148 }
2149 } // next j
2150
2151 if (sp_at > 0) {
2152 char * ns = mprintf(" xmlns:b%d='", i);
2153 size_t ns_len = mstrlen(ns);
2154 p_buf.put_s(ns_len, (cbyte*)ns);
2155
2156 UNIVERSAL_CHARSTRING before(sp_at, (const universal_char*)(*elem));
2157 before.XER_encode(UNIVERSAL_CHARSTRING_xer_, p_buf,
2158 flavor | ANY_ATTRIBUTES, indent, 0);
2159
2160 p_buf.put_c('\'');
2161 p_buf.put_c(' ');
2162
2163 // Keep just the "b%d" part from ns
2164 p_buf.put_s(ns_len - 9, (cbyte*)ns + 7);
2165 p_buf.put_c(':');
2166 Free(ns);
2167 }
2168 else {
2169 p_buf.put_c(' ');
2170 j = 0;
2171 }
2172
2173 UNIVERSAL_CHARSTRING after(len - j, (const universal_char*)(*elem) + j);
2174 after.XER_encode(UNIVERSAL_CHARSTRING_xer_, p_buf,
2175 flavor | ANY_ATTRIBUTES, indent, 0);
2176 }
2177 }
2178
2179 if (ev && ev->after) {
2180 if (ev->after->errval==NULL) TTCN_error(
2181 "internal error: erroneous after value missing");
2182 else {
2183 if (ev->after->raw) ev->after->errval->encode_raw(p_buf);
2184 else {
2185 if (ev->after->type_descr==NULL) TTCN_error(
2186 "internal error: erroneous after type descriptor missing");
2187 else ev->after->errval->XER_encode(*ev->after->type_descr->xer,
2188 p_buf, flavor, indent, 0);
2189 }
2190 }
2191 }
2192 // omit_after value -1 becomes "very big"
2193 if ((unsigned int)i >= (unsigned int)p_err_descr->omit_after) break;
2194 }
2195 if (shorter) {
2196 p_buf.put_s(shorter, saved); // restore the '>' and anything after
2197 delete[] saved;
2198 }
2199 }
2200 else { // not ANY-ATTRIBUTES
2201 unsigned int sub_flavor = flavor | XER_RECOF | (p_td.xer_bits & (XER_LIST|ANY_ATTRIBUTES));
2202
2203 TTCN_EncDec_ErrorContext ec;
2204
2205 for (int i = 0; i < nof_elements; ++i) {
2206 if (i < p_err_descr->omit_before) continue;
2207
2208 if (0 != emb_val && i > 0 && !own_tag &&
2209 emb_val->embval_index < emb_val->embval_array->size_of()) {
2210 const Erroneous_values_t * ev0_i = NULL;
2211 const Erroneous_descriptor_t* ed0_i = NULL;
2212 if (emb_val->embval_err) {
2213 ev0_i = emb_val->embval_err->next_field_err_values(emb_val->embval_index, emb_val->embval_err_val_idx);
2214 ed0_i = emb_val->embval_err->next_field_emb_descr (emb_val->embval_index, emb_val->embval_err_descr_idx);
2215 }
2216 emb_val->embval_array->encode_element(emb_val->embval_index, UNIVERSAL_CHARSTRING_xer_,
2217 ev0_i, ed0_i, p_buf, flavor | EMBED_VALUES, indent + own_tag, 0);
2218 ++emb_val->embval_index;
2219 }
2220
2221 const Erroneous_values_t* err_vals =
2222 p_err_descr->next_field_err_values(i, values_idx);
2223 const Erroneous_descriptor_t* emb_descr =
2224 p_err_descr->next_field_emb_descr (i, edescr_idx);
2225
2226 encode_element(i, *p_td.oftype_descr, err_vals, emb_descr, p_buf, sub_flavor, indent+own_tag, emb_val);
2227
2228 // omit_after value -1 becomes "very big"
2229 if ((unsigned int)i >= (unsigned int)p_err_descr->omit_after) break;
2230 }
2231
2232 if (indenting && nof_elements && !is_exerlist(flavor)) {
2233 if (xmlValueList && !exer) p_buf.put_c('\n'); /* !exer or GDMO */
2234 //do_indent(p_buf, indent);
2235 }
2236 }
2237
2238 Base_Type::end_xml(p_td, p_buf, flavor, indent, !nof_elements);
2239 return (int)p_buf.get_len() - encoded_length;
2240 }
2241
2242 int Record_Of_Type::XER_decode(const XERdescriptor_t& p_td,
2243 XmlReaderWrap& reader, unsigned int flavor, unsigned int flavor2, embed_values_dec_struct_t* emb_val)
2244 {
2245 int exer = is_exer(flavor);
2246 int xerbits = p_td.xer_bits;
2247 if (flavor & XER_TOPLEVEL) xerbits &= ~UNTAGGED;
2248 boolean own_tag =
2249 !(exer && ((xerbits & (ANY_ELEMENT | ANY_ATTRIBUTES | UNTAGGED))
2250 || (flavor & USE_TYPE_ATTR))); /* incase the parent has USE-UNION */
2251 /* not toplevel anymore and remove the flags for USE-UNION the oftype doesn't need them */
2252 flavor &= ~XER_TOPLEVEL & ~XER_LIST & ~USE_TYPE_ATTR;
2253 int success=1, depth=-1;
2254 set_val(NULL_VALUE); // empty but initialized array, val_ptr != NULL
2255 int type;
2256 if (own_tag) for (success = 1; success == 1; success = reader.Read()) {
2257 type = reader.NodeType();
2258 if (exer && (p_td.xer_bits & XER_ATTRIBUTE)) {
2259 if (XML_READER_TYPE_ATTRIBUTE == type) break;
2260 }
2261 if (exer && (p_td.xer_bits & XER_LIST)) {
2262 if (XML_READER_TYPE_TEXT == type) break;
2263 }
2264 else {
2265 if (XML_READER_TYPE_ELEMENT == type) {
2266 verify_name(reader, p_td, exer);
2267 depth = reader.Depth();
2268 break;
2269 }
2270 } /* endif(exer && list) */
2271 } /* next read */
2272 else depth = reader.Depth();
2273 TTCN_EncDec_ErrorContext ec_0("Index ");
2274 TTCN_EncDec_ErrorContext ec_1;
2275 flavor |= XER_RECOF;
2276 if (exer && (p_td.xer_bits & ANY_ATTRIBUTES)) {
2277 // The enclosing type should handle the decoding.
2278 TTCN_error("Incorrect decoding of ANY-ATTRIBUTES");
2279 }
2280 else if (exer && (p_td.xer_bits & XER_LIST)) { /* LIST decoding*/
2281 char *val = (char*)reader.NewValue(); /* we own it */
2282 size_t pos = 0;
2283 size_t len = strlen(val);
2284 /* The string contains a bunch of values separated by whitespace.
2285 * Tokenize the string and create a new buffer which looks like
2286 * an XML element (<ns:name xmlns:ns='uri'>value</ns:name>), then use that
2287 * to decode the value. */
2288 for(char * str = strtok(val, " \t\x0A\x0D"); str != 0; str = strtok(val + pos, " \t\x0A\x0D")) {
2289 // Calling strtok with NULL won't work here, since the decoded element can have strtok calls aswell
2290 pos += strlen(str) + 1;
2291 // Construct a new XML Reader with the current token.
2292 TTCN_Buffer buf2;
2293 const XERdescriptor_t& sub_xer = *p_td.oftype_descr;
2294 buf2.put_c('<');
2295 write_ns_prefix(sub_xer, buf2);
2296
2297 boolean i_can_has_ns = sub_xer.my_module != 0 && sub_xer.ns_index != -1;
2298 const char * const exer_name = sub_xer.names[1];
2299 buf2.put_s((size_t)sub_xer.namelens[1]-1-i_can_has_ns, (cbyte*)exer_name);
2300 if (i_can_has_ns) {
2301 const namespace_t * const pns = sub_xer.my_module->get_ns(sub_xer.ns_index);
2302 buf2.put_s(7 - (*pns->px == 0), (cbyte*)" xmlns:");
2303 buf2.put_s(strlen(pns->px), (cbyte*)pns->px);
2304 buf2.put_s(2, (cbyte*)"='");
2305 buf2.put_s(strlen(pns->ns), (cbyte*)pns->ns);
2306 buf2.put_s(2, (cbyte*)"'>");
2307 }
2308 // start tag completed
2309 buf2.put_s(strlen(str), (cbyte*)str);
2310
2311 buf2.put_c('<');
2312 buf2.put_c('/');
2313 write_ns_prefix(sub_xer, buf2);
2314 buf2.put_s((size_t)sub_xer.namelens[1], (cbyte*)exer_name);
2315 XmlReaderWrap reader2(buf2);
2316 reader2.Read(); // Move to the start element.
2317 // Don't move to the #text, that's the callee's responsibility.
2318 ec_1.set_msg("%d: ", get_nof_elements());
2319 // The call to the non-const operator[], I mean get_at(), creates
2320 // a new element (because it is indexing one past the last element).
2321 // Then we call its XER_decode with the temporary XML reader.
2322 get_at(get_nof_elements())->XER_decode(sub_xer, reader2, flavor, flavor2, 0);
2323 if (flavor & EXIT_ON_ERROR && !is_elem_bound(get_nof_elements() - 1)) {
2324 if (1 == get_nof_elements()) {
2325 // Failed to decode even the first element
2326 clean_up();
2327 } else {
2328 // Some elements were successfully decoded -> only delete the last one
2329 set_size(get_nof_elements() - 1);
2330 }
2331 xmlFree(val);
2332 return -1;
2333 }
2334 if (pos >= len) break;
2335 }
2336 xmlFree(val);
2337 if (p_td.xer_bits & XER_ATTRIBUTE) {
2338 //Let the caller do reader.AdvanceAttribute();
2339 }
2340 else if (own_tag) {
2341 reader.Read(); // on closing tag
2342 reader.Read(); // past it
2343 }
2344 }
2345 else { // not LIST
2346 if (flavor & PARENT_CLOSED) {
2347 // Nothing to do. We are probably untagged; do not advance in the XML
2348 // because it would move past the parent.
2349 }
2350 else if (own_tag && reader.IsEmptyElement()) { // Nothing to do
2351 reader.Read(); // This is our own empty tag, move past it
2352 }
2353 else {
2354 /* Note: there is no reader.Read() at the end of the loop below.
2355 * Each element is supposed to consume enough to leave the next element
2356 * well-positioned. */
2357 for (success = own_tag ? reader.Read() : reader.Ok(); success == 1; ) {
2358 type = reader.NodeType();
2359 if (XML_READER_TYPE_ELEMENT == type)
2360 {
2361 if (exer && (p_td.xer_bits & ANY_ELEMENT)) {
2362 /* This is a (record-of UNIVERSAL_CHARSTRING) with ANY-ELEMENT.
2363 * The ANY-ELEMENT is really meant for the element type,
2364 * so behave like a record-of (string with ANY-ELEMENT):
2365 * call the non-const operator[], I mean get_at(), to create
2366 * a new element, then read the entire XML element into it. */
2367 UNIVERSAL_CHARSTRING* uc =
2368 static_cast<UNIVERSAL_CHARSTRING*>(get_at(val_ptr->n_elements));
2369 const xmlChar* outer = reader.ReadOuterXml();
2370 uc->decode_utf8(strlen((const char*)outer), outer);
2371 // consume the element
2372 for (success = reader.Read(); success == 1 && reader.Depth() > depth; success = reader.Read()) {}
2373 if (reader.NodeType() != XML_READER_TYPE_ELEMENT) success = reader.Read(); // one last time
2374 }
2375 else {
2376 /* If this is an untagged record-of and the start element does not
2377 * belong to the embedded type, the record-of has already ended. */
2378 if (!own_tag && !can_start_v(
2379 (const char*)reader.LocalName(), (const char*)reader.NamespaceUri(),
2380 p_td, flavor | UNTAGGED))
2381 {
2382 for (; success == 1 && reader.Depth() > depth; success = reader.Read()) ;
2383 // We should now be back at the same depth as we started.
2384 break;
2385 }
2386 ec_1.set_msg("%d: ", get_nof_elements());
2387 /* The call to the non-const get_at() creates the element */
2388 get_at(get_nof_elements())->XER_decode(*p_td.oftype_descr, reader, flavor, flavor2, emb_val);
2389 }
2390 if (0 != emb_val && !own_tag && get_nof_elements() > 1) {
2391 ++emb_val->embval_index;
2392 }
2393 }
2394 else if (XML_READER_TYPE_END_ELEMENT == type) {
2395 for (; success == 1 && reader.Depth() > depth; success = reader.Read()) ;
2396 // If the depth just decreased, this must be an end element
2397 // (but a different one from what we had before the loop)
2398 if (own_tag) {
2399 verify_end(reader, p_td, depth, exer);
2400 reader.Read(); // move forward one last time
2401 }
2402 break;
2403 }
2404 else if (XML_READER_TYPE_TEXT == type && 0 != emb_val && !own_tag && get_nof_elements() > 0) {
2405 UNIVERSAL_CHARSTRING emb_ustr((const char*)reader.Value());
2406 emb_val->embval_array->get_at(emb_val->embval_index)->set_value(&emb_ustr);
2407 success = reader.Read();
2408 }
2409 else {
2410 success = reader.Read();
2411 }
2412 } /* next read */
2413 } /* if not empty element */
2414 } /* if not LIST */
2415 if (!own_tag && exer && (p_td.xer_bits & XER_OPTIONAL) && get_nof_elements() == 0) {
2416 // set it to unbound, so the OPTIONAL class sets it to omit
2417 clean_up();
2418 }
2419 return 1; // decode successful
2420 }
2421
2422 void Record_Of_Type::set_param(Module_Param& param) {
2423 if (dynamic_cast<Module_Param_Name*>(param.get_id()) != NULL &&
2424 param.get_id()->next_name()) {
2425 // Haven't reached the end of the module parameter name
2426 // => the name refers to one of the elements, not to the whole record of
2427 char* param_field = param.get_id()->get_current_name();
2428 if (param_field[0] < '0' || param_field[0] > '9') {
2429 param.error("Unexpected record field name in module parameter, expected a valid"
2430 " index for %s type `%s'", is_set() ? "set of" : "record of", get_descriptor()->name);
2431 }
2432 int param_index = -1;
2433 sscanf(param_field, "%d", &param_index);
2434 get_at(param_index)->set_param(param);
2435 return;
2436 }
2437
2438 param.basic_check(Module_Param::BC_VALUE|Module_Param::BC_LIST, is_set()?"set of value":"record of value");
2439
2440 Module_Param_Ptr mp = &param;
2441 if (param.get_type() == Module_Param::MP_Reference) {
2442 mp = param.get_referenced_param();
2443 }
2444
2445 switch (param.get_operation_type()) {
2446 case Module_Param::OT_ASSIGN:
2447 if (mp->get_type()==Module_Param::MP_Value_List && mp->get_size()==0) {
2448 set_val(NULL_VALUE);
2449 return;
2450 }
2451 switch (mp->get_type()) {
2452 case Module_Param::MP_Value_List:
2453 set_size(mp->get_size());
2454 for (size_t i=0; i<mp->get_size(); ++i) {
2455 Module_Param* const curr = mp->get_elem(i);
2456 if (curr->get_type()!=Module_Param::MP_NotUsed) {
2457 get_at(i)->set_param(*curr);
2458 }
2459 }
2460 break;
2461 case Module_Param::MP_Indexed_List:
2462 for (size_t i=0; i<mp->get_size(); ++i) {
2463 Module_Param* const current = mp->get_elem(i);
2464 get_at(current->get_id()->get_index())->set_param(*current);
2465 }
2466 break;
2467 default:
2468 param.type_error(is_set()?"set of value":"record of value", get_descriptor()->name);
2469 }
2470 break;
2471 case Module_Param::OT_CONCAT:
2472 switch (mp->get_type()) {
2473 case Module_Param::MP_Value_List: {
2474 if (!is_bound()) set_val(NULL_VALUE);
2475 int start_idx = lengthof();
2476 for (size_t i=0; i<mp->get_size(); ++i) {
2477 Module_Param* const curr = mp->get_elem(i);
2478 if ((curr->get_type()!=Module_Param::MP_NotUsed)) {
2479 get_at(start_idx+(int)i)->set_param(*curr);
2480 }
2481 }
2482 } break;
2483 case Module_Param::MP_Indexed_List:
2484 param.error("Cannot concatenate an indexed value list");
2485 break;
2486 default:
2487 param.type_error(is_set()?"set of value":"record of value", get_descriptor()->name);
2488 }
2489 break;
2490 default:
2491 TTCN_error("Internal error: Record_Of_Type::set_param()");
2492 }
2493 }
2494
2495 Module_Param* Record_Of_Type::get_param(Module_Param_Name& param_name) const
2496 {
2497 if (!is_bound()) {
2498 return new Module_Param_Unbound();
2499 }
2500 if (param_name.next_name()) {
2501 // Haven't reached the end of the module parameter name
2502 // => the name refers to one of the elements, not to the whole record of
2503 char* param_field = param_name.get_current_name();
2504 if (param_field[0] < '0' || param_field[0] > '9') {
2505 TTCN_error("Unexpected record field name in module parameter reference, "
2506 "expected a valid index for %s type `%s'",
2507 is_set() ? "set of" : "record of", get_descriptor()->name);
2508 }
2509 int param_index = -1;
2510 sscanf(param_field, "%d", &param_index);
2511 return get_at(param_index)->get_param(param_name);
2512 }
2513 Vector<Module_Param*> values;
2514 for (int i = 0; i < val_ptr->n_elements; ++i) {
2515 values.push_back(val_ptr->value_elements[i]->get_param(param_name));
2516 }
2517 Module_Param_Value_List* mp = new Module_Param_Value_List();
2518 mp->add_list_with_implicit_ids(&values);
2519 values.clear();
2520 return mp;
2521 }
2522
2523 void Record_Of_Type::set_implicit_omit()
2524 {
2525 for (int i = 0; i < get_nof_elements(); ++i) {
2526 if (is_elem_bound(i))
2527 val_ptr->value_elements[i]->set_implicit_omit();
2528 }
2529 }
2530
2531 void Record_Of_Type::add_refd_index(int index)
2532 {
2533 if (NULL == refd_ind_ptr) {
2534 refd_ind_ptr = new refd_index_struct;
2535 refd_ind_ptr->max_refd_index = -1;
2536 }
2537 refd_ind_ptr->refd_indices.push_back(index);
2538 if (index > get_max_refd_index()) {
2539 refd_ind_ptr->max_refd_index = index;
2540 }
2541 }
2542
2543 void Record_Of_Type::remove_refd_index(int index)
2544 {
2545 for (size_t i = refd_ind_ptr->refd_indices.size(); i > 0; --i) {
2546 if (refd_ind_ptr->refd_indices[i - 1] == index) {
2547 refd_ind_ptr->refd_indices.erase_at(i - 1);
2548 break;
2549 }
2550 }
2551 if (refd_ind_ptr->refd_indices.empty()) {
2552 delete refd_ind_ptr;
2553 refd_ind_ptr = NULL;
2554 }
2555 else if (get_max_refd_index() == index) {
2556 refd_ind_ptr->max_refd_index = -1;
2557 }
2558 }
2559
2560 boolean operator==(null_type /*null_value*/, const Record_Of_Type& other_value)
2561 {
2562 if (other_value.val_ptr == NULL)
2563 TTCN_error("The right operand of comparison is an unbound value of type %s.",
2564 other_value.get_descriptor()->name);
2565 return other_value.get_nof_elements() == 0;
2566 }
2567
2568 boolean operator!=(null_type null_value,
2569 const Record_Of_Type& other_value)
2570 {
2571 return !(null_value == other_value);
2572 }
2573
2574 ////////////////////////////////////////////////////////////////////////////////
2575
2576 boolean Record_Type::is_bound() const
2577 {
2578 int field_cnt = get_count();
2579 for (int field_idx=0; field_idx<field_cnt; field_idx++) {
2580 const Base_Type* temp = get_at(field_idx);
2581 if(temp->is_optional()) {
2582 if(temp->is_present() && temp->get_opt_value()->is_bound()) return TRUE;
2583 }
2584 if(temp->is_bound()) return TRUE;
2585 }
2586 return FALSE;
2587 }
2588
2589 boolean Record_Type::is_value() const
2590 {
2591 int field_cnt = get_count();
2592 for (int field_idx=0; field_idx<field_cnt; field_idx++) {
2593 const Base_Type* temp = get_at(field_idx);
2594 if(temp->is_optional()) {
2595 if(!temp->is_bound()) return FALSE;
2596 if(temp->is_present() && !temp->is_value()) return FALSE;
2597 } else {
2598 if(!temp->is_value()) return FALSE;
2599 }
2600 }
2601 return TRUE;
2602 }
2603
2604 void Record_Type::clean_up()
2605 {
2606 int field_cnt = get_count();
2607 for (int field_idx=0; field_idx<field_cnt; field_idx++) {
2608 get_at(field_idx)->clean_up();
2609 }
2610 }
2611
2612 void Record_Type::log() const
2613 {
2614 if (!is_bound()) {
2615 TTCN_Logger::log_event_unbound();
2616 return;
2617 }
2618 TTCN_Logger::log_event_str("{ ");
2619 int field_cnt = get_count();
2620 for (int field_idx=0; field_idx<field_cnt; field_idx++) {
2621 if (field_idx) TTCN_Logger::log_event_str(", ");
2622 TTCN_Logger::log_event_str(fld_name(field_idx));
2623 TTCN_Logger::log_event_str(" := ");
2624 get_at(field_idx)->log();
2625 }
2626 TTCN_Logger::log_event_str(" }");
2627 if (err_descr) err_descr->log();
2628 }
2629
2630 void Record_Type::set_param(Module_Param& param) {
2631 if (dynamic_cast<Module_Param_Name*>(param.get_id()) != NULL &&
2632 param.get_id()->next_name()) {
2633 // Haven't reached the end of the module parameter name
2634 // => the name refers to one of the fields, not to the whole record
2635 char* param_field = param.get_id()->get_current_name();
2636 if (param_field[0] >= '0' && param_field[0] <= '9') {
2637 param.error("Unexpected array index in module parameter, expected a valid field"
2638 " name for %s type `%s'", is_set() ? "set" : "record", get_descriptor()->name);
2639 }
2640 int field_cnt = get_count();
2641 for (int field_idx = 0; field_idx < field_cnt; field_idx++) {
2642 if (strcmp(fld_name(field_idx), param_field) == 0) {
2643 get_at(field_idx)->set_param(param);
2644 return;
2645 }
2646 }
2647 param.error("Field `%s' not found in %s type `%s'",
2648 param_field, is_set() ? "set" : "record", get_descriptor()->name);
2649 }
2650
2651 param.basic_check(Module_Param::BC_VALUE, is_set()?"set value":"record value");
2652
2653 Module_Param_Ptr mp = &param;
2654 if (param.get_type() == Module_Param::MP_Reference) {
2655 mp = param.get_referenced_param();
2656 }
2657
2658 switch (mp->get_type()) {
2659 case Module_Param::MP_Value_List:
2660 if (get_count()<(int)mp->get_size()) {
2661 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());
2662 }
2663 for (size_t i=0; i<mp->get_size(); i++) {
2664 Module_Param* mp_elem = mp->get_elem(i);
2665 if (mp_elem->get_type()!=Module_Param::MP_NotUsed) {
2666 get_at((int)i)->set_param(*mp_elem);
2667 }
2668 }
2669 break;
2670 case Module_Param::MP_Assignment_List:
2671 for (size_t i=0; i<mp->get_size(); ++i) {
2672 Module_Param* const current = mp->get_elem(i);
2673 bool found = false;
2674 for (int j=0; j<get_count(); ++j) {
2675 if (!strcmp(fld_name(j), current->get_id()->get_name())) {
2676 if (current->get_type()!=Module_Param::MP_NotUsed) {
2677 get_at(j)->set_param(*current);
2678 }
2679 found = true;
2680 break;
2681 }
2682 }
2683 if (!found) {
2684 current->error("Non existent field name in type %s: %s.", get_descriptor()->name, current->get_id()->get_name());
2685 }
2686 }
2687 break;
2688 default:
2689 param.type_error(is_set()?"set value":"record value", get_descriptor()->name);
2690 }
2691 }
2692
2693 Module_Param* Record_Type::get_param(Module_Param_Name& param_name) const
2694 {
2695 if (!is_bound()) {
2696 return new Module_Param_Unbound();
2697 }
2698 if (param_name.next_name()) {
2699 // Haven't reached the end of the module parameter name
2700 // => the name refers to one of the fields, not to the whole record
2701 char* param_field = param_name.get_current_name();
2702 if (param_field[0] >= '0' && param_field[0] <= '9') {
2703 TTCN_error("Unexpected array index in module parameter reference, "
2704 "expected a valid field name for %s type `%s'",
2705 is_set() ? "set" : "record", get_descriptor()->name);
2706 }
2707 int field_cnt = get_count();
2708 for (int field_idx = 0; field_idx < field_cnt; field_idx++) {
2709 if (strcmp(fld_name(field_idx), param_field) == 0) {
2710 return get_at(field_idx)->get_param(param_name);
2711 }
2712 }
2713 TTCN_error("Field `%s' not found in %s type `%s'",
2714 param_field, is_set() ? "set" : "record", get_descriptor()->name);
2715 }
2716 Module_Param_Assignment_List* mp = new Module_Param_Assignment_List();
2717 for (int i = 0; i < get_count(); ++i) {
2718 Module_Param* mp_field = get_at(i)->get_param(param_name);
2719 mp_field->set_id(new Module_Param_FieldName(mcopystr(fld_name(i))));
2720 mp->add_elem(mp_field);
2721 }
2722 return mp;
2723 }
2724
2725 void Record_Type::set_implicit_omit()
2726 {
2727 int field_cnt = get_count();
2728 for (int field_idx = 0; field_idx < field_cnt; field_idx++) {
2729 Base_Type *temp = get_at(field_idx);
2730 if (temp->is_optional()) {
2731 if (temp->is_bound()) temp->set_implicit_omit();
2732 else temp->set_to_omit();
2733 } else if (temp->is_bound()) {
2734 temp->set_implicit_omit();
2735 }
2736 }
2737 }
2738
2739 int Record_Type::size_of() const
2740 {
2741 int opt_count = optional_count();
2742 if (opt_count==0) return get_count();
2743 const int* optional_indexes = get_optional_indexes();
2744 int my_size = get_count();
2745 for (int i=0; i<opt_count; i++) {
2746 if (!get_at(optional_indexes[i])->ispresent()) my_size--;
2747 }
2748 return my_size;
2749 }
2750
2751 void Record_Type::encode_text(Text_Buf& text_buf) const
2752 {
2753 if (!is_bound()) {
2754 TTCN_error("Text encoder: Encoding an unbound record/set value of type %s.",
2755 get_descriptor()->name);
2756 }
2757 int field_cnt = get_count();
2758 for (int field_idx=0; field_idx<field_cnt; field_idx++)
2759 get_at(field_idx)->encode_text(text_buf);
2760 }
2761
2762 void Record_Type::decode_text(Text_Buf& text_buf)
2763 {
2764 int field_cnt = get_count();
2765 for (int field_idx=0; field_idx<field_cnt; field_idx++)
2766 get_at(field_idx)->decode_text(text_buf);
2767 }
2768
2769 boolean Record_Type::is_equal(const Base_Type* other_value) const
2770 {
2771 const Record_Type* other_record = static_cast<const Record_Type*>(other_value);
2772 int field_cnt = get_count();
2773 for (int field_idx=0; field_idx<field_cnt; field_idx++) {
2774 const Base_Type* elem = get_at(field_idx);
2775 const Base_Type* other_elem = other_record->get_at(field_idx);
2776 if (elem->is_bound()) {
2777 if (other_elem->is_bound()) {
2778 if (!elem->is_equal(other_elem))
2779 return FALSE;
2780 } else return FALSE;
2781 } else if (other_elem->is_bound()) return FALSE;
2782 }
2783 return TRUE;
2784 }
2785
2786 void Record_Type::set_value(const Base_Type* other_value)
2787 {
2788 if (this==other_value) return;
2789 if (!other_value->is_bound())
2790 TTCN_error("Copying an unbound record/set value of type %s.",
2791 other_value->get_descriptor()->name);
2792 const Record_Type* other_record = static_cast<const Record_Type*>(other_value);
2793 int field_cnt = get_count();
2794 for (int field_idx=0; field_idx<field_cnt; field_idx++) {
2795 const Base_Type* elem = other_record->get_at(field_idx);
2796 if (elem->is_bound()) {
2797 get_at(field_idx)->set_value(elem);
2798 } else {
2799 get_at(field_idx)->clean_up();
2800 }
2801 }
2802 err_descr = other_record->err_descr;
2803 }
2804
2805 void Record_Type::encode(const TTCN_Typedescriptor_t& p_td,
2806 TTCN_Buffer& p_buf, TTCN_EncDec::coding_t p_coding, ...) const
2807 {
2808 va_list pvar;
2809 va_start(pvar, p_coding);
2810 switch(p_coding) {
2811 case TTCN_EncDec::CT_BER: {
2812 TTCN_EncDec_ErrorContext ec("While BER-encoding type '%s': ", p_td.name);
2813 unsigned BER_coding=va_arg(pvar, unsigned);
2814 BER_encode_chk_coding(BER_coding);
2815 ASN_BER_TLV_t *tlv=BER_encode_TLV(p_td, BER_coding);
2816 tlv->put_in_buffer(p_buf);
2817 ASN_BER_TLV_t::destruct(tlv);
2818 break;}
2819 case TTCN_EncDec::CT_RAW: {
2820 TTCN_EncDec_ErrorContext ec("While RAW-encoding type '%s': ", p_td.name);
2821 if(!p_td.raw) TTCN_EncDec_ErrorContext::error_internal
2822 ("No RAW descriptor available for type '%s'.", p_td.name);
2823 RAW_enc_tr_pos rp;
2824 rp.level=0;
2825 rp.pos=NULL;
2826 RAW_enc_tree root(FALSE, NULL, &rp, 1, p_td.raw);
2827 RAW_encode(p_td, root);
2828 root.put_to_buf(p_buf);
2829 break;}
2830 case TTCN_EncDec::CT_TEXT: {
2831 TTCN_EncDec_ErrorContext ec("While TEXT-encoding type '%s': ", p_td.name);
2832 if(!p_td.text) TTCN_EncDec_ErrorContext::error_internal
2833 ("No TEXT descriptor available for type '%s'.", p_td.name);
2834 TEXT_encode(p_td,p_buf);
2835 break;}
2836 case TTCN_EncDec::CT_XER: {
2837 TTCN_EncDec_ErrorContext ec("While XER-encoding type '%s': ", p_td.name);
2838 unsigned XER_coding=va_arg(pvar, unsigned);
2839 XER_encode(*(p_td.xer),p_buf, XER_coding, 0, 0);
2840 p_buf.put_c('\n');
2841 break;}
2842 case TTCN_EncDec::CT_JSON: {
2843 TTCN_EncDec_ErrorContext ec("While JSON-encoding type '%s': ", p_td.name);
2844 if(!p_td.json) TTCN_EncDec_ErrorContext::error_internal
2845 ("No JSON descriptor available for type '%s'.", p_td.name);
2846 JSON_Tokenizer tok(va_arg(pvar, int) != 0);
2847 JSON_encode(p_td, tok);
2848 p_buf.put_s(tok.get_buffer_length(), (const unsigned char*)tok.get_buffer());
2849 break;}
2850 default:
2851 TTCN_error("Unknown coding method requested to encode type '%s'", p_td.name);
2852 }
2853 va_end(pvar);
2854 }
2855
2856 void Record_Type::decode(const TTCN_Typedescriptor_t& p_td,
2857 TTCN_Buffer& p_buf, TTCN_EncDec::coding_t p_coding, ...)
2858 {
2859 va_list pvar;
2860 va_start(pvar, p_coding);
2861 switch(p_coding) {
2862 case TTCN_EncDec::CT_BER: {
2863 TTCN_EncDec_ErrorContext ec("While BER-decoding type '%s': ", p_td.name);
2864 unsigned L_form=va_arg(pvar, unsigned);
2865 ASN_BER_TLV_t tlv;
2866 BER_decode_str2TLV(p_buf, tlv, L_form);
2867 BER_decode_TLV(p_td, tlv, L_form);
2868 if(tlv.isComplete) p_buf.increase_pos(tlv.get_len());
2869 break;}
2870 case TTCN_EncDec::CT_RAW: {
2871 TTCN_EncDec_ErrorContext ec("While RAW-decoding type '%s': ", p_td.name);
2872 if(!p_td.raw)
2873 TTCN_EncDec_ErrorContext::error_internal
2874 ("No RAW descriptor available for type '%s'.", p_td.name);
2875 raw_order_t order;
2876 switch(p_td.raw->top_bit_order) {
2877 case TOP_BIT_LEFT:
2878 order=ORDER_LSB;
2879 break;
2880 case TOP_BIT_RIGHT:
2881 default:
2882 order=ORDER_MSB;
2883 }
2884 int rawr = RAW_decode(p_td, p_buf, p_buf.get_len()*8, order);
2885 if (rawr < 0) switch (-rawr) {
2886 case TTCN_EncDec::ET_INCOMPL_MSG:
2887 case TTCN_EncDec::ET_LEN_ERR:
2888 ec.error(TTCN_EncDec::ET_INCOMPL_MSG,
2889 "Can not decode type '%s', because incomplete"
2890 " message was received", p_td.name);
2891 break;
2892 case 1:
2893 // The RAW/TEXT decoders return -1 for anything not a length error.
2894 // This is the value for ET_UNBOUND, which can't happen in decoding.
2895 default:
2896 ec.error(TTCN_EncDec::ET_INVAL_MSG,
2897 "Can not decode type '%s', because invalid"
2898 " message was received", p_td.name);
2899 break;
2900 }
2901 break;}
2902 case TTCN_EncDec::CT_TEXT: {
2903 Limit_Token_List limit;
2904 TTCN_EncDec_ErrorContext ec("While TEXT-decoding type '%s': ", p_td.name);
2905 if(!p_td.text) TTCN_EncDec_ErrorContext::error_internal
2906 ("No TEXT descriptor available for type '%s'.", p_td.name);
2907 const unsigned char *b=p_buf.get_data();
2908 if(b[p_buf.get_len()-1]!='\0'){
2909 p_buf.set_pos(p_buf.get_len());
2910 p_buf.put_zero(8,ORDER_LSB);
2911 p_buf.rewind();
2912 }
2913 if(TEXT_decode(p_td,p_buf,limit)<0)
2914 ec.error(TTCN_EncDec::ET_INCOMPL_MSG,
2915 "Can not decode type '%s', because invalid or incomplete"
2916 " message was received", p_td.name);
2917 break;}
2918 case TTCN_EncDec::CT_XER: {
2919 TTCN_EncDec_ErrorContext ec("While XER-decoding type '%s': ", p_td.name);
2920 unsigned XER_coding=va_arg(pvar, unsigned);
2921 XmlReaderWrap reader(p_buf);
2922 for (int success=reader.Read(); success==1; success=reader.Read()) {
2923 if (reader.NodeType() == XML_READER_TYPE_ELEMENT) break;
2924 }
2925 XER_decode(*(p_td.xer), reader, XER_coding | XER_TOPLEVEL, XER_NONE, 0);
2926 size_t bytes = reader.ByteConsumed();
2927 p_buf.set_pos(bytes);
2928 break;}
2929 case TTCN_EncDec::CT_JSON: {
2930 TTCN_EncDec_ErrorContext ec("While JSON-decoding type '%s': ", p_td.name);
2931 if(!p_td.json) TTCN_EncDec_ErrorContext::error_internal
2932 ("No JSON descriptor available for type '%s'.", p_td.name);
2933 JSON_Tokenizer tok((const char*)p_buf.get_data(), p_buf.get_len());
2934 if(JSON_decode(p_td, tok, false)<0)
2935 ec.error(TTCN_EncDec::ET_INCOMPL_MSG,
2936 "Can not decode type '%s', because invalid or incomplete"
2937 " message was received", p_td.name);
2938 p_buf.set_pos(tok.get_buf_pos());
2939 break;}
2940 default:
2941 TTCN_error("Unknown coding method requested to decode type '%s'", p_td.name);
2942 }
2943 va_end(pvar);
2944 }
2945
2946 ASN_BER_TLV_t* Record_Type::BER_encode_TLV(const TTCN_Typedescriptor_t& p_td, unsigned p_coding) const
2947 {
2948 if (err_descr) {
2949 return BER_encode_TLV_negtest(err_descr, p_td, p_coding);
2950 }
2951 if (!is_bound()) {
2952 TTCN_EncDec_ErrorContext::error
2953 (TTCN_EncDec::ET_UNBOUND, "Encoding an unbound value.");
2954 }
2955 BER_chk_descr(p_td);
2956 ASN_BER_TLV_t *new_tlv=ASN_BER_TLV_t::construct(NULL);
2957 TTCN_EncDec_ErrorContext ec_0("Component '");
2958 TTCN_EncDec_ErrorContext ec_1;
2959 int next_default_idx = 0;
2960 const default_struct* default_indexes = get_default_indexes();
2961 int field_cnt = get_count();
2962 for(int i=0; i<field_cnt; i++) {
2963 boolean is_default_field = default_indexes && (default_indexes[next_default_idx].index==i);
2964 if (!default_as_optional() && is_default_field) {
2965 if (!get_at(i)->is_equal(default_indexes[next_default_idx].value)) {
2966 ec_1.set_msg("%s': ", fld_name(i));
2967 new_tlv->add_TLV(get_at(i)->BER_encode_TLV(*fld_descr(i), p_coding));
2968 }
2969 } else { /* is not DEFAULT */
2970 ec_1.set_msg("%s': ", fld_name(i));
2971 new_tlv->add_TLV(get_at(i)->BER_encode_TLV(*fld_descr(i), p_coding));
2972 } /* !isDefault */
2973 if (is_default_field) next_default_idx++;
2974 } /* for i */
2975 if (is_set())
2976 if (p_coding==BER_ENCODE_DER) new_tlv->sort_tlvs_tag();
2977 new_tlv=ASN_BER_V2TLV(new_tlv, p_td, p_coding);
2978 return new_tlv;
2979 }
2980
2981 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
2982 {
2983 if (!is_bound()) {
2984 TTCN_EncDec_ErrorContext::error
2985 (TTCN_EncDec::ET_UNBOUND, "Encoding an unbound value.");
2986 }
2987 BER_chk_descr(p_td);
2988 ASN_BER_TLV_t *new_tlv=ASN_BER_TLV_t::construct(NULL);
2989 TTCN_EncDec_ErrorContext ec_0("Component '");
2990 TTCN_EncDec_ErrorContext ec_1;
2991 int next_default_idx = 0;
2992 const default_struct* default_indexes = get_default_indexes();
2993 int field_cnt = get_count();
2994
2995 int values_idx = 0;
2996 int edescr_idx = 0;
2997
2998 for (int i=0; i<field_cnt; i++) {
2999 boolean is_default_field = default_indexes && (default_indexes[next_default_idx].index==i);
3000 // the first condition is not needed, kept for ease of understanding
3001 if ( (p_err_descr->omit_before!=-1) && (i<p_err_descr->omit_before) ) {
3002 if (is_default_field) next_default_idx++;
3003 continue;
3004 }
3005 const Erroneous_values_t* err_vals = p_err_descr->next_field_err_values(i, values_idx);
3006 const Erroneous_descriptor_t* emb_descr = p_err_descr->next_field_emb_descr(i, edescr_idx);
3007
3008 if (err_vals && err_vals->before) {
3009 if (err_vals->before->errval==NULL) TTCN_error(
3010 "internal error: erroneous before value missing");
3011 ec_1.set_msg("%s'(erroneous before): ", fld_name(i));
3012 if (err_vals->before->raw) {
3013 new_tlv->add_TLV(err_vals->before->errval->BER_encode_negtest_raw());
3014 } else {
3015 if (err_vals->before->type_descr==NULL) TTCN_error(
3016 "internal error: erroneous before typedescriptor missing");
3017 new_tlv->add_TLV(err_vals->before->errval->BER_encode_TLV(
3018 *err_vals->before->type_descr, p_coding));
3019 }
3020 }
3021
3022 if (err_vals && err_vals->value) {
3023 if (err_vals->value->errval) { // replace
3024 ec_1.set_msg("%s'(erroneous value): ", fld_name(i));
3025 if (err_vals->value->raw) {
3026 new_tlv->add_TLV(err_vals->value->errval->BER_encode_negtest_raw());
3027 } else {
3028 if (err_vals->value->type_descr==NULL) TTCN_error(
3029 "internal error: erroneous value typedescriptor missing");
3030 new_tlv->add_TLV(err_vals->value->errval->BER_encode_TLV(
3031 *err_vals->value->type_descr, p_coding));
3032 }
3033 } // else -> omit
3034 } else {
3035 if (!default_as_optional() && is_default_field) {
3036 if (!get_at(i)->is_equal(default_indexes[next_default_idx].value)) {
3037 ec_1.set_msg("'%s': ", fld_name(i));
3038 if (emb_descr) {
3039 new_tlv->add_TLV(get_at(i)->BER_encode_TLV_negtest(emb_descr,
3040 *fld_descr(i), p_coding));
3041 } else {
3042 new_tlv->add_TLV(get_at(i)->BER_encode_TLV(*fld_descr(i), p_coding));
3043 }
3044 }
3045 } else { /* is not DEFAULT */
3046 ec_1.set_msg("'%s': ", fld_name(i));
3047 if (emb_descr) {
3048 new_tlv->add_TLV(get_at(i)->BER_encode_TLV_negtest(emb_descr,
3049 *fld_descr(i), p_coding));
3050 } else {
3051 new_tlv->add_TLV(get_at(i)->BER_encode_TLV(*fld_descr(i), p_coding));
3052 }
3053 } /* !isDefault */
3054 }
3055
3056 if (err_vals && err_vals->after) {
3057 if (err_vals->after->errval==NULL) TTCN_error(
3058 "internal error: erroneous after value missing");
3059 ec_1.set_msg("%s'(erroneous after): ", fld_name(i));
3060 if (err_vals->after->raw) {
3061 new_tlv->add_TLV(err_vals->after->errval->BER_encode_negtest_raw());
3062 } else {
3063 if (err_vals->after->type_descr==NULL) TTCN_error(
3064 "internal error: erroneous after typedescriptor missing");
3065 new_tlv->add_TLV(err_vals->after->errval->BER_encode_TLV(
3066 *err_vals->after->type_descr, p_coding));
3067 }
3068 }
3069
3070 if (is_default_field) next_default_idx++;
3071 if ( (p_err_descr->omit_after!=-1) && (i>=p_err_descr->omit_after) ) break;
3072 } /* for i */
3073
3074 if (is_set())
3075 if (p_coding==BER_ENCODE_DER) new_tlv->sort_tlvs_tag();
3076 new_tlv=ASN_BER_V2TLV(new_tlv, p_td, p_coding);
3077 return new_tlv;
3078 }
3079
3080 boolean Record_Type::BER_decode_TLV(const TTCN_Typedescriptor_t& p_td,
3081 const ASN_BER_TLV_t& p_tlv, unsigned L_form)
3082 {
3083 BER_chk_descr(p_td);
3084 ASN_BER_TLV_t stripped_tlv;
3085 BER_decode_strip_tags(*p_td.ber, p_tlv, L_form, stripped_tlv);
3086 TTCN_EncDec_ErrorContext ec_0("While decoding '%s' type: ", get_descriptor()->name);
3087 stripped_tlv.chk_constructed_flag(TRUE);
3088 size_t V_pos=0;
3089 ASN_BER_TLV_t tmp_tlv;
3090 if (!is_set())
3091 { /* SEQUENCE decoding */
3092 boolean tlv_present=FALSE;
3093 {
3094 TTCN_EncDec_ErrorContext ec_1("Component '");
3095 TTCN_EncDec_ErrorContext ec_2;
3096 int next_default_idx = 0;
3097 int next_optional_idx = 0;
3098 const default_struct* default_indexes = get_default_indexes();
3099 const int* optional_indexes = get_optional_indexes();
3100 int field_cnt = get_count();
3101 for(int i=0; i<field_cnt; i++) {
3102 boolean is_default_field = default_indexes && (default_indexes[next_default_idx].index==i);
3103 boolean is_optional_field = optional_indexes && (optional_indexes[next_optional_idx]==i);
3104 ec_2.set_msg("%s': ", fld_descr(i)->name);
3105 if (!tlv_present) tlv_present=BER_decode_constdTLV_next(stripped_tlv, V_pos, L_form, tmp_tlv);
3106 if (is_default_field) { /* is DEFAULT */
3107 if (!tlv_present || !get_at(i)->BER_decode_isMyMsg(*fld_descr(i), tmp_tlv)) {
3108 get_at(i)->set_value(default_indexes[next_default_idx].value);
3109 } else {
3110 get_at(i)->BER_decode_TLV(*fld_descr(i), tmp_tlv, L_form);
3111 tlv_present=FALSE;
3112 }
3113 }
3114 else if (is_optional_field) { /* is OPTIONAL */
3115 if (!tlv_present) get_at(i)->set_to_omit();
3116 else {
3117 get_at(i)->BER_decode_TLV(*fld_descr(i), tmp_tlv, L_form);
3118 if (get_at(i)->ispresent()) tlv_present=FALSE;
3119 }
3120 }
3121 else { /* is not DEFAULT OPTIONAL */
3122 if(!tlv_present){
3123 ec_2.error(TTCN_EncDec::ET_INCOMPL_MSG,"Invalid or incomplete message was received.");
3124 return FALSE;
3125 }
3126 get_at(i)->BER_decode_TLV(*fld_descr(i), tmp_tlv, L_form);
3127 tlv_present=FALSE;
3128 } /* !isDefault */
3129 if (is_default_field) next_default_idx++;
3130 if (is_optional_field) next_optional_idx++;
3131 } /* for i */
3132 }
3133 BER_decode_constdTLV_end(stripped_tlv, V_pos, L_form, tmp_tlv, tlv_present);
3134 } /* SEQUENCE decoding */
3135 else
3136 { /* SET decoding */
3137 /* field indicator:
3138 * 0x01: value arrived
3139 * 0x02: is optional / not used :)
3140 * 0x04: has default / not used :)
3141 */
3142 int field_cnt = get_count();
3143 unsigned char* fld_indctr = new unsigned char[field_cnt];
3144 for (int i=0; i<field_cnt; i++) fld_indctr[i] = 0;
3145 int fld_curr = -1; /* ellipsis or error... */
3146 while (BER_decode_constdTLV_next(stripped_tlv, V_pos, L_form, tmp_tlv)) {
3147 for (int i=0; i<field_cnt; i++) {
3148 if (get_at(i)->BER_decode_isMyMsg(*fld_descr(i), tmp_tlv)) {
3149 fld_curr=i;
3150 TTCN_EncDec_ErrorContext ec_1("Component '%s': ", fld_name(i));
3151 get_at(i)->BER_decode_TLV(*fld_descr(i), tmp_tlv, L_form);
3152 break;
3153 }
3154 }
3155 if (fld_curr!=-1) {
3156 if (fld_indctr[fld_curr])
3157 ec_0.error(TTCN_EncDec::ET_DEC_DUPFLD, "Duplicated value for component '%s'.", fld_name(fld_curr));
3158 fld_indctr[fld_curr]=1;
3159 } /* if != -1 */
3160 } /* while */
3161 int next_default_idx = 0;
3162 int next_optional_idx = 0;
3163 const default_struct* default_indexes = get_default_indexes();
3164 const int* optional_indexes = get_optional_indexes();
3165 for (fld_curr=0; fld_curr<field_cnt; fld_curr++) {
3166 boolean is_default_field = default_indexes && (default_indexes[next_default_idx].index==fld_curr);
3167 boolean is_optional_field = optional_indexes && (optional_indexes[next_optional_idx]==fld_curr);
3168 if (!fld_indctr[fld_curr]) {
3169 if (is_default_field) get_at(fld_curr)->set_value(default_indexes[next_default_idx].value);
3170 else if (is_optional_field) get_at(fld_curr)->set_to_omit();
3171 else ec_0.error(TTCN_EncDec::ET_DEC_MISSFLD, "Missing value for component '%s'.", fld_name(fld_curr));
3172 }
3173 if (is_default_field) next_default_idx++;
3174 if (is_optional_field) next_optional_idx++;
3175 }
3176 delete[] fld_indctr;
3177 } /* SET decoding */
3178
3179 if (is_opentype_outermost()) {
3180 TTCN_EncDec_ErrorContext ec_1("While decoding opentypes: ");
3181 TTCN_Type_list p_typelist;
3182 BER_decode_opentypes(p_typelist, L_form);
3183 } /* if sdef->opentype_outermost */
3184 return TRUE;
3185 }
3186
3187 void Record_Type::BER_decode_opentypes(TTCN_Type_list& p_typelist, unsigned L_form)
3188 {
3189 p_typelist.push(this);
3190 TTCN_EncDec_ErrorContext ec_0("Component '");
3191 TTCN_EncDec_ErrorContext ec_1;
3192 int field_cnt = get_count();
3193 for(int i=0; i<field_cnt; i++) {
3194 ec_1.set_msg("%s': ", fld_name(i));
3195 get_at(i)->BER_decode_opentypes(p_typelist, L_form);
3196 } /* for i */
3197 p_typelist.pop();
3198 }
3199
3200 int Record_Type::RAW_encode(const TTCN_Typedescriptor_t& p_td,
3201 RAW_enc_tree& myleaf) const
3202 {
3203 if (err_descr) return RAW_encode_negtest(err_descr, p_td, myleaf);
3204 if (!is_bound()) {
3205 TTCN_EncDec_ErrorContext::error
3206 (TTCN_EncDec::ET_UNBOUND, "Encoding an unbound value.");
3207 }
3208 int encoded_length = 0;
3209 int field_cnt = get_count();
3210 myleaf.isleaf = false;
3211 myleaf.body.node.num_of_nodes = field_cnt;
3212 myleaf.body.node.nodes = init_nodes_of_enc_tree(field_cnt);
3213 /* init nodes */
3214 int next_optional_idx = 0;
3215 const int* optional_indexes = get_optional_indexes();
3216 for (int i = 0; i < field_cnt; i++) {
3217 boolean is_optional_field = optional_indexes
3218 && (optional_indexes[next_optional_idx] == i);
3219 if (!is_optional_field || get_at(i)->ispresent()) {
3220 myleaf.body.node.nodes[i] = new RAW_enc_tree(true, &myleaf,
3221 &(myleaf.curr_pos), i, fld_descr(i)->raw);
3222 }
3223 else {
3224 myleaf.body.node.nodes[i] = NULL;
3225 }
3226 if (is_optional_field) next_optional_idx++;
3227 }
3228 next_optional_idx = 0;
3229 for (int i = 0; i < field_cnt; i++) { /*encoding fields*/
3230 boolean is_optional_field = optional_indexes
3231 && (optional_indexes[next_optional_idx] == i);
3232 /* encoding of normal fields*/
3233 const Base_Type *field = get_at(i);
3234 if (is_optional_field) {
3235 next_optional_idx++;
3236 if (!field->ispresent())
3237 continue; // do not encode
3238 else
3239 field = field->get_opt_value(); // "reach into" the optional
3240 }
3241 encoded_length += field->RAW_encode(*fld_descr(i),
3242 *myleaf.body.node.nodes[i]);
3243 }
3244 return myleaf.length = encoded_length;
3245 }
3246
3247 // In some cases (e.g. LENGTHTO, POINTERTO, CROSSTAG) it is not generated.
3248 int Record_Type::RAW_encode_negtest(const Erroneous_descriptor_t *p_err_descr,
3249 const TTCN_Typedescriptor_t& /*p_td*/, RAW_enc_tree& myleaf) const
3250 {
3251 if (!is_bound()) {
3252 TTCN_EncDec_ErrorContext::error
3253 (TTCN_EncDec::ET_UNBOUND, "Encoding an unbound value.");
3254 }
3255 int encoded_length = 0;
3256 int num_fields = get_count();
3257 myleaf.isleaf = false;
3258 myleaf.body.node.num_of_nodes = 0;
3259 for (int field_idx = 0; field_idx < num_fields; ++field_idx) {
3260 if ((p_err_descr->omit_before != -1) &&
3261 (field_idx < p_err_descr->omit_before))
3262 continue;
3263 else ++myleaf.body.node.num_of_nodes;
3264 const Erroneous_values_t *err_vals = p_err_descr->get_field_err_values(field_idx);
3265 if (err_vals && err_vals->before)
3266 ++myleaf.body.node.num_of_nodes;
3267 if (err_vals && err_vals->value && !err_vals->value->errval)
3268 --myleaf.body.node.num_of_nodes;
3269 if (err_vals && err_vals->after)
3270 ++myleaf.body.node.num_of_nodes;
3271 if ((p_err_descr->omit_after != -1) &&
3272 (field_idx >= p_err_descr->omit_after))
3273 break;
3274 }
3275 myleaf.body.node.nodes = init_nodes_of_enc_tree(myleaf.body.node.num_of_nodes);
3276 TTCN_EncDec_ErrorContext ec;
3277 int next_optional_idx = 0;
3278 const int *my_optional_indexes = get_optional_indexes();
3279 // Counter for fields and additional before/after fields.
3280 int node_pos = 0;
3281 for (int field_idx = 0; field_idx < num_fields; ++field_idx) {
3282 boolean is_optional_field = my_optional_indexes &&
3283 (my_optional_indexes[next_optional_idx] == field_idx);
3284 if ((p_err_descr->omit_before != -1) &&
3285 (field_idx < p_err_descr->omit_before)) {
3286 if (is_optional_field) ++next_optional_idx;
3287 continue;
3288 }
3289 const Erroneous_values_t *err_vals = p_err_descr->get_field_err_values(field_idx);
3290 const Erroneous_descriptor_t *emb_descr = p_err_descr->get_field_emb_descr(field_idx);
3291 if (err_vals && err_vals->before) {
3292 if (err_vals->before->errval == NULL)
3293 TTCN_error("internal error: erroneous before value missing");
3294 if (err_vals->before->raw) {
3295 myleaf.body.node.nodes[node_pos] =
3296 new RAW_enc_tree(true, &myleaf, &(myleaf.curr_pos), node_pos,
3297 err_vals->before->errval->get_descriptor()->raw);
3298 encoded_length += err_vals->before->errval->
3299 RAW_encode_negtest_raw(*myleaf.body.node.nodes[node_pos++]);
3300 } else {
3301 if (err_vals->before->type_descr == NULL)
3302 TTCN_error("internal error: erroneous before typedescriptor missing");
3303 myleaf.body.node.nodes[node_pos] =
3304 new RAW_enc_tree(true, &myleaf, &(myleaf.curr_pos), node_pos,
3305 err_vals->before->type_descr->raw);
3306 encoded_length += err_vals->before->errval->
3307 RAW_encode(*(err_vals->before->type_descr),
3308 *myleaf.body.node.nodes[node_pos++]);
3309 }
3310 }
3311 if (err_vals && err_vals->value) {
3312 if (err_vals->value->errval) {
3313 ec.set_msg("'%s'(erroneous value): ", fld_name(field_idx));
3314 if (err_vals->value->raw) {
3315 myleaf.body.node.nodes[node_pos] =
3316 new RAW_enc_tree(true, &myleaf, &(myleaf.curr_pos), node_pos,
3317 err_vals->value->errval->get_descriptor()->raw);
3318 encoded_length += err_vals->value->errval->
3319 RAW_encode_negtest_raw(*myleaf.body.node.nodes[node_pos++]);
3320 } else {
3321 if (err_vals->value->type_descr == NULL)
3322 TTCN_error("internal error: erroneous value typedescriptor missing");
3323 myleaf.body.node.nodes[node_pos] =
3324 new RAW_enc_tree(true, &myleaf, &(myleaf.curr_pos), node_pos,
3325 err_vals->value->type_descr->raw);
3326 encoded_length += err_vals->value->errval->
3327 RAW_encode(*(err_vals->value->type_descr),
3328 *myleaf.body.node.nodes[node_pos++]);
3329 }
3330 }
3331 } else {
3332 ec.set_msg("'%s': ", fld_name(field_idx));
3333 if (!is_optional_field || get_at(field_idx)->ispresent()) {
3334 const Base_Type *field =
3335 is_optional_field ? get_at(field_idx)->get_opt_value()
3336 : get_at(field_idx);
3337 myleaf.body.node.nodes[node_pos] =
3338 new RAW_enc_tree(true, &myleaf, &(myleaf.curr_pos), node_pos,
3339 fld_descr(field_idx)->raw);
3340 if (emb_descr) {
3341 encoded_length +=
3342 field->RAW_encode_negtest(emb_descr, *fld_descr(field_idx),
3343 *myleaf.body.node.nodes[node_pos++]);
3344 } else {
3345 encoded_length +=
3346 field->RAW_encode(*fld_descr(field_idx),
3347 *myleaf.body.node.nodes[node_pos++]);
3348 }
3349 } else {
3350 // `omitted' field.
3351 myleaf.body.node.nodes[node_pos++] = NULL;
3352 }
3353 }
3354 if (err_vals && err_vals->after) {
3355 if (err_vals->after->errval == NULL)
3356 TTCN_error("internal error: erroneous before value missing");
3357 if (err_vals->after->raw) {
3358 myleaf.body.node.nodes[node_pos] =
3359 new RAW_enc_tree(true, &myleaf, &(myleaf.curr_pos), node_pos,
3360 err_vals->after->errval->get_descriptor()->raw);
3361 encoded_length += err_vals->after->errval->
3362 RAW_encode_negtest_raw(*myleaf.body.node.nodes[node_pos++]);
3363 } else {
3364 if (err_vals->after->type_descr == NULL)
3365 TTCN_error("internal error: erroneous after typedescriptor missing");
3366 myleaf.body.node.nodes[node_pos] =
3367 new RAW_enc_tree(true, &myleaf, &(myleaf.curr_pos), node_pos,
3368 err_vals->after->type_descr->raw);
3369 encoded_length += err_vals->after->errval->
3370 RAW_encode(*(err_vals->after->type_descr),
3371 *myleaf.body.node.nodes[node_pos++]);
3372 }
3373 }
3374 if (is_optional_field) ++next_optional_idx;
3375 if ((p_err_descr->omit_after != -1) &&
3376 (field_idx >= p_err_descr->omit_after))
3377 break;
3378 }
3379 return myleaf.length = encoded_length;
3380 }
3381
3382 int Record_Type::RAW_decode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& buff,
3383 int limit, raw_order_t top_bit_ord, boolean no_err, int, boolean)
3384 {
3385 int field_cnt = get_count();
3386 int opt_cnt = optional_count();
3387 int mand_num = field_cnt - opt_cnt; // expected mandatory fields
3388
3389 raw_order_t local_top_order;
3390 if (p_td.raw->top_bit_order == TOP_BIT_INHERITED) local_top_order = top_bit_ord;
3391 else if (p_td.raw->top_bit_order == TOP_BIT_RIGHT) local_top_order = ORDER_MSB;
3392 else local_top_order = ORDER_LSB;
3393
3394 if (is_set()) { /* set decoder start*/
3395 int prepaddlength = buff.increase_pos_padd(p_td.raw->prepadding);
3396 limit -= prepaddlength;
3397 int decoded_length = 0;
3398 int * const field_map = new int[field_cnt];
3399 memset(field_map, 0, field_cnt * sizeof(int));
3400 int nof_mand_fields = 0; // mandatory fields actually decoded
3401 if (opt_cnt>0) {
3402 const int* optional_indexes = get_optional_indexes();
3403 for (int i=0; i<opt_cnt; i++) get_at(optional_indexes[i])->set_to_omit();
3404 }
3405 while (limit > 0) {
3406 size_t fl_start_pos = buff.get_pos_bit();
3407 int next_optional_idx = 0;
3408 const int* optional_indexes = get_optional_indexes();
3409 for (int i=0; i<field_cnt; i++) { /* decoding fields without TAG */
3410 boolean is_optional_field = optional_indexes && (optional_indexes[next_optional_idx]==i);
3411 if (field_map[i] == 0) {
3412 Base_Type* field_ptr = get_at(i);
3413 if (is_optional_field) {
3414 field_ptr->set_to_present();
3415 field_ptr=field_ptr->get_opt_value();
3416 }
3417 int decoded_field_length = field_ptr->RAW_decode(*fld_descr(i), buff,
3418 limit, local_top_order, TRUE);
3419 if ( (is_optional_field && (decoded_field_length>0)) ||
3420 (!is_optional_field && (decoded_field_length>=0)) ) {
3421 decoded_length += decoded_field_length;
3422 limit -= decoded_field_length;
3423 if (!is_optional_field) nof_mand_fields++;
3424 field_map[i] = 1;
3425 goto continue_while;
3426 } else {
3427 buff.set_pos_bit(fl_start_pos);
3428 if (is_optional_field) get_at(i)->set_to_omit();
3429 }
3430 }
3431 if (is_optional_field) next_optional_idx++;
3432 }//for i
3433 break; // no field could be decoded successfully, quit
3434 continue_while: ;
3435 }
3436 delete[] field_map;
3437 if (mand_num > 0 && nof_mand_fields != mand_num) {
3438 /* Not all required fields were decoded. If there are no bits left,
3439 * that means that the last field was decoded successfully but used up
3440 * the buffer. Signal "incomplete". If there were bits left, that means
3441 * no field could be decoded from them; signal an error. */
3442 return limit ? -1 : -TTCN_EncDec::ET_INCOMPL_MSG;
3443 }
3444 return decoded_length + prepaddlength + buff.increase_pos_padd(p_td.raw->padding);
3445 } else { /* record decoder start */
3446 int prepaddlength = buff.increase_pos_padd(p_td.raw->prepadding);
3447 limit -= prepaddlength;
3448 size_t last_decoded_pos = buff.get_pos_bit();
3449 size_t fl_start_pos;
3450 int decoded_length = 0;
3451 int decoded_field_length = 0;
3452 if (raw_has_ext_bit()) {
3453 const unsigned char* data=buff.get_read_data();
3454 int count=1;
3455 unsigned mask = 1 << (local_top_order==ORDER_LSB ? 0 : 7);
3456 if (p_td.raw->extension_bit==EXT_BIT_YES) {
3457 while((data[count-1] & mask) == 0 && count * 8 < (int)limit) count++;
3458 }
3459 else {
3460 while((data[count-1] & mask) != 0 && count * 8 < (int)limit) count++;
3461 }
3462 if(limit) limit=count*8;
3463 }
3464
3465 int next_optional_idx = 0;
3466 const int* optional_indexes = get_optional_indexes();
3467 for (int i=0; i<field_cnt; i++) { /* decoding fields */
3468 boolean is_optional_field = optional_indexes && (optional_indexes[next_optional_idx]==i);
3469 /* check if enough bits to decode the field*/
3470 if (!is_optional_field || (limit>0)) {
3471 /* decoding of normal field */
3472 fl_start_pos = buff.get_pos_bit();
3473 Base_Type* field_ptr = get_at(i);
3474 if (is_optional_field) {
3475 field_ptr->set_to_present();
3476 field_ptr=field_ptr->get_opt_value();
3477 }
3478 decoded_field_length = field_ptr->RAW_decode(*fld_descr(i), buff, limit,
3479 local_top_order, is_optional_field ? TRUE : no_err);
3480 boolean field_present = TRUE;
3481 if (is_optional_field) {
3482 if (decoded_field_length < 1) { // swallow any error and become omit
3483 field_present = FALSE;
3484 get_at(i)->set_to_omit();
3485 buff.set_pos_bit(fl_start_pos);
3486 }
3487 } else {
3488 if (decoded_field_length < 0) return decoded_field_length;
3489 }
3490 if (field_present) {
3491 decoded_length+=decoded_field_length;
3492 limit-=decoded_field_length;
3493 last_decoded_pos=last_decoded_pos<buff.get_pos_bit()?buff.get_pos_bit():last_decoded_pos;
3494 }
3495 } else {
3496 get_at(i)->set_to_omit();
3497 }
3498 if (is_optional_field) next_optional_idx++;
3499 } /* decoding fields*/
3500
3501 buff.set_pos_bit(last_decoded_pos);
3502 return decoded_length+prepaddlength+buff.increase_pos_padd(p_td.raw->padding);
3503 } /* record decoder end*/
3504 }
3505
3506 int Record_Type::TEXT_encode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& buff) const
3507 {
3508 if (err_descr) {
3509 return TEXT_encode_negtest(err_descr, p_td, buff);
3510 }
3511 if (!is_bound()) {
3512 TTCN_EncDec_ErrorContext::error
3513 (TTCN_EncDec::ET_UNBOUND, "Encoding an unbound value.");
3514 }
3515 bool need_separator=false;
3516 int encoded_length=0;
3517 if (p_td.text->begin_encode) {
3518 buff.put_cs(*p_td.text->begin_encode);
3519 encoded_length+=p_td.text->begin_encode->lengthof();
3520 }
3521 int next_optional_idx = 0;
3522 const int* optional_indexes = get_optional_indexes();
3523 int field_cnt = get_count();
3524 for(int i=0;i<field_cnt;i++) {
3525 boolean is_optional_field = optional_indexes && (optional_indexes[next_optional_idx]==i);
3526 if (!is_optional_field || get_at(i)->ispresent()) {
3527 if (need_separator && p_td.text->separator_encode) {
3528 buff.put_cs(*p_td.text->separator_encode);
3529 encoded_length+=p_td.text->separator_encode->lengthof();
3530 }
3531 encoded_length += get_at(i)->TEXT_encode(*fld_descr(i),buff);
3532 need_separator=true;
3533 }
3534 if (is_optional_field) next_optional_idx++;
3535 }
3536 if (p_td.text->end_encode) {
3537 buff.put_cs(*p_td.text->end_encode);
3538 encoded_length+=p_td.text->end_encode->lengthof();
3539 }
3540 return encoded_length;
3541 }
3542
3543 /**
3544 * TEXT encode negative testing
3545 */
3546 int Record_Type::TEXT_encode_negtest(const Erroneous_descriptor_t* p_err_descr, const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& buff) const
3547 {
3548 if (!is_bound()) {
3549 TTCN_EncDec_ErrorContext::error
3550 (TTCN_EncDec::ET_UNBOUND, "Encoding an unbound value.");
3551 }
3552 bool need_separator=false;
3553 int encoded_length=0;
3554 if (p_td.text->begin_encode) {
3555 buff.put_cs(*p_td.text->begin_encode);
3556 encoded_length+=p_td.text->begin_encode->lengthof();
3557 }
3558 int next_optional_idx = 0;
3559 const int* optional_indexes = get_optional_indexes();
3560 int field_cnt = get_count();
3561
3562 int values_idx = 0;
3563 int edescr_idx = 0;
3564
3565 for(int i=0;i<field_cnt;i++) {
3566 boolean is_optional_field = optional_indexes && (optional_indexes[next_optional_idx]==i);
3567
3568 if ( (p_err_descr->omit_before!=-1) && (i<p_err_descr->omit_before) ) {
3569 if (is_optional_field) next_optional_idx++;
3570 continue;
3571 }
3572
3573 const Erroneous_values_t* err_vals = p_err_descr->next_field_err_values(i, values_idx);
3574 const Erroneous_descriptor_t* emb_descr = p_err_descr->next_field_emb_descr(i, edescr_idx);
3575
3576 if (err_vals && err_vals->before) {
3577 if (err_vals->before->errval==NULL) TTCN_error(
3578 "internal error: erroneous before value missing");
3579
3580 if (need_separator && p_td.text->separator_encode) {
3581 buff.put_cs(*p_td.text->separator_encode);
3582 encoded_length+=p_td.text->separator_encode->lengthof();
3583 }
3584 if (err_vals->before->raw) {
3585 encoded_length += err_vals->before->errval->encode_raw(buff);
3586 } else {
3587 if (err_vals->before->type_descr==NULL) TTCN_error(
3588 "internal error: erroneous before typedescriptor missing");
3589 encoded_length += err_vals->before->errval->TEXT_encode(
3590 *(err_vals->before->type_descr),buff);
3591 }
3592 need_separator=true;
3593 }
3594
3595 if (err_vals && err_vals->value) {
3596 if (err_vals->value->errval) {
3597 if (need_separator && p_td.text->separator_encode) {
3598 buff.put_cs(*p_td.text->separator_encode);
3599 encoded_length+=p_td.text->separator_encode->lengthof();
3600 }
3601 if (err_vals->value->raw) {
3602 encoded_length += err_vals->value->errval->encode_raw(buff);
3603 } else {
3604 if (err_vals->value->type_descr==NULL) TTCN_error(
3605 "internal error: erroneous value typedescriptor missing");
3606 encoded_length += err_vals->value->errval->TEXT_encode(
3607 *(err_vals->value->type_descr),buff);
3608 }
3609 need_separator=true;
3610 } // else -> omit
3611 } else {
3612 if (!is_optional_field || get_at(i)->ispresent()) {
3613 if (need_separator && p_td.text->separator_encode) {
3614 buff.put_cs(*p_td.text->separator_encode);
3615 encoded_length+=p_td.text->separator_encode->lengthof();
3616 }
3617 if (emb_descr) {
3618 encoded_length += get_at(i)->TEXT_encode_negtest(emb_descr, *fld_descr(i),buff);
3619 } else {
3620 encoded_length += get_at(i)->TEXT_encode(*fld_descr(i),buff);
3621 }
3622 need_separator=true;
3623 }
3624 }
3625
3626 if (err_vals && err_vals->after) {
3627 if (err_vals->after->errval==NULL) TTCN_error(
3628 "internal error: erroneous after value missing");
3629 if (need_separator && p_td.text->separator_encode) {
3630 buff.put_cs(*p_td.text->separator_encode);
3631 encoded_length+=p_td.text->separator_encode->lengthof();
3632 }
3633 if (err_vals->after->raw) {
3634 encoded_length += err_vals->after->errval->encode_raw(buff);
3635 } else {
3636 if (err_vals->after->type_descr==NULL) TTCN_error(
3637 "internal error: erroneous after typedescriptor missing");
3638 encoded_length += err_vals->after->errval->TEXT_encode(
3639 *(err_vals->after->type_descr),buff);
3640 }
3641 need_separator=true;
3642 }
3643
3644 if (is_optional_field) next_optional_idx++;
3645
3646 if ( (p_err_descr->omit_after!=-1) && (i>=p_err_descr->omit_after) ) break;
3647 }
3648 if (p_td.text->end_encode) {
3649 buff.put_cs(*p_td.text->end_encode);
3650 encoded_length+=p_td.text->end_encode->lengthof();
3651 }
3652 return encoded_length;
3653 }
3654
3655 int Record_Type::TEXT_decode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& buff,
3656 Limit_Token_List& limit, boolean no_err, boolean /*first_call*/)
3657 {
3658 if (is_set()) {
3659 int decoded_length=0;
3660 int decoded_field_length=0;
3661 size_t pos=buff.get_pos();
3662 boolean sep_found=FALSE;
3663 int ml=0;
3664 int sep_length=0;
3665 int loop_detector=1;
3666 int last_field_num=-1;
3667 if (p_td.text->begin_decode) {
3668 int tl;
3669 if ((tl=p_td.text->begin_decode->match_begin(buff))<0) {
3670 if(no_err) return -1;
3671 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR,
3672 "The specified token '%s' not found for '%s': ",
3673 (const char*)*(p_td.text->begin_decode), p_td.name);
3674 return 0;
3675 }
3676 decoded_length+=tl;
3677 buff.increase_pos(tl);
3678 }
3679 if (p_td.text->end_decode) {
3680 limit.add_token(p_td.text->end_decode);
3681 ml++;
3682 }
3683 if(p_td.text->separator_decode){
3684 limit.add_token(p_td.text->separator_decode);
3685 ml++;
3686 }
3687
3688 int field_cnt = get_count();
3689 int * const field_map = new int[field_cnt];
3690 memset(field_map, 0, field_cnt * sizeof(int));
3691
3692 int mand_field_num = 0;
3693 int opt_field_num = 0;
3694 int seof = 0;
3695 int has_repeatable=0;
3696 boolean repeatable = TRUE;
3697
3698 int next_optional_idx = 0;
3699 const int* optional_indexes = get_optional_indexes();
3700 for (int i=0;i<field_cnt;i++) {
3701 boolean is_optional_field = optional_indexes && (optional_indexes[next_optional_idx]==i);
3702 if (is_optional_field) {
3703 get_at(i)->set_to_omit();
3704 opt_field_num++;
3705 } else {
3706 mand_field_num++;
3707 }
3708 if (get_at(i)->is_seof()) {
3709 seof++;
3710 repeatable = repeatable && fld_descr(i)->text->val.parameters->decoding_params.repeatable;
3711 }
3712 if (is_optional_field) next_optional_idx++;
3713 }
3714 boolean has_optinals = opt_field_num > 0;
3715 if ((seof>0) && repeatable) has_repeatable=1;
3716
3717 while (mand_field_num+opt_field_num+has_repeatable) {
3718 loop_detector=1;
3719 /*while (TRUE)*/
3720 {
3721 next_optional_idx = 0;
3722 for (int i=0;i<field_cnt;i++) {
3723 boolean is_optional_field = optional_indexes && (optional_indexes[next_optional_idx]==i);
3724 if (get_at(i)->is_seof()) {
3725 if ( (fld_descr(i)->text->val.parameters->decoding_params.repeatable && field_map[i]<3)
3726 || !field_map[i] ) {
3727 pos=buff.get_pos();
3728 decoded_field_length = get_at(i)->TEXT_decode(*fld_descr(i),buff, limit, true,!field_map[i]);
3729 if (decoded_field_length<0) {
3730 buff.set_pos(pos);
3731 if (is_optional_field && !field_map[i]) get_at(i)->set_to_omit();
3732 } else {
3733 loop_detector=0;
3734 if (!field_map[i]) {
3735 if (is_optional_field) opt_field_num--;
3736 else mand_field_num--;
3737 field_map[i]=1;
3738 } else field_map[i]=2;
3739 last_field_num=i;
3740 break;
3741 }
3742 }
3743 } else { // !...->is_seof
3744 if (!field_map[i]) {
3745 pos=buff.get_pos();
3746 decoded_field_length = get_at(i)->TEXT_decode(*fld_descr(i),buff,limit,true);
3747 if (decoded_field_length<0) {
3748 buff.set_pos(pos);
3749 if (is_optional_field) get_at(i)->set_to_omit();
3750 } else {
3751 loop_detector=0;
3752 field_map[i]=1;
3753 if (is_optional_field) opt_field_num--;
3754 else mand_field_num--;
3755 last_field_num=i;
3756 break;
3757 }
3758 }
3759 } // !...->is_seof
3760 if (is_optional_field) next_optional_idx++;
3761 } // for i
3762 /* break*/
3763 }
3764 if (loop_detector) break;
3765 if (p_td.text->separator_decode) {
3766 int tl;
3767 if ((tl=p_td.text->separator_decode->match_begin(buff))<0) {
3768 if (p_td.text->end_decode) {
3769 int tl2;
3770 if ((tl2=p_td.text->end_decode->match_begin(buff))!=-1) {
3771 sep_found=FALSE;
3772 break;
3773 }
3774 } else if (limit.has_token(ml)) {
3775 int tl2;
3776 if ((tl2=limit.match(buff,ml))==0) {
3777 sep_found=FALSE;
3778 break;
3779 }
3780 } else break;
3781 buff.set_pos(pos);
3782 decoded_length-=decoded_field_length;
3783 field_map[last_field_num]+=2;
3784
3785 if (has_optinals) {
3786 if (last_field_num>=0 && last_field_num<field_cnt) {
3787 if (get_at(last_field_num)->is_seof()) {
3788 if (get_at(last_field_num)->is_optional()) {
3789 if (field_map[last_field_num]==3) {
3790 get_at(last_field_num)->set_to_omit();
3791 opt_field_num++;
3792 }
3793 } else {
3794 if (field_map[last_field_num]==3) {
3795 mand_field_num++;
3796 }
3797 }
3798 } else if (get_at(last_field_num)->is_optional()) {
3799 get_at(last_field_num)->set_to_omit();
3800 opt_field_num++;
3801 } else {
3802 mand_field_num++;
3803 }
3804 } else {
3805 mand_field_num++;
3806 }
3807 } // if (has_optinals)
3808 } else {
3809 sep_length=tl;
3810 decoded_length+=tl;
3811 buff.increase_pos(tl);
3812 for (int a=0;a<field_cnt;a++) if(field_map[a]>2) field_map[a]-=3;
3813 sep_found=TRUE;
3814 }
3815 } else if (p_td.text->end_decode) {
3816 int tl;
3817 if ((tl=p_td.text->end_decode->match_begin(buff))!=-1) {
3818 decoded_length+=tl;
3819 buff.increase_pos(tl);
3820 limit.remove_tokens(ml);
3821 if (mand_field_num) decoded_length = -1;
3822 goto bail;
3823 }
3824 } else if(limit.has_token(ml)){
3825 int tl;
3826 if ((tl=limit.match(buff,ml))==0) {
3827 sep_found=FALSE;
3828 break;
3829 }
3830 }
3831 } // while ( + + )
3832 limit.remove_tokens(ml);
3833 if (sep_found) {
3834 if (mand_field_num) {
3835 if (no_err) decoded_length = -1;
3836 else TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR,
3837 "Error during decoding '%s': ", p_td.name);
3838 goto bail;
3839 } else {
3840 decoded_length-=sep_length;
3841 buff.set_pos(buff.get_pos()-sep_length);
3842 }
3843 }
3844 if (p_td.text->end_decode) {
3845 int tl;
3846 if ((tl=p_td.text->end_decode->match_begin(buff))<0) {
3847 if (no_err) decoded_length = -1;
3848 else TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR,
3849 "The specified token '%s' not found for '%s': ",
3850 (const char*)*(p_td.text->end_decode),p_td.name);
3851 goto bail;
3852 }
3853 decoded_length+=tl;
3854 buff.increase_pos(tl);
3855 }
3856 if (mand_field_num) decoded_length = -1;
3857 bail:
3858 delete[] field_map;
3859 return decoded_length;
3860 } else { // record decoder
3861 int decoded_length=0;
3862 int decoded_field_length=0;
3863 size_t pos=buff.get_pos();
3864 boolean sep_found=FALSE;
3865 int sep_length=0;
3866 int ml=0;
3867 if (p_td.text->begin_decode) {
3868 int tl;
3869 if ((tl=p_td.text->begin_decode->match_begin(buff))<0) {
3870 if(no_err)return -1;
3871 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR,
3872 "The specified token '%s' not found for '%s': ",
3873 (const char*)*(p_td.text->begin_decode), p_td.name);
3874 return 0;
3875 }
3876 decoded_length+=tl;
3877 buff.increase_pos(tl);
3878 }
3879 if (p_td.text->end_decode) {
3880 limit.add_token(p_td.text->end_decode);
3881 ml++;
3882 }
3883 if (p_td.text->separator_decode) {
3884 limit.add_token(p_td.text->separator_decode);
3885 ml++;
3886 }
3887
3888 int mand_field_num = 0;
3889 int opt_field_num = 0;
3890 int last_man_index = 0;
3891
3892 int field_cnt = get_count();
3893 int next_optional_idx = 0;
3894 const int* optional_indexes = get_optional_indexes();
3895 for (int i=0;i<field_cnt;i++) {
3896 boolean is_optional_field = optional_indexes && (optional_indexes[next_optional_idx]==i);
3897 if (is_optional_field) {
3898 get_at(i)->set_to_omit();
3899 opt_field_num++;
3900 } else {
3901 last_man_index=i+1;
3902 mand_field_num++;
3903 }
3904 if (is_optional_field) next_optional_idx++;
3905 }
3906
3907 next_optional_idx = 0;
3908 for(int i=0;i<field_cnt;i++) {
3909 boolean is_optional_field = optional_indexes && (optional_indexes[next_optional_idx]==i);
3910 if (is_optional_field) {
3911 pos=buff.get_pos();
3912 }
3913 decoded_field_length = get_at(i)->TEXT_decode(*fld_descr(i),buff,limit,TRUE);
3914 if (decoded_field_length<0) {
3915 if (is_optional_field) {
3916 get_at(i)->set_to_omit();
3917 buff.set_pos(pos);
3918 } else {
3919 limit.remove_tokens(ml);
3920 if (no_err) return -1;
3921 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR,
3922 "Error during decoding field '%s' for '%s': ",
3923 fld_descr(i)->name, p_td.name);
3924 return decoded_length;
3925 }
3926 } else {
3927 decoded_length+=decoded_field_length;
3928 if (last_man_index>(i+1)) {
3929 if (p_td.text->separator_decode) {
3930 int tl;
3931 if ((tl=p_td.text->separator_decode->match_begin(buff))<0) {
3932 if(is_optional_field) {
3933 get_at(i)->set_to_omit();
3934 buff.set_pos(pos);
3935 decoded_length-=decoded_field_length;
3936 } else {
3937 limit.remove_tokens(ml);
3938 if(no_err)return -1;
3939 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR,
3940 "The specified token '%s' not found for '%s': ",
3941 (const char*)*(p_td.text->separator_decode),p_td.name);
3942 return decoded_length;
3943 }
3944 } else {
3945 decoded_length+=tl;
3946 buff.increase_pos(tl);
3947 sep_length=tl;
3948 sep_found=TRUE;
3949 }
3950 } else sep_found=FALSE;
3951
3952 } else if (i==(field_cnt-1)) {
3953 sep_found=FALSE;
3954 } else {
3955 if (p_td.text->separator_decode) {
3956 int tl;
3957 if ((tl=p_td.text->separator_decode->match_begin(buff))<0) {
3958 if (is_optional_field) {
3959 if (p_td.text->end_decode) {
3960 if ((tl=p_td.text->end_decode->match_begin(buff))!=-1) {
3961 decoded_length+=tl;
3962 buff.increase_pos(tl);
3963 limit.remove_tokens(ml);
3964 return decoded_length;
3965 }
3966 } else if (limit.has_token(ml)) {
3967 if ((tl=limit.match(buff,ml))==0) {
3968 sep_found=FALSE;
3969 break;
3970 }
3971 } else break;
3972 get_at(i)->set_to_omit();
3973 buff.set_pos(pos);
3974 decoded_length-=decoded_field_length;
3975 } else {
3976 sep_found=FALSE;
3977 break;
3978 }
3979 } else {
3980 decoded_length+=tl;
3981 buff.increase_pos(tl);
3982 sep_length=tl;
3983 sep_found=TRUE;
3984 }
3985 } else {
3986 sep_found=FALSE;
3987 int tl;
3988 if (p_td.text->end_decode) {
3989 if ((tl=p_td.text->end_decode->match_begin(buff))!=-1) {
3990 decoded_length+=tl;
3991 buff.increase_pos(tl);
3992 limit.remove_tokens(ml);
3993 return decoded_length;
3994 }
3995 } else if (limit.has_token(ml)) {
3996 if ((tl=limit.match(buff,ml))==0) {
3997 sep_found=FALSE;
3998 break;
3999 }
4000 }
4001 }
4002 }
4003 }
4004 if (is_optional_field) next_optional_idx++;
4005 } // for i
4006 limit.remove_tokens(ml);
4007 if (sep_found) {
4008 buff.set_pos(buff.get_pos()-sep_length);
4009 decoded_length-=sep_length;
4010 }
4011 if (p_td.text->end_decode) {
4012 int tl;
4013 if ((tl=p_td.text->end_decode->match_begin(buff))<0) {
4014 if(no_err)return -1;
4015 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR,
4016 "The specified token '%s' not found for '%s': ",
4017 (const char*)*(p_td.text->end_decode),p_td.name);
4018 return decoded_length;
4019 }
4020 decoded_length+=tl;
4021 buff.increase_pos(tl);
4022 }
4023 return decoded_length;
4024 } // record decoder
4025 }
4026
4027 const XERdescriptor_t* Record_Type::xer_descr(int /*field_index*/) const
4028 {
4029 TTCN_error("Internal error: Record_Type::xer_descr() called.");
4030 return NULL;
4031 }
4032
4033 char ** Record_Type::collect_ns(const XERdescriptor_t& p_td, size_t& num, bool& def_ns) const
4034 {
4035 const int field_cnt = get_count();
4036 // The USE-ORDER member is first, unless preempted by EMBED-VALUES
4037 const int uo_index = ((p_td.xer_bits & EMBED_VALUES) !=0);
4038 // Index of the first "normal" member (after E-V and U-O)
4039 const int start_at = uo_index + ((p_td.xer_bits & USE_ORDER) != 0);
4040
4041 size_t num_collected = 0;
4042 // First, our own namespace. Sets num_collected to 0 or 1.
4043 // If it throws, nothing was allocated.
4044 char **collected_ns = Base_Type::collect_ns(p_td, num_collected, def_ns);
4045
4046 try{
4047 // If the nil attribute will be written, add the control namespace
4048 boolean nil_attribute = (p_td.xer_bits & USE_NIL)
4049 && !get_at(field_cnt-1)->ispresent();
4050
4051 if (nil_attribute) {
4052 collected_ns = (char**)Realloc(collected_ns, sizeof(char*) * ++num_collected);
4053 const namespace_t *c_ns = p_td.my_module->get_controlns();
4054
4055 collected_ns[num_collected-1] = mprintf(" xmlns:%s='%s'", c_ns->px, c_ns->ns);
4056 }
4057
4058 // Collect namespace declarations from all components (recursively).
4059 // This is extremely nasty, but we can't prosecute you for that.
4060 // (Monty Python - Crunchy Frog sketch). This whole thing is O(n^3). Yuck.
4061 for (int a = start_at; a < field_cnt; ++a) {
4062 size_t num_new = 0;
4063 bool def_ns_1 = false;
4064 char **new_namespaces = get_at(a)->collect_ns(*xer_descr(a), num_new, def_ns_1);
4065 merge_ns(collected_ns, num_collected, new_namespaces, num_new);
4066 def_ns = def_ns || def_ns_1;
4067 // merge_ns freed new_namespaces
4068 } // next field
4069 }
4070 catch (...) {
4071 // Probably a TC_Error thrown from the element's collect_ns(),
4072 // e.g. if encoding an unbound value.
4073 while (num_collected > 0) Free(collected_ns[--num_collected]);
4074 Free(collected_ns);
4075 throw;
4076 }
4077
4078 num = num_collected;
4079 return collected_ns;
4080 }
4081
4082 // FIXME some hashing should be implemented
4083 int Record_Type::get_index_byname(const char *name, const char *uri) const {
4084 int num_fields = get_count();
4085 for (int i = 0; i < num_fields; ++i) {
4086 const XERdescriptor_t& xer = *xer_descr(i);
4087 if (check_name(name, xer, TRUE)
4088 && check_namespace(uri, xer)) return i;
4089 }
4090 return -1;
4091 }
4092
4093 int Record_Type::XER_encode(const XERdescriptor_t& p_td, TTCN_Buffer& p_buf,
4094 unsigned int flavor, int indent, embed_values_enc_struct_t*) const
4095 {
4096 if (err_descr) {
4097 return XER_encode_negtest(err_descr, p_td, p_buf, flavor, indent, 0);
4098 }
4099 if (!is_bound()) {
4100 TTCN_EncDec_ErrorContext::error
4101 (TTCN_EncDec::ET_UNBOUND, "Encoding an unbound value.");
4102 }
4103
4104 TTCN_EncDec_ErrorContext ec_0("Component '");
4105 TTCN_EncDec_ErrorContext ec_1;
4106 int encoded_length=(int)p_buf.get_len(); // how much is already in the buffer
4107
4108 int exer = is_exer(flavor);
4109 if (exer && (p_td.xer_bits & EMBED_VALUES)) flavor |= XER_CANONICAL;
4110 const boolean indenting = !is_canonical(flavor);
4111 const int field_cnt = get_count();
4112 const int num_attributes = get_xer_num_attr();
4113 // The USE-ORDER member is first, unless preempted by EMBED-VALUES
4114 const int uo_index = ((p_td.xer_bits & EMBED_VALUES) !=0);
4115 // Index of the first "normal" member (after E-V and U-O)
4116 const int start_at = uo_index + ((p_td.xer_bits & USE_ORDER) != 0);
4117 const int first_nonattr = start_at + num_attributes;
4118 // start_tag_len is keeping track of how much was written at the end of the
4119 // start tag, i.e. the ">\n". This is used later to "back up" over it.
4120 int start_tag_len = 1 + indenting;
4121 // The EMBED-VALUES member, if applicable
4122 const Record_Of_Type* embed_values = 0;
4123 if (p_td.xer_bits & EMBED_VALUES) {
4124 embed_values = dynamic_cast<const Record_Of_Type*>(get_at(0));
4125 if (NULL == embed_values) {
4126 const OPTIONAL<Record_Of_Type>* const embed_opt = static_cast<const OPTIONAL<Record_Of_Type>*>(get_at(0));
4127 if(embed_opt->is_present()) {
4128 embed_values = &(*embed_opt)();
4129 }
4130 }
4131 }
4132 // The USE-ORDER member, if applicable
4133 const Record_Of_Type* const use_order = (p_td.xer_bits & USE_ORDER)
4134 ? static_cast<const Record_Of_Type*>(get_at(uo_index)) : 0;
4135
4136 size_t num_collected = 0; // we use this to compute delay_close
4137 char **collected_ns = NULL;
4138 bool def_ns = false;
4139 if (exer) {
4140 if (indent == 0) { // top-level type
4141 collected_ns = collect_ns(p_td, num_collected, def_ns);
4142 }
4143 else if ((flavor & DEF_NS_SQUASHED) && p_td.my_module && p_td.ns_index != -1) {
4144 const namespace_t * ns = p_td.my_module->get_ns(p_td.ns_index);
4145 // The default namespace has been squashed.
4146 // If we are in the default namespace, restore it.
4147 if (*ns->px == '\0') {
4148 collected_ns = Base_Type::collect_ns(p_td, num_collected, def_ns);
4149 }
4150 }
4151 }
4152
4153 // The type's own tag is omitted if we're doing E-XER,
4154 // and it's not the top-level type (XML must have a root element)
4155 // and it's either UNTAGGED or got USE_NIL or USE_TYPE or USE_UNION.
4156 boolean omit_tag = exer && (indent > 0)
4157 && ( (p_td.xer_bits & (UNTAGGED|XER_ATTRIBUTE))
4158 || (flavor & (USE_NIL|USE_TYPE_ATTR)));
4159
4160 // If a default namespace is in effect (uri but no prefix) and the type
4161 // is unqualified, the default namespace must be canceled; otherwise
4162 // an XML tag without a ns prefix looks like it belongs to the def.namespace
4163 const boolean empty_ns_hack = exer && !omit_tag && (indent > 0)
4164 && (p_td.xer_bits & FORM_UNQUALIFIED)
4165 && (flavor & DEF_NS_PRESENT);
4166
4167 // delay_close=true if there is stuff before the '>' of the start tag
4168 // (prevents writing the '>' which is built into the name).
4169 // This can only happen for EXER: if there are attributes or namespaces,
4170 // or either USE-NIL or USE-QNAME is set.
4171 boolean delay_close = exer && (num_attributes
4172 || empty_ns_hack // counts as having a namespace
4173 || (num_collected != 0)
4174 || (p_td.xer_bits & (USE_NIL|USE_QNAME))
4175 || (flavor & USE_NIL));
4176
4177 size_t shorter = 0;
4178
4179 if (!omit_tag) { /* write start tag */
4180 if (indenting) do_indent(p_buf, indent);
4181 /* name looks like this: "tagname>\n"
4182 * lose the \n if : not indenting or (single untagged(*) or attributes (*)) AND exer
4183 * lose the > if attributes are present (*) AND exer
4184 */
4185 p_buf.put_c('<');
4186 if (exer) write_ns_prefix(p_td, p_buf);
4187 p_buf.put_s((size_t)p_td.namelens[exer] - delay_close
4188 - (!indenting || delay_close || (exer && (p_td.xer_bits & HAS_1UNTAGGED))),
4189 (cbyte*)p_td.names[exer]);
4190 }
4191 else if (flavor & (USE_NIL|USE_TYPE_ATTR)) {
4192 // reopen the parent's start tag by overwriting the '>'
4193 size_t buf_len = p_buf.get_len();
4194 const unsigned char * const buf_data = p_buf.get_data();
4195 if (buf_data[buf_len - 1 - shorter] == '\n') ++shorter;
4196 if (buf_data[buf_len - 1 - shorter] == '>' ) ++shorter;
4197
4198 if (shorter) {
4199 p_buf.increase_length(-shorter);
4200 }
4201 delay_close = TRUE;
4202 }
4203
4204 int sub_len=0;
4205 // mask out extra flags we received, do not send them to the fields
4206 flavor &= XER_MASK;
4207
4208 if (exer && (p_td.xer_bits & USE_QNAME)) { // QName trumps everything
4209 const Base_Type * const q_uri = get_at(0);
4210 if (q_uri->is_present()) {
4211 p_buf.put_s(11, (cbyte*)" xmlns:b0='");
4212 q_uri->XER_encode(*xer_descr(0), p_buf, flavor | XER_LIST, indent+1, 0);
4213 p_buf.put_c('\'');
4214 }
4215
4216 if (p_td.xer_bits & XER_ATTRIBUTE) begin_attribute(p_td, p_buf);
4217 else p_buf.put_c('>');
4218
4219 if (q_uri->is_present()) {
4220 p_buf.put_s(3, (cbyte*)"b0:");
4221 sub_len += 3;
4222 }
4223 const Base_Type* const q_name = get_at(1);
4224 sub_len += q_name->XER_encode(*xer_descr(1), p_buf, flavor | XER_LIST, indent+1, 0);
4225 if (p_td.xer_bits & XER_ATTRIBUTE) p_buf.put_c('\'');
4226 }
4227 else { // not USE-QNAME
4228 if (!exer && (p_td.xer_bits & EMBED_VALUES) && embed_values != NULL) {
4229 // The EMBED-VALUES member as an ordinary record of string
4230 sub_len += embed_values->XER_encode(*xer_descr(0), p_buf, flavor, indent+1, 0);
4231 }
4232
4233 if (!exer && (p_td.xer_bits & USE_ORDER)) {
4234 // The USE-ORDER member as an ordinary record of enumerated
4235 sub_len += use_order->XER_encode(*xer_descr(uo_index), p_buf, flavor, indent+1, 0);
4236 }
4237
4238 if (exer && (indent==0 || (flavor & DEF_NS_SQUASHED))) // write namespaces for toplevel only
4239 {
4240 for (size_t cur_coll = 0; cur_coll < num_collected; ++cur_coll) {
4241 p_buf.put_s(strlen(collected_ns[cur_coll]), (cbyte*)collected_ns[cur_coll]);
4242 Free(collected_ns[cur_coll]); // job done
4243 }
4244 Free(collected_ns);
4245 }
4246
4247 if (def_ns) {
4248 flavor &= ~DEF_NS_SQUASHED;
4249 flavor |= DEF_NS_PRESENT;
4250 }
4251 else if (empty_ns_hack) {
4252 p_buf.put_s(9, (cbyte*)" xmlns=''");
4253 flavor &= ~DEF_NS_PRESENT;
4254 flavor |= DEF_NS_SQUASHED;
4255 }
4256
4257 /* First all the attributes (not added to sub_len) */
4258 int i;
4259 for (i = start_at; i < first_nonattr; ++i) {
4260 boolean is_xer_attr_field = xer_descr(i)->xer_bits & XER_ATTRIBUTE;
4261 ec_1.set_msg("%s': ", fld_name(i)); // attr
4262 int tmp_len = get_at(i)->XER_encode(*xer_descr(i), p_buf, flavor, indent+1, 0);
4263 if (is_xer_attr_field && !exer) sub_len += tmp_len; /* do not add if attribute and EXER */
4264 }
4265
4266 // True if the "nil" attribute needs to be written.
4267 boolean nil_attribute = exer && (p_td.xer_bits & USE_NIL)
4268 && !get_at(field_cnt-1)->ispresent();
4269
4270 // True if USE_ORDER is in effect and the "nil" attribute was written.
4271 // Then the record-of-enum for USE-ORDER will be empty.
4272 boolean early_to_bed = FALSE;
4273
4274 if (nil_attribute) { // req. exer and USE_NIL
4275 const namespace_t *control_ns = p_td.my_module->get_controlns();
4276 p_buf.put_c(' ');
4277 p_buf.put_s(strlen(control_ns->px),
4278 (cbyte*)control_ns->px);
4279 p_buf.put_c(':');
4280 p_buf.put_s(10, (cbyte*)"nil='true'");
4281 if ((p_td.xer_bits & USE_ORDER)) early_to_bed = TRUE;
4282 // The whole content was omitted; nothing to do (and if we tried
4283 // to do it, we'd get an error for over-indexing a 0-length record-of).
4284 }
4285
4286 if (delay_close && (!omit_tag || shorter)) {
4287 // Close the start tag left open. If indenting, also write a newline
4288 // unless USE-NIL in effect or there is a single untagged component.
4289 start_tag_len = 1 +
4290 ((p_td.xer_bits & (/*USE_NIL|*/HAS_1UNTAGGED)) ? 0 : indenting);
4291 p_buf.put_s(start_tag_len , (cbyte*)">\n");
4292 }
4293
4294 if (exer && (p_td.xer_bits & EMBED_VALUES)) {
4295 /* write the first string */
4296 if (embed_values != NULL && embed_values->size_of() > 0) {
4297 sub_len += embed_values->get_at(0)->XER_encode(UNIVERSAL_CHARSTRING_xer_,
4298 p_buf, flavor | EMBED_VALUES, indent+1, 0);
4299 }
4300 }
4301
4302 const Record_Type *ordered = this; // the record affected by USE-ORDER
4303
4304 // Index of the first non-attribute field of the record pointed to by
4305 // ordered, that is, the first field affected by USE-ORDER.
4306 size_t useorder_base = first_nonattr;
4307
4308 int begin = i;
4309 int end = field_cnt;
4310 if (exer && (p_td.xer_bits & USE_ORDER)) {
4311 const int to_send = use_order->size_of();
4312 // the length of the loop is determined by the length of use_order
4313 begin = 0;
4314 end = to_send;
4315
4316 // Count the non-attribute optionals
4317 int n_optionals = 0;
4318 for (int B = optional_count() - 1; B >=+0; B--) {
4319 int oi = get_optional_indexes()[B];
4320 if (oi < first_nonattr) break;
4321 ++n_optionals;
4322 }
4323
4324 int expected_max = field_cnt - first_nonattr;
4325 int expected_min = expected_max - n_optionals;
4326
4327 if ((p_td.xer_bits & USE_NIL) && get_at(field_cnt-1)->ispresent()) {
4328 // The special case when USE_ORDER refers to the fields of a field,
4329 // not this record
4330 const Base_Type *last_optional = get_at(field_cnt-1);
4331 const Base_Type* inner = last_optional->get_opt_value();
4332 // it absolutely, positively has to be (derived from) Record_Type
4333 ordered = static_cast<const Record_Type*>(inner);
4334 useorder_base = ordered->get_xer_num_attr();
4335 begin = useorder_base;
4336 end = ordered->get_count();
4337
4338 expected_min = expected_max = ordered->get_count();
4339 }
4340
4341 if (to_send > expected_max
4342 ||to_send < expected_min) {
4343 ec_1.set_msg("%s': ", fld_name(uo_index));
4344 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_CONSTRAINT,
4345 "Wrong number of USE-ORDER %d, must be %d..%d", to_send, expected_min, expected_max);
4346 begin = end = 0; // don't bother sending anything
4347 }
4348 else { // check no duplicates
4349 int *seen = new int [to_send];
4350 int num_seen = 0;
4351 for (int ei = 0; ei < to_send; ++ei) {
4352 const Base_Type *uoe = use_order->get_at(ei);
4353 const Enum_Type *enm = static_cast<const Enum_Type *>(uoe);
4354 int val = enm->as_int();
4355 for (int x = 0; x < num_seen; ++x) {
4356 if (val == seen[x]) { // complain
4357 ec_1.set_msg("%s': ", fld_name(uo_index));
4358 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_CONSTRAINT,
4359 "Duplicate value for USE-ORDER");
4360 begin = end = 0; // don't bother sending anything
4361 goto trouble;
4362 }
4363 }
4364 seen[num_seen++] = val;
4365 }
4366 trouble:
4367 delete [] seen;
4368 // If the number is right and there are no duplicates, then carry on
4369 }
4370 }
4371
4372 /* Then, all the non-attributes. Structuring the code like this depends on
4373 * all attributes appearing before all non-attributes (excluding
4374 * pseudo-members for USE-ORDER, etc.) */
4375
4376 // early_to_bed can only be true if exer is true (transitive through nil_attribute)
4377 if (!early_to_bed) {
4378 embed_values_enc_struct_t* emb_val = 0;
4379 if (exer && (p_td.xer_bits & EMBED_VALUES) &&
4380 embed_values != NULL && embed_values->size_of() > 1) {
4381 emb_val = new embed_values_enc_struct_t;
4382 emb_val->embval_array = embed_values;
4383 emb_val->embval_index = 1;
4384 emb_val->embval_err = 0;
4385 }
4386
4387 for ( i = begin; i < end; ++i ) {
4388 const Base_Type *uoe = 0; // "useOrder enum"
4389 const Enum_Type *enm = 0; // the enum value selecting the field
4390 if (exer && use_order) {
4391 uoe = use_order->get_at(i - begin);
4392 enm = static_cast<const Enum_Type *>(uoe);
4393 }
4394
4395 // "actual" index, may be perturbed by USE-ORDER
4396 int ai = !(exer && (p_td.xer_bits & USE_ORDER)) ? i :
4397 enm->as_int() + useorder_base;
4398 ec_1.set_msg("%s': ", ordered->fld_name(ai)); // non-attr
4399
4400 const XERdescriptor_t& descr = *ordered->xer_descr(ai);
4401 sub_len += ordered->get_at(ai)->XER_encode(descr, p_buf,
4402 // Pass USE-NIL to the last field (except when USE-ORDER is also in effect,
4403 // because the tag-stripping effect of USE-NIL has been achieved
4404 // by encoding the sub-fields directly).
4405 flavor | ((exer && !use_order && (i == field_cnt-1)) ? (p_td.xer_bits & USE_NIL) : 0),
4406 indent+!omit_tag, emb_val);
4407
4408 // Now the next embed-values string (NOT affected by USE-ORDER!)
4409 if (exer && (p_td.xer_bits & EMBED_VALUES) && 0 != emb_val &&
4410 embed_values != NULL && emb_val->embval_index < embed_values->size_of()) {
4411 embed_values->get_at(emb_val->embval_index)->XER_encode(UNIVERSAL_CHARSTRING_xer_
4412 , p_buf, flavor | EMBED_VALUES, indent+1, 0);
4413 ++emb_val->embval_index;
4414 }
4415 } //for
4416
4417 if (0 != emb_val) {
4418 if (embed_values != NULL && emb_val->embval_index < embed_values->size_of()) {
4419 ec_1.set_msg("%s': ", fld_name(0));
4420 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_CONSTRAINT,
4421 "Too many EMBED-VALUEs specified: %d (expected %d or less)",
4422 embed_values->size_of(), emb_val->embval_index);
4423 }
4424 delete emb_val;
4425 }
4426 } // if (!early_to_bed)
4427 } // if (QNAME)
4428
4429 if (!omit_tag) {
4430 if (sub_len) { // something was written, now an end tag
4431 if (indenting && !(exer && (p_td.xer_bits & (HAS_1UNTAGGED | USE_QNAME)))) {
4432 // The tags of the last optional member involved with USE_NIL
4433 // have been removed. If it was a simple type, the content was probably
4434 // written on a single line without anything resembling a close tag.
4435 // Do not indent our end tag in this case.
4436 switch ((int)(exer && (p_td.xer_bits & USE_NIL))) {
4437 case 1: {
4438 const unsigned char *buf_end = p_buf.get_data() + (p_buf.get_len()-1);
4439 if (buf_end[-1] != '>' || *buf_end != '\n') break;
4440 // If it does not look like an end tag, skip the indenting,
4441 // else fall through.
4442 }
4443 case 0:
4444 do_indent(p_buf, indent);
4445 break;
4446 }
4447 }
4448 p_buf.put_c('<');
4449 p_buf.put_c('/');
4450 if (exer) write_ns_prefix(p_td, p_buf);
4451 p_buf.put_s((size_t)p_td.namelens[exer]-!indenting, (cbyte*)p_td.names[exer]);
4452 }
4453 else { // need to generate an empty element tag
4454 p_buf.increase_length(-start_tag_len); // decrease length
4455 p_buf.put_s((size_t)2+indenting, (cbyte*)"/>\n");
4456 }
4457 }
4458
4459 return (int)p_buf.get_len() - encoded_length;
4460 }
4461
4462 // XERSTUFF Record_Type::encode_field
4463 /** Helper for Record_Type::XER_encode_negtest
4464 *
4465 * Factored out because Record_Type::XER_encode (on which XER_encode_negtest
4466 * is based) calls the XER_encode method of the field in two places:
4467 * one for attributes, the other for elements.
4468 *
4469 * @param i index of the field
4470 * @param err_vals erroneous descriptor for the field
4471 * @param emb_descr deeper erroneous values
4472 * @param p_buf buffer containing the encoded value
4473 * @param sub_flavor flags
4474 * @param indent indentation level
4475 * @return the number of bytes generated
4476 */
4477 int Record_Type::encode_field(int i,
4478 const Erroneous_values_t* err_vals, const Erroneous_descriptor_t* emb_descr,
4479 TTCN_Buffer& p_buf, unsigned int sub_flavor, int indent, embed_values_enc_struct_t* emb_val) const
4480 {
4481 int enc_len = 0;
4482 TTCN_EncDec_ErrorContext ec;
4483 if (err_vals && err_vals->before) {
4484 if (err_vals->before->errval==NULL) TTCN_error(
4485 "internal error: erroneous before value missing");
4486 ec.set_msg("Erroneous value before component %s: ", fld_name(i));
4487 if (err_vals->before->raw) {
4488 enc_len += err_vals->before->errval->encode_raw(p_buf);
4489 } else {
4490 if (err_vals->before->type_descr==NULL) TTCN_error(
4491 "internal error: erroneous before typedescriptor missing");
4492 enc_len += err_vals->before->errval->XER_encode(
4493 *err_vals->before->type_descr->xer, p_buf, sub_flavor, indent, 0);
4494 }
4495 }
4496
4497 if (err_vals && err_vals->value) {
4498 if (err_vals->value->errval) { // replace
4499 ec.set_msg("Erroneous value for component %s: ", fld_name(i));
4500 if (err_vals->value->raw) {
4501 enc_len += err_vals->value->errval->encode_raw(p_buf);
4502 } else {
4503 if (err_vals->value->type_descr==NULL) TTCN_error(
4504 "internal error: erroneous value typedescriptor missing");
4505 enc_len += err_vals->value->errval->XER_encode(
4506 *err_vals->value->type_descr->xer, p_buf, sub_flavor, indent, 0);
4507 }
4508 } // else -> omit
4509 } else {
4510 ec.set_msg("Component %s: ", fld_name(i));
4511 if (emb_descr) {
4512 enc_len += get_at(i)->XER_encode_negtest(emb_descr, *xer_descr(i), p_buf,
4513 sub_flavor, indent, emb_val);
4514 } else {
4515 // the "real" encoder
4516 enc_len += get_at(i)->XER_encode(*xer_descr(i), p_buf,
4517 sub_flavor, indent, emb_val);
4518 }
4519 }
4520
4521 if (err_vals && err_vals->after) {
4522 if (err_vals->after->errval==NULL) TTCN_error(
4523 "internal error: erroneous after value missing");
4524 ec.set_msg("Erroneous value after component %s: ", fld_name(i));
4525 if (err_vals->after->raw) {
4526 enc_len += err_vals->after->errval->encode_raw(p_buf);
4527 } else {
4528 if (err_vals->after->type_descr==NULL) TTCN_error(
4529 "internal error: erroneous after typedescriptor missing");
4530 enc_len += err_vals->after->errval->XER_encode(
4531 *err_vals->after->type_descr->xer, p_buf, sub_flavor, indent, 0);
4532 }
4533 }
4534
4535 return enc_len;
4536 }
4537
4538 // XERSTUFF Record_Type::XER_encode_negtest
4539 int Record_Type::XER_encode_negtest(const Erroneous_descriptor_t* p_err_descr,
4540 const XERdescriptor_t& p_td, TTCN_Buffer& p_buf, unsigned int flavor, int indent,
4541 embed_values_enc_struct_t*) const
4542 {
4543 if (!is_bound()) {
4544 TTCN_EncDec_ErrorContext::error
4545 (TTCN_EncDec::ET_UNBOUND, "Encoding an unbound value.");
4546 }
4547 TTCN_EncDec_ErrorContext ec_0("Component '");
4548 TTCN_EncDec_ErrorContext ec_1;
4549 int encoded_length=(int)p_buf.get_len(); // how much is already in the buffer
4550
4551 int exer = is_exer(flavor);
4552 if (exer && (p_td.xer_bits & EMBED_VALUES)) flavor |= XER_CANONICAL;
4553 const boolean indenting = !is_canonical(flavor);
4554 const int field_cnt = get_count();
4555 const int num_attributes = get_xer_num_attr();
4556 // The USE-ORDER member is first, unless preempted by EMBED-VALUES
4557 const int uo_index = ((p_td.xer_bits & EMBED_VALUES) !=0);
4558 // Index of the first "normal" member (after E-V and U-O)
4559 const int start_at = uo_index + ((p_td.xer_bits & USE_ORDER) != 0);
4560 const int first_nonattr = start_at + num_attributes;
4561 // start_tag_len is keeping track of how much was written at the end of the
4562 // start tag, i.e. the ">\n". This is used later to "back up" over it.
4563 int start_tag_len = 1 + indenting;
4564 // The EMBED-VALUES member, if applicable (always first)
4565 const Record_Of_Type* const embed_values = (p_td.xer_bits & EMBED_VALUES)
4566 ? static_cast<const Record_Of_Type*>(get_at(0)) : 0;
4567 // The USE-ORDER member, if applicable (first unless preempted by embed_vals)
4568 const Record_Of_Type* const use_order = (p_td.xer_bits & USE_ORDER)
4569 ? static_cast<const Record_Of_Type*>(get_at(uo_index)) : 0;
4570
4571 int values_idx = 0;
4572 int edescr_idx = 0;
4573
4574 size_t num_collected = 0; // we use this to compute delay_close
4575 char **collected_ns = NULL;
4576 bool def_ns = false;
4577 if (exer) {
4578 if (indent == 0) { // top-level type
4579 collected_ns = collect_ns(p_td, num_collected, def_ns);
4580 }
4581 else if ((flavor & DEF_NS_SQUASHED) && p_td.my_module && p_td.ns_index != -1) {
4582 const namespace_t * ns = p_td.my_module->get_ns(p_td.ns_index);
4583 // The default namespace has been squashed.
4584 // If we are in the default namespace, restore it.
4585 if (*ns->px == '\0') {
4586 collected_ns = Base_Type::collect_ns(p_td, num_collected, def_ns);
4587 }
4588 }
4589 }
4590
4591 // The type's own tag is omitted if we're doing E-XER,
4592 // and it's not the top-level type (XML must have a root element)
4593 // and it's either UNTAGGED or got USE_NIL.
4594 boolean omit_tag = exer && indent
4595 && ( (p_td.xer_bits & (UNTAGGED|XER_ATTRIBUTE))
4596 || (flavor & (USE_NIL|USE_TYPE_ATTR)));
4597
4598 // If a default namespace is in effect (uri but no prefix) and the type
4599 // is unqualified, the default namespace must be canceled; otherwise
4600 // an XML tag without a ns prefix looks like it belongs to the def.namespace
4601 const boolean empty_ns_hack = exer && !omit_tag && (indent > 0)
4602 && (p_td.xer_bits & FORM_UNQUALIFIED)
4603 && (flavor & DEF_NS_PRESENT);
4604
4605 // delay_close=true if there is stuff before the '>' of the start tag
4606 // (prevents writing the '>' which is built into the name).
4607 // This can only happen for EXER: if there are attributes or namespaces,
4608 // or either USE-NIL or USE-QNAME is set.
4609 boolean delay_close = exer && (num_attributes
4610 || empty_ns_hack // counts as having a namespace
4611 || (num_collected != 0)
4612 || (p_td.xer_bits & (USE_NIL|USE_QNAME))
4613 || (flavor & USE_NIL));
4614
4615 size_t shorter = 0;
4616 if (!omit_tag) { /* write start tag */
4617 if (indenting) do_indent(p_buf, indent);
4618 /* name looks like this: "tagname>\n"
4619 * lose the \n if : not indenting or (single untagged(*) or attributes (*)) AND exer
4620 * lose the > if attributes are present (*) AND exer
4621 */
4622 p_buf.put_c('<');
4623 if (exer) write_ns_prefix(p_td, p_buf);
4624 p_buf.put_s((size_t)p_td.namelens[exer] - delay_close
4625 - (!indenting || delay_close || (exer && (p_td.xer_bits & HAS_1UNTAGGED))),
4626 (cbyte*)p_td.names[exer]);
4627 }
4628 else if (flavor & USE_TYPE_ATTR) {
4629 // reopen the parent's tag
4630 size_t buf_len = p_buf.get_len();
4631 const unsigned char * const buf_data = p_buf.get_data();
4632 if (buf_data[buf_len - 1 - shorter] == '\n') ++shorter;
4633 if (buf_data[buf_len - 1 - shorter] == '>' ) ++shorter;
4634
4635 if (shorter) {
4636 p_buf.increase_length(-shorter);
4637 }
4638 delay_close = TRUE;
4639 }
4640
4641 int sub_len=0, tmp_len;
4642 // mask out extra flags we received, do not send them to the fields
4643 flavor &= XER_MASK;
4644
4645 if (exer && (p_td.xer_bits & USE_QNAME)) {
4646 const Erroneous_values_t * ev =
4647 p_err_descr->next_field_err_values(0, values_idx);
4648 const Erroneous_descriptor_t* ed =
4649 p_err_descr->next_field_emb_descr (0, edescr_idx);
4650 // At first, erroneous info for the first component (uri)
4651
4652 TTCN_EncDec_ErrorContext ec;
4653 const Base_Type * const q_uri = get_at(0);
4654
4655 if (ev && ev->before) {
4656 if (ev->before->errval==NULL) TTCN_error(
4657 "internal error: erroneous before value missing");
4658 ec.set_msg("Erroneous value before component #0: ");
4659 if (ev->before->raw) {
4660 sub_len += ev->before->errval->encode_raw(p_buf);
4661 } else {
4662 if (ev->before->type_descr==NULL) TTCN_error(
4663 "internal error: erroneous before typedescriptor missing");
4664 sub_len += ev->before->errval->XER_encode(
4665 *ev->before->type_descr->xer, p_buf, flavor, indent, 0);
4666 }
4667 }
4668
4669 if (ev && ev->value) {
4670 if (ev->value->errval) { // replace
4671 ec.set_msg("Erroneous value for component #0: ");
4672 if (ev->value->raw) {
4673 sub_len += ev->value->errval->encode_raw(p_buf);
4674 } else {
4675 if (ev->value->type_descr==NULL) TTCN_error(
4676 "internal error: erroneous value typedescriptor missing");
4677 sub_len += ev->value->errval->XER_encode(
4678 *ev->value->type_descr->xer, p_buf, flavor, indent, 0);
4679 }
4680 } // else -> omit
4681 } else {
4682 ec.set_msg("Component #0: ");
4683 if (ed) {
4684 // universal charstring does not have components.
4685 // TTCN code which could have generated embedded erroneous descriptor
4686 // should have failed semantic analysis.
4687 TTCN_error("internal error: embedded descriptor unexpected");
4688 } else {
4689 // the "real" encoder
4690 if (q_uri->is_present()) {
4691 p_buf.put_s(11, (cbyte*)" xmlns:b0='");
4692 sub_len += q_uri->XER_encode(*xer_descr(0), p_buf, flavor | XER_LIST, indent+1, 0);
4693 p_buf.put_c('\'');
4694 }
4695 }
4696 }
4697
4698 if (ev && ev->after) {
4699 if (ev->after->errval==NULL) TTCN_error(
4700 "internal error: erroneous after value missing");
4701 ec.set_msg("Erroneous value after component #0: ");
4702 if (ev->after->raw) {
4703 sub_len += ev->after->errval->encode_raw(p_buf);
4704 } else {
4705 if (ev->after->type_descr==NULL) TTCN_error(
4706 "internal error: erroneous after typedescriptor missing");
4707 sub_len += ev->after->errval->XER_encode(
4708 *ev->after->type_descr->xer, p_buf, flavor, indent, 0);
4709 }
4710 }
4711
4712 if (p_td.xer_bits & XER_ATTRIBUTE) begin_attribute(p_td, p_buf);
4713 else p_buf.put_c('>');
4714
4715 // Now switch to the second field (name)
4716 ev = p_err_descr->next_field_err_values(1, values_idx);
4717 ed = p_err_descr->next_field_emb_descr (1, edescr_idx);
4718
4719 if (ev && ev->before) {
4720 if (ev->before->errval==NULL) TTCN_error(
4721 "internal error: erroneous before value missing");
4722 ec.set_msg("Erroneous value before component #1: ");
4723 if (ev->before->raw) {
4724 sub_len += ev->before->errval->encode_raw(p_buf);
4725 } else {
4726 if (ev->before->type_descr==NULL) TTCN_error(
4727 "internal error: erroneous before typedescriptor missing");
4728 sub_len += ev->before->errval->XER_encode(
4729 *ev->before->type_descr->xer, p_buf, flavor, indent, 0);
4730 }
4731 }
4732
4733 if (ev && ev->value) {
4734 if (ev->value->errval) { // replace
4735 ec.set_msg("Erroneous value for component #1: ");
4736 if (ev->value->raw) {
4737 sub_len += ev->value->errval->encode_raw(p_buf);
4738 } else {
4739 if (ev->value->type_descr==NULL) TTCN_error(
4740 "internal error: erroneous value typedescriptor missing");
4741 sub_len += ev->value->errval->XER_encode(
4742 *ev->value->type_descr->xer, p_buf, flavor, indent, 0);
4743 }
4744 } // else -> omit
4745 } else {
4746 ec.set_msg("Component #1: ");
4747 if (ed) {
4748 // universal charstring does not have components
4749 TTCN_error("internal error: embedded descriptor unexpected");
4750 } else {
4751 // the "real" encoder
4752 if (q_uri->is_present()) {
4753 p_buf.put_s(3, (cbyte*)"b0:");
4754 sub_len += 3;
4755 }
4756
4757 sub_len += get_at(1)->XER_encode(*xer_descr(1), p_buf, flavor | XER_LIST, indent+1, 0);
4758 }
4759 }
4760
4761 if (ev && ev->after) {
4762 if (ev->after->errval==NULL) TTCN_error(
4763 "internal error: erroneous after value missing");
4764 ec.set_msg("Erroneous value after component #1: ");
4765 if (ev->after->raw) {
4766 sub_len += ev->after->errval->encode_raw(p_buf);
4767 } else {
4768 if (ev->after->type_descr==NULL) TTCN_error(
4769 "internal error: erroneous after typedescriptor missing");
4770 sub_len += ev->after->errval->XER_encode(
4771 *ev->after->type_descr->xer, p_buf, flavor, indent, 0);
4772 }
4773 }
4774
4775 if (p_td.xer_bits & XER_ATTRIBUTE) p_buf.put_c('\'');
4776 }
4777 else { // not USE-QNAME
4778 if (!exer && (p_td.xer_bits & EMBED_VALUES)) {
4779 // The EMBED-VALUES member as an ordinary record of string
4780 sub_len += embed_values->XER_encode(*xer_descr(0), p_buf, flavor, indent+1, 0);
4781 }
4782
4783 if (!exer && (p_td.xer_bits & USE_ORDER)) {
4784 // The USE-ORDER member as an ordinary record of enumerated
4785 sub_len += use_order->XER_encode(*xer_descr(uo_index), p_buf, flavor, indent+1, 0);
4786 }
4787
4788 if (exer && (indent==0 || (flavor & DEF_NS_SQUASHED))) // write namespaces for toplevel only
4789 {
4790 for (size_t cur_coll = 0; cur_coll < num_collected; ++cur_coll) {
4791 p_buf.put_s(strlen(collected_ns[cur_coll]), (cbyte*)collected_ns[cur_coll]);
4792 Free(collected_ns[cur_coll]); // job done
4793 }
4794 Free(collected_ns);
4795 }
4796
4797 if (def_ns) {
4798 flavor &= ~DEF_NS_SQUASHED;
4799 flavor |= DEF_NS_PRESENT;
4800 }
4801 else if (empty_ns_hack) {
4802 p_buf.put_s(9, (cbyte*)" xmlns=''");
4803 flavor &= ~DEF_NS_PRESENT;
4804 flavor |= DEF_NS_SQUASHED;
4805 }
4806
4807 // True if the non-attribute fields need to be omitted;
4808 // e.g. if USE_ORDER is in effect and the "nil" attribute was written
4809 // (then the record-of-enum for USE-ORDER will be empty),
4810 // or "omit all after" was hit while processing attributes.
4811 boolean early_to_bed = FALSE;
4812
4813 // First all the attributes (not added to sub_len)
4814 int i;
4815 for (i = start_at; i < first_nonattr; ++i) {
4816 const Erroneous_values_t * ev =
4817 p_err_descr->next_field_err_values(i, values_idx);
4818 const Erroneous_descriptor_t* ed =
4819 p_err_descr->next_field_emb_descr(i, edescr_idx);
4820
4821 if (i < p_err_descr->omit_before) continue;
4822
4823 boolean is_xer_attr_field = xer_descr(i)->xer_bits & XER_ATTRIBUTE;
4824 ec_1.set_msg("%s': ", fld_name(i)); // attr
4825
4826 tmp_len = encode_field(i, ev, ed, p_buf, flavor, indent + !omit_tag, 0);
4827
4828 if (is_xer_attr_field && !exer) sub_len += tmp_len; // do not add if attribute and EXER
4829
4830 // omit_after value -1 becomes "very big"
4831 if ((unsigned int)i >= (unsigned int)p_err_descr->omit_after) {
4832 early_to_bed = TRUE; // no more fields to write
4833 break;
4834 }
4835 }
4836
4837 // True if the "nil" attribute needs to be written.
4838 boolean nil_attribute = FALSE;
4839 // nil attribute unaffected by erroneous
4840 boolean nil_attribute_simple = FALSE;
4841 if (exer && (p_td.xer_bits & USE_NIL)) {
4842 nil_attribute = nil_attribute_simple = !get_at(field_cnt-1)->ispresent();
4843
4844 if (p_err_descr->values_size > 0) // there is an erroneous "value := ..."
4845 {
4846 const Erroneous_values_t *ev_nil =
4847 p_err_descr->get_field_err_values(field_cnt-1);
4848 if (ev_nil && ev_nil->value) // value override for the last field
4849 {
4850 nil_attribute = (ev_nil->value->errval == NULL);
4851 }
4852 }
4853 }
4854
4855 if (nil_attribute) { // req. exer and USE_NIL
4856 const namespace_t *control_ns = p_td.my_module->get_controlns();
4857
4858 if (!nil_attribute_simple) {
4859 // It is likely that the declaration for namespace "xsi"
4860 // was not written. Do it now.
4861 p_buf.put_s(7, (cbyte*)" xmlns:");
4862 p_buf.put_s(strlen(control_ns->px), (cbyte*)control_ns->px);
4863 p_buf.put_s(2, (cbyte*)"='");
4864 p_buf.put_s(strlen(control_ns->ns), (cbyte*)control_ns->ns);
4865 p_buf.put_c('\'');
4866 }
4867
4868 p_buf.put_c(' ');
4869 p_buf.put_s(strlen(control_ns->px), (cbyte*)control_ns->px);
4870 p_buf.put_c(':');
4871 p_buf.put_s(10, (cbyte*)"nil='true'");
4872 if ((p_td.xer_bits & USE_ORDER)) early_to_bed = TRUE;
4873 // The whole content was omitted; nothing to do (and if we tried
4874 // to do it, we'd get an error for over-indexing a 0-length record-of).
4875 }
4876
4877 if (delay_close && (!omit_tag || shorter)) {
4878 // Close the start tag left open. If indenting, also write a newline
4879 // unless USE-NIL in effect or there is a single untagged component.
4880 start_tag_len = 1 +
4881 ((p_td.xer_bits & (/*USE_NIL|*/HAS_1UNTAGGED)) ? 0 : indenting);
4882 p_buf.put_s(start_tag_len , (cbyte*)">\n");
4883 }
4884
4885 // Erroneous values for the embed_values member (if any).
4886 // Collected once but referenced multiple times.
4887 const Erroneous_descriptor_t* ed0 = NULL;
4888 int embed_values_val_idx = 0;
4889 int embed_values_descr_idx = 0;
4890
4891 if (exer && (p_td.xer_bits & EMBED_VALUES)) {
4892 ed0 = p_err_descr->next_field_emb_descr(0, edescr_idx);
4893
4894 // write the first string
4895 if (embed_values->size_of() > 0) {
4896 const Erroneous_values_t * ev0_0 = NULL;
4897 const Erroneous_descriptor_t* ed0_0 = NULL;
4898 if (ed0) {
4899 ev0_0 = ed0->next_field_err_values(0, embed_values_val_idx);
4900 ed0_0 = ed0->next_field_emb_descr (0, embed_values_descr_idx);
4901 }
4902 sub_len += embed_values->encode_element(0, UNIVERSAL_CHARSTRING_xer_,
4903 ev0_0, ed0_0, p_buf, flavor | EMBED_VALUES, indent+!omit_tag, 0);
4904 }
4905 }
4906
4907 const Record_Type *ordered = this; // the record affected by USE-ORDER
4908 // By default it's this record, unless USE_NIL is _also_ in effect,
4909 // in which case it's the last member of this.
4910
4911 // Index of the first non-attribute field of the record pointed to by
4912 // ordered, that is, the first field affected by USE-ORDER.
4913 size_t useorder_base = first_nonattr;
4914
4915 int begin = i;
4916 int end = field_cnt; // "one past", do not touch
4917 // by default, continue from the current field until the end, indexing this
4918
4919 if (exer && (p_td.xer_bits & USE_ORDER)) {
4920 // the length of the loop is determined by the length of use_order
4921 const int to_send = use_order->size_of();
4922
4923 // i will index all elements of the use_order member
4924 begin = 0;
4925 end = to_send;
4926
4927 // Count the non-attribute optionals
4928 int n_optionals = 0;
4929 for (int B = optional_count() - 1; B >=+0; B--) {
4930 int oi = get_optional_indexes()[B];
4931 if (oi < first_nonattr) break;
4932 ++n_optionals;
4933 }
4934
4935 int expected_min = field_cnt - first_nonattr - n_optionals;
4936 int expected_max = field_cnt - first_nonattr;
4937
4938 if ((p_td.xer_bits & USE_NIL) && get_at(field_cnt-1)->ispresent()) {
4939 // The special case when USE_ORDER refers to the fields of a field,
4940 // not this record
4941 const Base_Type *last_optional = get_at(field_cnt-1);
4942 const Base_Type* inner = last_optional->get_opt_value();
4943 // it absolutely, positively has to be (derived from) Record_Type
4944 ordered = static_cast<const Record_Type*>(inner);
4945 useorder_base = ordered->get_xer_num_attr();
4946 begin = useorder_base;
4947 end = ordered->get_count();
4948
4949 expected_min = expected_max = ordered->get_count();
4950 }
4951
4952 if (to_send > expected_max
4953 ||to_send < expected_min) {
4954 ec_1.set_msg("%s': ", fld_name(uo_index));
4955 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_CONSTRAINT,
4956 "Wrong number of USE-ORDER %d, must be %d..%d", to_send, expected_min, expected_max);
4957 early_to_bed = TRUE; // don't bother sending anything
4958 }
4959 else { // check no duplicates
4960 int *seen = new int [to_send];
4961 int num_seen = 0;
4962 for (int ei = 0; ei < to_send; ++ei) {
4963 const Base_Type *uoe = use_order->get_at(ei);
4964 const Enum_Type *enm = static_cast<const Enum_Type *>(uoe);
4965 int val = enm->as_int();
4966 for (int x = 0; x < num_seen; ++x) {
4967 if (val == seen[x]) { // complain
4968 ec_1.set_msg("%s': ", fld_name(uo_index));
4969 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_CONSTRAINT,
4970 "Duplicate value for USE-ORDER");
4971 early_to_bed = TRUE; // don't bother sending anything
4972 goto trouble;
4973 }
4974 }
4975 seen[num_seen++] = val;
4976 }
4977 trouble:
4978 delete [] seen;
4979 // If the number is right and there are no duplicates, then carry on
4980 }
4981 } // endif(USE_ORDER)
4982
4983 // Then, all the non-attributes. Structuring the code like this depends on
4984 // all attributes appearing before all non-attributes (excluding
4985 // pseudo-members for USE-ORDER, etc.)
4986
4987 // This loop handles both the normal case (no USE_ORDER) when i indexes
4988 // fields of this record; and the USE_ORDER case (with or without USE-NIL).
4989 //
4990 // early_to_bed can only be true if exer is true (transitive through nil_attribute)
4991 if (!early_to_bed) {
4992 embed_values_enc_struct_t* emb_val = 0;
4993 if (exer && (p_td.xer_bits & EMBED_VALUES) && embed_values->size_of() > 1) {
4994 emb_val = new embed_values_enc_struct_t;
4995 emb_val->embval_array = embed_values;
4996 emb_val->embval_index = 1;
4997 emb_val->embval_err = ed0;
4998 emb_val->embval_err_val_idx = embed_values_val_idx;
4999 emb_val->embval_err_descr_idx = embed_values_descr_idx;
5000 }
5001
5002 for ( i = begin; i < end; ++i ) {
5003
5004 const Base_Type *uoe = 0; // "useOrder enum"
5005 const Enum_Type *enm = 0; // the enum value selecting the field
5006
5007 // "actual" index, may be perturbed by USE-ORDER.
5008 // We use this value to index the appropriate record.
5009 int ai = i;
5010
5011 const Erroneous_values_t * ev = NULL;
5012 const Erroneous_descriptor_t* ed = NULL;
5013 if (exer && use_order) {
5014 // If USE-ORDER is in effect, it introduces a level of indirection
5015 // into the indexing of fields: "i" is used to select an element
5016 // of the use_order member (an enum), whose value is used to select
5017 // the field being encoded.
5018 uoe = use_order->get_at(i - begin);
5019 enm = static_cast<const Enum_Type *>(uoe);
5020 ai = enm->as_int() + useorder_base;
5021
5022 // Because it is not guaranteed that ai will increase monotonically,
5023 // we can't use next_field_...().
5024 ev = p_err_descr->get_field_err_values(ai);
5025 ed = p_err_descr->get_field_emb_descr (ai);
5026 }
5027 else { // not USE-ORDER, sequential access
5028 ev = p_err_descr->next_field_err_values(ai, values_idx);
5029 ed = p_err_descr->next_field_emb_descr (ai, edescr_idx);
5030 }
5031 ec_1.set_msg("%s': ", ordered->fld_name(ai)); // non-attr
5032
5033 if (ai < p_err_descr->omit_before) continue;
5034
5035 // omit_after value -1 becomes "very big".
5036 if ((unsigned int)ai > (unsigned int)p_err_descr->omit_after) continue;
5037 // We can't skip all fields with break, because the next ai may be lower
5038 // than omit_after.
5039
5040 sub_len += ordered->encode_field(ai, ev, ed, p_buf,
5041 // Pass USE-NIL to the last field (except when USE-ORDER is also in effect,
5042 // because the tag-stripping effect of USE-NIL has been achieved
5043 // by encoding the sub-fields directly).
5044 flavor | ((exer && !use_order && (i == field_cnt-1)) ? (p_td.xer_bits & USE_NIL) : 0),
5045 indent + !omit_tag, emb_val);
5046
5047 // Now the next embed-values string (NOT affected by USE-ORDER!)
5048 if (exer && (p_td.xer_bits & EMBED_VALUES) && 0 != emb_val &&
5049 emb_val->embval_index < embed_values->size_of()) {
5050 const Erroneous_values_t * ev0_i = NULL;
5051 const Erroneous_descriptor_t* ed0_i = NULL;
5052 if (ed0) {
5053 ev0_i = ed0->next_field_err_values(emb_val->embval_index, emb_val->embval_err_val_idx);
5054 ed0_i = ed0->next_field_emb_descr (emb_val->embval_index, emb_val->embval_err_descr_idx);
5055 }
5056 embed_values->encode_element(emb_val->embval_index, UNIVERSAL_CHARSTRING_xer_,
5057 ev0_i, ed0_i, p_buf, flavor | EMBED_VALUES, indent + !omit_tag, 0);
5058 ++emb_val->embval_index;
5059 }
5060 } //for
5061 if (0 != emb_val) {
5062 if (emb_val->embval_index < embed_values->size_of()) {
5063 ec_1.set_msg("%s': ", fld_name(0));
5064 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_CONSTRAINT,
5065 "Too many EMBED-VALUEs specified: %d (expected %d or less)",
5066 embed_values->size_of(), emb_val->embval_index);
5067 }
5068 delete emb_val;
5069 }
5070 } // if (!early_to_bed)
5071 } // if (QNAME)
5072
5073
5074 if (!omit_tag) {
5075 if (sub_len) { // something was written, now an end tag
5076 if (indenting && !(exer && (p_td.xer_bits & (HAS_1UNTAGGED | USE_QNAME))))
5077 // The tags of the last optional member involved with USE_NIL
5078 // have been removed. If it was a simple type, the content was probably
5079 // written on a single line without anything resembling a close tag.
5080 // Do not indent our end tag in this case.
5081 switch ((int)(exer && (p_td.xer_bits & USE_NIL))) {
5082 case 1: {
5083 const unsigned char *buf_end = p_buf.get_data() + (p_buf.get_len()-1);
5084 if (buf_end[-1] != '>' || *buf_end != '\n') break;
5085 // If it does not look like an end tag, skip the indenting,
5086 // else fall through.
5087 }
5088 case 0:
5089 do_indent(p_buf, indent);
5090 break;
5091 }
5092 p_buf.put_c('<');
5093 p_buf.put_c('/');
5094 if (exer) write_ns_prefix(p_td, p_buf);
5095 p_buf.put_s((size_t)p_td.namelens[exer]-!indenting, (cbyte*)p_td.names[exer]);
5096 }
5097 else { // need to generate an empty element tag
5098 p_buf.increase_length(-start_tag_len); // decrease length
5099 p_buf.put_s((size_t)2+indenting, (cbyte*)"/>\n");
5100 }
5101 }
5102
5103 return (int)p_buf.get_len() - encoded_length;
5104 }
5105
5106 int Record_Type::XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& reader,
5107 unsigned int flavor, unsigned int flavor2, embed_values_dec_struct_t*)
5108 {
5109 int exer = is_exer(flavor);
5110 int success, type;
5111 int depth=-1; // depth of the start tag
5112 int xerbits = p_td.xer_bits;
5113 if (flavor & XER_TOPLEVEL) xerbits &= ~UNTAGGED;
5114 const boolean own_tag = !(exer
5115 && ( (xerbits & (ANY_ELEMENT | UNTAGGED | XER_ATTRIBUTE))
5116 || (flavor & (USE_NIL | USE_TYPE_ATTR))));
5117 boolean tag_closed = (flavor & PARENT_CLOSED) != 0;
5118 // If the parent has USE-TYPE, our ATTRIBUTE members can be found
5119 // in the parent's tag (the reader is sitting on it).
5120 const boolean parent_tag = exer && ((flavor & USE_TYPE_ATTR) || (flavor2 & USE_NIL_PARENT_TAG));
5121
5122 // Filter out flags passed by our parent. These are not for the fields.
5123 flavor &= XER_MASK; // also removes XER_TOPLEVEL
5124 flavor2 = XER_NONE; // Remove only bit: USE_NIL_PARENT_TAG (for now)
5125
5126 const int field_cnt = get_count();
5127 const int num_attributes = get_xer_num_attr();
5128
5129 // The index of potential "order" field, regardless of whether USE_ORDER
5130 // is in use or not.
5131 const int uo_index = ((p_td.xer_bits & EMBED_VALUES) !=0);
5132
5133 // The first "non-special" field (skipping the USE-ORDER and EMBED-VALUES
5134 // fields); normal processing start at this field.
5135 const int start_at = uo_index + ((p_td.xer_bits & USE_ORDER) != 0);
5136 const int first_nonattr = start_at + num_attributes;
5137
5138 // The index of the ANY-ATTRIBUTES member, if any
5139 int aa_index = -1;
5140 for (int k = 0; k < first_nonattr; ++k) {
5141 if (xer_descr(k)->xer_bits & ANY_ATTRIBUTES) {
5142 aa_index = k;
5143 if (!get_at(aa_index)->is_optional()) {
5144 static_cast<Record_Of_Type*>(get_at(aa_index))->set_size(0);
5145 }
5146 break; // there can be only one, 18.2.2
5147 }
5148 }
5149
5150 if (own_tag) for (success=reader.Ok(); success==1; success=reader.Read()) {
5151 type = reader.NodeType();
5152 if (type==XML_READER_TYPE_ELEMENT) {
5153 verify_name(reader, p_td, exer);
5154 depth = reader.Depth();
5155 tag_closed = reader.IsEmptyElement();
5156 break;
5157 }
5158 }//for
5159
5160 int i = 0;
5161
5162 if (exer && (p_td.xer_bits & USE_QNAME)) { // QName trumps everything !
5163 // If element, it looks like this:
5164 // <name xmlns:b0="http://www.furniture.com">b0:table</name>
5165 // If attribute, it looks like this:
5166 // name='b0:table'
5167
5168 if (p_td.xer_bits & XER_ATTRIBUTE) success = 1; // do nothing
5169 else for (success = reader.Read(); success == 1; success = reader.Read()) {
5170 type = reader.NodeType();
5171 if (type == XML_READER_TYPE_TEXT) break;
5172 }
5173
5174 if (success == 1) {
5175 xmlChar *val = reader.NewValue();
5176 xmlChar *npfx = (xmlChar*)strchr((char*)val, ':');
5177 xmlChar *pfx;
5178 if (npfx != NULL) {
5179 *npfx++ = '\0'; // cut the string into two
5180 pfx = val;
5181 }
5182 else {
5183 npfx = val;
5184 pfx = NULL;
5185 }
5186
5187 xmlChar *nsu = reader.LookupNamespace(pfx);
5188
5189 OPTIONAL<UNIVERSAL_CHARSTRING> *q_prefix2 =
5190 static_cast<OPTIONAL<UNIVERSAL_CHARSTRING>*>(get_at(0));
5191 if (nsu) *q_prefix2 = (const char*)nsu;
5192 else q_prefix2->set_to_omit(); // public in RT2 only
5193
5194 UNIVERSAL_CHARSTRING *q_name2 = static_cast<UNIVERSAL_CHARSTRING*>(get_at(1));
5195 *q_name2 = (const char*)npfx;
5196
5197 xmlFree(nsu);
5198 xmlFree(val);
5199 }
5200 }
5201 else { // not use-qname
5202 TTCN_EncDec_ErrorContext ec_0("Component '");
5203 TTCN_EncDec_ErrorContext ec_1;
5204 boolean usenil_attribute = FALSE; // true if found and said yes
5205 // If nillable and the nillable field is a record type, that has attributes
5206 // then it will become true, and skips the processing of the fields after
5207 boolean already_processed = FALSE;
5208 if (!exer) {
5209 if (!reader.IsEmptyElement()) reader.Read();
5210 // First, the (would-be) attributes (unaffected by USE-ORDER)
5211 for (i = 0; i < first_nonattr; i++) {
5212 ec_1.set_msg("%s': ", fld_name(i));
5213 get_at(i)->XER_decode(*xer_descr(i), reader, flavor, flavor2, 0);
5214 } // next field
5215 }
5216 else if (own_tag || parent_tag) { // EXER and not UNTAGGED: do attributes
5217 // Prepare for lack of attributes.
5218 // Fields with defaultForEmpty get the D-F-E value, optional get omit.
5219 for (i = start_at; i < first_nonattr; i++) {
5220 Base_Type &fld = *get_at(i);
5221 const XERdescriptor_t& xd = *xer_descr(i);
5222 if (xd.dfeValue) {
5223 if (fld.is_optional()) {
5224 fld.set_to_present();
5225 fld.get_opt_value()->set_value(xd.dfeValue);
5226 }
5227 else fld.set_value(xd.dfeValue);
5228 }
5229 else if (fld.is_optional()) fld.set_to_omit();
5230 }
5231
5232 int num_aa = 0; // index into the ANY-ATTRIBUTE member
5233
5234 const namespace_t *control_ns = 0;
5235 if (parent_tag || (p_td.xer_bits & USE_NIL)) {
5236 // xsi:type or xsi:nil
5237 control_ns = p_td.my_module->get_controlns();
5238 }
5239
5240 /* * * * * * * * * Attributes * * * * * * * * * * * * * */
5241 if(parent_tag && reader.NodeType() == XML_READER_TYPE_ATTRIBUTE) {
5242 success = reader.Ok();
5243 } else {
5244 success = reader.MoveToFirstAttribute();
5245 }
5246 for (;
5247 success == 1 && reader.NodeType() == XML_READER_TYPE_ATTRIBUTE;
5248 success = reader.AdvanceAttribute())
5249 {
5250 if (reader.IsNamespaceDecl()) {
5251 continue; // namespace declarations are handled for us by libxml2
5252 }
5253
5254 const char *attr_name = (const char*)reader.LocalName();
5255 const char *ns_uri = (const char*)reader.NamespaceUri();
5256 int field_index = get_index_byname(attr_name, ns_uri);
5257 if (field_index != -1) {
5258 // There is a field. Let it decode the attribute.
5259 ec_1.set_msg("%s': ", fld_name(field_index));
5260 get_at(field_index)->XER_decode(*xer_descr(field_index), reader, flavor, flavor2, 0);
5261 continue;
5262 }
5263
5264 // Attribute not found. It could be the "nil" attribute
5265 if (p_td.xer_bits & USE_NIL) {
5266 const char *prefix = (const char*)reader.Prefix();
5267 // prefix may be NULL, control_ns->px is never NULL or empty
5268 if (prefix && !strcmp(prefix, control_ns->px)
5269 && !strcmp((const char*)reader.LocalName(), "nil"))
5270 { // It is the "nil" attribute
5271 const char *value = (const char*)reader.Value();
5272 if (value) {
5273 if (!strcmp(value, "1") || !strcmp(value, "true")) {
5274 // The field affected by USE-NIL is always the last one
5275 get_at(field_cnt-1)->set_to_omit();
5276 usenil_attribute = TRUE;
5277 } // true
5278 } // if value
5279
5280 continue;
5281 } // it is the "nil" attribute
5282 // else, let the nillable field decode the next attributes, it is possible
5283 // that it belongs to him
5284 get_at(field_cnt-1)->XER_decode(*xer_descr(field_cnt-1), reader, flavor | USE_NIL, flavor2 | USE_NIL_PARENT_TAG, 0);
5285 already_processed = TRUE;
5286 continue;
5287 } // type has USE-NIL
5288
5289 if (parent_tag) {
5290 const char *prefix = (const char*)reader.Prefix();
5291 // prefix may be NULL, control_ns->px is never NULL or empty
5292 if (prefix && !strcmp(prefix, control_ns->px)
5293 && !strcmp((const char*)reader.LocalName(), "type")) {
5294 continue; // xsi:type has been processed by the parent
5295 }
5296 }
5297
5298 if (aa_index >= 0) {
5299 ec_1.set_msg("%s': ", fld_name(aa_index));
5300 TTCN_EncDec_ErrorContext ec_2("Attribute %d: ", num_aa);
5301 // We have a component with ANY-ATTRIBUTE. It must be a record of
5302 // UNIVERSAL_CHARSTRING. Add the attribute to it.
5303 Record_Of_Type *aa = 0;
5304 if (get_at(aa_index)->is_optional()) {
5305 if (num_aa == 0) {
5306 get_at(aa_index)->set_to_present();
5307 }
5308 aa = static_cast<Record_Of_Type*>(get_at(aa_index)->get_opt_value());
5309 }
5310 else {
5311 aa = static_cast<Record_Of_Type*>(get_at(aa_index));
5312 }
5313 UNIVERSAL_CHARSTRING *new_elem = static_cast<UNIVERSAL_CHARSTRING *>
5314 (aa->get_at(num_aa++));
5315
5316 // Construct the AnyAttributeFormat (X.693amd1, 18.2.6)
5317 TTCN_Buffer aabuf;
5318 const xmlChar *name = reader.LocalName();
5319 const xmlChar *val = reader.Value();
5320 const xmlChar *uri = reader.NamespaceUri();
5321
5322 if (xer_descr(aa_index)->xer_bits & (ANY_FROM | ANY_EXCEPT)) {
5323 check_namespace_restrictions(*xer_descr(aa_index), (const char*)uri);
5324 }
5325 // We don't care about reader.Prefix()
5326 // Using strlen to count UTF8 bytes, not characters
5327 aabuf.put_s(uri ? strlen((const char*)uri) : 0, uri);
5328 if (uri && *uri) aabuf.put_c(' ');
5329 aabuf.put_s(name ? strlen((const char*)name) : 0, name);
5330 aabuf.put_c('=');
5331 aabuf.put_c('"');
5332 aabuf.put_s(val ? strlen((const char*)val) : 0, val);
5333 aabuf.put_c('"');
5334 new_elem->decode_utf8(aabuf.get_len(), aabuf.get_data());
5335
5336 continue;
5337 }
5338
5339 // Lastly check for the xsi:schemaLocation attribute, this does not
5340 // affect TTCN-3, but it shouldn't cause a DTE
5341 if (reader.LocalName() && !strcmp((const char*)reader.LocalName(), "schemaLocation")) {
5342 if (!control_ns) {
5343 control_ns = p_td.my_module->get_controlns();
5344 }
5345 if (reader.Prefix() && !strcmp((const char*)reader.Prefix(), control_ns->px)) {
5346 continue;
5347 }
5348 }
5349
5350 // Nobody wanted the attribute. That is an error.
5351 ec_0.set_msg(" "); ec_1.set_msg(" ");
5352 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG,
5353 "Unexpected attribute '%s', ns '%s'", attr_name,
5354 ns_uri ? ns_uri : "");
5355 } // next attribute
5356
5357 // Now check that all mandatory attributes have been set
5358 for (i = start_at; i < first_nonattr; ++i) {
5359 Base_Type * fld = get_at(i);
5360 if (fld->is_optional()) continue; // field is allowed to be unset
5361 if (!fld->is_bound()) {
5362 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG,
5363 "Missing attribute '%s'", this->fld_name(i));
5364 }
5365 }
5366
5367 i = first_nonattr; // finished with attributes
5368 // AdvanceAttribute did MoveToElement. Move into the content (if any).
5369 if (!reader.IsEmptyElement()) reader.Read();
5370 } // end if (own_tag)
5371
5372 /* * * * * * * * Non-attributes (elements) * * * * * * * * * * * */
5373 embed_values_dec_struct_t* emb_val = 0;
5374 bool emb_val_optional = false;
5375 if (exer && (p_td.xer_bits & EMBED_VALUES)) {
5376 emb_val = new embed_values_dec_struct_t;
5377 emb_val->embval_array = dynamic_cast<Record_Of_Type*>(get_at(0));
5378 if (NULL == emb_val->embval_array) {
5379 OPTIONAL<PreGenRecordOf::PREGEN__RECORD__OF__UNIVERSAL__CHARSTRING>* embed_value = static_cast<OPTIONAL<PreGenRecordOf::PREGEN__RECORD__OF__UNIVERSAL__CHARSTRING>*>(get_at(0));
5380 embed_value->set_to_present();
5381 emb_val->embval_array = static_cast<Record_Of_Type*>((*embed_value).get_opt_value());
5382 emb_val_optional = true;
5383 }
5384 emb_val->embval_array->set_size(0);
5385 emb_val->embval_index = 0;
5386 }
5387
5388 if (exer && (p_td.xer_bits & USE_ORDER)) {
5389 // Set all optional fields to omit because their respective XER_decode
5390 // will not be run (and will stay unbound) if the value is missing.
5391 int n_optionals = 0;
5392 for (int B = optional_count() - 1; B >=+0; B--) {
5393 int oi = get_optional_indexes()[B];
5394 if (oi < first_nonattr) break;
5395 get_at(oi)->set_to_omit();
5396 ++n_optionals;
5397 }
5398
5399 Record_Of_Type *use_order = static_cast<Record_Of_Type*>(get_at(uo_index));
5400 // Initialize the use_order field to empty. Let it grow on demand.
5401 // (setting it to the minimum acceptable size may leave unbound elements
5402 // if the XML was incomplete).
5403 use_order->set_size(0);
5404
5405 // Nothing to order if there are no child elements
5406 if (!tag_closed) {
5407 Record_Type *jumbled = this; // the record affected by USE_ORDER
5408 int begin = first_nonattr;
5409 int end = field_cnt; // "one past"
5410 if (p_td.xer_bits & USE_NIL) {
5411 Base_Type *last_optional = get_at(field_cnt-1);
5412 if (!usenil_attribute) { // exer known true
5413 last_optional->set_to_present();
5414 jumbled = static_cast<Record_Type*>(last_optional->get_opt_value());
5415 // We will operate on the members of last_optional,
5416 // effectively bypassing last_optional->XER_decode() itself.
5417 begin = 0;
5418 end = jumbled->get_count();
5419 ec_1.set_msg("%s': ", fld_name(field_cnt-1));
5420 }
5421 }
5422 if (num_attributes > 0
5423 && first_nonattr != field_cnt
5424 && i == first_nonattr - 1) { // exer known true
5425 // If there were attributes and their processing just finished,
5426 // the reader is positioned on the start tag of the record.
5427 // Move ahead, unless there are no non-attribute fields.
5428 reader.Read();
5429 }
5430 // Then, the non-attributes
5431
5432 // The index runs over the members affected by USE-ORDER.
5433 // This is [first_nonattr,field_cnt) unless USE-NIL is involved,
5434 // in which case it's [0,optional_sequence::field_cnt)
5435 int *seen = new int[end-begin];
5436 int num_seen = 0;
5437 int last_any_elem = begin - 1;
5438 // The index of the latest embedded value can change outside of this function
5439 // (if the field is an untagged record of), in this case the next value should
5440 // be ignored, as it's already been handled by the record of
5441 int last_embval_index = 0;
5442 bool early_exit = false;
5443 for (i = begin; i < end; i++) {
5444 for (success = reader.Ok(); success == 1; success = reader.Read()) {
5445 type = reader.NodeType();
5446 if (0 != emb_val && reader.NodeType()==XML_READER_TYPE_TEXT) {
5447 UNIVERSAL_CHARSTRING emb_ustr((const char*)reader.Value());
5448 emb_val->embval_array->get_at(emb_val->embval_index)->set_value(&emb_ustr);
5449 }
5450 // The non-attribute components must not be UNTAGGED
5451 if (type == XML_READER_TYPE_ELEMENT) break;
5452 if (type == XML_READER_TYPE_END_ELEMENT) {
5453 early_exit = true;
5454 break;
5455 }
5456 }
5457 if (0 != emb_val) {
5458 if (last_embval_index == emb_val->embval_index) {
5459 ++emb_val->embval_index;
5460 }
5461 last_embval_index = emb_val->embval_index;
5462 }
5463 if (success != 1 || early_exit) break;
5464 const char *name = (const char *)reader.LocalName();
5465 bool field_name_found = false;
5466 // Find out which member it is.
5467 // FIXME some hashing should be implemented
5468 for (int k = begin; k < end; k++) {
5469 if (!(jumbled->xer_descr(k)->xer_bits & ANY_ELEMENT) &&
5470 check_name(name, *jumbled->xer_descr(k), 1)) {
5471 ec_1.set_msg("%s': ", jumbled->fld_name(k));
5472
5473 // Check for the same field being decoded twice.
5474 // We can't use the field's is_bound()/is_present(),
5475 // because the field may be bound on input, e.g. for
5476 // prototype(fast) or prototype(backtrack).
5477 int in_dex = k - begin;
5478 for (int o = 0; o < num_seen ;++o) {
5479 if (in_dex == seen[o]) TTCN_EncDec_ErrorContext::error(
5480 TTCN_EncDec::ET_INVAL_MSG, "Duplicate element");
5481 }
5482 seen[num_seen++] = in_dex;
5483 // Set the next use-order member.
5484 // Non-const get_at creates the object in the record-of.
5485 static_cast<Enum_Type*>(use_order->get_at(i - begin))
5486 ->from_int(in_dex);
5487 Base_Type *b = jumbled->get_at(k);
5488 b->XER_decode(*jumbled->xer_descr(k), reader, flavor, flavor2, emb_val);
5489 field_name_found = true;
5490 break;
5491 }
5492 }
5493 if (!field_name_found) {
5494 // Check the anyElement fields
5495 for (int k = last_any_elem + 1; k < end; k++) {
5496 if (jumbled->xer_descr(k)->xer_bits & ANY_ELEMENT) {
5497 ec_1.set_msg("%s': ", jumbled->fld_name(k));
5498
5499 // Check for the same field being decoded twice.
5500 // We can't use the field's is_bound()/is_present(),
5501 // because the field may be bound on input, e.g. for
5502 // prototype(fast) or prototype(backtrack).
5503 int in_dex = k - begin;
5504 for (int o = 0; o < num_seen ;++o) {
5505 if (in_dex == seen[o]) TTCN_EncDec_ErrorContext::error(
5506 TTCN_EncDec::ET_INVAL_MSG, "Duplicate element");
5507 }
5508 seen[num_seen++] = in_dex;
5509 // Set the next use-order member.
5510 // Non-const get_at creates the object in the record-of.
5511 static_cast<Enum_Type*>(use_order->get_at(i - begin))
5512 ->from_int(in_dex);
5513 Base_Type *b = jumbled->get_at(k);
5514 b->XER_decode(*jumbled->xer_descr(k), reader, flavor, flavor2, emb_val);
5515 last_any_elem = k;
5516 field_name_found = true;
5517 break;
5518 }
5519 }
5520 }
5521 if (!field_name_found) {
5522 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG,
5523 "Bad XML tag '%s' instead of a valid field", name);
5524 break;
5525 }
5526 } // next field
5527 if (0 != emb_val) {
5528 if (reader.NodeType()==XML_READER_TYPE_TEXT) {
5529 UNIVERSAL_CHARSTRING emb_ustr((const char*)reader.Value());
5530 emb_val->embval_array->get_at(emb_val->embval_index)->set_value(&emb_ustr);
5531 }
5532 if (last_embval_index == emb_val->embval_index) {
5533 ++emb_val->embval_index;
5534 }
5535 }
5536 delete [] seen;
5537 ec_1.set_msg(" "); // no active component
5538 ec_0.set_msg(" ");
5539
5540 // Check that we collected the required number of children
5541 int num_collected = use_order->size_of();
5542 if (p_td.xer_bits & USE_NIL) {
5543 int expected = usenil_attribute ? 0 : jumbled->get_count();
5544 if (num_collected != expected) {
5545 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INCOMPL_MSG,
5546 "Incorrect number of fields %d, expected %d",
5547 num_collected, expected);
5548 }
5549 }
5550 else {
5551 if (num_collected < field_cnt - first_nonattr - n_optionals
5552 ||num_collected > field_cnt - first_nonattr) {
5553 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INCOMPL_MSG,
5554 "Wrong number of fields! size = %d, expected %d..%d",
5555 use_order->size_of(), field_cnt - first_nonattr - n_optionals,
5556 field_cnt - first_nonattr);
5557 }
5558 }
5559 } // not empty element
5560 }
5561 else { // not USE-ORDER, simpler code
5562 if (usenil_attribute) {
5563 reader.MoveToElement(); // value absent, nothing more to do
5564 } else {
5565 // The index of the latest embedded value can change outside of this function
5566 // (if the field is a untagged record of), in this case the next value should
5567 // be ignored, as it's already been handled by the record of
5568 // Omitted fields can also reset this value
5569 int last_embval_index = 0;
5570 for (; i<field_cnt; i++) {
5571 if (0 != emb_val) {
5572 if (reader.NodeType()==XML_READER_TYPE_TEXT) {
5573 UNIVERSAL_CHARSTRING emb_ustr((const char*)reader.Value());
5574 emb_val->embval_array->get_at(emb_val->embval_index)->set_value(&emb_ustr);
5575 }
5576 if (last_embval_index == emb_val->embval_index) {
5577 ++emb_val->embval_index;
5578 }
5579 last_embval_index = emb_val->embval_index;
5580 }
5581 ec_1.set_msg("%s': ", fld_name(i));
5582 if (exer && i==field_cnt-1 && p_td.dfeValue && reader.IsEmptyElement()) {
5583 get_at(i)->set_value(p_td.dfeValue);
5584 }
5585 else {
5586 // In case the field is an optional anyElement -> check if it should be omitted
5587 bool optional_any_elem_check = true;
5588 if (get_at(i)->is_optional() && (xer_descr(i)->xer_bits & ANY_ELEMENT)) {
5589 // The "anyElement" coding instruction can only be applied to a universal charstring field
5590 OPTIONAL<UNIVERSAL_CHARSTRING>* opt_field = dynamic_cast<OPTIONAL<UNIVERSAL_CHARSTRING>*>(get_at(i));
5591 if (opt_field) {
5592 const char* next_field_name = NULL;
5593 if (i < field_cnt - 1) {
5594 next_field_name = fld_name(i + 1);
5595 }
5596 optional_any_elem_check = opt_field->XER_check_any_elem(reader, next_field_name, tag_closed);
5597 }
5598 }
5599 if (optional_any_elem_check && !already_processed) {
5600 int new_flavor = flavor ;
5601 if (i == field_cnt-1) new_flavor |= (p_td.xer_bits & USE_NIL);
5602 if (tag_closed) new_flavor |= PARENT_CLOSED;
5603
5604 get_at(i)->XER_decode(*xer_descr(i), reader, new_flavor, flavor2, emb_val);
5605 }
5606 }
5607 if (!get_at(i)->is_present()) {
5608 // there was no new element, the last embedded value is for the next field
5609 // (or the end of the record if this is the last field)
5610 last_embval_index = -1;
5611 }
5612 } // next field
5613 if (0 != emb_val) {
5614 if (reader.NodeType()==XML_READER_TYPE_TEXT) {
5615 UNIVERSAL_CHARSTRING emb_ustr((const char*)reader.Value());
5616 emb_val->embval_array->get_at(emb_val->embval_index)->set_value(&emb_ustr);
5617 }
5618 if (last_embval_index == emb_val->embval_index) {
5619 ++emb_val->embval_index;
5620 }
5621 }
5622 }
5623 } // if use-order
5624
5625 if (0 != emb_val) {
5626 bool all_unbound = true;
5627 static const UNIVERSAL_CHARSTRING emptystring(0, (const char*)NULL);
5628 for (int j = 0; j < emb_val->embval_index; ++j) {
5629 if (!emb_val->embval_array->get_at(j)->is_bound()) {
5630 emb_val->embval_array->get_at(j)->set_value(&emptystring);
5631 }else if((static_cast<const UNIVERSAL_CHARSTRING*>(emb_val->embval_array->get_at(j)))->lengthof() !=0) {
5632 all_unbound = false;
5633 }
5634 }
5635 if(emb_val_optional && all_unbound){
5636 static_cast<OPTIONAL<PreGenRecordOf::PREGEN__RECORD__OF__UNIVERSAL__CHARSTRING>*>(get_at(0))->set_to_omit();
5637 }
5638 delete emb_val;
5639 } // if embed-values
5640
5641 } // if use-qname
5642
5643 // Check if every non-optional field has been set
5644 for (i = 0; i < field_cnt; ++i) {
5645 if (!get_at(i)->is_optional() && !get_at(i)->is_bound()) {
5646 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INCOMPL_MSG,
5647 "No data found for non-optional field '%s'", fld_name(i));
5648 }
5649 }
5650
5651 if (own_tag) {
5652 // We had our start tag. Then our fields did their thing.
5653 // Now we expect the end tag. And it better be our end tag!
5654 int current_depth;
5655 for (success = reader.Ok(); success == 1; success = reader.Read()) {
5656 type = reader.NodeType();
5657 current_depth = reader.Depth();
5658 if (current_depth > depth) {
5659 if (XML_READER_TYPE_ELEMENT == type) {
5660 // We found a deeper start tag; it was not processed at all.
5661 // That is an error (maybe we should report error for all node types
5662 // except TEXT and WHITESPACE, not just ELEMENT).
5663 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TAG,
5664 "Unprocessed XML tag `%s'", (const char *)reader.Name());
5665 }
5666
5667 continue; // go past hoping that our end tag will arrive eventually
5668 }
5669 else if (current_depth == depth) { // at our level
5670 if (XML_READER_TYPE_ELEMENT == type) {
5671 verify_name(reader, p_td, exer);
5672 if (reader.IsEmptyElement()) {
5673 // FIXME this shouldn't really be possible;
5674 // only an empty record should be encoded as an empty element,
5675 // but those are implemented by Empty_Record_Type, not Record_Type.
5676 reader.Read(); // one last time
5677 break;
5678 }
5679 }
5680 // If we find an end tag at the right depth, it must be ours
5681 else if (XML_READER_TYPE_END_ELEMENT == type) {
5682 verify_end(reader, p_td, depth, exer);
5683 reader.Read();
5684 break;
5685 }
5686 }
5687 else { //current_depth < depth; something has gone horribly wrong
5688 break; // better quit before we do further damage
5689 // Don't report an error; every enclosing type would do so,
5690 // spewing the same message over and over.
5691 }
5692 } // next
5693 }
5694 return 1; // decode successful
5695 }
5696
5697 int Record_Type::JSON_encode(const TTCN_Typedescriptor_t& p_td, JSON_Tokenizer& p_tok) const
5698 {
5699 if (err_descr) {
5700 return JSON_encode_negtest(err_descr, p_td, p_tok);
5701 }
5702
5703 if (!is_bound()) {
5704 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND,
5705 "Encoding an unbound %s value.", is_set() ? "set" : "record");
5706 return -1;
5707 }
5708
5709 int enc_len = p_tok.put_next_token(JSON_TOKEN_OBJECT_START, NULL);
5710
5711 int field_count = get_count();
5712 for (int i = 0; i < field_count; ++i) {
5713 boolean metainfo_unbound = NULL != fld_descr(i)->json && fld_descr(i)->json->metainfo_unbound;
5714 if ((NULL != fld_descr(i)->json && fld_descr(i)->json->omit_as_null) ||
5715 get_at(i)->is_present() || metainfo_unbound) {
5716 const char* field_name = (NULL != fld_descr(i)->json && NULL != fld_descr(i)->json->alias) ?
5717 fld_descr(i)->json->alias : fld_name(i);
5718 enc_len += p_tok.put_next_token(JSON_TOKEN_NAME, field_name);
5719 if (metainfo_unbound && !get_at(i)->is_bound()) {
5720 enc_len += p_tok.put_next_token(JSON_TOKEN_LITERAL_NULL);
5721 char* metainfo_str = mprintf("metainfo %s", field_name);
5722 enc_len += p_tok.put_next_token(JSON_TOKEN_NAME, metainfo_str);
5723 Free(metainfo_str);
5724 enc_len += p_tok.put_next_token(JSON_TOKEN_STRING, "\"unbound\"");
5725 }
5726 else {
5727 enc_len += get_at(i)->JSON_encode(*fld_descr(i), p_tok);
5728 }
5729 }
5730 }
5731
5732 enc_len += p_tok.put_next_token(JSON_TOKEN_OBJECT_END, NULL);
5733 return enc_len;
5734 }
5735
5736 int Record_Type::JSON_encode_negtest(const Erroneous_descriptor_t* p_err_descr,
5737 const TTCN_Typedescriptor_t& p_td,
5738 JSON_Tokenizer& p_tok) const
5739 {
5740 if (!is_bound()) {
5741 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND,
5742 "Encoding an unbound %s value.", is_set() ? "set" : "record");
5743 return -1;
5744 }
5745
5746 int enc_len = p_tok.put_next_token(JSON_TOKEN_OBJECT_START, NULL);
5747
5748 int values_idx = 0;
5749 int edescr_idx = 0;
5750
5751 int field_count = get_count();
5752 for (int i = 0; i < field_count; ++i) {
5753 if (-1 != p_err_descr->omit_before && p_err_descr->omit_before > i) {
5754 continue;
5755 }
5756
5757 const Erroneous_values_t* err_vals = p_err_descr->next_field_err_values(i, values_idx);
5758 const Erroneous_descriptor_t* emb_descr = p_err_descr->next_field_emb_descr(i, edescr_idx);
5759
5760 if (NULL != err_vals && NULL != err_vals->before) {
5761 if (NULL == err_vals->before->errval) {
5762 TTCN_error("internal error: erroneous before value missing");
5763 }
5764 if (err_vals->before->raw) {
5765 enc_len += err_vals->before->errval->JSON_encode_negtest_raw(p_tok);
5766 } else {
5767 if (NULL == err_vals->before->type_descr) {
5768 TTCN_error("internal error: erroneous before typedescriptor missing");
5769 }
5770 // it's an extra field, so use the erroneous type's name as the field name
5771 enc_len += p_tok.put_next_token(JSON_TOKEN_NAME, err_vals->before->type_descr->name);
5772 enc_len += err_vals->before->errval->JSON_encode(*(err_vals->before->type_descr), p_tok);
5773 }
5774 }
5775
5776 const char* field_name = (NULL != fld_descr(i)->json && NULL != fld_descr(i)->json->alias) ?
5777 fld_descr(i)->json->alias : fld_name(i);
5778 if (NULL != err_vals && NULL != err_vals->value) {
5779 if (NULL != err_vals->value->errval) {
5780 if (err_vals->value->raw) {
5781 enc_len += err_vals->value->errval->JSON_encode_negtest_raw(p_tok);
5782 } else {
5783 if (NULL == err_vals->value->type_descr) {
5784 TTCN_error("internal error: erroneous before typedescriptor missing");
5785 }
5786 // only replace the field's value, keep the field name
5787 enc_len += p_tok.put_next_token(JSON_TOKEN_NAME, field_name);
5788 enc_len += err_vals->value->errval->JSON_encode(*(err_vals->value->type_descr), p_tok);
5789 }
5790 }
5791 } else {
5792 boolean metainfo_unbound = NULL != fld_descr(i)->json && fld_descr(i)->json->metainfo_unbound;
5793 if ((NULL != fld_descr(i)->json && fld_descr(i)->json->omit_as_null) ||
5794 get_at(i)->is_present() || metainfo_unbound) {
5795 enc_len += p_tok.put_next_token(JSON_TOKEN_NAME, field_name);
5796 if (metainfo_unbound && !get_at(i)->is_bound()) {
5797 enc_len += p_tok.put_next_token(JSON_TOKEN_LITERAL_NULL);
5798 char* metainfo_str = mprintf("metainfo %s", field_name);
5799 enc_len += p_tok.put_next_token(JSON_TOKEN_NAME, metainfo_str);
5800 Free(metainfo_str);
5801 enc_len += p_tok.put_next_token(JSON_TOKEN_STRING, "\"unbound\"");
5802 }
5803 else if (NULL != emb_descr) {
5804 enc_len += get_at(i)->JSON_encode_negtest(emb_descr, *fld_descr(i), p_tok);
5805 } else {
5806 enc_len += get_at(i)->JSON_encode(*fld_descr(i), p_tok);
5807 }
5808 }
5809 }
5810
5811 if (NULL != err_vals && NULL != err_vals->after) {
5812 if (NULL == err_vals->after->errval) {
5813 TTCN_error("internal error: erroneous after value missing");
5814 }
5815 if (err_vals->after->raw) {
5816 enc_len += err_vals->after->errval->JSON_encode_negtest_raw(p_tok);
5817 } else {
5818 if (NULL == err_vals->after->type_descr) {
5819 TTCN_error("internal error: erroneous before typedescriptor missing");
5820 }
5821 // it's an extra field, so use the erroneous type's name as the field name
5822 enc_len += p_tok.put_next_token(JSON_TOKEN_NAME, err_vals->after->type_descr->name);
5823 enc_len += err_vals->after->errval->JSON_encode(*(err_vals->after->type_descr), p_tok);
5824 }
5825 }
5826
5827 if (-1 != p_err_descr->omit_after && p_err_descr->omit_after <= i) {
5828 break;
5829 }
5830 }
5831
5832 enc_len += p_tok.put_next_token(JSON_TOKEN_OBJECT_END, NULL);
5833 return enc_len;
5834 }
5835
5836 int Record_Type::JSON_decode(const TTCN_Typedescriptor_t& p_td, JSON_Tokenizer& p_tok, boolean p_silent)
5837 {
5838 json_token_t token = JSON_TOKEN_NONE;
5839 int dec_len = p_tok.get_next_token(&token, NULL, NULL);
5840 if (JSON_TOKEN_ERROR == token) {
5841 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_BAD_TOKEN_ERROR, "");
5842 return JSON_ERROR_FATAL;
5843 }
5844 else if (JSON_TOKEN_OBJECT_START != token) {
5845 return JSON_ERROR_INVALID_TOKEN;
5846 }
5847
5848 const int field_count = get_count();
5849
5850 // initialize meta info states
5851 int* metainfo = new int[field_count];
5852 boolean* field_found = new boolean[field_count];
5853 for (int i = 0; i < field_count; ++i) {
5854 field_found[i] = FALSE;
5855 metainfo[i] = (NULL != fld_descr(i)->json && fld_descr(i)->json->metainfo_unbound) ?
5856 JSON_METAINFO_NONE : JSON_METAINFO_NOT_APPLICABLE;
5857 }
5858
5859 while (true) {
5860 // Read name - value token pairs until we reach some other token
5861 char* name = 0;
5862 size_t name_len = 0;
5863 size_t buf_pos = p_tok.get_buf_pos();
5864 dec_len += p_tok.get_next_token(&token, &name, &name_len);
5865 if (JSON_TOKEN_ERROR == token) {
5866 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_BAD_TOKEN_ERROR, "");
5867 return JSON_ERROR_FATAL;
5868 }
5869 else if (JSON_TOKEN_NAME != token) {
5870 // undo the last action on the buffer
5871 p_tok.set_buf_pos(buf_pos);
5872 break;
5873 }
5874 else {
5875 // check for meta info
5876 boolean is_metainfo = FALSE;
5877 if (name_len > 9 && 0 == strncmp(name, "metainfo ", 9)) {
5878 name += 9;
5879 name_len -= 9;
5880 is_metainfo = TRUE;
5881 }
5882
5883 // check field name
5884 int field_idx;
5885 for (field_idx = 0; field_idx < field_count; ++field_idx) {
5886 const char* expected_name = 0;
5887 if (NULL != fld_descr(field_idx)->json && NULL != fld_descr(field_idx)->json->alias) {
5888 expected_name = fld_descr(field_idx)->json->alias;
5889 } else {
5890 expected_name = fld_name(field_idx);
5891 }
5892 if (strlen(expected_name) == name_len &&
5893 0 == strncmp(expected_name, name, name_len)) {
5894 field_found[field_idx] = TRUE;
5895 break;
5896 }
5897 }
5898 if (field_count == field_idx) {
5899 // invalid field name
5900 char* name2 = mcopystrn(name, name_len);
5901 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, is_metainfo ?
5902 JSON_DEC_METAINFO_NAME_ERROR : JSON_DEC_INVALID_NAME_ERROR, name2);
5903 // if this is set to a warning, skip the value of the field
5904 dec_len += p_tok.get_next_token(&token, NULL, NULL);
5905 if (JSON_TOKEN_NUMBER != token && JSON_TOKEN_STRING != token &&
5906 JSON_TOKEN_LITERAL_TRUE != token && JSON_TOKEN_LITERAL_FALSE != token &&
5907 JSON_TOKEN_LITERAL_NULL != token) {
5908 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_FIELD_TOKEN_ERROR, name2);
5909 Free(name2);
5910 return JSON_ERROR_FATAL;
5911 }
5912 Free(name2);
5913 continue;
5914 }
5915
5916 if (is_metainfo) {
5917 if (JSON_METAINFO_NOT_APPLICABLE != metainfo[field_idx]) {
5918 // check meta info
5919 char* info_value = 0;
5920 size_t info_len = 0;
5921 dec_len += p_tok.get_next_token(&token, &info_value, &info_len);
5922 if (JSON_TOKEN_STRING == token && 9 == info_len &&
5923 0 == strncmp(info_value, "\"unbound\"", 9)) {
5924 metainfo[field_idx] = JSON_METAINFO_UNBOUND;
5925 }
5926 else {
5927 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_METAINFO_VALUE_ERROR,
5928 fld_name(field_idx));
5929 return JSON_ERROR_FATAL;
5930 }
5931 }
5932 else {
5933 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_METAINFO_NOT_APPLICABLE,
5934 fld_name(field_idx));
5935 return JSON_ERROR_FATAL;
5936 }
5937 }
5938 else {
5939 buf_pos = p_tok.get_buf_pos();
5940 int ret_val = get_at(field_idx)->JSON_decode(*fld_descr(field_idx), p_tok, p_silent);
5941 if (0 > ret_val) {
5942 if (JSON_ERROR_INVALID_TOKEN == ret_val) {
5943 // undo the last action on the buffer, check if the invalid token was a null token
5944 p_tok.set_buf_pos(buf_pos);
5945 p_tok.get_next_token(&token, NULL, NULL);
5946 if (JSON_TOKEN_LITERAL_NULL == token) {
5947 if (JSON_METAINFO_NONE == metainfo[field_idx]) {
5948 // delay reporting an error for now, there might be meta info later
5949 metainfo[field_idx] = JSON_METAINFO_NEEDED;
5950 continue;
5951 }
5952 else if (JSON_METAINFO_UNBOUND == metainfo[field_idx]) {
5953 // meta info already found
5954 continue;
5955 }
5956 }
5957 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_FIELD_TOKEN_ERROR, fld_name(field_idx));
5958 }
5959 return JSON_ERROR_FATAL;
5960 }
5961 dec_len += ret_val;
5962 }
5963 }
5964 }
5965
5966 dec_len += p_tok.get_next_token(&token, NULL, NULL);
5967 if (JSON_TOKEN_OBJECT_END != token) {
5968 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_OBJECT_END_TOKEN_ERROR, "");
5969 return JSON_ERROR_FATAL;
5970 }
5971
5972 // Check if every field has been set and handle meta info
5973 for (int field_idx = 0; field_idx < field_count; ++field_idx) {
5974 Base_Type* field = get_at(field_idx);
5975 if (JSON_METAINFO_UNBOUND == metainfo[field_idx]) {
5976 field->clean_up();
5977 }
5978 else if (JSON_METAINFO_NEEDED == metainfo[field_idx]) {
5979 // no meta info was found for this field, report the delayed error
5980 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_FIELD_TOKEN_ERROR, fld_name(field_idx));
5981 }
5982 else if (!field_found[field_idx]) {
5983 if (NULL != fld_descr(field_idx)->json && NULL != fld_descr(field_idx)->json->default_value) {
5984 get_at(field_idx)->JSON_decode(*fld_descr(field_idx), DUMMY_BUFFER, p_silent);
5985 }
5986 else if (field->is_optional()) {
5987 field->set_to_omit();
5988 } else {
5989 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_MISSING_FIELD_ERROR, fld_name(field_idx));
5990 return JSON_ERROR_FATAL;
5991 }
5992 }
5993 }
5994
5995 delete metainfo;
5996
5997 return dec_len;
5998 }
5999
6000 ////////////////////////////////////////////////////////////////////////////////
6001
6002 Empty_Record_Type::Empty_Record_Type(): bound_flag(FALSE)
6003 {
6004 }
6005
6006 Empty_Record_Type::Empty_Record_Type(const Empty_Record_Type& other_value)
6007 : Base_Type(other_value), bound_flag(other_value.bound_flag)
6008 {
6009 if (!other_value.bound_flag)
6010 TTCN_error("Copying an unbound value of type %s.",
6011 other_value.get_descriptor()->name);
6012 }
6013
6014 boolean Empty_Record_Type::operator==(null_type) const
6015 {
6016 if (!bound_flag)
6017 TTCN_error("Comparison of an unbound value of type %s.",
6018 get_descriptor()->name);
6019 return TRUE;
6020 }
6021
6022 void Empty_Record_Type::log() const
6023 {
6024 if (bound_flag) TTCN_Logger::log_event_str("{ }");
6025 else TTCN_Logger::log_event_unbound();
6026 }
6027
6028 void Empty_Record_Type::set_param(Module_Param& param) {
6029 param.basic_check(Module_Param::BC_VALUE, "empty record/set value (i.e. { })");
6030 Module_Param_Ptr mp = &param;
6031 if (param.get_type() == Module_Param::MP_Reference) {
6032 mp = param.get_referenced_param();
6033 }
6034 if (mp->get_type()!=Module_Param::MP_Value_List || mp->get_size()>0) {
6035 param.type_error("empty record/set value (i.e. { })", get_descriptor()->name);
6036 }
6037 bound_flag = TRUE;
6038 }
6039
6040 Module_Param* Empty_Record_Type::get_param(Module_Param_Name& /* param_name */) const
6041 {
6042 if (!is_bound()) {
6043 return new Module_Param_Unbound();
6044 }
6045 return new Module_Param_Value_List();
6046 }
6047
6048 void Empty_Record_Type::encode_text(Text_Buf& /*text_buf*/) const
6049 {
6050 if (!bound_flag)
6051 TTCN_error("Text encoder: Encoding an unbound value of type %s.",
6052 get_descriptor()->name);
6053 }
6054
6055 void Empty_Record_Type::decode_text(Text_Buf& /*text_buf*/)
6056 {
6057 bound_flag = TRUE;
6058 }
6059
6060 boolean Empty_Record_Type::is_equal(const Base_Type* other_value) const
6061 {
6062 const Empty_Record_Type* r2 = static_cast<const Empty_Record_Type*>(other_value);
6063 if ((bound_flag && r2->bound_flag) || (!bound_flag && !r2->bound_flag))
6064 return TRUE;
6065 if (!bound_flag || !r2->bound_flag)
6066 TTCN_error("Comparison of an unbound value of type %s.", get_descriptor()->name);
6067 return FALSE;
6068 }
6069
6070 void Empty_Record_Type::set_value(const Base_Type* other_value)
6071 {
6072 if (!static_cast<const Empty_Record_Type*>(other_value)->is_bound())
6073 TTCN_error("Assignment of an unbound value of type %s.",
6074 other_value->get_descriptor()->name);
6075 bound_flag = TRUE;
6076 }
6077
6078 void Empty_Record_Type::encode(const TTCN_Typedescriptor_t& p_td,
6079 TTCN_Buffer& p_buf, TTCN_EncDec::coding_t p_coding, ...) const
6080 {
6081 va_list pvar;
6082 va_start(pvar, p_coding);
6083 switch(p_coding) {
6084 case TTCN_EncDec::CT_BER: {
6085 TTCN_EncDec_ErrorContext ec("While BER-encoding type '%s': ", p_td.name);
6086 unsigned BER_coding=va_arg(pvar, unsigned);
6087 BER_encode_chk_coding(BER_coding);
6088 ASN_BER_TLV_t *tlv=BER_encode_TLV(p_td, BER_coding);
6089 tlv->put_in_buffer(p_buf);
6090 ASN_BER_TLV_t::destruct(tlv);
6091 break;}
6092 case TTCN_EncDec::CT_RAW: {
6093 TTCN_EncDec_ErrorContext ec("While RAW-encoding type '%s': ", p_td.name);
6094 if(!p_td.raw) TTCN_EncDec_ErrorContext::error_internal
6095 ("No RAW descriptor available for type '%s'.", p_td.name);
6096 RAW_enc_tr_pos rp;
6097 rp.level=0;
6098 rp.pos=NULL;
6099 RAW_enc_tree root(FALSE, NULL, &rp, 1, p_td.raw);
6100 RAW_encode(p_td, root);
6101 root.put_to_buf(p_buf);
6102 break;}
6103 case TTCN_EncDec::CT_TEXT: {
6104 TTCN_EncDec_ErrorContext ec("While TEXT-encoding type '%s': ", p_td.name);
6105 if(!p_td.text) TTCN_EncDec_ErrorContext::error_internal
6106 ("No TEXT descriptor available for type '%s'.", p_td.name);
6107 TEXT_encode(p_td,p_buf);
6108 break;}
6109 case TTCN_EncDec::CT_XER: {
6110 TTCN_EncDec_ErrorContext ec("While XER-encoding type '%s': ", p_td.name);
6111 unsigned XER_coding=va_arg(pvar, unsigned);
6112 XER_encode(*(p_td.xer),p_buf, XER_coding, 0, 0);
6113 p_buf.put_c('\n');
6114 break;}
6115 case TTCN_EncDec::CT_JSON: {
6116 TTCN_EncDec_ErrorContext ec("While JSON-encoding type '%s': ", p_td.name);
6117 if(!p_td.json) TTCN_EncDec_ErrorContext::error_internal
6118 ("No JSON descriptor available for type '%s'.", p_td.name);
6119 JSON_Tokenizer tok(va_arg(pvar, int) != 0);
6120 JSON_encode(p_td, tok);
6121 p_buf.put_s(tok.get_buffer_length(), (const unsigned char*)tok.get_buffer());
6122 break;}
6123 default:
6124 TTCN_error("Unknown coding method requested to encode type '%s'", p_td.name);
6125 }
6126 va_end(pvar);
6127 }
6128
6129 void Empty_Record_Type::decode(const TTCN_Typedescriptor_t& p_td,
6130 TTCN_Buffer& p_buf, TTCN_EncDec::coding_t p_coding, ...)
6131 {
6132 va_list pvar;
6133 va_start(pvar, p_coding);
6134 switch(p_coding) {
6135 case TTCN_EncDec::CT_BER: {
6136 TTCN_EncDec_ErrorContext ec("While BER-decoding type '%s': ", p_td.name);
6137 unsigned L_form=va_arg(pvar, unsigned);
6138 ASN_BER_TLV_t tlv;
6139 BER_decode_str2TLV(p_buf, tlv, L_form);
6140 BER_decode_TLV(p_td, tlv, L_form);
6141 if(tlv.isComplete) p_buf.increase_pos(tlv.get_len());
6142 break;}
6143 case TTCN_EncDec::CT_RAW: {
6144 TTCN_EncDec_ErrorContext ec("While RAW-decoding type '%s': ", p_td.name);
6145 if(!p_td.raw)
6146 TTCN_EncDec_ErrorContext::error_internal
6147 ("No RAW descriptor available for type '%s'.", p_td.name);
6148 raw_order_t order;
6149 switch(p_td.raw->top_bit_order) {
6150 case TOP_BIT_LEFT:
6151 order=ORDER_LSB;
6152 break;
6153 case TOP_BIT_RIGHT:
6154 default:
6155 order=ORDER_MSB;
6156 }
6157 if(RAW_decode(p_td, p_buf, p_buf.get_len()*8, order)<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 break;}
6162 case TTCN_EncDec::CT_TEXT: {
6163 Limit_Token_List limit;
6164 TTCN_EncDec_ErrorContext ec("While TEXT-decoding type '%s': ", p_td.name);
6165 if(!p_td.text) TTCN_EncDec_ErrorContext::error_internal
6166 ("No TEXT descriptor available for type '%s'.", p_td.name);
6167 const unsigned char *b=p_buf.get_data();
6168 if(b[p_buf.get_len()-1]!='\0'){
6169 p_buf.set_pos(p_buf.get_len());
6170 p_buf.put_zero(8,ORDER_LSB);
6171 p_buf.rewind();
6172 }
6173 if(TEXT_decode(p_td,p_buf,limit)<0)
6174 ec.error(TTCN_EncDec::ET_INCOMPL_MSG,
6175 "Can not decode type '%s', because invalid or incomplete"
6176 " message was received", p_td.name);
6177 break;}
6178 case TTCN_EncDec::CT_XER: {
6179 TTCN_EncDec_ErrorContext ec("While XER-decoding type '%s': ", p_td.name);
6180 unsigned XER_coding=va_arg(pvar, unsigned);
6181 XmlReaderWrap reader(p_buf);
6182 for (int success=reader.Read(); success==1; success=reader.Read()) {
6183 if (reader.NodeType() == XML_READER_TYPE_ELEMENT) break;
6184 }
6185 XER_decode(*(p_td.xer), reader, XER_coding | XER_TOPLEVEL, XER_NONE, 0);
6186 size_t bytes = reader.ByteConsumed();
6187 p_buf.set_pos(bytes);
6188 break;}
6189 case TTCN_EncDec::CT_JSON: {
6190 TTCN_EncDec_ErrorContext ec("While JSON-decoding type '%s': ", p_td.name);
6191 if(!p_td.json) TTCN_EncDec_ErrorContext::error_internal
6192 ("No JSON descriptor available for type '%s'.", p_td.name);
6193 JSON_Tokenizer tok((const char*)p_buf.get_data(), p_buf.get_len());
6194 if(JSON_decode(p_td, tok, false)<0)
6195 ec.error(TTCN_EncDec::ET_INCOMPL_MSG,
6196 "Can not decode type '%s', because invalid or incomplete"
6197 " message was received", p_td.name);
6198 p_buf.set_pos(tok.get_buf_pos());
6199 break;}
6200 default:
6201 TTCN_error("Unknown coding method requested to decode type '%s'", p_td.name);
6202 }
6203 va_end(pvar);
6204 }
6205
6206 ASN_BER_TLV_t* Empty_Record_Type::BER_encode_TLV(const TTCN_Typedescriptor_t& p_td,
6207 unsigned p_coding) const
6208 {
6209 BER_chk_descr(p_td);
6210 ASN_BER_TLV_t *new_tlv=ASN_BER_TLV_t::construct(NULL);
6211 new_tlv=ASN_BER_V2TLV(new_tlv, p_td, p_coding);
6212 return new_tlv;
6213 }
6214
6215 boolean Empty_Record_Type::BER_decode_TLV(const TTCN_Typedescriptor_t& p_td,
6216 const ASN_BER_TLV_t& p_tlv, unsigned L_form)
6217 {
6218 BER_chk_descr(p_td);
6219 ASN_BER_TLV_t stripped_tlv;
6220 BER_decode_strip_tags(*p_td.ber, p_tlv, L_form, stripped_tlv);
6221 TTCN_EncDec_ErrorContext ec_0("While decoding '%s' type: ", get_descriptor()->name);
6222 stripped_tlv.chk_constructed_flag(TRUE);
6223 bound_flag=TRUE;
6224 return TRUE;
6225 }
6226
6227 int Empty_Record_Type::RAW_encode(const TTCN_Typedescriptor_t& p_td,
6228 RAW_enc_tree& /*myleaf*/) const
6229 {
6230 if (!bound_flag) TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND,
6231 "Encoding an unbound value of type %s.", p_td.name);
6232 return 0;
6233 }
6234
6235 int Empty_Record_Type::RAW_decode(const TTCN_Typedescriptor_t& p_td,
6236 TTCN_Buffer& buff, int /*limit*/, raw_order_t /*top_bit_ord*/,
6237 boolean /*no_err*/, int /*sel_field*/, boolean /*first_call*/)
6238 {
6239 bound_flag = TRUE;
6240 return buff.increase_pos_padd(p_td.raw->prepadding)
6241 + buff.increase_pos_padd(p_td.raw->padding);
6242 }
6243
6244 int Empty_Record_Type::TEXT_encode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& buff) const
6245 {
6246 int encoded_length=0;
6247 if(p_td.text->begin_encode) {
6248 buff.put_cs(*p_td.text->begin_encode);
6249 encoded_length+=p_td.text->begin_encode->lengthof();
6250 }
6251 if (!bound_flag) {
6252 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND, "Encoding an unbound value.");
6253 }
6254 if(p_td.text->end_encode) {
6255 buff.put_cs(*p_td.text->end_encode);
6256 encoded_length+=p_td.text->end_encode->lengthof();
6257 }
6258 return encoded_length;
6259 }
6260
6261 int Empty_Record_Type::TEXT_decode(const TTCN_Typedescriptor_t& p_td,
6262 TTCN_Buffer& buff, Limit_Token_List& /*limit*/, boolean no_err, boolean /*first_call*/)
6263 {
6264 int decoded_length=0;
6265 if(p_td.text->begin_decode) {
6266 int tl;
6267 if((tl=p_td.text->begin_decode->match_begin(buff))<0) {
6268 if(no_err)return -1;
6269 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR,
6270 "The specified token '%s' not found for '%s': ",
6271 (const char*)*(p_td.text->begin_decode), p_td.name);
6272 return 0;
6273 }
6274 decoded_length+=tl;
6275 buff.increase_pos(tl);
6276 }
6277 if(p_td.text->end_decode) {
6278 int tl;
6279 if((tl=p_td.text->end_decode->match_begin(buff))<0) {
6280 if(no_err)return -1;
6281 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR,
6282 "The specified token '%s' not found for '%s': ",
6283 (const char*)*(p_td.text->end_decode), p_td.name);
6284 return 0;
6285 }
6286 decoded_length+=tl;
6287 buff.increase_pos(tl);
6288 }
6289 bound_flag = TRUE;
6290 return decoded_length;
6291 }
6292
6293 int Empty_Record_Type::XER_encode(const XERdescriptor_t& p_td,
6294 TTCN_Buffer& p_buf, unsigned int flavor, int indent, embed_values_enc_struct_t*) const
6295 {
6296 int encoded_length=(int)p_buf.get_len();
6297 int indenting = !is_canonical(flavor);
6298 int exer = is_exer(flavor);
6299 if (indenting) do_indent(p_buf, indent);
6300 p_buf.put_c('<');
6301 if (exer) write_ns_prefix(p_td, p_buf);
6302 p_buf.put_s((size_t)p_td.namelens[exer]-2, (cbyte*)p_td.names[exer]);
6303 p_buf.put_s(2 + indenting, (cbyte*)"/>\n");
6304 return (int)p_buf.get_len() - encoded_length;
6305 }
6306
6307 int Empty_Record_Type::XER_decode(const XERdescriptor_t& p_td,
6308 XmlReaderWrap& reader, unsigned int flavor, unsigned int /*flavor2*/, embed_values_dec_struct_t*)
6309 {
6310 int exer = is_exer(flavor);
6311 bound_flag = true;
6312 int success, depth = -1;
6313 for (success=reader.Ok(); success==1; success=reader.Read()) {
6314 int type = reader.NodeType();
6315 if (type==XML_READER_TYPE_ELEMENT) {
6316 verify_name(reader, p_td, exer);
6317 depth = reader.Depth();
6318
6319 if (reader.IsEmptyElement()) {
6320 reader.Read(); break;
6321 }
6322 else if ((flavor & XER_MASK) == XER_CANONICAL) {
6323 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG,
6324 "Expected an empty element tag");
6325 // Stay in the loop and look for the end element, in case the error
6326 // was ignored or reduced to warning.
6327 } // if(empty)
6328 }
6329 else if (type == XML_READER_TYPE_END_ELEMENT && depth != -1) {
6330 verify_end(reader, p_td, depth, exer);
6331 reader.Read();
6332 break;
6333 }
6334 }
6335 return 1; // decode successful
6336 }
6337
6338 int Empty_Record_Type::JSON_encode(const TTCN_Typedescriptor_t&, JSON_Tokenizer& p_tok) const
6339 {
6340 if (!is_bound()) {
6341 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND,
6342 "Encoding an unbound empty %s value.", is_set() ? "set" : "record");
6343 return -1;
6344 }
6345
6346 return p_tok.put_next_token(JSON_TOKEN_OBJECT_START, NULL) +
6347 p_tok.put_next_token(JSON_TOKEN_OBJECT_END, NULL);
6348 }
6349
6350 int Empty_Record_Type::JSON_decode(const TTCN_Typedescriptor_t&, JSON_Tokenizer& p_tok, boolean p_silent)
6351 {
6352 json_token_t token = JSON_TOKEN_NONE;
6353 int dec_len = p_tok.get_next_token(&token, NULL, NULL);
6354 if (JSON_TOKEN_ERROR == token) {
6355 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_BAD_TOKEN_ERROR, "");
6356 return JSON_ERROR_FATAL;
6357 }
6358 else if (JSON_TOKEN_OBJECT_START != token) {
6359 return JSON_ERROR_INVALID_TOKEN;
6360 }
6361
6362 dec_len += p_tok.get_next_token(&token, NULL, NULL);
6363 if (JSON_TOKEN_OBJECT_END != token) {
6364 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_STATIC_OBJECT_END_TOKEN_ERROR, "");
6365 return JSON_ERROR_FATAL;
6366 }
6367
6368 bound_flag = true;
6369
6370 return dec_len;
6371 }
6372
6373 boolean operator==(null_type /*null_value*/, const Empty_Record_Type& other_value)
6374 {
6375 if (!other_value.is_bound())
6376 TTCN_error("Comparison of an unbound value of type %s.",
6377 other_value.get_descriptor()->name);
6378 return TRUE;
6379 }
6380
6381 boolean operator!=(null_type /*null_value*/, const Empty_Record_Type& other_value)
6382 {
6383 if (!other_value.is_bound())
6384 TTCN_error("Comparison of an unbound value of type %s.",
6385 other_value.get_descriptor()->name);
6386 return FALSE;
6387 }
6388 #endif
This page took 0.233886 seconds and 5 git commands to generate.