diff --git a/src/main/java/org/redkale/convert/json/JsonByteBufferWriter.java b/src/main/java/org/redkale/convert/json/JsonByteBufferWriter.java index 9c750746c..2a772cb87 100644 --- a/src/main/java/org/redkale/convert/json/JsonByteBufferWriter.java +++ b/src/main/java/org/redkale/convert/json/JsonByteBufferWriter.java @@ -348,7 +348,7 @@ public class JsonByteBufferWriter extends JsonWriter { } @Override - public void writeFieldShortValue(final byte[] fieldBytes, final short value) { + public void writeFieldShortValue(final byte[] fieldBytes, final char[] fieldChars, final short value) { byte[] bs1 = fieldBytes; byte[] bs2 = Utility.latin1ByteArray(String.valueOf(value)); int expandsize = expand(bs1.length + bs2.length); @@ -374,7 +374,7 @@ public class JsonByteBufferWriter extends JsonWriter { } @Override - public void writeFieldIntValue(final byte[] fieldBytes, final int value) { + public void writeFieldIntValue(final byte[] fieldBytes, final char[] fieldChars, final int value) { byte[] bs1 = fieldBytes; byte[] bs2 = Utility.latin1ByteArray(String.valueOf(value)); int expandsize = expand(bs1.length + bs2.length); @@ -400,7 +400,7 @@ public class JsonByteBufferWriter extends JsonWriter { } @Override - public void writeFieldLongValue(final byte[] fieldBytes, final long value) { + public void writeFieldLongValue(final byte[] fieldBytes, final char[] fieldChars, final long value) { byte[] bs1 = fieldBytes; byte[] bs2 = Utility.latin1ByteArray(String.valueOf(value)); int expandsize = expand(bs1.length + bs2.length); @@ -426,7 +426,7 @@ public class JsonByteBufferWriter extends JsonWriter { } @Override - public void writeFieldLatin1Value(final byte[] fieldBytes, final String value) { + public void writeFieldLatin1Value(final byte[] fieldBytes, final char[] fieldChars, final String value) { byte[] bs1 = fieldBytes; byte[] bs2 = Utility.latin1ByteArray(value); int expandsize = expand(bs1.length + bs2.length + 2); @@ -466,7 +466,7 @@ public class JsonByteBufferWriter extends JsonWriter { } @Override - public void writeLastFieldShortValue(final byte[] fieldBytes, final short value) { + public void writeLastFieldShortValue(final byte[] fieldBytes, final char[] fieldChars, final short value) { byte[] bs1 = fieldBytes; byte[] bs2 = Utility.latin1ByteArray(String.valueOf(value)); int expandsize = expand(bs1.length + bs2.length + 1); @@ -499,7 +499,7 @@ public class JsonByteBufferWriter extends JsonWriter { } @Override - public void writeLastFieldIntValue(final byte[] fieldBytes, final int value) { + public void writeLastFieldIntValue(final byte[] fieldBytes, final char[] fieldChars, final int value) { byte[] bs1 = fieldBytes; byte[] bs2 = Utility.latin1ByteArray(String.valueOf(value)); int expandsize = expand(bs1.length + bs2.length + 1); @@ -532,7 +532,7 @@ public class JsonByteBufferWriter extends JsonWriter { } @Override - public void writeLastFieldLongValue(final byte[] fieldBytes, final long value) { + public void writeLastFieldLongValue(final byte[] fieldBytes, final char[] fieldChars, final long value) { byte[] bs1 = fieldBytes; byte[] bs2 = Utility.latin1ByteArray(String.valueOf(value)); int expandsize = expand(bs1.length + bs2.length + 1); @@ -565,7 +565,7 @@ public class JsonByteBufferWriter extends JsonWriter { } @Override - public void writeLastFieldLatin1Value(final byte[] fieldBytes, final String value) { + public void writeLastFieldLatin1Value(final byte[] fieldBytes, final char[] fieldChars, final String value) { if (value == null && nullable()) { writeTo(fieldBytes); writeNull(); @@ -623,7 +623,8 @@ public class JsonByteBufferWriter extends JsonWriter { } @Override // firstFieldBytes 必须带{开头 - public void writeObjectByOnlyOneLatin1FieldValue(final byte[] firstFieldBytes, final String value) { + public void writeObjectByOnlyOneLatin1FieldValue( + final byte[] firstFieldBytes, final char[] firstFieldChars, final String value) { if (value == null && nullable()) { writeTo('{'); writeTo(firstFieldBytes); @@ -692,7 +693,12 @@ public class JsonByteBufferWriter extends JsonWriter { @Override // firstFieldBytes 必须带{开头, lastFieldBytes必须,开头 public void writeObjectByOnlyTwoIntFieldValue( - final byte[] firstFieldBytes, final int value1, final byte[] lastFieldBytes, final int value2) { + final byte[] firstFieldBytes, + final char[] firstFieldChars, + final int value1, + final byte[] lastFieldBytes, + final char[] lastFieldChars, + final int value2) { byte[] bs1 = firstFieldBytes; byte[] bs2 = Utility.latin1ByteArray(String.valueOf(value1)); byte[] bs3 = lastFieldBytes; diff --git a/src/main/java/org/redkale/convert/json/JsonBytesWriter.java b/src/main/java/org/redkale/convert/json/JsonBytesWriter.java index f47440845..59a69506f 100644 --- a/src/main/java/org/redkale/convert/json/JsonBytesWriter.java +++ b/src/main/java/org/redkale/convert/json/JsonBytesWriter.java @@ -31,17 +31,11 @@ public class JsonBytesWriter extends JsonWriter implements ByteTuple { private static final int TENTHOUSAND_MAX = 10001; private static final byte[][] TENTHOUSAND_BYTES = new byte[TENTHOUSAND_MAX][]; + private static final byte[][] TENTHOUSAND_BYTES2 = new byte[TENTHOUSAND_MAX][]; static { for (int i = 0; i < TENTHOUSAND_BYTES.length; i++) { TENTHOUSAND_BYTES[i] = String.valueOf(i).getBytes(); - } - } - - private static final byte[][] TENTHOUSAND_BYTES2 = new byte[TENTHOUSAND_MAX][]; - - static { - for (int i = 0; i < TENTHOUSAND_BYTES2.length; i++) { TENTHOUSAND_BYTES2[i] = String.valueOf(-i).getBytes(); } } @@ -191,7 +185,7 @@ public class JsonBytesWriter extends JsonWriter implements ByteTuple { } @Override - public void writeFieldShortValue(final byte[] fieldBytes, final short value) { + public void writeFieldShortValue(final byte[] fieldBytes, final char[] fieldChars, final short value) { byte[] bs1 = fieldBytes; byte[] bs2 = (value >= 0 && value < TENTHOUSAND_MAX) ? TENTHOUSAND_BYTES[value] @@ -208,7 +202,7 @@ public class JsonBytesWriter extends JsonWriter implements ByteTuple { } @Override - public void writeFieldIntValue(final byte[] fieldBytes, final int value) { + public void writeFieldIntValue(final byte[] fieldBytes, final char[] fieldChars, final int value) { byte[] bs1 = fieldBytes; byte[] bs2 = (value >= 0 && value < TENTHOUSAND_MAX) ? TENTHOUSAND_BYTES[value] @@ -225,7 +219,7 @@ public class JsonBytesWriter extends JsonWriter implements ByteTuple { } @Override - public void writeFieldLongValue(final byte[] fieldBytes, final long value) { + public void writeFieldLongValue(final byte[] fieldBytes, final char[] fieldChars, final long value) { byte[] bs1 = fieldBytes; byte[] bs2 = (value >= 0 && value < TENTHOUSAND_MAX) ? TENTHOUSAND_BYTES[(int) value] @@ -242,7 +236,7 @@ public class JsonBytesWriter extends JsonWriter implements ByteTuple { } @Override - public void writeFieldLatin1Value(final byte[] fieldBytes, final String value) { + public void writeFieldLatin1Value(final byte[] fieldBytes, final char[] fieldChars, final String value) { byte[] bs1 = fieldBytes; byte[] bs2 = Utility.latin1ByteArray(value); int len1 = bs1.length; @@ -257,7 +251,7 @@ public class JsonBytesWriter extends JsonWriter implements ByteTuple { } @Override - public void writeLastFieldShortValue(final byte[] fieldBytes, final short value) { + public void writeLastFieldShortValue(final byte[] fieldBytes, final char[] fieldChars, final short value) { byte[] bs1 = fieldBytes; byte[] bs2 = (value >= 0 && value < TENTHOUSAND_MAX) ? TENTHOUSAND_BYTES[value] @@ -275,7 +269,7 @@ public class JsonBytesWriter extends JsonWriter implements ByteTuple { } @Override - public void writeLastFieldIntValue(final byte[] fieldBytes, final int value) { + public void writeLastFieldIntValue(final byte[] fieldBytes, final char[] fieldChars, final int value) { byte[] bs1 = fieldBytes; byte[] bs2 = (value >= 0 && value < TENTHOUSAND_MAX) ? TENTHOUSAND_BYTES[value] @@ -293,7 +287,7 @@ public class JsonBytesWriter extends JsonWriter implements ByteTuple { } @Override - public void writeLastFieldLongValue(final byte[] fieldBytes, final long value) { + public void writeLastFieldLongValue(final byte[] fieldBytes, final char[] fieldChars, final long value) { byte[] bs1 = fieldBytes; byte[] bs2 = (value >= 0 && value < TENTHOUSAND_MAX) ? TENTHOUSAND_BYTES[(int) value] @@ -311,7 +305,7 @@ public class JsonBytesWriter extends JsonWriter implements ByteTuple { } @Override - public void writeLastFieldLatin1Value(final byte[] fieldBytes, final String value) { + public void writeLastFieldLatin1Value(final byte[] fieldBytes, final char[] fieldChars, final String value) { if (value == null && nullable()) { writeTo(fieldBytes); writeNull(); @@ -340,7 +334,8 @@ public class JsonBytesWriter extends JsonWriter implements ByteTuple { } @Override // firstFieldBytes 必须带{开头 - public void writeObjectByOnlyOneLatin1FieldValue(final byte[] firstFieldBytes, final String value) { + public void writeObjectByOnlyOneLatin1FieldValue( + final byte[] firstFieldBytes, final char[] firstFieldChars, final String value) { if (value == null && nullable()) { writeTo(BYTE_LBRACE); writeTo(firstFieldBytes); @@ -372,7 +367,12 @@ public class JsonBytesWriter extends JsonWriter implements ByteTuple { @Override // firstFieldBytes 必须带{开头, lastFieldBytes必须,开头 public void writeObjectByOnlyTwoIntFieldValue( - final byte[] firstFieldBytes, final int value1, final byte[] lastFieldBytes, final int value2) { + final byte[] firstFieldBytes, + final char[] firstFieldChars, + final int value1, + final byte[] lastFieldBytes, + final char[] lastFieldChars, + final int value2) { byte[] bs1 = firstFieldBytes; byte[] bs2 = (value1 >= 0 && value1 < TENTHOUSAND_MAX) ? TENTHOUSAND_BYTES[value1] @@ -466,6 +466,14 @@ public class JsonBytesWriter extends JsonWriter implements ByteTuple { bytes[curr++] = '\\'; bytes[curr++] = 'r'; break; + case '\f': + bytes[curr++] = '\\'; + bytes[curr++] = 'f'; + break; + case '\b': + bytes[curr++] = '\\'; + bytes[curr++] = 'b'; + break; case '\t': bytes[curr++] = '\\'; bytes[curr++] = 't'; @@ -474,9 +482,9 @@ public class JsonBytesWriter extends JsonWriter implements ByteTuple { bytes[curr++] = '\\'; bytes[curr++] = '\\'; break; - case '"': + case BYTE_DQUOTE: bytes[curr++] = '\\'; - bytes[curr++] = '"'; + bytes[curr++] = BYTE_DQUOTE; break; default: if (ch < 0x80) { @@ -521,7 +529,7 @@ public class JsonBytesWriter extends JsonWriter implements ByteTuple { if (b2 == 0 && b >= 0) { if (b == BYTE_DQUOTE) { bytes[curr++] = '\\'; - bytes[curr++] = '"'; + bytes[curr++] = BYTE_DQUOTE; } else if (b == '\\') { bytes[curr++] = '\\'; bytes[curr++] = '\\'; @@ -583,14 +591,14 @@ public class JsonBytesWriter extends JsonWriter implements ByteTuple { count = curr; } - private static final char MIN_LOW_SURROGATE = '\uDC00'; - private static final char MAX_LOW_SURROGATE = '\uDFFF'; - private static final char MIN_HIGH_SURROGATE = '\uD800'; - private static final char MAX_HIGH_SURROGATE = '\uDBFF'; - private static final int MIN_SUPPLEMENTARY_CODE_POINT = 0x010000; - private static final char MAX_LOW_SURROGATE_MORE = MAX_LOW_SURROGATE + 1; - private static final char MAX_HIGH_SURROGATE_MORE = MAX_HIGH_SURROGATE + 1; - private static final int MIN_SUPPLEMENTARY_CODE_POINT_MORE = + static final char MIN_LOW_SURROGATE = '\uDC00'; + static final char MAX_LOW_SURROGATE = '\uDFFF'; + static final char MIN_HIGH_SURROGATE = '\uD800'; + static final char MAX_HIGH_SURROGATE = '\uDBFF'; + static final int MIN_SUPPLEMENTARY_CODE_POINT = 0x010000; + static final char MAX_LOW_SURROGATE_MORE = MAX_LOW_SURROGATE + 1; + static final char MAX_HIGH_SURROGATE_MORE = MAX_HIGH_SURROGATE + 1; + static final int MIN_SUPPLEMENTARY_CODE_POINT_MORE = (MIN_SUPPLEMENTARY_CODE_POINT - (MIN_HIGH_SURROGATE << 10) - MIN_LOW_SURROGATE); private void writeEscapeLatinString(final boolean quote, byte[] value) { @@ -602,7 +610,7 @@ public class JsonBytesWriter extends JsonWriter implements ByteTuple { for (byte b : value) { if (b == BYTE_DQUOTE) { bytes[curr++] = '\\'; - bytes[curr++] = '"'; + bytes[curr++] = BYTE_DQUOTE; } else if (b == '\\') { bytes[curr++] = '\\'; bytes[curr++] = '\\'; diff --git a/src/main/java/org/redkale/convert/json/JsonCharsWriter.java b/src/main/java/org/redkale/convert/json/JsonCharsWriter.java new file mode 100644 index 000000000..224102275 --- /dev/null +++ b/src/main/java/org/redkale/convert/json/JsonCharsWriter.java @@ -0,0 +1,554 @@ +/* + * Copyright (c) 2016-2116 Redkale + * All rights reserved. + */ +package org.redkale.convert.json; + +import static org.redkale.convert.json.JsonWriter.BYTE_DQUOTE; +import static org.redkale.convert.json.JsonWriter.BYTE_LBRACE; +import static org.redkale.convert.json.JsonWriter.BYTE_RBRACE; +import static org.redkale.convert.json.JsonWriter.DEFAULT_SIZE; +import static org.redkale.convert.json.JsonWriter.DigitOnes; +import static org.redkale.convert.json.JsonWriter.DigitTens; +import static org.redkale.convert.json.JsonWriter.digits; +import static org.redkale.convert.json.JsonWriter.sizeTable; +import org.redkale.util.StringWrapper; +import org.redkale.util.Utility; + +/** + * writeTo系列的方法输出的字符不能含特殊字符 + * + *
详情见: https://redkale.org
+ *
+ * @author zhangjx
+ * @since 2.3.0
+ */
+public class JsonCharsWriter extends JsonWriter {
+
+ private static final char[] CHARS_TUREVALUE = "true".toCharArray();
+
+ private static final char[] CHARS_FALSEVALUE = "false".toCharArray();
+
+ private static final int TENTHOUSAND_MAX = 10001;
+
+ private static final char[][] TENTHOUSAND_CHARS = new char[TENTHOUSAND_MAX][];
+ private static final char[][] TENTHOUSAND_CHARS2 = new char[TENTHOUSAND_MAX][];
+
+ static {
+ for (int i = 0; i < TENTHOUSAND_CHARS.length; i++) {
+ TENTHOUSAND_CHARS[i] = String.valueOf(i).toCharArray();
+ TENTHOUSAND_CHARS2[i] = String.valueOf(-i).toCharArray();
+ }
+ }
+
+ private int count;
+
+ private char[] content;
+
+ public JsonCharsWriter() {
+ this(DEFAULT_SIZE);
+ }
+
+ public JsonCharsWriter(int size) {
+ this.content = new char[size > 1024 ? size : 1024];
+ }
+
+ // -----------------------------------------------------------------------
+ /**
+ * 返回指定至少指定长度的缓冲区
+ *
+ * @param len
+ *
+ * @return
+ */
+ private char[] expand(int len) {
+ int ncount = count + len;
+ if (ncount <= content.length) {
+ return content;
+ }
+ char[] newdata = new char[Math.max(content.length * 3 / 2, ncount)];
+ System.arraycopy(content, 0, newdata, 0, count);
+ this.content = newdata;
+ return newdata;
+ }
+
+ @Override
+ protected boolean recycle() {
+ super.recycle();
+ this.count = 0;
+ if (this.content != null && this.content.length > DEFAULT_SIZE * 100) {
+ this.content = new char[DEFAULT_SIZE];
+ }
+ return true;
+ }
+
+ @Override
+ public final boolean charsMode() {
+ return true;
+ }
+
+ @Override
+ public void writeTo(final char ch) { // 只能是 0 - 127 的字符
+ expand(1);
+ content[count++] = ch;
+ }
+
+ @Override
+ 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;
+ }
+
+ @Override
+ public void writeTo(final byte b) { // 只能是 0 - 127 的字符
+ expand(1);
+ content[count++] = (char) (b & 0xff);
+ }
+
+ @Override
+ public void writeTo(final byte[] bs, final int start, final int len) { // 只能是 0 - 127 的字符
+ char[] chars = expand(len);
+ for (int i = 0; i < len; i++) {
+ chars[count + i] = (char) (bs[start + i] & 0xff);
+ }
+ count += len;
+ }
+
+ /**
+ * 注意: 该String值不能为null且不会进行转义, 只用于不含需要转义字符的字符串,例如enum、double、BigInteger、BigDecimal转换的String
+ *
+ * @param quote 是否加双引号
+ * @param value 非null且不含需要转义的字符的String值
+ */
+ @Override
+ public void writeLatin1To(final boolean quote, final String value) {
+ int len = value.length();
+ if (quote) {
+ expand(len + 2);
+ content[count++] = BYTE_DQUOTE;
+ value.getChars(0, len, content, count);
+ count += len;
+ content[count++] = BYTE_DQUOTE;
+ } else {
+ expand(len);
+ value.getChars(0, len, content, count);
+ count += len;
+ }
+ }
+
+ @Override
+ public void writeFieldShortValue(final byte[] fieldBytes, final char[] fieldChars, final short value) {
+ char[] bs1 = fieldChars;
+ char[] bs2 = (value >= 0 && value < TENTHOUSAND_MAX)
+ ? TENTHOUSAND_CHARS[value]
+ : ((value < 0 && value > -TENTHOUSAND_MAX)
+ ? TENTHOUSAND_CHARS2[-value]
+ : String.valueOf(value).toCharArray());
+ int len1 = bs1.length;
+ int len2 = bs2.length;
+ char[] src = expand(len1 + len2);
+ System.arraycopy(bs1, 0, src, count, len1);
+ count += len1;
+ System.arraycopy(bs2, 0, src, count, len2);
+ count += len2;
+ }
+
+ @Override
+ public void writeFieldIntValue(final byte[] fieldBytes, final char[] fieldChars, final int value) {
+ char[] bs1 = fieldChars;
+ char[] bs2 = (value >= 0 && value < TENTHOUSAND_MAX)
+ ? TENTHOUSAND_CHARS[value]
+ : ((value < 0 && value > -TENTHOUSAND_MAX)
+ ? TENTHOUSAND_CHARS2[-value]
+ : String.valueOf(value).toCharArray());
+ int len1 = bs1.length;
+ int len2 = bs2.length;
+ char[] src = expand(len1 + len2);
+ System.arraycopy(bs1, 0, src, count, len1);
+ count += len1;
+ System.arraycopy(bs2, 0, src, count, len2);
+ count += len2;
+ }
+
+ @Override
+ public void writeFieldLongValue(final byte[] fieldBytes, final char[] fieldChars, final long value) {
+ char[] bs1 = fieldChars;
+ char[] bs2 = (value >= 0 && value < TENTHOUSAND_MAX)
+ ? TENTHOUSAND_CHARS[(int) value]
+ : ((value < 0 && value > -TENTHOUSAND_MAX)
+ ? TENTHOUSAND_CHARS2[(int) -value]
+ : String.valueOf(value).toCharArray());
+ int len1 = bs1.length;
+ int len2 = bs2.length;
+ char[] src = expand(len1 + len2);
+ System.arraycopy(bs1, 0, src, count, len1);
+ count += len1;
+ System.arraycopy(bs2, 0, src, count, len2);
+ count += len2;
+ }
+
+ @Override
+ public void writeFieldLatin1Value(final byte[] fieldBytes, final char[] fieldChars, final String value) {
+ char[] bs1 = fieldChars;
+ int len1 = bs1.length;
+ int len2 = value.length();
+ char[] src = expand(len1 + len2 + 2);
+ System.arraycopy(bs1, 0, src, count, len1);
+ count += len1;
+ src[count++] = BYTE_DQUOTE;
+ value.getChars(0, len2, content, count);
+ count += len2;
+ src[count++] = BYTE_DQUOTE;
+ }
+
+ @Override
+ public void writeLastFieldShortValue(final byte[] fieldBytes, final char[] fieldChars, final short value) {
+ char[] bs1 = fieldChars;
+ char[] bs2 = (value >= 0 && value < TENTHOUSAND_MAX)
+ ? TENTHOUSAND_CHARS[value]
+ : ((value < 0 && value > -TENTHOUSAND_MAX)
+ ? TENTHOUSAND_CHARS2[-value]
+ : String.valueOf(value).toCharArray());
+ int len1 = bs1.length;
+ int len2 = bs2.length;
+ char[] src = expand(len1 + len2 + 1);
+ System.arraycopy(bs1, 0, src, count, len1);
+ count += len1;
+ System.arraycopy(bs2, 0, src, count, len2);
+ count += len2;
+ src[count++] = BYTE_RBRACE;
+ }
+
+ @Override
+ public void writeLastFieldIntValue(final byte[] fieldBytes, final char[] fieldChars, final int value) {
+ char[] bs1 = fieldChars;
+ char[] bs2 = (value >= 0 && value < TENTHOUSAND_MAX)
+ ? TENTHOUSAND_CHARS[value]
+ : ((value < 0 && value > -TENTHOUSAND_MAX)
+ ? TENTHOUSAND_CHARS2[-value]
+ : String.valueOf(value).toCharArray());
+ int len1 = bs1.length;
+ int len2 = bs2.length;
+ char[] src = expand(len1 + len2 + 1);
+ System.arraycopy(bs1, 0, src, count, len1);
+ count += len1;
+ System.arraycopy(bs2, 0, src, count, len2);
+ count += len2;
+ src[count++] = BYTE_RBRACE;
+ }
+
+ @Override
+ public void writeLastFieldLongValue(final byte[] fieldBytes, final char[] fieldChars, final long value) {
+ char[] bs1 = fieldChars;
+ char[] bs2 = (value >= 0 && value < TENTHOUSAND_MAX)
+ ? TENTHOUSAND_CHARS[(int) value]
+ : ((value < 0 && value > -TENTHOUSAND_MAX)
+ ? TENTHOUSAND_CHARS2[(int) -value]
+ : String.valueOf(value).toCharArray());
+ int len1 = bs1.length;
+ int len2 = bs2.length;
+ char[] src = expand(len1 + len2 + 1);
+ System.arraycopy(bs1, 0, src, count, len1);
+ count += len1;
+ System.arraycopy(bs2, 0, src, count, len2);
+ count += len2;
+ src[count++] = BYTE_RBRACE;
+ }
+
+ @Override
+ public void writeLastFieldLatin1Value(final byte[] fieldBytes, final char[] fieldChars, final String value) {
+ if (value == null && nullable()) {
+ writeTo(fieldChars);
+ writeNull();
+ writeTo(BYTE_RBRACE);
+ return;
+ }
+ if (value == null || (tiny() && value.isEmpty())) {
+ expand(1);
+ content[count++] = BYTE_RBRACE;
+ } else {
+ int len1 = fieldChars.length;
+ int len2 = value.length();
+ char[] src = expand(len1 + len2 + 3);
+ System.arraycopy(fieldChars, 0, src, count, len1);
+ count += len1;
+ content[count++] = BYTE_DQUOTE;
+ value.getChars(0, len2, content, count);
+ count += len2;
+ content[count++] = BYTE_DQUOTE;
+ content[count++] = BYTE_RBRACE;
+ }
+ }
+
+ @Override // firstFieldBytes 必须带{开头
+ public void writeObjectByOnlyOneLatin1FieldValue(
+ byte[] firstFieldBytes, char[] firstFieldChars, final String value) {
+ if (value == null && nullable()) {
+ writeTo(BYTE_LBRACE);
+ writeTo(firstFieldChars);
+ writeNull();
+ writeTo(BYTE_RBRACE);
+ return;
+ }
+ if (value == null || (tiny() && value.isEmpty())) {
+ expand(2);
+ content[count++] = BYTE_LBRACE;
+ content[count++] = BYTE_RBRACE;
+ } else {
+ int len1 = firstFieldChars.length;
+ int len2 = value.length();
+ char[] src = expand(len1 + len2 + 3);
+ System.arraycopy(firstFieldChars, 0, src, count, len1);
+ count += len1;
+ content[count++] = BYTE_DQUOTE;
+ value.getChars(0, len2, content, count);
+ count += len2;
+ content[count++] = BYTE_DQUOTE;
+ content[count++] = BYTE_RBRACE;
+ }
+ }
+
+ @Override // firstFieldBytes 必须带{开头, lastFieldBytes必须,开头
+ public void writeObjectByOnlyTwoIntFieldValue(
+ final byte[] firstFieldBytes,
+ final char[] firstFieldChars,
+ final int value1,
+ final byte[] lastFieldBytes,
+ final char[] lastFieldChars,
+ final int value2) {
+ char[] bs1 = firstFieldChars;
+ char[] bs2 = (value1 >= 0 && value1 < TENTHOUSAND_MAX)
+ ? TENTHOUSAND_CHARS[value1]
+ : ((value1 < 0 && value1 > -TENTHOUSAND_MAX)
+ ? TENTHOUSAND_CHARS2[-value1]
+ : String.valueOf(value1).toCharArray());
+ char[] bs3 = lastFieldChars;
+ char[] bs4 = (value2 >= 0 && value2 < TENTHOUSAND_MAX)
+ ? TENTHOUSAND_CHARS[value2]
+ : ((value2 < 0 && value2 > -TENTHOUSAND_MAX)
+ ? TENTHOUSAND_CHARS2[-value2]
+ : String.valueOf(value2).toCharArray());
+ int len1 = bs1.length;
+ int len2 = bs2.length;
+ int len3 = bs3.length;
+ int len4 = bs4.length;
+ char[] src = expand(len1 + len2 + len3 + len4 + 1);
+ System.arraycopy(bs1, 0, src, count, len1);
+ count += len1;
+ System.arraycopy(bs2, 0, src, count, len2);
+ count += len2;
+ System.arraycopy(bs3, 0, src, count, len3);
+ count += len3;
+ System.arraycopy(bs4, 0, src, count, len4);
+ count += len4;
+ src[count++] = BYTE_RBRACE;
+ }
+
+ public byte[] toBytes() {
+ return Utility.encodeUTF8(content, 0, count);
+ }
+
+ public int count() {
+ return this.count;
+ }
+
+ @Override
+ public void writeString(String value) {
+ writeString(true, value);
+ }
+
+ @Override
+ public void writeString(final boolean quote, String value) {
+ if (value == null) {
+ writeNull();
+ return;
+ }
+ final String str = value;
+ final int len = str.length();
+ char[] chars = expand(len + 2);
+ int curr = count;
+ if (quote) {
+ chars[curr++] = BYTE_DQUOTE;
+ }
+ for (int i = 0; i < len; i++) {
+ char ch = str.charAt(i);
+ switch (ch) {
+ case '\n':
+ chars[curr++] = '\\';
+ chars[curr++] = 'n';
+ break;
+ case '\r':
+ chars[curr++] = '\\';
+ chars[curr++] = 'r';
+ break;
+ case '\f':
+ chars[curr++] = '\\';
+ chars[curr++] = 'f';
+ break;
+ case '\b':
+ chars[curr++] = '\\';
+ chars[curr++] = 'b';
+ break;
+ case '\t':
+ chars[curr++] = '\\';
+ chars[curr++] = 't';
+ break;
+ case '\\':
+ chars[curr++] = '\\';
+ chars[curr++] = ch;
+ break;
+ case '"':
+ chars[curr++] = '\\';
+ chars[curr++] = ch;
+ break;
+ default:
+ chars[curr++] = ch;
+ break;
+ }
+ }
+ if (quote) {
+ chars[curr++] = BYTE_DQUOTE;
+ }
+ count = curr;
+ }
+
+ @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 writeInt(int value) {
+ if (value >= 0 && value < TENTHOUSAND_MAX) {
+ writeTo(TENTHOUSAND_CHARS[value]);
+ return;
+ }
+ if (value < 0 && value > -TENTHOUSAND_MAX) {
+ writeTo(TENTHOUSAND_CHARS2[-value]);
+ return;
+ }
+ final char sign = value >= 0 ? 0 : '-';
+ if (value < 0) value = -value;
+ int size;
+ for (int i = 0; ; i++) {
+ if (value <= sizeTable[i]) {
+ size = i + 1;
+ break;
+ }
+ }
+ if (sign != 0) size++; // 负数
+ expand(size);
+
+ int q, r;
+ int charPos = count + size;
+
+ // Generate two digits per iteration
+ while (value >= 65536) {
+ q = value / 100;
+ // really: r = i - (q * 100);
+ r = value - ((q << 6) + (q << 5) + (q << 2));
+ value = q;
+ content[--charPos] = DigitOnes[r];
+ content[--charPos] = DigitTens[r];
+ }
+
+ // Fall thru to fast mode for smaller numbers
+ // assert(i <= 65536, i);
+ for (; ; ) {
+ q = (value * 52429) >>> (16 + 3);
+ r = value - ((q << 3) + (q << 1)); // r = i-(q*10) ...
+ content[--charPos] = digits[r];
+ value = q;
+ if (value == 0) break;
+ }
+ if (sign != 0) content[--charPos] = sign;
+ count += size;
+ }
+
+ @Override
+ public void writeLong(long value) {
+ if (value >= 0 && value < TENTHOUSAND_MAX) {
+ writeTo(TENTHOUSAND_CHARS[(int) value]);
+ return;
+ }
+ if (value < 0 && value > -TENTHOUSAND_MAX) {
+ writeTo(TENTHOUSAND_CHARS2[(int) -value]);
+ return;
+ }
+ final char sign = value >= 0 ? 0 : '-';
+ if (value < 0) value = -value;
+ int size = 19;
+ long p = 10;
+ for (int i = 1; i < 19; i++) {
+ if (value < p) {
+ size = i;
+ break;
+ }
+ p = 10 * p;
+ }
+ if (sign != 0) size++; // 负数
+ expand(size);
+
+ long q;
+ int r;
+ int charPos = count + size;
+
+ // Get 2 digits/iteration using longs until quotient fits into an int
+ while (value > Integer.MAX_VALUE) {
+ q = value / 100;
+ // really: r = i - (q * 100);
+ r = (int) (value - ((q << 6) + (q << 5) + (q << 2)));
+ value = q;
+ content[--charPos] = DigitOnes[r];
+ content[--charPos] = DigitTens[r];
+ }
+
+ // Get 2 digits/iteration using ints
+ int q2;
+ int i2 = (int) value;
+ while (i2 >= 65536) {
+ q2 = i2 / 100;
+ // really: r = i2 - (q * 100);
+ r = i2 - ((q2 << 6) + (q2 << 5) + (q2 << 2));
+ i2 = q2;
+ content[--charPos] = DigitOnes[r];
+ content[--charPos] = DigitTens[r];
+ }
+
+ // Fall thru to fast mode for smaller numbers
+ // assert(i2 <= 65536, i2);
+ for (; ; ) {
+ q2 = (i2 * 52429) >>> (16 + 3);
+ r = i2 - ((q2 << 3) + (q2 << 1)); // r = i2-(q2*10) ...
+ content[--charPos] = digits[r];
+ i2 = q2;
+ if (i2 == 0) break;
+ }
+ if (sign != 0) content[--charPos] = sign;
+ count += size;
+ }
+
+ @Override
+ public void writeWrapper(StringWrapper wrapper) {
+ if (wrapper == null || wrapper.getValue() == null) {
+ writeNull();
+ return;
+ }
+ String value = wrapper.getValue();
+ if (Utility.isLatin1(value)) {
+ writeTo(Utility.latin1ByteArray(value));
+ return;
+ }
+ int len2 = value.length();
+ char[] chars = expand(len2);
+ value.getChars(0, len2, chars, count);
+ count += len2;
+ }
+}
diff --git a/src/main/java/org/redkale/convert/json/JsonConvert.java b/src/main/java/org/redkale/convert/json/JsonConvert.java
index 0c83bf4cd..8754dff18 100644
--- a/src/main/java/org/redkale/convert/json/JsonConvert.java
+++ b/src/main/java/org/redkale/convert/json/JsonConvert.java
@@ -31,6 +31,8 @@ public class JsonConvert extends TextConvert