blob: 9fce199ad4ac99fff4063d1a114144ca44d191d1 [file] [log] [blame]
// SPDX-License-Identifier: LGPL-2.1-or-later
// Copyright (c) 2012-2014 Monty Program Ab
// Copyright (c) 2015-2021 MariaDB Corporation Ab
package org.mariadb.jdbc.util.log;
/** Logger helper to display network exchange */
public final class LoggerHelper {
private static final char[] hexArray = "0123456789ABCDEF".toCharArray();
/**
* Write bytes/hexadecimal value of a byte array to a StringBuilder.
*
* <p>String output example :
*
* <pre>{@code
* +--------------------------------------------------+
* | 0 1 2 3 4 5 6 7 8 9 a b c d e f |
* +--------------------------------------------------+------------------+
* | 5F 00 00 00 03 73 65 74 20 61 75 74 6F 63 6F 6D | _....set autocom |
* | 6D 69 74 3D 31 2C 20 73 65 73 73 69 6F 6E 5F 74 | mit=1, session_t |
* | 72 61 63 6B 5F 73 63 68 65 6D 61 3D 31 2C 20 73 | rack_schema=1, s |
* | 71 6C 5F 6D 6F 64 65 20 3D 20 63 6F 6E 63 61 74 | ql_mode = concat |
* | 28 40 40 73 71 6C 5F 6D 6F 64 65 2C 27 2C 53 54 | (@@sql_mode,',ST |
* | 52 49 43 54 5F 54 52 41 4E 53 5F 54 41 42 4C 45 | RICT_TRANS_TABLE |
* | 53 27 29 | S') |
* +--------------------------------------------------+------------------+
* }</pre>
*
* @param bytes byte array
* @param offset offset
* @param dataLength byte length to write
* @return formated hexa
*/
public static String hex(byte[] bytes, int offset, int dataLength) {
return hex(bytes, offset, dataLength, Integer.MAX_VALUE);
}
/**
* Transform bytes into readable string format
*
* @param bytes bytes
* @param offset offset
* @param dataLength data length
* @param trunkLength truncation limit
* @return readable string format
*/
public static String hex(byte[] bytes, int offset, int dataLength, int trunkLength) {
if (bytes == null || bytes.length == 0) {
return "";
}
char[] hexaValue = new char[16];
hexaValue[8] = ' ';
int pos = offset;
int line = 1;
int posHexa = 0;
int logLength = Math.min(dataLength, trunkLength);
StringBuilder sb = new StringBuilder(logLength * 3);
sb.append(
" +--------------------------------------------------+\n"
+ " | 0 1 2 3 4 5 6 7 8 9 a b c d e f |\n"
+ "+------+--------------------------------------------------+------------------+\n"
+ "|000000| ");
while (pos < logLength + offset) {
int byteValue = bytes[pos] & 0xFF;
sb.append(hexArray[byteValue >>> 4]).append(hexArray[byteValue & 0x0F]).append(" ");
hexaValue[posHexa++] = (byteValue > 31 && byteValue < 127) ? (char) byteValue : '.';
if (posHexa == 8) {
sb.append(" ");
}
if (posHexa == 16) {
sb.append("| ").append(hexaValue).append(" |\n");
if (pos + 1 != logLength + offset)
sb.append("|").append(mediumIntTohexa(line++)).append("| ");
posHexa = 0;
}
pos++;
}
int remaining = posHexa;
if (remaining > 0) {
if (remaining < 8) {
for (; remaining < 8; remaining++) {
sb.append(" ");
}
sb.append(" ");
}
for (; remaining < 16; remaining++) {
sb.append(" ");
}
for (; posHexa < 16; posHexa++) {
hexaValue[posHexa] = ' ';
}
sb.append("| ").append(hexaValue).append(" |\n");
}
if (dataLength > trunkLength) {
sb.append("+------+-------------------truncated----------------------+------------------+\n");
} else {
sb.append("+------+--------------------------------------------------+------------------+\n");
}
return sb.toString();
}
private static String mediumIntTohexa(int value) {
String st = Integer.toHexString(value * 16);
while (st.length() < 6) st = "0" + st;
return st;
}
/**
* return a string containing hexa displayable value of arrays
*
* @param header header array
* @param bytes data content
* @param offset data offset
* @param dataLength data length
* @param trunkLength data limit
* @return displayable value of arrays
*/
public static String hex(
byte[] header, byte[] bytes, int offset, int dataLength, int trunkLength) {
byte[] complete = new byte[dataLength + header.length];
System.arraycopy(header, 0, complete, 0, header.length);
System.arraycopy(bytes, offset, complete, header.length, dataLength);
return hex(complete, 0, dataLength + header.length, trunkLength);
}
}