Skip to content

Commit

Permalink
Move methods for decode hex dump into StringUtil
Browse files Browse the repository at this point in the history
Motivation:

PR netty#6811 introduced a public utility methods to decode hex dump and its parts, but they are not visible from netty-common.

Modifications:

1. Move the `decodeHexByte`, `decodeHexDump` and `decodeHexNibble` methods into `StringUtils`.
2. Apply these methods where applicable.
3. Remove similar methods from other locations (e.g. `HpackHex` test class).

Result:

Less code duplication.
  • Loading branch information
fenik17 authored and normanmaurer committed Jun 23, 2017
1 parent 1767814 commit 01eb428
Show file tree
Hide file tree
Showing 11 changed files with 92 additions and 272 deletions.
56 changes: 3 additions & 53 deletions buffer/src/main/java/io/netty/buffer/ByteBufUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
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;
Expand Down Expand Up @@ -129,21 +128,21 @@ public static String hexDump(byte[] array, int fromIndex, int length) {
* Decode a 2-digit hex byte from within a string.
*/
public static byte decodeHexByte(CharSequence s, int pos) {
return HexUtil.decodeHexByte(s, pos);
return StringUtil.decodeHexByte(s, pos);
}

/**
* Decodes a string generated by {@link #hexDump(byte[])}
*/
public static byte[] decodeHexDump(CharSequence hexDump) {
return HexUtil.decodeHexDump(hexDump, 0, hexDump.length());
return StringUtil.decodeHexDump(hexDump, 0, hexDump.length());
}

/**
* Decodes part of a string generated by {@link #hexDump(byte[])}
*/
public static byte[] decodeHexDump(CharSequence hexDump, int fromIndex, int length) {
return HexUtil.decodeHexDump(hexDump, fromIndex, length);
return StringUtil.decodeHexDump(hexDump, fromIndex, length);
}

/**
Expand Down Expand Up @@ -891,55 +890,6 @@ private static String hexDump(ByteBuf buffer, int fromIndex, int length) {
return new String(buf);
}

/**
* Helper to decode half of a hexadecimal number from a string.
* @param c The ASCII character of the hexadecimal number to decode.
* Must be in the range {@code [0-9a-fA-F]}.
* @return The hexadecimal value represented in the ASCII character
* given, or {@code -1} if the character is invalid.
*/
private static int decodeHexNibble(final char c) {
// Character.digit() is not used here, as it addresses a larger
// set of characters (both ASCII and full-width latin letters).
if ('0' <= c && c <= '9') {
return c - '0';
}
if ('a' <= c && c <= 'f') {
return c - 'a' + 0xA;
}
if ('A' <= c && c <= 'F') {
return c - 'A' + 0xA;
}
return -1;
}

private static byte decodeHexByte(CharSequence s, int pos) {
int hi = decodeHexNibble(s.charAt(pos));
int lo = decodeHexNibble(s.charAt(pos + 1));
if (hi == -1 || lo == -1) {
throw new IllegalArgumentException(String.format(
"invalid hex byte '%s' at index %d of '%s'", s.subSequence(pos, pos + 2), pos, s));
}
return (byte) ((hi << 4) + lo);
}

private static byte[] decodeHexDump(CharSequence hexDump, int fromIndex, int length) {
if (length < 0 || (length & 1) != 0) {
throw new IllegalArgumentException("length: " + length);
}
if (length == 0) {
return EmptyArrays.EMPTY_BYTES;
}

byte[] bytes = new byte[length >>> 1];

for (int i = 0; i < length; i += 2) {
bytes[i >>> 1] = decodeHexByte(hexDump, fromIndex + i);
}

return bytes;
}

private static String hexDump(byte[] array, int fromIndex, int length) {
if (length < 0) {
throw new IllegalArgumentException("length: " + length);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@

import static io.netty.util.internal.ObjectUtil.*;
import static io.netty.util.internal.StringUtil.*;
import static io.netty.buffer.ByteBufUtil.decodeHexByte;

/**
* Splits an HTTP query string into a path string and key-value parameter pairs.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.util.internal.StringUtil;
import org.junit.Before;
import org.junit.Test;

Expand All @@ -55,11 +56,11 @@ public class HpackDecoderTest {
private Http2Headers mockHeaders;

private static String hex(String s) {
return HpackHex.encodeHexString(s.getBytes());
return StringUtil.toHexString(s.getBytes());
}

private void decode(String encoded) throws Http2Exception {
byte[] b = HpackHex.decodeHex(encoded.toCharArray());
byte[] b = StringUtil.decodeHexDump(encoded);
ByteBuf in = Unpooled.wrappedBuffer(b);
try {
hpackDecoder.decode(0, in, mockHeaders);
Expand All @@ -79,7 +80,7 @@ public void testDecodeULE128IntMax() throws Http2Exception {
byte[] input = {(byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0x07};
ByteBuf in = Unpooled.wrappedBuffer(input);
try {
assertEquals(Integer.MAX_VALUE, decodeULE128(in, 0));
assertEquals(MAX_VALUE, decodeULE128(in, 0));
} finally {
in.release();
}
Expand Down Expand Up @@ -224,7 +225,7 @@ public void testLiteralHuffmanEncodedWithPaddingNotCorrespondingToMSBThrows() th

@Test(expected = Http2Exception.class)
public void testIncompleteIndex() throws Http2Exception {
byte[] compressed = HpackHex.decodeHex("FFF0".toCharArray());
byte[] compressed = StringUtil.decodeHexDump("FFF0");
ByteBuf in = Unpooled.wrappedBuffer(compressed);
try {
hpackDecoder.decode(0, in, mockHeaders);
Expand Down
162 changes: 0 additions & 162 deletions codec-http2/src/test/java/io/netty/handler/codec/http2/HpackHex.java

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@
import com.google.gson.JsonParseException;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.util.internal.StringUtil;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.Type;
Expand Down Expand Up @@ -71,11 +71,11 @@ final class HpackTestCase {
private HpackTestCase() {
}

static HpackTestCase load(InputStream is) throws IOException {
static HpackTestCase load(InputStream is) {
InputStreamReader r = new InputStreamReader(is);
HpackTestCase hpackTestCase = GSON.fromJson(r, HpackTestCase.class);
for (HeaderBlock headerBlock : hpackTestCase.headerBlocks) {
headerBlock.encodedBytes = HpackHex.decodeHex(headerBlock.getEncodedStr().toCharArray());
headerBlock.encodedBytes = StringUtil.decodeHexDump(headerBlock.getEncodedStr());
}
return hpackTestCase;
}
Expand All @@ -92,7 +92,7 @@ void testCompress() throws Exception {
if (!Arrays.equals(actual, headerBlock.encodedBytes)) {
throw new AssertionError(
"\nEXPECTED:\n" + headerBlock.getEncodedStr() +
"\nACTUAL:\n" + HpackHex.encodeHexString(actual));
"\nACTUAL:\n" + StringUtil.toHexString(actual));
}

List<HpackHeaderField> actualDynamicTable = new ArrayList<HpackHeaderField>();
Expand Down
22 changes: 2 additions & 20 deletions common/src/main/java/io/netty/util/NetUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

import io.netty.util.internal.PlatformDependent;
import io.netty.util.internal.SocketUtils;
import io.netty.util.internal.StringUtil;
import io.netty.util.internal.SystemPropertyUtil;
import io.netty.util.internal.logging.InternalLogger;
import io.netty.util.internal.logging.InternalLoggerFactory;
Expand Down Expand Up @@ -381,25 +382,6 @@ public static byte[] createByteArrayFromIpAddressString(String ipAddressString)
return null;
}

/**
* Convert ASCII hexadecimal character to the {@code int} value.
* Unlike {@link Character#digit(char, int)}, returns {@code 0} if character is not a HEX-represented.
*/
private static int getIntValue(char c) {
if (c >= '0' && c <= '9') {
return c - '0';
}
if (c >= 'A' && c <= 'F') {
// 0xA - a start value in sequence 'A'..'F'
return c - 'A' + 0xA;
}
if (c >= 'a' && c <= 'f') {
// 0xA - a start value in sequence 'a'..'f'
return c - 'a' + 0xA;
}
return 0;
}

private static int decimalDigit(String str, int pos) {
return str.charAt(pos) - '0';
}
Expand Down Expand Up @@ -808,7 +790,7 @@ private static byte[] getIPv6ByName(CharSequence ip, boolean ipv4Mapped) {
// at most 4 consecutive bytes we can use bit shifting to accomplish this.
// The most significant byte will be encountered first, and reside in the right most
// position of the following integer
value += getIntValue(c) << ((i - begin) << 2);
value += StringUtil.decodeHexNibble(c) << ((i - begin) << 2);
break;
}
}
Expand Down
Loading

0 comments on commit 01eb428

Please sign in to comment.