001    /**
002     *  Licensed to the Apache Software Foundation (ASF) under one or more
003     *  contributor license agreements.  See the NOTICE file distributed with
004     *  this work for additional information regarding copyright ownership.
005     *  The ASF licenses this file to You under the Apache License, Version 2.0
006     *  (the "License"); you may not use this file except in compliance with
007     *  the License.  You may obtain a copy of the License at
008     *
009     *     http://www.apache.org/licenses/LICENSE-2.0
010     *
011     *  Unless required by applicable law or agreed to in writing, software
012     *  distributed under the License is distributed on an "AS IS" BASIS,
013     *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     *  See the License for the specific language governing permissions and
015     *  limitations under the License.
016     */
017    
018    package org.apache.geronimo.crypto.asn1;
019    
020    import java.io.FilterOutputStream;
021    import java.io.IOException;
022    import java.io.OutputStream;
023    
024    public class DEROutputStream
025        extends FilterOutputStream implements DERTags
026    {
027        public DEROutputStream(
028            OutputStream    os)
029        {
030            super(os);
031        }
032    
033        private void writeLength(
034            int length)
035            throws IOException
036        {
037            if (length > 127)
038            {
039                int size = 1;
040                int val = length;
041    
042                while ((val >>>= 8) != 0)
043                {
044                    size++;
045                }
046    
047                write((byte)(size | 0x80));
048    
049                for (int i = (size - 1) * 8; i >= 0; i -= 8)
050                {
051                    write((byte)(length >> i));
052                }
053            }
054            else
055            {
056                write((byte)length);
057            }
058        }
059    
060        void writeEncoded(
061            int     tag,
062            byte[]  bytes)
063            throws IOException
064        {
065            write(tag);
066            writeLength(bytes.length);
067            write(bytes);
068        }
069    
070        protected void writeNull()
071            throws IOException
072        {
073            write(NULL);
074            write(0x00);
075        }
076    
077        public void writeObject(
078            Object    obj)
079            throws IOException
080        {
081            if (obj == null)
082            {
083                writeNull();
084            }
085            else if (obj instanceof DERObject)
086            {
087                ((DERObject)obj).encode(this);
088            }
089            else if (obj instanceof DEREncodable)
090            {
091                ((DEREncodable)obj).getDERObject().encode(this);
092            }
093            else
094            {
095                throw new IOException("object not DEREncodable");
096            }
097        }
098    }