From 693d38cb07b4c84e59874185cb2690b13ac53621 Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Wed, 11 Feb 2015 02:13:33 +0900 Subject: [PATCH 001/234] Refactoring MessageBuffer initializer --- .../msgpack/core/buffer/MessageBuffer.java | 131 +++++++++--------- 1 file changed, 62 insertions(+), 69 deletions(-) diff --git a/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBuffer.java b/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBuffer.java index 3dffa9dd1..34d7a4d55 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBuffer.java +++ b/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBuffer.java @@ -9,6 +9,7 @@ import java.lang.reflect.Method; import java.nio.BufferOverflowException; import java.nio.ByteBuffer; +import java.nio.ByteOrder; import static org.msgpack.core.Preconditions.*; @@ -45,10 +46,7 @@ enum DirectBufferConstructorType { String javaVersion = System.getProperty("java.specification.version", ""); int dotPos = javaVersion.indexOf('.'); boolean isJavaAtLeast7 = false; - if(dotPos == -1) { - isJavaAtLeast7 = false; - } - else { + if(dotPos != -1) { try { int major = Integer.parseInt(javaVersion.substring(0, dotPos)); int minor = Integer.parseInt(javaVersion.substring(dotPos + 1)); @@ -59,33 +57,74 @@ enum DirectBufferConstructorType { } } + boolean hasUnsafe = false; + try { + Class.forName("sun.misc.Unsafe"); + hasUnsafe = true; + } + catch(ClassNotFoundException e) { + } + // Detect android VM boolean isAndroid = System.getProperty("java.runtime.name", "").toLowerCase().contains("android"); - // Fetch theUnsafe object for Orackle JDK and OpenJDK - Unsafe u; - if(!isAndroid) { - // Fetch theUnsafe object for Oracle JDK and OpenJDK + + // For Java6, android and JVM that has no Unsafe class, use Universal MessageBuffer + boolean useUniversalBuffer = + Boolean.parseBoolean(System.getProperty("msgpack.universal-buffer", "false")) + || isAndroid + || !isJavaAtLeast7 + || !hasUnsafe; + + // We need to use reflection to find MessageBuffer implementation classes because + // importing these classes creates TypeProfile and adds some overhead to method calls. + String bufferClsName; + if(useUniversalBuffer) { + bufferClsName = "org.msgpack.core.buffer.MessageBufferU"; + unsafe = null; + ARRAY_BYTE_BASE_OFFSET = 16; // dummy value + ARRAY_BYTE_INDEX_SCALE = 1; + } + else { + // Check the endian of this CPU + boolean isLittleEndian = ByteOrder.nativeOrder() == ByteOrder.LITTLE_ENDIAN; + if(isLittleEndian) { + bufferClsName = "org.msgpack.core.buffer.MessageBuffer"; + } + else { + bufferClsName = "org.msgpack.core.buffer.MessageBufferBE"; + } + + // Fetch theUnsafe object for Oracle and OpenJDK + Unsafe u; Field field = Unsafe.class.getDeclaredField("theUnsafe"); field.setAccessible(true); unsafe = (Unsafe) field.get(null); + if(unsafe == null) { + throw new RuntimeException("Unsafe is unavailable"); + } + ARRAY_BYTE_BASE_OFFSET = unsafe.arrayBaseOffset(byte[].class); + ARRAY_BYTE_INDEX_SCALE = unsafe.arrayIndexScale(byte[].class); + + // Make sure the VM thinks bytes are only one byte wide + if(ARRAY_BYTE_INDEX_SCALE != 1) { + throw new IllegalStateException("Byte array index scale must be 1, but is " + ARRAY_BYTE_INDEX_SCALE); + } } - else { - // Workaround for creating an Unsafe instance for Android OS - Constructor unsafeConstructor = Unsafe.class.getDeclaredConstructor(); - unsafeConstructor.setAccessible(true); - unsafe = unsafeConstructor.newInstance(); - } - if(unsafe == null) { - throw new RuntimeException("Unsafe is unavailable"); - } + Class bufferCls = Class.forName(bufferClsName); + msgBufferClass = bufferCls; - ARRAY_BYTE_BASE_OFFSET = unsafe.arrayBaseOffset(byte[].class); - ARRAY_BYTE_INDEX_SCALE = unsafe.arrayIndexScale(byte[].class); + Constructor mbArrCstr = bufferCls.getDeclaredConstructor(byte[].class); + mbArrCstr.setAccessible(true); + mbArrConstructor = mbArrCstr; - // Make sure the VM thinks bytes are only one byte wide - if(ARRAY_BYTE_INDEX_SCALE != 1) { - throw new IllegalStateException("Byte array index scale must be 1, but is " + ARRAY_BYTE_INDEX_SCALE); - } + Constructor mbBBCstr = bufferCls.getDeclaredConstructor(ByteBuffer.class); + mbBBCstr.setAccessible(true); + mbBBConstructor = mbBBCstr; + + // Requires Java7 + //newMsgBuffer = MethodHandles.lookup().unreflectConstructor(mbArrCstr).asType( + // MethodType.methodType(bufferCls, byte[].class) + //); // Find the hidden constructor for DirectByteBuffer directByteBufferClass = ClassLoader.getSystemClassLoader().loadClass("java.nio.DirectByteBuffer"); @@ -123,52 +162,6 @@ enum DirectBufferConstructorType { throw new RuntimeException("Constructor of DirectByteBuffer is not found"); byteBufferConstructor.setAccessible(true); - - // Check the endian of this CPU - boolean isLittleEndian = true; - byte[] a = new byte[8]; - // use Unsafe.putLong to an array since Unsafe.getByte is not available in Android - unsafe.putLong(a, (long) ARRAY_BYTE_BASE_OFFSET, 0x0102030405060708L); - switch(a[0]) { - case 0x01: - isLittleEndian = false; - break; - case 0x08: - isLittleEndian = true; - break; - default: - assert false; - } - - // We need to use reflection to find MessageBuffer implementation classes because - // importing these classes creates TypeProfile and adds some overhead to method calls. - String bufferClsName; - boolean useUniversalBuffer = Boolean.parseBoolean(System.getProperty("msgpack.universal-buffer", "false")); - if(!useUniversalBuffer && !isAndroid && isJavaAtLeast7) { - if(isLittleEndian) - bufferClsName = "org.msgpack.core.buffer.MessageBuffer"; - else - bufferClsName = "org.msgpack.core.buffer.MessageBufferBE"; - } - else { - bufferClsName = "org.msgpack.core.buffer.MessageBufferU"; - } - - Class bufferCls = Class.forName(bufferClsName); - msgBufferClass = bufferCls; - - Constructor mbArrCstr = bufferCls.getDeclaredConstructor(byte[].class); - mbArrCstr.setAccessible(true); - mbArrConstructor = mbArrCstr; - - Constructor mbBBCstr = bufferCls.getDeclaredConstructor(ByteBuffer.class); - mbBBCstr.setAccessible(true); - mbBBConstructor = mbBBCstr; - - // Requires Java7 - //newMsgBuffer = MethodHandles.lookup().unreflectConstructor(mbArrCstr).asType( - // MethodType.methodType(bufferCls, byte[].class) - //); } catch(Exception e) { e.printStackTrace(System.err); From e2b4a71b15553af41f3c00d9576cfcee4789ad3e Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Wed, 11 Feb 2015 03:29:25 +0900 Subject: [PATCH 002/234] Add a flag to detect GAE platform --- .../java/org/msgpack/core/buffer/MessageBuffer.java | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBuffer.java b/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBuffer.java index 34d7a4d55..a63d52010 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBuffer.java +++ b/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBuffer.java @@ -59,23 +59,26 @@ enum DirectBufferConstructorType { boolean hasUnsafe = false; try { - Class.forName("sun.misc.Unsafe"); - hasUnsafe = true; + hasUnsafe = Class.forName("sun.misc.Unsafe") != null; } - catch(ClassNotFoundException e) { + catch(Exception e) { } // Detect android VM boolean isAndroid = System.getProperty("java.runtime.name", "").toLowerCase().contains("android"); + // Is Google App Engine? + boolean isGAE = System.getProperty("com.google.appengine.runtime.version") != null; + // For Java6, android and JVM that has no Unsafe class, use Universal MessageBuffer boolean useUniversalBuffer = Boolean.parseBoolean(System.getProperty("msgpack.universal-buffer", "false")) || isAndroid + || isGAE || !isJavaAtLeast7 || !hasUnsafe; - // We need to use reflection to find MessageBuffer implementation classes because + // We need to use reflection to find MessageBuffer implementation classes abecause // importing these classes creates TypeProfile and adds some overhead to method calls. String bufferClsName; if(useUniversalBuffer) { From 3ba731f9c9a2d6b926f7a19160e0f9161f0d25a0 Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Wed, 11 Feb 2015 04:14:48 +0900 Subject: [PATCH 003/234] Encupslate DirectByteBuffer accessors --- .../msgpack/core/buffer/MessageBuffer.java | 170 ++++++++++-------- 1 file changed, 97 insertions(+), 73 deletions(-) diff --git a/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBuffer.java b/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBuffer.java index a63d52010..260f8b017 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBuffer.java +++ b/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBuffer.java @@ -10,6 +10,7 @@ import java.nio.BufferOverflowException; import java.nio.ByteBuffer; import java.nio.ByteOrder; +import java.security.AccessControlException; import static org.msgpack.core.Preconditions.*; @@ -23,13 +24,9 @@ */ public class MessageBuffer { + static final boolean isUniversalBuffer; static final Unsafe unsafe; // TODO We should use MethodHandle for efficiency, but it is not available in JDK6 - static final Constructor byteBufferConstructor; - - static final Class directByteBufferClass; - static final DirectBufferConstructorType directBufferConstructorType; - static final Method memoryBlockWrapFromJni; static final int ARRAY_BYTE_BASE_OFFSET; static final int ARRAY_BYTE_INDEX_SCALE; @@ -37,7 +34,8 @@ enum DirectBufferConstructorType { ARGS_LONG_INT_REF, ARGS_LONG_INT, ARGS_INT_INT, - ARGS_MB_INT_INT + ARGS_MB_INT_INT, + NONE } static { @@ -71,17 +69,17 @@ enum DirectBufferConstructorType { boolean isGAE = System.getProperty("com.google.appengine.runtime.version") != null; // For Java6, android and JVM that has no Unsafe class, use Universal MessageBuffer - boolean useUniversalBuffer = + isUniversalBuffer = Boolean.parseBoolean(System.getProperty("msgpack.universal-buffer", "false")) || isAndroid || isGAE || !isJavaAtLeast7 || !hasUnsafe; - // We need to use reflection to find MessageBuffer implementation classes abecause + // We need to use reflection to find MessageBuffer implementation classes because // importing these classes creates TypeProfile and adds some overhead to method calls. String bufferClsName; - if(useUniversalBuffer) { + if(isUniversalBuffer) { bufferClsName = "org.msgpack.core.buffer.MessageBufferU"; unsafe = null; ARRAY_BYTE_BASE_OFFSET = 16; // dummy value @@ -129,42 +127,6 @@ enum DirectBufferConstructorType { // MethodType.methodType(bufferCls, byte[].class) //); - // Find the hidden constructor for DirectByteBuffer - directByteBufferClass = ClassLoader.getSystemClassLoader().loadClass("java.nio.DirectByteBuffer"); - Constructor directByteBufferConstructor = null; - DirectBufferConstructorType constructorType = null; - Method mbWrap = null; - try { - // TODO We should use MethodHandle for Java7, which can avoid the cost of boxing with JIT optimization - directByteBufferConstructor = directByteBufferClass.getDeclaredConstructor(long.class, int.class, Object.class); - constructorType = DirectBufferConstructorType.ARGS_LONG_INT_REF; - } - catch(NoSuchMethodException e0) { - try { - // https://android.googlesource.com/platform/libcore/+/master/luni/src/main/java/java/nio/DirectByteBuffer.java - // DirectByteBuffer(long address, int capacity) - directByteBufferConstructor = directByteBufferClass.getDeclaredConstructor(long.class, int.class); - constructorType = DirectBufferConstructorType.ARGS_LONG_INT; - } catch (NoSuchMethodException e1) { - try { - directByteBufferConstructor = directByteBufferClass.getDeclaredConstructor(int.class, int.class); - constructorType = DirectBufferConstructorType.ARGS_INT_INT; - } catch (NoSuchMethodException e2) { - Class aClass = Class.forName("java.nio.MemoryBlock"); - mbWrap = aClass.getDeclaredMethod("wrapFromJni", int.class, long.class); - mbWrap.setAccessible(true); - directByteBufferConstructor = directByteBufferClass.getDeclaredConstructor(aClass, int.class, int.class); - constructorType = DirectBufferConstructorType.ARGS_MB_INT_INT; - } - } - } - byteBufferConstructor = directByteBufferConstructor; - directBufferConstructorType = constructorType; - memoryBlockWrapFromJni = mbWrap; - if(byteBufferConstructor == null) - throw new RuntimeException("Constructor of DirectByteBuffer is not found"); - - byteBufferConstructor.setAccessible(true); } catch(Exception e) { e.printStackTrace(System.err); @@ -180,8 +142,61 @@ private static class DirectBufferAccess { static Method mCleaner; static Method mClean; + static Constructor byteBufferConstructor; + + static Class directByteBufferClass; + static DirectBufferConstructorType directBufferConstructorType; + static Method memoryBlockWrapFromJni; + static { try { + if(!isUniversalBuffer) { + try { + // Find the hidden constructor for DirectByteBuffer + directByteBufferClass = ClassLoader.getSystemClassLoader().loadClass("java.nio.DirectByteBuffer"); + Constructor directByteBufferConstructor = null; + DirectBufferConstructorType constructorType = null; + Method mbWrap = null; + try { + // TODO We should use MethodHandle for Java7, which can avoid the cost of boxing with JIT optimization + directByteBufferConstructor = directByteBufferClass.getDeclaredConstructor(long.class, int.class, Object.class); + constructorType = DirectBufferConstructorType.ARGS_LONG_INT_REF; + } + catch(NoSuchMethodException e0) { + try { + // https://android.googlesource.com/platform/libcore/+/master/luni/src/main/java/java/nio/DirectByteBuffer.java + // DirectByteBuffer(long address, int capacity) + directByteBufferConstructor = directByteBufferClass.getDeclaredConstructor(long.class, int.class); + constructorType = DirectBufferConstructorType.ARGS_LONG_INT; + } + catch(NoSuchMethodException e1) { + try { + directByteBufferConstructor = directByteBufferClass.getDeclaredConstructor(int.class, int.class); + constructorType = DirectBufferConstructorType.ARGS_INT_INT; + } + catch(NoSuchMethodException e2) { + Class aClass = Class.forName("java.nio.MemoryBlock"); + mbWrap = aClass.getDeclaredMethod("wrapFromJni", int.class, long.class); + mbWrap.setAccessible(true); + directByteBufferConstructor = directByteBufferClass.getDeclaredConstructor(aClass, int.class, int.class); + constructorType = DirectBufferConstructorType.ARGS_MB_INT_INT; + } + } + } + + byteBufferConstructor = directByteBufferConstructor; + directBufferConstructorType = constructorType; + memoryBlockWrapFromJni = mbWrap; + + if(byteBufferConstructor == null) + throw new RuntimeException("Constructor of DirectByteBuffer is not found"); + byteBufferConstructor.setAccessible(true); + } + catch(Exception e) { + directBufferConstructorType = DirectBufferConstructorType.NONE; + } + } + mGetAddress = directByteBufferClass.getDeclaredMethod("address"); mGetAddress.setAccessible(true); @@ -217,6 +232,33 @@ static void clean(Object base) { throw new RuntimeException(e); } } + + static boolean isDirectByteBufferInstance(Object s) { + return directByteBufferClass.isInstance(s); + } + + static ByteBuffer newByteBuffer(long address, int index, int length, ByteBuffer reference) { + try { + switch(directBufferConstructorType) { + case ARGS_LONG_INT_REF: + return (ByteBuffer) byteBufferConstructor.newInstance(address + index, length, reference); + case ARGS_LONG_INT: + return (ByteBuffer) byteBufferConstructor.newInstance(address + index, length); + case ARGS_INT_INT: + return (ByteBuffer) byteBufferConstructor.newInstance((int) address + index, length); + case ARGS_MB_INT_INT: + return (ByteBuffer) byteBufferConstructor.newInstance( + memoryBlockWrapFromJni.invoke(null, address + index, length), + length, 0); + default: + throw new IllegalStateException("Unexpected value"); + } + } + catch(Throwable e) { + // Convert checked exception to unchecked exception + throw new RuntimeException(e); + } + } } /** @@ -259,8 +301,13 @@ static void clean(Object base) { static MessageBuffer newOffHeapBuffer(int length) { // This method is not available in Android OS - long address = unsafe.allocateMemory(length); - return new MessageBuffer(address, length); + if(!isUniversalBuffer) { + long address = unsafe.allocateMemory(length); + return new MessageBuffer(address, length); + } + else { + return newDirectBuffer(length); + } } public static MessageBuffer newDirectBuffer(int length) { @@ -318,7 +365,7 @@ public static void releaseBuffer(MessageBuffer buffer) { if(buffer.base instanceof byte[]) { // We have nothing to do. Wait until the garbage-collector collects this array object } - else if(directByteBufferClass.isInstance(buffer.base)) { + else if(DirectBufferAccess.isDirectByteBufferInstance(buffer.base)) { DirectBufferAccess.clean(buffer.base); } else { @@ -530,31 +577,8 @@ public ByteBuffer toByteBuffer(int index, int length) { if(hasArray()) { return ByteBuffer.wrap((byte[]) base, (int) ((address - ARRAY_BYTE_BASE_OFFSET) + index), length); } - try { - ByteBuffer bb = null; - switch (directBufferConstructorType) { - case ARGS_LONG_INT_REF: - bb = (ByteBuffer) byteBufferConstructor.newInstance(address + index, length, reference); - break; - case ARGS_LONG_INT: - bb = (ByteBuffer) byteBufferConstructor.newInstance(address + index, length); - break; - case ARGS_INT_INT: - bb = (ByteBuffer) byteBufferConstructor.newInstance((int)address + index, length); - break; - case ARGS_MB_INT_INT: - bb = (ByteBuffer) byteBufferConstructor.newInstance( - memoryBlockWrapFromJni.invoke(null, address + index, length), - length, 0); - break; - default: - throw new IllegalStateException("Unexpected value"); - } - return bb; - } - catch(Throwable e) { - // Convert checked exception to unchecked exception - throw new RuntimeException(e); + else { + return DirectBufferAccess.newByteBuffer(address, index, length, reference); } } From c2fe48ce52d2cd6e35b3e221400fe82d36a8df84 Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Wed, 11 Feb 2015 04:27:12 +0900 Subject: [PATCH 004/234] Extract DirectBufferAccess to a new file --- .../core/buffer/DirectBufferAccess.java | 140 ++++++++++++++++ .../msgpack/core/buffer/MessageBuffer.java | 149 +----------------- 2 files changed, 145 insertions(+), 144 deletions(-) create mode 100644 msgpack-core/src/main/java/org/msgpack/core/buffer/DirectBufferAccess.java diff --git a/msgpack-core/src/main/java/org/msgpack/core/buffer/DirectBufferAccess.java b/msgpack-core/src/main/java/org/msgpack/core/buffer/DirectBufferAccess.java new file mode 100644 index 000000000..c31014975 --- /dev/null +++ b/msgpack-core/src/main/java/org/msgpack/core/buffer/DirectBufferAccess.java @@ -0,0 +1,140 @@ +package org.msgpack.core.buffer; + +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.nio.ByteBuffer; + +/** + * Wraps the difference of access methods to DirectBuffers between Android and others. + */ +class DirectBufferAccess { + + enum DirectBufferConstructorType { + ARGS_LONG_INT_REF, + ARGS_LONG_INT, + ARGS_INT_INT, + ARGS_MB_INT_INT + } + + + static Method mGetAddress; + static Method mCleaner; + static Method mClean; + + // TODO We should use MethodHandle for efficiency, but it is not available in JDK6 + static Constructor byteBufferConstructor; + static Class directByteBufferClass; + static DirectBufferConstructorType directBufferConstructorType; + static Method memoryBlockWrapFromJni; + + static { + try { + // Find the hidden constructor for DirectByteBuffer + directByteBufferClass = ClassLoader.getSystemClassLoader().loadClass("java.nio.DirectByteBuffer"); + Constructor directByteBufferConstructor = null; + DirectBufferConstructorType constructorType = null; + Method mbWrap = null; + try { + // TODO We should use MethodHandle for Java7, which can avoid the cost of boxing with JIT optimization + directByteBufferConstructor = directByteBufferClass.getDeclaredConstructor(long.class, int.class, Object.class); + constructorType = DirectBufferConstructorType.ARGS_LONG_INT_REF; + } + catch(NoSuchMethodException e0) { + try { + // https://android.googlesource.com/platform/libcore/+/master/luni/src/main/java/java/nio/DirectByteBuffer.java + // DirectByteBuffer(long address, int capacity) + directByteBufferConstructor = directByteBufferClass.getDeclaredConstructor(long.class, int.class); + constructorType = DirectBufferConstructorType.ARGS_LONG_INT; + } + catch(NoSuchMethodException e1) { + try { + directByteBufferConstructor = directByteBufferClass.getDeclaredConstructor(int.class, int.class); + constructorType = DirectBufferConstructorType.ARGS_INT_INT; + } + catch(NoSuchMethodException e2) { + Class aClass = Class.forName("java.nio.MemoryBlock"); + mbWrap = aClass.getDeclaredMethod("wrapFromJni", int.class, long.class); + mbWrap.setAccessible(true); + directByteBufferConstructor = directByteBufferClass.getDeclaredConstructor(aClass, int.class, int.class); + constructorType = DirectBufferConstructorType.ARGS_MB_INT_INT; + } + } + } + + byteBufferConstructor = directByteBufferConstructor; + directBufferConstructorType = constructorType; + memoryBlockWrapFromJni = mbWrap; + + if(byteBufferConstructor == null) + throw new RuntimeException("Constructor of DirectByteBuffer is not found"); + byteBufferConstructor.setAccessible(true); + } + catch(Exception e) { + + } + + try { + mGetAddress = directByteBufferClass.getDeclaredMethod("address"); + mGetAddress.setAccessible(true); + + mCleaner = directByteBufferClass.getDeclaredMethod("cleaner"); + mCleaner.setAccessible(true); + + mClean = mCleaner.getReturnType().getDeclaredMethod("clean"); + mClean.setAccessible(true); + } + catch(NoSuchMethodException e) { + throw new RuntimeException(e); + } + } + + static long getAddress(Object base) { + try { + return (Long) mGetAddress.invoke(base); + } + catch(IllegalAccessException e) { + throw new RuntimeException(e); + } + catch(InvocationTargetException e) { + throw new RuntimeException(e); + } + } + + static void clean(Object base) { + try { + Object cleaner = mCleaner.invoke(base); + mClean.invoke(cleaner); + } + catch(Throwable e) { + throw new RuntimeException(e); + } + } + + static boolean isDirectByteBufferInstance(Object s) { + return directByteBufferClass.isInstance(s); + } + + static ByteBuffer newByteBuffer(long address, int index, int length, ByteBuffer reference) { + try { + switch(directBufferConstructorType) { + case ARGS_LONG_INT_REF: + return (ByteBuffer) byteBufferConstructor.newInstance(address + index, length, reference); + case ARGS_LONG_INT: + return (ByteBuffer) byteBufferConstructor.newInstance(address + index, length); + case ARGS_INT_INT: + return (ByteBuffer) byteBufferConstructor.newInstance((int) address + index, length); + case ARGS_MB_INT_INT: + return (ByteBuffer) byteBufferConstructor.newInstance( + memoryBlockWrapFromJni.invoke(null, address + index, length), + length, 0); + default: + throw new IllegalStateException("Unexpected value"); + } + } + catch(Throwable e) { + // Convert checked exception to unchecked exception + throw new RuntimeException(e); + } + } +} diff --git a/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBuffer.java b/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBuffer.java index 260f8b017..807cdfba9 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBuffer.java +++ b/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBuffer.java @@ -5,12 +5,9 @@ import java.lang.reflect.Constructor; import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; import java.nio.BufferOverflowException; import java.nio.ByteBuffer; import java.nio.ByteOrder; -import java.security.AccessControlException; import static org.msgpack.core.Preconditions.*; @@ -26,18 +23,10 @@ public class MessageBuffer { static final boolean isUniversalBuffer; static final Unsafe unsafe; - // TODO We should use MethodHandle for efficiency, but it is not available in JDK6 + static final int ARRAY_BYTE_BASE_OFFSET; static final int ARRAY_BYTE_INDEX_SCALE; - enum DirectBufferConstructorType { - ARGS_LONG_INT_REF, - ARGS_LONG_INT, - ARGS_INT_INT, - ARGS_MB_INT_INT, - NONE - } - static { try { // Check java version @@ -134,133 +123,6 @@ enum DirectBufferConstructorType { } } - /** - * Wraps the difference of access methods to DirectBuffers between Android and others. - */ - private static class DirectBufferAccess { - static Method mGetAddress; - static Method mCleaner; - static Method mClean; - - static Constructor byteBufferConstructor; - - static Class directByteBufferClass; - static DirectBufferConstructorType directBufferConstructorType; - static Method memoryBlockWrapFromJni; - - static { - try { - if(!isUniversalBuffer) { - try { - // Find the hidden constructor for DirectByteBuffer - directByteBufferClass = ClassLoader.getSystemClassLoader().loadClass("java.nio.DirectByteBuffer"); - Constructor directByteBufferConstructor = null; - DirectBufferConstructorType constructorType = null; - Method mbWrap = null; - try { - // TODO We should use MethodHandle for Java7, which can avoid the cost of boxing with JIT optimization - directByteBufferConstructor = directByteBufferClass.getDeclaredConstructor(long.class, int.class, Object.class); - constructorType = DirectBufferConstructorType.ARGS_LONG_INT_REF; - } - catch(NoSuchMethodException e0) { - try { - // https://android.googlesource.com/platform/libcore/+/master/luni/src/main/java/java/nio/DirectByteBuffer.java - // DirectByteBuffer(long address, int capacity) - directByteBufferConstructor = directByteBufferClass.getDeclaredConstructor(long.class, int.class); - constructorType = DirectBufferConstructorType.ARGS_LONG_INT; - } - catch(NoSuchMethodException e1) { - try { - directByteBufferConstructor = directByteBufferClass.getDeclaredConstructor(int.class, int.class); - constructorType = DirectBufferConstructorType.ARGS_INT_INT; - } - catch(NoSuchMethodException e2) { - Class aClass = Class.forName("java.nio.MemoryBlock"); - mbWrap = aClass.getDeclaredMethod("wrapFromJni", int.class, long.class); - mbWrap.setAccessible(true); - directByteBufferConstructor = directByteBufferClass.getDeclaredConstructor(aClass, int.class, int.class); - constructorType = DirectBufferConstructorType.ARGS_MB_INT_INT; - } - } - } - - byteBufferConstructor = directByteBufferConstructor; - directBufferConstructorType = constructorType; - memoryBlockWrapFromJni = mbWrap; - - if(byteBufferConstructor == null) - throw new RuntimeException("Constructor of DirectByteBuffer is not found"); - byteBufferConstructor.setAccessible(true); - } - catch(Exception e) { - directBufferConstructorType = DirectBufferConstructorType.NONE; - } - } - - mGetAddress = directByteBufferClass.getDeclaredMethod("address"); - mGetAddress.setAccessible(true); - - mCleaner = directByteBufferClass.getDeclaredMethod("cleaner"); - mCleaner.setAccessible(true); - - mClean = mCleaner.getReturnType().getDeclaredMethod("clean"); - mClean.setAccessible(true); - } - catch(NoSuchMethodException e) { - throw new RuntimeException(e); - } - } - - static long getAddress(Object base) { - try { - return (Long) mGetAddress.invoke(base); - } - catch(IllegalAccessException e) { - throw new RuntimeException(e); - } - catch(InvocationTargetException e) { - throw new RuntimeException(e); - } - } - - static void clean(Object base) { - try { - Object cleaner = mCleaner.invoke(base); - mClean.invoke(cleaner); - } - catch(Throwable e) { - throw new RuntimeException(e); - } - } - - static boolean isDirectByteBufferInstance(Object s) { - return directByteBufferClass.isInstance(s); - } - - static ByteBuffer newByteBuffer(long address, int index, int length, ByteBuffer reference) { - try { - switch(directBufferConstructorType) { - case ARGS_LONG_INT_REF: - return (ByteBuffer) byteBufferConstructor.newInstance(address + index, length, reference); - case ARGS_LONG_INT: - return (ByteBuffer) byteBufferConstructor.newInstance(address + index, length); - case ARGS_INT_INT: - return (ByteBuffer) byteBufferConstructor.newInstance((int) address + index, length); - case ARGS_MB_INT_INT: - return (ByteBuffer) byteBufferConstructor.newInstance( - memoryBlockWrapFromJni.invoke(null, address + index, length), - length, 0); - default: - throw new IllegalStateException("Unexpected value"); - } - } - catch(Throwable e) { - // Convert checked exception to unchecked exception - throw new RuntimeException(e); - } - } - } - /** * MessageBuffer class to use. If this machine is big-endian, it uses MessageBufferBE, which overrides some methods in this class that translate endians. If not, uses MessageBuffer. */ @@ -295,10 +157,6 @@ static ByteBuffer newByteBuffer(long address, int index, int length, ByteBuffer */ protected final ByteBuffer reference; - // TODO life-time management of this buffer - //private AtomicInteger referenceCounter; - - static MessageBuffer newOffHeapBuffer(int length) { // This method is not available in Android OS if(!isUniversalBuffer) { @@ -362,7 +220,7 @@ private static MessageBuffer newMessageBuffer(byte[] arr) { } public static void releaseBuffer(MessageBuffer buffer) { - if(buffer.base instanceof byte[]) { + if(isUniversalBuffer || buffer.base instanceof byte[]) { // We have nothing to do. Wait until the garbage-collector collects this array object } else if(DirectBufferAccess.isDirectByteBufferInstance(buffer.base)) { @@ -394,6 +252,9 @@ else if(DirectBufferAccess.isDirectByteBufferInstance(buffer.base)) { */ MessageBuffer(ByteBuffer bb) { if(bb.isDirect()) { + if(isUniversalBuffer) { + throw new IllegalStateException("Cannot create MessageBuffer from DirectBuffer"); + } // Direct buffer or off-heap memory this.base = null; this.address = DirectBufferAccess.getAddress(bb); From 290298a5f9d02b9490e4341eb6df65e67109ceac Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Wed, 11 Feb 2015 04:32:56 +0900 Subject: [PATCH 005/234] Report errors on exception --- .../java/org/msgpack/core/buffer/DirectBufferAccess.java | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/msgpack-core/src/main/java/org/msgpack/core/buffer/DirectBufferAccess.java b/msgpack-core/src/main/java/org/msgpack/core/buffer/DirectBufferAccess.java index c31014975..f0e5091b6 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/buffer/DirectBufferAccess.java +++ b/msgpack-core/src/main/java/org/msgpack/core/buffer/DirectBufferAccess.java @@ -69,12 +69,7 @@ enum DirectBufferConstructorType { if(byteBufferConstructor == null) throw new RuntimeException("Constructor of DirectByteBuffer is not found"); byteBufferConstructor.setAccessible(true); - } - catch(Exception e) { - - } - try { mGetAddress = directByteBufferClass.getDeclaredMethod("address"); mGetAddress.setAccessible(true); @@ -84,7 +79,7 @@ enum DirectBufferConstructorType { mClean = mCleaner.getReturnType().getDeclaredMethod("clean"); mClean.setAccessible(true); } - catch(NoSuchMethodException e) { + catch(Exception e) { throw new RuntimeException(e); } } From ad711dbea72c1850c8bd05b1983945c621ad78a9 Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Wed, 11 Feb 2015 04:36:46 +0900 Subject: [PATCH 006/234] Add assertions --- .../src/main/java/org/msgpack/core/buffer/MessageBuffer.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBuffer.java b/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBuffer.java index 807cdfba9..592823a06 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBuffer.java +++ b/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBuffer.java @@ -406,6 +406,7 @@ public void putBytes(int index, byte[] src, int srcOffset, int length) { public void putByteBuffer(int index, ByteBuffer src, int len) { assert (len <= src.remaining()); + assert (!isUniversalBuffer); if(src.isDirect()) { unsafe.copyMemory(null, DirectBufferAccess.getAddress(src) + src.position(), base, address + index, len); @@ -439,6 +440,7 @@ public ByteBuffer toByteBuffer(int index, int length) { return ByteBuffer.wrap((byte[]) base, (int) ((address - ARRAY_BYTE_BASE_OFFSET) + index), length); } else { + assert (!isUniversalBuffer); return DirectBufferAccess.newByteBuffer(address, index, length, reference); } } From 28485bc5380440669e958cec7f7718e1f90de600 Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Thu, 12 Feb 2015 00:22:32 +0900 Subject: [PATCH 007/234] Remove TravisCI e-mail notfication. --- .travis.yml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/.travis.yml b/.travis.yml index cd27c1101..4c1703220 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,9 +13,3 @@ branches: - /^v07.*$/ script: sbt ++$TRAVIS_SCALA_VERSION test - -notifications: - email: - - ozawa.tsuyoshi@gmail.com - - leo@xerial.org - - komamitsu@gmail.com From a1991c98def948b1c3e5327bfde576f9ffbc793f Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Sun, 15 Feb 2015 22:11:14 +0900 Subject: [PATCH 008/234] Removed unused variable --- .../src/main/java/org/msgpack/core/buffer/MessageBuffer.java | 1 - 1 file changed, 1 deletion(-) diff --git a/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBuffer.java b/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBuffer.java index 592823a06..1638847a8 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBuffer.java +++ b/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBuffer.java @@ -85,7 +85,6 @@ public class MessageBuffer { } // Fetch theUnsafe object for Oracle and OpenJDK - Unsafe u; Field field = Unsafe.class.getDeclaredField("theUnsafe"); field.setAccessible(true); unsafe = (Unsafe) field.get(null); From 5fd6964a016417afce7bf277c1074bde8a0076fc Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Sun, 15 Feb 2015 23:22:37 +0900 Subject: [PATCH 009/234] Clean up MessageBuffer initialization. Add fallback to MesssageBufferU --- .../msgpack/core/buffer/MessageBuffer.java | 116 ++++++++++-------- 1 file changed, 63 insertions(+), 53 deletions(-) diff --git a/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBuffer.java b/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBuffer.java index 1638847a8..50a84ac3c 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBuffer.java +++ b/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBuffer.java @@ -23,11 +23,26 @@ public class MessageBuffer { static final boolean isUniversalBuffer; static final Unsafe unsafe; + /** + * Reference to MessageBuffer Constructors + */ + private final static Constructor mbArrConstructor; + private final static Constructor mbBBConstructor; + /** + * The offset from the object memory header to its byte array data + */ static final int ARRAY_BYTE_BASE_OFFSET; - static final int ARRAY_BYTE_INDEX_SCALE; static { + boolean useUniversalBuffer = false; + Unsafe unsafeInstance = null; + int arrayByteBaseOffset = 16; + + final String UNIVERSAL_MESSAGE_BUFFER = "org.msgpack.core.buffer.MessageBufferU"; + final String BIGENDIAN_MESSAGE_BUFFER = "org.msgpack.core.buffer.MessageBufferBE"; + final String DEFAULT_MESSAGE_BUFFER = "org.msgpack.core.buffer.MessageBuffer"; + try { // Check java version String javaVersion = System.getProperty("java.specification.version", ""); @@ -58,80 +73,75 @@ public class MessageBuffer { boolean isGAE = System.getProperty("com.google.appengine.runtime.version") != null; // For Java6, android and JVM that has no Unsafe class, use Universal MessageBuffer - isUniversalBuffer = + useUniversalBuffer = Boolean.parseBoolean(System.getProperty("msgpack.universal-buffer", "false")) || isAndroid || isGAE || !isJavaAtLeast7 || !hasUnsafe; - // We need to use reflection to find MessageBuffer implementation classes because - // importing these classes creates TypeProfile and adds some overhead to method calls. - String bufferClsName; - if(isUniversalBuffer) { - bufferClsName = "org.msgpack.core.buffer.MessageBufferU"; - unsafe = null; - ARRAY_BYTE_BASE_OFFSET = 16; // dummy value - ARRAY_BYTE_INDEX_SCALE = 1; - } - else { - // Check the endian of this CPU - boolean isLittleEndian = ByteOrder.nativeOrder() == ByteOrder.LITTLE_ENDIAN; - if(isLittleEndian) { - bufferClsName = "org.msgpack.core.buffer.MessageBuffer"; - } - else { - bufferClsName = "org.msgpack.core.buffer.MessageBufferBE"; - } - + if(!useUniversalBuffer) { // Fetch theUnsafe object for Oracle and OpenJDK Field field = Unsafe.class.getDeclaredField("theUnsafe"); field.setAccessible(true); - unsafe = (Unsafe) field.get(null); - if(unsafe == null) { + unsafeInstance = (Unsafe) field.get(null); + if(unsafeInstance == null) { throw new RuntimeException("Unsafe is unavailable"); } - ARRAY_BYTE_BASE_OFFSET = unsafe.arrayBaseOffset(byte[].class); - ARRAY_BYTE_INDEX_SCALE = unsafe.arrayIndexScale(byte[].class); + arrayByteBaseOffset = unsafeInstance.arrayBaseOffset(byte[].class); + int arrayByteIndexScale = unsafeInstance.arrayIndexScale(byte[].class); // Make sure the VM thinks bytes are only one byte wide - if(ARRAY_BYTE_INDEX_SCALE != 1) { - throw new IllegalStateException("Byte array index scale must be 1, but is " + ARRAY_BYTE_INDEX_SCALE); + if(arrayByteIndexScale != 1) { + throw new IllegalStateException("Byte array index scale must be 1, but is " + arrayByteIndexScale); } } - Class bufferCls = Class.forName(bufferClsName); - msgBufferClass = bufferCls; - - Constructor mbArrCstr = bufferCls.getDeclaredConstructor(byte[].class); - mbArrCstr.setAccessible(true); - mbArrConstructor = mbArrCstr; - - Constructor mbBBCstr = bufferCls.getDeclaredConstructor(ByteBuffer.class); - mbBBCstr.setAccessible(true); - mbBBConstructor = mbBBCstr; - - // Requires Java7 - //newMsgBuffer = MethodHandles.lookup().unreflectConstructor(mbArrCstr).asType( - // MethodType.methodType(bufferCls, byte[].class) - //); - } catch(Exception e) { e.printStackTrace(System.err); - throw new RuntimeException(e); + // Use MessageBufferU + useUniversalBuffer = true; } - } + finally { + // Initialize the static fields + unsafe = unsafeInstance; + ARRAY_BYTE_BASE_OFFSET = arrayByteBaseOffset; - /** - * MessageBuffer class to use. If this machine is big-endian, it uses MessageBufferBE, which overrides some methods in this class that translate endians. If not, uses MessageBuffer. - */ - private final static Class msgBufferClass; + // Switch MessageBuffer implementation according to the environment + isUniversalBuffer = useUniversalBuffer; + String bufferClsName; + if(isUniversalBuffer) { + bufferClsName = UNIVERSAL_MESSAGE_BUFFER; + } + else { + // Check the endian of this CPU + boolean isLittleEndian = ByteOrder.nativeOrder() == ByteOrder.LITTLE_ENDIAN; + bufferClsName = isLittleEndian ? DEFAULT_MESSAGE_BUFFER : BIGENDIAN_MESSAGE_BUFFER; + } - private final static Constructor mbArrConstructor; - private final static Constructor mbBBConstructor; + try { + // We need to use reflection here to find MessageBuffer implementation classes because + // importing these classes creates TypeProfile and adds some overhead to method calls. + + // MessageBufferX (default, BE or U) class + Class bufferCls = Class.forName(bufferClsName); - // Requires Java7 - //private final static MethodHandle newMsgBuffer; + // MessageBufferX(byte[]) constructor + Constructor mbArrCstr = bufferCls.getDeclaredConstructor(byte[].class); + mbArrCstr.setAccessible(true); + mbArrConstructor = mbArrCstr; + + // MessageBufferX(ByteBuffer) constructor + Constructor mbBBCstr = bufferCls.getDeclaredConstructor(ByteBuffer.class); + mbBBCstr.setAccessible(true); + mbBBConstructor = mbBBCstr; + } + catch(Exception e){ + e.printStackTrace(System.err); + throw new RuntimeException(e); // No more fallback exists if MessageBuffer constructors are inaccessible + } + } + } /** * Base object for resolving the relative address of the raw byte array. From 5526d1c991ab0f1319181df6725a8bf13b77b08a Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Mon, 16 Feb 2015 11:01:17 +0900 Subject: [PATCH 010/234] Add 0.7.0-p7 release notes --- README.md | 4 ++-- RELEASE_NOTES.md | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index da7e4cfa6..f8f0a164c 100644 --- a/README.md +++ b/README.md @@ -17,13 +17,13 @@ For Maven users: org.msgpack msgpack-core - 0.7.0-p5 + 0.7.0-p7 ``` For sbt users: ``` -libraryDependencies += "org.msgpack" % "msgpack-core" % "0.7.0-p5" +libraryDependencies += "org.msgpack" % "msgpack-core" % "0.7.0-p7" ``` - [Usage examples](msgpack-core/src/main/java/org/msgpack/core/example/MessagePackExample.java) diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index 1fa8c0f7a..f885d433a 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -1,5 +1,8 @@ # Release Notes +* 2015-02-16 0.7.0-p7 + * Google App Engine (GAE) support + * 2015-02-11 0.7.0-p6 * Add MessagePacker.getTotalWrittenBytes() From be2bf7fa4b3f87f1626e7146787795c95c7e67ad Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Mon, 16 Feb 2015 11:34:27 +0900 Subject: [PATCH 011/234] Setting version to 0.7.0-p7 --- version.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.sbt b/version.sbt index ab66eef97..f91e5502a 100644 --- a/version.sbt +++ b/version.sbt @@ -1 +1 @@ -version in ThisBuild := "0.7.0-p7-SNAPSHOT" \ No newline at end of file +version in ThisBuild := "0.7.0-p7" \ No newline at end of file From d2e7a0826c2462e9d0207a9c2fa6848a4a6394a3 Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Mon, 16 Feb 2015 11:34:48 +0900 Subject: [PATCH 012/234] Setting version to 0.7.0-p8-SNAPSHOT --- version.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.sbt b/version.sbt index f91e5502a..3bc36f7f8 100644 --- a/version.sbt +++ b/version.sbt @@ -1 +1 @@ -version in ThisBuild := "0.7.0-p7" \ No newline at end of file +version in ThisBuild := "0.7.0-p8-SNAPSHOT" \ No newline at end of file From 0f4acff4f3a4b065a79898a6f8471dfdfe01ee3c Mon Sep 17 00:00:00 2001 From: "Ramon Marco L. Navarro" Date: Wed, 25 Feb 2015 17:19:37 +0800 Subject: [PATCH 013/234] jackson: Add support for Extended type --- .../jackson/dataformat/MessagePackParser.java | 15 ++++++++-- .../dataformat/MessagePackParserTest.java | 28 +++++++++++++++---- 2 files changed, 36 insertions(+), 7 deletions(-) diff --git a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java index 926b5691b..c3f7314d1 100644 --- a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java +++ b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java @@ -10,6 +10,7 @@ import org.msgpack.core.buffer.ArrayBufferInput; import org.msgpack.core.buffer.InputStreamBufferInput; import org.msgpack.core.buffer.MessageBufferInput; +import org.msgpack.value.ValueRef; import org.msgpack.value.NumberValue; import org.msgpack.value.ValueType; import org.msgpack.value.holder.ValueHolder; @@ -160,7 +161,9 @@ public JsonToken nextToken() throws IOException, JsonParseException { newStack = new StackItemForObject(messageUnpacker.unpackMapHeader()); break; case EXTENDED: - throw new UnsupportedOperationException(); + messageUnpacker.unpackValue(valueHolder); + nextToken = JsonToken.VALUE_EMBEDDED_OBJECT; + break; default: throw new IllegalStateException("Shouldn't reach here"); } @@ -266,7 +269,15 @@ public BigDecimal getDecimalValue() throws IOException { @Override public Object getEmbeddedObject() throws IOException, JsonParseException { - return valueHolder.getRef().asBinary().toByteArray(); + ValueRef ref = valueHolder.getRef(); + + if (ref.isBinary()) { + return ref.asBinary().toByteArray(); + } else if (ref.isExtended()) { + return ref.asExtended().toValue(); + } else { + throw new UnsupportedOperationException(); + } } @Override diff --git a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackParserTest.java b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackParserTest.java index dfba2e25f..5a6f54fd4 100644 --- a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackParserTest.java +++ b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackParserTest.java @@ -7,6 +7,7 @@ import org.msgpack.core.MessagePack; import org.msgpack.core.MessagePacker; import org.msgpack.core.buffer.OutputStreamBufferOutput; +import org.msgpack.value.ExtendedValue; import java.io.*; import java.math.BigInteger; @@ -15,13 +16,14 @@ import java.util.Map; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertTrue; public class MessagePackParserTest extends MessagePackDataformatTestBase { @Test public void testParserShouldReadObject() throws IOException { MessagePacker packer = new MessagePacker(new OutputStreamBufferOutput(out)); - packer.packMapHeader(8); + packer.packMapHeader(9); // #1 packer.packString("str"); packer.packString("foobar"); @@ -58,6 +60,11 @@ public void testParserShouldReadObject() throws IOException { // #8 packer.packString("bool"); packer.packBoolean(false); + // #9 + byte[] extPayload = {-80, -50, -25, -114, -25, 16, 60, 68}; + packer.packString("ext"); + packer.packExtendedTypeHeader(2, extPayload.length); + packer.writePayload(extPayload); packer.flush(); @@ -65,7 +72,7 @@ public void testParserShouldReadObject() throws IOException { TypeReference> typeReference = new TypeReference>(){}; Map object = objectMapper.readValue(bytes, typeReference); - assertEquals(8, object.keySet().size()); + assertEquals(9, object.keySet().size()); int bitmap = 0; for (Map.Entry entry : object.entrySet()) { @@ -128,14 +135,19 @@ else if (k.equals("bool")) { bitmap |= 1 << 9; assertEquals(false, v); } + else if (k.equals("ext")) { + // #9 + bitmap |= 1 << 10; + assertArrayEquals(extPayload, ((ExtendedValue) v).toByteArray()); + } } - assertEquals(0x3FF, bitmap); + assertEquals(0x7FF, bitmap); } @Test public void testParserShouldReadArray() throws IOException { MessagePacker packer = new MessagePacker(new OutputStreamBufferOutput(out)); - packer.packArrayHeader(10); + packer.packArrayHeader(11); // #1 packer.packArrayHeader(3); { @@ -171,6 +183,10 @@ public void testParserShouldReadArray() throws IOException { } // #10 packer.packBoolean(true); + // #11 + byte[] extPayload = {-80, -50, -25, -114, -25, 16, 60, 68}; + packer.packExtendedTypeHeader(2, extPayload.length); + packer.writePayload(extPayload); packer.flush(); @@ -178,7 +194,7 @@ public void testParserShouldReadArray() throws IOException { TypeReference> typeReference = new TypeReference>(){}; List array = objectMapper.readValue(bytes, typeReference); - assertEquals(10, array.size()); + assertEquals(11, array.size()); int i = 0; // #1 @SuppressWarnings("unchecked") @@ -226,6 +242,8 @@ else if (k.equals("child_map_age")) { } // #10 assertEquals(true, array.get(i++)); + // #11 + assertArrayEquals(extPayload, ((ExtendedValue) array.get(i++)).toByteArray()); } @Test From 9f2d99acd439404e3329befb52c4da24934e6f78 Mon Sep 17 00:00:00 2001 From: xuwei-k <6b656e6a69@gmail.com> Date: Fri, 27 Feb 2015 07:44:04 +0900 Subject: [PATCH 014/234] update some dependencies --- project/Build.scala | 18 ++++++++++-------- project/plugins.sbt | 2 +- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/project/Build.scala b/project/Build.scala index fa800c3d7..6f2e36e85 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -157,19 +157,21 @@ object Build extends Build { object Dependencies { + val junitInterface = "com.novocode" % "junit-interface" % "0.11" % "test" + val testLib = Seq( - "org.scalatest" % "scalatest_2.11" % "2.2.0" % "test", - "org.scalacheck" % "scalacheck_2.11" % "1.11.4" % "test", - "org.xerial" % "xerial-core" % "3.3.0" % "test", - "org.msgpack" % "msgpack" % "0.6.9" % "test", - "com.novocode" % "junit-interface" % "0.10" % "test", - "commons-codec" % "commons-codec" % "1.9" % "test" + "org.scalatest" %% "scalatest" % "2.2.4" % "test", + "org.scalacheck" %% "scalacheck" % "1.12.2" % "test", + "org.xerial" % "xerial-core" % "3.3.5" % "test", + "org.msgpack" % "msgpack" % "0.6.11" % "test", + junitInterface, + "commons-codec" % "commons-codec" % "1.10" % "test" ) val jacksonLib = Seq( "com.fasterxml.jackson.core" % "jackson-databind" % "2.4.4", - "com.novocode" % "junit-interface" % "0.10" % "test", - "org.apache.commons" % "commons-math3" % "3.3" % "test" + junitInterface, + "org.apache.commons" % "commons-math3" % "3.4.1" % "test" ) } diff --git a/project/plugins.sbt b/project/plugins.sbt index 2ce2dad4c..eb6a52a1b 100755 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -9,6 +9,6 @@ addSbtPlugin("com.github.mpeltonen" % "sbt-idea" % "1.6.0") addSbtPlugin("de.johoop" % "findbugs4sbt" % "1.3.0") -addSbtPlugin("de.johoop" % "jacoco4sbt" % "2.1.5") +addSbtPlugin("de.johoop" % "jacoco4sbt" % "2.1.6") scalacOptions ++= Seq("-deprecation", "-feature") From 92fee71a5afa6f5ec0a79c9691592f3f4b62c3c9 Mon Sep 17 00:00:00 2001 From: Mitsunori Komatsu Date: Sat, 7 Mar 2015 22:12:23 +0900 Subject: [PATCH 015/234] Make MessagePackParser#getEmbeddedObject return MessagePackExtendedType --- .../dataformat/MessagePackExtendedType.java | 25 ++++++++ .../jackson/dataformat/MessagePackParser.java | 10 +++- .../MessagePackExtendedTypeTest.java | 60 +++++++++++++++++++ .../dataformat/MessagePackParserTest.java | 13 ++-- 4 files changed, 101 insertions(+), 7 deletions(-) create mode 100644 msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackExtendedType.java create mode 100644 msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackExtendedTypeTest.java diff --git a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackExtendedType.java b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackExtendedType.java new file mode 100644 index 000000000..96bfac2c8 --- /dev/null +++ b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackExtendedType.java @@ -0,0 +1,25 @@ +package org.msgpack.jackson.dataformat; + +import java.nio.ByteBuffer; + +/** + * Created by komamitsu on 3/7/15. + */ +public class MessagePackExtendedType { + private final int extType; + private final ByteBuffer byteBuffer; + + public MessagePackExtendedType(int extType, ByteBuffer byteBuffer) { + this.extType = extType; + this.byteBuffer = byteBuffer.isReadOnly() ? + byteBuffer : byteBuffer.asReadOnlyBuffer(); + } + + public int extType() { + return extType; + } + + public ByteBuffer byteBuffer() { + return byteBuffer; + } +} diff --git a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java index c3f7314d1..7cd666d44 100644 --- a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java +++ b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java @@ -10,6 +10,7 @@ import org.msgpack.core.buffer.ArrayBufferInput; import org.msgpack.core.buffer.InputStreamBufferInput; import org.msgpack.core.buffer.MessageBufferInput; +import org.msgpack.value.ExtendedValue; import org.msgpack.value.ValueRef; import org.msgpack.value.NumberValue; import org.msgpack.value.ValueType; @@ -272,11 +273,14 @@ public Object getEmbeddedObject() throws IOException, JsonParseException { ValueRef ref = valueHolder.getRef(); if (ref.isBinary()) { - return ref.asBinary().toByteArray(); + return ref.asBinary().toByteArray(); } else if (ref.isExtended()) { - return ref.asExtended().toValue(); + ExtendedValue extendedValue = ref.asExtended().toValue(); + MessagePackExtendedType extendedType = + new MessagePackExtendedType(extendedValue.getExtType(), extendedValue.toByteBuffer()); + return extendedType; } else { - throw new UnsupportedOperationException(); + throw new UnsupportedOperationException(); } } diff --git a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackExtendedTypeTest.java b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackExtendedTypeTest.java new file mode 100644 index 000000000..682773a7a --- /dev/null +++ b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackExtendedTypeTest.java @@ -0,0 +1,60 @@ +package org.msgpack.jackson.dataformat; + +import org.junit.Test; + +import java.nio.ByteBuffer; + +import static org.junit.Assert.*; + +public class MessagePackExtendedTypeTest { + private void assertExtendedType(MessagePackExtendedType x, + int expectedExtType, ByteBuffer expectedByteBuffer) { + assertEquals(expectedExtType, x.extType()); + assertEquals(expectedByteBuffer, x.byteBuffer()); + assertTrue(x.byteBuffer().isReadOnly()); + } + + @Test + public void testMessagePackExtendedType() { + byte[] bs = new byte[] {0x00, (byte) 0xCC, (byte) 0xFF}; + ByteBuffer expectedByteBuffer = ByteBuffer.wrap(bs); + + int extType = 1; + MessagePackExtendedType extendedType = + new MessagePackExtendedType(extType, ByteBuffer.wrap(bs)); + assertExtendedType(extendedType, extType, expectedByteBuffer); + + extType = 2; + ByteBuffer bb = ByteBuffer.allocate(3); + bb.put(bs); + bb.position(0); + extendedType = new MessagePackExtendedType(extType, bb); + assertExtendedType(extendedType, extType, expectedByteBuffer); + + extType = 3; + bb = ByteBuffer.allocateDirect(3); + bb.put(bs); + bb.position(0); + extendedType = new MessagePackExtendedType(extType, bb); + assertExtendedType(extendedType, extType, expectedByteBuffer); + + extType = -1; + extendedType = + new MessagePackExtendedType(extType, ByteBuffer.wrap(bs).asReadOnlyBuffer()); + assertExtendedType(extendedType, extType, expectedByteBuffer); + + extType = -2; + bb = ByteBuffer.allocate(3); + bb.put(bs); + bb.position(0); + extendedType = new MessagePackExtendedType(extType, bb.asReadOnlyBuffer()); + assertExtendedType(extendedType, extType, expectedByteBuffer); + + extType = -3; + bb = ByteBuffer.allocateDirect(3); + bb.put(bs); + bb.position(0); + extendedType = new MessagePackExtendedType(extType, bb.asReadOnlyBuffer()); + assertExtendedType(extendedType, extType, expectedByteBuffer); + } +} \ No newline at end of file diff --git a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackParserTest.java b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackParserTest.java index 5a6f54fd4..f29de3179 100644 --- a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackParserTest.java +++ b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackParserTest.java @@ -11,6 +11,7 @@ import java.io.*; import java.math.BigInteger; +import java.nio.ByteBuffer; import java.util.Arrays; import java.util.List; import java.util.Map; @@ -63,7 +64,7 @@ public void testParserShouldReadObject() throws IOException { // #9 byte[] extPayload = {-80, -50, -25, -114, -25, 16, 60, 68}; packer.packString("ext"); - packer.packExtendedTypeHeader(2, extPayload.length); + packer.packExtendedTypeHeader(0, extPayload.length); packer.writePayload(extPayload); packer.flush(); @@ -138,7 +139,9 @@ else if (k.equals("bool")) { else if (k.equals("ext")) { // #9 bitmap |= 1 << 10; - assertArrayEquals(extPayload, ((ExtendedValue) v).toByteArray()); + MessagePackExtendedType extendedType = (MessagePackExtendedType) v; + assertEquals(0, extendedType.extType()); + assertEquals(ByteBuffer.wrap(extPayload), extendedType.byteBuffer()); } } assertEquals(0x7FF, bitmap); @@ -185,7 +188,7 @@ public void testParserShouldReadArray() throws IOException { packer.packBoolean(true); // #11 byte[] extPayload = {-80, -50, -25, -114, -25, 16, 60, 68}; - packer.packExtendedTypeHeader(2, extPayload.length); + packer.packExtendedTypeHeader(-1, extPayload.length); packer.writePayload(extPayload); packer.flush(); @@ -243,7 +246,9 @@ else if (k.equals("child_map_age")) { // #10 assertEquals(true, array.get(i++)); // #11 - assertArrayEquals(extPayload, ((ExtendedValue) array.get(i++)).toByteArray()); + MessagePackExtendedType extendedType = (MessagePackExtendedType) array.get(i++); + assertEquals(-1, extendedType.extType()); + assertEquals(ByteBuffer.wrap(extPayload), extendedType.byteBuffer()); } @Test From 44be4951f2ba04b84de204fa9edbe1f1440191d2 Mon Sep 17 00:00:00 2001 From: Drew Kutcharian Date: Thu, 12 Mar 2015 23:32:19 -0700 Subject: [PATCH 016/234] Fixing the contract of nextToken to be compliant with com.fasterxml.jackson.core.JsonParser.nextToken() and not throw an EOFException if at the end of the stream --- .../msgpack/jackson/dataformat/MessagePackParser.java | 4 ++++ .../jackson/dataformat/MessagePackParserTest.java | 10 +++------- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java index 7cd666d44..bd3c63fc9 100644 --- a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java +++ b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java @@ -118,6 +118,10 @@ public JsonToken nextToken() throws IOException, JsonParseException { } } + if (!messageUnpacker.hasNext()) { + return null; + } + MessageFormat nextFormat = messageUnpacker.getNextFormat(); ValueType valueType = nextFormat.getValueType(); diff --git a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackParserTest.java b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackParserTest.java index f29de3179..81268d24b 100644 --- a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackParserTest.java +++ b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackParserTest.java @@ -19,6 +19,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertTrue; +import static org.junit.Assert.assertNull; public class MessagePackParserTest extends MessagePackDataformatTestBase { @Test @@ -309,13 +310,8 @@ public void testMessagePackParserDirectly() throws IOException { assertEquals(-1, parser.getCurrentLocation().getLineNr()); assertEquals(16, parser.getCurrentLocation().getColumnNr()); - try { - parser.nextToken(); - assertTrue(false); - } - catch (EOFException e) { - // Expected - } + assertNull(parser.nextToken()); + parser.close(); parser.close(); // Intentional } From c10decef12f06d0252add33c699310a1a7c544e1 Mon Sep 17 00:00:00 2001 From: Drew Kutcharian Date: Fri, 13 Mar 2015 13:04:32 -0700 Subject: [PATCH 017/234] add BigDecimal support --- .../dataformat/MessagePackGenerator.java | 18 ++++++++++++++++-- .../jackson/dataformat/MessagePackParser.java | 19 ++++++++++++++++++- 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackGenerator.java b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackGenerator.java index 7e21ff58b..19231e4f3 100644 --- a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackGenerator.java +++ b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackGenerator.java @@ -5,6 +5,7 @@ import com.fasterxml.jackson.core.ObjectCodec; import com.fasterxml.jackson.core.base.GeneratorBase; import com.fasterxml.jackson.core.json.JsonWriteContext; + import org.msgpack.core.MessagePacker; import org.msgpack.core.buffer.OutputStreamBufferOutput; @@ -17,6 +18,7 @@ import java.util.ArrayList; import java.util.LinkedList; import java.util.List; +import java.math.MathContext; public class MessagePackGenerator extends GeneratorBase { private static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8"); @@ -169,8 +171,20 @@ else if (v instanceof BigInteger) { messagePacker.packBigInteger((BigInteger) v); } else if (v instanceof BigDecimal) { - // TODO - throw new UnsupportedOperationException("BigDecimal isn't supported yet"); + BigDecimal decimal = (BigDecimal) v; + try { + //Check to see if this BigDecimal can be converted to BigInteger + BigInteger integer = decimal.toBigIntegerExact(); + messagePacker.packBigInteger(integer); + } catch (ArithmeticException e){ + //If not an integer, then try converting to double + double doubleValue = decimal.doubleValue(); + //Check to make sure this BigDecimal can be represented as a double + if (!new BigDecimal(doubleValue, MathContext.DECIMAL128).equals(decimal)) { + throw new IllegalArgumentException("Messagepack cannot serialize a BigDecimal that can't be represented as double"); + } + messagePacker.packDouble(doubleValue); + } } else if (v instanceof Boolean) { messagePacker.packBoolean((Boolean) v); diff --git a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java index 7cd666d44..03a40fba0 100644 --- a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java +++ b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java @@ -265,7 +265,24 @@ public double getDoubleValue() throws IOException, JsonParseException { @Override public BigDecimal getDecimalValue() throws IOException { - return null; + ValueRef ref = valueHolder.getRef(); + + if (ref.isInteger()) { + NumberValue number = ref.asNumber(); + //optimization to not convert the value to BigInteger unnecessarily + if (number.isValidByte() || number.isValidShort() || number.isValidInt() || number.isValidLong()) { + return BigDecimal.valueOf(number.asInt()); + } + else { + return new BigDecimal(number.asBigInteger()); + } + } + + if (ref.isFloat()) { + return BigDecimal.valueOf(ref.asFloat().toDouble()); + } + + throw new UnsupportedOperationException("couldn't parse value as BigDecimal"); } @Override From 83b64722040b2e2a73e337bd0a64d3461c7da518 Mon Sep 17 00:00:00 2001 From: Mitsunori Komatsu Date: Sat, 14 Mar 2015 22:35:05 +0900 Subject: [PATCH 018/234] Add unit tests for PR #205 and fix some bugs --- .../dataformat/MessagePackGenerator.java | 42 +++++++++------- .../jackson/dataformat/MessagePackParser.java | 8 +-- .../dataformat/MessagePackGeneratorTest.java | 50 +++++++++++++++++-- .../dataformat/MessagePackParserTest.java | 30 ++++++++++- 4 files changed, 102 insertions(+), 28 deletions(-) diff --git a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackGenerator.java b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackGenerator.java index 19231e4f3..bc23e130c 100644 --- a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackGenerator.java +++ b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackGenerator.java @@ -18,7 +18,6 @@ import java.util.ArrayList; import java.util.LinkedList; import java.util.List; -import java.math.MathContext; public class MessagePackGenerator extends GeneratorBase { private static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8"); @@ -171,20 +170,7 @@ else if (v instanceof BigInteger) { messagePacker.packBigInteger((BigInteger) v); } else if (v instanceof BigDecimal) { - BigDecimal decimal = (BigDecimal) v; - try { - //Check to see if this BigDecimal can be converted to BigInteger - BigInteger integer = decimal.toBigIntegerExact(); - messagePacker.packBigInteger(integer); - } catch (ArithmeticException e){ - //If not an integer, then try converting to double - double doubleValue = decimal.doubleValue(); - //Check to make sure this BigDecimal can be represented as a double - if (!new BigDecimal(doubleValue, MathContext.DECIMAL128).equals(decimal)) { - throw new IllegalArgumentException("Messagepack cannot serialize a BigDecimal that can't be represented as double"); - } - messagePacker.packDouble(doubleValue); - } + packBigDecimal((BigDecimal) v); } else if (v instanceof Boolean) { messagePacker.packBoolean((Boolean) v); @@ -194,6 +180,29 @@ else if (v instanceof Boolean) { } } + private void packBigDecimal(BigDecimal decimal) throws IOException { + MessagePacker messagePacker = getMessagePacker(); + boolean failedToPackAsBI = false; + try { + //Check to see if this BigDecimal can be converted to BigInteger + BigInteger integer = decimal.toBigIntegerExact(); + messagePacker.packBigInteger(integer); + } catch (ArithmeticException e) { + failedToPackAsBI = true; + } catch (IllegalArgumentException e) { + failedToPackAsBI = true; + } + + if (failedToPackAsBI) { + double doubleValue = decimal.doubleValue(); + //Check to make sure this BigDecimal can be represented as a double + if (!decimal.toEngineeringString().equals(BigDecimal.valueOf(doubleValue).toEngineeringString())) { + throw new IllegalArgumentException("MessagePack cannot serialize a BigDecimal that can't be represented as double. " + decimal); + } + messagePacker.packDouble(doubleValue); + } +} + private void packObject(StackItemForObject stackItem) throws IOException { List keys = stackItem.getKeys(); List values = stackItem.getValues(); @@ -320,9 +329,6 @@ public void close() throws IOException { try { flush(); } - catch (Exception e) { - e.printStackTrace(); - } finally { MessagePacker messagePacker = getMessagePacker(); messagePacker.close(); diff --git a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java index a2b5a2593..14ae24af2 100644 --- a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java +++ b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java @@ -281,12 +281,12 @@ public BigDecimal getDecimalValue() throws IOException { return new BigDecimal(number.asBigInteger()); } } - - if (ref.isFloat()) { + else if (ref.isFloat()) { return BigDecimal.valueOf(ref.asFloat().toDouble()); } - - throw new UnsupportedOperationException("couldn't parse value as BigDecimal"); + else { + throw new UnsupportedOperationException("Couldn't parse value as BigDecimal. " + ref); + } } @Override diff --git a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackGeneratorTest.java b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackGeneratorTest.java index 8126fa64a..f1655f3d0 100644 --- a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackGeneratorTest.java +++ b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackGeneratorTest.java @@ -17,6 +17,7 @@ import com.fasterxml.jackson.core.JsonEncoding; import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.Test; import org.msgpack.core.MessagePack; import org.msgpack.core.MessageUnpacker; @@ -25,10 +26,8 @@ import java.io.File; import java.io.FileInputStream; import java.io.IOException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.math.BigDecimal; +import java.util.*; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -221,4 +220,47 @@ public void testMessagePackGeneratorDirectly() throws IOException { assertEquals(2.0f, unpacker.unpackFloat(), 0.001f); assertFalse(unpacker.hasNext()); } + + @Test + public void testBigDecimal() throws IOException { + ObjectMapper mapper = new ObjectMapper(new MessagePackFactory()); + + { + double d0 = 1.23456789; + double d1 = 1.23450000000000000000006789; + List bigDecimals = Arrays.asList( + BigDecimal.valueOf(d0), + BigDecimal.valueOf(d1), + BigDecimal.valueOf(Double.MIN_VALUE), + BigDecimal.valueOf(Double.MAX_VALUE), + BigDecimal.valueOf(Double.MIN_NORMAL) + ); + + byte[] bytes = mapper.writeValueAsBytes(bigDecimals); + MessageUnpacker unpacker = MessagePack.newDefaultUnpacker(bytes); + + assertEquals(5, unpacker.unpackArrayHeader()); + assertEquals(d0, unpacker.unpackDouble(), 0.000000000000001); + assertEquals(d1, unpacker.unpackDouble(), 0.000000000000001); + assertEquals(Double.MIN_VALUE, unpacker.unpackDouble(), 0.000000000000001); + assertEquals(Double.MAX_VALUE, unpacker.unpackDouble(), 0.000000000000001); + assertEquals(Double.MIN_NORMAL, unpacker.unpackDouble(), 0.000000000000001); + } + + { + + BigDecimal decimal = new BigDecimal("1234.567890123456789012345678901234567890"); + List bigDecimals = Arrays.asList( + decimal + ); + + try { + mapper.writeValueAsBytes(bigDecimals); + assertTrue(false); + } + catch (IllegalArgumentException e) { + assertTrue(true); + } + } + } } diff --git a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackParserTest.java b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackParserTest.java index 81268d24b..dc81fc248 100644 --- a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackParserTest.java +++ b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackParserTest.java @@ -3,13 +3,15 @@ import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.JsonToken; import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.Test; import org.msgpack.core.MessagePack; import org.msgpack.core.MessagePacker; import org.msgpack.core.buffer.OutputStreamBufferOutput; -import org.msgpack.value.ExtendedValue; import java.io.*; +import java.math.BigDecimal; import java.math.BigInteger; import java.nio.ByteBuffer; import java.util.Arrays; @@ -17,7 +19,6 @@ import java.util.Map; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertNull; @@ -315,4 +316,29 @@ public void testMessagePackParserDirectly() throws IOException { parser.close(); parser.close(); // Intentional } + + @Test + public void testBigDecimal() throws IOException { + double d0 = 1.23456789; + double d1 = 1.23450000000000000000006789; + MessagePacker packer = new MessagePacker(new OutputStreamBufferOutput(out)); + packer.packArrayHeader(5); + packer.packDouble(d0); + packer.packDouble(d1); + packer.packDouble(Double.MIN_VALUE); + packer.packDouble(Double.MAX_VALUE); + packer.packDouble(Double.MIN_NORMAL); + packer.flush(); + + ObjectMapper mapper = new ObjectMapper(new MessagePackFactory()); + mapper.configure(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS, true); + List objects = mapper.readValue(out.toByteArray(), new TypeReference>(){}); + assertEquals(5, objects.size()); + int idx = 0; + assertEquals(BigDecimal.valueOf(d0), objects.get(idx++)); + assertEquals(BigDecimal.valueOf(d1), objects.get(idx++)); + assertEquals(BigDecimal.valueOf(Double.MIN_VALUE), objects.get(idx++)); + assertEquals(BigDecimal.valueOf(Double.MAX_VALUE), objects.get(idx++)); + assertEquals(BigDecimal.valueOf(Double.MIN_NORMAL), objects.get(idx++)); + } } From 36f0b2f802773a0b66604ddb676b03bae3887867 Mon Sep 17 00:00:00 2001 From: Stephane Landelle Date: Tue, 17 Mar 2015 11:59:05 +0100 Subject: [PATCH 019/234] Make MessageBufferU constructor public, close #210 So it can be used to unpack read-only ByteBuffers --- .../msgpack/core/buffer/MessageBufferU.java | 2 +- .../org/msgpack/core/ByteStringTest.scala | 41 +++++++++++++++++++ project/Build.scala | 3 +- 3 files changed, 44 insertions(+), 2 deletions(-) create mode 100644 msgpack-core/src/test/scala/org/msgpack/core/ByteStringTest.scala diff --git a/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferU.java b/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferU.java index 8ce58aa03..adc72acd0 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferU.java +++ b/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferU.java @@ -12,7 +12,7 @@ */ public class MessageBufferU extends MessageBuffer { - MessageBufferU(ByteBuffer bb) { + public MessageBufferU(ByteBuffer bb) { super(null, 0L, bb.capacity(), bb.order(ByteOrder.BIG_ENDIAN)); checkNotNull(reference); } diff --git a/msgpack-core/src/test/scala/org/msgpack/core/ByteStringTest.scala b/msgpack-core/src/test/scala/org/msgpack/core/ByteStringTest.scala new file mode 100644 index 000000000..abec84001 --- /dev/null +++ b/msgpack-core/src/test/scala/org/msgpack/core/ByteStringTest.scala @@ -0,0 +1,41 @@ +package org.msgpack.core + +import akka.util.ByteString +import org.msgpack.core.buffer.{MessageBufferU, MessageBuffer, MessageBufferInput, ByteBufferInput} + +class ByteStringTest extends MessagePackSpec { + + val unpackedString = "foo" + val byteString = ByteString(createMessagePackData(_.packString(unpackedString))) + + "Regular ByteBufferInput" should { + "fail to read a ByteString's ByteBuffer" in { + + val input = new ByteBufferInput(byteString.asByteBuffer) + + a[RuntimeException] shouldBe thrownBy(new MessageUnpacker(input).unpackString()) + } + } + + "A MessageBufferU based ByteBufferInput" should { + "be able to read a ByteString's ByteBuffer" in { + + val input = new MessageBufferInput { + + private var isRead = false + + override def next(): MessageBuffer = + if (isRead) { + null + } else { + isRead = true + new MessageBufferU(byteString.asByteBuffer) + } + + override def close(): Unit = {} + } + + new MessageUnpacker(input).unpackString() shouldBe unpackedString + } + } +} diff --git a/project/Build.scala b/project/Build.scala index 6f2e36e85..78ef93f74 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -165,7 +165,8 @@ object Build extends Build { "org.xerial" % "xerial-core" % "3.3.5" % "test", "org.msgpack" % "msgpack" % "0.6.11" % "test", junitInterface, - "commons-codec" % "commons-codec" % "1.10" % "test" + "commons-codec" % "commons-codec" % "1.10" % "test", + "com.typesafe.akka" %% "akka-actor"% "2.3.9" ) val jacksonLib = Seq( From ff5111b0395fd34797dc56bdeab5456a28b9f530 Mon Sep 17 00:00:00 2001 From: Stephane Landelle Date: Wed, 18 Mar 2015 13:51:45 +0100 Subject: [PATCH 020/234] Fix test so it can run with JDK6 --- .../org/msgpack/core/ByteStringTest.scala | 41 ------------------ .../msgpack/core/buffer/ByteStringTest.scala | 42 +++++++++++++++++++ 2 files changed, 42 insertions(+), 41 deletions(-) delete mode 100644 msgpack-core/src/test/scala/org/msgpack/core/ByteStringTest.scala create mode 100644 msgpack-core/src/test/scala/org/msgpack/core/buffer/ByteStringTest.scala diff --git a/msgpack-core/src/test/scala/org/msgpack/core/ByteStringTest.scala b/msgpack-core/src/test/scala/org/msgpack/core/ByteStringTest.scala deleted file mode 100644 index abec84001..000000000 --- a/msgpack-core/src/test/scala/org/msgpack/core/ByteStringTest.scala +++ /dev/null @@ -1,41 +0,0 @@ -package org.msgpack.core - -import akka.util.ByteString -import org.msgpack.core.buffer.{MessageBufferU, MessageBuffer, MessageBufferInput, ByteBufferInput} - -class ByteStringTest extends MessagePackSpec { - - val unpackedString = "foo" - val byteString = ByteString(createMessagePackData(_.packString(unpackedString))) - - "Regular ByteBufferInput" should { - "fail to read a ByteString's ByteBuffer" in { - - val input = new ByteBufferInput(byteString.asByteBuffer) - - a[RuntimeException] shouldBe thrownBy(new MessageUnpacker(input).unpackString()) - } - } - - "A MessageBufferU based ByteBufferInput" should { - "be able to read a ByteString's ByteBuffer" in { - - val input = new MessageBufferInput { - - private var isRead = false - - override def next(): MessageBuffer = - if (isRead) { - null - } else { - isRead = true - new MessageBufferU(byteString.asByteBuffer) - } - - override def close(): Unit = {} - } - - new MessageUnpacker(input).unpackString() shouldBe unpackedString - } - } -} diff --git a/msgpack-core/src/test/scala/org/msgpack/core/buffer/ByteStringTest.scala b/msgpack-core/src/test/scala/org/msgpack/core/buffer/ByteStringTest.scala new file mode 100644 index 000000000..60bc9f3e6 --- /dev/null +++ b/msgpack-core/src/test/scala/org/msgpack/core/buffer/ByteStringTest.scala @@ -0,0 +1,42 @@ +package org.msgpack.core.buffer + +import akka.util.ByteString +import org.msgpack.core.{MessagePackSpec, MessageUnpacker} + +class ByteStringTest extends MessagePackSpec { + + val unpackedString = "foo" + val byteString = ByteString(createMessagePackData(_.packString(unpackedString))) + + def unpackString(messageBuffer: MessageBuffer) = { + val input = new MessageBufferInput { + + private var isRead = false + + override def next(): MessageBuffer = + if (isRead) { + null + } else { + isRead = true + messageBuffer + } + + override def close(): Unit = {} + } + + new MessageUnpacker(input).unpackString() + } + + "Unpacking a ByteString's ByteBuffer" should { + "fail with a regular MessageBuffer" in { + + // can't demonstrate with new ByteBufferInput(byteString.asByteBuffer) + // as Travis tests run with JDK6 that picks up MessageBufferU + a[RuntimeException] shouldBe thrownBy(unpackString(new MessageBuffer(byteString.asByteBuffer))) + } + + "succeed with a MessageBufferU" in { + unpackString(new MessageBufferU(byteString.asByteBuffer)) shouldBe unpackedString + } + } +} From 4850ef7e30004f01b2b200d0662b2a920a88cd83 Mon Sep 17 00:00:00 2001 From: Stephane Landelle Date: Wed, 18 Mar 2015 15:02:05 +0100 Subject: [PATCH 021/234] scope test for Akka --- project/Build.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/Build.scala b/project/Build.scala index 78ef93f74..d51f7a09a 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -166,7 +166,7 @@ object Build extends Build { "org.msgpack" % "msgpack" % "0.6.11" % "test", junitInterface, "commons-codec" % "commons-codec" % "1.10" % "test", - "com.typesafe.akka" %% "akka-actor"% "2.3.9" + "com.typesafe.akka" %% "akka-actor"% "2.3.9" % "test" ) val jacksonLib = Seq( From 25fc565ba1c20ad8e1a27b36abb2849a87c9d8a6 Mon Sep 17 00:00:00 2001 From: Mitsunori Komatsu Date: Sat, 4 Apr 2015 21:31:32 +0900 Subject: [PATCH 022/234] Fix MessageUnpacker#unpackString in case that string length is more than 8192 --- .../org/msgpack/core/MessageUnpacker.java | 6 ++-- .../msgpack/core/MessageUnpackerTest.scala | 28 +++++++++++++++++++ 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java b/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java index 8f246830e..8ebd07de2 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java +++ b/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java @@ -980,7 +980,6 @@ public String unpackString() throws IOException { if(cr.isOverflow()) { // The output CharBuffer has insufficient space - readLen = bb.limit() - bb.remaining(); decoder.reset(); } @@ -1005,9 +1004,10 @@ public String unpackString() throws IOException { sb.append(decodeBuffer); decodeBuffer.clear(); - cursor += readLen; - consume(readLen); } + + cursor += readLen; + consume(readLen); } return sb.toString(); diff --git a/msgpack-core/src/test/scala/org/msgpack/core/MessageUnpackerTest.scala b/msgpack-core/src/test/scala/org/msgpack/core/MessageUnpackerTest.scala index 1428c68a9..dd0ba984b 100644 --- a/msgpack-core/src/test/scala/org/msgpack/core/MessageUnpackerTest.scala +++ b/msgpack-core/src/test/scala/org/msgpack/core/MessageUnpackerTest.scala @@ -618,5 +618,33 @@ class MessageUnpackerTest extends MessagePackSpec { checkFile(u) u.close } + + "parse message large packed data" taggedAs("unpack") in { + def createLargeData(stringLength: Int): Array[Byte] = { + val out = new ByteArrayOutputStream() + val packer = msgpack.newPacker(out) + + packer + .packArrayHeader(2) + .packString("l" * stringLength) + .packInt(1) + + packer.close() + + out.toByteArray + } + + Seq(8191, 8192, 8193, 16383, 16384, 16385).foreach { n => + val arr = createLargeData(n) + + val unpacker = msgpack.newUnpacker(arr) + + unpacker.unpackArrayHeader shouldBe 2 + unpacker.unpackString.length shouldBe n + unpacker.unpackInt shouldBe 1 + + unpacker.getTotalReadBytes shouldBe arr.length + } + } } } From b15e18fd761869227926031d46de15f2ecf2a1d2 Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Wed, 8 Apr 2015 10:58:10 +0900 Subject: [PATCH 023/234] Fix buffer size to ensure --- .../src/main/java/org/msgpack/core/MessageUnpacker.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java b/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java index 8ebd07de2..eb4943d0c 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java +++ b/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java @@ -965,7 +965,7 @@ public String unpackString() throws IOException { decodeBuffer.clear(); StringBuilder sb = new StringBuilder(); while(cursor < strLen) { - if (!ensure(strLen)) + if (!ensure(strLen-cursor)) throw new EOFException(); int readLen = Math.min(buffer.size() - position, strLen-cursor); From a4c95930be45742d0c34f0f9a40f48efca9a01e0 Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Thu, 9 Apr 2015 18:58:11 +0900 Subject: [PATCH 024/234] Avoid allocating too large bufffer when unpacking string --- .../src/main/java/org/msgpack/core/MessageUnpacker.java | 5 +++-- .../test/scala/org/msgpack/core/MessageUnpackerTest.scala | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java b/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java index eb4943d0c..628525990 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java +++ b/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java @@ -964,11 +964,12 @@ public String unpackString() throws IOException { int cursor = 0; decodeBuffer.clear(); StringBuilder sb = new StringBuilder(); + while(cursor < strLen) { - if (!ensure(strLen-cursor)) + int readLen = Math.min(position < buffer.size() ? buffer.size() - position : buffer.size(), strLen-cursor); + if (!ensure(readLen)) throw new EOFException(); - int readLen = Math.min(buffer.size() - position, strLen-cursor); ByteBuffer bb = buffer.toByteBuffer(position, readLen); while(bb.hasRemaining()) { diff --git a/msgpack-core/src/test/scala/org/msgpack/core/MessageUnpackerTest.scala b/msgpack-core/src/test/scala/org/msgpack/core/MessageUnpackerTest.scala index dd0ba984b..99115abc9 100644 --- a/msgpack-core/src/test/scala/org/msgpack/core/MessageUnpackerTest.scala +++ b/msgpack-core/src/test/scala/org/msgpack/core/MessageUnpackerTest.scala @@ -619,7 +619,7 @@ class MessageUnpackerTest extends MessagePackSpec { u.close } - "parse message large packed data" taggedAs("unpack") in { + "unpack large string data" taggedAs("large-string") in { def createLargeData(stringLength: Int): Array[Byte] = { val out = new ByteArrayOutputStream() val packer = msgpack.newPacker(out) From 6790c888aa49201fdc72c36ec35309733d7c55c0 Mon Sep 17 00:00:00 2001 From: Mitsunori Komatsu Date: Thu, 9 Apr 2015 22:39:12 +0900 Subject: [PATCH 025/234] Set version to 0.7.0-p8 --- version.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.sbt b/version.sbt index 3bc36f7f8..6a40a65dc 100644 --- a/version.sbt +++ b/version.sbt @@ -1 +1 @@ -version in ThisBuild := "0.7.0-p8-SNAPSHOT" \ No newline at end of file +version in ThisBuild := "0.7.0-p8" \ No newline at end of file From e9fdc9f90c0c9c5fa737501d145884b43aacb8d0 Mon Sep 17 00:00:00 2001 From: Mitsunori Komatsu Date: Thu, 9 Apr 2015 22:50:30 +0900 Subject: [PATCH 026/234] Set version to 0.7.0-p9-SNAPSHOT --- version.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.sbt b/version.sbt index 6a40a65dc..c305b0f8d 100644 --- a/version.sbt +++ b/version.sbt @@ -1 +1 @@ -version in ThisBuild := "0.7.0-p8" \ No newline at end of file +version in ThisBuild := "0.7.0-p9-SNAPSHOT" \ No newline at end of file From 17ec7ef5e136940358054ab986adc095a2184e90 Mon Sep 17 00:00:00 2001 From: Mitsunori Komatsu Date: Sat, 11 Apr 2015 14:30:40 +0900 Subject: [PATCH 027/234] Update RELEASE_NOTES.md --- RELEASE_NOTES.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index f885d433a..bbde5757c 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -1,5 +1,10 @@ # Release Notes +* 2015-04-09 0.7.0-p8 + * Support Extended type (defined in MessagePack) in msgpack-jackson + * Support BigDecimal type (defined in Jackson) in msgpack-jackson + * Fix MessageUnpacker#unpackString [#215](https://github.com/msgpack/msgpack-java/pull/215), [#216](https://github.com/msgpack/msgpack-java/pull/216) + * 2015-02-16 0.7.0-p7 * Google App Engine (GAE) support From 3dbe1784bea73d99ab75010d0a8e6bdbde1011b3 Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Mon, 27 Apr 2015 10:37:42 +0900 Subject: [PATCH 028/234] Fixes #217: Handle when FileInputStream.getChannel() returns null --- .../org/msgpack/core/buffer/InputStreamBufferInput.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/msgpack-core/src/main/java/org/msgpack/core/buffer/InputStreamBufferInput.java b/msgpack-core/src/main/java/org/msgpack/core/buffer/InputStreamBufferInput.java index 0e7e4626d..d9a7c3466 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/buffer/InputStreamBufferInput.java +++ b/msgpack-core/src/main/java/org/msgpack/core/buffer/InputStreamBufferInput.java @@ -3,6 +3,7 @@ import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; +import java.nio.channels.FileChannel; import static org.msgpack.core.Preconditions.checkNotNull; @@ -18,7 +19,10 @@ public class InputStreamBufferInput implements MessageBufferInput { public static MessageBufferInput newBufferInput(InputStream in) { checkNotNull(in, "InputStream is null"); if (in instanceof FileInputStream) { - return new ChannelBufferInput(((FileInputStream) in).getChannel()); + FileChannel channel = ((FileInputStream) in).getChannel(); + if(channel != null) { + return new ChannelBufferInput(channel); + } } return new InputStreamBufferInput(in); } From 19a9fc2e645b546d5b4f3ce42173ad63e0c04163 Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Mon, 27 Apr 2015 12:04:09 +0900 Subject: [PATCH 029/234] Add release notes --- RELEASE_NOTES.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index bbde5757c..b0f19d52a 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -1,5 +1,8 @@ # Release Notes +* 2015-04-27 0.7.0-p9 + * Fix [#217] when reading from SockectInputStream + * 2015-04-09 0.7.0-p8 * Support Extended type (defined in MessagePack) in msgpack-jackson * Support BigDecimal type (defined in Jackson) in msgpack-jackson From c0cb7760f0bcc611224847b78bc031ae7ea2c1d3 Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Mon, 27 Apr 2015 12:25:56 +0900 Subject: [PATCH 030/234] Setting version to 0.7.0-p9 --- version.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.sbt b/version.sbt index c305b0f8d..6f2a2ba1f 100644 --- a/version.sbt +++ b/version.sbt @@ -1 +1 @@ -version in ThisBuild := "0.7.0-p9-SNAPSHOT" \ No newline at end of file +version in ThisBuild := "0.7.0-p9" \ No newline at end of file From 251d92fe2f9e83d8e03d23f48453bb4bfe726669 Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Mon, 27 Apr 2015 12:26:24 +0900 Subject: [PATCH 031/234] Setting version to 0.7.0-p10-SNAPSHOT --- version.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.sbt b/version.sbt index 6f2a2ba1f..144b223b4 100644 --- a/version.sbt +++ b/version.sbt @@ -1 +1 @@ -version in ThisBuild := "0.7.0-p9" \ No newline at end of file +version in ThisBuild := "0.7.0-p10-SNAPSHOT" \ No newline at end of file From 8c42beb3557c8942b2bf00f40b88162fcf9e2115 Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Mon, 27 Apr 2015 12:39:41 +0900 Subject: [PATCH 032/234] Automate sbt release steps --- project/Build.scala | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/project/Build.scala b/project/Build.scala index d51f7a09a..d2a1ce7ac 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -22,8 +22,11 @@ import de.johoop.findbugs4sbt.FindBugs._ import de.johoop.jacoco4sbt._ import JacocoPlugin._ import sbtrelease.ReleasePlugin._ +import sbtrelease.ReleaseStateTransformations._ +import sbtrelease.ReleaseStep import scala.util.Properties import com.typesafe.sbt.pgp.PgpKeys +import xerial.sbt.Sonatype.SonatypeKeys._ object Build extends Build { @@ -47,7 +50,6 @@ object Build extends Build { concurrentRestrictions in Global := Seq( Tags.limit(Tags.Test, 1) ), - ReleaseKeys.tagName <<= (version in ThisBuild) map (v => v), publishTo := { val nexus = "https://oss.sonatype.org/" if (isSnapshot.value) @@ -55,6 +57,29 @@ object Build extends Build { else Some("releases" at nexus + "service/local/staging/deploy/maven2") }, + ReleaseKeys.tagName <<= (version in ThisBuild) map (v => v), + ReleaseKeys.releaseProcess := Seq[ReleaseStep]( + checkSnapshotDependencies, + inquireVersions, + runClean, + runTest, + setReleaseVersion, + commitReleaseVersion, + tagRelease, + ReleaseStep( + action = { state => + val extracted = Project extract state + extracted.runAggregated(PgpKeys.publishSigned in Global in extracted.get(thisProjectRef), state) + } + ), + setNextVersion, + commitNextVersion, + ReleaseStep{ state => + val extracted = Project extract state + extracted.runAggregated(sonatypeReleaseAll in Global in extracted.get(thisProjectRef), state) + }, + pushChanges + ), parallelExecution in jacoco.Config := false, // Since sbt-0.13.2 incOptions := incOptions.value.withNameHashing(true), From 27c4d1b5a0fea69be39fd253879363704ffc65d0 Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Mon, 27 Apr 2015 12:45:17 +0900 Subject: [PATCH 033/234] Fix version in README --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index f8f0a164c..4cc7ee4f6 100644 --- a/README.md +++ b/README.md @@ -17,13 +17,13 @@ For Maven users: org.msgpack msgpack-core - 0.7.0-p7 + 0.7.0-p9 ``` For sbt users: ``` -libraryDependencies += "org.msgpack" % "msgpack-core" % "0.7.0-p7" +libraryDependencies += "org.msgpack" % "msgpack-core" % "0.7.0-p9" ``` - [Usage examples](msgpack-core/src/main/java/org/msgpack/core/example/MessagePackExample.java) From a6b3bec6f38c0660078c51fd72888333e9126c5a Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Mon, 27 Apr 2015 12:46:37 +0900 Subject: [PATCH 034/234] Upgrade scala and sbt versions --- project/Build.scala | 4 ++-- project/build.properties | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/project/Build.scala b/project/Build.scala index d51f7a09a..503df5c43 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -27,7 +27,7 @@ import com.typesafe.sbt.pgp.PgpKeys object Build extends Build { - val SCALA_VERSION = "2.11.1" + val SCALA_VERSION = "2.11.6" lazy val buildSettings = Defaults.coreDefaultSettings ++ releaseSettings ++ @@ -162,7 +162,7 @@ object Build extends Build { val testLib = Seq( "org.scalatest" %% "scalatest" % "2.2.4" % "test", "org.scalacheck" %% "scalacheck" % "1.12.2" % "test", - "org.xerial" % "xerial-core" % "3.3.5" % "test", + "org.xerial" % "xerial-core" % "3.3.6" % "test", "org.msgpack" % "msgpack" % "0.6.11" % "test", junitInterface, "commons-codec" % "commons-codec" % "1.10" % "test", diff --git a/project/build.properties b/project/build.properties index 005786e4d..07b0ebbcd 100755 --- a/project/build.properties +++ b/project/build.properties @@ -1,2 +1,2 @@ -sbt.version=0.13.6 +sbt.version=0.13.8 From 2d70492c5b711f65bc646a274d9b6f4454eb2cf6 Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Mon, 27 Apr 2015 12:47:04 +0900 Subject: [PATCH 035/234] Removed sbt-idea plugin, which is no longer necessary --- project/plugins.sbt | 2 -- 1 file changed, 2 deletions(-) diff --git a/project/plugins.sbt b/project/plugins.sbt index eb6a52a1b..c3e154da5 100755 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -5,8 +5,6 @@ addSbtPlugin("org.xerial.sbt" % "sbt-sonatype" % "0.2.1") addSbtPlugin("com.typesafe.sbt" % "sbt-pgp" % "0.8.3") -addSbtPlugin("com.github.mpeltonen" % "sbt-idea" % "1.6.0") - addSbtPlugin("de.johoop" % "findbugs4sbt" % "1.3.0") addSbtPlugin("de.johoop" % "jacoco4sbt" % "2.1.6") From 8c2bae42bfa0efc4f93a1c176b2df3321bdfeb68 Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Mon, 27 Apr 2015 12:47:18 +0900 Subject: [PATCH 036/234] Upgrade sbt script --- sbt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sbt b/sbt index 3721584c9..19c39b6b8 100755 --- a/sbt +++ b/sbt @@ -4,8 +4,8 @@ # Author: Paul Phillips # todo - make this dynamic -declare -r sbt_release_version="0.13.1" -declare -r sbt_unreleased_version="0.13.2-SNAPSHOT" # -sbt-dev doesn't work at present +declare -r sbt_release_version="0.13.8" +declare -r sbt_unreleased_version="0.13.8-SNAPSHOT" # -sbt-dev doesn't work at present declare -r buildProps="project/build.properties" declare sbt_jar sbt_dir sbt_create sbt_launch_dir @@ -124,7 +124,7 @@ declare -r noshare_opts="-Dsbt.global.base=project/.sbtboot -Dsbt.boot.directory declare -r latest_28="2.8.2" declare -r latest_29="2.9.3" declare -r latest_210="2.10.3" -declare -r latest_211="2.11.0-M5" +declare -r latest_211="2.11.6" declare -r script_path="$(get_script_path "$BASH_SOURCE")" declare -r script_name="${script_path##*/}" From 18a46dcb32ba5ba251b7b9919c7ad9fa289a68b2 Mon Sep 17 00:00:00 2001 From: Frank Dinoff Date: Fri, 1 May 2015 17:25:16 -0400 Subject: [PATCH 037/234] Fixes #223: MapValueImpl does not implement getMapCursor --- .../src/main/java/org/msgpack/value/impl/MapValueImpl.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/MapValueImpl.java b/msgpack-core/src/main/java/org/msgpack/value/impl/MapValueImpl.java index adc0c00a1..3f010a7e2 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/impl/MapValueImpl.java +++ b/msgpack-core/src/main/java/org/msgpack/value/impl/MapValueImpl.java @@ -57,6 +57,10 @@ public void skipAll() { } } + @Override + public MapCursor getMapCursor() { + return this; + } private class MapImpl extends AbstractMap { From 63096e97f811206257f963a4141c0a9a10cb0685 Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Sun, 3 May 2015 23:36:15 +0900 Subject: [PATCH 038/234] Upgrade to sbt-sonatype-0.3.3 --- project/Build.scala | 60 ++++----------------------------------------- project/plugins.sbt | 2 +- sbt | 2 +- sonatype.sbt | 49 +++++++++++++++++++++++++++++++++++- 4 files changed, 55 insertions(+), 58 deletions(-) diff --git a/project/Build.scala b/project/Build.scala index ec5840c2a..534cd8c40 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -26,7 +26,8 @@ import sbtrelease.ReleaseStateTransformations._ import sbtrelease.ReleaseStep import scala.util.Properties import com.typesafe.sbt.pgp.PgpKeys -import xerial.sbt.Sonatype.SonatypeKeys._ +import xerial.sbt.Sonatype +import Sonatype.SonatypeKeys._ object Build extends Build { @@ -50,13 +51,6 @@ object Build extends Build { concurrentRestrictions in Global := Seq( Tags.limit(Tags.Test, 1) ), - publishTo := { - val nexus = "https://oss.sonatype.org/" - if (isSnapshot.value) - Some("snapshots" at nexus + "content/repositories/snapshots") - else - Some("releases" at nexus + "service/local/staging/deploy/maven2") - }, ReleaseKeys.tagName <<= (version in ThisBuild) map (v => v), ReleaseKeys.releaseProcess := Seq[ReleaseStep]( checkSnapshotDependencies, @@ -95,51 +89,7 @@ object Build extends Build { opts }, findbugsReportType := Some(ReportType.FancyHtml), - findbugsReportPath := Some(crossTarget.value / "findbugs" / "report.html"), - pomExtra := { - http://msgpack.org/ - - - Apache 2 - http://www.apache.org/licenses/LICENSE-2.0.txt - - - - scm:git:github.com/msgpack/msgpack-java.git - scm:git:git@github.com:msgpack/msgpack-java.git - github.com/msgpack/msgpack-java.git - - - UTF-8 - - - - frsyuki - Sadayuki Furuhashi - frsyuki@users.sourceforge.jp - - - muga - Muga Nishizawa - muga.nishizawa@gmail.com - - - oza - Tsuyoshi Ozawa - https://github.com/oza - - - komamitsu - Mitsunori Komatsu - komamitsu@gmail.com - - - xerial - Taro L. Saito - leo@xerial.org - - - } + findbugsReportPath := Some(crossTarget.value / "findbugs" / "report.html") ) import Dependencies._ @@ -167,7 +117,7 @@ object Build extends Build { description := "Core library of the MessagePack for Java", libraryDependencies ++= testLib ) - ) + ).disablePlugins(Sonatype) lazy val msgpackJackson = Project( id = "msgpack-jackson", @@ -178,7 +128,7 @@ object Build extends Build { libraryDependencies ++= jacksonLib, testOptions += Tests.Argument(TestFrameworks.JUnit, "-v") ) - ).dependsOn(msgpackCore) + ).disablePlugins(Sonatype).dependsOn(msgpackCore) object Dependencies { diff --git a/project/plugins.sbt b/project/plugins.sbt index c3e154da5..1b5cc6106 100755 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,7 +1,7 @@ addSbtPlugin("com.github.gseitz" % "sbt-release" % "0.8.5") -addSbtPlugin("org.xerial.sbt" % "sbt-sonatype" % "0.2.1") +addSbtPlugin("org.xerial.sbt" % "sbt-sonatype" % "0.3.3") addSbtPlugin("com.typesafe.sbt" % "sbt-pgp" % "0.8.3") diff --git a/sbt b/sbt index 19c39b6b8..7c9358235 100755 --- a/sbt +++ b/sbt @@ -119,7 +119,7 @@ init_default_option_file () { declare -r cms_opts="-XX:+CMSClassUnloadingEnabled -XX:+UseConcMarkSweepGC" declare -r jit_opts="-XX:ReservedCodeCacheSize=256m -XX:+TieredCompilation" -declare -r default_jvm_opts="-ea -Dfile.encoding=UTF8 -XX:MaxPermSize=384m -Xms512m -Xmx1536m -Xss2m $jit_opts $cms_opts" +declare -r default_jvm_opts="-ea -Dfile.encoding=UTF8 -Xms512m -Xmx1536m -Xss2m $jit_opts $cms_opts" declare -r noshare_opts="-Dsbt.global.base=project/.sbtboot -Dsbt.boot.directory=project/.boot -Dsbt.ivy.home=project/.ivy" declare -r latest_28="2.8.2" declare -r latest_29="2.9.3" diff --git a/sonatype.sbt b/sonatype.sbt index 1220a4a51..628e6c8b8 100644 --- a/sonatype.sbt +++ b/sonatype.sbt @@ -1 +1,48 @@ -sonatypeSettings +import SonatypeKeys._ + +sonatypeProfileName := "org.msgpack" + +pomExtra := { + http://msgpack.org/ + + + Apache 2 + http://www.apache.org/licenses/LICENSE-2.0.txt + + + + scm:git:github.com/msgpack/msgpack-java.git + scm:git:git@github.com:msgpack/msgpack-java.git + github.com/msgpack/msgpack-java.git + + + UTF-8 + + + + frsyuki + Sadayuki Furuhashi + frsyuki@users.sourceforge.jp + + + muga + Muga Nishizawa + muga.nishizawa@gmail.com + + + oza + Tsuyoshi Ozawa + https://github.com/oza + + + komamitsu + Mitsunori Komatsu + komamitsu@gmail.com + + + xerial + Taro L. Saito + leo@xerial.org + + +} From 0ad5b4d84d52c7cdd4a241f0711332815e7ff6aa Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Mon, 4 May 2015 02:14:35 +0900 Subject: [PATCH 039/234] Using sbt-sonatype-0.4.0, which simplifies settings --- project/Build.scala | 19 ++++++++----------- project/plugins.sbt | 2 +- sonatype.sbt | 2 +- 3 files changed, 10 insertions(+), 13 deletions(-) diff --git a/project/Build.scala b/project/Build.scala index 534cd8c40..e3bd1aa37 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -26,8 +26,7 @@ import sbtrelease.ReleaseStateTransformations._ import sbtrelease.ReleaseStep import scala.util.Properties import com.typesafe.sbt.pgp.PgpKeys -import xerial.sbt.Sonatype -import Sonatype.SonatypeKeys._ +import xerial.sbt.Sonatype.SonatypeKeys._ object Build extends Build { @@ -94,21 +93,19 @@ object Build extends Build { import Dependencies._ - lazy val root = Project( id = "msgpack-java", base = file("."), settings = buildSettings ++ Seq( - findbugs := { - // do not run findbugs for the root project - }, // Do not publish the root project publishArtifact := false, publish := {}, - publishLocal := {} + publishLocal := {}, + findbugs := { + // do not run findbugs for the root project + } ) - ) aggregate(msgpackCore, msgpackJackson) - + ).aggregate(msgpackCore, msgpackJackson) lazy val msgpackCore = Project( id = "msgpack-core", @@ -117,7 +114,7 @@ object Build extends Build { description := "Core library of the MessagePack for Java", libraryDependencies ++= testLib ) - ).disablePlugins(Sonatype) + ) lazy val msgpackJackson = Project( id = "msgpack-jackson", @@ -128,7 +125,7 @@ object Build extends Build { libraryDependencies ++= jacksonLib, testOptions += Tests.Argument(TestFrameworks.JUnit, "-v") ) - ).disablePlugins(Sonatype).dependsOn(msgpackCore) + ).dependsOn(msgpackCore) object Dependencies { diff --git a/project/plugins.sbt b/project/plugins.sbt index 1b5cc6106..aed9d8771 100755 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,7 +1,7 @@ addSbtPlugin("com.github.gseitz" % "sbt-release" % "0.8.5") -addSbtPlugin("org.xerial.sbt" % "sbt-sonatype" % "0.3.3") +addSbtPlugin("org.xerial.sbt" % "sbt-sonatype" % "0.4.0") addSbtPlugin("com.typesafe.sbt" % "sbt-pgp" % "0.8.3") diff --git a/sonatype.sbt b/sonatype.sbt index 628e6c8b8..0366b64f3 100644 --- a/sonatype.sbt +++ b/sonatype.sbt @@ -1,4 +1,4 @@ -import SonatypeKeys._ +Sonatype.sonatypeSettings sonatypeProfileName := "org.msgpack" From 9576984bf2cd14040241f6d0dbabd639362d631b Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Tue, 5 May 2015 00:36:47 +0900 Subject: [PATCH 040/234] Usign sbt-sonatype-0.5.0, which simplifies project settings --- project/Build.scala | 15 ++------------- project/plugins.sbt | 2 +- sonatype.sbt | 2 -- 3 files changed, 3 insertions(+), 16 deletions(-) diff --git a/project/Build.scala b/project/Build.scala index e3bd1aa37..39a2747ce 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -25,8 +25,6 @@ import sbtrelease.ReleasePlugin._ import sbtrelease.ReleaseStateTransformations._ import sbtrelease.ReleaseStep import scala.util.Properties -import com.typesafe.sbt.pgp.PgpKeys -import xerial.sbt.Sonatype.SonatypeKeys._ object Build extends Build { @@ -42,7 +40,6 @@ object Build extends Build { organizationHomepage := Some(new URL("http://msgpack.org/")), description := "MessagePack for Java", scalaVersion in Global := SCALA_VERSION, - ReleaseKeys.publishArtifactsAction := PgpKeys.publishSigned.value, logBuffered in Test := false, //parallelExecution in Test := false, autoScalaLibrary := false, @@ -59,18 +56,10 @@ object Build extends Build { setReleaseVersion, commitReleaseVersion, tagRelease, - ReleaseStep( - action = { state => - val extracted = Project extract state - extracted.runAggregated(PgpKeys.publishSigned in Global in extracted.get(thisProjectRef), state) - } - ), + ReleaseStep(action = Command.process("publishSigned", _)), setNextVersion, commitNextVersion, - ReleaseStep{ state => - val extracted = Project extract state - extracted.runAggregated(sonatypeReleaseAll in Global in extracted.get(thisProjectRef), state) - }, + ReleaseStep(action = Command.process("sonatypeReleaseAll", _)), pushChanges ), parallelExecution in jacoco.Config := false, diff --git a/project/plugins.sbt b/project/plugins.sbt index aed9d8771..8761d789c 100755 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,7 +1,7 @@ addSbtPlugin("com.github.gseitz" % "sbt-release" % "0.8.5") -addSbtPlugin("org.xerial.sbt" % "sbt-sonatype" % "0.4.0") +addSbtPlugin("org.xerial.sbt" % "sbt-sonatype" % "0.5.0") addSbtPlugin("com.typesafe.sbt" % "sbt-pgp" % "0.8.3") diff --git a/sonatype.sbt b/sonatype.sbt index 0366b64f3..11ac985c2 100644 --- a/sonatype.sbt +++ b/sonatype.sbt @@ -1,5 +1,3 @@ -Sonatype.sonatypeSettings - sonatypeProfileName := "org.msgpack" pomExtra := { From 00541cb8cabff8df5df6083466ce87a507a606c6 Mon Sep 17 00:00:00 2001 From: Mitsunori Komatsu Date: Sat, 9 May 2015 20:29:04 +0900 Subject: [PATCH 041/234] Update the version of `jackson-databind` --- project/Build.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/Build.scala b/project/Build.scala index 39a2747ce..6f19d1995 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -131,7 +131,7 @@ object Build extends Build { ) val jacksonLib = Seq( - "com.fasterxml.jackson.core" % "jackson-databind" % "2.4.4", + "com.fasterxml.jackson.core" % "jackson-databind" % "2.5.3", junitInterface, "org.apache.commons" % "commons-math3" % "3.4.1" % "test" ) From 5238391b1943be4e774340c52ad13e3e596c9925 Mon Sep 17 00:00:00 2001 From: Mitsunori Komatsu Date: Sun, 17 May 2015 15:37:39 +0900 Subject: [PATCH 042/234] Update README.md --- msgpack-jackson/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/msgpack-jackson/README.md b/msgpack-jackson/README.md index a10b2c6aa..255162b08 100644 --- a/msgpack-jackson/README.md +++ b/msgpack-jackson/README.md @@ -1,7 +1,7 @@ # jackson-dataformat-msgpack This Jackson extension library handles reading and writing of data encoded in [MessagePack](http://msgpack.org/) data format. -It extends standard Jackson streaming API (`JsonFactory`, `JsonParser`, `JsonGenerator`), and as such works seamlessly with all the higher level data abstractions (data binding, tree model, and pluggable extensions). +It extends standard Jackson streaming API (`JsonFactory`, `JsonParser`, `JsonGenerator`), and as such works seamlessly with all the higher level data abstractions (data binding, tree model, and pluggable extensions). For the details of Jackson-annotations, please see https://github.com/FasterXML/jackson-annotations. ## Maven dependency From 545d0de442913d488043fba4912cd74c55d92be4 Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Mon, 25 May 2015 15:32:38 +0900 Subject: [PATCH 043/234] Fixes #232 --- .../java/org/msgpack/core/buffer/MessageBuffer.java | 3 ++- .../scala/org/msgpack/core/MessagePackerTest.scala | 11 +++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBuffer.java b/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBuffer.java index 50a84ac3c..85775048c 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBuffer.java +++ b/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBuffer.java @@ -419,10 +419,12 @@ public void putByteBuffer(int index, ByteBuffer src, int len) { if(src.isDirect()) { unsafe.copyMemory(null, DirectBufferAccess.getAddress(src) + src.position(), base, address + index, len); + src.position(src.position() + len); } else if(src.hasArray()) { byte[] srcArray = src.array(); unsafe.copyMemory(srcArray, ARRAY_BYTE_BASE_OFFSET + src.position(), base, address + index, len); + src.position(src.position() + len); } else { if(base != null) { @@ -434,7 +436,6 @@ else if(src.hasArray()) { } } } - src.position(src.position() + len); } /** diff --git a/msgpack-core/src/test/scala/org/msgpack/core/MessagePackerTest.scala b/msgpack-core/src/test/scala/org/msgpack/core/MessagePackerTest.scala index 4fb621e46..4c2dc46e9 100644 --- a/msgpack-core/src/test/scala/org/msgpack/core/MessagePackerTest.scala +++ b/msgpack-core/src/test/scala/org/msgpack/core/MessagePackerTest.scala @@ -16,6 +16,7 @@ package org.msgpack.core import java.io.{FileInputStream, FileOutputStream, File, ByteArrayOutputStream} +import java.nio.ByteBuffer import org.msgpack.core.buffer.{ChannelBufferOutput, MessageBufferOutput, OutputStreamBufferOutput} import xerial.core.io.IOUtil @@ -217,4 +218,14 @@ class MessagePackerTest extends MessagePackSpec { out.toByteArray.length shouldBe packerTotalWrittenBytes } + + "support read-only buffer" taggedAs("read-only") in { + val payload = Array[Byte](1) + val buffer = ByteBuffer.wrap(payload).asReadOnlyBuffer() + val out = new ByteArrayOutputStream() + val packer = MessagePack.newDefaultPacker(out) + .packBinaryHeader(1) + .writePayload(buffer) + .close() + } } From edc9e33fbea8648ab906886d73243a5b4d3be0bf Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Mon, 25 May 2015 15:34:48 +0900 Subject: [PATCH 044/234] Upgrade sbt-pgp plugin version --- project/plugins.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/plugins.sbt b/project/plugins.sbt index 8761d789c..3c5b99d03 100755 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -3,7 +3,7 @@ addSbtPlugin("com.github.gseitz" % "sbt-release" % "0.8.5") addSbtPlugin("org.xerial.sbt" % "sbt-sonatype" % "0.5.0") -addSbtPlugin("com.typesafe.sbt" % "sbt-pgp" % "0.8.3") +addSbtPlugin("com.jsuereth" % "sbt-pgp" % "1.0.0") addSbtPlugin("de.johoop" % "findbugs4sbt" % "1.3.0") From 16a38b0a30d6a7129fdc23e3f5878b8a6eac1235 Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Mon, 25 May 2015 16:04:26 +0900 Subject: [PATCH 045/234] Fixes #222: Check whthere available() == 0 before calling blocking read() --- .../core/buffer/InputStreamBufferInput.java | 9 ++++-- .../core/buffer/MessageBufferInputTest.scala | 32 +++++++++++++++++-- 2 files changed, 35 insertions(+), 6 deletions(-) diff --git a/msgpack-core/src/main/java/org/msgpack/core/buffer/InputStreamBufferInput.java b/msgpack-core/src/main/java/org/msgpack/core/buffer/InputStreamBufferInput.java index d9a7c3466..feb473ea3 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/buffer/InputStreamBufferInput.java +++ b/msgpack-core/src/main/java/org/msgpack/core/buffer/InputStreamBufferInput.java @@ -57,11 +57,14 @@ public MessageBuffer next() throws IOException { byte[] buffer = null; int cursor = 0; while(!reachedEOF && cursor < bufferSize) { - if(buffer == null) + if(buffer == null) { buffer = new byte[bufferSize]; + } - int readLen = in.read(buffer, cursor, bufferSize - cursor); - if(readLen == -1) { + int readLen = -1; + // available() == 0 means, it reached the end of the stream + if(in.available() == 0 || + (readLen = in.read(buffer, cursor, bufferSize - cursor)) == -1) { reachedEOF = true; break; } diff --git a/msgpack-core/src/test/scala/org/msgpack/core/buffer/MessageBufferInputTest.scala b/msgpack-core/src/test/scala/org/msgpack/core/buffer/MessageBufferInputTest.scala index 379badf7e..8daa5929e 100644 --- a/msgpack-core/src/test/scala/org/msgpack/core/buffer/MessageBufferInputTest.scala +++ b/msgpack-core/src/test/scala/org/msgpack/core/buffer/MessageBufferInputTest.scala @@ -2,11 +2,11 @@ package org.msgpack.core.buffer import org.msgpack.core.{MessageUnpacker, MessagePack, MessagePackSpec} import java.io._ -import xerial.core.io.IOUtil +import xerial.core.io.IOUtil._ import scala.util.Random import java.util.zip.{GZIPOutputStream, GZIPInputStream} import java.nio.ByteBuffer -import org.msgpack.unpacker.MessagePackUnpacker + /** * Created on 5/30/14. @@ -49,7 +49,7 @@ class MessageBufferInputTest extends MessagePackSpec { val tmp = File.createTempFile("testbuf", ".dat", new File("target")) tmp.getParentFile.mkdirs() tmp.deleteOnExit() - IOUtil.withResource(new FileOutputStream(tmp)) { out => + withResource(new FileOutputStream(tmp)) { out => out.write(b) } tmp @@ -135,6 +135,32 @@ class MessageBufferInputTest extends MessagePackSpec { buf.reset(in1) readInt(buf) shouldBe 42 } + + "be non-blocking" taggedAs("non-blocking") in { + + withResource(new PipedOutputStream()) { pipedOutputStream => + withResource(new PipedInputStream()) { pipedInputStream => + pipedInputStream.connect(pipedOutputStream) + + val packer = MessagePack.newDefaultPacker(pipedOutputStream) + .packArrayHeader(2) + .packLong(42) + .packString("hello world") + + packer.flush + + val unpacker = MessagePack.newDefaultUnpacker(pipedInputStream) + unpacker.hasNext() shouldBe true + unpacker.unpackArrayHeader() shouldBe 2 + unpacker.unpackLong() shouldBe 42L + unpacker.unpackString() shouldBe "hello world" + + packer.close + unpacker.close + } + } + } + } "ChannelBufferInput" should { From 13e79eda2952f38572e2967ae316227f03a48794 Mon Sep 17 00:00:00 2001 From: Mitsunori Komatsu Date: Mon, 25 May 2015 18:06:34 +0900 Subject: [PATCH 046/234] Update README.md --- msgpack-jackson/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/msgpack-jackson/README.md b/msgpack-jackson/README.md index 255162b08..c6509845f 100644 --- a/msgpack-jackson/README.md +++ b/msgpack-jackson/README.md @@ -11,7 +11,7 @@ To use this module on Maven-based projects, use following dependency: org.msgpack jackson-dataformat-msgpack - 0.7.0-p5 + 0.7.0-p9 ``` From dad4a73142db6eac5a805aa578ba56c23a7e978e Mon Sep 17 00:00:00 2001 From: Mitsunori Komatsu Date: Mon, 25 May 2015 23:51:35 +0900 Subject: [PATCH 047/234] Consider JsonGenerator.Feature#AUTO_CLOSE_TARGET --- .../jackson/dataformat/MessagePackGenerator.java | 6 ++++-- .../dataformat/MessagePackGeneratorTest.java | 14 ++++++++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackGenerator.java b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackGenerator.java index bc23e130c..e04b01420 100644 --- a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackGenerator.java +++ b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackGenerator.java @@ -330,8 +330,10 @@ public void close() throws IOException { flush(); } finally { - MessagePacker messagePacker = getMessagePacker(); - messagePacker.close(); + if (isEnabled(Feature.AUTO_CLOSE_TARGET)) { + MessagePacker messagePacker = getMessagePacker(); + messagePacker.close(); + } } } diff --git a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackGeneratorTest.java b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackGeneratorTest.java index f1655f3d0..eb627e665 100644 --- a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackGeneratorTest.java +++ b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackGeneratorTest.java @@ -25,6 +25,7 @@ import java.io.File; import java.io.FileInputStream; +import java.io.FileOutputStream; import java.io.IOException; import java.math.BigDecimal; import java.util.*; @@ -263,4 +264,17 @@ public void testBigDecimal() throws IOException { } } } + + @Test + public void testDisableFeatureAutoCloseTarget() throws IOException { + File tempFile = File.createTempFile("test", "msgpack"); + FileOutputStream out = new FileOutputStream(tempFile); + MessagePackFactory messagePackFactory = new MessagePackFactory(); + messagePackFactory.disable(JsonGenerator.Feature.AUTO_CLOSE_TARGET); + ObjectMapper objectMapper = new ObjectMapper(messagePackFactory); + List integers = Arrays.asList(1); + objectMapper.writeValue(out, integers); + objectMapper.writeValue(out, integers); + out.close(); + } } From af428dee61c3468e0db593e26980df2d03444f17 Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Tue, 26 May 2015 01:06:32 +0900 Subject: [PATCH 048/234] Use partial read results to avoid I/O block when reading at the end of a stream --- .../core/buffer/InputStreamBufferInput.java | 23 +++++-------------- 1 file changed, 6 insertions(+), 17 deletions(-) diff --git a/msgpack-core/src/main/java/org/msgpack/core/buffer/InputStreamBufferInput.java b/msgpack-core/src/main/java/org/msgpack/core/buffer/InputStreamBufferInput.java index feb473ea3..7ccb61f7c 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/buffer/InputStreamBufferInput.java +++ b/msgpack-core/src/main/java/org/msgpack/core/buffer/InputStreamBufferInput.java @@ -54,24 +54,13 @@ public MessageBuffer next() throws IOException { if(reachedEOF) return null; - byte[] buffer = null; - int cursor = 0; - while(!reachedEOF && cursor < bufferSize) { - if(buffer == null) { - buffer = new byte[bufferSize]; - } - - int readLen = -1; - // available() == 0 means, it reached the end of the stream - if(in.available() == 0 || - (readLen = in.read(buffer, cursor, bufferSize - cursor)) == -1) { - reachedEOF = true; - break; - } - cursor += readLen; + byte[] buffer = new byte[bufferSize]; + int readLen = in.read(buffer); + if(readLen == -1) { + reachedEOF = true; + return null; } - - return buffer == null ? null : MessageBuffer.wrap(buffer).slice(0, cursor); + return MessageBuffer.wrap(buffer).slice(0, readLen); } @Override From a785c91534068241b5efc0bbe0e50572ba03594e Mon Sep 17 00:00:00 2001 From: Mitsunori Komatsu Date: Tue, 26 May 2015 01:42:21 +0900 Subject: [PATCH 049/234] Improve MessagePackGeneratorTest --- .../jackson/dataformat/MessagePackGeneratorTest.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackGeneratorTest.java b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackGeneratorTest.java index eb627e665..fad817b47 100644 --- a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackGeneratorTest.java +++ b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackGeneratorTest.java @@ -268,6 +268,7 @@ public void testBigDecimal() throws IOException { @Test public void testDisableFeatureAutoCloseTarget() throws IOException { File tempFile = File.createTempFile("test", "msgpack"); + tempFile.deleteOnExit(); FileOutputStream out = new FileOutputStream(tempFile); MessagePackFactory messagePackFactory = new MessagePackFactory(); messagePackFactory.disable(JsonGenerator.Feature.AUTO_CLOSE_TARGET); @@ -276,5 +277,11 @@ public void testDisableFeatureAutoCloseTarget() throws IOException { objectMapper.writeValue(out, integers); objectMapper.writeValue(out, integers); out.close(); + + MessageUnpacker unpacker = MessagePack.newDefaultUnpacker(new FileInputStream(tempFile)); + assertEquals(1, unpacker.unpackArrayHeader()); + assertEquals(1, unpacker.unpackInt()); + assertEquals(1, unpacker.unpackArrayHeader()); + assertEquals(1, unpacker.unpackInt()); } } From ead6f945ad5edee5d3661b45320a37299ffe7173 Mon Sep 17 00:00:00 2001 From: Mitsunori Komatsu Date: Tue, 26 May 2015 13:04:21 +0900 Subject: [PATCH 050/234] Add tests in MessagePackGeneratorTest --- .../dataformat/MessagePackGeneratorTest.java | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackGeneratorTest.java b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackGeneratorTest.java index fad817b47..383a8f593 100644 --- a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackGeneratorTest.java +++ b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackGeneratorTest.java @@ -265,14 +265,26 @@ public void testBigDecimal() throws IOException { } } + @Test(expected = IOException.class) + public void testEnableFeatureAutoCloseTarget() throws IOException { + File tempFile = File.createTempFile("test", "msgpack"); + tempFile.deleteOnExit(); + FileOutputStream out = new FileOutputStream(tempFile); + MessagePackFactory messagePackFactory = new MessagePackFactory(); + ObjectMapper objectMapper = new ObjectMapper(messagePackFactory); + List integers = Arrays.asList(1); + objectMapper.writeValue(out, integers); + objectMapper.writeValue(out, integers); + } + @Test public void testDisableFeatureAutoCloseTarget() throws IOException { File tempFile = File.createTempFile("test", "msgpack"); tempFile.deleteOnExit(); FileOutputStream out = new FileOutputStream(tempFile); MessagePackFactory messagePackFactory = new MessagePackFactory(); - messagePackFactory.disable(JsonGenerator.Feature.AUTO_CLOSE_TARGET); ObjectMapper objectMapper = new ObjectMapper(messagePackFactory); + objectMapper.configure(JsonGenerator.Feature.AUTO_CLOSE_TARGET, false); List integers = Arrays.asList(1); objectMapper.writeValue(out, integers); objectMapper.writeValue(out, integers); From 72cfaa74fd8f2bc782ac362eba24440e9fd5833e Mon Sep 17 00:00:00 2001 From: Mitsunori Komatsu Date: Thu, 28 May 2015 00:27:11 +0900 Subject: [PATCH 051/234] Use JsonFactory's _generatorFeatures and _parserFeatures in MessagePackFactory --- .../msgpack/jackson/dataformat/MessagePackFactory.java | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackFactory.java b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackFactory.java index 3d63f22a2..f1065bdaf 100644 --- a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackFactory.java +++ b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackFactory.java @@ -23,12 +23,10 @@ public class MessagePackFactory extends JsonFactory { private static final long serialVersionUID = 2578263992015504347L; - protected int messagePackGeneratorFeature = 0; - protected int messagePackParserFeature = 0; @Override public JsonGenerator createGenerator(OutputStream out, JsonEncoding enc) throws IOException { - return new MessagePackGenerator(messagePackGeneratorFeature, _objectCodec, out); + return new MessagePackGenerator(_generatorFeatures, _objectCodec, out); } @Override @@ -55,7 +53,7 @@ public JsonParser createParser(InputStream in) throws IOException, JsonParseExce @Override protected MessagePackParser _createParser(InputStream in, IOContext ctxt) throws IOException { - MessagePackParser parser = new MessagePackParser(ctxt, messagePackParserFeature, in); + MessagePackParser parser = new MessagePackParser(ctxt, _parserFeatures, in); return parser; } @@ -64,7 +62,7 @@ protected JsonParser _createParser(byte[] data, int offset, int len, IOContext c if (offset != 0 || len != data.length) { data = Arrays.copyOfRange(data, offset, offset + len); } - MessagePackParser parser = new MessagePackParser(ctxt, messagePackParserFeature, data); + MessagePackParser parser = new MessagePackParser(ctxt, _parserFeatures, data); return parser; } } From 93baf2113ce589b916444891ed8fd483b1f042bd Mon Sep 17 00:00:00 2001 From: Mitsunori Komatsu Date: Thu, 28 May 2015 02:20:18 +0900 Subject: [PATCH 052/234] Add some comments and tests about JsonParser.Feature.AUTO_CLOSE_SOURCE --- .../jackson/dataformat/MessagePackParser.java | 6 ++++ .../dataformat/MessagePackParserTest.java | 33 +++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java index 14ae24af2..131f00602 100644 --- a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java +++ b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java @@ -21,6 +21,7 @@ import java.math.BigDecimal; import java.math.BigInteger; import java.util.LinkedList; +import java.util.logging.Logger; public class MessagePackParser extends ParserMinimalBase { private static final ThreadLocal messageUnpackerHolder = new ThreadLocal(); @@ -72,6 +73,8 @@ public MessagePackParser(IOContext ctxt, int features, byte[] bytes) throws IOEx } private MessagePackParser(IOContext ctxt, int features, MessageBufferInput input) throws IOException { + super(features); + ioContext = ctxt; DupDetector dups = Feature.STRICT_DUPLICATE_DETECTION.enabledIn(features) ? DupDetector.rootDetector(this) : null; @@ -322,6 +325,9 @@ else if (numberValue.isValidLong()) { @Override public void close() throws IOException { try { + // JsonParser.Feature.AUTO_CLOSE_SOURCE can't be disabled for now. + // MessageUnpacker reads a stream ahead and load the data to its own buffer. + // As a result, following MessagePackParser fails to read the stream from proper position. MessageUnpacker messageUnpacker = getMessageUnpacker(); messageUnpacker.close(); } diff --git a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackParserTest.java b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackParserTest.java index dc81fc248..b119c303d 100644 --- a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackParserTest.java +++ b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackParserTest.java @@ -341,4 +341,37 @@ public void testBigDecimal() throws IOException { assertEquals(BigDecimal.valueOf(Double.MAX_VALUE), objects.get(idx++)); assertEquals(BigDecimal.valueOf(Double.MIN_NORMAL), objects.get(idx++)); } + + private File createTestFile() throws IOException { + File tempFile = File.createTempFile("test", "msgpack"); + tempFile.deleteOnExit(); + FileOutputStream out = new FileOutputStream(tempFile); + MessagePack.newDefaultPacker(out) + .packArrayHeader(1).packInt(1) + .packArrayHeader(1).packInt(1) + .close(); + return tempFile; + } + + @Test(expected = IOException.class) + public void testEnableFeatureAutoCloseSource() throws IOException { + File tempFile = createTestFile(); + MessagePackFactory messagePackFactory = new MessagePackFactory(); + FileInputStream in = new FileInputStream(tempFile); + ObjectMapper objectMapper = new ObjectMapper(messagePackFactory); + objectMapper.readValue(in, new TypeReference>() {}); + objectMapper.readValue(in, new TypeReference>() {}); + } + + // FIXME + @Test(expected = IOException.class) + public void testDisableFeatureAutoCloseSource() throws IOException { + File tempFile = createTestFile(); + MessagePackFactory messagePackFactory = new MessagePackFactory(); + FileInputStream in = new FileInputStream(tempFile); + ObjectMapper objectMapper = new ObjectMapper(messagePackFactory); + objectMapper.configure(JsonParser.Feature.AUTO_CLOSE_SOURCE, false); + objectMapper.readValue(in, new TypeReference>() {}); + objectMapper.readValue(in, new TypeReference>() {}); + } } From f2c5f794e38a19e7dc7e6286e0738e62c78a1d37 Mon Sep 17 00:00:00 2001 From: Mitsunori Komatsu Date: Fri, 29 May 2015 01:42:38 +0900 Subject: [PATCH 053/234] Take care of JsonParser.Feature.AUTO_CLOSE_SOURCE in MessagePackParser --- .../jackson/dataformat/MessagePackParser.java | 40 +++++++++++-------- .../org/msgpack/jackson/dataformat/Tuple.java | 22 ++++++++++ .../dataformat/MessagePackParserTest.java | 3 +- 3 files changed, 47 insertions(+), 18 deletions(-) create mode 100644 msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/Tuple.java diff --git a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java index 131f00602..3a7185eb2 100644 --- a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java +++ b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java @@ -24,7 +24,8 @@ import java.util.logging.Logger; public class MessagePackParser extends ParserMinimalBase { - private static final ThreadLocal messageUnpackerHolder = new ThreadLocal(); + private static final ThreadLocal> messageUnpackerHolder = + new ThreadLocal>(); private ObjectCodec codec; private JsonReadContext parsingContext; @@ -65,14 +66,14 @@ private static class StackItemForArray extends StackItem { } public MessagePackParser(IOContext ctxt, int features, InputStream in) throws IOException { - this(ctxt, features, new InputStreamBufferInput(in)); + this(ctxt, features, new InputStreamBufferInput(in), in); } public MessagePackParser(IOContext ctxt, int features, byte[] bytes) throws IOException { - this(ctxt, features, new ArrayBufferInput(bytes)); + this(ctxt, features, new ArrayBufferInput(bytes), bytes); } - private MessagePackParser(IOContext ctxt, int features, MessageBufferInput input) throws IOException { + private MessagePackParser(IOContext ctxt, int features, MessageBufferInput input, Object src) throws IOException { super(features); ioContext = ctxt; @@ -80,14 +81,22 @@ private MessagePackParser(IOContext ctxt, int features, MessageBufferInput input ? DupDetector.rootDetector(this) : null; parsingContext = JsonReadContext.createRootContext(dups); - MessageUnpacker messageUnpacker = messageUnpackerHolder.get(); - if (messageUnpacker == null) { + MessageUnpacker messageUnpacker; + Tuple messageUnpackerTuple = messageUnpackerHolder.get(); + if (messageUnpackerTuple == null) { messageUnpacker = new MessageUnpacker(input); } else { - messageUnpacker.reset(input); + // Considering to reuse InputStream with JsonParser.Feature.AUTO_CLOSE_SOURCE, + // MessagePackParser needs to use the MessageUnpacker that has the same InputStream + // since it has buffer which has loaded the InputStream data ahead. + // However, it needs to call MessageUnpacker#reset when the source is different from the previous one. + if (isEnabled(JsonParser.Feature.AUTO_CLOSE_SOURCE) || messageUnpackerTuple.first() != src) { + messageUnpackerTuple.second().reset(input); + } + messageUnpacker = messageUnpackerTuple.second(); } - messageUnpackerHolder.set(messageUnpacker); + messageUnpackerHolder.set(new Tuple(src, messageUnpacker)); } @Override @@ -325,11 +334,10 @@ else if (numberValue.isValidLong()) { @Override public void close() throws IOException { try { - // JsonParser.Feature.AUTO_CLOSE_SOURCE can't be disabled for now. - // MessageUnpacker reads a stream ahead and load the data to its own buffer. - // As a result, following MessagePackParser fails to read the stream from proper position. - MessageUnpacker messageUnpacker = getMessageUnpacker(); - messageUnpacker.close(); + if (isEnabled(JsonParser.Feature.AUTO_CLOSE_SOURCE)) { + MessageUnpacker messageUnpacker = getMessageUnpacker(); + messageUnpacker.close(); + } } catch (Exception e) { e.printStackTrace(); @@ -383,10 +391,10 @@ public void overrideCurrentName(String name) { } private MessageUnpacker getMessageUnpacker() { - MessageUnpacker messageUnpacker = messageUnpackerHolder.get(); - if (messageUnpacker == null) { + Tuple messageUnpackerTuple = messageUnpackerHolder.get(); + if (messageUnpackerTuple == null) { throw new IllegalStateException("messageUnpacker is null"); } - return messageUnpacker; + return messageUnpackerTuple.second(); } } diff --git a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/Tuple.java b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/Tuple.java new file mode 100644 index 000000000..8678e5200 --- /dev/null +++ b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/Tuple.java @@ -0,0 +1,22 @@ +package org.msgpack.jackson.dataformat; + +/** + * Created by komamitsu on 5/28/15. + */ +public class Tuple { + private final F first; + private final S second; + + public Tuple(F first, S second) { + this.first = first; + this.second = second; + } + + public F first() { + return first; + } + + public S second() { + return second; + } +} diff --git a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackParserTest.java b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackParserTest.java index b119c303d..ba6e8c346 100644 --- a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackParserTest.java +++ b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackParserTest.java @@ -363,8 +363,7 @@ public void testEnableFeatureAutoCloseSource() throws IOException { objectMapper.readValue(in, new TypeReference>() {}); } - // FIXME - @Test(expected = IOException.class) + @Test public void testDisableFeatureAutoCloseSource() throws IOException { File tempFile = createTestFile(); MessagePackFactory messagePackFactory = new MessagePackFactory(); From febcfde3c92355341070e2c8dcd08b79f96e37ad Mon Sep 17 00:00:00 2001 From: Mitsunori Komatsu Date: Sat, 30 May 2015 01:14:39 +0900 Subject: [PATCH 054/234] Fix wrong convertion fron long to int --- .../jackson/dataformat/MessagePackParser.java | 2 +- .../jackson/dataformat/MessagePackParserTest.java | 13 +++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java index 3a7185eb2..683343cff 100644 --- a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java +++ b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java @@ -287,7 +287,7 @@ public BigDecimal getDecimalValue() throws IOException { NumberValue number = ref.asNumber(); //optimization to not convert the value to BigInteger unnecessarily if (number.isValidByte() || number.isValidShort() || number.isValidInt() || number.isValidLong()) { - return BigDecimal.valueOf(number.asInt()); + return BigDecimal.valueOf(number.asLong()); } else { return new BigDecimal(number.asBigInteger()); diff --git a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackParserTest.java b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackParserTest.java index ba6e8c346..cf3314b3d 100644 --- a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackParserTest.java +++ b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackParserTest.java @@ -14,6 +14,7 @@ import java.math.BigDecimal; import java.math.BigInteger; import java.nio.ByteBuffer; +import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Map; @@ -373,4 +374,16 @@ public void testDisableFeatureAutoCloseSource() throws IOException { objectMapper.readValue(in, new TypeReference>() {}); objectMapper.readValue(in, new TypeReference>() {}); } + + @Test + public void testParseBigDecimal() throws IOException { + ArrayList list = new ArrayList(); + list.add(new BigDecimal(Long.MAX_VALUE)); + ObjectMapper objectMapper = new ObjectMapper(new MessagePackFactory()); + byte[] bytes = objectMapper.writeValueAsBytes(list); + + ArrayList result = objectMapper.readValue( + bytes, new TypeReference>() {}); + assertEquals(list, result); + } } From d5ba961a0eb9634e83b53b06a8203321fb61ce79 Mon Sep 17 00:00:00 2001 From: Mitsunori Komatsu Date: Sat, 30 May 2015 12:22:37 +0900 Subject: [PATCH 055/234] Enable MessagePackGenerator to write primitives directly --- .../dataformat/MessagePackGenerator.java | 23 +++++-- .../dataformat/MessagePackGeneratorTest.java | 69 ++++++++++++++++--- 2 files changed, 79 insertions(+), 13 deletions(-) diff --git a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackGenerator.java b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackGenerator.java index e04b01420..9ab725925 100644 --- a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackGenerator.java +++ b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackGenerator.java @@ -350,11 +350,16 @@ else if (rootStackItem instanceof StackItemForArray) { throw new IllegalStateException("Unexpected rootStackItem: " + rootStackItem); } rootStackItem = null; - MessagePacker messagePacker = getMessagePacker(); - messagePacker.flush(); + flushMessagePacker(); } } + private void flushMessagePacker() throws IOException + { + MessagePacker messagePacker = getMessagePacker(); + messagePacker.flush(); + } + @Override protected void _releaseBuffers() { @@ -395,11 +400,19 @@ private void addKeyToStackTop(String key) { getStackTop().addKey(key); } - private void addValueToStackTop(Object value) { - getStackTop().addValue(value); + private void addValueToStackTop(Object value) throws IOException + { + if (stack.isEmpty()) { + packValue(value); + flushMessagePacker(); + } + else { + getStackTop().addValue(value); + } } - private void popStackAndStoreTheItemAsValue() { + private void popStackAndStoreTheItemAsValue() throws IOException + { StackItem child = stack.pop(); if (stack.size() > 0) { addValueToStackTop(child); diff --git a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackGeneratorTest.java b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackGeneratorTest.java index 383a8f593..09bc1946a 100644 --- a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackGeneratorTest.java +++ b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackGeneratorTest.java @@ -27,6 +27,7 @@ import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; +import java.io.OutputStream; import java.math.BigDecimal; import java.util.*; @@ -199,8 +200,7 @@ else if (key.equals("num")) { @Test public void testMessagePackGeneratorDirectly() throws IOException { MessagePackFactory messagePackFactory = new MessagePackFactory(); - File tempFile = File.createTempFile("msgpackTest", "msgpack"); - tempFile.deleteOnExit(); + File tempFile = createTempFile(); JsonGenerator generator = messagePackFactory.createGenerator(tempFile, JsonEncoding.UTF8); assertTrue(generator instanceof MessagePackGenerator); @@ -222,6 +222,27 @@ public void testMessagePackGeneratorDirectly() throws IOException { assertFalse(unpacker.hasNext()); } + @Test + public void testWritePrimitives() throws IOException { + MessagePackFactory messagePackFactory = new MessagePackFactory(); + File tempFile = createTempFile(); + + JsonGenerator generator = messagePackFactory.createGenerator(tempFile, JsonEncoding.UTF8); + assertTrue(generator instanceof MessagePackGenerator); + generator.writeNumber(0); + generator.writeString("one"); + generator.writeNumber(2.0f); + generator.flush(); + generator.close(); + + FileInputStream fileInputStream = new FileInputStream(tempFile); + MessageUnpacker unpacker = MessagePack.newDefaultUnpacker(fileInputStream); + assertEquals(0, unpacker.unpackInt()); + assertEquals("one", unpacker.unpackString()); + assertEquals(2.0f, unpacker.unpackFloat(), 0.001f); + assertFalse(unpacker.hasNext()); + } + @Test public void testBigDecimal() throws IOException { ObjectMapper mapper = new ObjectMapper(new MessagePackFactory()); @@ -265,11 +286,21 @@ public void testBigDecimal() throws IOException { } } - @Test(expected = IOException.class) - public void testEnableFeatureAutoCloseTarget() throws IOException { + private File createTempFile() throws IOException { + File tempFile = File.createTempFile("test", "msgpack"); + tempFile.deleteOnExit(); + return tempFile; + } + + private OutputStream createTempFileOutputStream() throws IOException { File tempFile = File.createTempFile("test", "msgpack"); tempFile.deleteOnExit(); - FileOutputStream out = new FileOutputStream(tempFile); + return new FileOutputStream(tempFile); + } + + @Test(expected = IOException.class) + public void testEnableFeatureAutoCloseTarget() throws IOException { + OutputStream out = createTempFileOutputStream(); MessagePackFactory messagePackFactory = new MessagePackFactory(); ObjectMapper objectMapper = new ObjectMapper(messagePackFactory); List integers = Arrays.asList(1); @@ -279,9 +310,8 @@ public void testEnableFeatureAutoCloseTarget() throws IOException { @Test public void testDisableFeatureAutoCloseTarget() throws IOException { - File tempFile = File.createTempFile("test", "msgpack"); - tempFile.deleteOnExit(); - FileOutputStream out = new FileOutputStream(tempFile); + File tempFile = createTempFile(); + OutputStream out = new FileOutputStream(tempFile); MessagePackFactory messagePackFactory = new MessagePackFactory(); ObjectMapper objectMapper = new ObjectMapper(messagePackFactory); objectMapper.configure(JsonGenerator.Feature.AUTO_CLOSE_TARGET, false); @@ -296,4 +326,27 @@ public void testDisableFeatureAutoCloseTarget() throws IOException { assertEquals(1, unpacker.unpackArrayHeader()); assertEquals(1, unpacker.unpackInt()); } + + @Test + public void testWritePrimitiveObjectViaObjectMapper() throws IOException + { + File tempFile = createTempFile(); + OutputStream out = new FileOutputStream(tempFile); + + ObjectMapper objectMapper = new ObjectMapper(new MessagePackFactory()); + objectMapper.disable(JsonGenerator.Feature.AUTO_CLOSE_TARGET); + objectMapper.writeValue(out, 1); + objectMapper.writeValue(out, "two"); + objectMapper.writeValue(out, 3.14); + objectMapper.writeValue(out, Arrays.asList(4)); + objectMapper.writeValue(out, 5L); + + MessageUnpacker unpacker = MessagePack.newDefaultUnpacker(new FileInputStream(tempFile)); + assertEquals(1, unpacker.unpackInt()); + assertEquals("two", unpacker.unpackString()); + assertEquals(3.14, unpacker.unpackFloat(), 0.0001); + assertEquals(1, unpacker.unpackArrayHeader()); + assertEquals(4, unpacker.unpackInt()); + assertEquals(5, unpacker.unpackLong()); + } } From 1db7c3e2ca13c60a74db50c18803ed11b8d01073 Mon Sep 17 00:00:00 2001 From: Mitsunori Komatsu Date: Sat, 30 May 2015 23:21:00 +0900 Subject: [PATCH 056/234] Add some tests in MessagePackParserTest --- .../MessagePackDataformatTestBase.java | 27 ++++++ .../dataformat/MessagePackGeneratorTest.java | 21 +---- .../dataformat/MessagePackParserTest.java | 82 ++++++++++++++++--- 3 files changed, 101 insertions(+), 29 deletions(-) diff --git a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackDataformatTestBase.java b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackDataformatTestBase.java index 27a5dfd12..c248067d0 100644 --- a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackDataformatTestBase.java +++ b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackDataformatTestBase.java @@ -11,7 +11,10 @@ import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileOutputStream; import java.io.IOException; +import java.io.OutputStream; import java.math.BigInteger; import java.util.ArrayList; import java.util.Arrays; @@ -175,4 +178,28 @@ public static class ChangingPropertyNamesPojo { public void setTheName(String n) { _name = n; } } + protected interface FileSetup { + void setup(File f) throws Exception; + } + + protected File createTempFile() throws Exception + { + return createTempFile(null); + } + + protected File createTempFile(FileSetup fileSetup) throws Exception + { + File tempFile = File.createTempFile("test", "msgpack"); + tempFile.deleteOnExit(); + if (fileSetup != null) { + fileSetup.setup(tempFile); + } + return tempFile; + } + + protected OutputStream createTempFileOutputStream() throws IOException { + File tempFile = File.createTempFile("test", "msgpack"); + tempFile.deleteOnExit(); + return new FileOutputStream(tempFile); + } } diff --git a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackGeneratorTest.java b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackGeneratorTest.java index 09bc1946a..c8961f3c2 100644 --- a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackGeneratorTest.java +++ b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackGeneratorTest.java @@ -198,7 +198,7 @@ else if (key.equals("num")) { } @Test - public void testMessagePackGeneratorDirectly() throws IOException { + public void testMessagePackGeneratorDirectly() throws Exception { MessagePackFactory messagePackFactory = new MessagePackFactory(); File tempFile = createTempFile(); @@ -223,7 +223,7 @@ public void testMessagePackGeneratorDirectly() throws IOException { } @Test - public void testWritePrimitives() throws IOException { + public void testWritePrimitives() throws Exception { MessagePackFactory messagePackFactory = new MessagePackFactory(); File tempFile = createTempFile(); @@ -286,18 +286,6 @@ public void testBigDecimal() throws IOException { } } - private File createTempFile() throws IOException { - File tempFile = File.createTempFile("test", "msgpack"); - tempFile.deleteOnExit(); - return tempFile; - } - - private OutputStream createTempFileOutputStream() throws IOException { - File tempFile = File.createTempFile("test", "msgpack"); - tempFile.deleteOnExit(); - return new FileOutputStream(tempFile); - } - @Test(expected = IOException.class) public void testEnableFeatureAutoCloseTarget() throws IOException { OutputStream out = createTempFileOutputStream(); @@ -309,7 +297,7 @@ public void testEnableFeatureAutoCloseTarget() throws IOException { } @Test - public void testDisableFeatureAutoCloseTarget() throws IOException { + public void testDisableFeatureAutoCloseTarget() throws Exception { File tempFile = createTempFile(); OutputStream out = new FileOutputStream(tempFile); MessagePackFactory messagePackFactory = new MessagePackFactory(); @@ -328,8 +316,7 @@ public void testDisableFeatureAutoCloseTarget() throws IOException { } @Test - public void testWritePrimitiveObjectViaObjectMapper() throws IOException - { + public void testWritePrimitiveObjectViaObjectMapper() throws Exception { File tempFile = createTempFile(); OutputStream out = new FileOutputStream(tempFile); diff --git a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackParserTest.java b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackParserTest.java index cf3314b3d..2f227cce5 100644 --- a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackParserTest.java +++ b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackParserTest.java @@ -318,6 +318,36 @@ public void testMessagePackParserDirectly() throws IOException { parser.close(); // Intentional } + @Test + public void testReadPrimitives() throws Exception + { + MessagePackFactory messagePackFactory = new MessagePackFactory(); + File tempFile = createTempFile(); + + FileOutputStream out = new FileOutputStream(tempFile); + MessagePacker packer = MessagePack.newDefaultPacker(out); + packer.packString("foo"); + packer.packDouble(3.14); + packer.packLong(Long.MAX_VALUE); + byte[] bytes = {0x00, 0x11, 0x22}; + packer.packBinaryHeader(bytes.length); + packer.writePayload(bytes); + packer.close(); + + JsonParser parser = messagePackFactory.createParser(new FileInputStream(tempFile)); + assertEquals(JsonToken.VALUE_STRING, parser.nextToken()); + assertEquals("foo", parser.getText()); + assertEquals(JsonToken.VALUE_NUMBER_FLOAT, parser.nextToken()); + assertEquals(3.14, parser.getDoubleValue(), 0.0001); + assertEquals(JsonToken.VALUE_NUMBER_INT, parser.nextToken()); + assertEquals(Long.MAX_VALUE, parser.getLongValue()); + assertEquals(JsonToken.VALUE_EMBEDDED_OBJECT, parser.nextToken()); + assertEquals(bytes.length, parser.getBinaryValue().length); + assertEquals(bytes[0], parser.getBinaryValue()[0]); + assertEquals(bytes[1], parser.getBinaryValue()[1]); + assertEquals(bytes[2], parser.getBinaryValue()[2]); + } + @Test public void testBigDecimal() throws IOException { double d0 = 1.23456789; @@ -343,19 +373,21 @@ public void testBigDecimal() throws IOException { assertEquals(BigDecimal.valueOf(Double.MIN_NORMAL), objects.get(idx++)); } - private File createTestFile() throws IOException { - File tempFile = File.createTempFile("test", "msgpack"); - tempFile.deleteOnExit(); - FileOutputStream out = new FileOutputStream(tempFile); - MessagePack.newDefaultPacker(out) - .packArrayHeader(1).packInt(1) - .packArrayHeader(1).packInt(1) - .close(); + private File createTestFile() throws Exception { + File tempFile = createTempFile(new FileSetup() { + @Override + public void setup(File f) throws IOException { + MessagePack.newDefaultPacker(new FileOutputStream(f)) + .packArrayHeader(1).packInt(1) + .packArrayHeader(1).packInt(1) + .close(); + } + }); return tempFile; } @Test(expected = IOException.class) - public void testEnableFeatureAutoCloseSource() throws IOException { + public void testEnableFeatureAutoCloseSource() throws Exception { File tempFile = createTestFile(); MessagePackFactory messagePackFactory = new MessagePackFactory(); FileInputStream in = new FileInputStream(tempFile); @@ -365,11 +397,10 @@ public void testEnableFeatureAutoCloseSource() throws IOException { } @Test - public void testDisableFeatureAutoCloseSource() throws IOException { + public void testDisableFeatureAutoCloseSource() throws Exception { File tempFile = createTestFile(); - MessagePackFactory messagePackFactory = new MessagePackFactory(); FileInputStream in = new FileInputStream(tempFile); - ObjectMapper objectMapper = new ObjectMapper(messagePackFactory); + ObjectMapper objectMapper = new ObjectMapper(new MessagePackFactory()); objectMapper.configure(JsonParser.Feature.AUTO_CLOSE_SOURCE, false); objectMapper.readValue(in, new TypeReference>() {}); objectMapper.readValue(in, new TypeReference>() {}); @@ -386,4 +417,31 @@ public void testParseBigDecimal() throws IOException { bytes, new TypeReference>() {}); assertEquals(list, result); } + + @Test + public void testReadPrimitiveObjectViaObjectMapper() throws Exception { + File tempFile = createTempFile(); + FileOutputStream out = new FileOutputStream(tempFile); + + MessagePacker packer = MessagePack.newDefaultPacker(out); + packer.packString("foo"); + packer.packLong(Long.MAX_VALUE); + packer.packDouble(3.14); + byte[] bytes = {0x00, 0x11, 0x22}; + packer.packBinaryHeader(bytes.length); + packer.writePayload(bytes); + packer.close(); + + FileInputStream in = new FileInputStream(tempFile); + ObjectMapper objectMapper = new ObjectMapper(new MessagePackFactory()); + objectMapper.disable(JsonParser.Feature.AUTO_CLOSE_SOURCE); + assertEquals("foo", objectMapper.readValue(in, new TypeReference() {})); + assertEquals(Long.MAX_VALUE, objectMapper.readValue(in, new TypeReference() {})); + assertEquals(3.14, objectMapper.readValue(in, new TypeReference() {})); + byte[] bs = objectMapper.readValue(in, new TypeReference() {}); + assertEquals(bytes.length, bs.length); + assertEquals(bytes[0], bs[0]); + assertEquals(bytes[1], bs[1]); + assertEquals(bytes[2], bs[2]); + } } From 62b7512b55010fa640a2ac19ff43fdeb0347f85b Mon Sep 17 00:00:00 2001 From: Frank Dinoff Date: Sun, 7 Jun 2015 19:22:43 -0400 Subject: [PATCH 057/234] Propagate IOException to caller instead of swallowing --- .../java/org/msgpack/jackson/dataformat/MessagePackParser.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java index 683343cff..45ebcae71 100644 --- a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java +++ b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java @@ -339,9 +339,6 @@ public void close() throws IOException { messageUnpacker.close(); } } - catch (Exception e) { - e.printStackTrace(); - } finally { isClosed = true; } From 2242fe497b88c6add197b67ffd46a71e926ff593 Mon Sep 17 00:00:00 2001 From: Sadayuki Furuhashi Date: Wed, 10 Jun 2015 10:05:49 +0900 Subject: [PATCH 058/234] implemented Value API --- .../org/msgpack/core/ExtendedTypeHeader.java | 6 +- .../java/org/msgpack/core/MessageFormat.java | 2 +- .../core/MessageIntegerOverflowException.java | 1 - .../core/MessageTypeCastException.java | 34 ++ .../org/msgpack/core/MessageUnpacker.java | 224 +++++-------- .../core/example/MessagePackExample.java | 53 ++- .../msgpack/value/AbstractValueVisitor.java | 48 --- .../java/org/msgpack/value/ArrayCursor.java | 24 -- .../java/org/msgpack/value/ArrayValue.java | 57 +++- .../java/org/msgpack/value/BinaryValue.java | 26 +- .../java/org/msgpack/value/BooleanValue.java | 30 +- .../main/java/org/msgpack/value/Cursor.java | 66 ---- .../java/org/msgpack/value/ExtendedValue.java | 33 +- .../java/org/msgpack/value/FloatValue.java | 26 +- .../msgpack/value/ImmutableArrayValue.java | 34 ++ ...Visitor.java => ImmutableBinaryValue.java} | 17 +- .../msgpack/value/ImmutableBooleanValue.java | 19 ++ .../msgpack/value/ImmutableExtendedValue.java | 19 ++ .../msgpack/value/ImmutableFloatValue.java | 19 ++ .../msgpack/value/ImmutableIntegerValue.java | 19 ++ .../org/msgpack/value/ImmutableMapValue.java | 19 ++ .../org/msgpack/value/ImmutableNilValue.java | 19 ++ .../msgpack/value/ImmutableNumberValue.java | 19 ++ .../org/msgpack/value/ImmutableRawValue.java | 19 ++ .../msgpack/value/ImmutableStringValue.java | 19 ++ .../org/msgpack/value/ImmutableValue.java | 47 +++ .../java/org/msgpack/value/IntegerValue.java | 83 ++++- .../java/org/msgpack/value/MapCursor.java | 32 -- .../main/java/org/msgpack/value/MapValue.java | 54 ++- .../main/java/org/msgpack/value/NilValue.java | 20 +- .../java/org/msgpack/value/NumberValue.java | 116 +++---- .../main/java/org/msgpack/value/RawValue.java | 62 +++- .../java/org/msgpack/value/StringValue.java | 26 +- .../main/java/org/msgpack/value/Value.java | 234 ++++++++++++- .../java/org/msgpack/value/ValueFactory.java | 141 ++++---- .../main/java/org/msgpack/value/ValueRef.java | 54 --- .../java/org/msgpack/value/ValueType.java | 20 -- .../org/msgpack/value/holder/ExtHolder.java | 69 ---- .../org/msgpack/value/holder/FloatHolder.java | 178 ---------- .../msgpack/value/holder/IntegerHolder.java | 268 --------------- .../org/msgpack/value/holder/RawHolder.java | 270 --------------- .../org/msgpack/value/holder/ValueHolder.java | 127 ------- .../value/impl/AbstractImmutableRawValue.java | 168 ++++++++++ .../value/impl/AbstractImmutableValue.java | 132 ++++++++ .../org/msgpack/value/impl/AbstractValue.java | 13 - .../msgpack/value/impl/AbstractValueRef.java | 62 ---- .../msgpack/value/impl/ArrayCursorImpl.java | 126 ------- .../msgpack/value/impl/ArrayValueImpl.java | 162 --------- .../msgpack/value/impl/BinaryValueImpl.java | 33 -- .../msgpack/value/impl/BooleanValueImpl.java | 63 ---- .../org/msgpack/value/impl/CursorImpl.java | 134 -------- .../msgpack/value/impl/DoubleValueImpl.java | 152 --------- .../msgpack/value/impl/ExtendedValueImpl.java | 50 --- .../msgpack/value/impl/FloatValueImpl.java | 159 --------- .../value/impl/ImmutableArrayValueImpl.java | 210 ++++++++++++ ...java => ImmutableBigIntegerValueImpl.java} | 142 ++++---- .../value/impl/ImmutableBinaryValueImpl.java | 84 +++++ .../value/impl/ImmutableBooleanValueImpl.java | 101 ++++++ .../value/impl/ImmutableDoubleValueImpl.java | 116 +++++++ .../impl/ImmutableExtendedValueImpl.java | 111 +++++++ ...eImpl.java => ImmutableLongValueImpl.java} | 135 ++++---- .../value/impl/ImmutableMapValueImpl.java | 310 ++++++++++++++++++ .../value/impl/ImmutableNilValueImpl.java | 82 +++++ .../value/impl/ImmutableStringValueImpl.java | 88 +++++ .../msgpack/value/impl/IntegerValueImpl.java | 169 ---------- .../org/msgpack/value/impl/MapCursorImpl.java | 116 ------- .../org/msgpack/value/impl/MapValueImpl.java | 280 ---------------- .../org/msgpack/value/impl/NilValueImpl.java | 60 ---- .../value/impl/RawStringValueImpl.java | 69 ---- .../org/msgpack/value/impl/RawValueImpl.java | 116 ------- .../msgpack/value/impl/StringValueImpl.java | 84 ----- .../org/msgpack/value/impl/ValueUnion.java | 131 -------- .../dataformat/MessagePackExtendedType.java | 25 -- .../jackson/dataformat/MessagePackParser.java | 130 ++++---- 74 files changed, 2725 insertions(+), 3741 deletions(-) create mode 100644 msgpack-core/src/main/java/org/msgpack/core/MessageTypeCastException.java delete mode 100644 msgpack-core/src/main/java/org/msgpack/value/AbstractValueVisitor.java delete mode 100644 msgpack-core/src/main/java/org/msgpack/value/ArrayCursor.java delete mode 100644 msgpack-core/src/main/java/org/msgpack/value/Cursor.java create mode 100644 msgpack-core/src/main/java/org/msgpack/value/ImmutableArrayValue.java rename msgpack-core/src/main/java/org/msgpack/value/{ValueVisitor.java => ImmutableBinaryValue.java} (54%) create mode 100644 msgpack-core/src/main/java/org/msgpack/value/ImmutableBooleanValue.java create mode 100644 msgpack-core/src/main/java/org/msgpack/value/ImmutableExtendedValue.java create mode 100644 msgpack-core/src/main/java/org/msgpack/value/ImmutableFloatValue.java create mode 100644 msgpack-core/src/main/java/org/msgpack/value/ImmutableIntegerValue.java create mode 100644 msgpack-core/src/main/java/org/msgpack/value/ImmutableMapValue.java create mode 100644 msgpack-core/src/main/java/org/msgpack/value/ImmutableNilValue.java create mode 100644 msgpack-core/src/main/java/org/msgpack/value/ImmutableNumberValue.java create mode 100644 msgpack-core/src/main/java/org/msgpack/value/ImmutableRawValue.java create mode 100644 msgpack-core/src/main/java/org/msgpack/value/ImmutableStringValue.java create mode 100644 msgpack-core/src/main/java/org/msgpack/value/ImmutableValue.java delete mode 100644 msgpack-core/src/main/java/org/msgpack/value/MapCursor.java delete mode 100644 msgpack-core/src/main/java/org/msgpack/value/ValueRef.java delete mode 100644 msgpack-core/src/main/java/org/msgpack/value/holder/ExtHolder.java delete mode 100644 msgpack-core/src/main/java/org/msgpack/value/holder/FloatHolder.java delete mode 100644 msgpack-core/src/main/java/org/msgpack/value/holder/IntegerHolder.java delete mode 100644 msgpack-core/src/main/java/org/msgpack/value/holder/RawHolder.java delete mode 100644 msgpack-core/src/main/java/org/msgpack/value/holder/ValueHolder.java create mode 100644 msgpack-core/src/main/java/org/msgpack/value/impl/AbstractImmutableRawValue.java create mode 100644 msgpack-core/src/main/java/org/msgpack/value/impl/AbstractImmutableValue.java delete mode 100644 msgpack-core/src/main/java/org/msgpack/value/impl/AbstractValue.java delete mode 100644 msgpack-core/src/main/java/org/msgpack/value/impl/AbstractValueRef.java delete mode 100644 msgpack-core/src/main/java/org/msgpack/value/impl/ArrayCursorImpl.java delete mode 100644 msgpack-core/src/main/java/org/msgpack/value/impl/ArrayValueImpl.java delete mode 100644 msgpack-core/src/main/java/org/msgpack/value/impl/BinaryValueImpl.java delete mode 100644 msgpack-core/src/main/java/org/msgpack/value/impl/BooleanValueImpl.java delete mode 100644 msgpack-core/src/main/java/org/msgpack/value/impl/CursorImpl.java delete mode 100644 msgpack-core/src/main/java/org/msgpack/value/impl/DoubleValueImpl.java delete mode 100644 msgpack-core/src/main/java/org/msgpack/value/impl/ExtendedValueImpl.java delete mode 100644 msgpack-core/src/main/java/org/msgpack/value/impl/FloatValueImpl.java create mode 100644 msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableArrayValueImpl.java rename msgpack-core/src/main/java/org/msgpack/value/impl/{BigIntegerValueImpl.java => ImmutableBigIntegerValueImpl.java} (62%) create mode 100644 msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableBinaryValueImpl.java create mode 100644 msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableBooleanValueImpl.java create mode 100644 msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableDoubleValueImpl.java create mode 100644 msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableExtendedValueImpl.java rename msgpack-core/src/main/java/org/msgpack/value/impl/{LongValueImpl.java => ImmutableLongValueImpl.java} (57%) create mode 100644 msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableMapValueImpl.java create mode 100644 msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableNilValueImpl.java create mode 100644 msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableStringValueImpl.java delete mode 100644 msgpack-core/src/main/java/org/msgpack/value/impl/IntegerValueImpl.java delete mode 100644 msgpack-core/src/main/java/org/msgpack/value/impl/MapCursorImpl.java delete mode 100644 msgpack-core/src/main/java/org/msgpack/value/impl/MapValueImpl.java delete mode 100644 msgpack-core/src/main/java/org/msgpack/value/impl/NilValueImpl.java delete mode 100644 msgpack-core/src/main/java/org/msgpack/value/impl/RawStringValueImpl.java delete mode 100644 msgpack-core/src/main/java/org/msgpack/value/impl/RawValueImpl.java delete mode 100644 msgpack-core/src/main/java/org/msgpack/value/impl/StringValueImpl.java delete mode 100644 msgpack-core/src/main/java/org/msgpack/value/impl/ValueUnion.java delete mode 100644 msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackExtendedType.java diff --git a/msgpack-core/src/main/java/org/msgpack/core/ExtendedTypeHeader.java b/msgpack-core/src/main/java/org/msgpack/core/ExtendedTypeHeader.java index c4d4cc15e..517e971fe 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/ExtendedTypeHeader.java +++ b/msgpack-core/src/main/java/org/msgpack/core/ExtendedTypeHeader.java @@ -6,16 +6,16 @@ * Header of the extended types */ public class ExtendedTypeHeader { + private final byte type; private final int length; - private final int type; - ExtendedTypeHeader(int length, int type) { + ExtendedTypeHeader(byte type, int length) { checkArgument(length >= 0, String.format("length must be >= 0: %,d", length)); this.length = length; this.type = type; } - public int getType() { + public byte getType() { return type; } diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessageFormat.java b/msgpack-core/src/main/java/org/msgpack/core/MessageFormat.java index cffb525e2..7e32bcc79 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/MessageFormat.java +++ b/msgpack-core/src/main/java/org/msgpack/core/MessageFormat.java @@ -95,7 +95,7 @@ public static MessageFormat valueOf(final byte b) { * @return */ @VisibleForTesting - public static MessageFormat toMessageFormat(final byte b) { + static MessageFormat toMessageFormat(final byte b) { if (Code.isPosFixInt(b)) { return POSFIXINT; } diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessageIntegerOverflowException.java b/msgpack-core/src/main/java/org/msgpack/core/MessageIntegerOverflowException.java index c3d561ec1..21302803b 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/MessageIntegerOverflowException.java +++ b/msgpack-core/src/main/java/org/msgpack/core/MessageIntegerOverflowException.java @@ -24,7 +24,6 @@ * that is larger than Integer.MAX_VALUE will cause this exception. */ public class MessageIntegerOverflowException extends MessageOverflowException { - private final BigInteger bigInteger; public MessageIntegerOverflowException(BigInteger bigInteger) { diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessageTypeCastException.java b/msgpack-core/src/main/java/org/msgpack/core/MessageTypeCastException.java new file mode 100644 index 000000000..6189cc646 --- /dev/null +++ b/msgpack-core/src/main/java/org/msgpack/core/MessageTypeCastException.java @@ -0,0 +1,34 @@ +// +// MessagePack for Java +// +// 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.core; + +public class MessageTypeCastException extends MessageTypeException { + public MessageTypeCastException() { + super(); + } + + public MessageTypeCastException(String message) { + super(message); + } + + public MessageTypeCastException(String message, Throwable cause) { + super(message, cause); + } + + public MessageTypeCastException(Throwable cause) { + super(cause); + } +} diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java b/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java index 628525990..c0f163cf4 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java +++ b/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java @@ -30,12 +30,10 @@ import org.msgpack.core.MessagePack.Code; import org.msgpack.core.buffer.MessageBuffer; import org.msgpack.core.buffer.MessageBufferInput; -import org.msgpack.value.Cursor; +import org.msgpack.value.Value; +import org.msgpack.value.ImmutableValue; import org.msgpack.value.ValueType; -import org.msgpack.value.holder.FloatHolder; -import org.msgpack.value.holder.IntegerHolder; -import org.msgpack.value.holder.ValueHolder; -import org.msgpack.value.impl.CursorImpl; +import org.msgpack.value.ValueFactory; import static org.msgpack.core.Preconditions.*; @@ -79,6 +77,7 @@ public class MessageUnpacker implements Closeable { * Points to the current buffer to read */ private MessageBuffer buffer = EMPTY_BUFFER; + /** * Cursor position in the current buffer */ @@ -115,16 +114,6 @@ public class MessageUnpacker implements Closeable { private CharBuffer decodeBuffer; - /** - * Get a {@link org.msgpack.value.Cursor} for traversing message-packed values - * @return - */ - public Cursor getCursor() { - return new CursorImpl(this); - } - - - /** * Create an MessageUnpacker that reads data from the given MessageBufferInput * @@ -531,57 +520,71 @@ public void skipValue() throws IOException { */ private static MessageTypeException unexpected(String expected, byte b) throws MessageTypeException { - ValueType type = ValueType.valueOf(b); - return new MessageTypeException(String.format("Expected %s, but got %s (%02x)", expected, type.toTypeName(), b)); + MessageFormat format = MessageFormat.valueOf(b); + String typeName; + if (format == MessageFormat.NEVER_USED) { + typeName = "NeverUsed"; + } else { + String name = format.getValueType().name(); + typeName = name.substring(0, 1) + name.substring(1).toLowerCase(); + } + return new MessageTypeException(String.format("Expected %s, but got %s (%02x)", expected, typeName, b)); } - public MessageFormat unpackValue(ValueHolder holder) throws IOException { + public ImmutableValue unpackValue() throws IOException { MessageFormat mf = getNextFormat(); switch(mf.getValueType()) { case NIL: unpackNil(); - holder.setNil(); - break; + return ValueFactory.newNilValue(); case BOOLEAN: - holder.setBoolean(unpackBoolean()); - break; - case INTEGER: { - unpackInteger(holder.getIntegerHolder()); - holder.setToInteger(); - break; - } - case FLOAT: { - unpackFloat(holder.getFloatHolder()); - holder.setToFloat(); - break; + return ValueFactory.newBooleanValue(unpackBoolean()); + case INTEGER: + switch (mf) { + case UINT64: + return ValueFactory.newIntegerValue(unpackBigInteger()); + default: + return ValueFactory.newIntegerValue(unpackLong()); + } + case FLOAT: + return ValueFactory.newFloatValue(unpackDouble()); + case STRING: { + int length = unpackRawStringHeader(); + return ValueFactory.newRawStringValue(readPayload(length)); } - case STRING: - int strLen = unpackRawStringHeader(); - holder.setString(readPayloadAsReference(strLen)); - break; case BINARY: { - int binaryLen = unpackBinaryHeader(); - holder.setBinary(readPayloadAsReference(binaryLen)); - break; + int length = unpackBinaryHeader(); + return ValueFactory.newBinaryValue(readPayload(length)); } - case ARRAY: - holder.prepareArrayCursor(this); - break; - case MAP: - holder.prepareMapCursor(this); - break; - case EXTENDED: + case ARRAY: { + int size = unpackArrayHeader(); + Value[] array = new Value[size]; + for (int i=0; i < size; i++) { + array[i] = unpackValue(); + } + return ValueFactory.newArrayValue(array); + } + case MAP: { + int size = unpackMapHeader(); + Value[] kvs = new Value[size * 2]; + for (int i=0; i < size * 2; i++) { + kvs[i] = unpackValue(); + } + return ValueFactory.newMapValue(kvs); + } + case EXTENDED: { ExtendedTypeHeader extHeader = unpackExtendedTypeHeader(); - holder.setExt(extHeader.getType(), readPayloadAsReference(extHeader.getLength())); - break; + return ValueFactory.newExtendedValue(extHeader.getType(), readPayload(extHeader.getLength())); + } + default: + throw new MessageFormatException("Unknown value type"); } - return mf; } - public Object unpackNil() throws IOException { + public void unpackNil() throws IOException { byte b = consume(); if(b == Code.NIL) { - return null; + return; } throw unexpected("Nil", b); } @@ -832,73 +835,6 @@ public BigInteger unpackBigInteger() throws IOException { throw unexpected("Integer", b); } - - /** - * Unpack an integer, then store the read value to the given holder - * @param holder an integer holder to which the unpacked integer will be set. - * @throws IOException - */ - public void unpackInteger(IntegerHolder holder) throws IOException { - byte b = consume(); - - if(Code.isFixInt(b)) { - holder.setByte(b); - return; - } - - switch(b) { - case Code.INT8: // signed int 8 - holder.setByte(readByte()); - break; - case Code.INT16: - holder.setShort(readShort()); - break; - case Code.INT32: - holder.setInt(readInt()); - break; - case Code.INT64: // signed int 64 - holder.setLong(readLong()); - break; - case Code.UINT8: // unsigned int 8 - byte u8 = readByte(); - if(u8 < 0) { - holder.setShort((short) (u8 & 0xFF)); - } - else { - holder.setByte(u8); - } - break; - case Code.UINT16: // unsigned int 16 - short u16 = readShort(); - if(u16 < 0) { - holder.setInt(u16 & 0xFFFF); - } - else { - holder.setShort(u16); - } - break; - case Code.UINT32: // unsigned int 32 - int u32 = readInt(); - if(u32 < 0) { - holder.setLong((long) (u32 & 0x7fffffff) + 0x80000000L); - } else { - holder.setInt(u32); - } - break; - case Code.UINT64: // unsigned int 64 - long u64 = readLong(); - if(u64 < 0L) { - holder.setBigInteger(BigInteger.valueOf(u64 + Long.MAX_VALUE + 1L).setBit(63)); - } else { - holder.setLong(u64); - } - break; - default: - throw unexpected("Integer", b); - } - } - - public float unpackFloat() throws IOException { byte b = consume(); switch(b) { @@ -925,26 +861,6 @@ public double unpackDouble() throws IOException { throw unexpected("Float", b); } - public void unpackFloat(ValueHolder holder) throws IOException { - unpackFloat(holder.getFloatHolder()); - } - - public void unpackFloat(FloatHolder holder) throws IOException { - byte b = consume(); - switch(b) { - case Code.FLOAT32: // float - float fv = readFloat(); - holder.setFloat(fv); - break; - case Code.FLOAT64: // double - double dv = readDouble(); - holder.setDouble(dv); - break; - default: - throw unexpected("Float", b); - } - } - private final static String EMPTY_STRING = ""; @@ -1053,29 +969,29 @@ public ExtendedTypeHeader unpackExtendedTypeHeader() throws IOException { byte b = consume(); switch(b) { case Code.FIXEXT1: - return new ExtendedTypeHeader(1, readByte()); + return new ExtendedTypeHeader(readByte(), 1); case Code.FIXEXT2: - return new ExtendedTypeHeader(2, readByte()); + return new ExtendedTypeHeader(readByte(), 2); case Code.FIXEXT4: - return new ExtendedTypeHeader(4, readByte()); + return new ExtendedTypeHeader(readByte(), 4); case Code.FIXEXT8: - return new ExtendedTypeHeader(8, readByte()); + return new ExtendedTypeHeader(readByte(), 8); case Code.FIXEXT16: - return new ExtendedTypeHeader(16, readByte()); + return new ExtendedTypeHeader(readByte(), 16); case Code.EXT8: { - int len = readNextLength8(); - int t = readByte(); - return new ExtendedTypeHeader(len, t); + int length = readNextLength8(); + byte type = readByte(); + return new ExtendedTypeHeader(type, length); } case Code.EXT16: { - int len = readNextLength16(); - int t = readByte(); - return new ExtendedTypeHeader(len, t); + int length = readNextLength16(); + byte type = readByte(); + return new ExtendedTypeHeader(type, length); } case Code.EXT32: { - int len = readNextLength32(); - int t = readByte(); - return new ExtendedTypeHeader(len, t); + int length = readNextLength32(); + byte type = readByte(); + return new ExtendedTypeHeader(type, length); } } @@ -1161,6 +1077,12 @@ public void readPayload(byte[] dst) throws IOException { readPayload(dst, 0, dst.length); } + public byte[] readPayload(int length) throws IOException { + byte[] newArray = new byte[length]; + readPayload(newArray); + return newArray; + } + /** * Read up to len bytes of data into the destination array * diff --git a/msgpack-core/src/main/java/org/msgpack/core/example/MessagePackExample.java b/msgpack-core/src/main/java/org/msgpack/core/example/MessagePackExample.java index 2720ab3f9..60988c7e4 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/example/MessagePackExample.java +++ b/msgpack-core/src/main/java/org/msgpack/core/example/MessagePackExample.java @@ -18,10 +18,8 @@ import org.msgpack.core.*; import org.msgpack.core.buffer.MessageBuffer; import org.msgpack.value.*; -import org.msgpack.value.holder.FloatHolder; -import org.msgpack.value.holder.IntegerHolder; -import org.msgpack.value.holder.ValueHolder; +import java.math.BigInteger; import java.io.*; import java.nio.ByteBuffer; import java.nio.charset.CodingErrorAction; @@ -174,54 +172,55 @@ public static void readAndWriteFile() throws IOException { // Alternatively you can use ValueHolder to extract a value of any type // NOTE: Value interface is in a preliminary state, so the following code might change in future releases - ValueHolder v = new ValueHolder(); - format = unpacker.unpackValue(v); - switch(format.getValueType()) { + Value v = unpacker.unpackValue(); + switch(v.getValueType()) { case NIL: - Value nil = v.get(); - nil.isNil(); // true + v.isNilValue(); // true System.out.println("read nil"); break; case BOOLEAN: - boolean b = v.get().asBoolean().toBoolean(); + boolean b = v.asBooleanValue().getBoolean(); System.out.println("read boolean: " + b); break; case INTEGER: - IntegerHolder ih = v.getIntegerHolder(); - if(ih.isValidInt()) { // int range check [-2^31-1, 2^31-1] - int i = ih.asInt(); + IntegerValue iv = v.asIntegerValue(); + if(iv.isInIntRange()) { + int i = iv.intValue(); System.out.println("read int: " + i); } - else { - long l = ih.asLong(); + else if (iv.isInLongRange()) { + long l = iv.longValue(); System.out.println("read long: " + l); } + else { + BigInteger i = iv.bigIntegerValue(); + System.out.println("read long: " + i); + } break; case FLOAT: - FloatHolder fh = v.getFloatHolder(); - float f = fh.toFloat(); // read as float - double d = fh.toDouble(); // read as double + FloatValue fv = v.asFloatValue(); + float f = fv.floatValue(); // use as float + double d = fv.doubleValue(); // use as double System.out.println("read float: " + d); break; case STRING: - String s = v.get().asString().toString(); + String s = v.asStringValue().getString(); System.out.println("read string: " + s); break; case BINARY: - // Message buffer is an efficient byte buffer - MessageBuffer mb = v.get().asBinary().toMessageBuffer(); - System.out.println("read binary: " + mb.toHexString(0, mb.size())); + byte[] mb = v.asBinaryValue().getByteArray(); + System.out.println("read binary: size=" + mb.length); break; case ARRAY: - ArrayValue arr = v.get().asArrayValue(); - for(ValueRef a : arr) { - System.out.println("read array element: " + a); + ArrayValue a = v.asArrayValue(); + for(Value e : a) { + System.out.println("read array element: " + e); } break; case EXTENDED: - ExtendedValue ev = v.get().asExtended(); - int extType = ev.getExtType(); - byte[] extValue = ev.toByteArray(); + ExtendedValue ev = v.asExtendedValue(); + byte extType = ev.getType(); + byte[] extValue = ev.getData(); break; } } diff --git a/msgpack-core/src/main/java/org/msgpack/value/AbstractValueVisitor.java b/msgpack-core/src/main/java/org/msgpack/value/AbstractValueVisitor.java deleted file mode 100644 index 06697d3c5..000000000 --- a/msgpack-core/src/main/java/org/msgpack/value/AbstractValueVisitor.java +++ /dev/null @@ -1,48 +0,0 @@ -package org.msgpack.value; - -/** - * Empty visitor that does nothing - */ -public class AbstractValueVisitor implements ValueVisitor { - - @Override - public void visitNil() { - - } - @Override - public void visitBoolean(boolean v) { - - } - @Override - public void visitInteger(IntegerValue v) { - - } - @Override - public void visitFloat(FloatValue v) { - - } - @Override - public void visitBinary(BinaryValue v) { - - } - @Override - public void visitString(StringValue v) { - - } - @Override - public void visitArray(ArrayValue v) { - - } - @Override - public void visitMap(MapValue v) { - - } - @Override - public void visitExtended(ExtendedValue v) { - - } - @Override - public void onError(Exception e) { - - } -} diff --git a/msgpack-core/src/main/java/org/msgpack/value/ArrayCursor.java b/msgpack-core/src/main/java/org/msgpack/value/ArrayCursor.java deleted file mode 100644 index d491ba9c8..000000000 --- a/msgpack-core/src/main/java/org/msgpack/value/ArrayCursor.java +++ /dev/null @@ -1,24 +0,0 @@ -package org.msgpack.value; - -import java.util.Iterator; - -/** - * Created on 6/16/14. - */ -public interface ArrayCursor extends ValueRef, Iterable { - public int size(); - - public boolean hasNext(); - public ValueRef next(); - public void skip(); - - /** - * Skips all of the remaining values - */ - public void skipAll(); - - public Iterator iterator(); - - public ArrayValue toValue(); - -} diff --git a/msgpack-core/src/main/java/org/msgpack/value/ArrayValue.java b/msgpack-core/src/main/java/org/msgpack/value/ArrayValue.java index 1c15df7c0..a92805a17 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/ArrayValue.java +++ b/msgpack-core/src/main/java/org/msgpack/value/ArrayValue.java @@ -1,20 +1,59 @@ +// +// MessagePack for Java +// +// 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.value; +import java.util.List; +import java.util.Iterator; + /** - * Value interface for array type data. + * The interface {@code ArrayValue} represents MessagePack's Array type. * - * Implementation note: We do not implement List interface here, because - * we cannot reuse AbstractList and AbstractValue implementations simultaneously since - * Java does not support mixin of classes. Instead, it provides {@link #iterator} or - * {@link #toValueArray()} methods to traverse the array contents. + * MessagePack's Array type can represent sequence of values. */ -public interface ArrayValue extends Value, ArrayCursor { +public interface ArrayValue extends Value, Iterable { + @Override + public ImmutableArrayValue immutableValue(); - public Value[] toValueArray(); + /** + * Returns number of elements in this array. + */ + public int size(); + /** + * Returns the element at the specified position in this array. + * + * @throws IndexOutOfBoundsException + * If the index is out of range + * (index < 0 || index >= size()) + */ public Value get(int index); - public Value apply(int index); - public ArrayValue toValue(); + /** + * Returns the element at the specified position in this array. + * This method returns an ImmutableNilValue if the index is out of range. + */ + public Value getOrNilValue(int index); + + /** + * Returns an iterator over elements. + */ + public Iterator iterator(); + /** + * Returns the value as {@code List}. + */ + public List list(); } diff --git a/msgpack-core/src/main/java/org/msgpack/value/BinaryValue.java b/msgpack-core/src/main/java/org/msgpack/value/BinaryValue.java index 808de6f9b..8c9955694 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/BinaryValue.java +++ b/msgpack-core/src/main/java/org/msgpack/value/BinaryValue.java @@ -1,8 +1,28 @@ +// +// MessagePack for Java +// +// 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.value; /** -* Created on 5/30/14. -*/ + * The interface {@code BinaryValue} represents MessagePack's Binary type. + * + * MessagePack's Binary type can represent a byte array at most 264-1 bytes. + * + * @see org.msgpack.value.RawValue + */ public interface BinaryValue extends RawValue { - BinaryValue toValue(); + @Override + public ImmutableBinaryValue immutableValue(); } diff --git a/msgpack-core/src/main/java/org/msgpack/value/BooleanValue.java b/msgpack-core/src/main/java/org/msgpack/value/BooleanValue.java index 2d517469e..20d731a4b 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/BooleanValue.java +++ b/msgpack-core/src/main/java/org/msgpack/value/BooleanValue.java @@ -1,9 +1,31 @@ +// +// MessagePack for Java +// +// 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.value; /** -* Created on 5/30/14. -*/ + * The interface {@code BooleanValue} represents MessagePack's Boolean type. + * + * MessagePack's Boolean type can represent {@code true} or {@code false}. + */ public interface BooleanValue extends Value { - public boolean toBoolean(); - public BooleanValue toValue(); + @Override + public ImmutableBooleanValue immutableValue(); + + /** + * Returns the value as a {@code boolean}. + */ + public boolean getBoolean(); } diff --git a/msgpack-core/src/main/java/org/msgpack/value/Cursor.java b/msgpack-core/src/main/java/org/msgpack/value/Cursor.java deleted file mode 100644 index 09fa50e5f..000000000 --- a/msgpack-core/src/main/java/org/msgpack/value/Cursor.java +++ /dev/null @@ -1,66 +0,0 @@ -package org.msgpack.value; - - -import java.io.Closeable; -import java.util.Iterator; - -/** - * Cursor for traversing a stream of message-packed values - */ -public interface Cursor extends Iterator, Closeable { - - /** - * Tests whether there is a next element. - * @return true if there is a next element, or false if there is no more element. - */ - public boolean hasNext(); - - /** - * Returns a reference to the value, then proceeds the cursor. - * The returned reference is valid until {@link #hasNext()} is called. - * @return - */ - public ValueRef nextRef(); - - /** - * Returns the materialized value of the referenced value, then proceeds the cursor. - * @return - */ - public Value next(); - - /** - * Skip reading the current value. - */ - public void skip(); - - /** - * Returns the number of the read bytes - * @return the number of the read bytes - */ - public long getReadBytes(); - - public static interface Function { - public Out apply(Value input) throws Exception; - } - - /** - * Applies a function f to the referenced value, then returns the result of the function. - * @param f a function that receives the referenced value. - * @param the result type of the function - * @return the result of the function - */ - public Out apply(Function f); - - public boolean isNilValue(); - public boolean isBooleanValue(); - public boolean isNumberValue(); - public boolean isIntegerValue(); - public boolean isFloatValue(); - public boolean isBinaryValue(); - public boolean isStringValue(); - public boolean isRawValue(); - public boolean isArrayValue(); - public boolean isMapValue(); - public boolean isExtendedValue(); - -} diff --git a/msgpack-core/src/main/java/org/msgpack/value/ExtendedValue.java b/msgpack-core/src/main/java/org/msgpack/value/ExtendedValue.java index 9d4b47a16..220e5737b 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/ExtendedValue.java +++ b/msgpack-core/src/main/java/org/msgpack/value/ExtendedValue.java @@ -1,9 +1,32 @@ +// +// MessagePack for Java +// +// 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.value; /** -* Created on 5/30/14. -*/ -public interface ExtendedValue extends RawValue { - public int getExtType(); - public ExtendedValue toValue(); + * The interface {@code ExtendedValue} represents MessagePack's Extended type. + * + * MessagePack's Extended type can represent represents a tuple of type information and a byte array where type information is an integer whose meaning is defined by applications. + * + * As the type information, applications can use 0 to 127 as the application-specific types. -1 to -128 is reserved for MessagePack's future extension. + */ +public interface ExtendedValue extends Value { + @Override + public ImmutableExtendedValue immutableValue(); + + public byte getType(); + + public byte[] getData(); } diff --git a/msgpack-core/src/main/java/org/msgpack/value/FloatValue.java b/msgpack-core/src/main/java/org/msgpack/value/FloatValue.java index 3e5dda745..019ee2c4a 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/FloatValue.java +++ b/msgpack-core/src/main/java/org/msgpack/value/FloatValue.java @@ -1,8 +1,28 @@ +// +// MessagePack for Java +// +// 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.value; /** -* Created on 5/30/14. -*/ + * The interface {@code FloatValue} represents MessagePack's Float type. + * + * MessagePack's Float type can represent IEEE 754 double precision floating point numbers including NaN and infinity. This is same with Java's {@code double} type. + * + * @see org.msgpack.value.NumberValue + */ public interface FloatValue extends NumberValue { - FloatValue toValue(); + @Override + public ImmutableFloatValue immutableValue(); } diff --git a/msgpack-core/src/main/java/org/msgpack/value/ImmutableArrayValue.java b/msgpack-core/src/main/java/org/msgpack/value/ImmutableArrayValue.java new file mode 100644 index 000000000..f06c89e60 --- /dev/null +++ b/msgpack-core/src/main/java/org/msgpack/value/ImmutableArrayValue.java @@ -0,0 +1,34 @@ +// +// MessagePack for Java +// +// 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.value; + +import java.util.List; +import java.util.Iterator; + + +public interface ImmutableArrayValue extends ArrayValue, ImmutableValue { + /** + * Returns an iterator over elements. + * Returned Iterator does not support {@code remove()} method since the value is immutable. + */ + public Iterator iterator(); + + /** + * Returns the value as {@code List}. + * Returned List is immutable. It does not support {@code put()}, {@code clear()}, or other methods that modify the value. + */ + public List list(); +} diff --git a/msgpack-core/src/main/java/org/msgpack/value/ValueVisitor.java b/msgpack-core/src/main/java/org/msgpack/value/ImmutableBinaryValue.java similarity index 54% rename from msgpack-core/src/main/java/org/msgpack/value/ValueVisitor.java rename to msgpack-core/src/main/java/org/msgpack/value/ImmutableBinaryValue.java index 22436d30a..ce52bfc33 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/ValueVisitor.java +++ b/msgpack-core/src/main/java/org/msgpack/value/ImmutableBinaryValue.java @@ -15,20 +15,5 @@ // package org.msgpack.value; -/** - * Interface for implementing the visitor pattern on message-packed values - */ -public interface ValueVisitor { - - public void visitNil(); - public void visitBoolean(boolean v); - public void visitInteger(IntegerValue v); - public void visitFloat(FloatValue v); - public void visitBinary(BinaryValue v); - public void visitString(StringValue v); - public void visitArray(ArrayValue v); - public void visitMap(MapValue v); - public void visitExtended(ExtendedValue v); - - public void onError(Exception e); +public interface ImmutableBinaryValue extends BinaryValue, ImmutableRawValue { } diff --git a/msgpack-core/src/main/java/org/msgpack/value/ImmutableBooleanValue.java b/msgpack-core/src/main/java/org/msgpack/value/ImmutableBooleanValue.java new file mode 100644 index 000000000..23b7dbc0b --- /dev/null +++ b/msgpack-core/src/main/java/org/msgpack/value/ImmutableBooleanValue.java @@ -0,0 +1,19 @@ +// +// MessagePack for Java +// +// 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.value; + +public interface ImmutableBooleanValue extends BooleanValue, ImmutableValue { +} diff --git a/msgpack-core/src/main/java/org/msgpack/value/ImmutableExtendedValue.java b/msgpack-core/src/main/java/org/msgpack/value/ImmutableExtendedValue.java new file mode 100644 index 000000000..4d77577d4 --- /dev/null +++ b/msgpack-core/src/main/java/org/msgpack/value/ImmutableExtendedValue.java @@ -0,0 +1,19 @@ +// +// MessagePack for Java +// +// 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.value; + +public interface ImmutableExtendedValue extends ExtendedValue, ImmutableValue { +} diff --git a/msgpack-core/src/main/java/org/msgpack/value/ImmutableFloatValue.java b/msgpack-core/src/main/java/org/msgpack/value/ImmutableFloatValue.java new file mode 100644 index 000000000..bfa6cf114 --- /dev/null +++ b/msgpack-core/src/main/java/org/msgpack/value/ImmutableFloatValue.java @@ -0,0 +1,19 @@ +// +// MessagePack for Java +// +// 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.value; + +public interface ImmutableFloatValue extends FloatValue, ImmutableNumberValue { +} diff --git a/msgpack-core/src/main/java/org/msgpack/value/ImmutableIntegerValue.java b/msgpack-core/src/main/java/org/msgpack/value/ImmutableIntegerValue.java new file mode 100644 index 000000000..b2ab29938 --- /dev/null +++ b/msgpack-core/src/main/java/org/msgpack/value/ImmutableIntegerValue.java @@ -0,0 +1,19 @@ +// +// MessagePack for Java +// +// 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.value; + +public interface ImmutableIntegerValue extends IntegerValue, ImmutableNumberValue { +} diff --git a/msgpack-core/src/main/java/org/msgpack/value/ImmutableMapValue.java b/msgpack-core/src/main/java/org/msgpack/value/ImmutableMapValue.java new file mode 100644 index 000000000..f612f5758 --- /dev/null +++ b/msgpack-core/src/main/java/org/msgpack/value/ImmutableMapValue.java @@ -0,0 +1,19 @@ +// +// MessagePack for Java +// +// 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.value; + +public interface ImmutableMapValue extends MapValue, ImmutableValue { +} diff --git a/msgpack-core/src/main/java/org/msgpack/value/ImmutableNilValue.java b/msgpack-core/src/main/java/org/msgpack/value/ImmutableNilValue.java new file mode 100644 index 000000000..e4fbf48d4 --- /dev/null +++ b/msgpack-core/src/main/java/org/msgpack/value/ImmutableNilValue.java @@ -0,0 +1,19 @@ +// +// MessagePack for Java +// +// 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.value; + +public interface ImmutableNilValue extends NilValue, ImmutableValue { +} diff --git a/msgpack-core/src/main/java/org/msgpack/value/ImmutableNumberValue.java b/msgpack-core/src/main/java/org/msgpack/value/ImmutableNumberValue.java new file mode 100644 index 000000000..f264d58da --- /dev/null +++ b/msgpack-core/src/main/java/org/msgpack/value/ImmutableNumberValue.java @@ -0,0 +1,19 @@ +// +// MessagePack for Java +// +// 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.value; + +public interface ImmutableNumberValue extends NumberValue, ImmutableValue { +} diff --git a/msgpack-core/src/main/java/org/msgpack/value/ImmutableRawValue.java b/msgpack-core/src/main/java/org/msgpack/value/ImmutableRawValue.java new file mode 100644 index 000000000..8fa691fb6 --- /dev/null +++ b/msgpack-core/src/main/java/org/msgpack/value/ImmutableRawValue.java @@ -0,0 +1,19 @@ +// +// MessagePack for Java +// +// 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.value; + +public interface ImmutableRawValue extends RawValue, ImmutableValue { +} diff --git a/msgpack-core/src/main/java/org/msgpack/value/ImmutableStringValue.java b/msgpack-core/src/main/java/org/msgpack/value/ImmutableStringValue.java new file mode 100644 index 000000000..10a3ee217 --- /dev/null +++ b/msgpack-core/src/main/java/org/msgpack/value/ImmutableStringValue.java @@ -0,0 +1,19 @@ +// +// MessagePack for Java +// +// 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.value; + +public interface ImmutableStringValue extends StringValue, ImmutableRawValue { +} diff --git a/msgpack-core/src/main/java/org/msgpack/value/ImmutableValue.java b/msgpack-core/src/main/java/org/msgpack/value/ImmutableValue.java new file mode 100644 index 000000000..88d3bf260 --- /dev/null +++ b/msgpack-core/src/main/java/org/msgpack/value/ImmutableValue.java @@ -0,0 +1,47 @@ +// +// MessagePack for Java +// +// 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.value; + +import java.io.Serializable; + +public interface ImmutableValue extends Value { + @Override + public ImmutableNilValue asNilValue(); + + @Override + public ImmutableBooleanValue asBooleanValue(); + + @Override + public ImmutableIntegerValue asIntegerValue(); + + @Override + public ImmutableFloatValue asFloatValue(); + + @Override + public ImmutableArrayValue asArrayValue(); + + @Override + public ImmutableMapValue asMapValue(); + + @Override + public ImmutableRawValue asRawValue(); + + @Override + public ImmutableBinaryValue asBinaryValue(); + + @Override + public ImmutableStringValue asStringValue(); +} diff --git a/msgpack-core/src/main/java/org/msgpack/value/IntegerValue.java b/msgpack-core/src/main/java/org/msgpack/value/IntegerValue.java index 4299b42ad..267b7e127 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/IntegerValue.java +++ b/msgpack-core/src/main/java/org/msgpack/value/IntegerValue.java @@ -1,8 +1,85 @@ +// +// MessagePack for Java +// +// 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.value; +import java.math.BigInteger; + /** -* Created on 5/30/14. -*/ + * The interface {@code IntegerValue} represents MessagePack's Integer type. + * + * MessagePack's Integer type can represent from -263 to 264-1. + */ public interface IntegerValue extends NumberValue { - IntegerValue toValue(); + @Override + public ImmutableIntegerValue immutableValue(); + + /** + * Returns true if the value is in the range of [-27 to 27-1]. + */ + public boolean isInByteRange(); + + /** + * Returns true if the value is in the range of [-215 to 215-1] + */ + public boolean isInShortRange(); + + /** + * Returns true if the value is in the range of [-231 to 231-1] + */ + public boolean isInIntRange(); + + /** + * Returns true if the value is in the range of [-263 to 263-1] + */ + public boolean isInLongRange(); + + /** + * Returns the value as a {@code byte}, otherwise throws an exception. + * + * @throws MessageIntegerOverflowException + * If the value does not fit in the range of {@code byte} type. + */ + public byte getByte(); + + /** + * Returns the value as a {@code short}, otherwise throws an exception. + * + * @throws MessageIntegerOverflowException + * If the value does not fit in the range of {@code short} type. + */ + public short getShort(); + + /** + * Returns the value as an {@code int}, otherwise throws an exception. + * + * @throws MessageIntegerOverflowException + * If the value does not fit in the range of {@code int} type. + */ + public int getInt(); + + /** + * Returns the value as a {@code long}, otherwise throws an exception. + * + * @throws MessageIntegerOverflowException + * If the value does not fit in the range of {@code long} type. + */ + public long getLong(); + + /** + * Returns the value as a {@code BigInteger}. + */ + public BigInteger getBigInteger(); } diff --git a/msgpack-core/src/main/java/org/msgpack/value/MapCursor.java b/msgpack-core/src/main/java/org/msgpack/value/MapCursor.java deleted file mode 100644 index 17ac2fec2..000000000 --- a/msgpack-core/src/main/java/org/msgpack/value/MapCursor.java +++ /dev/null @@ -1,32 +0,0 @@ -package org.msgpack.value; - -/** - * Cursor for traversing map value entries. This cursor reports a sequence of key and value pairs. - */ -public interface MapCursor extends ValueRef { - public int size(); - - /** - * Test whether this cursor can point to a next key or value. - * @return - */ - public boolean hasNext(); - - /** - * Retrieves a reference to the next key or value. - * @return - */ - public ValueRef nextKeyOrValue(); - - /** - * Skips a next key or value - */ - public void skipKeyOrValue(); - - /** - * Skips all of the remaining keys and values. - */ - public void skipAll(); - - MapValue toValue(); -} diff --git a/msgpack-core/src/main/java/org/msgpack/value/MapValue.java b/msgpack-core/src/main/java/org/msgpack/value/MapValue.java index ea67fdad6..db5fe589a 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/MapValue.java +++ b/msgpack-core/src/main/java/org/msgpack/value/MapValue.java @@ -1,13 +1,55 @@ +// +// MessagePack for Java +// +// 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.value; import java.util.Map; +import java.util.Set; +import java.util.Collection; /** -* Created on 5/30/14. -*/ -public interface MapValue extends Value, MapCursor { - public Value[] toKeyValueSeq(); - public Map toMap(); + * The interface {@code ArrayValue} represents MessagePack's Map type. + * + * MessagePack's Map type can represent sequence of key-value pairs. + */ +public interface MapValue extends Value { + @Override + public ImmutableMapValue immutableValue(); - public MapValue toValue(); + /** + * Returns number of key-value pairs in this array. + */ + public int size(); + + public Set keySet(); + + public Set> entrySet(); + + public Collection values(); + + /** + * Returns the value as {@code Map}. + */ + public Map map(); + + /** + * Returns the key-value pairs as an array of {@code Value}. + * + * Odd elements are keys. Next element of an odd element is a value corresponding to the key. + * + * For example, if this value represents {"k1": "v1", "k2": "v2"}, this method returns ["k1", "v1", "k2", "v2"]. + */ + public Value[] getKeyValueArray(); } diff --git a/msgpack-core/src/main/java/org/msgpack/value/NilValue.java b/msgpack-core/src/main/java/org/msgpack/value/NilValue.java index 4c8c39beb..ea627c46d 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/NilValue.java +++ b/msgpack-core/src/main/java/org/msgpack/value/NilValue.java @@ -1,8 +1,24 @@ +// +// MessagePack for Java +// +// 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.value; /** - * References to values + * The interface {@code NilValue} represents MessagePack's Nil type. */ public interface NilValue extends Value { - NilValue toValue(); + @Override + public ImmutableNilValue immutableValue(); } diff --git a/msgpack-core/src/main/java/org/msgpack/value/NumberValue.java b/msgpack-core/src/main/java/org/msgpack/value/NumberValue.java index 38952fcc5..f472ad414 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/NumberValue.java +++ b/msgpack-core/src/main/java/org/msgpack/value/NumberValue.java @@ -1,106 +1,66 @@ +// +// MessagePack for Java +// +// 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.value; -import org.msgpack.core.MessageOverflowException; - import java.math.BigInteger; /** -* Created on 5/30/14. -*/ + * The interface {@code NumberValue} is the interface of {@code IntegerValue} and {@code FloatValue}. + * + * @see org.msgpack.value.IntegerValue + * @see org.msgpack.value.FloatValue + */ public interface NumberValue extends Value { + @Override + public ImmutableNumberValue immutableValue(); /** - * Check whether this value is a valid byte value. - * @return true if this value has no fractional part, and is within the range of {@link Byte#MIN_VALUE} and {@link Byte#MAX_VALUE}; otherwise returns false - */ - public boolean isValidByte(); - - /** - * Check whether this value is a valid short value. - * @return true if this value has no fractional part, and is within the range of {@link Short#MIN_VALUE} and {@link Short#MAX_VALUE}; otherwise returns false - */ - public boolean isValidShort(); - - /** - * Check whether this value is a valid integer value. - * @return true if this value has no fractional part, and is within the range of {@link Integer#MIN_VALUE} and {@link Integer#MAX_VALUE}; otherwise returns false - */ - public boolean isValidInt(); - - /** - * Check whether this value is a valid long value. - * @return true if this value has no fractional part, and is within the range of {@link Long#MIN_VALUE} and {@link Long#MAX_VALUE}; otherwise returns false - */ - public boolean isValidLong(); - - /** - * Returns true if this number has no decimal component - * @return true if this number has no decimal component, otherwise false (float, double values); + * Returns the value as a {@code byte}, which may involve rounding or truncation. */ - public boolean isWhole(); + public byte byteValue(); /** - * Convert this value into a byte value. If this value is not within the range of Byte value, it will truncate or round the value. + * Returns the value as a {@code short}, which may involve rounding or truncation. */ - public byte toByte(); - /** - * Convert this value into a short value. If this value is not within the range of Short value, it will truncate or round the value. - */ - public short toShort(); - /** - * Convert this value into an int value. If this value is not within the range of Int value, it will truncate or round the value. - */ - public int toInt(); - /** - * Convert this value into a long value. If this value is not within the range of Long value, it will truncate or round the value. - */ - public long toLong(); - /** - * Convert this value into a BigInteger - */ - public BigInteger toBigInteger(); - /** - * Convert this value into a float value - */ - public float toFloat(); - /** - * Convert this value into a double value - */ - public double toDouble(); + public short shortValue(); /** - * Convert this value into a byte value. If this value is not within the range of Byte value, it throws an exception. - * @return - * @throws org.msgpack.core.MessageOverflowException when the value is not within the range of {@link Byte#MIN_VALUE} and {@link Byte#MAX_VALUE}; + * Returns the value as an {@code int}, which may involve rounding or truncation. */ - public byte asByte() throws MessageOverflowException; + public int intValue(); /** - * Convert this value into a short value. If this value is not within the range of Short value, it throws an exception. - * @return - * @throws org.msgpack.core.MessageOverflowException when the value is not within the range of {@link Short#MIN_VALUE} and {@link Short#MAX_VALUE} + * Returns the value as a {@code long}, which may involve rounding or truncation. */ - public short asShort() throws MessageOverflowException; + public long longValue(); /** - * Convert this value into an int value. If this value is not within the range of Integer value, it throws an exception. - * @return - * @throws org.msgpack.core.MessageOverflowException when the value is not within the range of {@link Integer#MIN_VALUE} and {@link Integer#MAX_VALUE} + * Returns the value as a {@code BigInteger}, which may involve rounding or truncation. + * + * Rounding could happen if type of this value is float or double. */ - public int asInt() throws MessageOverflowException; + public BigInteger bigIntegerValue(); /** - * Convert this value into a long value. If this value is not within the range of Long value, it throws an exception. - * @return - * @throws org.msgpack.core.MessageOverflowException when the value is not within the range of {@link Long#MIN_VALUE} and {@link Long#MAX_VALUE} + * Returns the value as a {@code float}, which may involve rounding or truncation. */ - public long asLong() throws MessageOverflowException; + public float floatValue(); /** - * Convert this value into a BigInteger value. - * @return - * @throws org.msgpack.core.MessageOverflowException + * Returns the value as a {@code double}, which may involve rounding or truncation. */ - public BigInteger asBigInteger() throws MessageOverflowException; - + public double doubleValue(); } diff --git a/msgpack-core/src/main/java/org/msgpack/value/RawValue.java b/msgpack-core/src/main/java/org/msgpack/value/RawValue.java index 8db9e34b1..25688fcd4 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/RawValue.java +++ b/msgpack-core/src/main/java/org/msgpack/value/RawValue.java @@ -1,19 +1,63 @@ +// +// MessagePack for Java +// +// 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.value; -import org.msgpack.core.buffer.MessageBuffer; - import java.nio.ByteBuffer; /** - * Base type of StringValue, BinaryValue and ExtendedValue + * The interface {@code RawValue} represents MessagePack's Raw type, which means Binary or String type. + * + * MessagePack's Raw type can represent a byte array at most 264-1 bytes. + * + * @see org.msgpack.value.StringValue + * @see org.msgpack.value.BinaryValue */ public interface RawValue extends Value { - public byte[] toByteArray(); - public ByteBuffer toByteBuffer(); - public MessageBuffer toMessageBuffer(); - @Override - public String toString(); + public ImmutableRawValue immutableValue(); + + /** + * Returns the value as {@code byte[]}. + * + * This method copies the byte array. + */ + public byte[] getByteArray(); + + /** + * Returns the value as {@code ByteBuffer}. + * + * Returned ByteBuffer is read-only. See {@code#asReadOnlyBuffer()}. + * This method doesn't copy the byte array as much as possible. + */ + public ByteBuffer getByteBuffer(); + + /** + * Returns the value as {@code String}. + * + * This method throws an exception if the value includes invalid UTF-8 byte sequence. + * + * @throws MessageStringCodingException + * If this value includes invalid UTF-8 byte sequence. + */ + public String getString(); - public RawValue toValue(); + /** + * Returns the value as {@code String}. + * + * This method replaces an invalid UTF-8 byte sequence with U+FFFD replacement character. + */ + public String stringValue(); } diff --git a/msgpack-core/src/main/java/org/msgpack/value/StringValue.java b/msgpack-core/src/main/java/org/msgpack/value/StringValue.java index 35315f14d..36f1943f7 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/StringValue.java +++ b/msgpack-core/src/main/java/org/msgpack/value/StringValue.java @@ -1,8 +1,30 @@ +// +// MessagePack for Java +// +// 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.value; /** - * Created on 5/30/14. + * The interface {@code StringValue} represents MessagePack's String type. + * + * MessagePack's String type can represent a UTF-8 string at most 264-1 bytes. + * + * Note that the value could include invalid byte sequences. {@code getString()} method throws {@code MessageTypeStringCodingException} if the value includes invalid byte sequence. {@code stringValue()} method replaces an invalid byte sequence with U+FFFD replacement character. + * + * @see org.msgpack.value.RawValue */ public interface StringValue extends RawValue { - public StringValue toValue(); + @Override + public ImmutableStringValue immutableValue(); } diff --git a/msgpack-core/src/main/java/org/msgpack/value/Value.java b/msgpack-core/src/main/java/org/msgpack/value/Value.java index 0cf02453c..b8926dfa9 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/Value.java +++ b/msgpack-core/src/main/java/org/msgpack/value/Value.java @@ -15,15 +15,239 @@ // package org.msgpack.value; +import org.msgpack.core.MessagePacker; + +import java.io.IOException; -import org.msgpack.core.*; /** - * Value is a holder of a message-packed value. + * Value is an implementation of MessagePack type system. */ -public interface Value extends ValueRef { +public interface Value { + /** + * Returns type of this value. + * + * Note that you can't use instanceof to check type of a value because type of a mutable value is variable. + */ + public ValueType getValueType(); + + /** + * Returns immutable copy of this value. + * + * This method simply returns this without copying the value if this value is already immutable. + */ + public ImmutableValue immutableValue(); + + /** + * Returns true if type of this value is Nil. + * + * If this method returns true, {@code asNilValue} never throws exceptions. + * Note that you can't use instanceof or cast ((NilValue) thisValue) to check type of a value because type of a mutable value is variable. + */ + public boolean isNilValue(); + + /** + * Returns true if type of this value is Boolean. + * + * If this method returns true, {@code asBooleanValue} never throws exceptions. + * Note that you can't use instanceof or cast ((BooleanValue) thisValue) to check type of a value because type of a mutable value is variable. + */ + public boolean isBooleanValue(); + + /** + * Returns true if type of this value is Integer or Float. + * + * If this method returns true, {@code asNumberValue} never throws exceptions. + * Note that you can't use instanceof or cast ((NumberValue) thisValue) to check type of a value because type of a mutable value is variable. + */ + public boolean isNumberValue(); + + /** + * Returns true if type of this value is Integer. + * + * If this method returns true, {@code asIntegerValue} never throws exceptions. + * Note that you can't use instanceof or cast ((IntegerValue) thisValue) to check type of a value because type of a mutable value is variable. + */ + public boolean isIntegerValue(); + + /** + * Returns true if type of this value is Float. + * + * If this method returns true, {@code asFloatValue} never throws exceptions. + * Note that you can't use instanceof or cast ((FloatValue) thisValue) to check type of a value because type of a mutable value is variable. + */ + public boolean isFloatValue(); + + /** + * Returns true if type of this value is String or Binary. + * + * If this method returns true, {@code asRawValue} never throws exceptions. + * Note that you can't use instanceof or cast ((RawValue) thisValue) to check type of a value because type of a mutable value is variable. + */ + public boolean isRawValue(); + + /** + * Returns true if type of this value is Binary. + * + * If this method returns true, {@code asBinaryValue} never throws exceptions. + * Note that you can't use instanceof or cast ((BinaryValue) thisValue) to check type of a value because type of a mutable value is variable. + */ + public boolean isBinaryValue(); + + /** + * Returns true if type of this value is String. + * + * If this method returns true, {@code asStringValue} never throws exceptions. + * Note that you can't use instanceof or cast ((StringValue) thisValue) to check type of a value because type of a mutable value is variable. + */ + public boolean isStringValue(); + + /** + * Returns true if type of this value is Array. + * + * If this method returns true, {@code asArrayValue} never throws exceptions. + * Note that you can't use instanceof or cast ((ArrayValue) thisValue) to check type of a value because type of a mutable value is variable. + */ + public boolean isArrayValue(); + + /** + * Returns true if type of this value is Map. + * + * If this method returns true, {@code asMapValue} never throws exceptions. + * Note that you can't use instanceof or cast ((MapValue) thisValue) to check type of a value because type of a mutable value is variable. + */ + public boolean isMapValue(); + + /** + * Returns true if type of this an Extended. + * + * If this method returns true, {@code asExtendedValue} never throws exceptions. + * Note that you can't use instanceof or cast ((ExtendedValue) thisValue) to check type of a value because type of a mutable value is variable. + */ + public boolean isExtendedValue(); + + /** + * Returns the value as {@code NilValue}. Otherwise throws {@code MessageTypeCastException}. + * + * Note that you can't use instanceof or cast ((NilValue) thisValue) to check type of a value because type of a mutable value is variable. + * + * @throws MessageTypeCastException + * If type of this value is not Nil. + */ + public NilValue asNilValue(); + + /** + * Returns the value as {@code BooleanValue}. Otherwise throws {@code MessageTypeCastException}. + * + * Note that you can't use instanceof or cast ((BooleanValue) thisValue) to check type of a value because type of a mutable value is variable. + * + * @throws MessageTypeCastException + * If type of this value is not Boolean. + */ + public BooleanValue asBooleanValue(); + + /** + * Returns the value as {@code NumberValue}. Otherwise throws {@code MessageTypeCastException}. + * + * Note that you can't use instanceof or cast ((NumberValue) thisValue) to check type of a value because type of a mutable value is variable. + * + * @throws MessageTypeCastException + * If type of this value is not Integer or Float. + */ + public NumberValue asNumberValue(); + + /** + * Returns the value as {@code IntegerValue}. Otherwise throws {@code MessageTypeCastException}. + * + * Note that you can't use instanceof or cast ((IntegerValue) thisValue) to check type of a value because type of a mutable value is variable. + * + * @throws MessageTypeCastException + * If type of this value is not Integer. + */ + public IntegerValue asIntegerValue(); + + /** + * Returns the value as {@code FloatValue}. Otherwise throws {@code MessageTypeCastException}. + * + * Note that you can't use instanceof or cast ((FloatValue) thisValue) to check type of a value because type of a mutable value is variable. + * + * @throws MessageTypeCastException + * If type of this value is not Float. + */ + public FloatValue asFloatValue(); + + /** + * Returns the value as {@code RawValue}. Otherwise throws {@code MessageTypeCastException}. + * + * Note that you can't use instanceof or cast ((RawValue) thisValue) to check type of a value because type of a mutable value is variable. + * + * @throws MessageTypeCastException + * If type of this value is not Binary or String. + */ + public RawValue asRawValue(); + + /** + * Returns the value as {@code BinaryValue}. Otherwise throws {@code MessageTypeCastException}. + * + * Note that you can't use instanceof or cast ((BinaryValue) thisValue) to check type of a value because type of a mutable value is variable. + * + * @throws MessageTypeCastException + * If type of this value is not Binary. + */ + public BinaryValue asBinaryValue(); + + /** + * Returns the value as {@code StringValue}. Otherwise throws {@code MessageTypeCastException}. + * + * Note that you can't use instanceof or cast ((StringValue) thisValue) to check type of a value because type of a mutable value is variable. + * + * @throws MessageTypeCastException + * If type of this value is not String. + */ + public StringValue asStringValue(); + + /** + * Returns the value as {@code ArrayValue}. Otherwise throws {@code MessageTypeCastException}. + * + * Note that you can't use instanceof or cast ((ArrayValue) thisValue) to check type of a value because type of a mutable value is variable. + * + * @throws MessageTypeCastException + * If type of this value is not Array. + */ + public ArrayValue asArrayValue(); + + /** + * Returns the value as {@code MapValue}. Otherwise throws {@code MessageTypeCastException}. + * + * Note that you can't use instanceof or cast ((MapValue) thisValue) to check type of a value because type of a mutable value is variable. + * + * @throws MessageTypeCastException + * If type of this value is not Map. + */ + public MapValue asMapValue(); + + /** + * Returns the value as {@code ExtendedValue}. Otherwise throws {@code MessageTypeCastException}. + * + * Note that you can't use instanceof or cast ((ExtendedValue) thisValue) to check type of a value because type of a mutable value is variable. + * + * @throws MessageTypeCastException + * If type of this value is not Extended. + */ + public ExtendedValue asExtendedValue(); - public ArrayValue asArrayValue() throws MessageTypeException; - public MapValue asMapValue() throws MessageTypeException; + /** + * Serializes the value using the specified {@code MessagePacker} + * + * @see MessagePacker + */ + public void writeTo(MessagePacker pk) throws IOException; + /** + * Compares this value to the specified object. + * + * This method returns {@code true} if type and value are equivalent. + * If this value is {@code MapValue} or {@code ArrayValue}, this method check equivalence of elements recursively. + */ + public boolean equals(Object obj); } diff --git a/msgpack-core/src/main/java/org/msgpack/value/ValueFactory.java b/msgpack-core/src/main/java/org/msgpack/value/ValueFactory.java index 084d325da..4c5245921 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/ValueFactory.java +++ b/msgpack-core/src/main/java/org/msgpack/value/ValueFactory.java @@ -15,135 +15,126 @@ // package org.msgpack.value; -import org.msgpack.value.impl.*; +import org.msgpack.value.impl.ImmutableNilValueImpl; +import org.msgpack.value.impl.ImmutableBooleanValueImpl; +import org.msgpack.value.impl.ImmutableLongValueImpl; +import org.msgpack.value.impl.ImmutableBigIntegerValueImpl; +import org.msgpack.value.impl.ImmutableBinaryValueImpl; +import org.msgpack.value.impl.ImmutableDoubleValueImpl; +import org.msgpack.value.impl.ImmutableStringValueImpl; +import org.msgpack.value.impl.ImmutableArrayValueImpl; +import org.msgpack.value.impl.ImmutableMapValueImpl; +import org.msgpack.value.impl.ImmutableExtendedValueImpl; import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Arrays; import java.math.BigInteger; +import java.io.UnsupportedEncodingException; import java.nio.ByteBuffer; -/** - * Factory for creting Value instances - */ -public class ValueFactory { - public static NilValue nilValue() { - return NilValueImpl.getInstance(); - } - - public static BooleanValue newBoolean(boolean v) { - return v ? BooleanValueImpl.TRUE : BooleanValueImpl.FALSE; - } +public final class ValueFactory { + private ValueFactory() { } - public static IntegerValue newByte(byte v) { - return new IntegerValueImpl((int) v); + public static ImmutableNilValue newNilValue() { + return ImmutableNilValueImpl.get(); } - public static IntegerValue newShort(short v) { - return new IntegerValueImpl((int) v); + public static ImmutableBooleanValue newBooleanValue(boolean v) { + if (v) { + return ImmutableBooleanValueImpl.trueInstance(); + } else { + return ImmutableBooleanValueImpl.falseInstance(); + } } - public static IntegerValue newInt(int v) { - return new IntegerValueImpl(v); + public static ImmutableIntegerValue newIntegerValue(byte v) { + return new ImmutableLongValueImpl(v); } - public static IntegerValue newLong(long v) { - return new LongValueImpl(v); + public static ImmutableIntegerValue newIntegerValue(short v) { + return new ImmutableLongValueImpl(v); } - public static IntegerValue newBigInteger(BigInteger v) { - return new BigIntegerValueImpl(v); + public static ImmutableIntegerValue newIntegerValue(int v) { + return new ImmutableLongValueImpl(v); } - public static FloatValue newFloat(float v) { - return new FloatValueImpl(v); + public static ImmutableIntegerValue newIntegerValue(long v) { + return new ImmutableLongValueImpl(v); } - public static FloatValue newDouble(double v) { - return new DoubleValueImpl(v); + public static ImmutableIntegerValue newIntegerValue(BigInteger v) { + return new ImmutableBigIntegerValueImpl(v); } - public static BinaryValue newBinary(byte[] b) { - return new BinaryValueImpl(ByteBuffer.wrap(b)); + public static ImmutableFloatValue newFloatValue(float v) { + return new ImmutableDoubleValueImpl(v); } - public static BinaryValue newBinary(byte[] b, int off, int len) { - return new BinaryValueImpl(ByteBuffer.wrap(b, off, len)); + public static ImmutableFloatValue newFloatValue(double v) { + return new ImmutableDoubleValueImpl(v); } - public static BinaryValue newBinary(ByteBuffer bb) { - return new BinaryValueImpl(bb.duplicate()); + public static ImmutableBinaryValue newBinaryValue(byte[] b) { + return new ImmutableBinaryValueImpl(b); } - public static StringValue newString(String s) { - return new StringValueImpl(s); + public static ImmutableBinaryValue newBinaryValue(byte[] b, int off, int len) { + return new ImmutableBinaryValueImpl(Arrays.copyOfRange(b, off, len)); } - public static StringValue newRawString(byte[] b) { - return new RawStringValueImpl(ByteBuffer.wrap(b)); + public static ImmutableStringValue newStringValue(String s) { + return new ImmutableStringValueImpl(s); } - public static StringValue newRawString(byte[] b, int off, int len) { - return new RawStringValueImpl(ByteBuffer.wrap(b, off, len)); + public static ImmutableStringValue newRawStringValue(byte[] b) { + return new ImmutableStringValueImpl(b); } - public static StringValue newRawString(ByteBuffer bb) { - return new RawStringValueImpl(bb.duplicate()); + public static ImmutableStringValue newRawStringValue(byte[] b, int off, int len) { + return new ImmutableStringValueImpl(Arrays.copyOfRange(b, off, len)); } - public static ArrayValue newArrayFrom(List list) { + public static ImmutableArrayValue newArrayValue(List list) { if (list.isEmpty()) { - return ArrayValueImpl.empty(); + return ImmutableArrayValueImpl.empty(); } Value[] array = list.toArray(new Value[list.size()]); - return new ArrayValueImpl(array); + return new ImmutableArrayValueImpl(array); } - public static ArrayValue newArray(Value... array) { + public static ImmutableArrayValue newArrayValue(Value[] array) { if (array.length == 0) { - return ArrayValueImpl.empty(); + return ImmutableArrayValueImpl.empty(); } - return new ArrayValueImpl(array); - } - - public static ArrayValue emptyArray() { - return ArrayValueImpl.empty(); + return new ImmutableArrayValueImpl(Arrays.copyOf(array, array.length)); } - public static MapValue newMap(Map map) { - Value[] keyValueSequence = new Value[map.size() * 2]; + public static + ImmutableMapValue newMapValue(Map map) { + Value[] kvs = new Value[map.size() * 2]; Iterator> ite = map.entrySet().iterator(); int index = 0; while (ite.hasNext()) { Map.Entry pair = ite.next(); - keyValueSequence[index++] = pair.getKey(); - keyValueSequence[index++] = pair.getValue(); + kvs[index] = pair.getKey(); + index++; + kvs[index] = pair.getValue(); + index++; } - return newMap(keyValueSequence); + return newMapValue(kvs); } - public static MapValue newMap(Value[] keyValueSequence) { - if (keyValueSequence.length == 0) { - return MapValueImpl.empty(); + public static ImmutableMapValue newMapValue(Value[] kvs) { + if (kvs.length == 0) { + return ImmutableMapValueImpl.empty(); } - return new MapValueImpl(keyValueSequence); - } - - public static MapValue emptyMap() { - return MapValueImpl.empty(); - } - - public static ExtendedValue newExtendedValue(int extType, byte[] extData) { - return newExtendedValue(extType, ByteBuffer.wrap(extData)); - } - - public static ExtendedValue newExtendedValue(int extType, ByteBuffer extData) { - return new ExtendedValueImpl(extType, extData); + return new ImmutableMapValueImpl(Arrays.copyOf(kvs, kvs.length)); } - /** - * Hide the default constructor to forbid instantiation of this class - */ - protected ValueFactory() { + public static ImmutableExtendedValue newExtendedValue(byte type, byte[] data) { + return new ImmutableExtendedValueImpl(type, data); } } diff --git a/msgpack-core/src/main/java/org/msgpack/value/ValueRef.java b/msgpack-core/src/main/java/org/msgpack/value/ValueRef.java deleted file mode 100644 index 0043e4392..000000000 --- a/msgpack-core/src/main/java/org/msgpack/value/ValueRef.java +++ /dev/null @@ -1,54 +0,0 @@ -package org.msgpack.value; - -import org.msgpack.core.MessagePacker; -import org.msgpack.core.MessageTypeException; - -import java.io.IOException; - -/** - * Reference to the value - */ -public interface ValueRef { - public ValueType getValueType(); - - public NilValue asNil() throws MessageTypeException; - public BooleanValue asBoolean() throws MessageTypeException; - public NumberValue asNumber() throws MessageTypeException; - public IntegerValue asInteger() throws MessageTypeException; - public FloatValue asFloat() throws MessageTypeException; - public BinaryValue asBinary() throws MessageTypeException; - public StringValue asString() throws MessageTypeException; - public RawValue asRaw() throws MessageTypeException; - public ExtendedValue asExtended() throws MessageTypeException; - - public ArrayCursor getArrayCursor() throws MessageTypeException; - public MapCursor getMapCursor() throws MessageTypeException; - - public boolean isNil(); - public boolean isBoolean(); - public boolean isNumber(); - public boolean isInteger(); - public boolean isFloat(); - public boolean isBinary(); - public boolean isString(); - public boolean isRaw(); - public boolean isArray(); - public boolean isMap(); - public boolean isExtended(); - - public void writeTo(MessagePacker packer) throws IOException; - - public void accept(ValueVisitor visitor); - - /** - * Create an immutable value from this reference - * @return - */ - public Value toValue(); - - /** - * Test whether this value is a reference of not. - * @return true if this value is reference, otherwise false. - */ - public boolean isRef(); -} diff --git a/msgpack-core/src/main/java/org/msgpack/value/ValueType.java b/msgpack-core/src/main/java/org/msgpack/value/ValueType.java index 5e1b27b99..8a2ce8c83 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/ValueType.java +++ b/msgpack-core/src/main/java/org/msgpack/value/ValueType.java @@ -32,23 +32,12 @@ public enum ValueType { MAP(false, false), EXTENDED(false, true); - private final boolean numberType; private final boolean rawType; - private final int bitMask; private ValueType(boolean numberType, boolean rawType) { this.numberType = numberType; this.rawType = rawType; - this.bitMask = 1 << this.ordinal(); - } - - public int getBitMask() { - return bitMask; - } - - public boolean isTypeOf(int bitMask) { - return (this.bitMask & bitMask) != 0; } public boolean isNilType() { @@ -94,13 +83,4 @@ public boolean isMapType() { public boolean isExtendedType() { return this == EXTENDED; } - - public static ValueType valueOf(byte b) { - return MessageFormat.valueOf(b).getValueType(); - } - - public String toTypeName() { - return this.name().substring(0, 1) + this.name().substring(1).toLowerCase(); - } - } diff --git a/msgpack-core/src/main/java/org/msgpack/value/holder/ExtHolder.java b/msgpack-core/src/main/java/org/msgpack/value/holder/ExtHolder.java deleted file mode 100644 index 104e74210..000000000 --- a/msgpack-core/src/main/java/org/msgpack/value/holder/ExtHolder.java +++ /dev/null @@ -1,69 +0,0 @@ -package org.msgpack.value.holder; - -import org.msgpack.core.MessagePack; -import org.msgpack.core.MessagePacker; -import org.msgpack.core.MessageStringCodingException; -import org.msgpack.core.buffer.MessageBuffer; -import org.msgpack.value.*; -import org.msgpack.value.impl.AbstractValueRef; - -import java.io.IOException; -import java.nio.ByteBuffer; - -/** - * Created on 6/13/14. - */ -public class ExtHolder extends AbstractValueRef implements ExtendedValue { - - private int extType; - private MessageBuffer buffer; - - - public void setExtType(int extType, MessageBuffer buffer) { - this.extType = extType; - this.buffer = buffer; - } - - @Override - public int getExtType() { - return extType; - } - - @Override - public ValueType getValueType() { - return ValueType.EXTENDED; - } - - @Override - public void writeTo(MessagePacker packer) throws IOException { - packer.packExtendedTypeHeader(extType, buffer.size()).writePayload(buffer.toByteBuffer()); - } - - @Override - public void accept(ValueVisitor visitor) { - visitor.visitExtended(this); - } - @Override - public ExtendedValue toValue() { - // clone the buffer contents - return ValueFactory.newExtendedValue(extType, buffer.toByteArray()); - } - - @Override - public byte[] toByteArray() { - return buffer.toByteArray(); - } - @Override - public ByteBuffer toByteBuffer() { - return buffer.toByteBuffer(); - } - @Override - public MessageBuffer toMessageBuffer() { - return buffer; - } - - @Override - public String toString() throws MessageStringCodingException { - return new String(buffer.toByteArray(), MessagePack.UTF8); - } -} diff --git a/msgpack-core/src/main/java/org/msgpack/value/holder/FloatHolder.java b/msgpack-core/src/main/java/org/msgpack/value/holder/FloatHolder.java deleted file mode 100644 index fb369afdb..000000000 --- a/msgpack-core/src/main/java/org/msgpack/value/holder/FloatHolder.java +++ /dev/null @@ -1,178 +0,0 @@ -package org.msgpack.value.holder; - -import org.msgpack.core.MessageFloatOverflowException; -import org.msgpack.core.MessageOverflowException; -import org.msgpack.core.MessagePacker; -import org.msgpack.value.*; -import org.msgpack.value.impl.AbstractValueRef; - -import java.io.IOException; -import java.math.BigDecimal; -import java.math.BigInteger; - -/** - * Created on 6/3/14. - */ -public class FloatHolder extends AbstractValueRef implements FloatValue { - - public static enum Type { - FLOAT, - DOUBLE - } - - private Type tpe; - private double value; - - @Override - public boolean isValidByte() { - return ((double) ((byte) value)) == value; - } - @Override - public boolean isValidShort() { - return ((double) ((short) value)) == value; - } - @Override - public boolean isValidInt() { - return ((double) ((int) value)) == value; - } - @Override - public boolean isValidLong() { - long l = (long) value; - return ((double) l) == value && l != Long.MAX_VALUE; - } - @Override - public boolean isWhole() { - long l = (long) value; - return ((double) l == value) || l == Long.MAX_VALUE && value < Double.POSITIVE_INFINITY || l == Long.MIN_VALUE && value > Double.NEGATIVE_INFINITY; - } - @Override - public byte toByte() { - return (byte) value; - } - - @Override - public short toShort() { - return (short) value; - } - - @Override - public int toInt() { - return (int) value; - } - - @Override - public long toLong() { - return (long) value; - } - - @Override - public BigInteger toBigInteger() { - return new BigDecimal(value).toBigInteger(); - } - - @Override - public float toFloat() { - return (float) value; - } - - @Override - public double toDouble() { - return value; - } - @Override - public byte asByte() throws MessageOverflowException { - if(!isValidByte()) - throw new MessageFloatOverflowException(value); - return (byte) value; - } - @Override - public short asShort() throws MessageOverflowException { - if(!isValidShort()) - throw new MessageFloatOverflowException(value); - return (short) value; - } - @Override - public int asInt() throws MessageOverflowException { - if(!isValidInt()) - throw new MessageFloatOverflowException(value); - return (int) value; - } - @Override - public long asLong() throws MessageOverflowException { - if(!isValidLong()) - throw new MessageFloatOverflowException(value); - return (long) value; - } - @Override - public BigInteger asBigInteger() throws MessageOverflowException { - if(!isWhole()) - throw new MessageFloatOverflowException(value); - return new BigDecimal(value).toBigInteger(); - } - - @Override - public ValueType getValueType() { - return ValueType.FLOAT; - } - @Override - public void writeTo(MessagePacker pk) throws IOException { - switch(tpe) { - case FLOAT: - pk.packFloat(toFloat()); - break; - case DOUBLE: - pk.packDouble(value); - break; - } - } - - @Override - public void accept(ValueVisitor visitor) { - visitor.visitFloat(this); - } - @Override - public FloatValue toValue() { - switch(tpe) { - case FLOAT: - return ValueFactory.newFloat(toFloat()); - case DOUBLE: - return ValueFactory.newDouble(toDouble()); - default: - throw new IllegalStateException("cannot reach here"); - } - } - - public Type getType() { - return tpe; - } - - public void setFloat(float v) { - tpe = Type.FLOAT; - value = v; - } - - public void setDouble(double v) { - tpe = Type.DOUBLE; - value = v; - } - - @Override - public int hashCode() { - long v = Double.doubleToLongBits(value); - return (int) (v ^ (v >>> 32)); - } - - @Override - public String toString() { - switch(tpe) { - case FLOAT: - return Float.toString((float) value); - case DOUBLE: - return Double.toString(value); - default: - throw new IllegalStateException("cannot reach here"); - } - } - - -} diff --git a/msgpack-core/src/main/java/org/msgpack/value/holder/IntegerHolder.java b/msgpack-core/src/main/java/org/msgpack/value/holder/IntegerHolder.java deleted file mode 100644 index f7aab07fc..000000000 --- a/msgpack-core/src/main/java/org/msgpack/value/holder/IntegerHolder.java +++ /dev/null @@ -1,268 +0,0 @@ -package org.msgpack.value.holder; - -import org.msgpack.core.MessageIntegerOverflowException; -import org.msgpack.core.MessagePacker; -import org.msgpack.core.MessageTypeException; -import org.msgpack.value.*; -import org.msgpack.value.impl.AbstractValueRef; - -import java.io.IOException; -import java.math.BigInteger; -import static org.msgpack.core.NumberUtil.*; - -/** - * Union of integer values - */ -public class IntegerHolder extends AbstractValueRef implements IntegerValue { - - @Override - public ValueType getValueType() { - return ValueType.INTEGER; - } - @Override - public void writeTo(MessagePacker packer) throws IOException { - switch(tpe) { - case BIG_INTEGER: - packer.packBigInteger(biValue); - break; - default: - packer.packLong(longValue); - break; - } - } - - @Override - public IntegerValue asInteger() throws MessageTypeException { - return this; - } - - @Override - public void accept(ValueVisitor visitor) { - visitor.visitInteger(this); - } - - @Override - public IntegerValue toValue() { - switch(tpe){ - case BYTE: - return ValueFactory.newByte(toByte()); - case SHORT: - return ValueFactory.newShort(toShort()); - case INT: - return ValueFactory.newInt(toInt()); - case LONG: - return ValueFactory.newLong(toLong()); - case BIG_INTEGER: - return ValueFactory.newBigInteger(toBigInteger()); - default: - throw new IllegalStateException("cannot reach here"); - } - } - - public static enum Type { - BYTE, - SHORT, - INT, - LONG, - BIG_INTEGER - } - - private Type tpe; - private long longValue; - private BigInteger biValue; - - public Type getType() { - return tpe; - } - - public void setByte(byte v){ - tpe = Type.BYTE; - longValue = v; - } - public void setShort(short v) { - tpe = Type.SHORT; - longValue = v; - } - public void setInt(int v) { - tpe = Type.INT; - longValue = v; - } - public void setLong(long v) { - tpe = Type.LONG; - longValue = v; - } - public void setBigInteger(BigInteger v) { - tpe = Type.BIG_INTEGER; - biValue = v; - } - - private RuntimeException failure() { - return new IllegalStateException(); - } - - public boolean isBigInteger() { - return tpe == Type.BIG_INTEGER; - } - - @Override - public boolean isValidByte() { - return tpe == Type.BYTE; - } - @Override - public boolean isValidShort() { - return tpe.ordinal() <= Type.SHORT.ordinal(); - } - @Override - public boolean isValidInt() { - return tpe.ordinal() <= Type.INT.ordinal(); - } - @Override - public boolean isValidLong() { - return tpe.ordinal() <= Type.LONG.ordinal(); - } - - @Override - public boolean isWhole() { - return true; - } - - public byte toByte() { - return isBigInteger() ? biValue.byteValue() : (byte) longValue; - } - - public short toShort() { - return isBigInteger() ? biValue.shortValue() : (short) longValue; - } - - public int toInt() { - return isBigInteger() ? biValue.intValue() : (int) longValue; - } - - public long toLong(){ - return isBigInteger() ? biValue.longValue() : longValue; - } - - public BigInteger toBigInteger() { - return isBigInteger() ? biValue : BigInteger.valueOf(longValue); - } - @Override - public float toFloat() { - return isBigInteger() ? biValue.floatValue() : (float) longValue; - } - @Override - public double toDouble() { - return isBigInteger() ? biValue.doubleValue() : (double) longValue; - } - - - @Override - public byte asByte() throws MessageIntegerOverflowException { - switch(tpe) { - case BYTE: - return (byte) longValue; - case SHORT: - case INT: - case LONG: - if(LongUtil.isValidByte(longValue)) { - return (byte) longValue; - } - else { - throw new MessageIntegerOverflowException(longValue); - } - case BIG_INTEGER: - if(LongUtil.isValidByte(biValue)) { - return biValue.byteValue(); - } - else { - throw new MessageIntegerOverflowException(biValue); - } - default: - throw failure(); - } - } - - - @Override - public short asShort() throws MessageIntegerOverflowException { - switch(tpe) { - case BYTE: - case SHORT: - return (short) longValue; - case INT: - case LONG: - if(LongUtil.isValidShort(longValue)) { - return (short) longValue; - } - else { - throw new MessageIntegerOverflowException(longValue); - } - case BIG_INTEGER: - if(LongUtil.isValidShort(biValue)) { - return biValue.shortValue(); - } - else { - throw new MessageIntegerOverflowException(biValue); - } - default: - throw failure(); - } - } - - - @Override - public int asInt() throws MessageIntegerOverflowException { - switch(tpe) { - case BYTE: - case SHORT: - case INT: - return (int) longValue; - case LONG: - if(LongUtil.isValidInt(longValue)) { - return (int) longValue; - } - else { - throw new MessageIntegerOverflowException(longValue); - } - case BIG_INTEGER: - if(LongUtil.isValidInt(biValue)) { - return biValue.intValue(); - } - else { - throw new MessageIntegerOverflowException(biValue); - } - default: - throw failure(); - } - } - - @Override - public long asLong() throws MessageIntegerOverflowException { - if(isBigInteger()){ - if(LongUtil.isValidLong(biValue)) { - return biValue.longValue(); - } else { - throw new MessageIntegerOverflowException(biValue); - } - } - return longValue; - } - - @Override - public BigInteger asBigInteger() { - return toBigInteger(); - } - - - @Override - public int hashCode() { - return isBigInteger() ? biValue.hashCode() : (int) longValue; - } - - @Override - public String toString() { - return isBigInteger() ? biValue.toString() : Long.toString(longValue); - } - - - -} diff --git a/msgpack-core/src/main/java/org/msgpack/value/holder/RawHolder.java b/msgpack-core/src/main/java/org/msgpack/value/holder/RawHolder.java deleted file mode 100644 index 371589957..000000000 --- a/msgpack-core/src/main/java/org/msgpack/value/holder/RawHolder.java +++ /dev/null @@ -1,270 +0,0 @@ -package org.msgpack.value.holder; - -import org.msgpack.core.MessagePack; -import org.msgpack.core.MessagePacker; -import org.msgpack.core.MessageStringCodingException; -import org.msgpack.core.buffer.MessageBuffer; -import org.msgpack.value.*; -import org.msgpack.value.impl.AbstractValueRef; - -import java.io.IOException; -import java.nio.ByteBuffer; - -import static org.msgpack.core.MessagePackException.UNREACHABLE; - - -class RawHolderImpl extends AbstractValueRef implements RawValue { - - public static enum Type { - STRING, - BINARY - } - - protected Type tpe; - protected MessageBuffer buf; - - public void setString(MessageBuffer buf) { - this.tpe = Type.STRING; - this.buf = buf; - } - - public void setBinary(MessageBuffer buf) { - this.tpe = Type.BINARY; - this.buf = buf; - } - - public MessageBuffer getBuffer() { return buf; } - - @Override - public byte[] toByteArray() { - switch(tpe) { - case STRING: - case BINARY: - return buf.toByteArray(); - default: - throw UNREACHABLE; - } - } - - @Override - public ByteBuffer toByteBuffer() { - switch(tpe) { - case STRING: - return buf.toByteBuffer(); - default: - throw UNREACHABLE; - } - } - - @Override - public MessageBuffer toMessageBuffer() { - return buf; - } - - @Override - public String toString() throws MessageStringCodingException { - switch(tpe) { - case STRING: - return new String(buf.toByteArray(), MessagePack.UTF8); - case BINARY: - return buf.toHexString(0, buf.size()); - default: - throw UNREACHABLE; - } - } - - - @Override - public ValueType getValueType() { - switch(tpe) { - case STRING: - return ValueType.STRING; - case BINARY: - return ValueType.BINARY; - default: - throw UNREACHABLE; - } - } - - @Override - public void writeTo(MessagePacker packer) throws IOException { - switch(tpe) { - case STRING: - packer.packRawStringHeader(buf.size()).writePayload(buf.toByteBuffer()); - break; - case BINARY: - packer.packBinaryHeader(buf.size()).writePayload(buf.toByteBuffer()); - break; - default: - throw UNREACHABLE; - } - } - - @Override - public void accept(ValueVisitor visitor) { - switch(tpe) { - case STRING: - visitor.visitString(this.asString()); - break; - case BINARY: - visitor.visitBinary(this.asBinary()); - break; - default: - throw UNREACHABLE; - } - } - - @Override - public RawValue toValue() { - switch(tpe) { - case STRING: - return ValueFactory.newRawString(buf.toByteArray()); - case BINARY: - return ValueFactory.newBinary(buf.toByteArray()); - default: - throw UNREACHABLE; - } - } - -} - - -/** - * Holder of the raw values - */ -public class RawHolder extends RawHolderImpl { - - private static class StringValueWrap extends RawHolderImpl implements StringValue { - public StringValue toValue() { - return ValueFactory.newRawString(buf.toByteArray()); - } - } - - private static class BinaryValueWrap extends RawHolderImpl implements BinaryValue { - public BinaryValue toValue() { - return ValueFactory.newBinary(buf.toByteArray()); - } - } - - private StringValueWrap stringWrap = new StringValueWrap(); - private BinaryValueWrap binaryWrap = new BinaryValueWrap(); - - @Override - public void setString(MessageBuffer buf) { - this.tpe = Type.STRING; - this.buf = buf; - stringWrap.setString(buf); - } - - @Override - public void setBinary(MessageBuffer buf) { - this.tpe = Type.BINARY; - this.buf = buf; - binaryWrap.setBinary(buf); - } - - public MessageBuffer getBuffer() { return buf; } - - @Override - public byte[] toByteArray() { - switch(tpe) { - case STRING: - case BINARY: - return buf.toByteArray(); - default: - throw UNREACHABLE; - } - } - - @Override - public ByteBuffer toByteBuffer() { - switch(tpe) { - case STRING: - return buf.toByteBuffer(); - default: - throw UNREACHABLE; - } - } - - @Override - public MessageBuffer toMessageBuffer() { - return buf; - } - - @Override - public String toString() throws MessageStringCodingException { - switch(tpe) { - case STRING: - return new String(buf.toByteArray(), MessagePack.UTF8); - case BINARY: - return buf.toHexString(0, buf.size()); - default: - throw UNREACHABLE; - } - } - - - @Override - public ValueType getValueType() { - switch(tpe) { - case STRING: - return ValueType.STRING; - case BINARY: - return ValueType.BINARY; - default: - throw UNREACHABLE; - } - } - - @Override - public void writeTo(MessagePacker packer) throws IOException { - switch(tpe) { - case STRING: - packer.packRawStringHeader(buf.size()).writePayload(buf.toByteBuffer()); - break; - case BINARY: - packer.packBinaryHeader(buf.size()).writePayload(buf.toByteBuffer()); - break; - default: - throw UNREACHABLE; - } - } - - @Override - public void accept(ValueVisitor visitor) { - switch(tpe) { - case STRING: - visitor.visitString(this.asString()); - break; - case BINARY: - visitor.visitBinary(this.asBinary()); - break; - default: - throw UNREACHABLE; - } - } - - @Override - public RawValue toValue() { - switch(tpe) { - case STRING: - return ValueFactory.newRawString(buf.toByteArray()); - case BINARY: - return ValueFactory.newBinary(buf.toByteArray()); - default: - throw UNREACHABLE; - } - } - - - @Override - public StringValue asString() { - return stringWrap; - } - - @Override - public BinaryValue asBinary() { - return binaryWrap; - } - -} diff --git a/msgpack-core/src/main/java/org/msgpack/value/holder/ValueHolder.java b/msgpack-core/src/main/java/org/msgpack/value/holder/ValueHolder.java deleted file mode 100644 index fc0a99272..000000000 --- a/msgpack-core/src/main/java/org/msgpack/value/holder/ValueHolder.java +++ /dev/null @@ -1,127 +0,0 @@ -package org.msgpack.value.holder; - -import org.msgpack.core.MessageUnpacker; -import org.msgpack.core.buffer.MessageBuffer; -import org.msgpack.value.ValueRef; -import org.msgpack.value.impl.ArrayCursorImpl; -import org.msgpack.value.Value; -import org.msgpack.value.ValueFactory; -import org.msgpack.value.ValueType; -import org.msgpack.value.impl.MapCursorImpl; - -import java.io.IOException; -import java.nio.ByteBuffer; - -import static org.msgpack.core.MessagePackException.UNREACHABLE; - -/** - * This class can hold any message packed value. - */ -public class ValueHolder { - - private ValueType vt; - private IntegerHolder integerHolder = new IntegerHolder(); - private FloatHolder floatHolder = new FloatHolder(); - private RawHolder rawHolder = new RawHolder(); - private ExtHolder extHolder = new ExtHolder(); - private ArrayCursorImpl arrayCursor; - private MapCursorImpl mapCursor; - private ValueRef currentRef; - - public ValueRef getRef() { - if(currentRef == null) { - throw new IllegalStateException("no value is set to this holder"); - } - - return currentRef; - } - - public Value get() { - switch(vt) { - case NIL: - case BOOLEAN: - case INTEGER: - case FLOAT: - case ARRAY: - case MAP: - case EXTENDED: - return getRef().toValue(); - case STRING: - return ValueFactory.newRawString(cloneBuffer(rawHolder.getBuffer())); - case BINARY: - return ValueFactory.newBinary(cloneBuffer(rawHolder.getBuffer())); - default: - throw UNREACHABLE; - } - } - - - private static ByteBuffer cloneBuffer(MessageBuffer buffer) { - return ByteBuffer.wrap(buffer.toByteArray()); - } - - public IntegerHolder getIntegerHolder() { - return integerHolder; - } - - public FloatHolder getFloatHolder() { - return floatHolder; - } - - public void setBoolean(boolean v) { - vt = ValueType.BOOLEAN; - currentRef = ValueFactory.newBoolean(v); - } - - public void setNil() { - vt = ValueType.NIL; - currentRef = ValueFactory.nilValue(); - } - - public void setString(MessageBuffer rawString) { - vt = ValueType.STRING; - rawHolder.setString(rawString); - currentRef = rawHolder.asString(); - } - - public void setBinary(MessageBuffer b) { - vt = ValueType.BINARY; - rawHolder.setBinary(b); - currentRef = rawHolder.asBinary(); - } - - public void setToInteger() { - vt = ValueType.INTEGER; - currentRef = integerHolder; - } - - public void setToFloat() { - vt = ValueType.FLOAT; - currentRef = floatHolder; - } - - public void setExt(int extType, MessageBuffer b) { - vt = ValueType.EXTENDED; - extHolder.setExtType(extType, b); - currentRef = extHolder; - } - - public void prepareArrayCursor(MessageUnpacker unpacker) throws IOException { - vt = ValueType.ARRAY; - - // TODO reusing cursor instances - arrayCursor = new ArrayCursorImpl(new ValueHolder()); - arrayCursor.reset(unpacker); - currentRef = arrayCursor; - } - - public void prepareMapCursor(MessageUnpacker unpacker) throws IOException { - vt = ValueType.MAP; - - // TODO reusing cursor instances - mapCursor = new MapCursorImpl(new ValueHolder()); - mapCursor.reset(unpacker); - currentRef = mapCursor; - } - -} diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/AbstractImmutableRawValue.java b/msgpack-core/src/main/java/org/msgpack/value/impl/AbstractImmutableRawValue.java new file mode 100644 index 000000000..29b9e29b9 --- /dev/null +++ b/msgpack-core/src/main/java/org/msgpack/value/impl/AbstractImmutableRawValue.java @@ -0,0 +1,168 @@ +// +// MessagePack for Java +// +// 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.value.impl; + +import org.msgpack.core.MessagePack; +import org.msgpack.core.MessagePacker; +import org.msgpack.core.MessageStringCodingException; +import org.msgpack.value.Value; +import org.msgpack.value.ImmutableRawValue; + +import java.util.Arrays; +import java.io.IOException; +import java.nio.ByteBuffer; +import java.nio.charset.CharsetDecoder; +import java.nio.charset.CharsetEncoder; +import java.nio.charset.CodingErrorAction; +import java.nio.charset.CharacterCodingException; + + +public abstract class AbstractImmutableRawValue extends AbstractImmutableValue implements ImmutableRawValue { + protected final byte[] data; + private volatile String decodedStringCache; + private volatile CharacterCodingException codingException; + + public AbstractImmutableRawValue(byte[] data) { + this.data = data; + } + + public AbstractImmutableRawValue(String string) { + this.decodedStringCache = string; + this.data = string.getBytes(MessagePack.UTF8); // TODO + } + + @Override + public ImmutableRawValue asRawValue() { + return this; + } + + @Override + public byte[] getByteArray() { + return Arrays.copyOf(data, data.length); + } + + @Override + public ByteBuffer getByteBuffer() { + return ByteBuffer.wrap(data).asReadOnlyBuffer(); + } + + @Override + public String getString() { + if (decodedStringCache == null) { + decodeString(); + } + if (codingException != null) { + throw new MessageStringCodingException(codingException); + } else { + return decodedStringCache; + } + } + + @Override + public String stringValue() { + return decodedStringCache; + } + + private void decodeString() { + synchronized (data) { + if (decodedStringCache != null) { + return; + } + try { + CharsetDecoder reportDecoder = MessagePack.UTF8.newDecoder() + .onMalformedInput(CodingErrorAction.REPORT) + .onUnmappableCharacter(CodingErrorAction.REPORT); + this.decodedStringCache = reportDecoder.decode(getByteBuffer()).toString(); + } catch (CharacterCodingException ex) { + try { + CharsetDecoder replaceDecoder = MessagePack.UTF8.newDecoder() + .onMalformedInput(CodingErrorAction.REPLACE) + .onUnmappableCharacter(CodingErrorAction.REPLACE); + this.decodedStringCache = replaceDecoder.decode(getByteBuffer()).toString(); + } catch (CharacterCodingException neverThrown) { + throw new MessageStringCodingException(neverThrown); + } + this.codingException = ex; + } + } + } + + @Override + public String toString() { + return toString(new StringBuilder()).toString(); + } + + private StringBuilder toString(StringBuilder sb) { + String s = stringValue(); + sb.append("\""); + for (int i = 0; i < s.length(); i++) { + char ch = s.charAt(i); + if (ch < 0x20) { + switch (ch) { + case '\n': + sb.append("\\n"); + break; + case '\r': + sb.append("\\r"); + break; + case '\t': + sb.append("\\t"); + break; + case '\f': + sb.append("\\f"); + break; + case '\b': + sb.append("\\b"); + break; + default: + // control chars + escapeChar(sb, ch); + break; + } + } else if (ch <= 0x7f) { + switch (ch) { + case '\\': + sb.append("\\\\"); + break; + case '"': + sb.append("\\\""); + break; + default: + sb.append(ch); + break; + } + } else if (ch >= 0xd800 && ch <= 0xdfff) { + // surrogates + escapeChar(sb, ch); + } else { + sb.append(ch); + } + } + sb.append("\""); + + return sb; + } + + private final static char[] HEX_TABLE = "0123456789ABCDEF".toCharArray(); + + private void escapeChar(StringBuilder sb, int ch) { + sb.append("\\u"); + sb.append(HEX_TABLE[(ch >> 12) & 0x0f]); + sb.append(HEX_TABLE[(ch >> 8) & 0x0f]); + sb.append(HEX_TABLE[(ch >> 4) & 0x0f]); + sb.append(HEX_TABLE[ch & 0x0f]); + } +} diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/AbstractImmutableValue.java b/msgpack-core/src/main/java/org/msgpack/value/impl/AbstractImmutableValue.java new file mode 100644 index 000000000..e3cd51821 --- /dev/null +++ b/msgpack-core/src/main/java/org/msgpack/value/impl/AbstractImmutableValue.java @@ -0,0 +1,132 @@ +// +// MessagePack for Java +// +// 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.value.impl; + +import org.msgpack.core.MessageTypeCastException; +import org.msgpack.value.*; + + +abstract class AbstractImmutableValue implements ImmutableValue { + @Override + public boolean isNilValue() { + return getValueType().isNilType(); + } + + @Override + public boolean isBooleanValue() { + return getValueType().isBooleanType(); + } + + @Override + public boolean isNumberValue() { + return getValueType().isNumberType(); + } + + @Override + public boolean isIntegerValue() { + return getValueType().isIntegerType(); + } + + @Override + public boolean isFloatValue() { + return getValueType().isFloatType(); + } + + @Override + public boolean isRawValue() { + return getValueType().isRawType(); + } + + @Override + public boolean isBinaryValue() { + return getValueType().isBinaryType(); + } + + @Override + public boolean isStringValue() { + return getValueType().isStringType(); + } + + @Override + public boolean isArrayValue() { + return getValueType().isArrayType(); + } + + @Override + public boolean isMapValue() { + return getValueType().isMapType(); + } + + @Override + public boolean isExtendedValue() { + return getValueType().isExtendedType(); + } + + @Override + public ImmutableNilValue asNilValue() { + throw new MessageTypeCastException(); + } + + @Override + public ImmutableBooleanValue asBooleanValue() { + throw new MessageTypeCastException(); + } + + @Override + public ImmutableNumberValue asNumberValue() { + throw new MessageTypeCastException(); + } + + @Override + public ImmutableIntegerValue asIntegerValue() { + throw new MessageTypeCastException(); + } + + @Override + public ImmutableFloatValue asFloatValue() { + throw new MessageTypeCastException(); + } + + @Override + public ImmutableRawValue asRawValue() { + throw new MessageTypeCastException(); + } + + @Override + public ImmutableBinaryValue asBinaryValue() { + throw new MessageTypeCastException(); + } + + @Override + public ImmutableStringValue asStringValue() { + throw new MessageTypeCastException(); + } + + @Override + public ImmutableArrayValue asArrayValue() { + throw new MessageTypeCastException(); + } + + @Override + public ImmutableMapValue asMapValue() { + throw new MessageTypeCastException(); + } + + @Override + public ImmutableExtendedValue asExtendedValue() { + throw new MessageTypeCastException(); + } +} diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/AbstractValue.java b/msgpack-core/src/main/java/org/msgpack/value/impl/AbstractValue.java deleted file mode 100644 index 6408ed67a..000000000 --- a/msgpack-core/src/main/java/org/msgpack/value/impl/AbstractValue.java +++ /dev/null @@ -1,13 +0,0 @@ -package org.msgpack.value.impl; - -import org.msgpack.value.*; - -/** -* Base implementation of MessagePackValue -*/ -public abstract class AbstractValue extends AbstractValueRef implements Value { - - @Override - public boolean isRef() { return false; } - -} diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/AbstractValueRef.java b/msgpack-core/src/main/java/org/msgpack/value/impl/AbstractValueRef.java deleted file mode 100644 index 1e67a6b3c..000000000 --- a/msgpack-core/src/main/java/org/msgpack/value/impl/AbstractValueRef.java +++ /dev/null @@ -1,62 +0,0 @@ -package org.msgpack.value.impl; - -import org.msgpack.core.MessageTypeException; -import org.msgpack.value.*; - -/** - * Base implementation of message pack values - */ -public abstract class AbstractValueRef implements ValueRef { - - public boolean isRef() { return true; } - - protected static int NUMBER_TYPE_MASK = (1 << ValueType.INTEGER.ordinal()) - | (1 << ValueType.FLOAT.ordinal()); - protected static int RAW_TYPE_MASK = (1 << ValueType.STRING.ordinal()) - | (1 << ValueType.BINARY.ordinal()); - - protected E as(Class valueClass, ValueType vt) { - return as(valueClass, 1 << vt.ordinal()); - } - protected E as(Class valueClass, int bitMask) { - if(this.getValueType() == null) - throw new MessageTypeException("This value points to nothing"); - if(!this.getValueType().isTypeOf(bitMask)) - throw new MessageTypeException(String.format("Expected %s, but %s", valueClass.getSimpleName(), this.getValueType())); - return valueClass.cast(this); - } - - public NilValue asNil() throws MessageTypeException { return as(NilValue.class, ValueType.NIL); } - public BooleanValue asBoolean() throws MessageTypeException{ return as(BooleanValue.class, ValueType.BOOLEAN); } - public NumberValue asNumber() throws MessageTypeException { return as(NumberValue.class, NUMBER_TYPE_MASK); } - public IntegerValue asInteger() throws MessageTypeException { return as(IntegerValue.class, ValueType.INTEGER); } - public FloatValue asFloat() throws MessageTypeException { return as(FloatValue.class, ValueType.FLOAT); } - public BinaryValue asBinary() throws MessageTypeException { return as(BinaryValue.class, ValueType.BINARY); } - public StringValue asString() throws MessageTypeException { return as(StringValue.class, ValueType.STRING); } - public RawValue asRaw() throws MessageTypeException { return as(RawValue.class, RAW_TYPE_MASK); } - public ArrayValue asArrayValue() throws MessageTypeException { return as(ArrayValue.class, ValueType.ARRAY); } - public MapValue asMapValue() throws MessageTypeException { return as(MapValue.class, ValueType.MAP); } - public ExtendedValue asExtended() throws MessageTypeException { return as(ExtendedValue.class, ValueType.EXTENDED); } - - @Override - public ArrayCursor getArrayCursor() throws MessageTypeException { - throw new MessageTypeException("This value is not an array type"); - } - @Override - public MapCursor getMapCursor() throws MessageTypeException { - throw new MessageTypeException("This value is not a map type"); - } - - public boolean isNil() { return getValueType().isNilType(); } - public boolean isBoolean() { return getValueType().isBooleanType(); } - public boolean isNumber() { return getValueType().isNumberType(); } - public boolean isInteger() { return getValueType().isIntegerType(); } - public boolean isFloat() { return getValueType().isFloatType(); } - public boolean isBinary() { return getValueType().isBinaryType(); } - public boolean isString() { return getValueType().isStringType(); } - public boolean isRaw() { return getValueType().isRawType(); } - public boolean isArray() { return getValueType().isArrayType(); } - public boolean isMap() { return getValueType().isMapType(); } - public boolean isExtended() { return getValueType().isExtendedType(); } - -} diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/ArrayCursorImpl.java b/msgpack-core/src/main/java/org/msgpack/value/impl/ArrayCursorImpl.java deleted file mode 100644 index 5a5a1676e..000000000 --- a/msgpack-core/src/main/java/org/msgpack/value/impl/ArrayCursorImpl.java +++ /dev/null @@ -1,126 +0,0 @@ -package org.msgpack.value.impl; - -import org.msgpack.core.*; -import org.msgpack.value.*; -import org.msgpack.value.holder.ValueHolder; -import static org.msgpack.core.MessagePackException.UNSUPPORTED; - -import java.io.IOException; -import java.util.Iterator; - -/** - * Created on 6/16/14. - */ -public class ArrayCursorImpl extends AbstractValueRef implements ArrayCursor { - - private final ValueHolder valueHolder; - private MessageUnpacker unpacker; - private int cursor = 0; - private int arraySize; - - public ArrayCursorImpl(ValueHolder valueHolder) { - this.valueHolder = valueHolder; - } - - public void reset(MessageUnpacker unpacker) throws IOException { - this.unpacker = unpacker; - this.arraySize = unpacker.unpackArrayHeader(); - this.cursor = 0; - } - - @Override - public int size() { - return arraySize; - } - - @Override - public Iterator iterator() { - return new Iterator() { - @Override - public boolean hasNext() { - return ArrayCursorImpl.this.hasNext(); - } - @Override - public ValueRef next() { - return ArrayCursorImpl.this.next(); - } - @Override - public void remove() { - throw UNSUPPORTED("remove"); - } - }; - } - - public boolean hasNext() { - return cursor < arraySize; - } - - public ValueRef next() { - try { - unpacker.unpackValue(valueHolder); - cursor++; - return valueHolder.getRef(); - } - catch(IOException e) { - throw new MessageFormatException(e); - } - } - - @Override - public void skip() { - try { - unpacker.skipValue(); - cursor++; - } - catch(IOException e) { - throw new MessageFormatException(e); - } - } - - @Override - public void skipAll() { - while(hasNext()) { - skip(); - } - } - - - private void ensureNotTraversed() { - if(cursor != 0) - throw UNSUPPORTED("ArrayCursor is already traversed"); - } - - @Override - public ValueType getValueType() { - return ValueType.ARRAY; - } - - @Override - public ArrayCursor getArrayCursor() throws MessageTypeException { - return this; - } - - @Override - public void writeTo(MessagePacker packer) throws IOException { - ensureNotTraversed(); - packer.packArrayHeader(arraySize); - for(ValueRef v : this) { - packer.packValue(v.toValue()); - } - } - - @Override - public void accept(ValueVisitor visitor) { - visitor.visitArray(toValue()); - } - - @Override - public ArrayValue toValue() { - Value[] arr = new Value[arraySize]; - int i = 0; - for(ValueRef v : this) { - arr[i++] = v.toValue(); - } - return ValueFactory.newArray(arr); - } -} diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/ArrayValueImpl.java b/msgpack-core/src/main/java/org/msgpack/value/impl/ArrayValueImpl.java deleted file mode 100644 index c54df5992..000000000 --- a/msgpack-core/src/main/java/org/msgpack/value/impl/ArrayValueImpl.java +++ /dev/null @@ -1,162 +0,0 @@ -package org.msgpack.value.impl; - -import org.msgpack.core.MessagePacker; -import org.msgpack.core.MessageTypeException; -import org.msgpack.value.*; - -import java.io.IOException; -import java.util.Arrays; -import java.util.Iterator; - -/** -* Created on 5/30/14. -*/ -public class ArrayValueImpl extends AbstractValue implements ArrayValue { - private static ArrayValueImpl EMPTY = new ArrayValueImpl(new Value[0]); - - public static ArrayValue empty() { - return EMPTY; - } - - private int cursor = 0; - private final Value[] array; - - public ArrayValueImpl(Value[] array) { - this.array = array; - } - - public Value get(int index) { - return array[index]; - } - - public Value apply(int index) { - return array[index]; - } - - @Override - public ValueType getValueType() { - return ValueType.ARRAY; - } - - - @Override - public ArrayCursor getArrayCursor() throws MessageTypeException { - return this; - } - - @Override - public void writeTo(MessagePacker pk) throws IOException { - pk.packArrayHeader(array.length); - for(int i = 0; i < array.length; i++) { - array[i].writeTo(pk); - } - } - @Override - public void accept(ValueVisitor visitor) { - visitor.visitArray(this); - } - @Override - public ArrayValue toValue() { - return this; - } - - @Override - public boolean equals(Object o) { - if(o == this) { - return true; - } - if(!(o instanceof Value)) { - return false; - } - Value v = (Value) o; - if(!v.isArray()) { - return false; - } - Value[] other = v.asArrayValue().toValueArray(); - if(array.length != other.length) - return false; - - for(int i = 0; i < array.length; i++) { - if(!array[i].equals(other[i])) { - return false; - } - } - return true; - } - - @Override - public int hashCode() { - int h = 1; - for(int i = 0; i < array.length; i++) { - Value obj = array[i]; - h = 31 * h + obj.hashCode(); - } - return h; - } - - @Override - public String toString() { - return toString(new StringBuilder()).toString(); - } - - private StringBuilder toString(StringBuilder sb) { - if(array.length == 0) { - return sb.append("[]"); - } - sb.append("["); - sb.append(array[0]); - for(int i = 1; i < array.length; i++) { - sb.append(","); - sb.append(array[i].toString()); - } - sb.append("]"); - return sb; - } - - @Override - public int size() { - return array.length; - } - - @Override - public boolean hasNext() { - return cursor < array.length; - } - @Override - public ValueRef next() { - return array[cursor++]; - } - @Override - public void skip() { - cursor++; - } - @Override - public void skipAll() { - while(hasNext()) { - skip(); - } - } - - public Value[] toValueArray() { - return Arrays.copyOf(array, array.length); - } - - @Override - public Iterator iterator() { - return new Iterator() { - int cursor = 0; - @Override - public boolean hasNext() { - return cursor < array.length; - } - @Override - public ValueRef next() { - return array[cursor++]; - } - @Override - public void remove() { - throw new UnsupportedOperationException("remove"); - } - }; - } -} diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/BinaryValueImpl.java b/msgpack-core/src/main/java/org/msgpack/value/impl/BinaryValueImpl.java deleted file mode 100644 index 8b992f023..000000000 --- a/msgpack-core/src/main/java/org/msgpack/value/impl/BinaryValueImpl.java +++ /dev/null @@ -1,33 +0,0 @@ -package org.msgpack.value.impl; - -import org.msgpack.value.ValueType; -import org.msgpack.value.BinaryValue; -import org.msgpack.value.ValueVisitor; - -import java.nio.ByteBuffer; - -/** -* Created on 5/30/14. -*/ -public class BinaryValueImpl extends RawValueImpl implements BinaryValue { - public BinaryValueImpl(ByteBuffer byteBuffer) { - super(byteBuffer); - } - - @Override - public ValueType getValueType() { - return ValueType.BINARY; - } - @Override - public void accept(ValueVisitor visitor) { - visitor.visitBinary(this); - } - - @Override - public BinaryValue toValue() { - return this; - } - - - -} diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/BooleanValueImpl.java b/msgpack-core/src/main/java/org/msgpack/value/impl/BooleanValueImpl.java deleted file mode 100644 index 4d1cbc311..000000000 --- a/msgpack-core/src/main/java/org/msgpack/value/impl/BooleanValueImpl.java +++ /dev/null @@ -1,63 +0,0 @@ -package org.msgpack.value.impl; - -import org.msgpack.core.MessagePacker; -import org.msgpack.value.ValueType; -import org.msgpack.value.BooleanValue; -import org.msgpack.value.ValueVisitor; - -import java.io.IOException; - -/** -* Created on 5/30/14. -*/ -public class BooleanValueImpl extends AbstractValue implements BooleanValue { - - public static BooleanValue TRUE = new BooleanValueImpl(true); - public static BooleanValue FALSE = new BooleanValueImpl(false); - - private final boolean value; - - public BooleanValueImpl(boolean value) { - this.value = value; - } - - @Override - public ValueType getValueType() { - return ValueType.BOOLEAN; - } - @Override - public boolean equals(Object o) { - if (!(o instanceof BooleanValue)) - return false; - return value == ((BooleanValue) o).toBoolean(); - } - - @Override - public int hashCode() { - return 0; - } - - public String toString() { - return Boolean.toString(value); - } - - @Override - public boolean toBoolean() { - return value; - } - - @Override - public void writeTo(MessagePacker packer) throws IOException { - packer.packBoolean(value); - } - @Override - public void accept(ValueVisitor visitor) { - visitor.visitBoolean(value); - } - @Override - public BooleanValue toValue() { - return this; - } - - -} diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/CursorImpl.java b/msgpack-core/src/main/java/org/msgpack/value/impl/CursorImpl.java deleted file mode 100644 index 488ecae78..000000000 --- a/msgpack-core/src/main/java/org/msgpack/value/impl/CursorImpl.java +++ /dev/null @@ -1,134 +0,0 @@ -package org.msgpack.value.impl; - -import org.msgpack.core.*; -import org.msgpack.value.*; -import org.msgpack.value.holder.ValueHolder; -import java.io.IOException; - -/** - * Cursor implementation - */ -public class CursorImpl implements Cursor { - - private final MessageUnpacker unpacker; - private MessageFormat currentFormat; - private ValueHolder valueHolder; - - public CursorImpl(MessageUnpacker unpacker) { - this.unpacker = unpacker; - this.currentFormat = MessageFormat.NIL; - this.valueHolder = new ValueHolder(); - } - - @Override - public void remove() { - throw new UnsupportedOperationException("remove"); - } - - - @Override - public boolean hasNext() { - try { - return unpacker.hasNext(); - } - catch(IOException e) { - throw new MessageFormatException(e); - } - } - - @Override - public void skip() { - try { - unpacker.skipValue(); - } - catch(IOException e){ - throw new MessageFormatException(e); - } - } - @Override - public long getReadBytes() { - return unpacker.getTotalReadBytes(); - } - - - private final void readNext() { - try { - currentFormat = unpacker.unpackValue(valueHolder); - } - catch(IOException e) { - throw new MessageFormatException(e); - } - } - - @Override - public Value next() { - readNext(); - return valueHolder.get(); - } - - @Override - public ValueRef nextRef() { - readNext(); - return valueHolder.getRef(); - } - - private ValueType getValueType() { - return currentFormat.getValueType(); - } - - - @Override - public Out apply(Function f) { - return null; - } - - @Override - public boolean isNilValue() { - return getValueType().isNilType(); - } - @Override - public boolean isBooleanValue() { - return getValueType().isBooleanType(); - } - @Override - public boolean isNumberValue() { - return getValueType().isNumberType(); - } - @Override - public boolean isIntegerValue() { - return getValueType().isIntegerType(); - } - @Override - public boolean isFloatValue() { - return getValueType().isFloatType(); - } - @Override - public boolean isBinaryValue() { - return getValueType().isBinaryType(); - } - @Override - public boolean isStringValue() { - return getValueType().isStringType(); - } - @Override - public boolean isRawValue() { - return getValueType().isRawType(); - } - @Override - public boolean isArrayValue() { - return getValueType().isArrayType(); - } - @Override - public boolean isMapValue() { - return getValueType().isMapType(); - } - @Override - public boolean isExtendedValue() { - return getValueType().isExtendedType(); - } - - @Override - public void close() throws IOException { - unpacker.close(); - } -} diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/DoubleValueImpl.java b/msgpack-core/src/main/java/org/msgpack/value/impl/DoubleValueImpl.java deleted file mode 100644 index e8382a344..000000000 --- a/msgpack-core/src/main/java/org/msgpack/value/impl/DoubleValueImpl.java +++ /dev/null @@ -1,152 +0,0 @@ -package org.msgpack.value.impl; - -import org.msgpack.core.MessageFloatOverflowException; -import org.msgpack.core.MessageOverflowException; -import org.msgpack.core.MessagePacker; -import org.msgpack.value.*; - -import java.io.IOException; -import java.math.BigDecimal; -import java.math.BigInteger; - -/** -* Created on 5/30/14. -*/ -public class DoubleValueImpl extends AbstractValue implements FloatValue { - private final double value; - - public DoubleValueImpl(double value) { - this.value = value; - } - - @Override - public ValueType getValueType() { - return ValueType.FLOAT; - } - - @Override - public boolean isValidByte() { - return ((double) ((byte) value)) == value; - } - @Override - public boolean isValidShort() { - return ((double) ((short) value)) == value; - } - @Override - public boolean isValidInt() { - return ((double) ((int) value)) == value; - } - @Override - public boolean isValidLong() { - long l = (long) value; - return ((double) l) == value && l != Long.MAX_VALUE; - } - @Override - public boolean isWhole() { - long l = (long) value; - return ((double) l == value) || l == Long.MAX_VALUE && value < Double.POSITIVE_INFINITY || l == Long.MIN_VALUE && value > Double.NEGATIVE_INFINITY; - } - @Override - public byte toByte() { - return (byte) value; - } - - @Override - public short toShort() { - return (short) value; - } - - @Override - public int toInt() { - return (int) value; - } - - @Override - public long toLong() { - return (long) value; - } - - @Override - public BigInteger toBigInteger() { - return new BigDecimal(value).toBigInteger(); - } - - @Override - public float toFloat() { - return (float) value; - } - - @Override - public double toDouble() { - return value; - } - @Override - public byte asByte() throws MessageOverflowException { - if(!isValidByte()) - throw new MessageFloatOverflowException(value); - return (byte) value; - } - @Override - public short asShort() throws MessageOverflowException { - if(!isValidShort()) - throw new MessageFloatOverflowException(value); - return (short) value; - } - @Override - public int asInt() throws MessageOverflowException { - if(!isValidInt()) - throw new MessageFloatOverflowException(value); - return (int) value; - } - @Override - public long asLong() throws MessageOverflowException { - if(!isValidLong()) - throw new MessageFloatOverflowException(value); - return (long) value; - } - @Override - public BigInteger asBigInteger() throws MessageOverflowException { - if(!isWhole()) - throw new MessageFloatOverflowException(value); - return new BigDecimal(value).toBigInteger(); - } - - @Override - public boolean equals(Object o) { - if (o == this) { - return true; - } - if (!(o instanceof Value)) { - return false; - } - Value v = (Value) o; - if (!v.isFloat()) { - return false; - } - return value == v.asFloat().toDouble(); - } - - @Override - public FloatValue toValue() { - return ValueFactory.newDouble(value); - } - @Override - public void writeTo(MessagePacker pk) throws IOException { - pk.packDouble(value); - } - @Override - public void accept(ValueVisitor visitor) { - visitor.visitFloat(this); - } - - @Override - public int hashCode() { - long v = Double.doubleToLongBits(value); - return (int) (v ^ (v >>> 32)); - } - - @Override - public String toString() { - return Double.toString(value); - } -} diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/ExtendedValueImpl.java b/msgpack-core/src/main/java/org/msgpack/value/impl/ExtendedValueImpl.java deleted file mode 100644 index 1591b6308..000000000 --- a/msgpack-core/src/main/java/org/msgpack/value/impl/ExtendedValueImpl.java +++ /dev/null @@ -1,50 +0,0 @@ -package org.msgpack.value.impl; - -import org.msgpack.core.MessagePacker; -import org.msgpack.value.ValueType; -import org.msgpack.value.ExtendedValue; -import org.msgpack.value.ValueVisitor; - -import java.io.IOException; -import java.nio.ByteBuffer; - -/** - * Extended value implementation - */ -public class ExtendedValueImpl extends RawValueImpl implements ExtendedValue { - - private final int type; - - - public ExtendedValueImpl(int type, ByteBuffer data) { - super(data); - this.type = type; - } - - @Override - public ValueType getValueType() { - return ValueType.EXTENDED; - } - @Override - public void writeTo(MessagePacker packer) throws IOException { - packer.packExtendedTypeHeader(type, byteBuffer.remaining()); - packer.writePayload(byteBuffer); - } - - @Override - public void accept(ValueVisitor visitor) { - visitor.visitExtended(this); - } - - @Override - public ExtendedValue toValue() { - return this; - } - - @Override - public int getExtType() { - return type; - } - - -} diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/FloatValueImpl.java b/msgpack-core/src/main/java/org/msgpack/value/impl/FloatValueImpl.java deleted file mode 100644 index 644b81aaa..000000000 --- a/msgpack-core/src/main/java/org/msgpack/value/impl/FloatValueImpl.java +++ /dev/null @@ -1,159 +0,0 @@ -package org.msgpack.value.impl; - -import org.msgpack.core.MessageFloatOverflowException; -import org.msgpack.core.MessageOverflowException; -import org.msgpack.core.MessagePacker; -import org.msgpack.value.*; - -import java.io.IOException; -import java.math.BigDecimal; -import java.math.BigInteger; - -/** -* Created on 5/30/14. -*/ -public class FloatValueImpl extends AbstractValue implements FloatValue { - private final float value; - - public FloatValueImpl(float value) { - this.value = value; - } - - @Override - public ValueType getValueType() { - return ValueType.FLOAT; - } - - @Override - public boolean isValidByte() { - return (float) ((byte) value) == value; - } - @Override - public boolean isValidShort() { - return (float) ((short) value) == value; - } - @Override - public boolean isValidInt() { - int i = (int) value; - return ((float) i) == value && i != Integer.MAX_VALUE; - } - @Override - public boolean isValidLong() { - long l = (long) value; - return ((float) l) == value && l != Long.MAX_VALUE; - } - - @Override - public boolean isWhole() { - long l = (long) value; - return ((float) l) == value || l == Long.MAX_VALUE || value < Float.POSITIVE_INFINITY || l == Long.MIN_VALUE && value > Float.NEGATIVE_INFINITY; - } - - @Override - public byte toByte() { - return (byte) value; - } - - @Override - public short toShort() { - return (short) value; - } - - @Override - public int toInt() { - return (int) value; - } - - @Override - public long toLong() { - return (long) value; - } - - @Override - public BigInteger toBigInteger() { - return new BigDecimal((double) value).toBigInteger(); - } - - @Override - public float toFloat() { - return value; - } - - @Override - public double toDouble() { - return (double) value; - } - @Override - public byte asByte() throws MessageOverflowException { - if (!isValidByte()) { - throw new MessageFloatOverflowException(value); - } - return (byte) value; - } - @Override - public short asShort() throws MessageOverflowException { - if(!isValidShort()) - throw new MessageFloatOverflowException(value); - return (short) value; - } - @Override - public int asInt() throws MessageOverflowException { - if(!isValidInt()) - throw new MessageFloatOverflowException(value); - return (int) value; - } - - @Override - public long asLong() throws MessageOverflowException { - if(!isValidLong()) - throw new MessageFloatOverflowException(value); - return (long) value; - } - - @Override - public BigInteger asBigInteger() throws MessageOverflowException { - if(!isWhole()) - throw new MessageFloatOverflowException(value); - - return BigDecimal.valueOf(value).toBigInteger(); - } - - @Override - public boolean equals(Object o) { - if (o == this) { - return true; - } - if (!(o instanceof Value)) { - return false; - } - Value v = (Value) o; - if (!v.isFloat()) { - return false; - } - return (double) value == v.asFloat().toDouble(); - } - - @Override - public void writeTo(MessagePacker pk) throws IOException { - pk.packFloat(value); - } - @Override - public void accept(ValueVisitor visitor) { - visitor.visitFloat(this); - } - @Override - public FloatValue toValue() { - return this; - } - - @Override - public int hashCode() { - long v = Double.doubleToLongBits((double) value); - return (int) (v ^ (v >>> 32)); - } - - @Override - public String toString() { - return Float.toString(value); - } -} diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableArrayValueImpl.java b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableArrayValueImpl.java new file mode 100644 index 000000000..e32577cd4 --- /dev/null +++ b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableArrayValueImpl.java @@ -0,0 +1,210 @@ +// +// MessagePack for Java +// +// 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.value.impl; + +import org.msgpack.core.MessagePacker; +import org.msgpack.value.Value; +import org.msgpack.value.ValueType; +import org.msgpack.value.ArrayValue; +import org.msgpack.value.ImmutableArrayValue; + +import java.util.List; +import java.util.AbstractList; +import java.util.Arrays; +import java.util.Iterator; +import java.util.NoSuchElementException; +import java.io.IOException; + + +/** + * {@code ImmutableArrayValueImpl} Implements {@code ImmutableArrayValue} using a {@code Value[]} field. + * + * @see org.msgpack.value.IntegerValue + */ +public class ImmutableArrayValueImpl extends AbstractImmutableValue implements ImmutableArrayValue { + private static ImmutableArrayValueImpl EMPTY = new ImmutableArrayValueImpl(new Value[0]); + + public static ImmutableArrayValue empty() { + return EMPTY; + } + + private final Value[] array; + + public ImmutableArrayValueImpl(Value[] array) { + this.array = array; + } + + @Override + public ValueType getValueType() { + return ValueType.ARRAY; + } + + @Override + public ImmutableArrayValue immutableValue() { + return this; + } + + @Override + public ImmutableArrayValue asArrayValue() { + return this; + } + + @Override + public int size() { + return array.length; + } + + @Override + public Value get(int index) { + return array[index]; + } + + @Override + public Value getOrNilValue(int index) { + if (array.length < index && index >= 0) { + return array[index]; + } + return ImmutableNilValueImpl.get(); + } + + @Override + public Iterator iterator() { + return new Ite(array); + } + + @Override + public List list() { + return new ImmutableArrayValueList(array); + } + + @Override + public void writeTo(MessagePacker pk) throws IOException { + pk.packArrayHeader(array.length); + for(int i = 0; i < array.length; i++) { + array[i].writeTo(pk); + } + } + + @Override + public boolean equals(Object o) { + if(o == this) { + return true; + } + if(!(o instanceof Value)) { + return false; + } + Value v = (Value) o; + + if (v instanceof ImmutableArrayValueImpl) { + ImmutableArrayValueImpl oa = (ImmutableArrayValueImpl) v; + return Arrays.equals(array, oa.array); + } else { + if(!v.isArrayValue()) { + return false; + } + ArrayValue av = v.asArrayValue(); + if (size() != av.size()) { + return false; + } + Iterator oi = av.iterator(); + int i = 0; + while (i < array.length) { + if (!oi.hasNext() || !array[i].equals(oi.next())) { + return false; + } + i++; + } + return true; + } + } + + @Override + public int hashCode() { + int h = 1; + for(int i = 0; i < array.length; i++) { + Value obj = array[i]; + h = 31 * h + obj.hashCode(); + } + return h; + } + + @Override + public String toString() { + return toString(new StringBuilder()).toString(); + } + + private StringBuilder toString(StringBuilder sb) { + if(array.length == 0) { + return sb.append("[]"); + } + sb.append("["); + sb.append(array[0]); + for(int i = 1; i < array.length; i++) { + sb.append(","); + sb.append(array[i].toString()); + } + sb.append("]"); + return sb; + } + + private static class ImmutableArrayValueList extends AbstractList { + private final Value[] array; + + public ImmutableArrayValueList(Value[] array) { + this.array = array; + } + + @Override + public Value get(int index) { + return array[index]; + } + + @Override + public int size() { + return array.length; + } + } + + private static class Ite implements Iterator { + private final Value[] array; + private int index; + + public Ite(Value[] array) { + this.array = array; + this.index = 0; + } + + @Override + public boolean hasNext() { + return index != array.length; + } + + @Override + public Value next() { + int i = index; + if (i >= array.length) { + throw new NoSuchElementException(); + } + index = i + 1; + return array[i]; + } + + @Override + public void remove() { + throw new UnsupportedOperationException(); + } + } +} diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/BigIntegerValueImpl.java b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableBigIntegerValueImpl.java similarity index 62% rename from msgpack-core/src/main/java/org/msgpack/value/impl/BigIntegerValueImpl.java rename to msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableBigIntegerValueImpl.java index 85af4a176..34b17f8f2 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/impl/BigIntegerValueImpl.java +++ b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableBigIntegerValueImpl.java @@ -1,26 +1,42 @@ +// +// MessagePack for Java +// +// 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.value.impl; -import org.msgpack.core.MessageIntegerOverflowException; import org.msgpack.core.MessagePacker; +import org.msgpack.core.MessageIntegerOverflowException; +import org.msgpack.value.Value; import org.msgpack.value.ValueType; import org.msgpack.value.IntegerValue; -import org.msgpack.value.Value; -import org.msgpack.value.ValueVisitor; +import org.msgpack.value.ImmutableNumberValue; +import org.msgpack.value.ImmutableIntegerValue; import java.io.IOException; import java.math.BigInteger; -import static org.msgpack.core.Preconditions.checkNotNull; /** -* Created on 5/30/14. -*/ -public class BigIntegerValueImpl extends AbstractValue implements IntegerValue { - + * {@code ImmutableBigIntegerValueImpl} Implements {@code ImmutableBigIntegerValue} using a {@code BigInteger} field. + * + * @see org.msgpack.value.IntegerValue + */ +public class ImmutableBigIntegerValueImpl extends AbstractImmutableValue implements ImmutableIntegerValue { private final BigInteger value; - public BigIntegerValueImpl(BigInteger value) { - this.value = checkNotNull(value, "BigInteger value is null"); + public ImmutableBigIntegerValueImpl(BigInteger value) { + this.value = value; } private static final BigInteger BYTE_MIN = BigInteger.valueOf((long) Byte.MIN_VALUE); @@ -38,113 +54,116 @@ public ValueType getValueType() { } @Override - public byte toByte() { + public ImmutableIntegerValue immutableValue() { + return this; + } + + @Override + public ImmutableNumberValue asNumberValue() { + return this; + } + + @Override + public ImmutableIntegerValue asIntegerValue() { + return this; + } + + @Override + public byte byteValue() { return value.byteValue(); } @Override - public short toShort() { + public short shortValue() { return value.shortValue(); } @Override - public int toInt() { + public int intValue() { return value.intValue(); } @Override - public long toLong() { + public long longValue() { return value.longValue(); } @Override - public BigInteger toBigInteger() { + public BigInteger bigIntegerValue() { return value; } @Override - public float toFloat() { + public float floatValue() { return value.floatValue(); } @Override - public double toDouble() { + public double doubleValue() { return value.doubleValue(); } @Override - public byte asByte() throws MessageIntegerOverflowException { - if (!isValidByte()) { + public boolean isInByteRange() { + return 0 <= value.compareTo(BYTE_MIN) && value.compareTo(BYTE_MAX) <= 0; + } + + @Override + public boolean isInShortRange() { + return 0 <= value.compareTo(SHORT_MIN) && value.compareTo(SHORT_MAX) <= 0; + } + + @Override + public boolean isInIntRange() { + return 0 <= value.compareTo(INT_MIN) && value.compareTo(INT_MAX) <= 0; + } + + @Override + public boolean isInLongRange() { + return 0 <= value.compareTo(LONG_MIN) && value.compareTo(LONG_MAX) <= 0; + } + + @Override + public byte getByte() { + if (!isInByteRange()) { throw new MessageIntegerOverflowException(value); } return value.byteValue(); } @Override - public short asShort() throws MessageIntegerOverflowException { - if (!isValidShort()) { + public short getShort() { + if (!isInShortRange()) { throw new MessageIntegerOverflowException(value); } return value.shortValue(); } @Override - public int asInt() throws MessageIntegerOverflowException { - if (!isValidInt()) { + public int getInt() { + if (!isInIntRange()) { throw new MessageIntegerOverflowException(value); } return value.intValue(); } @Override - public long asLong() throws MessageIntegerOverflowException { - if (!isValidLong()) { + public long getLong() { + if (!isInLongRange()) { throw new MessageIntegerOverflowException(value); } return value.longValue(); } @Override - public BigInteger asBigInteger() throws MessageIntegerOverflowException { + public BigInteger getBigInteger() { return value; } - @Override - public boolean isValidByte() { - return 0 <= value.compareTo(BYTE_MIN) && value.compareTo(BYTE_MAX) <= 0; - } - - @Override - public boolean isValidShort() { - return 0 <= value.compareTo(SHORT_MIN) && value.compareTo(SHORT_MAX) <= 0; - } - - @Override - public boolean isValidInt() { - return 0 <= value.compareTo(INT_MIN) && value.compareTo(INT_MAX) <= 0; - } - - @Override - public boolean isValidLong() { - return 0 <= value.compareTo(LONG_MIN) && value.compareTo(LONG_MAX) <= 0; - } - @Override - public boolean isWhole() { - return true; - } - @Override public void writeTo(MessagePacker pk) throws IOException { pk.packBigInteger(value); } - @Override - public void accept(ValueVisitor visitor) { - visitor.visitInteger(this); - } - @Override - public IntegerValue toValue() { - return this; - } @Override public boolean equals(Object o) { @@ -155,11 +174,12 @@ public boolean equals(Object o) { return false; } Value v = (Value) o; - if (!v.isInteger()) { + + if (!v.isIntegerValue()) { return false; } - IntegerValue iv = v.asInteger(); - return value.equals(iv.toBigInteger()); + IntegerValue iv = v.asIntegerValue(); + return value.equals(iv.bigIntegerValue()); } @Override diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableBinaryValueImpl.java b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableBinaryValueImpl.java new file mode 100644 index 000000000..c9ebfd313 --- /dev/null +++ b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableBinaryValueImpl.java @@ -0,0 +1,84 @@ +// +// MessagePack for Java +// +// 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.value.impl; + +import org.msgpack.core.MessagePacker; +import org.msgpack.value.Value; +import org.msgpack.value.ValueType; +import org.msgpack.value.ImmutableBinaryValue; + +import java.util.Arrays; +import java.io.IOException; + + +/** + * {@code ImmutableBinaryValueImpl} Implements {@code ImmutableBinaryValue} using a {@code byte[]} field. + * This implementation caches result of {@code stringValue()} and {@code getString()} using a private {@code String} field. + * + * @see org.msgpack.value.StringValue + */ +public class ImmutableBinaryValueImpl extends AbstractImmutableRawValue implements ImmutableBinaryValue { + public ImmutableBinaryValueImpl(byte[] data) { + super(data); + } + + @Override + public ValueType getValueType() { + return ValueType.BINARY; + } + + @Override + public ImmutableBinaryValue immutableValue() { + return this; + } + + @Override + public ImmutableBinaryValue asBinaryValue() { + return this; + } + + @Override + public void writeTo(MessagePacker pk) throws IOException { + pk.packBinaryHeader(data.length); + pk.writePayload(data); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof Value)) { + return false; + } + Value v = (Value) o; + if (!v.isBinaryValue()) { + return false; + } + + if (v instanceof ImmutableBinaryValueImpl) { + ImmutableBinaryValueImpl bv = (ImmutableBinaryValueImpl) v; + return Arrays.equals(data, bv.data); + } else { + return Arrays.equals(data, v.asBinaryValue().getByteArray()); + } + } + + @Override + public int hashCode() { + return Arrays.hashCode(data); + } +} diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableBooleanValueImpl.java b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableBooleanValueImpl.java new file mode 100644 index 000000000..84ef95c44 --- /dev/null +++ b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableBooleanValueImpl.java @@ -0,0 +1,101 @@ +// +// MessagePack for Java +// +// 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.value.impl; + +import org.msgpack.core.MessagePacker; +import org.msgpack.value.Value; +import org.msgpack.value.ValueType; +import org.msgpack.value.BooleanValue; +import org.msgpack.value.ImmutableBooleanValue; + +import java.io.IOException; + + +/** + * {@code ImmutableBooleanValueImpl} Implements {@code ImmutableBooleanValue} using a {@code boolean} field. + * + * This class is a singleton. {@code ImmutableBooleanValueImpl.trueInstance()} and {@code ImmutableBooleanValueImpl.falseInstance()} are the only instances of this class. + * + * @see org.msgpack.value.BooleanValue + */ +public class ImmutableBooleanValueImpl extends AbstractImmutableValue implements ImmutableBooleanValue { + public static ImmutableBooleanValue TRUE = new ImmutableBooleanValueImpl(true); + public static ImmutableBooleanValue FALSE = new ImmutableBooleanValueImpl(false); + + private final boolean value; + + private ImmutableBooleanValueImpl(boolean value) { + this.value = value; + } + + public static ImmutableBooleanValue trueInstance() { + return TRUE; + } + + public static ImmutableBooleanValue falseInstance() { + return FALSE; + } + + @Override + public ValueType getValueType() { + return ValueType.BOOLEAN; + } + + @Override + public ImmutableBooleanValue immutableValue() { + return this; + } + + @Override + public boolean getBoolean() { + return value; + } + + @Override + public void writeTo(MessagePacker packer) throws IOException { + packer.packBoolean(value); + } + + @Override + public boolean equals(Object o) { + if (o == this) { + return true; + } + if (!(o instanceof Value)) { + return false; + } + Value v = (Value) o; + + if (!v.isBooleanValue()) { + return false; + } + return value == v.asBooleanValue().getBoolean(); + } + + @Override + public int hashCode() { + if (value) { + return 1231; + } else { + return 1237; + } + } + + @Override + public String toString() { + return Boolean.toString(value); + } +} diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableDoubleValueImpl.java b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableDoubleValueImpl.java new file mode 100644 index 000000000..abe53166b --- /dev/null +++ b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableDoubleValueImpl.java @@ -0,0 +1,116 @@ +// +// MessagePack for Java +// +// 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.value.impl; + +import org.msgpack.core.MessagePacker; +import org.msgpack.value.Value; +import org.msgpack.value.ValueType; +import org.msgpack.value.FloatValue; +import org.msgpack.value.ImmutableFloatValue; + +import java.io.IOException; +import java.math.BigInteger; + + +/** + * {@code ImmutableDoubleValueImpl} Implements {@code ImmutableFloatValue} using a {@code double} field. + * + * @see org.msgpack.value.FloatValue + */ +public class ImmutableDoubleValueImpl extends AbstractImmutableValue implements ImmutableFloatValue { + private final double value; + + public ImmutableDoubleValueImpl(double value) { + this.value = value; + } + + @Override + public ValueType getValueType() { + return ValueType.FLOAT; + } + + @Override + public ImmutableDoubleValueImpl immutableValue() { + return this; + } + + @Override + public byte byteValue() { + return (byte) value; + } + + @Override + public short shortValue() { + return (short) value; + } + + @Override + public int intValue() { + return (int) value; + } + + @Override + public long longValue() { + return (long) value; + } + + @Override + public BigInteger bigIntegerValue() { + return BigInteger.valueOf((long) value); + } + + @Override + public float floatValue() { + return (float) value; + } + + @Override + public double doubleValue() { + return value; + } + + @Override + public void writeTo(MessagePacker pk) throws IOException { + pk.packDouble(value); + } + + @Override + public boolean equals(Object o) { + if (o == this) { + return true; + } + if (!(o instanceof Value)) { + return false; + } + Value v = (Value) o; + + if (!v.isFloatValue()) { + return false; + } + return value == v.asFloatValue().doubleValue(); + } + + @Override + public int hashCode() { + long v = Double.doubleToLongBits(value); + return (int) (v ^ (v >>> 32)); + } + + @Override + public String toString() { + return Double.toString(value); + } +} diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableExtendedValueImpl.java b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableExtendedValueImpl.java new file mode 100644 index 000000000..8ff5af324 --- /dev/null +++ b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableExtendedValueImpl.java @@ -0,0 +1,111 @@ +// +// MessagePack for Java +// +// 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.value.impl; + +import org.msgpack.core.MessagePacker; +import org.msgpack.value.Value; +import org.msgpack.value.ValueType; +import org.msgpack.value.ExtendedValue; +import org.msgpack.value.ImmutableExtendedValue; + +import java.util.Arrays; +import java.io.IOException; + + +/** + * {@code ImmutableExtendedValueImpl} Implements {@code ImmutableExtendedValue} using a {@code byte} and a {@code byte[]} fields. + * + * @see org.msgpack.value.ExtendedValue + */ +public class ImmutableExtendedValueImpl extends AbstractImmutableValue implements ImmutableExtendedValue { + private final byte type; + private final byte[] data; + + public ImmutableExtendedValueImpl(byte type, byte[] data) { + this.type = type; + this.data = data; + } + + @Override + public ValueType getValueType() { + return ValueType.EXTENDED; + } + + @Override + public ImmutableExtendedValue immutableValue() { + return this; + } + + @Override + public ImmutableExtendedValue asExtendedValue() { + return this; + } + + @Override + public byte getType() { + return type; + } + + @Override + public byte[] getData() { + return data; + } + + @Override + public void writeTo(MessagePacker packer) throws IOException { + packer.packExtendedTypeHeader(type, data.length); + packer.writePayload(data); + } + + @Override + public boolean equals(Object o) { + if (o == this) { + return true; + } + if (!(o instanceof Value)) { + return false; + } + Value v = (Value) o; + + if (!v.isExtendedValue()) { + return false; + } + ExtendedValue ev = v.asExtendedValue(); + return type == ev.getType() && Arrays.equals(data, ev.getData()); + } + + @Override + public int hashCode() { + int hash = 31 + type; + for (byte e : data) { + hash = 31 * hash + e; + } + return hash; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append('('); + sb.append(Byte.toString(type)); + sb.append(",0x"); + for (byte e : data) { + sb.append(Integer.toString((int) e, 16)); + } + sb.append(")"); + return sb.toString(); + } +} diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/LongValueImpl.java b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableLongValueImpl.java similarity index 57% rename from msgpack-core/src/main/java/org/msgpack/value/impl/LongValueImpl.java rename to msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableLongValueImpl.java index 57346fe11..78c724cb5 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/impl/LongValueImpl.java +++ b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableLongValueImpl.java @@ -1,23 +1,41 @@ +// +// MessagePack for Java +// +// 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.value.impl; -import org.msgpack.core.MessageIntegerOverflowException; import org.msgpack.core.MessagePacker; +import org.msgpack.core.MessageIntegerOverflowException; import org.msgpack.value.ValueType; -import org.msgpack.value.IntegerValue; import org.msgpack.value.Value; -import org.msgpack.value.ValueVisitor; +import org.msgpack.value.IntegerValue; +import org.msgpack.value.ImmutableIntegerValue; +import org.msgpack.value.ImmutableNumberValue; import java.io.IOException; import java.math.BigInteger; -/** -* Created on 5/30/14. -*/ -public class LongValueImpl extends AbstractValue implements IntegerValue { +/** + * {@code ImmutableLongValueImpl} Implements {@code ImmutableIntegerValue} using a {@code long} field. + * + * @see org.msgpack.value.IntegerValue + */ +public class ImmutableLongValueImpl extends AbstractImmutableValue implements ImmutableIntegerValue { private final long value; - public LongValueImpl(long value) { + public ImmutableLongValueImpl(long value) { this.value = value; } @@ -34,115 +52,113 @@ public ValueType getValueType() { } @Override - public IntegerValue asInteger() { + public ImmutableIntegerValue immutableValue() { + return this; + } + + @Override + public ImmutableNumberValue asNumberValue() { + return this; + } + + @Override + public ImmutableIntegerValue asIntegerValue() { return this; } @Override - public byte toByte() { + public byte byteValue() { return (byte) value; } @Override - public short toShort() { + public short shortValue() { return (short) value; } @Override - public int toInt() { + public int intValue() { return (int) value; } @Override - public long toLong() { + public long longValue() { return value; } @Override - public BigInteger toBigInteger() { + public BigInteger bigIntegerValue() { return BigInteger.valueOf(value); } @Override - public float toFloat() { + public float floatValue() { return (float) value; } @Override - public double toDouble() { + public double doubleValue() { return (double) value; } @Override - public byte asByte() throws MessageIntegerOverflowException { - if (!isValidByte()) { - throw new MessageIntegerOverflowException(value); - } - return (byte) value; + public boolean isInByteRange() { + return BYTE_MIN <= value && value <= BYTE_MAX; } @Override - public short asShort() throws MessageIntegerOverflowException { - if (!isValidShort()) { - throw new MessageIntegerOverflowException(value); - } - return (short) value; + public boolean isInShortRange() { + return SHORT_MIN <= value && value <= SHORT_MAX; } @Override - public int asInt() throws MessageIntegerOverflowException { - if (!isValidInt()) { - throw new MessageIntegerOverflowException(value); - } - return (int) value; + public boolean isInIntRange() { + return INT_MIN <= value && value <= INT_MAX; } @Override - public long asLong() throws MessageIntegerOverflowException { - return value; + public boolean isInLongRange() { + return true; } @Override - public BigInteger asBigInteger() throws MessageIntegerOverflowException { - return BigInteger.valueOf(value); + public byte getByte() { + if (!isInByteRange()) { + throw new MessageIntegerOverflowException(value); + } + return (byte) value; } @Override - public boolean isValidByte() { - return BYTE_MIN <= value && value <= BYTE_MAX; + public short getShort() { + if (!isInByteRange()) { + throw new MessageIntegerOverflowException(value); + } + return (short) value; } @Override - public boolean isValidShort() { - return SHORT_MIN <= value && value <= SHORT_MAX; + public int getInt() { + if (!isInIntRange()) { + throw new MessageIntegerOverflowException(value); + } + return (int) value; } @Override - public boolean isValidInt() { - return INT_MIN <= value && value <= INT_MAX; + public long getLong() { + return value; } @Override - public boolean isValidLong() { - return true; - } - @Override - public boolean isWhole() { - return true; + public BigInteger getBigInteger() { + return BigInteger.valueOf((long) value); } @Override public void writeTo(MessagePacker pk) throws IOException { pk.packLong(value); } - @Override - public void accept(ValueVisitor visitor) { - visitor.visitInteger(this); - } - @Override - public IntegerValue toValue() { - return this; - } @Override public boolean equals(Object o) { @@ -153,14 +169,15 @@ public boolean equals(Object o) { return false; } Value v = (Value) o; - if (!v.isInteger()) { + if (!v.isIntegerValue()) { return false; } - IntegerValue iv = v.asInteger(); - if (!iv.isValidLong()) { + + IntegerValue iv = v.asIntegerValue(); + if (!iv.isInLongRange()) { return false; } - return value == iv.toLong(); + return value == iv.longValue(); } @Override diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableMapValueImpl.java b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableMapValueImpl.java new file mode 100644 index 000000000..51d504f07 --- /dev/null +++ b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableMapValueImpl.java @@ -0,0 +1,310 @@ +// +// MessagePack for Java +// +// 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.value.impl; + +import org.msgpack.core.MessagePacker; +import org.msgpack.value.Value; +import org.msgpack.value.ValueType; +import org.msgpack.value.MapValue; +import org.msgpack.value.ImmutableMapValue; + +import java.io.IOException; +import java.util.Map; +import java.util.Set; +import java.util.Collection; +import java.util.AbstractMap; +import java.util.AbstractSet; +import java.util.AbstractCollection; +import java.util.Iterator; +import java.util.Arrays; +import java.util.NoSuchElementException; + + +/** + * {@code ImmutableMapValueImpl} Implements {@code ImmutableMapValue} using a {@code Value[]} field. + * + * @see org.msgpack.value.MapValue + */ +public class ImmutableMapValueImpl extends AbstractImmutableValue implements ImmutableMapValue { + private static ImmutableMapValueImpl EMPTY = new ImmutableMapValueImpl(new Value[0]); + + public static ImmutableMapValue empty() { + return EMPTY; + } + + private final Value[] kvs; + + public ImmutableMapValueImpl(Value[] kvs) { + this.kvs = kvs; + } + + @Override + public ValueType getValueType() { + return ValueType.MAP; + } + + @Override + public ImmutableMapValue immutableValue() { + return this; + } + + @Override + public ImmutableMapValue asMapValue() { + return this; + } + + @Override + public Value[] getKeyValueArray() { + return Arrays.copyOf(kvs, kvs.length); + } + + @Override + public int size() { + return kvs.length / 2; + } + + @Override + public Set keySet() { + return new KeySet(kvs); + } + + @Override + public Set> entrySet() { + return new EntrySet(kvs); + } + + @Override + public Collection values() { + return new ValueCollection(kvs); + } + + @Override + public Map map() { + return new ImmutableMapValueMap(kvs); + } + + @Override + public void writeTo(MessagePacker pk) throws IOException { + pk.packMapHeader(kvs.length / 2); + for (int i = 0; i < kvs.length; i++) { + kvs[i].writeTo(pk); + } + } + + @Override + public boolean equals(Object o) { + if (o == this) { + return true; + } + if (!(o instanceof Value)) { + return false; + } + Value v = (Value) o; + + if (v instanceof ImmutableMapValueImpl) { + ImmutableMapValueImpl om = (ImmutableMapValueImpl) v; + return Arrays.equals(kvs, om.kvs); + } else { + if (!v.isMapValue()) { + return false; + } + MapValue mv = v.asMapValue(); + if (size() != mv.size()) { + return false; + } + Map m = mv.map(); + Iterator> ite = entrySet().iterator(); + while (ite.hasNext()) { + Map.Entry e = ite.next(); + Value ek = e.getKey(); + Value ev = e.getValue(); + if (ev == null) { + if (!(m.get(ek) == null && m.containsKey(ek))) { + return false; + } + } else { + if (!ev.equals(m.get(ek))) { + return false; + } + } + } + return true; + } + } + + @Override + public int hashCode() { + int h = 0; + for (int i = 0; i < kvs.length; i += 2) { + h += kvs[i].hashCode() ^ kvs[i + 1].hashCode(); + } + return h; + } + + @Override + public String toString() { + return toString(new StringBuilder()).toString(); + } + + private StringBuilder toString(StringBuilder sb) { + if (kvs.length == 0) { + return sb.append("{}"); + } + sb.append("{"); + sb.append(kvs[0]); + sb.append(":"); + sb.append(kvs[1]); + for (int i = 2; i < kvs.length; i += 2) { + sb.append(","); + sb.append(kvs[i].toString()); + sb.append(":"); + sb.append(kvs[i + 1].toString()); + } + sb.append("}"); + return sb; + } + + private static class ImmutableMapValueMap extends AbstractMap { + private final Value[] kvs; + + public ImmutableMapValueMap(Value[] kvs) { + this.kvs = kvs; + } + + @Override + public Set> entrySet() { + return new EntrySet(kvs); + } + } + + private static class EntrySet extends AbstractSet> { + private final Value[] kvs; + + EntrySet(Value[] kvs) { + this.kvs = kvs; + } + + @Override + public int size() { + return kvs.length / 2; + } + + @Override + public Iterator> iterator() { + return new EntrySetIterator(kvs); + } + } + + private static class EntrySetIterator implements Iterator> { + private final Value[] kvs; + private int index; + + EntrySetIterator(Value[] kvs) { + this.kvs = kvs; + this.index = 0; + } + + @Override + public boolean hasNext() { + return index < kvs.length; + } + + @Override + public Map.Entry next() { + if (index >= kvs.length) { + throw new NoSuchElementException(); // TODO message + } + + Value key = kvs[index]; + Value value = kvs[index + 1]; + Map.Entry pair = new AbstractMap.SimpleImmutableEntry(key, value); + + index += 2; + return pair; + } + + @Override + public void remove() { + throw new UnsupportedOperationException(); // TODO message + } + } + + private static class KeySet extends AbstractSet { + private Value[] kvs; + + KeySet(Value[] kvs) { + this.kvs = kvs; + } + + @Override + public int size() { + return kvs.length / 2; + } + + @Override + public Iterator iterator() { + return new EntryIterator(kvs, 0); + } + } + + private static class ValueCollection extends AbstractCollection { + private Value[] kvs; + + ValueCollection(Value[] kvs) { + this.kvs = kvs; + } + + @Override + public int size() { + return kvs.length / 2; + } + + @Override + public Iterator iterator() { + return new EntryIterator(kvs, 1); + } + } + + private static class EntryIterator implements Iterator { + private Value[] kvs; + private int index; + + public EntryIterator(Value[] kvs, int offset) { + this.kvs = kvs; + this.index = offset; + } + + @Override + public boolean hasNext() { + return index < kvs.length; + } + + @Override + public Value next() { + int i = index; + if (i >= kvs.length) { + throw new NoSuchElementException(); + } + index = i + 2; + return kvs[i]; + } + + @Override + public void remove() { + throw new UnsupportedOperationException(); + } + } +} diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableNilValueImpl.java b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableNilValueImpl.java new file mode 100644 index 000000000..c8f9c3bcc --- /dev/null +++ b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableNilValueImpl.java @@ -0,0 +1,82 @@ +// +// MessagePack for Java +// +// 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.value.impl; + +import org.msgpack.core.MessagePacker; +import org.msgpack.value.Value; +import org.msgpack.value.ValueType; +import org.msgpack.value.ImmutableNilValue; + +import java.io.IOException; + + +/** + * {@code ImmutableNilValueImpl} Implements {@code ImmutableNilValue}. + * + * This class is a singleton. {@code ImmutableNilValueImpl.get()} is the only instances of this class. + * + * @see org.msgpack.value.NilValue + */ +public class ImmutableNilValueImpl extends AbstractImmutableValue implements ImmutableNilValue { + private static ImmutableNilValue instance = new ImmutableNilValueImpl(); + + public static ImmutableNilValue get() { + return instance; + } + + private ImmutableNilValueImpl() { } + + @Override + public ValueType getValueType() { + return ValueType.NIL; + } + + @Override + public ImmutableNilValue immutableValue() { + return this; + } + + @Override + public ImmutableNilValue asNilValue() { + return this; + } + + @Override + public void writeTo(MessagePacker pk) throws IOException { + pk.packNil(); + } + + @Override + public boolean equals(Object o) { + if (o == this) { + return true; + } + if (!(o instanceof Value)) { + return false; + } + return ((Value) o).isNilValue(); + } + + @Override + public int hashCode() { + return 0; + } + + @Override + public String toString() { + return "null"; + } +} diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableStringValueImpl.java b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableStringValueImpl.java new file mode 100644 index 000000000..59e2cefb1 --- /dev/null +++ b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableStringValueImpl.java @@ -0,0 +1,88 @@ +// +// MessagePack for Java +// +// 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.value.impl; + +import org.msgpack.core.MessagePacker; +import org.msgpack.value.Value; +import org.msgpack.value.ValueType; +import org.msgpack.value.ImmutableStringValue; + +import java.util.Arrays; +import java.io.IOException; + + +/** + * {@code ImmutableStringValueImpl} Implements {@code ImmutableStringValue} using a {@code byte[]} field. + * This implementation caches result of {@code stringValue()} and {@code getString()} using a private {@code String} field. + * + * @see org.msgpack.value.StringValue + */ +public class ImmutableStringValueImpl extends AbstractImmutableRawValue implements ImmutableStringValue { + public ImmutableStringValueImpl(byte[] data) { + super(data); + } + + public ImmutableStringValueImpl(String string) { + super(string); + } + + @Override + public ValueType getValueType() { + return ValueType.STRING; + } + + @Override + public ImmutableStringValue immutableValue() { + return this; + } + + @Override + public ImmutableStringValue asStringValue() { + return this; + } + + @Override + public void writeTo(MessagePacker pk) throws IOException { + pk.packRawStringHeader(data.length); + pk.writePayload(data); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof Value)) { + return false; + } + Value v = (Value) o; + if (!v.isStringValue()) { + return false; + } + + if (v instanceof ImmutableStringValueImpl) { + ImmutableStringValueImpl bv = (ImmutableStringValueImpl) v; + return Arrays.equals(data, bv.data); + } else { + return Arrays.equals(data, v.asStringValue().getByteArray()); + } + } + + @Override + public int hashCode() { + return Arrays.hashCode(data); + } +} diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/IntegerValueImpl.java b/msgpack-core/src/main/java/org/msgpack/value/impl/IntegerValueImpl.java deleted file mode 100644 index 758fde939..000000000 --- a/msgpack-core/src/main/java/org/msgpack/value/impl/IntegerValueImpl.java +++ /dev/null @@ -1,169 +0,0 @@ -package org.msgpack.value.impl; - -import org.msgpack.core.MessageIntegerOverflowException; -import org.msgpack.core.MessageOverflowException; -import org.msgpack.core.MessagePacker; -import org.msgpack.value.*; - -import java.io.IOException; -import java.math.BigInteger; - -/** -* Created on 5/30/14. -*/ -public class IntegerValueImpl extends AbstractValue implements IntegerValue { - - private final int value; - - public IntegerValueImpl(int value) { - this.value = value; - } - - private static int BYTE_MIN = (int) Byte.MIN_VALUE; - private static int BYTE_MAX = (int) Byte.MAX_VALUE; - private static int SHORT_MIN = (int) Short.MIN_VALUE; - private static int SHORT_MAX = (int) Short.MAX_VALUE; - - @Override - public ValueType getValueType() { - return ValueType.INTEGER; - } - - @Override - public IntegerValue asInteger() { - return this; - } - - @Override - public byte toByte() { - return (byte) value; - } - - @Override - public short toShort() { - return (short) value; - } - - @Override - public int toInt() { - return value; - } - - @Override - public long toLong() { - return value; - } - - @Override - public BigInteger toBigInteger() { - return BigInteger.valueOf((long) value); - } - - @Override - public float toFloat() { - return (float) value; - } - - @Override - public double toDouble() { - return (double) value; - } - - @Override - public byte asByte() throws MessageOverflowException { - if (!isValidByte()) { - throw new MessageIntegerOverflowException(value); - } - return (byte) value; - } - - @Override - public short asShort() throws MessageOverflowException { - if (!isValidShort()) { - throw new MessageIntegerOverflowException(value); - } - return (short) value; - } - - @Override - public int asInt() throws MessageOverflowException { - return value; - } - - @Override - public long asLong() throws MessageOverflowException { - return value; - } - - @Override - public BigInteger asBigInteger() throws MessageOverflowException { - return BigInteger.valueOf((long) value); - } - - @Override - public boolean isValidByte() { - return BYTE_MIN <= value && value <= BYTE_MAX; - } - - @Override - public boolean isValidShort() { - return SHORT_MIN <= value && value <= SHORT_MAX; - } - - @Override - public boolean isValidInt() { - return true; - } - - @Override - public boolean isValidLong() { - return true; - } - - @Override - public boolean isWhole() { - return true; - } - - @Override - public void writeTo(MessagePacker pk) throws IOException { - pk.packInt(value); - } - @Override - public void accept(ValueVisitor visitor) { - visitor.visitInteger(this); - } - @Override - public IntegerValue toValue() { - return this; - } - - @Override - public boolean equals(Object o) { - if (o == this) { - return true; - } - if (!(o instanceof Value)) { - return false; - } - Value v = (Value) o; - if (!v.isInteger()) { - return false; - } - IntegerValue iv = v.asInteger(); - if (!iv.isValidInt()) { - return false; - } - return iv.toInt() == value; - } - - @Override - public int hashCode() { - return value; - } - - @Override - public String toString() { - return Integer.toString(value); - } -} diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/MapCursorImpl.java b/msgpack-core/src/main/java/org/msgpack/value/impl/MapCursorImpl.java deleted file mode 100644 index a6f5268b1..000000000 --- a/msgpack-core/src/main/java/org/msgpack/value/impl/MapCursorImpl.java +++ /dev/null @@ -1,116 +0,0 @@ -package org.msgpack.value.impl; - -import org.msgpack.core.*; -import org.msgpack.value.*; -import org.msgpack.value.holder.ValueHolder; - -import java.io.IOException; - -import static org.msgpack.core.MessagePackException.UNSUPPORTED; - -/** - * Created on 6/16/14. - */ -public class MapCursorImpl extends AbstractValueRef implements MapCursor { - - private final ValueHolder valueHolder; - private MessageUnpacker unpacker; - private int cursor = 0; - private int mapSize; - - public MapCursorImpl(ValueHolder valueHolder) { - this.valueHolder = valueHolder; - } - - public void reset(MessageUnpacker unpacker) throws IOException { - this.unpacker = unpacker; - cursor = 0; - this.mapSize = unpacker.unpackMapHeader(); - } - - @Override - public int size() { - return mapSize; - } - @Override - public boolean hasNext() { - try { - return cursor < (mapSize * 2) && unpacker.hasNext(); - } - catch(IOException e) { - return false; - } - } - - @Override - public ValueRef nextKeyOrValue() { - try { - MessageFormat f = unpacker.unpackValue(valueHolder); - cursor++; - return valueHolder.getRef(); - } - catch(IOException e) { - throw new MessageFormatException(e); - } - } - - @Override - public void skipKeyOrValue() { - try { - unpacker.skipValue(); - } - catch(IOException e) { - throw new MessageFormatException(e); - } - } - - @Override - public void skipAll() { - while(hasNext()) { - skipKeyOrValue(); - } - } - - private void ensureNotTraversed() { - if(cursor != 0) - throw UNSUPPORTED("MapCursor is already traversed"); - } - - - @Override - public MapCursor getMapCursor() throws MessageTypeException { - return this; - } - - @Override - public ValueType getValueType() { - return ValueType.MAP; - } - - @Override - public void writeTo(MessagePacker packer) throws IOException { - ensureNotTraversed(); - packer.packMapHeader(mapSize); - while(hasNext()) { - packer.packValue(nextKeyOrValue().toValue()); - } - } - - @Override - public void accept(ValueVisitor visitor) { - visitor.visitMap(this.toValue()); - } - - @Override - public MapValue toValue() { - ensureNotTraversed(); - Value[] keyValueArray = new Value[mapSize * 2]; - int i = 0; - while(hasNext()) { - keyValueArray[i++] = nextKeyOrValue().toValue(); - } - return ValueFactory.newMap(keyValueArray); - } - - -} diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/MapValueImpl.java b/msgpack-core/src/main/java/org/msgpack/value/impl/MapValueImpl.java deleted file mode 100644 index 3f010a7e2..000000000 --- a/msgpack-core/src/main/java/org/msgpack/value/impl/MapValueImpl.java +++ /dev/null @@ -1,280 +0,0 @@ -package org.msgpack.value.impl; - -import org.msgpack.core.MessagePacker; -import org.msgpack.value.*; - -import java.io.IOException; -import java.util.*; - -/** -* Created on 5/30/14. -*/ -public class MapValueImpl extends AbstractValue implements MapValue { - private static MapValueImpl EMPTY = new MapValueImpl(new Value[0]); - - public static MapValue empty() { - return EMPTY; - } - - private final Value[] array; - private transient int cursor = 0; - - public MapValueImpl(Value[] array) { - this.array = array; - } - - @Override - public ValueType getValueType() { - return ValueType.MAP; - } - - @Override - public Value[] toKeyValueSeq() { - return Arrays.copyOf(array, array.length); - } - @Override - public int size() { - return array.length / 2; - } - - @Override - public boolean hasNext() { - return cursor < array.length; - } - @Override - public ValueRef nextKeyOrValue() { - return array[cursor++]; - } - - @Override - public void skipKeyOrValue() { - cursor++; - } - @Override - public void skipAll() { - while(hasNext()) { - skipKeyOrValue(); - } - } - - @Override - public MapCursor getMapCursor() { - return this; - } - - private class MapImpl extends AbstractMap { - - private class EntrySet extends AbstractSet> { - - @Override - public int size() { - return array.length / 2; - } - - @Override - public Iterator> iterator() { - return new EntrySetIterator(); - } - } - - private class EntrySetIterator implements - Iterator> { - private int pos = 0; - - @Override - public boolean hasNext() { - return pos < array.length; - } - - @Override - public Entry next() { - if (pos >= array.length) { - throw new NoSuchElementException(); - } - - Value key = array[pos]; - Value value = array[pos + 1]; - Entry pair = new SimpleImmutableEntry(key, value); - - pos += 2; - return pair; - } - - @Override - public void remove() { - throw new UnsupportedOperationException(); - } - } - - private class KeySet extends AbstractSet { - @Override - public int size() { - return array.length / 2; - } - - @Override - public Iterator iterator() { - return new ValueIterator(0); - } - } - - private class ValueCollection extends AbstractCollection { - - @Override - public int size() { - return array.length / 2; - } - - @Override - public Iterator iterator() { - return new ValueIterator(1); - } - } - - private class ValueIterator implements Iterator { - private int pos; - - ValueIterator(int offset) { - this.pos = offset; - } - - @Override - public boolean hasNext() { - return pos < array.length; - } - - @Override - public Value next() { - if (pos >= array.length) { - throw new NoSuchElementException(); - } - Value v = array[pos]; - pos += 2; - return v; - } - - @Override - public void remove() { - throw new UnsupportedOperationException(); - } - } - - @Override - public Set> entrySet() { - return new EntrySet(); - } - - @Override - public Set keySet() { - return new KeySet(); - } - - @Override - public Collection values() { - return new ValueCollection(); - } - - - @Override - public Value get(Object key) { - for (int i = array.length - 2; i >= 0; i -= 2) { - if (array[i].equals(key)) { - return array[i + 1]; - } - } - return null; - } - } - - @Override - public Map toMap() { - return new MapImpl(); - } - - @Override - public void writeTo(MessagePacker pk) throws IOException { - pk.packMapHeader(array.length / 2); - for (int i = 0; i < array.length; i++) { - array[i].writeTo(pk); - } - } - @Override - public void accept(ValueVisitor visitor) { - visitor.visitMap(this); - } - - @Override - public MapValue toValue() { - return ValueFactory.newMap(array); - } - - @Override - public boolean equals(Object o) { - if (o == this) { - return true; - } - if (!(o instanceof Value)) { - return false; - } - Value v = (Value) o; - if (!v.isMap()) { - return false; - } - - Map mv = v.asMapValue().toMap(); - if (mv.size() != array.length / 2) { - return false; - } - - try { - for (int i = 0; i < array.length; i += 2) { - Value key = array[i]; - Value value = array[i + 1]; - if (!value.equals(mv.get(key))) { - return false; - } - } - } catch (ClassCastException ex) { - return false; - } catch (NullPointerException ex) { - return false; - } - - return true; - } - - @Override - public int hashCode() { - int h = 0; - for (int i = 0; i < array.length; i += 2) { - h += array[i].hashCode() ^ array[i + 1].hashCode(); - } - return h; - } - - @Override - public String toString() { - return toString(new StringBuilder()).toString(); - } - - private StringBuilder toString(StringBuilder sb) { - if (array.length == 0) { - return sb.append("{}"); - } - sb.append("{"); - sb.append(array[0]); - sb.append(":"); - sb.append(array[1]); - for (int i = 2; i < array.length; i += 2) { - sb.append(","); - sb.append(array[i].toString()); - sb.append(":"); - sb.append(array[i + 1].toString()); - } - sb.append("}"); - return sb; - } - - - -} diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/NilValueImpl.java b/msgpack-core/src/main/java/org/msgpack/value/impl/NilValueImpl.java deleted file mode 100644 index 3fea78364..000000000 --- a/msgpack-core/src/main/java/org/msgpack/value/impl/NilValueImpl.java +++ /dev/null @@ -1,60 +0,0 @@ -package org.msgpack.value.impl; - -import org.msgpack.core.MessagePacker; -import org.msgpack.value.ValueType; -import org.msgpack.value.NilValue; -import org.msgpack.value.Value; -import org.msgpack.value.ValueVisitor; - -import java.io.IOException; - -/** -* Created on 5/30/14. -*/ -public class NilValueImpl extends AbstractValue implements NilValue { - - private static NilValue instance = new NilValueImpl(); - - public static NilValue getInstance() { - return instance; - } - - @Override - public ValueType getValueType() { - return ValueType.NIL; - } - - @Override - public boolean equals(Object o) { - if (o == this) { - return true; - } - if (!(o instanceof Value)) { - return false; - } - return ((Value) o).isNil(); - } - - @Override - public int hashCode() { - return 0; - } - - @Override - public String toString() { - return "null"; - } - - @Override - public void writeTo(MessagePacker packer) throws IOException { - packer.packNil(); - } - @Override - public void accept(ValueVisitor visitor) { - visitor.visitNil(); - } - @Override - public NilValue toValue() { - return instance; - } -} diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/RawStringValueImpl.java b/msgpack-core/src/main/java/org/msgpack/value/impl/RawStringValueImpl.java deleted file mode 100644 index 7fd0d61f2..000000000 --- a/msgpack-core/src/main/java/org/msgpack/value/impl/RawStringValueImpl.java +++ /dev/null @@ -1,69 +0,0 @@ -package org.msgpack.value.impl; - -import org.msgpack.core.MessagePacker; -import org.msgpack.core.MessageStringCodingException; -import org.msgpack.value.*; - -import java.io.IOException; -import java.nio.ByteBuffer; - -/** -* Created on 5/30/14. -*/ -public class RawStringValueImpl extends RawValueImpl implements StringValue { - - public RawStringValueImpl(ByteBuffer byteBuffer) { - super(byteBuffer); - } - - @Override - public ValueType getValueType() { - return ValueType.STRING; - } - - @Override - public void accept(ValueVisitor visitor) { - visitor.visitString(this); - } - - @Override - public String toString() { - return super.toString(); - } - - @Override - public void writeTo(MessagePacker pk) throws IOException { - pk.packRawStringHeader(byteBuffer.remaining()); - pk.writePayload(byteBuffer); - } - - @Override - public StringValue toValue() { - return this; - } - - @Override - public boolean equals(Object o) { - if (o == this) { - return true; - } - if (!(o instanceof Value)) { - return false; - } - Value v = (Value) o; - if (!v.isString()) { - return false; - } - try { - return toString().equals(v.asString().toString()); - } catch (MessageStringCodingException ex) { - return false; - } - - } - - @Override - public int hashCode() { - return toString().hashCode(); - } -} diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/RawValueImpl.java b/msgpack-core/src/main/java/org/msgpack/value/impl/RawValueImpl.java deleted file mode 100644 index e9db5f129..000000000 --- a/msgpack-core/src/main/java/org/msgpack/value/impl/RawValueImpl.java +++ /dev/null @@ -1,116 +0,0 @@ -package org.msgpack.value.impl; - -import org.msgpack.core.MessagePacker; -import org.msgpack.core.MessageStringCodingException; -import org.msgpack.core.buffer.MessageBuffer; -import org.msgpack.value.BinaryValue; -import org.msgpack.value.RawValue; -import org.msgpack.value.Value; - -import java.io.IOException; -import java.nio.ByteBuffer; -import java.nio.charset.*; - -/** -* Created on 5/30/14. -*/ -public abstract class RawValueImpl extends AbstractValue implements RawValue { - - protected final ByteBuffer byteBuffer; - private transient String decodedStringCache; - private transient MessageStringCodingException codingException; - - public RawValueImpl(ByteBuffer byteBuffer) { - this.byteBuffer = byteBuffer.slice(); - } - - @Override - public byte[] toByteArray() { - byte[] byteArray = new byte[byteBuffer.remaining()]; - byteBuffer.slice().get(byteArray); - return byteArray; - } - - @Override - public RawValue toValue() { - return this; - } - - @Override - public ByteBuffer toByteBuffer() { - return byteBuffer.asReadOnlyBuffer(); - } - - @Override - public MessageBuffer toMessageBuffer() { - return MessageBuffer.wrap(byteBuffer); - } - - @Override - public String toString() { - if (decodedStringCache == null) { - decodeString(); - } - if (codingException != null) { - throw codingException; - } - return decodedStringCache; - } - - - private synchronized void decodeString() { - if (decodedStringCache != null) { - return; - } - ByteBuffer readOnlyBuffer = byteBuffer.asReadOnlyBuffer(); - try { - CharsetDecoder reportDecoder = Charset.forName("UTF-8").newDecoder() - .onMalformedInput(CodingErrorAction.REPLACE) - .onUnmappableCharacter(CodingErrorAction.REPLACE); - readOnlyBuffer.position(0); - decodedStringCache = reportDecoder.decode(readOnlyBuffer).toString(); - } catch (UnsupportedCharsetException neverThrown) { - throw new AssertionError(neverThrown); - } catch (CharacterCodingException ex) { - codingException = new MessageStringCodingException(ex); - try { - CharsetDecoder replaceDecoder = Charset.forName("UTF-8").newDecoder() - .onMalformedInput(CodingErrorAction.REPLACE) - .onUnmappableCharacter(CodingErrorAction.REPLACE); - readOnlyBuffer.position(0); - decodedStringCache = replaceDecoder.decode(readOnlyBuffer).toString(); - } catch (UnsupportedCharsetException neverThrown) { - throw new AssertionError(neverThrown); - } catch (CharacterCodingException neverThrown) { - throw new AssertionError(neverThrown); - } - } - } - - @Override - public boolean equals(Object o) { - if (o == this) { - return true; - } - if (!(o instanceof Value)) { - return false; - } - Value v = (Value) o; - if (!v.isBinary()) { - return false; - } - BinaryValue bv = v.asBinary(); - return bv.toByteBuffer().equals(byteBuffer); - } - - @Override - public int hashCode() { - return byteBuffer.hashCode(); - } - - @Override - public void writeTo(MessagePacker packer) throws IOException { - packer.packBinaryHeader(byteBuffer.remaining()); - packer.writePayload(byteBuffer); - } -} diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/StringValueImpl.java b/msgpack-core/src/main/java/org/msgpack/value/impl/StringValueImpl.java deleted file mode 100644 index 4bbe14d6f..000000000 --- a/msgpack-core/src/main/java/org/msgpack/value/impl/StringValueImpl.java +++ /dev/null @@ -1,84 +0,0 @@ -package org.msgpack.value.impl; - -import org.msgpack.core.MessagePack; -import org.msgpack.core.MessagePacker; -import org.msgpack.core.MessageStringCodingException; -import org.msgpack.core.buffer.MessageBuffer; -import org.msgpack.value.*; - -import java.io.IOException; -import java.nio.ByteBuffer; - -/** -* Created on 5/30/14. -*/ -public class StringValueImpl extends AbstractValue implements StringValue { - - private final String value; - - public StringValueImpl(String value) { - this.value = value; - } - - @Override - public ValueType getValueType() { - return ValueType.STRING; - } - - @Override - public byte[] toByteArray() { - return value.getBytes(MessagePack.UTF8); - } - - @Override - public MessageBuffer toMessageBuffer() { - return MessageBuffer.wrap(toByteArray()); - } - - @Override - public String toString() { - return value; - } - - @Override - public ByteBuffer toByteBuffer() { - return toMessageBuffer().toByteBuffer(); - } - - @Override - public void writeTo(MessagePacker pk) throws IOException { - pk.packString(value); - } - @Override - public void accept(ValueVisitor visitor) { - visitor.visitString(this); - } - @Override - public StringValue toValue() { - return ValueFactory.newString(value); - } - - @Override - public boolean equals(Object o) { - if (o == this) { - return true; - } - if (!(o instanceof Value)) { - return false; - } - Value v = (Value) o; - if (!v.isString()) { - return false; - } - try { - return v.asString().toString().equals(value); - } catch (MessageStringCodingException ex) { - return false; - } - } - - @Override - public int hashCode() { - return value.hashCode(); - } -} diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/ValueUnion.java b/msgpack-core/src/main/java/org/msgpack/value/impl/ValueUnion.java deleted file mode 100644 index 0a282ef0d..000000000 --- a/msgpack-core/src/main/java/org/msgpack/value/impl/ValueUnion.java +++ /dev/null @@ -1,131 +0,0 @@ -// -// MessagePack for Java -// -// 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.value.impl; - -import java.util.List; -import java.util.Map; -import java.math.BigInteger; -import java.nio.ByteBuffer; - -import org.msgpack.value.Value; - -/** - * Union of multiple values so that we can minimize the object initialization cost - */ -class ValueUnion { - public static enum Type { - BOOLEAN, - LONG, - BIG_INTEGER, - DOUBLE, - BYTE_BUFFER, - STRING, - LIST, - MAP; - } - - private Type type; - - private long longValue; - private double doubleValue; - private Object objectValue; - - public void reset() { - this.type = null; - } - - public boolean isSet() { - return type != null; - } - - public Type getType() { - return type; - } - - public void setBoolean(boolean v) { - this.type = Type.BOOLEAN; - this.longValue = (v ? 1L : 0L); - } - - public boolean getBoolean() { - return longValue != 0L; - } - - public void setLong(long v) { - this.type = Type.LONG; - this.longValue = v; - } - - public long getLong() { - return longValue; - } - - public void setBigInteger(BigInteger v) { - this.type = Type.BIG_INTEGER; - this.objectValue = v; - } - - public BigInteger getBigInteger() { - return (BigInteger) objectValue; - } - - public void setDouble(double v) { - this.type = Type.DOUBLE; - this.doubleValue = v; - } - - public double getDouble() { - return doubleValue; - } - - public void setByteBuffer(ByteBuffer v) { - this.type = Type.BYTE_BUFFER; - this.objectValue = v; - } - - public ByteBuffer getByteBuffer() { - return (ByteBuffer) objectValue; - } - - public void setString(String v) { - this.type = Type.STRING; - this.objectValue = v; - } - - public String getString() { - return (String) objectValue; - } - - public void setList(List v) { - this.type = Type.LIST; - this.objectValue = v; - } - - @SuppressWarnings("unchecked") - public List getList() { - return (List) objectValue; - } - - public void setMap(Map v) { - this.type = Type.MAP; - this.objectValue = v; - } - - @SuppressWarnings("unchecked") - public Map getMap() { - return (Map) objectValue; - } -} diff --git a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackExtendedType.java b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackExtendedType.java deleted file mode 100644 index 96bfac2c8..000000000 --- a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackExtendedType.java +++ /dev/null @@ -1,25 +0,0 @@ -package org.msgpack.jackson.dataformat; - -import java.nio.ByteBuffer; - -/** - * Created by komamitsu on 3/7/15. - */ -public class MessagePackExtendedType { - private final int extType; - private final ByteBuffer byteBuffer; - - public MessagePackExtendedType(int extType, ByteBuffer byteBuffer) { - this.extType = extType; - this.byteBuffer = byteBuffer.isReadOnly() ? - byteBuffer : byteBuffer.asReadOnlyBuffer(); - } - - public int extType() { - return extType; - } - - public ByteBuffer byteBuffer() { - return byteBuffer; - } -} diff --git a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java index 45ebcae71..b1125ca6b 100644 --- a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java +++ b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java @@ -10,11 +10,13 @@ import org.msgpack.core.buffer.ArrayBufferInput; import org.msgpack.core.buffer.InputStreamBufferInput; import org.msgpack.core.buffer.MessageBufferInput; -import org.msgpack.value.ExtendedValue; -import org.msgpack.value.ValueRef; +import org.msgpack.value.Value; +import org.msgpack.value.ImmutableValue; import org.msgpack.value.NumberValue; +import org.msgpack.value.IntegerValue; +import org.msgpack.value.ExtendedValue; import org.msgpack.value.ValueType; -import org.msgpack.value.holder.ValueHolder; +import org.msgpack.value.ValueFactory; import java.io.IOException; import java.io.InputStream; @@ -31,7 +33,7 @@ public class MessagePackParser extends ParserMinimalBase { private JsonReadContext parsingContext; private final LinkedList stack = new LinkedList(); - private final ValueHolder valueHolder = new ValueHolder(); + private ImmutableValue value = ValueFactory.newNilValue(); private boolean isClosed; private long tokenPosition; private long currentPosition; @@ -134,33 +136,34 @@ public JsonToken nextToken() throws IOException, JsonParseException { return null; } - MessageFormat nextFormat = messageUnpacker.getNextFormat(); - ValueType valueType = nextFormat.getValueType(); + ValueType type = messageUnpacker.getNextFormat().getValueType(); // We should push a new StackItem lazily after updating the current stack. StackItem newStack = null; - switch (valueType) { + switch (type) { case NIL: messageUnpacker.unpackNil(); + value = ValueFactory.newNilValue(); nextToken = JsonToken.VALUE_NULL; break; case BOOLEAN: boolean b = messageUnpacker.unpackBoolean(); + value = ValueFactory.newNilValue(); nextToken = b ? JsonToken.VALUE_TRUE : JsonToken.VALUE_FALSE; break; case INTEGER: - messageUnpacker.unpackValue(valueHolder); + value = messageUnpacker.unpackValue(); nextToken = JsonToken.VALUE_NUMBER_INT; break; case FLOAT: - messageUnpacker.unpackValue(valueHolder); + value = messageUnpacker.unpackValue(); nextToken = JsonToken.VALUE_NUMBER_FLOAT; break; case STRING: - messageUnpacker.unpackValue(valueHolder); + value = messageUnpacker.unpackValue(); if (parsingContext.inObject() && _currToken != JsonToken.FIELD_NAME) { - parsingContext.setCurrentName(valueHolder.getRef().asRaw().toString()); + parsingContext.setCurrentName(value.asRawValue().stringValue()); nextToken = JsonToken.FIELD_NAME; } else { @@ -168,17 +171,26 @@ public JsonToken nextToken() throws IOException, JsonParseException { } break; case BINARY: - messageUnpacker.unpackValue(valueHolder); - nextToken = JsonToken.VALUE_EMBEDDED_OBJECT; + value = messageUnpacker.unpackValue(); + if (parsingContext.inObject() && _currToken != JsonToken.FIELD_NAME) { + parsingContext.setCurrentName(value.asRawValue().stringValue()); + nextToken = JsonToken.FIELD_NAME; + } + else { + nextToken = JsonToken.VALUE_STRING; + nextToken = JsonToken.VALUE_EMBEDDED_OBJECT; + } break; case ARRAY: + value = ValueFactory.newNilValue(); newStack = new StackItemForArray(messageUnpacker.unpackArrayHeader()); break; case MAP: + value = ValueFactory.newNilValue(); newStack = new StackItemForObject(messageUnpacker.unpackMapHeader()); break; case EXTENDED: - messageUnpacker.unpackValue(valueHolder); + value = messageUnpacker.unpackValue(); nextToken = JsonToken.VALUE_EMBEDDED_OBJECT; break; default: @@ -212,7 +224,7 @@ protected void _handleEOF() throws JsonParseException {} @Override public String getText() throws IOException, JsonParseException { // This method can be called for new BigInteger(text) - return valueHolder.getRef().toString(); + return value.asRawValue().stringValue(); } @Override @@ -237,81 +249,78 @@ public int getTextOffset() throws IOException, JsonParseException { @Override public byte[] getBinaryValue(Base64Variant b64variant) throws IOException, JsonParseException { - return valueHolder.getRef().asBinary().toByteArray(); + return value.asRawValue().getByteArray(); } @Override public Number getNumberValue() throws IOException, JsonParseException { - NumberValue numberValue = valueHolder.getRef().asNumber(); - if (numberValue.isValidInt()) { - return numberValue.toInt(); - } - else if (numberValue.isValidLong()) { - return numberValue.toLong(); - } - else { - return numberValue.toBigInteger(); + if (value.isIntegerValue()) { + IntegerValue integerValue = value.asIntegerValue(); + if (integerValue.isInIntRange()) { + return integerValue.intValue(); + } + else if (integerValue.isInLongRange()) { + return integerValue.longValue(); + } + else { + return integerValue.bigIntegerValue(); + } + } else { + return value.asNumberValue().doubleValue(); } } @Override public int getIntValue() throws IOException, JsonParseException { - return valueHolder.getRef().asNumber().toInt(); + return value.asNumberValue().intValue(); } @Override public long getLongValue() throws IOException, JsonParseException { - return valueHolder.getRef().asNumber().toLong(); + return value.asNumberValue().longValue(); } @Override public BigInteger getBigIntegerValue() throws IOException, JsonParseException { - return valueHolder.getRef().asNumber().toBigInteger(); + return value.asNumberValue().bigIntegerValue(); } @Override public float getFloatValue() throws IOException, JsonParseException { - return valueHolder.getRef().asFloat().toFloat(); + return value.asNumberValue().floatValue(); } @Override public double getDoubleValue() throws IOException, JsonParseException { - return valueHolder.getRef().asFloat().toDouble(); + return value.asNumberValue().doubleValue(); } @Override public BigDecimal getDecimalValue() throws IOException { - ValueRef ref = valueHolder.getRef(); - - if (ref.isInteger()) { - NumberValue number = ref.asNumber(); + if (value.isIntegerValue()) { + IntegerValue number = value.asIntegerValue(); //optimization to not convert the value to BigInteger unnecessarily - if (number.isValidByte() || number.isValidShort() || number.isValidInt() || number.isValidLong()) { - return BigDecimal.valueOf(number.asLong()); + if (number.isInLongRange()) { + return BigDecimal.valueOf(number.longValue()); } else { - return new BigDecimal(number.asBigInteger()); + return new BigDecimal(number.bigIntegerValue()); } } - else if (ref.isFloat()) { - return BigDecimal.valueOf(ref.asFloat().toDouble()); + else if (value.isFloatValue()) { + return BigDecimal.valueOf(value.asFloatValue().doubleValue()); } else { - throw new UnsupportedOperationException("Couldn't parse value as BigDecimal. " + ref); + throw new UnsupportedOperationException("Couldn't parse value as BigDecimal. " + value); } } @Override public Object getEmbeddedObject() throws IOException, JsonParseException { - ValueRef ref = valueHolder.getRef(); - - if (ref.isBinary()) { - return ref.asBinary().toByteArray(); - } else if (ref.isExtended()) { - ExtendedValue extendedValue = ref.asExtended().toValue(); - MessagePackExtendedType extendedType = - new MessagePackExtendedType(extendedValue.getExtType(), extendedValue.toByteBuffer()); - return extendedType; + if (value.isBinaryValue()) { + return value.asBinaryValue().getByteArray(); + } else if (value.isExtendedValue()) { + return value.asExtendedValue(); } else { throw new UnsupportedOperationException(); } @@ -319,15 +328,20 @@ public Object getEmbeddedObject() throws IOException, JsonParseException { @Override public NumberType getNumberType() throws IOException, JsonParseException { - NumberValue numberValue = valueHolder.getRef().asNumber(); - if (numberValue.isValidInt()) { - return NumberType.INT; - } - else if (numberValue.isValidLong()) { - return NumberType.LONG; - } - else { - return NumberType.BIG_INTEGER; + if (value.isIntegerValue()) { + IntegerValue integerValue = value.asIntegerValue(); + if (integerValue.isInIntRange()) { + return NumberType.INT; + } + else if (integerValue.isInLongRange()) { + return NumberType.LONG; + } + else { + return NumberType.BIG_INTEGER; + } + } else { + value.asNumberValue(); + return NumberType.DOUBLE; } } From 768527637a5a985c102c8e81c39169ce2dd314b5 Mon Sep 17 00:00:00 2001 From: Sadayuki Furuhashi Date: Wed, 10 Jun 2015 11:39:18 +0900 Subject: [PATCH 059/234] added org.msgpack.value.Variable --- .../org/msgpack/core/MessageUnpacker.java | 78 +- .../java/org/msgpack/value/ValueFactory.java | 4 +- .../main/java/org/msgpack/value/Variable.java | 955 ++++++++++++++++++ .../value/impl/ImmutableDoubleValueImpl.java | 5 +- .../jackson/dataformat/MessagePackParser.java | 15 +- 5 files changed, 1044 insertions(+), 13 deletions(-) create mode 100644 msgpack-core/src/main/java/org/msgpack/value/Variable.java diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java b/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java index c0f163cf4..12af8572f 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java +++ b/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java @@ -15,6 +15,10 @@ // package org.msgpack.core; +import java.util.List; +import java.util.ArrayList; +import java.util.Map; +import java.util.HashMap; import java.io.Closeable; import java.io.EOFException; import java.io.IOException; @@ -32,6 +36,7 @@ import org.msgpack.core.buffer.MessageBufferInput; import org.msgpack.value.Value; import org.msgpack.value.ImmutableValue; +import org.msgpack.value.Variable; import org.msgpack.value.ValueType; import org.msgpack.value.ValueFactory; @@ -550,7 +555,7 @@ public ImmutableValue unpackValue() throws IOException { return ValueFactory.newFloatValue(unpackDouble()); case STRING: { int length = unpackRawStringHeader(); - return ValueFactory.newRawStringValue(readPayload(length)); + return ValueFactory.newStringValue(readPayload(length)); } case BINARY: { int length = unpackBinaryHeader(); @@ -567,8 +572,11 @@ public ImmutableValue unpackValue() throws IOException { case MAP: { int size = unpackMapHeader(); Value[] kvs = new Value[size * 2]; - for (int i=0; i < size * 2; i++) { + for (int i=0; i < size * 2; ) { kvs[i] = unpackValue(); + i++; + kvs[i] = unpackValue(); + i++; } return ValueFactory.newMapValue(kvs); } @@ -581,6 +589,72 @@ public ImmutableValue unpackValue() throws IOException { } } + public Variable unpackValue(Variable var) throws IOException { + MessageFormat mf = getNextFormat(); + switch(mf.getValueType()) { + case NIL: + unpackNil(); + var.setNilValue(); + return var; + case BOOLEAN: + var.setBooleanValue(unpackBoolean()); + return var; + case INTEGER: + switch (mf) { + case UINT64: + var.setIntegerValue(unpackBigInteger()); + return var; + default: + var.setIntegerValue(unpackLong()); + return var; + } + case FLOAT: + var.setFloatValue(unpackDouble()); + return var; + case STRING: { + int length = unpackRawStringHeader(); + var.setStringValue(readPayload(length)); + return var; + } + case BINARY: { + int length = unpackBinaryHeader(); + var.setBinaryValue(readPayload(length)); + return var; + } + case ARRAY: { + int size = unpackArrayHeader(); + List list = new ArrayList(size); + for (int i=0; i < size; i++) { + Variable e = new Variable(); + unpackValue(e); + list.add(e); + } + var.setArrayValue(list); + return var; + } + case MAP: { + int size = unpackMapHeader(); + Map map = new HashMap(); + for (int i=0; i < size; i++) { + Variable k = new Variable(); + unpackValue(k); + Variable v = new Variable(); + unpackValue(v); + map.put(k, v); + } + var.setMapValue(map); + return var; + } + case EXTENDED: { + ExtendedTypeHeader extHeader = unpackExtendedTypeHeader(); + var.setExtendedValue(extHeader.getType(), readPayload(extHeader.getLength())); + return var; + } + default: + throw new MessageFormatException("Unknown value type"); + } + } + public void unpackNil() throws IOException { byte b = consume(); if(b == Code.NIL) { diff --git a/msgpack-core/src/main/java/org/msgpack/value/ValueFactory.java b/msgpack-core/src/main/java/org/msgpack/value/ValueFactory.java index 4c5245921..4d6458728 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/ValueFactory.java +++ b/msgpack-core/src/main/java/org/msgpack/value/ValueFactory.java @@ -89,11 +89,11 @@ public static ImmutableStringValue newStringValue(String s) { return new ImmutableStringValueImpl(s); } - public static ImmutableStringValue newRawStringValue(byte[] b) { + public static ImmutableStringValue newStringValue(byte[] b) { return new ImmutableStringValueImpl(b); } - public static ImmutableStringValue newRawStringValue(byte[] b, int off, int len) { + public static ImmutableStringValue newStringValue(byte[] b, int off, int len) { return new ImmutableStringValueImpl(Arrays.copyOfRange(b, off, len)); } diff --git a/msgpack-core/src/main/java/org/msgpack/value/Variable.java b/msgpack-core/src/main/java/org/msgpack/value/Variable.java new file mode 100644 index 000000000..f980acf00 --- /dev/null +++ b/msgpack-core/src/main/java/org/msgpack/value/Variable.java @@ -0,0 +1,955 @@ +// +// MessagePack for Java +// +// 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.value; + +import org.msgpack.core.MessagePack; +import org.msgpack.core.MessagePacker; +import org.msgpack.core.MessageTypeCastException; +import org.msgpack.core.MessageStringCodingException; +import org.msgpack.core.MessageIntegerOverflowException; +import org.msgpack.value.*; + +import java.math.BigDecimal; +import java.math.BigInteger; +import java.util.List; +import java.util.Set; +import java.util.Map; +import java.util.Collection; +import java.util.Iterator; +import java.io.IOException; +import java.nio.ByteBuffer; +import java.nio.charset.CharsetDecoder; +import java.nio.charset.CharsetEncoder; +import java.nio.charset.CodingErrorAction; +import java.nio.charset.CharacterCodingException; + + +public class Variable implements Value +{ + private abstract class AbstractValueAccessor implements Value { + @Override + public boolean isNilValue() { + return getValueType().isNilType(); + } + + @Override + public boolean isBooleanValue() { + return getValueType().isBooleanType(); + } + + @Override + public boolean isNumberValue() { + return getValueType().isNumberType(); + } + + @Override + public boolean isIntegerValue() { + return getValueType().isIntegerType(); + } + + @Override + public boolean isFloatValue() { + return getValueType().isFloatType(); + } + + @Override + public boolean isRawValue() { + return getValueType().isRawType(); + } + + @Override + public boolean isBinaryValue() { + return getValueType().isBinaryType(); + } + + @Override + public boolean isStringValue() { + return getValueType().isStringType(); + } + + @Override + public boolean isArrayValue() { + return getValueType().isArrayType(); + } + + @Override + public boolean isMapValue() { + return getValueType().isMapType(); + } + + @Override + public boolean isExtendedValue() { + return getValueType().isExtendedType(); + } + + @Override + public NilValue asNilValue() { + throw new MessageTypeCastException(); + } + + @Override + public BooleanValue asBooleanValue() { + throw new MessageTypeCastException(); + } + + @Override + public NumberValue asNumberValue() { + throw new MessageTypeCastException(); + } + + @Override + public IntegerValue asIntegerValue() { + throw new MessageTypeCastException(); + } + + @Override + public FloatValue asFloatValue() { + throw new MessageTypeCastException(); + } + + @Override + public RawValue asRawValue() { + throw new MessageTypeCastException(); + } + + @Override + public BinaryValue asBinaryValue() { + throw new MessageTypeCastException(); + } + + @Override + public StringValue asStringValue() { + throw new MessageTypeCastException(); + } + + @Override + public ArrayValue asArrayValue() { + throw new MessageTypeCastException(); + } + + @Override + public MapValue asMapValue() { + throw new MessageTypeCastException(); + } + + @Override + public ExtendedValue asExtendedValue() { + throw new MessageTypeCastException(); + } + + @Override + public void writeTo(MessagePacker pk) throws IOException { + Variable.this.writeTo(pk); + } + + @Override + public boolean equals(Object obj) { + return Variable.this.equals(obj); + } + + @Override + public int hashCode() { + return Variable.this.hashCode(); + } + + @Override + public String toString() { + return Variable.this.toString(); + } + } + + public static enum Type { + NULL(ValueType.NIL), + BOOLEAN(ValueType.BOOLEAN), + LONG(ValueType.INTEGER), + BIG_INTEGER(ValueType.INTEGER), + DOUBLE(ValueType.FLOAT), + BYTE_ARRAY(ValueType.BINARY), + RAW_STRING(ValueType.STRING), + LIST(ValueType.ARRAY), + MAP(ValueType.MAP), + EXTENDED(ValueType.EXTENDED); + + private final ValueType valueType; + + private Type(ValueType valueType) { + this.valueType = valueType; + } + + public ValueType getValueType() { + return valueType; + } + } + + final NilValueAccessor nilAccessor = new NilValueAccessor(); + final BooleanValueAccessor booleanAccessor = new BooleanValueAccessor(); + final IntegerValueAccessor integerAccessor = new IntegerValueAccessor(); + final FloatValueAccessor floatAccessor = new FloatValueAccessor(); + final BinaryValueAccessor binaryAccessor = new BinaryValueAccessor(); + final StringValueAccessor stringAccessor = new StringValueAccessor(); + final ArrayValueAccessor arrayAccessor = new ArrayValueAccessor(); + final MapValueAccessor mapAccessor = new MapValueAccessor(); + final ExtendedValueAccessor extendedAccessor = new ExtendedValueAccessor(); + + private Type type; + + private long longValue; + private double doubleValue; + private Object objectValue; + + private AbstractValueAccessor accessor; + + public Variable() { + setNilValue(); + } + + + //// + // NilValue + // + + public Variable setNilValue() { + this.type = Type.NULL; + this.accessor = nilAccessor; + return this; + } + + private class NilValueAccessor extends AbstractValueAccessor implements NilValue { + @Override + public ValueType getValueType() { + return ValueType.NIL; + } + + @Override + public NilValue asNilValue() { + return this; + } + + @Override + public ImmutableNilValue immutableValue() { + return ValueFactory.newNilValue(); + } + } + + + //// + // BooleanValue + // + + public Variable setBooleanValue(boolean v) { + this.type = Type.BOOLEAN; + this.accessor = booleanAccessor; + this.longValue = (v ? 1L : 0L); + return this; + } + + private class BooleanValueAccessor extends AbstractValueAccessor implements BooleanValue { + @Override + public ValueType getValueType() { + return ValueType.BOOLEAN; + } + + @Override + public BooleanValue asBooleanValue() { + return this; + } + + @Override + public ImmutableBooleanValue immutableValue() { + return ValueFactory.newBooleanValue(getBoolean()); + } + + @Override + public boolean getBoolean() { + return longValue == 1L; + } + } + + + //// + // NumberValue + // IntegerValue + // FloatValue + // + + private static final BigInteger LONG_MIN = BigInteger.valueOf((long) Long.MIN_VALUE); + private static final BigInteger LONG_MAX = BigInteger.valueOf((long) Long.MAX_VALUE); + private static final long BYTE_MIN = (long) Byte.MIN_VALUE; + private static final long BYTE_MAX = (long) Byte.MAX_VALUE; + private static final long SHORT_MIN = (long) Short.MIN_VALUE; + private static final long SHORT_MAX = (long) Short.MAX_VALUE; + private static final long INT_MIN = (long) Integer.MIN_VALUE; + private static final long INT_MAX = (long) Integer.MAX_VALUE; + + private abstract class AbstractNumberValueAccessor extends AbstractValueAccessor implements NumberValue { + @Override + public NumberValue asNumberValue() { + return this; + } + + @Override + public byte byteValue() { + if (type == Type.BIG_INTEGER) { + return ((BigInteger) objectValue).byteValue(); + } + return (byte) longValue; + } + + @Override + public short shortValue() { + if (type == Type.BIG_INTEGER) { + return ((BigInteger) objectValue).shortValue(); + } + return (short) longValue; + } + + @Override + public int intValue() { + if (type == Type.BIG_INTEGER) { + return ((BigInteger) objectValue).intValue(); + } + return (int) longValue; + } + + @Override + public long longValue() { + if (type == Type.BIG_INTEGER) { + return ((BigInteger) objectValue).longValue(); + } + return (long) longValue; + } + + @Override + public BigInteger bigIntegerValue() { + if (type == Type.BIG_INTEGER) { + return (BigInteger) objectValue; + } + else if (type == Type.DOUBLE) { + return new BigDecimal(doubleValue).toBigInteger(); + } + return BigInteger.valueOf(longValue); + } + + @Override + public float floatValue() { + if (type == Type.BIG_INTEGER) { + return ((BigInteger) objectValue).floatValue(); + } + else if (type == Type.DOUBLE) { + return (float) doubleValue; + } + return (float) longValue; + } + + @Override + public double doubleValue() { + if (type == Type.BIG_INTEGER) { + return ((BigInteger) objectValue).doubleValue(); + } + else if (type == Type.DOUBLE) { + return doubleValue; + } + return (double) longValue; + } + } + + + //// + // IntegerValue + // + + public Variable setIntegerValue(long v) { + this.type = Type.LONG; + this.accessor = integerAccessor; + this.longValue = v; + return this; + } + + public Variable setIntegerValue(BigInteger v) { + if (0 <= v.compareTo(LONG_MIN) && v.compareTo(LONG_MAX) <= 0) { + this.type = Type.LONG; + this.longValue = v.longValue(); + } else { + this.type = Type.BIG_INTEGER; + this.objectValue = v; + } + return this; + } + + private class IntegerValueAccessor extends AbstractNumberValueAccessor implements IntegerValue { + @Override + public ValueType getValueType() { + return ValueType.INTEGER; + } + + @Override + public IntegerValue asIntegerValue() { + return this; + } + + @Override + public ImmutableIntegerValue immutableValue() { + if (type == Type.BIG_INTEGER) { + return ValueFactory.newIntegerValue((BigInteger) objectValue); + } + return ValueFactory.newIntegerValue(longValue); + } + + @Override + public boolean isInByteRange() { + if (type == Type.BIG_INTEGER) { + return false; + } + return BYTE_MIN <= longValue && longValue <= BYTE_MAX; + } + + @Override + public boolean isInShortRange() { + if (type == Type.BIG_INTEGER) { + return false; + } + return SHORT_MIN <= longValue && longValue <= SHORT_MAX; + } + + @Override + public boolean isInIntRange() { + if (type == Type.BIG_INTEGER) { + return false; + } + return INT_MIN <= longValue && longValue <= INT_MAX; + } + + @Override + public boolean isInLongRange() { + if (type == Type.BIG_INTEGER) { + return false; + } + return true; + } + + @Override + public byte getByte() { + if (!isInByteRange()) { + throw new MessageIntegerOverflowException(longValue); + } + return (byte) longValue; + } + + @Override + public short getShort() { + if (!isInByteRange()) { + throw new MessageIntegerOverflowException(longValue); + } + return (short) longValue; + } + + @Override + public int getInt() { + if (!isInIntRange()) { + throw new MessageIntegerOverflowException(longValue); + } + return (int) longValue; + } + + @Override + public long getLong() { + if (!isInLongRange()) { + throw new MessageIntegerOverflowException(longValue); + } + return longValue; + } + + @Override + public BigInteger getBigInteger() { + if (type == Type.BIG_INTEGER) { + return (BigInteger) objectValue; + } else { + return BigInteger.valueOf(longValue); + } + } + } + + + //// + // FloatValue + // + + public Variable setFloatValue(double v) { + this.type = Type.DOUBLE; + this.accessor = floatAccessor; + this.doubleValue = v; + this.longValue = (long) v; // AbstractNumberValueAccessor uses longValue + return this; + } + + private class FloatValueAccessor extends AbstractNumberValueAccessor implements FloatValue { + @Override + public FloatValue asFloatValue() { + return this; + } + + @Override + public ImmutableFloatValue immutableValue() { + return ValueFactory.newFloatValue(doubleValue); + } + + @Override + public ValueType getValueType() { + return ValueType.FLOAT; + } + } + + + //// + // RawValue + // BinaryValue + // StringValue + // + + private abstract class AbstractRawValueAccessor extends AbstractValueAccessor implements RawValue { + @Override + public RawValue asRawValue() { + return this; + } + + @Override + public byte[] getByteArray() { + return (byte[]) objectValue; + } + + @Override + public ByteBuffer getByteBuffer() { + return ByteBuffer.wrap(getByteArray()); + } + + @Override + public String getString() { + byte[] raw = (byte[]) objectValue; + try { + CharsetDecoder reportDecoder = MessagePack.UTF8.newDecoder() + .onMalformedInput(CodingErrorAction.REPORT) + .onUnmappableCharacter(CodingErrorAction.REPORT); + return reportDecoder.decode(ByteBuffer.wrap(raw)).toString(); + } catch (CharacterCodingException ex) { + throw new MessageStringCodingException(ex); + } + } + + @Override + public String stringValue() { + byte[] raw = (byte[]) objectValue; + try { + CharsetDecoder reportDecoder = MessagePack.UTF8.newDecoder() + .onMalformedInput(CodingErrorAction.REPLACE) + .onUnmappableCharacter(CodingErrorAction.REPLACE); + return reportDecoder.decode(ByteBuffer.wrap(raw)).toString(); + } catch (CharacterCodingException ex) { + throw new MessageStringCodingException(ex); + } + } + } + + //// + // BinaryValue + // + + public Variable setBinaryValue(byte[] v) { + this.type = Type.BYTE_ARRAY; + this.accessor = binaryAccessor; + this.objectValue = v; + return this; + } + + private class BinaryValueAccessor extends AbstractRawValueAccessor implements BinaryValue { + @Override + public ValueType getValueType() { + return ValueType.BINARY; + } + + @Override + public BinaryValue asBinaryValue() { + return this; + } + + @Override + public ImmutableBinaryValue immutableValue() { + return ValueFactory.newBinaryValue(getByteArray()); + } + } + + + //// + // StringValue + // + + public Variable setStringValue(String v) { + return setStringValue(v.getBytes(MessagePack.UTF8)); + } + + public Variable setStringValue(byte[] v) { + this.type = Type.RAW_STRING; + this.accessor = stringAccessor; + this.objectValue = v; + return this; + } + + private class StringValueAccessor extends AbstractRawValueAccessor implements StringValue { + @Override + public ValueType getValueType() { + return ValueType.STRING; + } + + @Override + public StringValue asStringValue() { + return this; + } + + @Override + public ImmutableStringValue immutableValue() { + return ValueFactory.newStringValue((byte[]) objectValue); + } + } + + + //// + // ArrayValue + // + + public Variable setArrayValue(List v) { + this.type = Type.LIST; + this.accessor = arrayAccessor; + this.objectValue = v; + return this; + } + + private class ArrayValueAccessor extends AbstractValueAccessor implements ArrayValue { + @Override + public ValueType getValueType() { + return ValueType.ARRAY; + } + + @Override + public ArrayValue asArrayValue() { + return this; + } + + @Override + public ImmutableArrayValue immutableValue() { + return ValueFactory.newArrayValue(list()); + } + + @Override + public int size() { + return list().size(); + } + + @Override + public Value get(int index) { + return list().get(index); + } + + @Override + public Value getOrNilValue(int index) { + List l = list(); + if (l.size() < index && index >= 0) { + return ValueFactory.newNilValue(); + } + return l.get(index); + } + + @Override + public Iterator iterator() { + return list().iterator(); + } + + @Override + @SuppressWarnings("unchecked") + public List list() { + return (List) objectValue; + } + } + + //// + // MapValue + // + + public Variable setMapValue(Map v) { + this.type = Type.MAP; + this.accessor = mapAccessor; + this.objectValue = v; + return this; + } + + private class MapValueAccessor extends AbstractValueAccessor implements MapValue { + @Override + public ValueType getValueType() { + return ValueType.MAP; + } + + @Override + public MapValue asMapValue() { + return this; + } + + @Override + public ImmutableMapValue immutableValue() { + return ValueFactory.newMapValue(map()); + } + + @Override + public int size() { + return map().size(); + } + + @Override + public Set keySet() { + return map().keySet(); + } + + @Override + public Set> entrySet() { + return map().entrySet(); + } + + @Override + public Collection values() { + return map().values(); + } + + @Override + public Value[] getKeyValueArray() { + Map v = map(); + Value[] kvs = new Value[v.size() * 2]; + Iterator> ite = v.entrySet().iterator(); + int i = 0; + while (ite.hasNext()) { + Map.Entry pair = ite.next(); + kvs[i] = pair.getKey(); + i++; + kvs[i] = pair.getValue(); + i++; + } + return kvs; + } + + @SuppressWarnings("unchecked") + public Map map() { + return (Map) objectValue; + } + } + + + //// + // ExtendedValue + // + + public Variable setExtendedValue(byte type, byte[] data) { + this.type = Type.EXTENDED; + this.accessor = extendedAccessor; + this.objectValue = ValueFactory.newExtendedValue(type, data); + return this; + } + + private class ExtendedValueAccessor extends AbstractValueAccessor implements ExtendedValue { + @Override + public ValueType getValueType() { + return ValueType.EXTENDED; + } + + @Override + public ExtendedValue asExtendedValue() { + return this; + } + + @Override + public ImmutableExtendedValue immutableValue() { + return (ImmutableExtendedValue) objectValue; + } + + @Override + public byte getType() { + return ((ImmutableExtendedValue) objectValue).getType(); + } + + @Override + public byte[] getData() { + return ((ImmutableExtendedValue) objectValue).getData(); + } + } + + + //// + // Value + // + + @Override + public ImmutableValue immutableValue() { + return accessor.immutableValue(); + } + + @Override + public void writeTo(MessagePacker pk) throws IOException { + // TODO + } + + @Override + public ValueType getValueType() { + return type.getValueType(); + } + + @Override + public boolean isNilValue() { + return getValueType().isNilType(); + } + + @Override + public boolean isBooleanValue() { + return getValueType().isBooleanType(); + } + + @Override + public boolean isNumberValue() { + return getValueType().isNumberType(); + } + + @Override + public boolean isIntegerValue() { + return getValueType().isIntegerType(); + } + + @Override + public boolean isFloatValue() { + return getValueType().isFloatType(); + } + + @Override + public boolean isRawValue() { + return getValueType().isRawType(); + } + + @Override + public boolean isBinaryValue() { + return getValueType().isBinaryType(); + } + + @Override + public boolean isStringValue() { + return getValueType().isStringType(); + } + + @Override + public boolean isArrayValue() { + return getValueType().isArrayType(); + } + + @Override + public boolean isMapValue() { + return getValueType().isMapType(); + } + + @Override + public boolean isExtendedValue() { + return getValueType().isExtendedType(); + } + + @Override + public NilValue asNilValue() { + if (!isNilValue()) { + throw new MessageTypeCastException(); + } + return (NilValue) accessor; + } + + @Override + public BooleanValue asBooleanValue() { + if (!isBooleanValue()) { + throw new MessageTypeCastException(); + } + return (BooleanValue) accessor; + } + + @Override + public NumberValue asNumberValue() { + if (!isNumberValue()) { + throw new MessageTypeCastException(); + } + return (NumberValue) accessor; + } + + @Override + public IntegerValue asIntegerValue() { + if (!isIntegerValue()) { + throw new MessageTypeCastException(); + } + return (IntegerValue) accessor; + } + + @Override + public FloatValue asFloatValue() { + if (!isFloatValue()) { + throw new MessageTypeCastException(); + } + return (FloatValue) accessor; + } + + @Override + public RawValue asRawValue() { + if (!isRawValue()) { + throw new MessageTypeCastException(); + } + return (RawValue) accessor; + } + + @Override + public BinaryValue asBinaryValue() { + if (!isBinaryValue()) { + throw new MessageTypeCastException(); + } + return (BinaryValue) accessor; + } + + @Override + public StringValue asStringValue() { + if (!isStringValue()) { + throw new MessageTypeCastException(); + } + return (StringValue) accessor; + } + + @Override + public ArrayValue asArrayValue() { + if (!isArrayValue()) { + throw new MessageTypeCastException(); + } + return (ArrayValue) accessor; + } + + @Override + public MapValue asMapValue() { + if (!isMapValue()) { + throw new MessageTypeCastException(); + } + return (MapValue) accessor; + } + + @Override + public ExtendedValue asExtendedValue() { + if (!isExtendedValue()) { + throw new MessageTypeCastException(); + } + return (ExtendedValue) accessor; + } +} diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableDoubleValueImpl.java b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableDoubleValueImpl.java index abe53166b..aa841bd82 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableDoubleValueImpl.java +++ b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableDoubleValueImpl.java @@ -21,8 +21,9 @@ import org.msgpack.value.FloatValue; import org.msgpack.value.ImmutableFloatValue; -import java.io.IOException; +import java.math.BigDecimal; import java.math.BigInteger; +import java.io.IOException; /** @@ -69,7 +70,7 @@ public long longValue() { @Override public BigInteger bigIntegerValue() { - return BigInteger.valueOf((long) value); + return new BigDecimal(value).toBigInteger(); } @Override diff --git a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java index b1125ca6b..0efa55509 100644 --- a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java +++ b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java @@ -11,7 +11,7 @@ import org.msgpack.core.buffer.InputStreamBufferInput; import org.msgpack.core.buffer.MessageBufferInput; import org.msgpack.value.Value; -import org.msgpack.value.ImmutableValue; +import org.msgpack.value.Variable; import org.msgpack.value.NumberValue; import org.msgpack.value.IntegerValue; import org.msgpack.value.ExtendedValue; @@ -33,7 +33,8 @@ public class MessagePackParser extends ParserMinimalBase { private JsonReadContext parsingContext; private final LinkedList stack = new LinkedList(); - private ImmutableValue value = ValueFactory.newNilValue(); + private Value value = ValueFactory.newNilValue(); + private Variable var = new Variable(); private boolean isClosed; private long tokenPosition; private long currentPosition; @@ -153,15 +154,15 @@ public JsonToken nextToken() throws IOException, JsonParseException { nextToken = b ? JsonToken.VALUE_TRUE : JsonToken.VALUE_FALSE; break; case INTEGER: - value = messageUnpacker.unpackValue(); + value = messageUnpacker.unpackValue(var); nextToken = JsonToken.VALUE_NUMBER_INT; break; case FLOAT: - value = messageUnpacker.unpackValue(); + value = messageUnpacker.unpackValue(var); nextToken = JsonToken.VALUE_NUMBER_FLOAT; break; case STRING: - value = messageUnpacker.unpackValue(); + value = messageUnpacker.unpackValue(var); if (parsingContext.inObject() && _currToken != JsonToken.FIELD_NAME) { parsingContext.setCurrentName(value.asRawValue().stringValue()); nextToken = JsonToken.FIELD_NAME; @@ -171,7 +172,7 @@ public JsonToken nextToken() throws IOException, JsonParseException { } break; case BINARY: - value = messageUnpacker.unpackValue(); + value = messageUnpacker.unpackValue(var); if (parsingContext.inObject() && _currToken != JsonToken.FIELD_NAME) { parsingContext.setCurrentName(value.asRawValue().stringValue()); nextToken = JsonToken.FIELD_NAME; @@ -190,7 +191,7 @@ public JsonToken nextToken() throws IOException, JsonParseException { newStack = new StackItemForObject(messageUnpacker.unpackMapHeader()); break; case EXTENDED: - value = messageUnpacker.unpackValue(); + value = messageUnpacker.unpackValue(var); nextToken = JsonToken.VALUE_EMBEDDED_OBJECT; break; default: From 339311096ca3332c9861ae532091d5a514c675b5 Mon Sep 17 00:00:00 2001 From: Sadayuki Furuhashi Date: Wed, 10 Jun 2015 11:48:29 +0900 Subject: [PATCH 060/234] implemented Variable.hashCode, equals, toString, and writeTo methods --- .../main/java/org/msgpack/value/Variable.java | 84 +++++++++++++++++-- 1 file changed, 78 insertions(+), 6 deletions(-) diff --git a/msgpack-core/src/main/java/org/msgpack/value/Variable.java b/msgpack-core/src/main/java/org/msgpack/value/Variable.java index f980acf00..7d303ff9d 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/Variable.java +++ b/msgpack-core/src/main/java/org/msgpack/value/Variable.java @@ -150,11 +150,6 @@ public ExtendedValue asExtendedValue() { throw new MessageTypeCastException(); } - @Override - public void writeTo(MessagePacker pk) throws IOException { - Variable.this.writeTo(pk); - } - @Override public boolean equals(Object obj) { return Variable.this.equals(obj); @@ -242,6 +237,11 @@ public NilValue asNilValue() { public ImmutableNilValue immutableValue() { return ValueFactory.newNilValue(); } + + @Override + public void writeTo(MessagePacker pk) throws IOException { + pk.packNil(); + } } @@ -276,6 +276,11 @@ public ImmutableBooleanValue immutableValue() { public boolean getBoolean() { return longValue == 1L; } + + @Override + public void writeTo(MessagePacker pk) throws IOException { + pk.packBoolean(longValue == 1L); + } } @@ -480,6 +485,15 @@ public BigInteger getBigInteger() { return BigInteger.valueOf(longValue); } } + + @Override + public void writeTo(MessagePacker pk) throws IOException { + if (type == Type.BIG_INTEGER) { + pk.packBigInteger((BigInteger) objectValue); + } else { + pk.packLong(longValue); + } + } } @@ -510,6 +524,11 @@ public ImmutableFloatValue immutableValue() { public ValueType getValueType() { return ValueType.FLOAT; } + + @Override + public void writeTo(MessagePacker pk) throws IOException { + pk.packDouble(doubleValue); + } } @@ -588,6 +607,13 @@ public BinaryValue asBinaryValue() { public ImmutableBinaryValue immutableValue() { return ValueFactory.newBinaryValue(getByteArray()); } + + @Override + public void writeTo(MessagePacker pk) throws IOException { + byte[] data = (byte[]) objectValue; + pk.packBinaryHeader(data.length); + pk.writePayload(data); + } } @@ -621,6 +647,13 @@ public StringValue asStringValue() { public ImmutableStringValue immutableValue() { return ValueFactory.newStringValue((byte[]) objectValue); } + + @Override + public void writeTo(MessagePacker pk) throws IOException { + byte[] data = (byte[]) objectValue; + pk.packRawStringHeader(data.length); + pk.writePayload(data); + } } @@ -680,6 +713,15 @@ public Iterator iterator() { public List list() { return (List) objectValue; } + + @Override + public void writeTo(MessagePacker pk) throws IOException { + List l = list(); + pk.packArrayHeader(l.size()); + for (Value e : l) { + e.writeTo(pk); + } + } } //// @@ -749,6 +791,16 @@ public Value[] getKeyValueArray() { public Map map() { return (Map) objectValue; } + + @Override + public void writeTo(MessagePacker pk) throws IOException { + Map m = map(); + pk.packArrayHeader(m.size()); + for (Map.Entry pair : m.entrySet()) { + pair.getKey().writeTo(pk); + pair.getValue().writeTo(pk); + } + } } @@ -788,6 +840,11 @@ public byte getType() { public byte[] getData() { return ((ImmutableExtendedValue) objectValue).getData(); } + + @Override + public void writeTo(MessagePacker pk) throws IOException { + ((ImmutableExtendedValue) objectValue).writeTo(pk); + } } @@ -802,7 +859,22 @@ public ImmutableValue immutableValue() { @Override public void writeTo(MessagePacker pk) throws IOException { - // TODO + accessor.writeTo(pk); + } + + @Override + public int hashCode() { + return immutableValue().hashCode(); // TODO optimize + } + + @Override + public boolean equals(Object o) { + return immutableValue().equals(o); // TODO optimize + } + + @Override + public String toString() { + return immutableValue().toString(); // TODO optimize } @Override From a40cbcba3d5b6a7536c40c9e0c2ca8d7579d3b6f Mon Sep 17 00:00:00 2001 From: Sadayuki Furuhashi Date: Wed, 10 Jun 2015 14:41:35 +0900 Subject: [PATCH 061/234] fixed Value API --- .../org/msgpack/core/MessageUnpacker.java | 17 ++++++++------- .../main/java/org/msgpack/value/Variable.java | 21 +++++++++---------- .../value/impl/AbstractImmutableRawValue.java | 3 +++ .../jackson/dataformat/MessagePackParser.java | 1 - 4 files changed, 23 insertions(+), 19 deletions(-) diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java b/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java index 12af8572f..f0a7df323 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java +++ b/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java @@ -625,9 +625,10 @@ public Variable unpackValue(Variable var) throws IOException { int size = unpackArrayHeader(); List list = new ArrayList(size); for (int i=0; i < size; i++) { - Variable e = new Variable(); - unpackValue(e); - list.add(e); + //Variable e = new Variable(); + //unpackValue(e); + //list.add(e); + list.add(unpackValue()); } var.setArrayValue(list); return var; @@ -636,10 +637,12 @@ public Variable unpackValue(Variable var) throws IOException { int size = unpackMapHeader(); Map map = new HashMap(); for (int i=0; i < size; i++) { - Variable k = new Variable(); - unpackValue(k); - Variable v = new Variable(); - unpackValue(v); + //Variable k = new Variable(); + //unpackValue(k); + //Variable v = new Variable(); + //unpackValue(v); + Value k = unpackValue(); + Value v = unpackValue(); map.put(k, v); } var.setMapValue(map); diff --git a/msgpack-core/src/main/java/org/msgpack/value/Variable.java b/msgpack-core/src/main/java/org/msgpack/value/Variable.java index 7d303ff9d..d29e9e0ba 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/Variable.java +++ b/msgpack-core/src/main/java/org/msgpack/value/Variable.java @@ -37,8 +37,7 @@ import java.nio.charset.CharacterCodingException; -public class Variable implements Value -{ +public class Variable implements Value { private abstract class AbstractValueAccessor implements Value { @Override public boolean isNilValue() { @@ -189,15 +188,15 @@ public ValueType getValueType() { } } - final NilValueAccessor nilAccessor = new NilValueAccessor(); - final BooleanValueAccessor booleanAccessor = new BooleanValueAccessor(); - final IntegerValueAccessor integerAccessor = new IntegerValueAccessor(); - final FloatValueAccessor floatAccessor = new FloatValueAccessor(); - final BinaryValueAccessor binaryAccessor = new BinaryValueAccessor(); - final StringValueAccessor stringAccessor = new StringValueAccessor(); - final ArrayValueAccessor arrayAccessor = new ArrayValueAccessor(); - final MapValueAccessor mapAccessor = new MapValueAccessor(); - final ExtendedValueAccessor extendedAccessor = new ExtendedValueAccessor(); + private final NilValueAccessor nilAccessor = new NilValueAccessor(); + private final BooleanValueAccessor booleanAccessor = new BooleanValueAccessor(); + private final IntegerValueAccessor integerAccessor = new IntegerValueAccessor(); + private final FloatValueAccessor floatAccessor = new FloatValueAccessor(); + private final BinaryValueAccessor binaryAccessor = new BinaryValueAccessor(); + private final StringValueAccessor stringAccessor = new StringValueAccessor(); + private final ArrayValueAccessor arrayAccessor = new ArrayValueAccessor(); + private final MapValueAccessor mapAccessor = new MapValueAccessor(); + private final ExtendedValueAccessor extendedAccessor = new ExtendedValueAccessor(); private Type type; diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/AbstractImmutableRawValue.java b/msgpack-core/src/main/java/org/msgpack/value/impl/AbstractImmutableRawValue.java index 29b9e29b9..b72461943 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/impl/AbstractImmutableRawValue.java +++ b/msgpack-core/src/main/java/org/msgpack/value/impl/AbstractImmutableRawValue.java @@ -73,6 +73,9 @@ public String getString() { @Override public String stringValue() { + if (decodedStringCache == null) { + decodeString(); + } return decodedStringCache; } diff --git a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java index 0efa55509..8594e1e17 100644 --- a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java +++ b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java @@ -178,7 +178,6 @@ public JsonToken nextToken() throws IOException, JsonParseException { nextToken = JsonToken.FIELD_NAME; } else { - nextToken = JsonToken.VALUE_STRING; nextToken = JsonToken.VALUE_EMBEDDED_OBJECT; } break; From 2ff4f5972880e2f09338a7f3673bf31969453922 Mon Sep 17 00:00:00 2001 From: Sadayuki Furuhashi Date: Wed, 10 Jun 2015 14:44:36 +0900 Subject: [PATCH 062/234] ImmutableMapValueImpl.equals should not assume order of elements is same --- .../value/impl/ImmutableArrayValueImpl.java | 2 +- .../value/impl/ImmutableMapValueImpl.java | 32 +++---------------- 2 files changed, 5 insertions(+), 29 deletions(-) diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableArrayValueImpl.java b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableArrayValueImpl.java index e32577cd4..0ada4f4d2 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableArrayValueImpl.java +++ b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableArrayValueImpl.java @@ -74,7 +74,7 @@ public Value get(int index) { @Override public Value getOrNilValue(int index) { - if (array.length < index && index >= 0) { + if (index < array.length && index >= 0) { return array[index]; } return ImmutableNilValueImpl.get(); diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableMapValueImpl.java b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableMapValueImpl.java index 51d504f07..5061fad19 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableMapValueImpl.java +++ b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableMapValueImpl.java @@ -114,35 +114,11 @@ public boolean equals(Object o) { } Value v = (Value) o; - if (v instanceof ImmutableMapValueImpl) { - ImmutableMapValueImpl om = (ImmutableMapValueImpl) v; - return Arrays.equals(kvs, om.kvs); - } else { - if (!v.isMapValue()) { - return false; - } - MapValue mv = v.asMapValue(); - if (size() != mv.size()) { - return false; - } - Map m = mv.map(); - Iterator> ite = entrySet().iterator(); - while (ite.hasNext()) { - Map.Entry e = ite.next(); - Value ek = e.getKey(); - Value ev = e.getValue(); - if (ev == null) { - if (!(m.get(ek) == null && m.containsKey(ek))) { - return false; - } - } else { - if (!ev.equals(m.get(ek))) { - return false; - } - } - } - return true; + if (!v.isMapValue()) { + return false; } + MapValue mv = v.asMapValue(); + return map().equals(mv.map()); } @Override From e2fc4e68171348bc83755ed80c6d048d776c9f4d Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Sat, 13 Jun 2015 22:14:43 +0900 Subject: [PATCH 063/234] Renmae ExtendedType -> ExtensionType --- README.md | 3 +- RELEASE_NOTES.md | 2 +- ...peHeader.java => ExtensionTypeHeader.java} | 12 ++-- .../java/org/msgpack/core/MessageFormat.java | 16 ++--- .../java/org/msgpack/core/MessagePacker.java | 8 +-- .../org/msgpack/core/MessageUnpacker.java | 31 +++++----- .../core/example/MessagePackExample.java | 7 +-- ...ExtendedValue.java => ExtensionValue.java} | 9 +-- ...alue.java => ImmutableExtensionValue.java} | 2 +- .../main/java/org/msgpack/value/Value.java | 19 +++--- .../java/org/msgpack/value/ValueFactory.java | 8 +-- .../java/org/msgpack/value/ValueType.java | 8 +-- .../main/java/org/msgpack/value/Variable.java | 48 +++++++-------- .../value/impl/AbstractImmutableValue.java | 6 +- ....java => ImmutableExtensionValueImpl.java} | 24 ++++---- .../org/msgpack/core/MessageFormatTest.scala | 16 ++--- .../org/msgpack/core/MessagePackTest.scala | 10 ++-- .../org/msgpack/value/ValueFactoryTest.scala | 9 ++- .../org/msgpack/value/ValueTypeTest.scala | 2 +- .../jackson/dataformat/MessagePackParser.java | 10 +--- .../MessagePackExtendedTypeTest.java | 60 ------------------- .../MessagePackExtensionTypeTest.java | 60 +++++++++++++++++++ .../dataformat/MessagePackParserTest.java | 16 ++--- 23 files changed, 189 insertions(+), 197 deletions(-) rename msgpack-core/src/main/java/org/msgpack/core/{ExtendedTypeHeader.java => ExtensionTypeHeader.java} (69%) rename msgpack-core/src/main/java/org/msgpack/value/{ExtendedValue.java => ExtensionValue.java} (70%) rename msgpack-core/src/main/java/org/msgpack/value/{ImmutableExtendedValue.java => ImmutableExtensionValue.java} (88%) rename msgpack-core/src/main/java/org/msgpack/value/impl/{ImmutableExtendedValueImpl.java => ImmutableExtensionValueImpl.java} (75%) delete mode 100644 msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackExtendedTypeTest.java create mode 100644 msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackExtensionTypeTest.java diff --git a/README.md b/README.md index 4cc7ee4f6..73fa29f4d 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,8 @@ MessagePack for Java * Message Pack specification: -MessagePack v7 (0.7.x) is a faster implementation of the previous version [v06](https://github.com/msgpack/msgpack-java/tree/v06), and supports all of the message pack types, including [extended format](https://github.com/msgpack/msgpack/blob/master/spec.md#formats-ext). +MessagePack v7 (0.7.x) is a faster implementation of the previous version [v06](https://github.com/msgpack/msgpack-java/tree/v06), and +supports all of the message pack types, including [extension format](https://github.com/msgpack/msgpack/blob/master/spec.md#formats-ext). ## Limitation - Value API is in a designing phase: https://github.com/msgpack/msgpack-java/pull/109 diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index b0f19d52a..f7e44f3d7 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -4,7 +4,7 @@ * Fix [#217] when reading from SockectInputStream * 2015-04-09 0.7.0-p8 - * Support Extended type (defined in MessagePack) in msgpack-jackson + * Support Extension type (defined in MessagePack) in msgpack-jackson * Support BigDecimal type (defined in Jackson) in msgpack-jackson * Fix MessageUnpacker#unpackString [#215](https://github.com/msgpack/msgpack-java/pull/215), [#216](https://github.com/msgpack/msgpack-java/pull/216) diff --git a/msgpack-core/src/main/java/org/msgpack/core/ExtendedTypeHeader.java b/msgpack-core/src/main/java/org/msgpack/core/ExtensionTypeHeader.java similarity index 69% rename from msgpack-core/src/main/java/org/msgpack/core/ExtendedTypeHeader.java rename to msgpack-core/src/main/java/org/msgpack/core/ExtensionTypeHeader.java index 517e971fe..b507f978d 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/ExtendedTypeHeader.java +++ b/msgpack-core/src/main/java/org/msgpack/core/ExtensionTypeHeader.java @@ -3,13 +3,13 @@ import static org.msgpack.core.Preconditions.*; /** - * Header of the extended types + * Header of the Extension types */ -public class ExtendedTypeHeader { +public class ExtensionTypeHeader { private final byte type; private final int length; - ExtendedTypeHeader(byte type, int length) { + ExtensionTypeHeader(byte type, int length) { checkArgument(length >= 0, String.format("length must be >= 0: %,d", length)); this.length = length; this.type = type; @@ -30,8 +30,8 @@ public int hashCode() { @Override public boolean equals(Object obj) { - if(obj instanceof ExtendedTypeHeader) { - ExtendedTypeHeader other = (ExtendedTypeHeader) obj; + if(obj instanceof ExtensionTypeHeader) { + ExtensionTypeHeader other = (ExtensionTypeHeader) obj; return this.type == other.type && this.length == other.length; } return false; @@ -39,7 +39,7 @@ public boolean equals(Object obj) { @Override public String toString() { - return String.format("ExtendedTypeHeader(type:%d, length:%,d)", type, length); + return String.format("ExtensionTypeHeader(type:%d, length:%,d)", type, length); } } diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessageFormat.java b/msgpack-core/src/main/java/org/msgpack/core/MessageFormat.java index 7e32bcc79..b00681244 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/MessageFormat.java +++ b/msgpack-core/src/main/java/org/msgpack/core/MessageFormat.java @@ -24,9 +24,9 @@ public enum MessageFormat { BIN8(ValueType.BINARY), BIN16(ValueType.BINARY), BIN32(ValueType.BINARY), - EXT8(ValueType.EXTENDED), - EXT16(ValueType.EXTENDED), - EXT32(ValueType.EXTENDED), + EXT8(ValueType.EXTENSION), + EXT16(ValueType.EXTENSION), + EXT32(ValueType.EXTENSION), FLOAT32(ValueType.FLOAT), FLOAT64(ValueType.FLOAT), UINT8(ValueType.INTEGER), @@ -38,11 +38,11 @@ public enum MessageFormat { INT16(ValueType.INTEGER), INT32(ValueType.INTEGER), INT64(ValueType.INTEGER), - FIXEXT1(ValueType.EXTENDED), - FIXEXT2(ValueType.EXTENDED), - FIXEXT4(ValueType.EXTENDED), - FIXEXT8(ValueType.EXTENDED), - FIXEXT16(ValueType.EXTENDED), + FIXEXT1(ValueType.EXTENSION), + FIXEXT2(ValueType.EXTENSION), + FIXEXT4(ValueType.EXTENSION), + FIXEXT8(ValueType.EXTENSION), + FIXEXT16(ValueType.EXTENSION), STR8(ValueType.STRING), STR16(ValueType.STRING), STR32(ValueType.STRING), diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessagePacker.java b/msgpack-core/src/main/java/org/msgpack/core/MessagePacker.java index 16f49c656..ec74f53f2 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/MessagePacker.java +++ b/msgpack-core/src/main/java/org/msgpack/core/MessagePacker.java @@ -379,7 +379,7 @@ public MessagePacker packString(String s) throws IOException { flush(); prepareBuffer(); - boolean isExtended = false; + boolean isExtension = false; ByteBuffer encodeBuffer = buffer.toByteBuffer(position, buffer.size() - position); encoder.reset(); while(in.hasRemaining()) { @@ -400,7 +400,7 @@ public MessagePacker packString(String s) throws IOException { // Coy the current encodeBuffer contents to the new buffer newBuffer.put(encodeBuffer); encodeBuffer = newBuffer; - isExtended = true; + isExtension = true; encoder.reset(); continue; } @@ -434,7 +434,7 @@ public MessagePacker packString(String s) throws IOException { flush(); // We need to dump the data here to MessageBufferOutput so that we can switch back to the original buffer // Reset to the original buffer (or encodeBuffer if new buffer is allocated) - buffer = isExtended ? MessageBuffer.wrap(encodeBuffer) : tmpBuf; + buffer = isExtension ? MessageBuffer.wrap(encodeBuffer) : tmpBuf; // No need exists to write payload since the encoded string (payload) is already written to the buffer position = strLen; return this; @@ -477,7 +477,7 @@ public MessagePacker packValue(Value v) throws IOException { return this; } - public MessagePacker packExtendedTypeHeader(int extType, int payloadLen) throws IOException { + public MessagePacker packExtensionTypeHeader(int extType, int payloadLen) throws IOException { if(payloadLen < (1 << 8)) { if(payloadLen > 0 && (payloadLen & (payloadLen - 1)) == 0) { // check whether dataLen == 2^x if(payloadLen == 1) { diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java b/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java index f0a7df323..b81ad808c 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java +++ b/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java @@ -37,7 +37,6 @@ import org.msgpack.value.Value; import org.msgpack.value.ImmutableValue; import org.msgpack.value.Variable; -import org.msgpack.value.ValueType; import org.msgpack.value.ValueFactory; import static org.msgpack.core.Preconditions.*; @@ -580,9 +579,9 @@ public ImmutableValue unpackValue() throws IOException { } return ValueFactory.newMapValue(kvs); } - case EXTENDED: { - ExtendedTypeHeader extHeader = unpackExtendedTypeHeader(); - return ValueFactory.newExtendedValue(extHeader.getType(), readPayload(extHeader.getLength())); + case EXTENSION: { + ExtensionTypeHeader extHeader = unpackExtensionTypeHeader(); + return ValueFactory.newExtensionValue(extHeader.getType(), readPayload(extHeader.getLength())); } default: throw new MessageFormatException("Unknown value type"); @@ -648,9 +647,9 @@ public Variable unpackValue(Variable var) throws IOException { var.setMapValue(map); return var; } - case EXTENDED: { - ExtendedTypeHeader extHeader = unpackExtendedTypeHeader(); - var.setExtendedValue(extHeader.getType(), readPayload(extHeader.getLength())); + case EXTENSION: { + ExtensionTypeHeader extHeader = unpackExtensionTypeHeader(); + var.setExtensionValue(extHeader.getType(), readPayload(extHeader.getLength())); return var; } default: @@ -1042,33 +1041,33 @@ public int unpackMapHeader() throws IOException { throw unexpected("Map", b); } - public ExtendedTypeHeader unpackExtendedTypeHeader() throws IOException { + public ExtensionTypeHeader unpackExtensionTypeHeader() throws IOException { byte b = consume(); switch(b) { case Code.FIXEXT1: - return new ExtendedTypeHeader(readByte(), 1); + return new ExtensionTypeHeader(readByte(), 1); case Code.FIXEXT2: - return new ExtendedTypeHeader(readByte(), 2); + return new ExtensionTypeHeader(readByte(), 2); case Code.FIXEXT4: - return new ExtendedTypeHeader(readByte(), 4); + return new ExtensionTypeHeader(readByte(), 4); case Code.FIXEXT8: - return new ExtendedTypeHeader(readByte(), 8); + return new ExtensionTypeHeader(readByte(), 8); case Code.FIXEXT16: - return new ExtendedTypeHeader(readByte(), 16); + return new ExtensionTypeHeader(readByte(), 16); case Code.EXT8: { int length = readNextLength8(); byte type = readByte(); - return new ExtendedTypeHeader(type, length); + return new ExtensionTypeHeader(type, length); } case Code.EXT16: { int length = readNextLength16(); byte type = readByte(); - return new ExtendedTypeHeader(type, length); + return new ExtensionTypeHeader(type, length); } case Code.EXT32: { int length = readNextLength32(); byte type = readByte(); - return new ExtendedTypeHeader(type, length); + return new ExtensionTypeHeader(type, length); } } diff --git a/msgpack-core/src/main/java/org/msgpack/core/example/MessagePackExample.java b/msgpack-core/src/main/java/org/msgpack/core/example/MessagePackExample.java index 60988c7e4..c057b9513 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/example/MessagePackExample.java +++ b/msgpack-core/src/main/java/org/msgpack/core/example/MessagePackExample.java @@ -16,7 +16,6 @@ package org.msgpack.core.example; import org.msgpack.core.*; -import org.msgpack.core.buffer.MessageBuffer; import org.msgpack.value.*; import java.math.BigInteger; @@ -126,7 +125,7 @@ public static void packer() throws IOException { // Write ext type data: https://github.com/msgpack/msgpack/blob/master/spec.md#ext-format-family byte[] extData = "custom data type".getBytes(MessagePack.UTF8); - packer.packExtendedTypeHeader(1, 10); // type number [0, 127], data byte length + packer.packExtensionTypeHeader(1, 10); // type number [0, 127], data byte length packer.writePayload(extData); // Succinct syntax for packing @@ -217,8 +216,8 @@ else if (iv.isInLongRange()) { System.out.println("read array element: " + e); } break; - case EXTENDED: - ExtendedValue ev = v.asExtendedValue(); + case EXTENSION: + ExtensionValue ev = v.asExtensionValue(); byte extType = ev.getType(); byte[] extValue = ev.getData(); break; diff --git a/msgpack-core/src/main/java/org/msgpack/value/ExtendedValue.java b/msgpack-core/src/main/java/org/msgpack/value/ExtensionValue.java similarity index 70% rename from msgpack-core/src/main/java/org/msgpack/value/ExtendedValue.java rename to msgpack-core/src/main/java/org/msgpack/value/ExtensionValue.java index 220e5737b..cda4812cd 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/ExtendedValue.java +++ b/msgpack-core/src/main/java/org/msgpack/value/ExtensionValue.java @@ -16,15 +16,16 @@ package org.msgpack.value; /** - * The interface {@code ExtendedValue} represents MessagePack's Extended type. + * The interface {@code ExtensionValue} represents MessagePack's Extension type. * - * MessagePack's Extended type can represent represents a tuple of type information and a byte array where type information is an integer whose meaning is defined by applications. + * MessagePack's Extension type can represent represents a tuple of type information and a byte array where type information is an + * integer whose meaning is defined by applications. * * As the type information, applications can use 0 to 127 as the application-specific types. -1 to -128 is reserved for MessagePack's future extension. */ -public interface ExtendedValue extends Value { +public interface ExtensionValue extends Value { @Override - public ImmutableExtendedValue immutableValue(); + public ImmutableExtensionValue immutableValue(); public byte getType(); diff --git a/msgpack-core/src/main/java/org/msgpack/value/ImmutableExtendedValue.java b/msgpack-core/src/main/java/org/msgpack/value/ImmutableExtensionValue.java similarity index 88% rename from msgpack-core/src/main/java/org/msgpack/value/ImmutableExtendedValue.java rename to msgpack-core/src/main/java/org/msgpack/value/ImmutableExtensionValue.java index 4d77577d4..ff1f0e9ea 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/ImmutableExtendedValue.java +++ b/msgpack-core/src/main/java/org/msgpack/value/ImmutableExtensionValue.java @@ -15,5 +15,5 @@ // package org.msgpack.value; -public interface ImmutableExtendedValue extends ExtendedValue, ImmutableValue { +public interface ImmutableExtensionValue extends ExtensionValue, ImmutableValue { } diff --git a/msgpack-core/src/main/java/org/msgpack/value/Value.java b/msgpack-core/src/main/java/org/msgpack/value/Value.java index b8926dfa9..d0b8bdcd1 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/Value.java +++ b/msgpack-core/src/main/java/org/msgpack/value/Value.java @@ -16,6 +16,7 @@ package org.msgpack.value; import org.msgpack.core.MessagePacker; +import org.msgpack.core.MessageTypeCastException; import java.io.IOException; @@ -119,12 +120,13 @@ public interface Value { public boolean isMapValue(); /** - * Returns true if type of this an Extended. + * Returns true if type of this an Extension. * - * If this method returns true, {@code asExtendedValue} never throws exceptions. - * Note that you can't use instanceof or cast ((ExtendedValue) thisValue) to check type of a value because type of a mutable value is variable. + * If this method returns true, {@code asExtensionValue} never throws exceptions. + * Note that you can't use instanceof or cast ((ExtensionValue) thisValue) to check type of a value because + * type of a mutable value is variable. */ - public boolean isExtendedValue(); + public boolean isExtensionValue(); /** * Returns the value as {@code NilValue}. Otherwise throws {@code MessageTypeCastException}. @@ -227,14 +229,15 @@ public interface Value { public MapValue asMapValue(); /** - * Returns the value as {@code ExtendedValue}. Otherwise throws {@code MessageTypeCastException}. + * Returns the value as {@code ExtensionValue}. Otherwise throws {@code MessageTypeCastException}. * - * Note that you can't use instanceof or cast ((ExtendedValue) thisValue) to check type of a value because type of a mutable value is variable. + * Note that you can't use instanceof or cast ((ExtensionValue) thisValue) to check type of a value + * because type of a mutable value is variable. * * @throws MessageTypeCastException - * If type of this value is not Extended. + * If type of this value is not an Extension. */ - public ExtendedValue asExtendedValue(); + public ExtensionValue asExtensionValue(); /** * Serializes the value using the specified {@code MessagePacker} diff --git a/msgpack-core/src/main/java/org/msgpack/value/ValueFactory.java b/msgpack-core/src/main/java/org/msgpack/value/ValueFactory.java index 4d6458728..84f3e7495 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/ValueFactory.java +++ b/msgpack-core/src/main/java/org/msgpack/value/ValueFactory.java @@ -24,15 +24,13 @@ import org.msgpack.value.impl.ImmutableStringValueImpl; import org.msgpack.value.impl.ImmutableArrayValueImpl; import org.msgpack.value.impl.ImmutableMapValueImpl; -import org.msgpack.value.impl.ImmutableExtendedValueImpl; +import org.msgpack.value.impl.ImmutableExtensionValueImpl; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Arrays; import java.math.BigInteger; -import java.io.UnsupportedEncodingException; -import java.nio.ByteBuffer; public final class ValueFactory { private ValueFactory() { } @@ -134,7 +132,7 @@ public static ImmutableMapValue newMapValue(Value[] kvs) { return new ImmutableMapValueImpl(Arrays.copyOf(kvs, kvs.length)); } - public static ImmutableExtendedValue newExtendedValue(byte type, byte[] data) { - return new ImmutableExtendedValueImpl(type, data); + public static ImmutableExtensionValue newExtensionValue(byte type, byte[] data) { + return new ImmutableExtensionValueImpl(type, data); } } diff --git a/msgpack-core/src/main/java/org/msgpack/value/ValueType.java b/msgpack-core/src/main/java/org/msgpack/value/ValueType.java index 8a2ce8c83..3d5a9c588 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/ValueType.java +++ b/msgpack-core/src/main/java/org/msgpack/value/ValueType.java @@ -15,8 +15,6 @@ // package org.msgpack.value; -import org.msgpack.core.MessageFormat; - /** * MessageTypeFamily is a group of {@link org.msgpack.core.MessageFormat}s */ @@ -30,7 +28,7 @@ public enum ValueType { BINARY(false, true), ARRAY(false, false), MAP(false, false), - EXTENDED(false, true); + EXTENSION(false, true); private final boolean numberType; private final boolean rawType; @@ -80,7 +78,7 @@ public boolean isMapType() { return this == MAP; } - public boolean isExtendedType() { - return this == EXTENDED; + public boolean isExtensionType() { + return this == EXTENSION; } } diff --git a/msgpack-core/src/main/java/org/msgpack/value/Variable.java b/msgpack-core/src/main/java/org/msgpack/value/Variable.java index d29e9e0ba..b36ae59a6 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/Variable.java +++ b/msgpack-core/src/main/java/org/msgpack/value/Variable.java @@ -20,7 +20,6 @@ import org.msgpack.core.MessageTypeCastException; import org.msgpack.core.MessageStringCodingException; import org.msgpack.core.MessageIntegerOverflowException; -import org.msgpack.value.*; import java.math.BigDecimal; import java.math.BigInteger; @@ -32,7 +31,6 @@ import java.io.IOException; import java.nio.ByteBuffer; import java.nio.charset.CharsetDecoder; -import java.nio.charset.CharsetEncoder; import java.nio.charset.CodingErrorAction; import java.nio.charset.CharacterCodingException; @@ -90,8 +88,8 @@ public boolean isMapValue() { } @Override - public boolean isExtendedValue() { - return getValueType().isExtendedType(); + public boolean isExtensionValue() { + return getValueType().isExtensionType(); } @Override @@ -145,7 +143,7 @@ public MapValue asMapValue() { } @Override - public ExtendedValue asExtendedValue() { + public ExtensionValue asExtensionValue() { throw new MessageTypeCastException(); } @@ -175,7 +173,7 @@ public static enum Type { RAW_STRING(ValueType.STRING), LIST(ValueType.ARRAY), MAP(ValueType.MAP), - EXTENDED(ValueType.EXTENDED); + EXTENSION(ValueType.EXTENSION); private final ValueType valueType; @@ -196,7 +194,7 @@ public ValueType getValueType() { private final StringValueAccessor stringAccessor = new StringValueAccessor(); private final ArrayValueAccessor arrayAccessor = new ArrayValueAccessor(); private final MapValueAccessor mapAccessor = new MapValueAccessor(); - private final ExtendedValueAccessor extendedAccessor = new ExtendedValueAccessor(); + private final ExtensionValueAccessor extensionAccessor = new ExtensionValueAccessor(); private Type type; @@ -804,45 +802,45 @@ public void writeTo(MessagePacker pk) throws IOException { //// - // ExtendedValue + // ExtensionValue // - public Variable setExtendedValue(byte type, byte[] data) { - this.type = Type.EXTENDED; - this.accessor = extendedAccessor; - this.objectValue = ValueFactory.newExtendedValue(type, data); + public Variable setExtensionValue(byte type, byte[] data) { + this.type = Type.EXTENSION; + this.accessor = extensionAccessor; + this.objectValue = ValueFactory.newExtensionValue(type, data); return this; } - private class ExtendedValueAccessor extends AbstractValueAccessor implements ExtendedValue { + private class ExtensionValueAccessor extends AbstractValueAccessor implements ExtensionValue { @Override public ValueType getValueType() { - return ValueType.EXTENDED; + return ValueType.EXTENSION; } @Override - public ExtendedValue asExtendedValue() { + public ExtensionValue asExtensionValue() { return this; } @Override - public ImmutableExtendedValue immutableValue() { - return (ImmutableExtendedValue) objectValue; + public ImmutableExtensionValue immutableValue() { + return (ImmutableExtensionValue) objectValue; } @Override public byte getType() { - return ((ImmutableExtendedValue) objectValue).getType(); + return ((ImmutableExtensionValue) objectValue).getType(); } @Override public byte[] getData() { - return ((ImmutableExtendedValue) objectValue).getData(); + return ((ImmutableExtensionValue) objectValue).getData(); } @Override public void writeTo(MessagePacker pk) throws IOException { - ((ImmutableExtendedValue) objectValue).writeTo(pk); + ((ImmutableExtensionValue) objectValue).writeTo(pk); } } @@ -932,8 +930,8 @@ public boolean isMapValue() { } @Override - public boolean isExtendedValue() { - return getValueType().isExtendedType(); + public boolean isExtensionValue() { + return getValueType().isExtensionType(); } @Override @@ -1017,10 +1015,10 @@ public MapValue asMapValue() { } @Override - public ExtendedValue asExtendedValue() { - if (!isExtendedValue()) { + public ExtensionValue asExtensionValue() { + if (!isExtensionValue()) { throw new MessageTypeCastException(); } - return (ExtendedValue) accessor; + return (ExtensionValue) accessor; } } diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/AbstractImmutableValue.java b/msgpack-core/src/main/java/org/msgpack/value/impl/AbstractImmutableValue.java index e3cd51821..1f337e127 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/impl/AbstractImmutableValue.java +++ b/msgpack-core/src/main/java/org/msgpack/value/impl/AbstractImmutableValue.java @@ -71,8 +71,8 @@ public boolean isMapValue() { } @Override - public boolean isExtendedValue() { - return getValueType().isExtendedType(); + public boolean isExtensionValue() { + return getValueType().isExtensionType(); } @Override @@ -126,7 +126,7 @@ public ImmutableMapValue asMapValue() { } @Override - public ImmutableExtendedValue asExtendedValue() { + public ImmutableExtensionValue asExtensionValue() { throw new MessageTypeCastException(); } } diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableExtendedValueImpl.java b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableExtensionValueImpl.java similarity index 75% rename from msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableExtendedValueImpl.java rename to msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableExtensionValueImpl.java index 8ff5af324..b1c5036ab 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableExtendedValueImpl.java +++ b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableExtensionValueImpl.java @@ -18,39 +18,39 @@ import org.msgpack.core.MessagePacker; import org.msgpack.value.Value; import org.msgpack.value.ValueType; -import org.msgpack.value.ExtendedValue; -import org.msgpack.value.ImmutableExtendedValue; +import org.msgpack.value.ExtensionValue; +import org.msgpack.value.ImmutableExtensionValue; import java.util.Arrays; import java.io.IOException; /** - * {@code ImmutableExtendedValueImpl} Implements {@code ImmutableExtendedValue} using a {@code byte} and a {@code byte[]} fields. + * {@code ImmutableExtensionValueImpl} Implements {@code ImmutableExtensionValue} using a {@code byte} and a {@code byte[]} fields. * - * @see org.msgpack.value.ExtendedValue + * @see ExtensionValue */ -public class ImmutableExtendedValueImpl extends AbstractImmutableValue implements ImmutableExtendedValue { +public class ImmutableExtensionValueImpl extends AbstractImmutableValue implements ImmutableExtensionValue { private final byte type; private final byte[] data; - public ImmutableExtendedValueImpl(byte type, byte[] data) { + public ImmutableExtensionValueImpl(byte type, byte[] data) { this.type = type; this.data = data; } @Override public ValueType getValueType() { - return ValueType.EXTENDED; + return ValueType.EXTENSION; } @Override - public ImmutableExtendedValue immutableValue() { + public ImmutableExtensionValue immutableValue() { return this; } @Override - public ImmutableExtendedValue asExtendedValue() { + public ImmutableExtensionValue asExtensionValue() { return this; } @@ -66,7 +66,7 @@ public byte[] getData() { @Override public void writeTo(MessagePacker packer) throws IOException { - packer.packExtendedTypeHeader(type, data.length); + packer.packExtensionTypeHeader(type, data.length); packer.writePayload(data); } @@ -80,10 +80,10 @@ public boolean equals(Object o) { } Value v = (Value) o; - if (!v.isExtendedValue()) { + if (!v.isExtensionValue()) { return false; } - ExtendedValue ev = v.asExtendedValue(); + ExtensionValue ev = v.asExtensionValue(); return type == ev.getType() && Arrays.equals(data, ev.getData()); } diff --git a/msgpack-core/src/test/scala/org/msgpack/core/MessageFormatTest.scala b/msgpack-core/src/test/scala/org/msgpack/core/MessageFormatTest.scala index c4e381cd0..7f89760f8 100644 --- a/msgpack-core/src/test/scala/org/msgpack/core/MessageFormatTest.scala +++ b/msgpack-core/src/test/scala/org/msgpack/core/MessageFormatTest.scala @@ -52,14 +52,14 @@ class MessageFormatTest extends MessagePackSpec { check(Code.BIN16, ValueType.BINARY, MessageFormat.BIN16) check(Code.BIN32, ValueType.BINARY, MessageFormat.BIN32) - check(Code.FIXEXT1, ValueType.EXTENDED, MessageFormat.FIXEXT1) - check(Code.FIXEXT2, ValueType.EXTENDED, MessageFormat.FIXEXT2) - check(Code.FIXEXT4, ValueType.EXTENDED, MessageFormat.FIXEXT4) - check(Code.FIXEXT8, ValueType.EXTENDED, MessageFormat.FIXEXT8) - check(Code.FIXEXT16, ValueType.EXTENDED, MessageFormat.FIXEXT16) - check(Code.EXT8, ValueType.EXTENDED, MessageFormat.EXT8) - check(Code.EXT16, ValueType.EXTENDED, MessageFormat.EXT16) - check(Code.EXT32, ValueType.EXTENDED, MessageFormat.EXT32) + check(Code.FIXEXT1, ValueType.EXTENSION, MessageFormat.FIXEXT1) + check(Code.FIXEXT2, ValueType.EXTENSION, MessageFormat.FIXEXT2) + check(Code.FIXEXT4, ValueType.EXTENSION, MessageFormat.FIXEXT4) + check(Code.FIXEXT8, ValueType.EXTENSION, MessageFormat.FIXEXT8) + check(Code.FIXEXT16, ValueType.EXTENSION, MessageFormat.FIXEXT16) + check(Code.EXT8, ValueType.EXTENSION, MessageFormat.EXT8) + check(Code.EXT16, ValueType.EXTENSION, MessageFormat.EXT16) + check(Code.EXT32, ValueType.EXTENSION, MessageFormat.EXT32) check(Code.INT8, ValueType.INTEGER, MessageFormat.INT8) diff --git a/msgpack-core/src/test/scala/org/msgpack/core/MessagePackTest.scala b/msgpack-core/src/test/scala/org/msgpack/core/MessagePackTest.scala index 59d71b6e8..cf241537f 100644 --- a/msgpack-core/src/test/scala/org/msgpack/core/MessagePackTest.scala +++ b/msgpack-core/src/test/scala/org/msgpack/core/MessagePackTest.scala @@ -414,19 +414,19 @@ class MessagePackTest extends MessagePackSpec { } - "pack/unpack extended types" taggedAs("ext") in { + "pack/unpack extension types" taggedAs("ext") in { forAll { (dataLen: Int, tpe: Int) => val l = Math.abs(dataLen) val t = Math.abs(tpe) % 128 whenever(l >= 0) { - val ext = new ExtendedTypeHeader(l, t) - check(ext, _.packExtendedTypeHeader(ext.getType, ext.getLength), _.unpackExtendedTypeHeader()) + val ext = new ExtensionTypeHeader(l, t) + check(ext, _.packExtensionTypeHeader(ext.getType, ext.getLength), _.unpackExtensionTypeHeader()) } } for(l <- testHeaderLength) { - val ext = new ExtendedTypeHeader(l, Random.nextInt(128)) - check(ext, _.packExtendedTypeHeader(ext.getType, ext.getLength), _.unpackExtendedTypeHeader()) + val ext = new ExtensionTypeHeader(l, Random.nextInt(128)) + check(ext, _.packExtensionTypeHeader(ext.getType, ext.getLength), _.unpackExtensionTypeHeader()) } } diff --git a/msgpack-core/src/test/scala/org/msgpack/value/ValueFactoryTest.scala b/msgpack-core/src/test/scala/org/msgpack/value/ValueFactoryTest.scala index cb79a575e..7465de706 100644 --- a/msgpack-core/src/test/scala/org/msgpack/value/ValueFactoryTest.scala +++ b/msgpack-core/src/test/scala/org/msgpack/value/ValueFactoryTest.scala @@ -1,10 +1,9 @@ package org.msgpack.value -import org.scalatest.FunSuite import org.msgpack.core.MessagePackSpec /** - * Created on 6/13/14. + * */ class ValueFactoryTest extends MessagePackSpec { @@ -18,7 +17,7 @@ class ValueFactoryTest extends MessagePackSpec { isBinary: Boolean = false, isArray: Boolean = false, isMap: Boolean = false, - isExtended : Boolean = false, + isExtension : Boolean = false, isRaw : Boolean = false, isNumber : Boolean = false ) { @@ -30,7 +29,7 @@ class ValueFactoryTest extends MessagePackSpec { v.isBinary shouldBe isBinary v.isArray shouldBe isArray v.isMap shouldBe isMap - v.isExtended shouldBe isExtended + v.isExtension shouldBe isExtension v.isRaw shouldBe isRaw v.isNumber shouldBe isNumber } @@ -46,7 +45,7 @@ class ValueFactoryTest extends MessagePackSpec { forAll{(v:Array[Byte]) => isValid(ValueFactory.newBinary(v), expected=ValueType.BINARY, isBinary = true, isRaw = true)} isValid(ValueFactory.emptyArray(), expected=ValueType.ARRAY, isArray = true) isValid(ValueFactory.emptyMap(), expected=ValueType.MAP, isMap = true) - forAll{(v:Array[Byte]) => isValid(ValueFactory.newExtendedValue(0, v), expected=ValueType.EXTENDED, isExtended=true, isRaw=true)} + forAll{(v:Array[Byte]) => isValid(ValueFactory.newExtensionValue(0, v), expected=ValueType.EXTENSION, isExtension=true, isRaw=true)} } } diff --git a/msgpack-core/src/test/scala/org/msgpack/value/ValueTypeTest.scala b/msgpack-core/src/test/scala/org/msgpack/value/ValueTypeTest.scala index 467162447..ac3052bc5 100644 --- a/msgpack-core/src/test/scala/org/msgpack/value/ValueTypeTest.scala +++ b/msgpack-core/src/test/scala/org/msgpack/value/ValueTypeTest.scala @@ -46,7 +46,7 @@ class ValueTypeTest extends MessagePackSpec { check(t, ValueType.BINARY) for(t <- Seq(FIXEXT1, FIXEXT2, FIXEXT4, FIXEXT8, FIXEXT16, EXT8, EXT16, EXT32)) - check(t, ValueType.EXTENDED) + check(t, ValueType.EXTENSION) for(t <- Seq(INT8, INT16, INT32, INT64, UINT8, UINT16, UINT32, UINT64)) check(t, ValueType.INTEGER) diff --git a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java index 8594e1e17..450a24f61 100644 --- a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java +++ b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java @@ -5,16 +5,13 @@ import com.fasterxml.jackson.core.io.IOContext; import com.fasterxml.jackson.core.json.DupDetector; import com.fasterxml.jackson.core.json.JsonReadContext; -import org.msgpack.core.MessageFormat; import org.msgpack.core.MessageUnpacker; import org.msgpack.core.buffer.ArrayBufferInput; import org.msgpack.core.buffer.InputStreamBufferInput; import org.msgpack.core.buffer.MessageBufferInput; import org.msgpack.value.Value; import org.msgpack.value.Variable; -import org.msgpack.value.NumberValue; import org.msgpack.value.IntegerValue; -import org.msgpack.value.ExtendedValue; import org.msgpack.value.ValueType; import org.msgpack.value.ValueFactory; @@ -23,7 +20,6 @@ import java.math.BigDecimal; import java.math.BigInteger; import java.util.LinkedList; -import java.util.logging.Logger; public class MessagePackParser extends ParserMinimalBase { private static final ThreadLocal> messageUnpackerHolder = @@ -189,7 +185,7 @@ public JsonToken nextToken() throws IOException, JsonParseException { value = ValueFactory.newNilValue(); newStack = new StackItemForObject(messageUnpacker.unpackMapHeader()); break; - case EXTENDED: + case EXTENSION: value = messageUnpacker.unpackValue(var); nextToken = JsonToken.VALUE_EMBEDDED_OBJECT; break; @@ -319,8 +315,8 @@ else if (value.isFloatValue()) { public Object getEmbeddedObject() throws IOException, JsonParseException { if (value.isBinaryValue()) { return value.asBinaryValue().getByteArray(); - } else if (value.isExtendedValue()) { - return value.asExtendedValue(); + } else if (value.isExtensionValue()) { + return value.asExtensionValue(); } else { throw new UnsupportedOperationException(); } diff --git a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackExtendedTypeTest.java b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackExtendedTypeTest.java deleted file mode 100644 index 682773a7a..000000000 --- a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackExtendedTypeTest.java +++ /dev/null @@ -1,60 +0,0 @@ -package org.msgpack.jackson.dataformat; - -import org.junit.Test; - -import java.nio.ByteBuffer; - -import static org.junit.Assert.*; - -public class MessagePackExtendedTypeTest { - private void assertExtendedType(MessagePackExtendedType x, - int expectedExtType, ByteBuffer expectedByteBuffer) { - assertEquals(expectedExtType, x.extType()); - assertEquals(expectedByteBuffer, x.byteBuffer()); - assertTrue(x.byteBuffer().isReadOnly()); - } - - @Test - public void testMessagePackExtendedType() { - byte[] bs = new byte[] {0x00, (byte) 0xCC, (byte) 0xFF}; - ByteBuffer expectedByteBuffer = ByteBuffer.wrap(bs); - - int extType = 1; - MessagePackExtendedType extendedType = - new MessagePackExtendedType(extType, ByteBuffer.wrap(bs)); - assertExtendedType(extendedType, extType, expectedByteBuffer); - - extType = 2; - ByteBuffer bb = ByteBuffer.allocate(3); - bb.put(bs); - bb.position(0); - extendedType = new MessagePackExtendedType(extType, bb); - assertExtendedType(extendedType, extType, expectedByteBuffer); - - extType = 3; - bb = ByteBuffer.allocateDirect(3); - bb.put(bs); - bb.position(0); - extendedType = new MessagePackExtendedType(extType, bb); - assertExtendedType(extendedType, extType, expectedByteBuffer); - - extType = -1; - extendedType = - new MessagePackExtendedType(extType, ByteBuffer.wrap(bs).asReadOnlyBuffer()); - assertExtendedType(extendedType, extType, expectedByteBuffer); - - extType = -2; - bb = ByteBuffer.allocate(3); - bb.put(bs); - bb.position(0); - extendedType = new MessagePackExtendedType(extType, bb.asReadOnlyBuffer()); - assertExtendedType(extendedType, extType, expectedByteBuffer); - - extType = -3; - bb = ByteBuffer.allocateDirect(3); - bb.put(bs); - bb.position(0); - extendedType = new MessagePackExtendedType(extType, bb.asReadOnlyBuffer()); - assertExtendedType(extendedType, extType, expectedByteBuffer); - } -} \ No newline at end of file diff --git a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackExtensionTypeTest.java b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackExtensionTypeTest.java new file mode 100644 index 000000000..f418c2193 --- /dev/null +++ b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackExtensionTypeTest.java @@ -0,0 +1,60 @@ +package org.msgpack.jackson.dataformat; + +import org.junit.Test; + +import java.nio.ByteBuffer; + +import static org.junit.Assert.*; + +public class MessagePackExtensionTypeTest { + private void assertExtensionType(MessagePackExtensionType x, + int expectedExtType, ByteBuffer expectedByteBuffer) { + assertEquals(expectedExtType, x.extType()); + assertEquals(expectedByteBuffer, x.byteBuffer()); + assertTrue(x.byteBuffer().isReadOnly()); + } + + @Test + public void testMessagePackExtensionType() { + byte[] bs = new byte[] {0x00, (byte) 0xCC, (byte) 0xFF}; + ByteBuffer expectedByteBuffer = ByteBuffer.wrap(bs); + + int extType = 1; + MessagePackExtensionType ExtensionType = + new MessagePackExtensionType(extType, ByteBuffer.wrap(bs)); + assertExtensionType(ExtensionType, extType, expectedByteBuffer); + + extType = 2; + ByteBuffer bb = ByteBuffer.allocate(3); + bb.put(bs); + bb.position(0); + ExtensionType = new MessagePackExtensionType(extType, bb); + assertExtensionType(ExtensionType, extType, expectedByteBuffer); + + extType = 3; + bb = ByteBuffer.allocateDirect(3); + bb.put(bs); + bb.position(0); + ExtensionType = new MessagePackExtensionType(extType, bb); + assertExtensionType(ExtensionType, extType, expectedByteBuffer); + + extType = -1; + ExtensionType = + new MessagePackExtensionType(extType, ByteBuffer.wrap(bs).asReadOnlyBuffer()); + assertExtensionType(ExtensionType, extType, expectedByteBuffer); + + extType = -2; + bb = ByteBuffer.allocate(3); + bb.put(bs); + bb.position(0); + ExtensionType = new MessagePackExtensionType(extType, bb.asReadOnlyBuffer()); + assertExtensionType(ExtensionType, extType, expectedByteBuffer); + + extType = -3; + bb = ByteBuffer.allocateDirect(3); + bb.put(bs); + bb.position(0); + ExtensionType = new MessagePackExtensionType(extType, bb.asReadOnlyBuffer()); + assertExtensionType(ExtensionType, extType, expectedByteBuffer); + } +} \ No newline at end of file diff --git a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackParserTest.java b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackParserTest.java index 2f227cce5..abf8a5f1c 100644 --- a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackParserTest.java +++ b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackParserTest.java @@ -67,7 +67,7 @@ public void testParserShouldReadObject() throws IOException { // #9 byte[] extPayload = {-80, -50, -25, -114, -25, 16, 60, 68}; packer.packString("ext"); - packer.packExtendedTypeHeader(0, extPayload.length); + packer.packExtensionTypeHeader(0, extPayload.length); packer.writePayload(extPayload); packer.flush(); @@ -142,9 +142,9 @@ else if (k.equals("bool")) { else if (k.equals("ext")) { // #9 bitmap |= 1 << 10; - MessagePackExtendedType extendedType = (MessagePackExtendedType) v; - assertEquals(0, extendedType.extType()); - assertEquals(ByteBuffer.wrap(extPayload), extendedType.byteBuffer()); + MessagePackExtensionType ExtensionType = (MessagePackExtensionType) v; + assertEquals(0, ExtensionType.extType()); + assertEquals(ByteBuffer.wrap(extPayload), ExtensionType.byteBuffer()); } } assertEquals(0x7FF, bitmap); @@ -191,7 +191,7 @@ public void testParserShouldReadArray() throws IOException { packer.packBoolean(true); // #11 byte[] extPayload = {-80, -50, -25, -114, -25, 16, 60, 68}; - packer.packExtendedTypeHeader(-1, extPayload.length); + packer.packExtensionTypeHeader(-1, extPayload.length); packer.writePayload(extPayload); packer.flush(); @@ -249,9 +249,9 @@ else if (k.equals("child_map_age")) { // #10 assertEquals(true, array.get(i++)); // #11 - MessagePackExtendedType extendedType = (MessagePackExtendedType) array.get(i++); - assertEquals(-1, extendedType.extType()); - assertEquals(ByteBuffer.wrap(extPayload), extendedType.byteBuffer()); + MessagePackExtensionType ExtensionType = (MessagePackExtensionType) array.get(i++); + assertEquals(-1, ExtensionType.extType()); + assertEquals(ByteBuffer.wrap(extPayload), ExtensionType.byteBuffer()); } @Test From bc7e503e916cf3b1010e0343f7bf8726ae56fa4d Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Sat, 13 Jun 2015 22:34:21 +0900 Subject: [PATCH 064/234] ValueFactory.newXXXValue -> newXXX for brevity --- .../org/msgpack/core/MessageUnpacker.java | 20 ++-- .../java/org/msgpack/value/ValueFactory.java | 96 +++++++++++++------ .../main/java/org/msgpack/value/Variable.java | 22 ++--- .../value/impl/ImmutableBooleanValueImpl.java | 8 -- .../org/msgpack/value/ValueFactoryTest.scala | 2 +- .../jackson/dataformat/MessagePackParser.java | 10 +- 6 files changed, 94 insertions(+), 64 deletions(-) diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java b/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java index b81ad808c..ed6bd2a4a 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java +++ b/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java @@ -540,25 +540,25 @@ public ImmutableValue unpackValue() throws IOException { switch(mf.getValueType()) { case NIL: unpackNil(); - return ValueFactory.newNilValue(); + return ValueFactory.nil(); case BOOLEAN: - return ValueFactory.newBooleanValue(unpackBoolean()); + return ValueFactory.newBoolean(unpackBoolean()); case INTEGER: switch (mf) { case UINT64: - return ValueFactory.newIntegerValue(unpackBigInteger()); + return ValueFactory.newInteger(unpackBigInteger()); default: - return ValueFactory.newIntegerValue(unpackLong()); + return ValueFactory.newInteger(unpackLong()); } case FLOAT: - return ValueFactory.newFloatValue(unpackDouble()); + return ValueFactory.newFloat(unpackDouble()); case STRING: { int length = unpackRawStringHeader(); - return ValueFactory.newStringValue(readPayload(length)); + return ValueFactory.newString(readPayload(length)); } case BINARY: { int length = unpackBinaryHeader(); - return ValueFactory.newBinaryValue(readPayload(length)); + return ValueFactory.newBinary(readPayload(length)); } case ARRAY: { int size = unpackArrayHeader(); @@ -566,7 +566,7 @@ public ImmutableValue unpackValue() throws IOException { for (int i=0; i < size; i++) { array[i] = unpackValue(); } - return ValueFactory.newArrayValue(array); + return ValueFactory.newArray(array); } case MAP: { int size = unpackMapHeader(); @@ -577,11 +577,11 @@ public ImmutableValue unpackValue() throws IOException { kvs[i] = unpackValue(); i++; } - return ValueFactory.newMapValue(kvs); + return ValueFactory.newMap(kvs); } case EXTENSION: { ExtensionTypeHeader extHeader = unpackExtensionTypeHeader(); - return ValueFactory.newExtensionValue(extHeader.getType(), readPayload(extHeader.getLength())); + return ValueFactory.newExtension(extHeader.getType(), readPayload(extHeader.getLength())); } default: throw new MessageFormatException("Unknown value type"); diff --git a/msgpack-core/src/main/java/org/msgpack/value/ValueFactory.java b/msgpack-core/src/main/java/org/msgpack/value/ValueFactory.java index 84f3e7495..1f386208c 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/ValueFactory.java +++ b/msgpack-core/src/main/java/org/msgpack/value/ValueFactory.java @@ -26,76 +26,69 @@ import org.msgpack.value.impl.ImmutableMapValueImpl; import org.msgpack.value.impl.ImmutableExtensionValueImpl; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Arrays; +import java.util.*; import java.math.BigInteger; public final class ValueFactory { private ValueFactory() { } - public static ImmutableNilValue newNilValue() { + public static ImmutableNilValue nil() { return ImmutableNilValueImpl.get(); } - public static ImmutableBooleanValue newBooleanValue(boolean v) { - if (v) { - return ImmutableBooleanValueImpl.trueInstance(); - } else { - return ImmutableBooleanValueImpl.falseInstance(); - } + public static ImmutableBooleanValue newBoolean(boolean v) { + return v ? ImmutableBooleanValueImpl.TRUE : ImmutableBooleanValueImpl.FALSE; } - public static ImmutableIntegerValue newIntegerValue(byte v) { + public static ImmutableIntegerValue newInteger(byte v) { return new ImmutableLongValueImpl(v); } - public static ImmutableIntegerValue newIntegerValue(short v) { + public static ImmutableIntegerValue newInteger(short v) { return new ImmutableLongValueImpl(v); } - public static ImmutableIntegerValue newIntegerValue(int v) { + public static ImmutableIntegerValue newInteger(int v) { return new ImmutableLongValueImpl(v); } - public static ImmutableIntegerValue newIntegerValue(long v) { + public static ImmutableIntegerValue newInteger(long v) { return new ImmutableLongValueImpl(v); } - public static ImmutableIntegerValue newIntegerValue(BigInteger v) { + public static ImmutableIntegerValue newInteger(BigInteger v) { return new ImmutableBigIntegerValueImpl(v); } - public static ImmutableFloatValue newFloatValue(float v) { + public static ImmutableFloatValue newFloat(float v) { return new ImmutableDoubleValueImpl(v); } - public static ImmutableFloatValue newFloatValue(double v) { + public static ImmutableFloatValue newFloat(double v) { return new ImmutableDoubleValueImpl(v); } - public static ImmutableBinaryValue newBinaryValue(byte[] b) { + public static ImmutableBinaryValue newBinary(byte[] b) { return new ImmutableBinaryValueImpl(b); } - public static ImmutableBinaryValue newBinaryValue(byte[] b, int off, int len) { + public static ImmutableBinaryValue newBinary(byte[] b, int off, int len) { return new ImmutableBinaryValueImpl(Arrays.copyOfRange(b, off, len)); } - public static ImmutableStringValue newStringValue(String s) { + public static ImmutableStringValue newString(String s) { return new ImmutableStringValueImpl(s); } - public static ImmutableStringValue newStringValue(byte[] b) { + public static ImmutableStringValue newString(byte[] b) { return new ImmutableStringValueImpl(b); } - public static ImmutableStringValue newStringValue(byte[] b, int off, int len) { + public static ImmutableStringValue newString(byte[] b, int off, int len) { return new ImmutableStringValueImpl(Arrays.copyOfRange(b, off, len)); } - public static ImmutableArrayValue newArrayValue(List list) { + public static ImmutableArrayValue newArray(List list) { if (list.isEmpty()) { return ImmutableArrayValueImpl.empty(); } @@ -103,7 +96,7 @@ public static ImmutableArrayValue newArrayValue(List list) { return new ImmutableArrayValueImpl(array); } - public static ImmutableArrayValue newArrayValue(Value[] array) { + public static ImmutableArrayValue newArray(Value[] array) { if (array.length == 0) { return ImmutableArrayValueImpl.empty(); } @@ -111,7 +104,7 @@ public static ImmutableArrayValue newArrayValue(Value[] array) { } public static - ImmutableMapValue newMapValue(Map map) { + ImmutableMapValue newMap(Map map) { Value[] kvs = new Value[map.size() * 2]; Iterator> ite = map.entrySet().iterator(); int index = 0; @@ -122,17 +115,62 @@ ImmutableMapValue newMapValue(Map map) { kvs[index] = pair.getValue(); index++; } - return newMapValue(kvs); + return newMap(kvs); } - public static ImmutableMapValue newMapValue(Value[] kvs) { + public static ImmutableMapValue newMap(Value[] kvs) { if (kvs.length == 0) { return ImmutableMapValueImpl.empty(); } return new ImmutableMapValueImpl(Arrays.copyOf(kvs, kvs.length)); } - public static ImmutableExtensionValue newExtensionValue(byte type, byte[] data) { + public static class MapEntry { + public final Value key; + public final Value value; + + public MapEntry(Value key, Value value) { + this.key = key; + this.value = value; + } + } + + public static MapValue newMap(MapEntry... pairs) { + MapBuilder b = new MapBuilder(); + for(MapEntry p : pairs) { + b.put(p); + } + return b.build(); + } + + + public static MapBuilder newMapBuilder() { + return new MapBuilder(); + } + + public static MapEntry newMapEntry(Value key, Value value) { + return new MapEntry(key, value); + + } + + public static class MapBuilder { + private Map map = new HashMap(); + public MapBuilder() {} + + public MapValue build() { + return newMap(map); + } + + public void put(MapEntry pair) { + put(pair.key, pair.value); + } + + public void put(Value key, Value value) { + map.put(key, value); + } + } + + public static ImmutableExtensionValue newExtension(byte type, byte[] data) { return new ImmutableExtensionValueImpl(type, data); } } diff --git a/msgpack-core/src/main/java/org/msgpack/value/Variable.java b/msgpack-core/src/main/java/org/msgpack/value/Variable.java index b36ae59a6..2fdb20795 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/Variable.java +++ b/msgpack-core/src/main/java/org/msgpack/value/Variable.java @@ -232,7 +232,7 @@ public NilValue asNilValue() { @Override public ImmutableNilValue immutableValue() { - return ValueFactory.newNilValue(); + return ValueFactory.nil(); } @Override @@ -266,7 +266,7 @@ public BooleanValue asBooleanValue() { @Override public ImmutableBooleanValue immutableValue() { - return ValueFactory.newBooleanValue(getBoolean()); + return ValueFactory.newBoolean(getBoolean()); } @Override @@ -405,9 +405,9 @@ public IntegerValue asIntegerValue() { @Override public ImmutableIntegerValue immutableValue() { if (type == Type.BIG_INTEGER) { - return ValueFactory.newIntegerValue((BigInteger) objectValue); + return ValueFactory.newInteger((BigInteger) objectValue); } - return ValueFactory.newIntegerValue(longValue); + return ValueFactory.newInteger(longValue); } @Override @@ -514,7 +514,7 @@ public FloatValue asFloatValue() { @Override public ImmutableFloatValue immutableValue() { - return ValueFactory.newFloatValue(doubleValue); + return ValueFactory.newFloat(doubleValue); } @Override @@ -602,7 +602,7 @@ public BinaryValue asBinaryValue() { @Override public ImmutableBinaryValue immutableValue() { - return ValueFactory.newBinaryValue(getByteArray()); + return ValueFactory.newBinary(getByteArray()); } @Override @@ -642,7 +642,7 @@ public StringValue asStringValue() { @Override public ImmutableStringValue immutableValue() { - return ValueFactory.newStringValue((byte[]) objectValue); + return ValueFactory.newString((byte[]) objectValue); } @Override @@ -678,7 +678,7 @@ public ArrayValue asArrayValue() { @Override public ImmutableArrayValue immutableValue() { - return ValueFactory.newArrayValue(list()); + return ValueFactory.newArray(list()); } @Override @@ -695,7 +695,7 @@ public Value get(int index) { public Value getOrNilValue(int index) { List l = list(); if (l.size() < index && index >= 0) { - return ValueFactory.newNilValue(); + return ValueFactory.nil(); } return l.get(index); } @@ -745,7 +745,7 @@ public MapValue asMapValue() { @Override public ImmutableMapValue immutableValue() { - return ValueFactory.newMapValue(map()); + return ValueFactory.newMap(map()); } @Override @@ -808,7 +808,7 @@ public void writeTo(MessagePacker pk) throws IOException { public Variable setExtensionValue(byte type, byte[] data) { this.type = Type.EXTENSION; this.accessor = extensionAccessor; - this.objectValue = ValueFactory.newExtensionValue(type, data); + this.objectValue = ValueFactory.newExtension(type, data); return this; } diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableBooleanValueImpl.java b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableBooleanValueImpl.java index 84ef95c44..4673ff36d 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableBooleanValueImpl.java +++ b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableBooleanValueImpl.java @@ -41,14 +41,6 @@ private ImmutableBooleanValueImpl(boolean value) { this.value = value; } - public static ImmutableBooleanValue trueInstance() { - return TRUE; - } - - public static ImmutableBooleanValue falseInstance() { - return FALSE; - } - @Override public ValueType getValueType() { return ValueType.BOOLEAN; diff --git a/msgpack-core/src/test/scala/org/msgpack/value/ValueFactoryTest.scala b/msgpack-core/src/test/scala/org/msgpack/value/ValueFactoryTest.scala index 7465de706..6069afadf 100644 --- a/msgpack-core/src/test/scala/org/msgpack/value/ValueFactoryTest.scala +++ b/msgpack-core/src/test/scala/org/msgpack/value/ValueFactoryTest.scala @@ -45,7 +45,7 @@ class ValueFactoryTest extends MessagePackSpec { forAll{(v:Array[Byte]) => isValid(ValueFactory.newBinary(v), expected=ValueType.BINARY, isBinary = true, isRaw = true)} isValid(ValueFactory.emptyArray(), expected=ValueType.ARRAY, isArray = true) isValid(ValueFactory.emptyMap(), expected=ValueType.MAP, isMap = true) - forAll{(v:Array[Byte]) => isValid(ValueFactory.newExtensionValue(0, v), expected=ValueType.EXTENSION, isExtension=true, isRaw=true)} + forAll{(v:Array[Byte]) => isValid(ValueFactory.newExtension(0, v), expected=ValueType.EXTENSION, isExtension=true, isRaw=true)} } } diff --git a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java index 450a24f61..756d8a55a 100644 --- a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java +++ b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java @@ -29,7 +29,7 @@ public class MessagePackParser extends ParserMinimalBase { private JsonReadContext parsingContext; private final LinkedList stack = new LinkedList(); - private Value value = ValueFactory.newNilValue(); + private Value value = ValueFactory.nil(); private Variable var = new Variable(); private boolean isClosed; private long tokenPosition; @@ -141,12 +141,12 @@ public JsonToken nextToken() throws IOException, JsonParseException { switch (type) { case NIL: messageUnpacker.unpackNil(); - value = ValueFactory.newNilValue(); + value = ValueFactory.nil(); nextToken = JsonToken.VALUE_NULL; break; case BOOLEAN: boolean b = messageUnpacker.unpackBoolean(); - value = ValueFactory.newNilValue(); + value = ValueFactory.nil(); nextToken = b ? JsonToken.VALUE_TRUE : JsonToken.VALUE_FALSE; break; case INTEGER: @@ -178,11 +178,11 @@ public JsonToken nextToken() throws IOException, JsonParseException { } break; case ARRAY: - value = ValueFactory.newNilValue(); + value = ValueFactory.nil(); newStack = new StackItemForArray(messageUnpacker.unpackArrayHeader()); break; case MAP: - value = ValueFactory.newNilValue(); + value = ValueFactory.nil(); newStack = new StackItemForObject(messageUnpacker.unpackMapHeader()); break; case EXTENSION: From b1230894c0cc05991564210037577617f5f6da58 Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Sat, 13 Jun 2015 23:06:06 +0900 Subject: [PATCH 065/234] immutableValue() -> toImmutable() --- .../java/org/msgpack/value/ArrayValue.java | 2 +- .../java/org/msgpack/value/BinaryValue.java | 2 +- .../java/org/msgpack/value/BooleanValue.java | 2 +- .../org/msgpack/value/ExtensionValue.java | 2 +- .../java/org/msgpack/value/FloatValue.java | 2 +- .../java/org/msgpack/value/IntegerValue.java | 2 +- .../main/java/org/msgpack/value/MapValue.java | 2 +- .../main/java/org/msgpack/value/NilValue.java | 2 +- .../java/org/msgpack/value/NumberValue.java | 2 +- .../main/java/org/msgpack/value/RawValue.java | 2 +- .../java/org/msgpack/value/StringValue.java | 2 +- .../main/java/org/msgpack/value/Variable.java | 39 ++++++++++++------- .../value/impl/ImmutableArrayValueImpl.java | 7 +--- .../impl/ImmutableBigIntegerValueImpl.java | 8 +--- .../value/impl/ImmutableBinaryValueImpl.java | 3 +- .../value/impl/ImmutableBooleanValueImpl.java | 7 +--- .../value/impl/ImmutableDoubleValueImpl.java | 7 +--- .../impl/ImmutableExtensionValueImpl.java | 7 +--- .../value/impl/ImmutableLongValueImpl.java | 8 +--- .../value/impl/ImmutableMapValueImpl.java | 7 +--- .../value/impl/ImmutableNilValueImpl.java | 3 +- .../value/impl/ImmutableStringValueImpl.java | 3 +- .../org/msgpack/core/MessagePackTest.scala | 4 +- 23 files changed, 57 insertions(+), 68 deletions(-) diff --git a/msgpack-core/src/main/java/org/msgpack/value/ArrayValue.java b/msgpack-core/src/main/java/org/msgpack/value/ArrayValue.java index a92805a17..8f69fc638 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/ArrayValue.java +++ b/msgpack-core/src/main/java/org/msgpack/value/ArrayValue.java @@ -25,7 +25,7 @@ */ public interface ArrayValue extends Value, Iterable { @Override - public ImmutableArrayValue immutableValue(); + public ImmutableArrayValue toImmutable(); /** * Returns number of elements in this array. diff --git a/msgpack-core/src/main/java/org/msgpack/value/BinaryValue.java b/msgpack-core/src/main/java/org/msgpack/value/BinaryValue.java index 8c9955694..5a6250ed4 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/BinaryValue.java +++ b/msgpack-core/src/main/java/org/msgpack/value/BinaryValue.java @@ -24,5 +24,5 @@ */ public interface BinaryValue extends RawValue { @Override - public ImmutableBinaryValue immutableValue(); + public ImmutableBinaryValue toImmutable(); } diff --git a/msgpack-core/src/main/java/org/msgpack/value/BooleanValue.java b/msgpack-core/src/main/java/org/msgpack/value/BooleanValue.java index 20d731a4b..cd4512833 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/BooleanValue.java +++ b/msgpack-core/src/main/java/org/msgpack/value/BooleanValue.java @@ -22,7 +22,7 @@ */ public interface BooleanValue extends Value { @Override - public ImmutableBooleanValue immutableValue(); + public ImmutableBooleanValue toImmutable(); /** * Returns the value as a {@code boolean}. diff --git a/msgpack-core/src/main/java/org/msgpack/value/ExtensionValue.java b/msgpack-core/src/main/java/org/msgpack/value/ExtensionValue.java index cda4812cd..faf7cbe33 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/ExtensionValue.java +++ b/msgpack-core/src/main/java/org/msgpack/value/ExtensionValue.java @@ -25,7 +25,7 @@ */ public interface ExtensionValue extends Value { @Override - public ImmutableExtensionValue immutableValue(); + public ImmutableExtensionValue toImmutable(); public byte getType(); diff --git a/msgpack-core/src/main/java/org/msgpack/value/FloatValue.java b/msgpack-core/src/main/java/org/msgpack/value/FloatValue.java index 019ee2c4a..9f447f4e3 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/FloatValue.java +++ b/msgpack-core/src/main/java/org/msgpack/value/FloatValue.java @@ -24,5 +24,5 @@ */ public interface FloatValue extends NumberValue { @Override - public ImmutableFloatValue immutableValue(); + public ImmutableFloatValue toImmutable(); } diff --git a/msgpack-core/src/main/java/org/msgpack/value/IntegerValue.java b/msgpack-core/src/main/java/org/msgpack/value/IntegerValue.java index 267b7e127..4d990ba9d 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/IntegerValue.java +++ b/msgpack-core/src/main/java/org/msgpack/value/IntegerValue.java @@ -24,7 +24,7 @@ */ public interface IntegerValue extends NumberValue { @Override - public ImmutableIntegerValue immutableValue(); + public ImmutableIntegerValue toImmutable(); /** * Returns true if the value is in the range of [-27 to 27-1]. diff --git a/msgpack-core/src/main/java/org/msgpack/value/MapValue.java b/msgpack-core/src/main/java/org/msgpack/value/MapValue.java index db5fe589a..c6945e820 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/MapValue.java +++ b/msgpack-core/src/main/java/org/msgpack/value/MapValue.java @@ -26,7 +26,7 @@ */ public interface MapValue extends Value { @Override - public ImmutableMapValue immutableValue(); + public ImmutableMapValue toImmutable(); /** * Returns number of key-value pairs in this array. diff --git a/msgpack-core/src/main/java/org/msgpack/value/NilValue.java b/msgpack-core/src/main/java/org/msgpack/value/NilValue.java index ea627c46d..2fe366b96 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/NilValue.java +++ b/msgpack-core/src/main/java/org/msgpack/value/NilValue.java @@ -20,5 +20,5 @@ */ public interface NilValue extends Value { @Override - public ImmutableNilValue immutableValue(); + public ImmutableNilValue toImmutable(); } diff --git a/msgpack-core/src/main/java/org/msgpack/value/NumberValue.java b/msgpack-core/src/main/java/org/msgpack/value/NumberValue.java index f472ad414..e106da1dd 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/NumberValue.java +++ b/msgpack-core/src/main/java/org/msgpack/value/NumberValue.java @@ -25,7 +25,7 @@ */ public interface NumberValue extends Value { @Override - public ImmutableNumberValue immutableValue(); + public ImmutableNumberValue toImmutable(); /** * Returns the value as a {@code byte}, which may involve rounding or truncation. diff --git a/msgpack-core/src/main/java/org/msgpack/value/RawValue.java b/msgpack-core/src/main/java/org/msgpack/value/RawValue.java index 25688fcd4..50cd55849 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/RawValue.java +++ b/msgpack-core/src/main/java/org/msgpack/value/RawValue.java @@ -27,7 +27,7 @@ */ public interface RawValue extends Value { @Override - public ImmutableRawValue immutableValue(); + public ImmutableRawValue toImmutable(); /** * Returns the value as {@code byte[]}. diff --git a/msgpack-core/src/main/java/org/msgpack/value/StringValue.java b/msgpack-core/src/main/java/org/msgpack/value/StringValue.java index 36f1943f7..d278a8459 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/StringValue.java +++ b/msgpack-core/src/main/java/org/msgpack/value/StringValue.java @@ -26,5 +26,5 @@ */ public interface StringValue extends RawValue { @Override - public ImmutableStringValue immutableValue(); + public ImmutableStringValue toImmutable(); } diff --git a/msgpack-core/src/main/java/org/msgpack/value/Variable.java b/msgpack-core/src/main/java/org/msgpack/value/Variable.java index 2fdb20795..3861ec422 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/Variable.java +++ b/msgpack-core/src/main/java/org/msgpack/value/Variable.java @@ -231,7 +231,7 @@ public NilValue asNilValue() { } @Override - public ImmutableNilValue immutableValue() { + public ImmutableNilValue toImmutable() { return ValueFactory.nil(); } @@ -265,7 +265,7 @@ public BooleanValue asBooleanValue() { } @Override - public ImmutableBooleanValue immutableValue() { + public ImmutableBooleanValue toImmutable() { return ValueFactory.newBoolean(getBoolean()); } @@ -403,7 +403,7 @@ public IntegerValue asIntegerValue() { } @Override - public ImmutableIntegerValue immutableValue() { + public ImmutableIntegerValue toImmutable() { if (type == Type.BIG_INTEGER) { return ValueFactory.newInteger((BigInteger) objectValue); } @@ -513,7 +513,7 @@ public FloatValue asFloatValue() { } @Override - public ImmutableFloatValue immutableValue() { + public ImmutableFloatValue toImmutable() { return ValueFactory.newFloat(doubleValue); } @@ -601,7 +601,7 @@ public BinaryValue asBinaryValue() { } @Override - public ImmutableBinaryValue immutableValue() { + public ImmutableBinaryValue toImmutable() { return ValueFactory.newBinary(getByteArray()); } @@ -641,7 +641,7 @@ public StringValue asStringValue() { } @Override - public ImmutableStringValue immutableValue() { + public ImmutableStringValue toImmutable() { return ValueFactory.newString((byte[]) objectValue); } @@ -677,7 +677,7 @@ public ArrayValue asArrayValue() { } @Override - public ImmutableArrayValue immutableValue() { + public ImmutableArrayValue toImmutable() { return ValueFactory.newArray(list()); } @@ -744,7 +744,7 @@ public MapValue asMapValue() { } @Override - public ImmutableMapValue immutableValue() { + public ImmutableMapValue toImmutable() { return ValueFactory.newMap(map()); } @@ -798,13 +798,17 @@ public void writeTo(MessagePacker pk) throws IOException { pair.getValue().writeTo(pk); } } + + @Override + public void accept(ValueVisitor visitor) { + visitor.visitMap(this); + } } //// // ExtensionValue // - public Variable setExtensionValue(byte type, byte[] data) { this.type = Type.EXTENSION; this.accessor = extensionAccessor; @@ -824,7 +828,7 @@ public ExtensionValue asExtensionValue() { } @Override - public ImmutableExtensionValue immutableValue() { + public ImmutableExtensionValue toImmutable() { return (ImmutableExtensionValue) objectValue; } @@ -850,8 +854,8 @@ public void writeTo(MessagePacker pk) throws IOException { // @Override - public ImmutableValue immutableValue() { - return accessor.immutableValue(); + public ImmutableValue toImmutable() { + return accessor.toImmutable(); } @Override @@ -859,19 +863,24 @@ public void writeTo(MessagePacker pk) throws IOException { accessor.writeTo(pk); } + @Override + public void accept(ValueVisitor visitor) { + accessor.accept(visitor); + } + @Override public int hashCode() { - return immutableValue().hashCode(); // TODO optimize + return toImmutable().hashCode(); // TODO optimize } @Override public boolean equals(Object o) { - return immutableValue().equals(o); // TODO optimize + return toImmutable().equals(o); // TODO optimize } @Override public String toString() { - return immutableValue().toString(); // TODO optimize + return toImmutable().toString(); // TODO optimize } @Override diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableArrayValueImpl.java b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableArrayValueImpl.java index 0ada4f4d2..79192f2dc 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableArrayValueImpl.java +++ b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableArrayValueImpl.java @@ -16,10 +16,7 @@ package org.msgpack.value.impl; import org.msgpack.core.MessagePacker; -import org.msgpack.value.Value; -import org.msgpack.value.ValueType; -import org.msgpack.value.ArrayValue; -import org.msgpack.value.ImmutableArrayValue; +import org.msgpack.value.*; import java.util.List; import java.util.AbstractList; @@ -53,7 +50,7 @@ public ValueType getValueType() { } @Override - public ImmutableArrayValue immutableValue() { + public ImmutableArrayValue toImmutable() { return this; } diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableBigIntegerValueImpl.java b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableBigIntegerValueImpl.java index 34b17f8f2..c173b8655 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableBigIntegerValueImpl.java +++ b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableBigIntegerValueImpl.java @@ -17,11 +17,7 @@ import org.msgpack.core.MessagePacker; import org.msgpack.core.MessageIntegerOverflowException; -import org.msgpack.value.Value; -import org.msgpack.value.ValueType; -import org.msgpack.value.IntegerValue; -import org.msgpack.value.ImmutableNumberValue; -import org.msgpack.value.ImmutableIntegerValue; +import org.msgpack.value.*; import java.io.IOException; import java.math.BigInteger; @@ -54,7 +50,7 @@ public ValueType getValueType() { } @Override - public ImmutableIntegerValue immutableValue() { + public ImmutableIntegerValue toImmutable() { return this; } diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableBinaryValueImpl.java b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableBinaryValueImpl.java index c9ebfd313..e50660466 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableBinaryValueImpl.java +++ b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableBinaryValueImpl.java @@ -19,6 +19,7 @@ import org.msgpack.value.Value; import org.msgpack.value.ValueType; import org.msgpack.value.ImmutableBinaryValue; +import org.msgpack.value.ValueVisitor; import java.util.Arrays; import java.io.IOException; @@ -41,7 +42,7 @@ public ValueType getValueType() { } @Override - public ImmutableBinaryValue immutableValue() { + public ImmutableBinaryValue toImmutable() { return this; } diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableBooleanValueImpl.java b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableBooleanValueImpl.java index 4673ff36d..4b281d71b 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableBooleanValueImpl.java +++ b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableBooleanValueImpl.java @@ -16,10 +16,7 @@ package org.msgpack.value.impl; import org.msgpack.core.MessagePacker; -import org.msgpack.value.Value; -import org.msgpack.value.ValueType; -import org.msgpack.value.BooleanValue; -import org.msgpack.value.ImmutableBooleanValue; +import org.msgpack.value.*; import java.io.IOException; @@ -47,7 +44,7 @@ public ValueType getValueType() { } @Override - public ImmutableBooleanValue immutableValue() { + public ImmutableBooleanValue toImmutable() { return this; } diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableDoubleValueImpl.java b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableDoubleValueImpl.java index aa841bd82..6a5f6840b 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableDoubleValueImpl.java +++ b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableDoubleValueImpl.java @@ -16,10 +16,7 @@ package org.msgpack.value.impl; import org.msgpack.core.MessagePacker; -import org.msgpack.value.Value; -import org.msgpack.value.ValueType; -import org.msgpack.value.FloatValue; -import org.msgpack.value.ImmutableFloatValue; +import org.msgpack.value.*; import java.math.BigDecimal; import java.math.BigInteger; @@ -44,7 +41,7 @@ public ValueType getValueType() { } @Override - public ImmutableDoubleValueImpl immutableValue() { + public ImmutableDoubleValueImpl toImmutable() { return this; } diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableExtensionValueImpl.java b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableExtensionValueImpl.java index b1c5036ab..a92d90fc7 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableExtensionValueImpl.java +++ b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableExtensionValueImpl.java @@ -16,10 +16,7 @@ package org.msgpack.value.impl; import org.msgpack.core.MessagePacker; -import org.msgpack.value.Value; -import org.msgpack.value.ValueType; -import org.msgpack.value.ExtensionValue; -import org.msgpack.value.ImmutableExtensionValue; +import org.msgpack.value.*; import java.util.Arrays; import java.io.IOException; @@ -45,7 +42,7 @@ public ValueType getValueType() { } @Override - public ImmutableExtensionValue immutableValue() { + public ImmutableExtensionValue toImmutable() { return this; } diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableLongValueImpl.java b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableLongValueImpl.java index 78c724cb5..a2b2f60da 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableLongValueImpl.java +++ b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableLongValueImpl.java @@ -17,11 +17,7 @@ import org.msgpack.core.MessagePacker; import org.msgpack.core.MessageIntegerOverflowException; -import org.msgpack.value.ValueType; -import org.msgpack.value.Value; -import org.msgpack.value.IntegerValue; -import org.msgpack.value.ImmutableIntegerValue; -import org.msgpack.value.ImmutableNumberValue; +import org.msgpack.value.*; import java.io.IOException; import java.math.BigInteger; @@ -52,7 +48,7 @@ public ValueType getValueType() { } @Override - public ImmutableIntegerValue immutableValue() { + public ImmutableIntegerValue toImmutable() { return this; } diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableMapValueImpl.java b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableMapValueImpl.java index 5061fad19..c5f1f4bc4 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableMapValueImpl.java +++ b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableMapValueImpl.java @@ -16,10 +16,7 @@ package org.msgpack.value.impl; import org.msgpack.core.MessagePacker; -import org.msgpack.value.Value; -import org.msgpack.value.ValueType; -import org.msgpack.value.MapValue; -import org.msgpack.value.ImmutableMapValue; +import org.msgpack.value.*; import java.io.IOException; import java.util.Map; @@ -57,7 +54,7 @@ public ValueType getValueType() { } @Override - public ImmutableMapValue immutableValue() { + public ImmutableMapValue toImmutable() { return this; } diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableNilValueImpl.java b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableNilValueImpl.java index c8f9c3bcc..1bc2ad086 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableNilValueImpl.java +++ b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableNilValueImpl.java @@ -19,6 +19,7 @@ import org.msgpack.value.Value; import org.msgpack.value.ValueType; import org.msgpack.value.ImmutableNilValue; +import org.msgpack.value.ValueVisitor; import java.io.IOException; @@ -45,7 +46,7 @@ public ValueType getValueType() { } @Override - public ImmutableNilValue immutableValue() { + public ImmutableNilValue toImmutable() { return this; } diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableStringValueImpl.java b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableStringValueImpl.java index 59e2cefb1..2a93a3630 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableStringValueImpl.java +++ b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableStringValueImpl.java @@ -19,6 +19,7 @@ import org.msgpack.value.Value; import org.msgpack.value.ValueType; import org.msgpack.value.ImmutableStringValue; +import org.msgpack.value.ValueVisitor; import java.util.Arrays; import java.io.IOException; @@ -45,7 +46,7 @@ public ValueType getValueType() { } @Override - public ImmutableStringValue immutableValue() { + public ImmutableStringValue toImmutable() { return this; } diff --git a/msgpack-core/src/test/scala/org/msgpack/core/MessagePackTest.scala b/msgpack-core/src/test/scala/org/msgpack/core/MessagePackTest.scala index cf241537f..dd145eaa7 100644 --- a/msgpack-core/src/test/scala/org/msgpack/core/MessagePackTest.scala +++ b/msgpack-core/src/test/scala/org/msgpack/core/MessagePackTest.scala @@ -15,7 +15,7 @@ // package org.msgpack.core -import org.msgpack.value.Value +import org.msgpack.value.{Variable, Value} import org.msgpack.value.holder.ValueHolder import scala.util.Random @@ -444,7 +444,7 @@ class MessagePackTest extends MessagePackSpec { } } }, { unpacker => - val holder = new ValueHolder() + val holder = new Variable() unpacker.unpackValue(holder) val v = holder.get() From 4bcfab5b96b255a3059e177578273ec9e61095c0 Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Sat, 13 Jun 2015 23:06:56 +0900 Subject: [PATCH 066/234] Add visitor interface --- .../core/MessageOverflowException.java | 4 +- .../main/java/org/msgpack/value/Value.java | 142 +++++++++--------- .../java/org/msgpack/value/ValueFactory.java | 5 + .../java/org/msgpack/value/ValueVisitor.java | 38 +++++ .../main/java/org/msgpack/value/Variable.java | 40 +++++ .../value/impl/ImmutableArrayValueImpl.java | 5 + .../impl/ImmutableBigIntegerValueImpl.java | 5 + .../value/impl/ImmutableBinaryValueImpl.java | 5 + .../value/impl/ImmutableBooleanValueImpl.java | 5 + .../value/impl/ImmutableDoubleValueImpl.java | 5 + .../impl/ImmutableExtensionValueImpl.java | 5 + .../value/impl/ImmutableLongValueImpl.java | 5 + .../value/impl/ImmutableMapValueImpl.java | 5 + .../value/impl/ImmutableNilValueImpl.java | 5 + .../value/impl/ImmutableStringValueImpl.java | 5 + .../MessagePackExtensionTypeTest.java | 32 ++-- 16 files changed, 221 insertions(+), 90 deletions(-) create mode 100644 msgpack-core/src/main/java/org/msgpack/value/ValueVisitor.java diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessageOverflowException.java b/msgpack-core/src/main/java/org/msgpack/core/MessageOverflowException.java index 2190a34c1..ff63ba588 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/MessageOverflowException.java +++ b/msgpack-core/src/main/java/org/msgpack/core/MessageOverflowException.java @@ -1,7 +1,9 @@ package org.msgpack.core; /** - * Created on 5/28/14. + * Thrown when converting a message into a type that causes truncation or rounding. + * For example, {@link org.msgpack.value.NumberValue#asInt()} throws this error if + * it is a long value more than {@link java.lang.Integer#MAX_VALUE}. */ public class MessageOverflowException extends MessageTypeException { diff --git a/msgpack-core/src/main/java/org/msgpack/value/Value.java b/msgpack-core/src/main/java/org/msgpack/value/Value.java index d0b8bdcd1..c223509ad 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/Value.java +++ b/msgpack-core/src/main/java/org/msgpack/value/Value.java @@ -27,230 +27,226 @@ public interface Value { /** * Returns type of this value. - * + *

* Note that you can't use instanceof to check type of a value because type of a mutable value is variable. */ public ValueType getValueType(); /** * Returns immutable copy of this value. - * + *

* This method simply returns this without copying the value if this value is already immutable. */ - public ImmutableValue immutableValue(); + ImmutableValue toImmutable(); /** * Returns true if type of this value is Nil. - * + *

* If this method returns true, {@code asNilValue} never throws exceptions. * Note that you can't use instanceof or cast ((NilValue) thisValue) to check type of a value because type of a mutable value is variable. */ - public boolean isNilValue(); + boolean isNilValue(); /** * Returns true if type of this value is Boolean. - * + *

* If this method returns true, {@code asBooleanValue} never throws exceptions. * Note that you can't use instanceof or cast ((BooleanValue) thisValue) to check type of a value because type of a mutable value is variable. */ - public boolean isBooleanValue(); + boolean isBooleanValue(); /** * Returns true if type of this value is Integer or Float. - * + *

* If this method returns true, {@code asNumberValue} never throws exceptions. * Note that you can't use instanceof or cast ((NumberValue) thisValue) to check type of a value because type of a mutable value is variable. */ - public boolean isNumberValue(); + boolean isNumberValue(); /** * Returns true if type of this value is Integer. - * + *

* If this method returns true, {@code asIntegerValue} never throws exceptions. * Note that you can't use instanceof or cast ((IntegerValue) thisValue) to check type of a value because type of a mutable value is variable. */ - public boolean isIntegerValue(); + boolean isIntegerValue(); /** * Returns true if type of this value is Float. - * + *

* If this method returns true, {@code asFloatValue} never throws exceptions. * Note that you can't use instanceof or cast ((FloatValue) thisValue) to check type of a value because type of a mutable value is variable. */ - public boolean isFloatValue(); + boolean isFloatValue(); /** * Returns true if type of this value is String or Binary. - * + *

* If this method returns true, {@code asRawValue} never throws exceptions. * Note that you can't use instanceof or cast ((RawValue) thisValue) to check type of a value because type of a mutable value is variable. */ - public boolean isRawValue(); + boolean isRawValue(); /** * Returns true if type of this value is Binary. - * + *

* If this method returns true, {@code asBinaryValue} never throws exceptions. * Note that you can't use instanceof or cast ((BinaryValue) thisValue) to check type of a value because type of a mutable value is variable. */ - public boolean isBinaryValue(); + boolean isBinaryValue(); /** * Returns true if type of this value is String. - * + *

* If this method returns true, {@code asStringValue} never throws exceptions. * Note that you can't use instanceof or cast ((StringValue) thisValue) to check type of a value because type of a mutable value is variable. */ - public boolean isStringValue(); + boolean isStringValue(); /** * Returns true if type of this value is Array. - * + *

* If this method returns true, {@code asArrayValue} never throws exceptions. * Note that you can't use instanceof or cast ((ArrayValue) thisValue) to check type of a value because type of a mutable value is variable. */ - public boolean isArrayValue(); + boolean isArrayValue(); /** * Returns true if type of this value is Map. - * + *

* If this method returns true, {@code asMapValue} never throws exceptions. * Note that you can't use instanceof or cast ((MapValue) thisValue) to check type of a value because type of a mutable value is variable. */ - public boolean isMapValue(); + boolean isMapValue(); /** * Returns true if type of this an Extension. - * + *

* If this method returns true, {@code asExtensionValue} never throws exceptions. * Note that you can't use instanceof or cast ((ExtensionValue) thisValue) to check type of a value because * type of a mutable value is variable. */ - public boolean isExtensionValue(); + boolean isExtensionValue(); /** * Returns the value as {@code NilValue}. Otherwise throws {@code MessageTypeCastException}. - * + *

* Note that you can't use instanceof or cast ((NilValue) thisValue) to check type of a value because type of a mutable value is variable. * - * @throws MessageTypeCastException - * If type of this value is not Nil. + * @throws MessageTypeCastException If type of this value is not Nil. */ - public NilValue asNilValue(); + NilValue asNilValue(); /** * Returns the value as {@code BooleanValue}. Otherwise throws {@code MessageTypeCastException}. - * + *

* Note that you can't use instanceof or cast ((BooleanValue) thisValue) to check type of a value because type of a mutable value is variable. * - * @throws MessageTypeCastException - * If type of this value is not Boolean. + * @throws MessageTypeCastException If type of this value is not Boolean. */ - public BooleanValue asBooleanValue(); + BooleanValue asBooleanValue(); /** * Returns the value as {@code NumberValue}. Otherwise throws {@code MessageTypeCastException}. - * + *

* Note that you can't use instanceof or cast ((NumberValue) thisValue) to check type of a value because type of a mutable value is variable. * - * @throws MessageTypeCastException - * If type of this value is not Integer or Float. + * @throws MessageTypeCastException If type of this value is not Integer or Float. */ - public NumberValue asNumberValue(); + NumberValue asNumberValue(); /** * Returns the value as {@code IntegerValue}. Otherwise throws {@code MessageTypeCastException}. - * + *

* Note that you can't use instanceof or cast ((IntegerValue) thisValue) to check type of a value because type of a mutable value is variable. * - * @throws MessageTypeCastException - * If type of this value is not Integer. + * @throws MessageTypeCastException If type of this value is not Integer. */ - public IntegerValue asIntegerValue(); + IntegerValue asIntegerValue(); /** * Returns the value as {@code FloatValue}. Otherwise throws {@code MessageTypeCastException}. - * + *

* Note that you can't use instanceof or cast ((FloatValue) thisValue) to check type of a value because type of a mutable value is variable. * - * @throws MessageTypeCastException - * If type of this value is not Float. + * @throws MessageTypeCastException If type of this value is not Float. */ - public FloatValue asFloatValue(); + FloatValue asFloatValue(); /** * Returns the value as {@code RawValue}. Otherwise throws {@code MessageTypeCastException}. - * + *

* Note that you can't use instanceof or cast ((RawValue) thisValue) to check type of a value because type of a mutable value is variable. * - * @throws MessageTypeCastException - * If type of this value is not Binary or String. + * @throws MessageTypeCastException If type of this value is not Binary or String. */ - public RawValue asRawValue(); + RawValue asRawValue(); /** * Returns the value as {@code BinaryValue}. Otherwise throws {@code MessageTypeCastException}. - * + *

* Note that you can't use instanceof or cast ((BinaryValue) thisValue) to check type of a value because type of a mutable value is variable. * - * @throws MessageTypeCastException - * If type of this value is not Binary. + * @throws MessageTypeCastException If type of this value is not Binary. */ - public BinaryValue asBinaryValue(); + BinaryValue asBinaryValue(); /** * Returns the value as {@code StringValue}. Otherwise throws {@code MessageTypeCastException}. - * + *

* Note that you can't use instanceof or cast ((StringValue) thisValue) to check type of a value because type of a mutable value is variable. * - * @throws MessageTypeCastException - * If type of this value is not String. + * @throws MessageTypeCastException If type of this value is not String. */ - public StringValue asStringValue(); + StringValue asStringValue(); /** * Returns the value as {@code ArrayValue}. Otherwise throws {@code MessageTypeCastException}. - * + *

* Note that you can't use instanceof or cast ((ArrayValue) thisValue) to check type of a value because type of a mutable value is variable. * - * @throws MessageTypeCastException - * If type of this value is not Array. + * @throws MessageTypeCastException If type of this value is not Array. */ - public ArrayValue asArrayValue(); + ArrayValue asArrayValue(); /** * Returns the value as {@code MapValue}. Otherwise throws {@code MessageTypeCastException}. - * + *

* Note that you can't use instanceof or cast ((MapValue) thisValue) to check type of a value because type of a mutable value is variable. * - * @throws MessageTypeCastException - * If type of this value is not Map. + * @throws MessageTypeCastException If type of this value is not Map. */ - public MapValue asMapValue(); + MapValue asMapValue(); /** * Returns the value as {@code ExtensionValue}. Otherwise throws {@code MessageTypeCastException}. - * + *

* Note that you can't use instanceof or cast ((ExtensionValue) thisValue) to check type of a value * because type of a mutable value is variable. * - * @throws MessageTypeCastException - * If type of this value is not an Extension. + * @throws MessageTypeCastException If type of this value is not an Extension. */ - public ExtensionValue asExtensionValue(); + ExtensionValue asExtensionValue(); /** * Serializes the value using the specified {@code MessagePacker} * - * @see MessagePacker + * @see MessagePacker */ - public void writeTo(MessagePacker pk) throws IOException; + void writeTo(MessagePacker pk) throws IOException; + + + /** + * Accept a visitor to traverse this value + * @param visitor + */ + void accept(ValueVisitor visitor); /** * Compares this value to the specified object. - * + *

* This method returns {@code true} if type and value are equivalent. * If this value is {@code MapValue} or {@code ArrayValue}, this method check equivalence of elements recursively. */ - public boolean equals(Object obj); + boolean equals(Object obj); } diff --git a/msgpack-core/src/main/java/org/msgpack/value/ValueFactory.java b/msgpack-core/src/main/java/org/msgpack/value/ValueFactory.java index 1f386208c..65d4e8061 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/ValueFactory.java +++ b/msgpack-core/src/main/java/org/msgpack/value/ValueFactory.java @@ -103,6 +103,11 @@ public static ImmutableArrayValue newArray(Value[] array) { return new ImmutableArrayValueImpl(Arrays.copyOf(array, array.length)); } + public static ImmutableArrayValue emptyArray() { + return ImmutableArrayValueImpl.empty(); + } + + public static ImmutableMapValue newMap(Map map) { Value[] kvs = new Value[map.size() * 2]; diff --git a/msgpack-core/src/main/java/org/msgpack/value/ValueVisitor.java b/msgpack-core/src/main/java/org/msgpack/value/ValueVisitor.java new file mode 100644 index 000000000..a8f0e93d2 --- /dev/null +++ b/msgpack-core/src/main/java/org/msgpack/value/ValueVisitor.java @@ -0,0 +1,38 @@ +// +// MessagePack for Java +// +// 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.value; + +/** + * Interface for implementing the visitor pattern on message-packed values + */ +public interface ValueVisitor { + + void visitNil(); + void visitBoolean(BooleanValue v); + void visitInteger(IntegerValue v); + void visitFloat(FloatValue v); + void visitBinary(BinaryValue v); + void visitString(StringValue v); + void visitArray(ArrayValue v); + void visitMap(MapValue v); + void visitExtension(ExtensionValue v); + + /** + * Visitor can use this method to handle an exception occurred while visiting a value + * @param e + */ + void onError(Exception e); +} diff --git a/msgpack-core/src/main/java/org/msgpack/value/Variable.java b/msgpack-core/src/main/java/org/msgpack/value/Variable.java index 3861ec422..33125920b 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/Variable.java +++ b/msgpack-core/src/main/java/org/msgpack/value/Variable.java @@ -239,6 +239,11 @@ public ImmutableNilValue toImmutable() { public void writeTo(MessagePacker pk) throws IOException { pk.packNil(); } + + @Override + public void accept(ValueVisitor visitor) { + visitor.visitNil(); + } } @@ -278,6 +283,11 @@ public boolean getBoolean() { public void writeTo(MessagePacker pk) throws IOException { pk.packBoolean(longValue == 1L); } + + @Override + public void accept(ValueVisitor visitor) { + visitor.visitBoolean(this); + } } @@ -491,6 +501,11 @@ public void writeTo(MessagePacker pk) throws IOException { pk.packLong(longValue); } } + + @Override + public void accept(ValueVisitor visitor) { + visitor.visitInteger(this); + } } @@ -526,6 +541,11 @@ public ValueType getValueType() { public void writeTo(MessagePacker pk) throws IOException { pk.packDouble(doubleValue); } + + @Override + public void accept(ValueVisitor visitor) { + visitor.visitFloat(this); + } } @@ -611,6 +631,11 @@ public void writeTo(MessagePacker pk) throws IOException { pk.packBinaryHeader(data.length); pk.writePayload(data); } + + @Override + public void accept(ValueVisitor visitor) { + visitor.visitBinary(this); + } } @@ -651,6 +676,11 @@ public void writeTo(MessagePacker pk) throws IOException { pk.packRawStringHeader(data.length); pk.writePayload(data); } + + @Override + public void accept(ValueVisitor visitor) { + visitor.visitString(this); + } } @@ -719,6 +749,11 @@ public void writeTo(MessagePacker pk) throws IOException { e.writeTo(pk); } } + + @Override + public void accept(ValueVisitor visitor) { + visitor.visitArray(this); + } } //// @@ -846,6 +881,11 @@ public byte[] getData() { public void writeTo(MessagePacker pk) throws IOException { ((ImmutableExtensionValue) objectValue).writeTo(pk); } + + @Override + public void accept(ValueVisitor visitor) { + visitor.visitExtension(((ImmutableExtensionValue) objectValue)); + } } diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableArrayValueImpl.java b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableArrayValueImpl.java index 79192f2dc..43bcb3f5f 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableArrayValueImpl.java +++ b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableArrayValueImpl.java @@ -95,6 +95,11 @@ public void writeTo(MessagePacker pk) throws IOException { } } + @Override + public void accept(ValueVisitor visitor) { + visitor.visitArray(this); + } + @Override public boolean equals(Object o) { if(o == this) { diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableBigIntegerValueImpl.java b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableBigIntegerValueImpl.java index c173b8655..8e117a074 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableBigIntegerValueImpl.java +++ b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableBigIntegerValueImpl.java @@ -161,6 +161,11 @@ public void writeTo(MessagePacker pk) throws IOException { pk.packBigInteger(value); } + @Override + public void accept(ValueVisitor visitor) { + visitor.visitInteger(this); + } + @Override public boolean equals(Object o) { if (o == this) { diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableBinaryValueImpl.java b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableBinaryValueImpl.java index e50660466..57a205b87 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableBinaryValueImpl.java +++ b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableBinaryValueImpl.java @@ -57,6 +57,11 @@ public void writeTo(MessagePacker pk) throws IOException { pk.writePayload(data); } + @Override + public void accept(ValueVisitor visitor) { + visitor.visitBinary(this); + } + @Override public boolean equals(Object o) { if (this == o) { diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableBooleanValueImpl.java b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableBooleanValueImpl.java index 4b281d71b..a902a5741 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableBooleanValueImpl.java +++ b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableBooleanValueImpl.java @@ -58,6 +58,11 @@ public void writeTo(MessagePacker packer) throws IOException { packer.packBoolean(value); } + @Override + public void accept(ValueVisitor visitor) { + visitor.visitBoolean(this); + } + @Override public boolean equals(Object o) { if (o == this) { diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableDoubleValueImpl.java b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableDoubleValueImpl.java index 6a5f6840b..343175f4c 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableDoubleValueImpl.java +++ b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableDoubleValueImpl.java @@ -85,6 +85,11 @@ public void writeTo(MessagePacker pk) throws IOException { pk.packDouble(value); } + @Override + public void accept(ValueVisitor visitor) { + visitor.visitFloat(this); + } + @Override public boolean equals(Object o) { if (o == this) { diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableExtensionValueImpl.java b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableExtensionValueImpl.java index a92d90fc7..fbb7c0314 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableExtensionValueImpl.java +++ b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableExtensionValueImpl.java @@ -67,6 +67,11 @@ public void writeTo(MessagePacker packer) throws IOException { packer.writePayload(data); } + @Override + public void accept(ValueVisitor visitor) { + visitor.visitExtension(this); + } + @Override public boolean equals(Object o) { if (o == this) { diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableLongValueImpl.java b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableLongValueImpl.java index a2b2f60da..3542aaacb 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableLongValueImpl.java +++ b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableLongValueImpl.java @@ -156,6 +156,11 @@ public void writeTo(MessagePacker pk) throws IOException { pk.packLong(value); } + @Override + public void accept(ValueVisitor visitor) { + visitor.visitInteger(this); + } + @Override public boolean equals(Object o) { if (o == this) { diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableMapValueImpl.java b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableMapValueImpl.java index c5f1f4bc4..465795a8e 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableMapValueImpl.java +++ b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableMapValueImpl.java @@ -101,6 +101,11 @@ public void writeTo(MessagePacker pk) throws IOException { } } + @Override + public void accept(ValueVisitor visitor) { + visitor.visitMap(this); + } + @Override public boolean equals(Object o) { if (o == this) { diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableNilValueImpl.java b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableNilValueImpl.java index 1bc2ad086..3e818b1e2 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableNilValueImpl.java +++ b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableNilValueImpl.java @@ -60,6 +60,11 @@ public void writeTo(MessagePacker pk) throws IOException { pk.packNil(); } + @Override + public void accept(ValueVisitor visitor) { + visitor.visitNil(); + } + @Override public boolean equals(Object o) { if (o == this) { diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableStringValueImpl.java b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableStringValueImpl.java index 2a93a3630..4af14b9f7 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableStringValueImpl.java +++ b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableStringValueImpl.java @@ -61,6 +61,11 @@ public void writeTo(MessagePacker pk) throws IOException { pk.writePayload(data); } + @Override + public void accept(ValueVisitor visitor) { + visitor.visitString(this); + } + @Override public boolean equals(Object o) { if (this == o) { diff --git a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackExtensionTypeTest.java b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackExtensionTypeTest.java index f418c2193..3300323a5 100644 --- a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackExtensionTypeTest.java +++ b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackExtensionTypeTest.java @@ -6,8 +6,8 @@ import static org.junit.Assert.*; -public class MessagePackExtensionTypeTest { - private void assertExtensionType(MessagePackExtensionType x, +public class MessagePackextensionTypeTest { + private void assertextensionType(MessagePackextensionType x, int expectedExtType, ByteBuffer expectedByteBuffer) { assertEquals(expectedExtType, x.extType()); assertEquals(expectedByteBuffer, x.byteBuffer()); @@ -15,46 +15,46 @@ private void assertExtensionType(MessagePackExtensionType x, } @Test - public void testMessagePackExtensionType() { + public void testMessagePackextensionType() { byte[] bs = new byte[] {0x00, (byte) 0xCC, (byte) 0xFF}; ByteBuffer expectedByteBuffer = ByteBuffer.wrap(bs); int extType = 1; - MessagePackExtensionType ExtensionType = + MessagePackextensionType extensionType = new MessagePackExtensionType(extType, ByteBuffer.wrap(bs)); - assertExtensionType(ExtensionType, extType, expectedByteBuffer); + assertExtensionType(extensionType, extType, expectedByteBuffer); extType = 2; ByteBuffer bb = ByteBuffer.allocate(3); bb.put(bs); bb.position(0); - ExtensionType = new MessagePackExtensionType(extType, bb); - assertExtensionType(ExtensionType, extType, expectedByteBuffer); + extensionType = new MessagePackextensionType(extType, bb); + assertextensionType(extensionType, extType, expectedByteBuffer); extType = 3; bb = ByteBuffer.allocateDirect(3); bb.put(bs); bb.position(0); - ExtensionType = new MessagePackExtensionType(extType, bb); - assertExtensionType(ExtensionType, extType, expectedByteBuffer); + extensionType = new MessagePackextensionType(extType, bb); + assertextensionType(extensionType, extType, expectedByteBuffer); extType = -1; - ExtensionType = - new MessagePackExtensionType(extType, ByteBuffer.wrap(bs).asReadOnlyBuffer()); - assertExtensionType(ExtensionType, extType, expectedByteBuffer); + extensionType = + new MessagePackextensionType(extType, ByteBuffer.wrap(bs).asReadOnlyBuffer()); + assertextensionType(extensionType, extType, expectedByteBuffer); extType = -2; bb = ByteBuffer.allocate(3); bb.put(bs); bb.position(0); - ExtensionType = new MessagePackExtensionType(extType, bb.asReadOnlyBuffer()); - assertExtensionType(ExtensionType, extType, expectedByteBuffer); + extensionType = new MessagePackextensionType(extType, bb.asReadOnlyBuffer()); + assertextensionType(extensionType, extType, expectedByteBuffer); extType = -3; bb = ByteBuffer.allocateDirect(3); bb.put(bs); bb.position(0); - ExtensionType = new MessagePackExtensionType(extType, bb.asReadOnlyBuffer()); - assertExtensionType(ExtensionType, extType, expectedByteBuffer); + extensionType = new MessagePackextensionType(extType, bb.asReadOnlyBuffer()); + assertextensionType(extensionType, extType, expectedByteBuffer); } } \ No newline at end of file From de6d1f5747e05eaa7b26d310a46038ecf1a1fda8 Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Sat, 13 Jun 2015 23:14:46 +0900 Subject: [PATCH 067/234] Add augumented constructor for ExtensionTypeHeader --- .../java/org/msgpack/core/ExtensionTypeHeader.java | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/msgpack-core/src/main/java/org/msgpack/core/ExtensionTypeHeader.java b/msgpack-core/src/main/java/org/msgpack/core/ExtensionTypeHeader.java index b507f978d..23a81eeef 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/ExtensionTypeHeader.java +++ b/msgpack-core/src/main/java/org/msgpack/core/ExtensionTypeHeader.java @@ -9,10 +9,16 @@ public class ExtensionTypeHeader { private final byte type; private final int length; - ExtensionTypeHeader(byte type, int length) { + public ExtensionTypeHeader(byte type, int length) { checkArgument(length >= 0, String.format("length must be >= 0: %,d", length)); - this.length = length; this.type = type; + this.length = length; + } + + public ExtensionTypeHeader(int type, int length) { + checkArgument(Byte.MIN_VALUE <= type && type <= Byte.MAX_VALUE, "Extension type must be within -128 to 127"); + this.type = (byte) type; + this.length = length; } public byte getType() { From 04819a37821b5219d9a36366cf087827da81263b Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Sat, 13 Jun 2015 23:25:03 +0900 Subject: [PATCH 068/234] Fix test case --- .../scala/org/msgpack/core/MessagePackTest.scala | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/msgpack-core/src/test/scala/org/msgpack/core/MessagePackTest.scala b/msgpack-core/src/test/scala/org/msgpack/core/MessagePackTest.scala index dd145eaa7..e0b03d794 100644 --- a/msgpack-core/src/test/scala/org/msgpack/core/MessagePackTest.scala +++ b/msgpack-core/src/test/scala/org/msgpack/core/MessagePackTest.scala @@ -16,7 +16,6 @@ package org.msgpack.core import org.msgpack.value.{Variable, Value} -import org.msgpack.value.holder.ValueHolder import scala.util.Random import MessagePack.Code @@ -444,19 +443,18 @@ class MessagePackTest extends MessagePackSpec { } } }, { unpacker => - val holder = new Variable() - unpacker.unpackValue(holder) - val v = holder.get() - - v.asArrayValue().toValueArray.map { m => + val v = new Variable() + unpacker.unpackValue(v) + import scala.collection.JavaConversions._ + v.asArrayValue().map { m => val mv = m.asMapValue() - val kvs = mv.toKeyValueSeq + val kvs = mv.getKeyValueArray kvs.grouped(2).map({ kvp: Array[Value] => val k = kvp(0) val v = kvp(1) - (k.asString().toString, v.asString().toString) + (k.asStringValue().toString, v.asStringValue().toString) }).toMap }.toList }) From d1807a5dc68bb315c887cca5492009e659991c3d Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Sat, 13 Jun 2015 23:35:35 +0900 Subject: [PATCH 069/234] Add ValueType bit mask to improve type check performance --- .../java/org/msgpack/core/MessageFormat.java | 2 +- .../java/org/msgpack/value/ValueFactory.java | 10 + .../java/org/msgpack/value/ValueType.java | 30 +++ .../scala/org/msgpack/value/CursorTest.scala | 199 ------------------ .../org/msgpack/value/ValueFactoryTest.scala | 26 +-- 5 files changed, 54 insertions(+), 213 deletions(-) delete mode 100644 msgpack-core/src/test/scala/org/msgpack/value/CursorTest.scala diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessageFormat.java b/msgpack-core/src/main/java/org/msgpack/core/MessageFormat.java index b00681244..4e02fced4 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/MessageFormat.java +++ b/msgpack-core/src/main/java/org/msgpack/core/MessageFormat.java @@ -95,7 +95,7 @@ public static MessageFormat valueOf(final byte b) { * @return */ @VisibleForTesting - static MessageFormat toMessageFormat(final byte b) { + public static MessageFormat toMessageFormat(final byte b) { if (Code.isPosFixInt(b)) { return POSFIXINT; } diff --git a/msgpack-core/src/main/java/org/msgpack/value/ValueFactory.java b/msgpack-core/src/main/java/org/msgpack/value/ValueFactory.java index 65d4e8061..e6390d5f6 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/ValueFactory.java +++ b/msgpack-core/src/main/java/org/msgpack/value/ValueFactory.java @@ -103,6 +103,11 @@ public static ImmutableArrayValue newArray(Value[] array) { return new ImmutableArrayValueImpl(Arrays.copyOf(array, array.length)); } + public static ImmutableArrayValue newArrayOf(Value... elem) { + return newArray(elem); + } + + public static ImmutableArrayValue emptyArray() { return ImmutableArrayValueImpl.empty(); } @@ -130,6 +135,11 @@ public static ImmutableMapValue newMap(Value[] kvs) { return new ImmutableMapValueImpl(Arrays.copyOf(kvs, kvs.length)); } + public static ImmutableMapValue emptyMap() { + return ImmutableMapValueImpl.empty(); + } + + public static class MapEntry { public final Value key; public final Value value; diff --git a/msgpack-core/src/main/java/org/msgpack/value/ValueType.java b/msgpack-core/src/main/java/org/msgpack/value/ValueType.java index 3d5a9c588..cda220551 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/ValueType.java +++ b/msgpack-core/src/main/java/org/msgpack/value/ValueType.java @@ -15,6 +15,8 @@ // package org.msgpack.value; +import org.msgpack.core.MessageFormat; + /** * MessageTypeFamily is a group of {@link org.msgpack.core.MessageFormat}s */ @@ -32,10 +34,30 @@ public enum ValueType { private final boolean numberType; private final boolean rawType; + private final int bitMask; private ValueType(boolean numberType, boolean rawType) { this.numberType = numberType; this.rawType = rawType; + this.bitMask = 1 << this.ordinal(); + } + + /** + * Returns a bit mask representing this value type for quickly cheking + * this value type + * @return bit mask representing this value type + */ + public int getBitMask() { + return bitMask; + } + + /** + * Check whether the given bit mask represents this value type + * @param bitMask + * @return + */ + public boolean isTypeOf(int bitMask) { + return (this.bitMask & bitMask) != 0; } public boolean isNilType() { @@ -81,4 +103,12 @@ public boolean isMapType() { public boolean isExtensionType() { return this == EXTENSION; } + + public static ValueType valueOf(byte b) { + return MessageFormat.valueOf(b).getValueType(); + } + + public String toTypeName() { + return this.name().substring(0, 1) + this.name().substring(1).toLowerCase(); + } } diff --git a/msgpack-core/src/test/scala/org/msgpack/value/CursorTest.scala b/msgpack-core/src/test/scala/org/msgpack/value/CursorTest.scala deleted file mode 100644 index ee46ff7bd..000000000 --- a/msgpack-core/src/test/scala/org/msgpack/value/CursorTest.scala +++ /dev/null @@ -1,199 +0,0 @@ -// -// MessagePack for Java -// -// 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.value - -import java.io.ByteArrayInputStream - -import org.msgpack.core.{MessagePack, MessageUnpacker, MessagePackSpec} -import ValueFactory._ -import scala.util.Random -import org.msgpack.value.holder.{ValueHolder, IntegerHolder} - -/** - * Created on 6/13/14. - */ -class CursorTest extends MessagePackSpec { - - val msgpack = MessagePack.DEFAULT - - def sampleData = createMessagePackData { packer => - packer.packValue( - ValueFactory.newArray( - newInt(10), - newBinary("message pack".getBytes(MessagePack.UTF8)), - newString("hello") - ) - ) - } - - def intSeq(n:Int) = createMessagePackData { packer => - (0 until n).foreach { i => - packer.packInt(Random.nextInt(65536)) - } - } - def binSeq(n:Int) = createMessagePackData { packer => - (0 until n).foreach { i => - val len = Random.nextInt(256) - val b = new Array[Byte](len) - Random.nextBytes(b) - packer.packBinaryHeader(b.length).writePayload(b) - } - } - - - "Cursor" should { - - "have array cursor" taggedAs("array") in { - - val cursor = msgpack.newUnpacker(sampleData).getCursor - // Traverse as references - val arrCursor = cursor.nextRef().getArrayCursor - arrCursor.size() shouldBe 3 - - import scala.collection.JavaConversions._ - for(v <- arrCursor) { - info(s"[${v.getValueType}]\t${v}") - } - } - - "have map cursor" taggedAs("map") in { - val packedData = createMessagePackData { packer => - packer packMapHeader(1) packString("f") packString("x") - } - - val cursor = msgpack.newUnpacker(packedData).getCursor - val mapCursor = cursor.nextRef().getMapCursor - mapCursor.size() shouldBe 1 - - val mapValue = mapCursor.toValue - val data = mapValue.toKeyValueSeq - - data should have length 2 - - data(0).asString().toString shouldBe "f" - data(1).asString().toString shouldBe "x" - } - - "traverse ValueRef faster than traversing Value" taggedAs("ref") in { - val N = 10000 - val data = binSeq(N) - - time("traversal", repeat=100) { - block("value") { - val cursor = msgpack.newUnpacker(data).getCursor - while(cursor.hasNext) { - cursor.next() - } - cursor.close() - } - block("value-ref") { - val cursor = msgpack.newUnpacker(data).getCursor - while(cursor.hasNext) { - cursor.nextRef() - } - cursor.close() - } - } - - } - - "have negligible overhead" taggedAs("perf") in { - val N = 10000 - val data = intSeq(N) - time("scan int-seq", repeat=1000) { - block("unpacker") { - val unpacker = msgpack.newUnpacker(data) - val intHolder = new IntegerHolder() - var count = 0 - while(unpacker.hasNext) { - val vt = unpacker.getNextFormat.getValueType - if(vt.isIntegerType) { - unpacker.unpackInteger(intHolder); - count += 1 - } - else { - throw new IllegalStateException(s"invalid format: ${vt}") - } - } - unpacker.close() - count shouldBe N - } - block("cursor") { - var count = 0 - val cursor = msgpack.newUnpacker(data).getCursor - while(cursor.hasNext) { - val ref = cursor.nextRef() - val v = ref.asInteger().toInt - count += 1 - } - cursor.close() - count shouldBe N - } - } - - } - - "create immutable map" taggedAs("im-map") in { - - val m = createMessagePackData { packer => - packer.packMapHeader(3) - - // A -> [1, "leo"] - packer.packString("A") - packer.packArrayHeader(2) - packer.packInt(1) - packer.packString("leo") - - // B -> 10 - packer.packString("B") - packer.packInt(10) - - // C -> {a -> 1.0f, b -> 5, c -> {cc->1}} - packer.packString("C") - packer.packMapHeader(3) - packer.packString("a") - packer.packFloat(1.0f) - packer.packString("b") - packer.packInt(5) - - packer.packString("c") - packer.packMapHeader(1) - packer.packString("cc") - packer.packInt(1) - - } - - val unpacker = msgpack.newUnpacker(m) - val vh = new ValueHolder - unpacker.unpackValue(vh) - val mapValue = vh.get().asMapValue() - - val map = mapValue.toMap - map.size shouldBe 3 - - val arr = map.get(ValueFactory.newString("A")).asArrayValue() - arr.size shouldBe 2 - - val cmap = map.get(ValueFactory.newString("C")).asMapValue() - cmap.size shouldBe 3 - cmap.toMap.get(ValueFactory.newString("c")).asMapValue().size() shouldBe 1 - - info(mapValue) - } - - - } -} diff --git a/msgpack-core/src/test/scala/org/msgpack/value/ValueFactoryTest.scala b/msgpack-core/src/test/scala/org/msgpack/value/ValueFactoryTest.scala index 6069afadf..51ac4704e 100644 --- a/msgpack-core/src/test/scala/org/msgpack/value/ValueFactoryTest.scala +++ b/msgpack-core/src/test/scala/org/msgpack/value/ValueFactoryTest.scala @@ -21,25 +21,25 @@ class ValueFactoryTest extends MessagePackSpec { isRaw : Boolean = false, isNumber : Boolean = false ) { - v.isNil shouldBe isNil - v.isBoolean shouldBe isBoolean - v.isInteger shouldBe isInteger - v.isFloat shouldBe isFloat - v.isString shouldBe isString - v.isBinary shouldBe isBinary - v.isArray shouldBe isArray - v.isMap shouldBe isMap - v.isExtension shouldBe isExtension - v.isRaw shouldBe isRaw - v.isNumber shouldBe isNumber + v.isNilValue shouldBe isNil + v.isBooleanValue shouldBe isBoolean + v.isIntegerValue shouldBe isInteger + v.isFloatValue shouldBe isFloat + v.isStringValue shouldBe isString + v.isBinaryValue shouldBe isBinary + v.isArrayValue shouldBe isArray + v.isMapValue shouldBe isMap + v.isExtensionValue shouldBe isExtension + v.isRawValue shouldBe isRaw + v.isNumberValue shouldBe isNumber } "ValueFactory" should { "create valid type values" in { - isValid(ValueFactory.nilValue(), expected=ValueType.NIL, isNil = true) + isValid(ValueFactory.nil(), expected=ValueType.NIL, isNil = true) forAll{(v:Boolean) => isValid(ValueFactory.newBoolean(v), expected=ValueType.BOOLEAN, isBoolean = true)} - forAll{(v:Int) => isValid(ValueFactory.newInt(v), expected=ValueType.INTEGER, isInteger = true, isNumber = true)} + forAll{(v:Int) => isValid(ValueFactory.newInteger(v), expected=ValueType.INTEGER, isInteger = true, isNumber = true)} forAll{(v:Float) => isValid(ValueFactory.newFloat(v), expected=ValueType.FLOAT, isFloat = true, isNumber = true)} forAll{(v:String) => isValid(ValueFactory.newString(v), expected=ValueType.STRING, isString = true, isRaw = true)} forAll{(v:Array[Byte]) => isValid(ValueFactory.newBinary(v), expected=ValueType.BINARY, isBinary = true, isRaw = true)} From 770f01368b389f666136695ee3f396d4c70f893d Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Sat, 13 Jun 2015 23:41:36 +0900 Subject: [PATCH 070/234] Preserve float and double differences --- msgpack-core/src/main/java/org/msgpack/value/Variable.java | 7 +++++++ .../test/scala/org/msgpack/core/MessagePackerTest.scala | 4 ++-- .../scala/org/msgpack/value/RawStringValueImplTest.scala | 2 +- .../test/scala/org/msgpack/value/RawValueImplTest.scala | 4 ++-- .../scala/org/msgpack/value/holder/FloatHolderTest.scala | 7 ++++--- 5 files changed, 16 insertions(+), 8 deletions(-) diff --git a/msgpack-core/src/main/java/org/msgpack/value/Variable.java b/msgpack-core/src/main/java/org/msgpack/value/Variable.java index 33125920b..941d09185 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/Variable.java +++ b/msgpack-core/src/main/java/org/msgpack/value/Variable.java @@ -521,6 +521,13 @@ public Variable setFloatValue(double v) { return this; } + public Variable setFloatValue(float v) { + this.type = Type.DOUBLE; + this.accessor = floatAccessor; + this.longValue = (long) v; // AbstractNumberValueAccessor uses longValue + return this; + } + private class FloatValueAccessor extends AbstractNumberValueAccessor implements FloatValue { @Override public FloatValue asFloatValue() { diff --git a/msgpack-core/src/test/scala/org/msgpack/core/MessagePackerTest.scala b/msgpack-core/src/test/scala/org/msgpack/core/MessagePackerTest.scala index 4c2dc46e9..e0c528731 100644 --- a/msgpack-core/src/test/scala/org/msgpack/core/MessagePackerTest.scala +++ b/msgpack-core/src/test/scala/org/msgpack/core/MessagePackerTest.scala @@ -128,8 +128,8 @@ class MessagePackerTest extends MessagePackSpec { def test(bufferSize: Int, stringSize: Int): Boolean = { val msgpack = new MessagePack(new MessagePack.ConfigBuilder().packerBufferSize(bufferSize).build) val str = "a" * stringSize - val rawString = ValueFactory.newRawString(str.getBytes("UTF-8")) - val array = ValueFactory.newArray(rawString) + val rawString = ValueFactory.newString(str.getBytes("UTF-8")) + val array = ValueFactory.newArrayOf(rawString) val out = new ByteArrayOutputStream() val packer = msgpack.newPacker(out) packer.packValue(array) diff --git a/msgpack-core/src/test/scala/org/msgpack/value/RawStringValueImplTest.scala b/msgpack-core/src/test/scala/org/msgpack/value/RawStringValueImplTest.scala index 1193a3310..bd57480e0 100644 --- a/msgpack-core/src/test/scala/org/msgpack/value/RawStringValueImplTest.scala +++ b/msgpack-core/src/test/scala/org/msgpack/value/RawStringValueImplTest.scala @@ -7,7 +7,7 @@ class RawStringValueImplTest extends MessagePackSpec { "StringValue" should { "return the same hash code if they are equal" in { val str = "a" - val a1 = ValueFactory.newRawString(str.getBytes("UTF-8")) + val a1 = ValueFactory.newString(str.getBytes("UTF-8")) val a2 = ValueFactory.newString(str) a1.shouldEqual(a2) diff --git a/msgpack-core/src/test/scala/org/msgpack/value/RawValueImplTest.scala b/msgpack-core/src/test/scala/org/msgpack/value/RawValueImplTest.scala index 6e56aa762..6a798410a 100644 --- a/msgpack-core/src/test/scala/org/msgpack/value/RawValueImplTest.scala +++ b/msgpack-core/src/test/scala/org/msgpack/value/RawValueImplTest.scala @@ -9,7 +9,7 @@ class RawValueImplTest extends MessagePackSpec { "RawValueImple" should { "toString shouldn't return empty value" in { val str = "aaa" - def newRawStr() = ValueFactory.newRawString(str.getBytes("UTF-8")) + def newRawStr() = ValueFactory.newString(str.getBytes("UTF-8")) def pack(v: Value): Array[Byte] = { val out = new ByteArrayOutputStream() @@ -28,7 +28,7 @@ class RawValueImplTest extends MessagePackSpec { { val rawStr = newRawStr() pack(rawStr) - rawStr.asString().toString shouldBe str + rawStr.asStringValue().toString shouldBe str } } } diff --git a/msgpack-core/src/test/scala/org/msgpack/value/holder/FloatHolderTest.scala b/msgpack-core/src/test/scala/org/msgpack/value/holder/FloatHolderTest.scala index 126d39352..ebbee0e7a 100644 --- a/msgpack-core/src/test/scala/org/msgpack/value/holder/FloatHolderTest.scala +++ b/msgpack-core/src/test/scala/org/msgpack/value/holder/FloatHolderTest.scala @@ -1,6 +1,7 @@ package org.msgpack.value.holder import org.msgpack.core.MessagePackSpec +import org.msgpack.value.Variable /** * @@ -11,13 +12,13 @@ class FloatHolderTest extends MessagePackSpec { "display value in an appropriate format" in { - val h = new FloatHolder + val h = new Variable val f = 0.1341f - h.setFloat(f) + h.setFloatValue(f) h.toString shouldBe java.lang.Float.toString(f) val d = 0.1341341344 - h.setDouble(d) + h.setFloatValue(d) h.toString shouldBe java.lang.Double.toString(d) } From 775379d06f929be27bdb14ec4a25a441bdb7e713 Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Sat, 13 Jun 2015 23:49:42 +0900 Subject: [PATCH 071/234] Renamed xxxValue that returns primitive type value as toXXX --- .../core/example/MessagePackExample.java | 10 +++--- .../java/org/msgpack/value/NumberValue.java | 36 +++++++++---------- .../main/java/org/msgpack/value/Value.java | 2 +- .../main/java/org/msgpack/value/Variable.java | 18 +++++----- .../impl/ImmutableBigIntegerValueImpl.java | 16 ++++----- .../value/impl/ImmutableDoubleValueImpl.java | 16 ++++----- .../value/impl/ImmutableLongValueImpl.java | 16 ++++----- .../jackson/dataformat/MessagePackParser.java | 24 ++++++------- 8 files changed, 67 insertions(+), 71 deletions(-) diff --git a/msgpack-core/src/main/java/org/msgpack/core/example/MessagePackExample.java b/msgpack-core/src/main/java/org/msgpack/core/example/MessagePackExample.java index c057b9513..beb9e767f 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/example/MessagePackExample.java +++ b/msgpack-core/src/main/java/org/msgpack/core/example/MessagePackExample.java @@ -184,22 +184,22 @@ public static void readAndWriteFile() throws IOException { case INTEGER: IntegerValue iv = v.asIntegerValue(); if(iv.isInIntRange()) { - int i = iv.intValue(); + int i = iv.toInt(); System.out.println("read int: " + i); } else if (iv.isInLongRange()) { - long l = iv.longValue(); + long l = iv.toLong(); System.out.println("read long: " + l); } else { - BigInteger i = iv.bigIntegerValue(); + BigInteger i = iv.toBigInteger(); System.out.println("read long: " + i); } break; case FLOAT: FloatValue fv = v.asFloatValue(); - float f = fv.floatValue(); // use as float - double d = fv.doubleValue(); // use as double + float f = fv.toFloat(); // use as float + double d = fv.toDouble(); // use as double System.out.println("read float: " + d); break; case STRING: diff --git a/msgpack-core/src/main/java/org/msgpack/value/NumberValue.java b/msgpack-core/src/main/java/org/msgpack/value/NumberValue.java index e106da1dd..5b6e976e1 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/NumberValue.java +++ b/msgpack-core/src/main/java/org/msgpack/value/NumberValue.java @@ -20,47 +20,43 @@ /** * The interface {@code NumberValue} is the interface of {@code IntegerValue} and {@code FloatValue}. * - * @see org.msgpack.value.IntegerValue - * @see org.msgpack.value.FloatValue + * @see org.msgpack.value.IntegerValue + * @see org.msgpack.value.FloatValue */ public interface NumberValue extends Value { - @Override - public ImmutableNumberValue toImmutable(); /** - * Returns the value as a {@code byte}, which may involve rounding or truncation. + * Convert this value into a byte value. If this value is not within the range of Byte value, it will truncate or round the value. */ - public byte byteValue(); + byte toByte(); /** - * Returns the value as a {@code short}, which may involve rounding or truncation. + * Convert this value into a short value. If this value is not within the range of Short value, it will truncate or round the value. */ - public short shortValue(); + short toShort(); /** - * Returns the value as an {@code int}, which may involve rounding or truncation. + * Convert this value into an int value. If this value is not within the range of Int value, it will truncate or round the value. */ - public int intValue(); + int toInt(); /** - * Returns the value as a {@code long}, which may involve rounding or truncation. + * Convert this value into a long value. If this value is not within the range of Long value, it will truncate or round the value. */ - public long longValue(); + long toLong(); /** - * Returns the value as a {@code BigInteger}, which may involve rounding or truncation. - * - * Rounding could happen if type of this value is float or double. + * Convert this value into a BigInteger. If value is Float type, it will round the value */ - public BigInteger bigIntegerValue(); + BigInteger toBigInteger(); /** - * Returns the value as a {@code float}, which may involve rounding or truncation. + * Converts this value into a 32-bit float */ - public float floatValue(); + float toFloat(); /** - * Returns the value as a {@code double}, which may involve rounding or truncation. + * Converts this value into a 64-bit double */ - public double doubleValue(); + double toDouble(); } diff --git a/msgpack-core/src/main/java/org/msgpack/value/Value.java b/msgpack-core/src/main/java/org/msgpack/value/Value.java index c223509ad..c643133a1 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/Value.java +++ b/msgpack-core/src/main/java/org/msgpack/value/Value.java @@ -30,7 +30,7 @@ public interface Value { *

* Note that you can't use instanceof to check type of a value because type of a mutable value is variable. */ - public ValueType getValueType(); + ValueType getValueType(); /** * Returns immutable copy of this value. diff --git a/msgpack-core/src/main/java/org/msgpack/value/Variable.java b/msgpack-core/src/main/java/org/msgpack/value/Variable.java index 941d09185..692cafcfc 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/Variable.java +++ b/msgpack-core/src/main/java/org/msgpack/value/Variable.java @@ -313,7 +313,7 @@ public NumberValue asNumberValue() { } @Override - public byte byteValue() { + public byte toByte() { if (type == Type.BIG_INTEGER) { return ((BigInteger) objectValue).byteValue(); } @@ -321,7 +321,7 @@ public byte byteValue() { } @Override - public short shortValue() { + public short toShort() { if (type == Type.BIG_INTEGER) { return ((BigInteger) objectValue).shortValue(); } @@ -329,7 +329,7 @@ public short shortValue() { } @Override - public int intValue() { + public int toInt() { if (type == Type.BIG_INTEGER) { return ((BigInteger) objectValue).intValue(); } @@ -337,7 +337,7 @@ public int intValue() { } @Override - public long longValue() { + public long toLong() { if (type == Type.BIG_INTEGER) { return ((BigInteger) objectValue).longValue(); } @@ -345,7 +345,7 @@ public long longValue() { } @Override - public BigInteger bigIntegerValue() { + public BigInteger toBigInteger() { if (type == Type.BIG_INTEGER) { return (BigInteger) objectValue; } @@ -356,7 +356,7 @@ else if (type == Type.DOUBLE) { } @Override - public float floatValue() { + public float toFloat() { if (type == Type.BIG_INTEGER) { return ((BigInteger) objectValue).floatValue(); } @@ -367,7 +367,7 @@ else if (type == Type.DOUBLE) { } @Override - public double doubleValue() { + public double toDouble() { if (type == Type.BIG_INTEGER) { return ((BigInteger) objectValue).doubleValue(); } @@ -517,14 +517,14 @@ public Variable setFloatValue(double v) { this.type = Type.DOUBLE; this.accessor = floatAccessor; this.doubleValue = v; - this.longValue = (long) v; // AbstractNumberValueAccessor uses longValue + this.longValue = (long) v; // AbstractNumberValueAccessor uses toLong return this; } public Variable setFloatValue(float v) { this.type = Type.DOUBLE; this.accessor = floatAccessor; - this.longValue = (long) v; // AbstractNumberValueAccessor uses longValue + this.longValue = (long) v; // AbstractNumberValueAccessor uses toLong return this; } diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableBigIntegerValueImpl.java b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableBigIntegerValueImpl.java index 8e117a074..e853bf8a2 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableBigIntegerValueImpl.java +++ b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableBigIntegerValueImpl.java @@ -65,37 +65,37 @@ public ImmutableIntegerValue asIntegerValue() { } @Override - public byte byteValue() { + public byte toByte() { return value.byteValue(); } @Override - public short shortValue() { + public short toShort() { return value.shortValue(); } @Override - public int intValue() { + public int toInt() { return value.intValue(); } @Override - public long longValue() { + public long toLong() { return value.longValue(); } @Override - public BigInteger bigIntegerValue() { + public BigInteger toBigInteger() { return value; } @Override - public float floatValue() { + public float toFloat() { return value.floatValue(); } @Override - public double doubleValue() { + public double toDouble() { return value.doubleValue(); } @@ -180,7 +180,7 @@ public boolean equals(Object o) { return false; } IntegerValue iv = v.asIntegerValue(); - return value.equals(iv.bigIntegerValue()); + return value.equals(iv.toBigInteger()); } @Override diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableDoubleValueImpl.java b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableDoubleValueImpl.java index 343175f4c..1ee8b963c 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableDoubleValueImpl.java +++ b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableDoubleValueImpl.java @@ -46,37 +46,37 @@ public ImmutableDoubleValueImpl toImmutable() { } @Override - public byte byteValue() { + public byte toByte() { return (byte) value; } @Override - public short shortValue() { + public short toShort() { return (short) value; } @Override - public int intValue() { + public int toInt() { return (int) value; } @Override - public long longValue() { + public long toLong() { return (long) value; } @Override - public BigInteger bigIntegerValue() { + public BigInteger toBigInteger() { return new BigDecimal(value).toBigInteger(); } @Override - public float floatValue() { + public float toFloat() { return (float) value; } @Override - public double doubleValue() { + public double toDouble() { return value; } @@ -103,7 +103,7 @@ public boolean equals(Object o) { if (!v.isFloatValue()) { return false; } - return value == v.asFloatValue().doubleValue(); + return value == v.asFloatValue().toDouble(); } @Override diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableLongValueImpl.java b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableLongValueImpl.java index 3542aaacb..839704415 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableLongValueImpl.java +++ b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableLongValueImpl.java @@ -63,37 +63,37 @@ public ImmutableIntegerValue asIntegerValue() { } @Override - public byte byteValue() { + public byte toByte() { return (byte) value; } @Override - public short shortValue() { + public short toShort() { return (short) value; } @Override - public int intValue() { + public int toInt() { return (int) value; } @Override - public long longValue() { + public long toLong() { return value; } @Override - public BigInteger bigIntegerValue() { + public BigInteger toBigInteger() { return BigInteger.valueOf(value); } @Override - public float floatValue() { + public float toFloat() { return (float) value; } @Override - public double doubleValue() { + public double toDouble() { return (double) value; } @@ -178,7 +178,7 @@ public boolean equals(Object o) { if (!iv.isInLongRange()) { return false; } - return value == iv.longValue(); + return value == iv.toLong(); } @Override diff --git a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java index 756d8a55a..5c1d308dc 100644 --- a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java +++ b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java @@ -253,42 +253,42 @@ public Number getNumberValue() throws IOException, JsonParseException { if (value.isIntegerValue()) { IntegerValue integerValue = value.asIntegerValue(); if (integerValue.isInIntRange()) { - return integerValue.intValue(); + return integerValue.toInt(); } else if (integerValue.isInLongRange()) { - return integerValue.longValue(); + return integerValue.toLong(); } else { - return integerValue.bigIntegerValue(); + return integerValue.toBigInteger(); } } else { - return value.asNumberValue().doubleValue(); + return value.asNumberValue().toDouble(); } } @Override public int getIntValue() throws IOException, JsonParseException { - return value.asNumberValue().intValue(); + return value.asNumberValue().toInt(); } @Override public long getLongValue() throws IOException, JsonParseException { - return value.asNumberValue().longValue(); + return value.asNumberValue().toLong(); } @Override public BigInteger getBigIntegerValue() throws IOException, JsonParseException { - return value.asNumberValue().bigIntegerValue(); + return value.asNumberValue().toBigInteger(); } @Override public float getFloatValue() throws IOException, JsonParseException { - return value.asNumberValue().floatValue(); + return value.asNumberValue().toFloat(); } @Override public double getDoubleValue() throws IOException, JsonParseException { - return value.asNumberValue().doubleValue(); + return value.asNumberValue().toDouble(); } @Override @@ -297,14 +297,14 @@ public BigDecimal getDecimalValue() throws IOException { IntegerValue number = value.asIntegerValue(); //optimization to not convert the value to BigInteger unnecessarily if (number.isInLongRange()) { - return BigDecimal.valueOf(number.longValue()); + return BigDecimal.valueOf(number.toLong()); } else { - return new BigDecimal(number.bigIntegerValue()); + return new BigDecimal(number.toBigInteger()); } } else if (value.isFloatValue()) { - return BigDecimal.valueOf(value.asFloatValue().doubleValue()); + return BigDecimal.valueOf(value.asFloatValue().toDouble()); } else { throw new UnsupportedOperationException("Couldn't parse value as BigDecimal. " + value); From 301ae108cbff746f6f63d6bb0303882b261a4c74 Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Sun, 14 Jun 2015 00:05:45 +0900 Subject: [PATCH 072/234] Remove public scope from interface --- .../java/org/msgpack/value/ArrayValue.java | 12 ++++---- .../java/org/msgpack/value/BinaryValue.java | 2 -- .../java/org/msgpack/value/BooleanValue.java | 5 +--- .../org/msgpack/value/ExtensionValue.java | 7 ++--- .../java/org/msgpack/value/FloatValue.java | 2 -- .../msgpack/value/ImmutableArrayValue.java | 4 +-- .../java/org/msgpack/value/IntegerValue.java | 30 +++++++++---------- .../main/java/org/msgpack/value/MapValue.java | 15 ++++------ .../main/java/org/msgpack/value/NilValue.java | 2 -- .../main/java/org/msgpack/value/RawValue.java | 12 ++++---- .../java/org/msgpack/value/StringValue.java | 2 -- 11 files changed, 35 insertions(+), 58 deletions(-) diff --git a/msgpack-core/src/main/java/org/msgpack/value/ArrayValue.java b/msgpack-core/src/main/java/org/msgpack/value/ArrayValue.java index 8f69fc638..bb0d00e41 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/ArrayValue.java +++ b/msgpack-core/src/main/java/org/msgpack/value/ArrayValue.java @@ -24,13 +24,11 @@ * MessagePack's Array type can represent sequence of values. */ public interface ArrayValue extends Value, Iterable { - @Override - public ImmutableArrayValue toImmutable(); /** * Returns number of elements in this array. */ - public int size(); + int size(); /** * Returns the element at the specified position in this array. @@ -39,21 +37,21 @@ public interface ArrayValue extends Value, Iterable { * If the index is out of range * (index < 0 || index >= size()) */ - public Value get(int index); + Value get(int index); /** * Returns the element at the specified position in this array. * This method returns an ImmutableNilValue if the index is out of range. */ - public Value getOrNilValue(int index); + Value getOrNilValue(int index); /** * Returns an iterator over elements. */ - public Iterator iterator(); + Iterator iterator(); /** * Returns the value as {@code List}. */ - public List list(); + List list(); } diff --git a/msgpack-core/src/main/java/org/msgpack/value/BinaryValue.java b/msgpack-core/src/main/java/org/msgpack/value/BinaryValue.java index 5a6250ed4..43ddcb966 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/BinaryValue.java +++ b/msgpack-core/src/main/java/org/msgpack/value/BinaryValue.java @@ -23,6 +23,4 @@ * @see org.msgpack.value.RawValue */ public interface BinaryValue extends RawValue { - @Override - public ImmutableBinaryValue toImmutable(); } diff --git a/msgpack-core/src/main/java/org/msgpack/value/BooleanValue.java b/msgpack-core/src/main/java/org/msgpack/value/BooleanValue.java index cd4512833..5b33d3567 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/BooleanValue.java +++ b/msgpack-core/src/main/java/org/msgpack/value/BooleanValue.java @@ -21,11 +21,8 @@ * MessagePack's Boolean type can represent {@code true} or {@code false}. */ public interface BooleanValue extends Value { - @Override - public ImmutableBooleanValue toImmutable(); - /** * Returns the value as a {@code boolean}. */ - public boolean getBoolean(); + boolean getBoolean(); } diff --git a/msgpack-core/src/main/java/org/msgpack/value/ExtensionValue.java b/msgpack-core/src/main/java/org/msgpack/value/ExtensionValue.java index faf7cbe33..12db63f29 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/ExtensionValue.java +++ b/msgpack-core/src/main/java/org/msgpack/value/ExtensionValue.java @@ -24,10 +24,7 @@ * As the type information, applications can use 0 to 127 as the application-specific types. -1 to -128 is reserved for MessagePack's future extension. */ public interface ExtensionValue extends Value { - @Override - public ImmutableExtensionValue toImmutable(); + byte getType(); - public byte getType(); - - public byte[] getData(); + byte[] getData(); } diff --git a/msgpack-core/src/main/java/org/msgpack/value/FloatValue.java b/msgpack-core/src/main/java/org/msgpack/value/FloatValue.java index 9f447f4e3..78f6da0e5 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/FloatValue.java +++ b/msgpack-core/src/main/java/org/msgpack/value/FloatValue.java @@ -23,6 +23,4 @@ * @see org.msgpack.value.NumberValue */ public interface FloatValue extends NumberValue { - @Override - public ImmutableFloatValue toImmutable(); } diff --git a/msgpack-core/src/main/java/org/msgpack/value/ImmutableArrayValue.java b/msgpack-core/src/main/java/org/msgpack/value/ImmutableArrayValue.java index f06c89e60..1c0ea24bb 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/ImmutableArrayValue.java +++ b/msgpack-core/src/main/java/org/msgpack/value/ImmutableArrayValue.java @@ -24,11 +24,11 @@ public interface ImmutableArrayValue extends ArrayValue, ImmutableValue { * Returns an iterator over elements. * Returned Iterator does not support {@code remove()} method since the value is immutable. */ - public Iterator iterator(); + Iterator iterator(); /** * Returns the value as {@code List}. * Returned List is immutable. It does not support {@code put()}, {@code clear()}, or other methods that modify the value. */ - public List list(); + List list(); } diff --git a/msgpack-core/src/main/java/org/msgpack/value/IntegerValue.java b/msgpack-core/src/main/java/org/msgpack/value/IntegerValue.java index 4d990ba9d..5f53e44c9 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/IntegerValue.java +++ b/msgpack-core/src/main/java/org/msgpack/value/IntegerValue.java @@ -16,6 +16,7 @@ package org.msgpack.value; import java.math.BigInteger; +import org.msgpack.core.MessageOverflowException; /** * The interface {@code IntegerValue} represents MessagePack's Integer type. @@ -23,63 +24,60 @@ * MessagePack's Integer type can represent from -263 to 264-1. */ public interface IntegerValue extends NumberValue { - @Override - public ImmutableIntegerValue toImmutable(); - /** * Returns true if the value is in the range of [-27 to 27-1]. */ - public boolean isInByteRange(); + boolean isInByteRange(); /** * Returns true if the value is in the range of [-215 to 215-1] */ - public boolean isInShortRange(); + boolean isInShortRange(); /** * Returns true if the value is in the range of [-231 to 231-1] */ - public boolean isInIntRange(); + boolean isInIntRange(); /** * Returns true if the value is in the range of [-263 to 263-1] */ - public boolean isInLongRange(); + boolean isInLongRange(); /** * Returns the value as a {@code byte}, otherwise throws an exception. * - * @throws MessageIntegerOverflowException + * @throws MessageOverflowException * If the value does not fit in the range of {@code byte} type. */ - public byte getByte(); + byte getByte(); /** * Returns the value as a {@code short}, otherwise throws an exception. * - * @throws MessageIntegerOverflowException + * @throws MessageOverflowException * If the value does not fit in the range of {@code short} type. */ - public short getShort(); + short getShort(); /** * Returns the value as an {@code int}, otherwise throws an exception. * - * @throws MessageIntegerOverflowException + * @throws MessageOverflowException * If the value does not fit in the range of {@code int} type. */ - public int getInt(); + int getInt(); /** * Returns the value as a {@code long}, otherwise throws an exception. * - * @throws MessageIntegerOverflowException + * @throws MessageOverflowException * If the value does not fit in the range of {@code long} type. */ - public long getLong(); + long getLong(); /** * Returns the value as a {@code BigInteger}. */ - public BigInteger getBigInteger(); + BigInteger getBigInteger(); } diff --git a/msgpack-core/src/main/java/org/msgpack/value/MapValue.java b/msgpack-core/src/main/java/org/msgpack/value/MapValue.java index c6945e820..b29617c5d 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/MapValue.java +++ b/msgpack-core/src/main/java/org/msgpack/value/MapValue.java @@ -25,24 +25,21 @@ * MessagePack's Map type can represent sequence of key-value pairs. */ public interface MapValue extends Value { - @Override - public ImmutableMapValue toImmutable(); - /** * Returns number of key-value pairs in this array. */ - public int size(); + int size(); - public Set keySet(); + Set keySet(); - public Set> entrySet(); + Set> entrySet(); - public Collection values(); + Collection values(); /** * Returns the value as {@code Map}. */ - public Map map(); + Map map(); /** * Returns the key-value pairs as an array of {@code Value}. @@ -51,5 +48,5 @@ public interface MapValue extends Value { * * For example, if this value represents {"k1": "v1", "k2": "v2"}, this method returns ["k1", "v1", "k2", "v2"]. */ - public Value[] getKeyValueArray(); + Value[] getKeyValueArray(); } diff --git a/msgpack-core/src/main/java/org/msgpack/value/NilValue.java b/msgpack-core/src/main/java/org/msgpack/value/NilValue.java index 2fe366b96..56c23a9f9 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/NilValue.java +++ b/msgpack-core/src/main/java/org/msgpack/value/NilValue.java @@ -19,6 +19,4 @@ * The interface {@code NilValue} represents MessagePack's Nil type. */ public interface NilValue extends Value { - @Override - public ImmutableNilValue toImmutable(); } diff --git a/msgpack-core/src/main/java/org/msgpack/value/RawValue.java b/msgpack-core/src/main/java/org/msgpack/value/RawValue.java index 50cd55849..748be0845 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/RawValue.java +++ b/msgpack-core/src/main/java/org/msgpack/value/RawValue.java @@ -16,6 +16,7 @@ package org.msgpack.value; import java.nio.ByteBuffer; +import org.msgpack.core.MessageStringCodingException; /** * The interface {@code RawValue} represents MessagePack's Raw type, which means Binary or String type. @@ -26,15 +27,12 @@ * @see org.msgpack.value.BinaryValue */ public interface RawValue extends Value { - @Override - public ImmutableRawValue toImmutable(); - /** * Returns the value as {@code byte[]}. * * This method copies the byte array. */ - public byte[] getByteArray(); + byte[] getByteArray(); /** * Returns the value as {@code ByteBuffer}. @@ -42,7 +40,7 @@ public interface RawValue extends Value { * Returned ByteBuffer is read-only. See {@code#asReadOnlyBuffer()}. * This method doesn't copy the byte array as much as possible. */ - public ByteBuffer getByteBuffer(); + ByteBuffer getByteBuffer(); /** * Returns the value as {@code String}. @@ -52,12 +50,12 @@ public interface RawValue extends Value { * @throws MessageStringCodingException * If this value includes invalid UTF-8 byte sequence. */ - public String getString(); + String getString(); /** * Returns the value as {@code String}. * * This method replaces an invalid UTF-8 byte sequence with U+FFFD replacement character. */ - public String stringValue(); + String stringValue(); } diff --git a/msgpack-core/src/main/java/org/msgpack/value/StringValue.java b/msgpack-core/src/main/java/org/msgpack/value/StringValue.java index d278a8459..0709a22b8 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/StringValue.java +++ b/msgpack-core/src/main/java/org/msgpack/value/StringValue.java @@ -25,6 +25,4 @@ * @see org.msgpack.value.RawValue */ public interface StringValue extends RawValue { - @Override - public ImmutableStringValue toImmutable(); } From 9db3537f6af1e7c66fd1aadcb74448da466ce751 Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Sun, 14 Jun 2015 00:30:24 +0900 Subject: [PATCH 073/234] Fix compilation error of msgpack-jackson --- .../dataformat/MessagePackExtensionType.java | 25 ++++++++++++++++++ .../MessagePackExtensionTypeTest.java | 26 +++++++++---------- .../dataformat/MessagePackParserTest.java | 12 ++++----- 3 files changed, 44 insertions(+), 19 deletions(-) create mode 100644 msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackExtensionType.java diff --git a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackExtensionType.java b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackExtensionType.java new file mode 100644 index 000000000..1218808e7 --- /dev/null +++ b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackExtensionType.java @@ -0,0 +1,25 @@ +package org.msgpack.jackson.dataformat; + + import java.nio.ByteBuffer; + +/** + * Created by komamitsu on 3/7/15. + */ +public class MessagePackExtensionType { + private final int extType; + private final ByteBuffer byteBuffer; + + public MessagePackExtensionType(int extType, ByteBuffer byteBuffer) { + this.extType = extType; + this.byteBuffer = byteBuffer.isReadOnly() ? + byteBuffer : byteBuffer.asReadOnlyBuffer(); + } + + public int extType() { + return extType; + } + + public ByteBuffer byteBuffer() { + return byteBuffer; + } +} diff --git a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackExtensionTypeTest.java b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackExtensionTypeTest.java index 3300323a5..1356638f1 100644 --- a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackExtensionTypeTest.java +++ b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackExtensionTypeTest.java @@ -6,8 +6,8 @@ import static org.junit.Assert.*; -public class MessagePackextensionTypeTest { - private void assertextensionType(MessagePackextensionType x, +public class MessagePackExtensionTypeTest { + private void assertExtensionType(MessagePackExtensionType x, int expectedExtType, ByteBuffer expectedByteBuffer) { assertEquals(expectedExtType, x.extType()); assertEquals(expectedByteBuffer, x.byteBuffer()); @@ -20,7 +20,7 @@ public void testMessagePackextensionType() { ByteBuffer expectedByteBuffer = ByteBuffer.wrap(bs); int extType = 1; - MessagePackextensionType extensionType = + MessagePackExtensionType extensionType = new MessagePackExtensionType(extType, ByteBuffer.wrap(bs)); assertExtensionType(extensionType, extType, expectedByteBuffer); @@ -28,33 +28,33 @@ public void testMessagePackextensionType() { ByteBuffer bb = ByteBuffer.allocate(3); bb.put(bs); bb.position(0); - extensionType = new MessagePackextensionType(extType, bb); - assertextensionType(extensionType, extType, expectedByteBuffer); + extensionType = new MessagePackExtensionType(extType, bb); + assertExtensionType(extensionType, extType, expectedByteBuffer); extType = 3; bb = ByteBuffer.allocateDirect(3); bb.put(bs); bb.position(0); - extensionType = new MessagePackextensionType(extType, bb); - assertextensionType(extensionType, extType, expectedByteBuffer); + extensionType = new MessagePackExtensionType(extType, bb); + assertExtensionType(extensionType, extType, expectedByteBuffer); extType = -1; extensionType = - new MessagePackextensionType(extType, ByteBuffer.wrap(bs).asReadOnlyBuffer()); - assertextensionType(extensionType, extType, expectedByteBuffer); + new MessagePackExtensionType(extType, ByteBuffer.wrap(bs).asReadOnlyBuffer()); + assertExtensionType(extensionType, extType, expectedByteBuffer); extType = -2; bb = ByteBuffer.allocate(3); bb.put(bs); bb.position(0); - extensionType = new MessagePackextensionType(extType, bb.asReadOnlyBuffer()); - assertextensionType(extensionType, extType, expectedByteBuffer); + extensionType = new MessagePackExtensionType(extType, bb.asReadOnlyBuffer()); + assertExtensionType(extensionType, extType, expectedByteBuffer); extType = -3; bb = ByteBuffer.allocateDirect(3); bb.put(bs); bb.position(0); - extensionType = new MessagePackextensionType(extType, bb.asReadOnlyBuffer()); - assertextensionType(extensionType, extType, expectedByteBuffer); + extensionType = new MessagePackExtensionType(extType, bb.asReadOnlyBuffer()); + assertExtensionType(extensionType, extType, expectedByteBuffer); } } \ No newline at end of file diff --git a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackParserTest.java b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackParserTest.java index abf8a5f1c..c781c9b00 100644 --- a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackParserTest.java +++ b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackParserTest.java @@ -142,9 +142,9 @@ else if (k.equals("bool")) { else if (k.equals("ext")) { // #9 bitmap |= 1 << 10; - MessagePackExtensionType ExtensionType = (MessagePackExtensionType) v; - assertEquals(0, ExtensionType.extType()); - assertEquals(ByteBuffer.wrap(extPayload), ExtensionType.byteBuffer()); + MessagePackExtensionType extensionType = (MessagePackExtensionType) v; + assertEquals(0, extensionType.extType()); + assertEquals(ByteBuffer.wrap(extPayload), extensionType.byteBuffer()); } } assertEquals(0x7FF, bitmap); @@ -249,9 +249,9 @@ else if (k.equals("child_map_age")) { // #10 assertEquals(true, array.get(i++)); // #11 - MessagePackExtensionType ExtensionType = (MessagePackExtensionType) array.get(i++); - assertEquals(-1, ExtensionType.extType()); - assertEquals(ByteBuffer.wrap(extPayload), ExtensionType.byteBuffer()); + MessagePackExtensionType extensionType = (MessagePackExtensionType) array.get(i++); + assertEquals(-1, extensionType.extType()); + assertEquals(ByteBuffer.wrap(extPayload), extensionType.byteBuffer()); } @Test From 584e9d27256e845aa1a4b01574b9df718804fa60 Mon Sep 17 00:00:00 2001 From: Mitsunori Komatsu Date: Sun, 14 Jun 2015 18:58:18 +0900 Subject: [PATCH 074/234] Make MessagePackGenerator be able to serialize extended type --- .../dataformat/MessagePackExtendedType.java | 25 ++++++++++++++++--- .../dataformat/MessagePackGenerator.java | 10 ++++++++ .../dataformat/MessagePackGeneratorTest.java | 23 +++++++++++++++-- 3 files changed, 53 insertions(+), 5 deletions(-) diff --git a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackExtendedType.java b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackExtendedType.java index 96bfac2c8..b48737942 100644 --- a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackExtendedType.java +++ b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackExtendedType.java @@ -1,10 +1,15 @@ package org.msgpack.jackson.dataformat; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; + +import java.io.IOException; import java.nio.ByteBuffer; -/** - * Created by komamitsu on 3/7/15. - */ +@JsonSerialize(using = MessagePackExtendedType.Serializer.class) public class MessagePackExtendedType { private final int extType; private final ByteBuffer byteBuffer; @@ -22,4 +27,18 @@ public int extType() { public ByteBuffer byteBuffer() { return byteBuffer; } + + public static class Serializer extends JsonSerializer { + @Override + public void serialize(MessagePackExtendedType value, JsonGenerator gen, SerializerProvider serializers) + throws IOException, JsonProcessingException { + if (gen instanceof MessagePackGenerator) { + MessagePackGenerator msgpackGenerator = (MessagePackGenerator)gen; + msgpackGenerator.writeExtendedType(value); + } + else { + throw new IllegalStateException("gen is expected to be MessagePackGenerator but it's " + gen.getClass()); + } + } + } } diff --git a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackGenerator.java b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackGenerator.java index 9ab725925..0ac144aea 100644 --- a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackGenerator.java +++ b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackGenerator.java @@ -175,6 +175,12 @@ else if (v instanceof BigDecimal) { else if (v instanceof Boolean) { messagePacker.packBoolean((Boolean) v); } + else if (v instanceof MessagePackExtendedType) { + MessagePackExtendedType extendedType = (MessagePackExtendedType) v; + ByteBuffer buf = extendedType.byteBuffer(); + messagePacker.packExtendedTypeHeader(extendedType.extType(), buf.remaining()); + messagePacker.writePayload(buf); + } else { throw new IllegalArgumentException(v.toString()); } @@ -324,6 +330,10 @@ public void writeNull() throws IOException, JsonGenerationException { addValueToStackTop(null); } + public void writeExtendedType(MessagePackExtendedType extendedType) throws IOException { + addValueToStackTop(extendedType); + } + @Override public void close() throws IOException { try { diff --git a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackGeneratorTest.java b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackGeneratorTest.java index c8961f3c2..b3ac4ef06 100644 --- a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackGeneratorTest.java +++ b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackGeneratorTest.java @@ -19,6 +19,7 @@ import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.Test; +import org.msgpack.core.ExtendedTypeHeader; import org.msgpack.core.MessagePack; import org.msgpack.core.MessageUnpacker; import org.msgpack.core.buffer.ArrayBufferInput; @@ -29,8 +30,10 @@ import java.io.IOException; import java.io.OutputStream; import java.math.BigDecimal; +import java.nio.ByteBuffer; import java.util.*; +import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; @@ -63,6 +66,10 @@ public void testGeneratorShouldWriteObject() throws IOException { childArray.add("child#1"); childArray.add(1.23f); hashMap.put("childArray", childArray); + // #10 + byte[] hello = "hello".getBytes("UTF-8"); + ByteBuffer buffer = ByteBuffer.wrap(hello); + hashMap.put("ext", new MessagePackExtendedType(17, buffer)); long bitmap = 0; byte[] bytes = objectMapper.writeValueAsBytes(hashMap); @@ -134,11 +141,24 @@ else if (key.equals("childArray")) { assertEquals(1.23f, messageUnpacker.unpackFloat(), 0.01f); bitmap |= 0x1 << 9; } + else if (key.equals("ext")) { + // #9 + ExtendedTypeHeader header = messageUnpacker.unpackExtendedTypeHeader(); + assertEquals(17, header.getType()); + assertEquals(5, header.getLength()); + ByteBuffer payload = ByteBuffer.allocate(header.getLength()); + payload.flip(); + payload.limit(payload.capacity()); + messageUnpacker.readPayload(payload); + payload.flip(); + assertArrayEquals("hello".getBytes(), payload.array()); + bitmap |= 0x1 << 10; + } else { assertTrue(false); } } - assertEquals(0x03FF, bitmap); + assertEquals(0x07FF, bitmap); } @Test @@ -270,7 +290,6 @@ public void testBigDecimal() throws IOException { } { - BigDecimal decimal = new BigDecimal("1234.567890123456789012345678901234567890"); List bigDecimals = Arrays.asList( decimal From 91bae6dc5669dbf99fc12174e9dd0862c1e06135 Mon Sep 17 00:00:00 2001 From: Mitsunori Komatsu Date: Sun, 14 Jun 2015 20:43:29 +0900 Subject: [PATCH 075/234] Change an error message in MessagePackExtendedType --- .../org/msgpack/jackson/dataformat/MessagePackExtendedType.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackExtendedType.java b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackExtendedType.java index b48737942..45355b939 100644 --- a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackExtendedType.java +++ b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackExtendedType.java @@ -37,7 +37,7 @@ public void serialize(MessagePackExtendedType value, JsonGenerator gen, Serializ msgpackGenerator.writeExtendedType(value); } else { - throw new IllegalStateException("gen is expected to be MessagePackGenerator but it's " + gen.getClass()); + throw new IllegalStateException("'gen' is expected to be MessagePackGenerator but it's " + gen.getClass()); } } } From 9cf12b0b990009227a13161410a17302ff7d7a0f Mon Sep 17 00:00:00 2001 From: Mitsunori Komatsu Date: Sun, 14 Jun 2015 20:46:08 +0900 Subject: [PATCH 076/234] Fix wrong comment --- .../msgpack/jackson/dataformat/MessagePackGeneratorTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackGeneratorTest.java b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackGeneratorTest.java index b3ac4ef06..05d8addb1 100644 --- a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackGeneratorTest.java +++ b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackGeneratorTest.java @@ -142,7 +142,7 @@ else if (key.equals("childArray")) { bitmap |= 0x1 << 9; } else if (key.equals("ext")) { - // #9 + // #10 ExtendedTypeHeader header = messageUnpacker.unpackExtendedTypeHeader(); assertEquals(17, header.getType()); assertEquals(5, header.getLength()); From 78ce8c8a95149e5f68a420310988ccddc72106f8 Mon Sep 17 00:00:00 2001 From: Mitsunori Komatsu Date: Mon, 15 Jun 2015 02:18:10 +0900 Subject: [PATCH 077/234] Fix MessageBufferU#putByteBuffer --- .../msgpack/core/buffer/MessageBufferU.java | 1 + .../core/buffer/MessageBufferTest.scala | 29 ++++++++++++++++++- 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferU.java b/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferU.java index adc72acd0..4240ac90b 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferU.java +++ b/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferU.java @@ -149,6 +149,7 @@ public void putByteBuffer(int index, ByteBuffer src, int len) { int prevSrcLimit = src.limit(); try { src.limit(src.position() + len); + reference.position(index); reference.put(src); } finally { diff --git a/msgpack-core/src/test/scala/org/msgpack/core/buffer/MessageBufferTest.scala b/msgpack-core/src/test/scala/org/msgpack/core/buffer/MessageBufferTest.scala index 505dbd312..6652079db 100644 --- a/msgpack-core/src/test/scala/org/msgpack/core/buffer/MessageBufferTest.scala +++ b/msgpack-core/src/test/scala/org/msgpack/core/buffer/MessageBufferTest.scala @@ -132,8 +132,35 @@ class MessageBufferTest extends MessagePackSpec { bb.capacity shouldBe 10 } } - } + "put ByteBuffer on itself" in { + for (t <- Seq( + MessageBuffer.newBuffer(10), + MessageBuffer.newDirectBuffer(10), + MessageBuffer.newOffHeapBuffer(10)) + ) { + val b = Array[Byte](0x02, 0x03) + val srcArray = ByteBuffer.wrap(b) + val srcHeap = ByteBuffer.allocate(b.length) + srcHeap.put(b).flip + val srcOffHeap = ByteBuffer.allocateDirect(b.length) + srcOffHeap.put(b).flip + + for (src <- Seq(srcArray, srcHeap, srcOffHeap)) { + // Write header bytes + val header = Array[Byte](0x00, 0x01) + t.putBytes(0, header, 0, header.length) + // Write src after the header + t.putByteBuffer(header.length, src, header.length) + + t.getByte(0) shouldBe 0x00 + t.getByte(1) shouldBe 0x01 + t.getByte(2) shouldBe 0x02 + t.getByte(3) shouldBe 0x03 + } + } + } + } } From c78245174b2e5a697395338f38a1f336edc75312 Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Mon, 15 Jun 2015 12:02:11 +0900 Subject: [PATCH 078/234] toImmutable -> immutableValue --- .../main/java/org/msgpack/value/Value.java | 2 +- .../main/java/org/msgpack/value/Variable.java | 28 +++++++++---------- .../value/impl/ImmutableArrayValueImpl.java | 2 +- .../impl/ImmutableBigIntegerValueImpl.java | 2 +- .../value/impl/ImmutableBinaryValueImpl.java | 2 +- .../value/impl/ImmutableBooleanValueImpl.java | 2 +- .../value/impl/ImmutableDoubleValueImpl.java | 2 +- .../impl/ImmutableExtensionValueImpl.java | 2 +- .../value/impl/ImmutableLongValueImpl.java | 2 +- .../value/impl/ImmutableMapValueImpl.java | 2 +- .../value/impl/ImmutableNilValueImpl.java | 2 +- .../value/impl/ImmutableStringValueImpl.java | 2 +- 12 files changed, 25 insertions(+), 25 deletions(-) diff --git a/msgpack-core/src/main/java/org/msgpack/value/Value.java b/msgpack-core/src/main/java/org/msgpack/value/Value.java index c643133a1..3f32a4778 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/Value.java +++ b/msgpack-core/src/main/java/org/msgpack/value/Value.java @@ -37,7 +37,7 @@ public interface Value { *

* This method simply returns this without copying the value if this value is already immutable. */ - ImmutableValue toImmutable(); + ImmutableValue immutableValue(); /** * Returns true if type of this value is Nil. diff --git a/msgpack-core/src/main/java/org/msgpack/value/Variable.java b/msgpack-core/src/main/java/org/msgpack/value/Variable.java index 692cafcfc..31154a61b 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/Variable.java +++ b/msgpack-core/src/main/java/org/msgpack/value/Variable.java @@ -231,7 +231,7 @@ public NilValue asNilValue() { } @Override - public ImmutableNilValue toImmutable() { + public ImmutableNilValue immutableValue() { return ValueFactory.nil(); } @@ -270,7 +270,7 @@ public BooleanValue asBooleanValue() { } @Override - public ImmutableBooleanValue toImmutable() { + public ImmutableBooleanValue immutableValue() { return ValueFactory.newBoolean(getBoolean()); } @@ -413,7 +413,7 @@ public IntegerValue asIntegerValue() { } @Override - public ImmutableIntegerValue toImmutable() { + public ImmutableIntegerValue immutableValue() { if (type == Type.BIG_INTEGER) { return ValueFactory.newInteger((BigInteger) objectValue); } @@ -535,7 +535,7 @@ public FloatValue asFloatValue() { } @Override - public ImmutableFloatValue toImmutable() { + public ImmutableFloatValue immutableValue() { return ValueFactory.newFloat(doubleValue); } @@ -628,7 +628,7 @@ public BinaryValue asBinaryValue() { } @Override - public ImmutableBinaryValue toImmutable() { + public ImmutableBinaryValue immutableValue() { return ValueFactory.newBinary(getByteArray()); } @@ -673,7 +673,7 @@ public StringValue asStringValue() { } @Override - public ImmutableStringValue toImmutable() { + public ImmutableStringValue immutableValue() { return ValueFactory.newString((byte[]) objectValue); } @@ -714,7 +714,7 @@ public ArrayValue asArrayValue() { } @Override - public ImmutableArrayValue toImmutable() { + public ImmutableArrayValue immutableValue() { return ValueFactory.newArray(list()); } @@ -786,7 +786,7 @@ public MapValue asMapValue() { } @Override - public ImmutableMapValue toImmutable() { + public ImmutableMapValue immutableValue() { return ValueFactory.newMap(map()); } @@ -870,7 +870,7 @@ public ExtensionValue asExtensionValue() { } @Override - public ImmutableExtensionValue toImmutable() { + public ImmutableExtensionValue immutableValue() { return (ImmutableExtensionValue) objectValue; } @@ -901,8 +901,8 @@ public void accept(ValueVisitor visitor) { // @Override - public ImmutableValue toImmutable() { - return accessor.toImmutable(); + public ImmutableValue immutableValue() { + return accessor.immutableValue(); } @Override @@ -917,17 +917,17 @@ public void accept(ValueVisitor visitor) { @Override public int hashCode() { - return toImmutable().hashCode(); // TODO optimize + return immutableValue().hashCode(); // TODO optimize } @Override public boolean equals(Object o) { - return toImmutable().equals(o); // TODO optimize + return immutableValue().equals(o); // TODO optimize } @Override public String toString() { - return toImmutable().toString(); // TODO optimize + return immutableValue().toString(); // TODO optimize } @Override diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableArrayValueImpl.java b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableArrayValueImpl.java index 43bcb3f5f..44b204332 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableArrayValueImpl.java +++ b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableArrayValueImpl.java @@ -50,7 +50,7 @@ public ValueType getValueType() { } @Override - public ImmutableArrayValue toImmutable() { + public ImmutableArrayValue immutableValue() { return this; } diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableBigIntegerValueImpl.java b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableBigIntegerValueImpl.java index e853bf8a2..98bcaf8e6 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableBigIntegerValueImpl.java +++ b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableBigIntegerValueImpl.java @@ -50,7 +50,7 @@ public ValueType getValueType() { } @Override - public ImmutableIntegerValue toImmutable() { + public ImmutableIntegerValue immutableValue() { return this; } diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableBinaryValueImpl.java b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableBinaryValueImpl.java index 57a205b87..ef0f5dd6b 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableBinaryValueImpl.java +++ b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableBinaryValueImpl.java @@ -42,7 +42,7 @@ public ValueType getValueType() { } @Override - public ImmutableBinaryValue toImmutable() { + public ImmutableBinaryValue immutableValue() { return this; } diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableBooleanValueImpl.java b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableBooleanValueImpl.java index a902a5741..f24504286 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableBooleanValueImpl.java +++ b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableBooleanValueImpl.java @@ -44,7 +44,7 @@ public ValueType getValueType() { } @Override - public ImmutableBooleanValue toImmutable() { + public ImmutableBooleanValue immutableValue() { return this; } diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableDoubleValueImpl.java b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableDoubleValueImpl.java index 1ee8b963c..7f71ae23a 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableDoubleValueImpl.java +++ b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableDoubleValueImpl.java @@ -41,7 +41,7 @@ public ValueType getValueType() { } @Override - public ImmutableDoubleValueImpl toImmutable() { + public ImmutableDoubleValueImpl immutableValue() { return this; } diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableExtensionValueImpl.java b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableExtensionValueImpl.java index fbb7c0314..e698be4c4 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableExtensionValueImpl.java +++ b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableExtensionValueImpl.java @@ -42,7 +42,7 @@ public ValueType getValueType() { } @Override - public ImmutableExtensionValue toImmutable() { + public ImmutableExtensionValue immutableValue() { return this; } diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableLongValueImpl.java b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableLongValueImpl.java index 839704415..5d7c65c75 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableLongValueImpl.java +++ b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableLongValueImpl.java @@ -48,7 +48,7 @@ public ValueType getValueType() { } @Override - public ImmutableIntegerValue toImmutable() { + public ImmutableIntegerValue immutableValue() { return this; } diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableMapValueImpl.java b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableMapValueImpl.java index 465795a8e..b96f9be50 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableMapValueImpl.java +++ b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableMapValueImpl.java @@ -54,7 +54,7 @@ public ValueType getValueType() { } @Override - public ImmutableMapValue toImmutable() { + public ImmutableMapValue immutableValue() { return this; } diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableNilValueImpl.java b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableNilValueImpl.java index 3e818b1e2..0a3ac2c6c 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableNilValueImpl.java +++ b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableNilValueImpl.java @@ -46,7 +46,7 @@ public ValueType getValueType() { } @Override - public ImmutableNilValue toImmutable() { + public ImmutableNilValue immutableValue() { return this; } diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableStringValueImpl.java b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableStringValueImpl.java index 4af14b9f7..45c14ace5 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableStringValueImpl.java +++ b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableStringValueImpl.java @@ -46,7 +46,7 @@ public ValueType getValueType() { } @Override - public ImmutableStringValue toImmutable() { + public ImmutableStringValue immutableValue() { return this; } From ed45331e90eaf85947b60e19f3abb2c98dbe0cbb Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Mon, 15 Jun 2015 12:28:51 +0900 Subject: [PATCH 079/234] Remove visitor, ExtensionTypeHeader constructor. Fix exception type of integer overflow --- .../org/msgpack/core/ExtensionTypeHeader.java | 9 ++-- .../java/org/msgpack/value/IntegerValue.java | 10 ++-- .../main/java/org/msgpack/value/Value.java | 7 --- .../java/org/msgpack/value/ValueVisitor.java | 38 --------------- .../main/java/org/msgpack/value/Variable.java | 48 ------------------- .../value/impl/ImmutableArrayValueImpl.java | 5 -- .../impl/ImmutableBigIntegerValueImpl.java | 5 -- .../value/impl/ImmutableBinaryValueImpl.java | 23 ++++----- .../value/impl/ImmutableBooleanValueImpl.java | 24 +++++----- .../value/impl/ImmutableDoubleValueImpl.java | 19 ++++---- .../impl/ImmutableExtensionValueImpl.java | 5 -- .../value/impl/ImmutableLongValueImpl.java | 5 -- .../value/impl/ImmutableMapValueImpl.java | 5 -- .../value/impl/ImmutableNilValueImpl.java | 6 --- .../value/impl/ImmutableStringValueImpl.java | 6 --- .../org/msgpack/core/MessagePackTest.scala | 4 +- 16 files changed, 39 insertions(+), 180 deletions(-) delete mode 100644 msgpack-core/src/main/java/org/msgpack/value/ValueVisitor.java diff --git a/msgpack-core/src/main/java/org/msgpack/core/ExtensionTypeHeader.java b/msgpack-core/src/main/java/org/msgpack/core/ExtensionTypeHeader.java index 23a81eeef..a0e27b670 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/ExtensionTypeHeader.java +++ b/msgpack-core/src/main/java/org/msgpack/core/ExtensionTypeHeader.java @@ -10,15 +10,14 @@ public class ExtensionTypeHeader { private final int length; public ExtensionTypeHeader(byte type, int length) { - checkArgument(length >= 0, String.format("length must be >= 0: %,d", length)); + checkArgument(length >= 0, "length must be >= 0"); this.type = type; this.length = length; } - public ExtensionTypeHeader(int type, int length) { - checkArgument(Byte.MIN_VALUE <= type && type <= Byte.MAX_VALUE, "Extension type must be within -128 to 127"); - this.type = (byte) type; - this.length = length; + public static byte checkedCastToByte(int code) { + checkArgument(code < Byte.MIN_VALUE && code > Byte.MAX_VALUE, "Extension type code must be within the range of byte"); + return (byte) code; } public byte getType() { diff --git a/msgpack-core/src/main/java/org/msgpack/value/IntegerValue.java b/msgpack-core/src/main/java/org/msgpack/value/IntegerValue.java index 5f53e44c9..c6cfec721 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/IntegerValue.java +++ b/msgpack-core/src/main/java/org/msgpack/value/IntegerValue.java @@ -16,7 +16,7 @@ package org.msgpack.value; import java.math.BigInteger; -import org.msgpack.core.MessageOverflowException; +import org.msgpack.core.MessageIntegerOverflowException; /** * The interface {@code IntegerValue} represents MessagePack's Integer type. @@ -47,7 +47,7 @@ public interface IntegerValue extends NumberValue { /** * Returns the value as a {@code byte}, otherwise throws an exception. * - * @throws MessageOverflowException + * @throws MessageIntegerOverflowException * If the value does not fit in the range of {@code byte} type. */ byte getByte(); @@ -55,7 +55,7 @@ public interface IntegerValue extends NumberValue { /** * Returns the value as a {@code short}, otherwise throws an exception. * - * @throws MessageOverflowException + * @throws MessageIntegerOverflowException * If the value does not fit in the range of {@code short} type. */ short getShort(); @@ -63,7 +63,7 @@ public interface IntegerValue extends NumberValue { /** * Returns the value as an {@code int}, otherwise throws an exception. * - * @throws MessageOverflowException + * @throws MessageIntegerOverflowException * If the value does not fit in the range of {@code int} type. */ int getInt(); @@ -71,7 +71,7 @@ public interface IntegerValue extends NumberValue { /** * Returns the value as a {@code long}, otherwise throws an exception. * - * @throws MessageOverflowException + * @throws MessageIntegerOverflowException * If the value does not fit in the range of {@code long} type. */ long getLong(); diff --git a/msgpack-core/src/main/java/org/msgpack/value/Value.java b/msgpack-core/src/main/java/org/msgpack/value/Value.java index 3f32a4778..1cc2f964e 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/Value.java +++ b/msgpack-core/src/main/java/org/msgpack/value/Value.java @@ -235,13 +235,6 @@ public interface Value { */ void writeTo(MessagePacker pk) throws IOException; - - /** - * Accept a visitor to traverse this value - * @param visitor - */ - void accept(ValueVisitor visitor); - /** * Compares this value to the specified object. *

diff --git a/msgpack-core/src/main/java/org/msgpack/value/ValueVisitor.java b/msgpack-core/src/main/java/org/msgpack/value/ValueVisitor.java deleted file mode 100644 index a8f0e93d2..000000000 --- a/msgpack-core/src/main/java/org/msgpack/value/ValueVisitor.java +++ /dev/null @@ -1,38 +0,0 @@ -// -// MessagePack for Java -// -// 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.value; - -/** - * Interface for implementing the visitor pattern on message-packed values - */ -public interface ValueVisitor { - - void visitNil(); - void visitBoolean(BooleanValue v); - void visitInteger(IntegerValue v); - void visitFloat(FloatValue v); - void visitBinary(BinaryValue v); - void visitString(StringValue v); - void visitArray(ArrayValue v); - void visitMap(MapValue v); - void visitExtension(ExtensionValue v); - - /** - * Visitor can use this method to handle an exception occurred while visiting a value - * @param e - */ - void onError(Exception e); -} diff --git a/msgpack-core/src/main/java/org/msgpack/value/Variable.java b/msgpack-core/src/main/java/org/msgpack/value/Variable.java index 31154a61b..1856d605f 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/Variable.java +++ b/msgpack-core/src/main/java/org/msgpack/value/Variable.java @@ -239,11 +239,6 @@ public ImmutableNilValue immutableValue() { public void writeTo(MessagePacker pk) throws IOException { pk.packNil(); } - - @Override - public void accept(ValueVisitor visitor) { - visitor.visitNil(); - } } @@ -283,11 +278,6 @@ public boolean getBoolean() { public void writeTo(MessagePacker pk) throws IOException { pk.packBoolean(longValue == 1L); } - - @Override - public void accept(ValueVisitor visitor) { - visitor.visitBoolean(this); - } } @@ -501,11 +491,6 @@ public void writeTo(MessagePacker pk) throws IOException { pk.packLong(longValue); } } - - @Override - public void accept(ValueVisitor visitor) { - visitor.visitInteger(this); - } } @@ -549,10 +534,6 @@ public void writeTo(MessagePacker pk) throws IOException { pk.packDouble(doubleValue); } - @Override - public void accept(ValueVisitor visitor) { - visitor.visitFloat(this); - } } @@ -639,10 +620,6 @@ public void writeTo(MessagePacker pk) throws IOException { pk.writePayload(data); } - @Override - public void accept(ValueVisitor visitor) { - visitor.visitBinary(this); - } } @@ -683,11 +660,6 @@ public void writeTo(MessagePacker pk) throws IOException { pk.packRawStringHeader(data.length); pk.writePayload(data); } - - @Override - public void accept(ValueVisitor visitor) { - visitor.visitString(this); - } } @@ -756,11 +728,6 @@ public void writeTo(MessagePacker pk) throws IOException { e.writeTo(pk); } } - - @Override - public void accept(ValueVisitor visitor) { - visitor.visitArray(this); - } } //// @@ -840,11 +807,6 @@ public void writeTo(MessagePacker pk) throws IOException { pair.getValue().writeTo(pk); } } - - @Override - public void accept(ValueVisitor visitor) { - visitor.visitMap(this); - } } @@ -888,11 +850,6 @@ public byte[] getData() { public void writeTo(MessagePacker pk) throws IOException { ((ImmutableExtensionValue) objectValue).writeTo(pk); } - - @Override - public void accept(ValueVisitor visitor) { - visitor.visitExtension(((ImmutableExtensionValue) objectValue)); - } } @@ -910,11 +867,6 @@ public void writeTo(MessagePacker pk) throws IOException { accessor.writeTo(pk); } - @Override - public void accept(ValueVisitor visitor) { - accessor.accept(visitor); - } - @Override public int hashCode() { return immutableValue().hashCode(); // TODO optimize diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableArrayValueImpl.java b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableArrayValueImpl.java index 44b204332..39564711d 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableArrayValueImpl.java +++ b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableArrayValueImpl.java @@ -95,11 +95,6 @@ public void writeTo(MessagePacker pk) throws IOException { } } - @Override - public void accept(ValueVisitor visitor) { - visitor.visitArray(this); - } - @Override public boolean equals(Object o) { if(o == this) { diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableBigIntegerValueImpl.java b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableBigIntegerValueImpl.java index 98bcaf8e6..2bbd9a8bd 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableBigIntegerValueImpl.java +++ b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableBigIntegerValueImpl.java @@ -161,11 +161,6 @@ public void writeTo(MessagePacker pk) throws IOException { pk.packBigInteger(value); } - @Override - public void accept(ValueVisitor visitor) { - visitor.visitInteger(this); - } - @Override public boolean equals(Object o) { if (o == this) { diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableBinaryValueImpl.java b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableBinaryValueImpl.java index ef0f5dd6b..da794e001 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableBinaryValueImpl.java +++ b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableBinaryValueImpl.java @@ -16,20 +16,19 @@ package org.msgpack.value.impl; import org.msgpack.core.MessagePacker; +import org.msgpack.value.ImmutableBinaryValue; import org.msgpack.value.Value; import org.msgpack.value.ValueType; -import org.msgpack.value.ImmutableBinaryValue; -import org.msgpack.value.ValueVisitor; -import java.util.Arrays; import java.io.IOException; +import java.util.Arrays; /** * {@code ImmutableBinaryValueImpl} Implements {@code ImmutableBinaryValue} using a {@code byte[]} field. * This implementation caches result of {@code stringValue()} and {@code getString()} using a private {@code String} field. * - * @see org.msgpack.value.StringValue + * @see org.msgpack.value.StringValue */ public class ImmutableBinaryValueImpl extends AbstractImmutableRawValue implements ImmutableBinaryValue { public ImmutableBinaryValueImpl(byte[] data) { @@ -57,28 +56,24 @@ public void writeTo(MessagePacker pk) throws IOException { pk.writePayload(data); } - @Override - public void accept(ValueVisitor visitor) { - visitor.visitBinary(this); - } - @Override public boolean equals(Object o) { - if (this == o) { + if(this == o) { return true; } - if (!(o instanceof Value)) { + if(!(o instanceof Value)) { return false; } Value v = (Value) o; - if (!v.isBinaryValue()) { + if(!v.isBinaryValue()) { return false; } - if (v instanceof ImmutableBinaryValueImpl) { + if(v instanceof ImmutableBinaryValueImpl) { ImmutableBinaryValueImpl bv = (ImmutableBinaryValueImpl) v; return Arrays.equals(data, bv.data); - } else { + } + else { return Arrays.equals(data, v.asBinaryValue().getByteArray()); } } diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableBooleanValueImpl.java b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableBooleanValueImpl.java index f24504286..aee366788 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableBooleanValueImpl.java +++ b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableBooleanValueImpl.java @@ -16,17 +16,19 @@ package org.msgpack.value.impl; import org.msgpack.core.MessagePacker; -import org.msgpack.value.*; +import org.msgpack.value.ImmutableBooleanValue; +import org.msgpack.value.Value; +import org.msgpack.value.ValueType; import java.io.IOException; /** * {@code ImmutableBooleanValueImpl} Implements {@code ImmutableBooleanValue} using a {@code boolean} field. - * + *

* This class is a singleton. {@code ImmutableBooleanValueImpl.trueInstance()} and {@code ImmutableBooleanValueImpl.falseInstance()} are the only instances of this class. * - * @see org.msgpack.value.BooleanValue + * @see org.msgpack.value.BooleanValue */ public class ImmutableBooleanValueImpl extends AbstractImmutableValue implements ImmutableBooleanValue { public static ImmutableBooleanValue TRUE = new ImmutableBooleanValueImpl(true); @@ -58,22 +60,17 @@ public void writeTo(MessagePacker packer) throws IOException { packer.packBoolean(value); } - @Override - public void accept(ValueVisitor visitor) { - visitor.visitBoolean(this); - } - @Override public boolean equals(Object o) { - if (o == this) { + if(o == this) { return true; } - if (!(o instanceof Value)) { + if(!(o instanceof Value)) { return false; } Value v = (Value) o; - if (!v.isBooleanValue()) { + if(!v.isBooleanValue()) { return false; } return value == v.asBooleanValue().getBoolean(); @@ -81,9 +78,10 @@ public boolean equals(Object o) { @Override public int hashCode() { - if (value) { + if(value) { return 1231; - } else { + } + else { return 1237; } } diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableDoubleValueImpl.java b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableDoubleValueImpl.java index 7f71ae23a..04e4bc3a3 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableDoubleValueImpl.java +++ b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableDoubleValueImpl.java @@ -16,17 +16,19 @@ package org.msgpack.value.impl; import org.msgpack.core.MessagePacker; -import org.msgpack.value.*; +import org.msgpack.value.ImmutableFloatValue; +import org.msgpack.value.Value; +import org.msgpack.value.ValueType; +import java.io.IOException; import java.math.BigDecimal; import java.math.BigInteger; -import java.io.IOException; /** * {@code ImmutableDoubleValueImpl} Implements {@code ImmutableFloatValue} using a {@code double} field. * - * @see org.msgpack.value.FloatValue + * @see org.msgpack.value.FloatValue */ public class ImmutableDoubleValueImpl extends AbstractImmutableValue implements ImmutableFloatValue { private final double value; @@ -85,22 +87,17 @@ public void writeTo(MessagePacker pk) throws IOException { pk.packDouble(value); } - @Override - public void accept(ValueVisitor visitor) { - visitor.visitFloat(this); - } - @Override public boolean equals(Object o) { - if (o == this) { + if(o == this) { return true; } - if (!(o instanceof Value)) { + if(!(o instanceof Value)) { return false; } Value v = (Value) o; - if (!v.isFloatValue()) { + if(!v.isFloatValue()) { return false; } return value == v.asFloatValue().toDouble(); diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableExtensionValueImpl.java b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableExtensionValueImpl.java index e698be4c4..fdd22b7f0 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableExtensionValueImpl.java +++ b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableExtensionValueImpl.java @@ -67,11 +67,6 @@ public void writeTo(MessagePacker packer) throws IOException { packer.writePayload(data); } - @Override - public void accept(ValueVisitor visitor) { - visitor.visitExtension(this); - } - @Override public boolean equals(Object o) { if (o == this) { diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableLongValueImpl.java b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableLongValueImpl.java index 5d7c65c75..4858ad7bf 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableLongValueImpl.java +++ b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableLongValueImpl.java @@ -156,11 +156,6 @@ public void writeTo(MessagePacker pk) throws IOException { pk.packLong(value); } - @Override - public void accept(ValueVisitor visitor) { - visitor.visitInteger(this); - } - @Override public boolean equals(Object o) { if (o == this) { diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableMapValueImpl.java b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableMapValueImpl.java index b96f9be50..bb477919e 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableMapValueImpl.java +++ b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableMapValueImpl.java @@ -101,11 +101,6 @@ public void writeTo(MessagePacker pk) throws IOException { } } - @Override - public void accept(ValueVisitor visitor) { - visitor.visitMap(this); - } - @Override public boolean equals(Object o) { if (o == this) { diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableNilValueImpl.java b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableNilValueImpl.java index 0a3ac2c6c..c8f9c3bcc 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableNilValueImpl.java +++ b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableNilValueImpl.java @@ -19,7 +19,6 @@ import org.msgpack.value.Value; import org.msgpack.value.ValueType; import org.msgpack.value.ImmutableNilValue; -import org.msgpack.value.ValueVisitor; import java.io.IOException; @@ -60,11 +59,6 @@ public void writeTo(MessagePacker pk) throws IOException { pk.packNil(); } - @Override - public void accept(ValueVisitor visitor) { - visitor.visitNil(); - } - @Override public boolean equals(Object o) { if (o == this) { diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableStringValueImpl.java b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableStringValueImpl.java index 45c14ace5..59e2cefb1 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableStringValueImpl.java +++ b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableStringValueImpl.java @@ -19,7 +19,6 @@ import org.msgpack.value.Value; import org.msgpack.value.ValueType; import org.msgpack.value.ImmutableStringValue; -import org.msgpack.value.ValueVisitor; import java.util.Arrays; import java.io.IOException; @@ -61,11 +60,6 @@ public void writeTo(MessagePacker pk) throws IOException { pk.writePayload(data); } - @Override - public void accept(ValueVisitor visitor) { - visitor.visitString(this); - } - @Override public boolean equals(Object o) { if (this == o) { diff --git a/msgpack-core/src/test/scala/org/msgpack/core/MessagePackTest.scala b/msgpack-core/src/test/scala/org/msgpack/core/MessagePackTest.scala index e0b03d794..a94bfafc1 100644 --- a/msgpack-core/src/test/scala/org/msgpack/core/MessagePackTest.scala +++ b/msgpack-core/src/test/scala/org/msgpack/core/MessagePackTest.scala @@ -418,13 +418,13 @@ class MessagePackTest extends MessagePackSpec { val l = Math.abs(dataLen) val t = Math.abs(tpe) % 128 whenever(l >= 0) { - val ext = new ExtensionTypeHeader(l, t) + val ext = new ExtensionTypeHeader(ExtensionTypeHeader.checkedCastToByte(l), t) check(ext, _.packExtensionTypeHeader(ext.getType, ext.getLength), _.unpackExtensionTypeHeader()) } } for(l <- testHeaderLength) { - val ext = new ExtensionTypeHeader(l, Random.nextInt(128)) + val ext = new ExtensionTypeHeader(ExtensionTypeHeader.checkedCastToByte(l), Random.nextInt(128)) check(ext, _.packExtensionTypeHeader(ext.getType, ext.getLength), _.unpackExtensionTypeHeader()) } From 787533c93fd925c7965e6af679e9a721b0581f90 Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Mon, 15 Jun 2015 12:30:14 +0900 Subject: [PATCH 080/234] Remove ValueFactory.newArrayOf --- .../src/main/java/org/msgpack/value/ValueFactory.java | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/msgpack-core/src/main/java/org/msgpack/value/ValueFactory.java b/msgpack-core/src/main/java/org/msgpack/value/ValueFactory.java index e6390d5f6..941e4247b 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/ValueFactory.java +++ b/msgpack-core/src/main/java/org/msgpack/value/ValueFactory.java @@ -96,23 +96,17 @@ public static ImmutableArrayValue newArray(List list) { return new ImmutableArrayValueImpl(array); } - public static ImmutableArrayValue newArray(Value[] array) { + public static ImmutableArrayValue newArray(Value... array) { if (array.length == 0) { return ImmutableArrayValueImpl.empty(); } return new ImmutableArrayValueImpl(Arrays.copyOf(array, array.length)); } - public static ImmutableArrayValue newArrayOf(Value... elem) { - return newArray(elem); - } - - public static ImmutableArrayValue emptyArray() { return ImmutableArrayValueImpl.empty(); } - public static ImmutableMapValue newMap(Map map) { Value[] kvs = new Value[map.size() * 2]; From 53557e9cc6957229a23fc3b602b45dd808e143f8 Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Mon, 15 Jun 2015 13:46:31 +0900 Subject: [PATCH 081/234] Removed ValueType.bitMask --- .../java/org/msgpack/core/MessageFormat.java | 2 +- .../java/org/msgpack/value/ValueType.java | 24 ------ .../org/msgpack/value/ValueTypeTest.scala | 73 ++++--------------- 3 files changed, 17 insertions(+), 82 deletions(-) diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessageFormat.java b/msgpack-core/src/main/java/org/msgpack/core/MessageFormat.java index 4e02fced4..b00681244 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/MessageFormat.java +++ b/msgpack-core/src/main/java/org/msgpack/core/MessageFormat.java @@ -95,7 +95,7 @@ public static MessageFormat valueOf(final byte b) { * @return */ @VisibleForTesting - public static MessageFormat toMessageFormat(final byte b) { + static MessageFormat toMessageFormat(final byte b) { if (Code.isPosFixInt(b)) { return POSFIXINT; } diff --git a/msgpack-core/src/main/java/org/msgpack/value/ValueType.java b/msgpack-core/src/main/java/org/msgpack/value/ValueType.java index cda220551..09fcbd51e 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/ValueType.java +++ b/msgpack-core/src/main/java/org/msgpack/value/ValueType.java @@ -34,30 +34,10 @@ public enum ValueType { private final boolean numberType; private final boolean rawType; - private final int bitMask; private ValueType(boolean numberType, boolean rawType) { this.numberType = numberType; this.rawType = rawType; - this.bitMask = 1 << this.ordinal(); - } - - /** - * Returns a bit mask representing this value type for quickly cheking - * this value type - * @return bit mask representing this value type - */ - public int getBitMask() { - return bitMask; - } - - /** - * Check whether the given bit mask represents this value type - * @param bitMask - * @return - */ - public boolean isTypeOf(int bitMask) { - return (this.bitMask & bitMask) != 0; } public boolean isNilType() { @@ -104,10 +84,6 @@ public boolean isExtensionType() { return this == EXTENSION; } - public static ValueType valueOf(byte b) { - return MessageFormat.valueOf(b).getValueType(); - } - public String toTypeName() { return this.name().substring(0, 1) + this.name().substring(1).toLowerCase(); } diff --git a/msgpack-core/src/test/scala/org/msgpack/value/ValueTypeTest.scala b/msgpack-core/src/test/scala/org/msgpack/value/ValueTypeTest.scala index ac3052bc5..99c0ce4d0 100644 --- a/msgpack-core/src/test/scala/org/msgpack/value/ValueTypeTest.scala +++ b/msgpack-core/src/test/scala/org/msgpack/value/ValueTypeTest.scala @@ -13,97 +13,56 @@ class ValueTypeTest extends MessagePackSpec { "ValueType" should { - "lookup ValueType from a byte value" taggedAs("code") in { + "lookup ValueType from a byte value" taggedAs ("code") in { - def check(b:Byte, tpe:ValueType) { - ValueType.valueOf(b) shouldBe tpe + def check(b: Byte, tpe: ValueType) { + MessageFormat.valueOf(b).getValueType shouldBe tpe } - for(i <- 0 until 0x7f) + for (i <- 0 until 0x7f) check(i.toByte, ValueType.INTEGER) - for(i <- 0x80 until 0x8f) + for (i <- 0x80 until 0x8f) check(i.toByte, ValueType.MAP) - for(i <- 0x90 until 0x9f) + for (i <- 0x90 until 0x9f) check(i.toByte, ValueType.ARRAY) check(NIL, ValueType.NIL) try { - ValueType.valueOf(NEVER_USED) + MessageFormat.valueOf(NEVER_USED).getValueType fail("NEVER_USED type should not have ValueType") } catch { - case e:MessageFormatException => - // OK + case e: MessageFormatException => + // OK } check(TRUE, ValueType.BOOLEAN) check(FALSE, ValueType.BOOLEAN) - for(t <- Seq(BIN8, BIN16, BIN32)) + for (t <- Seq(BIN8, BIN16, BIN32)) check(t, ValueType.BINARY) - for(t <- Seq(FIXEXT1, FIXEXT2, FIXEXT4, FIXEXT8, FIXEXT16, EXT8, EXT16, EXT32)) + for (t <- Seq(FIXEXT1, FIXEXT2, FIXEXT4, FIXEXT8, FIXEXT16, EXT8, EXT16, EXT32)) check(t, ValueType.EXTENSION) - for(t <- Seq(INT8, INT16, INT32, INT64, UINT8, UINT16, UINT32, UINT64)) + for (t <- Seq(INT8, INT16, INT32, INT64, UINT8, UINT16, UINT32, UINT64)) check(t, ValueType.INTEGER) - for(t <- Seq(STR8, STR16, STR32)) + for (t <- Seq(STR8, STR16, STR32)) check(t, ValueType.STRING) - for(t <- Seq(FLOAT32, FLOAT64)) + for (t <- Seq(FLOAT32, FLOAT64)) check(t, ValueType.FLOAT) - for(t <- Seq(ARRAY16, ARRAY32)) + for (t <- Seq(ARRAY16, ARRAY32)) check(t, ValueType.ARRAY) - for(i <- 0xe0 until 0xff) + for (i <- 0xe0 until 0xff) check(i.toByte, ValueType.INTEGER) } - - "lookup table" in { - - val N = 100000 - val idx = { - val b = Array.newBuilder[Byte] - for(i <- 0 until N) { - val r = Iterator.continually(Random.nextInt(256)).find(_.toByte != Code.NEVER_USED).get - b += r.toByte - } - b.result() - } - - time("lookup", repeat=100) { - block("switch") { - var i = 0 - while(i < N) { - MessageFormat.toMessageFormat(idx(i)).getValueType() - i += 1 - } - } - - block("table") { - var i = 0 - while(i < N) { - ValueType.valueOf(idx(i)) - i += 1 - } - } - - } - - } - - "support isTypeOf" in { - for(v <- ValueType.values()) { - v.isTypeOf(v.getBitMask) shouldBe true - } - } - - } } From 9e8c806a0f2712d53337db708c3efb2727226f9f Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Mon, 15 Jun 2015 13:47:06 +0900 Subject: [PATCH 082/234] Fix test compile error --- .../src/test/scala/org/msgpack/core/MessagePackerTest.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/msgpack-core/src/test/scala/org/msgpack/core/MessagePackerTest.scala b/msgpack-core/src/test/scala/org/msgpack/core/MessagePackerTest.scala index e0c528731..590936239 100644 --- a/msgpack-core/src/test/scala/org/msgpack/core/MessagePackerTest.scala +++ b/msgpack-core/src/test/scala/org/msgpack/core/MessagePackerTest.scala @@ -129,7 +129,7 @@ class MessagePackerTest extends MessagePackSpec { val msgpack = new MessagePack(new MessagePack.ConfigBuilder().packerBufferSize(bufferSize).build) val str = "a" * stringSize val rawString = ValueFactory.newString(str.getBytes("UTF-8")) - val array = ValueFactory.newArrayOf(rawString) + val array = ValueFactory.newArray(rawString) val out = new ByteArrayOutputStream() val packer = msgpack.newPacker(out) packer.packValue(array) From 33f9ccf1191622985f6449994ed94831ddf6317e Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Mon, 15 Jun 2015 14:41:50 +0900 Subject: [PATCH 083/234] Changed the extension type interface to use byte --- .../java/org/msgpack/core/MessagePacker.java | 20 +++++++++---------- .../core/example/MessagePackExample.java | 2 +- .../dataformat/MessagePackParserTest.java | 4 ++-- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessagePacker.java b/msgpack-core/src/main/java/org/msgpack/core/MessagePacker.java index ec74f53f2..e86bdc4ea 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/MessagePacker.java +++ b/msgpack-core/src/main/java/org/msgpack/core/MessagePacker.java @@ -477,41 +477,41 @@ public MessagePacker packValue(Value v) throws IOException { return this; } - public MessagePacker packExtensionTypeHeader(int extType, int payloadLen) throws IOException { + public MessagePacker packExtensionTypeHeader(byte extType, int payloadLen) throws IOException { if(payloadLen < (1 << 8)) { if(payloadLen > 0 && (payloadLen & (payloadLen - 1)) == 0) { // check whether dataLen == 2^x if(payloadLen == 1) { - writeByteAndByte(FIXEXT1, (byte) extType); + writeByteAndByte(FIXEXT1, extType); } else if(payloadLen == 2) { - writeByteAndByte(FIXEXT2, (byte) extType); + writeByteAndByte(FIXEXT2, extType); } else if(payloadLen == 4) { - writeByteAndByte(FIXEXT4, (byte) extType); + writeByteAndByte(FIXEXT4, extType); } else if(payloadLen == 8) { - writeByteAndByte(FIXEXT8, (byte) extType); + writeByteAndByte(FIXEXT8, extType); } else if(payloadLen == 16) { - writeByteAndByte(FIXEXT16, (byte) extType); + writeByteAndByte(FIXEXT16, extType); } else { writeByteAndByte(EXT8, (byte) payloadLen); - writeByte((byte) extType); + writeByte(extType); } } else { writeByteAndByte(EXT8, (byte) payloadLen); - writeByte((byte) extType); + writeByte(extType); } } else if(payloadLen < (1 << 16)) { writeByteAndShort(EXT16, (short) payloadLen); - writeByte((byte) extType); + writeByte(extType); } else { writeByteAndInt(EXT32, payloadLen); - writeByte((byte) extType); + writeByte(extType); // TODO support dataLen > 2^31 - 1 } diff --git a/msgpack-core/src/main/java/org/msgpack/core/example/MessagePackExample.java b/msgpack-core/src/main/java/org/msgpack/core/example/MessagePackExample.java index beb9e767f..af5b066f6 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/example/MessagePackExample.java +++ b/msgpack-core/src/main/java/org/msgpack/core/example/MessagePackExample.java @@ -125,7 +125,7 @@ public static void packer() throws IOException { // Write ext type data: https://github.com/msgpack/msgpack/blob/master/spec.md#ext-format-family byte[] extData = "custom data type".getBytes(MessagePack.UTF8); - packer.packExtensionTypeHeader(1, 10); // type number [0, 127], data byte length + packer.packExtensionTypeHeader((byte) 1, 10); // type number [0, 127], data byte length packer.writePayload(extData); // Succinct syntax for packing diff --git a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackParserTest.java b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackParserTest.java index c781c9b00..e223c71de 100644 --- a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackParserTest.java +++ b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackParserTest.java @@ -67,7 +67,7 @@ public void testParserShouldReadObject() throws IOException { // #9 byte[] extPayload = {-80, -50, -25, -114, -25, 16, 60, 68}; packer.packString("ext"); - packer.packExtensionTypeHeader(0, extPayload.length); + packer.packExtensionTypeHeader((byte) 0, extPayload.length); packer.writePayload(extPayload); packer.flush(); @@ -191,7 +191,7 @@ public void testParserShouldReadArray() throws IOException { packer.packBoolean(true); // #11 byte[] extPayload = {-80, -50, -25, -114, -25, 16, 60, 68}; - packer.packExtensionTypeHeader(-1, extPayload.length); + packer.packExtensionTypeHeader((byte) -1, extPayload.length); packer.writePayload(extPayload); packer.flush(); From 3df8f36fa5acccca44444c5bdae79629d573d1ba Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Mon, 15 Jun 2015 16:21:43 +0900 Subject: [PATCH 084/234] FloatHolder test is no longer necesary --- .../value/holder/FloatHolderTest.scala | 27 ------------------- 1 file changed, 27 deletions(-) delete mode 100644 msgpack-core/src/test/scala/org/msgpack/value/holder/FloatHolderTest.scala diff --git a/msgpack-core/src/test/scala/org/msgpack/value/holder/FloatHolderTest.scala b/msgpack-core/src/test/scala/org/msgpack/value/holder/FloatHolderTest.scala deleted file mode 100644 index ebbee0e7a..000000000 --- a/msgpack-core/src/test/scala/org/msgpack/value/holder/FloatHolderTest.scala +++ /dev/null @@ -1,27 +0,0 @@ -package org.msgpack.value.holder - -import org.msgpack.core.MessagePackSpec -import org.msgpack.value.Variable - -/** - * - */ -class FloatHolderTest extends MessagePackSpec { - - "FloatHolder" should { - - "display value in an appropriate format" in { - - val h = new Variable - val f = 0.1341f - h.setFloatValue(f) - h.toString shouldBe java.lang.Float.toString(f) - - val d = 0.1341341344 - h.setFloatValue(d) - h.toString shouldBe java.lang.Double.toString(d) - } - - } - -} From 52892896a66984090d23660570d35f08fbd2aa62 Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Mon, 15 Jun 2015 16:24:23 +0900 Subject: [PATCH 085/234] Remove RawValue --- .../org/msgpack/value/RawValueImplTest.scala | 35 ------------------- 1 file changed, 35 deletions(-) delete mode 100644 msgpack-core/src/test/scala/org/msgpack/value/RawValueImplTest.scala diff --git a/msgpack-core/src/test/scala/org/msgpack/value/RawValueImplTest.scala b/msgpack-core/src/test/scala/org/msgpack/value/RawValueImplTest.scala deleted file mode 100644 index 6a798410a..000000000 --- a/msgpack-core/src/test/scala/org/msgpack/value/RawValueImplTest.scala +++ /dev/null @@ -1,35 +0,0 @@ -package org.msgpack.value - -import org.msgpack.core.{MessagePack, MessagePackSpec} -import java.io.ByteArrayOutputStream - - -class RawValueImplTest extends MessagePackSpec { - - "RawValueImple" should { - "toString shouldn't return empty value" in { - val str = "aaa" - def newRawStr() = ValueFactory.newString(str.getBytes("UTF-8")) - - def pack(v: Value): Array[Byte] = { - val out = new ByteArrayOutputStream() - val packer = MessagePack.newDefaultPacker(out) - packer.packValue(v) - packer.close() - out.toByteArray - } - - { - val rawStr = newRawStr() - pack(rawStr) - rawStr.toString() shouldBe str - } - - { - val rawStr = newRawStr() - pack(rawStr) - rawStr.asStringValue().toString shouldBe str - } - } - } -} From 4cba6056e9e5714afa96d19352667714737fb259 Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Mon, 15 Jun 2015 16:32:37 +0900 Subject: [PATCH 086/234] Fix test case that checks nil value --- .../src/test/scala/org/msgpack/core/MessagePackTest.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/msgpack-core/src/test/scala/org/msgpack/core/MessagePackTest.scala b/msgpack-core/src/test/scala/org/msgpack/core/MessagePackTest.scala index a94bfafc1..3014afcf1 100644 --- a/msgpack-core/src/test/scala/org/msgpack/core/MessagePackTest.scala +++ b/msgpack-core/src/test/scala/org/msgpack/core/MessagePackTest.scala @@ -174,7 +174,7 @@ class MessagePackTest extends MessagePackSpec { forAll { (v: Float) => check(v, _.packFloat(v), _.unpackFloat)} forAll { (v: Long) => check(v, _.packLong(v), _.unpackLong)} forAll { (v: Double) => check(v, _.packDouble(v), _.unpackDouble)} - check(null, _.packNil, _.unpackNil()) + check(null, _.packNil, {unpacker => unpacker.unpackNil(); null}) } "pack/unpack integer values" taggedAs("int") in { From c14c87ccba56626d5003f7c03b5786f3d08f4343 Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Mon, 15 Jun 2015 16:36:43 +0900 Subject: [PATCH 087/234] Fix test cases and range check of extension types --- .../main/java/org/msgpack/core/ExtensionTypeHeader.java | 2 +- .../src/test/scala/org/msgpack/core/MessagePackTest.scala | 7 +++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/msgpack-core/src/main/java/org/msgpack/core/ExtensionTypeHeader.java b/msgpack-core/src/main/java/org/msgpack/core/ExtensionTypeHeader.java index a0e27b670..e0403c3ad 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/ExtensionTypeHeader.java +++ b/msgpack-core/src/main/java/org/msgpack/core/ExtensionTypeHeader.java @@ -16,7 +16,7 @@ public ExtensionTypeHeader(byte type, int length) { } public static byte checkedCastToByte(int code) { - checkArgument(code < Byte.MIN_VALUE && code > Byte.MAX_VALUE, "Extension type code must be within the range of byte"); + checkArgument(Byte.MIN_VALUE <= code && code <= Byte.MAX_VALUE, "Extension type code must be within the range of byte"); return (byte) code; } diff --git a/msgpack-core/src/test/scala/org/msgpack/core/MessagePackTest.scala b/msgpack-core/src/test/scala/org/msgpack/core/MessagePackTest.scala index 3014afcf1..1c7996c92 100644 --- a/msgpack-core/src/test/scala/org/msgpack/core/MessagePackTest.scala +++ b/msgpack-core/src/test/scala/org/msgpack/core/MessagePackTest.scala @@ -414,17 +414,16 @@ class MessagePackTest extends MessagePackSpec { } "pack/unpack extension types" taggedAs("ext") in { - forAll { (dataLen: Int, tpe: Int) => + forAll { (dataLen: Int, tpe: Byte) => val l = Math.abs(dataLen) - val t = Math.abs(tpe) % 128 whenever(l >= 0) { - val ext = new ExtensionTypeHeader(ExtensionTypeHeader.checkedCastToByte(l), t) + val ext = new ExtensionTypeHeader(ExtensionTypeHeader.checkedCastToByte(tpe), l) check(ext, _.packExtensionTypeHeader(ext.getType, ext.getLength), _.unpackExtensionTypeHeader()) } } for(l <- testHeaderLength) { - val ext = new ExtensionTypeHeader(ExtensionTypeHeader.checkedCastToByte(l), Random.nextInt(128)) + val ext = new ExtensionTypeHeader(ExtensionTypeHeader.checkedCastToByte(Random.nextInt(128)), l) check(ext, _.packExtensionTypeHeader(ext.getType, ext.getLength), _.unpackExtensionTypeHeader()) } From f6f9e8fefaeb8719a5a64515a21c59afd5f9e2bc Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Mon, 15 Jun 2015 16:51:10 +0900 Subject: [PATCH 088/234] Fixes test case to use getString to extract raw string value --- .../src/test/scala/org/msgpack/core/MessagePackTest.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/msgpack-core/src/test/scala/org/msgpack/core/MessagePackTest.scala b/msgpack-core/src/test/scala/org/msgpack/core/MessagePackTest.scala index 1c7996c92..6c1fbb791 100644 --- a/msgpack-core/src/test/scala/org/msgpack/core/MessagePackTest.scala +++ b/msgpack-core/src/test/scala/org/msgpack/core/MessagePackTest.scala @@ -453,7 +453,7 @@ class MessagePackTest extends MessagePackSpec { val k = kvp(0) val v = kvp(1) - (k.asStringValue().toString, v.asStringValue().toString) + (k.asStringValue().getString, v.asStringValue().getString) }).toMap }.toList }) From e1b81051a7567471fe7700c89e83a38eda1183f7 Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Mon, 15 Jun 2015 17:23:09 +0900 Subject: [PATCH 089/234] Removed obsolete classes --- .../org/msgpack/core/ExtensionTypeHeader.java | 5 ++ .../core/MessageFloatOverflowException.java | 20 ------- .../core/MessageIntegerOverflowException.java | 2 +- .../core/MessageOverflowException.java | 18 ------- .../java/org/msgpack/core/NumberUtil.java | 52 ------------------- .../org/msgpack/core/MessagePackTest.scala | 2 +- 6 files changed, 7 insertions(+), 92 deletions(-) delete mode 100644 msgpack-core/src/main/java/org/msgpack/core/MessageFloatOverflowException.java delete mode 100644 msgpack-core/src/main/java/org/msgpack/core/MessageOverflowException.java delete mode 100644 msgpack-core/src/main/java/org/msgpack/core/NumberUtil.java diff --git a/msgpack-core/src/main/java/org/msgpack/core/ExtensionTypeHeader.java b/msgpack-core/src/main/java/org/msgpack/core/ExtensionTypeHeader.java index e0403c3ad..e4e6b3d4e 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/ExtensionTypeHeader.java +++ b/msgpack-core/src/main/java/org/msgpack/core/ExtensionTypeHeader.java @@ -9,6 +9,11 @@ public class ExtensionTypeHeader { private final byte type; private final int length; + /** + * Create a ExtensionTypeHeader( + * @param type + * @param length + */ public ExtensionTypeHeader(byte type, int length) { checkArgument(length >= 0, "length must be >= 0"); this.type = type; diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessageFloatOverflowException.java b/msgpack-core/src/main/java/org/msgpack/core/MessageFloatOverflowException.java deleted file mode 100644 index 88449e6d5..000000000 --- a/msgpack-core/src/main/java/org/msgpack/core/MessageFloatOverflowException.java +++ /dev/null @@ -1,20 +0,0 @@ -package org.msgpack.core; - -/** - * This error is thrown when the user tries to read a value that has decimal component as byte, short, int and long. - * - */ -public class MessageFloatOverflowException extends MessageOverflowException { - - private final double value; - - public MessageFloatOverflowException(double value) { - super(); - this.value = value; - } - - public double getValue() { - return value; - } - -} diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessageIntegerOverflowException.java b/msgpack-core/src/main/java/org/msgpack/core/MessageIntegerOverflowException.java index 21302803b..28671ae22 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/MessageIntegerOverflowException.java +++ b/msgpack-core/src/main/java/org/msgpack/core/MessageIntegerOverflowException.java @@ -23,7 +23,7 @@ * using a smaller types. For example, calling MessageUnpacker.unpackInt() for an integer value * that is larger than Integer.MAX_VALUE will cause this exception. */ -public class MessageIntegerOverflowException extends MessageOverflowException { +public class MessageIntegerOverflowException extends MessageTypeException { private final BigInteger bigInteger; public MessageIntegerOverflowException(BigInteger bigInteger) { diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessageOverflowException.java b/msgpack-core/src/main/java/org/msgpack/core/MessageOverflowException.java deleted file mode 100644 index ff63ba588..000000000 --- a/msgpack-core/src/main/java/org/msgpack/core/MessageOverflowException.java +++ /dev/null @@ -1,18 +0,0 @@ -package org.msgpack.core; - -/** - * Thrown when converting a message into a type that causes truncation or rounding. - * For example, {@link org.msgpack.value.NumberValue#asInt()} throws this error if - * it is a long value more than {@link java.lang.Integer#MAX_VALUE}. - */ -public class MessageOverflowException extends MessageTypeException { - - public MessageOverflowException() { - super(); - } - - public MessageOverflowException(String message) { - super(message); - } - -} diff --git a/msgpack-core/src/main/java/org/msgpack/core/NumberUtil.java b/msgpack-core/src/main/java/org/msgpack/core/NumberUtil.java deleted file mode 100644 index 578833b43..000000000 --- a/msgpack-core/src/main/java/org/msgpack/core/NumberUtil.java +++ /dev/null @@ -1,52 +0,0 @@ -package org.msgpack.core; - -import java.math.BigInteger; - -/** - * Utilities for numbers - */ -public class NumberUtil { - - private static final BigInteger BI_BYTE_MIN = BigInteger.valueOf(Byte.MIN_VALUE); - private static final BigInteger BI_BYTE_MAX = BigInteger.valueOf(Byte.MAX_VALUE); - private static final BigInteger BI_SHORT_MIN = BigInteger.valueOf(Short.MIN_VALUE); - private static final BigInteger BI_SHORT_MAX = BigInteger.valueOf(Short.MAX_VALUE); - private static final BigInteger BI_INT_MIN = BigInteger.valueOf(Integer.MIN_VALUE); - private static final BigInteger BI_INT_MAX = BigInteger.valueOf(Integer.MAX_VALUE); - private static final BigInteger BI_LONG_MIN = BigInteger.valueOf(Long.MIN_VALUE); - private static final BigInteger BI_LONG_MAX = BigInteger.valueOf(Long.MAX_VALUE); - - public static class LongUtil { - - public static boolean isValidByte(long v) { - return Byte.MIN_VALUE <= v && v <= Byte.MAX_VALUE; - } - - public static boolean isValidByte(BigInteger v) { - return v.compareTo(BI_BYTE_MIN) >= 0 && v.compareTo(BI_BYTE_MAX) <= 0; - } - - public static boolean isValidShort(long v) { - return Short.MIN_VALUE <= v && v <= Short.MAX_VALUE; - } - - public static boolean isValidShort(BigInteger v) { - return v.compareTo(BI_SHORT_MIN) >= 0 && v.compareTo(BI_SHORT_MAX) <= 0; - } - - public static boolean isValidInt(long v) { - return Integer.MIN_VALUE <= v && v <= Integer.MAX_VALUE; - } - public static boolean isValidInt(BigInteger v) { - return v.compareTo(BI_INT_MIN) >= 0 && v.compareTo(BI_INT_MAX) <= 0; - } - - public static boolean isValidLong(BigInteger v) { - return v.compareTo(BI_LONG_MIN) >= 0 && v.compareTo(BI_LONG_MAX) <= 0; - } - } - - - - -} diff --git a/msgpack-core/src/test/scala/org/msgpack/core/MessagePackTest.scala b/msgpack-core/src/test/scala/org/msgpack/core/MessagePackTest.scala index 6c1fbb791..a31bf9625 100644 --- a/msgpack-core/src/test/scala/org/msgpack/core/MessagePackTest.scala +++ b/msgpack-core/src/test/scala/org/msgpack/core/MessagePackTest.scala @@ -407,7 +407,7 @@ class MessagePackTest extends MessagePackSpec { checkException(0, _.packMapHeader(-1), _.unpackMapHeader) } catch { - case e: IllegalArgumentException => // OK + case e: IllegalArgumentExcepNetion => // OK } From 1d1da11194983cd4b875ab8d17d25648c1bbdacb Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Mon, 15 Jun 2015 17:29:54 +0900 Subject: [PATCH 090/234] Moved example codes to test folder --- README.md | 2 +- .../org/msgpack/core/NonBlockingMessageUnpacker.java | 11 ----------- .../org/msgpack/core/example/MessagePackExample.java | 0 .../test/scala/org/msgpack/core/MessagePackTest.scala | 2 +- 4 files changed, 2 insertions(+), 13 deletions(-) delete mode 100644 msgpack-core/src/main/java/org/msgpack/core/NonBlockingMessageUnpacker.java rename msgpack-core/src/{main => test}/java/org/msgpack/core/example/MessagePackExample.java (100%) diff --git a/README.md b/README.md index 73fa29f4d..d0eb8234b 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ For sbt users: libraryDependencies += "org.msgpack" % "msgpack-core" % "0.7.0-p9" ``` -- [Usage examples](msgpack-core/src/main/java/org/msgpack/core/example/MessagePackExample.java) +- [Usage examples](msgpack-core/src/test/java/org/msgpack/core/example/MessagePackExample.java) msgpack-java supports serialization and deserialization of Java objects through [jackson-databind](https://github.com/FasterXML/jackson-databind). For details, see [msgpack-jackson/README.md](msgpack-jackson/README.md). The template-based serialization mechanism used in v06 is deprecated. diff --git a/msgpack-core/src/main/java/org/msgpack/core/NonBlockingMessageUnpacker.java b/msgpack-core/src/main/java/org/msgpack/core/NonBlockingMessageUnpacker.java deleted file mode 100644 index 7ec3122be..000000000 --- a/msgpack-core/src/main/java/org/msgpack/core/NonBlockingMessageUnpacker.java +++ /dev/null @@ -1,11 +0,0 @@ -package org.msgpack.core; - -/** - * MessageUnpacker implementation that supports event-driven I/O, which - * is necessary to implement an efficient RPC server that receives MessagePack data. - */ -public class NonBlockingMessageUnpacker { - - // TODO Impl - -} diff --git a/msgpack-core/src/main/java/org/msgpack/core/example/MessagePackExample.java b/msgpack-core/src/test/java/org/msgpack/core/example/MessagePackExample.java similarity index 100% rename from msgpack-core/src/main/java/org/msgpack/core/example/MessagePackExample.java rename to msgpack-core/src/test/java/org/msgpack/core/example/MessagePackExample.java diff --git a/msgpack-core/src/test/scala/org/msgpack/core/MessagePackTest.scala b/msgpack-core/src/test/scala/org/msgpack/core/MessagePackTest.scala index a31bf9625..6c1fbb791 100644 --- a/msgpack-core/src/test/scala/org/msgpack/core/MessagePackTest.scala +++ b/msgpack-core/src/test/scala/org/msgpack/core/MessagePackTest.scala @@ -407,7 +407,7 @@ class MessagePackTest extends MessagePackSpec { checkException(0, _.packMapHeader(-1), _.unpackMapHeader) } catch { - case e: IllegalArgumentExcepNetion => // OK + case e: IllegalArgumentException => // OK } From 005edf4867f879efe73d99f2b45c229e95aae9ae Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Tue, 16 Jun 2015 12:00:46 +0900 Subject: [PATCH 091/234] Map.Entry based builder. Add putAll methods --- .../java/org/msgpack/value/ValueFactory.java | 36 ++++++++++--------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/msgpack-core/src/main/java/org/msgpack/value/ValueFactory.java b/msgpack-core/src/main/java/org/msgpack/value/ValueFactory.java index 941e4247b..b230b114b 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/ValueFactory.java +++ b/msgpack-core/src/main/java/org/msgpack/value/ValueFactory.java @@ -134,19 +134,9 @@ public static ImmutableMapValue emptyMap() { } - public static class MapEntry { - public final Value key; - public final Value value; - - public MapEntry(Value key, Value value) { - this.key = key; - this.value = value; - } - } - - public static MapValue newMap(MapEntry... pairs) { + public static MapValue newMap(Map.Entry... pairs) { MapBuilder b = new MapBuilder(); - for(MapEntry p : pairs) { + for(Map.Entry p : pairs) { b.put(p); } return b.build(); @@ -157,26 +147,38 @@ public static MapBuilder newMapBuilder() { return new MapBuilder(); } - public static MapEntry newMapEntry(Value key, Value value) { - return new MapEntry(key, value); + public static Map.Entry newMapEntry(Value key, Value value) { + return new AbstractMap.SimpleEntry(key, value); } public static class MapBuilder { - private Map map = new HashMap(); + private final Map map = new HashMap(); public MapBuilder() {} public MapValue build() { return newMap(map); } - public void put(MapEntry pair) { - put(pair.key, pair.value); + public void put(Map.Entry pair) { + put(pair.getKey(), pair.getValue()); } public void put(Value key, Value value) { map.put(key, value); } + + public void putAll(Iterable> entries){ + for(Map.Entry entry : entries) { + put(entry.getKey(), entry.getValue()); + } + } + + public void putAll(Map map) { + for(Map.Entry entry : map.entrySet()) { + put(entry); + } + } } public static ImmutableExtensionValue newExtension(byte type, byte[] data) { From bef3c55f0f17671dceb3c57213997479da9ea55e Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Tue, 16 Jun 2015 16:52:11 +0900 Subject: [PATCH 092/234] nil() -> newNil() for method name consisitency --- .../main/java/org/msgpack/core/MessageUnpacker.java | 2 +- .../src/main/java/org/msgpack/value/ValueFactory.java | 2 +- .../src/main/java/org/msgpack/value/Variable.java | 4 ++-- .../scala/org/msgpack/value/ValueFactoryTest.scala | 2 +- .../msgpack/jackson/dataformat/MessagePackParser.java | 10 +++++----- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java b/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java index ed6bd2a4a..4ea0949b9 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java +++ b/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java @@ -540,7 +540,7 @@ public ImmutableValue unpackValue() throws IOException { switch(mf.getValueType()) { case NIL: unpackNil(); - return ValueFactory.nil(); + return ValueFactory.newNil(); case BOOLEAN: return ValueFactory.newBoolean(unpackBoolean()); case INTEGER: diff --git a/msgpack-core/src/main/java/org/msgpack/value/ValueFactory.java b/msgpack-core/src/main/java/org/msgpack/value/ValueFactory.java index b230b114b..d8addcebc 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/ValueFactory.java +++ b/msgpack-core/src/main/java/org/msgpack/value/ValueFactory.java @@ -32,7 +32,7 @@ public final class ValueFactory { private ValueFactory() { } - public static ImmutableNilValue nil() { + public static ImmutableNilValue newNil() { return ImmutableNilValueImpl.get(); } diff --git a/msgpack-core/src/main/java/org/msgpack/value/Variable.java b/msgpack-core/src/main/java/org/msgpack/value/Variable.java index 1856d605f..701ca51eb 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/Variable.java +++ b/msgpack-core/src/main/java/org/msgpack/value/Variable.java @@ -232,7 +232,7 @@ public NilValue asNilValue() { @Override public ImmutableNilValue immutableValue() { - return ValueFactory.nil(); + return ValueFactory.newNil(); } @Override @@ -704,7 +704,7 @@ public Value get(int index) { public Value getOrNilValue(int index) { List l = list(); if (l.size() < index && index >= 0) { - return ValueFactory.nil(); + return ValueFactory.newNil(); } return l.get(index); } diff --git a/msgpack-core/src/test/scala/org/msgpack/value/ValueFactoryTest.scala b/msgpack-core/src/test/scala/org/msgpack/value/ValueFactoryTest.scala index 51ac4704e..91552e217 100644 --- a/msgpack-core/src/test/scala/org/msgpack/value/ValueFactoryTest.scala +++ b/msgpack-core/src/test/scala/org/msgpack/value/ValueFactoryTest.scala @@ -37,7 +37,7 @@ class ValueFactoryTest extends MessagePackSpec { "ValueFactory" should { "create valid type values" in { - isValid(ValueFactory.nil(), expected=ValueType.NIL, isNil = true) + isValid(ValueFactory.newNil(), expected=ValueType.NIL, isNil = true) forAll{(v:Boolean) => isValid(ValueFactory.newBoolean(v), expected=ValueType.BOOLEAN, isBoolean = true)} forAll{(v:Int) => isValid(ValueFactory.newInteger(v), expected=ValueType.INTEGER, isInteger = true, isNumber = true)} forAll{(v:Float) => isValid(ValueFactory.newFloat(v), expected=ValueType.FLOAT, isFloat = true, isNumber = true)} diff --git a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java index 5c1d308dc..4605eb69c 100644 --- a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java +++ b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java @@ -29,7 +29,7 @@ public class MessagePackParser extends ParserMinimalBase { private JsonReadContext parsingContext; private final LinkedList stack = new LinkedList(); - private Value value = ValueFactory.nil(); + private Value value = ValueFactory.newNil(); private Variable var = new Variable(); private boolean isClosed; private long tokenPosition; @@ -141,12 +141,12 @@ public JsonToken nextToken() throws IOException, JsonParseException { switch (type) { case NIL: messageUnpacker.unpackNil(); - value = ValueFactory.nil(); + value = ValueFactory.newNil(); nextToken = JsonToken.VALUE_NULL; break; case BOOLEAN: boolean b = messageUnpacker.unpackBoolean(); - value = ValueFactory.nil(); + value = ValueFactory.newNil(); nextToken = b ? JsonToken.VALUE_TRUE : JsonToken.VALUE_FALSE; break; case INTEGER: @@ -178,11 +178,11 @@ public JsonToken nextToken() throws IOException, JsonParseException { } break; case ARRAY: - value = ValueFactory.nil(); + value = ValueFactory.newNil(); newStack = new StackItemForArray(messageUnpacker.unpackArrayHeader()); break; case MAP: - value = ValueFactory.nil(); + value = ValueFactory.newNil(); newStack = new StackItemForObject(messageUnpacker.unpackMapHeader()); break; case EXTENSION: From ca2fb1e0d5f96ea7b34419408e9f1fb45b7ae421 Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Tue, 16 Jun 2015 16:53:32 +0900 Subject: [PATCH 093/234] Add comment to ExtensionTypeHeader --- .../src/main/java/org/msgpack/core/ExtensionTypeHeader.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/msgpack-core/src/main/java/org/msgpack/core/ExtensionTypeHeader.java b/msgpack-core/src/main/java/org/msgpack/core/ExtensionTypeHeader.java index e4e6b3d4e..848925a00 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/ExtensionTypeHeader.java +++ b/msgpack-core/src/main/java/org/msgpack/core/ExtensionTypeHeader.java @@ -10,9 +10,9 @@ public class ExtensionTypeHeader { private final int length; /** - * Create a ExtensionTypeHeader( - * @param type - * @param length + * Create an extension type header + * @param type extension type (byte). You can check the valid byte range with {@link #checkedCastToByte(int)} method. + * @param length extension type data length */ public ExtensionTypeHeader(byte type, int length) { checkArgument(length >= 0, "length must be >= 0"); From a96075f6d3e413d218bc58f1b2f4ceb7d86c631e Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Thu, 18 Jun 2015 16:21:58 +0900 Subject: [PATCH 094/234] Add sbt-jcheckstyle code style checker --- README.md | 1 + project/plugins.sbt | 2 ++ 2 files changed, 3 insertions(+) diff --git a/README.md b/README.md index 4cc7ee4f6..38afc29ff 100644 --- a/README.md +++ b/README.md @@ -55,6 +55,7 @@ Here is a list of sbt commands for daily development: > package # Create a jar file in the target folder of each project > findbugs # Produce findbugs report in target/findbugs > jacoco:cover # Report the code coverage of tests to target/jacoco folder +> jcheckStyle # Run check style ``` ### Publishing diff --git a/project/plugins.sbt b/project/plugins.sbt index 3c5b99d03..0d70c54a7 100755 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -9,4 +9,6 @@ addSbtPlugin("de.johoop" % "findbugs4sbt" % "1.3.0") addSbtPlugin("de.johoop" % "jacoco4sbt" % "2.1.6") +addSbtPlugin("org.xerial.sbt" % "sbt-jcheckstyle" % "0.1.2") + scalacOptions ++= Seq("-deprecation", "-feature") From 5ba7366f1ef6f7d1733a546c2f9f1e837dd69ac6 Mon Sep 17 00:00:00 2001 From: Mitsunori Komatsu Date: Thu, 18 Jun 2015 23:13:11 +0900 Subject: [PATCH 095/234] Fix unit test errors --- .../main/java/org/msgpack/value/Variable.java | 2 + .../dataformat/MessagePackExtensionType.java | 25 -------- .../jackson/dataformat/MessagePackParser.java | 7 ++- .../MessagePackExtensionTypeTest.java | 60 ------------------- .../dataformat/MessagePackParserTest.java | 14 +++-- 5 files changed, 16 insertions(+), 92 deletions(-) delete mode 100644 msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackExtensionType.java delete mode 100644 msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackExtensionTypeTest.java diff --git a/msgpack-core/src/main/java/org/msgpack/value/Variable.java b/msgpack-core/src/main/java/org/msgpack/value/Variable.java index 701ca51eb..b30a0383d 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/Variable.java +++ b/msgpack-core/src/main/java/org/msgpack/value/Variable.java @@ -383,9 +383,11 @@ public Variable setIntegerValue(long v) { public Variable setIntegerValue(BigInteger v) { if (0 <= v.compareTo(LONG_MIN) && v.compareTo(LONG_MAX) <= 0) { this.type = Type.LONG; + this.accessor = integerAccessor; this.longValue = v.longValue(); } else { this.type = Type.BIG_INTEGER; + this.accessor = integerAccessor; this.objectValue = v; } return this; diff --git a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackExtensionType.java b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackExtensionType.java deleted file mode 100644 index 1218808e7..000000000 --- a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackExtensionType.java +++ /dev/null @@ -1,25 +0,0 @@ -package org.msgpack.jackson.dataformat; - - import java.nio.ByteBuffer; - -/** - * Created by komamitsu on 3/7/15. - */ -public class MessagePackExtensionType { - private final int extType; - private final ByteBuffer byteBuffer; - - public MessagePackExtensionType(int extType, ByteBuffer byteBuffer) { - this.extType = extType; - this.byteBuffer = byteBuffer.isReadOnly() ? - byteBuffer : byteBuffer.asReadOnlyBuffer(); - } - - public int extType() { - return extType; - } - - public ByteBuffer byteBuffer() { - return byteBuffer; - } -} diff --git a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java index 4605eb69c..4c7184eb8 100644 --- a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java +++ b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java @@ -220,7 +220,12 @@ protected void _handleEOF() throws JsonParseException {} @Override public String getText() throws IOException, JsonParseException { // This method can be called for new BigInteger(text) - return value.asRawValue().stringValue(); + if (value.isRawValue()) { + return value.asRawValue().stringValue(); + } + else { + return value.toString(); + } } @Override diff --git a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackExtensionTypeTest.java b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackExtensionTypeTest.java deleted file mode 100644 index 1356638f1..000000000 --- a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackExtensionTypeTest.java +++ /dev/null @@ -1,60 +0,0 @@ -package org.msgpack.jackson.dataformat; - -import org.junit.Test; - -import java.nio.ByteBuffer; - -import static org.junit.Assert.*; - -public class MessagePackExtensionTypeTest { - private void assertExtensionType(MessagePackExtensionType x, - int expectedExtType, ByteBuffer expectedByteBuffer) { - assertEquals(expectedExtType, x.extType()); - assertEquals(expectedByteBuffer, x.byteBuffer()); - assertTrue(x.byteBuffer().isReadOnly()); - } - - @Test - public void testMessagePackextensionType() { - byte[] bs = new byte[] {0x00, (byte) 0xCC, (byte) 0xFF}; - ByteBuffer expectedByteBuffer = ByteBuffer.wrap(bs); - - int extType = 1; - MessagePackExtensionType extensionType = - new MessagePackExtensionType(extType, ByteBuffer.wrap(bs)); - assertExtensionType(extensionType, extType, expectedByteBuffer); - - extType = 2; - ByteBuffer bb = ByteBuffer.allocate(3); - bb.put(bs); - bb.position(0); - extensionType = new MessagePackExtensionType(extType, bb); - assertExtensionType(extensionType, extType, expectedByteBuffer); - - extType = 3; - bb = ByteBuffer.allocateDirect(3); - bb.put(bs); - bb.position(0); - extensionType = new MessagePackExtensionType(extType, bb); - assertExtensionType(extensionType, extType, expectedByteBuffer); - - extType = -1; - extensionType = - new MessagePackExtensionType(extType, ByteBuffer.wrap(bs).asReadOnlyBuffer()); - assertExtensionType(extensionType, extType, expectedByteBuffer); - - extType = -2; - bb = ByteBuffer.allocate(3); - bb.put(bs); - bb.position(0); - extensionType = new MessagePackExtensionType(extType, bb.asReadOnlyBuffer()); - assertExtensionType(extensionType, extType, expectedByteBuffer); - - extType = -3; - bb = ByteBuffer.allocateDirect(3); - bb.put(bs); - bb.position(0); - extensionType = new MessagePackExtensionType(extType, bb.asReadOnlyBuffer()); - assertExtensionType(extensionType, extType, expectedByteBuffer); - } -} \ No newline at end of file diff --git a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackParserTest.java b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackParserTest.java index e223c71de..74de2ba7b 100644 --- a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackParserTest.java +++ b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackParserTest.java @@ -9,6 +9,7 @@ import org.msgpack.core.MessagePack; import org.msgpack.core.MessagePacker; import org.msgpack.core.buffer.OutputStreamBufferOutput; +import org.msgpack.value.ExtensionValue; import java.io.*; import java.math.BigDecimal; @@ -19,6 +20,7 @@ import java.util.List; import java.util.Map; +import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertNull; @@ -142,9 +144,9 @@ else if (k.equals("bool")) { else if (k.equals("ext")) { // #9 bitmap |= 1 << 10; - MessagePackExtensionType extensionType = (MessagePackExtensionType) v; - assertEquals(0, extensionType.extType()); - assertEquals(ByteBuffer.wrap(extPayload), extensionType.byteBuffer()); + ExtensionValue extensionValue = (ExtensionValue) v; + assertEquals(0, extensionValue.getType()); + assertArrayEquals(extPayload, extensionValue.getData()); } } assertEquals(0x7FF, bitmap); @@ -249,9 +251,9 @@ else if (k.equals("child_map_age")) { // #10 assertEquals(true, array.get(i++)); // #11 - MessagePackExtensionType extensionType = (MessagePackExtensionType) array.get(i++); - assertEquals(-1, extensionType.extType()); - assertEquals(ByteBuffer.wrap(extPayload), extensionType.byteBuffer()); + ExtensionValue extensionValue = (ExtensionValue) array.get(i++); + assertEquals(-1, extensionValue.getType()); + assertArrayEquals(extPayload, extensionValue.getData()); } @Test From b7787d4f01e1b0762728ffd2c39cdba12028022e Mon Sep 17 00:00:00 2001 From: Sadayuki Furuhashi Date: Mon, 22 Jun 2015 18:44:37 -0700 Subject: [PATCH 096/234] removed unnecessary empty lines --- .../src/main/java/org/msgpack/value/ValueFactory.java | 4 +--- msgpack-core/src/main/java/org/msgpack/value/Variable.java | 2 -- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/msgpack-core/src/main/java/org/msgpack/value/ValueFactory.java b/msgpack-core/src/main/java/org/msgpack/value/ValueFactory.java index d8addcebc..8842b6cf4 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/ValueFactory.java +++ b/msgpack-core/src/main/java/org/msgpack/value/ValueFactory.java @@ -133,7 +133,6 @@ public static ImmutableMapValue emptyMap() { return ImmutableMapValueImpl.empty(); } - public static MapValue newMap(Map.Entry... pairs) { MapBuilder b = new MapBuilder(); for(Map.Entry p : pairs) { @@ -142,18 +141,17 @@ public static MapValue newMap(Map.Entry... pai return b.build(); } - public static MapBuilder newMapBuilder() { return new MapBuilder(); } public static Map.Entry newMapEntry(Value key, Value value) { return new AbstractMap.SimpleEntry(key, value); - } public static class MapBuilder { private final Map map = new HashMap(); + public MapBuilder() {} public MapValue build() { diff --git a/msgpack-core/src/main/java/org/msgpack/value/Variable.java b/msgpack-core/src/main/java/org/msgpack/value/Variable.java index b30a0383d..ee17af327 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/Variable.java +++ b/msgpack-core/src/main/java/org/msgpack/value/Variable.java @@ -535,7 +535,6 @@ public ValueType getValueType() { public void writeTo(MessagePacker pk) throws IOException { pk.packDouble(doubleValue); } - } @@ -621,7 +620,6 @@ public void writeTo(MessagePacker pk) throws IOException { pk.packBinaryHeader(data.length); pk.writePayload(data); } - } From 27be4d94eeaeb1954c15cad92fa7c53adbf44b06 Mon Sep 17 00:00:00 2001 From: Sadayuki Furuhashi Date: Mon, 22 Jun 2015 18:45:02 -0700 Subject: [PATCH 097/234] removed unused ValueType.toTypeName() --- msgpack-core/src/main/java/org/msgpack/value/ValueType.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/msgpack-core/src/main/java/org/msgpack/value/ValueType.java b/msgpack-core/src/main/java/org/msgpack/value/ValueType.java index 09fcbd51e..c04916635 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/ValueType.java +++ b/msgpack-core/src/main/java/org/msgpack/value/ValueType.java @@ -83,8 +83,4 @@ public boolean isMapType() { public boolean isExtensionType() { return this == EXTENSION; } - - public String toTypeName() { - return this.name().substring(0, 1) + this.name().substring(1).toLowerCase(); - } } From 321d64bfc85cf8821bd699d855fe8225d9193385 Mon Sep 17 00:00:00 2001 From: Sadayuki Furuhashi Date: Mon, 22 Jun 2015 18:45:20 -0700 Subject: [PATCH 098/234] added example javadoc on ExtensionTypeHeader constructor --- .../java/org/msgpack/core/ExtensionTypeHeader.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/msgpack-core/src/main/java/org/msgpack/core/ExtensionTypeHeader.java b/msgpack-core/src/main/java/org/msgpack/core/ExtensionTypeHeader.java index 848925a00..6d6812fe4 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/ExtensionTypeHeader.java +++ b/msgpack-core/src/main/java/org/msgpack/core/ExtensionTypeHeader.java @@ -11,6 +11,16 @@ public class ExtensionTypeHeader { /** * Create an extension type header + * Example: + *

+     * {@code
+     * import org.msgpack.core.ExtensionTypeHeader;
+     * import static org.msgpack.core.ExtensionTypeHeader.checkedCastToByte;
+     * ...
+     * ExtensionTypeHeader header = new ExtensionTypeHeader(checkedCastToByte(0x01), 32);
+     * ...
+     * }
+     * 
* @param type extension type (byte). You can check the valid byte range with {@link #checkedCastToByte(int)} method. * @param length extension type data length */ From 5c51b39d00ae234aca3eeb9bc348add49efa8969 Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Tue, 23 Jun 2015 14:40:25 +0900 Subject: [PATCH 099/234] toXXX -> castAsXXX --- .../java/org/msgpack/value/NumberValue.java | 32 ++++++++++--------- .../main/java/org/msgpack/value/Variable.java | 18 +++++------ .../impl/ImmutableBigIntegerValueImpl.java | 16 +++++----- .../value/impl/ImmutableDoubleValueImpl.java | 16 +++++----- .../value/impl/ImmutableLongValueImpl.java | 16 +++++----- .../core/example/MessagePackExample.java | 10 +++--- .../jackson/dataformat/MessagePackParser.java | 24 +++++++------- 7 files changed, 67 insertions(+), 65 deletions(-) diff --git a/msgpack-core/src/main/java/org/msgpack/value/NumberValue.java b/msgpack-core/src/main/java/org/msgpack/value/NumberValue.java index 5b6e976e1..785d12581 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/NumberValue.java +++ b/msgpack-core/src/main/java/org/msgpack/value/NumberValue.java @@ -18,7 +18,7 @@ import java.math.BigInteger; /** - * The interface {@code NumberValue} is the interface of {@code IntegerValue} and {@code FloatValue}. + * The base interface {@code NumberValue} of {@code IntegerValue} and {@code FloatValue}. * * @see org.msgpack.value.IntegerValue * @see org.msgpack.value.FloatValue @@ -26,37 +26,39 @@ public interface NumberValue extends Value { /** - * Convert this value into a byte value. If this value is not within the range of Byte value, it will truncate or round the value. + * Represent this value as a byte value, which may involve rounding or truncation of the original value. + * the value. */ - byte toByte(); + byte castAsByte(); /** - * Convert this value into a short value. If this value is not within the range of Short value, it will truncate or round the value. + * Represent this value as a short value, which may involve rounding or truncation of the original value. */ - short toShort(); + short castAsShort(); /** - * Convert this value into an int value. If this value is not within the range of Int value, it will truncate or round the value. + * Represent this value as an int value, which may involve rounding or truncation of the original value. + * value. */ - int toInt(); + int castAsInt(); /** - * Convert this value into a long value. If this value is not within the range of Long value, it will truncate or round the value. + * Represent this value as a long value, which may involve rounding or truncation of the original value. */ - long toLong(); + long castAsLong(); /** - * Convert this value into a BigInteger. If value is Float type, it will round the value + * Represent this value as a BigInteger, which may involve rounding or truncation of the original value. */ - BigInteger toBigInteger(); + BigInteger castAsBigInteger(); /** - * Converts this value into a 32-bit float + * Represent this value as a 32-bit float value, which may involve rounding or truncation of the original value. */ - float toFloat(); + float castAsFloat(); /** - * Converts this value into a 64-bit double + * Represent this value as a 64-bit double value, which may involve rounding or truncation of the original value. */ - double toDouble(); + double castAsDouble(); } diff --git a/msgpack-core/src/main/java/org/msgpack/value/Variable.java b/msgpack-core/src/main/java/org/msgpack/value/Variable.java index ee17af327..227626ea8 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/Variable.java +++ b/msgpack-core/src/main/java/org/msgpack/value/Variable.java @@ -303,7 +303,7 @@ public NumberValue asNumberValue() { } @Override - public byte toByte() { + public byte castAsByte() { if (type == Type.BIG_INTEGER) { return ((BigInteger) objectValue).byteValue(); } @@ -311,7 +311,7 @@ public byte toByte() { } @Override - public short toShort() { + public short castAsShort() { if (type == Type.BIG_INTEGER) { return ((BigInteger) objectValue).shortValue(); } @@ -319,7 +319,7 @@ public short toShort() { } @Override - public int toInt() { + public int castAsInt() { if (type == Type.BIG_INTEGER) { return ((BigInteger) objectValue).intValue(); } @@ -327,7 +327,7 @@ public int toInt() { } @Override - public long toLong() { + public long castAsLong() { if (type == Type.BIG_INTEGER) { return ((BigInteger) objectValue).longValue(); } @@ -335,7 +335,7 @@ public long toLong() { } @Override - public BigInteger toBigInteger() { + public BigInteger castAsBigInteger() { if (type == Type.BIG_INTEGER) { return (BigInteger) objectValue; } @@ -346,7 +346,7 @@ else if (type == Type.DOUBLE) { } @Override - public float toFloat() { + public float castAsFloat() { if (type == Type.BIG_INTEGER) { return ((BigInteger) objectValue).floatValue(); } @@ -357,7 +357,7 @@ else if (type == Type.DOUBLE) { } @Override - public double toDouble() { + public double castAsDouble() { if (type == Type.BIG_INTEGER) { return ((BigInteger) objectValue).doubleValue(); } @@ -504,14 +504,14 @@ public Variable setFloatValue(double v) { this.type = Type.DOUBLE; this.accessor = floatAccessor; this.doubleValue = v; - this.longValue = (long) v; // AbstractNumberValueAccessor uses toLong + this.longValue = (long) v; // AbstractNumberValueAccessor uses castAsLong return this; } public Variable setFloatValue(float v) { this.type = Type.DOUBLE; this.accessor = floatAccessor; - this.longValue = (long) v; // AbstractNumberValueAccessor uses toLong + this.longValue = (long) v; // AbstractNumberValueAccessor uses castAsLong return this; } diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableBigIntegerValueImpl.java b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableBigIntegerValueImpl.java index 2bbd9a8bd..1e5ac8759 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableBigIntegerValueImpl.java +++ b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableBigIntegerValueImpl.java @@ -65,37 +65,37 @@ public ImmutableIntegerValue asIntegerValue() { } @Override - public byte toByte() { + public byte castAsByte() { return value.byteValue(); } @Override - public short toShort() { + public short castAsShort() { return value.shortValue(); } @Override - public int toInt() { + public int castAsInt() { return value.intValue(); } @Override - public long toLong() { + public long castAsLong() { return value.longValue(); } @Override - public BigInteger toBigInteger() { + public BigInteger castAsBigInteger() { return value; } @Override - public float toFloat() { + public float castAsFloat() { return value.floatValue(); } @Override - public double toDouble() { + public double castAsDouble() { return value.doubleValue(); } @@ -175,7 +175,7 @@ public boolean equals(Object o) { return false; } IntegerValue iv = v.asIntegerValue(); - return value.equals(iv.toBigInteger()); + return value.equals(iv.castAsBigInteger()); } @Override diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableDoubleValueImpl.java b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableDoubleValueImpl.java index 04e4bc3a3..db7a262b4 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableDoubleValueImpl.java +++ b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableDoubleValueImpl.java @@ -48,37 +48,37 @@ public ImmutableDoubleValueImpl immutableValue() { } @Override - public byte toByte() { + public byte castAsByte() { return (byte) value; } @Override - public short toShort() { + public short castAsShort() { return (short) value; } @Override - public int toInt() { + public int castAsInt() { return (int) value; } @Override - public long toLong() { + public long castAsLong() { return (long) value; } @Override - public BigInteger toBigInteger() { + public BigInteger castAsBigInteger() { return new BigDecimal(value).toBigInteger(); } @Override - public float toFloat() { + public float castAsFloat() { return (float) value; } @Override - public double toDouble() { + public double castAsDouble() { return value; } @@ -100,7 +100,7 @@ public boolean equals(Object o) { if(!v.isFloatValue()) { return false; } - return value == v.asFloatValue().toDouble(); + return value == v.asFloatValue().castAsDouble(); } @Override diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableLongValueImpl.java b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableLongValueImpl.java index 4858ad7bf..adad02764 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableLongValueImpl.java +++ b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableLongValueImpl.java @@ -63,37 +63,37 @@ public ImmutableIntegerValue asIntegerValue() { } @Override - public byte toByte() { + public byte castAsByte() { return (byte) value; } @Override - public short toShort() { + public short castAsShort() { return (short) value; } @Override - public int toInt() { + public int castAsInt() { return (int) value; } @Override - public long toLong() { + public long castAsLong() { return value; } @Override - public BigInteger toBigInteger() { + public BigInteger castAsBigInteger() { return BigInteger.valueOf(value); } @Override - public float toFloat() { + public float castAsFloat() { return (float) value; } @Override - public double toDouble() { + public double castAsDouble() { return (double) value; } @@ -173,7 +173,7 @@ public boolean equals(Object o) { if (!iv.isInLongRange()) { return false; } - return value == iv.toLong(); + return value == iv.castAsLong(); } @Override diff --git a/msgpack-core/src/test/java/org/msgpack/core/example/MessagePackExample.java b/msgpack-core/src/test/java/org/msgpack/core/example/MessagePackExample.java index af5b066f6..8e29c5255 100644 --- a/msgpack-core/src/test/java/org/msgpack/core/example/MessagePackExample.java +++ b/msgpack-core/src/test/java/org/msgpack/core/example/MessagePackExample.java @@ -184,22 +184,22 @@ public static void readAndWriteFile() throws IOException { case INTEGER: IntegerValue iv = v.asIntegerValue(); if(iv.isInIntRange()) { - int i = iv.toInt(); + int i = iv.castAsInt(); System.out.println("read int: " + i); } else if (iv.isInLongRange()) { - long l = iv.toLong(); + long l = iv.castAsLong(); System.out.println("read long: " + l); } else { - BigInteger i = iv.toBigInteger(); + BigInteger i = iv.castAsBigInteger(); System.out.println("read long: " + i); } break; case FLOAT: FloatValue fv = v.asFloatValue(); - float f = fv.toFloat(); // use as float - double d = fv.toDouble(); // use as double + float f = fv.castAsFloat(); // use as float + double d = fv.castAsDouble(); // use as double System.out.println("read float: " + d); break; case STRING: diff --git a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java index 4c7184eb8..1ae4597da 100644 --- a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java +++ b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java @@ -258,42 +258,42 @@ public Number getNumberValue() throws IOException, JsonParseException { if (value.isIntegerValue()) { IntegerValue integerValue = value.asIntegerValue(); if (integerValue.isInIntRange()) { - return integerValue.toInt(); + return integerValue.castAsInt(); } else if (integerValue.isInLongRange()) { - return integerValue.toLong(); + return integerValue.castAsLong(); } else { - return integerValue.toBigInteger(); + return integerValue.castAsBigInteger(); } } else { - return value.asNumberValue().toDouble(); + return value.asNumberValue().castAsDouble(); } } @Override public int getIntValue() throws IOException, JsonParseException { - return value.asNumberValue().toInt(); + return value.asNumberValue().castAsInt(); } @Override public long getLongValue() throws IOException, JsonParseException { - return value.asNumberValue().toLong(); + return value.asNumberValue().castAsLong(); } @Override public BigInteger getBigIntegerValue() throws IOException, JsonParseException { - return value.asNumberValue().toBigInteger(); + return value.asNumberValue().castAsBigInteger(); } @Override public float getFloatValue() throws IOException, JsonParseException { - return value.asNumberValue().toFloat(); + return value.asNumberValue().castAsFloat(); } @Override public double getDoubleValue() throws IOException, JsonParseException { - return value.asNumberValue().toDouble(); + return value.asNumberValue().castAsDouble(); } @Override @@ -302,14 +302,14 @@ public BigDecimal getDecimalValue() throws IOException { IntegerValue number = value.asIntegerValue(); //optimization to not convert the value to BigInteger unnecessarily if (number.isInLongRange()) { - return BigDecimal.valueOf(number.toLong()); + return BigDecimal.valueOf(number.castAsLong()); } else { - return new BigDecimal(number.toBigInteger()); + return new BigDecimal(number.castAsBigInteger()); } } else if (value.isFloatValue()) { - return BigDecimal.valueOf(value.asFloatValue().toDouble()); + return BigDecimal.valueOf(value.asFloatValue().castAsDouble()); } else { throw new UnsupportedOperationException("Couldn't parse value as BigDecimal. " + value); From 75df52669758aa187db9e0755379daca0afcc48e Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Tue, 23 Jun 2015 16:06:02 +0900 Subject: [PATCH 100/234] Add universal buffer test instead of using jdk6 --- .travis.yml | 7 +++---- .../scala/org/msgpack/core/buffer/MessageBufferTest.scala | 5 +++++ sonatype.sbt | 2 +- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index 4c1703220..e30cdb222 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,9 +1,6 @@ language: scala -scala: - - 2.11.1 jdk: - - openjdk6 - openjdk7 - oraclejdk7 - oraclejdk8 @@ -12,4 +9,6 @@ branches: only: - /^v07.*$/ -script: sbt ++$TRAVIS_SCALA_VERSION test +script: + - sbt test + - sbt test -J-Dmsgpack.universal-buffer=true diff --git a/msgpack-core/src/test/scala/org/msgpack/core/buffer/MessageBufferTest.scala b/msgpack-core/src/test/scala/org/msgpack/core/buffer/MessageBufferTest.scala index 6652079db..32432bdef 100644 --- a/msgpack-core/src/test/scala/org/msgpack/core/buffer/MessageBufferTest.scala +++ b/msgpack-core/src/test/scala/org/msgpack/core/buffer/MessageBufferTest.scala @@ -11,6 +11,11 @@ class MessageBufferTest extends MessagePackSpec { "MessageBuffer" should { + "check buffer type" in { + val b = MessageBuffer.newBuffer(0) + info(s"MessageBuffer type: ${b.getClass.getName}") + } + "wrap ByteBuffer considering position and remaining values" taggedAs("wrap-bb") in { val d = Array[Byte](10,11,12,13,14,15,16,17,18,19) val subset = ByteBuffer.wrap(d, 2, 2) diff --git a/sonatype.sbt b/sonatype.sbt index 11ac985c2..b94a33d4c 100644 --- a/sonatype.sbt +++ b/sonatype.sbt @@ -1,6 +1,6 @@ sonatypeProfileName := "org.msgpack" -pomExtra := { +pomExtra in Global := { http://msgpack.org/ From 9f4e258237f205729781a57fe8ff1894055af3a2 Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Tue, 23 Jun 2015 17:22:45 +0900 Subject: [PATCH 101/234] Fix codestyle with sbt-jcheckstyle --- .../org/msgpack/core/ExtensionTypeHeader.java | 30 +- .../java/org/msgpack/core/MessageFormat.java | 33 +- .../msgpack/core/MessageFormatException.java | 15 +- .../core/MessageIntegerOverflowException.java | 20 +- .../java/org/msgpack/core/MessagePack.java | 200 +++++-- .../msgpack/core/MessagePackException.java | 23 +- .../java/org/msgpack/core/MessagePacker.java | 323 ++++++---- .../msgpack/core/MessageSizeException.java | 15 +- .../core/MessageStringCodingException.java | 14 +- .../core/MessageTypeCastException.java | 16 +- .../msgpack/core/MessageTypeException.java | 16 +- .../org/msgpack/core/MessageUnpacker.java | 527 ++++++++++------- .../java/org/msgpack/core/Preconditions.java | 162 ++--- .../msgpack/core/annotations/Insecure.java | 3 +- .../msgpack/core/annotations/Nullable.java | 3 +- .../core/annotations/VisibleForTesting.java | 3 +- .../msgpack/core/buffer/ArrayBufferInput.java | 39 +- .../msgpack/core/buffer/ByteBufferInput.java | 27 +- .../core/buffer/ChannelBufferInput.java | 34 +- .../core/buffer/ChannelBufferOutput.java | 28 +- .../core/buffer/DirectBufferAccess.java | 46 +- .../core/buffer/InputStreamBufferInput.java | 42 +- .../msgpack/core/buffer/MessageBuffer.java | 217 ++++--- .../msgpack/core/buffer/MessageBufferBE.java | 46 +- .../core/buffer/MessageBufferInput.java | 13 +- .../core/buffer/MessageBufferOutput.java | 18 +- .../msgpack/core/buffer/MessageBufferU.java | 109 +++- .../core/buffer/OutputStreamBufferOutput.java | 37 +- .../java/org/msgpack/value/ArrayValue.java | 14 +- .../java/org/msgpack/value/BinaryValue.java | 8 +- .../java/org/msgpack/value/BooleanValue.java | 6 +- .../org/msgpack/value/ExtensionValue.java | 8 +- .../java/org/msgpack/value/FloatValue.java | 8 +- .../msgpack/value/ImmutableArrayValue.java | 7 +- .../msgpack/value/ImmutableBinaryValue.java | 4 +- .../msgpack/value/ImmutableBooleanValue.java | 4 +- .../value/ImmutableExtensionValue.java | 4 +- .../msgpack/value/ImmutableFloatValue.java | 4 +- .../msgpack/value/ImmutableIntegerValue.java | 4 +- .../org/msgpack/value/ImmutableMapValue.java | 4 +- .../org/msgpack/value/ImmutableNilValue.java | 4 +- .../msgpack/value/ImmutableNumberValue.java | 4 +- .../org/msgpack/value/ImmutableRawValue.java | 4 +- .../msgpack/value/ImmutableStringValue.java | 4 +- .../org/msgpack/value/ImmutableValue.java | 6 +- .../java/org/msgpack/value/IntegerValue.java | 19 +- .../main/java/org/msgpack/value/MapValue.java | 12 +- .../main/java/org/msgpack/value/NilValue.java | 4 +- .../java/org/msgpack/value/NumberValue.java | 5 +- .../main/java/org/msgpack/value/RawValue.java | 22 +- .../java/org/msgpack/value/StringValue.java | 10 +- .../main/java/org/msgpack/value/Value.java | 8 +- .../java/org/msgpack/value/ValueFactory.java | 122 ++-- .../java/org/msgpack/value/ValueType.java | 42 +- .../main/java/org/msgpack/value/Variable.java | 558 ++++++++++++------ .../value/impl/AbstractImmutableRawValue.java | 131 ++-- .../value/impl/AbstractImmutableValue.java | 88 ++- .../value/impl/ImmutableArrayValueImpl.java | 113 ++-- .../impl/ImmutableBigIntegerValueImpl.java | 95 ++- .../value/impl/ImmutableBinaryValueImpl.java | 36 +- .../value/impl/ImmutableBooleanValueImpl.java | 43 +- .../value/impl/ImmutableDoubleValueImpl.java | 55 +- .../impl/ImmutableExtensionValueImpl.java | 46 +- .../value/impl/ImmutableLongValueImpl.java | 95 ++- .../value/impl/ImmutableMapValueImpl.java | 157 +++-- .../value/impl/ImmutableNilValueImpl.java | 41 +- .../value/impl/ImmutableStringValueImpl.java | 40 +- .../core/example/MessagePackExample.java | 111 ++-- .../org/msgpack/core/MessageFormatTest.scala | 45 +- .../org/msgpack/core/MessagePackSpec.scala | 31 +- .../org/msgpack/core/MessagePackTest.scala | 123 ++-- .../org/msgpack/core/MessagePackerTest.scala | 117 ++-- .../msgpack/core/MessageUnpackerTest.scala | 98 +-- .../msgpack/core/buffer/ByteStringTest.scala | 18 +- .../core/buffer/MessageBufferInputTest.scala | 104 ++-- .../core/buffer/MessageBufferOutputTest.scala | 18 +- .../core/buffer/MessageBufferTest.scala | 38 +- .../core/example/MessagePackExampleTest.scala | 4 +- .../value/RawStringValueImplTest.scala | 3 +- .../org/msgpack/value/ValueFactoryTest.scala | 36 +- .../org/msgpack/value/ValueTypeTest.scala | 39 +- .../dataformat/MessagePackFactory.java | 45 +- .../dataformat/MessagePackGenerator.java | 197 +++++-- .../jackson/dataformat/MessagePackParser.java | 178 ++++-- .../org/msgpack/jackson/dataformat/Tuple.java | 12 +- .../MessagePackDataformatForPojoTest.java | 29 +- .../MessagePackDataformatTestBase.java | 90 ++- .../dataformat/MessagePackFactoryTest.java | 12 +- .../dataformat/MessagePackGeneratorTest.java | 55 +- .../dataformat/MessagePackParserTest.java | 89 ++- ...gePackDataformatHugeDataBenchmarkTest.java | 27 +- ...essagePackDataformatPojoBenchmarkTest.java | 34 +- project/Build.scala | 6 +- 93 files changed, 3468 insertions(+), 1989 deletions(-) diff --git a/msgpack-core/src/main/java/org/msgpack/core/ExtensionTypeHeader.java b/msgpack-core/src/main/java/org/msgpack/core/ExtensionTypeHeader.java index 6d6812fe4..725da34a7 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/ExtensionTypeHeader.java +++ b/msgpack-core/src/main/java/org/msgpack/core/ExtensionTypeHeader.java @@ -1,11 +1,12 @@ package org.msgpack.core; -import static org.msgpack.core.Preconditions.*; +import static org.msgpack.core.Preconditions.checkArgument; /** * Header of the Extension types */ -public class ExtensionTypeHeader { +public class ExtensionTypeHeader +{ private final byte type; private final int length; @@ -21,36 +22,43 @@ public class ExtensionTypeHeader { * ... * } * + * * @param type extension type (byte). You can check the valid byte range with {@link #checkedCastToByte(int)} method. * @param length extension type data length */ - public ExtensionTypeHeader(byte type, int length) { + public ExtensionTypeHeader(byte type, int length) + { checkArgument(length >= 0, "length must be >= 0"); this.type = type; this.length = length; } - public static byte checkedCastToByte(int code) { + public static byte checkedCastToByte(int code) + { checkArgument(Byte.MIN_VALUE <= code && code <= Byte.MAX_VALUE, "Extension type code must be within the range of byte"); return (byte) code; } - public byte getType() { + public byte getType() + { return type; } - public int getLength() { + public int getLength() + { return length; } @Override - public int hashCode() { + public int hashCode() + { return (type + 31) * 31 + length; } @Override - public boolean equals(Object obj) { - if(obj instanceof ExtensionTypeHeader) { + public boolean equals(Object obj) + { + if (obj instanceof ExtensionTypeHeader) { ExtensionTypeHeader other = (ExtensionTypeHeader) obj; return this.type == other.type && this.length == other.length; } @@ -58,8 +66,8 @@ public boolean equals(Object obj) { } @Override - public String toString() { + public String toString() + { return String.format("ExtensionTypeHeader(type:%d, length:%,d)", type, length); } - } diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessageFormat.java b/msgpack-core/src/main/java/org/msgpack/core/MessageFormat.java index b00681244..7fc258ceb 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/MessageFormat.java +++ b/msgpack-core/src/main/java/org/msgpack/core/MessageFormat.java @@ -4,12 +4,11 @@ import org.msgpack.core.annotations.VisibleForTesting; import org.msgpack.value.ValueType; - /** * Describes the list of the message format types defined in the MessagePack specification. */ -public enum MessageFormat { - +public enum MessageFormat +{ // INT7 POSFIXINT(ValueType.INTEGER), // MAP4 @@ -50,31 +49,34 @@ public enum MessageFormat { ARRAY32(ValueType.ARRAY), MAP16(ValueType.MAP), MAP32(ValueType.MAP), - NEGFIXINT(ValueType.INTEGER) - ; + NEGFIXINT(ValueType.INTEGER); + private static final MessageFormat[] formatTable = new MessageFormat[256]; private final ValueType valueType; - private MessageFormat(ValueType valueType) { + private MessageFormat(ValueType valueType) + { this.valueType = valueType; } /** * Retruns the ValueType corresponding to this MessageFormat + * * @return value type * @throws MessageFormatException if this == NEVER_USED type */ - public ValueType getValueType() throws MessageFormatException { - if(this == NEVER_USED) + public ValueType getValueType() + throws MessageFormatException + { + if (this == NEVER_USED) { throw new MessageFormatException("Cannot convert NEVER_USED to ValueType"); + } return valueType; } - private final static MessageFormat[] formatTable = new MessageFormat[256]; - static { // Preparing a look up table for converting byte values into MessageFormat types - for(int b = 0; b <= 0xFF; ++b) { + for (int b = 0; b <= 0xFF; ++b) { MessageFormat mf = toMessageFormat((byte) b); formatTable[b] = mf; } @@ -82,20 +84,24 @@ public ValueType getValueType() throws MessageFormatException { /** * Returns a MessageFormat type of the specified byte value + * * @param b MessageFormat of the given byte * @return */ - public static MessageFormat valueOf(final byte b) { + public static MessageFormat valueOf(final byte b) + { return formatTable[b & 0xFF]; } /** * Converting a byte value into MessageFormat. For faster performance, use {@link #valueOf} + * * @param b MessageFormat of the given byte * @return */ @VisibleForTesting - static MessageFormat toMessageFormat(final byte b) { + static MessageFormat toMessageFormat(final byte b) + { if (Code.isPosFixInt(b)) { return POSFIXINT; } @@ -177,5 +183,4 @@ static MessageFormat toMessageFormat(final byte b) { return NEVER_USED; } } - } diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessageFormatException.java b/msgpack-core/src/main/java/org/msgpack/core/MessageFormatException.java index f79bea279..cf169af80 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/MessageFormatException.java +++ b/msgpack-core/src/main/java/org/msgpack/core/MessageFormatException.java @@ -18,18 +18,21 @@ /** * Thrown when the input message pack format is invalid */ -public class MessageFormatException extends MessagePackException { - - public MessageFormatException(Throwable e) { +public class MessageFormatException + extends MessagePackException +{ + public MessageFormatException(Throwable e) + { super(e); } - - public MessageFormatException(String message) { + public MessageFormatException(String message) + { super(message); } - public MessageFormatException(String message, Throwable cause) { + public MessageFormatException(String message, Throwable cause) + { super(message, cause); } } diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessageIntegerOverflowException.java b/msgpack-core/src/main/java/org/msgpack/core/MessageIntegerOverflowException.java index 28671ae22..b3199ae2e 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/MessageIntegerOverflowException.java +++ b/msgpack-core/src/main/java/org/msgpack/core/MessageIntegerOverflowException.java @@ -17,35 +17,41 @@ import java.math.BigInteger; - /** * This error is thrown when the user tries to read an integer value * using a smaller types. For example, calling MessageUnpacker.unpackInt() for an integer value * that is larger than Integer.MAX_VALUE will cause this exception. */ -public class MessageIntegerOverflowException extends MessageTypeException { +public class MessageIntegerOverflowException + extends MessageTypeException +{ private final BigInteger bigInteger; - public MessageIntegerOverflowException(BigInteger bigInteger) { + public MessageIntegerOverflowException(BigInteger bigInteger) + { super(); this.bigInteger = bigInteger; } - public MessageIntegerOverflowException(long value) { + public MessageIntegerOverflowException(long value) + { this(BigInteger.valueOf(value)); } - public MessageIntegerOverflowException(String message, BigInteger bigInteger) { + public MessageIntegerOverflowException(String message, BigInteger bigInteger) + { super(message); this.bigInteger = bigInteger; } - public BigInteger getBigInteger() { + public BigInteger getBigInteger() + { return bigInteger; } @Override - public String getMessage() { + public String getMessage() + { return bigInteger.toString(); } } diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessagePack.java b/msgpack-core/src/main/java/org/msgpack/core/MessagePack.java index a6653a356..70140c8ed 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/MessagePack.java +++ b/msgpack-core/src/main/java/org/msgpack/core/MessagePack.java @@ -15,7 +15,11 @@ // package org.msgpack.core; -import org.msgpack.core.buffer.*; +import org.msgpack.core.buffer.ArrayBufferInput; +import org.msgpack.core.buffer.ChannelBufferInput; +import org.msgpack.core.buffer.ChannelBufferOutput; +import org.msgpack.core.buffer.InputStreamBufferInput; +import org.msgpack.core.buffer.OutputStreamBufferOutput; import java.io.InputStream; import java.io.OutputStream; @@ -28,16 +32,16 @@ /** * This class has MessagePack prefix code definitions and packer/unpacker factory methods. - * */ -public class MessagePack { - +public class MessagePack +{ public static final Charset UTF8 = Charset.forName("UTF-8"); /** * Message packer/unpacker configuration object */ - public static class Config { + public static class Config + { private final boolean readStringAsBinary; private final boolean readBinaryAsString; private final CodingErrorAction onMalFormedInput; @@ -57,8 +61,8 @@ public Config( int stringEncoderBufferSize, int stringDecoderBufferSize, int packerBufferSize, - int packerRawDataCopyingThreshold) { - + int packerRawDataCopyingThreshold) + { checkArgument(packerBufferSize > 0, "packer buffer size must be larger than 0: " + packerBufferSize); checkArgument(stringEncoderBufferSize > 0, "string encoder buffer size must be larger than 0: " + stringEncoderBufferSize); checkArgument(stringDecoderBufferSize > 0, "string decoder buffer size must be larger than 0: " + stringDecoderBufferSize); @@ -77,38 +81,69 @@ public Config( /** * allow unpackBinaryHeader to read str format family (default:true) */ - public boolean isReadStringAsBinary() { return readStringAsBinary; } + public boolean isReadStringAsBinary() + { + return readStringAsBinary; + } /** * allow unpackRawStringHeader and unpackString to read bin format family (default: true) */ - public boolean isReadBinaryAsString() { return readBinaryAsString; } + public boolean isReadBinaryAsString() + { + return readBinaryAsString; + } + /** * Action when encountered a malformed input */ - public CodingErrorAction getActionOnMalFormedInput() { return onMalFormedInput; } + public CodingErrorAction getActionOnMalFormedInput() + { + return onMalFormedInput; + } + /** * Action when an unmappable character is found */ - public CodingErrorAction getActionOnUnmappableCharacter() { return onUnmappableCharacter; } + public CodingErrorAction getActionOnUnmappableCharacter() + { + return onUnmappableCharacter; + } /** * unpackString size limit. (default: Integer.MAX_VALUE) */ - public int getMaxUnpackStringSize() { return maxUnpackStringSize; } + public int getMaxUnpackStringSize() + { + return maxUnpackStringSize; + } + + public int getStringEncoderBufferSize() + { + return stringEncoderBufferSize; + } - public int getStringEncoderBufferSize() { return stringEncoderBufferSize; } - public int getStringDecoderBufferSize() { return stringDecoderBufferSize; } + public int getStringDecoderBufferSize() + { + return stringDecoderBufferSize; + } - public int getPackerBufferSize() { return packerBufferSize; } - public int getPackerRawDataCopyingThreshold() { return packerRawDataCopyingThreshold; } + public int getPackerBufferSize() + { + return packerBufferSize; + } + + public int getPackerRawDataCopyingThreshold() + { + return packerRawDataCopyingThreshold; + } } /** * Builder of the configuration object */ - public static class ConfigBuilder { - + public static class ConfigBuilder + { private boolean readStringAsBinary = true; private boolean readBinaryAsString = true; @@ -121,7 +156,8 @@ public static class ConfigBuilder { private int packerBufferSize = 8192; private int packerRawDataCopyingThreshold = 512; - public Config build() { + public Config build() + { return new Config( readStringAsBinary, readBinaryAsString, @@ -135,79 +171,104 @@ public Config build() { ); } - public ConfigBuilder readStringAsBinary(boolean enable) { + public ConfigBuilder readStringAsBinary(boolean enable) + { this.readStringAsBinary = enable; return this; } - public ConfigBuilder readBinaryAsString(boolean enable) { + + public ConfigBuilder readBinaryAsString(boolean enable) + { this.readBinaryAsString = enable; return this; } - public ConfigBuilder onMalFormedInput(CodingErrorAction action) { + + public ConfigBuilder onMalFormedInput(CodingErrorAction action) + { this.onMalFormedInput = action; return this; } - public ConfigBuilder onUnmappableCharacter(CodingErrorAction action) { + + public ConfigBuilder onUnmappableCharacter(CodingErrorAction action) + { this.onUnmappableCharacter = action; return this; } - public ConfigBuilder maxUnpackStringSize(int size){ + + public ConfigBuilder maxUnpackStringSize(int size) + { this.maxUnpackStringSize = size; return this; } - public ConfigBuilder stringEncoderBufferSize(int size) { + + public ConfigBuilder stringEncoderBufferSize(int size) + { this.stringEncoderBufferSize = size; return this; } - public ConfigBuilder stringDecoderBufferSize(int size) { + + public ConfigBuilder stringDecoderBufferSize(int size) + { this.stringDecoderBufferSize = size; return this; } - public ConfigBuilder packerBufferSize(int size) { + + public ConfigBuilder packerBufferSize(int size) + { this.packerBufferSize = size; return this; } - public ConfigBuilder packerRawDataCopyingThreshold(int threshold) { + + public ConfigBuilder packerRawDataCopyingThreshold(int threshold) + { this.packerRawDataCopyingThreshold = threshold; return this; } } - - /** * Default configuration, which is visible only from classes in the core package. */ static final Config DEFAULT_CONFIG = new ConfigBuilder().build(); - /** * The prefix code set of MessagePack. See also https://github.com/msgpack/msgpack/blob/master/spec.md for details. */ - public static final class Code { - - public static final boolean isFixInt(byte b) { + public static final class Code + { + public static final boolean isFixInt(byte b) + { int v = b & 0xFF; return v <= 0x7f || v >= 0xe0; } - public static final boolean isPosFixInt(byte b) { + public static final boolean isPosFixInt(byte b) + { return (b & POSFIXINT_MASK) == 0; } - public static final boolean isNegFixInt(byte b) { + + public static final boolean isNegFixInt(byte b) + { return (b & NEGFIXINT_PREFIX) == NEGFIXINT_PREFIX; } - public static final boolean isFixStr(byte b) { + + public static final boolean isFixStr(byte b) + { return (b & (byte) 0xe0) == Code.FIXSTR_PREFIX; } - public static final boolean isFixedArray(byte b) { + + public static final boolean isFixedArray(byte b) + { return (b & (byte) 0xf0) == Code.FIXARRAY_PREFIX; } - public static final boolean isFixedMap(byte b) { + + public static final boolean isFixedMap(byte b) + { return (b & (byte) 0xe0) == Code.FIXMAP_PREFIX; } - public static final boolean isFixedRaw(byte b) { + public static final boolean isFixedRaw(byte b) + { return (b & (byte) 0xe0) == Code.FIXSTR_PREFIX; } @@ -262,11 +323,13 @@ public static final boolean isFixedRaw(byte b) { private final MessagePack.Config config; - public MessagePack() { + public MessagePack() + { this(MessagePack.DEFAULT_CONFIG); } - public MessagePack(MessagePack.Config config) { + public MessagePack(MessagePack.Config config) + { this.config = config; } @@ -275,78 +338,92 @@ public MessagePack(MessagePack.Config config) { */ public static final MessagePack DEFAULT = new MessagePack(MessagePack.DEFAULT_CONFIG); - /** * Create a MessagePacker that outputs the packed data to the specified stream, using the default configuration + * * @param out * @return */ - public static MessagePacker newDefaultPacker(OutputStream out) { + public static MessagePacker newDefaultPacker(OutputStream out) + { return DEFAULT.newPacker(out); } /** * Create a MessagePacker that outputs the packed data to the specified channel, using the default configuration + * * @param channel * @return */ - public static MessagePacker newDefaultPacker(WritableByteChannel channel) { + public static MessagePacker newDefaultPacker(WritableByteChannel channel) + { return DEFAULT.newPacker(channel); } /** * Create a MessageUnpacker that reads data from then given InputStream, using the default configuration + * * @param in * @return */ - public static MessageUnpacker newDefaultUnpacker(InputStream in) { + public static MessageUnpacker newDefaultUnpacker(InputStream in) + { return DEFAULT.newUnpacker(in); } /** * Create a MessageUnpacker that reads data from the given channel, using the default configuration + * * @param channel * @return */ - public static MessageUnpacker newDefaultUnpacker(ReadableByteChannel channel) { + public static MessageUnpacker newDefaultUnpacker(ReadableByteChannel channel) + { return DEFAULT.newUnpacker(channel); } /** * Create a MessageUnpacker that reads data from the given byte array, using the default configuration + * * @param arr * @return */ - public static MessageUnpacker newDefaultUnpacker(byte[] arr) { + public static MessageUnpacker newDefaultUnpacker(byte[] arr) + { return DEFAULT.newUnpacker(arr); } /** * Create a MessageUnpacker that reads data form the given byte array [offset, .. offset+length), using the default * configuration. + * * @param arr * @param offset * @param length * @return */ - public static MessageUnpacker newDefaultUnpacker(byte[] arr, int offset, int length) { + public static MessageUnpacker newDefaultUnpacker(byte[] arr, int offset, int length) + { return DEFAULT.newUnpacker(arr, offset, length); } - /** * Create a MessagePacker that outputs the packed data to the specified stream + * * @param out */ - public MessagePacker newPacker(OutputStream out) { + public MessagePacker newPacker(OutputStream out) + { return new MessagePacker(new OutputStreamBufferOutput(out), config); } /** * Create a MessagePacker that outputs the packed data to the specified channel + * * @param channel */ - public MessagePacker newPacker(WritableByteChannel channel) { + public MessagePacker newPacker(WritableByteChannel channel) + { return new MessagePacker(new ChannelBufferOutput(channel), config); } @@ -356,39 +433,40 @@ public MessagePacker newPacker(WritableByteChannel channel) { * * @param in */ - public MessageUnpacker newUnpacker(InputStream in) { + public MessageUnpacker newUnpacker(InputStream in) + { return new MessageUnpacker(InputStreamBufferInput.newBufferInput(in), config); } /** * Create a MessageUnpacker that reads data from the given ReadableByteChannel. + * * @param in */ - public MessageUnpacker newUnpacker(ReadableByteChannel in) { + public MessageUnpacker newUnpacker(ReadableByteChannel in) + { return new MessageUnpacker(new ChannelBufferInput(in), config); } - /** * Create a MessageUnpacker that reads data from the given byte array. * * @param arr */ - public MessageUnpacker newUnpacker(byte[] arr) { + public MessageUnpacker newUnpacker(byte[] arr) + { return new MessageUnpacker(new ArrayBufferInput(arr), config); } /** * Create a MessageUnpacker that reads data from the given byte array [offset, offset+length) + * * @param arr * @param offset * @param length */ - public MessageUnpacker newUnpacker(byte[] arr, int offset, int length) { + public MessageUnpacker newUnpacker(byte[] arr, int offset, int length) + { return new MessageUnpacker(new ArrayBufferInput(arr, offset, length), config); } - - - - } diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessagePackException.java b/msgpack-core/src/main/java/org/msgpack/core/MessagePackException.java index 4359f8f32..79474b4b7 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/MessagePackException.java +++ b/msgpack-core/src/main/java/org/msgpack/core/MessagePackException.java @@ -15,31 +15,36 @@ // package org.msgpack.core; - /** * A base class of all of the message pack exceptions. */ -public class MessagePackException extends RuntimeException { - public MessagePackException() { +public class MessagePackException + extends RuntimeException +{ + public MessagePackException() + { super(); } - public MessagePackException(String message) { + public MessagePackException(String message) + { super(message); } - public MessagePackException(String message, Throwable cause) { + public MessagePackException(String message, Throwable cause) + { super(message, cause); } - public MessagePackException(Throwable cause) { + public MessagePackException(Throwable cause) + { super(cause); } - - public static UnsupportedOperationException UNSUPPORTED(String operationName) { + public static UnsupportedOperationException UNSUPPORTED(String operationName) + { return new UnsupportedOperationException(operationName); } - public static IllegalStateException UNREACHABLE = new IllegalStateException("Cannot reach here"); + public static final IllegalStateException UNREACHABLE = new IllegalStateException("Cannot reach here"); } diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessagePacker.java b/msgpack-core/src/main/java/org/msgpack/core/MessagePacker.java index e86bdc4ea..fc13eae06 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/MessagePacker.java +++ b/msgpack-core/src/main/java/org/msgpack/core/MessagePacker.java @@ -20,8 +20,8 @@ import org.msgpack.value.Value; import java.io.Closeable; -import java.math.BigInteger; import java.io.IOException; +import java.math.BigInteger; import java.nio.ByteBuffer; import java.nio.CharBuffer; import java.nio.charset.CharacterCodingException; @@ -29,8 +29,41 @@ import java.nio.charset.CoderResult; import java.nio.charset.CodingErrorAction; -import static org.msgpack.core.MessagePack.Code.*; -import static org.msgpack.core.Preconditions.*; +import static org.msgpack.core.MessagePack.Code.ARRAY16; +import static org.msgpack.core.MessagePack.Code.ARRAY32; +import static org.msgpack.core.MessagePack.Code.BIN16; +import static org.msgpack.core.MessagePack.Code.BIN32; +import static org.msgpack.core.MessagePack.Code.BIN8; +import static org.msgpack.core.MessagePack.Code.EXT16; +import static org.msgpack.core.MessagePack.Code.EXT32; +import static org.msgpack.core.MessagePack.Code.EXT8; +import static org.msgpack.core.MessagePack.Code.FALSE; +import static org.msgpack.core.MessagePack.Code.FIXARRAY_PREFIX; +import static org.msgpack.core.MessagePack.Code.FIXEXT1; +import static org.msgpack.core.MessagePack.Code.FIXEXT16; +import static org.msgpack.core.MessagePack.Code.FIXEXT2; +import static org.msgpack.core.MessagePack.Code.FIXEXT4; +import static org.msgpack.core.MessagePack.Code.FIXEXT8; +import static org.msgpack.core.MessagePack.Code.FIXMAP_PREFIX; +import static org.msgpack.core.MessagePack.Code.FIXSTR_PREFIX; +import static org.msgpack.core.MessagePack.Code.FLOAT32; +import static org.msgpack.core.MessagePack.Code.FLOAT64; +import static org.msgpack.core.MessagePack.Code.INT16; +import static org.msgpack.core.MessagePack.Code.INT32; +import static org.msgpack.core.MessagePack.Code.INT64; +import static org.msgpack.core.MessagePack.Code.INT8; +import static org.msgpack.core.MessagePack.Code.MAP16; +import static org.msgpack.core.MessagePack.Code.MAP32; +import static org.msgpack.core.MessagePack.Code.NIL; +import static org.msgpack.core.MessagePack.Code.STR16; +import static org.msgpack.core.MessagePack.Code.STR32; +import static org.msgpack.core.MessagePack.Code.STR8; +import static org.msgpack.core.MessagePack.Code.TRUE; +import static org.msgpack.core.MessagePack.Code.UINT16; +import static org.msgpack.core.MessagePack.Code.UINT32; +import static org.msgpack.core.MessagePack.Code.UINT64; +import static org.msgpack.core.MessagePack.Code.UINT8; +import static org.msgpack.core.Preconditions.checkNotNull; /** * Writer of message packed data. @@ -49,8 +82,9 @@ * the binary data of the specified length in the header. *

*/ -public class MessagePacker implements Closeable { - +public class MessagePacker + implements Closeable +{ private final MessagePack.Config config; private MessageBufferOutput out; @@ -69,18 +103,19 @@ public class MessagePacker implements Closeable { */ private CharsetEncoder encoder; - /** * Create an MessagePacker that outputs the packed data to the given {@link org.msgpack.core.buffer.MessageBufferOutput} * * @param out MessageBufferOutput. Use {@link org.msgpack.core.buffer.OutputStreamBufferOutput}, {@link org.msgpack.core.buffer.ChannelBufferOutput} or - * your own implementation of {@link org.msgpack.core.buffer.MessageBufferOutput} interface. + * your own implementation of {@link org.msgpack.core.buffer.MessageBufferOutput} interface. */ - public MessagePacker(MessageBufferOutput out) { + public MessagePacker(MessageBufferOutput out) + { this(out, MessagePack.DEFAULT_CONFIG); } - public MessagePacker(MessageBufferOutput out, MessagePack.Config config) { + public MessagePacker(MessageBufferOutput out, MessagePack.Config config) + { this.config = checkNotNull(config, "config is null"); this.out = checkNotNull(out, "MessageBufferOutput is null"); this.position = 0; @@ -93,7 +128,9 @@ public MessagePacker(MessageBufferOutput out, MessagePack.Config config) { * @param out new output * @return the old resource */ - public MessageBufferOutput reset(MessageBufferOutput out) throws IOException { + public MessageBufferOutput reset(MessageBufferOutput out) + throws IOException + { // Validate the argument MessageBufferOutput newOut = checkNotNull(out, "MessageBufferOutput is null"); @@ -105,29 +142,34 @@ public MessageBufferOutput reset(MessageBufferOutput out) throws IOException { return old; } - public long getTotalWrittenBytes() { + public long getTotalWrittenBytes() + { return flushedBytes + position; } - private void prepareEncoder() { - if(encoder == null) { + private void prepareEncoder() + { + if (encoder == null) { this.encoder = MessagePack.UTF8.newEncoder().onMalformedInput(config.getActionOnMalFormedInput()).onUnmappableCharacter(config.getActionOnMalFormedInput()); } } - private void prepareBuffer() throws IOException { - if(buffer == null) { + private void prepareBuffer() + throws IOException + { + if (buffer == null) { buffer = out.next(config.getPackerBufferSize()); } } - - public void flush() throws IOException { - if(buffer == null) { + public void flush() + throws IOException + { + if (buffer == null) { return; } - if(position == buffer.size()) { + if (position == buffer.size()) { out.flush(buffer); } else { @@ -138,7 +180,9 @@ public void flush() throws IOException { position = 0; } - public void close() throws IOException { + public void close() + throws IOException + { try { flush(); } @@ -147,91 +191,117 @@ public void close() throws IOException { } } - private void ensureCapacity(int numBytesToWrite) throws IOException { - if(buffer == null || position + numBytesToWrite >= buffer.size()) { + private void ensureCapacity(int numBytesToWrite) + throws IOException + { + if (buffer == null || position + numBytesToWrite >= buffer.size()) { flush(); buffer = out.next(Math.max(config.getPackerBufferSize(), numBytesToWrite)); } } - private void writeByte(byte b) throws IOException { + private void writeByte(byte b) + throws IOException + { ensureCapacity(1); buffer.putByte(position++, b); } - - private void writeByteAndByte(byte b, byte v) throws IOException { + private void writeByteAndByte(byte b, byte v) + throws IOException + { ensureCapacity(2); buffer.putByte(position++, b); buffer.putByte(position++, v); } - private void writeByteAndShort(byte b, short v) throws IOException { + private void writeByteAndShort(byte b, short v) + throws IOException + { ensureCapacity(3); buffer.putByte(position++, b); buffer.putShort(position, v); position += 2; } - private void writeByteAndInt(byte b, int v) throws IOException { + private void writeByteAndInt(byte b, int v) + throws IOException + { ensureCapacity(5); buffer.putByte(position++, b); buffer.putInt(position, v); position += 4; } - private void writeByteAndFloat(byte b, float v) throws IOException { + private void writeByteAndFloat(byte b, float v) + throws IOException + { ensureCapacity(5); buffer.putByte(position++, b); buffer.putFloat(position, v); position += 4; } - private void writeByteAndDouble(byte b, double v) throws IOException { + private void writeByteAndDouble(byte b, double v) + throws IOException + { ensureCapacity(9); buffer.putByte(position++, b); buffer.putDouble(position, v); position += 8; } - private void writeByteAndLong(byte b, long v) throws IOException { + private void writeByteAndLong(byte b, long v) + throws IOException + { ensureCapacity(9); buffer.putByte(position++, b); buffer.putLong(position, v); position += 8; } - private void writeShort(short v) throws IOException { + private void writeShort(short v) + throws IOException + { ensureCapacity(2); buffer.putShort(position, v); position += 2; } - private void writeInt(int v) throws IOException { + private void writeInt(int v) + throws IOException + { ensureCapacity(4); buffer.putInt(position, v); position += 4; } - private void writeLong(long v) throws IOException { + private void writeLong(long v) + throws IOException + { ensureCapacity(8); buffer.putLong(position, v); position += 8; } - public MessagePacker packNil() throws IOException { + public MessagePacker packNil() + throws IOException + { writeByte(NIL); return this; } - public MessagePacker packBoolean(boolean b) throws IOException { + public MessagePacker packBoolean(boolean b) + throws IOException + { writeByte(b ? TRUE : FALSE); return this; } - - public MessagePacker packByte(byte b) throws IOException { - if(b < -(1 << 5)) { + public MessagePacker packByte(byte b) + throws IOException + { + if (b < -(1 << 5)) { writeByteAndByte(INT8, b); } else { @@ -240,20 +310,22 @@ public MessagePacker packByte(byte b) throws IOException { return this; } - public MessagePacker packShort(short v) throws IOException { - if(v < -(1 << 5)) { - if(v < -(1 << 7)) { + public MessagePacker packShort(short v) + throws IOException + { + if (v < -(1 << 5)) { + if (v < -(1 << 7)) { writeByteAndShort(INT16, v); } else { writeByteAndByte(INT8, (byte) v); } } - else if(v < (1 << 7)) { + else if (v < (1 << 7)) { writeByte((byte) v); } else { - if(v < (1 << 8)) { + if (v < (1 << 8)) { writeByteAndByte(UINT8, (byte) v); } else { @@ -263,26 +335,28 @@ else if(v < (1 << 7)) { return this; } - public MessagePacker packInt(int r) throws IOException { - if(r < -(1 << 5)) { - if(r < -(1 << 15)) { + public MessagePacker packInt(int r) + throws IOException + { + if (r < -(1 << 5)) { + if (r < -(1 << 15)) { writeByteAndInt(INT32, r); } - else if(r < -(1 << 7)) { + else if (r < -(1 << 7)) { writeByteAndShort(INT16, (short) r); } else { writeByteAndByte(INT8, (byte) r); } } - else if(r < (1 << 7)) { + else if (r < (1 << 7)) { writeByte((byte) r); } else { - if(r < (1 << 8)) { + if (r < (1 << 8)) { writeByteAndByte(UINT8, (byte) r); } - else if(r < (1 << 16)) { + else if (r < (1 << 16)) { writeByteAndShort(UINT16, (short) r); } else { @@ -293,10 +367,12 @@ else if(r < (1 << 16)) { return this; } - public MessagePacker packLong(long v) throws IOException { - if(v < -(1L << 5)) { - if(v < -(1L << 15)) { - if(v < -(1L << 31)) { + public MessagePacker packLong(long v) + throws IOException + { + if (v < -(1L << 5)) { + if (v < -(1L << 15)) { + if (v < -(1L << 31)) { writeByteAndLong(INT64, v); } else { @@ -304,7 +380,7 @@ public MessagePacker packLong(long v) throws IOException { } } else { - if(v < -(1 << 7)) { + if (v < -(1 << 7)) { writeByteAndShort(INT16, (short) v); } else { @@ -312,13 +388,13 @@ public MessagePacker packLong(long v) throws IOException { } } } - else if(v < (1 << 7)) { + else if (v < (1 << 7)) { // fixnum writeByte((byte) v); } else { - if(v < (1L << 16)) { - if(v < (1 << 8)) { + if (v < (1L << 16)) { + if (v < (1 << 8)) { writeByteAndByte(UINT8, (byte) v); } else { @@ -326,7 +402,7 @@ else if(v < (1 << 7)) { } } else { - if(v < (1L << 32)) { + if (v < (1L << 32)) { writeByteAndInt(UINT32, (int) v); } else { @@ -337,11 +413,13 @@ else if(v < (1 << 7)) { return this; } - public MessagePacker packBigInteger(BigInteger bi) throws IOException { - if(bi.bitLength() <= 63) { + public MessagePacker packBigInteger(BigInteger bi) + throws IOException + { + if (bi.bitLength() <= 63) { packLong(bi.longValue()); } - else if(bi.bitLength() == 64 && bi.signum() == 1) { + else if (bi.bitLength() == 64 && bi.signum() == 1) { writeByteAndLong(UINT64, bi.longValue()); } else { @@ -350,12 +428,16 @@ else if(bi.bitLength() == 64 && bi.signum() == 1) { return this; } - public MessagePacker packFloat(float v) throws IOException { + public MessagePacker packFloat(float v) + throws IOException + { writeByteAndFloat(FLOAT32, v); return this; } - public MessagePacker packDouble(double v) throws IOException { + public MessagePacker packDouble(double v) + throws IOException + { writeByteAndDouble(FLOAT64, v); return this; } @@ -367,8 +449,10 @@ public MessagePacker packDouble(double v) throws IOException { * @return * @throws IOException */ - public MessagePacker packString(String s) throws IOException { - if(s.length() <= 0) { + public MessagePacker packString(String s) + throws IOException + { + if (s.length() <= 0) { packRawStringHeader(0); return this; } @@ -382,17 +466,17 @@ public MessagePacker packString(String s) throws IOException { boolean isExtension = false; ByteBuffer encodeBuffer = buffer.toByteBuffer(position, buffer.size() - position); encoder.reset(); - while(in.hasRemaining()) { + while (in.hasRemaining()) { try { CoderResult cr = encoder.encode(in, encodeBuffer, true); // Input data is insufficient - if(cr.isUnderflow()) { + if (cr.isUnderflow()) { cr = encoder.flush(encodeBuffer); } // encodeBuffer is too small - if(cr.isOverflow()) { + if (cr.isOverflow()) { // Allocate a larger buffer int estimatedRemainingSize = Math.max(1, (int) (in.remaining() * encoder.averageBytesPerChar())); encodeBuffer.flip(); @@ -405,14 +489,14 @@ public MessagePacker packString(String s) throws IOException { continue; } - if(cr.isError()) { - if((cr.isMalformed() && config.getActionOnMalFormedInput() == CodingErrorAction.REPORT) || - (cr.isUnmappable() && config.getActionOnUnmappableCharacter() == CodingErrorAction.REPORT)) { + if (cr.isError()) { + if ((cr.isMalformed() && config.getActionOnMalFormedInput() == CodingErrorAction.REPORT) || + (cr.isUnmappable() && config.getActionOnUnmappableCharacter() == CodingErrorAction.REPORT)) { cr.throwException(); } } } - catch(CharacterCodingException e) { + catch (CharacterCodingException e) { throw new MessageStringCodingException(e); } } @@ -424,7 +508,7 @@ public MessagePacker packString(String s) throws IOException { MessageBuffer tmpBuf = buffer; // Switch the buffer to write the string length - if(strLenBuffer == null) { + if (strLenBuffer == null) { strLenBuffer = MessageBuffer.newBuffer(5); } buffer = strLenBuffer; @@ -440,14 +524,17 @@ public MessagePacker packString(String s) throws IOException { return this; } - public MessagePacker packArrayHeader(int arraySize) throws IOException { - if(arraySize < 0) + public MessagePacker packArrayHeader(int arraySize) + throws IOException + { + if (arraySize < 0) { throw new IllegalArgumentException("array size must be >= 0"); + } - if(arraySize < (1 << 4)) { + if (arraySize < (1 << 4)) { writeByte((byte) (FIXARRAY_PREFIX | arraySize)); } - else if(arraySize < (1 << 16)) { + else if (arraySize < (1 << 16)) { writeByteAndShort(ARRAY16, (short) arraySize); } else { @@ -456,14 +543,17 @@ else if(arraySize < (1 << 16)) { return this; } - public MessagePacker packMapHeader(int mapSize) throws IOException { - if(mapSize < 0) + public MessagePacker packMapHeader(int mapSize) + throws IOException + { + if (mapSize < 0) { throw new IllegalArgumentException("map size must be >= 0"); + } - if(mapSize < (1 << 4)) { + if (mapSize < (1 << 4)) { writeByte((byte) (FIXMAP_PREFIX | mapSize)); } - else if(mapSize < (1 << 16)) { + else if (mapSize < (1 << 16)) { writeByteAndShort(MAP16, (short) mapSize); } else { @@ -472,27 +562,31 @@ else if(mapSize < (1 << 16)) { return this; } - public MessagePacker packValue(Value v) throws IOException { + public MessagePacker packValue(Value v) + throws IOException + { v.writeTo(this); return this; } - public MessagePacker packExtensionTypeHeader(byte extType, int payloadLen) throws IOException { - if(payloadLen < (1 << 8)) { - if(payloadLen > 0 && (payloadLen & (payloadLen - 1)) == 0) { // check whether dataLen == 2^x - if(payloadLen == 1) { + public MessagePacker packExtensionTypeHeader(byte extType, int payloadLen) + throws IOException + { + if (payloadLen < (1 << 8)) { + if (payloadLen > 0 && (payloadLen & (payloadLen - 1)) == 0) { // check whether dataLen == 2^x + if (payloadLen == 1) { writeByteAndByte(FIXEXT1, extType); } - else if(payloadLen == 2) { + else if (payloadLen == 2) { writeByteAndByte(FIXEXT2, extType); } - else if(payloadLen == 4) { + else if (payloadLen == 4) { writeByteAndByte(FIXEXT4, extType); } - else if(payloadLen == 8) { + else if (payloadLen == 8) { writeByteAndByte(FIXEXT8, extType); } - else if(payloadLen == 16) { + else if (payloadLen == 16) { writeByteAndByte(FIXEXT16, extType); } else { @@ -505,7 +599,7 @@ else if(payloadLen == 16) { writeByte(extType); } } - else if(payloadLen < (1 << 16)) { + else if (payloadLen < (1 << 16)) { writeByteAndShort(EXT16, (short) payloadLen); writeByte(extType); } @@ -518,11 +612,13 @@ else if(payloadLen < (1 << 16)) { return this; } - public MessagePacker packBinaryHeader(int len) throws IOException { - if(len < (1 << 8)) { + public MessagePacker packBinaryHeader(int len) + throws IOException + { + if (len < (1 << 8)) { writeByteAndByte(BIN8, (byte) len); } - else if(len < (1 << 16)) { + else if (len < (1 << 16)) { writeByteAndShort(BIN16, (short) len); } else { @@ -531,14 +627,16 @@ else if(len < (1 << 16)) { return this; } - public MessagePacker packRawStringHeader(int len) throws IOException { - if(len < (1 << 5)) { + public MessagePacker packRawStringHeader(int len) + throws IOException + { + if (len < (1 << 5)) { writeByte((byte) (FIXSTR_PREFIX | len)); } - else if(len < (1 << 8)) { + else if (len < (1 << 8)) { writeByteAndByte(STR8, (byte) len); } - else if(len < (1 << 16)) { + else if (len < (1 << 16)) { writeByteAndShort(STR16, (short) len); } else { @@ -547,10 +645,11 @@ else if(len < (1 << 16)) { return this; } - - public MessagePacker writePayload(ByteBuffer src) throws IOException { + public MessagePacker writePayload(ByteBuffer src) + throws IOException + { int len = src.remaining(); - if(len >= config.getPackerRawDataCopyingThreshold()) { + if (len >= config.getPackerRawDataCopyingThreshold()) { // Use the source ByteBuffer directly to avoid memory copy // First, flush the current buffer contents @@ -565,8 +664,8 @@ public MessagePacker writePayload(ByteBuffer src) throws IOException { } else { // If the input source is small, simply copy the contents to the buffer - while(src.remaining() > 0) { - if(position >= buffer.size()) { + while (src.remaining() > 0) { + if (position >= buffer.size()) { flush(); } prepareBuffer(); @@ -579,12 +678,16 @@ public MessagePacker writePayload(ByteBuffer src) throws IOException { return this; } - public MessagePacker writePayload(byte[] src) throws IOException { + public MessagePacker writePayload(byte[] src) + throws IOException + { return writePayload(src, 0, src.length); } - public MessagePacker writePayload(byte[] src, int off, int len) throws IOException { - if(len >= config.getPackerRawDataCopyingThreshold()) { + public MessagePacker writePayload(byte[] src, int off, int len) + throws IOException + { + if (len >= config.getPackerRawDataCopyingThreshold()) { // Use the input array directory to avoid memory copy // Flush the current buffer contents @@ -598,8 +701,8 @@ public MessagePacker writePayload(byte[] src, int off, int len) throws IOExcepti } else { int cursor = 0; - while(cursor < len) { - if(buffer != null && position >= buffer.size()) { + while (cursor < len) { + if (buffer != null && position >= buffer.size()) { flush(); } prepareBuffer(); @@ -611,6 +714,4 @@ public MessagePacker writePayload(byte[] src, int off, int len) throws IOExcepti } return this; } - - } diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessageSizeException.java b/msgpack-core/src/main/java/org/msgpack/core/MessageSizeException.java index 0947a17f8..7636f614c 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/MessageSizeException.java +++ b/msgpack-core/src/main/java/org/msgpack/core/MessageSizeException.java @@ -18,22 +18,25 @@ /** * Thrown to indicate too large message size (e.g, larger than 2^31-1). */ -public class MessageSizeException extends MessagePackException { +public class MessageSizeException + extends MessagePackException +{ private final long size; - public MessageSizeException(long size) { + public MessageSizeException(long size) + { super(); this.size = size; } - public MessageSizeException(String message, long size) { + public MessageSizeException(String message, long size) + { super(message); this.size = size; } - public long getSize() { + public long getSize() + { return size; } - - } diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessageStringCodingException.java b/msgpack-core/src/main/java/org/msgpack/core/MessageStringCodingException.java index fbe38bffe..b4d549c4b 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/MessageStringCodingException.java +++ b/msgpack-core/src/main/java/org/msgpack/core/MessageStringCodingException.java @@ -20,18 +20,22 @@ /** * Thrown to indicate an error when encoding/decoding a String value */ -public class MessageStringCodingException extends MessagePackException { - public MessageStringCodingException(String message, CharacterCodingException cause) { +public class MessageStringCodingException + extends MessagePackException +{ + public MessageStringCodingException(String message, CharacterCodingException cause) + { super(message, cause); } - public MessageStringCodingException(CharacterCodingException cause) { + public MessageStringCodingException(CharacterCodingException cause) + { super(cause); } @Override - public CharacterCodingException getCause() { + public CharacterCodingException getCause() + { return (CharacterCodingException) super.getCause(); } - } diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessageTypeCastException.java b/msgpack-core/src/main/java/org/msgpack/core/MessageTypeCastException.java index 6189cc646..62e7d914e 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/MessageTypeCastException.java +++ b/msgpack-core/src/main/java/org/msgpack/core/MessageTypeCastException.java @@ -15,20 +15,26 @@ // package org.msgpack.core; -public class MessageTypeCastException extends MessageTypeException { - public MessageTypeCastException() { +public class MessageTypeCastException + extends MessageTypeException +{ + public MessageTypeCastException() + { super(); } - public MessageTypeCastException(String message) { + public MessageTypeCastException(String message) + { super(message); } - public MessageTypeCastException(String message, Throwable cause) { + public MessageTypeCastException(String message, Throwable cause) + { super(message, cause); } - public MessageTypeCastException(Throwable cause) { + public MessageTypeCastException(Throwable cause) + { super(cause); } } diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessageTypeException.java b/msgpack-core/src/main/java/org/msgpack/core/MessageTypeException.java index 925f5fd3f..f457ab82b 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/MessageTypeException.java +++ b/msgpack-core/src/main/java/org/msgpack/core/MessageTypeException.java @@ -18,20 +18,26 @@ /** * Thrown when a type mismatch error occurs */ -public class MessageTypeException extends MessagePackException { - public MessageTypeException() { +public class MessageTypeException + extends MessagePackException +{ + public MessageTypeException() + { super(); } - public MessageTypeException(String message) { + public MessageTypeException(String message) + { super(message); } - public MessageTypeException(String message, Throwable cause) { + public MessageTypeException(String message, Throwable cause) + { super(message, cause); } - public MessageTypeException(Throwable cause) { + public MessageTypeException(Throwable cause) + { super(cause); } } diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java b/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java index 4ea0949b9..c74c3307d 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java +++ b/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java @@ -15,37 +15,37 @@ // package org.msgpack.core; -import java.util.List; -import java.util.ArrayList; -import java.util.Map; -import java.util.HashMap; +import org.msgpack.core.MessagePack.Code; +import org.msgpack.core.buffer.MessageBuffer; +import org.msgpack.core.buffer.MessageBufferInput; +import org.msgpack.value.ImmutableValue; +import org.msgpack.value.Value; +import org.msgpack.value.ValueFactory; +import org.msgpack.value.Variable; + import java.io.Closeable; import java.io.EOFException; import java.io.IOException; -import java.nio.ByteBuffer; import java.math.BigInteger; +import java.nio.ByteBuffer; import java.nio.CharBuffer; import java.nio.charset.CharacterCodingException; import java.nio.charset.CharsetDecoder; import java.nio.charset.CoderResult; import java.nio.charset.CodingErrorAction; import java.nio.charset.MalformedInputException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; -import org.msgpack.core.MessagePack.Code; -import org.msgpack.core.buffer.MessageBuffer; -import org.msgpack.core.buffer.MessageBufferInput; -import org.msgpack.value.Value; -import org.msgpack.value.ImmutableValue; -import org.msgpack.value.Variable; -import org.msgpack.value.ValueFactory; - -import static org.msgpack.core.Preconditions.*; - +import static org.msgpack.core.Preconditions.checkArgument; +import static org.msgpack.core.Preconditions.checkNotNull; /** * MessageUnpacker lets an application read message-packed values from a data stream. * The application needs to call {@link #getNextFormat()} followed by an appropriate unpackXXX method according to the the returned format type. - * + *

*

  * 
  *     MessageUnpacker unpacker = MessagePackFactory.DEFAULT.newUnpacker(...);
@@ -63,15 +63,16 @@
  *                break;
  *             }
  *             // ...
-  *       }
+ *       }
  *     }
  *
  * 
  * 
*/ -public class MessageUnpacker implements Closeable { - - private final static MessageBuffer EMPTY_BUFFER = MessageBuffer.wrap(new byte[0]); +public class MessageUnpacker + implements Closeable +{ + private static final MessageBuffer EMPTY_BUFFER = MessageBuffer.wrap(new byte[0]); private final MessagePack.Config config; @@ -117,23 +118,24 @@ public class MessageUnpacker implements Closeable { */ private CharBuffer decodeBuffer; - /** * Create an MessageUnpacker that reads data from the given MessageBufferInput * * @param in */ - public MessageUnpacker(MessageBufferInput in) { + public MessageUnpacker(MessageBufferInput in) + { this(in, MessagePack.DEFAULT_CONFIG); } - /** * Create an MessageUnpacker + * * @param in * @param config configuration */ - public MessageUnpacker(MessageBufferInput in, MessagePack.Config config) { + public MessageUnpacker(MessageBufferInput in, MessagePack.Config config) + { // Root constructor. All of the constructors must call this constructor. this.in = checkNotNull(in, "MessageBufferInput is null"); this.config = checkNotNull(config, "Config"); @@ -141,10 +143,13 @@ public MessageUnpacker(MessageBufferInput in, MessagePack.Config config) { /** * Reset input. This method doesn't close the old resource. + * * @param in new input * @return the old resource */ - public MessageBufferInput reset(MessageBufferInput in) throws IOException { + public MessageBufferInput reset(MessageBufferInput in) + throws IOException + { MessageBufferInput newIn = checkNotNull(in, "MessageBufferInput is null"); // Reset the internal states @@ -159,12 +164,14 @@ public MessageBufferInput reset(MessageBufferInput in) throws IOException { return old; } - public long getTotalReadBytes() { + public long getTotalReadBytes() + { return totalReadBytes + position; } - private void prepareDecoder() { - if(decoder == null) { + private void prepareDecoder() + { + if (decoder == null) { decodeBuffer = CharBuffer.allocate(config.getStringDecoderBufferSize()); decoder = MessagePack.UTF8.newDecoder() .onMalformedInput(config.getActionOnMalFormedInput()) @@ -172,15 +179,16 @@ private void prepareDecoder() { } } - /** * Relocate the cursor position so that it points to the real buffer * * @return true if it succeeds to move the cursor, or false if there is no more buffer to read * @throws IOException when failed to retrieve next buffer */ - private boolean ensureBuffer() throws IOException { - while(buffer != null && position >= buffer.size()) { + private boolean ensureBuffer() + throws IOException + { + while (buffer != null && position >= buffer.size()) { // Fetch the next buffer int bufferSize = buffer.size(); position -= bufferSize; @@ -190,12 +198,15 @@ private boolean ensureBuffer() throws IOException { return buffer != null; } - private MessageBuffer takeNextBuffer() throws IOException { - if(reachedEOF) + private MessageBuffer takeNextBuffer() + throws IOException + { + if (reachedEOF) { return null; + } MessageBuffer nextBuffer = null; - if(secondaryBuffer == null) { + if (secondaryBuffer == null) { nextBuffer = in.next(); } else { @@ -203,13 +214,12 @@ private MessageBuffer takeNextBuffer() throws IOException { secondaryBuffer = null; } - if(nextBuffer == null) { + if (nextBuffer == null) { reachedEOF = true; } return nextBuffer; } - /** * Ensure that the buffer has the data of at least the specified size. * @@ -217,15 +227,19 @@ private MessageBuffer takeNextBuffer() throws IOException { * @return if the buffer can have the data of the specified size returns true, or if the input source reached an EOF, it returns false. * @throws IOException */ - private boolean ensure(int byteSizeToRead) throws IOException { - if(byteSizeToRead == 0) + private boolean ensure(int byteSizeToRead) + throws IOException + { + if (byteSizeToRead == 0) { return true; + } - if(!ensureBuffer()) + if (!ensureBuffer()) { return false; + } // The buffer contains the data - if(position + byteSizeToRead <= buffer.size()) { + if (position + byteSizeToRead <= buffer.size()) { // OK return true; } @@ -244,22 +258,24 @@ private boolean ensure(int byteSizeToRead) throws IOException { // Copy the remaining buffer contents to the new buffer int firstHalfSize = buffer.size() - position; - if(firstHalfSize > 0) + if (firstHalfSize > 0) { buffer.copyTo(position, newBuffer, 0, firstHalfSize); + } // Read the last half contents from the next buffers int cursor = firstHalfSize; - while(cursor < byteSizeToRead) { + while (cursor < byteSizeToRead) { secondaryBuffer = takeNextBuffer(); - if(secondaryBuffer == null) + if (secondaryBuffer == null) { return false; // No more buffer to read + } // Copy the contents from the secondary buffer to the new buffer int copyLen = Math.min(byteSizeToRead - cursor, secondaryBuffer.size()); secondaryBuffer.copyTo(0, newBuffer, cursor, copyLen); // Truncate the copied part from the secondaryBuffer - secondaryBuffer = copyLen == secondaryBuffer.size() ? null : secondaryBuffer.slice(copyLen, secondaryBuffer.size()-copyLen); + secondaryBuffer = copyLen == secondaryBuffer.size() ? null : secondaryBuffer.slice(copyLen, secondaryBuffer.size() - copyLen); cursor += copyLen; } @@ -278,20 +294,25 @@ private boolean ensure(int byteSizeToRead) throws IOException { * * @return true if this unpacker has more elements to read */ - public boolean hasNext() throws IOException { + public boolean hasNext() + throws IOException + { return ensure(1); } /** * Returns the next MessageFormat type. This method should be called after {@link #hasNext()} returns true. * If {@link #hasNext()} returns false, calling this method throws {@link java.io.EOFException}. - * + *

* This method does not proceed the internal cursor. + * * @return the next MessageFormat * @throws IOException when failed to read the input data. * @throws EOFException when the end of file reached, i.e. {@link #hasNext()} == false. */ - public MessageFormat getNextFormat() throws IOException { + public MessageFormat getNextFormat() + throws IOException + { byte b = lookAhead(); return MessageFormat.valueOf(b); } @@ -303,18 +324,23 @@ public MessageFormat getNextFormat() throws IOException { * @return * @throws IOException */ - private byte lookAhead() throws IOException { - if(ensure(1)) + private byte lookAhead() + throws IOException + { + if (ensure(1)) { return buffer.getByte(position); - else + } + else { throw new EOFException(); + } } - /** * Get the head byte value and proceeds the cursor by 1 */ - private byte consume() throws IOException { + private byte consume() + throws IOException + { byte b = lookAhead(); position += 1; return b; @@ -323,14 +349,16 @@ private byte consume() throws IOException { /** * Proceeds the cursor by the specified byte length */ - private void consume(int numBytes) throws IOException { - assert(numBytes >= 0); + private void consume(int numBytes) + throws IOException + { + assert (numBytes >= 0); // If position + numBytes becomes negative, it indicates an overflow from Integer.MAX_VALUE. - if(position + numBytes < 0) { + if (position + numBytes < 0) { ensureBuffer(); } position += numBytes; - } + } /** * Read a byte value at the cursor and proceed the cursor. @@ -338,8 +366,10 @@ private void consume(int numBytes) throws IOException { * @return * @throws IOException */ - private byte readByte() throws IOException { - if(!ensure(1)) { + private byte readByte() + throws IOException + { + if (!ensure(1)) { throw new EOFException("insufficient data length for reading byte value"); } byte b = buffer.getByte(position); @@ -347,8 +377,10 @@ private byte readByte() throws IOException { return b; } - private short readShort() throws IOException { - if(!ensure(2)) { + private short readShort() + throws IOException + { + if (!ensure(2)) { throw new EOFException("insufficient data length for reading short value"); } short s = buffer.getShort(position); @@ -356,8 +388,10 @@ private short readShort() throws IOException { return s; } - private int readInt() throws IOException { - if(!ensure(4)) { + private int readInt() + throws IOException + { + if (!ensure(4)) { throw new EOFException("insufficient data length for reading int value"); } int i = buffer.getInt(position); @@ -365,8 +399,10 @@ private int readInt() throws IOException { return i; } - private float readFloat() throws IOException { - if(!ensure(4)) { + private float readFloat() + throws IOException + { + if (!ensure(4)) { throw new EOFException("insufficient data length for reading float value"); } float f = buffer.getFloat(position); @@ -374,8 +410,10 @@ private float readFloat() throws IOException { return f; } - private long readLong() throws IOException { - if(!ensure(8)) { + private long readLong() + throws IOException + { + if (!ensure(8)) { throw new EOFException("insufficient data length for reading long value"); } long l = buffer.getLong(position); @@ -383,8 +421,10 @@ private long readLong() throws IOException { return l; } - private double readDouble() throws IOException { - if(!ensure(8)) { + private double readDouble() + throws IOException + { + if (!ensure(8)) { throw new EOFException("insufficient data length for reading double value"); } double d = buffer.getDouble(position); @@ -392,7 +432,6 @@ private double readDouble() throws IOException { return d; } - /** * Skip reading the specified number of bytes. Use this method only if you know skipping data is safe. * For simply skipping the next value, use {@link #skipValue()}. @@ -400,7 +439,9 @@ private double readDouble() throws IOException { * @param numBytes * @throws IOException */ - public void skipBytes(int numBytes) throws IOException { + public void skipBytes(int numBytes) + throws IOException + { checkArgument(numBytes >= 0, "skip length must be >= 0: " + numBytes); consume(numBytes); } @@ -410,16 +451,18 @@ public void skipBytes(int numBytes) throws IOException { * * @throws IOException */ - public void skipValue() throws IOException { + public void skipValue() + throws IOException + { int remainingValues = 1; - while(remainingValues > 0) { - if(reachedEOF) { + while (remainingValues > 0) { + if (reachedEOF) { throw new EOFException(); } MessageFormat f = getNextFormat(); byte b = consume(); - switch(f) { + switch (f) { case POSFIXINT: case NEGFIXINT: case BOOLEAN: @@ -523,21 +566,25 @@ public void skipValue() throws IOException { * @throws MessageFormatException */ private static MessageTypeException unexpected(String expected, byte b) - throws MessageTypeException { + throws MessageTypeException + { MessageFormat format = MessageFormat.valueOf(b); String typeName; if (format == MessageFormat.NEVER_USED) { typeName = "NeverUsed"; - } else { + } + else { String name = format.getValueType().name(); typeName = name.substring(0, 1) + name.substring(1).toLowerCase(); } return new MessageTypeException(String.format("Expected %s, but got %s (%02x)", expected, typeName, b)); } - public ImmutableValue unpackValue() throws IOException { + public ImmutableValue unpackValue() + throws IOException + { MessageFormat mf = getNextFormat(); - switch(mf.getValueType()) { + switch (mf.getValueType()) { case NIL: unpackNil(); return ValueFactory.newNil(); @@ -563,7 +610,7 @@ public ImmutableValue unpackValue() throws IOException { case ARRAY: { int size = unpackArrayHeader(); Value[] array = new Value[size]; - for (int i=0; i < size; i++) { + for (int i = 0; i < size; i++) { array[i] = unpackValue(); } return ValueFactory.newArray(array); @@ -571,7 +618,7 @@ public ImmutableValue unpackValue() throws IOException { case MAP: { int size = unpackMapHeader(); Value[] kvs = new Value[size * 2]; - for (int i=0; i < size * 2; ) { + for (int i = 0; i < size * 2; ) { kvs[i] = unpackValue(); i++; kvs[i] = unpackValue(); @@ -588,9 +635,11 @@ public ImmutableValue unpackValue() throws IOException { } } - public Variable unpackValue(Variable var) throws IOException { + public Variable unpackValue(Variable var) + throws IOException + { MessageFormat mf = getNextFormat(); - switch(mf.getValueType()) { + switch (mf.getValueType()) { case NIL: unpackNil(); var.setNilValue(); @@ -623,7 +672,7 @@ public Variable unpackValue(Variable var) throws IOException { case ARRAY: { int size = unpackArrayHeader(); List list = new ArrayList(size); - for (int i=0; i < size; i++) { + for (int i = 0; i < size; i++) { //Variable e = new Variable(); //unpackValue(e); //list.add(e); @@ -634,8 +683,8 @@ public Variable unpackValue(Variable var) throws IOException { } case MAP: { int size = unpackMapHeader(); - Map map = new HashMap(); - for (int i=0; i < size; i++) { + Map map = new HashMap(); + for (int i = 0; i < size; i++) { //Variable k = new Variable(); //unpackValue(k); //Variable v = new Variable(); @@ -657,53 +706,59 @@ public Variable unpackValue(Variable var) throws IOException { } } - public void unpackNil() throws IOException { + public void unpackNil() + throws IOException + { byte b = consume(); - if(b == Code.NIL) { + if (b == Code.NIL) { return; } throw unexpected("Nil", b); } - - public boolean unpackBoolean() throws IOException { + public boolean unpackBoolean() + throws IOException + { byte b = consume(); - if(b == Code.FALSE) { + if (b == Code.FALSE) { return false; - } else if(b == Code.TRUE) { + } + else if (b == Code.TRUE) { return true; } throw unexpected("boolean", b); } - public byte unpackByte() throws IOException { + public byte unpackByte() + throws IOException + { byte b = consume(); - if(Code.isFixInt(b)) { + if (Code.isFixInt(b)) { return b; } - switch(b) { + switch (b) { case Code.UINT8: // unsigned int 8 byte u8 = readByte(); - if(u8 < (byte) 0) { + if (u8 < (byte) 0) { throw overflowU8(u8); } return u8; case Code.UINT16: // unsigned int 16 short u16 = readShort(); - if(u16 < 0 || u16 > Byte.MAX_VALUE) { + if (u16 < 0 || u16 > Byte.MAX_VALUE) { throw overflowU16(u16); } return (byte) u16; case Code.UINT32: // unsigned int 32 int u32 = readInt(); - if(u32 < 0 || u32 > Byte.MAX_VALUE) { + if (u32 < 0 || u32 > Byte.MAX_VALUE) { throw overflowU32(u32); } return (byte) u32; case Code.UINT64: // unsigned int 64 long u64 = readLong(); - if(u64 < 0L || u64 > Byte.MAX_VALUE) { + if (u64 < 0L || u64 > Byte.MAX_VALUE) { throw overflowU64(u64); } return (byte) u64; @@ -712,19 +767,19 @@ public byte unpackByte() throws IOException { return i8; case Code.INT16: // signed int 16 short i16 = readShort(); - if(i16 < Byte.MIN_VALUE || i16 > Byte.MAX_VALUE) { + if (i16 < Byte.MIN_VALUE || i16 > Byte.MAX_VALUE) { throw overflowI16(i16); } return (byte) i16; case Code.INT32: // signed int 32 int i32 = readInt(); - if(i32 < Byte.MIN_VALUE || i32 > Byte.MAX_VALUE) { + if (i32 < Byte.MIN_VALUE || i32 > Byte.MAX_VALUE) { throw overflowI32(i32); } return (byte) i32; case Code.INT64: // signed int 64 long i64 = readLong(); - if(i64 < Byte.MIN_VALUE || i64 > Byte.MAX_VALUE) { + if (i64 < Byte.MIN_VALUE || i64 > Byte.MAX_VALUE) { throw overflowI64(i64); } return (byte) i64; @@ -732,30 +787,32 @@ public byte unpackByte() throws IOException { throw unexpected("Integer", b); } - public short unpackShort() throws IOException { + public short unpackShort() + throws IOException + { byte b = consume(); - if(Code.isFixInt(b)) { + if (Code.isFixInt(b)) { return (short) b; } - switch(b) { + switch (b) { case Code.UINT8: // unsigned int 8 byte u8 = readByte(); return (short) (u8 & 0xff); case Code.UINT16: // unsigned int 16 short u16 = readShort(); - if(u16 < (short) 0) { + if (u16 < (short) 0) { throw overflowU16(u16); } return u16; case Code.UINT32: // unsigned int 32 int u32 = readInt(); - if(u32 < 0 || u32 > Short.MAX_VALUE) { + if (u32 < 0 || u32 > Short.MAX_VALUE) { throw overflowU32(u32); } return (short) u32; case Code.UINT64: // unsigned int 64 long u64 = readLong(); - if(u64 < 0L || u64 > Short.MAX_VALUE) { + if (u64 < 0L || u64 > Short.MAX_VALUE) { throw overflowU64(u64); } return (short) u64; @@ -767,27 +824,28 @@ public short unpackShort() throws IOException { return i16; case Code.INT32: // signed int 32 int i32 = readInt(); - if(i32 < Short.MIN_VALUE || i32 > Short.MAX_VALUE) { + if (i32 < Short.MIN_VALUE || i32 > Short.MAX_VALUE) { throw overflowI32(i32); } return (short) i32; case Code.INT64: // signed int 64 long i64 = readLong(); - if(i64 < Short.MIN_VALUE || i64 > Short.MAX_VALUE) { + if (i64 < Short.MIN_VALUE || i64 > Short.MAX_VALUE) { throw overflowI64(i64); } return (short) i64; } throw unexpected("Integer", b); - } - public int unpackInt() throws IOException { + public int unpackInt() + throws IOException + { byte b = consume(); - if(Code.isFixInt(b)) { + if (Code.isFixInt(b)) { return (int) b; } - switch(b) { + switch (b) { case Code.UINT8: // unsigned int 8 byte u8 = readByte(); return u8 & 0xff; @@ -796,13 +854,13 @@ public int unpackInt() throws IOException { return u16 & 0xffff; case Code.UINT32: // unsigned int 32 int u32 = readInt(); - if(u32 < 0) { + if (u32 < 0) { throw overflowU32(u32); } return u32; case Code.UINT64: // unsigned int 64 long u64 = readLong(); - if(u64 < 0L || u64 > (long) Integer.MAX_VALUE) { + if (u64 < 0L || u64 > (long) Integer.MAX_VALUE) { throw overflowU64(u64); } return (int) u64; @@ -817,21 +875,22 @@ public int unpackInt() throws IOException { return i32; case Code.INT64: // signed int 64 long i64 = readLong(); - if(i64 < (long) Integer.MIN_VALUE || i64 > (long) Integer.MAX_VALUE) { + if (i64 < (long) Integer.MIN_VALUE || i64 > (long) Integer.MAX_VALUE) { throw overflowI64(i64); } return (int) i64; } throw unexpected("Integer", b); - } - public long unpackLong() throws IOException { + public long unpackLong() + throws IOException + { byte b = consume(); - if(Code.isFixInt(b)) { + if (Code.isFixInt(b)) { return (long) b; } - switch(b) { + switch (b) { case Code.UINT8: // unsigned int 8 byte u8 = readByte(); return (long) (u8 & 0xff); @@ -840,14 +899,15 @@ public long unpackLong() throws IOException { return (long) (u16 & 0xffff); case Code.UINT32: // unsigned int 32 int u32 = readInt(); - if(u32 < 0) { + if (u32 < 0) { return (long) (u32 & 0x7fffffff) + 0x80000000L; - } else { + } + else { return (long) u32; } case Code.UINT64: // unsigned int 64 long u64 = readLong(); - if(u64 < 0L) { + if (u64 < 0L) { throw overflowU64(u64); } return u64; @@ -865,15 +925,16 @@ public long unpackLong() throws IOException { return i64; } throw unexpected("Integer", b); - } - public BigInteger unpackBigInteger() throws IOException { + public BigInteger unpackBigInteger() + throws IOException + { byte b = consume(); - if(Code.isFixInt(b)) { + if (Code.isFixInt(b)) { return BigInteger.valueOf((long) b); } - switch(b) { + switch (b) { case Code.UINT8: // unsigned int 8 byte u8 = readByte(); return BigInteger.valueOf((long) (u8 & 0xff)); @@ -882,17 +943,19 @@ public BigInteger unpackBigInteger() throws IOException { return BigInteger.valueOf((long) (u16 & 0xffff)); case Code.UINT32: // unsigned int 32 int u32 = readInt(); - if(u32 < 0) { + if (u32 < 0) { return BigInteger.valueOf((long) (u32 & 0x7fffffff) + 0x80000000L); - } else { + } + else { return BigInteger.valueOf((long) u32); } case Code.UINT64: // unsigned int 64 long u64 = readLong(); - if(u64 < 0L) { + if (u64 < 0L) { BigInteger bi = BigInteger.valueOf(u64 + Long.MAX_VALUE + 1L).setBit(63); return bi; - } else { + } + else { return BigInteger.valueOf(u64); } case Code.INT8: // signed int 8 @@ -911,9 +974,11 @@ public BigInteger unpackBigInteger() throws IOException { throw unexpected("Integer", b); } - public float unpackFloat() throws IOException { + public float unpackFloat() + throws IOException + { byte b = consume(); - switch(b) { + switch (b) { case Code.FLOAT32: // float float fv = readFloat(); return fv; @@ -924,9 +989,11 @@ public float unpackFloat() throws IOException { throw unexpected("Float", b); } - public double unpackDouble() throws IOException { + public double unpackDouble() + throws IOException + { byte b = consume(); - switch(b) { + switch (b) { case Code.FLOAT32: // float float fv = readFloat(); return (double) fv; @@ -937,18 +1004,19 @@ public double unpackDouble() throws IOException { throw unexpected("Float", b); } + private static final String EMPTY_STRING = ""; - private final static String EMPTY_STRING = ""; - - public String unpackString() throws IOException { + public String unpackString() + throws IOException + { int strLen = unpackRawStringHeader(); - if(strLen > 0) { - if(strLen > config.getMaxUnpackStringSize()) { + if (strLen > 0) { + if (strLen > config.getMaxUnpackStringSize()) { throw new MessageSizeException(String.format("cannot unpack a String of size larger than %,d: %,d", config.getMaxUnpackStringSize(), strLen), strLen); } prepareDecoder(); - assert(decoder != null); + assert (decoder != null); decoder.reset(); @@ -957,38 +1025,41 @@ public String unpackString() throws IOException { decodeBuffer.clear(); StringBuilder sb = new StringBuilder(); - while(cursor < strLen) { - int readLen = Math.min(position < buffer.size() ? buffer.size() - position : buffer.size(), strLen-cursor); - if (!ensure(readLen)) + while (cursor < strLen) { + int readLen = Math.min(position < buffer.size() ? buffer.size() - position : buffer.size(), strLen - cursor); + if (!ensure(readLen)) { throw new EOFException(); + } ByteBuffer bb = buffer.toByteBuffer(position, readLen); - while(bb.hasRemaining()) { + while (bb.hasRemaining()) { boolean endOfInput = (cursor + readLen) >= strLen; CoderResult cr = decoder.decode(bb, decodeBuffer, endOfInput); - if(endOfInput && cr.isUnderflow()) + if (endOfInput && cr.isUnderflow()) { cr = decoder.flush(decodeBuffer); + } - if(cr.isOverflow()) { + if (cr.isOverflow()) { // The output CharBuffer has insufficient space decoder.reset(); } - if(cr.isUnderflow() && bb.hasRemaining()) { + if (cr.isUnderflow() && bb.hasRemaining()) { // input buffer doesn't have enough bytes for multi bytes characters - if(config.getActionOnMalFormedInput() == CodingErrorAction.REPORT) { + if (config.getActionOnMalFormedInput() == CodingErrorAction.REPORT) { throw new MalformedInputException(strLen); } // trash truncated bytes - while (bb.hasRemaining()) + while (bb.hasRemaining()) { bb.get(); + } } - if(cr.isError()) { - if((cr.isMalformed() && config.getActionOnMalFormedInput() == CodingErrorAction.REPORT) || - (cr.isUnmappable() && config.getActionOnUnmappableCharacter() == CodingErrorAction.REPORT)) { + if (cr.isError()) { + if ((cr.isMalformed() && config.getActionOnMalFormedInput() == CodingErrorAction.REPORT) || + (cr.isUnmappable() && config.getActionOnUnmappableCharacter() == CodingErrorAction.REPORT)) { cr.throwException(); } } @@ -1005,20 +1076,23 @@ public String unpackString() throws IOException { return sb.toString(); } - catch(CharacterCodingException e) { + catch (CharacterCodingException e) { throw new MessageStringCodingException(e); } - } else + } + else { return EMPTY_STRING; + } } - - public int unpackArrayHeader() throws IOException { + public int unpackArrayHeader() + throws IOException + { byte b = consume(); - if(Code.isFixedArray(b)) { // fixarray + if (Code.isFixedArray(b)) { // fixarray return b & 0x0f; } - switch(b) { + switch (b) { case Code.ARRAY16: // array 16 return readNextLength16(); case Code.ARRAY32: // array 32 @@ -1027,12 +1101,14 @@ public int unpackArrayHeader() throws IOException { throw unexpected("Array", b); } - public int unpackMapHeader() throws IOException { + public int unpackMapHeader() + throws IOException + { byte b = consume(); - if(Code.isFixedMap(b)) { // fixmap + if (Code.isFixedMap(b)) { // fixmap return b & 0x0f; } - switch(b) { + switch (b) { case Code.MAP16: // map 16 return readNextLength16(); case Code.MAP32: // map 32 @@ -1041,9 +1117,11 @@ public int unpackMapHeader() throws IOException { throw unexpected("Map", b); } - public ExtensionTypeHeader unpackExtensionTypeHeader() throws IOException { + public ExtensionTypeHeader unpackExtensionTypeHeader() + throws IOException + { byte b = consume(); - switch(b) { + switch (b) { case Code.FIXEXT1: return new ExtensionTypeHeader(readByte(), 1); case Code.FIXEXT2: @@ -1074,8 +1152,10 @@ public ExtensionTypeHeader unpackExtensionTypeHeader() throws IOException { throw unexpected("Ext", b); } - private int readStringHeader(byte b) throws IOException { - switch(b) { + private int readStringHeader(byte b) + throws IOException + { + switch (b) { case Code.STR8: // str 8 return readNextLength8(); case Code.STR16: // str 16 @@ -1087,8 +1167,10 @@ private int readStringHeader(byte b) throws IOException { } } - private int readBinaryHeader(byte b) throws IOException { - switch(b) { + private int readBinaryHeader(byte b) + throws IOException + { + switch (b) { case Code.BIN8: // bin 8 return readNextLength8(); case Code.BIN16: // bin 16 @@ -1100,60 +1182,72 @@ private int readBinaryHeader(byte b) throws IOException { } } - - public int unpackRawStringHeader() throws IOException { + public int unpackRawStringHeader() + throws IOException + { byte b = consume(); - if(Code.isFixedRaw(b)) { // FixRaw + if (Code.isFixedRaw(b)) { // FixRaw return b & 0x1f; } int len = readStringHeader(b); - if(len >= 0) + if (len >= 0) { return len; + } - if(config.isReadBinaryAsString()){ + if (config.isReadBinaryAsString()) { len = readBinaryHeader(b); - if(len >= 0) + if (len >= 0) { return len; + } } throw unexpected("String", b); } - - public int unpackBinaryHeader() throws IOException { + public int unpackBinaryHeader() + throws IOException + { byte b = consume(); - if(Code.isFixedRaw(b)) { // FixRaw + if (Code.isFixedRaw(b)) { // FixRaw return b & 0x1f; } int len = readBinaryHeader(b); - if(len >= 0) + if (len >= 0) { return len; + } - if(config.isReadStringAsBinary()) { + if (config.isReadStringAsBinary()) { len = readStringHeader(b); - if(len >= 0) + if (len >= 0) { return len; + } } throw unexpected("Binary", b); } // TODO returns a buffer reference to the payload (zero-copy) - - public void readPayload(ByteBuffer dst) throws IOException { - while(dst.remaining() > 0) { - if(!ensureBuffer()) + public void readPayload(ByteBuffer dst) + throws IOException + { + while (dst.remaining() > 0) { + if (!ensureBuffer()) { throw new EOFException(); + } int l = Math.min(buffer.size() - position, dst.remaining()); buffer.getBytes(position, l, dst); consume(l); } } - public void readPayload(byte[] dst) throws IOException { + public void readPayload(byte[] dst) + throws IOException + { readPayload(dst, 0, dst.length); } - public byte[] readPayload(int length) throws IOException { + public byte[] readPayload(int length) + throws IOException + { byte[] newArray = new byte[length]; readPayload(newArray); return newArray; @@ -1167,11 +1261,14 @@ public byte[] readPayload(int length) throws IOException { * @param len the number of bytes to read * @throws IOException */ - public void readPayload(byte[] dst, int off, int len) throws IOException { + public void readPayload(byte[] dst, int off, int len) + throws IOException + { int writtenLen = 0; - while(writtenLen < len) { - if(!ensureBuffer()) + while (writtenLen < len) { + if (!ensureBuffer()) { throw new EOFException(); + } int l = Math.min(buffer.size() - position, len - writtenLen); buffer.getBytes(position, dst, off + writtenLen, l); consume(l); @@ -1179,79 +1276,95 @@ public void readPayload(byte[] dst, int off, int len) throws IOException { } } - public MessageBuffer readPayloadAsReference(int length) throws IOException { + public MessageBuffer readPayloadAsReference(int length) + throws IOException + { checkArgument(length >= 0); - if(!ensure(length)) + if (!ensure(length)) { throw new EOFException(); + } MessageBuffer ref = buffer.slice(position, length); position += length; return ref; } - - private int readNextLength8() throws IOException { + private int readNextLength8() + throws IOException + { byte u8 = readByte(); return u8 & 0xff; } - private int readNextLength16() throws IOException { + private int readNextLength16() + throws IOException + { short u16 = readShort(); return u16 & 0xffff; } - private int readNextLength32() throws IOException { + private int readNextLength32() + throws IOException + { int u32 = readInt(); - if(u32 < 0) { + if (u32 < 0) { throw overflowU32Size(u32); } return u32; } @Override - public void close() throws IOException { + public void close() + throws IOException + { in.close(); } - private static MessageIntegerOverflowException overflowU8(byte u8) { + private static MessageIntegerOverflowException overflowU8(byte u8) + { BigInteger bi = BigInteger.valueOf((long) (u8 & 0xff)); return new MessageIntegerOverflowException(bi); } - private static MessageIntegerOverflowException overflowU16(short u16) { + private static MessageIntegerOverflowException overflowU16(short u16) + { BigInteger bi = BigInteger.valueOf((long) (u16 & 0xffff)); return new MessageIntegerOverflowException(bi); } - private static MessageIntegerOverflowException overflowU32(int u32) { + private static MessageIntegerOverflowException overflowU32(int u32) + { BigInteger bi = BigInteger.valueOf((long) (u32 & 0x7fffffff) + 0x80000000L); return new MessageIntegerOverflowException(bi); } - private static MessageIntegerOverflowException overflowU64(long u64) { + private static MessageIntegerOverflowException overflowU64(long u64) + { BigInteger bi = BigInteger.valueOf(u64 + Long.MAX_VALUE + 1L).setBit(63); return new MessageIntegerOverflowException(bi); } - private static MessageIntegerOverflowException overflowI16(short i16) { + private static MessageIntegerOverflowException overflowI16(short i16) + { BigInteger bi = BigInteger.valueOf((long) i16); return new MessageIntegerOverflowException(bi); } - private static MessageIntegerOverflowException overflowI32(int i32) { + private static MessageIntegerOverflowException overflowI32(int i32) + { BigInteger bi = BigInteger.valueOf((long) i32); return new MessageIntegerOverflowException(bi); } - private static MessageIntegerOverflowException overflowI64(long i64) { + private static MessageIntegerOverflowException overflowI64(long i64) + { BigInteger bi = BigInteger.valueOf(i64); return new MessageIntegerOverflowException(bi); } - private static MessageSizeException overflowU32Size(int u32) { + private static MessageSizeException overflowU32Size(int u32) + { long lv = (long) (u32 & 0x7fffffff) + 0x80000000L; return new MessageSizeException(lv); } - - } diff --git a/msgpack-core/src/main/java/org/msgpack/core/Preconditions.java b/msgpack-core/src/main/java/org/msgpack/core/Preconditions.java index b2b72f1c4..b1ad967b8 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/Preconditions.java +++ b/msgpack-core/src/main/java/org/msgpack/core/Preconditions.java @@ -15,7 +15,6 @@ */ package org.msgpack.core; - import org.msgpack.core.annotations.Nullable; import org.msgpack.core.annotations.VisibleForTesting; @@ -56,7 +55,8 @@ * @author Kevin Bourrillion * @since 2.0 (imported from Google Collections Library) */ -public final class Preconditions { +public final class Preconditions +{ private Preconditions() {} /** @@ -66,7 +66,8 @@ private Preconditions() {} * @param expression a boolean expression * @throws IllegalArgumentException if {@code expression} is false */ - public static void checkArgument(boolean expression) { + public static void checkArgument(boolean expression) + { if (!expression) { throw new IllegalArgumentException(); } @@ -78,11 +79,12 @@ public static void checkArgument(boolean expression) { * * @param expression a boolean expression * @param errorMessage the exception message to use if the check fails; will - * be converted to a string using {@link String#valueOf(Object)} + * be converted to a string using {@link String#valueOf(Object)} * @throws IllegalArgumentException if {@code expression} is false */ public static void checkArgument( - boolean expression, @Nullable Object errorMessage) { + boolean expression, @Nullable Object errorMessage) + { if (!expression) { throw new IllegalArgumentException(String.valueOf(errorMessage)); } @@ -94,22 +96,23 @@ public static void checkArgument( * * @param expression a boolean expression * @param errorMessageTemplate a template for the exception message should the - * check fail. The message is formed by replacing each {@code %s} - * placeholder in the template with an argument. These are matched by - * position - the first {@code %s} gets {@code errorMessageArgs[0]}, etc. - * Unmatched arguments will be appended to the formatted message in square - * braces. Unmatched placeholders will be left as-is. + * check fail. The message is formed by replacing each {@code %s} + * placeholder in the template with an argument. These are matched by + * position - the first {@code %s} gets {@code errorMessageArgs[0]}, etc. + * Unmatched arguments will be appended to the formatted message in square + * braces. Unmatched placeholders will be left as-is. * @param errorMessageArgs the arguments to be substituted into the message - * template. Arguments are converted to strings using - * {@link String#valueOf(Object)}. + * template. Arguments are converted to strings using + * {@link String#valueOf(Object)}. * @throws IllegalArgumentException if {@code expression} is false * @throws NullPointerException if the check fails and either {@code - * errorMessageTemplate} or {@code errorMessageArgs} is null (don't let - * this happen) + * errorMessageTemplate} or {@code errorMessageArgs} is null (don't let + * this happen) */ public static void checkArgument(boolean expression, - @Nullable String errorMessageTemplate, - @Nullable Object... errorMessageArgs) { + @Nullable String errorMessageTemplate, + @Nullable Object... errorMessageArgs) + { if (!expression) { throw new IllegalArgumentException( format(errorMessageTemplate, errorMessageArgs)); @@ -123,7 +126,8 @@ public static void checkArgument(boolean expression, * @param expression a boolean expression * @throws IllegalStateException if {@code expression} is false */ - public static void checkState(boolean expression) { + public static void checkState(boolean expression) + { if (!expression) { throw new IllegalStateException(); } @@ -135,11 +139,12 @@ public static void checkState(boolean expression) { * * @param expression a boolean expression * @param errorMessage the exception message to use if the check fails; will - * be converted to a string using {@link String#valueOf(Object)} + * be converted to a string using {@link String#valueOf(Object)} * @throws IllegalStateException if {@code expression} is false */ public static void checkState( - boolean expression, @Nullable Object errorMessage) { + boolean expression, @Nullable Object errorMessage) + { if (!expression) { throw new IllegalStateException(String.valueOf(errorMessage)); } @@ -151,22 +156,23 @@ public static void checkState( * * @param expression a boolean expression * @param errorMessageTemplate a template for the exception message should the - * check fail. The message is formed by replacing each {@code %s} - * placeholder in the template with an argument. These are matched by - * position - the first {@code %s} gets {@code errorMessageArgs[0]}, etc. - * Unmatched arguments will be appended to the formatted message in square - * braces. Unmatched placeholders will be left as-is. + * check fail. The message is formed by replacing each {@code %s} + * placeholder in the template with an argument. These are matched by + * position - the first {@code %s} gets {@code errorMessageArgs[0]}, etc. + * Unmatched arguments will be appended to the formatted message in square + * braces. Unmatched placeholders will be left as-is. * @param errorMessageArgs the arguments to be substituted into the message - * template. Arguments are converted to strings using - * {@link String#valueOf(Object)}. + * template. Arguments are converted to strings using + * {@link String#valueOf(Object)}. * @throws IllegalStateException if {@code expression} is false * @throws NullPointerException if the check fails and either {@code - * errorMessageTemplate} or {@code errorMessageArgs} is null (don't let - * this happen) + * errorMessageTemplate} or {@code errorMessageArgs} is null (don't let + * this happen) */ public static void checkState(boolean expression, - @Nullable String errorMessageTemplate, - @Nullable Object... errorMessageArgs) { + @Nullable String errorMessageTemplate, + @Nullable Object... errorMessageArgs) + { if (!expression) { throw new IllegalStateException( format(errorMessageTemplate, errorMessageArgs)); @@ -181,7 +187,8 @@ public static void checkState(boolean expression, * @return the non-null reference that was validated * @throws NullPointerException if {@code reference} is null */ - public static T checkNotNull(T reference) { + public static T checkNotNull(T reference) + { if (reference == null) { throw new NullPointerException(); } @@ -194,11 +201,12 @@ public static T checkNotNull(T reference) { * * @param reference an object reference * @param errorMessage the exception message to use if the check fails; will - * be converted to a string using {@link String#valueOf(Object)} + * be converted to a string using {@link String#valueOf(Object)} * @return the non-null reference that was validated * @throws NullPointerException if {@code reference} is null */ - public static T checkNotNull(T reference, @Nullable Object errorMessage) { + public static T checkNotNull(T reference, @Nullable Object errorMessage) + { if (reference == null) { throw new NullPointerException(String.valueOf(errorMessage)); } @@ -211,20 +219,21 @@ public static T checkNotNull(T reference, @Nullable Object errorMessage) { * * @param reference an object reference * @param errorMessageTemplate a template for the exception message should the - * check fail. The message is formed by replacing each {@code %s} - * placeholder in the template with an argument. These are matched by - * position - the first {@code %s} gets {@code errorMessageArgs[0]}, etc. - * Unmatched arguments will be appended to the formatted message in square - * braces. Unmatched placeholders will be left as-is. + * check fail. The message is formed by replacing each {@code %s} + * placeholder in the template with an argument. These are matched by + * position - the first {@code %s} gets {@code errorMessageArgs[0]}, etc. + * Unmatched arguments will be appended to the formatted message in square + * braces. Unmatched placeholders will be left as-is. * @param errorMessageArgs the arguments to be substituted into the message - * template. Arguments are converted to strings using - * {@link String#valueOf(Object)}. + * template. Arguments are converted to strings using + * {@link String#valueOf(Object)}. * @return the non-null reference that was validated * @throws NullPointerException if {@code reference} is null */ public static T checkNotNull(T reference, - @Nullable String errorMessageTemplate, - @Nullable Object... errorMessageArgs) { + @Nullable String errorMessageTemplate, + @Nullable Object... errorMessageArgs) + { if (reference == null) { // If either of these parameters is null, the right thing happens anyway throw new NullPointerException( @@ -268,14 +277,15 @@ public static T checkNotNull(T reference, * inclusive, to {@code size}, exclusive. * * @param index a user-supplied index identifying an element of an array, list - * or string + * or string * @param size the size of that array, list or string * @return the value of {@code index} * @throws IndexOutOfBoundsException if {@code index} is negative or is not - * less than {@code size} + * less than {@code size} * @throws IllegalArgumentException if {@code size} is negative */ - public static int checkElementIndex(int index, int size) { + public static int checkElementIndex(int index, int size) + { return checkElementIndex(index, size, "index"); } @@ -285,16 +295,17 @@ public static int checkElementIndex(int index, int size) { * inclusive, to {@code size}, exclusive. * * @param index a user-supplied index identifying an element of an array, list - * or string + * or string * @param size the size of that array, list or string * @param desc the text to use to describe this index in an error message * @return the value of {@code index} * @throws IndexOutOfBoundsException if {@code index} is negative or is not - * less than {@code size} + * less than {@code size} * @throws IllegalArgumentException if {@code size} is negative */ public static int checkElementIndex( - int index, int size, @Nullable String desc) { + int index, int size, @Nullable String desc) + { // Carefully optimized for execution by hotspot (explanatory comment above) if (index < 0 || index >= size) { throw new IndexOutOfBoundsException(badElementIndex(index, size, desc)); @@ -302,12 +313,15 @@ public static int checkElementIndex( return index; } - private static String badElementIndex(int index, int size, String desc) { + private static String badElementIndex(int index, int size, String desc) + { if (index < 0) { return format("%s (%s) must not be negative", desc, index); - } else if (size < 0) { + } + else if (size < 0) { throw new IllegalArgumentException("negative size: " + size); - } else { // index >= size + } + else { // index >= size return format("%s (%s) must be less than size (%s)", desc, index, size); } } @@ -318,14 +332,15 @@ private static String badElementIndex(int index, int size, String desc) { * to {@code size}, inclusive. * * @param index a user-supplied index identifying a position in an array, list - * or string + * or string * @param size the size of that array, list or string * @return the value of {@code index} * @throws IndexOutOfBoundsException if {@code index} is negative or is - * greater than {@code size} + * greater than {@code size} * @throws IllegalArgumentException if {@code size} is negative */ - public static int checkPositionIndex(int index, int size) { + public static int checkPositionIndex(int index, int size) + { return checkPositionIndex(index, size, "index"); } @@ -335,16 +350,17 @@ public static int checkPositionIndex(int index, int size) { * to {@code size}, inclusive. * * @param index a user-supplied index identifying a position in an array, list - * or string + * or string * @param size the size of that array, list or string * @param desc the text to use to describe this index in an error message * @return the value of {@code index} * @throws IndexOutOfBoundsException if {@code index} is negative or is - * greater than {@code size} + * greater than {@code size} * @throws IllegalArgumentException if {@code size} is negative */ public static int checkPositionIndex( - int index, int size, @Nullable String desc) { + int index, int size, @Nullable String desc) + { // Carefully optimized for execution by hotspot (explanatory comment above) if (index < 0 || index > size) { throw new IndexOutOfBoundsException(badPositionIndex(index, size, desc)); @@ -352,12 +368,15 @@ public static int checkPositionIndex( return index; } - private static String badPositionIndex(int index, int size, String desc) { + private static String badPositionIndex(int index, int size, String desc) + { if (index < 0) { return format("%s (%s) must not be negative", desc, index); - } else if (size < 0) { + } + else if (size < 0) { throw new IllegalArgumentException("negative size: " + size); - } else { // index > size + } + else { // index > size return format("%s (%s) must not be greater than size (%s)", desc, index, size); } @@ -369,22 +388,24 @@ private static String badPositionIndex(int index, int size, String desc) { * position index may range from zero to {@code size}, inclusive. * * @param start a user-supplied index identifying a starting position in an - * array, list or string + * array, list or string * @param end a user-supplied index identifying a ending position in an array, - * list or string + * list or string * @param size the size of that array, list or string * @throws IndexOutOfBoundsException if either index is negative or is - * greater than {@code size}, or if {@code end} is less than {@code start} + * greater than {@code size}, or if {@code end} is less than {@code start} * @throws IllegalArgumentException if {@code size} is negative */ - public static void checkPositionIndexes(int start, int end, int size) { + public static void checkPositionIndexes(int start, int end, int size) + { // Carefully optimized for execution by hotspot (explanatory comment above) if (start < 0 || end < start || end > size) { throw new IndexOutOfBoundsException(badPositionIndexes(start, end, size)); } } - private static String badPositionIndexes(int start, int end, int size) { + private static String badPositionIndexes(int start, int end, int size) + { if (start < 0 || start > size) { return badPositionIndex(start, size, "start index"); } @@ -403,14 +424,15 @@ private static String badPositionIndexes(int start, int end, int size) { * be appended to the end of the formatted message in square braces. * * @param template a non-null string containing 0 or more {@code %s} - * placeholders. + * placeholders. * @param args the arguments to be substituted into the message - * template. Arguments are converted to strings using - * {@link String#valueOf(Object)}. Arguments can be null. + * template. Arguments are converted to strings using + * {@link String#valueOf(Object)}. Arguments can be null. */ @VisibleForTesting static String format(String template, - @Nullable Object... args) { + @Nullable Object... args) + { template = String.valueOf(template); // null -> "null" // start substituting the arguments into the '%s' placeholders @@ -442,4 +464,4 @@ static String format(String template, return builder.toString(); } -} \ No newline at end of file +} diff --git a/msgpack-core/src/main/java/org/msgpack/core/annotations/Insecure.java b/msgpack-core/src/main/java/org/msgpack/core/annotations/Insecure.java index 11d0fade3..e66f20b8b 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/annotations/Insecure.java +++ b/msgpack-core/src/main/java/org/msgpack/core/annotations/Insecure.java @@ -3,5 +3,6 @@ /** * Annotates a code which must be used carefully. */ -public @interface Insecure { +public @interface Insecure +{ } diff --git a/msgpack-core/src/main/java/org/msgpack/core/annotations/Nullable.java b/msgpack-core/src/main/java/org/msgpack/core/annotations/Nullable.java index 0871b6ec1..45146c203 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/annotations/Nullable.java +++ b/msgpack-core/src/main/java/org/msgpack/core/annotations/Nullable.java @@ -3,5 +3,6 @@ /** * Annotates a field which can be null */ -public @interface Nullable { +public @interface Nullable +{ } diff --git a/msgpack-core/src/main/java/org/msgpack/core/annotations/VisibleForTesting.java b/msgpack-core/src/main/java/org/msgpack/core/annotations/VisibleForTesting.java index 3c9876851..360f22c44 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/annotations/VisibleForTesting.java +++ b/msgpack-core/src/main/java/org/msgpack/core/annotations/VisibleForTesting.java @@ -3,5 +3,6 @@ /** * Annotates a code which is used only for testing. */ -public @interface VisibleForTesting { +public @interface VisibleForTesting +{ } diff --git a/msgpack-core/src/main/java/org/msgpack/core/buffer/ArrayBufferInput.java b/msgpack-core/src/main/java/org/msgpack/core/buffer/ArrayBufferInput.java index 2a8661fcc..66d6a5c64 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/buffer/ArrayBufferInput.java +++ b/msgpack-core/src/main/java/org/msgpack/core/buffer/ArrayBufferInput.java @@ -1,59 +1,74 @@ package org.msgpack.core.buffer; import java.io.IOException; -import static org.msgpack.core.Preconditions.*; + +import static org.msgpack.core.Preconditions.checkArgument; +import static org.msgpack.core.Preconditions.checkNotNull; /** * MessageBufferInput adapter for byte arrays */ -public class ArrayBufferInput implements MessageBufferInput { - +public class ArrayBufferInput + implements MessageBufferInput +{ private MessageBuffer buffer; private boolean isRead = false; - public ArrayBufferInput(MessageBuffer buf) { + public ArrayBufferInput(MessageBuffer buf) + { this.buffer = checkNotNull(buf, "input buffer is null"); } - public ArrayBufferInput(byte[] arr) { + public ArrayBufferInput(byte[] arr) + { this(arr, 0, arr.length); } - public ArrayBufferInput(byte[] arr, int offset, int length) { + public ArrayBufferInput(byte[] arr, int offset, int length) + { checkArgument(offset + length <= arr.length); this.buffer = MessageBuffer.wrap(checkNotNull(arr, "input array is null")).slice(offset, length); } /** * Reset buffer. This method doesn't close the old resource. + * * @param buf new buffer * @return the old resource */ - public MessageBuffer reset(MessageBuffer buf) { + public MessageBuffer reset(MessageBuffer buf) + { MessageBuffer old = this.buffer; this.buffer = buf; this.isRead = false; return old; } - public void reset(byte[] arr) { + public void reset(byte[] arr) + { reset(MessageBuffer.wrap(checkNotNull(arr, "input array is null"))); } - public void reset(byte[] arr, int offset, int len) { + public void reset(byte[] arr, int offset, int len) + { reset(MessageBuffer.wrap(checkNotNull(arr, "input array is null")).slice(offset, len)); } @Override - public MessageBuffer next() throws IOException { - if(isRead) + public MessageBuffer next() + throws IOException + { + if (isRead) { return null; + } isRead = true; return buffer; } @Override - public void close() throws IOException { + public void close() + throws IOException + { buffer = null; isRead = false; } diff --git a/msgpack-core/src/main/java/org/msgpack/core/buffer/ByteBufferInput.java b/msgpack-core/src/main/java/org/msgpack/core/buffer/ByteBufferInput.java index 3335b2bb2..33c0b0c94 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/buffer/ByteBufferInput.java +++ b/msgpack-core/src/main/java/org/msgpack/core/buffer/ByteBufferInput.java @@ -2,26 +2,31 @@ import java.io.IOException; import java.nio.ByteBuffer; -import static org.msgpack.core.Preconditions.*; + +import static org.msgpack.core.Preconditions.checkNotNull; /** * {@link MessageBufferInput} adapter for {@link java.nio.ByteBuffer} */ -public class ByteBufferInput implements MessageBufferInput { - +public class ByteBufferInput + implements MessageBufferInput +{ private ByteBuffer input; private boolean isRead = false; - public ByteBufferInput(ByteBuffer input) { + public ByteBufferInput(ByteBuffer input) + { this.input = checkNotNull(input, "input ByteBuffer is null"); } /** * Reset buffer. This method doesn't close the old resource. + * * @param input new buffer * @return the old resource */ - public ByteBuffer reset(ByteBuffer input) { + public ByteBuffer reset(ByteBuffer input) + { ByteBuffer old = this.input; this.input = input; isRead = false; @@ -29,17 +34,21 @@ public ByteBuffer reset(ByteBuffer input) { } @Override - public MessageBuffer next() throws IOException { - if(isRead) + public MessageBuffer next() + throws IOException + { + if (isRead) { return null; + } isRead = true; return MessageBuffer.wrap(input); } - @Override - public void close() throws IOException { + public void close() + throws IOException + { // Nothing to do } } diff --git a/msgpack-core/src/main/java/org/msgpack/core/buffer/ChannelBufferInput.java b/msgpack-core/src/main/java/org/msgpack/core/buffer/ChannelBufferInput.java index 409ea4cb3..e6b926b43 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/buffer/ChannelBufferInput.java +++ b/msgpack-core/src/main/java/org/msgpack/core/buffer/ChannelBufferInput.java @@ -4,22 +4,26 @@ import java.nio.ByteBuffer; import java.nio.channels.ReadableByteChannel; -import static org.msgpack.core.Preconditions.*; +import static org.msgpack.core.Preconditions.checkArgument; +import static org.msgpack.core.Preconditions.checkNotNull; /** * {@link MessageBufferInput} adapter for {@link java.nio.channels.ReadableByteChannel} */ -public class ChannelBufferInput implements MessageBufferInput { - +public class ChannelBufferInput + implements MessageBufferInput +{ private ReadableByteChannel channel; private boolean reachedEOF = false; private final int bufferSize; - public ChannelBufferInput(ReadableByteChannel channel) { + public ChannelBufferInput(ReadableByteChannel channel) + { this(channel, 8192); } - public ChannelBufferInput(ReadableByteChannel channel, int bufferSize) { + public ChannelBufferInput(ReadableByteChannel channel, int bufferSize) + { this.channel = checkNotNull(channel, "input channel is null"); checkArgument(bufferSize > 0, "buffer size must be > 0: " + bufferSize); this.bufferSize = bufferSize; @@ -27,10 +31,13 @@ public ChannelBufferInput(ReadableByteChannel channel, int bufferSize) { /** * Reset channel. This method doesn't close the old resource. + * * @param channel new channel * @return the old resource */ - public ReadableByteChannel reset(ReadableByteChannel channel) throws IOException { + public ReadableByteChannel reset(ReadableByteChannel channel) + throws IOException + { ReadableByteChannel old = this.channel; this.channel = channel; this.reachedEOF = false; @@ -38,17 +45,18 @@ public ReadableByteChannel reset(ReadableByteChannel channel) throws IOException } @Override - public MessageBuffer next() throws IOException { - - if(reachedEOF) { + public MessageBuffer next() + throws IOException + { + if (reachedEOF) { return null; } MessageBuffer m = MessageBuffer.newBuffer(bufferSize); ByteBuffer b = m.toByteBuffer(); - while(!reachedEOF && b.remaining() > 0) { + while (!reachedEOF && b.remaining() > 0) { int ret = channel.read(b); - if(ret == -1) { + if (ret == -1) { reachedEOF = true; } } @@ -57,7 +65,9 @@ public MessageBuffer next() throws IOException { } @Override - public void close() throws IOException { + public void close() + throws IOException + { channel.close(); } } diff --git a/msgpack-core/src/main/java/org/msgpack/core/buffer/ChannelBufferOutput.java b/msgpack-core/src/main/java/org/msgpack/core/buffer/ChannelBufferOutput.java index eaf0ebffa..0e1beb79b 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/buffer/ChannelBufferOutput.java +++ b/msgpack-core/src/main/java/org/msgpack/core/buffer/ChannelBufferOutput.java @@ -9,43 +9,53 @@ /** * {@link MessageBufferOutput} adapter for {@link java.nio.channels.WritableByteChannel} */ -public class ChannelBufferOutput implements MessageBufferOutput { - +public class ChannelBufferOutput + implements MessageBufferOutput +{ private WritableByteChannel channel; private MessageBuffer buffer; - public ChannelBufferOutput(WritableByteChannel channel) { + public ChannelBufferOutput(WritableByteChannel channel) + { this.channel = checkNotNull(channel, "output channel is null"); } /** * Reset channel. This method doesn't close the old resource. + * * @param channel new channel * @return the old resource */ - public WritableByteChannel reset(WritableByteChannel channel) throws IOException { + public WritableByteChannel reset(WritableByteChannel channel) + throws IOException + { WritableByteChannel old = this.channel; this.channel = channel; return old; } - @Override - public MessageBuffer next(int bufferSize) throws IOException { - if(buffer == null || buffer.size() != bufferSize) { + public MessageBuffer next(int bufferSize) + throws IOException + { + if (buffer == null || buffer.size() != bufferSize) { buffer = MessageBuffer.newBuffer(bufferSize); } return buffer; } @Override - public void flush(MessageBuffer buf) throws IOException { + public void flush(MessageBuffer buf) + throws IOException + { ByteBuffer bb = buf.toByteBuffer(); channel.write(bb); } @Override - public void close() throws IOException { + public void close() + throws IOException + { channel.close(); } } diff --git a/msgpack-core/src/main/java/org/msgpack/core/buffer/DirectBufferAccess.java b/msgpack-core/src/main/java/org/msgpack/core/buffer/DirectBufferAccess.java index f0e5091b6..49f41c58f 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/buffer/DirectBufferAccess.java +++ b/msgpack-core/src/main/java/org/msgpack/core/buffer/DirectBufferAccess.java @@ -8,16 +8,19 @@ /** * Wraps the difference of access methods to DirectBuffers between Android and others. */ -class DirectBufferAccess { +class DirectBufferAccess +{ + private DirectBufferAccess() + {} - enum DirectBufferConstructorType { + enum DirectBufferConstructorType + { ARGS_LONG_INT_REF, ARGS_LONG_INT, ARGS_INT_INT, ARGS_MB_INT_INT } - static Method mGetAddress; static Method mCleaner; static Method mClean; @@ -40,19 +43,19 @@ enum DirectBufferConstructorType { directByteBufferConstructor = directByteBufferClass.getDeclaredConstructor(long.class, int.class, Object.class); constructorType = DirectBufferConstructorType.ARGS_LONG_INT_REF; } - catch(NoSuchMethodException e0) { + catch (NoSuchMethodException e0) { try { // https://android.googlesource.com/platform/libcore/+/master/luni/src/main/java/java/nio/DirectByteBuffer.java // DirectByteBuffer(long address, int capacity) directByteBufferConstructor = directByteBufferClass.getDeclaredConstructor(long.class, int.class); constructorType = DirectBufferConstructorType.ARGS_LONG_INT; } - catch(NoSuchMethodException e1) { + catch (NoSuchMethodException e1) { try { directByteBufferConstructor = directByteBufferClass.getDeclaredConstructor(int.class, int.class); constructorType = DirectBufferConstructorType.ARGS_INT_INT; } - catch(NoSuchMethodException e2) { + catch (NoSuchMethodException e2) { Class aClass = Class.forName("java.nio.MemoryBlock"); mbWrap = aClass.getDeclaredMethod("wrapFromJni", int.class, long.class); mbWrap.setAccessible(true); @@ -66,8 +69,9 @@ enum DirectBufferConstructorType { directBufferConstructorType = constructorType; memoryBlockWrapFromJni = mbWrap; - if(byteBufferConstructor == null) + if (byteBufferConstructor == null) { throw new RuntimeException("Constructor of DirectByteBuffer is not found"); + } byteBufferConstructor.setAccessible(true); mGetAddress = directByteBufferClass.getDeclaredMethod("address"); @@ -79,40 +83,44 @@ enum DirectBufferConstructorType { mClean = mCleaner.getReturnType().getDeclaredMethod("clean"); mClean.setAccessible(true); } - catch(Exception e) { + catch (Exception e) { throw new RuntimeException(e); } } - static long getAddress(Object base) { + static long getAddress(Object base) + { try { return (Long) mGetAddress.invoke(base); } - catch(IllegalAccessException e) { + catch (IllegalAccessException e) { throw new RuntimeException(e); } - catch(InvocationTargetException e) { + catch (InvocationTargetException e) { throw new RuntimeException(e); } } - static void clean(Object base) { + static void clean(Object base) + { try { Object cleaner = mCleaner.invoke(base); mClean.invoke(cleaner); } - catch(Throwable e) { + catch (Throwable e) { throw new RuntimeException(e); } } - static boolean isDirectByteBufferInstance(Object s) { + static boolean isDirectByteBufferInstance(Object s) + { return directByteBufferClass.isInstance(s); } - static ByteBuffer newByteBuffer(long address, int index, int length, ByteBuffer reference) { + static ByteBuffer newByteBuffer(long address, int index, int length, ByteBuffer reference) + { try { - switch(directBufferConstructorType) { + switch (directBufferConstructorType) { case ARGS_LONG_INT_REF: return (ByteBuffer) byteBufferConstructor.newInstance(address + index, length, reference); case ARGS_LONG_INT: @@ -121,13 +129,13 @@ static ByteBuffer newByteBuffer(long address, int index, int length, ByteBuffer return (ByteBuffer) byteBufferConstructor.newInstance((int) address + index, length); case ARGS_MB_INT_INT: return (ByteBuffer) byteBufferConstructor.newInstance( - memoryBlockWrapFromJni.invoke(null, address + index, length), - length, 0); + memoryBlockWrapFromJni.invoke(null, address + index, length), + length, 0); default: throw new IllegalStateException("Unexpected value"); } } - catch(Throwable e) { + catch (Throwable e) { // Convert checked exception to unchecked exception throw new RuntimeException(e); } diff --git a/msgpack-core/src/main/java/org/msgpack/core/buffer/InputStreamBufferInput.java b/msgpack-core/src/main/java/org/msgpack/core/buffer/InputStreamBufferInput.java index 7ccb61f7c..a05b32bac 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/buffer/InputStreamBufferInput.java +++ b/msgpack-core/src/main/java/org/msgpack/core/buffer/InputStreamBufferInput.java @@ -10,53 +10,62 @@ /** * {@link MessageBufferInput} adapter for {@link InputStream} */ -public class InputStreamBufferInput implements MessageBufferInput { - +public class InputStreamBufferInput + implements MessageBufferInput +{ private InputStream in; private final int bufferSize; private boolean reachedEOF = false; - public static MessageBufferInput newBufferInput(InputStream in) { + public static MessageBufferInput newBufferInput(InputStream in) + { checkNotNull(in, "InputStream is null"); if (in instanceof FileInputStream) { FileChannel channel = ((FileInputStream) in).getChannel(); - if(channel != null) { + if (channel != null) { return new ChannelBufferInput(channel); } } return new InputStreamBufferInput(in); } - public InputStreamBufferInput(InputStream in) { + public InputStreamBufferInput(InputStream in) + { this(in, 8192); } - public InputStreamBufferInput(InputStream in, int bufferSize) { + public InputStreamBufferInput(InputStream in, int bufferSize) + { this.in = checkNotNull(in, "input is null"); this.bufferSize = bufferSize; } /** * Reset Stream. This method doesn't close the old resource. + * * @param in new stream * @return the old resource */ - public InputStream reset(InputStream in) throws IOException { + public InputStream reset(InputStream in) + throws IOException + { InputStream old = this.in; this.in = in; reachedEOF = false; return old; } - @Override - public MessageBuffer next() throws IOException { - if(reachedEOF) + public MessageBuffer next() + throws IOException + { + if (reachedEOF) { return null; + } byte[] buffer = new byte[bufferSize]; int readLen = in.read(buffer); - if(readLen == -1) { + if (readLen == -1) { reachedEOF = true; return null; } @@ -64,12 +73,9 @@ public MessageBuffer next() throws IOException { } @Override - public void close() throws IOException { - try { - in.close(); - } - finally { - - } + public void close() + throws IOException + { + in.close(); } } diff --git a/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBuffer.java b/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBuffer.java index 85775048c..a052d21fa 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBuffer.java +++ b/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBuffer.java @@ -9,7 +9,8 @@ import java.nio.ByteBuffer; import java.nio.ByteOrder; -import static org.msgpack.core.Preconditions.*; +import static org.msgpack.core.Preconditions.checkArgument; +import static org.msgpack.core.Preconditions.checkNotNull; /** * MessageBuffer class is an abstraction of memory for reading/writing message packed data. @@ -19,42 +20,42 @@ * implemented without using any interface method that produces invokeinterface call in JVM. * Compared to invokevirtual, invokeinterface is 30% slower in general because it needs to find a target function from the table. */ -public class MessageBuffer { - +public class MessageBuffer +{ static final boolean isUniversalBuffer; static final Unsafe unsafe; /** * Reference to MessageBuffer Constructors */ - private final static Constructor mbArrConstructor; - private final static Constructor mbBBConstructor; + private static final Constructor mbArrConstructor; + private static final Constructor mbBBConstructor; /** * The offset from the object memory header to its byte array data */ static final int ARRAY_BYTE_BASE_OFFSET; + private static final String UNIVERSAL_MESSAGE_BUFFER = "org.msgpack.core.buffer.MessageBufferU"; + private static final String BIGENDIAN_MESSAGE_BUFFER = "org.msgpack.core.buffer.MessageBufferBE"; + private static final String DEFAULT_MESSAGE_BUFFER = "org.msgpack.core.buffer.MessageBuffer"; + static { boolean useUniversalBuffer = false; Unsafe unsafeInstance = null; int arrayByteBaseOffset = 16; - final String UNIVERSAL_MESSAGE_BUFFER = "org.msgpack.core.buffer.MessageBufferU"; - final String BIGENDIAN_MESSAGE_BUFFER = "org.msgpack.core.buffer.MessageBufferBE"; - final String DEFAULT_MESSAGE_BUFFER = "org.msgpack.core.buffer.MessageBuffer"; - try { // Check java version String javaVersion = System.getProperty("java.specification.version", ""); int dotPos = javaVersion.indexOf('.'); boolean isJavaAtLeast7 = false; - if(dotPos != -1) { + if (dotPos != -1) { try { int major = Integer.parseInt(javaVersion.substring(0, dotPos)); int minor = Integer.parseInt(javaVersion.substring(dotPos + 1)); isJavaAtLeast7 = major > 1 || (major == 1 && minor >= 7); } - catch(NumberFormatException e) { + catch (NumberFormatException e) { e.printStackTrace(System.err); } } @@ -63,7 +64,7 @@ public class MessageBuffer { try { hasUnsafe = Class.forName("sun.misc.Unsafe") != null; } - catch(Exception e) { + catch (Exception e) { } // Detect android VM @@ -74,30 +75,30 @@ public class MessageBuffer { // For Java6, android and JVM that has no Unsafe class, use Universal MessageBuffer useUniversalBuffer = - Boolean.parseBoolean(System.getProperty("msgpack.universal-buffer", "false")) - || isAndroid - || isGAE - || !isJavaAtLeast7 - || !hasUnsafe; + Boolean.parseBoolean(System.getProperty("msgpack.universal-buffer", "false")) + || isAndroid + || isGAE + || !isJavaAtLeast7 + || !hasUnsafe; - if(!useUniversalBuffer) { + if (!useUniversalBuffer) { // Fetch theUnsafe object for Oracle and OpenJDK Field field = Unsafe.class.getDeclaredField("theUnsafe"); field.setAccessible(true); unsafeInstance = (Unsafe) field.get(null); - if(unsafeInstance == null) { + if (unsafeInstance == null) { throw new RuntimeException("Unsafe is unavailable"); } arrayByteBaseOffset = unsafeInstance.arrayBaseOffset(byte[].class); int arrayByteIndexScale = unsafeInstance.arrayIndexScale(byte[].class); // Make sure the VM thinks bytes are only one byte wide - if(arrayByteIndexScale != 1) { + if (arrayByteIndexScale != 1) { throw new IllegalStateException("Byte array index scale must be 1, but is " + arrayByteIndexScale); } } } - catch(Exception e) { + catch (Exception e) { e.printStackTrace(System.err); // Use MessageBufferU useUniversalBuffer = true; @@ -110,7 +111,7 @@ public class MessageBuffer { // Switch MessageBuffer implementation according to the environment isUniversalBuffer = useUniversalBuffer; String bufferClsName; - if(isUniversalBuffer) { + if (isUniversalBuffer) { bufferClsName = UNIVERSAL_MESSAGE_BUFFER; } else { @@ -136,7 +137,7 @@ public class MessageBuffer { mbBBCstr.setAccessible(true); mbBBConstructor = mbBBCstr; } - catch(Exception e){ + catch (Exception e) { e.printStackTrace(System.err); throw new RuntimeException(e); // No more fallback exists if MessageBuffer constructors are inaccessible } @@ -166,9 +167,10 @@ public class MessageBuffer { */ protected final ByteBuffer reference; - static MessageBuffer newOffHeapBuffer(int length) { + static MessageBuffer newOffHeapBuffer(int length) + { // This method is not available in Android OS - if(!isUniversalBuffer) { + if (!isUniversalBuffer) { long address = unsafe.allocateMemory(length); return new MessageBuffer(address, length); } @@ -177,20 +179,24 @@ static MessageBuffer newOffHeapBuffer(int length) { } } - public static MessageBuffer newDirectBuffer(int length) { + public static MessageBuffer newDirectBuffer(int length) + { ByteBuffer m = ByteBuffer.allocateDirect(length); return newMessageBuffer(m); } - public static MessageBuffer newBuffer(int length) { + public static MessageBuffer newBuffer(int length) + { return newMessageBuffer(new byte[length]); } - public static MessageBuffer wrap(byte[] array) { + public static MessageBuffer wrap(byte[] array) + { return newMessageBuffer(array); } - public static MessageBuffer wrap(ByteBuffer bb) { + public static MessageBuffer wrap(ByteBuffer bb) + { return newMessageBuffer(bb).slice(bb.position(), bb.remaining()); } @@ -200,14 +206,15 @@ public static MessageBuffer wrap(ByteBuffer bb) { * @param bb * @return */ - private static MessageBuffer newMessageBuffer(ByteBuffer bb) { + private static MessageBuffer newMessageBuffer(ByteBuffer bb) + { checkNotNull(bb); try { // We need to use reflection to create MessageBuffer instances in order to prevent TypeProfile generation for getInt method. TypeProfile will be // generated to resolve one of the method references when two or more classes overrides the method. return (MessageBuffer) mbBBConstructor.newInstance(bb); } - catch(Exception e) { + catch (Exception e) { throw new RuntimeException(e); } } @@ -218,21 +225,23 @@ private static MessageBuffer newMessageBuffer(ByteBuffer bb) { * @param arr * @return */ - private static MessageBuffer newMessageBuffer(byte[] arr) { + private static MessageBuffer newMessageBuffer(byte[] arr) + { checkNotNull(arr); try { return (MessageBuffer) mbArrConstructor.newInstance(arr); } - catch(Throwable e) { + catch (Throwable e) { throw new RuntimeException(e); } } - public static void releaseBuffer(MessageBuffer buffer) { - if(isUniversalBuffer || buffer.base instanceof byte[]) { + public static void releaseBuffer(MessageBuffer buffer) + { + if (isUniversalBuffer || buffer.base instanceof byte[]) { // We have nothing to do. Wait until the garbage-collector collects this array object } - else if(DirectBufferAccess.isDirectByteBufferInstance(buffer.base)) { + else if (DirectBufferAccess.isDirectByteBufferInstance(buffer.base)) { DirectBufferAccess.clean(buffer.base); } else { @@ -247,7 +256,8 @@ else if(DirectBufferAccess.isDirectByteBufferInstance(buffer.base)) { * @param address * @param length */ - MessageBuffer(long address, int length) { + MessageBuffer(long address, int length) + { this.base = null; this.address = address; this.size = length; @@ -259,9 +269,10 @@ else if(DirectBufferAccess.isDirectByteBufferInstance(buffer.base)) { * * @param bb */ - MessageBuffer(ByteBuffer bb) { - if(bb.isDirect()) { - if(isUniversalBuffer) { + MessageBuffer(ByteBuffer bb) + { + if (bb.isDirect()) { + if (isUniversalBuffer) { throw new IllegalStateException("Cannot create MessageBuffer from DirectBuffer"); } // Direct buffer or off-heap memory @@ -270,7 +281,7 @@ else if(DirectBufferAccess.isDirectByteBufferInstance(buffer.base)) { this.size = bb.capacity(); this.reference = bb; } - else if(bb.hasArray()) { + else if (bb.hasArray()) { this.base = bb.array(); this.address = ARRAY_BYTE_BASE_OFFSET; this.size = bb.array().length; @@ -281,20 +292,21 @@ else if(bb.hasArray()) { } } - /** * Create a MessageBuffer instance from an java heap array * * @param arr */ - MessageBuffer(byte[] arr) { + MessageBuffer(byte[] arr) + { this.base = arr; this.address = ARRAY_BYTE_BASE_OFFSET; this.size = arr.length; this.reference = null; } - MessageBuffer(Object base, long address, int length, ByteBuffer reference) { + MessageBuffer(Object base, long address, int length, ByteBuffer reference) + { this.base = base; this.address = address; this.size = length; @@ -306,29 +318,35 @@ else if(bb.hasArray()) { * * @return */ - public int size() { + public int size() + { return size; } - public MessageBuffer slice(int offset, int length) { + public MessageBuffer slice(int offset, int length) + { // TODO ensure deleting this slice does not collapse this MessageBuffer - if(offset == 0 && length == size()) + if (offset == 0 && length == size()) { return this; + } else { checkArgument(offset + length <= size()); return new MessageBuffer(base, address + offset, length, reference); } } - public byte getByte(int index) { + public byte getByte(int index) + { return unsafe.getByte(base, address + index); } - public boolean getBoolean(int index) { + public boolean getBoolean(int index) + { return unsafe.getBoolean(base, address + index); } - public short getShort(int index) { + public short getShort(int index) + { short v = unsafe.getShort(base, address + index); return Short.reverseBytes(v); } @@ -339,46 +357,56 @@ public short getShort(int index) { * @param index * @return */ - public int getInt(int index) { + public int getInt(int index) + { // Reading little-endian value int i = unsafe.getInt(base, address + index); // Reversing the endian return Integer.reverseBytes(i); } - public float getFloat(int index) { + public float getFloat(int index) + { return Float.intBitsToFloat(getInt(index)); } - public long getLong(int index) { + public long getLong(int index) + { long l = unsafe.getLong(base, address + index); return Long.reverseBytes(l); } - public double getDouble(int index) { + public double getDouble(int index) + { return Double.longBitsToDouble(getLong(index)); } - public void getBytes(int index, byte[] dst, int dstOffset, int length) { + public void getBytes(int index, byte[] dst, int dstOffset, int length) + { unsafe.copyMemory(base, address + index, dst, ARRAY_BYTE_BASE_OFFSET + dstOffset, length); } - public void getBytes(int index, int len, ByteBuffer dst) { - if(dst.remaining() > len) + public void getBytes(int index, int len, ByteBuffer dst) + { + if (dst.remaining() > len) { throw new BufferOverflowException(); + } ByteBuffer src = toByteBuffer(index, len); dst.put(src); } - public void putByte(int index, byte v) { + public void putByte(int index, byte v) + { unsafe.putByte(base, address + index, v); } - public void putBoolean(int index, boolean v) { + public void putBoolean(int index, boolean v) + { unsafe.putBoolean(base, address + index, v); } - public void putShort(int index, short v) { + public void putShort(int index, short v) + { v = Short.reverseBytes(v); unsafe.putShort(base, address + index, v); } @@ -389,49 +417,55 @@ public void putShort(int index, short v) { * @param index * @param v */ - public void putInt(int index, int v) { + public void putInt(int index, int v) + { // Reversing the endian v = Integer.reverseBytes(v); unsafe.putInt(base, address + index, v); } - public void putFloat(int index, float v) { + public void putFloat(int index, float v) + { putInt(index, Float.floatToRawIntBits(v)); } - public void putLong(int index, long l) { + public void putLong(int index, long l) + { // Reversing the endian l = Long.reverseBytes(l); unsafe.putLong(base, address + index, l); } - public void putDouble(int index, double v) { + public void putDouble(int index, double v) + { putLong(index, Double.doubleToRawLongBits(v)); } - public void putBytes(int index, byte[] src, int srcOffset, int length) { + public void putBytes(int index, byte[] src, int srcOffset, int length) + { unsafe.copyMemory(src, ARRAY_BYTE_BASE_OFFSET + srcOffset, base, address + index, length); } - public void putByteBuffer(int index, ByteBuffer src, int len) { + public void putByteBuffer(int index, ByteBuffer src, int len) + { assert (len <= src.remaining()); assert (!isUniversalBuffer); - if(src.isDirect()) { + if (src.isDirect()) { unsafe.copyMemory(null, DirectBufferAccess.getAddress(src) + src.position(), base, address + index, len); src.position(src.position() + len); } - else if(src.hasArray()) { + else if (src.hasArray()) { byte[] srcArray = src.array(); unsafe.copyMemory(srcArray, ARRAY_BYTE_BASE_OFFSET + src.position(), base, address + index, len); src.position(src.position() + len); } else { - if(base != null) { + if (base != null) { src.get((byte[]) base, index, len); } else { - for(int i = 0; i < len; ++i) { + for (int i = 0; i < len; ++i) { unsafe.putByte(base, address + index, src.get()); } } @@ -445,8 +479,9 @@ else if(src.hasArray()) { * @param length * @return */ - public ByteBuffer toByteBuffer(int index, int length) { - if(hasArray()) { + public ByteBuffer toByteBuffer(int index, int length) + { + if (hasArray()) { return ByteBuffer.wrap((byte[]) base, (int) ((address - ARRAY_BYTE_BASE_OFFSET) + index), length); } else { @@ -460,7 +495,8 @@ public ByteBuffer toByteBuffer(int index, int length) { * * @return */ - public ByteBuffer toByteBuffer() { + public ByteBuffer toByteBuffer() + { return toByteBuffer(0, size()); } @@ -469,35 +505,41 @@ public ByteBuffer toByteBuffer() { * * @return */ - public byte[] toByteArray() { + public byte[] toByteArray() + { byte[] b = new byte[size()]; unsafe.copyMemory(base, address, b, ARRAY_BYTE_BASE_OFFSET, size()); return b; } @Insecure - public boolean hasArray() { + public boolean hasArray() + { return base instanceof byte[]; } @Insecure - public byte[] getArray() { + public byte[] getArray() + { return (byte[]) base; } @Insecure - public Object getBase() { + public Object getBase() + { return base; } @Insecure - public long getAddress() { + public long getAddress() + { return address; } @Insecure - public int offset() { - if(hasArray()) { + public int offset() + { + if (hasArray()) { return (int) address - ARRAY_BYTE_BASE_OFFSET; } else { @@ -506,7 +548,8 @@ public int offset() { } @Insecure - public ByteBuffer getReference() { + public ByteBuffer getReference() + { return reference; } @@ -518,18 +561,20 @@ public ByteBuffer getReference() { * @param offset * @param length */ - public void copyTo(int index, MessageBuffer dst, int offset, int length) { + public void copyTo(int index, MessageBuffer dst, int offset, int length) + { unsafe.copyMemory(base, address + index, dst.base, dst.address + offset, length); } - public String toHexString(int offset, int length) { + public String toHexString(int offset, int length) + { StringBuilder s = new StringBuilder(); - for(int i = offset; i < length; ++i) { - if(i != offset) + for (int i = offset; i < length; ++i) { + if (i != offset) { s.append(" "); + } s.append(String.format("%02x", getByte(i))); } return s.toString(); } - } diff --git a/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferBE.java b/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferBE.java index e879e4c81..b1a3ca7b0 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferBE.java +++ b/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferBE.java @@ -9,20 +9,25 @@ * The specification of Message Pack demands writing short/int/float/long/double values in the big-endian format. * In the big-endian machine, we do not need to swap the byte order. */ -public class MessageBufferBE extends MessageBuffer { - - MessageBufferBE(ByteBuffer bb) { +public class MessageBufferBE + extends MessageBuffer +{ + MessageBufferBE(ByteBuffer bb) + { super(bb); } - private MessageBufferBE(Object base, long address, int length, ByteBuffer reference) { + private MessageBufferBE(Object base, long address, int length, ByteBuffer reference) + { super(base, address, length, reference); } @Override - public MessageBufferBE slice(int offset, int length) { - if(offset == 0 && length == size()) + public MessageBufferBE slice(int offset, int length) + { + if (offset == 0 && length == size()) { return this; + } else { checkArgument(offset + length <= size()); return new MessageBufferBE(base, address + offset, length, reference); @@ -30,49 +35,56 @@ public MessageBufferBE slice(int offset, int length) { } @Override - public short getShort(int index) { + public short getShort(int index) + { return unsafe.getShort(base, address + index); } @Override - public int getInt(int index) { + public int getInt(int index) + { // We can simply return the integer value as big-endian value return unsafe.getInt(base, address + index); } - public long getLong(int index) { + public long getLong(int index) + { return unsafe.getLong(base, address + index); } @Override - public float getFloat(int index) { + public float getFloat(int index) + { return unsafe.getFloat(base, address + index); } @Override - public double getDouble(int index) { + public double getDouble(int index) + { return unsafe.getDouble(base, address + index); } @Override - public void putShort(int index, short v) { + public void putShort(int index, short v) + { unsafe.putShort(base, address + index, v); } @Override - public void putInt(int index, int v) { + public void putInt(int index, int v) + { unsafe.putInt(base, address + index, v); } @Override - public void putLong(int index, long v) { + public void putLong(int index, long v) + { unsafe.putLong(base, address + index, v); } @Override - public void putDouble(int index, double v) { + public void putDouble(int index, double v) + { unsafe.putDouble(base, address + index, v); } - - } diff --git a/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferInput.java b/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferInput.java index 447c71798..87478dd91 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferInput.java +++ b/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferInput.java @@ -6,16 +6,15 @@ /** * Provides a sequence of MessageBuffers that contains message packed data. */ -public interface MessageBufferInput extends Closeable { - +public interface MessageBufferInput + extends Closeable +{ /** * Get a next buffer to read. + * * @return the next MessageBuffer, or null if no more buffer is available. * @throws IOException when error occurred when reading the data */ - public MessageBuffer next() throws IOException; - - + public MessageBuffer next() + throws IOException; } - - diff --git a/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferOutput.java b/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferOutput.java index 4b529c44f..218f69f07 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferOutput.java +++ b/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferOutput.java @@ -1,14 +1,14 @@ package org.msgpack.core.buffer; - import java.io.Closeable; import java.io.IOException; /** * Provides a sequence of MessageBuffers for packing the input data */ -public interface MessageBufferOutput extends Closeable { - +public interface MessageBufferOutput + extends Closeable +{ /** * Retrieves the next buffer for writing message packed data * @@ -16,18 +16,16 @@ public interface MessageBufferOutput extends Closeable { * @return * @throws IOException */ - public MessageBuffer next(int bufferSize) throws IOException; + public MessageBuffer next(int bufferSize) + throws IOException; /** * Output the buffer contents. If you need to output a part of the * buffer use {@link MessageBuffer#slice(int, int)} + * * @param buf * @throws IOException */ - public void flush(MessageBuffer buf) throws IOException; - + public void flush(MessageBuffer buf) + throws IOException; } - - - - diff --git a/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferU.java b/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferU.java index 4240ac90b..a6316fce6 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferU.java +++ b/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferU.java @@ -1,30 +1,35 @@ package org.msgpack.core.buffer; - import java.nio.ByteBuffer; import java.nio.ByteOrder; -import static org.msgpack.core.Preconditions.*; +import static org.msgpack.core.Preconditions.checkArgument; +import static org.msgpack.core.Preconditions.checkNotNull; /** * Universal MessageBuffer implementation supporting Java6 and Android. * This buffer always uses ByteBuffer-based memory access */ -public class MessageBufferU extends MessageBuffer { - - public MessageBufferU(ByteBuffer bb) { +public class MessageBufferU + extends MessageBuffer +{ + public MessageBufferU(ByteBuffer bb) + { super(null, 0L, bb.capacity(), bb.order(ByteOrder.BIG_ENDIAN)); checkNotNull(reference); } - MessageBufferU(byte[] arr) { + MessageBufferU(byte[] arr) + { this(ByteBuffer.wrap(arr)); } @Override - public MessageBufferU slice(int offset, int length) { - if(offset == 0 && length == size()) + public MessageBufferU slice(int offset, int length) + { + if (offset == 0 && length == size()) { return this; + } else { checkArgument(offset + length <= size()); try { @@ -38,41 +43,57 @@ public MessageBufferU slice(int offset, int length) { } } - private void resetBufferPosition() { + private void resetBufferPosition() + { reference.position(0); reference.limit(size); } @Override - public byte getByte(int index) { + public byte getByte(int index) + { return reference.get(index); } + @Override - public boolean getBoolean(int index) { + public boolean getBoolean(int index) + { return reference.get(index) != 0; } + @Override - public short getShort(int index) { + public short getShort(int index) + { return reference.getShort(index); } + @Override - public int getInt(int index) { + public int getInt(int index) + { return reference.getInt(index); } + @Override - public float getFloat(int index) { + public float getFloat(int index) + { return reference.getFloat(index); } + @Override - public long getLong(int index) { + public long getLong(int index) + { return reference.getLong(index); } + @Override - public double getDouble(int index) { + public double getDouble(int index) + { return reference.getDouble(index); } + @Override - public void getBytes(int index, int len, ByteBuffer dst) { + public void getBytes(int index, int len, ByteBuffer dst) + { try { reference.position(index); reference.limit(index + len); @@ -82,36 +103,52 @@ public void getBytes(int index, int len, ByteBuffer dst) { resetBufferPosition(); } } + @Override - public void putByte(int index, byte v) { + public void putByte(int index, byte v) + { reference.put(index, v); } + @Override - public void putBoolean(int index, boolean v) { + public void putBoolean(int index, boolean v) + { reference.put(index, v ? (byte) 1 : (byte) 0); } + @Override - public void putShort(int index, short v) { + public void putShort(int index, short v) + { reference.putShort(index, v); } + @Override - public void putInt(int index, int v) { + public void putInt(int index, int v) + { reference.putInt(index, v); } + @Override - public void putFloat(int index, float v) { + public void putFloat(int index, float v) + { reference.putFloat(index, v); } + @Override - public void putLong(int index, long l) { + public void putLong(int index, long l) + { reference.putLong(index, l); } + @Override - public void putDouble(int index, double v) { + public void putDouble(int index, double v) + { reference.putDouble(index, v); } + @Override - public ByteBuffer toByteBuffer(int index, int length) { + public ByteBuffer toByteBuffer(int index, int length) + { try { reference.position(index); reference.limit(index + length); @@ -121,13 +158,16 @@ public ByteBuffer toByteBuffer(int index, int length) { resetBufferPosition(); } } + @Override - public ByteBuffer toByteBuffer() { + public ByteBuffer toByteBuffer() + { return toByteBuffer(0, size); } @Override - public void getBytes(int index, byte[] dst, int dstOffset, int length) { + public void getBytes(int index, byte[] dst, int dstOffset, int length) + { try { reference.position(index); reference.get(dst, dstOffset, length); @@ -138,10 +178,11 @@ public void getBytes(int index, byte[] dst, int dstOffset, int length) { } @Override - public void putByteBuffer(int index, ByteBuffer src, int len) { + public void putByteBuffer(int index, ByteBuffer src, int len) + { assert (len <= src.remaining()); - if(src.hasArray()) { + if (src.hasArray()) { putBytes(index, src.array(), src.position(), len); src.position(src.position() + len); } @@ -159,7 +200,8 @@ public void putByteBuffer(int index, ByteBuffer src, int len) { } @Override - public void putBytes(int index, byte[] src, int srcOffset, int length) { + public void putBytes(int index, byte[] src, int srcOffset, int length) + { try { reference.position(index); reference.put(src, srcOffset, length); @@ -170,7 +212,8 @@ public void putBytes(int index, byte[] src, int srcOffset, int length) { } @Override - public void copyTo(int index, MessageBuffer dst, int offset, int length) { + public void copyTo(int index, MessageBuffer dst, int offset, int length) + { try { reference.position(index); dst.putByteBuffer(offset, reference, length); @@ -179,8 +222,10 @@ public void copyTo(int index, MessageBuffer dst, int offset, int length) { resetBufferPosition(); } } + @Override - public byte[] toByteArray() { + public byte[] toByteArray() + { byte[] b = new byte[size()]; getBytes(0, b, 0, b.length); return b; diff --git a/msgpack-core/src/main/java/org/msgpack/core/buffer/OutputStreamBufferOutput.java b/msgpack-core/src/main/java/org/msgpack/core/buffer/OutputStreamBufferOutput.java index 768c3621d..4deb8528f 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/buffer/OutputStreamBufferOutput.java +++ b/msgpack-core/src/main/java/org/msgpack/core/buffer/OutputStreamBufferOutput.java @@ -8,45 +8,52 @@ /** * MessageBufferOutput adapter for {@link java.io.OutputStream}. */ -public class OutputStreamBufferOutput implements MessageBufferOutput { - +public class OutputStreamBufferOutput + implements MessageBufferOutput +{ private OutputStream out; private MessageBuffer buffer; private byte[] tmpBuf; - public OutputStreamBufferOutput(OutputStream out) { + public OutputStreamBufferOutput(OutputStream out) + { this.out = checkNotNull(out, "output is null"); } /** * Reset Stream. This method doesn't close the old resource. + * * @param out new stream * @return the old resource */ - public OutputStream reset(OutputStream out) throws IOException { + public OutputStream reset(OutputStream out) + throws IOException + { OutputStream old = this.out; this.out = out; return old; } @Override - public MessageBuffer next(int bufferSize) throws IOException { - if(buffer == null || buffer.size != bufferSize) { - return buffer = MessageBuffer.newBuffer(bufferSize); - } - else { - return buffer; + public MessageBuffer next(int bufferSize) + throws IOException + { + if (buffer == null || buffer.size != bufferSize) { + buffer = MessageBuffer.newBuffer(bufferSize); } + return buffer; } @Override - public void flush(MessageBuffer buf) throws IOException { + public void flush(MessageBuffer buf) + throws IOException + { int writeLen = buf.size(); - if(buf.hasArray()) { + if (buf.hasArray()) { out.write(buf.getArray(), buf.offset(), writeLen); } else { - if(tmpBuf == null || tmpBuf.length < writeLen) { + if (tmpBuf == null || tmpBuf.length < writeLen) { tmpBuf = new byte[writeLen]; } buf.getBytes(0, tmpBuf, 0, writeLen); @@ -55,7 +62,9 @@ public void flush(MessageBuffer buf) throws IOException { } @Override - public void close() throws IOException { + public void close() + throws IOException + { try { out.flush(); } diff --git a/msgpack-core/src/main/java/org/msgpack/value/ArrayValue.java b/msgpack-core/src/main/java/org/msgpack/value/ArrayValue.java index bb0d00e41..53fa77099 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/ArrayValue.java +++ b/msgpack-core/src/main/java/org/msgpack/value/ArrayValue.java @@ -15,16 +15,17 @@ // package org.msgpack.value; -import java.util.List; import java.util.Iterator; +import java.util.List; /** * The interface {@code ArrayValue} represents MessagePack's Array type. - * + *

* MessagePack's Array type can represent sequence of values. */ -public interface ArrayValue extends Value, Iterable { - +public interface ArrayValue + extends Value, Iterable +{ /** * Returns number of elements in this array. */ @@ -33,9 +34,8 @@ public interface ArrayValue extends Value, Iterable { /** * Returns the element at the specified position in this array. * - * @throws IndexOutOfBoundsException - * If the index is out of range - * (index < 0 || index >= size()) + * @throws IndexOutOfBoundsException If the index is out of range + * (index < 0 || index >= size()) */ Value get(int index); diff --git a/msgpack-core/src/main/java/org/msgpack/value/BinaryValue.java b/msgpack-core/src/main/java/org/msgpack/value/BinaryValue.java index 43ddcb966..b0c636d9c 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/BinaryValue.java +++ b/msgpack-core/src/main/java/org/msgpack/value/BinaryValue.java @@ -17,10 +17,12 @@ /** * The interface {@code BinaryValue} represents MessagePack's Binary type. - * + *

* MessagePack's Binary type can represent a byte array at most 264-1 bytes. * - * @see org.msgpack.value.RawValue + * @see org.msgpack.value.RawValue */ -public interface BinaryValue extends RawValue { +public interface BinaryValue + extends RawValue +{ } diff --git a/msgpack-core/src/main/java/org/msgpack/value/BooleanValue.java b/msgpack-core/src/main/java/org/msgpack/value/BooleanValue.java index 5b33d3567..f81353907 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/BooleanValue.java +++ b/msgpack-core/src/main/java/org/msgpack/value/BooleanValue.java @@ -17,10 +17,12 @@ /** * The interface {@code BooleanValue} represents MessagePack's Boolean type. - * + *

* MessagePack's Boolean type can represent {@code true} or {@code false}. */ -public interface BooleanValue extends Value { +public interface BooleanValue + extends Value +{ /** * Returns the value as a {@code boolean}. */ diff --git a/msgpack-core/src/main/java/org/msgpack/value/ExtensionValue.java b/msgpack-core/src/main/java/org/msgpack/value/ExtensionValue.java index 12db63f29..43a5e5c08 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/ExtensionValue.java +++ b/msgpack-core/src/main/java/org/msgpack/value/ExtensionValue.java @@ -17,13 +17,15 @@ /** * The interface {@code ExtensionValue} represents MessagePack's Extension type. - * + *

* MessagePack's Extension type can represent represents a tuple of type information and a byte array where type information is an * integer whose meaning is defined by applications. - * + *

* As the type information, applications can use 0 to 127 as the application-specific types. -1 to -128 is reserved for MessagePack's future extension. */ -public interface ExtensionValue extends Value { +public interface ExtensionValue + extends Value +{ byte getType(); byte[] getData(); diff --git a/msgpack-core/src/main/java/org/msgpack/value/FloatValue.java b/msgpack-core/src/main/java/org/msgpack/value/FloatValue.java index 78f6da0e5..306a609fd 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/FloatValue.java +++ b/msgpack-core/src/main/java/org/msgpack/value/FloatValue.java @@ -17,10 +17,12 @@ /** * The interface {@code FloatValue} represents MessagePack's Float type. - * + *

* MessagePack's Float type can represent IEEE 754 double precision floating point numbers including NaN and infinity. This is same with Java's {@code double} type. * - * @see org.msgpack.value.NumberValue + * @see org.msgpack.value.NumberValue */ -public interface FloatValue extends NumberValue { +public interface FloatValue + extends NumberValue +{ } diff --git a/msgpack-core/src/main/java/org/msgpack/value/ImmutableArrayValue.java b/msgpack-core/src/main/java/org/msgpack/value/ImmutableArrayValue.java index 1c0ea24bb..9301c2eb8 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/ImmutableArrayValue.java +++ b/msgpack-core/src/main/java/org/msgpack/value/ImmutableArrayValue.java @@ -15,11 +15,12 @@ // package org.msgpack.value; -import java.util.List; import java.util.Iterator; +import java.util.List; - -public interface ImmutableArrayValue extends ArrayValue, ImmutableValue { +public interface ImmutableArrayValue + extends ArrayValue, ImmutableValue +{ /** * Returns an iterator over elements. * Returned Iterator does not support {@code remove()} method since the value is immutable. diff --git a/msgpack-core/src/main/java/org/msgpack/value/ImmutableBinaryValue.java b/msgpack-core/src/main/java/org/msgpack/value/ImmutableBinaryValue.java index ce52bfc33..475241a57 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/ImmutableBinaryValue.java +++ b/msgpack-core/src/main/java/org/msgpack/value/ImmutableBinaryValue.java @@ -15,5 +15,7 @@ // package org.msgpack.value; -public interface ImmutableBinaryValue extends BinaryValue, ImmutableRawValue { +public interface ImmutableBinaryValue + extends BinaryValue, ImmutableRawValue +{ } diff --git a/msgpack-core/src/main/java/org/msgpack/value/ImmutableBooleanValue.java b/msgpack-core/src/main/java/org/msgpack/value/ImmutableBooleanValue.java index 23b7dbc0b..dd2afad43 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/ImmutableBooleanValue.java +++ b/msgpack-core/src/main/java/org/msgpack/value/ImmutableBooleanValue.java @@ -15,5 +15,7 @@ // package org.msgpack.value; -public interface ImmutableBooleanValue extends BooleanValue, ImmutableValue { +public interface ImmutableBooleanValue + extends BooleanValue, ImmutableValue +{ } diff --git a/msgpack-core/src/main/java/org/msgpack/value/ImmutableExtensionValue.java b/msgpack-core/src/main/java/org/msgpack/value/ImmutableExtensionValue.java index ff1f0e9ea..5e984db05 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/ImmutableExtensionValue.java +++ b/msgpack-core/src/main/java/org/msgpack/value/ImmutableExtensionValue.java @@ -15,5 +15,7 @@ // package org.msgpack.value; -public interface ImmutableExtensionValue extends ExtensionValue, ImmutableValue { +public interface ImmutableExtensionValue + extends ExtensionValue, ImmutableValue +{ } diff --git a/msgpack-core/src/main/java/org/msgpack/value/ImmutableFloatValue.java b/msgpack-core/src/main/java/org/msgpack/value/ImmutableFloatValue.java index bfa6cf114..7105483d1 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/ImmutableFloatValue.java +++ b/msgpack-core/src/main/java/org/msgpack/value/ImmutableFloatValue.java @@ -15,5 +15,7 @@ // package org.msgpack.value; -public interface ImmutableFloatValue extends FloatValue, ImmutableNumberValue { +public interface ImmutableFloatValue + extends FloatValue, ImmutableNumberValue +{ } diff --git a/msgpack-core/src/main/java/org/msgpack/value/ImmutableIntegerValue.java b/msgpack-core/src/main/java/org/msgpack/value/ImmutableIntegerValue.java index b2ab29938..3482583ff 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/ImmutableIntegerValue.java +++ b/msgpack-core/src/main/java/org/msgpack/value/ImmutableIntegerValue.java @@ -15,5 +15,7 @@ // package org.msgpack.value; -public interface ImmutableIntegerValue extends IntegerValue, ImmutableNumberValue { +public interface ImmutableIntegerValue + extends IntegerValue, ImmutableNumberValue +{ } diff --git a/msgpack-core/src/main/java/org/msgpack/value/ImmutableMapValue.java b/msgpack-core/src/main/java/org/msgpack/value/ImmutableMapValue.java index f612f5758..cc3122f03 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/ImmutableMapValue.java +++ b/msgpack-core/src/main/java/org/msgpack/value/ImmutableMapValue.java @@ -15,5 +15,7 @@ // package org.msgpack.value; -public interface ImmutableMapValue extends MapValue, ImmutableValue { +public interface ImmutableMapValue + extends MapValue, ImmutableValue +{ } diff --git a/msgpack-core/src/main/java/org/msgpack/value/ImmutableNilValue.java b/msgpack-core/src/main/java/org/msgpack/value/ImmutableNilValue.java index e4fbf48d4..8a7857287 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/ImmutableNilValue.java +++ b/msgpack-core/src/main/java/org/msgpack/value/ImmutableNilValue.java @@ -15,5 +15,7 @@ // package org.msgpack.value; -public interface ImmutableNilValue extends NilValue, ImmutableValue { +public interface ImmutableNilValue + extends NilValue, ImmutableValue +{ } diff --git a/msgpack-core/src/main/java/org/msgpack/value/ImmutableNumberValue.java b/msgpack-core/src/main/java/org/msgpack/value/ImmutableNumberValue.java index f264d58da..42afcf304 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/ImmutableNumberValue.java +++ b/msgpack-core/src/main/java/org/msgpack/value/ImmutableNumberValue.java @@ -15,5 +15,7 @@ // package org.msgpack.value; -public interface ImmutableNumberValue extends NumberValue, ImmutableValue { +public interface ImmutableNumberValue + extends NumberValue, ImmutableValue +{ } diff --git a/msgpack-core/src/main/java/org/msgpack/value/ImmutableRawValue.java b/msgpack-core/src/main/java/org/msgpack/value/ImmutableRawValue.java index 8fa691fb6..36698dbeb 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/ImmutableRawValue.java +++ b/msgpack-core/src/main/java/org/msgpack/value/ImmutableRawValue.java @@ -15,5 +15,7 @@ // package org.msgpack.value; -public interface ImmutableRawValue extends RawValue, ImmutableValue { +public interface ImmutableRawValue + extends RawValue, ImmutableValue +{ } diff --git a/msgpack-core/src/main/java/org/msgpack/value/ImmutableStringValue.java b/msgpack-core/src/main/java/org/msgpack/value/ImmutableStringValue.java index 10a3ee217..6e3f95360 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/ImmutableStringValue.java +++ b/msgpack-core/src/main/java/org/msgpack/value/ImmutableStringValue.java @@ -15,5 +15,7 @@ // package org.msgpack.value; -public interface ImmutableStringValue extends StringValue, ImmutableRawValue { +public interface ImmutableStringValue + extends StringValue, ImmutableRawValue +{ } diff --git a/msgpack-core/src/main/java/org/msgpack/value/ImmutableValue.java b/msgpack-core/src/main/java/org/msgpack/value/ImmutableValue.java index 88d3bf260..6a5740029 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/ImmutableValue.java +++ b/msgpack-core/src/main/java/org/msgpack/value/ImmutableValue.java @@ -15,9 +15,9 @@ // package org.msgpack.value; -import java.io.Serializable; - -public interface ImmutableValue extends Value { +public interface ImmutableValue + extends Value +{ @Override public ImmutableNilValue asNilValue(); diff --git a/msgpack-core/src/main/java/org/msgpack/value/IntegerValue.java b/msgpack-core/src/main/java/org/msgpack/value/IntegerValue.java index c6cfec721..ca0ffcd33 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/IntegerValue.java +++ b/msgpack-core/src/main/java/org/msgpack/value/IntegerValue.java @@ -16,14 +16,15 @@ package org.msgpack.value; import java.math.BigInteger; -import org.msgpack.core.MessageIntegerOverflowException; /** * The interface {@code IntegerValue} represents MessagePack's Integer type. - * + *

* MessagePack's Integer type can represent from -263 to 264-1. */ -public interface IntegerValue extends NumberValue { +public interface IntegerValue + extends NumberValue +{ /** * Returns true if the value is in the range of [-27 to 27-1]. */ @@ -47,32 +48,28 @@ public interface IntegerValue extends NumberValue { /** * Returns the value as a {@code byte}, otherwise throws an exception. * - * @throws MessageIntegerOverflowException - * If the value does not fit in the range of {@code byte} type. + * @throws MessageIntegerOverflowException If the value does not fit in the range of {@code byte} type. */ byte getByte(); /** * Returns the value as a {@code short}, otherwise throws an exception. * - * @throws MessageIntegerOverflowException - * If the value does not fit in the range of {@code short} type. + * @throws MessageIntegerOverflowException If the value does not fit in the range of {@code short} type. */ short getShort(); /** * Returns the value as an {@code int}, otherwise throws an exception. * - * @throws MessageIntegerOverflowException - * If the value does not fit in the range of {@code int} type. + * @throws MessageIntegerOverflowException If the value does not fit in the range of {@code int} type. */ int getInt(); /** * Returns the value as a {@code long}, otherwise throws an exception. * - * @throws MessageIntegerOverflowException - * If the value does not fit in the range of {@code long} type. + * @throws MessageIntegerOverflowException If the value does not fit in the range of {@code long} type. */ long getLong(); diff --git a/msgpack-core/src/main/java/org/msgpack/value/MapValue.java b/msgpack-core/src/main/java/org/msgpack/value/MapValue.java index b29617c5d..f34e77c60 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/MapValue.java +++ b/msgpack-core/src/main/java/org/msgpack/value/MapValue.java @@ -15,16 +15,18 @@ // package org.msgpack.value; +import java.util.Collection; import java.util.Map; import java.util.Set; -import java.util.Collection; /** * The interface {@code ArrayValue} represents MessagePack's Map type. - * + *

* MessagePack's Map type can represent sequence of key-value pairs. */ -public interface MapValue extends Value { +public interface MapValue + extends Value +{ /** * Returns number of key-value pairs in this array. */ @@ -43,9 +45,9 @@ public interface MapValue extends Value { /** * Returns the key-value pairs as an array of {@code Value}. - * + *

* Odd elements are keys. Next element of an odd element is a value corresponding to the key. - * + *

* For example, if this value represents {"k1": "v1", "k2": "v2"}, this method returns ["k1", "v1", "k2", "v2"]. */ Value[] getKeyValueArray(); diff --git a/msgpack-core/src/main/java/org/msgpack/value/NilValue.java b/msgpack-core/src/main/java/org/msgpack/value/NilValue.java index 56c23a9f9..8f5835001 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/NilValue.java +++ b/msgpack-core/src/main/java/org/msgpack/value/NilValue.java @@ -18,5 +18,7 @@ /** * The interface {@code NilValue} represents MessagePack's Nil type. */ -public interface NilValue extends Value { +public interface NilValue + extends Value +{ } diff --git a/msgpack-core/src/main/java/org/msgpack/value/NumberValue.java b/msgpack-core/src/main/java/org/msgpack/value/NumberValue.java index 785d12581..0a43973ab 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/NumberValue.java +++ b/msgpack-core/src/main/java/org/msgpack/value/NumberValue.java @@ -23,8 +23,9 @@ * @see org.msgpack.value.IntegerValue * @see org.msgpack.value.FloatValue */ -public interface NumberValue extends Value { - +public interface NumberValue + extends Value +{ /** * Represent this value as a byte value, which may involve rounding or truncation of the original value. * the value. diff --git a/msgpack-core/src/main/java/org/msgpack/value/RawValue.java b/msgpack-core/src/main/java/org/msgpack/value/RawValue.java index 748be0845..6d51d1b51 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/RawValue.java +++ b/msgpack-core/src/main/java/org/msgpack/value/RawValue.java @@ -16,27 +16,28 @@ package org.msgpack.value; import java.nio.ByteBuffer; -import org.msgpack.core.MessageStringCodingException; /** * The interface {@code RawValue} represents MessagePack's Raw type, which means Binary or String type. - * + *

* MessagePack's Raw type can represent a byte array at most 264-1 bytes. * - * @see org.msgpack.value.StringValue - * @see org.msgpack.value.BinaryValue + * @see org.msgpack.value.StringValue + * @see org.msgpack.value.BinaryValue */ -public interface RawValue extends Value { +public interface RawValue + extends Value +{ /** * Returns the value as {@code byte[]}. - * + *

* This method copies the byte array. */ byte[] getByteArray(); /** * Returns the value as {@code ByteBuffer}. - * + *

* Returned ByteBuffer is read-only. See {@code#asReadOnlyBuffer()}. * This method doesn't copy the byte array as much as possible. */ @@ -44,17 +45,16 @@ public interface RawValue extends Value { /** * Returns the value as {@code String}. - * + *

* This method throws an exception if the value includes invalid UTF-8 byte sequence. * - * @throws MessageStringCodingException - * If this value includes invalid UTF-8 byte sequence. + * @throws MessageStringCodingException If this value includes invalid UTF-8 byte sequence. */ String getString(); /** * Returns the value as {@code String}. - * + *

* This method replaces an invalid UTF-8 byte sequence with U+FFFD replacement character. */ String stringValue(); diff --git a/msgpack-core/src/main/java/org/msgpack/value/StringValue.java b/msgpack-core/src/main/java/org/msgpack/value/StringValue.java index 0709a22b8..da49cd8f6 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/StringValue.java +++ b/msgpack-core/src/main/java/org/msgpack/value/StringValue.java @@ -17,12 +17,14 @@ /** * The interface {@code StringValue} represents MessagePack's String type. - * + *

* MessagePack's String type can represent a UTF-8 string at most 264-1 bytes. - * + *

* Note that the value could include invalid byte sequences. {@code getString()} method throws {@code MessageTypeStringCodingException} if the value includes invalid byte sequence. {@code stringValue()} method replaces an invalid byte sequence with U+FFFD replacement character. * - * @see org.msgpack.value.RawValue + * @see org.msgpack.value.RawValue */ -public interface StringValue extends RawValue { +public interface StringValue + extends RawValue +{ } diff --git a/msgpack-core/src/main/java/org/msgpack/value/Value.java b/msgpack-core/src/main/java/org/msgpack/value/Value.java index 1cc2f964e..d10d7ba48 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/Value.java +++ b/msgpack-core/src/main/java/org/msgpack/value/Value.java @@ -16,15 +16,14 @@ package org.msgpack.value; import org.msgpack.core.MessagePacker; -import org.msgpack.core.MessageTypeCastException; import java.io.IOException; - /** * Value is an implementation of MessagePack type system. */ -public interface Value { +public interface Value +{ /** * Returns type of this value. *

@@ -233,7 +232,8 @@ public interface Value { * * @see MessagePacker */ - void writeTo(MessagePacker pk) throws IOException; + void writeTo(MessagePacker pk) + throws IOException; /** * Compares this value to the specified object. diff --git a/msgpack-core/src/main/java/org/msgpack/value/ValueFactory.java b/msgpack-core/src/main/java/org/msgpack/value/ValueFactory.java index 8842b6cf4..d229e2659 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/ValueFactory.java +++ b/msgpack-core/src/main/java/org/msgpack/value/ValueFactory.java @@ -15,80 +15,103 @@ // package org.msgpack.value; -import org.msgpack.value.impl.ImmutableNilValueImpl; -import org.msgpack.value.impl.ImmutableBooleanValueImpl; -import org.msgpack.value.impl.ImmutableLongValueImpl; +import org.msgpack.value.impl.ImmutableArrayValueImpl; import org.msgpack.value.impl.ImmutableBigIntegerValueImpl; import org.msgpack.value.impl.ImmutableBinaryValueImpl; +import org.msgpack.value.impl.ImmutableBooleanValueImpl; import org.msgpack.value.impl.ImmutableDoubleValueImpl; -import org.msgpack.value.impl.ImmutableStringValueImpl; -import org.msgpack.value.impl.ImmutableArrayValueImpl; -import org.msgpack.value.impl.ImmutableMapValueImpl; import org.msgpack.value.impl.ImmutableExtensionValueImpl; +import org.msgpack.value.impl.ImmutableLongValueImpl; +import org.msgpack.value.impl.ImmutableMapValueImpl; +import org.msgpack.value.impl.ImmutableNilValueImpl; +import org.msgpack.value.impl.ImmutableStringValueImpl; -import java.util.*; import java.math.BigInteger; +import java.util.AbstractMap; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; -public final class ValueFactory { - private ValueFactory() { } +public final class ValueFactory +{ + private ValueFactory() + { + } - public static ImmutableNilValue newNil() { + public static ImmutableNilValue newNil() + { return ImmutableNilValueImpl.get(); } - public static ImmutableBooleanValue newBoolean(boolean v) { + public static ImmutableBooleanValue newBoolean(boolean v) + { return v ? ImmutableBooleanValueImpl.TRUE : ImmutableBooleanValueImpl.FALSE; } - public static ImmutableIntegerValue newInteger(byte v) { + public static ImmutableIntegerValue newInteger(byte v) + { return new ImmutableLongValueImpl(v); } - public static ImmutableIntegerValue newInteger(short v) { + public static ImmutableIntegerValue newInteger(short v) + { return new ImmutableLongValueImpl(v); } - public static ImmutableIntegerValue newInteger(int v) { + public static ImmutableIntegerValue newInteger(int v) + { return new ImmutableLongValueImpl(v); } - public static ImmutableIntegerValue newInteger(long v) { + public static ImmutableIntegerValue newInteger(long v) + { return new ImmutableLongValueImpl(v); } - public static ImmutableIntegerValue newInteger(BigInteger v) { + public static ImmutableIntegerValue newInteger(BigInteger v) + { return new ImmutableBigIntegerValueImpl(v); } - public static ImmutableFloatValue newFloat(float v) { + public static ImmutableFloatValue newFloat(float v) + { return new ImmutableDoubleValueImpl(v); } - public static ImmutableFloatValue newFloat(double v) { + public static ImmutableFloatValue newFloat(double v) + { return new ImmutableDoubleValueImpl(v); } - public static ImmutableBinaryValue newBinary(byte[] b) { + public static ImmutableBinaryValue newBinary(byte[] b) + { return new ImmutableBinaryValueImpl(b); } - public static ImmutableBinaryValue newBinary(byte[] b, int off, int len) { + public static ImmutableBinaryValue newBinary(byte[] b, int off, int len) + { return new ImmutableBinaryValueImpl(Arrays.copyOfRange(b, off, len)); } - public static ImmutableStringValue newString(String s) { + public static ImmutableStringValue newString(String s) + { return new ImmutableStringValueImpl(s); } - public static ImmutableStringValue newString(byte[] b) { + public static ImmutableStringValue newString(byte[] b) + { return new ImmutableStringValueImpl(b); } - public static ImmutableStringValue newString(byte[] b, int off, int len) { + public static ImmutableStringValue newString(byte[] b, int off, int len) + { return new ImmutableStringValueImpl(Arrays.copyOfRange(b, off, len)); } - public static ImmutableArrayValue newArray(List list) { + public static ImmutableArrayValue newArray(List list) + { if (list.isEmpty()) { return ImmutableArrayValueImpl.empty(); } @@ -96,19 +119,22 @@ public static ImmutableArrayValue newArray(List list) { return new ImmutableArrayValueImpl(array); } - public static ImmutableArrayValue newArray(Value... array) { + public static ImmutableArrayValue newArray(Value... array) + { if (array.length == 0) { return ImmutableArrayValueImpl.empty(); } return new ImmutableArrayValueImpl(Arrays.copyOf(array, array.length)); } - public static ImmutableArrayValue emptyArray() { + public static ImmutableArrayValue emptyArray() + { return ImmutableArrayValueImpl.empty(); } public static - ImmutableMapValue newMap(Map map) { + ImmutableMapValue newMap(Map map) + { Value[] kvs = new Value[map.size() * 2]; Iterator> ite = map.entrySet().iterator(); int index = 0; @@ -122,64 +148,76 @@ ImmutableMapValue newMap(Map map) { return newMap(kvs); } - public static ImmutableMapValue newMap(Value[] kvs) { + public static ImmutableMapValue newMap(Value[] kvs) + { if (kvs.length == 0) { return ImmutableMapValueImpl.empty(); } return new ImmutableMapValueImpl(Arrays.copyOf(kvs, kvs.length)); } - public static ImmutableMapValue emptyMap() { + public static ImmutableMapValue emptyMap() + { return ImmutableMapValueImpl.empty(); } - public static MapValue newMap(Map.Entry... pairs) { + public static MapValue newMap(Map.Entry... pairs) + { MapBuilder b = new MapBuilder(); - for(Map.Entry p : pairs) { + for (Map.Entry p : pairs) { b.put(p); } return b.build(); } - public static MapBuilder newMapBuilder() { + public static MapBuilder newMapBuilder() + { return new MapBuilder(); } - public static Map.Entry newMapEntry(Value key, Value value) { + public static Map.Entry newMapEntry(Value key, Value value) + { return new AbstractMap.SimpleEntry(key, value); } - public static class MapBuilder { + public static class MapBuilder + { private final Map map = new HashMap(); public MapBuilder() {} - public MapValue build() { + public MapValue build() + { return newMap(map); } - public void put(Map.Entry pair) { + public void put(Map.Entry pair) + { put(pair.getKey(), pair.getValue()); } - public void put(Value key, Value value) { + public void put(Value key, Value value) + { map.put(key, value); } - public void putAll(Iterable> entries){ - for(Map.Entry entry : entries) { + public void putAll(Iterable> entries) + { + for (Map.Entry entry : entries) { put(entry.getKey(), entry.getValue()); } } - public void putAll(Map map) { - for(Map.Entry entry : map.entrySet()) { + public void putAll(Map map) + { + for (Map.Entry entry : map.entrySet()) { put(entry); } } } - public static ImmutableExtensionValue newExtension(byte type, byte[] data) { + public static ImmutableExtensionValue newExtension(byte type, byte[] data) + { return new ImmutableExtensionValueImpl(type, data); } } diff --git a/msgpack-core/src/main/java/org/msgpack/value/ValueType.java b/msgpack-core/src/main/java/org/msgpack/value/ValueType.java index c04916635..715ebbd18 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/ValueType.java +++ b/msgpack-core/src/main/java/org/msgpack/value/ValueType.java @@ -15,13 +15,11 @@ // package org.msgpack.value; -import org.msgpack.core.MessageFormat; - /** * MessageTypeFamily is a group of {@link org.msgpack.core.MessageFormat}s */ -public enum ValueType { - +public enum ValueType +{ NIL(false, false), BOOLEAN(false, false), INTEGER(true, false), @@ -35,52 +33,64 @@ public enum ValueType { private final boolean numberType; private final boolean rawType; - private ValueType(boolean numberType, boolean rawType) { + private ValueType(boolean numberType, boolean rawType) + { this.numberType = numberType; this.rawType = rawType; } - public boolean isNilType() { + public boolean isNilType() + { return this == NIL; } - public boolean isBooleanType() { + public boolean isBooleanType() + { return this == BOOLEAN; } - public boolean isNumberType() { + public boolean isNumberType() + { return numberType; } - public boolean isIntegerType() { + public boolean isIntegerType() + { return this == INTEGER; } - public boolean isFloatType() { + public boolean isFloatType() + { return this == FLOAT; } - public boolean isRawType() { + public boolean isRawType() + { return rawType; } - public boolean isStringType() { + public boolean isStringType() + { return this == STRING; } - public boolean isBinaryType() { + public boolean isBinaryType() + { return this == BINARY; } - public boolean isArrayType() { + public boolean isArrayType() + { return this == ARRAY; } - public boolean isMapType() { + public boolean isMapType() + { return this == MAP; } - public boolean isExtensionType() { + public boolean isExtensionType() + { return this == EXTENSION; } } diff --git a/msgpack-core/src/main/java/org/msgpack/value/Variable.java b/msgpack-core/src/main/java/org/msgpack/value/Variable.java index 227626ea8..7cd164336 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/Variable.java +++ b/msgpack-core/src/main/java/org/msgpack/value/Variable.java @@ -15,155 +15,184 @@ // package org.msgpack.value; +import org.msgpack.core.MessageIntegerOverflowException; import org.msgpack.core.MessagePack; import org.msgpack.core.MessagePacker; -import org.msgpack.core.MessageTypeCastException; import org.msgpack.core.MessageStringCodingException; -import org.msgpack.core.MessageIntegerOverflowException; +import org.msgpack.core.MessageTypeCastException; +import java.io.IOException; import java.math.BigDecimal; import java.math.BigInteger; -import java.util.List; -import java.util.Set; -import java.util.Map; -import java.util.Collection; -import java.util.Iterator; -import java.io.IOException; import java.nio.ByteBuffer; +import java.nio.charset.CharacterCodingException; import java.nio.charset.CharsetDecoder; import java.nio.charset.CodingErrorAction; -import java.nio.charset.CharacterCodingException; - +import java.util.Collection; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; -public class Variable implements Value { - private abstract class AbstractValueAccessor implements Value { +public class Variable + implements Value +{ + private abstract class AbstractValueAccessor + implements Value + { @Override - public boolean isNilValue() { + public boolean isNilValue() + { return getValueType().isNilType(); } @Override - public boolean isBooleanValue() { + public boolean isBooleanValue() + { return getValueType().isBooleanType(); } @Override - public boolean isNumberValue() { + public boolean isNumberValue() + { return getValueType().isNumberType(); } @Override - public boolean isIntegerValue() { + public boolean isIntegerValue() + { return getValueType().isIntegerType(); } @Override - public boolean isFloatValue() { + public boolean isFloatValue() + { return getValueType().isFloatType(); } @Override - public boolean isRawValue() { + public boolean isRawValue() + { return getValueType().isRawType(); } @Override - public boolean isBinaryValue() { + public boolean isBinaryValue() + { return getValueType().isBinaryType(); } @Override - public boolean isStringValue() { + public boolean isStringValue() + { return getValueType().isStringType(); } @Override - public boolean isArrayValue() { + public boolean isArrayValue() + { return getValueType().isArrayType(); } @Override - public boolean isMapValue() { + public boolean isMapValue() + { return getValueType().isMapType(); } @Override - public boolean isExtensionValue() { + public boolean isExtensionValue() + { return getValueType().isExtensionType(); } @Override - public NilValue asNilValue() { + public NilValue asNilValue() + { throw new MessageTypeCastException(); } @Override - public BooleanValue asBooleanValue() { + public BooleanValue asBooleanValue() + { throw new MessageTypeCastException(); } @Override - public NumberValue asNumberValue() { + public NumberValue asNumberValue() + { throw new MessageTypeCastException(); } @Override - public IntegerValue asIntegerValue() { + public IntegerValue asIntegerValue() + { throw new MessageTypeCastException(); } @Override - public FloatValue asFloatValue() { + public FloatValue asFloatValue() + { throw new MessageTypeCastException(); } @Override - public RawValue asRawValue() { + public RawValue asRawValue() + { throw new MessageTypeCastException(); } @Override - public BinaryValue asBinaryValue() { + public BinaryValue asBinaryValue() + { throw new MessageTypeCastException(); } @Override - public StringValue asStringValue() { + public StringValue asStringValue() + { throw new MessageTypeCastException(); } @Override - public ArrayValue asArrayValue() { + public ArrayValue asArrayValue() + { throw new MessageTypeCastException(); } @Override - public MapValue asMapValue() { + public MapValue asMapValue() + { throw new MessageTypeCastException(); } @Override - public ExtensionValue asExtensionValue() { + public ExtensionValue asExtensionValue() + { throw new MessageTypeCastException(); } @Override - public boolean equals(Object obj) { + public boolean equals(Object obj) + { return Variable.this.equals(obj); } @Override - public int hashCode() { + public int hashCode() + { return Variable.this.hashCode(); } @Override - public String toString() { + public String toString() + { return Variable.this.toString(); } } - public static enum Type { + public static enum Type + { NULL(ValueType.NIL), BOOLEAN(ValueType.BOOLEAN), LONG(ValueType.INTEGER), @@ -177,11 +206,13 @@ public static enum Type { private final ValueType valueType; - private Type(ValueType valueType) { + private Type(ValueType valueType) + { this.valueType = valueType; } - public ValueType getValueType() { + public ValueType getValueType() + { return valueType; } } @@ -204,83 +235,100 @@ public ValueType getValueType() { private AbstractValueAccessor accessor; - public Variable() { + public Variable() + { setNilValue(); } - //// // NilValue // - public Variable setNilValue() { + public Variable setNilValue() + { this.type = Type.NULL; this.accessor = nilAccessor; return this; } - private class NilValueAccessor extends AbstractValueAccessor implements NilValue { + private class NilValueAccessor + extends AbstractValueAccessor + implements NilValue + { @Override - public ValueType getValueType() { + public ValueType getValueType() + { return ValueType.NIL; } @Override - public NilValue asNilValue() { + public NilValue asNilValue() + { return this; } @Override - public ImmutableNilValue immutableValue() { + public ImmutableNilValue immutableValue() + { return ValueFactory.newNil(); } @Override - public void writeTo(MessagePacker pk) throws IOException { + public void writeTo(MessagePacker pk) + throws IOException + { pk.packNil(); } } - //// // BooleanValue // - public Variable setBooleanValue(boolean v) { + public Variable setBooleanValue(boolean v) + { this.type = Type.BOOLEAN; this.accessor = booleanAccessor; this.longValue = (v ? 1L : 0L); return this; } - private class BooleanValueAccessor extends AbstractValueAccessor implements BooleanValue { + private class BooleanValueAccessor + extends AbstractValueAccessor + implements BooleanValue + { @Override - public ValueType getValueType() { + public ValueType getValueType() + { return ValueType.BOOLEAN; } @Override - public BooleanValue asBooleanValue() { + public BooleanValue asBooleanValue() + { return this; } @Override - public ImmutableBooleanValue immutableValue() { + public ImmutableBooleanValue immutableValue() + { return ValueFactory.newBoolean(getBoolean()); } @Override - public boolean getBoolean() { + public boolean getBoolean() + { return longValue == 1L; } @Override - public void writeTo(MessagePacker pk) throws IOException { + public void writeTo(MessagePacker pk) + throws IOException + { pk.packBoolean(longValue == 1L); } } - //// // NumberValue // IntegerValue @@ -296,14 +344,19 @@ public void writeTo(MessagePacker pk) throws IOException { private static final long INT_MIN = (long) Integer.MIN_VALUE; private static final long INT_MAX = (long) Integer.MAX_VALUE; - private abstract class AbstractNumberValueAccessor extends AbstractValueAccessor implements NumberValue { + private abstract class AbstractNumberValueAccessor + extends AbstractValueAccessor + implements NumberValue + { @Override - public NumberValue asNumberValue() { + public NumberValue asNumberValue() + { return this; } @Override - public byte castAsByte() { + public byte castAsByte() + { if (type == Type.BIG_INTEGER) { return ((BigInteger) objectValue).byteValue(); } @@ -311,7 +364,8 @@ public byte castAsByte() { } @Override - public short castAsShort() { + public short castAsShort() + { if (type == Type.BIG_INTEGER) { return ((BigInteger) objectValue).shortValue(); } @@ -319,7 +373,8 @@ public short castAsShort() { } @Override - public int castAsInt() { + public int castAsInt() + { if (type == Type.BIG_INTEGER) { return ((BigInteger) objectValue).intValue(); } @@ -327,7 +382,8 @@ public int castAsInt() { } @Override - public long castAsLong() { + public long castAsLong() + { if (type == Type.BIG_INTEGER) { return ((BigInteger) objectValue).longValue(); } @@ -335,7 +391,8 @@ public long castAsLong() { } @Override - public BigInteger castAsBigInteger() { + public BigInteger castAsBigInteger() + { if (type == Type.BIG_INTEGER) { return (BigInteger) objectValue; } @@ -346,7 +403,8 @@ else if (type == Type.DOUBLE) { } @Override - public float castAsFloat() { + public float castAsFloat() + { if (type == Type.BIG_INTEGER) { return ((BigInteger) objectValue).floatValue(); } @@ -357,7 +415,8 @@ else if (type == Type.DOUBLE) { } @Override - public double castAsDouble() { + public double castAsDouble() + { if (type == Type.BIG_INTEGER) { return ((BigInteger) objectValue).doubleValue(); } @@ -368,24 +427,26 @@ else if (type == Type.DOUBLE) { } } - //// // IntegerValue // - public Variable setIntegerValue(long v) { + public Variable setIntegerValue(long v) + { this.type = Type.LONG; this.accessor = integerAccessor; this.longValue = v; return this; } - public Variable setIntegerValue(BigInteger v) { + public Variable setIntegerValue(BigInteger v) + { if (0 <= v.compareTo(LONG_MIN) && v.compareTo(LONG_MAX) <= 0) { this.type = Type.LONG; this.accessor = integerAccessor; this.longValue = v.longValue(); - } else { + } + else { this.type = Type.BIG_INTEGER; this.accessor = integerAccessor; this.objectValue = v; @@ -393,19 +454,25 @@ public Variable setIntegerValue(BigInteger v) { return this; } - private class IntegerValueAccessor extends AbstractNumberValueAccessor implements IntegerValue { + private class IntegerValueAccessor + extends AbstractNumberValueAccessor + implements IntegerValue + { @Override - public ValueType getValueType() { + public ValueType getValueType() + { return ValueType.INTEGER; } @Override - public IntegerValue asIntegerValue() { + public IntegerValue asIntegerValue() + { return this; } @Override - public ImmutableIntegerValue immutableValue() { + public ImmutableIntegerValue immutableValue() + { if (type == Type.BIG_INTEGER) { return ValueFactory.newInteger((BigInteger) objectValue); } @@ -413,7 +480,8 @@ public ImmutableIntegerValue immutableValue() { } @Override - public boolean isInByteRange() { + public boolean isInByteRange() + { if (type == Type.BIG_INTEGER) { return false; } @@ -421,7 +489,8 @@ public boolean isInByteRange() { } @Override - public boolean isInShortRange() { + public boolean isInShortRange() + { if (type == Type.BIG_INTEGER) { return false; } @@ -429,7 +498,8 @@ public boolean isInShortRange() { } @Override - public boolean isInIntRange() { + public boolean isInIntRange() + { if (type == Type.BIG_INTEGER) { return false; } @@ -437,7 +507,8 @@ public boolean isInIntRange() { } @Override - public boolean isInLongRange() { + public boolean isInLongRange() + { if (type == Type.BIG_INTEGER) { return false; } @@ -445,7 +516,8 @@ public boolean isInLongRange() { } @Override - public byte getByte() { + public byte getByte() + { if (!isInByteRange()) { throw new MessageIntegerOverflowException(longValue); } @@ -453,7 +525,8 @@ public byte getByte() { } @Override - public short getShort() { + public short getShort() + { if (!isInByteRange()) { throw new MessageIntegerOverflowException(longValue); } @@ -461,7 +534,8 @@ public short getShort() { } @Override - public int getInt() { + public int getInt() + { if (!isInIntRange()) { throw new MessageIntegerOverflowException(longValue); } @@ -469,7 +543,8 @@ public int getInt() { } @Override - public long getLong() { + public long getLong() + { if (!isInLongRange()) { throw new MessageIntegerOverflowException(longValue); } @@ -477,30 +552,35 @@ public long getLong() { } @Override - public BigInteger getBigInteger() { + public BigInteger getBigInteger() + { if (type == Type.BIG_INTEGER) { return (BigInteger) objectValue; - } else { + } + else { return BigInteger.valueOf(longValue); } } @Override - public void writeTo(MessagePacker pk) throws IOException { + public void writeTo(MessagePacker pk) + throws IOException + { if (type == Type.BIG_INTEGER) { pk.packBigInteger((BigInteger) objectValue); - } else { + } + else { pk.packLong(longValue); } } } - //// // FloatValue // - public Variable setFloatValue(double v) { + public Variable setFloatValue(double v) + { this.type = Type.DOUBLE; this.accessor = floatAccessor; this.doubleValue = v; @@ -508,80 +588,98 @@ public Variable setFloatValue(double v) { return this; } - public Variable setFloatValue(float v) { + public Variable setFloatValue(float v) + { this.type = Type.DOUBLE; this.accessor = floatAccessor; this.longValue = (long) v; // AbstractNumberValueAccessor uses castAsLong return this; } - private class FloatValueAccessor extends AbstractNumberValueAccessor implements FloatValue { + private class FloatValueAccessor + extends AbstractNumberValueAccessor + implements FloatValue + { @Override - public FloatValue asFloatValue() { + public FloatValue asFloatValue() + { return this; } @Override - public ImmutableFloatValue immutableValue() { + public ImmutableFloatValue immutableValue() + { return ValueFactory.newFloat(doubleValue); } @Override - public ValueType getValueType() { + public ValueType getValueType() + { return ValueType.FLOAT; } @Override - public void writeTo(MessagePacker pk) throws IOException { + public void writeTo(MessagePacker pk) + throws IOException + { pk.packDouble(doubleValue); } } - //// // RawValue // BinaryValue // StringValue // - private abstract class AbstractRawValueAccessor extends AbstractValueAccessor implements RawValue { + private abstract class AbstractRawValueAccessor + extends AbstractValueAccessor + implements RawValue + { @Override - public RawValue asRawValue() { + public RawValue asRawValue() + { return this; } @Override - public byte[] getByteArray() { + public byte[] getByteArray() + { return (byte[]) objectValue; } @Override - public ByteBuffer getByteBuffer() { + public ByteBuffer getByteBuffer() + { return ByteBuffer.wrap(getByteArray()); } @Override - public String getString() { + public String getString() + { byte[] raw = (byte[]) objectValue; try { CharsetDecoder reportDecoder = MessagePack.UTF8.newDecoder() - .onMalformedInput(CodingErrorAction.REPORT) - .onUnmappableCharacter(CodingErrorAction.REPORT); + .onMalformedInput(CodingErrorAction.REPORT) + .onUnmappableCharacter(CodingErrorAction.REPORT); return reportDecoder.decode(ByteBuffer.wrap(raw)).toString(); - } catch (CharacterCodingException ex) { + } + catch (CharacterCodingException ex) { throw new MessageStringCodingException(ex); } } @Override - public String stringValue() { + public String stringValue() + { byte[] raw = (byte[]) objectValue; try { CharsetDecoder reportDecoder = MessagePack.UTF8.newDecoder() - .onMalformedInput(CodingErrorAction.REPLACE) - .onUnmappableCharacter(CodingErrorAction.REPLACE); + .onMalformedInput(CodingErrorAction.REPLACE) + .onUnmappableCharacter(CodingErrorAction.REPLACE); return reportDecoder.decode(ByteBuffer.wrap(raw)).toString(); - } catch (CharacterCodingException ex) { + } + catch (CharacterCodingException ex) { throw new MessageStringCodingException(ex); } } @@ -591,117 +689,144 @@ public String stringValue() { // BinaryValue // - public Variable setBinaryValue(byte[] v) { + public Variable setBinaryValue(byte[] v) + { this.type = Type.BYTE_ARRAY; this.accessor = binaryAccessor; this.objectValue = v; return this; } - private class BinaryValueAccessor extends AbstractRawValueAccessor implements BinaryValue { + private class BinaryValueAccessor + extends AbstractRawValueAccessor + implements BinaryValue + { @Override - public ValueType getValueType() { + public ValueType getValueType() + { return ValueType.BINARY; } @Override - public BinaryValue asBinaryValue() { + public BinaryValue asBinaryValue() + { return this; } @Override - public ImmutableBinaryValue immutableValue() { + public ImmutableBinaryValue immutableValue() + { return ValueFactory.newBinary(getByteArray()); } @Override - public void writeTo(MessagePacker pk) throws IOException { + public void writeTo(MessagePacker pk) + throws IOException + { byte[] data = (byte[]) objectValue; pk.packBinaryHeader(data.length); pk.writePayload(data); } } - //// // StringValue // - public Variable setStringValue(String v) { + public Variable setStringValue(String v) + { return setStringValue(v.getBytes(MessagePack.UTF8)); } - public Variable setStringValue(byte[] v) { + public Variable setStringValue(byte[] v) + { this.type = Type.RAW_STRING; this.accessor = stringAccessor; this.objectValue = v; return this; } - private class StringValueAccessor extends AbstractRawValueAccessor implements StringValue { + private class StringValueAccessor + extends AbstractRawValueAccessor + implements StringValue + { @Override - public ValueType getValueType() { + public ValueType getValueType() + { return ValueType.STRING; } @Override - public StringValue asStringValue() { + public StringValue asStringValue() + { return this; } @Override - public ImmutableStringValue immutableValue() { + public ImmutableStringValue immutableValue() + { return ValueFactory.newString((byte[]) objectValue); } @Override - public void writeTo(MessagePacker pk) throws IOException { + public void writeTo(MessagePacker pk) + throws IOException + { byte[] data = (byte[]) objectValue; pk.packRawStringHeader(data.length); pk.writePayload(data); } } - //// // ArrayValue // - public Variable setArrayValue(List v) { + public Variable setArrayValue(List v) + { this.type = Type.LIST; this.accessor = arrayAccessor; this.objectValue = v; return this; } - private class ArrayValueAccessor extends AbstractValueAccessor implements ArrayValue { + private class ArrayValueAccessor + extends AbstractValueAccessor + implements ArrayValue + { @Override - public ValueType getValueType() { + public ValueType getValueType() + { return ValueType.ARRAY; } @Override - public ArrayValue asArrayValue() { + public ArrayValue asArrayValue() + { return this; } @Override - public ImmutableArrayValue immutableValue() { + public ImmutableArrayValue immutableValue() + { return ValueFactory.newArray(list()); } @Override - public int size() { + public int size() + { return list().size(); } @Override - public Value get(int index) { + public Value get(int index) + { return list().get(index); } @Override - public Value getOrNilValue(int index) { + public Value getOrNilValue(int index) + { List l = list(); if (l.size() < index && index >= 0) { return ValueFactory.newNil(); @@ -710,18 +835,22 @@ public Value getOrNilValue(int index) { } @Override - public Iterator iterator() { + public Iterator iterator() + { return list().iterator(); } @Override @SuppressWarnings("unchecked") - public List list() { + public List list() + { return (List) objectValue; } @Override - public void writeTo(MessagePacker pk) throws IOException { + public void writeTo(MessagePacker pk) + throws IOException + { List l = list(); pk.packArrayHeader(l.size()); for (Value e : l) { @@ -734,57 +863,69 @@ public void writeTo(MessagePacker pk) throws IOException { // MapValue // - public Variable setMapValue(Map v) { + public Variable setMapValue(Map v) + { this.type = Type.MAP; this.accessor = mapAccessor; this.objectValue = v; return this; } - private class MapValueAccessor extends AbstractValueAccessor implements MapValue { + private class MapValueAccessor + extends AbstractValueAccessor + implements MapValue + { @Override - public ValueType getValueType() { + public ValueType getValueType() + { return ValueType.MAP; } @Override - public MapValue asMapValue() { + public MapValue asMapValue() + { return this; } @Override - public ImmutableMapValue immutableValue() { + public ImmutableMapValue immutableValue() + { return ValueFactory.newMap(map()); } @Override - public int size() { + public int size() + { return map().size(); } @Override - public Set keySet() { + public Set keySet() + { return map().keySet(); } @Override - public Set> entrySet() { + public Set> entrySet() + { return map().entrySet(); } @Override - public Collection values() { + public Collection values() + { return map().values(); } @Override - public Value[] getKeyValueArray() { - Map v = map(); + public Value[] getKeyValueArray() + { + Map v = map(); Value[] kvs = new Value[v.size() * 2]; - Iterator> ite = v.entrySet().iterator(); + Iterator> ite = v.entrySet().iterator(); int i = 0; while (ite.hasNext()) { - Map.Entry pair = ite.next(); + Map.Entry pair = ite.next(); kvs[i] = pair.getKey(); i++; kvs[i] = pair.getValue(); @@ -794,156 +935,187 @@ public Value[] getKeyValueArray() { } @SuppressWarnings("unchecked") - public Map map() { + public Map map() + { return (Map) objectValue; } @Override - public void writeTo(MessagePacker pk) throws IOException { - Map m = map(); + public void writeTo(MessagePacker pk) + throws IOException + { + Map m = map(); pk.packArrayHeader(m.size()); - for (Map.Entry pair : m.entrySet()) { + for (Map.Entry pair : m.entrySet()) { pair.getKey().writeTo(pk); pair.getValue().writeTo(pk); } } } - //// // ExtensionValue // - public Variable setExtensionValue(byte type, byte[] data) { + public Variable setExtensionValue(byte type, byte[] data) + { this.type = Type.EXTENSION; this.accessor = extensionAccessor; this.objectValue = ValueFactory.newExtension(type, data); return this; } - private class ExtensionValueAccessor extends AbstractValueAccessor implements ExtensionValue { + private class ExtensionValueAccessor + extends AbstractValueAccessor + implements ExtensionValue + { @Override - public ValueType getValueType() { + public ValueType getValueType() + { return ValueType.EXTENSION; } @Override - public ExtensionValue asExtensionValue() { + public ExtensionValue asExtensionValue() + { return this; } @Override - public ImmutableExtensionValue immutableValue() { + public ImmutableExtensionValue immutableValue() + { return (ImmutableExtensionValue) objectValue; } @Override - public byte getType() { + public byte getType() + { return ((ImmutableExtensionValue) objectValue).getType(); } @Override - public byte[] getData() { + public byte[] getData() + { return ((ImmutableExtensionValue) objectValue).getData(); } @Override - public void writeTo(MessagePacker pk) throws IOException { + public void writeTo(MessagePacker pk) + throws IOException + { ((ImmutableExtensionValue) objectValue).writeTo(pk); } } - //// // Value // @Override - public ImmutableValue immutableValue() { + public ImmutableValue immutableValue() + { return accessor.immutableValue(); } @Override - public void writeTo(MessagePacker pk) throws IOException { + public void writeTo(MessagePacker pk) + throws IOException + { accessor.writeTo(pk); } @Override - public int hashCode() { + public int hashCode() + { return immutableValue().hashCode(); // TODO optimize } @Override - public boolean equals(Object o) { + public boolean equals(Object o) + { return immutableValue().equals(o); // TODO optimize } @Override - public String toString() { + public String toString() + { return immutableValue().toString(); // TODO optimize } @Override - public ValueType getValueType() { + public ValueType getValueType() + { return type.getValueType(); } @Override - public boolean isNilValue() { + public boolean isNilValue() + { return getValueType().isNilType(); } @Override - public boolean isBooleanValue() { + public boolean isBooleanValue() + { return getValueType().isBooleanType(); } @Override - public boolean isNumberValue() { + public boolean isNumberValue() + { return getValueType().isNumberType(); } @Override - public boolean isIntegerValue() { + public boolean isIntegerValue() + { return getValueType().isIntegerType(); } @Override - public boolean isFloatValue() { + public boolean isFloatValue() + { return getValueType().isFloatType(); } @Override - public boolean isRawValue() { + public boolean isRawValue() + { return getValueType().isRawType(); } @Override - public boolean isBinaryValue() { + public boolean isBinaryValue() + { return getValueType().isBinaryType(); } @Override - public boolean isStringValue() { + public boolean isStringValue() + { return getValueType().isStringType(); } @Override - public boolean isArrayValue() { + public boolean isArrayValue() + { return getValueType().isArrayType(); } @Override - public boolean isMapValue() { + public boolean isMapValue() + { return getValueType().isMapType(); } @Override - public boolean isExtensionValue() { + public boolean isExtensionValue() + { return getValueType().isExtensionType(); } @Override - public NilValue asNilValue() { + public NilValue asNilValue() + { if (!isNilValue()) { throw new MessageTypeCastException(); } @@ -951,7 +1123,8 @@ public NilValue asNilValue() { } @Override - public BooleanValue asBooleanValue() { + public BooleanValue asBooleanValue() + { if (!isBooleanValue()) { throw new MessageTypeCastException(); } @@ -959,7 +1132,8 @@ public BooleanValue asBooleanValue() { } @Override - public NumberValue asNumberValue() { + public NumberValue asNumberValue() + { if (!isNumberValue()) { throw new MessageTypeCastException(); } @@ -967,7 +1141,8 @@ public NumberValue asNumberValue() { } @Override - public IntegerValue asIntegerValue() { + public IntegerValue asIntegerValue() + { if (!isIntegerValue()) { throw new MessageTypeCastException(); } @@ -975,7 +1150,8 @@ public IntegerValue asIntegerValue() { } @Override - public FloatValue asFloatValue() { + public FloatValue asFloatValue() + { if (!isFloatValue()) { throw new MessageTypeCastException(); } @@ -983,7 +1159,8 @@ public FloatValue asFloatValue() { } @Override - public RawValue asRawValue() { + public RawValue asRawValue() + { if (!isRawValue()) { throw new MessageTypeCastException(); } @@ -991,7 +1168,8 @@ public RawValue asRawValue() { } @Override - public BinaryValue asBinaryValue() { + public BinaryValue asBinaryValue() + { if (!isBinaryValue()) { throw new MessageTypeCastException(); } @@ -999,7 +1177,8 @@ public BinaryValue asBinaryValue() { } @Override - public StringValue asStringValue() { + public StringValue asStringValue() + { if (!isStringValue()) { throw new MessageTypeCastException(); } @@ -1007,7 +1186,8 @@ public StringValue asStringValue() { } @Override - public ArrayValue asArrayValue() { + public ArrayValue asArrayValue() + { if (!isArrayValue()) { throw new MessageTypeCastException(); } @@ -1015,7 +1195,8 @@ public ArrayValue asArrayValue() { } @Override - public MapValue asMapValue() { + public MapValue asMapValue() + { if (!isMapValue()) { throw new MessageTypeCastException(); } @@ -1023,7 +1204,8 @@ public MapValue asMapValue() { } @Override - public ExtensionValue asExtensionValue() { + public ExtensionValue asExtensionValue() + { if (!isExtensionValue()) { throw new MessageTypeCastException(); } diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/AbstractImmutableRawValue.java b/msgpack-core/src/main/java/org/msgpack/value/impl/AbstractImmutableRawValue.java index b72461943..d558234cf 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/impl/AbstractImmutableRawValue.java +++ b/msgpack-core/src/main/java/org/msgpack/value/impl/AbstractImmutableRawValue.java @@ -16,86 +16,95 @@ package org.msgpack.value.impl; import org.msgpack.core.MessagePack; -import org.msgpack.core.MessagePacker; import org.msgpack.core.MessageStringCodingException; -import org.msgpack.value.Value; import org.msgpack.value.ImmutableRawValue; -import java.util.Arrays; -import java.io.IOException; import java.nio.ByteBuffer; +import java.nio.charset.CharacterCodingException; import java.nio.charset.CharsetDecoder; -import java.nio.charset.CharsetEncoder; import java.nio.charset.CodingErrorAction; -import java.nio.charset.CharacterCodingException; - +import java.util.Arrays; -public abstract class AbstractImmutableRawValue extends AbstractImmutableValue implements ImmutableRawValue { +public abstract class AbstractImmutableRawValue + extends AbstractImmutableValue + implements ImmutableRawValue +{ protected final byte[] data; private volatile String decodedStringCache; private volatile CharacterCodingException codingException; - public AbstractImmutableRawValue(byte[] data) { + public AbstractImmutableRawValue(byte[] data) + { this.data = data; } - public AbstractImmutableRawValue(String string) { + public AbstractImmutableRawValue(String string) + { this.decodedStringCache = string; this.data = string.getBytes(MessagePack.UTF8); // TODO } @Override - public ImmutableRawValue asRawValue() { + public ImmutableRawValue asRawValue() + { return this; } @Override - public byte[] getByteArray() { + public byte[] getByteArray() + { return Arrays.copyOf(data, data.length); } @Override - public ByteBuffer getByteBuffer() { + public ByteBuffer getByteBuffer() + { return ByteBuffer.wrap(data).asReadOnlyBuffer(); } @Override - public String getString() { + public String getString() + { if (decodedStringCache == null) { decodeString(); } if (codingException != null) { throw new MessageStringCodingException(codingException); - } else { + } + else { return decodedStringCache; } } @Override - public String stringValue() { + public String stringValue() + { if (decodedStringCache == null) { decodeString(); } return decodedStringCache; } - private void decodeString() { + private void decodeString() + { synchronized (data) { if (decodedStringCache != null) { return; } try { CharsetDecoder reportDecoder = MessagePack.UTF8.newDecoder() - .onMalformedInput(CodingErrorAction.REPORT) - .onUnmappableCharacter(CodingErrorAction.REPORT); + .onMalformedInput(CodingErrorAction.REPORT) + .onUnmappableCharacter(CodingErrorAction.REPORT); this.decodedStringCache = reportDecoder.decode(getByteBuffer()).toString(); - } catch (CharacterCodingException ex) { + } + catch (CharacterCodingException ex) { try { CharsetDecoder replaceDecoder = MessagePack.UTF8.newDecoder() - .onMalformedInput(CodingErrorAction.REPLACE) - .onUnmappableCharacter(CodingErrorAction.REPLACE); + .onMalformedInput(CodingErrorAction.REPLACE) + .onUnmappableCharacter(CodingErrorAction.REPLACE); this.decodedStringCache = replaceDecoder.decode(getByteBuffer()).toString(); - } catch (CharacterCodingException neverThrown) { + } + catch (CharacterCodingException neverThrown) { throw new MessageStringCodingException(neverThrown); } this.codingException = ex; @@ -104,53 +113,58 @@ private void decodeString() { } @Override - public String toString() { + public String toString() + { return toString(new StringBuilder()).toString(); } - private StringBuilder toString(StringBuilder sb) { + private StringBuilder toString(StringBuilder sb) + { String s = stringValue(); sb.append("\""); for (int i = 0; i < s.length(); i++) { char ch = s.charAt(i); if (ch < 0x20) { switch (ch) { - case '\n': - sb.append("\\n"); - break; - case '\r': - sb.append("\\r"); - break; - case '\t': - sb.append("\\t"); - break; - case '\f': - sb.append("\\f"); - break; - case '\b': - sb.append("\\b"); - break; - default: - // control chars - escapeChar(sb, ch); - break; + case '\n': + sb.append("\\n"); + break; + case '\r': + sb.append("\\r"); + break; + case '\t': + sb.append("\\t"); + break; + case '\f': + sb.append("\\f"); + break; + case '\b': + sb.append("\\b"); + break; + default: + // control chars + escapeChar(sb, ch); + break; } - } else if (ch <= 0x7f) { + } + else if (ch <= 0x7f) { switch (ch) { - case '\\': - sb.append("\\\\"); - break; - case '"': - sb.append("\\\""); - break; - default: - sb.append(ch); - break; + case '\\': + sb.append("\\\\"); + break; + case '"': + sb.append("\\\""); + break; + default: + sb.append(ch); + break; } - } else if (ch >= 0xd800 && ch <= 0xdfff) { + } + else if (ch >= 0xd800 && ch <= 0xdfff) { // surrogates escapeChar(sb, ch); - } else { + } + else { sb.append(ch); } } @@ -159,9 +173,10 @@ private StringBuilder toString(StringBuilder sb) { return sb; } - private final static char[] HEX_TABLE = "0123456789ABCDEF".toCharArray(); + private static final char[] HEX_TABLE = "0123456789ABCDEF".toCharArray(); - private void escapeChar(StringBuilder sb, int ch) { + private void escapeChar(StringBuilder sb, int ch) + { sb.append("\\u"); sb.append(HEX_TABLE[(ch >> 12) & 0x0f]); sb.append(HEX_TABLE[(ch >> 8) & 0x0f]); diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/AbstractImmutableValue.java b/msgpack-core/src/main/java/org/msgpack/value/impl/AbstractImmutableValue.java index 1f337e127..1dae99cf2 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/impl/AbstractImmutableValue.java +++ b/msgpack-core/src/main/java/org/msgpack/value/impl/AbstractImmutableValue.java @@ -16,117 +16,151 @@ package org.msgpack.value.impl; import org.msgpack.core.MessageTypeCastException; -import org.msgpack.value.*; - - -abstract class AbstractImmutableValue implements ImmutableValue { - @Override - public boolean isNilValue() { +import org.msgpack.value.ImmutableArrayValue; +import org.msgpack.value.ImmutableBinaryValue; +import org.msgpack.value.ImmutableBooleanValue; +import org.msgpack.value.ImmutableExtensionValue; +import org.msgpack.value.ImmutableFloatValue; +import org.msgpack.value.ImmutableIntegerValue; +import org.msgpack.value.ImmutableMapValue; +import org.msgpack.value.ImmutableNilValue; +import org.msgpack.value.ImmutableNumberValue; +import org.msgpack.value.ImmutableRawValue; +import org.msgpack.value.ImmutableStringValue; +import org.msgpack.value.ImmutableValue; + +abstract class AbstractImmutableValue + implements ImmutableValue +{ + @Override + public boolean isNilValue() + { return getValueType().isNilType(); } @Override - public boolean isBooleanValue() { + public boolean isBooleanValue() + { return getValueType().isBooleanType(); } @Override - public boolean isNumberValue() { + public boolean isNumberValue() + { return getValueType().isNumberType(); } @Override - public boolean isIntegerValue() { + public boolean isIntegerValue() + { return getValueType().isIntegerType(); } @Override - public boolean isFloatValue() { + public boolean isFloatValue() + { return getValueType().isFloatType(); } @Override - public boolean isRawValue() { + public boolean isRawValue() + { return getValueType().isRawType(); } @Override - public boolean isBinaryValue() { + public boolean isBinaryValue() + { return getValueType().isBinaryType(); } @Override - public boolean isStringValue() { + public boolean isStringValue() + { return getValueType().isStringType(); } @Override - public boolean isArrayValue() { + public boolean isArrayValue() + { return getValueType().isArrayType(); } @Override - public boolean isMapValue() { + public boolean isMapValue() + { return getValueType().isMapType(); } @Override - public boolean isExtensionValue() { + public boolean isExtensionValue() + { return getValueType().isExtensionType(); } @Override - public ImmutableNilValue asNilValue() { + public ImmutableNilValue asNilValue() + { throw new MessageTypeCastException(); } @Override - public ImmutableBooleanValue asBooleanValue() { + public ImmutableBooleanValue asBooleanValue() + { throw new MessageTypeCastException(); } @Override - public ImmutableNumberValue asNumberValue() { + public ImmutableNumberValue asNumberValue() + { throw new MessageTypeCastException(); } @Override - public ImmutableIntegerValue asIntegerValue() { + public ImmutableIntegerValue asIntegerValue() + { throw new MessageTypeCastException(); } @Override - public ImmutableFloatValue asFloatValue() { + public ImmutableFloatValue asFloatValue() + { throw new MessageTypeCastException(); } @Override - public ImmutableRawValue asRawValue() { + public ImmutableRawValue asRawValue() + { throw new MessageTypeCastException(); } @Override - public ImmutableBinaryValue asBinaryValue() { + public ImmutableBinaryValue asBinaryValue() + { throw new MessageTypeCastException(); } @Override - public ImmutableStringValue asStringValue() { + public ImmutableStringValue asStringValue() + { throw new MessageTypeCastException(); } @Override - public ImmutableArrayValue asArrayValue() { + public ImmutableArrayValue asArrayValue() + { throw new MessageTypeCastException(); } @Override - public ImmutableMapValue asMapValue() { + public ImmutableMapValue asMapValue() + { throw new MessageTypeCastException(); } @Override - public ImmutableExtensionValue asExtensionValue() { + public ImmutableExtensionValue asExtensionValue() + { throw new MessageTypeCastException(); } } diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableArrayValueImpl.java b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableArrayValueImpl.java index 39564711d..a62e7cc64 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableArrayValueImpl.java +++ b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableArrayValueImpl.java @@ -16,61 +16,74 @@ package org.msgpack.value.impl; import org.msgpack.core.MessagePacker; -import org.msgpack.value.*; +import org.msgpack.value.ArrayValue; +import org.msgpack.value.ImmutableArrayValue; +import org.msgpack.value.Value; +import org.msgpack.value.ValueType; -import java.util.List; +import java.io.IOException; import java.util.AbstractList; import java.util.Arrays; import java.util.Iterator; +import java.util.List; import java.util.NoSuchElementException; -import java.io.IOException; - /** * {@code ImmutableArrayValueImpl} Implements {@code ImmutableArrayValue} using a {@code Value[]} field. * - * @see org.msgpack.value.IntegerValue + * @see org.msgpack.value.IntegerValue */ -public class ImmutableArrayValueImpl extends AbstractImmutableValue implements ImmutableArrayValue { - private static ImmutableArrayValueImpl EMPTY = new ImmutableArrayValueImpl(new Value[0]); - - public static ImmutableArrayValue empty() { +public class ImmutableArrayValueImpl + extends AbstractImmutableValue + implements ImmutableArrayValue +{ + private static final ImmutableArrayValueImpl EMPTY = new ImmutableArrayValueImpl(new Value[0]); + + public static ImmutableArrayValue empty() + { return EMPTY; } private final Value[] array; - public ImmutableArrayValueImpl(Value[] array) { + public ImmutableArrayValueImpl(Value[] array) + { this.array = array; } @Override - public ValueType getValueType() { + public ValueType getValueType() + { return ValueType.ARRAY; } @Override - public ImmutableArrayValue immutableValue() { + public ImmutableArrayValue immutableValue() + { return this; } @Override - public ImmutableArrayValue asArrayValue() { + public ImmutableArrayValue asArrayValue() + { return this; } @Override - public int size() { + public int size() + { return array.length; } @Override - public Value get(int index) { + public Value get(int index) + { return array[index]; } @Override - public Value getOrNilValue(int index) { + public Value getOrNilValue(int index) + { if (index < array.length && index >= 0) { return array[index]; } @@ -78,29 +91,34 @@ public Value getOrNilValue(int index) { } @Override - public Iterator iterator() { + public Iterator iterator() + { return new Ite(array); } @Override - public List list() { + public List list() + { return new ImmutableArrayValueList(array); } @Override - public void writeTo(MessagePacker pk) throws IOException { + public void writeTo(MessagePacker pk) + throws IOException + { pk.packArrayHeader(array.length); - for(int i = 0; i < array.length; i++) { + for (int i = 0; i < array.length; i++) { array[i].writeTo(pk); } } @Override - public boolean equals(Object o) { - if(o == this) { + public boolean equals(Object o) + { + if (o == this) { return true; } - if(!(o instanceof Value)) { + if (!(o instanceof Value)) { return false; } Value v = (Value) o; @@ -108,8 +126,9 @@ public boolean equals(Object o) { if (v instanceof ImmutableArrayValueImpl) { ImmutableArrayValueImpl oa = (ImmutableArrayValueImpl) v; return Arrays.equals(array, oa.array); - } else { - if(!v.isArrayValue()) { + } + else { + if (!v.isArrayValue()) { return false; } ArrayValue av = v.asArrayValue(); @@ -129,9 +148,10 @@ public boolean equals(Object o) { } @Override - public int hashCode() { + public int hashCode() + { int h = 1; - for(int i = 0; i < array.length; i++) { + for (int i = 0; i < array.length; i++) { Value obj = array[i]; h = 31 * h + obj.hashCode(); } @@ -139,17 +159,19 @@ public int hashCode() { } @Override - public String toString() { + public String toString() + { return toString(new StringBuilder()).toString(); } - private StringBuilder toString(StringBuilder sb) { - if(array.length == 0) { + private StringBuilder toString(StringBuilder sb) + { + if (array.length == 0) { return sb.append("[]"); } sb.append("["); sb.append(array[0]); - for(int i = 1; i < array.length; i++) { + for (int i = 1; i < array.length; i++) { sb.append(","); sb.append(array[i].toString()); } @@ -157,40 +179,50 @@ private StringBuilder toString(StringBuilder sb) { return sb; } - private static class ImmutableArrayValueList extends AbstractList { + private static class ImmutableArrayValueList + extends AbstractList + { private final Value[] array; - public ImmutableArrayValueList(Value[] array) { + public ImmutableArrayValueList(Value[] array) + { this.array = array; } @Override - public Value get(int index) { + public Value get(int index) + { return array[index]; } @Override - public int size() { + public int size() + { return array.length; } } - private static class Ite implements Iterator { + private static class Ite + implements Iterator + { private final Value[] array; private int index; - public Ite(Value[] array) { + public Ite(Value[] array) + { this.array = array; this.index = 0; } @Override - public boolean hasNext() { + public boolean hasNext() + { return index != array.length; } @Override - public Value next() { + public Value next() + { int i = index; if (i >= array.length) { throw new NoSuchElementException(); @@ -200,7 +232,8 @@ public Value next() { } @Override - public void remove() { + public void remove() + { throw new UnsupportedOperationException(); } } diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableBigIntegerValueImpl.java b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableBigIntegerValueImpl.java index 1e5ac8759..2893c4154 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableBigIntegerValueImpl.java +++ b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableBigIntegerValueImpl.java @@ -15,23 +15,30 @@ // package org.msgpack.value.impl; -import org.msgpack.core.MessagePacker; import org.msgpack.core.MessageIntegerOverflowException; -import org.msgpack.value.*; +import org.msgpack.core.MessagePacker; +import org.msgpack.value.ImmutableIntegerValue; +import org.msgpack.value.ImmutableNumberValue; +import org.msgpack.value.IntegerValue; +import org.msgpack.value.Value; +import org.msgpack.value.ValueType; import java.io.IOException; import java.math.BigInteger; - /** * {@code ImmutableBigIntegerValueImpl} Implements {@code ImmutableBigIntegerValue} using a {@code BigInteger} field. * - * @see org.msgpack.value.IntegerValue + * @see org.msgpack.value.IntegerValue */ -public class ImmutableBigIntegerValueImpl extends AbstractImmutableValue implements ImmutableIntegerValue { +public class ImmutableBigIntegerValueImpl + extends AbstractImmutableValue + implements ImmutableIntegerValue +{ private final BigInteger value; - public ImmutableBigIntegerValueImpl(BigInteger value) { + public ImmutableBigIntegerValueImpl(BigInteger value) + { this.value = value; } @@ -45,82 +52,98 @@ public ImmutableBigIntegerValueImpl(BigInteger value) { private static final BigInteger LONG_MAX = BigInteger.valueOf((long) Long.MAX_VALUE); @Override - public ValueType getValueType() { + public ValueType getValueType() + { return ValueType.INTEGER; } @Override - public ImmutableIntegerValue immutableValue() { + public ImmutableIntegerValue immutableValue() + { return this; } @Override - public ImmutableNumberValue asNumberValue() { + public ImmutableNumberValue asNumberValue() + { return this; } @Override - public ImmutableIntegerValue asIntegerValue() { + public ImmutableIntegerValue asIntegerValue() + { return this; } @Override - public byte castAsByte() { + public byte castAsByte() + { return value.byteValue(); } @Override - public short castAsShort() { + public short castAsShort() + { return value.shortValue(); } @Override - public int castAsInt() { + public int castAsInt() + { return value.intValue(); } @Override - public long castAsLong() { + public long castAsLong() + { return value.longValue(); } @Override - public BigInteger castAsBigInteger() { + public BigInteger castAsBigInteger() + { return value; } @Override - public float castAsFloat() { + public float castAsFloat() + { return value.floatValue(); } @Override - public double castAsDouble() { + public double castAsDouble() + { return value.doubleValue(); } @Override - public boolean isInByteRange() { + public boolean isInByteRange() + { return 0 <= value.compareTo(BYTE_MIN) && value.compareTo(BYTE_MAX) <= 0; } @Override - public boolean isInShortRange() { + public boolean isInShortRange() + { return 0 <= value.compareTo(SHORT_MIN) && value.compareTo(SHORT_MAX) <= 0; } @Override - public boolean isInIntRange() { + public boolean isInIntRange() + { return 0 <= value.compareTo(INT_MIN) && value.compareTo(INT_MAX) <= 0; } @Override - public boolean isInLongRange() { + public boolean isInLongRange() + { return 0 <= value.compareTo(LONG_MIN) && value.compareTo(LONG_MAX) <= 0; } @Override - public byte getByte() { + public byte getByte() + { if (!isInByteRange()) { throw new MessageIntegerOverflowException(value); } @@ -128,7 +151,8 @@ public byte getByte() { } @Override - public short getShort() { + public short getShort() + { if (!isInShortRange()) { throw new MessageIntegerOverflowException(value); } @@ -136,7 +160,8 @@ public short getShort() { } @Override - public int getInt() { + public int getInt() + { if (!isInIntRange()) { throw new MessageIntegerOverflowException(value); } @@ -144,7 +169,8 @@ public int getInt() { } @Override - public long getLong() { + public long getLong() + { if (!isInLongRange()) { throw new MessageIntegerOverflowException(value); } @@ -152,17 +178,21 @@ public long getLong() { } @Override - public BigInteger getBigInteger() { + public BigInteger getBigInteger() + { return value; } @Override - public void writeTo(MessagePacker pk) throws IOException { + public void writeTo(MessagePacker pk) + throws IOException + { pk.packBigInteger(value); } @Override - public boolean equals(Object o) { + public boolean equals(Object o) + { if (o == this) { return true; } @@ -179,10 +209,12 @@ public boolean equals(Object o) { } @Override - public int hashCode() { + public int hashCode() + { if (INT_MIN.compareTo(value) <= 0 && value.compareTo(INT_MAX) <= 0) { return (int) value.longValue(); - } else if (LONG_MIN.compareTo(value) <= 0 + } + else if (LONG_MIN.compareTo(value) <= 0 && value.compareTo(LONG_MAX) <= 0) { long v = value.longValue(); return (int) (v ^ (v >>> 32)); @@ -191,7 +223,8 @@ public int hashCode() { } @Override - public String toString() { + public String toString() + { return value.toString(); } } diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableBinaryValueImpl.java b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableBinaryValueImpl.java index da794e001..41bbb8659 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableBinaryValueImpl.java +++ b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableBinaryValueImpl.java @@ -23,53 +23,62 @@ import java.io.IOException; import java.util.Arrays; - /** * {@code ImmutableBinaryValueImpl} Implements {@code ImmutableBinaryValue} using a {@code byte[]} field. * This implementation caches result of {@code stringValue()} and {@code getString()} using a private {@code String} field. * * @see org.msgpack.value.StringValue */ -public class ImmutableBinaryValueImpl extends AbstractImmutableRawValue implements ImmutableBinaryValue { - public ImmutableBinaryValueImpl(byte[] data) { +public class ImmutableBinaryValueImpl + extends AbstractImmutableRawValue + implements ImmutableBinaryValue +{ + public ImmutableBinaryValueImpl(byte[] data) + { super(data); } @Override - public ValueType getValueType() { + public ValueType getValueType() + { return ValueType.BINARY; } @Override - public ImmutableBinaryValue immutableValue() { + public ImmutableBinaryValue immutableValue() + { return this; } @Override - public ImmutableBinaryValue asBinaryValue() { + public ImmutableBinaryValue asBinaryValue() + { return this; } @Override - public void writeTo(MessagePacker pk) throws IOException { + public void writeTo(MessagePacker pk) + throws IOException + { pk.packBinaryHeader(data.length); pk.writePayload(data); } @Override - public boolean equals(Object o) { - if(this == o) { + public boolean equals(Object o) + { + if (this == o) { return true; } - if(!(o instanceof Value)) { + if (!(o instanceof Value)) { return false; } Value v = (Value) o; - if(!v.isBinaryValue()) { + if (!v.isBinaryValue()) { return false; } - if(v instanceof ImmutableBinaryValueImpl) { + if (v instanceof ImmutableBinaryValueImpl) { ImmutableBinaryValueImpl bv = (ImmutableBinaryValueImpl) v; return Arrays.equals(data, bv.data); } @@ -79,7 +88,8 @@ public boolean equals(Object o) { } @Override - public int hashCode() { + public int hashCode() + { return Arrays.hashCode(data); } } diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableBooleanValueImpl.java b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableBooleanValueImpl.java index aee366788..9bd11bdf9 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableBooleanValueImpl.java +++ b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableBooleanValueImpl.java @@ -22,7 +22,6 @@ import java.io.IOException; - /** * {@code ImmutableBooleanValueImpl} Implements {@code ImmutableBooleanValue} using a {@code boolean} field. *

@@ -30,55 +29,66 @@ * * @see org.msgpack.value.BooleanValue */ -public class ImmutableBooleanValueImpl extends AbstractImmutableValue implements ImmutableBooleanValue { - public static ImmutableBooleanValue TRUE = new ImmutableBooleanValueImpl(true); - public static ImmutableBooleanValue FALSE = new ImmutableBooleanValueImpl(false); +public class ImmutableBooleanValueImpl + extends AbstractImmutableValue + implements ImmutableBooleanValue +{ + public static final ImmutableBooleanValue TRUE = new ImmutableBooleanValueImpl(true); + public static final ImmutableBooleanValue FALSE = new ImmutableBooleanValueImpl(false); private final boolean value; - private ImmutableBooleanValueImpl(boolean value) { + private ImmutableBooleanValueImpl(boolean value) + { this.value = value; } @Override - public ValueType getValueType() { + public ValueType getValueType() + { return ValueType.BOOLEAN; } @Override - public ImmutableBooleanValue immutableValue() { + public ImmutableBooleanValue immutableValue() + { return this; } @Override - public boolean getBoolean() { + public boolean getBoolean() + { return value; } @Override - public void writeTo(MessagePacker packer) throws IOException { + public void writeTo(MessagePacker packer) + throws IOException + { packer.packBoolean(value); } @Override - public boolean equals(Object o) { - if(o == this) { + public boolean equals(Object o) + { + if (o == this) { return true; } - if(!(o instanceof Value)) { + if (!(o instanceof Value)) { return false; } Value v = (Value) o; - if(!v.isBooleanValue()) { + if (!v.isBooleanValue()) { return false; } return value == v.asBooleanValue().getBoolean(); } @Override - public int hashCode() { - if(value) { + public int hashCode() + { + if (value) { return 1231; } else { @@ -87,7 +97,8 @@ public int hashCode() { } @Override - public String toString() { + public String toString() + { return Boolean.toString(value); } } diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableDoubleValueImpl.java b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableDoubleValueImpl.java index db7a262b4..a69afe242 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableDoubleValueImpl.java +++ b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableDoubleValueImpl.java @@ -24,93 +24,110 @@ import java.math.BigDecimal; import java.math.BigInteger; - /** * {@code ImmutableDoubleValueImpl} Implements {@code ImmutableFloatValue} using a {@code double} field. * * @see org.msgpack.value.FloatValue */ -public class ImmutableDoubleValueImpl extends AbstractImmutableValue implements ImmutableFloatValue { +public class ImmutableDoubleValueImpl + extends AbstractImmutableValue + implements ImmutableFloatValue +{ private final double value; - public ImmutableDoubleValueImpl(double value) { + public ImmutableDoubleValueImpl(double value) + { this.value = value; } @Override - public ValueType getValueType() { + public ValueType getValueType() + { return ValueType.FLOAT; } @Override - public ImmutableDoubleValueImpl immutableValue() { + public ImmutableDoubleValueImpl immutableValue() + { return this; } @Override - public byte castAsByte() { + public byte castAsByte() + { return (byte) value; } @Override - public short castAsShort() { + public short castAsShort() + { return (short) value; } @Override - public int castAsInt() { + public int castAsInt() + { return (int) value; } @Override - public long castAsLong() { + public long castAsLong() + { return (long) value; } @Override - public BigInteger castAsBigInteger() { + public BigInteger castAsBigInteger() + { return new BigDecimal(value).toBigInteger(); } @Override - public float castAsFloat() { + public float castAsFloat() + { return (float) value; } @Override - public double castAsDouble() { + public double castAsDouble() + { return value; } @Override - public void writeTo(MessagePacker pk) throws IOException { + public void writeTo(MessagePacker pk) + throws IOException + { pk.packDouble(value); } @Override - public boolean equals(Object o) { - if(o == this) { + public boolean equals(Object o) + { + if (o == this) { return true; } - if(!(o instanceof Value)) { + if (!(o instanceof Value)) { return false; } Value v = (Value) o; - if(!v.isFloatValue()) { + if (!v.isFloatValue()) { return false; } return value == v.asFloatValue().castAsDouble(); } @Override - public int hashCode() { + public int hashCode() + { long v = Double.doubleToLongBits(value); return (int) (v ^ (v >>> 32)); } @Override - public String toString() { + public String toString() + { return Double.toString(value); } } diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableExtensionValueImpl.java b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableExtensionValueImpl.java index fdd22b7f0..b37de8139 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableExtensionValueImpl.java +++ b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableExtensionValueImpl.java @@ -16,59 +16,73 @@ package org.msgpack.value.impl; import org.msgpack.core.MessagePacker; -import org.msgpack.value.*; +import org.msgpack.value.ExtensionValue; +import org.msgpack.value.ImmutableExtensionValue; +import org.msgpack.value.Value; +import org.msgpack.value.ValueType; -import java.util.Arrays; import java.io.IOException; - +import java.util.Arrays; /** * {@code ImmutableExtensionValueImpl} Implements {@code ImmutableExtensionValue} using a {@code byte} and a {@code byte[]} fields. * - * @see ExtensionValue + * @see ExtensionValue */ -public class ImmutableExtensionValueImpl extends AbstractImmutableValue implements ImmutableExtensionValue { +public class ImmutableExtensionValueImpl + extends AbstractImmutableValue + implements ImmutableExtensionValue +{ private final byte type; private final byte[] data; - public ImmutableExtensionValueImpl(byte type, byte[] data) { + public ImmutableExtensionValueImpl(byte type, byte[] data) + { this.type = type; this.data = data; } @Override - public ValueType getValueType() { + public ValueType getValueType() + { return ValueType.EXTENSION; } @Override - public ImmutableExtensionValue immutableValue() { + public ImmutableExtensionValue immutableValue() + { return this; } @Override - public ImmutableExtensionValue asExtensionValue() { + public ImmutableExtensionValue asExtensionValue() + { return this; } @Override - public byte getType() { + public byte getType() + { return type; } @Override - public byte[] getData() { + public byte[] getData() + { return data; } @Override - public void writeTo(MessagePacker packer) throws IOException { + public void writeTo(MessagePacker packer) + throws IOException + { packer.packExtensionTypeHeader(type, data.length); packer.writePayload(data); } @Override - public boolean equals(Object o) { + public boolean equals(Object o) + { if (o == this) { return true; } @@ -85,7 +99,8 @@ public boolean equals(Object o) { } @Override - public int hashCode() { + public int hashCode() + { int hash = 31 + type; for (byte e : data) { hash = 31 * hash + e; @@ -94,7 +109,8 @@ public int hashCode() { } @Override - public String toString() { + public String toString() + { StringBuilder sb = new StringBuilder(); sb.append('('); sb.append(Byte.toString(type)); diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableLongValueImpl.java b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableLongValueImpl.java index adad02764..65e184f1c 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableLongValueImpl.java +++ b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableLongValueImpl.java @@ -15,23 +15,30 @@ // package org.msgpack.value.impl; -import org.msgpack.core.MessagePacker; import org.msgpack.core.MessageIntegerOverflowException; -import org.msgpack.value.*; +import org.msgpack.core.MessagePacker; +import org.msgpack.value.ImmutableIntegerValue; +import org.msgpack.value.ImmutableNumberValue; +import org.msgpack.value.IntegerValue; +import org.msgpack.value.Value; +import org.msgpack.value.ValueType; import java.io.IOException; import java.math.BigInteger; - /** * {@code ImmutableLongValueImpl} Implements {@code ImmutableIntegerValue} using a {@code long} field. * - * @see org.msgpack.value.IntegerValue + * @see org.msgpack.value.IntegerValue */ -public class ImmutableLongValueImpl extends AbstractImmutableValue implements ImmutableIntegerValue { +public class ImmutableLongValueImpl + extends AbstractImmutableValue + implements ImmutableIntegerValue +{ private final long value; - public ImmutableLongValueImpl(long value) { + public ImmutableLongValueImpl(long value) + { this.value = value; } @@ -43,82 +50,98 @@ public ImmutableLongValueImpl(long value) { private static final long INT_MAX = (long) Integer.MAX_VALUE; @Override - public ValueType getValueType() { + public ValueType getValueType() + { return ValueType.INTEGER; } @Override - public ImmutableIntegerValue immutableValue() { + public ImmutableIntegerValue immutableValue() + { return this; } @Override - public ImmutableNumberValue asNumberValue() { + public ImmutableNumberValue asNumberValue() + { return this; } @Override - public ImmutableIntegerValue asIntegerValue() { + public ImmutableIntegerValue asIntegerValue() + { return this; } @Override - public byte castAsByte() { + public byte castAsByte() + { return (byte) value; } @Override - public short castAsShort() { + public short castAsShort() + { return (short) value; } @Override - public int castAsInt() { + public int castAsInt() + { return (int) value; } @Override - public long castAsLong() { + public long castAsLong() + { return value; } @Override - public BigInteger castAsBigInteger() { + public BigInteger castAsBigInteger() + { return BigInteger.valueOf(value); } @Override - public float castAsFloat() { + public float castAsFloat() + { return (float) value; } @Override - public double castAsDouble() { + public double castAsDouble() + { return (double) value; } @Override - public boolean isInByteRange() { + public boolean isInByteRange() + { return BYTE_MIN <= value && value <= BYTE_MAX; } @Override - public boolean isInShortRange() { + public boolean isInShortRange() + { return SHORT_MIN <= value && value <= SHORT_MAX; } @Override - public boolean isInIntRange() { + public boolean isInIntRange() + { return INT_MIN <= value && value <= INT_MAX; } @Override - public boolean isInLongRange() { + public boolean isInLongRange() + { return true; } @Override - public byte getByte() { + public byte getByte() + { if (!isInByteRange()) { throw new MessageIntegerOverflowException(value); } @@ -126,7 +149,8 @@ public byte getByte() { } @Override - public short getShort() { + public short getShort() + { if (!isInByteRange()) { throw new MessageIntegerOverflowException(value); } @@ -134,7 +158,8 @@ public short getShort() { } @Override - public int getInt() { + public int getInt() + { if (!isInIntRange()) { throw new MessageIntegerOverflowException(value); } @@ -142,22 +167,27 @@ public int getInt() { } @Override - public long getLong() { + public long getLong() + { return value; } @Override - public BigInteger getBigInteger() { + public BigInteger getBigInteger() + { return BigInteger.valueOf((long) value); } @Override - public void writeTo(MessagePacker pk) throws IOException { + public void writeTo(MessagePacker pk) + throws IOException + { pk.packLong(value); } @Override - public boolean equals(Object o) { + public boolean equals(Object o) + { if (o == this) { return true; } @@ -177,16 +207,19 @@ public boolean equals(Object o) { } @Override - public int hashCode() { + public int hashCode() + { if (INT_MIN <= value && value <= INT_MAX) { return (int) value; - } else { + } + else { return (int) (value ^ (value >>> 32)); } } @Override - public String toString() { + public String toString() + { return Long.toString(value); } } diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableMapValueImpl.java b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableMapValueImpl.java index bb477919e..b9a0a6f5c 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableMapValueImpl.java +++ b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableMapValueImpl.java @@ -16,85 +16,103 @@ package org.msgpack.value.impl; import org.msgpack.core.MessagePacker; -import org.msgpack.value.*; +import org.msgpack.value.ImmutableMapValue; +import org.msgpack.value.MapValue; +import org.msgpack.value.Value; +import org.msgpack.value.ValueType; import java.io.IOException; -import java.util.Map; -import java.util.Set; -import java.util.Collection; +import java.util.AbstractCollection; import java.util.AbstractMap; import java.util.AbstractSet; -import java.util.AbstractCollection; -import java.util.Iterator; import java.util.Arrays; +import java.util.Collection; +import java.util.Iterator; +import java.util.Map; import java.util.NoSuchElementException; - +import java.util.Set; /** * {@code ImmutableMapValueImpl} Implements {@code ImmutableMapValue} using a {@code Value[]} field. * - * @see org.msgpack.value.MapValue + * @see org.msgpack.value.MapValue */ -public class ImmutableMapValueImpl extends AbstractImmutableValue implements ImmutableMapValue { - private static ImmutableMapValueImpl EMPTY = new ImmutableMapValueImpl(new Value[0]); - - public static ImmutableMapValue empty() { +public class ImmutableMapValueImpl + extends AbstractImmutableValue + implements ImmutableMapValue +{ + private static final ImmutableMapValueImpl EMPTY = new ImmutableMapValueImpl(new Value[0]); + + public static ImmutableMapValue empty() + { return EMPTY; } private final Value[] kvs; - public ImmutableMapValueImpl(Value[] kvs) { + public ImmutableMapValueImpl(Value[] kvs) + { this.kvs = kvs; } @Override - public ValueType getValueType() { + public ValueType getValueType() + { return ValueType.MAP; } @Override - public ImmutableMapValue immutableValue() { + public ImmutableMapValue immutableValue() + { return this; } @Override - public ImmutableMapValue asMapValue() { + public ImmutableMapValue asMapValue() + { return this; } @Override - public Value[] getKeyValueArray() { + public Value[] getKeyValueArray() + { return Arrays.copyOf(kvs, kvs.length); } @Override - public int size() { + public int size() + { return kvs.length / 2; } @Override - public Set keySet() { + public Set keySet() + { return new KeySet(kvs); } @Override - public Set> entrySet() { + public Set> entrySet() + { return new EntrySet(kvs); } @Override - public Collection values() { + public Collection values() + { return new ValueCollection(kvs); } @Override - public Map map() { + public Map map() + { return new ImmutableMapValueMap(kvs); } @Override - public void writeTo(MessagePacker pk) throws IOException { + public void writeTo(MessagePacker pk) + throws IOException + { pk.packMapHeader(kvs.length / 2); for (int i = 0; i < kvs.length; i++) { kvs[i].writeTo(pk); @@ -102,7 +120,8 @@ public void writeTo(MessagePacker pk) throws IOException { } @Override - public boolean equals(Object o) { + public boolean equals(Object o) + { if (o == this) { return true; } @@ -119,7 +138,8 @@ public boolean equals(Object o) { } @Override - public int hashCode() { + public int hashCode() + { int h = 0; for (int i = 0; i < kvs.length; i += 2) { h += kvs[i].hashCode() ^ kvs[i + 1].hashCode(); @@ -128,11 +148,13 @@ public int hashCode() { } @Override - public String toString() { + public String toString() + { return toString(new StringBuilder()).toString(); } - private StringBuilder toString(StringBuilder sb) { + private StringBuilder toString(StringBuilder sb) + { if (kvs.length == 0) { return sb.append("{}"); } @@ -150,53 +172,67 @@ private StringBuilder toString(StringBuilder sb) { return sb; } - private static class ImmutableMapValueMap extends AbstractMap { + private static class ImmutableMapValueMap + extends AbstractMap + { private final Value[] kvs; - public ImmutableMapValueMap(Value[] kvs) { + public ImmutableMapValueMap(Value[] kvs) + { this.kvs = kvs; } @Override - public Set> entrySet() { + public Set> entrySet() + { return new EntrySet(kvs); } } - private static class EntrySet extends AbstractSet> { + private static class EntrySet + extends AbstractSet> + { private final Value[] kvs; - EntrySet(Value[] kvs) { + EntrySet(Value[] kvs) + { this.kvs = kvs; } @Override - public int size() { + public int size() + { return kvs.length / 2; } @Override - public Iterator> iterator() { + public Iterator> iterator() + { return new EntrySetIterator(kvs); } } - private static class EntrySetIterator implements Iterator> { + private static class EntrySetIterator + implements Iterator> + { private final Value[] kvs; private int index; - EntrySetIterator(Value[] kvs) { + EntrySetIterator(Value[] kvs) + { this.kvs = kvs; this.index = 0; } @Override - public boolean hasNext() { + public boolean hasNext() + { return index < kvs.length; } @Override - public Map.Entry next() { + public Map.Entry next() + { if (index >= kvs.length) { throw new NoSuchElementException(); // TODO message } @@ -210,63 +246,79 @@ public Map.Entry next() { } @Override - public void remove() { + public void remove() + { throw new UnsupportedOperationException(); // TODO message } } - private static class KeySet extends AbstractSet { + private static class KeySet + extends AbstractSet + { private Value[] kvs; - KeySet(Value[] kvs) { + KeySet(Value[] kvs) + { this.kvs = kvs; } @Override - public int size() { + public int size() + { return kvs.length / 2; } @Override - public Iterator iterator() { + public Iterator iterator() + { return new EntryIterator(kvs, 0); } } - private static class ValueCollection extends AbstractCollection { + private static class ValueCollection + extends AbstractCollection + { private Value[] kvs; - ValueCollection(Value[] kvs) { + ValueCollection(Value[] kvs) + { this.kvs = kvs; } @Override - public int size() { + public int size() + { return kvs.length / 2; } @Override - public Iterator iterator() { + public Iterator iterator() + { return new EntryIterator(kvs, 1); } } - private static class EntryIterator implements Iterator { + private static class EntryIterator + implements Iterator + { private Value[] kvs; private int index; - public EntryIterator(Value[] kvs, int offset) { + public EntryIterator(Value[] kvs, int offset) + { this.kvs = kvs; this.index = offset; } @Override - public boolean hasNext() { + public boolean hasNext() + { return index < kvs.length; } @Override - public Value next() { + public Value next() + { int i = index; if (i >= kvs.length) { throw new NoSuchElementException(); @@ -276,7 +328,8 @@ public Value next() { } @Override - public void remove() { + public void remove() + { throw new UnsupportedOperationException(); } } diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableNilValueImpl.java b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableNilValueImpl.java index c8f9c3bcc..dab10b54f 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableNilValueImpl.java +++ b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableNilValueImpl.java @@ -16,51 +16,62 @@ package org.msgpack.value.impl; import org.msgpack.core.MessagePacker; +import org.msgpack.value.ImmutableNilValue; import org.msgpack.value.Value; import org.msgpack.value.ValueType; -import org.msgpack.value.ImmutableNilValue; import java.io.IOException; - /** * {@code ImmutableNilValueImpl} Implements {@code ImmutableNilValue}. - * + *

* This class is a singleton. {@code ImmutableNilValueImpl.get()} is the only instances of this class. * - * @see org.msgpack.value.NilValue + * @see org.msgpack.value.NilValue */ -public class ImmutableNilValueImpl extends AbstractImmutableValue implements ImmutableNilValue { +public class ImmutableNilValueImpl + extends AbstractImmutableValue + implements ImmutableNilValue +{ private static ImmutableNilValue instance = new ImmutableNilValueImpl(); - public static ImmutableNilValue get() { + public static ImmutableNilValue get() + { return instance; } - private ImmutableNilValueImpl() { } + private ImmutableNilValueImpl() + { + } @Override - public ValueType getValueType() { + public ValueType getValueType() + { return ValueType.NIL; } @Override - public ImmutableNilValue immutableValue() { + public ImmutableNilValue immutableValue() + { return this; } @Override - public ImmutableNilValue asNilValue() { + public ImmutableNilValue asNilValue() + { return this; } @Override - public void writeTo(MessagePacker pk) throws IOException { + public void writeTo(MessagePacker pk) + throws IOException + { pk.packNil(); } @Override - public boolean equals(Object o) { + public boolean equals(Object o) + { if (o == this) { return true; } @@ -71,12 +82,14 @@ public boolean equals(Object o) { } @Override - public int hashCode() { + public int hashCode() + { return 0; } @Override - public String toString() { + public String toString() + { return "null"; } } diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableStringValueImpl.java b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableStringValueImpl.java index 59e2cefb1..e40139979 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableStringValueImpl.java +++ b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableStringValueImpl.java @@ -16,52 +16,62 @@ package org.msgpack.value.impl; import org.msgpack.core.MessagePacker; +import org.msgpack.value.ImmutableStringValue; import org.msgpack.value.Value; import org.msgpack.value.ValueType; -import org.msgpack.value.ImmutableStringValue; -import java.util.Arrays; import java.io.IOException; - +import java.util.Arrays; /** * {@code ImmutableStringValueImpl} Implements {@code ImmutableStringValue} using a {@code byte[]} field. * This implementation caches result of {@code stringValue()} and {@code getString()} using a private {@code String} field. * - * @see org.msgpack.value.StringValue + * @see org.msgpack.value.StringValue */ -public class ImmutableStringValueImpl extends AbstractImmutableRawValue implements ImmutableStringValue { - public ImmutableStringValueImpl(byte[] data) { +public class ImmutableStringValueImpl + extends AbstractImmutableRawValue + implements ImmutableStringValue +{ + public ImmutableStringValueImpl(byte[] data) + { super(data); } - public ImmutableStringValueImpl(String string) { + public ImmutableStringValueImpl(String string) + { super(string); } @Override - public ValueType getValueType() { + public ValueType getValueType() + { return ValueType.STRING; } @Override - public ImmutableStringValue immutableValue() { + public ImmutableStringValue immutableValue() + { return this; } @Override - public ImmutableStringValue asStringValue() { + public ImmutableStringValue asStringValue() + { return this; } @Override - public void writeTo(MessagePacker pk) throws IOException { + public void writeTo(MessagePacker pk) + throws IOException + { pk.packRawStringHeader(data.length); pk.writePayload(data); } @Override - public boolean equals(Object o) { + public boolean equals(Object o) + { if (this == o) { return true; } @@ -76,13 +86,15 @@ public boolean equals(Object o) { if (v instanceof ImmutableStringValueImpl) { ImmutableStringValueImpl bv = (ImmutableStringValueImpl) v; return Arrays.equals(data, bv.data); - } else { + } + else { return Arrays.equals(data, v.asStringValue().getByteArray()); } } @Override - public int hashCode() { + public int hashCode() + { return Arrays.hashCode(data); } } diff --git a/msgpack-core/src/test/java/org/msgpack/core/example/MessagePackExample.java b/msgpack-core/src/test/java/org/msgpack/core/example/MessagePackExample.java index 8e29c5255..e0ea34679 100644 --- a/msgpack-core/src/test/java/org/msgpack/core/example/MessagePackExample.java +++ b/msgpack-core/src/test/java/org/msgpack/core/example/MessagePackExample.java @@ -15,35 +15,51 @@ // package org.msgpack.core.example; -import org.msgpack.core.*; -import org.msgpack.value.*; - +import org.msgpack.core.MessageFormat; +import org.msgpack.core.MessagePack; +import org.msgpack.core.MessagePacker; +import org.msgpack.core.MessageUnpacker; +import org.msgpack.value.ArrayValue; +import org.msgpack.value.ExtensionValue; +import org.msgpack.value.FloatValue; +import org.msgpack.value.IntegerValue; +import org.msgpack.value.Value; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; import java.math.BigInteger; -import java.io.*; import java.nio.ByteBuffer; import java.nio.charset.CodingErrorAction; /** * This class describes the usage of MessagePack v07 */ -public class MessagePackExample { - +public class MessagePackExample +{ + private MessagePackExample() + { + } /** * Basic usage example + * * @throws IOException */ - public static void basicUsage() throws IOException { - + public static void basicUsage() + throws IOException + { // Serialize with MessagePacker ByteArrayOutputStream out = new ByteArrayOutputStream(); MessagePacker packer = MessagePack.newDefaultPacker(out); packer - .packInt(1) - .packString("leo") - .packArrayHeader(2) - .packString("xxx-xxxx") - .packString("yyy-yyyy"); + .packInt(1) + .packString("leo") + .packArrayHeader(2) + .packString("xxx-xxxx") + .packString("yyy-yyyy"); packer.close(); // Deserialize with MessageUnpacker @@ -52,7 +68,7 @@ public static void basicUsage() throws IOException { String name = unpacker.unpackString(); // "leo" int numPhones = unpacker.unpackArrayHeader(); // 2 String[] phones = new String[numPhones]; - for(int i=0; i < numPhones; ++i) { + for (int i = 0; i < numPhones; ++i) { phones[i] = unpacker.unpackString(); // phones = {"xxx-xxxx", "yyy-yyyy"} } unpacker.close(); @@ -60,10 +76,11 @@ public static void basicUsage() throws IOException { System.out.println(String.format("id:%d, name:%s, phone:[%s]", id, name, join(phones))); } - private static String join(String[] in) { + private static String join(String[] in) + { StringBuilder s = new StringBuilder(); - for(int i=0; i 0) { + for (int i = 0; i < in.length; ++i) { + if (i > 0) { s.append(", "); } s.append(in[i]); @@ -73,10 +90,12 @@ private static String join(String[] in) { /** * Packing various types of data + * * @throws IOException */ - public static void packer() throws IOException { - + public static void packer() + throws IOException + { // Create a MesagePacker (encoder) instance ByteArrayOutputStream out = new ByteArrayOutputStream(); MessagePacker packer = MessagePack.newDefaultPacker(out); @@ -102,9 +121,9 @@ public static void packer() throws IOException { packer.writePayload(s); // pack arrays - int[] arr = new int[]{3, 5, 1, 0, -1, 255}; + int[] arr = new int[] {3, 5, 1, 0, -1, 255}; packer.packArrayHeader(arr.length); - for(int v : arr) { + for (int v : arr) { packer.packInt(v); } @@ -118,11 +137,10 @@ public static void packer() throws IOException { packer.packInt(2); // pack binary data - byte[] ba = new byte[]{1, 2, 3, 4}; + byte[] ba = new byte[] {1, 2, 3, 4}; packer.packBinaryHeader(ba.length); packer.writePayload(ba); - // Write ext type data: https://github.com/msgpack/msgpack/blob/master/spec.md#ext-format-family byte[] extData = "custom data type".getBytes(MessagePack.UTF8); packer.packExtensionTypeHeader((byte) 1, 10); // type number [0, 127], data byte length @@ -130,27 +148,26 @@ public static void packer() throws IOException { // Succinct syntax for packing packer - .packInt(1) - .packString("leo") - .packArrayHeader(2) - .packString("xxx-xxxx") - .packString("yyy-yyyy"); - + .packInt(1) + .packString("leo") + .packArrayHeader(2) + .packString("xxx-xxxx") + .packString("yyy-yyyy"); // [Advanced] write data using ByteBuffer ByteBuffer bb = ByteBuffer.wrap(new byte[] {'b', 'i', 'n', 'a', 'r', 'y', 'd', 'a', 't', 'a'}); packer.packBinaryHeader(bb.remaining()); packer.writePayload(bb); - } - /** * An example of reading and writing MessagePack data + * * @throws IOException */ - public static void readAndWriteFile() throws IOException { - + public static void readAndWriteFile() + throws IOException + { File tempFile = File.createTempFile("target/tmp", ".txt"); tempFile.deleteOnExit(); @@ -164,7 +181,7 @@ public static void readAndWriteFile() throws IOException { // Read packed data from a file. No need exists to wrap the file stream with an buffer MessageUnpacker unpacker = MessagePack.newDefaultUnpacker(new FileInputStream(tempFile)); - while(unpacker.hasNext()) { + while (unpacker.hasNext()) { // [Advanced] You can check the detailed data format with getNextFormat() // Here is a list of message pack data format: https://github.com/msgpack/msgpack/blob/master/spec.md#overview MessageFormat format = unpacker.getNextFormat(); @@ -172,7 +189,7 @@ public static void readAndWriteFile() throws IOException { // Alternatively you can use ValueHolder to extract a value of any type // NOTE: Value interface is in a preliminary state, so the following code might change in future releases Value v = unpacker.unpackValue(); - switch(v.getValueType()) { + switch (v.getValueType()) { case NIL: v.isNilValue(); // true System.out.println("read nil"); @@ -183,7 +200,7 @@ public static void readAndWriteFile() throws IOException { break; case INTEGER: IntegerValue iv = v.asIntegerValue(); - if(iv.isInIntRange()) { + if (iv.isInIntRange()) { int i = iv.castAsInt(); System.out.println("read int: " + i); } @@ -212,7 +229,7 @@ else if (iv.isInLongRange()) { break; case ARRAY: ArrayValue a = v.asArrayValue(); - for(Value e : a) { + for (Value e : a) { System.out.println("read array element: " + e); } break; @@ -223,21 +240,22 @@ else if (iv.isInLongRange()) { break; } } - } /** * Example of using custom MessagePack configuration + * * @throws IOException */ - public static void configuration() throws IOException { - + public static void configuration() + throws IOException + { // Build a conifiguration MessagePack.Config config = new MessagePack.ConfigBuilder() - .onMalFormedInput(CodingErrorAction.REPLACE) // Drop malformed and unmappable UTF-8 characters - .onUnmappableCharacter(CodingErrorAction.REPLACE) - .packerBufferSize(8192 * 2) - .build(); + .onMalFormedInput(CodingErrorAction.REPLACE) // Drop malformed and unmappable UTF-8 characters + .onUnmappableCharacter(CodingErrorAction.REPLACE) + .packerBufferSize(8192 * 2) + .build(); // Create a that uses this configuration MessagePack msgpack = new MessagePack(config); @@ -255,9 +273,4 @@ public static void configuration() throws IOException { boolean b = unpacker.unpackBoolean(); // true unpacker.close(); } - - - - - } diff --git a/msgpack-core/src/test/scala/org/msgpack/core/MessageFormatTest.scala b/msgpack-core/src/test/scala/org/msgpack/core/MessageFormatTest.scala index 7f89760f8..9b9939608 100644 --- a/msgpack-core/src/test/scala/org/msgpack/core/MessageFormatTest.scala +++ b/msgpack-core/src/test/scala/org/msgpack/core/MessageFormatTest.scala @@ -1,52 +1,56 @@ package org.msgpack.core -import org.scalatest.exceptions.TestFailedException import org.msgpack.core.MessagePack.Code -import scala.util.Random import org.msgpack.value.ValueType +import org.scalatest.exceptions.TestFailedException + +import scala.util.Random /** * Created on 2014/05/07. */ -class MessageFormatTest extends MessagePackSpec { - +class MessageFormatTest + extends MessagePackSpec { "MessageFormat" should { "cover all byte codes" in { - - def checkV(b:Byte, tpe:ValueType) { + def checkV(b: Byte, tpe: ValueType) { try MessageFormat.valueOf(b).getValueType shouldBe tpe catch { - case e:TestFailedException => + case e: TestFailedException => error(f"Failure when looking at byte ${b}%02x") throw e } } - def checkF(b:Byte, f:MessageFormat) { + def checkF(b: Byte, f: MessageFormat) { MessageFormat.valueOf(b) shouldBe f } - def check(b:Byte, tpe:ValueType, f:MessageFormat) { + def check(b: Byte, tpe: ValueType, f: MessageFormat) { checkV(b, tpe) checkF(b, f) } - for(i <- 0 until 0x7f) + for (i <- 0 until 0x7f) { check(i.toByte, ValueType.INTEGER, MessageFormat.POSFIXINT) + } - for(i <- 0x80 until 0x8f) + for (i <- 0x80 until 0x8f) { check(i.toByte, ValueType.MAP, MessageFormat.FIXMAP) + } - for(i <- 0x90 until 0x9f) + for (i <- 0x90 until 0x9f) { check(i.toByte, ValueType.ARRAY, MessageFormat.FIXARRAY) + } check(Code.NIL, ValueType.NIL, MessageFormat.NIL) MessageFormat.valueOf(Code.NEVER_USED) shouldBe MessageFormat.NEVER_USED - for(i <- Seq(Code.TRUE, Code.FALSE)) + for (i <- Seq(Code.TRUE, Code.FALSE)) { check(i, ValueType.BOOLEAN, MessageFormat.BOOLEAN) + } check(Code.BIN8, ValueType.BINARY, MessageFormat.BIN8) check(Code.BIN16, ValueType.BINARY, MessageFormat.BIN16) @@ -82,13 +86,12 @@ class MessageFormatTest extends MessagePackSpec { check(Code.ARRAY16, ValueType.ARRAY, MessageFormat.ARRAY16) check(Code.ARRAY32, ValueType.ARRAY, MessageFormat.ARRAY32) - for(i <- 0xe0 to 0xff) + for (i <- 0xe0 to 0xff) { check(i.toByte, ValueType.INTEGER, MessageFormat.NEGFIXINT) - + } } "improve the valueOf performance" in { - val N = 1000000 val idx = (0 until N).map(x => Random.nextInt(256).toByte).toArray[Byte] @@ -98,7 +101,7 @@ class MessageFormatTest extends MessagePackSpec { time("lookup", repeat = 10) { block("switch") { var i = 0 - while(i < N) { + while (i < N) { MessageFormat.toMessageFormat(idx(i)) i += 1 } @@ -106,18 +109,12 @@ class MessageFormatTest extends MessagePackSpec { block("table") { var i = 0 - while(i < N) { + while (i < N) { MessageFormat.valueOf(idx(i)) i += 1 } } - } - } - } - - - } diff --git a/msgpack-core/src/test/scala/org/msgpack/core/MessagePackSpec.scala b/msgpack-core/src/test/scala/org/msgpack/core/MessagePackSpec.scala index 8eec662c4..b8be3bed0 100644 --- a/msgpack-core/src/test/scala/org/msgpack/core/MessagePackSpec.scala +++ b/msgpack-core/src/test/scala/org/msgpack/core/MessagePackSpec.scala @@ -15,12 +15,14 @@ // package org.msgpack.core +import java.io.ByteArrayOutputStream + import org.scalatest._ +import org.scalatest.prop.PropertyChecks import xerial.core.log.{LogLevel, Logger} import xerial.core.util.{TimeReport, Timer} + import scala.language.implicitConversions -import org.scalatest.prop.PropertyChecks -import java.io.ByteArrayOutputStream trait MessagePackSpec extends WordSpec @@ -32,43 +34,36 @@ trait MessagePackSpec with Benchmark with Logger { - implicit def toTag(s:String) : Tag = Tag(s) + implicit def toTag(s: String): Tag = Tag(s) - def toHex(arr:Array[Byte]) = arr.map(x => f"$x%02x").mkString(" ") + def toHex(arr: Array[Byte]) = arr.map(x => f"$x%02x").mkString(" ") - - def createMessagePackData(f: MessagePacker => Unit) : Array[Byte] = { - val b = new ByteArrayOutputStream() + def createMessagePackData(f: MessagePacker => Unit): Array[Byte] = { + val b = new + ByteArrayOutputStream() val packer = MessagePack.newDefaultPacker(b) f(packer) packer.close() b.toByteArray } - - - - } - -trait Benchmark extends Timer { +trait Benchmark + extends Timer { val numWarmUpRuns = 10 - override protected def time[A](blockName: String, logLevel: LogLevel, repeat: Int)(f: => A): TimeReport = { - super.time(blockName, logLevel=LogLevel.INFO, repeat)(f) + super.time(blockName, logLevel = LogLevel.INFO, repeat)(f) } override protected def block[A](name: String, repeat: Int)(f: => A): TimeReport = { var i = 0 - while(i < numWarmUpRuns) { + while (i < numWarmUpRuns) { f i += 1 } super.block(name, repeat)(f) - } - } \ No newline at end of file diff --git a/msgpack-core/src/test/scala/org/msgpack/core/MessagePackTest.scala b/msgpack-core/src/test/scala/org/msgpack/core/MessagePackTest.scala index 6c1fbb791..7d87b02a7 100644 --- a/msgpack-core/src/test/scala/org/msgpack/core/MessagePackTest.scala +++ b/msgpack-core/src/test/scala/org/msgpack/core/MessagePackTest.scala @@ -15,25 +15,26 @@ // package org.msgpack.core -import org.msgpack.value.{Variable, Value} - -import scala.util.Random -import MessagePack.Code import java.io.ByteArrayOutputStream import java.math.BigInteger import java.nio.CharBuffer -import java.nio.charset.{UnmappableCharacterException, CodingErrorAction} +import java.nio.charset.{CodingErrorAction, UnmappableCharacterException} + +import org.msgpack.core.MessagePack.Code +import org.msgpack.value.{Value, Variable} + +import scala.util.Random /** * Created on 2014/05/07. */ -class MessagePackTest extends MessagePackSpec { +class MessagePackTest extends MessagePackSpec { def isValidUTF8(s: String) = { MessagePack.UTF8.newEncoder().canEncode(s) } - def containsUnmappableCharacter(s: String) : Boolean = { + def containsUnmappableCharacter(s: String): Boolean = { try { MessagePack.UTF8.newEncoder().onUnmappableCharacter(CodingErrorAction.REPORT).encode(CharBuffer.wrap(s)) false @@ -116,7 +117,7 @@ class MessagePackTest extends MessagePackSpec { } - def check[A](v: A, pack: MessagePacker => Unit, unpack: MessageUnpacker => A, msgpack:MessagePack = MessagePack.DEFAULT): Unit = { + def check[A](v: A, pack: MessagePacker => Unit, unpack: MessageUnpacker => A, msgpack: MessagePack = MessagePack.DEFAULT): Unit = { var b: Array[Byte] = null try { val bs = new ByteArrayOutputStream() @@ -133,13 +134,15 @@ class MessagePackTest extends MessagePackSpec { catch { case e: Exception => warn(e.getMessage) - if (b != null) + if (b != null) { warn(s"packed data (size:${b.length}): ${toHex(b)}") + } throw e } } - def checkException[A](v: A, pack: MessagePacker => Unit, unpack: MessageUnpacker => A, msgpack:MessagePack=MessagePack.DEFAULT) : Unit = { + def checkException[A](v: A, pack: MessagePacker => Unit, unpack: MessageUnpacker => A, + msgpack: MessagePack = MessagePack.DEFAULT): Unit = { var b: Array[Byte] = null val bs = new ByteArrayOutputStream() val packer = msgpack.newPacker(bs) @@ -159,30 +162,32 @@ class MessagePackTest extends MessagePackSpec { checkException[A](v, pack, unpack) } catch { - case e:MessageIntegerOverflowException => // OK + case e: MessageIntegerOverflowException => // OK } } - "pack/unpack primitive values" taggedAs("prim") in { - forAll { (v: Boolean) => check(v, _.packBoolean(v), _.unpackBoolean)} - forAll { (v: Byte) => check(v, _.packByte(v), _.unpackByte)} - forAll { (v: Short) => check(v, _.packShort(v), _.unpackShort)} - forAll { (v: Int) => check(v, _.packInt(v), _.unpackInt)} - forAll { (v: Float) => check(v, _.packFloat(v), _.unpackFloat)} - forAll { (v: Long) => check(v, _.packLong(v), _.unpackLong)} - forAll { (v: Double) => check(v, _.packDouble(v), _.unpackDouble)} - check(null, _.packNil, {unpacker => unpacker.unpackNil(); null}) + "pack/unpack primitive values" taggedAs ("prim") in { + forAll { (v: Boolean) => check(v, _.packBoolean(v), _.unpackBoolean) } + forAll { (v: Byte) => check(v, _.packByte(v), _.unpackByte) } + forAll { (v: Short) => check(v, _.packShort(v), _.unpackShort) } + forAll { (v: Int) => check(v, _.packInt(v), _.unpackInt) } + forAll { (v: Float) => check(v, _.packFloat(v), _.unpackFloat) } + forAll { (v: Long) => check(v, _.packLong(v), _.unpackLong) } + forAll { (v: Double) => check(v, _.packDouble(v), _.unpackDouble) } + check(null, _.packNil, { unpacker => unpacker.unpackNil(); null }) } - "pack/unpack integer values" taggedAs("int") in { - val sampleData = Seq[Long](Int.MinValue.toLong - 10, -65535, -8191, -1024, -255, -127, -63, -31, -15, -7, -3, -1, 0, 2, 4, 8, 16, 32, 64, 128, 256, 1024, 8192, 65536, Int.MaxValue.toLong + 10) - for(v <- sampleData) { + "pack/unpack integer values" taggedAs ("int") in { + val sampleData = Seq[Long](Int.MinValue.toLong - + 10, -65535, -8191, -1024, -255, -127, -63, -31, -15, -7, -3, -1, 0, 2, 4, 8, 16, 32, 64, 128, 256, 1024, 8192, 65536, + Int.MaxValue.toLong + 10) + for (v <- sampleData) { check(v, _.packLong(v), _.unpackLong) - if(v.isValidInt) { + if (v.isValidInt) { val vi = v.toInt check(vi, _.packInt(vi), _.unpackInt) } @@ -190,7 +195,7 @@ class MessagePackTest extends MessagePackSpec { checkOverflow(v, _.packLong(v), _.unpackInt) } - if(v.isValidShort) { + if (v.isValidShort) { val vi = v.toShort check(vi, _.packShort(vi), _.unpackShort) } @@ -198,7 +203,7 @@ class MessagePackTest extends MessagePackSpec { checkOverflow(v, _.packLong(v), _.unpackShort) } - if(v.isValidByte) { + if (v.isValidByte) { val vi = v.toByte check(vi, _.packByte(vi), _.unpackByte) } @@ -210,23 +215,23 @@ class MessagePackTest extends MessagePackSpec { } - "pack/unpack BigInteger" taggedAs("bi") in { + "pack/unpack BigInteger" taggedAs ("bi") in { forAll { (a: Long) => val v = BigInteger.valueOf(a) check(v, _.packBigInteger(v), _.unpackBigInteger) } - for(bi <- Seq(BigInteger.valueOf(Long.MaxValue).add(BigInteger.valueOf(1)))) { + for (bi <- Seq(BigInteger.valueOf(Long.MaxValue).add(BigInteger.valueOf(1)))) { check(bi, _.packBigInteger(bi), _.unpackBigInteger()) } - for(bi <- Seq(BigInteger.valueOf(Long.MaxValue).shiftLeft(10))) { + for (bi <- Seq(BigInteger.valueOf(Long.MaxValue).shiftLeft(10))) { try { checkException(bi, _.packBigInteger(bi), _.unpackBigInteger()) fail("cannot reach here") } catch { - case e:IllegalArgumentException => // OK + case e: IllegalArgumentException => // OK } } @@ -244,14 +249,14 @@ class MessagePackTest extends MessagePackSpec { "pack/unpack large strings" taggedAs ("large-string") in { // Large string val strLen = Seq(1000, 2000, 10000, 50000, 100000, 500000) - for(l <- strLen) { - val v : String = Iterator.continually(Random.nextString(l * 10)).find(isValidUTF8).get + for (l <- strLen) { + val v: String = Iterator.continually(Random.nextString(l * 10)).find(isValidUTF8).get check(v, _.packString(v), _.unpackString) } } - "report errors when packing/unpacking malformed strings" taggedAs("malformed") in { + "report errors when packing/unpacking malformed strings" taggedAs ("malformed") in { // TODO produce malformed utf-8 strings in Java8" pending // Create 100 malformed UTF8 Strings @@ -286,20 +291,22 @@ class MessagePackTest extends MessagePackSpec { } } - "report errors when packing/unpacking strings that contain unmappable characters" taggedAs("unmap") in { + "report errors when packing/unpacking strings that contain unmappable characters" taggedAs ("unmap") in { val unmappable = Array[Byte](0xfc.toByte, 0x0a.toByte) //val unmappableChar = Array[Char](new Character(0xfc0a).toChar) // Report error on unmappable character - val config = new MessagePack.ConfigBuilder().onMalFormedInput(CodingErrorAction.REPORT).onUnmappableCharacter(CodingErrorAction.REPORT).build() + val config = new MessagePack.ConfigBuilder() + .onMalFormedInput(CodingErrorAction.REPORT) + .onUnmappableCharacter(CodingErrorAction.REPORT) + .build() val msgpack = new MessagePack(config) - for(bytes <- Seq(unmappable)) { + for (bytes <- Seq(unmappable)) { When("unpacking") try { - checkException(bytes, - { packer => + checkException(bytes, { packer => packer.packRawStringHeader(bytes.length) packer.writePayload(bytes) }, @@ -307,24 +314,24 @@ class MessagePackTest extends MessagePackSpec { msgpack) } catch { - case e:MessageStringCodingException => // OK + case e: MessageStringCodingException => // OK } -// When("packing") -// try { -// val s = new String(unmappableChar) -// checkException(s, _.packString(s), _.unpackString()) -// } -// catch { -// case e:MessageStringCodingException => // OK -// } - } + // When("packing") + // try { + // val s = new String(unmappableChar) + // checkException(s, _.packString(s), _.unpackString()) + // } + // catch { + // case e:MessageStringCodingException => // OK + // } + } } "pack/unpack binary" taggedAs ("binary") in { forAll { (v: Array[Byte]) => - check(v, { packer => packer.packBinaryHeader(v.length); packer.writePayload(v)}, { unpacker => + check(v, { packer => packer.packBinaryHeader(v.length); packer.writePayload(v) }, { unpacker => val len = unpacker.unpackBinaryHeader() val out = new Array[Byte](len) unpacker.readPayload(out, 0, len) @@ -334,10 +341,10 @@ class MessagePackTest extends MessagePackSpec { } val len = Seq(1000, 2000, 10000, 50000, 100000, 500000) - for(l <- len) { + for (l <- len) { val v = new Array[Byte](l) Random.nextBytes(v) - check(v, { packer => packer.packBinaryHeader(v.length); packer.writePayload(v)}, { unpacker => + check(v, { packer => packer.packBinaryHeader(v.length); packer.writePayload(v) }, { unpacker => val len = unpacker.unpackBinaryHeader() val out = new Array[Byte](len) unpacker.readPayload(out, 0, len) @@ -358,14 +365,15 @@ class MessagePackTest extends MessagePackSpec { }, { unpacker => val len = unpacker.unpackArrayHeader() val out = new Array[Int](len) - for (i <- 0 until v.length) + for (i <- 0 until v.length) { out(i) = unpacker.unpackInt + } out } ) } - for(l <- testHeaderLength) { + for (l <- testHeaderLength) { check(l, _.packArrayHeader(l), _.unpackArrayHeader()) } @@ -392,14 +400,15 @@ class MessagePackTest extends MessagePackSpec { }, { unpacker => val len = unpacker.unpackMapHeader() val b = Seq.newBuilder[(Int, String)] - for (i <- 0 until len) + for (i <- 0 until len) { b += ((unpacker.unpackInt, unpacker.unpackString)) + } b.result } ) } - for(l <- testHeaderLength) { + for (l <- testHeaderLength) { check(l, _.packMapHeader(l), _.unpackMapHeader()) } @@ -413,7 +422,7 @@ class MessagePackTest extends MessagePackSpec { } - "pack/unpack extension types" taggedAs("ext") in { + "pack/unpack extension types" taggedAs ("ext") in { forAll { (dataLen: Int, tpe: Byte) => val l = Math.abs(dataLen) whenever(l >= 0) { @@ -422,7 +431,7 @@ class MessagePackTest extends MessagePackSpec { } } - for(l <- testHeaderLength) { + for (l <- testHeaderLength) { val ext = new ExtensionTypeHeader(ExtensionTypeHeader.checkedCastToByte(Random.nextInt(128)), l) check(ext, _.packExtensionTypeHeader(ext.getType, ext.getLength), _.unpackExtensionTypeHeader()) } diff --git a/msgpack-core/src/test/scala/org/msgpack/core/MessagePackerTest.scala b/msgpack-core/src/test/scala/org/msgpack/core/MessagePackerTest.scala index 590936239..bc2ec9d1c 100644 --- a/msgpack-core/src/test/scala/org/msgpack/core/MessagePackerTest.scala +++ b/msgpack-core/src/test/scala/org/msgpack/core/MessagePackerTest.scala @@ -15,26 +15,27 @@ // package org.msgpack.core -import java.io.{FileInputStream, FileOutputStream, File, ByteArrayOutputStream} +import java.io.{ByteArrayOutputStream, File, FileInputStream, FileOutputStream} import java.nio.ByteBuffer -import org.msgpack.core.buffer.{ChannelBufferOutput, MessageBufferOutput, OutputStreamBufferOutput} +import org.msgpack.core.buffer.{ChannelBufferOutput, OutputStreamBufferOutput} +import org.msgpack.value.ValueFactory import xerial.core.io.IOUtil import scala.util.Random -import org.msgpack.value.ValueFactory /** * */ -class MessagePackerTest extends MessagePackSpec { +class MessagePackerTest + extends MessagePackSpec { val msgpack = MessagePack.DEFAULT - def verifyIntSeq(answer:Array[Int], packed:Array[Byte]) { + def verifyIntSeq(answer: Array[Int], packed: Array[Byte]) { val unpacker = msgpack.newUnpacker(packed) val b = Array.newBuilder[Int] - while(unpacker.hasNext) { + while (unpacker.hasNext) { b += unpacker.unpackInt() } val result = b.result @@ -50,7 +51,8 @@ class MessagePackerTest extends MessagePackSpec { def createTempFileWithOutputStream = { val f = createTempFile - val out = new FileOutputStream(f) + val out = new + FileOutputStream(f) (f, out) } @@ -65,37 +67,48 @@ class MessagePackerTest extends MessagePackSpec { "reset the internal states" in { val intSeq = (0 until 100).map(i => Random.nextInt).toArray - val b = new ByteArrayOutputStream + val b = new + ByteArrayOutputStream val packer = msgpack.newPacker(b) intSeq foreach packer.packInt packer.close verifyIntSeq(intSeq, b.toByteArray) val intSeq2 = intSeq.reverse - val b2 = new ByteArrayOutputStream - packer.reset(new OutputStreamBufferOutput(b2)) + val b2 = new + ByteArrayOutputStream + packer + .reset(new + OutputStreamBufferOutput(b2)) intSeq2 foreach packer.packInt packer.close verifyIntSeq(intSeq2, b2.toByteArray) val intSeq3 = intSeq2.sorted - val b3 = new ByteArrayOutputStream - packer.reset(new OutputStreamBufferOutput(b3)) + val b3 = new + ByteArrayOutputStream + packer + .reset(new + OutputStreamBufferOutput(b3)) intSeq3 foreach packer.packInt packer.close verifyIntSeq(intSeq3, b3.toByteArray) } - "improve the performance via reset method" taggedAs("reset") in { + "improve the performance via reset method" taggedAs ("reset") in { val N = 1000 val t = time("packer", repeat = 10) { block("no-buffer-reset") { - val out = new ByteArrayOutputStream + val out = new + ByteArrayOutputStream IOUtil.withResource(msgpack.newPacker(out)) { packer => for (i <- 0 until N) { - val outputStream = new ByteArrayOutputStream() - packer.reset(new OutputStreamBufferOutput(outputStream)) + val outputStream = new + ByteArrayOutputStream() + packer + .reset(new + OutputStreamBufferOutput(outputStream)) packer.packInt(0) packer.flush() } @@ -103,11 +116,15 @@ class MessagePackerTest extends MessagePackSpec { } block("buffer-reset") { - val out = new ByteArrayOutputStream + val out = new + ByteArrayOutputStream IOUtil.withResource(msgpack.newPacker(out)) { packer => - val bufferOut = new OutputStreamBufferOutput(new ByteArrayOutputStream()) + val bufferOut = new + OutputStreamBufferOutput(new + ByteArrayOutputStream()) for (i <- 0 until N) { - val outputStream = new ByteArrayOutputStream() + val outputStream = new + ByteArrayOutputStream() bufferOut.reset(outputStream) packer.reset(bufferOut) packer.packInt(0) @@ -118,7 +135,6 @@ class MessagePackerTest extends MessagePackSpec { } t("buffer-reset").averageWithoutMinMax should be <= t("no-buffer-reset").averageWithoutMinMax - } "pack larger string array than byte buf" taggedAs ("larger-string-array-than-byte-buf") in { @@ -126,11 +142,14 @@ class MessagePackerTest extends MessagePackSpec { // TODO: Refactor this test code to fit other ones. def test(bufferSize: Int, stringSize: Int): Boolean = { - val msgpack = new MessagePack(new MessagePack.ConfigBuilder().packerBufferSize(bufferSize).build) + val msgpack = new + MessagePack(new + MessagePack.ConfigBuilder().packerBufferSize(bufferSize).build) val str = "a" * stringSize val rawString = ValueFactory.newString(str.getBytes("UTF-8")) val array = ValueFactory.newArray(rawString) - val out = new ByteArrayOutputStream() + val out = new + ByteArrayOutputStream() val packer = msgpack.newPacker(out) packer.packValue(array) packer.close() @@ -144,7 +163,7 @@ class MessagePackerTest extends MessagePackSpec { 32 -> 31, 34 -> 32 ) - testCases.foreach{ + testCases.foreach { case (bufferSize, stringSize) => test(bufferSize, stringSize) } } @@ -155,20 +174,28 @@ class MessagePackerTest extends MessagePackSpec { packer.packInt(99) packer.close - val up0 = MessagePack.newDefaultUnpacker(new FileInputStream(f0)) + val up0 = MessagePack + .newDefaultUnpacker(new + FileInputStream(f0)) up0.unpackInt shouldBe 99 up0.hasNext shouldBe false up0.close val (f1, out1) = createTempFileWithOutputStream - packer.reset(new OutputStreamBufferOutput(out1)) + packer + .reset(new + OutputStreamBufferOutput(out1)) packer.packInt(99) packer.flush - packer.reset(new OutputStreamBufferOutput(out1)) + packer + .reset(new + OutputStreamBufferOutput(out1)) packer.packString("hello") packer.close - val up1 = MessagePack.newDefaultUnpacker(new FileInputStream(f1)) + val up1 = MessagePack + .newDefaultUnpacker(new + FileInputStream(f1)) up1.unpackInt shouldBe 99 up1.unpackString shouldBe "hello" up1.hasNext shouldBe false @@ -181,20 +208,28 @@ class MessagePackerTest extends MessagePackSpec { packer.packInt(99) packer.close - val up0 = MessagePack.newDefaultUnpacker(new FileInputStream(f0)) + val up0 = MessagePack + .newDefaultUnpacker(new + FileInputStream(f0)) up0.unpackInt shouldBe 99 up0.hasNext shouldBe false up0.close val (f1, out1) = createTempFileWithChannel - packer.reset(new ChannelBufferOutput(out1)) + packer + .reset(new + ChannelBufferOutput(out1)) packer.packInt(99) packer.flush - packer.reset(new ChannelBufferOutput(out1)) + packer + .reset(new + ChannelBufferOutput(out1)) packer.packString("hello") packer.close - val up1 = MessagePack.newDefaultUnpacker(new FileInputStream(f1)) + val up1 = MessagePack + .newDefaultUnpacker(new + FileInputStream(f1)) up1.unpackInt shouldBe 99 up1.unpackString shouldBe "hello" up1.hasNext shouldBe false @@ -203,15 +238,16 @@ class MessagePackerTest extends MessagePackSpec { } "compute totalWrittenBytes" in { - val out = new ByteArrayOutputStream + val out = new + ByteArrayOutputStream val packerTotalWrittenBytes = IOUtil.withResource(msgpack.newPacker(out)) { packer => packer.packByte(0) // 1 - .packBoolean(true) // 1 - .packShort(12) // 1 - .packInt(1024) // 3 - .packLong(Long.MaxValue) // 5 - .packString("foobar") // 7 - .flush() + .packBoolean(true) // 1 + .packShort(12) // 1 + .packInt(1024) // 3 + .packLong(Long.MaxValue) // 5 + .packString("foobar") // 7 + .flush() packer.getTotalWrittenBytes } @@ -219,10 +255,11 @@ class MessagePackerTest extends MessagePackSpec { out.toByteArray.length shouldBe packerTotalWrittenBytes } - "support read-only buffer" taggedAs("read-only") in { + "support read-only buffer" taggedAs ("read-only") in { val payload = Array[Byte](1) val buffer = ByteBuffer.wrap(payload).asReadOnlyBuffer() - val out = new ByteArrayOutputStream() + val out = new + ByteArrayOutputStream() val packer = MessagePack.newDefaultPacker(out) .packBinaryHeader(1) .writePayload(buffer) diff --git a/msgpack-core/src/test/scala/org/msgpack/core/MessageUnpackerTest.scala b/msgpack-core/src/test/scala/org/msgpack/core/MessageUnpackerTest.scala index 99115abc9..f6fc37cb7 100644 --- a/msgpack-core/src/test/scala/org/msgpack/core/MessageUnpackerTest.scala +++ b/msgpack-core/src/test/scala/org/msgpack/core/MessageUnpackerTest.scala @@ -1,11 +1,13 @@ package org.msgpack.core import java.io._ -import scala.util.Random + import org.msgpack.core.buffer._ import org.msgpack.value.ValueType import xerial.core.io.IOUtil +import scala.util.Random + /** * Created on 2014/05/07. */ @@ -13,7 +15,7 @@ class MessageUnpackerTest extends MessagePackSpec { val msgpack = MessagePack.DEFAULT - def testData : Array[Byte] = { + def testData: Array[Byte] = { val out = new ByteArrayOutputStream() val packer = msgpack.newPacker(out) @@ -33,10 +35,9 @@ class MessageUnpackerTest extends MessagePackSpec { arr } - val intSeq = (for(i <- 0 until 100) yield Random.nextInt()).toArray[Int] - - def testData2 : Array[Byte] = { + val intSeq = (for (i <- 0 until 100) yield Random.nextInt()).toArray[Int] + def testData2: Array[Byte] = { val out = new ByteArrayOutputStream() val packer = msgpack.newPacker(out); @@ -52,7 +53,7 @@ class MessageUnpackerTest extends MessagePackSpec { arr } - def write(packer:MessagePacker, r:Random) { + def write(packer: MessagePacker, r: Random) { val tpeIndex = Iterator.continually(r.nextInt(MessageFormat.values().length)).find(_ != MessageFormat.NEVER_USED.ordinal()).get val tpe = MessageFormat.values()(tpeIndex) tpe.getValueType match { @@ -85,7 +86,7 @@ class MessageUnpackerTest extends MessagePackSpec { trace(s"array len: $len") packer.packArrayHeader(len) var i = 0 - while(i < len) { + while (i < len) { write(packer, r) i += 1 } @@ -94,7 +95,7 @@ class MessageUnpackerTest extends MessagePackSpec { packer.packMapHeader(len) trace(s"map len: ${len}") var i = 0 - while(i < len * 2) { + while (i < len * 2) { write(packer, r) i += 1 } @@ -105,7 +106,7 @@ class MessageUnpackerTest extends MessagePackSpec { } } - def testData3(N:Int) : Array[Byte] = { + def testData3(N: Int): Array[Byte] = { val out = new ByteArrayOutputStream() val packer = msgpack.newPacker(out) @@ -122,7 +123,7 @@ class MessageUnpackerTest extends MessagePackSpec { } - def readValue(unpacker:MessageUnpacker) { + def readValue(unpacker: MessageUnpacker) { val f = unpacker.getNextFormat() f.getValueType match { case ValueType.ARRAY => @@ -152,20 +153,20 @@ class MessageUnpackerTest extends MessagePackSpec { f } - def checkFile(u:MessageUnpacker) = { + def checkFile(u: MessageUnpacker) = { u.unpackInt shouldBe 99 u.hasNext shouldBe false } "MessageUnpacker" should { - "parse message packed data" taggedAs("unpack") in { + "parse message packed data" taggedAs ("unpack") in { val arr = testData val unpacker = msgpack.newUnpacker(arr) var count = 0 - while(unpacker.hasNext) { + while (unpacker.hasNext) { count += 1 readValue(unpacker) } @@ -177,7 +178,7 @@ class MessageUnpackerTest extends MessagePackSpec { val unpacker = msgpack.newUnpacker(testData) var skipCount = 0 - while(unpacker.hasNext) { + while (unpacker.hasNext) { unpacker.skipValue() skipCount += 1 } @@ -186,7 +187,7 @@ class MessageUnpackerTest extends MessagePackSpec { unpacker.getTotalReadBytes shouldBe testData.length } - "compare skip performance" taggedAs("skip") in { + "compare skip performance" taggedAs ("skip") in { val N = 10000 val data = testData3(N) @@ -194,7 +195,7 @@ class MessageUnpackerTest extends MessagePackSpec { block("switch") { val unpacker = msgpack.newUnpacker(data) var skipCount = 0 - while(unpacker.hasNext) { + while (unpacker.hasNext) { unpacker.skipValue() skipCount += 1 } @@ -211,7 +212,7 @@ class MessageUnpackerTest extends MessagePackSpec { val ib = Seq.newBuilder[Int] val unpacker = msgpack.newUnpacker(testData2) - while(unpacker.hasNext) { + while (unpacker.hasNext) { val f = unpacker.getNextFormat f.getValueType match { case ValueType.INTEGER => @@ -231,7 +232,7 @@ class MessageUnpackerTest extends MessagePackSpec { } - class SplitMessageBufferInput(array:Array[Array[Byte]]) extends MessageBufferInput { + class SplitMessageBufferInput(array: Array[Array[Byte]]) extends MessageBufferInput { var cursor = 0 override def next(): MessageBuffer = { if (cursor < array.length) { @@ -239,17 +240,18 @@ class MessageUnpackerTest extends MessagePackSpec { cursor += 1 MessageBuffer.wrap(a) } - else + else { null + } } override def close(): Unit = {} } - "read data at the buffer boundary" taggedAs("boundary") in { + "read data at the buffer boundary" taggedAs ("boundary") in { trait SplitTest { - val data : Array[Byte] + val data: Array[Byte] def run { val unpacker = msgpack.newUnpacker(data) val numElems = { @@ -278,12 +280,12 @@ class MessageUnpackerTest extends MessagePackSpec { } } - new SplitTest { val data = testData }.run - new SplitTest { val data = testData3(30) }.run + new SplitTest {val data = testData}.run + new SplitTest {val data = testData3(30)}.run } - "be faster then msgpack-v6 skip" taggedAs("cmp-skip") in { + "be faster then msgpack-v6 skip" taggedAs ("cmp-skip") in { val data = testData3(10000) val N = 100 @@ -324,22 +326,22 @@ class MessageUnpackerTest extends MessagePackSpec { t("v7").averageWithoutMinMax should be <= t("v6").averageWithoutMinMax } - import org.msgpack.`type`.{ValueType=>ValueTypeV6} + import org.msgpack.`type`.{ValueType => ValueTypeV6} - "be faster than msgpack-v6 read value" taggedAs("cmp-unpack") in { + "be faster than msgpack-v6 read value" taggedAs ("cmp-unpack") in { - def readValueV6(unpacker:org.msgpack.unpacker.MessagePackUnpacker) { + def readValueV6(unpacker: org.msgpack.unpacker.MessagePackUnpacker) { val vt = unpacker.getNextType() vt match { case ValueTypeV6.ARRAY => val len = unpacker.readArrayBegin() var i = 0 - while(i < len) { readValueV6(unpacker); i += 1 } + while (i < len) {readValueV6(unpacker); i += 1} unpacker.readArrayEnd() case ValueTypeV6.MAP => val len = unpacker.readMapBegin() var i = 0 - while(i < len) { readValueV6(unpacker); readValueV6(unpacker); i += 1 } + while (i < len) {readValueV6(unpacker); readValueV6(unpacker); i += 1} unpacker.readMapEnd() case ValueTypeV6.NIL => unpacker.readNil() @@ -358,18 +360,18 @@ class MessageUnpackerTest extends MessagePackSpec { val buf = new Array[Byte](8192) - def readValue(unpacker:MessageUnpacker) { + def readValue(unpacker: MessageUnpacker) { val f = unpacker.getNextFormat val vt = f.getValueType vt match { case ValueType.ARRAY => val len = unpacker.unpackArrayHeader() var i = 0 - while(i < len) { readValue(unpacker); i += 1 } + while (i < len) {readValue(unpacker); i += 1} case ValueType.MAP => val len = unpacker.unpackMapHeader() var i = 0 - while(i < len) { readValue(unpacker); readValue(unpacker); i += 1 } + while (i < len) {readValue(unpacker); readValue(unpacker); i += 1} case ValueType.NIL => unpacker.unpackNil() case ValueType.INTEGER => @@ -391,19 +393,19 @@ class MessageUnpackerTest extends MessagePackSpec { val data = testData3(10000) val N = 100 - val t = time("unpack performance", repeat=N) { + val t = time("unpack performance", repeat = N) { block("v6") { val v6 = new org.msgpack.MessagePack() val unpacker = new org.msgpack.unpacker.MessagePackUnpacker(v6, new ByteArrayInputStream(data)) var count = 0 try { - while(true) { + while (true) { readValueV6(unpacker) count += 1 } } catch { - case e:EOFException => + case e: EOFException => } finally unpacker.close() @@ -428,7 +430,7 @@ class MessageUnpackerTest extends MessagePackSpec { } - "be faster for reading binary than v6" taggedAs("cmp-binary") in { + "be faster for reading binary than v6" taggedAs ("cmp-binary") in { val bos = new ByteArrayOutputStream() val packer = msgpack.newPacker(bos) @@ -441,12 +443,12 @@ class MessageUnpackerTest extends MessagePackSpec { packer.close() val b = bos.toByteArray - time("unpackBinary", repeat=100) { + time("unpackBinary", repeat = 100) { block("v6") { val v6 = new org.msgpack.MessagePack() val unpacker = new org.msgpack.unpacker.MessagePackUnpacker(v6, new ByteArrayInputStream(b)) var i = 0 - while(i < R) { + while (i < R) { val out = unpacker.readByteArray() i += 1 } @@ -456,7 +458,7 @@ class MessageUnpackerTest extends MessagePackSpec { block("v7") { val unpacker = msgpack.newUnpacker(b) var i = 0 - while(i < R) { + while (i < R) { val len = unpacker.unpackBinaryHeader() val out = new Array[Byte](len) unpacker.readPayload(out, 0, len) @@ -468,7 +470,7 @@ class MessageUnpackerTest extends MessagePackSpec { block("v7-ref") { val unpacker = msgpack.newUnpacker(b) var i = 0 - while(i < R) { + while (i < R) { val len = unpacker.unpackBinaryHeader() val out = unpacker.readPayloadAsReference(len) i += 1 @@ -478,11 +480,11 @@ class MessageUnpackerTest extends MessagePackSpec { } } - "read payload as a reference" taggedAs("ref") in { + "read payload as a reference" taggedAs ("ref") in { val dataSizes = Seq(0, 1, 5, 8, 16, 32, 128, 256, 1024, 2000, 10000, 100000) - for(s <- dataSizes) { + for (s <- dataSizes) { When(f"data size is $s%,d") val data = new Array[Byte](s) Random.nextBytes(data) @@ -507,14 +509,14 @@ class MessageUnpackerTest extends MessagePackSpec { } - "reset the internal states" taggedAs("reset") in { + "reset the internal states" taggedAs ("reset") in { val data = intSeq val b = createMessagePackData(packer => data foreach packer.packInt) val unpacker = msgpack.newUnpacker(b) val unpacked = Array.newBuilder[Int] - while(unpacker.hasNext) { + while (unpacker.hasNext) { unpacked += unpacker.unpackInt() } unpacker.close @@ -525,7 +527,7 @@ class MessageUnpackerTest extends MessagePackSpec { val bi = new ArrayBufferInput(b2) unpacker.reset(bi) val unpacked2 = Array.newBuilder[Int] - while(unpacker.hasNext) { + while (unpacker.hasNext) { unpacked2 += unpacker.unpackInt() } unpacker.close @@ -535,7 +537,7 @@ class MessageUnpackerTest extends MessagePackSpec { bi.reset(b2) unpacker.reset(bi) val unpacked3 = Array.newBuilder[Int] - while(unpacker.hasNext) { + while (unpacker.hasNext) { unpacked3 += unpacker.unpackInt() } unpacker.close @@ -543,7 +545,7 @@ class MessageUnpackerTest extends MessagePackSpec { } - "improve the performance via reset method" taggedAs("reset-arr") in { + "improve the performance via reset method" taggedAs ("reset-arr") in { val out = new ByteArrayOutputStream val packer = msgpack.newPacker(out) @@ -619,7 +621,7 @@ class MessageUnpackerTest extends MessagePackSpec { u.close } - "unpack large string data" taggedAs("large-string") in { + "unpack large string data" taggedAs ("large-string") in { def createLargeData(stringLength: Int): Array[Byte] = { val out = new ByteArrayOutputStream() val packer = msgpack.newPacker(out) diff --git a/msgpack-core/src/test/scala/org/msgpack/core/buffer/ByteStringTest.scala b/msgpack-core/src/test/scala/org/msgpack/core/buffer/ByteStringTest.scala index 60bc9f3e6..336f30755 100644 --- a/msgpack-core/src/test/scala/org/msgpack/core/buffer/ByteStringTest.scala +++ b/msgpack-core/src/test/scala/org/msgpack/core/buffer/ByteStringTest.scala @@ -3,20 +3,23 @@ package org.msgpack.core.buffer import akka.util.ByteString import org.msgpack.core.{MessagePackSpec, MessageUnpacker} -class ByteStringTest extends MessagePackSpec { +class ByteStringTest + extends MessagePackSpec { val unpackedString = "foo" val byteString = ByteString(createMessagePackData(_.packString(unpackedString))) def unpackString(messageBuffer: MessageBuffer) = { - val input = new MessageBufferInput { + val input = new + MessageBufferInput { private var isRead = false override def next(): MessageBuffer = if (isRead) { null - } else { + } + else { isRead = true messageBuffer } @@ -24,7 +27,8 @@ class ByteStringTest extends MessagePackSpec { override def close(): Unit = {} } - new MessageUnpacker(input).unpackString() + new + MessageUnpacker(input).unpackString() } "Unpacking a ByteString's ByteBuffer" should { @@ -32,11 +36,13 @@ class ByteStringTest extends MessagePackSpec { // can't demonstrate with new ByteBufferInput(byteString.asByteBuffer) // as Travis tests run with JDK6 that picks up MessageBufferU - a[RuntimeException] shouldBe thrownBy(unpackString(new MessageBuffer(byteString.asByteBuffer))) + a[RuntimeException] shouldBe thrownBy(unpackString(new + MessageBuffer(byteString.asByteBuffer))) } "succeed with a MessageBufferU" in { - unpackString(new MessageBufferU(byteString.asByteBuffer)) shouldBe unpackedString + unpackString(new + MessageBufferU(byteString.asByteBuffer)) shouldBe unpackedString } } } diff --git a/msgpack-core/src/test/scala/org/msgpack/core/buffer/MessageBufferInputTest.scala b/msgpack-core/src/test/scala/org/msgpack/core/buffer/MessageBufferInputTest.scala index 8daa5929e..8903e375c 100644 --- a/msgpack-core/src/test/scala/org/msgpack/core/buffer/MessageBufferInputTest.scala +++ b/msgpack-core/src/test/scala/org/msgpack/core/buffer/MessageBufferInputTest.scala @@ -1,23 +1,26 @@ package org.msgpack.core.buffer -import org.msgpack.core.{MessageUnpacker, MessagePack, MessagePackSpec} import java.io._ -import xerial.core.io.IOUtil._ -import scala.util.Random -import java.util.zip.{GZIPOutputStream, GZIPInputStream} import java.nio.ByteBuffer +import java.util.zip.{GZIPInputStream, GZIPOutputStream} +import org.msgpack.core.{MessagePack, MessagePackSpec, MessageUnpacker} +import xerial.core.io.IOUtil._ + +import scala.util.Random /** * Created on 5/30/14. */ -class MessageBufferInputTest extends MessagePackSpec { +class MessageBufferInputTest + extends MessagePackSpec { val targetInputSize = Seq(0, 10, 500, 1000, 2000, 4000, 8000, 10000, 30000, 50000, 100000) - def testData(size:Int) = { + def testData(size: Int) = { //debug(s"test data size: ${size}") - val b = new Array[Byte](size) + val b = new + Array[Byte](size) Random.nextBytes(b) b } @@ -25,17 +28,19 @@ class MessageBufferInputTest extends MessagePackSpec { def testDataSet = { targetInputSize.map(testData) } - - def runTest(factory:Array[Byte] => MessageBufferInput) { - for(b <- testDataSet) { + + def runTest(factory: Array[Byte] => MessageBufferInput) { + for (b <- testDataSet) { checkInputData(b, factory(b)) } } - implicit class InputData(b:Array[Byte]) { + implicit class InputData(b: Array[Byte]) { def compress = { - val compressed = new ByteArrayOutputStream() - val out = new GZIPOutputStream(compressed) + val compressed = new + ByteArrayOutputStream() + val out = new + GZIPOutputStream(compressed) out.write(b) out.close() compressed.toByteArray @@ -45,59 +50,66 @@ class MessageBufferInputTest extends MessagePackSpec { ByteBuffer.wrap(b) } - def saveToTmpFile : File = { - val tmp = File.createTempFile("testbuf", ".dat", new File("target")) + def saveToTmpFile: File = { + val tmp = File + .createTempFile("testbuf", + ".dat", + new + File("target")) tmp.getParentFile.mkdirs() tmp.deleteOnExit() - withResource(new FileOutputStream(tmp)) { out => + withResource(new + FileOutputStream(tmp)) { out => out.write(b) } tmp } } - - - def checkInputData(inputData:Array[Byte], in:MessageBufferInput) { + def checkInputData(inputData: Array[Byte], in: MessageBufferInput) { When(s"input data size = ${inputData.length}") var cursor = 0 - for(m <- Iterator.continually(in.next).takeWhile(_ != null)) { + for (m <- Iterator.continually(in.next).takeWhile(_ != null)) { m.toByteArray() shouldBe inputData.slice(cursor, cursor + m.size()) cursor += m.size() } cursor shouldBe inputData.length - } - "MessageBufferInput" should { "support byte arrays" in { - runTest(new ArrayBufferInput(_)) + runTest(new + ArrayBufferInput(_)) } "support ByteBuffers" in { - runTest(b => new ByteBufferInput(b.toByteBuffer)) + runTest(b => new + ByteBufferInput(b.toByteBuffer)) } - "support InputStreams" taggedAs("is") in { - runTest(b => - new InputStreamBufferInput( - new GZIPInputStream(new ByteArrayInputStream(b.compress))) + "support InputStreams" taggedAs ("is") in { + runTest(b => + new + InputStreamBufferInput( + new + GZIPInputStream(new + ByteArrayInputStream(b.compress))) ) } - "support file input channel" taggedAs("fc") in { + "support file input channel" taggedAs ("fc") in { runTest { b => val tmp = b.saveToTmpFile try { - InputStreamBufferInput.newBufferInput(new FileInputStream(tmp)) + InputStreamBufferInput + .newBufferInput(new + FileInputStream(tmp)) } finally { tmp.delete() } } } - } def createTempFile = { @@ -108,9 +120,12 @@ class MessageBufferInputTest extends MessagePackSpec { def createTempFileWithInputStream = { val f = createTempFile - val out = new FileOutputStream(f) - new MessagePack().newPacker(out).packInt(42).close - val in = new FileInputStream(f) + val out = new + FileOutputStream(f) + new + MessagePack().newPacker(out).packInt(42).close + val in = new + FileInputStream(f) (f, in) } @@ -120,15 +135,17 @@ class MessageBufferInputTest extends MessagePackSpec { (f, ch) } - def readInt(buf:MessageBufferInput) : Int = { - val unpacker = new MessageUnpacker(buf) + def readInt(buf: MessageBufferInput): Int = { + val unpacker = new + MessageUnpacker(buf) unpacker.unpackInt } "InputStreamBufferInput" should { "reset buffer" in { val (f0, in0) = createTempFileWithInputStream - val buf = new InputStreamBufferInput(in0) + val buf = new + InputStreamBufferInput(in0) readInt(buf) shouldBe 42 val (f1, in1) = createTempFileWithInputStream @@ -136,10 +153,12 @@ class MessageBufferInputTest extends MessagePackSpec { readInt(buf) shouldBe 42 } - "be non-blocking" taggedAs("non-blocking") in { + "be non-blocking" taggedAs ("non-blocking") in { - withResource(new PipedOutputStream()) { pipedOutputStream => - withResource(new PipedInputStream()) { pipedInputStream => + withResource(new + PipedOutputStream()) { pipedOutputStream => + withResource(new + PipedInputStream()) { pipedInputStream => pipedInputStream.connect(pipedOutputStream) val packer = MessagePack.newDefaultPacker(pipedOutputStream) @@ -160,13 +179,13 @@ class MessageBufferInputTest extends MessagePackSpec { } } } - } "ChannelBufferInput" should { "reset buffer" in { val (f0, in0) = createTempFileWithChannel - val buf = new ChannelBufferInput(in0) + val buf = new + ChannelBufferInput(in0) readInt(buf) shouldBe 42 val (f1, in1) = createTempFileWithChannel @@ -174,5 +193,4 @@ class MessageBufferInputTest extends MessagePackSpec { readInt(buf) shouldBe 42 } } - } diff --git a/msgpack-core/src/test/scala/org/msgpack/core/buffer/MessageBufferOutputTest.scala b/msgpack-core/src/test/scala/org/msgpack/core/buffer/MessageBufferOutputTest.scala index 7d8940dc6..af38b009f 100644 --- a/msgpack-core/src/test/scala/org/msgpack/core/buffer/MessageBufferOutputTest.scala +++ b/msgpack-core/src/test/scala/org/msgpack/core/buffer/MessageBufferOutputTest.scala @@ -1,9 +1,11 @@ package org.msgpack.core.buffer -import org.msgpack.core.MessagePackSpec import java.io._ -class MessageBufferOutputTest extends MessagePackSpec { +import org.msgpack.core.MessagePackSpec + +class MessageBufferOutputTest + extends MessagePackSpec { def createTempFile = { val f = File.createTempFile("msgpackTest", "msgpack") @@ -13,7 +15,8 @@ class MessageBufferOutputTest extends MessagePackSpec { def createTempFileWithOutputStream = { val f = createTempFile - val out = new FileOutputStream(f) + val out = new + FileOutputStream(f) (f, out) } @@ -23,7 +26,7 @@ class MessageBufferOutputTest extends MessagePackSpec { (f, ch) } - def writeIntToBuf(buf:MessageBufferOutput) = { + def writeIntToBuf(buf: MessageBufferOutput) = { val mb0 = buf.next(8) mb0.putInt(0, 42) buf.flush(mb0) @@ -33,7 +36,8 @@ class MessageBufferOutputTest extends MessagePackSpec { "OutputStreamBufferOutput" should { "reset buffer" in { val (f0, out0) = createTempFileWithOutputStream - val buf = new OutputStreamBufferOutput(out0) + val buf = new + OutputStreamBufferOutput(out0) writeIntToBuf(buf) f0.length.toInt should be > 0 @@ -47,7 +51,8 @@ class MessageBufferOutputTest extends MessagePackSpec { "ChannelBufferOutput" should { "reset buffer" in { val (f0, ch0) = createTempFileWithChannel - val buf = new ChannelBufferOutput(ch0) + val buf = new + ChannelBufferOutput(ch0) writeIntToBuf(buf) f0.length.toInt should be > 0 @@ -57,5 +62,4 @@ class MessageBufferOutputTest extends MessagePackSpec { f1.length.toInt should be > 0 } } - } diff --git a/msgpack-core/src/test/scala/org/msgpack/core/buffer/MessageBufferTest.scala b/msgpack-core/src/test/scala/org/msgpack/core/buffer/MessageBufferTest.scala index 32432bdef..d5e2f2b33 100644 --- a/msgpack-core/src/test/scala/org/msgpack/core/buffer/MessageBufferTest.scala +++ b/msgpack-core/src/test/scala/org/msgpack/core/buffer/MessageBufferTest.scala @@ -1,13 +1,16 @@ package org.msgpack.core.buffer import java.nio.ByteBuffer -import scala.util.Random + import org.msgpack.core.MessagePackSpec +import scala.util.Random + /** * Created on 2014/05/01. */ -class MessageBufferTest extends MessagePackSpec { +class MessageBufferTest + extends MessagePackSpec { "MessageBuffer" should { @@ -16,8 +19,8 @@ class MessageBufferTest extends MessagePackSpec { info(s"MessageBuffer type: ${b.getClass.getName}") } - "wrap ByteBuffer considering position and remaining values" taggedAs("wrap-bb") in { - val d = Array[Byte](10,11,12,13,14,15,16,17,18,19) + "wrap ByteBuffer considering position and remaining values" taggedAs ("wrap-bb") in { + val d = Array[Byte](10, 11, 12, 13, 14, 15, 16, 17, 18, 19) val subset = ByteBuffer.wrap(d, 2, 2) val mb = MessageBuffer.wrap(subset) mb.getByte(0) shouldBe 12 @@ -36,18 +39,20 @@ class MessageBufferTest extends MessagePackSpec { def bench(f: Int => Unit) { var i = 0 - while(i < N) { + while (i < N) { f((i * 4) % M) i += 1 } } - val r = new Random(0) - val rs = new Array[Int](N) + val r = new + Random(0) + val rs = new + Array[Int](N) (0 until N).map(i => rs(i) = r.nextInt(N)) def randomBench(f: Int => Unit) { var i = 0 - while(i < N) { + while (i < N) { f((rs(i) * 4) % M) i += 1 } @@ -58,7 +63,7 @@ class MessageBufferTest extends MessagePackSpec { time("sequential getInt", repeat = rep) { block("unsafe array") { var i = 0 - while(i < N) { + while (i < N) { ub.getInt((i * 4) % M) i += 1 } @@ -66,7 +71,7 @@ class MessageBufferTest extends MessagePackSpec { block("unsafe direct") { var i = 0 - while(i < N) { + while (i < N) { ud.getInt((i * 4) % M) i += 1 } @@ -74,7 +79,7 @@ class MessageBufferTest extends MessagePackSpec { block("allocate") { var i = 0 - while(i < N) { + while (i < N) { hb.getInt((i * 4) % M) i += 1 } @@ -82,7 +87,7 @@ class MessageBufferTest extends MessagePackSpec { block("allocateDirect") { var i = 0 - while(i < N) { + while (i < N) { db.getInt((i * 4) % M) i += 1 } @@ -92,7 +97,7 @@ class MessageBufferTest extends MessagePackSpec { time("random getInt", repeat = rep) { block("unsafe array") { var i = 0 - while(i < N) { + while (i < N) { ub.getInt((rs(i) * 4) % M) i += 1 } @@ -100,7 +105,7 @@ class MessageBufferTest extends MessagePackSpec { block("unsafe direct") { var i = 0 - while(i < N) { + while (i < N) { ud.getInt((rs(i) * 4) % M) i += 1 } @@ -108,7 +113,7 @@ class MessageBufferTest extends MessagePackSpec { block("allocate") { var i = 0 - while(i < N) { + while (i < N) { hb.getInt((rs(i) * 4) % M) i += 1 } @@ -116,13 +121,12 @@ class MessageBufferTest extends MessagePackSpec { block("allocateDirect") { var i = 0 - while(i < N) { + while (i < N) { db.getInt((rs(i) * 4) % M) i += 1 } } } - } "convert to ByteBuffer" in { diff --git a/msgpack-core/src/test/scala/org/msgpack/core/example/MessagePackExampleTest.scala b/msgpack-core/src/test/scala/org/msgpack/core/example/MessagePackExampleTest.scala index 21c1d8334..e8b167674 100644 --- a/msgpack-core/src/test/scala/org/msgpack/core/example/MessagePackExampleTest.scala +++ b/msgpack-core/src/test/scala/org/msgpack/core/example/MessagePackExampleTest.scala @@ -5,7 +5,8 @@ import org.msgpack.core.MessagePackSpec /** * */ -class MessagePackExampleTest extends MessagePackSpec { +class MessagePackExampleTest + extends MessagePackSpec { "example" should { @@ -24,6 +25,5 @@ class MessagePackExampleTest extends MessagePackSpec { "have configuration example" in { MessagePackExample.configuration(); } - } } diff --git a/msgpack-core/src/test/scala/org/msgpack/value/RawStringValueImplTest.scala b/msgpack-core/src/test/scala/org/msgpack/value/RawStringValueImplTest.scala index bd57480e0..7372887c6 100644 --- a/msgpack-core/src/test/scala/org/msgpack/value/RawStringValueImplTest.scala +++ b/msgpack-core/src/test/scala/org/msgpack/value/RawStringValueImplTest.scala @@ -2,7 +2,8 @@ package org.msgpack.value import org.msgpack.core.MessagePackSpec -class RawStringValueImplTest extends MessagePackSpec { +class RawStringValueImplTest + extends MessagePackSpec { "StringValue" should { "return the same hash code if they are equal" in { diff --git a/msgpack-core/src/test/scala/org/msgpack/value/ValueFactoryTest.scala b/msgpack-core/src/test/scala/org/msgpack/value/ValueFactoryTest.scala index 91552e217..0b531ddad 100644 --- a/msgpack-core/src/test/scala/org/msgpack/value/ValueFactoryTest.scala +++ b/msgpack-core/src/test/scala/org/msgpack/value/ValueFactoryTest.scala @@ -5,21 +5,22 @@ import org.msgpack.core.MessagePackSpec /** * */ -class ValueFactoryTest extends MessagePackSpec { +class ValueFactoryTest + extends MessagePackSpec { - def isValid(v:Value, - expected:ValueType, + def isValid(v: Value, + expected: ValueType, isNil: Boolean = false, isBoolean: Boolean = false, isInteger: Boolean = false, - isString : Boolean = false, + isString: Boolean = false, isFloat: Boolean = false, isBinary: Boolean = false, isArray: Boolean = false, isMap: Boolean = false, - isExtension : Boolean = false, - isRaw : Boolean = false, - isNumber : Boolean = false + isExtension: Boolean = false, + isRaw: Boolean = false, + isNumber: Boolean = false ) { v.isNilValue shouldBe isNil v.isBooleanValue shouldBe isBoolean @@ -37,16 +38,17 @@ class ValueFactoryTest extends MessagePackSpec { "ValueFactory" should { "create valid type values" in { - isValid(ValueFactory.newNil(), expected=ValueType.NIL, isNil = true) - forAll{(v:Boolean) => isValid(ValueFactory.newBoolean(v), expected=ValueType.BOOLEAN, isBoolean = true)} - forAll{(v:Int) => isValid(ValueFactory.newInteger(v), expected=ValueType.INTEGER, isInteger = true, isNumber = true)} - forAll{(v:Float) => isValid(ValueFactory.newFloat(v), expected=ValueType.FLOAT, isFloat = true, isNumber = true)} - forAll{(v:String) => isValid(ValueFactory.newString(v), expected=ValueType.STRING, isString = true, isRaw = true)} - forAll{(v:Array[Byte]) => isValid(ValueFactory.newBinary(v), expected=ValueType.BINARY, isBinary = true, isRaw = true)} - isValid(ValueFactory.emptyArray(), expected=ValueType.ARRAY, isArray = true) - isValid(ValueFactory.emptyMap(), expected=ValueType.MAP, isMap = true) - forAll{(v:Array[Byte]) => isValid(ValueFactory.newExtension(0, v), expected=ValueType.EXTENSION, isExtension=true, isRaw=true)} + isValid(ValueFactory.newNil(), expected = ValueType.NIL, isNil = true) + forAll { (v: Boolean) => isValid(ValueFactory.newBoolean(v), expected = ValueType.BOOLEAN, isBoolean = true) } + forAll { (v: Int) => isValid(ValueFactory.newInteger(v), expected = ValueType.INTEGER, isInteger = true, isNumber = true) } + forAll { (v: Float) => isValid(ValueFactory.newFloat(v), expected = ValueType.FLOAT, isFloat = true, isNumber = true) } + forAll { (v: String) => isValid(ValueFactory.newString(v), expected = ValueType.STRING, isString = true, isRaw = true) } + forAll { (v: Array[Byte]) => isValid(ValueFactory.newBinary(v), expected = ValueType.BINARY, isBinary = true, isRaw = true) } + isValid(ValueFactory.emptyArray(), expected = ValueType.ARRAY, isArray = true) + isValid(ValueFactory.emptyMap(), expected = ValueType.MAP, isMap = true) + forAll { (v: Array[Byte]) => isValid(ValueFactory.newExtension(0, v), expected = ValueType + .EXTENSION, isExtension = true, isRaw = true) + } } - } } diff --git a/msgpack-core/src/test/scala/org/msgpack/value/ValueTypeTest.scala b/msgpack-core/src/test/scala/org/msgpack/value/ValueTypeTest.scala index 99c0ce4d0..c5f46fdb0 100644 --- a/msgpack-core/src/test/scala/org/msgpack/value/ValueTypeTest.scala +++ b/msgpack-core/src/test/scala/org/msgpack/value/ValueTypeTest.scala @@ -1,15 +1,13 @@ package org.msgpack.value -import scala.util.Random -import org.msgpack.core.MessagePack.Code -import org.msgpack.core.{MessageFormat, MessageFormatException, MessagePackSpec} import org.msgpack.core.MessagePack.Code._ - +import org.msgpack.core.{MessageFormat, MessageFormatException, MessagePackSpec} /** * Created on 2014/05/06. */ -class ValueTypeTest extends MessagePackSpec { +class ValueTypeTest + extends MessagePackSpec { "ValueType" should { @@ -19,14 +17,17 @@ class ValueTypeTest extends MessagePackSpec { MessageFormat.valueOf(b).getValueType shouldBe tpe } - for (i <- 0 until 0x7f) + for (i <- 0 until 0x7f) { check(i.toByte, ValueType.INTEGER) + } - for (i <- 0x80 until 0x8f) + for (i <- 0x80 until 0x8f) { check(i.toByte, ValueType.MAP) + } - for (i <- 0x90 until 0x9f) + for (i <- 0x90 until 0x9f) { check(i.toByte, ValueType.ARRAY) + } check(NIL, ValueType.NIL) @@ -42,27 +43,33 @@ class ValueTypeTest extends MessagePackSpec { check(TRUE, ValueType.BOOLEAN) check(FALSE, ValueType.BOOLEAN) - for (t <- Seq(BIN8, BIN16, BIN32)) + for (t <- Seq(BIN8, BIN16, BIN32)) { check(t, ValueType.BINARY) + } - for (t <- Seq(FIXEXT1, FIXEXT2, FIXEXT4, FIXEXT8, FIXEXT16, EXT8, EXT16, EXT32)) + for (t <- Seq(FIXEXT1, FIXEXT2, FIXEXT4, FIXEXT8, FIXEXT16, EXT8, EXT16, EXT32)) { check(t, ValueType.EXTENSION) + } - for (t <- Seq(INT8, INT16, INT32, INT64, UINT8, UINT16, UINT32, UINT64)) + for (t <- Seq(INT8, INT16, INT32, INT64, UINT8, UINT16, UINT32, UINT64)) { check(t, ValueType.INTEGER) + } - for (t <- Seq(STR8, STR16, STR32)) + for (t <- Seq(STR8, STR16, STR32)) { check(t, ValueType.STRING) + } - for (t <- Seq(FLOAT32, FLOAT64)) + for (t <- Seq(FLOAT32, FLOAT64)) { check(t, ValueType.FLOAT) + } - for (t <- Seq(ARRAY16, ARRAY32)) + for (t <- Seq(ARRAY16, ARRAY32)) { check(t, ValueType.ARRAY) + } - for (i <- 0xe0 until 0xff) + for (i <- 0xe0 until 0xff) { check(i.toByte, ValueType.INTEGER) - + } } } } diff --git a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackFactory.java b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackFactory.java index f1065bdaf..06f7a93cd 100644 --- a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackFactory.java +++ b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackFactory.java @@ -15,50 +15,75 @@ // package org.msgpack.jackson.dataformat; -import com.fasterxml.jackson.core.*; +import com.fasterxml.jackson.core.JsonEncoding; +import com.fasterxml.jackson.core.JsonFactory; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.io.IOContext; -import java.io.*; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.Writer; import java.util.Arrays; -public class MessagePackFactory extends JsonFactory { +public class MessagePackFactory + extends JsonFactory +{ private static final long serialVersionUID = 2578263992015504347L; @Override - public JsonGenerator createGenerator(OutputStream out, JsonEncoding enc) throws IOException { + public JsonGenerator createGenerator(OutputStream out, JsonEncoding enc) + throws IOException + { return new MessagePackGenerator(_generatorFeatures, _objectCodec, out); } @Override - public JsonGenerator createGenerator(File f, JsonEncoding enc) throws IOException { + public JsonGenerator createGenerator(File f, JsonEncoding enc) + throws IOException + { return createGenerator(new FileOutputStream(f), enc); } @Override - public JsonGenerator createGenerator(Writer w) throws IOException { + public JsonGenerator createGenerator(Writer w) + throws IOException + { throw new UnsupportedOperationException(); } @Override - public JsonParser createParser(byte[] data) throws IOException, JsonParseException { + public JsonParser createParser(byte[] data) + throws IOException, JsonParseException + { IOContext ioContext = _createContext(data, false); return _createParser(data, 0, data.length, ioContext); } @Override - public JsonParser createParser(InputStream in) throws IOException, JsonParseException { + public JsonParser createParser(InputStream in) + throws IOException, JsonParseException + { IOContext ioContext = _createContext(in, false); return _createParser(in, ioContext); } @Override - protected MessagePackParser _createParser(InputStream in, IOContext ctxt) throws IOException { + protected MessagePackParser _createParser(InputStream in, IOContext ctxt) + throws IOException + { MessagePackParser parser = new MessagePackParser(ctxt, _parserFeatures, in); return parser; } @Override - protected JsonParser _createParser(byte[] data, int offset, int len, IOContext ctxt) throws IOException, JsonParseException { + protected JsonParser _createParser(byte[] data, int offset, int len, IOContext ctxt) + throws IOException, JsonParseException + { if (offset != 0 || len != data.length) { data = Arrays.copyOfRange(data, offset, offset + len); } diff --git a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackGenerator.java b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackGenerator.java index 9ab725925..f1ce4a135 100644 --- a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackGenerator.java +++ b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackGenerator.java @@ -5,7 +5,6 @@ import com.fasterxml.jackson.core.ObjectCodec; import com.fasterxml.jackson.core.base.GeneratorBase; import com.fasterxml.jackson.core.json.JsonWriteContext; - import org.msgpack.core.MessagePacker; import org.msgpack.core.buffer.OutputStreamBufferOutput; @@ -19,56 +18,70 @@ import java.util.LinkedList; import java.util.List; -public class MessagePackGenerator extends GeneratorBase { +public class MessagePackGenerator + extends GeneratorBase +{ private static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8"); private static ThreadLocal messagePackersHolder = new ThreadLocal(); private static ThreadLocal messageBufferOutputHolder = new ThreadLocal(); private LinkedList stack; private StackItem rootStackItem; - - private static abstract class StackItem { + private abstract static class StackItem + { protected List objectKeys = new ArrayList(); protected List objectValues = new ArrayList(); abstract void addKey(String key); - void addValue(Object value) { + void addValue(Object value) + { objectValues.add(value); } abstract List getKeys(); - List getValues() { + List getValues() + { return objectValues; } } - private static class StackItemForObject extends StackItem { + private static class StackItemForObject + extends StackItem + { @Override - void addKey(String key) { + void addKey(String key) + { objectKeys.add(key); } @Override - List getKeys() { + List getKeys() + { return objectKeys; } } - private static class StackItemForArray extends StackItem { + private static class StackItemForArray + extends StackItem + { @Override - void addKey(String key) { + void addKey(String key) + { throw new IllegalStateException("This method shouldn't be called"); } @Override - List getKeys() { + List getKeys() + { throw new IllegalStateException("This method shouldn't be called"); } } - public MessagePackGenerator(int features, ObjectCodec codec, OutputStream out) throws IOException { + public MessagePackGenerator(int features, ObjectCodec codec, OutputStream out) + throws IOException + { super(features, codec); MessagePacker messagePacker = messagePackersHolder.get(); OutputStreamBufferOutput messageBufferOutput = messageBufferOutputHolder.get(); @@ -92,13 +105,17 @@ public MessagePackGenerator(int features, ObjectCodec codec, OutputStream out) t } @Override - public void writeStartArray() throws IOException, JsonGenerationException { + public void writeStartArray() + throws IOException, JsonGenerationException + { _writeContext = _writeContext.createChildArrayContext(); stack.push(new StackItemForArray()); } @Override - public void writeEndArray() throws IOException, JsonGenerationException { + public void writeEndArray() + throws IOException, JsonGenerationException + { if (!_writeContext.inArray()) { _reportError("Current context not an array but " + _writeContext.getTypeDesc()); } @@ -111,13 +128,17 @@ public void writeEndArray() throws IOException, JsonGenerationException { } @Override - public void writeStartObject() throws IOException, JsonGenerationException { + public void writeStartObject() + throws IOException, JsonGenerationException + { _writeContext = _writeContext.createChildObjectContext(); stack.push(new StackItemForObject()); } @Override - public void writeEndObject() throws IOException, JsonGenerationException { + public void writeEndObject() + throws IOException, JsonGenerationException + { if (!_writeContext.inObject()) { _reportError("Current context not an object but " + _writeContext.getTypeDesc()); } @@ -135,7 +156,9 @@ public void writeEndObject() throws IOException, JsonGenerationException { popStackAndStoreTheItemAsValue(); } - private void packValue(Object v) throws IOException { + private void packValue(Object v) + throws IOException + { MessagePacker messagePacker = getMessagePacker(); if (v == null) { messagePacker.packNil(); @@ -180,16 +203,20 @@ else if (v instanceof Boolean) { } } - private void packBigDecimal(BigDecimal decimal) throws IOException { + private void packBigDecimal(BigDecimal decimal) + throws IOException + { MessagePacker messagePacker = getMessagePacker(); boolean failedToPackAsBI = false; try { //Check to see if this BigDecimal can be converted to BigInteger BigInteger integer = decimal.toBigIntegerExact(); messagePacker.packBigInteger(integer); - } catch (ArithmeticException e) { + } + catch (ArithmeticException e) { failedToPackAsBI = true; - } catch (IllegalArgumentException e) { + } + catch (IllegalArgumentException e) { failedToPackAsBI = true; } @@ -201,9 +228,11 @@ private void packBigDecimal(BigDecimal decimal) throws IOException { } messagePacker.packDouble(doubleValue); } -} + } - private void packObject(StackItemForObject stackItem) throws IOException { + private void packObject(StackItemForObject stackItem) + throws IOException + { List keys = stackItem.getKeys(); List values = stackItem.getValues(); @@ -217,7 +246,9 @@ private void packObject(StackItemForObject stackItem) throws IOException { } } - private void packArray(StackItemForArray stackItem) throws IOException { + private void packArray(StackItemForArray stackItem) + throws IOException + { List values = stackItem.getValues(); MessagePacker messagePacker = getMessagePacker(); @@ -230,102 +261,142 @@ private void packArray(StackItemForArray stackItem) throws IOException { } @Override - public void writeFieldName(String name) throws IOException, JsonGenerationException { + public void writeFieldName(String name) + throws IOException, JsonGenerationException + { addKeyToStackTop(name); } @Override - public void writeString(String text) throws IOException, JsonGenerationException { + public void writeString(String text) + throws IOException, JsonGenerationException + { addValueToStackTop(text); } @Override - public void writeString(char[] text, int offset, int len) throws IOException, JsonGenerationException { + public void writeString(char[] text, int offset, int len) + throws IOException, JsonGenerationException + { addValueToStackTop(new String(text, offset, len)); } @Override - public void writeRawUTF8String(byte[] text, int offset, int length) throws IOException, JsonGenerationException { + public void writeRawUTF8String(byte[] text, int offset, int length) + throws IOException, JsonGenerationException + { addValueToStackTop(new String(text, offset, length, DEFAULT_CHARSET)); } @Override - public void writeUTF8String(byte[] text, int offset, int length) throws IOException, JsonGenerationException { + public void writeUTF8String(byte[] text, int offset, int length) + throws IOException, JsonGenerationException + { addValueToStackTop(new String(text, offset, length, DEFAULT_CHARSET)); } @Override - public void writeRaw(String text) throws IOException, JsonGenerationException { + public void writeRaw(String text) + throws IOException, JsonGenerationException + { addValueToStackTop(text); } @Override - public void writeRaw(String text, int offset, int len) throws IOException, JsonGenerationException { + public void writeRaw(String text, int offset, int len) + throws IOException, JsonGenerationException + { addValueToStackTop(text.substring(0, len)); } @Override - public void writeRaw(char[] text, int offset, int len) throws IOException, JsonGenerationException { + public void writeRaw(char[] text, int offset, int len) + throws IOException, JsonGenerationException + { addValueToStackTop(new String(text, offset, len)); } @Override - public void writeRaw(char c) throws IOException, JsonGenerationException { + public void writeRaw(char c) + throws IOException, JsonGenerationException + { addValueToStackTop(String.valueOf(c)); } @Override - public void writeBinary(Base64Variant b64variant, byte[] data, int offset, int len) throws IOException, JsonGenerationException { + public void writeBinary(Base64Variant b64variant, byte[] data, int offset, int len) + throws IOException, JsonGenerationException + { addValueToStackTop(ByteBuffer.wrap(data, offset, len)); } @Override - public void writeNumber(int v) throws IOException, JsonGenerationException { + public void writeNumber(int v) + throws IOException, JsonGenerationException + { addValueToStackTop(Integer.valueOf(v)); } @Override - public void writeNumber(long v) throws IOException, JsonGenerationException { + public void writeNumber(long v) + throws IOException, JsonGenerationException + { addValueToStackTop(Long.valueOf(v)); } @Override - public void writeNumber(BigInteger v) throws IOException, JsonGenerationException { + public void writeNumber(BigInteger v) + throws IOException, JsonGenerationException + { addValueToStackTop(v); } @Override - public void writeNumber(double d) throws IOException, JsonGenerationException { + public void writeNumber(double d) + throws IOException, JsonGenerationException + { addValueToStackTop(Double.valueOf(d)); } @Override - public void writeNumber(float f) throws IOException, JsonGenerationException { + public void writeNumber(float f) + throws IOException, JsonGenerationException + { addValueToStackTop(Float.valueOf(f)); } @Override - public void writeNumber(BigDecimal dec) throws IOException, JsonGenerationException { + public void writeNumber(BigDecimal dec) + throws IOException, JsonGenerationException + { addValueToStackTop(dec); } @Override - public void writeNumber(String encodedValue) throws IOException, JsonGenerationException, UnsupportedOperationException { + public void writeNumber(String encodedValue) + throws IOException, JsonGenerationException, UnsupportedOperationException + { throw new UnsupportedOperationException("writeNumber(String encodedValue) isn't supported yet"); } @Override - public void writeBoolean(boolean state) throws IOException, JsonGenerationException { + public void writeBoolean(boolean state) + throws IOException, JsonGenerationException + { addValueToStackTop(Boolean.valueOf(state)); } @Override - public void writeNull() throws IOException, JsonGenerationException { + public void writeNull() + throws IOException, JsonGenerationException + { addValueToStackTop(null); } @Override - public void close() throws IOException { + public void close() + throws IOException + { try { flush(); } @@ -338,7 +409,9 @@ public void close() throws IOException { } @Override - public void flush() throws IOException { + public void flush() + throws IOException + { if (rootStackItem != null) { if (rootStackItem instanceof StackItemForObject) { packObject((StackItemForObject) rootStackItem); @@ -354,33 +427,38 @@ else if (rootStackItem instanceof StackItemForArray) { } } - private void flushMessagePacker() throws IOException + private void flushMessagePacker() + throws IOException { MessagePacker messagePacker = getMessagePacker(); messagePacker.flush(); } @Override - protected void _releaseBuffers() { - + protected void _releaseBuffers() + { } @Override - protected void _verifyValueWrite(String typeMsg) throws IOException, JsonGenerationException { + protected void _verifyValueWrite(String typeMsg) + throws IOException, JsonGenerationException + { int status = _writeContext.writeValue(); if (status == JsonWriteContext.STATUS_EXPECT_NAME) { - _reportError("Can not "+typeMsg+", expecting field name"); + _reportError("Can not " + typeMsg + ", expecting field name"); } } - private StackItem getStackTop() { + private StackItem getStackTop() + { if (stack.isEmpty()) { throw new IllegalStateException("The stack is empty"); } return stack.getFirst(); } - private StackItemForObject getStackTopForObject() { + private StackItemForObject getStackTopForObject() + { StackItem stackTop = getStackTop(); if (!(stackTop instanceof StackItemForObject)) { throw new IllegalStateException("The stack top should be Object: " + stackTop); @@ -388,7 +466,8 @@ private StackItemForObject getStackTopForObject() { return (StackItemForObject) stackTop; } - private StackItemForArray getStackTopForArray() { + private StackItemForArray getStackTopForArray() + { StackItem stackTop = getStackTop(); if (!(stackTop instanceof StackItemForArray)) { throw new IllegalStateException("The stack top should be Array: " + stackTop); @@ -396,11 +475,13 @@ private StackItemForArray getStackTopForArray() { return (StackItemForArray) stackTop; } - private void addKeyToStackTop(String key) { + private void addKeyToStackTop(String key) + { getStackTop().addKey(key); } - private void addValueToStackTop(Object value) throws IOException + private void addValueToStackTop(Object value) + throws IOException { if (stack.isEmpty()) { packValue(value); @@ -411,7 +492,8 @@ private void addValueToStackTop(Object value) throws IOException } } - private void popStackAndStoreTheItemAsValue() throws IOException + private void popStackAndStoreTheItemAsValue() + throws IOException { StackItem child = stack.pop(); if (stack.size() > 0) { @@ -427,7 +509,8 @@ private void popStackAndStoreTheItemAsValue() throws IOException } } - private MessagePacker getMessagePacker() { + private MessagePacker getMessagePacker() + { MessagePacker messagePacker = messagePackersHolder.get(); if (messagePacker == null) { throw new IllegalStateException("messagePacker is null"); diff --git a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java index 1ae4597da..4063ac1fa 100644 --- a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java +++ b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java @@ -1,6 +1,14 @@ package org.msgpack.jackson.dataformat; -import com.fasterxml.jackson.core.*; +import com.fasterxml.jackson.core.Base64Variant; +import com.fasterxml.jackson.core.JsonLocation; +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.core.JsonStreamContext; +import com.fasterxml.jackson.core.JsonToken; +import com.fasterxml.jackson.core.ObjectCodec; +import com.fasterxml.jackson.core.Version; import com.fasterxml.jackson.core.base.ParserMinimalBase; import com.fasterxml.jackson.core.io.IOContext; import com.fasterxml.jackson.core.json.DupDetector; @@ -9,11 +17,11 @@ import org.msgpack.core.buffer.ArrayBufferInput; import org.msgpack.core.buffer.InputStreamBufferInput; import org.msgpack.core.buffer.MessageBufferInput; -import org.msgpack.value.Value; -import org.msgpack.value.Variable; import org.msgpack.value.IntegerValue; -import org.msgpack.value.ValueType; +import org.msgpack.value.Value; import org.msgpack.value.ValueFactory; +import org.msgpack.value.ValueType; +import org.msgpack.value.Variable; import java.io.IOException; import java.io.InputStream; @@ -21,7 +29,9 @@ import java.math.BigInteger; import java.util.LinkedList; -public class MessagePackParser extends ParserMinimalBase { +public class MessagePackParser + extends ParserMinimalBase +{ private static final ThreadLocal> messageUnpackerHolder = new ThreadLocal>(); @@ -36,43 +46,59 @@ public class MessagePackParser extends ParserMinimalBase { private long currentPosition; private final IOContext ioContext; - private static abstract class StackItem { + private abstract static class StackItem + { private long numOfElements; - protected StackItem(long numOfElements) { + protected StackItem(long numOfElements) + { this.numOfElements = numOfElements; } - public void consume() { - numOfElements--; + public void consume() + { + numOfElements--; } - public boolean isEmpty() { + public boolean isEmpty() + { return numOfElements == 0; } } - private static class StackItemForObject extends StackItem { - StackItemForObject(long numOfElements) { + private static class StackItemForObject + extends StackItem + { + StackItemForObject(long numOfElements) + { super(numOfElements); } } - private static class StackItemForArray extends StackItem { - StackItemForArray(long numOfElements) { + private static class StackItemForArray + extends StackItem + { + StackItemForArray(long numOfElements) + { super(numOfElements); } } - public MessagePackParser(IOContext ctxt, int features, InputStream in) throws IOException { + public MessagePackParser(IOContext ctxt, int features, InputStream in) + throws IOException + { this(ctxt, features, new InputStreamBufferInput(in), in); } - public MessagePackParser(IOContext ctxt, int features, byte[] bytes) throws IOException { + public MessagePackParser(IOContext ctxt, int features, byte[] bytes) + throws IOException + { this(ctxt, features, new ArrayBufferInput(bytes), bytes); } - private MessagePackParser(IOContext ctxt, int features, MessageBufferInput input, Object src) throws IOException { + private MessagePackParser(IOContext ctxt, int features, MessageBufferInput input, Object src) + throws IOException + { super(features); ioContext = ctxt; @@ -99,22 +125,27 @@ private MessagePackParser(IOContext ctxt, int features, MessageBufferInput input } @Override - public ObjectCodec getCodec() { + public ObjectCodec getCodec() + { return codec; } @Override - public void setCodec(ObjectCodec c) { + public void setCodec(ObjectCodec c) + { codec = c; } @Override - public Version version() { + public Version version() + { return null; } @Override - public JsonToken nextToken() throws IOException, JsonParseException { + public JsonToken nextToken() + throws IOException, JsonParseException + { MessageUnpacker messageUnpacker = getMessageUnpacker(); tokenPosition = messageUnpacker.getTotalReadBytes(); @@ -215,10 +246,14 @@ else if (newStack instanceof StackItemForObject) { } @Override - protected void _handleEOF() throws JsonParseException {} + protected void _handleEOF() + throws JsonParseException + {} @Override - public String getText() throws IOException, JsonParseException { + public String getText() + throws IOException, JsonParseException + { // This method can be called for new BigInteger(text) if (value.isRawValue()) { return value.asRawValue().stringValue(); @@ -229,32 +264,43 @@ public String getText() throws IOException, JsonParseException { } @Override - public char[] getTextCharacters() throws IOException, JsonParseException { + public char[] getTextCharacters() + throws IOException, JsonParseException + { return getText().toCharArray(); } @Override - public boolean hasTextCharacters() { + public boolean hasTextCharacters() + { return false; } @Override - public int getTextLength() throws IOException, JsonParseException { + public int getTextLength() + throws IOException, JsonParseException + { return getText().length(); } @Override - public int getTextOffset() throws IOException, JsonParseException { + public int getTextOffset() + throws IOException, JsonParseException + { return 0; } @Override - public byte[] getBinaryValue(Base64Variant b64variant) throws IOException, JsonParseException { + public byte[] getBinaryValue(Base64Variant b64variant) + throws IOException, JsonParseException + { return value.asRawValue().getByteArray(); } @Override - public Number getNumberValue() throws IOException, JsonParseException { + public Number getNumberValue() + throws IOException, JsonParseException + { if (value.isIntegerValue()) { IntegerValue integerValue = value.asIntegerValue(); if (integerValue.isInIntRange()) { @@ -266,38 +312,51 @@ else if (integerValue.isInLongRange()) { else { return integerValue.castAsBigInteger(); } - } else { + } + else { return value.asNumberValue().castAsDouble(); } } @Override - public int getIntValue() throws IOException, JsonParseException { + public int getIntValue() + throws IOException, JsonParseException + { return value.asNumberValue().castAsInt(); } @Override - public long getLongValue() throws IOException, JsonParseException { + public long getLongValue() + throws IOException, JsonParseException + { return value.asNumberValue().castAsLong(); } @Override - public BigInteger getBigIntegerValue() throws IOException, JsonParseException { + public BigInteger getBigIntegerValue() + throws IOException, JsonParseException + { return value.asNumberValue().castAsBigInteger(); } @Override - public float getFloatValue() throws IOException, JsonParseException { + public float getFloatValue() + throws IOException, JsonParseException + { return value.asNumberValue().castAsFloat(); } @Override - public double getDoubleValue() throws IOException, JsonParseException { + public double getDoubleValue() + throws IOException, JsonParseException + { return value.asNumberValue().castAsDouble(); } @Override - public BigDecimal getDecimalValue() throws IOException { + public BigDecimal getDecimalValue() + throws IOException + { if (value.isIntegerValue()) { IntegerValue number = value.asIntegerValue(); //optimization to not convert the value to BigInteger unnecessarily @@ -317,18 +376,24 @@ else if (value.isFloatValue()) { } @Override - public Object getEmbeddedObject() throws IOException, JsonParseException { + public Object getEmbeddedObject() + throws IOException, JsonParseException + { if (value.isBinaryValue()) { return value.asBinaryValue().getByteArray(); - } else if (value.isExtensionValue()) { + } + else if (value.isExtensionValue()) { return value.asExtensionValue(); - } else { + } + else { throw new UnsupportedOperationException(); } } @Override - public NumberType getNumberType() throws IOException, JsonParseException { + public NumberType getNumberType() + throws IOException, JsonParseException + { if (value.isIntegerValue()) { IntegerValue integerValue = value.asIntegerValue(); if (integerValue.isInIntRange()) { @@ -340,14 +405,17 @@ else if (integerValue.isInLongRange()) { else { return NumberType.BIG_INTEGER; } - } else { + } + else { value.asNumberValue(); return NumberType.DOUBLE; } } @Override - public void close() throws IOException { + public void close() + throws IOException + { try { if (isEnabled(JsonParser.Feature.AUTO_CLOSE_SOURCE)) { MessageUnpacker messageUnpacker = getMessageUnpacker(); @@ -360,27 +428,32 @@ public void close() throws IOException { } @Override - public boolean isClosed() { + public boolean isClosed() + { return isClosed; } @Override - public JsonStreamContext getParsingContext() { + public JsonStreamContext getParsingContext() + { return parsingContext; } @Override - public JsonLocation getTokenLocation() { + public JsonLocation getTokenLocation() + { return new JsonLocation(ioContext.getSourceReference(), tokenPosition, -1, -1, (int) tokenPosition); } @Override - public JsonLocation getCurrentLocation() { + public JsonLocation getCurrentLocation() + { return new JsonLocation(ioContext.getSourceReference(), currentPosition, -1, -1, (int) currentPosition); } @Override - public void overrideCurrentName(String name) { + public void overrideCurrentName(String name) + { try { if (_currToken == JsonToken.START_OBJECT || _currToken == JsonToken.START_ARRAY) { JsonReadContext parent = parsingContext.getParent(); @@ -389,12 +462,16 @@ public void overrideCurrentName(String name) { else { parsingContext.setCurrentName(name); } - } catch (JsonProcessingException e) { + } + catch (JsonProcessingException e) { throw new IllegalStateException(e); } } - @Override public String getCurrentName() throws IOException { + @Override + public String getCurrentName() + throws IOException + { if (_currToken == JsonToken.START_OBJECT || _currToken == JsonToken.START_ARRAY) { JsonReadContext parent = parsingContext.getParent(); return parent.getCurrentName(); @@ -402,7 +479,8 @@ public void overrideCurrentName(String name) { return parsingContext.getCurrentName(); } - private MessageUnpacker getMessageUnpacker() { + private MessageUnpacker getMessageUnpacker() + { Tuple messageUnpackerTuple = messageUnpackerHolder.get(); if (messageUnpackerTuple == null) { throw new IllegalStateException("messageUnpacker is null"); diff --git a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/Tuple.java b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/Tuple.java index 8678e5200..e17dce2f5 100644 --- a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/Tuple.java +++ b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/Tuple.java @@ -3,20 +3,24 @@ /** * Created by komamitsu on 5/28/15. */ -public class Tuple { +public class Tuple +{ private final F first; private final S second; - public Tuple(F first, S second) { + public Tuple(F first, S second) + { this.first = first; this.second = second; } - public F first() { + public F first() + { return first; } - public S second() { + public S second() + { return second; } } diff --git a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackDataformatForPojoTest.java b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackDataformatForPojoTest.java index a27bc27fa..d9a40097c 100644 --- a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackDataformatForPojoTest.java +++ b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackDataformatForPojoTest.java @@ -8,9 +8,13 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; -public class MessagePackDataformatForPojoTest extends MessagePackDataformatTestBase { +public class MessagePackDataformatForPojoTest + extends MessagePackDataformatTestBase +{ @Test - public void testNormal() throws IOException { + public void testNormal() + throws IOException + { byte[] bytes = objectMapper.writeValueAsBytes(normalPojo); NormalPojo value = objectMapper.readValue(bytes, NormalPojo.class); assertEquals(normalPojo.s, value.getS()); @@ -25,7 +29,9 @@ public void testNormal() throws IOException { } @Test - public void testNestedList() throws IOException { + public void testNestedList() + throws IOException + { byte[] bytes = objectMapper.writeValueAsBytes(nestedListPojo); NestedListPojo value = objectMapper.readValue(bytes, NestedListPojo.class); assertEquals(nestedListPojo.s, value.s); @@ -33,7 +39,9 @@ public void testNestedList() throws IOException { } @Test - public void testNestedListComplex() throws IOException { + public void testNestedListComplex() + throws IOException + { byte[] bytes = objectMapper.writeValueAsBytes(nestedListComplexPojo); NestedListComplexPojo value = objectMapper.readValue(bytes, NestedListComplexPojo.class); assertEquals(nestedListPojo.s, value.s); @@ -41,7 +49,9 @@ public void testNestedListComplex() throws IOException { } @Test - public void testUsingCustomConstructor() throws IOException { + public void testUsingCustomConstructor() + throws IOException + { UsingCustomConstructorPojo orig = new UsingCustomConstructorPojo("komamitsu", 55); byte[] bytes = objectMapper.writeValueAsBytes(orig); UsingCustomConstructorPojo value = objectMapper.readValue(bytes, UsingCustomConstructorPojo.class); @@ -50,7 +60,9 @@ public void testUsingCustomConstructor() throws IOException { } @Test - public void testIgnoringProperties() throws IOException { + public void testIgnoringProperties() + throws IOException + { IgnoringPropertiesPojo orig = new IgnoringPropertiesPojo(); orig.internal = "internal"; orig.external = "external"; @@ -63,12 +75,13 @@ public void testIgnoringProperties() throws IOException { } @Test - public void testChangingPropertyNames() throws IOException { + public void testChangingPropertyNames() + throws IOException + { ChangingPropertyNamesPojo orig = new ChangingPropertyNamesPojo(); orig.setTheName("komamitsu"); byte[] bytes = objectMapper.writeValueAsBytes(orig); ChangingPropertyNamesPojo value = objectMapper.readValue(bytes, ChangingPropertyNamesPojo.class); assertEquals("komamitsu", value.getTheName()); } - } diff --git a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackDataformatTestBase.java b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackDataformatTestBase.java index c248067d0..5ed5ae039 100644 --- a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackDataformatTestBase.java +++ b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackDataformatTestBase.java @@ -20,7 +20,8 @@ import java.util.Arrays; import java.util.List; -public class MessagePackDataformatTestBase { +public class MessagePackDataformatTestBase +{ protected MessagePackFactory factory; protected ByteArrayOutputStream out; protected ByteArrayInputStream in; @@ -31,7 +32,8 @@ public class MessagePackDataformatTestBase { protected TinyPojo tinyPojo; @Before - public void setup() { + public void setup() + { factory = new MessagePackFactory(); objectMapper = new ObjectMapper(factory); out = new ByteArrayOutputStream(); @@ -61,11 +63,13 @@ public void setup() { } @After - public void teardown() { + public void teardown() + { if (in != null) { try { in.close(); - } catch (IOException e) { + } + catch (IOException e) { e.printStackTrace(); } } @@ -73,13 +77,15 @@ public void teardown() { if (out != null) { try { out.close(); - } catch (IOException e) { + } + catch (IOException e) { e.printStackTrace(); } } } - protected void printStat(String label, double[] values) { + protected void printStat(String label, double[] values) + { StandardDeviation standardDeviation = new StandardDeviation(); System.out.println(label + ":"); System.out.println(String.format(" mean : %.2f", StatUtils.mean(values))); @@ -89,25 +95,30 @@ protected void printStat(String label, double[] values) { System.out.println(""); } - public enum Suit { + public enum Suit + { SPADE, HEART, DIAMOND, CLUB; } - public static class NestedListPojo { + public static class NestedListPojo + { public String s; public List strs; } - public static class TinyPojo { + public static class TinyPojo + { public String t; } - public static class NestedListComplexPojo { + public static class NestedListComplexPojo + { public String s; public List foos; } - public static class NormalPojo { + public static class NormalPojo + { String s; public boolean bool; public int i; @@ -118,11 +129,13 @@ public static class NormalPojo { public BigInteger bi; public Suit suit; - public String getS() { + public String getS() + { return s; } - public void setS(String s) { + public void setS(String s) + { this.s = s; } } @@ -138,19 +151,21 @@ public UsingCustomConstructorPojo(@JsonProperty("name") String name, @JsonProper this.age = age; } - public String getName() { + public String getName() + { return name; } - public int getAge() { + public int getAge() + { return age; } } - @JsonIgnoreProperties({ "foo", "bar" }) + @JsonIgnoreProperties({"foo", "bar"}) public static class IgnoringPropertiesPojo { - int _code; + int code; // will not be written as JSON; nor assigned from JSON: @JsonIgnore @@ -160,34 +175,51 @@ public static class IgnoringPropertiesPojo public String external; @JsonIgnore - public void setCode(int c) { _code = c; } + public void setCode(int c) + { + code = c; + } // note: will also be ignored because setter has annotation! - public int getCode() { return _code; } + public int getCode() + { + return code; + } } - public static class ChangingPropertyNamesPojo { - String _name; + public static class ChangingPropertyNamesPojo + { + String name; // without annotation, we'd get "theName", but we want "name": @JsonProperty("name") - public String getTheName() { return _name; } + public String getTheName() + { + return name; + } // note: it is enough to add annotation on just getter OR setter; // so we can omit it here - public void setTheName(String n) { _name = n; } + public void setTheName(String n) + { + name = n; + } } - protected interface FileSetup { - void setup(File f) throws Exception; + protected interface FileSetup + { + void setup(File f) + throws Exception; } - protected File createTempFile() throws Exception + protected File createTempFile() + throws Exception { return createTempFile(null); } - protected File createTempFile(FileSetup fileSetup) throws Exception + protected File createTempFile(FileSetup fileSetup) + throws Exception { File tempFile = File.createTempFile("test", "msgpack"); tempFile.deleteOnExit(); @@ -197,7 +229,9 @@ protected File createTempFile(FileSetup fileSetup) throws Exception return tempFile; } - protected OutputStream createTempFileOutputStream() throws IOException { + protected OutputStream createTempFileOutputStream() + throws IOException + { File tempFile = File.createTempFile("test", "msgpack"); tempFile.deleteOnExit(); return new FileOutputStream(tempFile); diff --git a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackFactoryTest.java b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackFactoryTest.java index 867229518..d9b9adfe5 100644 --- a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackFactoryTest.java +++ b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackFactoryTest.java @@ -9,16 +9,22 @@ import static org.junit.Assert.assertEquals; -public class MessagePackFactoryTest extends MessagePackDataformatTestBase { +public class MessagePackFactoryTest + extends MessagePackDataformatTestBase +{ @Test - public void testCreateGenerator() throws IOException { + public void testCreateGenerator() + throws IOException + { JsonEncoding enc = JsonEncoding.UTF8; JsonGenerator generator = factory.createGenerator(out, enc); assertEquals(MessagePackGenerator.class, generator.getClass()); } @Test - public void testCreateParser() throws IOException { + public void testCreateParser() + throws IOException + { JsonParser parser = factory.createParser(in); assertEquals(MessagePackParser.class, parser.getClass()); } diff --git a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackGeneratorTest.java b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackGeneratorTest.java index c8961f3c2..bc3adee3b 100644 --- a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackGeneratorTest.java +++ b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackGeneratorTest.java @@ -29,15 +29,23 @@ import java.io.IOException; import java.io.OutputStream; import java.math.BigDecimal; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; -public class MessagePackGeneratorTest extends MessagePackDataformatTestBase { +public class MessagePackGeneratorTest + extends MessagePackDataformatTestBase +{ @Test - public void testGeneratorShouldWriteObject() throws IOException { + public void testGeneratorShouldWriteObject() + throws IOException + { Map hashMap = new HashMap(); // #1 hashMap.put("str", "komamitsu"); @@ -52,7 +60,7 @@ public void testGeneratorShouldWriteObject() throws IOException { // #6 hashMap.put("double", 3.14159d); // #7 - hashMap.put("bin", new byte[]{0x00, 0x01, (byte)0xFE, (byte)0xFF}); + hashMap.put("bin", new byte[] {0x00, 0x01, (byte) 0xFE, (byte) 0xFF}); // #8 Map childObj = new HashMap(); childObj.put("co_str", "child#0"); @@ -102,11 +110,11 @@ else if (key.equals("double")) { } else if (key.equals("bin")) { // #7 - assertEquals(4, messageUnpacker.unpackBinaryHeader()); - assertEquals((byte)0x00, messageUnpacker.unpackByte()); - assertEquals((byte)0x01, messageUnpacker.unpackByte()); - assertEquals((byte)0xFE, messageUnpacker.unpackByte()); - assertEquals((byte)0xFF, messageUnpacker.unpackByte()); + assertEquals(4, messageUnpacker.unpackBinaryHeader()); + assertEquals((byte) 0x00, messageUnpacker.unpackByte()); + assertEquals((byte) 0x01, messageUnpacker.unpackByte()); + assertEquals((byte) 0xFE, messageUnpacker.unpackByte()); + assertEquals((byte) 0xFF, messageUnpacker.unpackByte()); bitmap |= 0x1 << 6; } else if (key.equals("childObj")) { @@ -142,7 +150,9 @@ else if (key.equals("childArray")) { } @Test - public void testGeneratorShouldWriteArray() throws IOException { + public void testGeneratorShouldWriteArray() + throws IOException + { List array = new ArrayList(); // #1 array.add("komamitsu"); @@ -198,7 +208,9 @@ else if (key.equals("num")) { } @Test - public void testMessagePackGeneratorDirectly() throws Exception { + public void testMessagePackGeneratorDirectly() + throws Exception + { MessagePackFactory messagePackFactory = new MessagePackFactory(); File tempFile = createTempFile(); @@ -223,7 +235,9 @@ public void testMessagePackGeneratorDirectly() throws Exception { } @Test - public void testWritePrimitives() throws Exception { + public void testWritePrimitives() + throws Exception + { MessagePackFactory messagePackFactory = new MessagePackFactory(); File tempFile = createTempFile(); @@ -244,7 +258,9 @@ public void testWritePrimitives() throws Exception { } @Test - public void testBigDecimal() throws IOException { + public void testBigDecimal() + throws IOException + { ObjectMapper mapper = new ObjectMapper(new MessagePackFactory()); { @@ -270,7 +286,6 @@ public void testBigDecimal() throws IOException { } { - BigDecimal decimal = new BigDecimal("1234.567890123456789012345678901234567890"); List bigDecimals = Arrays.asList( decimal @@ -287,7 +302,9 @@ public void testBigDecimal() throws IOException { } @Test(expected = IOException.class) - public void testEnableFeatureAutoCloseTarget() throws IOException { + public void testEnableFeatureAutoCloseTarget() + throws IOException + { OutputStream out = createTempFileOutputStream(); MessagePackFactory messagePackFactory = new MessagePackFactory(); ObjectMapper objectMapper = new ObjectMapper(messagePackFactory); @@ -297,7 +314,9 @@ public void testEnableFeatureAutoCloseTarget() throws IOException { } @Test - public void testDisableFeatureAutoCloseTarget() throws Exception { + public void testDisableFeatureAutoCloseTarget() + throws Exception + { File tempFile = createTempFile(); OutputStream out = new FileOutputStream(tempFile); MessagePackFactory messagePackFactory = new MessagePackFactory(); @@ -316,7 +335,9 @@ public void testDisableFeatureAutoCloseTarget() throws Exception { } @Test - public void testWritePrimitiveObjectViaObjectMapper() throws Exception { + public void testWritePrimitiveObjectViaObjectMapper() + throws Exception + { File tempFile = createTempFile(); OutputStream out = new FileOutputStream(tempFile); diff --git a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackParserTest.java b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackParserTest.java index 74de2ba7b..0b42bc2c4 100644 --- a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackParserTest.java +++ b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackParserTest.java @@ -11,10 +11,13 @@ import org.msgpack.core.buffer.OutputStreamBufferOutput; import org.msgpack.value.ExtensionValue; -import java.io.*; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.Serializable; import java.math.BigDecimal; import java.math.BigInteger; -import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -22,12 +25,16 @@ import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; -public class MessagePackParserTest extends MessagePackDataformatTestBase { +public class MessagePackParserTest + extends MessagePackDataformatTestBase +{ @Test - public void testParserShouldReadObject() throws IOException { + public void testParserShouldReadObject() + throws IOException + { MessagePacker packer = new MessagePacker(new OutputStreamBufferOutput(out)); packer.packMapHeader(9); // #1 @@ -76,7 +83,7 @@ public void testParserShouldReadObject() throws IOException { byte[] bytes = out.toByteArray(); - TypeReference> typeReference = new TypeReference>(){}; + TypeReference> typeReference = new TypeReference>() {}; Map object = objectMapper.readValue(bytes, typeReference); assertEquals(9, object.keySet().size()); @@ -133,7 +140,7 @@ else if (k.equals("array")) { // #7 bitmap |= 1 << 8; @SuppressWarnings("unchecked") - List expected = Arrays.asList((double)Float.MIN_VALUE, null, "array_child_str"); + List expected = Arrays.asList((double) Float.MIN_VALUE, null, "array_child_str"); assertEquals(expected, v); } else if (k.equals("bool")) { @@ -153,7 +160,9 @@ else if (k.equals("ext")) { } @Test - public void testParserShouldReadArray() throws IOException { + public void testParserShouldReadArray() + throws IOException + { MessagePacker packer = new MessagePacker(new OutputStreamBufferOutput(out)); packer.packArrayHeader(11); // #1 @@ -178,7 +187,7 @@ public void testParserShouldReadArray() throws IOException { bi = bi.add(BigInteger.ONE); packer.packBigInteger(bi); // #8 - byte[] bytes = new byte[]{(byte) 0xFF, (byte) 0xFE, 0x01, 0x00}; + byte[] bytes = new byte[] {(byte) 0xFF, (byte) 0xFE, 0x01, 0x00}; packer.packBinaryHeader(bytes.length); packer.writePayload(bytes); // #9 @@ -200,7 +209,7 @@ public void testParserShouldReadArray() throws IOException { bytes = out.toByteArray(); - TypeReference> typeReference = new TypeReference>(){}; + TypeReference> typeReference = new TypeReference>() {}; List array = objectMapper.readValue(bytes, typeReference); assertEquals(11, array.size()); int i = 0; @@ -220,18 +229,18 @@ public void testParserShouldReadArray() throws IOException { // #4 assertEquals(Long.MIN_VALUE, array.get(i++)); // #5 - assertEquals(Float.MAX_VALUE, (Double)array.get(i++), 0.001f); + assertEquals(Float.MAX_VALUE, (Double) array.get(i++), 0.001f); // #6 - assertEquals(Double.MIN_VALUE, (Double)array.get(i++), 0.001f); + assertEquals(Double.MIN_VALUE, (Double) array.get(i++), 0.001f); // #7 assertEquals(bi, array.get(i++)); // #8 byte[] bs = (byte[]) array.get(i++); assertEquals(4, bs.length); - assertEquals((byte)0xFF, bs[0]); - assertEquals((byte)0xFE, bs[1]); - assertEquals((byte)0x01, bs[2]); - assertEquals((byte)0x00, bs[3]); + assertEquals((byte) 0xFF, bs[0]); + assertEquals((byte) 0xFE, bs[1]); + assertEquals((byte) 0x01, bs[2]); + assertEquals((byte) 0x00, bs[3]); // #9 @SuppressWarnings("unchecked") Map childMap = (Map) array.get(i++); @@ -257,7 +266,9 @@ else if (k.equals("child_map_age")) { } @Test - public void testMessagePackParserDirectly() throws IOException { + public void testMessagePackParserDirectly() + throws IOException + { MessagePackFactory messagePackFactory = new MessagePackFactory(); File tempFile = File.createTempFile("msgpackTest", "msgpack"); tempFile.deleteOnExit(); @@ -321,7 +332,8 @@ public void testMessagePackParserDirectly() throws IOException { } @Test - public void testReadPrimitives() throws Exception + public void testReadPrimitives() + throws Exception { MessagePackFactory messagePackFactory = new MessagePackFactory(); File tempFile = createTempFile(); @@ -351,7 +363,9 @@ public void testReadPrimitives() throws Exception } @Test - public void testBigDecimal() throws IOException { + public void testBigDecimal() + throws IOException + { double d0 = 1.23456789; double d1 = 1.23450000000000000000006789; MessagePacker packer = new MessagePacker(new OutputStreamBufferOutput(out)); @@ -365,7 +379,7 @@ public void testBigDecimal() throws IOException { ObjectMapper mapper = new ObjectMapper(new MessagePackFactory()); mapper.configure(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS, true); - List objects = mapper.readValue(out.toByteArray(), new TypeReference>(){}); + List objects = mapper.readValue(out.toByteArray(), new TypeReference>() {}); assertEquals(5, objects.size()); int idx = 0; assertEquals(BigDecimal.valueOf(d0), objects.get(idx++)); @@ -375,21 +389,28 @@ public void testBigDecimal() throws IOException { assertEquals(BigDecimal.valueOf(Double.MIN_NORMAL), objects.get(idx++)); } - private File createTestFile() throws Exception { - File tempFile = createTempFile(new FileSetup() { + private File createTestFile() + throws Exception + { + File tempFile = createTempFile(new FileSetup() + { @Override - public void setup(File f) throws IOException { + public void setup(File f) + throws IOException + { MessagePack.newDefaultPacker(new FileOutputStream(f)) - .packArrayHeader(1).packInt(1) - .packArrayHeader(1).packInt(1) - .close(); + .packArrayHeader(1).packInt(1) + .packArrayHeader(1).packInt(1) + .close(); } }); return tempFile; } @Test(expected = IOException.class) - public void testEnableFeatureAutoCloseSource() throws Exception { + public void testEnableFeatureAutoCloseSource() + throws Exception + { File tempFile = createTestFile(); MessagePackFactory messagePackFactory = new MessagePackFactory(); FileInputStream in = new FileInputStream(tempFile); @@ -399,7 +420,9 @@ public void testEnableFeatureAutoCloseSource() throws Exception { } @Test - public void testDisableFeatureAutoCloseSource() throws Exception { + public void testDisableFeatureAutoCloseSource() + throws Exception + { File tempFile = createTestFile(); FileInputStream in = new FileInputStream(tempFile); ObjectMapper objectMapper = new ObjectMapper(new MessagePackFactory()); @@ -409,7 +432,9 @@ public void testDisableFeatureAutoCloseSource() throws Exception { } @Test - public void testParseBigDecimal() throws IOException { + public void testParseBigDecimal() + throws IOException + { ArrayList list = new ArrayList(); list.add(new BigDecimal(Long.MAX_VALUE)); ObjectMapper objectMapper = new ObjectMapper(new MessagePackFactory()); @@ -421,7 +446,9 @@ public void testParseBigDecimal() throws IOException { } @Test - public void testReadPrimitiveObjectViaObjectMapper() throws Exception { + public void testReadPrimitiveObjectViaObjectMapper() + throws Exception + { File tempFile = createTempFile(); FileOutputStream out = new FileOutputStream(tempFile); @@ -440,7 +467,7 @@ public void testReadPrimitiveObjectViaObjectMapper() throws Exception { assertEquals("foo", objectMapper.readValue(in, new TypeReference() {})); assertEquals(Long.MAX_VALUE, objectMapper.readValue(in, new TypeReference() {})); assertEquals(3.14, objectMapper.readValue(in, new TypeReference() {})); - byte[] bs = objectMapper.readValue(in, new TypeReference() {}); + byte[] bs = objectMapper.readValue(in, new TypeReference() {}); assertEquals(bytes.length, bs.length); assertEquals(bytes[0], bs[0]); assertEquals(bytes[1], bs[1]); diff --git a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/benchmark/MessagePackDataformatHugeDataBenchmarkTest.java b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/benchmark/MessagePackDataformatHugeDataBenchmarkTest.java index 504651456..342db62f5 100644 --- a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/benchmark/MessagePackDataformatHugeDataBenchmarkTest.java +++ b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/benchmark/MessagePackDataformatHugeDataBenchmarkTest.java @@ -25,7 +25,9 @@ import java.util.ArrayList; import java.util.List; -public class MessagePackDataformatHugeDataBenchmarkTest extends MessagePackDataformatTestBase { +public class MessagePackDataformatHugeDataBenchmarkTest + extends MessagePackDataformatTestBase +{ private static final int ELM_NUM = 1000000; private static final int SAMPLING_COUNT = 4; private final ObjectMapper origObjectMapper = new ObjectMapper(); @@ -33,13 +35,14 @@ public class MessagePackDataformatHugeDataBenchmarkTest extends MessagePackDataf private static final List value; private static final byte[] packedByOriginal; private static final byte[] packedByMsgPack; + static { value = new ArrayList(); for (int i = 0; i < ELM_NUM; i++) { - value.add((long)i); + value.add((long) i); } for (int i = 0; i < ELM_NUM; i++) { - value.add((double)i); + value.add((double) i); } for (int i = 0; i < ELM_NUM; i++) { value.add(String.valueOf(i)); @@ -48,25 +51,29 @@ public class MessagePackDataformatHugeDataBenchmarkTest extends MessagePackDataf byte[] bytes = null; try { bytes = new ObjectMapper().writeValueAsBytes(value); - } catch (JsonProcessingException e) { + } + catch (JsonProcessingException e) { e.printStackTrace(); } packedByOriginal = bytes; try { bytes = new ObjectMapper(new MessagePackFactory()).writeValueAsBytes(value); - } catch (JsonProcessingException e) { + } + catch (JsonProcessingException e) { e.printStackTrace(); } packedByMsgPack = bytes; } @Test - public void testBenchmark() throws Exception { - double durationOfSerializeWithJson[] = new double[SAMPLING_COUNT]; - double durationOfSerializeWithMsgPack[] = new double[SAMPLING_COUNT]; - double durationOfDeserializeWithJson[] = new double[SAMPLING_COUNT]; - double durationOfDeserializeWithMsgPack[] = new double[SAMPLING_COUNT]; + public void testBenchmark() + throws Exception + { + double[] durationOfSerializeWithJson = new double[SAMPLING_COUNT]; + double[] durationOfSerializeWithMsgPack = new double[SAMPLING_COUNT]; + double[] durationOfDeserializeWithJson = new double[SAMPLING_COUNT]; + double[] durationOfDeserializeWithMsgPack = new double[SAMPLING_COUNT]; for (int si = 0; si < SAMPLING_COUNT; si++) { long currentTimeMillis = System.currentTimeMillis(); origObjectMapper.writeValueAsBytes(value); diff --git a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/benchmark/MessagePackDataformatPojoBenchmarkTest.java b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/benchmark/MessagePackDataformatPojoBenchmarkTest.java index d7dedc43e..eef58b242 100644 --- a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/benchmark/MessagePackDataformatPojoBenchmarkTest.java +++ b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/benchmark/MessagePackDataformatPojoBenchmarkTest.java @@ -25,7 +25,9 @@ import java.util.ArrayList; import java.util.List; -public class MessagePackDataformatPojoBenchmarkTest extends MessagePackDataformatTestBase { +public class MessagePackDataformatPojoBenchmarkTest + extends MessagePackDataformatTestBase +{ private static final int LOOP_MAX = 1000; private static final int LOOP_FACTOR = 50; private static final int SAMPLING_COUNT = 4; @@ -69,7 +71,8 @@ public class MessagePackDataformatPojoBenchmarkTest extends MessagePackDataforma for (int i = 0; i < LOOP_MAX; i++) { try { pojosSerWithOrig.add(origObjectMapper.writeValueAsBytes(pojos.get(i))); - } catch (JsonProcessingException e) { + } + catch (JsonProcessingException e) { e.printStackTrace(); } } @@ -77,45 +80,52 @@ public class MessagePackDataformatPojoBenchmarkTest extends MessagePackDataforma for (int i = 0; i < LOOP_MAX; i++) { try { pojosSerWithMsgPack.add(msgpackObjectMapper.writeValueAsBytes(pojos.get(i))); - } catch (JsonProcessingException e) { + } + catch (JsonProcessingException e) { e.printStackTrace(); } } } @Test - public void testBenchmark() throws Exception { - double durationOfSerializeWithJson[] = new double[SAMPLING_COUNT]; - double durationOfSerializeWithMsgPack[] = new double[SAMPLING_COUNT]; - double durationOfDeserializeWithJson[] = new double[SAMPLING_COUNT]; - double durationOfDeserializeWithMsgPack[] = new double[SAMPLING_COUNT]; + public void testBenchmark() + throws Exception + { + double[] durationOfSerializeWithJson = new double[SAMPLING_COUNT]; + double[] durationOfSerializeWithMsgPack = new double[SAMPLING_COUNT]; + double[] durationOfDeserializeWithJson = new double[SAMPLING_COUNT]; + double[] durationOfDeserializeWithMsgPack = new double[SAMPLING_COUNT]; for (int si = 0; si < SAMPLING_COUNT; si++) { long currentTimeMillis = System.currentTimeMillis(); - for (int j = 0; j < LOOP_FACTOR; j++) + for (int j = 0; j < LOOP_FACTOR; j++) { for (int i = 0; i < LOOP_MAX; i++) { origObjectMapper.writeValueAsBytes(pojos.get(i)); } + } durationOfSerializeWithJson[si] = System.currentTimeMillis() - currentTimeMillis; currentTimeMillis = System.currentTimeMillis(); - for (int j = 0; j < LOOP_FACTOR; j++) + for (int j = 0; j < LOOP_FACTOR; j++) { for (int i = 0; i < LOOP_MAX; i++) { msgpackObjectMapper.writeValueAsBytes(pojos.get(i)); } + } durationOfSerializeWithMsgPack[si] = System.currentTimeMillis() - currentTimeMillis; currentTimeMillis = System.currentTimeMillis(); - for (int j = 0; j < LOOP_FACTOR; j++) + for (int j = 0; j < LOOP_FACTOR; j++) { for (int i = 0; i < LOOP_MAX; i++) { origObjectMapper.readValue(pojosSerWithOrig.get(i), NormalPojo.class); } + } durationOfDeserializeWithJson[si] = System.currentTimeMillis() - currentTimeMillis; currentTimeMillis = System.currentTimeMillis(); - for (int j = 0; j < LOOP_FACTOR; j++) + for (int j = 0; j < LOOP_FACTOR; j++) { for (int i = 0; i < LOOP_MAX; i++) { msgpackObjectMapper.readValue(pojosSerWithMsgPack.get(i), NormalPojo.class); } + } durationOfDeserializeWithMsgPack[si] = System.currentTimeMillis() - currentTimeMillis; } printStat("serialize(pojo) with JSON", durationOfSerializeWithJson); diff --git a/project/Build.scala b/project/Build.scala index 6f19d1995..1b3f32efd 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -25,6 +25,7 @@ import sbtrelease.ReleasePlugin._ import sbtrelease.ReleaseStateTransformations._ import sbtrelease.ReleaseStep import scala.util.Properties +import xerial.sbt.jcheckstyle.JCheckStyle.JCheckStyleKeys._ object Build extends Build { @@ -77,7 +78,10 @@ object Build extends Build { opts }, findbugsReportType := Some(ReportType.FancyHtml), - findbugsReportPath := Some(crossTarget.value / "findbugs" / "report.html") + findbugsReportPath := Some(crossTarget.value / "findbugs" / "report.html"), + jcheckStyleConfig := "facebook", + compile <<= (compile in Compile) dependsOn (jcheckStyle in Compile), + compile <<= (compile in Test) dependsOn (jcheckStyle in Test) ) import Dependencies._ From 7e2b8f805e903d57b2ae142c79704bf97b06d0b6 Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Tue, 23 Jun 2015 17:54:46 +0900 Subject: [PATCH 102/234] Add notes on coding style --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 1bf7b8f80..eabe54553 100644 --- a/README.md +++ b/README.md @@ -39,6 +39,10 @@ For details, see [msgpack-jackson/README.md](msgpack-jackson/README.md). The tem msgpack-java uses [sbt](http://www.scala-sbt.org/) for building the projects. For the basic usage of sbt, see: * [Building Java projects with sbt](http://xerial.org/blog/2014/03/24/sbt/) +Coding style + * msgpack-java uses [the same coding style](https://github.com/airlift/codestyle) with Facebook Presto + * [IntelliJ setting file](https://raw.githubusercontent.com/airlift/codestyle/master/IntelliJIdea13/Airlift.xml) + ### Basic sbt commands Enter the sbt console: ``` From f75d7a33881567b85fed3b398db76df9ea7c0b18 Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Tue, 23 Jun 2015 18:02:08 +0900 Subject: [PATCH 103/234] Add release notes for 0.7.0-M6 --- RELEASE_NOTES.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index f7e44f3d7..a31eff829 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -1,7 +1,12 @@ # Release Notes +* 2015-06-23 0.7.0-M6 + * Add a prototype of Value implementation + * Apply strict coding style + * Several bug fixes + * 2015-04-27 0.7.0-p9 - * Fix [#217] when reading from SockectInputStream + * Fix [#217](https://github.com/msgpack/msgpack-java/issues/217) when reading from SockectInputStream * 2015-04-09 0.7.0-p8 * Support Extension type (defined in MessagePack) in msgpack-jackson From d9a472ddbc5152ecfb5b4c4bcf46c84a94436c29 Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Tue, 23 Jun 2015 18:06:37 +0900 Subject: [PATCH 104/234] Remove release dates. Use git tag instead --- RELEASE_NOTES.md | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index a31eff829..1419dae66 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -1,28 +1,27 @@ # Release Notes -* 2015-06-23 0.7.0-M6 +* 0.7.0-M6 * Add a prototype of Value implementation * Apply strict coding style * Several bug fixes -* 2015-04-27 0.7.0-p9 +* 0.7.0-p9 * Fix [#217](https://github.com/msgpack/msgpack-java/issues/217) when reading from SockectInputStream -* 2015-04-09 0.7.0-p8 +* 0.7.0-p8 * Support Extension type (defined in MessagePack) in msgpack-jackson * Support BigDecimal type (defined in Jackson) in msgpack-jackson * Fix MessageUnpacker#unpackString [#215](https://github.com/msgpack/msgpack-java/pull/215), [#216](https://github.com/msgpack/msgpack-java/pull/216) -* 2015-02-16 0.7.0-p7 +* 0.7.0-p7 * Google App Engine (GAE) support -* 2015-02-11 0.7.0-p6 +* 0.7.0-p6 * Add MessagePacker.getTotalWrittenBytes() -* 2015-01-28 0.7.0-p5 +* 0.7.0-p5 * Fix skipValue [#185](https://github.com/msgpack/msgpack-java/pull/185) -* 2015-01-19 0.7.0-p4 +* 0.7.0-p4 * Supporting some java6 platform and Android - From fa554b05209b462833221ba6eb3ddfce66bcc1ac Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Tue, 23 Jun 2015 19:58:37 +0900 Subject: [PATCH 105/234] Fixes #95: Apply license headers --- .../org/msgpack/core/ExtensionTypeHeader.java | 15 +++++++++++++++ .../java/org/msgpack/core/MessageFormat.java | 15 +++++++++++++++ .../java/org/msgpack/core/Preconditions.java | 16 ++++++++++++++++ .../org/msgpack/core/annotations/Insecure.java | 15 +++++++++++++++ .../org/msgpack/core/annotations/Nullable.java | 15 +++++++++++++++ .../core/annotations/VisibleForTesting.java | 15 +++++++++++++++ .../msgpack/core/buffer/ArrayBufferInput.java | 15 +++++++++++++++ .../org/msgpack/core/buffer/ByteBufferInput.java | 15 +++++++++++++++ .../msgpack/core/buffer/ChannelBufferInput.java | 15 +++++++++++++++ .../msgpack/core/buffer/ChannelBufferOutput.java | 15 +++++++++++++++ .../msgpack/core/buffer/DirectBufferAccess.java | 15 +++++++++++++++ .../core/buffer/InputStreamBufferInput.java | 15 +++++++++++++++ .../org/msgpack/core/buffer/MessageBuffer.java | 15 +++++++++++++++ .../org/msgpack/core/buffer/MessageBufferBE.java | 15 +++++++++++++++ .../msgpack/core/buffer/MessageBufferInput.java | 15 +++++++++++++++ .../msgpack/core/buffer/MessageBufferOutput.java | 15 +++++++++++++++ .../org/msgpack/core/buffer/MessageBufferU.java | 15 +++++++++++++++ .../core/buffer/OutputStreamBufferOutput.java | 15 +++++++++++++++ .../org/msgpack/core/MessageFormatTest.scala | 15 +++++++++++++++ .../org/msgpack/core/MessageUnpackerTest.scala | 15 +++++++++++++++ .../org/msgpack/core/buffer/ByteStringTest.scala | 15 +++++++++++++++ .../core/buffer/MessageBufferInputTest.scala | 15 +++++++++++++++ .../core/buffer/MessageBufferOutputTest.scala | 15 +++++++++++++++ .../msgpack/core/buffer/MessageBufferTest.scala | 15 +++++++++++++++ .../core/example/MessagePackExampleTest.scala | 15 +++++++++++++++ .../msgpack/value/RawStringValueImplTest.scala | 15 +++++++++++++++ .../org/msgpack/value/ValueFactoryTest.scala | 15 +++++++++++++++ .../scala/org/msgpack/value/ValueTypeTest.scala | 15 +++++++++++++++ .../jackson/dataformat/MessagePackGenerator.java | 15 +++++++++++++++ .../jackson/dataformat/MessagePackParser.java | 15 +++++++++++++++ .../org/msgpack/jackson/dataformat/Tuple.java | 15 +++++++++++++++ .../MessagePackDataformatForPojoTest.java | 15 +++++++++++++++ .../MessagePackDataformatTestBase.java | 15 +++++++++++++++ .../dataformat/MessagePackFactoryTest.java | 15 +++++++++++++++ .../dataformat/MessagePackParserTest.java | 15 +++++++++++++++ 35 files changed, 526 insertions(+) diff --git a/msgpack-core/src/main/java/org/msgpack/core/ExtensionTypeHeader.java b/msgpack-core/src/main/java/org/msgpack/core/ExtensionTypeHeader.java index 725da34a7..73e92035a 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/ExtensionTypeHeader.java +++ b/msgpack-core/src/main/java/org/msgpack/core/ExtensionTypeHeader.java @@ -1,3 +1,18 @@ +// +// MessagePack for Java +// +// 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.core; import static org.msgpack.core.Preconditions.checkArgument; diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessageFormat.java b/msgpack-core/src/main/java/org/msgpack/core/MessageFormat.java index 7fc258ceb..8e44b0aae 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/MessageFormat.java +++ b/msgpack-core/src/main/java/org/msgpack/core/MessageFormat.java @@ -1,3 +1,18 @@ +// +// MessagePack for Java +// +// 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.core; import org.msgpack.core.MessagePack.Code; diff --git a/msgpack-core/src/main/java/org/msgpack/core/Preconditions.java b/msgpack-core/src/main/java/org/msgpack/core/Preconditions.java index b1ad967b8..e44d97d15 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/Preconditions.java +++ b/msgpack-core/src/main/java/org/msgpack/core/Preconditions.java @@ -1,3 +1,19 @@ +// +// MessagePack for Java +// +// 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. +// + /* * Copyright (C) 2007 The Guava Authors * diff --git a/msgpack-core/src/main/java/org/msgpack/core/annotations/Insecure.java b/msgpack-core/src/main/java/org/msgpack/core/annotations/Insecure.java index e66f20b8b..c8678ae41 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/annotations/Insecure.java +++ b/msgpack-core/src/main/java/org/msgpack/core/annotations/Insecure.java @@ -1,3 +1,18 @@ +// +// MessagePack for Java +// +// 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.core.annotations; /** diff --git a/msgpack-core/src/main/java/org/msgpack/core/annotations/Nullable.java b/msgpack-core/src/main/java/org/msgpack/core/annotations/Nullable.java index 45146c203..9e7c94fab 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/annotations/Nullable.java +++ b/msgpack-core/src/main/java/org/msgpack/core/annotations/Nullable.java @@ -1,3 +1,18 @@ +// +// MessagePack for Java +// +// 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.core.annotations; /** diff --git a/msgpack-core/src/main/java/org/msgpack/core/annotations/VisibleForTesting.java b/msgpack-core/src/main/java/org/msgpack/core/annotations/VisibleForTesting.java index 360f22c44..ddd4aa4c9 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/annotations/VisibleForTesting.java +++ b/msgpack-core/src/main/java/org/msgpack/core/annotations/VisibleForTesting.java @@ -1,3 +1,18 @@ +// +// MessagePack for Java +// +// 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.core.annotations; /** diff --git a/msgpack-core/src/main/java/org/msgpack/core/buffer/ArrayBufferInput.java b/msgpack-core/src/main/java/org/msgpack/core/buffer/ArrayBufferInput.java index 66d6a5c64..88fe45942 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/buffer/ArrayBufferInput.java +++ b/msgpack-core/src/main/java/org/msgpack/core/buffer/ArrayBufferInput.java @@ -1,3 +1,18 @@ +// +// MessagePack for Java +// +// 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.core.buffer; import java.io.IOException; diff --git a/msgpack-core/src/main/java/org/msgpack/core/buffer/ByteBufferInput.java b/msgpack-core/src/main/java/org/msgpack/core/buffer/ByteBufferInput.java index 33c0b0c94..b9b4304ad 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/buffer/ByteBufferInput.java +++ b/msgpack-core/src/main/java/org/msgpack/core/buffer/ByteBufferInput.java @@ -1,3 +1,18 @@ +// +// MessagePack for Java +// +// 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.core.buffer; import java.io.IOException; diff --git a/msgpack-core/src/main/java/org/msgpack/core/buffer/ChannelBufferInput.java b/msgpack-core/src/main/java/org/msgpack/core/buffer/ChannelBufferInput.java index e6b926b43..4b8baeb75 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/buffer/ChannelBufferInput.java +++ b/msgpack-core/src/main/java/org/msgpack/core/buffer/ChannelBufferInput.java @@ -1,3 +1,18 @@ +// +// MessagePack for Java +// +// 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.core.buffer; import java.io.IOException; diff --git a/msgpack-core/src/main/java/org/msgpack/core/buffer/ChannelBufferOutput.java b/msgpack-core/src/main/java/org/msgpack/core/buffer/ChannelBufferOutput.java index 0e1beb79b..9ecddf3ac 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/buffer/ChannelBufferOutput.java +++ b/msgpack-core/src/main/java/org/msgpack/core/buffer/ChannelBufferOutput.java @@ -1,3 +1,18 @@ +// +// MessagePack for Java +// +// 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.core.buffer; import java.io.IOException; diff --git a/msgpack-core/src/main/java/org/msgpack/core/buffer/DirectBufferAccess.java b/msgpack-core/src/main/java/org/msgpack/core/buffer/DirectBufferAccess.java index 49f41c58f..ab86061d3 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/buffer/DirectBufferAccess.java +++ b/msgpack-core/src/main/java/org/msgpack/core/buffer/DirectBufferAccess.java @@ -1,3 +1,18 @@ +// +// MessagePack for Java +// +// 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.core.buffer; import java.lang.reflect.Constructor; diff --git a/msgpack-core/src/main/java/org/msgpack/core/buffer/InputStreamBufferInput.java b/msgpack-core/src/main/java/org/msgpack/core/buffer/InputStreamBufferInput.java index a05b32bac..81aabd762 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/buffer/InputStreamBufferInput.java +++ b/msgpack-core/src/main/java/org/msgpack/core/buffer/InputStreamBufferInput.java @@ -1,3 +1,18 @@ +// +// MessagePack for Java +// +// 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.core.buffer; import java.io.FileInputStream; diff --git a/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBuffer.java b/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBuffer.java index a052d21fa..4dd1396f1 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBuffer.java +++ b/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBuffer.java @@ -1,3 +1,18 @@ +// +// MessagePack for Java +// +// 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.core.buffer; import org.msgpack.core.annotations.Insecure; diff --git a/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferBE.java b/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferBE.java index b1a3ca7b0..bd78b6653 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferBE.java +++ b/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferBE.java @@ -1,3 +1,18 @@ +// +// MessagePack for Java +// +// 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.core.buffer; import java.nio.ByteBuffer; diff --git a/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferInput.java b/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferInput.java index 87478dd91..786ce2721 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferInput.java +++ b/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferInput.java @@ -1,3 +1,18 @@ +// +// MessagePack for Java +// +// 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.core.buffer; import java.io.Closeable; diff --git a/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferOutput.java b/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferOutput.java index 218f69f07..77fe12454 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferOutput.java +++ b/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferOutput.java @@ -1,3 +1,18 @@ +// +// MessagePack for Java +// +// 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.core.buffer; import java.io.Closeable; diff --git a/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferU.java b/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferU.java index a6316fce6..4d60d8aad 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferU.java +++ b/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferU.java @@ -1,3 +1,18 @@ +// +// MessagePack for Java +// +// 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.core.buffer; import java.nio.ByteBuffer; diff --git a/msgpack-core/src/main/java/org/msgpack/core/buffer/OutputStreamBufferOutput.java b/msgpack-core/src/main/java/org/msgpack/core/buffer/OutputStreamBufferOutput.java index 4deb8528f..07d423bf0 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/buffer/OutputStreamBufferOutput.java +++ b/msgpack-core/src/main/java/org/msgpack/core/buffer/OutputStreamBufferOutput.java @@ -1,3 +1,18 @@ +// +// MessagePack for Java +// +// 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.core.buffer; import java.io.IOException; diff --git a/msgpack-core/src/test/scala/org/msgpack/core/MessageFormatTest.scala b/msgpack-core/src/test/scala/org/msgpack/core/MessageFormatTest.scala index 9b9939608..be9d270cd 100644 --- a/msgpack-core/src/test/scala/org/msgpack/core/MessageFormatTest.scala +++ b/msgpack-core/src/test/scala/org/msgpack/core/MessageFormatTest.scala @@ -1,3 +1,18 @@ +// +// MessagePack for Java +// +// 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.core import org.msgpack.core.MessagePack.Code diff --git a/msgpack-core/src/test/scala/org/msgpack/core/MessageUnpackerTest.scala b/msgpack-core/src/test/scala/org/msgpack/core/MessageUnpackerTest.scala index f6fc37cb7..39ca1639b 100644 --- a/msgpack-core/src/test/scala/org/msgpack/core/MessageUnpackerTest.scala +++ b/msgpack-core/src/test/scala/org/msgpack/core/MessageUnpackerTest.scala @@ -1,3 +1,18 @@ +// +// MessagePack for Java +// +// 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.core import java.io._ diff --git a/msgpack-core/src/test/scala/org/msgpack/core/buffer/ByteStringTest.scala b/msgpack-core/src/test/scala/org/msgpack/core/buffer/ByteStringTest.scala index 336f30755..362038d95 100644 --- a/msgpack-core/src/test/scala/org/msgpack/core/buffer/ByteStringTest.scala +++ b/msgpack-core/src/test/scala/org/msgpack/core/buffer/ByteStringTest.scala @@ -1,3 +1,18 @@ +// +// MessagePack for Java +// +// 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.core.buffer import akka.util.ByteString diff --git a/msgpack-core/src/test/scala/org/msgpack/core/buffer/MessageBufferInputTest.scala b/msgpack-core/src/test/scala/org/msgpack/core/buffer/MessageBufferInputTest.scala index 8903e375c..d7ebeac84 100644 --- a/msgpack-core/src/test/scala/org/msgpack/core/buffer/MessageBufferInputTest.scala +++ b/msgpack-core/src/test/scala/org/msgpack/core/buffer/MessageBufferInputTest.scala @@ -1,3 +1,18 @@ +// +// MessagePack for Java +// +// 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.core.buffer import java.io._ diff --git a/msgpack-core/src/test/scala/org/msgpack/core/buffer/MessageBufferOutputTest.scala b/msgpack-core/src/test/scala/org/msgpack/core/buffer/MessageBufferOutputTest.scala index af38b009f..8616d1c69 100644 --- a/msgpack-core/src/test/scala/org/msgpack/core/buffer/MessageBufferOutputTest.scala +++ b/msgpack-core/src/test/scala/org/msgpack/core/buffer/MessageBufferOutputTest.scala @@ -1,3 +1,18 @@ +// +// MessagePack for Java +// +// 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.core.buffer import java.io._ diff --git a/msgpack-core/src/test/scala/org/msgpack/core/buffer/MessageBufferTest.scala b/msgpack-core/src/test/scala/org/msgpack/core/buffer/MessageBufferTest.scala index d5e2f2b33..32ee58f02 100644 --- a/msgpack-core/src/test/scala/org/msgpack/core/buffer/MessageBufferTest.scala +++ b/msgpack-core/src/test/scala/org/msgpack/core/buffer/MessageBufferTest.scala @@ -1,3 +1,18 @@ +// +// MessagePack for Java +// +// 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.core.buffer import java.nio.ByteBuffer diff --git a/msgpack-core/src/test/scala/org/msgpack/core/example/MessagePackExampleTest.scala b/msgpack-core/src/test/scala/org/msgpack/core/example/MessagePackExampleTest.scala index e8b167674..bacf39ed4 100644 --- a/msgpack-core/src/test/scala/org/msgpack/core/example/MessagePackExampleTest.scala +++ b/msgpack-core/src/test/scala/org/msgpack/core/example/MessagePackExampleTest.scala @@ -1,3 +1,18 @@ +// +// MessagePack for Java +// +// 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.core.example import org.msgpack.core.MessagePackSpec diff --git a/msgpack-core/src/test/scala/org/msgpack/value/RawStringValueImplTest.scala b/msgpack-core/src/test/scala/org/msgpack/value/RawStringValueImplTest.scala index 7372887c6..e545d7d2a 100644 --- a/msgpack-core/src/test/scala/org/msgpack/value/RawStringValueImplTest.scala +++ b/msgpack-core/src/test/scala/org/msgpack/value/RawStringValueImplTest.scala @@ -1,3 +1,18 @@ +// +// MessagePack for Java +// +// 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.value import org.msgpack.core.MessagePackSpec diff --git a/msgpack-core/src/test/scala/org/msgpack/value/ValueFactoryTest.scala b/msgpack-core/src/test/scala/org/msgpack/value/ValueFactoryTest.scala index 0b531ddad..a8d996376 100644 --- a/msgpack-core/src/test/scala/org/msgpack/value/ValueFactoryTest.scala +++ b/msgpack-core/src/test/scala/org/msgpack/value/ValueFactoryTest.scala @@ -1,3 +1,18 @@ +// +// MessagePack for Java +// +// 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.value import org.msgpack.core.MessagePackSpec diff --git a/msgpack-core/src/test/scala/org/msgpack/value/ValueTypeTest.scala b/msgpack-core/src/test/scala/org/msgpack/value/ValueTypeTest.scala index c5f46fdb0..6634ef606 100644 --- a/msgpack-core/src/test/scala/org/msgpack/value/ValueTypeTest.scala +++ b/msgpack-core/src/test/scala/org/msgpack/value/ValueTypeTest.scala @@ -1,3 +1,18 @@ +// +// MessagePack for Java +// +// 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.value import org.msgpack.core.MessagePack.Code._ diff --git a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackGenerator.java b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackGenerator.java index f1ce4a135..3be62fb53 100644 --- a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackGenerator.java +++ b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackGenerator.java @@ -1,3 +1,18 @@ +// +// MessagePack for Java +// +// 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.jackson.dataformat; import com.fasterxml.jackson.core.Base64Variant; diff --git a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java index 4063ac1fa..9e8ab8b7f 100644 --- a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java +++ b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java @@ -1,3 +1,18 @@ +// +// MessagePack for Java +// +// 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.jackson.dataformat; import com.fasterxml.jackson.core.Base64Variant; diff --git a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/Tuple.java b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/Tuple.java index e17dce2f5..1a252739f 100644 --- a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/Tuple.java +++ b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/Tuple.java @@ -1,3 +1,18 @@ +// +// MessagePack for Java +// +// 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.jackson.dataformat; /** diff --git a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackDataformatForPojoTest.java b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackDataformatForPojoTest.java index d9a40097c..5c1559770 100644 --- a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackDataformatForPojoTest.java +++ b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackDataformatForPojoTest.java @@ -1,3 +1,18 @@ +// +// MessagePack for Java +// +// 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.jackson.dataformat; import org.junit.Test; diff --git a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackDataformatTestBase.java b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackDataformatTestBase.java index 5ed5ae039..fad09b910 100644 --- a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackDataformatTestBase.java +++ b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackDataformatTestBase.java @@ -1,3 +1,18 @@ +// +// MessagePack for Java +// +// 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.jackson.dataformat; import com.fasterxml.jackson.annotation.JsonIgnore; diff --git a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackFactoryTest.java b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackFactoryTest.java index d9b9adfe5..25180f784 100644 --- a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackFactoryTest.java +++ b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackFactoryTest.java @@ -1,3 +1,18 @@ +// +// MessagePack for Java +// +// 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.jackson.dataformat; import com.fasterxml.jackson.core.JsonEncoding; diff --git a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackParserTest.java b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackParserTest.java index 0b42bc2c4..bb4d1f9e5 100644 --- a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackParserTest.java +++ b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackParserTest.java @@ -1,3 +1,18 @@ +// +// MessagePack for Java +// +// 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.jackson.dataformat; import com.fasterxml.jackson.core.JsonParser; From c7006c9b491b4e05b3f82e24147bb00427d14af3 Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Tue, 23 Jun 2015 20:02:03 +0900 Subject: [PATCH 106/234] Add copyright setting for IntelliJ --- .idea/copyright/msgpack.xml | 8 ++++++++ .idea/copyright/profiles_settings.xml | 19 +++++++++++++++++++ 2 files changed, 27 insertions(+) create mode 100644 .idea/copyright/msgpack.xml create mode 100644 .idea/copyright/profiles_settings.xml diff --git a/.idea/copyright/msgpack.xml b/.idea/copyright/msgpack.xml new file mode 100644 index 000000000..0859c620a --- /dev/null +++ b/.idea/copyright/msgpack.xml @@ -0,0 +1,8 @@ + + + + \ No newline at end of file diff --git a/.idea/copyright/profiles_settings.xml b/.idea/copyright/profiles_settings.xml new file mode 100644 index 000000000..8635b5bef --- /dev/null +++ b/.idea/copyright/profiles_settings.xml @@ -0,0 +1,19 @@ + + + + + + + + + + \ No newline at end of file From 0f11bda0ece1c189a81247fd52a6f5e688d2d457 Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Tue, 23 Jun 2015 22:50:37 +0900 Subject: [PATCH 107/234] Fixes #38: Add IntegerValue.mostSuccinctMessageFormat --- .../java/org/msgpack/core/MessagePacker.java | 2 +- .../java/org/msgpack/value/IntegerValue.java | 8 +++ .../main/java/org/msgpack/value/Variable.java | 8 +++ .../impl/ImmutableBigIntegerValueImpl.java | 27 ++++++++++ .../value/impl/ImmutableLongValueImpl.java | 7 +++ .../scala/org/msgpack/value/ValueTest.scala | 49 +++++++++++++++++++ 6 files changed, 100 insertions(+), 1 deletion(-) create mode 100644 msgpack-core/src/test/scala/org/msgpack/value/ValueTest.scala diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessagePacker.java b/msgpack-core/src/main/java/org/msgpack/core/MessagePacker.java index fc13eae06..ca40540fa 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/MessagePacker.java +++ b/msgpack-core/src/main/java/org/msgpack/core/MessagePacker.java @@ -423,7 +423,7 @@ else if (bi.bitLength() == 64 && bi.signum() == 1) { writeByteAndLong(UINT64, bi.longValue()); } else { - throw new IllegalArgumentException("Messagepack cannot serialize BigInteger larger than 2^64-1"); + throw new IllegalArgumentException("MessagePack cannot serialize BigInteger larger than 2^64-1"); } return this; } diff --git a/msgpack-core/src/main/java/org/msgpack/value/IntegerValue.java b/msgpack-core/src/main/java/org/msgpack/value/IntegerValue.java index ca0ffcd33..294a0f775 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/IntegerValue.java +++ b/msgpack-core/src/main/java/org/msgpack/value/IntegerValue.java @@ -15,6 +15,8 @@ // package org.msgpack.value; +import org.msgpack.core.MessageFormat; + import java.math.BigInteger; /** @@ -45,6 +47,12 @@ public interface IntegerValue */ boolean isInLongRange(); + /** + * Returns the most succinct MessageFormat type to represent this integer value. + * @return + */ + MessageFormat mostSuccinctMessageFormat(); + /** * Returns the value as a {@code byte}, otherwise throws an exception. * diff --git a/msgpack-core/src/main/java/org/msgpack/value/Variable.java b/msgpack-core/src/main/java/org/msgpack/value/Variable.java index 7cd164336..67a5325fe 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/Variable.java +++ b/msgpack-core/src/main/java/org/msgpack/value/Variable.java @@ -15,11 +15,13 @@ // package org.msgpack.value; +import org.msgpack.core.MessageFormat; import org.msgpack.core.MessageIntegerOverflowException; import org.msgpack.core.MessagePack; import org.msgpack.core.MessagePacker; import org.msgpack.core.MessageStringCodingException; import org.msgpack.core.MessageTypeCastException; +import org.msgpack.value.impl.ImmutableBigIntegerValueImpl; import java.io.IOException; import java.math.BigDecimal; @@ -515,6 +517,12 @@ public boolean isInLongRange() return true; } + @Override + public MessageFormat mostSuccinctMessageFormat() + { + return ImmutableBigIntegerValueImpl.mostSuccinctMessageFormat(this); + } + @Override public byte getByte() { diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableBigIntegerValueImpl.java b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableBigIntegerValueImpl.java index 2893c4154..ef1de0966 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableBigIntegerValueImpl.java +++ b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableBigIntegerValueImpl.java @@ -15,6 +15,7 @@ // package org.msgpack.value.impl; +import org.msgpack.core.MessageFormat; import org.msgpack.core.MessageIntegerOverflowException; import org.msgpack.core.MessagePacker; import org.msgpack.value.ImmutableIntegerValue; @@ -35,6 +36,26 @@ public class ImmutableBigIntegerValueImpl extends AbstractImmutableValue implements ImmutableIntegerValue { + public static MessageFormat mostSuccinctMessageFormat(IntegerValue v) + { + if(v.isInByteRange()) { + return MessageFormat.INT8; + } + else if(v.isInShortRange()) { + return MessageFormat.INT16; + } + else if(v.isInIntRange()) { + return MessageFormat.INT32; + } + else if(v.isInLongRange()) { + return MessageFormat.INT64; + } + else { + return MessageFormat.UINT64; + } + } + + private final BigInteger value; public ImmutableBigIntegerValueImpl(BigInteger value) @@ -141,6 +162,12 @@ public boolean isInLongRange() return 0 <= value.compareTo(LONG_MIN) && value.compareTo(LONG_MAX) <= 0; } + @Override + public MessageFormat mostSuccinctMessageFormat() + { + return mostSuccinctMessageFormat(this); + } + @Override public byte getByte() { diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableLongValueImpl.java b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableLongValueImpl.java index 65e184f1c..350e01cc5 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableLongValueImpl.java +++ b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableLongValueImpl.java @@ -15,6 +15,7 @@ // package org.msgpack.value.impl; +import org.msgpack.core.MessageFormat; import org.msgpack.core.MessageIntegerOverflowException; import org.msgpack.core.MessagePacker; import org.msgpack.value.ImmutableIntegerValue; @@ -139,6 +140,12 @@ public boolean isInLongRange() return true; } + @Override + public MessageFormat mostSuccinctMessageFormat() + { + return ImmutableBigIntegerValueImpl.mostSuccinctMessageFormat(this); + } + @Override public byte getByte() { diff --git a/msgpack-core/src/test/scala/org/msgpack/value/ValueTest.scala b/msgpack-core/src/test/scala/org/msgpack/value/ValueTest.scala new file mode 100644 index 000000000..e08b34670 --- /dev/null +++ b/msgpack-core/src/test/scala/org/msgpack/value/ValueTest.scala @@ -0,0 +1,49 @@ +// +// MessagePack for Java +// +// 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.value + +import java.math.BigInteger + +import org.msgpack.core._ + +class ValueTest extends MessagePackSpec +{ + def checkSuccinctType(pack:MessagePacker => Unit, expectedAtMost:MessageFormat) { + val b = createMessagePackData(pack) + val v1 = MessagePack.newDefaultUnpacker(b).unpackValue() + v1.asIntegerValue().mostSuccinctMessageFormat().ordinal() shouldBe <= (expectedAtMost.ordinal()) + + val v2 = new Variable + MessagePack.newDefaultUnpacker(b).unpackValue(v2) + v2.asIntegerValue().mostSuccinctMessageFormat().ordinal() shouldBe <= (expectedAtMost.ordinal()) + } + + "Value" should { + "tell most succinct integer type" in { + forAll { (v: Byte) => checkSuccinctType(_.packByte(v), MessageFormat.INT8) } + forAll { (v: Short) => checkSuccinctType(_.packShort(v), MessageFormat.INT16) } + forAll { (v: Int) => checkSuccinctType(_.packInt(v), MessageFormat.INT32) } + forAll { (v: Long) => checkSuccinctType(_.packLong(v), MessageFormat.INT64) } + forAll { (v: Long) => checkSuccinctType(_.packBigInteger(BigInteger.valueOf(v)), MessageFormat.INT64) } + forAll { (v: Long) => + whenever(v > 0) { + // Create value between 2^63-1 < v <= 2^64-1 + checkSuccinctType(_.packBigInteger(BigInteger.valueOf(Long.MaxValue).add(BigInteger.valueOf(v))), MessageFormat.UINT64) + } + } + } + } +} From 05edaed22d3011189524715b5b84122adc054fba Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Tue, 23 Jun 2015 23:09:33 +0900 Subject: [PATCH 108/234] Add Integer type test --- .../src/test/scala/org/msgpack/value/ValueTest.scala | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/msgpack-core/src/test/scala/org/msgpack/value/ValueTest.scala b/msgpack-core/src/test/scala/org/msgpack/value/ValueTest.scala index e08b34670..a89dcb880 100644 --- a/msgpack-core/src/test/scala/org/msgpack/value/ValueTest.scala +++ b/msgpack-core/src/test/scala/org/msgpack/value/ValueTest.scala @@ -24,11 +24,15 @@ class ValueTest extends MessagePackSpec def checkSuccinctType(pack:MessagePacker => Unit, expectedAtMost:MessageFormat) { val b = createMessagePackData(pack) val v1 = MessagePack.newDefaultUnpacker(b).unpackValue() - v1.asIntegerValue().mostSuccinctMessageFormat().ordinal() shouldBe <= (expectedAtMost.ordinal()) + val mf = v1.asIntegerValue().mostSuccinctMessageFormat() + mf.getValueType shouldBe ValueType.INTEGER + mf.ordinal() shouldBe <= (expectedAtMost.ordinal()) val v2 = new Variable MessagePack.newDefaultUnpacker(b).unpackValue(v2) - v2.asIntegerValue().mostSuccinctMessageFormat().ordinal() shouldBe <= (expectedAtMost.ordinal()) + val mf2 = v2.asIntegerValue().mostSuccinctMessageFormat() + mf2.getValueType shouldBe ValueType.INTEGER + mf2.ordinal() shouldBe <= (expectedAtMost.ordinal()) } "Value" should { From 4245ec994f3d99210f4966e35b1ede65c8ee35f3 Mon Sep 17 00:00:00 2001 From: Mitsunori Komatsu Date: Sun, 28 Jun 2015 22:55:26 +0900 Subject: [PATCH 109/234] Add test for issue#235 --- .../dataformat/MessagePackParserTest.java | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackParserTest.java b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackParserTest.java index bb4d1f9e5..764da9d8f 100644 --- a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackParserTest.java +++ b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackParserTest.java @@ -26,6 +26,7 @@ import org.msgpack.core.buffer.OutputStreamBufferOutput; import org.msgpack.value.ExtensionValue; +import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; @@ -488,4 +489,52 @@ public void testReadPrimitiveObjectViaObjectMapper() assertEquals(bytes[1], bs[1]); assertEquals(bytes[2], bs[2]); } + + @Test + public void testBinaryKey() + throws Exception + { + File tempFile = createTempFile(); + FileOutputStream out = new FileOutputStream(tempFile); + MessagePacker packer = MessagePack.newDefaultPacker(out); + packer.packMapHeader(2); + packer.packString("foo"); + packer.packDouble(3.14); + byte[] bytes = "bar".getBytes(); + packer.packBinaryHeader(bytes.length); + packer.writePayload(bytes); + packer.packLong(42); + packer.close(); + + ObjectMapper mapper = new ObjectMapper(new MessagePackFactory()); + Map object = mapper.readValue(new FileInputStream(tempFile), new TypeReference>() {}); + assertEquals(2, object.size()); + assertEquals(3.14, object.get("foo")); + assertEquals(42, object.get("bar")); + } + + @Test + public void testBinaryKeyInNestedObject() + throws Exception + { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + MessagePacker packer = MessagePack.newDefaultPacker(out); + packer.packArrayHeader(2); + packer.packMapHeader(1); + byte[] bytes = "bar".getBytes(); + packer.packBinaryHeader(bytes.length); + packer.writePayload(bytes); + packer.packInt(12); + packer.packInt(1); + packer.close(); + + ObjectMapper mapper = new ObjectMapper(new MessagePackFactory()); + List objects = mapper.readValue(out.toByteArray(), new TypeReference>() {}); + assertEquals(2, objects.size()); + @SuppressWarnings(value="unchecked") + Map map = (Map) objects.get(0); + assertEquals(1, map.size()); + assertEquals(12, map.get("bar")); + assertEquals(1, objects.get(1)); + } } From b915a78941264d521d9092afa007076dddda28db Mon Sep 17 00:00:00 2001 From: Mitsunori Komatsu Date: Mon, 29 Jun 2015 14:36:56 +0900 Subject: [PATCH 110/234] Fix wrong style --- .../org/msgpack/jackson/dataformat/MessagePackParserTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackParserTest.java b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackParserTest.java index 764da9d8f..aaab700af 100644 --- a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackParserTest.java +++ b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackParserTest.java @@ -531,7 +531,7 @@ public void testBinaryKeyInNestedObject() ObjectMapper mapper = new ObjectMapper(new MessagePackFactory()); List objects = mapper.readValue(out.toByteArray(), new TypeReference>() {}); assertEquals(2, objects.size()); - @SuppressWarnings(value="unchecked") + @SuppressWarnings(value = "unchecked") Map map = (Map) objects.get(0); assertEquals(1, map.size()); assertEquals(12, map.get("bar")); From 498ab6c1273e0f1fa89400a3c3a3f86ab758d59c Mon Sep 17 00:00:00 2001 From: Mitsunori Komatsu Date: Mon, 29 Jun 2015 15:44:17 +0900 Subject: [PATCH 111/234] Fix wrong return type of MessagePackParser#getEmbeddedObject --- .../dataformat/MessagePackExtensionType.java | 29 ++++++++++--------- .../dataformat/MessagePackGenerator.java | 6 ++-- .../jackson/dataformat/MessagePackParser.java | 9 ++---- .../dataformat/MessagePackGeneratorTest.java | 5 ++-- .../dataformat/MessagePackParserTest.java | 14 ++++----- 5 files changed, 31 insertions(+), 32 deletions(-) diff --git a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackExtensionType.java b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackExtensionType.java index 7a99b1d6b..9fb9b77d7 100644 --- a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackExtensionType.java +++ b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackExtensionType.java @@ -7,32 +7,35 @@ import com.fasterxml.jackson.databind.annotation.JsonSerialize; import java.io.IOException; -import java.nio.ByteBuffer; @JsonSerialize(using = MessagePackExtensionType.Serializer.class) public class MessagePackExtensionType { - private final int extType; - private final ByteBuffer byteBuffer; + private final int type; + private final byte[] data; - public MessagePackExtensionType(int extType, ByteBuffer byteBuffer) { - this.extType = extType; - this.byteBuffer = byteBuffer.isReadOnly() ? - byteBuffer : byteBuffer.asReadOnlyBuffer(); + public MessagePackExtensionType(int extType, byte[] extData) + { + this.type = extType; + this.data = extData; } - public int extType() { - return extType; + public int getType() + { + return type; } - public ByteBuffer byteBuffer() { - return byteBuffer; + public byte[] getData() + { + return data; } - public static class Serializer extends JsonSerializer { + public static class Serializer extends JsonSerializer + { @Override public void serialize(MessagePackExtensionType value, JsonGenerator gen, SerializerProvider serializers) - throws IOException, JsonProcessingException { + throws IOException, JsonProcessingException + { if (gen instanceof MessagePackGenerator) { MessagePackGenerator msgpackGenerator = (MessagePackGenerator)gen; msgpackGenerator.writeExtendedType(value); diff --git a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackGenerator.java b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackGenerator.java index 4a7727bed..3bdf2d035 100644 --- a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackGenerator.java +++ b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackGenerator.java @@ -215,9 +215,9 @@ else if (v instanceof Boolean) { } else if (v instanceof MessagePackExtensionType) { MessagePackExtensionType extendedType = (MessagePackExtensionType) v; - ByteBuffer buf = extendedType.byteBuffer(); - messagePacker.packExtensionTypeHeader((byte)extendedType.extType(), buf.remaining()); - messagePacker.writePayload(buf); + byte[] extData = extendedType.getData(); + messagePacker.packExtensionTypeHeader((byte)extendedType.getType(), extData.length); + messagePacker.writePayload(extData); } else { throw new IllegalArgumentException(v.toString()); diff --git a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java index 9e8ab8b7f..88648c697 100644 --- a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java +++ b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java @@ -32,11 +32,7 @@ import org.msgpack.core.buffer.ArrayBufferInput; import org.msgpack.core.buffer.InputStreamBufferInput; import org.msgpack.core.buffer.MessageBufferInput; -import org.msgpack.value.IntegerValue; -import org.msgpack.value.Value; -import org.msgpack.value.ValueFactory; -import org.msgpack.value.ValueType; -import org.msgpack.value.Variable; +import org.msgpack.value.*; import java.io.IOException; import java.io.InputStream; @@ -398,7 +394,8 @@ public Object getEmbeddedObject() return value.asBinaryValue().getByteArray(); } else if (value.isExtensionValue()) { - return value.asExtensionValue(); + ExtensionValue extensionValue = value.asExtensionValue(); + return new MessagePackExtensionType(extensionValue.getType(), extensionValue.getData()); } else { throw new UnsupportedOperationException(); diff --git a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackGeneratorTest.java b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackGeneratorTest.java index 598b6f730..4c47d6cbf 100644 --- a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackGeneratorTest.java +++ b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackGeneratorTest.java @@ -76,8 +76,7 @@ public void testGeneratorShouldWriteObject() hashMap.put("childArray", childArray); // #10 byte[] hello = "hello".getBytes("UTF-8"); - ByteBuffer buffer = ByteBuffer.wrap(hello); - hashMap.put("ext", new MessagePackExtensionType(17, buffer)); + hashMap.put("ext", new MessagePackExtensionType(17, hello)); long bitmap = 0; byte[] bytes = objectMapper.writeValueAsBytes(hashMap); @@ -362,7 +361,7 @@ public void testWritePrimitiveObjectViaObjectMapper() OutputStream out = new FileOutputStream(tempFile); ObjectMapper objectMapper = new ObjectMapper(new MessagePackFactory()); - objectMapper.disable(JsonGenerator.Feature.AUTO_CLOSE_TARGET); + objectMapper.configure(JsonGenerator.Feature.AUTO_CLOSE_TARGET, false); objectMapper.writeValue(out, 1); objectMapper.writeValue(out, "two"); objectMapper.writeValue(out, 3.14); diff --git a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackParserTest.java b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackParserTest.java index aaab700af..c280fd30b 100644 --- a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackParserTest.java +++ b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackParserTest.java @@ -167,9 +167,9 @@ else if (k.equals("bool")) { else if (k.equals("ext")) { // #9 bitmap |= 1 << 10; - ExtensionValue extensionValue = (ExtensionValue) v; - assertEquals(0, extensionValue.getType()); - assertArrayEquals(extPayload, extensionValue.getData()); + MessagePackExtensionType extensionType = (MessagePackExtensionType) v; + assertEquals(0, extensionType.getType()); + assertArrayEquals(extPayload, extensionType.getData()); } } assertEquals(0x7FF, bitmap); @@ -276,9 +276,9 @@ else if (k.equals("child_map_age")) { // #10 assertEquals(true, array.get(i++)); // #11 - ExtensionValue extensionValue = (ExtensionValue) array.get(i++); - assertEquals(-1, extensionValue.getType()); - assertArrayEquals(extPayload, extensionValue.getData()); + MessagePackExtensionType extensionType = (MessagePackExtensionType) array.get(i++); + assertEquals(-1, extensionType.getType()); + assertArrayEquals(extPayload, extensionType.getData()); } @Test @@ -479,7 +479,7 @@ public void testReadPrimitiveObjectViaObjectMapper() FileInputStream in = new FileInputStream(tempFile); ObjectMapper objectMapper = new ObjectMapper(new MessagePackFactory()); - objectMapper.disable(JsonParser.Feature.AUTO_CLOSE_SOURCE); + objectMapper.configure(JsonParser.Feature.AUTO_CLOSE_SOURCE, false); assertEquals("foo", objectMapper.readValue(in, new TypeReference() {})); assertEquals(Long.MAX_VALUE, objectMapper.readValue(in, new TypeReference() {})); assertEquals(3.14, objectMapper.readValue(in, new TypeReference() {})); From 31feb4c8405b2d2ed8368431c2431c8cfd0bc5ab Mon Sep 17 00:00:00 2001 From: Mitsunori Komatsu Date: Mon, 29 Jun 2015 15:51:21 +0900 Subject: [PATCH 112/234] Change type of MessagePackExtensionType#type --- .../jackson/dataformat/MessagePackExtensionType.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackExtensionType.java b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackExtensionType.java index 9fb9b77d7..5050ee106 100644 --- a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackExtensionType.java +++ b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackExtensionType.java @@ -11,16 +11,16 @@ @JsonSerialize(using = MessagePackExtensionType.Serializer.class) public class MessagePackExtensionType { - private final int type; + private final byte type; private final byte[] data; - public MessagePackExtensionType(int extType, byte[] extData) + public MessagePackExtensionType(byte extType, byte[] extData) { this.type = extType; this.data = extData; } - public int getType() + public byte getType() { return type; } From 9235602225fc551709fec5fdf9e131c1412b06a4 Mon Sep 17 00:00:00 2001 From: Mitsunori Komatsu Date: Mon, 29 Jun 2015 15:55:15 +0900 Subject: [PATCH 113/234] Minor fixes --- .../jackson/dataformat/MessagePackExtensionType.java | 6 +++--- .../jackson/dataformat/MessagePackGeneratorTest.java | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackExtensionType.java b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackExtensionType.java index 5050ee106..abceffcb9 100644 --- a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackExtensionType.java +++ b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackExtensionType.java @@ -14,10 +14,10 @@ public class MessagePackExtensionType private final byte type; private final byte[] data; - public MessagePackExtensionType(byte extType, byte[] extData) + public MessagePackExtensionType(byte type, byte[] data) { - this.type = extType; - this.data = extData; + this.type = type; + this.data = data; } public byte getType() diff --git a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackGeneratorTest.java b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackGeneratorTest.java index 4c47d6cbf..68eaa4557 100644 --- a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackGeneratorTest.java +++ b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackGeneratorTest.java @@ -76,7 +76,7 @@ public void testGeneratorShouldWriteObject() hashMap.put("childArray", childArray); // #10 byte[] hello = "hello".getBytes("UTF-8"); - hashMap.put("ext", new MessagePackExtensionType(17, hello)); + hashMap.put("ext", new MessagePackExtensionType((byte) 17, hello)); long bitmap = 0; byte[] bytes = objectMapper.writeValueAsBytes(hashMap); From 07e81b4eee64fe40af40c362ea58aa67788829ff Mon Sep 17 00:00:00 2001 From: Frank Dinoff Date: Mon, 29 Jun 2015 21:22:58 -0400 Subject: [PATCH 114/234] Rename Extended to Extension A previous commit changed most references extended to extension since the Message Pack spec calls them Extension type. This converts a few missed references to extension. --- .../jackson/dataformat/MessagePackExtensionType.java | 4 ++-- .../jackson/dataformat/MessagePackGenerator.java | 12 +++++++----- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackExtensionType.java b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackExtensionType.java index abceffcb9..1906757f5 100644 --- a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackExtensionType.java +++ b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackExtensionType.java @@ -37,8 +37,8 @@ public void serialize(MessagePackExtensionType value, JsonGenerator gen, Seriali throws IOException, JsonProcessingException { if (gen instanceof MessagePackGenerator) { - MessagePackGenerator msgpackGenerator = (MessagePackGenerator)gen; - msgpackGenerator.writeExtendedType(value); + MessagePackGenerator msgpackGenerator = (MessagePackGenerator) gen; + msgpackGenerator.writeExtensionType(value); } else { throw new IllegalStateException("'gen' is expected to be MessagePackGenerator but it's " + gen.getClass()); diff --git a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackGenerator.java b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackGenerator.java index 3bdf2d035..9ba9a5ac3 100644 --- a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackGenerator.java +++ b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackGenerator.java @@ -214,9 +214,9 @@ else if (v instanceof Boolean) { messagePacker.packBoolean((Boolean) v); } else if (v instanceof MessagePackExtensionType) { - MessagePackExtensionType extendedType = (MessagePackExtensionType) v; - byte[] extData = extendedType.getData(); - messagePacker.packExtensionTypeHeader((byte)extendedType.getType(), extData.length); + MessagePackExtensionType extensionType = (MessagePackExtensionType) v; + byte[] extData = extensionType.getData(); + messagePacker.packExtensionTypeHeader(extensionType.getType(), extData.length); messagePacker.writePayload(extData); } else { @@ -414,8 +414,10 @@ public void writeNull() addValueToStackTop(null); } - public void writeExtendedType(MessagePackExtensionType extendedType) throws IOException { - addValueToStackTop(extendedType); + public void writeExtensionType(MessagePackExtensionType extensionType) + throws IOException + { + addValueToStackTop(extensionType); } @Override From b18aecfbe9d1eb206d259429f74862d408aecf59 Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Wed, 1 Jul 2015 00:26:15 +0900 Subject: [PATCH 115/234] #259: Rename data access methods --- .../java/org/msgpack/value/IntegerValue.java | 10 ++-- .../java/org/msgpack/value/NumberValue.java | 16 +++--- .../main/java/org/msgpack/value/RawValue.java | 12 +--- .../java/org/msgpack/value/StringValue.java | 2 +- .../main/java/org/msgpack/value/Value.java | 14 ++++- .../java/org/msgpack/value/ValueFactory.java | 12 ++-- .../main/java/org/msgpack/value/Variable.java | 56 +++++++++++-------- .../value/impl/AbstractImmutableRawValue.java | 26 ++++----- .../value/impl/ImmutableArrayValueImpl.java | 16 ++++-- .../impl/ImmutableBigIntegerValueImpl.java | 34 ++++++----- .../value/impl/ImmutableBinaryValueImpl.java | 4 +- .../value/impl/ImmutableBooleanValueImpl.java | 8 ++- .../value/impl/ImmutableDoubleValueImpl.java | 24 +++++--- .../impl/ImmutableExtensionValueImpl.java | 8 ++- .../value/impl/ImmutableLongValueImpl.java | 34 ++++++----- .../value/impl/ImmutableMapValueImpl.java | 18 ++++-- .../value/impl/ImmutableNilValueImpl.java | 6 ++ .../value/impl/ImmutableStringValueImpl.java | 4 +- .../core/example/MessagePackExample.java | 14 ++--- .../org/msgpack/core/MessagePackTest.scala | 2 +- .../scala/org/msgpack/value/ValueTest.scala | 48 ++++++++++++++++ .../jackson/dataformat/MessagePackParser.java | 34 +++++------ 22 files changed, 260 insertions(+), 142 deletions(-) diff --git a/msgpack-core/src/main/java/org/msgpack/value/IntegerValue.java b/msgpack-core/src/main/java/org/msgpack/value/IntegerValue.java index 294a0f775..51446526f 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/IntegerValue.java +++ b/msgpack-core/src/main/java/org/msgpack/value/IntegerValue.java @@ -58,31 +58,31 @@ public interface IntegerValue * * @throws MessageIntegerOverflowException If the value does not fit in the range of {@code byte} type. */ - byte getByte(); + byte asByte(); /** * Returns the value as a {@code short}, otherwise throws an exception. * * @throws MessageIntegerOverflowException If the value does not fit in the range of {@code short} type. */ - short getShort(); + short asShort(); /** * Returns the value as an {@code int}, otherwise throws an exception. * * @throws MessageIntegerOverflowException If the value does not fit in the range of {@code int} type. */ - int getInt(); + int asInt(); /** * Returns the value as a {@code long}, otherwise throws an exception. * * @throws MessageIntegerOverflowException If the value does not fit in the range of {@code long} type. */ - long getLong(); + long asLong(); /** * Returns the value as a {@code BigInteger}. */ - BigInteger getBigInteger(); + BigInteger asBigInteger(); } diff --git a/msgpack-core/src/main/java/org/msgpack/value/NumberValue.java b/msgpack-core/src/main/java/org/msgpack/value/NumberValue.java index 0a43973ab..3e5bd75e0 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/NumberValue.java +++ b/msgpack-core/src/main/java/org/msgpack/value/NumberValue.java @@ -18,7 +18,7 @@ import java.math.BigInteger; /** - * The base interface {@code NumberValue} of {@code IntegerValue} and {@code FloatValue}. + * The base interface {@code NumberValue} of {@code IntegerValue} and {@code FloatValue}. To extract primitive type values, call toXXX methods, which may lose some information by rounding or truncation. * * @see org.msgpack.value.IntegerValue * @see org.msgpack.value.FloatValue @@ -30,36 +30,36 @@ public interface NumberValue * Represent this value as a byte value, which may involve rounding or truncation of the original value. * the value. */ - byte castAsByte(); + byte toByte(); /** * Represent this value as a short value, which may involve rounding or truncation of the original value. */ - short castAsShort(); + short toShort(); /** * Represent this value as an int value, which may involve rounding or truncation of the original value. * value. */ - int castAsInt(); + int toInt(); /** * Represent this value as a long value, which may involve rounding or truncation of the original value. */ - long castAsLong(); + long toLong(); /** * Represent this value as a BigInteger, which may involve rounding or truncation of the original value. */ - BigInteger castAsBigInteger(); + BigInteger toBigInteger(); /** * Represent this value as a 32-bit float value, which may involve rounding or truncation of the original value. */ - float castAsFloat(); + float toFloat(); /** * Represent this value as a 64-bit double value, which may involve rounding or truncation of the original value. */ - double castAsDouble(); + double toDouble(); } diff --git a/msgpack-core/src/main/java/org/msgpack/value/RawValue.java b/msgpack-core/src/main/java/org/msgpack/value/RawValue.java index 6d51d1b51..da68ad40d 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/RawValue.java +++ b/msgpack-core/src/main/java/org/msgpack/value/RawValue.java @@ -33,7 +33,7 @@ public interface RawValue *

* This method copies the byte array. */ - byte[] getByteArray(); + byte[] asByteArray(); /** * Returns the value as {@code ByteBuffer}. @@ -41,7 +41,7 @@ public interface RawValue * Returned ByteBuffer is read-only. See {@code#asReadOnlyBuffer()}. * This method doesn't copy the byte array as much as possible. */ - ByteBuffer getByteBuffer(); + ByteBuffer asByteBuffer(); /** * Returns the value as {@code String}. @@ -50,12 +50,6 @@ public interface RawValue * * @throws MessageStringCodingException If this value includes invalid UTF-8 byte sequence. */ - String getString(); + String asString(); - /** - * Returns the value as {@code String}. - *

- * This method replaces an invalid UTF-8 byte sequence with U+FFFD replacement character. - */ - String stringValue(); } diff --git a/msgpack-core/src/main/java/org/msgpack/value/StringValue.java b/msgpack-core/src/main/java/org/msgpack/value/StringValue.java index da49cd8f6..9be80b62d 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/StringValue.java +++ b/msgpack-core/src/main/java/org/msgpack/value/StringValue.java @@ -20,7 +20,7 @@ *

* MessagePack's String type can represent a UTF-8 string at most 264-1 bytes. *

- * Note that the value could include invalid byte sequences. {@code getString()} method throws {@code MessageTypeStringCodingException} if the value includes invalid byte sequence. {@code stringValue()} method replaces an invalid byte sequence with U+FFFD replacement character. + * Note that the value could include invalid byte sequences. {@code asString()} method throws {@code MessageTypeStringCodingException} if the value includes invalid byte sequence. {@code toJson()} method replaces an invalid byte sequence with U+FFFD replacement character. * * @see org.msgpack.value.RawValue */ diff --git a/msgpack-core/src/main/java/org/msgpack/value/Value.java b/msgpack-core/src/main/java/org/msgpack/value/Value.java index d10d7ba48..7ab4344c8 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/Value.java +++ b/msgpack-core/src/main/java/org/msgpack/value/Value.java @@ -20,7 +20,11 @@ import java.io.IOException; /** - * Value is an implementation of MessagePack type system. + * Value is an implementation of MessagePack type system. To retrieve values from a Value object, + * You need to check its {@link ValueType} then call an appropriate asXXXValue method. + * + * + * */ public interface Value { @@ -242,4 +246,12 @@ void writeTo(MessagePacker pk) * If this value is {@code MapValue} or {@code ArrayValue}, this method check equivalence of elements recursively. */ boolean equals(Object obj); + + /** + * Returns json representation of this Value for debugging purpose. + * This output json format is subject to change in future. + * Do not write code that depends on the resulting json format. + */ + String toJson(); + } diff --git a/msgpack-core/src/main/java/org/msgpack/value/ValueFactory.java b/msgpack-core/src/main/java/org/msgpack/value/ValueFactory.java index d229e2659..b0ffc932a 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/ValueFactory.java +++ b/msgpack-core/src/main/java/org/msgpack/value/ValueFactory.java @@ -191,28 +191,32 @@ public MapValue build() return newMap(map); } - public void put(Map.Entry pair) + public MapBuilder put(Map.Entry pair) { put(pair.getKey(), pair.getValue()); + return this; } - public void put(Value key, Value value) + public MapBuilder put(Value key, Value value) { map.put(key, value); + return this; } - public void putAll(Iterable> entries) + public MapBuilder putAll(Iterable> entries) { for (Map.Entry entry : entries) { put(entry.getKey(), entry.getValue()); } + return this; } - public void putAll(Map map) + public MapBuilder putAll(Map map) { for (Map.Entry entry : map.entrySet()) { put(entry); } + return this; } } diff --git a/msgpack-core/src/main/java/org/msgpack/value/Variable.java b/msgpack-core/src/main/java/org/msgpack/value/Variable.java index 67a5325fe..3782f7dee 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/Variable.java +++ b/msgpack-core/src/main/java/org/msgpack/value/Variable.java @@ -186,10 +186,16 @@ public int hashCode() return Variable.this.hashCode(); } + @Override + public String toJson() + { + return Variable.this.toJson(); + } + @Override public String toString() { - return Variable.this.toString(); + return toJson(); } } @@ -357,7 +363,7 @@ public NumberValue asNumberValue() } @Override - public byte castAsByte() + public byte toByte() { if (type == Type.BIG_INTEGER) { return ((BigInteger) objectValue).byteValue(); @@ -366,7 +372,7 @@ public byte castAsByte() } @Override - public short castAsShort() + public short toShort() { if (type == Type.BIG_INTEGER) { return ((BigInteger) objectValue).shortValue(); @@ -375,7 +381,7 @@ public short castAsShort() } @Override - public int castAsInt() + public int toInt() { if (type == Type.BIG_INTEGER) { return ((BigInteger) objectValue).intValue(); @@ -384,7 +390,7 @@ public int castAsInt() } @Override - public long castAsLong() + public long toLong() { if (type == Type.BIG_INTEGER) { return ((BigInteger) objectValue).longValue(); @@ -393,7 +399,7 @@ public long castAsLong() } @Override - public BigInteger castAsBigInteger() + public BigInteger toBigInteger() { if (type == Type.BIG_INTEGER) { return (BigInteger) objectValue; @@ -405,7 +411,7 @@ else if (type == Type.DOUBLE) { } @Override - public float castAsFloat() + public float toFloat() { if (type == Type.BIG_INTEGER) { return ((BigInteger) objectValue).floatValue(); @@ -417,7 +423,7 @@ else if (type == Type.DOUBLE) { } @Override - public double castAsDouble() + public double toDouble() { if (type == Type.BIG_INTEGER) { return ((BigInteger) objectValue).doubleValue(); @@ -524,7 +530,7 @@ public MessageFormat mostSuccinctMessageFormat() } @Override - public byte getByte() + public byte asByte() { if (!isInByteRange()) { throw new MessageIntegerOverflowException(longValue); @@ -533,7 +539,7 @@ public byte getByte() } @Override - public short getShort() + public short asShort() { if (!isInByteRange()) { throw new MessageIntegerOverflowException(longValue); @@ -542,7 +548,7 @@ public short getShort() } @Override - public int getInt() + public int asInt() { if (!isInIntRange()) { throw new MessageIntegerOverflowException(longValue); @@ -551,7 +557,7 @@ public int getInt() } @Override - public long getLong() + public long asLong() { if (!isInLongRange()) { throw new MessageIntegerOverflowException(longValue); @@ -560,7 +566,7 @@ public long getLong() } @Override - public BigInteger getBigInteger() + public BigInteger asBigInteger() { if (type == Type.BIG_INTEGER) { return (BigInteger) objectValue; @@ -592,7 +598,7 @@ public Variable setFloatValue(double v) this.type = Type.DOUBLE; this.accessor = floatAccessor; this.doubleValue = v; - this.longValue = (long) v; // AbstractNumberValueAccessor uses castAsLong + this.longValue = (long) v; // AbstractNumberValueAccessor uses toLong return this; } @@ -600,7 +606,7 @@ public Variable setFloatValue(float v) { this.type = Type.DOUBLE; this.accessor = floatAccessor; - this.longValue = (long) v; // AbstractNumberValueAccessor uses castAsLong + this.longValue = (long) v; // AbstractNumberValueAccessor uses toLong return this; } @@ -651,19 +657,19 @@ public RawValue asRawValue() } @Override - public byte[] getByteArray() + public byte[] asByteArray() { return (byte[]) objectValue; } @Override - public ByteBuffer getByteBuffer() + public ByteBuffer asByteBuffer() { - return ByteBuffer.wrap(getByteArray()); + return ByteBuffer.wrap(asByteArray()); } @Override - public String getString() + public String asString() { byte[] raw = (byte[]) objectValue; try { @@ -678,7 +684,7 @@ public String getString() } @Override - public String stringValue() + public String toJson() { byte[] raw = (byte[]) objectValue; try { @@ -724,7 +730,7 @@ public BinaryValue asBinaryValue() @Override public ImmutableBinaryValue immutableValue() { - return ValueFactory.newBinary(getByteArray()); + return ValueFactory.newBinary(asByteArray()); } @Override @@ -1044,11 +1050,17 @@ public boolean equals(Object o) } @Override - public String toString() + public String toJson() { return immutableValue().toString(); // TODO optimize } + @Override + public String toString() + { + return toJson(); + } + @Override public ValueType getValueType() { diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/AbstractImmutableRawValue.java b/msgpack-core/src/main/java/org/msgpack/value/impl/AbstractImmutableRawValue.java index d558234cf..13b4764f1 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/impl/AbstractImmutableRawValue.java +++ b/msgpack-core/src/main/java/org/msgpack/value/impl/AbstractImmutableRawValue.java @@ -51,19 +51,19 @@ public ImmutableRawValue asRawValue() } @Override - public byte[] getByteArray() + public byte[] asByteArray() { return Arrays.copyOf(data, data.length); } @Override - public ByteBuffer getByteBuffer() + public ByteBuffer asByteBuffer() { return ByteBuffer.wrap(data).asReadOnlyBuffer(); } @Override - public String getString() + public String asString() { if (decodedStringCache == null) { decodeString(); @@ -77,12 +77,9 @@ public String getString() } @Override - public String stringValue() + public String toJson() { - if (decodedStringCache == null) { - decodeString(); - } - return decodedStringCache; + return toJson(new StringBuilder()).toString(); } private void decodeString() @@ -95,14 +92,14 @@ private void decodeString() CharsetDecoder reportDecoder = MessagePack.UTF8.newDecoder() .onMalformedInput(CodingErrorAction.REPORT) .onUnmappableCharacter(CodingErrorAction.REPORT); - this.decodedStringCache = reportDecoder.decode(getByteBuffer()).toString(); + this.decodedStringCache = reportDecoder.decode(asByteBuffer()).toString(); } catch (CharacterCodingException ex) { try { CharsetDecoder replaceDecoder = MessagePack.UTF8.newDecoder() .onMalformedInput(CodingErrorAction.REPLACE) .onUnmappableCharacter(CodingErrorAction.REPLACE); - this.decodedStringCache = replaceDecoder.decode(getByteBuffer()).toString(); + this.decodedStringCache = replaceDecoder.decode(asByteBuffer()).toString(); } catch (CharacterCodingException neverThrown) { throw new MessageStringCodingException(neverThrown); @@ -115,12 +112,15 @@ private void decodeString() @Override public String toString() { - return toString(new StringBuilder()).toString(); + if (decodedStringCache == null) { + decodeString(); + } + return decodedStringCache; } - private StringBuilder toString(StringBuilder sb) + private StringBuilder toJson(StringBuilder sb) { - String s = stringValue(); + String s = toString(); sb.append("\""); for (int i = 0; i < s.length(); i++) { char ch = s.charAt(i); diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableArrayValueImpl.java b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableArrayValueImpl.java index a62e7cc64..093c5a0f5 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableArrayValueImpl.java +++ b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableArrayValueImpl.java @@ -159,26 +159,32 @@ public int hashCode() } @Override - public String toString() + public String toJson() { - return toString(new StringBuilder()).toString(); + return toJson(new StringBuilder()).toString(); } - private StringBuilder toString(StringBuilder sb) + private StringBuilder toJson(StringBuilder sb) { if (array.length == 0) { return sb.append("[]"); } sb.append("["); - sb.append(array[0]); + sb.append(array[0].toJson()); for (int i = 1; i < array.length; i++) { sb.append(","); - sb.append(array[i].toString()); + sb.append(array[i].toJson()); } sb.append("]"); return sb; } + @Override + public String toString() + { + return toJson(); + } + private static class ImmutableArrayValueList extends AbstractList { diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableBigIntegerValueImpl.java b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableBigIntegerValueImpl.java index ef1de0966..b1c7c0b10 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableBigIntegerValueImpl.java +++ b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableBigIntegerValueImpl.java @@ -97,43 +97,43 @@ public ImmutableIntegerValue asIntegerValue() } @Override - public byte castAsByte() + public byte toByte() { return value.byteValue(); } @Override - public short castAsShort() + public short toShort() { return value.shortValue(); } @Override - public int castAsInt() + public int toInt() { return value.intValue(); } @Override - public long castAsLong() + public long toLong() { return value.longValue(); } @Override - public BigInteger castAsBigInteger() + public BigInteger toBigInteger() { return value; } @Override - public float castAsFloat() + public float toFloat() { return value.floatValue(); } @Override - public double castAsDouble() + public double toDouble() { return value.doubleValue(); } @@ -169,7 +169,7 @@ public MessageFormat mostSuccinctMessageFormat() } @Override - public byte getByte() + public byte asByte() { if (!isInByteRange()) { throw new MessageIntegerOverflowException(value); @@ -178,7 +178,7 @@ public byte getByte() } @Override - public short getShort() + public short asShort() { if (!isInShortRange()) { throw new MessageIntegerOverflowException(value); @@ -187,7 +187,7 @@ public short getShort() } @Override - public int getInt() + public int asInt() { if (!isInIntRange()) { throw new MessageIntegerOverflowException(value); @@ -196,7 +196,7 @@ public int getInt() } @Override - public long getLong() + public long asLong() { if (!isInLongRange()) { throw new MessageIntegerOverflowException(value); @@ -205,7 +205,7 @@ public long getLong() } @Override - public BigInteger getBigInteger() + public BigInteger asBigInteger() { return value; } @@ -232,7 +232,7 @@ public boolean equals(Object o) return false; } IntegerValue iv = v.asIntegerValue(); - return value.equals(iv.castAsBigInteger()); + return value.equals(iv.toBigInteger()); } @Override @@ -250,8 +250,14 @@ else if (LONG_MIN.compareTo(value) <= 0 } @Override - public String toString() + public String toJson() { return value.toString(); } + + @Override + public String toString() + { + return toJson(); + } } diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableBinaryValueImpl.java b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableBinaryValueImpl.java index 41bbb8659..ca5ccfae0 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableBinaryValueImpl.java +++ b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableBinaryValueImpl.java @@ -25,7 +25,7 @@ /** * {@code ImmutableBinaryValueImpl} Implements {@code ImmutableBinaryValue} using a {@code byte[]} field. - * This implementation caches result of {@code stringValue()} and {@code getString()} using a private {@code String} field. + * This implementation caches result of {@code toJson()} and {@code asString()} using a private {@code String} field. * * @see org.msgpack.value.StringValue */ @@ -83,7 +83,7 @@ public boolean equals(Object o) return Arrays.equals(data, bv.data); } else { - return Arrays.equals(data, v.asBinaryValue().getByteArray()); + return Arrays.equals(data, v.asBinaryValue().asByteArray()); } } diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableBooleanValueImpl.java b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableBooleanValueImpl.java index 9bd11bdf9..5d15698a7 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableBooleanValueImpl.java +++ b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableBooleanValueImpl.java @@ -97,8 +97,14 @@ public int hashCode() } @Override - public String toString() + public String toJson() { return Boolean.toString(value); } + + @Override + public String toString() + { + return toJson(); + } } diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableDoubleValueImpl.java b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableDoubleValueImpl.java index a69afe242..5cc9b66f7 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableDoubleValueImpl.java +++ b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableDoubleValueImpl.java @@ -53,43 +53,43 @@ public ImmutableDoubleValueImpl immutableValue() } @Override - public byte castAsByte() + public byte toByte() { return (byte) value; } @Override - public short castAsShort() + public short toShort() { return (short) value; } @Override - public int castAsInt() + public int toInt() { return (int) value; } @Override - public long castAsLong() + public long toLong() { return (long) value; } @Override - public BigInteger castAsBigInteger() + public BigInteger toBigInteger() { return new BigDecimal(value).toBigInteger(); } @Override - public float castAsFloat() + public float toFloat() { return (float) value; } @Override - public double castAsDouble() + public double toDouble() { return value; } @@ -115,7 +115,7 @@ public boolean equals(Object o) if (!v.isFloatValue()) { return false; } - return value == v.asFloatValue().castAsDouble(); + return value == v.asFloatValue().toDouble(); } @Override @@ -126,8 +126,14 @@ public int hashCode() } @Override - public String toString() + public String toJson() { return Double.toString(value); } + + @Override + public String toString() + { + return toJson(); + } } diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableExtensionValueImpl.java b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableExtensionValueImpl.java index b37de8139..c7659a477 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableExtensionValueImpl.java +++ b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableExtensionValueImpl.java @@ -109,7 +109,7 @@ public int hashCode() } @Override - public String toString() + public String toJson() { StringBuilder sb = new StringBuilder(); sb.append('('); @@ -121,4 +121,10 @@ public String toString() sb.append(")"); return sb.toString(); } + + @Override + public String toString() + { + return toJson(); + } } diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableLongValueImpl.java b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableLongValueImpl.java index 350e01cc5..c83bda332 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableLongValueImpl.java +++ b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableLongValueImpl.java @@ -75,43 +75,43 @@ public ImmutableIntegerValue asIntegerValue() } @Override - public byte castAsByte() + public byte toByte() { return (byte) value; } @Override - public short castAsShort() + public short toShort() { return (short) value; } @Override - public int castAsInt() + public int toInt() { return (int) value; } @Override - public long castAsLong() + public long toLong() { return value; } @Override - public BigInteger castAsBigInteger() + public BigInteger toBigInteger() { return BigInteger.valueOf(value); } @Override - public float castAsFloat() + public float toFloat() { return (float) value; } @Override - public double castAsDouble() + public double toDouble() { return (double) value; } @@ -147,7 +147,7 @@ public MessageFormat mostSuccinctMessageFormat() } @Override - public byte getByte() + public byte asByte() { if (!isInByteRange()) { throw new MessageIntegerOverflowException(value); @@ -156,7 +156,7 @@ public byte getByte() } @Override - public short getShort() + public short asShort() { if (!isInByteRange()) { throw new MessageIntegerOverflowException(value); @@ -165,7 +165,7 @@ public short getShort() } @Override - public int getInt() + public int asInt() { if (!isInIntRange()) { throw new MessageIntegerOverflowException(value); @@ -174,13 +174,13 @@ public int getInt() } @Override - public long getLong() + public long asLong() { return value; } @Override - public BigInteger getBigInteger() + public BigInteger asBigInteger() { return BigInteger.valueOf((long) value); } @@ -210,7 +210,7 @@ public boolean equals(Object o) if (!iv.isInLongRange()) { return false; } - return value == iv.castAsLong(); + return value == iv.toLong(); } @Override @@ -225,8 +225,14 @@ public int hashCode() } @Override - public String toString() + public String toJson() { return Long.toString(value); } + + @Override + public String toString() + { + return toJson(); + } } diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableMapValueImpl.java b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableMapValueImpl.java index b9a0a6f5c..ede45d170 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableMapValueImpl.java +++ b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableMapValueImpl.java @@ -150,23 +150,29 @@ public int hashCode() @Override public String toString() { - return toString(new StringBuilder()).toString(); + return toJson(); } - private StringBuilder toString(StringBuilder sb) + @Override + public String toJson() + { + return toJson(new StringBuilder()).toString(); + } + + private StringBuilder toJson(StringBuilder sb) { if (kvs.length == 0) { return sb.append("{}"); } sb.append("{"); - sb.append(kvs[0]); + sb.append(kvs[0].toJson()); sb.append(":"); - sb.append(kvs[1]); + sb.append(kvs[1].toJson()); for (int i = 2; i < kvs.length; i += 2) { sb.append(","); - sb.append(kvs[i].toString()); + sb.append(kvs[i].toJson()); sb.append(":"); - sb.append(kvs[i + 1].toString()); + sb.append(kvs[i + 1].toJson()); } sb.append("}"); return sb; diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableNilValueImpl.java b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableNilValueImpl.java index dab10b54f..141e2ce1a 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableNilValueImpl.java +++ b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableNilValueImpl.java @@ -89,6 +89,12 @@ public int hashCode() @Override public String toString() + { + return toJson(); + } + + @Override + public String toJson() { return "null"; } diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableStringValueImpl.java b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableStringValueImpl.java index e40139979..ab26c72d4 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableStringValueImpl.java +++ b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableStringValueImpl.java @@ -25,7 +25,7 @@ /** * {@code ImmutableStringValueImpl} Implements {@code ImmutableStringValue} using a {@code byte[]} field. - * This implementation caches result of {@code stringValue()} and {@code getString()} using a private {@code String} field. + * This implementation caches result of {@code toJson()} and {@code asString()} using a private {@code String} field. * * @see org.msgpack.value.StringValue */ @@ -88,7 +88,7 @@ public boolean equals(Object o) return Arrays.equals(data, bv.data); } else { - return Arrays.equals(data, v.asStringValue().getByteArray()); + return Arrays.equals(data, v.asStringValue().asByteArray()); } } diff --git a/msgpack-core/src/test/java/org/msgpack/core/example/MessagePackExample.java b/msgpack-core/src/test/java/org/msgpack/core/example/MessagePackExample.java index e0ea34679..a74c5cd18 100644 --- a/msgpack-core/src/test/java/org/msgpack/core/example/MessagePackExample.java +++ b/msgpack-core/src/test/java/org/msgpack/core/example/MessagePackExample.java @@ -201,30 +201,30 @@ public static void readAndWriteFile() case INTEGER: IntegerValue iv = v.asIntegerValue(); if (iv.isInIntRange()) { - int i = iv.castAsInt(); + int i = iv.toInt(); System.out.println("read int: " + i); } else if (iv.isInLongRange()) { - long l = iv.castAsLong(); + long l = iv.toLong(); System.out.println("read long: " + l); } else { - BigInteger i = iv.castAsBigInteger(); + BigInteger i = iv.toBigInteger(); System.out.println("read long: " + i); } break; case FLOAT: FloatValue fv = v.asFloatValue(); - float f = fv.castAsFloat(); // use as float - double d = fv.castAsDouble(); // use as double + float f = fv.toFloat(); // use as float + double d = fv.toDouble(); // use as double System.out.println("read float: " + d); break; case STRING: - String s = v.asStringValue().getString(); + String s = v.asStringValue().asString(); System.out.println("read string: " + s); break; case BINARY: - byte[] mb = v.asBinaryValue().getByteArray(); + byte[] mb = v.asBinaryValue().asByteArray(); System.out.println("read binary: size=" + mb.length); break; case ARRAY: diff --git a/msgpack-core/src/test/scala/org/msgpack/core/MessagePackTest.scala b/msgpack-core/src/test/scala/org/msgpack/core/MessagePackTest.scala index 7d87b02a7..62bf8ae82 100644 --- a/msgpack-core/src/test/scala/org/msgpack/core/MessagePackTest.scala +++ b/msgpack-core/src/test/scala/org/msgpack/core/MessagePackTest.scala @@ -462,7 +462,7 @@ class MessagePackTest extends MessagePackSpec { val k = kvp(0) val v = kvp(1) - (k.asStringValue().getString, v.asStringValue().getString) + (k.asStringValue().asString, v.asStringValue().asString) }).toMap }.toList }) diff --git a/msgpack-core/src/test/scala/org/msgpack/value/ValueTest.scala b/msgpack-core/src/test/scala/org/msgpack/value/ValueTest.scala index a89dcb880..e21c387fb 100644 --- a/msgpack-core/src/test/scala/org/msgpack/value/ValueTest.scala +++ b/msgpack-core/src/test/scala/org/msgpack/value/ValueTest.scala @@ -19,6 +19,8 @@ import java.math.BigInteger import org.msgpack.core._ +import scala.util.parsing.json.JSON + class ValueTest extends MessagePackSpec { def checkSuccinctType(pack:MessagePacker => Unit, expectedAtMost:MessageFormat) { @@ -49,5 +51,51 @@ class ValueTest extends MessagePackSpec } } } + + "produce json strings" in { + + import ValueFactory._ + + newNil().toJson shouldBe "null" + newNil().toString shouldBe "null" + + newBoolean(true).toJson shouldBe "true" + newBoolean(false).toJson shouldBe "false" + newBoolean(true).toString shouldBe "true" + newBoolean(false).toString shouldBe "false" + + newInteger(3).toJson shouldBe "3" + newInteger(3).toString shouldBe "3" + newInteger(BigInteger.valueOf(1324134134134L)).toJson shouldBe "1324134134134" + newInteger(BigInteger.valueOf(1324134134134L)).toString shouldBe "1324134134134" + + newFloat(0.1).toJson shouldBe "0.1" + newFloat(0.1).toString shouldBe "0.1" + + newArray(newInteger(0), newString("hello")).toJson shouldBe "[0,\"hello\"]" + newArray(newInteger(0), newString("hello")).toString shouldBe "[0,\"hello\"]" + newArray(newArray(newString("Apple"), newFloat(0.2)), newNil()).toJson shouldBe """[["Apple",0.2],null]""" + + // Map value + val m = newMapBuilder() + .put(newString("id"), newInteger(1001)) + .put(newString("name"), newString("leo")) + .put(newString("address"), newArray(newString("xxx-xxxx"), newString("yyy-yyyy"))) + .put(newString("name"), newString("mitsu")) + .build() + val i1 = JSON.parseFull(m.toJson) + val i2 = JSON.parseFull(m.toString) // expect json value + val a1 = JSON.parseFull("""{"id":1001,"name":"mitsu","address":["xxx-xxxx","yyy-yyyy"]}""") + // Equals as JSON map + i1 shouldBe a1 + i2 shouldBe a1 + + // toJson should quote strings + newString("1").toJson shouldBe "\"1\"" + // toString is for extracting string values + newString("1").toString shouldBe "1" + + } + } } diff --git a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java index 88648c697..e41d45735 100644 --- a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java +++ b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java @@ -202,7 +202,7 @@ public JsonToken nextToken() case STRING: value = messageUnpacker.unpackValue(var); if (parsingContext.inObject() && _currToken != JsonToken.FIELD_NAME) { - parsingContext.setCurrentName(value.asRawValue().stringValue()); + parsingContext.setCurrentName(value.asRawValue().toJson()); nextToken = JsonToken.FIELD_NAME; } else { @@ -212,7 +212,7 @@ public JsonToken nextToken() case BINARY: value = messageUnpacker.unpackValue(var); if (parsingContext.inObject() && _currToken != JsonToken.FIELD_NAME) { - parsingContext.setCurrentName(value.asRawValue().stringValue()); + parsingContext.setCurrentName(value.asRawValue().toJson()); nextToken = JsonToken.FIELD_NAME; } else { @@ -267,7 +267,7 @@ public String getText() { // This method can be called for new BigInteger(text) if (value.isRawValue()) { - return value.asRawValue().stringValue(); + return value.asRawValue().toJson(); } else { return value.toString(); @@ -305,7 +305,7 @@ public int getTextOffset() public byte[] getBinaryValue(Base64Variant b64variant) throws IOException, JsonParseException { - return value.asRawValue().getByteArray(); + return value.asRawValue().asByteArray(); } @Override @@ -315,17 +315,17 @@ public Number getNumberValue() if (value.isIntegerValue()) { IntegerValue integerValue = value.asIntegerValue(); if (integerValue.isInIntRange()) { - return integerValue.castAsInt(); + return integerValue.toInt(); } else if (integerValue.isInLongRange()) { - return integerValue.castAsLong(); + return integerValue.toLong(); } else { - return integerValue.castAsBigInteger(); + return integerValue.toBigInteger(); } } else { - return value.asNumberValue().castAsDouble(); + return value.asNumberValue().toDouble(); } } @@ -333,35 +333,35 @@ else if (integerValue.isInLongRange()) { public int getIntValue() throws IOException, JsonParseException { - return value.asNumberValue().castAsInt(); + return value.asNumberValue().toInt(); } @Override public long getLongValue() throws IOException, JsonParseException { - return value.asNumberValue().castAsLong(); + return value.asNumberValue().toLong(); } @Override public BigInteger getBigIntegerValue() throws IOException, JsonParseException { - return value.asNumberValue().castAsBigInteger(); + return value.asNumberValue().toBigInteger(); } @Override public float getFloatValue() throws IOException, JsonParseException { - return value.asNumberValue().castAsFloat(); + return value.asNumberValue().toFloat(); } @Override public double getDoubleValue() throws IOException, JsonParseException { - return value.asNumberValue().castAsDouble(); + return value.asNumberValue().toDouble(); } @Override @@ -372,14 +372,14 @@ public BigDecimal getDecimalValue() IntegerValue number = value.asIntegerValue(); //optimization to not convert the value to BigInteger unnecessarily if (number.isInLongRange()) { - return BigDecimal.valueOf(number.castAsLong()); + return BigDecimal.valueOf(number.toLong()); } else { - return new BigDecimal(number.castAsBigInteger()); + return new BigDecimal(number.toBigInteger()); } } else if (value.isFloatValue()) { - return BigDecimal.valueOf(value.asFloatValue().castAsDouble()); + return BigDecimal.valueOf(value.asFloatValue().toDouble()); } else { throw new UnsupportedOperationException("Couldn't parse value as BigDecimal. " + value); @@ -391,7 +391,7 @@ public Object getEmbeddedObject() throws IOException, JsonParseException { if (value.isBinaryValue()) { - return value.asBinaryValue().getByteArray(); + return value.asBinaryValue().asByteArray(); } else if (value.isExtensionValue()) { ExtensionValue extensionValue = value.asExtensionValue(); From 31d2fe8f12f21cb53a07308164270c3f76eaa5a3 Mon Sep 17 00:00:00 2001 From: Sadayuki Furuhashi Date: Tue, 30 Jun 2015 18:57:18 -0700 Subject: [PATCH 116/234] Fix Value#toJson Value#toJson() is expected to return a valid json since its name. Some valid MessagePack values are invalid in JSON such as ExtensionValue, non-string keys in a MapValue, NaN or Infinite. --- .../java/org/msgpack/value/ArrayValue.java | 2 +- .../java/org/msgpack/value/BinaryValue.java | 2 +- .../java/org/msgpack/value/BooleanValue.java | 2 +- .../org/msgpack/value/ExtensionValue.java | 4 +- .../java/org/msgpack/value/FloatValue.java | 2 +- .../java/org/msgpack/value/IntegerValue.java | 2 +- .../main/java/org/msgpack/value/MapValue.java | 6 +- .../main/java/org/msgpack/value/RawValue.java | 12 +++- .../java/org/msgpack/value/StringValue.java | 4 +- .../main/java/org/msgpack/value/Value.java | 63 ++++++++++--------- .../main/java/org/msgpack/value/Variable.java | 9 +-- .../value/impl/AbstractImmutableRawValue.java | 15 +++-- .../value/impl/ImmutableArrayValueImpl.java | 32 +++++++--- .../value/impl/ImmutableBinaryValueImpl.java | 2 +- .../value/impl/ImmutableBooleanValueImpl.java | 2 +- .../value/impl/ImmutableDoubleValueImpl.java | 8 ++- .../impl/ImmutableExtensionValueImpl.java | 16 +++-- .../value/impl/ImmutableMapValueImpl.java | 53 ++++++++++++---- .../value/impl/ImmutableNilValueImpl.java | 2 +- .../value/impl/ImmutableStringValueImpl.java | 2 +- 20 files changed, 154 insertions(+), 86 deletions(-) diff --git a/msgpack-core/src/main/java/org/msgpack/value/ArrayValue.java b/msgpack-core/src/main/java/org/msgpack/value/ArrayValue.java index 53fa77099..4d7a6e8c2 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/ArrayValue.java +++ b/msgpack-core/src/main/java/org/msgpack/value/ArrayValue.java @@ -20,7 +20,7 @@ /** * The interface {@code ArrayValue} represents MessagePack's Array type. - *

+ * * MessagePack's Array type can represent sequence of values. */ public interface ArrayValue diff --git a/msgpack-core/src/main/java/org/msgpack/value/BinaryValue.java b/msgpack-core/src/main/java/org/msgpack/value/BinaryValue.java index b0c636d9c..c66f7a67c 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/BinaryValue.java +++ b/msgpack-core/src/main/java/org/msgpack/value/BinaryValue.java @@ -17,7 +17,7 @@ /** * The interface {@code BinaryValue} represents MessagePack's Binary type. - *

+ * * MessagePack's Binary type can represent a byte array at most 264-1 bytes. * * @see org.msgpack.value.RawValue diff --git a/msgpack-core/src/main/java/org/msgpack/value/BooleanValue.java b/msgpack-core/src/main/java/org/msgpack/value/BooleanValue.java index f81353907..6ccf5c9ef 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/BooleanValue.java +++ b/msgpack-core/src/main/java/org/msgpack/value/BooleanValue.java @@ -17,7 +17,7 @@ /** * The interface {@code BooleanValue} represents MessagePack's Boolean type. - *

+ * * MessagePack's Boolean type can represent {@code true} or {@code false}. */ public interface BooleanValue diff --git a/msgpack-core/src/main/java/org/msgpack/value/ExtensionValue.java b/msgpack-core/src/main/java/org/msgpack/value/ExtensionValue.java index 43a5e5c08..5a076ecbc 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/ExtensionValue.java +++ b/msgpack-core/src/main/java/org/msgpack/value/ExtensionValue.java @@ -17,10 +17,10 @@ /** * The interface {@code ExtensionValue} represents MessagePack's Extension type. - *

+ * * MessagePack's Extension type can represent represents a tuple of type information and a byte array where type information is an * integer whose meaning is defined by applications. - *

+ * * As the type information, applications can use 0 to 127 as the application-specific types. -1 to -128 is reserved for MessagePack's future extension. */ public interface ExtensionValue diff --git a/msgpack-core/src/main/java/org/msgpack/value/FloatValue.java b/msgpack-core/src/main/java/org/msgpack/value/FloatValue.java index 306a609fd..dbaf73a18 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/FloatValue.java +++ b/msgpack-core/src/main/java/org/msgpack/value/FloatValue.java @@ -17,7 +17,7 @@ /** * The interface {@code FloatValue} represents MessagePack's Float type. - *

+ * * MessagePack's Float type can represent IEEE 754 double precision floating point numbers including NaN and infinity. This is same with Java's {@code double} type. * * @see org.msgpack.value.NumberValue diff --git a/msgpack-core/src/main/java/org/msgpack/value/IntegerValue.java b/msgpack-core/src/main/java/org/msgpack/value/IntegerValue.java index 51446526f..8480751c4 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/IntegerValue.java +++ b/msgpack-core/src/main/java/org/msgpack/value/IntegerValue.java @@ -21,7 +21,7 @@ /** * The interface {@code IntegerValue} represents MessagePack's Integer type. - *

+ * * MessagePack's Integer type can represent from -263 to 264-1. */ public interface IntegerValue diff --git a/msgpack-core/src/main/java/org/msgpack/value/MapValue.java b/msgpack-core/src/main/java/org/msgpack/value/MapValue.java index f34e77c60..fa7f55c8d 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/MapValue.java +++ b/msgpack-core/src/main/java/org/msgpack/value/MapValue.java @@ -21,7 +21,7 @@ /** * The interface {@code ArrayValue} represents MessagePack's Map type. - *

+ * * MessagePack's Map type can represent sequence of key-value pairs. */ public interface MapValue @@ -45,9 +45,9 @@ public interface MapValue /** * Returns the key-value pairs as an array of {@code Value}. - *

+ * * Odd elements are keys. Next element of an odd element is a value corresponding to the key. - *

+ * * For example, if this value represents {"k1": "v1", "k2": "v2"}, this method returns ["k1", "v1", "k2", "v2"]. */ Value[] getKeyValueArray(); diff --git a/msgpack-core/src/main/java/org/msgpack/value/RawValue.java b/msgpack-core/src/main/java/org/msgpack/value/RawValue.java index da68ad40d..8857b5340 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/RawValue.java +++ b/msgpack-core/src/main/java/org/msgpack/value/RawValue.java @@ -30,14 +30,14 @@ public interface RawValue { /** * Returns the value as {@code byte[]}. - *

+ * * This method copies the byte array. */ byte[] asByteArray(); /** * Returns the value as {@code ByteBuffer}. - *

+ * * Returned ByteBuffer is read-only. See {@code#asReadOnlyBuffer()}. * This method doesn't copy the byte array as much as possible. */ @@ -45,11 +45,17 @@ public interface RawValue /** * Returns the value as {@code String}. - *

+ * * This method throws an exception if the value includes invalid UTF-8 byte sequence. * * @throws MessageStringCodingException If this value includes invalid UTF-8 byte sequence. */ String asString(); + /** + * Returns the value as {@code String}. + * + * This method replaces an invalid UTF-8 byte sequence with U+FFFD replacement character. + */ + String toString(); } diff --git a/msgpack-core/src/main/java/org/msgpack/value/StringValue.java b/msgpack-core/src/main/java/org/msgpack/value/StringValue.java index 9be80b62d..0c812d58d 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/StringValue.java +++ b/msgpack-core/src/main/java/org/msgpack/value/StringValue.java @@ -17,9 +17,9 @@ /** * The interface {@code StringValue} represents MessagePack's String type. - *

+ * * MessagePack's String type can represent a UTF-8 string at most 264-1 bytes. - *

+ * * Note that the value could include invalid byte sequences. {@code asString()} method throws {@code MessageTypeStringCodingException} if the value includes invalid byte sequence. {@code toJson()} method replaces an invalid byte sequence with U+FFFD replacement character. * * @see org.msgpack.value.RawValue diff --git a/msgpack-core/src/main/java/org/msgpack/value/Value.java b/msgpack-core/src/main/java/org/msgpack/value/Value.java index 7ab4344c8..2fae838b4 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/Value.java +++ b/msgpack-core/src/main/java/org/msgpack/value/Value.java @@ -30,21 +30,21 @@ public interface Value { /** * Returns type of this value. - *

+ * * Note that you can't use instanceof to check type of a value because type of a mutable value is variable. */ ValueType getValueType(); /** * Returns immutable copy of this value. - *

+ * * This method simply returns this without copying the value if this value is already immutable. */ ImmutableValue immutableValue(); /** * Returns true if type of this value is Nil. - *

+ * * If this method returns true, {@code asNilValue} never throws exceptions. * Note that you can't use instanceof or cast ((NilValue) thisValue) to check type of a value because type of a mutable value is variable. */ @@ -52,7 +52,7 @@ public interface Value /** * Returns true if type of this value is Boolean. - *

+ * * If this method returns true, {@code asBooleanValue} never throws exceptions. * Note that you can't use instanceof or cast ((BooleanValue) thisValue) to check type of a value because type of a mutable value is variable. */ @@ -60,7 +60,7 @@ public interface Value /** * Returns true if type of this value is Integer or Float. - *

+ * * If this method returns true, {@code asNumberValue} never throws exceptions. * Note that you can't use instanceof or cast ((NumberValue) thisValue) to check type of a value because type of a mutable value is variable. */ @@ -68,7 +68,7 @@ public interface Value /** * Returns true if type of this value is Integer. - *

+ * * If this method returns true, {@code asIntegerValue} never throws exceptions. * Note that you can't use instanceof or cast ((IntegerValue) thisValue) to check type of a value because type of a mutable value is variable. */ @@ -76,7 +76,7 @@ public interface Value /** * Returns true if type of this value is Float. - *

+ * * If this method returns true, {@code asFloatValue} never throws exceptions. * Note that you can't use instanceof or cast ((FloatValue) thisValue) to check type of a value because type of a mutable value is variable. */ @@ -84,7 +84,7 @@ public interface Value /** * Returns true if type of this value is String or Binary. - *

+ * * If this method returns true, {@code asRawValue} never throws exceptions. * Note that you can't use instanceof or cast ((RawValue) thisValue) to check type of a value because type of a mutable value is variable. */ @@ -92,7 +92,7 @@ public interface Value /** * Returns true if type of this value is Binary. - *

+ * * If this method returns true, {@code asBinaryValue} never throws exceptions. * Note that you can't use instanceof or cast ((BinaryValue) thisValue) to check type of a value because type of a mutable value is variable. */ @@ -100,7 +100,7 @@ public interface Value /** * Returns true if type of this value is String. - *

+ * * If this method returns true, {@code asStringValue} never throws exceptions. * Note that you can't use instanceof or cast ((StringValue) thisValue) to check type of a value because type of a mutable value is variable. */ @@ -108,7 +108,7 @@ public interface Value /** * Returns true if type of this value is Array. - *

+ * * If this method returns true, {@code asArrayValue} never throws exceptions. * Note that you can't use instanceof or cast ((ArrayValue) thisValue) to check type of a value because type of a mutable value is variable. */ @@ -116,7 +116,7 @@ public interface Value /** * Returns true if type of this value is Map. - *

+ * * If this method returns true, {@code asMapValue} never throws exceptions. * Note that you can't use instanceof or cast ((MapValue) thisValue) to check type of a value because type of a mutable value is variable. */ @@ -124,7 +124,7 @@ public interface Value /** * Returns true if type of this an Extension. - *

+ * * If this method returns true, {@code asExtensionValue} never throws exceptions. * Note that you can't use instanceof or cast ((ExtensionValue) thisValue) to check type of a value because * type of a mutable value is variable. @@ -133,7 +133,7 @@ public interface Value /** * Returns the value as {@code NilValue}. Otherwise throws {@code MessageTypeCastException}. - *

+ * * Note that you can't use instanceof or cast ((NilValue) thisValue) to check type of a value because type of a mutable value is variable. * * @throws MessageTypeCastException If type of this value is not Nil. @@ -142,7 +142,7 @@ public interface Value /** * Returns the value as {@code BooleanValue}. Otherwise throws {@code MessageTypeCastException}. - *

+ * * Note that you can't use instanceof or cast ((BooleanValue) thisValue) to check type of a value because type of a mutable value is variable. * * @throws MessageTypeCastException If type of this value is not Boolean. @@ -151,7 +151,7 @@ public interface Value /** * Returns the value as {@code NumberValue}. Otherwise throws {@code MessageTypeCastException}. - *

+ * * Note that you can't use instanceof or cast ((NumberValue) thisValue) to check type of a value because type of a mutable value is variable. * * @throws MessageTypeCastException If type of this value is not Integer or Float. @@ -160,7 +160,7 @@ public interface Value /** * Returns the value as {@code IntegerValue}. Otherwise throws {@code MessageTypeCastException}. - *

+ * * Note that you can't use instanceof or cast ((IntegerValue) thisValue) to check type of a value because type of a mutable value is variable. * * @throws MessageTypeCastException If type of this value is not Integer. @@ -169,7 +169,7 @@ public interface Value /** * Returns the value as {@code FloatValue}. Otherwise throws {@code MessageTypeCastException}. - *

+ * * Note that you can't use instanceof or cast ((FloatValue) thisValue) to check type of a value because type of a mutable value is variable. * * @throws MessageTypeCastException If type of this value is not Float. @@ -178,7 +178,7 @@ public interface Value /** * Returns the value as {@code RawValue}. Otherwise throws {@code MessageTypeCastException}. - *

+ * * Note that you can't use instanceof or cast ((RawValue) thisValue) to check type of a value because type of a mutable value is variable. * * @throws MessageTypeCastException If type of this value is not Binary or String. @@ -187,7 +187,7 @@ public interface Value /** * Returns the value as {@code BinaryValue}. Otherwise throws {@code MessageTypeCastException}. - *

+ * * Note that you can't use instanceof or cast ((BinaryValue) thisValue) to check type of a value because type of a mutable value is variable. * * @throws MessageTypeCastException If type of this value is not Binary. @@ -196,7 +196,7 @@ public interface Value /** * Returns the value as {@code StringValue}. Otherwise throws {@code MessageTypeCastException}. - *

+ * * Note that you can't use instanceof or cast ((StringValue) thisValue) to check type of a value because type of a mutable value is variable. * * @throws MessageTypeCastException If type of this value is not String. @@ -205,7 +205,7 @@ public interface Value /** * Returns the value as {@code ArrayValue}. Otherwise throws {@code MessageTypeCastException}. - *

+ * * Note that you can't use instanceof or cast ((ArrayValue) thisValue) to check type of a value because type of a mutable value is variable. * * @throws MessageTypeCastException If type of this value is not Array. @@ -214,7 +214,7 @@ public interface Value /** * Returns the value as {@code MapValue}. Otherwise throws {@code MessageTypeCastException}. - *

+ * * Note that you can't use instanceof or cast ((MapValue) thisValue) to check type of a value because type of a mutable value is variable. * * @throws MessageTypeCastException If type of this value is not Map. @@ -223,7 +223,7 @@ public interface Value /** * Returns the value as {@code ExtensionValue}. Otherwise throws {@code MessageTypeCastException}. - *

+ * * Note that you can't use instanceof or cast ((ExtensionValue) thisValue) to check type of a value * because type of a mutable value is variable. * @@ -241,17 +241,22 @@ void writeTo(MessagePacker pk) /** * Compares this value to the specified object. - *

+ * * This method returns {@code true} if type and value are equivalent. * If this value is {@code MapValue} or {@code ArrayValue}, this method check equivalence of elements recursively. */ boolean equals(Object obj); /** - * Returns json representation of this Value for debugging purpose. - * This output json format is subject to change in future. - * Do not write code that depends on the resulting json format. + * Returns json representation of this Value. + * + * Following behavior is not configurable at this release and they might be changed at future releases: + * + * * if a key of MapValue is not string, the key is converted to a string using toString method. + * * NaN and Infinity of DoubleValue are converted to null. + * * ExtensionValue is converted to a 2-element array where first element is a number and second element is the data encoded in hex. + * * BinaryValue is converted to a string using UTF-8 encoding. Invalid byte sequence is replaced with U+FFFD replacement character. + * * Invalid UTF-8 byte sequences in StringValue is replaced with U+FFFD replacement character */ String toJson(); - } diff --git a/msgpack-core/src/main/java/org/msgpack/value/Variable.java b/msgpack-core/src/main/java/org/msgpack/value/Variable.java index 3782f7dee..59e6930cb 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/Variable.java +++ b/msgpack-core/src/main/java/org/msgpack/value/Variable.java @@ -195,7 +195,7 @@ public String toJson() @Override public String toString() { - return toJson(); + return Variable.this.toString(); } } @@ -683,8 +683,9 @@ public String asString() } } + // override for performance optimization @Override - public String toJson() + public String toString() { byte[] raw = (byte[]) objectValue; try { @@ -1052,13 +1053,13 @@ public boolean equals(Object o) @Override public String toJson() { - return immutableValue().toString(); // TODO optimize + return immutableValue().toJson(); // TODO optimize } @Override public String toString() { - return toJson(); + return immutableValue().toString(); // TODO optimize } @Override diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/AbstractImmutableRawValue.java b/msgpack-core/src/main/java/org/msgpack/value/impl/AbstractImmutableRawValue.java index 13b4764f1..31adb5b1a 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/impl/AbstractImmutableRawValue.java +++ b/msgpack-core/src/main/java/org/msgpack/value/impl/AbstractImmutableRawValue.java @@ -79,7 +79,9 @@ public String asString() @Override public String toJson() { - return toJson(new StringBuilder()).toString(); + StringBuilder sb = new StringBuilder(); + appendJsonString(sb, toString()); + return sb.toString(); } private void decodeString() @@ -118,12 +120,11 @@ public String toString() return decodedStringCache; } - private StringBuilder toJson(StringBuilder sb) + static void appendJsonString(StringBuilder sb, String string) { - String s = toString(); sb.append("\""); - for (int i = 0; i < s.length(); i++) { - char ch = s.charAt(i); + for (int i = 0; i < string.length(); i++) { + char ch = string.charAt(i); if (ch < 0x20) { switch (ch) { case '\n': @@ -169,13 +170,11 @@ else if (ch >= 0xd800 && ch <= 0xdfff) { } } sb.append("\""); - - return sb; } private static final char[] HEX_TABLE = "0123456789ABCDEF".toCharArray(); - private void escapeChar(StringBuilder sb, int ch) + private static void escapeChar(StringBuilder sb, int ch) { sb.append("\\u"); sb.append(HEX_TABLE[(ch >> 12) & 0x0f]); diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableArrayValueImpl.java b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableArrayValueImpl.java index 093c5a0f5..09fc18e52 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableArrayValueImpl.java +++ b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableArrayValueImpl.java @@ -160,15 +160,11 @@ public int hashCode() @Override public String toJson() - { - return toJson(new StringBuilder()).toString(); - } - - private StringBuilder toJson(StringBuilder sb) { if (array.length == 0) { - return sb.append("[]"); + return "[]"; } + StringBuilder sb = new StringBuilder(); sb.append("["); sb.append(array[0].toJson()); for (int i = 1; i < array.length; i++) { @@ -176,13 +172,33 @@ private StringBuilder toJson(StringBuilder sb) sb.append(array[i].toJson()); } sb.append("]"); - return sb; + return sb.toString(); } @Override public String toString() { - return toJson(); + if (array.length == 0) { + return "[]"; + } + StringBuilder sb = new StringBuilder(); + sb.append("["); + appendString(sb, array[0]); + for (int i = 1; i < array.length; i++) { + sb.append(","); + appendString(sb, array[i]); + } + sb.append("]"); + return sb.toString(); + } + + private static void appendString(StringBuilder sb, Value value) + { + if (value.isRawValue()) { + sb.append(value.toJson()); + } else { + sb.append(value.toString()); + } } private static class ImmutableArrayValueList diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableBinaryValueImpl.java b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableBinaryValueImpl.java index ca5ccfae0..2d444ae83 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableBinaryValueImpl.java +++ b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableBinaryValueImpl.java @@ -25,7 +25,7 @@ /** * {@code ImmutableBinaryValueImpl} Implements {@code ImmutableBinaryValue} using a {@code byte[]} field. - * This implementation caches result of {@code toJson()} and {@code asString()} using a private {@code String} field. + * This implementation caches result of {@code toString()} and {@code asString()} using a private {@code String} field. * * @see org.msgpack.value.StringValue */ diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableBooleanValueImpl.java b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableBooleanValueImpl.java index 5d15698a7..535e91c61 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableBooleanValueImpl.java +++ b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableBooleanValueImpl.java @@ -24,7 +24,7 @@ /** * {@code ImmutableBooleanValueImpl} Implements {@code ImmutableBooleanValue} using a {@code boolean} field. - *

+ * * This class is a singleton. {@code ImmutableBooleanValueImpl.trueInstance()} and {@code ImmutableBooleanValueImpl.falseInstance()} are the only instances of this class. * * @see org.msgpack.value.BooleanValue diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableDoubleValueImpl.java b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableDoubleValueImpl.java index 5cc9b66f7..b7fa39397 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableDoubleValueImpl.java +++ b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableDoubleValueImpl.java @@ -128,12 +128,16 @@ public int hashCode() @Override public String toJson() { - return Double.toString(value); + if (Double.isNaN(value) || Double.isInfinite(value)) { + return "null"; + } else { + return Double.toString(value); + } } @Override public String toString() { - return toJson(); + return Double.toString(value); } } diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableExtensionValueImpl.java b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableExtensionValueImpl.java index c7659a477..eb14cc767 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableExtensionValueImpl.java +++ b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableExtensionValueImpl.java @@ -112,19 +112,27 @@ public int hashCode() public String toJson() { StringBuilder sb = new StringBuilder(); - sb.append('('); + sb.append('['); sb.append(Byte.toString(type)); - sb.append(",0x"); + sb.append(",\""); for (byte e : data) { sb.append(Integer.toString((int) e, 16)); } - sb.append(")"); + sb.append("\"]"); return sb.toString(); } @Override public String toString() { - return toJson(); + StringBuilder sb = new StringBuilder(); + sb.append('('); + sb.append(Byte.toString(type)); + sb.append(",0x"); + for (byte e : data) { + sb.append(Integer.toString((int) e, 16)); + } + sb.append(")"); + return sb.toString(); } } diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableMapValueImpl.java b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableMapValueImpl.java index ede45d170..3df98d619 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableMapValueImpl.java +++ b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableMapValueImpl.java @@ -148,34 +148,63 @@ public int hashCode() } @Override - public String toString() + public String toJson() { - return toJson(); + if (kvs.length == 0) { + return "{}"; + } + StringBuilder sb = new StringBuilder(); + sb.append("{"); + appendJsonKey(sb, kvs[0]); + sb.append(":"); + sb.append(kvs[1].toJson()); + for (int i = 2; i < kvs.length; i += 2) { + sb.append(","); + appendJsonKey(sb, kvs[i]); + sb.append(":"); + sb.append(kvs[i + 1].toJson()); + } + sb.append("}"); + return sb.toString(); } - @Override - public String toJson() + private static void appendJsonKey(StringBuilder sb, Value key) { - return toJson(new StringBuilder()).toString(); + if (key.isRawValue()) { + sb.append(key.toJson()); + } else { + ImmutableStringValueImpl.appendJsonString(sb, key.toString()); + } } - private StringBuilder toJson(StringBuilder sb) + @Override + public String toString() { if (kvs.length == 0) { - return sb.append("{}"); + return "{}"; } + StringBuilder sb = new StringBuilder(); sb.append("{"); - sb.append(kvs[0].toJson()); + appendString(sb, kvs[0]); sb.append(":"); - sb.append(kvs[1].toJson()); + appendString(sb, kvs[1]); for (int i = 2; i < kvs.length; i += 2) { sb.append(","); - sb.append(kvs[i].toJson()); + appendString(sb, kvs[i]); sb.append(":"); - sb.append(kvs[i + 1].toJson()); + appendString(sb, kvs[i + 1]); } sb.append("}"); - return sb; + return sb.toString(); + } + + private static void appendString(StringBuilder sb, Value value) + { + if (value.isRawValue()) { + sb.append(value.toJson()); + } else { + sb.append(value.toString()); + } } private static class ImmutableMapValueMap diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableNilValueImpl.java b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableNilValueImpl.java index 141e2ce1a..7077d115e 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableNilValueImpl.java +++ b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableNilValueImpl.java @@ -24,7 +24,7 @@ /** * {@code ImmutableNilValueImpl} Implements {@code ImmutableNilValue}. - *

+ * * This class is a singleton. {@code ImmutableNilValueImpl.get()} is the only instances of this class. * * @see org.msgpack.value.NilValue diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableStringValueImpl.java b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableStringValueImpl.java index ab26c72d4..dbdb57195 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableStringValueImpl.java +++ b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableStringValueImpl.java @@ -25,7 +25,7 @@ /** * {@code ImmutableStringValueImpl} Implements {@code ImmutableStringValue} using a {@code byte[]} field. - * This implementation caches result of {@code toJson()} and {@code asString()} using a private {@code String} field. + * This implementation caches result of {@code toString()} and {@code asString()} using a private {@code String} field. * * @see org.msgpack.value.StringValue */ From 6d06d14f658744d55cf50c8ea64bd02ccd3f822d Mon Sep 17 00:00:00 2001 From: Santhosh Kumar Tekuri Date: Fri, 3 Jul 2015 20:59:59 +0530 Subject: [PATCH 117/234] NoSuchMethodException on bigendian system java.lang.NoSuchMethodException: org.msgpack.core.buffer.MessageBufferBE.([B) on MessageBuffer.java:146 --- .../main/java/org/msgpack/core/buffer/MessageBufferBE.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferBE.java b/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferBE.java index bd78b6653..4fec0cd42 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferBE.java +++ b/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferBE.java @@ -32,6 +32,11 @@ public class MessageBufferBE super(bb); } + MessageBufferBE(byte[] arr) + { + super(arr); + } + private MessageBufferBE(Object base, long address, int length, ByteBuffer reference) { super(base, address, length, reference); From 54029afd4ca23d2824bd6deda1786c6009540fec Mon Sep 17 00:00:00 2001 From: Mitsunori Komatsu Date: Sat, 4 Jul 2015 22:30:18 +0900 Subject: [PATCH 118/234] Use RawValue#toString instead of Value#toJson in MessagePackParser --- .../org/msgpack/jackson/dataformat/MessagePackParser.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java index e41d45735..1297861f3 100644 --- a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java +++ b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java @@ -202,7 +202,7 @@ public JsonToken nextToken() case STRING: value = messageUnpacker.unpackValue(var); if (parsingContext.inObject() && _currToken != JsonToken.FIELD_NAME) { - parsingContext.setCurrentName(value.asRawValue().toJson()); + parsingContext.setCurrentName(value.asRawValue().toString()); nextToken = JsonToken.FIELD_NAME; } else { @@ -212,7 +212,7 @@ public JsonToken nextToken() case BINARY: value = messageUnpacker.unpackValue(var); if (parsingContext.inObject() && _currToken != JsonToken.FIELD_NAME) { - parsingContext.setCurrentName(value.asRawValue().toJson()); + parsingContext.setCurrentName(value.asRawValue().toString()); nextToken = JsonToken.FIELD_NAME; } else { @@ -267,7 +267,7 @@ public String getText() { // This method can be called for new BigInteger(text) if (value.isRawValue()) { - return value.asRawValue().toJson(); + return value.asRawValue().toString(); } else { return value.toString(); From 682a658bb03573c87a48382fbd9d6390d2214ace Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Sat, 4 Jul 2015 09:21:06 -0700 Subject: [PATCH 119/234] Setting version to 0.7.0-M6 --- version.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.sbt b/version.sbt index 144b223b4..d630bd483 100644 --- a/version.sbt +++ b/version.sbt @@ -1 +1 @@ -version in ThisBuild := "0.7.0-p10-SNAPSHOT" \ No newline at end of file +version in ThisBuild := "0.7.0-M6" \ No newline at end of file From dd1ac732f3709bac4d331b94999a30439ba6db8d Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Sat, 4 Jul 2015 09:21:28 -0700 Subject: [PATCH 120/234] Setting version to 0.7.0-M7-SNAPSHOT --- version.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.sbt b/version.sbt index d630bd483..ee25b71c8 100644 --- a/version.sbt +++ b/version.sbt @@ -1 +1 @@ -version in ThisBuild := "0.7.0-M6" \ No newline at end of file +version in ThisBuild := "0.7.0-M7-SNAPSHOT" \ No newline at end of file From 0f48c3d5efec72f3692fd8a4a916a870cc4b3c38 Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Sat, 4 Jul 2015 09:22:55 -0700 Subject: [PATCH 121/234] Update document --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index eabe54553..96e8400f9 100644 --- a/README.md +++ b/README.md @@ -18,13 +18,13 @@ For Maven users: org.msgpack msgpack-core - 0.7.0-p9 + 0.7.0-M6 ``` For sbt users: ``` -libraryDependencies += "org.msgpack" % "msgpack-core" % "0.7.0-p9" +libraryDependencies += "org.msgpack" % "msgpack-core" % "0.7.0-M6" ``` - [Usage examples](msgpack-core/src/test/java/org/msgpack/core/example/MessagePackExample.java) From 67f83c65b858d4192237570c2958e688951561f5 Mon Sep 17 00:00:00 2001 From: Mitsunori Komatsu Date: Sun, 9 Aug 2015 18:59:52 +0900 Subject: [PATCH 122/234] Save ObjectCodec in MessagePackParser --- .../dataformat/MessagePackFactory.java | 4 +- .../jackson/dataformat/MessagePackParser.java | 11 +- .../ExampleOfTypeInformationSerDe.java | 168 ++++++++++++++++++ 3 files changed, 176 insertions(+), 7 deletions(-) create mode 100644 msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/ExampleOfTypeInformationSerDe.java diff --git a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackFactory.java b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackFactory.java index 06f7a93cd..ff7aa373f 100644 --- a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackFactory.java +++ b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackFactory.java @@ -76,7 +76,7 @@ public JsonParser createParser(InputStream in) protected MessagePackParser _createParser(InputStream in, IOContext ctxt) throws IOException { - MessagePackParser parser = new MessagePackParser(ctxt, _parserFeatures, in); + MessagePackParser parser = new MessagePackParser(ctxt, _parserFeatures, _objectCodec, in); return parser; } @@ -87,7 +87,7 @@ protected JsonParser _createParser(byte[] data, int offset, int len, IOContext c if (offset != 0 || len != data.length) { data = Arrays.copyOfRange(data, offset, offset + len); } - MessagePackParser parser = new MessagePackParser(ctxt, _parserFeatures, data); + MessagePackParser parser = new MessagePackParser(ctxt, _parserFeatures, _objectCodec, data); return parser; } } diff --git a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java index 1297861f3..0f85b3459 100644 --- a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java +++ b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java @@ -95,23 +95,24 @@ private static class StackItemForArray } } - public MessagePackParser(IOContext ctxt, int features, InputStream in) + public MessagePackParser(IOContext ctxt, int features, ObjectCodec objectCodec, InputStream in) throws IOException { - this(ctxt, features, new InputStreamBufferInput(in), in); + this(ctxt, features, new InputStreamBufferInput(in), objectCodec, in); } - public MessagePackParser(IOContext ctxt, int features, byte[] bytes) + public MessagePackParser(IOContext ctxt, int features, ObjectCodec objectCodec, byte[] bytes) throws IOException { - this(ctxt, features, new ArrayBufferInput(bytes), bytes); + this(ctxt, features, new ArrayBufferInput(bytes), objectCodec, bytes); } - private MessagePackParser(IOContext ctxt, int features, MessageBufferInput input, Object src) + private MessagePackParser(IOContext ctxt, int features, MessageBufferInput input, ObjectCodec objectCodec, Object src) throws IOException { super(features); + this.codec = objectCodec; ioContext = ctxt; DupDetector dups = Feature.STRICT_DUPLICATE_DETECTION.enabledIn(features) ? DupDetector.rootDetector(this) : null; diff --git a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/ExampleOfTypeInformationSerDe.java b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/ExampleOfTypeInformationSerDe.java new file mode 100644 index 000000000..2781ce5a2 --- /dev/null +++ b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/ExampleOfTypeInformationSerDe.java @@ -0,0 +1,168 @@ +// +// MessagePack for Java +// +// 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.jackson.dataformat; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.core.TreeNode; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonDeserializer; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import org.junit.Test; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; + +public class ExampleOfTypeInformationSerDe + extends MessagePackDataformatTestBase +{ + static class A + { + private List list = new ArrayList(); + + public List getList() + { + return list; + } + + public void setList(List list) + { + this.list = list; + } + } + + static class B + { + private String str; + + public String getStr() + { + return str; + } + + public void setStr(String str) + { + this.str = str; + } + } + + + @JsonSerialize(using=ObjectContainerSerializer.class) + @JsonDeserialize(using=ObjectContainerDeserializer.class) + static class ObjectContainer + { + private final Map objects; + + public ObjectContainer(Map objects) + { + this.objects = objects; + } + + public Map getObjects() + { + return objects; + } + } + + static class ObjectContainerSerializer + extends JsonSerializer + { + @Override + public void serialize(ObjectContainer value, JsonGenerator gen, SerializerProvider serializers) + throws IOException, JsonProcessingException + { + gen.writeStartObject(); + HashMap metadata = new HashMap(); + for (Map.Entry entry : value.getObjects().entrySet()) { + metadata.put(entry.getKey(), entry.getValue().getClass().getName()); + } + gen.writeObjectField("__metadata", metadata); + gen.writeObjectField("objects", value.getObjects()); + gen.writeEndObject(); + } + } + + static class ObjectContainerDeserializer + extends JsonDeserializer + { + @Override + public ObjectContainer deserialize(JsonParser p, DeserializationContext ctxt) + throws IOException, JsonProcessingException + { + ObjectContainer objectContainer = new ObjectContainer(new HashMap()); + TreeNode treeNode = p.readValueAsTree(); + + Map metadata = treeNode.get("__metadata").traverse(p.getCodec()).readValueAs(new TypeReference>() {}); + TreeNode dataMapTree = treeNode.get("objects"); + for (Map.Entry entry : metadata.entrySet()) { + try { + Object o = dataMapTree.get(entry.getKey()).traverse(p.getCodec()).readValueAs(Class.forName(entry.getValue())); + objectContainer.getObjects().put(entry.getKey(), o); + } + catch (ClassNotFoundException e) { + throw new RuntimeException("Failed to deserialize: " + entry, e); + } + } + + return objectContainer; + } + } + + @Test + public void test() + throws IOException + { + ObjectContainer objectContainer = new ObjectContainer(new HashMap()); + { + A a = new A(); + a.setList(Arrays.asList("first", "second", "third")); + objectContainer.getObjects().put("a", a); + + B b = new B(); + b.setStr("hello world"); + objectContainer.getObjects().put("b", b); + + Double pi = 3.14; + objectContainer.getObjects().put("pi", pi); + } + + ObjectMapper objectMapper = new ObjectMapper(new MessagePackFactory()); + byte[] bytes = objectMapper.writeValueAsBytes(objectContainer); + ObjectContainer restored = objectMapper.readValue(bytes, ObjectContainer.class); + + { + assertEquals(3, restored.getObjects().size()); + A a = (A) restored.getObjects().get("a"); + assertArrayEquals(new String[] {"first", "second", "third"}, a.getList().toArray()); + B b = (B) restored.getObjects().get("b"); + assertEquals("hello world", b.getStr()); + assertEquals(3.14, restored.getObjects().get("pi")); + } + } +} From e50747ff4b546ad1fdd62fe6a249e449f4d4640c Mon Sep 17 00:00:00 2001 From: Mitsunori Komatsu Date: Mon, 10 Aug 2015 00:45:34 +0900 Subject: [PATCH 123/234] Support non-string key in jackson-dataformat-msgpack --- .../jackson/dataformat/MessagePackParser.java | 24 +++- .../dataformat/MessagePackParserTest.java | 135 ++++++++++++++++++ 2 files changed, 156 insertions(+), 3 deletions(-) diff --git a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java index 0f85b3459..7ac2fa5af 100644 --- a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java +++ b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java @@ -190,15 +190,33 @@ public JsonToken nextToken() case BOOLEAN: boolean b = messageUnpacker.unpackBoolean(); value = ValueFactory.newNil(); - nextToken = b ? JsonToken.VALUE_TRUE : JsonToken.VALUE_FALSE; + if (parsingContext.inObject() && _currToken != JsonToken.FIELD_NAME) { + parsingContext.setCurrentName(Boolean.toString(b)); + nextToken = JsonToken.FIELD_NAME; + } + else { + nextToken = b ? JsonToken.VALUE_TRUE : JsonToken.VALUE_FALSE; + } break; case INTEGER: value = messageUnpacker.unpackValue(var); - nextToken = JsonToken.VALUE_NUMBER_INT; + if (parsingContext.inObject() && _currToken != JsonToken.FIELD_NAME) { + parsingContext.setCurrentName(value.asIntegerValue().toString()); + nextToken = JsonToken.FIELD_NAME; + } + else { + nextToken = JsonToken.VALUE_NUMBER_INT; + } break; case FLOAT: value = messageUnpacker.unpackValue(var); - nextToken = JsonToken.VALUE_NUMBER_FLOAT; + if (parsingContext.inObject() && _currToken != JsonToken.FIELD_NAME) { + parsingContext.setCurrentName(value.asFloatValue().toString()); + nextToken = JsonToken.FIELD_NAME; + } + else { + nextToken = JsonToken.VALUE_NUMBER_FLOAT; + } break; case STRING: value = messageUnpacker.unpackValue(var); diff --git a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackParserTest.java b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackParserTest.java index c280fd30b..c2bd7c15b 100644 --- a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackParserTest.java +++ b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackParserTest.java @@ -16,10 +16,14 @@ package org.msgpack.jackson.dataformat; import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.JsonToken; import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.KeyDeserializer; import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.module.SimpleModule; import org.junit.Test; import org.msgpack.core.MessagePack; import org.msgpack.core.MessagePacker; @@ -537,4 +541,135 @@ public void testBinaryKeyInNestedObject() assertEquals(12, map.get("bar")); assertEquals(1, objects.get(1)); } + + @Test + public void testByteArrayKey() + throws IOException + { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + MessagePacker messagePacker = MessagePack.newDefaultPacker(out).packMapHeader(2); + byte[] k0 = new byte[] {0}; + byte[] k1 = new byte[] {1}; + messagePacker.packBinaryHeader(1).writePayload(k0).packInt(2); + messagePacker.packBinaryHeader(1).writePayload(k1).packInt(3); + messagePacker.close(); + + ObjectMapper objectMapper = new ObjectMapper(new MessagePackFactory()); + SimpleModule module = new SimpleModule(); + module.addKeyDeserializer(byte[].class, new KeyDeserializer() + { + @Override + public Object deserializeKey(String key, DeserializationContext ctxt) + throws IOException, JsonProcessingException + { + return key.getBytes(); + } + }); + objectMapper.registerModule(module); + + Map map = objectMapper.readValue( + out.toByteArray(), new TypeReference>() {}); + assertEquals(2, map.size()); + for (Map.Entry entry : map.entrySet()) { + if (Arrays.equals(entry.getKey(), k0)) { + assertEquals((Integer) 2, entry.getValue()); + } + else if (Arrays.equals(entry.getKey(), k1)) { + assertEquals((Integer) 3, entry.getValue()); + } + } + } + + @Test + public void testIntegerKey() + throws IOException + { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + MessagePacker messagePacker = MessagePack.newDefaultPacker(out).packMapHeader(3); + for (int i = 0; i < 2; i++) { + messagePacker.packInt(i).packInt(i + 2); + } + messagePacker.close(); + + ObjectMapper objectMapper = new ObjectMapper(new MessagePackFactory()); + SimpleModule module = new SimpleModule(); + module.addKeyDeserializer(Integer.class, new KeyDeserializer() + { + @Override + public Object deserializeKey(String key, DeserializationContext ctxt) + throws IOException, JsonProcessingException + { + return Integer.valueOf(key); + } + }); + objectMapper.registerModule(module); + + Map map = objectMapper.readValue( + out.toByteArray(), new TypeReference>() {}); + assertEquals(2, map.size()); + assertEquals((Integer) 2, map.get(0)); + assertEquals((Integer) 3, map.get(1)); + } + + @Test + public void testFloatKey() + throws IOException + { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + MessagePacker messagePacker = MessagePack.newDefaultPacker(out).packMapHeader(3); + for (int i = 0; i < 2; i++) { + messagePacker.packFloat(i).packInt(i + 2); + } + messagePacker.close(); + + ObjectMapper objectMapper = new ObjectMapper(new MessagePackFactory()); + SimpleModule module = new SimpleModule(); + module.addKeyDeserializer(Float.class, new KeyDeserializer() + { + @Override + public Object deserializeKey(String key, DeserializationContext ctxt) + throws IOException, JsonProcessingException + { + return Float.valueOf(key); + } + }); + objectMapper.registerModule(module); + + Map map = objectMapper.readValue( + out.toByteArray(), new TypeReference>() {}); + assertEquals(2, map.size()); + assertEquals((Integer) 2, map.get(0f)); + assertEquals((Integer) 3, map.get(1f)); + } + + @Test + public void testBooleanKey() + throws IOException + { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + MessagePacker messagePacker = MessagePack.newDefaultPacker(out).packMapHeader(3); + messagePacker.packBoolean(true).packInt(2); + messagePacker.packBoolean(false).packInt(3); + messagePacker.close(); + + ObjectMapper objectMapper = new ObjectMapper(new MessagePackFactory()); + SimpleModule module = new SimpleModule(); + module.addKeyDeserializer(Boolean.class, new KeyDeserializer() + { + @Override + public Object deserializeKey(String key, DeserializationContext ctxt) + throws IOException, JsonProcessingException + { + return Boolean.valueOf(key); + } + }); + objectMapper.registerModule(module); + + Map map = objectMapper.readValue( + out.toByteArray(), new TypeReference>() {}); + assertEquals(2, map.size()); + assertEquals((Integer) 2, map.get(true)); + assertEquals((Integer) 3, map.get(false)); + } } + From 47f4b6a0e35575d4a37d63c240f82ae8e3105aad Mon Sep 17 00:00:00 2001 From: Jun Hiroe Date: Thu, 3 Sep 2015 23:35:40 +0900 Subject: [PATCH 124/234] Remove an unecessary import statement --- .../org/msgpack/jackson/dataformat/MessagePackParserTest.java | 1 - 1 file changed, 1 deletion(-) diff --git a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackParserTest.java b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackParserTest.java index c2bd7c15b..30f1b4894 100644 --- a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackParserTest.java +++ b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackParserTest.java @@ -28,7 +28,6 @@ import org.msgpack.core.MessagePack; import org.msgpack.core.MessagePacker; import org.msgpack.core.buffer.OutputStreamBufferOutput; -import org.msgpack.value.ExtensionValue; import java.io.ByteArrayOutputStream; import java.io.File; From d488b04a4de337f2f63d7450966090c4e7907712 Mon Sep 17 00:00:00 2001 From: Jun Hiroe Date: Thu, 3 Sep 2015 23:55:56 +0900 Subject: [PATCH 125/234] Fix style errors --- .../jackson/dataformat/ExampleOfTypeInformationSerDe.java | 5 ++--- .../msgpack/jackson/dataformat/MessagePackParserTest.java | 1 - 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/ExampleOfTypeInformationSerDe.java b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/ExampleOfTypeInformationSerDe.java index 2781ce5a2..5414b0bdc 100644 --- a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/ExampleOfTypeInformationSerDe.java +++ b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/ExampleOfTypeInformationSerDe.java @@ -72,9 +72,8 @@ public void setStr(String str) } } - - @JsonSerialize(using=ObjectContainerSerializer.class) - @JsonDeserialize(using=ObjectContainerDeserializer.class) + @JsonSerialize(using = ObjectContainerSerializer.class) + @JsonDeserialize(using = ObjectContainerDeserializer.class) static class ObjectContainer { private final Map objects; diff --git a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackParserTest.java b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackParserTest.java index c2bd7c15b..61172e9b3 100644 --- a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackParserTest.java +++ b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackParserTest.java @@ -672,4 +672,3 @@ public Object deserializeKey(String key, DeserializationContext ctxt) assertEquals((Integer) 3, map.get(false)); } } - From 0bcf921c5cab43cfc2b4fdf32cf47381176da6fe Mon Sep 17 00:00:00 2001 From: Jun Hiroe Date: Sun, 6 Sep 2015 13:21:44 +0900 Subject: [PATCH 126/234] Update README.md [skip ci] --- README.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/README.md b/README.md index 96e8400f9..e3805fde9 100644 --- a/README.md +++ b/README.md @@ -27,6 +27,17 @@ For sbt users: libraryDependencies += "org.msgpack" % "msgpack-core" % "0.7.0-M6" ``` +For gradle users: +``` +repositories { + mavenCentral() +} + +dependencies { + compile 'org.msgpack:msgpack-core:0.7.0-M6' +} +``` + - [Usage examples](msgpack-core/src/test/java/org/msgpack/core/example/MessagePackExample.java) msgpack-java supports serialization and deserialization of Java objects through [jackson-databind](https://github.com/FasterXML/jackson-databind). From 09f5d5ee79f2d833647c2f88c6212bfb424a79a8 Mon Sep 17 00:00:00 2001 From: Mitsunori Komatsu Date: Sun, 25 Oct 2015 01:23:21 +0900 Subject: [PATCH 127/234] Take care of `offset` of source ByteBuffer in MessageBuffer#putByteBuffer --- .../msgpack/core/buffer/MessageBufferU.java | 2 +- .../core/buffer/MessageBufferTest.scala | 42 +++++++++++++++++++ 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferU.java b/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferU.java index 4d60d8aad..54caa8838 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferU.java +++ b/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferU.java @@ -198,7 +198,7 @@ public void putByteBuffer(int index, ByteBuffer src, int len) assert (len <= src.remaining()); if (src.hasArray()) { - putBytes(index, src.array(), src.position(), len); + putBytes(index, src.array(), src.position() + src.arrayOffset(), len); src.position(src.position() + len); } else { diff --git a/msgpack-core/src/test/scala/org/msgpack/core/buffer/MessageBufferTest.scala b/msgpack-core/src/test/scala/org/msgpack/core/buffer/MessageBufferTest.scala index 32ee58f02..73ec87670 100644 --- a/msgpack-core/src/test/scala/org/msgpack/core/buffer/MessageBufferTest.scala +++ b/msgpack-core/src/test/scala/org/msgpack/core/buffer/MessageBufferTest.scala @@ -15,6 +15,7 @@ // package org.msgpack.core.buffer +import java.io.ByteArrayInputStream import java.nio.ByteBuffer import org.msgpack.core.MessagePackSpec @@ -184,6 +185,47 @@ class MessageBufferTest } } } + + "copy sliced buffer" in { + def prepareBytes : Array[Byte] = { + Array[Byte](0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07) + } + + def prepareDirectBuffer : ByteBuffer = { + val directBuffer = ByteBuffer.allocateDirect(prepareBytes.length) + directBuffer.put(prepareBytes) + directBuffer + } + + def checkSliceAndCopyTo(srcBuffer: MessageBuffer, dstBuffer: MessageBuffer) = { + val sliced = srcBuffer.slice(2, 5) + + sliced.size() shouldBe 5 + sliced.getByte(0) shouldBe 0x02 + sliced.getByte(1) shouldBe 0x03 + sliced.getByte(2) shouldBe 0x04 + sliced.getByte(3) shouldBe 0x05 + sliced.getByte(4) shouldBe 0x06 + + sliced.copyTo(3, dstBuffer, 1, 2) // copy 0x05 and 0x06 to dstBuffer[1] and [2] + + dstBuffer.getByte(0) shouldBe 0x00 + dstBuffer.getByte(1) shouldBe 0x05 // copied by sliced.getByte(3) + dstBuffer.getByte(2) shouldBe 0x06 // copied by sliced.getByte(4) + dstBuffer.getByte(3) shouldBe 0x03 + dstBuffer.getByte(4) shouldBe 0x04 + dstBuffer.getByte(5) shouldBe 0x05 + dstBuffer.getByte(6) shouldBe 0x06 + dstBuffer.getByte(7) shouldBe 0x07 + } + + checkSliceAndCopyTo(new MessageBufferU(prepareBytes), new MessageBufferU(prepareBytes)) + checkSliceAndCopyTo(new MessageBufferU(ByteBuffer.wrap(prepareBytes)), new MessageBufferU(ByteBuffer.wrap(prepareBytes))) + checkSliceAndCopyTo(new MessageBufferU(prepareDirectBuffer), new MessageBufferU(prepareDirectBuffer)) + checkSliceAndCopyTo(new MessageBufferBE(prepareBytes), new MessageBufferBE(prepareBytes)) + checkSliceAndCopyTo(new MessageBufferBE(ByteBuffer.wrap(prepareBytes)), new MessageBufferBE(ByteBuffer.wrap(prepareBytes))) + checkSliceAndCopyTo(new MessageBufferBE(prepareDirectBuffer), new MessageBufferBE(prepareDirectBuffer)) + } } } From eacd3f46d091017cf695571d79762a6749b73107 Mon Sep 17 00:00:00 2001 From: Mitsunori Komatsu Date: Sun, 25 Oct 2015 01:27:05 +0900 Subject: [PATCH 128/234] Removed unnecessary import --- .../test/scala/org/msgpack/core/buffer/MessageBufferTest.scala | 1 - 1 file changed, 1 deletion(-) diff --git a/msgpack-core/src/test/scala/org/msgpack/core/buffer/MessageBufferTest.scala b/msgpack-core/src/test/scala/org/msgpack/core/buffer/MessageBufferTest.scala index 73ec87670..ac2c47acd 100644 --- a/msgpack-core/src/test/scala/org/msgpack/core/buffer/MessageBufferTest.scala +++ b/msgpack-core/src/test/scala/org/msgpack/core/buffer/MessageBufferTest.scala @@ -15,7 +15,6 @@ // package org.msgpack.core.buffer -import java.io.ByteArrayInputStream import java.nio.ByteBuffer import org.msgpack.core.MessagePackSpec From 0b6ccbbc3164e91a7aafe581622a9e8a111672b9 Mon Sep 17 00:00:00 2001 From: Mitsunori Komatsu Date: Sun, 25 Oct 2015 18:54:59 +0900 Subject: [PATCH 129/234] Use MessageBuffer.wrap() instead of MessageBufferBE() directly to work on Travis CI --- .../org/msgpack/core/buffer/MessageBufferTest.scala | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/msgpack-core/src/test/scala/org/msgpack/core/buffer/MessageBufferTest.scala b/msgpack-core/src/test/scala/org/msgpack/core/buffer/MessageBufferTest.scala index ac2c47acd..db4dec659 100644 --- a/msgpack-core/src/test/scala/org/msgpack/core/buffer/MessageBufferTest.scala +++ b/msgpack-core/src/test/scala/org/msgpack/core/buffer/MessageBufferTest.scala @@ -193,6 +193,7 @@ class MessageBufferTest def prepareDirectBuffer : ByteBuffer = { val directBuffer = ByteBuffer.allocateDirect(prepareBytes.length) directBuffer.put(prepareBytes) + directBuffer.flip directBuffer } @@ -218,12 +219,9 @@ class MessageBufferTest dstBuffer.getByte(7) shouldBe 0x07 } - checkSliceAndCopyTo(new MessageBufferU(prepareBytes), new MessageBufferU(prepareBytes)) - checkSliceAndCopyTo(new MessageBufferU(ByteBuffer.wrap(prepareBytes)), new MessageBufferU(ByteBuffer.wrap(prepareBytes))) - checkSliceAndCopyTo(new MessageBufferU(prepareDirectBuffer), new MessageBufferU(prepareDirectBuffer)) - checkSliceAndCopyTo(new MessageBufferBE(prepareBytes), new MessageBufferBE(prepareBytes)) - checkSliceAndCopyTo(new MessageBufferBE(ByteBuffer.wrap(prepareBytes)), new MessageBufferBE(ByteBuffer.wrap(prepareBytes))) - checkSliceAndCopyTo(new MessageBufferBE(prepareDirectBuffer), new MessageBufferBE(prepareDirectBuffer)) + checkSliceAndCopyTo(MessageBuffer.wrap(prepareBytes), MessageBuffer.wrap(prepareBytes)) + checkSliceAndCopyTo(MessageBuffer.wrap(ByteBuffer.wrap(prepareBytes)), MessageBuffer.wrap(ByteBuffer.wrap(prepareBytes))) + checkSliceAndCopyTo(MessageBuffer.wrap(prepareDirectBuffer), MessageBuffer.wrap(prepareDirectBuffer)) } } } From ac1ad7e8d8cb86432a85e2eaa44922bb578e8e28 Mon Sep 17 00:00:00 2001 From: Mitsunori Komatsu Date: Sat, 24 Oct 2015 22:08:49 +0900 Subject: [PATCH 130/234] Take care of incomplete multi-bytes at the tail of buffer --- .../org/msgpack/core/MessageUnpacker.java | 18 ++++++++++--- .../msgpack/core/MessageUnpackerTest.scala | 26 +++++++++++++++++++ 2 files changed, 40 insertions(+), 4 deletions(-) diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java b/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java index c74c3307d..5ca7dc1e3 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java +++ b/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java @@ -1025,13 +1025,20 @@ public String unpackString() decodeBuffer.clear(); StringBuilder sb = new StringBuilder(); + boolean incompleteMultiBytes = false; while (cursor < strLen) { int readLen = Math.min(position < buffer.size() ? buffer.size() - position : buffer.size(), strLen - cursor); + if (incompleteMultiBytes) { + // Prepare enough buffer for decoding multi-bytes character right after running into incomplete one + readLen = Math.min(config.getStringDecoderBufferSize(), strLen - cursor); + } if (!ensure(readLen)) { throw new EOFException(); } + incompleteMultiBytes = false; ByteBuffer bb = buffer.toByteBuffer(position, readLen); + int startPos = bb.position(); while (bb.hasRemaining()) { boolean endOfInput = (cursor + readLen) >= strLen; @@ -1051,10 +1058,9 @@ public String unpackString() if (config.getActionOnMalFormedInput() == CodingErrorAction.REPORT) { throw new MalformedInputException(strLen); } - // trash truncated bytes - while (bb.hasRemaining()) { - bb.get(); - } + incompleteMultiBytes = true; + // Proceed the cursor with the length already decoded successfully. + readLen = bb.position() - startPos; } if (cr.isError()) { @@ -1068,6 +1074,10 @@ public String unpackString() sb.append(decodeBuffer); decodeBuffer.clear(); + + if (incompleteMultiBytes) { + break; + } } cursor += readLen; diff --git a/msgpack-core/src/test/scala/org/msgpack/core/MessageUnpackerTest.scala b/msgpack-core/src/test/scala/org/msgpack/core/MessageUnpackerTest.scala index 39ca1639b..c4f1ffe5d 100644 --- a/msgpack-core/src/test/scala/org/msgpack/core/MessageUnpackerTest.scala +++ b/msgpack-core/src/test/scala/org/msgpack/core/MessageUnpackerTest.scala @@ -16,6 +16,7 @@ package org.msgpack.core import java.io._ +import java.nio.ByteBuffer import org.msgpack.core.buffer._ import org.msgpack.value.ValueType @@ -663,5 +664,30 @@ class MessageUnpackerTest extends MessagePackSpec { unpacker.getTotalReadBytes shouldBe arr.length } } + + "unpack string crossing end of buffer" in { + def check(expected: String, strLen: Int) = { + val bytes = new Array[Byte](strLen) + val out = new ByteArrayOutputStream + + val packer = MessagePack.newDefaultPacker(out) + packer.packBinaryHeader(bytes.length) + packer.writePayload(bytes) + packer.packString(expected) + packer.close + + val unpacker = new MessageUnpacker(new InputStreamBufferInput(new ByteArrayInputStream(out.toByteArray))) + val len = unpacker.unpackBinaryHeader + unpacker.readPayload(len) + val got = unpacker.unpackString + unpacker.close + + got shouldBe expected + } + + Seq("あ", "aあ", "あa", "あいうえおかきくけこさしすせそ").foreach { s => + Seq(8185, 8186, 8187, 8188, 16377, 16378, 16379, 16380).foreach { n => check(s, n)} + } + } } } From 8ac9d126555d00d5c949a52ab535fdbce634e082 Mon Sep 17 00:00:00 2001 From: Mitsunori Komatsu Date: Wed, 28 Oct 2015 23:57:36 +0900 Subject: [PATCH 131/234] Minor refactoring --- .../main/java/org/msgpack/core/MessageUnpacker.java | 10 +++++----- .../scala/org/msgpack/core/MessageUnpackerTest.scala | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java b/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java index 5ca7dc1e3..43f6eede6 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java +++ b/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java @@ -1025,10 +1025,10 @@ public String unpackString() decodeBuffer.clear(); StringBuilder sb = new StringBuilder(); - boolean incompleteMultiBytes = false; + boolean hasIncompleteMultiBytes = false; while (cursor < strLen) { int readLen = Math.min(position < buffer.size() ? buffer.size() - position : buffer.size(), strLen - cursor); - if (incompleteMultiBytes) { + if (hasIncompleteMultiBytes) { // Prepare enough buffer for decoding multi-bytes character right after running into incomplete one readLen = Math.min(config.getStringDecoderBufferSize(), strLen - cursor); } @@ -1036,7 +1036,7 @@ public String unpackString() throw new EOFException(); } - incompleteMultiBytes = false; + hasIncompleteMultiBytes = false; ByteBuffer bb = buffer.toByteBuffer(position, readLen); int startPos = bb.position(); @@ -1058,7 +1058,7 @@ public String unpackString() if (config.getActionOnMalFormedInput() == CodingErrorAction.REPORT) { throw new MalformedInputException(strLen); } - incompleteMultiBytes = true; + hasIncompleteMultiBytes = true; // Proceed the cursor with the length already decoded successfully. readLen = bb.position() - startPos; } @@ -1075,7 +1075,7 @@ public String unpackString() decodeBuffer.clear(); - if (incompleteMultiBytes) { + if (hasIncompleteMultiBytes) { break; } } diff --git a/msgpack-core/src/test/scala/org/msgpack/core/MessageUnpackerTest.scala b/msgpack-core/src/test/scala/org/msgpack/core/MessageUnpackerTest.scala index c4f1ffe5d..672edd615 100644 --- a/msgpack-core/src/test/scala/org/msgpack/core/MessageUnpackerTest.scala +++ b/msgpack-core/src/test/scala/org/msgpack/core/MessageUnpackerTest.scala @@ -685,7 +685,7 @@ class MessageUnpackerTest extends MessagePackSpec { got shouldBe expected } - Seq("あ", "aあ", "あa", "あいうえおかきくけこさしすせそ").foreach { s => + Seq("\u3042", "a\u3042", "\u3042a", "\u3042\u3044\u3046\u3048\u304A\u304B\u304D\u304F\u3051\u3053\u3055\u3057\u3059\u305B\u305D").foreach { s => Seq(8185, 8186, 8187, 8188, 16377, 16378, 16379, 16380).foreach { n => check(s, n)} } } From 7b3d64f36204af0f5a5bbe9770b39402e15a94fd Mon Sep 17 00:00:00 2001 From: Mitsunori Komatsu Date: Sun, 1 Nov 2015 22:09:45 +0900 Subject: [PATCH 132/234] Handle trailing zeros of BigDecimal in MessagePackGenerator --- .../org/msgpack/jackson/dataformat/MessagePackGenerator.java | 2 +- .../msgpack/jackson/dataformat/MessagePackGeneratorTest.java | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackGenerator.java b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackGenerator.java index 9ba9a5ac3..189197209 100644 --- a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackGenerator.java +++ b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackGenerator.java @@ -244,7 +244,7 @@ private void packBigDecimal(BigDecimal decimal) if (failedToPackAsBI) { double doubleValue = decimal.doubleValue(); //Check to make sure this BigDecimal can be represented as a double - if (!decimal.toEngineeringString().equals(BigDecimal.valueOf(doubleValue).toEngineeringString())) { + if (!decimal.stripTrailingZeros().toEngineeringString().equals(BigDecimal.valueOf(doubleValue).toEngineeringString())) { throw new IllegalArgumentException("MessagePack cannot serialize a BigDecimal that can't be represented as double. " + decimal); } messagePacker.packDouble(doubleValue); diff --git a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackGeneratorTest.java b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackGeneratorTest.java index 68eaa4557..b88d0d645 100644 --- a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackGeneratorTest.java +++ b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackGeneratorTest.java @@ -285,9 +285,11 @@ public void testBigDecimal() { double d0 = 1.23456789; double d1 = 1.23450000000000000000006789; + String d2 = "12.30"; List bigDecimals = Arrays.asList( BigDecimal.valueOf(d0), BigDecimal.valueOf(d1), + new BigDecimal(d2), BigDecimal.valueOf(Double.MIN_VALUE), BigDecimal.valueOf(Double.MAX_VALUE), BigDecimal.valueOf(Double.MIN_NORMAL) @@ -296,9 +298,10 @@ public void testBigDecimal() byte[] bytes = mapper.writeValueAsBytes(bigDecimals); MessageUnpacker unpacker = MessagePack.newDefaultUnpacker(bytes); - assertEquals(5, unpacker.unpackArrayHeader()); + assertEquals(bigDecimals.size(), unpacker.unpackArrayHeader()); assertEquals(d0, unpacker.unpackDouble(), 0.000000000000001); assertEquals(d1, unpacker.unpackDouble(), 0.000000000000001); + assertEquals(Double.valueOf(d2), unpacker.unpackDouble(), 0.000000000000001); assertEquals(Double.MIN_VALUE, unpacker.unpackDouble(), 0.000000000000001); assertEquals(Double.MAX_VALUE, unpacker.unpackDouble(), 0.000000000000001); assertEquals(Double.MIN_NORMAL, unpacker.unpackDouble(), 0.000000000000001); From 5d2bac11b2f56665521627f320d9054b9f940e57 Mon Sep 17 00:00:00 2001 From: Mitsunori Komatsu Date: Sun, 1 Nov 2015 22:47:29 +0900 Subject: [PATCH 133/234] Update the version of jackson-databind to 2.6.3 --- project/Build.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/Build.scala b/project/Build.scala index 1b3f32efd..3687c74fc 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -135,7 +135,7 @@ object Build extends Build { ) val jacksonLib = Seq( - "com.fasterxml.jackson.core" % "jackson-databind" % "2.5.3", + "com.fasterxml.jackson.core" % "jackson-databind" % "2.6.3", junitInterface, "org.apache.commons" % "commons-math3" % "3.4.1" % "test" ) From d43c4087a38776625f1e2ec2e507913e0207646c Mon Sep 17 00:00:00 2001 From: Mitsunori Komatsu Date: Mon, 2 Nov 2015 23:47:15 +0900 Subject: [PATCH 134/234] Setting version to 0.7.0 --- version.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.sbt b/version.sbt index ee25b71c8..c92acc8ad 100644 --- a/version.sbt +++ b/version.sbt @@ -1 +1 @@ -version in ThisBuild := "0.7.0-M7-SNAPSHOT" \ No newline at end of file +version in ThisBuild := "0.7.0" \ No newline at end of file From e40d59f4833b8b9afb9ea95fdb923cbfd9a525b2 Mon Sep 17 00:00:00 2001 From: Mitsunori Komatsu Date: Mon, 2 Nov 2015 23:48:34 +0900 Subject: [PATCH 135/234] Setting version to 0.7.1-SNAPSHOT --- version.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.sbt b/version.sbt index c92acc8ad..890da3daa 100644 --- a/version.sbt +++ b/version.sbt @@ -1 +1 @@ -version in ThisBuild := "0.7.0" \ No newline at end of file +version in ThisBuild := "0.7.1-SNAPSHOT" \ No newline at end of file From 382845bc6e433761be83f42065ed098adc837799 Mon Sep 17 00:00:00 2001 From: Chandraprakash Sharma Date: Wed, 4 Nov 2015 19:18:16 +0900 Subject: [PATCH 136/234] Fixed: asShort in LongValueImpl should check isInShortRange instead of isInByteRange --- .../java/org/msgpack/value/impl/ImmutableLongValueImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableLongValueImpl.java b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableLongValueImpl.java index c83bda332..872b97af0 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableLongValueImpl.java +++ b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableLongValueImpl.java @@ -158,7 +158,7 @@ public byte asByte() @Override public short asShort() { - if (!isInByteRange()) { + if (!isInShortRange()) { throw new MessageIntegerOverflowException(value); } return (short) value; From 919ab704831000930b85a4d6260e68d957ce7098 Mon Sep 17 00:00:00 2001 From: Chandraprakash Sharma Date: Tue, 10 Nov 2015 11:01:57 +0900 Subject: [PATCH 137/234] added tests for integer value range checks and casts --- .../scala/org/msgpack/value/ValueTest.scala | 31 ++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/msgpack-core/src/test/scala/org/msgpack/value/ValueTest.scala b/msgpack-core/src/test/scala/org/msgpack/value/ValueTest.scala index e21c387fb..2d23090ca 100644 --- a/msgpack-core/src/test/scala/org/msgpack/value/ValueTest.scala +++ b/msgpack-core/src/test/scala/org/msgpack/value/ValueTest.scala @@ -16,7 +16,6 @@ package org.msgpack.value import java.math.BigInteger - import org.msgpack.core._ import scala.util.parsing.json.JSON @@ -97,5 +96,35 @@ class ValueTest extends MessagePackSpec } + "check appropriate range for integers" in { + import ValueFactory._ + import java.lang.Byte + import java.lang.Short + + newInteger(Byte.MAX_VALUE).asByte() shouldBe Byte.MAX_VALUE + newInteger(Byte.MIN_VALUE).asByte() shouldBe Byte.MIN_VALUE + newInteger(Short.MAX_VALUE).asShort() shouldBe Short.MAX_VALUE + newInteger(Short.MIN_VALUE).asShort() shouldBe Short.MIN_VALUE + newInteger(Integer.MAX_VALUE).asInt() shouldBe Integer.MAX_VALUE + newInteger(Integer.MIN_VALUE).asInt() shouldBe Integer.MIN_VALUE + intercept[MessageIntegerOverflowException] { + newInteger(Byte.MAX_VALUE+1).asByte() + } + intercept[MessageIntegerOverflowException] { + newInteger(Byte.MIN_VALUE-1).asByte() + } + intercept[MessageIntegerOverflowException] { + newInteger(Short.MAX_VALUE+1).asShort() + } + intercept[MessageIntegerOverflowException] { + newInteger(Short.MIN_VALUE-1).asShort() + } + intercept[MessageIntegerOverflowException] { + newInteger(Integer.MAX_VALUE+1).asInt() + } + intercept[MessageIntegerOverflowException] { + newInteger(Integer.MIN_VALUE-1).asInt() + } + } } } From 6b9d5d315d2e7277e694f2ac2b80b2547fc44904 Mon Sep 17 00:00:00 2001 From: Chandraprakash Sharma Date: Tue, 10 Nov 2015 11:18:43 +0900 Subject: [PATCH 138/234] fixed integer literal related issue in integer range check test --- msgpack-core/src/test/scala/org/msgpack/value/ValueTest.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/msgpack-core/src/test/scala/org/msgpack/value/ValueTest.scala b/msgpack-core/src/test/scala/org/msgpack/value/ValueTest.scala index 2d23090ca..6cb7af603 100644 --- a/msgpack-core/src/test/scala/org/msgpack/value/ValueTest.scala +++ b/msgpack-core/src/test/scala/org/msgpack/value/ValueTest.scala @@ -120,10 +120,10 @@ class ValueTest extends MessagePackSpec newInteger(Short.MIN_VALUE-1).asShort() } intercept[MessageIntegerOverflowException] { - newInteger(Integer.MAX_VALUE+1).asInt() + newInteger(Integer.MAX_VALUE+1.toLong).asInt() } intercept[MessageIntegerOverflowException] { - newInteger(Integer.MIN_VALUE-1).asInt() + newInteger(Integer.MIN_VALUE-1.toLong).asInt() } } } From b6d5ff116fdebe8ec77fb8237ab602a87ea888f5 Mon Sep 17 00:00:00 2001 From: Mitsunori Komatsu Date: Thu, 12 Nov 2015 23:19:17 +0900 Subject: [PATCH 139/234] Add release notes for 0.7.0 --- RELEASE_NOTES.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index 1419dae66..fdb624745 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -1,5 +1,10 @@ # Release Notes +* 0.7.0 + * Support non-string key in jackson-dataformat-msgpack + * Update the version of jackson-databind to 2.6.3 + * Several bug fixes + * 0.7.0-M6 * Add a prototype of Value implementation * Apply strict coding style From 6058ec2369588b3710d5a2b67c9097c955216176 Mon Sep 17 00:00:00 2001 From: Mitsunori Komatsu Date: Thu, 12 Nov 2015 23:25:17 +0900 Subject: [PATCH 140/234] Add release notes for 0.7.1 --- RELEASE_NOTES.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index fdb624745..6b691c476 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -1,5 +1,8 @@ # Release Notes +* 0.7.1 + * Fix ImmutableLongValueImpl#asShort [#287](https://github.com/msgpack/msgpack-java/pull/287) + * 0.7.0 * Support non-string key in jackson-dataformat-msgpack * Update the version of jackson-databind to 2.6.3 From 342a4ea6e86544a7b4584df660bc1470a0c7d8d5 Mon Sep 17 00:00:00 2001 From: Mitsunori Komatsu Date: Thu, 12 Nov 2015 23:28:44 +0900 Subject: [PATCH 141/234] Setting version to 0.7.1 --- version.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.sbt b/version.sbt index 890da3daa..26dd39738 100644 --- a/version.sbt +++ b/version.sbt @@ -1 +1 @@ -version in ThisBuild := "0.7.1-SNAPSHOT" \ No newline at end of file +version in ThisBuild := "0.7.1" \ No newline at end of file From 44550d11499fb9eef8c617b63fb8743d709c7cfd Mon Sep 17 00:00:00 2001 From: Mitsunori Komatsu Date: Thu, 12 Nov 2015 23:29:20 +0900 Subject: [PATCH 142/234] Setting version to 0.7.2-SNAPSHOT --- version.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.sbt b/version.sbt index 26dd39738..984699500 100644 --- a/version.sbt +++ b/version.sbt @@ -1 +1 @@ -version in ThisBuild := "0.7.1" \ No newline at end of file +version in ThisBuild := "0.7.2-SNAPSHOT" \ No newline at end of file From 51c4aed466626246049da4435fabdae75dec1164 Mon Sep 17 00:00:00 2001 From: Mitsunori Komatsu Date: Thu, 12 Nov 2015 23:38:04 +0900 Subject: [PATCH 143/234] Update msgpack-java versions in README --- README.md | 6 +++--- msgpack-jackson/README.md | 18 +++++++++++++++--- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index e3805fde9..c66b668d7 100644 --- a/README.md +++ b/README.md @@ -18,13 +18,13 @@ For Maven users: org.msgpack msgpack-core - 0.7.0-M6 + 0.7.1 ``` For sbt users: ``` -libraryDependencies += "org.msgpack" % "msgpack-core" % "0.7.0-M6" +libraryDependencies += "org.msgpack" % "msgpack-core" % "0.7.1" ``` For gradle users: @@ -34,7 +34,7 @@ repositories { } dependencies { - compile 'org.msgpack:msgpack-core:0.7.0-M6' + compile 'org.msgpack:msgpack-core:0.7.1' } ``` diff --git a/msgpack-jackson/README.md b/msgpack-jackson/README.md index c6509845f..55ed19233 100644 --- a/msgpack-jackson/README.md +++ b/msgpack-jackson/README.md @@ -3,18 +3,30 @@ This Jackson extension library handles reading and writing of data encoded in [MessagePack](http://msgpack.org/) data format. It extends standard Jackson streaming API (`JsonFactory`, `JsonParser`, `JsonGenerator`), and as such works seamlessly with all the higher level data abstractions (data binding, tree model, and pluggable extensions). For the details of Jackson-annotations, please see https://github.com/FasterXML/jackson-annotations. -## Maven dependency +## Install -To use this module on Maven-based projects, use following dependency: +### Maven ``` org.msgpack jackson-dataformat-msgpack - 0.7.0-p9 + 0.7.1 ``` +### Gradle +``` +repositories { + mavenCentral() +} + +dependencies { + compile 'org.msgpack:jackson-dataformat-msgpack:0.7.1' +} +``` + + ## Usage Only thing you need to do is to instantiate MessagePackFactory and pass it to the constructor of ObjectMapper. From af98ae9c747256ad504d59ef58c4e326964e7d4f Mon Sep 17 00:00:00 2001 From: Mitsunori Komatsu Date: Sun, 15 Nov 2015 17:42:38 +0900 Subject: [PATCH 144/234] Avoid to flush an extra buffer when the string isn't too large in MessagePack#packString --- .../java/org/msgpack/core/MessagePack.java | 16 +++++++++++++++ .../java/org/msgpack/core/MessagePacker.java | 14 +++++++++++++ .../org/msgpack/core/MessagePackerTest.scala | 20 +++++++++++++++++++ 3 files changed, 50 insertions(+) diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessagePack.java b/msgpack-core/src/main/java/org/msgpack/core/MessagePack.java index 70140c8ed..d7e05369c 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/MessagePack.java +++ b/msgpack-core/src/main/java/org/msgpack/core/MessagePack.java @@ -50,6 +50,7 @@ public static class Config private final int stringEncoderBufferSize; private final int stringDecoderBufferSize; private final int packerBufferSize; + private final int packerLargeStringThreshold; private final int packerRawDataCopyingThreshold; public Config( @@ -61,6 +62,7 @@ public Config( int stringEncoderBufferSize, int stringDecoderBufferSize, int packerBufferSize, + int packerLargeStringLengthThreshold, int packerRawDataCopyingThreshold) { checkArgument(packerBufferSize > 0, "packer buffer size must be larger than 0: " + packerBufferSize); @@ -75,6 +77,7 @@ public Config( this.stringEncoderBufferSize = stringEncoderBufferSize; this.stringDecoderBufferSize = stringDecoderBufferSize; this.packerBufferSize = packerBufferSize; + this.packerLargeStringThreshold = packerLargeStringLengthThreshold; this.packerRawDataCopyingThreshold = packerRawDataCopyingThreshold; } @@ -133,6 +136,11 @@ public int getPackerBufferSize() return packerBufferSize; } + public int getPackerLargeStringLengthThreshold() + { + return packerLargeStringThreshold; + } + public int getPackerRawDataCopyingThreshold() { return packerRawDataCopyingThreshold; @@ -154,6 +162,7 @@ public static class ConfigBuilder private int stringEncoderBufferSize = 8192; private int stringDecoderBufferSize = 8192; private int packerBufferSize = 8192; + private int packerLargeStringLengthThreshold = 512; private int packerRawDataCopyingThreshold = 512; public Config build() @@ -167,6 +176,7 @@ public Config build() stringEncoderBufferSize, stringDecoderBufferSize, packerBufferSize, + packerLargeStringLengthThreshold, packerRawDataCopyingThreshold ); } @@ -219,6 +229,12 @@ public ConfigBuilder packerBufferSize(int size) return this; } + public ConfigBuilder packerLargeStringThreshold(int threshold) + { + this.packerLargeStringLengthThreshold = threshold; + return this; + } + public ConfigBuilder packerRawDataCopyingThreshold(int threshold) { this.packerRawDataCopyingThreshold = threshold; diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessagePacker.java b/msgpack-core/src/main/java/org/msgpack/core/MessagePacker.java index ca40540fa..078d83107 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/MessagePacker.java +++ b/msgpack-core/src/main/java/org/msgpack/core/MessagePacker.java @@ -442,6 +442,14 @@ public MessagePacker packDouble(double v) return this; } + private void packSmallString(String s) + throws IOException + { + byte[] bytes = s.getBytes("UTF-8"); + packRawStringHeader(bytes.length); + writePayload(bytes); + } + /** * Pack the input String in UTF-8 encoding * @@ -457,6 +465,12 @@ public MessagePacker packString(String s) return this; } + if (s.length() < config.getPackerLargeStringLengthThreshold()) { + // Write the length and payload of small string to the buffer so that it avoids an extra flush of buffer + packSmallString(s); + return this; + } + CharBuffer in = CharBuffer.wrap(s); prepareEncoder(); diff --git a/msgpack-core/src/test/scala/org/msgpack/core/MessagePackerTest.scala b/msgpack-core/src/test/scala/org/msgpack/core/MessagePackerTest.scala index bc2ec9d1c..8ec2487cc 100644 --- a/msgpack-core/src/test/scala/org/msgpack/core/MessagePackerTest.scala +++ b/msgpack-core/src/test/scala/org/msgpack/core/MessagePackerTest.scala @@ -22,6 +22,7 @@ import org.msgpack.core.buffer.{ChannelBufferOutput, OutputStreamBufferOutput} import org.msgpack.value.ValueFactory import xerial.core.io.IOUtil +import scala.compat.Platform import scala.util.Random /** @@ -235,6 +236,25 @@ class MessagePackerTest up1.hasNext shouldBe false up1.close } + + "pack a lot of String within expected time" in { + val count = 500000 + + def measureDuration(outputStream: java.io.OutputStream) : Long = { + val packer = MessagePack.newDefaultPacker(outputStream) + val start = Platform.currentTime + for (i <- 0 to count) { + packer.packString("0123456789ABCDEF") + } + packer.close + Platform.currentTime - start + } + + val baseDuration = measureDuration(new ByteArrayOutputStream()) + val (_, fileOutput) = createTempFileWithOutputStream + val targetDuration = measureDuration(fileOutput) + targetDuration shouldBe <= (baseDuration * 3) + } } "compute totalWrittenBytes" in { From 4f5b594e2ac31985165185c7f1d020549f2d9b48 Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Sun, 15 Nov 2015 09:01:48 -0800 Subject: [PATCH 145/234] Simplify the config object --- .../java/org/msgpack/core/MessagePack.java | 101 +++++------------- .../java/org/msgpack/core/MessagePacker.java | 14 +-- .../org/msgpack/core/MessageUnpacker.java | 22 ++-- 3 files changed, 46 insertions(+), 91 deletions(-) diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessagePack.java b/msgpack-core/src/main/java/org/msgpack/core/MessagePack.java index 70140c8ed..1ca58a64e 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/MessagePack.java +++ b/msgpack-core/src/main/java/org/msgpack/core/MessagePack.java @@ -42,21 +42,36 @@ public class MessagePack */ public static class Config { - private final boolean readStringAsBinary; - private final boolean readBinaryAsString; - private final CodingErrorAction onMalFormedInput; - private final CodingErrorAction onUnmappableCharacter; - private final int maxUnpackStringSize; - private final int stringEncoderBufferSize; - private final int stringDecoderBufferSize; - private final int packerBufferSize; - private final int packerRawDataCopyingThreshold; + /** + * allow unpackBinaryHeader to read str format family (default:true) + */ + public final boolean readStringAsBinary; + /** + * allow unpackRawStringHeader and unpackString to read bin format family (default: true) + */ + public final boolean readBinaryAsString; + /** + * Action when encountered a malformed input + */ + public final CodingErrorAction actionOnMalFormedInput; + /** + * Action when an unmappable character is found + */ + public final CodingErrorAction actionOnUnmappableCharacter; + /** + * unpackString size limit. (default: Integer.MAX_VALUE) + */ + public final int maxUnpackStringSize; + public final int stringEncoderBufferSize; + public final int stringDecoderBufferSize; + public final int packerBufferSize; + public final int packerRawDataCopyingThreshold; public Config( boolean readStringAsBinary, boolean readBinaryAsString, - CodingErrorAction onMalFormedInput, - CodingErrorAction onUnmappableCharacter, + CodingErrorAction actionOnMalFormedInput, + CodingErrorAction actionOnUnmappableCharacter, int maxUnpackStringSize, int stringEncoderBufferSize, int stringDecoderBufferSize, @@ -69,74 +84,14 @@ public Config( this.readStringAsBinary = readStringAsBinary; this.readBinaryAsString = readBinaryAsString; - this.onMalFormedInput = onMalFormedInput; - this.onUnmappableCharacter = onUnmappableCharacter; + this.actionOnMalFormedInput = actionOnMalFormedInput; + this.actionOnUnmappableCharacter = actionOnUnmappableCharacter; this.maxUnpackStringSize = maxUnpackStringSize; this.stringEncoderBufferSize = stringEncoderBufferSize; this.stringDecoderBufferSize = stringDecoderBufferSize; this.packerBufferSize = packerBufferSize; this.packerRawDataCopyingThreshold = packerRawDataCopyingThreshold; } - - /** - * allow unpackBinaryHeader to read str format family (default:true) - */ - public boolean isReadStringAsBinary() - { - return readStringAsBinary; - } - - /** - * allow unpackRawStringHeader and unpackString to read bin format family (default: true) - */ - public boolean isReadBinaryAsString() - { - return readBinaryAsString; - } - - /** - * Action when encountered a malformed input - */ - public CodingErrorAction getActionOnMalFormedInput() - { - return onMalFormedInput; - } - - /** - * Action when an unmappable character is found - */ - public CodingErrorAction getActionOnUnmappableCharacter() - { - return onUnmappableCharacter; - } - - /** - * unpackString size limit. (default: Integer.MAX_VALUE) - */ - public int getMaxUnpackStringSize() - { - return maxUnpackStringSize; - } - - public int getStringEncoderBufferSize() - { - return stringEncoderBufferSize; - } - - public int getStringDecoderBufferSize() - { - return stringDecoderBufferSize; - } - - public int getPackerBufferSize() - { - return packerBufferSize; - } - - public int getPackerRawDataCopyingThreshold() - { - return packerRawDataCopyingThreshold; - } } /** diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessagePacker.java b/msgpack-core/src/main/java/org/msgpack/core/MessagePacker.java index ca40540fa..cf425b830 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/MessagePacker.java +++ b/msgpack-core/src/main/java/org/msgpack/core/MessagePacker.java @@ -150,7 +150,7 @@ public long getTotalWrittenBytes() private void prepareEncoder() { if (encoder == null) { - this.encoder = MessagePack.UTF8.newEncoder().onMalformedInput(config.getActionOnMalFormedInput()).onUnmappableCharacter(config.getActionOnMalFormedInput()); + this.encoder = MessagePack.UTF8.newEncoder().onMalformedInput(config.actionOnMalFormedInput).onUnmappableCharacter(config.actionOnMalFormedInput); } } @@ -158,7 +158,7 @@ private void prepareBuffer() throws IOException { if (buffer == null) { - buffer = out.next(config.getPackerBufferSize()); + buffer = out.next(config.packerBufferSize); } } @@ -196,7 +196,7 @@ private void ensureCapacity(int numBytesToWrite) { if (buffer == null || position + numBytesToWrite >= buffer.size()) { flush(); - buffer = out.next(Math.max(config.getPackerBufferSize(), numBytesToWrite)); + buffer = out.next(Math.max(config.packerBufferSize, numBytesToWrite)); } } @@ -490,8 +490,8 @@ public MessagePacker packString(String s) } if (cr.isError()) { - if ((cr.isMalformed() && config.getActionOnMalFormedInput() == CodingErrorAction.REPORT) || - (cr.isUnmappable() && config.getActionOnUnmappableCharacter() == CodingErrorAction.REPORT)) { + if ((cr.isMalformed() && config.actionOnMalFormedInput == CodingErrorAction.REPORT) || + (cr.isUnmappable() && config.actionOnUnmappableCharacter == CodingErrorAction.REPORT)) { cr.throwException(); } } @@ -649,7 +649,7 @@ public MessagePacker writePayload(ByteBuffer src) throws IOException { int len = src.remaining(); - if (len >= config.getPackerRawDataCopyingThreshold()) { + if (len >= config.packerRawDataCopyingThreshold) { // Use the source ByteBuffer directly to avoid memory copy // First, flush the current buffer contents @@ -687,7 +687,7 @@ public MessagePacker writePayload(byte[] src) public MessagePacker writePayload(byte[] src, int off, int len) throws IOException { - if (len >= config.getPackerRawDataCopyingThreshold()) { + if (len >= config.packerRawDataCopyingThreshold) { // Use the input array directory to avoid memory copy // Flush the current buffer contents diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java b/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java index 43f6eede6..c50d183ee 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java +++ b/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java @@ -172,10 +172,10 @@ public long getTotalReadBytes() private void prepareDecoder() { if (decoder == null) { - decodeBuffer = CharBuffer.allocate(config.getStringDecoderBufferSize()); + decodeBuffer = CharBuffer.allocate(config.stringDecoderBufferSize); decoder = MessagePack.UTF8.newDecoder() - .onMalformedInput(config.getActionOnMalFormedInput()) - .onUnmappableCharacter(config.getActionOnUnmappableCharacter()); + .onMalformedInput(config.actionOnMalFormedInput) + .onUnmappableCharacter(config.actionOnUnmappableCharacter); } } @@ -1011,8 +1011,8 @@ public String unpackString() { int strLen = unpackRawStringHeader(); if (strLen > 0) { - if (strLen > config.getMaxUnpackStringSize()) { - throw new MessageSizeException(String.format("cannot unpack a String of size larger than %,d: %,d", config.getMaxUnpackStringSize(), strLen), strLen); + if (strLen > config.maxUnpackStringSize) { + throw new MessageSizeException(String.format("cannot unpack a String of size larger than %,d: %,d", config.maxUnpackStringSize, strLen), strLen); } prepareDecoder(); @@ -1030,7 +1030,7 @@ public String unpackString() int readLen = Math.min(position < buffer.size() ? buffer.size() - position : buffer.size(), strLen - cursor); if (hasIncompleteMultiBytes) { // Prepare enough buffer for decoding multi-bytes character right after running into incomplete one - readLen = Math.min(config.getStringDecoderBufferSize(), strLen - cursor); + readLen = Math.min(config.stringDecoderBufferSize, strLen - cursor); } if (!ensure(readLen)) { throw new EOFException(); @@ -1055,7 +1055,7 @@ public String unpackString() if (cr.isUnderflow() && bb.hasRemaining()) { // input buffer doesn't have enough bytes for multi bytes characters - if (config.getActionOnMalFormedInput() == CodingErrorAction.REPORT) { + if (config.actionOnMalFormedInput == CodingErrorAction.REPORT) { throw new MalformedInputException(strLen); } hasIncompleteMultiBytes = true; @@ -1064,8 +1064,8 @@ public String unpackString() } if (cr.isError()) { - if ((cr.isMalformed() && config.getActionOnMalFormedInput() == CodingErrorAction.REPORT) || - (cr.isUnmappable() && config.getActionOnUnmappableCharacter() == CodingErrorAction.REPORT)) { + if ((cr.isMalformed() && config.actionOnMalFormedInput == CodingErrorAction.REPORT) || + (cr.isUnmappable() && config.actionOnUnmappableCharacter == CodingErrorAction.REPORT)) { cr.throwException(); } } @@ -1204,7 +1204,7 @@ public int unpackRawStringHeader() return len; } - if (config.isReadBinaryAsString()) { + if (config.readBinaryAsString) { len = readBinaryHeader(b); if (len >= 0) { return len; @@ -1225,7 +1225,7 @@ public int unpackBinaryHeader() return len; } - if (config.isReadStringAsBinary()) { + if (config.readStringAsBinary) { len = readStringHeader(b); if (len >= 0) { return len; From 78ab7c1a27f3d58202dbb2871add3cb11a14c90a Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Sun, 15 Nov 2015 10:08:31 -0800 Subject: [PATCH 146/234] Use build.sbt to reduce Scala code --- build.sbt | 115 +++++++++++++ .../dataformat/MessagePackParserTest.java | 6 +- project/Build.scala | 152 ------------------ project/build.properties | 2 +- project/plugins.sbt | 4 +- 5 files changed, 122 insertions(+), 157 deletions(-) create mode 100644 build.sbt delete mode 100644 project/Build.scala diff --git a/build.sbt b/build.sbt new file mode 100644 index 000000000..c796a80a4 --- /dev/null +++ b/build.sbt @@ -0,0 +1,115 @@ +import de.johoop.findbugs4sbt.ReportType + +organization := "org.msgpack" +organizationName := "MessagePack" +organizationHomepage := Some(new + URL("http://msgpack.org/")) +description := "MessagePack for Java" +scalaVersion in Global := "2.11.7" +logBuffered in Test := false +autoScalaLibrary := false +crossPaths := false + +// For performance testing, ensure each test run one-by-one +concurrentRestrictions in Global := Seq( + Tags.limit(Tags.Test, 1) +) + +incOptions := incOptions.value.withNameHashing(true) + +// JVM options for building +scalacOptions ++= Seq("-encoding", "UTF-8", "-deprecation", "-unchecked", "-target:jvm-1.6", "-feature") + +javaOptions in Test ++= Seq("-ea") +javacOptions in (Compile, compile) ++= Seq("-encoding", "UTF-8", "-Xlint:unchecked", "-Xlint:deprecation", "-source", "1.6", "-target", "1.6") + +// Use lenient validation mode when generating Javadoc (for Java8) +javacOptions in doc := { + val opts = Seq("-source", "1.6") + if (scala.util.Properties.isJavaAtLeast("1.8")) { + opts ++ Seq("-Xdoclint:none") + } + else { + opts + } +} + +val junitInterface = "com.novocode" % "junit-interface" % "0.11" % "test" + +// Project settings +lazy val root = Project(id = "msgpack-java", base = file(".")) + .settings( + // Do not publish the root project + publishArtifact := false, + publish := {}, + publishLocal := {}, + findbugs := { + // do not run findbugs for the root project + } + ).aggregate(msgpackCore, msgpackJackson) + +lazy val msgpackCore = Project(id = "msgpack-core", base = file("msgpack-core")) + .settings( + description := "Core library of the MessagePack for Java", + libraryDependencies ++= Seq( + // msgpack-core should have no external dependencies + junitInterface, + "org.scalatest" %% "scalatest" % "2.2.4" % "test", + "org.scalacheck" %% "scalacheck" % "1.12.2" % "test", + "org.xerial" % "xerial-core" % "3.3.6" % "test", + "org.msgpack" % "msgpack" % "0.6.11" % "test", + "commons-codec" % "commons-codec" % "1.10" % "test", + "com.typesafe.akka" %% "akka-actor" % "2.3.9" % "test" + ) + ) + +lazy val msgpackJackson = Project(id = "msgpack-jackson", base = file("msgpack-jackson")) + .settings( + name := "jackson-dataformat-msgpack", + description := "Jackson extension that adds support for MessagePack", + libraryDependencies ++= Seq( + "com.fasterxml.jackson.core" % "jackson-databind" % "2.6.3", + junitInterface, + "org.apache.commons" % "commons-math3" % "3.4.1" % "test" + ), + testOptions += Tests.Argument(TestFrameworks.JUnit, "-v") + ).dependsOn(msgpackCore) + + +// Release settings + +import sbtrelease.ReleasePlugin.autoImport.ReleaseTransformations._ + +releaseTagName := { + (version in ThisBuild).value +} +releaseProcess := Seq[ReleaseStep]( + checkSnapshotDependencies, + inquireVersions, + runClean, + runTest, + setReleaseVersion, + commitReleaseVersion, + tagRelease, + ReleaseStep(action = Command.process("publishSigned", _)), + setNextVersion, + commitNextVersion, + ReleaseStep(action = Command.process("sonatypeReleaseAll", _)), + pushChanges + ) + +// Jacoco code coverage report +jacoco.settings +parallelExecution in jacoco.Config := false + +// Find bugs +findbugsSettings +findbugsReportType := Some(ReportType.FancyHtml) +findbugsReportPath := Some(crossTarget.value / "findbugs" / "report.html") + +// Style check config: (sbt-jchekcstyle) +jcheckStyleConfig := "facebook" + +// Run jcheckstyle both for main and test codes +compile <<= (compile in Compile) dependsOn (jcheckStyle in Compile) +compile <<= (compile in Test) dependsOn (jcheckStyle in Test) diff --git a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackParserTest.java b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackParserTest.java index b47278d8f..96af2de32 100644 --- a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackParserTest.java +++ b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackParserTest.java @@ -484,8 +484,10 @@ public void testReadPrimitiveObjectViaObjectMapper() ObjectMapper objectMapper = new ObjectMapper(new MessagePackFactory()); objectMapper.configure(JsonParser.Feature.AUTO_CLOSE_SOURCE, false); assertEquals("foo", objectMapper.readValue(in, new TypeReference() {})); - assertEquals(Long.MAX_VALUE, objectMapper.readValue(in, new TypeReference() {})); - assertEquals(3.14, objectMapper.readValue(in, new TypeReference() {})); + long l = objectMapper.readValue(in, new TypeReference() {}); + assertEquals(Long.MAX_VALUE, l); + double d = objectMapper.readValue(in, new TypeReference() {}); + assertEquals(3.14, d, 0.001); byte[] bs = objectMapper.readValue(in, new TypeReference() {}); assertEquals(bytes.length, bs.length); assertEquals(bytes[0], bs[0]); diff --git a/project/Build.scala b/project/Build.scala deleted file mode 100644 index 3687c74fc..000000000 --- a/project/Build.scala +++ /dev/null @@ -1,152 +0,0 @@ -/* - * Copyright 2012 Taro L. Saito - * - * 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. - */ - - -import de.johoop.findbugs4sbt.ReportType -import sbt._ -import Keys._ -import de.johoop.findbugs4sbt.FindBugs._ -import de.johoop.jacoco4sbt._ -import JacocoPlugin._ -import sbtrelease.ReleasePlugin._ -import sbtrelease.ReleaseStateTransformations._ -import sbtrelease.ReleaseStep -import scala.util.Properties -import xerial.sbt.jcheckstyle.JCheckStyle.JCheckStyleKeys._ - -object Build extends Build { - - val SCALA_VERSION = "2.11.6" - - lazy val buildSettings = Defaults.coreDefaultSettings ++ - releaseSettings ++ - findbugsSettings ++ - jacoco.settings ++ - Seq[Setting[_]]( - organization := "org.msgpack", - organizationName := "MessagePack", - organizationHomepage := Some(new URL("http://msgpack.org/")), - description := "MessagePack for Java", - scalaVersion in Global := SCALA_VERSION, - logBuffered in Test := false, - //parallelExecution in Test := false, - autoScalaLibrary := false, - crossPaths := false, - concurrentRestrictions in Global := Seq( - Tags.limit(Tags.Test, 1) - ), - ReleaseKeys.tagName <<= (version in ThisBuild) map (v => v), - ReleaseKeys.releaseProcess := Seq[ReleaseStep]( - checkSnapshotDependencies, - inquireVersions, - runClean, - runTest, - setReleaseVersion, - commitReleaseVersion, - tagRelease, - ReleaseStep(action = Command.process("publishSigned", _)), - setNextVersion, - commitNextVersion, - ReleaseStep(action = Command.process("sonatypeReleaseAll", _)), - pushChanges - ), - parallelExecution in jacoco.Config := false, - // Since sbt-0.13.2 - incOptions := incOptions.value.withNameHashing(true), - //resolvers += Resolver.mavenLocal, - scalacOptions ++= Seq("-encoding", "UTF-8", "-deprecation", "-unchecked", "-target:jvm-1.6", "-feature"), - javaOptions in Test ++= Seq("-ea"), - javacOptions in (Compile, compile) ++= Seq("-encoding", "UTF-8", "-Xlint:unchecked", "-Xlint:deprecation", "-source", "1.6", "-target", "1.6"), - javacOptions in doc := { - val opts = Seq("-source", "1.6") - if (Properties.isJavaAtLeast("1.8")) - opts ++ Seq("-Xdoclint:none") - else - opts - }, - findbugsReportType := Some(ReportType.FancyHtml), - findbugsReportPath := Some(crossTarget.value / "findbugs" / "report.html"), - jcheckStyleConfig := "facebook", - compile <<= (compile in Compile) dependsOn (jcheckStyle in Compile), - compile <<= (compile in Test) dependsOn (jcheckStyle in Test) - ) - - import Dependencies._ - - lazy val root = Project( - id = "msgpack-java", - base = file("."), - settings = buildSettings ++ Seq( - // Do not publish the root project - publishArtifact := false, - publish := {}, - publishLocal := {}, - findbugs := { - // do not run findbugs for the root project - } - ) - ).aggregate(msgpackCore, msgpackJackson) - - lazy val msgpackCore = Project( - id = "msgpack-core", - base = file("msgpack-core"), - settings = buildSettings ++ Seq( - description := "Core library of the MessagePack for Java", - libraryDependencies ++= testLib - ) - ) - - lazy val msgpackJackson = Project( - id = "msgpack-jackson", - base = file("msgpack-jackson"), - settings = buildSettings ++ Seq( - name := "jackson-dataformat-msgpack", - description := "Jackson extension that adds support for MessagePack", - libraryDependencies ++= jacksonLib, - testOptions += Tests.Argument(TestFrameworks.JUnit, "-v") - ) - ).dependsOn(msgpackCore) - - object Dependencies { - - val junitInterface = "com.novocode" % "junit-interface" % "0.11" % "test" - - val testLib = Seq( - "org.scalatest" %% "scalatest" % "2.2.4" % "test", - "org.scalacheck" %% "scalacheck" % "1.12.2" % "test", - "org.xerial" % "xerial-core" % "3.3.6" % "test", - "org.msgpack" % "msgpack" % "0.6.11" % "test", - junitInterface, - "commons-codec" % "commons-codec" % "1.10" % "test", - "com.typesafe.akka" %% "akka-actor"% "2.3.9" % "test" - ) - - val jacksonLib = Seq( - "com.fasterxml.jackson.core" % "jackson-databind" % "2.6.3", - junitInterface, - "org.apache.commons" % "commons-math3" % "3.4.1" % "test" - ) - } - -} - - - - - - - - diff --git a/project/build.properties b/project/build.properties index 07b0ebbcd..02cb92b32 100755 --- a/project/build.properties +++ b/project/build.properties @@ -1,2 +1,2 @@ -sbt.version=0.13.8 +sbt.version=0.13.9 diff --git a/project/plugins.sbt b/project/plugins.sbt index 0d70c54a7..be8535f05 100755 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,7 +1,7 @@ -addSbtPlugin("com.github.gseitz" % "sbt-release" % "0.8.5") +addSbtPlugin("com.github.gseitz" % "sbt-release" % "1.0.0") -addSbtPlugin("org.xerial.sbt" % "sbt-sonatype" % "0.5.0") +addSbtPlugin("org.xerial.sbt" % "sbt-sonatype" % "1.0") addSbtPlugin("com.jsuereth" % "sbt-pgp" % "1.0.0") From 1381a513426d20c2046d44badfb2cd5a6f33cecc Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Sun, 15 Nov 2015 10:11:38 -0800 Subject: [PATCH 147/234] Fix code style --- build.sbt | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/build.sbt b/build.sbt index c796a80a4..b99461796 100644 --- a/build.sbt +++ b/build.sbt @@ -2,8 +2,7 @@ import de.johoop.findbugs4sbt.ReportType organization := "org.msgpack" organizationName := "MessagePack" -organizationHomepage := Some(new - URL("http://msgpack.org/")) +organizationHomepage := Some(new URL("http://msgpack.org/")) description := "MessagePack for Java" scalaVersion in Global := "2.11.7" logBuffered in Test := false @@ -78,11 +77,9 @@ lazy val msgpackJackson = Project(id = "msgpack-jackson", base = file("msgpack-j // Release settings -import sbtrelease.ReleasePlugin.autoImport.ReleaseTransformations._ +import ReleaseTransformations._ -releaseTagName := { - (version in ThisBuild).value -} +releaseTagName := { (version in ThisBuild).value } releaseProcess := Seq[ReleaseStep]( checkSnapshotDependencies, inquireVersions, From 0dabac51e9b1190ad7de6e07efcf6c630e89ebb8 Mon Sep 17 00:00:00 2001 From: Mitsunori Komatsu Date: Mon, 16 Nov 2015 23:44:15 +0900 Subject: [PATCH 148/234] Benchmark the performance more precisely --- .../org/msgpack/core/MessagePackerTest.scala | 26 ++++++++++++------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/msgpack-core/src/test/scala/org/msgpack/core/MessagePackerTest.scala b/msgpack-core/src/test/scala/org/msgpack/core/MessagePackerTest.scala index 8ec2487cc..f598a133f 100644 --- a/msgpack-core/src/test/scala/org/msgpack/core/MessagePackerTest.scala +++ b/msgpack-core/src/test/scala/org/msgpack/core/MessagePackerTest.scala @@ -22,7 +22,6 @@ import org.msgpack.core.buffer.{ChannelBufferOutput, OutputStreamBufferOutput} import org.msgpack.value.ValueFactory import xerial.core.io.IOUtil -import scala.compat.Platform import scala.util.Random /** @@ -238,22 +237,29 @@ class MessagePackerTest } "pack a lot of String within expected time" in { - val count = 500000 + val count = 20000 - def measureDuration(outputStream: java.io.OutputStream) : Long = { + def measureDuration(outputStream: java.io.OutputStream) = { val packer = MessagePack.newDefaultPacker(outputStream) - val start = Platform.currentTime - for (i <- 0 to count) { + var i = 0 + while (i < count) { packer.packString("0123456789ABCDEF") + i += 1 } packer.close - Platform.currentTime - start } - val baseDuration = measureDuration(new ByteArrayOutputStream()) - val (_, fileOutput) = createTempFileWithOutputStream - val targetDuration = measureDuration(fileOutput) - targetDuration shouldBe <= (baseDuration * 3) + val t = time("packString into OutputStream", repeat = 10) { + block("byte-array-output-stream") { + measureDuration(new ByteArrayOutputStream()) + } + + block("file-output-stream") { + val (_, fileOutput) = createTempFileWithOutputStream + measureDuration(fileOutput) + } + } + t("file-output-stream").averageWithoutMinMax shouldBe < (t("byte-array-output-stream").averageWithoutMinMax * 4) } } From 5c80a861d928d69eff4685271c59d9c8bbe6cedf Mon Sep 17 00:00:00 2001 From: Mitsunori Komatsu Date: Mon, 16 Nov 2015 23:45:33 +0900 Subject: [PATCH 149/234] Change the param name of configuration to `packerSmallStringOptimizationThreshold` --- .../java/org/msgpack/core/MessagePack.java | 18 +++++++++--------- .../java/org/msgpack/core/MessagePacker.java | 4 ++-- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessagePack.java b/msgpack-core/src/main/java/org/msgpack/core/MessagePack.java index d7e05369c..1b9d580b5 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/MessagePack.java +++ b/msgpack-core/src/main/java/org/msgpack/core/MessagePack.java @@ -50,7 +50,7 @@ public static class Config private final int stringEncoderBufferSize; private final int stringDecoderBufferSize; private final int packerBufferSize; - private final int packerLargeStringThreshold; + private final int packerSmallStringOptimizationThreshold; // This parameter is subject to change private final int packerRawDataCopyingThreshold; public Config( @@ -62,7 +62,7 @@ public Config( int stringEncoderBufferSize, int stringDecoderBufferSize, int packerBufferSize, - int packerLargeStringLengthThreshold, + int packerSmallStringOptimizationThreshold, int packerRawDataCopyingThreshold) { checkArgument(packerBufferSize > 0, "packer buffer size must be larger than 0: " + packerBufferSize); @@ -77,7 +77,7 @@ public Config( this.stringEncoderBufferSize = stringEncoderBufferSize; this.stringDecoderBufferSize = stringDecoderBufferSize; this.packerBufferSize = packerBufferSize; - this.packerLargeStringThreshold = packerLargeStringLengthThreshold; + this.packerSmallStringOptimizationThreshold = packerSmallStringOptimizationThreshold; this.packerRawDataCopyingThreshold = packerRawDataCopyingThreshold; } @@ -136,9 +136,9 @@ public int getPackerBufferSize() return packerBufferSize; } - public int getPackerLargeStringLengthThreshold() + public int getPackerSmallStringOptimizationThreshold() { - return packerLargeStringThreshold; + return packerSmallStringOptimizationThreshold; } public int getPackerRawDataCopyingThreshold() @@ -162,7 +162,7 @@ public static class ConfigBuilder private int stringEncoderBufferSize = 8192; private int stringDecoderBufferSize = 8192; private int packerBufferSize = 8192; - private int packerLargeStringLengthThreshold = 512; + private int packerSmallStringOptimizationThreshold = 512; // This parameter is subject to change private int packerRawDataCopyingThreshold = 512; public Config build() @@ -176,7 +176,7 @@ public Config build() stringEncoderBufferSize, stringDecoderBufferSize, packerBufferSize, - packerLargeStringLengthThreshold, + packerSmallStringOptimizationThreshold, packerRawDataCopyingThreshold ); } @@ -229,9 +229,9 @@ public ConfigBuilder packerBufferSize(int size) return this; } - public ConfigBuilder packerLargeStringThreshold(int threshold) + public ConfigBuilder packerSmallStringOptimizationThreshold(int threshold) { - this.packerLargeStringLengthThreshold = threshold; + this.packerSmallStringOptimizationThreshold = threshold; return this; } diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessagePacker.java b/msgpack-core/src/main/java/org/msgpack/core/MessagePacker.java index 078d83107..11d673dcd 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/MessagePacker.java +++ b/msgpack-core/src/main/java/org/msgpack/core/MessagePacker.java @@ -445,7 +445,7 @@ public MessagePacker packDouble(double v) private void packSmallString(String s) throws IOException { - byte[] bytes = s.getBytes("UTF-8"); + byte[] bytes = s.getBytes(MessagePack.UTF8); packRawStringHeader(bytes.length); writePayload(bytes); } @@ -465,7 +465,7 @@ public MessagePacker packString(String s) return this; } - if (s.length() < config.getPackerLargeStringLengthThreshold()) { + if (s.length() < config.getPackerSmallStringOptimizationThreshold()) { // Write the length and payload of small string to the buffer so that it avoids an extra flush of buffer packSmallString(s); return this; From f90efe8364896eaa7e0df30953c7fc83c134286d Mon Sep 17 00:00:00 2001 From: xuwei-k <6b656e6a69@gmail.com> Date: Sun, 22 Nov 2015 04:47:16 +0900 Subject: [PATCH 150/234] fix build.sbt --- build.sbt | 129 ++++++++++++++++++++++++++---------------------------- 1 file changed, 61 insertions(+), 68 deletions(-) diff --git a/build.sbt b/build.sbt index b99461796..365719b83 100644 --- a/build.sbt +++ b/build.sbt @@ -1,43 +1,71 @@ import de.johoop.findbugs4sbt.ReportType +import ReleaseTransformations._ -organization := "org.msgpack" -organizationName := "MessagePack" -organizationHomepage := Some(new URL("http://msgpack.org/")) -description := "MessagePack for Java" -scalaVersion in Global := "2.11.7" -logBuffered in Test := false -autoScalaLibrary := false -crossPaths := false - -// For performance testing, ensure each test run one-by-one -concurrentRestrictions in Global := Seq( - Tags.limit(Tags.Test, 1) +val buildSettings = findbugsSettings ++ jacoco.settings ++ Seq[Setting[_]]( + organization := "org.msgpack", + organizationName := "MessagePack", + organizationHomepage := Some(new URL("http://msgpack.org/")), + description := "MessagePack for Java", + scalaVersion := "2.11.7", + logBuffered in Test := false, + autoScalaLibrary := false, + crossPaths := false, + // For performance testing, ensure each test run one-by-one + concurrentRestrictions in Global := Seq( + Tags.limit(Tags.Test, 1) + ), + // JVM options for building + scalacOptions ++= Seq("-encoding", "UTF-8", "-deprecation", "-unchecked", "-target:jvm-1.6", "-feature"), + javaOptions in Test ++= Seq("-ea"), + javacOptions in (Compile, compile) ++= Seq("-encoding", "UTF-8", "-Xlint:unchecked", "-Xlint:deprecation", "-source", "1.6", "-target", "1.6"), + // Use lenient validation mode when generating Javadoc (for Java8) + javacOptions in doc := { + val opts = Seq("-source", "1.6") + if (scala.util.Properties.isJavaAtLeast("1.8")) { + opts ++ Seq("-Xdoclint:none") + } + else { + opts + } + }, + // Release settings + releaseTagName := { (version in ThisBuild).value }, + releaseProcess := Seq[ReleaseStep]( + checkSnapshotDependencies, + inquireVersions, + runClean, + runTest, + setReleaseVersion, + commitReleaseVersion, + tagRelease, + ReleaseStep(action = Command.process("publishSigned", _)), + setNextVersion, + commitNextVersion, + ReleaseStep(action = Command.process("sonatypeReleaseAll", _)), + pushChanges + ), + + // Jacoco code coverage report + parallelExecution in jacoco.Config := false, + + // Find bugs + findbugsReportType := Some(ReportType.FancyHtml), + findbugsReportPath := Some(crossTarget.value / "findbugs" / "report.html"), + + // Style check config: (sbt-jchekcstyle) + jcheckStyleConfig := "facebook", + + // Run jcheckstyle both for main and test codes + compile <<= (compile in Compile) dependsOn (jcheckStyle in Compile), + compile <<= (compile in Test) dependsOn (jcheckStyle in Test) ) -incOptions := incOptions.value.withNameHashing(true) - -// JVM options for building -scalacOptions ++= Seq("-encoding", "UTF-8", "-deprecation", "-unchecked", "-target:jvm-1.6", "-feature") - -javaOptions in Test ++= Seq("-ea") -javacOptions in (Compile, compile) ++= Seq("-encoding", "UTF-8", "-Xlint:unchecked", "-Xlint:deprecation", "-source", "1.6", "-target", "1.6") - -// Use lenient validation mode when generating Javadoc (for Java8) -javacOptions in doc := { - val opts = Seq("-source", "1.6") - if (scala.util.Properties.isJavaAtLeast("1.8")) { - opts ++ Seq("-Xdoclint:none") - } - else { - opts - } -} - val junitInterface = "com.novocode" % "junit-interface" % "0.11" % "test" // Project settings lazy val root = Project(id = "msgpack-java", base = file(".")) .settings( + buildSettings, // Do not publish the root project publishArtifact := false, publish := {}, @@ -49,6 +77,7 @@ lazy val root = Project(id = "msgpack-java", base = file(".")) lazy val msgpackCore = Project(id = "msgpack-core", base = file("msgpack-core")) .settings( + buildSettings, description := "Core library of the MessagePack for Java", libraryDependencies ++= Seq( // msgpack-core should have no external dependencies @@ -64,6 +93,7 @@ lazy val msgpackCore = Project(id = "msgpack-core", base = file("msgpack-core")) lazy val msgpackJackson = Project(id = "msgpack-jackson", base = file("msgpack-jackson")) .settings( + buildSettings, name := "jackson-dataformat-msgpack", description := "Jackson extension that adds support for MessagePack", libraryDependencies ++= Seq( @@ -73,40 +103,3 @@ lazy val msgpackJackson = Project(id = "msgpack-jackson", base = file("msgpack-j ), testOptions += Tests.Argument(TestFrameworks.JUnit, "-v") ).dependsOn(msgpackCore) - - -// Release settings - -import ReleaseTransformations._ - -releaseTagName := { (version in ThisBuild).value } -releaseProcess := Seq[ReleaseStep]( - checkSnapshotDependencies, - inquireVersions, - runClean, - runTest, - setReleaseVersion, - commitReleaseVersion, - tagRelease, - ReleaseStep(action = Command.process("publishSigned", _)), - setNextVersion, - commitNextVersion, - ReleaseStep(action = Command.process("sonatypeReleaseAll", _)), - pushChanges - ) - -// Jacoco code coverage report -jacoco.settings -parallelExecution in jacoco.Config := false - -// Find bugs -findbugsSettings -findbugsReportType := Some(ReportType.FancyHtml) -findbugsReportPath := Some(crossTarget.value / "findbugs" / "report.html") - -// Style check config: (sbt-jchekcstyle) -jcheckStyleConfig := "facebook" - -// Run jcheckstyle both for main and test codes -compile <<= (compile in Compile) dependsOn (jcheckStyle in Compile) -compile <<= (compile in Test) dependsOn (jcheckStyle in Test) From 1751ba3da5de027c82a01f600ba8144466a79cdb Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Mon, 21 Dec 2015 17:13:09 +0900 Subject: [PATCH 151/234] Update sbt-extra --- sbt | 381 +++++++++++++++++++++++++++++++++++------------------------- 1 file changed, 224 insertions(+), 157 deletions(-) mode change 100755 => 100644 sbt diff --git a/sbt b/sbt old mode 100755 new mode 100644 index 7c9358235..c475bc64b --- a/sbt +++ b/sbt @@ -1,36 +1,27 @@ #!/usr/bin/env bash # # A more capable sbt runner, coincidentally also called sbt. -# Author: Paul Phillips +# Author: Paul Phillips + +set -o pipefail # todo - make this dynamic -declare -r sbt_release_version="0.13.8" -declare -r sbt_unreleased_version="0.13.8-SNAPSHOT" # -sbt-dev doesn't work at present +declare -r sbt_release_version="0.13.9" +declare -r sbt_unreleased_version="0.13.9" declare -r buildProps="project/build.properties" -declare sbt_jar sbt_dir sbt_create sbt_launch_dir -declare scala_version java_home sbt_explicit_version -declare verbose debug quiet noshare batch trace_level log_level -declare sbt_saved_stty - -echoerr () { [[ -z "$quiet" ]] && echo "$@" >&2; } -vlog () { [[ -n "$verbose$debug" ]] && echoerr "$@"; } -dlog () { [[ -n "$debug" ]] && echoerr "$@"; } - -# we'd like these set before we get around to properly processing arguments -for arg in "$@"; do - case "$arg" in - -q|-quiet) quiet=true ;; - -d|-debug) debug=true ;; - -v|-verbose) verbose=true ;; - *) ;; - esac -done +declare sbt_jar sbt_dir sbt_create sbt_version +declare scala_version sbt_explicit_version +declare verbose noshare batch trace_level log_level +declare sbt_saved_stty debugUs + +echoerr () { echo >&2 "$@"; } +vlog () { [[ -n "$verbose" ]] && echoerr "$@"; } # spaces are possible, e.g. sbt.version = 0.13.0 build_props_sbt () { [[ -r "$buildProps" ]] && \ - grep '^sbt\.version' "$buildProps" | tr '=' ' ' | awk '{ print $2; }' + grep '^sbt\.version' "$buildProps" | tr '=\r' ' ' | awk '{ print $2; }' } update_build_props_sbt () { @@ -41,31 +32,24 @@ update_build_props_sbt () { perl -pi -e "s/^sbt\.version\b.*\$/sbt.version=${ver}/" "$buildProps" grep -q '^sbt.version[ =]' "$buildProps" || printf "\nsbt.version=%s\n" "$ver" >> "$buildProps" - echoerr "!!!" - echoerr "!!! Updated file $buildProps setting sbt.version to: $ver" - echoerr "!!! Previous value was: $old" - echoerr "!!!" + vlog "!!!" + vlog "!!! Updated file $buildProps setting sbt.version to: $ver" + vlog "!!! Previous value was: $old" + vlog "!!!" } } -sbt_version () { - if [[ -n "$sbt_explicit_version" ]]; then - echo "$sbt_explicit_version" - else - local v="$(build_props_sbt)" - if [[ -n "$v" ]]; then - echo "$v" - else - echo "$sbt_release_version" - fi - fi +set_sbt_version () { + sbt_version="${sbt_explicit_version:-$(build_props_sbt)}" + [[ -n "$sbt_version" ]] || sbt_version=$sbt_release_version + export sbt_version } # restore stty settings (echo in particular) onSbtRunnerExit() { [[ -n "$sbt_saved_stty" ]] || return - dlog "" - dlog "restoring stty: $sbt_saved_stty" + vlog "" + vlog "restoring stty: $sbt_saved_stty" stty "$sbt_saved_stty" unset sbt_saved_stty } @@ -73,7 +57,7 @@ onSbtRunnerExit() { # save stty and trap exit, to ensure echo is reenabled if we are interrupted. trap onSbtRunnerExit EXIT sbt_saved_stty="$(stty -g 2>/dev/null)" -dlog "Saved stty: $sbt_saved_stty" +vlog "Saved stty: $sbt_saved_stty" # this seems to cover the bases on OSX, and someone will # have to tell me about the others. @@ -119,12 +103,13 @@ init_default_option_file () { declare -r cms_opts="-XX:+CMSClassUnloadingEnabled -XX:+UseConcMarkSweepGC" declare -r jit_opts="-XX:ReservedCodeCacheSize=256m -XX:+TieredCompilation" -declare -r default_jvm_opts="-ea -Dfile.encoding=UTF8 -Xms512m -Xmx1536m -Xss2m $jit_opts $cms_opts" +declare -r default_jvm_opts_common="-Xms512m -Xmx1536m -Xss2m $jit_opts $cms_opts" declare -r noshare_opts="-Dsbt.global.base=project/.sbtboot -Dsbt.boot.directory=project/.boot -Dsbt.ivy.home=project/.ivy" declare -r latest_28="2.8.2" declare -r latest_29="2.9.3" -declare -r latest_210="2.10.3" -declare -r latest_211="2.11.6" +declare -r latest_210="2.10.5" +declare -r latest_211="2.11.7" +declare -r latest_212="2.12.0-M3" declare -r script_path="$(get_script_path "$BASH_SOURCE")" declare -r script_name="${script_path##*/}" @@ -133,7 +118,7 @@ declare -r script_name="${script_path##*/}" declare java_cmd="java" declare sbt_opts_file="$(init_default_option_file SBT_OPTS .sbtopts)" declare jvm_opts_file="$(init_default_option_file JVM_OPTS .jvmopts)" -declare sbt_launch_repo="http://typesafe.artifactoryonline.com/typesafe/ivy-releases" +declare sbt_launch_repo="http://repo.typesafe.com/typesafe/ivy-releases" # pull -J and -D options to give to java. declare -a residual_args @@ -144,14 +129,79 @@ declare -a sbt_commands # args to jvm/sbt via files or environment variables declare -a extra_jvm_opts extra_sbt_opts -# if set, use JAVA_HOME over java found in path -[[ -e "$JAVA_HOME/bin/java" ]] && java_cmd="$JAVA_HOME/bin/java" +addJava () { + vlog "[addJava] arg = '$1'" + java_args+=("$1") +} +addSbt () { + vlog "[addSbt] arg = '$1'" + sbt_commands+=("$1") +} +setThisBuild () { + vlog "[addBuild] args = '$@'" + local key="$1" && shift + addSbt "set $key in ThisBuild := $@" +} +addScalac () { + vlog "[addScalac] arg = '$1'" + scalac_args+=("$1") +} +addResidual () { + vlog "[residual] arg = '$1'" + residual_args+=("$1") +} +addResolver () { + addSbt "set resolvers += $1" +} +addDebugger () { + addJava "-Xdebug" + addJava "-Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=$1" +} +setScalaVersion () { + [[ "$1" == *"-SNAPSHOT" ]] && addResolver 'Resolver.sonatypeRepo("snapshots")' + addSbt "++ $1" +} +setJavaHome () { + java_cmd="$1/bin/java" + setThisBuild javaHome "Some(file(\"$1\"))" + export JAVA_HOME="$1" + export JDK_HOME="$1" + export PATH="$JAVA_HOME/bin:$PATH" +} +setJavaHomeQuietly () { + addSbt warn + setJavaHome "$1" + addSbt info +} + +# if set, use JDK_HOME/JAVA_HOME over java found in path +if [[ -e "$JDK_HOME/lib/tools.jar" ]]; then + setJavaHomeQuietly "$JDK_HOME" +elif [[ -e "$JAVA_HOME/bin/java" ]]; then + setJavaHomeQuietly "$JAVA_HOME" +fi # directory to store sbt launchers declare sbt_launch_dir="$HOME/.sbt/launchers" [[ -d "$sbt_launch_dir" ]] || mkdir -p "$sbt_launch_dir" [[ -w "$sbt_launch_dir" ]] || sbt_launch_dir="$(mktemp -d -t sbt_extras_launchers.XXXXXX)" +java_version () { + local version=$("$java_cmd" -version 2>&1 | grep -E -e '(java|openjdk) version' | awk '{ print $3 }' | tr -d \") + vlog "Detected Java version: $version" + echo "${version:2:1}" +} + +# MaxPermSize critical on pre-8 jvms but incurs noisy warning on 8+ +default_jvm_opts () { + local v="$(java_version)" + if [[ $v -ge 8 ]]; then + echo "$default_jvm_opts_common" + else + echo "-XX:MaxPermSize=384m $default_jvm_opts_common" + fi +} + build_props_scala () { if [[ -r "$buildProps" ]]; then versionLine="$(grep '^build.scala.versions' "$buildProps")" @@ -162,22 +212,20 @@ build_props_scala () { execRunner () { # print the arguments one to a line, quoting any containing spaces - [[ "$verbose" || "$debug" ]] && echo "# Executing command line:" && { + vlog "# Executing command line:" && { for arg; do if [[ -n "$arg" ]]; then if printf "%s\n" "$arg" | grep -q ' '; then - printf "\"%s\"\n" "$arg" + printf >&2 "\"%s\"\n" "$arg" else - printf "%s\n" "$arg" + printf >&2 "%s\n" "$arg" fi fi done - echo "" + vlog "" } - if [[ -n "$batch" ]]; then - exec /dev/null; then - curl --fail --silent "$url" --output "$jar" + curl --fail --silent --location "$url" --output "$jar" elif which wget >/dev/null; then wget --quiet -O "$jar" "$url" fi @@ -207,9 +255,8 @@ download_url () { } acquire_sbt_jar () { - for_sbt_version="$(sbt_version)" - sbt_url="$(jar_url "$for_sbt_version")" - sbt_jar="$(jar_file "$for_sbt_version")" + sbt_url="$(jar_url "$sbt_version")" + sbt_jar="$(jar_file "$sbt_version")" [[ -r "$sbt_jar" ]] || download_url "$sbt_url" "$sbt_jar" } @@ -218,11 +265,23 @@ usage () { cat < display stack traces with a max of frames (default: -1, traces suppressed) + -debug-inc enable debugging log for the incremental compiler -no-colors disable ANSI color codes -sbt-create start sbt even if current directory contains no sbt project -sbt-dir path to global settings/plugins directory (default: ~/.sbt/) @@ -234,12 +293,12 @@ Usage: $script_name [options] -batch Disable interactive mode -prompt Set the sbt prompt; in expr, 's' is the State and 'e' is Extracted - # sbt version (default: from $buildProps if present, else latest release) - !!! The only way to accomplish this pre-0.12.0 if there is a build.properties file which - !!! contains an sbt.version property is to update the file on disk. That's what this does. + # sbt version (default: sbt.version from $buildProps if present, otherwise $sbt_release_version) + -sbt-force-latest force the use of the latest release of sbt: $sbt_release_version -sbt-version use the specified version of sbt (default: $sbt_release_version) + -sbt-dev use the latest pre-release version of sbt: $sbt_unreleased_version -sbt-jar use the specified jar as the sbt launcher - -sbt-launch-dir directory to hold sbt launchers (default: $sbt_launch_dir) + -sbt-launch-dir directory to hold sbt launchers (default: ~/.sbt/launchers) -sbt-launch-repo repo url for downloading sbt launcher jar (default: $sbt_launch_repo) # scala version (default: as chosen by sbt) @@ -247,6 +306,7 @@ Usage: $script_name [options] -29 use $latest_29 -210 use $latest_210 -211 use $latest_211 + -212 use $latest_212 -scala-home use the scala build at the specified directory -scala-version use the specified version of scala -binary-version use the specified scala version when searching for dependencies @@ -256,7 +316,7 @@ Usage: $script_name [options] # passing options to the jvm - note it does NOT use JAVA_OPTS due to pollution # The default set is used if JVM_OPTS is unset and no -jvm-opts file is found - $default_jvm_opts + $(default_jvm_opts) JVM_OPTS environment variable holding either the jvm args directly, or the reference to a file containing jvm args if given path is prepended by '@' (e.g. '@/etc/jvmopts') Note: "@"-file is overridden by local '.jvmopts' or '-jvm-opts' argument. @@ -273,34 +333,6 @@ Usage: $script_name [options] EOM } -addJava () { - dlog "[addJava] arg = '$1'" - java_args=( "${java_args[@]}" "$1" ) -} -addSbt () { - dlog "[addSbt] arg = '$1'" - sbt_commands=( "${sbt_commands[@]}" "$1" ) -} -addScalac () { - dlog "[addScalac] arg = '$1'" - scalac_args=( "${scalac_args[@]}" "$1" ) -} -addResidual () { - dlog "[residual] arg = '$1'" - residual_args=( "${residual_args[@]}" "$1" ) -} -addResolver () { - addSbt "set resolvers += $1" -} -addDebugger () { - addJava "-Xdebug" - addJava "-Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=$1" -} -setScalaVersion () { - [[ "$1" == *"-SNAPSHOT" ]] && addResolver 'Resolver.sonatypeRepo("snapshots")' - addSbt "++ $1" -} - process_args () { require_arg () { @@ -314,45 +346,51 @@ process_args () } while [[ $# -gt 0 ]]; do case "$1" in - -h|-help) usage; exit 1 ;; - -v|-verbose) verbose=true && log_level=Info && shift ;; - -d|-debug) debug=true && log_level=Debug && shift ;; - -q|-quiet) quiet=true && log_level=Error && shift ;; - - -trace) require_arg integer "$1" "$2" && trace_level="$2" && shift 2 ;; - -ivy) require_arg path "$1" "$2" && addJava "-Dsbt.ivy.home=$2" && shift 2 ;; - -no-colors) addJava "-Dsbt.log.noformat=true" && shift ;; - -no-share) noshare=true && shift ;; - -sbt-boot) require_arg path "$1" "$2" && addJava "-Dsbt.boot.directory=$2" && shift 2 ;; - -sbt-dir) require_arg path "$1" "$2" && sbt_dir="$2" && shift 2 ;; - -debug-inc) addJava "-Dxsbt.inc.debug=true" && shift ;; - -offline) addSbt "set offline := true" && shift ;; - -jvm-debug) require_arg port "$1" "$2" && addDebugger "$2" && shift 2 ;; - -batch) batch=true && shift ;; - -prompt) require_arg "expr" "$1" "$2" && addSbt "set shellPrompt in ThisBuild := (s => { val e = Project.extract(s) ; $2 })" && shift 2 ;; - - -sbt-create) sbt_create=true && shift ;; - -sbt-jar) require_arg path "$1" "$2" && sbt_jar="$2" && shift 2 ;; - -sbt-version) require_arg version "$1" "$2" && sbt_explicit_version="$2" && shift 2 ;; - -sbt-dev) sbt_explicit_version="$sbt_unreleased_version" && shift ;; --sbt-launch-dir) require_arg path "$1" "$2" && sbt_launch_dir="$2" && shift 2 ;; --sbt-launch-repo) require_arg path "$1" "$2" && sbt_launch_repo="$2" && shift 2 ;; - -scala-version) require_arg version "$1" "$2" && setScalaVersion "$2" && shift 2 ;; --binary-version) require_arg version "$1" "$2" && addSbt "set scalaBinaryVersion in ThisBuild := \"$2\"" && shift 2 ;; - -scala-home) require_arg path "$1" "$2" && addSbt "set every scalaHome := Some(file(\"$2\"))" && shift 2 ;; - -java-home) require_arg path "$1" "$2" && java_cmd="$2/bin/java" && shift 2 ;; - -sbt-opts) require_arg path "$1" "$2" && sbt_opts_file="$2" && shift 2 ;; - -jvm-opts) require_arg path "$1" "$2" && jvm_opts_file="$2" && shift 2 ;; - - -D*) addJava "$1" && shift ;; - -J*) addJava "${1:2}" && shift ;; - -S*) addScalac "${1:2}" && shift ;; - -28) setScalaVersion "$latest_28" && shift ;; - -29) setScalaVersion "$latest_29" && shift ;; - -210) setScalaVersion "$latest_210" && shift ;; - -211) setScalaVersion "$latest_211" && shift ;; - - *) addResidual "$1" && shift ;; + -h|-help) usage; exit 1 ;; + -v) verbose=true && shift ;; + -d) addSbt "--debug" && addSbt debug && shift ;; + -w) addSbt "--warn" && addSbt warn && shift ;; + -q) addSbt "--error" && addSbt error && shift ;; + -x) debugUs=true && shift ;; + -trace) require_arg integer "$1" "$2" && trace_level="$2" && shift 2 ;; + -ivy) require_arg path "$1" "$2" && addJava "-Dsbt.ivy.home=$2" && shift 2 ;; + -no-colors) addJava "-Dsbt.log.noformat=true" && shift ;; + -no-share) noshare=true && shift ;; + -sbt-boot) require_arg path "$1" "$2" && addJava "-Dsbt.boot.directory=$2" && shift 2 ;; + -sbt-dir) require_arg path "$1" "$2" && sbt_dir="$2" && shift 2 ;; + -debug-inc) addJava "-Dxsbt.inc.debug=true" && shift ;; + -offline) addSbt "set offline := true" && shift ;; + -jvm-debug) require_arg port "$1" "$2" && addDebugger "$2" && shift 2 ;; + -batch) batch=true && shift ;; + -prompt) require_arg "expr" "$1" "$2" && setThisBuild shellPrompt "(s => { val e = Project.extract(s) ; $2 })" && shift 2 ;; + + -sbt-create) sbt_create=true && shift ;; + -sbt-jar) require_arg path "$1" "$2" && sbt_jar="$2" && shift 2 ;; + -sbt-version) require_arg version "$1" "$2" && sbt_explicit_version="$2" && shift 2 ;; + -sbt-force-latest) sbt_explicit_version="$sbt_release_version" && shift ;; + -sbt-dev) sbt_explicit_version="$sbt_unreleased_version" && shift ;; + -sbt-launch-dir) require_arg path "$1" "$2" && sbt_launch_dir="$2" && shift 2 ;; + -sbt-launch-repo) require_arg path "$1" "$2" && sbt_launch_repo="$2" && shift 2 ;; + -scala-version) require_arg version "$1" "$2" && setScalaVersion "$2" && shift 2 ;; + -binary-version) require_arg version "$1" "$2" && setThisBuild scalaBinaryVersion "\"$2\"" && shift 2 ;; + -scala-home) require_arg path "$1" "$2" && setThisBuild scalaHome "Some(file(\"$2\"))" && shift 2 ;; + -java-home) require_arg path "$1" "$2" && setJavaHome "$2" && shift 2 ;; + -sbt-opts) require_arg path "$1" "$2" && sbt_opts_file="$2" && shift 2 ;; + -jvm-opts) require_arg path "$1" "$2" && jvm_opts_file="$2" && shift 2 ;; + + -D*) addJava "$1" && shift ;; + -J*) addJava "${1:2}" && shift ;; + -S*) addScalac "${1:2}" && shift ;; + -28) setScalaVersion "$latest_28" && shift ;; + -29) setScalaVersion "$latest_29" && shift ;; + -210) setScalaVersion "$latest_210" && shift ;; + -211) setScalaVersion "$latest_211" && shift ;; + -212) setScalaVersion "$latest_212" && shift ;; + + --debug) addSbt debug && addResidual "$1" && shift ;; + --warn) addSbt warn && addResidual "$1" && shift ;; + --error) addSbt error && addResidual "$1" && shift ;; + *) addResidual "$1" && shift ;; esac done } @@ -379,21 +417,20 @@ else vlog "No extra sbt options have been defined" fi -[[ -n "$extra_sbt_opts" ]] && process_args "${extra_sbt_opts[@]}" +[[ -n "${extra_sbt_opts[*]}" ]] && process_args "${extra_sbt_opts[@]}" # reset "$@" to the residual args set -- "${residual_args[@]}" argumentCount=$# +# set sbt version +set_sbt_version + # only exists in 0.12+ setTraceLevel() { - case "$(sbt_version)" in - "0.7."* | "0.10."* | "0.11."* ) - echoerr "Cannot set trace level in sbt version $(sbt_version)" - ;; - *) - addSbt "set every traceLevel := $trace_level" - ;; + case "$sbt_version" in + "0.7."* | "0.10."* | "0.11."* ) echoerr "Cannot set trace level in sbt version $sbt_version" ;; + *) setThisBuild traceLevel $trace_level ;; esac } @@ -402,9 +439,9 @@ setTraceLevel() { # Update build.properties on disk to set explicit version - sbt gives us no choice [[ -n "$sbt_explicit_version" ]] && update_build_props_sbt "$sbt_explicit_version" -vlog "Detected sbt version $(sbt_version)" +vlog "Detected sbt version $sbt_version" -[[ -n "$scala_version" ]] && echoerr "Overriding scala version to $scala_version" +[[ -n "$scala_version" ]] && vlog "Overriding scala version to $scala_version" # no args - alert them there's stuff in here (( argumentCount > 0 )) || { @@ -438,10 +475,10 @@ if [[ -n "$noshare" ]]; then addJava "$opt" done else - case "$(sbt_version)" in + case "$sbt_version" in "0.7."* | "0.10."* | "0.11."* | "0.12."* ) [[ -n "$sbt_dir" ]] || { - sbt_dir="$HOME/.sbt/$(sbt_version)" + sbt_dir="$HOME/.sbt/$sbt_version" vlog "Using $sbt_dir as sbt dir, -sbt-dir to override." } ;; @@ -460,22 +497,52 @@ elif [[ -n "$JVM_OPTS" && ! ("$JVM_OPTS" =~ ^@.*) ]]; then extra_jvm_opts=( $JVM_OPTS ) else vlog "Using default jvm options" - extra_jvm_opts=( $default_jvm_opts ) + extra_jvm_opts=( $(default_jvm_opts) ) fi # traceLevel is 0.12+ [[ -n "$trace_level" ]] && setTraceLevel +main () { + execRunner "$java_cmd" \ + "${extra_jvm_opts[@]}" \ + "${java_args[@]}" \ + -jar "$sbt_jar" \ + "${sbt_commands[@]}" \ + "${residual_args[@]}" +} -if [[ -n "$log_level" ]] && [[ "$log_level" != Info ]]; then - sbt_commands=("set logLevel in Global := Level.$log_level" "${sbt_commands[@]}") -fi +# sbt inserts this string on certain lines when formatting is enabled: +# val OverwriteLine = "\r\u001BM\u001B[2K" +# ...in order not to spam the console with a million "Resolving" lines. +# Unfortunately that makes it that much harder to work with when +# we're not going to print those lines anyway. We strip that bit of +# line noise, but leave the other codes to preserve color. +mainFiltered () { + local ansiOverwrite='\r\x1BM\x1B[2K' + local excludeRegex=$(egrep -v '^#|^$' ~/.sbtignore | paste -sd'|' -) + + echoLine () { + local line="$1" + local line1="$(echo "$line" | sed -r 's/\r\x1BM\x1B\[2K//g')" # This strips the OverwriteLine code. + local line2="$(echo "$line1" | sed -r 's/\x1B\[[0-9;]*[JKmsu]//g')" # This strips all codes - we test regexes against this. + + if [[ $line2 =~ $excludeRegex ]]; then + [[ -n $debugUs ]] && echo "[X] $line1" + else + [[ -n $debugUs ]] && echo " $line1" || echo "$line1" + fi + } + + echoLine "Starting sbt with output filtering enabled." + main | while read -r line; do echoLine "$line"; done +} +# Only filter if there's a filter file and we don't see a known interactive command. +# Obviously this is super ad hoc but I don't know how to improve on it. Testing whether +# stdin is a terminal is useless because most of my use cases for this filtering are +# exactly when I'm at a terminal, running sbt non-interactively. +shouldFilter () { [[ -f ~/.sbtignore ]] && ! egrep -q '\b(shell|console|consoleProject)\b' <<<"${residual_args[@]}"; } # run sbt -execRunner "$java_cmd" \ - "${extra_jvm_opts[@]}" \ - "${java_args[@]}" \ - -jar "$sbt_jar" \ - "${sbt_commands[@]}" \ - "${residual_args[@]}" +if shouldFilter; then mainFiltered; else main; fi From ae01c51e5ccdd2c834a171e4e14b6b65294f5b97 Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Mon, 21 Dec 2015 17:24:06 +0900 Subject: [PATCH 152/234] chmod +x --- sbt | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 sbt diff --git a/sbt b/sbt old mode 100644 new mode 100755 From 6e01b68e581354dd6502b266b1587576a7d62337 Mon Sep 17 00:00:00 2001 From: Sadayuki Furuhashi Date: Mon, 21 Dec 2015 21:00:22 +0900 Subject: [PATCH 153/234] optimized unpacker buffer --- .../MessageInsufficientBufferException.java | 40 + .../core/MessageNeverUsedFormatException.java | 38 + .../org/msgpack/core/MessageUnpacker.java | 808 ++++++++++-------- .../msgpack/core/buffer/ArrayBufferInput.java | 5 + .../msgpack/core/buffer/ByteBufferInput.java | 5 + .../core/buffer/ChannelBufferInput.java | 5 + .../core/buffer/InputStreamBufferInput.java | 5 + .../msgpack/core/buffer/MessageBuffer.java | 5 + .../core/buffer/MessageBufferInput.java | 7 +- .../core/buffer/MessageBufferReader.java | 122 +++ .../org/msgpack/core/MessagePackTest.scala | 2 +- .../msgpack/core/MessageUnpackerTest.scala | 2 + .../msgpack/core/buffer/ByteStringTest.scala | 2 + 13 files changed, 689 insertions(+), 357 deletions(-) create mode 100644 msgpack-core/src/main/java/org/msgpack/core/MessageInsufficientBufferException.java create mode 100644 msgpack-core/src/main/java/org/msgpack/core/MessageNeverUsedFormatException.java create mode 100644 msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferReader.java diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessageInsufficientBufferException.java b/msgpack-core/src/main/java/org/msgpack/core/MessageInsufficientBufferException.java new file mode 100644 index 000000000..838dc77ab --- /dev/null +++ b/msgpack-core/src/main/java/org/msgpack/core/MessageInsufficientBufferException.java @@ -0,0 +1,40 @@ +// +// MessagePack for Java +// +// 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.core; + +public class MessageInsufficientBufferException + extends MessagePackException +{ + public MessageInsufficientBufferException() + { + super(); + } + + public MessageInsufficientBufferException(String message) + { + super(message); + } + + public MessageInsufficientBufferException(Throwable cause) + { + super(cause); + } + + public MessageInsufficientBufferException(String message, Throwable cause) + { + super(message, cause); + } +} diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessageNeverUsedFormatException.java b/msgpack-core/src/main/java/org/msgpack/core/MessageNeverUsedFormatException.java new file mode 100644 index 000000000..726ffb497 --- /dev/null +++ b/msgpack-core/src/main/java/org/msgpack/core/MessageNeverUsedFormatException.java @@ -0,0 +1,38 @@ +// +// MessagePack for Java +// +// 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.core; + +/** + * Thrown when the input message pack format is invalid + */ +public class MessageNeverUsedFormatException + extends MessageFormatException +{ + public MessageNeverUsedFormatException(Throwable e) + { + super(e); + } + + public MessageNeverUsedFormatException(String message) + { + super(message); + } + + public MessageNeverUsedFormatException(String message, Throwable cause) + { + super(message, cause); + } +} diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java b/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java index c50d183ee..05babb1ce 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java +++ b/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java @@ -17,6 +17,7 @@ import org.msgpack.core.MessagePack.Code; import org.msgpack.core.buffer.MessageBuffer; +import org.msgpack.core.buffer.MessageBufferReader; import org.msgpack.core.buffer.MessageBufferInput; import org.msgpack.value.ImmutableValue; import org.msgpack.value.Value; @@ -74,10 +75,14 @@ public class MessageUnpacker { private static final MessageBuffer EMPTY_BUFFER = MessageBuffer.wrap(new byte[0]); + private static final byte HEAD_BYTE_REQUIRED = (byte) 0xc1; + private final MessagePack.Config config; private MessageBufferInput in; + private byte headByte = HEAD_BYTE_REQUIRED; + /** * Points to the current buffer to read */ @@ -94,19 +99,24 @@ public class MessageUnpacker private long totalReadBytes; /** - * For preserving the next buffer to use + * Extra buffer for fixed-length data at the buffer boundary. At most 17-byte buffer (for FIXEXT16) is required. */ - private MessageBuffer secondaryBuffer = null; + private final MessageBuffer castBuffer = MessageBuffer.newBuffer(24); /** - * Extra buffer for string data at the buffer boundary. Using 17-byte buffer (for FIXEXT16) is sufficient. + * Variable by ensureHeader method. Caller of the method should use this variable to read from returned MessageBuffer. */ - private final MessageBuffer extraBuffer = MessageBuffer.wrap(new byte[24]); + private int readCastBufferPosition; /** - * True if no more data is available from the MessageBufferInput + * For decoding String in unpackString. + */ + private StringBuilder decodeStringBuffer; + + /** + * For decoding String in unpackString. */ - private boolean reachedEOF = false; + private int readingRawRemaining = 0; /** * For decoding String in unpackString. @@ -158,9 +168,9 @@ public MessageBufferInput reset(MessageBufferInput in) this.buffer = EMPTY_BUFFER; this.position = 0; this.totalReadBytes = 0; - this.secondaryBuffer = null; - this.reachedEOF = false; + this.readingRawRemaining = 0; // No need to initialize the already allocated string decoder here since we can reuse it. + return old; } @@ -169,195 +179,118 @@ public long getTotalReadBytes() return totalReadBytes + position; } - private void prepareDecoder() + private byte getHeadByte() + throws IOException { - if (decoder == null) { - decodeBuffer = CharBuffer.allocate(config.stringDecoderBufferSize); - decoder = MessagePack.UTF8.newDecoder() - .onMalformedInput(config.actionOnMalFormedInput) - .onUnmappableCharacter(config.actionOnUnmappableCharacter); + byte b = headByte; + if (b == HEAD_BYTE_REQUIRED) { + b = headByte = readByte(); + if (b == HEAD_BYTE_REQUIRED) { + throw new MessageNeverUsedFormatException("Encountered 0xC1 NEVER_USED byte"); + } } + return b; } - /** - * Relocate the cursor position so that it points to the real buffer - * - * @return true if it succeeds to move the cursor, or false if there is no more buffer to read - * @throws IOException when failed to retrieve next buffer - */ - private boolean ensureBuffer() - throws IOException + private void resetHeadByte() { - while (buffer != null && position >= buffer.size()) { - // Fetch the next buffer - int bufferSize = buffer.size(); - position -= bufferSize; - totalReadBytes += bufferSize; - buffer = takeNextBuffer(); - } - return buffer != null; + headByte = HEAD_BYTE_REQUIRED; } - private MessageBuffer takeNextBuffer() + private void nextBuffer() throws IOException { - if (reachedEOF) { - return null; - } - - MessageBuffer nextBuffer = null; - if (secondaryBuffer == null) { - nextBuffer = in.next(); - } - else { - nextBuffer = secondaryBuffer; - secondaryBuffer = null; - } - - if (nextBuffer == null) { - reachedEOF = true; + MessageBuffer next = in.next(); + if (next == null) { + throw new MessageInsufficientBufferException(); } - return nextBuffer; + totalReadBytes += buffer.size(); + in.release(buffer); + buffer = next; + position = 0; } - /** - * Ensure that the buffer has the data of at least the specified size. - * - * @param byteSizeToRead the data size to be read - * @return if the buffer can have the data of the specified size returns true, or if the input source reached an EOF, it returns false. - * @throws IOException - */ - private boolean ensure(int byteSizeToRead) + private MessageBuffer readCastBuffer(int length) throws IOException { - if (byteSizeToRead == 0) { - return true; - } - - if (!ensureBuffer()) { - return false; - } - - // The buffer contains the data - if (position + byteSizeToRead <= buffer.size()) { - // OK - return true; + int remaining = buffer.size() - position; + if (remaining >= length) { + readCastBufferPosition = position; + position += length; // here assumes following buffer.getXxx never throws exception + return buffer; } + else { + // TODO loop this method until castBuffer is filled + MessageBuffer next = in.next(); + if (next == null) { + throw new MessageInsufficientBufferException(); + } - // When the data is at the boundary - /* - |---(byte size to read) ----| - -- current buffer --| - |--- extra buffer (slice) --|----| - |-------|---------- secondary buffer (slice) ----------------| - - */ - - // If the byte size to read fits within the extra buffer, use the extraBuffer - MessageBuffer newBuffer = byteSizeToRead <= extraBuffer.size() ? extraBuffer : MessageBuffer.newBuffer(byteSizeToRead); - - // Copy the remaining buffer contents to the new buffer - int firstHalfSize = buffer.size() - position; - if (firstHalfSize > 0) { - buffer.copyTo(position, newBuffer, 0, firstHalfSize); - } + // TODO this doesn't work if MessageBuffer is allocated by newDirectBuffer. + // add copy method to MessageBuffer to solve this issue. + castBuffer.putBytes(0, buffer.getArray(), buffer.offset() + position, remaining); + castBuffer.putBytes(remaining, next.getArray(), next.offset(), length - remaining); - // Read the last half contents from the next buffers - int cursor = firstHalfSize; - while (cursor < byteSizeToRead) { - secondaryBuffer = takeNextBuffer(); - if (secondaryBuffer == null) { - return false; // No more buffer to read - } + totalReadBytes += buffer.size(); + in.release(buffer); - // Copy the contents from the secondary buffer to the new buffer - int copyLen = Math.min(byteSizeToRead - cursor, secondaryBuffer.size()); - secondaryBuffer.copyTo(0, newBuffer, cursor, copyLen); + buffer = next; + position = length - remaining; + readCastBufferPosition = 0; - // Truncate the copied part from the secondaryBuffer - secondaryBuffer = copyLen == secondaryBuffer.size() ? null : secondaryBuffer.slice(copyLen, secondaryBuffer.size() - copyLen); - cursor += copyLen; + return castBuffer; } + } - // Replace the current buffer with the new buffer - totalReadBytes += position; - buffer = byteSizeToRead == newBuffer.size() ? newBuffer : newBuffer.slice(0, byteSizeToRead); - position = 0; - - return true; + private static int utf8MultibyteCharacterSize(byte firstByte) + { + System.out.println("first byte: "+(firstByte & 0xff)); + return Integer.numberOfLeadingZeros(~(firstByte & 0xff)); } /** * Returns true true if this unpacker has more elements. * When this returns true, subsequent call to {@link #getNextFormat()} returns an - * MessageFormat instance. If false, {@link #getNextFormat()} will throw an EOFException. + * MessageFormat instance. If false, next {@link #getNextFormat()} call will throw an MessageInsufficientBufferException. * * @return true if this unpacker has more elements to read */ public boolean hasNext() throws IOException { - return ensure(1); + if (buffer.size() <= position) { + MessageBuffer next = in.next(); + if (next == null) { + return false; + } + totalReadBytes += buffer.size(); + in.release(buffer); + buffer = next; + position = 0; + } + return true; } /** * Returns the next MessageFormat type. This method should be called after {@link #hasNext()} returns true. - * If {@link #hasNext()} returns false, calling this method throws {@link java.io.EOFException}. + * If {@link #hasNext()} returns false, calling this method throws {@link MessageInsufficientBufferException}. *

* This method does not proceed the internal cursor. * * @return the next MessageFormat * @throws IOException when failed to read the input data. - * @throws EOFException when the end of file reached, i.e. {@link #hasNext()} == false. + * @throws MessageInsufficientBufferException when the end of file reached, i.e. {@link #hasNext()} == false. */ public MessageFormat getNextFormat() throws IOException { - byte b = lookAhead(); - return MessageFormat.valueOf(b); - } - - /** - * Look-ahead a byte value at the current cursor position. - * This method does not proceed the cursor. - * - * @return - * @throws IOException - */ - private byte lookAhead() - throws IOException - { - if (ensure(1)) { - return buffer.getByte(position); - } - else { - throw new EOFException(); + try { + byte b = getHeadByte(); + return MessageFormat.valueOf(b); } - } - - /** - * Get the head byte value and proceeds the cursor by 1 - */ - private byte consume() - throws IOException - { - byte b = lookAhead(); - position += 1; - return b; - } - - /** - * Proceeds the cursor by the specified byte length - */ - private void consume(int numBytes) - throws IOException - { - assert (numBytes >= 0); - // If position + numBytes becomes negative, it indicates an overflow from Integer.MAX_VALUE. - if (position + numBytes < 0) { - ensureBuffer(); + catch (MessageNeverUsedFormatException ex) { + return MessageFormat.NEVER_USED; } - position += numBytes; } /** @@ -369,81 +302,55 @@ private void consume(int numBytes) private byte readByte() throws IOException { - if (!ensure(1)) { - throw new EOFException("insufficient data length for reading byte value"); + if (buffer.size() > position) { + byte b = buffer.getByte(position); + position++; + return b; + } + else { + nextBuffer(); + if (buffer.size() > 0) { + byte b = buffer.getByte(0); + position = 1; + return b; + } + return readByte(); } - byte b = buffer.getByte(position); - consume(1); - return b; } private short readShort() throws IOException { - if (!ensure(2)) { - throw new EOFException("insufficient data length for reading short value"); - } - short s = buffer.getShort(position); - consume(2); - return s; + MessageBuffer castBuffer = readCastBuffer(2); + return castBuffer.getShort(readCastBufferPosition); } private int readInt() throws IOException { - if (!ensure(4)) { - throw new EOFException("insufficient data length for reading int value"); - } - int i = buffer.getInt(position); - consume(4); - return i; - } - - private float readFloat() - throws IOException - { - if (!ensure(4)) { - throw new EOFException("insufficient data length for reading float value"); - } - float f = buffer.getFloat(position); - consume(4); - return f; + MessageBuffer castBuffer = readCastBuffer(4); + return castBuffer.getInt(readCastBufferPosition); } private long readLong() throws IOException { - if (!ensure(8)) { - throw new EOFException("insufficient data length for reading long value"); - } - long l = buffer.getLong(position); - consume(8); - return l; + MessageBuffer castBuffer = readCastBuffer(8); + return castBuffer.getLong(readCastBufferPosition); } - private double readDouble() + private float readFloat() throws IOException { - if (!ensure(8)) { - throw new EOFException("insufficient data length for reading double value"); - } - double d = buffer.getDouble(position); - consume(8); - return d; + MessageBuffer castBuffer = readCastBuffer(4); + return castBuffer.getFloat(readCastBufferPosition); } - /** - * Skip reading the specified number of bytes. Use this method only if you know skipping data is safe. - * For simply skipping the next value, use {@link #skipValue()}. - * - * @param numBytes - * @throws IOException - */ - public void skipBytes(int numBytes) + private double readDouble() throws IOException { - checkArgument(numBytes >= 0, "skip length must be >= 0: " + numBytes); - consume(numBytes); + MessageBuffer castBuffer = readCastBuffer(8); + return castBuffer.getDouble(readCastBufferPosition); } /** @@ -456,12 +363,9 @@ public void skipValue() { int remainingValues = 1; while (remainingValues > 0) { - if (reachedEOF) { - throw new EOFException(); - } - - MessageFormat f = getNextFormat(); - byte b = consume(); + byte b = getHeadByte(); + MessageFormat f = MessageFormat.valueOf(b); + resetHeadByte(); switch (f) { case POSFIXINT: case NEGFIXINT: @@ -480,62 +384,62 @@ public void skipValue() } case FIXSTR: { int strLen = b & 0x1f; - consume(strLen); + skipPayload(strLen); break; } case INT8: case UINT8: - consume(1); + skipPayload(1); break; case INT16: case UINT16: - consume(2); + skipPayload(2); break; case INT32: case UINT32: case FLOAT32: - consume(4); + skipPayload(4); break; case INT64: case UINT64: case FLOAT64: - consume(8); + skipPayload(8); break; case BIN8: case STR8: - consume(readNextLength8()); + skipPayload(readNextLength8()); break; case BIN16: case STR16: - consume(readNextLength16()); + skipPayload(readNextLength16()); break; case BIN32: case STR32: - consume(readNextLength32()); + skipPayload(readNextLength32()); break; case FIXEXT1: - consume(2); + skipPayload(2); break; case FIXEXT2: - consume(3); + skipPayload(3); break; case FIXEXT4: - consume(5); + skipPayload(5); break; case FIXEXT8: - consume(9); + skipPayload(9); break; case FIXEXT16: - consume(17); + skipPayload(17); break; case EXT8: - consume(readNextLength8() + 1); + skipPayload(readNextLength8() + 1); break; case EXT16: - consume(readNextLength16() + 1); + skipPayload(readNextLength16() + 1); break; case EXT32: - consume(readNextLength32() + 1); + skipPayload(readNextLength32() + 1); break; case ARRAY16: remainingValues += readNextLength16(); @@ -709,8 +613,9 @@ public Variable unpackValue(Variable var) public void unpackNil() throws IOException { - byte b = consume(); + byte b = getHeadByte(); if (b == Code.NIL) { + resetHeadByte(); return; } throw unexpected("Nil", b); @@ -719,66 +624,76 @@ public void unpackNil() public boolean unpackBoolean() throws IOException { - byte b = consume(); + byte b = getHeadByte(); if (b == Code.FALSE) { + resetHeadByte(); return false; } else if (b == Code.TRUE) { + resetHeadByte(); return true; } - throw unexpected("boolean", b); } public byte unpackByte() throws IOException { - byte b = consume(); + byte b = getHeadByte(); if (Code.isFixInt(b)) { + resetHeadByte(); return b; } switch (b) { case Code.UINT8: // unsigned int 8 byte u8 = readByte(); + resetHeadByte(); if (u8 < (byte) 0) { throw overflowU8(u8); } return u8; case Code.UINT16: // unsigned int 16 short u16 = readShort(); + resetHeadByte(); if (u16 < 0 || u16 > Byte.MAX_VALUE) { throw overflowU16(u16); } return (byte) u16; case Code.UINT32: // unsigned int 32 int u32 = readInt(); + resetHeadByte(); if (u32 < 0 || u32 > Byte.MAX_VALUE) { throw overflowU32(u32); } return (byte) u32; case Code.UINT64: // unsigned int 64 long u64 = readLong(); + resetHeadByte(); if (u64 < 0L || u64 > Byte.MAX_VALUE) { throw overflowU64(u64); } return (byte) u64; case Code.INT8: // signed int 8 byte i8 = readByte(); + resetHeadByte(); return i8; case Code.INT16: // signed int 16 short i16 = readShort(); + resetHeadByte(); if (i16 < Byte.MIN_VALUE || i16 > Byte.MAX_VALUE) { throw overflowI16(i16); } return (byte) i16; case Code.INT32: // signed int 32 int i32 = readInt(); + resetHeadByte(); if (i32 < Byte.MIN_VALUE || i32 > Byte.MAX_VALUE) { throw overflowI32(i32); } return (byte) i32; case Code.INT64: // signed int 64 long i64 = readLong(); + resetHeadByte(); if (i64 < Byte.MIN_VALUE || i64 > Byte.MAX_VALUE) { throw overflowI64(i64); } @@ -790,27 +705,32 @@ public byte unpackByte() public short unpackShort() throws IOException { - byte b = consume(); + byte b = getHeadByte(); if (Code.isFixInt(b)) { + resetHeadByte(); return (short) b; } switch (b) { case Code.UINT8: // unsigned int 8 byte u8 = readByte(); + resetHeadByte(); return (short) (u8 & 0xff); case Code.UINT16: // unsigned int 16 short u16 = readShort(); + resetHeadByte(); if (u16 < (short) 0) { throw overflowU16(u16); } return u16; case Code.UINT32: // unsigned int 32 int u32 = readInt(); + resetHeadByte(); if (u32 < 0 || u32 > Short.MAX_VALUE) { throw overflowU32(u32); } return (short) u32; case Code.UINT64: // unsigned int 64 + resetHeadByte(); long u64 = readLong(); if (u64 < 0L || u64 > Short.MAX_VALUE) { throw overflowU64(u64); @@ -818,18 +738,22 @@ public short unpackShort() return (short) u64; case Code.INT8: // signed int 8 byte i8 = readByte(); + resetHeadByte(); return (short) i8; case Code.INT16: // signed int 16 short i16 = readShort(); + resetHeadByte(); return i16; case Code.INT32: // signed int 32 int i32 = readInt(); + resetHeadByte(); if (i32 < Short.MIN_VALUE || i32 > Short.MAX_VALUE) { throw overflowI32(i32); } return (short) i32; case Code.INT64: // signed int 64 long i64 = readLong(); + resetHeadByte(); if (i64 < Short.MIN_VALUE || i64 > Short.MAX_VALUE) { throw overflowI64(i64); } @@ -841,40 +765,49 @@ public short unpackShort() public int unpackInt() throws IOException { - byte b = consume(); + byte b = getHeadByte(); if (Code.isFixInt(b)) { + resetHeadByte(); return (int) b; } switch (b) { case Code.UINT8: // unsigned int 8 byte u8 = readByte(); + resetHeadByte(); return u8 & 0xff; case Code.UINT16: // unsigned int 16 short u16 = readShort(); + resetHeadByte(); return u16 & 0xffff; case Code.UINT32: // unsigned int 32 int u32 = readInt(); if (u32 < 0) { throw overflowU32(u32); } + resetHeadByte(); return u32; case Code.UINT64: // unsigned int 64 long u64 = readLong(); + resetHeadByte(); if (u64 < 0L || u64 > (long) Integer.MAX_VALUE) { throw overflowU64(u64); } return (int) u64; case Code.INT8: // signed int 8 byte i8 = readByte(); + resetHeadByte(); return i8; case Code.INT16: // signed int 16 short i16 = readShort(); + resetHeadByte(); return i16; case Code.INT32: // signed int 32 int i32 = readInt(); + resetHeadByte(); return i32; case Code.INT64: // signed int 64 long i64 = readLong(); + resetHeadByte(); if (i64 < (long) Integer.MIN_VALUE || i64 > (long) Integer.MAX_VALUE) { throw overflowI64(i64); } @@ -886,19 +819,23 @@ public int unpackInt() public long unpackLong() throws IOException { - byte b = consume(); + byte b = getHeadByte(); if (Code.isFixInt(b)) { + resetHeadByte(); return (long) b; } switch (b) { case Code.UINT8: // unsigned int 8 byte u8 = readByte(); + resetHeadByte(); return (long) (u8 & 0xff); case Code.UINT16: // unsigned int 16 short u16 = readShort(); + resetHeadByte(); return (long) (u16 & 0xffff); case Code.UINT32: // unsigned int 32 int u32 = readInt(); + resetHeadByte(); if (u32 < 0) { return (long) (u32 & 0x7fffffff) + 0x80000000L; } @@ -907,21 +844,26 @@ public long unpackLong() } case Code.UINT64: // unsigned int 64 long u64 = readLong(); + resetHeadByte(); if (u64 < 0L) { throw overflowU64(u64); } return u64; case Code.INT8: // signed int 8 byte i8 = readByte(); + resetHeadByte(); return (long) i8; case Code.INT16: // signed int 16 short i16 = readShort(); + resetHeadByte(); return (long) i16; case Code.INT32: // signed int 32 int i32 = readInt(); + resetHeadByte(); return (long) i32; case Code.INT64: // signed int 64 long i64 = readLong(); + resetHeadByte(); return i64; } throw unexpected("Integer", b); @@ -930,19 +872,23 @@ public long unpackLong() public BigInteger unpackBigInteger() throws IOException { - byte b = consume(); + byte b = getHeadByte(); if (Code.isFixInt(b)) { + resetHeadByte(); return BigInteger.valueOf((long) b); } switch (b) { case Code.UINT8: // unsigned int 8 byte u8 = readByte(); + resetHeadByte(); return BigInteger.valueOf((long) (u8 & 0xff)); case Code.UINT16: // unsigned int 16 short u16 = readShort(); + resetHeadByte(); return BigInteger.valueOf((long) (u16 & 0xffff)); case Code.UINT32: // unsigned int 32 int u32 = readInt(); + resetHeadByte(); if (u32 < 0) { return BigInteger.valueOf((long) (u32 & 0x7fffffff) + 0x80000000L); } @@ -951,6 +897,7 @@ public BigInteger unpackBigInteger() } case Code.UINT64: // unsigned int 64 long u64 = readLong(); + resetHeadByte(); if (u64 < 0L) { BigInteger bi = BigInteger.valueOf(u64 + Long.MAX_VALUE + 1L).setBit(63); return bi; @@ -960,15 +907,19 @@ public BigInteger unpackBigInteger() } case Code.INT8: // signed int 8 byte i8 = readByte(); + resetHeadByte(); return BigInteger.valueOf((long) i8); case Code.INT16: // signed int 16 short i16 = readShort(); + resetHeadByte(); return BigInteger.valueOf((long) i16); case Code.INT32: // signed int 32 int i32 = readInt(); + resetHeadByte(); return BigInteger.valueOf((long) i32); case Code.INT64: // signed int 64 long i64 = readLong(); + resetHeadByte(); return BigInteger.valueOf(i64); } throw unexpected("Integer", b); @@ -977,13 +928,15 @@ public BigInteger unpackBigInteger() public float unpackFloat() throws IOException { - byte b = consume(); + byte b = getHeadByte(); switch (b) { case Code.FLOAT32: // float float fv = readFloat(); + resetHeadByte(); return fv; case Code.FLOAT64: // double double dv = readDouble(); + resetHeadByte(); return (float) dv; } throw unexpected("Float", b); @@ -992,13 +945,15 @@ public float unpackFloat() public double unpackDouble() throws IOException { - byte b = consume(); + byte b = getHeadByte(); switch (b) { case Code.FLOAT32: // float float fv = readFloat(); + resetHeadByte(); return (double) fv; case Code.FLOAT64: // double double dv = readDouble(); + resetHeadByte(); return dv; } throw unexpected("Float", b); @@ -1006,107 +961,191 @@ public double unpackDouble() private static final String EMPTY_STRING = ""; + private void resetDecoder() + { + if (decoder == null) { + decodeBuffer = CharBuffer.allocate(config.stringDecoderBufferSize); + decoder = MessagePack.UTF8.newDecoder() + .onMalformedInput(config.actionOnMalFormedInput) + .onUnmappableCharacter(config.actionOnUnmappableCharacter); + } + else { + decoder.reset(); + } + decodeStringBuffer = new StringBuilder(); + } + + /** + * This method is not repeatable. + */ public String unpackString() throws IOException { - int strLen = unpackRawStringHeader(); - if (strLen > 0) { - if (strLen > config.maxUnpackStringSize) { - throw new MessageSizeException(String.format("cannot unpack a String of size larger than %,d: %,d", config.maxUnpackStringSize, strLen), strLen); + if (readingRawRemaining == 0) { + int len = unpackRawStringHeader(); + if (len == 0) { + return EMPTY_STRING; + } + if (len > config.maxUnpackStringSize) { + throw new MessageSizeException(String.format("cannot unpack a String of size larger than %,d: %,d", config.maxUnpackStringSize, len), len); } + if (buffer.size() - position >= len) { + return decodeStringFastPath(len); + } + readingRawRemaining = len; + resetDecoder(); + } - prepareDecoder(); - assert (decoder != null); + assert (decoder != null); - decoder.reset(); + try { + while (readingRawRemaining > 0) { + int bufferRemaining = buffer.size() - position; + if (bufferRemaining >= readingRawRemaining) { + ByteBuffer bb = buffer.toByteBuffer(position, readingRawRemaining); + int bbStartPosition = bb.position(); + decodeBuffer.clear(); - try { - int cursor = 0; - decodeBuffer.clear(); - StringBuilder sb = new StringBuilder(); - - boolean hasIncompleteMultiBytes = false; - while (cursor < strLen) { - int readLen = Math.min(position < buffer.size() ? buffer.size() - position : buffer.size(), strLen - cursor); - if (hasIncompleteMultiBytes) { - // Prepare enough buffer for decoding multi-bytes character right after running into incomplete one - readLen = Math.min(config.stringDecoderBufferSize, strLen - cursor); + CoderResult cr = decoder.decode(bb, decodeBuffer, true); + int readLen = bb.position() - bbStartPosition; + position += readLen; + readingRawRemaining -= readLen; + decodeStringBuffer.append(decodeBuffer.flip()); + + if (cr.isError()) { + handleCoderError(cr); } - if (!ensure(readLen)) { - throw new EOFException(); + if (cr.isUnderflow() && config.actionOnMalFormedInput == CodingErrorAction.REPORT) { + throw new MalformedInputException(cr.length()); } - hasIncompleteMultiBytes = false; - ByteBuffer bb = buffer.toByteBuffer(position, readLen); - int startPos = bb.position(); - - while (bb.hasRemaining()) { - boolean endOfInput = (cursor + readLen) >= strLen; - CoderResult cr = decoder.decode(bb, decodeBuffer, endOfInput); - - if (endOfInput && cr.isUnderflow()) { - cr = decoder.flush(decodeBuffer); - } - - if (cr.isOverflow()) { - // The output CharBuffer has insufficient space - decoder.reset(); - } - - if (cr.isUnderflow() && bb.hasRemaining()) { - // input buffer doesn't have enough bytes for multi bytes characters - if (config.actionOnMalFormedInput == CodingErrorAction.REPORT) { - throw new MalformedInputException(strLen); + if (cr.isOverflow()) { + // go to next loop + } + else { + break; + } + } + else if (bufferRemaining == 0) { + nextBuffer(); + } + else { + ByteBuffer bb = buffer.toByteBuffer(position, bufferRemaining); + int bbStartPosition = bb.position(); + decodeBuffer.clear(); + + CoderResult cr = decoder.decode(bb, decodeBuffer, false); + int readLen = bb.position() - bbStartPosition; + position += readLen; + readingRawRemaining -= readLen; + decodeStringBuffer.append(decodeBuffer.flip()); + + if (cr.isError()) { + handleCoderError(cr); + } + if (cr.isUnderflow() && readLen < bufferRemaining) { + // handle incomplete multibyte character + int incompleteMultiBytes = utf8MultibyteCharacterSize(buffer.getByte(position)); + ByteBuffer multiByteBuffer = ByteBuffer.allocate(incompleteMultiBytes); + buffer.getBytes(position, buffer.size() - position, multiByteBuffer); + + // read until multiByteBuffer is filled + while (true) { + nextBuffer(); + + int more = multiByteBuffer.remaining(); + if (buffer.size() >= more) { + buffer.getBytes(0, more, multiByteBuffer); + position = more; + break; + } + else { + buffer.getBytes(0, buffer.size(), multiByteBuffer); + position = buffer.size(); } - hasIncompleteMultiBytes = true; - // Proceed the cursor with the length already decoded successfully. - readLen = bb.position() - startPos; } - + multiByteBuffer.position(0); + decodeBuffer.clear(); + cr = decoder.decode(multiByteBuffer, decodeBuffer, false); if (cr.isError()) { - if ((cr.isMalformed() && config.actionOnMalFormedInput == CodingErrorAction.REPORT) || - (cr.isUnmappable() && config.actionOnUnmappableCharacter == CodingErrorAction.REPORT)) { + handleCoderError(cr); + } + if (cr.isUnderflow() || cr.isOverflow()) { + // isOverflow or isOverflow must not happen. if happened, throw exception + try { cr.throwException(); + throw new MessageFormatException("Unexpected UTF-8 multibyte sequence"); + } + catch (Exception ex) { + throw new MessageFormatException("Unexpected UTF-8 multibyte sequence", ex); } } - - decodeBuffer.flip(); - sb.append(decodeBuffer); - - decodeBuffer.clear(); - - if (hasIncompleteMultiBytes) { - break; - } + readingRawRemaining -= multiByteBuffer.limit(); + decodeStringBuffer.append(decodeBuffer.flip()); } - - cursor += readLen; - consume(readLen); } + } + return decodeStringBuffer.toString(); + } + catch (CharacterCodingException e) { + throw new MessageStringCodingException(e); + } + } - return sb.toString(); + private void handleCoderError(CoderResult cr) + throws CharacterCodingException + { + if ((cr.isMalformed() && config.actionOnMalFormedInput == CodingErrorAction.REPORT) || + (cr.isUnmappable() && config.actionOnUnmappableCharacter == CodingErrorAction.REPORT)) { + cr.throwException(); + } + } + + private String decodeStringFastPath(int length) + { + if (config.actionOnMalFormedInput == CodingErrorAction.REPLACE && + config.actionOnUnmappableCharacter == CodingErrorAction.REPLACE && + buffer.hasArray()) { + String s = new String(buffer.getArray(), position, length, MessagePack.UTF8); + position += length; + return s; + } + else { + resetDecoder(); + ByteBuffer bb = buffer.toByteBuffer(); + bb.limit(position + length); + bb.position(position); + CharBuffer cb; + try { + cb = decoder.decode(bb); } catch (CharacterCodingException e) { throw new MessageStringCodingException(e); } - } - else { - return EMPTY_STRING; + position += length; + return cb.toString(); } } public int unpackArrayHeader() throws IOException { - byte b = consume(); + byte b = getHeadByte(); if (Code.isFixedArray(b)) { // fixarray + resetHeadByte(); return b & 0x0f; } switch (b) { - case Code.ARRAY16: // array 16 - return readNextLength16(); - case Code.ARRAY32: // array 32 - return readNextLength32(); + case Code.ARRAY16: { // array 16 + int len = readNextLength16(); + resetHeadByte(); + return len; + } + case Code.ARRAY32: { // array 32 + int len = readNextLength32(); + resetHeadByte(); + return len; + } } throw unexpected("Array", b); } @@ -1114,15 +1153,22 @@ public int unpackArrayHeader() public int unpackMapHeader() throws IOException { - byte b = consume(); + byte b = getHeadByte(); if (Code.isFixedMap(b)) { // fixmap + resetHeadByte(); return b & 0x0f; } switch (b) { - case Code.MAP16: // map 16 - return readNextLength16(); - case Code.MAP32: // map 32 - return readNextLength32(); + case Code.MAP16: { // map 16 + int len = readNextLength16(); + resetHeadByte(); + return len; + } + case Code.MAP32: { // map 32 + int len = readNextLength32(); + resetHeadByte(); + return len; + } } throw unexpected("Map", b); } @@ -1130,31 +1176,58 @@ public int unpackMapHeader() public ExtensionTypeHeader unpackExtensionTypeHeader() throws IOException { - byte b = consume(); + byte b = getHeadByte(); switch (b) { - case Code.FIXEXT1: - return new ExtensionTypeHeader(readByte(), 1); - case Code.FIXEXT2: - return new ExtensionTypeHeader(readByte(), 2); - case Code.FIXEXT4: - return new ExtensionTypeHeader(readByte(), 4); - case Code.FIXEXT8: - return new ExtensionTypeHeader(readByte(), 8); - case Code.FIXEXT16: - return new ExtensionTypeHeader(readByte(), 16); - case Code.EXT8: { - int length = readNextLength8(); + case Code.FIXEXT1: { + byte type = readByte(); + resetHeadByte(); + return new ExtensionTypeHeader(type, 1); + } + case Code.FIXEXT2: { + byte type = readByte(); + resetHeadByte(); + return new ExtensionTypeHeader(type, 2); + } + case Code.FIXEXT4: { + byte type = readByte(); + resetHeadByte(); + return new ExtensionTypeHeader(type, 4); + } + case Code.FIXEXT8: { byte type = readByte(); + resetHeadByte(); + return new ExtensionTypeHeader(type, 8); + } + case Code.FIXEXT16: { + byte type = readByte(); + resetHeadByte(); + return new ExtensionTypeHeader(type, 16); + } + case Code.EXT8: { + MessageBuffer castBuffer = readCastBuffer(2); + resetHeadByte(); + int u8 = castBuffer.getByte(readCastBufferPosition); + int length = u8 & 0xff; + byte type = castBuffer.getByte(readCastBufferPosition + 1); return new ExtensionTypeHeader(type, length); } case Code.EXT16: { - int length = readNextLength16(); - byte type = readByte(); + MessageBuffer castBuffer = readCastBuffer(3); + resetHeadByte(); + int u16 = castBuffer.getShort(readCastBufferPosition); + int length = u16 & 0xffff; + byte type = castBuffer.getByte(readCastBufferPosition + 2); return new ExtensionTypeHeader(type, length); } case Code.EXT32: { - int length = readNextLength32(); - byte type = readByte(); + MessageBuffer castBuffer = readCastBuffer(5); + resetHeadByte(); + int u32 = castBuffer.getInt(readCastBufferPosition); + if (u32 < 0) { + throw overflowU32Size(u32); + } + int length = u32; + byte type = castBuffer.getByte(readCastBufferPosition + 4); return new ExtensionTypeHeader(type, length); } } @@ -1162,7 +1235,7 @@ public ExtensionTypeHeader unpackExtensionTypeHeader() throw unexpected("Ext", b); } - private int readStringHeader(byte b) + private int tryReadStringHeader(byte b) throws IOException { switch (b) { @@ -1177,7 +1250,7 @@ private int readStringHeader(byte b) } } - private int readBinaryHeader(byte b) + private int tryReadBinaryHeader(byte b) throws IOException { switch (b) { @@ -1195,18 +1268,21 @@ private int readBinaryHeader(byte b) public int unpackRawStringHeader() throws IOException { - byte b = consume(); + byte b = getHeadByte(); if (Code.isFixedRaw(b)) { // FixRaw + resetHeadByte(); return b & 0x1f; } - int len = readStringHeader(b); + int len = tryReadStringHeader(b); if (len >= 0) { + resetHeadByte(); return len; } if (config.readBinaryAsString) { - len = readBinaryHeader(b); + len = tryReadBinaryHeader(b); if (len >= 0) { + resetHeadByte(); return len; } } @@ -1216,36 +1292,65 @@ public int unpackRawStringHeader() public int unpackBinaryHeader() throws IOException { - byte b = consume(); + byte b = getHeadByte(); if (Code.isFixedRaw(b)) { // FixRaw + resetHeadByte(); return b & 0x1f; } - int len = readBinaryHeader(b); + int len = tryReadBinaryHeader(b); if (len >= 0) { + resetHeadByte(); return len; } if (config.readStringAsBinary) { - len = readStringHeader(b); + len = tryReadStringHeader(b); if (len >= 0) { + resetHeadByte(); return len; } } throw unexpected("Binary", b); } - // TODO returns a buffer reference to the payload (zero-copy) + /** + * Skip reading the specified number of bytes. Use this method only if you know skipping data is safe. + * For simply skipping the next value, use {@link #skipValue()}. + * + * @param numBytes + * @throws IOException + */ + private void skipPayload(int numBytes) + throws IOException + { + while (true) { + int bufferRemaining = buffer.size() - position; + if (bufferRemaining >= numBytes) { + position += numBytes; + return; + } + else { + position += bufferRemaining; + } + nextBuffer(); + } + } public void readPayload(ByteBuffer dst) throws IOException { - while (dst.remaining() > 0) { - if (!ensureBuffer()) { - throw new EOFException(); + while (true) { + int dstRemaining = dst.remaining(); + int bufferRemaining = buffer.size() - position; + if (bufferRemaining >= dstRemaining) { + buffer.getBytes(position, dstRemaining, dst); + position += dstRemaining; + return; } - int l = Math.min(buffer.size() - position, dst.remaining()); - buffer.getBytes(position, l, dst); - consume(l); + buffer.getBytes(position, bufferRemaining, dst); + position += bufferRemaining; + + nextBuffer(); } } @@ -1274,29 +1379,22 @@ public byte[] readPayload(int length) public void readPayload(byte[] dst, int off, int len) throws IOException { - int writtenLen = 0; - while (writtenLen < len) { - if (!ensureBuffer()) { - throw new EOFException(); - } - int l = Math.min(buffer.size() - position, len - writtenLen); - buffer.getBytes(position, dst, off + writtenLen, l); - consume(l); - writtenLen += l; - } + // TODO optimize + readPayload(ByteBuffer.wrap(dst, off, len)); } public MessageBuffer readPayloadAsReference(int length) throws IOException { - checkArgument(length >= 0); - if (!ensure(length)) { - throw new EOFException(); + int bufferRemaining = buffer.size() - position; + if (bufferRemaining >= length) { + MessageBuffer slice = buffer.slice(position, length); + position += length; + return slice; } - - MessageBuffer ref = buffer.slice(position, length); - position += length; - return ref; + MessageBuffer dst = MessageBuffer.newBuffer(length); + readPayload(dst.getReference()); + return dst; } private int readNextLength8() diff --git a/msgpack-core/src/main/java/org/msgpack/core/buffer/ArrayBufferInput.java b/msgpack-core/src/main/java/org/msgpack/core/buffer/ArrayBufferInput.java index 88fe45942..35f76c14c 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/buffer/ArrayBufferInput.java +++ b/msgpack-core/src/main/java/org/msgpack/core/buffer/ArrayBufferInput.java @@ -87,4 +87,9 @@ public void close() buffer = null; isRead = false; } + + // TODO + public void release(MessageBuffer buffer) + { + } } diff --git a/msgpack-core/src/main/java/org/msgpack/core/buffer/ByteBufferInput.java b/msgpack-core/src/main/java/org/msgpack/core/buffer/ByteBufferInput.java index b9b4304ad..1f60b3fec 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/buffer/ByteBufferInput.java +++ b/msgpack-core/src/main/java/org/msgpack/core/buffer/ByteBufferInput.java @@ -66,4 +66,9 @@ public void close() { // Nothing to do } + + // TODO + public void release(MessageBuffer buffer) + { + } } diff --git a/msgpack-core/src/main/java/org/msgpack/core/buffer/ChannelBufferInput.java b/msgpack-core/src/main/java/org/msgpack/core/buffer/ChannelBufferInput.java index 4b8baeb75..6dd262599 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/buffer/ChannelBufferInput.java +++ b/msgpack-core/src/main/java/org/msgpack/core/buffer/ChannelBufferInput.java @@ -85,4 +85,9 @@ public void close() { channel.close(); } + + // TODO + public void release(MessageBuffer buffer) + { + } } diff --git a/msgpack-core/src/main/java/org/msgpack/core/buffer/InputStreamBufferInput.java b/msgpack-core/src/main/java/org/msgpack/core/buffer/InputStreamBufferInput.java index 81aabd762..b0d42e4a0 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/buffer/InputStreamBufferInput.java +++ b/msgpack-core/src/main/java/org/msgpack/core/buffer/InputStreamBufferInput.java @@ -93,4 +93,9 @@ public void close() { in.close(); } + + // TODO + public void release(MessageBuffer buffer) + { + } } diff --git a/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBuffer.java b/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBuffer.java index 4dd1396f1..46a777af0 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBuffer.java +++ b/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBuffer.java @@ -328,6 +328,11 @@ else if (bb.hasArray()) { this.reference = reference; } + public MessageBufferReader newReader() + { + return new MessageBufferReader(this); + } + /** * byte size of the buffer * diff --git a/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferInput.java b/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferInput.java index 786ce2721..2a92160b2 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferInput.java +++ b/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferInput.java @@ -27,9 +27,14 @@ public interface MessageBufferInput /** * Get a next buffer to read. * - * @return the next MessageBuffer, or null if no more buffer is available. + * @return the next MessageBuffer, or return null if no more buffer is available. * @throws IOException when error occurred when reading the data */ public MessageBuffer next() throws IOException; + + /** + * Release an unused buffer formerly returned by next() method. + */ + public void release(MessageBuffer buffer); } diff --git a/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferReader.java b/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferReader.java new file mode 100644 index 000000000..f9656d22d --- /dev/null +++ b/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferReader.java @@ -0,0 +1,122 @@ +// +// MessagePack for Java +// +// 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.core.buffer; + +public class MessageBufferReader +{ + // TODO add more reader methods for each type + + private MessageBuffer buffer; + private int position; + + MessageBufferReader(MessageBuffer buffer) + { + this.buffer = buffer; + } + + public MessageBuffer buffer() + { + return buffer; + } + + public int position() + { + return position; + } + + public void position(int newPosition) + { + // TODO validation? + this.position = newPosition; + } + + public int remaining() + { + return buffer.size() - position; + } + + public byte getByte() + { + return buffer.getByte(position); + } + + public byte readByte() + { + byte v = buffer.getByte(position); + position += 1; + return v; + } + + public short getShort() + { + return buffer.getShort(position); + } + + public short readShort() + { + short v = buffer.getShort(position); + position += 1; + return v; + } + + public int getInt() + { + return buffer.getInt(position); + } + + public int readInt() + { + int v = buffer.getInt(position); + position += 1; + return v; + } + + public long getLong() + { + return buffer.getLong(position); + } + + public long readLong() + { + long v = buffer.getLong(position); + position += 1; + return v; + } + + public float getFloat() + { + return buffer.getFloat(position); + } + + public float readFloat() + { + float v = buffer.getFloat(position); + position += 1; + return v; + } + + public double getDouble() + { + return buffer.getDouble(position); + } + + public double readDouble() + { + double v = buffer.getDouble(position); + position += 1; + return v; + } +} diff --git a/msgpack-core/src/test/scala/org/msgpack/core/MessagePackTest.scala b/msgpack-core/src/test/scala/org/msgpack/core/MessagePackTest.scala index 62bf8ae82..f903cf88d 100644 --- a/msgpack-core/src/test/scala/org/msgpack/core/MessagePackTest.scala +++ b/msgpack-core/src/test/scala/org/msgpack/core/MessagePackTest.scala @@ -469,4 +469,4 @@ class MessagePackTest extends MessagePackSpec { } } -} \ No newline at end of file +} diff --git a/msgpack-core/src/test/scala/org/msgpack/core/MessageUnpackerTest.scala b/msgpack-core/src/test/scala/org/msgpack/core/MessageUnpackerTest.scala index 672edd615..179ca5eb1 100644 --- a/msgpack-core/src/test/scala/org/msgpack/core/MessageUnpackerTest.scala +++ b/msgpack-core/src/test/scala/org/msgpack/core/MessageUnpackerTest.scala @@ -261,6 +261,8 @@ class MessageUnpackerTest extends MessagePackSpec { } } + override def release(buffer: MessageBuffer): Unit = {} + override def close(): Unit = {} } diff --git a/msgpack-core/src/test/scala/org/msgpack/core/buffer/ByteStringTest.scala b/msgpack-core/src/test/scala/org/msgpack/core/buffer/ByteStringTest.scala index 362038d95..39526a0ce 100644 --- a/msgpack-core/src/test/scala/org/msgpack/core/buffer/ByteStringTest.scala +++ b/msgpack-core/src/test/scala/org/msgpack/core/buffer/ByteStringTest.scala @@ -39,6 +39,8 @@ class ByteStringTest messageBuffer } + override def release(buffer: MessageBuffer): Unit = {} + override def close(): Unit = {} } From 606cf982dd2a2d55dd22a456b4f125ac022f158c Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Tue, 22 Dec 2015 10:16:31 +0900 Subject: [PATCH 154/234] Use the local sbt script since TravisCI crashes with the pre-installed sbt --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index e30cdb222..59686eaf6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,5 +10,5 @@ branches: - /^v07.*$/ script: - - sbt test - - sbt test -J-Dmsgpack.universal-buffer=true + - ./sbt test + - ./sbt test -J-Dmsgpack.universal-buffer=true From 70098b3b4dfbc9774becddc0d8c17a29d5d7c659 Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Tue, 22 Dec 2015 10:21:03 +0900 Subject: [PATCH 155/234] Test container-based TravicCI infrastructure --- .travis.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index 59686eaf6..1159165a7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,7 @@ language: scala +sudo: false + jdk: - openjdk7 - oraclejdk7 From 749684805ada554bbd7cac741755a843e23085c9 Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Tue, 22 Dec 2015 10:29:09 +0900 Subject: [PATCH 156/234] Cache dependency directories for mvn and sbt --- .travis.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.travis.yml b/.travis.yml index 1159165a7..9dd79943e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,11 @@ language: scala +cache: + directories: + - $HOME/.m2/repository/ + - $HOME/.ivy2/cache/ + - $HOME/.sbt/boot/ + sudo: false jdk: From 61f86994e21858d16306023077a2b1561c0bf5e8 Mon Sep 17 00:00:00 2001 From: Sadayuki Furuhashi Date: Tue, 22 Dec 2015 10:39:03 +0900 Subject: [PATCH 157/234] fixed MessageUnpacker.utf8MultibyteCharacterSize --- .../org/msgpack/core/MessageUnpacker.java | 29 +++-- .../msgpack/core/buffer/MessageBuffer.java | 7 +- .../core/buffer/MessageBufferReader.java | 122 ------------------ sbt | 0 4 files changed, 20 insertions(+), 138 deletions(-) delete mode 100644 msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferReader.java mode change 100644 => 100755 sbt diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java b/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java index 05babb1ce..b22c98dfb 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java +++ b/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java @@ -17,7 +17,6 @@ import org.msgpack.core.MessagePack.Code; import org.msgpack.core.buffer.MessageBuffer; -import org.msgpack.core.buffer.MessageBufferReader; import org.msgpack.core.buffer.MessageBufferInput; import org.msgpack.value.ImmutableValue; import org.msgpack.value.Value; @@ -186,7 +185,7 @@ private byte getHeadByte() if (b == HEAD_BYTE_REQUIRED) { b = headByte = readByte(); if (b == HEAD_BYTE_REQUIRED) { - throw new MessageNeverUsedFormatException("Encountered 0xC1 NEVER_USED byte"); + throw new MessageNeverUsedFormatException("Encountered 0xC1 \"NEVER_USED\" byte"); } } return b; @@ -205,7 +204,9 @@ private void nextBuffer() throw new MessageInsufficientBufferException(); } totalReadBytes += buffer.size(); - in.release(buffer); + if (buffer != EMPTY_BUFFER) { + in.release(buffer); + } buffer = next; position = 0; } @@ -232,7 +233,9 @@ private MessageBuffer readCastBuffer(int length) castBuffer.putBytes(remaining, next.getArray(), next.offset(), length - remaining); totalReadBytes += buffer.size(); - in.release(buffer); + if (buffer != EMPTY_BUFFER) { + in.release(buffer); + } buffer = next; position = length - remaining; @@ -244,8 +247,7 @@ private MessageBuffer readCastBuffer(int length) private static int utf8MultibyteCharacterSize(byte firstByte) { - System.out.println("first byte: "+(firstByte & 0xff)); - return Integer.numberOfLeadingZeros(~(firstByte & 0xff)); + return Integer.numberOfLeadingZeros(~(firstByte & 0xff) << 24); } /** @@ -264,7 +266,9 @@ public boolean hasNext() return false; } totalReadBytes += buffer.size(); - in.release(buffer); + if (buffer != EMPTY_BUFFER) { + in.release(buffer); + } buffer = next; position = 0; } @@ -490,7 +494,7 @@ public ImmutableValue unpackValue() MessageFormat mf = getNextFormat(); switch (mf.getValueType()) { case NIL: - unpackNil(); + readByte(); return ValueFactory.newNil(); case BOOLEAN: return ValueFactory.newBoolean(unpackBoolean()); @@ -1070,7 +1074,7 @@ else if (bufferRemaining == 0) { if (cr.isError()) { handleCoderError(cr); } - if (cr.isUnderflow() || cr.isOverflow()) { + if (cr.isOverflow() || (cr.isUnderflow() && multiByteBuffer.position() < multiByteBuffer.limit())) { // isOverflow or isOverflow must not happen. if happened, throw exception try { cr.throwException(); @@ -1106,7 +1110,7 @@ private String decodeStringFastPath(int length) if (config.actionOnMalFormedInput == CodingErrorAction.REPLACE && config.actionOnUnmappableCharacter == CodingErrorAction.REPLACE && buffer.hasArray()) { - String s = new String(buffer.getArray(), position, length, MessagePack.UTF8); + String s = new String(buffer.getArray(), buffer.offset() + position, length, MessagePack.UTF8); position += length; return s; } @@ -1425,6 +1429,11 @@ private int readNextLength32() public void close() throws IOException { + if (buffer != EMPTY_BUFFER) { + in.release(buffer); + buffer = EMPTY_BUFFER; + position = 0; + } in.close(); } diff --git a/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBuffer.java b/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBuffer.java index 46a777af0..302105f83 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBuffer.java +++ b/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBuffer.java @@ -328,11 +328,6 @@ else if (bb.hasArray()) { this.reference = reference; } - public MessageBufferReader newReader() - { - return new MessageBufferReader(this); - } - /** * byte size of the buffer * @@ -408,7 +403,7 @@ public void getBytes(int index, byte[] dst, int dstOffset, int length) public void getBytes(int index, int len, ByteBuffer dst) { - if (dst.remaining() > len) { + if (dst.remaining() < len) { throw new BufferOverflowException(); } ByteBuffer src = toByteBuffer(index, len); diff --git a/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferReader.java b/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferReader.java deleted file mode 100644 index f9656d22d..000000000 --- a/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferReader.java +++ /dev/null @@ -1,122 +0,0 @@ -// -// MessagePack for Java -// -// 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.core.buffer; - -public class MessageBufferReader -{ - // TODO add more reader methods for each type - - private MessageBuffer buffer; - private int position; - - MessageBufferReader(MessageBuffer buffer) - { - this.buffer = buffer; - } - - public MessageBuffer buffer() - { - return buffer; - } - - public int position() - { - return position; - } - - public void position(int newPosition) - { - // TODO validation? - this.position = newPosition; - } - - public int remaining() - { - return buffer.size() - position; - } - - public byte getByte() - { - return buffer.getByte(position); - } - - public byte readByte() - { - byte v = buffer.getByte(position); - position += 1; - return v; - } - - public short getShort() - { - return buffer.getShort(position); - } - - public short readShort() - { - short v = buffer.getShort(position); - position += 1; - return v; - } - - public int getInt() - { - return buffer.getInt(position); - } - - public int readInt() - { - int v = buffer.getInt(position); - position += 1; - return v; - } - - public long getLong() - { - return buffer.getLong(position); - } - - public long readLong() - { - long v = buffer.getLong(position); - position += 1; - return v; - } - - public float getFloat() - { - return buffer.getFloat(position); - } - - public float readFloat() - { - float v = buffer.getFloat(position); - position += 1; - return v; - } - - public double getDouble() - { - return buffer.getDouble(position); - } - - public double readDouble() - { - double v = buffer.getDouble(position); - position += 1; - return v; - } -} diff --git a/sbt b/sbt old mode 100644 new mode 100755 From b182ed2ee4d09755d0b1272b414eeffeb915be6e Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Tue, 22 Dec 2015 18:18:42 +0900 Subject: [PATCH 158/234] Remove release method from MessageBufferInput --- .../org/msgpack/core/MessageUnpacker.java | 16 ++-------------- .../msgpack/core/buffer/ArrayBufferInput.java | 4 ---- .../msgpack/core/buffer/ByteBufferInput.java | 4 ---- .../core/buffer/ChannelBufferInput.java | 19 ++++--------------- .../core/buffer/InputStreamBufferInput.java | 17 ++--------------- .../core/buffer/MessageBufferInput.java | 6 ++---- .../msgpack/core/MessageUnpackerTest.scala | 2 -- .../msgpack/core/buffer/ByteStringTest.scala | 3 --- 8 files changed, 10 insertions(+), 61 deletions(-) diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java b/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java index b22c98dfb..70a050990 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java +++ b/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java @@ -204,9 +204,6 @@ private void nextBuffer() throw new MessageInsufficientBufferException(); } totalReadBytes += buffer.size(); - if (buffer != EMPTY_BUFFER) { - in.release(buffer); - } buffer = next; position = 0; } @@ -233,9 +230,6 @@ private MessageBuffer readCastBuffer(int length) castBuffer.putBytes(remaining, next.getArray(), next.offset(), length - remaining); totalReadBytes += buffer.size(); - if (buffer != EMPTY_BUFFER) { - in.release(buffer); - } buffer = next; position = length - remaining; @@ -266,9 +260,6 @@ public boolean hasNext() return false; } totalReadBytes += buffer.size(); - if (buffer != EMPTY_BUFFER) { - in.release(buffer); - } buffer = next; position = 0; } @@ -1429,11 +1420,8 @@ private int readNextLength32() public void close() throws IOException { - if (buffer != EMPTY_BUFFER) { - in.release(buffer); - buffer = EMPTY_BUFFER; - position = 0; - } + buffer = EMPTY_BUFFER; + position = 0; in.close(); } diff --git a/msgpack-core/src/main/java/org/msgpack/core/buffer/ArrayBufferInput.java b/msgpack-core/src/main/java/org/msgpack/core/buffer/ArrayBufferInput.java index 35f76c14c..a777b8a73 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/buffer/ArrayBufferInput.java +++ b/msgpack-core/src/main/java/org/msgpack/core/buffer/ArrayBufferInput.java @@ -88,8 +88,4 @@ public void close() isRead = false; } - // TODO - public void release(MessageBuffer buffer) - { - } } diff --git a/msgpack-core/src/main/java/org/msgpack/core/buffer/ByteBufferInput.java b/msgpack-core/src/main/java/org/msgpack/core/buffer/ByteBufferInput.java index 1f60b3fec..034d8882b 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/buffer/ByteBufferInput.java +++ b/msgpack-core/src/main/java/org/msgpack/core/buffer/ByteBufferInput.java @@ -67,8 +67,4 @@ public void close() // Nothing to do } - // TODO - public void release(MessageBuffer buffer) - { - } } diff --git a/msgpack-core/src/main/java/org/msgpack/core/buffer/ChannelBufferInput.java b/msgpack-core/src/main/java/org/msgpack/core/buffer/ChannelBufferInput.java index 6dd262599..73dcb5db6 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/buffer/ChannelBufferInput.java +++ b/msgpack-core/src/main/java/org/msgpack/core/buffer/ChannelBufferInput.java @@ -29,8 +29,7 @@ public class ChannelBufferInput implements MessageBufferInput { private ReadableByteChannel channel; - private boolean reachedEOF = false; - private final int bufferSize; + private final MessageBuffer m; public ChannelBufferInput(ReadableByteChannel channel) { @@ -41,7 +40,7 @@ public ChannelBufferInput(ReadableByteChannel channel, int bufferSize) { this.channel = checkNotNull(channel, "input channel is null"); checkArgument(bufferSize > 0, "buffer size must be > 0: " + bufferSize); - this.bufferSize = bufferSize; + this.m = MessageBuffer.newBuffer(bufferSize); } /** @@ -55,7 +54,6 @@ public ReadableByteChannel reset(ReadableByteChannel channel) { ReadableByteChannel old = this.channel; this.channel = channel; - this.reachedEOF = false; return old; } @@ -63,16 +61,11 @@ public ReadableByteChannel reset(ReadableByteChannel channel) public MessageBuffer next() throws IOException { - if (reachedEOF) { - return null; - } - - MessageBuffer m = MessageBuffer.newBuffer(bufferSize); ByteBuffer b = m.toByteBuffer(); - while (!reachedEOF && b.remaining() > 0) { + while (b.remaining() > 0) { int ret = channel.read(b); if (ret == -1) { - reachedEOF = true; + break; } } b.flip(); @@ -86,8 +79,4 @@ public void close() channel.close(); } - // TODO - public void release(MessageBuffer buffer) - { - } } diff --git a/msgpack-core/src/main/java/org/msgpack/core/buffer/InputStreamBufferInput.java b/msgpack-core/src/main/java/org/msgpack/core/buffer/InputStreamBufferInput.java index b0d42e4a0..ad8aa462f 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/buffer/InputStreamBufferInput.java +++ b/msgpack-core/src/main/java/org/msgpack/core/buffer/InputStreamBufferInput.java @@ -29,8 +29,7 @@ public class InputStreamBufferInput implements MessageBufferInput { private InputStream in; - private final int bufferSize; - private boolean reachedEOF = false; + private final byte[] buffer; public static MessageBufferInput newBufferInput(InputStream in) { @@ -52,7 +51,7 @@ public InputStreamBufferInput(InputStream in) public InputStreamBufferInput(InputStream in, int bufferSize) { this.in = checkNotNull(in, "input is null"); - this.bufferSize = bufferSize; + this.buffer = new byte[bufferSize]; } /** @@ -66,7 +65,6 @@ public InputStream reset(InputStream in) { InputStream old = this.in; this.in = in; - reachedEOF = false; return old; } @@ -74,14 +72,8 @@ public InputStream reset(InputStream in) public MessageBuffer next() throws IOException { - if (reachedEOF) { - return null; - } - - byte[] buffer = new byte[bufferSize]; int readLen = in.read(buffer); if (readLen == -1) { - reachedEOF = true; return null; } return MessageBuffer.wrap(buffer).slice(0, readLen); @@ -93,9 +85,4 @@ public void close() { in.close(); } - - // TODO - public void release(MessageBuffer buffer) - { - } } diff --git a/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferInput.java b/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferInput.java index 2a92160b2..5925557cf 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferInput.java +++ b/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferInput.java @@ -27,14 +27,12 @@ public interface MessageBufferInput /** * Get a next buffer to read. * + * When this method is called twice, the formally allocated buffer can be safely discarded. + * * @return the next MessageBuffer, or return null if no more buffer is available. * @throws IOException when error occurred when reading the data */ public MessageBuffer next() throws IOException; - /** - * Release an unused buffer formerly returned by next() method. - */ - public void release(MessageBuffer buffer); } diff --git a/msgpack-core/src/test/scala/org/msgpack/core/MessageUnpackerTest.scala b/msgpack-core/src/test/scala/org/msgpack/core/MessageUnpackerTest.scala index 179ca5eb1..672edd615 100644 --- a/msgpack-core/src/test/scala/org/msgpack/core/MessageUnpackerTest.scala +++ b/msgpack-core/src/test/scala/org/msgpack/core/MessageUnpackerTest.scala @@ -261,8 +261,6 @@ class MessageUnpackerTest extends MessagePackSpec { } } - override def release(buffer: MessageBuffer): Unit = {} - override def close(): Unit = {} } diff --git a/msgpack-core/src/test/scala/org/msgpack/core/buffer/ByteStringTest.scala b/msgpack-core/src/test/scala/org/msgpack/core/buffer/ByteStringTest.scala index 39526a0ce..92103dc31 100644 --- a/msgpack-core/src/test/scala/org/msgpack/core/buffer/ByteStringTest.scala +++ b/msgpack-core/src/test/scala/org/msgpack/core/buffer/ByteStringTest.scala @@ -38,9 +38,6 @@ class ByteStringTest isRead = true messageBuffer } - - override def release(buffer: MessageBuffer): Unit = {} - override def close(): Unit = {} } From 60fc2b286b87c261c3168e5be9e7d3b522ab0369 Mon Sep 17 00:00:00 2001 From: Sadayuki Furuhashi Date: Tue, 22 Dec 2015 18:24:43 +0900 Subject: [PATCH 159/234] fixed skipPayload --- msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java | 1 + 1 file changed, 1 insertion(+) diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java b/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java index 70a050990..38880d03d 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java +++ b/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java @@ -1326,6 +1326,7 @@ private void skipPayload(int numBytes) } else { position += bufferRemaining; + numBytes -= bufferRemaining; } nextBuffer(); } From 3d9e16834d5e908b7af32dde6b9901c186a085bb Mon Sep 17 00:00:00 2001 From: Mitsunori Komatsu Date: Wed, 23 Dec 2015 22:09:00 +0900 Subject: [PATCH 160/234] Improve MessagePackDataformat(Pojo|HugeData)BenchmarkTest --- .../MessagePackDataformatTestBase.java | 13 --- .../dataformat/benchmark/Benchmarker.java | 95 +++++++++++++++++++ ...gePackDataformatHugeDataBenchmarkTest.java | 65 ++++++++----- ...essagePackDataformatPojoBenchmarkTest.java | 85 ++++++++++------- 4 files changed, 184 insertions(+), 74 deletions(-) create mode 100644 msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/benchmark/Benchmarker.java diff --git a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackDataformatTestBase.java b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackDataformatTestBase.java index fad09b910..1d5156adc 100644 --- a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackDataformatTestBase.java +++ b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackDataformatTestBase.java @@ -19,8 +19,6 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.databind.ObjectMapper; -import org.apache.commons.math3.stat.StatUtils; -import org.apache.commons.math3.stat.descriptive.moment.StandardDeviation; import org.junit.After; import org.junit.Before; @@ -99,17 +97,6 @@ public void teardown() } } - protected void printStat(String label, double[] values) - { - StandardDeviation standardDeviation = new StandardDeviation(); - System.out.println(label + ":"); - System.out.println(String.format(" mean : %.2f", StatUtils.mean(values))); - System.out.println(String.format(" min : %.2f", StatUtils.min(values))); - System.out.println(String.format(" max : %.2f", StatUtils.max(values))); - System.out.println(String.format(" stdev: %.2f", standardDeviation.evaluate(values))); - System.out.println(""); - } - public enum Suit { SPADE, HEART, DIAMOND, CLUB; diff --git a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/benchmark/Benchmarker.java b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/benchmark/Benchmarker.java new file mode 100644 index 000000000..4a11c4307 --- /dev/null +++ b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/benchmark/Benchmarker.java @@ -0,0 +1,95 @@ +// +// MessagePack for Java +// +// 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.jackson.dataformat.benchmark; + +import org.apache.commons.math3.stat.StatUtils; +import org.apache.commons.math3.stat.descriptive.moment.StandardDeviation; + +import java.util.ArrayList; +import java.util.List; + +public class Benchmarker +{ + private final List benchmarkableList = new ArrayList(); + + public abstract static class Benchmarkable + { + private final String label; + + protected Benchmarkable(String label) + { + this.label = label; + } + + public abstract void run() throws Exception; + } + + public void addBenchmark(Benchmarkable benchmark) + { + benchmarkableList.add(benchmark); + } + + private static class Tuple + { + F first; + S second; + + public Tuple(F first, S second) + { + this.first = first; + this.second = second; + } + } + + public void run(int count, int warmupCount) + throws Exception + { + List> benchmarksResults = new ArrayList>(benchmarkableList.size()); + + for (Benchmarkable benchmark : benchmarkableList) { + double[] durations = new double[count]; + + for (int i = 0; i < count + warmupCount; i++) { + if (i >= warmupCount) { + System.gc(); + } + + long currentTimeNanos = System.nanoTime(); + benchmark.run(); + + if (i >= warmupCount) { + durations[i - warmupCount] = (System.nanoTime() - currentTimeNanos) / 1000000.0; + } + } + benchmarksResults.add(new Tuple(benchmark.label, durations)); + } + + for (Tuple benchmarkResult : benchmarksResults) { + printStat(benchmarkResult.first, benchmarkResult.second); + } + } + + private void printStat(String label, double[] values) + { + StandardDeviation standardDeviation = new StandardDeviation(); + System.out.println(label + ":"); + System.out.println(String.format(" mean : %8.3f", StatUtils.mean(values))); + System.out.println(String.format(" min : %8.3f", StatUtils.min(values))); + System.out.println(String.format(" max : %8.3f", StatUtils.max(values))); + System.out.println(String.format(" stdev: %8.3f", standardDeviation.evaluate(values))); + System.out.println(""); + } +} diff --git a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/benchmark/MessagePackDataformatHugeDataBenchmarkTest.java b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/benchmark/MessagePackDataformatHugeDataBenchmarkTest.java index 342db62f5..07aec379f 100644 --- a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/benchmark/MessagePackDataformatHugeDataBenchmarkTest.java +++ b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/benchmark/MessagePackDataformatHugeDataBenchmarkTest.java @@ -19,17 +19,16 @@ import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.Test; -import org.msgpack.jackson.dataformat.MessagePackDataformatTestBase; import org.msgpack.jackson.dataformat.MessagePackFactory; import java.util.ArrayList; import java.util.List; public class MessagePackDataformatHugeDataBenchmarkTest - extends MessagePackDataformatTestBase { - private static final int ELM_NUM = 1000000; - private static final int SAMPLING_COUNT = 4; + private static final int ELM_NUM = 100000; + private static final int COUNT = 6; + private static final int WARMUP_COUNT = 4; private final ObjectMapper origObjectMapper = new ObjectMapper(); private final ObjectMapper msgpackObjectMapper = new ObjectMapper(new MessagePackFactory()); private static final List value; @@ -70,30 +69,44 @@ public class MessagePackDataformatHugeDataBenchmarkTest public void testBenchmark() throws Exception { - double[] durationOfSerializeWithJson = new double[SAMPLING_COUNT]; - double[] durationOfSerializeWithMsgPack = new double[SAMPLING_COUNT]; - double[] durationOfDeserializeWithJson = new double[SAMPLING_COUNT]; - double[] durationOfDeserializeWithMsgPack = new double[SAMPLING_COUNT]; - for (int si = 0; si < SAMPLING_COUNT; si++) { - long currentTimeMillis = System.currentTimeMillis(); - origObjectMapper.writeValueAsBytes(value); - durationOfSerializeWithJson[si] = System.currentTimeMillis() - currentTimeMillis; + Benchmarker benchmarker = new Benchmarker(); - currentTimeMillis = System.currentTimeMillis(); - msgpackObjectMapper.writeValueAsBytes(value); - durationOfSerializeWithMsgPack[si] = System.currentTimeMillis() - currentTimeMillis; + benchmarker.addBenchmark(new Benchmarker.Benchmarkable("serialize(huge) with JSON") { + @Override + public void run() + throws Exception + { + origObjectMapper.writeValueAsBytes(value); + } + }); - currentTimeMillis = System.currentTimeMillis(); - origObjectMapper.readValue(packedByOriginal, new TypeReference>() {}); - durationOfDeserializeWithJson[si] = System.currentTimeMillis() - currentTimeMillis; + benchmarker.addBenchmark(new Benchmarker.Benchmarkable("serialize(huge) with MessagePack") { + @Override + public void run() + throws Exception + { + msgpackObjectMapper.writeValueAsBytes(value); + } + }); - currentTimeMillis = System.currentTimeMillis(); - msgpackObjectMapper.readValue(packedByMsgPack, new TypeReference>() {}); - durationOfDeserializeWithMsgPack[si] = System.currentTimeMillis() - currentTimeMillis; - } - printStat("serialize(huge) with JSON", durationOfSerializeWithJson); - printStat("serialize(huge) with MessagePack", durationOfSerializeWithMsgPack); - printStat("deserialize(huge) with JSON", durationOfDeserializeWithJson); - printStat("deserialize(huge) with MessagePack", durationOfDeserializeWithMsgPack); + benchmarker.addBenchmark(new Benchmarker.Benchmarkable("deserialize(huge) with JSON") { + @Override + public void run() + throws Exception + { + origObjectMapper.readValue(packedByOriginal, new TypeReference>() {}); + } + }); + + benchmarker.addBenchmark(new Benchmarker.Benchmarkable("deserialize(huge) with MessagePack") { + @Override + public void run() + throws Exception + { + msgpackObjectMapper.readValue(packedByMsgPack, new TypeReference>() {}); + } + }); + + benchmarker.run(COUNT, WARMUP_COUNT); } } diff --git a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/benchmark/MessagePackDataformatPojoBenchmarkTest.java b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/benchmark/MessagePackDataformatPojoBenchmarkTest.java index eef58b242..af66c5d66 100644 --- a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/benchmark/MessagePackDataformatPojoBenchmarkTest.java +++ b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/benchmark/MessagePackDataformatPojoBenchmarkTest.java @@ -18,19 +18,20 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.Test; -import org.msgpack.jackson.dataformat.MessagePackDataformatTestBase; import org.msgpack.jackson.dataformat.MessagePackFactory; +import static org.msgpack.jackson.dataformat.MessagePackDataformatTestBase.NormalPojo; +import static org.msgpack.jackson.dataformat.MessagePackDataformatTestBase.Suit; import java.math.BigInteger; import java.util.ArrayList; import java.util.List; public class MessagePackDataformatPojoBenchmarkTest - extends MessagePackDataformatTestBase { - private static final int LOOP_MAX = 1000; - private static final int LOOP_FACTOR = 50; - private static final int SAMPLING_COUNT = 4; + private static final int LOOP_MAX = 600; + private static final int LOOP_FACTOR = 40; + private static final int COUNT = 6; + private static final int WARMUP_COUNT = 4; private static final List pojos = new ArrayList(LOOP_MAX); private static final List pojosSerWithOrig = new ArrayList(LOOP_MAX); private static final List pojosSerWithMsgPack = new ArrayList(LOOP_MAX); @@ -91,46 +92,60 @@ public class MessagePackDataformatPojoBenchmarkTest public void testBenchmark() throws Exception { - double[] durationOfSerializeWithJson = new double[SAMPLING_COUNT]; - double[] durationOfSerializeWithMsgPack = new double[SAMPLING_COUNT]; - double[] durationOfDeserializeWithJson = new double[SAMPLING_COUNT]; - double[] durationOfDeserializeWithMsgPack = new double[SAMPLING_COUNT]; - for (int si = 0; si < SAMPLING_COUNT; si++) { - long currentTimeMillis = System.currentTimeMillis(); - for (int j = 0; j < LOOP_FACTOR; j++) { - for (int i = 0; i < LOOP_MAX; i++) { - origObjectMapper.writeValueAsBytes(pojos.get(i)); + Benchmarker benchmarker = new Benchmarker(); + + benchmarker.addBenchmark(new Benchmarker.Benchmarkable("serialize(pojo) with JSON") { + @Override + public void run() + throws Exception + { + for (int j = 0; j < LOOP_FACTOR; j++) { + for (int i = 0; i < LOOP_MAX; i++) { + origObjectMapper.writeValueAsBytes(pojos.get(i)); + } } } - durationOfSerializeWithJson[si] = System.currentTimeMillis() - currentTimeMillis; + }); - currentTimeMillis = System.currentTimeMillis(); - for (int j = 0; j < LOOP_FACTOR; j++) { - for (int i = 0; i < LOOP_MAX; i++) { - msgpackObjectMapper.writeValueAsBytes(pojos.get(i)); + benchmarker.addBenchmark(new Benchmarker.Benchmarkable("serialize(pojo) with MessagePack") { + @Override + public void run() + throws Exception + { + for (int j = 0; j < LOOP_FACTOR; j++) { + for (int i = 0; i < LOOP_MAX; i++) { + msgpackObjectMapper.writeValueAsBytes(pojos.get(i)); + } } } - durationOfSerializeWithMsgPack[si] = System.currentTimeMillis() - currentTimeMillis; + }); - currentTimeMillis = System.currentTimeMillis(); - for (int j = 0; j < LOOP_FACTOR; j++) { - for (int i = 0; i < LOOP_MAX; i++) { - origObjectMapper.readValue(pojosSerWithOrig.get(i), NormalPojo.class); + benchmarker.addBenchmark(new Benchmarker.Benchmarkable("deserialize(pojo) with JSON") { + @Override + public void run() + throws Exception + { + for (int j = 0; j < LOOP_FACTOR; j++) { + for (int i = 0; i < LOOP_MAX; i++) { + origObjectMapper.readValue(pojosSerWithOrig.get(i), NormalPojo.class); + } } } - durationOfDeserializeWithJson[si] = System.currentTimeMillis() - currentTimeMillis; + }); - currentTimeMillis = System.currentTimeMillis(); - for (int j = 0; j < LOOP_FACTOR; j++) { - for (int i = 0; i < LOOP_MAX; i++) { - msgpackObjectMapper.readValue(pojosSerWithMsgPack.get(i), NormalPojo.class); + benchmarker.addBenchmark(new Benchmarker.Benchmarkable("deserialize(pojo) with MessagePack") { + @Override + public void run() + throws Exception + { + for (int j = 0; j < LOOP_FACTOR; j++) { + for (int i = 0; i < LOOP_MAX; i++) { + msgpackObjectMapper.readValue(pojosSerWithMsgPack.get(i), NormalPojo.class); + } } } - durationOfDeserializeWithMsgPack[si] = System.currentTimeMillis() - currentTimeMillis; - } - printStat("serialize(pojo) with JSON", durationOfSerializeWithJson); - printStat("serialize(pojo) with MessagePack", durationOfSerializeWithMsgPack); - printStat("deserialize(pojo) with JSON", durationOfDeserializeWithJson); - printStat("deserialize(pojo) with MessagePack", durationOfDeserializeWithMsgPack); + }); + + benchmarker.run(COUNT, WARMUP_COUNT); } } From 4d2594e2aafc6037cf3c0709a74c26706e736338 Mon Sep 17 00:00:00 2001 From: Mitsunori Komatsu Date: Wed, 23 Dec 2015 22:37:55 +0900 Subject: [PATCH 161/234] Use ObjectMapper#writeValue() instead of writeValueAsBytes() in benchmark --- ...gePackDataformatHugeDataBenchmarkTest.java | 30 +++++++++++++++++-- ...essagePackDataformatPojoBenchmarkTest.java | 30 +++++++++++++++++-- 2 files changed, 54 insertions(+), 6 deletions(-) diff --git a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/benchmark/MessagePackDataformatHugeDataBenchmarkTest.java b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/benchmark/MessagePackDataformatHugeDataBenchmarkTest.java index 07aec379f..b3a159111 100644 --- a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/benchmark/MessagePackDataformatHugeDataBenchmarkTest.java +++ b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/benchmark/MessagePackDataformatHugeDataBenchmarkTest.java @@ -15,12 +15,16 @@ // package org.msgpack.jackson.dataformat.benchmark; +import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.Test; import org.msgpack.jackson.dataformat.MessagePackFactory; +import java.io.File; +import java.io.FileOutputStream; +import java.io.OutputStream; import java.util.ArrayList; import java.util.List; @@ -65,18 +69,32 @@ public class MessagePackDataformatHugeDataBenchmarkTest packedByMsgPack = bytes; } + public MessagePackDataformatHugeDataBenchmarkTest() + { + origObjectMapper.configure(JsonGenerator.Feature.AUTO_CLOSE_TARGET, false); + msgpackObjectMapper.configure(JsonGenerator.Feature.AUTO_CLOSE_TARGET, false); + } + @Test public void testBenchmark() throws Exception { Benchmarker benchmarker = new Benchmarker(); + File tempFileJackson = File.createTempFile("msgpack-jackson-", "-huge-jackson"); + tempFileJackson.deleteOnExit(); + final OutputStream outputStreamJackson = new FileOutputStream(tempFileJackson); + + File tempFileMsgpack = File.createTempFile("msgpack-jackson-", "-huge-msgpack"); + tempFileMsgpack.deleteOnExit(); + final OutputStream outputStreamMsgpack = new FileOutputStream(tempFileMsgpack); + benchmarker.addBenchmark(new Benchmarker.Benchmarkable("serialize(huge) with JSON") { @Override public void run() throws Exception { - origObjectMapper.writeValueAsBytes(value); + origObjectMapper.writeValue(outputStreamJackson, value); } }); @@ -85,7 +103,7 @@ public void run() public void run() throws Exception { - msgpackObjectMapper.writeValueAsBytes(value); + msgpackObjectMapper.writeValue(outputStreamMsgpack, value); } }); @@ -107,6 +125,12 @@ public void run() } }); - benchmarker.run(COUNT, WARMUP_COUNT); + try { + benchmarker.run(COUNT, WARMUP_COUNT); + } + finally { + outputStreamJackson.close(); + outputStreamMsgpack.close(); + } } } diff --git a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/benchmark/MessagePackDataformatPojoBenchmarkTest.java b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/benchmark/MessagePackDataformatPojoBenchmarkTest.java index af66c5d66..de2118508 100644 --- a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/benchmark/MessagePackDataformatPojoBenchmarkTest.java +++ b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/benchmark/MessagePackDataformatPojoBenchmarkTest.java @@ -15,6 +15,7 @@ // package org.msgpack.jackson.dataformat.benchmark; +import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.Test; @@ -22,6 +23,9 @@ import static org.msgpack.jackson.dataformat.MessagePackDataformatTestBase.NormalPojo; import static org.msgpack.jackson.dataformat.MessagePackDataformatTestBase.Suit; +import java.io.File; +import java.io.FileOutputStream; +import java.io.OutputStream; import java.math.BigInteger; import java.util.ArrayList; import java.util.List; @@ -88,12 +92,26 @@ public class MessagePackDataformatPojoBenchmarkTest } } + public MessagePackDataformatPojoBenchmarkTest() + { + origObjectMapper.configure(JsonGenerator.Feature.AUTO_CLOSE_TARGET, false); + msgpackObjectMapper.configure(JsonGenerator.Feature.AUTO_CLOSE_TARGET, false); + } + @Test public void testBenchmark() throws Exception { Benchmarker benchmarker = new Benchmarker(); + File tempFileJackson = File.createTempFile("msgpack-jackson-", "-huge-jackson"); + tempFileJackson.deleteOnExit(); + final OutputStream outputStreamJackson = new FileOutputStream(tempFileJackson); + + File tempFileMsgpack = File.createTempFile("msgpack-jackson-", "-huge-msgpack"); + tempFileMsgpack.deleteOnExit(); + final OutputStream outputStreamMsgpack = new FileOutputStream(tempFileMsgpack); + benchmarker.addBenchmark(new Benchmarker.Benchmarkable("serialize(pojo) with JSON") { @Override public void run() @@ -101,7 +119,7 @@ public void run() { for (int j = 0; j < LOOP_FACTOR; j++) { for (int i = 0; i < LOOP_MAX; i++) { - origObjectMapper.writeValueAsBytes(pojos.get(i)); + origObjectMapper.writeValue(outputStreamJackson, pojos.get(i)); } } } @@ -114,7 +132,7 @@ public void run() { for (int j = 0; j < LOOP_FACTOR; j++) { for (int i = 0; i < LOOP_MAX; i++) { - msgpackObjectMapper.writeValueAsBytes(pojos.get(i)); + msgpackObjectMapper.writeValue(outputStreamMsgpack, pojos.get(i)); } } } @@ -146,6 +164,12 @@ public void run() } }); - benchmarker.run(COUNT, WARMUP_COUNT); + try { + benchmarker.run(COUNT, WARMUP_COUNT); + } + finally { + outputStreamJackson.close(); + outputStreamMsgpack.close(); + } } } From f45be09506b81f9b90167afd4028285a8ddf7f8a Mon Sep 17 00:00:00 2001 From: Sadayuki Furuhashi Date: Thu, 24 Dec 2015 09:44:27 +0900 Subject: [PATCH 162/234] simplified streaming string decoding code --- .../org/msgpack/core/MessageUnpacker.java | 26 +++---------------- 1 file changed, 3 insertions(+), 23 deletions(-) diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java b/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java index 38880d03d..c6730a009 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java +++ b/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java @@ -997,29 +997,9 @@ public String unpackString() while (readingRawRemaining > 0) { int bufferRemaining = buffer.size() - position; if (bufferRemaining >= readingRawRemaining) { - ByteBuffer bb = buffer.toByteBuffer(position, readingRawRemaining); - int bbStartPosition = bb.position(); - decodeBuffer.clear(); - - CoderResult cr = decoder.decode(bb, decodeBuffer, true); - int readLen = bb.position() - bbStartPosition; - position += readLen; - readingRawRemaining -= readLen; - decodeStringBuffer.append(decodeBuffer.flip()); - - if (cr.isError()) { - handleCoderError(cr); - } - if (cr.isUnderflow() && config.actionOnMalFormedInput == CodingErrorAction.REPORT) { - throw new MalformedInputException(cr.length()); - } - - if (cr.isOverflow()) { - // go to next loop - } - else { - break; - } + decodeStringBuffer.append(decodeStringFastPath(readingRawRemaining)); + readingRawRemaining = 0; + break; } else if (bufferRemaining == 0) { nextBuffer(); From 0b03305f0e840f8db4174de0228d5fad11579282 Mon Sep 17 00:00:00 2001 From: Sadayuki Furuhashi Date: Thu, 24 Dec 2015 10:00:21 +0900 Subject: [PATCH 163/234] 0xC1 NEVER_USED always throws MessageNeverUsedFormatException regardless of context rather than MessageTypeException or MessageFormatException depending on context --- .../java/org/msgpack/core/MessageUnpacker.java | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java b/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java index c6730a009..bd6339418 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java +++ b/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java @@ -449,7 +449,7 @@ public void skipValue() remainingValues += readNextLength32() * 2; // TODO check int overflow break; case NEVER_USED: - throw new MessageFormatException(String.format("unknown code: %02x is found", b)); + throw new MessageNeverUsedFormatException("Encountered 0xC1 \"NEVER_USED\" byte"); } remainingValues--; @@ -464,19 +464,17 @@ public void skipValue() * @return * @throws MessageFormatException */ - private static MessageTypeException unexpected(String expected, byte b) - throws MessageTypeException + private static MessagePackException unexpected(String expected, byte b) { MessageFormat format = MessageFormat.valueOf(b); - String typeName; if (format == MessageFormat.NEVER_USED) { - typeName = "NeverUsed"; + return new MessageNeverUsedFormatException(String.format("Expected %s, but encountered 0xC1 \"NEVER_USED\" byte", expected)); } else { String name = format.getValueType().name(); - typeName = name.substring(0, 1) + name.substring(1).toLowerCase(); + String typeName = name.substring(0, 1) + name.substring(1).toLowerCase(); + return new MessageTypeException(String.format("Expected %s, but got %s (%02x)", expected, typeName, b)); } - return new MessageTypeException(String.format("Expected %s, but got %s (%02x)", expected, typeName, b)); } public ImmutableValue unpackValue() @@ -530,7 +528,7 @@ public ImmutableValue unpackValue() return ValueFactory.newExtension(extHeader.getType(), readPayload(extHeader.getLength())); } default: - throw new MessageFormatException("Unknown value type"); + throw new MessageNeverUsedFormatException("Unknown value type"); } } From dc1f10b9ac060dc4dea0d1ec773a94808f4a1a48 Mon Sep 17 00:00:00 2001 From: Sadayuki Furuhashi Date: Fri, 25 Dec 2015 10:19:18 +0900 Subject: [PATCH 164/234] minimum required castBuffer size is 8 bytes --- .../src/main/java/org/msgpack/core/MessageUnpacker.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java b/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java index bd6339418..9b8e159bc 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java +++ b/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java @@ -98,9 +98,10 @@ public class MessageUnpacker private long totalReadBytes; /** - * Extra buffer for fixed-length data at the buffer boundary. At most 17-byte buffer (for FIXEXT16) is required. + * Extra buffer for fixed-length data at the buffer boundary. + * At most 8-byte buffer (for readLong used by uint 64 and UTF-8 character decoding) is required. */ - private final MessageBuffer castBuffer = MessageBuffer.newBuffer(24); + private final MessageBuffer castBuffer = MessageBuffer.newBuffer(8); /** * Variable by ensureHeader method. Caller of the method should use this variable to read from returned MessageBuffer. From 2ce99168eaa86930f3c57ec5b8821f3e558c4897 Mon Sep 17 00:00:00 2001 From: Sadayuki Furuhashi Date: Fri, 25 Dec 2015 12:28:43 +0900 Subject: [PATCH 165/234] optimized packer buffer interface --- .../java/org/msgpack/core/MessagePacker.java | 325 ++++++++++-------- .../core/buffer/ChannelBufferOutput.java | 46 ++- .../msgpack/core/buffer/MessageBuffer.java | 5 + .../core/buffer/MessageBufferOutput.java | 48 ++- .../core/buffer/OutputStreamBufferOutput.java | 59 ++-- .../core/example/MessagePackExample.java | 5 - .../org/msgpack/core/MessagePackerTest.scala | 3 +- .../core/buffer/MessageBufferOutputTest.scala | 2 +- .../dataformat/MessagePackGenerator.java | 13 +- 9 files changed, 306 insertions(+), 200 deletions(-) diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessagePacker.java b/msgpack-core/src/main/java/org/msgpack/core/MessagePacker.java index 032cda7f3..11f2fcb5d 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/MessagePacker.java +++ b/msgpack-core/src/main/java/org/msgpack/core/MessagePacker.java @@ -88,15 +88,15 @@ public class MessagePacker private final MessagePack.Config config; private MessageBufferOutput out; + private MessageBuffer buffer; - private MessageBuffer strLenBuffer; private int position; /** * Total written byte size */ - private long flushedBytes; + private long totalFlushBytes; /** * String encoder @@ -119,7 +119,7 @@ public MessagePacker(MessageBufferOutput out, MessagePack.Config config) this.config = checkNotNull(config, "config is null"); this.out = checkNotNull(out, "MessageBufferOutput is null"); this.position = 0; - this.flushedBytes = 0; + this.totalFlushBytes = 0; } /** @@ -134,50 +134,32 @@ public MessageBufferOutput reset(MessageBufferOutput out) // Validate the argument MessageBufferOutput newOut = checkNotNull(out, "MessageBufferOutput is null"); - // Reset the internal states + // Flush before reset + flush(); MessageBufferOutput old = this.out; this.out = newOut; - this.position = 0; - this.flushedBytes = 0; - return old; - } - public long getTotalWrittenBytes() - { - return flushedBytes + position; - } + // Reset totalFlushBytes + this.totalFlushBytes = 0; - private void prepareEncoder() - { - if (encoder == null) { - this.encoder = MessagePack.UTF8.newEncoder().onMalformedInput(config.actionOnMalFormedInput).onUnmappableCharacter(config.actionOnMalFormedInput); - } + return old; } - private void prepareBuffer() - throws IOException + public long getTotalWrittenBytes() { - if (buffer == null) { - buffer = out.next(config.packerBufferSize); - } + return totalFlushBytes + position; } public void flush() throws IOException { - if (buffer == null) { - return; + if (position > 0) { + out.writeBuffer(position); + buffer = null; + totalFlushBytes += position; + position = 0; } - - if (position == buffer.size()) { - out.flush(buffer); - } - else { - out.flush(buffer.slice(0, position)); - } - buffer = null; - flushedBytes += position; - position = 0; + out.flush(); } public void close() @@ -191,12 +173,18 @@ public void close() } } - private void ensureCapacity(int numBytesToWrite) + private void ensureCapacity(int mimimumSize) throws IOException { - if (buffer == null || position + numBytesToWrite >= buffer.size()) { - flush(); - buffer = out.next(Math.max(config.packerBufferSize, numBytesToWrite)); + if (buffer == null) { + buffer = out.next(mimimumSize); + } + else if (position + mimimumSize >= buffer.size()) { + out.writeBuffer(position); + buffer = null; + totalFlushBytes += position; + position = 0; + buffer = out.next(mimimumSize); } } @@ -442,14 +430,44 @@ public MessagePacker packDouble(double v) return this; } - private void packSmallString(String s) + private void packStringByGetBytes(String s) throws IOException { byte[] bytes = s.getBytes(MessagePack.UTF8); packRawStringHeader(bytes.length); - writePayload(bytes); + addPayload(bytes); } + private void prepareEncoder() + { + if (encoder == null) { + this.encoder = MessagePack.UTF8.newEncoder().onMalformedInput(config.actionOnMalFormedInput).onUnmappableCharacter(config.actionOnMalFormedInput); + } + } + + private int encodeStringToBufferAt(int pos, String s) + { + prepareEncoder(); + ByteBuffer bb = buffer.toByteBuffer(pos, buffer.size() - pos); + int startPosition = bb.position(); + CharBuffer in = CharBuffer.wrap(s); + CoderResult cr = encoder.encode(in, bb, true); + if (cr.isError()) { + try { + cr.throwException(); + } + catch (CharacterCodingException e) { + throw new MessageStringCodingException(e); + } + } + if (cr.isUnderflow() || cr.isOverflow()) { + return -1; + } + return bb.position() - startPosition; + } + + private static final int UTF_8_MAX_CHAR_SIZE = 6; + /** * Pack the input String in UTF-8 encoding * @@ -464,77 +482,76 @@ public MessagePacker packString(String s) packRawStringHeader(0); return this; } - - if (s.length() < config.packerSmallStringOptimizationThreshold) { + else if (s.length() < config.packerSmallStringOptimizationThreshold) { // Write the length and payload of small string to the buffer so that it avoids an extra flush of buffer - packSmallString(s); + packStringByGetBytes(s); return this; } - - CharBuffer in = CharBuffer.wrap(s); - prepareEncoder(); - - flush(); - - prepareBuffer(); - boolean isExtension = false; - ByteBuffer encodeBuffer = buffer.toByteBuffer(position, buffer.size() - position); - encoder.reset(); - while (in.hasRemaining()) { - try { - CoderResult cr = encoder.encode(in, encodeBuffer, true); - - // Input data is insufficient - if (cr.isUnderflow()) { - cr = encoder.flush(encodeBuffer); + else if (s.length() < (1 << 8)) { + // ensure capacity for 2-byte raw string header + the maximum string size (+ 1 byte for falback code) + ensureCapacity(2 + s.length() * UTF_8_MAX_CHAR_SIZE + 1); + // keep 2-byte header region and write raw string + int written = encodeStringToBufferAt(position + 2, s); + if (written >= 0) { + if (written < (1 << 8)) { + buffer.putByte(position++, STR8); + buffer.putByte(position++, (byte) written); + position += written; } - - // encodeBuffer is too small - if (cr.isOverflow()) { - // Allocate a larger buffer - int estimatedRemainingSize = Math.max(1, (int) (in.remaining() * encoder.averageBytesPerChar())); - encodeBuffer.flip(); - ByteBuffer newBuffer = ByteBuffer.allocate(Math.max((int) (encodeBuffer.capacity() * 1.5), encodeBuffer.remaining() + estimatedRemainingSize)); - // Coy the current encodeBuffer contents to the new buffer - newBuffer.put(encodeBuffer); - encodeBuffer = newBuffer; - isExtension = true; - encoder.reset(); - continue; - } - - if (cr.isError()) { - if ((cr.isMalformed() && config.actionOnMalFormedInput == CodingErrorAction.REPORT) || - (cr.isUnmappable() && config.actionOnUnmappableCharacter == CodingErrorAction.REPORT)) { - cr.throwException(); + else { + if (written >= (1 << 16)) { + // this must not happen because s.length() is less than 2^8 and (2^8) * UTF_8_MAX_CHAR_SIZE is less than 2^16 + throw new IllegalArgumentException("Unexpected UTF-8 encoder state"); } + // move 1 byte backward to expand 3-byte header region to 3 bytes + buffer.putBytes(position + 3, + buffer.getArray(), buffer.offset() + position + 2, written); + // write 3-byte header header + buffer.putByte(position++, STR16); + buffer.putShort(position, (short) written); + position += 2; + position += written; } + return this; } - catch (CharacterCodingException e) { - throw new MessageStringCodingException(e); + } + else if (s.length() < (1 << 16)) { + // ensure capacity for 3-byte raw string header + the maximum string size (+ 2 bytes for falback code) + ensureCapacity(3 + s.length() * UTF_8_MAX_CHAR_SIZE + 2); + // keep 3-byte header region and write raw string + int written = encodeStringToBufferAt(position + 3, s); + if (written >= 0) { + if (written < (1 << 16)) { + buffer.putByte(position++, STR16); + buffer.putShort(position, (short) written); + position += 2; + position += written; + } + else { + if (written >= (1 << 32)) { + // this must not happen because s.length() is less than 2^16 and (2^16) * UTF_8_MAX_CHAR_SIZE is less than 2^32 + throw new IllegalArgumentException("Unexpected UTF-8 encoder state"); + } + // move 2 bytes backward to expand 3-byte header region to 5 bytes + buffer.putBytes(position + 5, + buffer.getArray(), buffer.offset() + position + 3, written); + // write 3-byte header header + buffer.putByte(position++, STR32); + buffer.putInt(position, written); + position += 4; + position += written; + } + return this; } } - encodeBuffer.flip(); - int strLen = encodeBuffer.remaining(); - - // Preserve the current buffer - MessageBuffer tmpBuf = buffer; - - // Switch the buffer to write the string length - if (strLenBuffer == null) { - strLenBuffer = MessageBuffer.newBuffer(5); - } - buffer = strLenBuffer; - position = 0; - // pack raw string header (string binary size) - packRawStringHeader(strLen); - flush(); // We need to dump the data here to MessageBufferOutput so that we can switch back to the original buffer + // Here doesn't use above optimized code for s.length() < (1 << 32) so that + // ensureCapacity is not called with an integer larger than (3 + ((1 << 16) * UTF_8_MAX_CHAR_SIZE) + 2). + // This makes it sure that MessageBufferOutput.next won't be called a size larger than + // 384KB, which is OK size to keep in memory. - // Reset to the original buffer (or encodeBuffer if new buffer is allocated) - buffer = isExtension ? MessageBuffer.wrap(encodeBuffer) : tmpBuf; - // No need exists to write payload since the encoded string (payload) is already written to the buffer - position = strLen; + // fallback + packStringByGetBytes(s); return this; } @@ -659,72 +676,82 @@ else if (len < (1 << 16)) { return this; } - public MessagePacker writePayload(ByteBuffer src) + /** + * Writes buffer to the output. + * This method is used with packRawStringHeader or packBinaryHeader. + * + * @param src the data to add + * @return this + * @throws IOException + */ + public MessagePacker writePayload(byte[] src) throws IOException { - int len = src.remaining(); - if (len >= config.packerRawDataCopyingThreshold) { - // Use the source ByteBuffer directly to avoid memory copy - - // First, flush the current buffer contents - flush(); + return writePayload(src, 0, src.length); + } - // Wrap the input source as a MessageBuffer - MessageBuffer wrapped = MessageBuffer.wrap(src); - // Then, dump the source data to the output - out.flush(wrapped); - src.position(src.limit()); - flushedBytes += len; + /** + * Writes buffer to the output. + * This method is used with packRawStringHeader or packBinaryHeader. + * + * @param src the data to add + * @param off the start offset in the data + * @param len the number of bytes to add + * @return this + * @throws IOException + */ + public MessagePacker writePayload(byte[] src, int off, int len) + throws IOException + { + if (buffer.size() - position < len || len > 8192) { + flush(); // call flush before write + out.write(src, off, len); + totalFlushBytes += len; } else { - // If the input source is small, simply copy the contents to the buffer - while (src.remaining() > 0) { - if (position >= buffer.size()) { - flush(); - } - prepareBuffer(); - int writeLen = Math.min(buffer.size() - position, src.remaining()); - buffer.putByteBuffer(position, src, writeLen); - position += writeLen; - } + buffer.putBytes(position, src, off, len); + position += len; } - return this; } - public MessagePacker writePayload(byte[] src) + /** + * Writes buffer to the output. + * Unlike writePayload method, addPayload method doesn't copy the source data. It means that the caller + * must not modify the data after calling this method. + * + * @param src the data to add + * @return this + * @throws IOException + */ + public MessagePacker addPayload(byte[] src) throws IOException { - return writePayload(src, 0, src.length); + return addPayload(src, 0, src.length); } - public MessagePacker writePayload(byte[] src, int off, int len) + /** + * Writes buffer to the output. + * Unlike writePayload method, addPayload method doesn't copy the source data. It means that the caller + * must not modify the data after calling this method. + * + * @param src the data to add + * @param off the start offset in the data + * @param len the number of bytes to add + * @return this + * @throws IOException + */ + public MessagePacker addPayload(byte[] src, int off, int len) throws IOException { - if (len >= config.packerRawDataCopyingThreshold) { - // Use the input array directory to avoid memory copy - - // Flush the current buffer contents - flush(); - - // Wrap the input array as a MessageBuffer - MessageBuffer wrapped = MessageBuffer.wrap(src).slice(off, len); - // Dump the source data to the output - out.flush(wrapped); - flushedBytes += len; + if (buffer.size() - position < len || len > 8192) { + flush(); // call flush before add + out.add(src, off, len); + totalFlushBytes += len; } else { - int cursor = 0; - while (cursor < len) { - if (buffer != null && position >= buffer.size()) { - flush(); - } - prepareBuffer(); - int writeLen = Math.min(buffer.size() - position, len - cursor); - buffer.putBytes(position, src, off + cursor, writeLen); - position += writeLen; - cursor += writeLen; - } + buffer.putBytes(position, src, off, len); + position += len; } return this; } diff --git a/msgpack-core/src/main/java/org/msgpack/core/buffer/ChannelBufferOutput.java b/msgpack-core/src/main/java/org/msgpack/core/buffer/ChannelBufferOutput.java index 9ecddf3ac..b981cc95d 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/buffer/ChannelBufferOutput.java +++ b/msgpack-core/src/main/java/org/msgpack/core/buffer/ChannelBufferOutput.java @@ -31,15 +31,21 @@ public class ChannelBufferOutput private MessageBuffer buffer; public ChannelBufferOutput(WritableByteChannel channel) + { + this(channel, 8192); + } + + public ChannelBufferOutput(WritableByteChannel channel, int bufferSize) { this.channel = checkNotNull(channel, "output channel is null"); + this.buffer = MessageBuffer.newBuffer(bufferSize); } /** - * Reset channel. This method doesn't close the old resource. + * Reset channel. This method doesn't close the old channel. * * @param channel new channel - * @return the old resource + * @return the old channel */ public WritableByteChannel reset(WritableByteChannel channel) throws IOException @@ -50,21 +56,40 @@ public WritableByteChannel reset(WritableByteChannel channel) } @Override - public MessageBuffer next(int bufferSize) + public MessageBuffer next(int mimimumSize) throws IOException { - if (buffer == null || buffer.size() != bufferSize) { - buffer = MessageBuffer.newBuffer(bufferSize); + if (buffer.size() < mimimumSize) { + buffer = MessageBuffer.newBuffer(mimimumSize); } return buffer; } @Override - public void flush(MessageBuffer buf) + public void writeBuffer(int length) + throws IOException + { + ByteBuffer bb = buffer.toByteBuffer(0, length); + while (bb.hasRemaining()) { + channel.write(bb); + } + } + + @Override + public void write(byte[] buffer, int offset, int length) throws IOException { - ByteBuffer bb = buf.toByteBuffer(); - channel.write(bb); + ByteBuffer bb = ByteBuffer.wrap(buffer, offset, length); + while (bb.hasRemaining()) { + channel.write(bb); + } + } + + @Override + public void add(byte[] buffer, int offset, int length) + throws IOException + { + write(buffer, offset, length); } @Override @@ -73,4 +98,9 @@ public void close() { channel.close(); } + + @Override + public void flush() + throws IOException + { } } diff --git a/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBuffer.java b/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBuffer.java index 302105f83..fce8020ce 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBuffer.java +++ b/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBuffer.java @@ -210,6 +210,11 @@ public static MessageBuffer wrap(byte[] array) return newMessageBuffer(array); } + public static MessageBuffer wrap(byte[] array, int offset, int length) + { + return newMessageBuffer(array).slice(offset, length); + } + public static MessageBuffer wrap(ByteBuffer bb) { return newMessageBuffer(bb).slice(bb.position(), bb.remaining()); diff --git a/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferOutput.java b/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferOutput.java index 77fe12454..92eb760a9 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferOutput.java +++ b/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferOutput.java @@ -17,30 +17,60 @@ import java.io.Closeable; import java.io.IOException; +import java.io.Flushable; /** - * Provides a sequence of MessageBuffers for packing the input data + * Provides a buffered output stream for packing objects */ public interface MessageBufferOutput - extends Closeable + extends Closeable, Flushable { /** - * Retrieves the next buffer for writing message packed data + * Allocates the next buffer for writing message packed data. + * If the previously allocated buffer is not flushed yet, this next method should discard + * it without writing it. * - * @param bufferSize the buffer size to retrieve + * @param mimimumSize the mimium required buffer size to allocate * @return * @throws IOException */ - public MessageBuffer next(int bufferSize) + public MessageBuffer next(int mimimumSize) throws IOException; /** - * Output the buffer contents. If you need to output a part of the - * buffer use {@link MessageBuffer#slice(int, int)} + * Flushes the previously allocated buffer. + * This method is not always called because next method also flushes previously allocated buffer. + * This method is called when write method is called or application wants to control the timing of flush. * - * @param buf + * @param length the size of buffer to flush * @throws IOException */ - public void flush(MessageBuffer buf) + public void writeBuffer(int length) + throws IOException; + + /** + * Writes an external payload data. + * This method should follow semantics of OutputStream. + * + * @param buffer the data to write + * @param offset the start offset in the data + * @param length the number of bytes to write + * @return + * @throws IOException + */ + public void write(byte[] buffer, int offset, int length) + throws IOException; + + /** + * Writes an external payload data. + * This buffer is given - this MessageBufferOutput owns the buffer and may modify contents of the buffer. Contents of this buffer won't be modified by the caller. + * + * @param buffer the data to add + * @param offset the start offset in the data + * @param length the number of bytes to add + * @return + * @throws IOException + */ + public void add(byte[] buffer, int offset, int length) throws IOException; } diff --git a/msgpack-core/src/main/java/org/msgpack/core/buffer/OutputStreamBufferOutput.java b/msgpack-core/src/main/java/org/msgpack/core/buffer/OutputStreamBufferOutput.java index 07d423bf0..d6f17c783 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/buffer/OutputStreamBufferOutput.java +++ b/msgpack-core/src/main/java/org/msgpack/core/buffer/OutputStreamBufferOutput.java @@ -28,18 +28,23 @@ public class OutputStreamBufferOutput { private OutputStream out; private MessageBuffer buffer; - private byte[] tmpBuf; public OutputStreamBufferOutput(OutputStream out) + { + this(out, 8192); + } + + public OutputStreamBufferOutput(OutputStream out, int bufferSize) { this.out = checkNotNull(out, "output is null"); + this.buffer = MessageBuffer.newBuffer(bufferSize); } /** - * Reset Stream. This method doesn't close the old resource. + * Reset Stream. This method doesn't close the old stream. * * @param out new stream - * @return the old resource + * @return the old stream */ public OutputStream reset(OutputStream out) throws IOException @@ -50,41 +55,47 @@ public OutputStream reset(OutputStream out) } @Override - public MessageBuffer next(int bufferSize) + public MessageBuffer next(int mimimumSize) throws IOException { - if (buffer == null || buffer.size != bufferSize) { - buffer = MessageBuffer.newBuffer(bufferSize); + if (buffer.size() < mimimumSize) { + buffer = MessageBuffer.newBuffer(mimimumSize); } return buffer; } @Override - public void flush(MessageBuffer buf) + public void writeBuffer(int length) throws IOException { - int writeLen = buf.size(); - if (buf.hasArray()) { - out.write(buf.getArray(), buf.offset(), writeLen); - } - else { - if (tmpBuf == null || tmpBuf.length < writeLen) { - tmpBuf = new byte[writeLen]; - } - buf.getBytes(0, tmpBuf, 0, writeLen); - out.write(tmpBuf, 0, writeLen); - } + write(buffer.getArray(), buffer.offset(), length); + } + + @Override + public void write(byte[] buffer, int offset, int length) + throws IOException + { + out.write(buffer, offset, length); + } + + @Override + public void add(byte[] buffer, int offset, int length) + throws IOException + { + write(buffer, offset, length); } @Override public void close() throws IOException { - try { - out.flush(); - } - finally { - out.close(); - } + out.close(); + } + + @Override + public void flush() + throws IOException + { + out.flush(); } } diff --git a/msgpack-core/src/test/java/org/msgpack/core/example/MessagePackExample.java b/msgpack-core/src/test/java/org/msgpack/core/example/MessagePackExample.java index a74c5cd18..7636742e0 100644 --- a/msgpack-core/src/test/java/org/msgpack/core/example/MessagePackExample.java +++ b/msgpack-core/src/test/java/org/msgpack/core/example/MessagePackExample.java @@ -153,11 +153,6 @@ public static void packer() .packArrayHeader(2) .packString("xxx-xxxx") .packString("yyy-yyyy"); - - // [Advanced] write data using ByteBuffer - ByteBuffer bb = ByteBuffer.wrap(new byte[] {'b', 'i', 'n', 'a', 'r', 'y', 'd', 'a', 't', 'a'}); - packer.packBinaryHeader(bb.remaining()); - packer.writePayload(bb); } /** diff --git a/msgpack-core/src/test/scala/org/msgpack/core/MessagePackerTest.scala b/msgpack-core/src/test/scala/org/msgpack/core/MessagePackerTest.scala index f598a133f..f6971b331 100644 --- a/msgpack-core/src/test/scala/org/msgpack/core/MessagePackerTest.scala +++ b/msgpack-core/src/test/scala/org/msgpack/core/MessagePackerTest.scala @@ -283,12 +283,11 @@ class MessagePackerTest "support read-only buffer" taggedAs ("read-only") in { val payload = Array[Byte](1) - val buffer = ByteBuffer.wrap(payload).asReadOnlyBuffer() val out = new ByteArrayOutputStream() val packer = MessagePack.newDefaultPacker(out) .packBinaryHeader(1) - .writePayload(buffer) + .writePayload(payload) .close() } } diff --git a/msgpack-core/src/test/scala/org/msgpack/core/buffer/MessageBufferOutputTest.scala b/msgpack-core/src/test/scala/org/msgpack/core/buffer/MessageBufferOutputTest.scala index 8616d1c69..1869f2aad 100644 --- a/msgpack-core/src/test/scala/org/msgpack/core/buffer/MessageBufferOutputTest.scala +++ b/msgpack-core/src/test/scala/org/msgpack/core/buffer/MessageBufferOutputTest.scala @@ -44,7 +44,7 @@ class MessageBufferOutputTest def writeIntToBuf(buf: MessageBufferOutput) = { val mb0 = buf.next(8) mb0.putInt(0, 42) - buf.flush(mb0) + buf.writeBuffer(4) buf.close } diff --git a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackGenerator.java b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackGenerator.java index 189197209..c040ee7dd 100644 --- a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackGenerator.java +++ b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackGenerator.java @@ -183,8 +183,17 @@ else if (v instanceof Integer) { } else if (v instanceof ByteBuffer) { ByteBuffer bb = (ByteBuffer) v; - messagePacker.packBinaryHeader(bb.limit()); - messagePacker.writePayload(bb); + int len = bb.remaining(); + if (bb.hasArray()) { + messagePacker.packBinaryHeader(len); + messagePacker.writePayload(bb.array(), bb.arrayOffset(), len); + } + else { + byte[] data = new byte[len]; + bb.get(data); + messagePacker.packBinaryHeader(len); + messagePacker.addPayload(data); + } } else if (v instanceof String) { messagePacker.packString((String) v); From 9b2f4e32d9d85ce1ac0a03b86e6b2df6d24221a4 Mon Sep 17 00:00:00 2001 From: Mitsunori Komatsu Date: Fri, 25 Dec 2015 13:16:01 +0900 Subject: [PATCH 166/234] Take care of the order of benchmarks and remove outliers --- .../dataformat/benchmark/Benchmarker.java | 23 +++++++++++-------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/benchmark/Benchmarker.java b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/benchmark/Benchmarker.java index 4a11c4307..980348024 100644 --- a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/benchmark/Benchmarker.java +++ b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/benchmark/Benchmarker.java @@ -19,6 +19,7 @@ import org.apache.commons.math3.stat.descriptive.moment.StandardDeviation; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; public class Benchmarker @@ -58,23 +59,20 @@ public void run(int count, int warmupCount) throws Exception { List> benchmarksResults = new ArrayList>(benchmarkableList.size()); - for (Benchmarkable benchmark : benchmarkableList) { - double[] durations = new double[count]; - - for (int i = 0; i < count + warmupCount; i++) { - if (i >= warmupCount) { - System.gc(); - } + benchmarksResults.add(new Tuple(benchmark.label, new double[count])); + } + for (int i = 0; i < count + warmupCount; i++) { + for (int bi = 0; bi < benchmarkableList.size(); bi++) { + Benchmarkable benchmark = benchmarkableList.get(bi); long currentTimeNanos = System.nanoTime(); benchmark.run(); if (i >= warmupCount) { - durations[i - warmupCount] = (System.nanoTime() - currentTimeNanos) / 1000000.0; + benchmarksResults.get(bi).second[i - warmupCount] = (System.nanoTime() - currentTimeNanos) / 1000000.0; } } - benchmarksResults.add(new Tuple(benchmark.label, durations)); } for (Tuple benchmarkResult : benchmarksResults) { @@ -82,8 +80,13 @@ public void run(int count, int warmupCount) } } - private void printStat(String label, double[] values) + private void printStat(String label, double[] origValues) { + double[] values = origValues; + Arrays.sort(origValues); + if (origValues.length > 2) { + values = Arrays.copyOfRange(origValues, 1, origValues.length - 1); + } StandardDeviation standardDeviation = new StandardDeviation(); System.out.println(label + ":"); System.out.println(String.format(" mean : %8.3f", StatUtils.mean(values))); From bc6830e89c7536c19aaf5d4eaea69fd9282aa78a Mon Sep 17 00:00:00 2001 From: Sadayuki Furuhashi Date: Fri, 25 Dec 2015 15:28:15 +0900 Subject: [PATCH 167/234] reorganized MessagePacker interface to use MessagePacker --- .../org/msgpack/core/MessageBufferPacker.java | 73 ++++ .../java/org/msgpack/core/MessageFormat.java | 89 ++++- .../java/org/msgpack/core/MessagePack.java | 374 ++---------------- .../org/msgpack/core/MessagePackFactory.java | 203 ++++++++++ .../java/org/msgpack/core/MessagePacker.java | 88 ++--- .../org/msgpack/core/MessageUnpacker.java | 78 ++-- .../core/buffer/ArrayBufferOutput.java | 136 +++++++ .../core/example/MessagePackExample.java | 15 +- .../org/msgpack/core/MessageFormatTest.scala | 2 +- .../org/msgpack/core/MessagePackTest.scala | 24 +- .../org/msgpack/core/MessagePackerTest.scala | 19 +- .../msgpack/core/MessageUnpackerTest.scala | 46 +-- .../core/buffer/MessageBufferInputTest.scala | 6 +- .../org/msgpack/value/ValueTypeTest.scala | 2 +- 14 files changed, 686 insertions(+), 469 deletions(-) create mode 100644 msgpack-core/src/main/java/org/msgpack/core/MessageBufferPacker.java create mode 100644 msgpack-core/src/main/java/org/msgpack/core/MessagePackFactory.java create mode 100644 msgpack-core/src/main/java/org/msgpack/core/buffer/ArrayBufferOutput.java diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessageBufferPacker.java b/msgpack-core/src/main/java/org/msgpack/core/MessageBufferPacker.java new file mode 100644 index 000000000..02b94f773 --- /dev/null +++ b/msgpack-core/src/main/java/org/msgpack/core/MessageBufferPacker.java @@ -0,0 +1,73 @@ +// +// MessagePack for Java +// +// 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.core; + +import org.msgpack.core.buffer.MessageBuffer; +import org.msgpack.core.buffer.MessageBufferOutput; +import org.msgpack.core.buffer.ArrayBufferOutput; + +import java.io.IOException; +import java.util.List; + +public class MessageBufferPacker + extends MessagePacker +{ + public MessageBufferPacker() + { + this(new ArrayBufferOutput()); + } + + public MessageBufferPacker(ArrayBufferOutput out) + { + super(out); + } + + @Override + public MessageBufferPacker setSmallStringOptimizationThreshold(int bytes) + { + super.setSmallStringOptimizationThreshold(bytes); + return this; + } + + public MessageBufferOutput reset(MessageBufferOutput out) + throws IOException + { + if (!(out instanceof ArrayBufferOutput)) { + throw new IllegalArgumentException("MessageBufferPacker accepts only ArrayBufferOutput"); + } + return super.reset(out); + } + + public void clear() + { + ((ArrayBufferOutput) out).clear(); + } + + public byte[] toByteArray() + { + return ((ArrayBufferOutput) out).toByteArray(); + } + + public MessageBuffer toMessageBuffer() + { + return ((ArrayBufferOutput) out).toMessageBuffer(); + } + + public List toBufferList() + { + return ((ArrayBufferOutput) out).toBufferList(); + } +} diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessageFormat.java b/msgpack-core/src/main/java/org/msgpack/core/MessageFormat.java index 8e44b0aae..17a0f1555 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/MessageFormat.java +++ b/msgpack-core/src/main/java/org/msgpack/core/MessageFormat.java @@ -15,7 +15,6 @@ // package org.msgpack.core; -import org.msgpack.core.MessagePack.Code; import org.msgpack.core.annotations.VisibleForTesting; import org.msgpack.value.ValueType; @@ -66,6 +65,94 @@ public enum MessageFormat MAP32(ValueType.MAP), NEGFIXINT(ValueType.INTEGER); + /** + * The prefix code set of MessagePack. See also https://github.com/msgpack/msgpack/blob/master/spec.md for details. + */ + public static final class Code + { + public static final boolean isFixInt(byte b) + { + int v = b & 0xFF; + return v <= 0x7f || v >= 0xe0; + } + + public static final boolean isPosFixInt(byte b) + { + return (b & POSFIXINT_MASK) == 0; + } + + public static final boolean isNegFixInt(byte b) + { + return (b & NEGFIXINT_PREFIX) == NEGFIXINT_PREFIX; + } + + public static final boolean isFixStr(byte b) + { + return (b & (byte) 0xe0) == Code.FIXSTR_PREFIX; + } + + public static final boolean isFixedArray(byte b) + { + return (b & (byte) 0xf0) == Code.FIXARRAY_PREFIX; + } + + public static final boolean isFixedMap(byte b) + { + return (b & (byte) 0xe0) == Code.FIXMAP_PREFIX; + } + + public static final boolean isFixedRaw(byte b) + { + return (b & (byte) 0xe0) == Code.FIXSTR_PREFIX; + } + + public static final byte POSFIXINT_MASK = (byte) 0x80; + + public static final byte FIXMAP_PREFIX = (byte) 0x80; + public static final byte FIXARRAY_PREFIX = (byte) 0x90; + public static final byte FIXSTR_PREFIX = (byte) 0xa0; + + public static final byte NIL = (byte) 0xc0; + public static final byte NEVER_USED = (byte) 0xc1; + public static final byte FALSE = (byte) 0xc2; + public static final byte TRUE = (byte) 0xc3; + public static final byte BIN8 = (byte) 0xc4; + public static final byte BIN16 = (byte) 0xc5; + public static final byte BIN32 = (byte) 0xc6; + public static final byte EXT8 = (byte) 0xc7; + public static final byte EXT16 = (byte) 0xc8; + public static final byte EXT32 = (byte) 0xc9; + public static final byte FLOAT32 = (byte) 0xca; + public static final byte FLOAT64 = (byte) 0xcb; + public static final byte UINT8 = (byte) 0xcc; + public static final byte UINT16 = (byte) 0xcd; + public static final byte UINT32 = (byte) 0xce; + public static final byte UINT64 = (byte) 0xcf; + + public static final byte INT8 = (byte) 0xd0; + public static final byte INT16 = (byte) 0xd1; + public static final byte INT32 = (byte) 0xd2; + public static final byte INT64 = (byte) 0xd3; + + public static final byte FIXEXT1 = (byte) 0xd4; + public static final byte FIXEXT2 = (byte) 0xd5; + public static final byte FIXEXT4 = (byte) 0xd6; + public static final byte FIXEXT8 = (byte) 0xd7; + public static final byte FIXEXT16 = (byte) 0xd8; + + public static final byte STR8 = (byte) 0xd9; + public static final byte STR16 = (byte) 0xda; + public static final byte STR32 = (byte) 0xdb; + + public static final byte ARRAY16 = (byte) 0xdc; + public static final byte ARRAY32 = (byte) 0xdd; + + public static final byte MAP16 = (byte) 0xde; + public static final byte MAP32 = (byte) 0xdf; + + public static final byte NEGFIXINT_PREFIX = (byte) 0xe0; + } + private static final MessageFormat[] formatTable = new MessageFormat[256]; private final ValueType valueType; diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessagePack.java b/msgpack-core/src/main/java/org/msgpack/core/MessagePack.java index 9847d461e..8af53a884 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/MessagePack.java +++ b/msgpack-core/src/main/java/org/msgpack/core/MessagePack.java @@ -37,406 +37,102 @@ public class MessagePack { public static final Charset UTF8 = Charset.forName("UTF-8"); - /** - * Message packer/unpacker configuration object - */ - public static class Config - { - /** - * allow unpackBinaryHeader to read str format family (default:true) - */ - public final boolean readStringAsBinary; - /** - * allow unpackRawStringHeader and unpackString to read bin format family (default: true) - */ - public final boolean readBinaryAsString; - /** - * Action when encountered a malformed input - */ - public final CodingErrorAction actionOnMalFormedInput; - /** - * Action when an unmappable character is found - */ - public final CodingErrorAction actionOnUnmappableCharacter; - /** - * unpackString size limit. (default: Integer.MAX_VALUE) - */ - public final int maxUnpackStringSize; - public final int stringEncoderBufferSize; - public final int stringDecoderBufferSize; - public final int packerBufferSize; - public final int packerRawDataCopyingThreshold; - /** - * Use String.getBytes() for strings smaller than this threshold. - * Note that this parameter is subject to change. - */ - public final int packerSmallStringOptimizationThreshold; - - public Config( - boolean readStringAsBinary, - boolean readBinaryAsString, - CodingErrorAction actionOnMalFormedInput, - CodingErrorAction actionOnUnmappableCharacter, - int maxUnpackStringSize, - int stringEncoderBufferSize, - int stringDecoderBufferSize, - int packerBufferSize, - int packerSmallStringOptimizationThreshold, - int packerRawDataCopyingThreshold) - { - checkArgument(packerBufferSize > 0, "packer buffer size must be larger than 0: " + packerBufferSize); - checkArgument(stringEncoderBufferSize > 0, "string encoder buffer size must be larger than 0: " + stringEncoderBufferSize); - checkArgument(stringDecoderBufferSize > 0, "string decoder buffer size must be larger than 0: " + stringDecoderBufferSize); - - this.readStringAsBinary = readStringAsBinary; - this.readBinaryAsString = readBinaryAsString; - this.actionOnMalFormedInput = actionOnMalFormedInput; - this.actionOnUnmappableCharacter = actionOnUnmappableCharacter; - this.maxUnpackStringSize = maxUnpackStringSize; - this.stringEncoderBufferSize = stringEncoderBufferSize; - this.stringDecoderBufferSize = stringDecoderBufferSize; - this.packerBufferSize = packerBufferSize; - this.packerSmallStringOptimizationThreshold = packerSmallStringOptimizationThreshold; - this.packerRawDataCopyingThreshold = packerRawDataCopyingThreshold; - } - } - - /** - * Builder of the configuration object - */ - public static class ConfigBuilder - { - private boolean readStringAsBinary = true; - private boolean readBinaryAsString = true; - - private CodingErrorAction onMalFormedInput = CodingErrorAction.REPLACE; - private CodingErrorAction onUnmappableCharacter = CodingErrorAction.REPLACE; - - private int maxUnpackStringSize = Integer.MAX_VALUE; - private int stringEncoderBufferSize = 8192; - private int stringDecoderBufferSize = 8192; - private int packerBufferSize = 8192; - private int packerSmallStringOptimizationThreshold = 512; // This parameter is subject to change - private int packerRawDataCopyingThreshold = 512; - - public Config build() - { - return new Config( - readStringAsBinary, - readBinaryAsString, - onMalFormedInput, - onUnmappableCharacter, - maxUnpackStringSize, - stringEncoderBufferSize, - stringDecoderBufferSize, - packerBufferSize, - packerSmallStringOptimizationThreshold, - packerRawDataCopyingThreshold - ); - } - - public ConfigBuilder readStringAsBinary(boolean enable) - { - this.readStringAsBinary = enable; - return this; - } - - public ConfigBuilder readBinaryAsString(boolean enable) - { - this.readBinaryAsString = enable; - return this; - } - - public ConfigBuilder onMalFormedInput(CodingErrorAction action) - { - this.onMalFormedInput = action; - return this; - } - - public ConfigBuilder onUnmappableCharacter(CodingErrorAction action) - { - this.onUnmappableCharacter = action; - return this; - } - - public ConfigBuilder maxUnpackStringSize(int size) - { - this.maxUnpackStringSize = size; - return this; - } - - public ConfigBuilder stringEncoderBufferSize(int size) - { - this.stringEncoderBufferSize = size; - return this; - } - - public ConfigBuilder stringDecoderBufferSize(int size) - { - this.stringDecoderBufferSize = size; - return this; - } - - public ConfigBuilder packerBufferSize(int size) - { - this.packerBufferSize = size; - return this; - } - - public ConfigBuilder packerSmallStringOptimizationThreshold(int threshold) - { - this.packerSmallStringOptimizationThreshold = threshold; - return this; - } - - public ConfigBuilder packerRawDataCopyingThreshold(int threshold) - { - this.packerRawDataCopyingThreshold = threshold; - return this; - } - } + private static MessagePackFactory defaultFactory = new MessagePackFactory(); /** - * Default configuration, which is visible only from classes in the core package. + * Sets the default configuration used for the static constructor methods of this MessagePack class. */ - static final Config DEFAULT_CONFIG = new ConfigBuilder().build(); - - /** - * The prefix code set of MessagePack. See also https://github.com/msgpack/msgpack/blob/master/spec.md for details. - */ - public static final class Code - { - public static final boolean isFixInt(byte b) - { - int v = b & 0xFF; - return v <= 0x7f || v >= 0xe0; - } - - public static final boolean isPosFixInt(byte b) - { - return (b & POSFIXINT_MASK) == 0; - } - - public static final boolean isNegFixInt(byte b) - { - return (b & NEGFIXINT_PREFIX) == NEGFIXINT_PREFIX; - } - - public static final boolean isFixStr(byte b) - { - return (b & (byte) 0xe0) == Code.FIXSTR_PREFIX; - } - - public static final boolean isFixedArray(byte b) - { - return (b & (byte) 0xf0) == Code.FIXARRAY_PREFIX; - } - - public static final boolean isFixedMap(byte b) - { - return (b & (byte) 0xe0) == Code.FIXMAP_PREFIX; - } - - public static final boolean isFixedRaw(byte b) - { - return (b & (byte) 0xe0) == Code.FIXSTR_PREFIX; - } - - public static final byte POSFIXINT_MASK = (byte) 0x80; - - public static final byte FIXMAP_PREFIX = (byte) 0x80; - public static final byte FIXARRAY_PREFIX = (byte) 0x90; - public static final byte FIXSTR_PREFIX = (byte) 0xa0; - - public static final byte NIL = (byte) 0xc0; - public static final byte NEVER_USED = (byte) 0xc1; - public static final byte FALSE = (byte) 0xc2; - public static final byte TRUE = (byte) 0xc3; - public static final byte BIN8 = (byte) 0xc4; - public static final byte BIN16 = (byte) 0xc5; - public static final byte BIN32 = (byte) 0xc6; - public static final byte EXT8 = (byte) 0xc7; - public static final byte EXT16 = (byte) 0xc8; - public static final byte EXT32 = (byte) 0xc9; - public static final byte FLOAT32 = (byte) 0xca; - public static final byte FLOAT64 = (byte) 0xcb; - public static final byte UINT8 = (byte) 0xcc; - public static final byte UINT16 = (byte) 0xcd; - public static final byte UINT32 = (byte) 0xce; - public static final byte UINT64 = (byte) 0xcf; - - public static final byte INT8 = (byte) 0xd0; - public static final byte INT16 = (byte) 0xd1; - public static final byte INT32 = (byte) 0xd2; - public static final byte INT64 = (byte) 0xd3; - - public static final byte FIXEXT1 = (byte) 0xd4; - public static final byte FIXEXT2 = (byte) 0xd5; - public static final byte FIXEXT4 = (byte) 0xd6; - public static final byte FIXEXT8 = (byte) 0xd7; - public static final byte FIXEXT16 = (byte) 0xd8; - - public static final byte STR8 = (byte) 0xd9; - public static final byte STR16 = (byte) 0xda; - public static final byte STR32 = (byte) 0xdb; - - public static final byte ARRAY16 = (byte) 0xdc; - public static final byte ARRAY32 = (byte) 0xdd; - - public static final byte MAP16 = (byte) 0xde; - public static final byte MAP32 = (byte) 0xdf; - - public static final byte NEGFIXINT_PREFIX = (byte) 0xe0; - } - - // Packer/Unpacker factory methods - - private final MessagePack.Config config; - - public MessagePack() + public static void setDefaultFactory(MessagePackFactory newDefaultFactory) { - this(MessagePack.DEFAULT_CONFIG); + defaultFactory = newDefaultFactory; } - public MessagePack(MessagePack.Config config) + public static MessagePackFactory getDefaultFactory() { - this.config = config; + return defaultFactory; } - /** - * Default MessagePack packer/unpacker factory - */ - public static final MessagePack DEFAULT = new MessagePack(MessagePack.DEFAULT_CONFIG); + private MessagePack() + { } /** - * Create a MessagePacker that outputs the packed data to the specified stream, using the default configuration + * Equivalent to getDefaultFactory().newPacker(out). * * @param out * @return */ public static MessagePacker newDefaultPacker(OutputStream out) { - return DEFAULT.newPacker(out); + return defaultFactory.newPacker(out); } /** - * Create a MessagePacker that outputs the packed data to the specified channel, using the default configuration + * Equivalent to getDefaultFactory().newPacker(channel). * * @param channel * @return */ public static MessagePacker newDefaultPacker(WritableByteChannel channel) { - return DEFAULT.newPacker(channel); - } - - /** - * Create a MessageUnpacker that reads data from then given InputStream, using the default configuration - * - * @param in - * @return - */ - public static MessageUnpacker newDefaultUnpacker(InputStream in) - { - return DEFAULT.newUnpacker(in); + return defaultFactory.newPacker(channel); } /** - * Create a MessageUnpacker that reads data from the given channel, using the default configuration + * Equivalent to getDefaultFactory().newBufferPacker() * * @param channel * @return */ - public static MessageUnpacker newDefaultUnpacker(ReadableByteChannel channel) - { - return DEFAULT.newUnpacker(channel); - } - - /** - * Create a MessageUnpacker that reads data from the given byte array, using the default configuration - * - * @param arr - * @return - */ - public static MessageUnpacker newDefaultUnpacker(byte[] arr) + public static MessageBufferPacker newDefaultBufferPacker() { - return DEFAULT.newUnpacker(arr); + return defaultFactory.newBufferPacker(); } /** - * Create a MessageUnpacker that reads data form the given byte array [offset, .. offset+length), using the default - * configuration. + * Equivalent to getDefaultFactory().newUnpacker(in). * - * @param arr - * @param offset - * @param length + * @param in * @return */ - public static MessageUnpacker newDefaultUnpacker(byte[] arr, int offset, int length) - { - return DEFAULT.newUnpacker(arr, offset, length); - } - - /** - * Create a MessagePacker that outputs the packed data to the specified stream - * - * @param out - */ - public MessagePacker newPacker(OutputStream out) + public static MessageUnpacker newDefaultUnpacker(InputStream in) { - return new MessagePacker(new OutputStreamBufferOutput(out), config); + return defaultFactory.newUnpacker(in); } /** - * Create a MessagePacker that outputs the packed data to the specified channel + * Equivalent to getDefaultFactory().newUnpacker(channel). * * @param channel + * @return */ - public MessagePacker newPacker(WritableByteChannel channel) - { - return new MessagePacker(new ChannelBufferOutput(channel), config); - } - - /** - * Create a MessageUnpacker that reads data from the given InputStream. - * For reading data efficiently from byte[], use {@link MessageUnpacker(byte[])} or {@link MessageUnpacker(byte[], int, int)} instead of this constructor. - * - * @param in - */ - public MessageUnpacker newUnpacker(InputStream in) - { - return new MessageUnpacker(InputStreamBufferInput.newBufferInput(in), config); - } - - /** - * Create a MessageUnpacker that reads data from the given ReadableByteChannel. - * - * @param in - */ - public MessageUnpacker newUnpacker(ReadableByteChannel in) + public static MessageUnpacker newDefaultUnpacker(ReadableByteChannel channel) { - return new MessageUnpacker(new ChannelBufferInput(in), config); + return defaultFactory.newUnpacker(channel); } /** - * Create a MessageUnpacker that reads data from the given byte array. + * Equivalent to getDefaultFactory().newUnpacker(contents). * - * @param arr + * @param contents + * @return */ - public MessageUnpacker newUnpacker(byte[] arr) + public static MessageUnpacker newDefaultUnpacker(byte[] contents) { - return new MessageUnpacker(new ArrayBufferInput(arr), config); + return defaultFactory.newUnpacker(contents); } /** - * Create a MessageUnpacker that reads data from the given byte array [offset, offset+length) + * Equivalent to getDefaultFactory().newUnpacker(contents, offset, length). * - * @param arr + * @param contents * @param offset * @param length + * @return */ - public MessageUnpacker newUnpacker(byte[] arr, int offset, int length) + public static MessageUnpacker newDefaultUnpacker(byte[] contents, int offset, int length) { - return new MessageUnpacker(new ArrayBufferInput(arr, offset, length), config); + return defaultFactory.newUnpacker(contents, offset, length); } + + // TODO add convenient methods here to pack/unpack objects with byte array/stream } diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessagePackFactory.java b/msgpack-core/src/main/java/org/msgpack/core/MessagePackFactory.java new file mode 100644 index 000000000..f76df5490 --- /dev/null +++ b/msgpack-core/src/main/java/org/msgpack/core/MessagePackFactory.java @@ -0,0 +1,203 @@ +// +// MessagePack for Java +// +// 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.core; + +import org.msgpack.core.buffer.ArrayBufferInput; +import org.msgpack.core.buffer.ChannelBufferInput; +import org.msgpack.core.buffer.ChannelBufferOutput; +import org.msgpack.core.buffer.InputStreamBufferInput; +import org.msgpack.core.buffer.OutputStreamBufferOutput; +import org.msgpack.core.buffer.MessageBufferInput; +import org.msgpack.core.buffer.MessageBufferOutput; + +import java.io.InputStream; +import java.io.OutputStream; +import java.nio.channels.WritableByteChannel; +import java.nio.channels.ReadableByteChannel; + +import java.nio.charset.CodingErrorAction; +import static org.msgpack.core.Preconditions.checkArgument; + +public class MessagePackFactory +{ + private int packerSmallStringOptimizationThreshold = 512; + + private boolean unpackAllowStringAsBinary = true; + private boolean unpackAllowBinaryAsString = true; + private CodingErrorAction unpackActionOnMalformedString = CodingErrorAction.REPLACE; + private CodingErrorAction unpackActionOnUnmappableString = CodingErrorAction.REPLACE; + private int unpackStringSizeLimit = Integer.MAX_VALUE; + private int unpackStringDecoderBufferSize = 8192; + + private int inputBufferSize = 16*1024; + private int outputBufferSize = 16*1024; + + public MessagePacker newPacker(OutputStream out) + { + return newPacker(new OutputStreamBufferOutput(out)); + } + + public MessagePacker newPacker(WritableByteChannel channel) + { + return newPacker(new ChannelBufferOutput(channel)); + } + + public MessagePacker newPacker(MessageBufferOutput output) + { + return new MessagePacker(output) + .setSmallStringOptimizationThreshold(packerSmallStringOptimizationThreshold); + } + + public MessageBufferPacker newBufferPacker() + { + return new MessageBufferPacker() + .setSmallStringOptimizationThreshold(packerSmallStringOptimizationThreshold); + } + + public MessageUnpacker newUnpacker(byte[] contents) + { + return newUnpacker(contents, 0, contents.length); + } + + public MessageUnpacker newUnpacker(byte[] contents, int offset, int length) + { + return newUnpacker(new ArrayBufferInput(contents, offset, length)); + } + + public MessageUnpacker newUnpacker(InputStream in) + { + return newUnpacker(new InputStreamBufferInput(in)); + } + + public MessageUnpacker newUnpacker(ReadableByteChannel channel) + { + return newUnpacker(new ChannelBufferInput(channel)); + } + + public MessageUnpacker newUnpacker(MessageBufferInput input) + { + return new MessageUnpacker(input) + .setAllowStringAsBinary(unpackAllowStringAsBinary) + .setAllowBinaryAsString(unpackAllowBinaryAsString) + .setActionOnMalformedString(unpackActionOnMalformedString) + .setActionOnUnmappableString(unpackActionOnUnmappableString) + .setStringSizeLimit(unpackStringSizeLimit) + .setStringDecoderBufferSize(unpackStringDecoderBufferSize); + } + + /** + * Use String.getBytes() for strings smaller than this threshold. + * Note that this parameter is subject to change. + */ + public MessagePackFactory packerSmallStringOptimizationThreshold(int bytes) + { + this.packerSmallStringOptimizationThreshold = bytes; + return this; + } + + public MessagePackFactory unpackAllowStringAsBinary(boolean enabled) + { + this.unpackAllowStringAsBinary = enabled; + return this; + } + + public MessagePackFactory unpackAllowBinaryAsString(boolean enabled) + { + this.unpackAllowBinaryAsString = enabled; + return this; + } + + public MessagePackFactory unpackActionOnMalformedString(CodingErrorAction action) + { + this.unpackActionOnMalformedString = action; + return this; + } + + public MessagePackFactory unpackActionOnUnmappableString(CodingErrorAction action) + { + this.unpackActionOnUnmappableString = action; + return this; + } + + public MessagePackFactory unpackStringSizeLimit(int bytes) + { + this.unpackStringSizeLimit = bytes; + return this; + } + + public MessagePackFactory unpackStringDecoderBufferSize(int bytes) + { + this.unpackStringDecoderBufferSize = bytes; + return this; + } + + public MessagePackFactory inputBufferSize(int bytes) + { + this.inputBufferSize = bytes; + return this; + } + + public MessagePackFactory outputBufferSize(int bytes) + { + this.inputBufferSize = bytes; + return this; + } + + private int getPackerSmallStringOptimizationThreshold() + { + return packerSmallStringOptimizationThreshold; + } + + private boolean getUnpackAllowStringAsBinary() + { + return unpackAllowStringAsBinary; + } + + private boolean getUnpackAllowBinaryAsString() + { + return unpackAllowBinaryAsString; + } + + private CodingErrorAction getUnpackActionOnMalformedString() + { + return unpackActionOnMalformedString; + } + + private CodingErrorAction getUnpackActionOnUnmappableString() + { + return unpackActionOnUnmappableString; + } + + private int getUnpackStringSizeLimit() + { + return unpackStringSizeLimit; + } + + private int getUnpackStringDecoderBufferSize() + { + return unpackStringDecoderBufferSize; + } + + private int getInputBufferSize() + { + return inputBufferSize; + } + + private int getOutputBufferSize() + { + return outputBufferSize; + } +} diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessagePacker.java b/msgpack-core/src/main/java/org/msgpack/core/MessagePacker.java index 11f2fcb5d..a145df162 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/MessagePacker.java +++ b/msgpack-core/src/main/java/org/msgpack/core/MessagePacker.java @@ -29,40 +29,40 @@ import java.nio.charset.CoderResult; import java.nio.charset.CodingErrorAction; -import static org.msgpack.core.MessagePack.Code.ARRAY16; -import static org.msgpack.core.MessagePack.Code.ARRAY32; -import static org.msgpack.core.MessagePack.Code.BIN16; -import static org.msgpack.core.MessagePack.Code.BIN32; -import static org.msgpack.core.MessagePack.Code.BIN8; -import static org.msgpack.core.MessagePack.Code.EXT16; -import static org.msgpack.core.MessagePack.Code.EXT32; -import static org.msgpack.core.MessagePack.Code.EXT8; -import static org.msgpack.core.MessagePack.Code.FALSE; -import static org.msgpack.core.MessagePack.Code.FIXARRAY_PREFIX; -import static org.msgpack.core.MessagePack.Code.FIXEXT1; -import static org.msgpack.core.MessagePack.Code.FIXEXT16; -import static org.msgpack.core.MessagePack.Code.FIXEXT2; -import static org.msgpack.core.MessagePack.Code.FIXEXT4; -import static org.msgpack.core.MessagePack.Code.FIXEXT8; -import static org.msgpack.core.MessagePack.Code.FIXMAP_PREFIX; -import static org.msgpack.core.MessagePack.Code.FIXSTR_PREFIX; -import static org.msgpack.core.MessagePack.Code.FLOAT32; -import static org.msgpack.core.MessagePack.Code.FLOAT64; -import static org.msgpack.core.MessagePack.Code.INT16; -import static org.msgpack.core.MessagePack.Code.INT32; -import static org.msgpack.core.MessagePack.Code.INT64; -import static org.msgpack.core.MessagePack.Code.INT8; -import static org.msgpack.core.MessagePack.Code.MAP16; -import static org.msgpack.core.MessagePack.Code.MAP32; -import static org.msgpack.core.MessagePack.Code.NIL; -import static org.msgpack.core.MessagePack.Code.STR16; -import static org.msgpack.core.MessagePack.Code.STR32; -import static org.msgpack.core.MessagePack.Code.STR8; -import static org.msgpack.core.MessagePack.Code.TRUE; -import static org.msgpack.core.MessagePack.Code.UINT16; -import static org.msgpack.core.MessagePack.Code.UINT32; -import static org.msgpack.core.MessagePack.Code.UINT64; -import static org.msgpack.core.MessagePack.Code.UINT8; +import static org.msgpack.core.MessageFormat.Code.ARRAY16; +import static org.msgpack.core.MessageFormat.Code.ARRAY32; +import static org.msgpack.core.MessageFormat.Code.BIN16; +import static org.msgpack.core.MessageFormat.Code.BIN32; +import static org.msgpack.core.MessageFormat.Code.BIN8; +import static org.msgpack.core.MessageFormat.Code.EXT16; +import static org.msgpack.core.MessageFormat.Code.EXT32; +import static org.msgpack.core.MessageFormat.Code.EXT8; +import static org.msgpack.core.MessageFormat.Code.FALSE; +import static org.msgpack.core.MessageFormat.Code.FIXARRAY_PREFIX; +import static org.msgpack.core.MessageFormat.Code.FIXEXT1; +import static org.msgpack.core.MessageFormat.Code.FIXEXT16; +import static org.msgpack.core.MessageFormat.Code.FIXEXT2; +import static org.msgpack.core.MessageFormat.Code.FIXEXT4; +import static org.msgpack.core.MessageFormat.Code.FIXEXT8; +import static org.msgpack.core.MessageFormat.Code.FIXMAP_PREFIX; +import static org.msgpack.core.MessageFormat.Code.FIXSTR_PREFIX; +import static org.msgpack.core.MessageFormat.Code.FLOAT32; +import static org.msgpack.core.MessageFormat.Code.FLOAT64; +import static org.msgpack.core.MessageFormat.Code.INT16; +import static org.msgpack.core.MessageFormat.Code.INT32; +import static org.msgpack.core.MessageFormat.Code.INT64; +import static org.msgpack.core.MessageFormat.Code.INT8; +import static org.msgpack.core.MessageFormat.Code.MAP16; +import static org.msgpack.core.MessageFormat.Code.MAP32; +import static org.msgpack.core.MessageFormat.Code.NIL; +import static org.msgpack.core.MessageFormat.Code.STR16; +import static org.msgpack.core.MessageFormat.Code.STR32; +import static org.msgpack.core.MessageFormat.Code.STR8; +import static org.msgpack.core.MessageFormat.Code.TRUE; +import static org.msgpack.core.MessageFormat.Code.UINT16; +import static org.msgpack.core.MessageFormat.Code.UINT32; +import static org.msgpack.core.MessageFormat.Code.UINT64; +import static org.msgpack.core.MessageFormat.Code.UINT8; import static org.msgpack.core.Preconditions.checkNotNull; /** @@ -85,9 +85,9 @@ public class MessagePacker implements Closeable { - private final MessagePack.Config config; + private int smallStringOptimizationThreshold = 512; - private MessageBufferOutput out; + protected MessageBufferOutput out; private MessageBuffer buffer; @@ -111,17 +111,17 @@ public class MessagePacker */ public MessagePacker(MessageBufferOutput out) { - this(out, MessagePack.DEFAULT_CONFIG); - } - - public MessagePacker(MessageBufferOutput out, MessagePack.Config config) - { - this.config = checkNotNull(config, "config is null"); this.out = checkNotNull(out, "MessageBufferOutput is null"); this.position = 0; this.totalFlushBytes = 0; } + public MessagePacker setSmallStringOptimizationThreshold(int bytes) + { + this.smallStringOptimizationThreshold = bytes; + return this; + } + /** * Reset output. This method doesn't close the old resource. * @@ -441,7 +441,7 @@ private void packStringByGetBytes(String s) private void prepareEncoder() { if (encoder == null) { - this.encoder = MessagePack.UTF8.newEncoder().onMalformedInput(config.actionOnMalFormedInput).onUnmappableCharacter(config.actionOnMalFormedInput); + this.encoder = MessagePack.UTF8.newEncoder(); } } @@ -482,7 +482,7 @@ public MessagePacker packString(String s) packRawStringHeader(0); return this; } - else if (s.length() < config.packerSmallStringOptimizationThreshold) { + else if (s.length() < smallStringOptimizationThreshold) { // Write the length and payload of small string to the buffer so that it avoids an extra flush of buffer packStringByGetBytes(s); return this; diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java b/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java index 9b8e159bc..7e54d5253 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java +++ b/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java @@ -15,7 +15,7 @@ // package org.msgpack.core; -import org.msgpack.core.MessagePack.Code; +import org.msgpack.core.MessageFormat.Code; import org.msgpack.core.buffer.MessageBuffer; import org.msgpack.core.buffer.MessageBufferInput; import org.msgpack.value.ImmutableValue; @@ -48,7 +48,7 @@ *

*

  * 
- *     MessageUnpacker unpacker = MessagePackFactory.DEFAULT.newUnpacker(...);
+ *     MessageUnpacker unpacker = MessagePack.newDefaultUnpacker(...);
  *     while(unpacker.hasNext()) {
  *         MessageFormat f = unpacker.getNextFormat();
  *         switch(f) {
@@ -76,7 +76,12 @@ public class MessageUnpacker
 
     private static final byte HEAD_BYTE_REQUIRED = (byte) 0xc1;
 
-    private final MessagePack.Config config;
+    private boolean allowStringAsBinary = true;
+    private boolean allowBinaryAsString = true;
+    private CodingErrorAction actionOnMalformedString = CodingErrorAction.REPLACE;
+    private CodingErrorAction actionOnUnmappableString = CodingErrorAction.REPLACE;
+    private int stringSizeLimit = Integer.MAX_VALUE;
+    private int stringDecoderBufferSize = 8192;
 
     private MessageBufferInput in;
 
@@ -135,20 +140,43 @@ public class MessageUnpacker
      */
     public MessageUnpacker(MessageBufferInput in)
     {
-        this(in, MessagePack.DEFAULT_CONFIG);
+        this.in = checkNotNull(in, "MessageBufferInput is null");
     }
 
-    /**
-     * Create an MessageUnpacker
-     *
-     * @param in
-     * @param config configuration
-     */
-    public MessageUnpacker(MessageBufferInput in, MessagePack.Config config)
+    public MessageUnpacker setAllowStringAsBinary(boolean enabled)
     {
-        // Root constructor. All of the constructors must call this constructor.
-        this.in = checkNotNull(in, "MessageBufferInput is null");
-        this.config = checkNotNull(config, "Config");
+        this.allowStringAsBinary = enabled;
+        return this;
+    }
+
+    public MessageUnpacker setAllowBinaryAsString(boolean enabled)
+    {
+        this.allowBinaryAsString = enabled;
+        return this;
+    }
+
+    public MessageUnpacker setActionOnMalformedString(CodingErrorAction action)
+    {
+        this.actionOnMalformedString = action;
+        return this;
+    }
+
+    public MessageUnpacker setActionOnUnmappableString(CodingErrorAction action)
+    {
+        this.actionOnUnmappableString = action;
+        return this;
+    }
+
+    public MessageUnpacker setStringSizeLimit(int bytes)
+    {
+        this.stringSizeLimit = bytes;
+        return this;
+    }
+
+    public MessageUnpacker setStringDecoderBufferSize(int bytes)
+    {
+        this.stringDecoderBufferSize = bytes;
+        return this;
     }
 
     /**
@@ -958,10 +986,10 @@ public double unpackDouble()
     private void resetDecoder()
     {
         if (decoder == null) {
-            decodeBuffer = CharBuffer.allocate(config.stringDecoderBufferSize);
+            decodeBuffer = CharBuffer.allocate(stringDecoderBufferSize);
             decoder = MessagePack.UTF8.newDecoder()
-                    .onMalformedInput(config.actionOnMalFormedInput)
-                    .onUnmappableCharacter(config.actionOnUnmappableCharacter);
+                    .onMalformedInput(actionOnMalformedString)
+                    .onUnmappableCharacter(actionOnUnmappableString);
         }
         else {
             decoder.reset();
@@ -980,8 +1008,8 @@ public String unpackString()
             if (len == 0) {
                 return EMPTY_STRING;
             }
-            if (len > config.maxUnpackStringSize) {
-                throw new MessageSizeException(String.format("cannot unpack a String of size larger than %,d: %,d", config.maxUnpackStringSize, len), len);
+            if (len > stringSizeLimit) {
+                throw new MessageSizeException(String.format("cannot unpack a String of size larger than %,d: %,d", stringSizeLimit, len), len);
             }
             if (buffer.size() - position >= len) {
                 return decodeStringFastPath(len);
@@ -1069,16 +1097,16 @@ else if (bufferRemaining == 0) {
     private void handleCoderError(CoderResult cr)
         throws CharacterCodingException
     {
-        if ((cr.isMalformed() && config.actionOnMalFormedInput == CodingErrorAction.REPORT) ||
-                (cr.isUnmappable() && config.actionOnUnmappableCharacter == CodingErrorAction.REPORT)) {
+        if ((cr.isMalformed() && actionOnMalformedString == CodingErrorAction.REPORT) ||
+                (cr.isUnmappable() && actionOnUnmappableString == CodingErrorAction.REPORT)) {
             cr.throwException();
         }
     }
 
     private String decodeStringFastPath(int length)
     {
-        if (config.actionOnMalFormedInput == CodingErrorAction.REPLACE &&
-                config.actionOnUnmappableCharacter == CodingErrorAction.REPLACE &&
+        if (actionOnMalformedString == CodingErrorAction.REPLACE &&
+                actionOnUnmappableString == CodingErrorAction.REPLACE &&
                 buffer.hasArray()) {
             String s = new String(buffer.getArray(), buffer.offset() + position, length, MessagePack.UTF8);
             position += length;
@@ -1253,7 +1281,7 @@ public int unpackRawStringHeader()
             return len;
         }
 
-        if (config.readBinaryAsString) {
+        if (allowBinaryAsString) {
             len = tryReadBinaryHeader(b);
             if (len >= 0) {
                 resetHeadByte();
@@ -1277,7 +1305,7 @@ public int unpackBinaryHeader()
             return len;
         }
 
-        if (config.readStringAsBinary) {
+        if (allowStringAsBinary) {
             len = tryReadStringHeader(b);
             if (len >= 0) {
                 resetHeadByte();
diff --git a/msgpack-core/src/main/java/org/msgpack/core/buffer/ArrayBufferOutput.java b/msgpack-core/src/main/java/org/msgpack/core/buffer/ArrayBufferOutput.java
new file mode 100644
index 000000000..710013153
--- /dev/null
+++ b/msgpack-core/src/main/java/org/msgpack/core/buffer/ArrayBufferOutput.java
@@ -0,0 +1,136 @@
+//
+// MessagePack for Java
+//
+//    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.core.buffer;
+
+import java.util.List;
+import java.util.ArrayList;
+
+/**
+ * MessageBufferOutput adapter that packs data into list of byte arrays.
+ */
+public class ArrayBufferOutput
+        implements MessageBufferOutput
+{
+    private List list;
+    private MessageBuffer lastBuffer;
+    private int bufferSize;
+
+    public ArrayBufferOutput()
+    {
+        this(8192);
+    }
+
+    public ArrayBufferOutput(int bufferSize)
+    {
+        this.bufferSize = bufferSize;
+        this.list = new ArrayList();
+    }
+
+    public int getSize()
+    {
+        int size = 0;
+        for (MessageBuffer buffer : list) {
+            size += buffer.size();
+        }
+        return size;
+    }
+
+    public byte[] toByteArray()
+    {
+        byte[] data = new byte[getSize()];
+        int off = 0;
+        for (MessageBuffer buffer : list) {
+            buffer.getBytes(0, data, off, buffer.size());
+            off += buffer.size();
+        }
+        return data;
+    }
+
+    public MessageBuffer toMessageBuffer()
+    {
+        if (list.size() == 1) {
+            return list.get(0);
+        }
+        else if (list.isEmpty()) {
+            return MessageBuffer.newBuffer(0);
+        }
+        else {
+            return MessageBuffer.wrap(toByteArray());
+        }
+    }
+
+    public List toBufferList()
+    {
+        return new ArrayList(list);
+    }
+
+    /**
+     * Clears the internal buffers
+     */
+    public void clear()
+    {
+        list.clear();
+    }
+
+    @Override
+    public MessageBuffer next(int mimimumSize)
+    {
+        if (lastBuffer != null && lastBuffer.size() > mimimumSize) {
+            return lastBuffer;
+        }
+        else {
+            int size = Math.max(bufferSize, mimimumSize);
+            MessageBuffer buffer = MessageBuffer.newBuffer(size);
+            lastBuffer = buffer;
+            return buffer;
+        }
+    }
+
+    @Override
+    public void writeBuffer(int length)
+    {
+        list.add(lastBuffer.slice(0, length));
+        if (lastBuffer.size() - length > bufferSize / 4) {
+            lastBuffer = lastBuffer.slice(length, lastBuffer.size() - length);
+        }
+        else {
+            lastBuffer = null;
+        }
+    }
+
+    @Override
+    public void write(byte[] buffer, int offset, int length)
+    {
+        MessageBuffer copy = MessageBuffer.newBuffer(length);
+        copy.putBytes(0, buffer, offset, length);
+        list.add(copy);
+    }
+
+    @Override
+    public void add(byte[] buffer, int offset, int length)
+    {
+        MessageBuffer wrapped = MessageBuffer.wrap(buffer, offset, length);
+        list.add(wrapped);
+    }
+
+    @Override
+    public void close()
+    { }
+
+    @Override
+    public void flush()
+    { }
+}
diff --git a/msgpack-core/src/test/java/org/msgpack/core/example/MessagePackExample.java b/msgpack-core/src/test/java/org/msgpack/core/example/MessagePackExample.java
index 7636742e0..d7dffe64b 100644
--- a/msgpack-core/src/test/java/org/msgpack/core/example/MessagePackExample.java
+++ b/msgpack-core/src/test/java/org/msgpack/core/example/MessagePackExample.java
@@ -17,6 +17,7 @@
 
 import org.msgpack.core.MessageFormat;
 import org.msgpack.core.MessagePack;
+import org.msgpack.core.MessagePackFactory;
 import org.msgpack.core.MessagePacker;
 import org.msgpack.core.MessageUnpacker;
 import org.msgpack.value.ArrayValue;
@@ -246,24 +247,22 @@ public static void configuration()
             throws IOException
     {
         // Build a conifiguration
-        MessagePack.Config config = new MessagePack.ConfigBuilder()
-                .onMalFormedInput(CodingErrorAction.REPLACE)         // Drop malformed and unmappable UTF-8 characters
-                .onUnmappableCharacter(CodingErrorAction.REPLACE)
-                .packerBufferSize(8192 * 2)
-                .build();
+        MessagePackFactory factory = new MessagePackFactory()
+                .unpackActionOnMalformedString(CodingErrorAction.REPLACE)         // Drop malformed and unmappable UTF-8 characters
+                .unpackActionOnUnmappableString(CodingErrorAction.REPLACE)
+                .outputBufferSize(8192 * 2);
         // Create a  that uses this configuration
-        MessagePack msgpack = new MessagePack(config);
 
         // Pack data
         ByteArrayOutputStream out = new ByteArrayOutputStream();
-        MessagePacker packer = msgpack.newPacker(out);
+        MessagePacker packer = factory.newPacker(out);
         packer.packInt(10);
         packer.packBoolean(true);
         packer.close();
 
         // Unpack data
         byte[] packedData = out.toByteArray();
-        MessageUnpacker unpacker = msgpack.newUnpacker(packedData);
+        MessageUnpacker unpacker = factory.newUnpacker(packedData);
         int i = unpacker.unpackInt();  // 10
         boolean b = unpacker.unpackBoolean(); // true
         unpacker.close();
diff --git a/msgpack-core/src/test/scala/org/msgpack/core/MessageFormatTest.scala b/msgpack-core/src/test/scala/org/msgpack/core/MessageFormatTest.scala
index be9d270cd..a6a71e2d9 100644
--- a/msgpack-core/src/test/scala/org/msgpack/core/MessageFormatTest.scala
+++ b/msgpack-core/src/test/scala/org/msgpack/core/MessageFormatTest.scala
@@ -15,7 +15,7 @@
 //
 package org.msgpack.core
 
-import org.msgpack.core.MessagePack.Code
+import org.msgpack.core.MessageFormat.Code
 import org.msgpack.value.ValueType
 import org.scalatest.exceptions.TestFailedException
 
diff --git a/msgpack-core/src/test/scala/org/msgpack/core/MessagePackTest.scala b/msgpack-core/src/test/scala/org/msgpack/core/MessagePackTest.scala
index f903cf88d..5cf8ea2e6 100644
--- a/msgpack-core/src/test/scala/org/msgpack/core/MessagePackTest.scala
+++ b/msgpack-core/src/test/scala/org/msgpack/core/MessagePackTest.scala
@@ -20,7 +20,7 @@ import java.math.BigInteger
 import java.nio.CharBuffer
 import java.nio.charset.{CodingErrorAction, UnmappableCharacterException}
 
-import org.msgpack.core.MessagePack.Code
+import org.msgpack.core.MessageFormat.Code
 import org.msgpack.value.{Value, Variable}
 
 import scala.util.Random
@@ -117,17 +117,17 @@ class MessagePackTest extends MessagePackSpec {
     }
 
 
-    def check[A](v: A, pack: MessagePacker => Unit, unpack: MessageUnpacker => A, msgpack: MessagePack = MessagePack.DEFAULT): Unit = {
+    def check[A](v: A, pack: MessagePacker => Unit, unpack: MessageUnpacker => A, factory: MessagePackFactory = new MessagePackFactory()): Unit = {
       var b: Array[Byte] = null
       try {
         val bs = new ByteArrayOutputStream()
-        val packer = msgpack.newPacker(bs)
+        val packer = factory.newPacker(bs)
         pack(packer)
         packer.close()
 
         b = bs.toByteArray
 
-        val unpacker = msgpack.newUnpacker(b)
+        val unpacker = factory.newUnpacker(b)
         val ret = unpack(unpacker)
         ret shouldBe v
       }
@@ -142,16 +142,16 @@ class MessagePackTest extends MessagePackSpec {
     }
 
     def checkException[A](v: A, pack: MessagePacker => Unit, unpack: MessageUnpacker => A,
-                          msgpack: MessagePack = MessagePack.DEFAULT): Unit = {
+                          factory: MessagePackFactory = new MessagePackFactory()): Unit = {
       var b: Array[Byte] = null
       val bs = new ByteArrayOutputStream()
-      val packer = msgpack.newPacker(bs)
+      val packer = factory.newPacker(bs)
       pack(packer)
       packer.close()
 
       b = bs.toByteArray
 
-      val unpacker = msgpack.newUnpacker(b)
+      val unpacker = factory.newUnpacker(b)
       val ret = unpack(unpacker)
 
       fail("cannot not reach here")
@@ -297,11 +297,9 @@ class MessagePackTest extends MessagePackSpec {
       //val unmappableChar = Array[Char](new Character(0xfc0a).toChar)
 
       // Report error on unmappable character
-      val config = new MessagePack.ConfigBuilder()
-        .onMalFormedInput(CodingErrorAction.REPORT)
-        .onUnmappableCharacter(CodingErrorAction.REPORT)
-        .build()
-      val msgpack = new MessagePack(config)
+      val factory = new MessagePackFactory()
+        .unpackActionOnMalformedString(CodingErrorAction.REPORT)
+        .unpackActionOnUnmappableString(CodingErrorAction.REPORT);
 
       for (bytes <- Seq(unmappable)) {
         When("unpacking")
@@ -311,7 +309,7 @@ class MessagePackTest extends MessagePackSpec {
             packer.writePayload(bytes)
           },
           _.unpackString(),
-          msgpack)
+          factory)
         }
         catch {
           case e: MessageStringCodingException => // OK
diff --git a/msgpack-core/src/test/scala/org/msgpack/core/MessagePackerTest.scala b/msgpack-core/src/test/scala/org/msgpack/core/MessagePackerTest.scala
index f6971b331..8cb0d723b 100644
--- a/msgpack-core/src/test/scala/org/msgpack/core/MessagePackerTest.scala
+++ b/msgpack-core/src/test/scala/org/msgpack/core/MessagePackerTest.scala
@@ -30,10 +30,10 @@ import scala.util.Random
 class MessagePackerTest
   extends MessagePackSpec {
 
-  val msgpack = MessagePack.DEFAULT
+  val factory = new MessagePackFactory()
 
   def verifyIntSeq(answer: Array[Int], packed: Array[Byte]) {
-    val unpacker = msgpack.newUnpacker(packed)
+    val unpacker = factory.newUnpacker(packed)
     val b = Array.newBuilder[Int]
     while (unpacker.hasNext) {
       b += unpacker.unpackInt()
@@ -69,7 +69,7 @@ class MessagePackerTest
 
       val b = new
           ByteArrayOutputStream
-      val packer = msgpack.newPacker(b)
+      val packer = factory.newPacker(b)
       intSeq foreach packer.packInt
       packer.close
       verifyIntSeq(intSeq, b.toByteArray)
@@ -102,7 +102,7 @@ class MessagePackerTest
         block("no-buffer-reset") {
           val out = new
               ByteArrayOutputStream
-          IOUtil.withResource(msgpack.newPacker(out)) { packer =>
+          IOUtil.withResource(factory.newPacker(out)) { packer =>
             for (i <- 0 until N) {
               val outputStream = new
                   ByteArrayOutputStream()
@@ -118,7 +118,7 @@ class MessagePackerTest
         block("buffer-reset") {
           val out = new
               ByteArrayOutputStream
-          IOUtil.withResource(msgpack.newPacker(out)) { packer =>
+          IOUtil.withResource(factory.newPacker(out)) { packer =>
             val bufferOut = new
                 OutputStreamBufferOutput(new
                     ByteArrayOutputStream())
@@ -142,15 +142,14 @@ class MessagePackerTest
 
       // TODO: Refactor this test code to fit other ones.
       def test(bufferSize: Int, stringSize: Int): Boolean = {
-        val msgpack = new
-            MessagePack(new
-                MessagePack.ConfigBuilder().packerBufferSize(bufferSize).build)
+        val factory = new MessagePackFactory()
+            .outputBufferSize(bufferSize);
         val str = "a" * stringSize
         val rawString = ValueFactory.newString(str.getBytes("UTF-8"))
         val array = ValueFactory.newArray(rawString)
         val out = new
             ByteArrayOutputStream()
-        val packer = msgpack.newPacker(out)
+        val packer = factory.newPacker(out)
         packer.packValue(array)
         packer.close()
         out.toByteArray
@@ -266,7 +265,7 @@ class MessagePackerTest
   "compute totalWrittenBytes" in {
     val out = new
         ByteArrayOutputStream
-    val packerTotalWrittenBytes = IOUtil.withResource(msgpack.newPacker(out)) { packer =>
+    val packerTotalWrittenBytes = IOUtil.withResource(factory.newPacker(out)) { packer =>
       packer.packByte(0) // 1
         .packBoolean(true) // 1
         .packShort(12) // 1
diff --git a/msgpack-core/src/test/scala/org/msgpack/core/MessageUnpackerTest.scala b/msgpack-core/src/test/scala/org/msgpack/core/MessageUnpackerTest.scala
index 672edd615..763b6fe78 100644
--- a/msgpack-core/src/test/scala/org/msgpack/core/MessageUnpackerTest.scala
+++ b/msgpack-core/src/test/scala/org/msgpack/core/MessageUnpackerTest.scala
@@ -29,11 +29,11 @@ import scala.util.Random
  */
 class MessageUnpackerTest extends MessagePackSpec {
 
-  val msgpack = MessagePack.DEFAULT
+  val factory = new MessagePackFactory()
 
   def testData: Array[Byte] = {
     val out = new ByteArrayOutputStream()
-    val packer = msgpack.newPacker(out)
+    val packer = factory.newPacker(out)
 
     packer
       .packArrayHeader(2)
@@ -55,7 +55,7 @@ class MessageUnpackerTest extends MessagePackSpec {
 
   def testData2: Array[Byte] = {
     val out = new ByteArrayOutputStream()
-    val packer = msgpack.newPacker(out);
+    val packer = factory.newPacker(out);
 
     packer
       .packBoolean(true)
@@ -125,7 +125,7 @@ class MessageUnpackerTest extends MessagePackSpec {
   def testData3(N: Int): Array[Byte] = {
 
     val out = new ByteArrayOutputStream()
-    val packer = msgpack.newPacker(out)
+    val packer = factory.newPacker(out)
 
     val r = new Random(0)
 
@@ -179,7 +179,7 @@ class MessageUnpackerTest extends MessagePackSpec {
     "parse message packed data" taggedAs ("unpack") in {
       val arr = testData
 
-      val unpacker = msgpack.newUnpacker(arr)
+      val unpacker = factory.newUnpacker(arr)
 
       var count = 0
       while (unpacker.hasNext) {
@@ -192,7 +192,7 @@ class MessageUnpackerTest extends MessagePackSpec {
 
     "skip reading values" in {
 
-      val unpacker = msgpack.newUnpacker(testData)
+      val unpacker = factory.newUnpacker(testData)
       var skipCount = 0
       while (unpacker.hasNext) {
         unpacker.skipValue()
@@ -209,7 +209,7 @@ class MessageUnpackerTest extends MessagePackSpec {
 
       time("skip performance", repeat = 100) {
         block("switch") {
-          val unpacker = msgpack.newUnpacker(data)
+          val unpacker = factory.newUnpacker(data)
           var skipCount = 0
           while (unpacker.hasNext) {
             unpacker.skipValue()
@@ -227,7 +227,7 @@ class MessageUnpackerTest extends MessagePackSpec {
 
       val ib = Seq.newBuilder[Int]
 
-      val unpacker = msgpack.newUnpacker(testData2)
+      val unpacker = factory.newUnpacker(testData2)
       while (unpacker.hasNext) {
         val f = unpacker.getNextFormat
         f.getValueType match {
@@ -269,7 +269,7 @@ class MessageUnpackerTest extends MessagePackSpec {
       trait SplitTest {
         val data: Array[Byte]
         def run {
-          val unpacker = msgpack.newUnpacker(data)
+          val unpacker = factory.newUnpacker(data)
           val numElems = {
             var c = 0
             while (unpacker.hasNext) {
@@ -326,7 +326,7 @@ class MessageUnpackerTest extends MessagePackSpec {
         }
 
         block("v7") {
-          val unpacker = msgpack.newUnpacker(data)
+          val unpacker = factory.newUnpacker(data)
           var count = 0
           try {
             while (unpacker.hasNext) {
@@ -428,7 +428,7 @@ class MessageUnpackerTest extends MessagePackSpec {
         }
 
         block("v7") {
-          val unpacker = msgpack.newUnpacker(data)
+          val unpacker = factory.newUnpacker(data)
           var count = 0
           try {
             while (unpacker.hasNext) {
@@ -449,7 +449,7 @@ class MessageUnpackerTest extends MessagePackSpec {
     "be faster for reading binary than v6" taggedAs ("cmp-binary") in {
 
       val bos = new ByteArrayOutputStream()
-      val packer = msgpack.newPacker(bos)
+      val packer = factory.newPacker(bos)
       val L = 10000
       val R = 100
       (0 until R).foreach { i =>
@@ -472,7 +472,7 @@ class MessageUnpackerTest extends MessagePackSpec {
         }
 
         block("v7") {
-          val unpacker = msgpack.newUnpacker(b)
+          val unpacker = factory.newUnpacker(b)
           var i = 0
           while (i < R) {
             val len = unpacker.unpackBinaryHeader()
@@ -484,7 +484,7 @@ class MessageUnpackerTest extends MessagePackSpec {
         }
 
         block("v7-ref") {
-          val unpacker = msgpack.newUnpacker(b)
+          val unpacker = factory.newUnpacker(b)
           var i = 0
           while (i < R) {
             val len = unpacker.unpackBinaryHeader()
@@ -505,12 +505,12 @@ class MessageUnpackerTest extends MessagePackSpec {
         val data = new Array[Byte](s)
         Random.nextBytes(data)
         val b = new ByteArrayOutputStream()
-        val packer = msgpack.newPacker(b)
+        val packer = factory.newPacker(b)
         packer.packBinaryHeader(s)
         packer.writePayload(data)
         packer.close()
 
-        val unpacker = msgpack.newUnpacker(b.toByteArray)
+        val unpacker = factory.newUnpacker(b.toByteArray)
         val len = unpacker.unpackBinaryHeader()
         len shouldBe s
         val ref = unpacker.readPayloadAsReference(len)
@@ -529,7 +529,7 @@ class MessageUnpackerTest extends MessagePackSpec {
 
       val data = intSeq
       val b = createMessagePackData(packer => data foreach packer.packInt)
-      val unpacker = msgpack.newUnpacker(b)
+      val unpacker = factory.newUnpacker(b)
 
       val unpacked = Array.newBuilder[Int]
       while (unpacker.hasNext) {
@@ -564,7 +564,7 @@ class MessageUnpackerTest extends MessagePackSpec {
     "improve the performance via reset method" taggedAs ("reset-arr") in {
 
       val out = new ByteArrayOutputStream
-      val packer = msgpack.newPacker(out)
+      val packer = factory.newPacker(out)
       packer.packInt(0)
       packer.flush
       val arr = out.toByteArray
@@ -573,7 +573,7 @@ class MessageUnpackerTest extends MessagePackSpec {
       val N = 1000
       val t = time("unpacker", repeat = 10) {
         block("no-buffer-reset") {
-          IOUtil.withResource(msgpack.newUnpacker(arr)) { unpacker =>
+          IOUtil.withResource(factory.newUnpacker(arr)) { unpacker =>
             for (i <- 0 until N) {
               val buf = new ArrayBufferInput(arr)
               unpacker.reset(buf)
@@ -584,7 +584,7 @@ class MessageUnpackerTest extends MessagePackSpec {
         }
 
         block("reuse-array-input") {
-          IOUtil.withResource(msgpack.newUnpacker(arr)) { unpacker =>
+          IOUtil.withResource(factory.newUnpacker(arr)) { unpacker =>
             val buf = new ArrayBufferInput(arr)
             for (i <- 0 until N) {
               buf.reset(arr)
@@ -596,7 +596,7 @@ class MessageUnpackerTest extends MessagePackSpec {
         }
 
         block("reuse-message-buffer") {
-          IOUtil.withResource(msgpack.newUnpacker(arr)) { unpacker =>
+          IOUtil.withResource(factory.newUnpacker(arr)) { unpacker =>
             val buf = new ArrayBufferInput(arr)
             for (i <- 0 until N) {
               buf.reset(mb)
@@ -640,7 +640,7 @@ class MessageUnpackerTest extends MessagePackSpec {
     "unpack large string data" taggedAs ("large-string") in {
       def createLargeData(stringLength: Int): Array[Byte] = {
         val out = new ByteArrayOutputStream()
-        val packer = msgpack.newPacker(out)
+        val packer = factory.newPacker(out)
 
         packer
           .packArrayHeader(2)
@@ -655,7 +655,7 @@ class MessageUnpackerTest extends MessagePackSpec {
       Seq(8191, 8192, 8193, 16383, 16384, 16385).foreach { n =>
         val arr = createLargeData(n)
 
-        val unpacker = msgpack.newUnpacker(arr)
+        val unpacker = factory.newUnpacker(arr)
 
         unpacker.unpackArrayHeader shouldBe 2
         unpacker.unpackString.length shouldBe n
diff --git a/msgpack-core/src/test/scala/org/msgpack/core/buffer/MessageBufferInputTest.scala b/msgpack-core/src/test/scala/org/msgpack/core/buffer/MessageBufferInputTest.scala
index d7ebeac84..b6ee7bf08 100644
--- a/msgpack-core/src/test/scala/org/msgpack/core/buffer/MessageBufferInputTest.scala
+++ b/msgpack-core/src/test/scala/org/msgpack/core/buffer/MessageBufferInputTest.scala
@@ -135,10 +135,8 @@ class MessageBufferInputTest
 
   def createTempFileWithInputStream = {
     val f = createTempFile
-    val out = new
-        FileOutputStream(f)
-    new
-        MessagePack().newPacker(out).packInt(42).close
+    val out = new FileOutputStream(f)
+    MessagePack.newDefaultPacker(out).packInt(42).close
     val in = new
         FileInputStream(f)
     (f, in)
diff --git a/msgpack-core/src/test/scala/org/msgpack/value/ValueTypeTest.scala b/msgpack-core/src/test/scala/org/msgpack/value/ValueTypeTest.scala
index 6634ef606..2bd1c7b14 100644
--- a/msgpack-core/src/test/scala/org/msgpack/value/ValueTypeTest.scala
+++ b/msgpack-core/src/test/scala/org/msgpack/value/ValueTypeTest.scala
@@ -15,7 +15,7 @@
 //
 package org.msgpack.value
 
-import org.msgpack.core.MessagePack.Code._
+import org.msgpack.core.MessageFormat.Code._
 import org.msgpack.core.{MessageFormat, MessageFormatException, MessagePackSpec}
 
 /**

From 285ec1fcbb838e73d5020f280f776c4348501860 Mon Sep 17 00:00:00 2001
From: Sadayuki Furuhashi 
Date: Fri, 25 Dec 2015 15:51:57 +0900
Subject: [PATCH 168/234] removed support for ByteBuffer

---
 .../java/org/msgpack/core/MessagePack.java    |   2 -
 .../java/org/msgpack/core/MessagePacker.java  |   2 +-
 .../org/msgpack/core/MessageUnpacker.java     |  10 +-
 .../core/buffer/ArrayBufferOutput.java        |   6 +-
 .../msgpack/core/buffer/ByteBufferInput.java  |  70 --------
 .../core/buffer/ChannelBufferInput.java       |   4 +-
 .../core/buffer/ChannelBufferOutput.java      |   6 +-
 .../msgpack/core/buffer/MessageBuffer.java    | 150 +++---------------
 .../msgpack/core/buffer/MessageBufferBE.java  |  15 +-
 .../msgpack/core/buffer/MessageBufferU.java   |  85 +++++-----
 .../core/buffer/OutputStreamBufferOutput.java |   4 +-
 .../msgpack/core/buffer/ByteStringTest.scala  |  15 --
 .../core/buffer/MessageBufferInputTest.scala  |   5 -
 .../core/buffer/MessageBufferTest.scala       |  43 +----
 14 files changed, 91 insertions(+), 326 deletions(-)
 delete mode 100644 msgpack-core/src/main/java/org/msgpack/core/buffer/ByteBufferInput.java

diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessagePack.java b/msgpack-core/src/main/java/org/msgpack/core/MessagePack.java
index 8af53a884..f1bee0774 100644
--- a/msgpack-core/src/main/java/org/msgpack/core/MessagePack.java
+++ b/msgpack-core/src/main/java/org/msgpack/core/MessagePack.java
@@ -133,6 +133,4 @@ public static MessageUnpacker newDefaultUnpacker(byte[] contents, int offset, in
     {
         return defaultFactory.newUnpacker(contents, offset, length);
     }
-
-    // TODO add convenient methods here to pack/unpack objects with byte array/stream
 }
diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessagePacker.java b/msgpack-core/src/main/java/org/msgpack/core/MessagePacker.java
index a145df162..7c71b6807 100644
--- a/msgpack-core/src/main/java/org/msgpack/core/MessagePacker.java
+++ b/msgpack-core/src/main/java/org/msgpack/core/MessagePacker.java
@@ -448,7 +448,7 @@ private void prepareEncoder()
     private int encodeStringToBufferAt(int pos, String s)
     {
         prepareEncoder();
-        ByteBuffer bb = buffer.toByteBuffer(pos, buffer.size() - pos);
+        ByteBuffer bb = buffer.sliceAsByteBuffer(pos, buffer.size() - pos);
         int startPosition = bb.position();
         CharBuffer in = CharBuffer.wrap(s);
         CoderResult cr = encoder.encode(in, bb, true);
diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java b/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java
index 7e54d5253..2e00a5bc3 100644
--- a/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java
+++ b/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java
@@ -106,7 +106,7 @@ public class MessageUnpacker
      * Extra buffer for fixed-length data at the buffer boundary.
      * At most 8-byte buffer (for readLong used by uint 64 and UTF-8 character decoding) is required.
      */
-    private final MessageBuffer castBuffer = MessageBuffer.newBuffer(8);
+    private final MessageBuffer castBuffer = MessageBuffer.allocate(8);
 
     /**
      * Variable by ensureHeader method. Caller of the method should use this variable to read from returned MessageBuffer.
@@ -1032,7 +1032,7 @@ else if (bufferRemaining == 0) {
                     nextBuffer();
                 }
                 else {
-                    ByteBuffer bb = buffer.toByteBuffer(position, bufferRemaining);
+                    ByteBuffer bb = buffer.sliceAsByteBuffer(position, bufferRemaining);
                     int bbStartPosition = bb.position();
                     decodeBuffer.clear();
 
@@ -1114,7 +1114,7 @@ private String decodeStringFastPath(int length)
         }
         else {
             resetDecoder();
-            ByteBuffer bb = buffer.toByteBuffer();
+            ByteBuffer bb = buffer.sliceAsByteBuffer();
             bb.limit(position + length);
             bb.position(position);
             CharBuffer cb;
@@ -1395,8 +1395,8 @@ public MessageBuffer readPayloadAsReference(int length)
             position += length;
             return slice;
         }
-        MessageBuffer dst = MessageBuffer.newBuffer(length);
-        readPayload(dst.getReference());
+        MessageBuffer dst = MessageBuffer.allocate(length);
+        readPayload(dst.sliceAsByteBuffer());
         return dst;
     }
 
diff --git a/msgpack-core/src/main/java/org/msgpack/core/buffer/ArrayBufferOutput.java b/msgpack-core/src/main/java/org/msgpack/core/buffer/ArrayBufferOutput.java
index 710013153..186a579af 100644
--- a/msgpack-core/src/main/java/org/msgpack/core/buffer/ArrayBufferOutput.java
+++ b/msgpack-core/src/main/java/org/msgpack/core/buffer/ArrayBufferOutput.java
@@ -65,7 +65,7 @@ public MessageBuffer toMessageBuffer()
             return list.get(0);
         }
         else if (list.isEmpty()) {
-            return MessageBuffer.newBuffer(0);
+            return MessageBuffer.allocate(0);
         }
         else {
             return MessageBuffer.wrap(toByteArray());
@@ -93,7 +93,7 @@ public MessageBuffer next(int mimimumSize)
         }
         else {
             int size = Math.max(bufferSize, mimimumSize);
-            MessageBuffer buffer = MessageBuffer.newBuffer(size);
+            MessageBuffer buffer = MessageBuffer.allocate(size);
             lastBuffer = buffer;
             return buffer;
         }
@@ -114,7 +114,7 @@ public void writeBuffer(int length)
     @Override
     public void write(byte[] buffer, int offset, int length)
     {
-        MessageBuffer copy = MessageBuffer.newBuffer(length);
+        MessageBuffer copy = MessageBuffer.allocate(length);
         copy.putBytes(0, buffer, offset, length);
         list.add(copy);
     }
diff --git a/msgpack-core/src/main/java/org/msgpack/core/buffer/ByteBufferInput.java b/msgpack-core/src/main/java/org/msgpack/core/buffer/ByteBufferInput.java
deleted file mode 100644
index 034d8882b..000000000
--- a/msgpack-core/src/main/java/org/msgpack/core/buffer/ByteBufferInput.java
+++ /dev/null
@@ -1,70 +0,0 @@
-//
-// MessagePack for Java
-//
-//    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.core.buffer;
-
-import java.io.IOException;
-import java.nio.ByteBuffer;
-
-import static org.msgpack.core.Preconditions.checkNotNull;
-
-/**
- * {@link MessageBufferInput} adapter for {@link java.nio.ByteBuffer}
- */
-public class ByteBufferInput
-        implements MessageBufferInput
-{
-    private ByteBuffer input;
-    private boolean isRead = false;
-
-    public ByteBufferInput(ByteBuffer input)
-    {
-        this.input = checkNotNull(input, "input ByteBuffer is null");
-    }
-
-    /**
-     * Reset buffer. This method doesn't close the old resource.
-     *
-     * @param input new buffer
-     * @return the old resource
-     */
-    public ByteBuffer reset(ByteBuffer input)
-    {
-        ByteBuffer old = this.input;
-        this.input = input;
-        isRead = false;
-        return old;
-    }
-
-    @Override
-    public MessageBuffer next()
-            throws IOException
-    {
-        if (isRead) {
-            return null;
-        }
-
-        isRead = true;
-        return MessageBuffer.wrap(input);
-    }
-
-    @Override
-    public void close()
-            throws IOException
-    {
-        // Nothing to do
-    }
-
-}
diff --git a/msgpack-core/src/main/java/org/msgpack/core/buffer/ChannelBufferInput.java b/msgpack-core/src/main/java/org/msgpack/core/buffer/ChannelBufferInput.java
index 73dcb5db6..781b7afb9 100644
--- a/msgpack-core/src/main/java/org/msgpack/core/buffer/ChannelBufferInput.java
+++ b/msgpack-core/src/main/java/org/msgpack/core/buffer/ChannelBufferInput.java
@@ -40,7 +40,7 @@ public ChannelBufferInput(ReadableByteChannel channel, int bufferSize)
     {
         this.channel = checkNotNull(channel, "input channel is null");
         checkArgument(bufferSize > 0, "buffer size must be > 0: " + bufferSize);
-        this.m = MessageBuffer.newBuffer(bufferSize);
+        this.m = MessageBuffer.allocate(bufferSize);
     }
 
     /**
@@ -61,7 +61,7 @@ public ReadableByteChannel reset(ReadableByteChannel channel)
     public MessageBuffer next()
             throws IOException
     {
-        ByteBuffer b = m.toByteBuffer();
+        ByteBuffer b = m.sliceAsByteBuffer();
         while (b.remaining() > 0) {
             int ret = channel.read(b);
             if (ret == -1) {
diff --git a/msgpack-core/src/main/java/org/msgpack/core/buffer/ChannelBufferOutput.java b/msgpack-core/src/main/java/org/msgpack/core/buffer/ChannelBufferOutput.java
index b981cc95d..32969f29a 100644
--- a/msgpack-core/src/main/java/org/msgpack/core/buffer/ChannelBufferOutput.java
+++ b/msgpack-core/src/main/java/org/msgpack/core/buffer/ChannelBufferOutput.java
@@ -38,7 +38,7 @@ public ChannelBufferOutput(WritableByteChannel channel)
     public ChannelBufferOutput(WritableByteChannel channel, int bufferSize)
     {
         this.channel = checkNotNull(channel, "output channel is null");
-        this.buffer = MessageBuffer.newBuffer(bufferSize);
+        this.buffer = MessageBuffer.allocate(bufferSize);
     }
 
     /**
@@ -60,7 +60,7 @@ public MessageBuffer next(int mimimumSize)
             throws IOException
     {
         if (buffer.size() < mimimumSize) {
-            buffer = MessageBuffer.newBuffer(mimimumSize);
+            buffer = MessageBuffer.allocate(mimimumSize);
         }
         return buffer;
     }
@@ -69,7 +69,7 @@ public MessageBuffer next(int mimimumSize)
     public void writeBuffer(int length)
             throws IOException
     {
-        ByteBuffer bb = buffer.toByteBuffer(0, length);
+        ByteBuffer bb = buffer.sliceAsByteBuffer(0, length);
         while (bb.hasRemaining()) {
             channel.write(bb);
         }
diff --git a/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBuffer.java b/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBuffer.java
index fce8020ce..e2258265e 100644
--- a/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBuffer.java
+++ b/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBuffer.java
@@ -39,11 +39,11 @@ public class MessageBuffer
 {
     static final boolean isUniversalBuffer;
     static final Unsafe unsafe;
+
     /**
      * Reference to MessageBuffer Constructors
      */
     private static final Constructor mbArrConstructor;
-    private static final Constructor mbBBConstructor;
 
     /**
      * The offset from the object memory header to its byte array data
@@ -143,14 +143,9 @@ public class MessageBuffer
                 Class bufferCls = Class.forName(bufferClsName);
 
                 // MessageBufferX(byte[]) constructor
-                Constructor mbArrCstr = bufferCls.getDeclaredConstructor(byte[].class);
+                Constructor mbArrCstr = bufferCls.getDeclaredConstructor(byte[].class, int.class, int.class);
                 mbArrCstr.setAccessible(true);
                 mbArrConstructor = mbArrCstr;
-
-                // MessageBufferX(ByteBuffer) constructor
-                Constructor mbBBCstr = bufferCls.getDeclaredConstructor(ByteBuffer.class);
-                mbBBCstr.setAccessible(true);
-                mbBBConstructor = mbBBCstr;
             }
             catch (Exception e) {
                 e.printStackTrace(System.err);
@@ -176,67 +171,19 @@ public class MessageBuffer
      */
     protected final int size;
 
-    /**
-     * Reference is used to hold a reference to an object that holds the underlying memory so that it cannot be
-     * released by the garbage collector.
-     */
-    protected final ByteBuffer reference;
-
-    static MessageBuffer newOffHeapBuffer(int length)
-    {
-        // This method is not available in Android OS
-        if (!isUniversalBuffer) {
-            long address = unsafe.allocateMemory(length);
-            return new MessageBuffer(address, length);
-        }
-        else {
-            return newDirectBuffer(length);
-        }
-    }
-
-    public static MessageBuffer newDirectBuffer(int length)
-    {
-        ByteBuffer m = ByteBuffer.allocateDirect(length);
-        return newMessageBuffer(m);
-    }
-
-    public static MessageBuffer newBuffer(int length)
+    public static MessageBuffer allocate(int length)
     {
-        return newMessageBuffer(new byte[length]);
+        return wrap(new byte[length]);
     }
 
     public static MessageBuffer wrap(byte[] array)
     {
-        return newMessageBuffer(array);
+        return newMessageBuffer(array, 0, array.length);
     }
 
     public static MessageBuffer wrap(byte[] array, int offset, int length)
     {
-        return newMessageBuffer(array).slice(offset, length);
-    }
-
-    public static MessageBuffer wrap(ByteBuffer bb)
-    {
-        return newMessageBuffer(bb).slice(bb.position(), bb.remaining());
-    }
-
-    /**
-     * Creates a new MessageBuffer instance backed by ByteBuffer
-     *
-     * @param bb
-     * @return
-     */
-    private static MessageBuffer newMessageBuffer(ByteBuffer bb)
-    {
-        checkNotNull(bb);
-        try {
-            // We need to use reflection to create MessageBuffer instances in order to prevent TypeProfile generation for getInt method. TypeProfile will be
-            // generated to resolve one of the method references when two or more classes overrides the method.
-            return (MessageBuffer) mbBBConstructor.newInstance(bb);
-        }
-        catch (Exception e) {
-            throw new RuntimeException(e);
-        }
+        return newMessageBuffer(array, offset, length);
     }
 
     /**
@@ -245,11 +192,11 @@ private static MessageBuffer newMessageBuffer(ByteBuffer bb)
      * @param arr
      * @return
      */
-    private static MessageBuffer newMessageBuffer(byte[] arr)
+    private static MessageBuffer newMessageBuffer(byte[] arr, int off, int len)
     {
         checkNotNull(arr);
         try {
-            return (MessageBuffer) mbArrConstructor.newInstance(arr);
+            return (MessageBuffer) mbArrConstructor.newInstance(arr, off, len);
         }
         catch (Throwable e) {
             throw new RuntimeException(e);
@@ -261,76 +208,31 @@ public static void releaseBuffer(MessageBuffer buffer)
         if (isUniversalBuffer || buffer.base instanceof byte[]) {
             // We have nothing to do. Wait until the garbage-collector collects this array object
         }
-        else if (DirectBufferAccess.isDirectByteBufferInstance(buffer.base)) {
-            DirectBufferAccess.clean(buffer.base);
-        }
         else {
             // Maybe cannot reach here
             unsafe.freeMemory(buffer.address);
         }
     }
 
-    /**
-     * Create a MessageBuffer instance from a given memory address and length
-     *
-     * @param address
-     * @param length
-     */
-    MessageBuffer(long address, int length)
-    {
-        this.base = null;
-        this.address = address;
-        this.size = length;
-        this.reference = null;
-    }
-
-    /**
-     * Create a MessageBuffer instance from a given ByteBuffer instance
-     *
-     * @param bb
-     */
-    MessageBuffer(ByteBuffer bb)
-    {
-        if (bb.isDirect()) {
-            if (isUniversalBuffer) {
-                throw new IllegalStateException("Cannot create MessageBuffer from DirectBuffer");
-            }
-            // Direct buffer or off-heap memory
-            this.base = null;
-            this.address = DirectBufferAccess.getAddress(bb);
-            this.size = bb.capacity();
-            this.reference = bb;
-        }
-        else if (bb.hasArray()) {
-            this.base = bb.array();
-            this.address = ARRAY_BYTE_BASE_OFFSET;
-            this.size = bb.array().length;
-            this.reference = null;
-        }
-        else {
-            throw new IllegalArgumentException("Only the array-backed ByteBuffer or DirectBuffer are supported");
-        }
-    }
-
     /**
      * Create a MessageBuffer instance from an java heap array
      *
      * @param arr
+     * @param offset
+     * @param length
      */
-    MessageBuffer(byte[] arr)
+    MessageBuffer(byte[] arr, int offset, int length)
     {
         this.base = arr;
-        this.address = ARRAY_BYTE_BASE_OFFSET;
-        this.size = arr.length;
-        this.reference = null;
+        this.address = ARRAY_BYTE_BASE_OFFSET + offset;
+        this.size = length;
     }
 
-    MessageBuffer(Object base, long address, int length, ByteBuffer reference)
+    protected MessageBuffer(Object base, long address, int length)
     {
         this.base = base;
         this.address = address;
         this.size = length;
-        this.reference = reference;
     }
 
     /**
@@ -351,7 +253,7 @@ public MessageBuffer slice(int offset, int length)
         }
         else {
             checkArgument(offset + length <= size());
-            return new MessageBuffer(base, address + offset, length, reference);
+            return new MessageBuffer(base, address + offset, length);
         }
     }
 
@@ -411,7 +313,7 @@ public void getBytes(int index, int len, ByteBuffer dst)
         if (dst.remaining() < len) {
             throw new BufferOverflowException();
         }
-        ByteBuffer src = toByteBuffer(index, len);
+        ByteBuffer src = sliceAsByteBuffer(index, len);
         dst.put(src);
     }
 
@@ -499,15 +401,9 @@ else if (src.hasArray()) {
      * @param length
      * @return
      */
-    public ByteBuffer toByteBuffer(int index, int length)
+    public ByteBuffer sliceAsByteBuffer(int index, int length)
     {
-        if (hasArray()) {
-            return ByteBuffer.wrap((byte[]) base, (int) ((address - ARRAY_BYTE_BASE_OFFSET) + index), length);
-        }
-        else {
-            assert (!isUniversalBuffer);
-            return DirectBufferAccess.newByteBuffer(address, index, length, reference);
-        }
+        return ByteBuffer.wrap((byte[]) base, (int) ((address - ARRAY_BYTE_BASE_OFFSET) + index), length);
     }
 
     /**
@@ -515,9 +411,9 @@ public ByteBuffer toByteBuffer(int index, int length)
      *
      * @return
      */
-    public ByteBuffer toByteBuffer()
+    public ByteBuffer sliceAsByteBuffer()
     {
-        return toByteBuffer(0, size());
+        return sliceAsByteBuffer(0, size());
     }
 
     /**
@@ -567,12 +463,6 @@ public int offset()
         }
     }
 
-    @Insecure
-    public ByteBuffer getReference()
-    {
-        return reference;
-    }
-
     /**
      * Copy this buffer contents to another MessageBuffer
      *
diff --git a/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferBE.java b/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferBE.java
index 4fec0cd42..3f5d24976 100644
--- a/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferBE.java
+++ b/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferBE.java
@@ -27,19 +27,14 @@
 public class MessageBufferBE
         extends MessageBuffer
 {
-    MessageBufferBE(ByteBuffer bb)
+    MessageBufferBE(byte[] arr, int offset, int length)
     {
-        super(bb);
+        super(arr, offset, length);
     }
 
-    MessageBufferBE(byte[] arr)
+    private MessageBufferBE(Object base, long address, int length)
     {
-        super(arr);
-    }
-
-    private MessageBufferBE(Object base, long address, int length, ByteBuffer reference)
-    {
-        super(base, address, length, reference);
+        super(base, address, length);
     }
 
     @Override
@@ -50,7 +45,7 @@ public MessageBufferBE slice(int offset, int length)
         }
         else {
             checkArgument(offset + length <= size());
-            return new MessageBufferBE(base, address + offset, length, reference);
+            return new MessageBufferBE(base, address + offset, length);
         }
     }
 
diff --git a/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferU.java b/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferU.java
index 54caa8838..d5b68c1a4 100644
--- a/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferU.java
+++ b/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferU.java
@@ -28,15 +28,18 @@
 public class MessageBufferU
         extends MessageBuffer
 {
-    public MessageBufferU(ByteBuffer bb)
+    private final ByteBuffer wrap;
+
+    MessageBufferU(byte[] arr, int offset, int length)
     {
-        super(null, 0L, bb.capacity(), bb.order(ByteOrder.BIG_ENDIAN));
-        checkNotNull(reference);
+        super(arr, offset, length);
+        this.wrap = ByteBuffer.wrap(arr, offset, length);
     }
 
-    MessageBufferU(byte[] arr)
+    private MessageBufferU(Object base, long address, int length, ByteBuffer wrap)
     {
-        this(ByteBuffer.wrap(arr));
+        super(base, address, length);
+        this.wrap = wrap;
     }
 
     @Override
@@ -48,9 +51,9 @@ public MessageBufferU slice(int offset, int length)
         else {
             checkArgument(offset + length <= size());
             try {
-                reference.position(offset);
-                reference.limit(offset + length);
-                return new MessageBufferU(reference.slice());
+                wrap.position(offset);
+                wrap.limit(offset + length);
+                return new MessageBufferU(base, address + offset, length, wrap.slice());
             }
             finally {
                 resetBufferPosition();
@@ -60,59 +63,59 @@ public MessageBufferU slice(int offset, int length)
 
     private void resetBufferPosition()
     {
-        reference.position(0);
-        reference.limit(size);
+        wrap.position(0);
+        wrap.limit(size);
     }
 
     @Override
     public byte getByte(int index)
     {
-        return reference.get(index);
+        return wrap.get(index);
     }
 
     @Override
     public boolean getBoolean(int index)
     {
-        return reference.get(index) != 0;
+        return wrap.get(index) != 0;
     }
 
     @Override
     public short getShort(int index)
     {
-        return reference.getShort(index);
+        return wrap.getShort(index);
     }
 
     @Override
     public int getInt(int index)
     {
-        return reference.getInt(index);
+        return wrap.getInt(index);
     }
 
     @Override
     public float getFloat(int index)
     {
-        return reference.getFloat(index);
+        return wrap.getFloat(index);
     }
 
     @Override
     public long getLong(int index)
     {
-        return reference.getLong(index);
+        return wrap.getLong(index);
     }
 
     @Override
     public double getDouble(int index)
     {
-        return reference.getDouble(index);
+        return wrap.getDouble(index);
     }
 
     @Override
     public void getBytes(int index, int len, ByteBuffer dst)
     {
         try {
-            reference.position(index);
-            reference.limit(index + len);
-            dst.put(reference);
+            wrap.position(index);
+            wrap.limit(index + len);
+            dst.put(wrap);
         }
         finally {
             resetBufferPosition();
@@ -122,52 +125,52 @@ public void getBytes(int index, int len, ByteBuffer dst)
     @Override
     public void putByte(int index, byte v)
     {
-        reference.put(index, v);
+        wrap.put(index, v);
     }
 
     @Override
     public void putBoolean(int index, boolean v)
     {
-        reference.put(index, v ? (byte) 1 : (byte) 0);
+        wrap.put(index, v ? (byte) 1 : (byte) 0);
     }
 
     @Override
     public void putShort(int index, short v)
     {
-        reference.putShort(index, v);
+        wrap.putShort(index, v);
     }
 
     @Override
     public void putInt(int index, int v)
     {
-        reference.putInt(index, v);
+        wrap.putInt(index, v);
     }
 
     @Override
     public void putFloat(int index, float v)
     {
-        reference.putFloat(index, v);
+        wrap.putFloat(index, v);
     }
 
     @Override
     public void putLong(int index, long l)
     {
-        reference.putLong(index, l);
+        wrap.putLong(index, l);
     }
 
     @Override
     public void putDouble(int index, double v)
     {
-        reference.putDouble(index, v);
+        wrap.putDouble(index, v);
     }
 
     @Override
-    public ByteBuffer toByteBuffer(int index, int length)
+    public ByteBuffer sliceAsByteBuffer(int index, int length)
     {
         try {
-            reference.position(index);
-            reference.limit(index + length);
-            return reference.slice();
+            wrap.position(index);
+            wrap.limit(index + length);
+            return wrap.slice();
         }
         finally {
             resetBufferPosition();
@@ -175,17 +178,17 @@ public ByteBuffer toByteBuffer(int index, int length)
     }
 
     @Override
-    public ByteBuffer toByteBuffer()
+    public ByteBuffer sliceAsByteBuffer()
     {
-        return toByteBuffer(0, size);
+        return sliceAsByteBuffer(0, size);
     }
 
     @Override
     public void getBytes(int index, byte[] dst, int dstOffset, int length)
     {
         try {
-            reference.position(index);
-            reference.get(dst, dstOffset, length);
+            wrap.position(index);
+            wrap.get(dst, dstOffset, length);
         }
         finally {
             resetBufferPosition();
@@ -205,8 +208,8 @@ public void putByteBuffer(int index, ByteBuffer src, int len)
             int prevSrcLimit = src.limit();
             try {
                 src.limit(src.position() + len);
-                reference.position(index);
-                reference.put(src);
+                wrap.position(index);
+                wrap.put(src);
             }
             finally {
                 src.limit(prevSrcLimit);
@@ -218,8 +221,8 @@ public void putByteBuffer(int index, ByteBuffer src, int len)
     public void putBytes(int index, byte[] src, int srcOffset, int length)
     {
         try {
-            reference.position(index);
-            reference.put(src, srcOffset, length);
+            wrap.position(index);
+            wrap.put(src, srcOffset, length);
         }
         finally {
             resetBufferPosition();
@@ -230,8 +233,8 @@ public void putBytes(int index, byte[] src, int srcOffset, int length)
     public void copyTo(int index, MessageBuffer dst, int offset, int length)
     {
         try {
-            reference.position(index);
-            dst.putByteBuffer(offset, reference, length);
+            wrap.position(index);
+            dst.putByteBuffer(offset, wrap, length);
         }
         finally {
             resetBufferPosition();
diff --git a/msgpack-core/src/main/java/org/msgpack/core/buffer/OutputStreamBufferOutput.java b/msgpack-core/src/main/java/org/msgpack/core/buffer/OutputStreamBufferOutput.java
index d6f17c783..f29832b34 100644
--- a/msgpack-core/src/main/java/org/msgpack/core/buffer/OutputStreamBufferOutput.java
+++ b/msgpack-core/src/main/java/org/msgpack/core/buffer/OutputStreamBufferOutput.java
@@ -37,7 +37,7 @@ public OutputStreamBufferOutput(OutputStream out)
     public OutputStreamBufferOutput(OutputStream out, int bufferSize)
     {
         this.out = checkNotNull(out, "output is null");
-        this.buffer = MessageBuffer.newBuffer(bufferSize);
+        this.buffer = MessageBuffer.allocate(bufferSize);
     }
 
     /**
@@ -59,7 +59,7 @@ public MessageBuffer next(int mimimumSize)
             throws IOException
     {
         if (buffer.size() < mimimumSize) {
-            buffer = MessageBuffer.newBuffer(mimimumSize);
+            buffer = MessageBuffer.allocate(mimimumSize);
         }
         return buffer;
     }
diff --git a/msgpack-core/src/test/scala/org/msgpack/core/buffer/ByteStringTest.scala b/msgpack-core/src/test/scala/org/msgpack/core/buffer/ByteStringTest.scala
index 92103dc31..eb78432d2 100644
--- a/msgpack-core/src/test/scala/org/msgpack/core/buffer/ByteStringTest.scala
+++ b/msgpack-core/src/test/scala/org/msgpack/core/buffer/ByteStringTest.scala
@@ -44,19 +44,4 @@ class ByteStringTest
     new
         MessageUnpacker(input).unpackString()
   }
-
-  "Unpacking a ByteString's ByteBuffer" should {
-    "fail with a regular MessageBuffer" in {
-
-      // can't demonstrate with new ByteBufferInput(byteString.asByteBuffer)
-      // as Travis tests run with JDK6 that picks up MessageBufferU
-      a[RuntimeException] shouldBe thrownBy(unpackString(new
-          MessageBuffer(byteString.asByteBuffer)))
-    }
-
-    "succeed with a MessageBufferU" in {
-      unpackString(new
-          MessageBufferU(byteString.asByteBuffer)) shouldBe unpackedString
-    }
-  }
 }
diff --git a/msgpack-core/src/test/scala/org/msgpack/core/buffer/MessageBufferInputTest.scala b/msgpack-core/src/test/scala/org/msgpack/core/buffer/MessageBufferInputTest.scala
index b6ee7bf08..6333e381c 100644
--- a/msgpack-core/src/test/scala/org/msgpack/core/buffer/MessageBufferInputTest.scala
+++ b/msgpack-core/src/test/scala/org/msgpack/core/buffer/MessageBufferInputTest.scala
@@ -97,11 +97,6 @@ class MessageBufferInputTest
           ArrayBufferInput(_))
     }
 
-    "support ByteBuffers" in {
-      runTest(b => new
-          ByteBufferInput(b.toByteBuffer))
-    }
-
     "support InputStreams" taggedAs ("is") in {
       runTest(b =>
         new
diff --git a/msgpack-core/src/test/scala/org/msgpack/core/buffer/MessageBufferTest.scala b/msgpack-core/src/test/scala/org/msgpack/core/buffer/MessageBufferTest.scala
index db4dec659..75ef00a11 100644
--- a/msgpack-core/src/test/scala/org/msgpack/core/buffer/MessageBufferTest.scala
+++ b/msgpack-core/src/test/scala/org/msgpack/core/buffer/MessageBufferTest.scala
@@ -30,14 +30,13 @@ class MessageBufferTest
   "MessageBuffer" should {
 
     "check buffer type" in {
-      val b = MessageBuffer.newBuffer(0)
+      val b = MessageBuffer.allocate(0)
       info(s"MessageBuffer type: ${b.getClass.getName}")
     }
 
     "wrap ByteBuffer considering position and remaining values" taggedAs ("wrap-bb") in {
       val d = Array[Byte](10, 11, 12, 13, 14, 15, 16, 17, 18, 19)
-      val subset = ByteBuffer.wrap(d, 2, 2)
-      val mb = MessageBuffer.wrap(subset)
+      val mb = MessageBuffer.wrap(d, 2, 2)
       mb.getByte(0) shouldBe 12
       mb.size() shouldBe 2
     }
@@ -47,8 +46,7 @@ class MessageBufferTest
       val N = 1000000
       val M = 64 * 1024 * 1024
 
-      val ub = MessageBuffer.newBuffer(M)
-      val ud = MessageBuffer.newDirectBuffer(M)
+      val ub = MessageBuffer.allocate(M)
       val hb = ByteBuffer.allocate(M)
       val db = ByteBuffer.allocateDirect(M)
 
@@ -84,14 +82,6 @@ class MessageBufferTest
           }
         }
 
-        block("unsafe direct") {
-          var i = 0
-          while (i < N) {
-            ud.getInt((i * 4) % M)
-            i += 1
-          }
-        }
-
         block("allocate") {
           var i = 0
           while (i < N) {
@@ -118,14 +108,6 @@ class MessageBufferTest
           }
         }
 
-        block("unsafe direct") {
-          var i = 0
-          while (i < N) {
-            ud.getInt((rs(i) * 4) % M)
-            i += 1
-          }
-        }
-
         block("allocate") {
           var i = 0
           while (i < N) {
@@ -146,11 +128,9 @@ class MessageBufferTest
 
     "convert to ByteBuffer" in {
       for (t <- Seq(
-        MessageBuffer.newBuffer(10),
-        MessageBuffer.newDirectBuffer(10),
-        MessageBuffer.newOffHeapBuffer(10))
+        MessageBuffer.allocate(10))
       ) {
-        val bb = t.toByteBuffer
+        val bb = t.sliceAsByteBuffer
         bb.position shouldBe 0
         bb.limit shouldBe 10
         bb.capacity shouldBe 10
@@ -159,9 +139,7 @@ class MessageBufferTest
 
     "put ByteBuffer on itself" in {
       for (t <- Seq(
-        MessageBuffer.newBuffer(10),
-        MessageBuffer.newDirectBuffer(10),
-        MessageBuffer.newOffHeapBuffer(10))
+        MessageBuffer.allocate(10))
       ) {
         val b = Array[Byte](0x02, 0x03)
         val srcArray = ByteBuffer.wrap(b)
@@ -190,13 +168,6 @@ class MessageBufferTest
         Array[Byte](0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07)
       }
 
-      def prepareDirectBuffer : ByteBuffer = {
-        val directBuffer = ByteBuffer.allocateDirect(prepareBytes.length)
-        directBuffer.put(prepareBytes)
-        directBuffer.flip
-        directBuffer
-      }
-
       def checkSliceAndCopyTo(srcBuffer: MessageBuffer, dstBuffer: MessageBuffer) = {
         val sliced = srcBuffer.slice(2, 5)
 
@@ -220,8 +191,6 @@ class MessageBufferTest
       }
 
       checkSliceAndCopyTo(MessageBuffer.wrap(prepareBytes), MessageBuffer.wrap(prepareBytes))
-      checkSliceAndCopyTo(MessageBuffer.wrap(ByteBuffer.wrap(prepareBytes)), MessageBuffer.wrap(ByteBuffer.wrap(prepareBytes)))
-      checkSliceAndCopyTo(MessageBuffer.wrap(prepareDirectBuffer), MessageBuffer.wrap(prepareDirectBuffer))
     }
   }
 }

From a82ded243c1190ed9563edd9a187b0d383f5f082 Mon Sep 17 00:00:00 2001
From: Sadayuki Furuhashi 
Date: Fri, 25 Dec 2015 16:03:35 +0900
Subject: [PATCH 169/234] MessageBuffer is now always safe to get internal
 array, and exposing base and address become unnecessary

---
 .../java/org/msgpack/core/MessagePacker.java  |  4 +--
 .../org/msgpack/core/MessageUnpacker.java     |  9 +++---
 .../core/{annotations => }/Nullable.java      |  4 +--
 .../java/org/msgpack/core/Preconditions.java  |  1 -
 .../msgpack/core/annotations/Insecure.java    | 23 -------------
 .../msgpack/core/buffer/MessageBuffer.java    | 32 ++-----------------
 .../msgpack/core/buffer/MessageBufferU.java   |  5 ++-
 .../core/buffer/OutputStreamBufferOutput.java |  2 +-
 8 files changed, 16 insertions(+), 64 deletions(-)
 rename msgpack-core/src/main/java/org/msgpack/core/{annotations => }/Nullable.java (91%)
 delete mode 100644 msgpack-core/src/main/java/org/msgpack/core/annotations/Insecure.java

diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessagePacker.java b/msgpack-core/src/main/java/org/msgpack/core/MessagePacker.java
index 7c71b6807..b3fcff5a8 100644
--- a/msgpack-core/src/main/java/org/msgpack/core/MessagePacker.java
+++ b/msgpack-core/src/main/java/org/msgpack/core/MessagePacker.java
@@ -505,7 +505,7 @@ else if (s.length() < (1 << 8)) {
                     }
                     // move 1 byte backward to expand 3-byte header region to 3 bytes
                     buffer.putBytes(position + 3,
-                            buffer.getArray(), buffer.offset() + position + 2, written);
+                            buffer.array(), buffer.arrayOffset() + position + 2, written);
                     // write 3-byte header header
                     buffer.putByte(position++, STR16);
                     buffer.putShort(position, (short) written);
@@ -534,7 +534,7 @@ else if (s.length() < (1 << 16)) {
                     }
                     // move 2 bytes backward to expand 3-byte header region to 5 bytes
                     buffer.putBytes(position + 5,
-                            buffer.getArray(), buffer.offset() + position + 3, written);
+                            buffer.array(), buffer.arrayOffset() + position + 3, written);
                     // write 3-byte header header
                     buffer.putByte(position++, STR32);
                     buffer.putInt(position, written);
diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java b/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java
index 2e00a5bc3..6ef5901f5 100644
--- a/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java
+++ b/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java
@@ -255,8 +255,8 @@ private MessageBuffer readCastBuffer(int length)
 
             // TODO this doesn't work if MessageBuffer is allocated by newDirectBuffer.
             //      add copy method to MessageBuffer to solve this issue.
-            castBuffer.putBytes(0, buffer.getArray(), buffer.offset() + position, remaining);
-            castBuffer.putBytes(remaining, next.getArray(), next.offset(), length - remaining);
+            castBuffer.putBytes(0, buffer.array(), buffer.arrayOffset() + position, remaining);
+            castBuffer.putBytes(remaining, next.array(), next.arrayOffset(), length - remaining);
 
             totalReadBytes += buffer.size();
 
@@ -1106,9 +1106,8 @@ private void handleCoderError(CoderResult cr)
     private String decodeStringFastPath(int length)
     {
         if (actionOnMalformedString == CodingErrorAction.REPLACE &&
-                actionOnUnmappableString == CodingErrorAction.REPLACE &&
-                buffer.hasArray()) {
-            String s = new String(buffer.getArray(), buffer.offset() + position, length, MessagePack.UTF8);
+                actionOnUnmappableString == CodingErrorAction.REPLACE) {
+            String s = new String(buffer.array(), buffer.arrayOffset() + position, length, MessagePack.UTF8);
             position += length;
             return s;
         }
diff --git a/msgpack-core/src/main/java/org/msgpack/core/annotations/Nullable.java b/msgpack-core/src/main/java/org/msgpack/core/Nullable.java
similarity index 91%
rename from msgpack-core/src/main/java/org/msgpack/core/annotations/Nullable.java
rename to msgpack-core/src/main/java/org/msgpack/core/Nullable.java
index 9e7c94fab..b2e7585a5 100644
--- a/msgpack-core/src/main/java/org/msgpack/core/annotations/Nullable.java
+++ b/msgpack-core/src/main/java/org/msgpack/core/Nullable.java
@@ -13,11 +13,11 @@
 //    See the License for the specific language governing permissions and
 //    limitations under the License.
 //
-package org.msgpack.core.annotations;
+package org.msgpack.core;
 
 /**
  * Annotates a field which can be null
  */
-public @interface Nullable
+@interface Nullable
 {
 }
diff --git a/msgpack-core/src/main/java/org/msgpack/core/Preconditions.java b/msgpack-core/src/main/java/org/msgpack/core/Preconditions.java
index e44d97d15..d8f43bcb7 100644
--- a/msgpack-core/src/main/java/org/msgpack/core/Preconditions.java
+++ b/msgpack-core/src/main/java/org/msgpack/core/Preconditions.java
@@ -31,7 +31,6 @@
  */
 package org.msgpack.core;
 
-import org.msgpack.core.annotations.Nullable;
 import org.msgpack.core.annotations.VisibleForTesting;
 
 /**
diff --git a/msgpack-core/src/main/java/org/msgpack/core/annotations/Insecure.java b/msgpack-core/src/main/java/org/msgpack/core/annotations/Insecure.java
deleted file mode 100644
index c8678ae41..000000000
--- a/msgpack-core/src/main/java/org/msgpack/core/annotations/Insecure.java
+++ /dev/null
@@ -1,23 +0,0 @@
-//
-// MessagePack for Java
-//
-//    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.core.annotations;
-
-/**
- * Annotates a code which must be used carefully.
- */
-public @interface Insecure
-{
-}
diff --git a/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBuffer.java b/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBuffer.java
index e2258265e..d4d5f2238 100644
--- a/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBuffer.java
+++ b/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBuffer.java
@@ -15,7 +15,6 @@
 //
 package org.msgpack.core.buffer;
 
-import org.msgpack.core.annotations.Insecure;
 import sun.misc.Unsafe;
 
 import java.lang.reflect.Constructor;
@@ -428,39 +427,14 @@ public byte[] toByteArray()
         return b;
     }
 
-    @Insecure
-    public boolean hasArray()
-    {
-        return base instanceof byte[];
-    }
-
-    @Insecure
-    public byte[] getArray()
+    public byte[] array()
     {
         return (byte[]) base;
     }
 
-    @Insecure
-    public Object getBase()
-    {
-        return base;
-    }
-
-    @Insecure
-    public long getAddress()
+    public int arrayOffset()
     {
-        return address;
-    }
-
-    @Insecure
-    public int offset()
-    {
-        if (hasArray()) {
-            return (int) address - ARRAY_BYTE_BASE_OFFSET;
-        }
-        else {
-            return 0;
-        }
+        return (int) address - ARRAY_BYTE_BASE_OFFSET;
     }
 
     /**
diff --git a/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferU.java b/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferU.java
index d5b68c1a4..151b6cd2e 100644
--- a/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferU.java
+++ b/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferU.java
@@ -33,7 +33,10 @@ public class MessageBufferU
     MessageBufferU(byte[] arr, int offset, int length)
     {
         super(arr, offset, length);
-        this.wrap = ByteBuffer.wrap(arr, offset, length);
+        ByteBuffer bb = ByteBuffer.wrap(arr);
+        bb.position(offset);
+        bb.limit(offset + length);
+        this.wrap = bb.slice();
     }
 
     private MessageBufferU(Object base, long address, int length, ByteBuffer wrap)
diff --git a/msgpack-core/src/main/java/org/msgpack/core/buffer/OutputStreamBufferOutput.java b/msgpack-core/src/main/java/org/msgpack/core/buffer/OutputStreamBufferOutput.java
index f29832b34..08fd3960b 100644
--- a/msgpack-core/src/main/java/org/msgpack/core/buffer/OutputStreamBufferOutput.java
+++ b/msgpack-core/src/main/java/org/msgpack/core/buffer/OutputStreamBufferOutput.java
@@ -68,7 +68,7 @@ public MessageBuffer next(int mimimumSize)
     public void writeBuffer(int length)
             throws IOException
     {
-        write(buffer.getArray(), buffer.offset(), length);
+        write(buffer.array(), buffer.arrayOffset(), length);
     }
 
     @Override

From 05af0e62bacdb386f404c568f4c47116c67e83ec Mon Sep 17 00:00:00 2001
From: Mitsunori Komatsu 
Date: Fri, 25 Dec 2015 16:06:29 +0900
Subject: [PATCH 170/234] Remove unused import

---
 .../test/java/org/msgpack/core/example/MessagePackExample.java   | 1 -
 1 file changed, 1 deletion(-)

diff --git a/msgpack-core/src/test/java/org/msgpack/core/example/MessagePackExample.java b/msgpack-core/src/test/java/org/msgpack/core/example/MessagePackExample.java
index d7dffe64b..9a8242591 100644
--- a/msgpack-core/src/test/java/org/msgpack/core/example/MessagePackExample.java
+++ b/msgpack-core/src/test/java/org/msgpack/core/example/MessagePackExample.java
@@ -32,7 +32,6 @@
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.math.BigInteger;
-import java.nio.ByteBuffer;
 import java.nio.charset.CodingErrorAction;
 
 /**

From 7d425ede89b073c86239d8ae7a1e431e05ae63ea Mon Sep 17 00:00:00 2001
From: Sadayuki Furuhashi 
Date: Fri, 25 Dec 2015 16:06:48 +0900
Subject: [PATCH 171/234] fixed unused import

---
 .../test/java/org/msgpack/core/example/MessagePackExample.java   | 1 -
 1 file changed, 1 deletion(-)

diff --git a/msgpack-core/src/test/java/org/msgpack/core/example/MessagePackExample.java b/msgpack-core/src/test/java/org/msgpack/core/example/MessagePackExample.java
index d7dffe64b..9a8242591 100644
--- a/msgpack-core/src/test/java/org/msgpack/core/example/MessagePackExample.java
+++ b/msgpack-core/src/test/java/org/msgpack/core/example/MessagePackExample.java
@@ -32,7 +32,6 @@
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.math.BigInteger;
-import java.nio.ByteBuffer;
 import java.nio.charset.CodingErrorAction;
 
 /**

From e7876009498ffefe92a09201a6e1c3d8f38add59 Mon Sep 17 00:00:00 2001
From: Mitsunori Komatsu 
Date: Fri, 25 Dec 2015 16:31:48 +0900
Subject: [PATCH 172/234] Lift threshold of benchmark test in MessagePackerTest

---
 .../src/test/scala/org/msgpack/core/MessagePackerTest.scala     | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/msgpack-core/src/test/scala/org/msgpack/core/MessagePackerTest.scala b/msgpack-core/src/test/scala/org/msgpack/core/MessagePackerTest.scala
index f598a133f..20f4f560b 100644
--- a/msgpack-core/src/test/scala/org/msgpack/core/MessagePackerTest.scala
+++ b/msgpack-core/src/test/scala/org/msgpack/core/MessagePackerTest.scala
@@ -259,7 +259,7 @@ class MessagePackerTest
           measureDuration(fileOutput)
         }
       }
-      t("file-output-stream").averageWithoutMinMax shouldBe < (t("byte-array-output-stream").averageWithoutMinMax * 4)
+      t("file-output-stream").averageWithoutMinMax shouldBe < (t("byte-array-output-stream").averageWithoutMinMax * 5)
     }
   }
 

From 7791ffbc3bebaea5ffc0f1bd21e8945caf45a2ab Mon Sep 17 00:00:00 2001
From: Mitsunori Komatsu 
Date: Fri, 25 Dec 2015 16:55:56 +0900
Subject: [PATCH 173/234] Ignore micro benchmark comparison

---
 .../src/test/scala/org/msgpack/core/MessageUnpackerTest.scala | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/msgpack-core/src/test/scala/org/msgpack/core/MessageUnpackerTest.scala b/msgpack-core/src/test/scala/org/msgpack/core/MessageUnpackerTest.scala
index 672edd615..fc03d5680 100644
--- a/msgpack-core/src/test/scala/org/msgpack/core/MessageUnpackerTest.scala
+++ b/msgpack-core/src/test/scala/org/msgpack/core/MessageUnpackerTest.scala
@@ -608,8 +608,8 @@ class MessageUnpackerTest extends MessagePackSpec {
         }
       }
 
-      t("reuse-message-buffer").averageWithoutMinMax should be <= t("no-buffer-reset").averageWithoutMinMax
-      // This performance comparition is too close, so we disabled it
+      // This performance comparison is too close, so we disabled it
+      // t("reuse-message-buffer").averageWithoutMinMax should be <= t("no-buffer-reset").averageWithoutMinMax
       // t("reuse-array-input").averageWithoutMinMax should be <= t("no-buffer-reset").averageWithoutMinMax
     }
 

From f861bd580cbf73cbdb701b6a49aad387c095327b Mon Sep 17 00:00:00 2001
From: Sadayuki Furuhashi 
Date: Sat, 26 Dec 2015 18:46:29 +0900
Subject: [PATCH 174/234] renamed
 org.msgpack.jackson.dataformat.MessagePackFactory to MessagePackFormatFactory
 to avoid name confusion

---
 msgpack-jackson/README.md                     |  4 +--
 ...ory.java => MessagePackFormatFactory.java} |  2 +-
 .../ExampleOfTypeInformationSerDe.java        |  2 +-
 .../MessagePackDataformatTestBase.java        |  4 +--
 ...java => MessagePackFormatFactoryTest.java} |  2 +-
 .../dataformat/MessagePackGeneratorTest.java  | 12 +++----
 .../dataformat/MessagePackParserTest.java     | 32 +++++++++----------
 ...gePackDataformatHugeDataBenchmarkTest.java |  6 ++--
 ...essagePackDataformatPojoBenchmarkTest.java |  6 ++--
 9 files changed, 35 insertions(+), 35 deletions(-)
 rename msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/{MessagePackFactory.java => MessagePackFormatFactory.java} (98%)
 rename msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/{MessagePackFactoryTest.java => MessagePackFormatFactoryTest.java} (97%)

diff --git a/msgpack-jackson/README.md b/msgpack-jackson/README.md
index 55ed19233..51435b401 100644
--- a/msgpack-jackson/README.md
+++ b/msgpack-jackson/README.md
@@ -29,10 +29,10 @@ dependencies {
 
 ## Usage
 
-Only thing you need to do is to instantiate MessagePackFactory and pass it to the constructor of ObjectMapper.
+Only thing you need to do is to instantiate MessagePackFormatFactory and pass it to the constructor of ObjectMapper.
 
 ```
-  ObjectMapper objectMapper = new ObjectMapper(new MessagePackFactory());
+  ObjectMapper objectMapper = new ObjectMapper(new MessagePackFormatFactory());
   ExamplePojo orig = new ExamplePojo("komamitsu");
   byte[] bytes = objectMapper.writeValueAsBytes(orig);
   ExamplePojo value = objectMapper.readValue(bytes, ExamplePojo.class);
diff --git a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackFactory.java b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackFormatFactory.java
similarity index 98%
rename from msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackFactory.java
rename to msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackFormatFactory.java
index ff7aa373f..1082e5770 100644
--- a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackFactory.java
+++ b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackFormatFactory.java
@@ -30,7 +30,7 @@
 import java.io.Writer;
 import java.util.Arrays;
 
-public class MessagePackFactory
+public class MessagePackFormatFactory
         extends JsonFactory
 {
     private static final long serialVersionUID = 2578263992015504347L;
diff --git a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/ExampleOfTypeInformationSerDe.java b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/ExampleOfTypeInformationSerDe.java
index 5414b0bdc..6a211b3ae 100644
--- a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/ExampleOfTypeInformationSerDe.java
+++ b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/ExampleOfTypeInformationSerDe.java
@@ -151,7 +151,7 @@ public void test()
             objectContainer.getObjects().put("pi", pi);
         }
 
-        ObjectMapper objectMapper = new ObjectMapper(new MessagePackFactory());
+        ObjectMapper objectMapper = new ObjectMapper(new MessagePackFormatFactory());
         byte[] bytes = objectMapper.writeValueAsBytes(objectContainer);
         ObjectContainer restored = objectMapper.readValue(bytes, ObjectContainer.class);
 
diff --git a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackDataformatTestBase.java b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackDataformatTestBase.java
index 1d5156adc..c9692ebf9 100644
--- a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackDataformatTestBase.java
+++ b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackDataformatTestBase.java
@@ -35,7 +35,7 @@
 
 public class MessagePackDataformatTestBase
 {
-    protected MessagePackFactory factory;
+    protected MessagePackFormatFactory factory;
     protected ByteArrayOutputStream out;
     protected ByteArrayInputStream in;
     protected ObjectMapper objectMapper;
@@ -47,7 +47,7 @@ public class MessagePackDataformatTestBase
     @Before
     public void setup()
     {
-        factory = new MessagePackFactory();
+        factory = new MessagePackFormatFactory();
         objectMapper = new ObjectMapper(factory);
         out = new ByteArrayOutputStream();
         in = new ByteArrayInputStream(new byte[4096]);
diff --git a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackFactoryTest.java b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackFormatFactoryTest.java
similarity index 97%
rename from msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackFactoryTest.java
rename to msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackFormatFactoryTest.java
index 25180f784..f7e5fe045 100644
--- a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackFactoryTest.java
+++ b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackFormatFactoryTest.java
@@ -24,7 +24,7 @@
 
 import static org.junit.Assert.assertEquals;
 
-public class MessagePackFactoryTest
+public class MessagePackFormatFactoryTest
         extends MessagePackDataformatTestBase
 {
     @Test
diff --git a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackGeneratorTest.java b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackGeneratorTest.java
index b88d0d645..de58e4a1a 100644
--- a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackGeneratorTest.java
+++ b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackGeneratorTest.java
@@ -230,7 +230,7 @@ else if (key.equals("num")) {
     public void testMessagePackGeneratorDirectly()
             throws Exception
     {
-        MessagePackFactory messagePackFactory = new MessagePackFactory();
+        MessagePackFormatFactory messagePackFactory = new MessagePackFormatFactory();
         File tempFile = createTempFile();
 
         JsonGenerator generator = messagePackFactory.createGenerator(tempFile, JsonEncoding.UTF8);
@@ -257,7 +257,7 @@ public void testMessagePackGeneratorDirectly()
     public void testWritePrimitives()
             throws Exception
     {
-        MessagePackFactory messagePackFactory = new MessagePackFactory();
+        MessagePackFormatFactory messagePackFactory = new MessagePackFormatFactory();
         File tempFile = createTempFile();
 
         JsonGenerator generator = messagePackFactory.createGenerator(tempFile, JsonEncoding.UTF8);
@@ -280,7 +280,7 @@ public void testWritePrimitives()
     public void testBigDecimal()
             throws IOException
     {
-        ObjectMapper mapper = new ObjectMapper(new MessagePackFactory());
+        ObjectMapper mapper = new ObjectMapper(new MessagePackFormatFactory());
 
         {
             double d0 = 1.23456789;
@@ -328,7 +328,7 @@ public void testEnableFeatureAutoCloseTarget()
             throws IOException
     {
         OutputStream out = createTempFileOutputStream();
-        MessagePackFactory messagePackFactory = new MessagePackFactory();
+        MessagePackFormatFactory messagePackFactory = new MessagePackFormatFactory();
         ObjectMapper objectMapper = new ObjectMapper(messagePackFactory);
         List integers = Arrays.asList(1);
         objectMapper.writeValue(out, integers);
@@ -341,7 +341,7 @@ public void testDisableFeatureAutoCloseTarget()
     {
         File tempFile = createTempFile();
         OutputStream out = new FileOutputStream(tempFile);
-        MessagePackFactory messagePackFactory = new MessagePackFactory();
+        MessagePackFormatFactory messagePackFactory = new MessagePackFormatFactory();
         ObjectMapper objectMapper = new ObjectMapper(messagePackFactory);
         objectMapper.configure(JsonGenerator.Feature.AUTO_CLOSE_TARGET, false);
         List integers = Arrays.asList(1);
@@ -363,7 +363,7 @@ public void testWritePrimitiveObjectViaObjectMapper()
         File tempFile = createTempFile();
         OutputStream out = new FileOutputStream(tempFile);
 
-        ObjectMapper objectMapper = new ObjectMapper(new MessagePackFactory());
+        ObjectMapper objectMapper = new ObjectMapper(new MessagePackFormatFactory());
         objectMapper.configure(JsonGenerator.Feature.AUTO_CLOSE_TARGET, false);
         objectMapper.writeValue(out, 1);
         objectMapper.writeValue(out, "two");
diff --git a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackParserTest.java b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackParserTest.java
index 96af2de32..3321110d4 100644
--- a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackParserTest.java
+++ b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackParserTest.java
@@ -288,7 +288,7 @@ else if (k.equals("child_map_age")) {
     public void testMessagePackParserDirectly()
             throws IOException
     {
-        MessagePackFactory messagePackFactory = new MessagePackFactory();
+        MessagePackFormatFactory factory = new MessagePackFormatFactory();
         File tempFile = File.createTempFile("msgpackTest", "msgpack");
         tempFile.deleteOnExit();
 
@@ -301,7 +301,7 @@ public void testMessagePackParserDirectly()
         packer.packFloat(1.0f);
         packer.close();
 
-        JsonParser parser = messagePackFactory.createParser(tempFile);
+        JsonParser parser = factory.createParser(tempFile);
         assertTrue(parser instanceof MessagePackParser);
 
         JsonToken jsonToken = parser.nextToken();
@@ -354,7 +354,7 @@ public void testMessagePackParserDirectly()
     public void testReadPrimitives()
             throws Exception
     {
-        MessagePackFactory messagePackFactory = new MessagePackFactory();
+        MessagePackFormatFactory factory = new MessagePackFormatFactory();
         File tempFile = createTempFile();
 
         FileOutputStream out = new FileOutputStream(tempFile);
@@ -367,7 +367,7 @@ public void testReadPrimitives()
         packer.writePayload(bytes);
         packer.close();
 
-        JsonParser parser = messagePackFactory.createParser(new FileInputStream(tempFile));
+        JsonParser parser = factory.createParser(new FileInputStream(tempFile));
         assertEquals(JsonToken.VALUE_STRING, parser.nextToken());
         assertEquals("foo", parser.getText());
         assertEquals(JsonToken.VALUE_NUMBER_FLOAT, parser.nextToken());
@@ -396,7 +396,7 @@ public void testBigDecimal()
         packer.packDouble(Double.MIN_NORMAL);
         packer.flush();
 
-        ObjectMapper mapper = new ObjectMapper(new MessagePackFactory());
+        ObjectMapper mapper = new ObjectMapper(new MessagePackFormatFactory());
         mapper.configure(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS, true);
         List objects = mapper.readValue(out.toByteArray(), new TypeReference>() {});
         assertEquals(5, objects.size());
@@ -431,9 +431,9 @@ public void testEnableFeatureAutoCloseSource()
             throws Exception
     {
         File tempFile = createTestFile();
-        MessagePackFactory messagePackFactory = new MessagePackFactory();
+        MessagePackFormatFactory factory = new MessagePackFormatFactory();
         FileInputStream in = new FileInputStream(tempFile);
-        ObjectMapper objectMapper = new ObjectMapper(messagePackFactory);
+        ObjectMapper objectMapper = new ObjectMapper(factory);
         objectMapper.readValue(in, new TypeReference>() {});
         objectMapper.readValue(in, new TypeReference>() {});
     }
@@ -444,7 +444,7 @@ public void testDisableFeatureAutoCloseSource()
     {
         File tempFile = createTestFile();
         FileInputStream in = new FileInputStream(tempFile);
-        ObjectMapper objectMapper = new ObjectMapper(new MessagePackFactory());
+        ObjectMapper objectMapper = new ObjectMapper(new MessagePackFormatFactory());
         objectMapper.configure(JsonParser.Feature.AUTO_CLOSE_SOURCE, false);
         objectMapper.readValue(in, new TypeReference>() {});
         objectMapper.readValue(in, new TypeReference>() {});
@@ -456,7 +456,7 @@ public void testParseBigDecimal()
     {
         ArrayList list = new ArrayList();
         list.add(new BigDecimal(Long.MAX_VALUE));
-        ObjectMapper objectMapper = new ObjectMapper(new MessagePackFactory());
+        ObjectMapper objectMapper = new ObjectMapper(new MessagePackFormatFactory());
         byte[] bytes = objectMapper.writeValueAsBytes(list);
 
         ArrayList result = objectMapper.readValue(
@@ -481,7 +481,7 @@ public void testReadPrimitiveObjectViaObjectMapper()
         packer.close();
 
         FileInputStream in = new FileInputStream(tempFile);
-        ObjectMapper objectMapper = new ObjectMapper(new MessagePackFactory());
+        ObjectMapper objectMapper = new ObjectMapper(new MessagePackFormatFactory());
         objectMapper.configure(JsonParser.Feature.AUTO_CLOSE_SOURCE, false);
         assertEquals("foo", objectMapper.readValue(in, new TypeReference() {}));
         long l = objectMapper.readValue(in, new TypeReference() {});
@@ -511,7 +511,7 @@ public void testBinaryKey()
         packer.packLong(42);
         packer.close();
 
-        ObjectMapper mapper = new ObjectMapper(new MessagePackFactory());
+        ObjectMapper mapper = new ObjectMapper(new MessagePackFormatFactory());
         Map object = mapper.readValue(new FileInputStream(tempFile), new TypeReference>() {});
         assertEquals(2, object.size());
         assertEquals(3.14, object.get("foo"));
@@ -533,7 +533,7 @@ public void testBinaryKeyInNestedObject()
         packer.packInt(1);
         packer.close();
 
-        ObjectMapper mapper = new ObjectMapper(new MessagePackFactory());
+        ObjectMapper mapper = new ObjectMapper(new MessagePackFormatFactory());
         List objects = mapper.readValue(out.toByteArray(), new TypeReference>() {});
         assertEquals(2, objects.size());
         @SuppressWarnings(value = "unchecked")
@@ -555,7 +555,7 @@ public void testByteArrayKey()
         messagePacker.packBinaryHeader(1).writePayload(k1).packInt(3);
         messagePacker.close();
 
-        ObjectMapper objectMapper = new ObjectMapper(new MessagePackFactory());
+        ObjectMapper objectMapper = new ObjectMapper(new MessagePackFormatFactory());
         SimpleModule module = new SimpleModule();
         module.addKeyDeserializer(byte[].class, new KeyDeserializer()
         {
@@ -592,7 +592,7 @@ public void testIntegerKey()
         }
         messagePacker.close();
 
-        ObjectMapper objectMapper = new ObjectMapper(new MessagePackFactory());
+        ObjectMapper objectMapper = new ObjectMapper(new MessagePackFormatFactory());
         SimpleModule module = new SimpleModule();
         module.addKeyDeserializer(Integer.class, new KeyDeserializer()
         {
@@ -623,7 +623,7 @@ public void testFloatKey()
         }
         messagePacker.close();
 
-        ObjectMapper objectMapper = new ObjectMapper(new MessagePackFactory());
+        ObjectMapper objectMapper = new ObjectMapper(new MessagePackFormatFactory());
         SimpleModule module = new SimpleModule();
         module.addKeyDeserializer(Float.class, new KeyDeserializer()
         {
@@ -653,7 +653,7 @@ public void testBooleanKey()
         messagePacker.packBoolean(false).packInt(3);
         messagePacker.close();
 
-        ObjectMapper objectMapper = new ObjectMapper(new MessagePackFactory());
+        ObjectMapper objectMapper = new ObjectMapper(new MessagePackFormatFactory());
         SimpleModule module = new SimpleModule();
         module.addKeyDeserializer(Boolean.class, new KeyDeserializer()
         {
diff --git a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/benchmark/MessagePackDataformatHugeDataBenchmarkTest.java b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/benchmark/MessagePackDataformatHugeDataBenchmarkTest.java
index b3a159111..aaf828439 100644
--- a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/benchmark/MessagePackDataformatHugeDataBenchmarkTest.java
+++ b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/benchmark/MessagePackDataformatHugeDataBenchmarkTest.java
@@ -20,7 +20,7 @@
 import com.fasterxml.jackson.core.type.TypeReference;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import org.junit.Test;
-import org.msgpack.jackson.dataformat.MessagePackFactory;
+import org.msgpack.jackson.dataformat.MessagePackFormatFactory;
 
 import java.io.File;
 import java.io.FileOutputStream;
@@ -34,7 +34,7 @@ public class MessagePackDataformatHugeDataBenchmarkTest
     private static final int COUNT = 6;
     private static final int WARMUP_COUNT = 4;
     private final ObjectMapper origObjectMapper = new ObjectMapper();
-    private final ObjectMapper msgpackObjectMapper = new ObjectMapper(new MessagePackFactory());
+    private final ObjectMapper msgpackObjectMapper = new ObjectMapper(new MessagePackFormatFactory());
     private static final List value;
     private static final byte[] packedByOriginal;
     private static final byte[] packedByMsgPack;
@@ -61,7 +61,7 @@ public class MessagePackDataformatHugeDataBenchmarkTest
         packedByOriginal = bytes;
 
         try {
-            bytes = new ObjectMapper(new MessagePackFactory()).writeValueAsBytes(value);
+            bytes = new ObjectMapper(new MessagePackFormatFactory()).writeValueAsBytes(value);
         }
         catch (JsonProcessingException e) {
             e.printStackTrace();
diff --git a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/benchmark/MessagePackDataformatPojoBenchmarkTest.java b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/benchmark/MessagePackDataformatPojoBenchmarkTest.java
index de2118508..33c5f024c 100644
--- a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/benchmark/MessagePackDataformatPojoBenchmarkTest.java
+++ b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/benchmark/MessagePackDataformatPojoBenchmarkTest.java
@@ -19,7 +19,7 @@
 import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import org.junit.Test;
-import org.msgpack.jackson.dataformat.MessagePackFactory;
+import org.msgpack.jackson.dataformat.MessagePackFormatFactory;
 import static org.msgpack.jackson.dataformat.MessagePackDataformatTestBase.NormalPojo;
 import static org.msgpack.jackson.dataformat.MessagePackDataformatTestBase.Suit;
 
@@ -40,11 +40,11 @@ public class MessagePackDataformatPojoBenchmarkTest
     private static final List pojosSerWithOrig = new ArrayList(LOOP_MAX);
     private static final List pojosSerWithMsgPack = new ArrayList(LOOP_MAX);
     private final ObjectMapper origObjectMapper = new ObjectMapper();
-    private final ObjectMapper msgpackObjectMapper = new ObjectMapper(new MessagePackFactory());
+    private final ObjectMapper msgpackObjectMapper = new ObjectMapper(new MessagePackFormatFactory());
 
     static {
         final ObjectMapper origObjectMapper = new ObjectMapper();
-        final ObjectMapper msgpackObjectMapper = new ObjectMapper(new MessagePackFactory());
+        final ObjectMapper msgpackObjectMapper = new ObjectMapper(new MessagePackFormatFactory());
 
         for (int i = 0; i < LOOP_MAX; i++) {
             NormalPojo pojo = new NormalPojo();

From b84cbb3aaae4d95dda2b89a20b99396b3cba4383 Mon Sep 17 00:00:00 2001
From: Sadayuki Furuhashi 
Date: Sun, 27 Dec 2015 12:58:18 +0900
Subject: [PATCH 175/234] optimized slightly MessageUnpacker.readCastBuffer

---
 .../org/msgpack/core/MessageUnpacker.java     | 26 ++++++++++++-------
 .../core/buffer/InputStreamBufferInput.java   |  2 +-
 2 files changed, 18 insertions(+), 10 deletions(-)

diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java b/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java
index 6ef5901f5..4dcc69e80 100644
--- a/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java
+++ b/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java
@@ -253,18 +253,26 @@ private MessageBuffer readCastBuffer(int length)
                 throw new MessageInsufficientBufferException();
             }
 
-            // TODO this doesn't work if MessageBuffer is allocated by newDirectBuffer.
-            //      add copy method to MessageBuffer to solve this issue.
-            castBuffer.putBytes(0, buffer.array(), buffer.arrayOffset() + position, remaining);
-            castBuffer.putBytes(remaining, next.array(), next.arrayOffset(), length - remaining);
-
             totalReadBytes += buffer.size();
 
-            buffer = next;
-            position = length - remaining;
-            readCastBufferPosition = 0;
+            if (remaining > 0) {
+                // TODO this doesn't work if MessageBuffer is allocated by newDirectBuffer.
+                //      add copy method to MessageBuffer to solve this issue.
+                castBuffer.putBytes(0, buffer.array(), buffer.arrayOffset() + position, remaining);
+                castBuffer.putBytes(remaining, next.array(), next.arrayOffset(), length - remaining);
+
+                buffer = next;
+                position = length - remaining;
+                readCastBufferPosition = 0;
 
-            return castBuffer;
+                return castBuffer;
+            }
+            else {
+                buffer = next;
+                position = length;
+                readCastBufferPosition = 0;
+                return buffer;
+            }
         }
     }
 
diff --git a/msgpack-core/src/main/java/org/msgpack/core/buffer/InputStreamBufferInput.java b/msgpack-core/src/main/java/org/msgpack/core/buffer/InputStreamBufferInput.java
index ad8aa462f..d605fec3a 100644
--- a/msgpack-core/src/main/java/org/msgpack/core/buffer/InputStreamBufferInput.java
+++ b/msgpack-core/src/main/java/org/msgpack/core/buffer/InputStreamBufferInput.java
@@ -76,7 +76,7 @@ public MessageBuffer next()
         if (readLen == -1) {
             return null;
         }
-        return MessageBuffer.wrap(buffer).slice(0, readLen);
+        return MessageBuffer.wrap(buffer, 0, readLen);
     }
 
     @Override

From 194bd8ef143c6ee9d14f2d8316bfaf79b6d6b3ab Mon Sep 17 00:00:00 2001
From: Sadayuki Furuhashi 
Date: Sun, 27 Dec 2015 13:14:25 +0900
Subject: [PATCH 176/234] Gave up repeatable deserialization

Adding support for repeatable to castBuffer seems hard without
performance impact. For now, here removes repeatable read support.
---
 .../org/msgpack/core/MessageUnpacker.java     | 180 ++++--------------
 1 file changed, 38 insertions(+), 142 deletions(-)

diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java b/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java
index 4dcc69e80..ab7b3e496 100644
--- a/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java
+++ b/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java
@@ -118,11 +118,6 @@ public class MessageUnpacker
      */
     private StringBuilder decodeStringBuffer;
 
-    /**
-     * For decoding String in unpackString.
-     */
-    private int readingRawRemaining = 0;
-
     /**
      * For decoding String in unpackString.
      */
@@ -196,7 +191,6 @@ public MessageBufferInput reset(MessageBufferInput in)
         this.buffer = EMPTY_BUFFER;
         this.position = 0;
         this.totalReadBytes = 0;
-        this.readingRawRemaining = 0;
         // No need to initialize the already allocated string decoder here since we can reuse it.
 
         return old;
@@ -207,24 +201,6 @@ public long getTotalReadBytes()
         return totalReadBytes + position;
     }
 
-    private byte getHeadByte()
-            throws IOException
-    {
-        byte b = headByte;
-        if (b == HEAD_BYTE_REQUIRED) {
-            b = headByte = readByte();
-            if (b == HEAD_BYTE_REQUIRED) {
-                throw new MessageNeverUsedFormatException("Encountered 0xC1 \"NEVER_USED\" byte");
-            }
-        }
-        return b;
-    }
-
-    private void resetHeadByte()
-    {
-        headByte = HEAD_BYTE_REQUIRED;
-    }
-
     private void nextBuffer()
             throws IOException
     {
@@ -291,7 +267,7 @@ private static int utf8MultibyteCharacterSize(byte firstByte)
     public boolean hasNext()
             throws IOException
     {
-        if (buffer.size() <= position) {
+        while (buffer.size() <= position) {
             MessageBuffer next = in.next();
             if (next == null) {
                 return false;
@@ -316,13 +292,12 @@ public boolean hasNext()
     public MessageFormat getNextFormat()
             throws IOException
     {
-        try {
-            byte b = getHeadByte();
-            return MessageFormat.valueOf(b);
-        }
-        catch (MessageNeverUsedFormatException ex) {
-            return MessageFormat.NEVER_USED;
+        // makes sure that buffer has at leat 1 byte
+        if (!hasNext()) {
+            throw new MessageInsufficientBufferException();
         }
+        byte b = buffer.getByte(position);
+        return MessageFormat.valueOf(b);
     }
 
     /**
@@ -395,9 +370,8 @@ public void skipValue()
     {
         int remainingValues = 1;
         while (remainingValues > 0) {
-            byte b = getHeadByte();
+            byte b = readByte();
             MessageFormat f = MessageFormat.valueOf(b);
-            resetHeadByte();
             switch (f) {
                 case POSFIXINT:
                 case NEGFIXINT:
@@ -643,9 +617,8 @@ public Variable unpackValue(Variable var)
     public void unpackNil()
             throws IOException
     {
-        byte b = getHeadByte();
+        byte b = readByte();
         if (b == Code.NIL) {
-            resetHeadByte();
             return;
         }
         throw unexpected("Nil", b);
@@ -654,13 +627,11 @@ public void unpackNil()
     public boolean unpackBoolean()
             throws IOException
     {
-        byte b = getHeadByte();
+        byte b = readByte();
         if (b == Code.FALSE) {
-            resetHeadByte();
             return false;
         }
         else if (b == Code.TRUE) {
-            resetHeadByte();
             return true;
         }
         throw unexpected("boolean", b);
@@ -669,61 +640,52 @@ else if (b == Code.TRUE) {
     public byte unpackByte()
             throws IOException
     {
-        byte b = getHeadByte();
+        byte b = readByte();
         if (Code.isFixInt(b)) {
-            resetHeadByte();
             return b;
         }
         switch (b) {
             case Code.UINT8: // unsigned int 8
                 byte u8 = readByte();
-                resetHeadByte();
                 if (u8 < (byte) 0) {
                     throw overflowU8(u8);
                 }
                 return u8;
             case Code.UINT16: // unsigned int 16
                 short u16 = readShort();
-                resetHeadByte();
                 if (u16 < 0 || u16 > Byte.MAX_VALUE) {
                     throw overflowU16(u16);
                 }
                 return (byte) u16;
             case Code.UINT32: // unsigned int 32
                 int u32 = readInt();
-                resetHeadByte();
                 if (u32 < 0 || u32 > Byte.MAX_VALUE) {
                     throw overflowU32(u32);
                 }
                 return (byte) u32;
             case Code.UINT64: // unsigned int 64
                 long u64 = readLong();
-                resetHeadByte();
                 if (u64 < 0L || u64 > Byte.MAX_VALUE) {
                     throw overflowU64(u64);
                 }
                 return (byte) u64;
             case Code.INT8: // signed int 8
                 byte i8 = readByte();
-                resetHeadByte();
                 return i8;
             case Code.INT16: // signed int 16
                 short i16 = readShort();
-                resetHeadByte();
                 if (i16 < Byte.MIN_VALUE || i16 > Byte.MAX_VALUE) {
                     throw overflowI16(i16);
                 }
                 return (byte) i16;
             case Code.INT32: // signed int 32
                 int i32 = readInt();
-                resetHeadByte();
                 if (i32 < Byte.MIN_VALUE || i32 > Byte.MAX_VALUE) {
                     throw overflowI32(i32);
                 }
                 return (byte) i32;
             case Code.INT64: // signed int 64
                 long i64 = readLong();
-                resetHeadByte();
                 if (i64 < Byte.MIN_VALUE || i64 > Byte.MAX_VALUE) {
                     throw overflowI64(i64);
                 }
@@ -735,32 +697,27 @@ public byte unpackByte()
     public short unpackShort()
             throws IOException
     {
-        byte b = getHeadByte();
+        byte b = readByte();
         if (Code.isFixInt(b)) {
-            resetHeadByte();
             return (short) b;
         }
         switch (b) {
             case Code.UINT8: // unsigned int 8
                 byte u8 = readByte();
-                resetHeadByte();
                 return (short) (u8 & 0xff);
             case Code.UINT16: // unsigned int 16
                 short u16 = readShort();
-                resetHeadByte();
                 if (u16 < (short) 0) {
                     throw overflowU16(u16);
                 }
                 return u16;
             case Code.UINT32: // unsigned int 32
                 int u32 = readInt();
-                resetHeadByte();
                 if (u32 < 0 || u32 > Short.MAX_VALUE) {
                     throw overflowU32(u32);
                 }
                 return (short) u32;
             case Code.UINT64: // unsigned int 64
-                resetHeadByte();
                 long u64 = readLong();
                 if (u64 < 0L || u64 > Short.MAX_VALUE) {
                     throw overflowU64(u64);
@@ -768,22 +725,18 @@ public short unpackShort()
                 return (short) u64;
             case Code.INT8: // signed int 8
                 byte i8 = readByte();
-                resetHeadByte();
                 return (short) i8;
             case Code.INT16: // signed int 16
                 short i16 = readShort();
-                resetHeadByte();
                 return i16;
             case Code.INT32: // signed int 32
                 int i32 = readInt();
-                resetHeadByte();
                 if (i32 < Short.MIN_VALUE || i32 > Short.MAX_VALUE) {
                     throw overflowI32(i32);
                 }
                 return (short) i32;
             case Code.INT64: // signed int 64
                 long i64 = readLong();
-                resetHeadByte();
                 if (i64 < Short.MIN_VALUE || i64 > Short.MAX_VALUE) {
                     throw overflowI64(i64);
                 }
@@ -795,49 +748,40 @@ public short unpackShort()
     public int unpackInt()
             throws IOException
     {
-        byte b = getHeadByte();
+        byte b = readByte();
         if (Code.isFixInt(b)) {
-            resetHeadByte();
             return (int) b;
         }
         switch (b) {
             case Code.UINT8: // unsigned int 8
                 byte u8 = readByte();
-                resetHeadByte();
                 return u8 & 0xff;
             case Code.UINT16: // unsigned int 16
                 short u16 = readShort();
-                resetHeadByte();
                 return u16 & 0xffff;
             case Code.UINT32: // unsigned int 32
                 int u32 = readInt();
                 if (u32 < 0) {
                     throw overflowU32(u32);
                 }
-                resetHeadByte();
                 return u32;
             case Code.UINT64: // unsigned int 64
                 long u64 = readLong();
-                resetHeadByte();
                 if (u64 < 0L || u64 > (long) Integer.MAX_VALUE) {
                     throw overflowU64(u64);
                 }
                 return (int) u64;
             case Code.INT8: // signed int 8
                 byte i8 = readByte();
-                resetHeadByte();
                 return i8;
             case Code.INT16: // signed int 16
                 short i16 = readShort();
-                resetHeadByte();
                 return i16;
             case Code.INT32: // signed int 32
                 int i32 = readInt();
-                resetHeadByte();
                 return i32;
             case Code.INT64: // signed int 64
                 long i64 = readLong();
-                resetHeadByte();
                 if (i64 < (long) Integer.MIN_VALUE || i64 > (long) Integer.MAX_VALUE) {
                     throw overflowI64(i64);
                 }
@@ -849,23 +793,19 @@ public int unpackInt()
     public long unpackLong()
             throws IOException
     {
-        byte b = getHeadByte();
+        byte b = readByte();
         if (Code.isFixInt(b)) {
-            resetHeadByte();
             return (long) b;
         }
         switch (b) {
             case Code.UINT8: // unsigned int 8
                 byte u8 = readByte();
-                resetHeadByte();
                 return (long) (u8 & 0xff);
             case Code.UINT16: // unsigned int 16
                 short u16 = readShort();
-                resetHeadByte();
                 return (long) (u16 & 0xffff);
             case Code.UINT32: // unsigned int 32
                 int u32 = readInt();
-                resetHeadByte();
                 if (u32 < 0) {
                     return (long) (u32 & 0x7fffffff) + 0x80000000L;
                 }
@@ -874,26 +814,21 @@ public long unpackLong()
                 }
             case Code.UINT64: // unsigned int 64
                 long u64 = readLong();
-                resetHeadByte();
                 if (u64 < 0L) {
                     throw overflowU64(u64);
                 }
                 return u64;
             case Code.INT8: // signed int 8
                 byte i8 = readByte();
-                resetHeadByte();
                 return (long) i8;
             case Code.INT16: // signed int 16
                 short i16 = readShort();
-                resetHeadByte();
                 return (long) i16;
             case Code.INT32: // signed int 32
                 int i32 = readInt();
-                resetHeadByte();
                 return (long) i32;
             case Code.INT64: // signed int 64
                 long i64 = readLong();
-                resetHeadByte();
                 return i64;
         }
         throw unexpected("Integer", b);
@@ -902,23 +837,19 @@ public long unpackLong()
     public BigInteger unpackBigInteger()
             throws IOException
     {
-        byte b = getHeadByte();
+        byte b = readByte();
         if (Code.isFixInt(b)) {
-            resetHeadByte();
             return BigInteger.valueOf((long) b);
         }
         switch (b) {
             case Code.UINT8: // unsigned int 8
                 byte u8 = readByte();
-                resetHeadByte();
                 return BigInteger.valueOf((long) (u8 & 0xff));
             case Code.UINT16: // unsigned int 16
                 short u16 = readShort();
-                resetHeadByte();
                 return BigInteger.valueOf((long) (u16 & 0xffff));
             case Code.UINT32: // unsigned int 32
                 int u32 = readInt();
-                resetHeadByte();
                 if (u32 < 0) {
                     return BigInteger.valueOf((long) (u32 & 0x7fffffff) + 0x80000000L);
                 }
@@ -927,7 +858,6 @@ public BigInteger unpackBigInteger()
                 }
             case Code.UINT64: // unsigned int 64
                 long u64 = readLong();
-                resetHeadByte();
                 if (u64 < 0L) {
                     BigInteger bi = BigInteger.valueOf(u64 + Long.MAX_VALUE + 1L).setBit(63);
                     return bi;
@@ -937,19 +867,15 @@ public BigInteger unpackBigInteger()
                 }
             case Code.INT8: // signed int 8
                 byte i8 = readByte();
-                resetHeadByte();
                 return BigInteger.valueOf((long) i8);
             case Code.INT16: // signed int 16
                 short i16 = readShort();
-                resetHeadByte();
                 return BigInteger.valueOf((long) i16);
             case Code.INT32: // signed int 32
                 int i32 = readInt();
-                resetHeadByte();
                 return BigInteger.valueOf((long) i32);
             case Code.INT64: // signed int 64
                 long i64 = readLong();
-                resetHeadByte();
                 return BigInteger.valueOf(i64);
         }
         throw unexpected("Integer", b);
@@ -958,15 +884,13 @@ public BigInteger unpackBigInteger()
     public float unpackFloat()
             throws IOException
     {
-        byte b = getHeadByte();
+        byte b = readByte();
         switch (b) {
             case Code.FLOAT32: // float
                 float fv = readFloat();
-                resetHeadByte();
                 return fv;
             case Code.FLOAT64: // double
                 double dv = readDouble();
-                resetHeadByte();
                 return (float) dv;
         }
         throw unexpected("Float", b);
@@ -975,15 +899,13 @@ public float unpackFloat()
     public double unpackDouble()
             throws IOException
     {
-        byte b = getHeadByte();
+        byte b = readByte();
         switch (b) {
             case Code.FLOAT32: // float
                 float fv = readFloat();
-                resetHeadByte();
                 return (double) fv;
             case Code.FLOAT64: // double
                 double dv = readDouble();
-                resetHeadByte();
                 return dv;
         }
         throw unexpected("Float", b);
@@ -1005,35 +927,29 @@ private void resetDecoder()
         decodeStringBuffer = new StringBuilder();
     }
 
-    /**
-     * This method is not repeatable.
-     */
     public String unpackString()
             throws IOException
     {
-        if (readingRawRemaining == 0) {
-            int len = unpackRawStringHeader();
-            if (len == 0) {
-                return EMPTY_STRING;
-            }
-            if (len > stringSizeLimit) {
-                throw new MessageSizeException(String.format("cannot unpack a String of size larger than %,d: %,d", stringSizeLimit, len), len);
-            }
-            if (buffer.size() - position >= len) {
-                return decodeStringFastPath(len);
-            }
-            readingRawRemaining = len;
-            resetDecoder();
+        int len = unpackRawStringHeader();
+        if (len == 0) {
+            return EMPTY_STRING;
+        }
+        if (len > stringSizeLimit) {
+            throw new MessageSizeException(String.format("cannot unpack a String of size larger than %,d: %,d", stringSizeLimit, len), len);
+        }
+        if (buffer.size() - position >= len) {
+            return decodeStringFastPath(len);
         }
 
-        assert (decoder != null);
+        resetDecoder();
 
         try {
-            while (readingRawRemaining > 0) {
+            int rawRemaining = len;
+            while (rawRemaining > 0) {
                 int bufferRemaining = buffer.size() - position;
-                if (bufferRemaining >= readingRawRemaining) {
-                    decodeStringBuffer.append(decodeStringFastPath(readingRawRemaining));
-                    readingRawRemaining = 0;
+                if (bufferRemaining >= rawRemaining) {
+                    decodeStringBuffer.append(decodeStringFastPath(rawRemaining));
+                    rawRemaining = 0;
                     break;
                 }
                 else if (bufferRemaining == 0) {
@@ -1047,7 +963,7 @@ else if (bufferRemaining == 0) {
                     CoderResult cr = decoder.decode(bb, decodeBuffer, false);
                     int readLen = bb.position() - bbStartPosition;
                     position += readLen;
-                    readingRawRemaining -= readLen;
+                    rawRemaining -= readLen;
                     decodeStringBuffer.append(decodeBuffer.flip());
 
                     if (cr.isError()) {
@@ -1090,7 +1006,7 @@ else if (bufferRemaining == 0) {
                                 throw new MessageFormatException("Unexpected UTF-8 multibyte sequence", ex);
                             }
                         }
-                        readingRawRemaining -= multiByteBuffer.limit();
+                        rawRemaining -= multiByteBuffer.limit();
                         decodeStringBuffer.append(decodeBuffer.flip());
                     }
                 }
@@ -1139,20 +1055,17 @@ private String decodeStringFastPath(int length)
     public int unpackArrayHeader()
             throws IOException
     {
-        byte b = getHeadByte();
+        byte b = readByte();
         if (Code.isFixedArray(b)) { // fixarray
-            resetHeadByte();
             return b & 0x0f;
         }
         switch (b) {
             case Code.ARRAY16: { // array 16
                 int len = readNextLength16();
-                resetHeadByte();
                 return len;
             }
             case Code.ARRAY32: { // array 32
                 int len = readNextLength32();
-                resetHeadByte();
                 return len;
             }
         }
@@ -1162,20 +1075,17 @@ public int unpackArrayHeader()
     public int unpackMapHeader()
             throws IOException
     {
-        byte b = getHeadByte();
+        byte b = readByte();
         if (Code.isFixedMap(b)) { // fixmap
-            resetHeadByte();
             return b & 0x0f;
         }
         switch (b) {
             case Code.MAP16: { // map 16
                 int len = readNextLength16();
-                resetHeadByte();
                 return len;
             }
             case Code.MAP32: { // map 32
                 int len = readNextLength32();
-                resetHeadByte();
                 return len;
             }
         }
@@ -1185,36 +1095,30 @@ public int unpackMapHeader()
     public ExtensionTypeHeader unpackExtensionTypeHeader()
             throws IOException
     {
-        byte b = getHeadByte();
+        byte b = readByte();
         switch (b) {
             case Code.FIXEXT1: {
                 byte type = readByte();
-                resetHeadByte();
                 return new ExtensionTypeHeader(type, 1);
             }
             case Code.FIXEXT2: {
                 byte type = readByte();
-                resetHeadByte();
                 return new ExtensionTypeHeader(type, 2);
             }
             case Code.FIXEXT4: {
                 byte type = readByte();
-                resetHeadByte();
                 return new ExtensionTypeHeader(type, 4);
             }
             case Code.FIXEXT8: {
                 byte type = readByte();
-                resetHeadByte();
                 return new ExtensionTypeHeader(type, 8);
             }
             case Code.FIXEXT16: {
                 byte type = readByte();
-                resetHeadByte();
                 return new ExtensionTypeHeader(type, 16);
             }
             case Code.EXT8: {
                 MessageBuffer castBuffer = readCastBuffer(2);
-                resetHeadByte();
                 int u8 = castBuffer.getByte(readCastBufferPosition);
                 int length = u8 & 0xff;
                 byte type = castBuffer.getByte(readCastBufferPosition + 1);
@@ -1222,7 +1126,6 @@ public ExtensionTypeHeader unpackExtensionTypeHeader()
             }
             case Code.EXT16: {
                 MessageBuffer castBuffer = readCastBuffer(3);
-                resetHeadByte();
                 int u16 = castBuffer.getShort(readCastBufferPosition);
                 int length = u16 & 0xffff;
                 byte type = castBuffer.getByte(readCastBufferPosition + 2);
@@ -1230,7 +1133,6 @@ public ExtensionTypeHeader unpackExtensionTypeHeader()
             }
             case Code.EXT32: {
                 MessageBuffer castBuffer = readCastBuffer(5);
-                resetHeadByte();
                 int u32 = castBuffer.getInt(readCastBufferPosition);
                 if (u32 < 0) {
                     throw overflowU32Size(u32);
@@ -1277,21 +1179,18 @@ private int tryReadBinaryHeader(byte b)
     public int unpackRawStringHeader()
             throws IOException
     {
-        byte b = getHeadByte();
+        byte b = readByte();
         if (Code.isFixedRaw(b)) { // FixRaw
-            resetHeadByte();
             return b & 0x1f;
         }
         int len = tryReadStringHeader(b);
         if (len >= 0) {
-            resetHeadByte();
             return len;
         }
 
         if (allowBinaryAsString) {
             len = tryReadBinaryHeader(b);
             if (len >= 0) {
-                resetHeadByte();
                 return len;
             }
         }
@@ -1301,21 +1200,18 @@ public int unpackRawStringHeader()
     public int unpackBinaryHeader()
             throws IOException
     {
-        byte b = getHeadByte();
+        byte b = readByte();
         if (Code.isFixedRaw(b)) { // FixRaw
-            resetHeadByte();
             return b & 0x1f;
         }
         int len = tryReadBinaryHeader(b);
         if (len >= 0) {
-            resetHeadByte();
             return len;
         }
 
         if (allowStringAsBinary) {
             len = tryReadStringHeader(b);
             if (len >= 0) {
-                resetHeadByte();
                 return len;
             }
         }

From 79c998044f986c1067d6aa1bde42fc74e5fea303 Mon Sep 17 00:00:00 2001
From: Mitsunori Komatsu 
Date: Sun, 27 Dec 2015 17:21:52 +0900
Subject: [PATCH 177/234] Test various lengths of String

---
 ...essagePackDataformatPojoBenchmarkTest.java | 19 ++++++++++++-------
 1 file changed, 12 insertions(+), 7 deletions(-)

diff --git a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/benchmark/MessagePackDataformatPojoBenchmarkTest.java b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/benchmark/MessagePackDataformatPojoBenchmarkTest.java
index de2118508..84dfde2fc 100644
--- a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/benchmark/MessagePackDataformatPojoBenchmarkTest.java
+++ b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/benchmark/MessagePackDataformatPojoBenchmarkTest.java
@@ -32,8 +32,9 @@
 
 public class MessagePackDataformatPojoBenchmarkTest
 {
-    private static final int LOOP_MAX = 600;
-    private static final int LOOP_FACTOR = 40;
+    private static final int LOOP_MAX = 200;
+    private static final int LOOP_FACTOR_SER = 40;
+    private static final int LOOP_FACTOR_DESER = 200;
     private static final int COUNT = 6;
     private static final int WARMUP_COUNT = 4;
     private static final List pojos = new ArrayList(LOOP_MAX);
@@ -52,7 +53,11 @@ public class MessagePackDataformatPojoBenchmarkTest
             pojo.l = i;
             pojo.f = Float.valueOf(i);
             pojo.d = Double.valueOf(i);
-            pojo.setS(String.valueOf(i));
+            StringBuilder sb = new StringBuilder();
+            for (int sbi = 0; sbi < i * 40; sbi++) {
+                sb.append("x");
+            }
+            pojo.setS(sb.toString());
             pojo.bool = i % 2 == 0;
             pojo.bi = BigInteger.valueOf(i);
             switch (i % 4) {
@@ -117,7 +122,7 @@ public void testBenchmark()
             public void run()
                     throws Exception
             {
-                for (int j = 0; j < LOOP_FACTOR; j++) {
+                for (int j = 0; j < LOOP_FACTOR_SER; j++) {
                     for (int i = 0; i < LOOP_MAX; i++) {
                         origObjectMapper.writeValue(outputStreamJackson, pojos.get(i));
                     }
@@ -130,7 +135,7 @@ public void run()
             public void run()
                     throws Exception
             {
-                for (int j = 0; j < LOOP_FACTOR; j++) {
+                for (int j = 0; j < LOOP_FACTOR_SER; j++) {
                     for (int i = 0; i < LOOP_MAX; i++) {
                         msgpackObjectMapper.writeValue(outputStreamMsgpack, pojos.get(i));
                     }
@@ -143,7 +148,7 @@ public void run()
             public void run()
                     throws Exception
             {
-                for (int j = 0; j < LOOP_FACTOR; j++) {
+                for (int j = 0; j < LOOP_FACTOR_DESER; j++) {
                     for (int i = 0; i < LOOP_MAX; i++) {
                         origObjectMapper.readValue(pojosSerWithOrig.get(i), NormalPojo.class);
                     }
@@ -156,7 +161,7 @@ public void run()
             public void run()
                     throws Exception
             {
-                for (int j = 0; j < LOOP_FACTOR; j++) {
+                for (int j = 0; j < LOOP_FACTOR_DESER; j++) {
                     for (int i = 0; i < LOOP_MAX; i++) {
                         msgpackObjectMapper.readValue(pojosSerWithMsgPack.get(i), NormalPojo.class);
                     }

From c6054b8c5497ae09573522a5f3e54e01e23f3293 Mon Sep 17 00:00:00 2001
From: Mitsunori Komatsu 
Date: Sun, 27 Dec 2015 17:35:23 +0900
Subject: [PATCH 178/234] Minor refactoring

---
 ...essagePackDataformatPojoBenchmarkTest.java | 25 ++++++++-----------
 1 file changed, 10 insertions(+), 15 deletions(-)

diff --git a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/benchmark/MessagePackDataformatPojoBenchmarkTest.java b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/benchmark/MessagePackDataformatPojoBenchmarkTest.java
index 84dfde2fc..179b09891 100644
--- a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/benchmark/MessagePackDataformatPojoBenchmarkTest.java
+++ b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/benchmark/MessagePackDataformatPojoBenchmarkTest.java
@@ -37,15 +37,16 @@ public class MessagePackDataformatPojoBenchmarkTest
     private static final int LOOP_FACTOR_DESER = 200;
     private static final int COUNT = 6;
     private static final int WARMUP_COUNT = 4;
-    private static final List pojos = new ArrayList(LOOP_MAX);
-    private static final List pojosSerWithOrig = new ArrayList(LOOP_MAX);
-    private static final List pojosSerWithMsgPack = new ArrayList(LOOP_MAX);
+    private final List pojos = new ArrayList(LOOP_MAX);
+    private final List pojosSerWithOrig = new ArrayList(LOOP_MAX);
+    private final List pojosSerWithMsgPack = new ArrayList(LOOP_MAX);
     private final ObjectMapper origObjectMapper = new ObjectMapper();
     private final ObjectMapper msgpackObjectMapper = new ObjectMapper(new MessagePackFactory());
 
-    static {
-        final ObjectMapper origObjectMapper = new ObjectMapper();
-        final ObjectMapper msgpackObjectMapper = new ObjectMapper(new MessagePackFactory());
+    public MessagePackDataformatPojoBenchmarkTest()
+    {
+        origObjectMapper.configure(JsonGenerator.Feature.AUTO_CLOSE_TARGET, false);
+        msgpackObjectMapper.configure(JsonGenerator.Feature.AUTO_CLOSE_TARGET, false);
 
         for (int i = 0; i < LOOP_MAX; i++) {
             NormalPojo pojo = new NormalPojo();
@@ -54,7 +55,7 @@ public class MessagePackDataformatPojoBenchmarkTest
             pojo.f = Float.valueOf(i);
             pojo.d = Double.valueOf(i);
             StringBuilder sb = new StringBuilder();
-            for (int sbi = 0; sbi < i * 40; sbi++) {
+            for (int sbi = 0; sbi < i * 50; sbi++) {
                 sb.append("x");
             }
             pojo.setS(sb.toString());
@@ -83,7 +84,7 @@ public class MessagePackDataformatPojoBenchmarkTest
                 pojosSerWithOrig.add(origObjectMapper.writeValueAsBytes(pojos.get(i)));
             }
             catch (JsonProcessingException e) {
-                e.printStackTrace();
+                throw new RuntimeException("Failed to create test data");
             }
         }
 
@@ -92,17 +93,11 @@ public class MessagePackDataformatPojoBenchmarkTest
                 pojosSerWithMsgPack.add(msgpackObjectMapper.writeValueAsBytes(pojos.get(i)));
             }
             catch (JsonProcessingException e) {
-                e.printStackTrace();
+                throw new RuntimeException("Failed to create test data");
             }
         }
     }
 
-    public MessagePackDataformatPojoBenchmarkTest()
-    {
-        origObjectMapper.configure(JsonGenerator.Feature.AUTO_CLOSE_TARGET, false);
-        msgpackObjectMapper.configure(JsonGenerator.Feature.AUTO_CLOSE_TARGET, false);
-    }
-
     @Test
     public void testBenchmark()
             throws Exception

From 10d132a2d5d94c5f7e99b18b607dd2a97e31ec5d Mon Sep 17 00:00:00 2001
From: Sadayuki Furuhashi 
Date: Mon, 21 Dec 2015 21:00:22 +0900
Subject: [PATCH 179/234] optimized unpacker buffer

---
 .../MessageInsufficientBufferException.java   |  40 +
 .../core/MessageNeverUsedFormatException.java |  38 +
 .../org/msgpack/core/MessageUnpacker.java     | 808 ++++++++++--------
 .../msgpack/core/buffer/ArrayBufferInput.java |   5 +
 .../msgpack/core/buffer/ByteBufferInput.java  |   5 +
 .../core/buffer/ChannelBufferInput.java       |   5 +
 .../core/buffer/InputStreamBufferInput.java   |   5 +
 .../msgpack/core/buffer/MessageBuffer.java    |   5 +
 .../core/buffer/MessageBufferInput.java       |   7 +-
 .../core/buffer/MessageBufferReader.java      | 122 +++
 .../org/msgpack/core/MessagePackTest.scala    |   2 +-
 .../msgpack/core/MessageUnpackerTest.scala    |   2 +
 .../msgpack/core/buffer/ByteStringTest.scala  |   2 +
 13 files changed, 689 insertions(+), 357 deletions(-)
 create mode 100644 msgpack-core/src/main/java/org/msgpack/core/MessageInsufficientBufferException.java
 create mode 100644 msgpack-core/src/main/java/org/msgpack/core/MessageNeverUsedFormatException.java
 create mode 100644 msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferReader.java

diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessageInsufficientBufferException.java b/msgpack-core/src/main/java/org/msgpack/core/MessageInsufficientBufferException.java
new file mode 100644
index 000000000..838dc77ab
--- /dev/null
+++ b/msgpack-core/src/main/java/org/msgpack/core/MessageInsufficientBufferException.java
@@ -0,0 +1,40 @@
+//
+// MessagePack for Java
+//
+//    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.core;
+
+public class MessageInsufficientBufferException
+        extends MessagePackException
+{
+    public MessageInsufficientBufferException()
+    {
+        super();
+    }
+
+    public MessageInsufficientBufferException(String message)
+    {
+        super(message);
+    }
+
+    public MessageInsufficientBufferException(Throwable cause)
+    {
+        super(cause);
+    }
+
+    public MessageInsufficientBufferException(String message, Throwable cause)
+    {
+        super(message, cause);
+    }
+}
diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessageNeverUsedFormatException.java b/msgpack-core/src/main/java/org/msgpack/core/MessageNeverUsedFormatException.java
new file mode 100644
index 000000000..726ffb497
--- /dev/null
+++ b/msgpack-core/src/main/java/org/msgpack/core/MessageNeverUsedFormatException.java
@@ -0,0 +1,38 @@
+//
+// MessagePack for Java
+//
+//    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.core;
+
+/**
+ * Thrown when the input message pack format is invalid
+ */
+public class MessageNeverUsedFormatException
+        extends MessageFormatException
+{
+    public MessageNeverUsedFormatException(Throwable e)
+    {
+        super(e);
+    }
+
+    public MessageNeverUsedFormatException(String message)
+    {
+        super(message);
+    }
+
+    public MessageNeverUsedFormatException(String message, Throwable cause)
+    {
+        super(message, cause);
+    }
+}
diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java b/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java
index c50d183ee..05babb1ce 100644
--- a/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java
+++ b/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java
@@ -17,6 +17,7 @@
 
 import org.msgpack.core.MessagePack.Code;
 import org.msgpack.core.buffer.MessageBuffer;
+import org.msgpack.core.buffer.MessageBufferReader;
 import org.msgpack.core.buffer.MessageBufferInput;
 import org.msgpack.value.ImmutableValue;
 import org.msgpack.value.Value;
@@ -74,10 +75,14 @@ public class MessageUnpacker
 {
     private static final MessageBuffer EMPTY_BUFFER = MessageBuffer.wrap(new byte[0]);
 
+    private static final byte HEAD_BYTE_REQUIRED = (byte) 0xc1;
+
     private final MessagePack.Config config;
 
     private MessageBufferInput in;
 
+    private byte headByte = HEAD_BYTE_REQUIRED;
+
     /**
      * Points to the current buffer to read
      */
@@ -94,19 +99,24 @@ public class MessageUnpacker
     private long totalReadBytes;
 
     /**
-     * For preserving the next buffer to use
+     * Extra buffer for fixed-length data at the buffer boundary. At most 17-byte buffer (for FIXEXT16) is required.
      */
-    private MessageBuffer secondaryBuffer = null;
+    private final MessageBuffer castBuffer = MessageBuffer.newBuffer(24);
 
     /**
-     * Extra buffer for string data at the buffer boundary. Using 17-byte buffer (for FIXEXT16) is sufficient.
+     * Variable by ensureHeader method. Caller of the method should use this variable to read from returned MessageBuffer.
      */
-    private final MessageBuffer extraBuffer = MessageBuffer.wrap(new byte[24]);
+    private int readCastBufferPosition;
 
     /**
-     * True if no more data is available from the MessageBufferInput
+     * For decoding String in unpackString.
+     */
+    private StringBuilder decodeStringBuffer;
+
+    /**
+     * For decoding String in unpackString.
      */
-    private boolean reachedEOF = false;
+    private int readingRawRemaining = 0;
 
     /**
      * For decoding String in unpackString.
@@ -158,9 +168,9 @@ public MessageBufferInput reset(MessageBufferInput in)
         this.buffer = EMPTY_BUFFER;
         this.position = 0;
         this.totalReadBytes = 0;
-        this.secondaryBuffer = null;
-        this.reachedEOF = false;
+        this.readingRawRemaining = 0;
         // No need to initialize the already allocated string decoder here since we can reuse it.
+
         return old;
     }
 
@@ -169,195 +179,118 @@ public long getTotalReadBytes()
         return totalReadBytes + position;
     }
 
-    private void prepareDecoder()
+    private byte getHeadByte()
+            throws IOException
     {
-        if (decoder == null) {
-            decodeBuffer = CharBuffer.allocate(config.stringDecoderBufferSize);
-            decoder = MessagePack.UTF8.newDecoder()
-                    .onMalformedInput(config.actionOnMalFormedInput)
-                    .onUnmappableCharacter(config.actionOnUnmappableCharacter);
+        byte b = headByte;
+        if (b == HEAD_BYTE_REQUIRED) {
+            b = headByte = readByte();
+            if (b == HEAD_BYTE_REQUIRED) {
+                throw new MessageNeverUsedFormatException("Encountered 0xC1 NEVER_USED byte");
+            }
         }
+        return b;
     }
 
-    /**
-     * Relocate the cursor position so that it points to the real buffer
-     *
-     * @return true if it succeeds to move the cursor, or false if there is no more buffer to read
-     * @throws IOException when failed to retrieve next buffer
-     */
-    private boolean ensureBuffer()
-            throws IOException
+    private void resetHeadByte()
     {
-        while (buffer != null && position >= buffer.size()) {
-            // Fetch the next buffer
-            int bufferSize = buffer.size();
-            position -= bufferSize;
-            totalReadBytes += bufferSize;
-            buffer = takeNextBuffer();
-        }
-        return buffer != null;
+        headByte = HEAD_BYTE_REQUIRED;
     }
 
-    private MessageBuffer takeNextBuffer()
+    private void nextBuffer()
             throws IOException
     {
-        if (reachedEOF) {
-            return null;
-        }
-
-        MessageBuffer nextBuffer = null;
-        if (secondaryBuffer == null) {
-            nextBuffer = in.next();
-        }
-        else {
-            nextBuffer = secondaryBuffer;
-            secondaryBuffer = null;
-        }
-
-        if (nextBuffer == null) {
-            reachedEOF = true;
+        MessageBuffer next = in.next();
+        if (next == null) {
+            throw new MessageInsufficientBufferException();
         }
-        return nextBuffer;
+        totalReadBytes += buffer.size();
+        in.release(buffer);
+        buffer = next;
+        position = 0;
     }
 
-    /**
-     * Ensure that the buffer has the data of at least the specified size.
-     *
-     * @param byteSizeToRead the data size to be read
-     * @return if the buffer can have the data of the specified size returns true, or if the input source reached an EOF, it returns false.
-     * @throws IOException
-     */
-    private boolean ensure(int byteSizeToRead)
+    private MessageBuffer readCastBuffer(int length)
             throws IOException
     {
-        if (byteSizeToRead == 0) {
-            return true;
-        }
-
-        if (!ensureBuffer()) {
-            return false;
-        }
-
-        // The buffer contains the data
-        if (position + byteSizeToRead <= buffer.size()) {
-            // OK
-            return true;
+        int remaining = buffer.size() - position;
+        if (remaining >= length) {
+            readCastBufferPosition = position;
+            position += length;  // here assumes following buffer.getXxx never throws exception
+            return buffer;
         }
+        else {
+            // TODO loop this method until castBuffer is filled
+            MessageBuffer next = in.next();
+            if (next == null) {
+                throw new MessageInsufficientBufferException();
+            }
 
-        // When the data is at the boundary
-        /*
-             |---(byte size to read) ----|
-             -- current buffer --|
-             |--- extra buffer (slice) --|----|
-                                 |-------|---------- secondary buffer (slice) ----------------|
-
-             */
-
-        // If the byte size to read fits within the extra buffer, use the extraBuffer
-        MessageBuffer newBuffer = byteSizeToRead <= extraBuffer.size() ? extraBuffer : MessageBuffer.newBuffer(byteSizeToRead);
-
-        // Copy the remaining buffer contents to the new buffer
-        int firstHalfSize = buffer.size() - position;
-        if (firstHalfSize > 0) {
-            buffer.copyTo(position, newBuffer, 0, firstHalfSize);
-        }
+            // TODO this doesn't work if MessageBuffer is allocated by newDirectBuffer.
+            //      add copy method to MessageBuffer to solve this issue.
+            castBuffer.putBytes(0, buffer.getArray(), buffer.offset() + position, remaining);
+            castBuffer.putBytes(remaining, next.getArray(), next.offset(), length - remaining);
 
-        // Read the last half contents from the next buffers
-        int cursor = firstHalfSize;
-        while (cursor < byteSizeToRead) {
-            secondaryBuffer = takeNextBuffer();
-            if (secondaryBuffer == null) {
-                return false; // No more buffer to read
-            }
+            totalReadBytes += buffer.size();
+            in.release(buffer);
 
-            // Copy the contents from the secondary buffer to the new buffer
-            int copyLen = Math.min(byteSizeToRead - cursor, secondaryBuffer.size());
-            secondaryBuffer.copyTo(0, newBuffer, cursor, copyLen);
+            buffer = next;
+            position = length - remaining;
+            readCastBufferPosition = 0;
 
-            // Truncate the copied part from the secondaryBuffer
-            secondaryBuffer = copyLen == secondaryBuffer.size() ? null : secondaryBuffer.slice(copyLen, secondaryBuffer.size() - copyLen);
-            cursor += copyLen;
+            return castBuffer;
         }
+    }
 
-        // Replace the current buffer with the new buffer
-        totalReadBytes += position;
-        buffer = byteSizeToRead == newBuffer.size() ? newBuffer : newBuffer.slice(0, byteSizeToRead);
-        position = 0;
-
-        return true;
+    private static int utf8MultibyteCharacterSize(byte firstByte)
+    {
+        System.out.println("first byte: "+(firstByte & 0xff));
+        return Integer.numberOfLeadingZeros(~(firstByte & 0xff));
     }
 
     /**
      * Returns true true if this unpacker has more elements.
      * When this returns true, subsequent call to {@link #getNextFormat()} returns an
-     * MessageFormat instance. If false, {@link #getNextFormat()} will throw an EOFException.
+     * MessageFormat instance. If false, next {@link #getNextFormat()} call will throw an MessageInsufficientBufferException.
      *
      * @return true if this unpacker has more elements to read
      */
     public boolean hasNext()
             throws IOException
     {
-        return ensure(1);
+        if (buffer.size() <= position) {
+            MessageBuffer next = in.next();
+            if (next == null) {
+                return false;
+            }
+            totalReadBytes += buffer.size();
+            in.release(buffer);
+            buffer = next;
+            position = 0;
+        }
+        return true;
     }
 
     /**
      * Returns the next MessageFormat type. This method should be called after {@link #hasNext()} returns true.
-     * If {@link #hasNext()} returns false, calling this method throws {@link java.io.EOFException}.
+     * If {@link #hasNext()} returns false, calling this method throws {@link MessageInsufficientBufferException}.
      * 

* This method does not proceed the internal cursor. * * @return the next MessageFormat * @throws IOException when failed to read the input data. - * @throws EOFException when the end of file reached, i.e. {@link #hasNext()} == false. + * @throws MessageInsufficientBufferException when the end of file reached, i.e. {@link #hasNext()} == false. */ public MessageFormat getNextFormat() throws IOException { - byte b = lookAhead(); - return MessageFormat.valueOf(b); - } - - /** - * Look-ahead a byte value at the current cursor position. - * This method does not proceed the cursor. - * - * @return - * @throws IOException - */ - private byte lookAhead() - throws IOException - { - if (ensure(1)) { - return buffer.getByte(position); - } - else { - throw new EOFException(); + try { + byte b = getHeadByte(); + return MessageFormat.valueOf(b); } - } - - /** - * Get the head byte value and proceeds the cursor by 1 - */ - private byte consume() - throws IOException - { - byte b = lookAhead(); - position += 1; - return b; - } - - /** - * Proceeds the cursor by the specified byte length - */ - private void consume(int numBytes) - throws IOException - { - assert (numBytes >= 0); - // If position + numBytes becomes negative, it indicates an overflow from Integer.MAX_VALUE. - if (position + numBytes < 0) { - ensureBuffer(); + catch (MessageNeverUsedFormatException ex) { + return MessageFormat.NEVER_USED; } - position += numBytes; } /** @@ -369,81 +302,55 @@ private void consume(int numBytes) private byte readByte() throws IOException { - if (!ensure(1)) { - throw new EOFException("insufficient data length for reading byte value"); + if (buffer.size() > position) { + byte b = buffer.getByte(position); + position++; + return b; + } + else { + nextBuffer(); + if (buffer.size() > 0) { + byte b = buffer.getByte(0); + position = 1; + return b; + } + return readByte(); } - byte b = buffer.getByte(position); - consume(1); - return b; } private short readShort() throws IOException { - if (!ensure(2)) { - throw new EOFException("insufficient data length for reading short value"); - } - short s = buffer.getShort(position); - consume(2); - return s; + MessageBuffer castBuffer = readCastBuffer(2); + return castBuffer.getShort(readCastBufferPosition); } private int readInt() throws IOException { - if (!ensure(4)) { - throw new EOFException("insufficient data length for reading int value"); - } - int i = buffer.getInt(position); - consume(4); - return i; - } - - private float readFloat() - throws IOException - { - if (!ensure(4)) { - throw new EOFException("insufficient data length for reading float value"); - } - float f = buffer.getFloat(position); - consume(4); - return f; + MessageBuffer castBuffer = readCastBuffer(4); + return castBuffer.getInt(readCastBufferPosition); } private long readLong() throws IOException { - if (!ensure(8)) { - throw new EOFException("insufficient data length for reading long value"); - } - long l = buffer.getLong(position); - consume(8); - return l; + MessageBuffer castBuffer = readCastBuffer(8); + return castBuffer.getLong(readCastBufferPosition); } - private double readDouble() + private float readFloat() throws IOException { - if (!ensure(8)) { - throw new EOFException("insufficient data length for reading double value"); - } - double d = buffer.getDouble(position); - consume(8); - return d; + MessageBuffer castBuffer = readCastBuffer(4); + return castBuffer.getFloat(readCastBufferPosition); } - /** - * Skip reading the specified number of bytes. Use this method only if you know skipping data is safe. - * For simply skipping the next value, use {@link #skipValue()}. - * - * @param numBytes - * @throws IOException - */ - public void skipBytes(int numBytes) + private double readDouble() throws IOException { - checkArgument(numBytes >= 0, "skip length must be >= 0: " + numBytes); - consume(numBytes); + MessageBuffer castBuffer = readCastBuffer(8); + return castBuffer.getDouble(readCastBufferPosition); } /** @@ -456,12 +363,9 @@ public void skipValue() { int remainingValues = 1; while (remainingValues > 0) { - if (reachedEOF) { - throw new EOFException(); - } - - MessageFormat f = getNextFormat(); - byte b = consume(); + byte b = getHeadByte(); + MessageFormat f = MessageFormat.valueOf(b); + resetHeadByte(); switch (f) { case POSFIXINT: case NEGFIXINT: @@ -480,62 +384,62 @@ public void skipValue() } case FIXSTR: { int strLen = b & 0x1f; - consume(strLen); + skipPayload(strLen); break; } case INT8: case UINT8: - consume(1); + skipPayload(1); break; case INT16: case UINT16: - consume(2); + skipPayload(2); break; case INT32: case UINT32: case FLOAT32: - consume(4); + skipPayload(4); break; case INT64: case UINT64: case FLOAT64: - consume(8); + skipPayload(8); break; case BIN8: case STR8: - consume(readNextLength8()); + skipPayload(readNextLength8()); break; case BIN16: case STR16: - consume(readNextLength16()); + skipPayload(readNextLength16()); break; case BIN32: case STR32: - consume(readNextLength32()); + skipPayload(readNextLength32()); break; case FIXEXT1: - consume(2); + skipPayload(2); break; case FIXEXT2: - consume(3); + skipPayload(3); break; case FIXEXT4: - consume(5); + skipPayload(5); break; case FIXEXT8: - consume(9); + skipPayload(9); break; case FIXEXT16: - consume(17); + skipPayload(17); break; case EXT8: - consume(readNextLength8() + 1); + skipPayload(readNextLength8() + 1); break; case EXT16: - consume(readNextLength16() + 1); + skipPayload(readNextLength16() + 1); break; case EXT32: - consume(readNextLength32() + 1); + skipPayload(readNextLength32() + 1); break; case ARRAY16: remainingValues += readNextLength16(); @@ -709,8 +613,9 @@ public Variable unpackValue(Variable var) public void unpackNil() throws IOException { - byte b = consume(); + byte b = getHeadByte(); if (b == Code.NIL) { + resetHeadByte(); return; } throw unexpected("Nil", b); @@ -719,66 +624,76 @@ public void unpackNil() public boolean unpackBoolean() throws IOException { - byte b = consume(); + byte b = getHeadByte(); if (b == Code.FALSE) { + resetHeadByte(); return false; } else if (b == Code.TRUE) { + resetHeadByte(); return true; } - throw unexpected("boolean", b); } public byte unpackByte() throws IOException { - byte b = consume(); + byte b = getHeadByte(); if (Code.isFixInt(b)) { + resetHeadByte(); return b; } switch (b) { case Code.UINT8: // unsigned int 8 byte u8 = readByte(); + resetHeadByte(); if (u8 < (byte) 0) { throw overflowU8(u8); } return u8; case Code.UINT16: // unsigned int 16 short u16 = readShort(); + resetHeadByte(); if (u16 < 0 || u16 > Byte.MAX_VALUE) { throw overflowU16(u16); } return (byte) u16; case Code.UINT32: // unsigned int 32 int u32 = readInt(); + resetHeadByte(); if (u32 < 0 || u32 > Byte.MAX_VALUE) { throw overflowU32(u32); } return (byte) u32; case Code.UINT64: // unsigned int 64 long u64 = readLong(); + resetHeadByte(); if (u64 < 0L || u64 > Byte.MAX_VALUE) { throw overflowU64(u64); } return (byte) u64; case Code.INT8: // signed int 8 byte i8 = readByte(); + resetHeadByte(); return i8; case Code.INT16: // signed int 16 short i16 = readShort(); + resetHeadByte(); if (i16 < Byte.MIN_VALUE || i16 > Byte.MAX_VALUE) { throw overflowI16(i16); } return (byte) i16; case Code.INT32: // signed int 32 int i32 = readInt(); + resetHeadByte(); if (i32 < Byte.MIN_VALUE || i32 > Byte.MAX_VALUE) { throw overflowI32(i32); } return (byte) i32; case Code.INT64: // signed int 64 long i64 = readLong(); + resetHeadByte(); if (i64 < Byte.MIN_VALUE || i64 > Byte.MAX_VALUE) { throw overflowI64(i64); } @@ -790,27 +705,32 @@ public byte unpackByte() public short unpackShort() throws IOException { - byte b = consume(); + byte b = getHeadByte(); if (Code.isFixInt(b)) { + resetHeadByte(); return (short) b; } switch (b) { case Code.UINT8: // unsigned int 8 byte u8 = readByte(); + resetHeadByte(); return (short) (u8 & 0xff); case Code.UINT16: // unsigned int 16 short u16 = readShort(); + resetHeadByte(); if (u16 < (short) 0) { throw overflowU16(u16); } return u16; case Code.UINT32: // unsigned int 32 int u32 = readInt(); + resetHeadByte(); if (u32 < 0 || u32 > Short.MAX_VALUE) { throw overflowU32(u32); } return (short) u32; case Code.UINT64: // unsigned int 64 + resetHeadByte(); long u64 = readLong(); if (u64 < 0L || u64 > Short.MAX_VALUE) { throw overflowU64(u64); @@ -818,18 +738,22 @@ public short unpackShort() return (short) u64; case Code.INT8: // signed int 8 byte i8 = readByte(); + resetHeadByte(); return (short) i8; case Code.INT16: // signed int 16 short i16 = readShort(); + resetHeadByte(); return i16; case Code.INT32: // signed int 32 int i32 = readInt(); + resetHeadByte(); if (i32 < Short.MIN_VALUE || i32 > Short.MAX_VALUE) { throw overflowI32(i32); } return (short) i32; case Code.INT64: // signed int 64 long i64 = readLong(); + resetHeadByte(); if (i64 < Short.MIN_VALUE || i64 > Short.MAX_VALUE) { throw overflowI64(i64); } @@ -841,40 +765,49 @@ public short unpackShort() public int unpackInt() throws IOException { - byte b = consume(); + byte b = getHeadByte(); if (Code.isFixInt(b)) { + resetHeadByte(); return (int) b; } switch (b) { case Code.UINT8: // unsigned int 8 byte u8 = readByte(); + resetHeadByte(); return u8 & 0xff; case Code.UINT16: // unsigned int 16 short u16 = readShort(); + resetHeadByte(); return u16 & 0xffff; case Code.UINT32: // unsigned int 32 int u32 = readInt(); if (u32 < 0) { throw overflowU32(u32); } + resetHeadByte(); return u32; case Code.UINT64: // unsigned int 64 long u64 = readLong(); + resetHeadByte(); if (u64 < 0L || u64 > (long) Integer.MAX_VALUE) { throw overflowU64(u64); } return (int) u64; case Code.INT8: // signed int 8 byte i8 = readByte(); + resetHeadByte(); return i8; case Code.INT16: // signed int 16 short i16 = readShort(); + resetHeadByte(); return i16; case Code.INT32: // signed int 32 int i32 = readInt(); + resetHeadByte(); return i32; case Code.INT64: // signed int 64 long i64 = readLong(); + resetHeadByte(); if (i64 < (long) Integer.MIN_VALUE || i64 > (long) Integer.MAX_VALUE) { throw overflowI64(i64); } @@ -886,19 +819,23 @@ public int unpackInt() public long unpackLong() throws IOException { - byte b = consume(); + byte b = getHeadByte(); if (Code.isFixInt(b)) { + resetHeadByte(); return (long) b; } switch (b) { case Code.UINT8: // unsigned int 8 byte u8 = readByte(); + resetHeadByte(); return (long) (u8 & 0xff); case Code.UINT16: // unsigned int 16 short u16 = readShort(); + resetHeadByte(); return (long) (u16 & 0xffff); case Code.UINT32: // unsigned int 32 int u32 = readInt(); + resetHeadByte(); if (u32 < 0) { return (long) (u32 & 0x7fffffff) + 0x80000000L; } @@ -907,21 +844,26 @@ public long unpackLong() } case Code.UINT64: // unsigned int 64 long u64 = readLong(); + resetHeadByte(); if (u64 < 0L) { throw overflowU64(u64); } return u64; case Code.INT8: // signed int 8 byte i8 = readByte(); + resetHeadByte(); return (long) i8; case Code.INT16: // signed int 16 short i16 = readShort(); + resetHeadByte(); return (long) i16; case Code.INT32: // signed int 32 int i32 = readInt(); + resetHeadByte(); return (long) i32; case Code.INT64: // signed int 64 long i64 = readLong(); + resetHeadByte(); return i64; } throw unexpected("Integer", b); @@ -930,19 +872,23 @@ public long unpackLong() public BigInteger unpackBigInteger() throws IOException { - byte b = consume(); + byte b = getHeadByte(); if (Code.isFixInt(b)) { + resetHeadByte(); return BigInteger.valueOf((long) b); } switch (b) { case Code.UINT8: // unsigned int 8 byte u8 = readByte(); + resetHeadByte(); return BigInteger.valueOf((long) (u8 & 0xff)); case Code.UINT16: // unsigned int 16 short u16 = readShort(); + resetHeadByte(); return BigInteger.valueOf((long) (u16 & 0xffff)); case Code.UINT32: // unsigned int 32 int u32 = readInt(); + resetHeadByte(); if (u32 < 0) { return BigInteger.valueOf((long) (u32 & 0x7fffffff) + 0x80000000L); } @@ -951,6 +897,7 @@ public BigInteger unpackBigInteger() } case Code.UINT64: // unsigned int 64 long u64 = readLong(); + resetHeadByte(); if (u64 < 0L) { BigInteger bi = BigInteger.valueOf(u64 + Long.MAX_VALUE + 1L).setBit(63); return bi; @@ -960,15 +907,19 @@ public BigInteger unpackBigInteger() } case Code.INT8: // signed int 8 byte i8 = readByte(); + resetHeadByte(); return BigInteger.valueOf((long) i8); case Code.INT16: // signed int 16 short i16 = readShort(); + resetHeadByte(); return BigInteger.valueOf((long) i16); case Code.INT32: // signed int 32 int i32 = readInt(); + resetHeadByte(); return BigInteger.valueOf((long) i32); case Code.INT64: // signed int 64 long i64 = readLong(); + resetHeadByte(); return BigInteger.valueOf(i64); } throw unexpected("Integer", b); @@ -977,13 +928,15 @@ public BigInteger unpackBigInteger() public float unpackFloat() throws IOException { - byte b = consume(); + byte b = getHeadByte(); switch (b) { case Code.FLOAT32: // float float fv = readFloat(); + resetHeadByte(); return fv; case Code.FLOAT64: // double double dv = readDouble(); + resetHeadByte(); return (float) dv; } throw unexpected("Float", b); @@ -992,13 +945,15 @@ public float unpackFloat() public double unpackDouble() throws IOException { - byte b = consume(); + byte b = getHeadByte(); switch (b) { case Code.FLOAT32: // float float fv = readFloat(); + resetHeadByte(); return (double) fv; case Code.FLOAT64: // double double dv = readDouble(); + resetHeadByte(); return dv; } throw unexpected("Float", b); @@ -1006,107 +961,191 @@ public double unpackDouble() private static final String EMPTY_STRING = ""; + private void resetDecoder() + { + if (decoder == null) { + decodeBuffer = CharBuffer.allocate(config.stringDecoderBufferSize); + decoder = MessagePack.UTF8.newDecoder() + .onMalformedInput(config.actionOnMalFormedInput) + .onUnmappableCharacter(config.actionOnUnmappableCharacter); + } + else { + decoder.reset(); + } + decodeStringBuffer = new StringBuilder(); + } + + /** + * This method is not repeatable. + */ public String unpackString() throws IOException { - int strLen = unpackRawStringHeader(); - if (strLen > 0) { - if (strLen > config.maxUnpackStringSize) { - throw new MessageSizeException(String.format("cannot unpack a String of size larger than %,d: %,d", config.maxUnpackStringSize, strLen), strLen); + if (readingRawRemaining == 0) { + int len = unpackRawStringHeader(); + if (len == 0) { + return EMPTY_STRING; + } + if (len > config.maxUnpackStringSize) { + throw new MessageSizeException(String.format("cannot unpack a String of size larger than %,d: %,d", config.maxUnpackStringSize, len), len); } + if (buffer.size() - position >= len) { + return decodeStringFastPath(len); + } + readingRawRemaining = len; + resetDecoder(); + } - prepareDecoder(); - assert (decoder != null); + assert (decoder != null); - decoder.reset(); + try { + while (readingRawRemaining > 0) { + int bufferRemaining = buffer.size() - position; + if (bufferRemaining >= readingRawRemaining) { + ByteBuffer bb = buffer.toByteBuffer(position, readingRawRemaining); + int bbStartPosition = bb.position(); + decodeBuffer.clear(); - try { - int cursor = 0; - decodeBuffer.clear(); - StringBuilder sb = new StringBuilder(); - - boolean hasIncompleteMultiBytes = false; - while (cursor < strLen) { - int readLen = Math.min(position < buffer.size() ? buffer.size() - position : buffer.size(), strLen - cursor); - if (hasIncompleteMultiBytes) { - // Prepare enough buffer for decoding multi-bytes character right after running into incomplete one - readLen = Math.min(config.stringDecoderBufferSize, strLen - cursor); + CoderResult cr = decoder.decode(bb, decodeBuffer, true); + int readLen = bb.position() - bbStartPosition; + position += readLen; + readingRawRemaining -= readLen; + decodeStringBuffer.append(decodeBuffer.flip()); + + if (cr.isError()) { + handleCoderError(cr); } - if (!ensure(readLen)) { - throw new EOFException(); + if (cr.isUnderflow() && config.actionOnMalFormedInput == CodingErrorAction.REPORT) { + throw new MalformedInputException(cr.length()); } - hasIncompleteMultiBytes = false; - ByteBuffer bb = buffer.toByteBuffer(position, readLen); - int startPos = bb.position(); - - while (bb.hasRemaining()) { - boolean endOfInput = (cursor + readLen) >= strLen; - CoderResult cr = decoder.decode(bb, decodeBuffer, endOfInput); - - if (endOfInput && cr.isUnderflow()) { - cr = decoder.flush(decodeBuffer); - } - - if (cr.isOverflow()) { - // The output CharBuffer has insufficient space - decoder.reset(); - } - - if (cr.isUnderflow() && bb.hasRemaining()) { - // input buffer doesn't have enough bytes for multi bytes characters - if (config.actionOnMalFormedInput == CodingErrorAction.REPORT) { - throw new MalformedInputException(strLen); + if (cr.isOverflow()) { + // go to next loop + } + else { + break; + } + } + else if (bufferRemaining == 0) { + nextBuffer(); + } + else { + ByteBuffer bb = buffer.toByteBuffer(position, bufferRemaining); + int bbStartPosition = bb.position(); + decodeBuffer.clear(); + + CoderResult cr = decoder.decode(bb, decodeBuffer, false); + int readLen = bb.position() - bbStartPosition; + position += readLen; + readingRawRemaining -= readLen; + decodeStringBuffer.append(decodeBuffer.flip()); + + if (cr.isError()) { + handleCoderError(cr); + } + if (cr.isUnderflow() && readLen < bufferRemaining) { + // handle incomplete multibyte character + int incompleteMultiBytes = utf8MultibyteCharacterSize(buffer.getByte(position)); + ByteBuffer multiByteBuffer = ByteBuffer.allocate(incompleteMultiBytes); + buffer.getBytes(position, buffer.size() - position, multiByteBuffer); + + // read until multiByteBuffer is filled + while (true) { + nextBuffer(); + + int more = multiByteBuffer.remaining(); + if (buffer.size() >= more) { + buffer.getBytes(0, more, multiByteBuffer); + position = more; + break; + } + else { + buffer.getBytes(0, buffer.size(), multiByteBuffer); + position = buffer.size(); } - hasIncompleteMultiBytes = true; - // Proceed the cursor with the length already decoded successfully. - readLen = bb.position() - startPos; } - + multiByteBuffer.position(0); + decodeBuffer.clear(); + cr = decoder.decode(multiByteBuffer, decodeBuffer, false); if (cr.isError()) { - if ((cr.isMalformed() && config.actionOnMalFormedInput == CodingErrorAction.REPORT) || - (cr.isUnmappable() && config.actionOnUnmappableCharacter == CodingErrorAction.REPORT)) { + handleCoderError(cr); + } + if (cr.isUnderflow() || cr.isOverflow()) { + // isOverflow or isOverflow must not happen. if happened, throw exception + try { cr.throwException(); + throw new MessageFormatException("Unexpected UTF-8 multibyte sequence"); + } + catch (Exception ex) { + throw new MessageFormatException("Unexpected UTF-8 multibyte sequence", ex); } } - - decodeBuffer.flip(); - sb.append(decodeBuffer); - - decodeBuffer.clear(); - - if (hasIncompleteMultiBytes) { - break; - } + readingRawRemaining -= multiByteBuffer.limit(); + decodeStringBuffer.append(decodeBuffer.flip()); } - - cursor += readLen; - consume(readLen); } + } + return decodeStringBuffer.toString(); + } + catch (CharacterCodingException e) { + throw new MessageStringCodingException(e); + } + } - return sb.toString(); + private void handleCoderError(CoderResult cr) + throws CharacterCodingException + { + if ((cr.isMalformed() && config.actionOnMalFormedInput == CodingErrorAction.REPORT) || + (cr.isUnmappable() && config.actionOnUnmappableCharacter == CodingErrorAction.REPORT)) { + cr.throwException(); + } + } + + private String decodeStringFastPath(int length) + { + if (config.actionOnMalFormedInput == CodingErrorAction.REPLACE && + config.actionOnUnmappableCharacter == CodingErrorAction.REPLACE && + buffer.hasArray()) { + String s = new String(buffer.getArray(), position, length, MessagePack.UTF8); + position += length; + return s; + } + else { + resetDecoder(); + ByteBuffer bb = buffer.toByteBuffer(); + bb.limit(position + length); + bb.position(position); + CharBuffer cb; + try { + cb = decoder.decode(bb); } catch (CharacterCodingException e) { throw new MessageStringCodingException(e); } - } - else { - return EMPTY_STRING; + position += length; + return cb.toString(); } } public int unpackArrayHeader() throws IOException { - byte b = consume(); + byte b = getHeadByte(); if (Code.isFixedArray(b)) { // fixarray + resetHeadByte(); return b & 0x0f; } switch (b) { - case Code.ARRAY16: // array 16 - return readNextLength16(); - case Code.ARRAY32: // array 32 - return readNextLength32(); + case Code.ARRAY16: { // array 16 + int len = readNextLength16(); + resetHeadByte(); + return len; + } + case Code.ARRAY32: { // array 32 + int len = readNextLength32(); + resetHeadByte(); + return len; + } } throw unexpected("Array", b); } @@ -1114,15 +1153,22 @@ public int unpackArrayHeader() public int unpackMapHeader() throws IOException { - byte b = consume(); + byte b = getHeadByte(); if (Code.isFixedMap(b)) { // fixmap + resetHeadByte(); return b & 0x0f; } switch (b) { - case Code.MAP16: // map 16 - return readNextLength16(); - case Code.MAP32: // map 32 - return readNextLength32(); + case Code.MAP16: { // map 16 + int len = readNextLength16(); + resetHeadByte(); + return len; + } + case Code.MAP32: { // map 32 + int len = readNextLength32(); + resetHeadByte(); + return len; + } } throw unexpected("Map", b); } @@ -1130,31 +1176,58 @@ public int unpackMapHeader() public ExtensionTypeHeader unpackExtensionTypeHeader() throws IOException { - byte b = consume(); + byte b = getHeadByte(); switch (b) { - case Code.FIXEXT1: - return new ExtensionTypeHeader(readByte(), 1); - case Code.FIXEXT2: - return new ExtensionTypeHeader(readByte(), 2); - case Code.FIXEXT4: - return new ExtensionTypeHeader(readByte(), 4); - case Code.FIXEXT8: - return new ExtensionTypeHeader(readByte(), 8); - case Code.FIXEXT16: - return new ExtensionTypeHeader(readByte(), 16); - case Code.EXT8: { - int length = readNextLength8(); + case Code.FIXEXT1: { + byte type = readByte(); + resetHeadByte(); + return new ExtensionTypeHeader(type, 1); + } + case Code.FIXEXT2: { + byte type = readByte(); + resetHeadByte(); + return new ExtensionTypeHeader(type, 2); + } + case Code.FIXEXT4: { + byte type = readByte(); + resetHeadByte(); + return new ExtensionTypeHeader(type, 4); + } + case Code.FIXEXT8: { byte type = readByte(); + resetHeadByte(); + return new ExtensionTypeHeader(type, 8); + } + case Code.FIXEXT16: { + byte type = readByte(); + resetHeadByte(); + return new ExtensionTypeHeader(type, 16); + } + case Code.EXT8: { + MessageBuffer castBuffer = readCastBuffer(2); + resetHeadByte(); + int u8 = castBuffer.getByte(readCastBufferPosition); + int length = u8 & 0xff; + byte type = castBuffer.getByte(readCastBufferPosition + 1); return new ExtensionTypeHeader(type, length); } case Code.EXT16: { - int length = readNextLength16(); - byte type = readByte(); + MessageBuffer castBuffer = readCastBuffer(3); + resetHeadByte(); + int u16 = castBuffer.getShort(readCastBufferPosition); + int length = u16 & 0xffff; + byte type = castBuffer.getByte(readCastBufferPosition + 2); return new ExtensionTypeHeader(type, length); } case Code.EXT32: { - int length = readNextLength32(); - byte type = readByte(); + MessageBuffer castBuffer = readCastBuffer(5); + resetHeadByte(); + int u32 = castBuffer.getInt(readCastBufferPosition); + if (u32 < 0) { + throw overflowU32Size(u32); + } + int length = u32; + byte type = castBuffer.getByte(readCastBufferPosition + 4); return new ExtensionTypeHeader(type, length); } } @@ -1162,7 +1235,7 @@ public ExtensionTypeHeader unpackExtensionTypeHeader() throw unexpected("Ext", b); } - private int readStringHeader(byte b) + private int tryReadStringHeader(byte b) throws IOException { switch (b) { @@ -1177,7 +1250,7 @@ private int readStringHeader(byte b) } } - private int readBinaryHeader(byte b) + private int tryReadBinaryHeader(byte b) throws IOException { switch (b) { @@ -1195,18 +1268,21 @@ private int readBinaryHeader(byte b) public int unpackRawStringHeader() throws IOException { - byte b = consume(); + byte b = getHeadByte(); if (Code.isFixedRaw(b)) { // FixRaw + resetHeadByte(); return b & 0x1f; } - int len = readStringHeader(b); + int len = tryReadStringHeader(b); if (len >= 0) { + resetHeadByte(); return len; } if (config.readBinaryAsString) { - len = readBinaryHeader(b); + len = tryReadBinaryHeader(b); if (len >= 0) { + resetHeadByte(); return len; } } @@ -1216,36 +1292,65 @@ public int unpackRawStringHeader() public int unpackBinaryHeader() throws IOException { - byte b = consume(); + byte b = getHeadByte(); if (Code.isFixedRaw(b)) { // FixRaw + resetHeadByte(); return b & 0x1f; } - int len = readBinaryHeader(b); + int len = tryReadBinaryHeader(b); if (len >= 0) { + resetHeadByte(); return len; } if (config.readStringAsBinary) { - len = readStringHeader(b); + len = tryReadStringHeader(b); if (len >= 0) { + resetHeadByte(); return len; } } throw unexpected("Binary", b); } - // TODO returns a buffer reference to the payload (zero-copy) + /** + * Skip reading the specified number of bytes. Use this method only if you know skipping data is safe. + * For simply skipping the next value, use {@link #skipValue()}. + * + * @param numBytes + * @throws IOException + */ + private void skipPayload(int numBytes) + throws IOException + { + while (true) { + int bufferRemaining = buffer.size() - position; + if (bufferRemaining >= numBytes) { + position += numBytes; + return; + } + else { + position += bufferRemaining; + } + nextBuffer(); + } + } public void readPayload(ByteBuffer dst) throws IOException { - while (dst.remaining() > 0) { - if (!ensureBuffer()) { - throw new EOFException(); + while (true) { + int dstRemaining = dst.remaining(); + int bufferRemaining = buffer.size() - position; + if (bufferRemaining >= dstRemaining) { + buffer.getBytes(position, dstRemaining, dst); + position += dstRemaining; + return; } - int l = Math.min(buffer.size() - position, dst.remaining()); - buffer.getBytes(position, l, dst); - consume(l); + buffer.getBytes(position, bufferRemaining, dst); + position += bufferRemaining; + + nextBuffer(); } } @@ -1274,29 +1379,22 @@ public byte[] readPayload(int length) public void readPayload(byte[] dst, int off, int len) throws IOException { - int writtenLen = 0; - while (writtenLen < len) { - if (!ensureBuffer()) { - throw new EOFException(); - } - int l = Math.min(buffer.size() - position, len - writtenLen); - buffer.getBytes(position, dst, off + writtenLen, l); - consume(l); - writtenLen += l; - } + // TODO optimize + readPayload(ByteBuffer.wrap(dst, off, len)); } public MessageBuffer readPayloadAsReference(int length) throws IOException { - checkArgument(length >= 0); - if (!ensure(length)) { - throw new EOFException(); + int bufferRemaining = buffer.size() - position; + if (bufferRemaining >= length) { + MessageBuffer slice = buffer.slice(position, length); + position += length; + return slice; } - - MessageBuffer ref = buffer.slice(position, length); - position += length; - return ref; + MessageBuffer dst = MessageBuffer.newBuffer(length); + readPayload(dst.getReference()); + return dst; } private int readNextLength8() diff --git a/msgpack-core/src/main/java/org/msgpack/core/buffer/ArrayBufferInput.java b/msgpack-core/src/main/java/org/msgpack/core/buffer/ArrayBufferInput.java index 88fe45942..35f76c14c 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/buffer/ArrayBufferInput.java +++ b/msgpack-core/src/main/java/org/msgpack/core/buffer/ArrayBufferInput.java @@ -87,4 +87,9 @@ public void close() buffer = null; isRead = false; } + + // TODO + public void release(MessageBuffer buffer) + { + } } diff --git a/msgpack-core/src/main/java/org/msgpack/core/buffer/ByteBufferInput.java b/msgpack-core/src/main/java/org/msgpack/core/buffer/ByteBufferInput.java index b9b4304ad..1f60b3fec 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/buffer/ByteBufferInput.java +++ b/msgpack-core/src/main/java/org/msgpack/core/buffer/ByteBufferInput.java @@ -66,4 +66,9 @@ public void close() { // Nothing to do } + + // TODO + public void release(MessageBuffer buffer) + { + } } diff --git a/msgpack-core/src/main/java/org/msgpack/core/buffer/ChannelBufferInput.java b/msgpack-core/src/main/java/org/msgpack/core/buffer/ChannelBufferInput.java index 4b8baeb75..6dd262599 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/buffer/ChannelBufferInput.java +++ b/msgpack-core/src/main/java/org/msgpack/core/buffer/ChannelBufferInput.java @@ -85,4 +85,9 @@ public void close() { channel.close(); } + + // TODO + public void release(MessageBuffer buffer) + { + } } diff --git a/msgpack-core/src/main/java/org/msgpack/core/buffer/InputStreamBufferInput.java b/msgpack-core/src/main/java/org/msgpack/core/buffer/InputStreamBufferInput.java index 81aabd762..b0d42e4a0 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/buffer/InputStreamBufferInput.java +++ b/msgpack-core/src/main/java/org/msgpack/core/buffer/InputStreamBufferInput.java @@ -93,4 +93,9 @@ public void close() { in.close(); } + + // TODO + public void release(MessageBuffer buffer) + { + } } diff --git a/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBuffer.java b/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBuffer.java index 4dd1396f1..46a777af0 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBuffer.java +++ b/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBuffer.java @@ -328,6 +328,11 @@ else if (bb.hasArray()) { this.reference = reference; } + public MessageBufferReader newReader() + { + return new MessageBufferReader(this); + } + /** * byte size of the buffer * diff --git a/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferInput.java b/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferInput.java index 786ce2721..2a92160b2 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferInput.java +++ b/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferInput.java @@ -27,9 +27,14 @@ public interface MessageBufferInput /** * Get a next buffer to read. * - * @return the next MessageBuffer, or null if no more buffer is available. + * @return the next MessageBuffer, or return null if no more buffer is available. * @throws IOException when error occurred when reading the data */ public MessageBuffer next() throws IOException; + + /** + * Release an unused buffer formerly returned by next() method. + */ + public void release(MessageBuffer buffer); } diff --git a/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferReader.java b/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferReader.java new file mode 100644 index 000000000..f9656d22d --- /dev/null +++ b/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferReader.java @@ -0,0 +1,122 @@ +// +// MessagePack for Java +// +// 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.core.buffer; + +public class MessageBufferReader +{ + // TODO add more reader methods for each type + + private MessageBuffer buffer; + private int position; + + MessageBufferReader(MessageBuffer buffer) + { + this.buffer = buffer; + } + + public MessageBuffer buffer() + { + return buffer; + } + + public int position() + { + return position; + } + + public void position(int newPosition) + { + // TODO validation? + this.position = newPosition; + } + + public int remaining() + { + return buffer.size() - position; + } + + public byte getByte() + { + return buffer.getByte(position); + } + + public byte readByte() + { + byte v = buffer.getByte(position); + position += 1; + return v; + } + + public short getShort() + { + return buffer.getShort(position); + } + + public short readShort() + { + short v = buffer.getShort(position); + position += 1; + return v; + } + + public int getInt() + { + return buffer.getInt(position); + } + + public int readInt() + { + int v = buffer.getInt(position); + position += 1; + return v; + } + + public long getLong() + { + return buffer.getLong(position); + } + + public long readLong() + { + long v = buffer.getLong(position); + position += 1; + return v; + } + + public float getFloat() + { + return buffer.getFloat(position); + } + + public float readFloat() + { + float v = buffer.getFloat(position); + position += 1; + return v; + } + + public double getDouble() + { + return buffer.getDouble(position); + } + + public double readDouble() + { + double v = buffer.getDouble(position); + position += 1; + return v; + } +} diff --git a/msgpack-core/src/test/scala/org/msgpack/core/MessagePackTest.scala b/msgpack-core/src/test/scala/org/msgpack/core/MessagePackTest.scala index 62bf8ae82..f903cf88d 100644 --- a/msgpack-core/src/test/scala/org/msgpack/core/MessagePackTest.scala +++ b/msgpack-core/src/test/scala/org/msgpack/core/MessagePackTest.scala @@ -469,4 +469,4 @@ class MessagePackTest extends MessagePackSpec { } } -} \ No newline at end of file +} diff --git a/msgpack-core/src/test/scala/org/msgpack/core/MessageUnpackerTest.scala b/msgpack-core/src/test/scala/org/msgpack/core/MessageUnpackerTest.scala index fc03d5680..9ecf70a21 100644 --- a/msgpack-core/src/test/scala/org/msgpack/core/MessageUnpackerTest.scala +++ b/msgpack-core/src/test/scala/org/msgpack/core/MessageUnpackerTest.scala @@ -261,6 +261,8 @@ class MessageUnpackerTest extends MessagePackSpec { } } + override def release(buffer: MessageBuffer): Unit = {} + override def close(): Unit = {} } diff --git a/msgpack-core/src/test/scala/org/msgpack/core/buffer/ByteStringTest.scala b/msgpack-core/src/test/scala/org/msgpack/core/buffer/ByteStringTest.scala index 362038d95..39526a0ce 100644 --- a/msgpack-core/src/test/scala/org/msgpack/core/buffer/ByteStringTest.scala +++ b/msgpack-core/src/test/scala/org/msgpack/core/buffer/ByteStringTest.scala @@ -39,6 +39,8 @@ class ByteStringTest messageBuffer } + override def release(buffer: MessageBuffer): Unit = {} + override def close(): Unit = {} } From ccac8a76f5ba0007644554068f5815a4f6e31390 Mon Sep 17 00:00:00 2001 From: Sadayuki Furuhashi Date: Tue, 22 Dec 2015 10:39:03 +0900 Subject: [PATCH 180/234] fixed MessageUnpacker.utf8MultibyteCharacterSize --- .../org/msgpack/core/MessageUnpacker.java | 29 +++-- .../msgpack/core/buffer/MessageBuffer.java | 7 +- .../core/buffer/MessageBufferReader.java | 122 ------------------ 3 files changed, 20 insertions(+), 138 deletions(-) delete mode 100644 msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferReader.java diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java b/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java index 05babb1ce..b22c98dfb 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java +++ b/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java @@ -17,7 +17,6 @@ import org.msgpack.core.MessagePack.Code; import org.msgpack.core.buffer.MessageBuffer; -import org.msgpack.core.buffer.MessageBufferReader; import org.msgpack.core.buffer.MessageBufferInput; import org.msgpack.value.ImmutableValue; import org.msgpack.value.Value; @@ -186,7 +185,7 @@ private byte getHeadByte() if (b == HEAD_BYTE_REQUIRED) { b = headByte = readByte(); if (b == HEAD_BYTE_REQUIRED) { - throw new MessageNeverUsedFormatException("Encountered 0xC1 NEVER_USED byte"); + throw new MessageNeverUsedFormatException("Encountered 0xC1 \"NEVER_USED\" byte"); } } return b; @@ -205,7 +204,9 @@ private void nextBuffer() throw new MessageInsufficientBufferException(); } totalReadBytes += buffer.size(); - in.release(buffer); + if (buffer != EMPTY_BUFFER) { + in.release(buffer); + } buffer = next; position = 0; } @@ -232,7 +233,9 @@ private MessageBuffer readCastBuffer(int length) castBuffer.putBytes(remaining, next.getArray(), next.offset(), length - remaining); totalReadBytes += buffer.size(); - in.release(buffer); + if (buffer != EMPTY_BUFFER) { + in.release(buffer); + } buffer = next; position = length - remaining; @@ -244,8 +247,7 @@ private MessageBuffer readCastBuffer(int length) private static int utf8MultibyteCharacterSize(byte firstByte) { - System.out.println("first byte: "+(firstByte & 0xff)); - return Integer.numberOfLeadingZeros(~(firstByte & 0xff)); + return Integer.numberOfLeadingZeros(~(firstByte & 0xff) << 24); } /** @@ -264,7 +266,9 @@ public boolean hasNext() return false; } totalReadBytes += buffer.size(); - in.release(buffer); + if (buffer != EMPTY_BUFFER) { + in.release(buffer); + } buffer = next; position = 0; } @@ -490,7 +494,7 @@ public ImmutableValue unpackValue() MessageFormat mf = getNextFormat(); switch (mf.getValueType()) { case NIL: - unpackNil(); + readByte(); return ValueFactory.newNil(); case BOOLEAN: return ValueFactory.newBoolean(unpackBoolean()); @@ -1070,7 +1074,7 @@ else if (bufferRemaining == 0) { if (cr.isError()) { handleCoderError(cr); } - if (cr.isUnderflow() || cr.isOverflow()) { + if (cr.isOverflow() || (cr.isUnderflow() && multiByteBuffer.position() < multiByteBuffer.limit())) { // isOverflow or isOverflow must not happen. if happened, throw exception try { cr.throwException(); @@ -1106,7 +1110,7 @@ private String decodeStringFastPath(int length) if (config.actionOnMalFormedInput == CodingErrorAction.REPLACE && config.actionOnUnmappableCharacter == CodingErrorAction.REPLACE && buffer.hasArray()) { - String s = new String(buffer.getArray(), position, length, MessagePack.UTF8); + String s = new String(buffer.getArray(), buffer.offset() + position, length, MessagePack.UTF8); position += length; return s; } @@ -1425,6 +1429,11 @@ private int readNextLength32() public void close() throws IOException { + if (buffer != EMPTY_BUFFER) { + in.release(buffer); + buffer = EMPTY_BUFFER; + position = 0; + } in.close(); } diff --git a/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBuffer.java b/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBuffer.java index 46a777af0..302105f83 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBuffer.java +++ b/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBuffer.java @@ -328,11 +328,6 @@ else if (bb.hasArray()) { this.reference = reference; } - public MessageBufferReader newReader() - { - return new MessageBufferReader(this); - } - /** * byte size of the buffer * @@ -408,7 +403,7 @@ public void getBytes(int index, byte[] dst, int dstOffset, int length) public void getBytes(int index, int len, ByteBuffer dst) { - if (dst.remaining() > len) { + if (dst.remaining() < len) { throw new BufferOverflowException(); } ByteBuffer src = toByteBuffer(index, len); diff --git a/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferReader.java b/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferReader.java deleted file mode 100644 index f9656d22d..000000000 --- a/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferReader.java +++ /dev/null @@ -1,122 +0,0 @@ -// -// MessagePack for Java -// -// 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.core.buffer; - -public class MessageBufferReader -{ - // TODO add more reader methods for each type - - private MessageBuffer buffer; - private int position; - - MessageBufferReader(MessageBuffer buffer) - { - this.buffer = buffer; - } - - public MessageBuffer buffer() - { - return buffer; - } - - public int position() - { - return position; - } - - public void position(int newPosition) - { - // TODO validation? - this.position = newPosition; - } - - public int remaining() - { - return buffer.size() - position; - } - - public byte getByte() - { - return buffer.getByte(position); - } - - public byte readByte() - { - byte v = buffer.getByte(position); - position += 1; - return v; - } - - public short getShort() - { - return buffer.getShort(position); - } - - public short readShort() - { - short v = buffer.getShort(position); - position += 1; - return v; - } - - public int getInt() - { - return buffer.getInt(position); - } - - public int readInt() - { - int v = buffer.getInt(position); - position += 1; - return v; - } - - public long getLong() - { - return buffer.getLong(position); - } - - public long readLong() - { - long v = buffer.getLong(position); - position += 1; - return v; - } - - public float getFloat() - { - return buffer.getFloat(position); - } - - public float readFloat() - { - float v = buffer.getFloat(position); - position += 1; - return v; - } - - public double getDouble() - { - return buffer.getDouble(position); - } - - public double readDouble() - { - double v = buffer.getDouble(position); - position += 1; - return v; - } -} From c1986f54df7e5224318745ba4f85a0aaaa0ec433 Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Tue, 22 Dec 2015 18:18:42 +0900 Subject: [PATCH 181/234] Remove release method from MessageBufferInput --- .../org/msgpack/core/MessageUnpacker.java | 16 ++-------------- .../msgpack/core/buffer/ArrayBufferInput.java | 4 ---- .../msgpack/core/buffer/ByteBufferInput.java | 4 ---- .../core/buffer/ChannelBufferInput.java | 19 ++++--------------- .../core/buffer/InputStreamBufferInput.java | 17 ++--------------- .../core/buffer/MessageBufferInput.java | 6 ++---- .../msgpack/core/MessageUnpackerTest.scala | 2 -- .../msgpack/core/buffer/ByteStringTest.scala | 3 --- 8 files changed, 10 insertions(+), 61 deletions(-) diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java b/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java index b22c98dfb..70a050990 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java +++ b/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java @@ -204,9 +204,6 @@ private void nextBuffer() throw new MessageInsufficientBufferException(); } totalReadBytes += buffer.size(); - if (buffer != EMPTY_BUFFER) { - in.release(buffer); - } buffer = next; position = 0; } @@ -233,9 +230,6 @@ private MessageBuffer readCastBuffer(int length) castBuffer.putBytes(remaining, next.getArray(), next.offset(), length - remaining); totalReadBytes += buffer.size(); - if (buffer != EMPTY_BUFFER) { - in.release(buffer); - } buffer = next; position = length - remaining; @@ -266,9 +260,6 @@ public boolean hasNext() return false; } totalReadBytes += buffer.size(); - if (buffer != EMPTY_BUFFER) { - in.release(buffer); - } buffer = next; position = 0; } @@ -1429,11 +1420,8 @@ private int readNextLength32() public void close() throws IOException { - if (buffer != EMPTY_BUFFER) { - in.release(buffer); - buffer = EMPTY_BUFFER; - position = 0; - } + buffer = EMPTY_BUFFER; + position = 0; in.close(); } diff --git a/msgpack-core/src/main/java/org/msgpack/core/buffer/ArrayBufferInput.java b/msgpack-core/src/main/java/org/msgpack/core/buffer/ArrayBufferInput.java index 35f76c14c..a777b8a73 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/buffer/ArrayBufferInput.java +++ b/msgpack-core/src/main/java/org/msgpack/core/buffer/ArrayBufferInput.java @@ -88,8 +88,4 @@ public void close() isRead = false; } - // TODO - public void release(MessageBuffer buffer) - { - } } diff --git a/msgpack-core/src/main/java/org/msgpack/core/buffer/ByteBufferInput.java b/msgpack-core/src/main/java/org/msgpack/core/buffer/ByteBufferInput.java index 1f60b3fec..034d8882b 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/buffer/ByteBufferInput.java +++ b/msgpack-core/src/main/java/org/msgpack/core/buffer/ByteBufferInput.java @@ -67,8 +67,4 @@ public void close() // Nothing to do } - // TODO - public void release(MessageBuffer buffer) - { - } } diff --git a/msgpack-core/src/main/java/org/msgpack/core/buffer/ChannelBufferInput.java b/msgpack-core/src/main/java/org/msgpack/core/buffer/ChannelBufferInput.java index 6dd262599..73dcb5db6 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/buffer/ChannelBufferInput.java +++ b/msgpack-core/src/main/java/org/msgpack/core/buffer/ChannelBufferInput.java @@ -29,8 +29,7 @@ public class ChannelBufferInput implements MessageBufferInput { private ReadableByteChannel channel; - private boolean reachedEOF = false; - private final int bufferSize; + private final MessageBuffer m; public ChannelBufferInput(ReadableByteChannel channel) { @@ -41,7 +40,7 @@ public ChannelBufferInput(ReadableByteChannel channel, int bufferSize) { this.channel = checkNotNull(channel, "input channel is null"); checkArgument(bufferSize > 0, "buffer size must be > 0: " + bufferSize); - this.bufferSize = bufferSize; + this.m = MessageBuffer.newBuffer(bufferSize); } /** @@ -55,7 +54,6 @@ public ReadableByteChannel reset(ReadableByteChannel channel) { ReadableByteChannel old = this.channel; this.channel = channel; - this.reachedEOF = false; return old; } @@ -63,16 +61,11 @@ public ReadableByteChannel reset(ReadableByteChannel channel) public MessageBuffer next() throws IOException { - if (reachedEOF) { - return null; - } - - MessageBuffer m = MessageBuffer.newBuffer(bufferSize); ByteBuffer b = m.toByteBuffer(); - while (!reachedEOF && b.remaining() > 0) { + while (b.remaining() > 0) { int ret = channel.read(b); if (ret == -1) { - reachedEOF = true; + break; } } b.flip(); @@ -86,8 +79,4 @@ public void close() channel.close(); } - // TODO - public void release(MessageBuffer buffer) - { - } } diff --git a/msgpack-core/src/main/java/org/msgpack/core/buffer/InputStreamBufferInput.java b/msgpack-core/src/main/java/org/msgpack/core/buffer/InputStreamBufferInput.java index b0d42e4a0..ad8aa462f 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/buffer/InputStreamBufferInput.java +++ b/msgpack-core/src/main/java/org/msgpack/core/buffer/InputStreamBufferInput.java @@ -29,8 +29,7 @@ public class InputStreamBufferInput implements MessageBufferInput { private InputStream in; - private final int bufferSize; - private boolean reachedEOF = false; + private final byte[] buffer; public static MessageBufferInput newBufferInput(InputStream in) { @@ -52,7 +51,7 @@ public InputStreamBufferInput(InputStream in) public InputStreamBufferInput(InputStream in, int bufferSize) { this.in = checkNotNull(in, "input is null"); - this.bufferSize = bufferSize; + this.buffer = new byte[bufferSize]; } /** @@ -66,7 +65,6 @@ public InputStream reset(InputStream in) { InputStream old = this.in; this.in = in; - reachedEOF = false; return old; } @@ -74,14 +72,8 @@ public InputStream reset(InputStream in) public MessageBuffer next() throws IOException { - if (reachedEOF) { - return null; - } - - byte[] buffer = new byte[bufferSize]; int readLen = in.read(buffer); if (readLen == -1) { - reachedEOF = true; return null; } return MessageBuffer.wrap(buffer).slice(0, readLen); @@ -93,9 +85,4 @@ public void close() { in.close(); } - - // TODO - public void release(MessageBuffer buffer) - { - } } diff --git a/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferInput.java b/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferInput.java index 2a92160b2..5925557cf 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferInput.java +++ b/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferInput.java @@ -27,14 +27,12 @@ public interface MessageBufferInput /** * Get a next buffer to read. * + * When this method is called twice, the formally allocated buffer can be safely discarded. + * * @return the next MessageBuffer, or return null if no more buffer is available. * @throws IOException when error occurred when reading the data */ public MessageBuffer next() throws IOException; - /** - * Release an unused buffer formerly returned by next() method. - */ - public void release(MessageBuffer buffer); } diff --git a/msgpack-core/src/test/scala/org/msgpack/core/MessageUnpackerTest.scala b/msgpack-core/src/test/scala/org/msgpack/core/MessageUnpackerTest.scala index 9ecf70a21..fc03d5680 100644 --- a/msgpack-core/src/test/scala/org/msgpack/core/MessageUnpackerTest.scala +++ b/msgpack-core/src/test/scala/org/msgpack/core/MessageUnpackerTest.scala @@ -261,8 +261,6 @@ class MessageUnpackerTest extends MessagePackSpec { } } - override def release(buffer: MessageBuffer): Unit = {} - override def close(): Unit = {} } diff --git a/msgpack-core/src/test/scala/org/msgpack/core/buffer/ByteStringTest.scala b/msgpack-core/src/test/scala/org/msgpack/core/buffer/ByteStringTest.scala index 39526a0ce..92103dc31 100644 --- a/msgpack-core/src/test/scala/org/msgpack/core/buffer/ByteStringTest.scala +++ b/msgpack-core/src/test/scala/org/msgpack/core/buffer/ByteStringTest.scala @@ -38,9 +38,6 @@ class ByteStringTest isRead = true messageBuffer } - - override def release(buffer: MessageBuffer): Unit = {} - override def close(): Unit = {} } From 6a4e190c0387b302e756c0052059188f2103191e Mon Sep 17 00:00:00 2001 From: Sadayuki Furuhashi Date: Tue, 22 Dec 2015 18:24:43 +0900 Subject: [PATCH 182/234] fixed skipPayload --- msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java | 1 + 1 file changed, 1 insertion(+) diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java b/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java index 70a050990..38880d03d 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java +++ b/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java @@ -1326,6 +1326,7 @@ private void skipPayload(int numBytes) } else { position += bufferRemaining; + numBytes -= bufferRemaining; } nextBuffer(); } From 0a463e4489e75d787bbca29c7de5c7f8f8d50fa5 Mon Sep 17 00:00:00 2001 From: Sadayuki Furuhashi Date: Thu, 24 Dec 2015 09:44:27 +0900 Subject: [PATCH 183/234] simplified streaming string decoding code --- .../org/msgpack/core/MessageUnpacker.java | 26 +++---------------- 1 file changed, 3 insertions(+), 23 deletions(-) diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java b/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java index 38880d03d..c6730a009 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java +++ b/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java @@ -997,29 +997,9 @@ public String unpackString() while (readingRawRemaining > 0) { int bufferRemaining = buffer.size() - position; if (bufferRemaining >= readingRawRemaining) { - ByteBuffer bb = buffer.toByteBuffer(position, readingRawRemaining); - int bbStartPosition = bb.position(); - decodeBuffer.clear(); - - CoderResult cr = decoder.decode(bb, decodeBuffer, true); - int readLen = bb.position() - bbStartPosition; - position += readLen; - readingRawRemaining -= readLen; - decodeStringBuffer.append(decodeBuffer.flip()); - - if (cr.isError()) { - handleCoderError(cr); - } - if (cr.isUnderflow() && config.actionOnMalFormedInput == CodingErrorAction.REPORT) { - throw new MalformedInputException(cr.length()); - } - - if (cr.isOverflow()) { - // go to next loop - } - else { - break; - } + decodeStringBuffer.append(decodeStringFastPath(readingRawRemaining)); + readingRawRemaining = 0; + break; } else if (bufferRemaining == 0) { nextBuffer(); From 634fdd8629045c4767a391c205bf233350aa76c1 Mon Sep 17 00:00:00 2001 From: Sadayuki Furuhashi Date: Thu, 24 Dec 2015 10:00:21 +0900 Subject: [PATCH 184/234] 0xC1 NEVER_USED always throws MessageNeverUsedFormatException regardless of context rather than MessageTypeException or MessageFormatException depending on context --- .../java/org/msgpack/core/MessageUnpacker.java | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java b/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java index c6730a009..bd6339418 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java +++ b/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java @@ -449,7 +449,7 @@ public void skipValue() remainingValues += readNextLength32() * 2; // TODO check int overflow break; case NEVER_USED: - throw new MessageFormatException(String.format("unknown code: %02x is found", b)); + throw new MessageNeverUsedFormatException("Encountered 0xC1 \"NEVER_USED\" byte"); } remainingValues--; @@ -464,19 +464,17 @@ public void skipValue() * @return * @throws MessageFormatException */ - private static MessageTypeException unexpected(String expected, byte b) - throws MessageTypeException + private static MessagePackException unexpected(String expected, byte b) { MessageFormat format = MessageFormat.valueOf(b); - String typeName; if (format == MessageFormat.NEVER_USED) { - typeName = "NeverUsed"; + return new MessageNeverUsedFormatException(String.format("Expected %s, but encountered 0xC1 \"NEVER_USED\" byte", expected)); } else { String name = format.getValueType().name(); - typeName = name.substring(0, 1) + name.substring(1).toLowerCase(); + String typeName = name.substring(0, 1) + name.substring(1).toLowerCase(); + return new MessageTypeException(String.format("Expected %s, but got %s (%02x)", expected, typeName, b)); } - return new MessageTypeException(String.format("Expected %s, but got %s (%02x)", expected, typeName, b)); } public ImmutableValue unpackValue() @@ -530,7 +528,7 @@ public ImmutableValue unpackValue() return ValueFactory.newExtension(extHeader.getType(), readPayload(extHeader.getLength())); } default: - throw new MessageFormatException("Unknown value type"); + throw new MessageNeverUsedFormatException("Unknown value type"); } } From 23b0fd889ee6566ae5dc21a900b29ac065351aba Mon Sep 17 00:00:00 2001 From: Sadayuki Furuhashi Date: Fri, 25 Dec 2015 10:19:18 +0900 Subject: [PATCH 185/234] minimum required castBuffer size is 8 bytes --- .../src/main/java/org/msgpack/core/MessageUnpacker.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java b/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java index bd6339418..9b8e159bc 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java +++ b/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java @@ -98,9 +98,10 @@ public class MessageUnpacker private long totalReadBytes; /** - * Extra buffer for fixed-length data at the buffer boundary. At most 17-byte buffer (for FIXEXT16) is required. + * Extra buffer for fixed-length data at the buffer boundary. + * At most 8-byte buffer (for readLong used by uint 64 and UTF-8 character decoding) is required. */ - private final MessageBuffer castBuffer = MessageBuffer.newBuffer(24); + private final MessageBuffer castBuffer = MessageBuffer.newBuffer(8); /** * Variable by ensureHeader method. Caller of the method should use this variable to read from returned MessageBuffer. From 97b0af40814f4d346a32f667405875d47f751e1a Mon Sep 17 00:00:00 2001 From: Sadayuki Furuhashi Date: Fri, 25 Dec 2015 12:28:43 +0900 Subject: [PATCH 186/234] optimized packer buffer interface --- .../java/org/msgpack/core/MessagePacker.java | 325 ++++++++++-------- .../core/buffer/ChannelBufferOutput.java | 46 ++- .../msgpack/core/buffer/MessageBuffer.java | 5 + .../core/buffer/MessageBufferOutput.java | 48 ++- .../core/buffer/OutputStreamBufferOutput.java | 59 ++-- .../core/example/MessagePackExample.java | 5 - .../org/msgpack/core/MessagePackerTest.scala | 3 +- .../core/buffer/MessageBufferOutputTest.scala | 2 +- .../dataformat/MessagePackGenerator.java | 13 +- 9 files changed, 306 insertions(+), 200 deletions(-) diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessagePacker.java b/msgpack-core/src/main/java/org/msgpack/core/MessagePacker.java index 032cda7f3..11f2fcb5d 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/MessagePacker.java +++ b/msgpack-core/src/main/java/org/msgpack/core/MessagePacker.java @@ -88,15 +88,15 @@ public class MessagePacker private final MessagePack.Config config; private MessageBufferOutput out; + private MessageBuffer buffer; - private MessageBuffer strLenBuffer; private int position; /** * Total written byte size */ - private long flushedBytes; + private long totalFlushBytes; /** * String encoder @@ -119,7 +119,7 @@ public MessagePacker(MessageBufferOutput out, MessagePack.Config config) this.config = checkNotNull(config, "config is null"); this.out = checkNotNull(out, "MessageBufferOutput is null"); this.position = 0; - this.flushedBytes = 0; + this.totalFlushBytes = 0; } /** @@ -134,50 +134,32 @@ public MessageBufferOutput reset(MessageBufferOutput out) // Validate the argument MessageBufferOutput newOut = checkNotNull(out, "MessageBufferOutput is null"); - // Reset the internal states + // Flush before reset + flush(); MessageBufferOutput old = this.out; this.out = newOut; - this.position = 0; - this.flushedBytes = 0; - return old; - } - public long getTotalWrittenBytes() - { - return flushedBytes + position; - } + // Reset totalFlushBytes + this.totalFlushBytes = 0; - private void prepareEncoder() - { - if (encoder == null) { - this.encoder = MessagePack.UTF8.newEncoder().onMalformedInput(config.actionOnMalFormedInput).onUnmappableCharacter(config.actionOnMalFormedInput); - } + return old; } - private void prepareBuffer() - throws IOException + public long getTotalWrittenBytes() { - if (buffer == null) { - buffer = out.next(config.packerBufferSize); - } + return totalFlushBytes + position; } public void flush() throws IOException { - if (buffer == null) { - return; + if (position > 0) { + out.writeBuffer(position); + buffer = null; + totalFlushBytes += position; + position = 0; } - - if (position == buffer.size()) { - out.flush(buffer); - } - else { - out.flush(buffer.slice(0, position)); - } - buffer = null; - flushedBytes += position; - position = 0; + out.flush(); } public void close() @@ -191,12 +173,18 @@ public void close() } } - private void ensureCapacity(int numBytesToWrite) + private void ensureCapacity(int mimimumSize) throws IOException { - if (buffer == null || position + numBytesToWrite >= buffer.size()) { - flush(); - buffer = out.next(Math.max(config.packerBufferSize, numBytesToWrite)); + if (buffer == null) { + buffer = out.next(mimimumSize); + } + else if (position + mimimumSize >= buffer.size()) { + out.writeBuffer(position); + buffer = null; + totalFlushBytes += position; + position = 0; + buffer = out.next(mimimumSize); } } @@ -442,14 +430,44 @@ public MessagePacker packDouble(double v) return this; } - private void packSmallString(String s) + private void packStringByGetBytes(String s) throws IOException { byte[] bytes = s.getBytes(MessagePack.UTF8); packRawStringHeader(bytes.length); - writePayload(bytes); + addPayload(bytes); } + private void prepareEncoder() + { + if (encoder == null) { + this.encoder = MessagePack.UTF8.newEncoder().onMalformedInput(config.actionOnMalFormedInput).onUnmappableCharacter(config.actionOnMalFormedInput); + } + } + + private int encodeStringToBufferAt(int pos, String s) + { + prepareEncoder(); + ByteBuffer bb = buffer.toByteBuffer(pos, buffer.size() - pos); + int startPosition = bb.position(); + CharBuffer in = CharBuffer.wrap(s); + CoderResult cr = encoder.encode(in, bb, true); + if (cr.isError()) { + try { + cr.throwException(); + } + catch (CharacterCodingException e) { + throw new MessageStringCodingException(e); + } + } + if (cr.isUnderflow() || cr.isOverflow()) { + return -1; + } + return bb.position() - startPosition; + } + + private static final int UTF_8_MAX_CHAR_SIZE = 6; + /** * Pack the input String in UTF-8 encoding * @@ -464,77 +482,76 @@ public MessagePacker packString(String s) packRawStringHeader(0); return this; } - - if (s.length() < config.packerSmallStringOptimizationThreshold) { + else if (s.length() < config.packerSmallStringOptimizationThreshold) { // Write the length and payload of small string to the buffer so that it avoids an extra flush of buffer - packSmallString(s); + packStringByGetBytes(s); return this; } - - CharBuffer in = CharBuffer.wrap(s); - prepareEncoder(); - - flush(); - - prepareBuffer(); - boolean isExtension = false; - ByteBuffer encodeBuffer = buffer.toByteBuffer(position, buffer.size() - position); - encoder.reset(); - while (in.hasRemaining()) { - try { - CoderResult cr = encoder.encode(in, encodeBuffer, true); - - // Input data is insufficient - if (cr.isUnderflow()) { - cr = encoder.flush(encodeBuffer); + else if (s.length() < (1 << 8)) { + // ensure capacity for 2-byte raw string header + the maximum string size (+ 1 byte for falback code) + ensureCapacity(2 + s.length() * UTF_8_MAX_CHAR_SIZE + 1); + // keep 2-byte header region and write raw string + int written = encodeStringToBufferAt(position + 2, s); + if (written >= 0) { + if (written < (1 << 8)) { + buffer.putByte(position++, STR8); + buffer.putByte(position++, (byte) written); + position += written; } - - // encodeBuffer is too small - if (cr.isOverflow()) { - // Allocate a larger buffer - int estimatedRemainingSize = Math.max(1, (int) (in.remaining() * encoder.averageBytesPerChar())); - encodeBuffer.flip(); - ByteBuffer newBuffer = ByteBuffer.allocate(Math.max((int) (encodeBuffer.capacity() * 1.5), encodeBuffer.remaining() + estimatedRemainingSize)); - // Coy the current encodeBuffer contents to the new buffer - newBuffer.put(encodeBuffer); - encodeBuffer = newBuffer; - isExtension = true; - encoder.reset(); - continue; - } - - if (cr.isError()) { - if ((cr.isMalformed() && config.actionOnMalFormedInput == CodingErrorAction.REPORT) || - (cr.isUnmappable() && config.actionOnUnmappableCharacter == CodingErrorAction.REPORT)) { - cr.throwException(); + else { + if (written >= (1 << 16)) { + // this must not happen because s.length() is less than 2^8 and (2^8) * UTF_8_MAX_CHAR_SIZE is less than 2^16 + throw new IllegalArgumentException("Unexpected UTF-8 encoder state"); } + // move 1 byte backward to expand 3-byte header region to 3 bytes + buffer.putBytes(position + 3, + buffer.getArray(), buffer.offset() + position + 2, written); + // write 3-byte header header + buffer.putByte(position++, STR16); + buffer.putShort(position, (short) written); + position += 2; + position += written; } + return this; } - catch (CharacterCodingException e) { - throw new MessageStringCodingException(e); + } + else if (s.length() < (1 << 16)) { + // ensure capacity for 3-byte raw string header + the maximum string size (+ 2 bytes for falback code) + ensureCapacity(3 + s.length() * UTF_8_MAX_CHAR_SIZE + 2); + // keep 3-byte header region and write raw string + int written = encodeStringToBufferAt(position + 3, s); + if (written >= 0) { + if (written < (1 << 16)) { + buffer.putByte(position++, STR16); + buffer.putShort(position, (short) written); + position += 2; + position += written; + } + else { + if (written >= (1 << 32)) { + // this must not happen because s.length() is less than 2^16 and (2^16) * UTF_8_MAX_CHAR_SIZE is less than 2^32 + throw new IllegalArgumentException("Unexpected UTF-8 encoder state"); + } + // move 2 bytes backward to expand 3-byte header region to 5 bytes + buffer.putBytes(position + 5, + buffer.getArray(), buffer.offset() + position + 3, written); + // write 3-byte header header + buffer.putByte(position++, STR32); + buffer.putInt(position, written); + position += 4; + position += written; + } + return this; } } - encodeBuffer.flip(); - int strLen = encodeBuffer.remaining(); - - // Preserve the current buffer - MessageBuffer tmpBuf = buffer; - - // Switch the buffer to write the string length - if (strLenBuffer == null) { - strLenBuffer = MessageBuffer.newBuffer(5); - } - buffer = strLenBuffer; - position = 0; - // pack raw string header (string binary size) - packRawStringHeader(strLen); - flush(); // We need to dump the data here to MessageBufferOutput so that we can switch back to the original buffer + // Here doesn't use above optimized code for s.length() < (1 << 32) so that + // ensureCapacity is not called with an integer larger than (3 + ((1 << 16) * UTF_8_MAX_CHAR_SIZE) + 2). + // This makes it sure that MessageBufferOutput.next won't be called a size larger than + // 384KB, which is OK size to keep in memory. - // Reset to the original buffer (or encodeBuffer if new buffer is allocated) - buffer = isExtension ? MessageBuffer.wrap(encodeBuffer) : tmpBuf; - // No need exists to write payload since the encoded string (payload) is already written to the buffer - position = strLen; + // fallback + packStringByGetBytes(s); return this; } @@ -659,72 +676,82 @@ else if (len < (1 << 16)) { return this; } - public MessagePacker writePayload(ByteBuffer src) + /** + * Writes buffer to the output. + * This method is used with packRawStringHeader or packBinaryHeader. + * + * @param src the data to add + * @return this + * @throws IOException + */ + public MessagePacker writePayload(byte[] src) throws IOException { - int len = src.remaining(); - if (len >= config.packerRawDataCopyingThreshold) { - // Use the source ByteBuffer directly to avoid memory copy - - // First, flush the current buffer contents - flush(); + return writePayload(src, 0, src.length); + } - // Wrap the input source as a MessageBuffer - MessageBuffer wrapped = MessageBuffer.wrap(src); - // Then, dump the source data to the output - out.flush(wrapped); - src.position(src.limit()); - flushedBytes += len; + /** + * Writes buffer to the output. + * This method is used with packRawStringHeader or packBinaryHeader. + * + * @param src the data to add + * @param off the start offset in the data + * @param len the number of bytes to add + * @return this + * @throws IOException + */ + public MessagePacker writePayload(byte[] src, int off, int len) + throws IOException + { + if (buffer.size() - position < len || len > 8192) { + flush(); // call flush before write + out.write(src, off, len); + totalFlushBytes += len; } else { - // If the input source is small, simply copy the contents to the buffer - while (src.remaining() > 0) { - if (position >= buffer.size()) { - flush(); - } - prepareBuffer(); - int writeLen = Math.min(buffer.size() - position, src.remaining()); - buffer.putByteBuffer(position, src, writeLen); - position += writeLen; - } + buffer.putBytes(position, src, off, len); + position += len; } - return this; } - public MessagePacker writePayload(byte[] src) + /** + * Writes buffer to the output. + * Unlike writePayload method, addPayload method doesn't copy the source data. It means that the caller + * must not modify the data after calling this method. + * + * @param src the data to add + * @return this + * @throws IOException + */ + public MessagePacker addPayload(byte[] src) throws IOException { - return writePayload(src, 0, src.length); + return addPayload(src, 0, src.length); } - public MessagePacker writePayload(byte[] src, int off, int len) + /** + * Writes buffer to the output. + * Unlike writePayload method, addPayload method doesn't copy the source data. It means that the caller + * must not modify the data after calling this method. + * + * @param src the data to add + * @param off the start offset in the data + * @param len the number of bytes to add + * @return this + * @throws IOException + */ + public MessagePacker addPayload(byte[] src, int off, int len) throws IOException { - if (len >= config.packerRawDataCopyingThreshold) { - // Use the input array directory to avoid memory copy - - // Flush the current buffer contents - flush(); - - // Wrap the input array as a MessageBuffer - MessageBuffer wrapped = MessageBuffer.wrap(src).slice(off, len); - // Dump the source data to the output - out.flush(wrapped); - flushedBytes += len; + if (buffer.size() - position < len || len > 8192) { + flush(); // call flush before add + out.add(src, off, len); + totalFlushBytes += len; } else { - int cursor = 0; - while (cursor < len) { - if (buffer != null && position >= buffer.size()) { - flush(); - } - prepareBuffer(); - int writeLen = Math.min(buffer.size() - position, len - cursor); - buffer.putBytes(position, src, off + cursor, writeLen); - position += writeLen; - cursor += writeLen; - } + buffer.putBytes(position, src, off, len); + position += len; } return this; } diff --git a/msgpack-core/src/main/java/org/msgpack/core/buffer/ChannelBufferOutput.java b/msgpack-core/src/main/java/org/msgpack/core/buffer/ChannelBufferOutput.java index 9ecddf3ac..b981cc95d 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/buffer/ChannelBufferOutput.java +++ b/msgpack-core/src/main/java/org/msgpack/core/buffer/ChannelBufferOutput.java @@ -31,15 +31,21 @@ public class ChannelBufferOutput private MessageBuffer buffer; public ChannelBufferOutput(WritableByteChannel channel) + { + this(channel, 8192); + } + + public ChannelBufferOutput(WritableByteChannel channel, int bufferSize) { this.channel = checkNotNull(channel, "output channel is null"); + this.buffer = MessageBuffer.newBuffer(bufferSize); } /** - * Reset channel. This method doesn't close the old resource. + * Reset channel. This method doesn't close the old channel. * * @param channel new channel - * @return the old resource + * @return the old channel */ public WritableByteChannel reset(WritableByteChannel channel) throws IOException @@ -50,21 +56,40 @@ public WritableByteChannel reset(WritableByteChannel channel) } @Override - public MessageBuffer next(int bufferSize) + public MessageBuffer next(int mimimumSize) throws IOException { - if (buffer == null || buffer.size() != bufferSize) { - buffer = MessageBuffer.newBuffer(bufferSize); + if (buffer.size() < mimimumSize) { + buffer = MessageBuffer.newBuffer(mimimumSize); } return buffer; } @Override - public void flush(MessageBuffer buf) + public void writeBuffer(int length) + throws IOException + { + ByteBuffer bb = buffer.toByteBuffer(0, length); + while (bb.hasRemaining()) { + channel.write(bb); + } + } + + @Override + public void write(byte[] buffer, int offset, int length) throws IOException { - ByteBuffer bb = buf.toByteBuffer(); - channel.write(bb); + ByteBuffer bb = ByteBuffer.wrap(buffer, offset, length); + while (bb.hasRemaining()) { + channel.write(bb); + } + } + + @Override + public void add(byte[] buffer, int offset, int length) + throws IOException + { + write(buffer, offset, length); } @Override @@ -73,4 +98,9 @@ public void close() { channel.close(); } + + @Override + public void flush() + throws IOException + { } } diff --git a/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBuffer.java b/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBuffer.java index 302105f83..fce8020ce 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBuffer.java +++ b/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBuffer.java @@ -210,6 +210,11 @@ public static MessageBuffer wrap(byte[] array) return newMessageBuffer(array); } + public static MessageBuffer wrap(byte[] array, int offset, int length) + { + return newMessageBuffer(array).slice(offset, length); + } + public static MessageBuffer wrap(ByteBuffer bb) { return newMessageBuffer(bb).slice(bb.position(), bb.remaining()); diff --git a/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferOutput.java b/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferOutput.java index 77fe12454..92eb760a9 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferOutput.java +++ b/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferOutput.java @@ -17,30 +17,60 @@ import java.io.Closeable; import java.io.IOException; +import java.io.Flushable; /** - * Provides a sequence of MessageBuffers for packing the input data + * Provides a buffered output stream for packing objects */ public interface MessageBufferOutput - extends Closeable + extends Closeable, Flushable { /** - * Retrieves the next buffer for writing message packed data + * Allocates the next buffer for writing message packed data. + * If the previously allocated buffer is not flushed yet, this next method should discard + * it without writing it. * - * @param bufferSize the buffer size to retrieve + * @param mimimumSize the mimium required buffer size to allocate * @return * @throws IOException */ - public MessageBuffer next(int bufferSize) + public MessageBuffer next(int mimimumSize) throws IOException; /** - * Output the buffer contents. If you need to output a part of the - * buffer use {@link MessageBuffer#slice(int, int)} + * Flushes the previously allocated buffer. + * This method is not always called because next method also flushes previously allocated buffer. + * This method is called when write method is called or application wants to control the timing of flush. * - * @param buf + * @param length the size of buffer to flush * @throws IOException */ - public void flush(MessageBuffer buf) + public void writeBuffer(int length) + throws IOException; + + /** + * Writes an external payload data. + * This method should follow semantics of OutputStream. + * + * @param buffer the data to write + * @param offset the start offset in the data + * @param length the number of bytes to write + * @return + * @throws IOException + */ + public void write(byte[] buffer, int offset, int length) + throws IOException; + + /** + * Writes an external payload data. + * This buffer is given - this MessageBufferOutput owns the buffer and may modify contents of the buffer. Contents of this buffer won't be modified by the caller. + * + * @param buffer the data to add + * @param offset the start offset in the data + * @param length the number of bytes to add + * @return + * @throws IOException + */ + public void add(byte[] buffer, int offset, int length) throws IOException; } diff --git a/msgpack-core/src/main/java/org/msgpack/core/buffer/OutputStreamBufferOutput.java b/msgpack-core/src/main/java/org/msgpack/core/buffer/OutputStreamBufferOutput.java index 07d423bf0..d6f17c783 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/buffer/OutputStreamBufferOutput.java +++ b/msgpack-core/src/main/java/org/msgpack/core/buffer/OutputStreamBufferOutput.java @@ -28,18 +28,23 @@ public class OutputStreamBufferOutput { private OutputStream out; private MessageBuffer buffer; - private byte[] tmpBuf; public OutputStreamBufferOutput(OutputStream out) + { + this(out, 8192); + } + + public OutputStreamBufferOutput(OutputStream out, int bufferSize) { this.out = checkNotNull(out, "output is null"); + this.buffer = MessageBuffer.newBuffer(bufferSize); } /** - * Reset Stream. This method doesn't close the old resource. + * Reset Stream. This method doesn't close the old stream. * * @param out new stream - * @return the old resource + * @return the old stream */ public OutputStream reset(OutputStream out) throws IOException @@ -50,41 +55,47 @@ public OutputStream reset(OutputStream out) } @Override - public MessageBuffer next(int bufferSize) + public MessageBuffer next(int mimimumSize) throws IOException { - if (buffer == null || buffer.size != bufferSize) { - buffer = MessageBuffer.newBuffer(bufferSize); + if (buffer.size() < mimimumSize) { + buffer = MessageBuffer.newBuffer(mimimumSize); } return buffer; } @Override - public void flush(MessageBuffer buf) + public void writeBuffer(int length) throws IOException { - int writeLen = buf.size(); - if (buf.hasArray()) { - out.write(buf.getArray(), buf.offset(), writeLen); - } - else { - if (tmpBuf == null || tmpBuf.length < writeLen) { - tmpBuf = new byte[writeLen]; - } - buf.getBytes(0, tmpBuf, 0, writeLen); - out.write(tmpBuf, 0, writeLen); - } + write(buffer.getArray(), buffer.offset(), length); + } + + @Override + public void write(byte[] buffer, int offset, int length) + throws IOException + { + out.write(buffer, offset, length); + } + + @Override + public void add(byte[] buffer, int offset, int length) + throws IOException + { + write(buffer, offset, length); } @Override public void close() throws IOException { - try { - out.flush(); - } - finally { - out.close(); - } + out.close(); + } + + @Override + public void flush() + throws IOException + { + out.flush(); } } diff --git a/msgpack-core/src/test/java/org/msgpack/core/example/MessagePackExample.java b/msgpack-core/src/test/java/org/msgpack/core/example/MessagePackExample.java index a74c5cd18..7636742e0 100644 --- a/msgpack-core/src/test/java/org/msgpack/core/example/MessagePackExample.java +++ b/msgpack-core/src/test/java/org/msgpack/core/example/MessagePackExample.java @@ -153,11 +153,6 @@ public static void packer() .packArrayHeader(2) .packString("xxx-xxxx") .packString("yyy-yyyy"); - - // [Advanced] write data using ByteBuffer - ByteBuffer bb = ByteBuffer.wrap(new byte[] {'b', 'i', 'n', 'a', 'r', 'y', 'd', 'a', 't', 'a'}); - packer.packBinaryHeader(bb.remaining()); - packer.writePayload(bb); } /** diff --git a/msgpack-core/src/test/scala/org/msgpack/core/MessagePackerTest.scala b/msgpack-core/src/test/scala/org/msgpack/core/MessagePackerTest.scala index 20f4f560b..967cf07a1 100644 --- a/msgpack-core/src/test/scala/org/msgpack/core/MessagePackerTest.scala +++ b/msgpack-core/src/test/scala/org/msgpack/core/MessagePackerTest.scala @@ -283,12 +283,11 @@ class MessagePackerTest "support read-only buffer" taggedAs ("read-only") in { val payload = Array[Byte](1) - val buffer = ByteBuffer.wrap(payload).asReadOnlyBuffer() val out = new ByteArrayOutputStream() val packer = MessagePack.newDefaultPacker(out) .packBinaryHeader(1) - .writePayload(buffer) + .writePayload(payload) .close() } } diff --git a/msgpack-core/src/test/scala/org/msgpack/core/buffer/MessageBufferOutputTest.scala b/msgpack-core/src/test/scala/org/msgpack/core/buffer/MessageBufferOutputTest.scala index 8616d1c69..1869f2aad 100644 --- a/msgpack-core/src/test/scala/org/msgpack/core/buffer/MessageBufferOutputTest.scala +++ b/msgpack-core/src/test/scala/org/msgpack/core/buffer/MessageBufferOutputTest.scala @@ -44,7 +44,7 @@ class MessageBufferOutputTest def writeIntToBuf(buf: MessageBufferOutput) = { val mb0 = buf.next(8) mb0.putInt(0, 42) - buf.flush(mb0) + buf.writeBuffer(4) buf.close } diff --git a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackGenerator.java b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackGenerator.java index 189197209..c040ee7dd 100644 --- a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackGenerator.java +++ b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackGenerator.java @@ -183,8 +183,17 @@ else if (v instanceof Integer) { } else if (v instanceof ByteBuffer) { ByteBuffer bb = (ByteBuffer) v; - messagePacker.packBinaryHeader(bb.limit()); - messagePacker.writePayload(bb); + int len = bb.remaining(); + if (bb.hasArray()) { + messagePacker.packBinaryHeader(len); + messagePacker.writePayload(bb.array(), bb.arrayOffset(), len); + } + else { + byte[] data = new byte[len]; + bb.get(data); + messagePacker.packBinaryHeader(len); + messagePacker.addPayload(data); + } } else if (v instanceof String) { messagePacker.packString((String) v); From 5c26c6fe3394214fe86c51757f7d6f2eee8da0cc Mon Sep 17 00:00:00 2001 From: Sadayuki Furuhashi Date: Fri, 25 Dec 2015 15:28:15 +0900 Subject: [PATCH 187/234] reorganized MessagePacker interface to use MessagePacker --- .../org/msgpack/core/MessageBufferPacker.java | 73 ++++ .../java/org/msgpack/core/MessageFormat.java | 89 ++++- .../java/org/msgpack/core/MessagePack.java | 374 ++---------------- .../org/msgpack/core/MessagePackFactory.java | 203 ++++++++++ .../java/org/msgpack/core/MessagePacker.java | 88 ++--- .../org/msgpack/core/MessageUnpacker.java | 78 ++-- .../core/buffer/ArrayBufferOutput.java | 136 +++++++ .../core/example/MessagePackExample.java | 15 +- .../org/msgpack/core/MessageFormatTest.scala | 2 +- .../org/msgpack/core/MessagePackTest.scala | 24 +- .../org/msgpack/core/MessagePackerTest.scala | 19 +- .../msgpack/core/MessageUnpackerTest.scala | 46 +-- .../core/buffer/MessageBufferInputTest.scala | 6 +- .../org/msgpack/value/ValueTypeTest.scala | 2 +- 14 files changed, 686 insertions(+), 469 deletions(-) create mode 100644 msgpack-core/src/main/java/org/msgpack/core/MessageBufferPacker.java create mode 100644 msgpack-core/src/main/java/org/msgpack/core/MessagePackFactory.java create mode 100644 msgpack-core/src/main/java/org/msgpack/core/buffer/ArrayBufferOutput.java diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessageBufferPacker.java b/msgpack-core/src/main/java/org/msgpack/core/MessageBufferPacker.java new file mode 100644 index 000000000..02b94f773 --- /dev/null +++ b/msgpack-core/src/main/java/org/msgpack/core/MessageBufferPacker.java @@ -0,0 +1,73 @@ +// +// MessagePack for Java +// +// 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.core; + +import org.msgpack.core.buffer.MessageBuffer; +import org.msgpack.core.buffer.MessageBufferOutput; +import org.msgpack.core.buffer.ArrayBufferOutput; + +import java.io.IOException; +import java.util.List; + +public class MessageBufferPacker + extends MessagePacker +{ + public MessageBufferPacker() + { + this(new ArrayBufferOutput()); + } + + public MessageBufferPacker(ArrayBufferOutput out) + { + super(out); + } + + @Override + public MessageBufferPacker setSmallStringOptimizationThreshold(int bytes) + { + super.setSmallStringOptimizationThreshold(bytes); + return this; + } + + public MessageBufferOutput reset(MessageBufferOutput out) + throws IOException + { + if (!(out instanceof ArrayBufferOutput)) { + throw new IllegalArgumentException("MessageBufferPacker accepts only ArrayBufferOutput"); + } + return super.reset(out); + } + + public void clear() + { + ((ArrayBufferOutput) out).clear(); + } + + public byte[] toByteArray() + { + return ((ArrayBufferOutput) out).toByteArray(); + } + + public MessageBuffer toMessageBuffer() + { + return ((ArrayBufferOutput) out).toMessageBuffer(); + } + + public List toBufferList() + { + return ((ArrayBufferOutput) out).toBufferList(); + } +} diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessageFormat.java b/msgpack-core/src/main/java/org/msgpack/core/MessageFormat.java index 8e44b0aae..17a0f1555 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/MessageFormat.java +++ b/msgpack-core/src/main/java/org/msgpack/core/MessageFormat.java @@ -15,7 +15,6 @@ // package org.msgpack.core; -import org.msgpack.core.MessagePack.Code; import org.msgpack.core.annotations.VisibleForTesting; import org.msgpack.value.ValueType; @@ -66,6 +65,94 @@ public enum MessageFormat MAP32(ValueType.MAP), NEGFIXINT(ValueType.INTEGER); + /** + * The prefix code set of MessagePack. See also https://github.com/msgpack/msgpack/blob/master/spec.md for details. + */ + public static final class Code + { + public static final boolean isFixInt(byte b) + { + int v = b & 0xFF; + return v <= 0x7f || v >= 0xe0; + } + + public static final boolean isPosFixInt(byte b) + { + return (b & POSFIXINT_MASK) == 0; + } + + public static final boolean isNegFixInt(byte b) + { + return (b & NEGFIXINT_PREFIX) == NEGFIXINT_PREFIX; + } + + public static final boolean isFixStr(byte b) + { + return (b & (byte) 0xe0) == Code.FIXSTR_PREFIX; + } + + public static final boolean isFixedArray(byte b) + { + return (b & (byte) 0xf0) == Code.FIXARRAY_PREFIX; + } + + public static final boolean isFixedMap(byte b) + { + return (b & (byte) 0xe0) == Code.FIXMAP_PREFIX; + } + + public static final boolean isFixedRaw(byte b) + { + return (b & (byte) 0xe0) == Code.FIXSTR_PREFIX; + } + + public static final byte POSFIXINT_MASK = (byte) 0x80; + + public static final byte FIXMAP_PREFIX = (byte) 0x80; + public static final byte FIXARRAY_PREFIX = (byte) 0x90; + public static final byte FIXSTR_PREFIX = (byte) 0xa0; + + public static final byte NIL = (byte) 0xc0; + public static final byte NEVER_USED = (byte) 0xc1; + public static final byte FALSE = (byte) 0xc2; + public static final byte TRUE = (byte) 0xc3; + public static final byte BIN8 = (byte) 0xc4; + public static final byte BIN16 = (byte) 0xc5; + public static final byte BIN32 = (byte) 0xc6; + public static final byte EXT8 = (byte) 0xc7; + public static final byte EXT16 = (byte) 0xc8; + public static final byte EXT32 = (byte) 0xc9; + public static final byte FLOAT32 = (byte) 0xca; + public static final byte FLOAT64 = (byte) 0xcb; + public static final byte UINT8 = (byte) 0xcc; + public static final byte UINT16 = (byte) 0xcd; + public static final byte UINT32 = (byte) 0xce; + public static final byte UINT64 = (byte) 0xcf; + + public static final byte INT8 = (byte) 0xd0; + public static final byte INT16 = (byte) 0xd1; + public static final byte INT32 = (byte) 0xd2; + public static final byte INT64 = (byte) 0xd3; + + public static final byte FIXEXT1 = (byte) 0xd4; + public static final byte FIXEXT2 = (byte) 0xd5; + public static final byte FIXEXT4 = (byte) 0xd6; + public static final byte FIXEXT8 = (byte) 0xd7; + public static final byte FIXEXT16 = (byte) 0xd8; + + public static final byte STR8 = (byte) 0xd9; + public static final byte STR16 = (byte) 0xda; + public static final byte STR32 = (byte) 0xdb; + + public static final byte ARRAY16 = (byte) 0xdc; + public static final byte ARRAY32 = (byte) 0xdd; + + public static final byte MAP16 = (byte) 0xde; + public static final byte MAP32 = (byte) 0xdf; + + public static final byte NEGFIXINT_PREFIX = (byte) 0xe0; + } + private static final MessageFormat[] formatTable = new MessageFormat[256]; private final ValueType valueType; diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessagePack.java b/msgpack-core/src/main/java/org/msgpack/core/MessagePack.java index 9847d461e..8af53a884 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/MessagePack.java +++ b/msgpack-core/src/main/java/org/msgpack/core/MessagePack.java @@ -37,406 +37,102 @@ public class MessagePack { public static final Charset UTF8 = Charset.forName("UTF-8"); - /** - * Message packer/unpacker configuration object - */ - public static class Config - { - /** - * allow unpackBinaryHeader to read str format family (default:true) - */ - public final boolean readStringAsBinary; - /** - * allow unpackRawStringHeader and unpackString to read bin format family (default: true) - */ - public final boolean readBinaryAsString; - /** - * Action when encountered a malformed input - */ - public final CodingErrorAction actionOnMalFormedInput; - /** - * Action when an unmappable character is found - */ - public final CodingErrorAction actionOnUnmappableCharacter; - /** - * unpackString size limit. (default: Integer.MAX_VALUE) - */ - public final int maxUnpackStringSize; - public final int stringEncoderBufferSize; - public final int stringDecoderBufferSize; - public final int packerBufferSize; - public final int packerRawDataCopyingThreshold; - /** - * Use String.getBytes() for strings smaller than this threshold. - * Note that this parameter is subject to change. - */ - public final int packerSmallStringOptimizationThreshold; - - public Config( - boolean readStringAsBinary, - boolean readBinaryAsString, - CodingErrorAction actionOnMalFormedInput, - CodingErrorAction actionOnUnmappableCharacter, - int maxUnpackStringSize, - int stringEncoderBufferSize, - int stringDecoderBufferSize, - int packerBufferSize, - int packerSmallStringOptimizationThreshold, - int packerRawDataCopyingThreshold) - { - checkArgument(packerBufferSize > 0, "packer buffer size must be larger than 0: " + packerBufferSize); - checkArgument(stringEncoderBufferSize > 0, "string encoder buffer size must be larger than 0: " + stringEncoderBufferSize); - checkArgument(stringDecoderBufferSize > 0, "string decoder buffer size must be larger than 0: " + stringDecoderBufferSize); - - this.readStringAsBinary = readStringAsBinary; - this.readBinaryAsString = readBinaryAsString; - this.actionOnMalFormedInput = actionOnMalFormedInput; - this.actionOnUnmappableCharacter = actionOnUnmappableCharacter; - this.maxUnpackStringSize = maxUnpackStringSize; - this.stringEncoderBufferSize = stringEncoderBufferSize; - this.stringDecoderBufferSize = stringDecoderBufferSize; - this.packerBufferSize = packerBufferSize; - this.packerSmallStringOptimizationThreshold = packerSmallStringOptimizationThreshold; - this.packerRawDataCopyingThreshold = packerRawDataCopyingThreshold; - } - } - - /** - * Builder of the configuration object - */ - public static class ConfigBuilder - { - private boolean readStringAsBinary = true; - private boolean readBinaryAsString = true; - - private CodingErrorAction onMalFormedInput = CodingErrorAction.REPLACE; - private CodingErrorAction onUnmappableCharacter = CodingErrorAction.REPLACE; - - private int maxUnpackStringSize = Integer.MAX_VALUE; - private int stringEncoderBufferSize = 8192; - private int stringDecoderBufferSize = 8192; - private int packerBufferSize = 8192; - private int packerSmallStringOptimizationThreshold = 512; // This parameter is subject to change - private int packerRawDataCopyingThreshold = 512; - - public Config build() - { - return new Config( - readStringAsBinary, - readBinaryAsString, - onMalFormedInput, - onUnmappableCharacter, - maxUnpackStringSize, - stringEncoderBufferSize, - stringDecoderBufferSize, - packerBufferSize, - packerSmallStringOptimizationThreshold, - packerRawDataCopyingThreshold - ); - } - - public ConfigBuilder readStringAsBinary(boolean enable) - { - this.readStringAsBinary = enable; - return this; - } - - public ConfigBuilder readBinaryAsString(boolean enable) - { - this.readBinaryAsString = enable; - return this; - } - - public ConfigBuilder onMalFormedInput(CodingErrorAction action) - { - this.onMalFormedInput = action; - return this; - } - - public ConfigBuilder onUnmappableCharacter(CodingErrorAction action) - { - this.onUnmappableCharacter = action; - return this; - } - - public ConfigBuilder maxUnpackStringSize(int size) - { - this.maxUnpackStringSize = size; - return this; - } - - public ConfigBuilder stringEncoderBufferSize(int size) - { - this.stringEncoderBufferSize = size; - return this; - } - - public ConfigBuilder stringDecoderBufferSize(int size) - { - this.stringDecoderBufferSize = size; - return this; - } - - public ConfigBuilder packerBufferSize(int size) - { - this.packerBufferSize = size; - return this; - } - - public ConfigBuilder packerSmallStringOptimizationThreshold(int threshold) - { - this.packerSmallStringOptimizationThreshold = threshold; - return this; - } - - public ConfigBuilder packerRawDataCopyingThreshold(int threshold) - { - this.packerRawDataCopyingThreshold = threshold; - return this; - } - } + private static MessagePackFactory defaultFactory = new MessagePackFactory(); /** - * Default configuration, which is visible only from classes in the core package. + * Sets the default configuration used for the static constructor methods of this MessagePack class. */ - static final Config DEFAULT_CONFIG = new ConfigBuilder().build(); - - /** - * The prefix code set of MessagePack. See also https://github.com/msgpack/msgpack/blob/master/spec.md for details. - */ - public static final class Code - { - public static final boolean isFixInt(byte b) - { - int v = b & 0xFF; - return v <= 0x7f || v >= 0xe0; - } - - public static final boolean isPosFixInt(byte b) - { - return (b & POSFIXINT_MASK) == 0; - } - - public static final boolean isNegFixInt(byte b) - { - return (b & NEGFIXINT_PREFIX) == NEGFIXINT_PREFIX; - } - - public static final boolean isFixStr(byte b) - { - return (b & (byte) 0xe0) == Code.FIXSTR_PREFIX; - } - - public static final boolean isFixedArray(byte b) - { - return (b & (byte) 0xf0) == Code.FIXARRAY_PREFIX; - } - - public static final boolean isFixedMap(byte b) - { - return (b & (byte) 0xe0) == Code.FIXMAP_PREFIX; - } - - public static final boolean isFixedRaw(byte b) - { - return (b & (byte) 0xe0) == Code.FIXSTR_PREFIX; - } - - public static final byte POSFIXINT_MASK = (byte) 0x80; - - public static final byte FIXMAP_PREFIX = (byte) 0x80; - public static final byte FIXARRAY_PREFIX = (byte) 0x90; - public static final byte FIXSTR_PREFIX = (byte) 0xa0; - - public static final byte NIL = (byte) 0xc0; - public static final byte NEVER_USED = (byte) 0xc1; - public static final byte FALSE = (byte) 0xc2; - public static final byte TRUE = (byte) 0xc3; - public static final byte BIN8 = (byte) 0xc4; - public static final byte BIN16 = (byte) 0xc5; - public static final byte BIN32 = (byte) 0xc6; - public static final byte EXT8 = (byte) 0xc7; - public static final byte EXT16 = (byte) 0xc8; - public static final byte EXT32 = (byte) 0xc9; - public static final byte FLOAT32 = (byte) 0xca; - public static final byte FLOAT64 = (byte) 0xcb; - public static final byte UINT8 = (byte) 0xcc; - public static final byte UINT16 = (byte) 0xcd; - public static final byte UINT32 = (byte) 0xce; - public static final byte UINT64 = (byte) 0xcf; - - public static final byte INT8 = (byte) 0xd0; - public static final byte INT16 = (byte) 0xd1; - public static final byte INT32 = (byte) 0xd2; - public static final byte INT64 = (byte) 0xd3; - - public static final byte FIXEXT1 = (byte) 0xd4; - public static final byte FIXEXT2 = (byte) 0xd5; - public static final byte FIXEXT4 = (byte) 0xd6; - public static final byte FIXEXT8 = (byte) 0xd7; - public static final byte FIXEXT16 = (byte) 0xd8; - - public static final byte STR8 = (byte) 0xd9; - public static final byte STR16 = (byte) 0xda; - public static final byte STR32 = (byte) 0xdb; - - public static final byte ARRAY16 = (byte) 0xdc; - public static final byte ARRAY32 = (byte) 0xdd; - - public static final byte MAP16 = (byte) 0xde; - public static final byte MAP32 = (byte) 0xdf; - - public static final byte NEGFIXINT_PREFIX = (byte) 0xe0; - } - - // Packer/Unpacker factory methods - - private final MessagePack.Config config; - - public MessagePack() + public static void setDefaultFactory(MessagePackFactory newDefaultFactory) { - this(MessagePack.DEFAULT_CONFIG); + defaultFactory = newDefaultFactory; } - public MessagePack(MessagePack.Config config) + public static MessagePackFactory getDefaultFactory() { - this.config = config; + return defaultFactory; } - /** - * Default MessagePack packer/unpacker factory - */ - public static final MessagePack DEFAULT = new MessagePack(MessagePack.DEFAULT_CONFIG); + private MessagePack() + { } /** - * Create a MessagePacker that outputs the packed data to the specified stream, using the default configuration + * Equivalent to getDefaultFactory().newPacker(out). * * @param out * @return */ public static MessagePacker newDefaultPacker(OutputStream out) { - return DEFAULT.newPacker(out); + return defaultFactory.newPacker(out); } /** - * Create a MessagePacker that outputs the packed data to the specified channel, using the default configuration + * Equivalent to getDefaultFactory().newPacker(channel). * * @param channel * @return */ public static MessagePacker newDefaultPacker(WritableByteChannel channel) { - return DEFAULT.newPacker(channel); - } - - /** - * Create a MessageUnpacker that reads data from then given InputStream, using the default configuration - * - * @param in - * @return - */ - public static MessageUnpacker newDefaultUnpacker(InputStream in) - { - return DEFAULT.newUnpacker(in); + return defaultFactory.newPacker(channel); } /** - * Create a MessageUnpacker that reads data from the given channel, using the default configuration + * Equivalent to getDefaultFactory().newBufferPacker() * * @param channel * @return */ - public static MessageUnpacker newDefaultUnpacker(ReadableByteChannel channel) - { - return DEFAULT.newUnpacker(channel); - } - - /** - * Create a MessageUnpacker that reads data from the given byte array, using the default configuration - * - * @param arr - * @return - */ - public static MessageUnpacker newDefaultUnpacker(byte[] arr) + public static MessageBufferPacker newDefaultBufferPacker() { - return DEFAULT.newUnpacker(arr); + return defaultFactory.newBufferPacker(); } /** - * Create a MessageUnpacker that reads data form the given byte array [offset, .. offset+length), using the default - * configuration. + * Equivalent to getDefaultFactory().newUnpacker(in). * - * @param arr - * @param offset - * @param length + * @param in * @return */ - public static MessageUnpacker newDefaultUnpacker(byte[] arr, int offset, int length) - { - return DEFAULT.newUnpacker(arr, offset, length); - } - - /** - * Create a MessagePacker that outputs the packed data to the specified stream - * - * @param out - */ - public MessagePacker newPacker(OutputStream out) + public static MessageUnpacker newDefaultUnpacker(InputStream in) { - return new MessagePacker(new OutputStreamBufferOutput(out), config); + return defaultFactory.newUnpacker(in); } /** - * Create a MessagePacker that outputs the packed data to the specified channel + * Equivalent to getDefaultFactory().newUnpacker(channel). * * @param channel + * @return */ - public MessagePacker newPacker(WritableByteChannel channel) - { - return new MessagePacker(new ChannelBufferOutput(channel), config); - } - - /** - * Create a MessageUnpacker that reads data from the given InputStream. - * For reading data efficiently from byte[], use {@link MessageUnpacker(byte[])} or {@link MessageUnpacker(byte[], int, int)} instead of this constructor. - * - * @param in - */ - public MessageUnpacker newUnpacker(InputStream in) - { - return new MessageUnpacker(InputStreamBufferInput.newBufferInput(in), config); - } - - /** - * Create a MessageUnpacker that reads data from the given ReadableByteChannel. - * - * @param in - */ - public MessageUnpacker newUnpacker(ReadableByteChannel in) + public static MessageUnpacker newDefaultUnpacker(ReadableByteChannel channel) { - return new MessageUnpacker(new ChannelBufferInput(in), config); + return defaultFactory.newUnpacker(channel); } /** - * Create a MessageUnpacker that reads data from the given byte array. + * Equivalent to getDefaultFactory().newUnpacker(contents). * - * @param arr + * @param contents + * @return */ - public MessageUnpacker newUnpacker(byte[] arr) + public static MessageUnpacker newDefaultUnpacker(byte[] contents) { - return new MessageUnpacker(new ArrayBufferInput(arr), config); + return defaultFactory.newUnpacker(contents); } /** - * Create a MessageUnpacker that reads data from the given byte array [offset, offset+length) + * Equivalent to getDefaultFactory().newUnpacker(contents, offset, length). * - * @param arr + * @param contents * @param offset * @param length + * @return */ - public MessageUnpacker newUnpacker(byte[] arr, int offset, int length) + public static MessageUnpacker newDefaultUnpacker(byte[] contents, int offset, int length) { - return new MessageUnpacker(new ArrayBufferInput(arr, offset, length), config); + return defaultFactory.newUnpacker(contents, offset, length); } + + // TODO add convenient methods here to pack/unpack objects with byte array/stream } diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessagePackFactory.java b/msgpack-core/src/main/java/org/msgpack/core/MessagePackFactory.java new file mode 100644 index 000000000..f76df5490 --- /dev/null +++ b/msgpack-core/src/main/java/org/msgpack/core/MessagePackFactory.java @@ -0,0 +1,203 @@ +// +// MessagePack for Java +// +// 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.core; + +import org.msgpack.core.buffer.ArrayBufferInput; +import org.msgpack.core.buffer.ChannelBufferInput; +import org.msgpack.core.buffer.ChannelBufferOutput; +import org.msgpack.core.buffer.InputStreamBufferInput; +import org.msgpack.core.buffer.OutputStreamBufferOutput; +import org.msgpack.core.buffer.MessageBufferInput; +import org.msgpack.core.buffer.MessageBufferOutput; + +import java.io.InputStream; +import java.io.OutputStream; +import java.nio.channels.WritableByteChannel; +import java.nio.channels.ReadableByteChannel; + +import java.nio.charset.CodingErrorAction; +import static org.msgpack.core.Preconditions.checkArgument; + +public class MessagePackFactory +{ + private int packerSmallStringOptimizationThreshold = 512; + + private boolean unpackAllowStringAsBinary = true; + private boolean unpackAllowBinaryAsString = true; + private CodingErrorAction unpackActionOnMalformedString = CodingErrorAction.REPLACE; + private CodingErrorAction unpackActionOnUnmappableString = CodingErrorAction.REPLACE; + private int unpackStringSizeLimit = Integer.MAX_VALUE; + private int unpackStringDecoderBufferSize = 8192; + + private int inputBufferSize = 16*1024; + private int outputBufferSize = 16*1024; + + public MessagePacker newPacker(OutputStream out) + { + return newPacker(new OutputStreamBufferOutput(out)); + } + + public MessagePacker newPacker(WritableByteChannel channel) + { + return newPacker(new ChannelBufferOutput(channel)); + } + + public MessagePacker newPacker(MessageBufferOutput output) + { + return new MessagePacker(output) + .setSmallStringOptimizationThreshold(packerSmallStringOptimizationThreshold); + } + + public MessageBufferPacker newBufferPacker() + { + return new MessageBufferPacker() + .setSmallStringOptimizationThreshold(packerSmallStringOptimizationThreshold); + } + + public MessageUnpacker newUnpacker(byte[] contents) + { + return newUnpacker(contents, 0, contents.length); + } + + public MessageUnpacker newUnpacker(byte[] contents, int offset, int length) + { + return newUnpacker(new ArrayBufferInput(contents, offset, length)); + } + + public MessageUnpacker newUnpacker(InputStream in) + { + return newUnpacker(new InputStreamBufferInput(in)); + } + + public MessageUnpacker newUnpacker(ReadableByteChannel channel) + { + return newUnpacker(new ChannelBufferInput(channel)); + } + + public MessageUnpacker newUnpacker(MessageBufferInput input) + { + return new MessageUnpacker(input) + .setAllowStringAsBinary(unpackAllowStringAsBinary) + .setAllowBinaryAsString(unpackAllowBinaryAsString) + .setActionOnMalformedString(unpackActionOnMalformedString) + .setActionOnUnmappableString(unpackActionOnUnmappableString) + .setStringSizeLimit(unpackStringSizeLimit) + .setStringDecoderBufferSize(unpackStringDecoderBufferSize); + } + + /** + * Use String.getBytes() for strings smaller than this threshold. + * Note that this parameter is subject to change. + */ + public MessagePackFactory packerSmallStringOptimizationThreshold(int bytes) + { + this.packerSmallStringOptimizationThreshold = bytes; + return this; + } + + public MessagePackFactory unpackAllowStringAsBinary(boolean enabled) + { + this.unpackAllowStringAsBinary = enabled; + return this; + } + + public MessagePackFactory unpackAllowBinaryAsString(boolean enabled) + { + this.unpackAllowBinaryAsString = enabled; + return this; + } + + public MessagePackFactory unpackActionOnMalformedString(CodingErrorAction action) + { + this.unpackActionOnMalformedString = action; + return this; + } + + public MessagePackFactory unpackActionOnUnmappableString(CodingErrorAction action) + { + this.unpackActionOnUnmappableString = action; + return this; + } + + public MessagePackFactory unpackStringSizeLimit(int bytes) + { + this.unpackStringSizeLimit = bytes; + return this; + } + + public MessagePackFactory unpackStringDecoderBufferSize(int bytes) + { + this.unpackStringDecoderBufferSize = bytes; + return this; + } + + public MessagePackFactory inputBufferSize(int bytes) + { + this.inputBufferSize = bytes; + return this; + } + + public MessagePackFactory outputBufferSize(int bytes) + { + this.inputBufferSize = bytes; + return this; + } + + private int getPackerSmallStringOptimizationThreshold() + { + return packerSmallStringOptimizationThreshold; + } + + private boolean getUnpackAllowStringAsBinary() + { + return unpackAllowStringAsBinary; + } + + private boolean getUnpackAllowBinaryAsString() + { + return unpackAllowBinaryAsString; + } + + private CodingErrorAction getUnpackActionOnMalformedString() + { + return unpackActionOnMalformedString; + } + + private CodingErrorAction getUnpackActionOnUnmappableString() + { + return unpackActionOnUnmappableString; + } + + private int getUnpackStringSizeLimit() + { + return unpackStringSizeLimit; + } + + private int getUnpackStringDecoderBufferSize() + { + return unpackStringDecoderBufferSize; + } + + private int getInputBufferSize() + { + return inputBufferSize; + } + + private int getOutputBufferSize() + { + return outputBufferSize; + } +} diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessagePacker.java b/msgpack-core/src/main/java/org/msgpack/core/MessagePacker.java index 11f2fcb5d..a145df162 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/MessagePacker.java +++ b/msgpack-core/src/main/java/org/msgpack/core/MessagePacker.java @@ -29,40 +29,40 @@ import java.nio.charset.CoderResult; import java.nio.charset.CodingErrorAction; -import static org.msgpack.core.MessagePack.Code.ARRAY16; -import static org.msgpack.core.MessagePack.Code.ARRAY32; -import static org.msgpack.core.MessagePack.Code.BIN16; -import static org.msgpack.core.MessagePack.Code.BIN32; -import static org.msgpack.core.MessagePack.Code.BIN8; -import static org.msgpack.core.MessagePack.Code.EXT16; -import static org.msgpack.core.MessagePack.Code.EXT32; -import static org.msgpack.core.MessagePack.Code.EXT8; -import static org.msgpack.core.MessagePack.Code.FALSE; -import static org.msgpack.core.MessagePack.Code.FIXARRAY_PREFIX; -import static org.msgpack.core.MessagePack.Code.FIXEXT1; -import static org.msgpack.core.MessagePack.Code.FIXEXT16; -import static org.msgpack.core.MessagePack.Code.FIXEXT2; -import static org.msgpack.core.MessagePack.Code.FIXEXT4; -import static org.msgpack.core.MessagePack.Code.FIXEXT8; -import static org.msgpack.core.MessagePack.Code.FIXMAP_PREFIX; -import static org.msgpack.core.MessagePack.Code.FIXSTR_PREFIX; -import static org.msgpack.core.MessagePack.Code.FLOAT32; -import static org.msgpack.core.MessagePack.Code.FLOAT64; -import static org.msgpack.core.MessagePack.Code.INT16; -import static org.msgpack.core.MessagePack.Code.INT32; -import static org.msgpack.core.MessagePack.Code.INT64; -import static org.msgpack.core.MessagePack.Code.INT8; -import static org.msgpack.core.MessagePack.Code.MAP16; -import static org.msgpack.core.MessagePack.Code.MAP32; -import static org.msgpack.core.MessagePack.Code.NIL; -import static org.msgpack.core.MessagePack.Code.STR16; -import static org.msgpack.core.MessagePack.Code.STR32; -import static org.msgpack.core.MessagePack.Code.STR8; -import static org.msgpack.core.MessagePack.Code.TRUE; -import static org.msgpack.core.MessagePack.Code.UINT16; -import static org.msgpack.core.MessagePack.Code.UINT32; -import static org.msgpack.core.MessagePack.Code.UINT64; -import static org.msgpack.core.MessagePack.Code.UINT8; +import static org.msgpack.core.MessageFormat.Code.ARRAY16; +import static org.msgpack.core.MessageFormat.Code.ARRAY32; +import static org.msgpack.core.MessageFormat.Code.BIN16; +import static org.msgpack.core.MessageFormat.Code.BIN32; +import static org.msgpack.core.MessageFormat.Code.BIN8; +import static org.msgpack.core.MessageFormat.Code.EXT16; +import static org.msgpack.core.MessageFormat.Code.EXT32; +import static org.msgpack.core.MessageFormat.Code.EXT8; +import static org.msgpack.core.MessageFormat.Code.FALSE; +import static org.msgpack.core.MessageFormat.Code.FIXARRAY_PREFIX; +import static org.msgpack.core.MessageFormat.Code.FIXEXT1; +import static org.msgpack.core.MessageFormat.Code.FIXEXT16; +import static org.msgpack.core.MessageFormat.Code.FIXEXT2; +import static org.msgpack.core.MessageFormat.Code.FIXEXT4; +import static org.msgpack.core.MessageFormat.Code.FIXEXT8; +import static org.msgpack.core.MessageFormat.Code.FIXMAP_PREFIX; +import static org.msgpack.core.MessageFormat.Code.FIXSTR_PREFIX; +import static org.msgpack.core.MessageFormat.Code.FLOAT32; +import static org.msgpack.core.MessageFormat.Code.FLOAT64; +import static org.msgpack.core.MessageFormat.Code.INT16; +import static org.msgpack.core.MessageFormat.Code.INT32; +import static org.msgpack.core.MessageFormat.Code.INT64; +import static org.msgpack.core.MessageFormat.Code.INT8; +import static org.msgpack.core.MessageFormat.Code.MAP16; +import static org.msgpack.core.MessageFormat.Code.MAP32; +import static org.msgpack.core.MessageFormat.Code.NIL; +import static org.msgpack.core.MessageFormat.Code.STR16; +import static org.msgpack.core.MessageFormat.Code.STR32; +import static org.msgpack.core.MessageFormat.Code.STR8; +import static org.msgpack.core.MessageFormat.Code.TRUE; +import static org.msgpack.core.MessageFormat.Code.UINT16; +import static org.msgpack.core.MessageFormat.Code.UINT32; +import static org.msgpack.core.MessageFormat.Code.UINT64; +import static org.msgpack.core.MessageFormat.Code.UINT8; import static org.msgpack.core.Preconditions.checkNotNull; /** @@ -85,9 +85,9 @@ public class MessagePacker implements Closeable { - private final MessagePack.Config config; + private int smallStringOptimizationThreshold = 512; - private MessageBufferOutput out; + protected MessageBufferOutput out; private MessageBuffer buffer; @@ -111,17 +111,17 @@ public class MessagePacker */ public MessagePacker(MessageBufferOutput out) { - this(out, MessagePack.DEFAULT_CONFIG); - } - - public MessagePacker(MessageBufferOutput out, MessagePack.Config config) - { - this.config = checkNotNull(config, "config is null"); this.out = checkNotNull(out, "MessageBufferOutput is null"); this.position = 0; this.totalFlushBytes = 0; } + public MessagePacker setSmallStringOptimizationThreshold(int bytes) + { + this.smallStringOptimizationThreshold = bytes; + return this; + } + /** * Reset output. This method doesn't close the old resource. * @@ -441,7 +441,7 @@ private void packStringByGetBytes(String s) private void prepareEncoder() { if (encoder == null) { - this.encoder = MessagePack.UTF8.newEncoder().onMalformedInput(config.actionOnMalFormedInput).onUnmappableCharacter(config.actionOnMalFormedInput); + this.encoder = MessagePack.UTF8.newEncoder(); } } @@ -482,7 +482,7 @@ public MessagePacker packString(String s) packRawStringHeader(0); return this; } - else if (s.length() < config.packerSmallStringOptimizationThreshold) { + else if (s.length() < smallStringOptimizationThreshold) { // Write the length and payload of small string to the buffer so that it avoids an extra flush of buffer packStringByGetBytes(s); return this; diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java b/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java index 9b8e159bc..7e54d5253 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java +++ b/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java @@ -15,7 +15,7 @@ // package org.msgpack.core; -import org.msgpack.core.MessagePack.Code; +import org.msgpack.core.MessageFormat.Code; import org.msgpack.core.buffer.MessageBuffer; import org.msgpack.core.buffer.MessageBufferInput; import org.msgpack.value.ImmutableValue; @@ -48,7 +48,7 @@ *

*

  * 
- *     MessageUnpacker unpacker = MessagePackFactory.DEFAULT.newUnpacker(...);
+ *     MessageUnpacker unpacker = MessagePack.newDefaultUnpacker(...);
  *     while(unpacker.hasNext()) {
  *         MessageFormat f = unpacker.getNextFormat();
  *         switch(f) {
@@ -76,7 +76,12 @@ public class MessageUnpacker
 
     private static final byte HEAD_BYTE_REQUIRED = (byte) 0xc1;
 
-    private final MessagePack.Config config;
+    private boolean allowStringAsBinary = true;
+    private boolean allowBinaryAsString = true;
+    private CodingErrorAction actionOnMalformedString = CodingErrorAction.REPLACE;
+    private CodingErrorAction actionOnUnmappableString = CodingErrorAction.REPLACE;
+    private int stringSizeLimit = Integer.MAX_VALUE;
+    private int stringDecoderBufferSize = 8192;
 
     private MessageBufferInput in;
 
@@ -135,20 +140,43 @@ public class MessageUnpacker
      */
     public MessageUnpacker(MessageBufferInput in)
     {
-        this(in, MessagePack.DEFAULT_CONFIG);
+        this.in = checkNotNull(in, "MessageBufferInput is null");
     }
 
-    /**
-     * Create an MessageUnpacker
-     *
-     * @param in
-     * @param config configuration
-     */
-    public MessageUnpacker(MessageBufferInput in, MessagePack.Config config)
+    public MessageUnpacker setAllowStringAsBinary(boolean enabled)
     {
-        // Root constructor. All of the constructors must call this constructor.
-        this.in = checkNotNull(in, "MessageBufferInput is null");
-        this.config = checkNotNull(config, "Config");
+        this.allowStringAsBinary = enabled;
+        return this;
+    }
+
+    public MessageUnpacker setAllowBinaryAsString(boolean enabled)
+    {
+        this.allowBinaryAsString = enabled;
+        return this;
+    }
+
+    public MessageUnpacker setActionOnMalformedString(CodingErrorAction action)
+    {
+        this.actionOnMalformedString = action;
+        return this;
+    }
+
+    public MessageUnpacker setActionOnUnmappableString(CodingErrorAction action)
+    {
+        this.actionOnUnmappableString = action;
+        return this;
+    }
+
+    public MessageUnpacker setStringSizeLimit(int bytes)
+    {
+        this.stringSizeLimit = bytes;
+        return this;
+    }
+
+    public MessageUnpacker setStringDecoderBufferSize(int bytes)
+    {
+        this.stringDecoderBufferSize = bytes;
+        return this;
     }
 
     /**
@@ -958,10 +986,10 @@ public double unpackDouble()
     private void resetDecoder()
     {
         if (decoder == null) {
-            decodeBuffer = CharBuffer.allocate(config.stringDecoderBufferSize);
+            decodeBuffer = CharBuffer.allocate(stringDecoderBufferSize);
             decoder = MessagePack.UTF8.newDecoder()
-                    .onMalformedInput(config.actionOnMalFormedInput)
-                    .onUnmappableCharacter(config.actionOnUnmappableCharacter);
+                    .onMalformedInput(actionOnMalformedString)
+                    .onUnmappableCharacter(actionOnUnmappableString);
         }
         else {
             decoder.reset();
@@ -980,8 +1008,8 @@ public String unpackString()
             if (len == 0) {
                 return EMPTY_STRING;
             }
-            if (len > config.maxUnpackStringSize) {
-                throw new MessageSizeException(String.format("cannot unpack a String of size larger than %,d: %,d", config.maxUnpackStringSize, len), len);
+            if (len > stringSizeLimit) {
+                throw new MessageSizeException(String.format("cannot unpack a String of size larger than %,d: %,d", stringSizeLimit, len), len);
             }
             if (buffer.size() - position >= len) {
                 return decodeStringFastPath(len);
@@ -1069,16 +1097,16 @@ else if (bufferRemaining == 0) {
     private void handleCoderError(CoderResult cr)
         throws CharacterCodingException
     {
-        if ((cr.isMalformed() && config.actionOnMalFormedInput == CodingErrorAction.REPORT) ||
-                (cr.isUnmappable() && config.actionOnUnmappableCharacter == CodingErrorAction.REPORT)) {
+        if ((cr.isMalformed() && actionOnMalformedString == CodingErrorAction.REPORT) ||
+                (cr.isUnmappable() && actionOnUnmappableString == CodingErrorAction.REPORT)) {
             cr.throwException();
         }
     }
 
     private String decodeStringFastPath(int length)
     {
-        if (config.actionOnMalFormedInput == CodingErrorAction.REPLACE &&
-                config.actionOnUnmappableCharacter == CodingErrorAction.REPLACE &&
+        if (actionOnMalformedString == CodingErrorAction.REPLACE &&
+                actionOnUnmappableString == CodingErrorAction.REPLACE &&
                 buffer.hasArray()) {
             String s = new String(buffer.getArray(), buffer.offset() + position, length, MessagePack.UTF8);
             position += length;
@@ -1253,7 +1281,7 @@ public int unpackRawStringHeader()
             return len;
         }
 
-        if (config.readBinaryAsString) {
+        if (allowBinaryAsString) {
             len = tryReadBinaryHeader(b);
             if (len >= 0) {
                 resetHeadByte();
@@ -1277,7 +1305,7 @@ public int unpackBinaryHeader()
             return len;
         }
 
-        if (config.readStringAsBinary) {
+        if (allowStringAsBinary) {
             len = tryReadStringHeader(b);
             if (len >= 0) {
                 resetHeadByte();
diff --git a/msgpack-core/src/main/java/org/msgpack/core/buffer/ArrayBufferOutput.java b/msgpack-core/src/main/java/org/msgpack/core/buffer/ArrayBufferOutput.java
new file mode 100644
index 000000000..710013153
--- /dev/null
+++ b/msgpack-core/src/main/java/org/msgpack/core/buffer/ArrayBufferOutput.java
@@ -0,0 +1,136 @@
+//
+// MessagePack for Java
+//
+//    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.core.buffer;
+
+import java.util.List;
+import java.util.ArrayList;
+
+/**
+ * MessageBufferOutput adapter that packs data into list of byte arrays.
+ */
+public class ArrayBufferOutput
+        implements MessageBufferOutput
+{
+    private List list;
+    private MessageBuffer lastBuffer;
+    private int bufferSize;
+
+    public ArrayBufferOutput()
+    {
+        this(8192);
+    }
+
+    public ArrayBufferOutput(int bufferSize)
+    {
+        this.bufferSize = bufferSize;
+        this.list = new ArrayList();
+    }
+
+    public int getSize()
+    {
+        int size = 0;
+        for (MessageBuffer buffer : list) {
+            size += buffer.size();
+        }
+        return size;
+    }
+
+    public byte[] toByteArray()
+    {
+        byte[] data = new byte[getSize()];
+        int off = 0;
+        for (MessageBuffer buffer : list) {
+            buffer.getBytes(0, data, off, buffer.size());
+            off += buffer.size();
+        }
+        return data;
+    }
+
+    public MessageBuffer toMessageBuffer()
+    {
+        if (list.size() == 1) {
+            return list.get(0);
+        }
+        else if (list.isEmpty()) {
+            return MessageBuffer.newBuffer(0);
+        }
+        else {
+            return MessageBuffer.wrap(toByteArray());
+        }
+    }
+
+    public List toBufferList()
+    {
+        return new ArrayList(list);
+    }
+
+    /**
+     * Clears the internal buffers
+     */
+    public void clear()
+    {
+        list.clear();
+    }
+
+    @Override
+    public MessageBuffer next(int mimimumSize)
+    {
+        if (lastBuffer != null && lastBuffer.size() > mimimumSize) {
+            return lastBuffer;
+        }
+        else {
+            int size = Math.max(bufferSize, mimimumSize);
+            MessageBuffer buffer = MessageBuffer.newBuffer(size);
+            lastBuffer = buffer;
+            return buffer;
+        }
+    }
+
+    @Override
+    public void writeBuffer(int length)
+    {
+        list.add(lastBuffer.slice(0, length));
+        if (lastBuffer.size() - length > bufferSize / 4) {
+            lastBuffer = lastBuffer.slice(length, lastBuffer.size() - length);
+        }
+        else {
+            lastBuffer = null;
+        }
+    }
+
+    @Override
+    public void write(byte[] buffer, int offset, int length)
+    {
+        MessageBuffer copy = MessageBuffer.newBuffer(length);
+        copy.putBytes(0, buffer, offset, length);
+        list.add(copy);
+    }
+
+    @Override
+    public void add(byte[] buffer, int offset, int length)
+    {
+        MessageBuffer wrapped = MessageBuffer.wrap(buffer, offset, length);
+        list.add(wrapped);
+    }
+
+    @Override
+    public void close()
+    { }
+
+    @Override
+    public void flush()
+    { }
+}
diff --git a/msgpack-core/src/test/java/org/msgpack/core/example/MessagePackExample.java b/msgpack-core/src/test/java/org/msgpack/core/example/MessagePackExample.java
index 7636742e0..d7dffe64b 100644
--- a/msgpack-core/src/test/java/org/msgpack/core/example/MessagePackExample.java
+++ b/msgpack-core/src/test/java/org/msgpack/core/example/MessagePackExample.java
@@ -17,6 +17,7 @@
 
 import org.msgpack.core.MessageFormat;
 import org.msgpack.core.MessagePack;
+import org.msgpack.core.MessagePackFactory;
 import org.msgpack.core.MessagePacker;
 import org.msgpack.core.MessageUnpacker;
 import org.msgpack.value.ArrayValue;
@@ -246,24 +247,22 @@ public static void configuration()
             throws IOException
     {
         // Build a conifiguration
-        MessagePack.Config config = new MessagePack.ConfigBuilder()
-                .onMalFormedInput(CodingErrorAction.REPLACE)         // Drop malformed and unmappable UTF-8 characters
-                .onUnmappableCharacter(CodingErrorAction.REPLACE)
-                .packerBufferSize(8192 * 2)
-                .build();
+        MessagePackFactory factory = new MessagePackFactory()
+                .unpackActionOnMalformedString(CodingErrorAction.REPLACE)         // Drop malformed and unmappable UTF-8 characters
+                .unpackActionOnUnmappableString(CodingErrorAction.REPLACE)
+                .outputBufferSize(8192 * 2);
         // Create a  that uses this configuration
-        MessagePack msgpack = new MessagePack(config);
 
         // Pack data
         ByteArrayOutputStream out = new ByteArrayOutputStream();
-        MessagePacker packer = msgpack.newPacker(out);
+        MessagePacker packer = factory.newPacker(out);
         packer.packInt(10);
         packer.packBoolean(true);
         packer.close();
 
         // Unpack data
         byte[] packedData = out.toByteArray();
-        MessageUnpacker unpacker = msgpack.newUnpacker(packedData);
+        MessageUnpacker unpacker = factory.newUnpacker(packedData);
         int i = unpacker.unpackInt();  // 10
         boolean b = unpacker.unpackBoolean(); // true
         unpacker.close();
diff --git a/msgpack-core/src/test/scala/org/msgpack/core/MessageFormatTest.scala b/msgpack-core/src/test/scala/org/msgpack/core/MessageFormatTest.scala
index be9d270cd..a6a71e2d9 100644
--- a/msgpack-core/src/test/scala/org/msgpack/core/MessageFormatTest.scala
+++ b/msgpack-core/src/test/scala/org/msgpack/core/MessageFormatTest.scala
@@ -15,7 +15,7 @@
 //
 package org.msgpack.core
 
-import org.msgpack.core.MessagePack.Code
+import org.msgpack.core.MessageFormat.Code
 import org.msgpack.value.ValueType
 import org.scalatest.exceptions.TestFailedException
 
diff --git a/msgpack-core/src/test/scala/org/msgpack/core/MessagePackTest.scala b/msgpack-core/src/test/scala/org/msgpack/core/MessagePackTest.scala
index f903cf88d..5cf8ea2e6 100644
--- a/msgpack-core/src/test/scala/org/msgpack/core/MessagePackTest.scala
+++ b/msgpack-core/src/test/scala/org/msgpack/core/MessagePackTest.scala
@@ -20,7 +20,7 @@ import java.math.BigInteger
 import java.nio.CharBuffer
 import java.nio.charset.{CodingErrorAction, UnmappableCharacterException}
 
-import org.msgpack.core.MessagePack.Code
+import org.msgpack.core.MessageFormat.Code
 import org.msgpack.value.{Value, Variable}
 
 import scala.util.Random
@@ -117,17 +117,17 @@ class MessagePackTest extends MessagePackSpec {
     }
 
 
-    def check[A](v: A, pack: MessagePacker => Unit, unpack: MessageUnpacker => A, msgpack: MessagePack = MessagePack.DEFAULT): Unit = {
+    def check[A](v: A, pack: MessagePacker => Unit, unpack: MessageUnpacker => A, factory: MessagePackFactory = new MessagePackFactory()): Unit = {
       var b: Array[Byte] = null
       try {
         val bs = new ByteArrayOutputStream()
-        val packer = msgpack.newPacker(bs)
+        val packer = factory.newPacker(bs)
         pack(packer)
         packer.close()
 
         b = bs.toByteArray
 
-        val unpacker = msgpack.newUnpacker(b)
+        val unpacker = factory.newUnpacker(b)
         val ret = unpack(unpacker)
         ret shouldBe v
       }
@@ -142,16 +142,16 @@ class MessagePackTest extends MessagePackSpec {
     }
 
     def checkException[A](v: A, pack: MessagePacker => Unit, unpack: MessageUnpacker => A,
-                          msgpack: MessagePack = MessagePack.DEFAULT): Unit = {
+                          factory: MessagePackFactory = new MessagePackFactory()): Unit = {
       var b: Array[Byte] = null
       val bs = new ByteArrayOutputStream()
-      val packer = msgpack.newPacker(bs)
+      val packer = factory.newPacker(bs)
       pack(packer)
       packer.close()
 
       b = bs.toByteArray
 
-      val unpacker = msgpack.newUnpacker(b)
+      val unpacker = factory.newUnpacker(b)
       val ret = unpack(unpacker)
 
       fail("cannot not reach here")
@@ -297,11 +297,9 @@ class MessagePackTest extends MessagePackSpec {
       //val unmappableChar = Array[Char](new Character(0xfc0a).toChar)
 
       // Report error on unmappable character
-      val config = new MessagePack.ConfigBuilder()
-        .onMalFormedInput(CodingErrorAction.REPORT)
-        .onUnmappableCharacter(CodingErrorAction.REPORT)
-        .build()
-      val msgpack = new MessagePack(config)
+      val factory = new MessagePackFactory()
+        .unpackActionOnMalformedString(CodingErrorAction.REPORT)
+        .unpackActionOnUnmappableString(CodingErrorAction.REPORT);
 
       for (bytes <- Seq(unmappable)) {
         When("unpacking")
@@ -311,7 +309,7 @@ class MessagePackTest extends MessagePackSpec {
             packer.writePayload(bytes)
           },
           _.unpackString(),
-          msgpack)
+          factory)
         }
         catch {
           case e: MessageStringCodingException => // OK
diff --git a/msgpack-core/src/test/scala/org/msgpack/core/MessagePackerTest.scala b/msgpack-core/src/test/scala/org/msgpack/core/MessagePackerTest.scala
index 967cf07a1..51d411f5f 100644
--- a/msgpack-core/src/test/scala/org/msgpack/core/MessagePackerTest.scala
+++ b/msgpack-core/src/test/scala/org/msgpack/core/MessagePackerTest.scala
@@ -30,10 +30,10 @@ import scala.util.Random
 class MessagePackerTest
   extends MessagePackSpec {
 
-  val msgpack = MessagePack.DEFAULT
+  val factory = new MessagePackFactory()
 
   def verifyIntSeq(answer: Array[Int], packed: Array[Byte]) {
-    val unpacker = msgpack.newUnpacker(packed)
+    val unpacker = factory.newUnpacker(packed)
     val b = Array.newBuilder[Int]
     while (unpacker.hasNext) {
       b += unpacker.unpackInt()
@@ -69,7 +69,7 @@ class MessagePackerTest
 
       val b = new
           ByteArrayOutputStream
-      val packer = msgpack.newPacker(b)
+      val packer = factory.newPacker(b)
       intSeq foreach packer.packInt
       packer.close
       verifyIntSeq(intSeq, b.toByteArray)
@@ -102,7 +102,7 @@ class MessagePackerTest
         block("no-buffer-reset") {
           val out = new
               ByteArrayOutputStream
-          IOUtil.withResource(msgpack.newPacker(out)) { packer =>
+          IOUtil.withResource(factory.newPacker(out)) { packer =>
             for (i <- 0 until N) {
               val outputStream = new
                   ByteArrayOutputStream()
@@ -118,7 +118,7 @@ class MessagePackerTest
         block("buffer-reset") {
           val out = new
               ByteArrayOutputStream
-          IOUtil.withResource(msgpack.newPacker(out)) { packer =>
+          IOUtil.withResource(factory.newPacker(out)) { packer =>
             val bufferOut = new
                 OutputStreamBufferOutput(new
                     ByteArrayOutputStream())
@@ -142,15 +142,14 @@ class MessagePackerTest
 
       // TODO: Refactor this test code to fit other ones.
       def test(bufferSize: Int, stringSize: Int): Boolean = {
-        val msgpack = new
-            MessagePack(new
-                MessagePack.ConfigBuilder().packerBufferSize(bufferSize).build)
+        val factory = new MessagePackFactory()
+            .outputBufferSize(bufferSize);
         val str = "a" * stringSize
         val rawString = ValueFactory.newString(str.getBytes("UTF-8"))
         val array = ValueFactory.newArray(rawString)
         val out = new
             ByteArrayOutputStream()
-        val packer = msgpack.newPacker(out)
+        val packer = factory.newPacker(out)
         packer.packValue(array)
         packer.close()
         out.toByteArray
@@ -266,7 +265,7 @@ class MessagePackerTest
   "compute totalWrittenBytes" in {
     val out = new
         ByteArrayOutputStream
-    val packerTotalWrittenBytes = IOUtil.withResource(msgpack.newPacker(out)) { packer =>
+    val packerTotalWrittenBytes = IOUtil.withResource(factory.newPacker(out)) { packer =>
       packer.packByte(0) // 1
         .packBoolean(true) // 1
         .packShort(12) // 1
diff --git a/msgpack-core/src/test/scala/org/msgpack/core/MessageUnpackerTest.scala b/msgpack-core/src/test/scala/org/msgpack/core/MessageUnpackerTest.scala
index fc03d5680..2611d8c9d 100644
--- a/msgpack-core/src/test/scala/org/msgpack/core/MessageUnpackerTest.scala
+++ b/msgpack-core/src/test/scala/org/msgpack/core/MessageUnpackerTest.scala
@@ -29,11 +29,11 @@ import scala.util.Random
  */
 class MessageUnpackerTest extends MessagePackSpec {
 
-  val msgpack = MessagePack.DEFAULT
+  val factory = new MessagePackFactory()
 
   def testData: Array[Byte] = {
     val out = new ByteArrayOutputStream()
-    val packer = msgpack.newPacker(out)
+    val packer = factory.newPacker(out)
 
     packer
       .packArrayHeader(2)
@@ -55,7 +55,7 @@ class MessageUnpackerTest extends MessagePackSpec {
 
   def testData2: Array[Byte] = {
     val out = new ByteArrayOutputStream()
-    val packer = msgpack.newPacker(out);
+    val packer = factory.newPacker(out);
 
     packer
       .packBoolean(true)
@@ -125,7 +125,7 @@ class MessageUnpackerTest extends MessagePackSpec {
   def testData3(N: Int): Array[Byte] = {
 
     val out = new ByteArrayOutputStream()
-    val packer = msgpack.newPacker(out)
+    val packer = factory.newPacker(out)
 
     val r = new Random(0)
 
@@ -179,7 +179,7 @@ class MessageUnpackerTest extends MessagePackSpec {
     "parse message packed data" taggedAs ("unpack") in {
       val arr = testData
 
-      val unpacker = msgpack.newUnpacker(arr)
+      val unpacker = factory.newUnpacker(arr)
 
       var count = 0
       while (unpacker.hasNext) {
@@ -192,7 +192,7 @@ class MessageUnpackerTest extends MessagePackSpec {
 
     "skip reading values" in {
 
-      val unpacker = msgpack.newUnpacker(testData)
+      val unpacker = factory.newUnpacker(testData)
       var skipCount = 0
       while (unpacker.hasNext) {
         unpacker.skipValue()
@@ -209,7 +209,7 @@ class MessageUnpackerTest extends MessagePackSpec {
 
       time("skip performance", repeat = 100) {
         block("switch") {
-          val unpacker = msgpack.newUnpacker(data)
+          val unpacker = factory.newUnpacker(data)
           var skipCount = 0
           while (unpacker.hasNext) {
             unpacker.skipValue()
@@ -227,7 +227,7 @@ class MessageUnpackerTest extends MessagePackSpec {
 
       val ib = Seq.newBuilder[Int]
 
-      val unpacker = msgpack.newUnpacker(testData2)
+      val unpacker = factory.newUnpacker(testData2)
       while (unpacker.hasNext) {
         val f = unpacker.getNextFormat
         f.getValueType match {
@@ -269,7 +269,7 @@ class MessageUnpackerTest extends MessagePackSpec {
       trait SplitTest {
         val data: Array[Byte]
         def run {
-          val unpacker = msgpack.newUnpacker(data)
+          val unpacker = factory.newUnpacker(data)
           val numElems = {
             var c = 0
             while (unpacker.hasNext) {
@@ -326,7 +326,7 @@ class MessageUnpackerTest extends MessagePackSpec {
         }
 
         block("v7") {
-          val unpacker = msgpack.newUnpacker(data)
+          val unpacker = factory.newUnpacker(data)
           var count = 0
           try {
             while (unpacker.hasNext) {
@@ -428,7 +428,7 @@ class MessageUnpackerTest extends MessagePackSpec {
         }
 
         block("v7") {
-          val unpacker = msgpack.newUnpacker(data)
+          val unpacker = factory.newUnpacker(data)
           var count = 0
           try {
             while (unpacker.hasNext) {
@@ -449,7 +449,7 @@ class MessageUnpackerTest extends MessagePackSpec {
     "be faster for reading binary than v6" taggedAs ("cmp-binary") in {
 
       val bos = new ByteArrayOutputStream()
-      val packer = msgpack.newPacker(bos)
+      val packer = factory.newPacker(bos)
       val L = 10000
       val R = 100
       (0 until R).foreach { i =>
@@ -472,7 +472,7 @@ class MessageUnpackerTest extends MessagePackSpec {
         }
 
         block("v7") {
-          val unpacker = msgpack.newUnpacker(b)
+          val unpacker = factory.newUnpacker(b)
           var i = 0
           while (i < R) {
             val len = unpacker.unpackBinaryHeader()
@@ -484,7 +484,7 @@ class MessageUnpackerTest extends MessagePackSpec {
         }
 
         block("v7-ref") {
-          val unpacker = msgpack.newUnpacker(b)
+          val unpacker = factory.newUnpacker(b)
           var i = 0
           while (i < R) {
             val len = unpacker.unpackBinaryHeader()
@@ -505,12 +505,12 @@ class MessageUnpackerTest extends MessagePackSpec {
         val data = new Array[Byte](s)
         Random.nextBytes(data)
         val b = new ByteArrayOutputStream()
-        val packer = msgpack.newPacker(b)
+        val packer = factory.newPacker(b)
         packer.packBinaryHeader(s)
         packer.writePayload(data)
         packer.close()
 
-        val unpacker = msgpack.newUnpacker(b.toByteArray)
+        val unpacker = factory.newUnpacker(b.toByteArray)
         val len = unpacker.unpackBinaryHeader()
         len shouldBe s
         val ref = unpacker.readPayloadAsReference(len)
@@ -529,7 +529,7 @@ class MessageUnpackerTest extends MessagePackSpec {
 
       val data = intSeq
       val b = createMessagePackData(packer => data foreach packer.packInt)
-      val unpacker = msgpack.newUnpacker(b)
+      val unpacker = factory.newUnpacker(b)
 
       val unpacked = Array.newBuilder[Int]
       while (unpacker.hasNext) {
@@ -564,7 +564,7 @@ class MessageUnpackerTest extends MessagePackSpec {
     "improve the performance via reset method" taggedAs ("reset-arr") in {
 
       val out = new ByteArrayOutputStream
-      val packer = msgpack.newPacker(out)
+      val packer = factory.newPacker(out)
       packer.packInt(0)
       packer.flush
       val arr = out.toByteArray
@@ -573,7 +573,7 @@ class MessageUnpackerTest extends MessagePackSpec {
       val N = 1000
       val t = time("unpacker", repeat = 10) {
         block("no-buffer-reset") {
-          IOUtil.withResource(msgpack.newUnpacker(arr)) { unpacker =>
+          IOUtil.withResource(factory.newUnpacker(arr)) { unpacker =>
             for (i <- 0 until N) {
               val buf = new ArrayBufferInput(arr)
               unpacker.reset(buf)
@@ -584,7 +584,7 @@ class MessageUnpackerTest extends MessagePackSpec {
         }
 
         block("reuse-array-input") {
-          IOUtil.withResource(msgpack.newUnpacker(arr)) { unpacker =>
+          IOUtil.withResource(factory.newUnpacker(arr)) { unpacker =>
             val buf = new ArrayBufferInput(arr)
             for (i <- 0 until N) {
               buf.reset(arr)
@@ -596,7 +596,7 @@ class MessageUnpackerTest extends MessagePackSpec {
         }
 
         block("reuse-message-buffer") {
-          IOUtil.withResource(msgpack.newUnpacker(arr)) { unpacker =>
+          IOUtil.withResource(factory.newUnpacker(arr)) { unpacker =>
             val buf = new ArrayBufferInput(arr)
             for (i <- 0 until N) {
               buf.reset(mb)
@@ -640,7 +640,7 @@ class MessageUnpackerTest extends MessagePackSpec {
     "unpack large string data" taggedAs ("large-string") in {
       def createLargeData(stringLength: Int): Array[Byte] = {
         val out = new ByteArrayOutputStream()
-        val packer = msgpack.newPacker(out)
+        val packer = factory.newPacker(out)
 
         packer
           .packArrayHeader(2)
@@ -655,7 +655,7 @@ class MessageUnpackerTest extends MessagePackSpec {
       Seq(8191, 8192, 8193, 16383, 16384, 16385).foreach { n =>
         val arr = createLargeData(n)
 
-        val unpacker = msgpack.newUnpacker(arr)
+        val unpacker = factory.newUnpacker(arr)
 
         unpacker.unpackArrayHeader shouldBe 2
         unpacker.unpackString.length shouldBe n
diff --git a/msgpack-core/src/test/scala/org/msgpack/core/buffer/MessageBufferInputTest.scala b/msgpack-core/src/test/scala/org/msgpack/core/buffer/MessageBufferInputTest.scala
index d7ebeac84..b6ee7bf08 100644
--- a/msgpack-core/src/test/scala/org/msgpack/core/buffer/MessageBufferInputTest.scala
+++ b/msgpack-core/src/test/scala/org/msgpack/core/buffer/MessageBufferInputTest.scala
@@ -135,10 +135,8 @@ class MessageBufferInputTest
 
   def createTempFileWithInputStream = {
     val f = createTempFile
-    val out = new
-        FileOutputStream(f)
-    new
-        MessagePack().newPacker(out).packInt(42).close
+    val out = new FileOutputStream(f)
+    MessagePack.newDefaultPacker(out).packInt(42).close
     val in = new
         FileInputStream(f)
     (f, in)
diff --git a/msgpack-core/src/test/scala/org/msgpack/value/ValueTypeTest.scala b/msgpack-core/src/test/scala/org/msgpack/value/ValueTypeTest.scala
index 6634ef606..2bd1c7b14 100644
--- a/msgpack-core/src/test/scala/org/msgpack/value/ValueTypeTest.scala
+++ b/msgpack-core/src/test/scala/org/msgpack/value/ValueTypeTest.scala
@@ -15,7 +15,7 @@
 //
 package org.msgpack.value
 
-import org.msgpack.core.MessagePack.Code._
+import org.msgpack.core.MessageFormat.Code._
 import org.msgpack.core.{MessageFormat, MessageFormatException, MessagePackSpec}
 
 /**

From b662828b3f9c70a8137e4ba50a21b9ac53eb0b80 Mon Sep 17 00:00:00 2001
From: Sadayuki Furuhashi 
Date: Fri, 25 Dec 2015 15:51:57 +0900
Subject: [PATCH 188/234] removed support for ByteBuffer

---
 .../java/org/msgpack/core/MessagePack.java    |   2 -
 .../java/org/msgpack/core/MessagePacker.java  |   2 +-
 .../org/msgpack/core/MessageUnpacker.java     |  10 +-
 .../core/buffer/ArrayBufferOutput.java        |   6 +-
 .../msgpack/core/buffer/ByteBufferInput.java  |  70 --------
 .../core/buffer/ChannelBufferInput.java       |   4 +-
 .../core/buffer/ChannelBufferOutput.java      |   6 +-
 .../msgpack/core/buffer/MessageBuffer.java    | 150 +++---------------
 .../msgpack/core/buffer/MessageBufferBE.java  |  15 +-
 .../msgpack/core/buffer/MessageBufferU.java   |  85 +++++-----
 .../core/buffer/OutputStreamBufferOutput.java |   4 +-
 .../msgpack/core/buffer/ByteStringTest.scala  |  15 --
 .../core/buffer/MessageBufferInputTest.scala  |   5 -
 .../core/buffer/MessageBufferTest.scala       |  43 +----
 14 files changed, 91 insertions(+), 326 deletions(-)
 delete mode 100644 msgpack-core/src/main/java/org/msgpack/core/buffer/ByteBufferInput.java

diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessagePack.java b/msgpack-core/src/main/java/org/msgpack/core/MessagePack.java
index 8af53a884..f1bee0774 100644
--- a/msgpack-core/src/main/java/org/msgpack/core/MessagePack.java
+++ b/msgpack-core/src/main/java/org/msgpack/core/MessagePack.java
@@ -133,6 +133,4 @@ public static MessageUnpacker newDefaultUnpacker(byte[] contents, int offset, in
     {
         return defaultFactory.newUnpacker(contents, offset, length);
     }
-
-    // TODO add convenient methods here to pack/unpack objects with byte array/stream
 }
diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessagePacker.java b/msgpack-core/src/main/java/org/msgpack/core/MessagePacker.java
index a145df162..7c71b6807 100644
--- a/msgpack-core/src/main/java/org/msgpack/core/MessagePacker.java
+++ b/msgpack-core/src/main/java/org/msgpack/core/MessagePacker.java
@@ -448,7 +448,7 @@ private void prepareEncoder()
     private int encodeStringToBufferAt(int pos, String s)
     {
         prepareEncoder();
-        ByteBuffer bb = buffer.toByteBuffer(pos, buffer.size() - pos);
+        ByteBuffer bb = buffer.sliceAsByteBuffer(pos, buffer.size() - pos);
         int startPosition = bb.position();
         CharBuffer in = CharBuffer.wrap(s);
         CoderResult cr = encoder.encode(in, bb, true);
diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java b/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java
index 7e54d5253..2e00a5bc3 100644
--- a/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java
+++ b/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java
@@ -106,7 +106,7 @@ public class MessageUnpacker
      * Extra buffer for fixed-length data at the buffer boundary.
      * At most 8-byte buffer (for readLong used by uint 64 and UTF-8 character decoding) is required.
      */
-    private final MessageBuffer castBuffer = MessageBuffer.newBuffer(8);
+    private final MessageBuffer castBuffer = MessageBuffer.allocate(8);
 
     /**
      * Variable by ensureHeader method. Caller of the method should use this variable to read from returned MessageBuffer.
@@ -1032,7 +1032,7 @@ else if (bufferRemaining == 0) {
                     nextBuffer();
                 }
                 else {
-                    ByteBuffer bb = buffer.toByteBuffer(position, bufferRemaining);
+                    ByteBuffer bb = buffer.sliceAsByteBuffer(position, bufferRemaining);
                     int bbStartPosition = bb.position();
                     decodeBuffer.clear();
 
@@ -1114,7 +1114,7 @@ private String decodeStringFastPath(int length)
         }
         else {
             resetDecoder();
-            ByteBuffer bb = buffer.toByteBuffer();
+            ByteBuffer bb = buffer.sliceAsByteBuffer();
             bb.limit(position + length);
             bb.position(position);
             CharBuffer cb;
@@ -1395,8 +1395,8 @@ public MessageBuffer readPayloadAsReference(int length)
             position += length;
             return slice;
         }
-        MessageBuffer dst = MessageBuffer.newBuffer(length);
-        readPayload(dst.getReference());
+        MessageBuffer dst = MessageBuffer.allocate(length);
+        readPayload(dst.sliceAsByteBuffer());
         return dst;
     }
 
diff --git a/msgpack-core/src/main/java/org/msgpack/core/buffer/ArrayBufferOutput.java b/msgpack-core/src/main/java/org/msgpack/core/buffer/ArrayBufferOutput.java
index 710013153..186a579af 100644
--- a/msgpack-core/src/main/java/org/msgpack/core/buffer/ArrayBufferOutput.java
+++ b/msgpack-core/src/main/java/org/msgpack/core/buffer/ArrayBufferOutput.java
@@ -65,7 +65,7 @@ public MessageBuffer toMessageBuffer()
             return list.get(0);
         }
         else if (list.isEmpty()) {
-            return MessageBuffer.newBuffer(0);
+            return MessageBuffer.allocate(0);
         }
         else {
             return MessageBuffer.wrap(toByteArray());
@@ -93,7 +93,7 @@ public MessageBuffer next(int mimimumSize)
         }
         else {
             int size = Math.max(bufferSize, mimimumSize);
-            MessageBuffer buffer = MessageBuffer.newBuffer(size);
+            MessageBuffer buffer = MessageBuffer.allocate(size);
             lastBuffer = buffer;
             return buffer;
         }
@@ -114,7 +114,7 @@ public void writeBuffer(int length)
     @Override
     public void write(byte[] buffer, int offset, int length)
     {
-        MessageBuffer copy = MessageBuffer.newBuffer(length);
+        MessageBuffer copy = MessageBuffer.allocate(length);
         copy.putBytes(0, buffer, offset, length);
         list.add(copy);
     }
diff --git a/msgpack-core/src/main/java/org/msgpack/core/buffer/ByteBufferInput.java b/msgpack-core/src/main/java/org/msgpack/core/buffer/ByteBufferInput.java
deleted file mode 100644
index 034d8882b..000000000
--- a/msgpack-core/src/main/java/org/msgpack/core/buffer/ByteBufferInput.java
+++ /dev/null
@@ -1,70 +0,0 @@
-//
-// MessagePack for Java
-//
-//    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.core.buffer;
-
-import java.io.IOException;
-import java.nio.ByteBuffer;
-
-import static org.msgpack.core.Preconditions.checkNotNull;
-
-/**
- * {@link MessageBufferInput} adapter for {@link java.nio.ByteBuffer}
- */
-public class ByteBufferInput
-        implements MessageBufferInput
-{
-    private ByteBuffer input;
-    private boolean isRead = false;
-
-    public ByteBufferInput(ByteBuffer input)
-    {
-        this.input = checkNotNull(input, "input ByteBuffer is null");
-    }
-
-    /**
-     * Reset buffer. This method doesn't close the old resource.
-     *
-     * @param input new buffer
-     * @return the old resource
-     */
-    public ByteBuffer reset(ByteBuffer input)
-    {
-        ByteBuffer old = this.input;
-        this.input = input;
-        isRead = false;
-        return old;
-    }
-
-    @Override
-    public MessageBuffer next()
-            throws IOException
-    {
-        if (isRead) {
-            return null;
-        }
-
-        isRead = true;
-        return MessageBuffer.wrap(input);
-    }
-
-    @Override
-    public void close()
-            throws IOException
-    {
-        // Nothing to do
-    }
-
-}
diff --git a/msgpack-core/src/main/java/org/msgpack/core/buffer/ChannelBufferInput.java b/msgpack-core/src/main/java/org/msgpack/core/buffer/ChannelBufferInput.java
index 73dcb5db6..781b7afb9 100644
--- a/msgpack-core/src/main/java/org/msgpack/core/buffer/ChannelBufferInput.java
+++ b/msgpack-core/src/main/java/org/msgpack/core/buffer/ChannelBufferInput.java
@@ -40,7 +40,7 @@ public ChannelBufferInput(ReadableByteChannel channel, int bufferSize)
     {
         this.channel = checkNotNull(channel, "input channel is null");
         checkArgument(bufferSize > 0, "buffer size must be > 0: " + bufferSize);
-        this.m = MessageBuffer.newBuffer(bufferSize);
+        this.m = MessageBuffer.allocate(bufferSize);
     }
 
     /**
@@ -61,7 +61,7 @@ public ReadableByteChannel reset(ReadableByteChannel channel)
     public MessageBuffer next()
             throws IOException
     {
-        ByteBuffer b = m.toByteBuffer();
+        ByteBuffer b = m.sliceAsByteBuffer();
         while (b.remaining() > 0) {
             int ret = channel.read(b);
             if (ret == -1) {
diff --git a/msgpack-core/src/main/java/org/msgpack/core/buffer/ChannelBufferOutput.java b/msgpack-core/src/main/java/org/msgpack/core/buffer/ChannelBufferOutput.java
index b981cc95d..32969f29a 100644
--- a/msgpack-core/src/main/java/org/msgpack/core/buffer/ChannelBufferOutput.java
+++ b/msgpack-core/src/main/java/org/msgpack/core/buffer/ChannelBufferOutput.java
@@ -38,7 +38,7 @@ public ChannelBufferOutput(WritableByteChannel channel)
     public ChannelBufferOutput(WritableByteChannel channel, int bufferSize)
     {
         this.channel = checkNotNull(channel, "output channel is null");
-        this.buffer = MessageBuffer.newBuffer(bufferSize);
+        this.buffer = MessageBuffer.allocate(bufferSize);
     }
 
     /**
@@ -60,7 +60,7 @@ public MessageBuffer next(int mimimumSize)
             throws IOException
     {
         if (buffer.size() < mimimumSize) {
-            buffer = MessageBuffer.newBuffer(mimimumSize);
+            buffer = MessageBuffer.allocate(mimimumSize);
         }
         return buffer;
     }
@@ -69,7 +69,7 @@ public MessageBuffer next(int mimimumSize)
     public void writeBuffer(int length)
             throws IOException
     {
-        ByteBuffer bb = buffer.toByteBuffer(0, length);
+        ByteBuffer bb = buffer.sliceAsByteBuffer(0, length);
         while (bb.hasRemaining()) {
             channel.write(bb);
         }
diff --git a/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBuffer.java b/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBuffer.java
index fce8020ce..e2258265e 100644
--- a/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBuffer.java
+++ b/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBuffer.java
@@ -39,11 +39,11 @@ public class MessageBuffer
 {
     static final boolean isUniversalBuffer;
     static final Unsafe unsafe;
+
     /**
      * Reference to MessageBuffer Constructors
      */
     private static final Constructor mbArrConstructor;
-    private static final Constructor mbBBConstructor;
 
     /**
      * The offset from the object memory header to its byte array data
@@ -143,14 +143,9 @@ public class MessageBuffer
                 Class bufferCls = Class.forName(bufferClsName);
 
                 // MessageBufferX(byte[]) constructor
-                Constructor mbArrCstr = bufferCls.getDeclaredConstructor(byte[].class);
+                Constructor mbArrCstr = bufferCls.getDeclaredConstructor(byte[].class, int.class, int.class);
                 mbArrCstr.setAccessible(true);
                 mbArrConstructor = mbArrCstr;
-
-                // MessageBufferX(ByteBuffer) constructor
-                Constructor mbBBCstr = bufferCls.getDeclaredConstructor(ByteBuffer.class);
-                mbBBCstr.setAccessible(true);
-                mbBBConstructor = mbBBCstr;
             }
             catch (Exception e) {
                 e.printStackTrace(System.err);
@@ -176,67 +171,19 @@ public class MessageBuffer
      */
     protected final int size;
 
-    /**
-     * Reference is used to hold a reference to an object that holds the underlying memory so that it cannot be
-     * released by the garbage collector.
-     */
-    protected final ByteBuffer reference;
-
-    static MessageBuffer newOffHeapBuffer(int length)
-    {
-        // This method is not available in Android OS
-        if (!isUniversalBuffer) {
-            long address = unsafe.allocateMemory(length);
-            return new MessageBuffer(address, length);
-        }
-        else {
-            return newDirectBuffer(length);
-        }
-    }
-
-    public static MessageBuffer newDirectBuffer(int length)
-    {
-        ByteBuffer m = ByteBuffer.allocateDirect(length);
-        return newMessageBuffer(m);
-    }
-
-    public static MessageBuffer newBuffer(int length)
+    public static MessageBuffer allocate(int length)
     {
-        return newMessageBuffer(new byte[length]);
+        return wrap(new byte[length]);
     }
 
     public static MessageBuffer wrap(byte[] array)
     {
-        return newMessageBuffer(array);
+        return newMessageBuffer(array, 0, array.length);
     }
 
     public static MessageBuffer wrap(byte[] array, int offset, int length)
     {
-        return newMessageBuffer(array).slice(offset, length);
-    }
-
-    public static MessageBuffer wrap(ByteBuffer bb)
-    {
-        return newMessageBuffer(bb).slice(bb.position(), bb.remaining());
-    }
-
-    /**
-     * Creates a new MessageBuffer instance backed by ByteBuffer
-     *
-     * @param bb
-     * @return
-     */
-    private static MessageBuffer newMessageBuffer(ByteBuffer bb)
-    {
-        checkNotNull(bb);
-        try {
-            // We need to use reflection to create MessageBuffer instances in order to prevent TypeProfile generation for getInt method. TypeProfile will be
-            // generated to resolve one of the method references when two or more classes overrides the method.
-            return (MessageBuffer) mbBBConstructor.newInstance(bb);
-        }
-        catch (Exception e) {
-            throw new RuntimeException(e);
-        }
+        return newMessageBuffer(array, offset, length);
     }
 
     /**
@@ -245,11 +192,11 @@ private static MessageBuffer newMessageBuffer(ByteBuffer bb)
      * @param arr
      * @return
      */
-    private static MessageBuffer newMessageBuffer(byte[] arr)
+    private static MessageBuffer newMessageBuffer(byte[] arr, int off, int len)
     {
         checkNotNull(arr);
         try {
-            return (MessageBuffer) mbArrConstructor.newInstance(arr);
+            return (MessageBuffer) mbArrConstructor.newInstance(arr, off, len);
         }
         catch (Throwable e) {
             throw new RuntimeException(e);
@@ -261,76 +208,31 @@ public static void releaseBuffer(MessageBuffer buffer)
         if (isUniversalBuffer || buffer.base instanceof byte[]) {
             // We have nothing to do. Wait until the garbage-collector collects this array object
         }
-        else if (DirectBufferAccess.isDirectByteBufferInstance(buffer.base)) {
-            DirectBufferAccess.clean(buffer.base);
-        }
         else {
             // Maybe cannot reach here
             unsafe.freeMemory(buffer.address);
         }
     }
 
-    /**
-     * Create a MessageBuffer instance from a given memory address and length
-     *
-     * @param address
-     * @param length
-     */
-    MessageBuffer(long address, int length)
-    {
-        this.base = null;
-        this.address = address;
-        this.size = length;
-        this.reference = null;
-    }
-
-    /**
-     * Create a MessageBuffer instance from a given ByteBuffer instance
-     *
-     * @param bb
-     */
-    MessageBuffer(ByteBuffer bb)
-    {
-        if (bb.isDirect()) {
-            if (isUniversalBuffer) {
-                throw new IllegalStateException("Cannot create MessageBuffer from DirectBuffer");
-            }
-            // Direct buffer or off-heap memory
-            this.base = null;
-            this.address = DirectBufferAccess.getAddress(bb);
-            this.size = bb.capacity();
-            this.reference = bb;
-        }
-        else if (bb.hasArray()) {
-            this.base = bb.array();
-            this.address = ARRAY_BYTE_BASE_OFFSET;
-            this.size = bb.array().length;
-            this.reference = null;
-        }
-        else {
-            throw new IllegalArgumentException("Only the array-backed ByteBuffer or DirectBuffer are supported");
-        }
-    }
-
     /**
      * Create a MessageBuffer instance from an java heap array
      *
      * @param arr
+     * @param offset
+     * @param length
      */
-    MessageBuffer(byte[] arr)
+    MessageBuffer(byte[] arr, int offset, int length)
     {
         this.base = arr;
-        this.address = ARRAY_BYTE_BASE_OFFSET;
-        this.size = arr.length;
-        this.reference = null;
+        this.address = ARRAY_BYTE_BASE_OFFSET + offset;
+        this.size = length;
     }
 
-    MessageBuffer(Object base, long address, int length, ByteBuffer reference)
+    protected MessageBuffer(Object base, long address, int length)
     {
         this.base = base;
         this.address = address;
         this.size = length;
-        this.reference = reference;
     }
 
     /**
@@ -351,7 +253,7 @@ public MessageBuffer slice(int offset, int length)
         }
         else {
             checkArgument(offset + length <= size());
-            return new MessageBuffer(base, address + offset, length, reference);
+            return new MessageBuffer(base, address + offset, length);
         }
     }
 
@@ -411,7 +313,7 @@ public void getBytes(int index, int len, ByteBuffer dst)
         if (dst.remaining() < len) {
             throw new BufferOverflowException();
         }
-        ByteBuffer src = toByteBuffer(index, len);
+        ByteBuffer src = sliceAsByteBuffer(index, len);
         dst.put(src);
     }
 
@@ -499,15 +401,9 @@ else if (src.hasArray()) {
      * @param length
      * @return
      */
-    public ByteBuffer toByteBuffer(int index, int length)
+    public ByteBuffer sliceAsByteBuffer(int index, int length)
     {
-        if (hasArray()) {
-            return ByteBuffer.wrap((byte[]) base, (int) ((address - ARRAY_BYTE_BASE_OFFSET) + index), length);
-        }
-        else {
-            assert (!isUniversalBuffer);
-            return DirectBufferAccess.newByteBuffer(address, index, length, reference);
-        }
+        return ByteBuffer.wrap((byte[]) base, (int) ((address - ARRAY_BYTE_BASE_OFFSET) + index), length);
     }
 
     /**
@@ -515,9 +411,9 @@ public ByteBuffer toByteBuffer(int index, int length)
      *
      * @return
      */
-    public ByteBuffer toByteBuffer()
+    public ByteBuffer sliceAsByteBuffer()
     {
-        return toByteBuffer(0, size());
+        return sliceAsByteBuffer(0, size());
     }
 
     /**
@@ -567,12 +463,6 @@ public int offset()
         }
     }
 
-    @Insecure
-    public ByteBuffer getReference()
-    {
-        return reference;
-    }
-
     /**
      * Copy this buffer contents to another MessageBuffer
      *
diff --git a/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferBE.java b/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferBE.java
index 4fec0cd42..3f5d24976 100644
--- a/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferBE.java
+++ b/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferBE.java
@@ -27,19 +27,14 @@
 public class MessageBufferBE
         extends MessageBuffer
 {
-    MessageBufferBE(ByteBuffer bb)
+    MessageBufferBE(byte[] arr, int offset, int length)
     {
-        super(bb);
+        super(arr, offset, length);
     }
 
-    MessageBufferBE(byte[] arr)
+    private MessageBufferBE(Object base, long address, int length)
     {
-        super(arr);
-    }
-
-    private MessageBufferBE(Object base, long address, int length, ByteBuffer reference)
-    {
-        super(base, address, length, reference);
+        super(base, address, length);
     }
 
     @Override
@@ -50,7 +45,7 @@ public MessageBufferBE slice(int offset, int length)
         }
         else {
             checkArgument(offset + length <= size());
-            return new MessageBufferBE(base, address + offset, length, reference);
+            return new MessageBufferBE(base, address + offset, length);
         }
     }
 
diff --git a/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferU.java b/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferU.java
index 54caa8838..d5b68c1a4 100644
--- a/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferU.java
+++ b/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferU.java
@@ -28,15 +28,18 @@
 public class MessageBufferU
         extends MessageBuffer
 {
-    public MessageBufferU(ByteBuffer bb)
+    private final ByteBuffer wrap;
+
+    MessageBufferU(byte[] arr, int offset, int length)
     {
-        super(null, 0L, bb.capacity(), bb.order(ByteOrder.BIG_ENDIAN));
-        checkNotNull(reference);
+        super(arr, offset, length);
+        this.wrap = ByteBuffer.wrap(arr, offset, length);
     }
 
-    MessageBufferU(byte[] arr)
+    private MessageBufferU(Object base, long address, int length, ByteBuffer wrap)
     {
-        this(ByteBuffer.wrap(arr));
+        super(base, address, length);
+        this.wrap = wrap;
     }
 
     @Override
@@ -48,9 +51,9 @@ public MessageBufferU slice(int offset, int length)
         else {
             checkArgument(offset + length <= size());
             try {
-                reference.position(offset);
-                reference.limit(offset + length);
-                return new MessageBufferU(reference.slice());
+                wrap.position(offset);
+                wrap.limit(offset + length);
+                return new MessageBufferU(base, address + offset, length, wrap.slice());
             }
             finally {
                 resetBufferPosition();
@@ -60,59 +63,59 @@ public MessageBufferU slice(int offset, int length)
 
     private void resetBufferPosition()
     {
-        reference.position(0);
-        reference.limit(size);
+        wrap.position(0);
+        wrap.limit(size);
     }
 
     @Override
     public byte getByte(int index)
     {
-        return reference.get(index);
+        return wrap.get(index);
     }
 
     @Override
     public boolean getBoolean(int index)
     {
-        return reference.get(index) != 0;
+        return wrap.get(index) != 0;
     }
 
     @Override
     public short getShort(int index)
     {
-        return reference.getShort(index);
+        return wrap.getShort(index);
     }
 
     @Override
     public int getInt(int index)
     {
-        return reference.getInt(index);
+        return wrap.getInt(index);
     }
 
     @Override
     public float getFloat(int index)
     {
-        return reference.getFloat(index);
+        return wrap.getFloat(index);
     }
 
     @Override
     public long getLong(int index)
     {
-        return reference.getLong(index);
+        return wrap.getLong(index);
     }
 
     @Override
     public double getDouble(int index)
     {
-        return reference.getDouble(index);
+        return wrap.getDouble(index);
     }
 
     @Override
     public void getBytes(int index, int len, ByteBuffer dst)
     {
         try {
-            reference.position(index);
-            reference.limit(index + len);
-            dst.put(reference);
+            wrap.position(index);
+            wrap.limit(index + len);
+            dst.put(wrap);
         }
         finally {
             resetBufferPosition();
@@ -122,52 +125,52 @@ public void getBytes(int index, int len, ByteBuffer dst)
     @Override
     public void putByte(int index, byte v)
     {
-        reference.put(index, v);
+        wrap.put(index, v);
     }
 
     @Override
     public void putBoolean(int index, boolean v)
     {
-        reference.put(index, v ? (byte) 1 : (byte) 0);
+        wrap.put(index, v ? (byte) 1 : (byte) 0);
     }
 
     @Override
     public void putShort(int index, short v)
     {
-        reference.putShort(index, v);
+        wrap.putShort(index, v);
     }
 
     @Override
     public void putInt(int index, int v)
     {
-        reference.putInt(index, v);
+        wrap.putInt(index, v);
     }
 
     @Override
     public void putFloat(int index, float v)
     {
-        reference.putFloat(index, v);
+        wrap.putFloat(index, v);
     }
 
     @Override
     public void putLong(int index, long l)
     {
-        reference.putLong(index, l);
+        wrap.putLong(index, l);
     }
 
     @Override
     public void putDouble(int index, double v)
     {
-        reference.putDouble(index, v);
+        wrap.putDouble(index, v);
     }
 
     @Override
-    public ByteBuffer toByteBuffer(int index, int length)
+    public ByteBuffer sliceAsByteBuffer(int index, int length)
     {
         try {
-            reference.position(index);
-            reference.limit(index + length);
-            return reference.slice();
+            wrap.position(index);
+            wrap.limit(index + length);
+            return wrap.slice();
         }
         finally {
             resetBufferPosition();
@@ -175,17 +178,17 @@ public ByteBuffer toByteBuffer(int index, int length)
     }
 
     @Override
-    public ByteBuffer toByteBuffer()
+    public ByteBuffer sliceAsByteBuffer()
     {
-        return toByteBuffer(0, size);
+        return sliceAsByteBuffer(0, size);
     }
 
     @Override
     public void getBytes(int index, byte[] dst, int dstOffset, int length)
     {
         try {
-            reference.position(index);
-            reference.get(dst, dstOffset, length);
+            wrap.position(index);
+            wrap.get(dst, dstOffset, length);
         }
         finally {
             resetBufferPosition();
@@ -205,8 +208,8 @@ public void putByteBuffer(int index, ByteBuffer src, int len)
             int prevSrcLimit = src.limit();
             try {
                 src.limit(src.position() + len);
-                reference.position(index);
-                reference.put(src);
+                wrap.position(index);
+                wrap.put(src);
             }
             finally {
                 src.limit(prevSrcLimit);
@@ -218,8 +221,8 @@ public void putByteBuffer(int index, ByteBuffer src, int len)
     public void putBytes(int index, byte[] src, int srcOffset, int length)
     {
         try {
-            reference.position(index);
-            reference.put(src, srcOffset, length);
+            wrap.position(index);
+            wrap.put(src, srcOffset, length);
         }
         finally {
             resetBufferPosition();
@@ -230,8 +233,8 @@ public void putBytes(int index, byte[] src, int srcOffset, int length)
     public void copyTo(int index, MessageBuffer dst, int offset, int length)
     {
         try {
-            reference.position(index);
-            dst.putByteBuffer(offset, reference, length);
+            wrap.position(index);
+            dst.putByteBuffer(offset, wrap, length);
         }
         finally {
             resetBufferPosition();
diff --git a/msgpack-core/src/main/java/org/msgpack/core/buffer/OutputStreamBufferOutput.java b/msgpack-core/src/main/java/org/msgpack/core/buffer/OutputStreamBufferOutput.java
index d6f17c783..f29832b34 100644
--- a/msgpack-core/src/main/java/org/msgpack/core/buffer/OutputStreamBufferOutput.java
+++ b/msgpack-core/src/main/java/org/msgpack/core/buffer/OutputStreamBufferOutput.java
@@ -37,7 +37,7 @@ public OutputStreamBufferOutput(OutputStream out)
     public OutputStreamBufferOutput(OutputStream out, int bufferSize)
     {
         this.out = checkNotNull(out, "output is null");
-        this.buffer = MessageBuffer.newBuffer(bufferSize);
+        this.buffer = MessageBuffer.allocate(bufferSize);
     }
 
     /**
@@ -59,7 +59,7 @@ public MessageBuffer next(int mimimumSize)
             throws IOException
     {
         if (buffer.size() < mimimumSize) {
-            buffer = MessageBuffer.newBuffer(mimimumSize);
+            buffer = MessageBuffer.allocate(mimimumSize);
         }
         return buffer;
     }
diff --git a/msgpack-core/src/test/scala/org/msgpack/core/buffer/ByteStringTest.scala b/msgpack-core/src/test/scala/org/msgpack/core/buffer/ByteStringTest.scala
index 92103dc31..eb78432d2 100644
--- a/msgpack-core/src/test/scala/org/msgpack/core/buffer/ByteStringTest.scala
+++ b/msgpack-core/src/test/scala/org/msgpack/core/buffer/ByteStringTest.scala
@@ -44,19 +44,4 @@ class ByteStringTest
     new
         MessageUnpacker(input).unpackString()
   }
-
-  "Unpacking a ByteString's ByteBuffer" should {
-    "fail with a regular MessageBuffer" in {
-
-      // can't demonstrate with new ByteBufferInput(byteString.asByteBuffer)
-      // as Travis tests run with JDK6 that picks up MessageBufferU
-      a[RuntimeException] shouldBe thrownBy(unpackString(new
-          MessageBuffer(byteString.asByteBuffer)))
-    }
-
-    "succeed with a MessageBufferU" in {
-      unpackString(new
-          MessageBufferU(byteString.asByteBuffer)) shouldBe unpackedString
-    }
-  }
 }
diff --git a/msgpack-core/src/test/scala/org/msgpack/core/buffer/MessageBufferInputTest.scala b/msgpack-core/src/test/scala/org/msgpack/core/buffer/MessageBufferInputTest.scala
index b6ee7bf08..6333e381c 100644
--- a/msgpack-core/src/test/scala/org/msgpack/core/buffer/MessageBufferInputTest.scala
+++ b/msgpack-core/src/test/scala/org/msgpack/core/buffer/MessageBufferInputTest.scala
@@ -97,11 +97,6 @@ class MessageBufferInputTest
           ArrayBufferInput(_))
     }
 
-    "support ByteBuffers" in {
-      runTest(b => new
-          ByteBufferInput(b.toByteBuffer))
-    }
-
     "support InputStreams" taggedAs ("is") in {
       runTest(b =>
         new
diff --git a/msgpack-core/src/test/scala/org/msgpack/core/buffer/MessageBufferTest.scala b/msgpack-core/src/test/scala/org/msgpack/core/buffer/MessageBufferTest.scala
index db4dec659..75ef00a11 100644
--- a/msgpack-core/src/test/scala/org/msgpack/core/buffer/MessageBufferTest.scala
+++ b/msgpack-core/src/test/scala/org/msgpack/core/buffer/MessageBufferTest.scala
@@ -30,14 +30,13 @@ class MessageBufferTest
   "MessageBuffer" should {
 
     "check buffer type" in {
-      val b = MessageBuffer.newBuffer(0)
+      val b = MessageBuffer.allocate(0)
       info(s"MessageBuffer type: ${b.getClass.getName}")
     }
 
     "wrap ByteBuffer considering position and remaining values" taggedAs ("wrap-bb") in {
       val d = Array[Byte](10, 11, 12, 13, 14, 15, 16, 17, 18, 19)
-      val subset = ByteBuffer.wrap(d, 2, 2)
-      val mb = MessageBuffer.wrap(subset)
+      val mb = MessageBuffer.wrap(d, 2, 2)
       mb.getByte(0) shouldBe 12
       mb.size() shouldBe 2
     }
@@ -47,8 +46,7 @@ class MessageBufferTest
       val N = 1000000
       val M = 64 * 1024 * 1024
 
-      val ub = MessageBuffer.newBuffer(M)
-      val ud = MessageBuffer.newDirectBuffer(M)
+      val ub = MessageBuffer.allocate(M)
       val hb = ByteBuffer.allocate(M)
       val db = ByteBuffer.allocateDirect(M)
 
@@ -84,14 +82,6 @@ class MessageBufferTest
           }
         }
 
-        block("unsafe direct") {
-          var i = 0
-          while (i < N) {
-            ud.getInt((i * 4) % M)
-            i += 1
-          }
-        }
-
         block("allocate") {
           var i = 0
           while (i < N) {
@@ -118,14 +108,6 @@ class MessageBufferTest
           }
         }
 
-        block("unsafe direct") {
-          var i = 0
-          while (i < N) {
-            ud.getInt((rs(i) * 4) % M)
-            i += 1
-          }
-        }
-
         block("allocate") {
           var i = 0
           while (i < N) {
@@ -146,11 +128,9 @@ class MessageBufferTest
 
     "convert to ByteBuffer" in {
       for (t <- Seq(
-        MessageBuffer.newBuffer(10),
-        MessageBuffer.newDirectBuffer(10),
-        MessageBuffer.newOffHeapBuffer(10))
+        MessageBuffer.allocate(10))
       ) {
-        val bb = t.toByteBuffer
+        val bb = t.sliceAsByteBuffer
         bb.position shouldBe 0
         bb.limit shouldBe 10
         bb.capacity shouldBe 10
@@ -159,9 +139,7 @@ class MessageBufferTest
 
     "put ByteBuffer on itself" in {
       for (t <- Seq(
-        MessageBuffer.newBuffer(10),
-        MessageBuffer.newDirectBuffer(10),
-        MessageBuffer.newOffHeapBuffer(10))
+        MessageBuffer.allocate(10))
       ) {
         val b = Array[Byte](0x02, 0x03)
         val srcArray = ByteBuffer.wrap(b)
@@ -190,13 +168,6 @@ class MessageBufferTest
         Array[Byte](0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07)
       }
 
-      def prepareDirectBuffer : ByteBuffer = {
-        val directBuffer = ByteBuffer.allocateDirect(prepareBytes.length)
-        directBuffer.put(prepareBytes)
-        directBuffer.flip
-        directBuffer
-      }
-
       def checkSliceAndCopyTo(srcBuffer: MessageBuffer, dstBuffer: MessageBuffer) = {
         val sliced = srcBuffer.slice(2, 5)
 
@@ -220,8 +191,6 @@ class MessageBufferTest
       }
 
       checkSliceAndCopyTo(MessageBuffer.wrap(prepareBytes), MessageBuffer.wrap(prepareBytes))
-      checkSliceAndCopyTo(MessageBuffer.wrap(ByteBuffer.wrap(prepareBytes)), MessageBuffer.wrap(ByteBuffer.wrap(prepareBytes)))
-      checkSliceAndCopyTo(MessageBuffer.wrap(prepareDirectBuffer), MessageBuffer.wrap(prepareDirectBuffer))
     }
   }
 }

From e6811be1b63932ec716cb125fe0c8892ed999c20 Mon Sep 17 00:00:00 2001
From: Sadayuki Furuhashi 
Date: Fri, 25 Dec 2015 16:03:35 +0900
Subject: [PATCH 189/234] MessageBuffer is now always safe to get internal
 array, and exposing base and address become unnecessary

---
 .../java/org/msgpack/core/MessagePacker.java  |  4 +--
 .../org/msgpack/core/MessageUnpacker.java     |  9 +++---
 .../core/{annotations => }/Nullable.java      |  4 +--
 .../java/org/msgpack/core/Preconditions.java  |  1 -
 .../msgpack/core/annotations/Insecure.java    | 23 -------------
 .../msgpack/core/buffer/MessageBuffer.java    | 32 ++-----------------
 .../msgpack/core/buffer/MessageBufferU.java   |  5 ++-
 .../core/buffer/OutputStreamBufferOutput.java |  2 +-
 8 files changed, 16 insertions(+), 64 deletions(-)
 rename msgpack-core/src/main/java/org/msgpack/core/{annotations => }/Nullable.java (91%)
 delete mode 100644 msgpack-core/src/main/java/org/msgpack/core/annotations/Insecure.java

diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessagePacker.java b/msgpack-core/src/main/java/org/msgpack/core/MessagePacker.java
index 7c71b6807..b3fcff5a8 100644
--- a/msgpack-core/src/main/java/org/msgpack/core/MessagePacker.java
+++ b/msgpack-core/src/main/java/org/msgpack/core/MessagePacker.java
@@ -505,7 +505,7 @@ else if (s.length() < (1 << 8)) {
                     }
                     // move 1 byte backward to expand 3-byte header region to 3 bytes
                     buffer.putBytes(position + 3,
-                            buffer.getArray(), buffer.offset() + position + 2, written);
+                            buffer.array(), buffer.arrayOffset() + position + 2, written);
                     // write 3-byte header header
                     buffer.putByte(position++, STR16);
                     buffer.putShort(position, (short) written);
@@ -534,7 +534,7 @@ else if (s.length() < (1 << 16)) {
                     }
                     // move 2 bytes backward to expand 3-byte header region to 5 bytes
                     buffer.putBytes(position + 5,
-                            buffer.getArray(), buffer.offset() + position + 3, written);
+                            buffer.array(), buffer.arrayOffset() + position + 3, written);
                     // write 3-byte header header
                     buffer.putByte(position++, STR32);
                     buffer.putInt(position, written);
diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java b/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java
index 2e00a5bc3..6ef5901f5 100644
--- a/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java
+++ b/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java
@@ -255,8 +255,8 @@ private MessageBuffer readCastBuffer(int length)
 
             // TODO this doesn't work if MessageBuffer is allocated by newDirectBuffer.
             //      add copy method to MessageBuffer to solve this issue.
-            castBuffer.putBytes(0, buffer.getArray(), buffer.offset() + position, remaining);
-            castBuffer.putBytes(remaining, next.getArray(), next.offset(), length - remaining);
+            castBuffer.putBytes(0, buffer.array(), buffer.arrayOffset() + position, remaining);
+            castBuffer.putBytes(remaining, next.array(), next.arrayOffset(), length - remaining);
 
             totalReadBytes += buffer.size();
 
@@ -1106,9 +1106,8 @@ private void handleCoderError(CoderResult cr)
     private String decodeStringFastPath(int length)
     {
         if (actionOnMalformedString == CodingErrorAction.REPLACE &&
-                actionOnUnmappableString == CodingErrorAction.REPLACE &&
-                buffer.hasArray()) {
-            String s = new String(buffer.getArray(), buffer.offset() + position, length, MessagePack.UTF8);
+                actionOnUnmappableString == CodingErrorAction.REPLACE) {
+            String s = new String(buffer.array(), buffer.arrayOffset() + position, length, MessagePack.UTF8);
             position += length;
             return s;
         }
diff --git a/msgpack-core/src/main/java/org/msgpack/core/annotations/Nullable.java b/msgpack-core/src/main/java/org/msgpack/core/Nullable.java
similarity index 91%
rename from msgpack-core/src/main/java/org/msgpack/core/annotations/Nullable.java
rename to msgpack-core/src/main/java/org/msgpack/core/Nullable.java
index 9e7c94fab..b2e7585a5 100644
--- a/msgpack-core/src/main/java/org/msgpack/core/annotations/Nullable.java
+++ b/msgpack-core/src/main/java/org/msgpack/core/Nullable.java
@@ -13,11 +13,11 @@
 //    See the License for the specific language governing permissions and
 //    limitations under the License.
 //
-package org.msgpack.core.annotations;
+package org.msgpack.core;
 
 /**
  * Annotates a field which can be null
  */
-public @interface Nullable
+@interface Nullable
 {
 }
diff --git a/msgpack-core/src/main/java/org/msgpack/core/Preconditions.java b/msgpack-core/src/main/java/org/msgpack/core/Preconditions.java
index e44d97d15..d8f43bcb7 100644
--- a/msgpack-core/src/main/java/org/msgpack/core/Preconditions.java
+++ b/msgpack-core/src/main/java/org/msgpack/core/Preconditions.java
@@ -31,7 +31,6 @@
  */
 package org.msgpack.core;
 
-import org.msgpack.core.annotations.Nullable;
 import org.msgpack.core.annotations.VisibleForTesting;
 
 /**
diff --git a/msgpack-core/src/main/java/org/msgpack/core/annotations/Insecure.java b/msgpack-core/src/main/java/org/msgpack/core/annotations/Insecure.java
deleted file mode 100644
index c8678ae41..000000000
--- a/msgpack-core/src/main/java/org/msgpack/core/annotations/Insecure.java
+++ /dev/null
@@ -1,23 +0,0 @@
-//
-// MessagePack for Java
-//
-//    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.core.annotations;
-
-/**
- * Annotates a code which must be used carefully.
- */
-public @interface Insecure
-{
-}
diff --git a/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBuffer.java b/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBuffer.java
index e2258265e..d4d5f2238 100644
--- a/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBuffer.java
+++ b/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBuffer.java
@@ -15,7 +15,6 @@
 //
 package org.msgpack.core.buffer;
 
-import org.msgpack.core.annotations.Insecure;
 import sun.misc.Unsafe;
 
 import java.lang.reflect.Constructor;
@@ -428,39 +427,14 @@ public byte[] toByteArray()
         return b;
     }
 
-    @Insecure
-    public boolean hasArray()
-    {
-        return base instanceof byte[];
-    }
-
-    @Insecure
-    public byte[] getArray()
+    public byte[] array()
     {
         return (byte[]) base;
     }
 
-    @Insecure
-    public Object getBase()
-    {
-        return base;
-    }
-
-    @Insecure
-    public long getAddress()
+    public int arrayOffset()
     {
-        return address;
-    }
-
-    @Insecure
-    public int offset()
-    {
-        if (hasArray()) {
-            return (int) address - ARRAY_BYTE_BASE_OFFSET;
-        }
-        else {
-            return 0;
-        }
+        return (int) address - ARRAY_BYTE_BASE_OFFSET;
     }
 
     /**
diff --git a/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferU.java b/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferU.java
index d5b68c1a4..151b6cd2e 100644
--- a/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferU.java
+++ b/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferU.java
@@ -33,7 +33,10 @@ public class MessageBufferU
     MessageBufferU(byte[] arr, int offset, int length)
     {
         super(arr, offset, length);
-        this.wrap = ByteBuffer.wrap(arr, offset, length);
+        ByteBuffer bb = ByteBuffer.wrap(arr);
+        bb.position(offset);
+        bb.limit(offset + length);
+        this.wrap = bb.slice();
     }
 
     private MessageBufferU(Object base, long address, int length, ByteBuffer wrap)
diff --git a/msgpack-core/src/main/java/org/msgpack/core/buffer/OutputStreamBufferOutput.java b/msgpack-core/src/main/java/org/msgpack/core/buffer/OutputStreamBufferOutput.java
index f29832b34..08fd3960b 100644
--- a/msgpack-core/src/main/java/org/msgpack/core/buffer/OutputStreamBufferOutput.java
+++ b/msgpack-core/src/main/java/org/msgpack/core/buffer/OutputStreamBufferOutput.java
@@ -68,7 +68,7 @@ public MessageBuffer next(int mimimumSize)
     public void writeBuffer(int length)
             throws IOException
     {
-        write(buffer.getArray(), buffer.offset(), length);
+        write(buffer.array(), buffer.arrayOffset(), length);
     }
 
     @Override

From 4098489fcaf60307315ddaf9897ee7a6097e1a25 Mon Sep 17 00:00:00 2001
From: Mitsunori Komatsu 
Date: Fri, 25 Dec 2015 16:06:29 +0900
Subject: [PATCH 190/234] Remove unused import

---
 .../test/java/org/msgpack/core/example/MessagePackExample.java   | 1 -
 1 file changed, 1 deletion(-)

diff --git a/msgpack-core/src/test/java/org/msgpack/core/example/MessagePackExample.java b/msgpack-core/src/test/java/org/msgpack/core/example/MessagePackExample.java
index d7dffe64b..9a8242591 100644
--- a/msgpack-core/src/test/java/org/msgpack/core/example/MessagePackExample.java
+++ b/msgpack-core/src/test/java/org/msgpack/core/example/MessagePackExample.java
@@ -32,7 +32,6 @@
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.math.BigInteger;
-import java.nio.ByteBuffer;
 import java.nio.charset.CodingErrorAction;
 
 /**

From 6390efce5b1cd0ee380b1f74551d8cbd9e6ff469 Mon Sep 17 00:00:00 2001
From: Sadayuki Furuhashi 
Date: Sat, 26 Dec 2015 18:46:29 +0900
Subject: [PATCH 191/234] renamed
 org.msgpack.jackson.dataformat.MessagePackFactory to MessagePackFormatFactory
 to avoid name confusion

---
 msgpack-jackson/README.md                     |  4 +--
 ...ory.java => MessagePackFormatFactory.java} |  2 +-
 .../ExampleOfTypeInformationSerDe.java        |  2 +-
 .../MessagePackDataformatTestBase.java        |  4 +--
 ...java => MessagePackFormatFactoryTest.java} |  2 +-
 .../dataformat/MessagePackGeneratorTest.java  | 12 +++----
 .../dataformat/MessagePackParserTest.java     | 32 +++++++++----------
 ...gePackDataformatHugeDataBenchmarkTest.java |  6 ++--
 ...essagePackDataformatPojoBenchmarkTest.java |  6 ++--
 9 files changed, 35 insertions(+), 35 deletions(-)
 rename msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/{MessagePackFactory.java => MessagePackFormatFactory.java} (98%)
 rename msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/{MessagePackFactoryTest.java => MessagePackFormatFactoryTest.java} (97%)

diff --git a/msgpack-jackson/README.md b/msgpack-jackson/README.md
index 55ed19233..51435b401 100644
--- a/msgpack-jackson/README.md
+++ b/msgpack-jackson/README.md
@@ -29,10 +29,10 @@ dependencies {
 
 ## Usage
 
-Only thing you need to do is to instantiate MessagePackFactory and pass it to the constructor of ObjectMapper.
+Only thing you need to do is to instantiate MessagePackFormatFactory and pass it to the constructor of ObjectMapper.
 
 ```
-  ObjectMapper objectMapper = new ObjectMapper(new MessagePackFactory());
+  ObjectMapper objectMapper = new ObjectMapper(new MessagePackFormatFactory());
   ExamplePojo orig = new ExamplePojo("komamitsu");
   byte[] bytes = objectMapper.writeValueAsBytes(orig);
   ExamplePojo value = objectMapper.readValue(bytes, ExamplePojo.class);
diff --git a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackFactory.java b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackFormatFactory.java
similarity index 98%
rename from msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackFactory.java
rename to msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackFormatFactory.java
index ff7aa373f..1082e5770 100644
--- a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackFactory.java
+++ b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackFormatFactory.java
@@ -30,7 +30,7 @@
 import java.io.Writer;
 import java.util.Arrays;
 
-public class MessagePackFactory
+public class MessagePackFormatFactory
         extends JsonFactory
 {
     private static final long serialVersionUID = 2578263992015504347L;
diff --git a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/ExampleOfTypeInformationSerDe.java b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/ExampleOfTypeInformationSerDe.java
index 5414b0bdc..6a211b3ae 100644
--- a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/ExampleOfTypeInformationSerDe.java
+++ b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/ExampleOfTypeInformationSerDe.java
@@ -151,7 +151,7 @@ public void test()
             objectContainer.getObjects().put("pi", pi);
         }
 
-        ObjectMapper objectMapper = new ObjectMapper(new MessagePackFactory());
+        ObjectMapper objectMapper = new ObjectMapper(new MessagePackFormatFactory());
         byte[] bytes = objectMapper.writeValueAsBytes(objectContainer);
         ObjectContainer restored = objectMapper.readValue(bytes, ObjectContainer.class);
 
diff --git a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackDataformatTestBase.java b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackDataformatTestBase.java
index 1d5156adc..c9692ebf9 100644
--- a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackDataformatTestBase.java
+++ b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackDataformatTestBase.java
@@ -35,7 +35,7 @@
 
 public class MessagePackDataformatTestBase
 {
-    protected MessagePackFactory factory;
+    protected MessagePackFormatFactory factory;
     protected ByteArrayOutputStream out;
     protected ByteArrayInputStream in;
     protected ObjectMapper objectMapper;
@@ -47,7 +47,7 @@ public class MessagePackDataformatTestBase
     @Before
     public void setup()
     {
-        factory = new MessagePackFactory();
+        factory = new MessagePackFormatFactory();
         objectMapper = new ObjectMapper(factory);
         out = new ByteArrayOutputStream();
         in = new ByteArrayInputStream(new byte[4096]);
diff --git a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackFactoryTest.java b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackFormatFactoryTest.java
similarity index 97%
rename from msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackFactoryTest.java
rename to msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackFormatFactoryTest.java
index 25180f784..f7e5fe045 100644
--- a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackFactoryTest.java
+++ b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackFormatFactoryTest.java
@@ -24,7 +24,7 @@
 
 import static org.junit.Assert.assertEquals;
 
-public class MessagePackFactoryTest
+public class MessagePackFormatFactoryTest
         extends MessagePackDataformatTestBase
 {
     @Test
diff --git a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackGeneratorTest.java b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackGeneratorTest.java
index b88d0d645..de58e4a1a 100644
--- a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackGeneratorTest.java
+++ b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackGeneratorTest.java
@@ -230,7 +230,7 @@ else if (key.equals("num")) {
     public void testMessagePackGeneratorDirectly()
             throws Exception
     {
-        MessagePackFactory messagePackFactory = new MessagePackFactory();
+        MessagePackFormatFactory messagePackFactory = new MessagePackFormatFactory();
         File tempFile = createTempFile();
 
         JsonGenerator generator = messagePackFactory.createGenerator(tempFile, JsonEncoding.UTF8);
@@ -257,7 +257,7 @@ public void testMessagePackGeneratorDirectly()
     public void testWritePrimitives()
             throws Exception
     {
-        MessagePackFactory messagePackFactory = new MessagePackFactory();
+        MessagePackFormatFactory messagePackFactory = new MessagePackFormatFactory();
         File tempFile = createTempFile();
 
         JsonGenerator generator = messagePackFactory.createGenerator(tempFile, JsonEncoding.UTF8);
@@ -280,7 +280,7 @@ public void testWritePrimitives()
     public void testBigDecimal()
             throws IOException
     {
-        ObjectMapper mapper = new ObjectMapper(new MessagePackFactory());
+        ObjectMapper mapper = new ObjectMapper(new MessagePackFormatFactory());
 
         {
             double d0 = 1.23456789;
@@ -328,7 +328,7 @@ public void testEnableFeatureAutoCloseTarget()
             throws IOException
     {
         OutputStream out = createTempFileOutputStream();
-        MessagePackFactory messagePackFactory = new MessagePackFactory();
+        MessagePackFormatFactory messagePackFactory = new MessagePackFormatFactory();
         ObjectMapper objectMapper = new ObjectMapper(messagePackFactory);
         List integers = Arrays.asList(1);
         objectMapper.writeValue(out, integers);
@@ -341,7 +341,7 @@ public void testDisableFeatureAutoCloseTarget()
     {
         File tempFile = createTempFile();
         OutputStream out = new FileOutputStream(tempFile);
-        MessagePackFactory messagePackFactory = new MessagePackFactory();
+        MessagePackFormatFactory messagePackFactory = new MessagePackFormatFactory();
         ObjectMapper objectMapper = new ObjectMapper(messagePackFactory);
         objectMapper.configure(JsonGenerator.Feature.AUTO_CLOSE_TARGET, false);
         List integers = Arrays.asList(1);
@@ -363,7 +363,7 @@ public void testWritePrimitiveObjectViaObjectMapper()
         File tempFile = createTempFile();
         OutputStream out = new FileOutputStream(tempFile);
 
-        ObjectMapper objectMapper = new ObjectMapper(new MessagePackFactory());
+        ObjectMapper objectMapper = new ObjectMapper(new MessagePackFormatFactory());
         objectMapper.configure(JsonGenerator.Feature.AUTO_CLOSE_TARGET, false);
         objectMapper.writeValue(out, 1);
         objectMapper.writeValue(out, "two");
diff --git a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackParserTest.java b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackParserTest.java
index 96af2de32..3321110d4 100644
--- a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackParserTest.java
+++ b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackParserTest.java
@@ -288,7 +288,7 @@ else if (k.equals("child_map_age")) {
     public void testMessagePackParserDirectly()
             throws IOException
     {
-        MessagePackFactory messagePackFactory = new MessagePackFactory();
+        MessagePackFormatFactory factory = new MessagePackFormatFactory();
         File tempFile = File.createTempFile("msgpackTest", "msgpack");
         tempFile.deleteOnExit();
 
@@ -301,7 +301,7 @@ public void testMessagePackParserDirectly()
         packer.packFloat(1.0f);
         packer.close();
 
-        JsonParser parser = messagePackFactory.createParser(tempFile);
+        JsonParser parser = factory.createParser(tempFile);
         assertTrue(parser instanceof MessagePackParser);
 
         JsonToken jsonToken = parser.nextToken();
@@ -354,7 +354,7 @@ public void testMessagePackParserDirectly()
     public void testReadPrimitives()
             throws Exception
     {
-        MessagePackFactory messagePackFactory = new MessagePackFactory();
+        MessagePackFormatFactory factory = new MessagePackFormatFactory();
         File tempFile = createTempFile();
 
         FileOutputStream out = new FileOutputStream(tempFile);
@@ -367,7 +367,7 @@ public void testReadPrimitives()
         packer.writePayload(bytes);
         packer.close();
 
-        JsonParser parser = messagePackFactory.createParser(new FileInputStream(tempFile));
+        JsonParser parser = factory.createParser(new FileInputStream(tempFile));
         assertEquals(JsonToken.VALUE_STRING, parser.nextToken());
         assertEquals("foo", parser.getText());
         assertEquals(JsonToken.VALUE_NUMBER_FLOAT, parser.nextToken());
@@ -396,7 +396,7 @@ public void testBigDecimal()
         packer.packDouble(Double.MIN_NORMAL);
         packer.flush();
 
-        ObjectMapper mapper = new ObjectMapper(new MessagePackFactory());
+        ObjectMapper mapper = new ObjectMapper(new MessagePackFormatFactory());
         mapper.configure(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS, true);
         List objects = mapper.readValue(out.toByteArray(), new TypeReference>() {});
         assertEquals(5, objects.size());
@@ -431,9 +431,9 @@ public void testEnableFeatureAutoCloseSource()
             throws Exception
     {
         File tempFile = createTestFile();
-        MessagePackFactory messagePackFactory = new MessagePackFactory();
+        MessagePackFormatFactory factory = new MessagePackFormatFactory();
         FileInputStream in = new FileInputStream(tempFile);
-        ObjectMapper objectMapper = new ObjectMapper(messagePackFactory);
+        ObjectMapper objectMapper = new ObjectMapper(factory);
         objectMapper.readValue(in, new TypeReference>() {});
         objectMapper.readValue(in, new TypeReference>() {});
     }
@@ -444,7 +444,7 @@ public void testDisableFeatureAutoCloseSource()
     {
         File tempFile = createTestFile();
         FileInputStream in = new FileInputStream(tempFile);
-        ObjectMapper objectMapper = new ObjectMapper(new MessagePackFactory());
+        ObjectMapper objectMapper = new ObjectMapper(new MessagePackFormatFactory());
         objectMapper.configure(JsonParser.Feature.AUTO_CLOSE_SOURCE, false);
         objectMapper.readValue(in, new TypeReference>() {});
         objectMapper.readValue(in, new TypeReference>() {});
@@ -456,7 +456,7 @@ public void testParseBigDecimal()
     {
         ArrayList list = new ArrayList();
         list.add(new BigDecimal(Long.MAX_VALUE));
-        ObjectMapper objectMapper = new ObjectMapper(new MessagePackFactory());
+        ObjectMapper objectMapper = new ObjectMapper(new MessagePackFormatFactory());
         byte[] bytes = objectMapper.writeValueAsBytes(list);
 
         ArrayList result = objectMapper.readValue(
@@ -481,7 +481,7 @@ public void testReadPrimitiveObjectViaObjectMapper()
         packer.close();
 
         FileInputStream in = new FileInputStream(tempFile);
-        ObjectMapper objectMapper = new ObjectMapper(new MessagePackFactory());
+        ObjectMapper objectMapper = new ObjectMapper(new MessagePackFormatFactory());
         objectMapper.configure(JsonParser.Feature.AUTO_CLOSE_SOURCE, false);
         assertEquals("foo", objectMapper.readValue(in, new TypeReference() {}));
         long l = objectMapper.readValue(in, new TypeReference() {});
@@ -511,7 +511,7 @@ public void testBinaryKey()
         packer.packLong(42);
         packer.close();
 
-        ObjectMapper mapper = new ObjectMapper(new MessagePackFactory());
+        ObjectMapper mapper = new ObjectMapper(new MessagePackFormatFactory());
         Map object = mapper.readValue(new FileInputStream(tempFile), new TypeReference>() {});
         assertEquals(2, object.size());
         assertEquals(3.14, object.get("foo"));
@@ -533,7 +533,7 @@ public void testBinaryKeyInNestedObject()
         packer.packInt(1);
         packer.close();
 
-        ObjectMapper mapper = new ObjectMapper(new MessagePackFactory());
+        ObjectMapper mapper = new ObjectMapper(new MessagePackFormatFactory());
         List objects = mapper.readValue(out.toByteArray(), new TypeReference>() {});
         assertEquals(2, objects.size());
         @SuppressWarnings(value = "unchecked")
@@ -555,7 +555,7 @@ public void testByteArrayKey()
         messagePacker.packBinaryHeader(1).writePayload(k1).packInt(3);
         messagePacker.close();
 
-        ObjectMapper objectMapper = new ObjectMapper(new MessagePackFactory());
+        ObjectMapper objectMapper = new ObjectMapper(new MessagePackFormatFactory());
         SimpleModule module = new SimpleModule();
         module.addKeyDeserializer(byte[].class, new KeyDeserializer()
         {
@@ -592,7 +592,7 @@ public void testIntegerKey()
         }
         messagePacker.close();
 
-        ObjectMapper objectMapper = new ObjectMapper(new MessagePackFactory());
+        ObjectMapper objectMapper = new ObjectMapper(new MessagePackFormatFactory());
         SimpleModule module = new SimpleModule();
         module.addKeyDeserializer(Integer.class, new KeyDeserializer()
         {
@@ -623,7 +623,7 @@ public void testFloatKey()
         }
         messagePacker.close();
 
-        ObjectMapper objectMapper = new ObjectMapper(new MessagePackFactory());
+        ObjectMapper objectMapper = new ObjectMapper(new MessagePackFormatFactory());
         SimpleModule module = new SimpleModule();
         module.addKeyDeserializer(Float.class, new KeyDeserializer()
         {
@@ -653,7 +653,7 @@ public void testBooleanKey()
         messagePacker.packBoolean(false).packInt(3);
         messagePacker.close();
 
-        ObjectMapper objectMapper = new ObjectMapper(new MessagePackFactory());
+        ObjectMapper objectMapper = new ObjectMapper(new MessagePackFormatFactory());
         SimpleModule module = new SimpleModule();
         module.addKeyDeserializer(Boolean.class, new KeyDeserializer()
         {
diff --git a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/benchmark/MessagePackDataformatHugeDataBenchmarkTest.java b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/benchmark/MessagePackDataformatHugeDataBenchmarkTest.java
index b3a159111..aaf828439 100644
--- a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/benchmark/MessagePackDataformatHugeDataBenchmarkTest.java
+++ b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/benchmark/MessagePackDataformatHugeDataBenchmarkTest.java
@@ -20,7 +20,7 @@
 import com.fasterxml.jackson.core.type.TypeReference;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import org.junit.Test;
-import org.msgpack.jackson.dataformat.MessagePackFactory;
+import org.msgpack.jackson.dataformat.MessagePackFormatFactory;
 
 import java.io.File;
 import java.io.FileOutputStream;
@@ -34,7 +34,7 @@ public class MessagePackDataformatHugeDataBenchmarkTest
     private static final int COUNT = 6;
     private static final int WARMUP_COUNT = 4;
     private final ObjectMapper origObjectMapper = new ObjectMapper();
-    private final ObjectMapper msgpackObjectMapper = new ObjectMapper(new MessagePackFactory());
+    private final ObjectMapper msgpackObjectMapper = new ObjectMapper(new MessagePackFormatFactory());
     private static final List value;
     private static final byte[] packedByOriginal;
     private static final byte[] packedByMsgPack;
@@ -61,7 +61,7 @@ public class MessagePackDataformatHugeDataBenchmarkTest
         packedByOriginal = bytes;
 
         try {
-            bytes = new ObjectMapper(new MessagePackFactory()).writeValueAsBytes(value);
+            bytes = new ObjectMapper(new MessagePackFormatFactory()).writeValueAsBytes(value);
         }
         catch (JsonProcessingException e) {
             e.printStackTrace();
diff --git a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/benchmark/MessagePackDataformatPojoBenchmarkTest.java b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/benchmark/MessagePackDataformatPojoBenchmarkTest.java
index de2118508..33c5f024c 100644
--- a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/benchmark/MessagePackDataformatPojoBenchmarkTest.java
+++ b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/benchmark/MessagePackDataformatPojoBenchmarkTest.java
@@ -19,7 +19,7 @@
 import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import org.junit.Test;
-import org.msgpack.jackson.dataformat.MessagePackFactory;
+import org.msgpack.jackson.dataformat.MessagePackFormatFactory;
 import static org.msgpack.jackson.dataformat.MessagePackDataformatTestBase.NormalPojo;
 import static org.msgpack.jackson.dataformat.MessagePackDataformatTestBase.Suit;
 
@@ -40,11 +40,11 @@ public class MessagePackDataformatPojoBenchmarkTest
     private static final List pojosSerWithOrig = new ArrayList(LOOP_MAX);
     private static final List pojosSerWithMsgPack = new ArrayList(LOOP_MAX);
     private final ObjectMapper origObjectMapper = new ObjectMapper();
-    private final ObjectMapper msgpackObjectMapper = new ObjectMapper(new MessagePackFactory());
+    private final ObjectMapper msgpackObjectMapper = new ObjectMapper(new MessagePackFormatFactory());
 
     static {
         final ObjectMapper origObjectMapper = new ObjectMapper();
-        final ObjectMapper msgpackObjectMapper = new ObjectMapper(new MessagePackFactory());
+        final ObjectMapper msgpackObjectMapper = new ObjectMapper(new MessagePackFormatFactory());
 
         for (int i = 0; i < LOOP_MAX; i++) {
             NormalPojo pojo = new NormalPojo();

From 9eff0cac5a2099e7c35f2768ef9b744e7025fe84 Mon Sep 17 00:00:00 2001
From: Sadayuki Furuhashi 
Date: Sun, 27 Dec 2015 12:58:18 +0900
Subject: [PATCH 192/234] optimized slightly MessageUnpacker.readCastBuffer

---
 .../org/msgpack/core/MessageUnpacker.java     | 26 ++++++++++++-------
 .../core/buffer/InputStreamBufferInput.java   |  2 +-
 2 files changed, 18 insertions(+), 10 deletions(-)

diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java b/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java
index 6ef5901f5..4dcc69e80 100644
--- a/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java
+++ b/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java
@@ -253,18 +253,26 @@ private MessageBuffer readCastBuffer(int length)
                 throw new MessageInsufficientBufferException();
             }
 
-            // TODO this doesn't work if MessageBuffer is allocated by newDirectBuffer.
-            //      add copy method to MessageBuffer to solve this issue.
-            castBuffer.putBytes(0, buffer.array(), buffer.arrayOffset() + position, remaining);
-            castBuffer.putBytes(remaining, next.array(), next.arrayOffset(), length - remaining);
-
             totalReadBytes += buffer.size();
 
-            buffer = next;
-            position = length - remaining;
-            readCastBufferPosition = 0;
+            if (remaining > 0) {
+                // TODO this doesn't work if MessageBuffer is allocated by newDirectBuffer.
+                //      add copy method to MessageBuffer to solve this issue.
+                castBuffer.putBytes(0, buffer.array(), buffer.arrayOffset() + position, remaining);
+                castBuffer.putBytes(remaining, next.array(), next.arrayOffset(), length - remaining);
+
+                buffer = next;
+                position = length - remaining;
+                readCastBufferPosition = 0;
 
-            return castBuffer;
+                return castBuffer;
+            }
+            else {
+                buffer = next;
+                position = length;
+                readCastBufferPosition = 0;
+                return buffer;
+            }
         }
     }
 
diff --git a/msgpack-core/src/main/java/org/msgpack/core/buffer/InputStreamBufferInput.java b/msgpack-core/src/main/java/org/msgpack/core/buffer/InputStreamBufferInput.java
index ad8aa462f..d605fec3a 100644
--- a/msgpack-core/src/main/java/org/msgpack/core/buffer/InputStreamBufferInput.java
+++ b/msgpack-core/src/main/java/org/msgpack/core/buffer/InputStreamBufferInput.java
@@ -76,7 +76,7 @@ public MessageBuffer next()
         if (readLen == -1) {
             return null;
         }
-        return MessageBuffer.wrap(buffer).slice(0, readLen);
+        return MessageBuffer.wrap(buffer, 0, readLen);
     }
 
     @Override

From ab592c88de05f0bce33124cae8d040b63343257c Mon Sep 17 00:00:00 2001
From: Sadayuki Furuhashi 
Date: Sun, 27 Dec 2015 13:14:25 +0900
Subject: [PATCH 193/234] Gave up repeatable deserialization

Adding support for repeatable to castBuffer seems hard without
performance impact. For now, here removes repeatable read support.
---
 .../org/msgpack/core/MessageUnpacker.java     | 180 ++++--------------
 1 file changed, 38 insertions(+), 142 deletions(-)

diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java b/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java
index 4dcc69e80..ab7b3e496 100644
--- a/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java
+++ b/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java
@@ -118,11 +118,6 @@ public class MessageUnpacker
      */
     private StringBuilder decodeStringBuffer;
 
-    /**
-     * For decoding String in unpackString.
-     */
-    private int readingRawRemaining = 0;
-
     /**
      * For decoding String in unpackString.
      */
@@ -196,7 +191,6 @@ public MessageBufferInput reset(MessageBufferInput in)
         this.buffer = EMPTY_BUFFER;
         this.position = 0;
         this.totalReadBytes = 0;
-        this.readingRawRemaining = 0;
         // No need to initialize the already allocated string decoder here since we can reuse it.
 
         return old;
@@ -207,24 +201,6 @@ public long getTotalReadBytes()
         return totalReadBytes + position;
     }
 
-    private byte getHeadByte()
-            throws IOException
-    {
-        byte b = headByte;
-        if (b == HEAD_BYTE_REQUIRED) {
-            b = headByte = readByte();
-            if (b == HEAD_BYTE_REQUIRED) {
-                throw new MessageNeverUsedFormatException("Encountered 0xC1 \"NEVER_USED\" byte");
-            }
-        }
-        return b;
-    }
-
-    private void resetHeadByte()
-    {
-        headByte = HEAD_BYTE_REQUIRED;
-    }
-
     private void nextBuffer()
             throws IOException
     {
@@ -291,7 +267,7 @@ private static int utf8MultibyteCharacterSize(byte firstByte)
     public boolean hasNext()
             throws IOException
     {
-        if (buffer.size() <= position) {
+        while (buffer.size() <= position) {
             MessageBuffer next = in.next();
             if (next == null) {
                 return false;
@@ -316,13 +292,12 @@ public boolean hasNext()
     public MessageFormat getNextFormat()
             throws IOException
     {
-        try {
-            byte b = getHeadByte();
-            return MessageFormat.valueOf(b);
-        }
-        catch (MessageNeverUsedFormatException ex) {
-            return MessageFormat.NEVER_USED;
+        // makes sure that buffer has at leat 1 byte
+        if (!hasNext()) {
+            throw new MessageInsufficientBufferException();
         }
+        byte b = buffer.getByte(position);
+        return MessageFormat.valueOf(b);
     }
 
     /**
@@ -395,9 +370,8 @@ public void skipValue()
     {
         int remainingValues = 1;
         while (remainingValues > 0) {
-            byte b = getHeadByte();
+            byte b = readByte();
             MessageFormat f = MessageFormat.valueOf(b);
-            resetHeadByte();
             switch (f) {
                 case POSFIXINT:
                 case NEGFIXINT:
@@ -643,9 +617,8 @@ public Variable unpackValue(Variable var)
     public void unpackNil()
             throws IOException
     {
-        byte b = getHeadByte();
+        byte b = readByte();
         if (b == Code.NIL) {
-            resetHeadByte();
             return;
         }
         throw unexpected("Nil", b);
@@ -654,13 +627,11 @@ public void unpackNil()
     public boolean unpackBoolean()
             throws IOException
     {
-        byte b = getHeadByte();
+        byte b = readByte();
         if (b == Code.FALSE) {
-            resetHeadByte();
             return false;
         }
         else if (b == Code.TRUE) {
-            resetHeadByte();
             return true;
         }
         throw unexpected("boolean", b);
@@ -669,61 +640,52 @@ else if (b == Code.TRUE) {
     public byte unpackByte()
             throws IOException
     {
-        byte b = getHeadByte();
+        byte b = readByte();
         if (Code.isFixInt(b)) {
-            resetHeadByte();
             return b;
         }
         switch (b) {
             case Code.UINT8: // unsigned int 8
                 byte u8 = readByte();
-                resetHeadByte();
                 if (u8 < (byte) 0) {
                     throw overflowU8(u8);
                 }
                 return u8;
             case Code.UINT16: // unsigned int 16
                 short u16 = readShort();
-                resetHeadByte();
                 if (u16 < 0 || u16 > Byte.MAX_VALUE) {
                     throw overflowU16(u16);
                 }
                 return (byte) u16;
             case Code.UINT32: // unsigned int 32
                 int u32 = readInt();
-                resetHeadByte();
                 if (u32 < 0 || u32 > Byte.MAX_VALUE) {
                     throw overflowU32(u32);
                 }
                 return (byte) u32;
             case Code.UINT64: // unsigned int 64
                 long u64 = readLong();
-                resetHeadByte();
                 if (u64 < 0L || u64 > Byte.MAX_VALUE) {
                     throw overflowU64(u64);
                 }
                 return (byte) u64;
             case Code.INT8: // signed int 8
                 byte i8 = readByte();
-                resetHeadByte();
                 return i8;
             case Code.INT16: // signed int 16
                 short i16 = readShort();
-                resetHeadByte();
                 if (i16 < Byte.MIN_VALUE || i16 > Byte.MAX_VALUE) {
                     throw overflowI16(i16);
                 }
                 return (byte) i16;
             case Code.INT32: // signed int 32
                 int i32 = readInt();
-                resetHeadByte();
                 if (i32 < Byte.MIN_VALUE || i32 > Byte.MAX_VALUE) {
                     throw overflowI32(i32);
                 }
                 return (byte) i32;
             case Code.INT64: // signed int 64
                 long i64 = readLong();
-                resetHeadByte();
                 if (i64 < Byte.MIN_VALUE || i64 > Byte.MAX_VALUE) {
                     throw overflowI64(i64);
                 }
@@ -735,32 +697,27 @@ public byte unpackByte()
     public short unpackShort()
             throws IOException
     {
-        byte b = getHeadByte();
+        byte b = readByte();
         if (Code.isFixInt(b)) {
-            resetHeadByte();
             return (short) b;
         }
         switch (b) {
             case Code.UINT8: // unsigned int 8
                 byte u8 = readByte();
-                resetHeadByte();
                 return (short) (u8 & 0xff);
             case Code.UINT16: // unsigned int 16
                 short u16 = readShort();
-                resetHeadByte();
                 if (u16 < (short) 0) {
                     throw overflowU16(u16);
                 }
                 return u16;
             case Code.UINT32: // unsigned int 32
                 int u32 = readInt();
-                resetHeadByte();
                 if (u32 < 0 || u32 > Short.MAX_VALUE) {
                     throw overflowU32(u32);
                 }
                 return (short) u32;
             case Code.UINT64: // unsigned int 64
-                resetHeadByte();
                 long u64 = readLong();
                 if (u64 < 0L || u64 > Short.MAX_VALUE) {
                     throw overflowU64(u64);
@@ -768,22 +725,18 @@ public short unpackShort()
                 return (short) u64;
             case Code.INT8: // signed int 8
                 byte i8 = readByte();
-                resetHeadByte();
                 return (short) i8;
             case Code.INT16: // signed int 16
                 short i16 = readShort();
-                resetHeadByte();
                 return i16;
             case Code.INT32: // signed int 32
                 int i32 = readInt();
-                resetHeadByte();
                 if (i32 < Short.MIN_VALUE || i32 > Short.MAX_VALUE) {
                     throw overflowI32(i32);
                 }
                 return (short) i32;
             case Code.INT64: // signed int 64
                 long i64 = readLong();
-                resetHeadByte();
                 if (i64 < Short.MIN_VALUE || i64 > Short.MAX_VALUE) {
                     throw overflowI64(i64);
                 }
@@ -795,49 +748,40 @@ public short unpackShort()
     public int unpackInt()
             throws IOException
     {
-        byte b = getHeadByte();
+        byte b = readByte();
         if (Code.isFixInt(b)) {
-            resetHeadByte();
             return (int) b;
         }
         switch (b) {
             case Code.UINT8: // unsigned int 8
                 byte u8 = readByte();
-                resetHeadByte();
                 return u8 & 0xff;
             case Code.UINT16: // unsigned int 16
                 short u16 = readShort();
-                resetHeadByte();
                 return u16 & 0xffff;
             case Code.UINT32: // unsigned int 32
                 int u32 = readInt();
                 if (u32 < 0) {
                     throw overflowU32(u32);
                 }
-                resetHeadByte();
                 return u32;
             case Code.UINT64: // unsigned int 64
                 long u64 = readLong();
-                resetHeadByte();
                 if (u64 < 0L || u64 > (long) Integer.MAX_VALUE) {
                     throw overflowU64(u64);
                 }
                 return (int) u64;
             case Code.INT8: // signed int 8
                 byte i8 = readByte();
-                resetHeadByte();
                 return i8;
             case Code.INT16: // signed int 16
                 short i16 = readShort();
-                resetHeadByte();
                 return i16;
             case Code.INT32: // signed int 32
                 int i32 = readInt();
-                resetHeadByte();
                 return i32;
             case Code.INT64: // signed int 64
                 long i64 = readLong();
-                resetHeadByte();
                 if (i64 < (long) Integer.MIN_VALUE || i64 > (long) Integer.MAX_VALUE) {
                     throw overflowI64(i64);
                 }
@@ -849,23 +793,19 @@ public int unpackInt()
     public long unpackLong()
             throws IOException
     {
-        byte b = getHeadByte();
+        byte b = readByte();
         if (Code.isFixInt(b)) {
-            resetHeadByte();
             return (long) b;
         }
         switch (b) {
             case Code.UINT8: // unsigned int 8
                 byte u8 = readByte();
-                resetHeadByte();
                 return (long) (u8 & 0xff);
             case Code.UINT16: // unsigned int 16
                 short u16 = readShort();
-                resetHeadByte();
                 return (long) (u16 & 0xffff);
             case Code.UINT32: // unsigned int 32
                 int u32 = readInt();
-                resetHeadByte();
                 if (u32 < 0) {
                     return (long) (u32 & 0x7fffffff) + 0x80000000L;
                 }
@@ -874,26 +814,21 @@ public long unpackLong()
                 }
             case Code.UINT64: // unsigned int 64
                 long u64 = readLong();
-                resetHeadByte();
                 if (u64 < 0L) {
                     throw overflowU64(u64);
                 }
                 return u64;
             case Code.INT8: // signed int 8
                 byte i8 = readByte();
-                resetHeadByte();
                 return (long) i8;
             case Code.INT16: // signed int 16
                 short i16 = readShort();
-                resetHeadByte();
                 return (long) i16;
             case Code.INT32: // signed int 32
                 int i32 = readInt();
-                resetHeadByte();
                 return (long) i32;
             case Code.INT64: // signed int 64
                 long i64 = readLong();
-                resetHeadByte();
                 return i64;
         }
         throw unexpected("Integer", b);
@@ -902,23 +837,19 @@ public long unpackLong()
     public BigInteger unpackBigInteger()
             throws IOException
     {
-        byte b = getHeadByte();
+        byte b = readByte();
         if (Code.isFixInt(b)) {
-            resetHeadByte();
             return BigInteger.valueOf((long) b);
         }
         switch (b) {
             case Code.UINT8: // unsigned int 8
                 byte u8 = readByte();
-                resetHeadByte();
                 return BigInteger.valueOf((long) (u8 & 0xff));
             case Code.UINT16: // unsigned int 16
                 short u16 = readShort();
-                resetHeadByte();
                 return BigInteger.valueOf((long) (u16 & 0xffff));
             case Code.UINT32: // unsigned int 32
                 int u32 = readInt();
-                resetHeadByte();
                 if (u32 < 0) {
                     return BigInteger.valueOf((long) (u32 & 0x7fffffff) + 0x80000000L);
                 }
@@ -927,7 +858,6 @@ public BigInteger unpackBigInteger()
                 }
             case Code.UINT64: // unsigned int 64
                 long u64 = readLong();
-                resetHeadByte();
                 if (u64 < 0L) {
                     BigInteger bi = BigInteger.valueOf(u64 + Long.MAX_VALUE + 1L).setBit(63);
                     return bi;
@@ -937,19 +867,15 @@ public BigInteger unpackBigInteger()
                 }
             case Code.INT8: // signed int 8
                 byte i8 = readByte();
-                resetHeadByte();
                 return BigInteger.valueOf((long) i8);
             case Code.INT16: // signed int 16
                 short i16 = readShort();
-                resetHeadByte();
                 return BigInteger.valueOf((long) i16);
             case Code.INT32: // signed int 32
                 int i32 = readInt();
-                resetHeadByte();
                 return BigInteger.valueOf((long) i32);
             case Code.INT64: // signed int 64
                 long i64 = readLong();
-                resetHeadByte();
                 return BigInteger.valueOf(i64);
         }
         throw unexpected("Integer", b);
@@ -958,15 +884,13 @@ public BigInteger unpackBigInteger()
     public float unpackFloat()
             throws IOException
     {
-        byte b = getHeadByte();
+        byte b = readByte();
         switch (b) {
             case Code.FLOAT32: // float
                 float fv = readFloat();
-                resetHeadByte();
                 return fv;
             case Code.FLOAT64: // double
                 double dv = readDouble();
-                resetHeadByte();
                 return (float) dv;
         }
         throw unexpected("Float", b);
@@ -975,15 +899,13 @@ public float unpackFloat()
     public double unpackDouble()
             throws IOException
     {
-        byte b = getHeadByte();
+        byte b = readByte();
         switch (b) {
             case Code.FLOAT32: // float
                 float fv = readFloat();
-                resetHeadByte();
                 return (double) fv;
             case Code.FLOAT64: // double
                 double dv = readDouble();
-                resetHeadByte();
                 return dv;
         }
         throw unexpected("Float", b);
@@ -1005,35 +927,29 @@ private void resetDecoder()
         decodeStringBuffer = new StringBuilder();
     }
 
-    /**
-     * This method is not repeatable.
-     */
     public String unpackString()
             throws IOException
     {
-        if (readingRawRemaining == 0) {
-            int len = unpackRawStringHeader();
-            if (len == 0) {
-                return EMPTY_STRING;
-            }
-            if (len > stringSizeLimit) {
-                throw new MessageSizeException(String.format("cannot unpack a String of size larger than %,d: %,d", stringSizeLimit, len), len);
-            }
-            if (buffer.size() - position >= len) {
-                return decodeStringFastPath(len);
-            }
-            readingRawRemaining = len;
-            resetDecoder();
+        int len = unpackRawStringHeader();
+        if (len == 0) {
+            return EMPTY_STRING;
+        }
+        if (len > stringSizeLimit) {
+            throw new MessageSizeException(String.format("cannot unpack a String of size larger than %,d: %,d", stringSizeLimit, len), len);
+        }
+        if (buffer.size() - position >= len) {
+            return decodeStringFastPath(len);
         }
 
-        assert (decoder != null);
+        resetDecoder();
 
         try {
-            while (readingRawRemaining > 0) {
+            int rawRemaining = len;
+            while (rawRemaining > 0) {
                 int bufferRemaining = buffer.size() - position;
-                if (bufferRemaining >= readingRawRemaining) {
-                    decodeStringBuffer.append(decodeStringFastPath(readingRawRemaining));
-                    readingRawRemaining = 0;
+                if (bufferRemaining >= rawRemaining) {
+                    decodeStringBuffer.append(decodeStringFastPath(rawRemaining));
+                    rawRemaining = 0;
                     break;
                 }
                 else if (bufferRemaining == 0) {
@@ -1047,7 +963,7 @@ else if (bufferRemaining == 0) {
                     CoderResult cr = decoder.decode(bb, decodeBuffer, false);
                     int readLen = bb.position() - bbStartPosition;
                     position += readLen;
-                    readingRawRemaining -= readLen;
+                    rawRemaining -= readLen;
                     decodeStringBuffer.append(decodeBuffer.flip());
 
                     if (cr.isError()) {
@@ -1090,7 +1006,7 @@ else if (bufferRemaining == 0) {
                                 throw new MessageFormatException("Unexpected UTF-8 multibyte sequence", ex);
                             }
                         }
-                        readingRawRemaining -= multiByteBuffer.limit();
+                        rawRemaining -= multiByteBuffer.limit();
                         decodeStringBuffer.append(decodeBuffer.flip());
                     }
                 }
@@ -1139,20 +1055,17 @@ private String decodeStringFastPath(int length)
     public int unpackArrayHeader()
             throws IOException
     {
-        byte b = getHeadByte();
+        byte b = readByte();
         if (Code.isFixedArray(b)) { // fixarray
-            resetHeadByte();
             return b & 0x0f;
         }
         switch (b) {
             case Code.ARRAY16: { // array 16
                 int len = readNextLength16();
-                resetHeadByte();
                 return len;
             }
             case Code.ARRAY32: { // array 32
                 int len = readNextLength32();
-                resetHeadByte();
                 return len;
             }
         }
@@ -1162,20 +1075,17 @@ public int unpackArrayHeader()
     public int unpackMapHeader()
             throws IOException
     {
-        byte b = getHeadByte();
+        byte b = readByte();
         if (Code.isFixedMap(b)) { // fixmap
-            resetHeadByte();
             return b & 0x0f;
         }
         switch (b) {
             case Code.MAP16: { // map 16
                 int len = readNextLength16();
-                resetHeadByte();
                 return len;
             }
             case Code.MAP32: { // map 32
                 int len = readNextLength32();
-                resetHeadByte();
                 return len;
             }
         }
@@ -1185,36 +1095,30 @@ public int unpackMapHeader()
     public ExtensionTypeHeader unpackExtensionTypeHeader()
             throws IOException
     {
-        byte b = getHeadByte();
+        byte b = readByte();
         switch (b) {
             case Code.FIXEXT1: {
                 byte type = readByte();
-                resetHeadByte();
                 return new ExtensionTypeHeader(type, 1);
             }
             case Code.FIXEXT2: {
                 byte type = readByte();
-                resetHeadByte();
                 return new ExtensionTypeHeader(type, 2);
             }
             case Code.FIXEXT4: {
                 byte type = readByte();
-                resetHeadByte();
                 return new ExtensionTypeHeader(type, 4);
             }
             case Code.FIXEXT8: {
                 byte type = readByte();
-                resetHeadByte();
                 return new ExtensionTypeHeader(type, 8);
             }
             case Code.FIXEXT16: {
                 byte type = readByte();
-                resetHeadByte();
                 return new ExtensionTypeHeader(type, 16);
             }
             case Code.EXT8: {
                 MessageBuffer castBuffer = readCastBuffer(2);
-                resetHeadByte();
                 int u8 = castBuffer.getByte(readCastBufferPosition);
                 int length = u8 & 0xff;
                 byte type = castBuffer.getByte(readCastBufferPosition + 1);
@@ -1222,7 +1126,6 @@ public ExtensionTypeHeader unpackExtensionTypeHeader()
             }
             case Code.EXT16: {
                 MessageBuffer castBuffer = readCastBuffer(3);
-                resetHeadByte();
                 int u16 = castBuffer.getShort(readCastBufferPosition);
                 int length = u16 & 0xffff;
                 byte type = castBuffer.getByte(readCastBufferPosition + 2);
@@ -1230,7 +1133,6 @@ public ExtensionTypeHeader unpackExtensionTypeHeader()
             }
             case Code.EXT32: {
                 MessageBuffer castBuffer = readCastBuffer(5);
-                resetHeadByte();
                 int u32 = castBuffer.getInt(readCastBufferPosition);
                 if (u32 < 0) {
                     throw overflowU32Size(u32);
@@ -1277,21 +1179,18 @@ private int tryReadBinaryHeader(byte b)
     public int unpackRawStringHeader()
             throws IOException
     {
-        byte b = getHeadByte();
+        byte b = readByte();
         if (Code.isFixedRaw(b)) { // FixRaw
-            resetHeadByte();
             return b & 0x1f;
         }
         int len = tryReadStringHeader(b);
         if (len >= 0) {
-            resetHeadByte();
             return len;
         }
 
         if (allowBinaryAsString) {
             len = tryReadBinaryHeader(b);
             if (len >= 0) {
-                resetHeadByte();
                 return len;
             }
         }
@@ -1301,21 +1200,18 @@ public int unpackRawStringHeader()
     public int unpackBinaryHeader()
             throws IOException
     {
-        byte b = getHeadByte();
+        byte b = readByte();
         if (Code.isFixedRaw(b)) { // FixRaw
-            resetHeadByte();
             return b & 0x1f;
         }
         int len = tryReadBinaryHeader(b);
         if (len >= 0) {
-            resetHeadByte();
             return len;
         }
 
         if (allowStringAsBinary) {
             len = tryReadStringHeader(b);
             if (len >= 0) {
-                resetHeadByte();
                 return len;
             }
         }

From d89ce27d0c54f28c796d6e9608374295583d481f Mon Sep 17 00:00:00 2001
From: Mitsunori Komatsu 
Date: Sun, 27 Dec 2015 17:21:52 +0900
Subject: [PATCH 194/234] Test various lengths of String

---
 ...essagePackDataformatPojoBenchmarkTest.java | 19 ++++++++++++-------
 1 file changed, 12 insertions(+), 7 deletions(-)

diff --git a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/benchmark/MessagePackDataformatPojoBenchmarkTest.java b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/benchmark/MessagePackDataformatPojoBenchmarkTest.java
index de2118508..84dfde2fc 100644
--- a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/benchmark/MessagePackDataformatPojoBenchmarkTest.java
+++ b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/benchmark/MessagePackDataformatPojoBenchmarkTest.java
@@ -32,8 +32,9 @@
 
 public class MessagePackDataformatPojoBenchmarkTest
 {
-    private static final int LOOP_MAX = 600;
-    private static final int LOOP_FACTOR = 40;
+    private static final int LOOP_MAX = 200;
+    private static final int LOOP_FACTOR_SER = 40;
+    private static final int LOOP_FACTOR_DESER = 200;
     private static final int COUNT = 6;
     private static final int WARMUP_COUNT = 4;
     private static final List pojos = new ArrayList(LOOP_MAX);
@@ -52,7 +53,11 @@ public class MessagePackDataformatPojoBenchmarkTest
             pojo.l = i;
             pojo.f = Float.valueOf(i);
             pojo.d = Double.valueOf(i);
-            pojo.setS(String.valueOf(i));
+            StringBuilder sb = new StringBuilder();
+            for (int sbi = 0; sbi < i * 40; sbi++) {
+                sb.append("x");
+            }
+            pojo.setS(sb.toString());
             pojo.bool = i % 2 == 0;
             pojo.bi = BigInteger.valueOf(i);
             switch (i % 4) {
@@ -117,7 +122,7 @@ public void testBenchmark()
             public void run()
                     throws Exception
             {
-                for (int j = 0; j < LOOP_FACTOR; j++) {
+                for (int j = 0; j < LOOP_FACTOR_SER; j++) {
                     for (int i = 0; i < LOOP_MAX; i++) {
                         origObjectMapper.writeValue(outputStreamJackson, pojos.get(i));
                     }
@@ -130,7 +135,7 @@ public void run()
             public void run()
                     throws Exception
             {
-                for (int j = 0; j < LOOP_FACTOR; j++) {
+                for (int j = 0; j < LOOP_FACTOR_SER; j++) {
                     for (int i = 0; i < LOOP_MAX; i++) {
                         msgpackObjectMapper.writeValue(outputStreamMsgpack, pojos.get(i));
                     }
@@ -143,7 +148,7 @@ public void run()
             public void run()
                     throws Exception
             {
-                for (int j = 0; j < LOOP_FACTOR; j++) {
+                for (int j = 0; j < LOOP_FACTOR_DESER; j++) {
                     for (int i = 0; i < LOOP_MAX; i++) {
                         origObjectMapper.readValue(pojosSerWithOrig.get(i), NormalPojo.class);
                     }
@@ -156,7 +161,7 @@ public void run()
             public void run()
                     throws Exception
             {
-                for (int j = 0; j < LOOP_FACTOR; j++) {
+                for (int j = 0; j < LOOP_FACTOR_DESER; j++) {
                     for (int i = 0; i < LOOP_MAX; i++) {
                         msgpackObjectMapper.readValue(pojosSerWithMsgPack.get(i), NormalPojo.class);
                     }

From b6fc9c994eb442e6eb2485d0af77551210ee09cd Mon Sep 17 00:00:00 2001
From: Mitsunori Komatsu 
Date: Sun, 27 Dec 2015 17:35:23 +0900
Subject: [PATCH 195/234] Minor refactoring

---
 ...essagePackDataformatPojoBenchmarkTest.java | 25 ++++++++-----------
 1 file changed, 10 insertions(+), 15 deletions(-)

diff --git a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/benchmark/MessagePackDataformatPojoBenchmarkTest.java b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/benchmark/MessagePackDataformatPojoBenchmarkTest.java
index 84dfde2fc..179b09891 100644
--- a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/benchmark/MessagePackDataformatPojoBenchmarkTest.java
+++ b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/benchmark/MessagePackDataformatPojoBenchmarkTest.java
@@ -37,15 +37,16 @@ public class MessagePackDataformatPojoBenchmarkTest
     private static final int LOOP_FACTOR_DESER = 200;
     private static final int COUNT = 6;
     private static final int WARMUP_COUNT = 4;
-    private static final List pojos = new ArrayList(LOOP_MAX);
-    private static final List pojosSerWithOrig = new ArrayList(LOOP_MAX);
-    private static final List pojosSerWithMsgPack = new ArrayList(LOOP_MAX);
+    private final List pojos = new ArrayList(LOOP_MAX);
+    private final List pojosSerWithOrig = new ArrayList(LOOP_MAX);
+    private final List pojosSerWithMsgPack = new ArrayList(LOOP_MAX);
     private final ObjectMapper origObjectMapper = new ObjectMapper();
     private final ObjectMapper msgpackObjectMapper = new ObjectMapper(new MessagePackFactory());
 
-    static {
-        final ObjectMapper origObjectMapper = new ObjectMapper();
-        final ObjectMapper msgpackObjectMapper = new ObjectMapper(new MessagePackFactory());
+    public MessagePackDataformatPojoBenchmarkTest()
+    {
+        origObjectMapper.configure(JsonGenerator.Feature.AUTO_CLOSE_TARGET, false);
+        msgpackObjectMapper.configure(JsonGenerator.Feature.AUTO_CLOSE_TARGET, false);
 
         for (int i = 0; i < LOOP_MAX; i++) {
             NormalPojo pojo = new NormalPojo();
@@ -54,7 +55,7 @@ public class MessagePackDataformatPojoBenchmarkTest
             pojo.f = Float.valueOf(i);
             pojo.d = Double.valueOf(i);
             StringBuilder sb = new StringBuilder();
-            for (int sbi = 0; sbi < i * 40; sbi++) {
+            for (int sbi = 0; sbi < i * 50; sbi++) {
                 sb.append("x");
             }
             pojo.setS(sb.toString());
@@ -83,7 +84,7 @@ public class MessagePackDataformatPojoBenchmarkTest
                 pojosSerWithOrig.add(origObjectMapper.writeValueAsBytes(pojos.get(i)));
             }
             catch (JsonProcessingException e) {
-                e.printStackTrace();
+                throw new RuntimeException("Failed to create test data");
             }
         }
 
@@ -92,17 +93,11 @@ public class MessagePackDataformatPojoBenchmarkTest
                 pojosSerWithMsgPack.add(msgpackObjectMapper.writeValueAsBytes(pojos.get(i)));
             }
             catch (JsonProcessingException e) {
-                e.printStackTrace();
+                throw new RuntimeException("Failed to create test data");
             }
         }
     }
 
-    public MessagePackDataformatPojoBenchmarkTest()
-    {
-        origObjectMapper.configure(JsonGenerator.Feature.AUTO_CLOSE_TARGET, false);
-        msgpackObjectMapper.configure(JsonGenerator.Feature.AUTO_CLOSE_TARGET, false);
-    }
-
     @Test
     public void testBenchmark()
             throws Exception

From d6dbfec7ef64be664fa0a0eae5c5a89e037dff14 Mon Sep 17 00:00:00 2001
From: Mitsunori Komatsu 
Date: Sun, 27 Dec 2015 21:36:24 +0900
Subject: [PATCH 196/234] Fix MessageFormat.Code#isFixedMap

---
 .../java/org/msgpack/core/MessageFormat.java  |  2 +-
 .../org/msgpack/core/MessagePackTest.scala    | 32 +++++++++++++++++++
 2 files changed, 33 insertions(+), 1 deletion(-)

diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessageFormat.java b/msgpack-core/src/main/java/org/msgpack/core/MessageFormat.java
index 17a0f1555..5a20518dc 100644
--- a/msgpack-core/src/main/java/org/msgpack/core/MessageFormat.java
+++ b/msgpack-core/src/main/java/org/msgpack/core/MessageFormat.java
@@ -98,7 +98,7 @@ public static final boolean isFixedArray(byte b)
 
         public static final boolean isFixedMap(byte b)
         {
-            return (b & (byte) 0xe0) == Code.FIXMAP_PREFIX;
+            return (b & (byte) 0xf0) == Code.FIXMAP_PREFIX;
         }
 
         public static final boolean isFixedRaw(byte b)
diff --git a/msgpack-core/src/test/scala/org/msgpack/core/MessagePackTest.scala b/msgpack-core/src/test/scala/org/msgpack/core/MessagePackTest.scala
index 5cf8ea2e6..8c2339f7d 100644
--- a/msgpack-core/src/test/scala/org/msgpack/core/MessagePackTest.scala
+++ b/msgpack-core/src/test/scala/org/msgpack/core/MessagePackTest.scala
@@ -59,6 +59,38 @@ class MessagePackTest extends MessagePackSpec {
       }
     }
 
+    "detect fixarray values" in {
+
+      val packer = new MessagePackFactory().newBufferPacker()
+      packer.packArrayHeader(0)
+      packer.close
+      val bytes = packer.toByteArray
+      new MessagePackFactory().newUnpacker(bytes).unpackArrayHeader() shouldBe 0
+      try {
+        new MessagePackFactory().newUnpacker(bytes).unpackMapHeader()
+        fail("Shouldn't reach here")
+      }
+      catch {
+        case e: MessageTypeException => // OK
+      }
+    }
+
+    "detect fixmap values" in {
+
+      val packer = new MessagePackFactory().newBufferPacker()
+      packer.packMapHeader(0)
+      packer.close
+      val bytes = packer.toByteArray
+      new MessagePackFactory().newUnpacker(bytes).unpackMapHeader() shouldBe 0
+      try {
+        new MessagePackFactory().newUnpacker(bytes).unpackArrayHeader()
+        fail("Shouldn't reach here")
+      }
+      catch {
+        case e: MessageTypeException => // OK
+      }
+    }
+
     "detect fixint quickly" in {
 
       val N = 100000

From c8c908e844aa716f93c5e651a05dcda9194efce9 Mon Sep 17 00:00:00 2001
From: Mitsunori Komatsu 
Date: Sun, 27 Dec 2015 17:21:52 +0900
Subject: [PATCH 197/234] Test various lengths of String

---
 ...essagePackDataformatPojoBenchmarkTest.java | 19 ++++++++++++-------
 1 file changed, 12 insertions(+), 7 deletions(-)

diff --git a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/benchmark/MessagePackDataformatPojoBenchmarkTest.java b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/benchmark/MessagePackDataformatPojoBenchmarkTest.java
index de2118508..84dfde2fc 100644
--- a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/benchmark/MessagePackDataformatPojoBenchmarkTest.java
+++ b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/benchmark/MessagePackDataformatPojoBenchmarkTest.java
@@ -32,8 +32,9 @@
 
 public class MessagePackDataformatPojoBenchmarkTest
 {
-    private static final int LOOP_MAX = 600;
-    private static final int LOOP_FACTOR = 40;
+    private static final int LOOP_MAX = 200;
+    private static final int LOOP_FACTOR_SER = 40;
+    private static final int LOOP_FACTOR_DESER = 200;
     private static final int COUNT = 6;
     private static final int WARMUP_COUNT = 4;
     private static final List pojos = new ArrayList(LOOP_MAX);
@@ -52,7 +53,11 @@ public class MessagePackDataformatPojoBenchmarkTest
             pojo.l = i;
             pojo.f = Float.valueOf(i);
             pojo.d = Double.valueOf(i);
-            pojo.setS(String.valueOf(i));
+            StringBuilder sb = new StringBuilder();
+            for (int sbi = 0; sbi < i * 40; sbi++) {
+                sb.append("x");
+            }
+            pojo.setS(sb.toString());
             pojo.bool = i % 2 == 0;
             pojo.bi = BigInteger.valueOf(i);
             switch (i % 4) {
@@ -117,7 +122,7 @@ public void testBenchmark()
             public void run()
                     throws Exception
             {
-                for (int j = 0; j < LOOP_FACTOR; j++) {
+                for (int j = 0; j < LOOP_FACTOR_SER; j++) {
                     for (int i = 0; i < LOOP_MAX; i++) {
                         origObjectMapper.writeValue(outputStreamJackson, pojos.get(i));
                     }
@@ -130,7 +135,7 @@ public void run()
             public void run()
                     throws Exception
             {
-                for (int j = 0; j < LOOP_FACTOR; j++) {
+                for (int j = 0; j < LOOP_FACTOR_SER; j++) {
                     for (int i = 0; i < LOOP_MAX; i++) {
                         msgpackObjectMapper.writeValue(outputStreamMsgpack, pojos.get(i));
                     }
@@ -143,7 +148,7 @@ public void run()
             public void run()
                     throws Exception
             {
-                for (int j = 0; j < LOOP_FACTOR; j++) {
+                for (int j = 0; j < LOOP_FACTOR_DESER; j++) {
                     for (int i = 0; i < LOOP_MAX; i++) {
                         origObjectMapper.readValue(pojosSerWithOrig.get(i), NormalPojo.class);
                     }
@@ -156,7 +161,7 @@ public void run()
             public void run()
                     throws Exception
             {
-                for (int j = 0; j < LOOP_FACTOR; j++) {
+                for (int j = 0; j < LOOP_FACTOR_DESER; j++) {
                     for (int i = 0; i < LOOP_MAX; i++) {
                         msgpackObjectMapper.readValue(pojosSerWithMsgPack.get(i), NormalPojo.class);
                     }

From 380f05b2f5f5f0519346585a910a6aac7c6c54b1 Mon Sep 17 00:00:00 2001
From: Mitsunori Komatsu 
Date: Sun, 27 Dec 2015 17:35:23 +0900
Subject: [PATCH 198/234] Minor refactoring

---
 ...essagePackDataformatPojoBenchmarkTest.java | 25 ++++++++-----------
 1 file changed, 10 insertions(+), 15 deletions(-)

diff --git a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/benchmark/MessagePackDataformatPojoBenchmarkTest.java b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/benchmark/MessagePackDataformatPojoBenchmarkTest.java
index 84dfde2fc..179b09891 100644
--- a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/benchmark/MessagePackDataformatPojoBenchmarkTest.java
+++ b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/benchmark/MessagePackDataformatPojoBenchmarkTest.java
@@ -37,15 +37,16 @@ public class MessagePackDataformatPojoBenchmarkTest
     private static final int LOOP_FACTOR_DESER = 200;
     private static final int COUNT = 6;
     private static final int WARMUP_COUNT = 4;
-    private static final List pojos = new ArrayList(LOOP_MAX);
-    private static final List pojosSerWithOrig = new ArrayList(LOOP_MAX);
-    private static final List pojosSerWithMsgPack = new ArrayList(LOOP_MAX);
+    private final List pojos = new ArrayList(LOOP_MAX);
+    private final List pojosSerWithOrig = new ArrayList(LOOP_MAX);
+    private final List pojosSerWithMsgPack = new ArrayList(LOOP_MAX);
     private final ObjectMapper origObjectMapper = new ObjectMapper();
     private final ObjectMapper msgpackObjectMapper = new ObjectMapper(new MessagePackFactory());
 
-    static {
-        final ObjectMapper origObjectMapper = new ObjectMapper();
-        final ObjectMapper msgpackObjectMapper = new ObjectMapper(new MessagePackFactory());
+    public MessagePackDataformatPojoBenchmarkTest()
+    {
+        origObjectMapper.configure(JsonGenerator.Feature.AUTO_CLOSE_TARGET, false);
+        msgpackObjectMapper.configure(JsonGenerator.Feature.AUTO_CLOSE_TARGET, false);
 
         for (int i = 0; i < LOOP_MAX; i++) {
             NormalPojo pojo = new NormalPojo();
@@ -54,7 +55,7 @@ public class MessagePackDataformatPojoBenchmarkTest
             pojo.f = Float.valueOf(i);
             pojo.d = Double.valueOf(i);
             StringBuilder sb = new StringBuilder();
-            for (int sbi = 0; sbi < i * 40; sbi++) {
+            for (int sbi = 0; sbi < i * 50; sbi++) {
                 sb.append("x");
             }
             pojo.setS(sb.toString());
@@ -83,7 +84,7 @@ public class MessagePackDataformatPojoBenchmarkTest
                 pojosSerWithOrig.add(origObjectMapper.writeValueAsBytes(pojos.get(i)));
             }
             catch (JsonProcessingException e) {
-                e.printStackTrace();
+                throw new RuntimeException("Failed to create test data");
             }
         }
 
@@ -92,17 +93,11 @@ public class MessagePackDataformatPojoBenchmarkTest
                 pojosSerWithMsgPack.add(msgpackObjectMapper.writeValueAsBytes(pojos.get(i)));
             }
             catch (JsonProcessingException e) {
-                e.printStackTrace();
+                throw new RuntimeException("Failed to create test data");
             }
         }
     }
 
-    public MessagePackDataformatPojoBenchmarkTest()
-    {
-        origObjectMapper.configure(JsonGenerator.Feature.AUTO_CLOSE_TARGET, false);
-        msgpackObjectMapper.configure(JsonGenerator.Feature.AUTO_CLOSE_TARGET, false);
-    }
-
     @Test
     public void testBenchmark()
             throws Exception

From c39b250d1356ce2067f3f3a5d7b334d58da8e808 Mon Sep 17 00:00:00 2001
From: Mitsunori Komatsu 
Date: Sun, 27 Dec 2015 17:21:52 +0900
Subject: [PATCH 199/234] Test various lengths of String

---
 .../benchmark/MessagePackDataformatPojoBenchmarkTest.java       | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/benchmark/MessagePackDataformatPojoBenchmarkTest.java b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/benchmark/MessagePackDataformatPojoBenchmarkTest.java
index 179b09891..9fb6b21d9 100644
--- a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/benchmark/MessagePackDataformatPojoBenchmarkTest.java
+++ b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/benchmark/MessagePackDataformatPojoBenchmarkTest.java
@@ -55,7 +55,7 @@ public MessagePackDataformatPojoBenchmarkTest()
             pojo.f = Float.valueOf(i);
             pojo.d = Double.valueOf(i);
             StringBuilder sb = new StringBuilder();
-            for (int sbi = 0; sbi < i * 50; sbi++) {
+            for (int sbi = 0; sbi < i * 40; sbi++) {
                 sb.append("x");
             }
             pojo.setS(sb.toString());

From aea539741a8b2682399a5d170a2236f02fd9ac8c Mon Sep 17 00:00:00 2001
From: Mitsunori Komatsu 
Date: Sun, 27 Dec 2015 17:35:23 +0900
Subject: [PATCH 200/234] Minor refactoring

---
 .../benchmark/MessagePackDataformatPojoBenchmarkTest.java       | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/benchmark/MessagePackDataformatPojoBenchmarkTest.java b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/benchmark/MessagePackDataformatPojoBenchmarkTest.java
index 9fb6b21d9..179b09891 100644
--- a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/benchmark/MessagePackDataformatPojoBenchmarkTest.java
+++ b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/benchmark/MessagePackDataformatPojoBenchmarkTest.java
@@ -55,7 +55,7 @@ public MessagePackDataformatPojoBenchmarkTest()
             pojo.f = Float.valueOf(i);
             pojo.d = Double.valueOf(i);
             StringBuilder sb = new StringBuilder();
-            for (int sbi = 0; sbi < i * 40; sbi++) {
+            for (int sbi = 0; sbi < i * 50; sbi++) {
                 sb.append("x");
             }
             pojo.setS(sb.toString());

From 28be745eaca17a8ded241a67a6774e25aa24d2c0 Mon Sep 17 00:00:00 2001
From: Mitsunori Komatsu 
Date: Fri, 1 Jan 2016 00:24:27 +0900
Subject: [PATCH 201/234] Add concurrent serialization test in
 MessagePackGeneratorTest

---
 .../dataformat/MessagePackGeneratorTest.java  | 56 +++++++++++++++++++
 1 file changed, 56 insertions(+)

diff --git a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackGeneratorTest.java b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackGeneratorTest.java
index b88d0d645..18fd9ec62 100644
--- a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackGeneratorTest.java
+++ b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackGeneratorTest.java
@@ -24,6 +24,7 @@
 import org.msgpack.core.MessageUnpacker;
 import org.msgpack.core.buffer.ArrayBufferInput;
 
+import java.io.ByteArrayOutputStream;
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileOutputStream;
@@ -36,6 +37,11 @@
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
 
 import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
@@ -379,4 +385,54 @@ public void testWritePrimitiveObjectViaObjectMapper()
         assertEquals(4, unpacker.unpackInt());
         assertEquals(5, unpacker.unpackLong());
     }
+
+    @Test
+    public void testInMultiThreads()
+            throws Exception
+    {
+        int threadCount = 8;
+        final int loopCount = 4000;
+        ExecutorService executorService = Executors.newFixedThreadPool(threadCount);
+        final ObjectMapper objectMapper = new ObjectMapper(new MessagePackFactory());
+        objectMapper.configure(JsonGenerator.Feature.AUTO_CLOSE_TARGET, false);
+        final List buffers = new ArrayList(threadCount);
+        List> results = new ArrayList>();
+
+        for (int ti = 0; ti < threadCount; ti++) {
+            buffers.add(new ByteArrayOutputStream());
+            final int threadIndex = ti;
+            results.add(executorService.submit(new Callable()
+            {
+                @Override
+                public Exception call()
+                        throws Exception
+                {
+                    try {
+                        for (int i = 0; i < loopCount; i++) {
+                            objectMapper.writeValue(buffers.get(threadIndex), threadIndex);
+                        }
+                        return null;
+                    }
+                    catch (IOException e) {
+                        return e;
+                    }
+                }
+            }));
+        }
+
+        for (int ti = 0; ti < threadCount; ti++) {
+            Future exceptionFuture = results.get(ti);
+            Exception exception = exceptionFuture.get(20, TimeUnit.SECONDS);
+            if (exception != null) {
+                throw exception;
+            }
+            else {
+                ByteArrayOutputStream outputStream = buffers.get(ti);
+                MessageUnpacker unpacker = MessagePack.newDefaultUnpacker(outputStream.toByteArray());
+                for (int i = 0; i < loopCount; i++) {
+                    assertEquals(ti, unpacker.unpackInt());
+                }
+            }
+        }
+    }
 }

From 7ad3f0a26b53d6796dcc26b86bb30200df0724a4 Mon Sep 17 00:00:00 2001
From: Mitsunori Komatsu 
Date: Sun, 3 Jan 2016 22:23:54 +0900
Subject: [PATCH 202/234] Fix MessagePack.Code#isFixedMap

---
 .../java/org/msgpack/core/MessagePack.java    |  2 +-
 .../org/msgpack/core/MessagePackTest.scala    | 34 +++++++++++++++++++
 2 files changed, 35 insertions(+), 1 deletion(-)

diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessagePack.java b/msgpack-core/src/main/java/org/msgpack/core/MessagePack.java
index 9847d461e..83d06b211 100644
--- a/msgpack-core/src/main/java/org/msgpack/core/MessagePack.java
+++ b/msgpack-core/src/main/java/org/msgpack/core/MessagePack.java
@@ -234,7 +234,7 @@ public static final boolean isFixedArray(byte b)
 
         public static final boolean isFixedMap(byte b)
         {
-            return (b & (byte) 0xe0) == Code.FIXMAP_PREFIX;
+            return (b & (byte) 0xf0) == Code.FIXMAP_PREFIX;
         }
 
         public static final boolean isFixedRaw(byte b)
diff --git a/msgpack-core/src/test/scala/org/msgpack/core/MessagePackTest.scala b/msgpack-core/src/test/scala/org/msgpack/core/MessagePackTest.scala
index 62bf8ae82..f00340f25 100644
--- a/msgpack-core/src/test/scala/org/msgpack/core/MessagePackTest.scala
+++ b/msgpack-core/src/test/scala/org/msgpack/core/MessagePackTest.scala
@@ -59,6 +59,40 @@ class MessagePackTest extends MessagePackSpec {
       }
     }
 
+    "detect fixarray values" in {
+
+      val outputStream = new ByteArrayOutputStream
+      val packer = MessagePack.newDefaultPacker(outputStream)
+      packer.packArrayHeader(0)
+      packer.close
+      val bytes = outputStream.toByteArray
+      MessagePack.newDefaultUnpacker(bytes).unpackArrayHeader() shouldBe 0
+      try {
+        MessagePack.newDefaultUnpacker(bytes).unpackMapHeader()
+        fail("Shouldn't reach here")
+      }
+      catch {
+        case e: MessageTypeException => // OK
+      }
+    }
+
+    "detect fixmap values" in {
+
+      val outputStream = new ByteArrayOutputStream
+      val packer = MessagePack.newDefaultPacker(outputStream)
+      packer.packMapHeader(0)
+      packer.close
+      val bytes = outputStream.toByteArray
+      MessagePack.newDefaultUnpacker(bytes).unpackMapHeader() shouldBe 0
+      try {
+        MessagePack.newDefaultUnpacker(bytes).unpackArrayHeader()
+        fail("Shouldn't reach here")
+      }
+      catch {
+        case e: MessageTypeException => // OK
+      }
+    }
+
     "detect fixint quickly" in {
 
       val N = 100000

From e261c59080f599e48dcaad01b97de16cf20da3eb Mon Sep 17 00:00:00 2001
From: "Taro L. Saito" 
Date: Mon, 4 Jan 2016 12:16:44 +0900
Subject: [PATCH 203/234] Merge v07-develop and fix code style

---
 .../java/org/msgpack/core/MessagePack.java    | 13 +----
 .../org/msgpack/core/MessagePackFactory.java  | 26 ++++-----
 .../java/org/msgpack/core/MessagePacker.java  |  1 -
 .../org/msgpack/core/MessageUnpacker.java     |  5 +-
 .../msgpack/core/buffer/ArrayBufferInput.java |  1 -
 .../core/buffer/ChannelBufferInput.java       |  1 -
 .../msgpack/core/buffer/MessageBufferBE.java  |  2 -
 .../core/buffer/MessageBufferInput.java       |  5 +-
 .../msgpack/core/buffer/MessageBufferU.java   |  2 -
 .../value/impl/ImmutableArrayValueImpl.java   |  3 +-
 .../impl/ImmutableBigIntegerValueImpl.java    |  9 ++-
 .../value/impl/ImmutableDoubleValueImpl.java  |  3 +-
 .../value/impl/ImmutableMapValueImpl.java     |  6 +-
 .../org/msgpack/core/MessagePackTest.scala    |  2 -
 .../jackson/dataformat/MessagePackParser.java | 10 +++-
 .../dataformat/MessagePackGeneratorTest.java  | 56 +++++++++++++++++++
 ...essagePackDataformatPojoBenchmarkTest.java | 42 +++++++-------
 17 files changed, 114 insertions(+), 73 deletions(-)

diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessagePack.java b/msgpack-core/src/main/java/org/msgpack/core/MessagePack.java
index f1bee0774..f7fec9f24 100644
--- a/msgpack-core/src/main/java/org/msgpack/core/MessagePack.java
+++ b/msgpack-core/src/main/java/org/msgpack/core/MessagePack.java
@@ -15,20 +15,11 @@
 //
 package org.msgpack.core;
 
-import org.msgpack.core.buffer.ArrayBufferInput;
-import org.msgpack.core.buffer.ChannelBufferInput;
-import org.msgpack.core.buffer.ChannelBufferOutput;
-import org.msgpack.core.buffer.InputStreamBufferInput;
-import org.msgpack.core.buffer.OutputStreamBufferOutput;
-
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.nio.channels.ReadableByteChannel;
 import java.nio.channels.WritableByteChannel;
 import java.nio.charset.Charset;
-import java.nio.charset.CodingErrorAction;
-
-import static org.msgpack.core.Preconditions.checkArgument;
 
 /**
  * This class has MessagePack prefix code definitions and packer/unpacker factory methods.
@@ -53,7 +44,8 @@ public static MessagePackFactory getDefaultFactory()
     }
 
     private MessagePack()
-    { }
+    {
+    }
 
     /**
      * Equivalent to getDefaultFactory().newPacker(out).
@@ -80,7 +72,6 @@ public static MessagePacker newDefaultPacker(WritableByteChannel channel)
     /**
      * Equivalent to getDefaultFactory().newBufferPacker()
      *
-     * @param channel
      * @return
      */
     public static MessageBufferPacker newDefaultBufferPacker()
diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessagePackFactory.java b/msgpack-core/src/main/java/org/msgpack/core/MessagePackFactory.java
index f76df5490..8863e4637 100644
--- a/msgpack-core/src/main/java/org/msgpack/core/MessagePackFactory.java
+++ b/msgpack-core/src/main/java/org/msgpack/core/MessagePackFactory.java
@@ -19,17 +19,15 @@
 import org.msgpack.core.buffer.ChannelBufferInput;
 import org.msgpack.core.buffer.ChannelBufferOutput;
 import org.msgpack.core.buffer.InputStreamBufferInput;
-import org.msgpack.core.buffer.OutputStreamBufferOutput;
 import org.msgpack.core.buffer.MessageBufferInput;
 import org.msgpack.core.buffer.MessageBufferOutput;
+import org.msgpack.core.buffer.OutputStreamBufferOutput;
 
 import java.io.InputStream;
 import java.io.OutputStream;
-import java.nio.channels.WritableByteChannel;
 import java.nio.channels.ReadableByteChannel;
-
+import java.nio.channels.WritableByteChannel;
 import java.nio.charset.CodingErrorAction;
-import static org.msgpack.core.Preconditions.checkArgument;
 
 public class MessagePackFactory
 {
@@ -42,8 +40,8 @@ public class MessagePackFactory
     private int unpackStringSizeLimit = Integer.MAX_VALUE;
     private int unpackStringDecoderBufferSize = 8192;
 
-    private int inputBufferSize = 16*1024;
-    private int outputBufferSize = 16*1024;
+    private int inputBufferSize = 16 * 1024;
+    private int outputBufferSize = 16 * 1024;
 
     public MessagePacker newPacker(OutputStream out)
     {
@@ -58,13 +56,13 @@ public MessagePacker newPacker(WritableByteChannel channel)
     public MessagePacker newPacker(MessageBufferOutput output)
     {
         return new MessagePacker(output)
-            .setSmallStringOptimizationThreshold(packerSmallStringOptimizationThreshold);
+                .setSmallStringOptimizationThreshold(packerSmallStringOptimizationThreshold);
     }
 
     public MessageBufferPacker newBufferPacker()
     {
         return new MessageBufferPacker()
-            .setSmallStringOptimizationThreshold(packerSmallStringOptimizationThreshold);
+                .setSmallStringOptimizationThreshold(packerSmallStringOptimizationThreshold);
     }
 
     public MessageUnpacker newUnpacker(byte[] contents)
@@ -90,12 +88,12 @@ public MessageUnpacker newUnpacker(ReadableByteChannel channel)
     public MessageUnpacker newUnpacker(MessageBufferInput input)
     {
         return new MessageUnpacker(input)
-            .setAllowStringAsBinary(unpackAllowStringAsBinary)
-            .setAllowBinaryAsString(unpackAllowBinaryAsString)
-            .setActionOnMalformedString(unpackActionOnMalformedString)
-            .setActionOnUnmappableString(unpackActionOnUnmappableString)
-            .setStringSizeLimit(unpackStringSizeLimit)
-            .setStringDecoderBufferSize(unpackStringDecoderBufferSize);
+                .setAllowStringAsBinary(unpackAllowStringAsBinary)
+                .setAllowBinaryAsString(unpackAllowBinaryAsString)
+                .setActionOnMalformedString(unpackActionOnMalformedString)
+                .setActionOnUnmappableString(unpackActionOnUnmappableString)
+                .setStringSizeLimit(unpackStringSizeLimit)
+                .setStringDecoderBufferSize(unpackStringDecoderBufferSize);
     }
 
     /**
diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessagePacker.java b/msgpack-core/src/main/java/org/msgpack/core/MessagePacker.java
index b3fcff5a8..5d2ff6323 100644
--- a/msgpack-core/src/main/java/org/msgpack/core/MessagePacker.java
+++ b/msgpack-core/src/main/java/org/msgpack/core/MessagePacker.java
@@ -27,7 +27,6 @@
 import java.nio.charset.CharacterCodingException;
 import java.nio.charset.CharsetEncoder;
 import java.nio.charset.CoderResult;
-import java.nio.charset.CodingErrorAction;
 
 import static org.msgpack.core.MessageFormat.Code.ARRAY16;
 import static org.msgpack.core.MessageFormat.Code.ARRAY32;
diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java b/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java
index ab7b3e496..017022204 100644
--- a/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java
+++ b/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java
@@ -24,7 +24,6 @@
 import org.msgpack.value.Variable;
 
 import java.io.Closeable;
-import java.io.EOFException;
 import java.io.IOException;
 import java.math.BigInteger;
 import java.nio.ByteBuffer;
@@ -33,13 +32,11 @@
 import java.nio.charset.CharsetDecoder;
 import java.nio.charset.CoderResult;
 import java.nio.charset.CodingErrorAction;
-import java.nio.charset.MalformedInputException;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
-import static org.msgpack.core.Preconditions.checkArgument;
 import static org.msgpack.core.Preconditions.checkNotNull;
 
 /**
@@ -1019,7 +1016,7 @@ else if (bufferRemaining == 0) {
     }
 
     private void handleCoderError(CoderResult cr)
-        throws CharacterCodingException
+            throws CharacterCodingException
     {
         if ((cr.isMalformed() && actionOnMalformedString == CodingErrorAction.REPORT) ||
                 (cr.isUnmappable() && actionOnUnmappableString == CodingErrorAction.REPORT)) {
diff --git a/msgpack-core/src/main/java/org/msgpack/core/buffer/ArrayBufferInput.java b/msgpack-core/src/main/java/org/msgpack/core/buffer/ArrayBufferInput.java
index a777b8a73..88fe45942 100644
--- a/msgpack-core/src/main/java/org/msgpack/core/buffer/ArrayBufferInput.java
+++ b/msgpack-core/src/main/java/org/msgpack/core/buffer/ArrayBufferInput.java
@@ -87,5 +87,4 @@ public void close()
         buffer = null;
         isRead = false;
     }
-
 }
diff --git a/msgpack-core/src/main/java/org/msgpack/core/buffer/ChannelBufferInput.java b/msgpack-core/src/main/java/org/msgpack/core/buffer/ChannelBufferInput.java
index 781b7afb9..6553e497f 100644
--- a/msgpack-core/src/main/java/org/msgpack/core/buffer/ChannelBufferInput.java
+++ b/msgpack-core/src/main/java/org/msgpack/core/buffer/ChannelBufferInput.java
@@ -78,5 +78,4 @@ public void close()
     {
         channel.close();
     }
-
 }
diff --git a/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferBE.java b/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferBE.java
index 3f5d24976..1326b396e 100644
--- a/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferBE.java
+++ b/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferBE.java
@@ -15,8 +15,6 @@
 //
 package org.msgpack.core.buffer;
 
-import java.nio.ByteBuffer;
-
 import static org.msgpack.core.Preconditions.checkArgument;
 
 /**
diff --git a/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferInput.java b/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferInput.java
index 5925557cf..cb5f7743d 100644
--- a/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferInput.java
+++ b/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferInput.java
@@ -26,13 +26,12 @@ public interface MessageBufferInput
 {
     /**
      * Get a next buffer to read.
-     *
-     * When this method is called twice, the formally allocated buffer can be safely discarded.
+     * 

+ * When this method is called, the formally allocated buffer can be safely discarded. * * @return the next MessageBuffer, or return null if no more buffer is available. * @throws IOException when error occurred when reading the data */ public MessageBuffer next() throws IOException; - } diff --git a/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferU.java b/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferU.java index 151b6cd2e..1e8783738 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferU.java +++ b/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferU.java @@ -16,10 +16,8 @@ package org.msgpack.core.buffer; import java.nio.ByteBuffer; -import java.nio.ByteOrder; import static org.msgpack.core.Preconditions.checkArgument; -import static org.msgpack.core.Preconditions.checkNotNull; /** * Universal MessageBuffer implementation supporting Java6 and Android. diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableArrayValueImpl.java b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableArrayValueImpl.java index 09fc18e52..3e1b732c2 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableArrayValueImpl.java +++ b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableArrayValueImpl.java @@ -196,7 +196,8 @@ private static void appendString(StringBuilder sb, Value value) { if (value.isRawValue()) { sb.append(value.toJson()); - } else { + } + else { sb.append(value.toString()); } } diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableBigIntegerValueImpl.java b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableBigIntegerValueImpl.java index b1c7c0b10..c6fe39386 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableBigIntegerValueImpl.java +++ b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableBigIntegerValueImpl.java @@ -38,16 +38,16 @@ public class ImmutableBigIntegerValueImpl { public static MessageFormat mostSuccinctMessageFormat(IntegerValue v) { - if(v.isInByteRange()) { + if (v.isInByteRange()) { return MessageFormat.INT8; } - else if(v.isInShortRange()) { + else if (v.isInShortRange()) { return MessageFormat.INT16; } - else if(v.isInIntRange()) { + else if (v.isInIntRange()) { return MessageFormat.INT32; } - else if(v.isInLongRange()) { + else if (v.isInLongRange()) { return MessageFormat.INT64; } else { @@ -55,7 +55,6 @@ else if(v.isInLongRange()) { } } - private final BigInteger value; public ImmutableBigIntegerValueImpl(BigInteger value) diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableDoubleValueImpl.java b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableDoubleValueImpl.java index b7fa39397..2aae1633a 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableDoubleValueImpl.java +++ b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableDoubleValueImpl.java @@ -130,7 +130,8 @@ public String toJson() { if (Double.isNaN(value) || Double.isInfinite(value)) { return "null"; - } else { + } + else { return Double.toString(value); } } diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableMapValueImpl.java b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableMapValueImpl.java index 3df98d619..dc55d783f 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableMapValueImpl.java +++ b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableMapValueImpl.java @@ -172,7 +172,8 @@ private static void appendJsonKey(StringBuilder sb, Value key) { if (key.isRawValue()) { sb.append(key.toJson()); - } else { + } + else { ImmutableStringValueImpl.appendJsonString(sb, key.toString()); } } @@ -202,7 +203,8 @@ private static void appendString(StringBuilder sb, Value value) { if (value.isRawValue()) { sb.append(value.toJson()); - } else { + } + else { sb.append(value.toString()); } } diff --git a/msgpack-core/src/test/scala/org/msgpack/core/MessagePackTest.scala b/msgpack-core/src/test/scala/org/msgpack/core/MessagePackTest.scala index 8c2339f7d..e1dc1d673 100644 --- a/msgpack-core/src/test/scala/org/msgpack/core/MessagePackTest.scala +++ b/msgpack-core/src/test/scala/org/msgpack/core/MessagePackTest.scala @@ -60,7 +60,6 @@ class MessagePackTest extends MessagePackSpec { } "detect fixarray values" in { - val packer = new MessagePackFactory().newBufferPacker() packer.packArrayHeader(0) packer.close @@ -76,7 +75,6 @@ class MessagePackTest extends MessagePackSpec { } "detect fixmap values" in { - val packer = new MessagePackFactory().newBufferPacker() packer.packMapHeader(0) packer.close diff --git a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java index 7ac2fa5af..08be64e59 100644 --- a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java +++ b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java @@ -32,7 +32,12 @@ import org.msgpack.core.buffer.ArrayBufferInput; import org.msgpack.core.buffer.InputStreamBufferInput; import org.msgpack.core.buffer.MessageBufferInput; -import org.msgpack.value.*; +import org.msgpack.value.ExtensionValue; +import org.msgpack.value.IntegerValue; +import org.msgpack.value.Value; +import org.msgpack.value.ValueFactory; +import org.msgpack.value.ValueType; +import org.msgpack.value.Variable; import java.io.IOException; import java.io.InputStream; @@ -278,7 +283,8 @@ else if (newStack instanceof StackItemForObject) { @Override protected void _handleEOF() throws JsonParseException - {} + { + } @Override public String getText() diff --git a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackGeneratorTest.java b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackGeneratorTest.java index de58e4a1a..845c45f40 100644 --- a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackGeneratorTest.java +++ b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackGeneratorTest.java @@ -24,6 +24,7 @@ import org.msgpack.core.MessageUnpacker; import org.msgpack.core.buffer.ArrayBufferInput; +import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; @@ -36,6 +37,11 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; @@ -379,4 +385,54 @@ public void testWritePrimitiveObjectViaObjectMapper() assertEquals(4, unpacker.unpackInt()); assertEquals(5, unpacker.unpackLong()); } + + @Test + public void testInMultiThreads() + throws Exception + { + int threadCount = 8; + final int loopCount = 4000; + ExecutorService executorService = Executors.newFixedThreadPool(threadCount); + final ObjectMapper objectMapper = new ObjectMapper(new MessagePackFormatFactory()); + objectMapper.configure(JsonGenerator.Feature.AUTO_CLOSE_TARGET, false); + final List buffers = new ArrayList(threadCount); + List> results = new ArrayList>(); + + for (int ti = 0; ti < threadCount; ti++) { + buffers.add(new ByteArrayOutputStream()); + final int threadIndex = ti; + results.add(executorService.submit(new Callable() + { + @Override + public Exception call() + throws Exception + { + try { + for (int i = 0; i < loopCount; i++) { + objectMapper.writeValue(buffers.get(threadIndex), threadIndex); + } + return null; + } + catch (IOException e) { + return e; + } + } + })); + } + + for (int ti = 0; ti < threadCount; ti++) { + Future exceptionFuture = results.get(ti); + Exception exception = exceptionFuture.get(20, TimeUnit.SECONDS); + if (exception != null) { + throw exception; + } + else { + ByteArrayOutputStream outputStream = buffers.get(ti); + MessageUnpacker unpacker = MessagePack.newDefaultUnpacker(outputStream.toByteArray()); + for (int i = 0; i < loopCount; i++) { + assertEquals(ti, unpacker.unpackInt()); + } + } + } + } } diff --git a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/benchmark/MessagePackDataformatPojoBenchmarkTest.java b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/benchmark/MessagePackDataformatPojoBenchmarkTest.java index 33c5f024c..e6b627f5c 100644 --- a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/benchmark/MessagePackDataformatPojoBenchmarkTest.java +++ b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/benchmark/MessagePackDataformatPojoBenchmarkTest.java @@ -32,19 +32,21 @@ public class MessagePackDataformatPojoBenchmarkTest { - private static final int LOOP_MAX = 600; - private static final int LOOP_FACTOR = 40; + private static final int LOOP_MAX = 200; + private static final int LOOP_FACTOR_SER = 40; + private static final int LOOP_FACTOR_DESER = 200; private static final int COUNT = 6; private static final int WARMUP_COUNT = 4; - private static final List pojos = new ArrayList(LOOP_MAX); - private static final List pojosSerWithOrig = new ArrayList(LOOP_MAX); - private static final List pojosSerWithMsgPack = new ArrayList(LOOP_MAX); + private final List pojos = new ArrayList(LOOP_MAX); + private final List pojosSerWithOrig = new ArrayList(LOOP_MAX); + private final List pojosSerWithMsgPack = new ArrayList(LOOP_MAX); private final ObjectMapper origObjectMapper = new ObjectMapper(); private final ObjectMapper msgpackObjectMapper = new ObjectMapper(new MessagePackFormatFactory()); - static { - final ObjectMapper origObjectMapper = new ObjectMapper(); - final ObjectMapper msgpackObjectMapper = new ObjectMapper(new MessagePackFormatFactory()); + public MessagePackDataformatPojoBenchmarkTest() + { + origObjectMapper.configure(JsonGenerator.Feature.AUTO_CLOSE_TARGET, false); + msgpackObjectMapper.configure(JsonGenerator.Feature.AUTO_CLOSE_TARGET, false); for (int i = 0; i < LOOP_MAX; i++) { NormalPojo pojo = new NormalPojo(); @@ -52,7 +54,11 @@ public class MessagePackDataformatPojoBenchmarkTest pojo.l = i; pojo.f = Float.valueOf(i); pojo.d = Double.valueOf(i); - pojo.setS(String.valueOf(i)); + StringBuilder sb = new StringBuilder(); + for (int sbi = 0; sbi < i * 50; sbi++) { + sb.append("x"); + } + pojo.setS(sb.toString()); pojo.bool = i % 2 == 0; pojo.bi = BigInteger.valueOf(i); switch (i % 4) { @@ -78,7 +84,7 @@ public class MessagePackDataformatPojoBenchmarkTest pojosSerWithOrig.add(origObjectMapper.writeValueAsBytes(pojos.get(i))); } catch (JsonProcessingException e) { - e.printStackTrace(); + throw new RuntimeException("Failed to create test data"); } } @@ -87,17 +93,11 @@ public class MessagePackDataformatPojoBenchmarkTest pojosSerWithMsgPack.add(msgpackObjectMapper.writeValueAsBytes(pojos.get(i))); } catch (JsonProcessingException e) { - e.printStackTrace(); + throw new RuntimeException("Failed to create test data"); } } } - public MessagePackDataformatPojoBenchmarkTest() - { - origObjectMapper.configure(JsonGenerator.Feature.AUTO_CLOSE_TARGET, false); - msgpackObjectMapper.configure(JsonGenerator.Feature.AUTO_CLOSE_TARGET, false); - } - @Test public void testBenchmark() throws Exception @@ -117,7 +117,7 @@ public void testBenchmark() public void run() throws Exception { - for (int j = 0; j < LOOP_FACTOR; j++) { + for (int j = 0; j < LOOP_FACTOR_SER; j++) { for (int i = 0; i < LOOP_MAX; i++) { origObjectMapper.writeValue(outputStreamJackson, pojos.get(i)); } @@ -130,7 +130,7 @@ public void run() public void run() throws Exception { - for (int j = 0; j < LOOP_FACTOR; j++) { + for (int j = 0; j < LOOP_FACTOR_SER; j++) { for (int i = 0; i < LOOP_MAX; i++) { msgpackObjectMapper.writeValue(outputStreamMsgpack, pojos.get(i)); } @@ -143,7 +143,7 @@ public void run() public void run() throws Exception { - for (int j = 0; j < LOOP_FACTOR; j++) { + for (int j = 0; j < LOOP_FACTOR_DESER; j++) { for (int i = 0; i < LOOP_MAX; i++) { origObjectMapper.readValue(pojosSerWithOrig.get(i), NormalPojo.class); } @@ -156,7 +156,7 @@ public void run() public void run() throws Exception { - for (int j = 0; j < LOOP_FACTOR; j++) { + for (int j = 0; j < LOOP_FACTOR_DESER; j++) { for (int i = 0; i < LOOP_MAX; i++) { msgpackObjectMapper.readValue(pojosSerWithMsgPack.get(i), NormalPojo.class); } From 8cb71d95f18a7911287bf60c2af8b68a898d02f8 Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Mon, 4 Jan 2016 13:00:33 +0900 Subject: [PATCH 204/234] Move Nullable to annocation package --- .../src/main/java/org/msgpack/core/Preconditions.java | 1 + .../java/org/msgpack/core/{ => annotations}/Nullable.java | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) rename msgpack-core/src/main/java/org/msgpack/core/{ => annotations}/Nullable.java (91%) diff --git a/msgpack-core/src/main/java/org/msgpack/core/Preconditions.java b/msgpack-core/src/main/java/org/msgpack/core/Preconditions.java index d8f43bcb7..e44d97d15 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/Preconditions.java +++ b/msgpack-core/src/main/java/org/msgpack/core/Preconditions.java @@ -31,6 +31,7 @@ */ package org.msgpack.core; +import org.msgpack.core.annotations.Nullable; import org.msgpack.core.annotations.VisibleForTesting; /** diff --git a/msgpack-core/src/main/java/org/msgpack/core/Nullable.java b/msgpack-core/src/main/java/org/msgpack/core/annotations/Nullable.java similarity index 91% rename from msgpack-core/src/main/java/org/msgpack/core/Nullable.java rename to msgpack-core/src/main/java/org/msgpack/core/annotations/Nullable.java index b2e7585a5..9e7c94fab 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/Nullable.java +++ b/msgpack-core/src/main/java/org/msgpack/core/annotations/Nullable.java @@ -13,11 +13,11 @@ // See the License for the specific language governing permissions and // limitations under the License. // -package org.msgpack.core; +package org.msgpack.core.annotations; /** * Annotates a field which can be null */ -@interface Nullable +public @interface Nullable { } From 0215af902b40dab982f916f865ee696b09dcab02 Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Mon, 4 Jan 2016 13:02:58 +0900 Subject: [PATCH 205/234] Fix typo --- .../java/org/msgpack/core/buffer/MessageBufferOutput.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferOutput.java b/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferOutput.java index 92eb760a9..055fb309e 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferOutput.java +++ b/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferOutput.java @@ -30,11 +30,11 @@ public interface MessageBufferOutput * If the previously allocated buffer is not flushed yet, this next method should discard * it without writing it. * - * @param mimimumSize the mimium required buffer size to allocate + * @param minimumSize the mimium required buffer size to allocate * @return * @throws IOException */ - public MessageBuffer next(int mimimumSize) + public MessageBuffer next(int minimumSize) throws IOException; /** From 7102ecb084ff7bcd0d3ba2d95aaaf5779773c759 Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Mon, 4 Jan 2016 13:04:39 +0900 Subject: [PATCH 206/234] Remove unnecessary public declaration from the interface --- .../java/org/msgpack/core/buffer/MessageBufferInput.java | 2 +- .../java/org/msgpack/core/buffer/MessageBufferOutput.java | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferInput.java b/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferInput.java index cb5f7743d..46eea243e 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferInput.java +++ b/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferInput.java @@ -32,6 +32,6 @@ public interface MessageBufferInput * @return the next MessageBuffer, or return null if no more buffer is available. * @throws IOException when error occurred when reading the data */ - public MessageBuffer next() + MessageBuffer next() throws IOException; } diff --git a/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferOutput.java b/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferOutput.java index 055fb309e..024414bae 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferOutput.java +++ b/msgpack-core/src/main/java/org/msgpack/core/buffer/MessageBufferOutput.java @@ -34,7 +34,7 @@ public interface MessageBufferOutput * @return * @throws IOException */ - public MessageBuffer next(int minimumSize) + MessageBuffer next(int minimumSize) throws IOException; /** @@ -45,7 +45,7 @@ public MessageBuffer next(int minimumSize) * @param length the size of buffer to flush * @throws IOException */ - public void writeBuffer(int length) + void writeBuffer(int length) throws IOException; /** @@ -58,7 +58,7 @@ public void writeBuffer(int length) * @return * @throws IOException */ - public void write(byte[] buffer, int offset, int length) + void write(byte[] buffer, int offset, int length) throws IOException; /** @@ -71,6 +71,6 @@ public void write(byte[] buffer, int offset, int length) * @return * @throws IOException */ - public void add(byte[] buffer, int offset, int length) + void add(byte[] buffer, int offset, int length) throws IOException; } From 7b7012fb775ade50a554424fcd0086180aeba056 Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Mon, 4 Jan 2016 13:07:15 +0900 Subject: [PATCH 207/234] Extract common code --- .../java/org/msgpack/core/MessagePacker.java | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessagePacker.java b/msgpack-core/src/main/java/org/msgpack/core/MessagePacker.java index 5d2ff6323..e0b1b6c65 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/MessagePacker.java +++ b/msgpack-core/src/main/java/org/msgpack/core/MessagePacker.java @@ -153,10 +153,7 @@ public void flush() throws IOException { if (position > 0) { - out.writeBuffer(position); - buffer = null; - totalFlushBytes += position; - position = 0; + flushBuffer(); } out.flush(); } @@ -172,6 +169,15 @@ public void close() } } + private void flushBuffer() + throws IOException + { + out.writeBuffer(position); + buffer = null; + totalFlushBytes += position; + position = 0; + } + private void ensureCapacity(int mimimumSize) throws IOException { @@ -179,10 +185,7 @@ private void ensureCapacity(int mimimumSize) buffer = out.next(mimimumSize); } else if (position + mimimumSize >= buffer.size()) { - out.writeBuffer(position); - buffer = null; - totalFlushBytes += position; - position = 0; + flushBuffer(); buffer = out.next(mimimumSize); } } From 5cbd2e0e2c38501ae5b75f5890434b864acd628d Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Mon, 4 Jan 2016 13:10:28 +0900 Subject: [PATCH 208/234] Use the root constructor --- .../main/java/org/msgpack/core/buffer/ArrayBufferInput.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/msgpack-core/src/main/java/org/msgpack/core/buffer/ArrayBufferInput.java b/msgpack-core/src/main/java/org/msgpack/core/buffer/ArrayBufferInput.java index 88fe45942..36f0ad3c1 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/buffer/ArrayBufferInput.java +++ b/msgpack-core/src/main/java/org/msgpack/core/buffer/ArrayBufferInput.java @@ -17,7 +17,6 @@ import java.io.IOException; -import static org.msgpack.core.Preconditions.checkArgument; import static org.msgpack.core.Preconditions.checkNotNull; /** @@ -41,8 +40,7 @@ public ArrayBufferInput(byte[] arr) public ArrayBufferInput(byte[] arr, int offset, int length) { - checkArgument(offset + length <= arr.length); - this.buffer = MessageBuffer.wrap(checkNotNull(arr, "input array is null")).slice(offset, length); + this(MessageBuffer.wrap(checkNotNull(arr, "input array is null")).slice(offset, length)); } /** From b391406a9da1a14d20a230d673afc485dae7bd60 Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Mon, 4 Jan 2016 13:46:37 +0900 Subject: [PATCH 209/234] remove default factory setter --- .../java/org/msgpack/core/MessagePack.java | 29 +++++-------------- .../msgpack/core/MesssagePackerConfig.java | 8 +++++ 2 files changed, 16 insertions(+), 21 deletions(-) create mode 100644 msgpack-core/src/main/java/org/msgpack/core/MesssagePackerConfig.java diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessagePack.java b/msgpack-core/src/main/java/org/msgpack/core/MessagePack.java index f7fec9f24..65177ae79 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/MessagePack.java +++ b/msgpack-core/src/main/java/org/msgpack/core/MessagePack.java @@ -28,27 +28,14 @@ public class MessagePack { public static final Charset UTF8 = Charset.forName("UTF-8"); - private static MessagePackFactory defaultFactory = new MessagePackFactory(); - - /** - * Sets the default configuration used for the static constructor methods of this MessagePack class. - */ - public static void setDefaultFactory(MessagePackFactory newDefaultFactory) - { - defaultFactory = newDefaultFactory; - } - - public static MessagePackFactory getDefaultFactory() - { - return defaultFactory; - } + private final static MessagePackFactory defaultFactory = new MessagePackFactory(); private MessagePack() { } /** - * Equivalent to getDefaultFactory().newPacker(out). + * Equivalent to defaultFactory().newPacker(out). * * @param out * @return @@ -59,7 +46,7 @@ public static MessagePacker newDefaultPacker(OutputStream out) } /** - * Equivalent to getDefaultFactory().newPacker(channel). + * Equivalent to defaultFactory().newPacker(channel). * * @param channel * @return @@ -70,7 +57,7 @@ public static MessagePacker newDefaultPacker(WritableByteChannel channel) } /** - * Equivalent to getDefaultFactory().newBufferPacker() + * Equivalent to defaultFactory().newBufferPacker() * * @return */ @@ -80,7 +67,7 @@ public static MessageBufferPacker newDefaultBufferPacker() } /** - * Equivalent to getDefaultFactory().newUnpacker(in). + * Equivalent to defaultFactory().newUnpacker(in). * * @param in * @return @@ -91,7 +78,7 @@ public static MessageUnpacker newDefaultUnpacker(InputStream in) } /** - * Equivalent to getDefaultFactory().newUnpacker(channel). + * Equivalent to defaultFactory().newUnpacker(channel). * * @param channel * @return @@ -102,7 +89,7 @@ public static MessageUnpacker newDefaultUnpacker(ReadableByteChannel channel) } /** - * Equivalent to getDefaultFactory().newUnpacker(contents). + * Equivalent to defaultFactory().newUnpacker(contents). * * @param contents * @return @@ -113,7 +100,7 @@ public static MessageUnpacker newDefaultUnpacker(byte[] contents) } /** - * Equivalent to getDefaultFactory().newUnpacker(contents, offset, length). + * Equivalent to defaultFactory().newUnpacker(contents, offset, length). * * @param contents * @param offset diff --git a/msgpack-core/src/main/java/org/msgpack/core/MesssagePackerConfig.java b/msgpack-core/src/main/java/org/msgpack/core/MesssagePackerConfig.java new file mode 100644 index 000000000..c3e39462d --- /dev/null +++ b/msgpack-core/src/main/java/org/msgpack/core/MesssagePackerConfig.java @@ -0,0 +1,8 @@ +package org.msgpack.core; + +/** + * + */ +public class MesssagePackerConfig +{ +} From d9dfb062f1aaa0a6d33b343b91c23e66048910cf Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Mon, 4 Jan 2016 15:35:26 +0900 Subject: [PATCH 210/234] Replace MessagePackFactory with mutable Packer/UnpackerConfig-based code --- .../org/msgpack/core/MessageBufferPacker.java | 30 +-- .../java/org/msgpack/core/MessagePack.java | 173 +++++++++++++-- .../org/msgpack/core/MessagePackFactory.java | 201 ------------------ .../java/org/msgpack/core/MessagePacker.java | 12 +- .../org/msgpack/core/MessageUnpacker.java | 57 ++--- .../msgpack/core/MesssagePackerConfig.java | 8 - .../core/example/MessagePackExample.java | 20 +- .../org/msgpack/core/MessagePackTest.scala | 59 ++--- .../org/msgpack/core/MessagePackerTest.scala | 27 +-- .../msgpack/core/MessageUnpackerTest.scala | 50 +++-- .../msgpack/core/buffer/ByteStringTest.scala | 5 +- .../core/buffer/MessageBufferInputTest.scala | 6 +- .../dataformat/MessagePackGenerator.java | 3 +- .../jackson/dataformat/MessagePackParser.java | 3 +- .../dataformat/MessagePackGeneratorTest.java | 4 +- .../dataformat/MessagePackParserTest.java | 6 +- 16 files changed, 275 insertions(+), 389 deletions(-) delete mode 100644 msgpack-core/src/main/java/org/msgpack/core/MessagePackFactory.java delete mode 100644 msgpack-core/src/main/java/org/msgpack/core/MesssagePackerConfig.java diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessageBufferPacker.java b/msgpack-core/src/main/java/org/msgpack/core/MessageBufferPacker.java index 02b94f773..829803a2d 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/MessageBufferPacker.java +++ b/msgpack-core/src/main/java/org/msgpack/core/MessageBufferPacker.java @@ -22,24 +22,20 @@ import java.io.IOException; import java.util.List; +/** + * MessagePacker that is useful to produce byte array output + */ public class MessageBufferPacker extends MessagePacker { - public MessageBufferPacker() + public MessageBufferPacker(MessagePack.PackerConfig config) { - this(new ArrayBufferOutput()); + this(new ArrayBufferOutput(), config); } - public MessageBufferPacker(ArrayBufferOutput out) + public MessageBufferPacker(ArrayBufferOutput out, MessagePack.PackerConfig config) { - super(out); - } - - @Override - public MessageBufferPacker setSmallStringOptimizationThreshold(int bytes) - { - super.setSmallStringOptimizationThreshold(bytes); - return this; + super(out, config); } public MessageBufferOutput reset(MessageBufferOutput out) @@ -51,23 +47,27 @@ public MessageBufferOutput reset(MessageBufferOutput out) return super.reset(out); } + private ArrayBufferOutput getArrayBufferOut() { + return (ArrayBufferOutput) out; + } + public void clear() { - ((ArrayBufferOutput) out).clear(); + getArrayBufferOut().clear(); } public byte[] toByteArray() { - return ((ArrayBufferOutput) out).toByteArray(); + return getArrayBufferOut().toByteArray(); } public MessageBuffer toMessageBuffer() { - return ((ArrayBufferOutput) out).toMessageBuffer(); + return getArrayBufferOut().toMessageBuffer(); } public List toBufferList() { - return ((ArrayBufferOutput) out).toBufferList(); + return getArrayBufferOut().toBufferList(); } } diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessagePack.java b/msgpack-core/src/main/java/org/msgpack/core/MessagePack.java index 65177ae79..02f94cde4 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/MessagePack.java +++ b/msgpack-core/src/main/java/org/msgpack/core/MessagePack.java @@ -15,11 +15,20 @@ // package org.msgpack.core; +import org.msgpack.core.buffer.ArrayBufferInput; +import org.msgpack.core.buffer.ChannelBufferInput; +import org.msgpack.core.buffer.ChannelBufferOutput; +import org.msgpack.core.buffer.InputStreamBufferInput; +import org.msgpack.core.buffer.MessageBufferInput; +import org.msgpack.core.buffer.MessageBufferOutput; +import org.msgpack.core.buffer.OutputStreamBufferOutput; + import java.io.InputStream; import java.io.OutputStream; import java.nio.channels.ReadableByteChannel; import java.nio.channels.WritableByteChannel; import java.nio.charset.Charset; +import java.nio.charset.CodingErrorAction; /** * This class has MessagePack prefix code definitions and packer/unpacker factory methods. @@ -28,79 +37,100 @@ public class MessagePack { public static final Charset UTF8 = Charset.forName("UTF-8"); - private final static MessagePackFactory defaultFactory = new MessagePackFactory(); - private MessagePack() { + // Prohibit instantiation of this class + } + + /** + * Create a packer that outputs the packed data to the specified output + * + * @param out + * @return + */ + public static MessagePacker newDefaultPacker(MessageBufferOutput out) + { + return new PackerConfig().newPacker(out); } /** - * Equivalent to defaultFactory().newPacker(out). + * Create a packer that outputs the packed data to a target output stream * * @param out * @return */ public static MessagePacker newDefaultPacker(OutputStream out) { - return defaultFactory.newPacker(out); + return new PackerConfig().newPacker(out); } /** - * Equivalent to defaultFactory().newPacker(channel). + * Create a packer that outputs the packed data to a channel * * @param channel * @return */ public static MessagePacker newDefaultPacker(WritableByteChannel channel) { - return defaultFactory.newPacker(channel); + return new PackerConfig().newPacker(channel); } /** - * Equivalent to defaultFactory().newBufferPacker() + * Create a packer for storing packed data into a byte array * * @return */ public static MessageBufferPacker newDefaultBufferPacker() { - return defaultFactory.newBufferPacker(); + return new PackerConfig().newBufferPacker(); } /** - * Equivalent to defaultFactory().newUnpacker(in). + * Create an unpacker that reads the data from a given input + * + * @param in + * @return + */ + public static MessageUnpacker newDefaultUnpacker(MessageBufferInput in) + { + return new UnpackerConfig().newUnpacker(in); + } + + /** + * Create an unpacker that reads the data from a given input stream * * @param in * @return */ public static MessageUnpacker newDefaultUnpacker(InputStream in) { - return defaultFactory.newUnpacker(in); + return new UnpackerConfig().newUnpacker(in); } /** - * Equivalent to defaultFactory().newUnpacker(channel). + * Create an unpacker that reads the data from a given channel * * @param channel * @return */ public static MessageUnpacker newDefaultUnpacker(ReadableByteChannel channel) { - return defaultFactory.newUnpacker(channel); + return new UnpackerConfig().newUnpacker(channel); } /** - * Equivalent to defaultFactory().newUnpacker(contents). + * Create an unpacker that reads the data from a given byte array * * @param contents * @return */ public static MessageUnpacker newDefaultUnpacker(byte[] contents) { - return defaultFactory.newUnpacker(contents); + return new UnpackerConfig().newUnpacker(contents); } /** - * Equivalent to defaultFactory().newUnpacker(contents, offset, length). + * Create an unpacker that reads the data from a given byte array [offset, offset+length) * * @param contents * @param offset @@ -109,6 +139,117 @@ public static MessageUnpacker newDefaultUnpacker(byte[] contents) */ public static MessageUnpacker newDefaultUnpacker(byte[] contents, int offset, int length) { - return defaultFactory.newUnpacker(contents, offset, length); + return new UnpackerConfig().newUnpacker(contents, offset, length); + } + + /** + * MessagePacker configuration. + */ + public static class PackerConfig + { + public int smallStringOptimizationThreshold = 512; + + /** + * Create a packer that outputs the packed data to a given output + * + * @param out + * @return + */ + public MessagePacker newPacker(MessageBufferOutput out) { + return new MessagePacker(out, this); + } + + /** + * Create a packer that outputs the packed data to a given output stream + * + * @param out + * @return + */ + public MessagePacker newPacker(OutputStream out) { + return newPacker(new OutputStreamBufferOutput(out)); + } + + /** + * Create a packer that outputs the packed data to a given output channel + * + * @param channel + * @return + */ + public MessagePacker newPacker(WritableByteChannel channel) { + return newPacker(new ChannelBufferOutput(channel)); + } + + /** + * Create a packer for storing packed data into a byte array + * + * @return + */ + public MessageBufferPacker newBufferPacker() { + return new MessageBufferPacker(this); + } + } + + /** + * MessageUnpacker configuration. + */ + public static class UnpackerConfig + { + public boolean allowStringAsBinary = true; + public boolean allowBinaryAsString = true; + public CodingErrorAction actionOnMalformedString = CodingErrorAction.REPLACE; + public CodingErrorAction actionOnUnmappableString = CodingErrorAction.REPLACE; + public int stringSizeLimit = Integer.MAX_VALUE; + public int stringDecoderBufferSize = 8192; + + /** + * Create an unpacker that reads the data from a given input + * + * @param in + * @return + */ + public MessageUnpacker newUnpacker(MessageBufferInput in) { + return new MessageUnpacker(in, this); + } + + /** + * Create an unpacker that reads the data from a given input stream + * + * @param in + * @return + */ + public MessageUnpacker newUnpacker(InputStream in) { + return newUnpacker(new InputStreamBufferInput(in)); + } + + /** + * Create an unpacker that reads the data from a given channel + * + * @param channel + * @return + */ + public MessageUnpacker newUnpacker(ReadableByteChannel channel) { + return newUnpacker(new ChannelBufferInput(channel)); + } + + /** + * Create an unpacker that reads the data from a given byte array + * + * @param contents + * @return + */ + public MessageUnpacker newUnpacker(byte[] contents) { + return newUnpacker(new ArrayBufferInput(contents)); + } + + /** + * Create an unpacker that reads the data from a given byte array [offset, offset+size) + * + * @param contents + * @return + */ + public MessageUnpacker newUnpacker(byte[] contents, int offset, int length) { + return newUnpacker(new ArrayBufferInput(contents, offset, length)); + } + } } diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessagePackFactory.java b/msgpack-core/src/main/java/org/msgpack/core/MessagePackFactory.java deleted file mode 100644 index 8863e4637..000000000 --- a/msgpack-core/src/main/java/org/msgpack/core/MessagePackFactory.java +++ /dev/null @@ -1,201 +0,0 @@ -// -// MessagePack for Java -// -// 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.core; - -import org.msgpack.core.buffer.ArrayBufferInput; -import org.msgpack.core.buffer.ChannelBufferInput; -import org.msgpack.core.buffer.ChannelBufferOutput; -import org.msgpack.core.buffer.InputStreamBufferInput; -import org.msgpack.core.buffer.MessageBufferInput; -import org.msgpack.core.buffer.MessageBufferOutput; -import org.msgpack.core.buffer.OutputStreamBufferOutput; - -import java.io.InputStream; -import java.io.OutputStream; -import java.nio.channels.ReadableByteChannel; -import java.nio.channels.WritableByteChannel; -import java.nio.charset.CodingErrorAction; - -public class MessagePackFactory -{ - private int packerSmallStringOptimizationThreshold = 512; - - private boolean unpackAllowStringAsBinary = true; - private boolean unpackAllowBinaryAsString = true; - private CodingErrorAction unpackActionOnMalformedString = CodingErrorAction.REPLACE; - private CodingErrorAction unpackActionOnUnmappableString = CodingErrorAction.REPLACE; - private int unpackStringSizeLimit = Integer.MAX_VALUE; - private int unpackStringDecoderBufferSize = 8192; - - private int inputBufferSize = 16 * 1024; - private int outputBufferSize = 16 * 1024; - - public MessagePacker newPacker(OutputStream out) - { - return newPacker(new OutputStreamBufferOutput(out)); - } - - public MessagePacker newPacker(WritableByteChannel channel) - { - return newPacker(new ChannelBufferOutput(channel)); - } - - public MessagePacker newPacker(MessageBufferOutput output) - { - return new MessagePacker(output) - .setSmallStringOptimizationThreshold(packerSmallStringOptimizationThreshold); - } - - public MessageBufferPacker newBufferPacker() - { - return new MessageBufferPacker() - .setSmallStringOptimizationThreshold(packerSmallStringOptimizationThreshold); - } - - public MessageUnpacker newUnpacker(byte[] contents) - { - return newUnpacker(contents, 0, contents.length); - } - - public MessageUnpacker newUnpacker(byte[] contents, int offset, int length) - { - return newUnpacker(new ArrayBufferInput(contents, offset, length)); - } - - public MessageUnpacker newUnpacker(InputStream in) - { - return newUnpacker(new InputStreamBufferInput(in)); - } - - public MessageUnpacker newUnpacker(ReadableByteChannel channel) - { - return newUnpacker(new ChannelBufferInput(channel)); - } - - public MessageUnpacker newUnpacker(MessageBufferInput input) - { - return new MessageUnpacker(input) - .setAllowStringAsBinary(unpackAllowStringAsBinary) - .setAllowBinaryAsString(unpackAllowBinaryAsString) - .setActionOnMalformedString(unpackActionOnMalformedString) - .setActionOnUnmappableString(unpackActionOnUnmappableString) - .setStringSizeLimit(unpackStringSizeLimit) - .setStringDecoderBufferSize(unpackStringDecoderBufferSize); - } - - /** - * Use String.getBytes() for strings smaller than this threshold. - * Note that this parameter is subject to change. - */ - public MessagePackFactory packerSmallStringOptimizationThreshold(int bytes) - { - this.packerSmallStringOptimizationThreshold = bytes; - return this; - } - - public MessagePackFactory unpackAllowStringAsBinary(boolean enabled) - { - this.unpackAllowStringAsBinary = enabled; - return this; - } - - public MessagePackFactory unpackAllowBinaryAsString(boolean enabled) - { - this.unpackAllowBinaryAsString = enabled; - return this; - } - - public MessagePackFactory unpackActionOnMalformedString(CodingErrorAction action) - { - this.unpackActionOnMalformedString = action; - return this; - } - - public MessagePackFactory unpackActionOnUnmappableString(CodingErrorAction action) - { - this.unpackActionOnUnmappableString = action; - return this; - } - - public MessagePackFactory unpackStringSizeLimit(int bytes) - { - this.unpackStringSizeLimit = bytes; - return this; - } - - public MessagePackFactory unpackStringDecoderBufferSize(int bytes) - { - this.unpackStringDecoderBufferSize = bytes; - return this; - } - - public MessagePackFactory inputBufferSize(int bytes) - { - this.inputBufferSize = bytes; - return this; - } - - public MessagePackFactory outputBufferSize(int bytes) - { - this.inputBufferSize = bytes; - return this; - } - - private int getPackerSmallStringOptimizationThreshold() - { - return packerSmallStringOptimizationThreshold; - } - - private boolean getUnpackAllowStringAsBinary() - { - return unpackAllowStringAsBinary; - } - - private boolean getUnpackAllowBinaryAsString() - { - return unpackAllowBinaryAsString; - } - - private CodingErrorAction getUnpackActionOnMalformedString() - { - return unpackActionOnMalformedString; - } - - private CodingErrorAction getUnpackActionOnUnmappableString() - { - return unpackActionOnUnmappableString; - } - - private int getUnpackStringSizeLimit() - { - return unpackStringSizeLimit; - } - - private int getUnpackStringDecoderBufferSize() - { - return unpackStringDecoderBufferSize; - } - - private int getInputBufferSize() - { - return inputBufferSize; - } - - private int getOutputBufferSize() - { - return outputBufferSize; - } -} diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessagePacker.java b/msgpack-core/src/main/java/org/msgpack/core/MessagePacker.java index e0b1b6c65..c54943d2c 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/MessagePacker.java +++ b/msgpack-core/src/main/java/org/msgpack/core/MessagePacker.java @@ -84,7 +84,7 @@ public class MessagePacker implements Closeable { - private int smallStringOptimizationThreshold = 512; + private final int smallStringOptimizationThreshold; protected MessageBufferOutput out; @@ -108,19 +108,15 @@ public class MessagePacker * @param out MessageBufferOutput. Use {@link org.msgpack.core.buffer.OutputStreamBufferOutput}, {@link org.msgpack.core.buffer.ChannelBufferOutput} or * your own implementation of {@link org.msgpack.core.buffer.MessageBufferOutput} interface. */ - public MessagePacker(MessageBufferOutput out) + public MessagePacker(MessageBufferOutput out, MessagePack.PackerConfig config) { this.out = checkNotNull(out, "MessageBufferOutput is null"); + // We must copy the configuration parameters here since the config object is mutable + this.smallStringOptimizationThreshold = config.smallStringOptimizationThreshold; this.position = 0; this.totalFlushBytes = 0; } - public MessagePacker setSmallStringOptimizationThreshold(int bytes) - { - this.smallStringOptimizationThreshold = bytes; - return this; - } - /** * Reset output. This method doesn't close the old resource. * diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java b/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java index 017022204..1602aa165 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java +++ b/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java @@ -73,12 +73,12 @@ public class MessageUnpacker private static final byte HEAD_BYTE_REQUIRED = (byte) 0xc1; - private boolean allowStringAsBinary = true; - private boolean allowBinaryAsString = true; - private CodingErrorAction actionOnMalformedString = CodingErrorAction.REPLACE; - private CodingErrorAction actionOnUnmappableString = CodingErrorAction.REPLACE; - private int stringSizeLimit = Integer.MAX_VALUE; - private int stringDecoderBufferSize = 8192; + private final boolean allowStringAsBinary; + private final boolean allowBinaryAsString; + private final CodingErrorAction actionOnMalformedString; + private final CodingErrorAction actionOnUnmappableString; + private final int stringSizeLimit; + private final int stringDecoderBufferSize; private MessageBufferInput in; @@ -130,45 +130,16 @@ public class MessageUnpacker * * @param in */ - public MessageUnpacker(MessageBufferInput in) + public MessageUnpacker(MessageBufferInput in, MessagePack.UnpackerConfig config) { this.in = checkNotNull(in, "MessageBufferInput is null"); - } - - public MessageUnpacker setAllowStringAsBinary(boolean enabled) - { - this.allowStringAsBinary = enabled; - return this; - } - - public MessageUnpacker setAllowBinaryAsString(boolean enabled) - { - this.allowBinaryAsString = enabled; - return this; - } - - public MessageUnpacker setActionOnMalformedString(CodingErrorAction action) - { - this.actionOnMalformedString = action; - return this; - } - - public MessageUnpacker setActionOnUnmappableString(CodingErrorAction action) - { - this.actionOnUnmappableString = action; - return this; - } - - public MessageUnpacker setStringSizeLimit(int bytes) - { - this.stringSizeLimit = bytes; - return this; - } - - public MessageUnpacker setStringDecoderBufferSize(int bytes) - { - this.stringDecoderBufferSize = bytes; - return this; + // We need to copy the configuration parameters since the config object is mutable + this.allowStringAsBinary = config.allowStringAsBinary; + this.allowBinaryAsString = config.allowBinaryAsString; + this.actionOnMalformedString = config.actionOnMalformedString; + this.actionOnUnmappableString = config.actionOnUnmappableString; + this.stringSizeLimit = config.stringSizeLimit; + this.stringDecoderBufferSize = config.stringDecoderBufferSize; } /** diff --git a/msgpack-core/src/main/java/org/msgpack/core/MesssagePackerConfig.java b/msgpack-core/src/main/java/org/msgpack/core/MesssagePackerConfig.java deleted file mode 100644 index c3e39462d..000000000 --- a/msgpack-core/src/main/java/org/msgpack/core/MesssagePackerConfig.java +++ /dev/null @@ -1,8 +0,0 @@ -package org.msgpack.core; - -/** - * - */ -public class MesssagePackerConfig -{ -} diff --git a/msgpack-core/src/test/java/org/msgpack/core/example/MessagePackExample.java b/msgpack-core/src/test/java/org/msgpack/core/example/MessagePackExample.java index 9a8242591..cbaf44f9b 100644 --- a/msgpack-core/src/test/java/org/msgpack/core/example/MessagePackExample.java +++ b/msgpack-core/src/test/java/org/msgpack/core/example/MessagePackExample.java @@ -17,7 +17,7 @@ import org.msgpack.core.MessageFormat; import org.msgpack.core.MessagePack; -import org.msgpack.core.MessagePackFactory; +import org.msgpack.core.MessagePack.PackerConfig; import org.msgpack.core.MessagePacker; import org.msgpack.core.MessageUnpacker; import org.msgpack.value.ArrayValue; @@ -245,23 +245,21 @@ else if (iv.isInLongRange()) { public static void configuration() throws IOException { - // Build a conifiguration - MessagePackFactory factory = new MessagePackFactory() - .unpackActionOnMalformedString(CodingErrorAction.REPLACE) // Drop malformed and unmappable UTF-8 characters - .unpackActionOnUnmappableString(CodingErrorAction.REPLACE) - .outputBufferSize(8192 * 2); - // Create a that uses this configuration - - // Pack data ByteArrayOutputStream out = new ByteArrayOutputStream(); - MessagePacker packer = factory.newPacker(out); + PackerConfig packerConfig = new PackerConfig(); + packerConfig.smallStringOptimizationThreshold = 256; // String + MessagePacker packer = packerConfig.newPacker(out); + packer.packInt(10); packer.packBoolean(true); packer.close(); // Unpack data + MessagePack.UnpackerConfig unpackerConfig = new MessagePack.UnpackerConfig(); + unpackerConfig.stringDecoderBufferSize = 16 * 1024; // If your data contains many large strings (the default is 8k) + byte[] packedData = out.toByteArray(); - MessageUnpacker unpacker = factory.newUnpacker(packedData); + MessageUnpacker unpacker = unpackerConfig.newUnpacker(packedData); int i = unpacker.unpackInt(); // 10 boolean b = unpacker.unpackBoolean(); // true unpacker.close(); diff --git a/msgpack-core/src/test/scala/org/msgpack/core/MessagePackTest.scala b/msgpack-core/src/test/scala/org/msgpack/core/MessagePackTest.scala index e1dc1d673..d11383e7f 100644 --- a/msgpack-core/src/test/scala/org/msgpack/core/MessagePackTest.scala +++ b/msgpack-core/src/test/scala/org/msgpack/core/MessagePackTest.scala @@ -21,6 +21,7 @@ import java.nio.CharBuffer import java.nio.charset.{CodingErrorAction, UnmappableCharacterException} import org.msgpack.core.MessageFormat.Code +import org.msgpack.core.MessagePack.{UnpackerConfig, PackerConfig} import org.msgpack.value.{Value, Variable} import scala.util.Random @@ -60,13 +61,13 @@ class MessagePackTest extends MessagePackSpec { } "detect fixarray values" in { - val packer = new MessagePackFactory().newBufferPacker() + val packer = MessagePack.newDefaultBufferPacker() packer.packArrayHeader(0) packer.close val bytes = packer.toByteArray - new MessagePackFactory().newUnpacker(bytes).unpackArrayHeader() shouldBe 0 + MessagePack.newDefaultUnpacker(bytes).unpackArrayHeader() shouldBe 0 try { - new MessagePackFactory().newUnpacker(bytes).unpackMapHeader() + MessagePack.newDefaultUnpacker(bytes).unpackMapHeader() fail("Shouldn't reach here") } catch { @@ -75,13 +76,13 @@ class MessagePackTest extends MessagePackSpec { } "detect fixmap values" in { - val packer = new MessagePackFactory().newBufferPacker() + val packer = MessagePack.newDefaultBufferPacker() packer.packMapHeader(0) packer.close val bytes = packer.toByteArray - new MessagePackFactory().newUnpacker(bytes).unpackMapHeader() shouldBe 0 + MessagePack.newDefaultUnpacker(bytes).unpackMapHeader() shouldBe 0 try { - new MessagePackFactory().newUnpacker(bytes).unpackArrayHeader() + MessagePack.newDefaultUnpacker(bytes).unpackArrayHeader() fail("Shouldn't reach here") } catch { @@ -147,17 +148,23 @@ class MessagePackTest extends MessagePackSpec { } - def check[A](v: A, pack: MessagePacker => Unit, unpack: MessageUnpacker => A, factory: MessagePackFactory = new MessagePackFactory()): Unit = { + def check[A]( + v: A, + pack: MessagePacker => Unit, + unpack: MessageUnpacker => A, + packerConfig: PackerConfig = new PackerConfig(), + unpackerConfig: UnpackerConfig = new UnpackerConfig() + ): Unit = { var b: Array[Byte] = null try { val bs = new ByteArrayOutputStream() - val packer = factory.newPacker(bs) + val packer = packerConfig.newPacker(bs) pack(packer) packer.close() b = bs.toByteArray - val unpacker = factory.newUnpacker(b) + val unpacker = unpackerConfig.newUnpacker(b) val ret = unpack(unpacker) ret shouldBe v } @@ -171,17 +178,22 @@ class MessagePackTest extends MessagePackSpec { } } - def checkException[A](v: A, pack: MessagePacker => Unit, unpack: MessageUnpacker => A, - factory: MessagePackFactory = new MessagePackFactory()): Unit = { + def checkException[A]( + v: A, + pack: MessagePacker => Unit, + unpack: MessageUnpacker => A, + packerConfig: PackerConfig = new PackerConfig(), + unpaackerConfig: UnpackerConfig = new UnpackerConfig() + ): Unit = { var b: Array[Byte] = null val bs = new ByteArrayOutputStream() - val packer = factory.newPacker(bs) + val packer = packerConfig.newPacker(bs) pack(packer) packer.close() b = bs.toByteArray - val unpacker = factory.newUnpacker(b) + val unpacker = unpaackerConfig.newUnpacker(b) val ret = unpack(unpacker) fail("cannot not reach here") @@ -196,9 +208,6 @@ class MessagePackTest extends MessagePackSpec { } } - - - "pack/unpack primitive values" taggedAs ("prim") in { forAll { (v: Boolean) => check(v, _.packBoolean(v), _.unpackBoolean) } forAll { (v: Byte) => check(v, _.packByte(v), _.unpackByte) } @@ -327,9 +336,9 @@ class MessagePackTest extends MessagePackSpec { //val unmappableChar = Array[Char](new Character(0xfc0a).toChar) // Report error on unmappable character - val factory = new MessagePackFactory() - .unpackActionOnMalformedString(CodingErrorAction.REPORT) - .unpackActionOnUnmappableString(CodingErrorAction.REPORT); + val unpackerConfig = new UnpackerConfig() + unpackerConfig.actionOnMalformedString = CodingErrorAction.REPORT + unpackerConfig.actionOnUnmappableString = CodingErrorAction.REPORT for (bytes <- Seq(unmappable)) { When("unpacking") @@ -339,20 +348,12 @@ class MessagePackTest extends MessagePackSpec { packer.writePayload(bytes) }, _.unpackString(), - factory) + new PackerConfig(), + unpackerConfig) } catch { case e: MessageStringCodingException => // OK } - - // When("packing") - // try { - // val s = new String(unmappableChar) - // checkException(s, _.packString(s), _.unpackString()) - // } - // catch { - // case e:MessageStringCodingException => // OK - // } } } diff --git a/msgpack-core/src/test/scala/org/msgpack/core/MessagePackerTest.scala b/msgpack-core/src/test/scala/org/msgpack/core/MessagePackerTest.scala index 51d411f5f..2fbe461d1 100644 --- a/msgpack-core/src/test/scala/org/msgpack/core/MessagePackerTest.scala +++ b/msgpack-core/src/test/scala/org/msgpack/core/MessagePackerTest.scala @@ -16,8 +16,8 @@ package org.msgpack.core import java.io.{ByteArrayOutputStream, File, FileInputStream, FileOutputStream} -import java.nio.ByteBuffer +import org.msgpack.core.MessagePack.{UnpackerConfig, PackerConfig} import org.msgpack.core.buffer.{ChannelBufferOutput, OutputStreamBufferOutput} import org.msgpack.value.ValueFactory import xerial.core.io.IOUtil @@ -27,13 +27,10 @@ import scala.util.Random /** * */ -class MessagePackerTest - extends MessagePackSpec { - - val factory = new MessagePackFactory() +class MessagePackerTest extends MessagePackSpec { def verifyIntSeq(answer: Array[Int], packed: Array[Byte]) { - val unpacker = factory.newUnpacker(packed) + val unpacker = MessagePack.newDefaultUnpacker(packed) val b = Array.newBuilder[Int] while (unpacker.hasNext) { b += unpacker.unpackInt() @@ -69,7 +66,7 @@ class MessagePackerTest val b = new ByteArrayOutputStream - val packer = factory.newPacker(b) + val packer = MessagePack.newDefaultPacker(b) intSeq foreach packer.packInt packer.close verifyIntSeq(intSeq, b.toByteArray) @@ -102,7 +99,7 @@ class MessagePackerTest block("no-buffer-reset") { val out = new ByteArrayOutputStream - IOUtil.withResource(factory.newPacker(out)) { packer => + IOUtil.withResource(MessagePack.newDefaultPacker(out)) { packer => for (i <- 0 until N) { val outputStream = new ByteArrayOutputStream() @@ -118,7 +115,7 @@ class MessagePackerTest block("buffer-reset") { val out = new ByteArrayOutputStream - IOUtil.withResource(factory.newPacker(out)) { packer => + IOUtil.withResource(MessagePack.newDefaultPacker(out)) { packer => val bufferOut = new OutputStreamBufferOutput(new ByteArrayOutputStream()) @@ -140,23 +137,19 @@ class MessagePackerTest "pack larger string array than byte buf" taggedAs ("larger-string-array-than-byte-buf") in { // Based on https://github.com/msgpack/msgpack-java/issues/154 - // TODO: Refactor this test code to fit other ones. def test(bufferSize: Int, stringSize: Int): Boolean = { - val factory = new MessagePackFactory() - .outputBufferSize(bufferSize); val str = "a" * stringSize val rawString = ValueFactory.newString(str.getBytes("UTF-8")) val array = ValueFactory.newArray(rawString) - val out = new - ByteArrayOutputStream() - val packer = factory.newPacker(out) + val out = new ByteArrayOutputStream(bufferSize) + val packer = MessagePack.newDefaultPacker(out) packer.packValue(array) packer.close() out.toByteArray true } - val testCases = List( + val testCases = Seq( 32 -> 30, 33 -> 31, 32 -> 31, @@ -265,7 +258,7 @@ class MessagePackerTest "compute totalWrittenBytes" in { val out = new ByteArrayOutputStream - val packerTotalWrittenBytes = IOUtil.withResource(factory.newPacker(out)) { packer => + val packerTotalWrittenBytes = IOUtil.withResource(MessagePack.newDefaultPacker(out)) { packer => packer.packByte(0) // 1 .packBoolean(true) // 1 .packShort(12) // 1 diff --git a/msgpack-core/src/test/scala/org/msgpack/core/MessageUnpackerTest.scala b/msgpack-core/src/test/scala/org/msgpack/core/MessageUnpackerTest.scala index 2611d8c9d..e8ed65be7 100644 --- a/msgpack-core/src/test/scala/org/msgpack/core/MessageUnpackerTest.scala +++ b/msgpack-core/src/test/scala/org/msgpack/core/MessageUnpackerTest.scala @@ -29,11 +29,9 @@ import scala.util.Random */ class MessageUnpackerTest extends MessagePackSpec { - val factory = new MessagePackFactory() - def testData: Array[Byte] = { val out = new ByteArrayOutputStream() - val packer = factory.newPacker(out) + val packer = MessagePack.newDefaultPacker(out) packer .packArrayHeader(2) @@ -55,7 +53,7 @@ class MessageUnpackerTest extends MessagePackSpec { def testData2: Array[Byte] = { val out = new ByteArrayOutputStream() - val packer = factory.newPacker(out); + val packer = MessagePack.newDefaultPacker(out); packer .packBoolean(true) @@ -125,7 +123,7 @@ class MessageUnpackerTest extends MessagePackSpec { def testData3(N: Int): Array[Byte] = { val out = new ByteArrayOutputStream() - val packer = factory.newPacker(out) + val packer = MessagePack.newDefaultPacker(out) val r = new Random(0) @@ -179,7 +177,7 @@ class MessageUnpackerTest extends MessagePackSpec { "parse message packed data" taggedAs ("unpack") in { val arr = testData - val unpacker = factory.newUnpacker(arr) + val unpacker = MessagePack.newDefaultUnpacker(arr) var count = 0 while (unpacker.hasNext) { @@ -192,7 +190,7 @@ class MessageUnpackerTest extends MessagePackSpec { "skip reading values" in { - val unpacker = factory.newUnpacker(testData) + val unpacker = MessagePack.newDefaultUnpacker(testData) var skipCount = 0 while (unpacker.hasNext) { unpacker.skipValue() @@ -209,7 +207,7 @@ class MessageUnpackerTest extends MessagePackSpec { time("skip performance", repeat = 100) { block("switch") { - val unpacker = factory.newUnpacker(data) + val unpacker = MessagePack.newDefaultUnpacker(data) var skipCount = 0 while (unpacker.hasNext) { unpacker.skipValue() @@ -227,7 +225,7 @@ class MessageUnpackerTest extends MessagePackSpec { val ib = Seq.newBuilder[Int] - val unpacker = factory.newUnpacker(testData2) + val unpacker = MessagePack.newDefaultUnpacker(testData2) while (unpacker.hasNext) { val f = unpacker.getNextFormat f.getValueType match { @@ -269,7 +267,7 @@ class MessageUnpackerTest extends MessagePackSpec { trait SplitTest { val data: Array[Byte] def run { - val unpacker = factory.newUnpacker(data) + val unpacker = MessagePack.newDefaultUnpacker(data) val numElems = { var c = 0 while (unpacker.hasNext) { @@ -283,7 +281,7 @@ class MessageUnpackerTest extends MessagePackSpec { debug(s"split at $splitPoint") val (h, t) = data.splitAt(splitPoint) val bin = new SplitMessageBufferInput(Array(h, t)) - val unpacker = new MessageUnpacker(bin) + val unpacker = MessagePack.newDefaultUnpacker(bin) var count = 0 while (unpacker.hasNext) { count += 1 @@ -326,7 +324,7 @@ class MessageUnpackerTest extends MessagePackSpec { } block("v7") { - val unpacker = factory.newUnpacker(data) + val unpacker = MessagePack.newDefaultUnpacker(data) var count = 0 try { while (unpacker.hasNext) { @@ -428,7 +426,7 @@ class MessageUnpackerTest extends MessagePackSpec { } block("v7") { - val unpacker = factory.newUnpacker(data) + val unpacker = MessagePack.newDefaultUnpacker(data) var count = 0 try { while (unpacker.hasNext) { @@ -449,7 +447,7 @@ class MessageUnpackerTest extends MessagePackSpec { "be faster for reading binary than v6" taggedAs ("cmp-binary") in { val bos = new ByteArrayOutputStream() - val packer = factory.newPacker(bos) + val packer = MessagePack.newDefaultPacker(bos) val L = 10000 val R = 100 (0 until R).foreach { i => @@ -472,7 +470,7 @@ class MessageUnpackerTest extends MessagePackSpec { } block("v7") { - val unpacker = factory.newUnpacker(b) + val unpacker = MessagePack.newDefaultUnpacker(b) var i = 0 while (i < R) { val len = unpacker.unpackBinaryHeader() @@ -484,7 +482,7 @@ class MessageUnpackerTest extends MessagePackSpec { } block("v7-ref") { - val unpacker = factory.newUnpacker(b) + val unpacker = MessagePack.newDefaultUnpacker(b) var i = 0 while (i < R) { val len = unpacker.unpackBinaryHeader() @@ -505,12 +503,12 @@ class MessageUnpackerTest extends MessagePackSpec { val data = new Array[Byte](s) Random.nextBytes(data) val b = new ByteArrayOutputStream() - val packer = factory.newPacker(b) + val packer = MessagePack.newDefaultPacker(b) packer.packBinaryHeader(s) packer.writePayload(data) packer.close() - val unpacker = factory.newUnpacker(b.toByteArray) + val unpacker = MessagePack.newDefaultUnpacker(b.toByteArray) val len = unpacker.unpackBinaryHeader() len shouldBe s val ref = unpacker.readPayloadAsReference(len) @@ -529,7 +527,7 @@ class MessageUnpackerTest extends MessagePackSpec { val data = intSeq val b = createMessagePackData(packer => data foreach packer.packInt) - val unpacker = factory.newUnpacker(b) + val unpacker = MessagePack.newDefaultUnpacker(b) val unpacked = Array.newBuilder[Int] while (unpacker.hasNext) { @@ -564,7 +562,7 @@ class MessageUnpackerTest extends MessagePackSpec { "improve the performance via reset method" taggedAs ("reset-arr") in { val out = new ByteArrayOutputStream - val packer = factory.newPacker(out) + val packer = MessagePack.newDefaultPacker(out) packer.packInt(0) packer.flush val arr = out.toByteArray @@ -573,7 +571,7 @@ class MessageUnpackerTest extends MessagePackSpec { val N = 1000 val t = time("unpacker", repeat = 10) { block("no-buffer-reset") { - IOUtil.withResource(factory.newUnpacker(arr)) { unpacker => + IOUtil.withResource(MessagePack.newDefaultUnpacker(arr)) { unpacker => for (i <- 0 until N) { val buf = new ArrayBufferInput(arr) unpacker.reset(buf) @@ -584,7 +582,7 @@ class MessageUnpackerTest extends MessagePackSpec { } block("reuse-array-input") { - IOUtil.withResource(factory.newUnpacker(arr)) { unpacker => + IOUtil.withResource(MessagePack.newDefaultUnpacker(arr)) { unpacker => val buf = new ArrayBufferInput(arr) for (i <- 0 until N) { buf.reset(arr) @@ -596,7 +594,7 @@ class MessageUnpackerTest extends MessagePackSpec { } block("reuse-message-buffer") { - IOUtil.withResource(factory.newUnpacker(arr)) { unpacker => + IOUtil.withResource(MessagePack.newDefaultUnpacker(arr)) { unpacker => val buf = new ArrayBufferInput(arr) for (i <- 0 until N) { buf.reset(mb) @@ -640,7 +638,7 @@ class MessageUnpackerTest extends MessagePackSpec { "unpack large string data" taggedAs ("large-string") in { def createLargeData(stringLength: Int): Array[Byte] = { val out = new ByteArrayOutputStream() - val packer = factory.newPacker(out) + val packer = MessagePack.newDefaultPacker(out) packer .packArrayHeader(2) @@ -655,7 +653,7 @@ class MessageUnpackerTest extends MessagePackSpec { Seq(8191, 8192, 8193, 16383, 16384, 16385).foreach { n => val arr = createLargeData(n) - val unpacker = factory.newUnpacker(arr) + val unpacker = MessagePack.newDefaultUnpacker(arr) unpacker.unpackArrayHeader shouldBe 2 unpacker.unpackString.length shouldBe n @@ -676,7 +674,7 @@ class MessageUnpackerTest extends MessagePackSpec { packer.packString(expected) packer.close - val unpacker = new MessageUnpacker(new InputStreamBufferInput(new ByteArrayInputStream(out.toByteArray))) + val unpacker = MessagePack.newDefaultUnpacker(new InputStreamBufferInput(new ByteArrayInputStream(out.toByteArray))) val len = unpacker.unpackBinaryHeader unpacker.readPayload(len) val got = unpacker.unpackString diff --git a/msgpack-core/src/test/scala/org/msgpack/core/buffer/ByteStringTest.scala b/msgpack-core/src/test/scala/org/msgpack/core/buffer/ByteStringTest.scala index eb78432d2..2c080b59a 100644 --- a/msgpack-core/src/test/scala/org/msgpack/core/buffer/ByteStringTest.scala +++ b/msgpack-core/src/test/scala/org/msgpack/core/buffer/ByteStringTest.scala @@ -16,7 +16,7 @@ package org.msgpack.core.buffer import akka.util.ByteString -import org.msgpack.core.{MessagePackSpec, MessageUnpacker} +import org.msgpack.core.{MessagePack, MessagePackSpec, MessageUnpacker} class ByteStringTest extends MessagePackSpec { @@ -41,7 +41,6 @@ class ByteStringTest override def close(): Unit = {} } - new - MessageUnpacker(input).unpackString() + MessagePack.newDefaultUnpacker(input).unpackString() } } diff --git a/msgpack-core/src/test/scala/org/msgpack/core/buffer/MessageBufferInputTest.scala b/msgpack-core/src/test/scala/org/msgpack/core/buffer/MessageBufferInputTest.scala index 6333e381c..1638806ee 100644 --- a/msgpack-core/src/test/scala/org/msgpack/core/buffer/MessageBufferInputTest.scala +++ b/msgpack-core/src/test/scala/org/msgpack/core/buffer/MessageBufferInputTest.scala @@ -24,9 +24,6 @@ import xerial.core.io.IOUtil._ import scala.util.Random -/** - * Created on 5/30/14. - */ class MessageBufferInputTest extends MessagePackSpec { @@ -144,8 +141,7 @@ class MessageBufferInputTest } def readInt(buf: MessageBufferInput): Int = { - val unpacker = new - MessageUnpacker(buf) + val unpacker = MessagePack.newDefaultUnpacker(buf) unpacker.unpackInt } diff --git a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackGenerator.java b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackGenerator.java index c040ee7dd..e62528a75 100644 --- a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackGenerator.java +++ b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackGenerator.java @@ -20,6 +20,7 @@ import com.fasterxml.jackson.core.ObjectCodec; import com.fasterxml.jackson.core.base.GeneratorBase; import com.fasterxml.jackson.core.json.JsonWriteContext; +import org.msgpack.core.MessagePack; import org.msgpack.core.MessagePacker; import org.msgpack.core.buffer.OutputStreamBufferOutput; @@ -109,7 +110,7 @@ public MessagePackGenerator(int features, ObjectCodec codec, OutputStream out) messageBufferOutputHolder.set(messageBufferOutput); if (messagePacker == null) { - messagePacker = new MessagePacker(messageBufferOutput); + messagePacker = MessagePack.newDefaultPacker(messageBufferOutput); } else { messagePacker.reset(messageBufferOutput); diff --git a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java index 08be64e59..e85ff7cd6 100644 --- a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java +++ b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java @@ -28,6 +28,7 @@ import com.fasterxml.jackson.core.io.IOContext; import com.fasterxml.jackson.core.json.DupDetector; import com.fasterxml.jackson.core.json.JsonReadContext; +import org.msgpack.core.MessagePack; import org.msgpack.core.MessageUnpacker; import org.msgpack.core.buffer.ArrayBufferInput; import org.msgpack.core.buffer.InputStreamBufferInput; @@ -126,7 +127,7 @@ private MessagePackParser(IOContext ctxt, int features, MessageBufferInput input MessageUnpacker messageUnpacker; Tuple messageUnpackerTuple = messageUnpackerHolder.get(); if (messageUnpackerTuple == null) { - messageUnpacker = new MessageUnpacker(input); + messageUnpacker = MessagePack.newDefaultUnpacker(input); } else { // Considering to reuse InputStream with JsonParser.Feature.AUTO_CLOSE_SOURCE, diff --git a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackGeneratorTest.java b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackGeneratorTest.java index 845c45f40..d7f8be600 100644 --- a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackGeneratorTest.java +++ b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackGeneratorTest.java @@ -86,7 +86,7 @@ public void testGeneratorShouldWriteObject() long bitmap = 0; byte[] bytes = objectMapper.writeValueAsBytes(hashMap); - MessageUnpacker messageUnpacker = new MessageUnpacker(new ArrayBufferInput(bytes)); + MessageUnpacker messageUnpacker = MessagePack.newDefaultUnpacker(new ArrayBufferInput(bytes)); assertEquals(hashMap.size(), messageUnpacker.unpackMapHeader()); for (int i = 0; i < hashMap.size(); i++) { String key = messageUnpacker.unpackString(); @@ -199,7 +199,7 @@ public void testGeneratorShouldWriteArray() long bitmap = 0; byte[] bytes = objectMapper.writeValueAsBytes(array); - MessageUnpacker messageUnpacker = new MessageUnpacker(new ArrayBufferInput(bytes)); + MessageUnpacker messageUnpacker = MessagePack.newDefaultUnpacker(new ArrayBufferInput(bytes)); assertEquals(array.size(), messageUnpacker.unpackArrayHeader()); // #1 assertEquals("komamitsu", messageUnpacker.unpackString()); diff --git a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackParserTest.java b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackParserTest.java index 3321110d4..065d398b3 100644 --- a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackParserTest.java +++ b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackParserTest.java @@ -54,7 +54,7 @@ public class MessagePackParserTest public void testParserShouldReadObject() throws IOException { - MessagePacker packer = new MessagePacker(new OutputStreamBufferOutput(out)); + MessagePacker packer = MessagePack.newDefaultPacker(out); packer.packMapHeader(9); // #1 packer.packString("str"); @@ -182,7 +182,7 @@ else if (k.equals("ext")) { public void testParserShouldReadArray() throws IOException { - MessagePacker packer = new MessagePacker(new OutputStreamBufferOutput(out)); + MessagePacker packer = MessagePack.newDefaultPacker(out); packer.packArrayHeader(11); // #1 packer.packArrayHeader(3); @@ -387,7 +387,7 @@ public void testBigDecimal() { double d0 = 1.23456789; double d1 = 1.23450000000000000000006789; - MessagePacker packer = new MessagePacker(new OutputStreamBufferOutput(out)); + MessagePacker packer = MessagePack.newDefaultPacker(out); packer.packArrayHeader(5); packer.packDouble(d0); packer.packDouble(d1); From 645abde9c1f76a184d78ae0e56ccd384da2c7456 Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Mon, 4 Jan 2016 15:36:27 +0900 Subject: [PATCH 211/234] Revert MessagePackFormatFactory -> MessagePackFactory --- ...atFactory.java => MessagePackFactory.java} | 2 +- .../ExampleOfTypeInformationSerDe.java | 2 +- .../MessagePackDataformatTestBase.java | 4 +-- ...yTest.java => MessagePackFactoryTest.java} | 2 +- .../dataformat/MessagePackGeneratorTest.java | 14 +++++----- .../dataformat/MessagePackParserTest.java | 27 +++++++++---------- ...gePackDataformatHugeDataBenchmarkTest.java | 6 ++--- ...essagePackDataformatPojoBenchmarkTest.java | 4 +-- 8 files changed, 30 insertions(+), 31 deletions(-) rename msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/{MessagePackFormatFactory.java => MessagePackFactory.java} (98%) rename msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/{MessagePackFormatFactoryTest.java => MessagePackFactoryTest.java} (97%) diff --git a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackFormatFactory.java b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackFactory.java similarity index 98% rename from msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackFormatFactory.java rename to msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackFactory.java index 1082e5770..ff7aa373f 100644 --- a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackFormatFactory.java +++ b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackFactory.java @@ -30,7 +30,7 @@ import java.io.Writer; import java.util.Arrays; -public class MessagePackFormatFactory +public class MessagePackFactory extends JsonFactory { private static final long serialVersionUID = 2578263992015504347L; diff --git a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/ExampleOfTypeInformationSerDe.java b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/ExampleOfTypeInformationSerDe.java index 6a211b3ae..5414b0bdc 100644 --- a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/ExampleOfTypeInformationSerDe.java +++ b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/ExampleOfTypeInformationSerDe.java @@ -151,7 +151,7 @@ public void test() objectContainer.getObjects().put("pi", pi); } - ObjectMapper objectMapper = new ObjectMapper(new MessagePackFormatFactory()); + ObjectMapper objectMapper = new ObjectMapper(new MessagePackFactory()); byte[] bytes = objectMapper.writeValueAsBytes(objectContainer); ObjectContainer restored = objectMapper.readValue(bytes, ObjectContainer.class); diff --git a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackDataformatTestBase.java b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackDataformatTestBase.java index c9692ebf9..1d5156adc 100644 --- a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackDataformatTestBase.java +++ b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackDataformatTestBase.java @@ -35,7 +35,7 @@ public class MessagePackDataformatTestBase { - protected MessagePackFormatFactory factory; + protected MessagePackFactory factory; protected ByteArrayOutputStream out; protected ByteArrayInputStream in; protected ObjectMapper objectMapper; @@ -47,7 +47,7 @@ public class MessagePackDataformatTestBase @Before public void setup() { - factory = new MessagePackFormatFactory(); + factory = new MessagePackFactory(); objectMapper = new ObjectMapper(factory); out = new ByteArrayOutputStream(); in = new ByteArrayInputStream(new byte[4096]); diff --git a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackFormatFactoryTest.java b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackFactoryTest.java similarity index 97% rename from msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackFormatFactoryTest.java rename to msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackFactoryTest.java index f7e5fe045..25180f784 100644 --- a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackFormatFactoryTest.java +++ b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackFactoryTest.java @@ -24,7 +24,7 @@ import static org.junit.Assert.assertEquals; -public class MessagePackFormatFactoryTest +public class MessagePackFactoryTest extends MessagePackDataformatTestBase { @Test diff --git a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackGeneratorTest.java b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackGeneratorTest.java index d7f8be600..fd2ea313f 100644 --- a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackGeneratorTest.java +++ b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackGeneratorTest.java @@ -236,7 +236,7 @@ else if (key.equals("num")) { public void testMessagePackGeneratorDirectly() throws Exception { - MessagePackFormatFactory messagePackFactory = new MessagePackFormatFactory(); + MessagePackFactory messagePackFactory = new MessagePackFactory(); File tempFile = createTempFile(); JsonGenerator generator = messagePackFactory.createGenerator(tempFile, JsonEncoding.UTF8); @@ -263,7 +263,7 @@ public void testMessagePackGeneratorDirectly() public void testWritePrimitives() throws Exception { - MessagePackFormatFactory messagePackFactory = new MessagePackFormatFactory(); + MessagePackFactory messagePackFactory = new MessagePackFactory(); File tempFile = createTempFile(); JsonGenerator generator = messagePackFactory.createGenerator(tempFile, JsonEncoding.UTF8); @@ -286,7 +286,7 @@ public void testWritePrimitives() public void testBigDecimal() throws IOException { - ObjectMapper mapper = new ObjectMapper(new MessagePackFormatFactory()); + ObjectMapper mapper = new ObjectMapper(new MessagePackFactory()); { double d0 = 1.23456789; @@ -334,7 +334,7 @@ public void testEnableFeatureAutoCloseTarget() throws IOException { OutputStream out = createTempFileOutputStream(); - MessagePackFormatFactory messagePackFactory = new MessagePackFormatFactory(); + MessagePackFactory messagePackFactory = new MessagePackFactory(); ObjectMapper objectMapper = new ObjectMapper(messagePackFactory); List integers = Arrays.asList(1); objectMapper.writeValue(out, integers); @@ -347,7 +347,7 @@ public void testDisableFeatureAutoCloseTarget() { File tempFile = createTempFile(); OutputStream out = new FileOutputStream(tempFile); - MessagePackFormatFactory messagePackFactory = new MessagePackFormatFactory(); + MessagePackFactory messagePackFactory = new MessagePackFactory(); ObjectMapper objectMapper = new ObjectMapper(messagePackFactory); objectMapper.configure(JsonGenerator.Feature.AUTO_CLOSE_TARGET, false); List integers = Arrays.asList(1); @@ -369,7 +369,7 @@ public void testWritePrimitiveObjectViaObjectMapper() File tempFile = createTempFile(); OutputStream out = new FileOutputStream(tempFile); - ObjectMapper objectMapper = new ObjectMapper(new MessagePackFormatFactory()); + ObjectMapper objectMapper = new ObjectMapper(new MessagePackFactory()); objectMapper.configure(JsonGenerator.Feature.AUTO_CLOSE_TARGET, false); objectMapper.writeValue(out, 1); objectMapper.writeValue(out, "two"); @@ -393,7 +393,7 @@ public void testInMultiThreads() int threadCount = 8; final int loopCount = 4000; ExecutorService executorService = Executors.newFixedThreadPool(threadCount); - final ObjectMapper objectMapper = new ObjectMapper(new MessagePackFormatFactory()); + final ObjectMapper objectMapper = new ObjectMapper(new MessagePackFactory()); objectMapper.configure(JsonGenerator.Feature.AUTO_CLOSE_TARGET, false); final List buffers = new ArrayList(threadCount); List> results = new ArrayList>(); diff --git a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackParserTest.java b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackParserTest.java index 065d398b3..112390598 100644 --- a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackParserTest.java +++ b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackParserTest.java @@ -27,7 +27,6 @@ import org.junit.Test; import org.msgpack.core.MessagePack; import org.msgpack.core.MessagePacker; -import org.msgpack.core.buffer.OutputStreamBufferOutput; import java.io.ByteArrayOutputStream; import java.io.File; @@ -288,7 +287,7 @@ else if (k.equals("child_map_age")) { public void testMessagePackParserDirectly() throws IOException { - MessagePackFormatFactory factory = new MessagePackFormatFactory(); + MessagePackFactory factory = new MessagePackFactory(); File tempFile = File.createTempFile("msgpackTest", "msgpack"); tempFile.deleteOnExit(); @@ -354,7 +353,7 @@ public void testMessagePackParserDirectly() public void testReadPrimitives() throws Exception { - MessagePackFormatFactory factory = new MessagePackFormatFactory(); + MessagePackFactory factory = new MessagePackFactory(); File tempFile = createTempFile(); FileOutputStream out = new FileOutputStream(tempFile); @@ -396,7 +395,7 @@ public void testBigDecimal() packer.packDouble(Double.MIN_NORMAL); packer.flush(); - ObjectMapper mapper = new ObjectMapper(new MessagePackFormatFactory()); + ObjectMapper mapper = new ObjectMapper(new MessagePackFactory()); mapper.configure(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS, true); List objects = mapper.readValue(out.toByteArray(), new TypeReference>() {}); assertEquals(5, objects.size()); @@ -431,7 +430,7 @@ public void testEnableFeatureAutoCloseSource() throws Exception { File tempFile = createTestFile(); - MessagePackFormatFactory factory = new MessagePackFormatFactory(); + MessagePackFactory factory = new MessagePackFactory(); FileInputStream in = new FileInputStream(tempFile); ObjectMapper objectMapper = new ObjectMapper(factory); objectMapper.readValue(in, new TypeReference>() {}); @@ -444,7 +443,7 @@ public void testDisableFeatureAutoCloseSource() { File tempFile = createTestFile(); FileInputStream in = new FileInputStream(tempFile); - ObjectMapper objectMapper = new ObjectMapper(new MessagePackFormatFactory()); + ObjectMapper objectMapper = new ObjectMapper(new MessagePackFactory()); objectMapper.configure(JsonParser.Feature.AUTO_CLOSE_SOURCE, false); objectMapper.readValue(in, new TypeReference>() {}); objectMapper.readValue(in, new TypeReference>() {}); @@ -456,7 +455,7 @@ public void testParseBigDecimal() { ArrayList list = new ArrayList(); list.add(new BigDecimal(Long.MAX_VALUE)); - ObjectMapper objectMapper = new ObjectMapper(new MessagePackFormatFactory()); + ObjectMapper objectMapper = new ObjectMapper(new MessagePackFactory()); byte[] bytes = objectMapper.writeValueAsBytes(list); ArrayList result = objectMapper.readValue( @@ -481,7 +480,7 @@ public void testReadPrimitiveObjectViaObjectMapper() packer.close(); FileInputStream in = new FileInputStream(tempFile); - ObjectMapper objectMapper = new ObjectMapper(new MessagePackFormatFactory()); + ObjectMapper objectMapper = new ObjectMapper(new MessagePackFactory()); objectMapper.configure(JsonParser.Feature.AUTO_CLOSE_SOURCE, false); assertEquals("foo", objectMapper.readValue(in, new TypeReference() {})); long l = objectMapper.readValue(in, new TypeReference() {}); @@ -511,7 +510,7 @@ public void testBinaryKey() packer.packLong(42); packer.close(); - ObjectMapper mapper = new ObjectMapper(new MessagePackFormatFactory()); + ObjectMapper mapper = new ObjectMapper(new MessagePackFactory()); Map object = mapper.readValue(new FileInputStream(tempFile), new TypeReference>() {}); assertEquals(2, object.size()); assertEquals(3.14, object.get("foo")); @@ -533,7 +532,7 @@ public void testBinaryKeyInNestedObject() packer.packInt(1); packer.close(); - ObjectMapper mapper = new ObjectMapper(new MessagePackFormatFactory()); + ObjectMapper mapper = new ObjectMapper(new MessagePackFactory()); List objects = mapper.readValue(out.toByteArray(), new TypeReference>() {}); assertEquals(2, objects.size()); @SuppressWarnings(value = "unchecked") @@ -555,7 +554,7 @@ public void testByteArrayKey() messagePacker.packBinaryHeader(1).writePayload(k1).packInt(3); messagePacker.close(); - ObjectMapper objectMapper = new ObjectMapper(new MessagePackFormatFactory()); + ObjectMapper objectMapper = new ObjectMapper(new MessagePackFactory()); SimpleModule module = new SimpleModule(); module.addKeyDeserializer(byte[].class, new KeyDeserializer() { @@ -592,7 +591,7 @@ public void testIntegerKey() } messagePacker.close(); - ObjectMapper objectMapper = new ObjectMapper(new MessagePackFormatFactory()); + ObjectMapper objectMapper = new ObjectMapper(new MessagePackFactory()); SimpleModule module = new SimpleModule(); module.addKeyDeserializer(Integer.class, new KeyDeserializer() { @@ -623,7 +622,7 @@ public void testFloatKey() } messagePacker.close(); - ObjectMapper objectMapper = new ObjectMapper(new MessagePackFormatFactory()); + ObjectMapper objectMapper = new ObjectMapper(new MessagePackFactory()); SimpleModule module = new SimpleModule(); module.addKeyDeserializer(Float.class, new KeyDeserializer() { @@ -653,7 +652,7 @@ public void testBooleanKey() messagePacker.packBoolean(false).packInt(3); messagePacker.close(); - ObjectMapper objectMapper = new ObjectMapper(new MessagePackFormatFactory()); + ObjectMapper objectMapper = new ObjectMapper(new MessagePackFactory()); SimpleModule module = new SimpleModule(); module.addKeyDeserializer(Boolean.class, new KeyDeserializer() { diff --git a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/benchmark/MessagePackDataformatHugeDataBenchmarkTest.java b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/benchmark/MessagePackDataformatHugeDataBenchmarkTest.java index aaf828439..b3a159111 100644 --- a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/benchmark/MessagePackDataformatHugeDataBenchmarkTest.java +++ b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/benchmark/MessagePackDataformatHugeDataBenchmarkTest.java @@ -20,7 +20,7 @@ import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.Test; -import org.msgpack.jackson.dataformat.MessagePackFormatFactory; +import org.msgpack.jackson.dataformat.MessagePackFactory; import java.io.File; import java.io.FileOutputStream; @@ -34,7 +34,7 @@ public class MessagePackDataformatHugeDataBenchmarkTest private static final int COUNT = 6; private static final int WARMUP_COUNT = 4; private final ObjectMapper origObjectMapper = new ObjectMapper(); - private final ObjectMapper msgpackObjectMapper = new ObjectMapper(new MessagePackFormatFactory()); + private final ObjectMapper msgpackObjectMapper = new ObjectMapper(new MessagePackFactory()); private static final List value; private static final byte[] packedByOriginal; private static final byte[] packedByMsgPack; @@ -61,7 +61,7 @@ public class MessagePackDataformatHugeDataBenchmarkTest packedByOriginal = bytes; try { - bytes = new ObjectMapper(new MessagePackFormatFactory()).writeValueAsBytes(value); + bytes = new ObjectMapper(new MessagePackFactory()).writeValueAsBytes(value); } catch (JsonProcessingException e) { e.printStackTrace(); diff --git a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/benchmark/MessagePackDataformatPojoBenchmarkTest.java b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/benchmark/MessagePackDataformatPojoBenchmarkTest.java index e6b627f5c..179b09891 100644 --- a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/benchmark/MessagePackDataformatPojoBenchmarkTest.java +++ b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/benchmark/MessagePackDataformatPojoBenchmarkTest.java @@ -19,7 +19,7 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.Test; -import org.msgpack.jackson.dataformat.MessagePackFormatFactory; +import org.msgpack.jackson.dataformat.MessagePackFactory; import static org.msgpack.jackson.dataformat.MessagePackDataformatTestBase.NormalPojo; import static org.msgpack.jackson.dataformat.MessagePackDataformatTestBase.Suit; @@ -41,7 +41,7 @@ public class MessagePackDataformatPojoBenchmarkTest private final List pojosSerWithOrig = new ArrayList(LOOP_MAX); private final List pojosSerWithMsgPack = new ArrayList(LOOP_MAX); private final ObjectMapper origObjectMapper = new ObjectMapper(); - private final ObjectMapper msgpackObjectMapper = new ObjectMapper(new MessagePackFormatFactory()); + private final ObjectMapper msgpackObjectMapper = new ObjectMapper(new MessagePackFactory()); public MessagePackDataformatPojoBenchmarkTest() { From 2cb2fcc3f63d4b83ace398dccb9e421a5ac4a570 Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Mon, 4 Jan 2016 15:42:47 +0900 Subject: [PATCH 212/234] Fix typo --- .../src/main/java/org/msgpack/core/MessagePacker.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessagePacker.java b/msgpack-core/src/main/java/org/msgpack/core/MessagePacker.java index c54943d2c..e3ba1e0d2 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/MessagePacker.java +++ b/msgpack-core/src/main/java/org/msgpack/core/MessagePacker.java @@ -174,15 +174,15 @@ private void flushBuffer() position = 0; } - private void ensureCapacity(int mimimumSize) + private void ensureCapacity(int minimumSize) throws IOException { if (buffer == null) { - buffer = out.next(mimimumSize); + buffer = out.next(minimumSize); } - else if (position + mimimumSize >= buffer.size()) { + else if (position + minimumSize >= buffer.size()) { flushBuffer(); - buffer = out.next(mimimumSize); + buffer = out.next(minimumSize); } } From 23b188226fbbbb633245aa8180b63636c8983ade Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Mon, 4 Jan 2016 15:44:38 +0900 Subject: [PATCH 213/234] Use static import --- .../test/java/org/msgpack/core/example/MessagePackExample.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/msgpack-core/src/test/java/org/msgpack/core/example/MessagePackExample.java b/msgpack-core/src/test/java/org/msgpack/core/example/MessagePackExample.java index cbaf44f9b..0b0e50123 100644 --- a/msgpack-core/src/test/java/org/msgpack/core/example/MessagePackExample.java +++ b/msgpack-core/src/test/java/org/msgpack/core/example/MessagePackExample.java @@ -18,6 +18,7 @@ import org.msgpack.core.MessageFormat; import org.msgpack.core.MessagePack; import org.msgpack.core.MessagePack.PackerConfig; +import org.msgpack.core.MessagePack.UnpackerConfig; import org.msgpack.core.MessagePacker; import org.msgpack.core.MessageUnpacker; import org.msgpack.value.ArrayValue; @@ -255,7 +256,7 @@ public static void configuration() packer.close(); // Unpack data - MessagePack.UnpackerConfig unpackerConfig = new MessagePack.UnpackerConfig(); + UnpackerConfig unpackerConfig = new UnpackerConfig(); unpackerConfig.stringDecoderBufferSize = 16 * 1024; // If your data contains many large strings (the default is 8k) byte[] packedData = out.toByteArray(); From 1fab3f7d6e613801915d5785aa5fbf078398d0af Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Mon, 4 Jan 2016 15:46:38 +0900 Subject: [PATCH 214/234] Remove comment --- .../src/main/java/org/msgpack/core/MessageUnpacker.java | 7 ------- 1 file changed, 7 deletions(-) diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java b/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java index 1602aa165..176e60863 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java +++ b/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java @@ -549,9 +549,6 @@ public Variable unpackValue(Variable var) int size = unpackArrayHeader(); List list = new ArrayList(size); for (int i = 0; i < size; i++) { - //Variable e = new Variable(); - //unpackValue(e); - //list.add(e); list.add(unpackValue()); } var.setArrayValue(list); @@ -561,10 +558,6 @@ public Variable unpackValue(Variable var) int size = unpackMapHeader(); Map map = new HashMap(); for (int i = 0; i < size; i++) { - //Variable k = new Variable(); - //unpackValue(k); - //Variable v = new Variable(); - //unpackValue(v); Value k = unpackValue(); Value v = unpackValue(); map.put(k, v); From d29276f7b6417af5d7a6a0a4837cb3cbed0c829d Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Mon, 4 Jan 2016 15:53:49 +0900 Subject: [PATCH 215/234] Revert the removed configuration comments and use more redable configuration names --- .../java/org/msgpack/core/MessagePack.java | 59 +++++++++++++++---- .../org/msgpack/core/MessageUnpacker.java | 14 ++--- 2 files changed, 54 insertions(+), 19 deletions(-) diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessagePack.java b/msgpack-core/src/main/java/org/msgpack/core/MessagePack.java index 02f94cde4..626447c31 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/MessagePack.java +++ b/msgpack-core/src/main/java/org/msgpack/core/MessagePack.java @@ -147,6 +147,10 @@ public static MessageUnpacker newDefaultUnpacker(byte[] contents, int offset, in */ public static class PackerConfig { + /** + * Use String.getBytes() for converting Java Strings that are smaller than this threshold into UTF8. + * Note that this parameter is subject to change. + */ public int smallStringOptimizationThreshold = 512; /** @@ -155,7 +159,8 @@ public static class PackerConfig * @param out * @return */ - public MessagePacker newPacker(MessageBufferOutput out) { + public MessagePacker newPacker(MessageBufferOutput out) + { return new MessagePacker(out, this); } @@ -165,7 +170,8 @@ public MessagePacker newPacker(MessageBufferOutput out) { * @param out * @return */ - public MessagePacker newPacker(OutputStream out) { + public MessagePacker newPacker(OutputStream out) + { return newPacker(new OutputStreamBufferOutput(out)); } @@ -175,7 +181,8 @@ public MessagePacker newPacker(OutputStream out) { * @param channel * @return */ - public MessagePacker newPacker(WritableByteChannel channel) { + public MessagePacker newPacker(WritableByteChannel channel) + { return newPacker(new ChannelBufferOutput(channel)); } @@ -184,7 +191,8 @@ public MessagePacker newPacker(WritableByteChannel channel) { * * @return */ - public MessageBufferPacker newBufferPacker() { + public MessageBufferPacker newBufferPacker() + { return new MessageBufferPacker(this); } } @@ -194,11 +202,34 @@ public MessageBufferPacker newBufferPacker() { */ public static class UnpackerConfig { - public boolean allowStringAsBinary = true; - public boolean allowBinaryAsString = true; + /** + * Allow unpackBinaryHeader to read str format family (default:true) + */ + public boolean allowReadingStringAsBinary = true; + + /** + * Allow unpackRawStringHeader and unpackString to read bin format family (default: true) + */ + public boolean allowReadingBinaryAsString = true; + + /** + * Action when encountered a malformed input + */ public CodingErrorAction actionOnMalformedString = CodingErrorAction.REPLACE; + + /** + * Action when an unmappable character is found + */ public CodingErrorAction actionOnUnmappableString = CodingErrorAction.REPLACE; + + /** + * unpackString size limit. (default: Integer.MAX_VALUE) + */ public int stringSizeLimit = Integer.MAX_VALUE; + + /** + * + */ public int stringDecoderBufferSize = 8192; /** @@ -207,7 +238,8 @@ public static class UnpackerConfig * @param in * @return */ - public MessageUnpacker newUnpacker(MessageBufferInput in) { + public MessageUnpacker newUnpacker(MessageBufferInput in) + { return new MessageUnpacker(in, this); } @@ -217,7 +249,8 @@ public MessageUnpacker newUnpacker(MessageBufferInput in) { * @param in * @return */ - public MessageUnpacker newUnpacker(InputStream in) { + public MessageUnpacker newUnpacker(InputStream in) + { return newUnpacker(new InputStreamBufferInput(in)); } @@ -227,7 +260,8 @@ public MessageUnpacker newUnpacker(InputStream in) { * @param channel * @return */ - public MessageUnpacker newUnpacker(ReadableByteChannel channel) { + public MessageUnpacker newUnpacker(ReadableByteChannel channel) + { return newUnpacker(new ChannelBufferInput(channel)); } @@ -237,7 +271,8 @@ public MessageUnpacker newUnpacker(ReadableByteChannel channel) { * @param contents * @return */ - public MessageUnpacker newUnpacker(byte[] contents) { + public MessageUnpacker newUnpacker(byte[] contents) + { return newUnpacker(new ArrayBufferInput(contents)); } @@ -247,9 +282,9 @@ public MessageUnpacker newUnpacker(byte[] contents) { * @param contents * @return */ - public MessageUnpacker newUnpacker(byte[] contents, int offset, int length) { + public MessageUnpacker newUnpacker(byte[] contents, int offset, int length) + { return newUnpacker(new ArrayBufferInput(contents, offset, length)); } - } } diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java b/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java index 176e60863..c4a8fc35b 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java +++ b/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java @@ -73,8 +73,8 @@ public class MessageUnpacker private static final byte HEAD_BYTE_REQUIRED = (byte) 0xc1; - private final boolean allowStringAsBinary; - private final boolean allowBinaryAsString; + private final boolean allowReadingStringAsBinary; + private final boolean allowReadingBinaryAsString; private final CodingErrorAction actionOnMalformedString; private final CodingErrorAction actionOnUnmappableString; private final int stringSizeLimit; @@ -134,10 +134,10 @@ public MessageUnpacker(MessageBufferInput in, MessagePack.UnpackerConfig config) { this.in = checkNotNull(in, "MessageBufferInput is null"); // We need to copy the configuration parameters since the config object is mutable - this.allowStringAsBinary = config.allowStringAsBinary; - this.allowBinaryAsString = config.allowBinaryAsString; + this.allowReadingStringAsBinary = config.allowReadingStringAsBinary; + this.allowReadingBinaryAsString = config.allowReadingBinaryAsString; this.actionOnMalformedString = config.actionOnMalformedString; - this.actionOnUnmappableString = config.actionOnUnmappableString; + this.actionOnUnmappableString = config.actionOnUnmappableString; this.stringSizeLimit = config.stringSizeLimit; this.stringDecoderBufferSize = config.stringDecoderBufferSize; } @@ -1149,7 +1149,7 @@ public int unpackRawStringHeader() return len; } - if (allowBinaryAsString) { + if (allowReadingBinaryAsString) { len = tryReadBinaryHeader(b); if (len >= 0) { return len; @@ -1170,7 +1170,7 @@ public int unpackBinaryHeader() return len; } - if (allowStringAsBinary) { + if (allowReadingStringAsBinary) { len = tryReadStringHeader(b); if (len >= 0) { return len; From f7d57e3f98fe3dccb0ff5f886545cd279c8aa755 Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Mon, 4 Jan 2016 16:10:08 +0900 Subject: [PATCH 216/234] Relocate Code class inside MessagePack again since it is used for Packer/Unpacker, which do not need to depend on MessageFormat enum --- .../java/org/msgpack/core/MessageFormat.java | 89 +------------------ .../java/org/msgpack/core/MessagePack.java | 89 +++++++++++++++++++ .../java/org/msgpack/core/MessagePacker.java | 68 +++++++------- .../org/msgpack/core/MessageUnpacker.java | 2 +- .../org/msgpack/core/MessageFormatTest.scala | 2 +- .../org/msgpack/core/MessagePackTest.scala | 2 +- .../org/msgpack/value/ValueTypeTest.scala | 12 +-- 7 files changed, 134 insertions(+), 130 deletions(-) diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessageFormat.java b/msgpack-core/src/main/java/org/msgpack/core/MessageFormat.java index 5a20518dc..d57c446f2 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/MessageFormat.java +++ b/msgpack-core/src/main/java/org/msgpack/core/MessageFormat.java @@ -17,6 +17,7 @@ import org.msgpack.core.annotations.VisibleForTesting; import org.msgpack.value.ValueType; +import org.msgpack.core.MessagePack.Code; /** * Describes the list of the message format types defined in the MessagePack specification. @@ -65,94 +66,6 @@ public enum MessageFormat MAP32(ValueType.MAP), NEGFIXINT(ValueType.INTEGER); - /** - * The prefix code set of MessagePack. See also https://github.com/msgpack/msgpack/blob/master/spec.md for details. - */ - public static final class Code - { - public static final boolean isFixInt(byte b) - { - int v = b & 0xFF; - return v <= 0x7f || v >= 0xe0; - } - - public static final boolean isPosFixInt(byte b) - { - return (b & POSFIXINT_MASK) == 0; - } - - public static final boolean isNegFixInt(byte b) - { - return (b & NEGFIXINT_PREFIX) == NEGFIXINT_PREFIX; - } - - public static final boolean isFixStr(byte b) - { - return (b & (byte) 0xe0) == Code.FIXSTR_PREFIX; - } - - public static final boolean isFixedArray(byte b) - { - return (b & (byte) 0xf0) == Code.FIXARRAY_PREFIX; - } - - public static final boolean isFixedMap(byte b) - { - return (b & (byte) 0xf0) == Code.FIXMAP_PREFIX; - } - - public static final boolean isFixedRaw(byte b) - { - return (b & (byte) 0xe0) == Code.FIXSTR_PREFIX; - } - - public static final byte POSFIXINT_MASK = (byte) 0x80; - - public static final byte FIXMAP_PREFIX = (byte) 0x80; - public static final byte FIXARRAY_PREFIX = (byte) 0x90; - public static final byte FIXSTR_PREFIX = (byte) 0xa0; - - public static final byte NIL = (byte) 0xc0; - public static final byte NEVER_USED = (byte) 0xc1; - public static final byte FALSE = (byte) 0xc2; - public static final byte TRUE = (byte) 0xc3; - public static final byte BIN8 = (byte) 0xc4; - public static final byte BIN16 = (byte) 0xc5; - public static final byte BIN32 = (byte) 0xc6; - public static final byte EXT8 = (byte) 0xc7; - public static final byte EXT16 = (byte) 0xc8; - public static final byte EXT32 = (byte) 0xc9; - public static final byte FLOAT32 = (byte) 0xca; - public static final byte FLOAT64 = (byte) 0xcb; - public static final byte UINT8 = (byte) 0xcc; - public static final byte UINT16 = (byte) 0xcd; - public static final byte UINT32 = (byte) 0xce; - public static final byte UINT64 = (byte) 0xcf; - - public static final byte INT8 = (byte) 0xd0; - public static final byte INT16 = (byte) 0xd1; - public static final byte INT32 = (byte) 0xd2; - public static final byte INT64 = (byte) 0xd3; - - public static final byte FIXEXT1 = (byte) 0xd4; - public static final byte FIXEXT2 = (byte) 0xd5; - public static final byte FIXEXT4 = (byte) 0xd6; - public static final byte FIXEXT8 = (byte) 0xd7; - public static final byte FIXEXT16 = (byte) 0xd8; - - public static final byte STR8 = (byte) 0xd9; - public static final byte STR16 = (byte) 0xda; - public static final byte STR32 = (byte) 0xdb; - - public static final byte ARRAY16 = (byte) 0xdc; - public static final byte ARRAY32 = (byte) 0xdd; - - public static final byte MAP16 = (byte) 0xde; - public static final byte MAP32 = (byte) 0xdf; - - public static final byte NEGFIXINT_PREFIX = (byte) 0xe0; - } - private static final MessageFormat[] formatTable = new MessageFormat[256]; private final ValueType valueType; diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessagePack.java b/msgpack-core/src/main/java/org/msgpack/core/MessagePack.java index 626447c31..bcc9d9359 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/MessagePack.java +++ b/msgpack-core/src/main/java/org/msgpack/core/MessagePack.java @@ -37,6 +37,95 @@ public class MessagePack { public static final Charset UTF8 = Charset.forName("UTF-8"); + /** + * The prefix code set of MessagePack. See also https://github.com/msgpack/msgpack/blob/master/spec.md for details. + */ + public static final class Code + { + public static final boolean isFixInt(byte b) + { + int v = b & 0xFF; + return v <= 0x7f || v >= 0xe0; + } + + public static final boolean isPosFixInt(byte b) + { + return (b & POSFIXINT_MASK) == 0; + } + + public static final boolean isNegFixInt(byte b) + { + return (b & NEGFIXINT_PREFIX) == NEGFIXINT_PREFIX; + } + + public static final boolean isFixStr(byte b) + { + return (b & (byte) 0xe0) == Code.FIXSTR_PREFIX; + } + + public static final boolean isFixedArray(byte b) + { + return (b & (byte) 0xf0) == Code.FIXARRAY_PREFIX; + } + + public static final boolean isFixedMap(byte b) + { + return (b & (byte) 0xf0) == Code.FIXMAP_PREFIX; + } + + public static final boolean isFixedRaw(byte b) + { + return (b & (byte) 0xe0) == Code.FIXSTR_PREFIX; + } + + public static final byte POSFIXINT_MASK = (byte) 0x80; + + public static final byte FIXMAP_PREFIX = (byte) 0x80; + public static final byte FIXARRAY_PREFIX = (byte) 0x90; + public static final byte FIXSTR_PREFIX = (byte) 0xa0; + + public static final byte NIL = (byte) 0xc0; + public static final byte NEVER_USED = (byte) 0xc1; + public static final byte FALSE = (byte) 0xc2; + public static final byte TRUE = (byte) 0xc3; + public static final byte BIN8 = (byte) 0xc4; + public static final byte BIN16 = (byte) 0xc5; + public static final byte BIN32 = (byte) 0xc6; + public static final byte EXT8 = (byte) 0xc7; + public static final byte EXT16 = (byte) 0xc8; + public static final byte EXT32 = (byte) 0xc9; + public static final byte FLOAT32 = (byte) 0xca; + public static final byte FLOAT64 = (byte) 0xcb; + public static final byte UINT8 = (byte) 0xcc; + public static final byte UINT16 = (byte) 0xcd; + public static final byte UINT32 = (byte) 0xce; + public static final byte UINT64 = (byte) 0xcf; + + public static final byte INT8 = (byte) 0xd0; + public static final byte INT16 = (byte) 0xd1; + public static final byte INT32 = (byte) 0xd2; + public static final byte INT64 = (byte) 0xd3; + + public static final byte FIXEXT1 = (byte) 0xd4; + public static final byte FIXEXT2 = (byte) 0xd5; + public static final byte FIXEXT4 = (byte) 0xd6; + public static final byte FIXEXT8 = (byte) 0xd7; + public static final byte FIXEXT16 = (byte) 0xd8; + + public static final byte STR8 = (byte) 0xd9; + public static final byte STR16 = (byte) 0xda; + public static final byte STR32 = (byte) 0xdb; + + public static final byte ARRAY16 = (byte) 0xdc; + public static final byte ARRAY32 = (byte) 0xdd; + + public static final byte MAP16 = (byte) 0xde; + public static final byte MAP32 = (byte) 0xdf; + + public static final byte NEGFIXINT_PREFIX = (byte) 0xe0; + } + + private MessagePack() { // Prohibit instantiation of this class diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessagePacker.java b/msgpack-core/src/main/java/org/msgpack/core/MessagePacker.java index e3ba1e0d2..c06cc5804 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/MessagePacker.java +++ b/msgpack-core/src/main/java/org/msgpack/core/MessagePacker.java @@ -28,40 +28,40 @@ import java.nio.charset.CharsetEncoder; import java.nio.charset.CoderResult; -import static org.msgpack.core.MessageFormat.Code.ARRAY16; -import static org.msgpack.core.MessageFormat.Code.ARRAY32; -import static org.msgpack.core.MessageFormat.Code.BIN16; -import static org.msgpack.core.MessageFormat.Code.BIN32; -import static org.msgpack.core.MessageFormat.Code.BIN8; -import static org.msgpack.core.MessageFormat.Code.EXT16; -import static org.msgpack.core.MessageFormat.Code.EXT32; -import static org.msgpack.core.MessageFormat.Code.EXT8; -import static org.msgpack.core.MessageFormat.Code.FALSE; -import static org.msgpack.core.MessageFormat.Code.FIXARRAY_PREFIX; -import static org.msgpack.core.MessageFormat.Code.FIXEXT1; -import static org.msgpack.core.MessageFormat.Code.FIXEXT16; -import static org.msgpack.core.MessageFormat.Code.FIXEXT2; -import static org.msgpack.core.MessageFormat.Code.FIXEXT4; -import static org.msgpack.core.MessageFormat.Code.FIXEXT8; -import static org.msgpack.core.MessageFormat.Code.FIXMAP_PREFIX; -import static org.msgpack.core.MessageFormat.Code.FIXSTR_PREFIX; -import static org.msgpack.core.MessageFormat.Code.FLOAT32; -import static org.msgpack.core.MessageFormat.Code.FLOAT64; -import static org.msgpack.core.MessageFormat.Code.INT16; -import static org.msgpack.core.MessageFormat.Code.INT32; -import static org.msgpack.core.MessageFormat.Code.INT64; -import static org.msgpack.core.MessageFormat.Code.INT8; -import static org.msgpack.core.MessageFormat.Code.MAP16; -import static org.msgpack.core.MessageFormat.Code.MAP32; -import static org.msgpack.core.MessageFormat.Code.NIL; -import static org.msgpack.core.MessageFormat.Code.STR16; -import static org.msgpack.core.MessageFormat.Code.STR32; -import static org.msgpack.core.MessageFormat.Code.STR8; -import static org.msgpack.core.MessageFormat.Code.TRUE; -import static org.msgpack.core.MessageFormat.Code.UINT16; -import static org.msgpack.core.MessageFormat.Code.UINT32; -import static org.msgpack.core.MessageFormat.Code.UINT64; -import static org.msgpack.core.MessageFormat.Code.UINT8; +import static org.msgpack.core.MessagePack.Code.ARRAY16; +import static org.msgpack.core.MessagePack.Code.ARRAY32; +import static org.msgpack.core.MessagePack.Code.BIN16; +import static org.msgpack.core.MessagePack.Code.BIN32; +import static org.msgpack.core.MessagePack.Code.BIN8; +import static org.msgpack.core.MessagePack.Code.EXT16; +import static org.msgpack.core.MessagePack.Code.EXT32; +import static org.msgpack.core.MessagePack.Code.EXT8; +import static org.msgpack.core.MessagePack.Code.FALSE; +import static org.msgpack.core.MessagePack.Code.FIXARRAY_PREFIX; +import static org.msgpack.core.MessagePack.Code.FIXEXT1; +import static org.msgpack.core.MessagePack.Code.FIXEXT16; +import static org.msgpack.core.MessagePack.Code.FIXEXT2; +import static org.msgpack.core.MessagePack.Code.FIXEXT4; +import static org.msgpack.core.MessagePack.Code.FIXEXT8; +import static org.msgpack.core.MessagePack.Code.FIXMAP_PREFIX; +import static org.msgpack.core.MessagePack.Code.FIXSTR_PREFIX; +import static org.msgpack.core.MessagePack.Code.FLOAT32; +import static org.msgpack.core.MessagePack.Code.FLOAT64; +import static org.msgpack.core.MessagePack.Code.INT16; +import static org.msgpack.core.MessagePack.Code.INT32; +import static org.msgpack.core.MessagePack.Code.INT64; +import static org.msgpack.core.MessagePack.Code.INT8; +import static org.msgpack.core.MessagePack.Code.MAP16; +import static org.msgpack.core.MessagePack.Code.MAP32; +import static org.msgpack.core.MessagePack.Code.NIL; +import static org.msgpack.core.MessagePack.Code.STR16; +import static org.msgpack.core.MessagePack.Code.STR32; +import static org.msgpack.core.MessagePack.Code.STR8; +import static org.msgpack.core.MessagePack.Code.TRUE; +import static org.msgpack.core.MessagePack.Code.UINT16; +import static org.msgpack.core.MessagePack.Code.UINT32; +import static org.msgpack.core.MessagePack.Code.UINT64; +import static org.msgpack.core.MessagePack.Code.UINT8; import static org.msgpack.core.Preconditions.checkNotNull; /** diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java b/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java index c4a8fc35b..d642fad6e 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java +++ b/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java @@ -15,7 +15,7 @@ // package org.msgpack.core; -import org.msgpack.core.MessageFormat.Code; +import org.msgpack.core.MessagePack.Code; import org.msgpack.core.buffer.MessageBuffer; import org.msgpack.core.buffer.MessageBufferInput; import org.msgpack.value.ImmutableValue; diff --git a/msgpack-core/src/test/scala/org/msgpack/core/MessageFormatTest.scala b/msgpack-core/src/test/scala/org/msgpack/core/MessageFormatTest.scala index a6a71e2d9..be9d270cd 100644 --- a/msgpack-core/src/test/scala/org/msgpack/core/MessageFormatTest.scala +++ b/msgpack-core/src/test/scala/org/msgpack/core/MessageFormatTest.scala @@ -15,7 +15,7 @@ // package org.msgpack.core -import org.msgpack.core.MessageFormat.Code +import org.msgpack.core.MessagePack.Code import org.msgpack.value.ValueType import org.scalatest.exceptions.TestFailedException diff --git a/msgpack-core/src/test/scala/org/msgpack/core/MessagePackTest.scala b/msgpack-core/src/test/scala/org/msgpack/core/MessagePackTest.scala index d11383e7f..112c3e5a7 100644 --- a/msgpack-core/src/test/scala/org/msgpack/core/MessagePackTest.scala +++ b/msgpack-core/src/test/scala/org/msgpack/core/MessagePackTest.scala @@ -20,7 +20,7 @@ import java.math.BigInteger import java.nio.CharBuffer import java.nio.charset.{CodingErrorAction, UnmappableCharacterException} -import org.msgpack.core.MessageFormat.Code +import org.msgpack.core.MessagePack.Code import org.msgpack.core.MessagePack.{UnpackerConfig, PackerConfig} import org.msgpack.value.{Value, Variable} diff --git a/msgpack-core/src/test/scala/org/msgpack/value/ValueTypeTest.scala b/msgpack-core/src/test/scala/org/msgpack/value/ValueTypeTest.scala index 2bd1c7b14..979c33c9b 100644 --- a/msgpack-core/src/test/scala/org/msgpack/value/ValueTypeTest.scala +++ b/msgpack-core/src/test/scala/org/msgpack/value/ValueTypeTest.scala @@ -15,20 +15,22 @@ // package org.msgpack.value -import org.msgpack.core.MessageFormat.Code._ +import org.msgpack.core.MessagePack.Code._ import org.msgpack.core.{MessageFormat, MessageFormatException, MessagePackSpec} /** - * Created on 2014/05/06. - */ + * Created on 2014/05/06. + */ class ValueTypeTest - extends MessagePackSpec { + extends MessagePackSpec +{ "ValueType" should { "lookup ValueType from a byte value" taggedAs ("code") in { - def check(b: Byte, tpe: ValueType) { + def check(b: Byte, tpe: ValueType) + { MessageFormat.valueOf(b).getValueType shouldBe tpe } From 031ead346902e6c69b3a8a95a0805395771e52f3 Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Mon, 4 Jan 2016 16:23:20 +0900 Subject: [PATCH 217/234] Rename to PackStringWithGetBytes and add comments --- .../src/main/java/org/msgpack/core/MessagePacker.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessagePacker.java b/msgpack-core/src/main/java/org/msgpack/core/MessagePacker.java index c06cc5804..cb8ccd371 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/MessagePacker.java +++ b/msgpack-core/src/main/java/org/msgpack/core/MessagePacker.java @@ -428,10 +428,12 @@ public MessagePacker packDouble(double v) return this; } - private void packStringByGetBytes(String s) + private void packStringWithGetBytes(String s) throws IOException { + // JVM performs various optimizations (memory allocation, reusing encoder etc.) when String.getBytes is used byte[] bytes = s.getBytes(MessagePack.UTF8); + // Write the length and payload of small string to the buffer so that it avoids an extra flush of buffer packRawStringHeader(bytes.length); addPayload(bytes); } @@ -481,8 +483,8 @@ public MessagePacker packString(String s) return this; } else if (s.length() < smallStringOptimizationThreshold) { - // Write the length and payload of small string to the buffer so that it avoids an extra flush of buffer - packStringByGetBytes(s); + // Using String.getBytes is generally faster for small strings + packStringWithGetBytes(s); return this; } else if (s.length() < (1 << 8)) { @@ -549,7 +551,7 @@ else if (s.length() < (1 << 16)) { // 384KB, which is OK size to keep in memory. // fallback - packStringByGetBytes(s); + packStringWithGetBytes(s); return this; } From 4230539a63e305368004b0bba78062c18c4c011d Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Mon, 4 Jan 2016 17:15:28 +0900 Subject: [PATCH 218/234] Rename castBuffer to numberBuffer to clarify the usage of this buffer --- .../org/msgpack/core/MessageBufferPacker.java | 5 +- .../java/org/msgpack/core/MessagePack.java | 1 - .../org/msgpack/core/MessageUnpacker.java | 108 ++++++++++-------- 3 files changed, 66 insertions(+), 48 deletions(-) diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessageBufferPacker.java b/msgpack-core/src/main/java/org/msgpack/core/MessageBufferPacker.java index 829803a2d..640b35f9d 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/MessageBufferPacker.java +++ b/msgpack-core/src/main/java/org/msgpack/core/MessageBufferPacker.java @@ -15,9 +15,9 @@ // package org.msgpack.core; +import org.msgpack.core.buffer.ArrayBufferOutput; import org.msgpack.core.buffer.MessageBuffer; import org.msgpack.core.buffer.MessageBufferOutput; -import org.msgpack.core.buffer.ArrayBufferOutput; import java.io.IOException; import java.util.List; @@ -47,7 +47,8 @@ public MessageBufferOutput reset(MessageBufferOutput out) return super.reset(out); } - private ArrayBufferOutput getArrayBufferOut() { + private ArrayBufferOutput getArrayBufferOut() + { return (ArrayBufferOutput) out; } diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessagePack.java b/msgpack-core/src/main/java/org/msgpack/core/MessagePack.java index bcc9d9359..7643f18f4 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/MessagePack.java +++ b/msgpack-core/src/main/java/org/msgpack/core/MessagePack.java @@ -125,7 +125,6 @@ public static final boolean isFixedRaw(byte b) public static final byte NEGFIXINT_PREFIX = (byte) 0xe0; } - private MessagePack() { // Prohibit instantiation of this class diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java b/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java index d642fad6e..c5dc4db2b 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java +++ b/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java @@ -100,15 +100,15 @@ public class MessageUnpacker private long totalReadBytes; /** - * Extra buffer for fixed-length data at the buffer boundary. + * An extra buffer for reading a small number value across the input buffer boundary. * At most 8-byte buffer (for readLong used by uint 64 and UTF-8 character decoding) is required. */ - private final MessageBuffer castBuffer = MessageBuffer.allocate(8); + private final MessageBuffer numberBuffer = MessageBuffer.allocate(8); /** - * Variable by ensureHeader method. Caller of the method should use this variable to read from returned MessageBuffer. + * After calling prepareNumberBuffer(), the caller should use this variable to read from the returned MessageBuffer. */ - private int readCastBufferPosition; + private int nextReadPosition; /** * For decoding String in unpackString. @@ -169,7 +169,12 @@ public long getTotalReadBytes() return totalReadBytes + position; } - private void nextBuffer() + /** + * Get the next buffer without changing the position + * @return + * @throws IOException + */ + private MessageBuffer getNextBuffer() throws IOException { MessageBuffer next = in.next(); @@ -177,44 +182,57 @@ private void nextBuffer() throw new MessageInsufficientBufferException(); } totalReadBytes += buffer.size(); - buffer = next; + return next; + } + + private void nextBuffer() + throws IOException + { + buffer = getNextBuffer(); position = 0; } - private MessageBuffer readCastBuffer(int length) + /** + * Returns a short size buffer (upto 8 bytes) to read a number value + * @param readLength + * @return + * @throws IOException + * @throws MessageInsufficientBufferException If no more buffer can be acquired from the input source for reading the specified data length + */ + private MessageBuffer prepareNumberBuffer(int readLength) throws IOException { int remaining = buffer.size() - position; - if (remaining >= length) { - readCastBufferPosition = position; - position += length; // here assumes following buffer.getXxx never throws exception - return buffer; + if (remaining >= readLength) { + // When the data is contained inside the default buffer + nextReadPosition = position; + position += readLength; // here assumes following buffer.getXxx never throws exception + return buffer; // Return the default buffer } else { - // TODO loop this method until castBuffer is filled - MessageBuffer next = in.next(); - if (next == null) { - throw new MessageInsufficientBufferException(); - } + // When the default buffer doesn't contain the whole length - totalReadBytes += buffer.size(); + // TODO loop this method until castBuffer is filled + MessageBuffer next = getNextBuffer(); if (remaining > 0) { - // TODO this doesn't work if MessageBuffer is allocated by newDirectBuffer. - // add copy method to MessageBuffer to solve this issue. - castBuffer.putBytes(0, buffer.array(), buffer.arrayOffset() + position, remaining); - castBuffer.putBytes(remaining, next.array(), next.arrayOffset(), length - remaining); + // TODO This doesn't work if MessageBuffer is allocated by newDirectBuffer. + // Add copy method to MessageBuffer to solve this issue. + + // Copy the data fragment from the current buffer + numberBuffer.putBytes(0, buffer.array(), buffer.arrayOffset() + position, remaining); + numberBuffer.putBytes(remaining, next.array(), next.arrayOffset(), readLength - remaining); buffer = next; - position = length - remaining; - readCastBufferPosition = 0; + position = readLength - remaining; + nextReadPosition = 0; - return castBuffer; + return numberBuffer; // Return the numberBuffer } else { buffer = next; - position = length; - readCastBufferPosition = 0; + position = readLength; + nextReadPosition = 0; return buffer; } } @@ -296,36 +314,36 @@ private byte readByte() private short readShort() throws IOException { - MessageBuffer castBuffer = readCastBuffer(2); - return castBuffer.getShort(readCastBufferPosition); + MessageBuffer numberBuffer = prepareNumberBuffer(2); + return numberBuffer.getShort(nextReadPosition); } private int readInt() throws IOException { - MessageBuffer castBuffer = readCastBuffer(4); - return castBuffer.getInt(readCastBufferPosition); + MessageBuffer numberBuffer = prepareNumberBuffer(4); + return numberBuffer.getInt(nextReadPosition); } private long readLong() throws IOException { - MessageBuffer castBuffer = readCastBuffer(8); - return castBuffer.getLong(readCastBufferPosition); + MessageBuffer numberBuffer = prepareNumberBuffer(8); + return numberBuffer.getLong(nextReadPosition); } private float readFloat() throws IOException { - MessageBuffer castBuffer = readCastBuffer(4); - return castBuffer.getFloat(readCastBufferPosition); + MessageBuffer numberBuffer = prepareNumberBuffer(4); + return numberBuffer.getFloat(nextReadPosition); } private double readDouble() throws IOException { - MessageBuffer castBuffer = readCastBuffer(8); - return castBuffer.getDouble(readCastBufferPosition); + MessageBuffer numberBuffer = prepareNumberBuffer(8); + return numberBuffer.getDouble(nextReadPosition); } /** @@ -1079,27 +1097,27 @@ public ExtensionTypeHeader unpackExtensionTypeHeader() return new ExtensionTypeHeader(type, 16); } case Code.EXT8: { - MessageBuffer castBuffer = readCastBuffer(2); - int u8 = castBuffer.getByte(readCastBufferPosition); + MessageBuffer numberBuffer = prepareNumberBuffer(2); + int u8 = numberBuffer.getByte(nextReadPosition); int length = u8 & 0xff; - byte type = castBuffer.getByte(readCastBufferPosition + 1); + byte type = numberBuffer.getByte(nextReadPosition + 1); return new ExtensionTypeHeader(type, length); } case Code.EXT16: { - MessageBuffer castBuffer = readCastBuffer(3); - int u16 = castBuffer.getShort(readCastBufferPosition); + MessageBuffer numberBuffer = prepareNumberBuffer(3); + int u16 = numberBuffer.getShort(nextReadPosition); int length = u16 & 0xffff; - byte type = castBuffer.getByte(readCastBufferPosition + 2); + byte type = numberBuffer.getByte(nextReadPosition + 2); return new ExtensionTypeHeader(type, length); } case Code.EXT32: { - MessageBuffer castBuffer = readCastBuffer(5); - int u32 = castBuffer.getInt(readCastBufferPosition); + MessageBuffer numberBuffer = prepareNumberBuffer(5); + int u32 = numberBuffer.getInt(nextReadPosition); if (u32 < 0) { throw overflowU32Size(u32); } int length = u32; - byte type = castBuffer.getByte(readCastBufferPosition + 4); + byte type = numberBuffer.getByte(nextReadPosition + 4); return new ExtensionTypeHeader(type, length); } } From 3d328e9f25c782931126e5ea5c846739855c6c97 Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Mon, 4 Jan 2016 23:09:56 +0900 Subject: [PATCH 219/234] Add assertion --- .../src/main/java/org/msgpack/core/MessageUnpacker.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java b/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java index c5dc4db2b..219c11d26 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java +++ b/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java @@ -171,6 +171,7 @@ public long getTotalReadBytes() /** * Get the next buffer without changing the position + * * @return * @throws IOException */ @@ -181,6 +182,7 @@ private MessageBuffer getNextBuffer() if (next == null) { throw new MessageInsufficientBufferException(); } + assert (buffer != null); totalReadBytes += buffer.size(); return next; } @@ -194,6 +196,7 @@ private void nextBuffer() /** * Returns a short size buffer (upto 8 bytes) to read a number value + * * @param readLength * @return * @throws IOException From 66ce882fb7ec990acf4574d5db9c895e4344a054 Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Mon, 4 Jan 2016 23:13:44 +0900 Subject: [PATCH 220/234] Remove unused variable --- .../src/main/java/org/msgpack/core/MessageUnpacker.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java b/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java index 219c11d26..52fdc5fed 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java +++ b/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java @@ -71,8 +71,6 @@ public class MessageUnpacker { private static final MessageBuffer EMPTY_BUFFER = MessageBuffer.wrap(new byte[0]); - private static final byte HEAD_BYTE_REQUIRED = (byte) 0xc1; - private final boolean allowReadingStringAsBinary; private final boolean allowReadingBinaryAsString; private final CodingErrorAction actionOnMalformedString; @@ -82,8 +80,6 @@ public class MessageUnpacker private MessageBufferInput in; - private byte headByte = HEAD_BYTE_REQUIRED; - /** * Points to the current buffer to read */ From 72ceb0c92dafad20ff3b6fd774945ba58d2a80a1 Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Mon, 4 Jan 2016 23:14:36 +0900 Subject: [PATCH 221/234] Fix comment --- .../src/main/java/org/msgpack/core/MessagePacker.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessagePacker.java b/msgpack-core/src/main/java/org/msgpack/core/MessagePacker.java index cb8ccd371..fe0363e99 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/MessagePacker.java +++ b/msgpack-core/src/main/java/org/msgpack/core/MessagePacker.java @@ -506,7 +506,7 @@ else if (s.length() < (1 << 8)) { // move 1 byte backward to expand 3-byte header region to 3 bytes buffer.putBytes(position + 3, buffer.array(), buffer.arrayOffset() + position + 2, written); - // write 3-byte header header + // write 3-byte header buffer.putByte(position++, STR16); buffer.putShort(position, (short) written); position += 2; @@ -516,7 +516,7 @@ else if (s.length() < (1 << 8)) { } } else if (s.length() < (1 << 16)) { - // ensure capacity for 3-byte raw string header + the maximum string size (+ 2 bytes for falback code) + // ensure capacity for 3-byte raw string header + the maximum string size (+ 2 bytes for fallback code) ensureCapacity(3 + s.length() * UTF_8_MAX_CHAR_SIZE + 2); // keep 3-byte header region and write raw string int written = encodeStringToBufferAt(position + 3, s); From 10c241b0d522f143b0145fa69f5e74053191efbc Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Mon, 4 Jan 2016 23:27:54 +0900 Subject: [PATCH 222/234] Use a config param for 8192 --- .../src/main/java/org/msgpack/core/MessagePack.java | 6 ++++++ .../src/main/java/org/msgpack/core/MessagePacker.java | 7 +++++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessagePack.java b/msgpack-core/src/main/java/org/msgpack/core/MessagePack.java index 7643f18f4..59bbbad48 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/MessagePack.java +++ b/msgpack-core/src/main/java/org/msgpack/core/MessagePack.java @@ -241,6 +241,12 @@ public static class PackerConfig */ public int smallStringOptimizationThreshold = 512; + /** + * When the next payload size exceeds this threshold, MessagePacker will call MessageBufferOutput.flush() before + * packing the data. + */ + public int bufferFlushThreshold = 8192; + /** * Create a packer that outputs the packed data to a given output * diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessagePacker.java b/msgpack-core/src/main/java/org/msgpack/core/MessagePacker.java index fe0363e99..c99653fc9 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/MessagePacker.java +++ b/msgpack-core/src/main/java/org/msgpack/core/MessagePacker.java @@ -86,6 +86,8 @@ public class MessagePacker { private final int smallStringOptimizationThreshold; + private final int bufferFlushThreshold; + protected MessageBufferOutput out; private MessageBuffer buffer; @@ -113,6 +115,7 @@ public MessagePacker(MessageBufferOutput out, MessagePack.PackerConfig config) this.out = checkNotNull(out, "MessageBufferOutput is null"); // We must copy the configuration parameters here since the config object is mutable this.smallStringOptimizationThreshold = config.smallStringOptimizationThreshold; + this.bufferFlushThreshold = config.bufferFlushThreshold; this.position = 0; this.totalFlushBytes = 0; } @@ -703,7 +706,7 @@ public MessagePacker writePayload(byte[] src) public MessagePacker writePayload(byte[] src, int off, int len) throws IOException { - if (buffer.size() - position < len || len > 8192) { + if (buffer.size() - position < len || len > bufferFlushThreshold) { flush(); // call flush before write out.write(src, off, len); totalFlushBytes += len; @@ -744,7 +747,7 @@ public MessagePacker addPayload(byte[] src) public MessagePacker addPayload(byte[] src, int off, int len) throws IOException { - if (buffer.size() - position < len || len > 8192) { + if (buffer.size() - position < len || len > bufferFlushThreshold) { flush(); // call flush before add out.add(src, off, len); totalFlushBytes += len; From 9a966a5a7ffdfa6497c434e65ea48b64e0823e62 Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Tue, 5 Jan 2016 00:06:45 +0900 Subject: [PATCH 223/234] Small optimization --- .../src/main/java/org/msgpack/core/MessageUnpacker.java | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java b/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java index 52fdc5fed..25b397359 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java +++ b/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java @@ -534,7 +534,7 @@ public Variable unpackValue(Variable var) MessageFormat mf = getNextFormat(); switch (mf.getValueType()) { case NIL: - unpackNil(); + readByte(); var.setNilValue(); return var; case BOOLEAN: @@ -902,7 +902,12 @@ private void resetDecoder() else { decoder.reset(); } - decodeStringBuffer = new StringBuilder(); + if (decodeStringBuffer == null) { + decodeStringBuffer = new StringBuilder(); + } + else { + decodeStringBuffer.setLength(0); + } } public String unpackString() From 0d78ca7d10e97b25c869d64d119f0eb8f2f2e05c Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Tue, 5 Jan 2016 00:48:24 +0900 Subject: [PATCH 224/234] Remove unused code --- msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java | 1 - 1 file changed, 1 deletion(-) diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java b/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java index 25b397359..a7cf970eb 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java +++ b/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java @@ -932,7 +932,6 @@ public String unpackString() int bufferRemaining = buffer.size() - position; if (bufferRemaining >= rawRemaining) { decodeStringBuffer.append(decodeStringFastPath(rawRemaining)); - rawRemaining = 0; break; } else if (bufferRemaining == 0) { From 31e1efa3adc6f5888e5d3d27affeac5b088ed7de Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Tue, 5 Jan 2016 02:25:07 +0900 Subject: [PATCH 225/234] Rename variable --- .../java/org/msgpack/core/buffer/ChannelBufferInput.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/msgpack-core/src/main/java/org/msgpack/core/buffer/ChannelBufferInput.java b/msgpack-core/src/main/java/org/msgpack/core/buffer/ChannelBufferInput.java index 6553e497f..f00cb0c30 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/buffer/ChannelBufferInput.java +++ b/msgpack-core/src/main/java/org/msgpack/core/buffer/ChannelBufferInput.java @@ -29,7 +29,7 @@ public class ChannelBufferInput implements MessageBufferInput { private ReadableByteChannel channel; - private final MessageBuffer m; + private final MessageBuffer buffer; public ChannelBufferInput(ReadableByteChannel channel) { @@ -40,7 +40,7 @@ public ChannelBufferInput(ReadableByteChannel channel, int bufferSize) { this.channel = checkNotNull(channel, "input channel is null"); checkArgument(bufferSize > 0, "buffer size must be > 0: " + bufferSize); - this.m = MessageBuffer.allocate(bufferSize); + this.buffer = MessageBuffer.allocate(bufferSize); } /** @@ -61,7 +61,7 @@ public ReadableByteChannel reset(ReadableByteChannel channel) public MessageBuffer next() throws IOException { - ByteBuffer b = m.sliceAsByteBuffer(); + ByteBuffer b = buffer.sliceAsByteBuffer(); while (b.remaining() > 0) { int ret = channel.read(b); if (ret == -1) { @@ -69,7 +69,7 @@ public MessageBuffer next() } } b.flip(); - return b.remaining() == 0 ? null : m.slice(0, b.limit()); + return b.remaining() == 0 ? null : buffer.slice(0, b.limit()); } @Override From cb38acad1cab8d040eaec455f84f3b8dba5d7a65 Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Tue, 5 Jan 2016 02:30:47 +0900 Subject: [PATCH 226/234] Set the version to 0.8.0-SNAPSHOT --- version.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.sbt b/version.sbt index 984699500..48bb0f19e 100644 --- a/version.sbt +++ b/version.sbt @@ -1 +1 @@ -version in ThisBuild := "0.7.2-SNAPSHOT" \ No newline at end of file +version in ThisBuild := "0.8.0-SNAPSHOT" \ No newline at end of file From 5e9bce63d1c742f506c8498f9ddb21f8782cef22 Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Tue, 5 Jan 2016 14:04:08 +0900 Subject: [PATCH 227/234] Prepare 0.8.0 release --- RELEASE_NOTES.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index 6b691c476..6ee94b80b 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -1,5 +1,10 @@ # Release Notes +* 0.8.0 + * Changed MessageBuffer API to alloww releasing the previously allocated buffers upon MessageBufferInput.next() call. + * Split MessagePack.Config into MessagePack.Packer/UnpackerConfig + * Performance improvement of packString + * 0.7.1 * Fix ImmutableLongValueImpl#asShort [#287](https://github.com/msgpack/msgpack-java/pull/287) From 172863371531a81b825cf0b86b49eb8fb0f77eff Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Tue, 5 Jan 2016 14:05:59 +0900 Subject: [PATCH 228/234] Setting version to 0.8.0 --- version.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.sbt b/version.sbt index 48bb0f19e..5a3cb9897 100644 --- a/version.sbt +++ b/version.sbt @@ -1 +1 @@ -version in ThisBuild := "0.8.0-SNAPSHOT" \ No newline at end of file +version in ThisBuild := "0.8.0" \ No newline at end of file From 328a97c302be55de995f9e25bd0b08a7bd8a70b4 Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Tue, 5 Jan 2016 14:06:24 +0900 Subject: [PATCH 229/234] Setting version to 0.8.1-SNAPSHOT --- version.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.sbt b/version.sbt index 5a3cb9897..93d712300 100644 --- a/version.sbt +++ b/version.sbt @@ -1 +1 @@ -version in ThisBuild := "0.8.0" \ No newline at end of file +version in ThisBuild := "0.8.1-SNAPSHOT" \ No newline at end of file From 61f11480fb73675bfb53f568fd6648ec9e4f0427 Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Tue, 5 Jan 2016 14:08:08 +0900 Subject: [PATCH 230/234] Update RELEASE_NOTES.md --- RELEASE_NOTES.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index 6ee94b80b..2f51f5db6 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -1,7 +1,7 @@ # Release Notes * 0.8.0 - * Changed MessageBuffer API to alloww releasing the previously allocated buffers upon MessageBufferInput.next() call. + * Changed MessageBuffer API to allow releasing the previously allocated buffers upon MessageBufferInput.next() call. * Split MessagePack.Config into MessagePack.Packer/UnpackerConfig * Performance improvement of packString From 875456158c9030998ab2074a13c463e59d5e9b73 Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Tue, 5 Jan 2016 14:13:22 +0900 Subject: [PATCH 231/234] Update RELEASE_NOTES.md --- RELEASE_NOTES.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index 2f51f5db6..5a269852b 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -1,8 +1,12 @@ # Release Notes * 0.8.0 - * Changed MessageBuffer API to allow releasing the previously allocated buffers upon MessageBufferInput.next() call. * Split MessagePack.Config into MessagePack.Packer/UnpackerConfig + * Changed MessageBuffer API + * It allows releasing the previously allocated buffers upon MessageBufferInput.next() call. + * MessageBufferOutput now can read data from external byte arrays + * MessagePacker supports addPayload(byte[]) to feed the data from an external data source + * This saves the cost of copying large data to the internal message buffer * Performance improvement of packString * 0.7.1 From 12791691c9c0c5b37754f55ad14415a9b767edef Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Tue, 5 Jan 2016 14:14:36 +0900 Subject: [PATCH 232/234] Update RELEASE_NOTES.md --- RELEASE_NOTES.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index 5a269852b..52b12f9d4 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -3,8 +3,8 @@ * 0.8.0 * Split MessagePack.Config into MessagePack.Packer/UnpackerConfig * Changed MessageBuffer API - * It allows releasing the previously allocated buffers upon MessageBufferInput.next() call. - * MessageBufferOutput now can read data from external byte arrays + * It allows releasing the previously allocated buffers upon MessageBufferInput.next() call. + * MessageBufferOutput now can read data from external byte arrays * MessagePacker supports addPayload(byte[]) to feed the data from an external data source * This saves the cost of copying large data to the internal message buffer * Performance improvement of packString From cb7f64286fa4365fa68cd9d5ef29a77df712363d Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Tue, 5 Jan 2016 14:23:10 +0900 Subject: [PATCH 233/234] Update README.md --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index c66b668d7..d2787d7e0 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ MessagePack for Java * Message Pack specification: -MessagePack v7 (0.7.x) is a faster implementation of the previous version [v06](https://github.com/msgpack/msgpack-java/tree/v06), and +MessagePack v7 (or later) is a faster implementation of the previous version [v06](https://github.com/msgpack/msgpack-java/tree/v06), and supports all of the message pack types, including [extension format](https://github.com/msgpack/msgpack/blob/master/spec.md#formats-ext). ## Limitation @@ -18,13 +18,13 @@ For Maven users: org.msgpack msgpack-core - 0.7.1 + 0.8.0 ``` For sbt users: ``` -libraryDependencies += "org.msgpack" % "msgpack-core" % "0.7.1" +libraryDependencies += "org.msgpack" % "msgpack-core" % "0.8.0" ``` For gradle users: @@ -34,7 +34,7 @@ repositories { } dependencies { - compile 'org.msgpack:msgpack-core:0.7.1' + compile 'org.msgpack:msgpack-core:0.8.0' } ``` From 94e3cee8d837bc06e567ceeebd44ba4308cbe476 Mon Sep 17 00:00:00 2001 From: Mitsunori Komatsu Date: Wed, 6 Jan 2016 22:56:06 +0900 Subject: [PATCH 234/234] Remove unused import in MessagePackExample --- .../test/java/org/msgpack/core/example/MessagePackExample.java | 1 - 1 file changed, 1 deletion(-) diff --git a/msgpack-core/src/test/java/org/msgpack/core/example/MessagePackExample.java b/msgpack-core/src/test/java/org/msgpack/core/example/MessagePackExample.java index 0b0e50123..e8802a037 100644 --- a/msgpack-core/src/test/java/org/msgpack/core/example/MessagePackExample.java +++ b/msgpack-core/src/test/java/org/msgpack/core/example/MessagePackExample.java @@ -33,7 +33,6 @@ import java.io.FileOutputStream; import java.io.IOException; import java.math.BigInteger; -import java.nio.charset.CodingErrorAction; /** * This class describes the usage of MessagePack v07