1    package org.bouncycastle.asn1;
2    
3    import java.io.*;
4    
5    /**
6     * DER UTF8String object.
7     */
8    public class DERUTF8String
9        extends DERObject
10       implements DERString
11   {
12       String  string;
13   
14       /**
15        * return an UTF8 string from the passed in object.
16        *
17        * @exception IllegalArgumentException if the object cannot be converted.
18        */
19       public static DERUTF8String getInstance(
20           Object  obj)
21       {
22           if (obj == null || obj instanceof DERUTF8String)
23           {
24               return (DERUTF8String)obj;
25           }
26   
27           if (obj instanceof ASN1OctetString)
28           {
29               return new DERUTF8String(((ASN1OctetString)obj).getOctets());
30           }
31   
32           if (obj instanceof ASN1TaggedObject)
33           {
34               return getInstance(((ASN1TaggedObject)obj).getObject());
35           }
36   
37           throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
38       }
39   
40       /**
41        * return an UTF8 String from a tagged object.
42        *
43        * @param obj the tagged object holding the object we want
44        * @param explicit true if the object is meant to be explicitly
45        *              tagged false otherwise.
46        * @exception IllegalArgumentException if the tagged object cannot
47        *               be converted.
48        */
49       public static DERUTF8String getInstance(
50           ASN1TaggedObject obj,
51           boolean          explicit)
52       {
53           return getInstance(obj.getObject());
54       }
55   
56       /**
57        * basic constructor - byte encoded string.
58        */
59       DERUTF8String(
60           byte[]   string)
61       {
62           int i = 0;
63           int length = 0;
64   
65           while (i < string.length)
66           {
67               length++;
68               if ((string[i] & 0xe0) == 0xe0)
69               {
70                   i += 3;
71               }
72               else if ((string[i] & 0xc0) == 0xc0)
73               {
74                   i += 2;
75               }
76               else
77               {
78                   i += 1;
79               }
80           }
81   
82           char[]  cs = new char[length];
83   
84           i = 0;
85           length = 0;
86   
87           while (i < string.length)
88           {
89               char    ch;
90   
91               if ((string[i] & 0xe0) == 0xe0)
92               {
93                   ch = (char)(((string[i] & 0x1f) << 12)
94                         | ((string[i + 1] & 0x3f) << 6) | (string[i + 2] & 0x3f));
95                   i += 3;
96               }
97               else if ((string[i] & 0xc0) == 0xc0)
98               {
99                   ch = (char)(((string[i] & 0x3f) << 6) | (string[i + 1] & 0x3f));
100                  i += 2;
101              }
102              else
103              {
104                  ch = (char)(string[i] & 0xff);
105                  i += 1;
106              }
107  
108              cs[length++] = ch;
109          }
110  
111          this.string = new String(cs);
112      }
113  
114      /**
115       * basic constructor
116       */
117      public DERUTF8String(
118          String   string)
119      {
120          this.string = string;
121      }
122  
123      public String getString()
124      {
125          return string;
126      }
127  
128      public int hashCode()
129      {
130          return this.getString().hashCode();
131      }
132  
133      public boolean equals(
134          Object  o)
135      {
136          if (!(o instanceof DERUTF8String))
137          {
138              return false;
139          }
140  
141          DERUTF8String  s = (DERUTF8String)o;
142  
143          return this.getString().equals(s.getString());
144      }
145  
146      void encode(
147          DEROutputStream  out)
148          throws IOException
149      {
150          char[]                  c = string.toCharArray();
151          ByteArrayOutputStream   bOut = new ByteArrayOutputStream();
152  
153          for (int i = 0; i != c.length; i++)
154          {
155              char    ch = c[i];
156  
157              if (ch < 0x0080)
158              {
159                  bOut.write(ch);
160              }
161              else if (ch < 0x0800)
162              {
163                  bOut.write(0xc0 | (ch >> 6));
164                  bOut.write(0x80 | (ch & 0x3f));
165              }
166              else
167              {
168                  bOut.write(0xe0 | (ch >> 12));
169                  bOut.write(0x80 | ((ch >> 6) & 0x3F));
170                  bOut.write(0x80 | (ch & 0x3F));
171              }
172          }
173  
174          out.writeEncoded(UTF8_STRING, bOut.toByteArray());
175      }
176  }
177