summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorfrsyuki <frsyuki@users.sourceforge.jp>2009-10-25 01:27:09 +0900
committerfrsyuki <frsyuki@users.sourceforge.jp>2009-10-25 01:27:09 +0900
commit5393a0df16f3bbdf296222b6337db5d57fe7c3a6 (patch)
treec9a5777139386dff7558aa966c49faedd6ce2241
parentc6a2569af8839ce68f96cca1d3aa61c0ac6ed4a6 (diff)
downloadmsgpack-python-5393a0df16f3bbdf296222b6337db5d57fe7c3a6.tar.gz
import MessagePack for Java implementation plan 1
-rw-r--r--java-plan1/MessagePack.java31
-rw-r--r--java-plan1/Packer.java266
-rw-r--r--java-plan1/Unpacker.java385
-rwxr-xr-xjava-plan1/run.sh3
-rw-r--r--java-plan1/test.java27
5 files changed, 712 insertions, 0 deletions
diff --git a/java-plan1/MessagePack.java b/java-plan1/MessagePack.java
new file mode 100644
index 0000000..143f6b5
--- /dev/null
+++ b/java-plan1/MessagePack.java
@@ -0,0 +1,31 @@
+import java.nio.ByteBuffer;
+import java.io.InputStream;
+import java.io.IOException;
+
+public class MessagePack {
+
+ static public Object unpack(InputStream source)
+ {
+ // FIXME not implemented yet
+ return null;
+ }
+
+ static public Object unpack(byte[] source, int len) throws IOException
+ {
+ // FIXME not implemented yet
+ return null;
+ }
+
+ static public Object unpack(ByteBuffer source) throws IOException
+ {
+ // FIXME not implemented yet
+ return null;
+ }
+
+ static public Object unpack(ByteBuffer[] source) throws IOException
+ {
+ // FIXME not implemented yet
+ return null;
+ }
+}
+
diff --git a/java-plan1/Packer.java b/java-plan1/Packer.java
new file mode 100644
index 0000000..ea6b2d4
--- /dev/null
+++ b/java-plan1/Packer.java
@@ -0,0 +1,266 @@
+import java.io.*;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.math.BigInteger;
+
+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 pack(Object o) throws IOException
+}
+
diff --git a/java-plan1/Unpacker.java b/java-plan1/Unpacker.java
new file mode 100644
index 0000000..be86344
--- /dev/null
+++ b/java-plan1/Unpacker.java
@@ -0,0 +1,385 @@
+import java.io.*;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.math.BigInteger;
+
+public class Unpacker {
+ protected static final int CS_HEADER = 0x00;
+ protected static final int CS_FLOAT = 0x0a;
+ protected static final int CS_DOUBLE = 0x0b;
+ protected static final int CS_UINT_8 = 0x0c;
+ protected static final int CS_UINT_16 = 0x0d;
+ protected static final int CS_UINT_32 = 0x0e;
+ protected static final int CS_UINT_64 = 0x0f;
+ protected static final int CS_INT_8 = 0x10;
+ protected static final int CS_INT_16 = 0x11;
+ protected static final int CS_INT_32 = 0x12;
+ protected static final int CS_INT_64 = 0x13;
+ protected static final int CS_RAW_16 = 0x1a;
+ protected static final int CS_RAW_32 = 0x1b;
+ protected static final int CS_ARRAY_16 = 0x1c;
+ protected static final int CS_ARRAY_32 = 0x1d;
+ protected static final int CS_MAP_16 = 0x1e;
+ protected static final int CS_MAP_32 = 0x1f;
+ protected static final int ACS_RAW_VALUE = 0x20;
+ protected static final int CT_ARRAY_ITEM = 0x00;
+ protected static final int CT_MAP_KEY = 0x01;
+ protected static final int CT_MAP_VALUE = 0x02;
+
+ protected static final int MAX_STACK_SIZE = 16;
+
+ protected int cs = CS_HEADER;
+ protected int trail = 0;
+ protected int top = -1;
+ protected boolean finished = false;
+ protected int[] stack_ct = new int[MAX_STACK_SIZE];
+ protected int[] stack_count = new int[MAX_STACK_SIZE];
+ protected Object[] stack_obj = new Object[MAX_STACK_SIZE];
+ protected Object[] stack_map_key = new Object[MAX_STACK_SIZE];
+ //protected Object user;
+ protected ByteBuffer castBuffer = ByteBuffer.allocate(8);
+
+ public Object getData()
+ {
+ return stack_obj[0];
+ }
+
+ public boolean isFinished()
+ {
+ return finished;
+ }
+
+
+ @SuppressWarnings("unchecked")
+ public int execute(byte[] src, int off, int length) throws IOException
+ {
+ if(off >= length) { return off; }
+
+ int limit = off + length;
+ int i = off;
+ int count;
+
+ Object obj = null;
+
+ _out: do {
+ _header_again: {
+ //System.out.println("while i:"+i);
+
+ int b = src[i];
+
+ _push: {
+ _fixed_trail_again:
+ if(cs == CS_HEADER) {
+
+ if((b & 0x80) == 0) { // Positive Fixnum
+ //System.out.println("positive fixnum "+b);
+ obj = b;
+ break _push;
+ }
+
+ if((b & 0xe0) == 0xe0) { // Negative Fixnum
+ //System.out.println("negative fixnum "+b);
+ obj = b;
+ break _push;
+ }
+
+ if((b & 0xe0) == 0xa0) { // FixRaw
+ trail = b & 0x1f;
+ if(trail == 0) {
+ obj = new byte[0];
+ break _push;
+ }
+ cs = ACS_RAW_VALUE;
+ break _fixed_trail_again;
+ }
+
+ if((b & 0xf0) == 0x90) { // FixArray
+ if(top >= MAX_STACK_SIZE) {
+ throw new IOException("parse error");
+ }
+ count = b & 0x0f;
+ ++top;
+ stack_obj[top] = new ArrayList(count);
+ stack_ct[top] = CT_ARRAY_ITEM;
+ stack_count[top] = count;
+ //System.out.println("fixarray count:"+count);
+ break _header_again;
+ }
+
+ if((b & 0xf0) == 0x80) { // FixMap
+ if(top >= MAX_STACK_SIZE) {
+ throw new IOException("parse error");
+ }
+ count = b & 0x0f;
+ ++top;
+ stack_obj[top] = new HashMap(count);
+ stack_ct[top] = CT_MAP_KEY;
+ stack_count[top] = count;
+ //System.out.println("fixmap count:"+count);
+ break _header_again;
+ }
+
+ switch(b & 0xff) { // FIXME
+ case 0xc0: // nil
+ obj = null;
+ break _push;
+ case 0xc2: // false
+ obj = false;
+ break _push;
+ case 0xc3: // true
+ obj = true;
+ break _push;
+ case 0xca: // float
+ case 0xcb: // double
+ case 0xcc: // unsigned int 8
+ case 0xcd: // unsigned int 16
+ case 0xce: // unsigned int 32
+ case 0xcf: // unsigned int 64
+ case 0xd0: // signed int 8
+ case 0xd1: // signed int 16
+ case 0xd2: // signed int 32
+ case 0xd3: // signed int 64
+ trail = 1 << (b & 0x03);
+ cs = b & 0x1f;
+ //System.out.println("a trail "+trail+" cs:"+cs);
+ break _fixed_trail_again;
+ case 0xda: // raw 16
+ case 0xdb: // raw 32
+ case 0xdc: // array 16
+ case 0xdd: // array 32
+ case 0xde: // map 16
+ case 0xdf: // map 32
+ trail = 2 << (b & 0x01);
+ cs = b & 0x1f;
+ //System.out.println("b trail "+trail+" cs:"+cs);
+ break _fixed_trail_again;
+ default:
+ //System.out.println("unknown b "+(b&0xff));
+ throw new IOException("parse error");
+ }
+
+ } // _fixed_trail_again
+
+ do {
+ _fixed_trail_again: {
+
+ if(limit - i <= trail) { break _out; }
+ int n = i + 1;
+ i += trail;
+
+ switch(cs) {
+ case CS_FLOAT:
+ castBuffer.rewind();
+ castBuffer.put(src, n, 4);
+ obj = castBuffer.getFloat(0);
+ //System.out.println("float "+obj);
+ break _push;
+ case CS_DOUBLE:
+ castBuffer.rewind();
+ castBuffer.put(src, n, 8);
+ obj = castBuffer.getDouble(0);
+ //System.out.println("double "+obj);
+ break _push;
+ case CS_UINT_8:
+ //System.out.println(n);
+ //System.out.println(src[n]);
+ //System.out.println(src[n+1]);
+ //System.out.println(src[n-1]);
+ obj = ((int)src[n]) & 0xff;
+ //System.out.println("uint8 "+obj);
+ break _push;
+ case CS_UINT_16:
+ //System.out.println(src[n]);
+ //System.out.println(src[n+1]);
+ castBuffer.rewind();
+ castBuffer.put(src, n, 2);
+ obj = ((int)castBuffer.getShort(0)) & 0xffff;
+ //System.out.println("uint 16 "+obj);
+ break _push;
+ case CS_UINT_32:
+ castBuffer.rewind();
+ castBuffer.put(src, n, 4);
+ {
+ // FIXME always long?
+ int o = castBuffer.getInt(0);
+ if(o < 0) {
+ obj = ((long)o) & 0xffffffffL;
+ } else {
+ obj = o;
+ }
+ }
+ //System.out.println("uint 32 "+obj);
+ break _push;
+ case CS_UINT_64:
+ castBuffer.rewind();
+ castBuffer.put(src, n, 8);
+ {
+ // FIXME always BigInteger?
+ long o = castBuffer.getLong(0);
+ if(o < 0) {
+ obj = BigInteger.valueOf(o & 0x7fffffffL).setBit(31);
+ } else {
+ obj = o;
+ }
+ }
+ throw new IOException("uint 64 is not supported");
+ case CS_INT_8:
+ obj = (int)src[n];
+ break _push;
+ case CS_INT_16:
+ castBuffer.rewind();
+ castBuffer.put(src, n, 2);
+ obj = (int)castBuffer.getShort(0);
+ break _push;
+ case CS_INT_32:
+ castBuffer.rewind();
+ castBuffer.put(src, n, 4);
+ obj = (int)castBuffer.getInt(0);
+ break _push;
+ case CS_INT_64:
+ castBuffer.rewind();
+ castBuffer.put(src, n, 8);
+ {
+ // FIXME always long?
+ long o = castBuffer.getLong(0);
+ if(o <= 0x7fffffffL && o > -0x80000000L) {
+ obj = (int)o;
+ } else {
+ obj = o;
+ }
+ }
+ //System.out.println("long "+obj);
+ break _push;
+ case CS_RAW_16:
+ castBuffer.rewind();
+ castBuffer.put(src, n, 2);
+ trail = ((int)castBuffer.getShort(0)) & 0xffff;
+ if(trail == 0) {
+ obj = new byte[0];
+ break _push;
+ }
+ cs = ACS_RAW_VALUE;
+ break _fixed_trail_again;
+ case CS_RAW_32:
+ castBuffer.rewind();
+ castBuffer.put(src, n, 4);
+ // FIXME overflow check
+ trail = castBuffer.getInt(0) & 0x7fffffff;
+ if(trail == 0) {
+ obj = new byte[0];
+ break _push;
+ }
+ cs = ACS_RAW_VALUE;
+ case ACS_RAW_VALUE:
+ obj = ByteBuffer.wrap(src, n, trail); // FIXME プール? コピー
+ break _push;
+ case CS_ARRAY_16:
+ if(top >= MAX_STACK_SIZE) {
+ throw new IOException("parse error");
+ }
+ castBuffer.rewind();
+ castBuffer.put(src, n, 2);
+ count = ((int)castBuffer.getShort(0)) & 0xffff;
+ ++top;
+ stack_obj[top] = new ArrayList(count);
+ stack_ct[top] = CT_ARRAY_ITEM;
+ stack_count[top] = count;
+ break _header_again;
+ case CS_ARRAY_32:
+ if(top >= MAX_STACK_SIZE) {
+ throw new IOException("parse error");
+ }
+ castBuffer.rewind();
+ castBuffer.put(src, n, 4);
+ // FIXME overflow check
+ count = castBuffer.getInt(0) & 0x7fffffff;
+ ++top;
+ stack_obj[top] = new ArrayList(count);
+ stack_ct[top] = CT_ARRAY_ITEM;
+ stack_count[top] = count;
+ break _header_again;
+ case CS_MAP_16:
+ if(top >= MAX_STACK_SIZE) {
+ throw new IOException("parse error");
+ }
+ castBuffer.rewind();
+ castBuffer.put(src, n, 2);
+ count = ((int)castBuffer.getShort(0)) & 0xffff;
+ ++top;
+ stack_obj[top] = new HashMap(count);
+ stack_ct[top] = CT_MAP_KEY;
+ stack_count[top] = count;
+ //System.out.println("fixmap count:"+count);
+ break _header_again;
+ case CS_MAP_32:
+ if(top >= MAX_STACK_SIZE) {
+ throw new IOException("parse error");
+ }
+ castBuffer.rewind();
+ castBuffer.put(src, n, 4);
+ // FIXME overflow check
+ count = castBuffer.getInt(0) & 0x7fffffff;
+ ++top;
+ stack_obj[top] = new HashMap(count);
+ stack_ct[top] = CT_MAP_KEY;
+ stack_count[top] = count;
+ //System.out.println("fixmap count:"+count);
+ break _header_again;
+ default:
+ throw new IOException("parse error");
+ }
+
+ } // _fixed_trail_again
+ } while(true);
+ } // _push
+
+ do {
+ _push: {
+ //System.out.println("push top:"+top);
+ if(top == -1) {
+ stack_obj[0] = obj;
+ finished = true;
+ break _out;
+ }
+
+ switch(stack_ct[top]) {
+ case CT_ARRAY_ITEM:
+ //System.out.println("array item "+obj);
+ ((ArrayList)(stack_obj[top])).add(obj);
+ if(--stack_count[top] == 0) {
+ obj = stack_obj[top];
+ --top;
+ break _push;
+ }
+ break _header_again;
+ case CT_MAP_KEY:
+ //System.out.println("map key:"+top+" "+obj);
+ stack_map_key[top] = obj;
+ stack_ct[top] = CT_MAP_VALUE;
+ break _header_again;
+ case CT_MAP_VALUE:
+ //System.out.println("map value:"+top+" "+obj);
+ ((HashMap)(stack_obj[top])).put(stack_map_key[top], obj);
+ if(--stack_count[top] == 0) {
+ obj = stack_obj[top];
+ --top;
+ break _push;
+ }
+ stack_ct[top] = CT_MAP_KEY;
+ break _header_again;
+ default:
+ throw new IOException("parse error");
+ }
+ } // _push
+ } while(true);
+
+ } // _header_again
+ cs = CS_HEADER;
+ ++i;
+ } while(i < limit); // _out
+
+ return i - off;
+ }
+}
+
diff --git a/java-plan1/run.sh b/java-plan1/run.sh
new file mode 100755
index 0000000..1539a37
--- /dev/null
+++ b/java-plan1/run.sh
@@ -0,0 +1,3 @@
+#!/bin/sh
+javac MessagePack.java Packer.java Unpacker.java test.java
+java test
diff --git a/java-plan1/test.java b/java-plan1/test.java
new file mode 100644
index 0000000..938a687
--- /dev/null
+++ b/java-plan1/test.java
@@ -0,0 +1,27 @@
+import java.util.*;
+import java.io.*;
+
+class OpenByteArrayOutputStream extends ByteArrayOutputStream {
+ int getCount() { return count; }
+ byte[] getBuffer() { return buf; }
+}
+
+public class test {
+ public static void main(String[] args) throws IOException
+ {
+ OpenByteArrayOutputStream out = new OpenByteArrayOutputStream();
+
+ Packer pk = new Packer(out);
+ pk.packArray(3)
+ .packInt(0)
+ .packByte((byte)1)
+ .packDouble(0.1);
+
+ Unpacker pac = new Unpacker();
+ int nlen = pac.execute(out.getBuffer(), 0, out.getCount());
+ if(pac.isFinished()) {
+ System.out.println(pac.getData());
+ }
+ }
+}
+