getWritableListPointer
This commit is contained in:
parent
c3142893f7
commit
b39b352dc6
7 changed files with 101 additions and 4 deletions
|
@ -1098,13 +1098,21 @@ private:
|
|||
spaces(indent), " public final boolean has", titleCase, "() {\n",
|
||||
spaces(indent), " return !_builder.getPointerField(", offset, ").isNull();\n",
|
||||
spaces(indent), " }\n",
|
||||
|
||||
spaces(indent), " public final ", type, ".", builderClass,
|
||||
" get", titleCase, "() {\n",
|
||||
spaces(indent), " throw new Error();\n",
|
||||
spaces(indent), " return new ", type, ".", builderClass, " (\n",
|
||||
spaces(indent), " ", builderFactoryArg, "_builder.getPointerField(", offset, ").get",
|
||||
(isStructList ?
|
||||
kj::strTree("StructList(", typeName(typeBody.getList().getElementType()),".STRUCT_SIZE)") :
|
||||
kj::strTree("List(", fieldSize, ")")),
|
||||
");\n",
|
||||
spaces(indent), " }\n",
|
||||
|
||||
spaces(indent), " public final void set", titleCase, "(", type, ".Reader value) {\n",
|
||||
spaces(indent), " throw new Error();\n",
|
||||
spaces(indent), " }\n",
|
||||
|
||||
spaces(indent), " public final ", type, ".", builderClass,
|
||||
" init", titleCase, "(int size) {\n",
|
||||
spaces(indent), " return new ", type, ".", builderClass, "(\n",
|
||||
|
|
|
@ -45,7 +45,7 @@ object TestUtil {
|
|||
|
||||
builder.setEnumField(TestEnum.CORGE);
|
||||
|
||||
//builder.initVoidList(6);
|
||||
builder.initVoidList(6);
|
||||
|
||||
}
|
||||
|
||||
|
@ -85,6 +85,8 @@ object TestUtil {
|
|||
assert(subSubBuilder.getTextField().toString() == "nested")
|
||||
}
|
||||
}
|
||||
|
||||
assert(builder.getVoidList().size() == 6);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
7
runtime/src/main/java/org/capnproto/InternalError.java
Normal file
7
runtime/src/main/java/org/capnproto/InternalError.java
Normal file
|
@ -0,0 +1,7 @@
|
|||
package org.capnproto;
|
||||
|
||||
public final class InternalError extends RuntimeException {
|
||||
public InternalError(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
|
@ -19,6 +19,10 @@ public final class ListBuilder {
|
|||
this.structPointerCount = structPointerCount;
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return this.elementCount;
|
||||
}
|
||||
|
||||
public final StructBuilder getStructElement(int index) {
|
||||
int indexBit = index * this.step;
|
||||
int structData = this.ptr + indexBit / 8 ;
|
||||
|
|
|
@ -21,6 +21,14 @@ public final class PointerBuilder {
|
|||
return WireHelpers.getWritableStructPointer(this.pointer, this.segment, size);
|
||||
}
|
||||
|
||||
public final ListBuilder getList(byte elementSize) {
|
||||
return WireHelpers.getWritableListPointer(this.pointer, this.segment, elementSize);
|
||||
}
|
||||
|
||||
public final ListBuilder getStructList(StructSize elementSize) {
|
||||
throw new Error("unimplemented");
|
||||
}
|
||||
|
||||
public final Text.Builder getText() {
|
||||
return WireHelpers.getWritableTextPointer(
|
||||
this.pointer, this.segment);
|
||||
|
@ -35,7 +43,7 @@ public final class PointerBuilder {
|
|||
}
|
||||
|
||||
public final ListBuilder initList(byte elementSize, int elementCount) {
|
||||
throw new Error("unimplemented");
|
||||
return WireHelpers.initListPointer(this.pointer, this.segment, elementCount, elementSize);
|
||||
}
|
||||
|
||||
public final ListBuilder initStructList(int elementCount, StructSize elementSize) {
|
||||
|
|
|
@ -25,6 +25,11 @@ public class PrimitiveList {
|
|||
this.builder = builder;
|
||||
}
|
||||
|
||||
|
||||
public int size() {
|
||||
return this.builder.size();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -52,6 +57,10 @@ public class PrimitiveList {
|
|||
this.builder = builder;
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return this.builder.size();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -71,7 +71,7 @@ final class WireHelpers {
|
|||
int elementCount,
|
||||
byte elementSize) {
|
||||
if (elementSize == FieldSize.INLINE_COMPOSITE) {
|
||||
throw new DecodeException("Should have called initStructListPointer instead");
|
||||
throw new InternalError("Should have called initStructListPointer instead");
|
||||
}
|
||||
|
||||
int dataSize = FieldSize.dataBitsPerElement(elementSize);
|
||||
|
@ -115,6 +115,65 @@ final class WireHelpers {
|
|||
elementSize.data * 64, elementSize.pointers);
|
||||
}
|
||||
|
||||
public static ListBuilder getWritableListPointer(int origRefOffset,
|
||||
SegmentBuilder origSegment,
|
||||
byte elementSize) {
|
||||
if (elementSize == FieldSize.INLINE_COMPOSITE) {
|
||||
throw new InternalError("Use getStructList{Element,Field} for structs");
|
||||
}
|
||||
|
||||
long origRef = WirePointer.get(origSegment.buffer, origRefOffset);
|
||||
int origRefTarget = WirePointer.target(origRefOffset, origRef);
|
||||
|
||||
if (WirePointer.isNull(origRef)) {
|
||||
throw new Error("unimplemented");
|
||||
}
|
||||
|
||||
//# We must verify that the pointer has the right size. Unlike
|
||||
//# in getWritableStructListReference(), we never need to
|
||||
//# "upgrade" the data, because this method is called only for
|
||||
//# non-struct lists, and there is no allowed upgrade path *to*
|
||||
//# a non-struct list, only *from* them.
|
||||
|
||||
long ref = origRef;
|
||||
SegmentBuilder segment = origSegment;
|
||||
int ptr = origRefTarget; // TODO follow fars.
|
||||
|
||||
if (WirePointer.kind(ref) != WirePointer.LIST) {
|
||||
throw new DecodeException("Called getList{Field,Element}() but existing pointer is not a list");
|
||||
}
|
||||
|
||||
byte oldSize = ListPointer.elementSize(WirePointer.listPointer(ref));
|
||||
|
||||
if (oldSize == FieldSize.INLINE_COMPOSITE) {
|
||||
//# The existing element size is InlineComposite, which
|
||||
//# means that it is at least two words, which makes it
|
||||
//# bigger than the expected element size. Since fields can
|
||||
//# only grow when upgraded, the existing data must have
|
||||
//# been written with a newer version of the protocol. We
|
||||
//# therefore never need to upgrade the data in this case,
|
||||
//# but we do need to validate that it is a valid upgrade
|
||||
//# from what we expected.
|
||||
throw new Error("unimplemented");
|
||||
} else {
|
||||
int dataSize = FieldSize.dataBitsPerElement(oldSize);
|
||||
int pointerCount = FieldSize.pointersPerElement(oldSize);
|
||||
|
||||
if (dataSize < FieldSize.dataBitsPerElement(elementSize)) {
|
||||
throw new DecodeException("Existing list value is incompatible with expected type.");
|
||||
}
|
||||
if (pointerCount < FieldSize.pointersPerElement(elementSize)) {
|
||||
throw new DecodeException("Existing list value is incompatible with expected type.");
|
||||
}
|
||||
|
||||
int step = dataSize + pointerCount * Constants.BITS_PER_POINTER;
|
||||
|
||||
return new ListBuilder(segment, ptr * Constants.BYTES_PER_WORD,
|
||||
ListPointer.elementCount(WirePointer.listPointer(ref)),
|
||||
step, dataSize, (short) pointerCount);
|
||||
}
|
||||
}
|
||||
|
||||
// size is in bytes
|
||||
public static Text.Builder initTextPointer(int refOffset,
|
||||
SegmentBuilder segment,
|
||||
|
|
Loading…
Reference in a new issue