AsnOutputStream.java :  » Parser » Rats-Parser-Generators » cryptix » jce » provider » asn » Java Open Source

Java Open Source » Parser » Rats Parser Generators 
Rats Parser Generators » cryptix » jce » provider » asn » AsnOutputStream.java
/* $Id: AsnOutputStream.java,v 1.1 2004/01/19 02:03:49 rgrimm Exp $
 *
 * Copyright (c) 2000 The Cryptix Foundation Limited. All rights reserved.
 */

package cryptix.jce.provider.asn;


import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;


/**
 * Class for writing DER-encoded AsnObjects to an OutputStream.
 *
 * @version $Revision: 1.1 $
 * @author  Jeroen C. van Gelderen (gelderen@cryptix.org)
 */
public final class AsnOutputStream {

// Instance variables
//............................................................................

    private final OutputStream os;


// Constructors and java.lang.Object overrides
//............................................................................

    /**
     * Convenience method that constructs an instance on top of an
     * internal ByteArrayOutputStream.
     */
    public AsnOutputStream() {
        this.os = new ByteArrayOutputStream();
    }


    /**
     * Constructs an instance on top of the given OutputStream.
     */
    public AsnOutputStream(OutputStream os) {
        this.os = os;
    }


// Public interface
//............................................................................

    /**
     * Calls flush() then close() on the underlying stream. Exceptions are
     * propagated up.
     *
     * @throws IOException
     *         When underlying stream does so.
     */
    public void close() throws IOException {
        this.os.flush();
        this.os.close();
    }


    /**
     * Calls flush() on the underlying stream. Exceptions are propagated up.
     *
     * @throws IOException
     *         When underlying stream does so.
     */
    public void flush() throws IOException {
        this.os.flush();
    }


    /**
     * Writes a DER-encoded AsnObject to the underlying stream.
     */
    public void write(AsnObject obj) throws IOException {
        obj.encode(this);
    }


    /**
     * Delegates to the underlying ByteArrayOutputStream if any.
     *
     * @throws IllegalStateException
     *         If the underlying stream is not a ByteArrayOutputStream.
     */
    public byte[] toByteArray() {

        if( !(this.os instanceof ByteArrayOutputStream) )
            throw new IllegalStateException(
                "Underlying stream is not instanceof ByteArrayOutputStream.");

        ByteArrayOutputStream baos = (ByteArrayOutputStream)this.os;
        return baos.toByteArray();
    }


// AsnObject.encode(...) callbacks and helpers
//............................................................................

    /**
     * Returns the number of bytes writeLength() will write when called 
     * with the given 'len'. Yes, ASN/DER encoding sucks, don't get me started.
     */
    /*package*/ int getLengthOfLength(int len) {
        if( len <= 127 )
            return 1;
        else if( len <= 0xFF )
            return 2;
        else if( len <= 0xFFFF )
            return 3;
        else if( len <= 0xFFFFFF )
            return 4;
        else
            return 5;
    }


    /*package*/ void writeByte(byte b) throws IOException {
        this.os.write(b&0xFF);
    }


    /*package*/ void writeBytes(byte[] data) throws IOException {
        this.os.write(data);
    }


    /**
     * Write a variable length length (yuk!) as per ASN.1/DER specification.
     */
    /*package*/ void writeLength(int len) throws IOException {

        if(len < 0 ) 
            throw new IllegalArgumentException("len: < 0");

        // shortcut for short form
        if(len <= 127) {
            this.os.write( (char)len );
            return;
        }

        // long form
        int lenOfLenData = getLengthOfLength(len) - 1;
        this.os.write( (byte)(lenOfLenData | 0x80) );
        while( lenOfLenData-- > 0 )
            this.os.write( (byte)(len >>> (lenOfLenData*8)) );
    }


    /*package*/ void writeType(byte type) throws IOException {
        this.os.write(type);
    }
}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.