SIM-115: update simulator to use latest E2SM KPM version 3
[sim/e2-interface.git] / e2sim / asn1c / OCTET_STRING.c
diff --git a/e2sim/asn1c/OCTET_STRING.c b/e2sim/asn1c/OCTET_STRING.c
new file mode 100644 (file)
index 0000000..d0bdead
--- /dev/null
@@ -0,0 +1,383 @@
+/*-
+ * Copyright (c) 2003-2017 Lev Walkin <vlm@lionet.info>.
+ * All rights reserved.
+ * Redistribution and modifications are permitted subject to BSD license.
+ */
+#include <asn_internal.h>
+#include <OCTET_STRING.h>
+#include <errno.h>
+
+/*
+ * OCTET STRING basic type description.
+ */
+static const ber_tlv_tag_t asn_DEF_OCTET_STRING_tags[] = {
+    (ASN_TAG_CLASS_UNIVERSAL | (4 << 2))
+};
+asn_OCTET_STRING_specifics_t asn_SPC_OCTET_STRING_specs = {
+    sizeof(OCTET_STRING_t),
+    offsetof(OCTET_STRING_t, _asn_ctx),
+    ASN_OSUBV_STR
+};
+asn_TYPE_operation_t asn_OP_OCTET_STRING = {
+    OCTET_STRING_free,
+#if !defined(ASN_DISABLE_PRINT_SUPPORT)
+    OCTET_STRING_print,  /* OCTET STRING generally means a non-ascii sequence */
+#else
+    0,
+#endif  /* !defined(ASN_DISABLE_PRINT_SUPPORT) */
+    OCTET_STRING_compare,
+#if !defined(ASN_DISABLE_BER_SUPPORT)
+    OCTET_STRING_decode_ber,
+    OCTET_STRING_encode_der,
+#else
+    0,
+    0,
+#endif  /* !defined(ASN_DISABLE_BER_SUPPORT) */
+#if !defined(ASN_DISABLE_XER_SUPPORT)
+    OCTET_STRING_decode_xer_hex,
+    OCTET_STRING_encode_xer,
+#else
+    0,
+    0,
+#endif  /* !defined(ASN_DISABLE_XER_SUPPORT) */
+#if !defined(ASN_DISABLE_JER_SUPPORT)
+    OCTET_STRING_encode_jer,
+#else
+    0,
+#endif  /* !defined(ASN_DISABLE_JER_SUPPORT) */
+#if !defined(ASN_DISABLE_OER_SUPPORT)
+    OCTET_STRING_decode_oer,
+    OCTET_STRING_encode_oer,
+#else
+    0,
+    0,
+#endif  /* !defined(ASN_DISABLE_OER_SUPPORT) */
+#if !defined(ASN_DISABLE_UPER_SUPPORT)
+    OCTET_STRING_decode_uper,  /* Unaligned PER decoder */
+    OCTET_STRING_encode_uper,  /* Unaligned PER encoder */
+#else
+    0,
+    0,
+#endif  /* !defined(ASN_DISABLE_UPER_SUPPORT) */
+#if !defined(ASN_DISABLE_APER_SUPPORT)
+    OCTET_STRING_decode_aper,  /* Aligned PER decoder */
+    OCTET_STRING_encode_aper,  /* Aligned PER encoder */
+#else
+    0,
+    0,
+#endif  /* !defined(ASN_DISABLE_APER_SUPPORT) */
+#if !defined(ASN_DISABLE_RFILL_SUPPORT)
+    OCTET_STRING_random_fill,
+#else
+    0,
+#endif  /* !defined(ASN_DISABLE_RFILL_SUPPORT) */
+    0  /* Use generic outmost tag fetcher */
+};
+asn_TYPE_descriptor_t asn_DEF_OCTET_STRING = {
+    "OCTET STRING",  /* Canonical name */
+    "OCTET_STRING",  /* XML tag name */
+    &asn_OP_OCTET_STRING,
+    asn_DEF_OCTET_STRING_tags,
+    sizeof(asn_DEF_OCTET_STRING_tags)
+        / sizeof(asn_DEF_OCTET_STRING_tags[0]),
+    asn_DEF_OCTET_STRING_tags, /* Same as above */
+    sizeof(asn_DEF_OCTET_STRING_tags)
+        / sizeof(asn_DEF_OCTET_STRING_tags[0]),
+    {
+#if !defined(ASN_DISABLE_OER_SUPPORT)
+        0,
+#endif  /* !defined(ASN_DISABLE_OER_SUPPORT) */
+#if !defined(ASN_DISABLE_UPER_SUPPORT) || !defined(ASN_DISABLE_APER_SUPPORT)
+        0,
+#endif  /* !defined(ASN_DISABLE_UPER_SUPPORT) || !defined(ASN_DISABLE_APER_SUPPORT) */
+        asn_generic_no_constraint
+    },
+    0, 0,  /* No members */
+    &asn_SPC_OCTET_STRING_specs
+};
+
+void
+OCTET_STRING_free(const asn_TYPE_descriptor_t *td, void *sptr,
+                  enum asn_struct_free_method method) {
+       OCTET_STRING_t *st = (OCTET_STRING_t *)sptr;
+
+       if(!td || !st)
+               return;
+
+       ASN_DEBUG("Freeing %s as OCTET STRING", td->name);
+
+       if(st->buf) {
+               FREEMEM(st->buf);
+               st->buf = 0;
+       }
+
+#if !defined(ASN_DISABLE_BER_SUPPORT)
+    const asn_OCTET_STRING_specifics_t *specs;
+    asn_struct_ctx_t *ctx;
+
+    specs = td->specifics
+            ? (const asn_OCTET_STRING_specifics_t *)td->specifics
+            : &asn_SPC_OCTET_STRING_specs;
+    ctx = (asn_struct_ctx_t *)((char *)st + specs->ctx_offset);
+
+    /*
+     * Remove decode-time stack.
+     */
+    struct _stack *stck;
+    stck = (struct _stack *)ctx->ptr;
+    if(stck) {
+        while(stck->tail) {
+            struct _stack_el *sel = stck->tail;
+            stck->tail = sel->prev;
+            FREEMEM(sel);
+        }
+        FREEMEM(stck);
+    }
+#endif  /* !defined(ASN_DISABLE_BER_SUPPORT) */
+
+    switch(method) {
+    case ASFM_FREE_EVERYTHING:
+        FREEMEM(sptr);
+        break;
+    case ASFM_FREE_UNDERLYING:
+        break;
+    case ASFM_FREE_UNDERLYING_AND_RESET:
+        memset(sptr, 0,
+               td->specifics
+                   ? ((const asn_OCTET_STRING_specifics_t *)(td->specifics))
+                         ->struct_size
+                   : sizeof(OCTET_STRING_t));
+        break;
+    }
+}
+
+/*
+ * Conversion routines.
+ */
+int
+OCTET_STRING_fromBuf(OCTET_STRING_t *st, const char *str, int len) {
+       void *buf;
+
+       if(st == 0 || (str == 0 && len)) {
+               errno = EINVAL;
+               return -1;
+       }
+
+       /*
+        * Clear the OCTET STRING.
+        */
+       if(str == NULL) {
+               FREEMEM(st->buf);
+               st->buf = 0;
+               st->size = 0;
+               return 0;
+       }
+
+       /* Determine the original string size, if not explicitly given */
+       if(len < 0)
+               len = strlen(str);
+
+       /* Allocate and fill the memory */
+       buf = MALLOC(len + 1);
+       if(buf == NULL)
+               return -1;
+
+       memcpy(buf, str, len);
+       ((uint8_t *)buf)[len] = '\0';   /* Couldn't use memcpy(len+1)! */
+       FREEMEM(st->buf);
+       st->buf = (uint8_t *)buf;
+       st->size = len;
+
+       return 0;
+}
+
+OCTET_STRING_t *
+OCTET_STRING_new_fromBuf(const asn_TYPE_descriptor_t *td, const char *str,
+                         int len) {
+    const asn_OCTET_STRING_specifics_t *specs =
+        td->specifics ? (const asn_OCTET_STRING_specifics_t *)td->specifics
+                      : &asn_SPC_OCTET_STRING_specs;
+    OCTET_STRING_t *st;
+
+       st = (OCTET_STRING_t *)CALLOC(1, specs->struct_size);
+       if(st && str && OCTET_STRING_fromBuf(st, str, len)) {
+               FREEMEM(st);
+               st = NULL;
+       }
+
+       return st;
+}
+
+/*
+ * Lexicographically compare the common prefix of both strings,
+ * and if it is the same return -1 for the smallest string.
+ */
+int
+OCTET_STRING_compare(const asn_TYPE_descriptor_t *td, const void *aptr,
+                     const void *bptr) {
+    const asn_OCTET_STRING_specifics_t *specs = td->specifics;
+    const OCTET_STRING_t *a = aptr;
+    const OCTET_STRING_t *b = bptr;
+
+    (void)specs;
+    assert(!specs || specs->subvariant != ASN_OSUBV_BIT);
+
+    if(a && b) {
+        size_t common_prefix_size = a->size <= b->size ? a->size : b->size;
+        int ret = memcmp(a->buf, b->buf, common_prefix_size);
+        if(ret == 0) {
+            /* Figure out which string with equal prefixes is longer. */
+            if(a->size < b->size) {
+                return -1;
+            } else if(a->size > b->size) {
+                return 1;
+            } else {
+                return 0;
+            }
+        } else {
+            return ret < 0 ? -1 : 1;
+        }
+    } else if(!a && !b) {
+        return 0;
+    } else if(!a) {
+        return -1;
+    } else {
+        return 1;
+    }
+
+}
+
+#if !defined(ASN_DISABLE_UPER_SUPPORT) || !defined(ASN_DISABLE_APER_SUPPORT)
+int
+OCTET_STRING_per_get_characters(asn_per_data_t *po, uint8_t *buf,
+                                size_t units, unsigned int bpc, unsigned int unit_bits,
+                                long lb, long ub, const asn_per_constraints_t *pc) {
+    uint8_t *end = buf + units * bpc;
+
+    ASN_DEBUG("Expanding %d characters into (%ld..%ld):%d",
+              (int)units, lb, ub, unit_bits);
+
+    /* X.691: 27.5.4 */
+    if((unsigned long)ub <= ((unsigned long)2 << (unit_bits - 1))) {
+        /* Decode without translation */
+        lb = 0;
+    } else if(pc && pc->code2value) {
+        if(unit_bits > 16)
+            return 1;  /* FATAL: can't have constrained
+                        * UniversalString with more than
+                        * 16 million code points */
+        for(; buf < end; buf += bpc) {
+            int value;
+            int code = per_get_few_bits(po, unit_bits);
+            if(code < 0) return -1;  /* WMORE */
+            value = pc->code2value(code);
+            if(value < 0) {
+                ASN_DEBUG("Code %d (0x%02x) is"
+                          " not in map (%ld..%ld)",
+                          code, code, lb, ub);
+                return 1;  /* FATAL */
+            }
+            switch(bpc) {
+            case 1: *buf = value; break;
+            case 2: buf[0] = value >> 8; buf[1] = value; break;
+            case 4: buf[0] = value >> 24; buf[1] = value >> 16;
+                buf[2] = value >> 8; buf[3] = value; break;
+            }
+        }
+        return 0;
+    }
+
+    /* Shortcut the no-op copying to the aligned structure */
+    if(lb == 0 && (unit_bits == 8 * bpc)) {
+        return per_get_many_bits(po, buf, 0, unit_bits * units);
+    }
+
+    for(; buf < end; buf += bpc) {
+        int32_t code = per_get_few_bits(po, unit_bits);
+        int32_t ch = code + lb;
+        if(code < 0) return -1;  /* WMORE */
+        if(ch > ub) {
+            ASN_DEBUG("Code %d is out of range (%ld..%ld)",
+                      ch, lb, ub);
+            return 1;  /* FATAL */
+        }
+        switch(bpc) {
+        case 1: *buf = ch; break;
+        case 2: buf[0] = ch >> 8; buf[1] = ch; break;
+        case 4: buf[0] = ch >> 24; buf[1] = ch >> 16;
+            buf[2] = ch >> 8; buf[3] = ch; break;
+        }
+    }
+
+    return 0;
+}
+
+int
+OCTET_STRING_per_put_characters(asn_per_outp_t *po, const uint8_t *buf,
+                                size_t units, unsigned int bpc, unsigned int unit_bits,
+                                long lb, long ub, const asn_per_constraints_t *pc) {
+    const uint8_t *end = buf + units * bpc;
+
+    ASN_DEBUG("Squeezing %d characters into (%ld..%ld):%d (%d bpc)",
+              (int)units, lb, ub, unit_bits, bpc);
+
+    /* X.691: 27.5.4 */
+    if((unsigned long)ub <= ((unsigned long)2 << (unit_bits - 1))) {
+        /* Encode as is */
+        lb = 0;
+    } else if(pc && pc->value2code) {
+        for(; buf < end; buf += bpc) {
+            int code;
+            uint32_t value;
+            switch(bpc) {
+            case 1: value = *(const uint8_t *)buf; break;
+            case 2: value = (buf[0] << 8) | buf[1]; break;
+            case 4: value = (buf[0] << 24) | (buf[1] << 16)
+                | (buf[2] << 8) | buf[3]; break;
+            default: return -1;
+            }
+            code = pc->value2code(value);
+            if(code < 0) {
+                ASN_DEBUG("Character %d (0x%02x) is"
+                          " not in map (%ld..%ld)",
+                          *buf, *buf, lb, ub);
+                return -1;
+            }
+            if(per_put_few_bits(po, code, unit_bits))
+    return -1;
+        }
+    }
+
+    /* Shortcut the no-op copying to the aligned structure */
+    if(lb == 0 && (unit_bits == 8 * bpc)) {
+        return per_put_many_bits(po, buf, unit_bits * units);
+    }
+
+    for(ub -= lb; buf < end; buf += bpc) {
+        int ch;
+        uint32_t value;
+        switch(bpc) {
+        case 1:
+            value = *(const uint8_t *)buf;
+            break;
+        case 2:
+            value = (buf[0] << 8) | buf[1];
+            break;
+        case 4:
+            value = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
+            break;
+        default:
+            return -1;
+        }
+        ch = value - lb;
+        if(ch < 0 || ch > ub) {
+            ASN_DEBUG("Character %d (0x%02x) is out of range (%ld..%ld)", *buf,
+                      value, lb, ub + lb);
+            return -1;
+        }
+        if(per_put_few_bits(po, ch, unit_bits)) return -1;
+    }
+
+    return 0;
+}
+#endif  /* !defined(ASN_DISABLE_UPER_SUPPORT) || !defined(ASN_DISABLE_APER_SUPPORT) */