using System; namespace Org.BouncyCastle.Utilities.Encoders { /// /// A class that allows encoding of data using a specific encoder to be processed in chunks. /// public class BufferedEncoder { internal byte[] Buffer; internal int bufOff; internal ITranslator translator; /// /// Create. /// /// The translator to use. /// Size of the chunks. public BufferedEncoder( 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. /// /// The byte. /// An array to store output in. /// Offset within output array to start writing from. /// public int ProcessByte( byte input, byte[] outBytes, int outOff) { int resultLen = 0; Buffer[bufOff++] = input; if (bufOff == Buffer.Length) { resultLen = translator.Encode(Buffer, 0, Buffer.Length, outBytes, outOff); bufOff = 0; } return resultLen; } /// /// Process data from a byte array. /// /// Input data Byte array containing data to be processed. /// Start position within input data array. /// Amount of input data to be processed. /// Output data array. /// Offset within output data array to start writing to. /// The amount of data written. 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.Encode(Buffer, 0, Buffer.Length, outBytes, outOff); bufOff = 0; len -= gapLen; inOff += gapLen; outOff += resultLen; int chunkSize = len - (len % Buffer.Length); resultLen += translator.Encode(input, inOff, chunkSize, outBytes, outOff); len -= chunkSize; inOff += chunkSize; } if (len != 0) { Array.Copy(input, inOff, Buffer, bufOff, len); bufOff += len; } return resultLen; } } }