change ptrsz to ptrs to free up space in capn_ptr

This commit is contained in:
James McKaskill 2013-09-13 10:02:03 -04:00
parent 7397df1216
commit 59f827e93d
5 changed files with 62 additions and 64 deletions

View file

@ -17,7 +17,7 @@ UINT_T CAT(capn_get,SZ) (LIST_T l, int off) {
case CAPN_COMPOSITE_LIST: case CAPN_COMPOSITE_LIST:
if (p.datasz < SZ/8) if (p.datasz < SZ/8)
return 0; return 0;
d = p.data + off * (p.datasz + p.ptrsz); d = p.data + off * (p.datasz + 8*p.ptrs);
return FLIP(*(UINT_T*)d); return FLIP(*(UINT_T*)d);
case CAPN_PTR_LIST: case CAPN_PTR_LIST:
@ -43,7 +43,7 @@ int CAT(capn_getv,SZ) (LIST_T l, int off, UINT_T *to, int sz) {
switch (p.type) { switch (p.type) {
case CAPN_LIST: case CAPN_LIST:
case CAPN_COMPOSITE_LIST: case CAPN_COMPOSITE_LIST:
if (p.datasz == SZ/8 && !p.ptrsz && (SZ == 8 || CAPN_LITTLE)) { if (p.datasz == SZ/8 && !p.ptrs && (SZ == 8 || CAPN_LITTLE)) {
memcpy(to, p.data + off, sz * (SZ/8)); memcpy(to, p.data + off, sz * (SZ/8));
return sz; return sz;
} else if (p.datasz < SZ/8) { } else if (p.datasz < SZ/8) {
@ -51,7 +51,7 @@ int CAT(capn_getv,SZ) (LIST_T l, int off, UINT_T *to, int sz) {
} }
for (i = 0; i < sz; i++) { for (i = 0; i < sz; i++) {
char *d = p.data + (i + off) * (p.datasz + p.ptrsz); char *d = p.data + (i + off) * (p.datasz + 8*p.ptrs);
to[i] = FLIP(*(UINT_T*)d); to[i] = FLIP(*(UINT_T*)d);
} }
return sz; return sz;
@ -84,7 +84,7 @@ int CAT(capn_set,SZ) (LIST_T l, int off, UINT_T v) {
case CAPN_COMPOSITE_LIST: case CAPN_COMPOSITE_LIST:
if (p.datasz < SZ/8) if (p.datasz < SZ/8)
return -1; return -1;
d = p.data + off * (p.datasz + p.ptrsz); d = p.data + off * (p.datasz + 8*p.ptrs);
*(UINT_T*) d = FLIP(v); *(UINT_T*) d = FLIP(v);
return 0; return 0;
@ -111,7 +111,7 @@ int CAT(capn_setv,SZ) (LIST_T l, int off, const UINT_T *from, int sz) {
switch (p.type) { switch (p.type) {
case CAPN_LIST: case CAPN_LIST:
case CAPN_COMPOSITE_LIST: case CAPN_COMPOSITE_LIST:
if (p.datasz == SZ/8 && !p.ptrsz && (SZ == 8 || CAPN_LITTLE)) { if (p.datasz == SZ/8 && !p.ptrs && (SZ == 8 || CAPN_LITTLE)) {
memcpy(p.data + off, from, sz * (SZ/8)); memcpy(p.data + off, from, sz * (SZ/8));
return sz; return sz;
} else if (p.datasz < SZ/8) { } else if (p.datasz < SZ/8) {
@ -119,7 +119,7 @@ int CAT(capn_setv,SZ) (LIST_T l, int off, const UINT_T *from, int sz) {
} }
for (i = 0; i < sz; i++) { for (i = 0; i < sz; i++) {
char *d = p.data + (i + off) * (p.datasz + p.ptrsz); char *d = p.data + (i + off) * (p.datasz + 8*p.ptrs);
*(UINT_T*) d = FLIP(from[i]); *(UINT_T*) d = FLIP(from[i]);
} }
return sz; return sz;

View file

@ -49,7 +49,7 @@ TEST(WireFormat, SimpleRawDataStruct) {
struct capn_ptr ptr = capn_getp(capn_root(&ctx), 0, 1); struct capn_ptr ptr = capn_getp(capn_root(&ctx), 0, 1);
EXPECT_EQ(CAPN_STRUCT, ptr.type); EXPECT_EQ(CAPN_STRUCT, ptr.type);
EXPECT_EQ(8, ptr.datasz); EXPECT_EQ(8, ptr.datasz);
EXPECT_EQ(0, ptr.ptrsz); EXPECT_EQ(0, ptr.ptrs);
EXPECT_EQ(UINT64_C(0xefcdab8967452301), capn_read64(ptr, 0)); EXPECT_EQ(UINT64_C(0xefcdab8967452301), capn_read64(ptr, 0));
EXPECT_EQ(UINT64_C(0), capn_read64(ptr, 8)); EXPECT_EQ(UINT64_C(0), capn_read64(ptr, 8));
@ -75,7 +75,7 @@ static void setupStruct(struct capn *ctx) {
struct capn_ptr ptr = capn_new_struct(root.seg, 16, 6); struct capn_ptr ptr = capn_new_struct(root.seg, 16, 6);
ASSERT_EQ(CAPN_STRUCT, ptr.type); ASSERT_EQ(CAPN_STRUCT, ptr.type);
EXPECT_EQ(16, ptr.datasz); EXPECT_EQ(16, ptr.datasz);
EXPECT_EQ(48, ptr.ptrsz); EXPECT_EQ(6, ptr.ptrs);
EXPECT_EQ(0, capn_setp(root, 0, ptr)); EXPECT_EQ(0, capn_setp(root, 0, ptr));
EXPECT_EQ(0, capn_write64(ptr, 0, UINT64_C(0x1011121314151617))); EXPECT_EQ(0, capn_write64(ptr, 0, UINT64_C(0x1011121314151617)));
@ -87,7 +87,7 @@ static void setupStruct(struct capn *ctx) {
capn_ptr subStruct = capn_new_struct(ptr.seg, 8, 0); capn_ptr subStruct = capn_new_struct(ptr.seg, 8, 0);
ASSERT_EQ(CAPN_STRUCT, subStruct.type); ASSERT_EQ(CAPN_STRUCT, subStruct.type);
EXPECT_EQ(8, subStruct.datasz); EXPECT_EQ(8, subStruct.datasz);
EXPECT_EQ(0, subStruct.ptrsz); EXPECT_EQ(0, subStruct.ptrs);
EXPECT_EQ(0, capn_write32(subStruct, 0, 123)); EXPECT_EQ(0, capn_write32(subStruct, 0, 123));
EXPECT_NE(0, capn_write32(subStruct, 8, 124)); EXPECT_NE(0, capn_write32(subStruct, 8, 124));
EXPECT_EQ(0, capn_setp(ptr, 0, subStruct)); EXPECT_EQ(0, capn_setp(ptr, 0, subStruct));
@ -108,19 +108,19 @@ static void setupStruct(struct capn *ctx) {
ASSERT_EQ(CAPN_COMPOSITE_LIST, list.type); ASSERT_EQ(CAPN_COMPOSITE_LIST, list.type);
EXPECT_EQ(4, list.len); EXPECT_EQ(4, list.len);
EXPECT_EQ(8, list.datasz); EXPECT_EQ(8, list.datasz);
EXPECT_EQ(8, list.ptrsz); EXPECT_EQ(1, list.ptrs);
EXPECT_EQ(0, capn_setp(ptr, 2, list)); EXPECT_EQ(0, capn_setp(ptr, 2, list));
for (int i = 0; i < 4; i++) { for (int i = 0; i < 4; i++) {
capn_ptr element = capn_getp(list, i, 1); capn_ptr element = capn_getp(list, i, 1);
ASSERT_EQ(CAPN_LIST_MEMBER, element.type); ASSERT_EQ(CAPN_LIST_MEMBER, element.type);
EXPECT_EQ(8, element.datasz); EXPECT_EQ(8, element.datasz);
EXPECT_EQ(8, element.ptrsz); EXPECT_EQ(1, element.ptrs);
EXPECT_EQ(0, capn_write32(element, 0, 300+i)); EXPECT_EQ(0, capn_write32(element, 0, 300+i));
capn_ptr subelement = capn_new_struct(element.seg, 8, 0); capn_ptr subelement = capn_new_struct(element.seg, 8, 0);
ASSERT_EQ(CAPN_STRUCT, subelement.type); ASSERT_EQ(CAPN_STRUCT, subelement.type);
EXPECT_EQ(8, subelement.datasz); EXPECT_EQ(8, subelement.datasz);
EXPECT_EQ(0, subelement.ptrsz); EXPECT_EQ(0, subelement.ptrs);
EXPECT_EQ(0, capn_write32(subelement, 0, 400+i)); EXPECT_EQ(0, capn_write32(subelement, 0, 400+i));
EXPECT_EQ(0, capn_setp(element, 0, subelement)); EXPECT_EQ(0, capn_setp(element, 0, subelement));
} }
@ -134,7 +134,7 @@ static void setupStruct(struct capn *ctx) {
ASSERT_EQ(CAPN_LIST, element.p.type); ASSERT_EQ(CAPN_LIST, element.p.type);
EXPECT_EQ(i+1, element.p.len); EXPECT_EQ(i+1, element.p.len);
EXPECT_EQ(2, element.p.datasz); EXPECT_EQ(2, element.p.datasz);
EXPECT_EQ(0, element.p.ptrsz); EXPECT_EQ(0, element.p.ptrs);
EXPECT_EQ(0, capn_setp(list, i, element.p)); EXPECT_EQ(0, capn_setp(list, i, element.p));
for (int j = 0; j <= i; j++) { for (int j = 0; j <= i; j++) {
EXPECT_EQ(0, capn_set16(element, j, 500+j)); EXPECT_EQ(0, capn_set16(element, j, 500+j));
@ -144,7 +144,7 @@ static void setupStruct(struct capn *ctx) {
capn_ptr recurse = capn_new_struct(ptr.seg, 0, 2); capn_ptr recurse = capn_new_struct(ptr.seg, 0, 2);
EXPECT_EQ(CAPN_STRUCT, recurse.type); EXPECT_EQ(CAPN_STRUCT, recurse.type);
EXPECT_EQ(0, recurse.datasz); EXPECT_EQ(0, recurse.datasz);
EXPECT_EQ(16, recurse.ptrsz); EXPECT_EQ(2, recurse.ptrs);
EXPECT_EQ(0, capn_setp(recurse, 0, recurse)); EXPECT_EQ(0, capn_setp(recurse, 0, recurse));
EXPECT_EQ(0, capn_setp(ptr, 4, recurse)); EXPECT_EQ(0, capn_setp(ptr, 4, recurse));
@ -154,7 +154,7 @@ static void checkStruct(struct capn *ctx) {
capn_ptr ptr = capn_getp(capn_root(ctx), 0, 1); capn_ptr ptr = capn_getp(capn_root(ctx), 0, 1);
EXPECT_EQ(CAPN_STRUCT, ptr.type); EXPECT_EQ(CAPN_STRUCT, ptr.type);
EXPECT_EQ(16, ptr.datasz); EXPECT_EQ(16, ptr.datasz);
EXPECT_EQ(48, ptr.ptrsz); EXPECT_EQ(6, ptr.ptrs);
EXPECT_EQ(UINT64_C(0x1011121314151617), capn_read64(ptr, 0)); EXPECT_EQ(UINT64_C(0x1011121314151617), capn_read64(ptr, 0));
EXPECT_EQ(UINT32_C(0x20212223), capn_read32(ptr, 8)); EXPECT_EQ(UINT32_C(0x20212223), capn_read32(ptr, 8));
EXPECT_EQ(0x3031, capn_read16(ptr, 12)); EXPECT_EQ(0x3031, capn_read16(ptr, 12));
@ -164,7 +164,7 @@ static void checkStruct(struct capn *ctx) {
capn_ptr subStruct = capn_getp(ptr, 0, 1); capn_ptr subStruct = capn_getp(ptr, 0, 1);
EXPECT_EQ(CAPN_STRUCT, subStruct.type); EXPECT_EQ(CAPN_STRUCT, subStruct.type);
EXPECT_EQ(8, subStruct.datasz); EXPECT_EQ(8, subStruct.datasz);
EXPECT_EQ(0, subStruct.ptrsz); EXPECT_EQ(0, subStruct.ptrs);
EXPECT_EQ(123, capn_read32(subStruct, 0)); EXPECT_EQ(123, capn_read32(subStruct, 0));
capn_list32 list32 = {capn_getp(ptr, 1, 1)}; capn_list32 list32 = {capn_getp(ptr, 1, 1)};
@ -174,7 +174,7 @@ static void checkStruct(struct capn *ctx) {
EXPECT_EQ(CAPN_LIST, list32.p.type); EXPECT_EQ(CAPN_LIST, list32.p.type);
EXPECT_EQ(3, list32.p.len); EXPECT_EQ(3, list32.p.len);
EXPECT_EQ(4, list32.p.datasz); EXPECT_EQ(4, list32.p.datasz);
EXPECT_EQ(0, list32.p.ptrsz); EXPECT_EQ(0, list32.p.ptrs);
EXPECT_EQ(200, capn_get32(list32, 0)); EXPECT_EQ(200, capn_get32(list32, 0));
EXPECT_EQ(201, capn_get32(list32, 1)); EXPECT_EQ(201, capn_get32(list32, 1));
EXPECT_EQ(202, capn_get32(list32, 2)); EXPECT_EQ(202, capn_get32(list32, 2));
@ -187,19 +187,19 @@ static void checkStruct(struct capn *ctx) {
EXPECT_EQ(CAPN_COMPOSITE_LIST, list.type); EXPECT_EQ(CAPN_COMPOSITE_LIST, list.type);
EXPECT_EQ(4, list.len); EXPECT_EQ(4, list.len);
EXPECT_EQ(8, list.datasz); EXPECT_EQ(8, list.datasz);
EXPECT_EQ(8, list.ptrsz); EXPECT_EQ(1, list.ptrs);
for (int i = 0; i < 4; i++) { for (int i = 0; i < 4; i++) {
capn_ptr element = capn_getp(list, i, 1); capn_ptr element = capn_getp(list, i, 1);
EXPECT_EQ(CAPN_LIST_MEMBER, element.type); EXPECT_EQ(CAPN_LIST_MEMBER, element.type);
EXPECT_EQ(8, element.datasz); EXPECT_EQ(8, element.datasz);
EXPECT_EQ(8, element.ptrsz); EXPECT_EQ(1, element.ptrs);
EXPECT_EQ(300+i, capn_read32(element,0)); EXPECT_EQ(300+i, capn_read32(element,0));
capn_ptr subelement = capn_getp(element, 0, 1); capn_ptr subelement = capn_getp(element, 0, 1);
EXPECT_EQ(CAPN_STRUCT, subelement.type); EXPECT_EQ(CAPN_STRUCT, subelement.type);
EXPECT_EQ(8, subelement.datasz); EXPECT_EQ(8, subelement.datasz);
EXPECT_EQ(0, subelement.ptrsz); EXPECT_EQ(0, subelement.ptrs);
EXPECT_EQ(400+i, capn_read32(subelement, 0)); EXPECT_EQ(400+i, capn_read32(subelement, 0));
} }
@ -211,7 +211,7 @@ static void checkStruct(struct capn *ctx) {
EXPECT_EQ(CAPN_LIST, element.p.type); EXPECT_EQ(CAPN_LIST, element.p.type);
EXPECT_EQ(i+1, element.p.len); EXPECT_EQ(i+1, element.p.len);
EXPECT_EQ(2, element.p.datasz); EXPECT_EQ(2, element.p.datasz);
EXPECT_EQ(0, element.p.ptrsz); EXPECT_EQ(0, element.p.ptrs);
for (int j = 0; j <= i; j++) { for (int j = 0; j <= i; j++) {
EXPECT_EQ(500+j, capn_get16(element, j)); EXPECT_EQ(500+j, capn_get16(element, j));
} }
@ -220,11 +220,11 @@ static void checkStruct(struct capn *ctx) {
capn_ptr recurse = capn_getp(ptr, 4, 1); capn_ptr recurse = capn_getp(ptr, 4, 1);
EXPECT_EQ(CAPN_STRUCT, recurse.type); EXPECT_EQ(CAPN_STRUCT, recurse.type);
EXPECT_EQ(0, recurse.datasz); EXPECT_EQ(0, recurse.datasz);
EXPECT_EQ(16, recurse.ptrsz); EXPECT_EQ(2, recurse.ptrs);
capn_ptr recurse_mbr = capn_getp(recurse, 0, 1); capn_ptr recurse_mbr = capn_getp(recurse, 0, 1);
EXPECT_EQ(CAPN_STRUCT, recurse_mbr.type); EXPECT_EQ(CAPN_STRUCT, recurse_mbr.type);
EXPECT_EQ(0, recurse_mbr.datasz); EXPECT_EQ(0, recurse_mbr.datasz);
EXPECT_EQ(16, recurse_mbr.ptrsz); EXPECT_EQ(2, recurse_mbr.ptrs);
EXPECT_EQ(recurse.seg, recurse_mbr.seg); EXPECT_EQ(recurse.seg, recurse_mbr.seg);
EXPECT_EQ(recurse.data, recurse_mbr.data); EXPECT_EQ(recurse.data, recurse_mbr.data);
EXPECT_EQ(CAPN_NULL, capn_getp(recurse, 1, 1).type); EXPECT_EQ(CAPN_NULL, capn_getp(recurse, 1, 1).type);

76
capn.c
View file

@ -333,8 +333,8 @@ static capn_ptr read_ptr(struct capn_segment *s, char *d) {
struct_common: struct_common:
ret.datasz = U32(U16(val >> 32)) * 8; ret.datasz = U32(U16(val >> 32)) * 8;
ret.ptrsz = U32(U16(val >> 48)) * 8; ret.ptrs = U32(U16(val >> 48));
e = d + ret.datasz + ret.ptrsz; e = d + ret.datasz + 8 * ret.ptrs;
break; break;
case LIST_PTR: case LIST_PTR:
@ -381,11 +381,11 @@ static capn_ptr read_ptr(struct capn_segment *s, char *d) {
e = d + ret.len * 8; e = d + ret.len * 8;
ret.datasz = U32(U16(val >> 32)) * 8; ret.datasz = U32(U16(val >> 32)) * 8;
ret.ptrsz = U32(U16(val >> 48)) * 8; ret.ptrs = U32(U16(val >> 48));
ret.len = U32(val) >> 2; ret.len = U32(val) >> 2;
ret.type = CAPN_COMPOSITE_LIST; ret.type = CAPN_COMPOSITE_LIST;
if ((ret.datasz + ret.ptrsz) * ret.len != e - d) { if ((ret.datasz + 8*ret.ptrs) * ret.len != e - d) {
goto err; goto err;
} }
break; break;
@ -424,10 +424,10 @@ capn_ptr capn_getp(capn_ptr p, int off, int resolve) {
/* Return an inner pointer */ /* Return an inner pointer */
if (off < p.len) { if (off < p.len) {
capn_ptr ret = {CAPN_LIST_MEMBER}; capn_ptr ret = {CAPN_LIST_MEMBER};
ret.data = p.data + off * (p.datasz + p.ptrsz); ret.data = p.data + off * (p.datasz + 8*p.ptrs);
ret.seg = p.seg; ret.seg = p.seg;
ret.datasz = p.datasz; ret.datasz = p.datasz;
ret.ptrsz = p.ptrsz; ret.ptrs = p.ptrs;
return ret; return ret;
} else { } else {
goto err; goto err;
@ -435,18 +435,17 @@ capn_ptr capn_getp(capn_ptr p, int off, int resolve) {
case CAPN_LIST_MEMBER: case CAPN_LIST_MEMBER:
case CAPN_STRUCT: case CAPN_STRUCT:
off *= 8; if (off >= p.ptrs) {
if (off >= p.ptrsz) {
goto err; goto err;
} }
ret.data = p.data + p.datasz + off; ret.data = p.data + p.datasz + 8*off;
break; break;
case CAPN_PTR_LIST: case CAPN_PTR_LIST:
if (off >= p.len) { if (off >= p.len) {
goto err; goto err;
} }
ret.data = p.data + off * 8; ret.data = p.data + 8*off;
break; break;
default: default:
@ -471,11 +470,11 @@ static int data_size(struct capn_ptr p) {
case CAPN_PTR_LIST: case CAPN_PTR_LIST:
return p.len*8; return p.len*8;
case CAPN_STRUCT: case CAPN_STRUCT:
return p.datasz + p.ptrsz; return p.datasz + 8*p.ptrs;
case CAPN_COMPOSITE_LIST: case CAPN_COMPOSITE_LIST:
return p.len * (p.datasz + p.ptrsz) + 8; return p.len * (p.datasz + 8*p.ptrs) + 8;
case CAPN_LIST: case CAPN_LIST:
return p.len * (p.datasz + p.ptrsz); return p.len * (p.datasz + 8*p.ptrs);
default: default:
return 0; return 0;
} }
@ -486,11 +485,11 @@ static void write_ptr_tag(char *d, capn_ptr p, int off) {
switch (p.type) { switch (p.type) {
case CAPN_STRUCT: case CAPN_STRUCT:
val |= STRUCT_PTR | (U64(p.datasz/8) << 32) | (U64(p.ptrsz/8) << 48); val |= STRUCT_PTR | (U64(p.datasz/8) << 32) | (U64(p.ptrs) << 48);
break; break;
case CAPN_COMPOSITE_LIST: case CAPN_COMPOSITE_LIST:
val |= LIST_PTR | (U64(COMPOSITE_LIST) << 32) | (U64(p.len * (p.datasz + p.ptrsz)/8) << 35); val |= LIST_PTR | (U64(COMPOSITE_LIST) << 32) | (U64(p.len * (p.datasz/8 + p.ptrs)) << 35);
break; break;
case CAPN_LIST: case CAPN_LIST:
@ -602,14 +601,14 @@ static capn_ptr new_clone(struct capn_segment *s, capn_ptr p) {
switch (p.type) { switch (p.type) {
case CAPN_STRUCT: case CAPN_STRUCT:
case CAPN_LIST_MEMBER: case CAPN_LIST_MEMBER:
return capn_new_struct(s, p.datasz, p.ptrsz/8); return capn_new_struct(s, p.datasz, p.ptrs);
case CAPN_PTR_LIST: case CAPN_PTR_LIST:
return capn_new_ptr_list(s, p.len); return capn_new_ptr_list(s, p.len);
case CAPN_BIT_LIST: case CAPN_BIT_LIST:
return capn_new_list1(s, p.len).p; return capn_new_list1(s, p.len).p;
case CAPN_LIST: case CAPN_LIST:
case CAPN_COMPOSITE_LIST: case CAPN_COMPOSITE_LIST:
return capn_new_list(s, p.len, p.datasz, p.ptrsz/8); return capn_new_list(s, p.len, p.datasz, p.ptrs);
default: default:
return p; return p;
} }
@ -620,7 +619,7 @@ static int is_ptr_equal(const struct capn_ptr *a, const struct capn_ptr *b) {
&& a->type == b->type && a->type == b->type
&& a->len == b->len && a->len == b->len
&& a->datasz == b->datasz && a->datasz == b->datasz
&& a->ptrsz == b->ptrsz; && a->ptrs == b->ptrs;
} }
static int copy_ptr(struct capn_segment *seg, char *data, struct capn_ptr *t, struct capn_ptr *f, int *dep) { static int copy_ptr(struct capn_segment *seg, char *data, struct capn_ptr *t, struct capn_ptr *f, int *dep) {
@ -702,9 +701,9 @@ static int copy_ptr(struct capn_segment *seg, char *data, struct capn_ptr *t, st
t->data += t->datasz; t->data += t->datasz;
f->data += t->datasz; f->data += t->datasz;
} }
if (t->ptrsz) { if (t->ptrs) {
t->type = CAPN_PTR_LIST; t->type = CAPN_PTR_LIST;
t->len = t->ptrsz/8; t->len = t->ptrs;
(*dep)++; (*dep)++;
} }
return 0; return 0;
@ -717,13 +716,13 @@ static int copy_ptr(struct capn_segment *seg, char *data, struct capn_ptr *t, st
case CAPN_COMPOSITE_LIST: case CAPN_COMPOSITE_LIST:
if (!t->len) { if (!t->len) {
/* empty list - nothing to copy */ /* empty list - nothing to copy */
} else if (t->ptrsz && t->datasz) { } else if (t->ptrs && t->datasz) {
(*dep)++; (*dep)++;
} else if (t->datasz) { } else if (t->datasz) {
memcpy(t->data, f->data, t->len * t->datasz); memcpy(t->data, f->data, t->len * t->datasz);
} else if (t->ptrsz) { } else if (t->ptrs) {
t->type = CAPN_PTR_LIST; t->type = CAPN_PTR_LIST;
t->len *= t->ptrsz/8; t->len *= t->ptrs;
(*dep)++; (*dep)++;
} }
return 0; return 0;
@ -748,13 +747,13 @@ static void copy_list_member(capn_ptr* t, capn_ptr *f, int *dep) {
f->data += f->datasz; f->data += f->datasz;
/* reset excess pointers */ /* reset excess pointers */
sz = min(t->ptrsz, f->ptrsz); sz = min(t->ptrs, f->ptrs);
memset(t->data + sz, 0, t->ptrsz - sz); memset(t->data + sz, 0, 8*(t->ptrs - sz));
/* create a pointer list for the main loop to copy */ /* create a pointer list for the main loop to copy */
if (t->ptrsz) { if (t->ptrs) {
t->type = CAPN_PTR_LIST; t->type = CAPN_PTR_LIST;
t->len = t->ptrsz/8; t->len = t->ptrs;
(*dep)++; (*dep)++;
} }
} }
@ -785,7 +784,7 @@ int capn_setp(capn_ptr p, int off, capn_ptr tgt) {
return -1; return -1;
to[0] = p; to[0] = p;
to[0].data += off * (p.datasz + p.ptrsz); to[0].data += off * (p.datasz + 8*p.ptrs);
from[0] = tgt; from[0] = tgt;
copy_list_member(to, from, &dep); copy_list_member(to, from, &dep);
break; break;
@ -793,15 +792,14 @@ int capn_setp(capn_ptr p, int off, capn_ptr tgt) {
case CAPN_PTR_LIST: case CAPN_PTR_LIST:
if (off >= p.len) if (off >= p.len)
return -1; return -1;
data = p.data + off * 8; data = p.data + 8*off;
goto copy_ptr; goto copy_ptr;
case CAPN_STRUCT: case CAPN_STRUCT:
case CAPN_LIST_MEMBER: case CAPN_LIST_MEMBER:
off *= 8; if (off >= p.ptrs)
if (off >= p.ptrsz)
return -1; return -1;
data = p.data + p.datasz + off; data = p.data + p.datasz + 8*off;
goto copy_ptr; goto copy_ptr;
copy_ptr: copy_ptr:
@ -845,8 +843,8 @@ int capn_setp(capn_ptr p, int off, capn_ptr tgt) {
copy_list_member(tn, fn, &dep); copy_list_member(tn, fn, &dep);
fc->data += fc->datasz + fc->ptrsz; fc->data += fc->datasz + 8*fc->ptrs;
tc->data += tc->datasz + tc->ptrsz; tc->data += tc->datasz + 8*tc->ptrs;
tc->len--; tc->len--;
} else { /* CAPN_PTR_LIST */ } else { /* CAPN_PTR_LIST */
@ -979,8 +977,8 @@ capn_ptr capn_new_struct(struct capn_segment *seg, int datasz, int ptrs) {
capn_ptr p = {CAPN_STRUCT}; capn_ptr p = {CAPN_STRUCT};
p.seg = seg; p.seg = seg;
p.datasz = (datasz + 7) & ~7; p.datasz = (datasz + 7) & ~7;
p.ptrsz = ptrs * 8; p.ptrs = ptrs;
new_object(&p, p.datasz + p.ptrsz); new_object(&p, p.datasz + 8*p.ptrs);
return p; return p;
} }
@ -994,8 +992,8 @@ capn_ptr capn_new_list(struct capn_segment *seg, int sz, int datasz, int ptrs) {
} else if (ptrs || datasz > 8) { } else if (ptrs || datasz > 8) {
p.type = CAPN_COMPOSITE_LIST; p.type = CAPN_COMPOSITE_LIST;
p.datasz = (datasz + 7) & ~7; p.datasz = (datasz + 7) & ~7;
p.ptrsz = ptrs*8; p.ptrs = ptrs;
new_object(&p, p.len * (p.datasz + p.ptrsz) + 8); new_object(&p, p.len * (p.datasz + 8*p.ptrs) + 8);
if (p.data) { if (p.data) {
uint64_t hdr = STRUCT_PTR | (U64(p.len) << 2) | (U64(p.datasz/8) << 32) | (U64(ptrs) << 48); uint64_t hdr = STRUCT_PTR | (U64(p.len) << 2) | (U64(p.datasz/8) << 32) | (U64(ptrs) << 48);
*(uint64_t*) p.data = capn_flip64(hdr); *(uint64_t*) p.data = capn_flip64(hdr);
@ -1028,7 +1026,7 @@ capn_ptr capn_new_ptr_list(struct capn_segment *seg, int sz) {
capn_ptr p = {CAPN_PTR_LIST}; capn_ptr p = {CAPN_PTR_LIST};
p.seg = seg; p.seg = seg;
p.len = sz; p.len = sz;
p.ptrsz = 0; p.ptrs = 0;
p.datasz = 0; p.datasz = 0;
new_object(&p, sz*8); new_object(&p, sz*8);
return p; return p;

2
capn.h
View file

@ -113,7 +113,7 @@ struct capn_ptr {
unsigned int type : 4; unsigned int type : 4;
unsigned int has_ptr_tag : 1; unsigned int has_ptr_tag : 1;
unsigned int datasz : 19; unsigned int datasz : 19;
unsigned int ptrsz : 19; unsigned int ptrs : 16;
int len; int len;
char *data; char *data;
struct capn_segment *seg; struct capn_segment *seg;

View file

@ -289,7 +289,7 @@ static void decode_value(struct value* v, Type_ptr type, Value_ptr value, const
p.type, p.type,
p.has_ptr_tag, p.has_ptr_tag,
p.datasz, p.datasz,
p.ptrsz, p.ptrs,
p.len, p.len,
(int) (p.data-p.seg->data-8)); (int) (p.data-p.seg->data-8));