using System; using System.IO; namespace NetVips; /// /// An source connected to a readable . /// internal class SourceStream : SourceCustom { /// /// Read from this stream. /// private readonly Stream _stream; /// /// The start position within the stream. /// private readonly long _startPosition; /// internal SourceStream(Stream stream) { var seekable = stream.CanSeek; _stream = stream; _startPosition = seekable ? _stream.Position : 0; OnRead += Read; if (seekable) { OnSeek += Seek; } } /// /// Create a attached to an . /// /// Read from this stream. /// A new . /// If is not readable. internal static SourceStream NewFromStream(Stream stream) { if (!stream.CanRead) { throw new ArgumentException("The stream should be readable.", nameof(stream)); } return new SourceStream(stream); } /// /// Attach a read handler. /// /// An array of bytes. /// The maximum number of bytes to be read. /// The total number of bytes read into the buffer. public int Read(byte[] buffer, int length) { return _stream.Read(buffer, 0, length); } /// /// Attach a seek handler. /// /// A byte offset relative to the /// parameter. /// A value of type indicating the /// reference point used to obtain the new position. /// The new position within the current stream. public long Seek(long offset, SeekOrigin origin) { try { return origin switch { SeekOrigin.Begin => _stream.Seek(_startPosition + offset, SeekOrigin.Begin) - _startPosition, SeekOrigin.Current => _stream.Seek(offset, SeekOrigin.Current) - _startPosition, SeekOrigin.End => _stream.Seek(offset, SeekOrigin.End) - _startPosition, _ => -1 }; } catch { return -1; } } }