Adding initial code jy.oak@samsung.com
[ric-app/kpimon.git] / asn1c_defs / all-defs / asn_application.c
diff --git a/asn1c_defs/all-defs/asn_application.c b/asn1c_defs/all-defs/asn_application.c
new file mode 100755 (executable)
index 0000000..c2410d2
--- /dev/null
@@ -0,0 +1,481 @@
+/*\r
+ * Copyright (c) 2017 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_application.h>\r
+#include <errno.h>\r
+\r
+static asn_enc_rval_t asn_encode_internal(const asn_codec_ctx_t *opt_codec_ctx,\r
+                                          enum asn_transfer_syntax syntax,\r
+                                          const asn_TYPE_descriptor_t *td,\r
+                                          const void *sptr,\r
+                                          asn_app_consume_bytes_f *callback,\r
+                                          void *callback_key);\r
+\r
+\r
+struct callback_count_bytes_key {\r
+    asn_app_consume_bytes_f *callback;\r
+    void *callback_key;\r
+    size_t computed_size;\r
+};\r
+\r
+/*\r
+ * Encoder which just counts bytes that come through it.\r
+ */\r
+static int\r
+callback_count_bytes_cb(const void *data, size_t size, void *keyp) {\r
+    struct callback_count_bytes_key *key = keyp;\r
+    int ret;\r
+\r
+    ret = key->callback(data, size, key->callback_key);\r
+    if(ret >= 0) {\r
+        key->computed_size += size;\r
+    }\r
+\r
+    return ret;\r
+}\r
+\r
+struct overrun_encoder_key {\r
+    void *buffer;\r
+    size_t buffer_size;\r
+    size_t computed_size;\r
+};\r
+\r
+struct dynamic_encoder_key {\r
+    void *buffer;\r
+    size_t buffer_size;\r
+    size_t computed_size;\r
+};\r
+\r
+struct callback_failure_catch_key {\r
+    asn_app_consume_bytes_f *callback;\r
+    void *callback_key;\r
+    int callback_failed;\r
+};\r
+\r
+/*\r
+ * Encoder which doesn't stop counting bytes\r
+ * even if it reaches the end of the buffer.\r
+ */\r
+static int\r
+overrun_encoder_cb(const void *data, size_t size, void *keyp) {\r
+    struct overrun_encoder_key *key = keyp;\r
+\r
+    if(key->computed_size + size > key->buffer_size) {\r
+        /*\r
+         * Avoid accident on the next call:\r
+         * stop adding bytes to the buffer.\r
+         */\r
+        key->buffer_size = 0;\r
+    } else {\r
+        memcpy((char *)key->buffer + key->computed_size, data, size);\r
+    }\r
+    key->computed_size += size;\r
+\r
+    return 0;\r
+}\r
+\r
+/*\r
+ * Encoder which dynamically allocates output, and continues\r
+ * to count even if allocation failed.\r
+ */\r
+static int\r
+dynamic_encoder_cb(const void *data, size_t size, void *keyp) {\r
+    struct dynamic_encoder_key *key = keyp;\r
+\r
+    if(key->buffer) {\r
+        if(key->computed_size + size >= key->buffer_size) {\r
+            void *p;\r
+            size_t new_size = key->buffer_size;\r
+\r
+            do {\r
+                new_size *= 2;\r
+            } while(new_size <= key->computed_size + size);\r
+\r
+            p = REALLOC(key->buffer, new_size);\r
+            if(p) {\r
+                key->buffer = p;\r
+                key->buffer_size = new_size;\r
+            } else {\r
+                FREEMEM(key->buffer);\r
+                key->buffer = 0;\r
+                key->buffer_size = 0;\r
+                key->computed_size += size;\r
+                return 0;\r
+            }\r
+        }\r
+        memcpy((char *)key->buffer + key->computed_size, data, size);\r
+    }\r
+\r
+    key->computed_size += size;\r
+\r
+    return 0;\r
+}\r
+\r
+/*\r
+ * Encoder which help convert the application level encoder failure into EIO.\r
+ */\r
+static int\r
+callback_failure_catch_cb(const void *data, size_t size, void *keyp) {\r
+    struct callback_failure_catch_key *key = keyp;\r
+    int ret;\r
+\r
+    ret = key->callback(data, size, key->callback_key);\r
+    if(ret < 0) {\r
+        key->callback_failed = 1;\r
+    }\r
+\r
+    return ret;\r
+}\r
+\r
+asn_enc_rval_t\r
+asn_encode(const asn_codec_ctx_t *opt_codec_ctx,\r
+           enum asn_transfer_syntax syntax, const asn_TYPE_descriptor_t *td,\r
+           const void *sptr, asn_app_consume_bytes_f *callback, void *callback_key) {\r
+    struct callback_failure_catch_key cb_key;\r
+    asn_enc_rval_t er = {0,0,0};\r
+\r
+    if(!callback) {\r
+        errno = EINVAL;\r
+        ASN__ENCODE_FAILED;\r
+    }\r
+\r
+    cb_key.callback = callback;\r
+    cb_key.callback_key = callback_key;\r
+    cb_key.callback_failed = 0;\r
+\r
+    er = asn_encode_internal(opt_codec_ctx, syntax, td, sptr,\r
+                             callback_failure_catch_cb, &cb_key);\r
+    if(cb_key.callback_failed) {\r
+        assert(er.encoded == -1);\r
+        assert(errno == EBADF);\r
+        errno = EIO;\r
+    }\r
+\r
+    return er;\r
+}\r
+\r
+asn_enc_rval_t\r
+asn_encode_to_buffer(const asn_codec_ctx_t *opt_codec_ctx,\r
+                     enum asn_transfer_syntax syntax,\r
+                     const asn_TYPE_descriptor_t *td, const void *sptr,\r
+                     void *buffer, size_t buffer_size) {\r
+    struct overrun_encoder_key buf_key;\r
+    asn_enc_rval_t er = {0,0,0};\r
+\r
+    if(buffer_size > 0 && !buffer) {\r
+        errno = EINVAL;\r
+        ASN__ENCODE_FAILED;\r
+    }\r
+\r
+    buf_key.buffer = buffer;\r
+    buf_key.buffer_size = buffer_size;\r
+    buf_key.computed_size = 0;\r
+\r
+    er = asn_encode_internal(opt_codec_ctx, syntax, td, sptr,\r
+                             overrun_encoder_cb, &buf_key);\r
+\r
+    if(er.encoded >= 0 && (size_t)er.encoded != buf_key.computed_size) {\r
+        ASN_DEBUG("asn_encode() returned %" ASN_PRI_SSIZE\r
+                  " yet produced %" ASN_PRI_SIZE " bytes",\r
+                  er.encoded, buf_key.computed_size);\r
+        assert(er.encoded < 0 || (size_t)er.encoded == buf_key.computed_size);\r
+    }\r
+\r
+    return er;\r
+}\r
+\r
+asn_encode_to_new_buffer_result_t\r
+asn_encode_to_new_buffer(const asn_codec_ctx_t *opt_codec_ctx,\r
+                         enum asn_transfer_syntax syntax,\r
+                         const asn_TYPE_descriptor_t *td, const void *sptr) {\r
+    struct dynamic_encoder_key buf_key;\r
+    asn_encode_to_new_buffer_result_t res;\r
+\r
+    buf_key.buffer_size = 16;\r
+    buf_key.buffer = MALLOC(buf_key.buffer_size);\r
+    buf_key.computed_size = 0;\r
+\r
+    res.result = asn_encode_internal(opt_codec_ctx, syntax, td, sptr,\r
+                                     dynamic_encoder_cb, &buf_key);\r
+\r
+    if(res.result.encoded >= 0\r
+       && (size_t)res.result.encoded != buf_key.computed_size) {\r
+        ASN_DEBUG("asn_encode() returned %" ASN_PRI_SSIZE\r
+                  " yet produced %" ASN_PRI_SIZE " bytes",\r
+                  res.result.encoded, buf_key.computed_size);\r
+        assert(res.result.encoded < 0\r
+               || (size_t)res.result.encoded == buf_key.computed_size);\r
+    }\r
+\r
+    res.buffer = buf_key.buffer;\r
+\r
+    /* 0-terminate just in case. */\r
+    if(res.buffer) {\r
+        assert(buf_key.computed_size < buf_key.buffer_size);\r
+        ((char *)res.buffer)[buf_key.computed_size] = '\0';\r
+    }\r
+\r
+    return res;\r
+}\r
+\r
+static asn_enc_rval_t\r
+asn_encode_internal(const asn_codec_ctx_t *opt_codec_ctx,\r
+                    enum asn_transfer_syntax syntax,\r
+                    const asn_TYPE_descriptor_t *td, const void *sptr,\r
+                    asn_app_consume_bytes_f *callback, void *callback_key) {\r
+    asn_enc_rval_t er = {0,0,0};\r
+    enum xer_encoder_flags_e xer_flags = XER_F_CANONICAL;\r
+\r
+    (void)opt_codec_ctx; /* Parameters are not checked on encode yet. */\r
+\r
+    if(!td || !sptr) {\r
+        errno = EINVAL;\r
+        ASN__ENCODE_FAILED;\r
+    }\r
+\r
+    switch(syntax) {\r
+    case ATS_NONSTANDARD_PLAINTEXT:\r
+        if(td->op->print_struct) {\r
+            struct callback_count_bytes_key cb_key;\r
+            cb_key.callback = callback;\r
+            cb_key.callback_key = callback_key;\r
+            cb_key.computed_size = 0;\r
+            if(td->op->print_struct(td, sptr, 1, callback_count_bytes_cb,\r
+                                    &cb_key)\r
+                   < 0\r
+               || callback_count_bytes_cb("\n", 1, &cb_key) < 0) {\r
+                errno = EBADF; /* Structure has incorrect form. */\r
+                er.encoded = -1;\r
+                er.failed_type = td;\r
+                er.structure_ptr = sptr;\r
+            } else {\r
+                er.encoded = cb_key.computed_size;\r
+                er.failed_type = 0;\r
+                er.structure_ptr = 0;\r
+            }\r
+        } else {\r
+            errno = ENOENT; /* Transfer syntax is not defined for this type. */\r
+            ASN__ENCODE_FAILED;\r
+        }\r
+        break;\r
+\r
+    case ATS_RANDOM:\r
+        errno = ENOENT; /* Randomization doesn't make sense on output. */\r
+        ASN__ENCODE_FAILED;\r
+\r
+    case ATS_BER:\r
+        /* BER is a superset of DER. */\r
+        /* Fall through. */\r
+    case ATS_DER:\r
+        if(td->op->der_encoder) {\r
+            er = der_encode(td, sptr, callback, callback_key);\r
+            if(er.encoded == -1) {\r
+                if(er.failed_type && er.failed_type->op->der_encoder) {\r
+                    errno = EBADF;  /* Structure has incorrect form. */\r
+                } else {\r
+                    errno = ENOENT; /* DER is not defined for this type. */\r
+                }\r
+            }\r
+        } else {\r
+            errno = ENOENT; /* Transfer syntax is not defined for this type. */\r
+            ASN__ENCODE_FAILED;\r
+        }\r
+        break;\r
+    case ATS_CER:\r
+        errno = ENOENT; /* Transfer syntax is not defined for any type. */\r
+        ASN__ENCODE_FAILED;\r
+\r
+#ifdef  ASN_DISABLE_OER_SUPPORT\r
+    case ATS_BASIC_OER:\r
+    case ATS_CANONICAL_OER:\r
+        errno = ENOENT; /* PER is not defined. */\r
+        ASN__ENCODE_FAILED;\r
+        break;\r
+#else /* ASN_DISABLE_OER_SUPPORT */\r
+    case ATS_BASIC_OER:\r
+        /* CANONICAL-OER is a superset of BASIC-OER. */\r
+        /* Fall through. */\r
+    case ATS_CANONICAL_OER:\r
+        if(td->op->oer_encoder) {\r
+            er = oer_encode(td, sptr, callback, callback_key);\r
+            if(er.encoded == -1) {\r
+                if(er.failed_type && er.failed_type->op->oer_encoder) {\r
+                    errno = EBADF;  /* Structure has incorrect form. */\r
+                } else {\r
+                    errno = ENOENT; /* OER is not defined for this type. */\r
+                }\r
+            }\r
+        } else {\r
+            errno = ENOENT; /* Transfer syntax is not defined for this type. */\r
+            ASN__ENCODE_FAILED;\r
+        }\r
+        break;\r
+#endif /* ASN_DISABLE_OER_SUPPORT */\r
+\r
+#ifdef  ASN_DISABLE_PER_SUPPORT\r
+    case ATS_UNALIGNED_BASIC_PER:\r
+    case ATS_UNALIGNED_CANONICAL_PER:\r
+    case ATS_ALIGNED_BASIC_PER:\r
+    case ATS_ALIGNED_CANONICAL_PER:\r
+        errno = ENOENT; /* PER is not defined. */\r
+        ASN__ENCODE_FAILED;\r
+        break;\r
+#else /* ASN_DISABLE_PER_SUPPORT */\r
+    case ATS_UNALIGNED_BASIC_PER:\r
+        /* CANONICAL-UPER is a superset of BASIC-UPER. */\r
+        /* Fall through. */\r
+    case ATS_UNALIGNED_CANONICAL_PER:\r
+        if(td->op->uper_encoder) {\r
+            er = uper_encode(td, 0, sptr, callback, callback_key);\r
+            if(er.encoded == -1) {\r
+                if(er.failed_type && er.failed_type->op->uper_encoder) {\r
+                    errno = EBADF;  /* Structure has incorrect form. */\r
+                } else {\r
+                    errno = ENOENT; /* UPER is not defined for this type. */\r
+                }\r
+            } else {\r
+                ASN_DEBUG("Complete encoded in %ld bits", (long)er.encoded);\r
+                if(er.encoded == 0) {\r
+                    /* Enforce "Complete Encoding" of X.691 #11.1 */\r
+                    if(callback("\0", 1, callback_key) < 0) {\r
+                        errno = EBADF;\r
+                        ASN__ENCODE_FAILED;\r
+                    }\r
+                    er.encoded = 8; /* Exactly 8 zero bits is added. */\r
+                }\r
+                /* Convert bits into bytes */\r
+                er.encoded = (er.encoded + 7) >> 3;\r
+            }\r
+        } else {\r
+            errno = ENOENT; /* Transfer syntax is not defined for this type. */\r
+            ASN__ENCODE_FAILED;\r
+        }\r
+        break;\r
+    case ATS_ALIGNED_BASIC_PER:\r
+        /* CANONICAL-APER is a superset of BASIC-APER. */\r
+        /* Fall through. */\r
+    case ATS_ALIGNED_CANONICAL_PER:\r
+        if(td->op->aper_encoder) {\r
+            er = aper_encode(td, 0, sptr, callback, callback_key);\r
+            if(er.encoded == -1) {\r
+                if(er.failed_type && er.failed_type->op->aper_encoder) {\r
+                    errno = EBADF;  /* Structure has incorrect form. */\r
+                } else {\r
+                    errno = ENOENT; /* APER is not defined for this type. */\r
+                }\r
+            } else {\r
+                ASN_DEBUG("Complete encoded in %ld bits", (long)er.encoded);\r
+                if(er.encoded == 0) {\r
+                    /* Enforce "Complete Encoding" of X.691 #11.1 */\r
+                    if(callback("\0", 1, callback_key) < 0) {\r
+                        errno = EBADF;\r
+                        ASN__ENCODE_FAILED;\r
+                    }\r
+                    er.encoded = 8; /* Exactly 8 zero bits is added. */\r
+                }\r
+                /* Convert bits into bytes */\r
+                er.encoded = (er.encoded + 7) >> 3;\r
+            }\r
+        } else {\r
+            errno = ENOENT; /* Transfer syntax is not defined for this type. */\r
+            ASN__ENCODE_FAILED;\r
+        }\r
+        break;\r
+#endif  /* ASN_DISABLE_PER_SUPPORT */\r
+\r
+    case ATS_BASIC_XER:\r
+        /* CANONICAL-XER is a superset of BASIC-XER. */\r
+        xer_flags &= ~XER_F_CANONICAL;\r
+        xer_flags |= XER_F_BASIC;\r
+        /* Fall through. */\r
+    case ATS_CANONICAL_XER:\r
+        if(td->op->xer_encoder) {\r
+            er = xer_encode(td, sptr, xer_flags, callback, callback_key);\r
+            if(er.encoded == -1) {\r
+                if(er.failed_type && er.failed_type->op->xer_encoder) {\r
+                    errno = EBADF;  /* Structure has incorrect form. */\r
+                } else {\r
+                    errno = ENOENT; /* XER is not defined for this type. */\r
+                }\r
+            }\r
+        } else {\r
+            errno = ENOENT; /* Transfer syntax is not defined for this type. */\r
+            ASN__ENCODE_FAILED;\r
+        }\r
+        break;\r
+\r
+    default:\r
+        errno = ENOENT;\r
+        ASN__ENCODE_FAILED;\r
+    }\r
+\r
+    return er;\r
+}\r
+\r
+asn_dec_rval_t\r
+asn_decode(const asn_codec_ctx_t *opt_codec_ctx,\r
+           enum asn_transfer_syntax syntax, const asn_TYPE_descriptor_t *td,\r
+           void **sptr, const void *buffer, size_t size) {\r
+    if(!td || !td->op || !sptr || (size && !buffer)) {\r
+        ASN__DECODE_FAILED;\r
+    }\r
+\r
+    switch(syntax) {\r
+    case ATS_CER:\r
+    case ATS_NONSTANDARD_PLAINTEXT:\r
+    default:\r
+        errno = ENOENT;\r
+        ASN__DECODE_FAILED;\r
+\r
+    case ATS_RANDOM:\r
+        if(!td->op->random_fill) {\r
+            ASN__DECODE_FAILED;\r
+        } else {\r
+            if(asn_random_fill(td, sptr, 16000) == 0) {\r
+                asn_dec_rval_t ret = {RC_OK, 0};\r
+                return ret;\r
+            } else {\r
+                ASN__DECODE_FAILED;\r
+            }\r
+        }\r
+        break;\r
+\r
+    case ATS_DER:\r
+    case ATS_BER:\r
+        return ber_decode(opt_codec_ctx, td, sptr, buffer, size);\r
+\r
+    case ATS_BASIC_OER:\r
+    case ATS_CANONICAL_OER:\r
+#ifdef  ASN_DISABLE_OER_SUPPORT\r
+        errno = ENOENT;\r
+        ASN__DECODE_FAILED;\r
+#else\r
+        return oer_decode(opt_codec_ctx, td, sptr, buffer, size);\r
+#endif\r
+\r
+    case ATS_UNALIGNED_BASIC_PER:\r
+    case ATS_UNALIGNED_CANONICAL_PER:\r
+#ifdef  ASN_DISABLE_PER_SUPPORT\r
+        errno = ENOENT;\r
+        ASN__DECODE_FAILED;\r
+#else\r
+        return uper_decode_complete(opt_codec_ctx, td, sptr, buffer, size);\r
+#endif\r
+\r
+    case ATS_ALIGNED_BASIC_PER:\r
+    case ATS_ALIGNED_CANONICAL_PER:\r
+#ifdef  ASN_DISABLE_PER_SUPPORT\r
+        errno = ENOENT;\r
+        ASN__DECODE_FAILED;\r
+#else\r
+        return aper_decode_complete(opt_codec_ctx, td, sptr, buffer, size);\r
+#endif\r
+\r
+    case ATS_BASIC_XER:\r
+    case ATS_CANONICAL_XER:\r
+        return xer_decode(opt_codec_ctx, td, sptr, buffer, size);\r
+    }\r
+}\r
+\r