@Test public void queryEndingWithSpaceDecoding() { assertEquals("foo ", Decoder.decode("foo%20", true)); assertEquals("foo ", Decoder.decode("foo ", true)); assertEquals("foo ", Decoder.decode("foo+", true)); }
public static String decode(final CharSequence path, final boolean query) { StringBuilder decoded = new StringBuilder(); int length = path.length(); int pos = 0; while (pos < length) { if (query && path.charAt(pos) == '+') { decoded.append(' '); pos++; continue; } if (path.charAt(pos) == '%') { byte[] bytes = new byte[length / 3]; int i = 0; boolean invalid = false; while (pos < length && path.charAt(pos) == '%') { if (pos + 2 < length) { try { String hex = path.subSequence(pos + 1, pos + 3).toString(); int b = Integer.parseInt(hex, 16); bytes[i++] = (byte) b; } catch (NumberFormatException e) { invalid = true; } } pos += 3; } if (!invalid) { decoded.append(new String(bytes, 0, i, UTF8)); } else { decoded.append('\uFFFD'); } } else { decoded.append(path.charAt(pos)); pos++; } } return decoded.toString(); }
Decoder { public static String decode(final CharSequence path, final boolean query) { StringBuilder decoded = new StringBuilder(); int length = path.length(); int pos = 0; while (pos < length) { if (query && path.charAt(pos) == '+') { decoded.append(' '); pos++; continue; } if (path.charAt(pos) == '%') { byte[] bytes = new byte[length / 3]; int i = 0; boolean invalid = false; while (pos < length && path.charAt(pos) == '%') { if (pos + 2 < length) { try { String hex = path.subSequence(pos + 1, pos + 3).toString(); int b = Integer.parseInt(hex, 16); bytes[i++] = (byte) b; } catch (NumberFormatException e) { invalid = true; } } pos += 3; } if (!invalid) { decoded.append(new String(bytes, 0, i, UTF8)); } else { decoded.append('\uFFFD'); } } else { decoded.append(path.charAt(pos)); pos++; } } return decoded.toString(); } }
Decoder { public static String decode(final CharSequence path, final boolean query) { StringBuilder decoded = new StringBuilder(); int length = path.length(); int pos = 0; while (pos < length) { if (query && path.charAt(pos) == '+') { decoded.append(' '); pos++; continue; } if (path.charAt(pos) == '%') { byte[] bytes = new byte[length / 3]; int i = 0; boolean invalid = false; while (pos < length && path.charAt(pos) == '%') { if (pos + 2 < length) { try { String hex = path.subSequence(pos + 1, pos + 3).toString(); int b = Integer.parseInt(hex, 16); bytes[i++] = (byte) b; } catch (NumberFormatException e) { invalid = true; } } pos += 3; } if (!invalid) { decoded.append(new String(bytes, 0, i, UTF8)); } else { decoded.append('\uFFFD'); } } else { decoded.append(path.charAt(pos)); pos++; } } return decoded.toString(); }  }
Decoder { public static String decode(final CharSequence path, final boolean query) { StringBuilder decoded = new StringBuilder(); int length = path.length(); int pos = 0; while (pos < length) { if (query && path.charAt(pos) == '+') { decoded.append(' '); pos++; continue; } if (path.charAt(pos) == '%') { byte[] bytes = new byte[length / 3]; int i = 0; boolean invalid = false; while (pos < length && path.charAt(pos) == '%') { if (pos + 2 < length) { try { String hex = path.subSequence(pos + 1, pos + 3).toString(); int b = Integer.parseInt(hex, 16); bytes[i++] = (byte) b; } catch (NumberFormatException e) { invalid = true; } } pos += 3; } if (!invalid) { decoded.append(new String(bytes, 0, i, UTF8)); } else { decoded.append('\uFFFD'); } } else { decoded.append(path.charAt(pos)); pos++; } } return decoded.toString(); }  static String path(final CharSequence path); static String query(final CharSequence query); static String decode(final CharSequence path, final boolean query); }
Decoder { public static String decode(final CharSequence path, final boolean query) { StringBuilder decoded = new StringBuilder(); int length = path.length(); int pos = 0; while (pos < length) { if (query && path.charAt(pos) == '+') { decoded.append(' '); pos++; continue; } if (path.charAt(pos) == '%') { byte[] bytes = new byte[length / 3]; int i = 0; boolean invalid = false; while (pos < length && path.charAt(pos) == '%') { if (pos + 2 < length) { try { String hex = path.subSequence(pos + 1, pos + 3).toString(); int b = Integer.parseInt(hex, 16); bytes[i++] = (byte) b; } catch (NumberFormatException e) { invalid = true; } } pos += 3; } if (!invalid) { decoded.append(new String(bytes, 0, i, UTF8)); } else { decoded.append('\uFFFD'); } } else { decoded.append(path.charAt(pos)); pos++; } } return decoded.toString(); }  static String path(final CharSequence path); static String query(final CharSequence query); static String decode(final CharSequence path, final boolean query);  }