This commit is contained in:
kamhung
2015-11-10 16:35:43 +08:00
parent 04dbcc664e
commit edaa02c9ef
4 changed files with 244 additions and 48 deletions

View 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;
}
}

View File

@@ -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();

View File

@@ -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() {
}
}

View File

@@ -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;
}