From 5846344fab742ef97c4c0e22e530afab5a6aa219 Mon Sep 17 00:00:00 2001 From: Daniel Friesel Date: Wed, 21 Nov 2018 08:22:03 +0100 Subject: working minimal capnp_c test case --- include/lib/capnp-c/capn-list.inc | 162 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 162 insertions(+) create mode 100644 include/lib/capnp-c/capn-list.inc (limited to 'include/lib/capnp-c/capn-list.inc') diff --git a/include/lib/capnp-c/capn-list.inc b/include/lib/capnp-c/capn-list.inc new file mode 100644 index 0000000..ad94ec8 --- /dev/null +++ b/include/lib/capnp-c/capn-list.inc @@ -0,0 +1,162 @@ +/* capn-list.inc + * + * Copyright (C) 2013 James McKaskill + * + * This software may be modified and distributed under the terms + * of the MIT license. See the LICENSE file for details. + */ + +#define CAT2(A,B) A ## B +#define CAT(A,B) CAT2(A, B) +#define UINT_T CAT(CAT(uint, SZ), _t) +#define LIST_T CAT(capn_list, SZ) +#define FLIP CAT(capn_flip, SZ) + +UINT_T CAT(capn_get,SZ) (LIST_T l, int off) { + char *d; + capn_ptr p = l.p; + if (off >= p.len) { + return 0; + } + + switch (p.type) { + case CAPN_LIST: + if (p.datasz < SZ/8) + return 0; + d = p.data + off * (p.datasz + 8*p.ptrs); + return FLIP(*(UINT_T*)d); + + case CAPN_PTR_LIST: + d = struct_ptr(p.seg, p.data + 8*off, SZ/8); + if (d) { + return FLIP(*(UINT_T*)d); + } else { + return 0; + } + + default: + return 0; + } +} + +int CAT(capn_getv,SZ) (LIST_T l, int off, UINT_T *to, int sz) { + int i; + capn_ptr p; + capn_resolve(&l.p); + p = l.p; + if (off + sz > p.len) { + sz = p.len - off; + } + + switch (p.type) { + case CAPN_LIST: + if (p.datasz == SZ/8 && !p.ptrs && (SZ == 8 || CAPN_LITTLE)) { + memcpy(to, p.data + off, sz * (SZ/8)); + return sz; + } else if (p.datasz < SZ/8) { + return -1; + } + + for (i = 0; i < sz; i++) { + char *d = p.data + (i + off) * (p.datasz + 8*p.ptrs); + to[i] = FLIP(*(UINT_T*)d); + } + return sz; + + case CAPN_PTR_LIST: + for (i = 0; i < sz; i++) { + char *d = struct_ptr(p.seg, p.data + 8*(i+off), SZ/8); + if (d) { + to[i] = FLIP(*(UINT_T*)d); + } else { + return -1; + } + } + return sz; + + default: + return -1; + } +} + +int CAT(capn_set,SZ) (LIST_T l, int off, UINT_T v) { + char *d; + capn_ptr p = l.p; + if (off >= p.len) { + return -1; + } + + switch (p.type) { + case CAPN_LIST: + if (p.datasz < SZ/8) + return -1; + d = p.data + off * (p.datasz + 8*p.ptrs); + *(UINT_T*) d = FLIP(v); + return 0; + + case CAPN_PTR_LIST: + d = struct_ptr(p.seg, p.data + 8*off, SZ/8); + if (!d) { + return -1; + } + *(UINT_T*) d = FLIP(v); + return 0; + + default: + return -1; + } +} + +int CAT(capn_setv,SZ) (LIST_T l, int off, const UINT_T *from, int sz) { + int i; + capn_ptr p = l.p; + if (off + sz > p.len) { + sz = p.len - off; + } + + switch (p.type) { + case CAPN_LIST: + if (p.datasz == SZ/8 && !p.ptrs && (SZ == 8 || CAPN_LITTLE)) { + memcpy(p.data + off, from, sz * (SZ/8)); + return sz; + } else if (p.datasz < SZ/8) { + return -1; + } + + for (i = 0; i < sz; i++) { + char *d = p.data + (i + off) * (p.datasz + 8*p.ptrs); + *(UINT_T*) d = FLIP(from[i]); + } + return sz; + + case CAPN_PTR_LIST: + for (i = 0; i < sz; i++) { + char *d = struct_ptr(p.seg, p.data + 8*(i+off), SZ/8); + if (d) { + *(UINT_T*) d = FLIP(from[i]); + } else { + return -1; + } + } + return sz; + + default: + return -1; + } +} + +LIST_T CAT(capn_new_list,SZ) (struct capn_segment *seg, int sz) { + LIST_T l = {{CAPN_LIST}}; + l.p.seg = seg; + l.p.len = sz; + l.p.datasz = SZ/8; + new_object(&l.p, sz*(SZ/8)); + return l; +} + +#undef CAT2 +#undef CAT +#undef UINT_T +#undef LIST_T +#undef FLIP + -- cgit v1.2.3