1 package com.csss.opensource.jhexdump; 2 3 import java.io.*; 4 5 import com.csss.opensource.util.HexUtil; 6 7 /*** 8 * This class provides a reader that will convert an input stream into 9 * hexadecimal output. 10 * 11 * To use the class, instantiate an instance of the class, passing in 12 * the stream which you want to retreive as hexadecimal output, and then 13 * repeatedly invoke readLine() to retrieve the output. 14 * 15 * readLine() will return -1 when the end of the stream has been reached 16 * 17 * I've only tested the reader on InputStream based on either FileInputStream 18 * or... so I'm not sure of the results on input streams that may block. 19 * 20 * @author Lee Walton - <a href="http://www.jzone.co.uk/">The jZone</a> 21 * @version 1.1 22 */ 23 public class JHexDumpReader { 24 25 /*** 26 * The InputStream to process 27 */ 28 private InputStream stream = null; 29 30 /*** 31 * BytesPerRow 32 */ 33 private int bytesPerRow; 34 35 /*** 36 * NoAscii 37 */ 38 private boolean noAscii; 39 40 /*** 41 * NoPosInd 42 */ 43 private boolean noPosInd; 44 45 /*** 46 * The current position within the InputStream 47 */ 48 private long pos = 0; 49 50 /*** 51 * Returns the number of bytes per line. 52 * 53 * @return int 54 */ 55 public int getBytesPerRow() { 56 return bytesPerRow; 57 } 58 59 /*** 60 * Sets the number of bytes per line. 61 * 62 * @param bytesPerRow 63 */ 64 public void setBytesPerRow(int bytesPerRow) { 65 this.bytesPerRow = bytesPerRow; 66 } 67 68 /*** 69 * Returns the value of NoAscii. 70 * <p> 71 * If set to true, the ASCII representation of the data is supressed. 72 * (defaults to false) 73 * 74 * @return boolean 75 */ 76 public boolean isNoAscii() { 77 return noAscii; 78 } 79 80 /*** 81 * Sets the value of NoAscii. 82 * <p> 83 * If set to true, the ASCII representation of the data is supressed. 84 * (defaults to false) 85 * 86 * @param noAscii 87 */ 88 public void setNoAscii(boolean noAscii) { 89 this.noAscii = noAscii; 90 } 91 92 /*** 93 * Returns the value of NoPosInd. 94 * <p> 95 * If set to true, the stream position indicator is supressed. 96 * (defaults to false) 97 * 98 * @return boolean 99 */ 100 public boolean isNoPosInd() { 101 return noPosInd; 102 } 103 104 /*** 105 * Sets the value of NoPosInd. 106 * <p> 107 * If set to true, the stream position indicator is supressed. 108 * (defaults to false) 109 * 110 * @param noPosInd 111 */ 112 public void setNoPosInd(boolean noPosInd) { 113 this.noPosInd = noPosInd; 114 } 115 116 /*** 117 * Constructor. 118 * <p> 119 * Defaults are used for the BytesPerRow, NoAscii, and NoPosInd. 120 * 121 * @param stream The InputStream to process 122 */ 123 public JHexDumpReader( 124 InputStream stream) { 125 this.stream = stream; 126 setBytesPerRow(16); 127 setNoAscii(false); 128 setNoPosInd(false); 129 this.pos = 0; 130 } 131 132 /*** 133 * Constructor. 134 * <p> 135 * Overides the defaults for BytesPerRow, NoAscii, and NoPosInd. 136 * 137 * @param stream The InputStream to process 138 * @param bytesPerRow 139 * @param noAscii 140 * @param noPosInd 141 */ 142 public JHexDumpReader( 143 InputStream stream, 144 int bytesPerRow, 145 boolean noAscii, 146 boolean noPosInd) { 147 this.stream = stream; 148 setBytesPerRow(bytesPerRow); 149 setNoAscii(noAscii); 150 setNoPosInd(noPosInd); 151 this.pos = 0; 152 } 153 154 /*** 155 * Processes a line of data from the InputStream 156 * <p> 157 * The output will include a position indicator at the begining of 158 * the line if NoPosInd is false, and an ASCII representation of 159 * the line if NoAscii is false. 160 * 161 * @param output The StringBuffer to return the output in 162 * @return int The number of bytes read from the input stream 163 * @throws java.io.IOException 164 */ 165 public int readLine(StringBuffer output) throws IOException { 166 167 if (stream == null) 168 throw new IllegalArgumentException(); 169 170 if (output == null) 171 throw new IllegalArgumentException(); 172 173 output.delete(0, output.length()); 174 175 byte buffer[] = new byte[getBytesPerRow()]; 176 String ascii = ""; 177 int bytesRead = -1; 178 179 bytesRead = stream.read(buffer); 180 181 if (bytesRead < 1) 182 return bytesRead; 183 184 if (!isNoPosInd()) 185 output.append(HexUtil.convert(pos, 8) + " : "); 186 187 ascii = ""; 188 189 for (int i = 0; i < bytesRead; i++) { 190 pos++; 191 192 if (buffer[i] >= 32 && buffer[i] <= 254) { 193 ascii = ascii + ((char) buffer[i]); 194 } else { 195 ascii = ascii + "."; 196 } 197 output.append(HexUtil.convert(buffer[i]) + " "); 198 } 199 200 while ((pos % getBytesPerRow()) != 0) { 201 output.append(" "); 202 ascii = ascii + " "; 203 pos++; 204 } 205 206 if (!isNoAscii()) 207 output.append(": " + ascii); 208 209 return bytesRead; 210 } 211 }