![JAR search and dependency download from the Maven repository](/logo.png)
one.nio.util.URLEncoder Maven / Gradle / Ivy
/*
* Copyright 2015 Odnoklassniki Ltd, Mail.Ru Group
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package one.nio.util;
// I know there are standard encoders, but this one is way faster
public final class URLEncoder {
private static final String SAFE_CHARS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-_.!*'()";
private static final boolean[] IS_SAFE_CHAR = new boolean[128];
static {
int length = SAFE_CHARS.length();
for (int i = 0; i < length; i++) {
IS_SAFE_CHAR[SAFE_CHARS.charAt(i)] = true;
}
}
public static String encode(String url) {
int length = url.length();
int specialChars = 0;
for (int i = 0; i < length; i++) {
char c = url.charAt(i);
if (c >= 128) {
specialChars += c <= 0xfff ? 5 : 8;
} else if (!IS_SAFE_CHAR[c]) {
specialChars += 2;
}
}
if (specialChars == 0) {
return url;
}
char[] chars = new char[length + specialChars];
int p = 0;
for (int i = 0; i < length; i++) {
char c = url.charAt(i);
if (c >= 128) {
if (c <= 0xfff) {
encodeByte(chars, p, 0xc0 | ((c >>> 6) & 0x1f));
encodeByte(chars, p + 3, 0x80 | (c & 0x3f));
p += 6;
} else {
encodeByte(chars, p, 0xe0 | ((c >>> 12) & 0x0f));
encodeByte(chars, p + 3, 0x80 | ((c >>> 6) & 0x3f));
encodeByte(chars, p + 6, 0x80 | (c & 0x3f));
p += 9;
}
} else if (!IS_SAFE_CHAR[c]) {
encodeByte(chars, p, c);
p += 3;
} else {
chars[p++] = c;
}
}
return new String(chars);
}
public static String decode(String url) {
int i = url.indexOf('%');
int j = url.indexOf('+');
if (i < 0 && j < 0) {
return url;
}
char[] chars = url.toCharArray();
while (j >= 0) {
chars[j] = ' ';
j = url.indexOf('+', j + 1);
}
if (i < 0) {
return new String(chars);
}
try {
int p = i;
while (i + 3 <= chars.length) {
int c1 = decodeByte(chars, i);
if (c1 <= 0x7f) {
chars[p] = (char) c1;
i += 3;
} else if ((c1 & 0xe0) == 0xc0 && i + 6 <= chars.length && chars[i + 3] == '%') {
int c2 = decodeByte(chars, i + 3);
chars[p] = (char) ((c1 & 0x1f) << 6 | (c2 & 0x3f));
i += 6;
} else if (i + 9 <= chars.length && chars[i + 3] == '%' && chars[i + 6] == '%') {
int c2 = decodeByte(chars, i + 3);
int c3 = decodeByte(chars, i + 6);
chars[p] = (char) ((c1 & 0x0f) << 12 | (c2 & 0x3f) << 6 | (c3 & 0x3f));
i += 9;
} else {
chars[p] = '%';
i++;
}
p++;
while (i < chars.length && chars[i] != '%') {
chars[p++] = chars[i++];
}
}
return new String(chars, 0, p);
} catch (RuntimeException e) {
throw new IllegalArgumentException("Invalid URL: " + url);
}
}
private static void encodeByte(char[] chars, int p, int value) {
chars[p] = '%';
chars[p + 1] = Hex.CAPITAL[value >>> 4];
chars[p + 2] = Hex.CAPITAL[value & 15];
}
private static int decodeByte(char[] chars, int p) {
return Hex.DIGIT_VALUE[chars[p + 1]] << 4 | Hex.DIGIT_VALUE[chars[p + 2]];
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy