public void SetLength_NoModify() { BlockStream s; BlockArray ba; byte[] buf; int cb; ba = new BlockArray(new Block(new byte[] { 0, 1, 2, 3, 4 }), new Block(new byte[] { 5, 6, 7, 8, 9 })); s = new BlockStream(ba); Assert.Equal(10, s.Length); s.Position = 10; s.SetLength(5, false); Assert.Equal(5, s.Length); Assert.Equal(5, s.Position); Assert.Equal(2, ba.Count); s.Position = 0; buf = new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; cb = s.Read(buf, 0, 10); Assert.Equal(5, cb); Assert.Equal(new byte[] { 0, 1, 2, 3, 4, 0, 0, 0, 0, 0 }, buf); s.Position = 0; s.SetLength(10, false); buf = new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; cb = s.Read(buf, 0, 10); Assert.Equal(10, cb); Assert.Equal(new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }, buf); }
public void SetLength_Modify() { BlockStream s; byte[] r = new byte[10]; byte[] w = new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; byte[] c = new byte[10]; s = new BlockStream(); s.SetLength(100000, true); Assert.Equal(100000, s.Length); Assert.Equal(0, s.Position); s.Position = 50000; s.Write(w, 0, 10); Assert.Equal(50010, s.Position); s.SetLength(50005, true); Assert.Equal(50005, s.Length); Assert.Equal(50005, s.Position); s.Position = 50000; Zero(r); Assert.Equal(5, s.Read(r, 0, 10)); Assert.Equal(new byte[] { 0, 1, 2, 3, 4, 0, 0, 0, 0, 0 }, r); s.SetLength(0, true); Assert.Equal(0, s.Length); Assert.Equal(0, s.Position); }
public void NotImplementedMethods() { using (var ms = new MemoryStream()) { // ReSharper disable AccessToDisposedClosure using (var writer = new BlockStream(Zstd, ms, CompressionMode.Compress, true)) { Assert.Throws <NotSupportedException>(delegate { // ReSharper disable once UnusedVariable long len = writer.Length; }); Assert.Throws <NotSupportedException>(delegate { writer.SetLength(10); }); Assert.Throws <NotSupportedException>(delegate { writer.Seek(0, SeekOrigin.Begin); }); Assert.Throws <NotSupportedException>(delegate { writer.Position = 0; }); } // ReSharper restore AccessToDisposedClosure } }
public void Exceptions() { Assert.Throws <ArgumentException>(() => new BlockStream(-10)); Assert.Throws <ArgumentException>(() => new BlockStream(0, -10)); Assert.Throws <ArgumentException>(() => new BlockStream(0, 0)); Assert.Throws <IOException>( () => { var s = new BlockStream(); s.SetLength(-1); }); Assert.Throws <IOException>( () => { var s = new BlockStream(); s.SetLength((long)int.MaxValue + 1); }); Assert.Throws <IOException>( () => { var s = new BlockStream(); s.SetLength(5000); s.Position = -1; }); Assert.Throws <IOException>( () => { var s = new BlockStream(); s.SetLength(5000); s.Position = (long)int.MaxValue + 1; }); Assert.Throws <IOException>( () => { var s = new BlockStream(); s.SetLength(5000); s.Seek(-1, SeekOrigin.Begin); }); Assert.Throws <IOException>( () => { var s = new BlockStream(); s.SetLength(5000); s.Position = -1; }); Assert.Throws <IOException>( () => { var s = new BlockStream(); s.SetLength(5000); s.Seek(5000, SeekOrigin.Begin); s.Seek(-5001, SeekOrigin.Current); }); Assert.Throws <IOException>( () => { var s = new BlockStream(); s.SetLength(5000); s.Seek(-5001, SeekOrigin.End); }); Assert.Throws <IOException>( () => { var s = new BlockStream(); s.SetLength(5000); s.Seek((long)int.MaxValue + 1, SeekOrigin.Begin); }); Assert.Throws <IOException>( () => { var s = new BlockStream(); s.SetLength(5000); s.Seek(5000, SeekOrigin.Begin); s.Seek((long)int.MaxValue - 5000 + 1, SeekOrigin.Current); }); Assert.Throws <IOException>( () => { var s = new BlockStream(); s.SetLength(5000); s.Seek((long)int.MaxValue - 5000 + 1, SeekOrigin.End); }); }
public void BlockStream_Exceptions() { BlockStream s; try { s = new BlockStream(-10); Assert.Fail(); } catch { } try { s = new BlockStream(0, -10); Assert.Fail(); } catch { } try { s = new BlockStream(0, 0); Assert.Fail(); } catch { } try { s = new BlockStream(); s.SetLength(-1); Assert.Fail(); } catch { } try { s = new BlockStream(); s.SetLength((long)int.MaxValue + 1); Assert.Fail(); } catch { } try { s = new BlockStream(); s.SetLength(5000); s.Position = -1; Assert.Fail(); } catch { } try { s = new BlockStream(); s.SetLength(5000); s.Position = (long)int.MaxValue + 1; Assert.Fail(); } catch { } try { s = new BlockStream(); s.SetLength(5000); s.Seek(-1, SeekOrigin.Begin); Assert.Fail(); } catch { } try { s = new BlockStream(); s.SetLength(5000); s.Position = -1; Assert.Fail(); } catch { } try { s = new BlockStream(); s.SetLength(5000); s.Seek(5000, SeekOrigin.Begin); s.Seek(-5001, SeekOrigin.Current); Assert.Fail(); } catch { } try { s = new BlockStream(); s.SetLength(5000); s.Seek(-5001, SeekOrigin.End); Assert.Fail(); } catch { } try { s = new BlockStream(); s.SetLength(5000); s.Seek((long)int.MaxValue + 1, SeekOrigin.Begin); Assert.Fail(); } catch { } try { s = new BlockStream(); s.SetLength(5000); s.Seek(5000, SeekOrigin.Begin); s.Seek((long)int.MaxValue - 5000 + 1, SeekOrigin.Current); Assert.Fail(); } catch { } try { s = new BlockStream(); s.SetLength(5000); s.Seek((long)int.MaxValue - 5000 + 1, SeekOrigin.End); Assert.Fail(); } catch { } }
/// <summary> /// Completes parsing of the headers. /// </summary> /// <param name="dataPos">Returns as the logical index of the first byte of request/response data.</param> /// <returns>A block array with the network data received so far.</returns> /// <remarks> /// The block array return contains the raw network data received so /// far. Much of this will be the request/response line and header data /// but it may also include some of the request/response data. The logical /// index of the first byte of any data will be returned in dataPos. /// </remarks> /// <exception cref="HttpBadProtocolException">Badly formatted HTTP message.</exception> /// <exception cref="InvalidOperationException">The class methods are not being used properly.</exception> public BlockArray EndParse(out int dataPos) { if (blocks == null) { throw new InvalidOperationException("Parsing not begun."); } if (this.dataPos == -1) { throw new InvalidOperationException("Parsing not completed."); } try { // Parse the request/response line and headers. BlockStream stream; StreamReader reader; string line; string name, value, key; int pos, posEnd; HttpHeader header, lastHeader; stream = new BlockStream(blocks); stream.SetLength(this.dataPos, false); reader = new StreamReader(stream, Encoding.ASCII); line = reader.ReadLine(); if (line == null) { throw new HttpBadProtocolException(); } if (isRequest) { // Request-Line = Method SP Request-URI SP HTTP-Version CRLF posEnd = line.IndexOf(' '); if (posEnd == -1) { throw new HttpBadProtocolException(); } method = line.Substring(0, posEnd).ToUpper(); if (method.Length == 0) { throw new HttpBadProtocolException(); } pos = posEnd + 1; posEnd = line.IndexOf(' ', pos); if (posEnd == -1) { throw new HttpBadProtocolException(); } rawUri = line.Substring(pos, posEnd - pos); if (rawUri.Length == 0) { throw new HttpBadProtocolException(); } pos = posEnd + 1; posEnd = line.IndexOf('/', pos); if (posEnd == -1 || line.Substring(pos, posEnd - pos).ToUpper() != "HTTP") { throw new HttpBadProtocolException(); } version = new Version(line.Substring(posEnd + 1)); } else { // Status-Line = HTTP-Version SP Status-Code SP Reason-Phrase CRLF posEnd = line.IndexOf('/'); if (posEnd == -1 || line.Substring(0, posEnd).ToUpper() != "HTTP") { throw new HttpBadProtocolException(); } pos = posEnd + 1; posEnd = line.IndexOf(' ', pos); version = new Version(line.Substring(pos, posEnd - pos)); pos = posEnd + 1; posEnd = line.IndexOf(' ', pos); status = (HttpStatus)int.Parse(line.Substring(pos, posEnd - pos)); reason = line.Substring(posEnd + 1); } // Parse the headers. Note that I'm going to convert // multiple headers with the same name into the equivalent // list form. headers = new Hashtable(); lastHeader = null; line = reader.ReadLine(); while (line != null && line.Length > 0) { if (Char.IsWhiteSpace(line[0])) { // Header continuation if (lastHeader == null) { throw new HttpBadProtocolException(); } lastHeader.AppendContinuation(line); } else { posEnd = line.IndexOf(':'); if (posEnd == -1) { throw new HttpBadProtocolException(); } name = line.Substring(0, posEnd).Trim(); value = line.Substring(posEnd + 1).Trim(); key = name.ToUpper(); header = (HttpHeader)headers[key]; if (header != null) { header.Append(value); } else { header = new HttpHeader(name, value); headers.Add(key, header); lastHeader = header; } } line = reader.ReadLine(); } // We're done, so return the data position and blocks. dataPos = this.dataPos; return(blocks); } finally { blocks = null; // Release this reference to help the GC } }