@@ -562,37 +562,56 @@ private final static int _parseIndex(String str) {
562
562
}
563
563
return NumberInput .parseInt (str );
564
564
}
565
-
566
- protected static JsonPointer _parseTail (String input ) {
567
- final int end = input .length ();
565
+
566
+ protected static JsonPointer _parseTail (String fullPath )
567
+ {
568
+ PointerParent parent = null ;
568
569
569
570
// first char is the contextual slash, skip
570
- for (int i = 1 ; i < end ; ) {
571
- char c = input .charAt (i );
571
+ int i = 1 ;
572
+ int end = fullPath .length ();
573
+
574
+ while (i < end ) {
575
+ char c = fullPath .charAt (i );
572
576
if (c == '/' ) { // common case, got a segment
573
- return new JsonPointer (input , input .substring (1 , i ),
574
- _parseTail (input .substring (i )));
577
+ parent = new PointerParent (parent , fullPath , fullPath .substring (1 , i ));
578
+ fullPath = fullPath .substring (i );
579
+ i = 1 ;
580
+ end = fullPath .length ();
581
+ continue ;
575
582
}
576
583
++i ;
577
584
// quoting is different; offline this case
578
585
if (c == '~' && i < end ) { // possibly, quote
579
586
// 04-Oct-2022, tatu: Let's decode escaped segment
580
587
// instead of recursive call
581
588
StringBuilder sb = new StringBuilder (32 );
582
- i = _extractEscapedSegment (input , i , sb );
589
+ i = _extractEscapedSegment (fullPath , i , sb );
583
590
final String segment = sb .toString ();
584
591
if (i < 0 ) { // end!
585
- return new JsonPointer ( input , segment , EMPTY );
592
+ return _buildPath ( fullPath , segment , parent );
586
593
}
587
- return new JsonPointer (input , segment ,
588
- _parseTail (input .substring (i )));
594
+ parent = new PointerParent (parent , fullPath , segment );
595
+ fullPath = fullPath .substring (i );
596
+ i = 1 ;
597
+ end = fullPath .length ();
598
+ continue ;
589
599
}
590
600
// otherwise, loop on
591
601
}
592
602
// end of the road, no escapes
593
- return new JsonPointer ( input , input .substring (1 ), EMPTY );
603
+ return _buildPath ( fullPath , fullPath .substring (1 ), parent );
594
604
}
595
605
606
+ private static JsonPointer _buildPath (String fullPath , String segment ,
607
+ PointerParent parent ) {
608
+ JsonPointer curr = new JsonPointer (fullPath , segment , EMPTY );
609
+ for (; parent != null ; parent = parent .parent ) {
610
+ curr = new JsonPointer (parent .fullPath , parent .segment , curr );
611
+ }
612
+ return curr ;
613
+ }
614
+
596
615
/**
597
616
* Method called to extract the next segment of the path, in case
598
617
* where we seem to have encountered a (tilde-)escaped character
@@ -665,6 +684,28 @@ protected JsonPointer _constructHead(int suffixLength, JsonPointer last)
665
684
_matchingElementIndex , next ._constructHead (suffixLength , last ));
666
685
}
667
686
687
+ /*
688
+ /**********************************************************
689
+ /* Helper class used to replace call stack (2.14+)
690
+ /**********************************************************
691
+ */
692
+
693
+ /**
694
+ * Helper class used to replace call stack when parsing JsonPointer
695
+ * expressions.
696
+ */
697
+ private static class PointerParent {
698
+ public final PointerParent parent ;
699
+ public final String fullPath ;
700
+ public final String segment ;
701
+
702
+ PointerParent (PointerParent pp , String fp , String sgm ) {
703
+ parent = pp ;
704
+ fullPath = fp ;
705
+ segment = sgm ;
706
+ }
707
+ }
708
+
668
709
/*
669
710
/**********************************************************
670
711
/* Support for JDK serialization (2.14+)
0 commit comments