private int ConvertData(ReadOnlySpan <char> data, bool flush) { ConvertStatus convertStatus; int inputOffset = 0; int inputLength = data.Length; do { convertStatus = _decoder.Convert(data, inputOffset, inputLength, _outputBuffer, _outputBufferOffset, _outputBufferLength, flush, out var inputUsed, out var outputUsed); inputOffset += inputUsed; inputLength -= inputUsed; _outputBufferOffset += outputUsed; _outputBufferLength -= outputUsed; if ((convertStatus == ConvertStatus.OutputRequired) || (convertStatus == ConvertStatus.Complete)) { _outputStream.Write(_outputBuffer, 0, _outputBufferOffset); _outputBufferOffset = 0; _outputBufferLength = _outputBuffer.Length; } } while (convertStatus == ConvertStatus.OutputRequired); // return number of characters consumed.. return(inputOffset); }
private static void Decode(BinaryCodec encoding, TextReader inputReader, Stream outputStream) { char[] inputBuffer = new char[encoding.MinimumInputBuffer]; byte[] outputBuffer = new byte[encoding.MinimumOutputBuffer]; bool readEof = false; int inputBufferEnd = 0; int outputBufferEnd = 0; int inputBufferUsed; int outputBufferUsed; BinaryDecoder decoder = encoding.GetDecoder(); while (true) { if ((inputBufferEnd < inputBuffer.Length) && (!readEof)) { int charsRead = inputReader.Read(inputBuffer, inputBufferEnd, inputBuffer.Length - inputBufferEnd); if (charsRead == 0) { readEof = true; } inputBufferEnd += charsRead; } // stop when we've read EOF and Convert returns true.. bool finished = ((decoder.Convert(inputBuffer, 0, inputBufferEnd, outputBuffer, 0, outputBuffer.Length, readEof, out inputBufferUsed, out outputBufferUsed)) && (readEof)); // dump any output produced to outputWriter.. outputStream.Write(outputBuffer, 0, outputBufferUsed); if (finished) { break; } // shift input as needed.. if (inputBufferUsed != 0) { if (inputBufferUsed < inputBufferEnd) { Buffer.BlockCopy(inputBuffer, inputBufferUsed * sizeof(char), inputBuffer, 0, (inputBufferEnd - inputBufferUsed) * sizeof(char)); inputBufferEnd -= inputBufferUsed; } else { inputBufferEnd = 0; } } } }
public override int Read(byte[] buffer, int offset, int count) { if (buffer == null) { throw new ArgumentNullException(nameof(buffer)); } if ((offset < 0) || (count < 0)) { throw new ArgumentOutOfRangeException((offset < 0) ? nameof(offset) : nameof(count)); } if (buffer.Length - offset < count) { throw new ArgumentException(Resources.InvalidOffsetCountLength); } if (_inputReader == null) { throw new ObjectDisposedException(GetType().Name); } // nothing to read after ConverStatus becomes Complete.. if (_convertStatus == ConvertStatus.Complete) { return(0); } int totalRead = 0; while (count > 0) { if (_convertStatus == ConvertStatus.InputRequired) { FillInputBuffer(); } _convertStatus = _decoder.Convert(_inputBuffer, _inputBufferOffset, _inputBufferEnd - _inputBufferOffset, buffer, offset, count, _isEos, out var inputUsed, out var outputUsed); _inputBufferOffset += inputUsed; offset += outputUsed; count -= outputUsed; totalRead += outputUsed; // if we've run out of output buffer or finished converting, then stop looping.. if ((_convertStatus == ConvertStatus.OutputRequired) || (_convertStatus == ConvertStatus.Complete)) { break; } // if we've already had a partial read from the input, then we'll stop and wait // for the next call to Read to access the underlying input reader again (unless we // haven't produced any output yet, in which case we need to continue reading) if ((_isBlocked) && (totalRead > 0)) { break; } } _isBlocked = false; _outputTotal += totalRead; return(totalRead); }