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
.FilterInputStream
;
20 import java
.io
.IOException
;
21 import java
.io
.InputStream
;
24 * An InputStream that does Base64 decoding on the data read through
27 public class Base64InputStream
extends FilterInputStream
{
28 private final Base64
.Coder coder
;
30 private static byte[] EMPTY
= new byte[0];
32 private static final int BUFFER_SIZE
= 2048;
34 private byte[] inputBuffer
;
35 private int outputStart
;
36 private int outputEnd
;
39 * An InputStream that performs Base64 decoding on the data read
40 * from the wrapped stream.
42 * @param in the InputStream to read the source data from
44 public Base64InputStream(InputStream in
) {
49 * Performs Base64 encoding or decoding on the data read from the
50 * wrapped InputStream.
52 * @param in the InputStream to read the source data from
53 * @param flags bit flags for controlling the decoder; see the
54 * constants in {@link Base64}
55 * @param encode true to encode, false to decode
59 public Base64InputStream(InputStream in
, boolean encode
) {
62 inputBuffer
= new byte[BUFFER_SIZE
];
64 coder
= new Base64
.Encoder(Base64
.NO_WRAP
, null);
66 coder
= new Base64
.Decoder(Base64
.NO_WRAP
, null);
68 coder
.output
= new byte[coder
.maxOutputSize(BUFFER_SIZE
)];
74 public boolean markSupported() {
78 @SuppressWarnings("sync-override")
80 public void mark(int readlimit
) {
81 throw new UnsupportedOperationException();
84 @SuppressWarnings("sync-override")
87 throw new UnsupportedOperationException();
91 public void close() throws IOException
{
97 public int available() {
98 return outputEnd
- outputStart
;
102 public long skip(long n
) throws IOException
{
103 if (outputStart
>= outputEnd
) {
106 if (outputStart
>= outputEnd
) {
109 long bytes
= Math
.min(n
, outputEnd
-outputStart
);
110 outputStart
+= bytes
;
115 public int read() throws IOException
{
116 if (outputStart
>= outputEnd
) {
119 if (outputStart
>= outputEnd
) {
123 return coder
.output
[outputStart
++] & 0xff;
127 public int read(byte[] b
, int off
, int len
) throws IOException
{
128 if (outputStart
>= outputEnd
) {
131 if (outputStart
>= outputEnd
) {
134 int bytes
= Math
.min(len
, outputEnd
-outputStart
);
135 System
.arraycopy(coder
.output
, outputStart
, b
, off
, bytes
);
136 outputStart
+= bytes
;
141 * Read data from the input stream into inputBuffer, then
142 * decode/encode it into the empty coder.output, and reset the
143 * outputStart and outputEnd pointers.
145 private void refill() throws IOException
{
147 int bytesRead
= in
.read(inputBuffer
);
149 if (bytesRead
== -1) {
151 success
= coder
.process(EMPTY
, 0, 0, true);
153 success
= coder
.process(inputBuffer
, 0, bytesRead
, false);
156 throw new IOException("bad base-64");
158 outputEnd
= coder
.op
;