Adding initial code jy.oak@samsung.com
[ric-app/kpimon.git] / asn1c_defs / all-defs / asn_codecs_prim.c
diff --git a/asn1c_defs/all-defs/asn_codecs_prim.c b/asn1c_defs/all-defs/asn_codecs_prim.c
new file mode 100755 (executable)
index 0000000..37affd4
--- /dev/null
@@ -0,0 +1,317 @@
+/*-\r
+ * Copyright (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.\r
+ * Redistribution and modifications are permitted subject to BSD license.\r
+ */\r
+#include <asn_internal.h>\r
+#include <asn_codecs_prim.h>\r
+#include <errno.h>\r
+\r
+/*\r
+ * Decode an always-primitive type.\r
+ */\r
+asn_dec_rval_t\r
+ber_decode_primitive(const asn_codec_ctx_t *opt_codec_ctx,\r
+                     const asn_TYPE_descriptor_t *td, void **sptr,\r
+                     const void *buf_ptr, size_t size, int tag_mode) {\r
+    ASN__PRIMITIVE_TYPE_t *st = (ASN__PRIMITIVE_TYPE_t *)*sptr;\r
+       asn_dec_rval_t rval;\r
+       ber_tlv_len_t length = 0; /* =0 to avoid [incorrect] warning. */\r
+\r
+       /*\r
+        * If the structure is not there, allocate it.\r
+        */\r
+       if(st == NULL) {\r
+               st = (ASN__PRIMITIVE_TYPE_t *)CALLOC(1, sizeof(*st));\r
+               if(st == NULL) ASN__DECODE_FAILED;\r
+               *sptr = (void *)st;\r
+       }\r
+\r
+       ASN_DEBUG("Decoding %s as plain primitive (tm=%d)",\r
+               td->name, tag_mode);\r
+\r
+       /*\r
+        * Check tags and extract value length.\r
+        */\r
+       rval = ber_check_tags(opt_codec_ctx, td, 0, buf_ptr, size,\r
+                       tag_mode, 0, &length, 0);\r
+       if(rval.code != RC_OK)\r
+               return rval;\r
+\r
+       ASN_DEBUG("%s length is %d bytes", td->name, (int)length);\r
+\r
+       /*\r
+        * Make sure we have this length.\r
+        */\r
+       buf_ptr = ((const char *)buf_ptr) + rval.consumed;\r
+       size -= rval.consumed;\r
+       if(length > (ber_tlv_len_t)size) {\r
+               rval.code = RC_WMORE;\r
+               rval.consumed = 0;\r
+               return rval;\r
+       }\r
+\r
+       st->size = (int)length;\r
+       /* The following better be optimized away. */\r
+       if(sizeof(st->size) != sizeof(length)\r
+                       && (ber_tlv_len_t)st->size != length) {\r
+               st->size = 0;\r
+               ASN__DECODE_FAILED;\r
+       }\r
+\r
+       st->buf = (uint8_t *)MALLOC(length + 1);\r
+       if(!st->buf) {\r
+               st->size = 0;\r
+               ASN__DECODE_FAILED;\r
+       }\r
+\r
+       memcpy(st->buf, buf_ptr, length);\r
+       st->buf[length] = '\0';         /* Just in case */\r
+\r
+       rval.code = RC_OK;\r
+       rval.consumed += length;\r
+\r
+       ASN_DEBUG("Took %ld/%ld bytes to encode %s",\r
+               (long)rval.consumed,\r
+               (long)length, td->name);\r
+\r
+       return rval;\r
+}\r
+\r
+/*\r
+ * Encode an always-primitive type using DER.\r
+ */\r
+asn_enc_rval_t\r
+der_encode_primitive(const asn_TYPE_descriptor_t *td, const void *sptr,\r
+                     int tag_mode, ber_tlv_tag_t tag,\r
+                     asn_app_consume_bytes_f *cb, void *app_key) {\r
+       asn_enc_rval_t erval = {0,0,0};\r
+       const ASN__PRIMITIVE_TYPE_t *st = (const ASN__PRIMITIVE_TYPE_t *)sptr;\r
+\r
+       ASN_DEBUG("%s %s as a primitive type (tm=%d)",\r
+               cb?"Encoding":"Estimating", td->name, tag_mode);\r
+\r
+       erval.encoded = der_write_tags(td, st->size, tag_mode, 0, tag,\r
+               cb, app_key);\r
+       ASN_DEBUG("%s wrote tags %d", td->name, (int)erval.encoded);\r
+       if(erval.encoded == -1) {\r
+               erval.failed_type = td;\r
+               erval.structure_ptr = sptr;\r
+               return erval;\r
+       }\r
+\r
+       if(cb && st->buf) {\r
+               if(cb(st->buf, st->size, app_key) < 0) {\r
+                       erval.encoded = -1;\r
+                       erval.failed_type = td;\r
+                       erval.structure_ptr = sptr;\r
+                       return erval;\r
+               }\r
+       } else {\r
+               assert(st->buf || st->size == 0);\r
+       }\r
+\r
+       erval.encoded += st->size;\r
+       ASN__ENCODED_OK(erval);\r
+}\r
+\r
+void\r
+ASN__PRIMITIVE_TYPE_free(const asn_TYPE_descriptor_t *td, void *sptr,\r
+                         enum asn_struct_free_method method) {\r
+    ASN__PRIMITIVE_TYPE_t *st = (ASN__PRIMITIVE_TYPE_t *)sptr;\r
+\r
+       if(!td || !sptr)\r
+               return;\r
+\r
+       ASN_DEBUG("Freeing %s as a primitive type", td->name);\r
+\r
+       if(st->buf)\r
+               FREEMEM(st->buf);\r
+\r
+    switch(method) {\r
+    case ASFM_FREE_EVERYTHING:\r
+        FREEMEM(sptr);\r
+        break;\r
+    case ASFM_FREE_UNDERLYING:\r
+        break;\r
+    case ASFM_FREE_UNDERLYING_AND_RESET:\r
+        memset(sptr, 0, sizeof(ASN__PRIMITIVE_TYPE_t));\r
+        break;\r
+    }\r
+}\r
+\r
+\r
+/*\r
+ * Local internal type passed around as an argument.\r
+ */\r
+struct xdp_arg_s {\r
+    const asn_TYPE_descriptor_t *type_descriptor;\r
+    void *struct_key;\r
+       xer_primitive_body_decoder_f *prim_body_decoder;\r
+       int decoded_something;\r
+       int want_more;\r
+};\r
+\r
+/*\r
+ * Since some kinds of primitive values can be encoded using value-specific\r
+ * tags (<MINUS-INFINITY>, <enum-element>, etc), the primitive decoder must\r
+ * be supplied with such tags to parse them as needed.\r
+ */\r
+static int\r
+xer_decode__unexpected_tag(void *key, const void *chunk_buf, size_t chunk_size) {\r
+       struct xdp_arg_s *arg = (struct xdp_arg_s *)key;\r
+       enum xer_pbd_rval bret;\r
+\r
+       /*\r
+        * The chunk_buf is guaranteed to start at '<'.\r
+        */\r
+       assert(chunk_size && ((const char *)chunk_buf)[0] == 0x3c);\r
+\r
+       /*\r
+        * Decoding was performed once already. Prohibit doing it again.\r
+        */\r
+       if(arg->decoded_something)\r
+               return -1;\r
+\r
+       bret = arg->prim_body_decoder(arg->type_descriptor,\r
+               arg->struct_key, chunk_buf, chunk_size);\r
+       switch(bret) {\r
+       case XPBD_SYSTEM_FAILURE:\r
+       case XPBD_DECODER_LIMIT:\r
+       case XPBD_BROKEN_ENCODING:\r
+               break;\r
+       case XPBD_BODY_CONSUMED:\r
+               /* Tag decoded successfully */\r
+               arg->decoded_something = 1;\r
+               /* Fall through */\r
+       case XPBD_NOT_BODY_IGNORE:      /* Safe to proceed further */\r
+               return 0;\r
+       }\r
+\r
+       return -1;\r
+}\r
+\r
+static ssize_t\r
+xer_decode__primitive_body(void *key, const void *chunk_buf, size_t chunk_size, int have_more) {\r
+       struct xdp_arg_s *arg = (struct xdp_arg_s *)key;\r
+       enum xer_pbd_rval bret;\r
+       size_t lead_wsp_size;\r
+\r
+       if(arg->decoded_something) {\r
+               if(xer_whitespace_span(chunk_buf, chunk_size) == chunk_size) {\r
+                       /*\r
+                        * Example:\r
+                        * "<INTEGER>123<!--/--> </INTEGER>"\r
+                        *                      ^- chunk_buf position.\r
+                        */\r
+                       return chunk_size;\r
+               }\r
+               /*\r
+                * Decoding was done once already. Prohibit doing it again.\r
+                */\r
+               return -1;\r
+       }\r
+\r
+       if(!have_more) {\r
+               /*\r
+                * If we've received something like "1", we can't really\r
+                * tell whether it is really `1` or `123`, until we know\r
+                * that there is no more data coming.\r
+                * The have_more argument will be set to 1 once something\r
+                * like this is available to the caller of this callback:\r
+                * "1<tag_start..."\r
+                */\r
+               arg->want_more = 1;\r
+               return -1;\r
+       }\r
+\r
+       lead_wsp_size = xer_whitespace_span(chunk_buf, chunk_size);\r
+       chunk_buf = (const char *)chunk_buf + lead_wsp_size;\r
+       chunk_size -= lead_wsp_size;\r
+\r
+       bret = arg->prim_body_decoder(arg->type_descriptor,\r
+               arg->struct_key, chunk_buf, chunk_size);\r
+       switch(bret) {\r
+       case XPBD_SYSTEM_FAILURE:\r
+       case XPBD_DECODER_LIMIT:\r
+       case XPBD_BROKEN_ENCODING:\r
+               break;\r
+       case XPBD_BODY_CONSUMED:\r
+               /* Tag decoded successfully */\r
+               arg->decoded_something = 1;\r
+               /* Fall through */\r
+       case XPBD_NOT_BODY_IGNORE:      /* Safe to proceed further */\r
+               return lead_wsp_size + chunk_size;\r
+       }\r
+\r
+       return -1;\r
+}\r
+\r
+\r
+asn_dec_rval_t\r
+xer_decode_primitive(const asn_codec_ctx_t *opt_codec_ctx,\r
+                     const asn_TYPE_descriptor_t *td, void **sptr,\r
+                     size_t struct_size, const char *opt_mname,\r
+                     const void *buf_ptr, size_t size,\r
+                     xer_primitive_body_decoder_f *prim_body_decoder) {\r
+    const char *xml_tag = opt_mname ? opt_mname : td->xml_tag;\r
+       asn_struct_ctx_t s_ctx;\r
+       struct xdp_arg_s s_arg;\r
+       asn_dec_rval_t rc;\r
+\r
+       /*\r
+        * Create the structure if does not exist.\r
+        */\r
+       if(!*sptr) {\r
+               *sptr = CALLOC(1, struct_size);\r
+               if(!*sptr) ASN__DECODE_FAILED;\r
+       }\r
+\r
+       memset(&s_ctx, 0, sizeof(s_ctx));\r
+       s_arg.type_descriptor = td;\r
+       s_arg.struct_key = *sptr;\r
+       s_arg.prim_body_decoder = prim_body_decoder;\r
+       s_arg.decoded_something = 0;\r
+       s_arg.want_more = 0;\r
+\r
+       rc = xer_decode_general(opt_codec_ctx, &s_ctx, &s_arg,\r
+               xml_tag, buf_ptr, size,\r
+               xer_decode__unexpected_tag, xer_decode__primitive_body);\r
+       switch(rc.code) {\r
+       case RC_OK:\r
+               if(!s_arg.decoded_something) {\r
+                       char ch;\r
+                       ASN_DEBUG("Primitive body is not recognized, "\r
+                               "supplying empty one");\r
+                       /*\r
+                        * Decoding opportunity has come and gone.\r
+                        * Where's the result?\r
+                        * Try to feed with empty body, see if it eats it.\r
+                        */\r
+                       if(prim_body_decoder(s_arg.type_descriptor,\r
+                               s_arg.struct_key, &ch, 0)\r
+                                       != XPBD_BODY_CONSUMED) {\r
+                               /*\r
+                                * This decoder does not like empty stuff.\r
+                                */\r
+                               ASN__DECODE_FAILED;\r
+                       }\r
+               }\r
+               break;\r
+       case RC_WMORE:\r
+               /*\r
+                * Redo the whole thing later.\r
+                * We don't have a context to save intermediate parsing state.\r
+                */\r
+               rc.consumed = 0;\r
+               break;\r
+       case RC_FAIL:\r
+               rc.consumed = 0;\r
+               if(s_arg.want_more)\r
+                       rc.code = RC_WMORE;\r
+               else\r
+                       ASN__DECODE_FAILED;\r
+               break;\r
+       }\r
+       return rc;\r
+}\r
+\r