using System; using System.Collections.Generic; using System.Globalization; using System.IO; using System.Net; using System.Text; using System.Threading.Tasks; using MediaBrowser.Model.Services; public sealed class HttpPostedFile : IDisposable { private string _name; private string _contentType; private Stream _stream; private bool _disposed = false; internal HttpPostedFile(string name, string content_type, Stream base_stream, long offset, long length) { _name = name; _contentType = content_type; _stream = new ReadSubStream(base_stream, offset, length); } public string ContentType => _contentType; public int ContentLength => (int)_stream.Length; public string FileName => _name; public Stream InputStream => _stream; /// /// Releases the unmanaged resources and disposes of the managed resources used. /// public void Dispose() { if (_disposed) { return; } _stream.Dispose(); _stream = null; _name = null; _contentType = null; _disposed = true; } private class ReadSubStream : Stream { private Stream _stream; private long _offset; private long _end; private long _position; public ReadSubStream(Stream s, long offset, long length) { _stream = s; _offset = offset; _end = offset + length; _position = offset; } public override bool CanRead => true; public override bool CanSeek => true; public override bool CanWrite => false; public override long Length => _end - _offset; public override long Position { get => _position - _offset; set { if (value > Length) { throw new ArgumentOutOfRangeException(nameof(value)); } _position = Seek(value, SeekOrigin.Begin); } } public override void Flush() { } public override int Read(byte[] buffer, int dest_offset, int count) { if (buffer == null) { throw new ArgumentNullException(nameof(buffer)); } if (dest_offset < 0) { throw new ArgumentOutOfRangeException(nameof(dest_offset), "< 0"); } if (count < 0) { throw new ArgumentOutOfRangeException(nameof(count), "< 0"); } int len = buffer.Length; if (dest_offset > len) { throw new ArgumentException("destination offset is beyond array size", nameof(dest_offset)); } // reordered to avoid possible integer overflow if (dest_offset > len - count) { throw new ArgumentException("Reading would overrun buffer", nameof(count)); } if (count > _end - _position) { count = (int)(_end - _position); } if (count <= 0) { return 0; } _stream.Position = _position; int result = _stream.Read(buffer, dest_offset, count); if (result > 0) { _position += result; } else { _position = _end; } return result; } public override int ReadByte() { if (_position >= _end) { return -1; } _stream.Position = _position; int result = _stream.ReadByte(); if (result < 0) { _position = _end; } else { _position++; } return result; } public override long Seek(long d, SeekOrigin origin) { long real; switch (origin) { case SeekOrigin.Begin: real = _offset + d; break; case SeekOrigin.End: real = _end + d; break; case SeekOrigin.Current: real = _position + d; break; default: throw new ArgumentException("Unknown SeekOrigin value", nameof(origin)); } long virt = real - _offset; if (virt < 0 || virt > Length) { throw new ArgumentException("Invalid position", nameof(d)); } _position = _stream.Seek(real, SeekOrigin.Begin); return _position; } public override void SetLength(long value) { throw new NotSupportedException(); } public override void Write(byte[] buffer, int offset, int count) { throw new NotSupportedException(); } } }