mirror of
https://github.com/msgpack/msgpack-c.git
synced 2025-04-01 01:16:52 +02:00
java: redesign
This commit is contained in:
parent
6cde9f3a9d
commit
979ff80982
@ -51,6 +51,14 @@ inline void operator<< (object::with_zone& o, type::nil v)
|
|||||||
{ static_cast<object&>(o) << v; }
|
{ static_cast<object&>(o) << v; }
|
||||||
|
|
||||||
|
|
||||||
|
template <>
|
||||||
|
inline void object::as<void>() const
|
||||||
|
{
|
||||||
|
msgpack::type::nil v;
|
||||||
|
convert(&v);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
} // namespace msgpack
|
} // namespace msgpack
|
||||||
|
|
||||||
#endif /* msgpack/type/nil.hpp */
|
#endif /* msgpack/type/nil.hpp */
|
||||||
|
384
java/src/main/java/org/msgpack/BufferedUnpackerImpl.java
Normal file
384
java/src/main/java/org/msgpack/BufferedUnpackerImpl.java
Normal file
@ -0,0 +1,384 @@
|
|||||||
|
//
|
||||||
|
// MessagePack for Java
|
||||||
|
//
|
||||||
|
// Copyright (C) 2009-2010 FURUHASHI Sadayuki
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
//
|
||||||
|
package org.msgpack;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
//import java.math.BigInteger;
|
||||||
|
|
||||||
|
abstract class BufferedUnpackerImpl extends UnpackerImpl {
|
||||||
|
int filled = 0;
|
||||||
|
byte[] buffer = null;
|
||||||
|
private ByteBuffer castBuffer = ByteBuffer.allocate(8);
|
||||||
|
|
||||||
|
abstract boolean fill() throws IOException;
|
||||||
|
|
||||||
|
final int next(int offset, UnpackResult result) throws IOException, UnpackException {
|
||||||
|
if(filled == 0) {
|
||||||
|
if(!fill()) {
|
||||||
|
return offset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
|
int noffset = super.execute(buffer, offset, filled);
|
||||||
|
if(noffset <= offset) {
|
||||||
|
if(!fill()) {
|
||||||
|
return offset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
offset = noffset;
|
||||||
|
} while(!super.isFinished());
|
||||||
|
|
||||||
|
Object obj = super.getData();
|
||||||
|
super.reset();
|
||||||
|
result.done(obj);
|
||||||
|
|
||||||
|
return offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
private final void more(int offset, int require) throws IOException, UnpackException {
|
||||||
|
while(filled - offset < require) {
|
||||||
|
if(!fill()) {
|
||||||
|
// FIXME
|
||||||
|
throw new UnpackException("insufficient buffer");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final byte unpackByte(UnpackCursor c, int offset) throws IOException, MessageTypeException {
|
||||||
|
int o = unpackInt(c, offset);
|
||||||
|
if(0x7f < o || o < -0x80) {
|
||||||
|
throw new MessageTypeException();
|
||||||
|
}
|
||||||
|
return (byte)o;
|
||||||
|
}
|
||||||
|
|
||||||
|
final short unpackShort(UnpackCursor c, int offset) throws IOException, MessageTypeException {
|
||||||
|
int o = unpackInt(c, offset);
|
||||||
|
if(0x7fff < o || o < -0x8000) {
|
||||||
|
throw new MessageTypeException();
|
||||||
|
}
|
||||||
|
return (short)o;
|
||||||
|
}
|
||||||
|
|
||||||
|
final int unpackInt(UnpackCursor c, int offset) throws IOException, MessageTypeException {
|
||||||
|
more(offset, 1);
|
||||||
|
int b = buffer[offset];
|
||||||
|
if((b & 0x80) == 0 || (b & 0xe0) == 0xe0) { // Fixnum
|
||||||
|
return (int)b;
|
||||||
|
}
|
||||||
|
switch(b & 0xff) {
|
||||||
|
case 0xcc: // unsigned int 8
|
||||||
|
more(offset, 2);
|
||||||
|
c.advance(2);
|
||||||
|
return (int)((short)buffer[offset+1] & 0xff);
|
||||||
|
case 0xcd: // unsigned int 16
|
||||||
|
more(offset, 3);
|
||||||
|
castBuffer.rewind();
|
||||||
|
castBuffer.put(buffer, offset+1, 2);
|
||||||
|
c.advance(3);
|
||||||
|
return (int)((int)castBuffer.getShort(0) & 0xffff);
|
||||||
|
case 0xce: // unsigned int 32
|
||||||
|
more(offset, 5);
|
||||||
|
castBuffer.rewind();
|
||||||
|
castBuffer.put(buffer, offset+1, 4);
|
||||||
|
{
|
||||||
|
int o = castBuffer.getInt(0);
|
||||||
|
if(o < 0) {
|
||||||
|
throw new MessageTypeException();
|
||||||
|
}
|
||||||
|
c.advance(5);
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
case 0xcf: // unsigned int 64
|
||||||
|
more(offset, 9);
|
||||||
|
castBuffer.rewind();
|
||||||
|
castBuffer.put(buffer, offset+1, 8);
|
||||||
|
{
|
||||||
|
long o = castBuffer.getLong(0);
|
||||||
|
if(o < 0 || o > 0x7fffffffL) {
|
||||||
|
throw new MessageTypeException();
|
||||||
|
}
|
||||||
|
c.advance(9);
|
||||||
|
return (int)o;
|
||||||
|
}
|
||||||
|
case 0xd0: // signed int 8
|
||||||
|
more(offset, 2);
|
||||||
|
c.advance(2);
|
||||||
|
return (int)buffer[offset+1];
|
||||||
|
case 0xd1: // signed int 16
|
||||||
|
more(offset, 3);
|
||||||
|
castBuffer.rewind();
|
||||||
|
castBuffer.put(buffer, offset+1, 2);
|
||||||
|
c.advance(3);
|
||||||
|
return (int)castBuffer.getShort(0);
|
||||||
|
case 0xd2: // signed int 32
|
||||||
|
more(offset, 4);
|
||||||
|
castBuffer.rewind();
|
||||||
|
castBuffer.put(buffer, offset+1, 4);
|
||||||
|
c.advance(4);
|
||||||
|
return (int)castBuffer.getInt(0);
|
||||||
|
case 0xd3: // signed int 64
|
||||||
|
more(offset, 9);
|
||||||
|
castBuffer.rewind();
|
||||||
|
castBuffer.put(buffer, offset+1, 8);
|
||||||
|
{
|
||||||
|
long o = castBuffer.getLong(0);
|
||||||
|
if(0x7fffffffL < o || o < -0x80000000L) {
|
||||||
|
throw new MessageTypeException();
|
||||||
|
}
|
||||||
|
c.advance(9);
|
||||||
|
return (int)o;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
throw new MessageTypeException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final long unpackLong(UnpackCursor c, int offset) throws IOException, MessageTypeException {
|
||||||
|
more(offset, 1);
|
||||||
|
int b = buffer[offset];
|
||||||
|
if((b & 0x80) == 0 || (b & 0xe0) == 0xe0) { // Fixnum
|
||||||
|
return (long)b;
|
||||||
|
}
|
||||||
|
switch(b & 0xff) {
|
||||||
|
case 0xcc: // unsigned int 8
|
||||||
|
more(offset, 2);
|
||||||
|
c.advance(2);
|
||||||
|
return (long)((short)buffer[offset+1] & 0xff);
|
||||||
|
case 0xcd: // unsigned int 16
|
||||||
|
more(offset, 3);
|
||||||
|
castBuffer.rewind();
|
||||||
|
castBuffer.put(buffer, offset+1, 2);
|
||||||
|
c.advance(3);
|
||||||
|
return (long)((int)castBuffer.getShort(0) & 0xffff);
|
||||||
|
case 0xce: // unsigned int 32
|
||||||
|
more(offset, 5);
|
||||||
|
castBuffer.rewind();
|
||||||
|
castBuffer.put(buffer, offset+1, 4);
|
||||||
|
c.advance(5);
|
||||||
|
return ((long)castBuffer.getInt(0) & 0xffffffffL);
|
||||||
|
case 0xcf: // unsigned int 64
|
||||||
|
more(offset, 9);
|
||||||
|
castBuffer.rewind();
|
||||||
|
castBuffer.put(buffer, offset+1, 8);
|
||||||
|
{
|
||||||
|
long o = castBuffer.getLong(0);
|
||||||
|
if(o < 0) {
|
||||||
|
// FIXME
|
||||||
|
throw new MessageTypeException("uint 64 bigger than 0x7fffffff is not supported");
|
||||||
|
}
|
||||||
|
c.advance(9);
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
case 0xd0: // signed int 8
|
||||||
|
more(offset, 2);
|
||||||
|
c.advance(2);
|
||||||
|
return (long)buffer[offset+1];
|
||||||
|
case 0xd1: // signed int 16
|
||||||
|
more(offset, 3);
|
||||||
|
castBuffer.rewind();
|
||||||
|
castBuffer.put(buffer, offset+1, 2);
|
||||||
|
c.advance(3);
|
||||||
|
return (long)castBuffer.getShort(0);
|
||||||
|
case 0xd2: // signed int 32
|
||||||
|
more(offset, 4);
|
||||||
|
castBuffer.rewind();
|
||||||
|
castBuffer.put(buffer, offset+1, 4);
|
||||||
|
c.advance(4);
|
||||||
|
return (long)castBuffer.getInt(0);
|
||||||
|
case 0xd3: // signed int 64
|
||||||
|
more(offset, 9);
|
||||||
|
castBuffer.rewind();
|
||||||
|
castBuffer.put(buffer, offset+1, 8);
|
||||||
|
c.advance(9);
|
||||||
|
return (long)castBuffer.getLong(0);
|
||||||
|
default:
|
||||||
|
throw new MessageTypeException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final float unpackFloat(UnpackCursor c, int offset) throws IOException, MessageTypeException {
|
||||||
|
more(offset, 1);
|
||||||
|
int b = buffer[offset];
|
||||||
|
switch(b & 0xff) {
|
||||||
|
case 0xca: // float
|
||||||
|
more(offset, 5);
|
||||||
|
castBuffer.rewind();
|
||||||
|
castBuffer.put(buffer, offset+1, 4);
|
||||||
|
c.advance(5);
|
||||||
|
return castBuffer.getFloat(0);
|
||||||
|
case 0xcb: // double
|
||||||
|
more(offset, 9);
|
||||||
|
castBuffer.rewind();
|
||||||
|
castBuffer.put(buffer, offset+1, 8);
|
||||||
|
c.advance(9);
|
||||||
|
// FIXME overflow check
|
||||||
|
return (float)castBuffer.getDouble(0);
|
||||||
|
default:
|
||||||
|
throw new MessageTypeException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final double unpackDouble(UnpackCursor c, int offset) throws IOException, MessageTypeException {
|
||||||
|
more(offset, 1);
|
||||||
|
int b = buffer[offset];
|
||||||
|
switch(b & 0xff) {
|
||||||
|
case 0xca: // float
|
||||||
|
more(offset, 5);
|
||||||
|
castBuffer.rewind();
|
||||||
|
castBuffer.put(buffer, offset+1, 4);
|
||||||
|
c.advance(5);
|
||||||
|
return (double)castBuffer.getFloat(0);
|
||||||
|
case 0xcb: // double
|
||||||
|
more(offset, 9);
|
||||||
|
castBuffer.rewind();
|
||||||
|
castBuffer.put(buffer, offset+1, 8);
|
||||||
|
c.advance(9);
|
||||||
|
return castBuffer.getDouble(0);
|
||||||
|
default:
|
||||||
|
throw new MessageTypeException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final Object unpackNull(UnpackCursor c, int offset) throws IOException, MessageTypeException {
|
||||||
|
more(offset, 1);
|
||||||
|
int b = buffer[offset] & 0xff;
|
||||||
|
if(b != 0xc0) { // nil
|
||||||
|
throw new MessageTypeException();
|
||||||
|
}
|
||||||
|
c.advance(1);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
final boolean unpackBoolean(UnpackCursor c, int offset) throws IOException, MessageTypeException {
|
||||||
|
more(offset, 1);
|
||||||
|
int b = buffer[offset] & 0xff;
|
||||||
|
if(b == 0xc2) { // false
|
||||||
|
c.advance(1);
|
||||||
|
return false;
|
||||||
|
} else if(b == 0xc3) { // true
|
||||||
|
c.advance(1);
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
throw new MessageTypeException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final int unpackArray(UnpackCursor c, int offset) throws IOException, MessageTypeException {
|
||||||
|
more(offset, 1);
|
||||||
|
int b = buffer[offset];
|
||||||
|
if((b & 0xf0) == 0x90) { // FixArray
|
||||||
|
c.advance(1);
|
||||||
|
return (int)(b & 0x0f);
|
||||||
|
}
|
||||||
|
switch(b & 0xff) {
|
||||||
|
case 0xdc: // array 16
|
||||||
|
more(offset, 3);
|
||||||
|
castBuffer.rewind();
|
||||||
|
castBuffer.put(buffer, offset+1, 2);
|
||||||
|
c.advance(3);
|
||||||
|
return (int)castBuffer.getShort(0) & 0xffff;
|
||||||
|
case 0xdd: // array 32
|
||||||
|
more(offset, 5);
|
||||||
|
castBuffer.rewind();
|
||||||
|
castBuffer.put(buffer, offset+1, 4);
|
||||||
|
c.advance(5);
|
||||||
|
// FIXME overflow check
|
||||||
|
return castBuffer.getInt(0) & 0x7fffffff;
|
||||||
|
default:
|
||||||
|
throw new MessageTypeException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final int unpackMap(UnpackCursor c, int offset) throws IOException, MessageTypeException {
|
||||||
|
more(offset, 1);
|
||||||
|
int b = buffer[offset];
|
||||||
|
if((b & 0xf0) == 0x80) { // FixMap
|
||||||
|
c.advance(1);
|
||||||
|
return (int)(b & 0x0f);
|
||||||
|
}
|
||||||
|
switch(b & 0xff) {
|
||||||
|
case 0xde: // map 16
|
||||||
|
more(offset, 3);
|
||||||
|
castBuffer.rewind();
|
||||||
|
castBuffer.put(buffer, offset+1, 2);
|
||||||
|
c.advance(3);
|
||||||
|
return (int)castBuffer.getShort(0) & 0xffff;
|
||||||
|
case 0xdf: // map 32
|
||||||
|
more(offset, 5);
|
||||||
|
castBuffer.rewind();
|
||||||
|
castBuffer.put(buffer, offset+1, 4);
|
||||||
|
c.advance(5);
|
||||||
|
// FIXME overflow check
|
||||||
|
return castBuffer.getInt(0) & 0x7fffffff;
|
||||||
|
default:
|
||||||
|
throw new MessageTypeException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final int unpackRaw(UnpackCursor c, int offset) throws IOException, MessageTypeException {
|
||||||
|
more(offset, 1);
|
||||||
|
int b = buffer[offset];
|
||||||
|
if((b & 0xe0) == 0xa0) { // FixRaw
|
||||||
|
c.advance(1);
|
||||||
|
return (int)(b & 0x0f);
|
||||||
|
}
|
||||||
|
switch(b & 0xff) {
|
||||||
|
case 0xda: // raw 16
|
||||||
|
more(offset, 3);
|
||||||
|
castBuffer.rewind();
|
||||||
|
castBuffer.put(buffer, offset+1, 2);
|
||||||
|
c.advance(3);
|
||||||
|
return (int)castBuffer.getShort(0) & 0xffff;
|
||||||
|
case 0xdb: // raw 32
|
||||||
|
more(offset, 5);
|
||||||
|
castBuffer.rewind();
|
||||||
|
castBuffer.put(buffer, offset+1, 4);
|
||||||
|
c.advance(5);
|
||||||
|
// FIXME overflow check
|
||||||
|
return castBuffer.getInt(0) & 0x7fffffff;
|
||||||
|
default:
|
||||||
|
throw new MessageTypeException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final byte[] unpackRawBody(UnpackCursor c, int offset, int length) throws IOException, MessageTypeException {
|
||||||
|
more(offset, length);
|
||||||
|
byte[] bytes = new byte[length];
|
||||||
|
System.arraycopy(buffer, offset, bytes, 0, length);
|
||||||
|
c.advance(length);
|
||||||
|
return bytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
final String unpackString(UnpackCursor c, int offset) throws IOException, MessageTypeException {
|
||||||
|
int length = unpackRaw(c, offset);
|
||||||
|
offset = c.getOffset();
|
||||||
|
more(offset, length);
|
||||||
|
String s;
|
||||||
|
try {
|
||||||
|
s = new String(buffer, offset, length, "UTF-8");
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new MessageTypeException();
|
||||||
|
}
|
||||||
|
c.advance(length);
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -17,7 +17,7 @@
|
|||||||
//
|
//
|
||||||
package org.msgpack;
|
package org.msgpack;
|
||||||
|
|
||||||
public interface MessageMergeable {
|
public interface MessageConvertable {
|
||||||
public void messageMerge(Object obj) throws MessageTypeException;
|
public void messageConvert(Object obj) throws MessageTypeException;
|
||||||
}
|
}
|
||||||
|
|
@ -17,9 +17,7 @@
|
|||||||
//
|
//
|
||||||
package org.msgpack;
|
package org.msgpack;
|
||||||
|
|
||||||
import java.io.IOException;
|
public class MessageTypeException extends RuntimeException {
|
||||||
|
|
||||||
public class MessageTypeException extends IOException {
|
|
||||||
public MessageTypeException() { }
|
public MessageTypeException() { }
|
||||||
|
|
||||||
public MessageTypeException(String s) {
|
public MessageTypeException(String s) {
|
||||||
|
25
java/src/main/java/org/msgpack/MessageUnpackable.java
Normal file
25
java/src/main/java/org/msgpack/MessageUnpackable.java
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
//
|
||||||
|
// MessagePack for Java
|
||||||
|
//
|
||||||
|
// Copyright (C) 2009-2010 FURUHASHI Sadayuki
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
//
|
||||||
|
package org.msgpack;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
public interface MessageUnpackable {
|
||||||
|
public void messageUnpack(Unpacker pk) throws IOException, MessageTypeException;
|
||||||
|
}
|
||||||
|
|
@ -401,7 +401,7 @@ public class Packer {
|
|||||||
} else if(o instanceof Double) {
|
} else if(o instanceof Double) {
|
||||||
return packDouble((Double)o);
|
return packDouble((Double)o);
|
||||||
} else {
|
} else {
|
||||||
throw new IOException("unknown object "+o+" ("+o.getClass()+")");
|
throw new MessageTypeException("unknown object "+o+" ("+o.getClass()+")");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,82 +0,0 @@
|
|||||||
//
|
|
||||||
// MessagePack for Java
|
|
||||||
//
|
|
||||||
// Copyright (C) 2009-2010 FURUHASHI Sadayuki
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
//
|
|
||||||
package org.msgpack;
|
|
||||||
|
|
||||||
import java.lang.Iterable;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import org.msgpack.impl.UnpackerImpl;
|
|
||||||
|
|
||||||
public class UnbufferedUnpacker extends UnpackerImpl {
|
|
||||||
private int offset;
|
|
||||||
private boolean finished;
|
|
||||||
private Object data;
|
|
||||||
|
|
||||||
public UnbufferedUnpacker() {
|
|
||||||
super();
|
|
||||||
this.offset = 0;
|
|
||||||
this.finished = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public UnbufferedUnpacker useSchema(Schema s) {
|
|
||||||
super.setSchema(s);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Object getData() {
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isFinished() {
|
|
||||||
return finished;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void reset() {
|
|
||||||
super.reset();
|
|
||||||
this.offset = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int getOffset() {
|
|
||||||
return offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setOffset(int offset) {
|
|
||||||
this.offset = offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int execute(byte[] buffer) throws UnpackException {
|
|
||||||
return execute(buffer, 0, buffer.length);
|
|
||||||
}
|
|
||||||
|
|
||||||
// FIXME
|
|
||||||
public int execute(byte[] buffer, int offset, int length) throws UnpackException
|
|
||||||
{
|
|
||||||
int noffset = super.execute(buffer, offset + this.offset, length);
|
|
||||||
this.offset = noffset - offset;
|
|
||||||
if(super.isFinished()) {
|
|
||||||
this.data = super.getData();
|
|
||||||
this.finished = true;
|
|
||||||
super.reset();
|
|
||||||
} else {
|
|
||||||
this.finished = false;
|
|
||||||
}
|
|
||||||
return noffset;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
96
java/src/main/java/org/msgpack/UnpackCursor.java
Normal file
96
java/src/main/java/org/msgpack/UnpackCursor.java
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
//
|
||||||
|
// MessagePack for Java
|
||||||
|
//
|
||||||
|
// Copyright (C) 2009-2010 FURUHASHI Sadayuki
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
//
|
||||||
|
package org.msgpack;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
public class UnpackCursor {
|
||||||
|
private Unpacker pac;
|
||||||
|
private int offset;
|
||||||
|
|
||||||
|
UnpackCursor(Unpacker pac, int offset)
|
||||||
|
{
|
||||||
|
this.pac = pac;
|
||||||
|
this.offset = offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
final void advance(int length) {
|
||||||
|
offset += length;
|
||||||
|
}
|
||||||
|
|
||||||
|
final int getOffset() {
|
||||||
|
return offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte unpackByte() throws IOException, MessageTypeException {
|
||||||
|
return pac.impl.unpackByte(this, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
public short unpackShort() throws IOException, MessageTypeException {
|
||||||
|
return pac.impl.unpackShort(this, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int unpackInt() throws IOException, MessageTypeException {
|
||||||
|
return pac.impl.unpackInt(this, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
public long unpackLong() throws IOException, MessageTypeException {
|
||||||
|
return pac.impl.unpackLong(this, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
public float unpackFloat() throws IOException, MessageTypeException {
|
||||||
|
return pac.impl.unpackFloat(this, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
public double unpackDouble() throws IOException, MessageTypeException {
|
||||||
|
return pac.impl.unpackDouble(this, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object unpackNull() throws IOException, MessageTypeException {
|
||||||
|
return pac.impl.unpackNull(this, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean unpackBoolean() throws IOException, MessageTypeException {
|
||||||
|
return pac.impl.unpackBoolean(this, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int unpackArray() throws IOException, MessageTypeException {
|
||||||
|
return pac.impl.unpackArray(this, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int unpackMap() throws IOException, MessageTypeException {
|
||||||
|
return pac.impl.unpackMap(this, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int unpackRaw() throws IOException, MessageTypeException {
|
||||||
|
return pac.impl.unpackRaw(this, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] unpackRawBody(int length) throws IOException, MessageTypeException {
|
||||||
|
return pac.impl.unpackRawBody(this, offset, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String unpackString() throws IOException, MessageTypeException {
|
||||||
|
return pac.impl.unpackString(this, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void commit() {
|
||||||
|
pac.setOffset(offset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -21,41 +21,27 @@ import java.io.IOException;
|
|||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.NoSuchElementException;
|
import java.util.NoSuchElementException;
|
||||||
|
|
||||||
public class UnpackIterator implements Iterator<Object> {
|
public class UnpackIterator extends UnpackResult implements Iterator<Object> {
|
||||||
private Unpacker pac;
|
private Unpacker pac;
|
||||||
private boolean have;
|
|
||||||
private Object data;
|
|
||||||
|
|
||||||
UnpackIterator(Unpacker pac) {
|
UnpackIterator(Unpacker pac) {
|
||||||
|
super();
|
||||||
this.pac = pac;
|
this.pac = pac;
|
||||||
this.have = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasNext() {
|
public boolean hasNext() {
|
||||||
if(have) { return true; }
|
|
||||||
try {
|
try {
|
||||||
while(true) {
|
return pac.next(this);
|
||||||
if(pac.execute()) {
|
|
||||||
data = pac.getData();
|
|
||||||
pac.reset();
|
|
||||||
have = true;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!pac.fill()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object next() {
|
public Object next() {
|
||||||
if(!have && !hasNext()) {
|
if(!finished && !hasNext()) {
|
||||||
throw new NoSuchElementException();
|
throw new NoSuchElementException();
|
||||||
}
|
}
|
||||||
have = false;
|
finished = false;
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
42
java/src/main/java/org/msgpack/UnpackResult.java
Normal file
42
java/src/main/java/org/msgpack/UnpackResult.java
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
//
|
||||||
|
// MessagePack for Java
|
||||||
|
//
|
||||||
|
// Copyright (C) 2009-2010 FURUHASHI Sadayuki
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
//
|
||||||
|
package org.msgpack;
|
||||||
|
|
||||||
|
public class UnpackResult {
|
||||||
|
protected boolean finished = false;
|
||||||
|
protected Object data = null;
|
||||||
|
|
||||||
|
public boolean isFinished() {
|
||||||
|
return finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object getData() {
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void reset() {
|
||||||
|
finished = false;
|
||||||
|
data = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
void done(Object obj) {
|
||||||
|
finished = true;
|
||||||
|
data = obj;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -22,18 +22,43 @@ import java.io.InputStream;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import org.msgpack.impl.UnpackerImpl;
|
|
||||||
|
|
||||||
public class Unpacker extends UnpackerImpl implements Iterable<Object> {
|
public class Unpacker implements Iterable<Object> {
|
||||||
|
|
||||||
public static final int DEFAULT_BUFFER_SIZE = 32*1024;
|
// buffer:
|
||||||
|
// +---------------------------------------------+
|
||||||
|
// | [object] | [obje| unparsed ... | unused ...|
|
||||||
|
// +---------------------------------------------+
|
||||||
|
// ^ parsed
|
||||||
|
// ^ offset
|
||||||
|
// ^ filled
|
||||||
|
// ^ buffer.length
|
||||||
|
|
||||||
|
private static final int DEFAULT_BUFFER_SIZE = 32*1024;
|
||||||
|
|
||||||
|
protected int offset;
|
||||||
|
protected int parsed;
|
||||||
|
protected int bufferReserveSize;
|
||||||
|
protected InputStream stream;
|
||||||
|
|
||||||
|
class BufferedUnpackerMixin extends BufferedUnpackerImpl {
|
||||||
|
boolean fill() throws IOException {
|
||||||
|
if(stream == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
reserveBuffer(bufferReserveSize);
|
||||||
|
int rl = stream.read(buffer, filled, buffer.length - filled);
|
||||||
|
// equals: stream.read(getBuffer(), getBufferOffset(), getBufferCapacity());
|
||||||
|
if(rl <= 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
bufferConsumed(rl);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
final BufferedUnpackerMixin impl = new BufferedUnpackerMixin();
|
||||||
|
|
||||||
private int used;
|
|
||||||
private int offset;
|
|
||||||
private int parsed;
|
|
||||||
private byte[] buffer;
|
|
||||||
private int bufferReserveSize;
|
|
||||||
private InputStream stream;
|
|
||||||
|
|
||||||
public Unpacker() {
|
public Unpacker() {
|
||||||
this(DEFAULT_BUFFER_SIZE);
|
this(DEFAULT_BUFFER_SIZE);
|
||||||
@ -48,67 +73,31 @@ public class Unpacker extends UnpackerImpl implements Iterable<Object> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Unpacker(InputStream stream, int bufferReserveSize) {
|
public Unpacker(InputStream stream, int bufferReserveSize) {
|
||||||
super();
|
|
||||||
this.used = 0;
|
|
||||||
this.offset = 0;
|
this.offset = 0;
|
||||||
this.parsed = 0;
|
this.parsed = 0;
|
||||||
this.buffer = new byte[bufferReserveSize];
|
|
||||||
this.bufferReserveSize = bufferReserveSize/2;
|
this.bufferReserveSize = bufferReserveSize/2;
|
||||||
this.stream = stream;
|
this.stream = stream;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Unpacker useSchema(Schema s) {
|
public Unpacker useSchema(Schema s) {
|
||||||
super.setSchema(s);
|
impl.setSchema(s);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void reserveBuffer(int size) {
|
|
||||||
if(buffer.length - used >= size) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
if(used == parsed && buffer.length >= size) {
|
|
||||||
// rewind buffer
|
|
||||||
used = 0;
|
|
||||||
offset = 0;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
int nextSize = buffer.length * 2;
|
public InputStream getStream() {
|
||||||
while(nextSize < size + used) {
|
return this.stream;
|
||||||
nextSize *= 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
byte[] tmp = new byte[nextSize];
|
|
||||||
System.arraycopy(buffer, offset, tmp, 0, used - offset);
|
|
||||||
|
|
||||||
buffer = tmp;
|
|
||||||
used -= offset;
|
|
||||||
offset = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] getBuffer() {
|
public void setStream(InputStream stream) {
|
||||||
return buffer;
|
this.stream = stream;
|
||||||
}
|
|
||||||
|
|
||||||
public int getBufferOffset() {
|
|
||||||
return used;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getBufferCapacity() {
|
|
||||||
return buffer.length - used;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void bufferConsumed(int size) {
|
|
||||||
used += size;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void feed(ByteBuffer buffer) {
|
public void feed(ByteBuffer buffer) {
|
||||||
int length = buffer.remaining();
|
int length = buffer.remaining();
|
||||||
if (length == 0) return;
|
if (length == 0) return;
|
||||||
reserveBuffer(length);
|
reserveBuffer(length);
|
||||||
buffer.get(this.buffer, this.offset, length);
|
buffer.get(impl.buffer, this.offset, length);
|
||||||
bufferConsumed(length);
|
bufferConsumed(length);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -118,48 +107,116 @@ public class Unpacker extends UnpackerImpl implements Iterable<Object> {
|
|||||||
|
|
||||||
public void feed(byte[] buffer, int offset, int length) {
|
public void feed(byte[] buffer, int offset, int length) {
|
||||||
reserveBuffer(length);
|
reserveBuffer(length);
|
||||||
System.arraycopy(buffer, offset, this.buffer, this.offset, length);
|
System.arraycopy(buffer, offset, impl.buffer, this.offset, length);
|
||||||
bufferConsumed(length);
|
bufferConsumed(length);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean fill() throws IOException {
|
public boolean fill() throws IOException {
|
||||||
if(stream == null) {
|
return impl.fill();
|
||||||
return false;
|
|
||||||
}
|
|
||||||
reserveBuffer(bufferReserveSize);
|
|
||||||
int rl = stream.read(getBuffer(), getBufferOffset(), getBufferCapacity());
|
|
||||||
if(rl <= 0) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
bufferConsumed(rl);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Iterator<Object> iterator() {
|
public Iterator<Object> iterator() {
|
||||||
return new UnpackIterator(this);
|
return new UnpackIterator(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public UnpackResult next() throws IOException, UnpackException {
|
||||||
|
UnpackResult result = new UnpackResult();
|
||||||
|
this.offset = impl.next(this.offset, result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean next(UnpackResult result) throws IOException, UnpackException {
|
||||||
|
this.offset = impl.next(this.offset, result);
|
||||||
|
return result.isFinished();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void reserveBuffer(int require) {
|
||||||
|
if(impl.buffer == null) {
|
||||||
|
int nextSize = (bufferReserveSize < require) ? require : bufferReserveSize;
|
||||||
|
impl.buffer = new byte[nextSize];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(impl.buffer.length - impl.filled >= require) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int nextSize = impl.buffer.length * 2;
|
||||||
|
int notParsed = impl.filled - this.offset;
|
||||||
|
while(nextSize < require + notParsed) {
|
||||||
|
nextSize *= 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
byte[] tmp = new byte[nextSize];
|
||||||
|
System.arraycopy(impl.buffer, this.offset, tmp, 0, impl.filled - this.offset);
|
||||||
|
|
||||||
|
impl.buffer = tmp;
|
||||||
|
impl.filled = notParsed;
|
||||||
|
this.offset = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] getBuffer() {
|
||||||
|
return impl.buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getBufferOffset() {
|
||||||
|
return impl.filled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getBufferCapacity() {
|
||||||
|
return impl.buffer.length - impl.filled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void bufferConsumed(int size) {
|
||||||
|
impl.filled += size;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean execute() throws UnpackException {
|
public boolean execute() throws UnpackException {
|
||||||
int noffset = super.execute(buffer, offset, used);
|
int noffset = impl.execute(impl.buffer, offset, impl.filled);
|
||||||
if(noffset <= offset) {
|
if(noffset <= offset) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
parsed += noffset - offset;
|
parsed += noffset - offset;
|
||||||
offset = noffset;
|
offset = noffset;
|
||||||
return super.isFinished();
|
return impl.isFinished();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public int execute(byte[] buffer) throws UnpackException {
|
||||||
|
return execute(buffer, 0, buffer.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int execute(byte[] buffer, int offset, int length) throws UnpackException {
|
||||||
|
int noffset = impl.execute(buffer, offset + this.offset, length);
|
||||||
|
this.offset = noffset - offset;
|
||||||
|
if(impl.isFinished()) {
|
||||||
|
impl.resetState();
|
||||||
|
}
|
||||||
|
return noffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isFinished() {
|
||||||
|
return impl.isFinished();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object getData() {
|
public Object getData() {
|
||||||
return super.getData();
|
return impl.getData();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void reset() {
|
public void reset() {
|
||||||
super.reset();
|
impl.reset();
|
||||||
parsed = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public UnpackCursor begin()
|
||||||
|
{
|
||||||
|
return new UnpackCursor(this, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public int getMessageSize() {
|
public int getMessageSize() {
|
||||||
return parsed - offset + used;
|
return parsed - offset + impl.filled;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getParsedSize() {
|
public int getParsedSize() {
|
||||||
@ -167,7 +224,7 @@ public class Unpacker extends UnpackerImpl implements Iterable<Object> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public int getNonParsedSize() {
|
public int getNonParsedSize() {
|
||||||
return used - offset;
|
return impl.filled - offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void skipNonparsedBuffer(int size) {
|
public void skipNonparsedBuffer(int size) {
|
||||||
@ -175,80 +232,14 @@ public class Unpacker extends UnpackerImpl implements Iterable<Object> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void removeNonparsedBuffer() {
|
public void removeNonparsedBuffer() {
|
||||||
used = offset;
|
impl.filled = offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
public static class Context {
|
|
||||||
private boolean finished;
|
|
||||||
private Object data;
|
|
||||||
private int offset;
|
|
||||||
private UnpackerImpl impl;
|
|
||||||
|
|
||||||
public Context()
|
void setOffset(int offset)
|
||||||
{
|
|
||||||
this.finished = false;
|
|
||||||
this.impl = new UnpackerImpl();
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isFinished()
|
|
||||||
{
|
|
||||||
return finished;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Object getData()
|
|
||||||
{
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
int getOffset()
|
|
||||||
{
|
|
||||||
return offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setFinished(boolean finished)
|
|
||||||
{
|
|
||||||
this.finished = finished;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setData(Object data)
|
|
||||||
{
|
|
||||||
this.data = data;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setOffset(int offset)
|
|
||||||
{
|
|
||||||
this.offset = offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
UnpackerImpl getImpl()
|
|
||||||
{
|
|
||||||
return impl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int unpack(Context ctx, byte[] buffer) throws UnpackException
|
|
||||||
{
|
{
|
||||||
return unpack(ctx, buffer, 0, buffer.length);
|
parsed += offset - this.offset;
|
||||||
|
this.offset = offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int unpack(Context ctx, byte[] buffer, int offset, int length) throws UnpackException
|
|
||||||
{
|
|
||||||
UnpackerImpl impl = ctx.getImpl();
|
|
||||||
int noffset = impl.execute(buffer, offset + ctx.getOffset(), length);
|
|
||||||
ctx.setOffset(noffset - offset);
|
|
||||||
if(impl.isFinished()) {
|
|
||||||
ctx.setData(impl.getData());
|
|
||||||
ctx.setFinished(false);
|
|
||||||
impl.reset();
|
|
||||||
} else {
|
|
||||||
ctx.setData(null);
|
|
||||||
ctx.setFinished(true);
|
|
||||||
}
|
|
||||||
int parsed = noffset - offset;
|
|
||||||
ctx.setOffset(parsed);
|
|
||||||
return noffset;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
//
|
//
|
||||||
package org.msgpack.impl;
|
package org.msgpack;
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
//import java.math.BigInteger;
|
//import java.math.BigInteger;
|
||||||
@ -47,7 +47,7 @@ public class UnpackerImpl {
|
|||||||
static final int CT_MAP_KEY = 0x01;
|
static final int CT_MAP_KEY = 0x01;
|
||||||
static final int CT_MAP_VALUE = 0x02;
|
static final int CT_MAP_VALUE = 0x02;
|
||||||
|
|
||||||
static final int MAX_STACK_SIZE = 16;
|
static final int MAX_STACK_SIZE = 32;
|
||||||
|
|
||||||
private int cs;
|
private int cs;
|
||||||
private int trail;
|
private int trail;
|
||||||
@ -67,41 +67,45 @@ public class UnpackerImpl {
|
|||||||
private static final Schema GENERIC_SCHEMA = new GenericSchema();
|
private static final Schema GENERIC_SCHEMA = new GenericSchema();
|
||||||
private Schema rootSchema;
|
private Schema rootSchema;
|
||||||
|
|
||||||
protected UnpackerImpl()
|
public UnpackerImpl()
|
||||||
{
|
{
|
||||||
setSchema(GENERIC_SCHEMA);
|
setSchema(GENERIC_SCHEMA);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void setSchema(Schema schema)
|
public void setSchema(Schema schema)
|
||||||
{
|
{
|
||||||
this.rootSchema = schema;
|
this.rootSchema = schema;
|
||||||
reset();
|
reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Object getData()
|
public final Object getData()
|
||||||
{
|
{
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean isFinished()
|
public final boolean isFinished()
|
||||||
{
|
{
|
||||||
return finished;
|
return finished;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void reset()
|
public final void resetState() {
|
||||||
{
|
|
||||||
cs = CS_HEADER;
|
cs = CS_HEADER;
|
||||||
top = -1;
|
top = -1;
|
||||||
finished = false;
|
|
||||||
data = null;
|
|
||||||
top_ct = 0;
|
top_ct = 0;
|
||||||
top_count = 0;
|
top_count = 0;
|
||||||
top_obj = null;
|
top_obj = null;
|
||||||
top_schema = rootSchema;
|
top_schema = rootSchema;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public final void reset()
|
||||||
|
{
|
||||||
|
resetState();
|
||||||
|
finished = false;
|
||||||
|
data = null;
|
||||||
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
protected int execute(byte[] src, int off, int length) throws UnpackException
|
public final int execute(byte[] src, int off, int length) throws UnpackException
|
||||||
{
|
{
|
||||||
if(off >= length) { return off; }
|
if(off >= length) { return off; }
|
||||||
|
|
154
java/src/test/java/org/msgpack/TestDirectConversion.java
Normal file
154
java/src/test/java/org/msgpack/TestDirectConversion.java
Normal file
@ -0,0 +1,154 @@
|
|||||||
|
package org.msgpack;
|
||||||
|
|
||||||
|
import org.msgpack.*;
|
||||||
|
import java.io.*;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
public class TestDirectConversion {
|
||||||
|
private UnpackCursor prepareCursor(ByteArrayOutputStream out) {
|
||||||
|
ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
|
||||||
|
Unpacker upk = new Unpacker(in);
|
||||||
|
return upk.begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testInt() throws Exception {
|
||||||
|
testInt(0);
|
||||||
|
testInt(-1);
|
||||||
|
testInt(1);
|
||||||
|
testInt(Integer.MIN_VALUE);
|
||||||
|
testInt(Integer.MAX_VALUE);
|
||||||
|
Random rand = new Random();
|
||||||
|
for (int i = 0; i < 1000; i++)
|
||||||
|
testInt(rand.nextInt());
|
||||||
|
}
|
||||||
|
public void testInt(int val) throws Exception {
|
||||||
|
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||||
|
new Packer(out).pack(val);
|
||||||
|
UnpackCursor c = prepareCursor(out);
|
||||||
|
assertEquals(val, c.unpackInt());
|
||||||
|
c.commit();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFloat() throws Exception {
|
||||||
|
testFloat((float)0.0);
|
||||||
|
testFloat((float)-0.0);
|
||||||
|
testFloat((float)1.0);
|
||||||
|
testFloat((float)-1.0);
|
||||||
|
testFloat((float)Float.MAX_VALUE);
|
||||||
|
testFloat((float)Float.MIN_VALUE);
|
||||||
|
testFloat((float)Float.NaN);
|
||||||
|
testFloat((float)Float.NEGATIVE_INFINITY);
|
||||||
|
testFloat((float)Float.POSITIVE_INFINITY);
|
||||||
|
Random rand = new Random();
|
||||||
|
for (int i = 0; i < 1000; i++)
|
||||||
|
testFloat(rand.nextFloat());
|
||||||
|
}
|
||||||
|
public void testFloat(float val) throws Exception {
|
||||||
|
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||||
|
new Packer(out).pack(val);
|
||||||
|
UnpackCursor c = prepareCursor(out);
|
||||||
|
float f = c.unpackFloat();
|
||||||
|
if(Float.isNaN(val)) {
|
||||||
|
assertTrue(Float.isNaN(f));
|
||||||
|
} else {
|
||||||
|
assertEquals(val, f, 10e-10);
|
||||||
|
}
|
||||||
|
c.commit();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDouble() throws Exception {
|
||||||
|
testDouble((double)0.0);
|
||||||
|
testDouble((double)-0.0);
|
||||||
|
testDouble((double)1.0);
|
||||||
|
testDouble((double)-1.0);
|
||||||
|
testDouble((double)Double.MAX_VALUE);
|
||||||
|
testDouble((double)Double.MIN_VALUE);
|
||||||
|
testDouble((double)Double.NaN);
|
||||||
|
testDouble((double)Double.NEGATIVE_INFINITY);
|
||||||
|
testDouble((double)Double.POSITIVE_INFINITY);
|
||||||
|
Random rand = new Random();
|
||||||
|
for (int i = 0; i < 1000; i++)
|
||||||
|
testDouble(rand.nextDouble());
|
||||||
|
}
|
||||||
|
public void testDouble(double val) throws Exception {
|
||||||
|
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||||
|
new Packer(out).pack(val);
|
||||||
|
UnpackCursor c = prepareCursor(out);
|
||||||
|
double f = c.unpackDouble();
|
||||||
|
if(Double.isNaN(val)) {
|
||||||
|
assertTrue(Double.isNaN(f));
|
||||||
|
} else {
|
||||||
|
assertEquals(val, f, 10e-10);
|
||||||
|
}
|
||||||
|
c.commit();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testNil() throws Exception {
|
||||||
|
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||||
|
new Packer(out).packNil();
|
||||||
|
UnpackCursor c = prepareCursor(out);
|
||||||
|
assertEquals(null, c.unpackNull());
|
||||||
|
c.commit();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testBoolean() throws Exception {
|
||||||
|
testBoolean(false);
|
||||||
|
testBoolean(true);
|
||||||
|
}
|
||||||
|
public void testBoolean(boolean val) throws Exception {
|
||||||
|
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||||
|
new Packer(out).pack(val);
|
||||||
|
UnpackCursor c = prepareCursor(out);
|
||||||
|
assertEquals(val, c.unpackBoolean());
|
||||||
|
c.commit();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testString() throws Exception {
|
||||||
|
testString("");
|
||||||
|
testString("a");
|
||||||
|
testString("ab");
|
||||||
|
testString("abc");
|
||||||
|
// small size string
|
||||||
|
for (int i = 0; i < 100; i++) {
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
int len = (int)Math.random() % 31 + 1;
|
||||||
|
for (int j = 0; j < len; j++)
|
||||||
|
sb.append('a' + ((int)Math.random()) & 26);
|
||||||
|
testString(sb.toString());
|
||||||
|
}
|
||||||
|
// medium size string
|
||||||
|
for (int i = 0; i < 100; i++) {
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
int len = (int)Math.random() % 100 + (1 << 15);
|
||||||
|
for (int j = 0; j < len; j++)
|
||||||
|
sb.append('a' + ((int)Math.random()) & 26);
|
||||||
|
testString(sb.toString());
|
||||||
|
}
|
||||||
|
// large size string
|
||||||
|
for (int i = 0; i < 10; i++) {
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
int len = (int)Math.random() % 100 + (1 << 31);
|
||||||
|
for (int j = 0; j < len; j++)
|
||||||
|
sb.append('a' + ((int)Math.random()) & 26);
|
||||||
|
testString(sb.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public void testString(String val) throws Exception {
|
||||||
|
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||||
|
new Packer(out).pack(val);
|
||||||
|
UnpackCursor c = prepareCursor(out);
|
||||||
|
assertEquals(val, c.unpackString());
|
||||||
|
c.commit();
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME container types
|
||||||
|
};
|
Loading…
x
Reference in New Issue
Block a user