diff --git a/java-plan2/test/Generate.java b/java-plan2/test/Generate.java
index 2ac5878d..6b7800bb 100644
--- a/java-plan2/test/Generate.java
+++ b/java-plan2/test/Generate.java
@@ -11,7 +11,7 @@ public class Generate {
Schema s1 = Schema.parse("(class Test (field uri raw) (field width int))");
ClassGenerator.write(s1, output);
- Schema s1 = Schema.parse("(class MediaContent (package serializers.msgpack) (field image (array (class Image (field uri string) (field title string) (field width int) (field height int) (field size int)))) (field media (class Media (field uri string) (field title string) (field width int) (field height int) (field format string) (field duration long) (field size long) (field bitrate int) (field person (array string)) (field player int) (field copyright string))))");
+ Schema s2 = Schema.parse("(class MediaContent (package serializers.msgpack) (field image (array (class Image (field uri string) (field title string) (field width int) (field height int) (field size int)))) (field media (class Media (field uri string) (field title string) (field width int) (field height int) (field format string) (field duration long) (field size long) (field bitrate int) (field person (array string)) (field player int) (field copyright string))))");
ClassGenerator.write(s2, output);
}
}
diff --git a/java-plan3/build.xml b/java-plan3/build.xml
new file mode 100644
index 00000000..598a853d
--- /dev/null
+++ b/java-plan3/build.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/java-plan3/src/org/msgpack/MessageMergeable.java b/java-plan3/src/org/msgpack/MessageMergeable.java
new file mode 100644
index 00000000..e11119cb
--- /dev/null
+++ b/java-plan3/src/org/msgpack/MessageMergeable.java
@@ -0,0 +1,23 @@
+//
+// MessagePack for Java
+//
+// Copyright (C) 2009 FURUHASHI Sadayuki
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+package org.msgpack;
+
+public interface MessageMergeable {
+ public void messageMerge(Object obj) throws MessageTypeException;
+}
+
diff --git a/java-plan3/src/org/msgpack/MessagePackable.java b/java-plan3/src/org/msgpack/MessagePackable.java
new file mode 100644
index 00000000..d8a7db9c
--- /dev/null
+++ b/java-plan3/src/org/msgpack/MessagePackable.java
@@ -0,0 +1,25 @@
+//
+// MessagePack for Java
+//
+// Copyright (C) 2009 FURUHASHI Sadayuki
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+package org.msgpack;
+
+import java.io.IOException;
+
+public interface MessagePackable {
+ public void messagePack(Packer pk) throws IOException;
+}
+
diff --git a/java-plan3/src/org/msgpack/MessageTypeException.java b/java-plan3/src/org/msgpack/MessageTypeException.java
new file mode 100644
index 00000000..09031b21
--- /dev/null
+++ b/java-plan3/src/org/msgpack/MessageTypeException.java
@@ -0,0 +1,39 @@
+//
+// MessagePack for Java
+//
+// Copyright (C) 2009 FURUHASHI Sadayuki
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+package org.msgpack;
+
+import java.io.IOException;
+
+public class MessageTypeException extends IOException {
+ public MessageTypeException() { }
+
+ public MessageTypeException(String s) {
+ super(s);
+ }
+
+ public static MessageTypeException invalidConvert(Object from, Schema to) {
+ return new MessageTypeException(from.getClass().getName()+" cannot be convert to "+to.getExpression());
+ }
+
+ /* FIXME
+ public static MessageTypeException schemaMismatch(Schema to) {
+ return new MessageTypeException("schema mismatch "+to.getExpression());
+ }
+ */
+}
+
diff --git a/java-plan3/src/org/msgpack/Packer.java b/java-plan3/src/org/msgpack/Packer.java
new file mode 100644
index 00000000..7f2508c3
--- /dev/null
+++ b/java-plan3/src/org/msgpack/Packer.java
@@ -0,0 +1,409 @@
+//
+// MessagePack for Java
+//
+// Copyright (C) 2009 FURUHASHI Sadayuki
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+package org.msgpack;
+
+import java.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;
+ }
+
+
+ public Packer packWithSchema(Object o, Schema s) throws IOException {
+ s.pack(this, o);
+ return this;
+ }
+
+
+ public Packer packString(String s) throws IOException {
+ byte[] b = ((String)s).getBytes("UTF-8");
+ packRaw(b.length);
+ return packRawBody(b);
+ }
+
+
+ public Packer pack(String o) throws IOException {
+ if(o == null) { return packNil(); }
+ return packString(o);
+ }
+
+ public Packer pack(MessagePackable o) throws IOException {
+ if(o == null) { return packNil(); }
+ o.messagePack(this);
+ return this;
+ }
+
+ public Packer pack(byte[] o) throws IOException {
+ if(o == null) { return packNil(); }
+ packRaw(o.length);
+ return packRawBody(o);
+ }
+
+ public Packer pack(List o) throws IOException {
+ if(o == null) { return packNil(); }
+ packArray(o.size());
+ for(Object i : o) { pack(i); }
+ return this;
+ }
+
+ @SuppressWarnings("unchecked")
+ public Packer pack(Map o) throws IOException {
+ if(o == null) { return packNil(); }
+ packMap(o.size());
+ for(Map.Entry e : ((Map