Sync from Azure to LF
[ric-plt/resource-status-manager.git] / RSM / asn1codec / e2ap_engine / ANY.c
1
2 /*
3  * Copyright (c) 2004-2017 Lev Walkin <vlm@lionet.info>. All rights reserved.
4  * Redistribution and modifications are permitted subject to BSD license.
5  */
6 #include <asn_internal.h>
7 #include <ANY.h>
8 #include <errno.h>
9
10 asn_OCTET_STRING_specifics_t asn_SPC_ANY_specs = {
11         sizeof(ANY_t),
12         offsetof(ANY_t, _asn_ctx),
13         ASN_OSUBV_ANY
14 };
15 asn_TYPE_operation_t asn_OP_ANY = {
16         OCTET_STRING_free,
17         OCTET_STRING_print,
18         OCTET_STRING_compare,
19         OCTET_STRING_decode_ber,
20         OCTET_STRING_encode_der,
21         OCTET_STRING_decode_xer_hex,
22         ANY_encode_xer,
23 #ifdef  ASN_DISABLE_OER_SUPPORT
24         0,
25         0,
26 #else
27         0,
28         0,
29 #endif  /* ASN_DISABLE_OER_SUPPORT */
30 #ifdef  ASN_DISABLE_PER_SUPPORT
31         0, 0, 0, 0,
32 #else
33         ANY_decode_uper,
34         ANY_encode_uper,
35         ANY_decode_aper,
36         ANY_encode_aper,
37 #endif  /* ASN_DISABLE_PER_SUPPORT */
38         0,      /* Random fill is not defined for ANY type */
39         0       /* Use generic outmost tag fetcher */
40 };
41 asn_TYPE_descriptor_t asn_DEF_ANY = {
42         "ANY",
43         "ANY",
44         &asn_OP_ANY,
45         0, 0, 0, 0,
46         { 0, 0, asn_generic_no_constraint },    /* No constraints */
47         0, 0,   /* No members */
48         &asn_SPC_ANY_specs,
49 };
50
51 #undef RETURN
52 #define RETURN(_code)                       \
53     do {                                    \
54         asn_dec_rval_t tmprval;             \
55         tmprval.code = _code;               \
56         tmprval.consumed = consumed_myself; \
57         return tmprval;                     \
58     } while(0)
59
60 asn_enc_rval_t
61 ANY_encode_xer(const asn_TYPE_descriptor_t *td, const void *sptr, int ilevel,
62                enum xer_encoder_flags_e flags, asn_app_consume_bytes_f *cb,
63                void *app_key) {
64     if(flags & XER_F_CANONICAL) {
65                 /*
66                  * Canonical XER-encoding of ANY type is not supported.
67                  */
68                 ASN__ENCODE_FAILED;
69         }
70
71         /* Dump as binary */
72         return OCTET_STRING_encode_xer(td, sptr, ilevel, flags, cb, app_key);
73 }
74
75 struct _callback_arg {
76         uint8_t *buffer;
77         size_t offset;
78         size_t size;
79 };
80
81 static int ANY__consume_bytes(const void *buffer, size_t size, void *key);
82
83 int
84 ANY_fromType(ANY_t *st, asn_TYPE_descriptor_t *td, void *sptr) {
85         struct _callback_arg arg;
86         asn_enc_rval_t erval = {0,0,0};
87
88         if(!st || !td) {
89                 errno = EINVAL;
90                 return -1;
91         }
92
93         if(!sptr) {
94                 if(st->buf) FREEMEM(st->buf);
95                 st->size = 0;
96                 return 0;
97         }
98
99         arg.offset = arg.size = 0;
100         arg.buffer = 0;
101
102         erval = der_encode(td, sptr, ANY__consume_bytes, &arg);
103         if(erval.encoded == -1) {
104                 if(arg.buffer) FREEMEM(arg.buffer);
105                 return -1;
106         }
107         assert((size_t)erval.encoded == arg.offset);
108
109         if(st->buf) FREEMEM(st->buf);
110         st->buf = arg.buffer;
111         st->size = arg.offset;
112
113         return 0;
114 }
115
116 int
117 ANY_fromType_aper(ANY_t *st, asn_TYPE_descriptor_t *td, void *sptr) {
118         uint8_t *buffer = NULL;
119         ssize_t erval;
120
121         if(!st || !td) {
122                 errno = EINVAL;
123                 return -1;
124         }
125
126         if(!sptr) {
127                 if(st->buf) FREEMEM(st->buf);
128                 st->size = 0;
129                 return 0;
130         }
131
132         erval = aper_encode_to_new_buffer(td, td->encoding_constraints.per_constraints, sptr, (void**)&buffer);
133
134         if(erval == -1) {
135                 if(buffer) FREEMEM(buffer);
136                 return -1;
137         }
138         assert((size_t)erval > 0);
139
140         if(st->buf) FREEMEM(st->buf);
141         st->buf = buffer;
142         st->size = erval;
143
144         return 0;
145 }
146
147 ANY_t *
148 ANY_new_fromType(asn_TYPE_descriptor_t *td, void *sptr) {
149         ANY_t tmp;
150         ANY_t *st;
151
152         if(!td || !sptr) {
153                 errno = EINVAL;
154                 return 0;
155         }
156
157         memset(&tmp, 0, sizeof(tmp));
158
159         if(ANY_fromType(&tmp, td, sptr)) return 0;
160
161         st = (ANY_t *)CALLOC(1, sizeof(ANY_t));
162         if(st) {
163                 *st = tmp;
164                 return st;
165         } else {
166                 FREEMEM(tmp.buf);
167                 return 0;
168         }
169 }
170
171 ANY_t *
172 ANY_new_fromType_aper(asn_TYPE_descriptor_t *td, void *sptr) {
173         ANY_t tmp;
174         ANY_t *st;
175
176         if(!td || !sptr) {
177                 errno = EINVAL;
178                 return 0;
179         }
180
181         memset(&tmp, 0, sizeof(tmp));
182
183         if(ANY_fromType_aper(&tmp, td, sptr)) return 0;
184
185         st = (ANY_t *)CALLOC(1, sizeof(ANY_t));
186         if(st) {
187                 *st = tmp;
188                 return st;
189         } else {
190                 FREEMEM(tmp.buf);
191                 return 0;
192         }
193 }
194
195 int
196 ANY_to_type(ANY_t *st, asn_TYPE_descriptor_t *td, void **struct_ptr) {
197         asn_dec_rval_t rval;
198         void *newst = 0;
199
200         if(!st || !td || !struct_ptr) {
201                 errno = EINVAL;
202                 return -1;
203         }
204
205         if(st->buf == 0) {
206                 /* Nothing to convert, make it empty. */
207                 *struct_ptr = (void *)0;
208                 return 0;
209         }
210
211         rval = ber_decode(0, td, (void **)&newst, st->buf, st->size);
212         if(rval.code == RC_OK) {
213                 *struct_ptr = newst;
214                 return 0;
215         } else {
216                 /* Remove possibly partially decoded data. */
217                 ASN_STRUCT_FREE(*td, newst);
218                 return -1;
219         }
220 }
221
222 int
223 ANY_to_type_aper(ANY_t *st, asn_TYPE_descriptor_t *td, void **struct_ptr) {
224         asn_dec_rval_t rval;
225         void *newst = 0;
226
227         if(!st || !td || !struct_ptr) {
228                 errno = EINVAL;
229                 return -1;
230         }
231
232         if(st->buf == 0) {
233                 /* Nothing to convert, make it empty. */
234                 *struct_ptr = (void *)0;
235                 return 0;
236         }
237
238         rval = aper_decode(0, td, (void **)&newst, st->buf, st->size, 0, 0);
239         if(rval.code == RC_OK) {
240                 *struct_ptr = newst;
241                 return 0;
242         } else {
243                 /* Remove possibly partially decoded data. */
244                 ASN_STRUCT_FREE(*td, newst);
245                 return -1;
246         }
247 }
248
249 static int ANY__consume_bytes(const void *buffer, size_t size, void *key) {
250         struct _callback_arg *arg = (struct _callback_arg *)key;
251
252         if((arg->offset + size) >= arg->size) {
253                 size_t nsize = (arg->size ? arg->size << 2 : 16) + size;
254                 void *p = REALLOC(arg->buffer, nsize);
255                 if(!p) return -1;
256                 arg->buffer = (uint8_t *)p;
257                 arg->size = nsize;
258         }
259
260         memcpy(arg->buffer + arg->offset, buffer, size);
261         arg->offset += size;
262         assert(arg->offset < arg->size);
263
264         return 0;
265 }
266
267 #ifndef ASN_DISABLE_PER_SUPPORT
268
269 asn_dec_rval_t
270 ANY_decode_uper(const asn_codec_ctx_t *opt_codec_ctx,
271                 const asn_TYPE_descriptor_t *td,
272                 const asn_per_constraints_t *constraints, void **sptr,
273                 asn_per_data_t *pd) {
274     const asn_OCTET_STRING_specifics_t *specs =
275         td->specifics ? (const asn_OCTET_STRING_specifics_t *)td->specifics
276                       : &asn_SPC_ANY_specs;
277     size_t consumed_myself = 0;
278     int repeat;
279     ANY_t *st = (ANY_t *)*sptr;
280
281     (void)opt_codec_ctx;
282     (void)constraints;
283
284     /*
285      * Allocate the structure.
286      */
287     if(!st) {
288         st = (ANY_t *)(*sptr = CALLOC(1, specs->struct_size));
289         if(!st) RETURN(RC_FAIL);
290     }
291
292     ASN_DEBUG("UPER Decoding ANY type");
293
294     st->size = 0;
295     do {
296         ssize_t raw_len;
297         ssize_t len_bytes;
298         ssize_t len_bits;
299         void *p;
300         int ret;
301
302         /* Get the PER length */
303         raw_len = uper_get_length(pd, -1, 0, &repeat);
304         if(raw_len < 0) RETURN(RC_WMORE);
305         if(raw_len == 0 && st->buf) break;
306
307         ASN_DEBUG("Got PER length len %" ASN_PRI_SIZE ", %s (%s)", raw_len,
308                   repeat ? "repeat" : "once", td->name);
309         len_bytes = raw_len;
310         len_bits = len_bytes * 8;
311
312         p = REALLOC(st->buf, st->size + len_bytes + 1);
313         if(!p) RETURN(RC_FAIL);
314         st->buf = (uint8_t *)p;
315
316         ret = per_get_many_bits(pd, &st->buf[st->size], 0, len_bits);
317         if(ret < 0) RETURN(RC_WMORE);
318         consumed_myself += len_bits;
319         st->size += len_bytes;
320     } while(repeat);
321     st->buf[st->size] = 0; /* nul-terminate */
322
323     RETURN(RC_OK);
324 }
325
326 asn_enc_rval_t
327 ANY_encode_uper(const asn_TYPE_descriptor_t *td,
328                 const asn_per_constraints_t *constraints, const void *sptr,
329                 asn_per_outp_t *po) {
330     const ANY_t *st = (const ANY_t *)sptr;
331     asn_enc_rval_t er = {0, 0, 0};
332     const uint8_t *buf;
333     size_t size;
334     int ret;
335
336     (void)constraints;
337
338     if(!st || (!st->buf && st->size)) ASN__ENCODE_FAILED;
339
340     buf = st->buf;
341     size = st->size;
342     do {
343         int need_eom = 0;
344         ssize_t may_save = uper_put_length(po, size, &need_eom);
345         if(may_save < 0) ASN__ENCODE_FAILED;
346
347         ret = per_put_many_bits(po, buf, may_save * 8);
348         if(ret) ASN__ENCODE_FAILED;
349
350         buf += may_save;
351         size -= may_save;
352         assert(!(may_save & 0x07) || !size);
353         if(need_eom && uper_put_length(po, 0, 0))
354             ASN__ENCODE_FAILED; /* End of Message length */
355     } while(size);
356
357     ASN__ENCODED_OK(er);
358 }
359
360 asn_dec_rval_t
361 ANY_decode_aper(const asn_codec_ctx_t *opt_codec_ctx,
362                 const asn_TYPE_descriptor_t *td,
363                 const asn_per_constraints_t *constraints, void **sptr,
364                 asn_per_data_t *pd) {
365     const asn_OCTET_STRING_specifics_t *specs =
366         td->specifics ? (const asn_OCTET_STRING_specifics_t *)td->specifics
367                       : &asn_SPC_ANY_specs;
368     size_t consumed_myself = 0;
369     int repeat;
370     ANY_t *st = (ANY_t *)*sptr;
371
372     (void)opt_codec_ctx;
373     (void)constraints;
374
375     /*
376      * Allocate the structure.
377      */
378     if(!st) {
379         st = (ANY_t *)(*sptr = CALLOC(1, specs->struct_size));
380         if(!st) RETURN(RC_FAIL);
381     }
382
383     ASN_DEBUG("APER Decoding ANY type");
384
385     st->size = 0;
386     do {
387         ssize_t raw_len;
388         ssize_t len_bytes;
389         ssize_t len_bits;
390         void *p;
391         int ret;
392
393         /* Get the PER length */
394         raw_len = aper_get_length(pd, -1, 0, &repeat);
395         if(raw_len < 0) RETURN(RC_WMORE);
396         if(raw_len == 0 && st->buf) break;
397
398         ASN_DEBUG("Got PER length len %" ASN_PRI_SIZE ", %s (%s)", raw_len,
399                   repeat ? "repeat" : "once", td->name);
400         len_bytes = raw_len;
401         len_bits = len_bytes * 8;
402
403         p = REALLOC(st->buf, st->size + len_bytes + 1);
404         if(!p) RETURN(RC_FAIL);
405         st->buf = (uint8_t *)p;
406
407         ret = per_get_many_bits(pd, &st->buf[st->size], 0, len_bits);
408         if(ret < 0) RETURN(RC_WMORE);
409         consumed_myself += len_bits;
410         st->size += len_bytes;
411     } while(repeat);
412     st->buf[st->size] = 0; /* nul-terminate */
413
414     RETURN(RC_OK);
415 }
416
417 asn_enc_rval_t
418 ANY_encode_aper(const asn_TYPE_descriptor_t *td,
419                 const asn_per_constraints_t *constraints, const void *sptr,
420                 asn_per_outp_t *po) {
421     const ANY_t *st = (const ANY_t *)sptr;
422     asn_enc_rval_t er = {0, 0, 0};
423     const uint8_t *buf;
424     size_t size;
425     int ret;
426
427     (void)constraints;
428
429     if(!st || (!st->buf && st->size)) ASN__ENCODE_FAILED;
430
431     buf = st->buf;
432     size = st->size;
433     do {
434         int need_eom = 0;
435         ssize_t may_save = uper_put_length(po, size, &need_eom);
436         if(may_save < 0) ASN__ENCODE_FAILED;
437
438         ret = per_put_many_bits(po, buf, may_save * 8);
439         if(ret) ASN__ENCODE_FAILED;
440
441         buf += may_save;
442         size -= may_save;
443         assert(!(may_save & 0x07) || !size);
444         if(need_eom && uper_put_length(po, 0, 0))
445             ASN__ENCODE_FAILED; /* End of Message length */
446     } while(size);
447
448     ASN__ENCODED_OK(er);
449 }
450 #endif /* ASN_DISABLE_PER_SUPPORT */
451