196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project/* ==================================================================== 296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * Copyright (c) 2006 J.T. Beetstra 396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * 496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * Permission is hereby granted, free of charge, to any person obtaining 596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * a copy of this software and associated documentation files (the 696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * "Software"), to deal in the Software without restriction, including 796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * without limitation the rights to use, copy, modify, merge, publish, 896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * distribute, sublicense, and/or sell copies of the Software, and to 996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * permit persons to whom the Software is furnished to do so, subject to 1096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * the following conditions: 1196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * 1296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * The above copyright notice and this permission notice shall be 1396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * included in all copies or substantial portions of the Software. 1496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * 1596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 1696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 1796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 1896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 1996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 2096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 2196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 2296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * ==================================================================== 2396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project */ 2496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project 2596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Projectpackage com.beetstra.jutf7; 2696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project 2796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Projectimport java.util.Arrays; 2896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project 2996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project/** 3096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * <p> 3196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * Represent a base 64 mapping. The 64 characters used in the encoding can be 3296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * specified, since modified-UTF-7 uses other characters than UTF-7 (',' instead 3396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * of '/'). 3496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * </p> 3596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * <p> 3696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * The exact type of the arguments and result values is adapted to the needs of 3796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * the encoder and decoder, as opposed to following a strict interpretation of 3896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * base 64. 3996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * </p> 4096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * <p> 4196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * Base 64, as specified in RFC 2045, is an encoding used to encode bytes as 4296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * characters. In (modified-)UTF-7 however, it is used to encode characters as 4396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * bytes, using some intermediate steps: 4496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * </p> 4596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * <ol> 4696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * <li>Encode all characters as a 16-bit (UTF-16) integer value</li> 4796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * <li>Write this as stream of bytes (most-significant first)</li> 4896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * <li>Encode these bytes using (modified) base 64 encoding</li> 4996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * <li>Write the thus formed stream of characters as a stream of bytes, using 5096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * ASCII encoding</li> 5196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * </ol> 5296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * 5396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * @author Jaap Beetstra 5496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project */ 5596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Projectclass Base64Util { 5696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project private static final int ALPHABET_LENGTH = 64; 5796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project private final char[] alphabet; 5896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project private final int[] inverseAlphabet; 5996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project 6096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project /** 6196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * Initializes the class with the specified encoding/decoding alphabet. 6296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * 6396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * @param alphabet 6496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * @throws IllegalArgumentException if alphabet is not 64 characters long or 6596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * contains characters which are not 7-bit ASCII 6696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project */ 6796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project Base64Util(final String alphabet) { 6896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project this.alphabet = alphabet.toCharArray(); 6996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project if (alphabet.length() != ALPHABET_LENGTH) 7096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project throw new IllegalArgumentException("alphabet has incorrect length (should be 64, not " 7196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project + alphabet.length() + ")"); 7296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project inverseAlphabet = new int[128]; 7396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project Arrays.fill(inverseAlphabet, -1); 7496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project for (int i = 0; i < this.alphabet.length; i++) { 7596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project final char ch = this.alphabet[i]; 7696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project if (ch >= 128) 7796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project throw new IllegalArgumentException("invalid character in alphabet: " + ch); 7896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project inverseAlphabet[ch] = i; 7996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project } 8096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project } 8196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project 8296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project /** 8396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * Returns the integer value of the six bits represented by the specified 8496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * character. 8596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * 8696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * @param ch The character, as a ASCII encoded byte 8796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * @return The six bits, as an integer value, or -1 if the byte is not in 8896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * the alphabet 8996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project */ 9096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project int getSextet(final byte ch) { 9196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project if (ch >= 128) 9296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project return -1; 9396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project return inverseAlphabet[ch]; 9496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project } 9596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project 9696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project /** 9796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * Tells whether the alphabet contains the specified character. 9896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * 9996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * @param ch The character 10096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * @return true if the alphabet contains <code>ch</code>, false otherwise 10196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project */ 10296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project boolean contains(final char ch) { 10396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project if (ch >= 128) 10496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project return false; 10596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project return inverseAlphabet[ch] >= 0; 10696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project } 10796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project 10896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project /** 10996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * Encodes the six bit group as a character. 11096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * 11196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * @param sextet The six bit group to be encoded 11296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * @return The ASCII value of the character 11396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project */ 11496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project byte getChar(final int sextet) { 11596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project return (byte)alphabet[sextet]; 11696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project } 11796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project} 118