Adding initial code jy.oak@samsung.com
[ric-app/kpimon.git] / asn1c_defs / all-defs / asn_random_fill.c
diff --git a/asn1c_defs/all-defs/asn_random_fill.c b/asn1c_defs/all-defs/asn_random_fill.c
new file mode 100755 (executable)
index 0000000..2496a0f
--- /dev/null
@@ -0,0 +1,56 @@
+/*\r
+ * Copyright (c) 2017 Lev Walkin <vlm@lionet.info>.\r
+ * All rights reserved.\r
+ * Redistribution and modifications are permitted subject to BSD license.\r
+ */\r
+#include <asn_internal.h>\r
+#include <asn_random_fill.h>\r
+#include <constr_TYPE.h>\r
+\r
+int\r
+asn_random_fill(const struct asn_TYPE_descriptor_s *td, void **struct_ptr,\r
+                size_t length) {\r
+\r
+    if(td && td->op->random_fill) {\r
+        asn_random_fill_result_t res =\r
+            td->op->random_fill(td, struct_ptr, 0, length);\r
+        return (res.code == ARFILL_OK) ? 0 : -1;\r
+    } else {\r
+        return -1;\r
+    }\r
+}\r
+\r
+static uintmax_t\r
+asn__intmax_range(intmax_t lb, intmax_t ub) {\r
+    assert(lb <= ub);\r
+    if((ub < 0) == (lb < 0)) {\r
+        return ub - lb;\r
+    } else if(lb < 0) {\r
+        return 1 + ((uintmax_t)ub + (uintmax_t)-(lb + 1));\r
+    } else {\r
+        assert(!"Unreachable");\r
+        return 0;\r
+    }\r
+}\r
+\r
+intmax_t\r
+asn_random_between(intmax_t lb, intmax_t rb) {\r
+    if(lb == rb) {\r
+        return lb;\r
+    } else {\r
+        const uintmax_t intmax_max = ((~(uintmax_t)0) >> 1);\r
+        uintmax_t range = asn__intmax_range(lb, rb);\r
+        uintmax_t value = 0;\r
+        uintmax_t got_entropy = 0;\r
+\r
+        assert(RAND_MAX > 0xffffff);    /* Seen 7ffffffd! */\r
+        assert(range < intmax_max);\r
+\r
+        for(; got_entropy < range;) {\r
+            got_entropy = (got_entropy << 24) | 0xffffff;\r
+            value = (value << 24) | (random() % 0xffffff);\r
+        }\r
+\r
+        return lb + (intmax_t)(value % (range + 1));\r
+    }\r
+}\r