/**
*
*/
package org.fusesource.restygwt.client.util;
import java.io.UnsupportedEncodingException;
import java.util.logging.Logger;
/**
* @author Larkin Lowrey
*
*/
public class Base64Codec
{
public static byte[] decode(String base64)
{
Logger log = Logger.getLogger("base64 decode");
log.info("encoded: [" + base64.length() + "] " + base64);
String decoded = jsDecode(base64);
byte bytes[];
try
{
bytes = decoded.getBytes("ISO-8859-1");
}
catch (UnsupportedEncodingException e)
{
throw new RuntimeException("Unable to decode base64", e);
}
StringBuilder sb = new StringBuilder();
sb.append("encoded: [");
sb.append(bytes.length);
sb.append("] ");
char HEX[] = "0123456789ABCDEF".toCharArray();
for (int i = 0; i < bytes.length; i++)
{
sb.append(HEX[(bytes[i] >> 4) & 0x0F]);
sb.append(HEX[(bytes[i] >> 0) & 0x0F]);
}
log.info(sb.toString());
return bytes;
}
public static String encode(byte bytes[])
{
try
{
return jsEncode(new String(bytes, "ISO-8859-1"));
}
catch (UnsupportedEncodingException e)
{
throw new RuntimeException("Unable to encode to base64", e);
}
}
private static native String jsDecode(String base64) /*-{
if (window.atob)
{
return atob(base64);
}
else
{
if (base64.length == 0)
return "";
var mod = base64.length % 4;
var encoded;
if (mod == 0)
encoded = base64;
else if (mod == 1)
throw "Illegal base64 length";
else if (mod == 2)
encoded = base64.concat("==");
else
encoded = base64.concat("=");
var wholeBlocks = encoded.length / 4;
if (encoded.charAt(encoded.length - 1) == '=' || encoded.charAt(encoded.length - 2) == '=')
wholeBlocks--;
var lookup = [
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,62,-1,-1,-1,63,
52,53,54,55,56,57,58,59,60,61,-1,-1,-1,-1,-1,-1,
-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,
15,16,17,18,19,20,21,22,23,24,25,-1,-1,-1,-1,-1,
-1,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,
41,42,43,44,45,46,47,48,49,50,51,-1,-1,-1,-1,-1
];
var decoded = "";
for (i = 0, j = 0; j < wholeBlocks; j++)
{
var c1 = encoded.charCodeAt(i++);
var c2 = encoded.charCodeAt(i++);
var c3 = encoded.charCodeAt(i++)
var c4 = encoded.charCodeAt(i++);
var e1 = 0 <= c1 && c1 <= 128 ? lookup[c1] : -1;
var e2 = 0 <= c2 && c2 <= 128 ? lookup[c2] : -1;
var e3 = 0 <= c3 && c3 <= 128 ? lookup[c3] : -1;
var e4 = 0 <= c4 && c4 <= 128 ? lookup[c4] : -1;
if (e1 == -1 || e2 == -1 || e3 == -1 || e4 == -1)
throw "Illegal base64 characters";
var d1 = String.fromCharCode(((e1 << 2) | (e2 >> 4)) & 0xFF);
var d2 = String.fromCharCode(((e2 << 4) | (e3 >> 2)) & 0xFF);
var d3 = String.fromCharCode(((e3 << 6) | (e4 >> 0)) & 0xFF);
decoded = decoded.concat(d1, d2, d3);
}
if (i < encoded.length)
{
var c1 = encoded.charCodeAt(i++);
var c2 = encoded.charCodeAt(i++);
var c3 = encoded.charCodeAt(i++)
var e1 = 0 <= c1 && c1 <= 128 ? lookup[c1] : -1;
var e2 = 0 <= c2 && c2 <= 128 ? lookup[c2] : -1;
if (e1 == -1 || e2 == -1)
throw "Illegal base64 characters";
var d1 = String.fromCharCode(((e1 << 2) | (e2 >> 4)) & 0xFF);
if (c3 != "=".charCodeAt(0))
{
var e3 = 0 <= c3 && c3 <= 128 ? lookup[c3] : -1;
if (e3 == -1)
throw "Illegal base64 characters";
var d2 = String.fromCharCode(((e2 << 4) | (e3 >> 2)) & 0xFF);
decoded = decoded.concat(d1, d2);
}
else
decoded = decoded.concat(d1);
}
return decoded;
}
}-*/;
private static native String jsEncode(String bytes) /*-{
if (window.btoa)
{
return btoa(bytes);
}
else
{
if (bytes.length == 0)
return "";
var encoded = "";
var wholeBlocks = Math.floor(bytes.length / 3);
var lookup = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
for (i = 0, j = 0; j < wholeBlocks; j++)
{
var b1 = bytes.charCodeAt(i++);
var b2 = bytes.charCodeAt(i++);
var b3 = bytes.charCodeAt(i++);
var e1 = b1 >> 2;
var e2 = (b1 << 4 | b2 >> 4);
var e3 = (b2 << 2) | (b3 >> 6);
var e4 = b3;
var c1 = lookup.charAt(e1 & 0x3F);
var c2 = lookup.charAt(e2 & 0x3F);
var c3 = lookup.charAt(e3 & 0x3F);
var c4 = lookup.charAt(e4 & 0x3F);
encoded = encoded.concat(c1, c2, c3, c4);
}
var rem = bytes.length - i;
if (rem > 0)
{
var b1 = bytes.charCodeAt(i++);
var b2 = rem == 2 ? bytes.charCodeAt(i++) : 0;
var e1 = (b1 >> 2) & 0x3F;
var e2 = (b1 << 4 | b2 >> 4) & 0x3F;
var c1 = lookup.charAt(e1);
var c2 = lookup.charAt(e2);
if (rem == 2)
{
var e3 = (b2 << 2) | (b3 >> 6) & 0x3F;
var c3 = lookup.charAt(e3);
encoded = encoded.concat(c1, c2, c3, "=");
}
else
encoded = encoded.concat(c1, c2, "==");
}
return encoded;
}
}-*/;
}