PercentCodec { static String decode(final CharSequence content, final Charset charset, final boolean plusAsBlank) { if (content == null) { return null; } final ByteBuffer bb = ByteBuffer.allocate(content.length()); final CharBuffer cb = CharBuffer.wrap(content); while (cb.hasRemaining()) { final char c = cb.get(); if (c == '%' && cb.remaining() >= 2) { final char uc = cb.get(); final char lc = cb.get(); final int u = Character.digit(uc, RADIX); final int l = Character.digit(lc, RADIX); if (u != -1 && l != -1) { bb.put((byte) ((u << 4) + l)); } else { bb.put((byte) '%'); bb.put((byte) uc); bb.put((byte) lc); } } else if (plusAsBlank && c == '+') { bb.put((byte) ' '); } else { bb.put((byte) c); } } bb.flip(); return (charset != null ? charset : StandardCharsets.UTF_8).decode(bb).toString(); }  static void encode(final StringBuilder buf, final CharSequence content, final Charset charset); static String encode(final CharSequence content, final Charset charset); static String decode(final CharSequence content, final Charset charset);  }
@Test public void testDecoding() { MatcherAssert.assertThat(PercentCodec.decode("blah%21%20~%20huh%3F", StandardCharsets.UTF_8), CoreMatchers.equalTo("blah! ~ huh?")); MatcherAssert.assertThat(PercentCodec.decode("blah%21+~%20huh%3F", StandardCharsets.UTF_8), CoreMatchers.equalTo("blah!+~ huh?")); MatcherAssert.assertThat(PercentCodec.decode("blah%21+~%20huh%3F", StandardCharsets.UTF_8, true), CoreMatchers.equalTo("blah! ~ huh?")); }
@Test public void testDecodingPartialContent() { MatcherAssert.assertThat(PercentCodec.decode("blah%21%20%", StandardCharsets.UTF_8), CoreMatchers.equalTo("blah! %")); MatcherAssert.assertThat(PercentCodec.decode("blah%21%20%a", StandardCharsets.UTF_8), CoreMatchers.equalTo("blah! %a")); MatcherAssert.assertThat(PercentCodec.decode("blah%21%20%wa", StandardCharsets.UTF_8), CoreMatchers.equalTo("blah! %wa")); }