blob: b56e01365fe17196bee998db9f4ae3484df246a8 [file] [log] [blame]
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF 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
*
* 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.
*/
package org.apache.mina.util;
import java.nio.ByteBuffer;
/**
* Utility class for smart dumping {@link ByteBuffer}
*
* @author <a href="http://mina.apache.org">Apache MINA Project</a>
*/
public class ByteBufferDumper {
/** Hex chars */
private static final byte[] HEX_CHAR = new byte[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B',
'C', 'D', 'E', 'F' };
/**
* Dump the content of the given ByteBuffer, up to a number of bytes. If the toAscii flag is set to
* <code>true</code>, this method will try to convert the bytes to a String
*
* @param buffer The buffer to dump
* @param nbBytes The number of bytes to dump (-1 for all of them)
* @param toAscii If we want to write the message as a String
* @return A dump of this ByteBuffer
*/
public static String dump(ByteBuffer buffer, int nbBytes, boolean toAscii) {
byte data[];
int start;
int size = Math.min(buffer.remaining(), nbBytes >= 0 ? nbBytes : Integer.MAX_VALUE);
int length = buffer.remaining();
if (buffer.hasArray() && !buffer.isReadOnly()) {
start = buffer.position();
data = buffer.array();
} else {
data = new byte[size];
int oldpos = buffer.position();
buffer.get(data);
buffer.position(oldpos);
start = 0;
length = data.length;
}
// is not ASCII printable ?
boolean binaryContent = false;
if (toAscii) {
for (int i = start; i < start + size; i++) {
byte b = data[i];
if (((b < 32) || (b > 126)) && (b != 13) && (b != 10)) {
binaryContent = true;
break;
}
}
}
if (!toAscii || binaryContent) {
StringBuilder out = new StringBuilder(size * 3 + 30);
out.append("ByteBuffer[len=").append(length).append(",bytes='");
// fill the first
int byteValue = data[start] & 0xFF;
boolean isFirst = true;
// and the others, too
for (int i = start; i < start + size; i++) {
if (isFirst) {
isFirst = false;
} else {
out.append(' ');
}
byteValue = data[i] & 0xFF;
out.append(new String(new byte[] { '0', 'x', HEX_CHAR[(byteValue & 0x00F0) >> 4],
HEX_CHAR[byteValue & 0x000F] }));
}
out.append("']");
return out.toString();
} else {
StringBuilder sb = new StringBuilder(size);
sb.append("ByteBuffer[len=").append(length).append(",str='").append(new String(data, start, size))
.append("']");
return sb.toString();
}
}
/**
* Dumps the given buffer. If the buffer contains only ascii, it will write the buffer content as a String.
*
* @param buffer The buffer to dump
* @return A string representing the buffer content
*/
public static String dump(ByteBuffer buffer) {
return dump(buffer, -1, true);
}
/**
* Dump a byte buffer remaining bytes as a hex-decimal string. The current buffer position will remain unchanged.
*
* @param buffer the buffer to dump
* @return a hex string
*/
public static String toHex(ByteBuffer buffer) {
StringBuilder out = new StringBuilder(buffer.remaining() * 2);
int pos = buffer.position();
while (buffer.hasRemaining()) {
int byteValue = buffer.get() & 0xFF;
out.append((char) (HEX_CHAR[(byteValue & 0x00F0) >> 4]))
.append((char) ((HEX_CHAR[byteValue & 0x000F]) - 0));
}
buffer.position(pos);
return out.toString();
}
public static ByteBuffer fromHexString(String hex) {
if (hex.length() % 2 != 0) {
throw new IllegalArgumentException("the hexa-decimal string length cannot be odd");
}
int size = hex.length() / 2;
ByteBuffer res = ByteBuffer.allocate(size);
for (int i = 0; i < size; i++) {
int b = Integer.parseInt(hex.substring(i*2, i*2 + 2), 16);
if (Integer.highestOneBit(b) == 128) {
b = b - 256;
}
res.put((byte) b);
}
res.flip();
return res;
}
}