JsonCharsWriter
This commit is contained in:
@@ -446,7 +446,7 @@ public class JsonBytesWriter extends JsonWriter implements ByteTuple {
|
|||||||
}
|
}
|
||||||
byte[] utf16s = Utility.byteUTF16Array(value);
|
byte[] utf16s = Utility.byteUTF16Array(value);
|
||||||
if (utf16s != null) { // JDK9+
|
if (utf16s != null) { // JDK9+
|
||||||
writeUTF16String(quote, utf16s);
|
writeEscapeUTF16String(quote, utf16s);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
int len = value.length();
|
int len = value.length();
|
||||||
@@ -513,7 +513,7 @@ public class JsonBytesWriter extends JsonWriter implements ByteTuple {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// see java.lang.StringCoding.encodeUTF8_UTF16 方法
|
// see java.lang.StringCoding.encodeUTF8_UTF16 方法
|
||||||
private void writeUTF16String(final boolean quote, byte[] value) {
|
private void writeEscapeUTF16String(final boolean quote, byte[] value) {
|
||||||
int len = value.length;
|
int len = value.length;
|
||||||
byte[] bytes = expand(len * 4 + 2);
|
byte[] bytes = expand(len * 4 + 2);
|
||||||
int curr = count;
|
int curr = count;
|
||||||
@@ -591,14 +591,14 @@ public class JsonBytesWriter extends JsonWriter implements ByteTuple {
|
|||||||
count = curr;
|
count = curr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static final char MIN_LOW_SURROGATE = '\uDC00';
|
private static final char MIN_LOW_SURROGATE = '\uDC00';
|
||||||
static final char MAX_LOW_SURROGATE = '\uDFFF';
|
private static final char MAX_LOW_SURROGATE = '\uDFFF';
|
||||||
static final char MIN_HIGH_SURROGATE = '\uD800';
|
private static final char MIN_HIGH_SURROGATE = '\uD800';
|
||||||
static final char MAX_HIGH_SURROGATE = '\uDBFF';
|
private static final char MAX_HIGH_SURROGATE = '\uDBFF';
|
||||||
static final int MIN_SUPPLEMENTARY_CODE_POINT = 0x010000;
|
private static final int MIN_SUPPLEMENTARY_CODE_POINT = 0x010000;
|
||||||
static final char MAX_LOW_SURROGATE_MORE = MAX_LOW_SURROGATE + 1;
|
private static final char MAX_LOW_SURROGATE_MORE = MAX_LOW_SURROGATE + 1;
|
||||||
static final char MAX_HIGH_SURROGATE_MORE = MAX_HIGH_SURROGATE + 1;
|
private static final char MAX_HIGH_SURROGATE_MORE = MAX_HIGH_SURROGATE + 1;
|
||||||
static final int MIN_SUPPLEMENTARY_CODE_POINT_MORE =
|
private static final int MIN_SUPPLEMENTARY_CODE_POINT_MORE =
|
||||||
(MIN_SUPPLEMENTARY_CODE_POINT - (MIN_HIGH_SURROGATE << 10) - MIN_LOW_SURROGATE);
|
(MIN_SUPPLEMENTARY_CODE_POINT - (MIN_HIGH_SURROGATE << 10) - MIN_LOW_SURROGATE);
|
||||||
|
|
||||||
private void writeEscapeLatinString(final boolean quote, byte[] value) {
|
private void writeEscapeLatinString(final boolean quote, byte[] value) {
|
||||||
@@ -654,11 +654,8 @@ public class JsonBytesWriter extends JsonWriter implements ByteTuple {
|
|||||||
writeTo(Utility.latin1ByteArray(value));
|
writeTo(Utility.latin1ByteArray(value));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
byte[] utf16s = Utility.byteUTF16Array(value);
|
// 不能使用writeEscapeUTF16String
|
||||||
if (utf16s != null) { // JDK9+
|
//
|
||||||
writeUTF16String(false, utf16s);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
byte[] bytes = expand(value.length() * 4 + 2);
|
byte[] bytes = expand(value.length() * 4 + 2);
|
||||||
int curr = count;
|
int curr = count;
|
||||||
int len = value.length();
|
int len = value.length();
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ public class JsonCharsWriter extends JsonWriter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public JsonCharsWriter(int size) {
|
public JsonCharsWriter(int size) {
|
||||||
this.content = new char[size > 1024 ? size : 1024];
|
this.content = new char[size > DEFAULT_SIZE ? size : DEFAULT_SIZE];
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------
|
// -----------------------------------------------------------------------
|
||||||
@@ -66,7 +66,7 @@ public class JsonCharsWriter extends JsonWriter {
|
|||||||
if (ncount <= content.length) {
|
if (ncount <= content.length) {
|
||||||
return content;
|
return content;
|
||||||
}
|
}
|
||||||
char[] newdata = new char[Math.max(content.length * 3 / 2, ncount)];
|
char[] newdata = new char[Math.max(content.length * 2, ncount)];
|
||||||
System.arraycopy(content, 0, newdata, 0, count);
|
System.arraycopy(content, 0, newdata, 0, count);
|
||||||
this.content = newdata;
|
this.content = newdata;
|
||||||
return newdata;
|
return newdata;
|
||||||
@@ -369,8 +369,17 @@ public class JsonCharsWriter extends JsonWriter {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final String str = value;
|
final String str = value;
|
||||||
|
if (Utility.isLatin1(str)) {
|
||||||
|
writeEscapeLatinString(quote, Utility.latin1ByteArray(str));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// byte[] utf16s = Utility.byteUTF16Array(value);
|
||||||
|
// if (utf16s != null) { // JDK9+
|
||||||
|
// writeEscapeUTF16String(quote, utf16s);
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
final int len = str.length();
|
final int len = str.length();
|
||||||
char[] chars = expand(len + 2);
|
char[] chars = expand(len * 2 + 2);
|
||||||
int curr = count;
|
int curr = count;
|
||||||
if (quote) {
|
if (quote) {
|
||||||
chars[curr++] = BYTE_DQUOTE;
|
chars[curr++] = BYTE_DQUOTE;
|
||||||
@@ -417,6 +426,101 @@ public class JsonCharsWriter extends JsonWriter {
|
|||||||
count = curr;
|
count = curr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void writeEscapeUTF16String(final boolean quote, byte[] value) {
|
||||||
|
byte[] bytes = value;
|
||||||
|
int len = bytes.length;
|
||||||
|
char[] chars = expand(len + 2);
|
||||||
|
int curr = count;
|
||||||
|
if (quote) {
|
||||||
|
chars[curr++] = BYTE_DQUOTE;
|
||||||
|
}
|
||||||
|
byte b1, b2;
|
||||||
|
for (int i = 0; i < len; i += 2) {
|
||||||
|
b1 = bytes[i];
|
||||||
|
b2 = bytes[i + 1];
|
||||||
|
char ch = (char) ((b2 == 0 && b1 >= 0) ? b1 : ((b1 & 0xff) | ((b2 & 0xff) << 8)));
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void writeEscapeLatinString(final boolean quote, byte[] value) {
|
||||||
|
char[] chars = expand(value.length * 2 + 2);
|
||||||
|
int curr = count;
|
||||||
|
if (quote) {
|
||||||
|
chars[curr++] = BYTE_DQUOTE;
|
||||||
|
}
|
||||||
|
for (byte b : value) {
|
||||||
|
if (b == BYTE_DQUOTE) {
|
||||||
|
chars[curr++] = '\\';
|
||||||
|
chars[curr++] = BYTE_DQUOTE;
|
||||||
|
} else if (b == '\\') {
|
||||||
|
chars[curr++] = '\\';
|
||||||
|
chars[curr++] = '\\';
|
||||||
|
} else if (b < 32) {
|
||||||
|
if (b == '\n') {
|
||||||
|
chars[curr++] = '\\';
|
||||||
|
chars[curr++] = 'n';
|
||||||
|
} else if (b == '\r') {
|
||||||
|
chars[curr++] = '\\';
|
||||||
|
chars[curr++] = 'r';
|
||||||
|
} else if (b == '\f') {
|
||||||
|
chars[curr++] = '\\';
|
||||||
|
chars[curr++] = 'f';
|
||||||
|
} else if (b == '\b') {
|
||||||
|
chars[curr++] = '\\';
|
||||||
|
chars[curr++] = 'b';
|
||||||
|
} else if (b == '\t') {
|
||||||
|
chars[curr++] = '\\';
|
||||||
|
chars[curr++] = 't';
|
||||||
|
} else {
|
||||||
|
chars[curr++] = (char) b;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
chars[curr++] = (char) b;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (quote) {
|
||||||
|
chars[curr++] = BYTE_DQUOTE;
|
||||||
|
}
|
||||||
|
count = curr;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return new String(content, 0, count);
|
return new String(content, 0, count);
|
||||||
|
|||||||
@@ -110,9 +110,9 @@ public final class Utility {
|
|||||||
private static final Unsafe unsafeInstance;
|
private static final Unsafe unsafeInstance;
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
private static final Function<Object, Object> strByteFunction;
|
private static final Function<String, byte[]> strByteFunction;
|
||||||
|
|
||||||
private static final Function<Object, Object> sbByteFunction;
|
private static final Function<StringBuilder, byte[]> sbByteFunction;
|
||||||
|
|
||||||
private static final Predicate<Object> strLatin1Function;
|
private static final Predicate<Object> strLatin1Function;
|
||||||
|
|
||||||
@@ -142,8 +142,8 @@ public final class Utility {
|
|||||||
.setRemoveOnCancelPolicy(true);
|
.setRemoveOnCancelPolicy(true);
|
||||||
|
|
||||||
Unsafe unsafe0 = null;
|
Unsafe unsafe0 = null;
|
||||||
Function<Object, Object> strByteFunction0 = null;
|
Function<String, byte[]> strByteFunction0 = null;
|
||||||
Function<Object, Object> sbByteFunction0 = null;
|
Function<StringBuilder, byte[]> sbByteFunction0 = null;
|
||||||
Predicate<Object> strLatin1Function0 = null;
|
Predicate<Object> strLatin1Function0 = null;
|
||||||
ToLongFunction<Object> bufferAddrFunction0 = null;
|
ToLongFunction<Object> bufferAddrFunction0 = null;
|
||||||
Consumer<Consumer<String>> signalShutdownConsumer0 = null;
|
Consumer<Consumer<String>> signalShutdownConsumer0 = null;
|
||||||
@@ -315,10 +315,11 @@ public final class Utility {
|
|||||||
final long fd3 = unsafe0.objectFieldOffset(String.class.getDeclaredField("coder"));
|
final long fd3 = unsafe0.objectFieldOffset(String.class.getDeclaredField("coder"));
|
||||||
final long fd4 = unsafe0.objectFieldOffset(Buffer.class.getDeclaredField("address"));
|
final long fd4 = unsafe0.objectFieldOffset(Buffer.class.getDeclaredField("address"));
|
||||||
Field cf = String.class.getDeclaredField("COMPACT_STRINGS");
|
Field cf = String.class.getDeclaredField("COMPACT_STRINGS");
|
||||||
|
strByteFunction0 = (String t) -> (byte[]) unsafe.getObject(t, fd1);
|
||||||
|
sbByteFunction0 = (StringBuilder t) -> (byte[]) unsafe.getObject(t, fd2);
|
||||||
final boolean compact = unsafe.getBoolean(String.class, unsafe0.staticFieldOffset(cf));
|
final boolean compact = unsafe.getBoolean(String.class, unsafe0.staticFieldOffset(cf));
|
||||||
strByteFunction0 = (Object t) -> unsafe.getObject(t, fd1);
|
// LATIN1:0 UTF16:1
|
||||||
sbByteFunction0 = (Object t) -> unsafe.getObject(t, fd2);
|
strLatin1Function0 = compact ? (Object t) -> unsafe.getByte(t, fd3) == 0 : (Object t) -> false;
|
||||||
strLatin1Function0 = (Object t) -> compact && unsafe.getByte(t, fd3) == 0; // LATIN1:0 UTF16:1
|
|
||||||
bufferAddrFunction0 = (Object t) -> unsafe.getLong(t, fd4);
|
bufferAddrFunction0 = (Object t) -> unsafe.getLong(t, fd4);
|
||||||
}
|
}
|
||||||
{ // signalShutdown
|
{ // signalShutdown
|
||||||
@@ -4915,7 +4916,7 @@ public final class Utility {
|
|||||||
if (value == null || strByteFunction == null) {
|
if (value == null || strByteFunction == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return (byte[]) strByteFunction.apply(value);
|
return strByteFunction.apply(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static char[] charArray(String value) {
|
public static char[] charArray(String value) {
|
||||||
@@ -4940,7 +4941,7 @@ public final class Utility {
|
|||||||
if (strByteFunction == null) {
|
if (strByteFunction == null) {
|
||||||
return latin1Value.getBytes();
|
return latin1Value.getBytes();
|
||||||
}
|
}
|
||||||
return (byte[]) strByteFunction.apply(latin1Value);
|
return strByteFunction.apply(latin1Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 只能是单字节字符串
|
// 只能是单字节字符串
|
||||||
@@ -4951,7 +4952,7 @@ public final class Utility {
|
|||||||
if (sbByteFunction == null) {
|
if (sbByteFunction == null) {
|
||||||
return latin1Value.toString().getBytes();
|
return latin1Value.toString().getBytes();
|
||||||
}
|
}
|
||||||
return (byte[]) sbByteFunction.apply(latin1Value);
|
return sbByteFunction.apply(latin1Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ByteBuffer encodeUTF8(final ByteBuffer buffer, final char[] array) {
|
public static ByteBuffer encodeUTF8(final ByteBuffer buffer, final char[] array) {
|
||||||
|
|||||||
Reference in New Issue
Block a user