initListPointer

This commit is contained in:
David Renshaw 2014-06-13 22:15:36 -04:00
parent 6239114885
commit 01edadb4c6
4 changed files with 66 additions and 3 deletions

View file

@ -35,7 +35,17 @@ object TestUtil {
subBuilder.setFloat32Field(-1.25e-10f);
subBuilder.setFloat64Field(345);
subBuilder.setTextField(new Text.Reader("baz"));
{
val subSubBuilder = subBuilder.initStructField();
subSubBuilder.setTextField(new Text.Reader("nested"));
subSubBuilder.initStructField().setTextField(new Text.Reader("really nested"));
}
}
builder.setEnumField(TestEnum.CORGE);
//builder.initVoidList(6);
}
@ -69,6 +79,11 @@ object TestUtil {
assert(subBuilder.getUInt64Field() == 345678901234567890L);
assert(subBuilder.getFloat32Field() == -1.25e-10f);
assert(subBuilder.getFloat64Field() == 345);
{
val subSubBuilder = subBuilder.getStructField();
assert(subSubBuilder.getTextField().toString() == "nested")
}
}
}

View file

@ -0,0 +1,8 @@
package org.capnproto;
final class Constants {
public static final int BITS_PER_POINTER = 64;
public static final int BITS_PER_WORD = 64;
public static final int BYTES_PER_WORD = 8;
public static final int POINTER_SIZE_IN_WORDS = 1;
}

View file

@ -9,4 +9,25 @@ public final class FieldSize {
public static final byte EIGHT_BYTES = 5;
public static final byte POINTER = 6;
public static final byte INLINE_COMPOSITE = 7;
public static final int dataBitsPerElement(byte size) {
switch (size) {
case VOID: return 0;
case BIT: return 1;
case BYTE: return 8;
case TWO_BYTES: return 16;
case FOUR_BYTES: return 32;
case EIGHT_BYTES: return 64;
case POINTER: return 0;
case INLINE_COMPOSITE: return 0;
default : throw new Error("impossible field size: " + size);
}
}
public static final int pointersPerElement(byte size) {
switch (size) {
case POINTER: return 1;
default: return 0;
}
}
}

View file

@ -6,9 +6,14 @@ final class WireHelpers {
return (bytes + 7) / 8;
}
public static int roundBitsUpToWords(long bits) {
//# This code assumes 64-bit words.
return (int)((bits + 63) / ((long) Constants.BITS_PER_WORD));
}
public static int allocate(int refOffset,
SegmentBuilder segment,
int amount,
int amount, // in words
byte kind) {
// TODO check for nullness, amount == 0 case.
@ -65,7 +70,20 @@ final class WireHelpers {
SegmentBuilder segment,
int elementCount,
byte elementSize) {
throw new Error("unimplemented");
if (elementSize == FieldSize.INLINE_COMPOSITE) {
throw new DecodeException("Should have called initStructListPointer instead");
}
int dataSize = FieldSize.dataBitsPerElement(elementSize);
int pointerCount = FieldSize.pointersPerElement(elementSize);
int step = dataSize + pointerCount * Constants.BITS_PER_POINTER;
int wordCount = roundBitsUpToWords((long)elementCount * (long)step);
int ptr = allocate(refOffset, segment, wordCount, WirePointer.LIST);
ListPointer.set(segment.buffer, refOffset, elementSize, elementCount);
return new ListBuilder(segment, ptr * Constants.BYTES_PER_WORD,
elementCount, step, dataSize, (short)pointerCount);
}
public static ListBuilder initStructListPointer(int refOffset,
@ -82,7 +100,8 @@ final class WireHelpers {
//# Allocate the list, prefixed by a single WirePointer.
int wordCount = elementCount * wordsPerElement;
int ptrOffset = allocate(refOffset, segment, 1 + wordCount, WirePointer.LIST);
int ptrOffset = allocate(refOffset, segment, Constants.POINTER_SIZE_IN_WORDS + wordCount,
WirePointer.LIST);
//# Initialize the pointer.
ListPointer.setInlineComposite(segment.buffer, refOffset, wordCount);