@@ -632,43 +632,33 @@ private static byte percentDecode(final byte[] bytes, final int start) {
632632 return ((byte ) ((c1 << 4 ) + c2 ));
633633 }
634634
635- public static String percentDecode (final String source ) {
635+ private static String percentDecode (final String source ) {
636636 if (source .isEmpty ()) {
637637 return source ;
638638 }
639639
640640 byte [] bytes = source .getBytes (StandardCharsets .UTF_8 );
641+ int i = indexOfPercentChar (bytes , 0 );
641642
642- int off = 0 ;
643- int idx = indexOfPercentChar (bytes , off );
644-
645- if (idx == -1 ) {
643+ if (i == -1 ) {
646644 return source ;
647645 }
648646
649647 ByteBuffer buffer = ByteBuffer .wrap (bytes );
648+ buffer .position (i );
649+ int length = buffer .capacity ();
650650
651- while (true ) {
652- int len = idx - off ;
651+ while (i < length ) {
652+ byte b = bytes [ i ] ;
653653
654- if (len > 0 ) {
655- buffer .put (bytes , off , len );
656- off += len ;
654+ if (isPercent (b )) {
655+ buffer .put (percentDecode (bytes , i ));
656+ i += 2 ;
657+ } else {
658+ buffer .put (b );
657659 }
658660
659- buffer .put (percentDecode (bytes , off ));
660- off += 3 ;
661- idx = indexOfPercentChar (bytes , off );
662-
663- if (idx == -1 ) {
664- int rem = bytes .length - off ;
665-
666- if (rem > 0 ) {
667- buffer .put (bytes , off , rem );
668- }
669-
670- break ;
671- }
661+ i ++;
672662 }
673663
674664 return new String (buffer .array (), 0 , buffer .position (), StandardCharsets .UTF_8 );
@@ -683,51 +673,30 @@ private static boolean isPercent(int c) {
683673 return (c == PERCENT_CHAR );
684674 }
685675
686- private static byte [] percentEncode (byte b ) {
687- byte b1 = (byte ) Character .toUpperCase (Character .forDigit ((b >> 4 ) & 0xF , 16 ));
688- byte b2 = (byte ) Character .toUpperCase (Character .forDigit (b & 0xF , 16 ));
689- return new byte [] {(byte ) PERCENT_CHAR , b1 , b2 };
690- }
691-
692- public static String percentEncode (final String source ) {
676+ private static String percentEncode (final String source ) {
693677 if (source .isEmpty ()) {
694678 return source ;
695679 }
696680
697681 byte [] bytes = source .getBytes (StandardCharsets .UTF_8 );
698-
699- int off = 0 ;
700- int idx = indexOfUnsafeChar (bytes , off );
701-
702- if (idx == -1 ) {
703- return source ;
704- }
705-
706- ByteBuffer buffer = ByteBuffer .allocate (bytes .length * 3 );
707-
708- while (true ) {
709- int len = idx - off ;
710-
711- if (len > 0 ) {
712- buffer .put (bytes , off , len );
713- off += len ;
714- }
715-
716- buffer .put (percentEncode (bytes [off ++]));
717- idx = indexOfUnsafeChar (bytes , off );
718-
719- if (idx == -1 ) {
720- int rem = bytes .length - off ;
721-
722- if (rem > 0 ) {
723- buffer .put (bytes , off , rem );
724- }
725-
726- break ;
682+ int length = bytes .length ;
683+ ByteBuffer buffer = ByteBuffer .allocate (length * 3 );
684+ boolean changed = false ;
685+
686+ for (byte b : bytes ) {
687+ if (shouldEncode (b )) {
688+ changed = true ;
689+ byte b1 = (byte ) Character .toUpperCase (Character .forDigit ((b >> 4 ) & 0xF , 16 ));
690+ byte b2 = (byte ) Character .toUpperCase (Character .forDigit (b & 0xF , 16 ));
691+ buffer .put ((byte ) PERCENT_CHAR );
692+ buffer .put (b1 );
693+ buffer .put (b2 );
694+ } else {
695+ buffer .put (b );
727696 }
728697 }
729698
730- return new String (buffer .array (), 0 , buffer .position (), StandardCharsets .UTF_8 );
699+ return changed ? new String (buffer .array (), 0 , buffer .position (), StandardCharsets .UTF_8 ) : source ;
731700 }
732701
733702 /**
0 commit comments