Adding initial code jy.oak@samsung.com
[ric-app/kpimon.git] / asn1c_defs / all-defs / ber_tlv_length.c
diff --git a/asn1c_defs/all-defs/ber_tlv_length.c b/asn1c_defs/all-defs/ber_tlv_length.c
new file mode 100755 (executable)
index 0000000..11234c9
--- /dev/null
@@ -0,0 +1,168 @@
+/*-\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 <ber_tlv_length.h>\r
+#include <ber_tlv_tag.h>\r
+\r
+ssize_t\r
+ber_fetch_length(int _is_constructed, const void *bufptr, size_t size,\r
+               ber_tlv_len_t *len_r) {\r
+       const uint8_t *buf = (const uint8_t *)bufptr;\r
+       unsigned oct;\r
+\r
+       if(size == 0)\r
+               return 0;       /* Want more */\r
+\r
+       oct = *(const uint8_t *)buf;\r
+       if((oct & 0x80) == 0) {\r
+               /*\r
+                * Short definite length.\r
+                */\r
+               *len_r = oct;   /* & 0x7F */\r
+               return 1;\r
+       } else {\r
+               ber_tlv_len_t len;\r
+               size_t skipped;\r
+\r
+               if(_is_constructed && oct == 0x80) {\r
+                       *len_r = -1;    /* Indefinite length */\r
+                       return 1;\r
+               }\r
+\r
+               if(oct == 0xff) {\r
+                       /* Reserved in standard for future use. */\r
+                       return -1;\r
+               }\r
+\r
+               oct &= 0x7F;    /* Leave only the 7 LS bits */\r
+               for(len = 0, buf++, skipped = 1;\r
+                       oct && (++skipped <= size); buf++, oct--) {\r
+\r
+                       /* Verify that we won't overflow. */\r
+                       if(!(len >> ((8 * sizeof(len)) - (8+1)))) {\r
+                               len = (len << 8) | *buf;\r
+                       } else {\r
+                               /* Too large length value. */\r
+                               return -1;\r
+                       }\r
+               }\r
+\r
+               if(oct == 0) {\r
+                       if(len < 0 || len > RSSIZE_MAX) {\r
+                               /* Length value out of sane range. */\r
+                               return -1;\r
+                       }\r
+\r
+                       *len_r = len;\r
+                       return skipped;\r
+               }\r
+\r
+               return 0;       /* Want more */\r
+       }\r
+\r
+}\r
+\r
+ssize_t\r
+ber_skip_length(const asn_codec_ctx_t *opt_codec_ctx,\r
+               int _is_constructed, const void *ptr, size_t size) {\r
+       ber_tlv_len_t vlen;     /* Length of V in TLV */\r
+       ssize_t tl;             /* Length of L in TLV */\r
+       ssize_t ll;             /* Length of L in TLV */\r
+       size_t skip;\r
+\r
+       /*\r
+        * Make sure we didn't exceed the maximum stack size.\r
+        */\r
+       if(ASN__STACK_OVERFLOW_CHECK(opt_codec_ctx))\r
+               return -1;\r
+\r
+       /*\r
+        * Determine the size of L in TLV.\r
+        */\r
+       ll = ber_fetch_length(_is_constructed, ptr, size, &vlen);\r
+       if(ll <= 0) return ll;\r
+\r
+       /*\r
+        * Definite length.\r
+        */\r
+       if(vlen >= 0) {\r
+               skip = ll + vlen;\r
+               if(skip > size)\r
+                       return 0;       /* Want more */\r
+               return skip;\r
+       }\r
+\r
+       /*\r
+        * Indefinite length!\r
+        */\r
+       ASN_DEBUG("Skipping indefinite length");\r
+       for(skip = ll, ptr = ((const char *)ptr) + ll, size -= ll;;) {\r
+               ber_tlv_tag_t tag;\r
+\r
+               /* Fetch the tag */\r
+               tl = ber_fetch_tag(ptr, size, &tag);\r
+               if(tl <= 0) return tl;\r
+\r
+               ll = ber_skip_length(opt_codec_ctx,\r
+                       BER_TLV_CONSTRUCTED(ptr),\r
+                       ((const char *)ptr) + tl, size - tl);\r
+               if(ll <= 0) return ll;\r
+\r
+               skip += tl + ll;\r
+\r
+               /*\r
+                * This may be the end of the indefinite length structure,\r
+                * two consecutive 0 octets.\r
+                * Check if it is true.\r
+                */\r
+               if(((const uint8_t *)ptr)[0] == 0\r
+               && ((const uint8_t *)ptr)[1] == 0)\r
+                       return skip;\r
+\r
+               ptr = ((const char *)ptr) + tl + ll;\r
+               size -= tl + ll;\r
+       }\r
+\r
+       /* UNREACHABLE */\r
+}\r
+\r
+size_t\r
+der_tlv_length_serialize(ber_tlv_len_t len, void *bufp, size_t size) {\r
+       size_t required_size;   /* Size of len encoding */\r
+       uint8_t *buf = (uint8_t *)bufp;\r
+       uint8_t *end;\r
+       int i;\r
+\r
+       if(len <= 127) {\r
+               /* Encoded in 1 octet */\r
+               if(size) *buf = (uint8_t)len;\r
+               return 1;\r
+       }\r
+\r
+       /*\r
+        * Compute the size of the subsequent bytes.\r
+        */\r
+       for(required_size = 1, i = 8; i < 8 * (int)sizeof(len); i += 8) {\r
+               if(len >> i)\r
+                       required_size++;\r
+               else\r
+                       break;\r
+       }\r
+\r
+       if(size <= required_size)\r
+               return required_size + 1;\r
+\r
+       *buf++ = (uint8_t)(0x80 | required_size);  /* Length of the encoding */\r
+\r
+       /*\r
+        * Produce the len encoding, space permitting.\r
+        */\r
+       end = buf + required_size;\r
+       for(i -= 8; buf < end; i -= 8, buf++)\r
+               *buf = (uint8_t)(len >> i);\r
+\r
+       return required_size + 1;\r
+}\r
+\r