Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
now readSlice will read either a DirectSlice, if there were no escape…
… or multibyte chars, or will allocate a String and return a StringSlice
  • Loading branch information
Miha-x64 committed Mar 4, 2018
commit b37c85171d1e0bc99bb50b71685b45e71aaf777f
1 change: 1 addition & 0 deletions src/main/java/com/jsoniter/CodegenAccess.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.jsoniter;

import com.jsoniter.slice.Slice;
import com.jsoniter.spi.*;

import java.io.IOException;
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/com/jsoniter/CodegenImplEnum.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ class CodegenImplEnum {
public static String genEnum(ClassInfo classInfo) {
StringBuilder lines = new StringBuilder();
append(lines, "if (iter.readNull()) { return null; }");
append(lines, "com.jsoniter.spi.Slice field = com.jsoniter.CodegenAccess.readSlice(iter);");
append(lines, "com.jsoniter.slice.Slice field = com.jsoniter.CodegenAccess.readSlice(iter);");
append(lines, "switch (field.len()) {");
append(lines, renderTriTree(buildTriTree(Arrays.asList(classInfo.clazz.getEnumConstants()))));
append(lines, "}"); // end of switch
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/com/jsoniter/CodegenImplObjectStrict.java
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ public static String genObjectUsingStrict(ClassDescriptor desc) {
if (desc.onExtraProperties != null || !desc.keyValueTypeWrappers.isEmpty()) {
append(lines, "java.util.Map extra = null;");
}
append(lines, "com.jsoniter.spi.Slice field = com.jsoniter.CodegenAccess.readObjectFieldAsSlice(iter);");
append(lines, "com.jsoniter.slice.Slice field = com.jsoniter.CodegenAccess.readObjectFieldAsSlice(iter);");
append(lines, "boolean once = true;");
append(lines, "while (once) {");
append(lines, "once = false;");
Expand Down
126 changes: 4 additions & 122 deletions src/main/java/com/jsoniter/IterImpl.java
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package com.jsoniter;

import com.jsoniter.any.Any;
import com.jsoniter.slice.Slice;
import com.jsoniter.spi.JsonException;
import com.jsoniter.spi.Slice;

import java.io.IOException;
import java.math.BigInteger;
Expand Down Expand Up @@ -140,18 +140,11 @@ final static boolean skipNumber(JsonIterator iter) throws IOException {

// read the bytes between " "
public final static Slice readSlice(JsonIterator iter) throws IOException {
if (IterImpl.nextToken(iter) != '"') {
Slice slice = IterImplString.readSlice(iter);
if (slice == null) {
throw iter.reportError("readSlice", "expect \" for string");
}
int end = IterImplString.findSliceEnd(iter);
if (end == -1) {
throw iter.reportError("readSlice", "incomplete string");
} else {
// reuse current buffer
iter.reusableSlice.reset(iter.buf, iter.head, end - 1);
iter.head = end;
return iter.reusableSlice;
}
return slice;
}

final static byte nextToken(final JsonIterator iter) throws IOException {
Expand Down Expand Up @@ -214,117 +207,6 @@ public final static boolean loadMore(JsonIterator iter) throws IOException {
return false;
}

public final static int readStringSlowPath(JsonIterator iter, int j) throws IOException {
try {
boolean isExpectingLowSurrogate = false;
for (int i = iter.head; i < iter.tail; ) {
int bc = iter.buf[i++];
if (bc == '"') {
iter.head = i;
return j;
}
if (bc == '\\') {
bc = iter.buf[i++];
switch (bc) {
case 'b':
bc = '\b';
break;
case 't':
bc = '\t';
break;
case 'n':
bc = '\n';
break;
case 'f':
bc = '\f';
break;
case 'r':
bc = '\r';
break;
case '"':
case '/':
case '\\':
break;
case 'u':
bc = (IterImplString.translateHex(iter.buf[i++]) << 12) +
(IterImplString.translateHex(iter.buf[i++]) << 8) +
(IterImplString.translateHex(iter.buf[i++]) << 4) +
IterImplString.translateHex(iter.buf[i++]);
if (Character.isHighSurrogate((char) bc)) {
if (isExpectingLowSurrogate) {
throw new JsonException("invalid surrogate");
} else {
isExpectingLowSurrogate = true;
}
} else if (Character.isLowSurrogate((char) bc)) {
if (isExpectingLowSurrogate) {
isExpectingLowSurrogate = false;
} else {
throw new JsonException("invalid surrogate");
}
} else {
if (isExpectingLowSurrogate) {
throw new JsonException("invalid surrogate");
}
}
break;

default:
throw iter.reportError("readStringSlowPath", "invalid escape character: " + bc);
}
} else if ((bc & 0x80) != 0) {
final int u2 = iter.buf[i++];
if ((bc & 0xE0) == 0xC0) {
bc = ((bc & 0x1F) << 6) + (u2 & 0x3F);
} else {
final int u3 = iter.buf[i++];
if ((bc & 0xF0) == 0xE0) {
bc = ((bc & 0x0F) << 12) + ((u2 & 0x3F) << 6) + (u3 & 0x3F);
} else {
final int u4 = iter.buf[i++];
if ((bc & 0xF8) == 0xF0) {
bc = ((bc & 0x07) << 18) + ((u2 & 0x3F) << 12) + ((u3 & 0x3F) << 6) + (u4 & 0x3F);
} else {
throw iter.reportError("readStringSlowPath", "invalid unicode character");
}

if (bc >= 0x10000) {
// check if valid unicode
if (bc >= 0x110000)
throw iter.reportError("readStringSlowPath", "invalid unicode character");

// split surrogates
final int sup = bc - 0x10000;
if (iter.reusableChars.length == j) {
char[] newBuf = new char[iter.reusableChars.length * 2];
System.arraycopy(iter.reusableChars, 0, newBuf, 0, iter.reusableChars.length);
iter.reusableChars = newBuf;
}
iter.reusableChars[j++] = (char) ((sup >>> 10) + 0xd800);
if (iter.reusableChars.length == j) {
char[] newBuf = new char[iter.reusableChars.length * 2];
System.arraycopy(iter.reusableChars, 0, newBuf, 0, iter.reusableChars.length);
iter.reusableChars = newBuf;
}
iter.reusableChars[j++] = (char) ((sup & 0x3ff) + 0xdc00);
continue;
}
}
}
}
if (iter.reusableChars.length == j) {
char[] newBuf = new char[iter.reusableChars.length * 2];
System.arraycopy(iter.reusableChars, 0, newBuf, 0, iter.reusableChars.length);
iter.reusableChars = newBuf;
}
iter.reusableChars[j++] = (char) bc;
}
throw iter.reportError("readStringSlowPath", "incomplete string");
} catch (IndexOutOfBoundsException e) {
throw iter.reportError("readString", "incomplete string");
}
}

public static int updateStringCopyBound(final JsonIterator iter, final int bound) {
return bound;
}
Expand Down
17 changes: 11 additions & 6 deletions src/main/java/com/jsoniter/IterImplForStreaming.java
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
package com.jsoniter;

import com.jsoniter.any.Any;
import com.jsoniter.slice.DirectSlice;
import com.jsoniter.slice.Slice;
import com.jsoniter.spi.JsonException;
import com.jsoniter.spi.Slice;

import java.io.IOException;

Expand Down Expand Up @@ -45,7 +46,9 @@ public static final Slice readObjectFieldAsSlice(JsonIterator iter) throws IOExc
int len = field.tail() - field.head();
byte[] newBuf = new byte[len];
System.arraycopy(field.data(), field.head(), newBuf, 0, len);
field.reset(newBuf, 0, newBuf.length);
DirectSlice ds = iter.rDirectSlice;
ds.reset(newBuf, 0, newBuf.length);
field = ds;
}
if (!loadMore(iter)) {
throw iter.reportError("readObjectFieldAsSlice", "expect : after object field");
Expand Down Expand Up @@ -203,9 +206,10 @@ final static Slice readSlice(JsonIterator iter) throws IOException {
int end = IterImplString.findSliceEnd(iter);
if (end != -1) {
// reuse current buffer
iter.reusableSlice.reset(iter.buf, iter.head, end - 1);
DirectSlice slice = iter.rDirectSlice;
slice.reset(iter.buf, iter.head, end - 1);
iter.head = end;
return iter.reusableSlice;
return slice;
}
// TODO: avoid small memory allocation
byte[] part1 = new byte[iter.tail - iter.head];
Expand All @@ -225,8 +229,9 @@ final static Slice readSlice(JsonIterator iter) throws IOException {
System.arraycopy(part1, 0, part2, 0, part1.length);
System.arraycopy(iter.buf, 0, part2, part1.length, end - 1);
iter.head = end;
iter.reusableSlice.reset(part2, 0, part2.length);
return iter.reusableSlice;
DirectSlice slice = iter.rDirectSlice;
slice.reset(part2, 0, part2.length);
return slice;
}
}
}
Expand Down
Loading