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), " public final boolean has", titleCase, "() {\n",
|
||||||
spaces(indent), " return !_builder.getPointerField(", offset, ").isNull();\n",
|
spaces(indent), " return !_builder.getPointerField(", offset, ").isNull();\n",
|
||||||
spaces(indent), " }\n",
|
spaces(indent), " }\n",
|
||||||
|
|
||||||
spaces(indent), " public final ", type, ".", builderClass,
|
spaces(indent), " public final ", type, ".", builderClass,
|
||||||
" get", titleCase, "() {\n",
|
" 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), " }\n",
|
||||||
|
|
||||||
spaces(indent), " public final void set", titleCase, "(", type, ".Reader value) {\n",
|
spaces(indent), " public final void set", titleCase, "(", type, ".Reader value) {\n",
|
||||||
spaces(indent), " throw new Error();\n",
|
spaces(indent), " throw new Error();\n",
|
||||||
spaces(indent), " }\n",
|
spaces(indent), " }\n",
|
||||||
|
|
||||||
spaces(indent), " public final ", type, ".", builderClass,
|
spaces(indent), " public final ", type, ".", builderClass,
|
||||||
" init", titleCase, "(int size) {\n",
|
" init", titleCase, "(int size) {\n",
|
||||||
spaces(indent), " return new ", type, ".", builderClass, "(\n",
|
spaces(indent), " return new ", type, ".", builderClass, "(\n",
|
||||||
|
|
|
@ -45,7 +45,7 @@ object TestUtil {
|
||||||
|
|
||||||
builder.setEnumField(TestEnum.CORGE);
|
builder.setEnumField(TestEnum.CORGE);
|
||||||
|
|
||||||
//builder.initVoidList(6);
|
builder.initVoidList(6);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,6 +85,8 @@ object TestUtil {
|
||||||
assert(subSubBuilder.getTextField().toString() == "nested")
|
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;
|
this.structPointerCount = structPointerCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int size() {
|
||||||
|
return this.elementCount;
|
||||||
|
}
|
||||||
|
|
||||||
public final StructBuilder getStructElement(int index) {
|
public final StructBuilder getStructElement(int index) {
|
||||||
int indexBit = index * this.step;
|
int indexBit = index * this.step;
|
||||||
int structData = this.ptr + indexBit / 8 ;
|
int structData = this.ptr + indexBit / 8 ;
|
||||||
|
|
|
@ -21,6 +21,14 @@ public final class PointerBuilder {
|
||||||
return WireHelpers.getWritableStructPointer(this.pointer, this.segment, size);
|
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() {
|
public final Text.Builder getText() {
|
||||||
return WireHelpers.getWritableTextPointer(
|
return WireHelpers.getWritableTextPointer(
|
||||||
this.pointer, this.segment);
|
this.pointer, this.segment);
|
||||||
|
@ -35,7 +43,7 @@ public final class PointerBuilder {
|
||||||
}
|
}
|
||||||
|
|
||||||
public final ListBuilder initList(byte elementSize, int elementCount) {
|
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) {
|
public final ListBuilder initStructList(int elementCount, StructSize elementSize) {
|
||||||
|
|
|
@ -25,6 +25,11 @@ public class PrimitiveList {
|
||||||
this.builder = builder;
|
this.builder = builder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public int size() {
|
||||||
|
return this.builder.size();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,6 +57,10 @@ public class PrimitiveList {
|
||||||
this.builder = builder;
|
this.builder = builder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int size() {
|
||||||
|
return this.builder.size();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,7 +71,7 @@ final class WireHelpers {
|
||||||
int elementCount,
|
int elementCount,
|
||||||
byte elementSize) {
|
byte elementSize) {
|
||||||
if (elementSize == FieldSize.INLINE_COMPOSITE) {
|
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);
|
int dataSize = FieldSize.dataBitsPerElement(elementSize);
|
||||||
|
@ -115,6 +115,65 @@ final class WireHelpers {
|
||||||
elementSize.data * 64, elementSize.pointers);
|
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
|
// size is in bytes
|
||||||
public static Text.Builder initTextPointer(int refOffset,
|
public static Text.Builder initTextPointer(int refOffset,
|
||||||
SegmentBuilder segment,
|
SegmentBuilder segment,
|
||||||
|
|
Loading…
Reference in a new issue