Updated INFO.yaml file
[ric-app/kpimon.git] / asn1c_defs / all-defs / asn_codecs_prim.c
1 /*-\r
2  * Copyright (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.\r
3  * Redistribution and modifications are permitted subject to BSD license.\r
4  */\r
5 #include <asn_internal.h>\r
6 #include <asn_codecs_prim.h>\r
7 #include <errno.h>\r
8 \r
9 /*\r
10  * Decode an always-primitive type.\r
11  */\r
12 asn_dec_rval_t\r
13 ber_decode_primitive(const asn_codec_ctx_t *opt_codec_ctx,\r
14                      const asn_TYPE_descriptor_t *td, void **sptr,\r
15                      const void *buf_ptr, size_t size, int tag_mode) {\r
16     ASN__PRIMITIVE_TYPE_t *st = (ASN__PRIMITIVE_TYPE_t *)*sptr;\r
17         asn_dec_rval_t rval;\r
18         ber_tlv_len_t length = 0; /* =0 to avoid [incorrect] warning. */\r
19 \r
20         /*\r
21          * If the structure is not there, allocate it.\r
22          */\r
23         if(st == NULL) {\r
24                 st = (ASN__PRIMITIVE_TYPE_t *)CALLOC(1, sizeof(*st));\r
25                 if(st == NULL) ASN__DECODE_FAILED;\r
26                 *sptr = (void *)st;\r
27         }\r
28 \r
29         ASN_DEBUG("Decoding %s as plain primitive (tm=%d)",\r
30                 td->name, tag_mode);\r
31 \r
32         /*\r
33          * Check tags and extract value length.\r
34          */\r
35         rval = ber_check_tags(opt_codec_ctx, td, 0, buf_ptr, size,\r
36                         tag_mode, 0, &length, 0);\r
37         if(rval.code != RC_OK)\r
38                 return rval;\r
39 \r
40         ASN_DEBUG("%s length is %d bytes", td->name, (int)length);\r
41 \r
42         /*\r
43          * Make sure we have this length.\r
44          */\r
45         buf_ptr = ((const char *)buf_ptr) + rval.consumed;\r
46         size -= rval.consumed;\r
47         if(length > (ber_tlv_len_t)size) {\r
48                 rval.code = RC_WMORE;\r
49                 rval.consumed = 0;\r
50                 return rval;\r
51         }\r
52 \r
53         st->size = (int)length;\r
54         /* The following better be optimized away. */\r
55         if(sizeof(st->size) != sizeof(length)\r
56                         && (ber_tlv_len_t)st->size != length) {\r
57                 st->size = 0;\r
58                 ASN__DECODE_FAILED;\r
59         }\r
60 \r
61         st->buf = (uint8_t *)MALLOC(length + 1);\r
62         if(!st->buf) {\r
63                 st->size = 0;\r
64                 ASN__DECODE_FAILED;\r
65         }\r
66 \r
67         memcpy(st->buf, buf_ptr, length);\r
68         st->buf[length] = '\0';         /* Just in case */\r
69 \r
70         rval.code = RC_OK;\r
71         rval.consumed += length;\r
72 \r
73         ASN_DEBUG("Took %ld/%ld bytes to encode %s",\r
74                 (long)rval.consumed,\r
75                 (long)length, td->name);\r
76 \r
77         return rval;\r
78 }\r
79 \r
80 /*\r
81  * Encode an always-primitive type using DER.\r
82  */\r
83 asn_enc_rval_t\r
84 der_encode_primitive(const asn_TYPE_descriptor_t *td, const void *sptr,\r
85                      int tag_mode, ber_tlv_tag_t tag,\r
86                      asn_app_consume_bytes_f *cb, void *app_key) {\r
87         asn_enc_rval_t erval = {0,0,0};\r
88         const ASN__PRIMITIVE_TYPE_t *st = (const ASN__PRIMITIVE_TYPE_t *)sptr;\r
89 \r
90         ASN_DEBUG("%s %s as a primitive type (tm=%d)",\r
91                 cb?"Encoding":"Estimating", td->name, tag_mode);\r
92 \r
93         erval.encoded = der_write_tags(td, st->size, tag_mode, 0, tag,\r
94                 cb, app_key);\r
95         ASN_DEBUG("%s wrote tags %d", td->name, (int)erval.encoded);\r
96         if(erval.encoded == -1) {\r
97                 erval.failed_type = td;\r
98                 erval.structure_ptr = sptr;\r
99                 return erval;\r
100         }\r
101 \r
102         if(cb && st->buf) {\r
103                 if(cb(st->buf, st->size, app_key) < 0) {\r
104                         erval.encoded = -1;\r
105                         erval.failed_type = td;\r
106                         erval.structure_ptr = sptr;\r
107                         return erval;\r
108                 }\r
109         } else {\r
110                 assert(st->buf || st->size == 0);\r
111         }\r
112 \r
113         erval.encoded += st->size;\r
114         ASN__ENCODED_OK(erval);\r
115 }\r
116 \r
117 void\r
118 ASN__PRIMITIVE_TYPE_free(const asn_TYPE_descriptor_t *td, void *sptr,\r
119                          enum asn_struct_free_method method) {\r
120     ASN__PRIMITIVE_TYPE_t *st = (ASN__PRIMITIVE_TYPE_t *)sptr;\r
121 \r
122         if(!td || !sptr)\r
123                 return;\r
124 \r
125         ASN_DEBUG("Freeing %s as a primitive type", td->name);\r
126 \r
127         if(st->buf)\r
128                 FREEMEM(st->buf);\r
129 \r
130     switch(method) {\r
131     case ASFM_FREE_EVERYTHING:\r
132         FREEMEM(sptr);\r
133         break;\r
134     case ASFM_FREE_UNDERLYING:\r
135         break;\r
136     case ASFM_FREE_UNDERLYING_AND_RESET:\r
137         memset(sptr, 0, sizeof(ASN__PRIMITIVE_TYPE_t));\r
138         break;\r
139     }\r
140 }\r
141 \r
142 \r
143 /*\r
144  * Local internal type passed around as an argument.\r
145  */\r
146 struct xdp_arg_s {\r
147     const asn_TYPE_descriptor_t *type_descriptor;\r
148     void *struct_key;\r
149         xer_primitive_body_decoder_f *prim_body_decoder;\r
150         int decoded_something;\r
151         int want_more;\r
152 };\r
153 \r
154 /*\r
155  * Since some kinds of primitive values can be encoded using value-specific\r
156  * tags (<MINUS-INFINITY>, <enum-element>, etc), the primitive decoder must\r
157  * be supplied with such tags to parse them as needed.\r
158  */\r
159 static int\r
160 xer_decode__unexpected_tag(void *key, const void *chunk_buf, size_t chunk_size) {\r
161         struct xdp_arg_s *arg = (struct xdp_arg_s *)key;\r
162         enum xer_pbd_rval bret;\r
163 \r
164         /*\r
165          * The chunk_buf is guaranteed to start at '<'.\r
166          */\r
167         assert(chunk_size && ((const char *)chunk_buf)[0] == 0x3c);\r
168 \r
169         /*\r
170          * Decoding was performed once already. Prohibit doing it again.\r
171          */\r
172         if(arg->decoded_something)\r
173                 return -1;\r
174 \r
175         bret = arg->prim_body_decoder(arg->type_descriptor,\r
176                 arg->struct_key, chunk_buf, chunk_size);\r
177         switch(bret) {\r
178         case XPBD_SYSTEM_FAILURE:\r
179         case XPBD_DECODER_LIMIT:\r
180         case XPBD_BROKEN_ENCODING:\r
181                 break;\r
182         case XPBD_BODY_CONSUMED:\r
183                 /* Tag decoded successfully */\r
184                 arg->decoded_something = 1;\r
185                 /* Fall through */\r
186         case XPBD_NOT_BODY_IGNORE:      /* Safe to proceed further */\r
187                 return 0;\r
188         }\r
189 \r
190         return -1;\r
191 }\r
192 \r
193 static ssize_t\r
194 xer_decode__primitive_body(void *key, const void *chunk_buf, size_t chunk_size, int have_more) {\r
195         struct xdp_arg_s *arg = (struct xdp_arg_s *)key;\r
196         enum xer_pbd_rval bret;\r
197         size_t lead_wsp_size;\r
198 \r
199         if(arg->decoded_something) {\r
200                 if(xer_whitespace_span(chunk_buf, chunk_size) == chunk_size) {\r
201                         /*\r
202                          * Example:\r
203                          * "<INTEGER>123<!--/--> </INTEGER>"\r
204                          *                      ^- chunk_buf position.\r
205                          */\r
206                         return chunk_size;\r
207                 }\r
208                 /*\r
209                  * Decoding was done once already. Prohibit doing it again.\r
210                  */\r
211                 return -1;\r
212         }\r
213 \r
214         if(!have_more) {\r
215                 /*\r
216                  * If we've received something like "1", we can't really\r
217                  * tell whether it is really `1` or `123`, until we know\r
218                  * that there is no more data coming.\r
219                  * The have_more argument will be set to 1 once something\r
220                  * like this is available to the caller of this callback:\r
221                  * "1<tag_start..."\r
222                  */\r
223                 arg->want_more = 1;\r
224                 return -1;\r
225         }\r
226 \r
227         lead_wsp_size = xer_whitespace_span(chunk_buf, chunk_size);\r
228         chunk_buf = (const char *)chunk_buf + lead_wsp_size;\r
229         chunk_size -= lead_wsp_size;\r
230 \r
231         bret = arg->prim_body_decoder(arg->type_descriptor,\r
232                 arg->struct_key, chunk_buf, chunk_size);\r
233         switch(bret) {\r
234         case XPBD_SYSTEM_FAILURE:\r
235         case XPBD_DECODER_LIMIT:\r
236         case XPBD_BROKEN_ENCODING:\r
237                 break;\r
238         case XPBD_BODY_CONSUMED:\r
239                 /* Tag decoded successfully */\r
240                 arg->decoded_something = 1;\r
241                 /* Fall through */\r
242         case XPBD_NOT_BODY_IGNORE:      /* Safe to proceed further */\r
243                 return lead_wsp_size + chunk_size;\r
244         }\r
245 \r
246         return -1;\r
247 }\r
248 \r
249 \r
250 asn_dec_rval_t\r
251 xer_decode_primitive(const asn_codec_ctx_t *opt_codec_ctx,\r
252                      const asn_TYPE_descriptor_t *td, void **sptr,\r
253                      size_t struct_size, const char *opt_mname,\r
254                      const void *buf_ptr, size_t size,\r
255                      xer_primitive_body_decoder_f *prim_body_decoder) {\r
256     const char *xml_tag = opt_mname ? opt_mname : td->xml_tag;\r
257         asn_struct_ctx_t s_ctx;\r
258         struct xdp_arg_s s_arg;\r
259         asn_dec_rval_t rc;\r
260 \r
261         /*\r
262          * Create the structure if does not exist.\r
263          */\r
264         if(!*sptr) {\r
265                 *sptr = CALLOC(1, struct_size);\r
266                 if(!*sptr) ASN__DECODE_FAILED;\r
267         }\r
268 \r
269         memset(&s_ctx, 0, sizeof(s_ctx));\r
270         s_arg.type_descriptor = td;\r
271         s_arg.struct_key = *sptr;\r
272         s_arg.prim_body_decoder = prim_body_decoder;\r
273         s_arg.decoded_something = 0;\r
274         s_arg.want_more = 0;\r
275 \r
276         rc = xer_decode_general(opt_codec_ctx, &s_ctx, &s_arg,\r
277                 xml_tag, buf_ptr, size,\r
278                 xer_decode__unexpected_tag, xer_decode__primitive_body);\r
279         switch(rc.code) {\r
280         case RC_OK:\r
281                 if(!s_arg.decoded_something) {\r
282                         char ch;\r
283                         ASN_DEBUG("Primitive body is not recognized, "\r
284                                 "supplying empty one");\r
285                         /*\r
286                          * Decoding opportunity has come and gone.\r
287                          * Where's the result?\r
288                          * Try to feed with empty body, see if it eats it.\r
289                          */\r
290                         if(prim_body_decoder(s_arg.type_descriptor,\r
291                                 s_arg.struct_key, &ch, 0)\r
292                                         != XPBD_BODY_CONSUMED) {\r
293                                 /*\r
294                                  * This decoder does not like empty stuff.\r
295                                  */\r
296                                 ASN__DECODE_FAILED;\r
297                         }\r
298                 }\r
299                 break;\r
300         case RC_WMORE:\r
301                 /*\r
302                  * Redo the whole thing later.\r
303                  * We don't have a context to save intermediate parsing state.\r
304                  */\r
305                 rc.consumed = 0;\r
306                 break;\r
307         case RC_FAIL:\r
308                 rc.consumed = 0;\r
309                 if(s_arg.want_more)\r
310                         rc.code = RC_WMORE;\r
311                 else\r
312                         ASN__DECODE_FAILED;\r
313                 break;\r
314         }\r
315         return rc;\r
316 }\r
317 \r