diff --git a/src/org/redkale/convert/EnMember.java b/src/org/redkale/convert/EnMember.java index 0ad09931a..9a2635710 100644 --- a/src/org/redkale/convert/EnMember.java +++ b/src/org/redkale/convert/EnMember.java @@ -41,7 +41,7 @@ public final class EnMember implements Comparable { return convert; } - public void setTiny(boolean tiny) { + public Factory tiny(boolean tiny) { this.tiny = tiny; + return this; } public ConvertColumnEntry findRef(AccessibleObject field) { diff --git a/src/org/redkale/convert/Writer.java b/src/org/redkale/convert/Writer.java index d517863aa..b271b8739 100644 --- a/src/org/redkale/convert/Writer.java +++ b/src/org/redkale/convert/Writer.java @@ -21,7 +21,7 @@ public interface Writer { * * @return 是否简化 */ - public boolean isTiny(); + public boolean tiny(); /** * 输出null值 diff --git a/src/org/redkale/convert/bson/BsonByteBufferReader.java b/src/org/redkale/convert/bson/BsonByteBufferReader.java index 97dafc419..f9ecc131a 100644 --- a/src/org/redkale/convert/bson/BsonByteBufferReader.java +++ b/src/org/redkale/convert/bson/BsonByteBufferReader.java @@ -14,7 +14,7 @@ import org.redkale.util.*; * * @author zhangjx */ -public final class BsonByteBufferReader extends BsonReader { +public class BsonByteBufferReader extends BsonReader { private ByteBuffer[] buffers; @@ -24,7 +24,7 @@ public final class BsonByteBufferReader extends BsonReader { protected BsonByteBufferReader(ByteBuffer... buffers) { this.buffers = buffers; - this.currentBuffer = buffers[currentIndex]; + if (buffers != null && buffers.length > 0) this.currentBuffer = buffers[currentIndex]; } @Override @@ -47,7 +47,7 @@ public final class BsonByteBufferReader extends BsonReader { * @return 数组长度或 SIGN_NULL */ @Override - public int readArrayB() { + public final int readArrayB() { short bt = readShort(); if (bt == Reader.SIGN_NULL) return bt; short lt = readShort(); @@ -56,7 +56,7 @@ public final class BsonByteBufferReader extends BsonReader { //------------------------------------------------------------ @Override - public boolean readBoolean() { + public final boolean readBoolean() { return readByte() == 1; } @@ -76,41 +76,49 @@ public final class BsonByteBufferReader extends BsonReader { } @Override - public char readChar() { - int remain = this.currentBuffer.remaining(); - if (remain >= 2) { - this.position += 2; - return this.currentBuffer.getChar(); + public final char readChar() { + if (this.currentBuffer != null) { + int remain = this.currentBuffer.remaining(); + if (remain >= 2) { + this.position += 2; + return this.currentBuffer.getChar(); + } } return (char) ((0xff00 & (readByte() << 8)) | (0xff & readByte())); } @Override - public short readShort() { - int remain = this.currentBuffer.remaining(); - if (remain >= 2) { - this.position += 2; - return this.currentBuffer.getShort(); + public final short readShort() { + if (this.currentBuffer != null) { + int remain = this.currentBuffer.remaining(); + if (remain >= 2) { + this.position += 2; + return this.currentBuffer.getShort(); + } } return (short) ((0xff00 & (readByte() << 8)) | (0xff & readByte())); } @Override - public int readInt() { - int remain = this.currentBuffer.remaining(); - if (remain >= 4) { - this.position += 4; - return this.currentBuffer.getInt(); + public final int readInt() { + if (this.currentBuffer != null) { + int remain = this.currentBuffer.remaining(); + if (remain >= 4) { + this.position += 4; + return this.currentBuffer.getInt(); + } } return ((readByte() & 0xff) << 24) | ((readByte() & 0xff) << 16) | ((readByte() & 0xff) << 8) | (readByte() & 0xff); } @Override - public long readLong() { - int remain = this.currentBuffer.remaining(); - if (remain >= 8) { - this.position += 8; - return this.currentBuffer.getLong(); + public final long readLong() { + if (this.currentBuffer != null) { + int remain = this.currentBuffer.remaining(); + if (remain >= 8) { + this.position += 8; + return this.currentBuffer.getLong(); + } } return ((((long) readByte() & 0xff) << 56) | (((long) readByte() & 0xff) << 48) @@ -128,7 +136,7 @@ public final class BsonByteBufferReader extends BsonReader { return bs; } - protected void read(final byte[] bs, final int pos) { + private void read(final byte[] bs, final int pos) { int remain = this.currentBuffer.remaining(); if (remain < 1) { this.currentBuffer = this.buffers[++this.currentIndex]; @@ -148,14 +156,14 @@ public final class BsonByteBufferReader extends BsonReader { } @Override - public String readSmallString() { + public final String readSmallString() { int len = 0xff & readByte(); if (len == 0) return ""; return new String(read(len)); } @Override - public String readString() { + public final String readString() { int len = readInt(); if (len == SIGN_NULL) return null; if (len == 0) return ""; diff --git a/src/org/redkale/convert/bson/BsonByteBufferWriter.java b/src/org/redkale/convert/bson/BsonByteBufferWriter.java index ab3f1aa41..540da7513 100644 --- a/src/org/redkale/convert/bson/BsonByteBufferWriter.java +++ b/src/org/redkale/convert/bson/BsonByteBufferWriter.java @@ -10,10 +10,12 @@ import java.util.function.*; /** * - *

详情见: http://www.redkale.org + *

+ * 详情见: http://www.redkale.org + * * @author zhangjx */ -public final class BsonByteBufferWriter extends BsonWriter { +public class BsonByteBufferWriter extends BsonWriter { private final Supplier supplier; @@ -21,8 +23,9 @@ public final class BsonByteBufferWriter extends BsonWriter { private int index; - protected BsonByteBufferWriter(Supplier supplier) { + protected BsonByteBufferWriter(boolean tiny, Supplier supplier) { super((byte[]) null); + this.tiny = tiny; this.supplier = supplier; } @@ -56,7 +59,7 @@ public final class BsonByteBufferWriter extends BsonWriter { } @Override - public BsonByteBufferWriter setTiny(boolean tiny) { + public BsonByteBufferWriter tiny(boolean tiny) { this.tiny = tiny; return this; } diff --git a/src/org/redkale/convert/bson/BsonConvert.java b/src/org/redkale/convert/bson/BsonConvert.java index 5157e7b77..9c26ab4c1 100644 --- a/src/org/redkale/convert/bson/BsonConvert.java +++ b/src/org/redkale/convert/bson/BsonConvert.java @@ -5,6 +5,7 @@ */ package org.redkale.convert.bson; +import java.io.*; import java.lang.reflect.*; import java.nio.*; import java.util.function.*; @@ -49,16 +50,18 @@ public final class BsonConvert extends Convert { this.tiny = tiny; } - public BsonByteBufferWriter pollBsonWriter(final Supplier supplier) { - return new BsonByteBufferWriter(supplier).setTiny(tiny); + @Override + public BsonFactory getFactory() { + return (BsonFactory) factory; } - public BsonWriter pollBsonWriter() { - return writerPool.get().setTiny(tiny); + //------------------------------ reader ----------------------------------------------------------- + public BsonReader pollBsonReader(final ByteBuffer... buffers) { + return new BsonByteBufferReader(buffers); } - public void offerBsonWriter(BsonWriter out) { - if (out != null) writerPool.offer(out); + public BsonReader pollBsonReader(final InputStream in) { + return new BsonStreamReader(in); } public BsonReader pollBsonReader() { @@ -69,6 +72,24 @@ public final class BsonConvert extends Convert { if (in != null) readerPool.offer(in); } + //------------------------------ writer ----------------------------------------------------------- + public BsonByteBufferWriter pollBsonWriter(final Supplier supplier) { + return new BsonByteBufferWriter(tiny, supplier); + } + + public BsonWriter pollBsonWriter(final OutputStream out) { + return new BsonStreamWriter(tiny, out); + } + + public BsonWriter pollBsonWriter() { + return writerPool.get().tiny(tiny); + } + + public void offerBsonWriter(BsonWriter out) { + if (out != null) writerPool.offer(out); + } + + //------------------------------ convertFrom ----------------------------------------------------------- public T convertFrom(final Type type, final byte[] bytes) { if (bytes == null) return null; return convertFrom(type, bytes, 0, bytes.length); @@ -89,6 +110,11 @@ public final class BsonConvert extends Convert { return (T) factory.loadDecoder(type).convertFrom(new BsonByteBufferReader(buffers)); } + public T convertFrom(final Type type, final InputStream in) { + if (type == null || in == null) return null; + return (T) factory.loadDecoder(type).convertFrom(new BsonStreamReader(in)); + } + public T convertFrom(final BsonReader in, final Type type) { if (type == null) return null; @SuppressWarnings("unchecked") @@ -96,42 +122,27 @@ public final class BsonConvert extends Convert { return rs; } + //------------------------------ convertTo ----------------------------------------------------------- + public byte[] convertTo(Object value) { + if (value == null) { + final BsonWriter out = writerPool.get().tiny(tiny); + out.writeNull(); + byte[] result = out.toArray(); + writerPool.offer(out); + return result; + } + return convertTo(value.getClass(), value); + } + public byte[] convertTo(final Type type, Object value) { if (type == null) return null; - final BsonWriter out = writerPool.get().setTiny(tiny); + final BsonWriter out = writerPool.get().tiny(tiny); factory.loadEncoder(type).convertTo(out, value); byte[] result = out.toArray(); writerPool.offer(out); return result; } - public void convertTo(final BsonWriter out, final Type type, Object value) { - if (type == null) return; - factory.loadEncoder(type).convertTo(out, value); - } - - public ByteBuffer[] convertTo(final Supplier 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 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(); @@ -140,26 +151,60 @@ public final class BsonConvert extends Convert { } } - public byte[] convertTo(Object value) { - if (value == null) { - final BsonWriter out = writerPool.get().setTiny(tiny); - out.writeNull(); - byte[] result = out.toArray(); - writerPool.offer(out); - return result; - } - return convertTo(value.getClass(), value); + public void convertTo(final BsonWriter out, final Type type, Object value) { + if (type == null) return; + factory.loadEncoder(type).convertTo(out, value); } - public BsonWriter convertToWriter(final Type type, Object value) { - if (type == null) return null; - final BsonWriter out = writerPool.get().setTiny(tiny); - factory.loadEncoder(type).convertTo(out, value); - return out; + public void convertTo(final OutputStream out, Object value) { + if (value == null) { + new BsonStreamWriter(tiny, out).writeNull(); + } else { + factory.loadEncoder(value.getClass()).convertTo(new BsonStreamWriter(tiny, out), value); + } + } + + public void convertTo(final OutputStream out, final Type type, Object value) { + if (type == null) return; + if (value == null) { + new BsonStreamWriter(tiny, out).writeNull(); + } else { + factory.loadEncoder(type).convertTo(new BsonStreamWriter(tiny, out), value); + } + } + + public ByteBuffer[] convertTo(final Supplier supplier, final Type type, Object value) { + if (supplier == null || type == null) return null; + BsonByteBufferWriter out = new BsonByteBufferWriter(tiny, supplier); + if (value == null) { + out.writeNull(); + } else { + factory.loadEncoder(type).convertTo(out, value); + } + return out.toBuffers(); + } + + public ByteBuffer[] convertTo(final Supplier supplier, Object value) { + if (supplier == null) return null; + BsonByteBufferWriter out = new BsonByteBufferWriter(tiny, supplier); + if (value == null) { + out.writeNull(); + } else { + factory.loadEncoder(value.getClass()).convertTo(out, value); + } + return out.toBuffers(); } public BsonWriter convertToWriter(Object value) { if (value == null) return null; return convertToWriter(value.getClass(), value); } + + public BsonWriter convertToWriter(final Type type, Object value) { + if (type == null) return null; + final BsonWriter out = writerPool.get().tiny(tiny); + factory.loadEncoder(type).convertTo(out, value); + return out; + } + } diff --git a/src/org/redkale/convert/bson/BsonFactory.java b/src/org/redkale/convert/bson/BsonFactory.java index 15ecee02e..62441c712 100644 --- a/src/org/redkale/convert/bson/BsonFactory.java +++ b/src/org/redkale/convert/bson/BsonFactory.java @@ -10,7 +10,9 @@ import org.redkale.convert.*; /** * - *

详情见: http://www.redkale.org + *

+ * 详情见: http://www.redkale.org + * * @author zhangjx */ public final class BsonFactory extends Factory { @@ -30,6 +32,12 @@ public final class BsonFactory extends Factory { super(parent, tiny); } + @Override + public BsonFactory tiny(boolean tiny) { + this.tiny = tiny; + return this; + } + public static BsonFactory root() { return instance; } diff --git a/src/org/redkale/convert/bson/BsonStreamReader.java b/src/org/redkale/convert/bson/BsonStreamReader.java new file mode 100644 index 000000000..cd314d3dc --- /dev/null +++ b/src/org/redkale/convert/bson/BsonStreamReader.java @@ -0,0 +1,60 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package org.redkale.convert.bson; + +import java.io.*; +import org.redkale.convert.*; + +/** + * + * @author zhangjx + */ +class BsonStreamReader extends BsonByteBufferReader { + + private InputStream in; + + private byte currByte; + + protected BsonStreamReader(InputStream in) { + this.in = in; + } + + @Override + protected boolean recycle() { + super.recycle(); // this.position 初始化值为-1 + this.in = null; + this.currByte = 0; + return false; + } + + @Override + public byte readByte() { + try { + byte b = (currByte = (byte) in.read()); + this.position++; + return b; + } catch (IOException e) { + throw new ConvertException(e); + } + } + + @Override + protected byte currentByte() { + return currByte; + } + + @Override + protected byte[] read(final int len) { + byte[] bs = new byte[len]; + try { + in.read(bs); + this.position += len; + } catch (IOException e) { + throw new ConvertException(e); + } + return bs; + } +} diff --git a/src/org/redkale/convert/bson/BsonStreamWriter.java b/src/org/redkale/convert/bson/BsonStreamWriter.java new file mode 100644 index 000000000..c0c22fd10 --- /dev/null +++ b/src/org/redkale/convert/bson/BsonStreamWriter.java @@ -0,0 +1,48 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package org.redkale.convert.bson; + +import java.io.*; +import org.redkale.convert.*; + +/** + * + * @author zhangjx + */ +class BsonStreamWriter extends BsonByteBufferWriter { + + private OutputStream out; + + protected BsonStreamWriter(boolean tiny, OutputStream out) { + super(tiny, null); + this.out = out; + } + + @Override + protected boolean recycle() { + super.recycle(); + this.out = null; + return false; + } + + @Override + public void writeTo(final byte[] chs, final int start, final int len) { + try { + out.write(chs, start, len); + } catch (IOException e) { + throw new ConvertException(e); + } + } + + @Override + public void writeTo(final byte ch) { + try { + out.write((byte) ch); + } catch (IOException e) { + throw new ConvertException(e); + } + } +} diff --git a/src/org/redkale/convert/bson/BsonWriter.java b/src/org/redkale/convert/bson/BsonWriter.java index fb6ad4fb0..e5de19e23 100644 --- a/src/org/redkale/convert/bson/BsonWriter.java +++ b/src/org/redkale/convert/bson/BsonWriter.java @@ -65,11 +65,11 @@ public class BsonWriter implements Writer { } @Override - public final boolean isTiny() { + public final boolean tiny() { return tiny; } - public BsonWriter setTiny(boolean tiny) { + public BsonWriter tiny(boolean tiny) { this.tiny = tiny; return this; } diff --git a/src/org/redkale/convert/json/JsonByteBufferReader.java b/src/org/redkale/convert/json/JsonByteBufferReader.java index e9d0d7c01..39b26cca4 100644 --- a/src/org/redkale/convert/json/JsonByteBufferReader.java +++ b/src/org/redkale/convert/json/JsonByteBufferReader.java @@ -27,7 +27,7 @@ public class JsonByteBufferReader extends JsonReader { protected JsonByteBufferReader(ByteBuffer... buffers) { this.buffers = buffers; - this.currentBuffer = buffers[currentIndex]; + if (buffers != null && buffers.length > 0) this.currentBuffer = buffers[currentIndex]; } @Override @@ -66,8 +66,10 @@ public class JsonByteBufferReader extends JsonReader { this.currentChar = 0; return ch; } - int remain = this.currentBuffer.remaining(); - if (remain == 0 && this.currentIndex + 1 >= this.buffers.length) return 0; + if (this.currentBuffer != null) { + int remain = this.currentBuffer.remaining(); + if (remain == 0 && this.currentIndex + 1 >= this.buffers.length) return 0; + } byte b1 = nextByte(); if (b1 >= 0) {// 1 byte, 7 bits: 0xxxxxxx return (char) b1; @@ -268,7 +270,7 @@ public class JsonByteBufferReader extends JsonReader { int value = 0; final boolean negative = firstchar == '-'; if (!negative) { - if (firstchar < '0' || firstchar > '9') throw new NumberFormatException("illegal escape(" + firstchar + ") (position = " + position + ")"); + if (firstchar < '0' || firstchar > '9') throw new ConvertException("illegal escape(" + firstchar + ") (position = " + position + ")"); value = firstchar - '0'; } for (;;) { @@ -281,7 +283,7 @@ public class JsonByteBufferReader extends JsonReader { backChar(ch); break; } else { - throw new NumberFormatException("illegal escape(" + ch + ") (position = " + position + ")"); + throw new ConvertException("illegal escape(" + ch + ") (position = " + position + ")"); } } return negative ? -value : value; @@ -302,7 +304,7 @@ public class JsonByteBufferReader extends JsonReader { long value = 0; final boolean negative = firstchar == '-'; if (!negative) { - if (firstchar < '0' || firstchar > '9') throw new NumberFormatException("illegal escape(" + firstchar + ") (position = " + position + ")"); + if (firstchar < '0' || firstchar > '9') throw new ConvertException("illegal escape(" + firstchar + ") (position = " + position + ")"); value = firstchar - '0'; } for (;;) { @@ -315,7 +317,7 @@ public class JsonByteBufferReader extends JsonReader { backChar(ch); break; } else { - throw new NumberFormatException("illegal escape(" + ch + ") (position = " + position + ")"); + throw new ConvertException("illegal escape(" + ch + ") (position = " + position + ")"); } } return negative ? -value : value; diff --git a/src/org/redkale/convert/json/JsonByteBufferWriter.java b/src/org/redkale/convert/json/JsonByteBufferWriter.java index 54b50506a..6b4e27f0b 100644 --- a/src/org/redkale/convert/json/JsonByteBufferWriter.java +++ b/src/org/redkale/convert/json/JsonByteBufferWriter.java @@ -9,18 +9,21 @@ import java.nio.*; import java.nio.charset.*; import java.util.*; import java.util.function.*; +import org.redkale.convert.*; import org.redkale.util.*; /** * - *

详情见: http://www.redkale.org + *

+ * 详情见: http://www.redkale.org + * * @author zhangjx */ -public final class JsonByteBufferWriter extends JsonWriter { +public class JsonByteBufferWriter extends JsonWriter { - private static final Charset UTF8 = Charset.forName("UTF-8"); + protected static final Charset UTF8 = Charset.forName("UTF-8"); - private final Charset charset; + protected Charset charset; private final Supplier supplier; @@ -28,17 +31,18 @@ public final class JsonByteBufferWriter extends JsonWriter { private int index; - protected JsonByteBufferWriter(Supplier supplier) { - this(null, supplier); + protected JsonByteBufferWriter(boolean tiny, Supplier supplier) { + this(tiny, null, supplier); } - protected JsonByteBufferWriter(Charset charset, Supplier supplier) { + protected JsonByteBufferWriter(boolean tiny, Charset charset, Supplier supplier) { + this.tiny = tiny; this.charset = UTF8.equals(charset) ? null : charset; this.supplier = supplier; } @Override - public JsonByteBufferWriter setTiny(boolean tiny) { + public JsonByteBufferWriter tiny(boolean tiny) { this.tiny = tiny; return this; } @@ -46,6 +50,7 @@ public final class JsonByteBufferWriter extends JsonWriter { @Override protected boolean recycle() { this.index = 0; + this.charset = null; this.buffers = null; return false; } @@ -101,13 +106,13 @@ public final class JsonByteBufferWriter extends JsonWriter { @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"); + if (ch > Byte.MAX_VALUE) throw new ConvertException("writeTo char(int.value = " + (int) ch + ") must be less 127"); expand(1); this.buffers[index].put((byte) ch); } @Override - public final void writeTo(final char[] chs, final int start, final int len) { + public void writeTo(final char[] chs, final int start, final int len) { writeTo(-1, false, chs, start, len); } @@ -239,7 +244,7 @@ public final class JsonByteBufferWriter extends JsonWriter { * @param value String值 */ @Override - public final void writeTo(final boolean quote, final String value) { + public void writeTo(final boolean quote, final String value) { char[] chs = Utility.charArray(value); writeTo(-1, quote, chs, 0, chs.length); } @@ -330,18 +335,6 @@ public final class JsonByteBufferWriter extends JsonWriter { writeTo(expandsize, true, cs, 0, sb.length()); } - @Override - public final void writeField(boolean comma, Attribute attribute) { - if (comma) writeTo(','); - writeTo(true, attribute.field()); - writeTo(':'); - } - - @Override - public final void writeSmallString(String value) { - writeTo(false, value); - } - @Override public String toString() { return Objects.toString(this); diff --git a/src/org/redkale/convert/json/JsonConvert.java b/src/org/redkale/convert/json/JsonConvert.java index 008aa7326..4fdf64c43 100644 --- a/src/org/redkale/convert/json/JsonConvert.java +++ b/src/org/redkale/convert/json/JsonConvert.java @@ -5,6 +5,7 @@ */ package org.redkale.convert.json; +import java.io.*; import java.lang.reflect.*; import java.nio.*; import java.nio.charset.*; @@ -14,7 +15,9 @@ import org.redkale.util.*; /** * - *

详情见: http://www.redkale.org + *

+ * 详情见: http://www.redkale.org + * * @author zhangjx */ @SuppressWarnings("unchecked") @@ -34,20 +37,18 @@ public final class JsonConvert extends Convert { this.tiny = tiny; } - public JsonByteBufferWriter pollJsonWriter(final Supplier supplier) { - return new JsonByteBufferWriter(supplier).setTiny(tiny); + @Override + public JsonFactory getFactory() { + return (JsonFactory) factory; } - public JsonByteBufferWriter pollJsonWriter(final Charset charset, final Supplier supplier) { - return new JsonByteBufferWriter(charset, supplier).setTiny(tiny); + //------------------------------ reader ----------------------------------------------------------- + public JsonReader pollJsonReader(final ByteBuffer... buffers) { + return new JsonByteBufferReader(buffers); } - public JsonWriter pollJsonWriter() { - return writerPool.get().setTiny(tiny); - } - - public void offerJsonWriter(JsonWriter out) { - if (out != null) writerPool.offer(out); + public JsonReader pollJsonReader(final InputStream in) { + return new JsonStreamReader(in); } public JsonReader pollJsonReader() { @@ -58,11 +59,28 @@ public final class JsonConvert extends Convert { if (in != null) readerPool.offer(in); } - @Override - public JsonFactory getFactory() { - return (JsonFactory) factory; + //------------------------------ writer ----------------------------------------------------------- + public JsonByteBufferWriter pollJsonWriter(final Supplier supplier) { + return new JsonByteBufferWriter(tiny, supplier); } + public JsonWriter pollJsonWriter(final OutputStream out) { + return new JsonStreamWriter(tiny, out); + } + + public JsonWriter pollJsonWriter(final Charset charset, final OutputStream out) { + return new JsonStreamWriter(tiny, charset, out); + } + + public JsonWriter pollJsonWriter() { + return writerPool.get().tiny(tiny); + } + + public void offerJsonWriter(JsonWriter out) { + if (out != null) writerPool.offer(out); + } + + //------------------------------ convertFrom ----------------------------------------------------------- public T convertFrom(final Type type, final String text) { if (text == null) return null; return convertFrom(type, Utility.charArray(text)); @@ -87,19 +105,40 @@ public final class JsonConvert extends Convert { return (T) factory.loadDecoder(type).convertFrom(new JsonByteBufferReader(buffers)); } + public T convertFrom(final Type type, final InputStream in) { + if (type == null || in == null) return null; + return (T) factory.loadDecoder(type).convertFrom(new JsonStreamReader(in)); + } + + public T convertFrom(final JsonReader in, final Type type) { + if (type == null) return null; + @SuppressWarnings("unchecked") + T rs = (T) factory.loadDecoder(type).convertFrom(in); + return rs; + } + + //------------------------------ convertTo ----------------------------------------------------------- + public String convertTo(Object value) { + if (value == null) return "null"; + return convertTo(value.getClass(), value); + } + public String convertTo(final Type type, Object value) { if (type == null) return null; if (value == null) return "null"; - final JsonWriter out = writerPool.get().setTiny(tiny); + final JsonWriter out = writerPool.get().tiny(tiny); factory.loadEncoder(type).convertTo(out, value); String result = out.toString(); writerPool.offer(out); return result; } - public String convertTo(Object value) { - if (value == null) return "null"; - return convertTo(value.getClass(), value); + public void convertTo(final JsonWriter out, Object value) { + if (value == null) { + out.writeNull(); + } else { + factory.loadEncoder(value.getClass()).convertTo(out, value); + } } public void convertTo(final JsonWriter out, final Type type, Object value) { @@ -111,21 +150,37 @@ public final class JsonConvert extends Convert { } } - public void convertTo(final JsonWriter out, Object value) { + public void convertTo(final OutputStream out, Object value) { + if (value == null) { + new JsonStreamWriter(tiny, out).writeNull(); + } else { + factory.loadEncoder(value.getClass()).convertTo(new JsonStreamWriter(tiny, out), value); + } + } + + public void convertTo(final OutputStream out, final Type type, Object value) { + if (type == null) return; + if (value == null) { + new JsonStreamWriter(tiny, out).writeNull(); + } else { + factory.loadEncoder(type).convertTo(new JsonStreamWriter(tiny, out), value); + } + } + + public ByteBuffer[] convertTo(final Supplier supplier, Object value) { + if (supplier == null) return null; + JsonByteBufferWriter out = new JsonByteBufferWriter(tiny, null, supplier); if (value == null) { out.writeNull(); } else { factory.loadEncoder(value.getClass()).convertTo(out, value); } + return out.toBuffers(); } public ByteBuffer[] convertTo(final Supplier supplier, final Type type, Object value) { - return convertTo(null, supplier, type, value); - } - - public ByteBuffer[] convertTo(final Charset charset, final Supplier supplier, final Type type, Object value) { if (supplier == null || type == null) return null; - JsonByteBufferWriter out = new JsonByteBufferWriter(charset, supplier); + JsonByteBufferWriter out = new JsonByteBufferWriter(tiny, null, supplier); if (value == null) { out.writeNull(); } else { @@ -134,18 +189,15 @@ public final class JsonConvert extends Convert { return out.toBuffers(); } - public ByteBuffer[] convertTo(final Supplier supplier, Object value) { - return convertTo(null, supplier, value); + public JsonWriter convertToWriter(Object value) { + if (value == null) return null; + return convertToWriter(value.getClass(), value); } - public ByteBuffer[] convertTo(final Charset charset, final Supplier 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(); + public JsonWriter convertToWriter(final Type type, Object value) { + if (type == null) return null; + final JsonWriter out = writerPool.get().tiny(tiny); + factory.loadEncoder(type).convertTo(out, value); + return out; } } diff --git a/src/org/redkale/convert/json/JsonFactory.java b/src/org/redkale/convert/json/JsonFactory.java index ff975bffb..ad4c43ca9 100644 --- a/src/org/redkale/convert/json/JsonFactory.java +++ b/src/org/redkale/convert/json/JsonFactory.java @@ -14,7 +14,9 @@ import org.redkale.util.*; /** * - *

详情见: http://www.redkale.org + *

+ * 详情见: http://www.redkale.org + * * @author zhangjx */ public final class JsonFactory extends Factory { @@ -32,6 +34,12 @@ public final class JsonFactory extends Factory { super(parent, tiny); } + @Override + public JsonFactory tiny(boolean tiny) { + this.tiny = tiny; + return this; + } + public static JsonFactory root() { return instance; } diff --git a/src/org/redkale/convert/json/JsonReader.java b/src/org/redkale/convert/json/JsonReader.java index a245457a8..1d6d8aaa2 100644 --- a/src/org/redkale/convert/json/JsonReader.java +++ b/src/org/redkale/convert/json/JsonReader.java @@ -350,7 +350,7 @@ public class JsonReader implements Reader { int value = 0; final boolean negative = firstchar == '-'; if (!negative) { - if (firstchar < '0' || firstchar > '9') throw new NumberFormatException("illegal escape(" + firstchar + ") (position = " + currpos + ") in (" + new String(this.text) + ")"); + if (firstchar < '0' || firstchar > '9') throw new ConvertException("illegal escape(" + firstchar + ") (position = " + currpos + ") in (" + new String(this.text) + ")"); value = firstchar - '0'; } for (;;) { @@ -362,7 +362,7 @@ public class JsonReader implements Reader { } else if (ch == ',' || ch == '}' || ch == ']' || ch <= ' ' || ch == ':') { break; } else { - throw new NumberFormatException("illegal escape(" + ch + ") (position = " + currpos + ") in (" + new String(this.text) + ")"); + throw new ConvertException("illegal escape(" + ch + ") (position = " + currpos + ") in (" + new String(this.text) + ")"); } } this.position = currpos - 1; @@ -396,7 +396,7 @@ public class JsonReader implements Reader { long value = 0; final boolean negative = firstchar == '-'; if (!negative) { - if (firstchar < '0' || firstchar > '9') throw new NumberFormatException("illegal escape(" + firstchar + ") (position = " + currpos + ") in (" + new String(this.text) + ")"); + if (firstchar < '0' || firstchar > '9') throw new ConvertException("illegal escape(" + firstchar + ") (position = " + currpos + ") in (" + new String(this.text) + ")"); value = firstchar - '0'; } for (;;) { @@ -408,7 +408,7 @@ public class JsonReader implements Reader { } else if (ch == ',' || ch == '}' || ch == ']' || ch <= ' ' || ch == ':') { break; } else { - throw new NumberFormatException("illegal escape(" + ch + ") (position = " + currpos + ") but '" + ch + "' in (" + new String(this.text) + ")"); + throw new ConvertException("illegal escape(" + ch + ") (position = " + currpos + ") but '" + ch + "' in (" + new String(this.text) + ")"); } } this.position = currpos - 1; diff --git a/src/org/redkale/convert/json/JsonStreamReader.java b/src/org/redkale/convert/json/JsonStreamReader.java new file mode 100644 index 000000000..836f554f8 --- /dev/null +++ b/src/org/redkale/convert/json/JsonStreamReader.java @@ -0,0 +1,40 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package org.redkale.convert.json; + +import java.io.*; +import org.redkale.convert.*; + +/** + * + * @author zhangjx + */ +class JsonStreamReader extends JsonByteBufferReader { + + private InputStream in; + + protected JsonStreamReader(InputStream in) { + this.in = in; + } + + @Override + protected boolean recycle() { + super.recycle(); // this.position 初始化值为-1 + this.in = null; + return false; + } + + @Override + protected byte nextByte() { + try { + byte b = (byte) in.read(); + this.position++; + return b; + } catch (IOException e) { + throw new ConvertException(e); + } + } +} diff --git a/src/org/redkale/convert/json/JsonStreamWriter.java b/src/org/redkale/convert/json/JsonStreamWriter.java new file mode 100644 index 000000000..7c9d1db12 --- /dev/null +++ b/src/org/redkale/convert/json/JsonStreamWriter.java @@ -0,0 +1,141 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package org.redkale.convert.json; + +import java.io.*; +import java.nio.*; +import java.nio.charset.*; +import org.redkale.convert.*; +import org.redkale.util.*; + +/** + * + * @author zhangjx + */ +class JsonStreamWriter extends JsonByteBufferWriter { + + private OutputStream out; + + protected JsonStreamWriter(boolean tiny, OutputStream out) { + this(tiny, null, out); + } + + protected JsonStreamWriter(boolean tiny, Charset charset, OutputStream out) { + super(tiny, charset, null); + this.out = out; + } + + @Override + protected boolean recycle() { + super.recycle(); + this.out = null; + return false; + } + + @Override + public void writeTo(final char ch) { + if (ch > Byte.MAX_VALUE) throw new ConvertException("writeTo char(int.value = " + (int) ch + ") must be less 127"); + try { + out.write((byte) ch); + } catch (IOException e) { + throw new ConvertException(e); + } + } + + @Override + public void writeTo(final char[] chs, final int start, final int len) { + writeTo(false, chs, start, len); + } + + private void writeTo(final boolean quote, final char[] chs, final int start, final int len) { + try { + if (quote) out.write('"'); + if (charset == null) { //UTF-8 + final int limit = start + len; + for (int i = start; i < limit; i++) { + char c = chs[i]; + if (c < 0x80) { + out.write((byte) c); + } else if (c < 0x800) { + out.write((byte) (0xc0 | (c >> 6))); + out.write((byte) (0x80 | (c & 0x3f))); + } else { + out.write((byte) (0xe0 | ((c >> 12)))); + out.write((byte) (0x80 | ((c >> 6) & 0x3f))); + out.write((byte) (0x80 | (c & 0x3f))); + } + } + } else { + ByteBuffer bb = charset.encode(CharBuffer.wrap(chs, start, len)); + out.write(bb.array()); + } + if (quote) out.write('"'); + } catch (IOException e) { + throw new ConvertException(e); + } + } + + /** + * 注意: 该String值不能为null且不会进行转义, 只用于不含需要转义字符的字符串,例如enum、double、BigInteger转换的String + * + * @param quote 是否写入双引号 + * @param value String值 + */ + @Override + public void writeTo(final boolean quote, final String value) { + char[] chs = Utility.charArray(value); + writeTo(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(true, chs, 0, len); + 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(true, cs, 0, sb.length()); + } +} diff --git a/src/org/redkale/convert/json/JsonWriter.java b/src/org/redkale/convert/json/JsonWriter.java index 93951a6e7..7a2c46dc0 100644 --- a/src/org/redkale/convert/json/JsonWriter.java +++ b/src/org/redkale/convert/json/JsonWriter.java @@ -58,11 +58,11 @@ public class JsonWriter implements Writer { } @Override - public boolean isTiny() { + public boolean tiny() { return tiny; } - public JsonWriter setTiny(boolean tiny) { + public JsonWriter tiny(boolean tiny) { this.tiny = tiny; return this; } @@ -159,14 +159,14 @@ public class JsonWriter implements Writer { } @Override - public void writeField(boolean comma, Attribute attribute) { + public final void writeField(boolean comma, Attribute attribute) { if (comma) writeTo(','); writeTo(true, attribute.field()); writeTo(':'); } @Override - public void writeSmallString(String value) { + public final void writeSmallString(String value) { writeTo(true, value); } diff --git a/src/org/redkale/net/http/HttpResponse.java b/src/org/redkale/net/http/HttpResponse.java index acc628034..090c7749e 100644 --- a/src/org/redkale/net/http/HttpResponse.java +++ b/src/org/redkale/net/http/HttpResponse.java @@ -189,17 +189,17 @@ public class HttpResponse extends Response { public void finishJson(Object obj) { this.contentType = "text/plain; charset=utf-8"; - finish(request.getJsonConvert().convertTo(context.getCharset(), context.getBufferSupplier(), obj)); + finish(request.getJsonConvert().convertTo(context.getBufferSupplier(), obj)); } public void finishJson(Type type, Object obj) { this.contentType = "text/plain; charset=utf-8"; - finish(request.getJsonConvert().convertTo(context.getCharset(), context.getBufferSupplier(), type, obj)); + finish(request.getJsonConvert().convertTo(context.getBufferSupplier(), type, obj)); } public void finishJson(Object... objs) { this.contentType = "text/plain; charset=utf-8"; - finish(request.getJsonConvert().convertTo(context.getCharset(), context.getBufferSupplier(), objs)); + finish(request.getJsonConvert().convertTo(context.getBufferSupplier(), objs)); } public void finish(String obj) {