Adding initial code jy.oak@samsung.com
[ric-app/kpimon.git] / asn1c_defs / all-defs / per_opentype.c
diff --git a/asn1c_defs/all-defs/per_opentype.c b/asn1c_defs/all-defs/per_opentype.c
new file mode 100755 (executable)
index 0000000..f9644c9
--- /dev/null
@@ -0,0 +1,533 @@
+/*\r
+ * Copyright (c) 2007 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 <per_support.h>\r
+#include <constr_TYPE.h>\r
+#include <per_opentype.h>\r
+\r
+typedef struct uper_ugot_key {\r
+       asn_per_data_t oldpd;   /* Old per data source */\r
+       size_t unclaimed;\r
+       size_t ot_moved;        /* Number of bits moved by OT processing */\r
+       int repeat;\r
+} uper_ugot_key;\r
+\r
+static int uper_ugot_refill(asn_per_data_t *pd);\r
+static int per_skip_bits(asn_per_data_t *pd, int skip_nbits);\r
+static asn_dec_rval_t uper_sot_suck(const asn_codec_ctx_t *,\r
+                                    const asn_TYPE_descriptor_t *td,\r
+                                    const asn_per_constraints_t *constraints,\r
+                                    void **sptr, asn_per_data_t *pd);\r
+\r
+/*\r
+ * Encode an "open type field".\r
+ * #10.1, #10.2\r
+ */\r
+int\r
+uper_open_type_put(const asn_TYPE_descriptor_t *td,\r
+                   const asn_per_constraints_t *constraints, const void *sptr,\r
+                   asn_per_outp_t *po) {\r
+    void *buf;\r
+    void *bptr;\r
+    ssize_t size;\r
+\r
+    ASN_DEBUG("Open type put %s ...", td->name);\r
+\r
+    size = uper_encode_to_new_buffer(td, constraints, sptr, &buf);\r
+    if(size <= 0) return -1;\r
+\r
+    ASN_DEBUG("Open type put %s of length %" ASN_PRI_SSIZE " + overhead (1byte?)", td->name,\r
+              size);\r
+\r
+    bptr = buf;\r
+    do {\r
+        int need_eom = 0;\r
+        ssize_t may_save = uper_put_length(po, size, &need_eom);\r
+        ASN_DEBUG("Prepending length %" ASN_PRI_SSIZE\r
+                  " to %s and allowing to save %" ASN_PRI_SSIZE,\r
+                  size, td->name, may_save);\r
+        if(may_save < 0) break;\r
+        if(per_put_many_bits(po, bptr, may_save * 8)) break;\r
+        bptr = (char *)bptr + may_save;\r
+        size -= may_save;\r
+        if(need_eom && uper_put_length(po, 0, 0)) {\r
+            FREEMEM(buf);\r
+            return -1;\r
+        }\r
+    } while(size);\r
+\r
+    FREEMEM(buf);\r
+    if(size) return -1;\r
+\r
+    return 0;\r
+}\r
+\r
+static asn_dec_rval_t\r
+uper_open_type_get_simple(const asn_codec_ctx_t *ctx,\r
+                          const asn_TYPE_descriptor_t *td,\r
+                          const asn_per_constraints_t *constraints, void **sptr,\r
+                          asn_per_data_t *pd) {\r
+    asn_dec_rval_t rv;\r
+       ssize_t chunk_bytes;\r
+       int repeat;\r
+       uint8_t *buf = 0;\r
+       size_t bufLen = 0;\r
+       size_t bufSize = 0;\r
+       asn_per_data_t spd;\r
+       size_t padding;\r
+\r
+       ASN__STACK_OVERFLOW_CHECK(ctx);\r
+\r
+       ASN_DEBUG("Getting open type %s...", td->name);\r
+\r
+       do {\r
+               chunk_bytes = uper_get_length(pd, -1, 0, &repeat);\r
+               if(chunk_bytes < 0) {\r
+                       FREEMEM(buf);\r
+                       ASN__DECODE_STARVED;\r
+               }\r
+               if(bufLen + chunk_bytes > bufSize) {\r
+                       void *ptr;\r
+                       bufSize = chunk_bytes + (bufSize << 2);\r
+                       ptr = REALLOC(buf, bufSize);\r
+                       if(!ptr) {\r
+                               FREEMEM(buf);\r
+                               ASN__DECODE_FAILED;\r
+                       }\r
+                       buf = ptr;\r
+               }\r
+               if(per_get_many_bits(pd, buf + bufLen, 0, chunk_bytes << 3)) {\r
+                       FREEMEM(buf);\r
+                       ASN__DECODE_STARVED;\r
+               }\r
+               bufLen += chunk_bytes;\r
+       } while(repeat);\r
+\r
+       ASN_DEBUG("Getting open type %s encoded in %ld bytes", td->name,\r
+               (long)bufLen);\r
+\r
+       memset(&spd, 0, sizeof(spd));\r
+       spd.buffer = buf;\r
+       spd.nbits = bufLen << 3;\r
+\r
+       ASN_DEBUG_INDENT_ADD(+4);\r
+       rv = td->op->uper_decoder(ctx, td, constraints, sptr, &spd);\r
+       ASN_DEBUG_INDENT_ADD(-4);\r
+\r
+       if(rv.code == RC_OK) {\r
+               /* Check padding validity */\r
+               padding = spd.nbits - spd.nboff;\r
+                if (((padding > 0 && padding < 8) ||\r
+               /* X.691#10.1.3 */\r
+               (spd.nboff == 0 && spd.nbits == 8 && spd.buffer == buf)) &&\r
+                    per_get_few_bits(&spd, padding) == 0) {\r
+                       /* Everything is cool */\r
+                       FREEMEM(buf);\r
+                       return rv;\r
+               }\r
+               FREEMEM(buf);\r
+               if(padding >= 8) {\r
+                       ASN_DEBUG("Too large padding %d in open type", (int)padding);\r
+                       ASN__DECODE_FAILED;\r
+               } else {\r
+                       ASN_DEBUG("No padding");\r
+               }\r
+       } else {\r
+               FREEMEM(buf);\r
+               /* rv.code could be RC_WMORE, nonsense in this context */\r
+               rv.code = RC_FAIL; /* Noone would give us more */\r
+       }\r
+\r
+       return rv;\r
+}\r
+\r
+static asn_dec_rval_t CC_NOTUSED\r
+uper_open_type_get_complex(const asn_codec_ctx_t *ctx,\r
+                           const asn_TYPE_descriptor_t *td,\r
+                           asn_per_constraints_t *constraints, void **sptr,\r
+                           asn_per_data_t *pd) {\r
+    uper_ugot_key arg;\r
+       asn_dec_rval_t rv;\r
+       ssize_t padding;\r
+\r
+       ASN__STACK_OVERFLOW_CHECK(ctx);\r
+\r
+       ASN_DEBUG("Getting open type %s from %s", td->name,\r
+               asn_bit_data_string(pd));\r
+       arg.oldpd = *pd;\r
+       arg.unclaimed = 0;\r
+       arg.ot_moved = 0;\r
+       arg.repeat = 1;\r
+       pd->refill = uper_ugot_refill;\r
+       pd->refill_key = &arg;\r
+       pd->nbits = pd->nboff;  /* 0 good bits at this point, will refill */\r
+       pd->moved = 0;  /* This now counts the open type size in bits */\r
+\r
+       ASN_DEBUG_INDENT_ADD(+4);\r
+       rv = td->op->uper_decoder(ctx, td, constraints, sptr, pd);\r
+       ASN_DEBUG_INDENT_ADD(-4);\r
+\r
+#define        UPDRESTOREPD    do {                                            \\r
+       /* buffer and nboff are valid, preserve them. */                \\r
+       pd->nbits = arg.oldpd.nbits - (pd->moved - arg.ot_moved);       \\r
+       pd->moved = arg.oldpd.moved + (pd->moved - arg.ot_moved);       \\r
+       pd->refill = arg.oldpd.refill;                                  \\r
+       pd->refill_key = arg.oldpd.refill_key;                          \\r
+  } while(0)\r
+\r
+       if(rv.code != RC_OK) {\r
+               UPDRESTOREPD;\r
+               return rv;\r
+       }\r
+\r
+       ASN_DEBUG("OpenType %s pd%s old%s unclaimed=%d, repeat=%d", td->name,\r
+               asn_bit_data_string(pd),\r
+               asn_bit_data_string(&arg.oldpd),\r
+               (int)arg.unclaimed, (int)arg.repeat);\r
+\r
+       padding = pd->moved % 8;\r
+       if(padding) {\r
+               int32_t pvalue;\r
+               if(padding > 7) {\r
+                       ASN_DEBUG("Too large padding %d in open type",\r
+                               (int)padding);\r
+                       rv.code = RC_FAIL;\r
+                       UPDRESTOREPD;\r
+                       return rv;\r
+               }\r
+               padding = 8 - padding;\r
+               ASN_DEBUG("Getting padding of %d bits", (int)padding);\r
+               pvalue = per_get_few_bits(pd, padding);\r
+               switch(pvalue) {\r
+               case -1:\r
+                       ASN_DEBUG("Padding skip failed");\r
+                       UPDRESTOREPD;\r
+                       ASN__DECODE_STARVED;\r
+               case 0: break;\r
+               default:\r
+                       ASN_DEBUG("Non-blank padding (%d bits 0x%02x)",\r
+                               (int)padding, (int)pvalue);\r
+                       UPDRESTOREPD;\r
+                       ASN__DECODE_FAILED;\r
+               }\r
+       }\r
+       if(pd->nboff != pd->nbits) {\r
+               ASN_DEBUG("Open type %s overhead pd%s old%s", td->name,\r
+                       asn_bit_data_string(pd), asn_bit_data_string(&arg.oldpd));\r
+               if(1) {\r
+                       UPDRESTOREPD;\r
+                       ASN__DECODE_FAILED;\r
+               } else {\r
+                       arg.unclaimed += pd->nbits - pd->nboff;\r
+               }\r
+       }\r
+\r
+       /* Adjust pd back so it points to original data */\r
+       UPDRESTOREPD;\r
+\r
+       /* Skip data not consumed by the decoder */\r
+       if(arg.unclaimed) {\r
+               ASN_DEBUG("Getting unclaimed %d", (int)arg.unclaimed);\r
+               switch(per_skip_bits(pd, arg.unclaimed)) {\r
+               case -1:\r
+                       ASN_DEBUG("Claim of %d failed", (int)arg.unclaimed);\r
+                       ASN__DECODE_STARVED;\r
+               case 0:\r
+                       ASN_DEBUG("Got claim of %d", (int)arg.unclaimed);\r
+                       break;\r
+               default:\r
+                       /* Padding must be blank */\r
+                       ASN_DEBUG("Non-blank unconsumed padding");\r
+                       ASN__DECODE_FAILED;\r
+               }\r
+               arg.unclaimed = 0;\r
+       }\r
+\r
+       if(arg.repeat) {\r
+               ASN_DEBUG("Not consumed the whole thing");\r
+               rv.code = RC_FAIL;\r
+               return rv;\r
+       }\r
+\r
+       return rv;\r
+}\r
+\r
+\r
+asn_dec_rval_t\r
+uper_open_type_get(const asn_codec_ctx_t *ctx, const asn_TYPE_descriptor_t *td,\r
+                   const asn_per_constraints_t *constraints, void **sptr,\r
+                   asn_per_data_t *pd) {\r
+    return uper_open_type_get_simple(ctx, td, constraints, sptr, pd);\r
+}\r
+\r
+int\r
+uper_open_type_skip(const asn_codec_ctx_t *ctx, asn_per_data_t *pd) {\r
+       asn_TYPE_descriptor_t s_td;\r
+    asn_TYPE_operation_t s_op;\r
+       asn_dec_rval_t rv;\r
+\r
+       s_td.name = "<unknown extension>";\r
+       s_td.op = &s_op;\r
+    s_op.uper_decoder = uper_sot_suck;\r
+\r
+       rv = uper_open_type_get(ctx, &s_td, 0, 0, pd);\r
+       if(rv.code != RC_OK)\r
+               return -1;\r
+       else\r
+               return 0;\r
+}\r
+\r
+/*\r
+ * Internal functions.\r
+ */\r
+\r
+static asn_dec_rval_t\r
+uper_sot_suck(const asn_codec_ctx_t *ctx, const asn_TYPE_descriptor_t *td,\r
+              const asn_per_constraints_t *constraints, void **sptr,\r
+              asn_per_data_t *pd) {\r
+    asn_dec_rval_t rv;\r
+\r
+       (void)ctx;\r
+       (void)td;\r
+       (void)constraints;\r
+       (void)sptr;\r
+\r
+       while(per_get_few_bits(pd, 1) >= 0);\r
+\r
+       rv.code = RC_OK;\r
+       rv.consumed = pd->moved;\r
+\r
+       return rv;\r
+}\r
+\r
+static int\r
+uper_ugot_refill(asn_per_data_t *pd) {\r
+       uper_ugot_key *arg = pd->refill_key;\r
+       ssize_t next_chunk_bytes, next_chunk_bits;\r
+       ssize_t avail;\r
+\r
+       asn_per_data_t *oldpd = &arg->oldpd;\r
+\r
+       ASN_DEBUG("REFILLING pd->moved=%ld, oldpd->moved=%ld",\r
+               (long)pd->moved, (long)oldpd->moved);\r
+\r
+       /* Advance our position to where pd is */\r
+       oldpd->buffer = pd->buffer;\r
+       oldpd->nboff  = pd->nboff;\r
+       oldpd->nbits -= pd->moved - arg->ot_moved;\r
+       oldpd->moved += pd->moved - arg->ot_moved;\r
+       arg->ot_moved = pd->moved;\r
+\r
+       if(arg->unclaimed) {\r
+               /* Refill the container */\r
+               if(per_get_few_bits(oldpd, 1))\r
+                       return -1;\r
+               if(oldpd->nboff == 0) {\r
+                       assert(0);\r
+                       return -1;\r
+               }\r
+               pd->buffer = oldpd->buffer;\r
+               pd->nboff = oldpd->nboff - 1;\r
+               pd->nbits = oldpd->nbits;\r
+               ASN_DEBUG("UNCLAIMED <- return from (pd->moved=%ld)",\r
+                       (long)pd->moved);\r
+               return 0;\r
+       }\r
+\r
+       if(!arg->repeat) {\r
+               ASN_DEBUG("Want more but refill doesn't have it");\r
+               return -1;\r
+       }\r
+\r
+       next_chunk_bytes = uper_get_length(oldpd, -1, 0, &arg->repeat);\r
+       ASN_DEBUG("Open type LENGTH %ld bytes at off %ld, repeat %ld",\r
+               (long)next_chunk_bytes, (long)oldpd->moved, (long)arg->repeat);\r
+       if(next_chunk_bytes < 0) return -1;\r
+       if(next_chunk_bytes == 0) {\r
+               pd->refill = 0; /* No more refills, naturally */\r
+               assert(!arg->repeat);   /* Implementation guarantee */\r
+       }\r
+       next_chunk_bits = next_chunk_bytes << 3;\r
+       avail = oldpd->nbits - oldpd->nboff;\r
+       if(avail >= next_chunk_bits) {\r
+               pd->nbits = oldpd->nboff + next_chunk_bits;\r
+               arg->unclaimed = 0;\r
+               ASN_DEBUG("!+Parent frame %ld bits, alloting %ld [%ld..%ld] (%ld)",\r
+                       (long)next_chunk_bits, (long)oldpd->moved,\r
+                       (long)oldpd->nboff, (long)oldpd->nbits,\r
+                       (long)(oldpd->nbits - oldpd->nboff));\r
+       } else {\r
+               pd->nbits = oldpd->nbits;\r
+               arg->unclaimed = next_chunk_bits - avail;\r
+               ASN_DEBUG("!-Parent frame %ld, require %ld, will claim %ld",\r
+                       (long)avail, (long)next_chunk_bits,\r
+                       (long)arg->unclaimed);\r
+       }\r
+       pd->buffer = oldpd->buffer;\r
+       pd->nboff = oldpd->nboff;\r
+       ASN_DEBUG("Refilled pd%s old%s",\r
+               asn_bit_data_string(pd), asn_bit_data_string(oldpd));\r
+       return 0;\r
+}\r
+\r
+static int\r
+per_skip_bits(asn_per_data_t *pd, int skip_nbits) {\r
+       int hasNonZeroBits = 0;\r
+       while(skip_nbits > 0) {\r
+               int skip;\r
+\r
+               /* per_get_few_bits() is more efficient when nbits <= 24 */\r
+               if(skip_nbits < 24)\r
+                       skip = skip_nbits;\r
+               else\r
+                       skip = 24;\r
+               skip_nbits -= skip;\r
+\r
+               switch(per_get_few_bits(pd, skip)) {\r
+               case -1: return -1;     /* Starving */\r
+               case 0: continue;       /* Skipped empty space */\r
+               default: hasNonZeroBits = 1; continue;\r
+               }\r
+       }\r
+       return hasNonZeroBits;\r
+}\r
+\r
+static asn_dec_rval_t\r
+aper_open_type_get_simple(const asn_codec_ctx_t *ctx,\r
+                          const asn_TYPE_descriptor_t *td,\r
+                          const asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) {\r
+       asn_dec_rval_t rv;\r
+       ssize_t chunk_bytes;\r
+       int repeat;\r
+       uint8_t *buf = 0;\r
+       size_t bufLen = 0;\r
+       size_t bufSize = 0;\r
+       asn_per_data_t spd;\r
+       size_t padding;\r
+\r
+       ASN__STACK_OVERFLOW_CHECK(ctx);\r
+\r
+       ASN_DEBUG("Getting open type %s...", td->name);\r
+\r
+       do {\r
+               chunk_bytes = aper_get_length(pd, -1, -1, &repeat);\r
+               if(chunk_bytes < 0) {\r
+                       FREEMEM(buf);\r
+                       ASN__DECODE_STARVED;\r
+               }\r
+               if(bufLen + chunk_bytes > bufSize) {\r
+                       void *ptr;\r
+                       bufSize = chunk_bytes + (bufSize << 2);\r
+                       ptr = REALLOC(buf, bufSize);\r
+                       if(!ptr) {\r
+                               FREEMEM(buf);\r
+                               ASN__DECODE_FAILED;\r
+                       }\r
+                       buf = ptr;\r
+               }\r
+               if(per_get_many_bits(pd, buf + bufLen, 0, chunk_bytes << 3)) {\r
+                       FREEMEM(buf);\r
+                       ASN__DECODE_STARVED;\r
+               }\r
+               bufLen += chunk_bytes;\r
+       } while(repeat);\r
+\r
+       ASN_DEBUG("Getting open type %s encoded in %ld bytes", td->name,\r
+               (long)bufLen);\r
+\r
+       memset(&spd, 0, sizeof(spd));\r
+       spd.buffer = buf;\r
+       spd.nbits = bufLen << 3;\r
+\r
+       ASN_DEBUG_INDENT_ADD(+4);\r
+       rv = td->op->aper_decoder(ctx, td, constraints, sptr, &spd);\r
+       ASN_DEBUG_INDENT_ADD(-4);\r
+\r
+       if(rv.code == RC_OK) {\r
+               /* Check padding validity */\r
+               padding = spd.nbits - spd.nboff;\r
+                if (((padding > 0 && padding < 8) ||\r
+               /* X.691#10.1.3 */\r
+               (spd.nboff == 0 && spd.nbits == 8 && spd.buffer == buf)) &&\r
+                    per_get_few_bits(&spd, padding) == 0) {\r
+                       /* Everything is cool */\r
+                       FREEMEM(buf);\r
+                       return rv;\r
+               }\r
+               FREEMEM(buf);\r
+               if(padding >= 8) {\r
+                       ASN_DEBUG("Too large padding %d in open type", (int)padding);\r
+                       ASN__DECODE_FAILED;\r
+               } else {\r
+                       ASN_DEBUG("No padding");\r
+               }\r
+       } else {\r
+               FREEMEM(buf);\r
+               /* rv.code could be RC_WMORE, nonsense in this context */\r
+               rv.code = RC_FAIL; /* Noone would give us more */\r
+       }\r
+\r
+       return rv;\r
+}\r
+\r
+int\r
+aper_open_type_put(const asn_TYPE_descriptor_t *td,\r
+                   const asn_per_constraints_t *constraints,\r
+                   const void *sptr, asn_per_outp_t *po) {\r
+       void *buf;\r
+       void *bptr;\r
+       ssize_t size;\r
+       size_t toGo;\r
+\r
+       ASN_DEBUG("Open type put %s ...", td->name);\r
+\r
+       size = aper_encode_to_new_buffer(td, constraints, sptr, &buf);\r
+       if(size <= 0) return -1;\r
+\r
+       for(bptr = buf, toGo = size; toGo;) {\r
+               ssize_t maySave = aper_put_length(po, -1, toGo);\r
+               if(maySave < 0) break;\r
+               if(per_put_many_bits(po, bptr, maySave * 8)) break;\r
+               bptr = (char *)bptr + maySave;\r
+               toGo -= maySave;\r
+       }\r
+\r
+       FREEMEM(buf);\r
+       if(toGo) return -1;\r
+\r
+       ASN_DEBUG("Open type put %s of length %ld + overhead (1byte?)",\r
+                         td->name, size);\r
+\r
+       return 0;\r
+}\r
+\r
+asn_dec_rval_t\r
+aper_open_type_get(const asn_codec_ctx_t *ctx,\r
+                   const asn_TYPE_descriptor_t *td,\r
+                   const asn_per_constraints_t *constraints,\r
+                   void **sptr, asn_per_data_t *pd) {\r
+\r
+       return aper_open_type_get_simple(ctx, td, constraints, sptr, pd);\r
+}\r
+\r
+int\r
+aper_open_type_skip(const asn_codec_ctx_t *ctx, asn_per_data_t *pd) {\r
+       asn_TYPE_descriptor_t s_td;\r
+       asn_dec_rval_t rv;\r
+       asn_TYPE_operation_t op_t;\r
+\r
+       memset(&op_t, 0, sizeof(op_t));\r
+       s_td.name = "<unknown extension>";\r
+       s_td.op = &op_t;\r
+       s_td.op->aper_decoder = uper_sot_suck;\r
+\r
+       rv = aper_open_type_get(ctx, &s_td, 0, 0, pd);\r
+       if(rv.code != RC_OK)\r
+               return -1;\r
+       else\r
+               return 0;\r
+}\r
+\r
+\r