001 /* 002 * Copyright (c) 2000 - 2006 The Legion Of The Bouncy Castle (http://www.bouncycastle.org) 003 * 004 * Permission is hereby granted, free of charge, to any person obtaining a copy of this 005 * software and associated documentation files (the "Software"), to deal in the Software 006 * without restriction, including without limitation the rights to use, copy, modify, 007 * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 008 * permit persons to whom the Software is furnished to do so, subject to the following 009 * conditions: 010 * 011 * The above copyright notice and this permission notice shall be included in all copies 012 * or substantial portions of the Software. 013 * 014 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 015 * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 016 * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE 017 * FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 018 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 019 * DEALINGS IN THE SOFTWARE. 020 * 021 */ 022 023 package org.apache.directory.shared.asn1.der; 024 025 026 import java.io.FilterOutputStream; 027 import java.io.IOException; 028 import java.io.OutputStream; 029 import java.nio.ByteBuffer; 030 031 import org.apache.directory.shared.i18n.I18n; 032 033 034 public class ASN1OutputStream extends FilterOutputStream 035 { 036 public ASN1OutputStream(OutputStream os) 037 { 038 super( os ); 039 } 040 041 042 public ASN1OutputStream(ByteBuffer out) 043 { 044 super( newOutputStream( out ) ); 045 } 046 047 048 public static OutputStream newOutputStream( final ByteBuffer buf ) 049 { 050 return new OutputStream() 051 { 052 public synchronized void write( int integer ) throws IOException 053 { 054 buf.put( ( byte ) integer ); 055 } 056 057 058 public synchronized void write( byte[] bytes, int off, int len ) throws IOException 059 { 060 buf.put( bytes, off, len ); 061 } 062 }; 063 } 064 065 066 private void writeLength( int length ) throws IOException 067 { 068 if ( length > 127 ) 069 { 070 int size = 1; 071 int val = length; 072 073 while ( ( val >>>= 8 ) != 0 ) 074 { 075 size++; 076 } 077 078 write( ( byte ) ( size | 0x80 ) ); 079 080 for ( int i = ( size - 1 ) * 8; i >= 0; i -= 8 ) 081 { 082 write( ( byte ) ( length >> i ) ); 083 } 084 } 085 else 086 { 087 write( ( byte ) length ); 088 } 089 } 090 091 092 void writeEncoded( int tag, byte[] bytes ) throws IOException 093 { 094 write( tag ); 095 writeLength( bytes.length ); 096 write( bytes ); 097 } 098 099 100 public void writeObject( Object obj ) throws IOException 101 { 102 if ( obj == null ) 103 { 104 writeNull(); 105 } 106 else if ( obj instanceof DEREncodable ) 107 { 108 ( ( DEREncodable ) obj ).encode( this ); 109 } 110 else 111 { 112 throw new IOException( I18n.err( I18n.ERR_00024 ) ); 113 } 114 } 115 116 117 protected void writeNull() throws IOException 118 { 119 write( DERObject.NULL ); 120 write( DERObject.TERMINATOR ); 121 } 122 }