1f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 2f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Licensed to the Apache Software Foundation (ASF) under one or more 3f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * contributor license agreements. See the NOTICE file distributed with 4f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * this work for additional information regarding copyright ownership. 5f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The ASF licenses this file to You under the Apache License, Version 2.0 6f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * (the "License"); you may not use this file except in compliance with 7f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the License. You may obtain a copy of the License at 8f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 9f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 10f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 11f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 12f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 13f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * See the License for the specific language governing permissions and 15f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * limitations under the License. 16f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 17f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 18f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpackage java.net; 19f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 20f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.io.ByteArrayOutputStream; 21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.io.UnsupportedEncodingException; 22f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 23f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport org.apache.harmony.luni.util.Msg; 24f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/** 26f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * This class is used to encode a string using the format required by {@code 27f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * application/x-www-form-urlencoded} MIME content type. It contains helper 28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * methods used by the URI class, and performs encoding and decoding in a 29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * slightly different way than {@code URLEncoder} and {@code URLDecoder}. 30f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectclass URIEncoderDecoder { 32f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 33f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project static final String digits = "0123456789ABCDEF"; //$NON-NLS-1$ 34f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 35f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project static final String encoding = "UTF8"; //$NON-NLS-1$ 36f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 37f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 38f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Validate a string by checking if it contains any characters other than: 39f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 1. letters ('a'..'z', 'A'..'Z') 2. numbers ('0'..'9') 3. characters in 40f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the legalset parameter 4. others (unicode characters that are not in 41f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * US-ASCII set, and are not ISO Control or are not ISO Space characters) 42f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <p> 43f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * called from {@code URI.Helper.parseURI()} to validate each component 443819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson * 45f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param s 46f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * {@code java.lang.String} the string to be validated 47f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param legal 48f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * {@code java.lang.String} the characters allowed in the String 49f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * s 50f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 51f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project static void validate(String s, String legal) throws URISyntaxException { 52f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (int i = 0; i < s.length();) { 53f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char ch = s.charAt(i); 54f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (ch == '%') { 55f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project do { 56f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (i + 2 >= s.length()) { 57f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new URISyntaxException(s, Msg.getString("K0313"), //$NON-NLS-1$ 58f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project i); 59f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 60f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int d1 = Character.digit(s.charAt(i + 1), 16); 61f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int d2 = Character.digit(s.charAt(i + 2), 16); 62f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (d1 == -1 || d2 == -1) { 63f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new URISyntaxException(s, Msg.getString("K0314", //$NON-NLS-1$ 64f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project s.substring(i, i + 3)), i); 65f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 66f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 67f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project i += 3; 68f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } while (i < s.length() && s.charAt(i) == '%'); 69f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 70f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project continue; 71f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 72f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') 73f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project || (ch >= '0' && ch <= '9') || legal.indexOf(ch) > -1 || (ch > 127 74f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project && !Character.isSpaceChar(ch) && !Character 75f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project .isISOControl(ch)))) { 76f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new URISyntaxException(s, Msg.getString("K00c1"), i); //$NON-NLS-1$ 77f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 78f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project i++; 79f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 80f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 81f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 82f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project static void validateSimple(String s, String legal) 83f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throws URISyntaxException { 84f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (int i = 0; i < s.length();) { 85f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char ch = s.charAt(i); 86f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') 87f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project || (ch >= '0' && ch <= '9') || legal.indexOf(ch) > -1)) { 88f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new URISyntaxException(s, Msg.getString("K00c1"), i); //$NON-NLS-1$ 89f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 90f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project i++; 91f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 92f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 93f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 94f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 95f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * All characters except letters ('a'..'z', 'A'..'Z') and numbers ('0'..'9') 96f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * and legal characters are converted into their hexidecimal value prepended 97f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * by '%'. 98f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <p> 99f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * For example: '#' -> %23 100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Other characters, which are unicode chars that are not US-ASCII, and are 101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * not ISO Control or are not ISO Space chars, are preserved. 102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <p> 103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Called from {@code URI.quoteComponent()} (for multiple argument 104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * constructors) 1053819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson * 106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param s 107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * java.lang.String the string to be converted 108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param legal 109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * java.lang.String the characters allowed to be preserved in the 110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * string s 111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return java.lang.String the converted string 112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project static String quoteIllegal(String s, String legal) 114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throws UnsupportedEncodingException { 11501021fcb0c9026e81ac2c262caf5e2ec830a7025Jesse Wilson StringBuilder buf = new StringBuilder(); 116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (int i = 0; i < s.length(); i++) { 117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char ch = s.charAt(i); 118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if ((ch >= 'a' && ch <= 'z') 119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project || (ch >= 'A' && ch <= 'Z') 120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project || (ch >= '0' && ch <= '9') 121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project || legal.indexOf(ch) > -1 122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project || (ch > 127 && !Character.isSpaceChar(ch) && !Character 123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project .isISOControl(ch))) { 124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project buf.append(ch); 125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project byte[] bytes = new String(new char[] { ch }).getBytes(encoding); 127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (int j = 0; j < bytes.length; j++) { 128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project buf.append('%'); 129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project buf.append(digits.charAt((bytes[j] & 0xf0) >> 4)); 130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project buf.append(digits.charAt(bytes[j] & 0xf)); 131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return buf.toString(); 135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Other characters, which are Unicode chars that are not US-ASCII, and are 139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * not ISO Control or are not ISO Space chars are not preserved. They are 140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * converted into their hexidecimal value prepended by '%'. 141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <p> 142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * For example: Euro currency symbol -> "%E2%82%AC". 1433819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson * <p> 144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Called from URI.toASCIIString() 1453819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson * 146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param s 147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * java.lang.String the string to be converted 148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return java.lang.String the converted string 149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project static String encodeOthers(String s) throws UnsupportedEncodingException { 15101021fcb0c9026e81ac2c262caf5e2ec830a7025Jesse Wilson StringBuilder buf = new StringBuilder(); 152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (int i = 0; i < s.length(); i++) { 153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char ch = s.charAt(i); 154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (ch <= 127) { 155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project buf.append(ch); 156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project byte[] bytes = new String(new char[] { ch }).getBytes(encoding); 158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (int j = 0; j < bytes.length; j++) { 159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project buf.append('%'); 160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project buf.append(digits.charAt((bytes[j] & 0xf0) >> 4)); 161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project buf.append(digits.charAt(bytes[j] & 0xf)); 162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return buf.toString(); 166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Decodes the string argument which is assumed to be encoded in the {@code 170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * x-www-form-urlencoded} MIME content type using the UTF-8 encoding scheme. 171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <p> 172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *'%' and two following hex digit characters are converted to the 173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * equivalent byte value. All other characters are passed through 174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * unmodified. 1753819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson * <p> 176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * e.g. "A%20B%20C %24%25" -> "A B C $%" 177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <p> 178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Called from URI.getXYZ() methods 179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param s 181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * java.lang.String The encoded string. 182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return java.lang.String The decoded version. 183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project static String decode(String s) throws UnsupportedEncodingException { 185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 18601021fcb0c9026e81ac2c262caf5e2ec830a7025Jesse Wilson StringBuilder result = new StringBuilder(); 187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ByteArrayOutputStream out = new ByteArrayOutputStream(); 188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (int i = 0; i < s.length();) { 189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char c = s.charAt(i); 190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (c == '%') { 191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project out.reset(); 192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project do { 193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (i + 2 >= s.length()) { 194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new IllegalArgumentException(Msg.getString( 195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "K01fe", i)); //$NON-NLS-1$ 196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int d1 = Character.digit(s.charAt(i + 1), 16); 198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int d2 = Character.digit(s.charAt(i + 2), 16); 199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (d1 == -1 || d2 == -1) { 200f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new IllegalArgumentException(Msg.getString( 201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "K01ff", s.substring(i, i + 3), //$NON-NLS-1$ 202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project String.valueOf(i))); 203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 204f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project out.write((byte) ((d1 << 4) + d2)); 205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project i += 3; 206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } while (i < s.length() && s.charAt(i) == '%'); 207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result.append(out.toString(encoding)); 208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project continue; 209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result.append(c); 211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project i++; 212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return result.toString(); 214f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 215f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 216f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 217