blob: 2b1c427fe337d0a64f8bf9204f3860b06de56571 [file] [log] [blame]
package org.bouncycastle.est;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import org.bouncycastle.util.encoders.Base64;
class CTEBase64InputStream
extends InputStream
{
protected final InputStream src;
protected final byte[] rawBuf = new byte[1024];
protected final byte[] data = new byte[768];
protected final OutputStream dataOutputStream;
protected final Long max;
protected int rp;
protected int wp;
protected boolean end;
protected long read;
public CTEBase64InputStream(InputStream src, Long limit)
{
this.src = src;
this.dataOutputStream = new OutputStream()
{
public void write(int b)
throws IOException
{
data[wp++] = (byte)b;
}
};
this.max = limit;
}
// Pulls a line from the source, decodes it and returns the decoded length.
// Or returns -1 if there is nothing more to read and nothing was read in this pass.
protected int pullFromSrc()
throws IOException
{
if (this.read >= this.max)
{
return -1;
}
int j = 0;
int c = 0;
do
{
j = src.read();
/*
* RFC2045 All line breaks or other characters not
* found in Table 1 must be ignored by decoding software.
* https://tools.ietf.org/html/rfc2045#section-6.8
* This uses the line brakes to to stop reading data and to decode a chunk.
*/
if (j >= 33 || (j == '\r' || j == '\n'))
{
if (c >= rawBuf.length)
{
throw new IOException("Content Transfer Encoding, base64 line length > 1024");
}
rawBuf[c++] = (byte)j;
read += 1;
}
else if (j >= 0)
{
read += 1;
}
}
while (j > -1 && c < rawBuf.length && j != 10 && this.read < this.max);
if (c > 0)
{
try
{
Base64.decode(rawBuf, 0, c, dataOutputStream);
}
catch (Exception ex)
{
throw new IOException("Decode Base64 Content-Transfer-Encoding: " + ex);
}
}
else
{
if (j == -1)
{
return -1;
}
}
return wp;
}
public int read()
throws IOException
{
// When we have read up to the write pointer (wp) pull some more.
if (rp == wp)
{
rp = 0;
wp = 0;
int i = pullFromSrc();
if (i == -1)
{
return i;
}
}
return data[rp++] & 0xFF;
}
public void close()
throws IOException
{
src.close();
}
}