From 561ca944c8a0fabb804454f9c060d0403033ca7a Mon Sep 17 00:00:00 2001 From: David Renshaw Date: Wed, 15 Oct 2014 20:25:45 -0400 Subject: [PATCH] more copyPointer --- .../main/java/org/capnproto/ElementSize.java | 2 +- .../main/java/org/capnproto/WireHelpers.java | 37 ++++++++++++++++--- 2 files changed, 33 insertions(+), 6 deletions(-) diff --git a/runtime/src/main/java/org/capnproto/ElementSize.java b/runtime/src/main/java/org/capnproto/ElementSize.java index a145d93..26446c1 100644 --- a/runtime/src/main/java/org/capnproto/ElementSize.java +++ b/runtime/src/main/java/org/capnproto/ElementSize.java @@ -45,7 +45,7 @@ public final class ElementSize { } } - public static final int pointersPerElement(byte size) { + public static final short pointersPerElement(byte size) { switch (size) { case POINTER: return 1; default: return 0; diff --git a/runtime/src/main/java/org/capnproto/WireHelpers.java b/runtime/src/main/java/org/capnproto/WireHelpers.java index 0f1c8fb..a26d614 100644 --- a/runtime/src/main/java/org/capnproto/WireHelpers.java +++ b/runtime/src/main/java/org/capnproto/WireHelpers.java @@ -552,7 +552,7 @@ final class WireHelpers { } resolved.segment.arena.checkReadLimit(StructPointer.wordSize(resolved.ref)); return setStructPointer(dstSegment, dstOffset, - new StructReader(srcSegment, + new StructReader(resolved.segment, resolved.ptr, resolved.ptr + StructPointer.dataSize(resolved.ref), StructPointer.dataSize(resolved.ref) * Constants.BITS_PER_WORD, @@ -575,16 +575,43 @@ final class WireHelpers { } int elementCount = WirePointer.inlineCompositeListElementCount(tag); - // ... + int wordsPerElement = StructPointer.wordSize(tag); + if (wordsPerElement * elementCount > wordCount) { + throw new DecodeException("INLINE_COMPOSITE list's elements overrun its word count."); + } + return setListPointer(dstSegment, dstOffset, + new ListReader(resolved.segment, + resolved.ptr, + elementCount, + wordsPerElement * Constants.BITS_PER_WORD, + StructPointer.dataSize(resolved.ref) * Constants.BITS_PER_WORD, + StructPointer.ptrCount(resolved.ref), + nestingLimit - 1)); } else { - // ... + int dataSize = ElementSize.dataBitsPerElement(elementSize); + short pointerCount = ElementSize.pointersPerElement(elementSize); + int step = dataSize + pointerCount * Constants.BITS_PER_POINTER; + int elementCount = ListPointer.elementCount(resolved.ref); + int wordCount = roundBitsUpToWords((long) elementCount * step); + + resolved.segment.arena.checkReadLimit(wordCount); + + return setListPointer(dstSegment, dstOffset, + new ListReader(resolved.segment, + resolved.ptr, + elementCount, + step, + dataSize, + pointerCount, + nestingLimit - 1)); } case WirePointer.FAR : + throw new Error("Far pointer should have been handled above."); case WirePointer.OTHER : + throw new Error("copyPointer is unimplemented"); } - - throw new Error("copyPointer is unimplemented"); + throw new Error("unreachable"); } static T readListPointer(ListReader.Factory factory,