diff --git a/src/main/java/org/jboss/netty/example/echo/EchoClient.java b/src/main/java/org/jboss/netty/example/echo/EchoClient.java index d9e17ad349..3a9694ae22 100644 --- a/src/main/java/org/jboss/netty/example/echo/EchoClient.java +++ b/src/main/java/org/jboss/netty/example/echo/EchoClient.java @@ -36,7 +36,7 @@ public class EchoClient { private final String host; private final int port; private final int firstMessageSize; - + public EchoClient(String host, int port, int firstMessageSize) { this.host = host; this.port = port; diff --git a/src/main/java/org/jboss/netty/handler/logging/LoggingHandler.java b/src/main/java/org/jboss/netty/handler/logging/LoggingHandler.java index b9effa4d56..255c3f1687 100644 --- a/src/main/java/org/jboss/netty/handler/logging/LoggingHandler.java +++ b/src/main/java/org/jboss/netty/handler/logging/LoggingHandler.java @@ -15,17 +15,15 @@ */ package org.jboss.netty.handler.logging; -import static org.jboss.netty.buffer.ChannelBuffers.*; - import org.jboss.netty.buffer.ChannelBuffer; import org.jboss.netty.channel.ChannelDownstreamHandler; import org.jboss.netty.channel.ChannelEvent; import org.jboss.netty.channel.ChannelHandler; +import org.jboss.netty.channel.ChannelHandler.Sharable; import org.jboss.netty.channel.ChannelHandlerContext; import org.jboss.netty.channel.ChannelUpstreamHandler; import org.jboss.netty.channel.ExceptionEvent; import org.jboss.netty.channel.MessageEvent; -import org.jboss.netty.channel.ChannelHandler.Sharable; import org.jboss.netty.logging.InternalLogLevel; import org.jboss.netty.logging.InternalLogger; import org.jboss.netty.logging.InternalLoggerFactory; @@ -41,6 +39,66 @@ import org.jboss.netty.logging.InternalLoggerFactory; public class LoggingHandler implements ChannelUpstreamHandler, ChannelDownstreamHandler { private static final InternalLogLevel DEFAULT_LEVEL = InternalLogLevel.DEBUG; + private static final String NEWLINE = String.format("%n"); + + private static final String[] BYTE2HEX = new String[256]; + private static final String[] HEXPADDING = new String[16]; + private static final String[] BYTEPADDING = new String[16]; + private static final char[] BYTE2CHAR = new char[256]; + + static { + int i; + + // Generate the lookup table for byte-to-hex-dump conversion + for (i = 0; i < 10; i ++) { + StringBuilder buf = new StringBuilder(3); + buf.append(" 0"); + buf.append(i); + BYTE2HEX[i] = buf.toString(); + } + for (;i < 16; i ++) { + StringBuilder buf = new StringBuilder(3); + buf.append(" 0"); + buf.append((char) ('a' + i - 10)); + BYTE2HEX[i] = buf.toString(); + } + for (; i < BYTE2HEX.length; i ++) { + StringBuilder buf = new StringBuilder(3); + buf.append(' '); + buf.append(Integer.toHexString(i)); + BYTE2HEX[i] = buf.toString(); + } + + // Generate the lookup table for hex dump paddings + for (i = 0; i < HEXPADDING.length; i ++) { + int padding = HEXPADDING.length - i; + StringBuilder buf = new StringBuilder(padding * 3); + for (int j = 0; j < padding; j ++) { + buf.append(" "); + } + HEXPADDING[i] = buf.toString(); + } + + // Generate the lookup table for byte dump paddings + for (i = 0; i < BYTEPADDING.length; i ++) { + int padding = BYTEPADDING.length - i; + StringBuilder buf = new StringBuilder(padding); + for (int j = 0; j < padding; j ++) { + buf.append(' '); + } + BYTEPADDING[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; + } + } + } + private final InternalLogger logger; private final InternalLogLevel level; @@ -206,8 +264,7 @@ public class LoggingHandler implements ChannelUpstreamHandler, ChannelDownstream if (hexDump && e instanceof MessageEvent) { MessageEvent me = (MessageEvent) e; if (me.getMessage() instanceof ChannelBuffer) { - ChannelBuffer buf = (ChannelBuffer) me.getMessage(); - msg = msg + " - (HEXDUMP: " + hexDump(buf) + ')'; + msg += formatBuffer((ChannelBuffer) me.getMessage()); } } @@ -220,6 +277,56 @@ public class LoggingHandler implements ChannelUpstreamHandler, ChannelDownstream } } + private static String formatBuffer(ChannelBuffer buf) { + int length = buf.readableBytes(); + int rows = length / 16 + (length % 15 == 0? 0 : 1) + 4; + StringBuilder dump = new StringBuilder(rows * 80); + + dump.append( + NEWLINE + " +-------------------------------------------------+" + + NEWLINE + " | 0 1 2 3 4 5 6 7 8 9 a b c d e f |" + + NEWLINE + "+--------+-------------------------------------------------+----------------+"); + + final int startIndex = buf.readerIndex(); + final int endIndex = buf.writerIndex(); + + int i; + for (i = startIndex; i < endIndex; i ++) { + int relIdx = i - startIndex; + int relIdxMod16 = relIdx & 15; + if (relIdxMod16 == 0) { + dump.append(NEWLINE); + dump.append(Long.toHexString(relIdx & 0xFFFFFFFFL | 0x100000000L)); + dump.setCharAt(dump.length() - 9, '|'); + dump.append('|'); + } + dump.append(BYTE2HEX[buf.getUnsignedByte(i)]); + if (relIdxMod16 == 15) { + dump.append(" |"); + for (int j = i - 15; j <= i; j ++) { + dump.append(BYTE2CHAR[buf.getUnsignedByte(j)]); + } + dump.append('|'); + } + } + + if ((i - startIndex & 15) != 0) { + int remainder = length & 15; + dump.append(HEXPADDING[remainder]); + dump.append(" |"); + for (int j = i - remainder; j < i; j ++) { + dump.append(BYTE2CHAR[buf.getUnsignedByte(j)]); + } + dump.append(BYTEPADDING[remainder]); + dump.append('|'); + } + + dump.append( + NEWLINE + "+--------+-------------------------------------------------+----------------+"); + + return dump.toString(); + } + public void handleUpstream(ChannelHandlerContext ctx, ChannelEvent e) throws Exception { log(e);