diff --git a/capn-test.cpp b/capn-test.cpp index a6e2419..d35b877 100644 --- a/capn-test.cpp +++ b/capn-test.cpp @@ -222,13 +222,14 @@ static void checkStruct(struct capn *ctx) { capn_ptr recurse = capn_getp(ptr, 4); EXPECT_EQ(CAPN_STRUCT, recurse.type); EXPECT_EQ(0, recurse.datasz); - EXPECT_EQ(8, recurse.ptrsz); + EXPECT_EQ(16, recurse.ptrsz); capn_ptr recurse_mbr = capn_getp(recurse, 0); EXPECT_EQ(CAPN_STRUCT, recurse_mbr.type); EXPECT_EQ(0, recurse_mbr.datasz); - EXPECT_EQ(8, recurse_mbr.ptrsz); + EXPECT_EQ(16, recurse_mbr.ptrsz); EXPECT_EQ(recurse.seg, recurse_mbr.seg); EXPECT_EQ(recurse.data, recurse_mbr.data); + EXPECT_EQ(CAPN_NULL, capn_getp(recurse, 1).type); } TEST(WireFormat, StructRoundTrip_OneSegment) { @@ -249,11 +250,11 @@ TEST(WireFormat, StructRoundTrip_OneSegment) { // 11 list list // 5 references to sub-lists // 6 sub-lists (4x 1 word, 1x 2 words) - // 1 recurse + // 2 recurse // ----- - // 36 + // 37 ASSERT_EQ(1, ctx.capn.segnum); - EXPECT_EQ(36*8, ctx.capn.seglist->len); + EXPECT_EQ(37*8, ctx.capn.seglist->len); checkStruct(&ctx.capn); @@ -309,7 +310,7 @@ TEST(WireFormat, StructRoundTrip_OneSegmentPerAllocation) { EXPECT_EQ(16, segments[12]->len); // list list sublist 3 EXPECT_EQ(16, segments[13]->len); // list list sublist 4 EXPECT_EQ(24, segments[14]->len); // list list sublist 5 - EXPECT_EQ(16, segments[15]->len); // recurse struct + EXPECT_EQ(24, segments[15]->len); // recurse struct checkStruct(&ctx.capn); @@ -364,7 +365,7 @@ TEST(WireFormat, StructRoundTrip_OneSegmentPerAllocation_NoTag) { EXPECT_EQ(16, segments[26]->len); // list list sublist 4 ptr EXPECT_EQ(16, segments[27]->len); // list list sublist 5 EXPECT_EQ(16, segments[28]->len); // list list sublist 5 ptr - EXPECT_EQ( 8, segments[29]->len); // recurse struct + EXPECT_EQ(16, segments[29]->len); // recurse struct EXPECT_EQ(16, segments[30]->len); // recurse struct ptr checkStruct(&ctx.capn); @@ -415,7 +416,7 @@ TEST(WireFormat, StructRoundTrip_MultipleSegmentsWithMultipleAllocations) { EXPECT_EQ(80, segments[2]->len); // struct list (72+tag) EXPECT_EQ(64, segments[3]->len); // struct list substructs 2+3+4 3*(8+tag) + list list sublist 3 (8+tag) EXPECT_EQ(64, segments[4]->len); // list list (40+tag) + sublist 1,2 2*(8) - EXPECT_EQ(56, segments[5]->len); // list list sublist 4 (8+tag), 5 (16+tag) + recurse struct (8+tag) + EXPECT_EQ(64, segments[5]->len); // list list sublist 4 (8+tag), 5 (16+tag) + recurse struct (16+tag) checkStruct(&ctx.capn); diff --git a/capn.c b/capn.c index e302c18..fb74442 100644 --- a/capn.c +++ b/capn.c @@ -327,10 +327,10 @@ static capn_ptr read_ptr(struct capn_segment *s, char *d) { } if ((val&3) == STRUCT_PTR) { - ret.type = CAPN_STRUCT; ret.datasz = U32(U16(val >> 32)) * 8; ret.ptrsz = U32(U16(val >> 48)) * 8; - e = d + ret.len * (ret.datasz + ret.ptrsz); + ret.type = (ret.datasz || ret.ptrsz) ? CAPN_STRUCT : CAPN_NULL; + e = d + ret.datasz + ret.ptrsz; } else { ret.type = CAPN_LIST; ret.len = val >> 35; @@ -821,7 +821,7 @@ int capn_setp(capn_ptr p, int off, capn_ptr tgt) { default: *fn = read_ptr(fc->seg, fc->data); - if (copy_ptr(tc->seg, tc->data, tn, fn, &dep)) + if (fn->type && copy_ptr(tc->seg, tc->data, tn, fn, &dep)) return -1; fc->data += 8; @@ -1056,7 +1056,7 @@ int capn_set_text(capn_ptr p, int off, capn_text tgt) { m.data = (char*)tgt.str; m.len = tgt.len + 1; m.datasz = 1; - } else if (tgt.str) { + } else if (p.seg && tgt.str) { m = capn_new_string(p.seg, tgt.str, tgt.len); } return capn_setp(p, off, m); diff --git a/capn.h b/capn.h index 4b73df5..e2487fa 100644 --- a/capn.h +++ b/capn.h @@ -91,7 +91,7 @@ enum CAPN_TYPE { }; struct capn_ptr { - enum CAPN_TYPE type : 3; + unsigned int type : 3; unsigned int is_list_member : 1; unsigned int has_ptr_tag : 1; unsigned int has_composite_tag : 1; @@ -357,19 +357,23 @@ CAPN_INLINE uint64_t capn_from_f64(double v) { } CAPN_INLINE capn_list8 capn_new_list8(struct capn_segment *seg, int sz) { - capn_list8 p = {capn_new_list(seg, sz, 1, 0)}; + capn_list8 p; + p.p = capn_new_list(seg, sz, 1, 0); return p; } CAPN_INLINE capn_list16 capn_new_list16(struct capn_segment *seg, int sz) { - capn_list16 p = {capn_new_list(seg, sz, 2, 0)}; + capn_list16 p; + p.p = capn_new_list(seg, sz, 2, 0); return p; } CAPN_INLINE capn_list32 capn_new_list32(struct capn_segment *seg, int sz) { - capn_list32 p = {capn_new_list(seg, sz, 4, 0)}; + capn_list32 p; + p.p = capn_new_list(seg, sz, 4, 0); return p; } CAPN_INLINE capn_list64 capn_new_list64(struct capn_segment *seg, int sz) { - capn_list64 p = {capn_new_list(seg, sz, 8, 0)}; + capn_list64 p; + p.p = capn_new_list(seg, sz, 8, 0); return p; } CAPN_INLINE int capn_set_data(capn_ptr p, int off, capn_data d) {