| // 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); |
| } |
| } |