/* This software is licensed by the MIT License, see LICENSE file */ /* Copyright © 2022 Gregory Lirent */ #include "__internal/assert.h" #include "__internal/vnode.h" /*#####################################################################################################################*/ static vnode_t create_number(vtype xt, const void* v, vtype t) { var_t _ = { .ptr = 0 }; if (t == VTYPE_POINTER) t = (sizeof(void*) == 8) ? VTYPE_UINT64 : VTYPE_UINT32; if (t == VTYPE_BOOLEAN) t = VTYPE_UINT8; if (xt == VTYPE_POINTER) xt = (sizeof(void*) == 8) ? VTYPE_UINT64 : VTYPE_UINT32; if (xt == VTYPE_BOOLEAN) xt = VTYPE_UINT8; switch (xt) { default: default_: abort(); case VTYPE_INT8: case VTYPE_UINT8: switch (t) { default: goto default_; case VTYPE_INT8: case VTYPE_UINT8: _.u8 = *(u8_t*)v; break; case VTYPE_INT16: case VTYPE_UINT16: _.u8 = *(u16_t*)v; break; case VTYPE_INT32: case VTYPE_UINT32: _.u8 = *(u32_t*)v; break; case VTYPE_INT64: case VTYPE_UINT64: _.u8 = *(u64_t*)v; break; } break; case VTYPE_INT16: case VTYPE_UINT16: switch (t) { default: goto default_; case VTYPE_INT8: case VTYPE_UINT8: _.u16 = *(u8_t*)v; break; case VTYPE_INT16: case VTYPE_UINT16: _.u16 = *(u16_t*)v; break; case VTYPE_INT32: case VTYPE_UINT32: _.u16 = *(u32_t*)v; break; case VTYPE_INT64: case VTYPE_UINT64: _.u16 = *(u64_t*)v; break; } break; case VTYPE_INT32: case VTYPE_UINT32: switch (t) { default: goto default_; case VTYPE_INT8: case VTYPE_UINT8: _.u32 = *(u8_t*)v; break; case VTYPE_INT16: case VTYPE_UINT16: _.u32 = *(u16_t*)v; break; case VTYPE_INT32: case VTYPE_UINT32: _.u32 = *(u32_t*)v; break; case VTYPE_INT64: case VTYPE_UINT64: _.u32 = *(u64_t*)v; break; } break; case VTYPE_INT64: case VTYPE_UINT64: switch (t) { default: goto default_; case VTYPE_INT8: case VTYPE_UINT8: _.u64 = *(u8_t*)v; goto u64_; case VTYPE_INT16: case VTYPE_UINT16: _.u64 = *(u16_t*)v; goto u64_; case VTYPE_INT32: case VTYPE_UINT32: _.u64 = *(u32_t*)v; goto u64_; case VTYPE_INT64: case VTYPE_UINT64: _.u64 = *(u64_t*)v; u64_: if (!is_x64) _.ptr = memndup(&_.u64, sizeof(_.u64)); break; } break; case VTYPE_FLOAT: switch (t) { default: goto default_; case VTYPE_DOUBLE: _.f = *(dbl_t*)v; goto f_; case VTYPE_LDOUBLE: _.f = *(ldbl_t*)v; goto f_; case VTYPE_FLOAT: _.f = *(fl_t*)v; f_: if (!is_permissible(fl_t)) _.ptr = memndup(&_.f, sizeof(_.f)); break; } break; case VTYPE_DOUBLE: switch (t) { default: goto default_; case VTYPE_FLOAT: _.d = *(fl_t*)v; goto d_; case VTYPE_LDOUBLE: _.d = *(ldbl_t*)v; goto d_; case VTYPE_DOUBLE: _.d = *(dbl_t*)v; d_: if (!is_permissible(dbl_t)) _.ptr = memndup(&_.d, sizeof(_.d)); break; } break; case VTYPE_LDOUBLE: switch (t) { default: goto default_; case VTYPE_FLOAT: _.ld = *(fl_t*)v; goto ld_; case VTYPE_DOUBLE: _.ld = *(dbl_t*)v; goto ld_; case VTYPE_LDOUBLE: _.ld = *(ldbl_t*)v; ld_: if (!is_permissible(ldbl_t)) _.ptr = memndup(&_.ld, sizeof(_.ld)); break; } break; } return _.ptr; } /*#####################################################################################################################*/ vnode_t hhttpc_vnode_create(const void* v, vtype t) { var_t _ = { .ptr = 0 }; switch (t) { default: abort(); case VTYPE_INT8: case VTYPE_UINT8: _.u8 = *(u8_t*)v; break; case VTYPE_INT16: case VTYPE_UINT16: _.u16 = *(u16_t*)v; break; case VTYPE_INT32: case VTYPE_UINT32: _.u32 = *(u32_t*)v; break; case VTYPE_INT64: case VTYPE_UINT64: u64_: if (is_x64) _.u64 = *(u64_t*)v; else _.ptr = memndup(v, sizeof(u64_t)); break; case VTYPE_FLOAT: if (is_permissible(fl_t)) _.ld = *(fl_t*)v; else _.ptr = memndup(v, sizeof(fl_t)); break; case VTYPE_DOUBLE: if (is_permissible(dbl_t)) _.ld = *(dbl_t*)v; else _.ptr = memndup(v, sizeof(dbl_t)); break; case VTYPE_LDOUBLE: if (is_permissible(ldbl_t)) _.ld = *(ldbl_t*)v; else _.ptr = memndup(v, sizeof(ldbl_t)); break; case VTYPE_BOOLEAN: _.b = *(_Bool*)v; break; case VTYPE_POINTER: _.ptr = *(void**)v; break; case VTYPE_STRING: _.ptr = string_duplicate(v); break; case VTYPE_MAP: _.ptr = map_duplicate(v); break; case VTYPE_ARRAY: _.ptr = array_duplicate(v); break; case VTYPE_LIST: _.ptr = list_duplicate(v); break; case VTYPE_SET: _.ptr = vset_duplicate(v); break; } return _.ptr; } /*#####################################################################################################################*/ void* libcdsb_vnode_peek(const vnode_t* x, vtype t) { switch (t) { default: abort(); case VTYPE_FLOAT: if (is_permissible(fl_t)) goto vt_; else goto pt_; case VTYPE_DOUBLE: if (is_permissible(dbl_t)) goto vt_; else goto pt_; case VTYPE_LDOUBLE: if (is_permissible(ldbl_t)) goto vt_; else goto pt_; case VTYPE_INT64: case VTYPE_UINT64: if (!is_x64) goto pt_; case VTYPE_BOOLEAN: case VTYPE_POINTER: case VTYPE_INT8: case VTYPE_UINT8: case VTYPE_INT16: case VTYPE_UINT16: case VTYPE_INT32: case VTYPE_UINT32: vt_: return (void*)x; case VTYPE_STRING: case VTYPE_MAP: case VTYPE_ARRAY: case VTYPE_LIST: case VTYPE_SET: pt_: return *x; } } void libcdsb_vnode_free(vnode_t* x, vtype t) { switch (t) { default: abort(); case VTYPE_FLOAT: if (is_permissible(fl_t)) goto vt_; else goto pt_; case VTYPE_DOUBLE: if (is_permissible(dbl_t)) goto vt_; else goto pt_; case VTYPE_LDOUBLE: if (is_permissible(ldbl_t)) goto vt_; else goto pt_; case VTYPE_INT64: case VTYPE_UINT64: if (!is_x64) goto pt_; case VTYPE_BOOLEAN: case VTYPE_POINTER: case VTYPE_INT8: case VTYPE_UINT8: case VTYPE_INT16: case VTYPE_UINT16: case VTYPE_INT32: case VTYPE_UINT32: vt_: break; case VTYPE_STRING: string_free(*x); goto pt_; case VTYPE_MAP: map_free(*x); goto pt_; case VTYPE_ARRAY: array_free(*x); goto pt_; case VTYPE_LIST: list_free(*x); goto pt_; case VTYPE_SET: vset_free(*x); pt_: free(*x); break; } *x = 0; } /*#####################################################################################################################*/ vnode_t libcdsb_vnode_create_target(vtype xt, const void* v, vtype t) { var_t _ = { .ptr = 0 }; if (is_integer(xt)) { tvalue_assert(t); return create_number(xt, v, t); } else if (is_float(xt)) { tfloat_assert(t); return create_number(xt, v, t); } type_assert(xt, t); switch (xt) { default: abort(); case VTYPE_STRING: _.ptr = string_duplicate(v); break; case VTYPE_MAP: _.ptr = map_duplicate(v); break; case VTYPE_ARRAY: _.ptr = array_duplicate(v); break; case VTYPE_LIST: _.ptr = list_duplicate(v); break; case VTYPE_SET: _.ptr = vset_duplicate(v); break; } return _.ptr; }