Skip to content

Commit e9de784

Browse files
committed
improve float/double ser; add enum support in codegen mode
1 parent 0c66c25 commit e9de784

13 files changed

Lines changed: 91 additions & 22 deletions

File tree

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
44
<modelVersion>4.0.0</modelVersion>
55
<groupId>com.jsoniter</groupId>
6-
<version>0.9.5</version>
6+
<version>0.9.6-SNAPSHOT</version>
77
<artifactId>jsoniter</artifactId>
88
<name>json iterator</name>
99
<description>jsoniter (json-iterator) is fast and flexible JSON parser available in Java and Go</description>

src/main/java/com/jsoniter/Codegen.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,9 @@ private static String genSource(Class clazz, Type[] typeArgs) {
214214
if (Collection.class.isAssignableFrom(clazz)) {
215215
return CodegenImplArray.genCollection(clazz, typeArgs);
216216
}
217+
if (clazz.isEnum()) {
218+
return CodegenImplNative.genEnum(clazz);
219+
}
217220
ClassDescriptor desc = JsoniterSpi.getDecodingClassDescriptor(clazz, false);
218221
if (shouldUseStrictMode(desc)) {
219222
return CodegenImplObject.genObjectUsingStrict(clazz, desc);

src/main/java/com/jsoniter/CodegenImplNative.java

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,13 @@ public static String genNative(String nativeReadKey) {
6060
return "return " + op + ";";
6161
}
6262

63+
public static String genEnum(Class clazz) {
64+
// TODO: avoid create string
65+
StringBuilder lines = new StringBuilder();
66+
append(lines, "return {{clazz}}.valueOf(iter.readString());");
67+
return lines.toString().replace("{{clazz}}", clazz.getName());
68+
}
69+
6370
public static String genReadOp(Type type) {
6471
if (type instanceof Class) {
6572
Class clazz = (Class) type;
@@ -91,11 +98,8 @@ public static String getTypeName(Type fieldType) {
9198
}
9299
}
93100

94-
public static boolean isNative(Type valueType) {
95-
if (valueType instanceof Class) {
96-
Class clazz = (Class) valueType;
97-
return NATIVE_READS.containsKey(clazz.getCanonicalName());
98-
}
99-
return false;
101+
private static void append(StringBuilder lines, String str) {
102+
lines.append(str);
103+
lines.append("\n");
100104
}
101105
}

src/main/java/com/jsoniter/IterImpl.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,7 @@ final static byte nextToken(JsonIterator iter) throws IOException {
162162
}
163163
}
164164
} catch (IndexOutOfBoundsException e) {
165+
iter.head = iter.tail;
165166
return 0;
166167
}
167168
}

src/main/java/com/jsoniter/JsonIterator.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,9 +113,9 @@ public final void close() throws IOException {
113113
}
114114
}
115115

116-
final void unreadByte() throws IOException {
116+
final void unreadByte() {
117117
if (head == 0) {
118-
throw new IOException("unread too many bytes");
118+
throw reportError("unreadByte", "unread too many bytes");
119119
}
120120
head--;
121121
}

src/main/java/com/jsoniter/output/Codegen.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,9 @@ private static String genSource(Class clazz, Type[] typeArgs) {
189189
if (Collection.class.isAssignableFrom(clazz)) {
190190
return CodegenImplArray.genCollection(clazz, typeArgs);
191191
}
192+
if (clazz.isEnum()) {
193+
return CodegenImplNative.genEnum(clazz);
194+
}
192195
return CodegenImplObject.genObject(clazz);
193196
}
194197

src/main/java/com/jsoniter/output/CodegenImplNative.java

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@
22

33
import com.jsoniter.JsonException;
44
import com.jsoniter.any.Any;
5-
import com.jsoniter.spi.Encoder;
6-
import com.jsoniter.spi.TypeLiteral;
5+
import com.jsoniter.spi.*;
76

87
import java.io.IOException;
8+
import java.lang.reflect.Method;
99
import java.lang.reflect.ParameterizedType;
1010
import java.lang.reflect.Type;
1111
import java.math.BigDecimal;
@@ -291,4 +291,20 @@ public static String getTypeName(Type fieldType) {
291291
throw new JsonException("unsupported type: " + fieldType);
292292
}
293293
}
294+
public static String genEnum(Class clazz) {
295+
ClassDescriptor desc = JsoniterSpi.getEncodingClassDescriptor(clazz, false);
296+
StringBuilder lines = new StringBuilder();
297+
append(lines, String.format("public static void encode_(java.lang.Object obj, com.jsoniter.output.JsonStream stream) throws java.io.IOException {", clazz.getCanonicalName()));
298+
append(lines, "if (obj == null) { stream.writeNull(); return; }");
299+
append(lines, "stream.write('\"');");
300+
append(lines, "stream.writeRaw(obj.toString());");
301+
append(lines, "stream.write('\"');");
302+
append(lines, "}");
303+
return lines.toString();
304+
}
305+
306+
private static void append(StringBuilder lines, String str) {
307+
lines.append(str);
308+
lines.append("\n");
309+
}
294310
}

src/main/java/com/jsoniter/output/JsonStream.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ public class JsonStream extends OutputStream {
1212

1313
public static int defaultIndentionStep = 0;
1414
public int indentionStep = defaultIndentionStep;
15-
public int indention = 0;
15+
private int indention = 0;
1616
private OutputStream out;
1717
private static final byte[] NULL = "null".getBytes();
1818
private static final byte[] TRUE = "true".getBytes();

src/main/java/com/jsoniter/output/StreamImplNumber.java

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -152,16 +152,19 @@ private static int stringSize(long x) {
152152
}
153153

154154
private static final int POW10[] = {1, 10, 100, 1000, 10000, 100000, 1000000};
155-
private static final long MAX_DOUBLE_TO_WRITE = Long.MAX_VALUE / 1000000 - 1;
156155

157156
public static final void writeFloat(JsonStream stream, float val) throws IOException {
158157
if (val < 0) {
159158
stream.write('-');
160159
val = -val;
161160
}
161+
if (val > 0x4ffffff) {
162+
stream.writeRaw(Float.toString(val));
163+
return;
164+
}
162165
int precision = 6;
163-
int exp = POW10[precision];
164-
long lval = (long)(val * exp + 0.5);
166+
int exp = 1000000; // 6
167+
long lval = (long)((double)val * exp + 0.5);
165168
stream.writeVal(lval / exp);
166169
long fval = lval % exp;
167170
if (fval == 0) {
@@ -172,7 +175,7 @@ public static final void writeFloat(JsonStream stream, float val) throws IOExcep
172175
stream.flushBuffer();
173176
}
174177
for (int p = precision - 1; p > 0 && fval < POW10[p]; p--) {
175-
stream.write('0');
178+
stream.buf[stream.count++] = '0';
176179
}
177180
stream.writeVal(fval);
178181
while(stream.buf[stream.count-1] == '0') {
@@ -185,12 +188,12 @@ public static final void writeDouble(JsonStream stream, double val) throws IOExc
185188
val = -val;
186189
stream.write('-');
187190
}
188-
if (val > MAX_DOUBLE_TO_WRITE) {
191+
if (val > 0x4ffffff) {
189192
stream.writeRaw(Double.toString(val));
190193
return;
191194
}
192195
int precision = 6;
193-
int exp = POW10[precision];
196+
int exp = 1000000; // 6
194197
long lval = (long)(val * exp + 0.5);
195198
stream.writeVal(lval / exp);
196199
long fval = lval % exp;
@@ -202,7 +205,7 @@ public static final void writeDouble(JsonStream stream, double val) throws IOExc
202205
stream.flushBuffer();
203206
}
204207
for (int p = precision - 1; p > 0 && fval < POW10[p]; p--) {
205-
stream.write('0');
208+
stream.buf[stream.count++] = '0';
206209
}
207210
stream.writeVal(fval);
208211
while(stream.buf[stream.count-1] == '0') {

src/main/java/com/jsoniter/spi/TypeLiteral.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,12 @@ private static String generateCacheKey(Type type, String prefix) {
9494
if (clazz.isAnonymousClass()) {
9595
throw new JsonException("anonymous class not supported: " + clazz);
9696
}
97-
decoderClassName.append(clazz.getCanonicalName().replace("[]", "_array"));
97+
if (clazz.isArray()) {
98+
decoderClassName.append(clazz.getCanonicalName().replace("[]", "_array"));
99+
} else {
100+
// for nested class $
101+
decoderClassName.append(clazz.getName().replace("[]", "_array"));
102+
}
98103
} else if (type instanceof ParameterizedType) {
99104
try {
100105
ParameterizedType pType = (ParameterizedType) type;

0 commit comments

Comments
 (0)