diff --git a/java/AUTHORS b/java/AUTHORS new file mode 100644 index 0000000..ababacb --- /dev/null +++ b/java/AUTHORS @@ -0,0 +1 @@ +FURUHASHI Sadayuki diff --git a/java/CHANGES.txt b/java/CHANGES.txt index 77e9318..a985ebd 100644 --- a/java/CHANGES.txt +++ b/java/CHANGES.txt @@ -1,3 +1,78 @@ + +Release 0.5.1 - 2010/12/14 + BUG FIXES + Fixes cast error on GenericArrayType + + Throws MessagePackException instead of NullPointerException if target is null + on pack method. + + +Release 0.5.0 - 2010/12/09 + NEW FEATURES + Dynamic template builder is rewritten. New ReflectionTemplateBuilder + supports DalvikVM. + + Some optimization for dynamic code generator. + + @MessagePackMessage accepts default filed option. + Added new field annotations: @Ignore, @Requred and @Index. + + Supported pack/unpack/convertion of arrays including multidimensional arrays. + + Added native pack/unpack routine of ByteBuffer. It will be zero-copy optimized + under a specific condition. + + +Release 0.4.3 - 2010/11/10 + NEW FEATURES + Added FieldList class and MessagePack.register(Class, FieldList) method + to specify optional/nullable options on runtime without annotations. + + Changed annotation name: @MessagePackNullable -> @Nullable + Changed annotation name: @MessagePackOptional -> @Optional + + Supported pack/unpack/convertion of enums. + + Added MessagePack.unpack(buffer, T to) and MessagePackObject.convert(T to) + methods. They can unpack/convert buffer/object into existing object and + eliminate re-allocation overhead. + + +Release 0.4.2 - 2010/11/09 + NEW FEATURES + Added MessagePackNullable annotation and Tempalte.tNullable(Template) + method. + + Added T MessagePackObject.unpack(Class) method. + + +Release 0.4.1 - 2010/11/05 + BUG FIXES + Fixed dynamic code generation of unpack methods + + +Release 0.4.0 - 2010/10/25 + NEW FEATURES + Added MessagePackObject class and org.msgpack.object package that + represent unpacked (=dynamically typed) objects. + Unpacker.unpack method returns MessagePackObject instead of Object. + + Added Templates class and org.msgpack.template package that provide + type conversion feature. + + User-defined classes annotated with MessagePackMessage can be + pack/unpack/converted. + + User-defined classes registered with MessagePack.register(Class) can be + pack/unpack/converted. + + Added dynamic code generation feature for user-defined classes. + + Added MessagePackOptional annotation. + + Added MessagePack class that implements typical useful methods. + + Release 0.3 - 2010/05/23 NEW FEATURES Added Unbuffered API + Direct Conversion API to the Unpacker. diff --git a/java/pom.xml b/java/pom.xml index aa3e3ce..c8a19b3 100755 --- a/java/pom.xml +++ b/java/pom.xml @@ -3,7 +3,7 @@ 4.0.0 org.msgpack msgpack - 0.4.0-devel + 0.5.1-devel MessagePack for Java MessagePack for Java diff --git a/java/src/main/java/org/msgpack/AbstractTemplate.java b/java/src/main/java/org/msgpack/AbstractTemplate.java index 5b4442e..7f8cb49 100644 --- a/java/src/main/java/org/msgpack/AbstractTemplate.java +++ b/java/src/main/java/org/msgpack/AbstractTemplate.java @@ -20,8 +20,8 @@ package org.msgpack; import java.io.IOException; public abstract class AbstractTemplate implements Template { - public Object unpack(Unpacker pac) throws IOException, MessageTypeException { - return convert(pac.unpackObject()); + public Object unpack(Unpacker pac, Object to) throws IOException, MessageTypeException { + return convert(pac.unpackObject(), to); } } diff --git a/java/src/main/java/org/msgpack/BufferedUnpackerImpl.java b/java/src/main/java/org/msgpack/BufferedUnpackerImpl.java index 5b449c7..406fff7 100644 --- a/java/src/main/java/org/msgpack/BufferedUnpackerImpl.java +++ b/java/src/main/java/org/msgpack/BufferedUnpackerImpl.java @@ -25,6 +25,7 @@ abstract class BufferedUnpackerImpl extends UnpackerImpl { int offset = 0; int filled = 0; byte[] buffer = null; + boolean bufferReferenced = false; // TODO zero-copy buffer private ByteBuffer castBuffer = ByteBuffer.allocate(8); abstract boolean fill() throws IOException; @@ -417,7 +418,18 @@ abstract class BufferedUnpackerImpl extends UnpackerImpl { final byte[] unpackByteArray() throws IOException, MessageTypeException { int length = unpackRaw(); - return unpackRawBody(length); + byte[] body = unpackRawBody(length); + return body; + } + + final ByteBuffer unpackByteBuffer() throws IOException, MessageTypeException { + // TODO zero-copy buffer + int length = unpackRaw(); + more(length); + ByteBuffer buf = ByteBuffer.wrap(buffer, offset, length); + bufferReferenced = true; // TODO fix magical code + advance(length); + return buf; } final String unpackString() throws IOException, MessageTypeException { diff --git a/java/src/main/java/org/msgpack/CustomConverter.java b/java/src/main/java/org/msgpack/CustomConverter.java deleted file mode 100644 index b9fb0b3..0000000 --- a/java/src/main/java/org/msgpack/CustomConverter.java +++ /dev/null @@ -1,44 +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; - -import java.util.concurrent.ConcurrentHashMap; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class CustomConverter { - private static Logger LOG = LoggerFactory.getLogger(CustomConverter.class); - - private static ConcurrentHashMap, MessageConverter> map = new ConcurrentHashMap, MessageConverter>(); - - public static void register(Class target, MessageConverter converter) { - LOG.debug("register a MessageConverter object for the type: " - + target.getName()); - map.put(target, converter); - } - - public static MessageConverter get(Class target) { - return map.get(target); - } - - public static boolean isRegistered(Class target) { - return map.containsKey(target); - } -} - diff --git a/java/src/main/java/org/msgpack/CustomMessage.java b/java/src/main/java/org/msgpack/CustomMessage.java deleted file mode 100644 index 832aa59..0000000 --- a/java/src/main/java/org/msgpack/CustomMessage.java +++ /dev/null @@ -1,44 +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; - -import java.lang.annotation.Annotation; - -public class CustomMessage { - public static void registerPacker(Class target, MessagePacker packer) { - CustomPacker.register(target, packer); - } - - public static void registerConverter(Class target, MessageConverter converter) { - CustomConverter.register(target, converter); - } - - public static void registerUnpacker(Class target, MessageUnpacker unpacker) { - CustomUnpacker.register(target, unpacker); - } - - public static void register(Class target, Template tmpl) { - CustomPacker.register(target, tmpl); - CustomConverter.register(target, tmpl); - CustomUnpacker.register(target, tmpl); - } - - public static boolean isAnnotated(Class target, Class with) { - return target.getAnnotation(with) != null; - } -} diff --git a/java/src/main/java/org/msgpack/CustomPacker.java b/java/src/main/java/org/msgpack/CustomPacker.java deleted file mode 100644 index 0c128b8..0000000 --- a/java/src/main/java/org/msgpack/CustomPacker.java +++ /dev/null @@ -1,43 +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; - -import java.util.concurrent.ConcurrentHashMap; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class CustomPacker { - private static Logger LOG = LoggerFactory.getLogger(CustomPacker.class); - - private static ConcurrentHashMap, MessagePacker> map = new ConcurrentHashMap, MessagePacker>(); - - public static void register(Class target, MessagePacker packer) { - LOG.debug("register a MessagePacker object for the type: " - + target.getName()); - map.put(target, packer); - } - - public static MessagePacker get(Class target) { - return map.get(target); - } - - public static boolean isRegistered(Class target) { - return map.containsKey(target); - } -} diff --git a/java/src/main/java/org/msgpack/CustomUnpacker.java b/java/src/main/java/org/msgpack/CustomUnpacker.java deleted file mode 100644 index fbf64b7..0000000 --- a/java/src/main/java/org/msgpack/CustomUnpacker.java +++ /dev/null @@ -1,43 +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; - -import java.util.concurrent.ConcurrentHashMap; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class CustomUnpacker { - private static Logger LOG = LoggerFactory.getLogger(CustomUnpacker.class); - - private static ConcurrentHashMap, MessageUnpacker> map = new ConcurrentHashMap, MessageUnpacker>(); - - public static void register(Class target, MessageUnpacker converter) { - LOG.debug("register a MessageUnpacker object for the type: " - + target.getName()); - map.put(target, converter); - } - - public static MessageUnpacker get(Class target) { - return map.get(target); - } - - public static boolean isRegistered(Class target) { - return map.containsKey(target); - } -} diff --git a/java/src/main/java/org/msgpack/MessageConverter.java b/java/src/main/java/org/msgpack/MessageConverter.java index 5e5f437..51d5ec1 100644 --- a/java/src/main/java/org/msgpack/MessageConverter.java +++ b/java/src/main/java/org/msgpack/MessageConverter.java @@ -18,6 +18,6 @@ package org.msgpack; public interface MessageConverter { - Object convert(MessagePackObject from) throws MessageTypeException; + Object convert(MessagePackObject from, Object to) throws MessageTypeException; } diff --git a/java/src/main/java/org/msgpack/MessagePack.java b/java/src/main/java/org/msgpack/MessagePack.java index e4bc627..f3a73c0 100644 --- a/java/src/main/java/org/msgpack/MessagePack.java +++ b/java/src/main/java/org/msgpack/MessagePack.java @@ -21,10 +21,9 @@ import java.io.OutputStream; import java.io.InputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; -//import org.msgpack.util.codegen.DynamicTemplate; // FIXME -import org.msgpack.util.codegen.DynamicPacker; -import org.msgpack.util.codegen.DynamicConverter; -import org.msgpack.util.codegen.DynamicUnpacker; +import org.msgpack.template.TemplateRegistry; +import org.msgpack.template.TemplateBuilder; +import org.msgpack.template.FieldList; public class MessagePack { public static byte[] pack(Object obj) { @@ -51,7 +50,7 @@ public class MessagePack { return out.toByteArray(); } - public static void pack(OutputStream out, Object obj, Template tmpl) throws IOException { + public static void pack(OutputStream out, Object obj, Template tmpl) throws IOException, MessageTypeException { new Packer(out).pack(obj, tmpl); } @@ -76,6 +75,16 @@ public class MessagePack { } } + public static T unpack(byte[] buffer, Template tmpl, T to) throws MessageTypeException { + Unpacker pac = new Unpacker(); + pac.wrap(buffer); + try { + return pac.unpack(tmpl, to); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + public static T unpack(byte[] buffer, Class klass) throws MessageTypeException { Unpacker pac = new Unpacker(); pac.wrap(buffer); @@ -86,15 +95,21 @@ public class MessagePack { } } - public static MessagePackObject unpack(InputStream in) { - Unpacker pac = new Unpacker(in); + public static T unpack(byte[] buffer, T to) throws MessageTypeException { + Unpacker pac = new Unpacker(); + pac.wrap(buffer); try { - return pac.unpackObject(); + return pac.unpack(to); } catch (IOException e) { throw new RuntimeException(e); } } + public static MessagePackObject unpack(InputStream in) throws IOException { + Unpacker pac = new Unpacker(in); + return pac.unpackObject(); + } + public static Object unpack(InputStream in, Template tmpl) throws IOException, MessageTypeException { Unpacker pac = new Unpacker(in); try { @@ -104,6 +119,15 @@ public class MessagePack { } } + public static T unpack(InputStream in, Template tmpl, T to) throws IOException, MessageTypeException { + Unpacker pac = new Unpacker(in); + try { + return pac.unpack(tmpl, to); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + public static T unpack(InputStream in, Class klass) throws IOException, MessageTypeException { Unpacker pac = new Unpacker(in); try { @@ -111,46 +135,27 @@ public class MessagePack { } catch (IOException e) { throw new RuntimeException(e); } - } - public static void register(Class target) { // auto-detect - // FIXME - //Template tmpl; - //if(List.isAssignableFrom(target)) { - //} else if(Set.isAssignableFrom(target)) { - //} else if(Map.isAssignableFrom(target)) { - //} else if(Collection.isAssignableFrom(target)) { - //} else if(BigInteger.isAssignableFrom(target)) { - //} else { - //} + public static T unpack(InputStream in, T to) throws IOException, MessageTypeException { + Unpacker pac = new Unpacker(in); + try { + return pac.unpack(to); + } catch (IOException e) { + throw new RuntimeException(e); + } + } - // FIXME - //Template tmpl = DynamicTemplate.create(target); - //register(target, tmpl); + public static void register(Class target) { + TemplateRegistry.register(target); + } - // FIXME - CustomPacker.register(target, DynamicPacker.create(target)); - CustomConverter.register(target, DynamicConverter.create(target)); - CustomUnpacker.register(target, DynamicUnpacker.create(target)); + public static void register(Class target, FieldList flist) throws NoSuchFieldException { + TemplateRegistry.register(target, flist); } public static void register(Class target, Template tmpl) { - CustomPacker.register(target, tmpl); - CustomConverter.register(target, tmpl); - CustomUnpacker.register(target, tmpl); - } - - public static void registerPacker(Class target, MessagePacker packer) { - CustomPacker.register(target, packer); - } - - public static void registerConverter(Class target, MessageConverter converter) { - CustomConverter.register(target, converter); - } - - public static void registerUnpacker(Class target, MessageUnpacker unpacker) { - CustomUnpacker.register(target, unpacker); + TemplateRegistry.register(target, tmpl); } } diff --git a/java/src/main/java/org/msgpack/MessagePackObject.java b/java/src/main/java/org/msgpack/MessagePackObject.java index 8dd9d8b..59fab62 100644 --- a/java/src/main/java/org/msgpack/MessagePackObject.java +++ b/java/src/main/java/org/msgpack/MessagePackObject.java @@ -21,12 +21,9 @@ import java.util.List; import java.util.Set; import java.util.Map; import java.math.BigInteger; +import org.msgpack.template.TemplateRegistry; public abstract class MessagePackObject implements Cloneable, MessagePackable { - static { - Templates.load(); - } - public boolean isNil() { return false; } @@ -138,7 +135,26 @@ public abstract class MessagePackObject implements Cloneable, MessagePackable { abstract public Object clone(); public Object convert(Template tmpl) throws MessageTypeException { - return tmpl.convert(this); + return convert(tmpl, null); + } + + public T convert(Template tmpl, T to) throws MessageTypeException { + return (T)tmpl.convert(this, to); + } + + public T convert(Class klass) throws MessageTypeException { + return convert(klass, null); + } + + public T convert(T to) throws MessageTypeException { + return convert((Class)to.getClass(), to); + } + + public T convert(Class klass, T to) throws MessageTypeException { + if(isNil()) { + return null; + } + return (T)convert(TemplateRegistry.lookup(klass), to); } } diff --git a/java/src/main/java/org/msgpack/util/codegen/DynamicOrdinalEnumPacker.java b/java/src/main/java/org/msgpack/MessagePackTemplateProvider.java similarity index 76% rename from java/src/main/java/org/msgpack/util/codegen/DynamicOrdinalEnumPacker.java rename to java/src/main/java/org/msgpack/MessagePackTemplateProvider.java index d1fdbc6..511625b 100644 --- a/java/src/main/java/org/msgpack/util/codegen/DynamicOrdinalEnumPacker.java +++ b/java/src/main/java/org/msgpack/MessagePackTemplateProvider.java @@ -15,12 +15,9 @@ // See the License for the specific language governing permissions and // limitations under the License. // -package org.msgpack.util.codegen; +package org.msgpack; -import org.msgpack.MessagePacker; +public interface MessagePackTemplateProvider { -public class DynamicOrdinalEnumPacker { - public static MessagePacker create(Class c) { - return DynamicOrdinalEnumTemplate.create(c); - } + Template getTemplate(); } diff --git a/java/src/main/java/org/msgpack/MessageTypeException.java b/java/src/main/java/org/msgpack/MessageTypeException.java index 7a06a3e..bd14844 100644 --- a/java/src/main/java/org/msgpack/MessageTypeException.java +++ b/java/src/main/java/org/msgpack/MessageTypeException.java @@ -27,5 +27,9 @@ public class MessageTypeException extends RuntimeException { public MessageTypeException(String s, Throwable t) { super(s, t); } + + public MessageTypeException(Throwable t) { + super(t); + } } diff --git a/java/src/main/java/org/msgpack/MessageUnpacker.java b/java/src/main/java/org/msgpack/MessageUnpacker.java index 2a89e45..fd9f1ec 100644 --- a/java/src/main/java/org/msgpack/MessageUnpacker.java +++ b/java/src/main/java/org/msgpack/MessageUnpacker.java @@ -20,6 +20,6 @@ package org.msgpack; import java.io.IOException; public interface MessageUnpacker { - Object unpack(Unpacker pac) throws IOException, MessageTypeException; + Object unpack(Unpacker pac, Object to) throws IOException, MessageTypeException; } diff --git a/java/src/main/java/org/msgpack/Packer.java b/java/src/main/java/org/msgpack/Packer.java index 8349a30..17a6796 100644 --- a/java/src/main/java/org/msgpack/Packer.java +++ b/java/src/main/java/org/msgpack/Packer.java @@ -25,11 +25,7 @@ import java.util.Set; import java.util.Map; import java.util.Collection; import java.math.BigInteger; - -import org.msgpack.annotation.MessagePackDelegate; -import org.msgpack.annotation.MessagePackMessage; -import org.msgpack.annotation.MessagePackOrdinalEnum; -import org.msgpack.util.codegen.DynamicTemplate; +import org.msgpack.template.TemplateRegistry; /** * Packer enables you to serialize objects into OutputStream. @@ -48,14 +44,10 @@ import org.msgpack.util.codegen.DynamicTemplate; * You can serialize objects that implements {@link MessagePackable} interface. */ public class Packer { - static { - Templates.load(); - } - public static void load() { } protected byte[] castBytes = new byte[9]; - protected ByteBuffer castBuffer = ByteBuffer.wrap(castBytes); + //protected ByteBuffer castBuffer = ByteBuffer.wrap(castBytes); protected OutputStream out; public Packer(OutputStream out) { @@ -78,7 +70,9 @@ public class Packer { if(d < -(1<<7)) { // signed 16 castBytes[0] = (byte)0xd1; - castBuffer.putShort(1, d); +// castBuffer.putShort(1, d); + castBytes[1] = (byte)(d >> 8); + castBytes[2] = (byte)(d >> 0); out.write(castBytes, 0, 3); } else { // signed 8 @@ -98,7 +92,9 @@ public class Packer { } else { // unsigned 16 castBytes[0] = (byte)0xcd; - castBuffer.putShort(1, d); +// castBuffer.putShort(1, d); + castBytes[1] = (byte)(d >> 8); + castBytes[2] = (byte)(d >> 0); out.write(castBytes, 0, 3); } } @@ -110,12 +106,18 @@ public class Packer { if(d < -(1<<15)) { // signed 32 castBytes[0] = (byte)0xd2; - castBuffer.putInt(1, d); +// castBuffer.putInt(1, d); + castBytes[1] = (byte)(d >> 24); + castBytes[2] = (byte)(d >> 16); + castBytes[3] = (byte)(d >> 8); + castBytes[4] = (byte)(d >> 0); out.write(castBytes, 0, 5); } else if(d < -(1<<7)) { // signed 16 castBytes[0] = (byte)0xd1; - castBuffer.putShort(1, (short)d); +// castBuffer.putShort(1, (short)d); + castBytes[1] = (byte)(d >> 8); + castBytes[2] = (byte)(d >> 0); out.write(castBytes, 0, 3); } else { // signed 8 @@ -135,12 +137,18 @@ public class Packer { } else if(d < (1<<16)) { // unsigned 16 castBytes[0] = (byte)0xcd; - castBuffer.putShort(1, (short)d); +// castBuffer.putShort(1, (short)d); + castBytes[1] = (byte)(d >> 8); + castBytes[2] = (byte)(d >> 0); out.write(castBytes, 0, 3); } else { // unsigned 32 castBytes[0] = (byte)0xce; - castBuffer.putInt(1, d); +// castBuffer.putInt(1, d); + castBytes[1] = (byte)(d >> 24); + castBytes[2] = (byte)(d >> 16); + castBytes[3] = (byte)(d >> 8); + castBytes[4] = (byte)(d >> 0); out.write(castBytes, 0, 5); } } @@ -153,19 +161,33 @@ public class Packer { if(d < -(1L<<31)) { // signed 64 castBytes[0] = (byte)0xd3; - castBuffer.putLong(1, d); +// castBuffer.putLong(1, d); + castBytes[1] = (byte)(d >> 56); + castBytes[2] = (byte)(d >> 48); + castBytes[3] = (byte)(d >> 40); + castBytes[4] = (byte)(d >> 32); + castBytes[5] = (byte)(d >> 24); + castBytes[6] = (byte)(d >> 16); + castBytes[7] = (byte)(d >> 8); + castBytes[8] = (byte)(d >> 0); out.write(castBytes, 0, 9); } else { // signed 32 castBytes[0] = (byte)0xd2; - castBuffer.putInt(1, (int)d); +// castBuffer.putInt(1, (int)d); + castBytes[1] = (byte)(d >> 24); + castBytes[2] = (byte)(d >> 16); + castBytes[3] = (byte)(d >> 8); + castBytes[4] = (byte)(d >> 0); out.write(castBytes, 0, 5); } } else { if(d < -(1<<7)) { // signed 16 castBytes[0] = (byte)0xd1; - castBuffer.putShort(1, (short)d); +// castBuffer.putShort(1, (short)d); + castBytes[1] = (byte)(d >> 8); + castBytes[2] = (byte)(d >> 0); out.write(castBytes, 0, 3); } else { // signed 8 @@ -187,7 +209,9 @@ public class Packer { } else { // unsigned 16 castBytes[0] = (byte)0xcd; - castBuffer.putShort(1, (short)d); +// castBuffer.putShort(1, (short)d); + castBytes[1] = (byte)((d & 0x0000ff00) >> 8); + castBytes[2] = (byte)((d & 0x000000ff) >> 0); out.write(castBytes, 0, 3); //System.out.println("pack uint 16 "+(short)d); } @@ -195,12 +219,24 @@ public class Packer { if(d < (1L<<32)) { // unsigned 32 castBytes[0] = (byte)0xce; - castBuffer.putInt(1, (int)d); +// castBuffer.putInt(1, (int)d); + castBytes[1] = (byte)((d & 0xff000000) >> 24); + castBytes[2] = (byte)((d & 0x00ff0000) >> 16); + castBytes[3] = (byte)((d & 0x0000ff00) >> 8); + castBytes[4] = (byte)((d & 0x000000ff) >> 0); out.write(castBytes, 0, 5); } else { // unsigned 64 castBytes[0] = (byte)0xcf; - castBuffer.putLong(1, d); +// castBuffer.putLong(1, d); + castBytes[1] = (byte)(d >> 56); + castBytes[2] = (byte)(d >> 48); + castBytes[3] = (byte)(d >> 40); + castBytes[4] = (byte)(d >> 32); + castBytes[5] = (byte)(d >> 24); + castBytes[6] = (byte)(d >> 16); + castBytes[7] = (byte)(d >> 8); + castBytes[8] = (byte)(d >> 0); out.write(castBytes, 0, 9); } } @@ -222,7 +258,7 @@ public class Packer { castBytes[6] = barray[barray.length-3]; castBytes[7] = barray[barray.length-2]; castBytes[8] = barray[barray.length-1]; - out.write(castBytes); + out.write(castBytes, 0, 9); return this; } else { throw new MessageTypeException("can't pack BigInteger larger than 0xffffffffffffffff"); @@ -231,14 +267,28 @@ public class Packer { public Packer packFloat(float d) throws IOException { castBytes[0] = (byte)0xca; - castBuffer.putFloat(1, d); +// castBuffer.putFloat(1, d); + int f = Float.floatToRawIntBits(d); + castBytes[1] = (byte)(f >> 24); + castBytes[2] = (byte)(f >> 16); + castBytes[3] = (byte)(f >> 8); + castBytes[4] = (byte)(f >> 0); out.write(castBytes, 0, 5); return this; } public Packer packDouble(double d) throws IOException { castBytes[0] = (byte)0xcb; - castBuffer.putDouble(1, d); +// castBuffer.putDouble(1, d); + long f = Double.doubleToRawLongBits(d); + castBytes[1] = (byte)(f >> 56); + castBytes[2] = (byte)(f >> 48); + castBytes[3] = (byte)(f >> 40); + castBytes[4] = (byte)(f >> 32); + castBytes[5] = (byte)(f >> 24); + castBytes[6] = (byte)(f >> 16); + castBytes[7] = (byte)(f >> 8); + castBytes[8] = (byte)(f >> 0); out.write(castBytes, 0, 9); return this; } @@ -268,11 +318,17 @@ public class Packer { out.write((byte)d); } else if(n < 65536) { castBytes[0] = (byte)0xdc; - castBuffer.putShort(1, (short)n); +// castBuffer.putShort(1, (short)n); + castBytes[1] = (byte)(n >> 8); + castBytes[2] = (byte)(n >> 0); out.write(castBytes, 0, 3); } else { castBytes[0] = (byte)0xdd; - castBuffer.putInt(1, n); +// castBuffer.putInt(1, n); + castBytes[1] = (byte)(n >> 24); + castBytes[2] = (byte)(n >> 16); + castBytes[3] = (byte)(n >> 8); + castBytes[4] = (byte)(n >> 0); out.write(castBytes, 0, 5); } return this; @@ -284,11 +340,17 @@ public class Packer { out.write((byte)d); } else if(n < 65536) { castBytes[0] = (byte)0xde; - castBuffer.putShort(1, (short)n); +// castBuffer.putShort(1, (short)n); + castBytes[1] = (byte)(n >> 8); + castBytes[2] = (byte)(n >> 0); out.write(castBytes, 0, 3); } else { castBytes[0] = (byte)0xdf; - castBuffer.putInt(1, n); +// castBuffer.putInt(1, n); + castBytes[1] = (byte)(n >> 24); + castBytes[2] = (byte)(n >> 16); + castBytes[3] = (byte)(n >> 8); + castBytes[4] = (byte)(n >> 0); out.write(castBytes, 0, 5); } return this; @@ -300,11 +362,17 @@ public class Packer { out.write((byte)d); } else if(n < 65536) { castBytes[0] = (byte)0xda; - castBuffer.putShort(1, (short)n); +// castBuffer.putShort(1, (short)n); + castBytes[1] = (byte)(n >> 8); + castBytes[2] = (byte)(n >> 0); out.write(castBytes, 0, 3); } else { castBytes[0] = (byte)0xdb; - castBuffer.putInt(1, n); +// castBuffer.putInt(1, n); + castBytes[1] = (byte)(n >> 24); + castBytes[2] = (byte)(n >> 16); + castBytes[3] = (byte)(n >> 8); + castBytes[4] = (byte)(n >> 0); out.write(castBytes, 0, 5); } return this; @@ -331,6 +399,11 @@ public class Packer { return packRawBody(b, off, length); } + public Packer packByteBuffer(ByteBuffer buf) throws IOException { + packRaw(buf.remaining()); + return packRawBody(buf.array(), buf.arrayOffset() + buf.position(), buf.remaining()); + } + public Packer packString(String s) throws IOException { byte[] b = ((String)s).getBytes("UTF-8"); packRaw(b.length); @@ -425,6 +498,12 @@ public class Packer { return packRawBody(o); } + public Packer pack(ByteBuffer o) throws IOException { + if (o == null) { return packNil(); } + packRaw(o.remaining()); + return packRawBody(o.array(), o.arrayOffset() + o.position(), o.remaining()); + } + public Packer pack(List o) throws IOException { if(o == null) { return packNil(); } packArray(o.size()); @@ -449,7 +528,8 @@ public class Packer { } public Packer pack(Object o) throws IOException { - Templates.TAny.pack(this, o); + if(o == null) { return packNil(); } + TemplateRegistry.lookup(o.getClass()).pack(this, o); return this; } diff --git a/java/src/main/java/org/msgpack/Templates.java b/java/src/main/java/org/msgpack/Templates.java index 3d7ccc5..4972670 100644 --- a/java/src/main/java/org/msgpack/Templates.java +++ b/java/src/main/java/org/msgpack/Templates.java @@ -20,7 +20,9 @@ package org.msgpack; import org.msgpack.template.*; public class Templates { - public static void load() { } + public static Template tNullable(Template elementTemplate) { + return new NullableTemplate(elementTemplate); + } public static final Template TAny = AnyTemplate.getInstance(); @@ -28,14 +30,6 @@ public class Templates { return TAny; } - public static Template tOptional(Template elementTemplate) { - return new OptionalTemplate(elementTemplate); - } - - public static Template tOptional(Template elementTemplate, Object defaultObject) { - return new OptionalTemplate(elementTemplate, defaultObject); - } - public static Template tList(Template elementTemplate) { return new ListTemplate(elementTemplate); @@ -50,10 +44,13 @@ public class Templates { } public static Template tClass(Class target) { - return new ClassTemplate(target); + Template tmpl = TemplateRegistry.lookup(target); + if(tmpl == null) { + // FIXME + } + return tmpl; } - public static final Template TByte = ByteTemplate.getInstance(); public static Template tByte() { return TByte; @@ -104,5 +101,9 @@ public class Templates { return TByteArray; } + public static final Template TByteBuffer = ByteBufferTemplate.getInstance(); + public static Template tByteBuffer() { + return TByteBuffer; + } } diff --git a/java/src/main/java/org/msgpack/Unpacker.java b/java/src/main/java/org/msgpack/Unpacker.java index d07de1e..01e3ea1 100644 --- a/java/src/main/java/org/msgpack/Unpacker.java +++ b/java/src/main/java/org/msgpack/Unpacker.java @@ -23,6 +23,7 @@ import java.io.IOException; import java.util.Iterator; import java.nio.ByteBuffer; import java.math.BigInteger; +import org.msgpack.template.TemplateRegistry; /** * Unpacker enables you to deserialize objects from stream. @@ -103,10 +104,6 @@ import java.math.BigInteger; * */ public class Unpacker implements Iterable { - static { - Templates.load(); - } - // buffer: // +---------------------------------------------+ // | [object] | [obje| unparsed ... | unused ...| @@ -235,6 +232,7 @@ public class Unpacker implements Iterable { impl.buffer = buffer; impl.offset = offset; impl.filled = length; + impl.bufferReferenced = false; // TODO zero-copy buffer } /** @@ -279,13 +277,16 @@ public class Unpacker implements Iterable { if(impl.buffer == null) { int nextSize = (bufferReserveSize < require) ? require : bufferReserveSize; impl.buffer = new byte[nextSize]; + impl.bufferReferenced = false; // TODO zero-copy buffer return; } - if(impl.filled <= impl.offset) { - // rewind the buffer - impl.filled = 0; - impl.offset = 0; + if(!impl.bufferReferenced) { // TODO zero-copy buffer + if(impl.filled <= impl.offset) { + // rewind the buffer + impl.filled = 0; + impl.offset = 0; + } } if(impl.buffer.length - impl.filled >= require) { @@ -304,6 +305,7 @@ public class Unpacker implements Iterable { impl.buffer = tmp; impl.filled = notParsed; impl.offset = 0; + impl.bufferReferenced = false; // TODO zero-copy buffer } /** @@ -370,8 +372,7 @@ public class Unpacker implements Iterable { * @return offset position that is parsed. */ public int execute(byte[] buffer, int offset, int length) throws UnpackException { - int noffset = impl.execute(buffer, offset + impl.offset, length); - impl.offset = noffset - offset; + int noffset = impl.execute(buffer, offset, length); if(impl.isFinished()) { impl.resetState(); } @@ -539,14 +540,23 @@ public class Unpacker implements Iterable { return impl.unpackRawBody(length); } + /** - * Gets one raw bytes from the buffer. + * Gets one raw object (header + body) from the buffer. * This method calls {@link fill()} method if needed. */ public byte[] unpackByteArray() throws IOException { return impl.unpackByteArray(); } + /** + * Gets one raw object (header + body) from the buffer. + * This method calls {@link fill()} method if needed. + */ + public ByteBuffer unpackByteBuffer() throws IOException { + return impl.unpackByteBuffer(); + } + /** * Gets one {@code String} value from the buffer. * This method calls {@link fill()} method if needed. @@ -576,13 +586,25 @@ public class Unpacker implements Iterable { // return unpackObject(); //} - final public Object unpack(Template tmpl) throws IOException, MessageTypeException { - return tmpl.unpack(this); + final public T unpack(T to) throws IOException, MessageTypeException { + return unpack((Class)to.getClass(), to); } final public T unpack(Class klass) throws IOException, MessageTypeException { - // FIXME optional? - return (T)unpack(Templates.tOptional(Templates.tClass(klass))); + return unpack(klass, null); + } + + final public T unpack(Class klass, T to) throws IOException, MessageTypeException { + if(tryUnpackNull()) { return null; } + return (T)TemplateRegistry.lookup(klass).unpack(this, to); + } + + final public Object unpack(Template tmpl) throws IOException, MessageTypeException { + return unpack(tmpl, null); + } + + final public T unpack(Template tmpl, T to) throws IOException, MessageTypeException { + return (T)tmpl.unpack(this, to); } } diff --git a/java/src/main/java/org/msgpack/UnpackerImpl.java b/java/src/main/java/org/msgpack/UnpackerImpl.java index 6a7085f..30456be 100644 --- a/java/src/main/java/org/msgpack/UnpackerImpl.java +++ b/java/src/main/java/org/msgpack/UnpackerImpl.java @@ -309,6 +309,7 @@ public class UnpackerImpl { cs = ACS_RAW_VALUE; break _fixed_trail_again; case ACS_RAW_VALUE: { + // TODO zero-copy buffer byte[] raw = new byte[trail]; System.arraycopy(src, n, raw, 0, trail); obj = RawType.create(raw); diff --git a/java/src/main/java/org/msgpack/annotation/MessagePackOptional.java b/java/src/main/java/org/msgpack/annotation/Ignore.java similarity index 91% rename from java/src/main/java/org/msgpack/annotation/MessagePackOptional.java rename to java/src/main/java/org/msgpack/annotation/Ignore.java index 9c1a0bb..96a37bb 100644 --- a/java/src/main/java/org/msgpack/annotation/MessagePackOptional.java +++ b/java/src/main/java/org/msgpack/annotation/Ignore.java @@ -22,7 +22,7 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; -@Target(ElementType.FIELD) +@Target({ElementType.FIELD, ElementType.PARAMETER}) @Retention(RetentionPolicy.RUNTIME) -public @interface MessagePackOptional { -} \ No newline at end of file +public @interface Ignore { +} diff --git a/java/src/main/java/org/msgpack/annotation/Index.java b/java/src/main/java/org/msgpack/annotation/Index.java new file mode 100644 index 0000000..7c1b659 --- /dev/null +++ b/java/src/main/java/org/msgpack/annotation/Index.java @@ -0,0 +1,29 @@ +// +// 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.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target({ElementType.FIELD, ElementType.PARAMETER}) +@Retention(RetentionPolicy.RUNTIME) +public @interface Index { + int value(); +} diff --git a/java/src/main/java/org/msgpack/annotation/MessagePackDelegate.java b/java/src/main/java/org/msgpack/annotation/MessagePackDelegate.java index 88c6f8c..bb16e2c 100644 --- a/java/src/main/java/org/msgpack/annotation/MessagePackDelegate.java +++ b/java/src/main/java/org/msgpack/annotation/MessagePackDelegate.java @@ -25,4 +25,5 @@ import java.lang.annotation.Target; @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) public @interface MessagePackDelegate { + String value(); } diff --git a/java/src/main/java/org/msgpack/annotation/MessagePackMessage.java b/java/src/main/java/org/msgpack/annotation/MessagePackMessage.java index 5f781e0..ab3ad0a 100644 --- a/java/src/main/java/org/msgpack/annotation/MessagePackMessage.java +++ b/java/src/main/java/org/msgpack/annotation/MessagePackMessage.java @@ -21,8 +21,10 @@ import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +import org.msgpack.template.FieldOption; @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) public @interface MessagePackMessage { + FieldOption value() default FieldOption.DEFAULT; } diff --git a/java/src/main/java/org/msgpack/annotation/Nullable.java b/java/src/main/java/org/msgpack/annotation/Nullable.java new file mode 100644 index 0000000..e6893e7 --- /dev/null +++ b/java/src/main/java/org/msgpack/annotation/Nullable.java @@ -0,0 +1,28 @@ +// +// 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.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target({ElementType.FIELD, ElementType.PARAMETER}) +@Retention(RetentionPolicy.RUNTIME) +public @interface Nullable { +} diff --git a/java/src/main/java/org/msgpack/annotation/Optional.java b/java/src/main/java/org/msgpack/annotation/Optional.java new file mode 100644 index 0000000..7894f88 --- /dev/null +++ b/java/src/main/java/org/msgpack/annotation/Optional.java @@ -0,0 +1,28 @@ +// +// 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.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target({ElementType.FIELD, ElementType.PARAMETER}) +@Retention(RetentionPolicy.RUNTIME) +public @interface Optional { +} diff --git a/java/src/main/java/org/msgpack/annotation/Required.java b/java/src/main/java/org/msgpack/annotation/Required.java new file mode 100644 index 0000000..1631108 --- /dev/null +++ b/java/src/main/java/org/msgpack/annotation/Required.java @@ -0,0 +1,28 @@ +// +// 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.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target({ElementType.FIELD, ElementType.PARAMETER}) +@Retention(RetentionPolicy.RUNTIME) +public @interface Required { +} diff --git a/java/src/main/java/org/msgpack/buffer/VectoredByteBuffer.java b/java/src/main/java/org/msgpack/buffer/VectoredByteBuffer.java new file mode 100644 index 0000000..79b9d9e --- /dev/null +++ b/java/src/main/java/org/msgpack/buffer/VectoredByteBuffer.java @@ -0,0 +1,462 @@ +// +// MessagePack for Java +// +// Copyright (C) 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.buffer; + +import java.io.InputStream; +import java.io.OutputStream; +import java.io.IOException; +import java.util.List; +import java.util.ArrayList; +import java.nio.ByteBuffer; +import java.nio.channels.GatheringByteChannel; +import java.nio.channels.ScatteringByteChannel; + +public class VectoredByteBuffer implements GatheringByteChannel, ScatteringByteChannel { + private List vec = new ArrayList(); + private ByteBuffer internalBuffer; + private ByteBuffer lastInternalBuffer; + private int chunkSize; + private int referenceThreshold; + + public VectoredByteBuffer() { + this(32*1024); + } + + public VectoredByteBuffer(int chunkSize) { + this(chunkSize, 32); + } + + public VectoredByteBuffer(int chunkSize, int referenceThreshold) { + this.chunkSize = chunkSize; + this.referenceThreshold = referenceThreshold; + internalBuffer = ByteBuffer.allocateDirect(chunkSize); + } + + + public void setChunkSize(int chunkSize) { + this.chunkSize = chunkSize; + } + + public int getChunkSize(int chunkSize) { + return this.chunkSize; + } + + public void setReferenceThreshold(int referenceThreshold) { + this.referenceThreshold = referenceThreshold; + } + + public int getReferenceThreshold(int referenceThreshold) { + return this.referenceThreshold; + } + + + @Override + public void close() { + reset(); + } + + @Override + public boolean isOpen() { + return true; // FIXME? + } + + + public synchronized void reset() { + vec.clear(); + lastInternalBuffer = null; + } + + + public void write(byte[] b) { + write(b, 0, b.length); + } + + public void write(byte[] b, int off, int len) { + if(off < 0 || len < 0 || b.length < off+len) { + throw new IndexOutOfBoundsException(); + } + if(referenceThreshold >= 0 && len > referenceThreshold) { + writeReference(b, off, len); + } else { + writeCopy(b, off, len); + } + } + + public void write(int b) { + byte[] ba = new byte[1]; + ba[0] = (byte)b; + write(ba); + } + + @Override + public int write(ByteBuffer src) { + int slen = src.remaining(); + if(referenceThreshold >= 0 && slen > referenceThreshold) { + writeCopy(src); + } else { + writeReference(src); + } + return slen; + } + + @Override + public synchronized long write(ByteBuffer[] srcs) { + return write(srcs, 0, srcs.length); + } + + @Override + public synchronized long write(ByteBuffer[] srcs, int offset, int length) { + if(offset < 0 || length < 0 || srcs.length < offset+length) { + throw new IndexOutOfBoundsException(); + } + long total = 0; + for(int i=offset; offset < length; offset++) { + ByteBuffer src = srcs[i]; + total += write(src); + } + return total; + } + + private synchronized void writeCopy(byte[] b, int off, int len) { + int ipos = internalBuffer.position(); + if(internalBuffer.capacity() - ipos < len) { + // allocate new buffer + int nsize = chunkSize > len ? chunkSize : len; + internalBuffer = ByteBuffer.allocateDirect(nsize); + ipos = 0; + } else if(internalBuffer == lastInternalBuffer) { + // optimization: concatenates to the last buffer instead + // of adding new reference + ByteBuffer dup = vec.get(vec.size()-1); + internalBuffer.put(b, off, len); + dup.limit(ipos + len); + return; + } + internalBuffer.put(b, off, len); + ByteBuffer dup = internalBuffer.duplicate(); + dup.position(ipos); + dup.mark(); + dup.limit(ipos + len); + vec.add(dup); + lastInternalBuffer = internalBuffer; + } + + private synchronized void writeCopy(ByteBuffer src) { + int slen = src.remaining(); + int ipos = internalBuffer.position(); + if(internalBuffer.capacity() - ipos < slen) { + // allocate new buffer + int nsize = chunkSize > slen ? chunkSize : slen; + internalBuffer = ByteBuffer.allocateDirect(nsize); + ipos = 0; + } else if(internalBuffer == lastInternalBuffer) { + // optimization: concatenates to the last buffer instead + // of adding new reference + ByteBuffer dup = vec.get(vec.size()-1); + int dpos = dup.position(); + internalBuffer.put(src); + ByteBuffer dup2 = internalBuffer.duplicate(); + dup2.position(dpos); + dup2.limit(ipos + slen); + vec.set(vec.size()-1, dup2); + return; + } + internalBuffer.put(src); + ByteBuffer dup = internalBuffer.duplicate(); + dup.position(ipos); + dup.mark(); + dup.limit(ipos + slen); + vec.add(dup); + lastInternalBuffer = internalBuffer; + } + + private synchronized void writeReference(byte[] b, int off, int len) { + ByteBuffer buf = ByteBuffer.wrap(b, off, len); + vec.add(buf); + lastInternalBuffer = null; + } + + private synchronized void writeReference(ByteBuffer src) { + ByteBuffer buf = src.duplicate(); + vec.add(buf); + lastInternalBuffer = null; + } + + + public synchronized void writeTo(java.io.OutputStream out) throws IOException { + byte[] tmpbuf = null; + for(int i=0; i < vec.size(); i++) { + ByteBuffer r = vec.get(i); + int rpos = r.position(); + int rlen = r.limit() - rpos; + if(r.hasArray()) { + byte[] array = r.array(); + out.write(array, rpos, rlen); + } else { + if(tmpbuf == null) { + int max = rlen; + for(int j=i+1; j < vec.size(); j++) { + ByteBuffer c = vec.get(j); + int clen = c.remaining(); + if(max < clen) { + max = clen; + } + } + tmpbuf = new byte[max]; + } + r.get(tmpbuf, 0, rlen); + r.position(rpos); + out.write(tmpbuf, 0, rlen); + } + } + } + + public synchronized byte[] toByteArray() { + byte[] out = new byte[available()]; + int off = 0; + for(ByteBuffer r: vec) { + int rpos = r.position(); + int rlen = r.limit() - rpos; + r.get(out, off, rlen); + r.position(rpos); + off += rlen; + } + return out; + } + + + public synchronized int available() { + int total = 0; + for(ByteBuffer r : vec) { + total += r.remaining(); + } + return total; + } + + public synchronized int read(byte[] b) { + return read(b, 0, b.length); + } + + public synchronized int read(byte[] b, int off, int len) { + if(off < 0 || len < 0 || b.length < off+len) { + throw new IndexOutOfBoundsException(); + } + int start = len; + while(!vec.isEmpty()) { + ByteBuffer r = vec.get(0); + int rlen = r.remaining(); + if(rlen <= len) { + r.get(b, off, rlen); + vec.remove(0); + off += rlen; + len -= rlen; + } else { + r.get(b, off, len); + return start; + } + } + return start - len; + } + + public synchronized int read() { + byte[] ba = new byte[1]; + if(read(ba) >= 1) { + return ba[0]; + } else { + return -1; + } + } + + @Override + public synchronized int read(ByteBuffer dst) { + int len = dst.remaining(); + int start = len; + while(!vec.isEmpty()) { + ByteBuffer r = vec.get(0); + int rlen = r.remaining(); + if(rlen <= len) { + dst.put(r); + vec.remove(0); + len -= rlen; + } else { + int blim = r.limit(); + r.limit(len); + try { + dst.put(r); + } finally { + r.limit(blim); + } + return start; + } + } + return start - len; + } + + @Override + public synchronized long read(ByteBuffer[] dsts) { + return read(dsts, 0, dsts.length); + } + + @Override + public synchronized long read(ByteBuffer[] dsts, int offset, int length) { + if(offset < 0 || length < 0 || dsts.length < offset+length) { + throw new IndexOutOfBoundsException(); + } + long total = 0; + for(int i=offset; i < length; i++) { + ByteBuffer dst = dsts[i]; + int dlen = dst.remaining(); + int rlen = read(dsts[i]); + total += rlen; + if(rlen < dlen) { + return total; + } + } + return total; + } + + public synchronized long read(GatheringByteChannel to) throws IOException { + long total = to.write(vec.toArray(new ByteBuffer[0])); + while(!vec.isEmpty()) { + ByteBuffer r = vec.get(0); + if(r.remaining() == 0) { + vec.remove(0); + } else { + break; + } + } + return total; + } + + public synchronized long skip(long len) { + if(len <= 0) { + return 0; + } + long start = len; + while(!vec.isEmpty()) { + ByteBuffer r = vec.get(0); + int rlen = r.remaining(); + if(rlen <= len) { + r.position(r.position()+rlen); + vec.remove(0); + len -= rlen; + } else { + r.position((int)(r.position()+len)); + return start; + } + } + return start - len; + } + + + public final static class OutputStream extends java.io.OutputStream { + private VectoredByteBuffer vbb; + + OutputStream(VectoredByteBuffer vbb) { + this.vbb = vbb; + } + + @Override + public void write(byte[] b) { + vbb.write(b); + } + + @Override + public void write(byte[] b, int off, int len) { + vbb.write(b, off, len); + } + + @Override + public void write(int b) { + vbb.write(b); + } + + public int write(ByteBuffer src) { + return vbb.write(src); + } + + public long write(ByteBuffer[] srcs) { + return vbb.write(srcs); + } + + public long write(ByteBuffer[] srcs, int offset, int length) { + return vbb.write(srcs, offset, length); + } + + public void writeTo(OutputStream out) throws IOException { + vbb.writeTo(out); + } + + public byte[] toByteArray() { + return vbb.toByteArray(); + } + } + + public final static class InputStream extends java.io.InputStream { + private VectoredByteBuffer vbb; + + InputStream(VectoredByteBuffer vbb) { + this.vbb = vbb; + } + + @Override + public int available() { + return vbb.available(); + } + + @Override + public int read(byte[] b) { + return vbb.read(b); + } + + @Override + public int read(byte[] b, int off, int len) { + return vbb.read(b, off, len); + } + + @Override + public int read() { + return vbb.read(); + } + + public int read(ByteBuffer dst) { + return vbb.read(dst); + } + + public long read(ByteBuffer[] dsts, int offset, int length) { + return vbb.read(dsts, offset, length); + } + + public long read(GatheringByteChannel to) throws IOException { + return vbb.read(to); + } + + public long skip(long len) { + return vbb.skip(len); + } + } + + public OutputStream outputStream() { + return new OutputStream(this); + } + + public InputStream inputStream() { + return new InputStream(this); + } +} + diff --git a/java/src/main/java/org/msgpack/packer/BooleanPacker.java b/java/src/main/java/org/msgpack/packer/BooleanPacker.java deleted file mode 100644 index 5392494..0000000 --- a/java/src/main/java/org/msgpack/packer/BooleanPacker.java +++ /dev/null @@ -1,40 +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.packer; - -import java.io.IOException; -import org.msgpack.*; - -public class BooleanPacker implements MessagePacker { - private BooleanPacker() { } - - public void pack(Packer pk, Object target) throws IOException { - pk.packBoolean((Boolean)target); - } - - static public BooleanPacker getInstance() { - return instance; - } - - static final BooleanPacker instance = new BooleanPacker(); - - static { - CustomMessage.registerPacker(Boolean.class, instance); - } -} - diff --git a/java/src/main/java/org/msgpack/packer/ByteArrayPacker.java b/java/src/main/java/org/msgpack/packer/ByteArrayPacker.java deleted file mode 100644 index 1c590fb..0000000 --- a/java/src/main/java/org/msgpack/packer/ByteArrayPacker.java +++ /dev/null @@ -1,40 +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.packer; - -import java.io.IOException; -import org.msgpack.*; - -public class ByteArrayPacker implements MessagePacker { - private ByteArrayPacker() { } - - public void pack(Packer pk, Object target) throws IOException { - pk.packByteArray((byte[])target); - } - - static public ByteArrayPacker getInstance() { - return instance; - } - - static final ByteArrayPacker instance = new ByteArrayPacker(); - - static { - CustomMessage.registerPacker(byte[].class, instance); - } -} - diff --git a/java/src/main/java/org/msgpack/packer/DoublePacker.java b/java/src/main/java/org/msgpack/packer/DoublePacker.java deleted file mode 100644 index c555869..0000000 --- a/java/src/main/java/org/msgpack/packer/DoublePacker.java +++ /dev/null @@ -1,40 +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.packer; - -import java.io.IOException; -import org.msgpack.*; - -public class DoublePacker implements MessagePacker { - private DoublePacker() { } - - public void pack(Packer pk, Object target) throws IOException { - pk.packDouble(((Double)target)); - } - - static public DoublePacker getInstance() { - return instance; - } - - static final DoublePacker instance = new DoublePacker(); - - static { - CustomMessage.registerPacker(Double.class, instance); - } -} - diff --git a/java/src/main/java/org/msgpack/packer/FloatPacker.java b/java/src/main/java/org/msgpack/packer/FloatPacker.java deleted file mode 100644 index d9dbc71..0000000 --- a/java/src/main/java/org/msgpack/packer/FloatPacker.java +++ /dev/null @@ -1,40 +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.packer; - -import java.io.IOException; -import org.msgpack.*; - -public class FloatPacker implements MessagePacker { - private FloatPacker() { } - - public void pack(Packer pk, Object target) throws IOException { - pk.packFloat((Float)target); - } - - static public FloatPacker getInstance() { - return instance; - } - - static final FloatPacker instance = new FloatPacker(); - - static { - CustomMessage.registerPacker(Float.class, instance); - } -} - diff --git a/java/src/main/java/org/msgpack/packer/IntegerPacker.java b/java/src/main/java/org/msgpack/packer/IntegerPacker.java deleted file mode 100644 index 4f9cde1..0000000 --- a/java/src/main/java/org/msgpack/packer/IntegerPacker.java +++ /dev/null @@ -1,40 +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.packer; - -import java.io.IOException; -import org.msgpack.*; - -public class IntegerPacker implements MessagePacker { - private IntegerPacker() { } - - public void pack(Packer pk, Object target) throws IOException { - pk.packInt((Integer)target); - } - - static public IntegerPacker getInstance() { - return instance; - } - - static final IntegerPacker instance = new IntegerPacker(); - - static { - CustomMessage.registerPacker(Integer.class, instance); - } -} - diff --git a/java/src/main/java/org/msgpack/packer/LongPacker.java b/java/src/main/java/org/msgpack/packer/LongPacker.java deleted file mode 100644 index bc7da8d..0000000 --- a/java/src/main/java/org/msgpack/packer/LongPacker.java +++ /dev/null @@ -1,40 +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.packer; - -import java.io.IOException; -import org.msgpack.*; - -public class LongPacker implements MessagePacker { - private LongPacker() { } - - public void pack(Packer pk, Object target) throws IOException { - pk.packLong((Long)target); - } - - static public LongPacker getInstance() { - return instance; - } - - static final LongPacker instance = new LongPacker(); - - static { - CustomMessage.registerPacker(Long.class, instance); - } -} - diff --git a/java/src/main/java/org/msgpack/packer/ShortPacker.java b/java/src/main/java/org/msgpack/packer/ShortPacker.java deleted file mode 100644 index 4c55cc7..0000000 --- a/java/src/main/java/org/msgpack/packer/ShortPacker.java +++ /dev/null @@ -1,40 +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.packer; - -import java.io.IOException; -import org.msgpack.*; - -public class ShortPacker implements MessagePacker { - private ShortPacker() { } - - public void pack(Packer pk, Object target) throws IOException { - pk.packShort((Short)target); - } - - static public ShortPacker getInstance() { - return instance; - } - - static final ShortPacker instance = new ShortPacker(); - - static { - CustomMessage.registerPacker(Short.class, instance); - } -} - diff --git a/java/src/main/java/org/msgpack/packer/StringPacker.java b/java/src/main/java/org/msgpack/packer/StringPacker.java deleted file mode 100644 index dfea620..0000000 --- a/java/src/main/java/org/msgpack/packer/StringPacker.java +++ /dev/null @@ -1,40 +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.packer; - -import java.io.IOException; -import org.msgpack.*; - -public class StringPacker implements MessagePacker { - private StringPacker() { } - - public void pack(Packer pk, Object target) throws IOException { - pk.packString((String)target); - } - - static public StringPacker getInstance() { - return instance; - } - - static final StringPacker instance = new StringPacker(); - - static { - CustomMessage.registerPacker(String.class, instance); - } -} - diff --git a/java/src/main/java/org/msgpack/template/AnyTemplate.java b/java/src/main/java/org/msgpack/template/AnyTemplate.java index 91eab90..f628388 100644 --- a/java/src/main/java/org/msgpack/template/AnyTemplate.java +++ b/java/src/main/java/org/msgpack/template/AnyTemplate.java @@ -24,18 +24,20 @@ public class AnyTemplate implements Template { private AnyTemplate() { } public void pack(Packer pk, Object target) throws IOException { - if(target == null) { + if(target instanceof MessagePackObject) { + pk.pack((MessagePackObject)target); + } else if(target == null) { pk.packNil(); } else { - new ClassTemplate(target.getClass()).pack(pk, target); + TemplateRegistry.lookup(target.getClass()).pack(pk, target); } } - public Object unpack(Unpacker pac) throws IOException, MessageTypeException { + public Object unpack(Unpacker pac, Object to) throws IOException, MessageTypeException { return pac.unpackObject(); } - public Object convert(MessagePackObject from) throws MessageTypeException { + public Object convert(MessagePackObject from, Object to) throws MessageTypeException { return from; } @@ -46,7 +48,7 @@ public class AnyTemplate implements Template { static final AnyTemplate instance = new AnyTemplate(); static { - CustomMessage.register(MessagePackObject.class, instance); + TemplateRegistry.register(MessagePackObject.class, instance); } } diff --git a/java/src/main/java/org/msgpack/template/BigIntegerTemplate.java b/java/src/main/java/org/msgpack/template/BigIntegerTemplate.java index 79b5c7d..65389b8 100644 --- a/java/src/main/java/org/msgpack/template/BigIntegerTemplate.java +++ b/java/src/main/java/org/msgpack/template/BigIntegerTemplate.java @@ -25,14 +25,18 @@ public class BigIntegerTemplate implements Template { private BigIntegerTemplate() { } public void pack(Packer pk, Object target) throws IOException { - pk.packBigInteger((BigInteger)target); + try { + pk.packBigInteger((BigInteger)target); + } catch (NullPointerException e) { + throw new MessageTypeException("target is null.", e); + } } - public Object unpack(Unpacker pac) throws IOException, MessageTypeException { + public Object unpack(Unpacker pac, Object to) throws IOException, MessageTypeException { return pac.unpackBigInteger(); } - public Object convert(MessagePackObject from) throws MessageTypeException { + public Object convert(MessagePackObject from, Object to) throws MessageTypeException { return from.asBigInteger(); } @@ -43,7 +47,7 @@ public class BigIntegerTemplate implements Template { static final BigIntegerTemplate instance = new BigIntegerTemplate(); static { - CustomMessage.register(BigInteger.class, instance); + TemplateRegistry.register(BigInteger.class, instance); } } diff --git a/java/src/main/java/org/msgpack/template/BooleanArrayTemplate.java b/java/src/main/java/org/msgpack/template/BooleanArrayTemplate.java new file mode 100644 index 0000000..a66e0e1 --- /dev/null +++ b/java/src/main/java/org/msgpack/template/BooleanArrayTemplate.java @@ -0,0 +1,80 @@ +// +// 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.io.IOException; +import org.msgpack.*; + +public class BooleanArrayTemplate implements Template { + private BooleanArrayTemplate() { } + + public void pack(Packer pk, Object target) throws IOException { + if(!(target instanceof boolean[])) { + throw new MessageTypeException(); + } + boolean[] array = (boolean[])target; + try { + pk.packArray(array.length); + } catch (NullPointerException e) { + throw new MessageTypeException("target is null.", e); + } + for(boolean a : array) { + pk.pack(a); + } + } + + public Object unpack(Unpacker pac, Object to) throws IOException, MessageTypeException { + int length = pac.unpackArray(); + boolean[] array; + if(to != null && to instanceof boolean[] && ((boolean[])to).length == length) { + array = (boolean[])to; + } else { + array = new boolean[length]; + } + for(int i=0; i < length; i++) { + array[i] = pac.unpackBoolean(); + } + return array; + } + + public Object convert(MessagePackObject from, Object to) throws MessageTypeException { + MessagePackObject[] src = from.asArray(); + boolean[] array; + if(to != null && to instanceof boolean[] && ((boolean[])to).length == src.length) { + array = (boolean[])to; + } else { + array = new boolean[src.length]; + } + for(int i=0; i < src.length; i++) { + MessagePackObject s = src[i]; + array[i] = s.asBoolean(); + } + return array; + } + + static public BooleanArrayTemplate getInstance() { + return instance; + } + + static final BooleanArrayTemplate instance = new BooleanArrayTemplate(); + + static { + TemplateRegistry.register(boolean[].class, instance); + } +} + diff --git a/java/src/main/java/org/msgpack/template/BooleanTemplate.java b/java/src/main/java/org/msgpack/template/BooleanTemplate.java index dd3367f..a756a62 100644 --- a/java/src/main/java/org/msgpack/template/BooleanTemplate.java +++ b/java/src/main/java/org/msgpack/template/BooleanTemplate.java @@ -24,14 +24,18 @@ public class BooleanTemplate implements Template { private BooleanTemplate() { } public void pack(Packer pk, Object target) throws IOException { - pk.packBoolean((Boolean)target); + try { + pk.packBoolean((Boolean)target); + } catch (NullPointerException e) { + throw new MessageTypeException("target is null.", e); + } } - public Object unpack(Unpacker pac) throws IOException, MessageTypeException { + public Object unpack(Unpacker pac, Object to) throws IOException, MessageTypeException { return pac.unpackBoolean(); } - public Object convert(MessagePackObject from) throws MessageTypeException { + public Object convert(MessagePackObject from, Object to) throws MessageTypeException { return from.asBoolean(); } @@ -42,7 +46,8 @@ public class BooleanTemplate implements Template { static final BooleanTemplate instance = new BooleanTemplate(); static { - CustomMessage.register(Boolean.class, instance); + TemplateRegistry.register(Boolean.class, instance); + TemplateRegistry.register(boolean.class, instance); } } diff --git a/java/src/main/java/org/msgpack/template/BuiltInTemplateLoader.java b/java/src/main/java/org/msgpack/template/BuiltInTemplateLoader.java new file mode 100644 index 0000000..9ac9a8e --- /dev/null +++ b/java/src/main/java/org/msgpack/template/BuiltInTemplateLoader.java @@ -0,0 +1,47 @@ +// +// 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; + +public class BuiltInTemplateLoader { + public static void load() { + AnyTemplate.getInstance(); + BigIntegerTemplate.getInstance(); + BooleanArrayTemplate.getInstance(); + BooleanTemplate.getInstance(); + ByteArrayTemplate.getInstance(); + ByteBufferTemplate.getInstance(); + ByteTemplate.getInstance(); + DoubleArrayTemplate.getInstance(); + DoubleTemplate.getInstance(); + FloatArrayTemplate.getInstance(); + FloatTemplate.getInstance(); + IntArrayTemplate.getInstance(); + IntegerTemplate.getInstance(); + LongArrayTemplate.getInstance(); + LongTemplate.getInstance(); + ShortArrayTemplate.getInstance(); + ShortTemplate.getInstance(); + StringTemplate.getInstance(); + + CollectionTemplate.load(); + ListTemplate.load(); + MapTemplate.load(); + NullableTemplate.load(); + } +} + diff --git a/java/src/main/java/org/msgpack/template/ByteArrayTemplate.java b/java/src/main/java/org/msgpack/template/ByteArrayTemplate.java index 2008b7c..038a541 100644 --- a/java/src/main/java/org/msgpack/template/ByteArrayTemplate.java +++ b/java/src/main/java/org/msgpack/template/ByteArrayTemplate.java @@ -24,14 +24,18 @@ public class ByteArrayTemplate implements Template { private ByteArrayTemplate() { } public void pack(Packer pk, Object target) throws IOException { - pk.packByteArray((byte[])target); + try { + pk.packByteArray((byte[])target); + } catch (NullPointerException e) { + throw new MessageTypeException("target is null.", e); + } } - public Object unpack(Unpacker pac) throws IOException, MessageTypeException { + public Object unpack(Unpacker pac, Object to) throws IOException, MessageTypeException { return pac.unpackByteArray(); } - public Object convert(MessagePackObject from) throws MessageTypeException { + public Object convert(MessagePackObject from, Object to) throws MessageTypeException { return from.asByteArray(); } @@ -42,7 +46,7 @@ public class ByteArrayTemplate implements Template { static final ByteArrayTemplate instance = new ByteArrayTemplate(); static { - CustomMessage.register(byte[].class, instance); + TemplateRegistry.register(byte[].class, instance); } } diff --git a/java/src/main/java/org/msgpack/packer/BytePacker.java b/java/src/main/java/org/msgpack/template/ByteBufferTemplate.java similarity index 51% rename from java/src/main/java/org/msgpack/packer/BytePacker.java rename to java/src/main/java/org/msgpack/template/ByteBufferTemplate.java index 79d5989..b84c3da 100644 --- a/java/src/main/java/org/msgpack/packer/BytePacker.java +++ b/java/src/main/java/org/msgpack/template/ByteBufferTemplate.java @@ -15,26 +15,42 @@ // See the License for the specific language governing permissions and // limitations under the License. // -package org.msgpack.packer; +package org.msgpack.template; +import java.nio.ByteBuffer; import java.io.IOException; import org.msgpack.*; -public class BytePacker implements MessagePacker { - private BytePacker() { } - - public void pack(Packer pk, Object target) throws IOException { - pk.packByte((Byte)target); +public class ByteBufferTemplate implements Template { + private ByteBufferTemplate() { } - static public BytePacker getInstance() { + public void pack(Packer pk, Object target) throws IOException { + try { + pk.packByteBuffer((ByteBuffer) target); + } catch (NullPointerException e) { + throw new MessageTypeException("target is null.", e); + } + } + + public Object unpack(Unpacker pac, Object to) throws IOException, MessageTypeException { + return pac.unpackByteBuffer(); + } + + public Object convert(MessagePackObject from, Object to) + throws MessageTypeException { + // FIXME + byte[] bytes = from.asByteArray(); + return ByteBuffer.wrap(bytes); + } + + static public ByteBufferTemplate getInstance() { return instance; } - static final BytePacker instance = new BytePacker(); + static final ByteBufferTemplate instance = new ByteBufferTemplate(); static { - CustomMessage.registerPacker(Byte.class, instance); + TemplateRegistry.register(ByteBuffer.class, instance); } } - diff --git a/java/src/main/java/org/msgpack/template/ByteTemplate.java b/java/src/main/java/org/msgpack/template/ByteTemplate.java index 0c8a31b..7c6048c 100644 --- a/java/src/main/java/org/msgpack/template/ByteTemplate.java +++ b/java/src/main/java/org/msgpack/template/ByteTemplate.java @@ -24,14 +24,18 @@ public class ByteTemplate implements Template { private ByteTemplate() { } public void pack(Packer pk, Object target) throws IOException { - pk.packByte((Byte)target); + try { + pk.packByte((Byte)target); + } catch (NullPointerException e) { + throw new MessageTypeException("target is null.", e); + } } - public Object unpack(Unpacker pac) throws IOException, MessageTypeException { + public Object unpack(Unpacker pac, Object to) throws IOException, MessageTypeException { return pac.unpackByte(); } - public Object convert(MessagePackObject from) throws MessageTypeException { + public Object convert(MessagePackObject from, Object to) throws MessageTypeException { return from.asByte(); } @@ -42,7 +46,8 @@ public class ByteTemplate implements Template { static final ByteTemplate instance = new ByteTemplate(); static { - CustomMessage.register(Byte.class, instance); + TemplateRegistry.register(Byte.class, instance); + TemplateRegistry.register(byte.class, instance); } } diff --git a/java/src/main/java/org/msgpack/template/ClassTemplate.java b/java/src/main/java/org/msgpack/template/ClassTemplate.java deleted file mode 100644 index 86e8fe8..0000000 --- a/java/src/main/java/org/msgpack/template/ClassTemplate.java +++ /dev/null @@ -1,246 +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.io.IOException; -import org.msgpack.*; -import org.msgpack.annotation.MessagePackDelegate; -import org.msgpack.annotation.MessagePackMessage; -import org.msgpack.annotation.MessagePackOrdinalEnum; -import org.msgpack.util.codegen.DynamicPacker; -import org.msgpack.util.codegen.DynamicConverter; -import org.msgpack.util.codegen.DynamicUnpacker; - -import java.util.*; -import java.math.BigInteger; - -public class ClassTemplate implements Template { - static { - Templates.load(); - } - - private Class klass; - - public ClassTemplate(Class klass) { - this.klass = klass; - } - - public void pack(Packer pk, Object o) throws IOException { - // FIXME - if(o == null) { - pk.packNil(); - return; - } - //if(o instanceof String) { - // pk.packString((String)o); - // return; - //} - if(o instanceof MessagePackable) { - ((MessagePackable)o).messagePack(pk); - return; - } - //if(o instanceof byte[]) { - // pk.packByteArray((byte[])o); - // return; - //} - if(o instanceof List) { - List l = (List)o; - pk.packArray(l.size()); - for(Object i : l) { - pk.pack(i); - } - return; - } - if(o instanceof Set) { - Set l = (Set)o; - pk.packArray(l.size()); - for(Object i : l) { - pk.pack(i); - } - return; - } - if(o instanceof Map) { - Map m = (Map)o; - pk.packMap(m.size()); - for(Map.Entry e : m.entrySet()) { - pk.pack(e.getKey()); - pk.pack(e.getValue()); - } - return; - } - if(o instanceof Collection) { - Collection l = (Collection)o; - pk.packArray(l.size()); - for(Object i : l) { - pk.pack(i); - } - return; - } - //if(o instanceof Boolean) { - // pk.packBoolean((Boolean)o); - // return; - //} - //if(o instanceof Integer) { - // pk.packInt((Integer)o); - // return; - //} - //if(o instanceof Long) { - // pk.packLong((Long)o); - // return; - //} - //if(o instanceof Short) { - // pk.packShort((Short)o); - // return; - //} - //if(o instanceof Byte) { - // pk.packByte((Byte)o); - // return; - //} - //if(o instanceof Float) { - // pk.packFloat((Float)o); - // return; - //} - //if(o instanceof Double) { - // pk.packDouble((Double)o); - // return; - //} - if(o instanceof BigInteger) { - pk.packBigInteger((BigInteger)o); - return; - } - - MessagePacker packer = CustomPacker.get(klass); - if(packer != null) { - packer.pack(pk, o); - return; - } - - if (CustomMessage.isAnnotated(klass, MessagePackMessage.class)) { - packer = DynamicPacker.create(klass); - } else if (CustomMessage.isAnnotated(klass, MessagePackDelegate.class)) { - // FIXME DelegatePacker - throw new UnsupportedOperationException("not supported yet. : " + klass.getName()); - } else if (CustomMessage.isAnnotated(klass, MessagePackOrdinalEnum.class)) { - // FIXME OrdinalEnumPacker - throw new UnsupportedOperationException("not supported yet. : " + klass.getName()); - } - - if (packer != null) { - CustomPacker.register(klass, packer); - packer.pack(pk, o); - return; - } - - throw new MessageTypeException("unknown object "+o+" ("+o.getClass()+")"); - } - - public Object unpack(Unpacker pac) throws IOException, MessageTypeException { - try { - MessageUnpacker unpacker = CustomUnpacker.get(klass); - if(unpacker != null) { - return unpacker.unpack(pac); - } - - if(MessageUnpackable.class.isAssignableFrom(klass)) { - Object obj = klass.newInstance(); - ((MessageUnpackable)obj).messageUnpack(pac); - return obj; - } - - if (CustomMessage.isAnnotated(klass, MessagePackMessage.class)) { - unpacker = DynamicUnpacker.create(klass); - } else if (CustomMessage.isAnnotated(klass, MessagePackDelegate.class)) { - // TODO DelegateUnpacker - throw new UnsupportedOperationException("not supported yet. : " + klass.getName()); - } else if (CustomMessage.isAnnotated(klass, MessagePackOrdinalEnum.class)) { - // TODO OrdinalEnumUnpacker - throw new UnsupportedOperationException("not supported yet. : " + klass.getName()); - } - - if (unpacker != null) { - CustomUnpacker.register(klass, unpacker); - return unpacker.unpack(pac); - } - - // fallback - { - MessageConverter converter = null; - - if (CustomMessage.isAnnotated(klass, MessagePackMessage.class)) { - converter = DynamicConverter.create(klass); - } else if (CustomMessage.isAnnotated(klass, MessagePackDelegate.class)) { - // TODO DelegateConverter - throw new UnsupportedOperationException("not supported yet. : " + klass.getName()); - } else if (CustomMessage.isAnnotated(klass, MessagePackOrdinalEnum.class)) { - // TODO OrdinalEnumConverter - throw new UnsupportedOperationException("not supported yet. : " + klass.getName()); - } - - if (converter != null) { - CustomConverter.register(klass, converter); - return converter.convert(pac.unpackObject()); - } - } - - throw new MessageTypeException(); - - } catch (IllegalAccessException e) { - throw new MessageTypeException(e.getMessage()); // FIXME - } catch (InstantiationException e) { - throw new MessageTypeException(e.getMessage()); // FIXME - } - } - - public Object convert(MessagePackObject from) throws MessageTypeException { - try { - MessageConverter converter = CustomConverter.get(klass); - if(converter != null) { - return converter.convert(from); - } - - if(MessageConvertable.class.isAssignableFrom(klass)) { - Object obj = klass.newInstance(); - ((MessageConvertable)obj).messageConvert(from); - return obj; - } - - if (CustomMessage.isAnnotated(klass, MessagePackMessage.class)) { - converter = DynamicConverter.create(klass); - } else if (CustomMessage.isAnnotated(klass, MessagePackDelegate.class)) { - // TODO DelegateConverter - throw new UnsupportedOperationException("not supported yet. : " + klass.getName()); - } else if (CustomMessage.isAnnotated(klass, MessagePackOrdinalEnum.class)) { - // TODO OrdinalEnumConverter - throw new UnsupportedOperationException("not supported yet. : " + klass.getName()); - } - - if (converter != null) { - CustomConverter.register(klass, converter); - return converter.convert(from); - } - - throw new MessageTypeException(); - - } catch (IllegalAccessException e) { - throw new MessageTypeException(e.getMessage()); // FIXME - } catch (InstantiationException e) { - throw new MessageTypeException(e.getMessage()); // FIXME - } - } -} - diff --git a/java/src/main/java/org/msgpack/template/CollectionTemplate.java b/java/src/main/java/org/msgpack/template/CollectionTemplate.java index 50e6b13..31a937e 100644 --- a/java/src/main/java/org/msgpack/template/CollectionTemplate.java +++ b/java/src/main/java/org/msgpack/template/CollectionTemplate.java @@ -18,45 +18,76 @@ package org.msgpack.template; import java.util.Collection; -import java.util.List; import java.util.LinkedList; import java.io.IOException; -import org.msgpack.*; + +import org.msgpack.MessagePackObject; +import org.msgpack.MessageTypeException; +import org.msgpack.Packer; +import org.msgpack.Template; +import org.msgpack.Unpacker; public class CollectionTemplate implements Template { + public static void load() { } + private Template elementTemplate; public CollectionTemplate(Template elementTemplate) { this.elementTemplate = elementTemplate; } + @SuppressWarnings("unchecked") public void pack(Packer pk, Object target) throws IOException { - if(!(target instanceof Collection)) { - throw new MessageTypeException(); + if (! (target instanceof Collection)) { + if (target == null) { + throw new MessageTypeException(new NullPointerException("target is null.")); + } + throw new MessageTypeException("target is not Collection type: " + target.getClass()); } - Collection collection = (Collection)target; + Collection collection = (Collection) target; pk.packArray(collection.size()); for(Object element : collection) { elementTemplate.pack(pk, element); } } - public Object unpack(Unpacker pac) throws IOException, MessageTypeException { + @SuppressWarnings("unchecked") + public Object unpack(Unpacker pac, Object to) throws IOException, MessageTypeException { int length = pac.unpackArray(); - List list = new LinkedList(); - for(; length > 0; length--) { - list.add( elementTemplate.unpack(pac) ); + Collection c; + if(to == null) { + c = new LinkedList(); + } else { + // TODO: optimize if list is instanceof ArrayList + c = (Collection) to; + c.clear(); } - return list; + for(; length > 0; length--) { + c.add(elementTemplate.unpack(pac, null)); + } + return c; } - public Object convert(MessagePackObject from) throws MessageTypeException { + @SuppressWarnings("unchecked") + public Object convert(MessagePackObject from, Object to) throws MessageTypeException { MessagePackObject[] array = from.asArray(); - List list = new LinkedList(); - for(MessagePackObject element : array) { - list.add( elementTemplate.convert(element) ); + Collection c; + if(to == null) { + c = new LinkedList(); + } else { + // TODO: optimize if list is instanceof ArrayList + c = (Collection) to; + c.clear(); } - return list; + for(MessagePackObject element : array) { + c.add(elementTemplate.convert(element, null)); + } + return c; + } + + static { + TemplateRegistry.registerGeneric(Collection.class, new GenericTemplate1(CollectionTemplate.class)); + TemplateRegistry.register(Collection.class, new CollectionTemplate(AnyTemplate.getInstance())); } } diff --git a/java/src/main/java/org/msgpack/template/DefaultTemplate.java b/java/src/main/java/org/msgpack/template/DefaultTemplate.java new file mode 100644 index 0000000..7784eb2 --- /dev/null +++ b/java/src/main/java/org/msgpack/template/DefaultTemplate.java @@ -0,0 +1,96 @@ +// +// 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.io.IOException; +import java.lang.reflect.Type; +import org.msgpack.*; + +public class DefaultTemplate implements Template { + private Class targetClass; + private Type lookupType; + private boolean messagePackable; + private boolean messageUnpackable; + private boolean messageConvertable; + + public DefaultTemplate(Class targetClass) { + this(targetClass, (Type)targetClass); + } + + public DefaultTemplate(Class targetClass, Type lookupType) { + this.targetClass = targetClass; + this.lookupType = lookupType; + this.messagePackable = MessagePackable.class.isAssignableFrom(targetClass); + this.messageUnpackable = MessageUnpackable.class.isAssignableFrom(targetClass); + this.messageConvertable = MessageConvertable.class.isAssignableFrom(targetClass); + } + + public void pack(Packer pk, Object target) throws IOException { + if(messagePackable) { + if(target == null) { + throw new MessageTypeException("target is null."); + } + ((MessagePackable)target).messagePack(pk); + return; + } + Template tmpl = TemplateRegistry.tryLookup(lookupType); + if(tmpl == this || tmpl == null) { + throw new MessageTypeException(); + } + tmpl.pack(pk, target); + } + + public Object unpack(Unpacker pac, Object to) throws IOException, MessageTypeException { + if(messageUnpackable) { + if(to == null) { + try { + to = targetClass.newInstance(); + } catch (Exception e) { + throw new MessageTypeException(e); + } + } + ((MessageUnpackable)to).messageUnpack(pac); + return to; + } + Template tmpl = TemplateRegistry.tryLookup(lookupType); + if(tmpl == this || tmpl == null) { + throw new MessageTypeException(); + } + return tmpl.unpack(pac, to); + } + + public Object convert(MessagePackObject from, Object to) throws MessageTypeException { + if(messageConvertable) { + if(to == null) { + try { + to = targetClass.newInstance(); + } catch (Exception e) { + throw new MessageTypeException(e); + } + } + ((MessageConvertable)to).messageConvert(from); + return from; + } + Template tmpl = TemplateRegistry.tryLookup(lookupType); + if(tmpl == this || tmpl == null) { + throw new MessageTypeException(); + } + return tmpl.convert(from, to); + } +} + diff --git a/java/src/main/java/org/msgpack/template/DoubleArrayTemplate.java b/java/src/main/java/org/msgpack/template/DoubleArrayTemplate.java new file mode 100644 index 0000000..087a33b --- /dev/null +++ b/java/src/main/java/org/msgpack/template/DoubleArrayTemplate.java @@ -0,0 +1,80 @@ +// +// 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.io.IOException; +import org.msgpack.*; + +public class DoubleArrayTemplate implements Template { + private DoubleArrayTemplate() { } + + public void pack(Packer pk, Object target) throws IOException { + if(!(target instanceof double[])) { + throw new MessageTypeException(); + } + double[] array = (double[])target; + try { + pk.packArray(array.length); + } catch (NullPointerException e) { + throw new MessageTypeException("target is null.", e); + } + for(double a : array) { + pk.pack(a); + } + } + + public Object unpack(Unpacker pac, Object to) throws IOException, MessageTypeException { + int length = pac.unpackArray(); + double[] array; + if(to != null && to instanceof double[] && ((double[])to).length == length) { + array = (double[])to; + } else { + array = new double[length]; + } + for(int i=0; i < length; i++) { + array[i] = pac.unpackDouble(); + } + return array; + } + + public Object convert(MessagePackObject from, Object to) throws MessageTypeException { + MessagePackObject[] src = from.asArray(); + double[] array; + if(to != null && to instanceof double[] && ((double[])to).length == src.length) { + array = (double[])to; + } else { + array = new double[src.length]; + } + for(int i=0; i < src.length; i++) { + MessagePackObject s = src[i]; + array[i] = s.asDouble(); + } + return array; + } + + static public DoubleArrayTemplate getInstance() { + return instance; + } + + static final DoubleArrayTemplate instance = new DoubleArrayTemplate(); + + static { + TemplateRegistry.register(double[].class, instance); + } +} + diff --git a/java/src/main/java/org/msgpack/template/DoubleTemplate.java b/java/src/main/java/org/msgpack/template/DoubleTemplate.java index 94550eb..b76a307 100644 --- a/java/src/main/java/org/msgpack/template/DoubleTemplate.java +++ b/java/src/main/java/org/msgpack/template/DoubleTemplate.java @@ -24,14 +24,18 @@ public class DoubleTemplate implements Template { private DoubleTemplate() { } public void pack(Packer pk, Object target) throws IOException { - pk.packDouble(((Double)target)); + try { + pk.packDouble(((Double)target)); + } catch (NullPointerException e) { + throw new MessageTypeException("target is null.", e); + } } - public Object unpack(Unpacker pac) throws IOException, MessageTypeException { + public Object unpack(Unpacker pac, Object to) throws IOException, MessageTypeException { return pac.unpackDouble(); } - public Object convert(MessagePackObject from) throws MessageTypeException { + public Object convert(MessagePackObject from, Object to) throws MessageTypeException { return from.asDouble(); } @@ -42,7 +46,8 @@ public class DoubleTemplate implements Template { static final DoubleTemplate instance = new DoubleTemplate(); static { - CustomMessage.register(Double.class, instance); + TemplateRegistry.register(Double.class, instance); + TemplateRegistry.register(double.class, instance); } } diff --git a/java/src/main/java/org/msgpack/template/FieldList.java b/java/src/main/java/org/msgpack/template/FieldList.java new file mode 100644 index 0000000..daf59f5 --- /dev/null +++ b/java/src/main/java/org/msgpack/template/FieldList.java @@ -0,0 +1,96 @@ +// +// 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; + +public class FieldList { + public static class Entry { + public Entry() { + this.name = null; + this.option = FieldOption.IGNORE; + } + + public Entry(String name, FieldOption option) { + this.name = name; + this.option = option; + } + + private String name; + private FieldOption option; + + public String getName() { + return name; + } + + public FieldOption getOption() { + return option; + } + + boolean isAvailable() { + return this.option != FieldOption.IGNORE; + } + + boolean isRequired() { + return this.option == FieldOption.REQUIRED; + } + + boolean isOptional() { + return this.option == FieldOption.OPTIONAL; + } + + boolean isNullable() { + return this.option == FieldOption.NULLABLE; + } + } + + private ArrayList list; + + public FieldList() { + list = new ArrayList(); + } + + public void add(final String name) { + add(name, FieldOption.REQUIRED); + } + + public void add(final String name, final FieldOption option) { + list.add(new Entry(name, option)); + } + + public void put(int index, final String name) { + put(index, name, FieldOption.REQUIRED); + } + + public void put(int index, final String name, final FieldOption option) { + if(list.size() < index) { + do { + list.add(new Entry()); + } while(list.size() < index); + list.add(new Entry(name, option)); + } else { + list.set(index, new Entry(name, option)); + } + } + + List getList() { + return list; + } +} + diff --git a/java/src/main/java/org/msgpack/util/codegen/DynamicOrdinalEnumUnpacker.java b/java/src/main/java/org/msgpack/template/FieldOption.java similarity index 75% rename from java/src/main/java/org/msgpack/util/codegen/DynamicOrdinalEnumUnpacker.java rename to java/src/main/java/org/msgpack/template/FieldOption.java index 4c00386..41f152f 100644 --- a/java/src/main/java/org/msgpack/util/codegen/DynamicOrdinalEnumUnpacker.java +++ b/java/src/main/java/org/msgpack/template/FieldOption.java @@ -15,12 +15,13 @@ // See the License for the specific language governing permissions and // limitations under the License. // -package org.msgpack.util.codegen; +package org.msgpack.template; -import org.msgpack.MessageUnpacker; - -public class DynamicOrdinalEnumUnpacker { - public static MessageUnpacker create(Class c) { - return DynamicOrdinalEnumTemplate.create(c); - } +public enum FieldOption { + IGNORE, + REQUIRED, + OPTIONAL, + NULLABLE, + DEFAULT; } + diff --git a/java/src/main/java/org/msgpack/template/FloatArrayTemplate.java b/java/src/main/java/org/msgpack/template/FloatArrayTemplate.java new file mode 100644 index 0000000..a0ca148 --- /dev/null +++ b/java/src/main/java/org/msgpack/template/FloatArrayTemplate.java @@ -0,0 +1,80 @@ +// +// 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.io.IOException; +import org.msgpack.*; + +public class FloatArrayTemplate implements Template { + private FloatArrayTemplate() { } + + public void pack(Packer pk, Object target) throws IOException { + if(!(target instanceof float[])) { + throw new MessageTypeException(); + } + float[] array = (float[])target; + try { + pk.packArray(array.length); + } catch (NullPointerException e) { + throw new MessageTypeException("target is null.", e); + } + for(float a : array) { + pk.pack(a); + } + } + + public Object unpack(Unpacker pac, Object to) throws IOException, MessageTypeException { + int length = pac.unpackArray(); + float[] array; + if(to != null && to instanceof float[] && ((float[])to).length == length) { + array = (float[])to; + } else { + array = new float[length]; + } + for(int i=0; i < length; i++) { + array[i] = pac.unpackFloat(); + } + return array; + } + + public Object convert(MessagePackObject from, Object to) throws MessageTypeException { + MessagePackObject[] src = from.asArray(); + float[] array; + if(to != null && to instanceof float[] && ((float[])to).length == src.length) { + array = (float[])to; + } else { + array = new float[src.length]; + } + for(int i=0; i < src.length; i++) { + MessagePackObject s = src[i]; + array[i] = s.asFloat(); + } + return array; + } + + static public FloatArrayTemplate getInstance() { + return instance; + } + + static final FloatArrayTemplate instance = new FloatArrayTemplate(); + + static { + TemplateRegistry.register(float[].class, instance); + } +} + diff --git a/java/src/main/java/org/msgpack/template/FloatTemplate.java b/java/src/main/java/org/msgpack/template/FloatTemplate.java index c247e29..823d893 100644 --- a/java/src/main/java/org/msgpack/template/FloatTemplate.java +++ b/java/src/main/java/org/msgpack/template/FloatTemplate.java @@ -24,14 +24,18 @@ public class FloatTemplate implements Template { private FloatTemplate() { } public void pack(Packer pk, Object target) throws IOException { - pk.packFloat((Float)target); + try { + pk.packFloat((Float)target); + } catch (NullPointerException e) { + throw new MessageTypeException("target is null.", e); + } } - public Object unpack(Unpacker pac) throws IOException, MessageTypeException { + public Object unpack(Unpacker pac, Object to) throws IOException, MessageTypeException { return pac.unpackFloat(); } - public Object convert(MessagePackObject from) throws MessageTypeException { + public Object convert(MessagePackObject from, Object to) throws MessageTypeException { return from.asFloat(); } @@ -42,7 +46,8 @@ public class FloatTemplate implements Template { static final FloatTemplate instance = new FloatTemplate(); static { - CustomMessage.register(Float.class, instance); + TemplateRegistry.register(Float.class, instance); + TemplateRegistry.register(float.class, instance); } } diff --git a/java/src/main/java/org/msgpack/util/codegen/DynamicOrdinalEnumConverter.java b/java/src/main/java/org/msgpack/template/GenericTemplate.java similarity index 75% rename from java/src/main/java/org/msgpack/util/codegen/DynamicOrdinalEnumConverter.java rename to java/src/main/java/org/msgpack/template/GenericTemplate.java index 598a878..3fa204c 100644 --- a/java/src/main/java/org/msgpack/util/codegen/DynamicOrdinalEnumConverter.java +++ b/java/src/main/java/org/msgpack/template/GenericTemplate.java @@ -15,12 +15,11 @@ // See the License for the specific language governing permissions and // limitations under the License. // -package org.msgpack.util.codegen; +package org.msgpack.template; -import org.msgpack.MessageConverter; +import org.msgpack.Template; -public class DynamicOrdinalEnumConverter { - public static MessageConverter create(Class c) { - return DynamicOrdinalEnumTemplate.create(c); - } +public interface GenericTemplate { + public Template build(Template[] params); } + diff --git a/java/src/main/java/org/msgpack/util/codegen/DynamicOrdinalEnumTemplate.java b/java/src/main/java/org/msgpack/template/GenericTemplate1.java similarity index 50% rename from java/src/main/java/org/msgpack/util/codegen/DynamicOrdinalEnumTemplate.java rename to java/src/main/java/org/msgpack/template/GenericTemplate1.java index 65adcd8..ca89b65 100644 --- a/java/src/main/java/org/msgpack/util/codegen/DynamicOrdinalEnumTemplate.java +++ b/java/src/main/java/org/msgpack/template/GenericTemplate1.java @@ -15,36 +15,40 @@ // See the License for the specific language governing permissions and // limitations under the License. // -package org.msgpack.util.codegen; +package org.msgpack.template; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; - import org.msgpack.Template; -import org.msgpack.util.codegen.DynamicCodeGenBase.TemplateAccessor; -public class DynamicOrdinalEnumTemplate { - public static Template create(Class c) { +public class GenericTemplate1 implements GenericTemplate { + Constructor constructor; + + public GenericTemplate1(Class tmpl) { try { - DynamicCodeGen gen = DynamicCodeGen.getInstance(); - Class tmplClass = gen.generateOrdinalEnumTemplateClass(c); - Constructor cons = tmplClass - .getDeclaredConstructor(new Class[] { Class.class }); - Object obj = cons.newInstance(new Object[] { c }); - ((TemplateAccessor) obj).setTemplates(gen.getTemplates(c)); - return (Template) obj; - } catch (InstantiationException e) { - throw new DynamicCodeGenException(e.getMessage(), e); - } catch (IllegalAccessException e) { - throw new DynamicCodeGenException(e.getMessage(), e); - } catch (SecurityException e) { - throw new DynamicCodeGenException(e.getMessage(), e); + this.constructor = tmpl.getConstructor(new Class[]{Template.class}); + constructor.newInstance(new Object[]{AnyTemplate.getInstance()}); } catch (NoSuchMethodException e) { - throw new DynamicCodeGenException(e.getMessage(), e); - } catch (IllegalArgumentException e) { - throw new DynamicCodeGenException(e.getMessage(), e); + throw new IllegalArgumentException(e); } catch (InvocationTargetException e) { - throw new DynamicCodeGenException(e.getMessage(), e); + throw new IllegalArgumentException(e); + } catch (IllegalAccessException e) { + throw new IllegalArgumentException(e); + } catch (InstantiationException e) { + throw new IllegalArgumentException(e); + } + } + + public Template build(Template[] params) { + try { + return constructor.newInstance(params); + } catch (InvocationTargetException e) { + throw new IllegalArgumentException(e); + } catch (IllegalAccessException e) { + throw new IllegalArgumentException(e); + } catch (InstantiationException e) { + throw new IllegalArgumentException(e); } } } + diff --git a/java/src/main/java/org/msgpack/template/GenericTemplate2.java b/java/src/main/java/org/msgpack/template/GenericTemplate2.java new file mode 100644 index 0000000..5f93877 --- /dev/null +++ b/java/src/main/java/org/msgpack/template/GenericTemplate2.java @@ -0,0 +1,54 @@ +// +// 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.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import org.msgpack.Template; + +public class GenericTemplate2 implements GenericTemplate { + Constructor constructor; + + public GenericTemplate2(Class tmpl) { + try { + this.constructor = tmpl.getConstructor(new Class[]{Template.class, Template.class}); + constructor.newInstance(new Object[]{AnyTemplate.getInstance(), AnyTemplate.getInstance()}); + } catch (NoSuchMethodException e) { + throw new IllegalArgumentException(e); + } catch (InvocationTargetException e) { + throw new IllegalArgumentException(e); + } catch (IllegalAccessException e) { + throw new IllegalArgumentException(e); + } catch (InstantiationException e) { + throw new IllegalArgumentException(e); + } + } + + public Template build(Template[] params) { + try { + return constructor.newInstance(params); + } catch (InvocationTargetException e) { + throw new IllegalArgumentException(e); + } catch (IllegalAccessException e) { + throw new IllegalArgumentException(e); + } catch (InstantiationException e) { + throw new IllegalArgumentException(e); + } + } +} + diff --git a/java/src/main/java/org/msgpack/template/IntArrayTemplate.java b/java/src/main/java/org/msgpack/template/IntArrayTemplate.java new file mode 100644 index 0000000..76e6176 --- /dev/null +++ b/java/src/main/java/org/msgpack/template/IntArrayTemplate.java @@ -0,0 +1,80 @@ +// +// 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.io.IOException; +import org.msgpack.*; + +public class IntArrayTemplate implements Template { + private IntArrayTemplate() { } + + public void pack(Packer pk, Object target) throws IOException { + if(!(target instanceof int[])) { + throw new MessageTypeException(); + } + int[] array = (int[])target; + try { + pk.packArray(array.length); + } catch (NullPointerException e) { + throw new MessageTypeException("target is null.", e); + } + for(int a : array) { + pk.pack(a); + } + } + + public Object unpack(Unpacker pac, Object to) throws IOException, MessageTypeException { + int length = pac.unpackArray(); + int[] array; + if(to != null && to instanceof int[] && ((int[])to).length == length) { + array = (int[])to; + } else { + array = new int[length]; + } + for(int i=0; i < length; i++) { + array[i] = pac.unpackInt(); + } + return array; + } + + public Object convert(MessagePackObject from, Object to) throws MessageTypeException { + MessagePackObject[] src = from.asArray(); + int[] array; + if(to != null && to instanceof int[] && ((int[])to).length == src.length) { + array = (int[])to; + } else { + array = new int[src.length]; + } + for(int i=0; i < src.length; i++) { + MessagePackObject s = src[i]; + array[i] = s.asInt(); + } + return array; + } + + static public IntArrayTemplate getInstance() { + return instance; + } + + static final IntArrayTemplate instance = new IntArrayTemplate(); + + static { + TemplateRegistry.register(int[].class, instance); + } +} + diff --git a/java/src/main/java/org/msgpack/template/IntegerTemplate.java b/java/src/main/java/org/msgpack/template/IntegerTemplate.java index 2dee8e0..f20d36c 100644 --- a/java/src/main/java/org/msgpack/template/IntegerTemplate.java +++ b/java/src/main/java/org/msgpack/template/IntegerTemplate.java @@ -24,14 +24,18 @@ public class IntegerTemplate implements Template { private IntegerTemplate() { } public void pack(Packer pk, Object target) throws IOException { - pk.packInt((Integer)target); + try { + pk.packInt((Integer)target); + } catch (NullPointerException e) { + throw new MessageTypeException("target is null.", e); + } } - public Object unpack(Unpacker pac) throws IOException, MessageTypeException { + public Object unpack(Unpacker pac, Object to) throws IOException, MessageTypeException { return pac.unpackInt(); } - public Object convert(MessagePackObject from) throws MessageTypeException { + public Object convert(MessagePackObject from, Object to) throws MessageTypeException { return from.asInt(); } @@ -42,7 +46,8 @@ public class IntegerTemplate implements Template { static final IntegerTemplate instance = new IntegerTemplate(); static { - CustomMessage.register(Integer.class, instance); + TemplateRegistry.register(Integer.class, instance); + TemplateRegistry.register(int.class, instance); } } diff --git a/java/src/main/java/org/msgpack/template/JavassistTemplateBuilder.java b/java/src/main/java/org/msgpack/template/JavassistTemplateBuilder.java new file mode 100644 index 0000000..38bb998 --- /dev/null +++ b/java/src/main/java/org/msgpack/template/JavassistTemplateBuilder.java @@ -0,0 +1,592 @@ +// +// 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.io.IOException; +import java.lang.reflect.Array; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Type; + +import org.msgpack.*; + +import javassist.CannotCompileException; +import javassist.ClassPool; +import javassist.CtClass; +import javassist.CtConstructor; +import javassist.CtMethod; +import javassist.CtNewConstructor; +import javassist.CtNewMethod; +import javassist.LoaderClassPath; +import javassist.NotFoundException; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class JavassistTemplateBuilder extends TemplateBuilder { + private static Logger LOG = LoggerFactory.getLogger(JavassistTemplateBuilder.class); + + private static JavassistTemplateBuilder instance; + + public synchronized static JavassistTemplateBuilder getInstance() { + if(instance == null) { + instance = new JavassistTemplateBuilder(); + } + return instance; + } + + public static void addClassLoader(ClassLoader cl) { + getInstance().pool.appendClassPath(new LoaderClassPath(cl)); + } + + private JavassistTemplateBuilder() { + this.pool = ClassPool.getDefault(); + } + + protected ClassPool pool; + + private int seqId = 0; + + CtClass makeCtClass(String className) { + return pool.makeClass(className); + } + + CtClass getCtClass(String className) throws NotFoundException { + return pool.get(className); + } + + int nextSeqId() { + return seqId++; + } + + private static abstract class BuildContextBase { + protected JavassistTemplateBuilder director; + + protected String tmplName; + + protected CtClass tmplCtClass; + + protected abstract void setSuperClass() throws CannotCompileException, NotFoundException; + + protected abstract void buildConstructor() throws CannotCompileException, NotFoundException; + + protected void buildMethodInit() { } + + protected abstract String buildPackMethodBody(); + + protected abstract String buildUnpackMethodBody(); + + protected abstract String buildConvertMethodBody(); + + protected abstract Template buildInstance(Class c) throws NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException; + + public BuildContextBase(JavassistTemplateBuilder director) { + this.director = director; + } + + protected Template build(final String className) { + try { + reset(className); + buildClass(); + buildConstructor(); + buildMethodInit(); + buildPackMethod(); + buildUnpackMethod(); + buildConvertMethod(); + return buildInstance(createClass()); + } catch (Exception e) { + String code = getBuiltString(); + if(code != null) { + LOG.error("builder: " + code, e); + throw new TemplateBuildException("cannot compile: " + code, e); + } else { + throw new TemplateBuildException(e); + } + } + } + + protected void reset(String className) { + tmplName = className + "_$$_Template" + director.nextSeqId(); + tmplCtClass = director.makeCtClass(tmplName); + } + + protected void buildClass() throws CannotCompileException, NotFoundException { + setSuperClass(); + tmplCtClass.addInterface(director.getCtClass(Template.class.getName())); + } + + protected void buildPackMethod() throws CannotCompileException, NotFoundException { + String mbody = buildPackMethodBody(); + int mod = javassist.Modifier.PUBLIC; + CtClass returnType = CtClass.voidType; + String mname = "pack"; + CtClass[] paramTypes = new CtClass[] { + director.getCtClass(Packer.class.getName()), + director.getCtClass(Object.class.getName()) + }; + CtClass[] exceptTypes = new CtClass[] { + director.getCtClass(IOException.class.getName()) + }; + CtMethod newCtMethod = CtNewMethod.make( + mod, returnType, mname, + paramTypes, exceptTypes, mbody, tmplCtClass); + tmplCtClass.addMethod(newCtMethod); + } + + protected void buildUnpackMethod() throws CannotCompileException, NotFoundException { + String mbody = buildUnpackMethodBody(); + int mod = javassist.Modifier.PUBLIC; + CtClass returnType = director.getCtClass(Object.class.getName()); + String mname = "unpack"; + CtClass[] paramTypes = new CtClass[] { + director.getCtClass(Unpacker.class.getName()), + director.getCtClass(Object.class.getName()) + }; + CtClass[] exceptTypes = new CtClass[] { + director.getCtClass(MessageTypeException.class.getName()) + }; + CtMethod newCtMethod = CtNewMethod.make( + mod, returnType, mname, + paramTypes, exceptTypes, mbody, tmplCtClass); + tmplCtClass.addMethod(newCtMethod); + } + + protected void buildConvertMethod() throws CannotCompileException, NotFoundException { + String mbody = buildConvertMethodBody(); + int mod = javassist.Modifier.PUBLIC; + CtClass returnType = director.getCtClass(Object.class.getName()); + String mname = "convert"; + CtClass[] paramTypes = new CtClass[] { + director.getCtClass(MessagePackObject.class.getName()), + director.getCtClass(Object.class.getName()) + }; + CtClass[] exceptTypes = new CtClass[] { + director.getCtClass(MessageTypeException.class.getName()) + }; + CtMethod newCtMethod = CtNewMethod.make( + mod, returnType, mname, + paramTypes, exceptTypes, mbody, tmplCtClass); + tmplCtClass.addMethod(newCtMethod); + } + + protected Class createClass() throws CannotCompileException { + return (Class) tmplCtClass.toClass(null, null); + } + + protected StringBuilder stringBuilder = null; + + protected void resetStringBuilder() { + stringBuilder = new StringBuilder(); + } + + protected void buildString(String str) { + stringBuilder.append(str); + } + + protected void buildString(String format, Object... args) { + stringBuilder.append(String.format(format, args)); + } + + protected String getBuiltString() { + if(stringBuilder == null) { + return null; + } + return stringBuilder.toString(); + } + } + + 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; + + public BuildContext(JavassistTemplateBuilder director) { + super(director); + } + + public Template buildTemplate(Class targetClass, FieldEntry[] entries, Template[] templates) { + this.entries = entries; + this.templates = templates; + this.origClass = targetClass; + this.origName = this.origClass.getName(); + return build(this.origName); + } + + protected void setSuperClass() throws CannotCompileException, NotFoundException { + this.tmplCtClass.setSuperclass( + director.getCtClass(JavassistTemplate.class.getName())); + } + + protected void buildConstructor() throws CannotCompileException, NotFoundException { + // Constructor(Class targetClass, Template[] templates) + CtConstructor newCtCons = CtNewConstructor.make( + new CtClass[] { + director.getCtClass(Class.class.getName()), + director.getCtClass(Template.class.getName()+"[]") + }, + new CtClass[0], + this.tmplCtClass); + this.tmplCtClass.addConstructor(newCtCons); + } + + protected Template buildInstance(Class c) throws NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException { + Constructor cons = c.getConstructor(new Class[] { + Class.class, + Template[].class + }); + Object tmpl = cons.newInstance(new Object[] { + this.origClass, + this.templates + }); + return (Template)tmpl; + } + + protected void buildMethodInit() { + this.minimumArrayLength = 0; + for(int i=0; i < entries.length; i++) { + FieldEntry e = entries[i]; + if(e.isRequired() || e.isNullable()) { + this.minimumArrayLength = i+1; + } + } + } + + protected String buildPackMethodBody() { + resetStringBuilder(); + buildString("{"); + buildString("%s _$$_t = (%s)$2;", this.origName, this.origName); + buildString("$1.packArray(%d);", entries.length); + for(int i=0; i < entries.length; i++) { + FieldEntry e = entries[i]; + if(!e.isAvailable()) { + buildString("$1.packNil();"); + continue; + } + Class type = e.getType(); + if(type.isPrimitive()) { + buildString("$1.%s(_$$_t.%s);", primitivePackName(type), e.getName()); + } else { + buildString("if(_$$_t.%s == null) {", e.getName()); + if(!e.isNullable() && !e.isOptional()) { + buildString("throw new %s();", MessageTypeException.class.getName()); + } else { + buildString("$1.packNil();"); + } + buildString("} else {"); + buildString(" this.templates[%d].pack($1, _$$_t.%s);", i, e.getName()); + buildString("}"); + } + } + buildString("}"); + return getBuiltString(); + } + + protected String buildUnpackMethodBody() { + resetStringBuilder(); + buildString("{ "); + + buildString("%s _$$_t;", this.origName); + buildString("if($2 == null) {"); + buildString(" _$$_t = new %s();", this.origName); + buildString("} else {"); + buildString(" _$$_t = (%s)$2;", this.origName); + buildString("}"); + + buildString("int length = $1.unpackArray();"); + buildString("if(length < %d) {", this.minimumArrayLength); + buildString(" throw new %s();", MessageTypeException.class.getName()); + buildString("}"); + + int i; + for(i=0; i < this.minimumArrayLength; i++) { + FieldEntry e = entries[i]; + if(!e.isAvailable()) { + buildString("$1.unpackObject();"); + continue; + } + + buildString("if($1.tryUnpackNull()) {"); + if(e.isRequired()) { + // Required + nil => exception + buildString("throw new %s();", MessageTypeException.class.getName()); + } else if(e.isOptional()) { + // Optional + nil => keep default value + } else { // Nullable + // Nullable + nil => set null + buildString("_$$_t.%s = null;", e.getName()); + } + buildString("} else {"); + Class type = e.getType(); + if(type.isPrimitive()) { + buildString("_$$_t.%s = $1.%s();", e.getName(), primitiveUnpackName(type)); + } else { + buildString("_$$_t.%s = (%s)this.templates[%d].unpack($1, _$$_t.%s);", e.getName(), e.getJavaTypeName(), i, e.getName()); + } + buildString("}"); + } + + for(; i < entries.length; i++) { + buildString("if(length <= %d) { return _$$_t; }", i); + + FieldEntry e = entries[i]; + if(!e.isAvailable()) { + buildString("$1.unpackObject();"); + continue; + } + + buildString("if($1.tryUnpackNull()) {"); + // this is Optional field becaue i >= minimumArrayLength + // Optional + nil => keep default value + buildString("} else {"); + Class type = e.getType(); + if(type.isPrimitive()) { + buildString("_$$_t.%s = $1.%s();", e.getName(), primitiveUnpackName(type)); + } else { + buildString("_$$_t.%s = (%s)this.templates[%d].unpack($1, _$$_t.%s);", e.getName(), e.getJavaTypeName(), i, e.getName()); + } + buildString("}"); + } + + // latter entries are all Optional + nil => keep default value + + buildString("for(int i=%d; i < length; i++) {", i); + buildString(" $1.unpackObject();"); + buildString("}"); + + buildString("return _$$_t;"); + + buildString("}"); + return getBuiltString(); + } + + protected String buildConvertMethodBody() { + resetStringBuilder(); + buildString("{ "); + + buildString("%s _$$_t;", this.origName); + buildString("if($2 == null) {"); + buildString(" _$$_t = new %s();", this.origName); + buildString("} else {"); + buildString(" _$$_t = (%s)$2;", this.origName); + buildString("}"); + + buildString("%s[] array = $1.asArray();", MessagePackObject.class.getName()); + buildString("int length = array.length;"); + buildString("if(length < %d) {", this.minimumArrayLength); + buildString(" throw new %s();", MessageTypeException.class.getName()); + buildString("}"); + + buildString("%s obj;", MessagePackObject.class.getName()); + + int i; + for(i=0; i < this.minimumArrayLength; i++) { + FieldEntry e = entries[i]; + if(!e.isAvailable()) { + continue; + } + + buildString("obj = array[%d];", i); + buildString("if(obj.isNil()) {"); + if(e.isRequired()) { + // Required + nil => exception + buildString("throw new %s();", MessageTypeException.class.getName()); + } else if(e.isOptional()) { + // Optional + nil => keep default value + } else { // Nullable + // Nullable + nil => set null + buildString("_$$_t.%s = null;", e.getName()); + } + buildString("} else {"); + Class type = e.getType(); + if(type.isPrimitive()) { + buildString("_$$_t.%s = obj.%s();", e.getName(), primitiveConvertName(type)); + } else { + buildString("_$$_t.%s = (%s)this.templates[%d].convert(obj, _$$_t.%s);", e.getName(), e.getJavaTypeName(), i, e.getName()); + } + buildString("}"); + } + + for(; i < entries.length; i++) { + buildString("if(length <= %d) { return _$$_t; }", i); + + FieldEntry e = entries[i]; + if(!e.isAvailable()) { + continue; + } + + buildString("obj = array[%d];", i); + buildString("if(obj.isNil()) {"); + // this is Optional field becaue i >= minimumArrayLength + // Optional + nil => keep default value + buildString("} else {"); + Class type = e.getType(); + if(type.isPrimitive()) { + buildString("_$$_t.%s = obj.%s();", e.getName(), primitiveConvertName(type)); + } else { + buildString("_$$_t.%s = (%s)this.templates[%d].convert(obj, _$$_t.%s);", e.getName(), e.getJavaTypeName(), i, e.getName()); + } + buildString("}"); + } + + // latter entries are all Optional + nil => keep default value + + buildString("return _$$_t;"); + + buildString("}"); + return getBuiltString(); + } + + protected String primitivePackName(Class type) { + if(type == boolean.class) { + return "packBoolean"; + } else if(type == byte.class) { + return "packByte"; + } else if(type == short.class) { + return "packShort"; + } else if(type == int.class) { + return "packInt"; + } else if(type == long.class) { + return "packLong"; + } else if(type == float.class) { + return "packFloat"; + } else if(type == double.class) { + return "packDouble"; + } + return null; + } + + protected String primitiveUnpackName(Class type) { + if(type == boolean.class) { + return "unpackBoolean"; + } else if(type == byte.class) { + return "unpackByte"; + } else if(type == short.class) { + return "unpackShort"; + } else if(type == int.class) { + return "unpackInt"; + } else if(type == long.class) { + return "unpackLong"; + } else if(type == float.class) { + return "unpackFloat"; + } else if(type == double.class) { + return "unpackDouble"; + } + return null; + } + + protected String primitiveConvertName(Class type) { + if(type == boolean.class) { + return "asBoolean"; + } else if(type == byte.class) { + return "asByte"; + } else if(type == short.class) { + return "asShort"; + } else if(type == int.class) { + return "asInt"; + } else if(type == long.class) { + return "asLong"; + } else if(type == float.class) { + return "asFloat"; + } else if(type == double.class) { + return "asDouble"; + } + return null; + } + } + + public Template buildTemplate(Class targetClass, FieldEntry[] entries) { + // FIXME private / packagefields + //for(FieldEntry e : entries) { + // Field f = e.getField(); + // int mod = f.getModifiers(); + // if(!Modifier.isPublic(mod)) { + // f.setAccessible(true); + // } + //} + + Template[] tmpls = new Template[entries.length]; + for(int i=0; i < entries.length; i++) { + FieldEntry e = entries[i]; + if(!e.isAvailable()) { + tmpls[i] = null; + } else { + Template tmpl = TemplateRegistry.lookup(e.getGenericType(), true); + tmpls[i] = tmpl; + } + } + + BuildContext bc = new BuildContext(this); + return bc.buildTemplate(targetClass, entries, tmpls); + } + + static class JavassistOrdinalEnumTemplate extends ReflectionTemplateBuilder.ReflectionOrdinalEnumTemplate { + JavassistOrdinalEnumTemplate(Enum[] entries) { + super(entries); + } + } + + 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/ListTemplate.java b/java/src/main/java/org/msgpack/template/ListTemplate.java index 34cbe35..385d7b0 100644 --- a/java/src/main/java/org/msgpack/template/ListTemplate.java +++ b/java/src/main/java/org/msgpack/template/ListTemplate.java @@ -23,6 +23,8 @@ import java.io.IOException; import org.msgpack.*; public class ListTemplate implements Template { + static void load() { } + private Template elementTemplate; public ListTemplate(Template elementTemplate) { @@ -35,8 +37,11 @@ public class ListTemplate implements Template { @SuppressWarnings("unchecked") public void pack(Packer pk, Object target) throws IOException { - if(!(target instanceof List)) { - throw new MessageTypeException(); + if (! (target instanceof List)) { + if (target == null) { + throw new MessageTypeException(new NullPointerException("target is null.")); + } + throw new MessageTypeException("target is not List type: " + target.getClass()); } List list = (List)target; pk.packArray(list.size()); @@ -45,22 +50,42 @@ public class ListTemplate implements Template { } } - public Object unpack(Unpacker pac) throws IOException, MessageTypeException { + @SuppressWarnings("unchecked") + public Object unpack(Unpacker pac, Object to) throws IOException, MessageTypeException { int length = pac.unpackArray(); - List list = new ArrayList(length); + List list; + if(to == null) { + list = new ArrayList(length); + } else { + list = (List) to; + list.clear(); + } for(; length > 0; length--) { - list.add( elementTemplate.unpack(pac) ); + list.add( elementTemplate.unpack(pac, null) ); } return list; } - public Object convert(MessagePackObject from) throws MessageTypeException { + @SuppressWarnings("unchecked") + public Object convert(MessagePackObject from, Object to) throws MessageTypeException { MessagePackObject[] array = from.asArray(); - List list = new ArrayList(array.length); + List list; + if(to == null) { + list = new ArrayList(array.length); + } else { + // TODO: optimize if list is instanceof ArrayList + list = (List) to; + list.clear(); + } for(MessagePackObject element : array) { - list.add( elementTemplate.convert(element) ); + list.add( elementTemplate.convert(element, null) ); } return list; } + + static { + TemplateRegistry.registerGeneric(List.class, new GenericTemplate1(ListTemplate.class)); + TemplateRegistry.register(List.class, new ListTemplate(AnyTemplate.getInstance())); + } } diff --git a/java/src/main/java/org/msgpack/template/LongArrayTemplate.java b/java/src/main/java/org/msgpack/template/LongArrayTemplate.java new file mode 100644 index 0000000..2854697 --- /dev/null +++ b/java/src/main/java/org/msgpack/template/LongArrayTemplate.java @@ -0,0 +1,80 @@ +// +// 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.io.IOException; +import org.msgpack.*; + +public class LongArrayTemplate implements Template { + private LongArrayTemplate() { } + + public void pack(Packer pk, Object target) throws IOException { + if(!(target instanceof long[])) { + throw new MessageTypeException(); + } + long[] array = (long[])target; + try { + pk.packArray(array.length); + } catch (NullPointerException e) { + throw new MessageTypeException("target is null.", e); + } + for(long a : array) { + pk.pack(a); + } + } + + public Object unpack(Unpacker pac, Object to) throws IOException, MessageTypeException { + int length = pac.unpackArray(); + long[] array; + if(to != null && to instanceof long[] && ((long[])to).length == length) { + array = (long[])to; + } else { + array = new long[length]; + } + for(int i=0; i < length; i++) { + array[i] = pac.unpackLong(); + } + return array; + } + + public Object convert(MessagePackObject from, Object to) throws MessageTypeException { + MessagePackObject[] src = from.asArray(); + long[] array; + if(to != null && to instanceof long[] && ((long[])to).length == src.length) { + array = (long[])to; + } else { + array = new long[src.length]; + } + for(int i=0; i < src.length; i++) { + MessagePackObject s = src[i]; + array[i] = s.asLong(); + } + return array; + } + + static public LongArrayTemplate getInstance() { + return instance; + } + + static final LongArrayTemplate instance = new LongArrayTemplate(); + + static { + TemplateRegistry.register(long[].class, instance); + } +} + diff --git a/java/src/main/java/org/msgpack/template/LongTemplate.java b/java/src/main/java/org/msgpack/template/LongTemplate.java index 930b7d0..28bad53 100644 --- a/java/src/main/java/org/msgpack/template/LongTemplate.java +++ b/java/src/main/java/org/msgpack/template/LongTemplate.java @@ -24,14 +24,18 @@ public class LongTemplate implements Template { private LongTemplate() { } public void pack(Packer pk, Object target) throws IOException { - pk.packLong((Long)target); + try { + pk.packLong((Long)target); + } catch (NullPointerException e) { + throw new MessageTypeException("target is null.", e); + } } - public Object unpack(Unpacker pac) throws IOException, MessageTypeException { + public Object unpack(Unpacker pac, Object to) throws IOException, MessageTypeException { return pac.unpackLong(); } - public Object convert(MessagePackObject from) throws MessageTypeException { + public Object convert(MessagePackObject from, Object to) throws MessageTypeException { return from.asLong(); } @@ -42,7 +46,8 @@ public class LongTemplate implements Template { static final LongTemplate instance = new LongTemplate(); static { - CustomMessage.register(Long.class, instance); + TemplateRegistry.register(Long.class, instance); + TemplateRegistry.register(long.class, instance); } } diff --git a/java/src/main/java/org/msgpack/template/MapTemplate.java b/java/src/main/java/org/msgpack/template/MapTemplate.java index 3720292..9ad74fa 100644 --- a/java/src/main/java/org/msgpack/template/MapTemplate.java +++ b/java/src/main/java/org/msgpack/template/MapTemplate.java @@ -23,6 +23,8 @@ import java.io.IOException; import org.msgpack.*; public class MapTemplate implements Template { + static void load() { } + private Template keyTemplate; private Template valueTemplate; @@ -42,9 +44,12 @@ public class MapTemplate implements Template { @SuppressWarnings("unchecked") public void pack(Packer pk, Object target) throws IOException { if(!(target instanceof Map)) { - throw new MessageTypeException(); + if (target == null) { + throw new MessageTypeException(new NullPointerException("target is null.")); + } + throw new MessageTypeException("target is not Map type: " + target.getClass()); } - Map map = (Map)target; + Map map = (Map) target; pk.packMap(map.size()); for(Map.Entry pair : map.entrySet()) { keyTemplate.pack(pk, pair.getKey()); @@ -52,27 +57,45 @@ public class MapTemplate implements Template { } } - public Object unpack(Unpacker pac) throws IOException, MessageTypeException { + @SuppressWarnings("unchecked") + public Object unpack(Unpacker pac, Object to) throws IOException, MessageTypeException { int length = pac.unpackMap(); - Map map = new HashMap(length); + Map map; + if(to == null) { + map = new HashMap(length); + } else { + map = (Map) to; + map.clear(); + } for(; length > 0; length--) { - Object key = keyTemplate.unpack(pac); - Object value = valueTemplate.unpack(pac); + Object key = keyTemplate.unpack(pac, null); + Object value = valueTemplate.unpack(pac, null); map.put(key, value); } return map; } @SuppressWarnings("unchecked") - public Object convert(MessagePackObject from) throws MessageTypeException { + public Object convert(MessagePackObject from, Object to) throws MessageTypeException { Map src = from.asMap(); - Map map = new HashMap(); + Map map; + if(to == null) { + map = new HashMap(src.size()); + } else { + map = (Map) to; + map.clear(); + } for(Map.Entry pair : src.entrySet()) { - Object key = keyTemplate.convert(pair.getKey()); - Object value = valueTemplate.convert(pair.getValue()); + Object key = keyTemplate.convert(pair.getKey(), null); + Object value = valueTemplate.convert(pair.getValue(), null); map.put(key, value); } return map; } + + static { + TemplateRegistry.registerGeneric(Map.class, new GenericTemplate2(MapTemplate.class)); + TemplateRegistry.register(Map.class, new MapTemplate(AnyTemplate.getInstance(), AnyTemplate.getInstance())); + } } diff --git a/java/src/main/java/org/msgpack/packer/OptionalPacker.java b/java/src/main/java/org/msgpack/template/NullableTemplate.java similarity index 54% rename from java/src/main/java/org/msgpack/packer/OptionalPacker.java rename to java/src/main/java/org/msgpack/template/NullableTemplate.java index e9550a4..431da59 100644 --- a/java/src/main/java/org/msgpack/packer/OptionalPacker.java +++ b/java/src/main/java/org/msgpack/template/NullableTemplate.java @@ -15,24 +15,44 @@ // See the License for the specific language governing permissions and // limitations under the License. // -package org.msgpack.packer; +package org.msgpack.template; import java.io.IOException; import org.msgpack.*; -public class OptionalPacker implements MessagePacker { - private MessagePacker elementPacker; +public class NullableTemplate implements Template { + static void load() { } - public OptionalPacker(MessagePacker elementPacker) { - this.elementPacker = elementPacker; + private Template elementTemplate; + + public NullableTemplate(Template elementTemplate) { + this.elementTemplate = elementTemplate; + } + + public Template getElementTemplate() { + return elementTemplate; } public void pack(Packer pk, Object target) throws IOException { if(target == null) { pk.packNil(); } else { - elementPacker.pack(pk, target); + elementTemplate.pack(pk, target); } } + + public Object unpack(Unpacker pac, Object to) throws IOException, MessageTypeException { + if(pac.tryUnpackNull()) { + return null; + } + return elementTemplate.unpack(pac, to); + } + + public Object convert(MessagePackObject from, Object to) throws MessageTypeException { + if(from.isNil()) { + return null; + } + return elementTemplate.convert(from, to); + } } diff --git a/java/src/main/java/org/msgpack/template/OptionalTemplate.java b/java/src/main/java/org/msgpack/template/OptionalTemplate.java index 6358d7d..9e519e7 100644 --- a/java/src/main/java/org/msgpack/template/OptionalTemplate.java +++ b/java/src/main/java/org/msgpack/template/OptionalTemplate.java @@ -45,18 +45,18 @@ public class OptionalTemplate implements Template { } } - public Object unpack(Unpacker pac) throws IOException, MessageTypeException { + public Object unpack(Unpacker pac, Object to) throws IOException, MessageTypeException { if(pac.tryUnpackNull()) { - return defaultObject; + return defaultObject; // FIXME return to? } - return elementTemplate.unpack(pac); + return elementTemplate.unpack(pac, to); } - public Object convert(MessagePackObject from) throws MessageTypeException { + public Object convert(MessagePackObject from, Object to) throws MessageTypeException { if(from.isNil()) { - return defaultObject; + return defaultObject; // FIXME return to? } - return elementTemplate.convert(from); + return elementTemplate.convert(from, to); } } diff --git a/java/src/main/java/org/msgpack/template/ReflectionTemplateBuilder.java b/java/src/main/java/org/msgpack/template/ReflectionTemplateBuilder.java new file mode 100644 index 0000000..03ff206 --- /dev/null +++ b/java/src/main/java/org/msgpack/template/ReflectionTemplateBuilder.java @@ -0,0 +1,569 @@ +// +// 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.io.IOException; +import java.lang.reflect.*; +import java.util.Map; +import java.util.HashMap; +import org.msgpack.*; + +public class ReflectionTemplateBuilder extends TemplateBuilder { + private static ReflectionTemplateBuilder instance; + public synchronized static ReflectionTemplateBuilder getInstance() { + if(instance == null) { + instance = new ReflectionTemplateBuilder(); + } + return instance; + } + + private ReflectionTemplateBuilder() { + } + + static abstract class ReflectionFieldEntry extends FieldEntry { + ReflectionFieldEntry(FieldEntry e) { + super(e.getField(), e.getOption()); + } + + public abstract void pack(Object target, Packer pac) throws IOException; + + public abstract void convert(Object target, MessagePackObject obj) throws MessageTypeException, IllegalAccessException; + + public abstract void unpack(Object target, Unpacker pac) throws IOException, MessageTypeException, IllegalAccessException; + + public void setNull(Object target) throws IllegalAccessException { + getField().set(target, null); + } + } + + static class NullFieldEntry extends ReflectionFieldEntry { + NullFieldEntry(FieldEntry e) { + super(e); + } + public void pack(Object target, Packer pac) throws IOException { } + public void convert(Object target, MessagePackObject obj) throws MessageTypeException, IllegalAccessException { } + public void unpack(Object target, Unpacker pac) throws IOException, MessageTypeException, IllegalAccessException { } + } + + static class ObjectFieldEntry extends ReflectionFieldEntry { + private Template template; + + ObjectFieldEntry(FieldEntry e, Template template) { + super(e); + this.template = template; + } + + public void pack(Object target, Packer pac) throws IOException { + template.pack(pac, target); + } + + public void convert(Object target, MessagePackObject obj) throws MessageTypeException, IllegalAccessException { + Field f = getField(); + Class type = (Class)f.getType(); + Object fieldReference = f.get(target); + Object valueReference = template.convert(obj, fieldReference); + if(valueReference != fieldReference) { + f.set(target, valueReference); + } + } + + public void unpack(Object target, Unpacker pac) throws IOException, MessageTypeException, IllegalAccessException { + Field f = getField(); + Class type = (Class)f.getType(); + Object fieldReference = f.get(target); + Object valueReference = template.unpack(pac, fieldReference); + if(valueReference != fieldReference) { + f.set(target, valueReference); + } + } + } + + static class BooleanFieldEntry extends ReflectionFieldEntry { + BooleanFieldEntry(FieldEntry e) { + super(e); + } + public void pack(Object target, Packer pac) throws IOException { + pac.pack((boolean)(Boolean)target); + } + public void convert(Object target, MessagePackObject obj) throws MessageTypeException, IllegalAccessException { + getField().setBoolean(target, obj.asBoolean()); + } + public void unpack(Object target, Unpacker pac) throws IOException, MessageTypeException, IllegalAccessException { + getField().setBoolean(target, pac.unpackBoolean()); + } + } + + static class ByteFieldEntry extends ReflectionFieldEntry { + ByteFieldEntry(FieldEntry e) { + super(e); + } + public void pack(Object target, Packer pac) throws IOException { + pac.pack((byte)(Byte)target); + } + public void convert(Object target, MessagePackObject obj) throws MessageTypeException, IllegalAccessException { + getField().setByte(target, obj.asByte()); + } + public void unpack(Object target, Unpacker pac) throws IOException, MessageTypeException, IllegalAccessException { + getField().setByte(target, pac.unpackByte()); + } + } + + static class ShortFieldEntry extends ReflectionFieldEntry { + ShortFieldEntry(FieldEntry e) { + super(e); + } + public void pack(Object target, Packer pac) throws IOException { + pac.pack((short)(Short)target); + } + public void convert(Object target, MessagePackObject obj) throws MessageTypeException, IllegalAccessException { + getField().setShort(target, obj.asShort()); + } + public void unpack(Object target, Unpacker pac) throws IOException, MessageTypeException, IllegalAccessException { + getField().setShort(target, pac.unpackShort()); + } + } + + static class IntFieldEntry extends ReflectionFieldEntry { + IntFieldEntry(FieldEntry e) { + super(e); + } + public void pack(Object target, Packer pac) throws IOException { + pac.pack((int)(Integer)target); + } + public void convert(Object target, MessagePackObject obj) throws MessageTypeException, IllegalAccessException { + getField().setInt(target, obj.asInt()); + } + public void unpack(Object target, Unpacker pac) throws IOException, MessageTypeException, IllegalAccessException { + getField().setInt(target, pac.unpackInt()); + } + } + + static class LongFieldEntry extends ReflectionFieldEntry { + LongFieldEntry(FieldEntry e) { + super(e); + } + public void pack(Object target, Packer pac) throws IOException { + pac.pack((long)(Long)target); + } + public void convert(Object target, MessagePackObject obj) throws MessageTypeException, IllegalAccessException { + getField().setLong(target, obj.asLong()); + } + public void unpack(Object target, Unpacker pac) throws IOException, MessageTypeException, IllegalAccessException { + getField().setLong(target, pac.unpackLong()); + } + } + + static class FloatFieldEntry extends ReflectionFieldEntry { + FloatFieldEntry(FieldEntry e) { + super(e); + } + public void pack(Object target, Packer pac) throws IOException { + pac.pack((float)(Float)target); + } + public void convert(Object target, MessagePackObject obj) throws MessageTypeException, IllegalAccessException { + getField().setFloat(target, obj.asFloat()); + } + public void unpack(Object target, Unpacker pac) throws IOException, MessageTypeException, IllegalAccessException { + getField().setFloat(target, pac.unpackFloat()); + } + } + + static class DoubleFieldEntry extends ReflectionFieldEntry { + DoubleFieldEntry(FieldEntry e) { + super(e); + } + public void pack(Object target, Packer pac) throws IOException { + pac.pack((double)(Double)target); + } + public void convert(Object target, MessagePackObject obj) throws MessageTypeException, IllegalAccessException { + getField().setDouble(target, obj.asDouble()); + } + public void unpack(Object target, Unpacker pac) throws IOException, MessageTypeException, IllegalAccessException { + getField().setDouble(target, pac.unpackDouble()); + } + } + + static class ReflectionTemplate extends AbstractTemplate { + protected Class targetClass; + protected ReflectionFieldEntry[] entries; + protected int minimumArrayLength; + + ReflectionTemplate(Class targetClass, ReflectionFieldEntry[] entries) { + this.targetClass = targetClass; + this.entries = entries; + this.minimumArrayLength = 0; + for(int i=0; i < entries.length; i++) { + ReflectionFieldEntry e = entries[i]; + if(e.isRequired() || e.isNullable()) { + this.minimumArrayLength = i+1; + } + } + } + + public void pack(Packer pk, Object target) throws IOException { + try { + pk.packArray(entries.length); + for(ReflectionFieldEntry e : entries) { + if(!e.isAvailable()) { + pk.packNil(); + continue; + } + Object obj = e.getField().get(target); + if(obj == null) { + if(!e.isNullable() && !e.isOptional()) { + throw new MessageTypeException(); + } + pk.packNil(); + } else { + e.pack(obj, pk); + } + } + + } catch (MessageTypeException e) { + throw e; + } catch (IOException e) { + throw e; + } catch (Exception e) { + throw new MessageTypeException(e); + } + } + + public Object unpack(Unpacker pac, Object to) throws IOException, MessageTypeException { + try { + if(to == null) { + to = targetClass.newInstance(); + } + + int length = pac.unpackArray(); + if(length < minimumArrayLength) { + throw new MessageTypeException(); + } + + int i; + for(i=0; i < minimumArrayLength; i++) { + ReflectionFieldEntry e = entries[i]; + if(!e.isAvailable()) { + pac.unpackObject(); + continue; + } + + if(pac.tryUnpackNull()) { + if(e.isRequired()) { + // Required + nil => exception + throw new MessageTypeException(); + } else if(e.isOptional()) { + // Optional + nil => keep default value + } else { // Nullable + // Nullable + nil => set null + e.setNull(to); + } + } else { + e.unpack(to, pac); + } + } + + int max = length < entries.length ? length : entries.length; + for(; i < max; i++) { + ReflectionFieldEntry e = entries[i]; + if(!e.isAvailable()) { + pac.unpackObject(); + continue; + } + + if(pac.tryUnpackNull()) { + // this is Optional field becaue i >= minimumArrayLength + // Optional + nil => keep default value + } else { + e.unpack(to, pac); + } + } + + // latter entries are all Optional + nil => keep default value + + for(; i < length; i++) { + pac.unpackObject(); + } + + return to; + + } catch (MessageTypeException e) { + throw e; + } catch (IOException e) { + throw e; + } catch (Exception e) { + throw new MessageTypeException(e); + } + } + + public Object convert(MessagePackObject from, Object to) throws MessageTypeException { + try { + if(to == null) { + to = targetClass.newInstance(); + } + + MessagePackObject[] array = from.asArray(); + int length = array.length; + if(length < minimumArrayLength) { + throw new MessageTypeException(); + } + + int i; + for(i=0; i < minimumArrayLength; i++) { + ReflectionFieldEntry e = entries[i]; + if(!e.isAvailable()) { + continue; + } + + MessagePackObject obj = array[i]; + if(obj.isNil()) { + if(e.isRequired()) { + // Required + nil => exception + throw new MessageTypeException(); + } else if(e.isOptional()) { + // Optional + nil => keep default value + } else { // Nullable + // Nullable + nil => set null + e.setNull(to); + } + } else { + e.convert(to, obj); + } + } + + int max = length < entries.length ? length : entries.length; + for(; i < max; i++) { + ReflectionFieldEntry e = entries[i]; + if(!e.isAvailable()) { + continue; + } + + MessagePackObject obj = array[i]; + if(obj.isNil()) { + // this is Optional field becaue i >= minimumArrayLength + // Optional + nil => keep default value + } else { + e.convert(to, obj); + } + } + + // latter entries are all Optional + nil => keep default value + + return to; + + } catch (MessageTypeException e) { + throw e; + } catch (Exception e) { + throw new MessageTypeException(e); + } + } + } + + public Template buildTemplate(Class targetClass, FieldEntry[] entries) { + for(FieldEntry e : entries) { + Field f = e.getField(); + int mod = f.getModifiers(); + if(!Modifier.isPublic(mod)) { + f.setAccessible(true); + } + } + + ReflectionFieldEntry[] res = new ReflectionFieldEntry[entries.length]; + for(int i=0; i < entries.length; i++) { + FieldEntry e = entries[i]; + Class type = e.getType(); + if(!e.isAvailable()) { + res[i] = new NullFieldEntry(e); + } else if(type.equals(boolean.class)) { + res[i] = new BooleanFieldEntry(e); + } else if(type.equals(byte.class)) { + res[i] = new ByteFieldEntry(e); + } else if(type.equals(short.class)) { + res[i] = new ShortFieldEntry(e); + } else if(type.equals(int.class)) { + res[i] = new IntFieldEntry(e); + } else if(type.equals(long.class)) { + res[i] = new LongFieldEntry(e); + } else if(type.equals(float.class)) { + res[i] = new FloatFieldEntry(e); + } else if(type.equals(double.class)) { + res[i] = new DoubleFieldEntry(e); + } else { + Template tmpl = TemplateRegistry.lookup(e.getGenericType(), true); + res[i] = new ObjectFieldEntry(e, tmpl); + } + } + + return new ReflectionTemplate(targetClass, res); + } + + static class ReflectionOrdinalEnumTemplate extends AbstractTemplate { + protected Enum[] entries; + protected Map, Integer> reverse; + + ReflectionOrdinalEnumTemplate(Enum[] entries) { + this.entries = entries; + this.reverse = new HashMap, Integer>(); + for(int i=0; i < entries.length; i++) { + this.reverse.put(entries[i], i); + } + } + + public void pack(Packer pk, Object target) throws IOException { + Integer ord = reverse.get(target); + if(ord == null) { + throw new MessageTypeException(); + } + pk.pack((int)ord); + } + + public Object unpack(Unpacker pac, Object to) throws IOException, MessageTypeException { + int ord = pac.unpackInt(); + if(entries.length <= ord) { + throw new MessageTypeException(); + } + return entries[ord]; + } + + public Object convert(MessagePackObject from, Object to) throws MessageTypeException { + int ord = from.asInt(); + if(entries.length <= ord) { + throw new MessageTypeException(); + } + return entries[ord]; + } + } + + 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/ShortArrayTemplate.java b/java/src/main/java/org/msgpack/template/ShortArrayTemplate.java new file mode 100644 index 0000000..2beb61b --- /dev/null +++ b/java/src/main/java/org/msgpack/template/ShortArrayTemplate.java @@ -0,0 +1,80 @@ +// +// 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.io.IOException; +import org.msgpack.*; + +public class ShortArrayTemplate implements Template { + private ShortArrayTemplate() { } + + public void pack(Packer pk, Object target) throws IOException { + if(!(target instanceof short[])) { + throw new MessageTypeException(); + } + short[] array = (short[])target; + try { + pk.packArray(array.length); + } catch (NullPointerException e) { + throw new MessageTypeException("target is null.", e); + } + for(short a : array) { + pk.pack(a); + } + } + + public Object unpack(Unpacker pac, Object to) throws IOException, MessageTypeException { + int length = pac.unpackArray(); + short[] array; + if(to != null && to instanceof short[] && ((short[])to).length == length) { + array = (short[])to; + } else { + array = new short[length]; + } + for(int i=0; i < length; i++) { + array[i] = pac.unpackShort(); + } + return array; + } + + public Object convert(MessagePackObject from, Object to) throws MessageTypeException { + MessagePackObject[] src = from.asArray(); + short[] array; + if(to != null && to instanceof short[] && ((short[])to).length == src.length) { + array = (short[])to; + } else { + array = new short[src.length]; + } + for(int i=0; i < src.length; i++) { + MessagePackObject s = src[i]; + array[i] = s.asShort(); + } + return array; + } + + static public ShortArrayTemplate getInstance() { + return instance; + } + + static final ShortArrayTemplate instance = new ShortArrayTemplate(); + + static { + TemplateRegistry.register(short[].class, instance); + } +} + diff --git a/java/src/main/java/org/msgpack/template/ShortTemplate.java b/java/src/main/java/org/msgpack/template/ShortTemplate.java index 10ac43b..9daba10 100644 --- a/java/src/main/java/org/msgpack/template/ShortTemplate.java +++ b/java/src/main/java/org/msgpack/template/ShortTemplate.java @@ -24,14 +24,18 @@ public class ShortTemplate implements Template { private ShortTemplate() { } public void pack(Packer pk, Object target) throws IOException { - pk.packShort((Short)target); + try { + pk.packShort((Short)target); + } catch (NullPointerException e) { + throw new MessageTypeException("target is null.", e); + } } - public Object unpack(Unpacker pac) throws IOException, MessageTypeException { + public Object unpack(Unpacker pac, Object to) throws IOException, MessageTypeException { return pac.unpackShort(); } - public Object convert(MessagePackObject from) throws MessageTypeException { + public Object convert(MessagePackObject from, Object to) throws MessageTypeException { return from.asShort(); } @@ -42,7 +46,8 @@ public class ShortTemplate implements Template { static final ShortTemplate instance = new ShortTemplate(); static { - CustomMessage.register(Short.class, instance); + TemplateRegistry.register(Short.class, instance); + TemplateRegistry.register(short.class, instance); } } diff --git a/java/src/main/java/org/msgpack/template/StringTemplate.java b/java/src/main/java/org/msgpack/template/StringTemplate.java index dd31d9e..0cb6381 100644 --- a/java/src/main/java/org/msgpack/template/StringTemplate.java +++ b/java/src/main/java/org/msgpack/template/StringTemplate.java @@ -24,14 +24,18 @@ public class StringTemplate implements Template { private StringTemplate() { } public void pack(Packer pk, Object target) throws IOException { - pk.packString((String)target); + try { + pk.packString((String)target); + } catch (NullPointerException e) { + throw new MessageTypeException("target is null.", e); + } } - public Object unpack(Unpacker pac) throws IOException, MessageTypeException { + public Object unpack(Unpacker pac, Object to) throws IOException, MessageTypeException { return pac.unpackString(); } - public Object convert(MessagePackObject from) throws MessageTypeException { + public Object convert(MessagePackObject from, Object to) throws MessageTypeException { return from.asString(); } @@ -42,7 +46,7 @@ public class StringTemplate implements Template { static final StringTemplate instance = new StringTemplate(); static { - CustomMessage.register(String.class, instance); + TemplateRegistry.register(String.class, instance); } } diff --git a/java/src/main/java/org/msgpack/util/codegen/DynamicCodeGenException.java b/java/src/main/java/org/msgpack/template/TemplateBuildException.java similarity index 73% rename from java/src/main/java/org/msgpack/util/codegen/DynamicCodeGenException.java rename to java/src/main/java/org/msgpack/template/TemplateBuildException.java index d4a2906..c4c9956 100644 --- a/java/src/main/java/org/msgpack/util/codegen/DynamicCodeGenException.java +++ b/java/src/main/java/org/msgpack/template/TemplateBuildException.java @@ -15,16 +15,21 @@ // See the License for the specific language governing permissions and // limitations under the License. // -package org.msgpack.util.codegen; +package org.msgpack.template; @SuppressWarnings("serial") -public class DynamicCodeGenException extends RuntimeException { +public class TemplateBuildException extends RuntimeException { - public DynamicCodeGenException(String reason) { + public TemplateBuildException(String reason) { super(reason); } - public DynamicCodeGenException(String reason, Throwable t) { + public TemplateBuildException(String reason, Throwable t) { super(reason, t); } + + public TemplateBuildException(Throwable t) { + super(t); + } } + diff --git a/java/src/main/java/org/msgpack/template/TemplateBuilder.java b/java/src/main/java/org/msgpack/template/TemplateBuilder.java new file mode 100644 index 0000000..e3d25b2 --- /dev/null +++ b/java/src/main/java/org/msgpack/template/TemplateBuilder.java @@ -0,0 +1,381 @@ +// +// 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.io.IOException; +import java.lang.reflect.*; +import java.lang.annotation.*; +import java.util.List; +import java.util.ArrayList; +import java.util.EnumSet; +import org.msgpack.*; +import org.msgpack.annotation.*; + +public abstract class TemplateBuilder { + public static class FieldEntry { + private Field field; + private FieldOption option; + + public FieldEntry() { + this.field = null; + this.option = FieldOption.IGNORE; + } + + public FieldEntry(FieldEntry e) { + this.field = e.field; + this.option = e.option; + } + + public FieldEntry(Field field, FieldOption option) { + this.field = field; + this.option = option; + } + + public Field getField() { + return field; + } + + public String getName() { + return field.getName(); + } + + public Class getType() { + return field.getType(); + } + + public String getJavaTypeName() { + Class type = field.getType(); + if(type.isArray()) { + return arrayTypeToString(type); + } else { + return type.getName(); + } + } + + public Type getGenericType() { + return field.getGenericType(); + } + + public FieldOption getOption() { + return option; + } + + public boolean isAvailable() { + return option != FieldOption.IGNORE; + } + + public boolean isRequired() { + return option == FieldOption.REQUIRED; + } + + public boolean isOptional() { + return option == FieldOption.OPTIONAL; + } + + public boolean isNullable() { + return option == FieldOption.NULLABLE; + } + + static String arrayTypeToString(Class type) { + int dim = 1; + Class baseType = type.getComponentType(); + while(baseType.isArray()) { + baseType = baseType.getComponentType(); + dim += 1; + } + StringBuilder sb = new StringBuilder(); + sb.append(baseType.getName()); + for (int i = 0; i < dim; ++i) { + sb.append("[]"); + } + return sb.toString(); + } + } + + // Override this method + public abstract Template buildTemplate(Class targetClass, FieldEntry[] entries); + + // 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); + return buildTemplate(targetClass, convertFieldEntries(targetClass, flist)); + } + + public Template buildTemplate(Class targetClass, FieldOption implicitOption) { + checkValidation(targetClass); + return buildTemplate(targetClass, readFieldEntries(targetClass, implicitOption)); + } + + public Template buildTemplate(Class targetClass) { + FieldOption implicitOption = readImplicitFieldOption(targetClass); + return buildTemplate(targetClass, implicitOption); + } + + public Template buildOrdinalEnumTemplate(Class targetClass) { + checkOrdinalEnumValidation(targetClass); + Enum[] entries = (Enum[])targetClass.getEnumConstants(); + 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; + } + if(baseType instanceof ParameterizedType) { + baseClass = (Class)((ParameterizedType)baseType).getRawType(); + } else { + baseClass = (Class)baseType; + } + } 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 { + instance = selectDefaultTemplateBuilder(); + } + + private static TemplateBuilder selectDefaultTemplateBuilder() { + try { + // FIXME JavassistTemplateBuilder doesn't work on DalvikVM + if(System.getProperty("java.vm.name").equals("Dalvik")) { + return ReflectionTemplateBuilder.getInstance(); + } + } catch (Exception e) { + } + return JavassistTemplateBuilder.getInstance(); + } + + synchronized static void setInstance(TemplateBuilder builder) { + instance = builder; + } + + public static Template build(Class targetClass) { + return instance.buildTemplate(targetClass); + } + + public static Template build(Class targetClass, FieldOption implicitOption) { + return instance.buildTemplate(targetClass, implicitOption); + } + + public static Template build(Class targetClass, FieldList flist) throws NoSuchFieldException { + return instance.buildTemplate(targetClass, flist); + } + + public static Template buildOrdinalEnum(Class targetClass) { + return instance.buildOrdinalEnumTemplate(targetClass); + } + + public static Template buildArray(Type arrayType) { + return instance.buildArrayTemplate(arrayType); + } + + + private static void checkValidation(Class targetClass) { + if(targetClass.isInterface()) { + throw new TemplateBuildException("cannot build template of interface"); + } + if(targetClass.isArray()) { + throw new TemplateBuildException("cannot build template of array class"); + } + if(targetClass.isPrimitive()) { + throw new TemplateBuildException("cannot build template of primitive type"); + } + } + + private static void checkOrdinalEnumValidation(Class targetClass) { + if(!targetClass.isEnum()) { + throw new TemplateBuildException("tried to build ordinal enum template of non-enum class"); + } + } + + + static FieldEntry[] convertFieldEntries(Class targetClass, FieldList flist) throws NoSuchFieldException { + List src = flist.getList(); + FieldEntry[] result = new FieldEntry[src.size()]; + for(int i=0; i < src.size(); i++) { + FieldList.Entry s = src.get(i); + if(s.isAvailable()) { + result[i] = new FieldEntry(targetClass.getDeclaredField(s.getName()), s.getOption()); + } else { + result[i] = new FieldEntry(); + } + } + return result; + } + + static FieldEntry[] readFieldEntries(Class targetClass, FieldOption implicitOption) { + Field[] allFields = readAllFields(targetClass); + + /* index: + * @Index(0) int field_a; // 0 + * int field_b; // 1 + * @Index(3) int field_c; // 3 + * int field_d; // 4 + * @Index(2) int field_e; // 2 + * int field_f; // 5 + */ + List indexed = new ArrayList(); + int maxIndex = -1; + for(Field f : allFields) { + FieldOption opt = readFieldOption(f, implicitOption); + if(opt == FieldOption.IGNORE) { + // skip + continue; + } + + int index = readFieldIndex(f, maxIndex); + + if(indexed.size() > index && indexed.get(index) != null) { + throw new TemplateBuildException("duplicated index: "+index); + } + if(index < 0) { + throw new TemplateBuildException("invalid index: "+index); + } + + while(indexed.size() <= index) { + indexed.add(null); + } + indexed.set(index, new FieldEntry(f, opt)); + + if(maxIndex < index) { + maxIndex = index; + } + } + + FieldEntry[] result = new FieldEntry[maxIndex+1]; + for(int i=0; i < indexed.size(); i++) { + FieldEntry e = indexed.get(i); + if(e == null) { + result[i] = new FieldEntry(); + } else { + result[i] = e; + } + } + + return result; + } + + private static Field[] readAllFields(Class targetClass) { + // order: [fields of super class, ..., fields of this class] + List succ = new ArrayList(); + int total = 0; + for(Class c = targetClass; c != Object.class; c = c.getSuperclass()) { + Field[] fields = c.getDeclaredFields(); + total += fields.length; + succ.add(fields); + } + Field[] result = new Field[total]; + int off = 0; + for(int i=succ.size()-1; i >= 0; i--) { + Field[] fields = succ.get(i); + System.arraycopy(fields, 0, result, off, fields.length); + off += fields.length; + } + return result; + } + + private static FieldOption readImplicitFieldOption(Class targetClass) { + MessagePackMessage a = targetClass.getAnnotation(MessagePackMessage.class); + if(a == null) { + return FieldOption.DEFAULT; + } + return a.value(); + } + + private static FieldOption readFieldOption(Field field, FieldOption implicitOption) { + int mod = field.getModifiers(); + if(Modifier.isStatic(mod) || Modifier.isFinal(mod)) { + return FieldOption.IGNORE; + } + + if(isAnnotated(field, Ignore.class)) { + return FieldOption.IGNORE; + } else if(isAnnotated(field, Required.class)) { + return FieldOption.REQUIRED; + } else if(isAnnotated(field, Optional.class)) { + return FieldOption.OPTIONAL; + } else if(isAnnotated(field, Nullable.class)) { + if(field.getDeclaringClass().isPrimitive()) { + return FieldOption.REQUIRED; + } else { + return FieldOption.NULLABLE; + } + } + + if(implicitOption != FieldOption.DEFAULT) { + return implicitOption; + } + + // default mode: + // transient : Ignore + // public : Required + // others : Ignore + if(Modifier.isTransient(mod)) { + return FieldOption.IGNORE; + } else if(Modifier.isPublic(mod)) { + return FieldOption.REQUIRED; + } else { + return FieldOption.IGNORE; + } + } + + private static int readFieldIndex(Field field, int maxIndex) { + Index a = field.getAnnotation(Index.class); + if(a == null) { + return maxIndex + 1; + } else { + return a.value(); + } + } + + private static boolean isAnnotated(AccessibleObject ao, Class with) { + return ao.getAnnotation(with) != null; + } +} + diff --git a/java/src/main/java/org/msgpack/template/TemplateRegistry.java b/java/src/main/java/org/msgpack/template/TemplateRegistry.java new file mode 100644 index 0000000..3f98fb4 --- /dev/null +++ b/java/src/main/java/org/msgpack/template/TemplateRegistry.java @@ -0,0 +1,205 @@ +// +// 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.Map; +import java.util.HashMap; +import java.lang.reflect.Type; +import java.lang.reflect.GenericArrayType; +import java.lang.reflect.ParameterizedType; +import java.lang.annotation.Annotation; +import org.msgpack.annotation.MessagePackMessage; +import org.msgpack.annotation.MessagePackDelegate; +import org.msgpack.annotation.MessagePackOrdinalEnum; +import org.msgpack.Template; +import org.msgpack.Templates; + +public class TemplateRegistry { + private static Map map; + private static Map genericMap; + + static { + map = new HashMap(); + genericMap = new HashMap(); + BuiltInTemplateLoader.load(); + } + + public static void register(Class target) { // auto-detect + if(target.isEnum()) { + register(target, TemplateBuilder.buildOrdinalEnum(target)); + } else { + register(target, TemplateBuilder.build(target)); + } + } + + public static void register(Class target, FieldOption implicitOption) { + register(target, TemplateBuilder.build(target, implicitOption)); + } + + public static void register(Class target, FieldList flist) throws NoSuchFieldException { + register(target, TemplateBuilder.build(target, flist)); + } + + public static synchronized void register(Type rawType, Template tmpl) { + if(rawType instanceof ParameterizedType) { + rawType = ((ParameterizedType)rawType).getRawType(); + } + map.put(rawType, tmpl); + } + + public static synchronized void registerGeneric(Type rawType, GenericTemplate gtmpl) { + if(rawType instanceof ParameterizedType) { + rawType = ((ParameterizedType)rawType).getRawType(); + } + genericMap.put(rawType, gtmpl); + } + + public static synchronized Template lookup(Type targetType) { + return lookupImpl(targetType, false, true); + } + + public static synchronized Template lookup(Type targetType, boolean forceBuild) { + return lookupImpl(targetType, forceBuild, true); + } + + public static synchronized Template tryLookup(Type targetType) { + return lookupImpl(targetType, false, false); + } + + public static synchronized Template tryLookup(Type targetType, boolean forceBuild) { + return lookupImpl(targetType, forceBuild, false); + } + + private static synchronized Template lookupImpl(Type targetType, boolean forceBuild, boolean fallbackDefault) { + Template tmpl; + + if(targetType instanceof ParameterizedType) { + // ParameterizedType is not a Class? + tmpl = lookupGenericImpl((ParameterizedType)targetType); + if(tmpl != null) { + return tmpl; + } + targetType = ((ParameterizedType)targetType).getRawType(); + } + + tmpl = map.get(targetType); + if(tmpl != null) { + 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); + register(target, tmpl); + return tmpl; + } else if(isAnnotated(target, MessagePackDelegate.class)) { + // TODO DelegateTemplate + throw new UnsupportedOperationException("not supported yet. : " + target.getName()); + } else if(isAnnotated(target, MessagePackOrdinalEnum.class)) { + tmpl = TemplateBuilder.buildOrdinalEnum(target); + register(target, tmpl); + return tmpl; + } + + for(Class i : target.getInterfaces()) { + tmpl = map.get(i); + if(tmpl != null) { + register(target, tmpl); + return tmpl; + } + } + + Class c = target.getSuperclass(); + if(c != null) { + for(; c != Object.class; c = c.getSuperclass()) { + tmpl = map.get(c); + if(tmpl != null) { + register(target, tmpl); + return tmpl; + } + } + + if(forceBuild) { + tmpl = TemplateBuilder.build(target); + register(target, tmpl); + return tmpl; + } + } + + if(fallbackDefault) { + tmpl = new DefaultTemplate((Class)target); + register(target, tmpl); + return tmpl; + } else { + return null; + } + } + + public static synchronized Template lookupGeneric(Type targetType) { + if(targetType instanceof ParameterizedType) { + ParameterizedType parameterizedType = (ParameterizedType)targetType; + Template tmpl = lookupGenericImpl(parameterizedType); + if(tmpl != null) { + return tmpl; + } + return new DefaultTemplate((Class)parameterizedType.getRawType(), parameterizedType); + } else { + throw new IllegalArgumentException("actual types of the generic type are erased: "+targetType); + } + } + + private static synchronized Template lookupGenericImpl(ParameterizedType type) { + Type rawType = type.getRawType(); + GenericTemplate gtmpl = genericMap.get(rawType); + if(gtmpl == null) { + return null; + } + + Type[] types = type.getActualTypeArguments(); + Template[] tmpls = new Template[types.length]; + for(int i=0; i < types.length; i++) { + tmpls[i] = lookup(types[i]); + } + + return gtmpl.build(tmpls); + } + + private static boolean isAnnotated(Class ao, Class with) { + return ao.getAnnotation(with) != null; + } + + public static void setTemplateBuilder(TemplateBuilder builder) { + TemplateBuilder.setInstance(builder); + } +} + diff --git a/java/src/main/java/org/msgpack/type/Raw.java b/java/src/main/java/org/msgpack/type/Raw.java new file mode 100644 index 0000000..cdd0c22 --- /dev/null +++ b/java/src/main/java/org/msgpack/type/Raw.java @@ -0,0 +1,69 @@ +// +// 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.type; + +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.nio.ByteBuffer; +import org.msgpack.*; + +public final class Raw { + private byte[] bytes; + private String string; + + public Raw(byte[] bytes) { + this.bytes = bytes; + this.string = null; + } + + public Raw(String string) { + this.bytes = null; + this.string = string; + } + + public String toString() { + if(string == null) { + try { + string = new String(bytes, "UTF-8"); + } catch (UnsupportedEncodingException e) { + throw new RuntimeException(e); + } + } + return string; + } + + public byte[] toByteArray() { + if(bytes == null) { + try { + bytes = string.getBytes("UTF-8"); + } catch (UnsupportedEncodingException e) { + throw new RuntimeException(e); + } + } + return bytes; + } + + public ByteBuffer toByteBuffer() { + return ByteBuffer.wrap(toByteArray()); + } + + static { + RawTemplate.load(); + } +} + diff --git a/java/src/main/java/org/msgpack/packer/BigIntegerPacker.java b/java/src/main/java/org/msgpack/type/RawTemplate.java similarity index 56% rename from java/src/main/java/org/msgpack/packer/BigIntegerPacker.java rename to java/src/main/java/org/msgpack/type/RawTemplate.java index 7d4c0a6..85fb5e4 100644 --- a/java/src/main/java/org/msgpack/packer/BigIntegerPacker.java +++ b/java/src/main/java/org/msgpack/type/RawTemplate.java @@ -15,27 +15,37 @@ // See the License for the specific language governing permissions and // limitations under the License. // -package org.msgpack.packer; +package org.msgpack.type; import java.io.IOException; -import java.math.BigInteger; import org.msgpack.*; +import org.msgpack.template.TemplateRegistry; -public class BigIntegerPacker implements MessagePacker { - private BigIntegerPacker() { } +public class RawTemplate implements Template { + static void load() { } + + private RawTemplate() { } public void pack(Packer pk, Object target) throws IOException { - pk.packBigInteger((BigInteger)target); + pk.packByteArray(((Raw)target).toByteArray()); } - static public BigIntegerPacker getInstance() { + public Object unpack(Unpacker pac, Object to) throws IOException, MessageTypeException { + return new Raw(pac.unpackByteArray()); + } + + public Object convert(MessagePackObject from, Object to) throws MessageTypeException { + return new Raw(from.asByteArray()); + } + + static public RawTemplate getInstance() { return instance; } - static final BigIntegerPacker instance = new BigIntegerPacker(); + static final RawTemplate instance = new RawTemplate(); static { - CustomMessage.registerPacker(BigInteger.class, instance); + TemplateRegistry.register(Raw.class, instance); } } diff --git a/java/src/main/java/org/msgpack/util/codegen/Constants.java b/java/src/main/java/org/msgpack/util/codegen/Constants.java deleted file mode 100644 index fc6650f..0000000 --- a/java/src/main/java/org/msgpack/util/codegen/Constants.java +++ /dev/null @@ -1,102 +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.util.codegen; - -public interface Constants { - String POSTFIX_TYPE_NAME_PACKER = "_$$_Packer"; - - String POSTFIX_TYPE_NAME_UNPACKER = "_$$_Unpacker"; - - String POSTFIX_TYPE_NAME_CONVERTER = "_$$_Converter"; - - String POSTFIX_TYPE_NAME_TEMPLATE = "_$$_Template"; - - String STRING_NAME_COMMA_SPACE = ", "; - - String STRING_NAME_LEFT_RIGHT_SQUARE_BRACKET = "[]"; - - String CHAR_NAME_SPACE = " "; - - String CHAR_NAME_RIGHT_CURLY_BRACKET = "}"; - - String CHAR_NAME_LEFT_CURLY_BRACKET = "{"; - - String VARIABLE_NAME_TEMPLATES = "_$$_templates"; - - String VARIABLE_NAME_PACKERS = "_$$_packers"; - - String VARIABLE_NAME_CLIENT = "_$$_client"; - - String METHOD_NAME_BOOLEANVALUE = "booleanValue"; - - String METHOD_NAME_BYTEVALUE = "byteValue"; - - String METHOD_NAME_SHORTVALUE = "shortValue"; - - String METHOD_NAME_INTVALUE = "intValue"; - - String METHOD_NAME_FLOATVALUE = "floatValue"; - - String METHOD_NAME_LONGVALUE = "longValue"; - - String METHOD_NAME_DOUBLEVALUE = "doubleValue"; - - String METHOD_NAME_GETENUMCONSTANTS = "getEnumConstants"; - - String METHOD_NAME_CONVERT = "convert"; - - String METHOD_NAME_SETTEMPLATES = "setTemplates"; - - String METHOD_NAME_SETMESSAGEPACKERS = "setMessagePackers"; - - String METHOD_NAME_PACK = "pack"; - - String METHOD_NAME_UNPACK = "unpack"; - - String STATEMENT_PACKER_PACKERMETHODBODY_01 = "%s _$$_t = (%s)$2; "; - - String STATEMENT_PACKER_PACKERMETHODBODY_02 = "$1.packArray(%d); "; - - String STATEMENT_PACKER_PACKERMETHODBODY_03 = "_$$_templates[%d].pack($1, %s_$$_t.%s%s); "; - - String STATEMENT_PACKER_PACKERMETHODBODY_04 = "$1.pack(((java.lang.Enum)_$$_t).ordinal()); "; - - String STATEMENT_TMPL_UNPACKERMETHODBODY_01 = "%s _$$_t = new %s(); "; - - String STATEMENT_TMPL_UNPACKERMETHODBODY_02 = "int _$$_L = $1.unpackArray(); "; - - String STATEMENT_TMPL_UNPACKERMETHODBODY_03 = "_$$_t.%s = %s(%s)_$$_templates[%d].unpack($1)%s; "; - - String STATEMENT_TMPL_UNPACKERMETHODBODY_04 = "return _$$_t; "; - - String STATEMENT_TMPL_UNPACKERMETHODBODY_05 = "int i = $1.unpackInt(); "; - - String STATEMENT_TMPL_UNPACKERMETHODBODY_06 = "return %s.class.getEnumConstants()[i]; "; - - String STATEMENT_TMPL_UNPACKERMETHODBODY_07 = "if(_$$_L <= %d) { throw new org.msgpack.MessageTypeException(); } "; - - String STATEMENT_TMPL_UNPACKERMETHODBODY_08 = "if(_$$_L > %d && !$1.tryUnpackNull()) "; - - String STATEMENT_TMPL_UNPACKERMETHODBODY_09 = "for(int _$$_n = %d; _$$_n < _$$_L; _$$_n++) { $1.unpackObject(); } "; - - String STATEMENT_TMPL_CONVERTMETHODBODY_01 = "%s _$$_ary = $1.asArray(); "; - - String STATEMENT_TMPL_CONVERTMETHODBODY_02 = "_$$_t.%s = %s(%s)_$$_templates[%d].convert(_$$_ary[%d])%s; "; - - String STATEMENT_TMPL_CONVERTMETHODBODY_03 = "int i = _$$_ary[0].asInt(); "; -} diff --git a/java/src/main/java/org/msgpack/util/codegen/DynamicCodeGen.java b/java/src/main/java/org/msgpack/util/codegen/DynamicCodeGen.java deleted file mode 100644 index edd23d8..0000000 --- a/java/src/main/java/org/msgpack/util/codegen/DynamicCodeGen.java +++ /dev/null @@ -1,567 +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.util.codegen; - -import java.io.IOException; -import java.lang.annotation.Annotation; -import java.lang.reflect.Constructor; -import java.lang.reflect.Field; -import java.lang.reflect.Modifier; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -import javassist.CannotCompileException; -import javassist.CtClass; -import javassist.CtMethod; -import javassist.CtNewMethod; -import javassist.NotFoundException; - -import org.msgpack.MessagePackObject; -import org.msgpack.MessageTypeException; -import org.msgpack.Packer; -import org.msgpack.Template; -import org.msgpack.Unpacker; -import org.msgpack.annotation.MessagePackOptional; -import org.msgpack.template.OptionalTemplate; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -class DynamicCodeGen extends DynamicCodeGenBase implements Constants { - - private static Logger LOG = LoggerFactory.getLogger(DynamicCodeGen.class); - - private static DynamicCodeGen INSTANCE; - - public static DynamicCodeGen getInstance() { - if (INSTANCE == null) { - LOG.info("create an instance of the type: " - + DynamicCodeGen.class.getName()); - INSTANCE = new DynamicCodeGen(); - } - return INSTANCE; - } - - private ConcurrentHashMap tmplCache; - - DynamicCodeGen() { - super(); - tmplCache = new ConcurrentHashMap(); - } - - public void setTemplates(Class type, Template[] tmpls) { - tmplCache.put(type.getName(), tmpls); - } - - public Template[] getTemplates(Class type) { - return tmplCache.get(type.getName()); - } - - public Class generateTemplateClass(Class origClass, - List fieldOpts) { - try { - LOG.debug("start generating a template class for " - + origClass.getName()); - String origName = origClass.getName(); - String tmplName = origName + POSTFIX_TYPE_NAME_TEMPLATE + inc(); - checkTypeValidation(origClass); - checkDefaultConstructorValidation(origClass); - CtClass tmplCtClass = pool.makeClass(tmplName); - setSuperclass(tmplCtClass, TemplateAccessorImpl.class); - setInterface(tmplCtClass, Template.class); - addClassTypeConstructor(tmplCtClass); - Field[] fields = getDeclaredFields(origClass); - Template[] tmpls = null; - if (fieldOpts != null) { - fields = sortFields(fields, fieldOpts); - tmpls = createTemplates(fieldOpts); - } else { - tmpls = createTemplates(fields); - } - setTemplates(origClass, tmpls); - addPackMethod(tmplCtClass, origClass, fields, false); - addUnpackMethod(tmplCtClass, origClass, fields, false); - addConvertMethod(tmplCtClass, origClass, fields, false); - Class tmplClass = createClass(tmplCtClass); - LOG.debug("generated a template class for " + origClass.getName()); - return tmplClass; - } catch (NotFoundException e) { - DynamicCodeGenException ex = new DynamicCodeGenException(e.getMessage(), e); - LOG.error(ex.getMessage(), ex); - throw ex; - } catch (CannotCompileException e) { - DynamicCodeGenException ex = new DynamicCodeGenException(e.getMessage(), e); - LOG.error(ex.getMessage(), ex); - throw ex; - } - } - - public Class generateOrdinalEnumTemplateClass(Class origClass) { - try { - LOG.debug("start generating a enum template class for " - + origClass.getName()); - String origName = origClass.getName(); - checkTypeValidation(origClass); - String tmplName = origName + POSTFIX_TYPE_NAME_TEMPLATE + inc(); - CtClass tmplCtClass = pool.makeClass(tmplName); - setSuperclass(tmplCtClass, TemplateAccessorImpl.class); - setInterface(tmplCtClass, Template.class); - addClassTypeConstructor(tmplCtClass); - addPackMethod(tmplCtClass, origClass, null, true); - addUnpackMethod(tmplCtClass, origClass, null, true); - addConvertMethod(tmplCtClass, origClass, null, true); - Class tmplClass = createClass(tmplCtClass); - LOG.debug("generated an enum template class for " - + origClass.getName()); - return tmplClass; - } catch (NotFoundException e) { - DynamicCodeGenException ex = new DynamicCodeGenException(e - .getMessage(), e); - LOG.error(ex.getMessage(), ex); - throw ex; - } catch (CannotCompileException e) { - DynamicCodeGenException ex = new DynamicCodeGenException(e - .getMessage(), e); - LOG.error(ex.getMessage(), ex); - throw ex; - } - } - - @Override - public void checkTypeValidation(Class origClass) { - // not public, abstract - int mod = origClass.getModifiers(); - if ((!Modifier.isPublic(mod)) || Modifier.isAbstract(mod)) { - throwTypeValidationException(origClass, - "a class must have a public modifier"); - } - // interface - if (origClass.isInterface()) { - throwTypeValidationException(origClass, - "cannot generate packer and unpacker for an interface"); - } - } - - @Override - public void checkDefaultConstructorValidation(Class origClass) { - // check that the zero-argument constructor exists - Constructor cons = null; - try { - cons = origClass.getDeclaredConstructor(new Class[0]); - } catch (Exception e) { - throwConstructorValidationException(origClass); - } - - // check the modifiers - int mod = cons.getModifiers(); - if (!Modifier.isPublic(mod)) { - throwConstructorValidationException(origClass); - } - } - - Field[] getDeclaredFields(Class origClass) { - ArrayList allFields = new ArrayList(); - Class nextClass = origClass; - while (nextClass != Object.class) { - Field[] fields = nextClass.getDeclaredFields(); - for (Field field : fields) { - try { - checkFieldValidation(field, allFields); - allFields.add(field); - } catch (DynamicCodeGenException e) { // ignore - LOG.trace(e.getMessage(), e); - } - } - nextClass = nextClass.getSuperclass(); - } - return allFields.toArray(new Field[0]); - } - - void checkFieldValidation(Field field, List fields) { - // check that it has a public modifier - int mod = field.getModifiers(); - if ((!(Modifier.isPublic(mod))) || Modifier.isStatic(mod) - || Modifier.isFinal(mod) || Modifier.isTransient(mod) - || field.isSynthetic()) { - throwFieldValidationException(field); - } - // check same name - for (Field f : fields) { - if (f.getName().equals(field.getName())) { - throwFieldValidationException(field); - } - } - } - - Field[] sortFields(Field[] fields, List fieldOpts) { - if (fields.length != fieldOpts.size()) { - throwFieldSortingException(String.format( - "Mismatch: public field num: %d, option num: %d", - new Object[] { fields.length, fieldOpts.size() })); - } - Field[] sorted = new Field[fields.length]; - for (int i = 0; i < sorted.length; ++i) { - FieldOption opt = fieldOpts.get(i); - Field match = null; - for (Field f : fields) { - if (opt.name.equals(f.getName())) { - match = f; - break; - } - } - if (match != null) { - sorted[i] = match; - } else { - throwFieldSortingException(String.format( - "Mismatch: a %s field option is not declared", - new Object[] { opt.name })); - } - } - return sorted; - } - - Template[] createTemplates(List fieldOpts) { - Template[] tmpls = new Template[fieldOpts.size()]; - for (int i = 0; i < tmpls.length; ++i) { - tmpls[i] = fieldOpts.get(i).tmpl; - } - return tmpls; - } - - Template[] createTemplates(Field[] fields) { - Template[] tmpls = new Template[fields.length]; - for (int i = 0; i < tmpls.length; ++i) { - tmpls[i] = createTemplate(fields[i]); - } - return tmpls; - } - - Template createTemplate(Field field) { - boolean isOptional = isAnnotated(field, MessagePackOptional.class); - Class c = field.getType(); - Template tmpl = null; - if (List.class.isAssignableFrom(c) || Map.class.isAssignableFrom(c)) { - tmpl = createTemplate(field.getGenericType()); - } else { - tmpl = createTemplate(c); - } - if (isOptional) { - // for pack - return new OptionalTemplate(tmpl); - } else { - return tmpl; - } - } - - private boolean isAnnotated(Field field, Class with) { - return field.getAnnotation(with) != null; - } - - private void addPackMethod(CtClass packerCtClass, Class c, - Field[] fields, boolean isEnum) { - // void pack(Packer pk, Object target) throws IOException; - StringBuilder sb = new StringBuilder(); - if (!isEnum) { - insertPackMethodBody(sb, c, fields); - } else { - insertOrdinalEnumPackMethodBody(sb, c); - } - try { - LOG.trace("pack method src: " + sb.toString()); - int mod = javassist.Modifier.PUBLIC; - CtClass returnType = classToCtClass(void.class); - String mname = METHOD_NAME_PACK; - CtClass[] paramTypes = new CtClass[] { - classToCtClass(Packer.class), classToCtClass(Object.class) }; - CtClass[] exceptTypes = new CtClass[] { classToCtClass(IOException.class) }; - CtMethod newCtMethod = CtNewMethod.make(mod, returnType, mname, - paramTypes, exceptTypes, sb.toString(), packerCtClass); - packerCtClass.addMethod(newCtMethod); - } catch (CannotCompileException e) { - DynamicCodeGenException ex = new DynamicCodeGenException(e - .getMessage() - + ": " + sb.toString(), e); - LOG.error(ex.getMessage(), ex); - throw ex; - } catch (NotFoundException e) { - DynamicCodeGenException ex = new DynamicCodeGenException(e - .getMessage() - + ": " + sb.toString(), e); - LOG.error(ex.getMessage(), ex); - throw ex; - } - } - - private void insertPackMethodBody(StringBuilder sb, Class type, - Field[] fields) { - // void pack(Packer packer, Object target) throws IOException; - sb.append(CHAR_NAME_LEFT_CURLY_BRACKET); - sb.append(CHAR_NAME_SPACE); - String typeName = classToString(type); - Object[] args0 = new Object[] { typeName, typeName }; - sb.append(String.format(STATEMENT_PACKER_PACKERMETHODBODY_01, args0)); - Object[] args1 = new Object[] { fields.length }; - sb.append(String.format(STATEMENT_PACKER_PACKERMETHODBODY_02, args1)); - for (int i = 0; i < fields.length; ++i) { - insertCodeOfPackMethodCall(sb, fields[i], i); - } - sb.append(CHAR_NAME_RIGHT_CURLY_BRACKET); - } - - private void insertCodeOfPackMethodCall(StringBuilder sb, Field field, int i) { - // _$$_packers[i].pack($1, new Integer(target.fi)); - Class type = field.getType(); - boolean isPrim = type.isPrimitive(); - Object[] args = new Object[] { - i, - isPrim ? "new " + getPrimToWrapperType(type).getName() + "(" - : "", field.getName(), isPrim ? ")" : "" }; - sb.append(String.format(STATEMENT_PACKER_PACKERMETHODBODY_03, args)); - } - - private void insertOrdinalEnumPackMethodBody(StringBuilder sb, Class c) { - // void pack(Packer packer, Object target) throws IOException; - sb.append(CHAR_NAME_LEFT_CURLY_BRACKET); - sb.append(CHAR_NAME_SPACE); - String typeName = classToString(c); - Object[] args0 = new Object[] { typeName, typeName }; - sb.append(String.format(STATEMENT_PACKER_PACKERMETHODBODY_01, args0)); - Object[] args1 = new Object[] { 1 }; - sb.append(String.format(STATEMENT_PACKER_PACKERMETHODBODY_02, args1)); - Object[] args2 = new Object[0]; - sb.append(String.format(STATEMENT_PACKER_PACKERMETHODBODY_04, args2)); - sb.append(CHAR_NAME_RIGHT_CURLY_BRACKET); - } - - private void addUnpackMethod(CtClass tmplCtClass, Class type, - Field[] fields, boolean isEnum) { - // Object unpack(Unpacker u) throws IOException, MessageTypeException; - StringBuilder sb = new StringBuilder(); - if (!isEnum) { - insertUnpackMethodBody(sb, type, fields); - } else { - insertOrdinalEnumUnpackMethodBody(sb, type); - } - try { - LOG.trace("unpack method src: " + sb.toString()); - int mod = javassist.Modifier.PUBLIC; - CtClass returnType = classToCtClass(Object.class); - String mname = METHOD_NAME_UNPACK; - CtClass[] paramTypes = new CtClass[] { classToCtClass(Unpacker.class) }; - CtClass[] exceptTypes = new CtClass[] { - classToCtClass(IOException.class), - classToCtClass(MessageTypeException.class) }; - CtMethod newCtMethod = CtNewMethod.make(mod, returnType, mname, - paramTypes, exceptTypes, sb.toString(), tmplCtClass); - tmplCtClass.addMethod(newCtMethod); - } catch (CannotCompileException e) { - DynamicCodeGenException ex = new DynamicCodeGenException(e - .getMessage() - + ": " + sb.toString(), e); - LOG.error(ex.getMessage(), ex); - throw ex; - } catch (NotFoundException e) { - DynamicCodeGenException ex = new DynamicCodeGenException(e - .getMessage() - + ": " + sb.toString(), e); - LOG.error(ex.getMessage(), ex); - throw ex; - } - } - - private void insertUnpackMethodBody(StringBuilder sb, Class type, - Field[] fields) { - // Object unpack(Unpacker u) throws IOException, MessageTypeException; - sb.append(CHAR_NAME_LEFT_CURLY_BRACKET); - sb.append(CHAR_NAME_SPACE); - // Foo _$$_t = new Foo(); - String typeName = classToString(type); - Object[] args0 = new Object[] { typeName, typeName }; - sb.append(String.format(STATEMENT_TMPL_UNPACKERMETHODBODY_01, args0)); - // int _$$_L = $1.unpackArray(); - Object[] args1 = new Object[0]; - sb.append(String.format(STATEMENT_TMPL_UNPACKERMETHODBODY_02, args1)); - insertCodeOfUnpackMethodCalls(sb, fields); - // return _$$_t; - Object[] args2 = new Object[0]; - sb.append(String.format(STATEMENT_TMPL_UNPACKERMETHODBODY_04, args2)); - sb.append(CHAR_NAME_RIGHT_CURLY_BRACKET); - } - - private void insertCodeOfUnpackMethodCalls(StringBuilder sb, Field[] fields) { - for (int i = 0; i < fields.length; ++i) { - insertCodeOfUnpackMethodCall(sb, fields[i], i); - } - insertCodeOfUnpackTrails(sb, fields.length); - } - - private void insertCodeOfUnpackMethodCall(StringBuilder sb, Field field, - int i) { - boolean isOptional = isAnnotated(field, MessagePackOptional.class); - - if(isOptional) { - // if(_$$_L > i && !$1.tryUnpackNull()) { - Object[] args0 = new Object[] { i }; - sb.append(String.format(STATEMENT_TMPL_UNPACKERMETHODBODY_08, args0)); - sb.append(CHAR_NAME_LEFT_CURLY_BRACKET); - - } else { - // if(_$$_L <= i) { - // throw new MessageTypeException(); - // } - Object[] args0 = new Object[] { i }; - sb.append(String.format(STATEMENT_TMPL_UNPACKERMETHODBODY_07, args0)); - } - - // target.fi = ((Integer)_$$_tmpls[i].unpack(_$$_pk)).intValue(); - Class returnType = field.getType(); - boolean isPrim = returnType.isPrimitive(); - Object[] args = new Object[] { - field.getName(), - isPrim ? "(" : "", - isPrim ? getPrimToWrapperType(returnType).getName() - : classToString(returnType), - i, - isPrim ? ")." + getPrimTypeValueMethodName(returnType) + "()" - : "" }; - sb.append(String.format(STATEMENT_TMPL_UNPACKERMETHODBODY_03, args)); - - if(isOptional) { - // } - sb.append(CHAR_NAME_RIGHT_CURLY_BRACKET); - } - } - - private void insertCodeOfUnpackTrails(StringBuilder sb, int length) { - // for(int _$$_n = length; _$$_n < _$$_L; _$$_n++) { - // $1.unpackObject(); - // } - Object[] args0 = new Object[] { length }; - sb.append(String.format(STATEMENT_TMPL_UNPACKERMETHODBODY_09, args0)); - } - - private void insertOrdinalEnumUnpackMethodBody(StringBuilder sb, - Class type) { - // Object unpack(Unpacker u) throws IOException, MessageTypeException; - sb.append(CHAR_NAME_LEFT_CURLY_BRACKET); - sb.append(CHAR_NAME_SPACE); - // $1.unpackArray(); - Object[] args0 = new Object[0]; - sb.append(String.format(STATEMENT_TMPL_UNPACKERMETHODBODY_02, args0)); - // int i = $1.unapckInt(); - Object[] args1 = new Object[0]; - sb.append(String.format(STATEMENT_TMPL_UNPACKERMETHODBODY_05, args1)); - // return Foo.class.getEnumConstants()[i]; - Object[] args2 = new Object[] { classToString(type) }; - sb.append(String.format(STATEMENT_TMPL_UNPACKERMETHODBODY_06, args2)); - sb.append(CHAR_NAME_RIGHT_CURLY_BRACKET); - } - - public void addConvertMethod(CtClass tmplCtClass, Class type, - Field[] fields, boolean isEnum) { - // Object convert(MessagePackObject mpo) throws MessageTypeException; - StringBuilder sb = new StringBuilder(); - if (!isEnum) { - insertConvertMethodBody(sb, type, fields); - } else { - insertOrdinalEnumConvertMethodBody(sb, type); - } - try { - LOG.trace("convert method src: " + sb.toString()); - int mod = javassist.Modifier.PUBLIC; - CtClass returnType = classToCtClass(Object.class); - String mname = METHOD_NAME_CONVERT; - CtClass[] paramTypes = new CtClass[] { classToCtClass(MessagePackObject.class) }; - CtClass[] exceptTypes = new CtClass[] { classToCtClass(MessageTypeException.class) }; - CtMethod newCtMethod = CtNewMethod.make(mod, returnType, mname, - paramTypes, exceptTypes, sb.toString(), tmplCtClass); - tmplCtClass.addMethod(newCtMethod); - } catch (CannotCompileException e) { - DynamicCodeGenException ex = new DynamicCodeGenException(e - .getMessage() - + ": " + sb.toString(), e); - LOG.error(ex.getMessage(), ex); - throw ex; - } catch (NotFoundException e) { - DynamicCodeGenException ex = new DynamicCodeGenException(e - .getMessage() - + ": " + sb.toString(), e); - LOG.error(ex.getMessage(), ex); - throw ex; - } - } - - private void insertConvertMethodBody(StringBuilder sb, Class type, - Field[] fields) { - // Object convert(MessagePackObject mpo) throws MessageTypeException; - sb.append(CHAR_NAME_LEFT_CURLY_BRACKET); - sb.append(CHAR_NAME_SPACE); - // Foo _$$_t = new Foo(); - String typeName = classToString(type); - Object[] args0 = new Object[] { typeName, typeName }; - sb.append(String.format(STATEMENT_TMPL_UNPACKERMETHODBODY_01, args0)); - // MessagePackObject[] _$$_ary = $1.asArray(); - Object[] args1 = new Object[] { classToString(MessagePackObject[].class) }; - sb.append(String.format(STATEMENT_TMPL_CONVERTMETHODBODY_01, args1)); - insertCodeOfConvertMethodCalls(sb, fields); - // return _$$_t; - Object[] args2 = new Object[0]; - sb.append(String.format(STATEMENT_TMPL_UNPACKERMETHODBODY_04, args2)); - sb.append(CHAR_NAME_RIGHT_CURLY_BRACKET); - } - - private void insertCodeOfConvertMethodCalls(StringBuilder sb, Field[] fields) { - for (int i = 0; i < fields.length; ++i) { - insertCodeOfConvMethodCall(sb, fields[i], i); - } - } - - private void insertCodeOfConvMethodCall(StringBuilder sb, Field field, int i) { - // target.fi = ((Object)_$$_tmpls[i].convert(_$$_ary[i])).intValue(); - Class returnType = field.getType(); - boolean isPrim = returnType.isPrimitive(); - Object[] args = new Object[] { - field.getName(), - isPrim ? "(" : "", - isPrim ? getPrimToWrapperType(returnType).getName() - : classToString(returnType), - i, - i, - isPrim ? ")." + getPrimTypeValueMethodName(returnType) + "()" - : "" }; - sb.append(String.format(STATEMENT_TMPL_CONVERTMETHODBODY_02, args)); - } - - private void insertOrdinalEnumConvertMethodBody(StringBuilder sb, - Class type) { - // Object convert(MessagePackObject mpo) throws MessageTypeException; - sb.append(CHAR_NAME_LEFT_CURLY_BRACKET); - sb.append(CHAR_NAME_SPACE); - // MessagePackObject[] _$$_ary = $1.asArray(); - Object[] args0 = new Object[] { classToString(MessagePackObject[].class) }; - sb.append(String.format(STATEMENT_TMPL_CONVERTMETHODBODY_01, args0)); - // int i = _$$_ary[0].asInt(); - Object[] args1 = new Object[0]; - sb.append(String.format(STATEMENT_TMPL_CONVERTMETHODBODY_03, args1)); - // return Foo.class.getEnumConstants()[i]; - Object[] args2 = new Object[] { classToString(type) }; - sb.append(String.format(STATEMENT_TMPL_UNPACKERMETHODBODY_06, args2)); - sb.append(CHAR_NAME_RIGHT_CURLY_BRACKET); - } -} diff --git a/java/src/main/java/org/msgpack/util/codegen/DynamicCodeGenBase.java b/java/src/main/java/org/msgpack/util/codegen/DynamicCodeGenBase.java deleted file mode 100644 index 2d2711a..0000000 --- a/java/src/main/java/org/msgpack/util/codegen/DynamicCodeGenBase.java +++ /dev/null @@ -1,444 +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.util.codegen; - -import java.io.IOException; -import java.lang.reflect.Field; -import java.lang.reflect.GenericArrayType; -import java.lang.reflect.Method; -import java.lang.reflect.ParameterizedType; -import java.lang.reflect.Type; -import java.math.BigInteger; -import java.util.List; -import java.util.Map; -import java.util.concurrent.atomic.AtomicInteger; - -import javassist.CannotCompileException; -import javassist.ClassPool; -import javassist.CtClass; -import javassist.CtConstructor; -import javassist.CtField; -import javassist.CtMethod; -import javassist.CtNewConstructor; -import javassist.CtNewMethod; -import javassist.NotFoundException; - -import org.msgpack.CustomConverter; -import org.msgpack.CustomMessage; -import org.msgpack.MessageConvertable; -import org.msgpack.MessagePackObject; -import org.msgpack.MessagePackable; -import org.msgpack.MessageTypeException; -import org.msgpack.MessageUnpackable; -import org.msgpack.Packer; -import org.msgpack.Template; -import org.msgpack.Templates; -import org.msgpack.Unpacker; -import org.msgpack.annotation.MessagePackDelegate; -import org.msgpack.annotation.MessagePackMessage; -import org.msgpack.annotation.MessagePackOrdinalEnum; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class DynamicCodeGenBase implements Constants { - - private static Logger LOG = LoggerFactory - .getLogger(DynamicCodeGenBase.class); - - static class MessagePackUnpackConvertableTemplate implements Template { - private Class type; - - MessagePackUnpackConvertableTemplate(Class type) { - this.type = type; - } - - @Override - public void pack(Packer packer, Object target) throws IOException { - MessagePackable mp = MessagePackable.class.cast(target); - mp.messagePack(packer); - } - - @Override - public Object unpack(Unpacker unpacker) throws IOException, - MessageTypeException { - try { - MessageUnpackable obj = (MessageUnpackable) type.newInstance(); - obj.messageUnpack(unpacker); - return obj; - } catch (ClassCastException e) { - throw new MessageTypeException(e.getMessage(), e); - } catch (InstantiationException e) { - throw new MessageTypeException(e.getMessage(), e); - } catch (IllegalAccessException e) { - throw new MessageTypeException(e.getMessage(), e); - } - } - - @Override - public Object convert(MessagePackObject from) - throws MessageTypeException { - try { - MessageConvertable obj = (MessageConvertable) type - .newInstance(); - obj.messageConvert(from); - return obj; - } catch (ClassCastException e) { - throw new MessageTypeException(e.getMessage(), e); - } catch (InstantiationException e) { - throw new MessageTypeException(e.getMessage(), e); - } catch (IllegalAccessException e) { - throw new MessageTypeException(e.getMessage(), e); - } - } - } - - public static interface TemplateAccessor { - void setTemplates(Template[] templates); - } - - protected static class TemplateAccessorImpl implements TemplateAccessor { - public Class type; - - public Template[] _$$_templates; - - public TemplateAccessorImpl() { - } - - public TemplateAccessorImpl(Class type) { - this.type = type; - } - - public void setTemplates(Template[] _$$_tmpls) { - _$$_templates = _$$_tmpls; - } - } - - private static AtomicInteger COUNTER = new AtomicInteger(0); - - protected static int inc() { - return COUNTER.addAndGet(1); - } - - protected ClassPool pool; - - protected DynamicCodeGenBase() { - pool = ClassPool.getDefault(); - } - - protected void checkTypeValidation(Class type) { - DynamicCodeGenException e = new DynamicCodeGenException(String.format( - "Fatal error: %s", new Object[] { type.getName() })); - LOG.error(e.getMessage(), e); - throw e; - } - - protected void throwTypeValidationException(Class type, String message) - throws DynamicCodeGenException { - DynamicCodeGenException e = new DynamicCodeGenException(String.format( - "%s: %s", new Object[] { message, type.getName() })); - LOG.error(e.getMessage(), e); - throw e; - } - - protected void checkDefaultConstructorValidation(Class type) { - DynamicCodeGenException e = new DynamicCodeGenException(String.format( - "Fatal error: %s", new Object[] { type.getName() })); - LOG.error(e.getMessage(), e); - throw e; - } - - protected void throwConstructorValidationException(Class origClass) { - DynamicCodeGenException e = new DynamicCodeGenException(String.format( - "it must have a public zero-argument constructor: %s", - new Object[] { origClass.getName() })); - LOG.error(e.getMessage(), e); - throw e; - } - - protected void throwFieldValidationException(Field field) { - DynamicCodeGenException e = new DynamicCodeGenException(String.format( - "it must be a public field: %s", - new Object[] { field.getName() })); - LOG.debug(e.getMessage(), e); - throw e; - } - - protected void throwFieldSortingException(String message) { - DynamicCodeGenException e = new DynamicCodeGenException(message); - LOG.debug(e.getMessage(), e); - throw e; - } - - protected static void throwMethodValidationException(Method method, - String message) throws DynamicCodeGenException { - DynamicCodeGenException e = new DynamicCodeGenException(String.format( - "%s: %s", new Object[] { message, method.getName() })); - LOG.error(e.getMessage(), e); - throw e; - } - - protected CtClass makeClass(String name) throws NotFoundException { - DynamicCodeGenException e = new DynamicCodeGenException(String.format( - "Fatal error: %s", new Object[] { name })); - LOG.error(e.getMessage(), e); - throw e; - } - - protected void setSuperclass(CtClass newCtClass, Class superClass) - throws NotFoundException, CannotCompileException { - // check the specified super class - if (superClass.isInterface() || superClass.isEnum() - || superClass.isAnnotation() || superClass.isArray() - || superClass.isPrimitive()) { - throwTypeValidationException(superClass, "Fatal error"); - } - - // check the base class - if (!newCtClass.getSuperclass().equals(classToCtClass(Object.class))) { - throwTypeValidationException(superClass, "Fatal error"); - } - CtClass superCtClass = pool.get(superClass.getName()); - newCtClass.setSuperclass(superCtClass); - } - - protected void setInterface(CtClass newCtClass, Class infClass) - throws NotFoundException { - CtClass infCtClass = pool.get(infClass.getName()); - newCtClass.addInterface(infCtClass); - } - - protected void addClassTypeConstructor(CtClass newCtClass) - throws CannotCompileException, NotFoundException { - CtConstructor newCtCons = CtNewConstructor.make(new CtClass[] { pool - .get(Class.class.getName()) }, new CtClass[0], newCtClass); - newCtClass.addConstructor(newCtCons); - } - - protected void addDefaultConstructor(CtClass newCtClass) - throws CannotCompileException { - CtConstructor newCtCons = CtNewConstructor - .defaultConstructor(newCtClass); - newCtClass.addConstructor(newCtCons); - } - - protected void addTemplateArrayField(CtClass newCtClass) - throws NotFoundException, CannotCompileException { - CtClass acsCtClass = pool.get(TemplateAccessorImpl.class.getName()); - CtField tmplsField = acsCtClass - .getDeclaredField(VARIABLE_NAME_TEMPLATES); - CtField tmplsField2 = new CtField(tmplsField.getType(), tmplsField - .getName(), newCtClass); - newCtClass.addField(tmplsField2); - } - - protected void addSetTemplatesMethod(CtClass newCtClass) - throws NotFoundException, CannotCompileException { - CtClass acsCtClass = pool.get(TemplateAccessorImpl.class.getName()); - CtMethod settmplsMethod = acsCtClass - .getDeclaredMethod(METHOD_NAME_SETTEMPLATES); - CtMethod settmplsMethod2 = CtNewMethod.copy(settmplsMethod, newCtClass, - null); - newCtClass.addMethod(settmplsMethod2); - } - - protected Class getPrimToWrapperType(Class type) { - if (type.equals(boolean.class)) { - return Boolean.class; - } else if (type.equals(byte.class)) { - return Byte.class; - } else if (type.equals(short.class)) { - return Short.class; - } else if (type.equals(int.class)) { - return Integer.class; - } else if (type.equals(long.class)) { - return Long.class; - } else if (type.equals(float.class)) { - return Float.class; - } else if (type.equals(double.class)) { - return Double.class; - } else { - throw new MessageTypeException("Type error: " + type.getName()); - } - } - - public static String getPrimTypeValueMethodName(Class type) { - if (type.equals(boolean.class)) { - return METHOD_NAME_BOOLEANVALUE; - } else if (type.equals(byte.class)) { - return METHOD_NAME_BYTEVALUE; - } else if (type.equals(short.class)) { - return METHOD_NAME_SHORTVALUE; - } else if (type.equals(int.class)) { - return METHOD_NAME_INTVALUE; - } else if (type.equals(long.class)) { - return METHOD_NAME_LONGVALUE; - } else if (type.equals(float.class)) { - return METHOD_NAME_FLOATVALUE; - } else if (type.equals(double.class)) { - return METHOD_NAME_DOUBLEVALUE; - } else { - throw new MessageTypeException("Type error: " + type.getName()); - } - } - - public static Template createTemplate(Type t) { - if (t.getClass().equals(Class.class)) { - Class c = (Class) t; - if (c.equals(boolean.class) || c.equals(Boolean.class)) { - return Templates.tBoolean(); - } else if (c.equals(byte.class) || c.equals(Byte.class)) { - return Templates.tByte(); - } else if (c.equals(short.class) || c.equals(Short.class)) { - return Templates.tShort(); - } else if (c.equals(int.class) || c.equals(Integer.class)) { - return Templates.tInteger(); - } else if (c.equals(float.class) || c.equals(Float.class)) { - return Templates.tFloat(); - } else if (c.equals(long.class) || c.equals(Long.class)) { - return Templates.tLong(); - } else if (c.equals(double.class) || c.equals(Double.class)) { - return Templates.tDouble(); - } else if (c.equals(String.class)) { - return Templates.tString(); - } else if (c.equals(BigInteger.class)) { - return Templates.tBigInteger(); - } else if (CustomConverter.isRegistered(c)) {// FIXME - return (Template) CustomConverter.get(c); - } else if (CustomMessage.isAnnotated(c, MessagePackMessage.class)) { - // @MessagePackMessage - Template tmpl = DynamicTemplate.create(c); - CustomMessage.register(c, tmpl); - return tmpl; - } else if (CustomMessage.isAnnotated(c, MessagePackDelegate.class)) { - // FIXME DelegatePacker - UnsupportedOperationException e = new UnsupportedOperationException( - "not supported yet. : " + c.getName()); - LOG.error(e.getMessage(), e); - throw e; - } else if (CustomMessage.isAnnotated(c, MessagePackOrdinalEnum.class)) { - // @MessagePackOrdinalEnum - Template tmpl = DynamicOrdinalEnumTemplate.create(c); - CustomMessage.register(c, tmpl); - return tmpl; - } else if (MessagePackable.class.isAssignableFrom(c) - || MessageConvertable.class.isAssignableFrom(c) - || MessageUnpackable.class.isAssignableFrom(c)) { - Template tmpl = new MessagePackUnpackConvertableTemplate(c); - CustomMessage.register(c, tmpl); - return tmpl; - } else { - throw new MessageTypeException("Type error: " + ((Class) t).getName()); - } - } else if (t instanceof GenericArrayType) { - GenericArrayType gat = (GenericArrayType) t; - Type gct = gat.getGenericComponentType(); - if (gct.equals(byte.class)) { - return Templates.tByteArray(); - } else { - throw new DynamicCodeGenException("Not supported yet: " + gat); - } - } else if (t instanceof ParameterizedType) { - ParameterizedType pt = (ParameterizedType) t; - Class rawType = (Class) pt.getRawType(); - if (rawType.equals(List.class)) { - Type[] ats = pt.getActualTypeArguments(); - return Templates.tList(createTemplate(ats[0])); - } else if (rawType.equals(Map.class)) { - Type[] ats = pt.getActualTypeArguments(); - return Templates.tMap(createTemplate(ats[0]), - createTemplate(ats[1])); - } else { - throw new DynamicCodeGenException("Type error: " - + t.getClass().getName()); - } - } else { - throw new DynamicCodeGenException("Type error: " - + t.getClass().getName()); - } - } - - static int getArrayDim(Class type) { - if (type.isArray()) { - return 1 + getArrayDim(type.getComponentType()); - } else { - return 0; - } - } - - static Class getArrayBaseType(Class type) { - if (type.isArray()) { - return getArrayBaseType(type.getComponentType()); - } else { - return type; - } - } - - static String arrayTypeToString(Class type) { - StringBuilder sb = new StringBuilder(); - int dim = getArrayDim(type); - Class t = getArrayBaseType(type); - sb.append(t.getName()); - for (int i = 0; i < dim; ++i) { - sb.append(STRING_NAME_LEFT_RIGHT_SQUARE_BRACKET); - } - return sb.toString(); - } - - protected static String classToString(Class type) { - if (type.isArray()) { - return arrayTypeToString(type); - } else { - return type.getName(); - } - } - - protected CtClass classToCtClass(Class type) throws NotFoundException { - if (type.equals(void.class)) { - return CtClass.voidType; - } else if (type.isPrimitive()) { - if (type.equals(boolean.class)) { - return CtClass.booleanType; - } else if (type.equals(byte.class)) { - return CtClass.byteType; - } else if (type.equals(char.class)) { - return CtClass.charType; - } else if (type.equals(short.class)) { - return CtClass.shortType; - } else if (type.equals(int.class)) { - return CtClass.intType; - } else if (type.equals(long.class)) { - return CtClass.longType; - } else if (type.equals(float.class)) { - return CtClass.floatType; - } else if (type.equals(double.class)) { - return CtClass.doubleType; - } else { - throw new MessageTypeException("Fatal error: " + type.getName()); - } - } else if (type.isArray()) { - return pool.get(arrayTypeToString(type)); - } else { - return pool.get(type.getName()); - } - } - - protected static Class createClass(CtClass newCtClass) - throws CannotCompileException { - return newCtClass.toClass(null, null); - } -} diff --git a/java/src/main/java/org/msgpack/util/codegen/DynamicConverter.java b/java/src/main/java/org/msgpack/util/codegen/DynamicConverter.java deleted file mode 100644 index 346de2d..0000000 --- a/java/src/main/java/org/msgpack/util/codegen/DynamicConverter.java +++ /dev/null @@ -1,33 +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.util.codegen; - -import java.util.List; - -import org.msgpack.MessageConverter; - -public class DynamicConverter { - public static MessageConverter create(Class c) { - return create(c, null); - } - - public static MessageConverter create(Class c, - List fieldOpts) { - return DynamicTemplate.create(c, fieldOpts); - } -} diff --git a/java/src/main/java/org/msgpack/util/codegen/DynamicPacker.java b/java/src/main/java/org/msgpack/util/codegen/DynamicPacker.java deleted file mode 100644 index 5796b71..0000000 --- a/java/src/main/java/org/msgpack/util/codegen/DynamicPacker.java +++ /dev/null @@ -1,33 +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.util.codegen; - -import java.util.List; - -import org.msgpack.MessagePacker; - -public class DynamicPacker { - - public static MessagePacker create(Class c) { - return create(c, null); - } - - public static MessagePacker create(Class c, List fieldOpts) { - return DynamicTemplate.create(c, fieldOpts); - } -} diff --git a/java/src/main/java/org/msgpack/util/codegen/DynamicTemplate.java b/java/src/main/java/org/msgpack/util/codegen/DynamicTemplate.java deleted file mode 100644 index 9bd6aef..0000000 --- a/java/src/main/java/org/msgpack/util/codegen/DynamicTemplate.java +++ /dev/null @@ -1,55 +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.util.codegen; - -import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationTargetException; -import java.util.List; - -import org.msgpack.Template; -import org.msgpack.util.codegen.DynamicCodeGenBase.TemplateAccessor; - -public class DynamicTemplate { - public static Template create(Class c) { - return create(c, null); - } - - public static Template create(Class c, List fieldOpts) { - try { - DynamicCodeGen gen = DynamicCodeGen.getInstance(); - Class tmplClass = gen.generateTemplateClass(c, fieldOpts); - Constructor cons = tmplClass - .getDeclaredConstructor(new Class[] { Class.class }); - Object obj = cons.newInstance(new Object[] { c }); - ((TemplateAccessor) obj).setTemplates(gen.getTemplates(c)); - return (Template) obj; - } catch (InstantiationException e) { - throw new DynamicCodeGenException(e.getMessage(), e); - } catch (IllegalAccessException e) { - throw new DynamicCodeGenException(e.getMessage(), e); - } catch (SecurityException e) { - throw new DynamicCodeGenException(e.getMessage(), e); - } catch (NoSuchMethodException e) { - throw new DynamicCodeGenException(e.getMessage(), e); - } catch (IllegalArgumentException e) { - throw new DynamicCodeGenException(e.getMessage(), e); - } catch (InvocationTargetException e) { - throw new DynamicCodeGenException(e.getMessage(), e); - } - } -} diff --git a/java/src/main/java/org/msgpack/util/codegen/DynamicUnpacker.java b/java/src/main/java/org/msgpack/util/codegen/DynamicUnpacker.java deleted file mode 100644 index ea198f0..0000000 --- a/java/src/main/java/org/msgpack/util/codegen/DynamicUnpacker.java +++ /dev/null @@ -1,32 +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.util.codegen; - -import java.util.List; - -import org.msgpack.MessageUnpacker; - -public class DynamicUnpacker { - public static MessageUnpacker create(Class c) { - return create(c, null); - } - - public static MessageUnpacker create(Class c, List fieldOpts) { - return DynamicTemplate.create(c, fieldOpts); - } -} diff --git a/java/src/main/java/org/msgpack/util/codegen/FieldOption.java b/java/src/main/java/org/msgpack/util/codegen/FieldOption.java deleted file mode 100644 index 9fb3e3b..0000000 --- a/java/src/main/java/org/msgpack/util/codegen/FieldOption.java +++ /dev/null @@ -1,42 +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.util.codegen; - -import org.msgpack.Template; - -public class FieldOption { - - private static final String NULL_ERR_MSG = "param is FieldOption is null."; - - String name; - - Template tmpl; - - public FieldOption(final String name, final Template tmpl) { - if (name == null) { - throw new NullPointerException(String.format("%s %s", new Object[] { - "1st", NULL_ERR_MSG })); - } - if (tmpl == null) { - throw new NullPointerException(String.format("%s %s", new Object[] { - "2nd", NULL_ERR_MSG })); - } - this.name = name; - this.tmpl = tmpl; - } -} diff --git a/java/src/test/java/org/msgpack/TestAnnotations.java b/java/src/test/java/org/msgpack/TestAnnotations.java new file mode 100644 index 0000000..657ca28 --- /dev/null +++ b/java/src/test/java/org/msgpack/TestAnnotations.java @@ -0,0 +1,150 @@ +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 TestAnnotations extends TestCase { + + @MessagePackMessage + public static class MyClassVersion1 { + // required field, not nullable. + public String name; + + // required and nullable field. + @Nullable + public String nickname; + } + + + @MessagePackMessage + public static class MyClassVersion2 { + public String name; + + @Nullable + public String nickname; + + // adds an optional field on version 2. + @Optional + public int age = -1; + } + + + @MessagePackMessage + public static class MyClassVersion3 { + public String name; + + @Nullable + public String nickname; + + // adds required fields on version 3, then + // this class is NOT compatible with version 1. + public int age; + + // optional field is nullable. + @Optional + public String school; + } + + + @Test + public void testBackwardCompatibility() throws Exception { + MyClassVersion1 v1 = new MyClassVersion1(); + v1.name = "Sadayuki Furuhashi"; + v1.nickname = "frsyuki"; + + byte[] bytes = MessagePack.pack(v1); + + MyClassVersion2 v2 = MessagePack.unpack(bytes, MyClassVersion2.class); + + assertEquals(v1.name, v2.name); + assertEquals(v1.nickname, v2.nickname); + assertEquals(v2.age, -1); + } + + @Test + public void testForwardCompatibility() throws Exception { + MyClassVersion2 v2 = new MyClassVersion2(); + v2.name = "Sadayuki Furuhashi"; + v2.nickname = "frsyuki"; + v2.age = 23; + + byte[] bytes = MessagePack.pack(v2); + + MyClassVersion1 v1 = MessagePack.unpack(bytes, MyClassVersion1.class); + + assertEquals(v2.name, v1.name); + assertEquals(v2.nickname, v1.nickname); + } + + @Test + public void testNullFields01() throws Exception { + MyClassVersion1 src = new MyClassVersion1(); + src.name = "Sadayuki Furuhashi"; + src.nickname = null; + + byte[] bytes = MessagePack.pack(src); + + MyClassVersion1 dst = MessagePack.unpack(bytes, MyClassVersion1.class); + + assertEquals(dst.name, src.name); + assertEquals(dst.nickname, src.nickname); + } + + @Test + public void testNullFields02() throws Exception { + MyClassVersion1 src = new MyClassVersion1(); + src.name = null; + src.nickname = "frsyuki"; + + try { + byte[] bytes = MessagePack.pack(src); + } catch (Exception e) { + assertTrue(true); + return; + } + assertTrue(false); + } + + @Test + public void testNullFields03() throws Exception { + List src = new ArrayList(); + src.add(null); + src.add("frsyuki"); + + byte[] bytes = MessagePack.pack(src); + + try { + MyClassVersion1 dst = MessagePack.unpack(bytes, MyClassVersion1.class); + } catch (Exception e) { + assertTrue(true); + return; + } + assertTrue(false); + } + + @Test + public void testNullFields04() throws Exception { + MyClassVersion3 src = new MyClassVersion3(); + src.name = "Sadayuki Furuhashi"; + src.nickname = null; + src.age = 23; + src.school = null; + + byte[] bytes = MessagePack.pack(src); + + MyClassVersion3 dst = MessagePack.unpack(bytes, MyClassVersion3.class); + + assertEquals(dst.name, src.name); + assertEquals(dst.nickname, src.nickname); + } +} + 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 0000000..92bb44c --- /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]); + } + } + } + } +} + diff --git a/java/src/test/java/org/msgpack/TestEnums.java b/java/src/test/java/org/msgpack/TestEnums.java new file mode 100644 index 0000000..84a390c --- /dev/null +++ b/java/src/test/java/org/msgpack/TestEnums.java @@ -0,0 +1,113 @@ +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 TestEnums extends TestCase { + public static enum ProvidedEnum { + RED, + GREEN, + BLUE + } + + @MessagePackOrdinalEnum + public static enum UserDefinedEnum { + CYAN, + MAGENTA, + YELLOW + } + + @MessagePackOrdinalEnum + public static enum UserDefinedEnumVersion2 { + CYAN, + MAGENTA, + YELLOW, + KEY + } + + + { + // provided classes need registration + MessagePack.register(ProvidedEnum.class); + // annotated classes don't need registration + } + + @Test + public void testRegisteredEnum() { + byte[] rout = MessagePack.pack(ProvidedEnum.RED); + byte[] gout = MessagePack.pack(ProvidedEnum.GREEN); + byte[] bout = MessagePack.pack(ProvidedEnum.BLUE); + + ProvidedEnum r = MessagePack.unpack(rout, ProvidedEnum.class); + ProvidedEnum g = MessagePack.unpack(gout, ProvidedEnum.class); + ProvidedEnum b = MessagePack.unpack(bout, ProvidedEnum.class); + + assertEquals(r, ProvidedEnum.RED); + assertEquals(g, ProvidedEnum.GREEN); + assertEquals(b, ProvidedEnum.BLUE); + } + + @Test + public void testAnnotatedEnum() { + byte[] cout = MessagePack.pack(UserDefinedEnum.CYAN); + byte[] mout = MessagePack.pack(UserDefinedEnum.MAGENTA); + byte[] yout = MessagePack.pack(UserDefinedEnum.YELLOW); + + UserDefinedEnum c = MessagePack.unpack(cout, UserDefinedEnum.class); + UserDefinedEnum m = MessagePack.unpack(mout, UserDefinedEnum.class); + UserDefinedEnum y = MessagePack.unpack(yout, UserDefinedEnum.class); + + assertEquals(c, UserDefinedEnum.CYAN); + assertEquals(m, UserDefinedEnum.MAGENTA); + assertEquals(y, UserDefinedEnum.YELLOW); + } + + @Test + public void testBackwardCompatibility() { + byte[] cout = MessagePack.pack(UserDefinedEnum.CYAN); + byte[] mout = MessagePack.pack(UserDefinedEnum.MAGENTA); + byte[] yout = MessagePack.pack(UserDefinedEnum.YELLOW); + + UserDefinedEnumVersion2 c = MessagePack.unpack(cout, UserDefinedEnumVersion2.class); + UserDefinedEnumVersion2 m = MessagePack.unpack(mout, UserDefinedEnumVersion2.class); + UserDefinedEnumVersion2 y = MessagePack.unpack(yout, UserDefinedEnumVersion2.class); + + assertEquals(c, UserDefinedEnumVersion2.CYAN); + assertEquals(m, UserDefinedEnumVersion2.MAGENTA); + assertEquals(y, UserDefinedEnumVersion2.YELLOW); + } + + @Test + public void testForwardCompatibility() { + byte[] cout = MessagePack.pack(UserDefinedEnumVersion2.CYAN); + byte[] mout = MessagePack.pack(UserDefinedEnumVersion2.MAGENTA); + byte[] yout = MessagePack.pack(UserDefinedEnumVersion2.YELLOW); + byte[] kout = MessagePack.pack(UserDefinedEnumVersion2.KEY); + + UserDefinedEnum c = MessagePack.unpack(cout, UserDefinedEnum.class); + UserDefinedEnum m = MessagePack.unpack(mout, UserDefinedEnum.class); + UserDefinedEnum y = MessagePack.unpack(yout, UserDefinedEnum.class); + + assertEquals(c, UserDefinedEnum.CYAN); + assertEquals(m, UserDefinedEnum.MAGENTA); + assertEquals(y, UserDefinedEnum.YELLOW); + + try { + MessagePack.unpack(kout, UserDefinedEnum.class); + } catch (Exception e) { + assertTrue(true); + return; + } + assertTrue(false); + } +} + diff --git a/java/src/test/java/org/msgpack/TestMessagePackStaticMethods.java b/java/src/test/java/org/msgpack/TestMessagePackStaticMethods.java index f08176e..7503d0e 100644 --- a/java/src/test/java/org/msgpack/TestMessagePackStaticMethods.java +++ b/java/src/test/java/org/msgpack/TestMessagePackStaticMethods.java @@ -75,16 +75,14 @@ public class TestMessagePackStaticMethods extends TestCase { { Object aobj = MessagePack.unpack(a, TString); Object bobj = MessagePack.unpack(b, TInteger); - Object cobj_any = MessagePack.unpack(c, TAny); - Object cobj_obj = MessagePack.unpack(c, tOptional(TAny)); + Object cobj = MessagePack.unpack(c, tNullable(TAny)); Object dobj = MessagePack.unpack(d, tList(TString)); Object eobj = MessagePack.unpack(e, tClass(ProvidedClass.class)); Object fobj = MessagePack.unpack(f, tClass(UserDefinedClass.class)); assertEquals(aobj, "msgpack"); assertEquals(bobj, 1); - assertEquals(cobj_any, NilType.create()); - assertEquals(cobj_obj, null); + assertEquals(cobj, null); assertEquals(dobj, createStringList()); assertEquals(eobj, createProvidedClass()); assertEquals(fobj, createUserDefinedClass()); @@ -94,6 +92,7 @@ public class TestMessagePackStaticMethods extends TestCase { String aobj = MessagePack.unpack(a, String.class); Integer bobj = MessagePack.unpack(b, Integer.class); Object cobj = MessagePack.unpack(c, Object.class); + // Generics are not supported on unpack(Class klass) interface ProvidedClass eobj = MessagePack.unpack(e, ProvidedClass.class); UserDefinedClass fobj = MessagePack.unpack(f, UserDefinedClass.class); @@ -103,43 +102,50 @@ public class TestMessagePackStaticMethods extends TestCase { assertEquals(eobj, createProvidedClass()); assertEquals(fobj, createUserDefinedClass()); } + + { + ProvidedClass eobj = MessagePack.unpack(e, createProvidedClass()); + UserDefinedClass fobj = MessagePack.unpack(f, createUserDefinedClass()); + + assertEquals(eobj, createProvidedClass()); + assertEquals(fobj, createUserDefinedClass()); + } } @Test public void testCheckedPackToStream() throws Exception { ByteArrayOutputStream aout = new ByteArrayOutputStream(); - MessagePack.pack(aout, "msgpack"); ByteArrayOutputStream bout = new ByteArrayOutputStream(); - MessagePack.pack(bout, (Object)1); ByteArrayOutputStream cout = new ByteArrayOutputStream(); - MessagePack.pack(cout, (Object)null); ByteArrayOutputStream dout = new ByteArrayOutputStream(); - MessagePack.pack(dout, createStringList()); ByteArrayOutputStream eout = new ByteArrayOutputStream(); - MessagePack.pack(eout, createProvidedClass()); ByteArrayOutputStream fout = new ByteArrayOutputStream(); + + MessagePack.pack(aout, "msgpack"); + MessagePack.pack(bout, (Object)1); + MessagePack.pack(cout, (Object)null); + MessagePack.pack(dout, createStringList()); + MessagePack.pack(eout, createProvidedClass()); MessagePack.pack(fout, createUserDefinedClass()); { InputStream ain = new ByteArrayInputStream(aout.toByteArray()); - Object aobj = MessagePack.unpack(ain, TString); InputStream bin = new ByteArrayInputStream(bout.toByteArray()); - Object bobj = MessagePack.unpack(bin, TInteger); - InputStream cin_any = new ByteArrayInputStream(cout.toByteArray()); - Object cobj_any = MessagePack.unpack(cin_any, TAny); - InputStream cin_obj = new ByteArrayInputStream(cout.toByteArray()); - Object cobj_obj = MessagePack.unpack(cin_obj, tOptional(TAny)); + InputStream cin = new ByteArrayInputStream(cout.toByteArray()); InputStream din = new ByteArrayInputStream(dout.toByteArray()); - Object dobj = MessagePack.unpack(din, tList(TString)); InputStream ein = new ByteArrayInputStream(eout.toByteArray()); - Object eobj = MessagePack.unpack(ein, tClass(ProvidedClass.class)); InputStream fin = new ByteArrayInputStream(fout.toByteArray()); + + Object aobj = MessagePack.unpack(ain, TString); + Object bobj = MessagePack.unpack(bin, TInteger); + Object cobj = MessagePack.unpack(cin, tNullable(TAny)); + Object dobj = MessagePack.unpack(din, tList(TString)); + Object eobj = MessagePack.unpack(ein, tClass(ProvidedClass.class)); Object fobj = MessagePack.unpack(fin, tClass(UserDefinedClass.class)); assertEquals(aobj, "msgpack"); assertEquals(bobj, 1); - assertEquals(cobj_any, NilType.create()); - assertEquals(cobj_obj, null); + assertEquals(cobj, null); assertEquals(dobj, createStringList()); assertEquals(eobj, createProvidedClass()); assertEquals(fobj, createUserDefinedClass()); @@ -147,14 +153,17 @@ public class TestMessagePackStaticMethods extends TestCase { { InputStream ain = new ByteArrayInputStream(aout.toByteArray()); - String aobj = MessagePack.unpack(ain, String.class); InputStream bin = new ByteArrayInputStream(bout.toByteArray()); - Integer bobj = MessagePack.unpack(bin, Integer.class); InputStream cin = new ByteArrayInputStream(cout.toByteArray()); - Object cobj = MessagePack.unpack(cin, Object.class); InputStream ein = new ByteArrayInputStream(eout.toByteArray()); - ProvidedClass eobj = MessagePack.unpack(ein, ProvidedClass.class); + // InputStream fin = new ByteArrayInputStream(fout.toByteArray()); + + String aobj = MessagePack.unpack(ain, String.class); + Integer bobj = MessagePack.unpack(bin, Integer.class); + Object cobj = MessagePack.unpack(cin, Object.class); + // Generics are not supported on unpack(Class klass) interface + ProvidedClass eobj = MessagePack.unpack(ein, ProvidedClass.class); UserDefinedClass fobj = MessagePack.unpack(fin, UserDefinedClass.class); assertEquals(aobj, "msgpack"); @@ -163,6 +172,17 @@ public class TestMessagePackStaticMethods extends TestCase { assertEquals(eobj, createProvidedClass()); assertEquals(fobj, createUserDefinedClass()); } + + { + InputStream ein = new ByteArrayInputStream(eout.toByteArray()); + InputStream fin = new ByteArrayInputStream(fout.toByteArray()); + + ProvidedClass eobj = MessagePack.unpack(ein, createProvidedClass()); + UserDefinedClass fobj = MessagePack.unpack(fin, createUserDefinedClass()); + + assertEquals(eobj, createProvidedClass()); + assertEquals(fobj, createUserDefinedClass()); + } } @Test @@ -194,30 +214,32 @@ public class TestMessagePackStaticMethods extends TestCase { @Test public void testPackToStream() throws Exception { ByteArrayOutputStream aout = new ByteArrayOutputStream(); - MessagePack.pack(aout, "msgpack"); ByteArrayOutputStream bout = new ByteArrayOutputStream(); - MessagePack.pack(bout, (Object)1); ByteArrayOutputStream cout = new ByteArrayOutputStream(); - MessagePack.pack(cout, (Object)null); ByteArrayOutputStream dout = new ByteArrayOutputStream(); - MessagePack.pack(dout, createStringList()); ByteArrayOutputStream eout = new ByteArrayOutputStream(); - MessagePack.pack(eout, createProvidedClass()); ByteArrayOutputStream fout = new ByteArrayOutputStream(); + + MessagePack.pack(aout, "msgpack"); + MessagePack.pack(bout, (Object)1); + MessagePack.pack(cout, (Object)null); + MessagePack.pack(dout, createStringList()); + MessagePack.pack(eout, createProvidedClass()); MessagePack.pack(fout, createUserDefinedClass()); { InputStream ain = new ByteArrayInputStream(aout.toByteArray()); - MessagePackObject aobj = MessagePack.unpack(ain); InputStream bin = new ByteArrayInputStream(bout.toByteArray()); - MessagePackObject bobj = MessagePack.unpack(bin); InputStream cin = new ByteArrayInputStream(cout.toByteArray()); - MessagePackObject cobj = MessagePack.unpack(cin); InputStream din = new ByteArrayInputStream(dout.toByteArray()); - MessagePackObject dobj = MessagePack.unpack(din); InputStream ein = new ByteArrayInputStream(eout.toByteArray()); - MessagePackObject eobj = MessagePack.unpack(ein); InputStream fin = new ByteArrayInputStream(fout.toByteArray()); + + MessagePackObject aobj = MessagePack.unpack(ain); + MessagePackObject bobj = MessagePack.unpack(bin); + MessagePackObject cobj = MessagePack.unpack(cin); + MessagePackObject dobj = MessagePack.unpack(din); + MessagePackObject eobj = MessagePack.unpack(ein); MessagePackObject fobj = MessagePack.unpack(fin); assertEquals(aobj, RawType.create("msgpack")); diff --git a/java/src/test/java/org/msgpack/buffer/VectoredByteBufferTest.java b/java/src/test/java/org/msgpack/buffer/VectoredByteBufferTest.java new file mode 100644 index 0000000..5c9c822 --- /dev/null +++ b/java/src/test/java/org/msgpack/buffer/VectoredByteBufferTest.java @@ -0,0 +1,45 @@ +package org.msgpack.buffer; + +import org.msgpack.*; +import org.msgpack.object.*; +import java.io.*; +import java.util.*; +import java.util.concurrent.*; +import java.net.*; +import junit.framework.*; +import org.junit.Test; + +public class VectoredByteBufferTest extends TestCase { + public VectoredByteBufferTest() { + } + + @Test + public void testIO() throws Exception { + VectoredByteBuffer v = new VectoredByteBuffer(); + ByteArrayOutputStream bo = new ByteArrayOutputStream(); + byte[] ref = new byte[40]; + byte[] copy = new byte[3]; + ref[0] = 10; + ref[1] = 20; + ref[2] = 30; + copy[0] = 40; + copy[1] = 50; + copy[2] = 60; + + byte[][] src = new byte[][] { + copy, ref, ref, copy, ref, copy, copy, ref + }; + + for(byte[] s : src) { + bo.write(s); + v.write(s); + } + + ByteArrayOutputStream check = new ByteArrayOutputStream(); + v.writeTo(check); + + assertEquals(bo.size(), check.size()); + assertTrue(Arrays.equals(bo.toByteArray(), check.toByteArray())); + } +} + diff --git a/java/src/test/java/org/msgpack/packer/TestPackConvert.java b/java/src/test/java/org/msgpack/packer/TestPackConvert.java deleted file mode 100644 index 26f3313..0000000 --- a/java/src/test/java/org/msgpack/packer/TestPackConvert.java +++ /dev/null @@ -1,448 +0,0 @@ -package org.msgpack.packer; - -import java.io.ByteArrayOutputStream; -import java.math.BigInteger; -import java.util.Random; - -import junit.framework.TestCase; - -import org.junit.Test; -import org.msgpack.MessagePackObject; -import org.msgpack.MessagePacker; -import org.msgpack.MessageTypeException; -import org.msgpack.Packer; -import org.msgpack.Template; -import org.msgpack.Util; -import org.msgpack.template.BigIntegerTemplate; -import org.msgpack.template.BooleanTemplate; -import org.msgpack.template.ByteTemplate; -import org.msgpack.template.DoubleTemplate; -import org.msgpack.template.FloatTemplate; -import org.msgpack.template.IntegerTemplate; -import org.msgpack.template.LongTemplate; -import org.msgpack.template.OptionalTemplate; -import org.msgpack.template.ShortTemplate; -import org.msgpack.template.StringTemplate; - -public class TestPackConvert extends TestCase { - - @Test - public void testByte() throws Exception { - _testByte((byte) 0); - _testByte((byte) -1); - _testByte((byte) 1); - _testByte(Byte.MIN_VALUE); - _testByte(Byte.MAX_VALUE); - Random rand = new Random(); - for (int i = 0; i < 1000; i++) { - _testByte((byte) rand.nextInt()); - } - } - - static void _testByte(Byte src) throws Exception { - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = BytePacker.getInstance(); - packer.pack(new Packer(out), src); - MessagePackObject obj = Util.unpackOne(out.toByteArray()); - assertEquals(src.byteValue(), obj.asByte()); - } - - @Test - public void testNullByte() throws Exception { - Byte src = null; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = new OptionalPacker(BytePacker.getInstance()); - packer.pack(new Packer(out), src); - MessagePackObject obj = Util.unpackOne(out.toByteArray()); - Template tmpl = null; - Byte dst = null; - try { - tmpl = ByteTemplate.getInstance(); - dst = (Byte) tmpl.convert(obj); - fail(); - } catch (Exception e) { - assertTrue(e instanceof MessageTypeException); - } - obj = Util.unpackOne(out.toByteArray()); - tmpl = new OptionalTemplate(ByteTemplate.getInstance()); - dst = (Byte) tmpl.convert(obj); - assertEquals(src, dst); - } - - @Test - public void testShort() throws Exception { - _testShort((short) 0); - _testShort((short) -1); - _testShort((short) 1); - _testShort(Short.MIN_VALUE); - _testShort(Short.MAX_VALUE); - Random rand = new Random(); - for (int i = 0; i < 1000; i++) { - _testShort((short) rand.nextInt()); - } - } - - static void _testShort(Short src) throws Exception { - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = ShortPacker.getInstance(); - packer.pack(new Packer(out), src); - MessagePackObject obj = Util.unpackOne(out.toByteArray()); - assertEquals(src.shortValue(), obj.asShort()); - } - - @Test - public void testNullShort() throws Exception { - Short src = null; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = new OptionalPacker(ShortPacker.getInstance()); - packer.pack(new Packer(out), src); - MessagePackObject obj = Util.unpackOne(out.toByteArray()); - Template tmpl = null; - Short dst = null; - try { - tmpl = ShortTemplate.getInstance(); - dst = (Short) tmpl.convert(obj); - fail(); - } catch (Exception e) { - assertTrue(e instanceof MessageTypeException); - } - obj = Util.unpackOne(out.toByteArray()); - tmpl = new OptionalTemplate(ShortTemplate.getInstance()); - dst = (Short) tmpl.convert(obj); - assertEquals(src, dst); - } - - @Test - public void testInteger() throws Exception { - _testInteger(0); - _testInteger(-1); - _testInteger(1); - _testInteger(Integer.MIN_VALUE); - _testInteger(Integer.MAX_VALUE); - Random rand = new Random(); - for (int i = 0; i < 1000; i++) { - _testInteger(rand.nextInt()); - } - } - - static void _testInteger(Integer src) throws Exception { - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = IntegerPacker.getInstance(); - packer.pack(new Packer(out), src); - MessagePackObject obj = Util.unpackOne(out.toByteArray()); - assertEquals(src.intValue(), obj.asInt()); - } - - @Test - public void testNullInteger() throws Exception { - Integer src = null; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = new OptionalPacker(IntegerPacker.getInstance()); - packer.pack(new Packer(out), src); - MessagePackObject obj = Util.unpackOne(out.toByteArray()); - Template tmpl = null; - Integer dst = null; - try { - tmpl = IntegerTemplate.getInstance(); - dst = (Integer) tmpl.convert(obj); - fail(); - } catch (Exception e) { - assertTrue(e instanceof MessageTypeException); - } - obj = Util.unpackOne(out.toByteArray()); - tmpl = new OptionalTemplate(IntegerTemplate.getInstance()); - dst = (Integer) tmpl.convert(obj); - assertEquals(src, dst); - } - - @Test - public void testLong() throws Exception { - _testLong((long) 0); - _testLong((long) -1); - _testLong((long) 1); - _testLong((long) Integer.MIN_VALUE); - _testLong((long) Integer.MAX_VALUE); - _testLong(Long.MIN_VALUE); - _testLong(Long.MAX_VALUE); - Random rand = new Random(); - for (int i = 0; i < 1000; i++) { - _testLong(rand.nextLong()); - } - } - - static void _testLong(Long src) throws Exception { - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = LongPacker.getInstance(); - packer.pack(new Packer(out), src); - MessagePackObject obj = Util.unpackOne(out.toByteArray()); - assertEquals(src.longValue(), obj.asLong()); - } - - @Test - public void testNullLong() throws Exception { - Long src = null; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = new OptionalPacker(LongPacker.getInstance()); - packer.pack(new Packer(out), src); - MessagePackObject obj = Util.unpackOne(out.toByteArray()); - Template tmpl = null; - Long dst = null; - try { - tmpl = LongTemplate.getInstance(); - dst = (Long) tmpl.convert(obj); - fail(); - } catch (Exception e) { - assertTrue(e instanceof MessageTypeException); - } - obj = Util.unpackOne(out.toByteArray()); - tmpl = new OptionalTemplate(LongTemplate.getInstance()); - dst = (Long) tmpl.convert(obj); - assertEquals(src, dst); - } - - @Test - public void testBigInteger() throws Exception { - _testBigInteger(BigInteger.valueOf(0)); - _testBigInteger(BigInteger.valueOf(-1)); - _testBigInteger(BigInteger.valueOf(1)); - _testBigInteger(BigInteger.valueOf(Integer.MIN_VALUE)); - _testBigInteger(BigInteger.valueOf(Integer.MAX_VALUE)); - _testBigInteger(BigInteger.valueOf(Long.MIN_VALUE)); - _testBigInteger(BigInteger.valueOf(Long.MAX_VALUE)); - BigInteger max = BigInteger.valueOf(Long.MAX_VALUE).setBit(63); - _testBigInteger(max); - Random rand = new Random(); - for (int i = 0; i < 1000; i++) { - _testBigInteger(max.subtract(BigInteger.valueOf(Math.abs(rand - .nextLong())))); - } - } - - static void _testBigInteger(BigInteger src) throws Exception { - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = BigIntegerPacker.getInstance(); - packer.pack(new Packer(out), src); - MessagePackObject obj = Util.unpackOne(out.toByteArray()); - assertEquals(src, obj.asBigInteger()); - } - - @Test - public void testNullBigInteger() throws Exception { - Long src = null; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = new OptionalPacker(BigIntegerPacker - .getInstance()); - packer.pack(new Packer(out), src); - MessagePackObject obj = Util.unpackOne(out.toByteArray()); - Template tmpl = null; - BigInteger dst = null; - try { - tmpl = BigIntegerTemplate.getInstance(); - dst = (BigInteger) tmpl.convert(obj); - fail(); - } catch (Exception e) { - assertTrue(e instanceof MessageTypeException); - } - obj = Util.unpackOne(out.toByteArray()); - tmpl = new OptionalTemplate(BigIntegerTemplate.getInstance()); - dst = (BigInteger) tmpl.convert(obj); - assertEquals(src, dst); - } - - @Test - public void testFloat() throws Exception { - _testFloat((float) 0.0); - _testFloat((float) -0.0); - _testFloat((float) 1.0); - _testFloat((float) -1.0); - _testFloat((float) Float.MAX_VALUE); - _testFloat((float) Float.MIN_VALUE); - _testFloat((float) Float.NaN); - _testFloat((float) Float.NEGATIVE_INFINITY); - _testFloat((float) Float.POSITIVE_INFINITY); - Random rand = new Random(); - for (int i = 0; i < 1000; i++) { - _testFloat(rand.nextFloat()); - } - } - - static void _testFloat(Float src) throws Exception { - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = FloatPacker.getInstance(); - packer.pack(new Packer(out), src); - MessagePackObject obj = Util.unpackOne(out.toByteArray()); - assertEquals(src.floatValue(), obj.asFloat(), 10e-10); - } - - @Test - public void testNullFloat() throws Exception { - Long src = null; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = new OptionalPacker(FloatPacker.getInstance()); - packer.pack(new Packer(out), src); - MessagePackObject obj = Util.unpackOne(out.toByteArray()); - Template tmpl = null; - Float dst = null; - try { - tmpl = FloatTemplate.getInstance(); - dst = (Float) tmpl.convert(obj); - fail(); - } catch (Exception e) { - assertTrue(e instanceof MessageTypeException); - } - obj = Util.unpackOne(out.toByteArray()); - tmpl = new OptionalTemplate(FloatTemplate.getInstance()); - dst = (Float) tmpl.convert(obj); - assertEquals(src, dst); - } - - @Test - public void testDouble() throws Exception { - _testDouble((double) 0.0); - _testDouble((double) -0.0); - _testDouble((double) 1.0); - _testDouble((double) -1.0); - _testDouble((double) Double.MAX_VALUE); - _testDouble((double) Double.MIN_VALUE); - _testDouble((double) Double.NaN); - _testDouble((double) Double.NEGATIVE_INFINITY); - _testDouble((double) Double.POSITIVE_INFINITY); - Random rand = new Random(); - for (int i = 0; i < 1000; i++) - _testDouble(rand.nextDouble()); - } - - static void _testDouble(Double src) throws Exception { - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = DoublePacker.getInstance(); - packer.pack(new Packer(out), src); - MessagePackObject obj = Util.unpackOne(out.toByteArray()); - assertEquals(src.doubleValue(), obj.asDouble(), 10e-10); - } - - @Test - public void testNullDouble() throws Exception { - Long src = null; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = new OptionalPacker(DoublePacker.getInstance()); - packer.pack(new Packer(out), src); - MessagePackObject obj = Util.unpackOne(out.toByteArray()); - Template tmpl = null; - Double dst = null; - try { - tmpl = DoubleTemplate.getInstance(); - dst = (Double) tmpl.convert(obj); - fail(); - } catch (Exception e) { - assertTrue(e instanceof MessageTypeException); - } - obj = Util.unpackOne(out.toByteArray()); - tmpl = new OptionalTemplate(DoubleTemplate.getInstance()); - dst = (Double) tmpl.convert(obj); - assertEquals(src, dst); - } - - @Test - public void testBoolean() throws Exception { - _testBoolean(false); - _testBoolean(true); - } - - static void _testBoolean(Boolean src) throws Exception { - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = BooleanPacker.getInstance(); - packer.pack(new Packer(out), src); - MessagePackObject obj = Util.unpackOne(out.toByteArray()); - assertEquals(src.booleanValue(), obj.asBoolean()); - } - - @Test - public void testNullBoolean() throws Exception { - Long src = null; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = new OptionalPacker(BooleanPacker.getInstance()); - packer.pack(new Packer(out), src); - MessagePackObject obj = Util.unpackOne(out.toByteArray()); - Template tmpl = null; - Boolean dst = null; - try { - tmpl = BooleanTemplate.getInstance(); - dst = (Boolean) tmpl.convert(obj); - fail(); - } catch (Exception e) { - assertTrue(e instanceof MessageTypeException); - } - obj = Util.unpackOne(out.toByteArray()); - tmpl = new OptionalTemplate(BooleanTemplate.getInstance()); - dst = (Boolean) tmpl.convert(obj); - assertEquals(src, dst); - } - - @Test - public void testString() throws Exception { - _testString(""); - _testString("a"); - _testString("ab"); - _testString("abc"); - - // small size string - for (int i = 0; i < 100; i++) { - StringBuilder sb = new StringBuilder(); - int len = (int) Math.random() % 31 + 1; - for (int j = 0; j < len; j++) { - sb.append('a' + ((int) Math.random()) & 26); - } - _testString(sb.toString()); - } - - // medium size string - for (int i = 0; i < 100; i++) { - StringBuilder sb = new StringBuilder(); - int len = (int) Math.random() % 100 + (1 << 15); - for (int j = 0; j < len; j++) { - sb.append('a' + ((int) Math.random()) & 26); - } - _testString(sb.toString()); - } - - // large size string - for (int i = 0; i < 10; i++) { - StringBuilder sb = new StringBuilder(); - int len = (int) Math.random() % 100 + (1 << 31); - for (int j = 0; j < len; j++) { - sb.append('a' + ((int) Math.random()) & 26); - } - _testString(sb.toString()); - } - } - - static void _testString(String src) throws Exception { - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = StringPacker.getInstance(); - packer.pack(new Packer(out), src); - MessagePackObject obj = Util.unpackOne(out.toByteArray()); - assertEquals(src, obj.asString()); - } - - @Test - public void testNullString() throws Exception { - String src = null; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = new OptionalPacker(StringPacker.getInstance()); - packer.pack(new Packer(out), src); - MessagePackObject obj = Util.unpackOne(out.toByteArray()); - Template tmpl = null; - String dst = null; - try { - tmpl = StringTemplate.getInstance(); - dst = (String) tmpl.convert(obj); - fail(); - } catch (Exception e) { - assertTrue(e instanceof MessageTypeException); - } - obj = Util.unpackOne(out.toByteArray()); - tmpl = new OptionalTemplate(StringTemplate.getInstance()); - dst = (String) tmpl.convert(obj); - assertEquals(src, dst); - } -} diff --git a/java/src/test/java/org/msgpack/packer/TestPackUnpack.java b/java/src/test/java/org/msgpack/packer/TestPackUnpack.java deleted file mode 100644 index 2dd631d..0000000 --- a/java/src/test/java/org/msgpack/packer/TestPackUnpack.java +++ /dev/null @@ -1,475 +0,0 @@ -package org.msgpack.packer; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.math.BigInteger; -import java.util.Random; - -import junit.framework.TestCase; - -import org.junit.Test; -import org.msgpack.MessagePacker; -import org.msgpack.MessageTypeException; -import org.msgpack.Packer; -import org.msgpack.Template; -import org.msgpack.Unpacker; -import org.msgpack.template.BigIntegerTemplate; -import org.msgpack.template.BooleanTemplate; -import org.msgpack.template.ByteTemplate; -import org.msgpack.template.DoubleTemplate; -import org.msgpack.template.FloatTemplate; -import org.msgpack.template.IntegerTemplate; -import org.msgpack.template.LongTemplate; -import org.msgpack.template.OptionalTemplate; -import org.msgpack.template.ShortTemplate; -import org.msgpack.template.StringTemplate; - -public class TestPackUnpack extends TestCase { - - @Test - public void testByte() throws Exception { - _testByte((byte) 0); - _testByte((byte) -1); - _testByte((byte) 1); - _testByte(Byte.MIN_VALUE); - _testByte(Byte.MAX_VALUE); - Random rand = new Random(); - for (int i = 0; i < 1000; i++) { - _testByte((byte) rand.nextInt()); - } - } - - static void _testByte(Byte src) throws Exception { - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = BytePacker.getInstance(); - packer.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Unpacker unpacker = new Unpacker(in); - assertEquals(src.byteValue(), unpacker.unpackByte()); - } - - @Test - public void testNullByte() throws Exception { - Byte src = null; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = new OptionalPacker(BytePacker.getInstance()); - packer.pack(new Packer(out), src); - byte[] bytes = out.toByteArray(); - Template tmpl = null; - Unpacker unpacker = new Unpacker(); - Byte dst = null; - try { - tmpl = ByteTemplate.getInstance(); - unpacker.wrap(bytes); - dst = (Byte) tmpl.unpack(unpacker); - fail(); - } catch (Exception e) { - assertTrue(e instanceof MessageTypeException); - } - unpacker.wrap(bytes); - tmpl = new OptionalTemplate(ByteTemplate.getInstance()); - dst = (Byte) tmpl.unpack(unpacker); - assertEquals(src, dst); - } - - @Test - public void testSort() throws Exception { - _testShort((short) 0); - _testShort((short) -1); - _testShort((short) 1); - _testShort(Short.MIN_VALUE); - _testShort(Short.MAX_VALUE); - Random rand = new Random(); - for (int i = 0; i < 1000; i++) { - _testShort((short) rand.nextInt()); - } - } - - static void _testShort(Short src) throws Exception { - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = ShortPacker.getInstance(); - packer.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Unpacker unpacker = new Unpacker(in); - assertEquals(src.shortValue(), unpacker.unpackShort()); - } - - @Test - public void testNullShort() throws Exception { - Short src = null; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = new OptionalPacker(ShortPacker.getInstance()); - packer.pack(new Packer(out), src); - byte[] bytes = out.toByteArray(); - Template tmpl = null; - Unpacker unpacker = new Unpacker(); - Short dst = null; - try { - tmpl = ShortTemplate.getInstance(); - unpacker.wrap(bytes); - dst = (Short) tmpl.unpack(unpacker); - fail(); - } catch (Exception e) { - assertTrue(e instanceof MessageTypeException); - } - unpacker.wrap(bytes); - tmpl = new OptionalTemplate(ShortTemplate.getInstance()); - dst = (Short) tmpl.unpack(unpacker); - assertEquals(src, dst); - } - - @Test - public void testInteger() throws Exception { - _testInteger(0); - _testInteger(-1); - _testInteger(1); - _testInteger(Integer.MIN_VALUE); - _testInteger(Integer.MAX_VALUE); - Random rand = new Random(); - for (int i = 0; i < 1000; i++) { - _testInteger(rand.nextInt()); - } - } - - static void _testInteger(Integer src) throws Exception { - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = IntegerPacker.getInstance(); - packer.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Unpacker unpacker = new Unpacker(in); - assertEquals(src.intValue(), unpacker.unpackInt()); - } - - @Test - public void testNullInteger() throws Exception { - Integer src = null; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = new OptionalPacker(IntegerPacker.getInstance()); - packer.pack(new Packer(out), src); - byte[] bytes = out.toByteArray(); - Template tmpl = null; - Unpacker unpacker = new Unpacker(); - Integer dst = null; - try { - tmpl = IntegerTemplate.getInstance(); - unpacker.wrap(bytes); - dst = (Integer) tmpl.unpack(unpacker); - fail(); - } catch (Exception e) { - assertTrue(e instanceof MessageTypeException); - } - unpacker.wrap(bytes); - tmpl = new OptionalTemplate(IntegerTemplate.getInstance()); - dst = (Integer) tmpl.unpack(unpacker); - assertEquals(src, dst); - } - - @Test - public void testLong() throws Exception { - _testLong((long) 0); - _testLong((long) -1); - _testLong((long) 1); - _testLong((long) Integer.MIN_VALUE); - _testLong((long) Integer.MAX_VALUE); - _testLong(Long.MIN_VALUE); - _testLong(Long.MAX_VALUE); - Random rand = new Random(); - for (int i = 0; i < 1000; i++) { - _testLong(rand.nextLong()); - } - } - - static void _testLong(Long src) throws Exception { - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = LongPacker.getInstance(); - packer.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Unpacker unpacker = new Unpacker(in); - assertEquals(src.longValue(), unpacker.unpackLong()); - } - - @Test - public void testNullLong() throws Exception { - Integer src = null; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = new OptionalPacker(LongPacker.getInstance()); - packer.pack(new Packer(out), src); - byte[] bytes = out.toByteArray(); - Template tmpl = null; - Unpacker unpacker = new Unpacker(); - Long dst = null; - try { - tmpl = LongTemplate.getInstance(); - unpacker.wrap(bytes); - dst = (Long) tmpl.unpack(unpacker); - fail(); - } catch (Exception e) { - assertTrue(e instanceof MessageTypeException); - } - unpacker.wrap(bytes); - tmpl = new OptionalTemplate(LongTemplate.getInstance()); - dst = (Long) tmpl.unpack(unpacker); - assertEquals(src, dst); - } - - @Test - public void testBigInteger() throws Exception { - _testBigInteger(BigInteger.valueOf(0)); - _testBigInteger(BigInteger.valueOf(-1)); - _testBigInteger(BigInteger.valueOf(1)); - _testBigInteger(BigInteger.valueOf(Integer.MIN_VALUE)); - _testBigInteger(BigInteger.valueOf(Integer.MAX_VALUE)); - _testBigInteger(BigInteger.valueOf(Long.MIN_VALUE)); - _testBigInteger(BigInteger.valueOf(Long.MAX_VALUE)); - BigInteger max = BigInteger.valueOf(Long.MAX_VALUE).setBit(63); - _testBigInteger(max); - Random rand = new Random(); - for (int i = 0; i < 1000; i++) { - _testBigInteger(max.subtract(BigInteger.valueOf(Math.abs(rand - .nextLong())))); - } - } - - static void _testBigInteger(BigInteger src) throws Exception { - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = BigIntegerPacker.getInstance(); - packer.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Unpacker unpacker = new Unpacker(in); - assertEquals(src, unpacker.unpackBigInteger()); - } - - @Test - public void testNullBigInteger() throws Exception { - BigInteger src = null; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = new OptionalPacker(BigIntegerPacker - .getInstance()); - packer.pack(new Packer(out), src); - byte[] bytes = out.toByteArray(); - Template tmpl = null; - Unpacker unpacker = new Unpacker(); - BigInteger dst = null; - try { - tmpl = BigIntegerTemplate.getInstance(); - unpacker.wrap(bytes); - dst = (BigInteger) tmpl.unpack(unpacker); - fail(); - } catch (Exception e) { - assertTrue(e instanceof MessageTypeException); - } - unpacker.wrap(bytes); - tmpl = new OptionalTemplate(BigIntegerTemplate.getInstance()); - dst = (BigInteger) tmpl.unpack(unpacker); - assertEquals(src, dst); - } - - @Test - public void testFloat() throws Exception { - _testFloat((float) 0.0); - _testFloat((float) -0.0); - _testFloat((float) 1.0); - _testFloat((float) -1.0); - _testFloat((float) Float.MAX_VALUE); - _testFloat((float) Float.MIN_VALUE); - _testFloat((float) Float.NaN); - _testFloat((float) Float.NEGATIVE_INFINITY); - _testFloat((float) Float.POSITIVE_INFINITY); - Random rand = new Random(); - for (int i = 0; i < 1000; i++) { - _testFloat(rand.nextFloat()); - } - } - - static void _testFloat(Float src) throws Exception { - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = FloatPacker.getInstance(); - packer.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Unpacker unpacker = new Unpacker(in); - assertEquals(src.floatValue(), unpacker.unpackFloat(), 10e-10); - } - - @Test - public void testNullFloat() throws Exception { - Float src = null; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = new OptionalPacker(FloatPacker.getInstance()); - packer.pack(new Packer(out), src); - byte[] bytes = out.toByteArray(); - Template tmpl = null; - Unpacker unpacker = new Unpacker(); - Float dst = null; - try { - tmpl = FloatTemplate.getInstance(); - unpacker.wrap(bytes); - dst = (Float) tmpl.unpack(unpacker); - fail(); - } catch (Exception e) { - assertTrue(e instanceof MessageTypeException); - } - unpacker.wrap(bytes); - tmpl = new OptionalTemplate(FloatTemplate.getInstance()); - dst = (Float) tmpl.unpack(unpacker); - assertEquals(src, dst); - } - - @Test - public void testDouble() throws Exception { - _testDouble((double) 0.0); - _testDouble((double) -0.0); - _testDouble((double) 1.0); - _testDouble((double) -1.0); - _testDouble((double) Double.MAX_VALUE); - _testDouble((double) Double.MIN_VALUE); - _testDouble((double) Double.NaN); - _testDouble((double) Double.NEGATIVE_INFINITY); - _testDouble((double) Double.POSITIVE_INFINITY); - Random rand = new Random(); - for (int i = 0; i < 1000; i++) - _testDouble(rand.nextDouble()); - } - - static void _testDouble(Double src) throws Exception { - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = DoublePacker.getInstance(); - packer.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Unpacker unpacker = new Unpacker(in); - assertEquals(src.doubleValue(), unpacker.unpackDouble(), 10e-10); - } - - @Test - public void testNullDouble() throws Exception { - Double src = null; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = new OptionalPacker(DoublePacker.getInstance()); - packer.pack(new Packer(out), src); - byte[] bytes = out.toByteArray(); - Template tmpl = null; - Unpacker unpacker = new Unpacker(); - Double dst = null; - try { - tmpl = DoubleTemplate.getInstance(); - unpacker.wrap(bytes); - dst = (Double) tmpl.unpack(unpacker); - fail(); - } catch (Exception e) { - assertTrue(e instanceof MessageTypeException); - } - unpacker.wrap(bytes); - tmpl = new OptionalTemplate(DoubleTemplate.getInstance()); - dst = (Double) tmpl.unpack(unpacker); - assertEquals(src, dst); - } - - @Test - public void testBoolean() throws Exception { - _testBoolean(false); - _testBoolean(true); - } - - static void _testBoolean(Boolean src) throws Exception { - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = BooleanPacker.getInstance(); - packer.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Unpacker unpacker = new Unpacker(in); - assertEquals(src.booleanValue(), unpacker.unpackBoolean()); - } - - @Test - public void testNullBoolean() throws Exception { - Boolean src = null; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = new OptionalPacker(BooleanPacker.getInstance()); - packer.pack(new Packer(out), src); - byte[] bytes = out.toByteArray(); - Template tmpl = null; - Unpacker unpacker = new Unpacker(); - Boolean dst = null; - try { - tmpl = BooleanTemplate.getInstance(); - unpacker.wrap(bytes); - dst = (Boolean) tmpl.unpack(unpacker); - fail(); - } catch (Exception e) { - assertTrue(e instanceof MessageTypeException); - } - unpacker.wrap(bytes); - tmpl = new OptionalTemplate(BooleanTemplate.getInstance()); - dst = (Boolean) tmpl.unpack(unpacker); - assertEquals(src, dst); - } - - @Test - public void testString() throws Exception { - _testString(""); - _testString("a"); - _testString("ab"); - _testString("abc"); - - // small size string - for (int i = 0; i < 100; i++) { - StringBuilder sb = new StringBuilder(); - int len = (int) Math.random() % 31 + 1; - for (int j = 0; j < len; j++) { - sb.append('a' + ((int) Math.random()) & 26); - } - _testString(sb.toString()); - } - - // medium size string - for (int i = 0; i < 100; i++) { - StringBuilder sb = new StringBuilder(); - int len = (int) Math.random() % 100 + (1 << 15); - for (int j = 0; j < len; j++) { - sb.append('a' + ((int) Math.random()) & 26); - } - _testString(sb.toString()); - } - - // large size string - for (int i = 0; i < 10; i++) { - StringBuilder sb = new StringBuilder(); - int len = (int) Math.random() % 100 + (1 << 31); - for (int j = 0; j < len; j++) { - sb.append('a' + ((int) Math.random()) & 26); - } - _testString(sb.toString()); - } - } - - static void _testString(String src) throws Exception { - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = StringPacker.getInstance(); - packer.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Unpacker unpacker = new Unpacker(in); - assertEquals(src, unpacker.unpackString()); - } - - @Test - public void testNullString() throws Exception { - String src = null; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = new OptionalPacker(StringPacker.getInstance()); - packer.pack(new Packer(out), src); - byte[] bytes = out.toByteArray(); - Template tmpl = null; - Unpacker unpacker = new Unpacker(); - String dst = null; - try { - tmpl = StringTemplate.getInstance(); - unpacker.wrap(bytes); - dst = (String) tmpl.unpack(unpacker); - fail(); - } catch (Exception e) { - assertTrue(e instanceof MessageTypeException); - } - unpacker.wrap(bytes); - tmpl = new OptionalTemplate(StringTemplate.getInstance()); - dst = (String) tmpl.unpack(unpacker); - assertEquals(src, dst); - } -} diff --git a/java/src/test/java/org/msgpack/template/TestPackConvert.java b/java/src/test/java/org/msgpack/template/TestPackConvert.java index 01063a5..9524b28 100644 --- a/java/src/test/java/org/msgpack/template/TestPackConvert.java +++ b/java/src/test/java/org/msgpack/template/TestPackConvert.java @@ -2,8 +2,12 @@ package org.msgpack.template; import java.io.ByteArrayOutputStream; import java.math.BigInteger; +import java.nio.ByteBuffer; import java.util.ArrayList; +import java.util.Collection; import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Random; @@ -34,30 +38,36 @@ public class TestPackConvert extends TestCase { static void _testInteger(Integer src) throws Exception { ByteArrayOutputStream out = new ByteArrayOutputStream(); - new Packer(out).pack(src); - MessagePackObject obj = Util.unpackOne(out.toByteArray()); Template tmpl = IntegerTemplate.getInstance(); - Integer dst = (Integer) tmpl.convert(obj); + tmpl.pack(new Packer(out), src); + MessagePackObject obj = Util.unpackOne(out.toByteArray()); + Integer dst = (Integer) tmpl.convert(obj, null); assertEquals(src, dst); } @Test public void testNullInteger() throws Exception { Integer src = null; + Template tmpl = IntegerTemplate.getInstance(); ByteArrayOutputStream out = new ByteArrayOutputStream(); + Packer packer = new Packer(out); + try { + tmpl.pack(packer, src); + fail(); + } catch (Exception e) { + assertTrue(e instanceof MessageTypeException); + } new Packer(out).pack(src); MessagePackObject obj = Util.unpackOne(out.toByteArray()); - Template tmpl = IntegerTemplate.getInstance(); - Integer dst = null; try { - dst = (Integer) tmpl.convert(obj); + tmpl.convert(obj, null); fail(); } catch (Exception e) { assertTrue(e instanceof MessageTypeException); } obj = Util.unpackOne(out.toByteArray()); - tmpl = new OptionalTemplate(IntegerTemplate.getInstance()); - dst = (Integer) tmpl.convert(obj); + tmpl = new NullableTemplate(IntegerTemplate.getInstance()); + Integer dst = (Integer) tmpl.convert(obj, null); assertEquals(src, dst); } @@ -78,30 +88,36 @@ public class TestPackConvert extends TestCase { public void _testLong(Long src) throws Exception { ByteArrayOutputStream out = new ByteArrayOutputStream(); - new Packer(out).pack(src); - MessagePackObject obj = Util.unpackOne(out.toByteArray()); Template tmpl = LongTemplate.getInstance(); - Long dst = (Long) tmpl.convert(obj); + tmpl.pack(new Packer(out), src); + MessagePackObject obj = Util.unpackOne(out.toByteArray()); + Long dst = (Long) tmpl.convert(obj, null); assertEquals(src, dst); } @Test public void testNullLong() throws Exception { Long src = null; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - new Packer(out).pack(src); - MessagePackObject obj = Util.unpackOne(out.toByteArray()); Template tmpl = LongTemplate.getInstance(); - Long dst = null; + ByteArrayOutputStream out = new ByteArrayOutputStream(); + Packer packer = new Packer(out); try { - dst = (Long) tmpl.convert(obj); + tmpl.pack(packer, src); + fail(); + } catch (Exception e) { + assertTrue(e instanceof MessageTypeException); + } + packer.pack(src); + MessagePackObject obj = Util.unpackOne(out.toByteArray()); + try { + tmpl.convert(obj, null); fail(); } catch (Exception e) { assertTrue(e instanceof MessageTypeException); } obj = Util.unpackOne(out.toByteArray()); - tmpl = new OptionalTemplate(LongTemplate.getInstance()); - dst = (Long) tmpl.convert(obj); + tmpl = new NullableTemplate(LongTemplate.getInstance()); + Long dst = (Long) tmpl.convert(obj, null); assertEquals(src, dst); } @@ -118,37 +134,41 @@ public class TestPackConvert extends TestCase { _testBigInteger(max); Random rand = new Random(); for (int i = 0; i < 1000; i++) { - _testBigInteger(max.subtract(BigInteger.valueOf(Math.abs(rand - .nextLong())))); + _testBigInteger(max.subtract(BigInteger.valueOf(Math.abs(rand.nextLong())))); } } static void _testBigInteger(BigInteger src) throws Exception { ByteArrayOutputStream out = new ByteArrayOutputStream(); - new Packer(out).pack(src); - MessagePackObject obj = Util.unpackOne(out.toByteArray()); Template tmpl = BigIntegerTemplate.getInstance(); - BigInteger dst = (BigInteger) tmpl.convert(obj); + tmpl.pack(new Packer(out), src); + MessagePackObject obj = Util.unpackOne(out.toByteArray()); + BigInteger dst = (BigInteger) tmpl.convert(obj, null); assertEquals(src, dst); } @Test public void testNullBigInteger() throws Exception { Long src = null; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - new Packer(out).pack(src); - MessagePackObject obj = Util.unpackOne(out.toByteArray()); Template tmpl = BigIntegerTemplate.getInstance(); - BigInteger dst = null; + ByteArrayOutputStream out = new ByteArrayOutputStream(); + Packer packer = new Packer(out); try { - dst = (BigInteger) tmpl.convert(obj); + tmpl.pack(packer, src); + } catch (Exception e) { + assertTrue(e instanceof MessageTypeException); + } + packer.pack(src); + MessagePackObject obj = Util.unpackOne(out.toByteArray()); + try { + tmpl.convert(obj, null); fail(); } catch (Exception e) { assertTrue(e instanceof MessageTypeException); } obj = Util.unpackOne(out.toByteArray()); - tmpl = new OptionalTemplate(BigIntegerTemplate.getInstance()); - dst = (BigInteger) tmpl.convert(obj); + tmpl = new NullableTemplate(BigIntegerTemplate.getInstance()); + BigInteger dst = (BigInteger) tmpl.convert(obj, null); assertEquals(src, dst); } @@ -171,30 +191,36 @@ public class TestPackConvert extends TestCase { static void _testFloat(Float src) throws Exception { ByteArrayOutputStream out = new ByteArrayOutputStream(); - new Packer(out).pack(src); - MessagePackObject obj = Util.unpackOne(out.toByteArray()); Template tmpl = FloatTemplate.getInstance(); - Float dst = (Float) tmpl.convert(obj); + tmpl.pack(new Packer(out), src); + MessagePackObject obj = Util.unpackOne(out.toByteArray()); + Float dst = (Float) tmpl.convert(obj, null); assertEquals(src, dst, 10e-10); } @Test public void testNullFloat() throws Exception { Long src = null; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - new Packer(out).pack(src); - MessagePackObject obj = Util.unpackOne(out.toByteArray()); Template tmpl = FloatTemplate.getInstance(); - Float dst = null; + ByteArrayOutputStream out = new ByteArrayOutputStream(); + Packer packer = new Packer(out); try { - dst = (Float) tmpl.convert(obj); + tmpl.pack(packer, src); + fail(); + } catch (Exception e) { + assertTrue(e instanceof MessageTypeException); + } + packer.pack(src); + MessagePackObject obj = Util.unpackOne(out.toByteArray()); + try { + tmpl.convert(obj, null); fail(); } catch (Exception e) { assertTrue(e instanceof MessageTypeException); } obj = Util.unpackOne(out.toByteArray()); - tmpl = new OptionalTemplate(FloatTemplate.getInstance()); - dst = (Float) tmpl.convert(obj); + tmpl = new NullableTemplate(FloatTemplate.getInstance()); + Float dst = (Float) tmpl.convert(obj, null); assertEquals(src, dst); } @@ -217,30 +243,36 @@ public class TestPackConvert extends TestCase { static void _testDouble(Double src) throws Exception { ByteArrayOutputStream out = new ByteArrayOutputStream(); - new Packer(out).pack(src); - MessagePackObject obj = Util.unpackOne(out.toByteArray()); Template tmpl = DoubleTemplate.getInstance(); - Double dst = (Double) tmpl.convert(obj); + tmpl.pack(new Packer(out), src); + MessagePackObject obj = Util.unpackOne(out.toByteArray()); + Double dst = (Double) tmpl.convert(obj, null); assertEquals(src, dst, 10e-10); } @Test public void testNullDouble() throws Exception { Long src = null; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - new Packer(out).pack(src); - MessagePackObject obj = Util.unpackOne(out.toByteArray()); Template tmpl = DoubleTemplate.getInstance(); - Double dst = null; + ByteArrayOutputStream out = new ByteArrayOutputStream(); + Packer packer = new Packer(out); try { - dst = (Double) tmpl.convert(obj); + tmpl.pack(packer, src); + fail(); + } catch (Exception e) { + assertTrue(e instanceof MessageTypeException); + } + packer.pack(src); + MessagePackObject obj = Util.unpackOne(out.toByteArray()); + try { + tmpl.convert(obj, null); fail(); } catch (Exception e) { assertTrue(e instanceof MessageTypeException); } obj = Util.unpackOne(out.toByteArray()); - tmpl = new OptionalTemplate(DoubleTemplate.getInstance()); - dst = (Double) tmpl.convert(obj); + tmpl = new NullableTemplate(DoubleTemplate.getInstance()); + Double dst = (Double) tmpl.convert(obj, null); assertEquals(src, dst); } @@ -252,30 +284,146 @@ public class TestPackConvert extends TestCase { static void _testBoolean(Boolean src) throws Exception { ByteArrayOutputStream out = new ByteArrayOutputStream(); - new Packer(out).pack(src); - MessagePackObject obj = Util.unpackOne(out.toByteArray()); Template tmpl = BooleanTemplate.getInstance(); - Boolean dst = (Boolean) tmpl.convert(obj); + tmpl.pack(new Packer(out), src); + MessagePackObject obj = Util.unpackOne(out.toByteArray()); + Boolean dst = (Boolean) tmpl.convert(obj, null); assertEquals(src, dst); } @Test public void testNullBoolean() throws Exception { Long src = null; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - new Packer(out).pack(src); - MessagePackObject obj = Util.unpackOne(out.toByteArray()); Template tmpl = BooleanTemplate.getInstance(); - Boolean dst = null; + ByteArrayOutputStream out = new ByteArrayOutputStream(); + Packer packer = new Packer(out); try { - dst = (Boolean) tmpl.convert(obj); + tmpl.pack(packer, src); + fail(); + } catch (Exception e) { + assertTrue(e instanceof MessageTypeException); + } + packer.pack(src); + MessagePackObject obj = Util.unpackOne(out.toByteArray()); + try { + tmpl.convert(obj, null); fail(); } catch (Exception e) { assertTrue(e instanceof MessageTypeException); } obj = Util.unpackOne(out.toByteArray()); - tmpl = new OptionalTemplate(BooleanTemplate.getInstance()); - dst = (Boolean) tmpl.convert(obj); + tmpl = new NullableTemplate(BooleanTemplate.getInstance()); + Boolean dst = (Boolean) tmpl.convert(obj, null); + assertEquals(src, dst); + } + + @Test + public void testByteArray() throws Exception { + Random rand = new Random(System.currentTimeMillis()); + byte[] b0 = new byte[0]; + _testByteArray(b0); + byte[] b1 = new byte[10]; + rand.nextBytes(b1); + _testByteArray(b1); + byte[] b2 = new byte[1024]; + rand.nextBytes(b2); + _testByteArray(b2); + } + + static void _testByteArray(byte[] src) throws Exception { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + Template tmpl = ByteArrayTemplate.getInstance(); + tmpl.pack(new Packer(out), src); + MessagePackObject obj = Util.unpackOne(out.toByteArray()); + byte[] dst = (byte[]) tmpl.convert(obj, null); + assertEquals(src.length, dst.length); + for (int i = 0; i < src.length; ++i) { + assertEquals(src[i], dst[i]); + } + } + + @Test + public void testNullByteArray() throws Exception { + byte[] src = null; + Template tmpl = ByteArrayTemplate.getInstance(); + ByteArrayOutputStream out = new ByteArrayOutputStream(); + Packer packer = new Packer(out); + try { + tmpl.pack(packer, src); + fail(); + } catch (Exception e) { + assertTrue(e instanceof MessageTypeException); + } + packer.pack(src); + MessagePackObject obj = Util.unpackOne(out.toByteArray()); + try { + tmpl.convert(obj, null); + fail(); + } catch (Exception e) { + assertTrue(e instanceof MessageTypeException); + } + tmpl = new NullableTemplate(ByteArrayTemplate.getInstance()); + obj = Util.unpackOne(out.toByteArray()); + byte[] dst = (byte[]) tmpl.convert(obj, null); + assertEquals(null, dst); + } + + @Test + public void testByteBuffer() throws Exception {// FIXME + Random rand = new Random(System.currentTimeMillis()); + byte[] b0 = new byte[0]; + ByteBuffer bb0 = ByteBuffer.wrap(b0); + _testByteBuffer(bb0); + bb0.clear(); + byte[] b1 = new byte[10]; + rand.nextBytes(b1); + ByteBuffer bb1 = ByteBuffer.wrap(b1); + _testByteBuffer(bb1); + bb1.clear(); + byte[] b2 = new byte[2048]; + rand.nextBytes(b2); + ByteBuffer bb2 = ByteBuffer.wrap(b2); + _testByteBuffer(bb2); + bb2.clear(); + } + + static void _testByteBuffer(ByteBuffer src) throws Exception { + Template tmpl = ByteBufferTemplate.getInstance(); + ByteArrayOutputStream out = new ByteArrayOutputStream(); + tmpl.pack(new Packer(out), src); + MessagePackObject obj = Util.unpackOne(out.toByteArray()); + ByteBuffer dst = (ByteBuffer) tmpl.convert(obj, null); + assertEquals(src.limit() - src.position(), dst.limit() - dst.position()); + int dst_pos = dst.position(); + for (int i = src.position(); i < src.limit(); ++i) { + assertEquals(src.get(i), dst.get(dst_pos)); + dst_pos++; + } + } + + @Test + public void testNullByteBuffer() throws Exception { + ByteBuffer src = null; + Template tmpl = ByteBufferTemplate.getInstance(); + ByteArrayOutputStream out = new ByteArrayOutputStream(); + Packer packer = new Packer(out); + try { + tmpl.pack(packer, src); + fail(); + } catch (Exception e) { + assertTrue(e instanceof MessageTypeException); + } + packer.pack(src); + MessagePackObject obj = Util.unpackOne(out.toByteArray()); + try { + tmpl.convert(obj, null); + fail(); + } catch (Exception e) { + assertTrue(e instanceof MessageTypeException); + } + obj = Util.unpackOne(out.toByteArray()); + tmpl = new NullableTemplate(BooleanTemplate.getInstance()); + ByteBuffer dst = (ByteBuffer) tmpl.convert(obj, null); assertEquals(src, dst); } @@ -319,78 +467,76 @@ public class TestPackConvert extends TestCase { static void _testString(String src) throws Exception { ByteArrayOutputStream out = new ByteArrayOutputStream(); - new Packer(out).pack(src); - MessagePackObject obj = Util.unpackOne(out.toByteArray()); Template tmpl = StringTemplate.getInstance(); - String dst = (String) tmpl.convert(obj); + tmpl.pack(new Packer(out), src); + MessagePackObject obj = Util.unpackOne(out.toByteArray()); + String dst = (String) tmpl.convert(obj, null); assertEquals(src, dst); } @Test public void testNullString() throws Exception { - Long src = null; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - new Packer(out).pack(src); - MessagePackObject obj = Util.unpackOne(out.toByteArray()); + String src = null; Template tmpl = StringTemplate.getInstance(); - String dst = null; + ByteArrayOutputStream out = new ByteArrayOutputStream(); + Packer packer = new Packer(out); try { - dst = (String) tmpl.convert(obj); + tmpl.pack(packer, src); + fail(); + } catch (Exception e) { + assertTrue(e instanceof MessageTypeException); + } + packer.pack(src); + MessagePackObject obj = Util.unpackOne(out.toByteArray()); + try { + tmpl.convert(obj, null); fail(); } catch (Exception e) { assertTrue(e instanceof MessageTypeException); } obj = Util.unpackOne(out.toByteArray()); - tmpl = new OptionalTemplate(StringTemplate.getInstance()); - dst = (String) tmpl.convert(obj); + tmpl = new NullableTemplate(StringTemplate.getInstance()); + String dst = (String) tmpl.convert(obj, null); assertEquals(src, dst); } @SuppressWarnings("unchecked") @Test public void testList() throws Exception { - List emptyList = new ArrayList(); + List src = new ArrayList(); + Template tmpl = new ListTemplate(IntegerTemplate.getInstance()); + // size is zero { ByteArrayOutputStream out = new ByteArrayOutputStream(); - new Packer(out).pack(emptyList); + tmpl.pack(new Packer(out), src); MessagePackObject obj = Util.unpackOne(out.toByteArray()); - Template tmpl = new ListTemplate(IntegerTemplate.getInstance()); - List dst = (List) tmpl.convert(obj); - assertEquals(emptyList, dst); + List dst = (List) tmpl.convert(obj, null); + assertEquals(src.size(), dst.size()); + Integer[] src_array = src.toArray(new Integer[0]); + Integer[] dst_array = dst.toArray(new Integer[0]); + for (int i = 0; i < src_array.length; ++i) { + assertEquals(src_array[i], dst_array[i]); + } + src.clear(); } - for (int i = 0; i < 1000; i++) { - List l = new ArrayList(); - int len = (int) Math.random() % 1000 + 1; - for (int j = 0; j < len; j++) { - l.add(j); + // otherwise + { + int len = (int) (Math.random() * 1000); + for (int i = 0; i < len; i++) { + src.add(i); } ByteArrayOutputStream out = new ByteArrayOutputStream(); - new Packer(out).pack(l); + tmpl.pack(new Packer(out), src); MessagePackObject obj = Util.unpackOne(out.toByteArray()); - Template tmpl = new ListTemplate(IntegerTemplate.getInstance()); - List dst = (List) tmpl.convert(obj); - assertEquals(l.size(), dst.size()); - for (int j = 0; j < len; j++) { - assertEquals(l.get(j), dst.get(j)); - } - } - - for (int i = 0; i < 1000; i++) { - List l = new ArrayList(); - int len = (int) Math.random() % 1000 + 1; - for (int j = 0; j < len; j++) { - l.add(Integer.toString(j)); - } - ByteArrayOutputStream out = new ByteArrayOutputStream(); - new Packer(out).pack(l); - MessagePackObject obj = Util.unpackOne(out.toByteArray()); - Template tmpl = new ListTemplate(StringTemplate.getInstance()); - List dst = (List) tmpl.convert(obj); - assertEquals(l.size(), dst.size()); - for (int j = 0; j < len; j++) { - assertEquals(l.get(j), dst.get(j)); + List dst = (List) tmpl.convert(obj, null); + assertEquals(src.size(), dst.size()); + Integer[] src_array = src.toArray(new Integer[0]); + Integer[] dst_array = dst.toArray(new Integer[0]); + for (int i = 0; i < src_array.length; ++i) { + assertEquals(src_array[i], dst_array[i]); } + src.clear(); } } @@ -398,74 +544,64 @@ public class TestPackConvert extends TestCase { @Test public void testNullList() throws Exception { List src = null; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - new Packer(out).pack(src); - MessagePackObject obj = Util.unpackOne(out.toByteArray()); Template tmpl = new ListTemplate(StringTemplate.getInstance()); - List dst = null; + ByteArrayOutputStream out = new ByteArrayOutputStream(); + Packer packer = new Packer(out); try { - dst = (List) tmpl.convert(obj); + tmpl.pack(packer, src); + fail(); + } catch (Exception e) { + assertTrue(e instanceof MessageTypeException); + } + packer.pack(src); + MessagePackObject obj = Util.unpackOne(out.toByteArray()); + try { + tmpl.convert(obj, null); fail(); } catch (Exception e) { assertTrue(e instanceof MessageTypeException); } obj = Util.unpackOne(out.toByteArray()); - tmpl = new OptionalTemplate(new ListTemplate(StringTemplate - .getInstance())); - dst = (List) tmpl.convert(obj); + tmpl = new NullableTemplate(new ListTemplate(StringTemplate.getInstance())); + List dst = (List) tmpl.convert(obj, null); assertEquals(src, dst); } @SuppressWarnings("unchecked") @Test public void testMap() throws Exception { - Map emptyMap = new HashMap(); + Map src = new HashMap(); + Template tmpl = new MapTemplate( + IntegerTemplate.getInstance(), + IntegerTemplate.getInstance()); + // size is zero { ByteArrayOutputStream out = new ByteArrayOutputStream(); - new Packer(out).pack(emptyMap); + tmpl.pack(new Packer(out), src); MessagePackObject obj = Util.unpackOne(out.toByteArray()); - Template tmpl = new MapTemplate(IntegerTemplate.getInstance(), - IntegerTemplate.getInstance()); - Map dst = (Map) tmpl - .convert(obj); - assertEquals(emptyMap, dst); - } - - for (int i = 0; i < 1000; i++) { - Map m = new HashMap(); - int len = (int) Math.random() % 1000 + 1; - for (int j = 0; j < len; j++) { - m.put(j, j); - } - ByteArrayOutputStream out = new ByteArrayOutputStream(); - new Packer(out).pack(m); - MessagePackObject obj = Util.unpackOne(out.toByteArray()); - Template tmpl = new MapTemplate(IntegerTemplate.getInstance(), - IntegerTemplate.getInstance()); - Map map = (Map) tmpl - .convert(obj); - assertEquals(m.size(), map.size()); - for (Map.Entry pair : map.entrySet()) { - Integer val = m.get(pair.getKey()); + Map dst = (Map) tmpl.convert(obj, null); + assertEquals(src.size(), src.size()); + for (Map.Entry pair : dst.entrySet()) { + Integer val = src.get(pair.getKey()); assertNotNull(val); assertEquals(val, pair.getValue()); } + src.clear(); } - for (int i = 0; i < 1000; i++) { - Map m = new HashMap(); - int len = (int) Math.random() % 1000 + 1; - for (int j = 0; j < len; j++) - m.put(Integer.toString(j), j); + // otherwise + { + int len = (int) (Math.random() * 1000); + for (int j = 0; j < len; j++) { + src.put(j, j); + } ByteArrayOutputStream out = new ByteArrayOutputStream(); - new Packer(out).pack(m); + tmpl.pack(new Packer(out), src); MessagePackObject obj = Util.unpackOne(out.toByteArray()); - Template tmpl = new MapTemplate(StringTemplate.getInstance(), - IntegerTemplate.getInstance()); - Map map = (Map) tmpl.convert(obj); - assertEquals(m.size(), map.size()); - for (Map.Entry pair : map.entrySet()) { - Integer val = m.get(pair.getKey()); + Map dst = (Map) tmpl.convert(obj, null); + assertEquals(src.size(), dst.size()); + for (Map.Entry pair : dst.entrySet()) { + Integer val = src.get(pair.getKey()); assertNotNull(val); assertEquals(val, pair.getValue()); } @@ -476,22 +612,133 @@ public class TestPackConvert extends TestCase { @Test public void testNullMap() throws Exception { Map src = null; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - new Packer(out).pack(src); - MessagePackObject obj = Util.unpackOne(out.toByteArray()); - Template tmpl = new MapTemplate(StringTemplate.getInstance(), + Template tmpl = new MapTemplate( + StringTemplate.getInstance(), StringTemplate.getInstance()); - Map dst = null; + ByteArrayOutputStream out = new ByteArrayOutputStream(); + Packer packer = new Packer(out); try { - dst = (Map) tmpl.convert(obj); + tmpl.pack(packer, src); + fail(); + } catch (Exception e) { + assertTrue(e instanceof MessageTypeException); + } + packer.pack(src); + MessagePackObject obj = Util.unpackOne(out.toByteArray()); + try { + tmpl.convert(obj, null); fail(); } catch (Exception e) { assertTrue(e instanceof MessageTypeException); } obj = Util.unpackOne(out.toByteArray()); - tmpl = new OptionalTemplate(new MapTemplate(StringTemplate - .getInstance(), StringTemplate.getInstance())); - dst = (Map) tmpl.convert(obj); + tmpl = new NullableTemplate(new MapTemplate( + StringTemplate.getInstance(), + StringTemplate.getInstance())); + Map dst = (Map) tmpl.convert(obj, null); + assertEquals(src, dst); + } + + @SuppressWarnings("unchecked") + @Test + public void testCollectionLinkedList() throws Exception { + LinkedList src = new LinkedList(); + Template tmpl = new CollectionTemplate(IntegerTemplate.getInstance()); + // size is zero + { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + tmpl.pack(new Packer(out), src); + MessagePackObject obj = Util.unpackOne(out.toByteArray()); + LinkedList dst = (LinkedList) + tmpl.convert(obj, new LinkedList()); + assertEquals(src.getClass(), dst.getClass()); + assertEquals(src.size(), dst.size()); + src.clear(); + } + + // otherwise + { + int len = (int) Math.random() % 1000 + 1; + for (int j = 0; j < len; j++) { + src.add(j); + } + ByteArrayOutputStream out = new ByteArrayOutputStream(); + tmpl.pack(new Packer(out), src); + MessagePackObject obj = Util.unpackOne(out.toByteArray()); + LinkedList dst = (LinkedList) + tmpl.convert(obj, new LinkedList()); + assertEquals(src.getClass(), dst.getClass()); + assertEquals(src.size(), dst.size()); + for (int j = 0; j < len; j++) { + assertEquals(src.get(j), dst.get(j)); + } + src.clear(); + } + } + + @SuppressWarnings("unchecked") + @Test + public void testCollectionHashSet() throws Exception { + HashSet src = new HashSet(); + Template tmpl = new CollectionTemplate(IntegerTemplate.getInstance()); + // size is zero + { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + tmpl.pack(new Packer(out), src); + MessagePackObject obj = Util.unpackOne(out.toByteArray()); + HashSet dst = (HashSet) + tmpl.convert(obj, new HashSet()); + assertEquals(src.getClass(), dst.getClass()); + assertEquals(src.size(), dst.size()); + src.clear(); + } + + // otherwise + { + int len = (int) Math.random() % 1000 + 1; + for (int j = 0; j < len; j++) { + src.add(j); + } + ByteArrayOutputStream out = new ByteArrayOutputStream(); + tmpl.pack(new Packer(out), src); + MessagePackObject obj = Util.unpackOne(out.toByteArray()); + HashSet dst = (HashSet) + tmpl.convert(obj, new HashSet()); + assertEquals(src.getClass(), dst.getClass()); + assertEquals(src.size(), dst.size()); + Integer[] src_array = src.toArray(new Integer[0]); + Integer[] dst_array = dst.toArray(new Integer[0]); + for (int j = 0; j < len; j++) { + assertEquals(src_array[j], dst_array[j]); + } + src.clear(); + } + } + + @SuppressWarnings("unchecked") + @Test + public void testNullCollection() throws Exception { + Collection src = null; + Template tmpl = new CollectionTemplate(StringTemplate.getInstance()); + ByteArrayOutputStream out = new ByteArrayOutputStream(); + Packer packer = new Packer(out); + try { + tmpl.pack(packer, src); + fail(); + } catch (Throwable t) { + assertTrue(t instanceof MessageTypeException); + } + packer.pack(src); + MessagePackObject obj = Util.unpackOne(out.toByteArray()); + try { + tmpl.convert(obj, null); + fail(); + } catch (Throwable t) { + assertTrue(t instanceof MessageTypeException); + } + obj = Util.unpackOne(out.toByteArray()); + tmpl = new NullableTemplate(new CollectionTemplate(StringTemplate.getInstance())); + Collection dst = (Collection) tmpl.convert(obj, null); assertEquals(src, dst); } } diff --git a/java/src/test/java/org/msgpack/template/TestPackUnpack.java b/java/src/test/java/org/msgpack/template/TestPackUnpack.java index 29ee78d..1fe92b0 100644 --- a/java/src/test/java/org/msgpack/template/TestPackUnpack.java +++ b/java/src/test/java/org/msgpack/template/TestPackUnpack.java @@ -3,8 +3,12 @@ package org.msgpack.template; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.math.BigInteger; +import java.nio.ByteBuffer; import java.util.ArrayList; +import java.util.Collection; import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Random; @@ -33,33 +37,38 @@ public class TestPackUnpack extends TestCase { static void _testInteger(Integer src) throws Exception { ByteArrayOutputStream out = new ByteArrayOutputStream(); - new Packer(out).pack(src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); Template tmpl = IntegerTemplate.getInstance(); - Integer dst = (Integer) tmpl.unpack(new Unpacker(in)); + tmpl.pack(new Packer(out), src); + ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); + Integer dst = (Integer) tmpl.unpack(new Unpacker(in), null); assertEquals(src, dst); } @Test public void testNullInteger() throws Exception { + Template tmpl = IntegerTemplate.getInstance(); Integer src = null; ByteArrayOutputStream out = new ByteArrayOutputStream(); - new Packer(out).pack(src); - byte[] bytes = out.toByteArray(); - Template tmpl = null; - Unpacker unpacker = new Unpacker(); - Integer dst = null; + Packer packer = new Packer(out); + try { + tmpl.pack(packer, src); + fail(); + } catch (Exception e) { + assertTrue(e instanceof MessageTypeException); + } + packer.pack(src); + byte[] bytes = out.toByteArray(); + Unpacker unpacker = new Unpacker(); try { - tmpl = IntegerTemplate.getInstance(); unpacker.wrap(bytes); - dst = (Integer) tmpl.unpack(unpacker); + tmpl.unpack(unpacker, null); fail(); } catch (Exception e) { assertTrue(e instanceof MessageTypeException); } unpacker.wrap(bytes); - tmpl = new OptionalTemplate(IntegerTemplate.getInstance()); - dst = (Integer) tmpl.unpack(unpacker); + tmpl = new NullableTemplate(IntegerTemplate.getInstance()); + Integer dst = (Integer) tmpl.unpack(unpacker, null); assertEquals(src, dst); } @@ -80,33 +89,38 @@ public class TestPackUnpack extends TestCase { static void _testLong(Long src) throws Exception { ByteArrayOutputStream out = new ByteArrayOutputStream(); - new Packer(out).pack(src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); Template tmpl = LongTemplate.getInstance(); - Long dst = (Long) tmpl.unpack(new Unpacker(in)); + tmpl.pack(new Packer(out), src); + ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); + Long dst = (Long) tmpl.unpack(new Unpacker(in), null); assertEquals(src, dst); } @Test public void testNullLong() throws Exception { Long src = null; + Template tmpl = LongTemplate.getInstance(); ByteArrayOutputStream out = new ByteArrayOutputStream(); - new Packer(out).pack(src); - byte[] bytes = out.toByteArray(); - Template tmpl = null; - Unpacker unpacker = new Unpacker(); - Long dst = null; + Packer packer = new Packer(out); + try { + tmpl.pack(packer, src); + fail(); + } catch (Exception e) { + assertTrue(e instanceof MessageTypeException); + } + packer.pack(src); + byte[] bytes = out.toByteArray(); + Unpacker unpacker = new Unpacker(); try { - tmpl = LongTemplate.getInstance(); unpacker.wrap(bytes); - dst = (Long) tmpl.unpack(unpacker); + tmpl.unpack(unpacker, null); fail(); } catch (Exception e) { assertTrue(e instanceof MessageTypeException); } unpacker.wrap(bytes); - tmpl = new OptionalTemplate(LongTemplate.getInstance()); - dst = (Long) tmpl.unpack(unpacker); + tmpl = new NullableTemplate(LongTemplate.getInstance()); + Long dst = (Long) tmpl.unpack(unpacker, null); assertEquals(src, dst); } @@ -130,33 +144,38 @@ public class TestPackUnpack extends TestCase { static void _testBigInteger(BigInteger src) throws Exception { ByteArrayOutputStream out = new ByteArrayOutputStream(); - new Packer(out).pack((Object) src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); Template tmpl = BigIntegerTemplate.getInstance(); - BigInteger dst = (BigInteger) tmpl.unpack(new Unpacker(in)); + tmpl.pack(new Packer(out), src); + ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); + BigInteger dst = (BigInteger) tmpl.unpack(new Unpacker(in), null); assertEquals(src, dst); } @Test public void testNullBigInteger() throws Exception { BigInteger src = null; + Template tmpl = BigIntegerTemplate.getInstance(); ByteArrayOutputStream out = new ByteArrayOutputStream(); - new Packer(out).pack(src); - byte[] bytes = out.toByteArray(); - Template tmpl = null; - Unpacker unpacker = new Unpacker(); - BigInteger dst = null; + Packer packer = new Packer(out); + try { + tmpl.pack(packer, src); + fail(); + } catch (Exception e) { + assertTrue(e instanceof MessageTypeException); + } + packer.pack(src); + byte[] bytes = out.toByteArray(); + Unpacker unpacker = new Unpacker(); try { - tmpl = BigIntegerTemplate.getInstance(); unpacker.wrap(bytes); - dst = (BigInteger) tmpl.unpack(unpacker); + tmpl.unpack(unpacker, null); fail(); } catch (Exception e) { assertTrue(e instanceof MessageTypeException); } unpacker.wrap(bytes); - tmpl = new OptionalTemplate(BigIntegerTemplate.getInstance()); - dst = (BigInteger) tmpl.unpack(unpacker); + tmpl = new NullableTemplate(BigIntegerTemplate.getInstance()); + BigInteger dst = (BigInteger) tmpl.unpack(unpacker, null); assertEquals(src, dst); } @@ -179,13 +198,41 @@ public class TestPackUnpack extends TestCase { static void _testFloat(Float src) throws Exception { ByteArrayOutputStream out = new ByteArrayOutputStream(); - new Packer(out).pack(src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); Template tmpl = FloatTemplate.getInstance(); - Float dst = (Float) tmpl.unpack(new Unpacker(in)); + tmpl.pack(new Packer(out), src); + ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); + Float dst = (Float) tmpl.unpack(new Unpacker(in), null); assertEquals(src, dst, 10e-10); } + @Test + public void testNullFloat() throws Exception { + Double src = null; + Template tmpl = FloatTemplate.getInstance(); + ByteArrayOutputStream out = new ByteArrayOutputStream(); + Packer packer = new Packer(out); + try { + tmpl.pack(packer, src); + fail(); + } catch (Exception e) { + assertTrue(e instanceof MessageTypeException); + } + packer.pack(src); + byte[] bytes = out.toByteArray(); + Unpacker unpacker = new Unpacker(); + try { + unpacker.wrap(bytes); + tmpl.unpack(unpacker, null); + fail(); + } catch (Exception e) { + assertTrue(e instanceof MessageTypeException); + } + unpacker.wrap(bytes); + tmpl = new NullableTemplate(FloatTemplate.getInstance()); + Float dst = (Float) tmpl.unpack(unpacker, null); + assertEquals(src, dst); + } + @Test public void testDouble() throws Exception { _testDouble((double) 0.0); @@ -205,33 +252,38 @@ public class TestPackUnpack extends TestCase { static void _testDouble(Double src) throws Exception { ByteArrayOutputStream out = new ByteArrayOutputStream(); - new Packer(out).pack(src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); Template tmpl = DoubleTemplate.getInstance(); - Double dst = (Double) tmpl.unpack(new Unpacker(in)); + tmpl.pack(new Packer(out), src); + ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); + Double dst = (Double) tmpl.unpack(new Unpacker(in), null); assertEquals(src, dst, 10e-10); } @Test public void testNullDouble() throws Exception { Double src = null; + Template tmpl = DoubleTemplate.getInstance(); ByteArrayOutputStream out = new ByteArrayOutputStream(); - new Packer(out).pack(src); - byte[] bytes = out.toByteArray(); - Template tmpl = null; - Unpacker unpacker = new Unpacker(); - Double dst = null; + Packer packer = new Packer(out); + try { + tmpl.pack(packer, src); + fail(); + } catch (Exception e) { + assertTrue(e instanceof MessageTypeException); + } + packer.pack(src); + byte[] bytes = out.toByteArray(); + Unpacker unpacker = new Unpacker(); try { - tmpl = DoubleTemplate.getInstance(); unpacker.wrap(bytes); - dst = (Double) tmpl.unpack(unpacker); + tmpl.unpack(unpacker, null); fail(); } catch (Exception e) { assertTrue(e instanceof MessageTypeException); } unpacker.wrap(bytes); - tmpl = new OptionalTemplate(DoubleTemplate.getInstance()); - dst = (Double) tmpl.unpack(unpacker); + tmpl = new NullableTemplate(DoubleTemplate.getInstance()); + Double dst = (Double) tmpl.unpack(unpacker, null); assertEquals(src, dst); } @@ -243,36 +295,156 @@ public class TestPackUnpack extends TestCase { static void _testBoolean(Boolean src) throws Exception { ByteArrayOutputStream out = new ByteArrayOutputStream(); - new Packer(out).pack(src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); Template tmpl = BooleanTemplate.getInstance(); - Boolean dst = (Boolean) tmpl.unpack(new Unpacker(in)); + Packer packer = new Packer(out); + tmpl.pack(packer, src); + ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); + Boolean dst = (Boolean) tmpl.unpack(new Unpacker(in), null); assertEquals(src, dst); } @Test public void testNullBoolean() throws Exception { Boolean src = null; + Template tmpl = BooleanTemplate.getInstance(); ByteArrayOutputStream out = new ByteArrayOutputStream(); - new Packer(out).pack(src); - byte[] bytes = out.toByteArray(); - Template tmpl = null; - Unpacker unpacker = new Unpacker(); - Boolean dst = null; + Packer packer = new Packer(out); + try { + tmpl.pack(packer, src); + fail(); + } catch (Exception e) { + assertTrue(e instanceof MessageTypeException); + } + packer.pack(src); + byte[] bytes = out.toByteArray(); + Unpacker unpacker = new Unpacker(); try { - tmpl = BooleanTemplate.getInstance(); unpacker.wrap(bytes); - dst = (Boolean) tmpl.unpack(unpacker); + tmpl.unpack(unpacker, null); fail(); } catch (Exception e) { assertTrue(e instanceof MessageTypeException); } unpacker.wrap(bytes); - tmpl = new OptionalTemplate(BooleanTemplate.getInstance()); - dst = (Boolean) tmpl.unpack(unpacker); + tmpl = new NullableTemplate(BooleanTemplate.getInstance()); + Boolean dst = (Boolean) tmpl.unpack(unpacker, null); assertEquals(src, dst); } + @Test + public void testByteArray() throws Exception { + Random rand = new Random(System.currentTimeMillis()); + byte[] b0 = new byte[0]; + _testByteArray(b0); + byte[] b1 = new byte[10]; + rand.nextBytes(b1); + _testByteArray(b1); + byte[] b2 = new byte[1024]; + rand.nextBytes(b2); + _testByteArray(b2); + } + + static void _testByteArray(byte[] src) throws Exception { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + Template tmpl = ByteArrayTemplate.getInstance(); + tmpl.pack(new Packer(out), src); + ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); + byte[] dst = (byte[]) tmpl.unpack(new Unpacker(in), null); + assertEquals(src.length, dst.length); + for (int i = 0; i < src.length; ++i) { + assertEquals(src[i], dst[i]); + } + } + + @Test + public void testNullByteArray() throws Exception { + byte[] src = null; + Template tmpl = ByteArrayTemplate.getInstance(); + ByteArrayOutputStream out = new ByteArrayOutputStream(); + Packer packer = new Packer(out); + try { + tmpl.pack(packer, src); + fail(); + } catch (Exception e) { + assertTrue(e instanceof MessageTypeException); + } + packer.pack(src); + byte[] bytes = out.toByteArray(); + Unpacker unpacker = new Unpacker(); + try { + unpacker.wrap(bytes); + tmpl.unpack(unpacker, null); + fail(); + } catch (Exception e) { + assertTrue(e instanceof MessageTypeException); + } + unpacker.wrap(bytes); + tmpl = new NullableTemplate(BooleanTemplate.getInstance()); + byte[] dst = (byte[]) tmpl.unpack(unpacker, null); + assertEquals(null, dst); + } + + @Test + public void testByteBuffer() throws Exception { + Random rand = new Random(System.currentTimeMillis()); + byte[] b0 = new byte[0]; + ByteBuffer bb0 = ByteBuffer.wrap(b0); + _testByteBuffer(bb0); + bb0.clear(); + byte[] b1 = new byte[10]; + rand.nextBytes(b1); + ByteBuffer bb1 = ByteBuffer.wrap(b1); + _testByteBuffer(bb1); + bb1.clear(); + byte[] b2 = new byte[2048]; + rand.nextBytes(b2); + ByteBuffer bb2 = ByteBuffer.wrap(b2); + _testByteBuffer(bb2); + bb2.clear(); + } + + static void _testByteBuffer(ByteBuffer src) throws Exception { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + Template tmpl = ByteBufferTemplate.getInstance(); + tmpl.pack(new Packer(out), src); + ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); + ByteBuffer dst = (ByteBuffer) tmpl.unpack(new Unpacker(in), null); + assertEquals(src.limit() - src.position(), dst.limit() - dst.position()); + int dst_pos = dst.position(); + for (int i = src.position(); i < src.limit(); ++i) { + assertEquals(src.get(i), dst.get(dst_pos)); + dst_pos++; + } + } + + @Test + public void testNullByteBuffer() throws Exception { + ByteBuffer src = null; + Template tmpl = ByteBufferTemplate.getInstance(); + ByteArrayOutputStream out = new ByteArrayOutputStream(); + Packer packer = new Packer(out); + try { + tmpl.pack(packer, src); + fail(); + } catch (Exception e) { + assertTrue(e instanceof MessageTypeException); + } + packer.pack(src); + byte[] bytes = out.toByteArray(); + Unpacker unpacker = new Unpacker(); + try { + unpacker.wrap(bytes); + tmpl.unpack(unpacker, null); + fail(); + } catch (Exception e) { + assertTrue(e instanceof MessageTypeException); + } + unpacker.wrap(bytes); + tmpl = new NullableTemplate(BooleanTemplate.getInstance()); + ByteBuffer dst = (ByteBuffer) tmpl.unpack(unpacker, null); + assertEquals(null, dst); + } + @Test public void testString() throws Exception { _testString(""); @@ -313,83 +485,78 @@ public class TestPackUnpack extends TestCase { static void _testString(String src) throws Exception { ByteArrayOutputStream out = new ByteArrayOutputStream(); - new Packer(out).pack(src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); Template tmpl = StringTemplate.getInstance(); - String dst = (String) tmpl.unpack(new Unpacker(in)); + tmpl.pack(new Packer(out), src); + ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); + String dst = (String) tmpl.unpack(new Unpacker(in), null); assertEquals(src, dst); } @Test public void testNullString() throws Exception { String src = null; + Template tmpl = StringTemplate.getInstance(); ByteArrayOutputStream out = new ByteArrayOutputStream(); - new Packer(out).pack(src); - byte[] bytes = out.toByteArray(); - Template tmpl = null; - Unpacker unpacker = new Unpacker(); - String dst = null; + Packer packer = new Packer(out); + try { + tmpl.pack(packer, src); + fail(); + } catch (Exception e) { + assertTrue(e instanceof MessageTypeException); + } + packer.pack(src); + byte[] bytes = out.toByteArray(); + Unpacker unpacker = new Unpacker(); try { - tmpl = StringTemplate.getInstance(); unpacker.wrap(bytes); - dst = (String) tmpl.unpack(unpacker); + tmpl.unpack(unpacker, null); fail(); } catch (Exception e) { assertTrue(e instanceof MessageTypeException); } unpacker.wrap(bytes); - tmpl = new OptionalTemplate(StringTemplate.getInstance()); - dst = (String) tmpl.unpack(unpacker); + tmpl = new NullableTemplate(StringTemplate.getInstance()); + String dst = (String) tmpl.unpack(unpacker, null); assertEquals(src, dst); } @SuppressWarnings("unchecked") @Test public void testList() throws Exception { - List emptyList = new ArrayList(); + List src = new ArrayList(); + Template tmpl = new ListTemplate(IntegerTemplate.getInstance()); + // size is zero { ByteArrayOutputStream out = new ByteArrayOutputStream(); - new Packer(out).pack(emptyList); - ByteArrayInputStream in = new ByteArrayInputStream(out - .toByteArray()); - Template tmpl = new ListTemplate(IntegerTemplate.getInstance()); - List dst = (List) tmpl.unpack(new Unpacker(in)); - assertEquals(emptyList, dst); + tmpl.pack(new Packer(out), src); + ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); + List dst = (List) tmpl.unpack(new Unpacker(in), null); + assertEquals(src.size(), dst.size()); + Integer[] src_array = src.toArray(new Integer[0]); + Integer[] dst_array = dst.toArray(new Integer[0]); + for (int i = 0; i < src_array.length; ++i) { + assertEquals(src_array[i], dst_array[i]); + } + src.clear(); } - for (int i = 0; i < 1000; i++) { - List l = new ArrayList(); - int len = (int) Math.random() % 1000 + 1; - for (int j = 0; j < len; j++) { - l.add(j); + // otherwise + { + int len = (int) (Math.random() * 1000); + for (int i = 0; i < len; i++) { + src.add(i); } ByteArrayOutputStream out = new ByteArrayOutputStream(); - new Packer(out).pack(l); - ByteArrayInputStream in = new ByteArrayInputStream(out - .toByteArray()); - Template tmpl = new ListTemplate(IntegerTemplate.getInstance()); - List dst = (List) tmpl.unpack(new Unpacker(in)); - assertEquals(len, dst.size()); - for (int j = 0; j < len; j++) { - assertEquals(l.get(j), dst.get(j)); - } - } - - for (int i = 0; i < 1000; i++) { - List l = new ArrayList(); - int len = (int) Math.random() % 1000 + 1; - for (int j = 0; j < len; j++) - l.add(Integer.toString(j)); - ByteArrayOutputStream out = new ByteArrayOutputStream(); - new Packer(out).pack(l); - ByteArrayInputStream in = new ByteArrayInputStream(out - .toByteArray()); - Template tmpl = new ListTemplate(StringTemplate.getInstance()); - List dst = (List) tmpl.unpack(new Unpacker(in)); - assertEquals(len, dst.size()); - for (int j = 0; j < len; j++) { - assertEquals(l.get(j), dst.get(j)); + tmpl.pack(new Packer(out), src); + ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); + List dst = (List) tmpl.unpack(new Unpacker(in), null); + assertEquals(src.size(), dst.size()); + Integer[] src_array = src.toArray(new Integer[0]); + Integer[] dst_array = dst.toArray(new Integer[0]); + for (int i = 0; i < src_array.length; ++i) { + assertEquals(src_array[i], dst_array[i]); } + src.clear(); } } @@ -397,82 +564,68 @@ public class TestPackUnpack extends TestCase { @Test public void testNullList() throws Exception { List src = null; + Template tmpl = new ListTemplate(StringTemplate.getInstance()); ByteArrayOutputStream out = new ByteArrayOutputStream(); - new Packer(out).pack(src); - byte[] bytes = out.toByteArray(); - Template tmpl = null; - Unpacker unpacker = new Unpacker(); - List dst = null; + Packer packer = new Packer(out); + try { + tmpl.pack(packer, src); + fail(); + } catch (Exception e) { + assertTrue(e instanceof MessageTypeException); + } + packer.pack(src); + byte[] bytes = out.toByteArray(); + Unpacker unpacker = new Unpacker(); try { - tmpl = new ListTemplate(StringTemplate.getInstance()); unpacker.wrap(bytes); - dst = (List) tmpl.unpack(unpacker); + tmpl.unpack(unpacker, null); fail(); } catch (Exception e) { assertTrue(e instanceof MessageTypeException); } unpacker.wrap(bytes); - tmpl = new OptionalTemplate(new ListTemplate(StringTemplate - .getInstance())); - dst = (List) tmpl.unpack(unpacker); + tmpl = new NullableTemplate(new ListTemplate(StringTemplate.getInstance())); + List dst = (List) tmpl.unpack(unpacker, null); assertEquals(src, dst); } @SuppressWarnings("unchecked") @Test public void testMap() throws Exception { - Map emptyMap = new HashMap(); + Map src = new HashMap(); + Template tmpl = new MapTemplate( + IntegerTemplate.getInstance(), + IntegerTemplate.getInstance()); + // size is zero { ByteArrayOutputStream out = new ByteArrayOutputStream(); - new Packer(out).pack(emptyMap); - ByteArrayInputStream in = new ByteArrayInputStream(out - .toByteArray()); - Template tmpl = new MapTemplate(IntegerTemplate.getInstance(), - IntegerTemplate.getInstance()); - Map dst = (Map) tmpl - .unpack(new Unpacker(in)); - assertEquals(emptyMap, dst); - } - - for (int i = 0; i < 1000; i++) { - Map m = new HashMap(); - int len = (int) Math.random() % 1000 + 1; - for (int j = 0; j < len; j++) { - m.put(j, j); - } - ByteArrayOutputStream out = new ByteArrayOutputStream(); - new Packer(out).pack(m); - ByteArrayInputStream in = new ByteArrayInputStream(out - .toByteArray()); - Template tmpl = new MapTemplate(IntegerTemplate.getInstance(), - IntegerTemplate.getInstance()); - Map map = (Map) tmpl - .unpack(new Unpacker(in)); - assertEquals(len, map.size()); - for (Map.Entry pair : map.entrySet()) { - Integer val = m.get(pair.getKey()); + tmpl.pack(new Packer(out), src); + ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); + Map dst = (Map) + tmpl.unpack(new Unpacker(in), null); + assertEquals(src.size(), src.size()); + for (Map.Entry pair : dst.entrySet()) { + Integer val = src.get(pair.getKey()); assertNotNull(val); assertEquals(val, pair.getValue()); } + src.clear(); } - for (int i = 0; i < 1000; i++) { - Map m = new HashMap(); - int len = (int) Math.random() % 1000 + 1; + // otherwise + { + int len = (int) (Math.random() * 1000); for (int j = 0; j < len; j++) { - m.put(Integer.toString(j), j); + src.put(j, j); } ByteArrayOutputStream out = new ByteArrayOutputStream(); - new Packer(out).pack(m); - ByteArrayInputStream in = new ByteArrayInputStream(out - .toByteArray()); - Template tmpl = new MapTemplate(StringTemplate.getInstance(), - IntegerTemplate.getInstance()); - Map map = (Map) tmpl - .unpack(new Unpacker(in)); - assertEquals(m.size(), map.size()); - for (Map.Entry pair : map.entrySet()) { - Integer val = m.get(pair.getKey()); + tmpl.pack(new Packer(out), src); + ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); + Map dst = (Map) + tmpl.unpack(new Unpacker(in), null); + assertEquals(src.size(), dst.size()); + for (Map.Entry pair : dst.entrySet()) { + Integer val = src.get(pair.getKey()); assertNotNull(val); assertEquals(val, pair.getValue()); } @@ -483,25 +636,136 @@ public class TestPackUnpack extends TestCase { @Test public void testNullMap() throws Exception { Map src = null; + Template tmpl = new MapTemplate( + StringTemplate.getInstance(), + StringTemplate.getInstance()); ByteArrayOutputStream out = new ByteArrayOutputStream(); - new Packer(out).pack(src); - byte[] bytes = out.toByteArray(); - Template tmpl = null; - Unpacker unpacker = new Unpacker(); - Map dst = null; + Packer packer = new Packer(out); + try { + tmpl.pack(packer, src); + fail(); + } catch (Exception e) { + assertTrue(e instanceof MessageTypeException); + } + packer.pack(src); + byte[] bytes = out.toByteArray(); + Unpacker unpacker = new Unpacker(); try { - tmpl = new MapTemplate(StringTemplate.getInstance(), StringTemplate - .getInstance()); unpacker.wrap(bytes); - dst = (Map) tmpl.unpack(unpacker); + tmpl.unpack(unpacker, null); fail(); } catch (Exception e) { assertTrue(e instanceof MessageTypeException); } unpacker.wrap(bytes); - tmpl = new OptionalTemplate(new MapTemplate(StringTemplate + tmpl = new NullableTemplate(new MapTemplate(StringTemplate .getInstance(), StringTemplate.getInstance())); - dst = (Map) tmpl.unpack(unpacker); + Map dst = (Map) tmpl.unpack(unpacker, null); + assertEquals(src, dst); + } + + @SuppressWarnings("unchecked") + @Test + public void testCollectionLinkedList() throws Exception { + LinkedList src = new LinkedList(); + Template tmpl = new CollectionTemplate(IntegerTemplate.getInstance()); + // size is zero + { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + tmpl.pack(new Packer(out), src); + ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); + LinkedList dst = (LinkedList) + tmpl.unpack(new Unpacker(in), new LinkedList()); + assertEquals(src.getClass(), dst.getClass()); + assertEquals(src.size(), dst.size()); + src.clear(); + } + + // otherwise + { + int len = (int) Math.random() % 1000 + 1; + for (int j = 0; j < len; j++) { + src.add(j); + } + ByteArrayOutputStream out = new ByteArrayOutputStream(); + tmpl.pack(new Packer(out), src); + ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); + LinkedList dst = (LinkedList) + tmpl.unpack(new Unpacker(in), new LinkedList()); + assertEquals(src.getClass(), dst.getClass()); + assertEquals(src.size(), dst.size()); + for (int j = 0; j < len; j++) { + assertEquals(src.get(j), dst.get(j)); + } + src.clear(); + } + } + + @SuppressWarnings("unchecked") + @Test + public void testCollectionHashSet() throws Exception { + HashSet src = new HashSet(); + Template tmpl = new CollectionTemplate(IntegerTemplate.getInstance()); + // size is zero + { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + tmpl.pack(new Packer(out), src); + ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); + HashSet dst = (HashSet) + tmpl.unpack(new Unpacker(in), new HashSet()); + assertEquals(src.getClass(), dst.getClass()); + assertEquals(src.size(), dst.size()); + src.clear(); + } + + // otherwise + { + int len = (int) Math.random() % 1000 + 1; + for (int j = 0; j < len; j++) { + src.add(j); + } + ByteArrayOutputStream out = new ByteArrayOutputStream(); + tmpl.pack(new Packer(out), src); + ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); + HashSet dst = (HashSet) + tmpl.unpack(new Unpacker(in), new HashSet()); + assertEquals(src.getClass(), dst.getClass()); + assertEquals(src.size(), dst.size()); + Integer[] src_array = src.toArray(new Integer[0]); + Integer[] dst_array = dst.toArray(new Integer[0]); + for (int j = 0; j < len; j++) { + assertEquals(src_array[j], dst_array[j]); + } + src.clear(); + } + } + + @SuppressWarnings("unchecked") + @Test + public void testNullCollection() throws Exception { + Collection src = null; + Template tmpl = new CollectionTemplate(StringTemplate.getInstance()); + ByteArrayOutputStream out = new ByteArrayOutputStream(); + Packer packer = new Packer(out); + try { + tmpl.pack(packer, src); + fail(); + } catch (Throwable t) { + assertTrue(t instanceof MessageTypeException); + } + packer.pack(src); + byte[] bytes = out.toByteArray(); + Unpacker unpacker = new Unpacker(); + unpacker.wrap(bytes); + try { + tmpl.unpack(unpacker, null); + fail(); + } catch (Throwable t) { + assertTrue(t instanceof MessageTypeException); + } + unpacker.wrap(bytes); + tmpl = new NullableTemplate(new CollectionTemplate(StringTemplate.getInstance())); + Collection dst = (Collection) tmpl.unpack(unpacker, null); assertEquals(src, dst); } } diff --git a/java/src/test/java/org/msgpack/template/TestTemplateBuilderPackConvert.java b/java/src/test/java/org/msgpack/template/TestTemplateBuilderPackConvert.java new file mode 100644 index 0000000..a99fa26 --- /dev/null +++ b/java/src/test/java/org/msgpack/template/TestTemplateBuilderPackConvert.java @@ -0,0 +1,1396 @@ +package org.msgpack.template; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.math.BigInteger; +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import org.junit.Test; + +import org.msgpack.MessagePack; +import org.msgpack.MessagePackable; +import org.msgpack.MessagePacker; +import org.msgpack.MessageTypeException; +import org.msgpack.MessageUnpackable; +import org.msgpack.Packer; +import org.msgpack.Template; +import org.msgpack.Unpacker; +import org.msgpack.annotation.MessagePackMessage; +import org.msgpack.annotation.MessagePackOrdinalEnum; +import org.msgpack.annotation.Optional; + +import junit.framework.TestCase; + +public class TestTemplateBuilderPackConvert extends TestCase { + static { + MessagePack.register(PrimitiveTypeFieldsClass.class); + MessagePack.register(OptionalPrimitiveTypeFieldsClass.class); + MessagePack.register(GeneralReferenceTypeFieldsClass.class); + MessagePack.register(GeneralOptionalReferenceTypeFieldsClass.class); + MessagePack.register(SampleListTypes.class); + MessagePack.register(SampleOptionalListTypes.class); + MessagePack.register(SampleMapTypes.class); + MessagePack.register(SampleOptionalMapTypes.class); + MessagePack.register(SampleEnumFieldClass.class); + MessagePack.register(SampleOptionalEnumFieldClass.class); + MessagePack.register(FieldModifiersClass.class); + MessagePack.register(OptionalFieldModifiersClass.class); + MessagePack.register(BaseClass.class); + MessagePack.register(NestedClass.class); + MessagePack.register(BaseClass2.class); + MessagePack.register(OptionalBaseClass.class); + MessagePack.register(OptionalNestedClass.class); + MessagePack.register(OptionalBaseClass2.class); + MessagePack.register(SampleSubClass.class); + MessagePack.register(SampleSuperClass.class); + MessagePack.register(SampleOptionalSubClass.class); + MessagePack.register(SampleOptionalSuperClass.class); + MessagePack.register(BaseMessagePackableUnpackableClass.class); + MessagePack.register(MessagePackableUnpackableClass.class); + MessagePack.register(OptionalBaseMessagePackableUnpackableClass.class); + MessagePack.register(OptionalMessagePackableUnpackableClass.class); + } + + @Test + public void testPrimitiveTypeFields00() throws Exception { + PrimitiveTypeFieldsClass src = new PrimitiveTypeFieldsClass(); + src.f0 = (byte) 0; + src.f1 = 1; + src.f2 = 2; + src.f3 = 3; + src.f4 = 4; + src.f5 = 5; + src.f6 = false; + + byte[] raw = MessagePack.pack(src); + + PrimitiveTypeFieldsClass dst = + MessagePack.unpack(raw).convert(PrimitiveTypeFieldsClass.class); + assertEquals(src.f0, dst.f0); + assertEquals(src.f1, dst.f1); + assertEquals(src.f2, dst.f2); + assertEquals(src.f3, dst.f3); + assertEquals(src.f4, dst.f4); + assertEquals(src.f5, dst.f5); + assertEquals(src.f6, dst.f6); + } + + @Test + public void testPrimitiveTypeFields01() throws Exception { + PrimitiveTypeFieldsClass src = new PrimitiveTypeFieldsClass(); + + byte[] raw = MessagePack.pack(src); + + PrimitiveTypeFieldsClass dst = + MessagePack.unpack(raw).convert(PrimitiveTypeFieldsClass.class); + assertEquals(src.f0, dst.f0); + assertEquals(src.f1, dst.f1); + assertEquals(src.f2, dst.f2); + assertEquals(src.f3, dst.f3); + assertEquals(src.f4, dst.f4); + assertEquals(src.f5, dst.f5); + assertEquals(src.f6, dst.f6); + } + + @Test + public void testPrimitiveTypeFields02() throws Exception { + PrimitiveTypeFieldsClass src = null; + + byte[] raw = MessagePack.pack(src); + + PrimitiveTypeFieldsClass dst = + MessagePack.unpack(raw).convert(PrimitiveTypeFieldsClass.class); + assertEquals(src, dst); + } + + public static class PrimitiveTypeFieldsClass { + public byte f0; + public short f1; + public int f2; + public long f3; + public float f4; + public double f5; + public boolean f6; + + public PrimitiveTypeFieldsClass() { + } + } + + @Test + public void testOptionalPrimitiveTypeFields00() throws Exception { + OptionalPrimitiveTypeFieldsClass src = new OptionalPrimitiveTypeFieldsClass(); + src.f0 = (byte) 0; + src.f1 = 1; + src.f2 = 2; + src.f3 = 3; + src.f4 = 4; + src.f5 = 5; + src.f6 = false; + + byte[] raw = MessagePack.pack(src); + + PrimitiveTypeFieldsClass dst = + MessagePack.unpack(raw).convert(PrimitiveTypeFieldsClass.class); + assertEquals(src.f0, dst.f0); + assertEquals(src.f1, dst.f1); + assertEquals(src.f2, dst.f2); + assertEquals(src.f3, dst.f3); + assertEquals(src.f4, dst.f4); + assertEquals(src.f5, dst.f5); + assertEquals(src.f6, dst.f6); + } + + @Test + public void testOptionalPrimitiveTypeFields01() throws Exception { + OptionalPrimitiveTypeFieldsClass src = new OptionalPrimitiveTypeFieldsClass(); + + byte[] raw = MessagePack.pack(src); + + OptionalPrimitiveTypeFieldsClass dst = + MessagePack.unpack(raw).convert(OptionalPrimitiveTypeFieldsClass.class); + assertEquals(src.f0, dst.f0); + assertEquals(src.f1, dst.f1); + assertEquals(src.f2, dst.f2); + assertEquals(src.f3, dst.f3); + assertEquals(src.f4, dst.f4); + assertEquals(src.f5, dst.f5); + assertEquals(src.f6, dst.f6); + } + + @Test + public void testOptionalPrimitiveTypeFields02() throws Exception { + OptionalPrimitiveTypeFieldsClass src = null; + + byte[] raw = MessagePack.pack(src); + + OptionalPrimitiveTypeFieldsClass dst = + MessagePack.unpack(raw).convert(OptionalPrimitiveTypeFieldsClass.class); + assertEquals(src, dst); + } + + public static class OptionalPrimitiveTypeFieldsClass { + @Optional + public byte f0; + @Optional + public short f1; + @Optional + public int f2; + @Optional + public long f3; + @Optional + public float f4; + @Optional + public double f5; + @Optional + public boolean f6; + + public OptionalPrimitiveTypeFieldsClass() { + } + } + + @Test + public void testGeneralReferenceTypeFieldsClass00() throws Exception { + GeneralReferenceTypeFieldsClass src = new GeneralReferenceTypeFieldsClass(); + src.f0 = 0; + src.f1 = 1; + src.f2 = 2; + src.f3 = (long) 3; + src.f4 = (float) 4; + src.f5 = (double) 5; + src.f6 = false; + src.f7 = new BigInteger("7"); + src.f8 = "8"; + src.f9 = new byte[] { 0x01, 0x02 }; + src.f10 = ByteBuffer.wrap("muga".getBytes()); + + byte[] raw = MessagePack.pack(src); + + GeneralReferenceTypeFieldsClass dst = + MessagePack.unpack(raw).convert(GeneralReferenceTypeFieldsClass.class); + assertEquals(src.f0, dst.f0); + assertEquals(src.f1, dst.f1); + assertEquals(src.f2, dst.f2); + assertEquals(src.f3, dst.f3); + assertEquals(src.f4, dst.f4); + assertEquals(src.f5, dst.f5); + assertEquals(src.f6, dst.f6); + assertEquals(src.f7, dst.f7); + assertEquals(src.f8, dst.f8); + assertEquals(src.f9[0], dst.f9[0]); + assertEquals(src.f9[1], dst.f9[1]); + assertEquals(src.f10, dst.f10); + } + + @Test + public void testGeneralReferenceTypeFieldsClass01() throws Exception { + GeneralReferenceTypeFieldsClass src = null; + + byte[] raw = MessagePack.pack(src); + + GeneralReferenceTypeFieldsClass dst = + MessagePack.unpack(raw).convert(GeneralReferenceTypeFieldsClass.class); + assertEquals(src, dst); + } + + public static class GeneralReferenceTypeFieldsClass { + public Byte f0; + public Short f1; + public Integer f2; + public Long f3; + public Float f4; + public Double f5; + public Boolean f6; + public BigInteger f7; + public String f8; + public byte[] f9; + public ByteBuffer f10; + + public GeneralReferenceTypeFieldsClass() { + } + } + + @Test + public void testGeneralOptionalReferenceTypeFieldsClass00() + throws Exception { + GeneralOptionalReferenceTypeFieldsClass src = new GeneralOptionalReferenceTypeFieldsClass(); + src.f0 = 0; + src.f1 = 1; + src.f2 = 2; + src.f3 = (long) 3; + src.f4 = (float) 4; + src.f5 = (double) 5; + src.f6 = false; + src.f7 = new BigInteger("7"); + src.f8 = "8"; + src.f9 = new byte[] { 0x01, 0x02 }; + src.f10 = ByteBuffer.wrap("muga".getBytes()); + + byte[] raw = MessagePack.pack(src); + + GeneralOptionalReferenceTypeFieldsClass dst = + MessagePack.unpack(raw).convert(GeneralOptionalReferenceTypeFieldsClass.class); + assertEquals(src.f0, dst.f0); + assertEquals(src.f1, dst.f1); + assertEquals(src.f2, dst.f2); + assertEquals(src.f3, dst.f3); + assertEquals(src.f4, dst.f4); + assertEquals(src.f5, dst.f5); + assertEquals(src.f6, dst.f6); + assertEquals(src.f7, dst.f7); + assertEquals(src.f8, dst.f8); + assertEquals(src.f9[0], dst.f9[0]); + assertEquals(src.f9[1], dst.f9[1]); + assertEquals(src.f10, dst.f10); + } + + @Test + public void testGeneralOptionalReferenceTypeFieldsClass01() + throws Exception { + GeneralOptionalReferenceTypeFieldsClass src = new GeneralOptionalReferenceTypeFieldsClass(); + src.f0 = null; + src.f1 = null; + src.f2 = null; + src.f3 = null; + src.f4 = null; + src.f5 = null; + src.f6 = null; + src.f7 = null; + src.f8 = null; + src.f9 = null; + src.f10 = null; + + byte[] raw = MessagePack.pack(src); + + GeneralOptionalReferenceTypeFieldsClass dst = + MessagePack.unpack(raw).convert(GeneralOptionalReferenceTypeFieldsClass.class); + assertEquals(src.f0, dst.f0); + assertEquals(src.f1, dst.f1); + assertEquals(src.f2, dst.f2); + assertEquals(src.f3, dst.f3); + assertEquals(src.f4, dst.f4); + assertEquals(src.f5, dst.f5); + assertEquals(src.f6, dst.f6); + assertEquals(src.f7, dst.f7); + assertEquals(src.f8, dst.f8); + assertEquals(src.f9, dst.f9); + assertEquals(src.f10, dst.f10); + } + + @Test + public void testGeneralOptionalReferenceTypeFieldsClass02() + throws Exception { + GeneralOptionalReferenceTypeFieldsClass src = null; + + byte[] raw = MessagePack.pack(src); + + GeneralOptionalReferenceTypeFieldsClass dst = + MessagePack.unpack(raw).convert(GeneralOptionalReferenceTypeFieldsClass.class); + assertEquals(src, dst); + } + + public static class GeneralOptionalReferenceTypeFieldsClass { + @Optional + public Byte f0; + @Optional + public Short f1; + @Optional + public Integer f2; + @Optional + public Long f3; + @Optional + public Float f4; + @Optional + public Double f5; + @Optional + public Boolean f6; + @Optional + public BigInteger f7; + @Optional + public String f8; + @Optional + public byte[] f9; + @Optional + public ByteBuffer f10; + + public GeneralOptionalReferenceTypeFieldsClass() { + } + } + + @Test + public void testListTypes00() throws Exception { + SampleListTypes src = new SampleListTypes(); + src.f0 = new ArrayList(); + src.f1 = new ArrayList(); + src.f1.add(1); + src.f1.add(2); + src.f1.add(3); + src.f2 = new ArrayList(); + src.f2.add("e1"); + src.f2.add("e2"); + src.f2.add("e3"); + src.f3 = new ArrayList>(); + src.f3.add(src.f2); + src.f4 = new ArrayList(); + SampleListNestedType slnt = new SampleListNestedType(); + slnt.f0 = new byte[] { 0x01, 0x02 }; + slnt.f1 = "muga"; + src.f4.add(slnt); + src.f5 = new ArrayList(); + src.f5.add(ByteBuffer.wrap("e1".getBytes())); + src.f5.add(ByteBuffer.wrap("e2".getBytes())); + src.f5.add(ByteBuffer.wrap("e3".getBytes())); + + byte[] raw = MessagePack.pack(src); + + SampleListTypes dst = + MessagePack.unpack(raw).convert(SampleListTypes.class); + for (int i = 0; i < src.f1.size(); ++i) { + assertEquals(src.f1.get(i), dst.f1.get(i)); + } + assertEquals(src.f2.size(), dst.f2.size()); + for (int i = 0; i < src.f2.size(); ++i) { + assertEquals(src.f2.get(i), dst.f2.get(i)); + } + assertEquals(src.f3.size(), dst.f3.size()); + for (int i = 0; i < src.f3.size(); ++i) { + List srclist = src.f3.get(i); + List dstlist = dst.f3.get(i); + assertEquals(srclist.size(), dstlist.size()); + for (int j = 0; j < srclist.size(); ++j) { + assertEquals(srclist.get(j), dstlist.get(j)); + } + } + assertEquals(src.f4.size(), dst.f4.size()); + for (int i = 0; i < src.f4.size(); ++i) { + SampleListNestedType s = src.f4.get(i); + SampleListNestedType d = dst.f4.get(i); + assertEquals(s.f0[0], d.f0[0]); + assertEquals(s.f0[1], d.f0[1]); + assertEquals(s.f1, d.f1); + } + assertEquals(src.f5.size(), dst.f5.size()); + for (int i = 0; i < src.f5.size(); ++i) { + ByteBuffer s = src.f5.get(i); + ByteBuffer d = dst.f5.get(i); + assertEquals(s, d); + } + } + + @Test + public void testListTypes01() throws Exception { + SampleListTypes src = null; + + byte[] raw = MessagePack.pack(src); + + SampleListTypes dst = + MessagePack.unpack(raw).convert(SampleListTypes.class); + assertEquals(src, dst); + } + + public static class SampleListTypes { + public List f0; + public List f1; + public List f2; + public List> f3; + public List f4; + public List f5; + + public SampleListTypes() { + } + } + + @MessagePackMessage + public static class SampleListNestedType { + public byte[] f0; + public String f1; + + public SampleListNestedType() { + } + } + + @Test + public void testOptionalListTypes00() throws Exception { + SampleOptionalListTypes src = new SampleOptionalListTypes(); + src.f0 = new ArrayList(); + src.f1 = new ArrayList(); + src.f1.add(1); + src.f1.add(2); + src.f1.add(3); + src.f2 = new ArrayList(); + src.f2.add("e1"); + src.f2.add("e2"); + src.f2.add("e3"); + src.f3 = new ArrayList>(); + src.f3.add(src.f2); + src.f4 = new ArrayList(); + SampleOptionalListNestedType slnt = new SampleOptionalListNestedType(); + slnt.f0 = new byte[] { 0x01, 0x02 }; + slnt.f1 = "muga"; + src.f4.add(slnt); + src.f5 = new ArrayList(); + src.f5.add(ByteBuffer.wrap("e1".getBytes())); + src.f5.add(ByteBuffer.wrap("e2".getBytes())); + src.f5.add(ByteBuffer.wrap("e3".getBytes())); + + byte[] raw = MessagePack.pack(src); + + SampleOptionalListTypes dst = + MessagePack.unpack(raw).convert(SampleOptionalListTypes.class); + assertEquals(src.f0.size(), dst.f0.size()); + assertEquals(src.f1.size(), dst.f1.size()); + for (int i = 0; i < src.f1.size(); ++i) { + assertEquals(src.f1.get(i), dst.f1.get(i)); + } + assertEquals(src.f2.size(), dst.f2.size()); + for (int i = 0; i < src.f2.size(); ++i) { + assertEquals(src.f2.get(i), dst.f2.get(i)); + } + assertEquals(src.f3.size(), dst.f3.size()); + for (int i = 0; i < src.f3.size(); ++i) { + List srclist = src.f3.get(i); + List dstlist = dst.f3.get(i); + assertEquals(srclist.size(), dstlist.size()); + for (int j = 0; j < srclist.size(); ++j) { + assertEquals(srclist.get(j), dstlist.get(j)); + } + } + assertEquals(src.f4.size(), dst.f4.size()); + for (int i = 0; i < src.f4.size(); ++i) { + SampleOptionalListNestedType s = src.f4.get(i); + SampleOptionalListNestedType d = dst.f4.get(i); + assertEquals(s.f0[0], d.f0[0]); + assertEquals(s.f0[1], d.f0[1]); + assertEquals(s.f1, d.f1); + } + assertEquals(src.f5.size(), dst.f5.size()); + for (int i = 0; i < src.f5.size(); ++i) { + ByteBuffer s = src.f5.get(i); + ByteBuffer d = dst.f5.get(i); + assertEquals(s, d); + } + } + + @Test + public void testOptionalListTypes01() throws Exception { + SampleOptionalListTypes src = new SampleOptionalListTypes(); + src.f0 = new ArrayList(); + src.f1 = null; + src.f2 = new ArrayList(); + src.f3 = new ArrayList>(); + src.f4 = null; + src.f5 = new ArrayList(); + + byte[] raw = MessagePack.pack(src); + + SampleOptionalListTypes dst = + MessagePack.unpack(raw).convert(SampleOptionalListTypes.class); + assertEquals(src.f0.size(), dst.f0.size()); + assertEquals(src.f1, dst.f1); + assertEquals(src.f2.size(), dst.f2.size()); + assertEquals(src.f3.size(), dst.f3.size()); + assertEquals(src.f4, dst.f4); + assertEquals(src.f5.size(), dst.f5.size()); + } + + @Test + public void testOptionalListTypes02() throws Exception { + SampleListTypes src = null; + + byte[] raw = MessagePack.pack(src); + + SampleListTypes dst = + MessagePack.unpack(raw).convert(SampleListTypes.class); + assertEquals(src, dst); + } + + public static class SampleOptionalListTypes { + @Optional + public List f0; + @Optional + public List f1; + @Optional + public List f2; + @Optional + public List> f3; + @Optional + public List f4; + @Optional + public List f5; + + public SampleOptionalListTypes() { + } + } + + @MessagePackMessage + public static class SampleOptionalListNestedType { + @Optional + public byte[] f0; + @Optional + public String f1; + + public SampleOptionalListNestedType() { + } + } + + @Test + public void testMapTypes00() throws Exception { + SampleMapTypes src = new SampleMapTypes(); + src.f0 = new HashMap(); + src.f1 = new HashMap(); + src.f1.put(1, 1); + src.f1.put(2, 2); + src.f1.put(3, 3); + src.f2 = new HashMap(); + src.f2.put("k1", 1); + src.f2.put("k2", 2); + src.f2.put("k3", 3); + + byte[] raw = MessagePack.pack(src); + + SampleMapTypes dst = + MessagePack.unpack(raw).convert(SampleMapTypes.class); + Iterator srcf1 = src.f1.keySet().iterator(); + Iterator dstf1 = dst.f1.keySet().iterator(); + while (srcf1.hasNext()) { + Integer s1 = srcf1.next(); + Integer d1 = dstf1.next(); + assertEquals(s1, d1); + assertEquals(src.f1.get(s1), dst.f1.get(d1)); + } + assertEquals(src.f2.size(), dst.f2.size()); + Iterator srcf2 = src.f2.keySet().iterator(); + Iterator dstf2 = dst.f2.keySet().iterator(); + while (srcf2.hasNext()) { + String s2 = srcf2.next(); + String d2 = dstf2.next(); + assertEquals(s2, d2); + assertEquals(src.f2.get(s2), dst.f2.get(d2)); + } + } + + @Test + public void testMapTypes01() throws Exception { + SampleMapTypes src = null; + + byte[] raw = MessagePack.pack(src); + + SampleMapTypes dst = + MessagePack.unpack(raw).convert(SampleMapTypes.class); + assertEquals(src, dst); + } + + public static class SampleMapTypes { + public Map f0; + public Map f1; + public Map f2; + + public SampleMapTypes() { + } + } + + @Test + public void testOptionalMapTypes00() throws Exception { + SampleOptionalMapTypes src = new SampleOptionalMapTypes(); + src.f0 = new HashMap(); + src.f1 = new HashMap(); + src.f1.put(1, 1); + src.f1.put(2, 2); + src.f1.put(3, 3); + src.f2 = new HashMap(); + src.f2.put("k1", 1); + src.f2.put("k2", 2); + src.f2.put("k3", 3); + + byte[] raw = MessagePack.pack(src); + + SampleOptionalMapTypes dst = + MessagePack.unpack(raw).convert(SampleOptionalMapTypes.class); + assertEquals(src.f0.size(), dst.f0.size()); + assertEquals(src.f1.size(), dst.f1.size()); + Iterator srcf1 = src.f1.keySet().iterator(); + Iterator dstf1 = dst.f1.keySet().iterator(); + while (srcf1.hasNext()) { + Integer s1 = srcf1.next(); + Integer d1 = dstf1.next(); + assertEquals(s1, d1); + assertEquals(src.f1.get(s1), dst.f1.get(d1)); + } + assertEquals(src.f2.size(), dst.f2.size()); + Iterator srcf2 = src.f2.keySet().iterator(); + Iterator dstf2 = dst.f2.keySet().iterator(); + while (srcf2.hasNext()) { + String s2 = srcf2.next(); + String d2 = dstf2.next(); + assertEquals(s2, d2); + assertEquals(src.f2.get(s2), dst.f2.get(d2)); + } + } + + @Test + public void testOptionalMapTypes01() throws Exception { + SampleOptionalMapTypes src = new SampleOptionalMapTypes(); + src.f0 = new HashMap(); + src.f1 = null; + src.f2 = new HashMap(); + + byte[] raw = MessagePack.pack(src); + + SampleOptionalMapTypes dst = + MessagePack.unpack(raw).convert(SampleOptionalMapTypes.class); + assertEquals(src.f0.size(), dst.f0.size()); + assertEquals(src.f1, dst.f1); + assertEquals(src.f2.size(), dst.f2.size()); + } + + @Test + public void testOptionalMapTypes02() throws Exception { + SampleOptionalMapTypes src = null; + + byte[] raw = MessagePack.pack(src); + + SampleOptionalMapTypes dst = + MessagePack.unpack(raw).convert(SampleOptionalMapTypes.class); + assertEquals(src, dst); + } + + public static class SampleOptionalMapTypes { + @Optional + public Map f0; + @Optional + public Map f1; + @Optional + public Map f2; + + public SampleOptionalMapTypes() { + } + } + + @Test + public void testFinalClass() throws Exception { + try { + TemplateBuilder.build(FinalModifierClass.class); + assertTrue(true); + } catch (TemplateBuildException e) { + fail(); + } + assertTrue(true); + } + + public final static class FinalModifierClass { + } + + public abstract static class AbstractModifierClass { + } + + @Test + public void testInterfaceType00() throws Exception { + try { + TemplateBuilder.build(SampleInterface.class); + fail(); + } catch (TemplateBuildException e) { + assertTrue(true); + } + assertTrue(true); + } + + @Test + public void testInterfaceType01() throws Exception { + try { + TemplateBuilder.build(SampleInterface.class); + fail(); + } catch (TemplateBuildException e) { + assertTrue(true); + } + assertTrue(true); + } + + public interface SampleInterface { + } + + @Test + public void testEnumTypeForOrdinal00() throws Exception { + SampleEnumFieldClass src = new SampleEnumFieldClass(); + src.f0 = 0; + src.f1 = SampleEnum.ONE; + + byte[] raw = MessagePack.pack(src); + + SampleEnumFieldClass dst = + MessagePack.unpack(raw).convert(SampleEnumFieldClass.class); + assertTrue(src.f1 == dst.f1); + } + + @Test + public void testEnumTypeForOrdinal01() throws Exception { + SampleEnumFieldClass src = null; + + byte[] raw = MessagePack.pack(src); + + SampleEnumFieldClass dst = + MessagePack.unpack(raw).convert(SampleEnumFieldClass.class); + assertEquals(src, dst); + } + + public static class SampleEnumFieldClass { + public int f0; + + public SampleEnum f1; + + public SampleEnumFieldClass() { + } + } + + @MessagePackOrdinalEnum + public enum SampleEnum { + ONE, TWO, THREE; + } + + @Test + public void testOptionalEnumTypeForOrdinal00() throws Exception { + SampleOptionalEnumFieldClass src = new SampleOptionalEnumFieldClass(); + src.f0 = 0; + src.f1 = SampleOptionalEnum.ONE; + + byte[] raw = MessagePack.pack(src); + + SampleOptionalEnumFieldClass dst = + MessagePack.unpack(raw).convert(SampleOptionalEnumFieldClass.class); + assertTrue(src.f0 == dst.f0); + assertTrue(src.f1 == dst.f1); + } + + @Test + public void testOptionalEnumTypeForOrdinal01() throws Exception { + SampleOptionalEnumFieldClass src = new SampleOptionalEnumFieldClass(); + src.f1 = null; + + byte[] raw = MessagePack.pack(src); + + SampleOptionalEnumFieldClass dst = + MessagePack.unpack(raw).convert(SampleOptionalEnumFieldClass.class); + assertTrue(src.f0 == dst.f0); + assertEquals(src.f1, dst.f1); + } + + @Test + public void testOptionalEnumTypeForOrdinal02() throws Exception { + SampleEnumFieldClass src = null; + + byte[] raw = MessagePack.pack(src); + + SampleEnumFieldClass dst = + MessagePack.unpack(raw).convert(SampleEnumFieldClass.class); + assertEquals(src, dst); + } + + public static class SampleOptionalEnumFieldClass { + @Optional + public int f0; + + @Optional + public SampleOptionalEnum f1; + + public SampleOptionalEnumFieldClass() { + } + } + + @MessagePackOrdinalEnum + public enum SampleOptionalEnum { + ONE, TWO, THREE; + } + + @Test + public void testFieldModifiers() throws Exception { + FieldModifiersClass src = new FieldModifiersClass(); + src.f0 = 0; + src.f2 = 2; + src.f3 = 3; + src.f4 = 4; + + byte[] raw = MessagePack.pack(src); + + FieldModifiersClass dst = + MessagePack.unpack(raw).convert(FieldModifiersClass.class); + assertTrue(src.f1 == dst.f1); + assertTrue(src.f2 != dst.f2); + assertTrue(src.f3 != dst.f3); + assertTrue(src.f4 != dst.f4); + } + + public static class FieldModifiersClass { + public int f0; + public final int f1 = 1; + private int f2; + protected int f3; + int f4; + + public FieldModifiersClass() { + } + } + + @Test + public void testOptionalFieldModifiers() throws Exception { + OptionalFieldModifiersClass src = new OptionalFieldModifiersClass(); + src.f0 = 0; + src.f2 = 2; + src.f3 = 3; + src.f4 = 4; + + byte[] raw = MessagePack.pack(src); + + OptionalFieldModifiersClass dst = + MessagePack.unpack(raw).convert(OptionalFieldModifiersClass.class); + assertTrue(src.f0 == dst.f0); + assertTrue(src.f1 == dst.f1); + assertTrue(src.f2 != dst.f2); + assertTrue(src.f3 != dst.f3); + assertTrue(src.f4 != dst.f4); + } + + public static class OptionalFieldModifiersClass { + @Optional + public int f0; + @Optional + public final int f1 = 1; + private int f2; + protected int f3; + int f4; + + public OptionalFieldModifiersClass() { + } + } + + @Test + public void testNestedFieldClass00() throws Exception { + BaseClass src = new BaseClass(); + NestedClass src2 = new NestedClass(); + src.f0 = 0; + src2.f2 = 2; + src.f1 = src2; + + byte[] raw = MessagePack.pack(src); + + BaseClass dst = + MessagePack.unpack(raw).convert(BaseClass.class); + assertTrue(src.f0 == dst.f0); + assertTrue(src.f1.f2 == dst.f1.f2); + } + + @Test + public void testNestedFieldClass01() throws Exception { + BaseClass src = null; + + byte[] raw = MessagePack.pack(src); + + BaseClass dst = + MessagePack.unpack(raw).convert(BaseClass.class); + assertEquals(src, dst); + } + + public static class BaseClass { + public int f0; + public NestedClass f1; + + public BaseClass() { + } + } + + public static class NestedClass { + public int f2; + + public NestedClass() { + } + } + + @Test + public void testOptionalNestedFieldClass00() throws Exception { + OptionalBaseClass src = new OptionalBaseClass(); + OptionalNestedClass src2 = new OptionalNestedClass(); + src.f0 = 0; + src2.f2 = 2; + src.f1 = src2; + + byte[] raw = MessagePack.pack(src); + + OptionalBaseClass dst = + MessagePack.unpack(raw).convert(OptionalBaseClass.class); + assertTrue(src.f0 == dst.f0); + assertTrue(src.f1.f2 == dst.f1.f2); + } + + @Test + public void testOptionalNestedFieldClass01() throws Exception { + OptionalBaseClass src = new OptionalBaseClass(); + src.f1 = null; + + byte[] raw = MessagePack.pack(src); + + OptionalBaseClass dst = + MessagePack.unpack(raw).convert(OptionalBaseClass.class); + assertTrue(src.f0 == dst.f0); + assertTrue(src.f1 == dst.f1); + } + + @Test + public void testOptionalNestedFieldClass02() throws Exception { + OptionalBaseClass src = null; + + byte[] raw = MessagePack.pack(src); + + OptionalBaseClass dst = + MessagePack.unpack(raw).convert(OptionalBaseClass.class); + assertEquals(src, dst); + } + + public static class OptionalBaseClass { + @Optional + public int f0; + @Optional + public OptionalNestedClass f1; + + public OptionalBaseClass() { + } + } + + public static class OptionalNestedClass { + @Optional + public int f2; + + public OptionalNestedClass() { + } + } + + @Test + public void testMessagePackMessageFieldClass00() throws Exception { + BaseClass2 src = new BaseClass2(); + MessagePackMessageClass2 src2 = new MessagePackMessageClass2(); + src.f0 = 0; + src2.f2 = 2; + src.f1 = src2; + + byte[] raw = MessagePack.pack(src); + + BaseClass2 dst = + MessagePack.unpack(raw).convert(BaseClass2.class); + assertTrue(src.f0 == dst.f0); + assertTrue(src.f1.f2 == dst.f1.f2); + } + + @Test + public void testMessagePackMessageFieldClass01() throws Exception { + BaseClass2 src = null; + + byte[] raw = MessagePack.pack(src); + + BaseClass2 dst = + MessagePack.unpack(raw).convert(BaseClass2.class); + assertEquals(src, dst); + } + + public static class BaseClass2 { + public int f0; + public MessagePackMessageClass2 f1; + + public BaseClass2() { + } + } + + @MessagePackMessage + public static class MessagePackMessageClass2 { + public int f2; + + public MessagePackMessageClass2() { + } + } + + @Test + public void testOptionalMessagePackMessageFieldClass00() throws Exception { + OptionalBaseClass2 src = new OptionalBaseClass2(); + OptionalMessagePackMessageClass2 src2 = new OptionalMessagePackMessageClass2(); + src.f0 = 0; + src2.f2 = 2; + src.f1 = src2; + + byte[] raw = MessagePack.pack(src); + + OptionalBaseClass2 dst = + MessagePack.unpack(raw).convert(OptionalBaseClass2.class); + assertTrue(src.f0 == dst.f0); + assertTrue(src.f1.f2 == dst.f1.f2); + } + + @Test + public void testOptionalMessagePackMessageFieldClass01() throws Exception { + OptionalBaseClass2 src = new OptionalBaseClass2(); + src.f1 = null; + + byte[] raw = MessagePack.pack(src); + + OptionalBaseClass2 dst = + MessagePack.unpack(raw).convert(OptionalBaseClass2.class); + assertTrue(src.f0 == dst.f0); + assertEquals(src.f1, dst.f1); + } + + @Test + public void testOptionalMessagePackMessageFieldClass02() throws Exception { + OptionalBaseClass2 src = null; + + byte[] raw = MessagePack.pack(src); + + OptionalBaseClass2 dst = + MessagePack.unpack(raw).convert(OptionalBaseClass2.class); + assertEquals(src, dst); + } + + public static class OptionalBaseClass2 { + @Optional + public int f0; + @Optional + public OptionalMessagePackMessageClass2 f1; + + public OptionalBaseClass2() { + } + } + + @MessagePackMessage + public static class OptionalMessagePackMessageClass2 { + @Optional + public int f2; + + public OptionalMessagePackMessageClass2() { + } + } + + @Test + public void testExtendedClass00() throws Exception { + SampleSubClass src = new SampleSubClass(); + src.f0 = 0; + src.f2 = 2; + src.f3 = 3; + src.f4 = 4; + src.f5 = 5; + src.f8 = 8; + src.f9 = 9; + + byte[] raw = MessagePack.pack(src); + + SampleSubClass dst = + MessagePack.unpack(raw).convert(SampleSubClass.class); + assertTrue(src.f0 == dst.f0); + assertTrue(src.f1 == dst.f1); + assertTrue(src.f2 != dst.f2); + assertTrue(src.f3 != dst.f3); + assertTrue(src.f4 != dst.f4); + assertTrue(src.f5 == dst.f5); + assertTrue(src.f6 == dst.f6); + assertTrue(src.f8 != dst.f8); + assertTrue(src.f9 != dst.f9); + } + + @Test + public void testExtendedClass01() throws Exception { + SampleSubClass src = null; + + byte[] raw = MessagePack.pack(src); + + SampleSubClass dst = + MessagePack.unpack(raw).convert(SampleSubClass.class); + assertEquals(src, dst); + } + + public static class SampleSubClass extends SampleSuperClass { + public int f0; + public final int f1 = 1; + private int f2; + protected int f3; + int f4; + + public SampleSubClass() { + } + } + + public static class SampleSuperClass { + public int f5; + public final int f6 = 2; + @SuppressWarnings("unused") + private int f7; + protected int f8; + int f9; + + public SampleSuperClass() { + } + } + + @Test + public void testOptionalExtendedClass00() throws Exception { + SampleOptionalSubClass src = new SampleOptionalSubClass(); + src.f0 = 0; + src.f2 = 2; + src.f3 = 3; + src.f4 = 4; + src.f5 = 5; + src.f8 = 8; + src.f9 = 9; + + byte[] raw = MessagePack.pack(src); + + SampleOptionalSubClass dst = + MessagePack.unpack(raw).convert(SampleOptionalSubClass.class); + assertTrue(src.f0 == dst.f0); + assertTrue(src.f1 == dst.f1); + assertTrue(src.f2 != dst.f2); + assertTrue(src.f3 != dst.f3); + assertTrue(src.f4 != dst.f4); + assertTrue(src.f5 == dst.f5); + assertTrue(src.f6 == dst.f6); + assertTrue(src.f8 != dst.f8); + assertTrue(src.f9 != dst.f9); + } + + @Test + public void testOptionalExtendedClass01() throws Exception { + SampleOptionalSubClass src = null; + + byte[] raw = MessagePack.pack(src); + + SampleOptionalSubClass dst = + MessagePack.unpack(raw).convert(SampleOptionalSubClass.class); + assertEquals(src, dst); + } + + public static class SampleOptionalSubClass extends SampleOptionalSuperClass { + @Optional + public int f0; + public final int f1 = 1; + private int f2; + protected int f3; + int f4; + + public SampleOptionalSubClass() { + } + } + + public static class SampleOptionalSuperClass { + @Optional + public int f5; + public final int f6 = 2; + @SuppressWarnings("unused") + private int f7; + protected int f8; + int f9; + + public SampleOptionalSuperClass() { + } + } + + @Test + public void testMessagePackableUnpackableClass00() throws Exception { + BaseMessagePackableUnpackableClass src = new BaseMessagePackableUnpackableClass(); + MessagePackableUnpackableClass src1 = new MessagePackableUnpackableClass(); + List src2 = new ArrayList(); + src1.f0 = 0; + src1.f1 = 1; + src.f0 = src1; + src.f1 = 1; + src2.add(src1); + src.f2 = src2; + + byte[] raw = MessagePack.pack(src); + + BaseMessagePackableUnpackableClass dst = + MessagePack.unpack(raw).convert(BaseMessagePackableUnpackableClass.class); + assertEquals(src.f0.f0, dst.f0.f0); + assertEquals(src.f0.f1, dst.f0.f1); + assertEquals(src.f1, dst.f1); + assertEquals(src.f2.size(), dst.f2.size()); + assertEquals(src.f2.get(0).f0, dst.f2.get(0).f0); + assertEquals(src.f2.get(0).f1, dst.f2.get(0).f1); + } + + @Test + public void testMessagePackableUnpackableClass01() throws Exception { + BaseMessagePackableUnpackableClass src = null; + + byte[] raw = MessagePack.pack(src); + + BaseMessagePackableUnpackableClass dst = + MessagePack.unpack(raw).convert(BaseMessagePackableUnpackableClass.class); + assertEquals(src, dst); + } + + public static class BaseMessagePackableUnpackableClass { + public MessagePackableUnpackableClass f0; + public int f1; + public List f2; + + public BaseMessagePackableUnpackableClass() { + } + } + + public static class MessagePackableUnpackableClass implements + MessagePackable, MessageUnpackable { + public int f0; + public int f1; + + public MessagePackableUnpackableClass() { + } + + @Override + public void messagePack(Packer packer) throws IOException { + packer.packArray(2); + packer.pack(f0); + packer.pack(f1); + } + + @Override + public void messageUnpack(Unpacker unpacker) throws IOException, + MessageTypeException { + if (unpacker.tryUnpackNull()) { + return; + } + unpacker.unpackArray(); + f0 = unpacker.unpackInt(); + f1 = unpacker.unpackInt(); + } + } + + @Test + public void testOptionalMessagePackableUnpackableClass00() throws Exception { + OptionalBaseMessagePackableUnpackableClass src = new OptionalBaseMessagePackableUnpackableClass(); + OptionalMessagePackableUnpackableClass src1 = new OptionalMessagePackableUnpackableClass(); + List src2 = new ArrayList(); + src1.f0 = 0; + src1.f1 = 1; + src.f0 = src1; + src.f1 = 1; + src2.add(src1); + src.f2 = src2; + + byte[] raw = MessagePack.pack(src); + + OptionalBaseMessagePackableUnpackableClass dst = + MessagePack.unpack(raw).convert(OptionalBaseMessagePackableUnpackableClass.class); + assertEquals(src.f0.f0, dst.f0.f0); + assertEquals(src.f0.f1, dst.f0.f1); + assertEquals(src.f1, dst.f1); + assertEquals(src.f2.size(), dst.f2.size()); + assertEquals(src.f2.get(0).f0, dst.f2.get(0).f0); + assertEquals(src.f2.get(0).f1, dst.f2.get(0).f1); + } + + @Test + public void testOptionalMessagePackableUnpackableClass01() throws Exception { + OptionalBaseMessagePackableUnpackableClass src = new OptionalBaseMessagePackableUnpackableClass(); + src.f0 = null; + src.f1 = 1; + src.f2 = null; + + byte[] raw = MessagePack.pack(src); + + OptionalBaseMessagePackableUnpackableClass dst = + MessagePack.unpack(raw).convert(OptionalBaseMessagePackableUnpackableClass.class); + assertEquals(src.f0, dst.f0); + assertEquals(src.f1, dst.f1); + assertEquals(src.f2, dst.f2); + } + + @Test + public void testOptionalMessagePackableUnpackableClass02() throws Exception { + OptionalBaseMessagePackableUnpackableClass src = null; + + byte[] raw = MessagePack.pack(src); + + OptionalBaseMessagePackableUnpackableClass dst = + MessagePack.unpack(raw).convert(OptionalBaseMessagePackableUnpackableClass.class); + assertEquals(src, dst); + } + + public static class OptionalBaseMessagePackableUnpackableClass { + @Optional + public OptionalMessagePackableUnpackableClass f0; + @Optional + public int f1; + @Optional + public List f2; + + public OptionalBaseMessagePackableUnpackableClass() { + } + } + + public static class OptionalMessagePackableUnpackableClass implements + MessagePackable, MessageUnpackable { + @Optional + public int f0; + @Optional + public int f1; + + public OptionalMessagePackableUnpackableClass() { + } + + @Override + public void messagePack(Packer packer) throws IOException { + packer.packArray(2); + packer.pack(f0); + packer.pack(f1); + } + + @Override + public void messageUnpack(Unpacker unpacker) throws IOException, + MessageTypeException { + if (unpacker.tryUnpackNull()) { + return; + } + unpacker.unpackArray(); + f0 = unpacker.unpackInt(); + f1 = unpacker.unpackInt(); + } + } +} + diff --git a/java/src/test/java/org/msgpack/template/TestTemplateBuilderPackUnpack.java b/java/src/test/java/org/msgpack/template/TestTemplateBuilderPackUnpack.java new file mode 100644 index 0000000..a2430a4 --- /dev/null +++ b/java/src/test/java/org/msgpack/template/TestTemplateBuilderPackUnpack.java @@ -0,0 +1,1396 @@ +package org.msgpack.template; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.math.BigInteger; +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import org.junit.Test; + +import org.msgpack.MessagePack; +import org.msgpack.MessagePackable; +import org.msgpack.MessagePacker; +import org.msgpack.MessageTypeException; +import org.msgpack.MessageUnpackable; +import org.msgpack.Packer; +import org.msgpack.Template; +import org.msgpack.Unpacker; +import org.msgpack.annotation.MessagePackMessage; +import org.msgpack.annotation.MessagePackOrdinalEnum; +import org.msgpack.annotation.Optional; + +import junit.framework.TestCase; + +public class TestTemplateBuilderPackUnpack extends TestCase { + static { + MessagePack.register(PrimitiveTypeFieldsClass.class); + MessagePack.register(OptionalPrimitiveTypeFieldsClass.class); + MessagePack.register(GeneralReferenceTypeFieldsClass.class); + MessagePack.register(GeneralOptionalReferenceTypeFieldsClass.class); + MessagePack.register(SampleListTypes.class); + MessagePack.register(SampleOptionalListTypes.class); + MessagePack.register(SampleMapTypes.class); + MessagePack.register(SampleOptionalMapTypes.class); + MessagePack.register(SampleEnumFieldClass.class); + MessagePack.register(SampleOptionalEnumFieldClass.class); + MessagePack.register(FieldModifiersClass.class); + MessagePack.register(OptionalFieldModifiersClass.class); + MessagePack.register(BaseClass.class); + MessagePack.register(NestedClass.class); + MessagePack.register(BaseClass2.class); + MessagePack.register(OptionalBaseClass.class); + MessagePack.register(OptionalNestedClass.class); + MessagePack.register(OptionalBaseClass2.class); + MessagePack.register(SampleSubClass.class); + MessagePack.register(SampleSuperClass.class); + MessagePack.register(SampleOptionalSubClass.class); + MessagePack.register(SampleOptionalSuperClass.class); + MessagePack.register(BaseMessagePackableUnpackableClass.class); + MessagePack.register(MessagePackableUnpackableClass.class); + MessagePack.register(OptionalBaseMessagePackableUnpackableClass.class); + MessagePack.register(OptionalMessagePackableUnpackableClass.class); + } + + @Test + public void testPrimitiveTypeFields00() throws Exception { + PrimitiveTypeFieldsClass src = new PrimitiveTypeFieldsClass(); + src.f0 = (byte) 0; + src.f1 = 1; + src.f2 = 2; + src.f3 = 3; + src.f4 = 4; + src.f5 = 5; + src.f6 = false; + + byte[] raw = MessagePack.pack(src); + + PrimitiveTypeFieldsClass dst = + MessagePack.unpack(raw, PrimitiveTypeFieldsClass.class); + assertEquals(src.f0, dst.f0); + assertEquals(src.f1, dst.f1); + assertEquals(src.f2, dst.f2); + assertEquals(src.f3, dst.f3); + assertEquals(src.f4, dst.f4); + assertEquals(src.f5, dst.f5); + assertEquals(src.f6, dst.f6); + } + + @Test + public void testPrimitiveTypeFields01() throws Exception { + PrimitiveTypeFieldsClass src = new PrimitiveTypeFieldsClass(); + + byte[] raw = MessagePack.pack(src); + + PrimitiveTypeFieldsClass dst = + MessagePack.unpack(raw, PrimitiveTypeFieldsClass.class); + assertEquals(src.f0, dst.f0); + assertEquals(src.f1, dst.f1); + assertEquals(src.f2, dst.f2); + assertEquals(src.f3, dst.f3); + assertEquals(src.f4, dst.f4); + assertEquals(src.f5, dst.f5); + assertEquals(src.f6, dst.f6); + } + + @Test + public void testPrimitiveTypeFields02() throws Exception { + PrimitiveTypeFieldsClass src = null; + + byte[] raw = MessagePack.pack(src); + + PrimitiveTypeFieldsClass dst = + MessagePack.unpack(raw, PrimitiveTypeFieldsClass.class); + assertEquals(src, dst); + } + + public static class PrimitiveTypeFieldsClass { + public byte f0; + public short f1; + public int f2; + public long f3; + public float f4; + public double f5; + public boolean f6; + + public PrimitiveTypeFieldsClass() { + } + } + + @Test + public void testOptionalPrimitiveTypeFields00() throws Exception { + OptionalPrimitiveTypeFieldsClass src = new OptionalPrimitiveTypeFieldsClass(); + src.f0 = (byte) 0; + src.f1 = 1; + src.f2 = 2; + src.f3 = 3; + src.f4 = 4; + src.f5 = 5; + src.f6 = false; + + byte[] raw = MessagePack.pack(src); + + PrimitiveTypeFieldsClass dst = + MessagePack.unpack(raw, PrimitiveTypeFieldsClass.class); + assertEquals(src.f0, dst.f0); + assertEquals(src.f1, dst.f1); + assertEquals(src.f2, dst.f2); + assertEquals(src.f3, dst.f3); + assertEquals(src.f4, dst.f4); + assertEquals(src.f5, dst.f5); + assertEquals(src.f6, dst.f6); + } + + @Test + public void testOptionalPrimitiveTypeFields01() throws Exception { + OptionalPrimitiveTypeFieldsClass src = new OptionalPrimitiveTypeFieldsClass(); + + byte[] raw = MessagePack.pack(src); + + OptionalPrimitiveTypeFieldsClass dst = + MessagePack.unpack(raw, OptionalPrimitiveTypeFieldsClass.class); + assertEquals(src.f0, dst.f0); + assertEquals(src.f1, dst.f1); + assertEquals(src.f2, dst.f2); + assertEquals(src.f3, dst.f3); + assertEquals(src.f4, dst.f4); + assertEquals(src.f5, dst.f5); + assertEquals(src.f6, dst.f6); + } + + @Test + public void testOptionalPrimitiveTypeFields02() throws Exception { + OptionalPrimitiveTypeFieldsClass src = null; + + byte[] raw = MessagePack.pack(src); + + OptionalPrimitiveTypeFieldsClass dst = + MessagePack.unpack(raw, OptionalPrimitiveTypeFieldsClass.class); + assertEquals(src, dst); + } + + public static class OptionalPrimitiveTypeFieldsClass { + @Optional + public byte f0; + @Optional + public short f1; + @Optional + public int f2; + @Optional + public long f3; + @Optional + public float f4; + @Optional + public double f5; + @Optional + public boolean f6; + + public OptionalPrimitiveTypeFieldsClass() { + } + } + + @Test + public void testGeneralReferenceTypeFieldsClass00() throws Exception { + GeneralReferenceTypeFieldsClass src = new GeneralReferenceTypeFieldsClass(); + src.f0 = 0; + src.f1 = 1; + src.f2 = 2; + src.f3 = (long) 3; + src.f4 = (float) 4; + src.f5 = (double) 5; + src.f6 = false; + src.f7 = new BigInteger("7"); + src.f8 = "8"; + src.f9 = new byte[] { 0x01, 0x02 }; + src.f10 = ByteBuffer.wrap("muga".getBytes()); + + byte[] raw = MessagePack.pack(src); + + GeneralReferenceTypeFieldsClass dst = + MessagePack.unpack(raw, GeneralReferenceTypeFieldsClass.class); + assertEquals(src.f0, dst.f0); + assertEquals(src.f1, dst.f1); + assertEquals(src.f2, dst.f2); + assertEquals(src.f3, dst.f3); + assertEquals(src.f4, dst.f4); + assertEquals(src.f5, dst.f5); + assertEquals(src.f6, dst.f6); + assertEquals(src.f7, dst.f7); + assertEquals(src.f8, dst.f8); + assertEquals(src.f9[0], dst.f9[0]); + assertEquals(src.f9[1], dst.f9[1]); + assertEquals(src.f10, dst.f10); + } + + @Test + public void testGeneralReferenceTypeFieldsClass01() throws Exception { + GeneralReferenceTypeFieldsClass src = null; + + byte[] raw = MessagePack.pack(src); + + GeneralReferenceTypeFieldsClass dst = + MessagePack.unpack(raw, GeneralReferenceTypeFieldsClass.class); + assertEquals(src, dst); + } + + public static class GeneralReferenceTypeFieldsClass { + public Byte f0; + public Short f1; + public Integer f2; + public Long f3; + public Float f4; + public Double f5; + public Boolean f6; + public BigInteger f7; + public String f8; + public byte[] f9; + public ByteBuffer f10; + + public GeneralReferenceTypeFieldsClass() { + } + } + + @Test + public void testGeneralOptionalReferenceTypeFieldsClass00() + throws Exception { + GeneralOptionalReferenceTypeFieldsClass src = new GeneralOptionalReferenceTypeFieldsClass(); + src.f0 = 0; + src.f1 = 1; + src.f2 = 2; + src.f3 = (long) 3; + src.f4 = (float) 4; + src.f5 = (double) 5; + src.f6 = false; + src.f7 = new BigInteger("7"); + src.f8 = "8"; + src.f9 = new byte[] { 0x01, 0x02 }; + src.f10 = ByteBuffer.wrap("muga".getBytes()); + + byte[] raw = MessagePack.pack(src); + + GeneralOptionalReferenceTypeFieldsClass dst = + MessagePack.unpack(raw, GeneralOptionalReferenceTypeFieldsClass.class); + assertEquals(src.f0, dst.f0); + assertEquals(src.f1, dst.f1); + assertEquals(src.f2, dst.f2); + assertEquals(src.f3, dst.f3); + assertEquals(src.f4, dst.f4); + assertEquals(src.f5, dst.f5); + assertEquals(src.f6, dst.f6); + assertEquals(src.f7, dst.f7); + assertEquals(src.f8, dst.f8); + assertEquals(src.f9[0], dst.f9[0]); + assertEquals(src.f9[1], dst.f9[1]); + assertEquals(src.f10, dst.f10); + } + + @Test + public void testGeneralOptionalReferenceTypeFieldsClass01() + throws Exception { + GeneralOptionalReferenceTypeFieldsClass src = new GeneralOptionalReferenceTypeFieldsClass(); + src.f0 = null; + src.f1 = null; + src.f2 = null; + src.f3 = null; + src.f4 = null; + src.f5 = null; + src.f6 = null; + src.f7 = null; + src.f8 = null; + src.f9 = null; + src.f10 = null; + + byte[] raw = MessagePack.pack(src); + + GeneralOptionalReferenceTypeFieldsClass dst = + MessagePack.unpack(raw, GeneralOptionalReferenceTypeFieldsClass.class); + assertEquals(src.f0, dst.f0); + assertEquals(src.f1, dst.f1); + assertEquals(src.f2, dst.f2); + assertEquals(src.f3, dst.f3); + assertEquals(src.f4, dst.f4); + assertEquals(src.f5, dst.f5); + assertEquals(src.f6, dst.f6); + assertEquals(src.f7, dst.f7); + assertEquals(src.f8, dst.f8); + assertEquals(src.f9, dst.f9); + assertEquals(src.f10, dst.f10); + } + + @Test + public void testGeneralOptionalReferenceTypeFieldsClass02() + throws Exception { + GeneralOptionalReferenceTypeFieldsClass src = null; + + byte[] raw = MessagePack.pack(src); + + GeneralOptionalReferenceTypeFieldsClass dst = + MessagePack.unpack(raw, GeneralOptionalReferenceTypeFieldsClass.class); + assertEquals(src, dst); + } + + public static class GeneralOptionalReferenceTypeFieldsClass { + @Optional + public Byte f0; + @Optional + public Short f1; + @Optional + public Integer f2; + @Optional + public Long f3; + @Optional + public Float f4; + @Optional + public Double f5; + @Optional + public Boolean f6; + @Optional + public BigInteger f7; + @Optional + public String f8; + @Optional + public byte[] f9; + @Optional + public ByteBuffer f10; + + public GeneralOptionalReferenceTypeFieldsClass() { + } + } + + @Test + public void testListTypes00() throws Exception { + SampleListTypes src = new SampleListTypes(); + src.f0 = new ArrayList(); + src.f1 = new ArrayList(); + src.f1.add(1); + src.f1.add(2); + src.f1.add(3); + src.f2 = new ArrayList(); + src.f2.add("e1"); + src.f2.add("e2"); + src.f2.add("e3"); + src.f3 = new ArrayList>(); + src.f3.add(src.f2); + src.f4 = new ArrayList(); + SampleListNestedType slnt = new SampleListNestedType(); + slnt.f0 = new byte[] { 0x01, 0x02 }; + slnt.f1 = "muga"; + src.f4.add(slnt); + src.f5 = new ArrayList(); + src.f5.add(ByteBuffer.wrap("e1".getBytes())); + src.f5.add(ByteBuffer.wrap("e2".getBytes())); + src.f5.add(ByteBuffer.wrap("e3".getBytes())); + + byte[] raw = MessagePack.pack(src); + + SampleListTypes dst = + MessagePack.unpack(raw, SampleListTypes.class); + for (int i = 0; i < src.f1.size(); ++i) { + assertEquals(src.f1.get(i), dst.f1.get(i)); + } + assertEquals(src.f2.size(), dst.f2.size()); + for (int i = 0; i < src.f2.size(); ++i) { + assertEquals(src.f2.get(i), dst.f2.get(i)); + } + assertEquals(src.f3.size(), dst.f3.size()); + for (int i = 0; i < src.f3.size(); ++i) { + List srclist = src.f3.get(i); + List dstlist = dst.f3.get(i); + assertEquals(srclist.size(), dstlist.size()); + for (int j = 0; j < srclist.size(); ++j) { + assertEquals(srclist.get(j), dstlist.get(j)); + } + } + assertEquals(src.f4.size(), dst.f4.size()); + for (int i = 0; i < src.f4.size(); ++i) { + SampleListNestedType s = src.f4.get(i); + SampleListNestedType d = dst.f4.get(i); + assertEquals(s.f0[0], d.f0[0]); + assertEquals(s.f0[1], d.f0[1]); + assertEquals(s.f1, d.f1); + } + assertEquals(src.f5.size(), dst.f5.size()); + for (int i = 0; i < src.f5.size(); ++i) { + ByteBuffer s = src.f5.get(i); + ByteBuffer d = dst.f5.get(i); + assertEquals(s, d); + } + } + + @Test + public void testListTypes01() throws Exception { + SampleListTypes src = null; + + byte[] raw = MessagePack.pack(src); + + SampleListTypes dst = + MessagePack.unpack(raw, SampleListTypes.class); + assertEquals(src, dst); + } + + public static class SampleListTypes { + public List f0; + public List f1; + public List f2; + public List> f3; + public List f4; + public List f5; + + public SampleListTypes() { + } + } + + @MessagePackMessage + public static class SampleListNestedType { + public byte[] f0; + public String f1; + + public SampleListNestedType() { + } + } + + @Test + public void testOptionalListTypes00() throws Exception { + SampleOptionalListTypes src = new SampleOptionalListTypes(); + src.f0 = new ArrayList(); + src.f1 = new ArrayList(); + src.f1.add(1); + src.f1.add(2); + src.f1.add(3); + src.f2 = new ArrayList(); + src.f2.add("e1"); + src.f2.add("e2"); + src.f2.add("e3"); + src.f3 = new ArrayList>(); + src.f3.add(src.f2); + src.f4 = new ArrayList(); + SampleOptionalListNestedType slnt = new SampleOptionalListNestedType(); + slnt.f0 = new byte[] { 0x01, 0x02 }; + slnt.f1 = "muga"; + src.f4.add(slnt); + src.f5 = new ArrayList(); + src.f5.add(ByteBuffer.wrap("e1".getBytes())); + src.f5.add(ByteBuffer.wrap("e2".getBytes())); + src.f5.add(ByteBuffer.wrap("e3".getBytes())); + + byte[] raw = MessagePack.pack(src); + + SampleOptionalListTypes dst = + MessagePack.unpack(raw, SampleOptionalListTypes.class); + assertEquals(src.f0.size(), dst.f0.size()); + assertEquals(src.f1.size(), dst.f1.size()); + for (int i = 0; i < src.f1.size(); ++i) { + assertEquals(src.f1.get(i), dst.f1.get(i)); + } + assertEquals(src.f2.size(), dst.f2.size()); + for (int i = 0; i < src.f2.size(); ++i) { + assertEquals(src.f2.get(i), dst.f2.get(i)); + } + assertEquals(src.f3.size(), dst.f3.size()); + for (int i = 0; i < src.f3.size(); ++i) { + List srclist = src.f3.get(i); + List dstlist = dst.f3.get(i); + assertEquals(srclist.size(), dstlist.size()); + for (int j = 0; j < srclist.size(); ++j) { + assertEquals(srclist.get(j), dstlist.get(j)); + } + } + assertEquals(src.f4.size(), dst.f4.size()); + for (int i = 0; i < src.f4.size(); ++i) { + SampleOptionalListNestedType s = src.f4.get(i); + SampleOptionalListNestedType d = dst.f4.get(i); + assertEquals(s.f0[0], d.f0[0]); + assertEquals(s.f0[1], d.f0[1]); + assertEquals(s.f1, d.f1); + } + assertEquals(src.f5.size(), dst.f5.size()); + for (int i = 0; i < src.f5.size(); ++i) { + ByteBuffer s = src.f5.get(i); + ByteBuffer d = dst.f5.get(i); + assertEquals(s, d); + } + } + + @Test + public void testOptionalListTypes01() throws Exception { + SampleOptionalListTypes src = new SampleOptionalListTypes(); + src.f0 = new ArrayList(); + src.f1 = null; + src.f2 = new ArrayList(); + src.f3 = new ArrayList>(); + src.f4 = null; + src.f5 = new ArrayList(); + + byte[] raw = MessagePack.pack(src); + + SampleOptionalListTypes dst = + MessagePack.unpack(raw, SampleOptionalListTypes.class); + assertEquals(src.f0.size(), dst.f0.size()); + assertEquals(src.f1, dst.f1); + assertEquals(src.f2.size(), dst.f2.size()); + assertEquals(src.f3.size(), dst.f3.size()); + assertEquals(src.f4, dst.f4); + assertEquals(src.f5.size(), dst.f5.size()); + } + + @Test + public void testOptionalListTypes02() throws Exception { + SampleListTypes src = null; + + byte[] raw = MessagePack.pack(src); + + SampleListTypes dst = + MessagePack.unpack(raw, SampleListTypes.class); + assertEquals(src, dst); + } + + public static class SampleOptionalListTypes { + @Optional + public List f0; + @Optional + public List f1; + @Optional + public List f2; + @Optional + public List> f3; + @Optional + public List f4; + @Optional + public List f5; + + public SampleOptionalListTypes() { + } + } + + @MessagePackMessage + public static class SampleOptionalListNestedType { + @Optional + public byte[] f0; + @Optional + public String f1; + + public SampleOptionalListNestedType() { + } + } + + @Test + public void testMapTypes00() throws Exception { + SampleMapTypes src = new SampleMapTypes(); + src.f0 = new HashMap(); + src.f1 = new HashMap(); + src.f1.put(1, 1); + src.f1.put(2, 2); + src.f1.put(3, 3); + src.f2 = new HashMap(); + src.f2.put("k1", 1); + src.f2.put("k2", 2); + src.f2.put("k3", 3); + + byte[] raw = MessagePack.pack(src); + + SampleMapTypes dst = + MessagePack.unpack(raw, SampleMapTypes.class); + Iterator srcf1 = src.f1.keySet().iterator(); + Iterator dstf1 = dst.f1.keySet().iterator(); + while (srcf1.hasNext()) { + Integer s1 = srcf1.next(); + Integer d1 = dstf1.next(); + assertEquals(s1, d1); + assertEquals(src.f1.get(s1), dst.f1.get(d1)); + } + assertEquals(src.f2.size(), dst.f2.size()); + Iterator srcf2 = src.f2.keySet().iterator(); + Iterator dstf2 = dst.f2.keySet().iterator(); + while (srcf2.hasNext()) { + String s2 = srcf2.next(); + String d2 = dstf2.next(); + assertEquals(s2, d2); + assertEquals(src.f2.get(s2), dst.f2.get(d2)); + } + } + + @Test + public void testMapTypes01() throws Exception { + SampleMapTypes src = null; + + byte[] raw = MessagePack.pack(src); + + SampleMapTypes dst = + MessagePack.unpack(raw, SampleMapTypes.class); + assertEquals(src, dst); + } + + public static class SampleMapTypes { + public Map f0; + public Map f1; + public Map f2; + + public SampleMapTypes() { + } + } + + @Test + public void testOptionalMapTypes00() throws Exception { + SampleOptionalMapTypes src = new SampleOptionalMapTypes(); + src.f0 = new HashMap(); + src.f1 = new HashMap(); + src.f1.put(1, 1); + src.f1.put(2, 2); + src.f1.put(3, 3); + src.f2 = new HashMap(); + src.f2.put("k1", 1); + src.f2.put("k2", 2); + src.f2.put("k3", 3); + + byte[] raw = MessagePack.pack(src); + + SampleOptionalMapTypes dst = + MessagePack.unpack(raw, SampleOptionalMapTypes.class); + assertEquals(src.f0.size(), dst.f0.size()); + assertEquals(src.f1.size(), dst.f1.size()); + Iterator srcf1 = src.f1.keySet().iterator(); + Iterator dstf1 = dst.f1.keySet().iterator(); + while (srcf1.hasNext()) { + Integer s1 = srcf1.next(); + Integer d1 = dstf1.next(); + assertEquals(s1, d1); + assertEquals(src.f1.get(s1), dst.f1.get(d1)); + } + assertEquals(src.f2.size(), dst.f2.size()); + Iterator srcf2 = src.f2.keySet().iterator(); + Iterator dstf2 = dst.f2.keySet().iterator(); + while (srcf2.hasNext()) { + String s2 = srcf2.next(); + String d2 = dstf2.next(); + assertEquals(s2, d2); + assertEquals(src.f2.get(s2), dst.f2.get(d2)); + } + } + + @Test + public void testOptionalMapTypes01() throws Exception { + SampleOptionalMapTypes src = new SampleOptionalMapTypes(); + src.f0 = new HashMap(); + src.f1 = null; + src.f2 = new HashMap(); + + byte[] raw = MessagePack.pack(src); + + SampleOptionalMapTypes dst = + MessagePack.unpack(raw, SampleOptionalMapTypes.class); + assertEquals(src.f0.size(), dst.f0.size()); + assertEquals(src.f1, dst.f1); + assertEquals(src.f2.size(), dst.f2.size()); + } + + @Test + public void testOptionalMapTypes02() throws Exception { + SampleOptionalMapTypes src = null; + + byte[] raw = MessagePack.pack(src); + + SampleOptionalMapTypes dst = + MessagePack.unpack(raw, SampleOptionalMapTypes.class); + assertEquals(src, dst); + } + + public static class SampleOptionalMapTypes { + @Optional + public Map f0; + @Optional + public Map f1; + @Optional + public Map f2; + + public SampleOptionalMapTypes() { + } + } + + @Test + public void testFinalClass() throws Exception { + try { + TemplateBuilder.build(FinalModifierClass.class); + assertTrue(true); + } catch (TemplateBuildException e) { + fail(); + } + assertTrue(true); + } + + public final static class FinalModifierClass { + } + + public abstract static class AbstractModifierClass { + } + + @Test + public void testInterfaceType00() throws Exception { + try { + TemplateBuilder.build(SampleInterface.class); + fail(); + } catch (TemplateBuildException e) { + assertTrue(true); + } + assertTrue(true); + } + + @Test + public void testInterfaceType01() throws Exception { + try { + TemplateBuilder.build(SampleInterface.class); + fail(); + } catch (TemplateBuildException e) { + assertTrue(true); + } + assertTrue(true); + } + + public interface SampleInterface { + } + + @Test + public void testEnumTypeForOrdinal00() throws Exception { + SampleEnumFieldClass src = new SampleEnumFieldClass(); + src.f0 = 0; + src.f1 = SampleEnum.ONE; + + byte[] raw = MessagePack.pack(src); + + SampleEnumFieldClass dst = + MessagePack.unpack(raw, SampleEnumFieldClass.class); + assertTrue(src.f1 == dst.f1); + } + + @Test + public void testEnumTypeForOrdinal01() throws Exception { + SampleEnumFieldClass src = null; + + byte[] raw = MessagePack.pack(src); + + SampleEnumFieldClass dst = + MessagePack.unpack(raw, SampleEnumFieldClass.class); + assertEquals(src, dst); + } + + public static class SampleEnumFieldClass { + public int f0; + + public SampleEnum f1; + + public SampleEnumFieldClass() { + } + } + + @MessagePackOrdinalEnum + public enum SampleEnum { + ONE, TWO, THREE; + } + + @Test + public void testOptionalEnumTypeForOrdinal00() throws Exception { + SampleOptionalEnumFieldClass src = new SampleOptionalEnumFieldClass(); + src.f0 = 0; + src.f1 = SampleOptionalEnum.ONE; + + byte[] raw = MessagePack.pack(src); + + SampleOptionalEnumFieldClass dst = + MessagePack.unpack(raw, SampleOptionalEnumFieldClass.class); + assertTrue(src.f0 == dst.f0); + assertTrue(src.f1 == dst.f1); + } + + @Test + public void testOptionalEnumTypeForOrdinal01() throws Exception { + SampleOptionalEnumFieldClass src = new SampleOptionalEnumFieldClass(); + src.f1 = null; + + byte[] raw = MessagePack.pack(src); + + SampleOptionalEnumFieldClass dst = + MessagePack.unpack(raw, SampleOptionalEnumFieldClass.class); + assertTrue(src.f0 == dst.f0); + assertEquals(src.f1, dst.f1); + } + + @Test + public void testOptionalEnumTypeForOrdinal02() throws Exception { + SampleEnumFieldClass src = null; + + byte[] raw = MessagePack.pack(src); + + SampleEnumFieldClass dst = + MessagePack.unpack(raw, SampleEnumFieldClass.class); + assertEquals(src, dst); + } + + public static class SampleOptionalEnumFieldClass { + @Optional + public int f0; + + @Optional + public SampleOptionalEnum f1; + + public SampleOptionalEnumFieldClass() { + } + } + + @MessagePackOrdinalEnum + public enum SampleOptionalEnum { + ONE, TWO, THREE; + } + + @Test + public void testFieldModifiers() throws Exception { + FieldModifiersClass src = new FieldModifiersClass(); + src.f0 = 0; + src.f2 = 2; + src.f3 = 3; + src.f4 = 4; + + byte[] raw = MessagePack.pack(src); + + FieldModifiersClass dst = + MessagePack.unpack(raw, FieldModifiersClass.class); + assertTrue(src.f1 == dst.f1); + assertTrue(src.f2 != dst.f2); + assertTrue(src.f3 != dst.f3); + assertTrue(src.f4 != dst.f4); + } + + public static class FieldModifiersClass { + public int f0; + public final int f1 = 1; + private int f2; + protected int f3; + int f4; + + public FieldModifiersClass() { + } + } + + @Test + public void testOptionalFieldModifiers() throws Exception { + OptionalFieldModifiersClass src = new OptionalFieldModifiersClass(); + src.f0 = 0; + src.f2 = 2; + src.f3 = 3; + src.f4 = 4; + + byte[] raw = MessagePack.pack(src); + + OptionalFieldModifiersClass dst = + MessagePack.unpack(raw, OptionalFieldModifiersClass.class); + assertTrue(src.f0 == dst.f0); + assertTrue(src.f1 == dst.f1); + assertTrue(src.f2 != dst.f2); + assertTrue(src.f3 != dst.f3); + assertTrue(src.f4 != dst.f4); + } + + public static class OptionalFieldModifiersClass { + @Optional + public int f0; + @Optional + public final int f1 = 1; + private int f2; + protected int f3; + int f4; + + public OptionalFieldModifiersClass() { + } + } + + @Test + public void testNestedFieldClass00() throws Exception { + BaseClass src = new BaseClass(); + NestedClass src2 = new NestedClass(); + src.f0 = 0; + src2.f2 = 2; + src.f1 = src2; + + byte[] raw = MessagePack.pack(src); + + BaseClass dst = + MessagePack.unpack(raw, BaseClass.class); + assertTrue(src.f0 == dst.f0); + assertTrue(src.f1.f2 == dst.f1.f2); + } + + @Test + public void testNestedFieldClass01() throws Exception { + BaseClass src = null; + + byte[] raw = MessagePack.pack(src); + + BaseClass dst = + MessagePack.unpack(raw, BaseClass.class); + assertEquals(src, dst); + } + + public static class BaseClass { + public int f0; + public NestedClass f1; + + public BaseClass() { + } + } + + public static class NestedClass { + public int f2; + + public NestedClass() { + } + } + + @Test + public void testOptionalNestedFieldClass00() throws Exception { + OptionalBaseClass src = new OptionalBaseClass(); + OptionalNestedClass src2 = new OptionalNestedClass(); + src.f0 = 0; + src2.f2 = 2; + src.f1 = src2; + + byte[] raw = MessagePack.pack(src); + + OptionalBaseClass dst = + MessagePack.unpack(raw, OptionalBaseClass.class); + assertTrue(src.f0 == dst.f0); + assertTrue(src.f1.f2 == dst.f1.f2); + } + + @Test + public void testOptionalNestedFieldClass01() throws Exception { + OptionalBaseClass src = new OptionalBaseClass(); + src.f1 = null; + + byte[] raw = MessagePack.pack(src); + + OptionalBaseClass dst = + MessagePack.unpack(raw, OptionalBaseClass.class); + assertTrue(src.f0 == dst.f0); + assertTrue(src.f1 == dst.f1); + } + + @Test + public void testOptionalNestedFieldClass02() throws Exception { + OptionalBaseClass src = null; + + byte[] raw = MessagePack.pack(src); + + OptionalBaseClass dst = + MessagePack.unpack(raw, OptionalBaseClass.class); + assertEquals(src, dst); + } + + public static class OptionalBaseClass { + @Optional + public int f0; + @Optional + public OptionalNestedClass f1; + + public OptionalBaseClass() { + } + } + + public static class OptionalNestedClass { + @Optional + public int f2; + + public OptionalNestedClass() { + } + } + + @Test + public void testMessagePackMessageFieldClass00() throws Exception { + BaseClass2 src = new BaseClass2(); + MessagePackMessageClass2 src2 = new MessagePackMessageClass2(); + src.f0 = 0; + src2.f2 = 2; + src.f1 = src2; + + byte[] raw = MessagePack.pack(src); + + BaseClass2 dst = + MessagePack.unpack(raw, BaseClass2.class); + assertTrue(src.f0 == dst.f0); + assertTrue(src.f1.f2 == dst.f1.f2); + } + + @Test + public void testMessagePackMessageFieldClass01() throws Exception { + BaseClass2 src = null; + + byte[] raw = MessagePack.pack(src); + + BaseClass2 dst = + MessagePack.unpack(raw, BaseClass2.class); + assertEquals(src, dst); + } + + public static class BaseClass2 { + public int f0; + public MessagePackMessageClass2 f1; + + public BaseClass2() { + } + } + + @MessagePackMessage + public static class MessagePackMessageClass2 { + public int f2; + + public MessagePackMessageClass2() { + } + } + + @Test + public void testOptionalMessagePackMessageFieldClass00() throws Exception { + OptionalBaseClass2 src = new OptionalBaseClass2(); + OptionalMessagePackMessageClass2 src2 = new OptionalMessagePackMessageClass2(); + src.f0 = 0; + src2.f2 = 2; + src.f1 = src2; + + byte[] raw = MessagePack.pack(src); + + OptionalBaseClass2 dst = + MessagePack.unpack(raw, OptionalBaseClass2.class); + assertTrue(src.f0 == dst.f0); + assertTrue(src.f1.f2 == dst.f1.f2); + } + + @Test + public void testOptionalMessagePackMessageFieldClass01() throws Exception { + OptionalBaseClass2 src = new OptionalBaseClass2(); + src.f1 = null; + + byte[] raw = MessagePack.pack(src); + + OptionalBaseClass2 dst = + MessagePack.unpack(raw, OptionalBaseClass2.class); + assertTrue(src.f0 == dst.f0); + assertEquals(src.f1, dst.f1); + } + + @Test + public void testOptionalMessagePackMessageFieldClass02() throws Exception { + OptionalBaseClass2 src = null; + + byte[] raw = MessagePack.pack(src); + + OptionalBaseClass2 dst = + MessagePack.unpack(raw, OptionalBaseClass2.class); + assertEquals(src, dst); + } + + public static class OptionalBaseClass2 { + @Optional + public int f0; + @Optional + public OptionalMessagePackMessageClass2 f1; + + public OptionalBaseClass2() { + } + } + + @MessagePackMessage + public static class OptionalMessagePackMessageClass2 { + @Optional + public int f2; + + public OptionalMessagePackMessageClass2() { + } + } + + @Test + public void testExtendedClass00() throws Exception { + SampleSubClass src = new SampleSubClass(); + src.f0 = 0; + src.f2 = 2; + src.f3 = 3; + src.f4 = 4; + src.f5 = 5; + src.f8 = 8; + src.f9 = 9; + + byte[] raw = MessagePack.pack(src); + + SampleSubClass dst = + MessagePack.unpack(raw, SampleSubClass.class); + assertTrue(src.f0 == dst.f0); + assertTrue(src.f1 == dst.f1); + assertTrue(src.f2 != dst.f2); + assertTrue(src.f3 != dst.f3); + assertTrue(src.f4 != dst.f4); + assertTrue(src.f5 == dst.f5); + assertTrue(src.f6 == dst.f6); + assertTrue(src.f8 != dst.f8); + assertTrue(src.f9 != dst.f9); + } + + @Test + public void testExtendedClass01() throws Exception { + SampleSubClass src = null; + + byte[] raw = MessagePack.pack(src); + + SampleSubClass dst = + MessagePack.unpack(raw, SampleSubClass.class); + assertEquals(src, dst); + } + + public static class SampleSubClass extends SampleSuperClass { + public int f0; + public final int f1 = 1; + private int f2; + protected int f3; + int f4; + + public SampleSubClass() { + } + } + + public static class SampleSuperClass { + public int f5; + public final int f6 = 2; + @SuppressWarnings("unused") + private int f7; + protected int f8; + int f9; + + public SampleSuperClass() { + } + } + + @Test + public void testOptionalExtendedClass00() throws Exception { + SampleOptionalSubClass src = new SampleOptionalSubClass(); + src.f0 = 0; + src.f2 = 2; + src.f3 = 3; + src.f4 = 4; + src.f5 = 5; + src.f8 = 8; + src.f9 = 9; + + byte[] raw = MessagePack.pack(src); + + SampleOptionalSubClass dst = + MessagePack.unpack(raw, SampleOptionalSubClass.class); + assertTrue(src.f0 == dst.f0); + assertTrue(src.f1 == dst.f1); + assertTrue(src.f2 != dst.f2); + assertTrue(src.f3 != dst.f3); + assertTrue(src.f4 != dst.f4); + assertTrue(src.f5 == dst.f5); + assertTrue(src.f6 == dst.f6); + assertTrue(src.f8 != dst.f8); + assertTrue(src.f9 != dst.f9); + } + + @Test + public void testOptionalExtendedClass01() throws Exception { + SampleOptionalSubClass src = null; + + byte[] raw = MessagePack.pack(src); + + SampleOptionalSubClass dst = + MessagePack.unpack(raw, SampleOptionalSubClass.class); + assertEquals(src, dst); + } + + public static class SampleOptionalSubClass extends SampleOptionalSuperClass { + @Optional + public int f0; + public final int f1 = 1; + private int f2; + protected int f3; + int f4; + + public SampleOptionalSubClass() { + } + } + + public static class SampleOptionalSuperClass { + @Optional + public int f5; + public final int f6 = 2; + @SuppressWarnings("unused") + private int f7; + protected int f8; + int f9; + + public SampleOptionalSuperClass() { + } + } + + @Test + public void testMessagePackableUnpackableClass00() throws Exception { + BaseMessagePackableUnpackableClass src = new BaseMessagePackableUnpackableClass(); + MessagePackableUnpackableClass src1 = new MessagePackableUnpackableClass(); + List src2 = new ArrayList(); + src1.f0 = 0; + src1.f1 = 1; + src.f0 = src1; + src.f1 = 1; + src2.add(src1); + src.f2 = src2; + + byte[] raw = MessagePack.pack(src); + + BaseMessagePackableUnpackableClass dst = + MessagePack.unpack(raw, BaseMessagePackableUnpackableClass.class); + assertEquals(src.f0.f0, dst.f0.f0); + assertEquals(src.f0.f1, dst.f0.f1); + assertEquals(src.f1, dst.f1); + assertEquals(src.f2.size(), dst.f2.size()); + assertEquals(src.f2.get(0).f0, dst.f2.get(0).f0); + assertEquals(src.f2.get(0).f1, dst.f2.get(0).f1); + } + + @Test + public void testMessagePackableUnpackableClass01() throws Exception { + BaseMessagePackableUnpackableClass src = null; + + byte[] raw = MessagePack.pack(src); + + BaseMessagePackableUnpackableClass dst = + MessagePack.unpack(raw, BaseMessagePackableUnpackableClass.class); + assertEquals(src, dst); + } + + public static class BaseMessagePackableUnpackableClass { + public MessagePackableUnpackableClass f0; + public int f1; + public List f2; + + public BaseMessagePackableUnpackableClass() { + } + } + + public static class MessagePackableUnpackableClass implements + MessagePackable, MessageUnpackable { + public int f0; + public int f1; + + public MessagePackableUnpackableClass() { + } + + @Override + public void messagePack(Packer packer) throws IOException { + packer.packArray(2); + packer.pack(f0); + packer.pack(f1); + } + + @Override + public void messageUnpack(Unpacker unpacker) throws IOException, + MessageTypeException { + if (unpacker.tryUnpackNull()) { + return; + } + unpacker.unpackArray(); + f0 = unpacker.unpackInt(); + f1 = unpacker.unpackInt(); + } + } + + @Test + public void testOptionalMessagePackableUnpackableClass00() throws Exception { + OptionalBaseMessagePackableUnpackableClass src = new OptionalBaseMessagePackableUnpackableClass(); + OptionalMessagePackableUnpackableClass src1 = new OptionalMessagePackableUnpackableClass(); + List src2 = new ArrayList(); + src1.f0 = 0; + src1.f1 = 1; + src.f0 = src1; + src.f1 = 1; + src2.add(src1); + src.f2 = src2; + + byte[] raw = MessagePack.pack(src); + + OptionalBaseMessagePackableUnpackableClass dst = + MessagePack.unpack(raw, OptionalBaseMessagePackableUnpackableClass.class); + assertEquals(src.f0.f0, dst.f0.f0); + assertEquals(src.f0.f1, dst.f0.f1); + assertEquals(src.f1, dst.f1); + assertEquals(src.f2.size(), dst.f2.size()); + assertEquals(src.f2.get(0).f0, dst.f2.get(0).f0); + assertEquals(src.f2.get(0).f1, dst.f2.get(0).f1); + } + + @Test + public void testOptionalMessagePackableUnpackableClass01() throws Exception { + OptionalBaseMessagePackableUnpackableClass src = new OptionalBaseMessagePackableUnpackableClass(); + src.f0 = null; + src.f1 = 1; + src.f2 = null; + + byte[] raw = MessagePack.pack(src); + + OptionalBaseMessagePackableUnpackableClass dst = + MessagePack.unpack(raw, OptionalBaseMessagePackableUnpackableClass.class); + assertEquals(src.f0, dst.f0); + assertEquals(src.f1, dst.f1); + assertEquals(src.f2, dst.f2); + } + + @Test + public void testOptionalMessagePackableUnpackableClass02() throws Exception { + OptionalBaseMessagePackableUnpackableClass src = null; + + byte[] raw = MessagePack.pack(src); + + OptionalBaseMessagePackableUnpackableClass dst = + MessagePack.unpack(raw, OptionalBaseMessagePackableUnpackableClass.class); + assertEquals(src, dst); + } + + public static class OptionalBaseMessagePackableUnpackableClass { + @Optional + public OptionalMessagePackableUnpackableClass f0; + @Optional + public int f1; + @Optional + public List f2; + + public OptionalBaseMessagePackableUnpackableClass() { + } + } + + public static class OptionalMessagePackableUnpackableClass implements + MessagePackable, MessageUnpackable { + @Optional + public int f0; + @Optional + public int f1; + + public OptionalMessagePackableUnpackableClass() { + } + + @Override + public void messagePack(Packer packer) throws IOException { + packer.packArray(2); + packer.pack(f0); + packer.pack(f1); + } + + @Override + public void messageUnpack(Unpacker unpacker) throws IOException, + MessageTypeException { + if (unpacker.tryUnpackNull()) { + return; + } + unpacker.unpackArray(); + f0 = unpacker.unpackInt(); + f1 = unpacker.unpackInt(); + } + } +} + diff --git a/java/src/test/java/org/msgpack/util/codegen/TestPackConvert.java b/java/src/test/java/org/msgpack/util/codegen/TestPackConvert.java deleted file mode 100644 index 5ea7ce0..0000000 --- a/java/src/test/java/org/msgpack/util/codegen/TestPackConvert.java +++ /dev/null @@ -1,1876 +0,0 @@ -package org.msgpack.util.codegen; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.math.BigInteger; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -import junit.framework.TestCase; - -import org.junit.Test; -import org.msgpack.CustomConverter; -import org.msgpack.CustomMessage; -import org.msgpack.CustomPacker; -import org.msgpack.CustomUnpacker; -import org.msgpack.MessageConvertable; -import org.msgpack.MessagePackObject; -import org.msgpack.MessagePackable; -import org.msgpack.MessagePacker; -import org.msgpack.MessageTypeException; -import org.msgpack.Packer; -import org.msgpack.Template; -import org.msgpack.Unpacker; -import org.msgpack.annotation.MessagePackMessage; -import org.msgpack.annotation.MessagePackOptional; -import org.msgpack.annotation.MessagePackOrdinalEnum; -import org.msgpack.packer.OptionalPacker; -import org.msgpack.template.OptionalTemplate; - -public class TestPackConvert extends TestCase { - - @Test - public void testPrimitiveTypeFields00() throws Exception { - PrimitiveTypeFieldsClass src = new PrimitiveTypeFieldsClass(); - src.f0 = (byte) 0; - src.f1 = 1; - src.f2 = 2; - src.f3 = 3; - src.f4 = 4; - src.f5 = 5; - src.f6 = false; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = DynamicPacker - .create(PrimitiveTypeFieldsClass.class); - packer.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Template tmpl = DynamicTemplate.create(PrimitiveTypeFieldsClass.class); - Unpacker pac = new Unpacker(in); - Iterator it = pac.iterator(); - assertTrue(it.hasNext()); - MessagePackObject mpo = it.next(); - PrimitiveTypeFieldsClass dst = (PrimitiveTypeFieldsClass) tmpl - .convert(mpo); - assertEquals(src.f0, dst.f0); - assertEquals(src.f1, dst.f1); - assertEquals(src.f2, dst.f2); - assertEquals(src.f3, dst.f3); - assertEquals(src.f4, dst.f4); - assertEquals(src.f5, dst.f5); - assertEquals(src.f6, dst.f6); - assertFalse(it.hasNext()); - } - - @Test - public void testPrimitiveTypeFields01() throws Exception { - PrimitiveTypeFieldsClass src = null; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = new OptionalPacker(DynamicPacker - .create(PrimitiveTypeFieldsClass.class)); - packer.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Template tmpl = new OptionalTemplate(DynamicTemplate - .create(PrimitiveTypeFieldsClass.class)); - Unpacker pac = new Unpacker(in); - Iterator it = pac.iterator(); - assertTrue(it.hasNext()); - MessagePackObject mpo = it.next(); - PrimitiveTypeFieldsClass dst = (PrimitiveTypeFieldsClass) tmpl - .convert(mpo); - assertEquals(src, dst); - assertFalse(it.hasNext()); - } - - public static class PrimitiveTypeFieldsClass { - public byte f0; - public short f1; - public int f2; - public long f3; - public float f4; - public double f5; - public boolean f6; - - public PrimitiveTypeFieldsClass() { - } - } - - @Test - public void testOptionalPrimitiveTypeFields00() throws Exception { - OptionalPrimitiveTypeFieldsClass src = new OptionalPrimitiveTypeFieldsClass(); - src.f0 = (byte) 0; - src.f1 = 1; - src.f2 = 2; - src.f3 = 3; - src.f4 = 4; - src.f5 = 5; - src.f6 = false; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = DynamicPacker - .create(OptionalPrimitiveTypeFieldsClass.class); - packer.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Template tmpl = DynamicTemplate - .create(OptionalPrimitiveTypeFieldsClass.class); - Unpacker pac = new Unpacker(in); - Iterator it = pac.iterator(); - assertTrue(it.hasNext()); - MessagePackObject mpo = it.next(); - OptionalPrimitiveTypeFieldsClass dst = (OptionalPrimitiveTypeFieldsClass) tmpl - .convert(mpo); - assertEquals(src.f0, dst.f0); - assertEquals(src.f1, dst.f1); - assertEquals(src.f2, dst.f2); - assertEquals(src.f3, dst.f3); - assertEquals(src.f4, dst.f4); - assertEquals(src.f5, dst.f5); - assertEquals(src.f6, dst.f6); - assertFalse(it.hasNext()); - } - - @Test - public void testOptionalPrimitiveTypeFields01() throws Exception { - OptionalPrimitiveTypeFieldsClass src = new OptionalPrimitiveTypeFieldsClass(); - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = DynamicPacker - .create(OptionalPrimitiveTypeFieldsClass.class); - packer.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Template tmpl = DynamicTemplate - .create(OptionalPrimitiveTypeFieldsClass.class); - Unpacker pac = new Unpacker(in); - Iterator it = pac.iterator(); - assertTrue(it.hasNext()); - MessagePackObject mpo = it.next(); - OptionalPrimitiveTypeFieldsClass dst = (OptionalPrimitiveTypeFieldsClass) tmpl - .convert(mpo); - assertEquals(src.f0, dst.f0); - assertEquals(src.f1, dst.f1); - assertEquals(src.f2, dst.f2); - assertEquals(src.f3, dst.f3); - assertEquals(src.f4, dst.f4); - assertEquals(src.f5, dst.f5); - assertEquals(src.f6, dst.f6); - assertFalse(it.hasNext()); - } - - @Test - public void testOptionalPrimitiveTypeFields02() throws Exception { - OptionalPrimitiveTypeFieldsClass src = null; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = new OptionalPacker(DynamicPacker - .create(OptionalPrimitiveTypeFieldsClass.class)); - packer.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Template tmpl = new OptionalTemplate(DynamicTemplate - .create(OptionalPrimitiveTypeFieldsClass.class)); - Unpacker pac = new Unpacker(in); - Iterator it = pac.iterator(); - assertTrue(it.hasNext()); - MessagePackObject mpo = it.next(); - OptionalPrimitiveTypeFieldsClass dst = (OptionalPrimitiveTypeFieldsClass) tmpl - .convert(mpo); - assertEquals(src, dst); - assertFalse(it.hasNext()); - } - - public static class OptionalPrimitiveTypeFieldsClass { - @MessagePackOptional - public byte f0; - @MessagePackOptional - public short f1; - @MessagePackOptional - public int f2; - @MessagePackOptional - public long f3; - @MessagePackOptional - public float f4; - @MessagePackOptional - public double f5; - @MessagePackOptional - public boolean f6; - - public OptionalPrimitiveTypeFieldsClass() { - } - } - - @Test - public void testGeneralReferenceTypeFieldsClass00() throws Exception { - GeneralReferenceTypeFieldsClass src = new GeneralReferenceTypeFieldsClass(); - src.f0 = 0; - src.f1 = 1; - src.f2 = 2; - src.f3 = (long) 3; - src.f4 = (float) 4; - src.f5 = (double) 5; - src.f6 = false; - src.f7 = new BigInteger("7"); - src.f8 = "8"; - src.f9 = new byte[] { 0x01, 0x02 }; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = DynamicPacker - .create(GeneralReferenceTypeFieldsClass.class); - packer.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Template tmpl = DynamicTemplate - .create(GeneralReferenceTypeFieldsClass.class); - Unpacker pac = new Unpacker(in); - Iterator it = pac.iterator(); - assertTrue(it.hasNext()); - MessagePackObject mpo = it.next(); - GeneralReferenceTypeFieldsClass dst = (GeneralReferenceTypeFieldsClass) tmpl - .convert(mpo); - assertEquals(src.f0, dst.f0); - assertEquals(src.f1, dst.f1); - assertEquals(src.f2, dst.f2); - assertEquals(src.f3, dst.f3); - assertEquals(src.f4, dst.f4); - assertEquals(src.f5, dst.f5); - assertEquals(src.f6, dst.f6); - assertEquals(src.f7, dst.f7); - assertEquals(src.f8, dst.f8); - assertEquals(src.f9[0], dst.f9[0]); - assertEquals(src.f9[1], dst.f9[1]); - assertFalse(it.hasNext()); - } - - @Test - public void testGeneralReferenceTypeFieldsClass01() throws Exception { - GeneralReferenceTypeFieldsClass src = null; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = new OptionalPacker(DynamicPacker - .create(GeneralReferenceTypeFieldsClass.class)); - packer.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Template tmpl = new OptionalTemplate(DynamicTemplate - .create(GeneralReferenceTypeFieldsClass.class)); - Unpacker pac = new Unpacker(in); - Iterator it = pac.iterator(); - assertTrue(it.hasNext()); - MessagePackObject mpo = it.next(); - GeneralReferenceTypeFieldsClass dst = (GeneralReferenceTypeFieldsClass) tmpl - .convert(mpo); - assertEquals(src, dst); - assertFalse(it.hasNext()); - } - - public static class GeneralReferenceTypeFieldsClass { - public Byte f0; - public Short f1; - public Integer f2; - public Long f3; - public Float f4; - public Double f5; - public Boolean f6; - public BigInteger f7; - public String f8; - public byte[] f9; - - public GeneralReferenceTypeFieldsClass() { - } - } - - @Test - public void testOptionalGeneralReferenceTypeFieldsClass00() - throws Exception { - OptionalGeneralReferenceTypeFieldsClass src = new OptionalGeneralReferenceTypeFieldsClass(); - src.f0 = 0; - src.f1 = 1; - src.f2 = 2; - src.f3 = (long) 3; - src.f4 = (float) 4; - src.f5 = (double) 5; - src.f6 = false; - src.f7 = new BigInteger("7"); - src.f8 = "8"; - src.f9 = new byte[] { 0x01, 0x02 }; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = DynamicPacker - .create(OptionalGeneralReferenceTypeFieldsClass.class); - packer.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Template tmpl = DynamicTemplate - .create(OptionalGeneralReferenceTypeFieldsClass.class); - Unpacker pac = new Unpacker(in); - Iterator it = pac.iterator(); - assertTrue(it.hasNext()); - MessagePackObject mpo = it.next(); - OptionalGeneralReferenceTypeFieldsClass dst = (OptionalGeneralReferenceTypeFieldsClass) tmpl - .convert(mpo); - assertEquals(src.f0, dst.f0); - assertEquals(src.f1, dst.f1); - assertEquals(src.f2, dst.f2); - assertEquals(src.f3, dst.f3); - assertEquals(src.f4, dst.f4); - assertEquals(src.f5, dst.f5); - assertEquals(src.f6, dst.f6); - assertEquals(src.f7, dst.f7); - assertEquals(src.f8, dst.f8); - assertEquals(src.f9[0], dst.f9[0]); - assertEquals(src.f9[1], dst.f9[1]); - assertFalse(it.hasNext()); - } - - @Test - public void testOptionalGeneralReferenceTypeFieldsClass01() - throws Exception { - OptionalGeneralReferenceTypeFieldsClass src = new OptionalGeneralReferenceTypeFieldsClass(); - src.f0 = null; - src.f1 = null; - src.f2 = null; - src.f3 = null; - src.f4 = null; - src.f5 = null; - src.f6 = null; - src.f7 = null; - src.f8 = null; - src.f9 = null; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = DynamicPacker - .create(OptionalGeneralReferenceTypeFieldsClass.class); - packer.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Template tmpl = DynamicTemplate - .create(OptionalGeneralReferenceTypeFieldsClass.class); - Unpacker pac = new Unpacker(in); - Iterator it = pac.iterator(); - assertTrue(it.hasNext()); - MessagePackObject mpo = it.next(); - OptionalGeneralReferenceTypeFieldsClass dst = (OptionalGeneralReferenceTypeFieldsClass) tmpl - .convert(mpo); - assertEquals(src.f0, dst.f0); - assertEquals(src.f1, dst.f1); - assertEquals(src.f2, dst.f2); - assertEquals(src.f3, dst.f3); - assertEquals(src.f4, dst.f4); - assertEquals(src.f5, dst.f5); - assertEquals(src.f6, dst.f6); - assertEquals(src.f7, dst.f7); - assertEquals(src.f8, dst.f8); - assertEquals(src.f9, dst.f9); - assertFalse(it.hasNext()); - } - - @Test - public void testOptionalGeneralReferenceTypeFieldsClass02() - throws Exception { - OptionalGeneralReferenceTypeFieldsClass src = null; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = new OptionalPacker(DynamicPacker - .create(OptionalGeneralReferenceTypeFieldsClass.class)); - packer.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Template tmpl = new OptionalTemplate(DynamicTemplate - .create(OptionalGeneralReferenceTypeFieldsClass.class)); - Unpacker pac = new Unpacker(in); - Iterator it = pac.iterator(); - assertTrue(it.hasNext()); - MessagePackObject mpo = it.next(); - OptionalGeneralReferenceTypeFieldsClass dst = (OptionalGeneralReferenceTypeFieldsClass) tmpl - .convert(mpo); - assertEquals(src, dst); - assertFalse(it.hasNext()); - } - - public static class OptionalGeneralReferenceTypeFieldsClass { - @MessagePackOptional - public Byte f0; - @MessagePackOptional - public Short f1; - @MessagePackOptional - public Integer f2; - @MessagePackOptional - public Long f3; - @MessagePackOptional - public Float f4; - @MessagePackOptional - public Double f5; - @MessagePackOptional - public Boolean f6; - @MessagePackOptional - public BigInteger f7; - @MessagePackOptional - public String f8; - @MessagePackOptional - public byte[] f9; - - public OptionalGeneralReferenceTypeFieldsClass() { - } - } - - @Test - public void testListTypes00() throws Exception { - SampleListTypes src = new SampleListTypes(); - src.f0 = new ArrayList(); - src.f1 = new ArrayList(); - src.f1.add(1); - src.f1.add(2); - src.f1.add(3); - src.f2 = new ArrayList(); - src.f2.add("e1"); - src.f2.add("e2"); - src.f2.add("e3"); - src.f3 = new ArrayList>(); - src.f3.add(src.f2); - src.f4 = new ArrayList(); - SampleListNestedType slnt = new SampleListNestedType(); - slnt.f0 = new byte[] { 0x01, 0x02 }; - slnt.f1 = "muga"; - src.f4.add(slnt); - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = DynamicPacker.create(SampleListTypes.class); - packer.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Template tmpl = DynamicTemplate.create(SampleListTypes.class); - Unpacker pac = new Unpacker(in); - Iterator it = pac.iterator(); - assertTrue(it.hasNext()); - MessagePackObject mpo = it.next(); - SampleListTypes dst = (SampleListTypes) tmpl.convert(mpo); - assertEquals(src.f0.size(), dst.f0.size()); - assertEquals(src.f1.size(), dst.f1.size()); - for (int i = 0; i < src.f1.size(); ++i) { - assertEquals(src.f1.get(i), dst.f1.get(i)); - } - assertEquals(src.f2.size(), dst.f2.size()); - for (int i = 0; i < src.f2.size(); ++i) { - assertEquals(src.f2.get(i), dst.f2.get(i)); - } - assertEquals(src.f3.size(), dst.f3.size()); - for (int i = 0; i < src.f3.size(); ++i) { - List srclist = src.f3.get(i); - List dstlist = dst.f3.get(i); - assertEquals(srclist.size(), dstlist.size()); - for (int j = 0; j < srclist.size(); ++j) { - assertEquals(srclist.get(j), dstlist.get(j)); - } - } - assertEquals(src.f4.size(), dst.f4.size()); - for (int i = 0; i < src.f4.size(); ++i) { - SampleListNestedType s = src.f4.get(i); - SampleListNestedType d = dst.f4.get(i); - assertEquals(s.f0[0], d.f0[0]); - assertEquals(s.f0[1], d.f0[1]); - assertEquals(s.f1, d.f1); - } - assertFalse(it.hasNext()); - } - - @Test - public void testListTypes01() throws Exception { - SampleListTypes src = null; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = new OptionalPacker(DynamicPacker - .create(SampleListTypes.class)); - packer.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Template tmpl = new OptionalTemplate(DynamicTemplate - .create(SampleListTypes.class)); - Unpacker pac = new Unpacker(in); - Iterator it = pac.iterator(); - assertTrue(it.hasNext()); - MessagePackObject mpo = it.next(); - SampleListTypes dst = (SampleListTypes) tmpl.convert(mpo); - assertEquals(src, dst); - assertFalse(it.hasNext()); - } - - public static class SampleListTypes { - public List f0; - public List f1; - public List f2; - public List> f3; - public List f4; - - public SampleListTypes() { - } - } - - @MessagePackMessage - public static class SampleListNestedType { - public byte[] f0; - public String f1; - - public SampleListNestedType() { - } - } - - @Test - public void testOptionalListTypes00() throws Exception { - SampleOptionalListTypes src = new SampleOptionalListTypes(); - src.f0 = new ArrayList(); - src.f1 = new ArrayList(); - src.f1.add(1); - src.f1.add(2); - src.f1.add(3); - src.f2 = new ArrayList(); - src.f2.add("e1"); - src.f2.add("e2"); - src.f2.add("e3"); - src.f3 = new ArrayList>(); - src.f3.add(src.f2); - src.f4 = new ArrayList(); - SampleOptionalListNestedType slnt = new SampleOptionalListNestedType(); - slnt.f0 = new byte[] { 0x01, 0x02 }; - slnt.f1 = "muga"; - src.f4.add(slnt); - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = DynamicPacker - .create(SampleOptionalListTypes.class); - packer.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Template tmpl = DynamicTemplate.create(SampleOptionalListTypes.class); - Unpacker pac = new Unpacker(in); - Iterator it = pac.iterator(); - assertTrue(it.hasNext()); - MessagePackObject mpo = it.next(); - SampleOptionalListTypes dst = (SampleOptionalListTypes) tmpl - .convert(mpo); - assertEquals(src.f0.size(), dst.f0.size()); - assertEquals(src.f1.size(), dst.f1.size()); - for (int i = 0; i < src.f1.size(); ++i) { - assertEquals(src.f1.get(i), dst.f1.get(i)); - } - assertEquals(src.f2.size(), dst.f2.size()); - for (int i = 0; i < src.f2.size(); ++i) { - assertEquals(src.f2.get(i), dst.f2.get(i)); - } - assertEquals(src.f3.size(), dst.f3.size()); - for (int i = 0; i < src.f3.size(); ++i) { - List srclist = src.f3.get(i); - List dstlist = dst.f3.get(i); - assertEquals(srclist.size(), dstlist.size()); - for (int j = 0; j < srclist.size(); ++j) { - assertEquals(srclist.get(j), dstlist.get(j)); - } - } - assertEquals(src.f4.size(), dst.f4.size()); - for (int i = 0; i < src.f4.size(); ++i) { - SampleOptionalListNestedType s = src.f4.get(i); - SampleOptionalListNestedType d = dst.f4.get(i); - assertEquals(s.f0[0], d.f0[0]); - assertEquals(s.f0[1], d.f0[1]); - assertEquals(s.f1, d.f1); - } - assertFalse(it.hasNext()); - } - - @Test - public void testOptionalListTypes01() throws Exception { - SampleOptionalListTypes src = new SampleOptionalListTypes(); - src.f0 = new ArrayList(); - src.f1 = null; - src.f2 = new ArrayList(); - src.f3 = null; - src.f4 = new ArrayList(); - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = DynamicPacker - .create(SampleOptionalListTypes.class); - packer.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Template tmpl = DynamicTemplate.create(SampleOptionalListTypes.class); - Unpacker pac = new Unpacker(in); - Iterator it = pac.iterator(); - assertTrue(it.hasNext()); - MessagePackObject mpo = it.next(); - SampleOptionalListTypes dst = (SampleOptionalListTypes) tmpl - .convert(mpo); - assertEquals(src.f0.size(), dst.f0.size()); - assertEquals(src.f1, dst.f1); - assertEquals(src.f2.size(), dst.f2.size()); - assertEquals(src.f3, dst.f3); - assertEquals(src.f4.size(), dst.f4.size()); - assertFalse(it.hasNext()); - } - - @Test - public void testOptionalListTypes02() throws Exception { - SampleOptionalListTypes src = null; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = new OptionalPacker(DynamicPacker - .create(SampleOptionalListTypes.class)); - packer.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Template tmpl = new OptionalTemplate(DynamicTemplate - .create(SampleOptionalListTypes.class)); - Unpacker pac = new Unpacker(in); - Iterator it = pac.iterator(); - assertTrue(it.hasNext()); - MessagePackObject mpo = it.next(); - SampleOptionalListTypes dst = (SampleOptionalListTypes) tmpl - .convert(mpo); - assertEquals(src, dst); - assertFalse(it.hasNext()); - } - - public static class SampleOptionalListTypes { - @MessagePackOptional - public List f0; - @MessagePackOptional - public List f1; - @MessagePackOptional - public List f2; - @MessagePackOptional - public List> f3; - @MessagePackOptional - public List f4; - - public SampleOptionalListTypes() { - } - } - - @MessagePackMessage - public static class SampleOptionalListNestedType { - @MessagePackOptional - public byte[] f0; - @MessagePackOptional - public String f1; - - public SampleOptionalListNestedType() { - } - } - - @Test - public void testMapTypes00() throws Exception { - SampleMapTypes src = new SampleMapTypes(); - src.f0 = new HashMap(); - src.f1 = new HashMap(); - src.f1.put(1, 1); - src.f1.put(2, 2); - src.f1.put(3, 3); - src.f2 = new HashMap(); - src.f2.put("k1", 1); - src.f2.put("k2", 2); - src.f2.put("k3", 3); - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = DynamicPacker.create(SampleMapTypes.class); - packer.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Template tmpl = DynamicTemplate.create(SampleMapTypes.class); - Unpacker pac = new Unpacker(in); - Iterator it = pac.iterator(); - assertTrue(it.hasNext()); - MessagePackObject mpo = it.next(); - SampleMapTypes dst = (SampleMapTypes) tmpl.convert(mpo); - assertEquals(src.f0.size(), dst.f0.size()); - assertEquals(src.f1.size(), dst.f1.size()); - Iterator srcf1 = src.f1.keySet().iterator(); - Iterator dstf1 = dst.f1.keySet().iterator(); - while (srcf1.hasNext()) { - Integer s1 = srcf1.next(); - Integer d1 = dstf1.next(); - assertEquals(s1, d1); - assertEquals(src.f1.get(s1), dst.f1.get(d1)); - } - assertEquals(src.f2.size(), dst.f2.size()); - Iterator srcf2 = src.f2.keySet().iterator(); - Iterator dstf2 = dst.f2.keySet().iterator(); - while (srcf2.hasNext()) { - String s2 = srcf2.next(); - String d2 = dstf2.next(); - assertEquals(s2, d2); - assertEquals(src.f2.get(s2), dst.f2.get(d2)); - } - assertFalse(it.hasNext()); - } - - @Test - public void testMapTypes02() throws Exception { - SampleMapTypes src = null; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = new OptionalPacker(DynamicPacker - .create(SampleMapTypes.class)); - packer.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Template tmpl = new OptionalTemplate(DynamicTemplate - .create(SampleMapTypes.class)); - Unpacker pac = new Unpacker(in); - Iterator it = pac.iterator(); - assertTrue(it.hasNext()); - MessagePackObject mpo = it.next(); - SampleMapTypes dst = (SampleMapTypes) tmpl.convert(mpo); - assertEquals(src, dst); - assertFalse(it.hasNext()); - } - - public static class SampleMapTypes { - public Map f0; - public Map f1; - public Map f2; - - public SampleMapTypes() { - } - } - - @Test - public void testOptionalMapTypes00() throws Exception { - SampleOptionalMapTypes src = new SampleOptionalMapTypes(); - src.f0 = new HashMap(); - src.f1 = new HashMap(); - src.f1.put(1, 1); - src.f1.put(2, 2); - src.f1.put(3, 3); - src.f2 = new HashMap(); - src.f2.put("k1", 1); - src.f2.put("k2", 2); - src.f2.put("k3", 3); - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = DynamicPacker - .create(SampleOptionalMapTypes.class); - packer.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Template tmpl = DynamicTemplate.create(SampleOptionalMapTypes.class); - Unpacker pac = new Unpacker(in); - Iterator it = pac.iterator(); - assertTrue(it.hasNext()); - MessagePackObject mpo = it.next(); - SampleOptionalMapTypes dst = (SampleOptionalMapTypes) tmpl.convert(mpo); - assertEquals(src.f0.size(), dst.f0.size()); - assertEquals(src.f1.size(), dst.f1.size()); - Iterator srcf1 = src.f1.keySet().iterator(); - Iterator dstf1 = dst.f1.keySet().iterator(); - while (srcf1.hasNext()) { - Integer s1 = srcf1.next(); - Integer d1 = dstf1.next(); - assertEquals(s1, d1); - assertEquals(src.f1.get(s1), dst.f1.get(d1)); - } - assertEquals(src.f2.size(), dst.f2.size()); - Iterator srcf2 = src.f2.keySet().iterator(); - Iterator dstf2 = dst.f2.keySet().iterator(); - while (srcf2.hasNext()) { - String s2 = srcf2.next(); - String d2 = dstf2.next(); - assertEquals(s2, d2); - assertEquals(src.f2.get(s2), dst.f2.get(d2)); - } - assertFalse(it.hasNext()); - } - - @Test - public void testOptionalMapTypes01() throws Exception { - SampleOptionalMapTypes src = new SampleOptionalMapTypes(); - src.f0 = new HashMap(); - src.f1 = null; - src.f2 = new HashMap(); - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = DynamicPacker - .create(SampleOptionalMapTypes.class); - packer.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Template tmpl = DynamicTemplate.create(SampleOptionalMapTypes.class); - Unpacker pac = new Unpacker(in); - Iterator it = pac.iterator(); - assertTrue(it.hasNext()); - MessagePackObject mpo = it.next(); - SampleOptionalMapTypes dst = (SampleOptionalMapTypes) tmpl.convert(mpo); - assertEquals(src.f0.size(), dst.f0.size()); - assertEquals(src.f1, dst.f1); - assertEquals(src.f2.size(), dst.f2.size()); - assertFalse(it.hasNext()); - } - - @Test - public void testOptionalMapTypes02() throws Exception { - SampleOptionalMapTypes src = null; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = new OptionalPacker(DynamicPacker - .create(SampleOptionalMapTypes.class)); - packer.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Template tmpl = new OptionalTemplate(DynamicTemplate - .create(SampleOptionalMapTypes.class)); - Unpacker pac = new Unpacker(in); - Iterator it = pac.iterator(); - assertTrue(it.hasNext()); - MessagePackObject mpo = it.next(); - SampleOptionalMapTypes dst = (SampleOptionalMapTypes) tmpl.convert(mpo); - assertEquals(src, dst); - assertFalse(it.hasNext()); - } - - public static class SampleOptionalMapTypes { - @MessagePackOptional - public Map f0; - @MessagePackOptional - public Map f1; - @MessagePackOptional - public Map f2; - - public SampleOptionalMapTypes() { - } - } - - @Test - public void testDefaultConstructorModifiers01() throws Exception { - try { - DynamicPacker.create(NoDefaultConstructorClass.class); - fail(); - } catch (DynamicCodeGenException e) { - assertTrue(true); - } - assertTrue(true); - try { - DynamicPacker.create(PrivateDefaultConstructorClass.class); - fail(); - } catch (DynamicCodeGenException e) { - assertTrue(true); - } - assertTrue(true); - try { - DynamicPacker.create(ProtectedDefaultConstructorClass.class); - fail(); - } catch (DynamicCodeGenException e) { - assertTrue(true); - } - assertTrue(true); - try { - DynamicPacker.create(PackageDefaultConstructorClass.class); - fail(); - } catch (DynamicCodeGenException e) { - assertTrue(true); - } - assertTrue(true); - } - - @Test - public void testDefaultConstructorModifiers02() throws Exception { - try { - DynamicTemplate.create(NoDefaultConstructorClass.class); - fail(); - } catch (DynamicCodeGenException e) { - assertTrue(true); - } - assertTrue(true); - try { - DynamicTemplate.create(PrivateDefaultConstructorClass.class); - fail(); - } catch (DynamicCodeGenException e) { - assertTrue(true); - } - assertTrue(true); - try { - DynamicTemplate.create(ProtectedDefaultConstructorClass.class); - fail(); - } catch (DynamicCodeGenException e) { - assertTrue(true); - } - assertTrue(true); - try { - DynamicTemplate.create(PackageDefaultConstructorClass.class); - fail(); - } catch (DynamicCodeGenException e) { - assertTrue(true); - } - assertTrue(true); - } - - public static class NoDefaultConstructorClass { - public NoDefaultConstructorClass(int i) { - } - } - - public static class PrivateDefaultConstructorClass { - private PrivateDefaultConstructorClass() { - } - } - - public static class ProtectedDefaultConstructorClass { - protected ProtectedDefaultConstructorClass() { - } - } - - public static class PackageDefaultConstructorClass { - PackageDefaultConstructorClass() { - } - } - - @Test - public void testClassModifiers01() throws Exception { - try { - DynamicPacker.create(PrivateModifierClass.class); - fail(); - } catch (DynamicCodeGenException e) { - assertTrue(true); - } - assertTrue(true); - try { - DynamicPacker.create(ProtectedModifierClass.class); - fail(); - } catch (DynamicCodeGenException e) { - assertTrue(true); - } - assertTrue(true); - try { - DynamicPacker.create(PackageModifierClass.class); - fail(); - } catch (DynamicCodeGenException e) { - assertTrue(true); - } - assertTrue(true); - } - - @Test - public void testClassModifiers02() throws Exception { - try { - DynamicTemplate.create(PrivateModifierClass.class); - fail(); - } catch (DynamicCodeGenException e) { - assertTrue(true); - } - assertTrue(true); - try { - DynamicTemplate.create(ProtectedModifierClass.class); - fail(); - } catch (DynamicCodeGenException e) { - assertTrue(true); - } - assertTrue(true); - try { - DynamicTemplate.create(PackageModifierClass.class); - fail(); - } catch (DynamicCodeGenException e) { - assertTrue(true); - } - assertTrue(true); - } - - private static class PrivateModifierClass { - } - - protected static class ProtectedModifierClass { - protected ProtectedModifierClass() { - } - } - - static class PackageModifierClass { - } - - @Test - public void testFinalClassAndAbstractClass01() throws Exception { - try { - DynamicPacker.create(FinalModifierClass.class); - assertTrue(true); - } catch (DynamicCodeGenException e) { - fail(); - } - assertTrue(true); - try { - DynamicPacker.create(AbstractModifierClass.class); - fail(); - } catch (DynamicCodeGenException e) { - assertTrue(true); - } - assertTrue(true); - } - - @Test - public void testFinalClassAndAbstractClass02() throws Exception { - try { - DynamicTemplate.create(FinalModifierClass.class); - assertTrue(true); - } catch (DynamicCodeGenException e) { - fail(); - } - assertTrue(true); - try { - DynamicTemplate.create(AbstractModifierClass.class); - fail(); - } catch (DynamicCodeGenException e) { - assertTrue(true); - } - assertTrue(true); - } - - public final static class FinalModifierClass { - } - - public abstract static class AbstractModifierClass { - } - - @Test - public void testInterfaceAndEnumType01() throws Exception { - try { - DynamicPacker.create(SampleInterface.class); - fail(); - } catch (DynamicCodeGenException e) { - assertTrue(true); - } - assertTrue(true); - try { - DynamicPacker.create(SampleEnum.class); - fail(); - } catch (DynamicCodeGenException e) { - assertTrue(true); - } - assertTrue(true); - } - - @Test - public void testInterfaceType() throws Exception { - try { - DynamicTemplate.create(SampleInterface.class); - fail(); - } catch (DynamicCodeGenException e) { - assertTrue(true); - } - assertTrue(true); - } - - public interface SampleInterface { - } - - @Test - public void testEnumTypeForOrdinal00() throws Exception { - SampleEnumFieldClass src = new SampleEnumFieldClass(); - src.f0 = 0; - src.f1 = SampleEnum.ONE; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = DynamicPacker.create(SampleEnumFieldClass.class); - packer.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Template tmpl = DynamicTemplate.create(SampleEnumFieldClass.class); - Unpacker pac = new Unpacker(in); - Iterator it = pac.iterator(); - assertTrue(it.hasNext()); - MessagePackObject mpo = it.next(); - SampleEnumFieldClass dst = (SampleEnumFieldClass) tmpl.convert(mpo); - assertTrue(src.f0 == dst.f0); - assertTrue(src.f1 == dst.f1); - assertFalse(it.hasNext()); - } - - @Test - public void testEnumTypeForOrdinal01() throws Exception { - SampleEnumFieldClass src = null; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = new OptionalPacker(DynamicPacker - .create(SampleEnumFieldClass.class)); - packer.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Template tmpl = new OptionalTemplate(DynamicTemplate - .create(SampleEnumFieldClass.class)); - Unpacker pac = new Unpacker(in); - Iterator it = pac.iterator(); - assertTrue(it.hasNext()); - MessagePackObject mpo = it.next(); - SampleEnumFieldClass dst = (SampleEnumFieldClass) tmpl.convert(mpo); - assertEquals(src, dst); - assertFalse(it.hasNext()); - } - - public static class SampleEnumFieldClass { - public int f0; - public SampleEnum f1; - - public SampleEnumFieldClass() { - } - } - - @MessagePackOrdinalEnum - public enum SampleEnum { - ONE, TWO, THREE; - } - - @Test - public void testOptionalEnumTypeForOrdinal00() throws Exception { - SampleOptionalEnumFieldClass src = new SampleOptionalEnumFieldClass(); - src.f0 = 0; - src.f1 = SampleOptionalEnum.ONE; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = DynamicPacker - .create(SampleOptionalEnumFieldClass.class); - packer.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Template tmpl = DynamicTemplate - .create(SampleOptionalEnumFieldClass.class); - Unpacker pac = new Unpacker(in); - Iterator it = pac.iterator(); - assertTrue(it.hasNext()); - MessagePackObject mpo = it.next(); - SampleOptionalEnumFieldClass dst = (SampleOptionalEnumFieldClass) tmpl - .convert(mpo); - assertTrue(src.f0 == dst.f0); - assertTrue(src.f1 == dst.f1); - assertFalse(it.hasNext()); - } - - @Test - public void testOptionalEnumTypeForOrdinal01() throws Exception { - SampleOptionalEnumFieldClass src = new SampleOptionalEnumFieldClass(); - src.f1 = null; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = DynamicPacker - .create(SampleOptionalEnumFieldClass.class); - packer.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Template tmpl = DynamicTemplate - .create(SampleOptionalEnumFieldClass.class); - Unpacker pac = new Unpacker(in); - Iterator it = pac.iterator(); - assertTrue(it.hasNext()); - MessagePackObject mpo = it.next(); - SampleOptionalEnumFieldClass dst = (SampleOptionalEnumFieldClass) tmpl - .convert(mpo); - assertEquals(src.f0, dst.f0); - assertEquals(src.f1, dst.f1); - assertFalse(it.hasNext()); - } - - @Test - public void testOptionalEnumTypeForOrdinal02() throws Exception { - SampleOptionalEnumFieldClass src = null; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = new OptionalPacker(DynamicPacker - .create(SampleOptionalEnumFieldClass.class)); - packer.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Template tmpl = new OptionalTemplate(DynamicTemplate - .create(SampleOptionalEnumFieldClass.class)); - Unpacker pac = new Unpacker(in); - Iterator it = pac.iterator(); - assertTrue(it.hasNext()); - MessagePackObject mpo = it.next(); - SampleOptionalEnumFieldClass dst = (SampleOptionalEnumFieldClass) tmpl - .convert(mpo); - assertEquals(src, dst); - assertFalse(it.hasNext()); - } - - public static class SampleOptionalEnumFieldClass { - @MessagePackOptional - public int f0; - @MessagePackOptional - public SampleOptionalEnum f1; - - public SampleOptionalEnumFieldClass() { - } - } - - @MessagePackOrdinalEnum - public enum SampleOptionalEnum { - ONE, TWO, THREE; - } - - @Test - public void testFieldModifiers() throws Exception { - FieldModifiersClass src = new FieldModifiersClass(); - src.f0 = 0; - src.f2 = 2; - src.f3 = 3; - src.f4 = 4; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = DynamicPacker.create(FieldModifiersClass.class); - packer.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Template tmpl = DynamicTemplate.create(FieldModifiersClass.class); - Unpacker pac = new Unpacker(in); - Iterator it = pac.iterator(); - assertTrue(it.hasNext()); - MessagePackObject mpo = it.next(); - FieldModifiersClass dst = (FieldModifiersClass) tmpl.convert(mpo); - assertTrue(src.f0 == dst.f0); - assertTrue(src.f1 == dst.f1); - assertTrue(src.f2 != dst.f2); - assertTrue(src.f3 != dst.f3); - assertTrue(src.f4 != dst.f4); - assertFalse(it.hasNext()); - } - - public static class FieldModifiersClass { - public int f0; - public final int f1 = 1; - private int f2; - protected int f3; - int f4; - - public FieldModifiersClass() { - } - } - - @Test - public void testOptionalFieldModifiers() throws Exception { - OptionalFieldModifiersClass src = new OptionalFieldModifiersClass(); - src.f0 = 0; - src.f2 = 2; - src.f3 = 3; - src.f4 = 4; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = DynamicPacker - .create(OptionalFieldModifiersClass.class); - packer.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Template tmpl = DynamicTemplate - .create(OptionalFieldModifiersClass.class); - Unpacker pac = new Unpacker(in); - Iterator it = pac.iterator(); - assertTrue(it.hasNext()); - MessagePackObject mpo = it.next(); - OptionalFieldModifiersClass dst = (OptionalFieldModifiersClass) tmpl - .convert(mpo); - assertTrue(src.f0 == dst.f0); - assertTrue(src.f1 == dst.f1); - assertTrue(src.f2 != dst.f2); - assertTrue(src.f3 != dst.f3); - assertTrue(src.f4 != dst.f4); - assertFalse(it.hasNext()); - } - - public static class OptionalFieldModifiersClass { - @MessagePackOptional - public int f0; - @MessagePackOptional - public final int f1 = 1; - private int f2; - protected int f3; - int f4; - - public OptionalFieldModifiersClass() { - } - } - - @Test - public void testNestedFieldClass00() throws Exception { - Template tmpl2 = DynamicTemplate.create(NestedClass.class); - CustomMessage.register(NestedClass.class, tmpl2); - Template tmpl = DynamicTemplate.create(BaseClass.class); - CustomMessage.register(BaseClass.class, tmpl); - BaseClass src = new BaseClass(); - NestedClass src2 = new NestedClass(); - src.f0 = 0; - src2.f2 = 2; - src.f1 = src2; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - tmpl.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Unpacker pac = new Unpacker(in); - Iterator it = pac.iterator(); - assertTrue(it.hasNext()); - MessagePackObject mpo = it.next(); - BaseClass dst = (BaseClass) tmpl.convert(mpo); - assertTrue(src.f0 == dst.f0); - assertTrue(src.f1.f2 == dst.f1.f2); - assertFalse(it.hasNext()); - } - - @Test - public void testNestedFieldClass02() throws Exception { - Template tmpl2 = DynamicTemplate.create(NestedClass.class); - CustomMessage.register(NestedClass.class, tmpl2); - Template tmpl = new OptionalTemplate(DynamicTemplate.create(BaseClass.class)); - CustomMessage.register(BaseClass.class, tmpl); - BaseClass src = null; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - tmpl.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Unpacker pac = new Unpacker(in); - Iterator it = pac.iterator(); - assertTrue(it.hasNext()); - MessagePackObject mpo = it.next(); - BaseClass dst = (BaseClass) tmpl.convert(mpo); - assertEquals(src, dst); - assertFalse(it.hasNext()); - } - - public static class BaseClass { - public int f0; - public NestedClass f1; - - public BaseClass() { - } - } - - public static class NestedClass { - public int f2; - - public NestedClass() { - } - } - - @Test - public void testOptionalNestedFieldClass00() throws Exception { - Template tmpl2 = DynamicTemplate.create(OptionalNestedClass.class); - CustomMessage.register(OptionalNestedClass.class, tmpl2); - Template tmpl = DynamicTemplate.create(OptionalBaseClass.class); - CustomMessage.register(OptionalBaseClass.class, tmpl); - OptionalBaseClass src = new OptionalBaseClass(); - OptionalNestedClass src2 = new OptionalNestedClass(); - src.f0 = 0; - src2.f2 = 2; - src.f1 = src2; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - tmpl.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Unpacker pac = new Unpacker(in); - Iterator it = pac.iterator(); - assertTrue(it.hasNext()); - MessagePackObject mpo = it.next(); - OptionalBaseClass dst = (OptionalBaseClass) tmpl.convert(mpo); - assertTrue(src.f0 == dst.f0); - assertTrue(src.f1.f2 == dst.f1.f2); - assertFalse(it.hasNext()); - } - - @Test - public void testOptionalNestedFieldClass01() throws Exception { - Template tmpl2 = DynamicTemplate.create(OptionalNestedClass.class); - CustomMessage.register(OptionalNestedClass.class, tmpl2); - Template tmpl = DynamicTemplate.create(OptionalBaseClass.class); - CustomMessage.register(OptionalBaseClass.class, tmpl); - OptionalBaseClass src = new OptionalBaseClass(); - ByteArrayOutputStream out = new ByteArrayOutputStream(); - tmpl.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Unpacker pac = new Unpacker(in); - Iterator it = pac.iterator(); - assertTrue(it.hasNext()); - MessagePackObject mpo = it.next(); - OptionalBaseClass dst = (OptionalBaseClass) tmpl.convert(mpo); - assertTrue(src.f0 == dst.f0); - assertEquals(src.f1, dst.f1); - assertFalse(it.hasNext()); - } - - @Test - public void testOptionalNestedFieldClass02() throws Exception { - MessagePacker packer2 = DynamicPacker.create(NestedClass.class); - CustomPacker.register(NestedClass.class, packer2); - MessagePacker packer = new OptionalPacker(DynamicPacker - .create(BaseClass.class)); - CustomPacker.register(BaseClass.class, packer); - Template tmpl2 = DynamicTemplate.create(NestedClass.class); - CustomUnpacker.register(NestedClass.class, tmpl2); - CustomConverter.register(NestedClass.class, tmpl2); - Template tmpl = new OptionalTemplate(DynamicTemplate - .create(BaseClass.class)); - CustomUnpacker.register(BaseClass.class, tmpl); - CustomConverter.register(BaseClass.class, tmpl); - BaseClass src = null; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - packer.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Unpacker pac = new Unpacker(in); - Iterator it = pac.iterator(); - assertTrue(it.hasNext()); - MessagePackObject mpo = it.next(); - BaseClass dst = (BaseClass) tmpl.convert(mpo); - assertEquals(src, dst); - assertFalse(it.hasNext()); - } - - public static class OptionalBaseClass { - @MessagePackOptional - public int f0; - @MessagePackOptional - public OptionalNestedClass f1; - - public OptionalBaseClass() { - } - } - - public static class OptionalNestedClass { - @MessagePackOptional - public int f2; - - public OptionalNestedClass() { - } - } - - @Test - public void testMessagePackMessageFieldClass00() throws Exception { - BaseClass2 src = new BaseClass2(); - MessagePackMessageClass2 src2 = new MessagePackMessageClass2(); - src.f0 = 0; - src2.f2 = 2; - src.f1 = src2; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = DynamicPacker.create(BaseClass2.class); - packer.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Unpacker pac = new Unpacker(in); - Iterator it = pac.iterator(); - assertTrue(it.hasNext()); - MessagePackObject mpo = it.next(); - Template tmpl = DynamicTemplate.create(BaseClass2.class); - BaseClass2 dst = (BaseClass2) tmpl.convert(mpo); - assertTrue(src.f0 == dst.f0); - assertTrue(src.f1.f2 == dst.f1.f2); - assertFalse(it.hasNext()); - } - - @Test - public void testMessagePackMessageFieldClass02() throws Exception { - BaseClass2 src = null; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = new OptionalPacker(DynamicPacker - .create(BaseClass2.class)); - packer.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Unpacker pac = new Unpacker(in); - Iterator it = pac.iterator(); - assertTrue(it.hasNext()); - MessagePackObject mpo = it.next(); - Template tmpl = new OptionalTemplate(DynamicTemplate - .create(BaseClass2.class)); - BaseClass2 dst = (BaseClass2) tmpl.convert(mpo); - assertEquals(src, dst); - assertFalse(it.hasNext()); - } - - public static class BaseClass2 { - public int f0; - public MessagePackMessageClass2 f1; - - public BaseClass2() { - } - } - - @MessagePackMessage - public static class MessagePackMessageClass2 { - public int f2; - - public MessagePackMessageClass2() { - } - } - - @Test - public void testOptionalMessagePackMessageFieldClass00() throws Exception { - OptionalBaseClass2 src = new OptionalBaseClass2(); - OptionalMessagePackMessageClass2 src2 = new OptionalMessagePackMessageClass2(); - src.f0 = 0; - src2.f2 = 2; - src.f1 = src2; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = DynamicPacker.create(OptionalBaseClass2.class); - packer.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Unpacker pac = new Unpacker(in); - Iterator it = pac.iterator(); - assertTrue(it.hasNext()); - MessagePackObject mpo = it.next(); - Template tmpl = DynamicTemplate.create(OptionalBaseClass2.class); - OptionalBaseClass2 dst = (OptionalBaseClass2) tmpl.convert(mpo); - assertTrue(src.f0 == dst.f0); - assertTrue(src.f1.f2 == dst.f1.f2); - assertFalse(it.hasNext()); - } - - @Test - public void testOptionalMessagePackMessageFieldClass01() throws Exception { - OptionalBaseClass2 src = new OptionalBaseClass2(); - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = DynamicPacker.create(OptionalBaseClass2.class); - packer.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Unpacker pac = new Unpacker(in); - Iterator it = pac.iterator(); - assertTrue(it.hasNext()); - MessagePackObject mpo = it.next(); - Template tmpl = DynamicTemplate.create(OptionalBaseClass2.class); - OptionalBaseClass2 dst = (OptionalBaseClass2) tmpl.convert(mpo); - assertTrue(src.f0 == dst.f0); - assertEquals(src.f1, dst.f1); - assertFalse(it.hasNext()); - } - - @Test - public void testOptionalMessagePackMessageFieldClass02() throws Exception { - OptionalBaseClass2 src = null; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = new OptionalPacker(DynamicPacker - .create(OptionalBaseClass2.class)); - packer.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Unpacker pac = new Unpacker(in); - Iterator it = pac.iterator(); - assertTrue(it.hasNext()); - MessagePackObject mpo = it.next(); - Template tmpl = new OptionalTemplate(DynamicTemplate - .create(OptionalBaseClass2.class)); - OptionalBaseClass2 dst = (OptionalBaseClass2) tmpl.convert(mpo); - assertEquals(src, dst); - assertFalse(it.hasNext()); - } - - public static class OptionalBaseClass2 { - @MessagePackOptional - public int f0; - @MessagePackOptional - public OptionalMessagePackMessageClass2 f1; - - public OptionalBaseClass2() { - } - } - - @MessagePackMessage - public static class OptionalMessagePackMessageClass2 { - @MessagePackOptional - public int f2; - - public OptionalMessagePackMessageClass2() { - } - } - - @Test - public void testExtendedClass00() throws Exception { - SampleSubClass src = new SampleSubClass(); - src.f0 = 0; - src.f2 = 2; - src.f3 = 3; - src.f4 = 4; - src.f5 = 5; - src.f8 = 8; - src.f9 = 9; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = DynamicPacker.create(SampleSubClass.class); - packer.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Template tmpl = DynamicTemplate.create(SampleSubClass.class); - Unpacker pac = new Unpacker(in); - Iterator it = pac.iterator(); - assertTrue(it.hasNext()); - MessagePackObject mpo = it.next(); - SampleSubClass dst = (SampleSubClass) tmpl.convert(mpo); - assertTrue(src.f0 == dst.f0); - assertTrue(src.f1 == dst.f1); - assertTrue(src.f2 != dst.f2); - assertTrue(src.f3 != dst.f3); - assertTrue(src.f4 != dst.f4); - assertTrue(src.f5 == dst.f5); - assertTrue(src.f6 == dst.f6); - assertTrue(src.f8 != dst.f8); - assertTrue(src.f9 != dst.f9); - assertFalse(it.hasNext()); - } - - @Test - public void testExtendedClass01() throws Exception { - SampleSubClass src = null; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = new OptionalPacker(DynamicPacker - .create(SampleSubClass.class)); - packer.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Template tmpl = new OptionalTemplate(DynamicTemplate - .create(SampleSubClass.class)); - Unpacker pac = new Unpacker(in); - Iterator it = pac.iterator(); - assertTrue(it.hasNext()); - MessagePackObject mpo = it.next(); - SampleSubClass dst = (SampleSubClass) tmpl.convert(mpo); - assertEquals(src, dst); - assertFalse(it.hasNext()); - } - - public static class SampleSubClass extends SampleSuperClass { - public int f0; - public final int f1 = 1; - private int f2; - protected int f3; - int f4; - - public SampleSubClass() { - } - } - - public static class SampleSuperClass { - public int f5; - public final int f6 = 2; - @SuppressWarnings("unused") - private int f7; - protected int f8; - int f9; - - public SampleSuperClass() { - } - } - - @Test - public void testOptionalExtendedClass00() throws Exception { - SampleOptionalSubClass src = new SampleOptionalSubClass(); - src.f0 = 0; - src.f2 = 2; - src.f3 = 3; - src.f4 = 4; - src.f5 = 5; - src.f8 = 8; - src.f9 = 9; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = DynamicPacker - .create(SampleOptionalSubClass.class); - packer.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Template tmpl = DynamicTemplate.create(SampleOptionalSubClass.class); - Unpacker pac = new Unpacker(in); - Iterator it = pac.iterator(); - assertTrue(it.hasNext()); - MessagePackObject mpo = it.next(); - SampleOptionalSubClass dst = (SampleOptionalSubClass) tmpl.convert(mpo); - assertTrue(src.f0 == dst.f0); - assertTrue(src.f1 == dst.f1); - assertTrue(src.f2 != dst.f2); - assertTrue(src.f3 != dst.f3); - assertTrue(src.f4 != dst.f4); - assertTrue(src.f5 == dst.f5); - assertTrue(src.f6 == dst.f6); - assertTrue(src.f8 != dst.f8); - assertTrue(src.f9 != dst.f9); - assertFalse(it.hasNext()); - } - - @Test - public void testOptionalExtendedClass01() throws Exception { - SampleOptionalSubClass src = null; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = new OptionalPacker(DynamicPacker - .create(SampleOptionalSubClass.class)); - packer.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Template tmpl = new OptionalTemplate(DynamicTemplate - .create(SampleOptionalSubClass.class)); - Unpacker pac = new Unpacker(in); - Iterator it = pac.iterator(); - assertTrue(it.hasNext()); - MessagePackObject mpo = it.next(); - SampleOptionalSubClass dst = (SampleOptionalSubClass) tmpl.convert(mpo); - assertEquals(src, dst); - assertFalse(it.hasNext()); - } - - public static class SampleOptionalSubClass extends SampleOptionalSuperClass { - @MessagePackOptional - public int f0; - public final int f1 = 1; - private int f2; - protected int f3; - int f4; - - public SampleOptionalSubClass() { - } - } - - public static class SampleOptionalSuperClass { - @MessagePackOptional - public int f5; - public final int f6 = 2; - @SuppressWarnings("unused") - private int f7; - protected int f8; - int f9; - - public SampleOptionalSuperClass() { - } - } - - @Test - public void testMessagePackableUnpackableClass00() throws Exception { - BaseMessagePackableConvertableClass src = new BaseMessagePackableConvertableClass(); - MessagePackableConvertableClass src1 = new MessagePackableConvertableClass(); - List src2 = new ArrayList(); - src1.f0 = 0; - src1.f1 = 1; - src.f0 = src1; - src.f1 = 1; - src2.add(src1); - src.f2 = src2; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = DynamicPacker - .create(BaseMessagePackableConvertableClass.class); - packer.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Template tmpl = DynamicTemplate - .create(BaseMessagePackableConvertableClass.class); - Unpacker pac = new Unpacker(in); - Iterator it = pac.iterator(); - assertTrue(it.hasNext()); - MessagePackObject mpo = it.next(); - BaseMessagePackableConvertableClass dst = (BaseMessagePackableConvertableClass) tmpl - .convert(mpo); - assertEquals(src.f0.f0, dst.f0.f0); - assertEquals(src.f0.f1, dst.f0.f1); - assertEquals(src.f1, dst.f1); - assertEquals(src.f2.size(), dst.f2.size()); - assertEquals(src.f2.get(0).f0, dst.f2.get(0).f0); - assertEquals(src.f2.get(0).f1, dst.f2.get(0).f1); - assertFalse(it.hasNext()); - } - - @Test - public void testMessagePackableUnpackableClass01() throws Exception { - BaseMessagePackableConvertableClass src = null; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = new OptionalPacker(DynamicPacker - .create(BaseMessagePackableConvertableClass.class)); - packer.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Template tmpl = new OptionalTemplate(DynamicTemplate - .create(BaseMessagePackableConvertableClass.class)); - Unpacker pac = new Unpacker(in); - Iterator it = pac.iterator(); - assertTrue(it.hasNext()); - MessagePackObject mpo = it.next(); - BaseMessagePackableConvertableClass dst = (BaseMessagePackableConvertableClass) tmpl - .convert(mpo); - assertEquals(src, dst); - assertFalse(it.hasNext()); - } - - public static class BaseMessagePackableConvertableClass { - public MessagePackableConvertableClass f0; - public int f1; - public List f2; - - public BaseMessagePackableConvertableClass() { - } - } - - public static class MessagePackableConvertableClass implements - MessagePackable, MessageConvertable { - public int f0; - public int f1; - - public MessagePackableConvertableClass() { - } - - @Override - public void messagePack(Packer packer) throws IOException { - packer.packArray(2); - packer.pack(f0); - packer.pack(f1); - } - - @Override - public void messageConvert(MessagePackObject from) - throws MessageTypeException { - if (from.isNil()) { - return; - } - MessagePackObject[] objs = from.asArray(); - f0 = objs[0].asInt(); - f1 = objs[1].asInt(); - } - } - - @Test - public void testOptionalMessagePackableUnpackableClass00() throws Exception { - OptionalBaseMessagePackableConvertableClass src = new OptionalBaseMessagePackableConvertableClass(); - OptionalMessagePackableConvertableClass src1 = new OptionalMessagePackableConvertableClass(); - List src2 = new ArrayList(); - src1.f0 = 0; - src1.f1 = 1; - src.f0 = src1; - src.f1 = 1; - src2.add(src1); - src.f2 = src2; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = DynamicPacker - .create(OptionalBaseMessagePackableConvertableClass.class); - packer.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Template tmpl = DynamicTemplate - .create(OptionalBaseMessagePackableConvertableClass.class); - Unpacker pac = new Unpacker(in); - Iterator it = pac.iterator(); - assertTrue(it.hasNext()); - MessagePackObject mpo = it.next(); - OptionalBaseMessagePackableConvertableClass dst = (OptionalBaseMessagePackableConvertableClass) tmpl - .convert(mpo); - assertEquals(src.f0.f0, dst.f0.f0); - assertEquals(src.f0.f1, dst.f0.f1); - assertEquals(src.f1, dst.f1); - assertEquals(src.f2.size(), dst.f2.size()); - assertEquals(src.f2.get(0).f0, dst.f2.get(0).f0); - assertEquals(src.f2.get(0).f1, dst.f2.get(0).f1); - assertFalse(it.hasNext()); - } - - @Test - public void testOptionalMessagePackableUnpackableClass01() throws Exception { - OptionalBaseMessagePackableConvertableClass src = new OptionalBaseMessagePackableConvertableClass(); - src.f0 = null; - src.f1 = 1; - src.f2 = null; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = DynamicPacker - .create(OptionalBaseMessagePackableConvertableClass.class); - packer.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Template tmpl = DynamicTemplate - .create(OptionalBaseMessagePackableConvertableClass.class); - Unpacker pac = new Unpacker(in); - Iterator it = pac.iterator(); - assertTrue(it.hasNext()); - MessagePackObject mpo = it.next(); - OptionalBaseMessagePackableConvertableClass dst = (OptionalBaseMessagePackableConvertableClass) tmpl - .convert(mpo); - assertEquals(src.f0, dst.f0); - assertEquals(src.f1, dst.f1); - assertEquals(src.f2, dst.f2); - assertFalse(it.hasNext()); - } - - @Test - public void testOptionalMessagePackableUnpackableClass02() throws Exception { - OptionalBaseMessagePackableConvertableClass src = null; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = new OptionalPacker(DynamicPacker - .create(OptionalBaseMessagePackableConvertableClass.class)); - packer.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Template tmpl = new OptionalTemplate(DynamicTemplate - .create(OptionalBaseMessagePackableConvertableClass.class)); - Unpacker pac = new Unpacker(in); - Iterator it = pac.iterator(); - assertTrue(it.hasNext()); - MessagePackObject mpo = it.next(); - OptionalBaseMessagePackableConvertableClass dst = (OptionalBaseMessagePackableConvertableClass) tmpl - .convert(mpo); - assertEquals(src, dst); - assertFalse(it.hasNext()); - } - - public static class OptionalBaseMessagePackableConvertableClass { - @MessagePackOptional - public OptionalMessagePackableConvertableClass f0; - @MessagePackOptional - public int f1; - - @MessagePackOptional - public List f2; - - public OptionalBaseMessagePackableConvertableClass() { - } - } - - public static class OptionalMessagePackableConvertableClass implements - MessagePackable, MessageConvertable { - @MessagePackOptional - public int f0; - @MessagePackOptional - public int f1; - - public OptionalMessagePackableConvertableClass() { - } - - @Override - public void messagePack(Packer packer) throws IOException { - packer.packArray(2); - packer.pack(f0); - packer.pack(f1); - } - - @Override - public void messageConvert(MessagePackObject from) - throws MessageTypeException { - if (from.isNil()) { - return; - } - MessagePackObject[] objs = from.asArray(); - f0 = objs[0].asInt(); - f1 = objs[1].asInt(); - } - } -} diff --git a/java/src/test/java/org/msgpack/util/codegen/TestPackConvertWithFieldOption.java b/java/src/test/java/org/msgpack/util/codegen/TestPackConvertWithFieldOption.java deleted file mode 100644 index a6110c5..0000000 --- a/java/src/test/java/org/msgpack/util/codegen/TestPackConvertWithFieldOption.java +++ /dev/null @@ -1,553 +0,0 @@ -package org.msgpack.util.codegen; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.math.BigInteger; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -import org.junit.Test; -import org.msgpack.MessagePackObject; -import org.msgpack.MessagePacker; -import org.msgpack.Packer; -import org.msgpack.Template; -import org.msgpack.Unpacker; -import org.msgpack.annotation.MessagePackMessage; -import org.msgpack.packer.OptionalPacker; -import org.msgpack.template.ListTemplate; -import org.msgpack.template.MapTemplate; -import org.msgpack.template.OptionalTemplate; -import static org.msgpack.Templates.tBigInteger; -import static org.msgpack.Templates.tBoolean; -import static org.msgpack.Templates.tByte; -import static org.msgpack.Templates.tByteArray; -import static org.msgpack.Templates.tDouble; -import static org.msgpack.Templates.tFloat; -import static org.msgpack.Templates.tInteger; -import static org.msgpack.Templates.tLong; -import static org.msgpack.Templates.tShort; -import static org.msgpack.Templates.tString; - -import junit.framework.TestCase; - -public class TestPackConvertWithFieldOption extends TestCase { - - @Test - public void testPrimitiveTypeFieldsClass00() throws Exception { - PrimitiveTypeFieldsClass src = new PrimitiveTypeFieldsClass(); - src.f0 = (byte) 0; - src.f1 = 1; - src.f2 = 2; - src.f3 = 3; - src.f4 = 4; - src.f5 = 5; - src.f6 = false; - - List opts = new ArrayList(); - opts.add(new FieldOption("f0", tByte())); - opts.add(new FieldOption("f1", tShort())); - opts.add(new FieldOption("f2", tInteger())); - opts.add(new FieldOption("f3", tLong())); - opts.add(new FieldOption("f4", tFloat())); - opts.add(new FieldOption("f5", tDouble())); - opts.add(new FieldOption("f6", tBoolean())); - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = DynamicPacker.create( - PrimitiveTypeFieldsClass.class, opts); - packer.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Template tmpl = DynamicTemplate.create(PrimitiveTypeFieldsClass.class, opts); - Unpacker pac = new Unpacker(in); - Iterator it = pac.iterator(); - assertTrue(it.hasNext()); - MessagePackObject mpo = it.next(); - PrimitiveTypeFieldsClass dst = (PrimitiveTypeFieldsClass) tmpl.convert(mpo); - assertEquals(src.f0, dst.f0); - assertEquals(src.f1, dst.f1); - assertEquals(src.f2, dst.f2); - assertEquals(src.f3, dst.f3); - assertEquals(src.f4, dst.f4); - assertEquals(src.f5, dst.f5); - assertEquals(src.f6, dst.f6); - assertFalse(it.hasNext()); - } - - @Test - public void testPrimitiveTypeFieldsClass01() throws Exception { - PrimitiveTypeFieldsClass src = new PrimitiveTypeFieldsClass(); - - List opts = new ArrayList(); - opts.add(new FieldOption("f0", new OptionalTemplate(tByte()))); - opts.add(new FieldOption("f1", new OptionalTemplate(tShort()))); - opts.add(new FieldOption("f2", new OptionalTemplate(tInteger()))); - opts.add(new FieldOption("f3", new OptionalTemplate(tLong()))); - opts.add(new FieldOption("f4", new OptionalTemplate(tFloat()))); - opts.add(new FieldOption("f5", new OptionalTemplate(tDouble()))); - opts.add(new FieldOption("f6", new OptionalTemplate(tBoolean()))); - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = DynamicPacker.create( - PrimitiveTypeFieldsClass.class, opts); - packer.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Template tmpl = DynamicTemplate.create(PrimitiveTypeFieldsClass.class, opts); - Unpacker pac = new Unpacker(in); - Iterator it = pac.iterator(); - assertTrue(it.hasNext()); - MessagePackObject mpo = it.next(); - PrimitiveTypeFieldsClass dst = (PrimitiveTypeFieldsClass) tmpl.convert(mpo); - assertEquals(src.f0, dst.f0); - assertEquals(src.f1, dst.f1); - assertEquals(src.f2, dst.f2); - assertEquals(src.f3, dst.f3); - assertEquals(src.f4, dst.f4); - assertEquals(src.f5, dst.f5); - assertEquals(src.f6, dst.f6); - assertFalse(it.hasNext()); - } - - @Test - public void testPrimitiveTypeFieldsClass02() throws Exception { - PrimitiveTypeFieldsClass src = null; - - List opts = new ArrayList(); - opts.add(new FieldOption("f0", tByte())); - opts.add(new FieldOption("f1", tShort())); - opts.add(new FieldOption("f2", tInteger())); - opts.add(new FieldOption("f3", tLong())); - opts.add(new FieldOption("f4", tFloat())); - opts.add(new FieldOption("f5", tDouble())); - opts.add(new FieldOption("f6", tBoolean())); - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = new OptionalPacker(DynamicPacker.create( - PrimitiveTypeFieldsClass.class, opts)); - packer.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Template tmpl = new OptionalTemplate(DynamicTemplate.create(PrimitiveTypeFieldsClass.class, opts)); - Unpacker pac = new Unpacker(in); - Iterator it = pac.iterator(); - assertTrue(it.hasNext()); - MessagePackObject mpo = it.next(); - PrimitiveTypeFieldsClass dst = (PrimitiveTypeFieldsClass) tmpl.convert(mpo); - assertEquals(src, dst); - assertFalse(it.hasNext()); - } - - public static class PrimitiveTypeFieldsClass { - public byte f0; - public short f1; - public int f2; - public long f3; - public float f4; - public double f5; - public boolean f6; - - public PrimitiveTypeFieldsClass() { - } - } - - @Test - public void testGeneralReferenceTypeFieldsClass00() throws Exception { - GeneralReferenceTypeFieldsClass src = new GeneralReferenceTypeFieldsClass(); - src.f0 = 0; - src.f1 = 1; - src.f2 = 2; - src.f3 = (long) 3; - src.f4 = (float) 4; - src.f5 = (double) 5; - src.f6 = false; - src.f7 = new BigInteger("7"); - src.f8 = "8"; - src.f9 = new byte[] { 0x01, 0x02 }; - - List opts = new ArrayList(); - opts.add(new FieldOption("f0", tByte())); - opts.add(new FieldOption("f1", tShort())); - opts.add(new FieldOption("f2", tInteger())); - opts.add(new FieldOption("f3", tLong())); - opts.add(new FieldOption("f4", tFloat())); - opts.add(new FieldOption("f5", tDouble())); - opts.add(new FieldOption("f6", tBoolean())); - opts.add(new FieldOption("f7", tBigInteger())); - opts.add(new FieldOption("f8", tString())); - opts.add(new FieldOption("f9", tByteArray())); - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = DynamicPacker - .create(GeneralReferenceTypeFieldsClass.class, opts); - packer.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Template tmpl = DynamicTemplate.create(GeneralReferenceTypeFieldsClass.class, opts); - Unpacker pac = new Unpacker(in); - Iterator it = pac.iterator(); - assertTrue(it.hasNext()); - MessagePackObject mpo = it.next(); - GeneralReferenceTypeFieldsClass dst = (GeneralReferenceTypeFieldsClass) tmpl.convert(mpo); - assertEquals(src.f0, dst.f0); - assertEquals(src.f1, dst.f1); - assertEquals(src.f2, dst.f2); - assertEquals(src.f3, dst.f3); - assertEquals(src.f4, dst.f4); - assertEquals(src.f5, dst.f5); - assertEquals(src.f6, dst.f6); - assertEquals(src.f7, dst.f7); - assertEquals(src.f8, dst.f8); - assertEquals(src.f9[0], dst.f9[0]); - assertEquals(src.f9[1], dst.f9[1]); - assertFalse(it.hasNext()); - } - - @Test - public void testGeneralReferenceTypeFieldsClass01() throws Exception { - GeneralReferenceTypeFieldsClass src = new GeneralReferenceTypeFieldsClass(); - src.f0 = null; - src.f1 = null; - src.f2 = null; - src.f3 = null; - src.f4 = null; - src.f5 = null; - src.f6 = null; - src.f7 = null; - src.f8 = null; - src.f9 = null; - - List opts = new ArrayList(); - opts.add(new FieldOption("f0", new OptionalTemplate(tByte()))); - opts.add(new FieldOption("f1", new OptionalTemplate(tShort()))); - opts.add(new FieldOption("f2", new OptionalTemplate(tInteger()))); - opts.add(new FieldOption("f3", new OptionalTemplate(tLong()))); - opts.add(new FieldOption("f4", new OptionalTemplate(tFloat()))); - opts.add(new FieldOption("f5", new OptionalTemplate(tDouble()))); - opts.add(new FieldOption("f6", new OptionalTemplate(tBoolean()))); - opts.add(new FieldOption("f7", new OptionalTemplate(tBigInteger()))); - opts.add(new FieldOption("f8", new OptionalTemplate(tString()))); - opts.add(new FieldOption("f9", new OptionalTemplate(tByteArray()))); - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = DynamicPacker - .create(GeneralReferenceTypeFieldsClass.class, opts); - packer.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Template tmpl = DynamicTemplate.create(GeneralReferenceTypeFieldsClass.class, opts); - Unpacker pac = new Unpacker(in); - Iterator it = pac.iterator(); - assertTrue(it.hasNext()); - MessagePackObject mpo = it.next(); - GeneralReferenceTypeFieldsClass dst = (GeneralReferenceTypeFieldsClass) tmpl.convert(mpo); - assertEquals(src.f0, dst.f0); - assertEquals(src.f1, dst.f1); - assertEquals(src.f2, dst.f2); - assertEquals(src.f3, dst.f3); - assertEquals(src.f4, dst.f4); - assertEquals(src.f5, dst.f5); - assertEquals(src.f6, dst.f6); - assertEquals(src.f7, dst.f7); - assertEquals(src.f8, dst.f8); - assertEquals(src.f9, dst.f9); - assertFalse(it.hasNext()); - } - - @Test - public void testGeneralReferenceTypeFieldsClass02() - throws Exception { - GeneralReferenceTypeFieldsClass src = null; - - List opts = new ArrayList(); - opts.add(new FieldOption("f0", new OptionalTemplate(tByte()))); - opts.add(new FieldOption("f1", new OptionalTemplate(tShort()))); - opts.add(new FieldOption("f2", new OptionalTemplate(tInteger()))); - opts.add(new FieldOption("f3", new OptionalTemplate(tLong()))); - opts.add(new FieldOption("f4", new OptionalTemplate(tFloat()))); - opts.add(new FieldOption("f5", new OptionalTemplate(tDouble()))); - opts.add(new FieldOption("f6", new OptionalTemplate(tBoolean()))); - opts.add(new FieldOption("f7", new OptionalTemplate(tBigInteger()))); - opts.add(new FieldOption("f8", new OptionalTemplate(tString()))); - opts.add(new FieldOption("f9", new OptionalTemplate(tByteArray()))); - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = new OptionalPacker(DynamicPacker - .create(GeneralReferenceTypeFieldsClass.class, opts)); - packer.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Template tmpl = new OptionalTemplate(DynamicTemplate - .create(GeneralReferenceTypeFieldsClass.class, opts)); - Unpacker pac = new Unpacker(in); - Iterator it = pac.iterator(); - assertTrue(it.hasNext()); - MessagePackObject mpo = it.next(); - GeneralReferenceTypeFieldsClass dst = (GeneralReferenceTypeFieldsClass) tmpl.convert(mpo); - assertEquals(src, dst); - assertFalse(it.hasNext()); - } - - public static class GeneralReferenceTypeFieldsClass { - public Byte f0; - public Short f1; - public Integer f2; - public Long f3; - public Float f4; - public Double f5; - public Boolean f6; - public BigInteger f7; - public String f8; - public byte[] f9; - - public GeneralReferenceTypeFieldsClass() { - } - } - - @Test - public void testListTypes00() throws Exception { - SampleListTypes src = new SampleListTypes(); - src.f0 = new ArrayList(); - src.f1 = new ArrayList(); - src.f1.add(1); - src.f1.add(2); - src.f1.add(3); - src.f2 = new ArrayList(); - src.f2.add("e1"); - src.f2.add("e2"); - src.f2.add("e3"); - src.f3 = new ArrayList>(); - src.f3.add(src.f2); - src.f4 = new ArrayList(); - SampleListNestedType slnt = new SampleListNestedType(); - slnt.f0 = new byte[] { 0x01, 0x02 }; - slnt.f1 = "muga"; - src.f4.add(slnt); - - List opts = new ArrayList(); - opts.add(new FieldOption("f0", new ListTemplate(tInteger()))); - opts.add(new FieldOption("f1", new ListTemplate(tInteger()))); - opts.add(new FieldOption("f2", new ListTemplate(tString()))); - opts.add(new FieldOption("f3", new ListTemplate(new ListTemplate(tString())))); - opts.add(new FieldOption("f4", new ListTemplate(DynamicTemplate.create(SampleListNestedType.class)))); - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = DynamicPacker - .create(SampleListTypes.class, opts); - packer.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Template tmpl = DynamicTemplate.create(SampleListTypes.class, opts); - Unpacker pac = new Unpacker(in); - Iterator it = pac.iterator(); - assertTrue(it.hasNext()); - MessagePackObject mpo = it.next(); - SampleListTypes dst = (SampleListTypes) tmpl.convert(mpo); - assertEquals(src.f0.size(), dst.f0.size()); - assertEquals(src.f1.size(), dst.f1.size()); - for (int i = 0; i < src.f1.size(); ++i) { - assertEquals(src.f1.get(i), dst.f1.get(i)); - } - assertEquals(src.f2.size(), dst.f2.size()); - for (int i = 0; i < src.f2.size(); ++i) { - assertEquals(src.f2.get(i), dst.f2.get(i)); - } - assertEquals(src.f3.size(), dst.f3.size()); - for (int i = 0; i < src.f3.size(); ++i) { - List srclist = src.f3.get(i); - List dstlist = dst.f3.get(i); - assertEquals(srclist.size(), dstlist.size()); - for (int j = 0; j < srclist.size(); ++j) { - assertEquals(srclist.get(j), dstlist.get(j)); - } - } - assertEquals(src.f4.size(), dst.f4.size()); - for (int i = 0; i < src.f4.size(); ++i) { - SampleListNestedType s = src.f4.get(i); - SampleListNestedType d = dst.f4.get(i); - assertEquals(s.f0[0], d.f0[0]); - assertEquals(s.f0[1], d.f0[1]); - assertEquals(s.f1, d.f1); - } - assertFalse(it.hasNext()); - } - - @Test - public void testListTypes01() throws Exception { - SampleListTypes src = new SampleListTypes(); - src.f0 = new ArrayList(); - src.f1 = null; - src.f2 = new ArrayList(); - src.f3 = new ArrayList>(); - src.f4 = null; - - List opts = new ArrayList(); - opts.add(new FieldOption("f0", new OptionalTemplate(new ListTemplate(tInteger())))); - opts.add(new FieldOption("f1", new OptionalTemplate(new ListTemplate(tInteger())))); - opts.add(new FieldOption("f2", new OptionalTemplate(new ListTemplate(tString())))); - opts.add(new FieldOption("f3", new OptionalTemplate(new ListTemplate(new ListTemplate(tString()))))); - opts.add(new FieldOption("f4", new OptionalTemplate(new ListTemplate(DynamicTemplate.create(SampleListNestedType.class))))); - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = DynamicPacker - .create(SampleListTypes.class, opts); - packer.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Template tmpl = DynamicTemplate.create(SampleListTypes.class, opts); - Unpacker pac = new Unpacker(in); - Iterator it = pac.iterator(); - assertTrue(it.hasNext()); - MessagePackObject mpo = it.next(); - SampleListTypes dst = (SampleListTypes) tmpl.convert(mpo); - assertEquals(src.f0.size(), dst.f0.size()); - assertEquals(src.f1, dst.f1); - assertEquals(src.f2.size(), dst.f2.size()); - assertEquals(src.f3.size(), dst.f3.size()); - assertEquals(src.f4, dst.f4); - assertFalse(it.hasNext()); - } - - @Test - public void testListTypes02() throws Exception { - SampleListTypes src = null; - - List opts = new ArrayList(); - opts.add(new FieldOption("f0", new OptionalTemplate(new ListTemplate(tInteger())))); - opts.add(new FieldOption("f1", new OptionalTemplate(new ListTemplate(tInteger())))); - opts.add(new FieldOption("f2", new OptionalTemplate(new ListTemplate(tString())))); - opts.add(new FieldOption("f3", new OptionalTemplate(new ListTemplate(new ListTemplate(tString()))))); - opts.add(new FieldOption("f4", new OptionalTemplate(new ListTemplate(DynamicTemplate.create(SampleListNestedType.class))))); - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = new OptionalPacker(DynamicPacker - .create(SampleListTypes.class)); - packer.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Template tmpl = new OptionalTemplate(DynamicTemplate - .create(SampleListTypes.class, opts)); - Unpacker pac = new Unpacker(in); - Iterator it = pac.iterator(); - assertTrue(it.hasNext()); - MessagePackObject mpo = it.next(); - SampleListTypes dst = (SampleListTypes) tmpl.convert(mpo); - assertEquals(src, dst); - assertFalse(it.hasNext()); - } - - public static class SampleListTypes { - public List f0; - public List f1; - public List f2; - public List> f3; - public List f4; - - public SampleListTypes() { - } - } - - @MessagePackMessage - public static class SampleListNestedType { - public byte[] f0; - public String f1; - - public SampleListNestedType() { - } - } - - @Test - public void testMapTypes00() throws Exception { - SampleMapTypes src = new SampleMapTypes(); - src.f0 = new HashMap(); - src.f1 = new HashMap(); - src.f1.put(1, 1); - src.f1.put(2, 2); - src.f1.put(3, 3); - src.f2 = new HashMap(); - src.f2.put("k1", 1); - src.f2.put("k2", 2); - src.f2.put("k3", 3); - - List opts = new ArrayList(); - opts.add(new FieldOption("f0", new MapTemplate(tInteger(), tInteger()))); - opts.add(new FieldOption("f1", new MapTemplate(tInteger(), tInteger()))); - opts.add(new FieldOption("f2", new MapTemplate(tString(), tInteger()))); - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = DynamicPacker - .create(SampleMapTypes.class, opts); - packer.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Template tmpl = DynamicTemplate.create(SampleMapTypes.class, opts); - Unpacker pac = new Unpacker(in); - Iterator it = pac.iterator(); - assertTrue(it.hasNext()); - MessagePackObject mpo = it.next(); - SampleMapTypes dst = (SampleMapTypes) tmpl.convert(mpo); - assertEquals(src.f0.size(), dst.f0.size()); - assertEquals(src.f1.size(), dst.f1.size()); - Iterator srcf1 = src.f1.keySet().iterator(); - Iterator dstf1 = dst.f1.keySet().iterator(); - while (srcf1.hasNext()) { - Integer s1 = srcf1.next(); - Integer d1 = dstf1.next(); - assertEquals(s1, d1); - assertEquals(src.f1.get(s1), dst.f1.get(d1)); - } - assertEquals(src.f2.size(), dst.f2.size()); - Iterator srcf2 = src.f2.keySet().iterator(); - Iterator dstf2 = dst.f2.keySet().iterator(); - while (srcf2.hasNext()) { - String s2 = srcf2.next(); - String d2 = dstf2.next(); - assertEquals(s2, d2); - assertEquals(src.f2.get(s2), dst.f2.get(d2)); - } - assertFalse(it.hasNext()); - } - - @Test - public void testMapTypes01() throws Exception { - SampleMapTypes src = new SampleMapTypes(); - src.f0 = new HashMap(); - src.f1 = null; - src.f2 = new HashMap(); - - List opts = new ArrayList(); - opts.add(new FieldOption("f0", new OptionalTemplate(new MapTemplate(tInteger(), tInteger())))); - opts.add(new FieldOption("f1", new OptionalTemplate(new MapTemplate(tInteger(), tInteger())))); - opts.add(new FieldOption("f2", new OptionalTemplate(new MapTemplate(tString(), tInteger())))); - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = DynamicPacker - .create(SampleMapTypes.class, opts); - packer.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Template tmpl = DynamicTemplate.create(SampleMapTypes.class, opts); - Unpacker pac = new Unpacker(in); - Iterator it = pac.iterator(); - assertTrue(it.hasNext()); - MessagePackObject mpo = it.next(); - SampleMapTypes dst = (SampleMapTypes) tmpl.convert(mpo); - assertEquals(src.f0.size(), dst.f0.size()); - assertEquals(src.f1, dst.f1); - assertEquals(src.f2.size(), dst.f2.size()); - assertFalse(it.hasNext()); - } - - @Test - public void testMapTypes02() throws Exception { - SampleMapTypes src = null; - - List opts = new ArrayList(); - opts.add(new FieldOption("f0", new OptionalTemplate(new MapTemplate(tInteger(), tInteger())))); - opts.add(new FieldOption("f1", new OptionalTemplate(new MapTemplate(tInteger(), tInteger())))); - opts.add(new FieldOption("f2", new OptionalTemplate(new MapTemplate(tString(), tInteger())))); - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = new OptionalPacker(DynamicPacker - .create(SampleMapTypes.class, opts)); - packer.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Template tmpl = new OptionalTemplate(DynamicTemplate.create(SampleMapTypes.class, opts)); - Unpacker pac = new Unpacker(in); - Iterator it = pac.iterator(); - assertTrue(it.hasNext()); - MessagePackObject mpo = it.next(); - SampleMapTypes dst = (SampleMapTypes) tmpl.convert(mpo); - assertEquals(src, dst); - assertFalse(it.hasNext()); - } - - public static class SampleMapTypes { - public Map f0; - public Map f1; - public Map f2; - - public SampleMapTypes() { - } - } -} diff --git a/java/src/test/java/org/msgpack/util/codegen/TestPackUnpack.java b/java/src/test/java/org/msgpack/util/codegen/TestPackUnpack.java deleted file mode 100644 index ab276f7..0000000 --- a/java/src/test/java/org/msgpack/util/codegen/TestPackUnpack.java +++ /dev/null @@ -1,1659 +0,0 @@ -package org.msgpack.util.codegen; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.math.BigInteger; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -import org.junit.Test; -import org.msgpack.CustomMessage; -import org.msgpack.MessagePackable; -import org.msgpack.MessagePacker; -import org.msgpack.MessageTypeException; -import org.msgpack.MessageUnpackable; -import org.msgpack.Packer; -import org.msgpack.Template; -import org.msgpack.Unpacker; -import org.msgpack.annotation.MessagePackMessage; -import org.msgpack.annotation.MessagePackOptional; -import org.msgpack.annotation.MessagePackOrdinalEnum; -import org.msgpack.packer.OptionalPacker; -import org.msgpack.template.OptionalTemplate; - -import junit.framework.TestCase; - -public class TestPackUnpack extends TestCase { - - @Test - public void testPrimitiveTypeFields00() throws Exception { - PrimitiveTypeFieldsClass src = new PrimitiveTypeFieldsClass(); - src.f0 = (byte) 0; - src.f1 = 1; - src.f2 = 2; - src.f3 = 3; - src.f4 = 4; - src.f5 = 5; - src.f6 = false; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = DynamicPacker - .create(PrimitiveTypeFieldsClass.class); - packer.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Template tmpl = DynamicTemplate.create(PrimitiveTypeFieldsClass.class); - PrimitiveTypeFieldsClass dst = (PrimitiveTypeFieldsClass) tmpl - .unpack(new Unpacker(in)); - assertEquals(src.f0, dst.f0); - assertEquals(src.f1, dst.f1); - assertEquals(src.f2, dst.f2); - assertEquals(src.f3, dst.f3); - assertEquals(src.f4, dst.f4); - assertEquals(src.f5, dst.f5); - assertEquals(src.f6, dst.f6); - } - - @Test - public void testPrimitiveTypeFields01() throws Exception { - PrimitiveTypeFieldsClass src = new PrimitiveTypeFieldsClass(); - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = DynamicPacker - .create(PrimitiveTypeFieldsClass.class); - packer.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Template tmpl = DynamicTemplate.create(PrimitiveTypeFieldsClass.class); - PrimitiveTypeFieldsClass dst = (PrimitiveTypeFieldsClass) tmpl - .unpack(new Unpacker(in)); - assertEquals(src.f0, dst.f0); - assertEquals(src.f1, dst.f1); - assertEquals(src.f2, dst.f2); - assertEquals(src.f3, dst.f3); - assertEquals(src.f4, dst.f4); - assertEquals(src.f5, dst.f5); - assertEquals(src.f6, dst.f6); - } - - @Test - public void testPrimitiveTypeFields02() throws Exception { - PrimitiveTypeFieldsClass src = null; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = new OptionalPacker(DynamicPacker - .create(PrimitiveTypeFieldsClass.class)); - packer.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Template tmpl = new OptionalTemplate(DynamicTemplate - .create(PrimitiveTypeFieldsClass.class)); - PrimitiveTypeFieldsClass dst = (PrimitiveTypeFieldsClass) tmpl - .unpack(new Unpacker(in)); - assertEquals(src, dst); - } - - public static class PrimitiveTypeFieldsClass { - public byte f0; - public short f1; - public int f2; - public long f3; - public float f4; - public double f5; - public boolean f6; - - public PrimitiveTypeFieldsClass() { - } - } - - @Test - public void testOptionalPrimitiveTypeFields00() throws Exception { - OptionalPrimitiveTypeFieldsClass src = new OptionalPrimitiveTypeFieldsClass(); - src.f0 = (byte) 0; - src.f1 = 1; - src.f2 = 2; - src.f3 = 3; - src.f4 = 4; - src.f5 = 5; - src.f6 = false; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = DynamicPacker - .create(OptionalPrimitiveTypeFieldsClass.class); - packer.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Template tmpl = DynamicTemplate - .create(OptionalPrimitiveTypeFieldsClass.class); - OptionalPrimitiveTypeFieldsClass dst = (OptionalPrimitiveTypeFieldsClass) tmpl - .unpack(new Unpacker(in)); - assertEquals(src.f0, dst.f0); - assertEquals(src.f1, dst.f1); - assertEquals(src.f2, dst.f2); - assertEquals(src.f3, dst.f3); - assertEquals(src.f4, dst.f4); - assertEquals(src.f5, dst.f5); - assertEquals(src.f6, dst.f6); - } - - @Test - public void testOptionalPrimitiveTypeFields01() throws Exception { - OptionalPrimitiveTypeFieldsClass src = new OptionalPrimitiveTypeFieldsClass(); - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = DynamicPacker - .create(OptionalPrimitiveTypeFieldsClass.class); - packer.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Template tmpl = DynamicTemplate - .create(OptionalPrimitiveTypeFieldsClass.class); - OptionalPrimitiveTypeFieldsClass dst = (OptionalPrimitiveTypeFieldsClass) tmpl - .unpack(new Unpacker(in)); - assertEquals(src.f0, dst.f0); - assertEquals(src.f1, dst.f1); - assertEquals(src.f2, dst.f2); - assertEquals(src.f3, dst.f3); - assertEquals(src.f4, dst.f4); - assertEquals(src.f5, dst.f5); - assertEquals(src.f6, dst.f6); - } - - @Test - public void testOptionalPrimitiveTypeFields02() throws Exception { - OptionalPrimitiveTypeFieldsClass src = null; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = new OptionalPacker(DynamicPacker - .create(OptionalPrimitiveTypeFieldsClass.class)); - packer.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Template tmpl = new OptionalTemplate(DynamicTemplate - .create(OptionalPrimitiveTypeFieldsClass.class)); - OptionalPrimitiveTypeFieldsClass dst = (OptionalPrimitiveTypeFieldsClass) tmpl - .unpack(new Unpacker(in)); - assertEquals(src, dst); - } - - public static class OptionalPrimitiveTypeFieldsClass { - @MessagePackOptional - public byte f0; - @MessagePackOptional - public short f1; - @MessagePackOptional - public int f2; - @MessagePackOptional - public long f3; - @MessagePackOptional - public float f4; - @MessagePackOptional - public double f5; - @MessagePackOptional - public boolean f6; - - public OptionalPrimitiveTypeFieldsClass() { - } - } - - @Test - public void testGeneralReferenceTypeFieldsClass00() throws Exception { - GeneralReferenceTypeFieldsClass src = new GeneralReferenceTypeFieldsClass(); - src.f0 = 0; - src.f1 = 1; - src.f2 = 2; - src.f3 = (long) 3; - src.f4 = (float) 4; - src.f5 = (double) 5; - src.f6 = false; - src.f7 = new BigInteger("7"); - src.f8 = "8"; - src.f9 = new byte[] { 0x01, 0x02 }; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = DynamicPacker - .create(GeneralReferenceTypeFieldsClass.class); - packer.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Template tmpl = DynamicTemplate - .create(GeneralReferenceTypeFieldsClass.class); - GeneralReferenceTypeFieldsClass dst = (GeneralReferenceTypeFieldsClass) tmpl - .unpack(new Unpacker(in)); - assertEquals(src.f0, dst.f0); - assertEquals(src.f1, dst.f1); - assertEquals(src.f2, dst.f2); - assertEquals(src.f3, dst.f3); - assertEquals(src.f4, dst.f4); - assertEquals(src.f5, dst.f5); - assertEquals(src.f6, dst.f6); - assertEquals(src.f7, dst.f7); - assertEquals(src.f8, dst.f8); - assertEquals(src.f9[0], dst.f9[0]); - assertEquals(src.f9[1], dst.f9[1]); - } - - @Test - public void testGeneralReferenceTypeFieldsClass01() throws Exception { - GeneralReferenceTypeFieldsClass src = null; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = new OptionalPacker(DynamicPacker - .create(GeneralReferenceTypeFieldsClass.class)); - packer.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Template tmpl = new OptionalTemplate(DynamicTemplate - .create(GeneralReferenceTypeFieldsClass.class)); - GeneralReferenceTypeFieldsClass dst = (GeneralReferenceTypeFieldsClass) tmpl - .unpack(new Unpacker(in)); - assertEquals(src, dst); - } - - public static class GeneralReferenceTypeFieldsClass { - public Byte f0; - public Short f1; - public Integer f2; - public Long f3; - public Float f4; - public Double f5; - public Boolean f6; - public BigInteger f7; - public String f8; - public byte[] f9; - - public GeneralReferenceTypeFieldsClass() { - } - } - - @Test - public void testGeneralOptionalReferenceTypeFieldsClass00() - throws Exception { - GeneralOptionalReferenceTypeFieldsClass src = new GeneralOptionalReferenceTypeFieldsClass(); - src.f0 = 0; - src.f1 = 1; - src.f2 = 2; - src.f3 = (long) 3; - src.f4 = (float) 4; - src.f5 = (double) 5; - src.f6 = false; - src.f7 = new BigInteger("7"); - src.f8 = "8"; - src.f9 = new byte[] { 0x01, 0x02 }; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = DynamicPacker - .create(GeneralOptionalReferenceTypeFieldsClass.class); - packer.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Template tmpl = DynamicTemplate - .create(GeneralOptionalReferenceTypeFieldsClass.class); - GeneralOptionalReferenceTypeFieldsClass dst = (GeneralOptionalReferenceTypeFieldsClass) tmpl - .unpack(new Unpacker(in)); - assertEquals(src.f0, dst.f0); - assertEquals(src.f1, dst.f1); - assertEquals(src.f2, dst.f2); - assertEquals(src.f3, dst.f3); - assertEquals(src.f4, dst.f4); - assertEquals(src.f5, dst.f5); - assertEquals(src.f6, dst.f6); - assertEquals(src.f7, dst.f7); - assertEquals(src.f8, dst.f8); - assertEquals(src.f9[0], dst.f9[0]); - assertEquals(src.f9[1], dst.f9[1]); - } - - @Test - public void testGeneralOptionalReferenceTypeFieldsClass01() - throws Exception { - GeneralOptionalReferenceTypeFieldsClass src = new GeneralOptionalReferenceTypeFieldsClass(); - src.f0 = null; - src.f1 = null; - src.f2 = null; - src.f3 = null; - src.f4 = null; - src.f5 = null; - src.f6 = null; - src.f7 = null; - src.f8 = null; - src.f9 = null; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = DynamicPacker - .create(GeneralOptionalReferenceTypeFieldsClass.class); - packer.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Template tmpl = DynamicTemplate - .create(GeneralOptionalReferenceTypeFieldsClass.class); - GeneralOptionalReferenceTypeFieldsClass dst = (GeneralOptionalReferenceTypeFieldsClass) tmpl - .unpack(new Unpacker(in)); - assertEquals(src.f0, dst.f0); - assertEquals(src.f1, dst.f1); - assertEquals(src.f2, dst.f2); - assertEquals(src.f3, dst.f3); - assertEquals(src.f4, dst.f4); - assertEquals(src.f5, dst.f5); - assertEquals(src.f6, dst.f6); - assertEquals(src.f7, dst.f7); - assertEquals(src.f8, dst.f8); - assertEquals(src.f9, dst.f9); - } - - @Test - public void testGeneralOptionalReferenceTypeFieldsClass02() - throws Exception { - GeneralOptionalReferenceTypeFieldsClass src = null; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = new OptionalPacker(DynamicPacker - .create(GeneralOptionalReferenceTypeFieldsClass.class)); - packer.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Template tmpl = new OptionalTemplate(DynamicTemplate - .create(GeneralOptionalReferenceTypeFieldsClass.class)); - GeneralOptionalReferenceTypeFieldsClass dst = (GeneralOptionalReferenceTypeFieldsClass) tmpl - .unpack(new Unpacker(in)); - assertEquals(src, dst); - } - - public static class GeneralOptionalReferenceTypeFieldsClass { - @MessagePackOptional - public Byte f0; - @MessagePackOptional - public Short f1; - @MessagePackOptional - public Integer f2; - @MessagePackOptional - public Long f3; - @MessagePackOptional - public Float f4; - @MessagePackOptional - public Double f5; - @MessagePackOptional - public Boolean f6; - @MessagePackOptional - public BigInteger f7; - @MessagePackOptional - public String f8; - @MessagePackOptional - public byte[] f9; - - public GeneralOptionalReferenceTypeFieldsClass() { - } - } - - @Test - public void testListTypes00() throws Exception { - SampleListTypes src = new SampleListTypes(); - src.f0 = new ArrayList(); - src.f1 = new ArrayList(); - src.f1.add(1); - src.f1.add(2); - src.f1.add(3); - src.f2 = new ArrayList(); - src.f2.add("e1"); - src.f2.add("e2"); - src.f2.add("e3"); - src.f3 = new ArrayList>(); - src.f3.add(src.f2); - src.f4 = new ArrayList(); - SampleListNestedType slnt = new SampleListNestedType(); - slnt.f0 = new byte[] { 0x01, 0x02 }; - slnt.f1 = "muga"; - src.f4.add(slnt); - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = DynamicPacker.create(SampleListTypes.class); - packer.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Template tmpl = DynamicTemplate.create(SampleListTypes.class); - SampleListTypes dst = (SampleListTypes) tmpl.unpack(new Unpacker(in)); - assertEquals(src.f0.size(), dst.f0.size()); - assertEquals(src.f1.size(), dst.f1.size()); - for (int i = 0; i < src.f1.size(); ++i) { - assertEquals(src.f1.get(i), dst.f1.get(i)); - } - assertEquals(src.f2.size(), dst.f2.size()); - for (int i = 0; i < src.f2.size(); ++i) { - assertEquals(src.f2.get(i), dst.f2.get(i)); - } - assertEquals(src.f3.size(), dst.f3.size()); - for (int i = 0; i < src.f3.size(); ++i) { - List srclist = src.f3.get(i); - List dstlist = dst.f3.get(i); - assertEquals(srclist.size(), dstlist.size()); - for (int j = 0; j < srclist.size(); ++j) { - assertEquals(srclist.get(j), dstlist.get(j)); - } - } - assertEquals(src.f4.size(), dst.f4.size()); - for (int i = 0; i < src.f4.size(); ++i) { - SampleListNestedType s = src.f4.get(i); - SampleListNestedType d = dst.f4.get(i); - assertEquals(s.f0[0], d.f0[0]); - assertEquals(s.f0[1], d.f0[1]); - assertEquals(s.f1, d.f1); - } - } - - @Test - public void testListTypes01() throws Exception { - SampleListTypes src = null; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = new OptionalPacker(DynamicPacker - .create(SampleListTypes.class)); - packer.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Template tmpl = new OptionalTemplate(DynamicTemplate - .create(SampleListTypes.class)); - SampleListTypes dst = (SampleListTypes) tmpl.unpack(new Unpacker(in)); - assertEquals(src, dst); - } - - public static class SampleListTypes { - public List f0; - public List f1; - public List f2; - public List> f3; - public List f4; - - public SampleListTypes() { - } - } - - @MessagePackMessage - public static class SampleListNestedType { - public byte[] f0; - public String f1; - - public SampleListNestedType() { - } - } - - @Test - public void testOptionalListTypes00() throws Exception { - SampleOptionalListTypes src = new SampleOptionalListTypes(); - src.f0 = new ArrayList(); - src.f1 = new ArrayList(); - src.f1.add(1); - src.f1.add(2); - src.f1.add(3); - src.f2 = new ArrayList(); - src.f2.add("e1"); - src.f2.add("e2"); - src.f2.add("e3"); - src.f3 = new ArrayList>(); - src.f3.add(src.f2); - src.f4 = new ArrayList(); - SampleOptionalListNestedType slnt = new SampleOptionalListNestedType(); - slnt.f0 = new byte[] { 0x01, 0x02 }; - slnt.f1 = "muga"; - src.f4.add(slnt); - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = DynamicPacker - .create(SampleOptionalListTypes.class); - packer.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Template tmpl = DynamicTemplate.create(SampleOptionalListTypes.class); - SampleOptionalListTypes dst = (SampleOptionalListTypes) tmpl - .unpack(new Unpacker(in)); - assertEquals(src.f0.size(), dst.f0.size()); - assertEquals(src.f1.size(), dst.f1.size()); - for (int i = 0; i < src.f1.size(); ++i) { - assertEquals(src.f1.get(i), dst.f1.get(i)); - } - assertEquals(src.f2.size(), dst.f2.size()); - for (int i = 0; i < src.f2.size(); ++i) { - assertEquals(src.f2.get(i), dst.f2.get(i)); - } - assertEquals(src.f3.size(), dst.f3.size()); - for (int i = 0; i < src.f3.size(); ++i) { - List srclist = src.f3.get(i); - List dstlist = dst.f3.get(i); - assertEquals(srclist.size(), dstlist.size()); - for (int j = 0; j < srclist.size(); ++j) { - assertEquals(srclist.get(j), dstlist.get(j)); - } - } - assertEquals(src.f4.size(), dst.f4.size()); - for (int i = 0; i < src.f4.size(); ++i) { - SampleOptionalListNestedType s = src.f4.get(i); - SampleOptionalListNestedType d = dst.f4.get(i); - assertEquals(s.f0[0], d.f0[0]); - assertEquals(s.f0[1], d.f0[1]); - assertEquals(s.f1, d.f1); - } - } - - @Test - public void testOptionalListTypes01() throws Exception { - SampleOptionalListTypes src = new SampleOptionalListTypes(); - src.f0 = new ArrayList(); - src.f1 = null; - src.f2 = new ArrayList(); - src.f3 = new ArrayList>(); - src.f4 = null; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = DynamicPacker - .create(SampleOptionalListTypes.class); - packer.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Template tmpl = DynamicTemplate.create(SampleOptionalListTypes.class); - SampleOptionalListTypes dst = (SampleOptionalListTypes) tmpl - .unpack(new Unpacker(in)); - assertEquals(src.f0.size(), dst.f0.size()); - assertEquals(src.f1, dst.f1); - assertEquals(src.f2.size(), dst.f2.size()); - assertEquals(src.f3.size(), dst.f3.size()); - assertEquals(src.f4, dst.f4); - } - - @Test - public void testOptionalListTypes02() throws Exception { - SampleListTypes src = null; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = new OptionalPacker(DynamicPacker - .create(SampleOptionalListTypes.class)); - packer.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Template tmpl = new OptionalTemplate(DynamicTemplate - .create(SampleOptionalListTypes.class)); - SampleListTypes dst = (SampleListTypes) tmpl.unpack(new Unpacker(in)); - assertEquals(src, dst); - } - - public static class SampleOptionalListTypes { - @MessagePackOptional - public List f0; - @MessagePackOptional - public List f1; - @MessagePackOptional - public List f2; - @MessagePackOptional - public List> f3; - @MessagePackOptional - public List f4; - - public SampleOptionalListTypes() { - } - } - - @MessagePackMessage - public static class SampleOptionalListNestedType { - @MessagePackOptional - public byte[] f0; - @MessagePackOptional - public String f1; - - public SampleOptionalListNestedType() { - } - } - - @Test - public void testMapTypes00() throws Exception { - SampleMapTypes src = new SampleMapTypes(); - src.f0 = new HashMap(); - src.f1 = new HashMap(); - src.f1.put(1, 1); - src.f1.put(2, 2); - src.f1.put(3, 3); - src.f2 = new HashMap(); - src.f2.put("k1", 1); - src.f2.put("k2", 2); - src.f2.put("k3", 3); - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = DynamicPacker.create(SampleMapTypes.class); - packer.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Template tmpl = DynamicTemplate.create(SampleMapTypes.class); - SampleMapTypes dst = (SampleMapTypes) tmpl.unpack(new Unpacker(in)); - assertEquals(src.f0.size(), dst.f0.size()); - assertEquals(src.f1.size(), dst.f1.size()); - Iterator srcf1 = src.f1.keySet().iterator(); - Iterator dstf1 = dst.f1.keySet().iterator(); - while (srcf1.hasNext()) { - Integer s1 = srcf1.next(); - Integer d1 = dstf1.next(); - assertEquals(s1, d1); - assertEquals(src.f1.get(s1), dst.f1.get(d1)); - } - assertEquals(src.f2.size(), dst.f2.size()); - Iterator srcf2 = src.f2.keySet().iterator(); - Iterator dstf2 = dst.f2.keySet().iterator(); - while (srcf2.hasNext()) { - String s2 = srcf2.next(); - String d2 = dstf2.next(); - assertEquals(s2, d2); - assertEquals(src.f2.get(s2), dst.f2.get(d2)); - } - } - - @Test - public void testMapTypes01() throws Exception { - SampleMapTypes src = null; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = new OptionalPacker(DynamicPacker - .create(SampleMapTypes.class)); - packer.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Template tmpl = new OptionalTemplate(DynamicTemplate - .create(SampleMapTypes.class)); - SampleMapTypes dst = (SampleMapTypes) tmpl.unpack(new Unpacker(in)); - assertEquals(src, dst); - } - - public static class SampleMapTypes { - public Map f0; - public Map f1; - public Map f2; - - public SampleMapTypes() { - } - } - - @Test - public void testOptionalMapTypes00() throws Exception { - SampleOptionalMapTypes src = new SampleOptionalMapTypes(); - src.f0 = new HashMap(); - src.f1 = new HashMap(); - src.f1.put(1, 1); - src.f1.put(2, 2); - src.f1.put(3, 3); - src.f2 = new HashMap(); - src.f2.put("k1", 1); - src.f2.put("k2", 2); - src.f2.put("k3", 3); - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = DynamicPacker - .create(SampleOptionalMapTypes.class); - packer.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Template tmpl = DynamicTemplate.create(SampleOptionalMapTypes.class); - SampleOptionalMapTypes dst = (SampleOptionalMapTypes) tmpl - .unpack(new Unpacker(in)); - assertEquals(src.f0.size(), dst.f0.size()); - assertEquals(src.f1.size(), dst.f1.size()); - Iterator srcf1 = src.f1.keySet().iterator(); - Iterator dstf1 = dst.f1.keySet().iterator(); - while (srcf1.hasNext()) { - Integer s1 = srcf1.next(); - Integer d1 = dstf1.next(); - assertEquals(s1, d1); - assertEquals(src.f1.get(s1), dst.f1.get(d1)); - } - assertEquals(src.f2.size(), dst.f2.size()); - Iterator srcf2 = src.f2.keySet().iterator(); - Iterator dstf2 = dst.f2.keySet().iterator(); - while (srcf2.hasNext()) { - String s2 = srcf2.next(); - String d2 = dstf2.next(); - assertEquals(s2, d2); - assertEquals(src.f2.get(s2), dst.f2.get(d2)); - } - } - - @Test - public void testOptionalMapTypes01() throws Exception { - SampleOptionalMapTypes src = new SampleOptionalMapTypes(); - src.f0 = new HashMap(); - src.f1 = null; - src.f2 = new HashMap(); - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = DynamicPacker - .create(SampleOptionalMapTypes.class); - packer.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Template tmpl = DynamicTemplate.create(SampleOptionalMapTypes.class); - SampleOptionalMapTypes dst = (SampleOptionalMapTypes) tmpl - .unpack(new Unpacker(in)); - assertEquals(src.f0.size(), dst.f0.size()); - assertEquals(src.f1, dst.f1); - assertEquals(src.f2.size(), dst.f2.size()); - } - - @Test - public void testOptionalMapTypes02() throws Exception { - SampleOptionalMapTypes src = null; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = new OptionalPacker(DynamicPacker - .create(SampleOptionalMapTypes.class)); - packer.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Template tmpl = new OptionalTemplate(DynamicTemplate - .create(SampleOptionalMapTypes.class)); - SampleOptionalMapTypes dst = (SampleOptionalMapTypes) tmpl - .unpack(new Unpacker(in)); - assertEquals(src, dst); - } - - public static class SampleOptionalMapTypes { - @MessagePackOptional - public Map f0; - @MessagePackOptional - public Map f1; - @MessagePackOptional - public Map f2; - - public SampleOptionalMapTypes() { - } - } - - @Test - public void testDefaultConstructorModifiers00() throws Exception { - try { - DynamicPacker.create(NoDefaultConstructorClass.class); - fail(); - } catch (DynamicCodeGenException e) { - assertTrue(true); - } - assertTrue(true); - try { - DynamicPacker.create(PrivateDefaultConstructorClass.class); - fail(); - } catch (DynamicCodeGenException e) { - assertTrue(true); - } - assertTrue(true); - try { - DynamicPacker.create(ProtectedDefaultConstructorClass.class); - fail(); - } catch (DynamicCodeGenException e) { - assertTrue(true); - } - assertTrue(true); - try { - DynamicPacker.create(PackageDefaultConstructorClass.class); - fail(); - } catch (DynamicCodeGenException e) { - assertTrue(true); - } - assertTrue(true); - } - - @Test - public void testDefaultConstructorModifiers01() throws Exception { - try { - DynamicUnpacker.create(NoDefaultConstructorClass.class); - fail(); - } catch (DynamicCodeGenException e) { - assertTrue(true); - } - assertTrue(true); - try { - DynamicUnpacker.create(PrivateDefaultConstructorClass.class); - fail(); - } catch (DynamicCodeGenException e) { - assertTrue(true); - } - assertTrue(true); - try { - DynamicUnpacker.create(ProtectedDefaultConstructorClass.class); - fail(); - } catch (DynamicCodeGenException e) { - assertTrue(true); - } - assertTrue(true); - try { - DynamicUnpacker.create(PackageDefaultConstructorClass.class); - fail(); - } catch (DynamicCodeGenException e) { - assertTrue(true); - } - assertTrue(true); - } - - public static class NoDefaultConstructorClass { - public NoDefaultConstructorClass(int i) { - } - } - - public static class PrivateDefaultConstructorClass { - private PrivateDefaultConstructorClass() { - } - } - - public static class ProtectedDefaultConstructorClass { - protected ProtectedDefaultConstructorClass() { - } - } - - public static class PackageDefaultConstructorClass { - PackageDefaultConstructorClass() { - } - } - - @Test - public void testClassModifiers00() throws Exception { - try { - DynamicPacker.create(PrivateModifierClass.class); - fail(); - } catch (DynamicCodeGenException e) { - assertTrue(true); - } - assertTrue(true); - try { - DynamicPacker.create(ProtectedModifierClass.class); - fail(); - } catch (DynamicCodeGenException e) { - assertTrue(true); - } - assertTrue(true); - try { - DynamicPacker.create(PackageModifierClass.class); - fail(); - } catch (DynamicCodeGenException e) { - assertTrue(true); - } - assertTrue(true); - } - - @Test - public void testClassModifiers01() throws Exception { - try { - DynamicUnpacker.create(PrivateModifierClass.class); - fail(); - } catch (DynamicCodeGenException e) { - assertTrue(true); - } - assertTrue(true); - try { - DynamicUnpacker.create(ProtectedModifierClass.class); - fail(); - } catch (DynamicCodeGenException e) { - assertTrue(true); - } - assertTrue(true); - try { - DynamicUnpacker.create(PackageModifierClass.class); - fail(); - } catch (DynamicCodeGenException e) { - assertTrue(true); - } - assertTrue(true); - } - - private static class PrivateModifierClass { - } - - protected static class ProtectedModifierClass { - protected ProtectedModifierClass() { - } - } - - static class PackageModifierClass { - } - - @Test - public void testFinalClassAndAbstractClass00() throws Exception { - try { - DynamicPacker.create(FinalModifierClass.class); - assertTrue(true); - } catch (DynamicCodeGenException e) { - fail(); - } - assertTrue(true); - try { - DynamicPacker.create(AbstractModifierClass.class); - fail(); - } catch (DynamicCodeGenException e) { - assertTrue(true); - } - assertTrue(true); - } - - @Test - public void testFinalClassAndAbstractClass01() throws Exception { - try { - DynamicUnpacker.create(FinalModifierClass.class); - assertTrue(true); - } catch (DynamicCodeGenException e) { - fail(); - } - assertTrue(true); - try { - DynamicUnpacker.create(AbstractModifierClass.class); - fail(); - } catch (DynamicCodeGenException e) { - assertTrue(true); - } - assertTrue(true); - } - - public final static class FinalModifierClass { - } - - public abstract static class AbstractModifierClass { - } - - @Test - public void testInterfaceType00() throws Exception { - try { - DynamicPacker.create(SampleInterface.class); - fail(); - } catch (DynamicCodeGenException e) { - assertTrue(true); - } - assertTrue(true); - } - - @Test - public void testInterfaceType01() throws Exception { - try { - DynamicUnpacker.create(SampleInterface.class); - fail(); - } catch (DynamicCodeGenException e) { - assertTrue(true); - } - assertTrue(true); - } - - public interface SampleInterface { - } - - @Test - public void testEnumTypeForOrdinal00() throws Exception { - SampleEnumFieldClass src = new SampleEnumFieldClass(); - src.f0 = 0; - src.f1 = SampleEnum.ONE; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = DynamicPacker.create(SampleEnumFieldClass.class); - packer.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Template tmpl = DynamicTemplate.create(SampleEnumFieldClass.class); - SampleEnumFieldClass dst = (SampleEnumFieldClass) tmpl - .unpack(new Unpacker(in)); - assertTrue(src.f0 == dst.f0); - assertTrue(src.f1 == dst.f1); - } - - @Test - public void testEnumTypeForOrdinal01() throws Exception { - SampleEnumFieldClass src = null; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = new OptionalPacker(DynamicPacker - .create(SampleEnumFieldClass.class)); - packer.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Template tmpl = new OptionalTemplate(DynamicTemplate - .create(SampleEnumFieldClass.class)); - SampleEnumFieldClass dst = (SampleEnumFieldClass) tmpl - .unpack(new Unpacker(in)); - assertEquals(src, dst); - } - - public static class SampleEnumFieldClass { - public int f0; - - public SampleEnum f1; - - public SampleEnumFieldClass() { - } - } - - @MessagePackOrdinalEnum - public enum SampleEnum { - ONE, TWO, THREE; - } - - @Test - public void testOptionalEnumTypeForOrdinal00() throws Exception { - SampleOptionalEnumFieldClass src = new SampleOptionalEnumFieldClass(); - src.f0 = 0; - src.f1 = SampleOptionalEnum.ONE; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = DynamicPacker - .create(SampleOptionalEnumFieldClass.class); - packer.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Template tmpl = DynamicTemplate - .create(SampleOptionalEnumFieldClass.class); - SampleOptionalEnumFieldClass dst = (SampleOptionalEnumFieldClass) tmpl - .unpack(new Unpacker(in)); - assertTrue(src.f0 == dst.f0); - assertTrue(src.f1 == dst.f1); - } - - @Test - public void testOptionalEnumTypeForOrdinal01() throws Exception { - SampleOptionalEnumFieldClass src = new SampleOptionalEnumFieldClass(); - src.f1 = null; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = DynamicPacker - .create(SampleOptionalEnumFieldClass.class); - packer.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Template tmpl = DynamicTemplate - .create(SampleOptionalEnumFieldClass.class); - SampleOptionalEnumFieldClass dst = (SampleOptionalEnumFieldClass) tmpl - .unpack(new Unpacker(in)); - assertTrue(src.f0 == dst.f0); - assertEquals(src.f1, dst.f1); - } - - @Test - public void testOptionalEnumTypeForOrdinal02() throws Exception { - SampleEnumFieldClass src = null; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = new OptionalPacker(DynamicPacker - .create(SampleEnumFieldClass.class)); - packer.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Template tmpl = new OptionalTemplate(DynamicTemplate - .create(SampleEnumFieldClass.class)); - SampleEnumFieldClass dst = (SampleEnumFieldClass) tmpl - .unpack(new Unpacker(in)); - assertEquals(src, dst); - } - - public static class SampleOptionalEnumFieldClass { - @MessagePackOptional - public int f0; - - @MessagePackOptional - public SampleOptionalEnum f1; - - public SampleOptionalEnumFieldClass() { - } - } - - @MessagePackOrdinalEnum - public enum SampleOptionalEnum { - ONE, TWO, THREE; - } - - @Test - public void testFieldModifiers() throws Exception { - FieldModifiersClass src = new FieldModifiersClass(); - src.f0 = 0; - src.f2 = 2; - src.f3 = 3; - src.f4 = 4; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = DynamicPacker.create(FieldModifiersClass.class); - packer.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Template tmpl = DynamicTemplate.create(FieldModifiersClass.class); - FieldModifiersClass dst = (FieldModifiersClass) tmpl - .unpack(new Unpacker(in)); - assertTrue(src.f0 == dst.f0); - assertTrue(src.f1 == dst.f1); - assertTrue(src.f2 != dst.f2); - assertTrue(src.f3 != dst.f3); - assertTrue(src.f4 != dst.f4); - } - - public static class FieldModifiersClass { - public int f0; - public final int f1 = 1; - private int f2; - protected int f3; - int f4; - - public FieldModifiersClass() { - } - } - - @Test - public void testOptionalFieldModifiers() throws Exception { - OptionalFieldModifiersClass src = new OptionalFieldModifiersClass(); - src.f0 = 0; - src.f2 = 2; - src.f3 = 3; - src.f4 = 4; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = DynamicPacker - .create(OptionalFieldModifiersClass.class); - packer.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Template tmpl = DynamicTemplate - .create(OptionalFieldModifiersClass.class); - OptionalFieldModifiersClass dst = (OptionalFieldModifiersClass) tmpl - .unpack(new Unpacker(in)); - assertTrue(src.f0 == dst.f0); - assertTrue(src.f1 == dst.f1); - assertTrue(src.f2 != dst.f2); - assertTrue(src.f3 != dst.f3); - assertTrue(src.f4 != dst.f4); - } - - public static class OptionalFieldModifiersClass { - @MessagePackOptional - public int f0; - @MessagePackOptional - public final int f1 = 1; - private int f2; - protected int f3; - int f4; - - public OptionalFieldModifiersClass() { - } - } - - @Test - public void testNestedFieldClass00() throws Exception { - Template tmpl2 = DynamicTemplate.create(NestedClass.class); - CustomMessage.register(NestedClass.class, tmpl2); - Template tmpl = DynamicTemplate.create(BaseClass.class); - CustomMessage.register(BaseClass.class, tmpl); - BaseClass src = new BaseClass(); - NestedClass src2 = new NestedClass(); - src.f0 = 0; - src2.f2 = 2; - src.f1 = src2; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - tmpl.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - BaseClass dst = (BaseClass) tmpl.unpack(new Unpacker(in)); - assertTrue(src.f0 == dst.f0); - assertTrue(src.f1.f2 == dst.f1.f2); - } - - @Test - public void testNestedFieldClass01() throws Exception { - Template tmpl2 = DynamicTemplate.create(NestedClass.class); - CustomMessage.register(NestedClass.class, tmpl2); - Template tmpl = new OptionalTemplate(DynamicTemplate.create(BaseClass.class)); - BaseClass src = null; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - tmpl.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - BaseClass dst = (BaseClass) tmpl.unpack(new Unpacker(in)); - assertEquals(src, dst); - } - - public static class BaseClass { - public int f0; - public NestedClass f1; - - public BaseClass() { - } - } - - public static class NestedClass { - public int f2; - - public NestedClass() { - } - } - - @Test - public void testOptionalNestedFieldClass00() throws Exception { - Template tmpl2 = DynamicTemplate.create(OptionalNestedClass.class); - CustomMessage.register(OptionalNestedClass.class, tmpl2); - Template tmpl = DynamicTemplate.create(OptionalBaseClass.class); - OptionalBaseClass src = new OptionalBaseClass(); - OptionalNestedClass src2 = new OptionalNestedClass(); - src.f0 = 0; - src2.f2 = 2; - src.f1 = src2; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - tmpl.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - OptionalBaseClass dst = (OptionalBaseClass) tmpl.unpack(new Unpacker(in)); - assertTrue(src.f0 == dst.f0); - assertTrue(src.f1.f2 == dst.f1.f2); - } - - @Test - public void testOptionalNestedFieldClass01() throws Exception { - Template tmpl2 = DynamicTemplate.create(OptionalNestedClass.class); - CustomMessage.register(OptionalNestedClass.class, tmpl2); - Template tmpl = DynamicTemplate.create(OptionalBaseClass.class); - CustomMessage.register(OptionalBaseClass.class, tmpl); - OptionalBaseClass src = new OptionalBaseClass(); - src.f1 = null; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - tmpl.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - OptionalBaseClass dst = (OptionalBaseClass) tmpl.unpack(new Unpacker(in)); - assertTrue(src.f0 == dst.f0); - assertTrue(src.f1 == dst.f1); - } - - @Test - public void testOptionalNestedFieldClass02() throws Exception { - Template tmpl2 = DynamicTemplate.create(OptionalNestedClass.class); - CustomMessage.register(OptionalNestedClass.class, tmpl2); - Template tmpl = new OptionalTemplate(DynamicTemplate.create(OptionalBaseClass.class)); - CustomMessage.register(OptionalBaseClass.class, tmpl); - OptionalBaseClass src = null; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - tmpl.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - OptionalBaseClass dst = (OptionalBaseClass) tmpl - .unpack(new Unpacker(in)); - assertEquals(src, dst); - } - - public static class OptionalBaseClass { - @MessagePackOptional - public int f0; - @MessagePackOptional - public OptionalNestedClass f1; - - public OptionalBaseClass() { - } - } - - public static class OptionalNestedClass { - @MessagePackOptional - public int f2; - - public OptionalNestedClass() { - } - } - - @Test - public void testMessagePackMessageFieldClass00() throws Exception { - BaseClass2 src = new BaseClass2(); - MessagePackMessageClass2 src2 = new MessagePackMessageClass2(); - src.f0 = 0; - src2.f2 = 2; - src.f1 = src2; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = DynamicPacker.create(BaseClass2.class); - packer.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Template tmpl = DynamicTemplate.create(BaseClass2.class); - BaseClass2 dst = (BaseClass2) tmpl.unpack(new Unpacker(in)); - assertTrue(src.f0 == dst.f0); - assertTrue(src.f1.f2 == dst.f1.f2); - } - - @Test - public void testMessagePackMessageFieldClass01() throws Exception { - BaseClass2 src = null; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = new OptionalPacker(DynamicPacker - .create(BaseClass2.class)); - packer.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Template tmpl = new OptionalTemplate(DynamicTemplate - .create(BaseClass2.class)); - BaseClass2 dst = (BaseClass2) tmpl.unpack(new Unpacker(in)); - assertEquals(src, dst); - } - - public static class BaseClass2 { - public int f0; - public MessagePackMessageClass2 f1; - - public BaseClass2() { - } - } - - @MessagePackMessage - public static class MessagePackMessageClass2 { - public int f2; - - public MessagePackMessageClass2() { - } - } - - @Test - public void testOptionalMessagePackMessageFieldClass00() throws Exception { - OptionalBaseClass2 src = new OptionalBaseClass2(); - OptionalMessagePackMessageClass2 src2 = new OptionalMessagePackMessageClass2(); - src.f0 = 0; - src2.f2 = 2; - src.f1 = src2; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = DynamicPacker.create(OptionalBaseClass2.class); - packer.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Template tmpl = DynamicTemplate.create(OptionalBaseClass2.class); - OptionalBaseClass2 dst = (OptionalBaseClass2) tmpl.unpack(new Unpacker( - in)); - assertTrue(src.f0 == dst.f0); - assertTrue(src.f1.f2 == dst.f1.f2); - } - - @Test - public void testOptionalMessagePackMessageFieldClass01() throws Exception { - OptionalBaseClass2 src = new OptionalBaseClass2(); - src.f1 = null; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = DynamicPacker.create(OptionalBaseClass2.class); - packer.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Template tmpl = DynamicTemplate.create(OptionalBaseClass2.class); - OptionalBaseClass2 dst = (OptionalBaseClass2) tmpl.unpack(new Unpacker( - in)); - assertTrue(src.f0 == dst.f0); - assertEquals(src.f1, dst.f1); - } - - @Test - public void testOptionalMessagePackMessageFieldClass02() throws Exception { - OptionalBaseClass2 src = null; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = new OptionalPacker(DynamicPacker - .create(OptionalBaseClass2.class)); - packer.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Template tmpl = new OptionalTemplate(DynamicTemplate - .create(OptionalBaseClass2.class)); - OptionalBaseClass2 dst = (OptionalBaseClass2) tmpl.unpack(new Unpacker( - in)); - assertEquals(src, dst); - } - - public static class OptionalBaseClass2 { - @MessagePackOptional - public int f0; - @MessagePackOptional - public OptionalMessagePackMessageClass2 f1; - - public OptionalBaseClass2() { - } - } - - @MessagePackMessage - public static class OptionalMessagePackMessageClass2 { - @MessagePackOptional - public int f2; - - public OptionalMessagePackMessageClass2() { - } - } - - @Test - public void testExtendedClass00() throws Exception { - SampleSubClass src = new SampleSubClass(); - src.f0 = 0; - src.f2 = 2; - src.f3 = 3; - src.f4 = 4; - src.f5 = 5; - src.f8 = 8; - src.f9 = 9; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = DynamicPacker.create(SampleSubClass.class); - packer.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Template tmpl = DynamicTemplate.create(SampleSubClass.class); - SampleSubClass dst = (SampleSubClass) tmpl.unpack(new Unpacker(in)); - assertTrue(src.f0 == dst.f0); - assertTrue(src.f1 == dst.f1); - assertTrue(src.f2 != dst.f2); - assertTrue(src.f3 != dst.f3); - assertTrue(src.f4 != dst.f4); - assertTrue(src.f5 == dst.f5); - assertTrue(src.f6 == dst.f6); - assertTrue(src.f8 != dst.f8); - assertTrue(src.f9 != dst.f9); - } - - @Test - public void testExtendedClass01() throws Exception { - SampleSubClass src = null; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = new OptionalPacker(DynamicPacker - .create(SampleSubClass.class)); - packer.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Template tmpl = new OptionalTemplate(DynamicTemplate - .create(SampleSubClass.class)); - SampleSubClass dst = (SampleSubClass) tmpl.unpack(new Unpacker(in)); - assertEquals(src, dst); - } - - public static class SampleSubClass extends SampleSuperClass { - public int f0; - public final int f1 = 1; - private int f2; - protected int f3; - int f4; - - public SampleSubClass() { - } - } - - public static class SampleSuperClass { - public int f5; - public final int f6 = 2; - @SuppressWarnings("unused") - private int f7; - protected int f8; - int f9; - - public SampleSuperClass() { - } - } - - @Test - public void testOptionalExtendedClass00() throws Exception { - SampleOptionalSubClass src = new SampleOptionalSubClass(); - src.f0 = 0; - src.f2 = 2; - src.f3 = 3; - src.f4 = 4; - src.f5 = 5; - src.f8 = 8; - src.f9 = 9; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = DynamicPacker - .create(SampleOptionalSubClass.class); - packer.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Template tmpl = DynamicTemplate.create(SampleOptionalSubClass.class); - SampleOptionalSubClass dst = (SampleOptionalSubClass) tmpl - .unpack(new Unpacker(in)); - assertTrue(src.f0 == dst.f0); - assertTrue(src.f1 == dst.f1); - assertTrue(src.f2 != dst.f2); - assertTrue(src.f3 != dst.f3); - assertTrue(src.f4 != dst.f4); - assertTrue(src.f5 == dst.f5); - assertTrue(src.f6 == dst.f6); - assertTrue(src.f8 != dst.f8); - assertTrue(src.f9 != dst.f9); - } - - @Test - public void testOptionalExtendedClass01() throws Exception { - SampleOptionalSubClass src = null; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = new OptionalPacker(DynamicPacker - .create(SampleOptionalSubClass.class)); - packer.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Template tmpl = new OptionalTemplate(DynamicTemplate - .create(SampleOptionalSubClass.class)); - SampleOptionalSubClass dst = (SampleOptionalSubClass) tmpl - .unpack(new Unpacker(in)); - assertEquals(src, dst); - } - - public static class SampleOptionalSubClass extends SampleOptionalSuperClass { - @MessagePackOptional - public int f0; - public final int f1 = 1; - private int f2; - protected int f3; - int f4; - - public SampleOptionalSubClass() { - } - } - - public static class SampleOptionalSuperClass { - @MessagePackOptional - public int f5; - public final int f6 = 2; - @SuppressWarnings("unused") - private int f7; - protected int f8; - int f9; - - public SampleOptionalSuperClass() { - } - } - - @Test - public void testMessagePackableUnpackableClass00() throws Exception { - BaseMessagePackableUnpackableClass src = new BaseMessagePackableUnpackableClass(); - MessagePackableUnpackableClass src1 = new MessagePackableUnpackableClass(); - List src2 = new ArrayList(); - src1.f0 = 0; - src1.f1 = 1; - src.f0 = src1; - src.f1 = 1; - src2.add(src1); - src.f2 = src2; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = DynamicPacker - .create(BaseMessagePackableUnpackableClass.class); - packer.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Template tmpl = DynamicTemplate - .create(BaseMessagePackableUnpackableClass.class); - BaseMessagePackableUnpackableClass dst = (BaseMessagePackableUnpackableClass) tmpl - .unpack(new Unpacker(in)); - assertEquals(src.f0.f0, dst.f0.f0); - assertEquals(src.f0.f1, dst.f0.f1); - assertEquals(src.f1, dst.f1); - assertEquals(src.f2.size(), dst.f2.size()); - assertEquals(src.f2.get(0).f0, dst.f2.get(0).f0); - assertEquals(src.f2.get(0).f1, dst.f2.get(0).f1); - } - - @Test - public void testMessagePackableUnpackableClass01() throws Exception { - BaseMessagePackableUnpackableClass src = null; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = new OptionalPacker(DynamicPacker - .create(BaseMessagePackableUnpackableClass.class)); - packer.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Template tmpl = new OptionalTemplate(DynamicTemplate - .create(BaseMessagePackableUnpackableClass.class)); - BaseMessagePackableUnpackableClass dst = (BaseMessagePackableUnpackableClass) tmpl - .unpack(new Unpacker(in)); - assertEquals(src, dst); - } - - public static class BaseMessagePackableUnpackableClass { - public MessagePackableUnpackableClass f0; - public int f1; - public List f2; - - public BaseMessagePackableUnpackableClass() { - } - } - - public static class MessagePackableUnpackableClass implements - MessagePackable, MessageUnpackable { - public int f0; - public int f1; - - public MessagePackableUnpackableClass() { - } - - @Override - public void messagePack(Packer packer) throws IOException { - packer.packArray(2); - packer.pack(f0); - packer.pack(f1); - } - - @Override - public void messageUnpack(Unpacker unpacker) throws IOException, - MessageTypeException { - if (unpacker.tryUnpackNull()) { - return; - } - unpacker.unpackArray(); - f0 = unpacker.unpackInt(); - f1 = unpacker.unpackInt(); - } - } - - @Test - public void testOptionalMessagePackableUnpackableClass00() throws Exception { - OptionalBaseMessagePackableUnpackableClass src = new OptionalBaseMessagePackableUnpackableClass(); - OptionalMessagePackableUnpackableClass src1 = new OptionalMessagePackableUnpackableClass(); - List src2 = new ArrayList(); - src1.f0 = 0; - src1.f1 = 1; - src.f0 = src1; - src.f1 = 1; - src2.add(src1); - src.f2 = src2; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = DynamicPacker - .create(OptionalBaseMessagePackableUnpackableClass.class); - packer.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Template tmpl = DynamicTemplate - .create(OptionalBaseMessagePackableUnpackableClass.class); - OptionalBaseMessagePackableUnpackableClass dst = (OptionalBaseMessagePackableUnpackableClass) tmpl - .unpack(new Unpacker(in)); - assertEquals(src.f0.f0, dst.f0.f0); - assertEquals(src.f0.f1, dst.f0.f1); - assertEquals(src.f1, dst.f1); - assertEquals(src.f2.size(), dst.f2.size()); - assertEquals(src.f2.get(0).f0, dst.f2.get(0).f0); - assertEquals(src.f2.get(0).f1, dst.f2.get(0).f1); - } - - @Test - public void testOptionalMessagePackableUnpackableClass01() throws Exception { - OptionalBaseMessagePackableUnpackableClass src = new OptionalBaseMessagePackableUnpackableClass(); - src.f0 = null; - src.f1 = 1; - src.f2 = null; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = DynamicPacker - .create(OptionalBaseMessagePackableUnpackableClass.class); - packer.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Template tmpl = DynamicTemplate - .create(OptionalBaseMessagePackableUnpackableClass.class); - OptionalBaseMessagePackableUnpackableClass dst = (OptionalBaseMessagePackableUnpackableClass) tmpl - .unpack(new Unpacker(in)); - assertEquals(src.f0, dst.f0); - assertEquals(src.f1, dst.f1); - assertEquals(src.f2, dst.f2); - } - - @Test - public void testOptionalMessagePackableUnpackableClass02() throws Exception { - OptionalBaseMessagePackableUnpackableClass src = null; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = new OptionalPacker(DynamicPacker - .create(OptionalBaseMessagePackableUnpackableClass.class)); - packer.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Template tmpl = new OptionalTemplate(DynamicTemplate - .create(OptionalBaseMessagePackableUnpackableClass.class)); - OptionalBaseMessagePackableUnpackableClass dst = (OptionalBaseMessagePackableUnpackableClass) tmpl - .unpack(new Unpacker(in)); - assertEquals(src, dst); - } - - public static class OptionalBaseMessagePackableUnpackableClass { - @MessagePackOptional - public OptionalMessagePackableUnpackableClass f0; - @MessagePackOptional - public int f1; - @MessagePackOptional - public List f2; - - public OptionalBaseMessagePackableUnpackableClass() { - } - } - - public static class OptionalMessagePackableUnpackableClass implements - MessagePackable, MessageUnpackable { - @MessagePackOptional - public int f0; - @MessagePackOptional - public int f1; - - public OptionalMessagePackableUnpackableClass() { - } - - @Override - public void messagePack(Packer packer) throws IOException { - packer.packArray(2); - packer.pack(f0); - packer.pack(f1); - } - - @Override - public void messageUnpack(Unpacker unpacker) throws IOException, - MessageTypeException { - if (unpacker.tryUnpackNull()) { - return; - } - unpacker.unpackArray(); - f0 = unpacker.unpackInt(); - f1 = unpacker.unpackInt(); - } - } -} diff --git a/java/src/test/java/org/msgpack/util/codegen/TestPackUnpackWithFieldOption.java b/java/src/test/java/org/msgpack/util/codegen/TestPackUnpackWithFieldOption.java deleted file mode 100644 index 62ad7ed..0000000 --- a/java/src/test/java/org/msgpack/util/codegen/TestPackUnpackWithFieldOption.java +++ /dev/null @@ -1,509 +0,0 @@ -package org.msgpack.util.codegen; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.math.BigInteger; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -import org.junit.Test; -import org.msgpack.MessagePacker; -import org.msgpack.Packer; -import org.msgpack.Template; -import org.msgpack.Unpacker; -import org.msgpack.annotation.MessagePackMessage; -import org.msgpack.packer.OptionalPacker; -import org.msgpack.template.ListTemplate; -import org.msgpack.template.MapTemplate; -import org.msgpack.template.OptionalTemplate; -import static org.msgpack.Templates.tBigInteger; -import static org.msgpack.Templates.tBoolean; -import static org.msgpack.Templates.tByte; -import static org.msgpack.Templates.tByteArray; -import static org.msgpack.Templates.tDouble; -import static org.msgpack.Templates.tFloat; -import static org.msgpack.Templates.tInteger; -import static org.msgpack.Templates.tLong; -import static org.msgpack.Templates.tShort; -import static org.msgpack.Templates.tString; - -import junit.framework.TestCase; - -public class TestPackUnpackWithFieldOption extends TestCase { - - @Test - public void testPrimitiveTypeFieldsClass00() throws Exception { - PrimitiveTypeFieldsClass src = new PrimitiveTypeFieldsClass(); - src.f0 = (byte) 0; - src.f1 = 1; - src.f2 = 2; - src.f3 = 3; - src.f4 = 4; - src.f5 = 5; - src.f6 = false; - - List opts = new ArrayList(); - opts.add(new FieldOption("f0", tByte())); - opts.add(new FieldOption("f1", tShort())); - opts.add(new FieldOption("f2", tInteger())); - opts.add(new FieldOption("f3", tLong())); - opts.add(new FieldOption("f4", tFloat())); - opts.add(new FieldOption("f5", tDouble())); - opts.add(new FieldOption("f6", tBoolean())); - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = DynamicPacker.create( - PrimitiveTypeFieldsClass.class, opts); - packer.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Template tmpl = DynamicTemplate.create(PrimitiveTypeFieldsClass.class, - opts); - PrimitiveTypeFieldsClass dst = (PrimitiveTypeFieldsClass) tmpl - .unpack(new Unpacker(in)); - assertEquals(src.f0, dst.f0); - assertEquals(src.f1, dst.f1); - assertEquals(src.f2, dst.f2); - assertEquals(src.f3, dst.f3); - assertEquals(src.f4, dst.f4); - assertEquals(src.f5, dst.f5); - assertEquals(src.f6, dst.f6); - } - - @Test - public void testPrimitiveTypeFieldsClass01() throws Exception { - PrimitiveTypeFieldsClass src = new PrimitiveTypeFieldsClass(); - - List opts = new ArrayList(); - opts.add(new FieldOption("f0", new OptionalTemplate(tByte()))); - opts.add(new FieldOption("f1", new OptionalTemplate(tShort()))); - opts.add(new FieldOption("f2", new OptionalTemplate(tInteger()))); - opts.add(new FieldOption("f3", new OptionalTemplate(tLong()))); - opts.add(new FieldOption("f4", new OptionalTemplate(tFloat()))); - opts.add(new FieldOption("f5", new OptionalTemplate(tDouble()))); - opts.add(new FieldOption("f6", new OptionalTemplate(tBoolean()))); - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = DynamicPacker.create( - PrimitiveTypeFieldsClass.class, opts); - packer.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Template tmpl = DynamicTemplate.create(PrimitiveTypeFieldsClass.class, - opts); - PrimitiveTypeFieldsClass dst = (PrimitiveTypeFieldsClass) tmpl - .unpack(new Unpacker(in)); - assertEquals(src.f0, dst.f0); - assertEquals(src.f1, dst.f1); - assertEquals(src.f2, dst.f2); - assertEquals(src.f3, dst.f3); - assertEquals(src.f4, dst.f4); - assertEquals(src.f5, dst.f5); - assertEquals(src.f6, dst.f6); - } - - @Test - public void testPrimitiveTypeFieldsClass02() throws Exception { - PrimitiveTypeFieldsClass src = null; - - List opts = new ArrayList(); - opts.add(new FieldOption("f0", tByte())); - opts.add(new FieldOption("f1", tShort())); - opts.add(new FieldOption("f2", tInteger())); - opts.add(new FieldOption("f3", tLong())); - opts.add(new FieldOption("f4", tFloat())); - opts.add(new FieldOption("f5", tDouble())); - opts.add(new FieldOption("f6", tBoolean())); - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = new OptionalPacker(DynamicPacker.create( - PrimitiveTypeFieldsClass.class, opts)); - packer.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Template tmpl = new OptionalTemplate(DynamicTemplate.create( - PrimitiveTypeFieldsClass.class, opts)); - PrimitiveTypeFieldsClass dst = (PrimitiveTypeFieldsClass) tmpl - .unpack(new Unpacker(in)); - assertEquals(src, dst); - } - - public static class PrimitiveTypeFieldsClass { - public byte f0; - public short f1; - public int f2; - public long f3; - public float f4; - public double f5; - public boolean f6; - - public PrimitiveTypeFieldsClass() { - } - } - - @Test - public void testGeneralReferenceTypeFieldsClass00() throws Exception { - GeneralReferenceTypeFieldsClass src = new GeneralReferenceTypeFieldsClass(); - src.f0 = 0; - src.f1 = 1; - src.f2 = 2; - src.f3 = (long) 3; - src.f4 = (float) 4; - src.f5 = (double) 5; - src.f6 = false; - src.f7 = new BigInteger("7"); - src.f8 = "8"; - src.f9 = new byte[] { 0x01, 0x02 }; - - List opts = new ArrayList(); - opts.add(new FieldOption("f0", tByte())); - opts.add(new FieldOption("f1", tShort())); - opts.add(new FieldOption("f2", tInteger())); - opts.add(new FieldOption("f3", tLong())); - opts.add(new FieldOption("f4", tFloat())); - opts.add(new FieldOption("f5", tDouble())); - opts.add(new FieldOption("f6", tBoolean())); - opts.add(new FieldOption("f7", tBigInteger())); - opts.add(new FieldOption("f8", tString())); - opts.add(new FieldOption("f9", tByteArray())); - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = DynamicPacker - .create(GeneralReferenceTypeFieldsClass.class, opts); - packer.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Template tmpl = DynamicTemplate - .create(GeneralReferenceTypeFieldsClass.class, opts); - GeneralReferenceTypeFieldsClass dst = (GeneralReferenceTypeFieldsClass) tmpl - .unpack(new Unpacker(in)); - assertEquals(src.f0, dst.f0); - assertEquals(src.f1, dst.f1); - assertEquals(src.f2, dst.f2); - assertEquals(src.f3, dst.f3); - assertEquals(src.f4, dst.f4); - assertEquals(src.f5, dst.f5); - assertEquals(src.f6, dst.f6); - assertEquals(src.f7, dst.f7); - assertEquals(src.f8, dst.f8); - assertEquals(src.f9[0], dst.f9[0]); - assertEquals(src.f9[1], dst.f9[1]); - } - - @Test - public void testGeneralReferenceTypeFieldsClass01() throws Exception { - GeneralReferenceTypeFieldsClass src = new GeneralReferenceTypeFieldsClass(); - src.f0 = null; - src.f1 = null; - src.f2 = null; - src.f3 = null; - src.f4 = null; - src.f5 = null; - src.f6 = null; - src.f7 = null; - src.f8 = null; - src.f9 = null; - - List opts = new ArrayList(); - opts.add(new FieldOption("f0", new OptionalTemplate(tByte()))); - opts.add(new FieldOption("f1", new OptionalTemplate(tShort()))); - opts.add(new FieldOption("f2", new OptionalTemplate(tInteger()))); - opts.add(new FieldOption("f3", new OptionalTemplate(tLong()))); - opts.add(new FieldOption("f4", new OptionalTemplate(tFloat()))); - opts.add(new FieldOption("f5", new OptionalTemplate(tDouble()))); - opts.add(new FieldOption("f6", new OptionalTemplate(tBoolean()))); - opts.add(new FieldOption("f7", new OptionalTemplate(tBigInteger()))); - opts.add(new FieldOption("f8", new OptionalTemplate(tString()))); - opts.add(new FieldOption("f9", new OptionalTemplate(tByteArray()))); - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = DynamicPacker - .create(GeneralReferenceTypeFieldsClass.class, opts); - packer.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Template tmpl = DynamicTemplate - .create(GeneralReferenceTypeFieldsClass.class, opts); - GeneralReferenceTypeFieldsClass dst = (GeneralReferenceTypeFieldsClass) tmpl - .unpack(new Unpacker(in)); - assertEquals(src.f0, dst.f0); - assertEquals(src.f1, dst.f1); - assertEquals(src.f2, dst.f2); - assertEquals(src.f3, dst.f3); - assertEquals(src.f4, dst.f4); - assertEquals(src.f5, dst.f5); - assertEquals(src.f6, dst.f6); - assertEquals(src.f7, dst.f7); - assertEquals(src.f8, dst.f8); - assertEquals(src.f9, dst.f9); - } - - @Test - public void testGeneralReferenceTypeFieldsClass02() - throws Exception { - GeneralReferenceTypeFieldsClass src = null; - - List opts = new ArrayList(); - opts.add(new FieldOption("f0", new OptionalTemplate(tByte()))); - opts.add(new FieldOption("f1", new OptionalTemplate(tShort()))); - opts.add(new FieldOption("f2", new OptionalTemplate(tInteger()))); - opts.add(new FieldOption("f3", new OptionalTemplate(tLong()))); - opts.add(new FieldOption("f4", new OptionalTemplate(tFloat()))); - opts.add(new FieldOption("f5", new OptionalTemplate(tDouble()))); - opts.add(new FieldOption("f6", new OptionalTemplate(tBoolean()))); - opts.add(new FieldOption("f7", new OptionalTemplate(tBigInteger()))); - opts.add(new FieldOption("f8", new OptionalTemplate(tString()))); - opts.add(new FieldOption("f9", new OptionalTemplate(tByteArray()))); - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = new OptionalPacker(DynamicPacker - .create(GeneralReferenceTypeFieldsClass.class, opts)); - packer.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Template tmpl = new OptionalTemplate(DynamicTemplate - .create(GeneralReferenceTypeFieldsClass.class, opts)); - GeneralReferenceTypeFieldsClass dst = (GeneralReferenceTypeFieldsClass) tmpl - .unpack(new Unpacker(in)); - assertEquals(src, dst); - } - - public static class GeneralReferenceTypeFieldsClass { - public Byte f0; - public Short f1; - public Integer f2; - public Long f3; - public Float f4; - public Double f5; - public Boolean f6; - public BigInteger f7; - public String f8; - public byte[] f9; - - public GeneralReferenceTypeFieldsClass() { - } - } - - @Test - public void testListTypes00() throws Exception { - SampleListTypes src = new SampleListTypes(); - src.f0 = new ArrayList(); - src.f1 = new ArrayList(); - src.f1.add(1); - src.f1.add(2); - src.f1.add(3); - src.f2 = new ArrayList(); - src.f2.add("e1"); - src.f2.add("e2"); - src.f2.add("e3"); - src.f3 = new ArrayList>(); - src.f3.add(src.f2); - src.f4 = new ArrayList(); - SampleListNestedType slnt = new SampleListNestedType(); - slnt.f0 = new byte[] { 0x01, 0x02 }; - slnt.f1 = "muga"; - src.f4.add(slnt); - - List opts = new ArrayList(); - opts.add(new FieldOption("f0", new ListTemplate(tInteger()))); - opts.add(new FieldOption("f1", new ListTemplate(tInteger()))); - opts.add(new FieldOption("f2", new ListTemplate(tString()))); - opts.add(new FieldOption("f3", new ListTemplate(new ListTemplate(tString())))); - opts.add(new FieldOption("f4", new ListTemplate(DynamicTemplate.create(SampleListNestedType.class)))); - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = DynamicPacker - .create(SampleListTypes.class, opts); - packer.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Template tmpl = DynamicTemplate.create(SampleListTypes.class, opts); - SampleListTypes dst = (SampleListTypes) tmpl - .unpack(new Unpacker(in)); - assertEquals(src.f0.size(), dst.f0.size()); - assertEquals(src.f1.size(), dst.f1.size()); - for (int i = 0; i < src.f1.size(); ++i) { - assertEquals(src.f1.get(i), dst.f1.get(i)); - } - assertEquals(src.f2.size(), dst.f2.size()); - for (int i = 0; i < src.f2.size(); ++i) { - assertEquals(src.f2.get(i), dst.f2.get(i)); - } - assertEquals(src.f3.size(), dst.f3.size()); - for (int i = 0; i < src.f3.size(); ++i) { - List srclist = src.f3.get(i); - List dstlist = dst.f3.get(i); - assertEquals(srclist.size(), dstlist.size()); - for (int j = 0; j < srclist.size(); ++j) { - assertEquals(srclist.get(j), dstlist.get(j)); - } - } - assertEquals(src.f4.size(), dst.f4.size()); - for (int i = 0; i < src.f4.size(); ++i) { - SampleListNestedType s = src.f4.get(i); - SampleListNestedType d = dst.f4.get(i); - assertEquals(s.f0[0], d.f0[0]); - assertEquals(s.f0[1], d.f0[1]); - assertEquals(s.f1, d.f1); - } - } - - @Test - public void testListTypes01() throws Exception { - SampleListTypes src = new SampleListTypes(); - src.f0 = new ArrayList(); - src.f1 = null; - src.f2 = new ArrayList(); - src.f3 = new ArrayList>(); - src.f4 = null; - - List opts = new ArrayList(); - opts.add(new FieldOption("f0", new OptionalTemplate(new ListTemplate(tInteger())))); - opts.add(new FieldOption("f1", new OptionalTemplate(new ListTemplate(tInteger())))); - opts.add(new FieldOption("f2", new OptionalTemplate(new ListTemplate(tString())))); - opts.add(new FieldOption("f3", new OptionalTemplate(new ListTemplate(new ListTemplate(tString()))))); - opts.add(new FieldOption("f4", new OptionalTemplate(new ListTemplate(DynamicTemplate.create(SampleListNestedType.class))))); - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = DynamicPacker - .create(SampleListTypes.class, opts); - packer.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Template tmpl = DynamicTemplate.create(SampleListTypes.class, opts); - SampleListTypes dst = (SampleListTypes) tmpl - .unpack(new Unpacker(in)); - assertEquals(src.f0.size(), dst.f0.size()); - assertEquals(src.f1, dst.f1); - assertEquals(src.f2.size(), dst.f2.size()); - assertEquals(src.f3.size(), dst.f3.size()); - assertEquals(src.f4, dst.f4); - } - - @Test - public void testListTypes02() throws Exception { - SampleListTypes src = null; - - List opts = new ArrayList(); - opts.add(new FieldOption("f0", new OptionalTemplate(new ListTemplate(tInteger())))); - opts.add(new FieldOption("f1", new OptionalTemplate(new ListTemplate(tInteger())))); - opts.add(new FieldOption("f2", new OptionalTemplate(new ListTemplate(tString())))); - opts.add(new FieldOption("f3", new OptionalTemplate(new ListTemplate(new ListTemplate(tString()))))); - opts.add(new FieldOption("f4", new OptionalTemplate(new ListTemplate(DynamicTemplate.create(SampleListNestedType.class))))); - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = new OptionalPacker(DynamicPacker - .create(SampleListTypes.class)); - packer.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Template tmpl = new OptionalTemplate(DynamicTemplate - .create(SampleListTypes.class)); - SampleListTypes dst = (SampleListTypes) tmpl.unpack(new Unpacker(in)); - assertEquals(src, dst); - } - - public static class SampleListTypes { - public List f0; - public List f1; - public List f2; - public List> f3; - public List f4; - - public SampleListTypes() { - } - } - - @MessagePackMessage - public static class SampleListNestedType { - public byte[] f0; - public String f1; - - public SampleListNestedType() { - } - } - - @Test - public void testMapTypes00() throws Exception { - SampleMapTypes src = new SampleMapTypes(); - src.f0 = new HashMap(); - src.f1 = new HashMap(); - src.f1.put(1, 1); - src.f1.put(2, 2); - src.f1.put(3, 3); - src.f2 = new HashMap(); - src.f2.put("k1", 1); - src.f2.put("k2", 2); - src.f2.put("k3", 3); - - List opts = new ArrayList(); - opts.add(new FieldOption("f0", new MapTemplate(tInteger(), tInteger()))); - opts.add(new FieldOption("f1", new MapTemplate(tInteger(), tInteger()))); - opts.add(new FieldOption("f2", new MapTemplate(tString(), tInteger()))); - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = DynamicPacker - .create(SampleMapTypes.class, opts); - packer.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Template tmpl = DynamicTemplate.create(SampleMapTypes.class, opts); - SampleMapTypes dst = (SampleMapTypes) tmpl - .unpack(new Unpacker(in)); - assertEquals(src.f0.size(), dst.f0.size()); - assertEquals(src.f1.size(), dst.f1.size()); - Iterator srcf1 = src.f1.keySet().iterator(); - Iterator dstf1 = dst.f1.keySet().iterator(); - while (srcf1.hasNext()) { - Integer s1 = srcf1.next(); - Integer d1 = dstf1.next(); - assertEquals(s1, d1); - assertEquals(src.f1.get(s1), dst.f1.get(d1)); - } - assertEquals(src.f2.size(), dst.f2.size()); - Iterator srcf2 = src.f2.keySet().iterator(); - Iterator dstf2 = dst.f2.keySet().iterator(); - while (srcf2.hasNext()) { - String s2 = srcf2.next(); - String d2 = dstf2.next(); - assertEquals(s2, d2); - assertEquals(src.f2.get(s2), dst.f2.get(d2)); - } - } - - @Test - public void testMapTypes01() throws Exception { - SampleMapTypes src = new SampleMapTypes(); - src.f0 = new HashMap(); - src.f1 = null; - src.f2 = new HashMap(); - - List opts = new ArrayList(); - opts.add(new FieldOption("f0", new OptionalTemplate(new MapTemplate(tInteger(), tInteger())))); - opts.add(new FieldOption("f1", new OptionalTemplate(new MapTemplate(tInteger(), tInteger())))); - opts.add(new FieldOption("f2", new OptionalTemplate(new MapTemplate(tString(), tInteger())))); - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = DynamicPacker - .create(SampleMapTypes.class, opts); - packer.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Template tmpl = DynamicTemplate.create(SampleMapTypes.class, opts); - SampleMapTypes dst = (SampleMapTypes) tmpl - .unpack(new Unpacker(in)); - assertEquals(src.f0.size(), dst.f0.size()); - assertEquals(src.f1, dst.f1); - assertEquals(src.f2.size(), dst.f2.size()); - } - - @Test - public void testMapTypes02() throws Exception { - SampleMapTypes src = null; - - List opts = new ArrayList(); - opts.add(new FieldOption("f0", new OptionalTemplate(new MapTemplate(tInteger(), tInteger())))); - opts.add(new FieldOption("f1", new OptionalTemplate(new MapTemplate(tInteger(), tInteger())))); - opts.add(new FieldOption("f2", new OptionalTemplate(new MapTemplate(tString(), tInteger())))); - ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = new OptionalPacker(DynamicPacker - .create(SampleMapTypes.class, opts)); - packer.pack(new Packer(out), src); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - Template tmpl = new OptionalTemplate(DynamicTemplate - .create(SampleMapTypes.class, opts)); - SampleMapTypes dst = (SampleMapTypes) tmpl - .unpack(new Unpacker(in)); - assertEquals(src, dst); - } - - public static class SampleMapTypes { - public Map f0; - public Map f1; - public Map f2; - - public SampleMapTypes() { - } - } -} diff --git a/java/test/Generate.java b/java/test/Generate.java deleted file mode 100644 index 1b72e90..0000000 --- a/java/test/Generate.java +++ /dev/null @@ -1,38 +0,0 @@ -import java.io.*; -import java.util.*; -import org.msgpack.*; -import org.msgpack.schema.*; - -public class Generate { - public static void main(String[] args) throws IOException - { - String source = - "(class MediaContent"+ - " (package serializers.msgpack)"+ - " (field image (array (class Image"+ - " (field uri string)"+ - " (field title string)"+ - " (field width int)"+ - " (field height int)"+ - " (field size int))))"+ - " (field media (class Media"+ - " (field uri string)"+ - " (field title string)"+ - " (field width int)"+ - " (field height int)"+ - " (field format string)"+ - " (field duration long)"+ - " (field size long)"+ - " (field bitrate int)"+ - " (field person (array string))"+ - " (field player int)"+ - " (field copyright string)))"+ - " )"; - - Schema schema = Schema.parse(source); - - Writer output = new OutputStreamWriter(System.out); - ClassGenerator.write(schema, output); - } -} - diff --git a/java/test/README b/java/test/README deleted file mode 100644 index 9b98d91..0000000 --- a/java/test/README +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/sh -svn checkout -r114 http://thrift-protobuf-compare.googlecode.com/svn/trunk/ thrift-protobuf-compare-base -cp -rf thrift-protobuf-compare/tpc thrift-protobuf-compare-base -cp ../target/msgpack*.jar thrift-protobuf-compare-base/tpc/lib/msgpack.jar -cd thrift-protobuf-compare-base/tpc/ -ant compile -./run-benchmark.sh diff --git a/java/test/thrift-protobuf-compare/tpc/src/serializers/BenchmarkRunner.java b/java/test/thrift-protobuf-compare/tpc/src/serializers/BenchmarkRunner.java deleted file mode 100644 index fa88b6b..0000000 --- a/java/test/thrift-protobuf-compare/tpc/src/serializers/BenchmarkRunner.java +++ /dev/null @@ -1,436 +0,0 @@ -package serializers; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.EnumMap; -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.LinkedHashSet; -import java.util.Map; -import java.util.Set; -import java.util.Map.Entry; - -import serializers.msgpack.MessagePackDirectSerializer; -import serializers.msgpack.MessagePackSpecificSerializer; -import serializers.msgpack.MessagePackIndirectSerializer; -import serializers.msgpack.MessagePackDynamicSerializer; -import serializers.msgpack.MessagePackGenericSerializer; -import serializers.avro.AvroGenericSerializer; -import serializers.avro.specific.AvroSpecificSerializer; -import serializers.kryo.KryoOptimizedSerializer; -import serializers.kryo.KryoSerializer; - -public class BenchmarkRunner -{ - public final static int ITERATIONS = 2000; - public final static int TRIALS = 20; - - /** - * Number of milliseconds to warm up for each operation type for each serializer. Let's - * start with 3 seconds. - */ - final static long WARMUP_MSECS = 3000; - - @SuppressWarnings("unchecked") - private Set _serializers = new LinkedHashSet(); - - public static void main(String... args) throws Exception - { - BenchmarkRunner runner = new BenchmarkRunner(); - - // binary codecs first - runner.addObjectSerializer(new MessagePackDirectSerializer()); - runner.addObjectSerializer(new MessagePackSpecificSerializer()); - runner.addObjectSerializer(new MessagePackIndirectSerializer()); - runner.addObjectSerializer(new MessagePackDynamicSerializer()); - runner.addObjectSerializer(new MessagePackGenericSerializer()); - runner.addObjectSerializer(new AvroGenericSerializer()); - runner.addObjectSerializer(new AvroSpecificSerializer()); - runner.addObjectSerializer(new ActiveMQProtobufSerializer()); - runner.addObjectSerializer(new ProtobufSerializer()); - runner.addObjectSerializer(new ThriftSerializer()); - runner.addObjectSerializer(new HessianSerializer()); - runner.addObjectSerializer(new KryoSerializer()); - runner.addObjectSerializer(new KryoOptimizedSerializer()); - - // None of the other serializers use compression, so we'll leave this out. - // runner.addObjectSerializer(new KryoCompressedSerializer()); - - // then language default serializers - runner.addObjectSerializer(new JavaSerializer()); - - runner.addObjectSerializer(new JavaExtSerializer()); - runner.addObjectSerializer(new ScalaSerializer()); - - // then Json - runner.addObjectSerializer(new JsonSerializer()); - runner.addObjectSerializer(new JsonDataBindingSerializer()); - runner.addObjectSerializer(new JsonMarshallerSerializer()); - runner.addObjectSerializer(new ProtostuffJsonSerializer()); - runner.addObjectSerializer(new ProtostuffNumericJsonSerializer()); - // this is pretty slow; so slow that it's almost not worth keeping but: - runner.addObjectSerializer(new GsonSerializer()); - - // then xml via stax, textual and binary - runner.addObjectSerializer(new StaxSerializer("stax/woodstox", - new com.ctc.wstx.stax.WstxInputFactory(), - new com.ctc.wstx.stax.WstxOutputFactory())); - runner.addObjectSerializer(new StaxSerializer("stax/aalto", - new com.fasterxml.aalto.stax.InputFactoryImpl(), - new com.fasterxml.aalto.stax.OutputFactoryImpl())); - - runner.addObjectSerializer(new StaxSerializer("binaryxml/FI", - new com.sun.xml.fastinfoset.stax.factory.StAXInputFactory(), - new com.sun.xml.fastinfoset.stax.factory.StAXOutputFactory())); - - // No point in running all 4 variants: let's just use fastest one: - //runner.addObjectSerializer(new XStreamSerializer("xstream (xpp)", false, null, null)); - //runner.addObjectSerializer(new XStreamSerializer("xstream (xpp with conv)", true, null, null)); - //runner.addObjectSerializer(new XStreamSerializer("xstream (stax)", false, new com.ctc.wstx.stax.WstxInputFactory(), new com.ctc.wstx.stax.WstxOutputFactory())); - runner.addObjectSerializer(new XStreamSerializer("xstream (stax with conv)", - true, - new com.ctc.wstx.stax.WstxInputFactory(), - new com.ctc.wstx.stax.WstxOutputFactory())); - runner.addObjectSerializer(new JavolutionXMLFormatSerializer()); - - runner.addObjectSerializer(new SbinarySerializer()); - // broken? Does not correctly round-trip: - // runner.addObjectSerializer(new YamlSerializer()); - - System.out.println("Starting"); - - runner.start(); - } - - @SuppressWarnings("unchecked") - private void addObjectSerializer(ObjectSerializer serializer) - { - _serializers.add(serializer); - } - - private double createObjects(ObjectSerializer serializer, int iterations) throws Exception - { - long start = System.nanoTime(); - for (int i = 0; i < iterations; i++) - { - serializer.create(); - } - return iterationTime(System.nanoTime() - start, iterations); - } - - private double iterationTime(long delta, int iterations) - { - return (double) delta / (double) (iterations); - } - - private double serializeDifferentObjects(ObjectSerializer serializer, int iterations) throws Exception - { - long start = System.nanoTime(); - for (int i = 0; i < iterations; i++) - { - T obj = serializer.create(); - serializer.serialize(obj); - } - return iterationTime(System.nanoTime()-start, iterations); - } - - - private double serializeSameObject(ObjectSerializer serializer, int iterations) throws Exception - { - // let's reuse same instance to reduce overhead - T obj = serializer.create(); - long delta = 0; - for (int i = 0; i < iterations; i++) - { - long start = System.nanoTime(); - serializer.serialize(obj); - delta += System.nanoTime() - start; - if (i % 1000 == 0) - doGc(); - } - return iterationTime(delta, iterations); - } - - private double deserializeNoFieldAccess(ObjectSerializer serializer, int iterations) throws Exception - { - byte[] array = serializer.serialize(serializer.create()); - long start = System.nanoTime(); - T result = null; - for (int i = 0; i < iterations; i++) - { - result = serializer.deserialize(array); - } - return iterationTime(System.nanoTime()-start, iterations); - } - - private double deserializeAndCheckAllFields(CheckingObjectSerializer serializer, int iterations) throws Exception - { - byte[] array = serializer.serialize(serializer.create()); - long delta = 0; - for (int i = 0; i < iterations; i++) - { - long start = System.nanoTime(); - T obj = serializer.deserialize(array); - serializer.checkAllFields(obj); - delta += System.nanoTime() - start; - } - return iterationTime(delta, iterations); - } - - private double deserializeAndCheckMediaField(CheckingObjectSerializer serializer, int iterations) throws Exception - { - byte[] array = serializer.serialize(serializer.create()); - long delta = 0; - for (int i = 0; i < iterations; i++) - { - long start = System.nanoTime(); - T obj = serializer.deserialize(array); - serializer.checkMediaField(obj); - delta += System.nanoTime() - start; - } - return iterationTime(delta, iterations); - } - - /** - * JVM is not required to honor GC requests, but adding bit of sleep around request is - * most likely to give it a chance to do it. - */ - private void doGc() - { - try { - Thread.sleep(50L); - } catch (InterruptedException ie) { } - System.gc(); - try { // longer sleep afterwards (not needed by GC, but may help with scheduling) - Thread.sleep(200L); - } catch (InterruptedException ie) { } - } - - enum measurements - { - timeCreate, timeSerializeDifferentObjects, timeSerializeSameObject, timeDeserializeNoFieldAccess, timeDeserializeAndCheckMediaField, timeDeserializeAndCheckAllFields, totalTime, length - } - - @SuppressWarnings("unchecked") - private void start() throws Exception - { - System.out.printf("%-24s, %15s, %15s, %15s, %15s, %15s, %15s, %15s, %10s\n", - " ", - "Object create", - "Serialize", - "/w Same Object", - "Deserialize", - "and Check Media", - "and Check All", - "Total Time", - "Serialized Size"); - EnumMap> values = new EnumMap>(measurements.class); - for (measurements m : measurements.values()) - values.put(m, new HashMap()); - - for (ObjectSerializer serializer : _serializers) - { - /* - * Should only warm things for the serializer that we test next: HotSpot JIT will - * otherwise spent most of its time optimizing slower ones... Use - * -XX:CompileThreshold=1 to hint the JIT to start immediately - * - * Actually: 1 is often not a good value -- threshold is the number - * of samples needed to trigger inlining, and there's no point in - * inlining everything. Default value is in thousands, so lowering - * it to, say, 1000 is usually better. - */ - warmCreation(serializer); - doGc(); - double timeCreate = Double.MAX_VALUE; - // do more iteration for object creation because of its short time - for (int i = 0; i < TRIALS; i++) - timeCreate = Math.min(timeCreate, createObjects(serializer, ITERATIONS * 100)); - - warmSerialization(serializer); - - // actually: let's verify serializer actually works now: - checkCorrectness(serializer); - - doGc(); - double timeSerializeDifferentObjects = Double.MAX_VALUE; - for (int i = 0; i < TRIALS; i++) - timeSerializeDifferentObjects = Math.min(timeSerializeDifferentObjects, serializeDifferentObjects(serializer, ITERATIONS)); - - doGc(); - double timeSerializeSameObject = Double.MAX_VALUE; - for (int i = 0; i < TRIALS; i++) - timeSerializeSameObject = Math.min(timeSerializeSameObject, serializeSameObject(serializer, ITERATIONS)); - - warmDeserialization(serializer); - - doGc(); - double timeDeserializeNoFieldAccess = Double.MAX_VALUE; - for (int i = 0; i < TRIALS; i++) - timeDeserializeNoFieldAccess = Math.min(timeDeserializeNoFieldAccess, deserializeNoFieldAccess(serializer, ITERATIONS)); - - double timeDeserializeAndCheckAllFields = Double.NaN; - double timeDeserializeAndCheckMediaField = Double.NaN; - - double totalTime = timeSerializeDifferentObjects + timeDeserializeNoFieldAccess; - - if( serializer instanceof CheckingObjectSerializer) { - CheckingObjectSerializer checkingSerializer = (CheckingObjectSerializer)serializer; - - timeDeserializeAndCheckMediaField = Double.MAX_VALUE; - doGc(); - for (int i = 0; i < TRIALS; i++) - timeDeserializeAndCheckMediaField = Math.min(timeDeserializeAndCheckMediaField, deserializeAndCheckMediaField(checkingSerializer, ITERATIONS)); - - timeDeserializeAndCheckAllFields = Double.MAX_VALUE; - doGc(); - for (int i = 0; i < TRIALS; i++) - timeDeserializeAndCheckAllFields = Math.min(timeDeserializeAndCheckAllFields, deserializeAndCheckAllFields(checkingSerializer, ITERATIONS)); - - totalTime = timeSerializeDifferentObjects + timeDeserializeAndCheckAllFields; - } - - - byte[] array = serializer.serialize(serializer.create()); - System.out.printf("%-24s, %15.5f, %15.5f, %15.5f, %15.5f, %15.5f, %15.5f, %15.5f, %10d\n", - serializer.getName(), - timeCreate, - timeSerializeDifferentObjects, - timeSerializeSameObject, - timeDeserializeNoFieldAccess, - timeDeserializeAndCheckMediaField, - timeDeserializeAndCheckAllFields, - totalTime, - array.length); - - addValue(values, serializer.getName(), timeCreate, timeSerializeDifferentObjects, timeSerializeSameObject, - timeDeserializeNoFieldAccess, timeDeserializeAndCheckMediaField, timeDeserializeAndCheckAllFields, totalTime, array.length); - } - printImages(values); - } - - /** - * Method that tries to validate correctness of serializer, using - * round-trip (construct, serializer, deserialize; compare objects - * after steps 1 and 3). - * Currently only done for StdMediaDeserializer... - */ - private void checkCorrectness(ObjectSerializer serializer) - throws Exception - { - Object input = serializer.create(); - byte[] array = serializer.serialize(input); - Object output = serializer.deserialize(array); - - if (!input.equals(output)) { - /* Should throw an exception; but for now (that we have a few - * failures) let's just whine... - */ - String msg = "serializer '"+serializer.getName()+"' failed round-trip test (ser+deser produces Object different from input), input="+input+", output="+output; - //throw new Exception("Error: "+msg); - System.err.println("WARN: "+msg); - } - } - - private void printImages(EnumMap> values) - { - for (measurements m : values.keySet()) { - Map map = values.get(m); - ArrayList list = new ArrayList(map.entrySet()); - Collections.sort(list, new Comparator() { - public int compare (Entry o1, Entry o2) { - double diff = (Double)o1.getValue() - (Double)o2.getValue(); - return diff > 0 ? 1 : (diff < 0 ? -1 : 0); - } - }); - LinkedHashMap sortedMap = new LinkedHashMap(); - for (Entry entry : list) { - if( !entry.getValue().isNaN() ) { - sortedMap.put(entry.getKey(), entry.getValue()); - } - } - printImage(sortedMap, m); - } - } - - private void printImage(Map map, measurements m) - { - StringBuilder valSb = new StringBuilder(); - String names = ""; - double max = Double.MIN_NORMAL; - for (Entry entry : map.entrySet()) - { - valSb.append(entry.getValue()).append(','); - max = Math.max(max, entry.getValue()); - names = entry.getKey() + '|' + names; - } - - int height = Math.min(30+map.size()*20, 430); - double scale = max * 1.1; - System.out.println(""); - - } - - private void addValue(EnumMap> values, - String name, - double timeCreate, - double timeSerializeDifferentObjects, - double timeSerializeSameObject, - double timeDeserializeNoFieldAccess, - double timeDeserializeAndCheckMediaField, - double timeDeserializeAndCheckAllFields, - double totalTime, - double length) - { - - values.get(measurements.timeCreate).put(name, timeCreate); - values.get(measurements.timeSerializeDifferentObjects).put(name, timeSerializeDifferentObjects); - values.get(measurements.timeSerializeSameObject).put(name, timeSerializeSameObject); - values.get(measurements.timeDeserializeNoFieldAccess).put(name, timeDeserializeNoFieldAccess); - values.get(measurements.timeDeserializeAndCheckMediaField).put(name, timeDeserializeAndCheckMediaField); - values.get(measurements.timeDeserializeAndCheckAllFields).put(name, timeDeserializeAndCheckAllFields); - values.get(measurements.totalTime).put(name, totalTime); - values.get(measurements.length).put(name, length); - } - - private void warmCreation(ObjectSerializer serializer) throws Exception - { - // Instead of fixed counts, let's try to prime by running for N seconds - long endTime = System.currentTimeMillis() + WARMUP_MSECS; - do - { - createObjects(serializer, 1); - } - while (System.currentTimeMillis() < endTime); - } - - private void warmSerialization(ObjectSerializer serializer) throws Exception - { - // Instead of fixed counts, let's try to prime by running for N seconds - long endTime = System.currentTimeMillis() + WARMUP_MSECS; - do - { - serializeDifferentObjects(serializer, 1); - } - while (System.currentTimeMillis() < endTime); - } - - private void warmDeserialization(ObjectSerializer serializer) throws Exception - { - // Instead of fixed counts, let's try to prime by running for N seconds - long endTime = System.currentTimeMillis() + WARMUP_MSECS; - do - { - deserializeNoFieldAccess(serializer, 1); - } - while (System.currentTimeMillis() < endTime); - } -} diff --git a/java/test/thrift-protobuf-compare/tpc/src/serializers/msgpack/MediaContent.java b/java/test/thrift-protobuf-compare/tpc/src/serializers/msgpack/MediaContent.java deleted file mode 100644 index e750b5a..0000000 --- a/java/test/thrift-protobuf-compare/tpc/src/serializers/msgpack/MediaContent.java +++ /dev/null @@ -1,239 +0,0 @@ -package serializers.msgpack; - -import java.util.*; -import java.io.*; -import org.msgpack.*; -import org.msgpack.schema.ClassSchema; -import org.msgpack.schema.FieldSchema; - -public final class MediaContent implements MessagePackable, MessageConvertable, MessageUnpackable -{ - private static final ClassSchema _SCHEMA = (ClassSchema)Schema.load("(class MediaContent (package serializers.msgpack) (field image (array (class Image (package serializers.msgpack) (field uri string) (field title string) (field width int) (field height int) (field size int)))) (field media (class Media (package serializers.msgpack) (field uri string) (field title string) (field width int) (field height int) (field format string) (field duration long) (field size long) (field bitrate int) (field person (array string)) (field player int) (field copyright string))))"); - public static ClassSchema getSchema() { return _SCHEMA; } - - public List image; - public Media media; - - public MediaContent() { } - - @Override - public void messagePack(Packer _pk) throws IOException - { - _pk.packArray(2); - FieldSchema[] _fields = _SCHEMA.getFields(); - _fields[0].getSchema().pack(_pk, image); - _fields[1].getSchema().pack(_pk, media); - } - - @Override - @SuppressWarnings("unchecked") - public void messageConvert(Object obj) throws MessageTypeException - { - Object[] _source = ((List)obj).toArray(); - FieldSchema[] _fields = _SCHEMA.getFields(); - if(_source.length <= 0) { return; } this.image = (List)_fields[0].getSchema().convert(_source[0]); - if(_source.length <= 1) { return; } this.media = (Media)_fields[1].getSchema().convert(_source[1]); - } - - @Override - public void messageUnpack(Unpacker _pac) throws IOException, MessageTypeException { - int _length = _pac.unpackArray(); - if(_length <= 0) { return; } - int _image_length = _pac.unpackArray(); - this.image = new ArrayList(_image_length); - for(int _i=0; _i < _image_length; ++_i) { - Image _image_i = new Image(); - _image_i.messageUnpack(_pac); - this.image.add(_image_i); - } - if(_length <= 1) { return; } - this.media = new Media(); - this.media.messageUnpack(_pac); - for(int _i=2; _i < _length; ++_i) { _pac.unpackObject(); } - } - - @SuppressWarnings("unchecked") - public static MediaContent createFromMessage(Object[] _message) - { - MediaContent _self = new MediaContent(); - if(_message.length <= 0) { return _self; } _self.image = (List)_message[0]; - if(_message.length <= 1) { return _self; } _self.media = (Media)_message[1]; - return _self; - } -} - -final class Image implements MessagePackable, MessageConvertable, MessageUnpackable -{ - private static final ClassSchema _SCHEMA = (ClassSchema)Schema.load("(class Image (package serializers.msgpack) (field uri string) (field title string) (field width int) (field height int) (field size int))"); - public static ClassSchema getSchema() { return _SCHEMA; } - - public String uri; - public String title; - public Integer width; - public Integer height; - public Integer size; - - public Image() { } - - @Override - public void messagePack(Packer _pk) throws IOException - { - _pk.packArray(5); - FieldSchema[] _fields = _SCHEMA.getFields(); - _fields[0].getSchema().pack(_pk, uri); - _fields[1].getSchema().pack(_pk, title); - _fields[2].getSchema().pack(_pk, width); - _fields[3].getSchema().pack(_pk, height); - _fields[4].getSchema().pack(_pk, size); - } - - @Override - @SuppressWarnings("unchecked") - public void messageConvert(Object obj) throws MessageTypeException - { - Object[] _source = ((List)obj).toArray(); - FieldSchema[] _fields = _SCHEMA.getFields(); - if(_source.length <= 0) { return; } this.uri = (String)_fields[0].getSchema().convert(_source[0]); - if(_source.length <= 1) { return; } this.title = (String)_fields[1].getSchema().convert(_source[1]); - if(_source.length <= 2) { return; } this.width = (Integer)_fields[2].getSchema().convert(_source[2]); - if(_source.length <= 3) { return; } this.height = (Integer)_fields[3].getSchema().convert(_source[3]); - if(_source.length <= 4) { return; } this.size = (Integer)_fields[4].getSchema().convert(_source[4]); - } - - @Override - public void messageUnpack(Unpacker _pac) throws IOException, MessageTypeException { - int _length = _pac.unpackArray(); - if(_length <= 0) { return; } - this.uri = _pac.unpackString(); - if(_length <= 1) { return; } - this.title = _pac.unpackString(); - if(_length <= 2) { return; } - this.width = _pac.unpackInt(); - if(_length <= 3) { return; } - this.height = _pac.unpackInt(); - if(_length <= 4) { return; } - this.size = _pac.unpackInt(); - for(int _i=5; _i < _length; ++_i) { _pac.unpackObject(); } - } - - @SuppressWarnings("unchecked") - public static Image createFromMessage(Object[] _message) - { - Image _self = new Image(); - if(_message.length <= 0) { return _self; } _self.uri = (String)_message[0]; - if(_message.length <= 1) { return _self; } _self.title = (String)_message[1]; - if(_message.length <= 2) { return _self; } _self.width = (Integer)_message[2]; - if(_message.length <= 3) { return _self; } _self.height = (Integer)_message[3]; - if(_message.length <= 4) { return _self; } _self.size = (Integer)_message[4]; - return _self; - } -} - -final class Media implements MessagePackable, MessageConvertable, MessageUnpackable -{ - private static final ClassSchema _SCHEMA = (ClassSchema)Schema.load("(class Media (package serializers.msgpack) (field uri string) (field title string) (field width int) (field height int) (field format string) (field duration long) (field size long) (field bitrate int) (field person (array string)) (field player int) (field copyright string))"); - public static ClassSchema getSchema() { return _SCHEMA; } - - public String uri; - public String title; - public Integer width; - public Integer height; - public String format; - public Long duration; - public Long size; - public Integer bitrate; - public List person; - public Integer player; - public String copyright; - - public Media() { } - - @Override - public void messagePack(Packer _pk) throws IOException - { - _pk.packArray(11); - FieldSchema[] _fields = _SCHEMA.getFields(); - _fields[0].getSchema().pack(_pk, uri); - _fields[1].getSchema().pack(_pk, title); - _fields[2].getSchema().pack(_pk, width); - _fields[3].getSchema().pack(_pk, height); - _fields[4].getSchema().pack(_pk, format); - _fields[5].getSchema().pack(_pk, duration); - _fields[6].getSchema().pack(_pk, size); - _fields[7].getSchema().pack(_pk, bitrate); - _fields[8].getSchema().pack(_pk, person); - _fields[9].getSchema().pack(_pk, player); - _fields[10].getSchema().pack(_pk, copyright); - } - - @Override - @SuppressWarnings("unchecked") - public void messageConvert(Object obj) throws MessageTypeException - { - Object[] _source = ((List)obj).toArray(); - FieldSchema[] _fields = _SCHEMA.getFields(); - if(_source.length <= 0) { return; } this.uri = (String)_fields[0].getSchema().convert(_source[0]); - if(_source.length <= 1) { return; } this.title = (String)_fields[1].getSchema().convert(_source[1]); - if(_source.length <= 2) { return; } this.width = (Integer)_fields[2].getSchema().convert(_source[2]); - if(_source.length <= 3) { return; } this.height = (Integer)_fields[3].getSchema().convert(_source[3]); - if(_source.length <= 4) { return; } this.format = (String)_fields[4].getSchema().convert(_source[4]); - if(_source.length <= 5) { return; } this.duration = (Long)_fields[5].getSchema().convert(_source[5]); - if(_source.length <= 6) { return; } this.size = (Long)_fields[6].getSchema().convert(_source[6]); - if(_source.length <= 7) { return; } this.bitrate = (Integer)_fields[7].getSchema().convert(_source[7]); - if(_source.length <= 8) { return; } this.person = (List)_fields[8].getSchema().convert(_source[8]); - if(_source.length <= 9) { return; } this.player = (Integer)_fields[9].getSchema().convert(_source[9]); - if(_source.length <= 10) { return; } this.copyright = (String)_fields[10].getSchema().convert(_source[10]); - } - - @Override - public void messageUnpack(Unpacker _pac) throws IOException, MessageTypeException { - int _length = _pac.unpackArray(); - if(_length <= 0) { return; } - this.uri = _pac.unpackString(); - if(_length <= 1) { return; } - this.title = _pac.unpackString(); - if(_length <= 2) { return; } - this.width = _pac.unpackInt(); - if(_length <= 3) { return; } - this.height = _pac.unpackInt(); - if(_length <= 4) { return; } - this.format = _pac.unpackString(); - if(_length <= 5) { return; } - this.duration = _pac.unpackLong(); - if(_length <= 6) { return; } - this.size = _pac.unpackLong(); - if(_length <= 7) { return; } - this.bitrate = _pac.unpackInt(); - if(_length <= 8) { return; } - int _person_length = _pac.unpackArray(); - this.person = new ArrayList(_person_length); - for(int _i=0; _i < _person_length; ++_i) { - String _person_i = _pac.unpackString(); - this.person.add(_person_i); - } - if(_length <= 9) { return; } - this.player = _pac.unpackInt(); - if(_length <= 10) { return; } - this.copyright = _pac.unpackString(); - for(int _i=11; _i < _length; ++_i) { _pac.unpackObject(); } - } - - @SuppressWarnings("unchecked") - public static Media createFromMessage(Object[] _message) - { - Media _self = new Media(); - if(_message.length <= 0) { return _self; } _self.uri = (String)_message[0]; - if(_message.length <= 1) { return _self; } _self.title = (String)_message[1]; - if(_message.length <= 2) { return _self; } _self.width = (Integer)_message[2]; - if(_message.length <= 3) { return _self; } _self.height = (Integer)_message[3]; - if(_message.length <= 4) { return _self; } _self.format = (String)_message[4]; - if(_message.length <= 5) { return _self; } _self.duration = (Long)_message[5]; - if(_message.length <= 6) { return _self; } _self.size = (Long)_message[6]; - if(_message.length <= 7) { return _self; } _self.bitrate = (Integer)_message[7]; - if(_message.length <= 8) { return _self; } _self.person = (List)_message[8]; - if(_message.length <= 9) { return _self; } _self.player = (Integer)_message[9]; - if(_message.length <= 10) { return _self; } _self.copyright = (String)_message[10]; - return _self; - } -} - diff --git a/java/test/thrift-protobuf-compare/tpc/src/serializers/msgpack/MediaContent.mpacs b/java/test/thrift-protobuf-compare/tpc/src/serializers/msgpack/MediaContent.mpacs deleted file mode 100644 index 547ba48..0000000 --- a/java/test/thrift-protobuf-compare/tpc/src/serializers/msgpack/MediaContent.mpacs +++ /dev/null @@ -1,21 +0,0 @@ -(class MediaContent - (package serializers.msgpack) - (field image (array (class Image - (field uri string) - (field title string) - (field width int) - (field height int) - (field size int)))) - (field media (class Media - (field uri string) - (field title string) - (field width int) - (field height int) - (field format string) - (field duration long) - (field size long) - (field bitrate int) - (field person (array string)) - (field player int) - (field copyright string))) - ) diff --git a/java/test/thrift-protobuf-compare/tpc/src/serializers/msgpack/MessagePackDirectSerializer.java b/java/test/thrift-protobuf-compare/tpc/src/serializers/msgpack/MessagePackDirectSerializer.java deleted file mode 100644 index 25f932b..0000000 --- a/java/test/thrift-protobuf-compare/tpc/src/serializers/msgpack/MessagePackDirectSerializer.java +++ /dev/null @@ -1,68 +0,0 @@ -package serializers.msgpack; - -import java.io.*; -import java.util.*; -import org.msgpack.*; -import serializers.ObjectSerializer; - -public class MessagePackDirectSerializer implements ObjectSerializer -{ - public String getName() { - return "msgpack-direct"; - } - - public MediaContent create() throws Exception { - Media media = new Media(); - media.uri = "http://javaone.com/keynote.mpg"; - media.format = "video/mpg4"; - media.title = "Javaone Keynote"; - media.duration = 1234567L; - media.bitrate = 0; - media.person = new ArrayList(2); - media.person.add("Bill Gates"); - media.person.add("Steve Jobs"); - media.player = 0; - media.height = 0; - media.width = 0; - media.size = 123L; - media.copyright = ""; - - Image image1 = new Image(); - image1.uri = "http://javaone.com/keynote_large.jpg"; - image1.width = 0; - image1.height = 0; - image1.size = 2; - image1.title = "Javaone Keynote"; - - Image image2 = new Image(); - image2.uri = "http://javaone.com/keynote_thumbnail.jpg"; - image2.width = 0; - image2.height = 0; - image2.size = 1; - image2.title = "Javaone Keynote"; - - MediaContent content = new MediaContent(); - content.media = media; - content.image = new ArrayList(2); - content.image.add(image1); - content.image.add(image2); - - return content; - } - - public byte[] serialize(MediaContent content) throws Exception { - ByteArrayOutputStream os = new ByteArrayOutputStream(); - Packer pk = new Packer(os); - pk.pack(content); - return os.toByteArray(); - } - - public MediaContent deserialize(byte[] array) throws Exception { - Unpacker pac = new Unpacker(); - pac.wrap(array); - MediaContent obj = new MediaContent(); - obj.messageUnpack(pac); - return obj; - } -} - diff --git a/java/test/thrift-protobuf-compare/tpc/src/serializers/msgpack/MessagePackDynamicSerializer.java b/java/test/thrift-protobuf-compare/tpc/src/serializers/msgpack/MessagePackDynamicSerializer.java deleted file mode 100644 index 9c8ccbe..0000000 --- a/java/test/thrift-protobuf-compare/tpc/src/serializers/msgpack/MessagePackDynamicSerializer.java +++ /dev/null @@ -1,68 +0,0 @@ -package serializers.msgpack; - -import java.io.*; -import java.util.*; -import org.msgpack.*; -import serializers.ObjectSerializer; - -public class MessagePackDynamicSerializer implements ObjectSerializer -{ - public String getName() { - return "msgpack-dynamic"; - } - - public Object create() throws Exception { - ArrayList media = new ArrayList(11); - media.add("http://javaone.com/keynote.mpg"); - media.add("video/mpg4"); - media.add("Javaone Keynote"); - media.add(1234567L); - media.add(0); - ArrayList person = new ArrayList(2); - person.add("Bill Gates"); - person.add("Steve Jobs"); - media.add(person); - media.add(0); - media.add(0); - media.add(0); - media.add(123L); - media.add(""); - - ArrayList image1 = new ArrayList(5); - image1.add("http://javaone.com/keynote_large.jpg"); - image1.add(0); - image1.add(0); - image1.add(2); - image1.add("Javaone Keynote"); - - ArrayList image2 = new ArrayList(5); - image2.add("http://javaone.com/keynote_thumbnail.jpg"); - image2.add(0); - image2.add(0); - image2.add(1); - image2.add("Javaone Keynote"); - - ArrayList content = new ArrayList(2); - content.add(media); - ArrayList images = new ArrayList(2); - images.add(image1); - images.add(image2); - content.add(images); - - return content; - } - - public byte[] serialize(Object content) throws Exception { - ByteArrayOutputStream os = new ByteArrayOutputStream(); - Packer pk = new Packer(os); - pk.pack(content); - return os.toByteArray(); - } - - public Object deserialize(byte[] array) throws Exception { - Unpacker pac = new Unpacker(); - pac.execute(array); - return (Object)pac.getData(); - } -} - diff --git a/java/test/thrift-protobuf-compare/tpc/src/serializers/msgpack/MessagePackGenericSerializer.java b/java/test/thrift-protobuf-compare/tpc/src/serializers/msgpack/MessagePackGenericSerializer.java deleted file mode 100644 index 316389a..0000000 --- a/java/test/thrift-protobuf-compare/tpc/src/serializers/msgpack/MessagePackGenericSerializer.java +++ /dev/null @@ -1,70 +0,0 @@ -package serializers.msgpack; - -import java.io.*; -import java.util.*; -import org.msgpack.*; -import serializers.ObjectSerializer; - -public class MessagePackGenericSerializer implements ObjectSerializer -{ - private static final Schema MEDIA_CONTENT_SCHEMA = Schema.parse("(class MediaContent (package serializers.msgpack) (field image (array (class Image (package serializers.msgpack) (field uri string) (field title string) (field width int) (field height int) (field size int)))) (field media (class Media (package serializers.msgpack) (field uri string) (field title string) (field width int) (field height int) (field format string) (field duration long) (field size long) (field bitrate int) (field person (array string)) (field player int) (field copyright string))))"); - - public String getName() { - return "msgpack-generic"; - } - - public Object create() throws Exception { - HashMap media = new HashMap(11); - media.put("uri", "http://javaone.com/keynote.mpg"); - media.put("format", "video/mpg4"); - media.put("title", "Javaone Keynote"); - media.put("duration", 1234567L); - media.put("bitrate", 0); - ArrayList person = new ArrayList(2); - person.add("Bill Gates"); - person.add("Steve Jobs"); - media.put("person", person); - media.put("player", 0); - media.put("height", 0); - media.put("width", 0); - media.put("size", 123L); - media.put("copyright", ""); - - HashMap image1 = new HashMap(5); - image1.put("uri", "http://javaone.com/keynote_large.jpg"); - image1.put("width", 0); - image1.put("height", 0); - image1.put("size", 2); - image1.put("title", "Javaone Keynote"); - - HashMap image2 = new HashMap(5); - image2.put("uri", "http://javaone.com/keynote_thumbnail.jpg"); - image2.put("width", 0); - image2.put("height", 0); - image2.put("size", 1); - image2.put("title", "Javaone Keynote"); - - HashMap content = new HashMap(2); - content.put("media", media); - ArrayList images = new ArrayList(2); - images.add(image1); - images.add(image2); - content.put("image", images); - - return content; - } - - public byte[] serialize(Object content) throws Exception { - ByteArrayOutputStream os = new ByteArrayOutputStream(); - Packer pk = new Packer(os); - pk.packWithSchema(content, MEDIA_CONTENT_SCHEMA); - return os.toByteArray(); - } - - public Object deserialize(byte[] array) throws Exception { - Unpacker pac = new Unpacker().useSchema(MEDIA_CONTENT_SCHEMA); - pac.execute(array); - return (Object)pac.getData(); - } -} - diff --git a/java/test/thrift-protobuf-compare/tpc/src/serializers/msgpack/MessagePackIndirectSerializer.java b/java/test/thrift-protobuf-compare/tpc/src/serializers/msgpack/MessagePackIndirectSerializer.java deleted file mode 100644 index e24472b..0000000 --- a/java/test/thrift-protobuf-compare/tpc/src/serializers/msgpack/MessagePackIndirectSerializer.java +++ /dev/null @@ -1,67 +0,0 @@ -package serializers.msgpack; - -import java.io.*; -import java.util.*; -import org.msgpack.*; -import serializers.ObjectSerializer; - -public class MessagePackIndirectSerializer implements ObjectSerializer -{ - public String getName() { - return "msgpack-indirect"; - } - - public MediaContent create() throws Exception { - Media media = new Media(); - media.uri = "http://javaone.com/keynote.mpg"; - media.format = "video/mpg4"; - media.title = "Javaone Keynote"; - media.duration = 1234567L; - media.bitrate = 0; - media.person = new ArrayList(2); - media.person.add("Bill Gates"); - media.person.add("Steve Jobs"); - media.player = 0; - media.height = 0; - media.width = 0; - media.size = 123L; - media.copyright = ""; - - Image image1 = new Image(); - image1.uri = "http://javaone.com/keynote_large.jpg"; - image1.width = 0; - image1.height = 0; - image1.size = 2; - image1.title = "Javaone Keynote"; - - Image image2 = new Image(); - image2.uri = "http://javaone.com/keynote_thumbnail.jpg"; - image2.width = 0; - image2.height = 0; - image2.size = 1; - image2.title = "Javaone Keynote"; - - MediaContent content = new MediaContent(); - content.media = media; - content.image = new ArrayList(2); - content.image.add(image1); - content.image.add(image2); - - return content; - } - - public byte[] serialize(MediaContent content) throws Exception { - ByteArrayOutputStream os = new ByteArrayOutputStream(); - Packer pk = new Packer(os); - pk.pack(content); - return os.toByteArray(); - } - - public MediaContent deserialize(byte[] array) throws Exception { - Unpacker pac = new Unpacker(); - pac.execute(array); - Object obj = pac.getData(); - return (MediaContent)MediaContent.getSchema().convert(obj); - } -} - diff --git a/java/test/thrift-protobuf-compare/tpc/src/serializers/msgpack/MessagePackSpecificSerializer.java b/java/test/thrift-protobuf-compare/tpc/src/serializers/msgpack/MessagePackSpecificSerializer.java deleted file mode 100644 index 9b6a8ce..0000000 --- a/java/test/thrift-protobuf-compare/tpc/src/serializers/msgpack/MessagePackSpecificSerializer.java +++ /dev/null @@ -1,66 +0,0 @@ -package serializers.msgpack; - -import java.io.*; -import java.util.*; -import org.msgpack.*; -import serializers.ObjectSerializer; - -public class MessagePackSpecificSerializer implements ObjectSerializer -{ - public String getName() { - return "msgpack-specific"; - } - - public MediaContent create() throws Exception { - Media media = new Media(); - media.uri = "http://javaone.com/keynote.mpg"; - media.format = "video/mpg4"; - media.title = "Javaone Keynote"; - media.duration = 1234567L; - media.bitrate = 0; - media.person = new ArrayList(2); - media.person.add("Bill Gates"); - media.person.add("Steve Jobs"); - media.player = 0; - media.height = 0; - media.width = 0; - media.size = 123L; - media.copyright = ""; - - Image image1 = new Image(); - image1.uri = "http://javaone.com/keynote_large.jpg"; - image1.width = 0; - image1.height = 0; - image1.size = 2; - image1.title = "Javaone Keynote"; - - Image image2 = new Image(); - image2.uri = "http://javaone.com/keynote_thumbnail.jpg"; - image2.width = 0; - image2.height = 0; - image2.size = 1; - image2.title = "Javaone Keynote"; - - MediaContent content = new MediaContent(); - content.media = media; - content.image = new ArrayList(2); - content.image.add(image1); - content.image.add(image2); - - return content; - } - - public byte[] serialize(MediaContent content) throws Exception { - ByteArrayOutputStream os = new ByteArrayOutputStream(); - Packer pk = new Packer(os); - pk.pack(content); - return os.toByteArray(); - } - - public MediaContent deserialize(byte[] array) throws Exception { - Unpacker pac = new Unpacker().useSchema(MediaContent.getSchema()); - pac.execute(array); - return (MediaContent)pac.getData(); - } -} - diff --git a/msgpack/sysdep.h b/msgpack/sysdep.h index 2bc01c9..8b4ead7 100644 --- a/msgpack/sysdep.h +++ b/msgpack/sysdep.h @@ -18,8 +18,9 @@ #ifndef MSGPACK_SYSDEP_H__ #define MSGPACK_SYSDEP_H__ - -#ifdef _MSC_VER +#include +#include +#if defined(_MSC_VER) && _MSC_VER < 1600 typedef __int8 int8_t; typedef unsigned __int8 uint8_t; typedef __int16 int16_t; @@ -28,8 +29,9 @@ typedef __int32 int32_t; typedef unsigned __int32 uint32_t; typedef __int64 int64_t; typedef unsigned __int64 uint64_t; +#elif defined(_MSC_VER) // && _MSC_VER >= 1600 +#include #else -#include #include #include #endif @@ -76,7 +78,7 @@ typedef unsigned int _msgpack_atomic_counter_t; #define _msgpack_be16(x) ntohs(x) #define _msgpack_be32(x) ntohl(x) -#if defined(_byteswap_uint64) +#if defined(_byteswap_uint64) || _MSC_VER >= 1400 # define _msgpack_be64(x) (_byteswap_uint64(x)) #elif defined(bswap_64) # define _msgpack_be64(x) bswap_64(x) diff --git a/php/ChangeLog b/php/ChangeLog index 3eb64e7..83db491 100644 --- a/php/ChangeLog +++ b/php/ChangeLog @@ -1,5 +1,19 @@ msgpack extension changelog +Version 0.3.4 +------------- + * Support PHP 5.3.x version on Windows. + (note: NAN and Resource is failed) + +Version 0.3.3 +------------- + * Update msgpack header files. + * Fix unpack internal processing. + +Version 0.3.2 +------------- + * Version PHP 5 or newer. + Version 0.3.1 ------------- * Fix class MessagePackUnpacker. diff --git a/php/benchmark.php b/php/benchmark.php index 559801c..cd531a9 100644 --- a/php/benchmark.php +++ b/php/benchmark.php @@ -1,6 +1,4 @@ start(); + + $start = microtime(true); for ($i = 0; $i < $loop; $i++) { $pack = serialize($value); } - $t->setMarker('serialize'); + $end = microtime(true); + $serialize_pack += ($end - $start); + + $start = microtime(true); for ($i = 0; $i < $loop; $i++) { $unpack = unserialize($pack); } - $t->stop(); - //$t->display(); - $profiling = $t->getProfiling(); - unset($t); + $end = microtime(true); + $serialize_unpack += ($end - $start); - $serialize_pack += $profiling[1]['diff']; - $serialize_unpack += $profiling[2]['diff']; $serialize_size += strlen($pack); if ($unpack === $value || (is_object($value) && $unpack == $value)) @@ -120,24 +117,22 @@ foreach ($types as $type) { $opt = true; } - $t = new Benchmark_Timer; - $t->start(); + $start = microtime(true); for ($i = 0; $i < $loop; $i++) { $pack = json_encode($value); } - $t->setMarker('json_encode'); + $end = microtime(true); + $json_pack += ($end - $start); + + $start = microtime(true); for ($i = 0; $i < $loop; $i++) { $unpack = json_decode($pack, $opt); } - $t->stop(); - //$t->display(); - $profiling = $t->getProfiling(); - unset($t); + $end = microtime(true); + $json_unpack += ($end - $start); - $json_pack += $profiling[1]['diff']; - $json_unpack += $profiling[2]['diff']; $json_size += strlen($pack); if ($unpack === $value || (is_object($value) && $unpack == $value) || @@ -153,24 +148,22 @@ foreach ($types as $type) { $pack = null; $unpack = null; - $t = new Benchmark_Timer; - $t->start(); + $start = microtime(true); for ($i = 0; $i < $loop; $i++) { $pack = igbinary_serialize($value); } - $t->setMarker('igbinary_serialize'); + $end = microtime(true); + $igbinary_pack += ($end - $start); + + $start = microtime(true); for ($i = 0; $i < $loop; $i++) { $unpack = igbinary_unserialize($pack); } - $t->stop(); - //$t->display(); - $profiling = $t->getProfiling(); - unset($t); + $end = microtime(true); + $igbinary_unpack += ($end - $start); - $igbinary_pack += $profiling[1]['diff']; - $igbinary_unpack += $profiling[2]['diff']; $igbinary_size += strlen($pack); if ($unpack === $value || (is_object($value) && $unpack == $value)) @@ -182,24 +175,22 @@ foreach ($types as $type) //msgpack $pack = null; $unpack = null; - $t = new Benchmark_Timer; - $t->start(); + $start = microtime(true); for ($i = 0; $i < $loop; $i++) { $pack = msgpack_serialize($value); } - $t->setMarker('msgpack_serialize'); + $end = microtime(true); + $msgpack_pack += ($end - $start); + + $start = microtime(true); for ($i = 0; $i < $loop; $i++) { $unpack = msgpack_unserialize($pack); } - $t->stop(); - //$t->display(); - $profiling = $t->getProfiling(); - unset($t); + $end = microtime(true); + $msgpack_unpack += ($end - $start); - $msgpack_pack += $profiling[1]['diff']; - $msgpack_unpack += $profiling[2]['diff']; $msgpack_size += strlen($pack); if ($unpack === $value || (is_object($value) && $unpack == $value)) diff --git a/php/config.m4 b/php/config.m4 index a78e1f3..19df8af 100644 --- a/php/config.m4 +++ b/php/config.m4 @@ -8,12 +8,12 @@ dnl Check PHP version: AC_MSG_CHECKING(PHP version) AC_TRY_COMPILE([#include "php/main/php_version.h"], [ -#if PHP_MAJOR_VERSION < 5 || (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION < 2) -#error this extension requires at least PHP version 5.2.0 +#if PHP_MAJOR_VERSION < 5 +#error this extension requires at least PHP version 5 or newer #endif ], [AC_MSG_RESULT(ok)], -[AC_MSG_ERROR([need at least PHP 5.2.0])]) +[AC_MSG_ERROR([need at least PHP 5 or newer])]) dnl If your extension references something external, use with: @@ -24,5 +24,10 @@ Make sure that the comment is aligned: if test "$PHP_MSGPACK" != "no"; then PHP_NEW_EXTENSION(msgpack, msgpack.c msgpack_pack.c msgpack_unpack.c msgpack_class.c, $ext_shared) - PHP_INSTALL_HEADERS([ext/msgpack], [php_msgpack.h]) + ifdef([PHP_INSTALL_HEADERS], + [ + PHP_INSTALL_HEADERS([ext/msgpack], [php_msgpack.h]) + ], [ + PHP_ADD_MAKEFILE_FRAGMENT + ]) fi diff --git a/php/config.w32 b/php/config.w32 index 726b75f..59f5140 100644 --- a/php/config.w32 +++ b/php/config.w32 @@ -1,9 +1,9 @@ // $Id$ // vim:ft=javascript -// If your extension references something external, use ARG_WITH -// ARG_WITH("msgpack", "for msgpack support", "no"); +ARG_ENABLE("msgpack", "for msgpack support", "yes"); if (PHP_MSGPACK != "no") { - EXTENSION("msgpack", "msgpack.c msgpack_pack.c msgpack_unpack.c msgpack_class.c"); + EXTENSION("msgpack", "msgpack.c", PHP_MSGPACK_SHARED, ""); + ADD_SOURCES(configure_module_dirname, "msgpack_pack.c msgpack_unpack.c msgpack_class.c", "msgpack"); } diff --git a/php/msgpack.c b/php/msgpack.c index 3b375ba..0d48be1 100644 --- a/php/msgpack.c +++ b/php/msgpack.c @@ -77,6 +77,12 @@ static ZEND_MINIT_FUNCTION(msgpack) msgpack_init_class(); +#if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION < 1) + REGISTER_LONG_CONSTANT( + "MESSAGEPACK_OPT_PHPONLY", MSGPACK_CLASS_OPT_PHPONLY, + CONST_CS | CONST_PERSISTENT); +#endif + return SUCCESS; } @@ -164,33 +170,41 @@ PS_SERIALIZER_DECODE_FUNC(msgpack) msgpack_unserialize_var_init(&var_hash); - (&mp)->user.retval = (zval *)tmp; - (&mp)->user.var_hash = (php_unserialize_data_t *)&var_hash; + mp.user.retval = (zval *)tmp; + mp.user.var_hash = (php_unserialize_data_t *)&var_hash; ret = template_execute(&mp, (char *)val, (size_t)vallen, &off); - msgpack_unserialize_var_destroy(&var_hash); - - tmp_hash = HASH_OF(tmp); - - zend_hash_internal_pointer_reset_ex(tmp_hash, &tmp_hash_pos); - while (zend_hash_get_current_data_ex( - tmp_hash, (void *)&value, &tmp_hash_pos) == SUCCESS) + if (ret == MSGPACK_UNPACK_EXTRA_BYTES || ret == MSGPACK_UNPACK_SUCCESS) { - ret = zend_hash_get_current_key_ex( - tmp_hash, &key_str, &key_len, &key_long, 0, &tmp_hash_pos); - switch (ret) + msgpack_unserialize_var_destroy(&var_hash, 0); + + tmp_hash = HASH_OF(tmp); + + zend_hash_internal_pointer_reset_ex(tmp_hash, &tmp_hash_pos); + + while (zend_hash_get_current_data_ex( + tmp_hash, (void *)&value, &tmp_hash_pos) == SUCCESS) { - case HASH_KEY_IS_LONG: - /* ??? */ - break; - case HASH_KEY_IS_STRING: - php_set_session_var( - key_str, key_len - 1, *value, NULL TSRMLS_CC); - php_add_session_var(key_str, key_len - 1 TSRMLS_CC); - break; + ret = zend_hash_get_current_key_ex( + tmp_hash, &key_str, &key_len, &key_long, 0, &tmp_hash_pos); + switch (ret) + { + case HASH_KEY_IS_LONG: + /* ??? */ + break; + case HASH_KEY_IS_STRING: + php_set_session_var( + key_str, key_len - 1, *value, NULL TSRMLS_CC); + php_add_session_var(key_str, key_len - 1 TSRMLS_CC); + break; + } + zend_hash_move_forward_ex(tmp_hash, &tmp_hash_pos); } - zend_hash_move_forward_ex(tmp_hash, &tmp_hash_pos); + } + else + { + msgpack_unserialize_var_destroy(&var_hash, 1); } zval_ptr_dtor(&tmp); @@ -226,43 +240,49 @@ PHP_MSGPACK_API void php_msgpack_unserialize( msgpack_unserialize_var_init(&var_hash); - (&mp)->user.retval = (zval *)return_value; - (&mp)->user.var_hash = (php_unserialize_data_t *)&var_hash; + mp.user.retval = (zval *)return_value; + mp.user.var_hash = (php_unserialize_data_t *)&var_hash; ret = template_execute(&mp, str, (size_t)str_len, &off); - msgpack_unserialize_var_destroy(&var_hash); - switch (ret) { case MSGPACK_UNPACK_PARSE_ERROR: + { + msgpack_unserialize_var_destroy(&var_hash, 1); if (MSGPACK_G(error_display)) { zend_error(E_WARNING, - "[msgpack] (php_msgpack_unserialize) Parse error"); + "[msgpack] (%s) Parse error", __FUNCTION__); } break; + } case MSGPACK_UNPACK_CONTINUE: + { + msgpack_unserialize_var_destroy(&var_hash, 1); if (MSGPACK_G(error_display)) { zend_error(E_WARNING, - "[msgpack] (php_msgpack_unserialize) " - "Insufficient data for unserializing"); + "[msgpack] (%s) Insufficient data for unserializing", + __FUNCTION__); } break; + } case MSGPACK_UNPACK_EXTRA_BYTES: case MSGPACK_UNPACK_SUCCESS: + msgpack_unserialize_var_destroy(&var_hash, 0); if (off < (size_t)str_len && MSGPACK_G(error_display)) { zend_error(E_WARNING, - "[msgpack] (php_msgpack_unserialize) Extra bytes"); + "[msgpack] (%s) Extra bytes", __FUNCTION__); } break; default: + msgpack_unserialize_var_destroy(&var_hash, 0); if (MSGPACK_G(error_display)) { zend_error(E_WARNING, - "[msgpack] (php_msgpack_unserialize) Unknown result"); + "[msgpack] (%s) Unknown result", __FUNCTION__); } break; } diff --git a/php/msgpack/pack_template.h b/php/msgpack/pack_template.h index b636967..887a61b 100644 --- a/php/msgpack/pack_template.h +++ b/php/msgpack/pack_template.h @@ -69,7 +69,7 @@ do { \ } else { \ /* unsigned 16 */ \ unsigned char buf[3]; \ - buf[0] = 0xcd; _msgpack_store16(&buf[1], d); \ + buf[0] = 0xcd; _msgpack_store16(&buf[1], (uint16_t)d); \ msgpack_pack_append_buffer(x, buf, 3); \ } \ } while(0) @@ -89,12 +89,12 @@ do { \ if(d < (1<<16)) { \ /* unsigned 16 */ \ unsigned char buf[3]; \ - buf[0] = 0xcd; _msgpack_store16(&buf[1], d); \ + buf[0] = 0xcd; _msgpack_store16(&buf[1], (uint16_t)d); \ msgpack_pack_append_buffer(x, buf, 3); \ } else { \ /* unsigned 32 */ \ unsigned char buf[5]; \ - buf[0] = 0xce; _msgpack_store32(&buf[1], d); \ + buf[0] = 0xce; _msgpack_store32(&buf[1], (uint32_t)d); \ msgpack_pack_append_buffer(x, buf, 5); \ } \ } \ @@ -103,7 +103,7 @@ do { \ #define msgpack_pack_real_uint64(x, d) \ do { \ if(d < (1ULL<<8)) { \ - if(d < (1<<7)) { \ + if(d < (1ULL<<7)) { \ /* fixnum */ \ msgpack_pack_append_buffer(x, &TAKE8_64(d), 1); \ } else { \ @@ -115,12 +115,12 @@ do { \ if(d < (1ULL<<16)) { \ /* unsigned 16 */ \ unsigned char buf[3]; \ - buf[0] = 0xcd; _msgpack_store16(&buf[1], d); \ + buf[0] = 0xcd; _msgpack_store16(&buf[1], (uint16_t)d); \ msgpack_pack_append_buffer(x, buf, 3); \ } else if(d < (1ULL<<32)) { \ /* unsigned 32 */ \ unsigned char buf[5]; \ - buf[0] = 0xce; _msgpack_store32(&buf[1], d); \ + buf[0] = 0xce; _msgpack_store32(&buf[1], (uint32_t)d); \ msgpack_pack_append_buffer(x, buf, 5); \ } else { \ /* unsigned 64 */ \ @@ -149,7 +149,7 @@ do { \ if(d < -(1<<7)) { \ /* signed 16 */ \ unsigned char buf[3]; \ - buf[0] = 0xd1; _msgpack_store16(&buf[1], d); \ + buf[0] = 0xd1; _msgpack_store16(&buf[1], (int16_t)d); \ msgpack_pack_append_buffer(x, buf, 3); \ } else { \ /* signed 8 */ \ @@ -167,7 +167,7 @@ do { \ } else { \ /* unsigned 16 */ \ unsigned char buf[3]; \ - buf[0] = 0xcd; _msgpack_store16(&buf[1], d); \ + buf[0] = 0xcd; _msgpack_store16(&buf[1], (uint16_t)d); \ msgpack_pack_append_buffer(x, buf, 3); \ } \ } \ @@ -179,12 +179,12 @@ do { \ if(d < -(1<<15)) { \ /* signed 32 */ \ unsigned char buf[5]; \ - buf[0] = 0xd2; _msgpack_store32(&buf[1], d); \ + buf[0] = 0xd2; _msgpack_store32(&buf[1], (int32_t)d); \ msgpack_pack_append_buffer(x, buf, 5); \ } else if(d < -(1<<7)) { \ /* signed 16 */ \ unsigned char buf[3]; \ - buf[0] = 0xd1; _msgpack_store16(&buf[1], d); \ + buf[0] = 0xd1; _msgpack_store16(&buf[1], (int16_t)d); \ msgpack_pack_append_buffer(x, buf, 3); \ } else { \ /* signed 8 */ \ @@ -202,12 +202,12 @@ do { \ } else if(d < (1<<16)) { \ /* unsigned 16 */ \ unsigned char buf[3]; \ - buf[0] = 0xcd; _msgpack_store16(&buf[1], d); \ + buf[0] = 0xcd; _msgpack_store16(&buf[1], (uint16_t)d); \ msgpack_pack_append_buffer(x, buf, 3); \ } else { \ /* unsigned 32 */ \ unsigned char buf[5]; \ - buf[0] = 0xce; _msgpack_store32(&buf[1], d); \ + buf[0] = 0xce; _msgpack_store32(&buf[1], (uint32_t)d); \ msgpack_pack_append_buffer(x, buf, 5); \ } \ } \ @@ -225,14 +225,14 @@ do { \ } else { \ /* signed 32 */ \ unsigned char buf[5]; \ - buf[0] = 0xd2; _msgpack_store32(&buf[1], d); \ + buf[0] = 0xd2; _msgpack_store32(&buf[1], (int32_t)d); \ msgpack_pack_append_buffer(x, buf, 5); \ } \ } else { \ if(d < -(1<<7)) { \ /* signed 16 */ \ unsigned char buf[3]; \ - buf[0] = 0xd1; _msgpack_store16(&buf[1], d); \ + buf[0] = 0xd1; _msgpack_store16(&buf[1], (int16_t)d); \ msgpack_pack_append_buffer(x, buf, 3); \ } else { \ /* signed 8 */ \ @@ -252,14 +252,14 @@ do { \ } else { \ /* unsigned 16 */ \ unsigned char buf[3]; \ - buf[0] = 0xcd; _msgpack_store16(&buf[1], d); \ + buf[0] = 0xcd; _msgpack_store16(&buf[1], (uint16_t)d); \ msgpack_pack_append_buffer(x, buf, 3); \ } \ } else { \ if(d < (1LL<<32)) { \ /* unsigned 32 */ \ unsigned char buf[5]; \ - buf[0] = 0xce; _msgpack_store32(&buf[1], d); \ + buf[0] = 0xce; _msgpack_store32(&buf[1], (uint32_t)d); \ msgpack_pack_append_buffer(x, buf, 5); \ } else { \ /* unsigned 64 */ \ @@ -635,8 +635,8 @@ if(sizeof(unsigned long long) == 2) { msgpack_pack_inline_func(_float)(msgpack_pack_user x, float d) { union { float f; uint32_t i; } mem; - mem.f = d; unsigned char buf[5]; + mem.f = d; buf[0] = 0xca; _msgpack_store32(&buf[1], mem.i); msgpack_pack_append_buffer(x, buf, 5); } @@ -644,8 +644,8 @@ msgpack_pack_inline_func(_float)(msgpack_pack_user x, float d) msgpack_pack_inline_func(_double)(msgpack_pack_user x, double d) { union { double f; uint64_t i; } mem; - mem.f = d; unsigned char buf[9]; + mem.f = d; buf[0] = 0xcb; _msgpack_store64(&buf[1], mem.i); msgpack_pack_append_buffer(x, buf, 9); } @@ -690,11 +690,11 @@ msgpack_pack_inline_func(_array)(msgpack_pack_user x, unsigned int n) msgpack_pack_append_buffer(x, &d, 1); } else if(n < 65536) { unsigned char buf[3]; - buf[0] = 0xdc; _msgpack_store16(&buf[1], n); + buf[0] = 0xdc; _msgpack_store16(&buf[1], (uint16_t)n); msgpack_pack_append_buffer(x, buf, 3); } else { unsigned char buf[5]; - buf[0] = 0xdd; _msgpack_store32(&buf[1], n); + buf[0] = 0xdd; _msgpack_store32(&buf[1], (uint32_t)n); msgpack_pack_append_buffer(x, buf, 5); } } @@ -711,11 +711,11 @@ msgpack_pack_inline_func(_map)(msgpack_pack_user x, unsigned int n) msgpack_pack_append_buffer(x, &TAKE8_8(d), 1); } else if(n < 65536) { unsigned char buf[3]; - buf[0] = 0xde; _msgpack_store16(&buf[1], n); + buf[0] = 0xde; _msgpack_store16(&buf[1], (uint16_t)n); msgpack_pack_append_buffer(x, buf, 3); } else { unsigned char buf[5]; - buf[0] = 0xdf; _msgpack_store32(&buf[1], n); + buf[0] = 0xdf; _msgpack_store32(&buf[1], (uint32_t)n); msgpack_pack_append_buffer(x, buf, 5); } } @@ -732,11 +732,11 @@ msgpack_pack_inline_func(_raw)(msgpack_pack_user x, size_t l) msgpack_pack_append_buffer(x, &TAKE8_8(d), 1); } else if(l < 65536) { unsigned char buf[3]; - buf[0] = 0xda; _msgpack_store16(&buf[1], l); + buf[0] = 0xda; _msgpack_store16(&buf[1], (uint16_t)l); msgpack_pack_append_buffer(x, buf, 3); } else { unsigned char buf[5]; - buf[0] = 0xdb; _msgpack_store32(&buf[1], l); + buf[0] = 0xdb; _msgpack_store32(&buf[1], (uint32_t)l); msgpack_pack_append_buffer(x, buf, 5); } } diff --git a/php/msgpack/sysdep.h b/php/msgpack/sysdep.h index 2bc01c9..8b4ead7 100644 --- a/php/msgpack/sysdep.h +++ b/php/msgpack/sysdep.h @@ -18,8 +18,9 @@ #ifndef MSGPACK_SYSDEP_H__ #define MSGPACK_SYSDEP_H__ - -#ifdef _MSC_VER +#include +#include +#if defined(_MSC_VER) && _MSC_VER < 1600 typedef __int8 int8_t; typedef unsigned __int8 uint8_t; typedef __int16 int16_t; @@ -28,8 +29,9 @@ typedef __int32 int32_t; typedef unsigned __int32 uint32_t; typedef __int64 int64_t; typedef unsigned __int64 uint64_t; +#elif defined(_MSC_VER) // && _MSC_VER >= 1600 +#include #else -#include #include #include #endif @@ -76,7 +78,7 @@ typedef unsigned int _msgpack_atomic_counter_t; #define _msgpack_be16(x) ntohs(x) #define _msgpack_be32(x) ntohl(x) -#if defined(_byteswap_uint64) +#if defined(_byteswap_uint64) || _MSC_VER >= 1400 # define _msgpack_be64(x) (_byteswap_uint64(x)) #elif defined(bswap_64) # define _msgpack_be64(x) bswap_64(x) diff --git a/php/msgpack/unpack_template.h b/php/msgpack/unpack_template.h index 0fbfbb7..beed4c4 100644 --- a/php/msgpack/unpack_template.h +++ b/php/msgpack/unpack_template.h @@ -96,7 +96,9 @@ msgpack_unpack_func(msgpack_unpack_object, _data)(msgpack_unpack_struct(_context msgpack_unpack_func(int, _execute)(msgpack_unpack_struct(_context)* ctx, const char* data, size_t len, size_t* off) { +#ifndef _MSC_VER assert(len >= *off); +#endif const unsigned char* p = (unsigned char*)data + *off; const unsigned char* const pe = (unsigned char*)data + len; @@ -105,6 +107,9 @@ msgpack_unpack_func(int, _execute)(msgpack_unpack_struct(_context)* ctx, const c unsigned int trail = ctx->trail; unsigned int cs = ctx->cs; unsigned int top = ctx->top; + + int ret; + msgpack_unpack_struct(_stack)* stack = ctx->stack; /* unsigned int stack_size = ctx->stack_size; @@ -114,8 +119,6 @@ msgpack_unpack_func(int, _execute)(msgpack_unpack_struct(_context)* ctx, const c msgpack_unpack_object obj; msgpack_unpack_struct(_stack)* c = NULL; - int ret; - #define push_simple_value(func) \ if(msgpack_unpack_callback(func)(user, &obj) < 0) { goto _failed; } \ goto _push diff --git a/php/msgpack_class.c b/php/msgpack_class.c index ce008d9..903712d 100644 --- a/php/msgpack_class.c +++ b/php/msgpack_class.c @@ -20,6 +20,7 @@ typedef struct { php_unserialize_data_t var_hash; long php_only; zend_bool finished; + int error; } php_msgpack_unpacker_t; #if ZEND_MODULE_API_NO >= 20060613 @@ -40,16 +41,25 @@ typedef struct { # define POP_EO_PARAM() (void)zend_ptr_stack_pop(&EG(argument_stack)) #endif +#if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION > 0) #define MSGPACK_METHOD_HELPER(classname, name, retval, thisptr, num, param) \ PUSH_PARAM(param); PUSH_PARAM((void*)num); \ PUSH_EO_PARAM(); \ MSGPACK_METHOD_BASE(classname, name)(num, retval, NULL, thisptr, 0 TSRMLS_CC); \ POP_EO_PARAM(); \ - POP_PARAM(); \ - POP_PARAM(); - + POP_PARAM(); POP_PARAM(); #define MSGPACK_METHOD(classname, name, retval, thisptr) \ MSGPACK_METHOD_BASE(classname, name)(0, retval, NULL, thisptr, 0 TSRMLS_CC) +#else +#define MSGPACK_METHOD_HELPER(classname, name, retval, thisptr, num, param) \ + PUSH_PARAM(param); PUSH_PARAM((void*)num); \ + PUSH_EO_PARAM(); \ + MSGPACK_METHOD_BASE(classname, name)(num, retval, thisptr, 0 TSRMLS_CC); \ + POP_EO_PARAM(); \ + POP_PARAM(); POP_PARAM(); +#define MSGPACK_METHOD(classname, name, retval, thisptr) \ + MSGPACK_METHOD_BASE(classname, name)(0, retval, thisptr, 0 TSRMLS_CC) +#endif #define MSGPACK_METHOD1(classname, name, retval, thisptr, param1) \ MSGPACK_METHOD_HELPER(classname, name, retval, thisptr, 1, param1); @@ -62,8 +72,6 @@ typedef struct { php_msgpack_unpacker_t *unpacker; \ unpacker = (php_msgpack_unpacker_t *)zend_object_store_get_object(getThis() TSRMLS_CC); -#define MSGPACK_CLASS_OPT_PHPONLY -1001 - /* MessagePack */ static zend_class_entry *msgpack_ce = NULL; @@ -161,7 +169,15 @@ static const zend_function_entry msgpack_unpacker_methods[] = { static void php_msgpack_base_free(php_msgpack_base_t *base TSRMLS_DC) { +#if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION > 0) zend_object_std_dtor(&base->object TSRMLS_CC); +#else + if (base->object.properties) + { + zend_hash_destroy(base->object.properties); + FREE_HASHTABLE(base->object.properties); + } +#endif efree(base); } @@ -173,7 +189,13 @@ static zend_object_value php_msgpack_base_new(zend_class_entry *ce TSRMLS_DC) base = emalloc(sizeof(php_msgpack_base_t)); +#if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION > 0) zend_object_std_init(&base->object, ce TSRMLS_CC); +#else + ALLOC_HASHTABLE(base->object.properties); + zend_hash_init(base->object.properties, 0, NULL, ZVAL_PTR_DTOR, 0); + base->object.ce = ce; +#endif zend_hash_copy( base->object.properties, &ce->default_properties, @@ -191,7 +213,15 @@ static zend_object_value php_msgpack_base_new(zend_class_entry *ce TSRMLS_DC) static void php_msgpack_unpacker_free( php_msgpack_unpacker_t *unpacker TSRMLS_DC) { +#if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION > 0) zend_object_std_dtor(&unpacker->object TSRMLS_CC); +#else + if (unpacker->object.properties) + { + zend_hash_destroy(unpacker->object.properties); + FREE_HASHTABLE(unpacker->object.properties); + } +#endif efree(unpacker); } @@ -204,7 +234,13 @@ static zend_object_value php_msgpack_unpacker_new( unpacker = emalloc(sizeof(php_msgpack_unpacker_t)); +#if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION > 0) zend_object_std_init(&unpacker->object, ce TSRMLS_CC); +#else + ALLOC_HASHTABLE(unpacker->object.properties); + zend_hash_init(unpacker->object.properties, 0, NULL, ZVAL_PTR_DTOR, 0); + unpacker->object.ce = ce; +#endif zend_hash_copy( unpacker->object.properties, &ce->default_properties, @@ -222,7 +258,7 @@ static zend_object_value php_msgpack_unpacker_new( /* MessagePack */ static ZEND_METHOD(msgpack, __construct) { - bool php_only = MSGPACK_G(php_only); + zend_bool php_only = MSGPACK_G(php_only); MSGPACK_BASE_OBJECT; if (zend_parse_parameters( @@ -333,7 +369,7 @@ static ZEND_METHOD(msgpack, unpacker) /* MessagePackUnpacker */ static ZEND_METHOD(msgpack_unpacker, __construct) { - bool php_only = MSGPACK_G(php_only); + zend_bool php_only = MSGPACK_G(php_only); MSGPACK_UNPACKER_OBJECT; if (zend_parse_parameters( @@ -350,6 +386,7 @@ static ZEND_METHOD(msgpack_unpacker, __construct) unpacker->retval = NULL; unpacker->offset = 0; unpacker->finished = 0; + unpacker->error = 0; template_init(&unpacker->mp); @@ -370,7 +407,7 @@ static ZEND_METHOD(msgpack_unpacker, __destruct) zval_ptr_dtor(&unpacker->retval); } - msgpack_unserialize_var_destroy(&unpacker->var_hash); + msgpack_unserialize_var_destroy(&unpacker->var_hash, unpacker->error); } static ZEND_METHOD(msgpack_unpacker, setOption) @@ -447,6 +484,17 @@ static ZEND_METHOD(msgpack_unpacker, execute) if (str != NULL) { + if (ZEND_NUM_ARGS() < 2) + { + if (MSGPACK_G(error_display)) + { + zend_error(E_WARNING, + "[msgpack] (MessagePackUnpacker::execute) " + "expects exactly 2 parameters"); + } + RETURN_FALSE; + } + data = (char *)str; len = (size_t)str_len; off = Z_LVAL_P(offset); @@ -466,8 +514,8 @@ static ZEND_METHOD(msgpack_unpacker, execute) { zval_ptr_dtor(&unpacker->retval); - msgpack_unserialize_var_destroy(&unpacker->var_hash); - + msgpack_unserialize_var_destroy(&unpacker->var_hash, unpacker->error); + unpacker->error = 0; ALLOC_INIT_ZVAL(unpacker->retval); @@ -502,8 +550,10 @@ static ZEND_METHOD(msgpack_unpacker, execute) case MSGPACK_UNPACK_EXTRA_BYTES: case MSGPACK_UNPACK_SUCCESS: unpacker->finished = 1; + unpacker->error = 0; RETURN_TRUE; default: + unpacker->error = 1; RETURN_FALSE; } } @@ -556,7 +606,8 @@ static ZEND_METHOD(msgpack_unpacker, reset) unpacker->retval = NULL; } - msgpack_unserialize_var_destroy(&unpacker->var_hash); + msgpack_unserialize_var_destroy(&unpacker->var_hash, unpacker->error); + unpacker->error = 0; template_init(&unpacker->mp); @@ -577,9 +628,11 @@ void msgpack_init_class() msgpack_ce = zend_register_internal_class(&ce TSRMLS_CC); msgpack_ce->create_object = php_msgpack_base_new; +#if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION > 0) zend_declare_class_constant_long( msgpack_ce, ZEND_STRS("OPT_PHPONLY") - 1, MSGPACK_CLASS_OPT_PHPONLY TSRMLS_CC); +#endif /* unpacker */ INIT_CLASS_ENTRY(ce, "MessagePackUnpacker", msgpack_unpacker_methods); diff --git a/php/msgpack_class.h b/php/msgpack_class.h index fbebaf4..f197523 100644 --- a/php/msgpack_class.h +++ b/php/msgpack_class.h @@ -2,6 +2,8 @@ #ifndef MSGPACK_CLASS_H #define MSGPACK_CLASS_H +#define MSGPACK_CLASS_OPT_PHPONLY -1001 + void msgpack_init_class(); #endif diff --git a/php/msgpack_pack.c b/php/msgpack_pack.c index d2d4ba3..36a1ade 100644 --- a/php/msgpack_pack.c +++ b/php/msgpack_pack.c @@ -38,11 +38,15 @@ inline static int msgpack_var_add( + (long)Z_OBJ_HANDLE_P(var)); len = id + sizeof(id) - 1 - p; } - else + else if (Z_TYPE_P(var) == IS_ARRAY) { p = smart_str_print_long(id + sizeof(id) - 1, (long)var); len = id + sizeof(id) - 1 - p; } + else + { + return FAILURE; + } if (var_old && zend_hash_find(var_hash, p, len, var_old) == SUCCESS) { @@ -122,10 +126,11 @@ inline static void msgpack_serialize_class( if (MSGPACK_G(error_display)) { zend_error(E_NOTICE, - "[msgpack] (msgpack_serialize_class) " + "[msgpack] (%s) " "__sleep should return an array only " "containing the names of " - "instance-variables to serialize."); + "instance-variables to serialize.", + __FUNCTION__); } continue; } @@ -199,10 +204,10 @@ inline static void msgpack_serialize_class( if (MSGPACK_G(error_display)) { zend_error(E_NOTICE, - "[msgpack] (msgpack_serialize_class) " + "[msgpack] (%s) " "\"%s\" returned as member variable from " "__sleep() but does not exist", - Z_STRVAL_PP(name)); + __FUNCTION__, Z_STRVAL_PP(name)); } msgpack_serialize_string( @@ -226,12 +231,12 @@ inline static void msgpack_serialize_class( } inline static void msgpack_serialize_array( - smart_str *buf, zval *val, HashTable *var_hash, bool object, + smart_str *buf, zval *val, HashTable *var_hash, zend_bool object, char* class_name, zend_uint name_len, zend_bool incomplete_class TSRMLS_DC) { HashTable *ht; size_t n; - bool hash = true; + zend_bool hash = 1; if (object) { @@ -278,12 +283,12 @@ inline static void msgpack_serialize_array( else { msgpack_pack_array(buf, n); - hash = false; + hash = 0; } } else if (n == 0) { - hash = false; + hash = 0; msgpack_pack_array(buf, n); } else @@ -339,8 +344,9 @@ inline static void msgpack_serialize_array( if (MSGPACK_G(error_display)) { zend_error(E_WARNING, - "[msgpack] (msgpack_serialize_array) " - "key is not string nor array"); + "[msgpack] (%s) " + "key is not string nor array", + __FUNCTION__); } break; } @@ -386,6 +392,7 @@ inline static void msgpack_serialize_object( ce = Z_OBJCE_P(val); } +#if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION > 0) if (ce && ce->serialize != NULL) { unsigned char *serialized_data = NULL; @@ -418,6 +425,7 @@ inline static void msgpack_serialize_object( return; } +#endif if (ce && ce != PHP_IC_ENTRY && zend_hash_exists(&ce->function_table, "__sleep", sizeof("__sleep"))) @@ -441,10 +449,11 @@ inline static void msgpack_serialize_object( if (MSGPACK_G(error_display)) { zend_error(E_NOTICE, - "[msgpack] (msgpack_serialize_object) " + "[msgpack] (%s) " "__sleep should return an array only " "containing the names of instance-variables " - "to serialize"); + "to serialize", + __FUNCTION__); } msgpack_pack_nil(buf); } @@ -460,7 +469,7 @@ inline static void msgpack_serialize_object( } msgpack_serialize_array( - buf, val, var_hash, true, + buf, val, var_hash, 1, class_name, name_len, incomplete_class TSRMLS_CC); } @@ -530,7 +539,7 @@ void msgpack_serialize_zval( break; case IS_ARRAY: msgpack_serialize_array( - buf, val, var_hash, false, NULL, 0, 0 TSRMLS_CC); + buf, val, var_hash, 0, NULL, 0, 0 TSRMLS_CC); break; case IS_OBJECT: { @@ -548,8 +557,8 @@ void msgpack_serialize_zval( if (MSGPACK_G(error_display)) { zend_error(E_WARNING, - "[msgpack] (php_msgpack_serialize) " - "type is unsupported, encoded as null"); + "[msgpack] (%s) type is unsupported, encoded as null", + __FUNCTION__); } msgpack_pack_nil(buf); break; diff --git a/php/msgpack_unpack.c b/php/msgpack_unpack.c index f3b610d..3c8e6ee 100644 --- a/php/msgpack_unpack.c +++ b/php/msgpack_unpack.c @@ -19,52 +19,41 @@ typedef struct { zval *data[VAR_ENTRIES_MAX]; long used_slots; - long value_slots; - long access_slots[VAR_ENTRIES_MAX]; - bool alloc_slots[VAR_ENTRIES_MAX]; void *next; } var_entries; -#define MSGPACK_UNSERIALIZE_ALLOC(_unpack) \ - if (_unpack->deps <= 0) { \ - *obj = _unpack->retval; \ - msgpack_var_push(_unpack->var_hash, obj, true, false); \ - } else { \ - ALLOC_INIT_ZVAL(*obj); \ - msgpack_var_push(_unpack->var_hash, obj, false, true); \ +#define MSGPACK_UNSERIALIZE_ALLOC_STACK(_unpack) \ + if (_unpack->deps <= 0) { \ + *obj = _unpack->retval; \ + msgpack_stack_push(_unpack->var_hash, obj, 0); \ + } else { \ + ALLOC_INIT_ZVAL(*obj); \ + msgpack_stack_push(_unpack->var_hash, obj, 1); \ } -#define MSGPACK_UNSERIALIZE_ALLOC_VALUE(_unpack) \ - if (_unpack->deps <= 0) { \ - *obj = _unpack->retval; \ - msgpack_var_push(_unpack->var_hash, obj, true, false); \ - } else { \ - ALLOC_INIT_ZVAL(*obj); \ - msgpack_var_push(_unpack->var_hash, obj, true, true); \ +#define MSGPACK_UNSERIALIZE_ALLOC_VALUE(_unpack) \ + if (_unpack->deps <= 0) { \ + *obj = _unpack->retval; \ + msgpack_var_push(_unpack->var_hash, obj); \ + } else { \ + ALLOC_INIT_ZVAL(*obj); \ + msgpack_var_push(_unpack->var_hash, obj); \ } -#define MSGPACK_UNSERIALIZE_PUSH_ITEM(_unpack, _count, _val) \ - msgpack_var_alloc(_unpack->var_hash, _count); \ - if (Z_TYPE_P(_val) != IS_ARRAY && Z_TYPE_P(_val) != IS_OBJECT) { \ - msgpack_var_push(_unpack->var_hash, &_val, true, false); \ - } - -#define MSGPACK_UNSERIALIZE_FINISH_ITEM(_unpack) \ - long deps = _unpack->deps - 1; \ - _unpack->stack[deps]--; \ - if (_unpack->stack[deps] == 0) { \ - _unpack->deps--; \ +#define MSGPACK_UNSERIALIZE_FINISH_ITEM(_unpack, _count) \ + msgpack_stack_pop(_unpack->var_hash, _count); \ + _unpack->stack[_unpack->deps-1]--; \ + if (_unpack->stack[_unpack->deps-1] == 0) { \ + _unpack->deps--; \ } #define MSGPACK_UNSERIALIZE_FINISH_MAP_ITEM(_unpack, _key, _val) \ zval_ptr_dtor(&_key); \ zval_ptr_dtor(&_val); \ - msgpack_var_alloc(_unpack->var_hash, 2); \ - MSGPACK_UNSERIALIZE_FINISH_ITEM(_unpack); - + MSGPACK_UNSERIALIZE_FINISH_ITEM(_unpack, 2); inline static void msgpack_var_push( - php_unserialize_data_t *var_hashx, zval **rval, bool value, bool alloc) + php_unserialize_data_t *var_hashx, zval **rval) { var_entries *var_hash, *prev = NULL; @@ -85,7 +74,6 @@ inline static void msgpack_var_push( { var_hash = emalloc(sizeof(var_entries)); var_hash->used_slots = 0; - var_hash->value_slots = 0; var_hash->next = 0; if (!var_hashx->first) @@ -98,45 +86,9 @@ inline static void msgpack_var_push( } } - var_hash->alloc_slots[var_hash->used_slots] = alloc; - - if (value) - { - var_hash->access_slots[var_hash->value_slots++] = var_hash->used_slots; - } - var_hash->data[var_hash->used_slots++] = *rval; } -inline static void msgpack_var_alloc( - php_unserialize_data_t *var_hashx, long count) -{ - long i; - var_entries *var_hash = var_hashx->first; - - while (var_hash && var_hash->used_slots == VAR_ENTRIES_MAX) - { - var_hash = var_hash->next; - } - - if (!var_hash || count <= 0) - { - return; - } - - for (i = var_hash->used_slots - 1; i >= 0; i--) - { - if (var_hash->alloc_slots[i]) - { - var_hash->alloc_slots[i] = false; - if (--count <= 0) - { - break; - } - } - } -} - inline static int msgpack_var_access( php_unserialize_data_t *var_hashx, long id, zval ***store) { @@ -154,13 +106,6 @@ inline static int msgpack_var_access( return !SUCCESS; } - if (id < 0 || id >= var_hash->value_slots) - { - return !SUCCESS; - } - - id = var_hash->access_slots[id]; - if (id < 0 || id >= var_hash->used_slots) { return !SUCCESS; @@ -171,11 +116,87 @@ inline static int msgpack_var_access( return SUCCESS; } +inline static void msgpack_stack_push( + php_unserialize_data_t *var_hashx, zval **rval, zend_bool save) +{ + var_entries *var_hash, *prev = NULL; + + if (!var_hashx) + { + return; + } + + var_hash = var_hashx->first_dtor; + + while (var_hash && var_hash->used_slots == VAR_ENTRIES_MAX) + { + prev = var_hash; + var_hash = var_hash->next; + } + + if (!var_hash) + { + var_hash = emalloc(sizeof(var_entries)); + var_hash->used_slots = 0; + var_hash->next = 0; + + if (!var_hashx->first_dtor) + { + var_hashx->first_dtor = var_hash; + } + else + { + prev->next = var_hash; + } + } + + if (save) + { + var_hash->data[var_hash->used_slots++] = *rval; + } + else + { + var_hash->data[var_hash->used_slots++] = NULL; + } +} + +inline static void msgpack_stack_pop( + php_unserialize_data_t *var_hashx, long count) +{ + long i; + var_entries *var_hash = var_hashx->first_dtor; + + while (var_hash && var_hash->used_slots == VAR_ENTRIES_MAX) + { + var_hash = var_hash->next; + } + + if (!var_hash || count <= 0) + { + return; + } + + for (i = count; i > 0; i--) + { + var_hash->used_slots--; + if (var_hash->used_slots < 0) + { + var_hash->used_slots = 0; + var_hash->data[var_hash->used_slots] = NULL; + break; + } + else + { + var_hash->data[var_hash->used_slots] = NULL; + } + } +} + inline static zend_class_entry* msgpack_unserialize_class( zval **container, char *class_name, size_t name_len) { zend_class_entry *ce, **pce; - bool incomplete_class = false; + zend_bool incomplete_class = 0; zval *user_func, *retval_ptr, **args[1], *arg_func_name; TSRMLS_FETCH(); @@ -210,8 +231,8 @@ inline static zend_class_entry* msgpack_unserialize_class( if (MSGPACK_G(error_display)) { zend_error(E_WARNING, - "[msgpack] (msgpack_unserialize_class) " - "defined (%s) but not found", class_name); + "[msgpack] (%s) defined (%s) but not found", + __FUNCTION__, class_name); } incomplete_class = 1; @@ -235,12 +256,12 @@ inline static zend_class_entry* msgpack_unserialize_class( if (MSGPACK_G(error_display)) { zend_error(E_WARNING, - "[msgpack] (msgpack_unserialize_class) " + "[msgpack] (%s) " "Function %s() hasn't defined the class " - "it was called for", class_name); + "it was called for", __FUNCTION__, class_name); } - incomplete_class = true; + incomplete_class = 1; ce = PHP_IC_ENTRY; } @@ -254,8 +275,7 @@ inline static zend_class_entry* msgpack_unserialize_class( if (MSGPACK_G(error_display)) { zend_error(E_WARNING, - "[msgpack] (msgpack_unserialize_class) " - "Exception error"); + "[msgpack] (%s) Exception error", __FUNCTION__); } return NULL; @@ -278,7 +298,8 @@ void msgpack_unserialize_var_init(php_unserialize_data_t *var_hashx) var_hashx->first_dtor = 0; } -void msgpack_unserialize_var_destroy(php_unserialize_data_t *var_hashx) +void msgpack_unserialize_var_destroy( + php_unserialize_data_t *var_hashx, zend_bool err) { void *next; long i; @@ -286,9 +307,29 @@ void msgpack_unserialize_var_destroy(php_unserialize_data_t *var_hashx) while (var_hash) { - for (i = 0; i < var_hash->used_slots; i++) + if (err) { - if (var_hash->alloc_slots[i] && var_hash->data[i]) + for (i = var_hash->used_slots - 1; i > 0; i--) + { + if (var_hash->data[i]) + { + zval_ptr_dtor(&var_hash->data[i]); + } + } + } + + next = var_hash->next; + efree(var_hash); + var_hash = next; + } + + var_hash = var_hashx->first_dtor; + + while (var_hash) + { + for (i = var_hash->used_slots - 1; i >= 0; i--) + { + if (var_hash->data[i]) { zval_ptr_dtor(&var_hash->data[i]); } @@ -298,21 +339,6 @@ void msgpack_unserialize_var_destroy(php_unserialize_data_t *var_hashx) efree(var_hash); var_hash = next; } - - /* - var_hash = var_hashx->first_dtor; - - while (var_hash) - { - for (i = 0; i < var_hash->used_slots; i++) - { - zval_ptr_dtor(&var_hash->data[i]); - } - next = var_hash->next; - efree(var_hash); - var_hash = next; - } - */ } void msgpack_unserialize_init(msgpack_unserialize_data *unpack) @@ -324,7 +350,7 @@ void msgpack_unserialize_init(msgpack_unserialize_data *unpack) int msgpack_unserialize_uint8( msgpack_unserialize_data *unpack, uint8_t data, zval **obj) { - MSGPACK_UNSERIALIZE_ALLOC(unpack); + MSGPACK_UNSERIALIZE_ALLOC_STACK(unpack); ZVAL_LONG(*obj, data); @@ -334,7 +360,7 @@ int msgpack_unserialize_uint8( int msgpack_unserialize_uint16( msgpack_unserialize_data *unpack, uint16_t data, zval **obj) { - MSGPACK_UNSERIALIZE_ALLOC(unpack); + MSGPACK_UNSERIALIZE_ALLOC_STACK(unpack); ZVAL_LONG(*obj, data); @@ -344,7 +370,7 @@ int msgpack_unserialize_uint16( int msgpack_unserialize_uint32( msgpack_unserialize_data *unpack, uint32_t data, zval **obj) { - MSGPACK_UNSERIALIZE_ALLOC(unpack); + MSGPACK_UNSERIALIZE_ALLOC_STACK(unpack); ZVAL_LONG(*obj, data); @@ -354,7 +380,7 @@ int msgpack_unserialize_uint32( int msgpack_unserialize_uint64( msgpack_unserialize_data *unpack, uint64_t data, zval **obj) { - MSGPACK_UNSERIALIZE_ALLOC(unpack); + MSGPACK_UNSERIALIZE_ALLOC_STACK(unpack); ZVAL_LONG(*obj, data); @@ -364,7 +390,7 @@ int msgpack_unserialize_uint64( int msgpack_unserialize_int8( msgpack_unserialize_data *unpack, int8_t data, zval **obj) { - MSGPACK_UNSERIALIZE_ALLOC(unpack); + MSGPACK_UNSERIALIZE_ALLOC_STACK(unpack); ZVAL_LONG(*obj, data); @@ -374,7 +400,7 @@ int msgpack_unserialize_int8( int msgpack_unserialize_int16( msgpack_unserialize_data *unpack, int16_t data, zval **obj) { - MSGPACK_UNSERIALIZE_ALLOC(unpack); + MSGPACK_UNSERIALIZE_ALLOC_STACK(unpack); ZVAL_LONG(*obj, data); @@ -384,7 +410,7 @@ int msgpack_unserialize_int16( int msgpack_unserialize_int32( msgpack_unserialize_data *unpack, int32_t data, zval **obj) { - MSGPACK_UNSERIALIZE_ALLOC(unpack); + MSGPACK_UNSERIALIZE_ALLOC_STACK(unpack); ZVAL_LONG(*obj, data); @@ -394,7 +420,7 @@ int msgpack_unserialize_int32( int msgpack_unserialize_int64( msgpack_unserialize_data *unpack, int64_t data, zval **obj) { - MSGPACK_UNSERIALIZE_ALLOC(unpack); + MSGPACK_UNSERIALIZE_ALLOC_STACK(unpack); ZVAL_LONG(*obj, data); @@ -404,7 +430,7 @@ int msgpack_unserialize_int64( int msgpack_unserialize_float( msgpack_unserialize_data *unpack, float data, zval **obj) { - MSGPACK_UNSERIALIZE_ALLOC(unpack); + MSGPACK_UNSERIALIZE_ALLOC_STACK(unpack); ZVAL_DOUBLE(*obj, data); @@ -414,7 +440,7 @@ int msgpack_unserialize_float( int msgpack_unserialize_double( msgpack_unserialize_data *unpack, double data, zval **obj) { - MSGPACK_UNSERIALIZE_ALLOC(unpack); + MSGPACK_UNSERIALIZE_ALLOC_STACK(unpack); ZVAL_DOUBLE(*obj, data); @@ -423,7 +449,7 @@ int msgpack_unserialize_double( int msgpack_unserialize_nil(msgpack_unserialize_data *unpack, zval **obj) { - MSGPACK_UNSERIALIZE_ALLOC(unpack); + MSGPACK_UNSERIALIZE_ALLOC_STACK(unpack); ZVAL_NULL(*obj); @@ -432,7 +458,7 @@ int msgpack_unserialize_nil(msgpack_unserialize_data *unpack, zval **obj) int msgpack_unserialize_true(msgpack_unserialize_data *unpack, zval **obj) { - MSGPACK_UNSERIALIZE_ALLOC(unpack); + MSGPACK_UNSERIALIZE_ALLOC_STACK(unpack); ZVAL_BOOL(*obj, 1); @@ -441,7 +467,7 @@ int msgpack_unserialize_true(msgpack_unserialize_data *unpack, zval **obj) int msgpack_unserialize_false(msgpack_unserialize_data *unpack, zval **obj) { - MSGPACK_UNSERIALIZE_ALLOC(unpack); + MSGPACK_UNSERIALIZE_ALLOC_STACK(unpack); ZVAL_BOOL(*obj, 0); @@ -452,7 +478,7 @@ int msgpack_unserialize_raw( msgpack_unserialize_data *unpack, const char* base, const char* data, unsigned int len, zval **obj) { - MSGPACK_UNSERIALIZE_ALLOC(unpack); + MSGPACK_UNSERIALIZE_ALLOC_STACK(unpack); if (len == 0) { @@ -481,11 +507,9 @@ int msgpack_unserialize_array( int msgpack_unserialize_array_item( msgpack_unserialize_data *unpack, zval **container, zval *obj) { - MSGPACK_UNSERIALIZE_PUSH_ITEM(unpack, 1, obj); - add_next_index_zval(*container, obj); - MSGPACK_UNSERIALIZE_FINISH_ITEM(unpack); + MSGPACK_UNSERIALIZE_FINISH_ITEM(unpack, 1); return 0; } @@ -505,10 +529,12 @@ int msgpack_unserialize_map( int msgpack_unserialize_map_item( msgpack_unserialize_data *unpack, zval **container, zval *key, zval *val) { + long deps; TSRMLS_FETCH(); if (MSGPACK_G(php_only)) { + zend_class_entry *ce; if (Z_TYPE_P(key) == IS_NULL) { unpack->type = MSGPACK_SERIALIZE_TYPE_NONE; @@ -532,7 +558,7 @@ int msgpack_unserialize_map_item( } else if (Z_TYPE_P(val) == IS_STRING) { - zend_class_entry *ce = msgpack_unserialize_class( + ce = msgpack_unserialize_class( container, Z_STRVAL_P(val), Z_STRLEN_P(val)); if (ce == NULL) @@ -551,7 +577,7 @@ int msgpack_unserialize_map_item( { unpack->type = MSGPACK_SERIALIZE_TYPE_NONE; - zend_class_entry *ce = msgpack_unserialize_class( + ce = msgpack_unserialize_class( container, Z_STRVAL_P(key), Z_STRLEN_P(key)); if (ce == NULL) @@ -561,14 +587,15 @@ int msgpack_unserialize_map_item( return 0; } +#if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION > 0) /* implementing Serializable */ if (ce->unserialize == NULL) { if (MSGPACK_G(error_display)) { zend_error(E_WARNING, - "[msgpack] (msgpack_unserialize_map_item) " - "Class %s has no unserializer", ce->name); + "[msgpack] (%s) Class %s has no unserializer", + __FUNCTION__, ce->name); } MSGPACK_UNSERIALIZE_FINISH_MAP_ITEM(unpack, key, val); @@ -580,6 +607,7 @@ int msgpack_unserialize_map_item( container, ce, (const unsigned char *)Z_STRVAL_P(val), Z_STRLEN_P(val) + 1, NULL TSRMLS_CC); +#endif MSGPACK_UNSERIALIZE_FINISH_MAP_ITEM(unpack, key, val); @@ -590,16 +618,14 @@ int msgpack_unserialize_map_item( zval **rval; unpack->type = MSGPACK_SERIALIZE_TYPE_NONE; - if (msgpack_var_access( unpack->var_hash, Z_LVAL_P(val) - 1, &rval) != SUCCESS) { if (MSGPACK_G(error_display)) { zend_error(E_WARNING, - "[msgpack] (msgpack_unserialize_map_item) " - "Invalid references value: %ld", - Z_LVAL_P(val) - 1); + "[msgpack] (%s) Invalid references value: %ld", + __FUNCTION__, Z_LVAL_P(val) - 1); } MSGPACK_UNSERIALIZE_FINISH_MAP_ITEM(unpack, key, val); @@ -622,8 +648,6 @@ int msgpack_unserialize_map_item( } } - MSGPACK_UNSERIALIZE_PUSH_ITEM(unpack, 2, val); - if (Z_TYPE_PP(container) != IS_ARRAY && Z_TYPE_PP(container) != IS_OBJECT) { array_init(*container); @@ -640,8 +664,9 @@ int msgpack_unserialize_map_item( if (MSGPACK_G(error_display)) { zend_error(E_WARNING, - "[msgpack] (msgpack_unserialize_map_item) " - "illegal offset type, skip this decoding"); + "[msgpack] (%s) " + "illegal offset type, skip this decoding", + __FUNCTION__); } } break; @@ -654,8 +679,9 @@ int msgpack_unserialize_map_item( if (MSGPACK_G(error_display)) { zend_error(E_WARNING, - "[msgpack] (msgpack_unserialize_map_item) " - "illegal offset type, skip this decoding"); + "[msgpack] (%s) " + "illegal offset type, skip this decoding", + __FUNCTION__); } } break; @@ -664,15 +690,17 @@ int msgpack_unserialize_map_item( if (MSGPACK_G(error_display)) { zend_error(E_WARNING, - "[msgpack] (msgpack_unserialize_map_item) " - "illegal offset type, skip this decoding"); + "[msgpack] (%s) " + "illegal offset type, skip this decoding", + __FUNCTION__); } break; } zval_ptr_dtor(&key); + msgpack_stack_pop(unpack->var_hash, 2); - long deps = unpack->deps - 1; + deps = unpack->deps - 1; unpack->stack[deps]--; if (unpack->stack[deps] == 0) { diff --git a/php/msgpack_unpack.h b/php/msgpack_unpack.h index da963eb..1f7b05e 100644 --- a/php/msgpack_unpack.h +++ b/php/msgpack_unpack.h @@ -25,7 +25,8 @@ typedef struct { } msgpack_unserialize_data; void msgpack_unserialize_var_init(php_unserialize_data_t *var_hashx); -void msgpack_unserialize_var_destroy(php_unserialize_data_t *var_hashx); +void msgpack_unserialize_var_destroy( + php_unserialize_data_t *var_hashx, zend_bool err); void msgpack_unserialize_init(msgpack_unserialize_data *unpack); diff --git a/php/package.xml b/php/package.xml index 803aa97..31a480b 100644 --- a/php/package.xml +++ b/php/package.xml @@ -10,11 +10,11 @@ advect@gmail.com yes - 2010-10-26 - + 2010-12-28 + - 0.3.1 - 0.3.1 + 0.3.4 + 0.3.4 beta @@ -26,20 +26,24 @@ - - - - - + + + + + + + + + - - - + + + - + - - + + @@ -49,61 +53,83 @@ - - + + - + + - - - + + + + + + + - + - - - - - - - - - + + + + + + + + + + + + + + + - + - + + + + - - - - + + + + + + - - - - + + + + + + - - - - - - - - + + + + + + + + + + + + @@ -111,15 +137,18 @@ - - - + + + + + + - 5.2.0 + 5.1.0 1.4.3 diff --git a/php/php-msgpack.spec b/php/php-msgpack.spec index 7609ca4..86125cb 100644 --- a/php/php-msgpack.spec +++ b/php/php-msgpack.spec @@ -3,7 +3,7 @@ Summary: PHP extension for interfacing with MessagePack Name: php-msgpack -Version: 0.3.0 +Version: 0.3.4 Release: 1%{?dist} Source: php-msgpack-%{version}.tar.gz License: New BSD License diff --git a/php/php_msgpack.h b/php/php_msgpack.h index 0791deb..80dce02 100644 --- a/php/php_msgpack.h +++ b/php/php_msgpack.h @@ -2,7 +2,7 @@ #ifndef PHP_MSGPACK_H #define PHP_MSGPACK_H -#define MSGPACK_EXTENSION_VERSION "0.3.1" +#define MSGPACK_EXTENSION_VERSION "0.3.4" #include "ext/standard/php_smart_str.h" diff --git a/php/tests/009.phpt b/php/tests/009.phpt index a1534c9..5189e3d 100644 --- a/php/tests/009.phpt +++ b/php/tests/009.phpt @@ -2,8 +2,10 @@ Check for reference serialization --SKIPIF-- = 0 && + version_compare(PHP_VERSION, '5.3.2') <= 0)) { + echo "skip tests in PHP 5.2.14/5.3.3 or newer"; } --FILE-- = 0) { - echo "skip tests in PHP 5.3.2 or older"; +if ((version_compare(PHP_VERSION, '5.3.0') < 0 && + version_compare(PHP_VERSION, '5.2.14') >= 0) || + (version_compare(PHP_VERSION, '5.3.3') >= 0)) { + echo "skip tests in PHP 5.2.13/5.3.2 or older"; } --FILE-- = 0) { + echo "skip tests in PHP 5.1 or older"; +} +--FILE-- +a = $a; + $this->b = $b; + $this->c = $c; + } +} + +$o = new Obj(1, 2, 3); + + +test('object', $o, false); +?> +--EXPECTF-- +object +84c0a34f626aa16101a4002a006202a6004f626a006303 +object(Obj)#%d (3) { + ["a"]=> + int(1) + ["b:protected"]=> + int(2) + ["c:private"]=> + int(3) +} +OK diff --git a/php/tests/015.phpt b/php/tests/015.phpt index 634a8b1..fcd9076 100644 --- a/php/tests/015.phpt +++ b/php/tests/015.phpt @@ -1,6 +1,10 @@ --TEST-- Check for serialization handler --SKIPIF-- += 0) { + echo "skip tests in PHP 5.2 or older"; +} +--FILE-- + +--EXPECT-- +2 +81a3666f6f02 +array(1) { + ["foo"]=> + int(2) +} diff --git a/php/tests/015e.phpt b/php/tests/015e.phpt new file mode 100644 index 0000000..f443452 --- /dev/null +++ b/php/tests/015e.phpt @@ -0,0 +1,65 @@ +--TEST-- +Check for serialization handler, broken +--SKIPIF-- + +--EXPECT-- +1 +82c001a3666f6f01 +array(1) { + ["foo"]=> + int(1) +} diff --git a/php/tests/015f.phpt b/php/tests/015f.phpt new file mode 100644 index 0000000..fe4278b --- /dev/null +++ b/php/tests/015f.phpt @@ -0,0 +1,65 @@ +--TEST-- +Check for serialization handler, broken +--SKIPIF-- += 0) { + echo "skip tests in PHP 5.2 or older"; +} +--FILE-- + +--EXPECT-- +1 +81a3666f6f01 +array(1) { + ["foo"]=> + int(1) +} diff --git a/php/tests/016.phpt b/php/tests/016.phpt index f8f4779..8fe47e8 100644 --- a/php/tests/016.phpt +++ b/php/tests/016.phpt @@ -1,6 +1,10 @@ --TEST-- Object test, __sleep --SKIPIF-- += 0) { + echo "skip tests in PHP 5.1 or older"; +} +--FILE-- +a = $a; + $this->b = $b; + $this->c = $c; + $this->d = $d; + } + + function __sleep() { + return array('a', 'b', 'c'); + } + +# function __wakeup() { +# $this->d = $this->a + $this->b + $this->c; +# } +} + +$o = new Obj(1, 2, 3, 4); + + +test('object', $o, true); +?> +--EXPECTF-- +object +84c0a34f626aa16101a4002a006202a6004f626a006303 +object(Obj)#%d (4) { + ["a"]=> + int(1) + ["b:protected"]=> + int(2) + ["c:private"]=> + int(3) + ["d"]=> + NULL +} +OK diff --git a/php/tests/021.phpt b/php/tests/021.phpt index 7960a1f..137d100 100644 --- a/php/tests/021.phpt +++ b/php/tests/021.phpt @@ -1,6 +1,10 @@ --TEST-- Object Serializable interface --SKIPIF-- + --FILE-- open('db.txt'); + $res = curl_init('http://php.net/'); +} else { + $test = 'dir'; + $res = opendir('/tmp'); } test('resource', $res, false); @@ -39,11 +33,8 @@ switch ($test) { case 'curl': curl_close($res); break; - case 'sqlite': - if (isset($sqlite)) { - $sqlite->close(); - } - @unlink('db.txt'); + default: + closedir($res); break; } ?> diff --git a/php/tests/024.phpt b/php/tests/024.phpt index 97db2a7..36c7c25 100644 --- a/php/tests/024.phpt +++ b/php/tests/024.phpt @@ -2,8 +2,10 @@ Recursive objects --SKIPIF-- = 0 && + version_compare(PHP_VERSION, '5.3.2') <= 0)) { + echo "skip tests in PHP 5.2.14/5.3.3 or newer"; } --FILE-- = 0) { - echo "skip tests in PHP 5.3.2 or older"; +if ((version_compare(PHP_VERSION, '5.3.0') < 0 && + version_compare(PHP_VERSION, '5.2.14') >= 0) || + (version_compare(PHP_VERSION, '5.3.3') >= 0)) { + echo "skip tests in PHP 5.2.13/5.3.2 or older"; +} +if (version_compare(PHP_VERSION, '5.2.0') < 0) { + echo "skip tests in PHP 5.2 or newer"; } --FILE-- = 0) { + echo "skip tests in PHP 5.1 or older"; +} +--FILE-- +a = $a; + $this->b = $b; + $this->c = $c; + } +} + +class Obj2 { + public $aa; + protected $bb; + private $cc; + private $obj; + + function __construct($a, $b, $c) { + $this->a = $a; + $this->b = $b; + $this->c = $c; + + $this->obj = new Obj($a, $b, $c); + } +} + +class Obj3 { + private $objs; + + function __construct($a, $b, $c) { + $this->objs = array(); + + for ($i = $a; $i < $c; $i += $b) { + $this->objs[] = new Obj($a, $i, $c); + } + } +} + +class Obj4 { + private $a; + private $obj; + + function __construct($a) { + $this->a = $a; + } + + public function set($obj) { + $this->obj = $obj; + } +} + +$o2 = new Obj2(1, 2, 3); +test('objectrec', $o2, false); + +$o3 = new Obj3(0, 1, 4); +test('objectrecarr', $o3, false); + +$o4 = new Obj4(100); +$o4->set($o4); +test('objectselfrec', $o4, true); +?> +--EXPECTF-- +objectrec +88c0a44f626a32a26161c0a5002a006262c0a8004f626a32006363c0a9004f626a32006f626a84c0a34f626aa16101a4002a006202a6004f626a006303a16101a16202a16303 +object(Obj2)#%d (7) { + ["aa"]=> + NULL + ["bb:protected"]=> + NULL + ["cc:private"]=> + NULL + ["obj:private"]=> + object(Obj)#%d (3) { + ["a"]=> + int(1) + ["b:protected"]=> + int(2) + ["c:private"]=> + int(3) + } + ["a"]=> + int(1) + ["b"]=> + int(2) + ["c"]=> + int(3) +} +OK +objectrecarr +82c0a44f626a33aa004f626a33006f626a73840084c0a34f626aa16100a4002a006200a6004f626a0063040184c0a34f626aa16100a4002a006201a6004f626a0063040284c0a34f626aa16100a4002a006202a6004f626a0063040384c0a34f626aa16100a4002a006203a6004f626a006304 +object(Obj3)#%d (1) { + ["objs:private"]=> + array(4) { + [0]=> + object(Obj)#%d (3) { + ["a"]=> + int(0) + ["b:protected"]=> + int(0) + ["c:private"]=> + int(4) + } + [1]=> + object(Obj)#%d (3) { + ["a"]=> + int(0) + ["b:protected"]=> + int(1) + ["c:private"]=> + int(4) + } + [2]=> + object(Obj)#%d (3) { + ["a"]=> + int(0) + ["b:protected"]=> + int(2) + ["c:private"]=> + int(4) + } + [3]=> + object(Obj)#%d (3) { + ["a"]=> + int(0) + ["b:protected"]=> + int(3) + ["c:private"]=> + int(4) + } + } +} +OK +objectselfrec +83c0a44f626a34a7004f626a34006164a9004f626a34006f626a82c0020001 +object(Obj4)#%d (2) { + ["a:private"]=> + int(100) + ["obj:private"]=> + object(Obj4)#%d (2) { + ["a:private"]=> + int(100) + ["obj:private"]=> + *RECURSION* + } +} +OK diff --git a/php/tests/025.phpt b/php/tests/025.phpt index 234539d..cb45a39 100644 --- a/php/tests/025.phpt +++ b/php/tests/025.phpt @@ -1,6 +1,10 @@ --TEST-- Object test, array of objects with __sleep --SKIPIF-- += 0) { + echo "skip tests in PHP 5.1 or older"; +} +--FILE-- +a = $a; + $this->b = $b; + $this->c = $c; + $this->d = $d; + } + + function __sleep() { + return array('a', 'b', 'c'); + } + +# function __wakeup() { +# $this->d = $this->a + $this->b + $this->c; +# } +} + +$array = array( + new Obj("aa", "bb", "cc", "dd"), + new Obj("ee", "ff", "gg", "hh"), + new Obj(1, 2, 3, 4), +); + + +test('array', $array, true); +?> +--EXPECTF-- +array(3) { + [0]=> + object(Obj)#1 (4) { + ["a"]=> + string(2) "aa" + ["b:protected"]=> + string(2) "bb" + ["c:private"]=> + string(2) "cc" + ["d"]=> + string(2) "dd" + } + [1]=> + object(Obj)#2 (4) { + ["a"]=> + string(2) "ee" + ["b:protected"]=> + string(2) "ff" + ["c:private"]=> + string(2) "gg" + ["d"]=> + string(2) "hh" + } + [2]=> + object(Obj)#3 (4) { + ["a"]=> + int(1) + ["b:protected"]=> + int(2) + ["c:private"]=> + int(3) + ["d"]=> + int(4) + } +} +array(3) { + [0]=> + object(Obj)#4 (4) { + ["a"]=> + string(2) "aa" + ["b:protected"]=> + string(2) "bb" + ["c:private"]=> + string(2) "cc" + ["d"]=> + NULL + } + [1]=> + object(Obj)#5 (4) { + ["a"]=> + string(2) "ee" + ["b:protected"]=> + string(2) "ff" + ["c:private"]=> + string(2) "gg" + ["d"]=> + NULL + } + [2]=> + object(Obj)#6 (4) { + ["a"]=> + int(1) + ["b:protected"]=> + int(2) + ["c:private"]=> + int(3) + ["d"]=> + NULL + } +} diff --git a/php/tests/026.phpt b/php/tests/026.phpt index 383289d..f7c706c 100644 --- a/php/tests/026.phpt +++ b/php/tests/026.phpt @@ -3,8 +3,10 @@ Cyclic array test --INI-- --SKIPIF-- = 0 && + version_compare(PHP_VERSION, '5.3.2') <= 0)) { + echo "skip tests in PHP 5.2.14/5.3.3 or newer"; } --FILE-- --EXPECT-- array -82a16182a162a163a164a165a16683c001a16182a162a163a164a165a16682c0020005 +82a16182a162a163a164a165a16683c001a16182a162a163a164a165a16682c0020003 array(2) { ["a"]=> array(2) { diff --git a/php/tests/026b.phpt b/php/tests/026b.phpt index 9eef7cb..dd18fa3 100644 --- a/php/tests/026b.phpt +++ b/php/tests/026b.phpt @@ -3,8 +3,13 @@ Cyclic array test --INI-- --SKIPIF-- = 0) { - echo "skip tests in PHP 5.3.2 or older"; +if ((version_compare(PHP_VERSION, '5.3.0') < 0 && + version_compare(PHP_VERSION, '5.2.14') >= 0) || + (version_compare(PHP_VERSION, '5.3.3') >= 0)) { + echo "skip tests in PHP 5.2.13/5.3.2 or older"; +} +if (version_compare(PHP_VERSION, '5.1.0') < 0) { + echo "skip tests in PHP 5.1 or newer"; } --FILE-- --EXPECT-- array -82a16182a162a163a164a165a16683c001a16182a162a163a164a165a16682c0020005 +82a16182a162a163a164a165a16683c001a16182a162a163a164a165a16682c0020003 array(2) { ["a"]=> array(2) { diff --git a/php/tests/026d.phpt b/php/tests/026d.phpt new file mode 100644 index 0000000..6a683c9 --- /dev/null +++ b/php/tests/026d.phpt @@ -0,0 +1,147 @@ +--TEST-- +Cyclic array test +--INI-- +--SKIPIF-- += 0) { + echo "skip tests in PHP 5.0 or older"; +} +--FILE-- + array( + 'b' => 'c', + 'd' => 'e' + ), +); + +$a['f'] = &$a; + +test('array', $a, true); + +$a = array("foo" => &$b); +$b = array(1, 2, $a); +var_dump($a); +var_dump($k = msgpack_unserialize(msgpack_serialize($a))); + +$k["foo"][1] = "b"; +var_dump($k); +?> +--EXPECT-- +array +82a16182a162a163a164a165a16682a16182a162a163a164a165a16682a16182a162a163a164a165a166c0 +array(2) { + ["a"]=> + array(2) { + ["b"]=> + string(1) "c" + ["d"]=> + string(1) "e" + } + ["f"]=> + array(2) { + ["a"]=> + array(2) { + ["b"]=> + string(1) "c" + ["d"]=> + string(1) "e" + } + ["f"]=> + array(2) { + ["a"]=> + array(2) { + ["b"]=> + string(1) "c" + ["d"]=> + string(1) "e" + } + ["f"]=> + NULL + } + } +} +OK +array(1) { + ["foo"]=> + &array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + array(1) { + ["foo"]=> + &array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + *RECURSION* + } + } + } +} +array(1) { + ["foo"]=> + &array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + array(1) { + ["foo"]=> + &array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + array(1) { + ["foo"]=> + *RECURSION* + } + } + } + } +} +array(1) { + ["foo"]=> + &array(3) { + [0]=> + int(1) + [1]=> + string(1) "b" + [2]=> + array(1) { + ["foo"]=> + &array(3) { + [0]=> + int(1) + [1]=> + string(1) "b" + [2]=> + array(1) { + ["foo"]=> + *RECURSION* + } + } + } + } +} diff --git a/php/tests/027.phpt b/php/tests/027.phpt index c9c7cbd..3963085 100644 --- a/php/tests/027.phpt +++ b/php/tests/027.phpt @@ -1,6 +1,10 @@ --TEST-- Check for serialization handler --SKIPIF-- += 0) { + echo "skip tests in PHP 5.2 or older"; +} +--FILE-- + +--EXPECT-- +bool(true) +read +wrote: 82a3666f6f01a474657374a6666f6f626172 +array(2) { + ["foo"]=> + int(1) + ["test"]=> + string(6) "foobar" +} diff --git a/php/tests/028.phpt b/php/tests/028.phpt index 1d326ce..65fa8db 100644 --- a/php/tests/028.phpt +++ b/php/tests/028.phpt @@ -2,8 +2,10 @@ Serialize object into session, full set --SKIPIF-- = 0 && + version_compare(PHP_VERSION, '5.3.2') <= 0)) { + echo "skip tests in PHP 5.2.14/5.3.3 or newer"; } --FILE-- --EXPECTF-- read -write: 84c001a36f6c6484c0a3466f6fa700466f6f00643184c0a3426172a2643182c0020002a70042617200643282c0020002a5002a00643382c0020002a5002a00643282c0020003a2643382c0020003a474657374a6666f6f626172a36e657784c0a3426172a2643184c0a3466f6fa700466f6f00643182c002000aa5002a00643282c002000aa2643382c002000aa70042617200643282c002000ba5002a00643382c002000b +write: 84c001a36f6c6484c0a3466f6fa700466f6f00643184c0a3426172a2643182c0020002a70042617200643282c0020002a5002a00643382c0020002a5002a00643282c0020003a2643382c0020003a474657374a6666f6f626172a36e657784c0a3426172a2643184c0a3466f6fa700466f6f00643182c0020009a5002a00643282c0020009a2643382c0020009a70042617200643282c002000aa5002a00643382c002000a array(3) { ["old"]=> object(Foo)#3 (3) { diff --git a/php/tests/028b.phpt b/php/tests/028b.phpt index 0efba18..d184f4e 100644 --- a/php/tests/028b.phpt +++ b/php/tests/028b.phpt @@ -2,8 +2,13 @@ Serialize object into session, full set --SKIPIF-- = 0) { - echo "skip tests in PHP 5.3.2 or older"; +if ((version_compare(PHP_VERSION, '5.3.0') < 0 && + version_compare(PHP_VERSION, '5.2.14') >= 0) || + (version_compare(PHP_VERSION, '5.3.3') >= 0)) { + echo "skip tests in PHP 5.2.13/5.3.2 or older"; +} +if (version_compare(PHP_VERSION, '5.2.0') < 0) { + echo "skip tests in PHP 5.2 or newer"; } --FILE-- --EXPECTF-- read -write: 84c001a36f6c6484c0a3466f6fa700466f6f00643184c0a3426172a2643182c0020002a70042617200643282c0020002a5002a00643382c0020002a5002a00643282c0020003a2643382c0020003a474657374a6666f6f626172a36e657784c0a3426172a2643184c0a3466f6fa700466f6f00643182c002000aa5002a00643282c002000aa2643382c002000aa70042617200643282c002000ba5002a00643382c002000b +write: 84c001a36f6c6484c0a3466f6fa700466f6f00643184c0a3426172a2643182c0020002a70042617200643282c0020002a5002a00643382c0020002a5002a00643282c0020003a2643382c0020003a474657374a6666f6f626172a36e657784c0a3426172a2643184c0a3466f6fa700466f6f00643182c0020009a5002a00643282c0020009a2643382c0020009a70042617200643282c002000aa5002a00643382c002000a array(3) { ["old"]=> object(Foo)#3 (3) { diff --git a/php/tests/028c.phpt b/php/tests/028c.phpt new file mode 100644 index 0000000..3e698ac --- /dev/null +++ b/php/tests/028c.phpt @@ -0,0 +1,672 @@ +--TEST-- +Serialize object into session, full set +--SKIPIF-- += 0) { + echo "skip tests in PHP 5.1"; +} +--FILE-- +d1 = $foo; + $this->d2 = $foo; + $this->d3 = $foo; + } +} + +class Bar { + private static $s1 = array(); + protected static $s2 = array(); + public static $s3 = array(); + + public $d1; + private $d2; + protected $d3; + + public function __construct() { + } + + public function set($foo) { + $this->d1 = $foo; + $this->d2 = $foo; + $this->d3 = $foo; + } +} + +$output = ''; + +function open($path, $name) { + return true; +} + +function close() { + return true; +} + +function read($id) { + global $output; + $output .= "read" . PHP_EOL; + $a = new Bar(); + $b = new Foo($a); + $a->set($b); + $session = array('old' => $b); + return msgpack_serialize($session); +} + +function write($id, $data) { + global $output; + $output .= "write: "; + $output .= bin2hex($data) . PHP_EOL; + return true; +} + +function destroy($id) { + return true; +} + +function gc($time) { + return true; +} + +ini_set('session.serialize_handler', 'msgpack'); + +session_set_save_handler('open', 'close', 'read', 'write', 'destroy', 'gc'); + +session_start(); + +$_SESSION['test'] = "foobar"; +$a = new Bar(); +$b = new Foo($a); +$a->set($b); +$_SESSION['new'] = $a; + +session_write_close(); + +echo $output; +var_dump($_SESSION); +?> +--EXPECTF-- +read +write: 83a36f6c6484c0a3466f6fa700466f6f00643184c0a3426172a2643182c0020002a70042617200643282c0020002a5002a00643382c0020002a5002a00643282c0020003a2643382c0020003a474657374a6666f6f626172a36e657784c0a3426172a2643184c0a3466f6fa700466f6f00643182c0020009a5002a00643282c0020009a2643382c0020009a70042617200643282c002000aa5002a00643382c002000a +array(3) { + ["old"]=> + object(Foo)#3 (3) { + ["d1:private"]=> + object(Bar)#4 (3) { + ["d1"]=> + object(Foo)#3 (3) { + ["d1:private"]=> + object(Bar)#4 (3) { + ["d1"]=> + *RECURSION* + ["d2:private"]=> + *RECURSION* + ["d3:protected"]=> + *RECURSION* + } + ["d2:protected"]=> + object(Bar)#4 (3) { + ["d1"]=> + *RECURSION* + ["d2:private"]=> + *RECURSION* + ["d3:protected"]=> + *RECURSION* + } + ["d3"]=> + object(Bar)#4 (3) { + ["d1"]=> + *RECURSION* + ["d2:private"]=> + *RECURSION* + ["d3:protected"]=> + *RECURSION* + } + } + ["d2:private"]=> + object(Foo)#3 (3) { + ["d1:private"]=> + object(Bar)#4 (3) { + ["d1"]=> + *RECURSION* + ["d2:private"]=> + *RECURSION* + ["d3:protected"]=> + *RECURSION* + } + ["d2:protected"]=> + object(Bar)#4 (3) { + ["d1"]=> + *RECURSION* + ["d2:private"]=> + *RECURSION* + ["d3:protected"]=> + *RECURSION* + } + ["d3"]=> + object(Bar)#4 (3) { + ["d1"]=> + *RECURSION* + ["d2:private"]=> + *RECURSION* + ["d3:protected"]=> + *RECURSION* + } + } + ["d3:protected"]=> + object(Foo)#3 (3) { + ["d1:private"]=> + object(Bar)#4 (3) { + ["d1"]=> + *RECURSION* + ["d2:private"]=> + *RECURSION* + ["d3:protected"]=> + *RECURSION* + } + ["d2:protected"]=> + object(Bar)#4 (3) { + ["d1"]=> + *RECURSION* + ["d2:private"]=> + *RECURSION* + ["d3:protected"]=> + *RECURSION* + } + ["d3"]=> + object(Bar)#4 (3) { + ["d1"]=> + *RECURSION* + ["d2:private"]=> + *RECURSION* + ["d3:protected"]=> + *RECURSION* + } + } + } + ["d2:protected"]=> + object(Bar)#4 (3) { + ["d1"]=> + object(Foo)#3 (3) { + ["d1:private"]=> + object(Bar)#4 (3) { + ["d1"]=> + *RECURSION* + ["d2:private"]=> + *RECURSION* + ["d3:protected"]=> + *RECURSION* + } + ["d2:protected"]=> + object(Bar)#4 (3) { + ["d1"]=> + *RECURSION* + ["d2:private"]=> + *RECURSION* + ["d3:protected"]=> + *RECURSION* + } + ["d3"]=> + object(Bar)#4 (3) { + ["d1"]=> + *RECURSION* + ["d2:private"]=> + *RECURSION* + ["d3:protected"]=> + *RECURSION* + } + } + ["d2:private"]=> + object(Foo)#3 (3) { + ["d1:private"]=> + object(Bar)#4 (3) { + ["d1"]=> + *RECURSION* + ["d2:private"]=> + *RECURSION* + ["d3:protected"]=> + *RECURSION* + } + ["d2:protected"]=> + object(Bar)#4 (3) { + ["d1"]=> + *RECURSION* + ["d2:private"]=> + *RECURSION* + ["d3:protected"]=> + *RECURSION* + } + ["d3"]=> + object(Bar)#4 (3) { + ["d1"]=> + *RECURSION* + ["d2:private"]=> + *RECURSION* + ["d3:protected"]=> + *RECURSION* + } + } + ["d3:protected"]=> + object(Foo)#3 (3) { + ["d1:private"]=> + object(Bar)#4 (3) { + ["d1"]=> + *RECURSION* + ["d2:private"]=> + *RECURSION* + ["d3:protected"]=> + *RECURSION* + } + ["d2:protected"]=> + object(Bar)#4 (3) { + ["d1"]=> + *RECURSION* + ["d2:private"]=> + *RECURSION* + ["d3:protected"]=> + *RECURSION* + } + ["d3"]=> + object(Bar)#4 (3) { + ["d1"]=> + *RECURSION* + ["d2:private"]=> + *RECURSION* + ["d3:protected"]=> + *RECURSION* + } + } + } + ["d3"]=> + object(Bar)#4 (3) { + ["d1"]=> + object(Foo)#3 (3) { + ["d1:private"]=> + object(Bar)#4 (3) { + ["d1"]=> + *RECURSION* + ["d2:private"]=> + *RECURSION* + ["d3:protected"]=> + *RECURSION* + } + ["d2:protected"]=> + object(Bar)#4 (3) { + ["d1"]=> + *RECURSION* + ["d2:private"]=> + *RECURSION* + ["d3:protected"]=> + *RECURSION* + } + ["d3"]=> + object(Bar)#4 (3) { + ["d1"]=> + *RECURSION* + ["d2:private"]=> + *RECURSION* + ["d3:protected"]=> + *RECURSION* + } + } + ["d2:private"]=> + object(Foo)#3 (3) { + ["d1:private"]=> + object(Bar)#4 (3) { + ["d1"]=> + *RECURSION* + ["d2:private"]=> + *RECURSION* + ["d3:protected"]=> + *RECURSION* + } + ["d2:protected"]=> + object(Bar)#4 (3) { + ["d1"]=> + *RECURSION* + ["d2:private"]=> + *RECURSION* + ["d3:protected"]=> + *RECURSION* + } + ["d3"]=> + object(Bar)#4 (3) { + ["d1"]=> + *RECURSION* + ["d2:private"]=> + *RECURSION* + ["d3:protected"]=> + *RECURSION* + } + } + ["d3:protected"]=> + object(Foo)#3 (3) { + ["d1:private"]=> + object(Bar)#4 (3) { + ["d1"]=> + *RECURSION* + ["d2:private"]=> + *RECURSION* + ["d3:protected"]=> + *RECURSION* + } + ["d2:protected"]=> + object(Bar)#4 (3) { + ["d1"]=> + *RECURSION* + ["d2:private"]=> + *RECURSION* + ["d3:protected"]=> + *RECURSION* + } + ["d3"]=> + object(Bar)#4 (3) { + ["d1"]=> + *RECURSION* + ["d2:private"]=> + *RECURSION* + ["d3:protected"]=> + *RECURSION* + } + } + } + } + ["test"]=> + string(6) "foobar" + ["new"]=> + object(Bar)#5 (3) { + ["d1"]=> + object(Foo)#6 (3) { + ["d1:private"]=> + object(Bar)#5 (3) { + ["d1"]=> + object(Foo)#6 (3) { + ["d1:private"]=> + *RECURSION* + ["d2:protected"]=> + *RECURSION* + ["d3"]=> + *RECURSION* + } + ["d2:private"]=> + object(Foo)#6 (3) { + ["d1:private"]=> + *RECURSION* + ["d2:protected"]=> + *RECURSION* + ["d3"]=> + *RECURSION* + } + ["d3:protected"]=> + object(Foo)#6 (3) { + ["d1:private"]=> + *RECURSION* + ["d2:protected"]=> + *RECURSION* + ["d3"]=> + *RECURSION* + } + } + ["d2:protected"]=> + object(Bar)#5 (3) { + ["d1"]=> + object(Foo)#6 (3) { + ["d1:private"]=> + *RECURSION* + ["d2:protected"]=> + *RECURSION* + ["d3"]=> + *RECURSION* + } + ["d2:private"]=> + object(Foo)#6 (3) { + ["d1:private"]=> + *RECURSION* + ["d2:protected"]=> + *RECURSION* + ["d3"]=> + *RECURSION* + } + ["d3:protected"]=> + object(Foo)#6 (3) { + ["d1:private"]=> + *RECURSION* + ["d2:protected"]=> + *RECURSION* + ["d3"]=> + *RECURSION* + } + } + ["d3"]=> + object(Bar)#5 (3) { + ["d1"]=> + object(Foo)#6 (3) { + ["d1:private"]=> + *RECURSION* + ["d2:protected"]=> + *RECURSION* + ["d3"]=> + *RECURSION* + } + ["d2:private"]=> + object(Foo)#6 (3) { + ["d1:private"]=> + *RECURSION* + ["d2:protected"]=> + *RECURSION* + ["d3"]=> + *RECURSION* + } + ["d3:protected"]=> + object(Foo)#6 (3) { + ["d1:private"]=> + *RECURSION* + ["d2:protected"]=> + *RECURSION* + ["d3"]=> + *RECURSION* + } + } + } + ["d2:private"]=> + object(Foo)#6 (3) { + ["d1:private"]=> + object(Bar)#5 (3) { + ["d1"]=> + object(Foo)#6 (3) { + ["d1:private"]=> + *RECURSION* + ["d2:protected"]=> + *RECURSION* + ["d3"]=> + *RECURSION* + } + ["d2:private"]=> + object(Foo)#6 (3) { + ["d1:private"]=> + *RECURSION* + ["d2:protected"]=> + *RECURSION* + ["d3"]=> + *RECURSION* + } + ["d3:protected"]=> + object(Foo)#6 (3) { + ["d1:private"]=> + *RECURSION* + ["d2:protected"]=> + *RECURSION* + ["d3"]=> + *RECURSION* + } + } + ["d2:protected"]=> + object(Bar)#5 (3) { + ["d1"]=> + object(Foo)#6 (3) { + ["d1:private"]=> + *RECURSION* + ["d2:protected"]=> + *RECURSION* + ["d3"]=> + *RECURSION* + } + ["d2:private"]=> + object(Foo)#6 (3) { + ["d1:private"]=> + *RECURSION* + ["d2:protected"]=> + *RECURSION* + ["d3"]=> + *RECURSION* + } + ["d3:protected"]=> + object(Foo)#6 (3) { + ["d1:private"]=> + *RECURSION* + ["d2:protected"]=> + *RECURSION* + ["d3"]=> + *RECURSION* + } + } + ["d3"]=> + object(Bar)#5 (3) { + ["d1"]=> + object(Foo)#6 (3) { + ["d1:private"]=> + *RECURSION* + ["d2:protected"]=> + *RECURSION* + ["d3"]=> + *RECURSION* + } + ["d2:private"]=> + object(Foo)#6 (3) { + ["d1:private"]=> + *RECURSION* + ["d2:protected"]=> + *RECURSION* + ["d3"]=> + *RECURSION* + } + ["d3:protected"]=> + object(Foo)#6 (3) { + ["d1:private"]=> + *RECURSION* + ["d2:protected"]=> + *RECURSION* + ["d3"]=> + *RECURSION* + } + } + } + ["d3:protected"]=> + object(Foo)#6 (3) { + ["d1:private"]=> + object(Bar)#5 (3) { + ["d1"]=> + object(Foo)#6 (3) { + ["d1:private"]=> + *RECURSION* + ["d2:protected"]=> + *RECURSION* + ["d3"]=> + *RECURSION* + } + ["d2:private"]=> + object(Foo)#6 (3) { + ["d1:private"]=> + *RECURSION* + ["d2:protected"]=> + *RECURSION* + ["d3"]=> + *RECURSION* + } + ["d3:protected"]=> + object(Foo)#6 (3) { + ["d1:private"]=> + *RECURSION* + ["d2:protected"]=> + *RECURSION* + ["d3"]=> + *RECURSION* + } + } + ["d2:protected"]=> + object(Bar)#5 (3) { + ["d1"]=> + object(Foo)#6 (3) { + ["d1:private"]=> + *RECURSION* + ["d2:protected"]=> + *RECURSION* + ["d3"]=> + *RECURSION* + } + ["d2:private"]=> + object(Foo)#6 (3) { + ["d1:private"]=> + *RECURSION* + ["d2:protected"]=> + *RECURSION* + ["d3"]=> + *RECURSION* + } + ["d3:protected"]=> + object(Foo)#6 (3) { + ["d1:private"]=> + *RECURSION* + ["d2:protected"]=> + *RECURSION* + ["d3"]=> + *RECURSION* + } + } + ["d3"]=> + object(Bar)#5 (3) { + ["d1"]=> + object(Foo)#6 (3) { + ["d1:private"]=> + *RECURSION* + ["d2:protected"]=> + *RECURSION* + ["d3"]=> + *RECURSION* + } + ["d2:private"]=> + object(Foo)#6 (3) { + ["d1:private"]=> + *RECURSION* + ["d2:protected"]=> + *RECURSION* + ["d3"]=> + *RECURSION* + } + ["d3:protected"]=> + object(Foo)#6 (3) { + ["d1:private"]=> + *RECURSION* + ["d2:protected"]=> + *RECURSION* + ["d3"]=> + *RECURSION* + } + } + } + } +} diff --git a/php/tests/028d.phpt b/php/tests/028d.phpt new file mode 100644 index 0000000..c316694 --- /dev/null +++ b/php/tests/028d.phpt @@ -0,0 +1,671 @@ +--TEST-- +Serialize object into session, full set +--SKIPIF-- += 0) { + echo "skip tests in PHP 5.0 or older"; +} +--FILE-- +d1 = $foo; + $this->d2 = $foo; + $this->d3 = $foo; + } +} + +class Bar { + private static $s1 = array(); + protected static $s2 = array(); + public static $s3 = array(); + + public $d1; + private $d2; + protected $d3; + + public function __construct() { + } + + public function set($foo) { + $this->d1 = $foo; + $this->d2 = $foo; + $this->d3 = $foo; + } +} + +$output = ''; + +function open($path, $name) { + return true; +} + +function close() { + return true; +} + +function read($id) { + global $output; + $output .= "read" . PHP_EOL; + $a = new Bar(); + $b = new Foo($a); + $a->set($b); + $session = array('old' => $b); + return msgpack_serialize($session); +} + +function write($id, $data) { + global $output; + $output .= "write: "; + $output .= bin2hex($data) . PHP_EOL; + return true; +} + +function destroy($id) { + return true; +} + +function gc($time) { + return true; +} + +ini_set('session.serialize_handler', 'msgpack'); + +session_set_save_handler('open', 'close', 'read', 'write', 'destroy', 'gc'); + +session_start(); + +$_SESSION['test'] = "foobar"; +$a = new Bar(); +$b = new Foo($a); +$a->set($b); +$_SESSION['new'] = $a; + +session_write_close(); + +echo $output; +var_dump($_SESSION); +?> +--EXPECTF-- +read +write: 83a36f6c6484c0a3466f6fa700466f6f00643184c0a3426172a2643182c0020002a70042617200643282c0020002a5002a00643382c0020002a5002a00643282c0020003a2643382c0020003a474657374a6666f6f626172a36e657784c0a3426172a2643184c0a3466f6fa700466f6f00643182c0020009a5002a00643282c0020009a2643382c0020009a70042617200643282c002000aa5002a00643382c002000a +array(3) { + ["old"]=> + object(Foo)#3 (3) { + ["d1:private"]=> + object(Bar)#4 (3) { + ["d1"]=> + object(Foo)#3 (3) { + ["d1:private"]=> + object(Bar)#4 (3) { + ["d1"]=> + *RECURSION* + ["d2:private"]=> + *RECURSION* + ["d3:protected"]=> + *RECURSION* + } + ["d2:protected"]=> + object(Bar)#4 (3) { + ["d1"]=> + *RECURSION* + ["d2:private"]=> + *RECURSION* + ["d3:protected"]=> + *RECURSION* + } + ["d3"]=> + object(Bar)#4 (3) { + ["d1"]=> + *RECURSION* + ["d2:private"]=> + *RECURSION* + ["d3:protected"]=> + *RECURSION* + } + } + ["d2:private"]=> + object(Foo)#3 (3) { + ["d1:private"]=> + object(Bar)#4 (3) { + ["d1"]=> + *RECURSION* + ["d2:private"]=> + *RECURSION* + ["d3:protected"]=> + *RECURSION* + } + ["d2:protected"]=> + object(Bar)#4 (3) { + ["d1"]=> + *RECURSION* + ["d2:private"]=> + *RECURSION* + ["d3:protected"]=> + *RECURSION* + } + ["d3"]=> + object(Bar)#4 (3) { + ["d1"]=> + *RECURSION* + ["d2:private"]=> + *RECURSION* + ["d3:protected"]=> + *RECURSION* + } + } + ["d3:protected"]=> + object(Foo)#3 (3) { + ["d1:private"]=> + object(Bar)#4 (3) { + ["d1"]=> + *RECURSION* + ["d2:private"]=> + *RECURSION* + ["d3:protected"]=> + *RECURSION* + } + ["d2:protected"]=> + object(Bar)#4 (3) { + ["d1"]=> + *RECURSION* + ["d2:private"]=> + *RECURSION* + ["d3:protected"]=> + *RECURSION* + } + ["d3"]=> + object(Bar)#4 (3) { + ["d1"]=> + *RECURSION* + ["d2:private"]=> + *RECURSION* + ["d3:protected"]=> + *RECURSION* + } + } + } + ["d2:protected"]=> + object(Bar)#4 (3) { + ["d1"]=> + object(Foo)#3 (3) { + ["d1:private"]=> + object(Bar)#4 (3) { + ["d1"]=> + *RECURSION* + ["d2:private"]=> + *RECURSION* + ["d3:protected"]=> + *RECURSION* + } + ["d2:protected"]=> + object(Bar)#4 (3) { + ["d1"]=> + *RECURSION* + ["d2:private"]=> + *RECURSION* + ["d3:protected"]=> + *RECURSION* + } + ["d3"]=> + object(Bar)#4 (3) { + ["d1"]=> + *RECURSION* + ["d2:private"]=> + *RECURSION* + ["d3:protected"]=> + *RECURSION* + } + } + ["d2:private"]=> + object(Foo)#3 (3) { + ["d1:private"]=> + object(Bar)#4 (3) { + ["d1"]=> + *RECURSION* + ["d2:private"]=> + *RECURSION* + ["d3:protected"]=> + *RECURSION* + } + ["d2:protected"]=> + object(Bar)#4 (3) { + ["d1"]=> + *RECURSION* + ["d2:private"]=> + *RECURSION* + ["d3:protected"]=> + *RECURSION* + } + ["d3"]=> + object(Bar)#4 (3) { + ["d1"]=> + *RECURSION* + ["d2:private"]=> + *RECURSION* + ["d3:protected"]=> + *RECURSION* + } + } + ["d3:protected"]=> + object(Foo)#3 (3) { + ["d1:private"]=> + object(Bar)#4 (3) { + ["d1"]=> + *RECURSION* + ["d2:private"]=> + *RECURSION* + ["d3:protected"]=> + *RECURSION* + } + ["d2:protected"]=> + object(Bar)#4 (3) { + ["d1"]=> + *RECURSION* + ["d2:private"]=> + *RECURSION* + ["d3:protected"]=> + *RECURSION* + } + ["d3"]=> + object(Bar)#4 (3) { + ["d1"]=> + *RECURSION* + ["d2:private"]=> + *RECURSION* + ["d3:protected"]=> + *RECURSION* + } + } + } + ["d3"]=> + object(Bar)#4 (3) { + ["d1"]=> + object(Foo)#3 (3) { + ["d1:private"]=> + object(Bar)#4 (3) { + ["d1"]=> + *RECURSION* + ["d2:private"]=> + *RECURSION* + ["d3:protected"]=> + *RECURSION* + } + ["d2:protected"]=> + object(Bar)#4 (3) { + ["d1"]=> + *RECURSION* + ["d2:private"]=> + *RECURSION* + ["d3:protected"]=> + *RECURSION* + } + ["d3"]=> + object(Bar)#4 (3) { + ["d1"]=> + *RECURSION* + ["d2:private"]=> + *RECURSION* + ["d3:protected"]=> + *RECURSION* + } + } + ["d2:private"]=> + object(Foo)#3 (3) { + ["d1:private"]=> + object(Bar)#4 (3) { + ["d1"]=> + *RECURSION* + ["d2:private"]=> + *RECURSION* + ["d3:protected"]=> + *RECURSION* + } + ["d2:protected"]=> + object(Bar)#4 (3) { + ["d1"]=> + *RECURSION* + ["d2:private"]=> + *RECURSION* + ["d3:protected"]=> + *RECURSION* + } + ["d3"]=> + object(Bar)#4 (3) { + ["d1"]=> + *RECURSION* + ["d2:private"]=> + *RECURSION* + ["d3:protected"]=> + *RECURSION* + } + } + ["d3:protected"]=> + object(Foo)#3 (3) { + ["d1:private"]=> + object(Bar)#4 (3) { + ["d1"]=> + *RECURSION* + ["d2:private"]=> + *RECURSION* + ["d3:protected"]=> + *RECURSION* + } + ["d2:protected"]=> + object(Bar)#4 (3) { + ["d1"]=> + *RECURSION* + ["d2:private"]=> + *RECURSION* + ["d3:protected"]=> + *RECURSION* + } + ["d3"]=> + object(Bar)#4 (3) { + ["d1"]=> + *RECURSION* + ["d2:private"]=> + *RECURSION* + ["d3:protected"]=> + *RECURSION* + } + } + } + } + ["test"]=> + string(6) "foobar" + ["new"]=> + object(Bar)#5 (3) { + ["d1"]=> + object(Foo)#6 (3) { + ["d1:private"]=> + object(Bar)#5 (3) { + ["d1"]=> + object(Foo)#6 (3) { + ["d1:private"]=> + *RECURSION* + ["d2:protected"]=> + *RECURSION* + ["d3"]=> + *RECURSION* + } + ["d2:private"]=> + object(Foo)#6 (3) { + ["d1:private"]=> + *RECURSION* + ["d2:protected"]=> + *RECURSION* + ["d3"]=> + *RECURSION* + } + ["d3:protected"]=> + object(Foo)#6 (3) { + ["d1:private"]=> + *RECURSION* + ["d2:protected"]=> + *RECURSION* + ["d3"]=> + *RECURSION* + } + } + ["d2:protected"]=> + object(Bar)#5 (3) { + ["d1"]=> + object(Foo)#6 (3) { + ["d1:private"]=> + *RECURSION* + ["d2:protected"]=> + *RECURSION* + ["d3"]=> + *RECURSION* + } + ["d2:private"]=> + object(Foo)#6 (3) { + ["d1:private"]=> + *RECURSION* + ["d2:protected"]=> + *RECURSION* + ["d3"]=> + *RECURSION* + } + ["d3:protected"]=> + object(Foo)#6 (3) { + ["d1:private"]=> + *RECURSION* + ["d2:protected"]=> + *RECURSION* + ["d3"]=> + *RECURSION* + } + } + ["d3"]=> + object(Bar)#5 (3) { + ["d1"]=> + object(Foo)#6 (3) { + ["d1:private"]=> + *RECURSION* + ["d2:protected"]=> + *RECURSION* + ["d3"]=> + *RECURSION* + } + ["d2:private"]=> + object(Foo)#6 (3) { + ["d1:private"]=> + *RECURSION* + ["d2:protected"]=> + *RECURSION* + ["d3"]=> + *RECURSION* + } + ["d3:protected"]=> + object(Foo)#6 (3) { + ["d1:private"]=> + *RECURSION* + ["d2:protected"]=> + *RECURSION* + ["d3"]=> + *RECURSION* + } + } + } + ["d2:private"]=> + object(Foo)#6 (3) { + ["d1:private"]=> + object(Bar)#5 (3) { + ["d1"]=> + object(Foo)#6 (3) { + ["d1:private"]=> + *RECURSION* + ["d2:protected"]=> + *RECURSION* + ["d3"]=> + *RECURSION* + } + ["d2:private"]=> + object(Foo)#6 (3) { + ["d1:private"]=> + *RECURSION* + ["d2:protected"]=> + *RECURSION* + ["d3"]=> + *RECURSION* + } + ["d3:protected"]=> + object(Foo)#6 (3) { + ["d1:private"]=> + *RECURSION* + ["d2:protected"]=> + *RECURSION* + ["d3"]=> + *RECURSION* + } + } + ["d2:protected"]=> + object(Bar)#5 (3) { + ["d1"]=> + object(Foo)#6 (3) { + ["d1:private"]=> + *RECURSION* + ["d2:protected"]=> + *RECURSION* + ["d3"]=> + *RECURSION* + } + ["d2:private"]=> + object(Foo)#6 (3) { + ["d1:private"]=> + *RECURSION* + ["d2:protected"]=> + *RECURSION* + ["d3"]=> + *RECURSION* + } + ["d3:protected"]=> + object(Foo)#6 (3) { + ["d1:private"]=> + *RECURSION* + ["d2:protected"]=> + *RECURSION* + ["d3"]=> + *RECURSION* + } + } + ["d3"]=> + object(Bar)#5 (3) { + ["d1"]=> + object(Foo)#6 (3) { + ["d1:private"]=> + *RECURSION* + ["d2:protected"]=> + *RECURSION* + ["d3"]=> + *RECURSION* + } + ["d2:private"]=> + object(Foo)#6 (3) { + ["d1:private"]=> + *RECURSION* + ["d2:protected"]=> + *RECURSION* + ["d3"]=> + *RECURSION* + } + ["d3:protected"]=> + object(Foo)#6 (3) { + ["d1:private"]=> + *RECURSION* + ["d2:protected"]=> + *RECURSION* + ["d3"]=> + *RECURSION* + } + } + } + ["d3:protected"]=> + object(Foo)#6 (3) { + ["d1:private"]=> + object(Bar)#5 (3) { + ["d1"]=> + object(Foo)#6 (3) { + ["d1:private"]=> + *RECURSION* + ["d2:protected"]=> + *RECURSION* + ["d3"]=> + *RECURSION* + } + ["d2:private"]=> + object(Foo)#6 (3) { + ["d1:private"]=> + *RECURSION* + ["d2:protected"]=> + *RECURSION* + ["d3"]=> + *RECURSION* + } + ["d3:protected"]=> + object(Foo)#6 (3) { + ["d1:private"]=> + *RECURSION* + ["d2:protected"]=> + *RECURSION* + ["d3"]=> + *RECURSION* + } + } + ["d2:protected"]=> + object(Bar)#5 (3) { + ["d1"]=> + object(Foo)#6 (3) { + ["d1:private"]=> + *RECURSION* + ["d2:protected"]=> + *RECURSION* + ["d3"]=> + *RECURSION* + } + ["d2:private"]=> + object(Foo)#6 (3) { + ["d1:private"]=> + *RECURSION* + ["d2:protected"]=> + *RECURSION* + ["d3"]=> + *RECURSION* + } + ["d3:protected"]=> + object(Foo)#6 (3) { + ["d1:private"]=> + *RECURSION* + ["d2:protected"]=> + *RECURSION* + ["d3"]=> + *RECURSION* + } + } + ["d3"]=> + object(Bar)#5 (3) { + ["d1"]=> + object(Foo)#6 (3) { + ["d1:private"]=> + *RECURSION* + ["d2:protected"]=> + *RECURSION* + ["d3"]=> + *RECURSION* + } + ["d2:private"]=> + object(Foo)#6 (3) { + ["d1:private"]=> + *RECURSION* + ["d2:protected"]=> + *RECURSION* + ["d3"]=> + *RECURSION* + } + ["d3:protected"]=> + object(Foo)#6 (3) { + ["d1:private"]=> + *RECURSION* + ["d2:protected"]=> + *RECURSION* + ["d3"]=> + *RECURSION* + } + } + } + } +} diff --git a/php/tests/031.phpt b/php/tests/031.phpt index ce3ba49..ce3a7c4 100644 --- a/php/tests/031.phpt +++ b/php/tests/031.phpt @@ -1,6 +1,10 @@ --TEST-- Object Serializable interface throws exceptions --SKIPIF-- +unpack($serialized)) === null) { + return true; + } + + // whole data is read? + if ($serialized !== msgpack_serialize($unserialized)) { + return true; + } + + echo bin2hex($serialized), "\n"; + var_dump($unserialized); + + return false; +} + +mt_srand(0x4c05b583); +for ($i = 0; $i < 100; ++$i) { + if (!test()) break; +} + +?> +--EXPECT-- diff --git a/php/tests/040c.phpt b/php/tests/040c.phpt new file mode 100644 index 0000000..bd882fa --- /dev/null +++ b/php/tests/040c.phpt @@ -0,0 +1,53 @@ +--TEST-- +broken random data test : MessagePackUnpacker::feed +--SKIPIF-- +--FILE-- +feed($serialized); + if ($unpacker->execute()) + { + if (($unserialized = $unpacker->data()) === null) { + return true; + } + $unpacker->reset(); + } + else + { + return true; + } + + // whole data is read? + if ($serialized !== msgpack_serialize($unserialized)) { + return true; + } + + echo bin2hex($serialized), "\n"; + var_dump($unserialized); + + return false; +} + +mt_srand(0x4c05b583); +for ($i = 0; $i < 100; ++$i) { + if (!test()) break; +} + +?> +--EXPECT-- diff --git a/php/tests/040d.phpt b/php/tests/040d.phpt new file mode 100644 index 0000000..de4c01d --- /dev/null +++ b/php/tests/040d.phpt @@ -0,0 +1,52 @@ +--TEST-- +broken random data test : MessagePackUnpacker::execute +--SKIPIF-- +--FILE-- +execute($serialized, $offset)) + { + if (($unserialized = $unpacker->data()) === null) { + return true; + } + $unpacker->reset(); + } + else + { + return true; + } + + // whole data is read? + if ($serialized !== msgpack_serialize($unserialized)) { + return true; + } + + echo bin2hex($serialized), "\n"; + var_dump($unserialized); + + return false; +} + +mt_srand(0x4c05b583); +for ($i = 0; $i < 100; ++$i) { + if (!test()) break; +} + +?> +--EXPECT-- diff --git a/php/tests/060.phpt b/php/tests/060.phpt index 3ea97eb..c210fa9 100644 --- a/php/tests/060.phpt +++ b/php/tests/060.phpt @@ -2,8 +2,10 @@ Check for buffered streaming unserialization --SKIPIF-- = 0 && + version_compare(PHP_VERSION, '5.3.2') <= 0)) { + echo "skip tests in PHP 5.2.14/5.3.3 or newer"; } --FILE-- = 0) { - echo "skip tests in PHP 5.3.2 or older"; +if ((version_compare(PHP_VERSION, '5.3.0') < 0 && + version_compare(PHP_VERSION, '5.2.14') >= 0) || + (version_compare(PHP_VERSION, '5.3.3') >= 0)) { + echo "skip tests in PHP 5.2.13/5.3.2 or older"; +} +if (version_compare(PHP_VERSION, '5.2.0') < 0) { + echo "skip tests in PHP 5.2 or newer"; } --FILE-- = 0) { + echo "skip tests in PHP 5.1 or older"; +} +--FILE-- +feed($str); + if ($unpacker->execute()) + { + $unserialized = $unpacker->data(); + var_dump($unserialized); + $unpacker->reset(); + } + + $i += $len; + } + + if (!is_bool($test)) + { + echo $unserialized === $variable ? 'OK' : 'ERROR', PHP_EOL; + } + else + { + echo $test || $unserialized == $variable ? 'OK' : 'ERROR', PHP_EOL; + } +} + +test('null', null); + +test('bool: true', true); +test('bool: false', false); + +test('zero: 0', 0); +test('small: 1', 1); +test('small: -1', -1); +test('medium: 1000', 1000); +test('medium: -1000', -1000); +test('large: 100000', 100000); +test('large: -100000', -100000); + +test('double: 123.456', 123.456); + +test('empty: ""', ""); +test('string: "foobar"', "foobar"); + +test('array', array(), false); +test('array(1, 2, 3)', array(1, 2, 3), false); +test('array(array(1, 2, 3), arr...', array(array(1, 2, 3), array(4, 5, 6), array(7, 8, 9)), false); + +test('array("foo", "foo", "foo")', array("foo", "foo", "foo"), false); +test('array("one" => 1, "two" => 2))', array("one" => 1, "two" => 2), false); +test('array("kek" => "lol", "lol" => "kek")', array("kek" => "lol", "lol" => "kek"), false); +test('array("" => "empty")', array("" => "empty"), false); + +$a = array('foo'); +test('array($a, $a)', array($a, $a), false); +test('array(&$a, &$a)', array(&$a, &$a), false); + +$a = array(null); +$b = array(&$a); +$a[0] = &$b; + +test('cyclic', $a, true); + +$a = array( + 'a' => array( + 'b' => 'c', + 'd' => 'e' + ), + 'f' => array( + 'g' => 'h' + ) + ); + +test('array', $a, false); + +class Obj { + public $a; + protected $b; + private $c; + + function __construct($a, $b, $c) { + $this->a = $a; + $this->b = $b; + $this->c = $c; + } +} + +test('object', new Obj(1, 2, 3), false); + +test('object', array(new Obj(1, 2, 3), new Obj(4, 5, 6)), false); + +$o = new Obj(1, 2, 3); + +test('object', array(&$o, &$o), false); +--EXPECTF-- +NULL +OK +bool(true) +OK +bool(false) +OK +int(0) +OK +int(1) +OK +int(-1) +OK +int(1000) +OK +int(-1000) +OK +int(100000) +OK +int(-100000) +OK +float(123.456) +OK +string(0) "" +OK +string(6) "foobar" +OK +array(0) { +} +OK +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} +OK +array(3) { + [0]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } + [1]=> + array(3) { + [0]=> + int(4) + [1]=> + int(5) + [2]=> + int(6) + } + [2]=> + array(3) { + [0]=> + int(7) + [1]=> + int(8) + [2]=> + int(9) + } +} +OK +array(3) { + [0]=> + string(3) "foo" + [1]=> + string(3) "foo" + [2]=> + string(3) "foo" +} +OK +array(2) { + ["one"]=> + int(1) + ["two"]=> + int(2) +} +OK +array(2) { + ["kek"]=> + string(3) "lol" + ["lol"]=> + string(3) "kek" +} +OK +array(1) { + [""]=> + string(5) "empty" +} +OK +array(2) { + [0]=> + array(1) { + [0]=> + string(3) "foo" + } + [1]=> + array(1) { + [0]=> + string(3) "foo" + } +} +OK +array(2) { + [0]=> + &array(1) { + [0]=> + string(3) "foo" + } + [1]=> + &array(1) { + [0]=> + string(3) "foo" + } +} +OK +array(1) { + [0]=> + &array(1) { + [0]=> + &array(1) { + [0]=> + &array(1) { + [0]=> + &array(1) { + [0]=> + *RECURSION* + } + } + } + } +} +OK +array(2) { + ["a"]=> + array(2) { + ["b"]=> + string(1) "c" + ["d"]=> + string(1) "e" + } + ["f"]=> + array(1) { + ["g"]=> + string(1) "h" + } +} +OK +object(Obj)#%d (3) { + ["a"]=> + int(1) + ["b:protected"]=> + int(2) + ["c:private"]=> + int(3) +} +OK +array(2) { + [0]=> + object(Obj)#%d (3) { + ["a"]=> + int(1) + ["b:protected"]=> + int(2) + ["c:private"]=> + int(3) + } + [1]=> + object(Obj)#%d (3) { + ["a"]=> + int(4) + ["b:protected"]=> + int(5) + ["c:private"]=> + int(6) + } +} +OK +array(2) { + [0]=> + &object(Obj)#%d (3) { + ["a"]=> + int(1) + ["b:protected"]=> + int(2) + ["c:private"]=> + int(3) + } + [1]=> + &object(Obj)#%d (3) { + ["a"]=> + int(1) + ["b:protected"]=> + int(2) + ["c:private"]=> + int(3) + } +} +OK diff --git a/php/tests/061.phpt b/php/tests/061.phpt index 2b42d31..e67774b 100644 --- a/php/tests/061.phpt +++ b/php/tests/061.phpt @@ -2,8 +2,10 @@ Check for unbuffered streaming unserialization --SKIPIF-- = 0 && + version_compare(PHP_VERSION, '5.3.2') <= 0)) { + echo "skip tests in PHP 5.2.14/5.3.3 or newer"; } --FILE-- = 0) { - echo "skip tests in PHP 5.3.2 or older"; +if ((version_compare(PHP_VERSION, '5.3.0') < 0 && + version_compare(PHP_VERSION, '5.2.14') >= 0) || + (version_compare(PHP_VERSION, '5.3.3') >= 0)) { + echo "skip tests in PHP 5.2.13/5.3.2 or older"; +} +if (version_compare(PHP_VERSION, '5.2.0') < 0) { + echo "skip tests in PHP 5.2 or newer"; } --FILE-- = 0) { + echo "skip tests in PHP 5.1 or older"; +} +--FILE-- +execute($str, $offset)) + { + $unserialized = $unpacker->data(); + var_dump($unserialized); + + $unpacker->reset(); + $str = ""; + $offset = 0; + } + + $i += $len; + } + + if (!is_bool($test)) + { + echo $unserialized === $variable ? 'OK' : 'ERROR', PHP_EOL; + } + else + { + echo $test || $unserialized == $variable ? 'OK' : 'ERROR', PHP_EOL; + } +} + +test('null', null); + +test('boo:l true', true); +test('bool: true', false); + +test('zero: 0', 0); +test('small: 1', 1); +test('small: -1', -1); +test('medium: 1000', 1000); +test('medium: -1000', -1000); +test('large: 100000', 100000); +test('large: -100000', -100000); + +test('double: 123.456', 123.456); + +test('empty: ""', ""); +test('string: "foobar"', "foobar"); + +test('empty: array', array(), false); +test('empty: array(1, 2, 3)', array(1, 2, 3), false); +test('empty: array(array(1, 2, 3), arr...', array(array(1, 2, 3), array(4, 5, 6), array(7, 8, 9)), false); + +test('array("foo", "foo", "foo")', array("foo", "foo", "foo"), false); +test('array("one" => 1, "two" => 2))', array("one" => 1, "two" => 2), false); +test('array("kek" => "lol", "lol" => "kek")', array("kek" => "lol", "lol" => "kek"), false); +test('array("" => "empty")', array("" => "empty"), false); + +$a = array('foo'); +test('array($a, $a)', array($a, $a), false); +test('array(&$a, &$a)', array(&$a, &$a), false); + +$a = array(null); +$b = array(&$a); +$a[0] = &$b; + +test('cyclic', $a, true); + +$a = array( + 'a' => array( + 'b' => 'c', + 'd' => 'e' + ), + 'f' => array( + 'g' => 'h' + ) + ); + +test('array', $a, false); + +class Obj { + public $a; + protected $b; + private $c; + + function __construct($a, $b, $c) { + $this->a = $a; + $this->b = $b; + $this->c = $c; + } +} + +test('object', new Obj(1, 2, 3), false); + +test('object', array(new Obj(1, 2, 3), new Obj(4, 5, 6)), false); + +$o = new Obj(1, 2, 3); + +test('object', array(&$o, &$o), false); +--EXPECTF-- +NULL +OK +bool(true) +OK +bool(false) +OK +int(0) +OK +int(1) +OK +int(-1) +OK +int(1000) +OK +int(-1000) +OK +int(100000) +OK +int(-100000) +OK +float(123.456) +OK +string(0) "" +OK +string(6) "foobar" +OK +array(0) { +} +OK +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} +OK +array(3) { + [0]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } + [1]=> + array(3) { + [0]=> + int(4) + [1]=> + int(5) + [2]=> + int(6) + } + [2]=> + array(3) { + [0]=> + int(7) + [1]=> + int(8) + [2]=> + int(9) + } +} +OK +array(3) { + [0]=> + string(3) "foo" + [1]=> + string(3) "foo" + [2]=> + string(3) "foo" +} +OK +array(2) { + ["one"]=> + int(1) + ["two"]=> + int(2) +} +OK +array(2) { + ["kek"]=> + string(3) "lol" + ["lol"]=> + string(3) "kek" +} +OK +array(1) { + [""]=> + string(5) "empty" +} +OK +array(2) { + [0]=> + array(1) { + [0]=> + string(3) "foo" + } + [1]=> + array(1) { + [0]=> + string(3) "foo" + } +} +OK +array(2) { + [0]=> + &array(1) { + [0]=> + string(3) "foo" + } + [1]=> + &array(1) { + [0]=> + string(3) "foo" + } +} +OK +array(1) { + [0]=> + &array(1) { + [0]=> + &array(1) { + [0]=> + &array(1) { + [0]=> + &array(1) { + [0]=> + *RECURSION* + } + } + } + } +} +OK +array(2) { + ["a"]=> + array(2) { + ["b"]=> + string(1) "c" + ["d"]=> + string(1) "e" + } + ["f"]=> + array(1) { + ["g"]=> + string(1) "h" + } +} +OK +object(Obj)#%d (3) { + ["a"]=> + int(1) + ["b:protected"]=> + int(2) + ["c:private"]=> + int(3) +} +OK +array(2) { + [0]=> + object(Obj)#%d (3) { + ["a"]=> + int(1) + ["b:protected"]=> + int(2) + ["c:private"]=> + int(3) + } + [1]=> + object(Obj)#%d (3) { + ["a"]=> + int(4) + ["b:protected"]=> + int(5) + ["c:private"]=> + int(6) + } +} +OK +array(2) { + [0]=> + &object(Obj)#%d (3) { + ["a"]=> + int(1) + ["b:protected"]=> + int(2) + ["c:private"]=> + int(3) + } + [1]=> + &object(Obj)#%d (3) { + ["a"]=> + int(1) + ["b:protected"]=> + int(2) + ["c:private"]=> + int(3) + } +} +OK diff --git a/php/tests/064.phpt b/php/tests/064.phpt index a7a2f3b..bbaffe9 100644 --- a/php/tests/064.phpt +++ b/php/tests/064.phpt @@ -2,8 +2,10 @@ Check for buffered streaming unserialization (single) --SKIPIF-- = 0 && + version_compare(PHP_VERSION, '5.3.2') <= 0)) { + echo "skip tests in PHP 5.2.14/5.3.3 or newer"; } --FILE-- = 0) { - echo "skip tests in PHP 5.3.2 or older"; +if ((version_compare(PHP_VERSION, '5.3.0') < 0 && + version_compare(PHP_VERSION, '5.2.14') >= 0) || + (version_compare(PHP_VERSION, '5.3.3') >= 0)) { + echo "skip tests in PHP 5.2.13/5.3.2 or older"; +} +if (version_compare(PHP_VERSION, '5.2.0') < 0) { + echo "skip tests in PHP 5.2 or newer"; } --FILE-- = 0) { + echo "skip tests in PHP 5.1 or older"; +} +--FILE-- +feed($str); + if ($unpacker->execute()) + { + $unserialized = $unpacker->data(); + var_dump($unserialized); + $unpacker->reset(); + } + + $i += $len; + } + + if (!is_bool($test)) + { + echo $unserialized === $variable ? 'OK' : 'ERROR', PHP_EOL; + } + else + { + echo $test || $unserialized == $variable ? 'OK' : 'ERROR', PHP_EOL; + } +} + +test('null', null); + +test('bool: true', true); +test('bool: false', false); + +test('zero: 0', 0); +test('small: 1', 1); +test('small: -1', -1); +test('medium: 1000', 1000); +test('medium: -1000', -1000); +test('large: 100000', 100000); +test('large: -100000', -100000); + +test('double: 123.456', 123.456); + +test('empty: ""', ""); +test('string: "foobar"', "foobar"); + +test('array', array(), false); +test('array(1, 2, 3)', array(1, 2, 3), false); +test('array(array(1, 2, 3), arr...', array(array(1, 2, 3), array(4, 5, 6), array(7, 8, 9)), false); + +test('array("foo", "foo", "foo")', array("foo", "foo", "foo"), false); +test('array("one" => 1, "two" => 2))', array("one" => 1, "two" => 2), false); +test('array("kek" => "lol", "lol" => "kek")', array("kek" => "lol", "lol" => "kek"), false); +test('array("" => "empty")', array("" => "empty"), false); + +$a = array('foo'); +test('array($a, $a)', array($a, $a), false); +test('array(&$a, &$a)', array(&$a, &$a), false); + +$a = array(null); +$b = array(&$a); +$a[0] = &$b; + +test('cyclic', $a, true); + +$a = array( + 'a' => array( + 'b' => 'c', + 'd' => 'e' + ), + 'f' => array( + 'g' => 'h' + ) + ); + +test('array', $a, false); + +class Obj { + public $a; + protected $b; + private $c; + + function __construct($a, $b, $c) { + $this->a = $a; + $this->b = $b; + $this->c = $c; + } +} + +test('object', new Obj(1, 2, 3), false); + +test('object', array(new Obj(1, 2, 3), new Obj(4, 5, 6)), false); + +$o = new Obj(1, 2, 3); + +test('object', array(&$o, &$o), false); +--EXPECTF-- +NULL +OK +bool(true) +OK +bool(false) +OK +int(0) +OK +int(1) +OK +int(-1) +OK +int(1000) +OK +int(-1000) +OK +int(100000) +OK +int(-100000) +OK +float(123.456) +OK +string(0) "" +OK +string(6) "foobar" +OK +array(0) { +} +OK +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} +OK +array(3) { + [0]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } + [1]=> + array(3) { + [0]=> + int(4) + [1]=> + int(5) + [2]=> + int(6) + } + [2]=> + array(3) { + [0]=> + int(7) + [1]=> + int(8) + [2]=> + int(9) + } +} +OK +array(3) { + [0]=> + string(3) "foo" + [1]=> + string(3) "foo" + [2]=> + string(3) "foo" +} +OK +array(2) { + ["one"]=> + int(1) + ["two"]=> + int(2) +} +OK +array(2) { + ["kek"]=> + string(3) "lol" + ["lol"]=> + string(3) "kek" +} +OK +array(1) { + [""]=> + string(5) "empty" +} +OK +array(2) { + [0]=> + array(1) { + [0]=> + string(3) "foo" + } + [1]=> + array(1) { + [0]=> + string(3) "foo" + } +} +OK +array(2) { + [0]=> + &array(1) { + [0]=> + string(3) "foo" + } + [1]=> + &array(1) { + [0]=> + string(3) "foo" + } +} +OK +array(1) { + [0]=> + &array(1) { + [0]=> + &array(1) { + [0]=> + &array(1) { + [0]=> + &array(1) { + [0]=> + *RECURSION* + } + } + } + } +} +OK +array(2) { + ["a"]=> + array(2) { + ["b"]=> + string(1) "c" + ["d"]=> + string(1) "e" + } + ["f"]=> + array(1) { + ["g"]=> + string(1) "h" + } +} +OK +object(Obj)#%d (3) { + ["a"]=> + int(1) + ["b:protected"]=> + int(2) + ["c:private"]=> + int(3) +} +OK +array(2) { + [0]=> + object(Obj)#%d (3) { + ["a"]=> + int(1) + ["b:protected"]=> + int(2) + ["c:private"]=> + int(3) + } + [1]=> + object(Obj)#%d (3) { + ["a"]=> + int(4) + ["b:protected"]=> + int(5) + ["c:private"]=> + int(6) + } +} +OK +array(2) { + [0]=> + &object(Obj)#%d (3) { + ["a"]=> + int(1) + ["b:protected"]=> + int(2) + ["c:private"]=> + int(3) + } + [1]=> + &object(Obj)#%d (3) { + ["a"]=> + int(1) + ["b:protected"]=> + int(2) + ["c:private"]=> + int(3) + } +} +OK diff --git a/php/tests/065.phpt b/php/tests/065.phpt index c37ca12..8139f24 100644 --- a/php/tests/065.phpt +++ b/php/tests/065.phpt @@ -2,8 +2,10 @@ Check for unbuffered streaming unserialization (single) --SKIPIF-- = 0 && + version_compare(PHP_VERSION, '5.3.2') <= 0)) { + echo "skip tests in PHP 5.2.14/5.3.3 or newer"; } --FILE-- = 0) { - echo "skip tests in PHP 5.3.2 or older"; +if ((version_compare(PHP_VERSION, '5.3.0') < 0 && + version_compare(PHP_VERSION, '5.2.14') >= 0) || + (version_compare(PHP_VERSION, '5.3.3') >= 0)) { + echo "skip tests in PHP 5.2.13/5.3.2 or older"; +} +if (version_compare(PHP_VERSION, '5.2.0') < 0) { + echo "skip tests in PHP 5.2 or newer"; } --FILE-- = 0) { + echo "skip tests in PHP 5.1 or older"; +} +--FILE-- +execute($str, $offset)) + { + $unserialized = $unpacker->data(); + var_dump($unserialized); + + $unpacker->reset(); + $str = ""; + $offset = 0; + } + + $i += $len; + } + + if (!is_bool($test)) + { + echo $unserialized === $variable ? 'OK' : 'ERROR', PHP_EOL; + } + else + { + echo $test || $unserialized == $variable ? 'OK' : 'ERROR', PHP_EOL; + } +} + +test('null', null); + +test('boo:l true', true); +test('bool: true', false); + +test('zero: 0', 0); +test('small: 1', 1); +test('small: -1', -1); +test('medium: 1000', 1000); +test('medium: -1000', -1000); +test('large: 100000', 100000); +test('large: -100000', -100000); + +test('double: 123.456', 123.456); + +test('empty: ""', ""); +test('string: "foobar"', "foobar"); + +test('empty: array', array(), false); +test('empty: array(1, 2, 3)', array(1, 2, 3), false); +test('empty: array(array(1, 2, 3), arr...', array(array(1, 2, 3), array(4, 5, 6), array(7, 8, 9)), false); + +test('array("foo", "foo", "foo")', array("foo", "foo", "foo"), false); +test('array("one" => 1, "two" => 2))', array("one" => 1, "two" => 2), false); +test('array("kek" => "lol", "lol" => "kek")', array("kek" => "lol", "lol" => "kek"), false); +test('array("" => "empty")', array("" => "empty"), false); + +$a = array('foo'); +test('array($a, $a)', array($a, $a), false); +test('array(&$a, &$a)', array(&$a, &$a), false); + +$a = array(null); +$b = array(&$a); +$a[0] = &$b; + +test('cyclic', $a, true); + +$a = array( + 'a' => array( + 'b' => 'c', + 'd' => 'e' + ), + 'f' => array( + 'g' => 'h' + ) + ); + +test('array', $a, false); + +class Obj { + public $a; + protected $b; + private $c; + + function __construct($a, $b, $c) { + $this->a = $a; + $this->b = $b; + $this->c = $c; + } +} + +test('object', new Obj(1, 2, 3), false); + +test('object', array(new Obj(1, 2, 3), new Obj(4, 5, 6)), false); + +$o = new Obj(1, 2, 3); + +test('object', array(&$o, &$o), false); +--EXPECTF-- +NULL +OK +bool(true) +OK +bool(false) +OK +int(0) +OK +int(1) +OK +int(-1) +OK +int(1000) +OK +int(-1000) +OK +int(100000) +OK +int(-100000) +OK +float(123.456) +OK +string(0) "" +OK +string(6) "foobar" +OK +array(0) { +} +OK +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} +OK +array(3) { + [0]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } + [1]=> + array(3) { + [0]=> + int(4) + [1]=> + int(5) + [2]=> + int(6) + } + [2]=> + array(3) { + [0]=> + int(7) + [1]=> + int(8) + [2]=> + int(9) + } +} +OK +array(3) { + [0]=> + string(3) "foo" + [1]=> + string(3) "foo" + [2]=> + string(3) "foo" +} +OK +array(2) { + ["one"]=> + int(1) + ["two"]=> + int(2) +} +OK +array(2) { + ["kek"]=> + string(3) "lol" + ["lol"]=> + string(3) "kek" +} +OK +array(1) { + [""]=> + string(5) "empty" +} +OK +array(2) { + [0]=> + array(1) { + [0]=> + string(3) "foo" + } + [1]=> + array(1) { + [0]=> + string(3) "foo" + } +} +OK +array(2) { + [0]=> + &array(1) { + [0]=> + string(3) "foo" + } + [1]=> + &array(1) { + [0]=> + string(3) "foo" + } +} +OK +array(1) { + [0]=> + &array(1) { + [0]=> + &array(1) { + [0]=> + &array(1) { + [0]=> + &array(1) { + [0]=> + *RECURSION* + } + } + } + } +} +OK +array(2) { + ["a"]=> + array(2) { + ["b"]=> + string(1) "c" + ["d"]=> + string(1) "e" + } + ["f"]=> + array(1) { + ["g"]=> + string(1) "h" + } +} +OK +object(Obj)#%d (3) { + ["a"]=> + int(1) + ["b:protected"]=> + int(2) + ["c:private"]=> + int(3) +} +OK +array(2) { + [0]=> + object(Obj)#%d (3) { + ["a"]=> + int(1) + ["b:protected"]=> + int(2) + ["c:private"]=> + int(3) + } + [1]=> + object(Obj)#%d (3) { + ["a"]=> + int(4) + ["b:protected"]=> + int(5) + ["c:private"]=> + int(6) + } +} +OK +array(2) { + [0]=> + &object(Obj)#%d (3) { + ["a"]=> + int(1) + ["b:protected"]=> + int(2) + ["c:private"]=> + int(3) + } + [1]=> + &object(Obj)#%d (3) { + ["a"]=> + int(1) + ["b:protected"]=> + int(2) + ["c:private"]=> + int(3) + } +} +OK diff --git a/php/tests/070.phpt b/php/tests/070.phpt index affcc72..fd915fd 100644 --- a/php/tests/070.phpt +++ b/php/tests/070.phpt @@ -2,8 +2,10 @@ Check for alias functions --SKIPIF-- = 0 && + version_compare(PHP_VERSION, '5.3.2') <= 0)) { + echo "skip tests in PHP 5.2.14/5.3.3 or newer"; } --FILE-- = 0) { - echo "skip tests in PHP 5.3.2 or older"; +if ((version_compare(PHP_VERSION, '5.3.0') < 0 && + version_compare(PHP_VERSION, '5.2.14') >= 0) || + (version_compare(PHP_VERSION, '5.3.3') >= 0)) { + echo "skip tests in PHP 5.2.13/5.3.2 or older"; +} +if (version_compare(PHP_VERSION, '5.2.0') < 0) { + echo "skip tests in PHP 5.2 or newer"; } --FILE-- = 0) { + echo "skip tests in PHP 5.1 or older"; +} +--FILE-- + 1, "two" => 2))', array("one" => 1, "two" => 2), false); +test('array("kek" => "lol", "lol" => "kek")', array("kek" => "lol", "lol" => "kek"), false); +test('array("" => "empty")', array("" => "empty"), false); + +$a = array('foo'); +test('array($a, $a)', array($a, $a), false); +test('array(&$a, &$a)', array(&$a, &$a), false); + +$a = array(null); +$b = array(&$a); +$a[0] = &$b; + +test('cyclic', $a, true); + +$a = array( + 'a' => array( + 'b' => 'c', + 'd' => 'e' + ), + 'f' => array( + 'g' => 'h' + ) + ); + +test('array', $a, false); + +class Obj { + public $a; + protected $b; + private $c; + + function __construct($a, $b, $c) { + $this->a = $a; + $this->b = $b; + $this->c = $c; + } +} + +test('object', new Obj(1, 2, 3), false); + +test('object', array(new Obj(1, 2, 3), new Obj(4, 5, 6)), false); + +$o = new Obj(1, 2, 3); + +test('object', array(&$o, &$o), false); +--EXPECTF-- +NULL +OK +bool(true) +OK +bool(false) +OK +int(0) +OK +int(1) +OK +int(-1) +OK +int(1000) +OK +int(-1000) +OK +int(100000) +OK +int(-100000) +OK +float(123.456) +OK +string(0) "" +OK +string(6) "foobar" +OK +array(0) { +} +OK +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} +OK +array(3) { + [0]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } + [1]=> + array(3) { + [0]=> + int(4) + [1]=> + int(5) + [2]=> + int(6) + } + [2]=> + array(3) { + [0]=> + int(7) + [1]=> + int(8) + [2]=> + int(9) + } +} +OK +array(3) { + [0]=> + string(3) "foo" + [1]=> + string(3) "foo" + [2]=> + string(3) "foo" +} +OK +array(2) { + ["one"]=> + int(1) + ["two"]=> + int(2) +} +OK +array(2) { + ["kek"]=> + string(3) "lol" + ["lol"]=> + string(3) "kek" +} +OK +array(1) { + [""]=> + string(5) "empty" +} +OK +array(2) { + [0]=> + array(1) { + [0]=> + string(3) "foo" + } + [1]=> + array(1) { + [0]=> + string(3) "foo" + } +} +OK +array(2) { + [0]=> + &array(1) { + [0]=> + string(3) "foo" + } + [1]=> + &array(1) { + [0]=> + string(3) "foo" + } +} +OK +array(1) { + [0]=> + &array(1) { + [0]=> + &array(1) { + [0]=> + &array(1) { + [0]=> + &array(1) { + [0]=> + *RECURSION* + } + } + } + } +} +OK +array(2) { + ["a"]=> + array(2) { + ["b"]=> + string(1) "c" + ["d"]=> + string(1) "e" + } + ["f"]=> + array(1) { + ["g"]=> + string(1) "h" + } +} +OK +object(Obj)#%d (3) { + ["a"]=> + int(1) + ["b:protected"]=> + int(2) + ["c:private"]=> + int(3) +} +OK +array(2) { + [0]=> + object(Obj)#%d (3) { + ["a"]=> + int(1) + ["b:protected"]=> + int(2) + ["c:private"]=> + int(3) + } + [1]=> + object(Obj)#%d (3) { + ["a"]=> + int(4) + ["b:protected"]=> + int(5) + ["c:private"]=> + int(6) + } +} +OK +array(2) { + [0]=> + &object(Obj)#%d (3) { + ["a"]=> + int(1) + ["b:protected"]=> + int(2) + ["c:private"]=> + int(3) + } + [1]=> + &object(Obj)#%d (3) { + ["a"]=> + int(1) + ["b:protected"]=> + int(2) + ["c:private"]=> + int(3) + } +} +OK diff --git a/php/tests/071.phpt b/php/tests/071.phpt index 20041d4..bc64c60 100644 --- a/php/tests/071.phpt +++ b/php/tests/071.phpt @@ -2,8 +2,10 @@ Check for class methods --SKIPIF-- = 0 && + version_compare(PHP_VERSION, '5.3.2') <= 0)) { + echo "skip tests in PHP 5.2.14/5.3.3 or newer"; } --FILE-- = 0) { - echo "skip tests in PHP 5.3.2 or older"; +if ((version_compare(PHP_VERSION, '5.3.0') < 0 && + version_compare(PHP_VERSION, '5.2.14') >= 0) || + (version_compare(PHP_VERSION, '5.3.3') >= 0)) { + echo "skip tests in PHP 5.2.13/5.3.2 or older"; +} +if (version_compare(PHP_VERSION, '5.2.0') < 0) { + echo "skip tests in PHP 5.2 or newer"; } --FILE-- = 0) { + echo "skip tests in PHP 5.1 or older"; +} +--FILE-- +pack($variable); + $unserialized = $msgpack->unpack($serialized); + + var_dump($unserialized); + + if (!is_bool($test)) + { + echo $unserialized === $variable ? 'OK' : 'ERROR', PHP_EOL; + } + else + { + echo $test || $unserialized == $variable ? 'OK' : 'ERROR', PHP_EOL; + } +} + +test('null', null); + +test('boo:l true', true); +test('bool: true', false); + +test('zero: 0', 0); +test('small: 1', 1); +test('small: -1', -1); +test('medium: 1000', 1000); +test('medium: -1000', -1000); +test('large: 100000', 100000); +test('large: -100000', -100000); + +test('double: 123.456', 123.456); + +test('empty: ""', ""); +test('string: "foobar"', "foobar"); + +test('empty: array', array(), false); +test('empty: array(1, 2, 3)', array(1, 2, 3), false); +test('empty: array(array(1, 2, 3), arr...', array(array(1, 2, 3), array(4, 5, 6), array(7, 8, 9)), false); + +test('array("foo", "foo", "foo")', array("foo", "foo", "foo"), false); +test('array("one" => 1, "two" => 2))', array("one" => 1, "two" => 2), false); +test('array("kek" => "lol", "lol" => "kek")', array("kek" => "lol", "lol" => "kek"), false); +test('array("" => "empty")', array("" => "empty"), false); + +$a = array('foo'); +test('array($a, $a)', array($a, $a), false); +test('array(&$a, &$a)', array(&$a, &$a), false); + +$a = array(null); +$b = array(&$a); +$a[0] = &$b; + +test('cyclic', $a, true); + +$a = array( + 'a' => array( + 'b' => 'c', + 'd' => 'e' + ), + 'f' => array( + 'g' => 'h' + ) + ); + +test('array', $a, false); + +class Obj { + public $a; + protected $b; + private $c; + + function __construct($a, $b, $c) { + $this->a = $a; + $this->b = $b; + $this->c = $c; + } +} + +test('object', new Obj(1, 2, 3), false); + +test('object', array(new Obj(1, 2, 3), new Obj(4, 5, 6)), false); + +$o = new Obj(1, 2, 3); + +test('object', array(&$o, &$o), false); +--EXPECTF-- +NULL +OK +bool(true) +OK +bool(false) +OK +int(0) +OK +int(1) +OK +int(-1) +OK +int(1000) +OK +int(-1000) +OK +int(100000) +OK +int(-100000) +OK +float(123.456) +OK +string(0) "" +OK +string(6) "foobar" +OK +array(0) { +} +OK +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} +OK +array(3) { + [0]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } + [1]=> + array(3) { + [0]=> + int(4) + [1]=> + int(5) + [2]=> + int(6) + } + [2]=> + array(3) { + [0]=> + int(7) + [1]=> + int(8) + [2]=> + int(9) + } +} +OK +array(3) { + [0]=> + string(3) "foo" + [1]=> + string(3) "foo" + [2]=> + string(3) "foo" +} +OK +array(2) { + ["one"]=> + int(1) + ["two"]=> + int(2) +} +OK +array(2) { + ["kek"]=> + string(3) "lol" + ["lol"]=> + string(3) "kek" +} +OK +array(1) { + [""]=> + string(5) "empty" +} +OK +array(2) { + [0]=> + array(1) { + [0]=> + string(3) "foo" + } + [1]=> + array(1) { + [0]=> + string(3) "foo" + } +} +OK +array(2) { + [0]=> + &array(1) { + [0]=> + string(3) "foo" + } + [1]=> + &array(1) { + [0]=> + string(3) "foo" + } +} +OK +array(1) { + [0]=> + &array(1) { + [0]=> + &array(1) { + [0]=> + &array(1) { + [0]=> + &array(1) { + [0]=> + *RECURSION* + } + } + } + } +} +OK +array(2) { + ["a"]=> + array(2) { + ["b"]=> + string(1) "c" + ["d"]=> + string(1) "e" + } + ["f"]=> + array(1) { + ["g"]=> + string(1) "h" + } +} +OK +object(Obj)#%d (3) { + ["a"]=> + int(1) + ["b:protected"]=> + int(2) + ["c:private"]=> + int(3) +} +OK +array(2) { + [0]=> + object(Obj)#%d (3) { + ["a"]=> + int(1) + ["b:protected"]=> + int(2) + ["c:private"]=> + int(3) + } + [1]=> + object(Obj)#%d (3) { + ["a"]=> + int(4) + ["b:protected"]=> + int(5) + ["c:private"]=> + int(6) + } +} +OK +array(2) { + [0]=> + &object(Obj)#%d (3) { + ["a"]=> + int(1) + ["b:protected"]=> + int(2) + ["c:private"]=> + int(3) + } + [1]=> + &object(Obj)#%d (3) { + ["a"]=> + int(1) + ["b:protected"]=> + int(2) + ["c:private"]=> + int(3) + } +} +OK diff --git a/php/tests/072.phpt b/php/tests/072.phpt index 0f89e0a..348bd34 100644 --- a/php/tests/072.phpt +++ b/php/tests/072.phpt @@ -2,8 +2,10 @@ Check for class methods unpacker --SKIPIF-- = 0 && + version_compare(PHP_VERSION, '5.3.2') <= 0)) { + echo "skip tests in PHP 5.2.14/5.3.3 or newer"; } --FILE-- = 0) { - echo "skip tests in PHP 5.3.2 or older"; +if ((version_compare(PHP_VERSION, '5.3.0') < 0 && + version_compare(PHP_VERSION, '5.2.14') >= 0) || + (version_compare(PHP_VERSION, '5.3.3') >= 0)) { + echo "skip tests in PHP 5.2.13/5.3.2 or older"; +} +if (version_compare(PHP_VERSION, '5.2.0') < 0) { + echo "skip tests in PHP 5.2 or newer"; } --FILE-- = 0) { + echo "skip tests in PHP 5.1 or older"; +} +--FILE-- +pack($variable); + $unpacker = $msgpack->unpacker(); + + $length = strlen($serialized); + + if (rand(0, 1)) + { + for ($i = 0; $i < $length;) { + $len = rand(1, 10); + $str = substr($serialized, $i, $len); + + $unpacker->feed($str); + if ($unpacker->execute()) + { + $unserialized = $unpacker->data(); + var_dump($unserialized); + $unpacker->reset(); + } + + $i += $len; + } + } + else + { + $str = ""; + $offset = 0; + + for ($i = 0; $i < $length;) { + $len = rand(1, 10); + $str .= substr($serialized, $i, $len); + + if ($unpacker->execute($str, $offset)) + { + $unserialized = $unpacker->data(); + var_dump($unserialized); + + $unpacker->reset(); + $str = ""; + $offset = 0; + } + + $i += $len; + } + } + + if (!is_bool($test)) + { + echo $unserialized === $variable ? 'OK' : 'ERROR', PHP_EOL; + } + else + { + echo $test || $unserialized == $variable ? 'OK' : 'ERROR', PHP_EOL; + } +} + +test('null', null); + +test('boo:l true', true); +test('bool: true', false); + +test('zero: 0', 0); +test('small: 1', 1); +test('small: -1', -1); +test('medium: 1000', 1000); +test('medium: -1000', -1000); +test('large: 100000', 100000); +test('large: -100000', -100000); + +test('double: 123.456', 123.456); + +test('empty: ""', ""); +test('string: "foobar"', "foobar"); + +test('empty: array', array(), false); +test('empty: array(1, 2, 3)', array(1, 2, 3), false); +test('empty: array(array(1, 2, 3), arr...', array(array(1, 2, 3), array(4, 5, 6), array(7, 8, 9)), false); + +test('array("foo", "foo", "foo")', array("foo", "foo", "foo"), false); +test('array("one" => 1, "two" => 2))', array("one" => 1, "two" => 2), false); +test('array("kek" => "lol", "lol" => "kek")', array("kek" => "lol", "lol" => "kek"), false); +test('array("" => "empty")', array("" => "empty"), false); + +$a = array('foo'); +test('array($a, $a)', array($a, $a), false); +test('array(&$a, &$a)', array(&$a, &$a), false); + +$a = array(null); +$b = array(&$a); +$a[0] = &$b; + +test('cyclic', $a, true); + +$a = array( + 'a' => array( + 'b' => 'c', + 'd' => 'e' + ), + 'f' => array( + 'g' => 'h' + ) + ); + +test('array', $a, false); + +class Obj { + public $a; + protected $b; + private $c; + + function __construct($a, $b, $c) { + $this->a = $a; + $this->b = $b; + $this->c = $c; + } +} + +test('object', new Obj(1, 2, 3), false); + +test('object', array(new Obj(1, 2, 3), new Obj(4, 5, 6)), false); + +$o = new Obj(1, 2, 3); + +test('object', array(&$o, &$o), false); +--EXPECTF-- +NULL +OK +bool(true) +OK +bool(false) +OK +int(0) +OK +int(1) +OK +int(-1) +OK +int(1000) +OK +int(-1000) +OK +int(100000) +OK +int(-100000) +OK +float(123.456) +OK +string(0) "" +OK +string(6) "foobar" +OK +array(0) { +} +OK +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} +OK +array(3) { + [0]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } + [1]=> + array(3) { + [0]=> + int(4) + [1]=> + int(5) + [2]=> + int(6) + } + [2]=> + array(3) { + [0]=> + int(7) + [1]=> + int(8) + [2]=> + int(9) + } +} +OK +array(3) { + [0]=> + string(3) "foo" + [1]=> + string(3) "foo" + [2]=> + string(3) "foo" +} +OK +array(2) { + ["one"]=> + int(1) + ["two"]=> + int(2) +} +OK +array(2) { + ["kek"]=> + string(3) "lol" + ["lol"]=> + string(3) "kek" +} +OK +array(1) { + [""]=> + string(5) "empty" +} +OK +array(2) { + [0]=> + array(1) { + [0]=> + string(3) "foo" + } + [1]=> + array(1) { + [0]=> + string(3) "foo" + } +} +OK +array(2) { + [0]=> + &array(1) { + [0]=> + string(3) "foo" + } + [1]=> + &array(1) { + [0]=> + string(3) "foo" + } +} +OK +array(1) { + [0]=> + &array(1) { + [0]=> + &array(1) { + [0]=> + &array(1) { + [0]=> + &array(1) { + [0]=> + *RECURSION* + } + } + } + } +} +OK +array(2) { + ["a"]=> + array(2) { + ["b"]=> + string(1) "c" + ["d"]=> + string(1) "e" + } + ["f"]=> + array(1) { + ["g"]=> + string(1) "h" + } +} +OK +object(Obj)#%d (3) { + ["a"]=> + int(1) + ["b:protected"]=> + int(2) + ["c:private"]=> + int(3) +} +OK +array(2) { + [0]=> + object(Obj)#%d (3) { + ["a"]=> + int(1) + ["b:protected"]=> + int(2) + ["c:private"]=> + int(3) + } + [1]=> + object(Obj)#%d (3) { + ["a"]=> + int(4) + ["b:protected"]=> + int(5) + ["c:private"]=> + int(6) + } +} +OK +array(2) { + [0]=> + &object(Obj)#%d (3) { + ["a"]=> + int(1) + ["b:protected"]=> + int(2) + ["c:private"]=> + int(3) + } + [1]=> + &object(Obj)#%d (3) { + ["a"]=> + int(1) + ["b:protected"]=> + int(2) + ["c:private"]=> + int(3) + } +} +OK diff --git a/php/tests/073.phpt b/php/tests/073.phpt index f6a91a6..c1eb9f4 100644 --- a/php/tests/073.phpt +++ b/php/tests/073.phpt @@ -2,8 +2,10 @@ Check for class unpacker --SKIPIF-- = 0 && + version_compare(PHP_VERSION, '5.3.2') <= 0)) { + echo "skip tests in PHP 5.2.14/5.3.3 or newer"; } --FILE-- = 0) { - echo "skip tests in PHP 5.3.2 or older"; +if ((version_compare(PHP_VERSION, '5.3.0') < 0 && + version_compare(PHP_VERSION, '5.2.14') >= 0) || + (version_compare(PHP_VERSION, '5.3.3') >= 0)) { + echo "skip tests in PHP 5.2.13/5.3.2 or older"; +} +if (version_compare(PHP_VERSION, '5.2.0') < 0) { + echo "skip tests in PHP 5.2 or newer"; } --FILE-- = 0) { + echo "skip tests in PHP 5.1 or older"; +} +--FILE-- +pack($variable); + + $unpacker = new MessagePackUnpacker(); + + $length = strlen($serialized); + + if (rand(0, 1)) + { + for ($i = 0; $i < $length;) { + $len = rand(1, 10); + $str = substr($serialized, $i, $len); + + $unpacker->feed($str); + if ($unpacker->execute()) + { + $unserialized = $unpacker->data(); + var_dump($unserialized); + $unpacker->reset(); + } + + $i += $len; + } + } + else + { + $str = ""; + $offset = 0; + + for ($i = 0; $i < $length;) { + $len = rand(1, 10); + $str .= substr($serialized, $i, $len); + + if ($unpacker->execute($str, $offset)) + { + $unserialized = $unpacker->data(); + var_dump($unserialized); + + $unpacker->reset(); + $str = ""; + $offset = 0; + } + + $i += $len; + } + } + + if (!is_bool($test)) + { + echo $unserialized === $variable ? 'OK' : 'ERROR', PHP_EOL; + } + else + { + echo $test || $unserialized == $variable ? 'OK' : 'ERROR', PHP_EOL; + } +} + +test('null', null); + +test('boo:l true', true); +test('bool: true', false); + +test('zero: 0', 0); +test('small: 1', 1); +test('small: -1', -1); +test('medium: 1000', 1000); +test('medium: -1000', -1000); +test('large: 100000', 100000); +test('large: -100000', -100000); + +test('double: 123.456', 123.456); + +test('empty: ""', ""); +test('string: "foobar"', "foobar"); + +test('empty: array', array(), false); +test('empty: array(1, 2, 3)', array(1, 2, 3), false); +test('empty: array(array(1, 2, 3), arr...', array(array(1, 2, 3), array(4, 5, 6), array(7, 8, 9)), false); + +test('array("foo", "foo", "foo")', array("foo", "foo", "foo"), false); +test('array("one" => 1, "two" => 2))', array("one" => 1, "two" => 2), false); +test('array("kek" => "lol", "lol" => "kek")', array("kek" => "lol", "lol" => "kek"), false); +test('array("" => "empty")', array("" => "empty"), false); + +$a = array('foo'); +test('array($a, $a)', array($a, $a), false); +test('array(&$a, &$a)', array(&$a, &$a), false); + +$a = array(null); +$b = array(&$a); +$a[0] = &$b; + +test('cyclic', $a, true); + +$a = array( + 'a' => array( + 'b' => 'c', + 'd' => 'e' + ), + 'f' => array( + 'g' => 'h' + ) + ); + +test('array', $a, false); + +class Obj { + public $a; + protected $b; + private $c; + + function __construct($a, $b, $c) { + $this->a = $a; + $this->b = $b; + $this->c = $c; + } +} + +test('object', new Obj(1, 2, 3), false); + +test('object', array(new Obj(1, 2, 3), new Obj(4, 5, 6)), false); + +$o = new Obj(1, 2, 3); + +test('object', array(&$o, &$o), false); +--EXPECTF-- +NULL +OK +bool(true) +OK +bool(false) +OK +int(0) +OK +int(1) +OK +int(-1) +OK +int(1000) +OK +int(-1000) +OK +int(100000) +OK +int(-100000) +OK +float(123.456) +OK +string(0) "" +OK +string(6) "foobar" +OK +array(0) { +} +OK +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} +OK +array(3) { + [0]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } + [1]=> + array(3) { + [0]=> + int(4) + [1]=> + int(5) + [2]=> + int(6) + } + [2]=> + array(3) { + [0]=> + int(7) + [1]=> + int(8) + [2]=> + int(9) + } +} +OK +array(3) { + [0]=> + string(3) "foo" + [1]=> + string(3) "foo" + [2]=> + string(3) "foo" +} +OK +array(2) { + ["one"]=> + int(1) + ["two"]=> + int(2) +} +OK +array(2) { + ["kek"]=> + string(3) "lol" + ["lol"]=> + string(3) "kek" +} +OK +array(1) { + [""]=> + string(5) "empty" +} +OK +array(2) { + [0]=> + array(1) { + [0]=> + string(3) "foo" + } + [1]=> + array(1) { + [0]=> + string(3) "foo" + } +} +OK +array(2) { + [0]=> + &array(1) { + [0]=> + string(3) "foo" + } + [1]=> + &array(1) { + [0]=> + string(3) "foo" + } +} +OK +array(1) { + [0]=> + &array(1) { + [0]=> + &array(1) { + [0]=> + &array(1) { + [0]=> + &array(1) { + [0]=> + *RECURSION* + } + } + } + } +} +OK +array(2) { + ["a"]=> + array(2) { + ["b"]=> + string(1) "c" + ["d"]=> + string(1) "e" + } + ["f"]=> + array(1) { + ["g"]=> + string(1) "h" + } +} +OK +object(Obj)#%d (3) { + ["a"]=> + int(1) + ["b:protected"]=> + int(2) + ["c:private"]=> + int(3) +} +OK +array(2) { + [0]=> + object(Obj)#%d (3) { + ["a"]=> + int(1) + ["b:protected"]=> + int(2) + ["c:private"]=> + int(3) + } + [1]=> + object(Obj)#%d (3) { + ["a"]=> + int(4) + ["b:protected"]=> + int(5) + ["c:private"]=> + int(6) + } +} +OK +array(2) { + [0]=> + &object(Obj)#%d (3) { + ["a"]=> + int(1) + ["b:protected"]=> + int(2) + ["c:private"]=> + int(3) + } + [1]=> + &object(Obj)#%d (3) { + ["a"]=> + int(1) + ["b:protected"]=> + int(2) + ["c:private"]=> + int(3) + } +} +OK diff --git a/php/tests/087.phpt b/php/tests/087.phpt index 9bb4e49..a7386a1 100644 --- a/php/tests/087.phpt +++ b/php/tests/087.phpt @@ -1,6 +1,10 @@ --TEST-- disabled php only for class methods (set option) --SKIPIF-- += 0) { + echo "skip tests in PHP 5.0 or older"; +} +--FILE-- +setOption(MESSAGEPACK_OPT_PHPONLY, false); + + $serialized = $msgpack->pack($variable); + $unserialized = $msgpack->unpack($serialized); + + var_dump($unserialized); + + if (!is_bool($test)) + { + echo $unserialized === $variable ? 'OK' : 'ERROR', PHP_EOL; + } + else + { + echo $test || $unserialized == $variable ? 'OK' : 'ERROR', PHP_EOL; + } +} + +test('null', null); + +test('boo:l true', true); +test('bool: true', false); + +test('zero: 0', 0); +test('small: 1', 1); +test('small: -1', -1); +test('medium: 1000', 1000); +test('medium: -1000', -1000); +test('large: 100000', 100000); +test('large: -100000', -100000); + +test('double: 123.456', 123.456); + +test('empty: ""', ""); +test('string: "foobar"', "foobar"); + +test('empty: array', array(), false); +test('empty: array(1, 2, 3)', array(1, 2, 3), false); +test('empty: array(array(1, 2, 3), arr...', array(array(1, 2, 3), array(4, 5, 6), array(7, 8, 9)), false); + +test('array("foo", "foo", "foo")', array("foo", "foo", "foo"), false); +test('array("one" => 1, "two" => 2))', array("one" => 1, "two" => 2), false); +test('array("kek" => "lol", "lol" => "kek")', array("kek" => "lol", "lol" => "kek"), false); +test('array("" => "empty")', array("" => "empty"), false); + +$a = array('foo'); +test('array($a, $a)', array($a, $a), false); +test('array(&$a, &$a)', array(&$a, &$a), false); + +$a = array(null); +$b = array(&$a); +$a[0] = &$b; + +test('cyclic', $a, true); + +$a = array( + 'a' => array( + 'b' => 'c', + 'd' => 'e' + ), + 'f' => array( + 'g' => 'h' + ) + ); + +test('array', $a, false); + +class Obj { + public $a; + protected $b; + private $c; + + function __construct($a, $b, $c) { + $this->a = $a; + $this->b = $b; + $this->c = $c; + } +} + +test('object', new Obj(1, 2, 3), true); + +test('object', array(new Obj(1, 2, 3), new Obj(4, 5, 6)), true); + +$o = new Obj(1, 2, 3); + +test('object', array(&$o, &$o), true); +--EXPECTF-- +NULL +OK +bool(true) +OK +bool(false) +OK +int(0) +OK +int(1) +OK +int(-1) +OK +int(1000) +OK +int(-1000) +OK +int(100000) +OK +int(-100000) +OK +float(123.456) +OK +string(0) "" +OK +string(6) "foobar" +OK +array(0) { +} +OK +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} +OK +array(3) { + [0]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } + [1]=> + array(3) { + [0]=> + int(4) + [1]=> + int(5) + [2]=> + int(6) + } + [2]=> + array(3) { + [0]=> + int(7) + [1]=> + int(8) + [2]=> + int(9) + } +} +OK +array(3) { + [0]=> + string(3) "foo" + [1]=> + string(3) "foo" + [2]=> + string(3) "foo" +} +OK +array(2) { + ["one"]=> + int(1) + ["two"]=> + int(2) +} +OK +array(2) { + ["kek"]=> + string(3) "lol" + ["lol"]=> + string(3) "kek" +} +OK +array(1) { + [""]=> + string(5) "empty" +} +OK +array(2) { + [0]=> + array(1) { + [0]=> + string(3) "foo" + } + [1]=> + array(1) { + [0]=> + string(3) "foo" + } +} +OK +array(2) { + [0]=> + array(1) { + [0]=> + string(3) "foo" + } + [1]=> + array(1) { + [0]=> + string(3) "foo" + } +} +OK +array(1) { + [0]=> + array(1) { + [0]=> + array(1) { + [0]=> + array(1) { + [0]=> + array(1) { + [0]=> + NULL + } + } + } + } +} +OK +array(2) { + ["a"]=> + array(2) { + ["b"]=> + string(1) "c" + ["d"]=> + string(1) "e" + } + ["f"]=> + array(1) { + ["g"]=> + string(1) "h" + } +} +OK +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} +OK +array(2) { + [0]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } + [1]=> + array(3) { + [0]=> + int(4) + [1]=> + int(5) + [2]=> + int(6) + } +} +OK +array(2) { + [0]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } + [1]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } +} +OK diff --git a/php/tests/088.phpt b/php/tests/088.phpt index 7cbabb9..1d44fd3 100644 --- a/php/tests/088.phpt +++ b/php/tests/088.phpt @@ -1,6 +1,10 @@ --TEST-- disabled php only for class methods unpacker (set option) --SKIPIF-- += 0) { + echo "skip tests in PHP 5.1.0 or older"; +} +--FILE-- +setOption(MESSAGEPACK_OPT_PHPONLY, false); + + $serialized = $msgpack->pack($variable); + $unpacker = $msgpack->unpacker(); + + $length = strlen($serialized); + + if (rand(0, 1)) + { + for ($i = 0; $i < $length;) + { + $len = rand(1, 10); + $str = substr($serialized, $i, $len); + + $unpacker->feed($str); + if ($unpacker->execute()) + { + $unserialized = $unpacker->data(); + var_dump($unserialized); + $unpacker->reset(); + } + + $i += $len; + } + } + else + { + $str = ""; + $offset = 0; + + for ($i = 0; $i < $length;) + { + $len = rand(1, 10); + $str .= substr($serialized, $i, $len); + + if ($unpacker->execute($str, $offset)) + { + $unserialized = $unpacker->data(); + var_dump($unserialized); + + $unpacker->reset(); + $str = ""; + $offset = 0; + } + + $i += $len; + } + } + + if (!is_bool($test)) + { + echo $unserialized === $variable ? 'OK' : 'ERROR', PHP_EOL; + } + else + { + echo $test || $unserialized == $variable ? 'OK' : 'ERROR', PHP_EOL; + } +} + +test('null', null); + +test('boo:l true', true); +test('bool: true', false); + +test('zero: 0', 0); +test('small: 1', 1); +test('small: -1', -1); +test('medium: 1000', 1000); +test('medium: -1000', -1000); +test('large: 100000', 100000); +test('large: -100000', -100000); + +test('double: 123.456', 123.456); + +test('empty: ""', ""); +test('string: "foobar"', "foobar"); + +test('empty: array', array(), false); +test('empty: array(1, 2, 3)', array(1, 2, 3), false); +test('empty: array(array(1, 2, 3), arr...', array(array(1, 2, 3), array(4, 5, 6), array(7, 8, 9)), false); + +test('array("foo", "foo", "foo")', array("foo", "foo", "foo"), false); +test('array("one" => 1, "two" => 2))', array("one" => 1, "two" => 2), false); +test('array("kek" => "lol", "lol" => "kek")', array("kek" => "lol", "lol" => "kek"), false); +test('array("" => "empty")', array("" => "empty"), false); + +$a = array('foo'); +test('array($a, $a)', array($a, $a), false); +test('array(&$a, &$a)', array(&$a, &$a), false); + +$a = array(null); +$b = array(&$a); +$a[0] = &$b; + +test('cyclic', $a, true); + +$a = array( + 'a' => array( + 'b' => 'c', + 'd' => 'e' + ), + 'f' => array( + 'g' => 'h' + ) + ); + +test('array', $a, false); + +class Obj { + public $a; + protected $b; + private $c; + + function __construct($a, $b, $c) { + $this->a = $a; + $this->b = $b; + $this->c = $c; + } +} + +test('object', new Obj(1, 2, 3), true); + +test('object', array(new Obj(1, 2, 3), new Obj(4, 5, 6)), true); + +$o = new Obj(1, 2, 3); + +test('object', array(&$o, &$o), true); +--EXPECTF-- +NULL +OK +bool(true) +OK +bool(false) +OK +int(0) +OK +int(1) +OK +int(-1) +OK +int(1000) +OK +int(-1000) +OK +int(100000) +OK +int(-100000) +OK +float(123.456) +OK +string(0) "" +OK +string(6) "foobar" +OK +array(0) { +} +OK +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} +OK +array(3) { + [0]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } + [1]=> + array(3) { + [0]=> + int(4) + [1]=> + int(5) + [2]=> + int(6) + } + [2]=> + array(3) { + [0]=> + int(7) + [1]=> + int(8) + [2]=> + int(9) + } +} +OK +array(3) { + [0]=> + string(3) "foo" + [1]=> + string(3) "foo" + [2]=> + string(3) "foo" +} +OK +array(2) { + ["one"]=> + int(1) + ["two"]=> + int(2) +} +OK +array(2) { + ["kek"]=> + string(3) "lol" + ["lol"]=> + string(3) "kek" +} +OK +array(1) { + [""]=> + string(5) "empty" +} +OK +array(2) { + [0]=> + array(1) { + [0]=> + string(3) "foo" + } + [1]=> + array(1) { + [0]=> + string(3) "foo" + } +} +OK +array(2) { + [0]=> + array(1) { + [0]=> + string(3) "foo" + } + [1]=> + array(1) { + [0]=> + string(3) "foo" + } +} +OK +array(1) { + [0]=> + array(1) { + [0]=> + array(1) { + [0]=> + array(1) { + [0]=> + array(1) { + [0]=> + NULL + } + } + } + } +} +OK +array(2) { + ["a"]=> + array(2) { + ["b"]=> + string(1) "c" + ["d"]=> + string(1) "e" + } + ["f"]=> + array(1) { + ["g"]=> + string(1) "h" + } +} +OK +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} +OK +array(2) { + [0]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } + [1]=> + array(3) { + [0]=> + int(4) + [1]=> + int(5) + [2]=> + int(6) + } +} +OK +array(2) { + [0]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } + [1]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } +} +OK diff --git a/php/tests/089.phpt b/php/tests/089.phpt index f3a0537..77be707 100644 --- a/php/tests/089.phpt +++ b/php/tests/089.phpt @@ -1,6 +1,10 @@ --TEST-- disabled php only for class unpacker (set option) --SKIPIF-- += 0) { + echo "skip tests in PHP 5.0 or older"; +} +--FILE-- +setOption(MESSAGEPACK_OPT_PHPONLY, false); + + $serialized = $msgpack->pack($variable); + + $unpacker = new MessagePackUnpacker(); + $unpacker->setOption(MESSAGEPACK_OPT_PHPONLY, false); + + $length = strlen($serialized); + + if (rand(0, 1)) + { + for ($i = 0; $i < $length;) + { + $len = rand(1, 10); + $str = substr($serialized, $i, $len); + + $unpacker->feed($str); + if ($unpacker->execute()) + { + $unserialized = $unpacker->data(); + var_dump($unserialized); + $unpacker->reset(); + } + + $i += $len; + } + } + else + { + $str = ""; + $offset = 0; + + for ($i = 0; $i < $length;) + { + $len = rand(1, 10); + $str .= substr($serialized, $i, $len); + + if ($unpacker->execute($str, $offset)) + { + $unserialized = $unpacker->data(); + var_dump($unserialized); + + $unpacker->reset(); + $str = ""; + $offset = 0; + } + + $i += $len; + } + } + + if (!is_bool($test)) + { + echo $unserialized === $variable ? 'OK' : 'ERROR', PHP_EOL; + } + else + { + echo $test || $unserialized == $variable ? 'OK' : 'ERROR', PHP_EOL; + } +} + +test('null', null); + +test('boo:l true', true); +test('bool: true', false); + +test('zero: 0', 0); +test('small: 1', 1); +test('small: -1', -1); +test('medium: 1000', 1000); +test('medium: -1000', -1000); +test('large: 100000', 100000); +test('large: -100000', -100000); + +test('double: 123.456', 123.456); + +test('empty: ""', ""); +test('string: "foobar"', "foobar"); + +test('empty: array', array(), false); +test('empty: array(1, 2, 3)', array(1, 2, 3), false); +test('empty: array(array(1, 2, 3), arr...', array(array(1, 2, 3), array(4, 5, 6), array(7, 8, 9)), false); + +test('array("foo", "foo", "foo")', array("foo", "foo", "foo"), false); +test('array("one" => 1, "two" => 2))', array("one" => 1, "two" => 2), false); +test('array("kek" => "lol", "lol" => "kek")', array("kek" => "lol", "lol" => "kek"), false); +test('array("" => "empty")', array("" => "empty"), false); + +$a = array('foo'); +test('array($a, $a)', array($a, $a), false); +test('array(&$a, &$a)', array(&$a, &$a), false); + +$a = array(null); +$b = array(&$a); +$a[0] = &$b; + +test('cyclic', $a, true); + +$a = array( + 'a' => array( + 'b' => 'c', + 'd' => 'e' + ), + 'f' => array( + 'g' => 'h' + ) + ); + +test('array', $a, false); + +class Obj { + public $a; + protected $b; + private $c; + + function __construct($a, $b, $c) { + $this->a = $a; + $this->b = $b; + $this->c = $c; + } +} + +test('object', new Obj(1, 2, 3), true); + +test('object', array(new Obj(1, 2, 3), new Obj(4, 5, 6)), true); + +$o = new Obj(1, 2, 3); + +test('object', array(&$o, &$o), true); +--EXPECTF-- +NULL +OK +bool(true) +OK +bool(false) +OK +int(0) +OK +int(1) +OK +int(-1) +OK +int(1000) +OK +int(-1000) +OK +int(100000) +OK +int(-100000) +OK +float(123.456) +OK +string(0) "" +OK +string(6) "foobar" +OK +array(0) { +} +OK +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} +OK +array(3) { + [0]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } + [1]=> + array(3) { + [0]=> + int(4) + [1]=> + int(5) + [2]=> + int(6) + } + [2]=> + array(3) { + [0]=> + int(7) + [1]=> + int(8) + [2]=> + int(9) + } +} +OK +array(3) { + [0]=> + string(3) "foo" + [1]=> + string(3) "foo" + [2]=> + string(3) "foo" +} +OK +array(2) { + ["one"]=> + int(1) + ["two"]=> + int(2) +} +OK +array(2) { + ["kek"]=> + string(3) "lol" + ["lol"]=> + string(3) "kek" +} +OK +array(1) { + [""]=> + string(5) "empty" +} +OK +array(2) { + [0]=> + array(1) { + [0]=> + string(3) "foo" + } + [1]=> + array(1) { + [0]=> + string(3) "foo" + } +} +OK +array(2) { + [0]=> + array(1) { + [0]=> + string(3) "foo" + } + [1]=> + array(1) { + [0]=> + string(3) "foo" + } +} +OK +array(1) { + [0]=> + array(1) { + [0]=> + array(1) { + [0]=> + array(1) { + [0]=> + array(1) { + [0]=> + NULL + } + } + } + } +} +OK +array(2) { + ["a"]=> + array(2) { + ["b"]=> + string(1) "c" + ["d"]=> + string(1) "e" + } + ["f"]=> + array(1) { + ["g"]=> + string(1) "h" + } +} +OK +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} +OK +array(2) { + [0]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } + [1]=> + array(3) { + [0]=> + int(4) + [1]=> + int(5) + [2]=> + int(6) + } +} +OK +array(2) { + [0]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } + [1]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } +} +OK diff --git a/ruby/makegem.sh b/ruby/makegem.sh index bf30cd4..6a99cfe 100755 --- a/ruby/makegem.sh +++ b/ruby/makegem.sh @@ -8,6 +8,7 @@ cp pack.h ext/ cp rbinit.c ext/ cp unpack.c ext/ cp unpack.h ext/ +cp compat.h ext/ cp version.rb ext/ cp ../msgpack/pack_define.h msgpack/ cp ../msgpack/pack_template.h msgpack/ diff --git a/ruby/test/test_pack_unpack.rb b/ruby/test/test_pack_unpack.rb index f378c3c..8bdb362 100644 --- a/ruby/test/test_pack_unpack.rb +++ b/ruby/test/test_pack_unpack.rb @@ -227,8 +227,9 @@ class MessagePackTestPackUnpack < Test::Unit::TestCase assert(fe.length > 0) off += fe.length - pac.feed fe - pac.each {|obj| + #pac.feed fe + #pac.each {|obj| + pac.feed_each(fe) {|obj| assert(!parsed) assert_equal(obj, str) parsed = true @@ -245,8 +246,8 @@ class MessagePackTestPackUnpack < Test::Unit::TestCase pac = MessagePack::Unpacker.new parsed = 0 raw.split(//).each do |b| - pac.feed(b) - pac.each {|o| + #pac.feed(b) + pac.feed_each(b) {|o| GC.start assert_equal(obj, o) parsed += 1 diff --git a/ruby/unpack.c b/ruby/unpack.c index 2d10e75..f61fe6d 100644 --- a/ruby/unpack.c +++ b/ruby/unpack.c @@ -24,7 +24,7 @@ static ID s_sysread; static ID s_readpartial; struct unpack_buffer { - size_t size; + size_t used; size_t free; char* ptr; }; @@ -37,6 +37,7 @@ typedef struct { VALUE stream; VALUE streambuf; ID stream_append_method; + size_t buffer_free_size; } unpack_user; @@ -241,6 +242,13 @@ static VALUE eUnpackError; #define MSGPACK_UNPACKER_BUFFER_RESERVE_SIZE (8*1024) #endif +/* +#ifndef MSGPACK_BUFFER_FREE_SIZE +#define MSGPACK_BUFFER_FREE_SIZE (1024*1024) +#endif +*/ +#define MSGPACK_BUFFER_FREE_SIZE 0 + static void MessagePack_Unpacker_free(void* data) { if(data) { @@ -273,7 +281,7 @@ static VALUE MessagePack_Unpacker_alloc(VALUE klass) mp->user.finished = 0; mp->user.offset = 0; - mp->user.buffer.size = 0; + mp->user.buffer.used = 0; mp->user.buffer.free = 0; mp->user.buffer.ptr = NULL; @@ -326,6 +334,7 @@ static VALUE MessagePack_Unpacker_initialize(int argc, VALUE *argv, VALUE self) mp->user.stream = stream; mp->user.streambuf = rb_str_buf_new(MSGPACK_UNPACKER_BUFFER_RESERVE_SIZE); mp->user.stream_append_method = append_method_of(stream); + mp->user.buffer_free_size = MSGPACK_BUFFER_FREE_SIZE; return self; } @@ -366,22 +375,27 @@ static void reserve_buffer(msgpack_unpack_t* mp, size_t require) { struct unpack_buffer* buffer = &mp->user.buffer; - if(buffer->size == 0) { - size_t nsize = MSGPACK_UNPACKER_BUFFER_INIT_SIZE; + if(buffer->used == 0) { + if(require <= buffer->free) { + /* enough free space */ + return; + } + /* no used buffer: realloc only */ + size_t nsize = buffer->free == 0 ? + MSGPACK_UNPACKER_BUFFER_INIT_SIZE : buffer->free*2; while(nsize < require) { nsize *= 2; } - char* tmp = ALLOC_N(char, nsize); - buffer->ptr = tmp; + char* tmp = REALLOC_N(buffer->ptr, char, nsize); buffer->free = nsize; - buffer->size = 0; + buffer->ptr = tmp; return; } - if(buffer->size <= mp->user.offset) { + if(buffer->used <= mp->user.offset) { /* clear buffer and rewind offset */ - buffer->free += buffer->size; - buffer->size = 0; + buffer->free += buffer->used; + buffer->used = 0; mp->user.offset = 0; } @@ -390,41 +404,91 @@ static void reserve_buffer(msgpack_unpack_t* mp, size_t require) return; } - size_t nsize = (buffer->size + buffer->free) * 2; + size_t nsize = (buffer->used + buffer->free) * 2; - if(mp->user.offset <= buffer->size / 2) { + if(mp->user.offset <= buffer->used / 2) { /* parsed less than half: realloc only */ - while(nsize < buffer->size + require) { + while(nsize < buffer->used + require) { nsize *= 2; } char* tmp = REALLOC_N(buffer->ptr, char, nsize); - buffer->free = nsize - buffer->size; + buffer->free = nsize - buffer->used; buffer->ptr = tmp; } else { /* parsed more than half: realloc and move */ - size_t not_parsed = buffer->size - mp->user.offset; + size_t not_parsed = buffer->used - mp->user.offset; while(nsize < not_parsed + require) { nsize *= 2; } char* tmp = REALLOC_N(buffer->ptr, char, nsize); memcpy(tmp, tmp + mp->user.offset, not_parsed); - buffer->free = nsize - buffer->size; - buffer->size = not_parsed; + buffer->free = nsize - not_parsed; + buffer->used = not_parsed; buffer->ptr = tmp; mp->user.offset = 0; } } -static inline void feed_buffer(msgpack_unpack_t* mp, const char* ptr, size_t len) +static inline void try_free_buffer(msgpack_unpack_t* mp, size_t require) +{ + if(mp->user.buffer_free_size == 0) { + return; + } + + struct unpack_buffer* buffer = &mp->user.buffer; + size_t csize = buffer->used + buffer->free; + + if(csize <= mp->user.buffer_free_size) { + return; + } + + if(mp->user.offset <= buffer->used / 2) { + /* parsed less than half: do nothing */ + + } else if(mp->user.offset < buffer->used) { + /* parsed more than half but not all: realloc and move */ + size_t nsize = MSGPACK_UNPACKER_BUFFER_INIT_SIZE; + size_t not_parsed = buffer->used - mp->user.offset; + while(nsize < not_parsed + require) { + nsize *= 2; + } + + if(nsize >= csize) { + return; + } + + char* tmp; + if(mp->user.offset == 0) { + tmp = ALLOC_N(char, nsize); + memcpy(tmp, buffer->ptr + mp->user.offset, not_parsed); + free(buffer->ptr); + } else { + tmp = REALLOC_N(buffer->ptr, char, nsize); + } + buffer->free = nsize - not_parsed; + buffer->used = not_parsed; + buffer->ptr = tmp; + mp->user.offset = 0; + + } else { + /* all parsed: free all */ + free(buffer->ptr); + buffer->free = 0; + buffer->used = 0; + buffer->ptr = NULL; + mp->user.offset = 0; + } +} + +static void feed_buffer(msgpack_unpack_t* mp, const char* ptr, size_t len) { struct unpack_buffer* buffer = &mp->user.buffer; - if(buffer->free < len) { - reserve_buffer(mp, len); - } - memcpy(buffer->ptr + buffer->size, ptr, len); - buffer->size += len; + reserve_buffer(mp, len); + + memcpy(buffer->ptr + buffer->used, ptr, len); + buffer->used += len; buffer->free -= len; } @@ -498,7 +562,7 @@ static VALUE MessagePack_Unpacker_each(VALUE self) #endif while(1) { - if(mp->user.buffer.size <= mp->user.offset) { + if(mp->user.buffer.used <= mp->user.offset) { do_fill: { VALUE len = MessagePack_Unpacker_fill(self); @@ -509,7 +573,7 @@ static VALUE MessagePack_Unpacker_each(VALUE self) } ret = template_execute_wrap_each(mp, - mp->user.buffer.ptr, mp->user.buffer.size, + mp->user.buffer.ptr, mp->user.buffer.used, &mp->user.offset); if(ret < 0) { @@ -525,9 +589,131 @@ static VALUE MessagePack_Unpacker_each(VALUE self) } } + try_free_buffer(mp, 0); + return Qnil; } +static VALUE feed_each_impl(VALUE args) +{ + VALUE self = ((VALUE*)args)[0]; + VALUE data = ((VALUE*)args)[1]; + size_t* pconsumed = (size_t*)((VALUE*)args)[2]; + + UNPACKER(self, mp); + int ret; + const char* ptr = RSTRING_PTR(data); + size_t len = RSTRING_LEN(data); + + if(mp->user.buffer.used > 0) { + while(1) { + ret = template_execute_wrap_each(mp, + mp->user.buffer.ptr, mp->user.buffer.used, + &mp->user.offset); + + if(ret < 0) { + rb_raise(eUnpackError, "parse error."); + + } else if(ret > 0) { + VALUE data = template_data(mp); + template_init(mp); + rb_yield(data); + + } else { + break; + } + } + } + + if(len <= 0) { + return Qnil; + } + + if(mp->user.buffer.used <= mp->user.offset) { + // wrap & execute & feed + while(1) { + ret = template_execute_wrap_each(mp, + ptr, len, pconsumed); + + if(ret < 0) { + rb_raise(eUnpackError, "parse error."); + + } else if(ret > 0) { + VALUE data = template_data(mp); + template_init(mp); + rb_yield(data); + + } else { + break; + } + } + + } else { + // feed & execute + feed_buffer(mp, ptr, len); + *pconsumed = len; + + while(1) { + ret = template_execute_wrap_each(mp, + mp->user.buffer.ptr, mp->user.buffer.used, + &mp->user.offset); + + if(ret < 0) { + rb_raise(eUnpackError, "parse error."); + + } else if(ret > 0) { + VALUE data = template_data(mp); + template_init(mp); + rb_yield(data); + + } else { + break; + } + } + } + + return Qnil; +} + +static VALUE feed_each_ensure(VALUE args) { + VALUE self = ((VALUE*)args)[0]; + VALUE data = ((VALUE*)args)[1]; + size_t* pconsumed = (size_t*)((VALUE*)args)[2]; + + const char* dptr = RSTRING_PTR(data) + *pconsumed; + size_t dlen = RSTRING_LEN(data) - *pconsumed; + + if(dlen > 0) { + UNPACKER(self, mp); + try_free_buffer(mp, dlen); + feed_buffer(mp, dptr, dlen); + } + + return Qnil; +} + +/** + * Document-method: MessagePack::Unpacker#feed_each + * + * call-seq: + * unpacker.feed_each(data) {|object| } + * + * Same as feed(data) + each {|object| }, but tries to avoid copying of the buffer. + */ +static VALUE MessagePack_Unpacker_feed_each(VALUE self, VALUE data) +{ + size_t consumed = 0; + StringValue(data); + + VALUE args[3]; + args[0] = self; + args[1] = data; + args[2] = (VALUE)&consumed; + + return rb_ensure(feed_each_impl, (VALUE)args, + feed_each_ensure, (VALUE)args); +} + static inline VALUE MessagePack_unpack_impl(VALUE self, VALUE data, unsigned long dlen) { @@ -620,7 +806,7 @@ static VALUE MessagePack_Unpacker_execute_impl(VALUE self, VALUE data, * * This method doesn't use the internal buffer. * - * Call *reset()* method before calling this method again. + * Call *reset* method before calling this method again. * * UnpackError is throw when parse error is occured. */ @@ -642,7 +828,7 @@ static VALUE MessagePack_Unpacker_execute_limit(VALUE self, VALUE data, * * This method doesn't use the internal buffer. * - * Call *reset()* method before calling this method again. + * Call *reset* method before calling this method again. * * This returns offset that was parsed to. * Use *finished?* method to check an object is deserialized and call *data* @@ -705,6 +891,7 @@ static VALUE MessagePack_Unpacker_reset(VALUE self) UNPACKER(self, mp); template_init(mp); mp->user.finished = 0; + try_free_buffer(mp, 0); return self; } @@ -726,6 +913,7 @@ void Init_msgpack_unpack(VALUE mMessagePack) rb_define_method(cUnpacker, "each", MessagePack_Unpacker_each, 0); rb_define_method(cUnpacker, "stream", MessagePack_Unpacker_stream_get, 0); rb_define_method(cUnpacker, "stream=", MessagePack_Unpacker_stream_set, 1); + rb_define_method(cUnpacker, "feed_each", MessagePack_Unpacker_feed_each, 1); /* Unbuffered API */ rb_define_method(cUnpacker, "execute", MessagePack_Unpacker_execute, 2); diff --git a/ruby/version.rb b/ruby/version.rb index b156620..4fca81f 100644 --- a/ruby/version.rb +++ b/ruby/version.rb @@ -1,3 +1,3 @@ module MessagePack - VERSION = "0.4.3" + VERSION = "0.4.4" end