aboutsummaryrefslogtreecommitdiff
path: root/src/value.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/value.c')
-rw-r--r--src/value.c45
1 files changed, 45 insertions, 0 deletions
diff --git a/src/value.c b/src/value.c
new file mode 100644
index 0000000..690527f
--- /dev/null
+++ b/src/value.c
@@ -0,0 +1,45 @@
+#include "../include/value.h"
+#include <string.h>
+
+static uint64_t hash_range(const uint8_t *data, size_t size) {
+ uint64_t result = 0xdec05eba;
+ while(size) {
+ result = ((result << 5) + result) + *data;
+ ++data;
+ --size;
+ }
+ return result;
+}
+
+uint64_t tsl_value_hash(const TslValue *key) {
+ switch(key->type) {
+ case TSL_TYPE_NULL:
+ return 0;
+ case TSL_TYPE_NUMBER:
+ return *(uint64_t*)&key->data.number;
+ case TSL_TYPE_STRING:
+ return hash_range(key->data.string->data, key->data.string->size);
+ case TSL_TYPE_BOOL:
+ return key->data.boolean;
+ case TSL_TYPE_LIST:
+ return (uint64_t)key->data.list;
+ case TSL_TYPE_MAP:
+ return (uint64_t)key->data.map;
+ case TSL_TYPE_USERDATA:
+ return (uint64_t)key->data.userdata;
+ }
+ return 0;
+}
+
+int tsl_value_equals(const TslValue *lhs, const TslValue *rhs) {
+ if(lhs->type == rhs->type) {
+ if(lhs->type == TSL_TYPE_STRING) {
+ return lhs->data.string->size == rhs->data.string->size
+ && memcmp(lhs->data.string->data, rhs->data.string->data, lhs->data.string->size) == 0;
+ } else {
+ return *(uint64_t*)&lhs->data == *(uint64_t*)&rhs->data;
+ }
+ } else {
+ return 0;
+ }
+}