1 /* 2 * Conditions Of Use 3 * 4 * This software was developed by employees of the National Institute of 5 * Standards and Technology (NIST), an agency of the Federal Government. 6 * Pursuant to title 15 Untied States Code Section 105, works of NIST 7 * employees are not subject to copyright protection in the United States 8 * and are considered to be in the public domain. As a result, a formal 9 * license is not needed to use the software. 10 * 11 * This software is provided by NIST as a service and is expressly 12 * provided "AS IS." NIST MAKES NO WARRANTY OF ANY KIND, EXPRESS, IMPLIED 13 * OR STATUTORY, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTY OF 14 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT 15 * AND DATA ACCURACY. NIST does not warrant or make any representations 16 * regarding the use of the software or the results thereof, including but 17 * not limited to the correctness, accuracy, reliability or usefulness of 18 * the software. 19 * 20 * Permission to use this software is contingent upon your acceptance 21 * of the terms of this agreement 22 * 23 * . 24 * 25 */ 26 package gov.nist.javax.sip.address; 27 28 import java.io.UnsupportedEncodingException; 29 30 /** 31 * Copied from Apache Excalibur project. 32 * Source code available at http://www.google.com/codesearch?hl=en&q=+excalibur+decodePath+show:sK_gDY0W5Rw:OTjCHAiSuF0:th3BdHtpX20&sa=N&cd=1&ct=rc&cs_p=http://apache.edgescape.com/excalibur/excalibur-sourceresolve/source/excalibur-sourceresolve-1.1-src.zip&cs_f=excalibur-sourceresolve-1.1/src/java/org/apache/excalibur/source/SourceUtil.java 33 * @author <A HREF="mailto:jean.deruelle@gmail.com">Jean Deruelle</A> 34 * 35 */ 36 public class RFC2396UrlDecoder { 37 38 /** 39 * Decode a path. 40 * 41 * <p>Interprets %XX (where XX is hexadecimal number) as UTF-8 encoded bytes. 42 * <p>The validity of the input path is not checked (i.e. characters that 43 * were not encoded will not be reported as errors). 44 * <p>This method differs from URLDecoder.decode in that it always uses UTF-8 45 * (while URLDecoder uses the platform default encoding, often ISO-8859-1), 46 * and doesn't translate + characters to spaces. 47 * 48 * @param uri the path to decode 49 * @return the decoded path 50 */ decode(String uri)51 public static String decode(String uri) { 52 StringBuffer translatedUri = new StringBuffer(uri.length()); 53 byte[] encodedchars = new byte[uri.length() / 3]; 54 int i = 0; 55 int length = uri.length(); 56 int encodedcharsLength = 0; 57 while (i < length) { 58 if (uri.charAt(i) == '%') { 59 //we must process all consecutive %-encoded characters in one go, because they represent 60 //an UTF-8 encoded string, and in UTF-8 one character can be encoded as multiple bytes 61 while (i < length && uri.charAt(i) == '%') { 62 if (i + 2 < length) { 63 try { 64 byte x = (byte)Integer.parseInt(uri.substring(i + 1, i + 3), 16); 65 encodedchars[encodedcharsLength] = x; 66 } catch (NumberFormatException e) { 67 throw new IllegalArgumentException("Illegal hex characters in pattern %" + uri.substring(i + 1, i + 3)); 68 } 69 encodedcharsLength++; 70 i += 3; 71 } else { 72 throw new IllegalArgumentException("% character should be followed by 2 hexadecimal characters."); 73 } 74 } 75 try { 76 String translatedPart = new String(encodedchars, 0, encodedcharsLength, "UTF-8"); 77 translatedUri.append(translatedPart); 78 } catch (UnsupportedEncodingException e) { 79 //the situation that UTF-8 is not supported is quite theoretical, so throw a runtime exception 80 throw new RuntimeException("Problem in decodePath: UTF-8 encoding not supported."); 81 } 82 encodedcharsLength = 0; 83 } else { 84 //a normal character 85 translatedUri.append(uri.charAt(i)); 86 i++; 87 } 88 } 89 return translatedUri.toString(); 90 } 91 }