using MediaBrowser.Model.Logging; using ServiceStack.Web; using System; using System.Collections.Generic; using System.Globalization; using System.IO; using System.Threading.Tasks; using MediaBrowser.Common.IO; using ServiceStack; namespace MediaBrowser.Server.Implementations.HttpServer { /// /// Class StreamWriter /// public class StreamWriter : IStreamWriter, IAsyncStreamWriter, IHasOptions { private ILogger Logger { get; set; } private static readonly CultureInfo UsCulture = new CultureInfo("en-US"); /// /// Gets or sets the source stream. /// /// The source stream. private Stream SourceStream { get; set; } /// /// The _options /// private readonly IDictionary _options = new Dictionary(); /// /// Gets the options. /// /// The options. public IDictionary Options { get { return _options; } } public Action OnComplete { get; set; } public Action OnError { get; set; } private readonly byte[] _bytes; /// /// Initializes a new instance of the class. /// /// The source. /// Type of the content. /// The logger. public StreamWriter(Stream source, string contentType, ILogger logger) { if (string.IsNullOrEmpty(contentType)) { throw new ArgumentNullException("contentType"); } SourceStream = source; Logger = logger; Options["Content-Type"] = contentType; if (source.CanSeek) { Options["Content-Length"] = source.Length.ToString(UsCulture); } } /// /// Initializes a new instance of the class. /// /// The source. /// Type of the content. /// The logger. public StreamWriter(byte[] source, string contentType, ILogger logger) : this(new MemoryStream(source), contentType, logger) { if (string.IsNullOrEmpty(contentType)) { throw new ArgumentNullException("contentType"); } _bytes = source; Logger = logger; Options["Content-Type"] = contentType; Options["Content-Length"] = source.Length.ToString(UsCulture); } private const int BufferSize = 81920; /// /// Writes to. /// /// The response stream. public void WriteTo(Stream responseStream) { try { if (_bytes != null) { responseStream.Write(_bytes, 0, _bytes.Length); } else { using (var src = SourceStream) { src.CopyTo(responseStream, BufferSize); } } } catch (Exception ex) { Logger.ErrorException("Error streaming data", ex); if (OnError != null) { OnError(); } throw; } finally { if (OnComplete != null) { OnComplete(); } } } public async Task WriteToAsync(Stream responseStream) { try { if (_bytes != null) { await responseStream.WriteAsync(_bytes, 0, _bytes.Length); } else { using (var src = SourceStream) { await src.CopyToAsync(responseStream, BufferSize).ConfigureAwait(false); } } } catch (Exception ex) { Logger.ErrorException("Error streaming data", ex); if (OnError != null) { OnError(); } throw; } finally { if (OnComplete != null) { OnComplete(); } } } } }