This commit is contained in:
164
src/org/redkale/convert/bson/BsonByteBufferReader.java
Normal file
164
src/org/redkale/convert/bson/BsonByteBufferReader.java
Normal 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)));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -13,21 +13,21 @@ import org.redkale.util.*;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* BSON协议格式:
|
* BSON协议格式:
|
||||||
* 1). 基本数据类型: 直接转换成byte[]
|
* 1). 基本数据类型: 直接转换成byte[]
|
||||||
* 2). SmallString(无特殊字符且长度小于256的字符串): length(1 byte) + byte[](utf8); 通常用于类名、字段名、枚举。
|
* 2). SmallString(无特殊字符且长度小于256的字符串): length(1 byte) + byte[](utf8); 通常用于类名、字段名、枚举。
|
||||||
* 3). String: length(4 bytes) + byte[](utf8);
|
* 3). String: length(4 bytes) + byte[](utf8);
|
||||||
* 4). 数组: length(4 bytes) + byte[]...
|
* 4). 数组: length(4 bytes) + byte[]...
|
||||||
* 5). Object:
|
* 5). Object:
|
||||||
* 1. realclass (SmallString) (如果指定格式化的class与实体对象的class不一致才会有该值)
|
* 1. realclass (SmallString) (如果指定格式化的class与实体对象的class不一致才会有该值)
|
||||||
* 2. 空字符串(SmallString)
|
* 2. 空字符串(SmallString)
|
||||||
* 3. SIGN_OBJECTB 标记位,值固定为0xBB (short)
|
* 3. SIGN_OBJECTB 标记位,值固定为0xBB (short)
|
||||||
* 4. 循环字段值:
|
* 4. 循环字段值:
|
||||||
* 4.1 SIGN_HASNEXT 标记位,值固定为1 (byte)
|
* 4.1 SIGN_HASNEXT 标记位,值固定为1 (byte)
|
||||||
* 4.2 字段类型; 1-9为基本类型&字符串; 101-109为基本类型&字符串的数组; 127为Object
|
* 4.2 字段类型; 1-9为基本类型&字符串; 101-109为基本类型&字符串的数组; 127为Object
|
||||||
* 4.3 字段名 (SmallString)
|
* 4.3 字段名 (SmallString)
|
||||||
* 4.4 字段的值Object
|
* 4.4 字段的值Object
|
||||||
* 5. SIGN_NONEXT 标记位,值固定为0 (byte)
|
* 5. SIGN_NONEXT 标记位,值固定为0 (byte)
|
||||||
* 6. SIGN_OBJECTE 标记位,值固定为0xEE (short)
|
* 6. SIGN_OBJECTE 标记位,值固定为0xEE (short)
|
||||||
*
|
*
|
||||||
* @see http://www.redkale.org
|
* @see http://www.redkale.org
|
||||||
* @author zhangjx
|
* @author zhangjx
|
||||||
@@ -80,6 +80,11 @@ public final class BsonConvert extends Convert<BsonReader, BsonWriter> {
|
|||||||
return rs;
|
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) {
|
public <T> T convertFrom(final BsonReader in, final Type type) {
|
||||||
if (type == null) return null;
|
if (type == null) return null;
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
|
|||||||
@@ -159,24 +159,28 @@ public class BsonReader implements Reader {
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public int readObjectB() {
|
public final int readObjectB() {
|
||||||
short bt = readShort();
|
short bt = readShort();
|
||||||
if (bt == Reader.SIGN_NULL) return bt;
|
if (bt == Reader.SIGN_NULL) return bt;
|
||||||
if (bt != SIGN_OBJECTB) {
|
if (bt != SIGN_OBJECTB) {
|
||||||
throw new ConvertException("a bson object must begin with " + (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;
|
return bt;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void readObjectE() {
|
public final void readObjectE() {
|
||||||
if (readShort() != SIGN_OBJECTE) {
|
if (readShort() != SIGN_OBJECTE) {
|
||||||
throw new ConvertException("a bson object must end with " + (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
|
@Override
|
||||||
public final int readMapB() {
|
public final int readMapB() {
|
||||||
return readArrayB();
|
return readArrayB();
|
||||||
@@ -288,17 +292,17 @@ public class BsonReader implements Reader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public float readFloat() {
|
public final float readFloat() {
|
||||||
return Float.intBitsToFloat(readInt());
|
return Float.intBitsToFloat(readInt());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public double readDouble() {
|
public final double readDouble() {
|
||||||
return Double.longBitsToDouble(readLong());
|
return Double.longBitsToDouble(readLong());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String readClassName() {
|
public final String readClassName() {
|
||||||
return readSmallString();
|
return readSmallString();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -307,7 +311,7 @@ public class BsonReader implements Reader {
|
|||||||
int len = 0xff & readByte();
|
int len = 0xff & readByte();
|
||||||
if (len == 0) return "";
|
if (len == 0) return "";
|
||||||
String value = new String(content, ++this.position, len);
|
String value = new String(content, ++this.position, len);
|
||||||
this.position += len - 1;
|
this.position += len - 1; //上一行已经++this.position,所以此处要-1
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -317,7 +321,7 @@ public class BsonReader implements Reader {
|
|||||||
if (len == SIGN_NULL) return null;
|
if (len == SIGN_NULL) return null;
|
||||||
if (len == 0) return "";
|
if (len == 0) return "";
|
||||||
String value = new String(Utility.decodeUTF8(content, ++this.position, len));
|
String value = new String(Utility.decodeUTF8(content, ++this.position, len));
|
||||||
this.position += len - 1;
|
this.position += len - 1;//上一行已经++this.position,所以此处要-1
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user