Adding initial code jy.oak@samsung.com
[ric-app/kpimon.git] / asn1c_defs / all-defs / ber_tlv_tag.c
diff --git a/asn1c_defs/all-defs/ber_tlv_tag.c b/asn1c_defs/all-defs/ber_tlv_tag.c
new file mode 100755 (executable)
index 0000000..219b3e6
--- /dev/null
@@ -0,0 +1,144 @@
+/*-\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_tag.h>\r
+#include <errno.h>\r
+\r
+ssize_t\r
+ber_fetch_tag(const void *ptr, size_t size, ber_tlv_tag_t *tag_r) {\r
+       ber_tlv_tag_t val;\r
+       ber_tlv_tag_t tclass;\r
+       size_t skipped;\r
+\r
+       if(size == 0)\r
+               return 0;\r
+\r
+       val = *(const uint8_t *)ptr;\r
+       tclass = (val >> 6);\r
+       if((val &= 0x1F) != 0x1F) {\r
+               /*\r
+                * Simple form: everything encoded in a single octet.\r
+                * Tag Class is encoded using two least significant bits.\r
+                */\r
+               *tag_r = (val << 2) | tclass;\r
+               return 1;\r
+       }\r
+\r
+       /*\r
+        * Each octet contains 7 bits of useful information.\r
+        * The MSB is 0 if it is the last octet of the tag.\r
+        */\r
+       for(val = 0, ptr = ((const char *)ptr) + 1, skipped = 2;\r
+                       skipped <= size;\r
+                               ptr = ((const char *)ptr) + 1, skipped++) {\r
+               unsigned int oct = *(const uint8_t *)ptr;\r
+               if(oct & 0x80) {\r
+                       val = (val << 7) | (oct & 0x7F);\r
+                       /*\r
+                        * Make sure there are at least 9 bits spare\r
+                        * at the MS side of a value.\r
+                        */\r
+                       if(val >> ((8 * sizeof(val)) - 9)) {\r
+                               /*\r
+                                * We would not be able to accomodate\r
+                                * any more tag bits.\r
+                                */\r
+                               return -1;\r
+                       }\r
+               } else {\r
+                       val = (val << 7) | oct;\r
+                       *tag_r = (val << 2) | tclass;\r
+                       return skipped;\r
+               }\r
+       }\r
+\r
+       return 0;       /* Want more */\r
+}\r
+\r
+\r
+ssize_t\r
+ber_tlv_tag_fwrite(ber_tlv_tag_t tag, FILE *f) {\r
+       char buf[sizeof("[APPLICATION ]") + 32];\r
+       ssize_t ret;\r
+\r
+       ret = ber_tlv_tag_snprint(tag, buf, sizeof(buf));\r
+       if(ret >= (ssize_t)sizeof(buf) || ret < 2) {\r
+               errno = EPERM;\r
+               return -1;\r
+       }\r
+\r
+       return fwrite(buf, 1, ret, f);\r
+}\r
+\r
+ssize_t\r
+ber_tlv_tag_snprint(ber_tlv_tag_t tag, char *buf, size_t size) {\r
+       const char *type = 0;\r
+       int ret;\r
+\r
+       switch(tag & 0x3) {\r
+       case ASN_TAG_CLASS_UNIVERSAL:   type = "UNIVERSAL ";    break;\r
+       case ASN_TAG_CLASS_APPLICATION: type = "APPLICATION ";  break;\r
+       case ASN_TAG_CLASS_CONTEXT:     type = "";              break;\r
+       case ASN_TAG_CLASS_PRIVATE:     type = "PRIVATE ";      break;\r
+       }\r
+\r
+       ret = snprintf(buf, size, "[%s%u]", type, ((unsigned)tag) >> 2);\r
+       if(ret <= 0 && size) buf[0] = '\0';     /* against broken libc's */\r
+\r
+       return ret;\r
+}\r
+\r
+char *\r
+ber_tlv_tag_string(ber_tlv_tag_t tag) {\r
+       static char buf[sizeof("[APPLICATION ]") + 32];\r
+\r
+       (void)ber_tlv_tag_snprint(tag, buf, sizeof(buf));\r
+\r
+       return buf;\r
+}\r
+\r
+\r
+size_t\r
+ber_tlv_tag_serialize(ber_tlv_tag_t tag, void *bufp, size_t size) {\r
+       int tclass = BER_TAG_CLASS(tag);\r
+       ber_tlv_tag_t tval = BER_TAG_VALUE(tag);\r
+       uint8_t *buf = (uint8_t *)bufp;\r
+       uint8_t *end;\r
+       size_t required_size;\r
+       size_t i;\r
+\r
+       if(tval <= 30) {\r
+               /* Encoded in 1 octet */\r
+               if(size) buf[0] = (tclass << 6) | tval;\r
+               return 1;\r
+       } else if(size) {\r
+               *buf++ = (tclass << 6) | 0x1F;\r
+               size--;\r
+       }\r
+\r
+       /*\r
+        * Compute the size of the subsequent bytes.\r
+        */\r
+       for(required_size = 1, i = 7; i < 8 * sizeof(tval); i += 7) {\r
+               if(tval >> i)\r
+                       required_size++;\r
+               else\r
+                       break;\r
+       }\r
+\r
+       if(size < required_size)\r
+               return required_size + 1;\r
+\r
+       /*\r
+        * Fill in the buffer, space permitting.\r
+        */\r
+       end = buf + required_size - 1;\r
+       for(i -= 7; buf < end; i -= 7, buf++)\r
+               *buf = 0x80 | ((tval >> i) & 0x7F);\r
+       *buf = (tval & 0x7F);   /* Last octet without high bit */\r
+\r
+       return required_size + 1;\r
+}\r
+\r