/**
* Copyright 2007-2015, Kaazing Corporation. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.kaazing.specification.httpxe.internal;
/**
* Internal class. This class manages the Base64 encoding and decoding
*/
final class Base64 {
private static final byte[] INDEXED = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".getBytes();
private static final byte PADDING_BYTE = (byte) '=';
public static byte[] encode(byte[] decodedArray) {
int decodedSize = decodedArray.length;
int effectiveDecodedSize = ((decodedSize + 2) / 3) * 3;
int decodedFragmentSize = decodedSize % 3;
int encodedArraySize = effectiveDecodedSize / 3 * 4;
byte[] encodedArray = new byte[encodedArraySize];
int encodedArrayPosition = 0;
int decodedArrayOffset = 0;
int decodedArrayPosition = decodedArrayOffset + 0;
int decodedArrayLimit = decodedArrayOffset + decodedArray.length - decodedFragmentSize;
while (decodedArrayPosition < decodedArrayLimit) {
int byte0 = decodedArray[decodedArrayPosition++] & 0xff;
int byte1 = decodedArray[decodedArrayPosition++] & 0xff;
int byte2 = decodedArray[decodedArrayPosition++] & 0xff;
encodedArray[encodedArrayPosition++] = INDEXED[(byte0 >> 2) & 0x3f];
encodedArray[encodedArrayPosition++] = INDEXED[((byte0 << 4) & 0x30) | ((byte1 >> 4) & 0x0f)];
encodedArray[encodedArrayPosition++] = INDEXED[((byte1 << 2) & 0x3c) | ((byte2 >> 6) & 0x03)];
encodedArray[encodedArrayPosition++] = INDEXED[byte2 & 0x3f];
}
if (decodedFragmentSize == 1) {
int byte0 = decodedArray[decodedArrayPosition++] & 0xff;
encodedArray[encodedArrayPosition++] = INDEXED[(byte0 >> 2) & 0x3f];
encodedArray[encodedArrayPosition++] = INDEXED[(byte0 << 4) & 0x30];
encodedArray[encodedArrayPosition++] = PADDING_BYTE;
encodedArray[encodedArrayPosition++] = PADDING_BYTE;
}
else if (decodedFragmentSize == 2) {
int byte0 = decodedArray[decodedArrayPosition++] & 0xff;
int byte1 = decodedArray[decodedArrayPosition++] & 0xff;
encodedArray[encodedArrayPosition++] = INDEXED[(byte0 >> 2) & 0x3f];
encodedArray[encodedArrayPosition++] = INDEXED[((byte0 << 4) & 0x30) | ((byte1 >> 4) & 0x0f)];
encodedArray[encodedArrayPosition++] = INDEXED[(byte1 << 2) & 0x3c];
encodedArray[encodedArrayPosition++] = PADDING_BYTE;
}
return encodedArray;
}
private Base64() {
// utility
}
}