summaryrefslogtreecommitdiff
path: root/include/lib/capnp-c/capn-list.inc
diff options
context:
space:
mode:
Diffstat (limited to 'include/lib/capnp-c/capn-list.inc')
-rw-r--r--include/lib/capnp-c/capn-list.inc162
1 files changed, 162 insertions, 0 deletions
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
+