Here you can find the source of urlDecodeInplace(StringBuilder input)
public static void urlDecodeInplace(StringBuilder input)
//package com.java2s; //License from project: Apache License public class Main { public static final char INVALID_HEX = (char) 256; public static void urlDecodeInplace(StringBuilder input) { urlDecodeInto(input, 0, input.length(), input, true); }/*from w w w . j av a 2 s .c om*/ public static void urlDecodeInto(CharSequence input, int start, int end, StringBuilder result) { urlDecodeInto(input, start, end, result, false); } private static void urlDecodeInto(CharSequence input, int start, int end, StringBuilder result, boolean inplace) { int writeHead = start; for (int i = start; i < end; i++) { char c = input.charAt(i); if (c == '%' && i + 2 < end) { char val = decodeHexPair(input.charAt(i + 1), input.charAt(i + 2)); if ((val & 0xE0) == 0xC0) { if (i + 5 < end && input.charAt(i + 3) == '%') { char val2 = decodeHexPair(input.charAt(i + 4), input.charAt(i + 5)); if (val2 != INVALID_HEX && (val2 & 0xC0) == 0x80) { // zimmerm%C3%A4dchen c = (char) (((val & 0x1F) << 6) | (val2 & 0x3F)); i += 5; } } } else if ((val & 0xF0) == 0xE0) { if (i + 8 < end && input.charAt(i + 3) == '%' && input.charAt(i + 6) == '%') { char val2 = decodeHexPair(input.charAt(i + 4), input.charAt(i + 5)); char val3 = decodeHexPair(input.charAt(i + 7), input.charAt(i + 8)); if (val2 != INVALID_HEX && val3 != INVALID_HEX && (val2 & 0xC0) == 0x80 && (val3 & 0xC0) == 0x80) { // Technologist+%E2%80%93+Full+Time c = (char) (((val & 0x0F) << 12) | ((val2 & 0x3F) << 6) | (val3 & 0x3F)); i += 8; } } } else if ((val & 0xF8) == 0xF0) { //these are code points > 0XFFFF, they need a surrogate pair to represent them if (i + 11 < end && input.charAt(i + 3) == '%' && input.charAt(i + 6) == '%' && input.charAt(i + 9) == '%') { char val2 = decodeHexPair(input.charAt(i + 4), input.charAt(i + 5)); char val3 = decodeHexPair(input.charAt(i + 7), input.charAt(i + 8)); char val4 = decodeHexPair(input.charAt(i + 10), input.charAt(i + 11)); if (val2 != INVALID_HEX && val3 != INVALID_HEX && val4 != INVALID_HEX && (val2 & 0xC0) == 0x80 && (val3 & 0xC0) == 0x80 && (val4 & 0xC0) == 0x80) { final int codePoint = (((val & 0x0F) << 15) | ((val2 & 0x3F) << 12) | ((val3 & 0x3F) << 6) | (val4 & 0x3F)); if (codePoint < Character.MIN_SUPPLEMENTARY_CODE_POINT) { c = (char) codePoint; } else { final int offset = codePoint - Character.MIN_SUPPLEMENTARY_CODE_POINT; final char highChar = (char) ((offset >>> 10) + Character.MIN_HIGH_SURROGATE); final char lowChar = (char) ((offset & 0x3ff) + Character.MIN_LOW_SURROGATE); if (!inplace) { result.append(highChar); } else { result.setCharAt(writeHead++, highChar); } c = lowChar; // let normal machinery take over here } i += 11; } } } else if (val != INVALID_HEX) { c = val; i += 2; } } else if (c == '+') { c = ' '; } if (!inplace) { result.append(c); } else { result.setCharAt(writeHead++, c); } } if (inplace) { result.delete(writeHead, end); } } public static char decodeHexPair(char c1, char c2) { char ret = 0; if (c1 >= '0' && c1 <= '9') { ret |= c1 - '0'; } else if (c1 >= 'a' && c1 <= 'f') { ret |= c1 - 'a' + 10; } else if (c1 >= 'A' && c1 <= 'F') { ret |= c1 - 'A' + 10; } else { return INVALID_HEX; } ret <<= 4; if (c2 >= '0' && c2 <= '9') { ret |= c2 - '0'; } else if (c2 >= 'a' && c2 <= 'f') { ret |= c2 - 'a' + 10; } else if (c2 >= 'A' && c2 <= 'F') { ret |= c2 - 'A' + 10; } else { return INVALID_HEX; } return ret; } }