diff --git a/compiler/src/main/cpp/capnpc-java.c++ b/compiler/src/main/cpp/capnpc-java.c++ index 7f4391d..1a8ff4d 100644 --- a/compiler/src/main/cpp/capnpc-java.c++ +++ b/compiler/src/main/cpp/capnpc-java.c++ @@ -942,6 +942,10 @@ private: } else if (kind == FieldKind::BLOB && typeBody.which() == schema::Type::TEXT ) { + uint64_t typeId = field.getContainingStruct().getProto().getId(); + kj::String defaultParams = defaultOffset == 0 ? kj::str() : kj::str( + "Schemas.b_", kj::hex(typeId), ", ", defaultOffset * 8, ", ", defaultSize); + kj::String blobKind = kj::str("Text"); return FieldText { @@ -955,7 +959,7 @@ private: spaces(indent), " public ", type, ".Reader", " get", titleCase, "() {\n", spaces(indent), " return _reader.getPointerField(", - offset, ").get", blobKind, " ();\n", // XXX + offset, ").getText(", defaultParams, ");\n", spaces(indent), " }\n", "\n"), kj::strTree( @@ -966,7 +970,7 @@ private: spaces(indent), " }\n", spaces(indent), " public final ", type, ".Builder get", titleCase, "() {\n", spaces(indent), " return _builder.getPointerField(", - offset, ").get", blobKind, " ();\n", // XXX + offset, ").get", blobKind, "(", defaultParams, ");\n", spaces(indent), " }\n", spaces(indent), " public final void set", titleCase, "(", type, ".Reader value) {\n", unionDiscrim.set, diff --git a/compiler/src/test/scala/org/capnproto/TestUtil.scala b/compiler/src/test/scala/org/capnproto/TestUtil.scala index 82b98f5..a940642 100644 --- a/compiler/src/test/scala/org/capnproto/TestUtil.scala +++ b/compiler/src/test/scala/org/capnproto/TestUtil.scala @@ -237,6 +237,7 @@ object TestUtil { assert(builder.getUInt64Field() == 0xab54a98ceb1f0ad2L); assert(builder.getFloat32Field() == 1234.5f); assert(builder.getFloat64Field() == -123e45); + (builder.getTextField().toString()) should equal ("foo"); } def checkDefaultMessage(reader : TestDefaults.Reader) { @@ -252,6 +253,7 @@ object TestUtil { assert(reader.getUInt64Field() == 0xab54a98ceb1f0ad2L); assert(reader.getFloat32Field() == 1234.5f); assert(reader.getFloat64Field() == -123e45); + (reader.getTextField().toString()) should equal ("foo"); } diff --git a/compiler/src/test/schema/test.capnp b/compiler/src/test/schema/test.capnp index fae2c21..424bbed 100644 --- a/compiler/src/test/schema/test.capnp +++ b/compiler/src/test/schema/test.capnp @@ -66,6 +66,7 @@ struct TestDefaults { uInt64Field @9 : UInt64 = 12345678901234567890; float32Field @10 : Float32 = 1234.5; float64Field @11 : Float64 = -123e45; + textField @12 : Text = "foo"; } struct TestAnyPointer { diff --git a/runtime/src/main/java/org/capnproto/PointerBuilder.java b/runtime/src/main/java/org/capnproto/PointerBuilder.java index 4cf07e7..53243d4 100644 --- a/runtime/src/main/java/org/capnproto/PointerBuilder.java +++ b/runtime/src/main/java/org/capnproto/PointerBuilder.java @@ -31,7 +31,15 @@ public final class PointerBuilder { public final Text.Builder getText() { return WireHelpers.getWritableTextPointer( - this.pointer, this.segment); + this.pointer, this.segment, null, 0, 0); + } + + public Text.Builder getText(java.nio.ByteBuffer defaultBuffer, int defaultOffset, int defaultSize) { + return WireHelpers.getWritableTextPointer(this.pointer, + this.segment, + defaultBuffer, + defaultOffset, + defaultSize); } public final Data.Builder getData() { diff --git a/runtime/src/main/java/org/capnproto/PointerReader.java b/runtime/src/main/java/org/capnproto/PointerReader.java index fbaef62..85af9aa 100644 --- a/runtime/src/main/java/org/capnproto/PointerReader.java +++ b/runtime/src/main/java/org/capnproto/PointerReader.java @@ -53,8 +53,11 @@ public final class PointerReader { } public Text.Reader getText() { - return WireHelpers.readTextPointer(this.segment, - this.pointer); + return WireHelpers.readTextPointer(this.segment, this.pointer, null, 0, 0); + } + + public Text.Reader getText(java.nio.ByteBuffer defaultBuffer, int defaultOffset, int defaultSize) { + return WireHelpers.readTextPointer(this.segment, this.pointer, defaultBuffer, defaultOffset, defaultSize); } public Data.Reader getData() { diff --git a/runtime/src/main/java/org/capnproto/WireHelpers.java b/runtime/src/main/java/org/capnproto/WireHelpers.java index e202374..20e2e95 100644 --- a/runtime/src/main/java/org/capnproto/WireHelpers.java +++ b/runtime/src/main/java/org/capnproto/WireHelpers.java @@ -1,5 +1,7 @@ package org.capnproto; +import java.nio.ByteBuffer; + final class WireHelpers { public static int roundBytesUpToWords(int bytes) { @@ -310,12 +312,23 @@ final class WireHelpers { } public static Text.Builder getWritableTextPointer(int refOffset, - SegmentBuilder segment) { + SegmentBuilder segment, + ByteBuffer defaultBuffer, + int defaultOffset, + int defaultSize) { long ref = WirePointer.get(segment.buffer, refOffset); if (WirePointer.isNull(ref)) { - // TODO default values - return new Text.Builder(null, 0, 0); + if (defaultBuffer == null) { + return new Text.Builder(null, 0, 0); + } else { + Text.Builder builder = initTextPointer(refOffset, segment, defaultSize); + // TODO is there a way to do this with bulk methods? + for (int i = 0; i < builder.size; ++i) { + builder.buffer.put(builder.offset + i, defaultBuffer.get(defaultOffset + i)); + } + return builder; + } } int refTarget = WirePointer.target(refOffset, ref); @@ -454,12 +467,19 @@ final class WireHelpers { } public static Text.Reader readTextPointer(SegmentReader segment, - int refOffset) { + int refOffset, + ByteBuffer defaultBuffer, + int defaultOffset, + int defaultSize) { long ref = WirePointer.get(segment.buffer, refOffset); if (WirePointer.isNull(ref)) { - // XXX should use the default value - return new Text.Reader(java.nio.ByteBuffer.wrap(new byte[0]), 0, 0); + if (defaultBuffer == null) { + // XXX -- what about null terminator? + return new Text.Reader(ByteBuffer.wrap(new byte[0]), 0, 0); + } else { + return new Text.Reader(defaultBuffer, defaultOffset, defaultSize); + } } int refTarget = WirePointer.target(refOffset, ref);