X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fclass%2Fcorlib%2FSystem.IO%2FStreamWriter.cs;h=fe3a606261730cd522bea0648a95c3deb600117e;hb=cbbd71101794e66ab7477db65cfbd61d67e08305;hp=7186a67f42b72e876f750af94f3665af082ad437;hpb=e52c1227e4d979f4aa39f7e959211c7ef9def804;p=mono.git diff --git a/mcs/class/corlib/System.IO/StreamWriter.cs b/mcs/class/corlib/System.IO/StreamWriter.cs index 7186a67f42b..fe3a6062617 100644 --- a/mcs/class/corlib/System.IO/StreamWriter.cs +++ b/mcs/class/corlib/System.IO/StreamWriter.cs @@ -60,7 +60,7 @@ namespace System.IO { #if NET_4_5 readonly bool leave_open; - Task async_task; + IDecoupledTask async_task; #endif public new static readonly StreamWriter Null = new StreamWriter (Stream.Null, Encoding.UTF8Unmarked, 1); @@ -234,6 +234,45 @@ namespace System.IO { } } + void LowLevelWrite (char[] buffer, int index, int count) + { + while (count > 0) { + int todo = decode_buf.Length - decode_pos; + if (todo == 0) { + Decode (); + todo = decode_buf.Length; + } + if (todo > count) + todo = count; + Buffer.BlockCopy (buffer, index * 2, decode_buf, decode_pos * 2, todo * 2); + count -= todo; + index += todo; + decode_pos += todo; + } + } + + void LowLevelWrite (string s) + { + int count = s.Length; + int index = 0; + while (count > 0) { + int todo = decode_buf.Length - decode_pos; + if (todo == 0) { + Decode (); + todo = decode_buf.Length; + } + if (todo > count) + todo = count; + + for (int i = 0; i < todo; i ++) + decode_buf [i + decode_pos] = s [i + index]; + + count -= todo; + index += todo; + decode_pos += todo; + } + } + #if NET_4_5 async Task FlushCoreAsync () { @@ -268,33 +307,13 @@ namespace System.IO { decode_pos = 0; } } -#endif - public override void Write (char[] buffer, int index, int count) - { - if (buffer == null) - throw new ArgumentNullException ("buffer"); - if (index < 0) - throw new ArgumentOutOfRangeException ("index", "< 0"); - if (count < 0) - throw new ArgumentOutOfRangeException ("count", "< 0"); - // re-ordered to avoid possible integer overflow - if (index > buffer.Length - count) - throw new ArgumentException ("index + count > buffer.Length"); - - CheckState (); - - LowLevelWrite (buffer, index, count); - if (iflush) - FlushCore (); - } - - void LowLevelWrite (char[] buffer, int index, int count) + async Task LowLevelWriteAsync (char[] buffer, int index, int count) { while (count > 0) { int todo = decode_buf.Length - decode_pos; if (todo == 0) { - Decode (); + await DecodeAsync ().ConfigureAwait (false); todo = decode_buf.Length; } if (todo > count) @@ -306,14 +325,14 @@ namespace System.IO { } } - void LowLevelWrite (string s) + async Task LowLevelWriteAsync (string s) { int count = s.Length; int index = 0; while (count > 0) { int todo = decode_buf.Length - decode_pos; if (todo == 0) { - Decode (); + await DecodeAsync ().ConfigureAwait (false); todo = decode_buf.Length; } if (todo > count) @@ -326,8 +345,28 @@ namespace System.IO { index += todo; decode_pos += todo; } - } + } +#endif + + public override void Write (char[] buffer, int index, int count) + { + if (buffer == null) + throw new ArgumentNullException ("buffer"); + if (index < 0) + throw new ArgumentOutOfRangeException ("index", "< 0"); + if (count < 0) + throw new ArgumentOutOfRangeException ("count", "< 0"); + // re-ordered to avoid possible integer overflow + if (index > buffer.Length - count) + throw new ArgumentException ("index + count > buffer.Length"); + CheckState (); + + LowLevelWrite (buffer, index, count); + if (iflush) + FlushCore (); + } + public override void Write (char value) { CheckState (); @@ -355,8 +394,10 @@ namespace System.IO { { CheckState (); - if (value != null) - LowLevelWrite (value); + if (value == null) + return; + + LowLevelWrite (value); if (iflush) FlushCore (); @@ -382,13 +423,18 @@ namespace System.IO { public override Task FlushAsync () { CheckState (); - return async_task = FlushCoreAsync (); + DecoupledTask res; + async_task = res = new DecoupledTask (FlushCoreAsync ()); + return res.Task; } public override Task WriteAsync (char value) { CheckState (); - return async_task = WriteAsyncCore (value); + + DecoupledTask res; + async_task = res = new DecoupledTask (WriteAsyncCore (value)); + return res.Task; } async Task WriteAsyncCore (char value) @@ -409,14 +455,16 @@ namespace System.IO { if (buffer == null) return TaskConstants.Finished; - return async_task = WriteAsyncCore (buffer, index, count); + DecoupledTask res; + async_task = res = new DecoupledTask (WriteAsyncCore (buffer, index, count)); + return res.Task; } async Task WriteAsyncCore (char[] buffer, int index, int count) { // Debug.Assert (buffer == null); - LowLevelWrite (buffer, 0, buffer.Length); + await LowLevelWriteAsync (buffer, index, count).ConfigureAwait (false); if (iflush) await FlushCoreAsync ().ConfigureAwait (false); @@ -425,31 +473,91 @@ namespace System.IO { public override Task WriteAsync (string value) { CheckState (); - return async_task = base.WriteAsync (value); + + if (value == null) + return TaskConstants.Finished; + + DecoupledTask res; + async_task = res = new DecoupledTask (WriteAsyncCore (value, false)); + return res.Task; } + async Task WriteAsyncCore (string value, bool appendNewLine) + { + // Debug.Assert (value == null); + + await LowLevelWriteAsync (value).ConfigureAwait (false); + if (appendNewLine) + await LowLevelWriteAsync (CoreNewLine, 0, CoreNewLine.Length).ConfigureAwait (false); + + if (iflush) + await FlushCoreAsync ().ConfigureAwait (false); + } + public override Task WriteLineAsync () { CheckState (); - return async_task = base.WriteLineAsync (); + + DecoupledTask res; + async_task = res = new DecoupledTask (WriteAsyncCore (CoreNewLine, 0, CoreNewLine.Length)); + return res.Task; } public override Task WriteLineAsync (char value) { CheckState (); - return async_task = base.WriteLineAsync (value); + DecoupledTask res; + async_task = res = new DecoupledTask (WriteLineAsyncCore (value)); + return res.Task; } + async Task WriteLineAsyncCore (char value) + { + await WriteAsyncCore (value).ConfigureAwait (false); + await LowLevelWriteAsync (CoreNewLine, 0, CoreNewLine.Length).ConfigureAwait (false); + + if (iflush) + await FlushCoreAsync ().ConfigureAwait (false); + } + public override Task WriteLineAsync (char[] buffer, int index, int count) { + if (buffer == null) + throw new ArgumentNullException ("buffer"); + if (index < 0) + throw new ArgumentOutOfRangeException ("index", "< 0"); + if (count < 0) + throw new ArgumentOutOfRangeException ("count", "< 0"); + // re-ordered to avoid possible integer overflow + if (index > buffer.Length - count) + throw new ArgumentException ("index + count > buffer.Length"); + CheckState (); - return async_task = base.WriteLineAsync (buffer, index, count); + DecoupledTask res; + async_task = res = new DecoupledTask (WriteLineAsyncCore (buffer, index, count)); + return res.Task; } + async Task WriteLineAsyncCore (char[] buffer, int index, int count) + { + // Debug.Assert (buffer == null); + + await LowLevelWriteAsync (buffer, index, count).ConfigureAwait (false); + await LowLevelWriteAsync (CoreNewLine, 0, CoreNewLine.Length).ConfigureAwait (false); + + if (iflush) + await FlushCoreAsync ().ConfigureAwait (false); + } + public override Task WriteLineAsync (string value) { + if (value == null) + return WriteLineAsync (); + CheckState (); - return async_task = base.WriteLineAsync (value); + DecoupledTask res; + async_task = res = new DecoupledTask (WriteAsyncCore (value, true)); + return res.Task; } #endif }