25
25
import java .util .AbstractMap ;
26
26
import java .util .Map ;
27
27
import java .util .NoSuchElementException ;
28
+ import java .util .Objects ;
28
29
import java .util .Spliterator ;
29
30
import java .util .Spliterators ;
30
31
import java .util .function .Consumer ;
@@ -190,25 +191,26 @@ public Stream<JsonValue> getArrayStream() {
190
191
}
191
192
Spliterator <JsonValue > spliterator =
192
193
new Spliterators .AbstractSpliterator <JsonValue >(Long .MAX_VALUE , Spliterator .ORDERED ) {
193
- @ Override
194
- public Spliterator <JsonValue > trySplit () {
195
- return null ;
196
- }
197
- @ Override
198
- public boolean tryAdvance (Consumer <? super JsonValue > action ) {
199
- if (action == null ) {
200
- throw new NullPointerException ();
201
- }
202
- if (! hasNext ()) {
203
- return false ;
204
- }
205
- if (next () == JsonParser .Event .END_ARRAY ) {
206
- return false ;
207
- }
208
- action .accept (getValue ());
209
- return true ;
210
- }
211
- };
194
+ @ Override
195
+ public Spliterator <JsonValue > trySplit () {
196
+ return null ;
197
+ }
198
+
199
+ @ Override
200
+ public boolean tryAdvance (Consumer <? super JsonValue > action ) {
201
+ if (action == null ) {
202
+ throw new NullPointerException ();
203
+ }
204
+ if (!hasNext ()) {
205
+ return false ;
206
+ }
207
+ if (next () == JsonParser .Event .END_ARRAY ) {
208
+ return false ;
209
+ }
210
+ action .accept (getValue ());
211
+ return true ;
212
+ }
213
+ };
212
214
return StreamSupport .stream (spliterator , false );
213
215
}
214
216
@@ -220,35 +222,36 @@ public Stream<Map.Entry<String, JsonValue>> getObjectStream() {
220
222
}
221
223
Spliterator <Map .Entry <String , JsonValue >> spliterator =
222
224
new Spliterators .AbstractSpliterator <Map .Entry <String , JsonValue >>(Long .MAX_VALUE , Spliterator .ORDERED ) {
223
- @ Override
224
- public Spliterator <Map .Entry <String ,JsonValue >> trySplit () {
225
- return null ;
226
- }
227
- @ Override
228
- public boolean tryAdvance (Consumer <? super Map .Entry <String , JsonValue >> action ) {
229
- if (action == null ) {
230
- throw new NullPointerException ();
231
- }
232
- if (! hasNext ()) {
233
- return false ;
234
- }
235
- JsonParser .Event e = next ();
236
- if (e == JsonParser .Event .END_OBJECT ) {
237
- return false ;
238
- }
239
- if (e != JsonParser .Event .KEY_NAME ) {
240
- throw new JsonException (JsonMessages .INTERNAL_ERROR ());
241
- }
242
- String key = getString ();
243
- if (! hasNext ()) {
244
- throw new JsonException (JsonMessages .INTERNAL_ERROR ());
245
- }
246
- next ();
247
- JsonValue value = getValue ();
248
- action .accept (new AbstractMap .SimpleImmutableEntry <>(key , value ));
249
- return true ;
250
- }
251
- };
225
+ @ Override
226
+ public Spliterator <Map .Entry <String , JsonValue >> trySplit () {
227
+ return null ;
228
+ }
229
+
230
+ @ Override
231
+ public boolean tryAdvance (Consumer <? super Map .Entry <String , JsonValue >> action ) {
232
+ if (action == null ) {
233
+ throw new NullPointerException ();
234
+ }
235
+ if (!hasNext ()) {
236
+ return false ;
237
+ }
238
+ JsonParser .Event e = next ();
239
+ if (e == JsonParser .Event .END_OBJECT ) {
240
+ return false ;
241
+ }
242
+ if (e != JsonParser .Event .KEY_NAME ) {
243
+ throw new JsonException (JsonMessages .INTERNAL_ERROR ());
244
+ }
245
+ String key = getString ();
246
+ if (!hasNext ()) {
247
+ throw new JsonException (JsonMessages .INTERNAL_ERROR ());
248
+ }
249
+ next ();
250
+ JsonValue value = getValue ();
251
+ action .accept (new AbstractMap .SimpleImmutableEntry <>(key , value ));
252
+ return true ;
253
+ }
254
+ };
252
255
return StreamSupport .stream (spliterator , false );
253
256
}
254
257
@@ -260,29 +263,30 @@ public Stream<JsonValue> getValueStream() {
260
263
}
261
264
Spliterator <JsonValue > spliterator =
262
265
new Spliterators .AbstractSpliterator <JsonValue >(Long .MAX_VALUE , Spliterator .ORDERED ) {
263
- @ Override
264
- public Spliterator <JsonValue > trySplit () {
265
- return null ;
266
- }
267
- @ Override
268
- public boolean tryAdvance (Consumer <? super JsonValue > action ) {
269
- if (action == null ) {
270
- throw new NullPointerException ();
271
- }
272
- if (! hasNext ()) {
273
- return false ;
274
- }
275
- next ();
276
- action .accept (getValue ());
277
- return true ;
278
- }
279
- };
266
+ @ Override
267
+ public Spliterator <JsonValue > trySplit () {
268
+ return null ;
269
+ }
270
+
271
+ @ Override
272
+ public boolean tryAdvance (Consumer <? super JsonValue > action ) {
273
+ if (action == null ) {
274
+ throw new NullPointerException ();
275
+ }
276
+ if (!hasNext ()) {
277
+ return false ;
278
+ }
279
+ next ();
280
+ action .accept (getValue ());
281
+ return true ;
282
+ }
283
+ };
280
284
return StreamSupport .stream (spliterator , false );
281
285
}
282
286
283
287
@ Override
284
288
public void skipArray () {
285
- if (currentEvent == Event . START_ARRAY ) {
289
+ if (currentContext instanceof ArrayContext ) {
286
290
currentContext .skip ();
287
291
currentContext = stack .pop ();
288
292
currentEvent = Event .END_ARRAY ;
@@ -291,7 +295,7 @@ public void skipArray() {
291
295
292
296
@ Override
293
297
public void skipObject () {
294
- if (currentEvent == Event . START_OBJECT ) {
298
+ if (currentContext instanceof ObjectContext ) {
295
299
currentContext .skip ();
296
300
currentContext = stack .pop ();
297
301
currentEvent = Event .END_OBJECT ;
@@ -418,27 +422,35 @@ private boolean isEmpty() {
418
422
}
419
423
}
420
424
421
- private abstract static class Context {
425
+ private abstract class Context {
422
426
Context next ;
423
427
abstract Event getNextEvent ();
424
428
abstract void skip ();
425
- }
426
429
427
- private final class NoneContext extends Context {
428
- @ Override
429
- public Event getNextEvent () {
430
- // Handle 1. { 2. [ 3. value
431
- JsonToken token = tokenizer .nextToken ();
432
- if (token == JsonToken .CURLYOPEN ) {
430
+ protected Event nextEventIfValueOrObjectOrArrayStart (JsonToken token ) {
431
+ if (token .isValue ()) {
432
+ return token .getEvent ();
433
+ } else if (token == JsonToken .CURLYOPEN ) {
433
434
stack .push (currentContext );
434
435
currentContext = new ObjectContext ();
435
436
return Event .START_OBJECT ;
436
437
} else if (token == JsonToken .SQUAREOPEN ) {
437
438
stack .push (currentContext );
438
439
currentContext = new ArrayContext ();
439
440
return Event .START_ARRAY ;
440
- } else if (token .isValue ()) {
441
- return token .getEvent ();
441
+ }
442
+ return null ;
443
+ }
444
+ }
445
+
446
+ private final class NoneContext extends Context {
447
+ @ Override
448
+ public Event getNextEvent () {
449
+ // Handle 1. { 2. [ 3. value
450
+ JsonToken token = tokenizer .nextToken ();
451
+ Event event = nextEventIfValueOrObjectOrArrayStart (token );
452
+ if (event != null ) {
453
+ return event ;
442
454
}
443
455
throw parsingException (token , "[CURLYOPEN, SQUAREOPEN, STRING, NUMBER, TRUE, FALSE, NULL]" );
444
456
}
@@ -455,9 +467,38 @@ private JsonParsingException parsingException(JsonToken token, String expectedTo
455
467
JsonMessages .PARSER_INVALID_TOKEN (token , location , expectedTokens ), location );
456
468
}
457
469
458
- private final class ObjectContext extends Context {
470
+ private abstract class SkippingContext extends Context {
471
+ private final JsonToken openToken ;
472
+ private final JsonToken closeToken ;
473
+
474
+ private SkippingContext (JsonToken openToken , JsonToken closeToken ) {
475
+ this .openToken = Objects .requireNonNull (openToken );
476
+ this .closeToken = Objects .requireNonNull (closeToken );
477
+ }
478
+
479
+ @ Override
480
+ void skip () {
481
+ JsonToken token ;
482
+ int depth = 1 ;
483
+ do {
484
+ token = tokenizer .nextToken ();
485
+ if (token == closeToken ) {
486
+ depth --;
487
+ }
488
+ if (token == openToken ) {
489
+ depth ++;
490
+ }
491
+ } while (!(token == closeToken && depth == 0 ));
492
+ }
493
+ }
494
+
495
+ private final class ObjectContext extends SkippingContext {
459
496
private boolean firstValue = true ;
460
497
498
+ private ObjectContext () {
499
+ super (JsonToken .CURLYOPEN , JsonToken .CURLYCLOSE );
500
+ }
501
+
461
502
/*
462
503
* Some more things could be optimized. For example, instead
463
504
* tokenizer.nextToken(), one could use tokenizer.matchColonToken() to
@@ -484,16 +525,9 @@ public Event getNextEvent() {
484
525
throw parsingException (token , "[COLON]" );
485
526
}
486
527
token = tokenizer .nextToken ();
487
- if (token .isValue ()) {
488
- return token .getEvent ();
489
- } else if (token == JsonToken .CURLYOPEN ) {
490
- stack .push (currentContext );
491
- currentContext = new ObjectContext ();
492
- return Event .START_OBJECT ;
493
- } else if (token == JsonToken .SQUAREOPEN ) {
494
- stack .push (currentContext );
495
- currentContext = new ArrayContext ();
496
- return Event .START_ARRAY ;
528
+ Event event = nextEventIfValueOrObjectOrArrayStart (token );
529
+ if (event != null ) {
530
+ return event ;
497
531
}
498
532
throw parsingException (token , "[CURLYOPEN, SQUAREOPEN, STRING, NUMBER, TRUE, FALSE, NULL]" );
499
533
} else {
@@ -516,29 +550,15 @@ public Event getNextEvent() {
516
550
throw parsingException (token , "[STRING]" );
517
551
}
518
552
}
519
-
520
- @ Override
521
- void skip () {
522
- JsonToken token ;
523
- int depth = 1 ;
524
- do {
525
- token = tokenizer .nextToken ();
526
- switch (token ) {
527
- case CURLYCLOSE :
528
- depth --;
529
- break ;
530
- case CURLYOPEN :
531
- depth ++;
532
- break ;
533
- }
534
- } while (!(token == JsonToken .CURLYCLOSE && depth == 0 ));
535
- }
536
-
537
553
}
538
554
539
- private final class ArrayContext extends Context {
555
+ private final class ArrayContext extends SkippingContext {
540
556
private boolean firstValue = true ;
541
557
558
+ private ArrayContext () {
559
+ super (JsonToken .SQUAREOPEN , JsonToken .SQUARECLOSE );
560
+ }
561
+
542
562
// Handle 1. ] 2. value 3. ,value
543
563
@ Override
544
564
public Event getNextEvent () {
@@ -563,36 +583,12 @@ public Event getNextEvent() {
563
583
}
564
584
token = tokenizer .nextToken ();
565
585
}
566
- if (token .isValue ()) {
567
- return token .getEvent ();
568
- } else if (token == JsonToken .CURLYOPEN ) {
569
- stack .push (currentContext );
570
- currentContext = new ObjectContext ();
571
- return Event .START_OBJECT ;
572
- } else if (token == JsonToken .SQUAREOPEN ) {
573
- stack .push (currentContext );
574
- currentContext = new ArrayContext ();
575
- return Event .START_ARRAY ;
586
+
587
+ Event event = nextEventIfValueOrObjectOrArrayStart (token );
588
+ if (event != null ) {
589
+ return event ;
576
590
}
577
591
throw parsingException (token , "[CURLYOPEN, SQUAREOPEN, STRING, NUMBER, TRUE, FALSE, NULL]" );
578
592
}
579
-
580
- @ Override
581
- void skip () {
582
- JsonToken token ;
583
- int depth = 1 ;
584
- do {
585
- token = tokenizer .nextToken ();
586
- switch (token ) {
587
- case SQUARECLOSE :
588
- depth --;
589
- break ;
590
- case SQUAREOPEN :
591
- depth ++;
592
- break ;
593
- }
594
- } while (!(token == JsonToken .SQUARECLOSE && depth == 0 ));
595
- }
596
593
}
597
-
598
594
}
0 commit comments