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 com.wentch.redkale.util.*;
import java.lang.reflect.*; import java.lang.reflect.*;
import java.nio.*; import java.nio.*;
import java.util.function.*;
/** /**
* BSON协议格式: * BSON协议格式:
@@ -95,6 +96,28 @@ public final class BsonConvert extends Convert<BsonReader, BsonWriter> {
factory.loadEncoder(type).convertTo(out, value); 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) { public void convertTo(final BsonWriter out, Object value) {
if (value == null) { if (value == null) {
out.writeNull(); out.writeNull();

View File

@@ -13,14 +13,14 @@ import java.nio.*;
* *
* @author zhangjx * @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); private static final int defaultSize = Integer.getInteger("convert.bson.writer.buffer.defsize", 1024);
protected int count;
private byte[] content; private byte[] content;
protected int count;
protected boolean tiny; protected boolean tiny;
public static ObjectPool<BsonWriter> createPool(int max) { public static ObjectPool<BsonWriter> createPool(int max) {
@@ -58,7 +58,7 @@ public final class BsonWriter implements Writer {
} }
@Override @Override
public boolean isTiny() { public final boolean isTiny() {
return tiny; return tiny;
} }
@@ -75,7 +75,7 @@ public final class BsonWriter implements Writer {
* @param len * @param len
* @return * @return
*/ */
public byte[] expand(int len) { private byte[] expand(int len) {
int newcount = count + len; int newcount = count + len;
if (newcount <= content.length) return content; if (newcount <= content.length) return content;
byte[] newdata = new byte[Math.max(content.length * 3 / 2, newcount)]; 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; 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); rewriteTo(position, (byte) (value >> 8), (byte) value);
return position + 2; 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)); rewriteTo(position, (byte) ((value & 0xFF00) >> 8), (byte) (value & 0xFF));
return position + 2; 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); rewriteTo(position, (byte) (value >> 24), (byte) (value >> 16), (byte) (value >> 8), (byte) value);
return position + 4; 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), 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); (byte) (value >> 24), (byte) (value >> 16), (byte) (value >> 8), (byte) value);
return position + 8; return position + 8;
@@ -128,15 +128,11 @@ public final class BsonWriter implements Writer {
content[count++] = ch; content[count++] = ch;
} }
public void writeTo(final byte... chs) { public final void writeTo(final byte... chs) {
int len = chs.length; writeTo(chs, 0, chs.length);
expand(len);
System.arraycopy(chs, 0, content, count, len);
count += len;
} }
public void writeTo(final byte[] chs, final int start, final int end) { public void writeTo(final byte[] chs, final int start, final int len) {
int len = end - start;
expand(len); expand(len);
System.arraycopy(chs, start, content, count, len); System.arraycopy(chs, start, content, count, len);
count += len; count += len;
@@ -150,68 +146,59 @@ public final class BsonWriter implements Writer {
return true; 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 @Override
public String toString() { public String toString() {
return new String(content, 0, count); return new String(content, 0, count);
} }
//------------------------------------------------------------------------
public final int count() {
return this.count;
}
@Override @Override
public void writeBoolean(boolean value) { public final void writeBoolean(boolean value) {
writeTo(value ? (byte) 1 : (byte) 0); writeTo(value ? (byte) 1 : (byte) 0);
} }
@Override @Override
public void writeByte(byte value) { public final void writeByte(byte value) {
writeTo(value); writeTo(value);
} }
@Override @Override
public void writeChar(final char value) { public final void writeChar(final char value) {
writeTo((byte) ((value & 0xFF00) >> 8), (byte) (value & 0xFF)); writeTo((byte) ((value & 0xFF00) >> 8), (byte) (value & 0xFF));
} }
@Override @Override
public void writeShort(short value) { public final void writeShort(short value) {
writeTo((byte) (value >> 8), (byte) value); writeTo((byte) (value >> 8), (byte) value);
} }
@Override @Override
public void writeInt(int value) { public final void writeInt(int value) {
writeTo((byte) (value >> 24), (byte) (value >> 16), (byte) (value >> 8), (byte) value); writeTo((byte) (value >> 24), (byte) (value >> 16), (byte) (value >> 8), (byte) value);
} }
@Override @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), writeTo((byte) (value >> 56), (byte) (value >> 48), (byte) (value >> 40), (byte) (value >> 32),
(byte) (value >> 24), (byte) (value >> 16), (byte) (value >> 8), (byte) value); (byte) (value >> 24), (byte) (value >> 16), (byte) (value >> 8), (byte) value);
} }
@Override @Override
public void writeFloat(float value) { public final void writeFloat(float value) {
writeInt(Float.floatToIntBits(value)); writeInt(Float.floatToIntBits(value));
} }
@Override @Override
public void writeDouble(double value) { public final void writeDouble(double value) {
writeLong(Double.doubleToLongBits(value)); writeLong(Double.doubleToLongBits(value));
} }
@Override @Override
public void wirteClassName(String clazz) { public final void wirteClassName(String clazz) {
writeSmallString(clazz == null ? "" : clazz); writeSmallString(clazz == null ? "" : clazz);
} }
@@ -279,7 +266,7 @@ public final class BsonWriter implements Writer {
* @param value * @param value
*/ */
@Override @Override
public void writeSmallString(String value) { public final void writeSmallString(String value) {
if (value.isEmpty()) { if (value.isEmpty()) {
writeTo((byte) 0); writeTo((byte) 0);
return; return;
@@ -296,7 +283,7 @@ public final class BsonWriter implements Writer {
} }
@Override @Override
public void writeString(String value) { public final void writeString(String value) {
if (value == null) { if (value == null) {
writeInt(Reader.SIGN_NULL); writeInt(Reader.SIGN_NULL);
return; return;
@@ -315,16 +302,16 @@ public final class BsonWriter implements Writer {
} }
@Override @Override
public void writeArrayB(int size) { public final void writeArrayB(int size) {
writeInt(size); writeInt(size);
} }
@Override @Override
public void writeArrayMark() { public final void writeArrayMark() {
} }
@Override @Override
public void writeArrayE() { public final void writeArrayE() {
} }
@Override @Override
@@ -333,11 +320,11 @@ public final class BsonWriter implements Writer {
} }
@Override @Override
public void writeMapMark() { public final void writeMapMark() {
} }
@Override @Override
public void writeMapE() { public final void writeMapE() {
} }
} }

View File

@@ -40,13 +40,14 @@ public final class JsonByteBufferWriter extends JsonWriter {
protected boolean recycle() { protected boolean recycle() {
this.index = 0; this.index = 0;
this.buffers = null; this.buffers = null;
return true; return false;
} }
public ByteBuffer[] toBuffers() { public ByteBuffer[] toBuffers() {
if (buffers == null) return new ByteBuffer[0]; if (buffers == null) return new ByteBuffer[0];
for (int i = index; i < this.buffers.length; i++) { 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; return this.buffers;
} }