Skip to content

Instantly share code, notes, and snippets.

@bnorm
Created March 29, 2017 21:22
Show Gist options
  • Save bnorm/7b29521703df3d0dc27f621ff938e1ff to your computer and use it in GitHub Desktop.
Save bnorm/7b29521703df3d0dc27f621ff938e1ff to your computer and use it in GitHub Desktop.
Charset for encoding and decoding bytes as hexidecimal
public class HexCharset extends Charset {
public static final HexCharset INSTANCE = new HexCharset();
private HexCharset() {
super("hex", new String[0]);
}
@Override
public boolean contains(Charset cs) {
return cs instanceof HexCharset;
}
@Override
public CharsetDecoder newDecoder() {
return new CharsetDecoder(HexCharset.this, 2f, 2f) {
@Override
protected CoderResult decodeLoop(ByteBuffer in, CharBuffer out) {
while (in.hasRemaining()) {
if (out.remaining() < 1) {
return CoderResult.OVERFLOW;
}
byte b = in.get();
out.append(HEX_DIGITS[(b >> 4) & 0xf]);
out.append(HEX_DIGITS[b & 0xf]);
}
return CoderResult.UNDERFLOW;
}
};
}
@Override
public CharsetEncoder newEncoder() {
return new CharsetEncoder(this, 0.5f, 1) {
@Override
protected CoderResult encodeLoop(CharBuffer in, ByteBuffer out) {
if (in.remaining() % 2 != 0) {
throw new IllegalArgumentException("Unexpected number of characters: " + in.remaining());
}
while (in.hasRemaining()) {
if (!out.hasRemaining()) {
return CoderResult.OVERFLOW;
}
char c1 = in.get();
char c2 = in.get();
int d1 = decodeHexDigit(c1);
int d2 = decodeHexDigit(c2);
out.put((byte) ((d1 << 4) + d2));
}
return CoderResult.UNDERFLOW;
}
};
}
// @formatter:off
private static final char[] HEX_DIGITS = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
private static int decodeHexDigit(char c) {
if (c >= '0' && c <= '9') { return c - '0'; }
if (c >= 'a' && c <= 'f') { return c - 'a' + 10; }
if (c >= 'A' && c <= 'F') { return c - 'A' + 10; }
throw new IllegalArgumentException("Unexpected hex digit: " + c);
}
// @formatter:on
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment