View Javadoc

1   /*
2    *   Copyright 2005 The Apache Software Foundation
3    *
4    *   Licensed under the Apache License, Version 2.0 (the "License");
5    *   you may not use this file except in compliance with the License.
6    *   You may obtain a copy of the License at
7    *
8    *       http://www.apache.org/licenses/LICENSE-2.0
9    *
10   *   Unless required by applicable law or agreed to in writing, software
11   *   distributed under the License is distributed on an "AS IS" BASIS,
12   *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   *   See the License for the specific language governing permissions and
14   *   limitations under the License.
15   *
16   */
17  
18  package org.apache.asn1.der;
19  
20  import java.io.ByteArrayOutputStream;
21  import java.io.IOException;
22  import java.util.Enumeration;
23  import java.util.Vector;
24  
25  
26  public class BERConstructedOctetString extends DEROctetString
27  {
28  	private Vector octets;
29      
30      /***
31       * @param string the octets making up the octet string.
32       */
33      public BERConstructedOctetString( byte[] string )
34      {
35          super( string );
36      }
37  
38      public BERConstructedOctetString( Vector octets )
39      {
40          super( toBytes( octets ) );
41  
42          this.octets = octets;
43      }
44      
45      /***
46       * Convert a vector of octet strings into a single byte string.
47       */
48      static private byte[] toBytes( Vector octs )
49      {
50          ByteArrayOutputStream baos = new ByteArrayOutputStream();
51  
52          for ( int i = 0; i != octs.size(); i++ )
53          {
54              try
55              {
56                  DEROctetString o = (DEROctetString)octs.elementAt( i );
57  
58                  baos.write( o.getOctets() );
59              }
60              catch (ClassCastException e)
61              {
62                  throw new IllegalArgumentException( octs.elementAt( i ).getClass().getName() + " found in input should only contain DEROctetString." );
63              }
64              catch (IOException e)
65              {
66                  throw new IllegalArgumentException( "Exception converting octets " + e.toString() );
67              }
68          }
69  
70          return baos.toByteArray();
71      }
72  
73      /***
74       * @return Enumeration the DER octets that make up this string.
75       */
76      public Enumeration getObjects()
77      {
78          if ( octets == null )
79          {
80              return generateOcts().elements();
81          }
82  
83          return octets.elements();
84      }
85      
86      private Vector generateOcts()
87      {
88          int    start  = 0;
89          int    end    = 0;
90          Vector vector = new Vector();
91  
92          while ( ( end + 1 ) < value.length )
93          {
94              if ( value[ end ] == 0 && value[ end + 1 ] == 0 )
95              {
96                  byte[]  nStr = new byte[ end - start + 1 ];
97  
98                  System.arraycopy( value, start, nStr, 0, nStr.length );
99  
100                 vector.addElement( new DEROctetString( nStr ) );
101                 start = end + 1;
102             }
103             end++;
104         }
105 
106         byte[] nStr = new byte[ value.length - start ];
107 
108         System.arraycopy( value, start, nStr, 0, nStr.length );
109 
110         vector.addElement( new DEROctetString( nStr ) );
111 
112         return vector;
113     }
114     
115     public void encode( ASN1OutputStream out )
116         throws IOException
117     {
118         out.write( CONSTRUCTED | OCTET_STRING );
119 
120         out.write( DERObject.TAGGED );
121         
122         if ( octets != null )
123         {
124             for ( int i = 0; i != octets.size(); i++ )
125             {
126                 out.writeObject( octets.elementAt( i ) );
127             }
128         }
129         else
130         {
131             int start = 0;
132             int end   = 0;
133 
134             while ( ( end + 1 ) < value.length )
135             {
136                 if ( value[ end ] == 0 && value[ end + 1 ] == 0 )
137                 {
138                     byte[] newString = new byte[ end - start + 1 ];
139 
140                     System.arraycopy( value, start, newString, 0, newString.length );
141 
142                     out.writeObject( new DEROctetString( newString ) );
143                     start = end + 1;
144                 }
145                 end++;
146             }
147 
148             byte[] newString = new byte[ value.length - start ];
149 
150             System.arraycopy( value, start, newString, 0, newString.length );
151 
152             out.writeObject( new DEROctetString( newString ) );
153         }
154 
155         out.write( TERMINATOR );
156         out.write( TERMINATOR );
157     }
158 }
159