All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.neo4j.kernel.impl.util.HexPrinter Maven / Gradle / Ivy

Go to download

ONgDB kernel is a lightweight, embedded Java database designed to store data structured as graphs rather than tables. For more information, see https://graphfoundation.org.

There is a newer version: 3.6.2
Show newest version
/*
 * Copyright (c) 2018-2020 "Graph Foundation,"
 * Graph Foundation, Inc. [https://graphfoundation.org]
 *
 * This file is part of ONgDB.
 *
 * ONgDB is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see .
 */
/*
 * Copyright (c) 2002-2020 "Neo4j,"
 * Neo4j Sweden AB [http://neo4j.com]
 *
 * This file is part of Neo4j.
 *
 * Neo4j is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see .
 */
package org.neo4j.kernel.impl.util;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.ByteBuffer;
import java.nio.channels.ReadableByteChannel;

import static java.nio.ByteBuffer.wrap;

/**
 * Prints streams of bytes as hex, printed in columns and rows neatly ordered. For example:
 *  

* @ 0x000A: FF B9 E2 5B 95 2B 69 21 CF 01 10 89 1E 05 67 51 0C 91 32 20 40 8A 4B 92 01 8C C7 93 F8 66 58 F0 *
* @ 0x000B: 39 C8 F1 2B 84 3B AF 8E C7 50 F7 82 E7 1C DB 20 BF E3 C1 08 68 12 46 72 BA 72 5F 82 13 9A C1 DF *
* @ 0x000C: 56 A6 83 85 36 25 00 DA B4 57 02 FF E6 97 1C 69 F9 16 56 AF 78 C9 0F A4 CD A4 1F A8 08 08 3B 3B *

* where number of bytes per line, number of bytes per group, byte group separator, length of line number, prefix * or suffix of line number can be controlled. If the length of line number is set to a non-positive number, * then no line number, prefix, or suffix will be added. * */ public class HexPrinter { private final PrintStream out; private int bytesPerLine; private int bytesPerGroup; private String byteSeparator; private String groupSeparator; private int maxLineNumberDigits; private String lineNumberPrefix; private String lineNumberSuffix; private long currentLineNumber; private int bytesOnThisLine; private static final int DEFAULT_BYTES_PER_GROUP = 8; private static final int DEFAULT_GROUPS_PER_LINE = 4; private static final int DEFAULT_MAX_LINE_NUMBER_DIGITS = 0; private static final String DEFAULT_GROUP_SEPARATOR = " "; private static final String DEFAULT_LINE_NUMBER_PREFIX = "@ "; private static final String DEFAULT_LINE_NUMBER_SUFFIX = ": "; private static final String DEFAULT_BYTE_SEPARATOR = " "; public HexPrinter withBytesPerLine( int bytesPerLine ) { this.bytesPerLine = bytesPerLine; return this; } public HexPrinter withBytesPerGroup( int bytesPerGroup ) { this.bytesPerGroup = bytesPerGroup; return this; } public HexPrinter withGroupSeparator( String separator ) { this.groupSeparator = separator; return this; } public HexPrinter withLineNumberDigits( int maxLineNumberDigits ) { this.maxLineNumberDigits = maxLineNumberDigits; return this; } public HexPrinter withLineNumberPrefix( String prefix ) { this.lineNumberPrefix = prefix; return this; } public HexPrinter withLineNumberSuffix( String suffix ) { this.lineNumberSuffix = suffix; return this; } public HexPrinter withLineNumberOffset( long offset ) { this.currentLineNumber = offset; return this; } public HexPrinter withByteSeparator( String byteSeparator ) { this.byteSeparator = byteSeparator; return this; } public HexPrinter withBytesGroupingFormat( int bytesPerLine, int bytesPerGroup, String separator ) { this.bytesPerLine = bytesPerLine; this.bytesPerGroup = bytesPerGroup; this.groupSeparator = separator; return this; } public HexPrinter withLineNumberFormat( int maxLineNumberDigits, String prefix, String suffix ) { this.maxLineNumberDigits = maxLineNumberDigits; this.lineNumberPrefix = prefix; this.lineNumberSuffix = suffix; return this; } /** * Using no line number, 8 bytes per group, 32 bytes per line, 4-space separator as default formating to * print bytes as hex. Output looks like: *

* 01 02 03 04 05 06 07 08 01 02 03 04 05 06 07 08 01 02 03 04 05 06 07 08 01 02 03 04 05 06 07 08 *
* 01 02 03 04 05 06 07 08 01 02 03 04 05 06 07 08 01 02 03 04 05 06 07 08 01 02 03 04 05 06 07 08 * * @param out */ public HexPrinter( PrintStream out ) { this( out, DEFAULT_BYTES_PER_GROUP, DEFAULT_GROUP_SEPARATOR ); } public HexPrinter( PrintStream out, int bytesPerGroup, String groupSep ) { this.out = out; this.bytesPerLine = DEFAULT_GROUPS_PER_LINE * bytesPerGroup; this.bytesPerGroup = bytesPerGroup; this.groupSeparator = groupSep; this.maxLineNumberDigits = DEFAULT_MAX_LINE_NUMBER_DIGITS; this.lineNumberPrefix = DEFAULT_LINE_NUMBER_PREFIX; this.lineNumberSuffix = DEFAULT_LINE_NUMBER_SUFFIX; this.byteSeparator = DEFAULT_BYTE_SEPARATOR; } /** * Append one byte into the print stream * @param value * @return */ public HexPrinter append( byte value ) { checkNewLine(); addHexValue( value ); return this; } /** * Append all the bytes in the channel into print stream * @param source * @return * @throws IOException */ public HexPrinter append( ReadableByteChannel source ) throws IOException { return append( source, -1 ); } /** * Append {@code atMost} count of bytes into print stream * @param source * @param atMost * @return * @throws IOException */ public HexPrinter append( ReadableByteChannel source, int atMost ) throws IOException { boolean indefinite = atMost == -1; ByteBuffer buffer = ByteBuffer.allocate( 4 * 1024 ); while ( true ) { buffer.clear(); if ( !indefinite ) { buffer.limit( Math.min( buffer.capacity(), atMost ) ); } int read = source.read( buffer ); if ( read == -1 ) { break; } atMost -= read; buffer.flip(); while ( buffer.hasRemaining() ) { append( buffer.get() ); } } return this; } /** * Append a part of byte buffer into print stream * @param bytes * @param offset * @param length * @return */ public HexPrinter append( ByteBuffer bytes, int offset, int length ) { for ( int i = offset; i < offset + length; i++ ) { append( bytes.get( i ) ); } return this; } /** * Append the bytes in the byte buffer, from its current position to its limit into print stream. This operation * will not move the buffers current position. * @param bytes * @return */ public HexPrinter append( ByteBuffer bytes ) { return append( bytes, bytes.position(), bytes.remaining() ); } /** * Append the whole byte array into print stream * @param bytes * @return */ public HexPrinter append( byte[] bytes ) { return append( wrap( bytes ), 0, bytes.length ); } private void addHexValue( byte value ) { if ( bytesOnThisLine == 1 ) { // it is the first byte // out.append( NOTHING ) } else if ( bytesOnThisLine % bytesPerGroup == 1 ) { // it is the first byte for a new byte group out.append( groupSeparator ); } else { out.append( byteSeparator ); } out.printf( "%X%X", 0xF & (value >> 4), 0xF & value ); } private void checkNewLine() { if ( bytesOnThisLine >= bytesPerLine ) { out.println(); bytesOnThisLine = 0; currentLineNumber++; } if ( bytesOnThisLine == 0 && maxLineNumberDigits > 0 ) { // a new line and line number enabled out.append( lineNumberPrefix ); out.printf( "0x%0" + maxLineNumberDigits + "X", currentLineNumber ); out.append( lineNumberSuffix ); } bytesOnThisLine++; } // Some static methods that could be used directly /** * Convert a subsection of a byte buffer to a human readable string of nicely formatted hex numbers. * Output looks like: * * 01 02 03 04 05 06 07 08 01 02 03 04 05 06 07 08 01 02 03 04 05 06 07 08 01 02 03 04 05 06 07 08 * 01 02 03 04 05 06 07 08 01 02 03 04 05 06 07 08 01 02 03 04 05 06 07 08 01 02 03 04 05 06 07 08 * * @param bytes * @param offset * @param length * @return formatted hex numbers in string */ public static String hex( ByteBuffer bytes, int offset, int length ) { return hex( bytes, offset, length, DEFAULT_BYTES_PER_GROUP, DEFAULT_GROUP_SEPARATOR ); } public static String hex( ByteBuffer bytes, int offset, int length, int bytesPerBlock, String groupSep ) { ByteArrayOutputStream outStream = new ByteArrayOutputStream(); PrintStream out = new PrintStream( outStream ); new HexPrinter( out, bytesPerBlock, groupSep ).append( bytes, offset, length ); out.flush(); return outStream.toString(); } /** * Convert a full byte buffer to a human readable string of nicely formatted hex numbers using default hex format. * Output looks like: * * 01 02 03 04 05 06 07 08 01 02 03 04 05 06 07 08 01 02 03 04 05 06 07 08 01 02 03 04 05 06 07 08 * 01 02 03 04 05 06 07 08 01 02 03 04 05 06 07 08 01 02 03 04 05 06 07 08 01 02 03 04 05 06 07 08 * * @param bytes * @return formatted hex numbers in string */ public static String hex( ByteBuffer bytes ) { return hex( bytes, DEFAULT_BYTES_PER_GROUP, DEFAULT_GROUP_SEPARATOR ); } public static String hex( ByteBuffer bytes, int bytesPerBlock, String groupSep ) { return hex( bytes, bytes.position(), bytes.limit(), bytesPerBlock, groupSep ); } /** * Convert a full byte buffer to a human readable string of nicely formatted hex numbers. * Output looks like: * * 01 02 03 04 05 06 07 08 01 02 03 04 05 06 07 08 01 02 03 04 05 06 07 08 01 02 03 04 05 06 07 08 * 01 02 03 04 05 06 07 08 01 02 03 04 05 06 07 08 01 02 03 04 05 06 07 08 01 02 03 04 05 06 07 08 * * @param bytes * @return formatted hex numbers in string */ public static String hex( byte[] bytes ) { return hex( bytes, DEFAULT_BYTES_PER_GROUP, DEFAULT_GROUP_SEPARATOR ); } public static String hex( byte[] bytes, int bytesPerBlock, String groupSep ) { return hex( wrap( bytes ), bytesPerBlock, groupSep ); } /** * Convert a single byte to a human-readable hex number. The number will always be two characters wide. * @param b * @return formatted hex numbers in string */ public static String hex( byte b ) { return String.format( "%02X", b ); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy