Skip to content

Commit 85ae951

Browse files
committed
Merge remote-tracking branch 'origin/master' into pull/add-omit-zero
2 parents d84a9f3 + 7d8caf4 commit 85ae951

File tree

9 files changed

+186
-72
lines changed

9 files changed

+186
-72
lines changed

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

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ public static CodegenResult genArray(String cacheKey, ClassInfo classInfo) {
3030
if (isCollectionValueNullable) {
3131
ctx.append("if (e == null) { stream.writeNull(); } else {");
3232
CodegenImplNative.genWriteOp(ctx, "e", compType, true);
33-
ctx.append("}");
33+
ctx.append("}"); // if
3434
} else {
3535
CodegenImplNative.genWriteOp(ctx, "e", compType, false);
3636
}
@@ -40,13 +40,13 @@ public static CodegenResult genArray(String cacheKey, ClassInfo classInfo) {
4040
if (isCollectionValueNullable) {
4141
ctx.append("if (e == null) { stream.writeNull(); } else {");
4242
CodegenImplNative.genWriteOp(ctx, "e", compType, true);
43-
ctx.append("}");
43+
ctx.append("}"); // if
4444
} else {
4545
CodegenImplNative.genWriteOp(ctx, "e", compType, false);
4646
}
47-
ctx.append("}");
47+
ctx.append("}"); // while
4848
ctx.buffer(']');
49-
ctx.append("}");
49+
ctx.append("}"); // public static void encode_
5050
return ctx;
5151
}
5252

@@ -100,13 +100,13 @@ private static CodegenResult genList(String cacheKey, Class clazz, Type compType
100100
if (isCollectionValueNullable) {
101101
ctx.append("if (e == null) { stream.writeNull(); } else {");
102102
CodegenImplNative.genWriteOp(ctx, "e", compType, true);
103-
ctx.append("}");
103+
ctx.append("}"); // if
104104
} else {
105105
CodegenImplNative.genWriteOp(ctx, "e", compType, false);
106106
}
107-
ctx.append("}");
107+
ctx.append("}"); // for
108108
ctx.buffer(']');
109-
ctx.append("}");
109+
ctx.append("}"); // public static void encode_
110110
return ctx;
111111
}
112112

@@ -124,7 +124,7 @@ private static CodegenResult genCollection(String cacheKey, Class clazz, Type co
124124
if (isCollectionValueNullable) {
125125
ctx.append("if (e == null) { stream.writeNull(); } else {");
126126
CodegenImplNative.genWriteOp(ctx, "e", compType, true);
127-
ctx.append("}");
127+
ctx.append("}"); // if
128128
} else {
129129
CodegenImplNative.genWriteOp(ctx, "e", compType, false);
130130
}
@@ -134,13 +134,13 @@ private static CodegenResult genCollection(String cacheKey, Class clazz, Type co
134134
if (isCollectionValueNullable) {
135135
ctx.append("if (e == null) { stream.writeNull(); } else {");
136136
CodegenImplNative.genWriteOp(ctx, "e", compType, true);
137-
ctx.append("}");
137+
ctx.append("}"); // if
138138
} else {
139139
CodegenImplNative.genWriteOp(ctx, "e", compType, false);
140140
}
141-
ctx.append("}");
141+
ctx.append("}"); // while
142142
ctx.buffer(']');
143-
ctx.append("}");
143+
ctx.append("}"); // public static void encode_
144144
return ctx;
145145
}
146146

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -269,9 +269,10 @@ public static void genWriteOp(CodegenResult ctx, String code, Type valueType, bo
269269
}
270270

271271
public static void genWriteOp(CodegenResult ctx, String code, Type valueType, boolean isNullable, boolean isCollectionValueNullable) {
272+
boolean supportBuffer = JsoniterSpi.getCurrentConfig().indentionStep() == 0;
272273
String cacheKey = TypeLiteral.create(valueType).getEncoderCacheKey();
273274
if (JsoniterSpi.getEncoder(cacheKey) == null) {
274-
if (!isNullable && String.class == valueType) {
275+
if (supportBuffer && !isNullable && String.class == valueType) {
275276
ctx.buffer('"');
276277
ctx.append(String.format("com.jsoniter.output.CodegenAccess.writeStringWithoutQuote((java.lang.String)%s, stream);", code));
277278
ctx.buffer('"');

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

Lines changed: 55 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,18 @@
66

77
class CodegenImplObject {
88
public static CodegenResult genObject(ClassInfo classInfo) {
9-
9+
boolean supportBuffer = JsoniterSpi.getCurrentConfig().indentionStep() == 0;
1010
CodegenResult ctx = new CodegenResult();
1111
ClassDescriptor desc = ClassDescriptor.getEncodingClassDescriptor(classInfo, false);
1212
List<EncodeTo> encodeTos = desc.encodeTos();
1313
ctx.append(String.format("public static void encode_(%s obj, com.jsoniter.output.JsonStream stream) throws java.io.IOException {", classInfo.clazz.getCanonicalName()));
1414
if (hasFieldOutput(desc)) {
1515
int notFirst = 0;
16-
ctx.buffer('{');
16+
if (supportBuffer) {
17+
ctx.buffer('{');
18+
} else {
19+
ctx.append("stream.writeObjectStart();");
20+
}
1721
for (EncodeTo encodeTo : encodeTos) {
1822
notFirst = genField(ctx, encodeTo.binding, encodeTo.toName, notFirst);
1923
}
@@ -34,7 +38,11 @@ public static CodegenResult genObject(ClassInfo classInfo) {
3438
ctx.append(String.format("obj.%s(stream);", unwrapper.method.getName()));
3539
}
3640
}
37-
ctx.buffer('}');
41+
if (supportBuffer) {
42+
ctx.buffer('}');
43+
} else {
44+
ctx.append("if (notFirst) { stream.writeObjectEnd(); } else { stream.write('}'); }");
45+
}
3846
} else {
3947
ctx.buffer("{}");
4048
}
@@ -51,6 +59,7 @@ private static boolean hasFieldOutput(ClassDescriptor desc) {
5159
}
5260

5361
private static int genField(CodegenResult ctx, Binding binding, String toName, int notFirst) {
62+
boolean supportBuffer = JsoniterSpi.getCurrentConfig().indentionStep() == 0;
5463
String fieldCacheKey = binding.encoderCacheKey();
5564
Encoder encoder = JsoniterSpi.getEncoder(fieldCacheKey);
5665
boolean isCollectionValueNullable = binding.isCollectionValueNullable;
@@ -79,31 +88,47 @@ private static int genField(CodegenResult ctx, Binding binding, String toName, i
7988
}
8089
ctx.append(String.format("if (%s != null) {", valueAccessor));
8190
notFirst = appendComma(ctx, notFirst);
82-
ctx.append(CodegenResult.bufferToWriteOp("\"" + toName + "\":"));
91+
if (supportBuffer) {
92+
ctx.append(CodegenResult.bufferToWriteOp("\"" + toName + "\":"));
93+
} else {
94+
ctx.append(String.format("stream.writeObjectField(\"%s\");", toName));
95+
}
8396
} else {
8497
notFirst = appendComma(ctx, notFirst);
85-
ctx.buffer('"');
86-
ctx.buffer(toName);
87-
ctx.buffer('"');
88-
ctx.buffer(':');
98+
if (supportBuffer) {
99+
ctx.buffer('"');
100+
ctx.buffer(toName);
101+
ctx.buffer('"');
102+
ctx.buffer(':');
103+
} else {
104+
ctx.append(String.format("stream.writeObjectField(\"%s\");", toName));
105+
}
89106
ctx.append(String.format("if (%s == null) { stream.writeNull(); } else {", valueAccessor));
90107
}
91108
} else {
92109
if (encoder == null && valueClazz.isPrimitive() && !(valueClazz == String.class) && omitZero) {
93-
if (notFirst == 0) {
94-
notFirst = 2;
110+
if (notFirst == 0) { // no previous field
111+
notFirst = 2; // maybe
95112
ctx.append("boolean notFirst = false;");
96113
}
97114
String t = CodegenImplNative.getTypeName(binding.valueType);
98115
ctx.append(String.format("if (!(((%s)%s) == 0)) {", t, valueAccessor));
99-
appendComma(ctx, notFirst);
100-
ctx.append(CodegenResult.bufferToWriteOp("\"" + toName + "\":"));
116+
notFirst = appendComma(ctx, notFirst);
117+
if (supportBuffer) {
118+
ctx.append(CodegenResult.bufferToWriteOp("\"" + toName + "\":"));
119+
} else {
120+
ctx.append(String.format("stream.writeObjectField(\"%s\");", toName));
121+
}
101122
} else {
102123
notFirst = appendComma(ctx, notFirst);
103-
ctx.buffer('"');
104-
ctx.buffer(toName);
105-
ctx.buffer('"');
106-
ctx.buffer(':');
124+
if (supportBuffer) {
125+
ctx.buffer('"');
126+
ctx.buffer(toName);
127+
ctx.buffer('"');
128+
ctx.buffer(':');
129+
} else {
130+
ctx.append(String.format("stream.writeObjectField(\"%s\");", toName));
131+
}
107132
}
108133
}
109134
if (encoder == null) {
@@ -119,12 +144,24 @@ private static int genField(CodegenResult ctx, Binding binding, String toName, i
119144
}
120145

121146
private static int appendComma(CodegenResult ctx, int notFirst) {
147+
boolean supportBuffer = JsoniterSpi.getCurrentConfig().indentionStep() == 0;
122148
if (notFirst == 1) { // definitely not first
123-
ctx.buffer(',');
149+
if (supportBuffer) {
150+
ctx.buffer(',');
151+
} else {
152+
ctx.append("stream.writeMore();");
153+
}
124154
} else if (notFirst == 2) { // maybe not first, previous field is omitNull
125-
ctx.append("if (notFirst) { stream.write(','); } else { notFirst = true; }");
155+
if (supportBuffer) {
156+
ctx.append("if (notFirst) { stream.write(','); } else { notFirst = true; }");
157+
} else {
158+
ctx.append("if (notFirst) { stream.writeMore(); } else { stream.writeIndention(); notFirst = true; }");
159+
}
126160
} else { // this is the first, do not write comma
127161
notFirst = 1;
162+
if (!supportBuffer) {
163+
ctx.append("stream.writeIndention();");
164+
}
128165
}
129166
return notFirst;
130167
}

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

Lines changed: 55 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,18 @@
11
package com.jsoniter.output;
22

3+
import com.jsoniter.spi.JsonException;
4+
import com.jsoniter.spi.JsoniterSpi;
5+
36
class CodegenResult {
47

8+
private final boolean supportBuffer;
59
String prelude = null; // first
610
String epilogue = null; // last
711
private StringBuilder lines = new StringBuilder();
812
private StringBuilder buffered = new StringBuilder();
913

10-
public static String bufferToWriteOp(String buffered) {
11-
if (buffered == null) {
12-
return "";
13-
}
14-
if (buffered.length() == 1) {
15-
return String.format("stream.write((byte)'%s');", escape(buffered.charAt(0)));
16-
} else if (buffered.length() == 2) {
17-
return String.format("stream.write((byte)'%s', (byte)'%s');",
18-
escape(buffered.charAt(0)), escape(buffered.charAt(1)));
19-
} else if (buffered.length() == 3) {
20-
return String.format("stream.write((byte)'%s', (byte)'%s', (byte)'%s');",
21-
escape(buffered.charAt(0)), escape(buffered.charAt(1)), escape(buffered.charAt(2)));
22-
} else if (buffered.length() == 4) {
23-
return String.format("stream.write((byte)'%s', (byte)'%s', (byte)'%s', (byte)'%s');",
24-
escape(buffered.charAt(0)), escape(buffered.charAt(1)), escape(buffered.charAt(2)), escape(buffered.charAt(3)));
25-
} else {
26-
StringBuilder escaped = new StringBuilder();
27-
for (int i = 0; i < buffered.length(); i++) {
28-
char c = buffered.charAt(i);
29-
if (c == '"') {
30-
escaped.append('\\');
31-
}
32-
escaped.append(c);
33-
}
34-
return String.format("stream.writeRaw(\"%s\", %s);", escaped.toString(), buffered.length());
35-
}
36-
}
37-
38-
private static String escape(char c) {
39-
if (c == '"') {
40-
return "\\\"";
41-
}
42-
if (c == '\\') {
43-
return "\\\\";
44-
}
45-
return String.valueOf(c);
14+
public CodegenResult() {
15+
supportBuffer = JsoniterSpi.getCurrentConfig().indentionStep() == 0;
4616
}
4717

4818
public void append(String str) {
@@ -56,14 +26,23 @@ public void append(String str) {
5626
}
5727

5828
public void buffer(char c) {
59-
buffered.append(c);
29+
if (supportBuffer) {
30+
buffered.append(c);
31+
} else {
32+
throw new UnsupportedOperationException("internal error: should not call buffer when indention step > 0");
33+
}
6034
}
6135

6236
public void buffer(String s) {
6337
if (s == null) {
6438
return;
6539
}
66-
buffered.append(s);
40+
if (supportBuffer) {
41+
buffered.append(s);
42+
} else {
43+
throw new UnsupportedOperationException("internal error: should not call buffer when indention step > 0");
44+
45+
}
6746
}
6847

6948
public void flushBuffer() {
@@ -111,4 +90,42 @@ private static void append(StringBuilder lines, String line) {
11190
lines.append(line);
11291
lines.append('\n');
11392
}
93+
94+
public static String bufferToWriteOp(String buffered) {
95+
if (buffered == null) {
96+
return "";
97+
}
98+
if (buffered.length() == 1) {
99+
return String.format("stream.write((byte)'%s');", escape(buffered.charAt(0)));
100+
} else if (buffered.length() == 2) {
101+
return String.format("stream.write((byte)'%s', (byte)'%s');",
102+
escape(buffered.charAt(0)), escape(buffered.charAt(1)));
103+
} else if (buffered.length() == 3) {
104+
return String.format("stream.write((byte)'%s', (byte)'%s', (byte)'%s');",
105+
escape(buffered.charAt(0)), escape(buffered.charAt(1)), escape(buffered.charAt(2)));
106+
} else if (buffered.length() == 4) {
107+
return String.format("stream.write((byte)'%s', (byte)'%s', (byte)'%s', (byte)'%s');",
108+
escape(buffered.charAt(0)), escape(buffered.charAt(1)), escape(buffered.charAt(2)), escape(buffered.charAt(3)));
109+
} else {
110+
StringBuilder escaped = new StringBuilder();
111+
for (int i = 0; i < buffered.length(); i++) {
112+
char c = buffered.charAt(i);
113+
if (c == '"') {
114+
escaped.append('\\');
115+
}
116+
escaped.append(c);
117+
}
118+
return String.format("stream.writeRaw(\"%s\", %s);", escaped.toString(), buffered.length());
119+
}
120+
}
121+
122+
private static String escape(char c) {
123+
if (c == '"') {
124+
return "\\\"";
125+
}
126+
if (c == '\\') {
127+
return "\\\\";
128+
}
129+
return String.valueOf(c);
130+
}
114131
}

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

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
public class JsonStream extends OutputStream {
1111

1212
public Config configCache;
13-
private int indention = 0;
13+
int indention = 0;
1414
private OutputStream out;
1515
byte buf[];
1616
int count;
@@ -294,7 +294,7 @@ public final void writeMore() throws IOException {
294294
writeIndention();
295295
}
296296

297-
private void writeIndention() throws IOException {
297+
public void writeIndention() throws IOException {
298298
writeIndention(0);
299299
}
300300

@@ -321,7 +321,6 @@ public final void writeObjectStart() throws IOException {
321321
int indentionStep = currentConfig().indentionStep();
322322
indention += indentionStep;
323323
write('{');
324-
writeIndention();
325324
}
326325

327326
public final void writeObjectField(String field) throws IOException {

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ public static JsonStream borrowJsonStream() {
2727

2828
public static void returnJsonStream(JsonStream jsonStream) {
2929
jsonStream.configCache = null;
30+
jsonStream.indention = 0;
3031
if (slot1.get() == null) {
3132
slot1.set(jsonStream);
3233
return;

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ public void encode(Object obj, JsonStream stream) throws IOException {
4040
if (notFirst) {
4141
stream.writeMore();
4242
} else {
43+
stream.writeIndention();
4344
notFirst = true;
4445
}
4546
if (mapKeyEncoder == null) {

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

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,11 @@ private void enocde_(Object obj, JsonStream stream) throws Exception {
9595
unwrapper.method.invoke(obj, stream);
9696
}
9797
}
98-
stream.writeObjectEnd();
98+
if (notFirst) {
99+
stream.writeObjectEnd();
100+
} else {
101+
stream.write('}');
102+
}
99103
}
100104

101105
private boolean writeEncodeTo(JsonStream stream, boolean notFirst, EncodeTo encodeTo, Object val) throws IOException {
@@ -106,6 +110,7 @@ private boolean writeEncodeTo(JsonStream stream, boolean notFirst, EncodeTo enco
106110
if (notFirst) {
107111
stream.writeMore();
108112
} else {
113+
stream.writeIndention();
109114
notFirst = true;
110115
}
111116
stream.writeObjectField(encodeTo.toName);

0 commit comments

Comments
 (0)