001    /**
002     *
003     *  Licensed to the Apache Software Foundation (ASF) under one or more
004     *  contributor license agreements.  See the NOTICE file distributed with
005     *  this work for additional information regarding copyright ownership.
006     *  The ASF licenses this file to You under the Apache License, Version 2.0
007     *  (the "License"); you may not use this file except in compliance with
008     *  the License.  You may obtain a copy of the License at
009     *
010     *     http://www.apache.org/licenses/LICENSE-2.0
011     *
012     *  Unless required by applicable law or agreed to in writing, software
013     *  distributed under the License is distributed on an "AS IS" BASIS,
014     *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015     *  See the License for the specific language governing permissions and
016     *  limitations under the License.
017     */
018    
019    package org.apache.geronimo.util.asn1;
020    
021    import java.io.ByteArrayOutputStream;
022    import java.io.IOException;
023    import java.util.Enumeration;
024    import java.util.Vector;
025    
026    public class BERConstructedOctetString
027        extends DEROctetString
028    {
029        /**
030         * convert a vector of octet strings into a single byte string
031         */
032        static private byte[] toBytes(
033            Vector  octs)
034        {
035            ByteArrayOutputStream   bOut = new ByteArrayOutputStream();
036    
037            for (int i = 0; i != octs.size(); i++)
038            {
039                try
040                {
041                    DEROctetString  o = (DEROctetString)octs.elementAt(i);
042    
043                    bOut.write(o.getOctets());
044                }
045                catch (ClassCastException e)
046                {
047                    throw new IllegalArgumentException(octs.elementAt(i).getClass().getName() + " found in input should only contain DEROctetString");
048                }
049                catch (IOException e)
050                {
051                    throw new IllegalArgumentException("exception converting octets " + e.toString());
052                }
053            }
054    
055            return bOut.toByteArray();
056        }
057    
058        private Vector  octs;
059    
060        /**
061         * @param string the octets making up the octet string.
062         */
063        public BERConstructedOctetString(
064            byte[]  string)
065        {
066            super(string);
067        }
068    
069        public BERConstructedOctetString(
070            Vector  octs)
071        {
072            super(toBytes(octs));
073    
074            this.octs = octs;
075        }
076    
077        public BERConstructedOctetString(
078            DERObject  obj)
079        {
080            super(obj);
081        }
082    
083        public BERConstructedOctetString(
084            DEREncodable  obj)
085        {
086            super(obj.getDERObject());
087        }
088    
089        public byte[] getOctets()
090        {
091            return string;
092        }
093    
094        /**
095         * return the DER octets that make up this string.
096         */
097        public Enumeration getObjects()
098        {
099            if (octs == null)
100            {
101                return generateOcts().elements();
102            }
103    
104            return octs.elements();
105        }
106    
107        private Vector generateOcts()
108        {
109            int     start = 0;
110            int     end = 0;
111            Vector  vec = new Vector();
112    
113            while ((end + 1) < string.length)
114            {
115                if (string[end] == 0 && string[end + 1] == 0)
116                {
117                    byte[]  nStr = new byte[end - start + 1];
118    
119                    System.arraycopy(string, start, nStr, 0, nStr.length);
120    
121                    vec.addElement(new DEROctetString(nStr));
122                    start = end + 1;
123                }
124                end++;
125            }
126    
127            byte[]  nStr = new byte[string.length - start];
128    
129            System.arraycopy(string, start, nStr, 0, nStr.length);
130    
131            vec.addElement(new DEROctetString(nStr));
132    
133            return vec;
134        }
135    
136        public void encode(
137            DEROutputStream out)
138            throws IOException
139        {
140            if (out instanceof ASN1OutputStream || out instanceof BEROutputStream)
141            {
142                out.write(CONSTRUCTED | OCTET_STRING);
143    
144                out.write(0x80);
145    
146                //
147                // write out the octet array
148                //
149                if (octs != null)
150                {
151                    for (int i = 0; i != octs.size(); i++)
152                    {
153                        out.writeObject(octs.elementAt(i));
154                    }
155                }
156                else
157                {
158                    int     start = 0;
159                    int     end = 0;
160    
161                    while ((end + 1) < string.length)
162                    {
163                        if (string[end] == 0 && string[end + 1] == 0)
164                        {
165                            byte[]  nStr = new byte[end - start + 1];
166    
167                            System.arraycopy(string, start, nStr, 0, nStr.length);
168    
169                            out.writeObject(new DEROctetString(nStr));
170                            start = end + 1;
171                        }
172                        end++;
173                    }
174    
175                    byte[]  nStr = new byte[string.length - start];
176    
177                    System.arraycopy(string, start, nStr, 0, nStr.length);
178    
179                    out.writeObject(new DEROctetString(nStr));
180                }
181    
182                out.write(0x00);
183                out.write(0x00);
184            }
185            else
186            {
187                super.encode(out);
188            }
189        }
190    }