EncodingByteBuffer
namespace System.Text
{
internal sealed class EncodingByteBuffer
{
private unsafe byte* _bytes;
private unsafe readonly byte* _byteStart;
private unsafe readonly byte* _byteEnd;
private unsafe char* _chars;
private unsafe readonly char* _charStart;
private unsafe readonly char* _charEnd;
private int _byteCountResult;
private readonly EncodingNLS _enc;
private readonly System.Text.EncoderNLS _encoder;
internal EncoderFallbackBuffer fallbackBuffer;
internal EncoderFallbackBufferHelper fallbackBufferHelper;
internal unsafe bool MoreData {
get {
if (fallbackBuffer.Remaining <= 0)
return _chars < _charEnd;
return true;
}
}
internal unsafe int CharsUsed => (int)(_chars - _charStart);
internal int Count => _byteCountResult;
internal unsafe EncodingByteBuffer(EncodingNLS inEncoding, System.Text.EncoderNLS inEncoder, byte* inByteStart, int inByteCount, char* inCharStart, int inCharCount)
{
_enc = inEncoding;
_encoder = inEncoder;
_charStart = inCharStart;
_chars = inCharStart;
_charEnd = inCharStart + inCharCount;
_bytes = inByteStart;
_byteStart = inByteStart;
_byteEnd = inByteStart + inByteCount;
if (_encoder == null)
fallbackBuffer = _enc.EncoderFallback.CreateFallbackBuffer();
else {
fallbackBuffer = _encoder.FallbackBuffer;
if (_encoder.m_throwOnOverflow && _encoder.InternalHasFallbackBuffer && fallbackBuffer.Remaining > 0)
throw new ArgumentException(System.SR.Format(System.SR.Argument_EncoderFallbackNotEmpty, _encoder.Encoding.EncodingName, _encoder.Fallback.GetType()));
}
fallbackBufferHelper = new EncoderFallbackBufferHelper(fallbackBuffer);
fallbackBufferHelper.InternalInitialize(_chars, _charEnd, _encoder, _bytes != null);
}
internal unsafe bool AddByte(byte b, int moreBytesExpected)
{
if (_bytes != null) {
if (_bytes >= _byteEnd - moreBytesExpected) {
MovePrevious(true);
return false;
}
*(_bytes++) = b;
}
_byteCountResult++;
return true;
}
internal bool AddByte(byte b1)
{
return AddByte(b1, 0);
}
internal bool AddByte(byte b1, byte b2)
{
return AddByte(b1, b2, 0);
}
internal bool AddByte(byte b1, byte b2, int moreBytesExpected)
{
if (AddByte(b1, 1 + moreBytesExpected))
return AddByte(b2, moreBytesExpected);
return false;
}
internal bool AddByte(byte b1, byte b2, byte b3)
{
return AddByte(b1, b2, b3, 0);
}
internal bool AddByte(byte b1, byte b2, byte b3, int moreBytesExpected)
{
if (AddByte(b1, 2 + moreBytesExpected) && AddByte(b2, 1 + moreBytesExpected))
return AddByte(b3, moreBytesExpected);
return false;
}
internal bool AddByte(byte b1, byte b2, byte b3, byte b4)
{
if (AddByte(b1, 3) && AddByte(b2, 2) && AddByte(b3, 1))
return AddByte(b4, 0);
return false;
}
internal unsafe void MovePrevious(bool bThrow)
{
if (fallbackBufferHelper.bFallingBack)
fallbackBuffer.MovePrevious();
else if (_chars > _charStart) {
_chars--;
}
if (bThrow)
_enc.ThrowBytesOverflow(_encoder, _bytes == _byteStart);
}
internal unsafe bool Fallback(char charFallback)
{
return fallbackBufferHelper.InternalFallback(charFallback, ref _chars);
}
internal unsafe char GetNextChar()
{
char c = fallbackBufferHelper.InternalGetNextChar();
if (c == '' && _chars < _charEnd) {
char* chars = _chars;
_chars = chars + 1;
c = *chars;
}
return c;
}
}
}