CharArray
This commit is contained in:
@@ -123,6 +123,10 @@ public class JsonCharsWriter extends JsonWriter {
|
||||
*/
|
||||
@Override
|
||||
public void writeLatin1To(final boolean quote, final String value) {
|
||||
if (value == null) {
|
||||
writeNull();
|
||||
return;
|
||||
}
|
||||
int len = value.length();
|
||||
if (quote) {
|
||||
expand(len + 2);
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
package org.redkale.convert.json;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
import org.redkale.convert.*;
|
||||
import static org.redkale.convert.Reader.*;
|
||||
@@ -27,6 +28,8 @@ public class JsonReader extends Reader {
|
||||
|
||||
private int limit;
|
||||
|
||||
private CharArray array;
|
||||
|
||||
// public static ObjectPool<JsonReader> createPool(int max) {
|
||||
// return new ObjectPool<>(max, (Object... params) -> new JsonReader(), null, JsonReader::recycle);
|
||||
// }
|
||||
@@ -69,9 +72,23 @@ public class JsonReader extends Reader {
|
||||
this.position = -1;
|
||||
this.limit = -1;
|
||||
this.text = null;
|
||||
if (this.array != null) {
|
||||
if (this.array.content.length > 102400) {
|
||||
this.array = null;
|
||||
} else {
|
||||
this.array.clear();
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
protected CharArray array() {
|
||||
if (array == null) {
|
||||
array = new CharArray();
|
||||
}
|
||||
return array.clear();
|
||||
}
|
||||
|
||||
public void close() {
|
||||
this.recycle();
|
||||
}
|
||||
@@ -369,59 +386,6 @@ public class JsonReader extends Reader {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String readSmallString() {
|
||||
final int eof = this.limit;
|
||||
if (this.position == eof) {
|
||||
return null;
|
||||
}
|
||||
char ch = nextGoodChar(true); // 需要跳过注释
|
||||
final char[] text0 = this.text;
|
||||
int currpos = this.position;
|
||||
if (ch == '"' || ch == '\'') {
|
||||
final char quote = ch;
|
||||
final int start = currpos + 1;
|
||||
for (; ; ) {
|
||||
ch = text0[++currpos];
|
||||
if (ch == '\\') {
|
||||
this.position = currpos - 1;
|
||||
return readEscapeValue(quote, start);
|
||||
} else if (ch == quote) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
this.position = currpos;
|
||||
char[] chs = new char[currpos - start];
|
||||
System.arraycopy(text0, start, chs, 0, chs.length);
|
||||
return new String(chs);
|
||||
} else {
|
||||
int start = currpos;
|
||||
for (; ; ) {
|
||||
if (currpos == eof) {
|
||||
break;
|
||||
}
|
||||
ch = text0[++currpos];
|
||||
if (ch == ',' || ch == ']' || ch == '}' || ch <= ' ' || ch == ':') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
int len = currpos - start;
|
||||
if (len < 1) {
|
||||
this.position = currpos;
|
||||
return String.valueOf(ch);
|
||||
}
|
||||
this.position = currpos - 1;
|
||||
if (len == 4
|
||||
&& text0[start] == 'n'
|
||||
&& text0[start + 1] == 'u'
|
||||
&& text0[start + 2] == 'l'
|
||||
&& text0[start + 3] == 'l') {
|
||||
return null;
|
||||
}
|
||||
return new String(text0, start, len == eof ? (len + 1) : len);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 读取一个int值
|
||||
*
|
||||
@@ -835,6 +799,57 @@ public class JsonReader extends Reader {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String readSmallString() {
|
||||
final int eof = this.limit;
|
||||
if (this.position == eof) {
|
||||
return null;
|
||||
}
|
||||
char ch = nextGoodChar(true); // 需要跳过注释
|
||||
final char[] text0 = this.text;
|
||||
int currpos = this.position;
|
||||
if (ch == '"' || ch == '\'') {
|
||||
final char quote = ch;
|
||||
final int start = currpos + 1;
|
||||
for (; ; ) {
|
||||
ch = text0[++currpos];
|
||||
if (ch == '\\') {
|
||||
this.position = currpos - 1;
|
||||
return readEscapeValue(quote, start);
|
||||
} else if (ch == quote) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
this.position = currpos;
|
||||
return new String(text0, start, currpos - start);
|
||||
} else {
|
||||
int start = currpos;
|
||||
for (; ; ) {
|
||||
if (currpos == eof) {
|
||||
break;
|
||||
}
|
||||
ch = text0[++currpos];
|
||||
if (ch == ',' || ch == ']' || ch == '}' || ch <= ' ' || ch == ':') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
int len = currpos - start;
|
||||
if (len < 1) {
|
||||
this.position = currpos;
|
||||
return String.valueOf(ch);
|
||||
}
|
||||
this.position = currpos - 1;
|
||||
if (len == 4
|
||||
&& text0[start] == 'n'
|
||||
&& text0[start + 1] == 'u'
|
||||
&& text0[start + 2] == 'l'
|
||||
&& text0[start + 3] == 'l') {
|
||||
return null;
|
||||
}
|
||||
return new String(text0, start, len == eof ? (len + 1) : len);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 读取字符串, 必须是"或者'包围的字符串值
|
||||
*
|
||||
@@ -909,22 +924,63 @@ public class JsonReader extends Reader {
|
||||
+ position + ") in (" + new String(this.text) + ")");
|
||||
}
|
||||
final int start = ++currpos;
|
||||
CharArray array = null;
|
||||
char c;
|
||||
for (; ; ) {
|
||||
char ch = text0[currpos];
|
||||
if (ch == expected) {
|
||||
break;
|
||||
} else if (ch == '\\') {
|
||||
this.position = currpos - 1;
|
||||
return readEscapeValue(expected, start);
|
||||
if (array == null) {
|
||||
array = array();
|
||||
array.append(text0, start, currpos - start);
|
||||
}
|
||||
c = text0[++currpos];
|
||||
switch (c) {
|
||||
case '"':
|
||||
case '\'':
|
||||
case '\\':
|
||||
case '/':
|
||||
array.append(c);
|
||||
break;
|
||||
case 'n':
|
||||
array.append('\n');
|
||||
break;
|
||||
case 'r':
|
||||
array.append('\r');
|
||||
break;
|
||||
case 'u':
|
||||
array.append((char) Integer.parseInt(
|
||||
new String(new char[] {
|
||||
text0[++currpos], text0[++currpos], text0[++currpos], text0[++currpos]
|
||||
}),
|
||||
16));
|
||||
break;
|
||||
case 't':
|
||||
array.append('\t');
|
||||
break;
|
||||
case 'b':
|
||||
array.append('\b');
|
||||
break;
|
||||
case 'f':
|
||||
array.append('\f');
|
||||
break;
|
||||
default:
|
||||
this.position = currpos;
|
||||
throw new ConvertException("illegal escape(" + c + ") (position = " + this.position + ") in ("
|
||||
+ new String(this.text) + ")");
|
||||
}
|
||||
} else if (array != null) {
|
||||
array.append(ch);
|
||||
}
|
||||
currpos++;
|
||||
}
|
||||
this.position = currpos;
|
||||
return new String(text0, start, currpos - start);
|
||||
return array != null ? array.toStringThenClear() : new String(text0, start, currpos - start);
|
||||
}
|
||||
|
||||
private String readEscapeValue(final char expected, int start) {
|
||||
StringBuilder array = new StringBuilder();
|
||||
CharArray array = this.array();
|
||||
final char[] text0 = this.text;
|
||||
int pos = this.position;
|
||||
array.append(text0, start, pos + 1 - start);
|
||||
@@ -933,7 +989,7 @@ public class JsonReader extends Reader {
|
||||
c = text0[++pos];
|
||||
if (c == expected) {
|
||||
this.position = pos;
|
||||
return array.toString();
|
||||
return array.toStringThenClear();
|
||||
} else if (c == '\\') {
|
||||
c = text0[++pos];
|
||||
switch (c) {
|
||||
@@ -992,4 +1048,63 @@ public class JsonReader extends Reader {
|
||||
digits[' '] = digits['\t'] = digits['\r'] = digits['\n'] = -3; // -3可能跳过
|
||||
digits[','] = digits['}'] = digits[']'] = digits[':'] = -4; // -4退出
|
||||
}
|
||||
|
||||
protected static class CharArray {
|
||||
|
||||
private int count;
|
||||
|
||||
private char[] content = new char[1024];
|
||||
|
||||
private char[] expand(int len) {
|
||||
int newcount = count + len;
|
||||
if (newcount <= content.length) {
|
||||
return content;
|
||||
}
|
||||
char[] newdata = new char[Math.max(content.length * 2, newcount)];
|
||||
System.arraycopy(content, 0, newdata, 0, count);
|
||||
this.content = newdata;
|
||||
return newdata;
|
||||
}
|
||||
|
||||
public CharArray append(char[] str, int offset, int len) {
|
||||
char[] chs = expand(len);
|
||||
System.arraycopy(str, offset, chs, count, len);
|
||||
count += len;
|
||||
return this;
|
||||
}
|
||||
|
||||
public CharArray append(char ch) {
|
||||
char[] chs = expand(1);
|
||||
chs[count++] = ch;
|
||||
return this;
|
||||
}
|
||||
|
||||
public CharArray clear() {
|
||||
this.count = 0;
|
||||
return this;
|
||||
}
|
||||
|
||||
public char[] content() {
|
||||
return content;
|
||||
}
|
||||
|
||||
public int length() {
|
||||
return count;
|
||||
}
|
||||
|
||||
public char[] getChars() {
|
||||
return Arrays.copyOfRange(content, 0, count);
|
||||
}
|
||||
|
||||
public String toStringThenClear() {
|
||||
String s = toString();
|
||||
this.count = 0;
|
||||
return s;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new String(content, 0, count);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,16 +8,14 @@ package org.redkale.test.convert;
|
||||
import java.util.*;
|
||||
import org.junit.jupiter.api.*;
|
||||
import org.redkale.convert.Convert;
|
||||
import org.redkale.convert.ConvertSmallString;
|
||||
import org.redkale.convert.json.*;
|
||||
|
||||
/** @author zhangjx */
|
||||
public class Json5Test {
|
||||
|
||||
private boolean main;
|
||||
|
||||
public static void main(String[] args) throws Throwable {
|
||||
Json5Test test = new Json5Test();
|
||||
test.main = true;
|
||||
test.run1();
|
||||
test.run2();
|
||||
}
|
||||
@@ -36,14 +34,16 @@ public class Json5Test {
|
||||
JsonConvert convert = JsonConvert.root();
|
||||
Json5Bean bean = new Json5Bean();
|
||||
bean.id = 500;
|
||||
bean.idx = 600;
|
||||
bean.decmails = 3.2f;
|
||||
bean.value = 44444;
|
||||
bean.name = "haha";
|
||||
String json = "{/*多行\r\n注释**/\"decmails\":3.2,//单行注释\r\n\"id\":0x1F4,\"name\":\"haha\",\"value\":44444,}";
|
||||
bean.name = "ha\t\"ha";
|
||||
bean.desc = "normal";
|
||||
String json =
|
||||
"{/*多行\r\n注释**/\"decmails\":3.2,//单行注释\r\n\"id\":0x1F4,\"idx\":600,\"name\":\"ha\\t\\\"ha\",\"desc\":\"normal\",\"value\":44444,}";
|
||||
Json5Bean bean2 = convert.convertFrom(Json5Bean.class, json);
|
||||
if (!main) {
|
||||
Assertions.assertTrue(bean.equals(bean2));
|
||||
}
|
||||
System.out.println(bean2.name);
|
||||
Assertions.assertTrue(bean.equals(bean2));
|
||||
System.out.println(convert.convertTo(bean2));
|
||||
|
||||
String arrayJson = "[" + json + "," + json + "," + "]";
|
||||
@@ -59,16 +59,22 @@ public class Json5Test {
|
||||
|
||||
public int id;
|
||||
|
||||
public int idx;
|
||||
|
||||
public float decmails;
|
||||
|
||||
public long value;
|
||||
|
||||
public String name;
|
||||
|
||||
@ConvertSmallString
|
||||
public String desc;
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int hash = 7;
|
||||
hash = 47 * hash + this.id;
|
||||
hash = 47 * hash + this.idx;
|
||||
hash = 47 * hash + Float.floatToIntBits(this.decmails);
|
||||
hash = 47 * hash + (int) (this.value ^ (this.value >>> 32));
|
||||
hash = 47 * hash + Objects.hashCode(this.name);
|
||||
@@ -90,6 +96,9 @@ public class Json5Test {
|
||||
if (this.id != other.id) {
|
||||
return false;
|
||||
}
|
||||
if (this.idx != other.idx) {
|
||||
return false;
|
||||
}
|
||||
if (Float.floatToIntBits(this.decmails) != Float.floatToIntBits(other.decmails)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user