1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 package org.apache.harmony.luni.util; 19 20 import java.io.ByteArrayOutputStream; 21 import java.io.UnsupportedEncodingException; 22 23 public final class Util { 24 /** 25 * '%' and two following hex digit characters are converted to the 26 * equivalent byte value. All other characters are passed through 27 * unmodified. e.g. "ABC %24%25" -> "ABC $%" 28 * 29 * @param s 30 * java.lang.String The encoded string. 31 * @return java.lang.String The decoded version. 32 */ 33 public static String decode(String s, boolean convertPlus) { 34 return decode(s, convertPlus, null); 35 } 36 37 /** 38 * '%' and two following hex digit characters are converted to the 39 * equivalent byte value. All other characters are passed through 40 * unmodified. e.g. "ABC %24%25" -> "ABC $%" 41 * 42 * @param s 43 * java.lang.String The encoded string. 44 * @param encoding 45 * the specified encoding 46 * @return java.lang.String The decoded version. 47 */ 48 public static String decode(String s, boolean convertPlus, String encoding) { 49 if (!convertPlus && s.indexOf('%') == -1) 50 return s; 51 StringBuilder result = new StringBuilder(s.length()); 52 ByteArrayOutputStream out = new ByteArrayOutputStream(); 53 for (int i = 0; i < s.length();) { 54 char c = s.charAt(i); 55 if (convertPlus && c == '+') 56 result.append(' '); 57 else if (c == '%') { 58 out.reset(); 59 do { 60 if (i + 2 >= s.length()) { 61 throw new IllegalArgumentException("Incomplete % sequence at: " + i); 62 } 63 int d1 = Character.digit(s.charAt(i + 1), 16); 64 int d2 = Character.digit(s.charAt(i + 2), 16); 65 if (d1 == -1 || d2 == -1) { 66 throw new IllegalArgumentException("Invalid % sequence " + 67 s.substring(i, i + 3) + " at " + i); 68 } 69 out.write((byte) ((d1 << 4) + d2)); 70 i += 3; 71 } while (i < s.length() && s.charAt(i) == '%'); 72 if (encoding == null) { 73 result.append(out.toString()); 74 } else { 75 try { 76 result.append(out.toString(encoding)); 77 } catch (UnsupportedEncodingException e) { 78 throw new IllegalArgumentException(e); 79 } 80 } 81 continue; 82 } else 83 result.append(c); 84 i++; 85 } 86 return result.toString(); 87 } 88 89 public static String toASCIILowerCase(String s) { 90 int len = s.length(); 91 StringBuilder buffer = new StringBuilder(len); 92 for (int i = 0; i < len; i++) { 93 char c = s.charAt(i); 94 if ('A' <= c && c <= 'Z') { 95 buffer.append((char) (c + ('a' - 'A'))); 96 } else { 97 buffer.append(c); 98 } 99 } 100 return buffer.toString(); 101 } 102 103 public static String toASCIIUpperCase(String s) { 104 int len = s.length(); 105 StringBuilder buffer = new StringBuilder(len); 106 for (int i = 0; i < len; i++) { 107 char c = s.charAt(i); 108 if ('a' <= c && c <= 'z') { 109 buffer.append((char) (c - ('a' - 'A'))); 110 } else { 111 buffer.append(c); 112 } 113 } 114 return buffer.toString(); 115 } 116 } 117