Mega Code Archive

 
Categories / Java / File Input Output
 

Binary Dump OutputStream

/*   * The Apache Software License, Version 1.1  *  * Copyright (c) 2000-2003 The Apache Software Foundation.  All rights  * reserved.  *  * Redistribution and use in source and binary forms, with or without  * modification, are permitted provided that the following conditions  * are met:  *  * 1. Redistributions of source code must retain the above copyright  *    notice, this list of conditions and the following disclaimer.  *  * 2. Redistributions in binary form must reproduce the above copyright  *    notice, this list of conditions and the following disclaimer in  *    the documentation and/or other materials provided with the  *    distribution.  *  * 3. The end-user documentation included with the redistribution,  *    if any, must include the following acknowledgment:  *       "This product includes software developed by the  *        Apache Software Foundation (http://apache.org/)."  *    Alternately, this acknowledgment may appear in the software itself,  *    if and wherever such third-party acknowledgments normally appear.  *  * 4. The names "Apache" and "Apache Software Foundation", "Tapestry"   *    must not be used to endorse or promote products derived from this  *    software without prior written permission. For written  *    permission, please contact apache@apache.org.  *  * 5. Products derived from this software may not be called "Apache"   *    or "Tapestry", nor may "Apache" or "Tapestry" appear in their   *    name, without prior written permission of the Apache Software Foundation.  *  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE  * DISCLAIMED.  IN NO EVENT SHALL THE TAPESTRY CONTRIBUTOR COMMUNITY  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF  * SUCH DAMAGE.  *   *  * This software consists of voluntary contributions made by many  * individuals on behalf of the Apache Software Foundation.  For more  * information on the Apache Software Foundation, please see  * <http://www.apache.org/>.  *  */ import java.io.IOException; import java.io.OutputStream; import java.io.PrintWriter; import java.io.Writer; /**  *  A kind of super-formatter.  It is sent a stream of binary data and  *  formats it in a human-readable dump format which is forwarded to  *  its output stream.  *  * <p>Currently, output is in hex though options to change that may  * be introduced.  *  *  @author Howard Lewis Ship  *  @version $Id: BinaryDumpOutputStream.java,v 1.1 2003/03/05 22:59:31 hlship Exp $  *   **/ public class BinaryDumpOutputStream extends OutputStream {     private PrintWriter out;     private boolean locked = false;     private boolean showOffset = true;     private int bytesPerLine = 16;     private int spacingInterval = 4;     private char substituteChar = '.';     private String offsetSeperator = ": ";     private int offset = 0;     private int lineCount = 0;     private int bytesSinceSpace = 0;     private char[] ascii = null;     private boolean showAscii = true;     private String asciiBegin = "  |";     private String asciiEnd = "|";     private static final char[] HEX =         {             '0',             '1',             '2',             '3',             '4',             '5',             '6',             '7',             '8',             '9',             'a',             'b',             'c',             'd',             'e',             'f' };     /**      *  Creates a <code>PrintWriter</code> for <code>System.out</code>.      *      **/     public BinaryDumpOutputStream()     {         this(new PrintWriter(System.out, true));     }     public BinaryDumpOutputStream(PrintWriter out)     {         this.out = out;     }     public BinaryDumpOutputStream(Writer out)     {         this.out = new PrintWriter(out);     }     public void close() throws IOException     {         if (out != null)         {             if (lineCount > 0)                 finishFinalLine();             out.close();         }         out = null;     }     private void finishFinalLine()     {         // Since we only finish the final line after at least one byte has         // been written to it, we don't need to worry about         // the offset.         while (lineCount < bytesPerLine)         {             // After every <n> bytes, emit a space.             if (spacingInterval > 0 && bytesSinceSpace == spacingInterval)             {                 out.print(' ');                 bytesSinceSpace = 0;             }             // Two spaces to substitute for the two hex digits.             out.print("  ");             if (showAscii)                 ascii[lineCount] = ' ';             lineCount++;             bytesSinceSpace++;         }         if (showAscii)         {             out.print(asciiBegin);             out.print(ascii);             out.print(asciiEnd);         }         out.println();     }     /**      *  Forwards the <code>flush()</code> to the <code>PrintWriter</code>.      *      **/     public void flush() throws IOException     {         out.flush();     }     public String getAsciiBegin()     {         return asciiBegin;     }     public String getAsciiEnd()     {         return asciiEnd;     }     public int getBytesPerLine()     {         return bytesPerLine;     }     public String getOffsetSeperator()     {         return offsetSeperator;     }     public boolean getShowAscii()     {         return showAscii;     }     public char getSubstituteChar()     {         return substituteChar;     }     public void setAsciiBegin(String value)     {         if (locked)             throw new IllegalStateException();         asciiBegin = value;     }     public void setAsciiEnd(String value)     {         if (locked)             throw new IllegalStateException();         asciiEnd = value;     }     public void setBytesPerLine(int value)     {         if (locked)             throw new IllegalStateException();         bytesPerLine = value;         ascii = null;     }     public void setOffsetSeperator(String value)     {         if (locked)             throw new IllegalStateException();         offsetSeperator = value;     }     public void setShowAscii(boolean value)     {         if (locked)             throw new IllegalStateException();         showAscii = value;     }     /**      *  Sets the character used in the ASCII dump that substitutes for characters      *  outside the range of 32..126.      *      **/     public void setSubstituteChar(char value)     {         if (locked)             throw new IllegalStateException();         substituteChar = value;     }     public void write(int b) throws IOException     {         char letter;         if (showAscii && ascii == null)             ascii = new char[bytesPerLine];         // Prevent further customization after output starts being written.         locked = true;         if (lineCount == bytesPerLine)         {             if (showAscii)             {                 out.print(asciiBegin);                 out.print(ascii);                 out.print(asciiEnd);             }             out.println();             bytesSinceSpace = 0;             lineCount = 0;             offset += bytesPerLine;         }         if (lineCount == 0 && showOffset)         {             writeHex(offset, 4);             out.print(offsetSeperator);         }         // After every <n> bytes, emit a space.         if (spacingInterval > 0 && bytesSinceSpace == spacingInterval)         {             out.print(' ');             bytesSinceSpace = 0;         }         writeHex(b, 2);         if (showAscii)         {             if (b < 32 | b > 127)                 letter = substituteChar;             else                 letter = (char) b;             ascii[lineCount] = letter;         }         lineCount++;         bytesSinceSpace++;     }     private void writeHex(int value, int digits)     {         int i;         int nybble;         for (i = 0; i < digits; i++)         {             nybble = (value >> 4 * (digits - i - 1)) & 0x0f;             out.print(HEX[nybble]);         }     } }