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)));
|
||||
}
|
||||
}
|
||||
@@ -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")
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user