1    package org.bouncycastle.asn1;
2    
3    import java.io.*;
4    import java.util.*;
5    
6    public class BERConstructedOctetString
7        extends DEROctetString
8    {
9        /**
10        * convert a vector of octet strings into a single byte string
11        */
12       static private byte[] toBytes(
13           Vector  octs)
14       {
15           ByteArrayOutputStream   bOut = new ByteArrayOutputStream();
16   
17           for (int i = 0; i != octs.size(); i++)
18           {
19               DEROctetString  o = (DEROctetString)octs.elementAt(i);
20   
21               try
22               {
23                   bOut.write(o.getOctets());
24               }
25               catch (IOException e)
26               {
27                   throw new RuntimeException("exception converting octets " + e.toString());
28               }
29           }
30   
31           return bOut.toByteArray();
32       }
33   
34       private Vector  octs;
35   
36       /**
37        * @param string the octets making up the octet string.
38        */
39       public BERConstructedOctetString(
40           byte[]  string)
41       {
42                   super(string);
43       }
44   
45       public BERConstructedOctetString(
46           Vector  octs)
47       {
48                   super(toBytes(octs));
49   
50           this.octs = octs;
51       }
52   
53       public BERConstructedOctetString(
54           DERObject  obj)
55       {
56                   super(obj);
57       }
58   
59       public BERConstructedOctetString(
60           DEREncodable  obj)
61       {
62           super(obj.getDERObject());
63       }
64   
65       public byte[] getOctets()
66       {
67           return string;
68       }
69   
70       /**
71        * return the DER octets that make up this string.
72        */
73       public Enumeration getObjects()
74       {
75           if (octs == null)
76           {
77               octs = generateOcts();
78           }
79   
80           return octs.elements();
81       }
82   
83       private Vector generateOcts()
84       {
85           int     start = 0;
86           int     end = 0;
87           Vector  vec = new Vector();
88   
89           while ((end + 1) < string.length)
90           {
91               if (string[end] == 0 && string[end + 1] == 0)
92               {
93                   byte[]  nStr = new byte[end - start + 1];
94   
95                   for (int i = 0; i != nStr.length; i++)
96                   {
97                       nStr[i] = string[start + i];
98                   }
99   
100                  vec.addElement(new DEROctetString(nStr));
101                  start = end + 1;
102              }
103              end++;
104          }
105  
106          byte[]  nStr = new byte[string.length - start];
107          for (int i = 0; i != nStr.length; i++)
108          {
109              nStr[i] = string[start + i];
110          }
111  
112          vec.addElement(new DEROctetString(nStr));
113  
114          return vec;
115      }
116  
117      public void encode(
118          DEROutputStream out)
119          throws IOException
120      {
121          if (out instanceof ASN1OutputStream || out instanceof BEROutputStream)
122          {
123              out.write(CONSTRUCTED | OCTET_STRING);
124  
125              out.write(0x80);
126  
127              if (octs == null)
128              {
129                  octs = generateOcts();
130              }
131  
132              for (int i = 0; i != octs.size(); i++)
133              {
134                  out.writeObject(octs.elementAt(i));
135              }
136  
137              out.write(0x00);
138              out.write(0x00);
139          }
140          else
141          {
142              super.encode(out);
143          }
144      }
145  }
146