KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdi > internal > VerboseWriter


1 /*******************************************************************************
2  * Copyright (c) 2000, 2005 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.jdi.internal;
12
13
14 import java.io.PrintWriter JavaDoc;
15 import java.util.ArrayList JavaDoc;
16 import java.util.List JavaDoc;
17 import java.util.Map JavaDoc;
18
19 public class VerboseWriter {
20     /** Length of verbose description. */
21     public static final int VERBOSE_DESCRIPTION_LENGTH = 21;
22     /** Number of hexadecimal verbose bytes per line. */
23     public static final int VERBOSE_HEX_BYTES_PER_LINE = 16;
24     /** Width of hex dump. */
25     public static final int VERBOSE_HEX_WIDTH = 16*3+2;
26     
27     /** Number extra verbose lines. These are caused by hex dumps that span more than one line. */
28     int fExtraVerboseLines = 0;
29     
30     /** PrintWriter that is written to. */
31     private PrintWriter JavaDoc fOutput;
32     /** Buffer for output: one StringBuffer entry per line. */
33     private List JavaDoc fLineBuffer;
34     /** Position from where buffer is written to. */
35     private int fPosition;
36     /** True if the current line has not yet been written to. */
37     private boolean fNewLine = true;
38
39     /**
40      * Creates new VerboseWriter that writes to the given PrintWriter.
41      * Output is buffered and previous entries in the buffer can be rewritten.
42      */

43     public VerboseWriter(PrintWriter JavaDoc out) {
44         fOutput = out;
45         fLineBuffer = new ArrayList JavaDoc();
46         fPosition = 0;
47         fLineBuffer.add(new StringBuffer JavaDoc());
48     }
49     
50     /**
51      * Terminate the current line by writing the line separator string.
52      * If autoflush is set and there are extra vebose lines caused by printHex, these lines are
53      * also printed.
54      */

55     public void println() {
56         while (fExtraVerboseLines > 0) {
57             fExtraVerboseLines--;
58             markLn();
59         }
60         
61         markLn();
62     }
63
64     /**
65      * Prints verbose line.
66      */

67     public void println(String JavaDoc description, byte value) {
68         printDescription(description);
69         printHex(value);
70         println();
71     }
72     
73     /**
74      * Prints verbose line.
75      */

76     public void println(String JavaDoc description, short value) {
77         printDescription(description);
78         printHex(value);
79         println();
80     }
81     
82     /**
83      * Prints verbose line.
84      */

85     public void println(String JavaDoc description, int value) {
86         printDescription(description);
87         printHex(value);
88         println();
89     }
90     
91     /**
92      * Prints verbose line.
93      */

94     public void println(String JavaDoc description, long value) {
95         printDescription(description);
96         printHex(value);
97         println();
98     }
99     
100     /**
101      * Prints verbose line.
102      */

103     public void println(String JavaDoc description, byte value, Map JavaDoc valueToString) {
104         printDescription(description);
105         printHex(value);
106         printValue(value, valueToString);
107         println();
108     }
109     
110     /**
111      * Prints verbose line.
112      */

113     public void println(String JavaDoc description, short value, Map JavaDoc valueToString) {
114         printDescription(description);
115         printHex(value);
116         printValue(value, valueToString);
117         println();
118     }
119     
120     /**
121      * Prints verbose line.
122      */

123     public void println(String JavaDoc description, int value, Map JavaDoc valueToString) {
124         printDescription(description);
125         printHex(value);
126         printValue(value, valueToString);
127         println();
128     }
129     
130     /**
131      * Prints verbose line.
132      */

133     public void println(String JavaDoc description, byte value, String JavaDoc[] bitNames) {
134         printDescription(description);
135         printHex(value);
136         printValue(value, bitNames);
137         println();
138     }
139     
140     /**
141      * Prints verbose line.
142      */

143     public void println(String JavaDoc description, short value, String JavaDoc[] bitNames) {
144         printDescription(description);
145         printHex(value);
146         printValue(value, bitNames);
147         println();
148     }
149     
150     /**
151      * Prints verbose line.
152      */

153     public void println(String JavaDoc description, int value, String JavaDoc[] bitNames) {
154         printDescription(description);
155         printHex(value);
156         printValue(value, bitNames);
157         println();
158     }
159     
160     /**
161      * Prints verbose line.
162      */

163     public void println(String JavaDoc description, String JavaDoc value) {
164         printDescription(description);
165         printHex(value);
166         print(value);
167         println();
168     }
169     
170     /**
171      * Prints verbose line.
172      */

173     public void println(String JavaDoc description, boolean value) {
174         printDescription(description);
175         printHex(value);
176         print(Boolean.valueOf(value).toString());
177         println();
178     }
179     
180     /**
181      * Prints verbose line.
182      */

183     public void println(String JavaDoc description, char value) {
184         printDescription(description);
185         printHex(value);
186         print(value);
187         println();
188     }
189     
190     /**
191      * Prints verbose line.
192      */

193     public void println(String JavaDoc description, double value) {
194         printDescription(description);
195         printHex(value);
196         print(new Double JavaDoc(value).toString());
197         println();
198     }
199     
200     /**
201      * Prints verbose line.
202      */

203     public void println(String JavaDoc description, float value) {
204         printDescription(description);
205         printHex(value);
206         print(new Float JavaDoc(value).toString());
207         println();
208     }
209     
210     /**
211      * Prints verbose line.
212      */

213     public void println(String JavaDoc description, byte[] value) {
214         printDescription(description);
215         printHex(value);
216         println();
217     }
218     
219     /**
220      * Prints string with right size.
221      */

222     public void printWidth(String JavaDoc str, int width) {
223         print(str);
224         int spaces = width - str.length();
225         if (spaces > 0) {
226             for (int i = 0; i < spaces; i++) {
227                 print(' ');
228             }
229         }
230     }
231     
232     /**
233      * Prints description string with right size plus its seperator spaces.
234      */

235     public void printDescription(String JavaDoc str) {
236         printWidth(str, VERBOSE_DESCRIPTION_LENGTH);
237     }
238     
239     /**
240      * Prints hex substitution string with right size plus its seperator spaces.
241      */

242     public void printHexSubstitution(String JavaDoc str) {
243         // Note that bytes also start with a space.
244
print(' ');
245         printWidth(str, VERBOSE_HEX_WIDTH - 1);
246     }
247     
248     /**
249      * Appends hex representation of given byte to an array.
250      */

251     private static void appendHexByte(byte b, char[] buffer, int pos) {
252         int count = 2;
253     
254         int abspos = 3*pos;
255         buffer[abspos] = ' ';
256         do {
257             int t = b & 15;
258             if (t > 9) {
259                 t = t - 10 + 'a';
260             } else {
261                 t += '0';
262             }
263             buffer[count-- + abspos] = (char) t;
264             b >>>= 4;
265         } while (count > 0);
266     }
267     
268     /**
269      * Appends remaining spaces to hex dump.
270      */

271     private static void appendHexSpaces(char[] buffer, int pos) {
272         for (int i = 3*pos; i <= VERBOSE_HEX_WIDTH - 3; i+=3) {
273             buffer[i] = ' ';
274             buffer[i+1] = ' ';
275             buffer[i+2] = ' ';
276         }
277         
278         // Two extra spaces as seperator
279
buffer[VERBOSE_HEX_WIDTH - 1] = ' ';
280         buffer[VERBOSE_HEX_WIDTH - 2] = ' ';
281     }
282     
283     /**
284      * Prints hex representation of a byte.
285      */

286     public void printHex(byte b) {
287         char buffer[] = new char[VERBOSE_HEX_WIDTH];
288         appendHexByte(b, buffer, 0);
289         appendHexSpaces(buffer, 1);
290         print(buffer);
291     }
292     
293     /**
294      * Prints hex representation of an int.
295      */

296     public void printHex(short s) {
297         char buffer[] = new char[VERBOSE_HEX_WIDTH];
298         for (int i = 1; i >= 0; i--)
299             appendHexByte((byte)(s >>> i*8), buffer, 1 - i);
300         appendHexSpaces(buffer, 2);
301         print(buffer);
302     }
303     
304     /**
305      * Prints hex representation of an int.
306      */

307     public void printHex(int integer) {
308         char buffer[] = new char[VERBOSE_HEX_WIDTH];
309         for (int i = 3; i >= 0; i--)
310             appendHexByte((byte)(integer >>> i*8), buffer, 3 - i);
311         appendHexSpaces(buffer, 4);
312         print(buffer);
313     }
314     
315     /**
316      * Prints hex representation of a long.
317      */

318     public void printHex(long l) {
319         char buffer[] = new char[VERBOSE_HEX_WIDTH];
320         for (int i = 7; i >= 0; i--)
321             appendHexByte((byte)(l >>> i*8), buffer, 7 - i);
322         appendHexSpaces(buffer, 8);
323         print(buffer);
324     }
325     
326     /**
327      * Prints hex representation of a long.
328      */

329     public void printHex(boolean b) {
330         printHexSubstitution("<boolean>"); //$NON-NLS-1$
331
}
332     
333     /**
334      * Prints hex representation of a long.
335      */

336     public void printHex(char c) {
337         printHexSubstitution("<char>"); //$NON-NLS-1$
338
}
339     
340     /**
341      * Prints hex representation of a long.
342      */

343     public void printHex(double d) {
344         printHexSubstitution("<double>"); //$NON-NLS-1$
345
}
346     
347     /**
348      * Prints hex representation of a long.
349      */

350     public void printHex(float f) {
351         printHexSubstitution("<float>"); //$NON-NLS-1$
352
}
353     
354     /**
355      * Prints hex representation of a String.
356      */

357     public void printHex(String JavaDoc str) {
358         printHexSubstitution("<string>"); //$NON-NLS-1$
359
}
360     
361     /**
362      * Prints hex representation of a byte array.
363      * Note that this can span more than one line, but is considered to be part of one
364      * 'verbose line'. Therefore, a println after a printHex can result in more than one line
365      * being printed to the PrintWriter.
366      */

367     public void printHex(byte[] bytes) {
368         int startPosition = position();
369         char linebuf[] = new char[VERBOSE_HEX_WIDTH];
370         int extraLines = 0;
371         int byteOnLine = 0;
372
373         for (int i = 0; i < bytes.length; i++) {
374             if (byteOnLine == VERBOSE_HEX_BYTES_PER_LINE) {
375                 appendHexSpaces(linebuf, VERBOSE_HEX_BYTES_PER_LINE);
376                 if (extraLines++ > 0) {
377                     printDescription(""); //$NON-NLS-1$
378
}
379                 print(linebuf);
380                 markLn();
381                 byteOnLine = 0;
382             }
383             appendHexByte(bytes[i], linebuf, byteOnLine++);
384         }
385         appendHexSpaces(linebuf, byteOnLine);
386         if (extraLines > 0) {
387             printDescription(""); //$NON-NLS-1$
388
}
389             
390         fExtraVerboseLines += extraLines;
391         print(linebuf);
392         if (extraLines > 0) {
393             gotoPosition(startPosition);
394         }
395     }
396
397     /**
398      * Prints string representation of a value given a Map from values to strings.
399      */

400     public void printValue(int value, Map JavaDoc valueToString) {
401         Integer JavaDoc val = new Integer JavaDoc(value);
402         if (valueToString == null) {
403             print(val.toString());
404             return;
405         }
406         String JavaDoc result = (String JavaDoc)valueToString.get(val);
407         if (result == null) {
408             print(val.toString() + JDIMessages.VerboseWriter___unknown_value__1);
409         } else {
410             print(result);
411         }
412     }
413     
414     /**
415      * Prints string representation of a value given a Vector with the names of the bits.
416      */

417     public void printValue(byte value, String JavaDoc[] bitNames) {
418         printValue(value & 0xff, bitNames);
419     }
420
421     /**
422      * Prints string representation of a value given a Vector with the names of the bits.
423      */

424     public void printValue(short value, String JavaDoc[] bitNames) {
425         printValue(value & 0xffff, bitNames);
426     }
427
428     /**
429      * Prints string representation of a value given a Vector with the names of the bits.
430      */

431     public void printValue(int value, String JavaDoc[] bitNames) {
432         Integer JavaDoc val = new Integer JavaDoc(value);
433         if (bitNames == null) {
434             print(val.toString());
435             return;
436         }
437             
438         boolean bitsSet = false;
439             
440         for (int i = 0; i < bitNames.length; i++) {
441             // Test if bit is set in value.
442
if ((1 << i & value) == 0) {
443                 continue;
444             }
445
446             // See if we have a desciption for the bit.
447
String JavaDoc bitString = bitNames[i];
448             if (bitString == null) {
449                 bitString = JDIMessages.VerboseWriter__unknown_bit__2;
450             }
451
452             if (!bitsSet) {
453                 print(bitString);
454             } else {
455                 print(" & "); //$NON-NLS-1$
456
print(bitString);
457             }
458             bitsSet = true;
459         }
460
461         if (!bitsSet) {
462             print(JDIMessages.VerboseWriter__none__4);
463         }
464     }
465     
466     /**
467      * Checks if a new line is written to. If so, first erase any data on that line.
468      * Line is marked 'not new' after this command.
469      */

470     private void checkForNewLine() {
471         if (fNewLine) {
472             ((StringBuffer JavaDoc)(fLineBuffer.get(fPosition))).setLength(0);
473             fNewLine = false;
474         }
475     }
476     
477     /**
478      * Print a String.
479      */

480     public void print(String JavaDoc str) {
481         checkForNewLine();
482         ((StringBuffer JavaDoc)(fLineBuffer.get(fPosition))).append(str);
483     }
484
485     /**
486      * Print a Character.
487      */

488     public void print(char c) {
489         checkForNewLine();
490         ((StringBuffer JavaDoc)(fLineBuffer.get(fPosition))).append(c);
491     }
492
493     /**
494      * Print array of Characters.
495      */

496     public void print(char[] c) {
497         checkForNewLine();
498         ((StringBuffer JavaDoc)(fLineBuffer.get(fPosition))).append(c);
499     }
500
501     /**
502      * Print a String and then terminate the line.
503      */

504     public void println(String JavaDoc str) {
505         print(str);
506         println();
507     }
508
509     /**
510      * Flush buffer.
511      * If autoflush is off, this method is synchronized on the PrintWriter given in the constructor.
512      */

513     public void flush() {
514         synchronized(fOutput) {
515             int bufSize = fLineBuffer.size();
516                 
517             for (int i = 0; i < bufSize - 1; i++)
518                 fOutput.println(new String JavaDoc((StringBuffer JavaDoc)fLineBuffer.get(i)));
519     
520             // The last line should be printed without an extra newline
521
StringBuffer JavaDoc lastLine = (StringBuffer JavaDoc)fLineBuffer.get(bufSize - 1);
522             if (lastLine.length() > 0)
523                 fOutput.print(new String JavaDoc(lastLine));
524     
525             fOutput.flush();
526             fLineBuffer.clear();
527             fPosition = 0;
528             fLineBuffer.add(new StringBuffer JavaDoc());
529         }
530     }
531     
532     /**
533      * Go to the given position in the buffer.
534      * If the given position is smaller than the current position,
535      * subsequent print commands overwrite existing lines in the buffer.
536      * Else, new lines are added to the buffer.
537      */

538     public void gotoPosition(int pos) {
539         int delta = pos - fPosition;
540         if (delta < 0) {
541             fPosition = pos;
542         } else {
543             while (delta-- > 0)
544                 println();
545         }
546     }
547
548     /**
549      * Prints given number of lines.
550      */

551     public void printLines(int lines) {
552         gotoPosition(fPosition + lines);
553     }
554
555     /**
556      * @return Returns current position in buffer.
557      */

558     public int position() {
559         return fPosition;
560     }
561     
562     /**
563      * Terminate the current line by writing the line separator string, start at end of next line.
564      */

565     public void markLn() {
566         if (++fPosition == fLineBuffer.size()) {
567             fLineBuffer.add(new StringBuffer JavaDoc());
568         }
569             
570         fNewLine = true;
571     }
572 }
573
Popular Tags