]>
Commit | Line | Data |
---|---|---|
f67539c2 TL |
1 | /* |
2 | * Licensed to the Apache Software Foundation (ASF) under one | |
3 | * or more contributor license agreements. See the NOTICE file | |
4 | * distributed with this work for additional information | |
5 | * regarding copyright ownership. The ASF licenses this file | |
6 | * to you under the Apache License, Version 2.0 (the | |
7 | * "License"); you may not use this file except in compliance | |
8 | * with the License. You may obtain a copy of the License at | |
9 | * | |
10 | * http://www.apache.org/licenses/LICENSE-2.0 | |
11 | * | |
12 | * Unless required by applicable law or agreed to in writing, | |
13 | * software distributed under the License is distributed on an | |
14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | |
15 | * KIND, either express or implied. See the License for the | |
16 | * specific language governing permissions and limitations | |
17 | * under the License. | |
18 | */ | |
19 | ||
20 | package org.apache.thrift.protocol; | |
21 | ||
22 | /** | |
23 | * Class for encoding and decoding Base64 data. | |
24 | * | |
25 | * This class is kept at package level because the interface does no input | |
26 | * validation and is therefore too low-level for generalized reuse. | |
27 | * | |
28 | * Note also that the encoding does not pad with equal signs , as discussed in | |
29 | * section 2.2 of the RFC (http://www.faqs.org/rfcs/rfc3548.html). Furthermore, | |
30 | * bad data encountered when decoding is neither rejected or ignored but simply | |
31 | * results in bad decoded data -- this is not in compliance with the RFC but is | |
32 | * done in the interest of performance. | |
33 | * | |
34 | */ | |
35 | class TBase64Utils { | |
36 | ||
37 | private static final String ENCODE_TABLE = | |
38 | "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; | |
39 | ||
40 | /** | |
41 | * Encode len bytes of data in src at offset srcOff, storing the result into | |
42 | * dst at offset dstOff. len must be 1, 2, or 3. dst must have at least len+1 | |
43 | * bytes of space at dstOff. src and dst should not be the same object. This | |
44 | * method does no validation of the input values in the interest of | |
45 | * performance. | |
46 | * | |
47 | * @param src the source of bytes to encode | |
48 | * @param srcOff the offset into the source to read the unencoded bytes | |
49 | * @param len the number of bytes to encode (must be 1, 2, or 3). | |
50 | * @param dst the destination for the encoding | |
51 | * @param dstOff the offset into the destination to place the encoded bytes | |
52 | */ | |
53 | static final void encode(byte[] src, int srcOff, int len, byte[] dst, | |
54 | int dstOff) { | |
55 | dst[dstOff] = (byte)ENCODE_TABLE.charAt((src[srcOff] >> 2) & 0x3F); | |
56 | if (len == 3) { | |
57 | dst[dstOff + 1] = | |
58 | (byte)ENCODE_TABLE.charAt( | |
59 | ((src[srcOff] << 4) & 0x30) | ((src[srcOff+1] >> 4) & 0x0F)); | |
60 | dst[dstOff + 2] = | |
61 | (byte)ENCODE_TABLE.charAt( | |
62 | ((src[srcOff+1] << 2) & 0x3C) | ((src[srcOff+2] >> 6) & 0x03)); | |
63 | dst[dstOff + 3] = | |
64 | (byte)ENCODE_TABLE.charAt(src[srcOff+2] & 0x3F); | |
65 | } | |
66 | else if (len == 2) { | |
67 | dst[dstOff+1] = | |
68 | (byte)ENCODE_TABLE.charAt( | |
69 | ((src[srcOff] << 4) & 0x30) | ((src[srcOff+1] >> 4) & 0x0F)); | |
70 | dst[dstOff + 2] = | |
71 | (byte)ENCODE_TABLE.charAt((src[srcOff+1] << 2) & 0x3C); | |
72 | } | |
73 | else { // len == 1) { | |
74 | dst[dstOff + 1] = | |
75 | (byte)ENCODE_TABLE.charAt((src[srcOff] << 4) & 0x30); | |
76 | } | |
77 | } | |
78 | ||
79 | private static final byte[] DECODE_TABLE = { | |
80 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, | |
81 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, | |
82 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,62,-1,-1,-1,63, | |
83 | 52,53,54,55,56,57,58,59,60,61,-1,-1,-1,-1,-1,-1, | |
84 | -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14, | |
85 | 15,16,17,18,19,20,21,22,23,24,25,-1,-1,-1,-1,-1, | |
86 | -1,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40, | |
87 | 41,42,43,44,45,46,47,48,49,50,51,-1,-1,-1,-1,-1, | |
88 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, | |
89 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, | |
90 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, | |
91 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, | |
92 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, | |
93 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, | |
94 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, | |
95 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, | |
96 | }; | |
97 | ||
98 | /** | |
99 | * Decode len bytes of data in src at offset srcOff, storing the result into | |
100 | * dst at offset dstOff. len must be 2, 3, or 4. dst must have at least len-1 | |
101 | * bytes of space at dstOff. src and dst may be the same object as long as | |
102 | * dstoff <= srcOff. This method does no validation of the input values in | |
103 | * the interest of performance. | |
104 | * | |
105 | * @param src the source of bytes to decode | |
106 | * @param srcOff the offset into the source to read the encoded bytes | |
107 | * @param len the number of bytes to decode (must be 2, 3, or 4) | |
108 | * @param dst the destination for the decoding | |
109 | * @param dstOff the offset into the destination to place the decoded bytes | |
110 | */ | |
111 | static final void decode(byte[] src, int srcOff, int len, byte[] dst, | |
112 | int dstOff) { | |
113 | dst[dstOff] = (byte) | |
114 | ((DECODE_TABLE[src[srcOff] & 0x0FF] << 2) | | |
115 | (DECODE_TABLE[src[srcOff+1] & 0x0FF] >> 4)); | |
116 | if (len > 2) { | |
117 | dst[dstOff+1] = (byte) | |
118 | (((DECODE_TABLE[src[srcOff+1] & 0x0FF] << 4) & 0xF0) | | |
119 | (DECODE_TABLE[src[srcOff+2] & 0x0FF] >> 2)); | |
120 | if (len > 3) { | |
121 | dst[dstOff+2] = (byte) | |
122 | (((DECODE_TABLE[src[srcOff+2] & 0x0FF] << 6) & 0xC0) | | |
123 | DECODE_TABLE[src[srcOff+3] & 0x0FF]); | |
124 | } | |
125 | } | |
126 | } | |
127 | } |