@@ -577,7 +577,7 @@ private static boolean isLowerCase(int c) {
577577 }
578578
579579 private static int toLowerCase (int c ) {
580- return ( c ^ 0x20 );
580+ return isUpperCase ( c ) ? ( c ^ 0x20 ) : c ;
581581 }
582582
583583 private static String toLowerCase (String s ) {
@@ -591,9 +591,7 @@ private static String toLowerCase(String s) {
591591 int length = chars .length ;
592592
593593 for (int i = pos ; i < length ; i ++) {
594- if (isUpperCase (chars [i ])) {
595- chars [i ] = (char ) toLowerCase (chars [i ]);
596- }
594+ chars [i ] = (char ) toLowerCase (chars [i ]);
597595 }
598596
599597 return new String (chars );
@@ -640,43 +638,33 @@ private static byte percentDecode(final byte[] bytes, final int start) {
640638 return ((byte ) ((c1 << 4 ) + c2 ));
641639 }
642640
643- public static String percentDecode (final String source ) {
641+ private static String percentDecode (final String source ) {
644642 if (source .isEmpty ()) {
645643 return source ;
646644 }
647645
648646 byte [] bytes = source .getBytes (StandardCharsets .UTF_8 );
647+ int i = indexOfPercentChar (bytes , 0 );
649648
650- int off = 0 ;
651- int idx = indexOfPercentChar (bytes , off );
652-
653- if (idx == -1 ) {
649+ if (i == -1 ) {
654650 return source ;
655651 }
656652
657653 ByteBuffer buffer = ByteBuffer .wrap (bytes );
654+ buffer .position (i );
655+ int length = buffer .capacity ();
658656
659- while (true ) {
660- int len = idx - off ;
657+ while (i < length ) {
658+ byte b = bytes [ i ] ;
661659
662- if (len > 0 ) {
663- buffer .put (bytes , off , len );
664- off += len ;
660+ if (isPercent (b )) {
661+ buffer .put (percentDecode (bytes , i ));
662+ i += 2 ;
663+ } else {
664+ buffer .put (b );
665665 }
666666
667- buffer .put (percentDecode (bytes , off ));
668- off += 3 ;
669- idx = indexOfPercentChar (bytes , off );
670-
671- if (idx == -1 ) {
672- int rem = bytes .length - off ;
673-
674- if (rem > 0 ) {
675- buffer .put (bytes , off , rem );
676- }
677-
678- break ;
679- }
667+ i ++;
680668 }
681669
682670 return new String (buffer .array (), 0 , buffer .position (), StandardCharsets .UTF_8 );
@@ -691,51 +679,30 @@ private static boolean isPercent(int c) {
691679 return (c == PERCENT_CHAR );
692680 }
693681
694- private static byte [] percentEncode (byte b ) {
695- byte b1 = (byte ) Character .toUpperCase (Character .forDigit ((b >> 4 ) & 0xF , 16 ));
696- byte b2 = (byte ) Character .toUpperCase (Character .forDigit (b & 0xF , 16 ));
697- return new byte [] {(byte ) PERCENT_CHAR , b1 , b2 };
698- }
699-
700- public static String percentEncode (final String source ) {
682+ private static String percentEncode (final String source ) {
701683 if (source .isEmpty ()) {
702684 return source ;
703685 }
704686
705687 byte [] bytes = source .getBytes (StandardCharsets .UTF_8 );
706-
707- int off = 0 ;
708- int idx = indexOfUnsafeChar (bytes , off );
709-
710- if (idx == -1 ) {
711- return source ;
712- }
713-
714- ByteBuffer buffer = ByteBuffer .allocate (bytes .length * 3 );
715-
716- while (true ) {
717- int len = idx - off ;
718-
719- if (len > 0 ) {
720- buffer .put (bytes , off , len );
721- off += len ;
722- }
723-
724- buffer .put (percentEncode (bytes [off ++]));
725- idx = indexOfUnsafeChar (bytes , off );
726-
727- if (idx == -1 ) {
728- int rem = bytes .length - off ;
729-
730- if (rem > 0 ) {
731- buffer .put (bytes , off , rem );
732- }
733-
734- break ;
688+ int length = bytes .length ;
689+ ByteBuffer buffer = ByteBuffer .allocate (length * 3 );
690+ boolean changed = false ;
691+
692+ for (byte b : bytes ) {
693+ if (shouldEncode (b )) {
694+ changed = true ;
695+ byte b1 = (byte ) Character .toUpperCase (Character .forDigit ((b >> 4 ) & 0xF , 16 ));
696+ byte b2 = (byte ) Character .toUpperCase (Character .forDigit (b & 0xF , 16 ));
697+ buffer .put ((byte ) PERCENT_CHAR );
698+ buffer .put (b1 );
699+ buffer .put (b2 );
700+ } else {
701+ buffer .put (b );
735702 }
736703 }
737704
738- return new String (buffer .array (), 0 , buffer .position (), StandardCharsets .UTF_8 );
705+ return changed ? new String (buffer .array (), 0 , buffer .position (), StandardCharsets .UTF_8 ) : source ;
739706 }
740707
741708 /**
@@ -1005,7 +972,7 @@ public String getCoordinates() {
1005972 * @since 1.2.0
1006973 */
1007974 public boolean isCanonicalEquals (final PackageURL purl ) {
1008- return ( this .canonicalize ().equals (purl .canonicalize () ));
975+ return this .canonicalize ().equals (purl .canonicalize ());
1009976 }
1010977
1011978 private static boolean isEmpty (@ Nullable String value ) {
0 commit comments