View Javadoc

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 }