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