diff --git a/java-plan1/MessagePack.java b/java-plan1/MessagePack.java
index 143f6b51..0a4f442c 100644
--- a/java-plan1/MessagePack.java
+++ b/java-plan1/MessagePack.java
@@ -29,3 +29,9 @@ public class MessagePack {
}
}
+/*
+public interface MessagePackable {
+ public void toMessagePack(Packer pk);
+}
+*/
+
diff --git a/java-plan2/build.xml b/java-plan2/build.xml
new file mode 100644
index 00000000..d382ce04
--- /dev/null
+++ b/java-plan2/build.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/java-plan2/src/org/msgpack/GenericArray.java b/java-plan2/src/org/msgpack/GenericArray.java
new file mode 100644
index 00000000..53799ca8
--- /dev/null
+++ b/java-plan2/src/org/msgpack/GenericArray.java
@@ -0,0 +1,25 @@
+package org.msgpack;
+
+import java.util.List;
+import java.util.ArrayList;
+
+public class GenericArray extends GenericObject {
+ private ArrayList array;
+
+ public GenericArray(int length)
+ {
+ this.array = new ArrayList(length);
+ }
+
+ public void add(GenericObject element)
+ {
+ array.add(element);
+ }
+
+ @Override
+ public List asArray()
+ {
+ return array;
+ }
+}
+
diff --git a/java-plan2/src/org/msgpack/GenericBoolean.java b/java-plan2/src/org/msgpack/GenericBoolean.java
new file mode 100644
index 00000000..908128f1
--- /dev/null
+++ b/java-plan2/src/org/msgpack/GenericBoolean.java
@@ -0,0 +1,17 @@
+package org.msgpack;
+
+public class GenericBoolean extends GenericObject {
+ boolean value;
+
+ public GenericBoolean(boolean value)
+ {
+ this.value = value;
+ }
+
+ @Override
+ public boolean asBoolean()
+ {
+ return value;
+ }
+}
+
diff --git a/java-plan2/src/org/msgpack/GenericLong.java b/java-plan2/src/org/msgpack/GenericLong.java
new file mode 100644
index 00000000..7cc9110d
--- /dev/null
+++ b/java-plan2/src/org/msgpack/GenericLong.java
@@ -0,0 +1,17 @@
+package org.msgpack;
+
+public class GenericLong extends GenericObject {
+ long value;
+
+ public GenericLong(long value)
+ {
+ this.value = value;
+ }
+
+ @Override
+ public long asLong()
+ {
+ return value;
+ }
+}
+
diff --git a/java-plan2/src/org/msgpack/GenericMap.java b/java-plan2/src/org/msgpack/GenericMap.java
new file mode 100644
index 00000000..0a5512a6
--- /dev/null
+++ b/java-plan2/src/org/msgpack/GenericMap.java
@@ -0,0 +1,25 @@
+package org.msgpack;
+
+import java.util.Map;
+import java.util.HashMap;
+
+public class GenericMap extends GenericObject {
+ private HashMap map;
+
+ public GenericMap(int length)
+ {
+ this.map = new HashMap(length);
+ }
+
+ public void put(GenericObject key, GenericObject value)
+ {
+ map.put(key, value);
+ }
+
+ @Override
+ public Map asMap()
+ {
+ return map;
+ }
+}
+
diff --git a/java-plan2/src/org/msgpack/GenericObject.java b/java-plan2/src/org/msgpack/GenericObject.java
new file mode 100644
index 00000000..32eacd36
--- /dev/null
+++ b/java-plan2/src/org/msgpack/GenericObject.java
@@ -0,0 +1,52 @@
+package org.msgpack;
+
+import java.util.List;
+import java.util.Map;
+
+public abstract class GenericObject {
+ public boolean asBoolean()
+ {
+ throw new RuntimeException("type error");
+ }
+
+ public byte asByte()
+ {
+ throw new RuntimeException("type error");
+ }
+
+ public short asShort()
+ {
+ throw new RuntimeException("type error");
+ }
+
+ public int asInt()
+ {
+ throw new RuntimeException("type error");
+ }
+
+ public long asLong()
+ {
+ throw new RuntimeException("type error");
+ }
+
+ public String asString()
+ {
+ throw new RuntimeException("type error");
+ }
+
+ public byte[] asBytes()
+ {
+ throw new RuntimeException("type error");
+ }
+
+ public List asArray()
+ {
+ throw new RuntimeException("type error");
+ }
+
+ public Map asMap()
+ {
+ throw new RuntimeException("type error");
+ }
+}
+
diff --git a/java-plan2/src/org/msgpack/GenericRaw.java b/java-plan2/src/org/msgpack/GenericRaw.java
new file mode 100644
index 00000000..6de03b28
--- /dev/null
+++ b/java-plan2/src/org/msgpack/GenericRaw.java
@@ -0,0 +1,59 @@
+package org.msgpack;
+
+import java.nio.charset.Charset;
+
+public class GenericRaw extends GenericObject {
+ byte[] bytes;
+ String string;
+
+ public GenericRaw()
+ {
+ this.bytes = new byte[0];
+ this.string = null;
+ }
+
+ public GenericRaw(byte[] bytes)
+ {
+ this.bytes = bytes;
+ this.string = null;
+ }
+
+ public GenericRaw(String string)
+ {
+ this.bytes = null;
+ this.string = string;
+ }
+
+ public synchronized void setString(String string)
+ {
+ this.string = string;
+ this.bytes = null;
+ }
+
+ public synchronized void setBytes(byte[] bytes)
+ {
+ this.bytes = bytes;
+ this.string = null;
+ }
+
+ private static Charset UTF8_CHARSET = Charset.forName("UTF-8");
+
+ @Override
+ public synchronized String asString()
+ {
+ if(string == null) {
+ return string = new String(bytes, UTF8_CHARSET);
+ }
+ return string;
+ }
+
+ @Override
+ public synchronized byte[] asBytes()
+ {
+ if(bytes == null) {
+ return bytes = string.getBytes(UTF8_CHARSET);
+ }
+ return bytes;
+ }
+}
+
diff --git a/java-plan2/src/org/msgpack/GenericRawRef.java b/java-plan2/src/org/msgpack/GenericRawRef.java
new file mode 100644
index 00000000..70078100
--- /dev/null
+++ b/java-plan2/src/org/msgpack/GenericRawRef.java
@@ -0,0 +1,55 @@
+package org.msgpack;
+
+import java.nio.charset.Charset;
+
+public class GenericRawRef extends GenericRaw {
+ int offset;
+ int length;
+
+ public GenericRawRef(byte[] bytes, int offset, int length)
+ {
+ this.bytes = bytes;
+ this.offset = offset;
+ this.length = length;
+ this.string = null;
+ }
+
+ public GenericRawRef(String string)
+ {
+ this.bytes = null;
+ this.string = string;
+ }
+
+ public synchronized void setString(String string)
+ {
+ this.string = string;
+ this.bytes = null;
+ }
+
+ public synchronized void setBytes(byte[] bytes)
+ {
+ this.bytes = bytes;
+ this.string = null;
+ }
+
+ private static Charset UTF8_CHARSET = Charset.forName("UTF-8");
+
+ @Override
+ public synchronized String asString()
+ {
+ if(string == null) {
+ return string = new String(bytes, UTF8_CHARSET);
+ }
+ return string;
+ }
+
+ @Override
+ public synchronized byte[] asBytes()
+ {
+ if(bytes == null) {
+ return bytes = string.getBytes(UTF8_CHARSET);
+ }
+ return bytes;
+ }
+}
+
diff --git a/java-plan2/src/org/msgpack/GenericShort.java b/java-plan2/src/org/msgpack/GenericShort.java
new file mode 100644
index 00000000..eb2463e3
--- /dev/null
+++ b/java-plan2/src/org/msgpack/GenericShort.java
@@ -0,0 +1,29 @@
+package org.msgpack;
+
+public class GenericShort extends GenericObject {
+ short value;
+
+ public GenericShort(short value)
+ {
+ this.value = value;
+ }
+
+ @Override
+ public short asShort()
+ {
+ return value;
+ }
+
+ @Override
+ public int asInt()
+ {
+ return value;
+ }
+
+ @Override
+ public long asLong()
+ {
+ return value;
+ }
+}
+
diff --git a/java-plan2/src/org/msgpack/MessageConvertable.java b/java-plan2/src/org/msgpack/MessageConvertable.java
new file mode 100644
index 00000000..68c123ec
--- /dev/null
+++ b/java-plan2/src/org/msgpack/MessageConvertable.java
@@ -0,0 +1,7 @@
+package org.msgpack;
+
+public interface MessageConvertable
+{
+ public void messageConvert(GenericObject obj);
+}
+
diff --git a/java-plan2/src/org/msgpack/MessageMergeable.java b/java-plan2/src/org/msgpack/MessageMergeable.java
new file mode 100644
index 00000000..dc507490
--- /dev/null
+++ b/java-plan2/src/org/msgpack/MessageMergeable.java
@@ -0,0 +1,7 @@
+package org.msgpack;
+
+public interface MessageMergeable {
+ public void setField(int index, Object value);
+ public Object getField(int index);
+}
+
diff --git a/java-plan2/src/org/msgpack/MessagePackException.java b/java-plan2/src/org/msgpack/MessagePackException.java
new file mode 100644
index 00000000..dc379893
--- /dev/null
+++ b/java-plan2/src/org/msgpack/MessagePackException.java
@@ -0,0 +1,10 @@
+package org.msgpack;
+
+public class MessagePackException extends RuntimeException
+{
+ public MessagePackException(String message)
+ {
+ super(message);
+ }
+}
+
diff --git a/java-plan2/src/org/msgpack/MessagePackable.java b/java-plan2/src/org/msgpack/MessagePackable.java
new file mode 100644
index 00000000..1efff3f0
--- /dev/null
+++ b/java-plan2/src/org/msgpack/MessagePackable.java
@@ -0,0 +1,9 @@
+package org.msgpack;
+
+import java.io.IOException;
+
+public interface MessagePackable
+{
+ public void messagePack(Packer pk) throws IOException;
+}
+
diff --git a/java-plan2/src/org/msgpack/Packer.java b/java-plan2/src/org/msgpack/Packer.java
new file mode 100644
index 00000000..4545849e
--- /dev/null
+++ b/java-plan2/src/org/msgpack/Packer.java
@@ -0,0 +1,332 @@
+package org.msgpack;
+
+import java.io.OutputStream;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.charset.Charset;
+import java.util.List;
+import java.util.Map;
+
+public class Packer {
+ protected byte[] castBytes = new byte[9];
+ protected ByteBuffer castBuffer = ByteBuffer.wrap(castBytes);
+ protected OutputStream out;
+
+ public Packer(OutputStream out)
+ {
+ this.out = out;
+ }
+
+ public Packer packByte(byte d) throws IOException
+ {
+ if(d < -(1<<5)) {
+ castBytes[0] = (byte)0xd1;
+ castBytes[1] = d;
+ out.write(castBytes, 0, 2);
+ } else {
+ out.write(d);
+ }
+ return this;
+ }
+
+ public Packer packShort(short d) throws IOException
+ {
+ if(d < -(1<<5)) {
+ if(d < -(1<<7)) {
+ // signed 16
+ castBytes[0] = (byte)0xd1;
+ castBuffer.putShort(1, d);
+ out.write(castBytes, 0, 3);
+ } else {
+ // signed 8
+ castBytes[0] = (byte)0xd0;
+ castBytes[1] = (byte)d;
+ out.write(castBytes, 0, 2);
+ }
+ } else if(d < (1<<7)) {
+ // fixnum
+ out.write((byte)d);
+ } else {
+ if(d < (1<<8)) {
+ // unsigned 8
+ castBytes[0] = (byte)0xcc;
+ castBytes[1] = (byte)d;
+ out.write(castBytes, 0, 2);
+ } else {
+ // unsigned 16
+ castBytes[0] = (byte)0xcd;
+ castBuffer.putShort(1, d);
+ out.write(castBytes, 0, 3);
+ }
+ }
+ return this;
+ }
+
+ public Packer packInt(int d) throws IOException
+ {
+ if(d < -(1<<5)) {
+ if(d < -(1<<15)) {
+ // signed 32
+ castBytes[0] = (byte)0xd2;
+ castBuffer.putInt(1, d);
+ out.write(castBytes, 0, 5);
+ } else if(d < -(1<<7)) {
+ // signed 16
+ castBytes[0] = (byte)0xd1;
+ castBuffer.putShort(1, (short)d);
+ out.write(castBytes, 0, 3);
+ } else {
+ // signed 8
+ castBytes[0] = (byte)0xd0;
+ castBytes[1] = (byte)d;
+ out.write(castBytes, 0, 2);
+ }
+ } else if(d < (1<<7)) {
+ // fixnum
+ out.write((byte)d);
+ } else {
+ if(d < (1<<8)) {
+ // unsigned 8
+ castBytes[0] = (byte)0xcc;
+ castBytes[1] = (byte)d;
+ out.write(castBytes, 0, 2);
+ } else if(d < (1<<16)) {
+ // unsigned 16
+ castBytes[0] = (byte)0xcd;
+ castBuffer.putShort(1, (short)d);
+ out.write(castBytes, 0, 3);
+ } else {
+ // unsigned 32
+ castBytes[0] = (byte)0xce;
+ castBuffer.putInt(1, d);
+ out.write(castBytes, 0, 5);
+ }
+ }
+ return this;
+ }
+
+ public Packer packLong(long d) throws IOException
+ {
+ if(d < -(1L<<5)) {
+ if(d < -(1L<<15)) {
+ if(d < -(1L<<31)) {
+ // signed 64
+ castBytes[0] = (byte)0xd3;
+ castBuffer.putLong(1, d);
+ out.write(castBytes, 0, 9);
+ } else {
+ // signed 32
+ castBytes[0] = (byte)0xd2;
+ castBuffer.putInt(1, (int)d);
+ out.write(castBytes, 0, 5);
+ }
+ } else {
+ if(d < -(1<<7)) {
+ // signed 16
+ castBytes[0] = (byte)0xd1;
+ castBuffer.putShort(1, (short)d);
+ out.write(castBytes, 0, 3);
+ } else {
+ // signed 8
+ castBytes[0] = (byte)0xd0;
+ castBytes[1] = (byte)d;
+ out.write(castBytes, 0, 2);
+ }
+ }
+ } else if(d < (1<<7)) {
+ // fixnum
+ out.write((byte)d);
+ } else {
+ if(d < (1L<<16)) {
+ if(d < (1<<8)) {
+ // unsigned 8
+ castBytes[0] = (byte)0xcc;
+ castBytes[1] = (byte)d;
+ out.write(castBytes, 0, 2);
+ } else {
+ // unsigned 16
+ castBytes[0] = (byte)0xcd;
+ castBuffer.putShort(1, (short)d);
+ out.write(castBytes, 0, 3);
+ //System.out.println("pack uint 16 "+(short)d);
+ }
+ } else {
+ if(d < (1L<<32)) {
+ // unsigned 32
+ castBytes[0] = (byte)0xce;
+ castBuffer.putInt(1, (int)d);
+ out.write(castBytes, 0, 5);
+ } else {
+ // unsigned 64
+ castBytes[0] = (byte)0xcf;
+ castBuffer.putLong(1, d);
+ out.write(castBytes, 0, 9);
+ }
+ }
+ }
+ return this;
+ }
+
+ public Packer packFloat(float d) throws IOException
+ {
+ castBytes[0] = (byte)0xca;
+ castBuffer.putFloat(1, d);
+ out.write(castBytes, 0, 5);
+ return this;
+ }
+
+ public Packer packDouble(double d) throws IOException
+ {
+ castBytes[0] = (byte)0xcb;
+ castBuffer.putDouble(1, d);
+ out.write(castBytes, 0, 9);
+ return this;
+ }
+
+ public Packer packNil() throws IOException
+ {
+ out.write((byte)0xc0);
+ return this;
+ }
+
+ public Packer packTrue() throws IOException
+ {
+ out.write((byte)0xc3);
+ return this;
+ }
+
+ public Packer packFalse() throws IOException
+ {
+ out.write((byte)0xc2);
+ return this;
+ }
+
+ public Packer packArray(int n) throws IOException
+ {
+ if(n < 16) {
+ final int d = 0x90 | n;
+ out.write((byte)d);
+ } else if(n < 65536) {
+ castBytes[0] = (byte)0xdc;
+ castBuffer.putShort(1, (short)n);
+ out.write(castBytes, 0, 3);
+ } else {
+ castBytes[0] = (byte)0xdd;
+ castBuffer.putInt(1, n);
+ out.write(castBytes, 0, 5);
+ }
+ return this;
+ }
+
+ public Packer packMap(int n) throws IOException
+ {
+ if(n < 16) {
+ final int d = 0x80 | n;
+ out.write((byte)d);
+ } else if(n < 65536) {
+ castBytes[0] = (byte)0xde;
+ castBuffer.putShort(1, (short)n);
+ out.write(castBytes, 0, 3);
+ } else {
+ castBytes[0] = (byte)0xdf;
+ castBuffer.putInt(1, n);
+ out.write(castBytes, 0, 5);
+ }
+ return this;
+ }
+
+ public Packer packRaw(int n) throws IOException
+ {
+ if(n < 32) {
+ final int d = 0xa0 | n;
+ out.write((byte)d);
+ } else if(n < 65536) {
+ castBytes[0] = (byte)0xda;
+ castBuffer.putShort(1, (short)n);
+ out.write(castBytes, 0, 3);
+ } else {
+ castBytes[0] = (byte)0xdb;
+ castBuffer.putInt(1, n);
+ out.write(castBytes, 0, 5);
+ }
+ return this;
+ }
+
+ public Packer packRawBody(byte[] b) throws IOException
+ {
+ out.write(b);
+ return this;
+ }
+
+ public Packer packRawBody(byte[] b, int off, int length) throws IOException
+ {
+ out.write(b, off, length);
+ return this;
+ }
+
+ private static Charset UTF8_CHARSET = Charset.forName("UTF-8");
+
+ public Packer packString(String s) throws IOException
+ {
+ byte[] b = ((String)s).getBytes(UTF8_CHARSET);
+ packRaw(b.length);
+ packRawBody(b);
+ return this;
+ }
+
+ public Packer pack(MessagePackable o) throws IOException
+ {
+ o.messagePack(this);
+ return this;
+ }
+
+ public Packer pack(Object o) throws IOException
+ {
+ if(o == null) {
+ packNil();
+ } else if(o instanceof String) {
+ byte[] b = ((String)o).getBytes(UTF8_CHARSET);
+ packRaw(b.length);
+ packRawBody(b);
+ } else if(o instanceof byte[]) {
+ byte[] b = (byte[])o;
+ packRaw(b.length);
+ packRawBody(b);
+ } else if(o instanceof List) {
+ List