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 }