This commit is contained in:
wentch
2015-12-30 11:04:34 +08:00
parent 11da4b6fef
commit d12efbb2de
3 changed files with 198 additions and 25 deletions

View File

@@ -0,0 +1,164 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.redkale.convert.bson;
import java.nio.*;
import org.redkale.convert.*;
import static org.redkale.convert.Reader.SIGN_NULL;
import org.redkale.util.*;
/**
*
* @author zhangjx
*/
public final class BsonByteBufferReader extends BsonReader {
private ByteBuffer[] buffers;
private int currentIndex = 0;
private ByteBuffer currentBuffer;
protected BsonByteBufferReader(ByteBuffer... buffers) {
this.buffers = buffers;
this.currentBuffer = buffers[currentIndex];
}
@Override
protected boolean recycle() {
super.recycle(); // this.position 初始化值为-1
this.currentIndex = 0;
this.currentBuffer = null;
this.buffers = null;
return false;
}
@Override
protected byte currentByte() {
return currentBuffer.get(currentBuffer.position());
}
/**
* 判断下一个非空白字节是否为[
*
* @return
*/
@Override
public int readArrayB() {
short bt = readShort();
if (bt == Reader.SIGN_NULL) return bt;
short lt = readShort();
return (bt & 0xffff) << 16 | (lt & 0xffff);
}
//------------------------------------------------------------
@Override
public boolean readBoolean() {
return readByte() == 1;
}
@Override
public byte readByte() {
if (this.currentBuffer.hasRemaining()) {
this.position++;
return this.currentBuffer.get();
}
for (;;) {
this.currentBuffer = this.buffers[++this.currentIndex];
if (this.currentBuffer.hasRemaining()) {
this.position++;
return this.currentBuffer.get();
}
}
}
@Override
public char readChar() {
int remain = this.currentBuffer.remaining();
if (remain >= 2) {
this.position += 2;
return this.currentBuffer.getChar();
}
return (char) ((0xff00 & (readByte() << 8)) | (0xff & readByte()));
}
@Override
public short readShort() {
int remain = this.currentBuffer.remaining();
if (remain >= 2) {
this.position += 2;
return this.currentBuffer.getShort();
}
return (short) ((0xff00 & (readByte() << 8)) | (0xff & readByte()));
}
@Override
public int readInt() {
int remain = this.currentBuffer.remaining();
if (remain >= 4) {
this.position += 4;
return this.currentBuffer.getInt();
}
return ((readByte() & 0xff) << 24) | ((readByte() & 0xff) << 16) | ((readByte() & 0xff) << 8) | (readByte() & 0xff);
}
@Override
public long readLong() {
int remain = this.currentBuffer.remaining();
if (remain >= 8) {
this.position += 8;
return this.currentBuffer.getLong();
}
return ((((long) readByte() & 0xff) << 56)
| (((long) readByte() & 0xff) << 48)
| (((long) readByte() & 0xff) << 40)
| (((long) readByte() & 0xff) << 32)
| (((long) readByte() & 0xff) << 24)
| (((long) readByte() & 0xff) << 16)
| (((long) readByte() & 0xff) << 8)
| (((long) readByte() & 0xff)));
}
protected byte[] read(final int len) {
byte[] bs = new byte[len];
read(bs, 0);
return bs;
}
protected void read(final byte[] bs, final int pos) {
int remain = this.currentBuffer.remaining();
if (remain < 1) {
this.currentBuffer = this.buffers[++this.currentIndex];
read(bs, pos);
return;
}
int len = bs.length - pos;
if (remain >= len) {
this.position += len;
this.currentBuffer.get(bs, pos, len);
return;
}
this.currentBuffer.get(bs, pos, remain);
this.position += remain;
this.currentBuffer = this.buffers[++this.currentIndex];
read(bs, pos + remain);
}
@Override
public String readSmallString() {
int len = 0xff & readByte();
if (len == 0) return "";
return new String(read(len));
}
@Override
public String readString() {
int len = readInt();
if (len == SIGN_NULL) return null;
if (len == 0) return "";
return new String(Utility.decodeUTF8(read(len)));
}
}

View File

@@ -12,22 +12,22 @@ import org.redkale.convert.*;
import org.redkale.util.*;
/**
* BSON协议格式:
* 1). 基本数据类型: 直接转换成byte[]
* 2). SmallString(无特殊字符且长度小于256的字符串): length(1 byte) + byte[](utf8); 通常用于类名、字段名、枚举。
* 3). String: length(4 bytes) + byte[](utf8);
* 4). 数组: length(4 bytes) + byte[]...
* 5). Object:
* 1. realclass (SmallString) (如果指定格式化的class与实体对象的class不一致才会有该值)
* 2. 空字符串(SmallString)
* 3. SIGN_OBJECTB 标记位值固定为0xBB (short)
* 4. 循环字段值:
* 4.1 SIGN_HASNEXT 标记位值固定为1 (byte)
* 4.2 字段类型; 1-9为基本类型&字符串; 101-109为基本类型&字符串的数组; 127为Object
* 4.3 字段名 (SmallString)
* 4.4 字段的值Object
* 5. SIGN_NONEXT 标记位值固定为0 (byte)
* 6. SIGN_OBJECTE 标记位值固定为0xEE (short)
* BSON协议格式:
* 1). 基本数据类型: 直接转换成byte[]
* 2). SmallString(无特殊字符且长度小于256的字符串): length(1 byte) + byte[](utf8); 通常用于类名、字段名、枚举。
* 3). String: length(4 bytes) + byte[](utf8);
* 4). 数组: length(4 bytes) + byte[]...
* 5). Object:
* 1. realclass (SmallString) (如果指定格式化的class与实体对象的class不一致才会有该值)
* 2. 空字符串(SmallString)
* 3. SIGN_OBJECTB 标记位值固定为0xBB (short)
* 4. 循环字段值:
* 4.1 SIGN_HASNEXT 标记位值固定为1 (byte)
* 4.2 字段类型; 1-9为基本类型&字符串; 101-109为基本类型&字符串的数组; 127为Object
* 4.3 字段名 (SmallString)
* 4.4 字段的值Object
* 5. SIGN_NONEXT 标记位值固定为0 (byte)
* 6. SIGN_OBJECTE 标记位值固定为0xEE (short)
*
* @see http://www.redkale.org
* @author zhangjx
@@ -80,6 +80,11 @@ public final class BsonConvert extends Convert<BsonReader, BsonWriter> {
return rs;
}
public <T> T convertFrom(final Type type, final ByteBuffer... buffers) {
if (type == null || buffers.length < 1) return null;
return (T) factory.loadDecoder(type).convertFrom(new BsonByteBufferReader(buffers));
}
public <T> T convertFrom(final BsonReader in, final Type type) {
if (type == null) return null;
@SuppressWarnings("unchecked")

View File

@@ -159,24 +159,28 @@ public class BsonReader implements Reader {
*
*/
@Override
public int readObjectB() {
public final int readObjectB() {
short bt = readShort();
if (bt == Reader.SIGN_NULL) return bt;
if (bt != SIGN_OBJECTB) {
throw new ConvertException("a bson object must begin with " + (SIGN_OBJECTB)
+ " (position = " + position + ") but '" + this.content[this.position] + "'");
+ " (position = " + position + ") but '" + currentByte() + "'");
}
return bt;
}
@Override
public void readObjectE() {
public final void readObjectE() {
if (readShort() != SIGN_OBJECTE) {
throw new ConvertException("a bson object must end with " + (SIGN_OBJECTE)
+ " (position = " + position + ") but '" + this.content[this.position] + "'");
+ " (position = " + position + ") but '" + currentByte() + "'");
}
}
protected byte currentByte() {
return this.content[this.position];
}
@Override
public final int readMapB() {
return readArrayB();
@@ -288,17 +292,17 @@ public class BsonReader implements Reader {
}
@Override
public float readFloat() {
public final float readFloat() {
return Float.intBitsToFloat(readInt());
}
@Override
public double readDouble() {
public final double readDouble() {
return Double.longBitsToDouble(readLong());
}
@Override
public String readClassName() {
public final String readClassName() {
return readSmallString();
}
@@ -307,7 +311,7 @@ public class BsonReader implements Reader {
int len = 0xff & readByte();
if (len == 0) return "";
String value = new String(content, ++this.position, len);
this.position += len - 1;
this.position += len - 1; //上一行已经++this.position所以此处要-1
return value;
}
@@ -317,7 +321,7 @@ public class BsonReader implements Reader {
if (len == SIGN_NULL) return null;
if (len == 0) return "";
String value = new String(Utility.decodeUTF8(content, ++this.position, len));
this.position += len - 1;
this.position += len - 1;//上一行已经++this.position所以此处要-1
return value;
}