2010-04-07 Jb Evain <jbevain@novell.com>
[mcs.git] / class / corlib / System / Console.cs
blobea9365e689fae20a2f144e5a859ac854217e1d35
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)
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.
32 using System.Diagnostics;
33 using System.IO;
34 using System.Runtime.CompilerServices;
35 using System.Runtime.InteropServices;
36 using System.Security;
37 using System.Security.Permissions;
38 using System.Text;
40 namespace System
42 public static class Console
44 #if !NET_2_1
45 private class WindowsConsole
47 [DllImport ("kernel32.dll", CharSet=CharSet.Auto, ExactSpelling=true)]
48 private static extern int GetConsoleCP ();
49 [DllImport ("kernel32.dll", CharSet=CharSet.Auto, ExactSpelling=true)]
50 private static extern int GetConsoleOutputCP ();
52 [MethodImpl (MethodImplOptions.NoInlining)]
53 public static int GetInputCodePage ()
55 return GetConsoleCP ();
58 [MethodImpl (MethodImplOptions.NoInlining)]
59 public static int GetOutputCodePage ()
61 return GetConsoleOutputCP ();
64 #endif
65 internal static TextWriter stdout;
66 private static TextWriter stderr;
67 private static TextReader stdin;
69 static Console ()
71 #if NET_2_1
72 Encoding inputEncoding;
73 Encoding outputEncoding;
74 #endif
76 if (Environment.IsRunningOnWindows) {
78 // On Windows, follow the Windows tradition
80 #if NET_2_1
81 // should never happen since Moonlight does not run on windows
82 inputEncoding = outputEncoding = Encoding.Default;
83 #else
84 try {
85 inputEncoding = Encoding.GetEncoding (WindowsConsole.GetInputCodePage ());
86 outputEncoding = Encoding.GetEncoding (WindowsConsole.GetOutputCodePage ());
87 // ArgumentException and NotSupportedException can be thrown as well
88 } catch {
89 // FIXME: I18N assemblies are not available when compiling mcs
90 // Use Latin 1 as it is fast and UTF-8 is never used as console code page
91 inputEncoding = outputEncoding = Encoding.Default;
93 #endif
94 } else {
96 // On Unix systems (128), do not output the
97 // UTF-8 ZWNBSP (zero-width non-breaking space).
99 int code_page = 0;
100 Encoding.InternalCodePage (ref code_page);
102 if (code_page != -1 && ((code_page & 0x0fffffff) == 3 // UTF8Encoding.UTF8_CODE_PAGE
103 || ((code_page & 0x10000000) != 0)))
104 inputEncoding = outputEncoding = Encoding.UTF8Unmarked;
105 else
106 inputEncoding = outputEncoding = Encoding.Default;
109 stderr = new UnexceptionalStreamWriter (OpenStandardError (0), outputEncoding);
110 ((StreamWriter)stderr).AutoFlush = true;
111 stderr = TextWriter.Synchronized (stderr, true);
113 #if !NET_2_1
114 if (!Environment.IsRunningOnWindows && ConsoleDriver.IsConsole) {
115 StreamWriter w = new CStreamWriter (OpenStandardOutput (0), outputEncoding);
116 w.AutoFlush = true;
117 stdout = TextWriter.Synchronized (w, true);
118 stdin = new CStreamReader (OpenStandardInput (0), inputEncoding);
119 } else {
120 #endif
121 stdout = new UnexceptionalStreamWriter (OpenStandardOutput (0), outputEncoding);
122 ((StreamWriter)stdout).AutoFlush = true;
123 stdout = TextWriter.Synchronized (stdout, true);
124 stdin = new UnexceptionalStreamReader (OpenStandardInput (0), inputEncoding);
125 stdin = TextReader.Synchronized (stdin);
126 #if !NET_2_1
128 #endif
130 GC.SuppressFinalize (stdout);
131 GC.SuppressFinalize (stderr);
132 GC.SuppressFinalize (stdin);
135 public static TextWriter Error {
136 get {
137 return stderr;
141 public static TextWriter Out {
142 get {
143 return stdout;
147 public static TextReader In {
148 get {
149 return stdin;
153 private static Stream Open (IntPtr handle, FileAccess access, int bufferSize)
155 #if MOONLIGHT
156 if (SecurityManager.SecurityEnabled && !Debugger.IsAttached && Environment.GetEnvironmentVariable ("MOONLIGHT_ENABLE_CONSOLE") == null)
157 return new NullStream ();
158 #endif
159 try {
160 return new FileStream (handle, access, false, bufferSize, false, bufferSize == 0);
161 } catch (IOException) {
162 return new NullStream ();
166 public static Stream OpenStandardError ()
168 return OpenStandardError (0);
171 // calling any FileStream constructor with a handle normally
172 // requires permissions UnmanagedCode permissions. In this
173 // case we assert this permission so the console can be used
174 // in partial trust (i.e. without having UnmanagedCode).
175 [SecurityPermission (SecurityAction.Assert, UnmanagedCode = true)]
176 public static Stream OpenStandardError (int bufferSize)
178 return Open (MonoIO.ConsoleError, FileAccess.Write, bufferSize);
181 public static Stream OpenStandardInput ()
183 return OpenStandardInput (0);
186 // calling any FileStream constructor with a handle normally
187 // requires permissions UnmanagedCode permissions. In this
188 // case we assert this permission so the console can be used
189 // in partial trust (i.e. without having UnmanagedCode).
190 [SecurityPermission (SecurityAction.Assert, UnmanagedCode = true)]
191 public static Stream OpenStandardInput (int bufferSize)
193 return Open (MonoIO.ConsoleInput, FileAccess.Read, bufferSize);
196 public static Stream OpenStandardOutput ()
198 return OpenStandardOutput (0);
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)
208 return Open (MonoIO.ConsoleOutput, FileAccess.Write, bufferSize);
211 [SecurityPermission (SecurityAction.Demand, UnmanagedCode = true)]
212 public static void SetError (TextWriter newError)
214 if (newError == null)
215 throw new ArgumentNullException ("newError");
217 stderr = newError;
220 [SecurityPermission (SecurityAction.Demand, UnmanagedCode = true)]
221 public static void SetIn (TextReader newIn)
223 if (newIn == null)
224 throw new ArgumentNullException ("newIn");
226 stdin = newIn;
229 [SecurityPermission (SecurityAction.Demand, UnmanagedCode = true)]
230 public static void SetOut (TextWriter newOut)
232 if (newOut == null)
233 throw new ArgumentNullException ("newOut");
235 stdout = newOut;
238 public static void Write (bool value)
240 stdout.Write (value);
243 public static void Write (char value)
245 stdout.Write (value);
248 public static void Write (char[] buffer)
250 stdout.Write (buffer);
253 public static void Write (decimal value)
255 stdout.Write (value);
258 public static void Write (double value)
260 stdout.Write (value);
263 public static void Write (int value)
265 stdout.Write (value);
268 public static void Write (long value)
270 stdout.Write (value);
273 public static void Write (object value)
275 stdout.Write (value);
278 public static void Write (float value)
280 stdout.Write (value);
283 public static void Write (string value)
285 stdout.Write (value);
288 [CLSCompliant (false)]
289 public static void Write (uint value)
291 stdout.Write (value);
294 [CLSCompliant (false)]
295 public static void Write (ulong value)
297 stdout.Write (value);
300 public static void Write (string format, object arg0)
302 stdout.Write (format, arg0);
305 public static void Write (string format, params object[] arg)
307 stdout.Write (format, arg);
310 public static void Write (char[] buffer, int index, int count)
312 stdout.Write (buffer, index, count);
315 public static void Write (string format, object arg0, object arg1)
317 stdout.Write (format, arg0, arg1);
320 public static void Write (string format, object arg0, object arg1, object arg2 )
322 stdout.Write (format, arg0, arg1, arg2);
325 [CLSCompliant (false)]
326 public static void Write (string format, object arg0, object arg1, object arg2, object arg3, __arglist)
328 ArgIterator iter = new ArgIterator (__arglist);
329 int argCount = iter.GetRemainingCount();
331 object[] args = new object [argCount + 4];
332 args [0] = arg0;
333 args [1] = arg1;
334 args [2] = arg2;
335 args [3] = arg3;
336 for (int i = 0; i < argCount; i++) {
337 TypedReference typedRef = iter.GetNextArg ();
338 args [i + 4] = TypedReference.ToObject (typedRef);
341 stdout.Write (String.Format (format, args));
344 public static void WriteLine ()
346 stdout.WriteLine ();
349 public static void WriteLine (bool value)
351 stdout.WriteLine (value);
354 public static void WriteLine (char value)
356 stdout.WriteLine (value);
359 public static void WriteLine (char[] buffer)
361 stdout.WriteLine (buffer);
364 public static void WriteLine (decimal value)
366 stdout.WriteLine (value);
369 public static void WriteLine (double value)
371 stdout.WriteLine (value);
374 public static void WriteLine (int value)
376 stdout.WriteLine (value);
379 public static void WriteLine (long value)
381 stdout.WriteLine (value);
384 public static void WriteLine (object value)
386 stdout.WriteLine (value);
389 public static void WriteLine (float value)
391 stdout.WriteLine (value);
394 public static void WriteLine (string value)
396 stdout.WriteLine (value);
399 [CLSCompliant (false)]
400 public static void WriteLine (uint value)
402 stdout.WriteLine (value);
405 [CLSCompliant (false)]
406 public static void WriteLine (ulong value)
408 stdout.WriteLine (value);
411 public static void WriteLine (string format, object arg0)
413 stdout.WriteLine (format, arg0);
416 public static void WriteLine (string format, params object[] arg)
418 stdout.WriteLine (format, arg);
421 public static void WriteLine (char[] buffer, int index, int count)
423 stdout.WriteLine (buffer, index, count);
426 public static void WriteLine (string format, object arg0, object arg1)
428 stdout.WriteLine (format, arg0, arg1);
431 public static void WriteLine (string format, object arg0, object arg1, object arg2)
433 stdout.WriteLine (format, arg0, arg1, arg2);
436 [CLSCompliant (false)]
437 public static void WriteLine (string format, object arg0, object arg1, object arg2, object arg3, __arglist)
439 ArgIterator iter = new ArgIterator (__arglist);
440 int argCount = iter.GetRemainingCount();
442 object[] args = new object [argCount + 4];
443 args [0] = arg0;
444 args [1] = arg1;
445 args [2] = arg2;
446 args [3] = arg3;
447 for (int i = 0; i < argCount; i++) {
448 TypedReference typedRef = iter.GetNextArg ();
449 args [i + 4] = TypedReference.ToObject (typedRef);
452 stdout.WriteLine (String.Format (format, args));
455 #if !NET_2_1
456 public static int Read ()
458 if ((stdin is CStreamReader) && ConsoleDriver.IsConsole) {
459 return ConsoleDriver.Read ();
460 } else {
461 return stdin.Read ();
465 public static string ReadLine ()
467 if ((stdin is CStreamReader) && ConsoleDriver.IsConsole) {
468 return ConsoleDriver.ReadLine ();
469 } else {
470 return stdin.ReadLine ();
473 #else
474 public static int Read ()
476 return stdin.Read ();
479 public static string ReadLine ()
481 return stdin.ReadLine ();
484 #endif
486 #if !NET_2_1
487 // FIXME: Console should use these encodings when changed
488 static Encoding inputEncoding;
489 static Encoding outputEncoding;
491 public static Encoding InputEncoding {
492 get { return inputEncoding; }
493 set { inputEncoding = value; }
496 public static Encoding OutputEncoding {
497 get { return outputEncoding; }
498 set { outputEncoding = value; }
501 public static ConsoleColor BackgroundColor {
502 get { return ConsoleDriver.BackgroundColor; }
503 set { ConsoleDriver.BackgroundColor = value; }
506 public static int BufferHeight {
507 get { return ConsoleDriver.BufferHeight; }
508 [MonoLimitation ("Implemented only on Windows")]
509 set { ConsoleDriver.BufferHeight = value; }
512 public static int BufferWidth {
513 get { return ConsoleDriver.BufferWidth; }
514 [MonoLimitation ("Implemented only on Windows")]
515 set { ConsoleDriver.BufferWidth = value; }
518 [MonoLimitation ("Implemented only on Windows")]
519 public static bool CapsLock {
520 get { return ConsoleDriver.CapsLock; }
523 public static int CursorLeft {
524 get { return ConsoleDriver.CursorLeft; }
525 set { ConsoleDriver.CursorLeft = value; }
528 public static int CursorTop {
529 get { return ConsoleDriver.CursorTop; }
530 set { ConsoleDriver.CursorTop = value; }
533 public static int CursorSize {
534 get { return ConsoleDriver.CursorSize; }
535 set { ConsoleDriver.CursorSize = value; }
538 public static bool CursorVisible {
539 get { return ConsoleDriver.CursorVisible; }
540 set { ConsoleDriver.CursorVisible = value; }
543 public static ConsoleColor ForegroundColor {
544 get { return ConsoleDriver.ForegroundColor; }
545 set { ConsoleDriver.ForegroundColor = value; }
548 public static bool KeyAvailable {
549 get { return ConsoleDriver.KeyAvailable; }
552 public static int LargestWindowHeight {
553 get { return ConsoleDriver.LargestWindowHeight; }
556 public static int LargestWindowWidth {
557 get { return ConsoleDriver.LargestWindowWidth; }
560 [MonoLimitation ("Only works on windows")]
561 public static bool NumberLock {
562 get { return ConsoleDriver.NumberLock; }
565 public static string Title {
566 get { return ConsoleDriver.Title; }
567 set { ConsoleDriver.Title = value; }
570 public static bool TreatControlCAsInput {
571 get { return ConsoleDriver.TreatControlCAsInput; }
572 set { ConsoleDriver.TreatControlCAsInput = value; }
575 [MonoLimitation ("Only works on windows")]
576 public static int WindowHeight {
577 get { return ConsoleDriver.WindowHeight; }
578 set { ConsoleDriver.WindowHeight = value; }
581 [MonoLimitation ("Only works on windows")]
582 public static int WindowLeft {
583 get { return ConsoleDriver.WindowLeft; }
584 set { ConsoleDriver.WindowLeft = value; }
587 [MonoLimitation ("Only works on windows")]
588 public static int WindowTop {
589 get { return ConsoleDriver.WindowTop; }
590 set { ConsoleDriver.WindowTop = value; }
593 [MonoLimitation ("Only works on windows")]
594 public static int WindowWidth {
595 get { return ConsoleDriver.WindowWidth; }
596 set { ConsoleDriver.WindowWidth = value; }
599 public static void Beep ()
601 Beep (1000, 500);
604 public static void Beep (int frequency, int duration)
606 if (frequency < 37 || frequency > 32767)
607 throw new ArgumentOutOfRangeException ("frequency");
609 if (duration <= 0)
610 throw new ArgumentOutOfRangeException ("duration");
612 ConsoleDriver.Beep (frequency, duration);
615 public static void Clear ()
617 ConsoleDriver.Clear ();
620 [MonoLimitation ("Implemented only on Windows")]
621 public static void MoveBufferArea (int sourceLeft, int sourceTop, int sourceWidth, int sourceHeight,
622 int targetLeft, int targetTop)
624 ConsoleDriver.MoveBufferArea (sourceLeft, sourceTop, sourceWidth, sourceHeight, targetLeft, targetTop);
627 [MonoLimitation ("Implemented only on Windows")]
628 public static void MoveBufferArea (int sourceLeft, int sourceTop, int sourceWidth, int sourceHeight,
629 int targetLeft, int targetTop, Char sourceChar,
630 ConsoleColor sourceForeColor, ConsoleColor sourceBackColor)
632 ConsoleDriver.MoveBufferArea (sourceLeft, sourceTop, sourceWidth, sourceHeight, targetLeft, targetTop,
633 sourceChar, sourceForeColor, sourceBackColor);
636 public static ConsoleKeyInfo ReadKey ()
638 return ReadKey (false);
641 public static ConsoleKeyInfo ReadKey (bool intercept)
643 return ConsoleDriver.ReadKey (intercept);
646 public static void ResetColor ()
648 ConsoleDriver.ResetColor ();
651 [MonoLimitation ("Only works on windows")]
652 public static void SetBufferSize (int width, int height)
654 ConsoleDriver.SetBufferSize (width, height);
657 public static void SetCursorPosition (int left, int top)
659 ConsoleDriver.SetCursorPosition (left, top);
662 public static void SetWindowPosition (int left, int top)
664 ConsoleDriver.SetWindowPosition (left, top);
667 public static void SetWindowSize (int width, int height)
669 ConsoleDriver.SetWindowSize (width, height);
672 static ConsoleCancelEventHandler cancel_event;
673 public static event ConsoleCancelEventHandler CancelKeyPress {
674 add {
675 if (ConsoleDriver.Initialized == false)
676 ConsoleDriver.Init ();
678 cancel_event += value;
680 remove {
681 if (ConsoleDriver.Initialized == false)
682 ConsoleDriver.Init ();
684 cancel_event -= value;
688 delegate void InternalCancelHandler ();
690 #pragma warning disable 414
692 // Used by console-io.c
694 static readonly InternalCancelHandler cancel_handler = new InternalCancelHandler (DoConsoleCancelEvent);
695 #pragma warning restore 414
697 internal static void DoConsoleCancelEvent ()
699 bool exit = true;
700 if (cancel_event != null) {
701 ConsoleCancelEventArgs args = new ConsoleCancelEventArgs (ConsoleSpecialKey.ControlC);
702 Delegate [] delegates = cancel_event.GetInvocationList ();
703 foreach (ConsoleCancelEventHandler d in delegates){
704 try {
705 // Sender is always null here.
706 d (null, args);
707 } catch {} // Ignore any exception.
709 exit = !args.Cancel;
712 if (exit)
713 Environment.Exit (58);
715 #endif