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    
024    /**
025     * DER UTF8String object.
026     */
027    public class DERUTF8String
028        extends DERObject
029        implements DERString
030    {
031        String  string;
032    
033        /**
034         * return an UTF8 string from the passed in object.
035         *
036         * @exception IllegalArgumentException if the object cannot be converted.
037         */
038        public static DERUTF8String getInstance(
039            Object  obj)
040        {
041            if (obj == null || obj instanceof DERUTF8String)
042            {
043                return (DERUTF8String)obj;
044            }
045    
046            if (obj instanceof ASN1OctetString)
047            {
048                return new DERUTF8String(((ASN1OctetString)obj).getOctets());
049            }
050    
051            if (obj instanceof ASN1TaggedObject)
052            {
053                return getInstance(((ASN1TaggedObject)obj).getObject());
054            }
055    
056            throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
057        }
058    
059        /**
060         * return an UTF8 String from a tagged object.
061         *
062         * @param obj the tagged object holding the object we want
063         * @param explicit true if the object is meant to be explicitly
064         *              tagged false otherwise.
065         * @exception IllegalArgumentException if the tagged object cannot
066         *               be converted.
067         */
068        public static DERUTF8String getInstance(
069            ASN1TaggedObject obj,
070            boolean          explicit)
071        {
072            return getInstance(obj.getObject());
073        }
074    
075        /**
076         * basic constructor - byte encoded string.
077         */
078        DERUTF8String(
079            byte[]   string)
080        {
081            int i = 0;
082            int length = 0;
083    
084            while (i < string.length)
085            {
086                length++;
087                if ((string[i] & 0xe0) == 0xe0)
088                {
089                    i += 3;
090                }
091                else if ((string[i] & 0xc0) == 0xc0)
092                {
093                    i += 2;
094                }
095                else
096                {
097                    i += 1;
098                }
099            }
100    
101            char[]  cs = new char[length];
102    
103            i = 0;
104            length = 0;
105    
106            while (i < string.length)
107            {
108                char    ch;
109    
110                if ((string[i] & 0xe0) == 0xe0)
111                {
112                    ch = (char)(((string[i] & 0x1f) << 12)
113                          | ((string[i + 1] & 0x3f) << 6) | (string[i + 2] & 0x3f));
114                    i += 3;
115                }
116                else if ((string[i] & 0xc0) == 0xc0)
117                {
118                    ch = (char)(((string[i] & 0x3f) << 6) | (string[i + 1] & 0x3f));
119                    i += 2;
120                }
121                else
122                {
123                    ch = (char)(string[i] & 0xff);
124                    i += 1;
125                }
126    
127                cs[length++] = ch;
128            }
129    
130            this.string = new String(cs);
131        }
132    
133        /**
134         * basic constructor
135         */
136        public DERUTF8String(
137            String   string)
138        {
139            this.string = string;
140        }
141    
142        public String getString()
143        {
144            return string;
145        }
146    
147        public int hashCode()
148        {
149            return this.getString().hashCode();
150        }
151    
152        public boolean equals(
153            Object  o)
154        {
155            if (!(o instanceof DERUTF8String))
156            {
157                return false;
158            }
159    
160            DERUTF8String  s = (DERUTF8String)o;
161    
162            return this.getString().equals(s.getString());
163        }
164    
165        void encode(
166            DEROutputStream  out)
167            throws IOException
168        {
169            char[]                  c = string.toCharArray();
170            ByteArrayOutputStream   bOut = new ByteArrayOutputStream();
171    
172            for (int i = 0; i != c.length; i++)
173            {
174                char    ch = c[i];
175    
176                if (ch < 0x0080)
177                {
178                    bOut.write(ch);
179                }
180                else if (ch < 0x0800)
181                {
182                    bOut.write(0xc0 | (ch >> 6));
183                    bOut.write(0x80 | (ch & 0x3f));
184                }
185                else
186                {
187                    bOut.write(0xe0 | (ch >> 12));
188                    bOut.write(0x80 | ((ch >> 6) & 0x3F));
189                    bOut.write(0x80 | (ch & 0x3F));
190                }
191            }
192    
193            out.writeEncoded(UTF8_STRING, bOut.toByteArray());
194        }
195    }