KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > tapestry > util > io > BinaryDumpOutputStream


1 // Copyright 2004, 2005 The Apache Software Foundation
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
// http://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14

15 package org.apache.tapestry.util.io;
16
17 import java.io.IOException JavaDoc;
18 import java.io.OutputStream JavaDoc;
19 import java.io.PrintWriter JavaDoc;
20 import java.io.Writer JavaDoc;
21
22 /**
23  * A kind of super-formatter. It is sent a stream of binary data and
24  * formats it in a human-readable dump format which is forwarded to
25  * its output stream.
26  *
27  * <p>Currently, output is in hex though options to change that may
28  * be introduced.
29  *
30  * @author Howard Lewis Ship
31  *
32  **/

33
34 public class BinaryDumpOutputStream extends OutputStream JavaDoc
35 {
36     private PrintWriter JavaDoc out;
37
38     private boolean locked = false;
39
40     private boolean showOffset = true;
41     private int bytesPerLine = 16;
42     private int spacingInterval = 4;
43     private char substituteChar = '.';
44     private String JavaDoc offsetSeperator = ": ";
45     private int offset = 0;
46     private int lineCount = 0;
47     private int bytesSinceSpace = 0;
48     private char[] ascii = null;
49     private boolean showAscii = true;
50     private String JavaDoc asciiBegin = " |";
51     private String JavaDoc asciiEnd = "|";
52
53     private static final char[] HEX =
54         {
55             '0',
56             '1',
57             '2',
58             '3',
59             '4',
60             '5',
61             '6',
62             '7',
63             '8',
64             '9',
65             'a',
66             'b',
67             'c',
68             'd',
69             'e',
70             'f' };
71
72     /**
73      * Creates a <code>PrintWriter</code> for <code>System.out</code>.
74      *
75      **/

76
77     public BinaryDumpOutputStream()
78     {
79         this(new PrintWriter JavaDoc(System.out, true));
80     }
81
82     public BinaryDumpOutputStream(PrintWriter JavaDoc out)
83     {
84         this.out = out;
85     }
86
87     public BinaryDumpOutputStream(Writer JavaDoc out)
88     {
89         this.out = new PrintWriter JavaDoc(out);
90     }
91
92     public void close() throws IOException JavaDoc
93     {
94         if (out != null)
95         {
96             if (lineCount > 0)
97                 finishFinalLine();
98
99             out.close();
100         }
101
102         out = null;
103     }
104
105     private void finishFinalLine()
106     {
107         // Since we only finish the final line after at least one byte has
108
// been written to it, we don't need to worry about
109
// the offset.
110

111         while (lineCount < bytesPerLine)
112         {
113             // After every <n> bytes, emit a space.
114

115             if (spacingInterval > 0 && bytesSinceSpace == spacingInterval)
116             {
117                 out.print(' ');
118                 bytesSinceSpace = 0;
119             }
120
121             // Two spaces to substitute for the two hex digits.
122

123             out.print(" ");
124
125             if (showAscii)
126                 ascii[lineCount] = ' ';
127
128             lineCount++;
129             bytesSinceSpace++;
130         }
131
132         if (showAscii)
133         {
134             out.print(asciiBegin);
135             out.print(ascii);
136             out.print(asciiEnd);
137         }
138
139         out.println();
140     }
141
142     /**
143      * Forwards the <code>flush()</code> to the <code>PrintWriter</code>.
144      *
145      **/

146
147     public void flush() throws IOException JavaDoc
148     {
149         out.flush();
150     }
151
152     public String JavaDoc getAsciiBegin()
153     {
154         return asciiBegin;
155     }
156
157     public String JavaDoc getAsciiEnd()
158     {
159         return asciiEnd;
160     }
161
162     public int getBytesPerLine()
163     {
164         return bytesPerLine;
165     }
166
167     public String JavaDoc getOffsetSeperator()
168     {
169         return offsetSeperator;
170     }
171
172     public boolean getShowAscii()
173     {
174         return showAscii;
175     }
176
177     public char getSubstituteChar()
178     {
179         return substituteChar;
180     }
181
182     public void setAsciiBegin(String JavaDoc value)
183     {
184         if (locked)
185             throw new IllegalStateException JavaDoc();
186
187         asciiBegin = value;
188     }
189
190     public void setAsciiEnd(String JavaDoc value)
191     {
192         if (locked)
193             throw new IllegalStateException JavaDoc();
194
195         asciiEnd = value;
196     }
197
198     public void setBytesPerLine(int value)
199     {
200         if (locked)
201             throw new IllegalStateException JavaDoc();
202
203         bytesPerLine = value;
204
205         ascii = null;
206     }
207
208     public void setOffsetSeperator(String JavaDoc value)
209     {
210         if (locked)
211             throw new IllegalStateException JavaDoc();
212
213         offsetSeperator = value;
214     }
215
216     public void setShowAscii(boolean value)
217     {
218         if (locked)
219             throw new IllegalStateException JavaDoc();
220
221         showAscii = value;
222     }
223
224     /**
225      * Sets the character used in the ASCII dump that substitutes for characters
226      * outside the range of 32..126.
227      *
228      **/

229
230     public void setSubstituteChar(char value)
231     {
232         if (locked)
233             throw new IllegalStateException JavaDoc();
234
235         substituteChar = value;
236     }
237
238     public void write(int b) throws IOException JavaDoc
239     {
240         char letter;
241
242         if (showAscii && ascii == null)
243             ascii = new char[bytesPerLine];
244
245         // Prevent further customization after output starts being written.
246

247         locked = true;
248
249         if (lineCount == bytesPerLine)
250         {
251             if (showAscii)
252             {
253                 out.print(asciiBegin);
254                 out.print(ascii);
255                 out.print(asciiEnd);
256             }
257
258             out.println();
259
260             bytesSinceSpace = 0;
261             lineCount = 0;
262             offset += bytesPerLine;
263         }
264
265         if (lineCount == 0 && showOffset)
266         {
267             writeHex(offset, 4);
268             out.print(offsetSeperator);
269         }
270
271         // After every <n> bytes, emit a space.
272

273         if (spacingInterval > 0 && bytesSinceSpace == spacingInterval)
274         {
275             out.print(' ');
276             bytesSinceSpace = 0;
277         }
278
279         writeHex(b, 2);
280
281         if (showAscii)
282         {
283             if (b < 32 | b > 127)
284                 letter = substituteChar;
285             else
286                 letter = (char) b;
287
288             ascii[lineCount] = letter;
289         }
290
291         lineCount++;
292         bytesSinceSpace++;
293     }
294
295     private void writeHex(int value, int digits)
296     {
297         int i;
298         int nybble;
299
300         for (i = 0; i < digits; i++)
301         {
302             nybble = (value >> 4 * (digits - i - 1)) & 0x0f;
303
304             out.print(HEX[nybble]);
305         }
306     }
307 }
Popular Tags