From 980cf133d0b0ebceb69b786ec13e4113db48134f Mon Sep 17 00:00:00 2001 From: David Renshaw Date: Fri, 12 Sep 2014 14:34:24 -0400 Subject: [PATCH] integer defaults --- compiler/src/main/cpp/capnpc-java.c++ | 28 ++++++------- .../scala/org/capnproto/EncodingTest.scala | 7 ++++ .../test/scala/org/capnproto/TestUtil.scala | 32 +++++++++++++-- compiler/src/test/schema/test.capnp | 15 +++++++ .../java/org/capnproto/StructBuilder.java | 40 +++++++++++++++++++ .../main/java/org/capnproto/StructReader.java | 20 ++++++++++ 6 files changed, 125 insertions(+), 17 deletions(-) diff --git a/compiler/src/main/cpp/capnpc-java.c++ b/compiler/src/main/cpp/capnpc-java.c++ index d6d6fbd..3ad17ca 100644 --- a/compiler/src/main/cpp/capnpc-java.c++ +++ b/compiler/src/main/cpp/capnpc-java.c++ @@ -708,23 +708,23 @@ private: setterDefault = " = ::capnp::VOID"; break; -#define HANDLE_PRIMITIVE(discrim, typeName, defaultName, suffix) \ +#define HANDLE_PRIMITIVE(discrim, typeName, javaTypeName, defaultName, suffix) \ case schema::Type::discrim: \ kind = FieldKind::PRIMITIVE; \ if (defaultBody.get##defaultName() != 0) { \ - defaultMask = kj::str(defaultBody.get##defaultName(), #suffix); \ + defaultMask = kj::str("(", #javaTypeName, ")", kj::implicitCast< typeName>(defaultBody.get##defaultName()), #suffix); \ } \ break; - HANDLE_PRIMITIVE(BOOL, bool, Bool, ); - HANDLE_PRIMITIVE(INT8 , ::int8_t , Int8 , ); - HANDLE_PRIMITIVE(INT16, ::int16_t, Int16, ); - HANDLE_PRIMITIVE(INT32, ::int32_t, Int32, ); - HANDLE_PRIMITIVE(INT64, ::int64_t, Int64, ll); - HANDLE_PRIMITIVE(UINT8 , ::uint8_t , Uint8 , u); - HANDLE_PRIMITIVE(UINT16, ::uint16_t, Uint16, u); - HANDLE_PRIMITIVE(UINT32, ::uint32_t, Uint32, u); - HANDLE_PRIMITIVE(UINT64, ::uint64_t, Uint64, ull); + HANDLE_PRIMITIVE(BOOL, bool, boolean, Bool, ); + HANDLE_PRIMITIVE(INT8 , ::int8_t , byte, Int8 , ); + HANDLE_PRIMITIVE(INT16, ::int16_t, short, Int16, ); + HANDLE_PRIMITIVE(INT32, ::int32_t, int, Int32, ); + HANDLE_PRIMITIVE(INT64, ::int64_t, long, Int64, L); + HANDLE_PRIMITIVE(UINT8 , ::int8_t , byte, Uint8 , ); + HANDLE_PRIMITIVE(UINT16, ::int16_t, short, Uint16, ); + HANDLE_PRIMITIVE(UINT32, ::int32_t, int, Uint32, ); + HANDLE_PRIMITIVE(UINT64, ::int64_t, long, Uint64, L); #undef HANDLE_PRIMITIVE case schema::Type::FLOAT32: @@ -811,7 +811,7 @@ private: kj::strTree(" return ", type, ".values()[_reader.getShortField(", offset, ")];\n") : (typeBody.which() == schema::Type::VOID ? kj::strTree(" return org.capnproto.Void.VOID;\n") : - kj::strTree(" return _reader.get",toTitleCase(type),"Field(", offset, ");\n"))), + kj::strTree(" return _reader.get",toTitleCase(type),"Field(", offset, defaultMaskParam, ");\n"))), spaces(indent), " }\n", "\n"), @@ -823,7 +823,7 @@ private: kj::strTree(" return ", type, ".values()[_builder.getShortField(", offset, ")];\n") : (typeBody.which() == schema::Type::VOID ? kj::strTree(" return org.capnproto.Void.VOID;\n") : - kj::strTree(" return _builder.get",toTitleCase(type),"Field(", offset, ");\n"))), + kj::strTree(" return _builder.get",toTitleCase(type),"Field(", offset, defaultMaskParam, ");\n"))), spaces(indent), " }\n", spaces(indent), " public final void set", titleCase, "(", type, " value) {\n", @@ -833,7 +833,7 @@ private: (typeBody.which() == schema::Type::VOID ? kj::strTree() : kj::strTree(spaces(indent), " _builder.set", - toTitleCase(type), "Field(", offset, ", value);\n"))), + toTitleCase(type), "Field(", offset, ", value", defaultMaskParam, ");\n"))), spaces(indent), " }\n", "\n"), diff --git a/compiler/src/test/scala/org/capnproto/EncodingTest.scala b/compiler/src/test/scala/org/capnproto/EncodingTest.scala index 918ffb5..a0d0432 100644 --- a/compiler/src/test/scala/org/capnproto/EncodingTest.scala +++ b/compiler/src/test/scala/org/capnproto/EncodingTest.scala @@ -24,6 +24,13 @@ class EncodingSuite extends FunSuite { TestUtil.checkTestMessage(allTypes.asReader()); } + test("Defaults") { + val message = new MessageBuilder(); + val defaults = message.initRoot(TestDefaults.factory); + TestUtil.checkDefaultMessage(defaults); + TestUtil.checkDefaultMessage(defaults.asReader()); + } + test("Groups") { val builder = new MessageBuilder(); val root = builder.initRoot(TestGroups.factory); diff --git a/compiler/src/test/scala/org/capnproto/TestUtil.scala b/compiler/src/test/scala/org/capnproto/TestUtil.scala index e001a85..e8a7540 100644 --- a/compiler/src/test/scala/org/capnproto/TestUtil.scala +++ b/compiler/src/test/scala/org/capnproto/TestUtil.scala @@ -12,7 +12,7 @@ object TestUtil { builder.setInt16Field(-12345); builder.setInt32Field(-12345678); builder.setInt64Field(-123456789012345L); - builder.setUInt8Field(0xef.toByte); + builder.setUInt8Field(0xea.toByte); builder.setUInt16Field(0x4567); builder.setUInt32Field(0x34567890); builder.setUInt64Field(0x1234567890123456L); @@ -67,7 +67,7 @@ object TestUtil { assert(builder.getInt16Field() == -12345); assert(builder.getInt32Field() == -12345678); assert(builder.getInt64Field() == -123456789012345L); - assert(builder.getUInt8Field() == 0xef.toByte); + assert(builder.getUInt8Field() == 0xea.toByte); assert(builder.getUInt16Field() == 0x4567); assert(builder.getUInt32Field() == 0x34567890); assert(builder.getUInt64Field() == 0x1234567890123456L); @@ -121,7 +121,7 @@ object TestUtil { assert(reader.getInt16Field() == -12345); assert(reader.getInt32Field() == -12345678); assert(reader.getInt64Field() == -123456789012345L); - assert(reader.getUInt8Field() == 0xef.toByte); + assert(reader.getUInt8Field() == 0xea.toByte); assert(reader.getUInt16Field() == 0x4567); assert(reader.getUInt32Field() == 0x34567890); assert(reader.getUInt64Field() == 0x1234567890123456L); @@ -167,5 +167,31 @@ object TestUtil { } + def checkDefaultMessage(reader : TestDefaults.Builder) { + reader.getVoidField(); + assert(reader.getBoolField() == true); + assert(reader.getInt8Field() == -123); + assert(reader.getInt16Field() == -12345); + assert(reader.getInt32Field() == -12345678); + assert(reader.getInt64Field() == -123456789012345L); + assert(reader.getUInt8Field() == 0xea.toByte); + assert(reader.getUInt16Field() == 45678.toShort); + assert(reader.getUInt32Field() == 0xce0a6a14); + assert(reader.getUInt64Field() == 0xab54a98ceb1f0ad2L); + } + + def checkDefaultMessage(reader : TestDefaults.Reader) { + reader.getVoidField(); + assert(reader.getBoolField() == true); + assert(reader.getInt8Field() == -123); + assert(reader.getInt16Field() == -12345); + assert(reader.getInt32Field() == -12345678); + assert(reader.getInt64Field() == -123456789012345L); + assert(reader.getUInt8Field() == 0xea.toByte); + assert(reader.getUInt16Field() == 45678.toShort); + assert(reader.getUInt32Field() == 0xce0a6a14); + assert(reader.getUInt64Field() == 0xab54a98ceb1f0ad2L); + } + } diff --git a/compiler/src/test/schema/test.capnp b/compiler/src/test/schema/test.capnp index 5eeff11..b3987fe 100644 --- a/compiler/src/test/schema/test.capnp +++ b/compiler/src/test/schema/test.capnp @@ -53,6 +53,21 @@ struct TestAllTypes { # interfaceList @33 : List(Void); } +struct TestDefaults { + voidField @0 : Void = void; + boolField @1 : Bool = true; + int8Field @2 : Int8 = -123; + int16Field @3 : Int16 = -12345; + int32Field @4 : Int32 = -12345678; + int64Field @5 : Int64 = -123456789012345; + uInt8Field @6 : UInt8 = 234; + uInt16Field @7 : UInt16 = 45678; + uInt32Field @8 : UInt32 = 3456789012; + uInt64Field @9 : UInt64 = 12345678901234567890; +# float32Field @10 : Float32 = 1234.5; +# float64Field @11 : Float64 = -123e45; +} + struct TestOutOfOrder { foo @3 :Text; bar @2 :Text; diff --git a/runtime/src/main/java/org/capnproto/StructBuilder.java b/runtime/src/main/java/org/capnproto/StructBuilder.java index 27734ce..61eb6c5 100644 --- a/runtime/src/main/java/org/capnproto/StructBuilder.java +++ b/runtime/src/main/java/org/capnproto/StructBuilder.java @@ -32,6 +32,10 @@ public final class StructBuilder { return (this.segment.buffer.get(position) & (1 << (bitOffset % 8))) != 0; } + public final boolean getBooleanField(int offset, boolean mask) { + return this.getBooleanField(offset) ^ mask; + } + public final void setBooleanField(int offset, boolean value) { int bitOffset = offset; if (offset == 0) { bitOffset = this.bit0Offset; } @@ -42,38 +46,74 @@ public final class StructBuilder { (byte)((oldValue & (~(1 << bitnum))) | (( value ? 1 : 0) << bitnum))); } + public final void setBooleanField(int offset, boolean value, boolean mask) { + this.setBooleanField(offset, value ^ mask); + } + public final byte getByteField(int offset) { return this.segment.buffer.get(this.data + offset); } + public final byte getByteField(int offset, byte mask) { + return (byte)(this.getByteField(offset) ^ mask); + } + public final void setByteField(int offset, byte value) { this.segment.buffer.put(this.data + offset, value); } + public final void setByteField(int offset, byte value, byte mask) { + this.setByteField(offset, (byte) (value ^ mask)); + } + public final short getShortField(int offset) { return this.segment.buffer.getShort(this.data + offset * 2); } + public final short getShortField(int offset, short mask) { + return (short)(this.getShortField(offset) ^ mask); + } + public final void setShortField(int offset, short value) { this.segment.buffer.putShort(this.data + offset * 2, value); } + public final void setShortField(int offset, short value, short mask) { + this.setShortField(offset, (short)(value ^ mask)); + } + public final int getIntField(int offset) { return this.segment.buffer.getInt(this.data + offset * 4); } + public final int getIntField(int offset, int mask) { + return this.getIntField(offset) ^ mask; + } + public final void setIntField(int offset, int value) { this.segment.buffer.putInt(this.data + offset * 4, value); } + public final void setIntField(int offset, int value, int mask) { + this.setIntField(offset, value ^ mask); + } + public final long getLongField(int offset) { return this.segment.buffer.getLong(this.data + offset * 8); } + public final long getLongField(int offset, long mask) { + return this.getLongField(offset) ^ mask; + } + public final void setLongField(int offset, long value) { this.segment.buffer.putLong(this.data + offset * 8, value); } + public final void setLongField(int offset, long value, long mask) { + this.setLongField(offset, value ^ mask); + } + public final float getFloatField(int offset) { return this.segment.buffer.getFloat(this.data + offset * 4); } diff --git a/runtime/src/main/java/org/capnproto/StructReader.java b/runtime/src/main/java/org/capnproto/StructReader.java index 5adb769..77e4835 100644 --- a/runtime/src/main/java/org/capnproto/StructReader.java +++ b/runtime/src/main/java/org/capnproto/StructReader.java @@ -35,6 +35,10 @@ public final class StructReader { } } + public final boolean getBooleanField(int offset, boolean mask) { + return this.getBooleanField(offset) ^ mask; + } + public final byte getByteField(int offset) { if ((offset + 1) * 8 <= this.dataSize) { return this.segment.buffer.get(this.data + offset); @@ -43,6 +47,10 @@ public final class StructReader { } } + public final byte getByteField(int offset, byte mask) { + return (byte)(this.getByteField(offset) ^ mask); + } + public final short getShortField(int offset) { if ((offset + 1) * 16 <= this.dataSize) { return this.segment.buffer.getShort(this.data + offset * 2); @@ -51,6 +59,10 @@ public final class StructReader { } } + public final short getShortField(int offset, short mask) { + return (short)(this.getShortField(offset) ^ mask); + } + public final int getIntField(int offset) { if ((offset + 1) * 32 <= this.dataSize) { return this.segment.buffer.getInt(this.data + offset * 4); @@ -59,6 +71,10 @@ public final class StructReader { } } + public final int getIntField(int offset, int mask) { + return this.getIntField(offset) ^ mask; + } + public final long getLongField(int offset) { if ((offset + 1) * 64 <= this.dataSize) { return this.segment.buffer.getLong(this.data + offset * 8); @@ -67,6 +83,10 @@ public final class StructReader { } } + public final long getLongField(int offset, long mask) { + return this.getLongField(offset) ^ mask; + } + public final float getFloatField(int offset) { if ((offset + 1) * 32 <= this.dataSize) { return this.segment.buffer.getFloat(this.data + offset * 4);