This commit is contained in:
@@ -18,7 +18,7 @@ import static java.lang.annotation.RetentionPolicy.*;
|
||||
@Documented
|
||||
@Target({METHOD, FIELD})
|
||||
@Retention(RUNTIME)
|
||||
//@Repeatable(ConvertColumns.class)
|
||||
@Repeatable(ConvertColumns.class)
|
||||
public @interface ConvertColumn {
|
||||
|
||||
/**
|
||||
|
||||
@@ -128,8 +128,7 @@ public abstract class Factory<R extends Reader, W extends Writer> {
|
||||
ConvertColumnEntry en = this.columnEntrys.get(field);
|
||||
if (en != null) return en;
|
||||
final ConvertType ct = this.getConvertType();
|
||||
ConvertColumn ref = field.getAnnotation(ConvertColumn.class);
|
||||
if (ref != null) {
|
||||
for (ConvertColumn ref : field.getAnnotationsByType(ConvertColumn.class)) {
|
||||
if (ref.type().contains(ct)) {
|
||||
ConvertColumnEntry entry = new ConvertColumnEntry(ref);
|
||||
if (skipAllIgnore) {
|
||||
|
||||
@@ -32,6 +32,10 @@ public final class ObjectDecoder<R extends Reader, T> implements Decodeable<R, T
|
||||
|
||||
protected Factory factory;
|
||||
|
||||
private boolean inited = false;
|
||||
|
||||
private final Object lock = new Object();
|
||||
|
||||
protected ObjectDecoder(Type type) {
|
||||
this.type = ((type instanceof Class) && ((Class) type).isInterface()) ? Object.class : type;
|
||||
if (type instanceof ParameterizedType) {
|
||||
@@ -45,56 +49,63 @@ public final class ObjectDecoder<R extends Reader, T> implements Decodeable<R, T
|
||||
|
||||
public void init(final Factory factory) {
|
||||
this.factory = factory;
|
||||
if (type == Object.class) return;
|
||||
|
||||
Class clazz = null;
|
||||
if (type instanceof ParameterizedType) {
|
||||
final ParameterizedType pts = (ParameterizedType) type;
|
||||
clazz = (Class) (pts).getRawType();
|
||||
} else if (!(type instanceof Class)) {
|
||||
throw new ConvertException("[" + type + "] is no a class");
|
||||
} else {
|
||||
clazz = (Class) type;
|
||||
}
|
||||
final Type[] virGenericTypes = this.typeClass.getTypeParameters();
|
||||
final Type[] realGenericTypes = (type instanceof ParameterizedType) ? ((ParameterizedType) type).getActualTypeArguments() : TYPEZERO;
|
||||
this.creator = factory.loadCreator(clazz);
|
||||
final Set<DeMember> list = new HashSet();
|
||||
try {
|
||||
ConvertColumnEntry ref;
|
||||
for (final Field field : clazz.getFields()) {
|
||||
if (Modifier.isStatic(field.getModifiers())) continue;
|
||||
ref = factory.findRef(field);
|
||||
if (ref != null && ref.ignore()) continue;
|
||||
Type t = ObjectEncoder.makeGenericType(field.getGenericType(), virGenericTypes, realGenericTypes);
|
||||
list.add(new DeMember(ObjectEncoder.createAttribute(factory, clazz, field, null, null), factory.loadDecoder(t)));
|
||||
if (type == Object.class) return;
|
||||
|
||||
Class clazz = null;
|
||||
if (type instanceof ParameterizedType) {
|
||||
final ParameterizedType pts = (ParameterizedType) type;
|
||||
clazz = (Class) (pts).getRawType();
|
||||
} else if (!(type instanceof Class)) {
|
||||
throw new ConvertException("[" + type + "] is no a class");
|
||||
} else {
|
||||
clazz = (Class) type;
|
||||
}
|
||||
final boolean reversible = factory.isReversible();
|
||||
for (final Method method : clazz.getMethods()) {
|
||||
if (Modifier.isStatic(method.getModifiers())) continue;
|
||||
if (Modifier.isAbstract(method.getModifiers())) continue;
|
||||
if (method.isSynthetic()) continue;
|
||||
if (method.getName().length() < 4) continue;
|
||||
if (!method.getName().startsWith("set")) continue;
|
||||
if (method.getParameterTypes().length != 1) continue;
|
||||
if (method.getReturnType() != void.class) continue;
|
||||
if (reversible) {
|
||||
boolean is = method.getParameterTypes()[0] == boolean.class || method.getParameterTypes()[0] == Boolean.class;
|
||||
try {
|
||||
clazz.getMethod(method.getName().replaceFirst("set", is ? "is" : "get"));
|
||||
} catch (Exception e) {
|
||||
continue;
|
||||
}
|
||||
final Type[] virGenericTypes = this.typeClass.getTypeParameters();
|
||||
final Type[] realGenericTypes = (type instanceof ParameterizedType) ? ((ParameterizedType) type).getActualTypeArguments() : TYPEZERO;
|
||||
this.creator = factory.loadCreator(clazz);
|
||||
final Set<DeMember> list = new HashSet();
|
||||
try {
|
||||
ConvertColumnEntry ref;
|
||||
for (final Field field : clazz.getFields()) {
|
||||
if (Modifier.isStatic(field.getModifiers())) continue;
|
||||
ref = factory.findRef(field);
|
||||
if (ref != null && ref.ignore()) continue;
|
||||
Type t = ObjectEncoder.makeGenericType(field.getGenericType(), virGenericTypes, realGenericTypes);
|
||||
list.add(new DeMember(ObjectEncoder.createAttribute(factory, clazz, field, null, null), factory.loadDecoder(t)));
|
||||
}
|
||||
ref = factory.findRef(method);
|
||||
if (ref != null && ref.ignore()) continue;
|
||||
Type t = ObjectEncoder.makeGenericType(method.getGenericParameterTypes()[0], virGenericTypes, realGenericTypes);
|
||||
list.add(new DeMember(ObjectEncoder.createAttribute(factory, clazz, null, null, method), factory.loadDecoder(t)));
|
||||
final boolean reversible = factory.isReversible();
|
||||
for (final Method method : clazz.getMethods()) {
|
||||
if (Modifier.isStatic(method.getModifiers())) continue;
|
||||
if (Modifier.isAbstract(method.getModifiers())) continue;
|
||||
if (method.isSynthetic()) continue;
|
||||
if (method.getName().length() < 4) continue;
|
||||
if (!method.getName().startsWith("set")) continue;
|
||||
if (method.getParameterTypes().length != 1) continue;
|
||||
if (method.getReturnType() != void.class) continue;
|
||||
if (reversible) {
|
||||
boolean is = method.getParameterTypes()[0] == boolean.class || method.getParameterTypes()[0] == Boolean.class;
|
||||
try {
|
||||
clazz.getMethod(method.getName().replaceFirst("set", is ? "is" : "get"));
|
||||
} catch (Exception e) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
ref = factory.findRef(method);
|
||||
if (ref != null && ref.ignore()) continue;
|
||||
Type t = ObjectEncoder.makeGenericType(method.getGenericParameterTypes()[0], virGenericTypes, realGenericTypes);
|
||||
list.add(new DeMember(ObjectEncoder.createAttribute(factory, clazz, null, null, method), factory.loadDecoder(t)));
|
||||
}
|
||||
this.members = list.toArray(new DeMember[list.size()]);
|
||||
Arrays.sort(this.members);
|
||||
} catch (Exception ex) {
|
||||
throw new ConvertException(ex);
|
||||
}
|
||||
} finally {
|
||||
inited = true;
|
||||
synchronized (lock) {
|
||||
lock.notifyAll();
|
||||
}
|
||||
this.members = list.toArray(new DeMember[list.size()]);
|
||||
Arrays.sort(this.members);
|
||||
} catch (Exception ex) {
|
||||
throw new ConvertException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -109,6 +120,15 @@ public final class ObjectDecoder<R extends Reader, T> implements Decodeable<R, T
|
||||
final String clazz = in.readClassName();
|
||||
if (clazz != null && !clazz.isEmpty()) return (T) factory.loadDecoder(factory.getEntity(clazz)).convertFrom(in);
|
||||
if (in.readObjectB() == Reader.SIGN_NULL) return null;
|
||||
if (!this.inited) {
|
||||
synchronized (lock) {
|
||||
try {
|
||||
lock.wait();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
final T result = this.creator.create();
|
||||
final AtomicInteger index = new AtomicInteger();
|
||||
while (in.hasNext()) {
|
||||
|
||||
@@ -29,6 +29,10 @@ public final class ObjectEncoder<W extends Writer, T> implements Encodeable<W, T
|
||||
|
||||
protected Factory factory;
|
||||
|
||||
private boolean inited = false;
|
||||
|
||||
private final Object lock = new Object();
|
||||
|
||||
protected ObjectEncoder(Type type) {
|
||||
this.type = type;
|
||||
if (type instanceof ParameterizedType) {
|
||||
@@ -132,52 +136,59 @@ public final class ObjectEncoder<W extends Writer, T> implements Encodeable<W, T
|
||||
|
||||
public void init(final Factory factory) {
|
||||
this.factory = factory;
|
||||
if (type == Object.class) return;
|
||||
//if (!(type instanceof Class)) throw new ConvertException("[" + type + "] is no a class");
|
||||
final Class clazz = this.typeClass;
|
||||
final Set<EnMember> list = new HashSet();
|
||||
final Type[] virGenericTypes = this.typeClass.getTypeParameters();
|
||||
final Type[] realGenericTypes = (type instanceof ParameterizedType) ? ((ParameterizedType) type).getActualTypeArguments() : null;
|
||||
if (realGenericTypes != null) {
|
||||
// println(type + "," + Arrays.toString(virGenericTypes) + ", " + Arrays.toString(realGenericTypes));
|
||||
}
|
||||
try {
|
||||
ConvertColumnEntry ref;
|
||||
for (final Field field : clazz.getFields()) {
|
||||
if (Modifier.isStatic(field.getModifiers())) continue;
|
||||
ref = factory.findRef(field);
|
||||
if (ref != null && ref.ignore()) continue;
|
||||
Type t = makeGenericType(field.getGenericType(), virGenericTypes, realGenericTypes);
|
||||
list.add(new EnMember(createAttribute(factory, clazz, field, null, null), factory.loadEncoder(t)));
|
||||
if (type == Object.class) return;
|
||||
//if (!(type instanceof Class)) throw new ConvertException("[" + type + "] is no a class");
|
||||
final Class clazz = this.typeClass;
|
||||
final Set<EnMember> list = new HashSet();
|
||||
final Type[] virGenericTypes = this.typeClass.getTypeParameters();
|
||||
final Type[] realGenericTypes = (type instanceof ParameterizedType) ? ((ParameterizedType) type).getActualTypeArguments() : null;
|
||||
if (realGenericTypes != null) {
|
||||
// println(type + "," + Arrays.toString(virGenericTypes) + ", " + Arrays.toString(realGenericTypes));
|
||||
}
|
||||
final boolean reversible = factory.isReversible();
|
||||
for (final Method method : clazz.getMethods()) {
|
||||
if (Modifier.isStatic(method.getModifiers())) continue;
|
||||
if (Modifier.isAbstract(method.getModifiers())) continue;
|
||||
if (method.isSynthetic()) continue;
|
||||
if (method.getName().length() < 3) continue;
|
||||
if (method.getName().equals("getClass")) continue;
|
||||
if (!method.getName().startsWith("is") && !method.getName().startsWith("get")) continue;
|
||||
if (method.getParameterTypes().length != 0) continue;
|
||||
if (method.getReturnType() == void.class) continue;
|
||||
if (reversible) {
|
||||
boolean is = method.getName().startsWith("is");
|
||||
try {
|
||||
clazz.getMethod(method.getName().replaceFirst(is ? "is" : "get", "set"), method.getReturnType());
|
||||
} catch (Exception e) {
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
ConvertColumnEntry ref;
|
||||
for (final Field field : clazz.getFields()) {
|
||||
if (Modifier.isStatic(field.getModifiers())) continue;
|
||||
ref = factory.findRef(field);
|
||||
if (ref != null && ref.ignore()) continue;
|
||||
Type t = makeGenericType(field.getGenericType(), virGenericTypes, realGenericTypes);
|
||||
list.add(new EnMember(createAttribute(factory, clazz, field, null, null), factory.loadEncoder(t)));
|
||||
}
|
||||
ref = factory.findRef(method);
|
||||
if (ref != null && ref.ignore()) continue;
|
||||
Type t = makeGenericType(method.getGenericReturnType(), virGenericTypes, realGenericTypes);
|
||||
list.add(new EnMember(createAttribute(factory, clazz, null, method, null), factory.loadEncoder(t)));
|
||||
}
|
||||
this.members = list.toArray(new EnMember[list.size()]);
|
||||
Arrays.sort(this.members);
|
||||
final boolean reversible = factory.isReversible();
|
||||
for (final Method method : clazz.getMethods()) {
|
||||
if (Modifier.isStatic(method.getModifiers())) continue;
|
||||
if (Modifier.isAbstract(method.getModifiers())) continue;
|
||||
if (method.isSynthetic()) continue;
|
||||
if (method.getName().length() < 3) continue;
|
||||
if (method.getName().equals("getClass")) continue;
|
||||
if (!method.getName().startsWith("is") && !method.getName().startsWith("get")) continue;
|
||||
if (method.getParameterTypes().length != 0) continue;
|
||||
if (method.getReturnType() == void.class) continue;
|
||||
if (reversible) {
|
||||
boolean is = method.getName().startsWith("is");
|
||||
try {
|
||||
clazz.getMethod(method.getName().replaceFirst(is ? "is" : "get", "set"), method.getReturnType());
|
||||
} catch (Exception e) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
ref = factory.findRef(method);
|
||||
if (ref != null && ref.ignore()) continue;
|
||||
Type t = makeGenericType(method.getGenericReturnType(), virGenericTypes, realGenericTypes);
|
||||
list.add(new EnMember(createAttribute(factory, clazz, null, method, null), factory.loadEncoder(t)));
|
||||
}
|
||||
this.members = list.toArray(new EnMember[list.size()]);
|
||||
Arrays.sort(this.members);
|
||||
|
||||
} catch (Exception ex) {
|
||||
throw new ConvertException(ex);
|
||||
} catch (Exception ex) {
|
||||
throw new ConvertException(ex);
|
||||
}
|
||||
} finally {
|
||||
inited = true;
|
||||
synchronized (lock) {
|
||||
lock.notifyAll();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -188,6 +199,15 @@ public final class ObjectEncoder<W extends Writer, T> implements Encodeable<W, T
|
||||
out.writeNull();
|
||||
return;
|
||||
}
|
||||
if (!this.inited) {
|
||||
synchronized (lock) {
|
||||
try {
|
||||
lock.wait();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (value != null && value.getClass() != this.typeClass) {
|
||||
final Class clz = value.getClass();
|
||||
out.wirteClassName(factory.getEntity(clz));
|
||||
|
||||
@@ -0,0 +1,134 @@
|
||||
/*
|
||||
* 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 com.wentch.redkale.util.*;
|
||||
import java.nio.*;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author zhangjx
|
||||
*/
|
||||
public final class BsonByteBufferWriter extends BsonWriter {
|
||||
|
||||
private final Supplier<ByteBuffer> supplier;
|
||||
|
||||
private ByteBuffer[] buffers;
|
||||
|
||||
private int index;
|
||||
|
||||
protected BsonByteBufferWriter(Supplier<ByteBuffer> supplier) {
|
||||
super((byte[]) null);
|
||||
this.supplier = supplier;
|
||||
}
|
||||
|
||||
@Override
|
||||
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 String toString() {
|
||||
return this.getClass().getSimpleName() + "[count=" + this.count + "]";
|
||||
}
|
||||
|
||||
@Override
|
||||
public BsonByteBufferWriter setTiny(boolean tiny) {
|
||||
this.tiny = tiny;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected 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 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;
|
||||
}
|
||||
}
|
||||
@@ -43,10 +43,12 @@ public final class BsonConvert extends Convert<BsonReader, BsonWriter> {
|
||||
this.tiny = tiny;
|
||||
}
|
||||
|
||||
public BsonByteBufferWriter pollBsonWriter(final Supplier<ByteBuffer> supplier) {
|
||||
return new BsonByteBufferWriter(supplier).setTiny(tiny);
|
||||
}
|
||||
|
||||
public BsonWriter pollBsonWriter() {
|
||||
final BsonWriter out = writerPool.get();
|
||||
out.setTiny(tiny);
|
||||
return out;
|
||||
return writerPool.get().setTiny(tiny);
|
||||
}
|
||||
|
||||
public void offerBsonWriter(BsonWriter out) {
|
||||
@@ -85,8 +87,7 @@ public final class BsonConvert extends Convert<BsonReader, BsonWriter> {
|
||||
|
||||
public byte[] convertTo(final Type type, Object value) {
|
||||
if (type == null) return null;
|
||||
final BsonWriter out = writerPool.get();
|
||||
out.setTiny(tiny);
|
||||
final BsonWriter out = writerPool.get().setTiny(tiny);
|
||||
factory.loadEncoder(type).convertTo(out, value);
|
||||
byte[] result = out.toArray();
|
||||
writerPool.offer(out);
|
||||
@@ -98,6 +99,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();
|
||||
@@ -108,8 +131,7 @@ public final class BsonConvert extends Convert<BsonReader, BsonWriter> {
|
||||
|
||||
public byte[] convertTo(Object value) {
|
||||
if (value == null) {
|
||||
final BsonWriter out = writerPool.get();
|
||||
out.setTiny(tiny);
|
||||
final BsonWriter out = writerPool.get().setTiny(tiny);
|
||||
out.writeNull();
|
||||
byte[] result = out.toArray();
|
||||
writerPool.offer(out);
|
||||
@@ -118,25 +140,15 @@ public final class BsonConvert extends Convert<BsonReader, BsonWriter> {
|
||||
return convertTo(value.getClass(), value);
|
||||
}
|
||||
|
||||
public ByteBuffer convertToBuffer(final Type type, Object value) {
|
||||
public BsonWriter convertToWriter(final Type type, Object value) {
|
||||
if (type == null) return null;
|
||||
final BsonWriter out = writerPool.get();
|
||||
out.setTiny(tiny);
|
||||
final BsonWriter out = writerPool.get().setTiny(tiny);
|
||||
factory.loadEncoder(type).convertTo(out, value);
|
||||
ByteBuffer result = out.toBuffer();
|
||||
writerPool.offer(out);
|
||||
return result;
|
||||
return out;
|
||||
}
|
||||
|
||||
public ByteBuffer convertToBuffer(Object value) {
|
||||
if (value == null) {
|
||||
final BsonWriter out = writerPool.get();
|
||||
out.setTiny(tiny);
|
||||
out.writeNull();
|
||||
ByteBuffer result = out.toBuffer();
|
||||
writerPool.offer(out);
|
||||
return result;
|
||||
}
|
||||
return convertToBuffer(value.getClass(), value);
|
||||
public BsonWriter convertToWriter(Object value) {
|
||||
if (value == null) return null;
|
||||
return convertToWriter(value.getClass(), value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,13 +62,21 @@ public final class BsonReader implements Reader {
|
||||
}
|
||||
|
||||
public final void setBytes(byte[] bytes) {
|
||||
setBytes(bytes, 0, bytes.length);
|
||||
if (bytes == null) {
|
||||
this.position = 0;
|
||||
} else {
|
||||
setBytes(bytes, 0, bytes.length);
|
||||
}
|
||||
}
|
||||
|
||||
public final void setBytes(byte[] bytes, int start, int len) {
|
||||
this.content = bytes;
|
||||
this.position = start - 1;
|
||||
//this.limit = start + len - 1;
|
||||
if (bytes == null) {
|
||||
this.position = 0;
|
||||
} else {
|
||||
this.content = bytes;
|
||||
this.position = start - 1;
|
||||
//this.limit = start + len - 1;
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean recycle() {
|
||||
|
||||
@@ -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) {
|
||||
@@ -46,8 +46,12 @@ public final class BsonWriter implements Writer {
|
||||
return newdata;
|
||||
}
|
||||
|
||||
public ByteBuffer toBuffer() {
|
||||
return ByteBuffer.wrap(content, 0, count);
|
||||
public ByteBuffer[] toBuffers() {
|
||||
return new ByteBuffer[]{ByteBuffer.wrap(content, 0, count)};
|
||||
}
|
||||
|
||||
protected BsonWriter(byte[] bs) {
|
||||
this.content = bs;
|
||||
}
|
||||
|
||||
public BsonWriter() {
|
||||
@@ -55,60 +59,34 @@ public final class BsonWriter implements Writer {
|
||||
}
|
||||
|
||||
public BsonWriter(int size) {
|
||||
this.content = new byte[size > 32 ? size : 32];
|
||||
this.content = new byte[size > 128 ? size : 128];
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isTiny() {
|
||||
public final boolean isTiny() {
|
||||
return tiny;
|
||||
}
|
||||
|
||||
public void setTiny(boolean tiny) {
|
||||
public BsonWriter setTiny(boolean tiny) {
|
||||
this.tiny = tiny;
|
||||
return this;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------
|
||||
/**
|
||||
* 返回指定至少指定长度的缓冲区
|
||||
* 扩充指定长度的缓冲区
|
||||
*
|
||||
* @param len
|
||||
* @return
|
||||
*/
|
||||
public byte[] expand(int len) {
|
||||
protected int expand(int len) {
|
||||
int newcount = count + len;
|
||||
if (newcount <= content.length) return content;
|
||||
if (newcount <= content.length) return 0;
|
||||
byte[] newdata = new byte[Math.max(content.length * 3 / 2, newcount)];
|
||||
System.arraycopy(content, 0, newdata, 0, count);
|
||||
this.content = newdata;
|
||||
return newdata;
|
||||
}
|
||||
|
||||
/**
|
||||
* 往指定的位置写入字节
|
||||
*
|
||||
* @param position
|
||||
* @param chs
|
||||
*/
|
||||
public void rewriteTo(int position, byte... chs) {
|
||||
System.arraycopy(chs, 0, content, position, chs.length);
|
||||
}
|
||||
|
||||
public void rewriteTo(int position, short value) {
|
||||
rewriteTo(position, (byte) (value >> 8), (byte) value);
|
||||
}
|
||||
|
||||
public void rewriteTo(int position, char value) {
|
||||
rewriteTo(position, (byte) ((value & 0xFF00) >> 8), (byte) (value & 0xFF));
|
||||
}
|
||||
|
||||
public void rewriteTo(int position, int value) {
|
||||
rewriteTo(position, (byte) (value >> 24), (byte) (value >> 16), (byte) (value >> 8), (byte) value);
|
||||
}
|
||||
|
||||
public void 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 0;
|
||||
}
|
||||
|
||||
public void writeTo(final byte ch) {
|
||||
@@ -116,15 +94,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;
|
||||
@@ -138,68 +112,59 @@ public final class BsonWriter implements Writer {
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
public int position() {
|
||||
return this.count;
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.getClass().getSimpleName() + "[count=" + 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);
|
||||
}
|
||||
|
||||
@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);
|
||||
}
|
||||
|
||||
@@ -267,7 +232,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;
|
||||
@@ -284,7 +249,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;
|
||||
@@ -303,16 +268,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
|
||||
@@ -321,11 +286,11 @@ public final class BsonWriter implements Writer {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeMapMark() {
|
||||
public final void writeMapMark() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeMapE() {
|
||||
public final void writeMapE() {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,348 @@
|
||||
/*
|
||||
* 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.json;
|
||||
|
||||
import com.wentch.redkale.util.*;
|
||||
import com.wentch.redkale.util.Supplier;
|
||||
import java.nio.*;
|
||||
import java.nio.charset.*;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author zhangjx
|
||||
*/
|
||||
public final class JsonByteBufferWriter extends JsonWriter {
|
||||
|
||||
private static final Charset UTF8 = Charset.forName("UTF-8");
|
||||
|
||||
private final Charset charset;
|
||||
|
||||
private final Supplier<ByteBuffer> supplier;
|
||||
|
||||
private ByteBuffer[] buffers;
|
||||
|
||||
private int index;
|
||||
|
||||
protected JsonByteBufferWriter(Supplier<ByteBuffer> supplier) {
|
||||
this(null, supplier);
|
||||
}
|
||||
|
||||
protected JsonByteBufferWriter(Charset charset, Supplier<ByteBuffer> supplier) {
|
||||
this.charset = UTF8.equals(charset) ? null : charset;
|
||||
this.supplier = supplier;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonByteBufferWriter setTiny(boolean tiny) {
|
||||
this.tiny = tiny;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean recycle() {
|
||||
this.index = 0;
|
||||
this.buffers = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
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 int count() {
|
||||
if (this.buffers == null) return 0;
|
||||
int len = 0;
|
||||
for (ByteBuffer buffer : buffers) {
|
||||
len += buffer.remaining();
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
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 void writeTo(final char ch) {
|
||||
if (ch > Byte.MAX_VALUE) throw new RuntimeException("writeTo char(int.value = " + (int) ch + ") must be less 127");
|
||||
expand(1);
|
||||
this.buffers[index].put((byte) ch);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeTo(final char[] chs, final int start, final int len) {
|
||||
writeTo(-1, false, chs, start, len);
|
||||
}
|
||||
|
||||
private void writeTo(int expandsize, final boolean quote, final char[] chs, final int start, final int len) {
|
||||
int byteLength = quote ? 2 : 0;
|
||||
ByteBuffer bb = null;
|
||||
if (charset == null) {
|
||||
byteLength += encodeUTF8Length(chs, start, len);
|
||||
} else {
|
||||
bb = charset.encode(CharBuffer.wrap(chs, start, len));
|
||||
byteLength += bb.remaining();
|
||||
}
|
||||
if (expandsize < 0) expandsize = expand(byteLength);
|
||||
if (expandsize == 0) { // 只需要一个buffer
|
||||
final ByteBuffer buffer = this.buffers[index];
|
||||
if (quote) buffer.put((byte) '"');
|
||||
|
||||
if (charset == null) { //UTF-8
|
||||
final int limit = start + len;
|
||||
for (int i = start; i < limit; i++) {
|
||||
char c = chs[i];
|
||||
if (c < 0x80) {
|
||||
buffer.put((byte) c);
|
||||
} else if (c < 0x800) {
|
||||
buffer.put((byte) (0xc0 | (c >> 6)));
|
||||
buffer.put((byte) (0x80 | (c & 0x3f)));
|
||||
} else {
|
||||
buffer.put((byte) (0xe0 | ((c >> 12))));
|
||||
buffer.put((byte) (0x80 | ((c >> 6) & 0x3f)));
|
||||
buffer.put((byte) (0x80 | (c & 0x3f)));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
buffer.put(bb);
|
||||
}
|
||||
|
||||
if (quote) buffer.put((byte) '"');
|
||||
return;
|
||||
}
|
||||
ByteBuffer buffer = this.buffers[index];
|
||||
if (quote) {
|
||||
if (!buffer.hasRemaining()) buffer = nextByteBuffer();
|
||||
buffer.put((byte) '"');
|
||||
}
|
||||
if (charset == null) { //UTF-8
|
||||
final int limit = start + len;
|
||||
for (int i = start; i < limit; i++) {
|
||||
buffer = putChar(buffer, chs[i]);
|
||||
}
|
||||
} else {
|
||||
while (bb.hasRemaining()) {
|
||||
if (!buffer.hasRemaining()) buffer = nextByteBuffer();
|
||||
buffer.put(bb.get());
|
||||
}
|
||||
}
|
||||
if (quote) {
|
||||
if (!buffer.hasRemaining()) buffer = nextByteBuffer();
|
||||
buffer.put((byte) '"');
|
||||
}
|
||||
}
|
||||
|
||||
private ByteBuffer putChar(ByteBuffer buffer, char c) {
|
||||
if (c < 0x80) {
|
||||
if (!buffer.hasRemaining()) buffer = nextByteBuffer();
|
||||
buffer.put((byte) c);
|
||||
} else if (c < 0x800) {
|
||||
if (!buffer.hasRemaining()) buffer = nextByteBuffer();
|
||||
buffer.put((byte) (0xc0 | (c >> 6)));
|
||||
if (!buffer.hasRemaining()) buffer = nextByteBuffer();
|
||||
buffer.put((byte) (0x80 | (c & 0x3f)));
|
||||
} else {
|
||||
if (!buffer.hasRemaining()) buffer = nextByteBuffer();
|
||||
buffer.put((byte) (0xe0 | ((c >> 12))));
|
||||
if (!buffer.hasRemaining()) buffer = nextByteBuffer();
|
||||
buffer.put((byte) (0x80 | ((c >> 6) & 0x3f)));
|
||||
if (!buffer.hasRemaining()) buffer = nextByteBuffer();
|
||||
buffer.put((byte) (0x80 | (c & 0x3f)));
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
|
||||
private ByteBuffer nextByteBuffer() {
|
||||
this.buffers[this.index].flip();
|
||||
return this.buffers[++this.index];
|
||||
}
|
||||
|
||||
private static int encodeUTF8Length(final char[] text, final int start, final int len) {
|
||||
char c;
|
||||
int size = 0;
|
||||
final char[] chars = text;
|
||||
final int limit = start + len;
|
||||
for (int i = start; i < limit; i++) {
|
||||
c = chars[i];
|
||||
size += (c < 0x80 ? 1 : (c < 0x800 ? 2 : 3));
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
private static int encodeEscapeUTF8Length(final char[] text, final int start, final int len) {
|
||||
char c;
|
||||
int size = 0;
|
||||
final char[] chars = text;
|
||||
final int limit = start + len;
|
||||
for (int i = start; i < limit; i++) {
|
||||
c = chars[i];
|
||||
switch (c) {
|
||||
case '\n': size += 2;
|
||||
break;
|
||||
case '\r': size += 2;
|
||||
break;
|
||||
case '\t': size += 2;
|
||||
break;
|
||||
case '\\': size += 2;
|
||||
break;
|
||||
case '"': size += 2;
|
||||
break;
|
||||
default:
|
||||
size += (c < 0x80 ? 1 : (c < 0x800 ? 2 : 3));
|
||||
break;
|
||||
}
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
/**
|
||||
* <b>注意:</b> 该String值不能为null且不会进行转义, 只用于不含需要转义字符的字符串,例如enum、double、BigInteger转换的String
|
||||
*
|
||||
* @param quote
|
||||
* @param value
|
||||
*/
|
||||
@Override
|
||||
public void writeTo(final boolean quote, final String value) {
|
||||
char[] chs = Utility.charArray(value);
|
||||
writeTo(-1, quote, chs, 0, chs.length);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeString(String value) {
|
||||
if (value == null) {
|
||||
writeNull();
|
||||
return;
|
||||
}
|
||||
final char[] chs = Utility.charArray(value);
|
||||
int len = 0;
|
||||
for (char ch : chs) {
|
||||
switch (ch) {
|
||||
case '\n': len += 2;
|
||||
break;
|
||||
case '\r': len += 2;
|
||||
break;
|
||||
case '\t': len += 2;
|
||||
break;
|
||||
case '\\': len += 2;
|
||||
break;
|
||||
case '"': len += 2;
|
||||
break;
|
||||
default: len++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (len == chs.length) {
|
||||
writeTo(-1, true, chs, 0, len);
|
||||
return;
|
||||
}
|
||||
int expandsize = -1;
|
||||
if (this.charset == null) { //UTF-8
|
||||
final int byteLength = 2 + encodeEscapeUTF8Length(chs, 0, chs.length);
|
||||
expandsize = expand(byteLength);
|
||||
if (expandsize == 0) { // 只需要一个buffer
|
||||
final ByteBuffer buffer = this.buffers[index];
|
||||
buffer.put((byte) '"');
|
||||
for (char c : chs) {
|
||||
switch (c) {
|
||||
case '\n': buffer.put((byte) '\\').put((byte) 'n');
|
||||
break;
|
||||
case '\r': buffer.put((byte) '\\').put((byte) 'r');
|
||||
break;
|
||||
case '\t': buffer.put((byte) '\\').put((byte) 't');
|
||||
break;
|
||||
case '\\': buffer.put((byte) '\\').put((byte) '\\');
|
||||
break;
|
||||
case '"': buffer.put((byte) '\\').put((byte) '"');
|
||||
break;
|
||||
default:
|
||||
if (c < 0x80) {
|
||||
buffer.put((byte) c);
|
||||
} else if (c < 0x800) {
|
||||
buffer.put((byte) (0xc0 | (c >> 6)));
|
||||
buffer.put((byte) (0x80 | (c & 0x3f)));
|
||||
} else {
|
||||
buffer.put((byte) (0xe0 | ((c >> 12))));
|
||||
buffer.put((byte) (0x80 | ((c >> 6) & 0x3f)));
|
||||
buffer.put((byte) (0x80 | (c & 0x3f)));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
buffer.put((byte) '"');
|
||||
return;
|
||||
}
|
||||
}
|
||||
StringBuilder sb = new StringBuilder(len);
|
||||
for (char ch : chs) {
|
||||
switch (ch) {
|
||||
case '\n': sb.append("\\n");
|
||||
break;
|
||||
case '\r': sb.append("\\r");
|
||||
break;
|
||||
case '\t': sb.append("\\t");
|
||||
break;
|
||||
case '\\': sb.append("\\\\");
|
||||
break;
|
||||
case '"': sb.append("\\\"");
|
||||
break;
|
||||
default: sb.append(ch);
|
||||
break;
|
||||
}
|
||||
}
|
||||
char[] cs = Utility.charArray(sb);
|
||||
writeTo(expandsize, true, cs, 0, sb.length());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeField(boolean comma, Attribute attribute) {
|
||||
if (comma) writeTo(',');
|
||||
writeTo(true, attribute.field());
|
||||
writeTo(':');
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeSmallString(String value) {
|
||||
writeTo(false, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return Objects.toString(this);
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,8 @@ package com.wentch.redkale.convert.json;
|
||||
import com.wentch.redkale.convert.*;
|
||||
import com.wentch.redkale.util.*;
|
||||
import java.lang.reflect.*;
|
||||
import java.nio.*;
|
||||
import java.nio.charset.*;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -30,6 +32,22 @@ public final class JsonConvert extends Convert<JsonReader, JsonWriter> {
|
||||
this.tiny = tiny;
|
||||
}
|
||||
|
||||
public JsonByteBufferWriter pollJsonWriter(final Supplier<ByteBuffer> supplier) {
|
||||
return new JsonByteBufferWriter(supplier).setTiny(tiny);
|
||||
}
|
||||
|
||||
public JsonByteBufferWriter pollJsonWriter(final Charset charset, final Supplier<ByteBuffer> supplier) {
|
||||
return new JsonByteBufferWriter(charset, supplier).setTiny(tiny);
|
||||
}
|
||||
|
||||
public JsonWriter pollJsonWriter() {
|
||||
return writerPool.get().setTiny(tiny);
|
||||
}
|
||||
|
||||
public void offerJsonWriter(JsonWriter out) {
|
||||
if (out != null) writerPool.offer(out);
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonFactory getFactory() {
|
||||
return (JsonFactory) factory;
|
||||
@@ -57,8 +75,7 @@ public final class JsonConvert extends Convert<JsonReader, JsonWriter> {
|
||||
public String convertTo(final Type type, Object value) {
|
||||
if (type == null) return null;
|
||||
if (value == null) return "null";
|
||||
final JsonWriter out = writerPool.get();
|
||||
out.setTiny(tiny);
|
||||
final JsonWriter out = writerPool.get().setTiny(tiny);
|
||||
factory.loadEncoder(type).convertTo(out, value);
|
||||
String result = out.toString();
|
||||
writerPool.offer(out);
|
||||
@@ -70,19 +87,50 @@ public final class JsonConvert extends Convert<JsonReader, JsonWriter> {
|
||||
return convertTo(value.getClass(), value);
|
||||
}
|
||||
|
||||
public byte[] convertToUTF8Bytes(Object value) {
|
||||
if (value == null) return new byte[]{110, 117, 108, 108};
|
||||
return convertToUTF8Bytes(value.getClass(), value);
|
||||
public void convertTo(final JsonWriter out, final Type type, Object value) {
|
||||
if (type == null) return;
|
||||
if (value == null) {
|
||||
out.writeNull();
|
||||
} else {
|
||||
factory.loadEncoder(type).convertTo(out, value);
|
||||
}
|
||||
}
|
||||
|
||||
public byte[] convertToUTF8Bytes(final Type type, Object value) {
|
||||
if (type == null) return null;
|
||||
if (value == null) return new byte[]{110, 117, 108, 108};
|
||||
final JsonWriter out = writerPool.get();
|
||||
out.setTiny(tiny);
|
||||
factory.loadEncoder(type).convertTo(out, value);
|
||||
byte[] result = out.toUTF8Bytes();
|
||||
writerPool.offer(out);
|
||||
return result;
|
||||
public void convertTo(final JsonWriter out, Object value) {
|
||||
if (value == null) {
|
||||
out.writeNull();
|
||||
} else {
|
||||
factory.loadEncoder(value.getClass()).convertTo(out, value);
|
||||
}
|
||||
}
|
||||
|
||||
public ByteBuffer[] convertTo(final Supplier<ByteBuffer> supplier, final Type type, Object value) {
|
||||
return convertTo(null, supplier, type, value);
|
||||
}
|
||||
|
||||
public ByteBuffer[] convertTo(final Charset charset, final Supplier<ByteBuffer> supplier, final Type type, Object value) {
|
||||
if (supplier == null || type == null) return null;
|
||||
JsonByteBufferWriter out = new JsonByteBufferWriter(charset, 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) {
|
||||
return convertTo(null, supplier, value);
|
||||
}
|
||||
|
||||
public ByteBuffer[] convertTo(final Charset charset, final Supplier<ByteBuffer> supplier, Object value) {
|
||||
if (supplier == null) return null;
|
||||
JsonByteBufferWriter out = new JsonByteBufferWriter(charset, supplier);
|
||||
if (value == null) {
|
||||
out.writeNull();
|
||||
} else {
|
||||
factory.loadEncoder(value.getClass()).convertTo(out, value);
|
||||
}
|
||||
return out.toBuffers();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ package com.wentch.redkale.convert.json;
|
||||
|
||||
import com.wentch.redkale.convert.*;
|
||||
import com.wentch.redkale.util.*;
|
||||
import java.nio.*;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -14,7 +15,7 @@ import com.wentch.redkale.util.*;
|
||||
*
|
||||
* @author zhangjx
|
||||
*/
|
||||
public final class JsonWriter implements Writer {
|
||||
public class JsonWriter implements Writer {
|
||||
|
||||
private static final char[] CHARS_TUREVALUE = "true".toCharArray();
|
||||
|
||||
@@ -22,7 +23,7 @@ public final class JsonWriter implements Writer {
|
||||
|
||||
private static final int defaultSize = Integer.getInteger("convert.json.writer.buffer.defsize", 1024);
|
||||
|
||||
protected int count;
|
||||
private int count;
|
||||
|
||||
private char[] content;
|
||||
|
||||
@@ -57,8 +58,9 @@ public final class JsonWriter implements Writer {
|
||||
return tiny;
|
||||
}
|
||||
|
||||
public void setTiny(boolean tiny) {
|
||||
public JsonWriter setTiny(boolean tiny) {
|
||||
this.tiny = tiny;
|
||||
return this;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
@@ -69,7 +71,7 @@ public final class JsonWriter implements Writer {
|
||||
* @param len
|
||||
* @return
|
||||
*/
|
||||
public char[] expand(int len) {
|
||||
private char[] expand(int len) {
|
||||
int newcount = count + len;
|
||||
if (newcount <= content.length) return content;
|
||||
char[] newdata = new char[Math.max(content.length * 3 / 2, newcount)];
|
||||
@@ -78,20 +80,12 @@ public final class JsonWriter implements Writer {
|
||||
return newdata;
|
||||
}
|
||||
|
||||
public void writeTo(final char ch) {
|
||||
public void writeTo(final char ch) { //只能是 0 - 127 的字符
|
||||
expand(1);
|
||||
content[count++] = ch;
|
||||
}
|
||||
|
||||
public void writeTo(final char... chs) {
|
||||
int len = chs.length;
|
||||
expand(len);
|
||||
System.arraycopy(chs, 0, content, count, len);
|
||||
count += len;
|
||||
}
|
||||
|
||||
public void writeTo(final char[] chs, final int start, final int end) {
|
||||
int len = end - start;
|
||||
public void writeTo(final char[] chs, final int start, final int len) { //只能是 0 - 127 的字符
|
||||
expand(len);
|
||||
System.arraycopy(chs, start, content, count, len);
|
||||
count += len;
|
||||
@@ -120,88 +114,14 @@ public final class JsonWriter implements Writer {
|
||||
return true;
|
||||
}
|
||||
|
||||
public char[] toArray() {
|
||||
if (count == content.length) return content;
|
||||
char[] newdata = new char[count];
|
||||
System.arraycopy(content, 0, newdata, 0, count);
|
||||
return newdata;
|
||||
public ByteBuffer[] toBuffers() {
|
||||
return new ByteBuffer[]{ByteBuffer.wrap(Utility.encodeUTF8(content, 0, count))};
|
||||
}
|
||||
|
||||
public byte[] toUTF8Bytes() {
|
||||
return Utility.encodeUTF8(content, 0, count);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
public final int count() {
|
||||
public int count() {
|
||||
return this.count;
|
||||
}
|
||||
|
||||
public final void count(int count) {
|
||||
if (count >= 0) this.count = count;
|
||||
}
|
||||
|
||||
// @SuppressWarnings("unchecked")
|
||||
// public final boolean writeRefer(final Object value) {
|
||||
// if (stack == null) return false;
|
||||
// int index = stack.indexOf(value);
|
||||
// if (index > -1) {
|
||||
// int deep = stack.size() - index;
|
||||
// if (deep < 0) throw new ConvertException("the refer deep value(" + deep + ") is illegal");
|
||||
// writeTo('{', '"', '@', '"', ':', '"');
|
||||
// for (int i = 0; i < deep; i++) {
|
||||
// writeTo('@');
|
||||
// }
|
||||
// writeTo('"', '}');
|
||||
// return true;
|
||||
// }
|
||||
// return false;
|
||||
// }
|
||||
//-----------------------------------------------------------------------
|
||||
@Override
|
||||
public String toString() {
|
||||
return new String(content, 0, count);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeBoolean(boolean value) {
|
||||
writeTo(value ? CHARS_TUREVALUE : CHARS_FALSEVALUE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeByte(byte value) {
|
||||
writeInt(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeChar(char value) {
|
||||
writeInt(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeShort(short value) {
|
||||
writeInt(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeInt(int value) {
|
||||
writeSmallString(String.valueOf(value));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeLong(long value) {
|
||||
writeSmallString(String.valueOf(value));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeFloat(float value) {
|
||||
writeSmallString(String.valueOf(value));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeDouble(double value) {
|
||||
writeSmallString(String.valueOf(value));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeString(String value) {
|
||||
if (value == null) {
|
||||
@@ -235,7 +155,69 @@ public final class JsonWriter implements Writer {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void wirteClassName(String clazz) {
|
||||
public void writeField(boolean comma, Attribute attribute) {
|
||||
if (comma) writeTo(',');
|
||||
writeTo(true, attribute.field());
|
||||
writeTo(':');
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeSmallString(String value) {
|
||||
writeTo(false, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new String(content, 0, count);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------
|
||||
public final void writeTo(final char... chs) { //只能是 0 - 127 的字符
|
||||
writeTo(chs, 0, chs.length);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void writeBoolean(boolean value) {
|
||||
writeTo(value ? CHARS_TUREVALUE : CHARS_FALSEVALUE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void writeByte(byte value) {
|
||||
writeInt(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void writeChar(char value) {
|
||||
writeInt(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void writeShort(short value) {
|
||||
writeInt(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void writeInt(int value) {
|
||||
writeSmallString(String.valueOf(value));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void writeLong(long value) {
|
||||
writeSmallString(String.valueOf(value));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void writeFloat(float value) {
|
||||
writeSmallString(String.valueOf(value));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void writeDouble(double value) {
|
||||
writeSmallString(String.valueOf(value));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void wirteClassName(String clazz) {
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -248,52 +230,38 @@ public final class JsonWriter implements Writer {
|
||||
writeTo('}');
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void writeField(boolean comma, Attribute attribute) {
|
||||
if (comma) writeTo(',');
|
||||
writeTo('"');
|
||||
writeSmallString(attribute.field());
|
||||
writeTo('"');
|
||||
writeTo(':');
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void writeNull() {
|
||||
writeTo('n', 'u', 'l', 'l');
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeArrayB(int size) {
|
||||
public final void writeArrayB(int size) {
|
||||
writeTo('[');
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeArrayMark() {
|
||||
public final void writeArrayMark() {
|
||||
writeTo(',');
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeArrayE() {
|
||||
public final void writeArrayE() {
|
||||
writeTo(']');
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeMapB(int size) {
|
||||
public final void writeMapB(int size) {
|
||||
writeTo('{');
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeMapMark() {
|
||||
public final void writeMapMark() {
|
||||
writeTo(':');
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeMapE() {
|
||||
public final void writeMapE() {
|
||||
writeTo('}');
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeSmallString(String value) {
|
||||
writeTo(false, value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,8 @@ import javax.net.ssl.*;
|
||||
*/
|
||||
public class WebSocketClient {
|
||||
|
||||
protected final boolean ssl;
|
||||
|
||||
protected final URI uri;
|
||||
|
||||
protected final Map<String, String> headers = new HashMap<String, String>();
|
||||
@@ -32,6 +34,7 @@ public class WebSocketClient {
|
||||
|
||||
private WebSocketClient(URI uri, Map<String, String> headers0) {
|
||||
this.uri = uri;
|
||||
this.ssl = "wss".equalsIgnoreCase(uri.getScheme());
|
||||
if (headers0 != null) this.headers.putAll(headers0);
|
||||
}
|
||||
|
||||
@@ -65,26 +68,28 @@ public class WebSocketClient {
|
||||
public int getPort() {
|
||||
int port = uri.getPort();
|
||||
if (port > 0) return port;
|
||||
return "wss".equalsIgnoreCase(uri.getScheme()) ? 443 : 80;
|
||||
return ssl ? 443 : 80;
|
||||
}
|
||||
|
||||
public void connect() throws IOException {
|
||||
if ("wss".equalsIgnoreCase(uri.getScheme())) {
|
||||
if (ssl) {
|
||||
if (proxy == null) {
|
||||
this.socket = (sslContext == null ? Utility.getDefaultSSLContext() : sslContext).getSocketFactory().createSocket(uri.getHost(), getPort());
|
||||
} else {
|
||||
Socket s = new Socket(proxy);
|
||||
this.socket.setSoTimeout(3000);
|
||||
s.connect(new InetSocketAddress(uri.getHost(), getPort()));
|
||||
this.socket = (sslContext == null ? Utility.getDefaultSSLContext() : sslContext).getSocketFactory().createSocket(s, uri.getHost(), getPort(), true);
|
||||
}
|
||||
} else {
|
||||
this.socket = proxy == null ? new Socket() : new Socket(proxy);
|
||||
this.socket.setSoTimeout(3000);
|
||||
this.socket.connect(new InetSocketAddress(uri.getHost(), getPort()));
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
URI uri = new URI("ws://10.28.2.207/pipes/ws/listen?test=aa");
|
||||
URI uri = new URI("ws://10.28.2.207:5050/pipes/ws/listen?test=aa");
|
||||
WebSocketClient client = WebSocketClient.create(uri);
|
||||
client.connect();
|
||||
System.out.println();
|
||||
|
||||
@@ -255,6 +255,13 @@ public final class Utility {
|
||||
return value == null ? null : value.toCharArray();
|
||||
}
|
||||
|
||||
public static char[] charArray(StringBuilder value) {
|
||||
if (value == null) return null;
|
||||
char[] chs = new char[value.length()];
|
||||
value.getChars(0, value.length(), chs, 0);
|
||||
return chs;
|
||||
}
|
||||
|
||||
public static ByteBuffer encodeUTF8(final ByteBuffer buffer, final char[] array) {
|
||||
return encodeUTF8(buffer, array, 0, array.length);
|
||||
}
|
||||
@@ -327,7 +334,7 @@ public final class Utility {
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
public static javax.net.ssl.SSLContext getDefaultSSLContext(){
|
||||
public static javax.net.ssl.SSLContext getDefaultSSLContext() {
|
||||
return DEFAULTSSL_CONTEXT;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user