1 64 65 package com.jcorporate.expresso.core.misc; 66 67 72 73 import com.jcorporate.expresso.kernel.util.FastStringBuffer; 74 75 import java.lang.ref.SoftReference ; 76 import java.util.ArrayList ; 77 import java.util.Iterator ; 78 79 80 87 public class URLUTF8Encoder { 88 89 private static SoftReference hexValues; 90 91 private URLUTF8Encoder() { 92 } 94 95 125 126 149 public static String encode(String s) { 150 FastStringBuffer sbuf = FastStringBuffer.getInstance(); 152 try { 153 String [] hex = getHex(); 154 int len = s.length(); 155 156 for (int i = 0; i < len; i++) { 157 int ch = s.charAt(i); 158 159 if ('A' <= ch && ch <= 'Z') { sbuf.append((char) ch); 161 } else if ('a' <= ch && ch <= 'z') { sbuf.append((char) ch); 163 } else if ('0' <= ch && ch <= '9') { sbuf.append((char) ch); 165 } else if (ch == ' ') { sbuf.append('+'); 167 } else if (ch <= 0x007f) { sbuf.append(hex[ch]); 169 } else if (ch <= 0x07FF) { sbuf.append(hex[0xc0 | (ch >> 6)]); 171 sbuf.append(hex[0x80 | (ch & 0x3F)]); 172 } else { sbuf.append(hex[0xe0 | (ch >> 12)]); 174 sbuf.append(hex[0x80 | ((ch >> 6) & 0x3F)]); 175 sbuf.append(hex[0x80 | (ch & 0x3F)]); 176 } 177 } 178 179 return sbuf.toString(); 180 } finally { 181 sbuf.release(); 182 } 183 } 184 185 189 public static String decode(String s) { 190 if (s == null) { 191 return null; 192 } 193 194 s = s.trim(); 195 196 FastStringBuffer sbuf = FastStringBuffer.getInstance(); 198 try { 199 int l = s.length(); 200 int ch = -1; 201 int b; 202 int sumb = 0; 203 204 for (int i = 0; i < l; i++) { 205 206 207 switch (ch = s.charAt(i)) { 208 case '%': 209 ch = s.charAt(++i); 210 211 int hb = (Character.isDigit((char) ch) 212 ? ch - '0' 213 : 10 + Character.toLowerCase((char) ch) - 214 'a') & 0xF; 215 216 if (i <= (l - 2)) { 217 ch = s.charAt(++i); 218 219 int lb = (Character.isDigit((char) ch) 220 ? ch - '0' 221 : 10 + 222 Character.toLowerCase((char) ch) - 223 'a') & 0xF; 224 b = (hb << 4) | lb; 225 } else { 226 b = ch; 227 } 228 229 break; 230 231 case '+': 232 b = ' '; 233 break; 234 235 default: 236 b = ch; 237 } 238 239 if ((b & 0xc0) == 0x80) { sumb = (sumb << 6) | (b & 0x3f); } else { if (i != 0) { sbuf.append((char) sumb); } 245 if ((b & 0x80) == 0x00) { sumb = b; } else { sumb = b & 0x1f; } 250 251 252 } 253 } 254 if (sumb != 0) { 255 sbuf.append((char) sumb); 256 } 257 258 return sbuf.toString().trim(); 259 } catch (StringIndexOutOfBoundsException se) { 260 se.printStackTrace(System.err); 261 throw new IllegalArgumentException ("Index out of bounds while " + 262 "decoding string '" + s + 263 "' (length " + s.length() + 264 ")"); 265 } finally { 266 sbuf.release(); 267 } 268 } 269 270 271 public static void main(String [] args) { 272 ArrayList testStrings = new ArrayList (); 273 testStrings.add("this is a test"); 274 testStrings.add("Now\nWe\nGet\tMore%04Complicated"); 275 testStrings.add("%Leading percent"); 276 testStrings.add("Trailing%"); 277 testStrings.add("%Leading and trailing%"); 278 testStrings.add("Even@$%%More!&Comlicated^@%"); 279 testStrings.add("Even@$%%More!&C|omlic|ated^@%"); 280 testStrings.add("|Even@$%%More!&C|omlic|ated^@%|"); 281 testStrings.add("LoginName|Admin%|"); 282 testStrings.add("|Even@$%%More!&C|omld^@%||Even@$%%More!&C|oml" + 283 "icic|ated^@%||Even@$%%More!&C|omlic|ated^@%||Even@$%%M" + 284 "ore!&C|omlic|ated^@%|"); 285 testStrings.add(""); 286 287 String encoded = null; 288 String decoded = null; 289 String testString = null; 290 291 for (Iterator i = testStrings.iterator(); i.hasNext();) { 292 testString = (String ) i.next(); 293 encoded = encode(testString); 294 decoded = decode(encoded); 295 296 if (!decoded.equals(testString)) { 297 System.out.println("Error encoding/decoding string '" + 298 testString + "' (length " + 299 testString.length() + "). Encoded as '" + 300 encoded + "' (length " + encoded.length() + 301 ") and decoded to '" + decoded + 302 "' (length " + decoded.length() + ")"); 303 } 304 } 305 306 System.out.println("Tests Complete"); 307 } 308 309 private static synchronized String [] getHex() { 310 String returnValue[]; 311 if (hexValues == null || hexValues.get() == null) { 312 final String [] hex = { 313 "%00", "%01", "%02", "%03", "%04", "%05", "%06", "%07", "%08", "%09", 314 "%0a", "%0b", "%0c", "%0d", "%0e", "%0f", "%10", "%11", "%12", "%13", 315 "%14", "%15", "%16", "%17", "%18", "%19", "%1a", "%1b", "%1c", "%1d", 316 "%1e", "%1f", "%20", "%21", "%22", "%23", "%24", "%25", "%26", "%27", 317 "%28", "%29", "%2a", "%2b", "%2c", "%2d", "%2e", "%2f", "%30", "%31", 318 "%32", "%33", "%34", "%35", "%36", "%37", "%38", "%39", "%3a", "%3b", 319 "%3c", "%3d", "%3e", "%3f", "%40", "%41", "%42", "%43", "%44", "%45", 320 "%46", "%47", "%48", "%49", "%4a", "%4b", "%4c", "%4d", "%4e", "%4f", 321 "%50", "%51", "%52", "%53", "%54", "%55", "%56", "%57", "%58", "%59", 322 "%5a", "%5b", "%5c", "%5d", "%5e", "%5f", "%60", "%61", "%62", "%63", 323 "%64", "%65", "%66", "%67", "%68", "%69", "%6a", "%6b", "%6c", "%6d", 324 "%6e", "%6f", "%70", "%71", "%72", "%73", "%74", "%75", "%76", "%77", 325 "%78", "%79", "%7a", "%7b", "%7c", "%7d", "%7e", "%7f", "%80", "%81", 326 "%82", "%83", "%84", "%85", "%86", "%87", "%88", "%89", "%8a", "%8b", 327 "%8c", "%8d", "%8e", "%8f", "%90", "%91", "%92", "%93", "%94", "%95", 328 "%96", "%97", "%98", "%99", "%9a", "%9b", "%9c", "%9d", "%9e", "%9f", 329 "%a0", "%a1", "%a2", "%a3", "%a4", "%a5", "%a6", "%a7", "%a8", "%a9", 330 "%aa", "%ab", "%ac", "%ad", "%ae", "%af", "%b0", "%b1", "%b2", "%b3", 331 "%b4", "%b5", "%b6", "%b7", "%b8", "%b9", "%ba", "%bb", "%bc", "%bd", 332 "%be", "%bf", "%c0", "%c1", "%c2", "%c3", "%c4", "%c5", "%c6", "%c7", 333 "%c8", "%c9", "%ca", "%cb", "%cc", "%cd", "%ce", "%cf", "%d0", "%d1", 334 "%d2", "%d3", "%d4", "%d5", "%d6", "%d7", "%d8", "%d9", "%da", "%db", 335 "%dc", "%dd", "%de", "%df", "%e0", "%e1", "%e2", "%e3", "%e4", "%e5", 336 "%e6", "%e7", "%e8", "%e9", "%ea", "%eb", "%ec", "%ed", "%ee", "%ef", 337 "%f0", "%f1", "%f2", "%f3", "%f4", "%f5", "%f6", "%f7", "%f8", "%f9", 338 "%fa", "%fb", "%fc", "%fd", "%fe", "%ff" 339 }; 340 341 returnValue = hex; 342 hexValues = new SoftReference (hex); 343 } else { 344 returnValue = (String []) hexValues.get(); 345 } 346 347 return returnValue; 348 } 349 } 350 351 | Popular Tags |