Cleanup network module.
This commit is contained in:
130
Assets/Cryville/Common/Network/Http11/Http11ResponseStream.cs
Normal file
130
Assets/Cryville/Common/Network/Http11/Http11ResponseStream.cs
Normal file
@@ -0,0 +1,130 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
||||
namespace Cryville.Common.Network.Http11 {
|
||||
public abstract class Http11ResponseStream : Stream {
|
||||
public override bool CanRead { get { return true; } }
|
||||
|
||||
public override bool CanSeek { get { return false; } }
|
||||
|
||||
public override bool CanWrite { get { return false; } }
|
||||
|
||||
public override long Length { get { throw new NotSupportedException(); } }
|
||||
|
||||
public override long Position {
|
||||
get { throw new NotSupportedException(); }
|
||||
set { throw new NotSupportedException(); }
|
||||
}
|
||||
|
||||
public override void Flush() { }
|
||||
|
||||
public abstract byte[] ReadToEnd();
|
||||
|
||||
public override long Seek(long offset, SeekOrigin origin) {
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
public override void SetLength(long value) {
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
public override void Write(byte[] buffer, int offset, int count) {
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
}
|
||||
|
||||
internal sealed class Http11ResponseBlockStream : Http11ResponseStream {
|
||||
readonly BinaryReader _reader;
|
||||
readonly int _length;
|
||||
int _pos = 0;
|
||||
internal Http11ResponseBlockStream(BinaryReader reader, int length) {
|
||||
_reader = reader;
|
||||
_length = length;
|
||||
}
|
||||
public override int Read(byte[] buffer, int offset, int count) {
|
||||
int recv = 0;
|
||||
int recv_len = System.Math.Min(count, _length - _pos);
|
||||
if (recv_len == 0) return 0;
|
||||
while (recv < recv_len) {
|
||||
recv += _reader.Read(buffer, offset + recv, count - recv);
|
||||
}
|
||||
_pos += recv_len;
|
||||
return recv_len;
|
||||
}
|
||||
public override byte[] ReadToEnd() {
|
||||
byte[] buffer = new byte[_length - _pos];
|
||||
Read(buffer, 0, buffer.Length);
|
||||
return buffer;
|
||||
}
|
||||
}
|
||||
|
||||
internal sealed class Http11ResponseChunkedStream : Http11ResponseStream {
|
||||
readonly BinaryReader _reader;
|
||||
byte[] _chunk = null;
|
||||
int _pos = 0;
|
||||
internal Http11ResponseChunkedStream(BinaryReader reader) {
|
||||
_reader = reader;
|
||||
ReadChunk();
|
||||
}
|
||||
public void ReadChunk() {
|
||||
if (_chunk != null && _chunk.Length == 0) return;
|
||||
string[] chunkHeader = Http11Response.ReadLine(_reader).Split(';');
|
||||
int chunkSize = int.Parse(chunkHeader[0], NumberStyles.HexNumber);
|
||||
if (chunkSize == -1)
|
||||
throw new IOException("Corrupted chunk received");
|
||||
if (chunkSize == 0) {
|
||||
_chunk = new byte[0];
|
||||
// TODO TE Header, now just discard
|
||||
var headers = new Dictionary<string, string>();
|
||||
while (Http11Response.ParseHeader(_reader, headers)) ;
|
||||
return;
|
||||
}
|
||||
_chunk = new byte[chunkSize];
|
||||
int recv = 0;
|
||||
while (recv < chunkSize) {
|
||||
recv += _reader.Read(_chunk, recv, chunkSize - recv);
|
||||
}
|
||||
_pos = 0;
|
||||
if (Http11Response.ReadLine(_reader) != "")
|
||||
throw new IOException("Corrupted chunk received");
|
||||
}
|
||||
public override int Read(byte[] buffer, int offset, int count) {
|
||||
if (_chunk.Length == 0) return 0;
|
||||
int recv = 0;
|
||||
while (true) {
|
||||
if (count - recv <= _chunk.Length - _pos) break;
|
||||
Array.Copy(_chunk, _pos, buffer, recv, _chunk.Length - _pos);
|
||||
recv += _chunk.Length - _pos;
|
||||
ReadChunk();
|
||||
if (_chunk.Length == 0) return recv;
|
||||
}
|
||||
Array.Copy(_chunk, _pos, buffer, recv, count - recv);
|
||||
return count;
|
||||
}
|
||||
public override byte[] ReadToEnd() {
|
||||
if (_chunk.Length == 0) return new byte[0];
|
||||
List<byte[]> segs = new List<byte[]>();
|
||||
while (true) {
|
||||
if (_pos != 0) {
|
||||
var buffer = new byte[_chunk.Length - _pos];
|
||||
Array.Copy(_chunk, _pos, buffer, 0, buffer.Length);
|
||||
segs.Add(buffer);
|
||||
}
|
||||
else segs.Add(_chunk);
|
||||
ReadChunk();
|
||||
if (_chunk.Length == 0) {
|
||||
var result = new byte[segs.Sum(i => i.Length)];
|
||||
int p = 0;
|
||||
foreach (var i in segs) {
|
||||
Array.Copy(i, 0, result, p, i.Length);
|
||||
p += i.Length;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user