3434import java .util .TreeMap ;
3535import java .util .regex .Pattern ;
3636import java .util .stream .Collectors ;
37- import java .util .stream .IntStream ;
3837
3938/**
4039 * <p>Package-URL (aka purl) is a "mostly universal" URL to describe a package. A purl is a URL composed of seven components:</p>
@@ -448,14 +447,18 @@ private static String uriEncode(String source, Charset charset) {
448447 }
449448
450449 byte [] bytes = source .getBytes (charset );
450+ int length = bytes .length ;
451+ int pos = indexOfFirstUnreservedChar (bytes );
451452
452- if (IntStream . range ( 0 , bytes . length ). allMatch ( i -> isUnreserved ( bytes [ i ])) ) {
453+ if (pos == - 1 ) {
453454 return source ;
454455 }
455456
456- StringBuilder builder = new StringBuilder (source .length ());
457+ StringBuilder builder = new StringBuilder (source .substring (0 , pos ));
458+
459+ for (int i = pos ; i < length ; i ++) {
460+ byte b = bytes [i ];
457461
458- for (byte b : bytes ) {
459462 if (isUnreserved (b )) {
460463 builder .append ((char ) b );
461464 } else {
@@ -468,6 +471,20 @@ private static String uriEncode(String source, Charset charset) {
468471 return builder .toString ();
469472 }
470473
474+ private static int indexOfFirstUnreservedChar (final byte [] bytes ) {
475+ final int length = bytes .length ;
476+ int pos = -1 ;
477+
478+ for (int i = 0 ; i < length ; i ++) {
479+ if (!isUnreserved (bytes [i ])) {
480+ pos = i ;
481+ break ;
482+ }
483+ }
484+
485+ return pos ;
486+ }
487+
471488 private static boolean isUnreserved (int c ) {
472489 return (isAlpha (c ) || isDigit (c ) || '-' == c || '.' == c || '_' == c || '~' == c );
473490 }
0 commit comments