New test.
[mono.git] / mcs / class / corlib / System / Console.cs
1 //
2 // System.Console.cs
3 //
4 // Author:
5 //      Dietmar Maurer (dietmar@ximian.com)
6 //      Gonzalo Paniagua Javier (gonzalo@ximian.com)
7 //
8 // (C) Ximian, Inc.  http://www.ximian.com
9 // (C) 2004,2005 Novell, Inc. (http://www.novell.com)
10 //
11
12 // Permission is hereby granted, free of charge, to any person obtaining
13 // a copy of this software and associated documentation files (the
14 // "Software"), to deal in the Software without restriction, including
15 // without limitation the rights to use, copy, modify, merge, publish,
16 // distribute, sublicense, and/or sell copies of the Software, and to
17 // permit persons to whom the Software is furnished to do so, subject to
18 // the following conditions:
19 // 
20 // The above copyright notice and this permission notice shall be
21 // included in all copies or substantial portions of the Software.
22 // 
23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
27 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
28 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
29 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 //
31
32 using System.IO;
33 using System.Runtime.CompilerServices;
34 using System.Runtime.InteropServices;
35 using System.Security.Permissions;
36 using System.Text;
37
38 namespace System
39 {
40         public
41 #if NET_2_0
42         static
43 #else
44         sealed
45 #endif
46         class Console
47         {
48                 private class WindowsConsole
49                 {
50                         [DllImport ("kernel32.dll", CharSet=CharSet.Auto, ExactSpelling=true)]
51                         private static extern int GetConsoleCP ();
52                         [DllImport ("kernel32.dll", CharSet=CharSet.Auto, ExactSpelling=true)]
53                         private static extern int GetConsoleOutputCP ();
54
55                         [MethodImpl (MethodImplOptions.NoInlining)]
56                         public static int GetInputCodePage ()
57                         {
58                                 return GetConsoleCP ();
59                         }
60
61                         [MethodImpl (MethodImplOptions.NoInlining)]
62                         public static int GetOutputCodePage ()
63                         {
64                                 return GetConsoleOutputCP ();
65                         }
66                 }
67
68                 internal static TextWriter stdout;
69                 private static TextWriter stderr;
70                 private static TextReader stdin;
71
72                 static Console ()
73                 {
74 #if !NET_2_0
75                         Encoding inputEncoding;
76                         Encoding outputEncoding;
77 #endif
78
79                         if (Environment.IsRunningOnWindows) {
80                                 //
81                                 // On Windows, follow the Windows tradition
82                                 //
83                                 try {
84                                         inputEncoding = Encoding.GetEncoding (WindowsConsole.GetInputCodePage ());
85                                         outputEncoding = Encoding.GetEncoding (WindowsConsole.GetOutputCodePage ());
86                                         // ArgumentException and NotSupportedException can be thrown as well
87                                 } catch {
88                                         // FIXME: I18N assemblies are not available when compiling mcs
89                                         // Use Latin 1 as it is fast and UTF-8 is never used as console code page
90                                         inputEncoding = outputEncoding = Encoding.GetEncoding (28591);
91                                 }
92                         } else {
93                                 //
94                                 // On Unix systems (128), do not output the
95                                 // UTF-8 ZWNBSP (zero-width non-breaking space).
96                                 //
97                                 int code_page = 0;
98                                 Encoding.InternalCodePage (ref code_page);
99
100                                 if (code_page != -1 && ((code_page & 0x0fffffff) == 3 // UTF8Encoding.UTF8_CODE_PAGE
101                                         || ((code_page & 0x10000000) != 0)))
102                                         inputEncoding = outputEncoding = Encoding.UTF8Unmarked;
103                                 else
104                                         inputEncoding = outputEncoding = Encoding.Default;
105                         }
106
107                         stderr = new UnexceptionalStreamWriter (OpenStandardError (0), outputEncoding); 
108                         ((StreamWriter)stderr).AutoFlush = true;
109                         stderr = TextWriter.Synchronized (stderr, true);
110
111 #if NET_2_0
112                         if (!Environment.IsRunningOnWindows && ConsoleDriver.IsConsole) {
113                                 StreamWriter w = new CStreamWriter (OpenStandardOutput (0), outputEncoding);
114                                 w.AutoFlush = true;
115                                 stdout = w;
116                                 stdin = new CStreamReader (OpenStandardInput (0), inputEncoding);
117                                 ConsoleDriver.Init ();
118                         } else {
119 #endif
120                                 stdout = new UnexceptionalStreamWriter (OpenStandardOutput (0), outputEncoding);
121                                 ((StreamWriter)stdout).AutoFlush = true;
122                                 stdout = TextWriter.Synchronized (stdout, true);
123                                 stdin = new UnexceptionalStreamReader (OpenStandardInput (0), inputEncoding);
124                                 stdin = TextReader.Synchronized (stdin);
125 #if NET_2_0
126                         }
127 #endif
128
129                         GC.SuppressFinalize (stdout);
130                         GC.SuppressFinalize (stderr);
131                         GC.SuppressFinalize (stdin);
132                 }
133
134 #if !NET_2_0
135                 private Console ()
136                 {
137                 }
138 #endif
139
140                 public static TextWriter Error {
141                         get {
142                                 return stderr;
143                         }
144                 }
145
146                 public static TextWriter Out {
147                         get {
148                                 return stdout;
149                         }
150                 }
151
152                 public static TextReader In {
153                         get {
154                                 return stdin;
155                         }
156                 }
157
158                 public static Stream OpenStandardError ()
159                 {
160                         return OpenStandardError (0);
161                 }
162
163                 // calling any FileStream constructor with a handle normally
164                 // requires permissions UnmanagedCode permissions. In this 
165                 // case we assert this permission so the console can be used
166                 // in partial trust (i.e. without having UnmanagedCode).
167                 [SecurityPermission (SecurityAction.Assert, UnmanagedCode = true)]
168                 public static Stream OpenStandardError (int bufferSize)
169                 {
170                         try {
171                                 return new FileStream (MonoIO.ConsoleError, FileAccess.Write, false, bufferSize, false, bufferSize == 0);
172                         } catch (IOException) {
173                                 return new NullStream ();
174                         }
175                 }
176
177                 public static Stream OpenStandardInput ()
178                 {
179                         return OpenStandardInput (0);
180                 }
181
182                 // calling any FileStream constructor with a handle normally
183                 // requires permissions UnmanagedCode permissions. In this 
184                 // case we assert this permission so the console can be used
185                 // in partial trust (i.e. without having UnmanagedCode).
186                 [SecurityPermission (SecurityAction.Assert, UnmanagedCode = true)]
187                 public static Stream OpenStandardInput (int bufferSize)
188                 {
189                         try {
190                                 return new FileStream (MonoIO.ConsoleInput, FileAccess.Read, false, bufferSize, false, bufferSize == 0);
191                         } catch (IOException) {
192                                 return new NullStream ();
193                         }
194                 }
195
196                 public static Stream OpenStandardOutput ()
197                 {
198                         return OpenStandardOutput (0);
199                 }
200
201                 // calling any FileStream constructor with a handle normally
202                 // requires permissions UnmanagedCode permissions. In this 
203                 // case we assert this permission so the console can be used
204                 // in partial trust (i.e. without having UnmanagedCode).
205                 [SecurityPermission (SecurityAction.Assert, UnmanagedCode = true)]
206                 public static Stream OpenStandardOutput (int bufferSize)
207                 {
208                         try {
209                                 return new FileStream (MonoIO.ConsoleOutput, FileAccess.Write, false, bufferSize, false, bufferSize == 0);
210                         } catch (IOException) {
211                                 return new NullStream ();
212                         }
213                 }
214
215                 [SecurityPermission (SecurityAction.Demand, UnmanagedCode = true)]
216                 public static void SetError (TextWriter newError)
217                 {
218                         if (newError == null)
219                                 throw new ArgumentNullException ("newError");
220
221                         stderr = newError;
222                 }
223
224                 [SecurityPermission (SecurityAction.Demand, UnmanagedCode = true)]
225                 public static void SetIn (TextReader newIn)
226                 {
227                         if (newIn == null)
228                                 throw new ArgumentNullException ("newIn");
229
230                         stdin = newIn;
231                 }
232
233                 [SecurityPermission (SecurityAction.Demand, UnmanagedCode = true)]
234                 public static void SetOut (TextWriter newOut)
235                 {
236                         if (newOut == null)
237                                 throw new ArgumentNullException ("newOut");
238
239                         stdout = newOut;
240                 }
241
242                 public static void Write (bool value)
243                 {
244                         stdout.Write (value);
245                 }
246
247                 public static void Write (char value)
248                 {
249                         stdout.Write (value);
250                 }
251
252                 public static void Write (char[] value)
253                 {
254                         stdout.Write (value);
255                 }
256
257                 public static void Write (decimal value)
258                 {
259                         stdout.Write (value);
260                 }
261                 
262                 public static void Write (double value)
263                 {
264                         stdout.Write (value);
265                 }
266
267                 public static void Write (int value)
268                 {
269                         stdout.Write (value);
270                 }
271
272                 public static void Write (long value)
273                 {
274                         stdout.Write (value);
275                 }
276
277                 public static void Write (object value)
278                 {
279                         stdout.Write (value);
280                 }
281
282                 public static void Write (float value)
283                 {
284                         stdout.Write (value);
285                 }
286
287                 public static void Write (string value)
288                 {
289                         stdout.Write (value);
290                 }
291
292                 [CLSCompliant (false)]
293                 public static void Write (uint value)
294                 {
295                         stdout.Write (value);
296                 }
297
298                 [CLSCompliant (false)]
299                 public static void Write (ulong value)
300                 {
301                         stdout.Write (value);
302                 }
303
304                 public static void Write (string format, object arg0)
305                 {
306                         stdout.Write (format, arg0);
307                 }
308
309                 public static void Write (string format, params object[] arg)
310                 {
311                         stdout.Write (format, arg);
312                 }
313
314                 public static void Write (char[] buffer, int index, int count)
315                 {
316                         stdout.Write (buffer, index, count);
317                 }
318
319                 public static void Write (string format, object arg0, object arg1)
320                 {
321                         stdout.Write (format, arg0, arg1);
322                 }
323
324                 public static void Write (string format, object arg0, object arg1, object arg2 )
325                 {
326                         stdout.Write (format, arg0, arg1, arg2);
327                 }
328
329 #if ! BOOTSTRAP_WITH_OLDLIB
330                 [CLSCompliant (false)]
331                 public static void Write (string format, object arg0, object arg1, object arg2, object arg3, __arglist)
332                 {
333                         ArgIterator iter = new ArgIterator (__arglist);
334                         int argCount = iter.GetRemainingCount();
335
336                         object[] args = new object [argCount + 4];
337                         args [0] = arg0;
338                         args [1] = arg1;
339                         args [2] = arg2;
340                         args [3] = arg3;
341                         for (int i = 0; i < argCount; i++) {
342                                 TypedReference typedRef = iter.GetNextArg ();
343                                 args [i + 4] = TypedReference.ToObject (typedRef);
344                         }
345
346                         stdout.Write (String.Format (format, args));
347                 }
348 #endif
349
350                 public static void WriteLine ()
351                 {
352                         stdout.WriteLine ();
353                 }
354
355                 public static void WriteLine (bool value)
356                 {
357                         stdout.WriteLine (value);
358                 }
359
360                 public static void WriteLine (char value)
361                 {
362                         stdout.WriteLine (value);
363                 }
364
365                 public static void WriteLine (char[] value)
366                 {
367                         stdout.WriteLine (value);
368                 }
369
370                 public static void WriteLine (decimal value)
371                 {
372                         stdout.WriteLine (value);
373                 }
374
375                 public static void WriteLine (double value)
376                 {
377                         stdout.WriteLine (value);
378                 }
379
380                 public static void WriteLine (int value)
381                 {
382                         stdout.WriteLine (value);
383                 }
384
385                 public static void WriteLine (long value)
386                 {
387                         stdout.WriteLine (value);
388                 }
389
390                 public static void WriteLine (object value)
391                 {
392                         stdout.WriteLine (value);
393                 }
394
395                 public static void WriteLine (float value)
396                 {
397                         stdout.WriteLine (value);
398                 }
399
400                 public static void WriteLine (string value)
401                 {
402                         stdout.WriteLine (value);
403                 }
404
405                 [CLSCompliant (false)]
406                 public static void WriteLine (uint value)
407                 {
408                         stdout.WriteLine (value);
409                 }
410
411                 [CLSCompliant (false)]
412                 public static void WriteLine (ulong value)
413                 {
414                         stdout.WriteLine (value);
415                 }
416
417                 public static void WriteLine (string format, object arg0)
418                 {
419                         stdout.WriteLine (format, arg0);
420                 }
421
422                 public static void WriteLine (string format, params object[] arg)
423                 {
424                         stdout.WriteLine (format, arg);
425                 }
426
427                 public static void WriteLine (char[] buffer, int index, int count)
428                 {
429                         stdout.WriteLine (buffer, index, count);
430                 }
431
432                 public static void WriteLine (string format, object arg0, object arg1)
433                 {
434                         stdout.WriteLine (format, arg0, arg1);
435                 }
436
437                 public static void WriteLine (string format, object arg0, object arg1, object arg2)
438                 {
439                         stdout.WriteLine (format, arg0, arg1, arg2);
440                 }
441
442 #if ! BOOTSTRAP_WITH_OLDLIB
443                 [CLSCompliant (false)]
444                 public static void WriteLine (string format, object arg0, object arg1, object arg2, object arg3, __arglist)
445                 {
446                         ArgIterator iter = new ArgIterator (__arglist);
447                         int argCount = iter.GetRemainingCount();
448
449                         object[] args = new object [argCount + 4];
450                         args [0] = arg0;
451                         args [1] = arg1;
452                         args [2] = arg2;
453                         args [3] = arg3;
454                         for (int i = 0; i < argCount; i++) {
455                                 TypedReference typedRef = iter.GetNextArg ();
456                                 args [i + 4] = TypedReference.ToObject (typedRef);
457                         }
458
459                         stdout.WriteLine (String.Format (format, args));
460                 }
461 #endif
462
463 #if NET_2_0
464                 public static int Read ()
465                 {
466                         if ((stdin is CStreamReader) && ConsoleDriver.IsConsole) {
467                                 return ConsoleDriver.Read ();
468                         } else {
469                                 return stdin.Read ();
470                         }
471                 }
472
473                 public static string ReadLine ()
474                 {
475                         if ((stdin is CStreamReader) && ConsoleDriver.IsConsole) {
476                                 return ConsoleDriver.ReadLine ();
477                         } else {
478                                 return stdin.ReadLine ();
479                         }
480                 }
481 #else
482                 public static int Read ()
483                 {
484                         return stdin.Read ();
485                 }
486
487                 public static string ReadLine ()
488                 {
489                         return stdin.ReadLine ();
490                 }
491
492 #endif
493
494 #if NET_2_0
495                 // FIXME: Console should use these encodings when changed
496                 static Encoding inputEncoding;
497                 static Encoding outputEncoding;
498
499                 public static Encoding InputEncoding {
500                         get { return inputEncoding; }
501                         set { inputEncoding = value; }
502                 }
503
504                 public static Encoding OutputEncoding {
505                         get { return outputEncoding; }
506                         set { outputEncoding = value; }
507                 }
508
509                 public static ConsoleColor BackgroundColor {
510                         get { return ConsoleDriver.BackgroundColor; }
511                         set { ConsoleDriver.BackgroundColor = value; }
512                 }
513
514                 public static int BufferHeight {
515                         get { return ConsoleDriver.BufferHeight; }
516                         set { ConsoleDriver.BufferHeight = value; }
517                 }
518
519                 public static int BufferWidth {
520                         get { return ConsoleDriver.BufferWidth; }
521                         set { ConsoleDriver.BufferWidth = value; }
522                 }
523
524                 public static int CursorLeft {
525                         get { return ConsoleDriver.CursorLeft; }
526                         set { ConsoleDriver.CursorLeft = value; }
527                 }
528
529                 public static int CursorTop {
530                         get { return ConsoleDriver.CursorTop; }
531                         set { ConsoleDriver.CursorTop = value; }
532                 }
533
534                 public static bool CursorVisible {
535                         get { return ConsoleDriver.CursorVisible; }
536                         set { ConsoleDriver.CursorVisible = value; }
537                 }
538
539                 public static ConsoleColor ForegroundColor {
540                         get { return ConsoleDriver.ForegroundColor; }
541                         set { ConsoleDriver.ForegroundColor = value; }
542                 }
543
544                 public static bool KeyAvailable {
545                         get { return ConsoleDriver.KeyAvailable; }
546                 }
547
548                 public static string Title {
549                         get { return ConsoleDriver.Title; }
550                         set { ConsoleDriver.Title = value; }
551                 }
552
553                 public static bool TreatControlCAsInput {
554                         get { return ConsoleDriver.TreatControlCAsInput; }
555                         set { ConsoleDriver.TreatControlCAsInput = value; }
556                 }
557
558                 public static int WindowHeight {
559                         get { return ConsoleDriver.WindowHeight; }
560                         set { ConsoleDriver.WindowHeight = value; }
561                 }
562
563                 public static int WindowLeft {
564                         get { return ConsoleDriver.WindowLeft; }
565                         set { ConsoleDriver.WindowLeft = value; }
566                 }
567
568                 public static int WindowTop {
569                         get { return ConsoleDriver.WindowTop; }
570                         set { ConsoleDriver.WindowTop = value; }
571                 }
572
573                 public static int WindowWidth {
574                         get { return ConsoleDriver.WindowWidth; }
575                         set { ConsoleDriver.WindowWidth = value; }
576                 }
577
578                 public static void Beep ()
579                 {
580                         Beep (1000, 500);
581                 }
582
583                 public static void Beep (int frequency, int duration)
584                 {
585                         if (frequency < 37 || frequency > 32767)
586                                 throw new ArgumentOutOfRangeException ("frequency");
587
588                         if (duration <= 0)
589                                 throw new ArgumentOutOfRangeException ("duration");
590
591                         ConsoleDriver.Beep (frequency, duration);
592                 }
593
594                 public static void Clear ()
595                 {
596                         ConsoleDriver.Clear ();
597                 }
598
599                 [MonoTODO]
600                 public static void MoveBufferArea (int sourceLeft, int sourceTop, int sourceWidth, int sourceHeight,
601                                                 int targetLeft, int targetTop)
602                 {
603                         throw new NotImplementedException ();
604                 }
605
606                 [MonoTODO]
607                 public static void MoveBufferArea (int sourceLeft, int sourceTop, int sourceWidth, int sourceHeight,
608                                                 int targetLeft, int targetTop, Char sourceChar,
609                                                 ConsoleColor sourceForeColor, ConsoleColor sourceBackColor)
610                 {
611                         throw new NotImplementedException ();
612                 }
613
614                 public static ConsoleKeyInfo ReadKey ()
615                 {
616                         return ReadKey (false);
617                 }
618
619                 public static ConsoleKeyInfo ReadKey (bool intercept)
620                 {
621                         return ConsoleDriver.ReadKey (intercept);
622                 }
623
624                 public static void ResetColor ()
625                 {
626                         ConsoleDriver.ResetColor ();
627                 }
628
629                 public static void SetBufferSize (int width, int height)
630                 {
631                         ConsoleDriver.SetBufferSize (width, height);
632                 }
633
634                 public static void SetCursorPosition (int left, int top)
635                 {
636                         ConsoleDriver.SetCursorPosition (left, top);
637                 }
638
639                 public static void SetWindowPosition (int left, int top)
640                 {
641                         ConsoleDriver.SetWindowPosition (left, top);
642                 }
643
644                 public static void SetWindowSize (int width, int height)
645                 {
646                         ConsoleDriver.SetWindowSize (width, height);
647                 }
648
649                 public static event ConsoleCancelEventHandler CancelKeyPress;
650
651                 delegate void InternalCancelHandler ();
652                 static InternalCancelHandler cancel_handler = new InternalCancelHandler (DoConsoleCancelEvent);
653
654                 internal static void DoConsoleCancelEvent ()
655                 {
656                         bool exit = true;
657                         if (CancelKeyPress != null) {
658                                 ConsoleCancelEventArgs args = new ConsoleCancelEventArgs (ConsoleSpecialKey.ControlC);
659                                 Delegate [] delegates = CancelKeyPress.GetInvocationList ();
660                                 foreach (ConsoleCancelEventHandler d in delegates){
661                                         try {
662                                                 // Sender is always null here.
663                                                 d (null, args);
664                                         } catch {} // Ignore any exception.
665                                 }
666                                 exit = !args.Cancel;
667                         }
668
669                         if (exit)
670                                 Environment.Exit (58);
671                 }
672 #endif
673         }
674 }
675