培训考核三期,新版培训,网页版培训登录器
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.

153 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");
}
}
}