1 package org.bouncycastle.util; 2 3 import java.io.ByteArrayOutputStream; 4 import java.util.Vector; 5 6 public final class Strings 7 { 8 public static String fromUTF8ByteArray(byte[] bytes) 9 { 10 int i = 0; 11 int length = 0; 12 13 while (i < bytes.length) 14 { 15 length++; 16 if ((bytes[i] & 0xf0) == 0xf0) 17 { 18 // surrogate pair 19 length++; 20 i += 4; 21 } 22 else if ((bytes[i] & 0xe0) == 0xe0) 23 { 24 i += 3; 25 } 26 else if ((bytes[i] & 0xc0) == 0xc0) 27 { 28 i += 2; 29 } 30 else 31 { 32 i += 1; 33 } 34 } 35 36 char[] cs = new char[length]; 37 38 i = 0; 39 length = 0; 40 41 while (i < bytes.length) 42 { 43 char ch; 44 45 if ((bytes[i] & 0xf0) == 0xf0) 46 { 47 int codePoint = ((bytes[i] & 0x03) << 18) | ((bytes[i+1] & 0x3F) << 12) | ((bytes[i+2] & 0x3F) << 6) | (bytes[i+3] & 0x3F); 48 int U = codePoint - 0x10000; 49 char W1 = (char)(0xD800 | (U >> 10)); 50 char W2 = (char)(0xDC00 | (U & 0x3FF)); 51 cs[length++] = W1; 52 ch = W2; 53 i += 4; 54 } 55 else if ((bytes[i] & 0xe0) == 0xe0) 56 { 57 ch = (char)(((bytes[i] & 0x0f) << 12) 58 | ((bytes[i + 1] & 0x3f) << 6) | (bytes[i + 2] & 0x3f)); 59 i += 3; 60 } 61 else if ((bytes[i] & 0xd0) == 0xd0) 62 { 63 ch = (char)(((bytes[i] & 0x1f) << 6) | (bytes[i + 1] & 0x3f)); 64 i += 2; 65 } 66 else if ((bytes[i] & 0xc0) == 0xc0) 67 { 68 ch = (char)(((bytes[i] & 0x1f) << 6) | (bytes[i + 1] & 0x3f)); 69 i += 2; 70 } 71 else 72 { 73 ch = (char)(bytes[i] & 0xff); 74 i += 1; 75 } 76 77 cs[length++] = ch; 78 } 79 80 return new String(cs); 81 } 82 83 public static byte[] toUTF8ByteArray(String string) 84 { 85 return toUTF8ByteArray(string.toCharArray()); 86 } 87 88 public static byte[] toUTF8ByteArray(char[] string) 89 { 90 ByteArrayOutputStream bOut = new ByteArrayOutputStream(); 91 char[] c = string; 92 int i = 0; 93 94 while (i < c.length) 95 { 96 char ch = c[i]; 97 98 if (ch < 0x0080) 99 { 100 bOut.write(ch); 101 } 102 else if (ch < 0x0800) 103 { 104 bOut.write(0xc0 | (ch >> 6)); 105 bOut.write(0x80 | (ch & 0x3f)); 106 } 107 // surrogate pair 108 else if (ch >= 0xD800 && ch <= 0xDFFF) 109 { 110 // in error - can only happen, if the Java String class has a 111 // bug. 112 if (i + 1 >= c.length) 113 { 114 throw new IllegalStateException("invalid UTF-16 codepoint"); 115 } 116 char W1 = ch; 117 ch = c[++i]; 118 char W2 = ch; 119 // in error - can only happen, if the Java String class has a 120 // bug. 121 if (W1 > 0xDBFF) 122 { 123 throw new IllegalStateException("invalid UTF-16 codepoint"); 124 } 125 int codePoint = (((W1 & 0x03FF) << 10) | (W2 & 0x03FF)) + 0x10000; 126 bOut.write(0xf0 | (codePoint >> 18)); 127 bOut.write(0x80 | ((codePoint >> 12) & 0x3F)); 128 bOut.write(0x80 | ((codePoint >> 6) & 0x3F)); 129 bOut.write(0x80 | (codePoint & 0x3F)); 130 } 131 else 132 { 133 bOut.write(0xe0 | (ch >> 12)); 134 bOut.write(0x80 | ((ch >> 6) & 0x3F)); 135 bOut.write(0x80 | (ch & 0x3F)); 136 } 137 138 i++; 139 } 140 141 return bOut.toByteArray(); 142 } 143 144 /** 145 * A locale independent version of toUpperCase. 146 * 147 * @param string input to be converted 148 * @return a US Ascii uppercase version 149 */ 150 public static String toUpperCase(String string) 151 { 152 boolean changed = false; 153 char[] chars = string.toCharArray(); 154 155 for (int i = 0; i != chars.length; i++) 156 { 157 char ch = chars[i]; 158 if ('a' <= ch && 'z' >= ch) 159 { 160 changed = true; 161 chars[i] = (char)(ch - 'a' + 'A'); 162 } 163 } 164 165 if (changed) 166 { 167 return new String(chars); 168 } 169 170 return string; 171 } 172 173 /** 174 * A locale independent version of toLowerCase. 175 * 176 * @param string input to be converted 177 * @return a US ASCII lowercase version 178 */ 179 public static String toLowerCase(String string) 180 { 181 boolean changed = false; 182 char[] chars = string.toCharArray(); 183 184 for (int i = 0; i != chars.length; i++) 185 { 186 char ch = chars[i]; 187 if ('A' <= ch && 'Z' >= ch) 188 { 189 changed = true; 190 chars[i] = (char)(ch - 'A' + 'a'); 191 } 192 } 193 194 if (changed) 195 { 196 return new String(chars); 197 } 198 199 return string; 200 } 201 202 public static byte[] toByteArray(String string) 203 { 204 byte[] bytes = new byte[string.length()]; 205 206 for (int i = 0; i != bytes.length; i++) 207 { 208 char ch = string.charAt(i); 209 210 bytes[i] = (byte)ch; 211 } 212 213 return bytes; 214 } 215 216 public static String[] split(String input, char delimiter) 217 { 218 Vector v = new Vector(); 219 boolean moreTokens = true; 220 String subString; 221 222 while (moreTokens) 223 { 224 int tokenLocation = input.indexOf(delimiter); 225 if (tokenLocation > 0) 226 { 227 subString = input.substring(0, tokenLocation); 228 v.addElement(subString); 229 input = input.substring(tokenLocation + 1); 230 } 231 else 232 { 233 moreTokens = false; 234 v.addElement(input); 235 } 236 } 237 238 String[] res = new String[v.size()]; 239 240 for (int i = 0; i != res.length; i++) 241 { 242 res[i] = (String)v.elementAt(i); 243 } 244 return res; 245 } 246 } 247