SIM-115: update simulator to use latest E2SM KPM version 3
[sim/e2-interface.git] / e2sim / asn1c / constr_SEQUENCE_uper.c
1 /*
2  * Copyright (c) 2017 Lev Walkin <vlm@lionet.info>.
3  * All rights reserved.
4  * Redistribution and modifications are permitted subject to BSD license.
5  */
6 #include <asn_internal.h>
7 #include <constr_SEQUENCE.h>
8 #include <OPEN_TYPE.h>
9 #include <uper_opentype.h>
10
11 /*
12  * Check whether we are inside the extensions group.
13  */
14 #define IN_EXTENSION_GROUP(specs, memb_idx)                \
15     ((specs)->first_extension >= 0                         \
16      && (unsigned)(specs)->first_extension <= (memb_idx))
17
18 asn_dec_rval_t
19 SEQUENCE_decode_uper(const asn_codec_ctx_t *opt_codec_ctx,
20                      const asn_TYPE_descriptor_t *td,
21                      const asn_per_constraints_t *constraints, void **sptr,
22                      asn_per_data_t *pd) {
23     const asn_SEQUENCE_specifics_t *specs = (const asn_SEQUENCE_specifics_t *)td->specifics;
24     void *st = *sptr;  /* Target structure. */
25     int extpresent;    /* Extension additions are present */
26     uint8_t *opres;    /* Presence of optional root members */
27     asn_per_data_t opmd;
28     asn_dec_rval_t rv;
29     size_t edx;
30
31     (void)constraints;
32
33     if(ASN__STACK_OVERFLOW_CHECK(opt_codec_ctx))
34         ASN__DECODE_FAILED;
35
36     if(!st) {
37         st = *sptr = CALLOC(1, specs->struct_size);
38         if(!st) ASN__DECODE_FAILED;
39     }
40
41     ASN_DEBUG("Decoding %s as SEQUENCE (UPER)", td->name);
42
43     /* Handle extensions */
44     if(specs->first_extension < 0) {
45         extpresent = 0;
46     } else {
47         extpresent = per_get_few_bits(pd, 1);
48         if(extpresent < 0) ASN__DECODE_STARVED;
49     }
50
51     /* Prepare a place and read-in the presence bitmap */
52     memset(&opmd, 0, sizeof(opmd));
53     if(specs->roms_count) {
54         opres = (uint8_t *)MALLOC(((specs->roms_count + 7) >> 3) + 1);
55         if(!opres) ASN__DECODE_FAILED;
56         /* Get the presence map */
57         if(per_get_many_bits(pd, opres, 0, specs->roms_count)) {
58             FREEMEM(opres);
59             ASN__DECODE_STARVED;
60         }
61         opmd.buffer = opres;
62         opmd.nbits = specs->roms_count;
63         ASN_DEBUG("Read in presence bitmap for %s of %d bits (%x..)",
64                   td->name, specs->roms_count, *opres);
65     } else {
66         opres = 0;
67     }
68
69     /*
70      * Get the sequence ROOT elements.
71      */
72     for(edx = 0;
73         edx < (specs->first_extension < 0 ? td->elements_count
74                                           : (size_t)specs->first_extension);
75         edx++) {
76         asn_TYPE_member_t *elm = &td->elements[edx];
77         void *memb_ptr;    /* Pointer to the member */
78         void **memb_ptr2;  /* Pointer to that pointer */
79
80         assert(!IN_EXTENSION_GROUP(specs, edx));
81
82         /* Fetch the pointer to this member */
83         if(elm->flags & ATF_POINTER) {
84             memb_ptr2 = (void **)((char *)st + elm->memb_offset);
85         } else {
86             memb_ptr = (char *)st + elm->memb_offset;
87             memb_ptr2 = &memb_ptr;
88         }
89
90         /* Deal with optionality */
91         if(elm->optional) {
92             int present = per_get_few_bits(&opmd, 1);
93             ASN_DEBUG("Member %s->%s is optional, p=%d (%d->%d)",
94                       td->name, elm->name, present,
95                       (int)opmd.nboff, (int)opmd.nbits);
96             if(present == 0) {
97                 /* This element is not present */
98                 if(elm->default_value_set) {
99                     /* Fill-in DEFAULT */
100                     if(elm->default_value_set(memb_ptr2)) {
101                         FREEMEM(opres);
102                         ASN__DECODE_FAILED;
103                     }
104                     ASN_DEBUG("Filled-in default");
105                 }
106                 /* The member is just not present */
107                 continue;
108             }
109             /* Fall through */
110         }
111
112         /* Fetch the member from the stream */
113         ASN_DEBUG("Decoding member \"%s\" in %s", elm->name, td->name);
114
115         if(elm->flags & ATF_OPEN_TYPE) {
116             rv = OPEN_TYPE_uper_get(opt_codec_ctx, td, st, elm, pd);
117         } else {
118             rv = elm->type->op->uper_decoder(opt_codec_ctx, elm->type,
119                                              elm->encoding_constraints.per_constraints,
120                                              memb_ptr2, pd);
121         }
122         if(rv.code != RC_OK) {
123             ASN_DEBUG("Failed decode %s in %s",
124                       elm->name, td->name);
125             FREEMEM(opres);
126             return rv;
127         }
128     }
129
130     /* Optionality map is not needed anymore */
131     FREEMEM(opres);
132
133     /*
134      * Deal with extensions.
135      */
136     if(extpresent) {
137         ssize_t bmlength;
138         uint8_t *epres;  /* Presence of extension members */
139         asn_per_data_t epmd;
140
141         bmlength = uper_get_nslength(pd);
142         if(bmlength < 0) ASN__DECODE_STARVED;
143
144         ASN_DEBUG("Extensions %" ASN_PRI_SSIZE " present in %s", bmlength, td->name);
145
146         epres = (uint8_t *)MALLOC((bmlength + 15) >> 3);
147         if(!epres) ASN__DECODE_STARVED;
148
149         /* Get the extensions map */
150         if(per_get_many_bits(pd, epres, 0, bmlength)) {
151             FREEMEM(epres);
152             ASN__DECODE_STARVED;
153         }
154
155         memset(&epmd, 0, sizeof(epmd));
156         epmd.buffer = epres;
157         epmd.nbits = bmlength;
158         ASN_DEBUG("Read in extensions bitmap for %s of %ld bits (%x..)",
159                   td->name, (long)bmlength, *epres);
160
161         /* Go over extensions and read them in */
162         for(edx = specs->first_extension; edx < td->elements_count; edx++) {
163             asn_TYPE_member_t *elm = &td->elements[edx];
164             void *memb_ptr;    /* Pointer to the member */
165             void **memb_ptr2;  /* Pointer to that pointer */
166             int present;
167
168             /* Fetch the pointer to this member */
169             if(elm->flags & ATF_POINTER) {
170                 memb_ptr2 = (void **)((char *)st + elm->memb_offset);
171             } else {
172                 memb_ptr = (void *)((char *)st + elm->memb_offset);
173                 memb_ptr2 = &memb_ptr;
174             }
175
176             present = per_get_few_bits(&epmd, 1);
177             if(present <= 0) {
178                 if(present < 0) break;  /* No more extensions */
179                 continue;
180             }
181
182             ASN_DEBUG("Decoding member %s in %s %p", elm->name, td->name,
183                       *memb_ptr2);
184             rv = uper_open_type_get(opt_codec_ctx, elm->type,
185                                     elm->encoding_constraints.per_constraints,
186                                     memb_ptr2, pd);
187             if(rv.code != RC_OK) {
188                 FREEMEM(epres);
189                 return rv;
190             }
191         }
192
193         /* Skip over overflow extensions which aren't present
194          * in this system's version of the protocol */
195         for(;;) {
196             ASN_DEBUG("Getting overflow extensions");
197             switch(per_get_few_bits(&epmd, 1)) {
198             case -1: break;
199             case 0: continue;
200             default:
201                 if(uper_open_type_skip(opt_codec_ctx, pd)) {
202                     FREEMEM(epres);
203                     ASN__DECODE_STARVED;
204                 }
205                 ASN_DEBUG("Skipped overflow extension");
206                 continue;
207             }
208             break;
209         }
210
211         FREEMEM(epres);
212     }
213
214     if(specs->first_extension >= 0) {
215         unsigned i;
216         /* Fill DEFAULT members in extensions */
217         for(i = specs->roms_count; i < specs->roms_count + specs->aoms_count;
218             i++) {
219             asn_TYPE_member_t *elm;
220             void **memb_ptr2;  /* Pointer to member pointer */
221
222             edx = specs->oms[i];
223             elm = &td->elements[edx];
224
225             if(!elm->default_value_set) continue;
226
227             /* Fetch the pointer to this member */
228             if(elm->flags & ATF_POINTER) {
229                 memb_ptr2 = (void **)((char *)st + elm->memb_offset);
230                 if(*memb_ptr2) continue;
231             } else {
232                 continue;  /* Extensions are all optionals */
233             }
234
235             /* Set default value */
236             if(elm->default_value_set(memb_ptr2)) {
237                 ASN__DECODE_FAILED;
238             }
239         }
240     }
241
242     rv.consumed = 0;
243     rv.code = RC_OK;
244     return rv;
245 }
246
247 static int
248 SEQUENCE__handle_extensions(const asn_TYPE_descriptor_t *td, const void *sptr,
249                             asn_per_outp_t *po1, asn_per_outp_t *po2) {
250     const asn_SEQUENCE_specifics_t *specs =
251         (const asn_SEQUENCE_specifics_t *)td->specifics;
252     int exts_present = 0;
253     int exts_count = 0;
254     size_t edx;
255
256     if(specs->first_extension < 0) {
257         return 0;
258     }
259
260     /* Find out which extensions are present */
261     for(edx = specs->first_extension; edx < td->elements_count; edx++) {
262         asn_TYPE_member_t *elm = &td->elements[edx];
263         const void *memb_ptr;          /* Pointer to the member */
264         const void *const *memb_ptr2;  /* Pointer to that pointer */
265         int present;
266
267         /* Fetch the pointer to this member */
268         if(elm->flags & ATF_POINTER) {
269             memb_ptr2 =
270                 (const void *const *)((const char *)sptr + elm->memb_offset);
271             present = (*memb_ptr2 != 0);
272         } else {
273             memb_ptr = (const void *)((const char *)sptr + elm->memb_offset);
274             memb_ptr2 = &memb_ptr;
275             present = 1;
276         }
277
278         ASN_DEBUG("checking %s:%s (@%" ASN_PRI_SIZE ") present => %d", elm->name,
279                   elm->type->name, edx, present);
280         exts_count++;
281         exts_present += present;
282
283         /* Encode as presence marker */
284         if(po1 && per_put_few_bits(po1, present, 1)) {
285             return -1;
286         }
287         /* Encode as open type field */
288         if(po2 && present
289            && uper_open_type_put(elm->type,
290                                  elm->encoding_constraints.per_constraints,
291                                  *memb_ptr2, po2))
292             return -1;
293     }
294
295     return exts_present ? exts_count : 0;
296 }
297
298 asn_enc_rval_t
299 SEQUENCE_encode_uper(const asn_TYPE_descriptor_t *td,
300                      const asn_per_constraints_t *constraints, const void *sptr,
301                      asn_per_outp_t *po) {
302     const asn_SEQUENCE_specifics_t *specs
303         = (const asn_SEQUENCE_specifics_t *)td->specifics;
304     asn_enc_rval_t er = {0,0,0};
305     int n_extensions;
306     size_t edx;
307     size_t i;
308
309     (void)constraints;
310
311     if(!sptr)
312         ASN__ENCODE_FAILED;
313
314     er.encoded = 0;
315
316     ASN_DEBUG("Encoding %s as SEQUENCE (UPER)", td->name);
317
318     /*
319      * X.691#18.1 Whether structure is extensible
320      * and whether to encode extensions
321      */
322     if(specs->first_extension < 0) {
323         n_extensions = 0; /* There are no extensions to encode */
324     } else {
325         n_extensions = SEQUENCE__handle_extensions(td, sptr, 0, 0);
326         if(n_extensions < 0) ASN__ENCODE_FAILED;
327         if(per_put_few_bits(po, n_extensions ? 1 : 0, 1)) {
328             ASN__ENCODE_FAILED;
329         }
330     }
331
332     /* Encode a presence bitmap */
333     for(i = 0; i < specs->roms_count; i++) {
334         asn_TYPE_member_t *elm;
335         const void *memb_ptr;          /* Pointer to the member */
336         const void *const *memb_ptr2;  /* Pointer to that pointer */
337         int present;
338
339         edx = specs->oms[i];
340         elm = &td->elements[edx];
341
342         /* Fetch the pointer to this member */
343         if(elm->flags & ATF_POINTER) {
344             memb_ptr2 =
345                 (const void *const *)((const char *)sptr + elm->memb_offset);
346             present = (*memb_ptr2 != 0);
347         } else {
348             memb_ptr = (const void *)((const char *)sptr + elm->memb_offset);
349             memb_ptr2 = &memb_ptr;
350             present = 1;
351         }
352
353         /* Eliminate default values */
354         if(present && elm->default_value_cmp
355            && elm->default_value_cmp(*memb_ptr2) == 0)
356             present = 0;
357
358         ASN_DEBUG("Element %s %s %s->%s is %s",
359                   elm->flags & ATF_POINTER ? "ptr" : "inline",
360                   elm->default_value_cmp ? "def" : "wtv",
361                   td->name, elm->name, present ? "present" : "absent");
362         if(per_put_few_bits(po, present, 1))
363             ASN__ENCODE_FAILED;
364     }
365
366     /*
367      * Encode the sequence ROOT elements.
368      */
369     ASN_DEBUG("first_extension = %d, elements = %d", specs->first_extension,
370               td->elements_count);
371     for(edx = 0;
372         edx < ((specs->first_extension < 0) ? td->elements_count
373                                             : (size_t)specs->first_extension);
374         edx++) {
375         asn_TYPE_member_t *elm = &td->elements[edx];
376         const void *memb_ptr;          /* Pointer to the member */
377         const void *const *memb_ptr2;  /* Pointer to that pointer */
378
379         ASN_DEBUG("About to encode %s", elm->type->name);
380
381         /* Fetch the pointer to this member */
382         if(elm->flags & ATF_POINTER) {
383             memb_ptr2 =
384                 (const void *const *)((const char *)sptr + elm->memb_offset);
385             if(!*memb_ptr2) {
386                 ASN_DEBUG("Element %s %" ASN_PRI_SIZE " not present",
387                     elm->name, edx);
388                 if(elm->optional)
389                     continue;
390                 /* Mandatory element is missing */
391                 ASN__ENCODE_FAILED;
392             }
393         } else {
394             memb_ptr = (const void *)((const char *)sptr + elm->memb_offset);
395             memb_ptr2 = &memb_ptr;
396         }
397
398         /* Eliminate default values */
399         if(elm->default_value_cmp && elm->default_value_cmp(*memb_ptr2) == 0)
400             continue;
401
402         ASN_DEBUG("Encoding %s->%s:%s", td->name, elm->name, elm->type->name);
403         er = elm->type->op->uper_encoder(
404             elm->type, elm->encoding_constraints.per_constraints, *memb_ptr2,
405             po);
406         if(er.encoded == -1) return er;
407     }
408
409     /* No extensions to encode */
410     if(!n_extensions) ASN__ENCODED_OK(er);
411
412     ASN_DEBUG("Length of extensions %d bit-map", n_extensions);
413     /* #18.8. Write down the presence bit-map length. */
414     if(uper_put_nslength(po, n_extensions))
415         ASN__ENCODE_FAILED;
416
417     ASN_DEBUG("Bit-map of %d elements", n_extensions);
418     /* #18.7. Encoding the extensions presence bit-map. */
419     /* TODO: act upon NOTE in #18.7 for canonical PER */
420     if(SEQUENCE__handle_extensions(td, sptr, po, 0) != n_extensions)
421         ASN__ENCODE_FAILED;
422
423     ASN_DEBUG("Writing %d extensions", n_extensions);
424     /* #18.9. Encode extensions as open type fields. */
425     if(SEQUENCE__handle_extensions(td, sptr, 0, po) != n_extensions)
426         ASN__ENCODE_FAILED;
427
428     ASN__ENCODED_OK(er);
429 }