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