1 2 /* ==================================================================== 3 * The Apache Software License, Version 1.1 4 * 5 * Copyright (c) 2002 The Apache Software Foundation. All rights 6 * reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in 17 * the documentation and/or other materials provided with the 18 * distribution. 19 * 20 * 3. The end-user documentation included with the redistribution, 21 * if any, must include the following acknowledgment: 22 * "This product includes software developed by the 23 * Apache Software Foundation (http://www.apache.org/)." 24 * Alternately, this acknowledgment may appear in the software itself, 25 * if and wherever such third-party acknowledgments normally appear. 26 * 27 * 4. The names "Apache" and "Apache Software Foundation" and 28 * "Apache POI" must not be used to endorse or promote products 29 * derived from this software without prior written permission. For 30 * written permission, please contact apache@apache.org. 31 * 32 * 5. Products derived from this software may not be called "Apache", 33 * "Apache POI", nor may "Apache" appear in their name, without 34 * prior written permission of the Apache Software Foundation. 35 * 36 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED 37 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 38 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 39 * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR 40 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 41 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 42 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 43 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 44 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 45 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 46 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 47 * SUCH DAMAGE. 48 * ==================================================================== 49 * 50 * This software consists of voluntary contributions made by many 51 * individuals on behalf of the Apache Software Foundation. For more 52 * information on the Apache Software Foundation, please see 53 * <http://www.apache.org/>. 54 */ 55 56 package org.apache.poi.util; 57 58 import java.io.*; 59 60 /** 61 * dump data in hexadecimal format; derived from a HexDump utility I 62 * wrote in June 2001. 63 * 64 * @author Marc Johnson 65 * @author Glen Stampoultzis (glens at apache.org) 66 */ 67 68 public class HexDump 69 { 70 71 // all static methods, so no need for a public constructor 72 private HexDump() 73 { 74 } 75 76 /** 77 * dump an array of bytes to an OutputStream 78 * 79 * @param data the byte array to be dumped 80 * @param offset its offset, whatever that might mean 81 * @param stream the OutputStream to which the data is to be 82 * written 83 * @param index initial index into the byte array 84 * 85 * @exception IOException is thrown if anything goes wrong writing 86 * the data to stream 87 * @exception ArrayIndexOutOfBoundsException if the index is 88 * outside the data array's bounds 89 * @exception IllegalArgumentException if the output stream is 90 * null 91 */ 92 93 public synchronized static void dump(final byte [] data, final long offset, 94 final OutputStream stream, final int index) 95 throws IOException, ArrayIndexOutOfBoundsException, 96 IllegalArgumentException 97 { 98 if ((index < 0) || (index >= data.length)) 99 { 100 throw new ArrayIndexOutOfBoundsException( 101 "illegal index: " + index + " into array of length " 102 + data.length); 103 } 104 if (stream == null) 105 { 106 throw new IllegalArgumentException("cannot write to nullstream"); 107 } 108 long display_offset = offset + index; 109 StringBuffer buffer = new StringBuffer(74); 110 111 for (int j = index; j < data.length; j += 16) 112 { 113 int chars_read = data.length - j; 114 115 if (chars_read > 16) 116 { 117 chars_read = 16; 118 } 119 buffer.append(dump(display_offset)).append(' '); 120 for (int k = 0; k < 16; k++) 121 { 122 if (k < chars_read) 123 { 124 buffer.append(dump(data[ k + j ])); 125 } 126 else 127 { 128 buffer.append(" "); 129 } 130 buffer.append(' '); 131 } 132 for (int k = 0; k < chars_read; k++) 133 { 134 if ((data[ k + j ] >= ' ') && (data[ k + j ] < 127)) 135 { 136 buffer.append(( char ) data[ k + j ]); 137 } 138 else 139 { 140 buffer.append('.'); 141 } 142 } 143 buffer.append(EOL); 144 stream.write(buffer.toString().getBytes()); 145 stream.flush(); 146 buffer.setLength(0); 147 display_offset += chars_read; 148 } 149 } 150 151 public static final String EOL = 152 System.getProperty("line.separator"); 153 private static final StringBuffer _lbuffer = new StringBuffer(8); 154 private static final StringBuffer _cbuffer = new StringBuffer(2); 155 private static final char _hexcodes[] = 156 { 157 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 158 'E', 'F' 159 }; 160 private static final int _shifts[] = 161 { 162 28, 24, 20, 16, 12, 8, 4, 0 163 }; 164 165 private static StringBuffer dump(final long value) 166 { 167 _lbuffer.setLength(0); 168 for (int j = 0; j < 8; j++) 169 { 170 _lbuffer 171 .append(_hexcodes[ (( int ) (value >> _shifts[ j ])) & 15 ]); 172 } 173 return _lbuffer; 174 } 175 176 private static StringBuffer dump(final byte value) 177 { 178 _cbuffer.setLength(0); 179 for (int j = 0; j < 2; j++) 180 { 181 _cbuffer.append(_hexcodes[ (value >> _shifts[ j + 6 ]) & 15 ]); 182 } 183 return _cbuffer; 184 } 185 186 /** 187 * Converts the parameter to a hex value. 188 * 189 * @param value The value to convert 190 * @return A String representing the array of bytes 191 */ 192 public static String toHex(final byte[] value) 193 { 194 StringBuffer retVal = new StringBuffer(); 195 retVal.append('['); 196 for(int x = 0; x < value.length; x++) 197 { 198 retVal.append(toHex(value[x])); 199 retVal.append(", "); 200 } 201 retVal.append(']'); 202 return retVal.toString(); 203 } 204 /** 205 * Converts the parameter to a hex value. 206 * 207 * @param value The value to convert 208 * @return The result right padded with 0 209 */ 210 public static String toHex(final short value) 211 { 212 return toHex(value, 4); 213 } 214 215 /** 216 * Converts the parameter to a hex value. 217 * 218 * @param value The value to convert 219 * @return The result right padded with 0 220 */ 221 public static String toHex(final byte value) 222 { 223 return toHex(value, 2); 224 } 225 226 /** 227 * Converts the parameter to a hex value. 228 * 229 * @param value The value to convert 230 * @return The result right padded with 0 231 */ 232 public static String toHex(final int value) 233 { 234 return toHex(value, 8); 235 } 236 237 238 private static String toHex(final long value, final int digits) 239 { 240 StringBuffer result = new StringBuffer(digits); 241 for (int j = 0; j < digits; j++) 242 { 243 result.append( _hexcodes[ (int) ((value >> _shifts[ j + (8 - digits) ]) & 15)]); 244 } 245 return result.toString(); 246 } 247 } 248