Skip to content

Commit c5a5a6e

Browse files
committed
Stream - refactor move name stack into underlying parser and generator
1 parent 6c8dc80 commit c5a5a6e

File tree

9 files changed

+102
-54
lines changed

9 files changed

+102
-54
lines changed

blackbox-test/pom.xml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<parent>
55
<groupId>io.avaje</groupId>
66
<artifactId>avaje-jsonb-parent</artifactId>
7-
<version>0.10-SNAPSHOT</version>
7+
<version>0.11-SNAPSHOT</version>
88
</parent>
99

1010
<artifactId>blackbox-test</artifactId>
@@ -22,14 +22,14 @@
2222

2323
<dependency>
2424
<groupId>io.avaje</groupId>
25-
<artifactId>avaje-jsonb-jackson</artifactId>
26-
<version>0.10-SNAPSHOT</version>
25+
<artifactId>avaje-jsonb</artifactId>
26+
<version>0.11-SNAPSHOT</version>
2727
</dependency>
2828

2929
<dependency>
3030
<groupId>io.avaje</groupId>
3131
<artifactId>avaje-jsonb-generator</artifactId>
32-
<version>0.10-SNAPSHOT</version>
32+
<version>0.11-SNAPSHOT</version>
3333
<scope>provided</scope>
3434
</dependency>
3535

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package org.example.customer.nesting;
2+
3+
import io.avaje.jsonb.Json;
4+
5+
import java.util.List;
6+
7+
public class Nesting {
8+
9+
@Json
10+
public record One(String a, List<Two> twos, int b, Three three, long c) {
11+
}
12+
13+
@Json
14+
public record Two(long f, Four four, String g) {
15+
16+
}
17+
18+
@Json
19+
public record Three(String other) {
20+
}
21+
22+
@Json
23+
public record Four(String four) {
24+
}
25+
26+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package org.example.customer.nesting;
2+
3+
import io.avaje.jsonb.Jsonb;
4+
import org.example.customer.nesting.Nesting.*;
5+
import org.junit.jupiter.api.Test;
6+
7+
import java.util.List;
8+
9+
import static org.assertj.core.api.Assertions.assertThat;
10+
11+
class NestingTest {
12+
13+
Jsonb jsonb = Jsonb.newBuilder().build();
14+
15+
@Test
16+
void asd() {
17+
18+
var one = new One("hi",
19+
List.of(new Two(44, new Four("f1"), "g1"), new Two(45, new Four("f2"), "g2")),
20+
89,
21+
new Three("ot"), 909L);
22+
23+
String asJson = jsonb.toJson(one);
24+
25+
assertThat(asJson).isEqualTo("{\"a\":\"hi\",\"twos\":[{\"f\":44,\"four\":{\"four\":\"f1\"},\"g\":\"g1\"},{\"f\":45,\"four\":{\"four\":\"f2\"},\"g\":\"g2\"}],\"b\":89,\"three\":{\"other\":\"ot\"},\"c\":909}");
26+
27+
28+
One fromJson = jsonb.type(One.class).fromJson(asJson);
29+
30+
assertThat(fromJson).isEqualTo(one);
31+
}
32+
}

jsonb/src/main/java/io/avaje/jsonb/stream/ArrayStack.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,4 +37,7 @@ E pop() {
3737
return len == 0 ? null : list.remove(len - 1);
3838
}
3939

40+
void clear() {
41+
list.clear();
42+
}
4043
}

jsonb/src/main/java/io/avaje/jsonb/stream/JGenerator.java

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ final class JGenerator implements JsonGenerator {
6060
private int position;
6161
private boolean pretty;
6262
private int depth;
63+
private final ArrayStack<JsonNames> nameStack = new ArrayStack<>();
64+
private JsonNames currentNames;
6365

6466
JGenerator() {
6567
this(512);
@@ -78,6 +80,7 @@ JsonGenerator prepare(OutputStream targetStream) {
7880
lastOp = 0;
7981
position = 0;
8082
pretty = false;
83+
nameStack.clear();
8184
return this;
8285
}
8386

@@ -438,6 +441,7 @@ public void startObject() {
438441

439442
@Override
440443
public void endObject() {
444+
currentNames = nameStack.pop();
441445
if (pretty) {
442446
writeNewLine();
443447
depth--;
@@ -480,16 +484,24 @@ private void prettyIndent() {
480484
}
481485

482486
@Override
483-
public void writeName(String name) {
487+
public void names(JsonNames nextNames) {
488+
if (currentNames != null) {
489+
nameStack.push(currentNames);
490+
}
491+
currentNames = nextNames;
492+
}
493+
494+
@Override
495+
public void writeName(int namePos) {
484496
prefixName();
485-
writeString(name);
497+
writeAscii(currentNames.key(namePos));
486498
writeColon();
487499
}
488500

489501
@Override
490-
public void writeName(byte[] escapedName) {
502+
public void writeName(String name) {
491503
prefixName();
492-
writeAscii(escapedName);
504+
writeString(name);
493505
writeColon();
494506
}
495507

jsonb/src/main/java/io/avaje/jsonb/stream/JParser.java

Lines changed: 8 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -81,9 +81,8 @@ enum UnknownNumberParsing {
8181
private final byte[] originalBuffer;
8282
private final int originalBufferLenWithExtraSpace;
8383

84-
private ArrayStack<JsonNames> nameStack;
84+
private final ArrayStack<JsonNames> nameStack = new ArrayStack<>();
8585
private JsonNames currentNames;
86-
private boolean pushedNames;
8786

8887
final ErrorInfo errorInfo;
8988
final DoublePrecision doublePrecision;
@@ -128,6 +127,7 @@ public void close() {
128127
this.currentIndex = 0;
129128
this.length = 0;
130129
this.readLimit = 0;
130+
this.nameStack.clear();
131131
this.stream = null;
132132
}
133133

@@ -140,6 +140,7 @@ public void close() {
140140
* @return itself
141141
*/
142142
public JParser process(final InputStream stream) {
143+
this.nameStack.clear();
143144
this.currentPosition = 0;
144145
this.currentIndex = 0;
145146
this.stream = stream;
@@ -169,6 +170,7 @@ public JParser process(final byte[] newBuffer, final int newLength) {
169170
if (newLength > buffer.length) {
170171
throw new IllegalArgumentException("length can't be longer than buffer.length");
171172
}
173+
this.nameStack.clear();
172174
this.currentIndex = 0;
173175
this.length = newLength;
174176
this.stream = null;
@@ -178,20 +180,10 @@ public JParser process(final byte[] newBuffer, final int newLength) {
178180

179181
@Override
180182
public void names(JsonNames nextNames) {
181-
if (currentNames != nextNames) {
182-
if (currentNames != null) {
183-
pushCurrentNames();
184-
}
185-
currentNames = nextNames;
186-
}
187-
}
188-
189-
private void pushCurrentNames() {
190-
if (nameStack == null) {
191-
nameStack = new ArrayStack<>();
183+
if (currentNames != null) {
184+
nameStack.push(currentNames);
192185
}
193-
pushedNames = true;
194-
nameStack.push(currentNames);
186+
currentNames = nextNames;
195187
}
196188

197189
/**
@@ -967,10 +959,7 @@ public void startObject() {
967959
*/
968960
@Override
969961
public void endObject() {
970-
if (pushedNames) {
971-
pushedNames = false;
972-
currentNames = nameStack != null ? nameStack.pop() : null;
973-
}
962+
currentNames = nameStack.pop();
974963
if (last != '}' && nextToken() != '}') {
975964
if (currentIndex >= length) throw newParseErrorAt("Unexpected end in JSON", 0, eof);
976965
throw newParseError("Expecting '}' as object end");

jsonb/src/main/java/io/avaje/jsonb/stream/JsonGenerator.java

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,14 +36,21 @@ interface JsonGenerator extends Closeable, Flushable {
3636
void endObject();
3737

3838
/**
39-
* Write a field name.
39+
* Set the already encoded and escaped names that can be used via {@link #writeName(int)}.
4040
*/
41-
void writeName(String name);
41+
void names(JsonNames nextNames);
4242

4343
/**
4444
* Write a field name that is already encoded and escaped.
45+
* <p>
46+
* The namePos is the name position in the JsonNames that has been set.
4547
*/
46-
void writeName(byte[] escapedName);
48+
void writeName(int namePos);
49+
50+
/**
51+
* Write a field name.
52+
*/
53+
void writeName(String name);
4754

4855
/**
4956
* Write null value.

jsonb/src/main/java/io/avaje/jsonb/stream/JsonReadAdapter.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,7 @@ public boolean hasNextField() {
5858
return true;
5959
}
6060
if (nextToken == ',') {
61-
nextToken = reader.nextToken();
62-
return nextToken == '"';
61+
return reader.nextToken() == '"';
6362
} else {
6463
return false;
6564
}

jsonb/src/main/java/io/avaje/jsonb/stream/JsonWriteAdapter.java

Lines changed: 2 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,6 @@ final class JsonWriteAdapter implements JsonWriter {
1717
private boolean serializeEmpty;
1818
private boolean serializeNulls;
1919
private String deferredName;
20-
private ArrayStack<JsonNames> nameStack;
21-
private JsonNames currentNames;
22-
private boolean pushedNames;
2320
private int namePos = -1;
2421

2522
JsonWriteAdapter(JsonGenerator generator, boolean serializeNulls, boolean serializeEmpty) {
@@ -96,10 +93,6 @@ public void beginObject() {
9693
@Override
9794
public void endObject() {
9895
generator.endObject();
99-
if (pushedNames) {
100-
pushedNames = false;
101-
currentNames = nameStack != null ? nameStack.pop() : null;
102-
}
10396
}
10497

10598
@Override
@@ -109,20 +102,7 @@ public void name(String name) {
109102

110103
@Override
111104
public void names(PropertyNames nextNames) {
112-
if (currentNames != nextNames) {
113-
if (currentNames != null) {
114-
pushCurrentNames();
115-
}
116-
currentNames = (JsonNames) nextNames;
117-
}
118-
}
119-
120-
private void pushCurrentNames() {
121-
if (nameStack == null) {
122-
nameStack = new ArrayStack<>();
123-
}
124-
pushedNames = true;
125-
nameStack.push(currentNames);
105+
generator.names((JsonNames) nextNames);
126106
}
127107

128108
@Override
@@ -132,7 +112,7 @@ public void name(int position) {
132112

133113
void writeDeferredName() throws IOException {
134114
if (namePos > -1) {
135-
generator.writeName(currentNames.key(namePos));
115+
generator.writeName(namePos);
136116
namePos = -1;
137117
} else if (deferredName != null) {
138118
generator.writeName(deferredName);

0 commit comments

Comments
 (0)