Skip to content

Commit d993b3a

Browse files
committed
Improve performance of encode and decode
Don't bother partitioning array Skip bytes already in the decode buffer
1 parent fe90327 commit d993b3a

File tree

1 file changed

+29
-60
lines changed

1 file changed

+29
-60
lines changed

src/main/java/com/github/packageurl/PackageURL.java

Lines changed: 29 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)