예제 #1
0
        private void ParseStreamOnStack(Stream stream, IPartProcessor partProcessor)
        {
            Span <byte> byteSpan   = stackalloc byte[_bufferSize];
            Span <char> stringSpan = stackalloc char[byteSpan.Length / _bytesPerChar * 2];

            ParseStreamInternal(stream, partProcessor, byteSpan, stringSpan);
        }
예제 #2
0
 public void ParseStream(Stream stream, IPartProcessor partProcessor)
 {
     // don't try to allocate more than 300kb on the stack for parsing
     // it easily leads to a stack overflow
     if (_bufferSize < 1024 * 100)
     {
         ParseStreamOnStack(stream, partProcessor);
     }
     else
     {
         ParseStreamOnArrayPool(stream, partProcessor);
     }
 }
예제 #3
0
        private void ParseStreamOnArrayPool(Stream stream, IPartProcessor partProcessor)
        {
            byte[] bytesFromPool = ArrayPool <byte> .Shared.Rent(_bufferSize);

            char[] charsFromPool = ArrayPool <char> .Shared.Rent(bytesFromPool.Length / _bytesPerChar * 2);

            try
            {
                ParseStreamInternal(stream, partProcessor, bytesFromPool, charsFromPool);
            }
            finally
            {
                ArrayPool <byte> .Shared.Return(bytesFromPool);

                ArrayPool <char> .Shared.Return(charsFromPool);
            }
        }
예제 #4
0
        /// <summary>
        /// Parses stringToParse for separator characters and returns parts to the processor.
        /// The tail end of the string will be returned and not passed to the processor if skipAndReturnLastLine is set to true. (Allowing for further composition of the part when using this with a small buffer)
        /// </summary>
        /// <param name="stringToParse"></param>
        /// <param name="processor"></param>
        /// <param name="skipAndReturnLastLine"></param>
        /// <returns>ReadOnlySpan<char>.Empty or the tail end of the stringToParse when skipAndReturnLastLine is set to true.</returns>
        public ReadOnlySpan <char> ExtractParts(ReadOnlySpan <char> stringToParse, IPartProcessor processor, bool skipAndReturnLastLine = false)
        {
            ReadOnlySpan <char> remainingString = stringToParse;

            int remainingStringEnd = remainingString.Length;
            int currentPartEnd     = GetPartEnd(remainingString);

            while (remainingStringEnd > 0 &&
                   currentPartEnd != -1 &&
                   currentPartEnd < remainingStringEnd)
            {
                ReadOnlySpan <char> part = remainingString.Slice(0, currentPartEnd);
                processor.OnPart(part);

                remainingString    = remainingString.Slice(currentPartEnd + 1);
                remainingStringEnd = remainingString.Length;
                currentPartEnd     = GetPartEnd(remainingString);
            }

            if (currentPartEnd == -1)
            {
                ReadOnlySpan <char> part = remainingString.Slice(0, remainingStringEnd);
                if (skipAndReturnLastLine)
                {
                    return(part);
                }
                else
                {
                    if (part.Length > 0)
                    {
                        processor.OnPart(part);
                    }
                }
            }

            return(ReadOnlySpan <char> .Empty);
        }
예제 #5
0
        private void ParseStreamInternal(Stream stream, IPartProcessor partProcessor, Span <byte> byteSpan, Span <char> stringSpan)
        {
            int remainingLength = 0;

            int read = stream.Read(byteSpan);

            while (read > 0)
            {
                Span <char> stringToEncode = stringSpan.Slice(remainingLength, stringSpan.Length - remainingLength);
                int         endOfString    = _encoding.GetChars(byteSpan.Slice(0, read), stringToEncode) + remainingLength;

                ReadOnlySpan <char> remaining = _splitter.ExtractParts(stringSpan.Slice(0, endOfString), partProcessor, true);

                remaining.CopyTo(stringSpan);
                remainingLength = remaining.Length;

                read = stream.Read(byteSpan);
            }

            if (remainingLength > 0)
            {
                partProcessor.OnPart(stringSpan.Slice(0, remainingLength));
            }
        }