struct defaults

This commit is contained in:
David Renshaw 2014-10-06 14:05:59 -04:00
parent f9dbcc3a53
commit de33553666
8 changed files with 119 additions and 30 deletions

View file

@ -965,6 +965,9 @@ private:
}; };
} else if (kind == FieldKind::STRUCT) { } else if (kind == FieldKind::STRUCT) {
uint64_t typeId = field.getContainingStruct().getProto().getId();
kj::String defaultParams = defaultOffset == 0 ? kj::str("null, 0") : kj::str(
"Schemas.b_", kj::hex(typeId), ", ", defaultOffset);
return FieldText { return FieldText {
kj::strTree( kj::strTree(
@ -976,7 +979,7 @@ private:
spaces(indent), " public ", type, ".Reader get", titleCase, "() {\n", spaces(indent), " public ", type, ".Reader get", titleCase, "() {\n",
unionDiscrim.check, unionDiscrim.check,
spaces(indent), " return ", type, spaces(indent), " return ", type,
".factory.fromStructReader(_reader.getPointerField(", offset,").getStruct());\n", ".factory.fromStructReader(_reader.getPointerField(", offset,").getStruct(", defaultParams, "));\n",
spaces(indent), " }\n", "\n"), spaces(indent), " }\n", "\n"),
kj::strTree( kj::strTree(
@ -985,7 +988,7 @@ private:
unionDiscrim.check, unionDiscrim.check,
spaces(indent), " return ", type, spaces(indent), " return ", type,
".factory.fromStructBuilder(_builder.getPointerField(", offset, ").getStruct(", ".factory.fromStructBuilder(_builder.getPointerField(", offset, ").getStruct(",
type, ".STRUCT_SIZE", "));\n", type, ".STRUCT_SIZE,", defaultParams, "));\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",
unionDiscrim.set, unionDiscrim.set,
@ -1003,7 +1006,7 @@ private:
uint64_t typeId = field.getContainingStruct().getProto().getId(); uint64_t typeId = field.getContainingStruct().getProto().getId();
kj::String defaultParams = defaultOffset == 0 ? kj::str() : kj::str( kj::String defaultParams = defaultOffset == 0 ? kj::str() : kj::str(
"Schemas.b_", kj::hex(typeId), ".buffer, ", defaultOffset * 8, ", ", defaultSize); "Schemas.b_", kj::hex(typeId), ".buffer, ", defaultOffset, ", ", defaultSize);
kj::String blobKind = typeBody.which() == schema::Type::TEXT ? kj::str("Text") : kj::str("Data"); kj::String blobKind = typeBody.which() == schema::Type::TEXT ? kj::str("Text") : kj::str("Data");
kj::String setterInputType = typeBody.which() == schema::Type::TEXT ? kj::str("String") : kj::str("byte []"); kj::String setterInputType = typeBody.which() == schema::Type::TEXT ? kj::str("String") : kj::str("byte []");

View file

@ -194,5 +194,4 @@ class EncodingSuite extends FunSuite {
//Serialize.writeMessage((new java.io.FileOutputStream("/Users/dwrensha/Desktop/test.dat")).getChannel(), //Serialize.writeMessage((new java.io.FileOutputStream("/Users/dwrensha/Desktop/test.dat")).getChannel(),
// message); // message);
} }

View file

@ -255,7 +255,23 @@ object TestUtil {
assert(reader.getFloat32Field() == 1234.5f); assert(reader.getFloat32Field() == 1234.5f);
assert(reader.getFloat64Field() == -123e45); assert(reader.getFloat64Field() == -123e45);
(reader.getTextField().toString()) should equal ("foo"); (reader.getTextField().toString()) should equal ("foo");
(reader.getDataField().toArray()) should equal (Array(0x62,0x61,0x72));
{
val subReader = reader.getStructField();
subReader.getVoidField();
subReader.getBoolField() should equal (true);
subReader.getInt8Field() should equal (-12);
subReader.getInt16Field() should equal (3456);
subReader.getInt32Field() should equal (-78901234);
// ...
subReader.getTextField().toString() should equal ("baz");
{
val subSubReader = subReader.getStructField();
subSubReader.getTextField().toString() should equal ("nested");
} }
}
}
} }

View file

@ -70,6 +70,50 @@ struct TestDefaults {
float64Field @11 : Float64 = -123e45; float64Field @11 : Float64 = -123e45;
textField @12 : Text = "foo"; textField @12 : Text = "foo";
dataField @13 : Data = "bar"; # 0x"62 61 72"; dataField @13 : Data = "bar"; # 0x"62 61 72";
structField @14 : TestAllTypes = (
voidField = void,
boolField = true,
int8Field = -12,
int16Field = 3456,
int32Field = -78901234,
int64Field = 56789012345678,
uInt8Field = 90,
uInt16Field = 1234,
uInt32Field = 56789012,
uInt64Field = 345678901234567890,
float32Field = -1.25e-10,
float64Field = 345,
textField = "baz",
dataField = "qux",
structField = (
textField = "nested",
structField = (textField = "really nested")),
enumField = baz,
# interfaceField can't have a default
voidList = [void, void, void],
boolList = [false, true, false, true, true],
int8List = [12, -34, -0x80, 0x7f],
int16List = [1234, -5678, -0x8000, 0x7fff],
int32List = [12345678, -90123456, -0x80000000, 0x7fffffff],
int64List = [123456789012345, -678901234567890, -0x8000000000000000, 0x7fffffffffffffff],
uInt8List = [12, 34, 0, 0xff],
uInt16List = [1234, 5678, 0, 0xffff],
uInt32List = [12345678, 90123456, 0, 0xffffffff],
uInt64List = [123456789012345, 678901234567890, 0, 0xffffffffffffffff],
float32List = [0, 1234567, 1e37, -1e37, 1e-37, -1e-37],
float64List = [0, 123456789012345, 1e306, -1e306, 1e-306, -1e-306],
textList = ["quux", "corge", "grault"],
dataList = ["garply", "waldo", "fred"],
structList = [
(textField = "x structlist 1"),
(textField = "x structlist 2"),
(textField = "x structlist 3")],
enumList = [qux, bar, grault]
# interfaceList can't have a default
);
} }
struct TestAnyPointer { struct TestAnyPointer {

View file

@ -18,7 +18,11 @@ public final class PointerBuilder {
} }
public final StructBuilder getStruct(StructSize size) { public final StructBuilder getStruct(StructSize size) {
return WireHelpers.getWritableStructPointer(this.pointer, this.segment, size); return WireHelpers.getWritableStructPointer(this.pointer, this.segment, size, null, 0);
}
public final StructBuilder getStruct(StructSize size, SegmentReader defaultBuffer, int defaultOffset) {
return WireHelpers.getWritableStructPointer(this.pointer, this.segment, size, defaultBuffer, defaultOffset);
} }
public final ListBuilder getList(byte elementSize) { public final ListBuilder getList(byte elementSize) {

View file

@ -29,28 +29,25 @@ public final class PointerReader {
} }
public StructReader getStruct() { public StructReader getStruct() {
if (this.segment == null) {
return WireHelpers.readStructPointer(SegmentReader.EMPTY, 0, this.nestingLimit);
} else {
return WireHelpers.readStructPointer(this.segment, return WireHelpers.readStructPointer(this.segment,
this.pointer, this.pointer,
null, 0,
this.nestingLimit); this.nestingLimit);
} }
public StructReader getStruct(SegmentReader defaultSegment, int defaultOffset) {
return WireHelpers.readStructPointer(this.segment,
this.pointer,
defaultSegment, defaultOffset,
this.nestingLimit);
} }
public ListReader getList(byte expectedElementSize) { public ListReader getList(byte expectedElementSize) {
if (this.segment == null) {
return WireHelpers.readListPointer(SegmentReader.EMPTY,
0,
expectedElementSize,
this.nestingLimit);
} else {
return WireHelpers.readListPointer(this.segment, return WireHelpers.readListPointer(this.segment,
this.pointer, this.pointer,
expectedElementSize, expectedElementSize,
this.nestingLimit); this.nestingLimit);
} }
}
public Text.Reader getText() { public Text.Reader getText() {
return WireHelpers.readTextPointer(this.segment, this.pointer, null, 0, 0); return WireHelpers.readTextPointer(this.segment, this.pointer, null, 0, 0);

View file

@ -9,6 +9,16 @@ public final class StructReader {
final byte bit0Offset; final byte bit0Offset;
final int nestingLimit; final int nestingLimit;
public StructReader() {
this.segment = SegmentReader.EMPTY;
this.data = 0;
this.pointers = 0;
this.dataSize = 0;
this.pointerCount = 0;
this.bit0Offset = 0;
this.nestingLimit = 0x7fffffff;
}
public StructReader(SegmentReader segment, int data, public StructReader(SegmentReader segment, int data,
int pointers, int dataSize, short pointerCount, int pointers, int dataSize, short pointerCount,
byte bit0Offset, int nestingLimit) { byte bit0Offset, int nestingLimit) {

View file

@ -157,11 +157,17 @@ final class WireHelpers {
static StructBuilder getWritableStructPointer(int refOffset, static StructBuilder getWritableStructPointer(int refOffset,
SegmentBuilder segment, SegmentBuilder segment,
StructSize size) { StructSize size,
SegmentReader defaultSegment,
int defaultOffset) {
long ref = WirePointer.get(segment.buffer, refOffset); long ref = WirePointer.get(segment.buffer, refOffset);
int target = WirePointer.target(refOffset, ref); int target = WirePointer.target(refOffset, ref);
if (WirePointer.isNull(ref)) { if (WirePointer.isNull(ref)) {
if (defaultSegment == null) {
return initStructPointer(refOffset, segment, size); return initStructPointer(refOffset, segment, size);
} else {
throw new Error("unimplemented");
}
} }
FollowBuilderFarsResult resolved = followBuilderFars(ref, target, segment); FollowBuilderFarsResult resolved = followBuilderFars(ref, target, segment);
@ -325,7 +331,7 @@ final class WireHelpers {
Text.Builder builder = initTextPointer(refOffset, segment, defaultSize); Text.Builder builder = initTextPointer(refOffset, segment, defaultSize);
// TODO is there a way to do this with bulk methods? // TODO is there a way to do this with bulk methods?
for (int i = 0; i < builder.size; ++i) { for (int i = 0; i < builder.size; ++i) {
builder.buffer.put(builder.offset + i, defaultBuffer.get(defaultOffset + i)); builder.buffer.put(builder.offset + i, defaultBuffer.get(defaultOffset * 8 + i));
} }
return builder; return builder;
} }
@ -389,7 +395,7 @@ final class WireHelpers {
Data.Builder builder = initDataPointer(refOffset, segment, defaultSize); Data.Builder builder = initDataPointer(refOffset, segment, defaultSize);
// TODO is there a way to do this with bulk methods? // TODO is there a way to do this with bulk methods?
for (int i = 0; i < builder.size; ++i) { for (int i = 0; i < builder.size; ++i) {
builder.buffer.put(builder.offset + i, defaultBuffer.get(defaultOffset + i)); builder.buffer.put(builder.offset + i, defaultBuffer.get(defaultOffset * 8 + i));
} }
return builder; return builder;
} }
@ -413,13 +419,23 @@ final class WireHelpers {
static StructReader readStructPointer(SegmentReader segment, static StructReader readStructPointer(SegmentReader segment,
int refOffset, int refOffset,
SegmentReader defaultSegment,
int defaultOffset,
int nestingLimit) { int nestingLimit) {
// TODO error handling. is_null long ref = WirePointer.get(segment.buffer, refOffset);
if (WirePointer.isNull(ref)) {
if (defaultSegment == null) {
return new StructReader();
} else {
return (new PointerReader(defaultSegment, defaultOffset, 0x7fffffff)).getStruct();
}
}
if (nestingLimit <= 0) { if (nestingLimit <= 0) {
throw new DecodeException("Message is too deeply nested or contains cycles."); throw new DecodeException("Message is too deeply nested or contains cycles.");
} }
long ref = WirePointer.get(segment.buffer, refOffset);
int refTarget = WirePointer.target(refOffset, ref); int refTarget = WirePointer.target(refOffset, ref);
FollowFarsResult resolved = followFars(ref, refTarget, segment); FollowFarsResult resolved = followFars(ref, refTarget, segment);