diff --git a/buffer/src/main/java/io/netty/buffer/ByteBufUtil.java b/buffer/src/main/java/io/netty/buffer/ByteBufUtil.java index 6ec59cc4399b..2dda96bac286 100644 --- a/buffer/src/main/java/io/netty/buffer/ByteBufUtil.java +++ b/buffer/src/main/java/io/netty/buffer/ByteBufUtil.java @@ -21,6 +21,7 @@ import io.netty.util.Recycler; import io.netty.util.Recycler.Handle; import io.netty.util.concurrent.FastThreadLocal; +import io.netty.util.internal.EmptyArrays; import io.netty.util.internal.PlatformDependent; import io.netty.util.internal.StringUtil; import io.netty.util.internal.SystemPropertyUtil; @@ -124,6 +125,13 @@ public static String hexDump(byte[] array, int fromIndex, int length) { return HexUtil.hexDump(array, fromIndex, length); } + /** + * Decodes a string generated by {@link #hexDump(byte[])} + */ + public static byte[] decodeHexDump(CharSequence hexDump) { + return HexUtil.decodeHexDump(hexDump, 0, hexDump.length()); + } + /** * Calculates the hash code of the specified buffer. This method is * useful when implementing a new buffer type. @@ -869,6 +877,25 @@ private static String hexDump(ByteBuf buffer, int fromIndex, int length) { return new String(buf); } + private static byte[] decodeHexDump(CharSequence hexDump, int fromIndex, int length) { + if (length < 0) { + throw new IllegalArgumentException("length: " + length); + } + if (length == 0) { + return EmptyArrays.EMPTY_BYTES; + } + + int endIndex = fromIndex + length - 1; + byte[] bytes = new byte[length >>> 1]; + + for (; fromIndex < endIndex; fromIndex += 2) { + bytes[fromIndex >>> 1] = (byte) ((Character.digit(hexDump.charAt(fromIndex), 16) << 4) + + Character.digit(hexDump.charAt(fromIndex + 1), 16)); + } + + return bytes; + } + private static String hexDump(byte[] array, int fromIndex, int length) { if (length < 0) { throw new IllegalArgumentException("length: " + length); diff --git a/buffer/src/test/java/io/netty/buffer/ByteBufUtilTest.java b/buffer/src/test/java/io/netty/buffer/ByteBufUtilTest.java index a2bcd2db6103..e1bf859b2cab 100644 --- a/buffer/src/test/java/io/netty/buffer/ByteBufUtilTest.java +++ b/buffer/src/test/java/io/netty/buffer/ByteBufUtilTest.java @@ -23,12 +23,32 @@ import java.util.Random; import static io.netty.buffer.Unpooled.unreleasableBuffer; +import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; public class ByteBufUtilTest { + @Test + public void decodeHexEvenLength() { + decodeHex(256); + } + + @Test + public void decodeHexOddLength() { + decodeHex(257); + } + + private static void decodeHex(int len) { + byte[] b = new byte[len]; + Random rand = new Random(); + rand.nextBytes(b); + String hexDump = ByteBufUtil.hexDump(b); + byte[] decodedBytes = ByteBufUtil.decodeHexDump(hexDump); + assertArrayEquals(b, decodedBytes); + } + @Test public void equalsBufferSubsections() { byte[] b1 = new byte[128];