Merge pull request #309 from i59/patch-1
[mono.git] / mcs / class / corlib / System.IO / TextWriter.cs
1 //
2 // System.IO.TextWriter.cs
3 //
4 // Authors:
5 //   Marcin Szczepanski (marcins@zipworld.com.au)
6 //   Miguel de Icaza (miguel@gnome.org)
7 //   Paolo Molaro (lupus@ximian.com)
8 //   Marek Safar (marek.safar@gmail.com)
9
10 //
11 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
12 // Copyright 2011 Xamarin Inc.
13 //
14 // Permission is hereby granted, free of charge, to any person obtaining
15 // a copy of this software and associated documentation files (the
16 // "Software"), to deal in the Software without restriction, including
17 // without limitation the rights to use, copy, modify, merge, publish,
18 // distribute, sublicense, and/or sell copies of the Software, and to
19 // permit persons to whom the Software is furnished to do so, subject to
20 // the following conditions:
21 // 
22 // The above copyright notice and this permission notice shall be
23 // included in all copies or substantial portions of the Software.
24 // 
25 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
29 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
30 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
31 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 //
33
34 using System.Text;
35 using System.Runtime.InteropServices;
36 #if NET_4_5
37 using System.Threading.Tasks;
38 #endif
39
40 namespace System.IO
41 {
42
43         [Serializable]
44         [ComVisible (true)]
45 #if NET_2_1
46         public abstract class TextWriter : IDisposable {
47 #else
48         public abstract class TextWriter : MarshalByRefObject, IDisposable
49         {
50 #endif
51                 //
52                 // Null version of the TextWriter, for the `Null' instance variable
53                 //
54                 sealed class NullTextWriter : TextWriter
55                 {
56                         public override Encoding Encoding
57                         {
58                                 get
59                                 {
60                                         return Encoding.Default;
61                                 }
62                         }
63
64                         public override void Write (string s)
65                         {
66                         }
67                         public override void Write (char value)
68                         {
69                         }
70                         public override void Write (char[] value, int index, int count)
71                         {
72                         }
73                 }
74
75                 protected TextWriter ()
76                 {
77                         CoreNewLine = System.Environment.NewLine.ToCharArray ();
78                 }
79
80                 protected TextWriter (IFormatProvider formatProvider)
81                 {
82                         CoreNewLine = System.Environment.NewLine.ToCharArray ();
83                         internalFormatProvider = formatProvider;
84                 }
85
86                 protected char[] CoreNewLine;
87
88                 internal IFormatProvider internalFormatProvider;
89
90                 public static readonly TextWriter Null = new NullTextWriter ();
91
92                 public abstract Encoding Encoding { get; }
93
94                 public virtual IFormatProvider FormatProvider {
95                         get {
96                                 return internalFormatProvider;
97                         }
98                 }
99
100                 public virtual string NewLine {
101                         get {
102                                 return new string (CoreNewLine);
103                         }
104
105                         set {
106                                 if (value == null)
107                                         value = Environment.NewLine;
108
109                                 CoreNewLine = value.ToCharArray ();
110                         }
111                 }
112
113                 public virtual void Close ()
114                 {
115                         Dispose (true);
116                 }
117
118                 protected virtual void Dispose (bool disposing)
119                 {
120                         if (disposing) {
121                                 // If we are explicitly disposed, we can avoid finalization.
122                                 GC.SuppressFinalize (this);
123                         }
124                 }
125                 public void Dispose ()
126                 {
127                         Dispose (true);
128
129                         // If we are explicitly disposed, we can avoid finalization.
130                         GC.SuppressFinalize (this);
131                 }
132
133                 public virtual void Flush ()
134                 {
135                         // do nothing
136                 }
137
138                 public static TextWriter Synchronized (TextWriter writer)
139                 {
140                         return Synchronized (writer, false);
141                 }
142
143                 internal static TextWriter Synchronized (TextWriter writer, bool neverClose)
144                 {
145                         if (writer == null)
146                                 throw new ArgumentNullException ("writer is null");
147
148                         if (writer is SynchronizedWriter)
149                                 return writer;
150
151                         return new SynchronizedWriter (writer, neverClose);
152                 }
153
154                 public virtual void Write (bool value)
155                 {
156                         Write (value.ToString ());
157                 }
158
159                 public virtual void Write (char value)
160                 {
161                         // Do nothing
162                 }
163
164                 public virtual void Write (char[] buffer)
165                 {
166                         if (buffer == null)
167                                 return;
168                         Write (buffer, 0, buffer.Length);
169                 }
170
171                 public virtual void Write (decimal value)
172                 {
173                         Write (value.ToString (internalFormatProvider));
174                 }
175
176                 public virtual void Write (double value)
177                 {
178                         Write (value.ToString (internalFormatProvider));
179                 }
180
181                 public virtual void Write (int value)
182                 {
183                         Write (value.ToString (internalFormatProvider));
184                 }
185
186                 public virtual void Write (long value)
187                 {
188                         Write (value.ToString (internalFormatProvider));
189                 }
190
191                 public virtual void Write (object value)
192                 {
193                         if (value != null)
194                                 Write (value.ToString ());
195                 }
196
197                 public virtual void Write (float value)
198                 {
199                         Write (value.ToString (internalFormatProvider));
200                 }
201
202                 public virtual void Write (string value)
203                 {
204                         if (value != null)
205                                 Write (value.ToCharArray ());
206                 }
207
208                 [CLSCompliant (false)]
209                 public virtual void Write (uint value)
210                 {
211                         Write (value.ToString (internalFormatProvider));
212                 }
213
214                 [CLSCompliant (false)]
215                 public virtual void Write (ulong value)
216                 {
217                         Write (value.ToString (internalFormatProvider));
218                 }
219
220                 public virtual void Write (string format, object arg0)
221                 {
222                         Write (String.Format (format, arg0));
223                 }
224
225                 public virtual void Write (string format, params object[] arg)
226                 {
227                         Write (String.Format (format, arg));
228                 }
229
230                 public virtual void Write (char[] buffer, int index, int count)
231                 {
232                         if (buffer == null)
233                                 throw new ArgumentNullException ("buffer");
234                         if (index < 0 || index > buffer.Length)
235                                 throw new ArgumentOutOfRangeException ("index");
236                         // re-ordered to avoid possible integer overflow
237                         if (count < 0 || (index > buffer.Length - count))
238                                 throw new ArgumentOutOfRangeException ("count");
239
240                         for (; count > 0; --count, ++index) {
241                                 Write (buffer[index]);
242                         }
243                 }
244
245                 public virtual void Write (string format, object arg0, object arg1)
246                 {
247                         Write (String.Format (format, arg0, arg1));
248                 }
249
250                 public virtual void Write (string format, object arg0, object arg1, object arg2)
251                 {
252                         Write (String.Format (format, arg0, arg1, arg2));
253                 }
254
255                 public virtual void WriteLine ()
256                 {
257                         Write (CoreNewLine);
258                 }
259
260                 public virtual void WriteLine (bool value)
261                 {
262                         Write (value);
263                         WriteLine ();
264                 }
265
266                 public virtual void WriteLine (char value)
267                 {
268                         Write (value);
269                         WriteLine ();
270                 }
271
272                 public virtual void WriteLine (char[] buffer)
273                 {
274                         Write (buffer);
275                         WriteLine ();
276                 }
277
278                 public virtual void WriteLine (decimal value)
279                 {
280                         Write (value);
281                         WriteLine ();
282                 }
283
284                 public virtual void WriteLine (double value)
285                 {
286                         Write (value);
287                         WriteLine ();
288                 }
289
290                 public virtual void WriteLine (int value)
291                 {
292                         Write (value);
293                         WriteLine ();
294                 }
295
296                 public virtual void WriteLine (long value)
297                 {
298                         Write (value);
299                         WriteLine ();
300                 }
301
302                 public virtual void WriteLine (object value)
303                 {
304                         Write (value);
305                         WriteLine ();
306                 }
307
308                 public virtual void WriteLine (float value)
309                 {
310                         Write (value);
311                         WriteLine ();
312                 }
313
314                 public virtual void WriteLine (string value)
315                 {
316                         Write (value);
317                         WriteLine ();
318                 }
319
320                 [CLSCompliant (false)]
321                 public virtual void WriteLine (uint value)
322                 {
323                         Write (value);
324                         WriteLine ();
325                 }
326
327                 [CLSCompliant (false)]
328                 public virtual void WriteLine (ulong value)
329                 {
330                         Write (value);
331                         WriteLine ();
332                 }
333
334                 public virtual void WriteLine (string format, object arg0)
335                 {
336                         Write (format, arg0);
337                         WriteLine ();
338                 }
339
340                 public virtual void WriteLine (string format, params object[] arg)
341                 {
342                         Write (format, arg);
343                         WriteLine ();
344                 }
345
346                 public virtual void WriteLine (char[] buffer, int index, int count)
347                 {
348                         Write (buffer, index, count);
349                         WriteLine ();
350                 }
351
352                 public virtual void WriteLine (string format, object arg0, object arg1)
353                 {
354                         Write (format, arg0, arg1);
355                         WriteLine ();
356                 }
357
358                 public virtual void WriteLine (string format, object arg0, object arg1, object arg2)
359                 {
360                         Write (format, arg0, arg1, arg2);
361                         WriteLine ();
362                 }
363
364 #if NET_4_5
365                 public virtual Task FlushAsync ()
366                 {
367                         return Task.Factory.StartNew (l => ((TextWriter)l).Flush (), this);
368                 }
369
370                 //
371                 // Use tuple to pack the arguments because it's faster than
372                 // setting up anonymous method container with an instance delegate
373                 //
374                 public virtual Task WriteAsync (char value)
375                 {
376                         return Task.Factory.StartNew (l => {
377                                 var t = (Tuple<TextWriter, char>) l;
378                                 t.Item1.Write (t.Item2);
379                         }, Tuple.Create (this, value));
380                 }
381
382                 public Task WriteAsync (char[] buffer)
383                 {
384                         return Task.Factory.StartNew (l => {
385                                 var t = (Tuple<TextWriter, char[]>) l;
386                                 t.Item1.Write (t.Item2);
387                         }, Tuple.Create (this, buffer));
388                 }
389
390                 public virtual Task WriteAsync (char[] buffer, int index, int count)
391                 {
392                         return Task.Factory.StartNew (l => {
393                                 var t = (Tuple<TextWriter, char[], int, int>) l;
394                                 t.Item1.Write (t.Item2, t.Item3, t.Item4);
395                         }, Tuple.Create (this, buffer, index, count));
396                 }
397
398                 public virtual Task WriteAsync (string value)
399                 {
400                         return Task.Factory.StartNew (l => {
401                                 var t = (Tuple<TextWriter, string>) l;
402                                 t.Item1.Write (t.Item2);
403                         }, Tuple.Create (this, value));
404                 }
405
406                 public virtual Task WriteLineAsync ()
407                 {
408                         return WriteAsync (CoreNewLine);
409                 }
410
411                 public virtual Task WriteLineAsync (char value)
412                 {
413                         return Task.Factory.StartNew (l => {
414                                 var t = (Tuple<TextWriter, char>) l;
415                                 t.Item1.WriteLine (t.Item2);
416                         }, Tuple.Create (this, value));
417                 }
418
419                 public Task WriteLineAsync (char[] buffer)
420                 {
421                         return Task.Factory.StartNew (l => {
422                                 var t = (Tuple<TextWriter, char[]>) l;
423                                 t.Item1.WriteLine (t.Item2);
424                         }, Tuple.Create (this, buffer));
425                 }
426
427                 public virtual Task WriteLineAsync (char[] buffer, int index, int count)
428                 {
429                         return Task.Factory.StartNew (l => {
430                                 var t = (Tuple<TextWriter, char[], int, int>) l;
431                                 t.Item1.WriteLine (t.Item2, t.Item3, t.Item4);
432                         }, Tuple.Create (this, buffer, index, count));
433                 }
434
435                 public virtual Task WriteLineAsync (string value)
436                 {
437                         return Task.Factory.StartNew (l => {
438                                 var t = (Tuple<TextWriter, string>) l;
439                                 t.Item1.WriteLine (t.Item2);
440                         }, Tuple.Create (this, value));
441                 }
442 #endif
443         }
444
445         //
446         // Sychronized version of the TextWriter.
447         //
448         [Serializable]
449         sealed class SynchronizedWriter : TextWriter
450         {
451                 private TextWriter writer;
452                 private bool neverClose;
453
454                 public SynchronizedWriter (TextWriter writer)
455                         : this (writer, false)
456                 {
457                 }
458
459                 public SynchronizedWriter (TextWriter writer, bool neverClose)
460                 {
461                         this.writer = writer;
462                         this.neverClose = neverClose;
463                 }
464
465                 public override void Close ()
466                 {
467                         if (neverClose)
468                                 return;
469                         lock (this) {
470                                 writer.Close ();
471                         }
472                 }
473
474                 public override void Flush ()
475                 {
476                         lock (this) {
477                                 writer.Flush ();
478                         }
479                 }
480
481                 #region Write methods
482                 public override void Write (bool value)
483                 {
484                         lock (this) {
485                                 writer.Write (value);
486                         }
487                 }
488
489                 public override void Write (char value)
490                 {
491                         lock (this) {
492                                 writer.Write (value);
493                         }
494                 }
495
496                 public override void Write (char[] value)
497                 {
498                         lock (this) {
499                                 writer.Write (value);
500                         }
501                 }
502
503                 public override void Write (Decimal value)
504                 {
505                         lock (this) {
506                                 writer.Write (value);
507                         }
508                 }
509
510                 public override void Write (int value)
511                 {
512                         lock (this) {
513                                 writer.Write (value);
514                         }
515                 }
516
517                 public override void Write (long value)
518                 {
519                         lock (this) {
520                                 writer.Write (value);
521                         }
522                 }
523
524                 public override void Write (object value)
525                 {
526                         lock (this) {
527                                 writer.Write (value);
528                         }
529                 }
530
531                 public override void Write (float value)
532                 {
533                         lock (this) {
534                                 writer.Write (value);
535                         }
536                 }
537
538                 public override void Write (string value)
539                 {
540                         lock (this) {
541                                 writer.Write (value);
542                         }
543                 }
544
545                 public override void Write (uint value)
546                 {
547                         lock (this) {
548                                 writer.Write (value);
549                         }
550                 }
551
552                 public override void Write (ulong value)
553                 {
554                         lock (this) {
555                                 writer.Write (value);
556                         }
557                 }
558
559                 public override void Write (string format, object value)
560                 {
561                         lock (this) {
562                                 writer.Write (format, value);
563                         }
564                 }
565
566                 public override void Write (string format, object[] value)
567                 {
568                         lock (this) {
569                                 writer.Write (format, value);
570                         }
571                 }
572
573                 public override void Write (char[] buffer, int index, int count)
574                 {
575                         lock (this) {
576                                 writer.Write (buffer, index, count);
577                         }
578                 }
579
580                 public override void Write (string format, object arg0, object arg1)
581                 {
582                         lock (this) {
583                                 writer.Write (format, arg0, arg1);
584                         }
585                 }
586
587                 public override void Write (string format, object arg0, object arg1, object arg2)
588                 {
589                         lock (this) {
590                                 writer.Write (format, arg0, arg1, arg2);
591                         }
592                 }
593                 #endregion
594                 #region WriteLine methods
595                 public override void WriteLine ()
596                 {
597                         lock (this) {
598                                 writer.WriteLine ();
599                         }
600                 }
601
602                 public override void WriteLine (bool value)
603                 {
604                         lock (this) {
605                                 writer.WriteLine (value);
606                         }
607                 }
608
609                 public override void WriteLine (char value)
610                 {
611                         lock (this) {
612                                 writer.WriteLine (value);
613                         }
614                 }
615
616                 public override void WriteLine (char[] value)
617                 {
618                         lock (this) {
619                                 writer.WriteLine (value);
620                         }
621                 }
622
623                 public override void WriteLine (Decimal value)
624                 {
625                         lock (this) {
626                                 writer.WriteLine (value);
627                         }
628                 }
629
630                 public override void WriteLine (double value)
631                 {
632                         lock (this) {
633                                 writer.WriteLine (value);
634                         }
635                 }
636
637                 public override void WriteLine (int value)
638                 {
639                         lock (this) {
640                                 writer.WriteLine (value);
641                         }
642                 }
643
644                 public override void WriteLine (long value)
645                 {
646                         lock (this) {
647                                 writer.WriteLine (value);
648                         }
649                 }
650
651                 public override void WriteLine (object value)
652                 {
653                         lock (this) {
654                                 writer.WriteLine (value);
655                         }
656                 }
657
658                 public override void WriteLine (float value)
659                 {
660                         lock (this) {
661                                 writer.WriteLine (value);
662                         }
663                 }
664
665                 public override void WriteLine (string value)
666                 {
667                         lock (this) {
668                                 writer.WriteLine (value);
669                         }
670                 }
671
672                 public override void WriteLine (uint value)
673                 {
674                         lock (this) {
675                                 writer.WriteLine (value);
676                         }
677                 }
678
679                 public override void WriteLine (ulong value)
680                 {
681                         lock (this) {
682                                 writer.WriteLine (value);
683                         }
684                 }
685
686                 public override void WriteLine (string format, object value)
687                 {
688                         lock (this) {
689                                 writer.WriteLine (format, value);
690                         }
691                 }
692
693                 public override void WriteLine (string format, object[] value)
694                 {
695                         lock (this) {
696                                 writer.WriteLine (format, value);
697                         }
698                 }
699
700                 public override void WriteLine (char[] buffer, int index, int count)
701                 {
702                         lock (this) {
703                                 writer.WriteLine (buffer, index, count);
704                         }
705                 }
706
707                 public override void WriteLine (string format, object arg0, object arg1)
708                 {
709                         lock (this) {
710                                 writer.WriteLine (format, arg0, arg1);
711                         }
712                 }
713
714                 public override void WriteLine (string format, object arg0, object arg1, object arg2)
715                 {
716                         lock (this) {
717                                 writer.WriteLine (format, arg0, arg1, arg2);
718                         }
719                 }
720                 #endregion
721
722 #if NET_4_5
723                 public override Task FlushAsync ()
724                 {
725                         lock (this) {
726                                 return writer.FlushAsync ();
727                         }
728                 }
729
730                 public override Task WriteAsync (char value)
731                 {
732                         lock (this) {
733                                 return writer.WriteAsync (value);
734                         }
735                 }
736
737                 public override Task WriteAsync (char[] buffer, int index, int count)
738                 {
739                         lock (this) {
740                                 return writer.WriteAsync (buffer, index, count);
741                         }
742                 }
743
744                 public override Task WriteAsync (string value)
745                 {
746                         lock (this) {
747                                 return writer.WriteAsync (value);
748                         }
749                 }
750
751                 public override Task WriteLineAsync ()
752                 {
753                         lock (this) {
754                                 return writer.WriteLineAsync ();
755                         }
756                 }
757
758                 public override Task WriteLineAsync (char value)
759                 {
760                         lock (this) {
761                                 return writer.WriteLineAsync (value);
762                         }
763                 }
764
765                 public override Task WriteLineAsync (char[] buffer, int index, int count)
766                 {
767                         lock (this) {
768                                 return writer.WriteLineAsync (buffer, index, count);
769                         }
770                 }
771
772                 public override Task WriteLineAsync (string value)
773                 {
774                         lock (this) {
775                                 return writer.WriteLineAsync (value);
776                         }
777                 }
778 #endif
779                 public override Encoding Encoding {
780                         get {
781                                 lock (this) {
782                                         return writer.Encoding;
783                                 }
784                         }
785                 }
786
787                 public override IFormatProvider FormatProvider {
788                         get {
789                                 lock (this) {
790                                         return writer.FormatProvider;
791                                 }
792                         }
793                 }
794
795                 public override string NewLine {
796                         get {
797                                 lock (this) {
798                                         return writer.NewLine;
799                                 }
800                         }
801
802                         set {
803                                 lock (this) {
804                                         writer.NewLine = value;
805                                 }
806                         }
807                 }
808         }
809 }