Created
September 22, 2009 20:14
-
-
Save gnufied/191371 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.io.ByteArrayOutputStream; | |
import java.io.IOException; | |
import java.io.OutputStreamWriter; | |
import java.io.UnsupportedEncodingException; | |
public class URLEncoder { | |
public static String encode(String s, String enc) | |
throws UnsupportedEncodingException { | |
boolean needToChange = false; | |
boolean wroteUnencodedChar = false; | |
int maxBytesPerChar = 10; // rather arbitrary limit, but safe for now | |
StringBuffer out = new StringBuffer(s.length()); | |
ByteArrayOutputStream buf = new ByteArrayOutputStream(maxBytesPerChar); | |
OutputStreamWriter writer = new OutputStreamWriter(buf, enc); | |
for (int i = 0; i < s.length(); i++) { | |
int c = (int) s.charAt(i); | |
if (dontNeedEncoding(c)) { | |
if (c == ' ') { | |
c = '+'; | |
needToChange = true; | |
} | |
out.append((char)c); | |
wroteUnencodedChar = true; | |
} else { | |
try { | |
if (wroteUnencodedChar) { // Fix for 4407610 | |
writer = new OutputStreamWriter(buf, enc); | |
wroteUnencodedChar = false; | |
} | |
writer.write(c); | |
if (c >= 0xD800 && c <= 0xDBFF) { | |
if ( (i+1) < s.length()) { | |
int d = (int) s.charAt(i+1); | |
if (d >= 0xDC00 && d <= 0xDFFF) { | |
writer.write(d); | |
i++; | |
} | |
} | |
} | |
writer.flush(); | |
} catch(IOException e) { | |
buf.reset(); | |
continue; | |
} | |
byte[] ba = buf.toByteArray(); | |
for (int j = 0; j < ba.length; j++) { | |
out.append('%'); | |
char ch = CCharacter.forDigit((ba[j] >> 4) & 0xF, 16); | |
out.append(ch); | |
ch = CCharacter.forDigit(ba[j] & 0xF, 16); | |
out.append(ch); | |
} | |
buf.reset(); | |
needToChange = true; | |
} | |
} | |
return (needToChange? out.toString() : s); | |
} | |
static class CCharacter { | |
public static char forDigit(int digit, int radix) { | |
if ((digit >= radix) || (digit < 0)) { | |
return '\0'; | |
} | |
if ((radix < Character.MIN_RADIX) || (radix > Character.MAX_RADIX)) { | |
return '\0'; | |
} | |
if (digit < 10) { | |
return (char)('0' + digit); | |
} | |
return (char)('a' - 10 + digit); | |
} | |
} | |
public static boolean dontNeedEncoding(int ch){ | |
int len = _dontNeedEncoding.length(); | |
boolean en = false; | |
for(int i =0;i< len;i++){ | |
if(_dontNeedEncoding.charAt(i) == ch) | |
{ | |
en = true; | |
break; | |
} | |
} | |
return en; | |
} | |
private static String _dontNeedEncoding = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ -_.*"; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment