@@ -630,43 +630,33 @@ private static byte percentDecode(final byte[] bytes, final int start) {
630630 return ((byte ) ((c1 << 4 ) + c2 ));
631631 }
632632
633- public static String percentDecode (final String source ) {
633+ private static String percentDecode (final String source ) {
634634 if (source .isEmpty ()) {
635635 return source ;
636636 }
637637
638638 byte [] bytes = source .getBytes (StandardCharsets .UTF_8 );
639+ int i = indexOfPercentChar (bytes , 0 );
639640
640- int off = 0 ;
641- int idx = indexOfPercentChar (bytes , off );
642-
643- if (idx == -1 ) {
641+ if (i == -1 ) {
644642 return source ;
645643 }
646644
647645 ByteBuffer buffer = ByteBuffer .wrap (bytes );
646+ buffer .position (i );
647+ int length = buffer .capacity ();
648648
649- while (true ) {
650- int len = idx - off ;
649+ while (i < length ) {
650+ byte b = bytes [ i ] ;
651651
652- if (len > 0 ) {
653- buffer .put (bytes , off , len );
654- off += len ;
652+ if (isPercent (b )) {
653+ buffer .put (percentDecode (bytes , i ));
654+ i += 2 ;
655+ } else {
656+ buffer .put (b );
655657 }
656658
657- buffer .put (percentDecode (bytes , off ));
658- off += 3 ;
659- idx = indexOfPercentChar (bytes , off );
660-
661- if (idx == -1 ) {
662- int rem = bytes .length - off ;
663-
664- if (rem > 0 ) {
665- buffer .put (bytes , off , rem );
666- }
667-
668- break ;
669- }
659+ i ++;
670660 }
671661
672662 return new String (buffer .array (), 0 , buffer .position (), StandardCharsets .UTF_8 );
@@ -681,51 +671,30 @@ private static boolean isPercent(int c) {
681671 return (c == PERCENT_CHAR );
682672 }
683673
684- private static byte [] percentEncode (byte b ) {
685- byte b1 = (byte ) Character .toUpperCase (Character .forDigit ((b >> 4 ) & 0xF , 16 ));
686- byte b2 = (byte ) Character .toUpperCase (Character .forDigit (b & 0xF , 16 ));
687- return new byte [] {(byte ) PERCENT_CHAR , b1 , b2 };
688- }
689-
690- public static String percentEncode (final String source ) {
674+ private static String percentEncode (final String source ) {
691675 if (source .isEmpty ()) {
692676 return source ;
693677 }
694678
695679 byte [] bytes = source .getBytes (StandardCharsets .UTF_8 );
696-
697- int off = 0 ;
698- int idx = indexOfUnsafeChar (bytes , off );
699-
700- if (idx == -1 ) {
701- return source ;
702- }
703-
704- ByteBuffer buffer = ByteBuffer .allocate (bytes .length * 3 );
705-
706- while (true ) {
707- int len = idx - off ;
708-
709- if (len > 0 ) {
710- buffer .put (bytes , off , len );
711- off += len ;
712- }
713-
714- buffer .put (percentEncode (bytes [off ++]));
715- idx = indexOfUnsafeChar (bytes , off );
716-
717- if (idx == -1 ) {
718- int rem = bytes .length - off ;
719-
720- if (rem > 0 ) {
721- buffer .put (bytes , off , rem );
722- }
723-
724- break ;
680+ int length = bytes .length ;
681+ ByteBuffer buffer = ByteBuffer .allocate (length * 3 );
682+ boolean changed = false ;
683+
684+ for (byte b : bytes ) {
685+ if (shouldEncode (b )) {
686+ changed = true ;
687+ byte b1 = (byte ) Character .toUpperCase (Character .forDigit ((b >> 4 ) & 0xF , 16 ));
688+ byte b2 = (byte ) Character .toUpperCase (Character .forDigit (b & 0xF , 16 ));
689+ buffer .put ((byte ) PERCENT_CHAR );
690+ buffer .put (b1 );
691+ buffer .put (b2 );
692+ } else {
693+ buffer .put (b );
725694 }
726695 }
727696
728- return new String (buffer .array (), 0 , buffer .position (), StandardCharsets .UTF_8 );
697+ return changed ? new String (buffer .array (), 0 , buffer .position (), StandardCharsets .UTF_8 ) : source ;
729698 }
730699
731700 /**
0 commit comments