@@ -575,7 +575,7 @@ private static boolean isLowerCase(int c) {
575575 }
576576
577577 private static int toLowerCase (int c ) {
578- return ( c ^ 0x20 );
578+ return isUpperCase ( c ) ? ( c ^ 0x20 ) : c ;
579579 }
580580
581581 private static String toLowerCase (String s ) {
@@ -589,9 +589,7 @@ private static String toLowerCase(String s) {
589589 int length = chars .length ;
590590
591591 for (int i = pos ; i < length ; i ++) {
592- if (isUpperCase (chars [i ])) {
593- chars [i ] = (char ) toLowerCase (chars [i ]);
594- }
592+ chars [i ] = (char ) toLowerCase (chars [i ]);
595593 }
596594
597595 return new String (chars );
@@ -638,43 +636,33 @@ private static byte percentDecode(final byte[] bytes, final int start) {
638636 return ((byte ) ((c1 << 4 ) + c2 ));
639637 }
640638
641- public static String percentDecode (final String source ) {
639+ private static String percentDecode (final String source ) {
642640 if (source .isEmpty ()) {
643641 return source ;
644642 }
645643
646644 byte [] bytes = source .getBytes (StandardCharsets .UTF_8 );
645+ int i = indexOfPercentChar (bytes , 0 );
647646
648- int off = 0 ;
649- int idx = indexOfPercentChar (bytes , off );
650-
651- if (idx == -1 ) {
647+ if (i == -1 ) {
652648 return source ;
653649 }
654650
655651 ByteBuffer buffer = ByteBuffer .wrap (bytes );
652+ buffer .position (i );
653+ int length = buffer .capacity ();
656654
657- while (true ) {
658- int len = idx - off ;
655+ while (i < length ) {
656+ byte b = bytes [ i ] ;
659657
660- if (len > 0 ) {
661- buffer .put (bytes , off , len );
662- off += len ;
658+ if (isPercent (b )) {
659+ buffer .put (percentDecode (bytes , i ));
660+ i += 2 ;
661+ } else {
662+ buffer .put (b );
663663 }
664664
665- buffer .put (percentDecode (bytes , off ));
666- off += 3 ;
667- idx = indexOfPercentChar (bytes , off );
668-
669- if (idx == -1 ) {
670- int rem = bytes .length - off ;
671-
672- if (rem > 0 ) {
673- buffer .put (bytes , off , rem );
674- }
675-
676- break ;
677- }
665+ i ++;
678666 }
679667
680668 return new String (buffer .array (), 0 , buffer .position (), StandardCharsets .UTF_8 );
@@ -689,51 +677,30 @@ private static boolean isPercent(int c) {
689677 return (c == PERCENT_CHAR );
690678 }
691679
692- private static byte [] percentEncode (byte b ) {
693- byte b1 = (byte ) Character .toUpperCase (Character .forDigit ((b >> 4 ) & 0xF , 16 ));
694- byte b2 = (byte ) Character .toUpperCase (Character .forDigit (b & 0xF , 16 ));
695- return new byte [] {(byte ) PERCENT_CHAR , b1 , b2 };
696- }
697-
698- public static String percentEncode (final String source ) {
680+ private static String percentEncode (final String source ) {
699681 if (source .isEmpty ()) {
700682 return source ;
701683 }
702684
703685 byte [] bytes = source .getBytes (StandardCharsets .UTF_8 );
704-
705- int off = 0 ;
706- int idx = indexOfUnsafeChar (bytes , off );
707-
708- if (idx == -1 ) {
709- return source ;
710- }
711-
712- ByteBuffer buffer = ByteBuffer .allocate (bytes .length * 3 );
713-
714- while (true ) {
715- int len = idx - off ;
716-
717- if (len > 0 ) {
718- buffer .put (bytes , off , len );
719- off += len ;
720- }
721-
722- buffer .put (percentEncode (bytes [off ++]));
723- idx = indexOfUnsafeChar (bytes , off );
724-
725- if (idx == -1 ) {
726- int rem = bytes .length - off ;
727-
728- if (rem > 0 ) {
729- buffer .put (bytes , off , rem );
730- }
731-
732- break ;
686+ int length = bytes .length ;
687+ ByteBuffer buffer = ByteBuffer .allocate (length * 3 );
688+ boolean changed = false ;
689+
690+ for (byte b : bytes ) {
691+ if (shouldEncode (b )) {
692+ changed = true ;
693+ byte b1 = (byte ) Character .toUpperCase (Character .forDigit ((b >> 4 ) & 0xF , 16 ));
694+ byte b2 = (byte ) Character .toUpperCase (Character .forDigit (b & 0xF , 16 ));
695+ buffer .put ((byte ) PERCENT_CHAR );
696+ buffer .put (b1 );
697+ buffer .put (b2 );
698+ } else {
699+ buffer .put (b );
733700 }
734701 }
735702
736- return new String (buffer .array (), 0 , buffer .position (), StandardCharsets .UTF_8 );
703+ return changed ? new String (buffer .array (), 0 , buffer .position (), StandardCharsets .UTF_8 ) : source ;
737704 }
738705
739706 /**
@@ -948,7 +915,7 @@ public String getCoordinates() {
948915 * @since 1.2.0
949916 */
950917 public boolean isCanonicalEquals (final PackageURL purl ) {
951- return ( this .canonicalize ().equals (purl .canonicalize () ));
918+ return this .canonicalize ().equals (purl .canonicalize ());
952919 }
953920
954921 private static boolean isEmpty (@ Nullable String value ) {
0 commit comments