You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
152 lines
4.1 KiB
152 lines
4.1 KiB
using BestHTTP.PlatformSupport.Memory; |
|
using System; |
|
|
|
namespace BestHTTP.Extensions |
|
{ |
|
/// <summary> |
|
/// Wrapper of multiple streams. Writes and reads are both supported. Read goes trough all the streams. |
|
/// </summary> |
|
public sealed class StreamList : System.IO.Stream |
|
{ |
|
private System.IO.Stream[] Streams; |
|
private int CurrentIdx; |
|
|
|
public StreamList(params System.IO.Stream[] streams) |
|
{ |
|
this.Streams = streams; |
|
this.CurrentIdx = 0; |
|
} |
|
|
|
public override bool CanRead |
|
{ |
|
get |
|
{ |
|
if (CurrentIdx >= Streams.Length) |
|
return false; |
|
return Streams[CurrentIdx].CanRead; |
|
} |
|
} |
|
|
|
public override bool CanSeek { get { return false; } } |
|
|
|
public override bool CanWrite |
|
{ |
|
get |
|
{ |
|
if (CurrentIdx >= Streams.Length) |
|
return false; |
|
return Streams[CurrentIdx].CanWrite; |
|
} |
|
} |
|
|
|
public override void Flush() |
|
{ |
|
if (CurrentIdx >= Streams.Length) |
|
return; |
|
|
|
// We have to call the flush to all previous streams, as we may advanced the CurrentIdx |
|
for (int i = 0; i <= CurrentIdx; ++i) |
|
Streams[i].Flush(); |
|
} |
|
|
|
public override long Length |
|
{ |
|
get |
|
{ |
|
if (CurrentIdx >= Streams.Length) |
|
return 0; |
|
|
|
long length = 0; |
|
for (int i = 0; i < Streams.Length; ++i) |
|
length += Streams[i].Length; |
|
|
|
return length; |
|
} |
|
} |
|
|
|
public override int Read(byte[] buffer, int offset, int count) |
|
{ |
|
if (CurrentIdx >= Streams.Length) |
|
return -1; |
|
|
|
int readCount = Streams[CurrentIdx].Read(buffer, offset, count); |
|
|
|
while (readCount < count && ++CurrentIdx < Streams.Length) |
|
{ |
|
// Dispose previous stream |
|
try |
|
{ |
|
Streams[CurrentIdx - 1].Dispose(); |
|
Streams[CurrentIdx - 1] = null; |
|
} |
|
catch (Exception ex) |
|
{ |
|
HTTPManager.Logger.Exception("StreamList", "Dispose", ex); |
|
} |
|
|
|
readCount += Streams[CurrentIdx].Read(buffer, offset + readCount, count - readCount); |
|
} |
|
|
|
return readCount; |
|
} |
|
|
|
public override void Write(byte[] buffer, int offset, int count) |
|
{ |
|
if (CurrentIdx >= Streams.Length) |
|
return; |
|
|
|
Streams[CurrentIdx].Write(buffer, offset, count); |
|
} |
|
|
|
public void Write(string str) |
|
{ |
|
var buffer = str.GetASCIIBytes(); |
|
this.Write(buffer.Data, buffer.Offset, buffer.Count); |
|
BufferPool.Release(buffer); |
|
} |
|
|
|
protected override void Dispose(bool disposing) |
|
{ |
|
if (disposing) |
|
{ |
|
for (int i = 0; i < Streams.Length; ++i) |
|
if (Streams[i] != null) |
|
{ |
|
try |
|
{ |
|
Streams[i].Dispose(); |
|
} |
|
catch (Exception ex) |
|
{ |
|
HTTPManager.Logger.Exception("StreamList", "Dispose", ex); |
|
} |
|
} |
|
} |
|
} |
|
|
|
public override long Position |
|
{ |
|
get |
|
{ |
|
throw new NotImplementedException("Position get"); |
|
} |
|
set |
|
{ |
|
throw new NotImplementedException("Position set"); |
|
} |
|
} |
|
|
|
public override long Seek(long offset, System.IO.SeekOrigin origin) |
|
{ |
|
if (CurrentIdx >= Streams.Length) |
|
return 0; |
|
|
|
return Streams[CurrentIdx].Seek(offset, origin); |
|
} |
|
|
|
public override void SetLength(long value) |
|
{ |
|
throw new NotImplementedException("SetLength"); |
|
} |
|
} |
|
}
|
|
|