Example #1
0
        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);
        }
Example #2
0
        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;
                    }
                }
            }
        }
Example #3
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);
        }