diff --git a/benchmark/src/main/java/org/capnproto/benchmark/CarSales.java b/benchmark/src/main/java/org/capnproto/benchmark/CarSales.java index 6622d47..e36d008 100644 --- a/benchmark/src/main/java/org/capnproto/benchmark/CarSales.java +++ b/benchmark/src/main/java/org/capnproto/benchmark/CarSales.java @@ -53,7 +53,7 @@ public class CarSales car.setMake(MAKES[rng.nextLessThan(MAKES.length)]); car.setModel(MODELS[rng.nextLessThan(MODELS.length)]); - car.setColor(Color.values()[rng.nextLessThan(Color.values().length)]); + car.setColor(Color.values()[rng.nextLessThan(Color.SILVER.ordinal() + 1)]); car.setSeats((byte)(2 + rng.nextLessThan(6))); car.setDoors((byte)(2 + rng.nextLessThan(3))); diff --git a/benchmark/src/main/java/org/capnproto/benchmark/Eval.java b/benchmark/src/main/java/org/capnproto/benchmark/Eval.java index 96df889..287cf13 100644 --- a/benchmark/src/main/java/org/capnproto/benchmark/Eval.java +++ b/benchmark/src/main/java/org/capnproto/benchmark/Eval.java @@ -10,7 +10,7 @@ public class Eval EvaluationResult.Factory, EvaluationResult.Builder, EvaluationResult.Reader, Integer> { public static int makeExpression(Common.FastRand rng, Expression.Builder exp, int depth) { - exp.setOp(Operation.values()[rng.nextLessThan(Operation.values().length)]); + exp.setOp(Operation.values()[rng.nextLessThan(Operation.MODULUS.ordinal() + 1)]); int left = 0; if (rng.nextLessThan(8) < depth) { diff --git a/compiler/src/main/cpp/capnpc-java.c++ b/compiler/src/main/cpp/capnpc-java.c++ index 6b88367..46d479a 100644 --- a/compiler/src/main/cpp/capnpc-java.c++ +++ b/compiler/src/main/cpp/capnpc-java.c++ @@ -820,7 +820,8 @@ private: spaces(indent), " public final ", type, " get", titleCase, "() {\n", spaces(indent), (typeBody.which() == schema::Type::ENUM ? - kj::strTree(" return ", type, ".values()[_reader.getShortField(", offset, ")];\n") : + kj::strTree(" return org.capnproto.GeneratedClassSupport.clampOrdinal(", 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, defaultMaskParam, ");\n"))), @@ -832,7 +833,8 @@ private: spaces(indent), " public final ", type, " get", titleCase, "() {\n", spaces(indent), (typeBody.which() == schema::Type::ENUM ? - kj::strTree(" return ", type, ".values()[_builder.getShortField(", offset, ")];\n") : + kj::strTree(" return org.capnproto.GeneratedClassSupport.clampOrdinal(", 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, defaultMaskParam, ");\n"))), @@ -1229,8 +1231,8 @@ private: "\n", (isUnion ? kj::strTree(spaces(indent), " public Which which() {\n", - spaces(indent), " return Which.values()[_reader.getShortField(", - discriminantOffset, ")];\n", + spaces(indent), " return org.capnproto.GeneratedClassSupport.clampOrdinal(Which.values(),", + "_reader.getShortField(", discriminantOffset, "));\n", spaces(indent), " }\n") : kj::strTree()), kj::mv(methodDecls), @@ -1250,8 +1252,8 @@ private: spaces(indent), " public org.capnproto.StructBuilder _builder;\n", (isUnion ? kj::strTree(spaces(indent), " public Which which() {\n", - spaces(indent), " return Which.values()[_builder.getShortField(", - structNode.getDiscriminantOffset(), ")];\n", + spaces(indent), " return org.capnproto.GeneratedClassSupport.clampOrdinal(Which.values(),", + "_builder.getShortField(", structNode.getDiscriminantOffset(), "));\n", spaces(indent), " }\n") : kj::strTree()), spaces(indent), " public final Reader asReader() {\n", @@ -1320,6 +1322,7 @@ private: return kj::strTree(); } }, + spaces(indent), " _UNKNOWN,\n", spaces(indent), " }\n"), KJ_MAP(n, nestedTypeDecls) { return kj::mv(n); }, spaces(indent), "}\n" @@ -1627,6 +1630,7 @@ private: KJ_MAP(e, enumerants) { return kj::strTree(spaces(indent), " ", toUpperCase(e.getProto().getName()), ",\n"); }, + spaces(indent), " _UNKNOWN,\n", spaces(indent), "}\n" "\n"), diff --git a/runtime/src/main/java/org/capnproto/GeneratedClassSupport.java b/runtime/src/main/java/org/capnproto/GeneratedClassSupport.java index e8a6624..d2b357a 100644 --- a/runtime/src/main/java/org/capnproto/GeneratedClassSupport.java +++ b/runtime/src/main/java/org/capnproto/GeneratedClassSupport.java @@ -1,6 +1,15 @@ package org.capnproto; public final class GeneratedClassSupport { + + public static T clampOrdinal(T values[], short ordinal) { + int index = ordinal; + if (ordinal < 0 || ordinal >= values.length) { + index = values.length - 1; + } + return values[index]; + } + public static byte[] decodeRawBytes(String s) { try { return s.getBytes("ISO_8859-1");