Merge pull request #1404 from woodsb02/mono-route
[mono.git] / mcs / class / System.Net.Http / System.Net.Http / HttpContent.cs
index 40cbde3a6abf0ecb6a553adca54834b4e94b267d..344d87164eb1621a6d55bc6d67d03c3def40488b 100644 (file)
@@ -75,6 +75,12 @@ namespace System.Net.Http
                        }
                }
 
+               internal long? LoadedBufferLength {
+                       get {
+                               return buffer == null ? (long?)null : buffer.Length;
+                       }
+               }
+
                public Task CopyToAsync (Stream stream)
                {
                        return CopyToAsync (stream, null);
@@ -119,7 +125,7 @@ namespace System.Net.Http
 
                public Task LoadIntoBufferAsync ()
                {
-                       return LoadIntoBufferAsync (65536);
+                       return LoadIntoBufferAsync (int.MaxValue);
                }
 
                public async Task LoadIntoBufferAsync (long maxBufferSize)
@@ -161,14 +167,43 @@ namespace System.Net.Http
                        if (buffer.Length == 0)
                                return string.Empty;
 
+                       var buf = buffer.GetBuffer ();
+                       var buf_length = (int) buffer.Length;
+                       int preambleLength = 0;
                        Encoding encoding;
+
                        if (headers != null && headers.ContentType != null && headers.ContentType.CharSet != null) {
                                encoding = Encoding.GetEncoding (headers.ContentType.CharSet);
+                               preambleLength = StartsWith (buf, buf_length, encoding.GetPreamble ());
                        } else {
-                               encoding = Encoding.UTF8;
+                               encoding = GetEncodingFromBuffer (buf, buf_length, ref preambleLength) ?? Encoding.UTF8;
+                       }
+
+                       return encoding.GetString (buf, preambleLength, buf_length - preambleLength);
+               }
+
+               static Encoding GetEncodingFromBuffer (byte[] buffer, int length, ref int preambleLength)
+               {
+                       var encodings_with_preamble = new [] { Encoding.UTF8, Encoding.UTF32, Encoding.Unicode };
+                       foreach (var enc in encodings_with_preamble) {
+                               if ((preambleLength = StartsWith (buffer, length, enc.GetPreamble ())) != 0)
+                                       return enc;
+                       }
+
+                       return null;
+               }
+
+               static int StartsWith (byte[] array, int length, byte[] value)
+               {
+                       if (length < value.Length)
+                               return 0;
+
+                       for (int i = 0; i < value.Length; ++i) {
+                               if (array [i] != value [i])
+                                       return 0;
                        }
 
-                       return encoding.GetString (buffer.GetBuffer (), 0, (int) buffer.Length);
+                       return value.Length;
                }
 
                protected internal abstract Task SerializeToStreamAsync (Stream stream, TransportContext context);