OLD | NEW |
---|---|
(Empty) | |
1 /* Copyright (c) 2002-2013 Sun Microsystems, Inc. All rights reserved | |
2 * | |
3 * This program is distributed under the terms of | |
4 * the GNU General Public License Version 2. See the LICENSE file | |
5 * at the top of the source tree. | |
6 */ | |
7 package org.pantsbuild.jmake; | |
Yaron
2015/09/30 02:19:25
Add to tools/android/eclipse/.classpath ?
agrieve
2015/10/01 16:26:11
Done.
| |
8 | |
9 import java.util.Arrays; | |
10 | |
11 | |
12 /** | |
13 * JMake needs to run against old versions of Java, that may not have JAXB's | |
14 * javax.xml.bind.DatatypeConverter. And we don't want JMake to depend on third- party external libraries, | |
15 * especially not just for this. So we implement a lightweight Base64 converter here ourselves. | |
16 | |
17 * Note that sun.misc.BASE64Encoder is not official API and can go away at any t ime. Plus it inserts | |
18 * line breaks into its emitted string, which is not what we want. So we can't u se that either. | |
19 */ | |
20 | |
21 public class Base64 { | |
22 // The easiest way to grok this code is to think of Base64 as the following chain of | |
23 // conversions (ignoring padding issues): | |
24 // 3 bytes -> 24 bits -> 4 6-bit nibbles -> 4 indexes from 0-63 -> 4 charact ers. | |
25 private static final char[] indexToDigit = | |
26 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".toCha rArray(); | |
27 private static final int[] digitToIndex = new int[128]; | |
28 static { | |
29 assert(indexToDigit.length == 64); | |
30 Arrays.fill(digitToIndex, -1); | |
31 for (int i = 0; i < indexToDigit.length; i++) digitToIndex[(int)indexToD igit[i]] = i; | |
32 } | |
33 | |
34 private Base64() {} | |
35 | |
36 public static char[] encode(byte[] in) { | |
37 char[] ret = new char[(in.length + 2) / 3 * 4]; | |
38 int p = 0; | |
39 int i = 0; | |
40 while (i < in.length) { | |
41 // Lowest 24 bits count. | |
42 int bits = (in[i++] & 0xff) << 16 | (i < in.length ? in[i++] & 0xff : 0) << 8 | (i < in.length ? in[i++] & 0xff : 0); | |
43 ret[p++] = indexToDigit[(bits & 0xfc0000) >> 18]; | |
44 ret[p++] = indexToDigit[(bits & 0x3f000) >> 12]; | |
45 ret[p++] = indexToDigit[(bits & 0xfc0) >> 6]; | |
46 ret[p++] = indexToDigit[bits & 0x3f]; | |
47 } | |
48 assert(p == ret.length); | |
49 int padding = (3 - in.length % 3) % 3; | |
50 for (int j = ret.length - padding; j < ret.length; j++) ret[j] = '='; | |
51 return ret; | |
52 } | |
53 | |
54 public static byte[] decode(char[] in) { | |
55 if (in.length % 4 != 0) throw new IllegalArgumentException("Base64-encod ed string must be of length that is a multiple of 4."); | |
56 int len = in.length; | |
57 while(len > 0 && in[len - 1] == '=') len--; | |
58 int padding = in.length - len; | |
59 byte[] ret = new byte[in.length / 4 * 3 - padding]; | |
60 int i = 0; | |
61 int p = 0; | |
62 while (i < len) { | |
63 char c0 = in[i++]; | |
64 char c1 = in[i++]; | |
65 char c2 = i < len ? in[i++] : 'A'; | |
66 char c3 = i < len ? in[i++] : 'A'; | |
67 if (c0 > 127 || c1 > 127 || c2 > 127 || c3 > 127) throw new IllegalA rgumentException("Invalid Base64 digit in: " + c0 + c1 + c2 + c3); | |
68 int n0 = digitToIndex[c0]; | |
69 int n1 = digitToIndex[c1]; | |
70 int n2 = digitToIndex[c2]; | |
71 int n3 = digitToIndex[c3]; | |
72 if (n0 < 0 || n1 < 0 || n2 < 0 || n3 < 0) throw new IllegalArgumentE xception("Invalid Base64 digit in: " + c0 + c1 + c2 + c3); | |
73 int bits = (n0 << 18) | (n1 << 12) | (n2 << 6) | n3; | |
74 ret[p++] = (byte)((bits & 0xff0000) >> 16); | |
75 if (p < ret.length) ret[p++] = (byte)((bits & 0xff00) >> 8); | |
76 if (p < ret.length) ret[p++] = (byte)(bits & 0xff); | |
77 } | |
78 return ret; | |
79 } | |
80 } | |
OLD | NEW |