diff --git a/compiler/src/test/scala/org/capnproto/EncodingTest.scala b/compiler/src/test/scala/org/capnproto/EncodingTest.scala index 3bb8fc1..560f63c 100644 --- a/compiler/src/test/scala/org/capnproto/EncodingTest.scala +++ b/compiler/src/test/scala/org/capnproto/EncodingTest.scala @@ -12,7 +12,7 @@ class EncodingSuite extends FunSuite { val allTypes = message.initRoot(TestAllTypes.Builder.factory); TestUtil.initTestMessage(allTypes); TestUtil.checkTestMessage(allTypes); - //TestUtil.checkTestMessage(allTypes.asReader()); + TestUtil.checkTestMessage(allTypes.asReader()); } test("AllTypesMultiSegment") { @@ -21,6 +21,7 @@ class EncodingSuite extends FunSuite { TestUtil.initTestMessage(allTypes); TestUtil.checkTestMessage(allTypes); + //TestUtil.checkTestMessage(allTypes.asReader()); } // to debug, do this: diff --git a/runtime/src/main/java/org/capnproto/WireHelpers.java b/runtime/src/main/java/org/capnproto/WireHelpers.java index 1f0c2f6..bc3bfe5 100644 --- a/runtime/src/main/java/org/capnproto/WireHelpers.java +++ b/runtime/src/main/java/org/capnproto/WireHelpers.java @@ -412,12 +412,46 @@ final class WireHelpers { StructPointer.ptrCount(tag), nestingLimit - 1); } - case FieldSize.VOID : break; - default : - throw new Error("unrecognized element size"); - } + default : { + //# This is a primitive or pointer list, but all such + //# lists can also be interpreted as struct lists. We + //# need to compute the data size and pointer count for + //# such structs. - throw new Error(); + int dataSize = FieldSize.dataBitsPerElement(ListPointer.elementSize(resolved.ref)); + int pointerCount = FieldSize.pointersPerElement(ListPointer.elementSize(resolved.ref)); + int step = dataSize + pointerCount * Constants.BITS_PER_POINTER; + + // TODO "bounds_check" + + //# Verify that the elements are at least as large as + //# the expected type. Note that if we expected + //# InlineComposite, the expected sizes here will be + //# zero, because bounds checking will be performed at + //# field access time. So this check here is for the + //# case where we expected a list of some primitive or + //# pointer type. + + int expectedDataBitsPerElement = FieldSize.dataBitsPerElement(expectedElementSize); + int expectedPointersPerElement = FieldSize.pointersPerElement(expectedElementSize); + + if (expectedDataBitsPerElement > dataSize) { + throw new DecodeException("Message contains list with incompatible element type."); + } + + if (expectedPointersPerElement > pointerCount) { + throw new DecodeException("Message contains list with incompatible element type."); + } + + return new ListReader(resolved.segment, + resolved.ptr * Constants.BYTES_PER_WORD, + ListPointer.elementCount(resolved.ref), + step, + dataSize, + (short)pointerCount, + nestingLimit - 1); + } + } } public static Text.Reader readTextPointer(SegmentReader segment,