123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303 |
- /* ====================================================================
- 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.poi.util;
-
- import java.io.IOException;
- import java.io.OutputStream;
- import java.io.OutputStreamWriter;
- import java.nio.charset.Charset;
- import java.nio.charset.StandardCharsets;
-
- /**
- * dump data in hexadecimal format
- */
- @Internal
- public final class HexDump {
- public static final String EOL = System.getProperty("line.separator");
- public static final Charset UTF8 = StandardCharsets.UTF_8;
-
- private HexDump() {
- // all static methods, so no need for a public constructor
- }
-
- /**
- * dump an array of bytes to an OutputStream
- *
- * @param data the byte array to be dumped
- * @param offset its offset, whatever that might mean
- * @param stream the OutputStream to which the data is to be
- * written
- * @param index initial index into the byte array
- * @param length number of characters to output
- *
- * @throws IOException is thrown if anything goes wrong writing
- * the data to stream
- * @throws ArrayIndexOutOfBoundsException if the index is
- * outside the data array's bounds
- * @throws IllegalArgumentException if the output stream is
- * null
- */
- public static void dump(final byte [] data, final long offset,
- final OutputStream stream, final int index, final int length)
- throws IOException, ArrayIndexOutOfBoundsException, IllegalArgumentException {
- if (stream == null) {
- throw new IllegalArgumentException("cannot write to nullstream");
- }
-
- OutputStreamWriter osw = new OutputStreamWriter(stream, UTF8);
- osw.write(dump(data, offset, index, length));
- osw.flush();
- }
-
- /**
- * dump an array of bytes to an OutputStream
- *
- * @param data the byte array to be dumped
- * @param offset its offset, whatever that might mean
- * @param stream the OutputStream to which the data is to be
- * written
- * @param index initial index into the byte array
- *
- * @throws IOException is thrown if anything goes wrong writing
- * the data to stream
- * @throws ArrayIndexOutOfBoundsException if the index is
- * outside the data array's bounds
- * @throws IllegalArgumentException if the output stream is
- * null
- */
-
- public synchronized static void dump(final byte [] data, final long offset,
- final OutputStream stream, final int index)
- throws IOException, ArrayIndexOutOfBoundsException, IllegalArgumentException {
- dump(data, offset, stream, index, Integer.MAX_VALUE);
- }
-
- /**
- * dump an array of bytes to a String
- *
- * @param data the byte array to be dumped
- * @param offset its offset, whatever that might mean
- * @param index initial index into the byte array
- *
- * @throws ArrayIndexOutOfBoundsException if the index is
- * outside the data array's bounds
- * @return output string
- */
-
- public static String dump(final byte [] data, final long offset, final int index) {
- return dump(data, offset, index, Integer.MAX_VALUE);
- }
-
- /**
- * dump an array of bytes to a String
- *
- * @param data the byte array to be dumped
- * @param offset its offset, whatever that might mean
- * @param index initial index into the byte array
- * @param length number of characters to output
- *
- * @throws ArrayIndexOutOfBoundsException if the index is
- * outside the data array's bounds
- * @return output string
- */
-
- public static String dump(final byte [] data, final long offset, final int index, final int length) {
- if (data == null || data.length == 0) {
- return "No Data"+EOL;
- }
-
- int data_length = (length == Integer.MAX_VALUE || length < 0 || index+length < 0)
- ? data.length
- : Math.min(data.length,index+length);
-
-
- if ((index < 0) || (index >= data.length)) {
- String err = "illegal index: "+index+" into array of length "+data.length;
- throw new ArrayIndexOutOfBoundsException(err);
- }
-
- long display_offset = offset + index;
- StringBuilder buffer = new StringBuilder(74);
-
- for (int j = index; j < data_length; j += 16) {
- int chars_read = data_length - j;
-
- if (chars_read > 16) {
- chars_read = 16;
- }
-
- writeHex(buffer, display_offset, 8, "");
- for (int k = 0; k < 16; k++) {
- if (k < chars_read) {
- writeHex(buffer, data[ k + j ], 2, " ");
- } else {
- buffer.append(" ");
- }
- }
- buffer.append(' ');
- for (int k = 0; k < chars_read; k++) {
- buffer.append(toAscii(data[ k + j ]));
- }
- buffer.append(EOL);
- display_offset += chars_read;
- }
- return buffer.toString();
- }
-
- public static char toAscii(int dataB) {
- char charB = (char)(dataB & 0xFF);
- if (Character.isISOControl(charB)) {
- return '.';
- }
-
- switch (charB) {
- // printable, but not compilable with current compiler encoding
- case 0xFF:
- case 0xDD:
- charB = '.';
- break;
- default:
- break;
- }
- return charB;
- }
-
- /**
- * Converts the parameter to a hex value.
- *
- * @param value The value to convert
- * @return A String representing the array of bytes
- */
- public static String toHex(final byte[] value)
- {
- StringBuilder retVal = new StringBuilder();
- retVal.append('[');
- if (value != null && value.length > 0)
- {
- for(int x = 0; x < value.length; x++)
- {
- if (x>0) {
- retVal.append(", ");
- }
- retVal.append(toHex(value[x]));
- }
- }
- retVal.append(']');
- return retVal.toString();
- }
-
- /**
- * Converts the parameter to a hex value.
- *
- * @param value The value to convert
- * @return The result right padded with 0
- */
- public static String toHex(short value) {
- StringBuilder sb = new StringBuilder(4);
- writeHex(sb, value & 0xFFFF, 4, "");
- return sb.toString();
- }
-
- /**
- * Converts the parameter to a hex value.
- *
- * @param value The value to convert
- * @return The result right padded with 0
- */
- public static String toHex(byte value) {
- StringBuilder sb = new StringBuilder(2);
- writeHex(sb, value & 0xFF, 2, "");
- return sb.toString();
- }
-
- /**
- * Converts the parameter to a hex value.
- *
- * @param value The value to convert
- * @return The result right padded with 0
- */
- public static String toHex(int value) {
- StringBuilder sb = new StringBuilder(8);
- writeHex(sb, value & 0xFFFFFFFFL, 8, "");
- return sb.toString();
- }
-
- /**
- * Converts the parameter to a hex value.
- *
- * @param value The value to convert
- * @return The result right padded with 0
- */
- public static String toHex(long value) {
- StringBuilder sb = new StringBuilder(16);
- writeHex(sb, value, 16, "");
- return sb.toString();
- }
-
- /**
- * @return string of 16 (zero padded) uppercase hex chars and prefixed with '0x'
- */
- public static String longToHex(long value) {
- StringBuilder sb = new StringBuilder(18);
- writeHex(sb, value, 16, "0x");
- return sb.toString();
- }
-
- /**
- * @return string of 8 (zero padded) uppercase hex chars and prefixed with '0x'
- */
- public static String intToHex(int value) {
- StringBuilder sb = new StringBuilder(10);
- writeHex(sb, value & 0xFFFFFFFFL, 8, "0x");
- return sb.toString();
- }
-
- /**
- * @return string of 4 (zero padded) uppercase hex chars and prefixed with '0x'
- */
- public static String shortToHex(int value) {
- StringBuilder sb = new StringBuilder(6);
- writeHex(sb, value & 0xFFFFL, 4, "0x");
- return sb.toString();
- }
-
- /**
- * @return string of 2 (zero padded) uppercase hex chars and prefixed with '0x'
- */
- public static String byteToHex(int value) {
- StringBuilder sb = new StringBuilder(4);
- writeHex(sb, value & 0xFFL, 2, "0x");
- return sb.toString();
- }
-
- /**
- * @see Integer#toHexString(int)
- * @see Long#toHexString(long)
- */
- private static void writeHex(StringBuilder sb, long value, int nDigits, String prefix) {
- sb.append(prefix);
- char[] buf = new char[nDigits];
- long acc = value;
- for(int i=nDigits-1; i>=0; i--) {
- int digit = Math.toIntExact(acc & 0x0F);
- buf[i] = (char) (digit < 10 ? ('0' + digit) : ('A' + digit - 10));
- acc >>>= 4;
- }
- sb.append(buf);
- }
- }
|