X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fclass%2FSystem.Net.Http%2FSystem.Net.Http%2FHttpContent.cs;h=ad068a598d41e04b27f727d85cfaf8d70aeaf29b;hb=c0a8ef12af1f473bfc837325581fe738f1b3178c;hp=619e0b834a1a0e45aa6bea39868918e303add62b;hpb=15af51806d816ad6ad966bc1dfbdd232b63fde52;p=mono.git diff --git a/mcs/class/System.Net.Http/System.Net.Http/HttpContent.cs b/mcs/class/System.Net.Http/System.Net.Http/HttpContent.cs index 619e0b834a1..ad068a598d4 100644 --- a/mcs/class/System.Net.Http/System.Net.Http/HttpContent.cs +++ b/mcs/class/System.Net.Http/System.Net.Http/HttpContent.cs @@ -27,17 +27,78 @@ // using System.Net.Http.Headers; +using System.IO; +using System.Threading.Tasks; +using System.Text; namespace System.Net.Http { public abstract class HttpContent : IDisposable { + sealed class FixedMemoryStream : MemoryStream + { + readonly long maxSize; + + public FixedMemoryStream (long maxSize) + : base () + { + this.maxSize = maxSize; + } + + void CheckOverflow (int count) + { + if (Length + count > maxSize) + throw new HttpRequestException (string.Format ("Cannot write more bytes to the buffer than the configured maximum buffer size: {0}", maxSize)); + } + + public override void WriteByte (byte value) + { + CheckOverflow (1); + base.WriteByte (value); + } + + public override void Write (byte[] buffer, int offset, int count) + { + CheckOverflow (count); + base.Write (buffer, offset, count); + } + } + + FixedMemoryStream buffer; + Stream stream; + bool disposed; + HttpContentHeaders headers; + public HttpContentHeaders Headers { get { - return new HttpContentHeaders (); + return headers ?? (headers = new HttpContentHeaders (this)); } } + + public Task CopyToAsync (Stream stream) + { + return CopyToAsync (stream, null); + } + + public Task CopyToAsync (Stream stream, TransportContext context) + { + if (stream == null) + throw new ArgumentNullException ("stream"); + + return SerializeToStreamAsync (stream, context); + } + + protected async virtual Task CreateContentReadStreamAsync () + { + await LoadIntoBufferAsync ().ConfigureAwait (false); + return buffer; + } + static FixedMemoryStream CreateFixedMemoryStream (long maxBufferSize) + { + return new FixedMemoryStream (maxBufferSize); + } + public void Dispose () { Dispose (true); @@ -45,11 +106,66 @@ namespace System.Net.Http protected virtual void Dispose (bool disposing) { + if (disposing && !disposed) { + disposed = true; + + if (buffer != null) + buffer.Dispose (); + } + } + + public Task LoadIntoBufferAsync () + { + return LoadIntoBufferAsync (65536); } - public string ReadAsString () + public async Task LoadIntoBufferAsync (long maxBufferSize) { - return null; + if (disposed) + throw new ObjectDisposedException (GetType ().ToString ()); + + if (buffer != null) + return; + + buffer = CreateFixedMemoryStream (maxBufferSize); + await SerializeToStreamAsync (buffer, null).ConfigureAwait (false); + buffer.Seek (0, SeekOrigin.Begin); + } + + public async Task ReadAsStreamAsync () + { + if (disposed) + throw new ObjectDisposedException (GetType ().ToString ()); + + if (stream == null) + stream = await CreateContentReadStreamAsync ().ConfigureAwait (false); + + return stream; } + + public async Task ReadAsByteArrayAsync () + { + await LoadIntoBufferAsync ().ConfigureAwait (false); + return buffer.ToArray (); + } + + public async Task ReadAsStringAsync () + { + await LoadIntoBufferAsync ().ConfigureAwait (false); + if (buffer.Length == 0) + return string.Empty; + + Encoding encoding; + if (headers != null && headers.ContentType != null && headers.ContentType.CharSet != null) { + encoding = Encoding.GetEncoding (headers.ContentType.CharSet); + } else { + encoding = Encoding.UTF8; + } + + return encoding.GetString (buffer.GetBuffer (), 0, (int) buffer.Length); + } + + protected internal abstract Task SerializeToStreamAsync (Stream stream, TransportContext context); + protected internal abstract bool TryComputeLength (out long length); } }