Skip to content

Commit eb3d9dc

Browse files
committed
support failOnPresent
1 parent 08ed1fa commit eb3d9dc

4 files changed

Lines changed: 42 additions & 13 deletions

File tree

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,8 +86,8 @@ private static String genSource(String cacheKey, Class clazz, Type[] typeArgs) {
8686
}
8787
ClassDescriptor desc = ExtensionManager.getClassDescriptor(clazz, false);
8888
List<Binding> allBindings = desc.allDecoderBindings();
89-
for (Binding allBinding : allBindings) {
90-
if (allBinding.failOnMissing) {
89+
for (Binding binding : allBindings) {
90+
if (binding.failOnMissing || binding.failOnPresent) {
9191
// only slice support mandatory tracking
9292
return CodegenImplObject.genObjectUsingSlice(clazz, cacheKey, desc);
9393
}

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

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,9 @@ public static String genObjectUsingSlice(Class clazz, String cacheKey, ClassDesc
3838
Map<Integer, Object> trieTree = buildTriTree(allBindings);
3939
StringBuilder lines = new StringBuilder();
4040
append(lines, "public static Object decode_(com.jsoniter.JsonIterator iter) {");
41-
// if null, return null
41+
// === if null, return null
4242
append(lines, "if (iter.readNull()) { com.jsoniter.CodegenAccess.resetExistingObject(iter); return null; }");
43-
// if input is empty object, return empty object
43+
// === if input is empty object, return empty object
4444
append(lines, "long tracker = 0;");
4545
if (desc.ctor.parameters.isEmpty()) {
4646
append(lines, "{{clazz}} obj = {{newInst}};");
@@ -71,6 +71,7 @@ public static String genObjectUsingSlice(Class clazz, String cacheKey, ClassDesc
7171
appendVarDef(lines, param);
7272
}
7373
}
74+
// === bind first field
7475
append(lines, "com.jsoniter.Slice field = com.jsoniter.CodegenAccess.readObjectFieldAsSlice(iter);");
7576
append(lines, "boolean once = true;");
7677
append(lines, "while (once) {");
@@ -93,6 +94,7 @@ public static String genObjectUsingSlice(Class clazz, String cacheKey, ClassDesc
9394
}
9495
appendOnUnknownField(lines, desc);
9596
append(lines, "}"); // end of while
97+
// === bind all fields
9698
append(lines, "while (com.jsoniter.CodegenAccess.nextToken(iter) == ',') {");
9799
append(lines, "field = com.jsoniter.CodegenAccess.readObjectFieldAsSlice(iter);");
98100
if (!allBindings.isEmpty()) {
@@ -181,12 +183,18 @@ private static void addFieldDispatch(
181183
append(lines, String.format("field.at(%d)==%s", i, b));
182184
append(lines, ") {");
183185
Binding field = (Binding) entry.getValue();
184-
append(lines, String.format("_%s_ = %s;", field.name, genField(field, cacheKey)));
185-
if (field.failOnMissing) {
186-
long mask = 1L << field.idx;
187-
append(lines, "tracker = tracker | " + mask + "L;");
186+
if (field.failOnPresent) {
187+
append(lines, String.format(
188+
"throw new com.jsoniter.JsonException('found should not present field: %s');".replace('\'', '"'),
189+
field.name));
190+
} else {
191+
append(lines, String.format("_%s_ = %s;", field.name, genField(field, cacheKey)));
192+
if (field.failOnMissing) {
193+
long mask = 1L << field.idx;
194+
append(lines, "tracker = tracker | " + mask + "L;");
195+
}
196+
append(lines, "continue;");
188197
}
189-
append(lines, "continue;");
190198
append(lines, "}");
191199
continue;
192200
}

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ public class Binding {
1717
public Decoder decoder;
1818
public Encoder encoder;
1919
public boolean failOnMissing;
20+
public boolean failOnPresent;
2021
// optional
2122
public Field field;
2223
public int idx;

src/test/java/com/jsoniter/TestCustomizeField.java

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ public void updateClassDescriptor(ClassDescriptor desc) {
7171

7272
public static class TestObject5 {
7373
private int field1;
74+
7475
public TestObject5(int field1) {
7576
this.field1 = field1;
7677
}
@@ -83,7 +84,7 @@ public void updateClassDescriptor(ClassDescriptor desc) {
8384
if (desc.clazz == TestObject5.class) {
8485
desc.ctor = new ConstructorDescriptor() {{
8586
parameters = (List) Arrays.asList(new Binding() {{
86-
name="param2";
87+
name = "param2";
8788
valueType = int.class;
8889
}});
8990
}};
@@ -214,8 +215,27 @@ public void updateClassDescriptor(ClassDescriptor desc) {
214215
}
215216
}
216217

217-
public void test_java() {
218-
long i = Long.MAX_VALUE >> 60;
219-
System.out.println(i);
218+
public static class TestObject11 {
219+
public String field1;
220+
}
221+
222+
public void test_fail_on_present() throws IOException {
223+
ExtensionManager.registerExtension(new EmptyExtension() {
224+
@Override
225+
public void updateClassDescriptor(ClassDescriptor desc) {
226+
if (desc.clazz != TestObject11.class) {
227+
return;
228+
}
229+
for (Binding field : desc.allDecoderBindings()) {
230+
field.failOnPresent = true;
231+
}
232+
}
233+
});
234+
JsonIterator iter = JsonIterator.parse("{'field1': '100'}".replace('\'', '"'));
235+
try {
236+
iter.read(TestObject11.class);
237+
fail("should throw exception");
238+
} catch (Exception e) {
239+
}
220240
}
221241
}

0 commit comments

Comments
 (0)