diff --git a/java/src/main/java/org/msgpack/template/BuiltInTemplateLoader.java b/java/src/main/java/org/msgpack/template/BuiltInTemplateLoader.java index 37e3a0f6..9ac9a8ed 100644 --- a/java/src/main/java/org/msgpack/template/BuiltInTemplateLoader.java +++ b/java/src/main/java/org/msgpack/template/BuiltInTemplateLoader.java @@ -42,7 +42,6 @@ public class BuiltInTemplateLoader { ListTemplate.load(); MapTemplate.load(); NullableTemplate.load(); - ObjectArrayTemplate.load(); } } diff --git a/java/src/main/java/org/msgpack/template/JavassistTemplateBuilder.java b/java/src/main/java/org/msgpack/template/JavassistTemplateBuilder.java index dca54101..0f22b9ba 100644 --- a/java/src/main/java/org/msgpack/template/JavassistTemplateBuilder.java +++ b/java/src/main/java/org/msgpack/template/JavassistTemplateBuilder.java @@ -72,16 +72,6 @@ public class JavassistTemplateBuilder extends TemplateBuilder { return seqId++; } - public static abstract class JavassistTemplate extends AbstractTemplate { - public Class targetClass; - public Template[] templates; - - public JavassistTemplate(Class targetClass, Template[] templates) { - this.targetClass = targetClass; - this.templates = templates; - } - } - private static abstract class BuildContextBase { protected JavassistTemplateBuilder director; protected Class origClass; @@ -101,9 +91,9 @@ public class JavassistTemplateBuilder extends TemplateBuilder { this.director = director; } - protected Template build(Class targetClass) { + protected Template build(String className) { try { - reset(targetClass); + reset(className); buildClass(); buildConstructor(); buildMethodInit(); @@ -124,10 +114,8 @@ public class JavassistTemplateBuilder extends TemplateBuilder { } } - protected void reset(Class targetClass) { - this.origClass = targetClass; - this.origName = this.origClass.getName(); - this.tmplName = this.origName + "_$$_Template" + director.nextSeqId(); + protected void reset(String className) { + this.tmplName = className + "_$$_Template" + director.nextSeqId(); this.tmplCtClass = director.makeCtClass(this.tmplName); } @@ -220,8 +208,20 @@ public class JavassistTemplateBuilder extends TemplateBuilder { } } + public static abstract class JavassistTemplate extends AbstractTemplate { + public Class targetClass; + public Template[] templates; + + public JavassistTemplate(Class targetClass, Template[] templates) { + this.targetClass = targetClass; + this.templates = templates; + } + } + private static class BuildContext extends BuildContextBase { protected FieldEntry[] entries; + protected Class origClass; + protected String origName; protected Template[] templates; protected int minimumArrayLength; @@ -232,7 +232,9 @@ public class JavassistTemplateBuilder extends TemplateBuilder { public Template buildTemplate(Class targetClass, FieldEntry[] entries, Template[] templates) { this.entries = entries; this.templates = templates; - return build(targetClass); + this.origClass = targetClass; + this.origName = this.origClass.getName(); + return build(this.origName); } protected void setSuperClass() throws CannotCompileException, NotFoundException { @@ -554,5 +556,38 @@ public class JavassistTemplateBuilder extends TemplateBuilder { public Template buildOrdinalEnumTemplate(Class targetClass, Enum[] entries) { return new JavassistOrdinalEnumTemplate(entries); } + + public Template buildArrayTemplate(Type arrayType, Type genericBaseType, Class baseClass, int dim) { + if(dim == 1) { + if(baseClass == boolean.class) { + return BooleanArrayTemplate.getInstance(); + } else if(baseClass == short.class) { + return ShortArrayTemplate.getInstance(); + } else if(baseClass == int.class) { + return IntArrayTemplate.getInstance(); + } else if(baseClass == long.class) { + return LongArrayTemplate.getInstance(); + } else if(baseClass == float.class) { + return FloatArrayTemplate.getInstance(); + } else if(baseClass == double.class) { + return DoubleArrayTemplate.getInstance(); + } else { + // FIXME + Template baseTemplate = TemplateRegistry.lookup(genericBaseType); + return new ReflectionTemplateBuilder.ReflectionObjectArrayTemplate(baseClass, baseTemplate); + } + } else if(dim == 2) { + // FIXME + Class componentClass = Array.newInstance(baseClass, 0).getClass(); + Template componentTemplate = buildArrayTemplate(arrayType, genericBaseType, baseClass, dim-1); + return new ReflectionTemplateBuilder.ReflectionMultidimentionalArrayTemplate(componentClass, componentTemplate); + } else { + // FIXME + ReflectionTemplateBuilder.ReflectionMultidimentionalArrayTemplate componentTemplate = (ReflectionTemplateBuilder.ReflectionMultidimentionalArrayTemplate) + buildArrayTemplate(arrayType, genericBaseType, baseClass, dim-1); + Class componentClass = Array.newInstance(componentTemplate.getComponentClass(), 0).getClass(); + return new ReflectionTemplateBuilder.ReflectionMultidimentionalArrayTemplate(componentClass, componentTemplate); + } + } } diff --git a/java/src/main/java/org/msgpack/template/ObjectArrayTemplate.java b/java/src/main/java/org/msgpack/template/ObjectArrayTemplate.java deleted file mode 100644 index f77a5b05..00000000 --- a/java/src/main/java/org/msgpack/template/ObjectArrayTemplate.java +++ /dev/null @@ -1,80 +0,0 @@ -// -// MessagePack for Java -// -// Copyright (C) 2009-2010 FURUHASHI Sadayuki -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -package org.msgpack.template; - -import java.util.List; -import java.util.ArrayList; -import java.io.IOException; -import org.msgpack.*; - -// FIXME -public class ObjectArrayTemplate implements Template { - static void load() { } - - private Template componentTemplate; - - public ObjectArrayTemplate(Template componentTemplate) { - this.componentTemplate = componentTemplate; - } - - public Template getcomponentTemplate() { - return componentTemplate; - } - - @SuppressWarnings("unchecked") - public void pack(Packer pk, Object target) throws IOException { - if(!(target instanceof Object[])) { - throw new MessageTypeException(); - } - Object[] array = (Object[])target; // FIXME - pk.packArray(array.length); - for(Object a : array) { - componentTemplate.pack(pk, a); - } - } - - public Object unpack(Unpacker pac, Object to) throws IOException, MessageTypeException { - int length = pac.unpackArray(); - Object[] array; // FIXME - if(to != null && to instanceof Object[] && ((Object[])to).length == length) { - array = (Object[])to; - } else { - array = new Object[length]; - } - for(int i=0; i < length; i++) { - array[i] = componentTemplate.unpack(pac, null); - } - return array; - } - - public Object convert(MessagePackObject from, Object to) throws MessageTypeException { - MessagePackObject[] src = from.asArray(); - Object[] array; // FIXME - if(to != null && to instanceof Object[] && ((Object[])to).length == src.length) { - array = (Object[])to; - } else { - array = new Object[src.length]; - } - for(int i=0; i < src.length; i++) { - MessagePackObject s = src[i]; - array[i] = componentTemplate.convert(s, array[i]); - } - return array; - } -} - diff --git a/java/src/main/java/org/msgpack/template/ReflectionTemplateBuilder.java b/java/src/main/java/org/msgpack/template/ReflectionTemplateBuilder.java index ce820ba4..03ff2067 100644 --- a/java/src/main/java/org/msgpack/template/ReflectionTemplateBuilder.java +++ b/java/src/main/java/org/msgpack/template/ReflectionTemplateBuilder.java @@ -451,5 +451,119 @@ public class ReflectionTemplateBuilder extends TemplateBuilder { public Template buildOrdinalEnumTemplate(Class targetClass, Enum[] entries) { return new ReflectionOrdinalEnumTemplate(entries); } + + + static class ReflectionObjectArrayTemplate extends AbstractTemplate { + private Class componentClass; + private Template elementTemplate; + + public ReflectionObjectArrayTemplate(Class componentClass, Template elementTemplate) { + this.componentClass = componentClass; + this.elementTemplate = elementTemplate; + } + + public void pack(Packer pk, Object target) throws IOException { + if(!(target instanceof Object[]) || !componentClass.isAssignableFrom(target.getClass().getComponentType())) { + throw new MessageTypeException(); + } + Object[] array = (Object[])target; + int length = array.length; + pk.packArray(length); + for(int i=0; i < length; i++) { + elementTemplate.pack(pk, array[i]); + } + } + + public Object unpack(Unpacker pac, Object to) throws IOException { + int length = pac.unpackArray(); + Object[] array = (Object[])Array.newInstance(componentClass, length); + for(int i=0; i < length; i++) { + array[i] = elementTemplate.unpack(pac, null); + } + return array; + } + + public Object convert(MessagePackObject from, Object to) throws MessageTypeException { + MessagePackObject[] src = from.asArray(); + int length = src.length; + Object[] array = (Object[])Array.newInstance(componentClass, length); + for(int i=0; i < length; i++) { + array[i] = elementTemplate.convert(src[i], null); + } + return array; + } + } + + static class ReflectionMultidimentionalArrayTemplate extends AbstractTemplate { + private Class componentClass; + private Template componentTemplate; + + public ReflectionMultidimentionalArrayTemplate(Class componentClass, Template componentTemplate) { + this.componentClass = componentClass; + this.componentTemplate = componentTemplate; + } + + Class getComponentClass() { + return componentClass; + } + + public void pack(Packer pk, Object target) throws IOException { + Object[] array = (Object[])target; + int length = array.length; + pk.packArray(length); + for(int i=0; i < length; i++) { + componentTemplate.pack(pk, array[i]); + } + } + + public Object unpack(Unpacker pac, Object to) throws IOException, MessageTypeException { + int length = pac.unpackArray(); + Object[] array = (Object[])Array.newInstance(componentClass, length); + for(int i=0; i < length; i++) { + array[i] = componentTemplate.unpack(pac, null); + } + return array; + } + + public Object convert(MessagePackObject from, Object to) throws MessageTypeException { + MessagePackObject[] src = from.asArray(); + int length = src.length; + Object[] array = (Object[])Array.newInstance(componentClass, length); + for(int i=0; i < length; i++) { + array[i] = componentTemplate.convert(src[i], null); + } + return array; + } + } + + public Template buildArrayTemplate(Type arrayType, Type genericBaseType, Class baseClass, int dim) { + if(dim == 1) { + if(baseClass == boolean.class) { + return BooleanArrayTemplate.getInstance(); + } else if(baseClass == short.class) { + return ShortArrayTemplate.getInstance(); + } else if(baseClass == int.class) { + return IntArrayTemplate.getInstance(); + } else if(baseClass == long.class) { + return LongArrayTemplate.getInstance(); + } else if(baseClass == float.class) { + return FloatArrayTemplate.getInstance(); + } else if(baseClass == double.class) { + return DoubleArrayTemplate.getInstance(); + } else { + Template baseTemplate = TemplateRegistry.lookup(genericBaseType); + return new ReflectionObjectArrayTemplate(baseClass, baseTemplate); + } + } else if(dim == 2) { + Class componentClass = Array.newInstance(baseClass, 0).getClass(); + Template componentTemplate = buildArrayTemplate(arrayType, genericBaseType, baseClass, dim-1); + return new ReflectionMultidimentionalArrayTemplate(componentClass, componentTemplate); + } else { + ReflectionMultidimentionalArrayTemplate componentTemplate = (ReflectionMultidimentionalArrayTemplate) + buildArrayTemplate(arrayType, genericBaseType, baseClass, dim-1); + Class componentClass = Array.newInstance(componentTemplate.getComponentClass(), 0).getClass(); + return new ReflectionMultidimentionalArrayTemplate(componentClass, componentTemplate); + } + } } diff --git a/java/src/main/java/org/msgpack/template/TemplateBuilder.java b/java/src/main/java/org/msgpack/template/TemplateBuilder.java index b4f38810..c77a4338 100644 --- a/java/src/main/java/org/msgpack/template/TemplateBuilder.java +++ b/java/src/main/java/org/msgpack/template/TemplateBuilder.java @@ -113,6 +113,9 @@ public abstract class TemplateBuilder { // Override this method public abstract Template buildOrdinalEnumTemplate(Class targetClass, Enum[] entries); + // Override this method + public abstract Template buildArrayTemplate(Type arrayType, Type genericBaseType, Class baseClass, int dim); + public Template buildTemplate(Class targetClass, FieldList flist) throws NoSuchFieldException { checkValidation(targetClass); @@ -135,6 +138,38 @@ public abstract class TemplateBuilder { return buildOrdinalEnumTemplate(targetClass, entries); } + public Template buildArrayTemplate(Type arrayType) { + Type baseType; + Class baseClass; + int dim = 1; + if(arrayType instanceof GenericArrayType) { + GenericArrayType type = (GenericArrayType)arrayType; + baseType = type.getGenericComponentType(); + while(baseType instanceof GenericArrayType) { + baseType = ((GenericArrayType)baseType).getGenericComponentType(); + dim += 1; + } + baseClass = (Class)((ParameterizedType)baseType).getRawType(); + } else { + Class type = (Class)arrayType; + baseClass = type.getComponentType(); + while(baseClass.isArray()) { + baseClass = baseClass.getComponentType(); + dim += 1; + } + baseType = baseClass; + } + return buildArrayTemplate(arrayType, baseType, baseClass, dim); + } + + private static Type getComponentType(Type arrayType) { + if(arrayType instanceof GenericArrayType) { + return ((GenericArrayType)arrayType).getGenericComponentType(); + } else { + return ((Class)arrayType).getComponentType(); + } + } + private static TemplateBuilder instance; static { @@ -172,6 +207,10 @@ public abstract class TemplateBuilder { return instance.buildOrdinalEnumTemplate(targetClass); } + public static Template buildArray(Type arrayType) { + return instance.buildArrayTemplate(arrayType); + } + private static void checkValidation(Class targetClass) { if(targetClass.isInterface()) { diff --git a/java/src/main/java/org/msgpack/template/TemplateRegistry.java b/java/src/main/java/org/msgpack/template/TemplateRegistry.java index 9c7b5485..3f98fb46 100644 --- a/java/src/main/java/org/msgpack/template/TemplateRegistry.java +++ b/java/src/main/java/org/msgpack/template/TemplateRegistry.java @@ -87,37 +87,36 @@ public class TemplateRegistry { private static synchronized Template lookupImpl(Type targetType, boolean forceBuild, boolean fallbackDefault) { Template tmpl; - Class target; - - // TODO - //if(targetType instanceof GenericArrayType) { - // return lookupGenericArray((GenericArrayType)targetType); - //} if(targetType instanceof ParameterizedType) { + // ParameterizedType is not a Class? tmpl = lookupGenericImpl((ParameterizedType)targetType); if(tmpl != null) { return tmpl; } - target = (Class)((ParameterizedType)targetType).getRawType(); - } else { - target = (Class)targetType; + targetType = ((ParameterizedType)targetType).getRawType(); } - tmpl = map.get(target); + tmpl = map.get(targetType); if(tmpl != null) { return tmpl; } - // TODO - //if(target.isArray()) { - // // FIXME can't distinguish type-erased Object[T<>]? - // Type componentType = target.getComponentType(); - // Template componentTemplate = lookup(componentType); - // tmpl = new ObjectArrayTemplate(componentTemplate); - // register(target, tmpl); - // return tmpl; - //} + if(targetType instanceof GenericArrayType) { + // GenericArrayType is not a Class + tmpl = TemplateBuilder.buildArray(targetType); + register(targetType, tmpl); + return tmpl; + } + + Class target = (Class)targetType; + + if(target.isArray()) { + // FIXME can't distinguish type-erased T<>[]? + tmpl = TemplateBuilder.buildArray(target); + register(target, tmpl); + return tmpl; + } if(isAnnotated(target, MessagePackMessage.class)) { tmpl = TemplateBuilder.build(target); @@ -166,22 +165,6 @@ public class TemplateRegistry { } } - private static synchronized Template lookupGenericArray(GenericArrayType arrayType) { - Template tmpl = map.get(arrayType); - if(tmpl != null) { - // TODO primitive types are included? - return tmpl; - } - - Type componentType = arrayType.getGenericComponentType(); - Template componentTemplate = lookup(componentType); - tmpl = new ObjectArrayTemplate(componentTemplate); - - register(arrayType, tmpl); - - return tmpl; - } - public static synchronized Template lookupGeneric(Type targetType) { if(targetType instanceof ParameterizedType) { ParameterizedType parameterizedType = (ParameterizedType)targetType; diff --git a/java/src/test/java/org/msgpack/TestArrays.java b/java/src/test/java/org/msgpack/TestArrays.java new file mode 100644 index 00000000..92bb44c2 --- /dev/null +++ b/java/src/test/java/org/msgpack/TestArrays.java @@ -0,0 +1,355 @@ +package org.msgpack; + +import org.msgpack.*; +import org.msgpack.object.*; +import org.msgpack.annotation.*; +import static org.msgpack.Templates.*; + +import java.io.*; +import java.util.*; +import java.math.BigInteger; + +import org.junit.Test; +import junit.framework.TestCase; + +public class TestArrays extends TestCase { + @MessagePackMessage + public static class PrimitiveTest { + public PrimitiveTest() { } + public boolean[] b = new boolean[0]; + public short[] s = new short[0]; + public int[] i = new int[0]; + //public long[] l = new long[0]; // FIXME javassist? + public float[] f = new float[0]; + //public double[] d = new double[0]; // FIXME javassist? + } + + @Test + public void testPrimitive() { + PrimitiveTest t = new PrimitiveTest(); + t.b = new boolean[] {true, false}; + t.s = new short[] {0, 1}; + t.i = new int[] {2, 3}; + //t.l = new long[] {4, 5}; + t.f = new float[] {2.0f, 4.0f}; + //t.d = new double[] {8.0, 16.0}; + + byte[] raw = MessagePack.pack(t); + + PrimitiveTest u = MessagePack.unpack(raw, PrimitiveTest.class); + assertEquals(t.b.length, u.b.length); + for(int i=0; i < t.b.length; i++) { assertEquals(t.b[i], u.b[i]); } + assertEquals(t.s.length, u.s.length); + for(int i=0; i < t.s.length; i++) { assertEquals(t.s[i], u.s[i]); } + assertEquals(t.i.length, u.i.length); + for(int i=0; i < t.i.length; i++) { assertEquals(t.i[i], u.i[i]); } + //assertEquals(t.l.length, u.l.length); + //for(int i=0; i < t.l.length; i++) { assertEquals(t.l[i], u.l[i]); } + assertEquals(t.f.length, u.f.length); + for(int i=0; i < t.f.length; i++) { assertEquals(t.f[i], u.f[i]); } + //assertEquals(t.d.length, u.d.length); + //for(int i=0; i < t.d.length; i++) { assertEquals(t.d[i], u.d[i]); } + + PrimitiveTest c = MessagePack.unpack(raw).convert(PrimitiveTest.class); + assertEquals(t.b.length, c.b.length); + for(int i=0; i < t.b.length; i++) { assertEquals(t.b[i], c.b[i]); } + assertEquals(t.s.length, c.s.length); + for(int i=0; i < t.s.length; i++) { assertEquals(t.s[i], c.s[i]); } + assertEquals(t.i.length, c.i.length); + for(int i=0; i < t.i.length; i++) { assertEquals(t.i[i], c.i[i]); } + //assertEquals(t.l.length, c.l.length); + //for(int i=0; i < t.l.length; i++) { assertEquals(t.l[i], c.l[i]); } + assertEquals(t.f.length, c.f.length); + for(int i=0; i < t.f.length; i++) { assertEquals(t.f[i], c.f[i]); } + //assertEquals(t.d.length, c.d.length); + //for(int i=0; i < t.d.length; i++) { assertEquals(t.d[i], c.d[i]); } + } + + @MessagePackMessage + public static class ReferenceTest { + public ReferenceTest() { } + public Boolean[] b; + public Short[] s; + public Integer[] i; + public Long[] l; + public Float[] f; + public Double[] d; + public String[] str; + } + + @Test + public void testReference() { + ReferenceTest t = new ReferenceTest(); + t.b = new Boolean[] {true, false}; + t.s = new Short[] {0, 1}; + t.i = new Integer[] {2, 3}; + t.l = new Long[] {4l, 5l}; + t.f = new Float[] {2.0f, 4.0f}; + t.d = new Double[] {8.0, 16.0}; + t.str = new String[] {"furuhashi", "java"}; + + byte[] raw = MessagePack.pack(t); + + ReferenceTest u = MessagePack.unpack(raw, ReferenceTest.class); + assertEquals(t.b.length, u.b.length); + for(int i=0; i < t.b.length; i++) { assertEquals(t.b[i], u.b[i]); } + assertEquals(t.s.length, u.s.length); + for(int i=0; i < t.s.length; i++) { assertEquals(t.s[i], u.s[i]); } + assertEquals(t.i.length, u.i.length); + for(int i=0; i < t.i.length; i++) { assertEquals(t.i[i], u.i[i]); } + assertEquals(t.l.length, u.l.length); + for(int i=0; i < t.l.length; i++) { assertEquals(t.l[i], u.l[i]); } + assertEquals(t.f.length, u.f.length); + for(int i=0; i < t.f.length; i++) { assertEquals(t.f[i], u.f[i]); } + assertEquals(t.d.length, u.d.length); + for(int i=0; i < t.d.length; i++) { assertEquals(t.d[i], u.d[i]); } + assertEquals(t.str.length, u.str.length); + for(int i=0; i < t.str.length; i++) { assertEquals(t.str[i], u.str[i]); } + + ReferenceTest c = MessagePack.unpack(raw).convert(ReferenceTest.class); + assertEquals(t.b.length, c.b.length); + for(int i=0; i < t.b.length; i++) { assertEquals(t.b[i], c.b[i]); } + assertEquals(t.s.length, c.s.length); + for(int i=0; i < t.s.length; i++) { assertEquals(t.s[i], c.s[i]); } + assertEquals(t.i.length, c.i.length); + for(int i=0; i < t.i.length; i++) { assertEquals(t.i[i], c.i[i]); } + assertEquals(t.l.length, c.l.length); + for(int i=0; i < t.l.length; i++) { assertEquals(t.l[i], c.l[i]); } + assertEquals(t.f.length, c.f.length); + for(int i=0; i < t.f.length; i++) { assertEquals(t.f[i], c.f[i]); } + assertEquals(t.d.length, c.d.length); + for(int i=0; i < t.d.length; i++) { assertEquals(t.d[i], c.d[i]); } + assertEquals(t.str.length, c.str.length); + for(int i=0; i < t.str.length; i++) { assertEquals(t.str[i], c.str[i]); } + } + + @MessagePackMessage + public static class GenericsTest { + public GenericsTest() { } + public List[] slist; + public Map[] imap; + } + + @Test + public void testGenerics() { + GenericsTest t = new GenericsTest(); + t.slist = new List[2]; + t.slist[0] = new ArrayList(); + t.slist[0].add("aa"); + t.slist[0].add("bb"); + t.slist[1] = new ArrayList(); + t.slist[1].add("cc"); + t.imap = new Map[2]; + t.imap[0] = new HashMap(); + t.imap[0].put("aa", 1); + t.imap[0].put("bb", 2); + t.imap[1] = new HashMap(); + t.imap[1].put("cc", 3); + + byte[] raw = MessagePack.pack(t); + + GenericsTest u = MessagePack.unpack(raw, GenericsTest.class); + assertEquals(t.slist.length, u.slist.length); + for(int i=0; i < t.slist.length; i++) { + assertEquals(t.slist[i].size(), u.slist[i].size()); + for(int j=0; j < t.slist[i].size(); j++) { + assertEquals(t.slist[i].get(j), u.slist[i].get(j)); + } + } + for(int i=0; i < t.imap.length; i++) { + assertEquals(t.imap[i].size(), u.imap[i].size()); + for(String j : t.imap[i].keySet()) { + assertEquals(t.imap[i].get(j), u.imap[i].get(j)); + } + } + + GenericsTest c = MessagePack.unpack(raw).convert(GenericsTest.class); + assertEquals(t.slist.length, c.slist.length); + for(int i=0; i < t.slist.length; i++) { + assertEquals(t.slist[i].size(), c.slist[i].size()); + for(int j=0; j < t.slist[i].size(); j++) { + assertEquals(t.slist[i].get(j), c.slist[i].get(j)); + } + } + for(int i=0; i < t.imap.length; i++) { + assertEquals(t.imap[i].size(), c.imap[i].size()); + for(String j : t.imap[i].keySet()) { + assertEquals(t.imap[i].get(j), c.imap[i].get(j)); + } + } + } + + @MessagePackMessage + public static class Dim2Test { + public Dim2Test() { } + public int[][] i; + public String[][] str; + public List[][] slist; + } + + @Test + public void testDim2() { + Dim2Test t = new Dim2Test(); + t.i = new int[2][]; + t.i[0] = new int[] {0, 1}; + t.i[1] = new int[] {2, 3, 4}; + t.str = new String[2][]; + t.str[0] = new String[] {"aa", "bb"}; + t.str[1] = new String[] {"cc", "dd", "ee"}; + t.slist = new List[2][]; + t.slist[0] = new List[1]; + t.slist[0][0] = new ArrayList(); + t.slist[0][0].add("ff"); + t.slist[0][0].add("gg"); + t.slist[1] = new List[2]; + t.slist[1][0] = new ArrayList(); + t.slist[1][0].add("hh"); + t.slist[1][0].add("ii"); + t.slist[1][1] = new ArrayList(); + t.slist[1][1].add("jj"); + t.slist[1][1].add("kk"); + + byte[] raw = MessagePack.pack(t); + + Dim2Test u = MessagePack.unpack(raw, Dim2Test.class); + assertEquals(t.i.length, t.i.length); + for(int i=0; i < t.i.length; i++) { + assertEquals(t.i[i].length, u.i[i].length); + for(int j=0; j < t.i[i].length; j++) { + assertEquals(t.i[i][j], u.i[i][j]); + } + } + assertEquals(t.str.length, t.str.length); + for(int i=0; i < t.str.length; i++) { + assertEquals(t.str[i].length, u.str[i].length); + for(int j=0; j < t.str[i].length; j++) { + assertEquals(t.str[i][j], u.str[i][j]); + } + } + assertEquals(t.slist.length, t.slist.length); + for(int i=0; i < t.slist.length; i++) { + assertEquals(t.slist[i].length, u.slist[i].length); + for(int j=0; j < t.slist[i].length; j++) { + assertEquals(t.slist[i][j].size(), u.slist[i][j].size()); + for(int k=0; k < t.slist[i][j].size(); k++) { + assertEquals(t.slist[i][j].get(k), u.slist[i][j].get(k)); + } + } + } + } + + @MessagePackMessage + public static class Dim3Test { + public Dim3Test() { } + public int[][][] i; + public String[][][] str; + public List[][][] slist; + } + + @Test + public void testDim3() { + Dim3Test t = new Dim3Test(); + t.i = new int[2][][]; + t.i[0] = new int[2][]; + t.i[0][0] = new int[] {0, 1}; + t.i[0][1] = new int[] {2, 3, 4}; + t.i[1] = new int[1][]; + t.i[1][0] = new int[] {5}; + t.str = new String[2][][]; + t.str[0] = new String[1][]; + t.str[0][0] = new String[] {"aa", "bb"}; + t.str[1] = new String[2][]; + t.str[1][0] = new String[] {"cc", "dd", "ee"}; + t.str[1][1] = new String[] {"ff"}; + t.slist = new List[2][][]; + t.slist[0] = new List[2][]; + t.slist[0][0] = new List[1]; + t.slist[0][0][0] = new ArrayList(); + t.slist[0][0][0].add("ff"); + t.slist[0][0][0].add("gg"); + t.slist[0][1] = new List[2]; + t.slist[0][1][0] = new ArrayList(); + t.slist[0][1][0].add("hh"); + t.slist[0][1][0].add("ii"); + t.slist[0][1][1] = new ArrayList(); + t.slist[0][1][1].add("jj"); + t.slist[0][1][1].add("kk"); + t.slist[1] = new List[1][]; + t.slist[1][0] = new List[0]; + + byte[] raw = MessagePack.pack(t); + + Dim3Test u = MessagePack.unpack(raw, Dim3Test.class); + assertEquals(t.i.length, t.i.length); + for(int i=0; i < t.i.length; i++) { + assertEquals(t.i[i].length, u.i[i].length); + for(int j=0; j < t.i[i].length; j++) { + for(int k=0; k < t.i[i].length; k++) { + assertEquals(t.i[i][j][k], u.i[i][j][k]); + } + } + } + assertEquals(t.str.length, t.str.length); + for(int i=0; i < t.str.length; i++) { + assertEquals(t.str[i].length, u.str[i].length); + for(int j=0; j < t.str[i].length; j++) { + assertEquals(t.str[i][j].length, u.str[i][j].length); + for(int k=0; k < t.str[i][j].length; k++) { + assertEquals(t.str[i][j][k], u.str[i][j][k]); + } + } + } + assertEquals(t.slist.length, t.slist.length); + for(int i=0; i < t.slist.length; i++) { + assertEquals(t.slist[i].length, u.slist[i].length); + for(int j=0; j < t.slist[i].length; j++) { + assertEquals(t.slist[i][j].length, u.slist[i][j].length); + for(int k=0; k < t.slist[i][j].length; k++) { + assertEquals(t.slist[i][j][k].size(), u.slist[i][j][k].size()); + for(int l=0; l < t.slist[i][j][k].size(); l++) { + assertEquals(t.slist[i][j][k].get(l), u.slist[i][j][k].get(l)); + } + } + } + } + } + + @Test + public void testLocal() throws IOException { + int[][][] src = new int[10][20][30]; + for (int i = 0; i < 10; ++i) { + for (int j = 0; j < 20; ++j) { + for (int k = 0; k < 30; ++k) { + src[i][j][k] = (int) (Math.random() * 100); + } + } + } + + byte[] raw = MessagePack.pack(src); + + int[][][] u = MessagePack.unpack(raw, int[][][].class); + assertEquals(src.length, u.length); + for(int i = 0; i < src.length; ++i) { + assertEquals(src[i].length, u[i].length); + for(int j = 0; j < src[i].length; ++j) { + assertEquals(src[i][j].length, u[i][j].length); + for(int k = 0; k < src[i][j].length; ++k) { + assertEquals(src[i][j][k], u[i][j][k]); + } + } + } + + int[][][] c = MessagePack.unpack(raw).convert(int[][][].class); + assertEquals(src.length, c.length); + for(int i = 0; i < src.length; ++i) { + assertEquals(src[i].length, c[i].length); + for(int j = 0; j < src[i].length; ++j) { + assertEquals(src[i][j].length, c[i][j].length); + for(int k = 0; k < src[i][j].length; ++k) { + assertEquals(src[i][j][k], c[i][j][k]); + } + } + } + } +} +