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.nio.ByteBuffer; 2896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Projectimport java.nio.CharBuffer; 2996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Projectimport java.nio.charset.CharsetEncoder; 3096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Projectimport java.nio.charset.CoderResult; 3196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project 3296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project/** 3396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * <p> 3496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * The CharsetEncoder used to encode both variants of the UTF-7 charset and the 3596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * modified-UTF-7 charset. 3696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * </p> 3796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * <p> 3896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * <strong>Please note this class does not behave strictly according to the 3996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * specification in Sun Java VMs before 1.6.</strong> This is done to get around 4096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * a bug in the implementation of 4196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * {@link java.nio.charset.CharsetEncoder#encode(CharBuffer)}. Unfortunately, 4296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * that method cannot be overridden. 4396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * </p> 4496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * 4596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * @see <a href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6221056">JDK 4696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * bug 6221056< /a> 4796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * @author Jaap Beetstra 4896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project */ 4996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Projectclass UTF7StyleCharsetEncoder extends CharsetEncoder { 5096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project private static final float AVG_BYTES_PER_CHAR = 1.5f; 5196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project private static final float MAX_BYTES_PER_CHAR = 5.0f; 5296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project private final UTF7StyleCharset cs; 5396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project private final Base64Util base64; 5496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project private final byte shift; 5596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project private final byte unshift; 5696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project private final boolean strict; 5796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project private boolean base64mode; 5896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project private int bitsToOutput; 5996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project private int sextet; 6096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project static boolean useUglyHackToForceCallToFlushInJava5; 6196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project static { 6296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project String version = System.getProperty("java.specification.version"); 6396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project String vendor = System.getProperty("java.vm.vendor"); 6496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project useUglyHackToForceCallToFlushInJava5 = "1.4".equals(version) || "1.5".equals(version); 6596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project useUglyHackToForceCallToFlushInJava5 &= "Sun Microsystems Inc.".equals(vendor); 6696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project } 6796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project 6896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project UTF7StyleCharsetEncoder(UTF7StyleCharset cs, Base64Util base64, boolean strict) { 6996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project super(cs, AVG_BYTES_PER_CHAR, MAX_BYTES_PER_CHAR); 7096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project this.cs = cs; 7196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project this.base64 = base64; 7296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project this.strict = strict; 7396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project this.shift = cs.shift(); 7496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project this.unshift = cs.unshift(); 7596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project } 7696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project 7796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project /* 7896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * (non-Javadoc) 7996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * @see java.nio.charset.CharsetEncoder#implReset() 8096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project */ 8196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project protected void implReset() { 8296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project base64mode = false; 8396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project sextet = 0; 8496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project bitsToOutput = 0; 8596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project } 8696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project 8796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project /** 8896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * {@inheritDoc} 8996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * <p> 9096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * Note that this method might return <code>CoderResult.OVERFLOW</code> (as 9196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * is required by the specification) if insufficient space is available in 9296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * the output buffer. However, calling it again on JDKs before Java 6 9396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * triggers a bug in 9496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * {@link java.nio.charset.CharsetEncoder#flush(ByteBuffer)} causing it to 9596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * throw an IllegalStateException (the buggy method is <code>final</code>, 9696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * thus cannot be overridden). 9796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * </p> 9896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * 9996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * @see <a 10096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6227608"> 10196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * JDK bug 6227608< /a> 10296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * @param out The output byte buffer 10396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * @return A coder-result object describing the reason for termination 10496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project */ 10596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project protected CoderResult implFlush(ByteBuffer out) { 10696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project if (base64mode) { 10796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project if (out.remaining() < 2) 10896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project return CoderResult.OVERFLOW; 10996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project if (bitsToOutput != 0) 11096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project out.put(base64.getChar(sextet)); 11196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project out.put(unshift); 11296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project } 11396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project return CoderResult.UNDERFLOW; 11496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project } 11596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project 11696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project /** 11796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * {@inheritDoc} 11896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * <p> 11996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * Note that this method might return <code>CoderResult.OVERFLOW</code>, 12096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * even though there is sufficient space available in the output buffer. 12196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * This is done to force the broken implementation of 12296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * {@link java.nio.charset.CharsetEncoder#encode(CharBuffer)} to call flush 12396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * (the buggy method is <code>final</code>, thus cannot be overridden). 12496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * </p> 12596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * <p> 12696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * However, String.getBytes() fails if CoderResult.OVERFLOW is returned, 12796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * since this assumes it always allocates sufficient bytes (maxBytesPerChar 12896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * * nr_of_chars). Thus, as an extra check, the size of the input buffer is 12996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * compared against the size of the output buffer. A static variable is used 13096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * to indicate if a broken java version is used. 13196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * </p> 13296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * <p> 13396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * It is not possible to directly write the last few bytes, since more bytes 13496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * might be waiting to be encoded then those available in the input buffer. 13596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * </p> 13696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * 13796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * @see <a 13896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6221056"> 13996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * JDK bug 6221056< /a> 14096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * @param in The input character buffer 14196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * @param out The output byte buffer 14296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * @return A coder-result object describing the reason for termination 14396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project */ 14496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project protected CoderResult encodeLoop(CharBuffer in, ByteBuffer out) { 14596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project while (in.hasRemaining()) { 14696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project if (out.remaining() < 4) 14796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project return CoderResult.OVERFLOW; 14896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project char ch = in.get(); 14996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project if (cs.canEncodeDirectly(ch)) { 15096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project unshift(out, ch); 15196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project out.put((byte)ch); 15296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project } else if (!base64mode && ch == shift) { 15396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project out.put(shift); 15496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project out.put(unshift); 15596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project } else 15696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project encodeBase64(ch, out); 15796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project } 15896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project /* 15996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * <HACK type="ugly"> These lines are required to trick JDK 1.5 and 16096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * earlier into flushing when using Charset.encode(String), 16196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * Charset.encode(CharBuffer) or CharsetEncoder.encode(CharBuffer) 16296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * Without them, the last few bytes may be missing. 16396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project */ 16496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project if (base64mode && useUglyHackToForceCallToFlushInJava5 16596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project && out.limit() != MAX_BYTES_PER_CHAR * in.limit()) 16696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project return CoderResult.OVERFLOW; 16796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project /* </HACK> */ 16896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project return CoderResult.UNDERFLOW; 16996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project } 17096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project 17196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project /** 17296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * <p> 17396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * Writes the bytes necessary to leave <i>base 64 mode</i>. This might 17496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * include an unshift character. 17596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * </p> 17696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * 17796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * @param out 17896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * @param ch 17996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project */ 18096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project private void unshift(ByteBuffer out, char ch) { 18196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project if (!base64mode) 18296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project return; 18396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project if (bitsToOutput != 0) 18496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project out.put(base64.getChar(sextet)); 18596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project if (base64.contains(ch) || ch == unshift || strict) 18696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project out.put(unshift); 18796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project base64mode = false; 18896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project sextet = 0; 18996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project bitsToOutput = 0; 19096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project } 19196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project 19296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project /** 19396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * <p> 19496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * Writes the bytes necessary to encode a character in <i>base 64 mode</i>. 19596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * All bytes which are fully determined will be written. The fields 19696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * <code>bitsToOutput</code> and <code>sextet</code> are used to remember 19796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * the bytes not yet fully determined. 19896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * </p> 19996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * 20096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * @param out 20196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * @param ch 20296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project */ 20396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project private void encodeBase64(char ch, ByteBuffer out) { 20496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project if (!base64mode) 20596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project out.put(shift); 20696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project base64mode = true; 20796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project bitsToOutput += 16; 20896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project while (bitsToOutput >= 6) { 20996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project bitsToOutput -= 6; 21096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project sextet += (ch >> bitsToOutput); 21196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project sextet &= 0x3F; 21296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project out.put(base64.getChar(sextet)); 21396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project sextet = 0; 21496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project } 21596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project sextet = (ch << (6 - bitsToOutput)) & 0x3F; 21696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project } 21796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project} 218