From 82602b7ca5c364d39cbb04ffd4f53a09b7565d49 Mon Sep 17 00:00:00 2001 From: David Renshaw Date: Sat, 10 May 2014 13:33:57 -0400 Subject: [PATCH] wirehelpers --- Makefile | 2 ++ src/capnp/FieldSize.java | 12 ++++++++++ src/capnp/ListPointer.java | 10 +++++++- src/capnp/PointerReader.java | 16 ++++++++++--- src/capnp/StructPointer.java | 22 +++++++++++++++++ src/capnp/WireHelpers.java | 46 +++++++++++++++++++++++++++++++++++- src/capnp/WirePointer.java | 16 +++++++++---- src/capnp/WordPointer.java | 2 +- 8 files changed, 116 insertions(+), 10 deletions(-) create mode 100644 src/capnp/FieldSize.java create mode 100644 src/capnp/StructPointer.java diff --git a/Makefile b/Makefile index 6dc24cc..93420d0 100644 --- a/Makefile +++ b/Makefile @@ -1,12 +1,14 @@ CXX=g++ -std=c++11 CAPNP_SOURCES=\ + src/capnp/FieldSize.java\ src/capnp/FromStructReader.java\ src/capnp/ListPointer.java\ src/capnp/ListReader.java\ src/capnp/PointerReader.java\ src/capnp/SegmentReader.java\ src/capnp/StructReader.java\ + src/capnp/StructPointer.java\ src/capnp/StructList.java\ src/capnp/Text.java\ src/capnp/WireHelpers.java\ diff --git a/src/capnp/FieldSize.java b/src/capnp/FieldSize.java new file mode 100644 index 0000000..8434c80 --- /dev/null +++ b/src/capnp/FieldSize.java @@ -0,0 +1,12 @@ +package capnp; + +public class FieldSize { + public static final byte VOID = 0; + public static final byte BIT = 1; + public static final byte BYTE = 2; + public static final byte TWO_BYTES = 3; + public static final byte FOUR_BYTES = 4; + public static final byte EIGHT_BYTES = 5; + public static final byte POINTER = 6; + public static final byte INLINE_COMPOSITE = 7; +} diff --git a/src/capnp/ListPointer.java b/src/capnp/ListPointer.java index 9724442..60cbf37 100644 --- a/src/capnp/ListPointer.java +++ b/src/capnp/ListPointer.java @@ -8,7 +8,15 @@ class ListPointer extends WirePointer { super(buffer, buffer_offset); } + public byte elementSize() { + return (byte)(this.buffer.getInt(buffer_offset * 2 + 1) & 7); + } + public int elementCount() { - return this.buffer.getInt(buffer_offset * 2) >> 3; + return this.buffer.getInt(buffer_offset * 2 + 1) >> 3; + } + + public int inlineCompositeWordCount() { + return this.elementCount(); } } diff --git a/src/capnp/PointerReader.java b/src/capnp/PointerReader.java index dcbb110..b84292d 100644 --- a/src/capnp/PointerReader.java +++ b/src/capnp/PointerReader.java @@ -7,7 +7,7 @@ public class PointerReader { public PointerReader() { this.segment = null; - this.pointer = 0; // XXX + this.pointer = 0; // XXX ? this.nestingLimit = 0x7fffffff; } @@ -17,7 +17,17 @@ public class PointerReader { this.nestingLimit = nestingLimit; } - public void getText() { - throw new Error(); + public ListReader getList(byte expectedElementSize) { + // TODO check nullness + WirePointer ref = new WirePointer(this.segment.ptr, this.pointer); + return WireHelpers.readListPointer(this.segment, + ref, + expectedElementSize); + } + + public Text.Reader getText() { + return WireHelpers.readTextPointer(this.segment, + new WirePointer(this.segment.ptr, + this.pointer)); } } diff --git a/src/capnp/StructPointer.java b/src/capnp/StructPointer.java new file mode 100644 index 0000000..1e23ad3 --- /dev/null +++ b/src/capnp/StructPointer.java @@ -0,0 +1,22 @@ +package capnp; + +import java.nio.ByteBuffer; + +class StructPointer extends WirePointer { + + public StructPointer(ByteBuffer buffer, int buffer_offset) { + super(buffer, buffer_offset); + } + + public short dataSize() { + return this.buffer.getShort(this.buffer_offset * 4 + 2); + } + + public short ptrCount() { + return this.buffer.getShort(this.buffer_offset * 4 + 3); + } + + public int wordSize() { + return this.dataSize() + this.ptrCount(); + } +} diff --git a/src/capnp/WireHelpers.java b/src/capnp/WireHelpers.java index e4c8807..eb5f0b4 100644 --- a/src/capnp/WireHelpers.java +++ b/src/capnp/WireHelpers.java @@ -1,8 +1,52 @@ package capnp; class WireHelpers { + + public static ListReader readListPointer(SegmentReader segment, + WirePointer ref, + int nestingLimit) { + + // TODO check for null, follow fars, nestingLimit + + ListPointer listPtr = (ListPointer)ref; + + WordPointer ptr = ref.target(); + + switch (listPtr.elementSize()) { + case FieldSize.INLINE_COMPOSITE : { + int wordCount = listPtr.inlineCompositeWordCount(); + + WirePointer tag = new WirePointer(ptr); + ptr.offset += 1; + + // TODO bounds check + + int size = tag.inlineCompositeListElementCount(); + StructPointer structPtr = (StructPointer)tag; + int wordsPerElement = structPtr.wordSize(); + + // TODO check that elemements do not overrun word count + + // TODO check whether the size is compatible + + return new ListReader(segment, // TODO follow fars + ptr.offset, // + size, + wordsPerElement * 64, + structPtr.dataSize() * 64, + structPtr.ptrCount(), + nestingLimit - 1); + } + case FieldSize.VOID : break; + default : + throw new Error("unrecognized element size"); + } + + throw new Error(); + } + public static Text.Reader readTextPointer(SegmentReader segment, - WirePointer ref) { + WirePointer ref) { ref.target(); ListPointer listPtr = (ListPointer)ref; return new Text.Reader(listPtr); diff --git a/src/capnp/WirePointer.java b/src/capnp/WirePointer.java index 23953a5..18f79fe 100644 --- a/src/capnp/WirePointer.java +++ b/src/capnp/WirePointer.java @@ -6,16 +6,21 @@ class WirePointer { public final ByteBuffer buffer; public final int buffer_offset; // in words - public final byte STRUCT = 0; - public final byte LIST = 1; - public final byte FAR = 2; - public final byte OTHER = 3; + public static final byte STRUCT = 0; + public static final byte LIST = 1; + public static final byte FAR = 2; + public static final byte OTHER = 3; public WirePointer(ByteBuffer buffer, int offset) { this.buffer = buffer; this.buffer_offset = offset; } + public WirePointer(WordPointer word) { + this.buffer = word.buffer; + this.buffer_offset = word.offset; + } + public int offset_and_kind() { return this.buffer.getInt(buffer_offset * 2); } @@ -27,6 +32,9 @@ class WirePointer { public WordPointer target() { return new WordPointer(buffer, 1 + (this.offset_and_kind() >> 2)); + } + public int inlineCompositeListElementCount() { + return this.offset_and_kind() >> 2; } } diff --git a/src/capnp/WordPointer.java b/src/capnp/WordPointer.java index 143139b..8b389a5 100644 --- a/src/capnp/WordPointer.java +++ b/src/capnp/WordPointer.java @@ -4,7 +4,7 @@ import java.nio.ByteBuffer; class WordPointer { public final ByteBuffer buffer; - public final int offset; // in words + public int offset; // in words public WordPointer(ByteBuffer buffer, int offset) { this.buffer = buffer;