Merge pull request #3656 from marek-safar/bootstrap
[mono.git] / mcs / class / System.Net.Http / System.Net.Http / HttpContent.cs
index 021f2e9b0d9f8edac15ac185d2ccff6c6091090c..df97dc50bbc11d7168206a84565ffb8321f9095e 100644 (file)
@@ -75,6 +75,18 @@ namespace System.Net.Http
                        }
                }
 
+               internal long? LoadedBufferLength {
+                       get {
+                               return buffer == null ? (long?)null : buffer.Length;
+                       }
+               }
+
+               // Only used by HttpWebRequest internals which is not async friendly
+               internal void CopyTo (Stream stream)
+               {
+                       CopyToAsync (stream).Wait ();
+               }
+
                public Task CopyToAsync (Stream stream)
                {
                        return CopyToAsync (stream, null);
@@ -161,14 +173,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);