1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 package org.apache.commons.io; 18 19 import java.io.IOException; 20 import java.io.OutputStream; 21 22 /** 23 * Dumps data in hexadecimal format. 24 * <p> 25 * Provides a single function to take an array of bytes and display it 26 * in hexadecimal form. 27 * <p> 28 * Origin of code: POI. 29 * 30 * @author Scott Sanders 31 * @author Marc Johnson 32 * @version $Id: HexDump.java 596667 2007-11-20 13:50:14Z niallp $ 33 */ 34 public class HexDump { 35 36 /** 37 * Instances should NOT be constructed in standard programming. 38 */ HexDump()39 public HexDump() { 40 super(); 41 } 42 43 /** 44 * Dump an array of bytes to an OutputStream. 45 * 46 * @param data the byte array to be dumped 47 * @param offset its offset, whatever that might mean 48 * @param stream the OutputStream to which the data is to be 49 * written 50 * @param index initial index into the byte array 51 * 52 * @throws IOException is thrown if anything goes wrong writing 53 * the data to stream 54 * @throws ArrayIndexOutOfBoundsException if the index is 55 * outside the data array's bounds 56 * @throws IllegalArgumentException if the output stream is null 57 */ 58 dump(byte[] data, long offset, OutputStream stream, int index)59 public static void dump(byte[] data, long offset, 60 OutputStream stream, int index) 61 throws IOException, ArrayIndexOutOfBoundsException, 62 IllegalArgumentException { 63 64 if ((index < 0) || (index >= data.length)) { 65 throw new ArrayIndexOutOfBoundsException( 66 "illegal index: " + index + " into array of length " 67 + data.length); 68 } 69 if (stream == null) { 70 throw new IllegalArgumentException("cannot write to nullstream"); 71 } 72 long display_offset = offset + index; 73 StringBuffer buffer = new StringBuffer(74); 74 75 for (int j = index; j < data.length; j += 16) { 76 int chars_read = data.length - j; 77 78 if (chars_read > 16) { 79 chars_read = 16; 80 } 81 dump(buffer, display_offset).append(' '); 82 for (int k = 0; k < 16; k++) { 83 if (k < chars_read) { 84 dump(buffer, data[k + j]); 85 } else { 86 buffer.append(" "); 87 } 88 buffer.append(' '); 89 } 90 for (int k = 0; k < chars_read; k++) { 91 if ((data[k + j] >= ' ') && (data[k + j] < 127)) { 92 buffer.append((char) data[k + j]); 93 } else { 94 buffer.append('.'); 95 } 96 } 97 buffer.append(EOL); 98 stream.write(buffer.toString().getBytes()); 99 stream.flush(); 100 buffer.setLength(0); 101 display_offset += chars_read; 102 } 103 } 104 105 /** 106 * The line-separator (initializes to "line.separator" system property. 107 */ 108 public static final String EOL = 109 System.getProperty("line.separator"); 110 private static final char[] _hexcodes = 111 { 112 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 113 'A', 'B', 'C', 'D', 'E', 'F' 114 }; 115 private static final int[] _shifts = 116 { 117 28, 24, 20, 16, 12, 8, 4, 0 118 }; 119 120 /** 121 * Dump a long value into a StringBuffer. 122 * 123 * @param _lbuffer the StringBuffer to dump the value in 124 * @param value the long value to be dumped 125 * @return StringBuffer containing the dumped value. 126 */ dump(StringBuffer _lbuffer, long value)127 private static StringBuffer dump(StringBuffer _lbuffer, long value) { 128 for (int j = 0; j < 8; j++) { 129 _lbuffer 130 .append(_hexcodes[((int) (value >> _shifts[j])) & 15]); 131 } 132 return _lbuffer; 133 } 134 135 /** 136 * Dump a byte value into a StringBuffer. 137 * 138 * @param _cbuffer the StringBuffer to dump the value in 139 * @param value the byte value to be dumped 140 * @return StringBuffer containing the dumped value. 141 */ dump(StringBuffer _cbuffer, byte value)142 private static StringBuffer dump(StringBuffer _cbuffer, byte value) { 143 for (int j = 0; j < 2; j++) { 144 _cbuffer.append(_hexcodes[(value >> _shifts[j + 6]) & 15]); 145 } 146 return _cbuffer; 147 } 148 149 } 150