@@ -182,6 +182,7 @@ private static String genObjectUsingHash(Class clazz, String cacheKey) {
182
182
if (clazz .getFields ().length == 0 ) {
183
183
StringBuilder lines = new StringBuilder ();
184
184
append (lines , "public static Object decode_(com.jsoniter.Jsoniter iter) {" );
185
+ append (lines , "if (iter.readNull()) { return null; }" );
185
186
append (lines , "{{clazz}} obj = {{newInst}};" );
186
187
append (lines , "iter.skip();" );
187
188
append (lines , "return obj;" );
@@ -190,10 +191,11 @@ private static String genObjectUsingHash(Class clazz, String cacheKey) {
190
191
}
191
192
StringBuilder lines = new StringBuilder ();
192
193
append (lines , "public static Object decode_(com.jsoniter.Jsoniter iter) {" );
194
+ append (lines , "if (iter.readNull()) { return null; }" );
193
195
append (lines , "{{clazz}} obj = {{newInst}};" );
194
- append (lines , "if (iter.readByte() != '{') { throw new RuntimeException();}" );
195
- append (lines , "if (iter.nextToken() != '\" ') { throw new RuntimeException();}" );
196
+ append (lines , "if (!com.jsoniter.CodegenAccess.readObjectStart(iter)) { return obj; }" );
196
197
append (lines , "switch (iter.readObjectFieldAsHash()) {" );
198
+ HashSet <Integer > knownHashes = new HashSet <Integer >();
197
199
for (Field field : clazz .getFields ()) {
198
200
long hash = 0x811c9dc5 ;
199
201
for (byte b : field .getName ().getBytes ()) {
@@ -205,15 +207,20 @@ private static String genObjectUsingHash(Class clazz, String cacheKey) {
205
207
// hash collision, 0 can not be used as sentinel
206
208
return genObject (clazz , cacheKey );
207
209
}
210
+ if (knownHashes .contains (intHash )) {
211
+ // hash collision with other field can not be used as sentinel
212
+ return genObject (clazz , cacheKey );
213
+ }
214
+ knownHashes .add (intHash );
208
215
append (lines , "case " + intHash + ": " );
209
216
genField (lines , field , cacheKey );
210
217
append (lines , "break;" );
211
218
}
212
219
append (lines , "default:" );
213
220
append (lines , "iter.skip();" );
214
221
append (lines , "}" );
215
- append (lines , "while (iter.nextToken() == ',') { " );
216
- append (lines , "iter. nextToken(); " );
222
+ append (lines , "byte c = 0; " );
223
+ append (lines , "while ((c = com.jsoniter.CodegenAccess. nextToken(iter)) == ',') { " );
217
224
append (lines , "switch (iter.readObjectFieldAsHash()) {" );
218
225
for (Field field : clazz .getFields ()) {
219
226
long hash = 0x811c9dc5 ;
@@ -222,17 +229,14 @@ private static String genObjectUsingHash(Class clazz, String cacheKey) {
222
229
hash *= 0x1000193 ;
223
230
}
224
231
int intHash = (int ) hash ;
225
- if (intHash == 0 ) {
226
- // hash collision, 0 can not be used as sentinel
227
- return genObject (clazz , cacheKey );
228
- }
229
232
append (lines , "case " + intHash + ": " );
230
233
genField (lines , field , cacheKey );
231
234
append (lines , "continue;" );
232
235
}
233
236
append (lines , "}" );
234
237
append (lines , "iter.skip();" );
235
238
append (lines , "}" );
239
+ append (lines , "if (c != '}') { com.jsoniter.CodegenAccess.reportIncompleteObject(iter); }" );
236
240
append (lines , "return obj;" );
237
241
append (lines , "}" );
238
242
return lines .toString ().replace ("{{clazz}}" , clazz .getCanonicalName ()).replace ("{{newInst}}" , newInstanceCode );
@@ -250,17 +254,9 @@ private static String genObject(Class clazz, String cacheKey) {
250
254
if (newInstanceCode == null ) {
251
255
newInstanceCode = "new " + clazz .getCanonicalName () + "()" ;
252
256
}
253
- if (trieTree .isEmpty ()) {
254
- StringBuilder lines = new StringBuilder ();
255
- append (lines , "public static Object decode_(com.jsoniter.Jsoniter iter) {" );
256
- append (lines , "{{clazz}} obj = {{newInst}};" );
257
- append (lines , "iter.skip();" );
258
- append (lines , "return obj;" );
259
- append (lines , "}" );
260
- return lines .toString ().replace ("{{clazz}}" , clazz .getCanonicalName ()).replace ("{{newInst}}" , newInstanceCode );
261
- }
262
257
StringBuilder lines = new StringBuilder ();
263
258
append (lines , "public static Object decode_(com.jsoniter.Jsoniter iter) {" );
259
+ append (lines , "if (iter.readNull()) { return null; }" );
264
260
append (lines , "{{clazz}} obj = {{newInst}};" );
265
261
append (lines , "for (com.jsoniter.Slice field = iter.readObjectAsSlice(); field != null; field = iter.readObjectAsSlice()) {" );
266
262
append (lines , "switch (field.len) {" );
@@ -458,15 +454,15 @@ private static String genArray(Class clazz) {
458
454
append (lines , "return new {{comp}}[0];" );
459
455
append (lines , "}" );
460
456
append (lines , "{{comp}} a1 = {{op}};" );
461
- append (lines , "if (! com.jsoniter.CodegenAccess.readArrayMiddle (iter)) {" );
457
+ append (lines , "if (com.jsoniter.CodegenAccess.nextToken (iter) != ',' ) {" );
462
458
append (lines , "return new {{comp}}[]{ a1 };" );
463
459
append (lines , "}" );
464
460
append (lines , "{{comp}} a2 = {{op}};" );
465
- append (lines , "if (! com.jsoniter.CodegenAccess.readArrayMiddle (iter)) {" );
461
+ append (lines , "if (com.jsoniter.CodegenAccess.nextToken (iter) != ',' ) {" );
466
462
append (lines , "return new {{comp}}[]{ a1, a2 };" );
467
463
append (lines , "}" );
468
464
append (lines , "{{comp}} a3 = {{op}};" );
469
- append (lines , "if (! com.jsoniter.CodegenAccess.readArrayMiddle (iter)) {" );
465
+ append (lines , "if (com.jsoniter.CodegenAccess.nextToken (iter) != ',' ) {" );
470
466
append (lines , "return new {{comp}}[]{ a1, a2, a3 };" );
471
467
append (lines , "}" );
472
468
append (lines , "{{comp}} a4 = ({{comp}}) {{op}};" );
@@ -476,7 +472,7 @@ private static String genArray(Class clazz) {
476
472
append (lines , "arr[2] = a3;" );
477
473
append (lines , "arr[3] = a4;" );
478
474
append (lines , "int i = 4;" );
479
- append (lines , "while (com.jsoniter.CodegenAccess.readArrayMiddle (iter)) {" );
475
+ append (lines , "while (com.jsoniter.CodegenAccess.nextToken (iter) == ',' ) {" );
480
476
append (lines , "if (i == arr.length) {" );
481
477
append (lines , "{{comp}}[] newArr = new {{comp}}[arr.length * 2];" );
482
478
append (lines , "System.arraycopy(arr, 0, newArr, 0, arr.length);" );
@@ -500,20 +496,20 @@ private static String genCollectionWithCapacity(Class clazz, Type compType) {
500
496
append (lines , "return new {{clazz}}(0);" );
501
497
append (lines , "}" );
502
498
append (lines , "Object a1 = {{op}};" );
503
- append (lines , "if (! com.jsoniter.CodegenAccess.readArrayMiddle (iter)) {" );
499
+ append (lines , "if (com.jsoniter.CodegenAccess.nextToken (iter) != ',' ) {" );
504
500
append (lines , "{{clazz}} obj = new {{clazz}}(1);" );
505
501
append (lines , "obj.add(a1);" );
506
502
append (lines , "return obj;" );
507
503
append (lines , "}" );
508
504
append (lines , "Object a2 = {{op}};" );
509
- append (lines , "if (! com.jsoniter.CodegenAccess.readArrayMiddle (iter)) {" );
505
+ append (lines , "if (com.jsoniter.CodegenAccess.nextToken (iter) != ',' ) {" );
510
506
append (lines , "{{clazz}} obj = new {{clazz}}(2);" );
511
507
append (lines , "obj.add(a1);" );
512
508
append (lines , "obj.add(a2);" );
513
509
append (lines , "return obj;" );
514
510
append (lines , "}" );
515
511
append (lines , "Object a3 = {{op}};" );
516
- append (lines , "if (! com.jsoniter.CodegenAccess.readArrayMiddle (iter)) {" );
512
+ append (lines , "if (com.jsoniter.CodegenAccess.nextToken (iter) != ',' ) {" );
517
513
append (lines , "{{clazz}} obj = new {{clazz}}(3);" );
518
514
append (lines , "obj.add(a1);" );
519
515
append (lines , "obj.add(a2);" );
@@ -527,7 +523,7 @@ private static String genCollectionWithCapacity(Class clazz, Type compType) {
527
523
append (lines , "obj.add(a3);" );
528
524
append (lines , "obj.add(a4);" );
529
525
append (lines , "int i = 4;" );
530
- append (lines , "while (com.jsoniter.CodegenAccess.readArrayMiddle (iter)) {" );
526
+ append (lines , "while (com.jsoniter.CodegenAccess.nextToken (iter) == ',' ) {" );
531
527
append (lines , "obj.add({{op}});" );
532
528
append (lines , "}" );
533
529
append (lines , "return obj;" );
@@ -544,20 +540,20 @@ private static String genCollection(Class clazz, Type compType) {
544
540
append (lines , "return new {{clazz}}();" );
545
541
append (lines , "}" );
546
542
append (lines , "Object a1 = {{op}};" );
547
- append (lines , "if (! com.jsoniter.CodegenAccess.readArrayMiddle (iter)) {" );
543
+ append (lines , "if (com.jsoniter.CodegenAccess.nextToken (iter) != ',' ) {" );
548
544
append (lines , "{{clazz}} obj = new {{clazz}}();" );
549
545
append (lines , "obj.add(a1);" );
550
546
append (lines , "return obj;" );
551
547
append (lines , "}" );
552
548
append (lines , "Object a2 = {{op}};" );
553
- append (lines , "if (! com.jsoniter.CodegenAccess.readArrayMiddle (iter)) {" );
549
+ append (lines , "if (com.jsoniter.CodegenAccess.nextToken (iter) != ',' ) {" );
554
550
append (lines , "{{clazz}} obj = new {{clazz}}();" );
555
551
append (lines , "obj.add(a1);" );
556
552
append (lines , "obj.add(a2);" );
557
553
append (lines , "return obj;" );
558
554
append (lines , "}" );
559
555
append (lines , "Object a3 = {{op}};" );
560
- append (lines , "if (! com.jsoniter.CodegenAccess.readArrayMiddle (iter)) {" );
556
+ append (lines , "if (com.jsoniter.CodegenAccess.nextToken (iter) != ',' ) {" );
561
557
append (lines , "{{clazz}} obj = new {{clazz}}();" );
562
558
append (lines , "obj.add(a1);" );
563
559
append (lines , "obj.add(a2);" );
@@ -571,7 +567,7 @@ private static String genCollection(Class clazz, Type compType) {
571
567
append (lines , "obj.add(a3);" );
572
568
append (lines , "obj.add(a4);" );
573
569
append (lines , "int i = 4;" );
574
- append (lines , "while (com.jsoniter.CodegenAccess.readArrayMiddle (iter)) {" );
570
+ append (lines , "while (com.jsoniter.CodegenAccess.nextToken (iter) == ',' ) {" );
575
571
append (lines , "obj.add({{op}});" );
576
572
append (lines , "}" );
577
573
append (lines , "return obj;" );
0 commit comments