Clover coverage report - Code Coverage for tapestry release 4.0-beta-6
Coverage timestamp: Wed Sep 7 2005 18:41:34 EDT
file stats: LOC: 316   Methods: 24
NCLOC: 200   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
BinaryDumpOutputStream.java 80% 81% 58.3% 77%
coverage coverage
 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;
 18    import java.io.OutputStream;
 19    import java.io.PrintWriter;
 20    import java.io.Writer;
 21   
 22    /**
 23    * A kind of super-formatter. It is sent a stream of binary data and formats it in a human-readable
 24    * dump format which is forwarded to its output stream.
 25    * <p>
 26    * Currently, output is in hex though options to change that may be introduced.
 27    *
 28    * @author Howard Lewis Ship
 29    */
 30   
 31    public class BinaryDumpOutputStream extends OutputStream
 32    {
 33    private PrintWriter out;
 34   
 35    private boolean locked = false;
 36   
 37    private boolean showOffset = true;
 38   
 39    private int bytesPerLine = 16;
 40   
 41    private int spacingInterval = 4;
 42   
 43    private char substituteChar = '.';
 44   
 45    private String offsetSeperator = ": ";
 46   
 47    private int offset = 0;
 48   
 49    private int lineCount = 0;
 50   
 51    private int bytesSinceSpace = 0;
 52   
 53    private char[] ascii = null;
 54   
 55    private boolean showAscii = true;
 56   
 57    private String asciiBegin = " |";
 58   
 59    private String asciiEnd = "|";
 60   
 61    private static final char[] HEX =
 62    { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
 63   
 64    /**
 65    * Creates a <code>PrintWriter</code> for <code>System.out</code>.
 66    */
 67   
 68  0 public BinaryDumpOutputStream()
 69    {
 70  0 this(new PrintWriter(System.out, true));
 71    }
 72   
 73  0 public BinaryDumpOutputStream(PrintWriter out)
 74    {
 75  0 this.out = out;
 76    }
 77   
 78  4 public BinaryDumpOutputStream(Writer out)
 79    {
 80  4 this.out = new PrintWriter(out);
 81    }
 82   
 83  4 public void close() throws IOException
 84    {
 85  4 if (out != null)
 86    {
 87  4 if (lineCount > 0)
 88  4 finishFinalLine();
 89   
 90  4 out.close();
 91    }
 92   
 93  4 out = null;
 94    }
 95   
 96  4 private void finishFinalLine()
 97    {
 98    // Since we only finish the final line after at least one byte has
 99    // been written to it, we don't need to worry about
 100    // the offset.
 101   
 102  4 while (lineCount < bytesPerLine)
 103    {
 104    // After every <n> bytes, emit a space.
 105   
 106  20 if (spacingInterval > 0 && bytesSinceSpace == spacingInterval)
 107    {
 108  2 out.print(' ');
 109  2 bytesSinceSpace = 0;
 110    }
 111   
 112    // Two spaces to substitute for the two hex digits.
 113   
 114  20 out.print(" ");
 115   
 116  20 if (showAscii)
 117  19 ascii[lineCount] = ' ';
 118   
 119  20 lineCount++;
 120  20 bytesSinceSpace++;
 121    }
 122   
 123  4 if (showAscii)
 124    {
 125  3 out.print(asciiBegin);
 126  3 out.print(ascii);
 127  3 out.print(asciiEnd);
 128    }
 129   
 130  4 out.println();
 131    }
 132   
 133    /**
 134    * Forwards the <code>flush()</code> to the <code>PrintWriter</code>.
 135    */
 136   
 137  8 public void flush() throws IOException
 138    {
 139  8 out.flush();
 140    }
 141   
 142  0 public String getAsciiBegin()
 143    {
 144  0 return asciiBegin;
 145    }
 146   
 147  0 public String getAsciiEnd()
 148    {
 149  0 return asciiEnd;
 150    }
 151   
 152  0 public int getBytesPerLine()
 153    {
 154  0 return bytesPerLine;
 155    }
 156   
 157  0 public String getOffsetSeperator()
 158    {
 159  0 return offsetSeperator;
 160    }
 161   
 162  0 public boolean getShowAscii()
 163    {
 164  0 return showAscii;
 165    }
 166   
 167  0 public char getSubstituteChar()
 168    {
 169  0 return substituteChar;
 170    }
 171   
 172  1 public void setAsciiBegin(String value)
 173    {
 174  1 if (locked)
 175  0 throw new IllegalStateException();
 176   
 177  1 asciiBegin = value;
 178    }
 179   
 180  1 public void setAsciiEnd(String value)
 181    {
 182  1 if (locked)
 183  0 throw new IllegalStateException();
 184   
 185  1 asciiEnd = value;
 186    }
 187   
 188  1 public void setBytesPerLine(int value)
 189    {
 190  1 if (locked)
 191  0 throw new IllegalStateException();
 192   
 193  1 bytesPerLine = value;
 194   
 195  1 ascii = null;
 196    }
 197   
 198  1 public void setOffsetSeperator(String value)
 199    {
 200  1 if (locked)
 201  0 throw new IllegalStateException();
 202   
 203  1 offsetSeperator = value;
 204    }
 205   
 206  1 public void setShowAscii(boolean value)
 207    {
 208  1 if (locked)
 209  0 throw new IllegalStateException();
 210   
 211  1 showAscii = value;
 212    }
 213   
 214    /**
 215    * Sets the character used in the ASCII dump that substitutes for characters outside the range
 216    * of 32..126.
 217    */
 218   
 219  1 public void setSubstituteChar(char value)
 220    {
 221  1 if (locked)
 222  0 throw new IllegalStateException();
 223   
 224  1 substituteChar = value;
 225    }
 226   
 227  508 public void write(int b) throws IOException
 228    {
 229  508 char letter;
 230   
 231  508 if (showAscii && ascii == null)
 232  3 ascii = new char[bytesPerLine];
 233   
 234    // Prevent further customization after output starts being written.
 235   
 236  508 locked = true;
 237   
 238  508 if (lineCount == bytesPerLine)
 239    {
 240  23 if (showAscii)
 241    {
 242  16 out.print(asciiBegin);
 243  16 out.print(ascii);
 244  16 out.print(asciiEnd);
 245    }
 246   
 247  23 out.println();
 248   
 249  23 bytesSinceSpace = 0;
 250  23 lineCount = 0;
 251  23 offset += bytesPerLine;
 252    }
 253   
 254  508 if (lineCount == 0 && showOffset)
 255    {
 256  19 writeHex(offset, 4);
 257  19 out.print(offsetSeperator);
 258    }
 259   
 260    // After every <n> bytes, emit a space.
 261   
 262  508 if (spacingInterval > 0 && bytesSinceSpace == spacingInterval)
 263    {
 264  85 out.print(' ');
 265  85 bytesSinceSpace = 0;
 266    }
 267   
 268  508 writeHex(b, 2);
 269   
 270  508 if (showAscii)
 271    {
 272  381 if (b < 32 | b > 127)
 273  129 letter = substituteChar;
 274    else
 275  252 letter = (char) b;
 276   
 277  381 ascii[lineCount] = letter;
 278    }
 279   
 280  508 lineCount++;
 281  508 bytesSinceSpace++;
 282    }
 283   
 284  527 private void writeHex(int value, int digits)
 285    {
 286  527 int i;
 287  527 int nybble;
 288   
 289  527 for (i = 0; i < digits; i++)
 290    {
 291  1092 nybble = (value >> 4 * (digits - i - 1)) & 0x0f;
 292   
 293  1092 out.print(HEX[nybble]);
 294    }
 295    }
 296   
 297  1 public void setSpacingInterval(int spacingInterval)
 298    {
 299  1 this.spacingInterval = spacingInterval;
 300    }
 301   
 302  0 public boolean isShowOffset()
 303    {
 304  0 return showOffset;
 305    }
 306   
 307  1 public void setShowOffset(boolean showOffset)
 308    {
 309  1 this.showOffset = showOffset;
 310    }
 311   
 312  0 public int getSpacingInterval()
 313    {
 314  0 return spacingInterval;
 315    }
 316    }