1f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpackage org.bouncycastle.util.encoders; 2f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.io.IOException; 4f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.io.OutputStream; 5f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 6f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpublic class Base64Encoder 7f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project implements Encoder 8f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 9f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project protected final byte[] encodingTable = 10f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 11f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project (byte)'A', (byte)'B', (byte)'C', (byte)'D', (byte)'E', (byte)'F', (byte)'G', 12f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project (byte)'H', (byte)'I', (byte)'J', (byte)'K', (byte)'L', (byte)'M', (byte)'N', 13f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project (byte)'O', (byte)'P', (byte)'Q', (byte)'R', (byte)'S', (byte)'T', (byte)'U', 14f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project (byte)'V', (byte)'W', (byte)'X', (byte)'Y', (byte)'Z', 15f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project (byte)'a', (byte)'b', (byte)'c', (byte)'d', (byte)'e', (byte)'f', (byte)'g', 16f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project (byte)'h', (byte)'i', (byte)'j', (byte)'k', (byte)'l', (byte)'m', (byte)'n', 17f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project (byte)'o', (byte)'p', (byte)'q', (byte)'r', (byte)'s', (byte)'t', (byte)'u', 18f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project (byte)'v', 19f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project (byte)'w', (byte)'x', (byte)'y', (byte)'z', 20f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project (byte)'0', (byte)'1', (byte)'2', (byte)'3', (byte)'4', (byte)'5', (byte)'6', 21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project (byte)'7', (byte)'8', (byte)'9', 22f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project (byte)'+', (byte)'/' 23f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project }; 24f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project protected byte padding = (byte)'='; 26f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 27f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * set up the decoding table. 29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 30f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project protected final byte[] decodingTable = new byte[128]; 31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 32f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project protected void initialiseDecodingTable() 33f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 34f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (int i = 0; i < encodingTable.length; i++) 35f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 36f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project decodingTable[encodingTable[i]] = (byte)i; 37f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 38f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 39f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 40f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public Base64Encoder() 41f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 42f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project initialiseDecodingTable(); 43f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 44f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 45f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 46f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * encode the input data producing a base 64 output stream. 47f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 48f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return the number of bytes produced. 49f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 50f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public int encode( 51f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project byte[] data, 52f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int off, 53f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int length, 54f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project OutputStream out) 55f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throws IOException 56f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 57f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int modulus = length % 3; 58f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int dataLength = (length - modulus); 59f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int a1, a2, a3; 60f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 61f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (int i = off; i < off + dataLength; i += 3) 62f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 63f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project a1 = data[i] & 0xff; 64f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project a2 = data[i + 1] & 0xff; 65f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project a3 = data[i + 2] & 0xff; 66f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 67f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project out.write(encodingTable[(a1 >>> 2) & 0x3f]); 68f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project out.write(encodingTable[((a1 << 4) | (a2 >>> 4)) & 0x3f]); 69f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project out.write(encodingTable[((a2 << 2) | (a3 >>> 6)) & 0x3f]); 70f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project out.write(encodingTable[a3 & 0x3f]); 71f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 72f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 73f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 74f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * process the tail end. 75f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 76f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int b1, b2, b3; 77f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int d1, d2; 78f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 79f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project switch (modulus) 80f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 81f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 0: /* nothing left to do */ 82f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 83f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 1: 84f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project d1 = data[off + dataLength] & 0xff; 85f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project b1 = (d1 >>> 2) & 0x3f; 86f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project b2 = (d1 << 4) & 0x3f; 87f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 88f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project out.write(encodingTable[b1]); 89f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project out.write(encodingTable[b2]); 90f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project out.write(padding); 91f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project out.write(padding); 92f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 93f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 2: 94f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project d1 = data[off + dataLength] & 0xff; 95f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project d2 = data[off + dataLength + 1] & 0xff; 96f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 97f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project b1 = (d1 >>> 2) & 0x3f; 98f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project b2 = ((d1 << 4) | (d2 >>> 4)) & 0x3f; 99f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project b3 = (d2 << 2) & 0x3f; 100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project out.write(encodingTable[b1]); 102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project out.write(encodingTable[b2]); 103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project out.write(encodingTable[b3]); 104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project out.write(padding); 105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return (dataLength / 3) * 4 + ((modulus == 0) ? 0 : 4); 109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private boolean ignore( 112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char c) 113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return (c == '\n' || c =='\r' || c == '\t' || c == ' '); 115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * decode the base 64 encoded byte data writing it to the given output stream, 119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * whitespace characters will be ignored. 120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return the number of bytes produced. 122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public int decode( 124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project byte[] data, 125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int off, 126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int length, 127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project OutputStream out) 128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throws IOException 129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project byte b1, b2, b3, b4; 131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int outLen = 0; 132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int end = off + length; 134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project while (end > off) 136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!ignore((char)data[end - 1])) 138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project end--; 143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int i = off; 146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int finish = end - 4; 147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project i = nextI(data, i, finish); 149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project while (i < finish) 151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project b1 = decodingTable[data[i++]]; 153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project i = nextI(data, i, finish); 155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project b2 = decodingTable[data[i++]]; 157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project i = nextI(data, i, finish); 159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project b3 = decodingTable[data[i++]]; 161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project i = nextI(data, i, finish); 163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project b4 = decodingTable[data[i++]]; 165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project out.write((b1 << 2) | (b2 >> 4)); 167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project out.write((b2 << 4) | (b3 >> 2)); 168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project out.write((b3 << 6) | b4); 169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project outLen += 3; 171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project i = nextI(data, i, finish); 173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project outLen += decodeLastBlock(out, (char)data[end - 4], (char)data[end - 3], (char)data[end - 2], (char)data[end - 1]); 176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return outLen; 178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private int nextI(byte[] data, int i, int finish) 181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project while ((i < finish) && ignore((char)data[i])) 183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project i++; 185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return i; 187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * decode the base 64 encoded String data writing it to the given output stream, 191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * whitespace characters will be ignored. 192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return the number of bytes produced. 194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public int decode( 196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project String data, 197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project OutputStream out) 198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throws IOException 199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 200f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project byte b1, b2, b3, b4; 201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int length = 0; 202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int end = data.length(); 204f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project while (end > 0) 206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!ignore(data.charAt(end - 1))) 208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project end--; 213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 214f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 215f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int i = 0; 216f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int finish = end - 4; 217f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project i = nextI(data, i, finish); 219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 220f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project while (i < finish) 221f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 222f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project b1 = decodingTable[data.charAt(i++)]; 223f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 224f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project i = nextI(data, i, finish); 225f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project b2 = decodingTable[data.charAt(i++)]; 227f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 228f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project i = nextI(data, i, finish); 229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 230f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project b3 = decodingTable[data.charAt(i++)]; 231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 232f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project i = nextI(data, i, finish); 233f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project b4 = decodingTable[data.charAt(i++)]; 235f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 236f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project out.write((b1 << 2) | (b2 >> 4)); 237f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project out.write((b2 << 4) | (b3 >> 2)); 238f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project out.write((b3 << 6) | b4); 239f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 240f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project length += 3; 241f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 242f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project i = nextI(data, i, finish); 243f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 245f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project length += decodeLastBlock(out, data.charAt(end - 4), data.charAt(end - 3), data.charAt(end - 2), data.charAt(end - 1)); 246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 247f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return length; 248f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 249f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 250f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private int decodeLastBlock(OutputStream out, char c1, char c2, char c3, char c4) 251f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throws IOException 252f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 253f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project byte b1, b2, b3, b4; 254f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 255f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (c3 == padding) 256f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 257f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project b1 = decodingTable[c1]; 258f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project b2 = decodingTable[c2]; 259f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 260f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project out.write((b1 << 2) | (b2 >> 4)); 261f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 262f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return 1; 263f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 264f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project else if (c4 == padding) 265f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 266f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project b1 = decodingTable[c1]; 267f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project b2 = decodingTable[c2]; 268f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project b3 = decodingTable[c3]; 269f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 270f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project out.write((b1 << 2) | (b2 >> 4)); 271f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project out.write((b2 << 4) | (b3 >> 2)); 272f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 273f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return 2; 274f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 275f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project else 276f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 277f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project b1 = decodingTable[c1]; 278f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project b2 = decodingTable[c2]; 279f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project b3 = decodingTable[c3]; 280f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project b4 = decodingTable[c4]; 281f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 282f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project out.write((b1 << 2) | (b2 >> 4)); 283f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project out.write((b2 << 4) | (b3 >> 2)); 284f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project out.write((b3 << 6) | b4); 285f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 286f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return 3; 287f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 288f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 289f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 290f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private int nextI(String data, int i, int finish) 291f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 292f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project while ((i < finish) && ignore(data.charAt(i))) 293f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 294f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project i++; 295f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 296f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return i; 297f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 298f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 299