using System;
namespace Org.BouncyCastle.Utilities.Encoders
{
///
/// A buffering class to allow translation from one format to another to
/// be done in discrete chunks.
///
public class BufferedDecoder
{
internal byte[] buffer;
internal int bufOff;
internal ITranslator translator;
///
/// Create a buffered Decoder.
///
/// The translater to use.
/// The size of the buffer.
public BufferedDecoder(
ITranslator translator,
int bufferSize)
{
this.translator = translator;
if ((bufferSize % translator.GetEncodedBlockSize()) != 0)
{
throw new ArgumentException("buffer size not multiple of input block size");
}
buffer = new byte[bufferSize];
// bufOff = 0;
}
///
/// Process one byte of data.
///
/// Data in.
/// Byte array for the output.
/// The offset in the output byte array to start writing from.
/// The amount of output bytes.
public int ProcessByte(
byte input,
byte[] output,
int outOff)
{
int resultLen = 0;
buffer[bufOff++] = input;
if (bufOff == buffer.Length)
{
resultLen = translator.Decode(buffer, 0, buffer.Length, output, outOff);
bufOff = 0;
}
return resultLen;
}
///
/// Process data from a byte array.
///
/// The input data.
/// Start position within input data array.
/// Amount of data to process from input data array.
/// Array to store output.
/// Position in output array to start writing from.
/// The amount of output bytes.
public int ProcessBytes(
byte[] input,
int inOff,
int len,
byte[] outBytes,
int outOff)
{
if (len < 0)
{
throw new ArgumentException("Can't have a negative input length!");
}
int resultLen = 0;
int gapLen = buffer.Length - bufOff;
if (len > gapLen)
{
Array.Copy(input, inOff, buffer, bufOff, gapLen);
resultLen += translator.Decode(buffer, 0, buffer.Length, outBytes, outOff);
bufOff = 0;
len -= gapLen;
inOff += gapLen;
outOff += resultLen;
int chunkSize = len - (len % buffer.Length);
resultLen += translator.Decode(input, inOff, chunkSize, outBytes, outOff);
len -= chunkSize;
inOff += chunkSize;
}
if (len != 0)
{
Array.Copy(input, inOff, buffer, bufOff, len);
bufOff += len;
}
return resultLen;
}
}
}