Пример #1
0
 public void ReadExactlyNullInput()
 {
     Assert.Throws <ArgumentNullException>(() =>
     {
         StreamUtil.ReadExactly(null, 10);
     });
 }
Пример #2
0
        public void ReadExactlyZeroBytesToRead()
        {
            StreamStub input = new StreamStub();

            input.AddReadData(new byte[] { 1, 2, 3, 4, 5 });
            StreamUtil.ReadExactly(input, 0);
        }
Пример #3
0
        public void ReadExactlyExactlyRightAmountOfData()
        {
            StreamStub input = new StreamStub();

            input.AddReadData(new byte[] { 1, 2, 3, 4, 5 });
            input.AddReadData(new byte[] { 6, 7, 8, 9, 10 });
            byte[] actual = StreamUtil.ReadExactly(input, 10);
            Assert.AreEqual(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }, actual);
        }
Пример #4
0
 public void ReadExactlyZeroBytesToRead()
 {
     Assert.Throws <ArgumentOutOfRangeException>(() =>
     {
         StreamStub input = new StreamStub();
         input.AddReadData(new byte[] { 1, 2, 3, 4, 5 });
         StreamUtil.ReadExactly(input, 0);
     });
 }
Пример #5
0
        public void ReadExactlyExcessData()
        {
            StreamStub input = new StreamStub();

            input.AddReadData(new byte[] { 1, 2, 3, 4, 5 });
            input.AddReadData(new byte[] { 6, 7, 8, 9 });
            input.AddReadData(new byte[] { 10, 11, 12, 13, 14 });
            byte[] actual = StreamUtil.ReadExactly(input, 9);
            Assert.AreEqual(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 }, actual);
            Assert.AreEqual(4, input.LastReadSize);
        }
Пример #6
0
 public void ReadExactlyNotEnoughData()
 {
     Assert.Throws <EndOfStreamException>(() =>
     {
         StreamStub input = new StreamStub();
         input.AddReadData(new byte[] { 1, 2, 3, 4, 5 });
         input.AddReadData(new byte[] { 6, 7, 8, 9, 10 });
         byte[] actual = StreamUtil.ReadExactly(input, 11);
         Assert.AreEqual(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }, actual);
     });
 }
Пример #7
0
        private IEnumerator <string> GetEnumeratorImpl(Stream stream)
        {
            try
            {
                long position = stream.Length;

                if (encoding is UnicodeEncoding && (position & 1) != 0)
                {
                    throw new InvalidDataException("UTF-16 encoding provided, but stream has odd length.");
                }

                // Allow up to two bytes for data from the start of the previous
                // read which didn't quite make it as full characters
                byte[] buffer       = new byte[bufferSize + 2];
                char[] charBuffer   = new char[encoding.GetMaxCharCount(buffer.Length)];
                int    leftOverData = 0;
                String previousEnd  = null;
                // TextReader doesn't return an empty string if there's line break at the end
                // of the data. Therefore we don't return an empty string if it's our *first*
                // return.
                bool firstYield = true;

                // A line-feed at the start of the previous buffer means we need to swallow
                // the carriage-return at the end of this buffer - hence this needs declaring
                // way up here!
                bool swallowCarriageReturn = false;

                while (position > 0)
                {
                    int bytesToRead = Math.Min(position > int.MaxValue ? bufferSize : (int)position, bufferSize);

                    position       -= bytesToRead;
                    stream.Position = position;
                    StreamUtil.ReadExactly(stream, buffer, bytesToRead);
                    // If we haven't read a full buffer, but we had bytes left
                    // over from before, copy them to the end of the buffer
                    if (leftOverData > 0 && bytesToRead != bufferSize)
                    {
                        // Buffer.BlockCopy doesn't document its behaviour with respect
                        // to overlapping data: we *might* just have read 7 bytes instead of
                        // 8, and have two bytes to copy...
                        Array.Copy(buffer, bufferSize, buffer, bytesToRead, leftOverData);
                    }
                    // We've now *effectively* read this much data.
                    bytesToRead += leftOverData;

                    int firstCharPosition = 0;
                    while (!characterStartDetector(position + firstCharPosition, buffer[firstCharPosition]))
                    {
                        firstCharPosition++;
                        // Bad UTF-8 sequences could trigger this. For UTF-8 we should always
                        // see a valid character start in every 3 bytes, and if this is the start of the file
                        // so we've done a short read, we should have the character start
                        // somewhere in the usable buffer.
                        if (firstCharPosition == 3 || firstCharPosition == bytesToRead)
                        {
                            throw new InvalidDataException("Invalid UTF-8 data");
                        }
                    }
                    leftOverData = firstCharPosition;

                    int charsRead    = encoding.GetChars(buffer, firstCharPosition, bytesToRead - firstCharPosition, charBuffer, 0);
                    int endExclusive = charsRead;

                    for (int i = charsRead - 1; i >= 0; i--)
                    {
                        char lookingAt = charBuffer[i];
                        if (swallowCarriageReturn)
                        {
                            swallowCarriageReturn = false;
                            if (lookingAt == '\r')
                            {
                                endExclusive--;
                                continue;
                            }
                        }
                        // Anything non-line-breaking, just keep looking backwards
                        if (lookingAt != '\n' && lookingAt != '\r')
                        {
                            continue;
                        }
                        // End of CRLF? Swallow the preceding CR
                        if (lookingAt == '\n')
                        {
                            swallowCarriageReturn = true;
                        }
                        int    start          = i + 1;
                        string bufferContents = new string(charBuffer, start, endExclusive - start);
                        endExclusive = i;
                        string stringToYield = previousEnd == null ? bufferContents : bufferContents + previousEnd;
                        if (!firstYield || stringToYield.Length != 0)
                        {
                            yield return(stringToYield);
                        }
                        firstYield  = false;
                        previousEnd = null;
                    }

                    previousEnd = endExclusive == 0 ? null : (new string(charBuffer, 0, endExclusive) + previousEnd);

                    // If we didn't decode the start of the array, put it at the end for next time
                    if (leftOverData != 0)
                    {
                        Buffer.BlockCopy(buffer, 0, buffer, bufferSize, leftOverData);
                    }
                }
                if (leftOverData != 0)
                {
                    // At the start of the final buffer, we had the end of another character.
                    throw new InvalidDataException("Invalid UTF-8 data at start of stream");
                }
                if (firstYield && string.IsNullOrEmpty(previousEnd))
                {
                    yield break;
                }
                yield return(previousEnd ?? "");
            }
            finally
            {
                stream.Dispose();
            }
        }
Пример #8
0
 public void ReadExactlyNullInput()
 {
     StreamUtil.ReadExactly(null, 10);
 }