summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShawn O. Pearce <sop@google.com>2010-07-28 13:01:44 -0700
committerShawn O. Pearce <sop@google.com>2010-07-28 13:01:44 -0700
commit9a9c21d675cbb7a15ec57d8f3cf4e08ab0831949 (patch)
tree67386982696089d774f29456ceb96ef14a6f7799
parent25732409c8808c97359de84825178a6591765a9e (diff)
downloadgwtorm-9a9c21d675cbb7a15ec57d8f3cf4e08ab0831949.tar.gz
protobuf: Support encoding Enums
Encode enum values using their ordinal as a varint, similar to what the proto compiler from Google would do. This requires that application developers carefully assign their enum orders in order to maintain values already encoded in protobufs. Change-Id: I1f40170c583125f425f4ff4a3aa7045ee0a820ca Signed-off-by: Shawn O. Pearce <sop@google.com>
-rw-r--r--src/main/java/com/google/gwtorm/protobuf/CodecGen.java24
-rw-r--r--src/main/java/com/google/gwtorm/schema/Util.java2
-rw-r--r--src/test/java/com/google/gwtorm/protobuf/ProtobufEncoderTest.java27
3 files changed, 52 insertions, 1 deletions
diff --git a/src/main/java/com/google/gwtorm/protobuf/CodecGen.java b/src/main/java/com/google/gwtorm/protobuf/CodecGen.java
index a7ab7ef..5a5342b 100644
--- a/src/main/java/com/google/gwtorm/protobuf/CodecGen.java
+++ b/src/main/java/com/google/gwtorm/protobuf/CodecGen.java
@@ -51,6 +51,7 @@ class CodecGen<T> implements Opcodes {
Type.getType(java.util.Collection.class);
private static final Type iterator = Type.getType(java.util.Iterator.class);
private static final Type string = Type.getType(String.class);
+ private static final Type enumType = Type.getType(Enum.class);
private static final Type byteString = Type.getType(ByteString.class);
private static final Type object = Type.getType(Object.class);
private static final Type codedOutputStream =
@@ -495,6 +496,15 @@ class CodecGen<T> implements Opcodes {
.getMethodDescriptor(Type.LONG_TYPE, new Type[] {}));
cgs.doinc("computeFixed64Size", Type.INT_TYPE, Type.LONG_TYPE);
+ } else if (f.getPrimitiveType().isEnum()) {
+ cgs.preinc();
+ cgs.push(f.getColumnID());
+ cgs.pushFieldValue();
+ mv.visitMethodInsn(INVOKEVIRTUAL, enumType.getInternalName(),
+ "ordinal", //
+ Type.getMethodDescriptor(Type.INT_TYPE, new Type[] {}));
+ cgs.doinc("computeEnumSize", Type.INT_TYPE, Type.INT_TYPE);
+
} else {
throw new OrmException("Type " + f.getPrimitiveType()
+ " not supported for field " + f.getPathToFieldName());
@@ -764,6 +774,12 @@ class CodecGen<T> implements Opcodes {
.getMethodDescriptor(Type.LONG_TYPE, new Type[] {}));
cgs.write("writeFixed64", Type.LONG_TYPE);
+ } else if (f.getPrimitiveType().isEnum()) {
+ mv.visitMethodInsn(INVOKEVIRTUAL, enumType.getInternalName(),
+ "ordinal", //
+ Type.getMethodDescriptor(Type.INT_TYPE, new Type[] {}));
+ cgs.write("writeEnum", Type.INT_TYPE);
+
} else {
throw new OrmException("Type " + f.getPrimitiveType()
+ " not supported for field " + f.getPathToFieldName());
@@ -1128,6 +1144,14 @@ class CodecGen<T> implements Opcodes {
Type.getMethodDescriptor(Type.VOID_TYPE,
new Type[] {Type.LONG_TYPE}));
+ } else if (f.getPrimitiveType().isEnum()) {
+ Type et = Type.getType(f.getPrimitiveType());
+ mv.visitMethodInsn(INVOKESTATIC, et.getInternalName(), "values", Type
+ .getMethodDescriptor(Type.getType("[" + et.getDescriptor()),
+ new Type[] {}));
+ cgs.call("readEnum", Type.INT_TYPE);
+ mv.visitInsn(AALOAD);
+
} else {
throw new OrmException("Type " + f.getPrimitiveType()
+ " not supported for field " + f.getPathToFieldName());
diff --git a/src/main/java/com/google/gwtorm/schema/Util.java b/src/main/java/com/google/gwtorm/schema/Util.java
index ff34f0a..1ca5e5d 100644
--- a/src/main/java/com/google/gwtorm/schema/Util.java
+++ b/src/main/java/com/google/gwtorm/schema/Util.java
@@ -67,7 +67,7 @@ public class Util {
if (type == null || type == Void.TYPE) {
return false;
}
- if (type.isPrimitive()) {
+ if (type.isPrimitive() || type.isEnum()) {
return true;
}
if (type == String.class) {
diff --git a/src/test/java/com/google/gwtorm/protobuf/ProtobufEncoderTest.java b/src/test/java/com/google/gwtorm/protobuf/ProtobufEncoderTest.java
index 14544c0..21007f6 100644
--- a/src/test/java/com/google/gwtorm/protobuf/ProtobufEncoderTest.java
+++ b/src/test/java/com/google/gwtorm/protobuf/ProtobufEncoderTest.java
@@ -197,6 +197,24 @@ public class ProtobufEncoderTest extends TestCase {
assertEquals(2, other.list.size());
}
+ public void testEnumEncoder() throws UnsupportedEncodingException {
+ assertEquals(1, ThingWithEnum.Type.B.ordinal());
+ assertSame(ThingWithEnum.Type.B, ThingWithEnum.Type.values()[1]);
+
+ ProtobufCodec<ThingWithEnum> e = CodecFactory.encoder(ThingWithEnum.class);
+
+ ThingWithEnum thing = new ThingWithEnum();
+ thing.type = ThingWithEnum.Type.B;
+
+ ThingWithEnum other = e.decode(e.encodeToByteArray(thing));
+ assertNotNull(other.type);
+ assertSame(thing.type, other.type);
+
+ byte[] act = e.encodeToByteArray(thing);
+ byte[] exp = {0x08, 0x01};
+ assertEquals(asString(exp), asString(act));
+ }
+
private static String asString(byte[] bin)
throws UnsupportedEncodingException {
return new String(bin, "ISO-8859-1");
@@ -247,4 +265,13 @@ public class ProtobufEncoderTest extends TestCase {
@CustomCodec(ItemCodec.class)
List<Item> list;
}
+
+ static class ThingWithEnum {
+ static enum Type {
+ A, B;
+ }
+
+ @Column(id = 1)
+ Type type;
+ }
}