//==============================================================================
// HexDump.java
//------------------------------------------------------------------------------
package tribble.util;
// System imports
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.InputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.lang.NullPointerException;
import java.lang.String;
import java.lang.System;
// Local imports
// (None)
/*******************************************************************************
* Hexadecimal dump utility methods.
*
* @version $Revision: 1.4 $ $Date: 2003/02/18 00:33:11 $
* @since 2000-02-08
* @author
* David R. Tribble,
* david@tribble.com.
*
* Copyright ©2000-2003 by David R. Tribble, all rights reserved.
*
* Permission is granted to freely use and distribute this source code
* provided that the original copyright and authorship notices remain
* intact.
*
* @see HexDumper
*/
public abstract class HexDump
{
// Identification
/** Class version number. */
public static final int VERS = 100;
/** Revision info. */
static final String REV =
"@(#)tribble/util/HexDump.java $Revision: 1.4 $ $Date: 2003/02/18 00:33:11 $\n";
/** Copyright info. */
static final String COPYRIGHT =
"Copyright ©2000-2003 by David R. Tribble, all rights reserved.";
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Constants
// (None)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Static class initializers
/*+++TEST CODE, NO LONGER USED
// Test vectors for hexDumpString()
static
{
String s;
hexDump(System.out,
"Hello, world\n................................."
+ "xxxxx\0xxx\u202Bxx\uFFFFxxxx/"
+ "4%%%%\t%%%%%%%%%%4%%%%%%%%%%%%%%%%4%%%%%%%%%%%%4%%%%%%%%%%%%4[]"
+ "5%%%%%%%%%%%%%%%5%%%%%%%%%%%%%%%%5%%%%%%%%%%%%5%%%%%%%%%%%%5[]"
+ "6%%%%%%%%%%%%%%%6%%%%%%%%%%%%%%%%6%%%%%%%%%%%%6%%%%%%%%%%%%6[]");
System.out.println();
hexDump(System.out, "Hello, world\n");
System.out.println();
hexDump(System.out, "abuuuuuuuukkkkkkkkk");
System.out.println();
hexDump(System.out, "abuuuuuuuukkkkkkkkkk");
System.out.println();
hexDump(System.out, "abuuuuuuuukkkkkkkkkkx");
System.out.println();
s = "abuuuuuuuukkkkkkkkkkx";
hexDump(System.out, s, 0, 0);
System.out.println();
hexDump(System.out, s, 0, 4);
System.out.println();
hexDump(System.out, s, 0, s.length()+100);
System.out.println();
hexDump(System.out, s, 1, s.length());
System.out.println();
hexDump(System.out, s, 100, 4);
System.out.println();
}
+++*/
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Public static methods
/***************************************************************************
* Print the contents of a byte array as a hexadecimal dump to an output
* stream.
*
*
* This method is equivalent to: *
* hexDump(out, data, 0, data.length);* * @param out * An output stream. * * @param data * An array of bytes to dump to out. * * @since 1.3, 2003-02-15 */ public static void hexDump(PrintWriter out, byte[] data) { // Dump the characters in 'data' hexDump(out, data, 0, data.length); } /*************************************************************************** * Print the contents of a byte array as a hexadecimal dump to an output * stream. * * @param out * An output stream. * * @param data * An array of bytes to dump to out. * * @param off * The index of the first byte within the byte array to dump. * * @param len * The number of bytes within the byte array to dump. * * @since 1.3, 2003-02-15 */ public static void hexDump(PrintWriter out, byte[] data, int off, int len) { // Check args if (out == null) return; if (data == null) { out.println("Null"); return; } // Dump the bytes in 'data' hexDumpAt(out, data, off, len, 0); out.flush(); } /*************************************************************************** * Print the contents of a byte array as a hexadecimal dump to an output * stream. * *
* This method is equivalent to: *
* hexDump(out, data, 0, data.length);* * @param out * An output stream. * * @param data * An array of bytes to dump to out. * * @since 1.3, 2003-02-15 */ public static void hexDump(PrintStream out, byte[] data) { // Dump the bytes in 'data' hexDump(new PrintWriter(out, false), data, 0, data.length); } /*************************************************************************** * Print the contents of a byte array as a hexadecimal dump to an output * stream. * * @param out * An output stream. * * @param data * An array of bytes to dump to out. * * @param off * The index of the first byte within the byte array to dump. * * @param len * The number of bytes within the byte array to dump. * * @since 1.3, 2003-02-15 */ public static void hexDump(PrintStream out, byte[] data, int off, int len) { // Dump the bytes in 'data' hexDump(new PrintWriter(out, false), data, off, len); } /*************************************************************************** * Print the contents of a string as a hexadecimal dump to an output stream. * *
* This method is equivalent to: *
* hexDump(out, s, 0, s.length());* * @param out * An output stream. * * @param s * A string of Unicode characters to dump to out. * * @since 1.3, 2003-02-15 */ public static void hexDump(PrintWriter out, String s) { // Dump the characters in 's' hexDump(out, s, 0, s.length()); } /*************************************************************************** * Print the contents of a string as a hexadecimal dump to an output stream. * * @param out * An output stream. * * @param off * The index of the first character within the string to dump. * * @param len * The number of bytes within the byte array to dump. * * @param s * A string of Unicode characters to dump to out. * * @since 1.3, 2003-02-15 */ public static void hexDump(PrintWriter out, String s, int off, int len) { // Check args if (out == null) return; if (s == null) { out.println("Null"); return; } // Dump the characters in 's' hexDumpStringAt(out, s, off, len, 0); out.flush(); } /*************************************************************************** * Print the contents of a string as a hexadecimal dump to an output stream. * *
* This method is equivalent to: *
* hexDump(out, s, 0, s.length());* * @param out * An output stream. * * @param s * A string of Unicode characters to dump to out. * * @since 1.3, 2003-02-15 */ public static void hexDump(PrintStream out, String s) { // Dump the characters in 's' hexDump(new PrintWriter(out, false), s, 0, s.length()); } /*************************************************************************** * Print the contents of a string as a hexadecimal dump to an output stream. * * @param out * An output stream. * * @param off * The index of the first character within the string to dump. * * @param len * The number of bytes within the byte array to dump. * * @param s * A string of Unicode characters to dump to out. * * @since 1.3, 2003-02-15 */ public static void hexDump(PrintStream out, String s, int off, int len) { hexDump(new PrintWriter(out, false), s, off, len); } /*************************************************************************** * Print the contents of an input stream as a hexadecimal dump to an output * stream. * *
* Note that any {@link java.io.IOException}s thrown while reading from the * input stream or writing to the output stream are ignored. * * @param in * An input (byte) stream. * Note that this stream is not closed after reading its contents. * * @param out * An output stream. * * @since 1.3, 2003-02-15 */ public static void hexDump(InputStream in, PrintWriter out) { // Check args if (out == null) return; if (in == null) throw new NullPointerException("Null input stream"); // Read and dump the contents of the input stream try { byte[] data; // Input data block int off; // Leftover data bytes int addr; // Data address // Read and dump the contents of the input stream data = new byte[64*1024]; off = 0; addr = 0; for (;;) { int len; int dlen; // Read a block of data from the file len = in.read(data, off, data.length - off); if (len <= 0) len = 0; // Dump the data block in hexadecimal dlen = (off+len) & ~0x0000000F; // = (off+len)/16 * 16 hexDumpAt(out, data, 0, dlen, addr); addr += dlen; // Save any leftover bytes for the next iteration off = off+len - dlen; if (off > 0) System.arraycopy(data, dlen, data, 0, off); // Check for end of file if (len == 0) { // End of file reached, dump the last remaining data bytes hexDumpAt(out, data, 0, off, addr); addr += off; // Stop reading and dumping break; } } out.flush(); } catch (IOException ex) { // Ignore } } /*************************************************************************** * Print the contents of an input stream as a hexadecimal dump to an output * stream. * *
* Note that any {@link java.io.IOException}s thrown while reading from the * input stream or writing to the output stream are ignored. * * @param in * An input (byte) stream. * Note that this stream is not closed after reading its contents. * * @param out * An output stream. * * @since 1.3, 2003-02-15 */ public static void hexDump(InputStream in, PrintStream out) { hexDump(in, new PrintWriter(out, false)); } /*************************************************************************** * Print the contents of a byte array as a hexadecimal dump to an output * stream. * * @param out * An output stream. * * @param data * An array of bytes to dump to out. * * @param off * The index of the first byte within the byte array to dump. * * @param len * The number of bytes within the byte array to dump * * @param base * The base address to assume in the printed dump. * * @since 1.4, 2003-02-17 (2003-02-15) */ public static void hexDumpAt(PrintWriter out, byte[] data, int off, int len, int base) { int loc; int end; // Print a hexadecimal dump of 'data[off...off+len-1]' if (off >= data.length) off = data.length; end = off+len; if (end >= data.length) end = data.length; len = end-off; if (len <= 0) return; loc = (off/0x10)*0x10; for (int i = loc; i < end; i += 0x10, loc += 0x10) { int j; // Print the location/offset { int v; v = base+loc; for (j = (8-1)*4; j >= 0; j -= 4) { int d; d = (v >>> j) & 0x0F; d = (d < 0xA ? d+'0' : d-0xA+'A'); out.print((char) d); } } // Print a row of hex bytes out.print(" "); for (j = 0x00; i+j < off; j++) out.print(".. "); for ( ; j < 0x10 && i+j < end; j++) { int ch; int d; if (j == 0x08) out.print(' '); ch = data[i+j] & 0xFF; d = (ch >>> 4); d = (d < 0xA ? d+'0' : d-0xA+'A'); out.print((char) d); d = (ch & 0x0F); d = (d < 0xA ? d+'0' : d-0xA+'A'); out.print((char) d); out.print(' '); } for ( ; j < 0x10; j++) { if (j == 0x08) out.print(' '); out.print(".. "); } // Print a row of printable characters out.print(" |"); for (j = 0x00; i+j < off; j++) out.print(' '); for ( ; j < 0x10 && i+j < end; j++) { int ch; ch = data[i+j] & 0xFF; if (ch < 0x20 || ch >= 0x7F && ch < 0xA0 || ch > 0xFF) { // The character is unprintable ch = '.'; } out.print((char) ch); } for ( ; j < 0x10; j++) out.print(' '); out.println("|"); } } /*************************************************************************** * Print the contents of a string as a hexadecimal dump to an output stream. * * @param out * An output stream. * * @param data * A string of Unicode characters to dump to out. * * @param off * The index of the first byte within the byte array to dump. * * @param len * The number of bytes within the byte array to dump * * @param base * The base address to assume in the printed dump. * * @since 1.4, 2003-02-17 (2003-02-15) */ public static void hexDumpStringAt(PrintWriter out, String data, int off, int len, int base) { int loc; int end; char[] h; // Print a hexadecimal dump of 'data[off...off+len-1]' if (off >= data.length()) off = data.length(); end = off+len; if (end >= data.length()) end = data.length(); len = end-off; if (len <= 0) return; loc = (off/0x10)*0x10; h = new char[10]; for (int i = loc; i < end; i += 10, loc += 10) { int j; // Print the location/offset { int v; v = base+loc; for (j = 1; j <= 10; j++) { int d; d = (v % 10) + '0'; v = (v / 10); h[10-j] = (char) d; } // Print the location/offset as a 4-10 digit decimal number for (j = 0; j < 10-1; j++) { if (h[j] == '0') h[j] = ' '; else break; } for (j = 0; j < 6; j++) if (h[j] != ' ') break; for ( ; j < 10; j++) out.print(h[j]); } // Print a row of hex bytes out.print(": "); for (j = 0; i+j < off; j++) out.print(".... "); for ( ; j < 10 && i+j < end; j++) { int ch; int d; ch = (int) data.charAt(i+j); d = (ch >>> 12) & 0x0F; d = (d < 0xA ? d+'0' : d-0xA+'A'); out.print((char) d); d = (ch >>> 8) & 0x0F; d = (d < 0xA ? d+'0' : d-0xA+'A'); out.print((char) d); d = (ch >>> 4) & 0x0F; d = (d < 0xA ? d+'0' : d-0xA+'A'); out.print((char) d); d = (ch & 0x0F); d = (d < 0xA ? d+'0' : d-0xA+'A'); out.print((char) d); out.print(' '); } for ( ; j < 10; j++) out.print(".... "); // Print a row of printable characters out.print('|'); for (j = 0; i+j < off; j++) out.print(' '); for ( ; j < 10 && i+j < end; j++) { int ch; ch = (int) data.charAt(i+j); if (ch < 0x0020 || ch >= 0x007F && ch < 0x00A0 || ch > 0x00FF) { // Assume that the character is unprintable ch = '.'; } out.print((char) ch); } for ( ; j < 10; j++) out.print(' '); out.println("|"); } } /*************************************************************************** * Print the contents of one or more files as a hexadecimal dump to the * standard output stream. * * *
* Usage *
* java tribble.util.HexDump file...* * @param args * Command line arguments (filenames to dump). * * @since 1.1, 2000-02-08 */ public static void main(String[] args) { PrintWriter out; // Check args if (args.length < 1) { // Display a usage message System.out.println("Dump the contents of one or more files in " + "hexadecimal."); System.out.println(); System.out.println("usage: java " + HexDump.class.getName() + " file..."); System.out.println(); System.out.println("A filename of \"-\" indicates input is to be " + "read from the standard input."); // Punt System.exit(255); } // Set up out = new PrintWriter(System.out, true); // Dump the contents of the filename args for (int i = 0; i < args.length; i++) { String fname; InputStream in = null; // Open the next filename fname = args[i]; try { // Open the next filename if (fname.equals("-")) { // Read input from standard input in = System.in; } else { // Read input from a named file in = new FileInputStream(new File(fname)); } // Dump the contents of the file if (i > 0) out.println(); out.print(fname); out.println(":"); hexDump(in, out); } catch (FileNotFoundException ex) { // Can't open/read the file System.out.println("Can't open/read file: " + fname + ": " + ex.getMessage()); } catch (IOException ex) { // Can't open/read the file System.out.println("I/O error for: " + fname + ": " + ex.getMessage()); } try { // Clean up out.flush(); if (in != null && in != System.in) in.close(); } catch (IOException ex) { // Ignore } } } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // Variables // (None) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // Constructors /*************************************************************************** * Default constructor. * * @since 1.1, 2000-02-08 */ private HexDump() { // Do nothing } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // Methods // (None) } // End HexDump.java