Adding initial code jy.oak@samsung.com
[ric-app/kpimon.git] / asn1c_defs / all-defs / NativeEnumerated.c
1 /*-\r
2  * Copyright (c) 2004, 2007 Lev Walkin <vlm@lionet.info>. All rights reserved.\r
3  * Redistribution and modifications are permitted subject to BSD license.\r
4  */\r
5 /*\r
6  * Read the NativeInteger.h for the explanation wrt. differences between\r
7  * INTEGER and NativeInteger.\r
8  * Basically, both are decoders and encoders of ASN.1 INTEGER type, but this\r
9  * implementation deals with the standard (machine-specific) representation\r
10  * of them instead of using the platform-independent buffer.\r
11  */\r
12 #include <asn_internal.h>\r
13 #include <NativeEnumerated.h>\r
14 \r
15 /*\r
16  * NativeEnumerated basic type description.\r
17  */\r
18 static const ber_tlv_tag_t asn_DEF_NativeEnumerated_tags[] = {\r
19         (ASN_TAG_CLASS_UNIVERSAL | (10 << 2))\r
20 };\r
21 asn_TYPE_operation_t asn_OP_NativeEnumerated = {\r
22         NativeInteger_free,\r
23         NativeInteger_print,\r
24         NativeInteger_compare,\r
25         NativeInteger_decode_ber,\r
26         NativeInteger_encode_der,\r
27         NativeInteger_decode_xer,\r
28         NativeEnumerated_encode_xer,\r
29 #ifdef  ASN_DISABLE_OER_SUPPORT\r
30         0,\r
31         0,\r
32 #else\r
33         NativeEnumerated_decode_oer,\r
34         NativeEnumerated_encode_oer,\r
35 #endif  /* ASN_DISABLE_OER_SUPPORT */\r
36 #ifdef  ASN_DISABLE_PER_SUPPORT\r
37         0,\r
38         0,\r
39         0,\r
40         0,\r
41 #else\r
42         NativeEnumerated_decode_uper,\r
43         NativeEnumerated_encode_uper,\r
44         NativeEnumerated_decode_aper,\r
45         NativeEnumerated_encode_aper,\r
46 #endif  /* ASN_DISABLE_PER_SUPPORT */\r
47         NativeEnumerated_random_fill,\r
48         0       /* Use generic outmost tag fetcher */\r
49 };\r
50 asn_TYPE_descriptor_t asn_DEF_NativeEnumerated = {\r
51         "ENUMERATED",                   /* The ASN.1 type is still ENUMERATED */\r
52         "ENUMERATED",\r
53         &asn_OP_NativeEnumerated,\r
54         asn_DEF_NativeEnumerated_tags,\r
55         sizeof(asn_DEF_NativeEnumerated_tags) / sizeof(asn_DEF_NativeEnumerated_tags[0]),\r
56         asn_DEF_NativeEnumerated_tags,  /* Same as above */\r
57         sizeof(asn_DEF_NativeEnumerated_tags) / sizeof(asn_DEF_NativeEnumerated_tags[0]),\r
58         { 0, 0, asn_generic_no_constraint },\r
59         0, 0,   /* No members */\r
60         0       /* No specifics */\r
61 };\r
62 \r
63 asn_enc_rval_t\r
64 NativeEnumerated_encode_xer(const asn_TYPE_descriptor_t *td, const void *sptr,\r
65                             int ilevel, enum xer_encoder_flags_e flags,\r
66                             asn_app_consume_bytes_f *cb, void *app_key) {\r
67     const asn_INTEGER_specifics_t *specs =\r
68         (const asn_INTEGER_specifics_t *)td->specifics;\r
69     asn_enc_rval_t er = {0,0,0};\r
70     const long *native = (const long *)sptr;\r
71     const asn_INTEGER_enum_map_t *el;\r
72 \r
73     (void)ilevel;\r
74     (void)flags;\r
75 \r
76     if(!native) ASN__ENCODE_FAILED;\r
77 \r
78     el = INTEGER_map_value2enum(specs, *native);\r
79     if(el) {\r
80         er.encoded =\r
81             asn__format_to_callback(cb, app_key, "<%s/>", el->enum_name);\r
82         if(er.encoded < 0) ASN__ENCODE_FAILED;\r
83         ASN__ENCODED_OK(er);\r
84     } else {\r
85         ASN_DEBUG(\r
86             "ASN.1 forbids dealing with "\r
87             "unknown value of ENUMERATED type");\r
88         ASN__ENCODE_FAILED;\r
89     }\r
90 }\r
91 \r
92 asn_dec_rval_t\r
93 NativeEnumerated_decode_uper(const asn_codec_ctx_t *opt_codec_ctx,\r
94                              const asn_TYPE_descriptor_t *td,\r
95                              const asn_per_constraints_t *constraints,\r
96                              void **sptr, asn_per_data_t *pd) {\r
97     const asn_INTEGER_specifics_t *specs = td->specifics;\r
98     asn_dec_rval_t rval = { RC_OK, 0 };\r
99         long *native = (long *)*sptr;\r
100         const asn_per_constraint_t *ct;\r
101         long value;\r
102 \r
103         (void)opt_codec_ctx;\r
104 \r
105         if(constraints) ct = &constraints->value;\r
106         else if(td->encoding_constraints.per_constraints)\r
107                 ct = &td->encoding_constraints.per_constraints->value;\r
108         else ASN__DECODE_FAILED;        /* Mandatory! */\r
109         if(!specs) ASN__DECODE_FAILED;\r
110 \r
111         if(!native) {\r
112                 native = (long *)(*sptr = CALLOC(1, sizeof(*native)));\r
113                 if(!native) ASN__DECODE_FAILED;\r
114         }\r
115 \r
116         ASN_DEBUG("Decoding %s as NativeEnumerated", td->name);\r
117 \r
118         if(ct->flags & APC_EXTENSIBLE) {\r
119                 int inext = per_get_few_bits(pd, 1);\r
120                 if(inext < 0) ASN__DECODE_STARVED;\r
121                 if(inext) ct = 0;\r
122         }\r
123 \r
124         if(ct && ct->range_bits >= 0) {\r
125                 value = per_get_few_bits(pd, ct->range_bits);\r
126                 if(value < 0) ASN__DECODE_STARVED;\r
127                 if(value >= (specs->extension\r
128                         ? specs->extension - 1 : specs->map_count))\r
129                         ASN__DECODE_FAILED;\r
130         } else {\r
131                 if(!specs->extension)\r
132                         ASN__DECODE_FAILED;\r
133                 /*\r
134                  * X.691, #10.6: normally small non-negative whole number;\r
135                  */\r
136                 value = uper_get_nsnnwn(pd);\r
137                 if(value < 0) ASN__DECODE_STARVED;\r
138                 value += specs->extension - 1;\r
139                 if(value >= specs->map_count)\r
140                         ASN__DECODE_FAILED;\r
141         }\r
142 \r
143         *native = specs->value2enum[value].nat_value;\r
144         ASN_DEBUG("Decoded %s = %ld", td->name, *native);\r
145 \r
146         return rval;\r
147 }\r
148 \r
149 static int\r
150 NativeEnumerated__compar_value2enum(const void *ap, const void *bp) {\r
151         const asn_INTEGER_enum_map_t *a = ap;\r
152         const asn_INTEGER_enum_map_t *b = bp;\r
153         if(a->nat_value == b->nat_value)\r
154                 return 0;\r
155         if(a->nat_value < b->nat_value)\r
156                 return -1;\r
157         return 1;\r
158 }\r
159 \r
160 asn_enc_rval_t\r
161 NativeEnumerated_encode_uper(const asn_TYPE_descriptor_t *td,\r
162                              const asn_per_constraints_t *constraints,\r
163                              const void *sptr, asn_per_outp_t *po) {\r
164         const asn_INTEGER_specifics_t *specs =\r
165         (const asn_INTEGER_specifics_t *)td->specifics;\r
166         asn_enc_rval_t er = {0,0,0};\r
167         long native, value;\r
168         const asn_per_constraint_t *ct;\r
169         int inext = 0;\r
170         asn_INTEGER_enum_map_t key;\r
171         const asn_INTEGER_enum_map_t *kf;\r
172 \r
173         if(!sptr) ASN__ENCODE_FAILED;\r
174         if(!specs) ASN__ENCODE_FAILED;\r
175 \r
176         if(constraints) ct = &constraints->value;\r
177         else if(td->encoding_constraints.per_constraints)\r
178                 ct = &td->encoding_constraints.per_constraints->value;\r
179         else ASN__ENCODE_FAILED;        /* Mandatory! */\r
180 \r
181         ASN_DEBUG("Encoding %s as NativeEnumerated", td->name);\r
182 \r
183         er.encoded = 0;\r
184 \r
185         native = *(const long *)sptr;\r
186 \r
187         key.nat_value = native;\r
188         kf = bsearch(&key, specs->value2enum, specs->map_count,\r
189                 sizeof(key), NativeEnumerated__compar_value2enum);\r
190         if(!kf) {\r
191                 ASN_DEBUG("No element corresponds to %ld", native);\r
192                 ASN__ENCODE_FAILED;\r
193         }\r
194         value = kf - specs->value2enum;\r
195 \r
196         if(ct->range_bits >= 0) {\r
197                 int cmpWith = specs->extension\r
198                                 ? specs->extension - 1 : specs->map_count;\r
199                 if(value >= cmpWith)\r
200                         inext = 1;\r
201         }\r
202         if(ct->flags & APC_EXTENSIBLE) {\r
203                 if(per_put_few_bits(po, inext, 1))\r
204                         ASN__ENCODE_FAILED;\r
205                 if(inext) ct = 0;\r
206         } else if(inext) {\r
207                 ASN__ENCODE_FAILED;\r
208         }\r
209 \r
210         if(ct && ct->range_bits >= 0) {\r
211                 if(per_put_few_bits(po, value, ct->range_bits))\r
212                         ASN__ENCODE_FAILED;\r
213                 ASN__ENCODED_OK(er);\r
214         }\r
215 \r
216         if(!specs->extension)\r
217                 ASN__ENCODE_FAILED;\r
218 \r
219         /*\r
220          * X.691, #10.6: normally small non-negative whole number;\r
221          */\r
222         ASN_DEBUG("value = %ld, ext = %d, inext = %d, res = %ld",\r
223                 value, specs->extension, inext,\r
224                 value - (inext ? (specs->extension - 1) : 0));\r
225         if(uper_put_nsnnwn(po, value - (inext ? (specs->extension - 1) : 0)))\r
226                 ASN__ENCODE_FAILED;\r
227 \r
228         ASN__ENCODED_OK(er);\r
229 }\r
230 \r
231 asn_dec_rval_t\r
232 NativeEnumerated_decode_aper(const asn_codec_ctx_t *opt_codec_ctx,\r
233                              const asn_TYPE_descriptor_t *td,\r
234                              const asn_per_constraints_t *constraints,\r
235                              void **sptr, asn_per_data_t *pd) {\r
236         const asn_INTEGER_specifics_t *specs = (const asn_INTEGER_specifics_t *)td->specifics;\r
237         asn_dec_rval_t rval = { RC_OK, 0 };\r
238         long *native = (long *)*sptr;\r
239         const asn_per_constraint_t *ct;\r
240         long value;\r
241 \r
242         (void)opt_codec_ctx;\r
243 \r
244         if(constraints) ct = &constraints->value;\r
245         else if(td->encoding_constraints.per_constraints)\r
246                 ct = &td->encoding_constraints.per_constraints->value;\r
247         else ASN__DECODE_FAILED;        /* Mandatory! */\r
248         if(!specs) ASN__DECODE_FAILED;\r
249 \r
250         if(!native) {\r
251                 native = (long *)(*sptr = CALLOC(1, sizeof(*native)));\r
252                 if(!native) ASN__DECODE_FAILED;\r
253         }\r
254 \r
255         ASN_DEBUG("Decoding %s as NativeEnumerated", td->name);\r
256 \r
257         if(ct->flags & APC_EXTENSIBLE) {\r
258                 int inext = per_get_few_bits(pd, 1);\r
259                 if(inext < 0) ASN__DECODE_STARVED;\r
260                 if(inext) ct = 0;\r
261         }\r
262 \r
263         /* Deal with APER padding */\r
264         if(ct && ct->upper_bound >= 255) {\r
265                 int padding = 0;\r
266                 padding = (8 - (pd->moved % 8)) % 8;\r
267                 ASN_DEBUG("For NativeEnumerated %s,offset= %lu Padding bits = %d", td->name, pd->moved, padding);\r
268                 ASN_DEBUG("For NativeEnumerated %s, upper bound = %lu", td->name, ct->upper_bound);\r
269                 if(padding > 0)\r
270                         per_get_few_bits(pd, padding);\r
271         }\r
272 \r
273         if(ct && ct->range_bits >= 0) {\r
274                 value = per_get_few_bits(pd, ct->range_bits);\r
275                 if(value < 0) ASN__DECODE_STARVED;\r
276                 if(value >= (specs->extension\r
277                              ? specs->extension - 1 : specs->map_count))\r
278                         ASN__DECODE_FAILED;\r
279         } else {\r
280                 if(!specs->extension)\r
281                         ASN__DECODE_FAILED;\r
282                 /*\r
283                  * X.691, #10.6: normally small non-negative whole number;\r
284                  */\r
285                 value = uper_get_nsnnwn(pd);\r
286                 if(value < 0) ASN__DECODE_STARVED;\r
287                 value += specs->extension - 1;\r
288                 if(value >= specs->map_count)\r
289                         ASN__DECODE_FAILED;\r
290         }\r
291 \r
292         *native = specs->value2enum[value].nat_value;\r
293         ASN_DEBUG("Decoded %s = %ld", td->name, *native);\r
294 \r
295         return rval;\r
296 }\r
297 \r
298 asn_enc_rval_t\r
299 NativeEnumerated_encode_aper(const asn_TYPE_descriptor_t *td,\r
300                              const asn_per_constraints_t *constraints,\r
301                              const void *sptr, asn_per_outp_t *po) {\r
302         const asn_INTEGER_specifics_t *specs = (const asn_INTEGER_specifics_t *)td->specifics;\r
303         asn_enc_rval_t er = {0,0,0};\r
304         long native, value;\r
305         const asn_per_constraint_t *ct;\r
306         int inext = 0;\r
307         asn_INTEGER_enum_map_t key;\r
308         asn_INTEGER_enum_map_t *kf;\r
309 \r
310         if(!sptr) ASN__ENCODE_FAILED;\r
311         if(!specs) ASN__ENCODE_FAILED;\r
312 \r
313         if(constraints) ct = &constraints->value;\r
314         else if(td->encoding_constraints.per_constraints)\r
315                 ct = &td->encoding_constraints.per_constraints->value;\r
316         else ASN__ENCODE_FAILED;        /* Mandatory! */\r
317 \r
318         ASN_DEBUG("Encoding %s as NativeEnumerated", td->name);\r
319 \r
320         er.encoded = 0;\r
321 \r
322         native = *(const long *)sptr;\r
323         if(native < 0) ASN__ENCODE_FAILED;\r
324 \r
325         key.nat_value = native;\r
326         kf = bsearch(&key, specs->value2enum, specs->map_count,\r
327                      sizeof(key), NativeEnumerated__compar_value2enum);\r
328         if(!kf) {\r
329                 ASN_DEBUG("No element corresponds to %ld", native);\r
330                 ASN__ENCODE_FAILED;\r
331         }\r
332         value = kf - specs->value2enum;\r
333 \r
334         if(ct->range_bits >= 0) {\r
335                 int cmpWith = specs->extension\r
336                               ? specs->extension - 1 : specs->map_count;\r
337                 if(value >= cmpWith)\r
338                         inext = 1;\r
339         }\r
340         if(ct->flags & APC_EXTENSIBLE) {\r
341                 if(per_put_few_bits(po, inext, 1))\r
342                         ASN__ENCODE_FAILED;\r
343                 if(inext) ct = 0;\r
344         } else if(inext) {\r
345                 ASN__ENCODE_FAILED;\r
346         }\r
347 \r
348         if(ct && ct->range_bits >= 0) {\r
349                 if(per_put_few_bits(po, value, ct->range_bits))\r
350                         ASN__ENCODE_FAILED;\r
351                 ASN__ENCODED_OK(er);\r
352         }\r
353 \r
354         if(!specs->extension)\r
355                 ASN__ENCODE_FAILED;\r
356 \r
357         /*\r
358          * X.691, #10.6: normally small non-negative whole number;\r
359          */\r
360         ASN_DEBUG("value = %ld, ext = %d, inext = %d, res = %ld",\r
361                   value, specs->extension, inext,\r
362                   value - (inext ? (specs->extension - 1) : 0));\r
363         if(uper_put_nsnnwn(po, value - (inext ? (specs->extension - 1) : 0)))\r
364                 ASN__ENCODE_FAILED;\r
365 \r
366         ASN__ENCODED_OK(er);\r
367 }\r