Coverage Report - org.apache.tapestry.util.io.BinaryDumpOutputStream
 
Classes in this File Line Coverage Branch Coverage Complexity
BinaryDumpOutputStream
0%
0/113
0%
0/52
2.25
 
 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  0
     private static final char[] HEX =
 34  
     { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
 35  
 
 36  
     private PrintWriter _out;
 37  
 
 38  0
     private boolean locked = false;
 39  
 
 40  0
     private boolean _showOffset = true;
 41  
 
 42  0
     private int bytesPerLine = 16;
 43  
 
 44  0
     private int _spacingInterval = 4;
 45  
 
 46  0
     private char substituteChar = '.';
 47  
 
 48  0
     private String offsetSeperator = ": ";
 49  
 
 50  0
     private int offset = 0;
 51  
 
 52  0
     private int lineCount = 0;
 53  
 
 54  0
     private int bytesSinceSpace = 0;
 55  
 
 56  0
     private char[] ascii = null;
 57  
 
 58  0
     private boolean showAscii = true;
 59  
 
 60  0
     private String asciiBegin = "  |";
 61  
 
 62  0
     private String asciiEnd = "|";
 63  
 
 64  
     /**
 65  
      * Creates a <code>PrintWriter</code> for <code>System.out</code>.
 66  
      */
 67  
 
 68  
     public BinaryDumpOutputStream()
 69  
     {
 70  0
         this(new PrintWriter(System.out, true));
 71  0
     }
 72  
 
 73  
     public BinaryDumpOutputStream(PrintWriter out)
 74  0
     {
 75  0
         this._out = out;
 76  0
     }
 77  
 
 78  
     public BinaryDumpOutputStream(Writer out)
 79  0
     {
 80  0
         this._out = new PrintWriter(out);
 81  0
     }
 82  
 
 83  
     public void close() throws IOException
 84  
     {
 85  0
         if (_out != null)
 86  
         {
 87  0
             if (lineCount > 0)
 88  0
                 finishFinalLine();
 89  
 
 90  0
             _out.close();
 91  
         }
 92  
 
 93  0
         _out = null;
 94  0
     }
 95  
 
 96  
     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  0
         while (lineCount < bytesPerLine)
 103  
         {
 104  
             // After every <n> bytes, emit a space.
 105  
 
 106  0
             if (_spacingInterval > 0 && bytesSinceSpace == _spacingInterval)
 107  
             {
 108  0
                 _out.print(' ');
 109  0
                 bytesSinceSpace = 0;
 110  
             }
 111  
 
 112  
             // Two spaces to substitute for the two hex digits.
 113  
 
 114  0
             _out.print("  ");
 115  
 
 116  0
             if (showAscii)
 117  0
                 ascii[lineCount] = ' ';
 118  
 
 119  0
             lineCount++;
 120  0
             bytesSinceSpace++;
 121  
         }
 122  
 
 123  0
         if (showAscii)
 124  
         {
 125  0
             _out.print(asciiBegin);
 126  0
             _out.print(ascii);
 127  0
             _out.print(asciiEnd);
 128  
         }
 129  
 
 130  0
         _out.println();
 131  0
     }
 132  
 
 133  
     /**
 134  
      * Forwards the <code>flush()</code> to the <code>PrintWriter</code>.
 135  
      */
 136  
 
 137  
     public void flush() throws IOException
 138  
     {
 139  0
         _out.flush();
 140  0
     }
 141  
 
 142  
     public String getAsciiBegin()
 143  
     {
 144  0
         return asciiBegin;
 145  
     }
 146  
 
 147  
     public String getAsciiEnd()
 148  
     {
 149  0
         return asciiEnd;
 150  
     }
 151  
 
 152  
     public int getBytesPerLine()
 153  
     {
 154  0
         return bytesPerLine;
 155  
     }
 156  
 
 157  
     public String getOffsetSeperator()
 158  
     {
 159  0
         return offsetSeperator;
 160  
     }
 161  
 
 162  
     public boolean getShowAscii()
 163  
     {
 164  0
         return showAscii;
 165  
     }
 166  
 
 167  
     public char getSubstituteChar()
 168  
     {
 169  0
         return substituteChar;
 170  
     }
 171  
 
 172  
     public void setAsciiBegin(String value)
 173  
     {
 174  0
         if (locked)
 175  0
             throw new IllegalStateException();
 176  
 
 177  0
         asciiBegin = value;
 178  0
     }
 179  
 
 180  
     public void setAsciiEnd(String value)
 181  
     {
 182  0
         if (locked)
 183  0
             throw new IllegalStateException();
 184  
 
 185  0
         asciiEnd = value;
 186  0
     }
 187  
 
 188  
     public void setBytesPerLine(int value)
 189  
     {
 190  0
         if (locked)
 191  0
             throw new IllegalStateException();
 192  
 
 193  0
         bytesPerLine = value;
 194  
 
 195  0
         ascii = null;
 196  0
     }
 197  
 
 198  
     public void setOffsetSeperator(String value)
 199  
     {
 200  0
         if (locked)
 201  0
             throw new IllegalStateException();
 202  
 
 203  0
         offsetSeperator = value;
 204  0
     }
 205  
 
 206  
     public void setShowAscii(boolean value)
 207  
     {
 208  0
         if (locked)
 209  0
             throw new IllegalStateException();
 210  
 
 211  0
         showAscii = value;
 212  0
     }
 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  
     public void setSubstituteChar(char value)
 220  
     {
 221  0
         if (locked)
 222  0
             throw new IllegalStateException();
 223  
 
 224  0
         substituteChar = value;
 225  0
     }
 226  
 
 227  
     public void write(int b) throws IOException
 228  
     {
 229  
         char letter;
 230  
 
 231  0
         if (showAscii && ascii == null)
 232  0
             ascii = new char[bytesPerLine];
 233  
 
 234  
         // Prevent further customization after output starts being written.
 235  
 
 236  0
         locked = true;
 237  
 
 238  0
         if (lineCount == bytesPerLine)
 239  
         {
 240  0
             if (showAscii)
 241  
             {
 242  0
                 _out.print(asciiBegin);
 243  0
                 _out.print(ascii);
 244  0
                 _out.print(asciiEnd);
 245  
             }
 246  
 
 247  0
             _out.println();
 248  
 
 249  0
             bytesSinceSpace = 0;
 250  0
             lineCount = 0;
 251  0
             offset += bytesPerLine;
 252  
         }
 253  
 
 254  0
         if (lineCount == 0 && _showOffset)
 255  
         {
 256  0
             writeHex(offset, 4);
 257  0
             _out.print(offsetSeperator);
 258  
         }
 259  
 
 260  
         // After every <n> bytes, emit a space.
 261  
 
 262  0
         if (_spacingInterval > 0 && bytesSinceSpace == _spacingInterval)
 263  
         {
 264  0
             _out.print(' ');
 265  0
             bytesSinceSpace = 0;
 266  
         }
 267  
 
 268  0
         writeHex(b, 2);
 269  
 
 270  0
         if (showAscii)
 271  
         {
 272  0
             if (b < 32 | b > 127)
 273  0
                 letter = substituteChar;
 274  
             else
 275  0
                 letter = (char) b;
 276  
 
 277  0
             ascii[lineCount] = letter;
 278  
         }
 279  
 
 280  0
         lineCount++;
 281  0
         bytesSinceSpace++;
 282  0
     }
 283  
 
 284  
     private void writeHex(int value, int digits)
 285  
     {
 286  
         int i;
 287  
         int nybble;
 288  
 
 289  0
         for (i = 0; i < digits; i++)
 290  
         {
 291  0
             nybble = (value >> 4 * (digits - i - 1)) & 0x0f;
 292  
 
 293  0
             _out.print(HEX[nybble]);
 294  
         }
 295  0
     }
 296  
 
 297  
     public void setSpacingInterval(int spacingInterval)
 298  
     {
 299  0
         this._spacingInterval = spacingInterval;
 300  0
     }
 301  
 
 302  
     public boolean isShowOffset()
 303  
     {
 304  0
         return _showOffset;
 305  
     }
 306  
 
 307  
     public void setShowOffset(boolean showOffset)
 308  
     {
 309  0
         this._showOffset = showOffset;
 310  0
     }
 311  
 
 312  
     public int getSpacingInterval()
 313  
     {
 314  0
         return _spacingInterval;
 315  
     }
 316  
 }