package org.herac.tuxguitar.util; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import org.apache.log4j.Logger; public class Base64Decoder { private static final int BUFFER_SIZE = 1024; private static int check(int ch) { if ((ch >= 'A') && (ch <= 'Z')) { return ch - 'A'; } else if ((ch >= 'a') && (ch <= 'z')) { return ch - 'a' + 26; } else if ((ch >= '0') && (ch <= '9')) { return ch - '0' + 52; } else { switch (ch) { case '=': return 65; case '+': return 62; case '/': return 63; default: return -1; } } } public static byte[] decode(byte[] bytes) { try { ByteArrayInputStream in = new ByteArrayInputStream(bytes); ByteArrayOutputStream out = new ByteArrayOutputStream(); byte buffer[] = new byte[BUFFER_SIZE]; byte chunk[] = new byte[4]; int got = -1; int ready = 0; fill: while ((got = in.read(buffer)) > 0) { int skiped = 0; while (skiped < got) { while (ready < 4) { if (skiped >= got) { continue fill; } int ch = check(buffer[skiped++]); if (ch >= 0) { chunk[ready++] = (byte) ch; } } if (chunk[2] == 65) { out.write(get1(chunk, 0)); return out.toByteArray(); } else if (chunk[3] == 65) { out.write(get1(chunk, 0)); out.write(get2(chunk, 0)); return out.toByteArray(); } else { out.write(get1(chunk, 0)); out.write(get2(chunk, 0)); out.write(get3(chunk, 0)); } ready = 0; } } if (ready == 0) { out.flush(); return out.toByteArray(); } } catch (Throwable throwable) { LOG.error(throwable); } return bytes; } /** The Logger for this class. */ public static final transient Logger LOG = Logger .getLogger(Base64Decoder.class); private static int get1(byte buf[], int off) { return ((buf[off] & 0x3f) << 2) | ((buf[off + 1] & 0x30) >>> 4); } private static int get2(byte buf[], int off) { return ((buf[off + 1] & 0x0f) << 4) | ((buf[off + 2] & 0x3c) >>> 2); } private static int get3(byte buf[], int off) { return ((buf[off + 2] & 0x03) << 6) | (buf[off + 3] & 0x3f); } }