public void ReadExactlyNullInput() { Assert.Throws <ArgumentNullException>(() => { StreamUtil.ReadExactly(null, 10); }); }
public void ReadExactlyZeroBytesToRead() { StreamStub input = new StreamStub(); input.AddReadData(new byte[] { 1, 2, 3, 4, 5 }); StreamUtil.ReadExactly(input, 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); }
public void ReadExactlyZeroBytesToRead() { Assert.Throws <ArgumentOutOfRangeException>(() => { StreamStub input = new StreamStub(); input.AddReadData(new byte[] { 1, 2, 3, 4, 5 }); StreamUtil.ReadExactly(input, 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); }
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); }); }
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(); } }
public void ReadExactlyNullInput() { StreamUtil.ReadExactly(null, 10); }