public void EndOfStream() { var str = "Hello World!"; using (var ms = new MemoryStream(Encoding.UTF8.GetBytes(str))) using (var bs = new BencodeStream(ms)) { bs.Read(12); Assert.IsTrue(bs.EndOfStream); Assert.AreEqual(-1, bs.Read()); } }
public void PeekAndReadEqual() { var str = "Hello World!"; using (var ms = new MemoryStream(Encoding.UTF8.GetBytes(str))) using (var bs = new BencodeStream(ms)) { Assert.Equal('H', bs.Peek()); Assert.Equal('H', bs.Read()); } }
public void PeekAreChangedAfterRead() { var str = "abcdefghijkl"; using (var ms = new MemoryStream(Encoding.UTF8.GetBytes(str))) using (var bs = new BencodeStream(ms)) { Assert.Equal('a', bs.Peek()); Assert.Equal('a', bs.Read()); Assert.Equal('b', bs.Peek()); Assert.Equal('b', bs.Read()); Assert.Equal('c', bs.Peek()); Assert.Equal('c', bs.Read()); Assert.Equal('d', bs.Peek()); Assert.Equal('d', bs.Read()); Assert.Equal('e', bs.Peek()); Assert.Equal('e', bs.Read()); } }
public void ReadZeroBytes() { using (var ms = new MemoryStream(Encoding.UTF8.GetBytes("Hello World!"))) using (var bs = new BencodeStream(ms)) { var bytes = bs.Read(0); Assert.AreEqual(0, bytes.Length); Assert.AreEqual("", Encoding.UTF8.GetString(bytes)); } }
public void ReadUnnaffectedByReadPrevious() { var str = "abcdefghijkl"; using (var ms = new MemoryStream(Encoding.UTF8.GetBytes(str))) using (var bs = new BencodeStream(ms)) { Assert.AreEqual('a', bs.Read()); bs.ReadPrevious(); Assert.AreEqual('b', bs.Read()); } }
public void ReadPreviousUnaffectedByPeek() { var str = "Hello World!"; using (var ms = new MemoryStream(Encoding.UTF8.GetBytes(str))) using (var bs = new BencodeStream(ms)) { bs.Read(1); Assert.AreEqual('H', bs.ReadPrevious()); Assert.AreEqual('e', bs.Peek()); Assert.AreEqual('H', bs.ReadPrevious()); } }
public void ReadPreviousChar() { var str = "Hello World!"; using (var ms = new MemoryStream(Encoding.UTF8.GetBytes(str))) using (var bs = new BencodeStream(ms)) { Assert.AreEqual(default(char), bs.ReadPreviousChar()); bs.Read(1); Assert.AreEqual('H', bs.ReadPreviousChar()); } }
public void ReadPrevious() { var str = "Hello World!"; using (var ms = new MemoryStream(Encoding.UTF8.GetBytes(str))) using (var bs = new BencodeStream(ms)) { Assert.AreEqual(-1, bs.ReadPrevious()); Assert.AreEqual('H', bs.Read()); Assert.AreEqual('H', bs.ReadPrevious()); Assert.AreEqual('e', bs.Read()); Assert.AreEqual('e', bs.ReadPrevious()); bs.Position = 20; Assert.AreEqual(-1, bs.ReadPrevious()); } }
public void ReadMoreBytesThanInStream() { using (var ms = new MemoryStream(Encoding.UTF8.GetBytes("Hello World!"))) using (var bs = new BencodeStream(ms)) { var bytes = bs.Read(20); Assert.AreEqual(12, bytes.Length); Assert.AreEqual("Hello World!", Encoding.UTF8.GetString(bytes)); } }
public void ReadBytesChangesStreamPosition() { var str = "Hello World!"; using (var ms = new MemoryStream(Encoding.UTF8.GetBytes(str))) using (var bs = new BencodeStream(ms)) { Assert.AreEqual(0, bs.Position); var bytes = bs.Read(str.Length); Assert.AreEqual(12, bytes.Length); Assert.AreEqual(str, Encoding.UTF8.GetString(bytes)); Assert.AreEqual(12, bs.Position); } }
public void Read() { var str = "Hello World!"; using (var ms = new MemoryStream(Encoding.UTF8.GetBytes(str))) using (var bs = new BencodeStream(ms)) { Assert.AreEqual('H', bs.Read()); Assert.AreEqual('e', bs.Read()); Assert.AreEqual('l', bs.Read()); Assert.AreEqual('l', bs.Read()); Assert.AreEqual('o', bs.Read()); Assert.AreEqual(' ', bs.Read()); Assert.AreEqual('W', bs.Read()); Assert.AreEqual('o', bs.Read()); Assert.AreEqual('r', bs.Read()); Assert.AreEqual('l', bs.Read()); Assert.AreEqual('d', bs.Read()); Assert.AreEqual('!', bs.Read()); Assert.AreEqual(-1, bs.Read()); } }
public void PeekAtEndOfStreamThenReadSingleByte() { var str = "abcdefghijkl"; using (var ms = new MemoryStream(Encoding.UTF8.GetBytes(str))) using (var bs = new BencodeStream(ms)) { bs.Read(12); Assert.AreEqual(-1, bs.Peek()); Assert.AreEqual(-1, bs.Read()); } }
public void PeekAreChangedAfterReadSingleByte() { var str = "abcdefghijkl"; using (var ms = new MemoryStream(Encoding.UTF8.GetBytes(str))) using (var bs = new BencodeStream(ms)) { byte[] bytes; Assert.AreEqual('a', bs.Peek()); bytes = bs.Read(1); Assert.AreEqual('a', (char)bytes[0]); Assert.AreEqual('b', bs.Peek()); bytes = bs.Read(1); Assert.AreEqual('b', (char)bytes[0]); Assert.AreEqual('c', bs.Peek()); } }
public static BString DecodeString(BencodeStream stream, Encoding encoding) { if (stream == null) throw new ArgumentNullException("stream"); if (encoding == null) throw new ArgumentNullException("encoding"); // Minimum valid bencode string is '0:' meaning an empty string if (stream.Length < 2) throw new BencodeDecodingException<BString>("Minimum valid stream length is 2 (an empty string: '0:')", stream.Position); var lengthChars = new List<char>(); while (!stream.EndOfStream) { var c = stream.ReadChar(); // Break when we reach ':' if it is not the first character found if (lengthChars.Count > 0 && c == ':') break; // Character then must be a digit if (!c.IsDigit()) { if (lengthChars.Count == 0) throw new BencodeDecodingException<BString>(string.Format("Must begin with an integer but began with '{0}'", c), stream.Position); // We have found some digits but this is neither a digit nor a ':' as expected throw new BencodeDecodingException<BString>("Delimiter ':' was not found.", stream.Position); } // Because of memory limitations (~1-2 GB) we know for certain we cannot handle more than 10 digits (10GB) if (lengthChars.Count >= BString.LengthMaxDigits) { throw new UnsupportedBencodeException( string.Format("Length of string is more than {0} digits (>10GB) and is not supported (max is ~1-2GB).", BString.LengthMaxDigits), stream.Position); } lengthChars.Add(c); } var stringLength = long.Parse(lengthChars.AsString()); // Int32.MaxValue is ~2GB and is the absolute maximum that can be handled in memory if (stringLength > int.MaxValue) { throw new UnsupportedBencodeException( string.Format("Length of string is {0:N0} but maximum supported length is {1:N0}.", stringLength, int.MaxValue), stream.Position); } // TODO: Catch possible OutOfMemoryException when stringLength is close Int32.MaxValue ? var bytes = stream.Read((int)stringLength); // If the two don't match we've reached the end of the stream before reading the expected number of chars if (bytes.Length != stringLength) { throw new BencodeDecodingException<BString>( string.Format("Expected string to be {0:N0} bytes long but could only read {1:N0} bytes.", stringLength, bytes.Length), stream.Position); } return new BString(bytes, encoding); }
public void ReadChangeStreamPosition() { var str = "Hello World!"; using (var ms = new MemoryStream(Encoding.UTF8.GetBytes(str))) using (var bs = new BencodeStream(ms)) { Assert.Equal('H', bs.Read()); Assert.Equal('e', bs.Read()); bs.Position -= 1; Assert.Equal('e', bs.Read()); } }