2 * Copyright (C) 2010 The Android Open Source Project
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 package be
.nikiroo
.utils
.streams
;
19 import java
.io
.FilterOutputStream
;
20 import java
.io
.IOException
;
21 import java
.io
.OutputStream
;
24 * An OutputStream that does Base64 encoding on the data written to
25 * it, writing the resulting data to another OutputStream.
27 public class Base64OutputStream
extends FilterOutputStream
{
28 private final Base64
.Coder coder
;
29 private final int flags
;
31 private byte[] buffer
= null;
34 private static byte[] EMPTY
= new byte[0];
37 * Performs Base64 encoding on the data written to the stream,
38 * writing the encoded data to another OutputStream.
40 * @param out the OutputStream to write the encoded data to
42 public Base64OutputStream(OutputStream out
) {
47 * Performs Base64 encoding or decoding on the data written to the
48 * stream, writing the encoded/decoded data to another
51 * @param out the OutputStream to write the encoded data to
52 * @param encode true to encode, false to decode
56 public Base64OutputStream(OutputStream out
, boolean encode
) {
58 this.flags
= Base64
.NO_WRAP
;
60 coder
= new Base64
.Encoder(flags
, null);
62 coder
= new Base64
.Decoder(flags
, null);
67 public void write(int b
) throws IOException
{
68 // To avoid invoking the encoder/decoder routines for single
69 // bytes, we buffer up calls to write(int) in an internal
70 // byte array to transform them into writes of decently-sized
74 buffer
= new byte[1024];
76 if (bpos
>= buffer
.length
) {
77 // internal buffer full; write it out.
78 internalWrite(buffer
, 0, bpos
, false);
81 buffer
[bpos
++] = (byte) b
;
85 * Flush any buffered data from calls to write(int). Needed
86 * before doing a write(byte[], int, int) or a close().
88 private void flushBuffer() throws IOException
{
90 internalWrite(buffer
, 0, bpos
, false);
96 public void write(byte[] b
, int off
, int len
) throws IOException
{
99 internalWrite(b
, off
, len
, false);
103 public void close() throws IOException
{
104 IOException thrown
= null;
107 internalWrite(EMPTY
, 0, 0, true);
108 } catch (IOException e
) {
113 if ((flags
& Base64
.NO_CLOSE
) == 0) {
118 } catch (IOException e
) {
119 if (thrown
!= null) {
124 if (thrown
!= null) {
130 * Write the given bytes to the encoder/decoder.
132 * @param finish true if this is the last batch of input, to cause
133 * encoder/decoder state to be finalized.
135 private void internalWrite(byte[] b
, int off
, int len
, boolean finish
) throws IOException
{
136 coder
.output
= embiggen(coder
.output
, coder
.maxOutputSize(len
));
137 if (!coder
.process(b
, off
, len
, finish
)) {
138 throw new IOException("bad base-64");
140 out
.write(coder
.output
, 0, coder
.op
);
144 * If b.length is at least len, return b. Otherwise return a new
145 * byte array of length len.
147 private byte[] embiggen(byte[] b
, int len
) {
148 if (b
== null || b
.length
< len
) {
149 return new byte[len
];