mirror of
				https://github.com/jellyfin/jellyfin.git
				synced 2025-11-03 19:17:24 -05:00 
			
		
		
		
	
		
			
				
	
	
		
			205 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			205 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
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;
 | 
						|
 | 
						|
    /// <summary>
 | 
						|
    /// Releases the unmanaged resources and disposes of the managed resources used.
 | 
						|
    /// </summary>
 | 
						|
    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 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();
 | 
						|
        }
 | 
						|
 | 
						|
        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);
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
}
 |