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>
@@ -451,14 +450,18 @@ private static String uriEncode(String source, Charset charset) {
451450 }
452451
453452 byte [] bytes = source .getBytes (charset );
453+ int length = bytes .length ;
454+ int pos = indexOfFirstUnreservedChar (bytes );
454455
455- if (IntStream . range ( 0 , bytes . length ). allMatch ( i -> isUnreserved ( bytes [ i ])) ) {
456+ if (pos == - 1 ) {
456457 return source ;
457458 }
458459
459- StringBuilder builder = new StringBuilder (source .length ());
460+ StringBuilder builder = new StringBuilder (source .substring (0 , pos ));
461+
462+ for (int i = pos ; i < length ; i ++) {
463+ byte b = bytes [i ];
460464
461- for (byte b : bytes ) {
462465 if (isUnreserved (b )) {
463466 builder .append ((char ) b );
464467 } else {
@@ -471,6 +474,20 @@ private static String uriEncode(String source, Charset charset) {
471474 return builder .toString ();
472475 }
473476
477+ private static int indexOfFirstUnreservedChar (final byte [] bytes ) {
478+ final int length = bytes .length ;
479+ int pos = -1 ;
480+
481+ for (int i = 0 ; i < length ; i ++) {
482+ if (!isUnreserved (bytes [i ])) {
483+ pos = i ;
484+ break ;
485+ }
486+ }
487+
488+ return pos ;
489+ }
490+
474491 private static boolean isUnreserved (int c ) {
475492 return (isAlpha (c ) || isDigit (c ) || '-' == c || '.' == c || '_' == c || '~' == c );
476493 }
0 commit comments