Skip to content

Commit

Permalink
[Java] Tidy up and improvements after merge of PR #169.
Browse files Browse the repository at this point in the history
  • Loading branch information
mjpt777 committed Apr 26, 2019
1 parent 9bddb2e commit 96308ec
Show file tree
Hide file tree
Showing 3 changed files with 104 additions and 101 deletions.
156 changes: 60 additions & 96 deletions agrona/src/main/java/org/agrona/PrintBufferUtil.java
Original file line number Diff line number Diff line change
@@ -1,92 +1,65 @@
/*
* Copyright 2012 The Netty Project
* Copyright 2014-2019 Real Logic Ltd.
*
* The Netty Project licenses this file to you under the Apache License,
* version 2.0 (the "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at:
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.agrona;


import java.util.Formatter;


/**
* Useful utils for hex dump of the agrona's buffers.
*
* This is code from <a href="https://netty.io/">the Netty project</a> adopted to {@link MutableDirectBuffer}
* This is code adapted from <a href="https://netty.io/">the Netty project</a> adopted to support {@link DirectBuffer}.
*/
public final class PrintBufferUtil
{
public static final String NEWLINE;
public static final String EMPTY_STRING = "";
private static final String NEWLINE = System.lineSeparator();
private static final String EMPTY_STRING = "";
private static final String[] BYTE2HEX_PAD = new String[256];

static
{
// Determine the newline character of the current platform.
String newLine;

try (Formatter formatter = new Formatter())
{
newLine = formatter.format("%n").toString();
}
catch (final Exception e)
{
// Should not reach here, but just in case.
newLine = "\n";
}

NEWLINE = newLine;

// Generate the lookup table that converts a byte into a 2-digit hexadecimal integer.
int i;
for (i = 0; i < 10; i++)
{
final StringBuilder builder = new StringBuilder(2);
builder.append('0');
builder.append(i);
BYTE2HEX_PAD[i] = builder.toString();
BYTE2HEX_PAD[i] = "0" + i;
}

for (; i < 16; i++)
{
final StringBuilder builder = new StringBuilder(2);
final char c = (char)('a' + i - 10);
builder.append('0');
builder.append(c);
BYTE2HEX_PAD[i] = builder.toString();
BYTE2HEX_PAD[i] = "0" + c;
}

for (; i < BYTE2HEX_PAD.length; i++)
{
final StringBuilder builder = new StringBuilder(2);
builder.append(Integer.toHexString(i));
final String str = builder.toString();
BYTE2HEX_PAD[i] = str;
BYTE2HEX_PAD[i] = Integer.toHexString(i);
}
}


/**
* Returns a <a href="http://en.wikipedia.org/wiki/Hex_dump">hex dump</a>
* of the specified buffer's readable bytes.
*
* @param buffer dumped buffer
* @return hex dump in a string representation
*/
public static String hexDump(final MutableDirectBuffer buffer)
public static String hexDump(final DirectBuffer buffer)
{
return hexDump(buffer, 0, buffer.capacity());
}


/**
* Returns a <a href="http://en.wikipedia.org/wiki/Hex_dump">hex dump</a>
* of the specified buffer's sub-region.
Expand All @@ -96,7 +69,7 @@ public static String hexDump(final MutableDirectBuffer buffer)
* @param length how much should we print
* @return hex dump in a string representation
*/
public static String hexDump(final MutableDirectBuffer buffer, final int fromIndex, final int length)
public static String hexDump(final DirectBuffer buffer, final int fromIndex, final int length)
{
return HexUtil.hexDump(buffer, fromIndex, length);
}
Expand Down Expand Up @@ -127,46 +100,45 @@ public static String hexDump(final byte[] array, final int fromIndex, final int
return HexUtil.hexDump(array, fromIndex, length);
}


/**
* Returns a multi-line hexadecimal dump of the specified {@link MutableDirectBuffer} that is easy to read by humans.
* Returns a hexadecimal dump of the specified {@link DirectBuffer} that is easy to read by humans.
*
* @param buffer dumped buffer
* @return pretty hex dump in a string representation
*/
public static String prettyHexDump(final MutableDirectBuffer buffer)
public static String prettyHexDump(final DirectBuffer buffer)
{
return prettyHexDump(buffer, 0, buffer.capacity());
}

/**
* Returns a multi-line hexadecimal dump of the specified {@link MutableDirectBuffer} that is easy to read by humans,
* Returns a hexadecimal dump of the specified {@link DirectBuffer} that is easy to read by humans,
* starting at the given {@code offset} using the given {@code length}.
*
* @param buffer dumped buffer
* @param offset where should we start to print
* @param length how much should we print
* @return pretty hex dump in a string representation
*/
public static String prettyHexDump(final MutableDirectBuffer buffer, final int offset, final int length)
public static String prettyHexDump(final DirectBuffer buffer, final int offset, final int length)
{
return HexUtil.prettyHexDump(buffer, offset, length);
}

/**
* Appends the prettified multi-line hexadecimal dump of the specified {@link MutableDirectBuffer} to the specified
* Appends the prettified multi-line hexadecimal dump of the specified {@link DirectBuffer} to the specified
* {@link StringBuilder} that is easy to read by humans.
*
* @param dump where should we append string representation of the buffer
* @param buffer dumped buffer
*/
public static void appendPrettyHexDump(final StringBuilder dump, final MutableDirectBuffer buffer)
public static void appendPrettyHexDump(final StringBuilder dump, final DirectBuffer buffer)
{
appendPrettyHexDump(dump, buffer, 0, buffer.capacity());
}

/**
* Appends the prettified multi-line hexadecimal dump of the specified {@link MutableDirectBuffer} to the specified
* Appends the prettified multi-line hexadecimal dump of the specified {@link DirectBuffer} to the specified
* {@link StringBuilder} that is easy to read by humans, starting at the given {@code offset} using
* the given {@code length}.
*
Expand All @@ -175,8 +147,8 @@ public static void appendPrettyHexDump(final StringBuilder dump, final MutableDi
* @param offset where should we start to print
* @param length how much should we print
*/
public static void appendPrettyHexDump(final StringBuilder dump, final MutableDirectBuffer buffer, final int offset,
final int length)
public static void appendPrettyHexDump(
final StringBuilder dump, final DirectBuffer buffer, final int offset, final int length)
{
HexUtil.appendPrettyHexDump(dump, buffer, offset, length);
}
Expand All @@ -192,16 +164,14 @@ public static String byteToHexStringPadded(final int value)
return BYTE2HEX_PAD[value & 0xff];
}

/* Separate class so that the expensive static initialization is only done when needed */
private static final class HexUtil
{

private static final char[] BYTE2CHAR = new char[256];
private static final char[] HEXDUMP_TABLE = new char[256 * 4];
private static final String[] HEXPADDING = new String[16];
private static final String[] HEXDUMP_ROWPREFIXES = new String[65536 >>> 4];
private static final String[] HEX_PADDING = new String[16];
private static final String[] HEXDUMP_ROW_PREFIXES = new String[65536 >>> 4];
private static final String[] BYTE2HEX = new String[256];
private static final String[] BYTEPADDING = new String[16];
private static final String[] BYTE_PADDING = new String[16];

static
{
Expand All @@ -214,27 +184,27 @@ private static final class HexUtil

int i;

// Generate the lookup table for hex dump paddings
for (i = 0; i < HEXPADDING.length; i++)
// Generate the lookup table for hex dump padding
for (i = 0; i < HEX_PADDING.length; i++)
{
final int padding = HEXPADDING.length - i;
final int padding = HEX_PADDING.length - i;
final StringBuilder buf = new StringBuilder(padding * 3);
for (int j = 0; j < padding; j++)
{
buf.append(" ");
}
HEXPADDING[i] = buf.toString();
HEX_PADDING[i] = buf.toString();
}

// Generate the lookup table for the start-offset header in each row (up to 64KiB).
for (i = 0; i < HEXDUMP_ROWPREFIXES.length; i++)
for (i = 0; i < HEXDUMP_ROW_PREFIXES.length; i++)
{
final StringBuilder buf = new StringBuilder(12);
buf.append(NEWLINE);
buf.append(Long.toHexString(i << 4 & 0xFFFFFFFFL | 0x100000000L));
buf.setCharAt(buf.length() - 9, '|');
buf.append('|');
HEXDUMP_ROWPREFIXES[i] = buf.toString();
HEXDUMP_ROW_PREFIXES[i] = buf.toString();
}

// Generate the lookup table for byte-to-hex-dump conversion
Expand All @@ -244,28 +214,21 @@ private static final class HexUtil
}

// Generate the lookup table for byte dump paddings
for (i = 0; i < BYTEPADDING.length; i++)
for (i = 0; i < BYTE_PADDING.length; i++)
{
final int padding = BYTEPADDING.length - i;
final int padding = BYTE_PADDING.length - i;
final StringBuilder buf = new StringBuilder(padding);
for (int j = 0; j < padding; j++)
{
buf.append(' ');
}
BYTEPADDING[i] = buf.toString();
BYTE_PADDING[i] = buf.toString();
}

// Generate the lookup table for byte-to-char conversion
for (i = 0; i < BYTE2CHAR.length; i++)
{
if (i <= 0x1f || i >= 0x7f)
{
BYTE2CHAR[i] = '.';
}
else
{
BYTE2CHAR[i] = (char)i;
}
BYTE2CHAR[i] = (i <= 0x1f || i >= 0x7f) ? '.' : (char)i;
}
}

Expand All @@ -276,17 +239,18 @@ private static final class HexUtil
* @param index the absolute {@code index} in the buffer.
* @return unsigned byte value
*/
static short getUnsignedByte(final MutableDirectBuffer buffer, final int index)
static short getUnsignedByte(final DirectBuffer buffer, final int index)
{
return (short)(buffer.getByte(index) & 0xFF);
}

private static String hexDump(final MutableDirectBuffer buffer, final int fromIndex, final int length)
private static String hexDump(final DirectBuffer buffer, final int fromIndex, final int length)
{
if (length < 0)
{
throw new IllegalArgumentException("length: " + length);
}

if (length == 0)
{
return "";
Expand All @@ -295,9 +259,7 @@ private static String hexDump(final MutableDirectBuffer buffer, final int fromIn
final int endIndex = fromIndex + length;
final char[] buf = new char[length << 1];

int srcIdx = fromIndex;
int dstIdx = 0;
for (; srcIdx < endIndex; srcIdx++, dstIdx += 2)
for (int dstIdx = 0, srcIdx = fromIndex; srcIdx < endIndex; srcIdx++, dstIdx += 2)
{
System.arraycopy(
HEXDUMP_TABLE, getUnsignedByte(buffer, srcIdx) << 1,
Expand All @@ -313,6 +275,7 @@ private static String hexDump(final byte[] array, final int fromIndex, final int
{
throw new IllegalArgumentException("length: " + length);
}

if (length == 0)
{
return "";
Expand All @@ -321,9 +284,7 @@ private static String hexDump(final byte[] array, final int fromIndex, final int
final int endIndex = fromIndex + length;
final char[] buf = new char[length << 1];

int srcIdx = fromIndex;
int dstIdx = 0;
for (; srcIdx < endIndex; srcIdx++, dstIdx += 2)
for (int dstIdx = 0, srcIdx = fromIndex; srcIdx < endIndex; srcIdx++, dstIdx += 2)
{
System.arraycopy(
HEXDUMP_TABLE, (array[srcIdx] & 0xFF) << 1,
Expand All @@ -333,7 +294,7 @@ private static String hexDump(final byte[] array, final int fromIndex, final int
return new String(buf);
}

private static String prettyHexDump(final MutableDirectBuffer buffer, final int offset, final int length)
private static String prettyHexDump(final DirectBuffer buffer, final int offset, final int length)
{
if (length == 0)
{
Expand All @@ -344,6 +305,7 @@ private static String prettyHexDump(final MutableDirectBuffer buffer, final int
final int rows = length / 16 + (length % 15 == 0 ? 0 : 1) + 4;
final StringBuilder stringBuilder = new StringBuilder(rows * 80);
appendPrettyHexDump(stringBuilder, buffer, offset, length);

return stringBuilder.toString();
}
}
Expand All @@ -362,20 +324,21 @@ public static boolean isOutOfBounds(final int index, final int length, final int
return (index | length | (index + length) | (capacity - (index + length))) < 0;
}

private static void appendPrettyHexDump(final StringBuilder dump, final MutableDirectBuffer buffer,
final int offset,
final int length)
private static void appendPrettyHexDump(
final StringBuilder dump, final DirectBuffer buffer, final int offset, final int length)
{
if (isOutOfBounds(offset, length, buffer.capacity()))
{
throw new IndexOutOfBoundsException(
"expected: " + "0 <= offset(" + offset + ") <= offset + length(" + length + ") <= " +
"buffer.capacity(" + buffer.capacity() + ')');
"buffer.capacity(" + buffer.capacity() + ')');
}

if (length == 0)
{
return;
}

dump.append(" +-------------------------------------------------+")
.append(NEWLINE)
.append(" | 0 1 2 3 4 5 6 7 8 9 a b c d e f |")
Expand Down Expand Up @@ -422,26 +385,27 @@ private static void appendPrettyHexDump(final StringBuilder dump, final MutableD
{
dump.append(BYTE2HEX[getUnsignedByte(buffer, j)]);
}
dump.append(HEXPADDING[remainder]);
dump.append(HEX_PADDING[remainder]);
dump.append(" |");

// Ascii dump
for (int j = rowStartIndex; j < rowEndIndex; j++)
{
dump.append(BYTE2CHAR[getUnsignedByte(buffer, j)]);
}
dump.append(BYTEPADDING[remainder]);
dump.append(BYTE_PADDING[remainder]);
dump.append('|');
}

dump.append(NEWLINE + "+--------+-------------------------------------------------+----------------+");
dump.append(NEWLINE)
.append("+--------+-------------------------------------------------+----------------+");
}

private static void appendHexDumpRowPrefix(final StringBuilder dump, final int row, final int rowStartIndex)
{
if (row < HEXDUMP_ROWPREFIXES.length)
if (row < HEXDUMP_ROW_PREFIXES.length)
{
dump.append(HEXDUMP_ROWPREFIXES[row]);
dump.append(HEXDUMP_ROW_PREFIXES[row]);
}
else
{
Expand Down
Loading

0 comments on commit 96308ec

Please sign in to comment.