This commit is contained in:
185
src/com/wentch/redkale/convert/bson/BsonByteBufferWriter.java
Normal file
185
src/com/wentch/redkale/convert/bson/BsonByteBufferWriter.java
Normal file
@@ -0,0 +1,185 @@
|
||||
/*
|
||||
* 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 com.wentch.redkale.convert.bson;
|
||||
|
||||
import java.nio.*;
|
||||
import java.nio.charset.*;
|
||||
import java.util.function.*;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author zhangjx
|
||||
*/
|
||||
public final class BsonByteBufferWriter extends BsonWriter {
|
||||
|
||||
private static final Charset UTF8 = Charset.forName("UTF-8");
|
||||
|
||||
private final Supplier<ByteBuffer> supplier;
|
||||
|
||||
private ByteBuffer[] buffers;
|
||||
|
||||
private int index;
|
||||
|
||||
public BsonByteBufferWriter(Supplier<ByteBuffer> supplier) {
|
||||
this.supplier = supplier;
|
||||
}
|
||||
|
||||
public ByteBuffer[] toBuffers() {
|
||||
if (buffers == null) return new ByteBuffer[0];
|
||||
for (int i = index; i < this.buffers.length; i++) {
|
||||
ByteBuffer buf = this.buffers[i];
|
||||
if (buf.position() != 0) buf.flip();
|
||||
}
|
||||
return this.buffers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] toArray() {
|
||||
if (buffers == null) return new byte[0];
|
||||
int pos = 0;
|
||||
byte[] bytes = new byte[this.count];
|
||||
for (ByteBuffer buf : toBuffers()) {
|
||||
int r = buf.remaining();
|
||||
buf.get(bytes, pos, r);
|
||||
buf.flip();
|
||||
pos += r;
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuffer toBuffer() {
|
||||
if (buffers == null) return null;
|
||||
if (buffers.length == 1) return buffers[0];
|
||||
final ByteBuffer rs = ByteBuffer.allocate(count);
|
||||
for (ByteBuffer buf : toBuffers()) {
|
||||
rs.put(buf);
|
||||
buf.flip();
|
||||
}
|
||||
rs.flip();
|
||||
return rs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void toBuffer(ByteBuffer buffer) {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public int toBuffer(int offset, ByteBuffer buffer) {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "bytes[" + count() + "]";
|
||||
}
|
||||
|
||||
@Override
|
||||
public BsonByteBufferWriter setTiny(boolean tiny) {
|
||||
this.tiny = tiny;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BsonByteBufferWriter fillRange(final int len) {
|
||||
ByteBuffer buffer = this.buffers[index];
|
||||
if (expand(len) == 0) {
|
||||
buffer.position(buffer.position() + len);
|
||||
} else {
|
||||
int remain = len; //还剩多少没有写
|
||||
while (remain > 0) {
|
||||
final int br = buffer.remaining();
|
||||
if (remain > br) { //一个buffer写不完
|
||||
buffer.position(buffer.position() + br);
|
||||
buffer = nextByteBuffer();
|
||||
remain -= br;
|
||||
} else {
|
||||
buffer.position(buffer.position() + remain);
|
||||
remain = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
this.count += len;
|
||||
return this;
|
||||
}
|
||||
|
||||
private int expand(final int byteLength) {
|
||||
if (this.buffers == null) {
|
||||
this.index = 0;
|
||||
this.buffers = new ByteBuffer[]{supplier.get()};
|
||||
}
|
||||
ByteBuffer buffer = this.buffers[index];
|
||||
if (!buffer.hasRemaining()) {
|
||||
buffer.flip();
|
||||
buffer = supplier.get();
|
||||
ByteBuffer[] bufs = new ByteBuffer[this.buffers.length + 1];
|
||||
System.arraycopy(this.buffers, 0, bufs, 0, this.buffers.length);
|
||||
bufs[this.buffers.length] = buffer;
|
||||
this.buffers = bufs;
|
||||
this.index++;
|
||||
}
|
||||
int len = buffer.remaining();
|
||||
int size = 0;
|
||||
while (len < byteLength) {
|
||||
buffer = supplier.get();
|
||||
ByteBuffer[] bufs = new ByteBuffer[this.buffers.length + 1];
|
||||
System.arraycopy(this.buffers, 0, bufs, 0, this.buffers.length);
|
||||
bufs[this.buffers.length] = buffer;
|
||||
this.buffers = bufs;
|
||||
len += buffer.remaining();
|
||||
size++;
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int rewriteTo(int position, byte... chs) {
|
||||
return position += chs.length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeTo(final byte[] chs, final int start, final int len) {
|
||||
if (expand(len) == 0) {
|
||||
this.buffers[index].put(chs, start, len);
|
||||
} else {
|
||||
ByteBuffer buffer = this.buffers[index];
|
||||
final int end = start + len;
|
||||
int remain = len; //还剩多少没有写
|
||||
while (remain > 0) {
|
||||
final int br = buffer.remaining();
|
||||
if (remain > br) { //一个buffer写不完
|
||||
buffer.put(chs, end - remain, br);
|
||||
buffer = nextByteBuffer();
|
||||
remain -= br;
|
||||
} else {
|
||||
buffer.put(chs, end - remain, remain);
|
||||
remain = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
this.count += len;
|
||||
}
|
||||
|
||||
private ByteBuffer nextByteBuffer() {
|
||||
this.buffers[this.index].flip();
|
||||
return this.buffers[++this.index];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeTo(final byte ch) {
|
||||
expand(1);
|
||||
this.buffers[index].put(ch);
|
||||
count++;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean recycle() {
|
||||
this.index = 0;
|
||||
this.buffers = null;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,7 @@ import com.wentch.redkale.convert.*;
|
||||
import com.wentch.redkale.util.*;
|
||||
import java.lang.reflect.*;
|
||||
import java.nio.*;
|
||||
import java.util.function.*;
|
||||
|
||||
/**
|
||||
* BSON协议格式:
|
||||
@@ -95,6 +96,28 @@ public final class BsonConvert extends Convert<BsonReader, BsonWriter> {
|
||||
factory.loadEncoder(type).convertTo(out, value);
|
||||
}
|
||||
|
||||
public ByteBuffer[] convertTo(final Supplier<ByteBuffer> supplier, final Type type, Object value) {
|
||||
if (supplier == null || type == null) return null;
|
||||
BsonByteBufferWriter out = new BsonByteBufferWriter(supplier);
|
||||
if (value == null) {
|
||||
out.writeNull();
|
||||
} else {
|
||||
factory.loadEncoder(type).convertTo(out, value);
|
||||
}
|
||||
return out.toBuffers();
|
||||
}
|
||||
|
||||
public ByteBuffer[] convertTo(final Supplier<ByteBuffer> supplier, Object value) {
|
||||
if (supplier == null) return null;
|
||||
BsonByteBufferWriter out = new BsonByteBufferWriter(supplier);
|
||||
if (value == null) {
|
||||
out.writeNull();
|
||||
} else {
|
||||
factory.loadEncoder(value.getClass()).convertTo(out, value);
|
||||
}
|
||||
return out.toBuffers();
|
||||
}
|
||||
|
||||
public void convertTo(final BsonWriter out, Object value) {
|
||||
if (value == null) {
|
||||
out.writeNull();
|
||||
|
||||
@@ -13,14 +13,14 @@ import java.nio.*;
|
||||
*
|
||||
* @author zhangjx
|
||||
*/
|
||||
public final class BsonWriter implements Writer {
|
||||
public class BsonWriter implements Writer {
|
||||
|
||||
private static final int defaultSize = Integer.getInteger("convert.bson.writer.buffer.defsize", 1024);
|
||||
|
||||
protected int count;
|
||||
|
||||
private byte[] content;
|
||||
|
||||
protected int count;
|
||||
|
||||
protected boolean tiny;
|
||||
|
||||
public static ObjectPool<BsonWriter> createPool(int max) {
|
||||
@@ -58,7 +58,7 @@ public final class BsonWriter implements Writer {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isTiny() {
|
||||
public final boolean isTiny() {
|
||||
return tiny;
|
||||
}
|
||||
|
||||
@@ -75,7 +75,7 @@ public final class BsonWriter implements Writer {
|
||||
* @param len
|
||||
* @return
|
||||
*/
|
||||
public byte[] expand(int len) {
|
||||
private byte[] expand(int len) {
|
||||
int newcount = count + len;
|
||||
if (newcount <= content.length) return content;
|
||||
byte[] newdata = new byte[Math.max(content.length * 3 / 2, newcount)];
|
||||
@@ -96,22 +96,22 @@ public final class BsonWriter implements Writer {
|
||||
return position + chs.length;
|
||||
}
|
||||
|
||||
public int rewriteTo(int position, short value) {
|
||||
public final int rewriteTo(int position, short value) {
|
||||
rewriteTo(position, (byte) (value >> 8), (byte) value);
|
||||
return position + 2;
|
||||
}
|
||||
|
||||
public int rewriteTo(int position, char value) {
|
||||
public final int rewriteTo(int position, char value) {
|
||||
rewriteTo(position, (byte) ((value & 0xFF00) >> 8), (byte) (value & 0xFF));
|
||||
return position + 2;
|
||||
}
|
||||
|
||||
public int rewriteTo(int position, int value) {
|
||||
public final int rewriteTo(int position, int value) {
|
||||
rewriteTo(position, (byte) (value >> 24), (byte) (value >> 16), (byte) (value >> 8), (byte) value);
|
||||
return position + 4;
|
||||
}
|
||||
|
||||
public int rewriteTo(int position, long value) {
|
||||
public final int rewriteTo(int position, long value) {
|
||||
rewriteTo(position, (byte) (value >> 56), (byte) (value >> 48), (byte) (value >> 40), (byte) (value >> 32),
|
||||
(byte) (value >> 24), (byte) (value >> 16), (byte) (value >> 8), (byte) value);
|
||||
return position + 8;
|
||||
@@ -128,15 +128,11 @@ public final class BsonWriter implements Writer {
|
||||
content[count++] = ch;
|
||||
}
|
||||
|
||||
public void writeTo(final byte... chs) {
|
||||
int len = chs.length;
|
||||
expand(len);
|
||||
System.arraycopy(chs, 0, content, count, len);
|
||||
count += len;
|
||||
public final void writeTo(final byte... chs) {
|
||||
writeTo(chs, 0, chs.length);
|
||||
}
|
||||
|
||||
public void writeTo(final byte[] chs, final int start, final int end) {
|
||||
int len = end - start;
|
||||
public void writeTo(final byte[] chs, final int start, final int len) {
|
||||
expand(len);
|
||||
System.arraycopy(chs, start, content, count, len);
|
||||
count += len;
|
||||
@@ -150,68 +146,59 @@ public final class BsonWriter implements Writer {
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
public int position() {
|
||||
return this.count;
|
||||
}
|
||||
|
||||
public final int count() {
|
||||
return this.count;
|
||||
}
|
||||
|
||||
public final void count(int count) {
|
||||
if (count >= 0) this.count = count;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
@Override
|
||||
public String toString() {
|
||||
return new String(content, 0, count);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
public final int count() {
|
||||
return this.count;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeBoolean(boolean value) {
|
||||
public final void writeBoolean(boolean value) {
|
||||
writeTo(value ? (byte) 1 : (byte) 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeByte(byte value) {
|
||||
public final void writeByte(byte value) {
|
||||
writeTo(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeChar(final char value) {
|
||||
public final void writeChar(final char value) {
|
||||
writeTo((byte) ((value & 0xFF00) >> 8), (byte) (value & 0xFF));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeShort(short value) {
|
||||
public final void writeShort(short value) {
|
||||
writeTo((byte) (value >> 8), (byte) value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeInt(int value) {
|
||||
public final void writeInt(int value) {
|
||||
writeTo((byte) (value >> 24), (byte) (value >> 16), (byte) (value >> 8), (byte) value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeLong(long value) {
|
||||
public final void writeLong(long value) {
|
||||
writeTo((byte) (value >> 56), (byte) (value >> 48), (byte) (value >> 40), (byte) (value >> 32),
|
||||
(byte) (value >> 24), (byte) (value >> 16), (byte) (value >> 8), (byte) value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeFloat(float value) {
|
||||
public final void writeFloat(float value) {
|
||||
writeInt(Float.floatToIntBits(value));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeDouble(double value) {
|
||||
public final void writeDouble(double value) {
|
||||
writeLong(Double.doubleToLongBits(value));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void wirteClassName(String clazz) {
|
||||
public final void wirteClassName(String clazz) {
|
||||
writeSmallString(clazz == null ? "" : clazz);
|
||||
}
|
||||
|
||||
@@ -279,7 +266,7 @@ public final class BsonWriter implements Writer {
|
||||
* @param value
|
||||
*/
|
||||
@Override
|
||||
public void writeSmallString(String value) {
|
||||
public final void writeSmallString(String value) {
|
||||
if (value.isEmpty()) {
|
||||
writeTo((byte) 0);
|
||||
return;
|
||||
@@ -296,7 +283,7 @@ public final class BsonWriter implements Writer {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeString(String value) {
|
||||
public final void writeString(String value) {
|
||||
if (value == null) {
|
||||
writeInt(Reader.SIGN_NULL);
|
||||
return;
|
||||
@@ -315,16 +302,16 @@ public final class BsonWriter implements Writer {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeArrayB(int size) {
|
||||
public final void writeArrayB(int size) {
|
||||
writeInt(size);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeArrayMark() {
|
||||
public final void writeArrayMark() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeArrayE() {
|
||||
public final void writeArrayE() {
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -333,11 +320,11 @@ public final class BsonWriter implements Writer {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeMapMark() {
|
||||
public final void writeMapMark() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeMapE() {
|
||||
public final void writeMapE() {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -40,13 +40,14 @@ public final class JsonByteBufferWriter extends JsonWriter {
|
||||
protected boolean recycle() {
|
||||
this.index = 0;
|
||||
this.buffers = null;
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
public ByteBuffer[] toBuffers() {
|
||||
if (buffers == null) return new ByteBuffer[0];
|
||||
for (int i = index; i < this.buffers.length; i++) {
|
||||
this.buffers[i].flip();
|
||||
ByteBuffer buf = this.buffers[i];
|
||||
if (buf.position() != 0) buf.flip();
|
||||
}
|
||||
return this.buffers;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user