diff --git a/src/capnp/PointerBuilder.java b/src/capnp/PointerBuilder.java index 9c7ec75..f461ed9 100644 --- a/src/capnp/PointerBuilder.java +++ b/src/capnp/PointerBuilder.java @@ -8,4 +8,10 @@ public final class PointerBuilder { this.segment = segment; this.pointer = pointer; } + + public final ListBuilder initStructList(int elementCount, StructSize elementSize) { + return WireHelpers.initStructListPointer(this.pointer, this.segment, elementCount, elementSize); + } + + } diff --git a/src/capnp/StructSize.java b/src/capnp/StructSize.java index 7539e0f..21a5125 100644 --- a/src/capnp/StructSize.java +++ b/src/capnp/StructSize.java @@ -1,8 +1,8 @@ package org.capnproto; public final class StructSize { - public final short data; - public final short pointers; + public final short data; // number of words in data section + public final short pointers; // number of words in pointer section public final byte preferredListEncoding; public StructSize(short data, short pointers, byte preferredListEncoding) { @@ -10,4 +10,9 @@ public final class StructSize { this.pointers = pointers; this.preferredListEncoding = preferredListEncoding; } + + public final int total() { + return (int)this.data + (int)this.pointers; + } + } diff --git a/src/capnp/WireHelpers.java b/src/capnp/WireHelpers.java index 76cf8cd..c4c4fb1 100644 --- a/src/capnp/WireHelpers.java +++ b/src/capnp/WireHelpers.java @@ -2,12 +2,38 @@ package org.capnproto; final class WireHelpers { + public static ListBuilder initListPointer(int refOffset, + SegmentBuilder segment, + int elementCount, + byte elementSize) { + throw new Error("unimplemented"); + } + + public static ListBuilder initStructListPointer(int refOffset, + SegmentBuilder segment, + int elementCount, + StructSize elementSize) { + if (elementSize.preferredListEncoding != FieldSize.INLINE_COMPOSITE) { + //# Small data-only struct. Allocate a list of primitives instead. + return initListPointer(refOffset, segment, elementCount, + elementSize.preferredListEncoding); + } + + int wordsPerElement = elementSize.total(); + + throw new Error("unimplemented"); + } + public static StructReader readStructPointer(SegmentReader segment, int refOffset, int nestingLimit) { // TODO error handling + if (nestingLimit < 0) { + throw new DecodeException("Message is too deeply nested or contains cycles."); + } + long ref = WirePointer.get(segment.buffer, refOffset); int ptrOffset = WirePointer.target(refOffset, ref); int structPtr = WirePointer.structPointer(ref); @@ -78,6 +104,12 @@ final class WireHelpers { public static Text.Reader readTextPointer(SegmentReader segment, int refOffset) { long ref = WirePointer.get(segment.buffer, refOffset); + + if (WirePointer.isNull(ref)) { + // XXX should use the default value + return new Text.Reader(java.nio.ByteBuffer.wrap(new byte[0]), 0, 0); + } + int ptrOffset = WirePointer.target(refOffset, ref); int listPtr = WirePointer.listPointer(ref); int size = ListPointer.elementCount(listPtr); @@ -93,7 +125,7 @@ final class WireHelpers { // TODO bounds check? if (size == 0 || segment.buffer.get(8 * ptrOffset + size - 1) != 0) { - throw new DecodeException("Message containts text that is not NUL-terminated."); + throw new DecodeException("Message contains text that is not NUL-terminated."); } return new Text.Reader(segment.buffer, ptrOffset, size - 1);