Merge pull request #1068 from esdrubal/bug18421
[mono.git] / mcs / class / corlib / System / Console.iOS.cs
1 //
2 // Helper for Console to allow indirect access to `stdout` using NSLog
3 //
4 // Authors:
5 //      Sebastien Pouliot  <sebastien@xamarin.com>
6 //
7 // Copyright 2012-2014 Xamarin Inc. All rights reserved.
8 //
9
10 #if FULL_AOT_RUNTIME
11
12 using System;
13 using System.IO;
14 using System.Runtime.InteropServices;
15 using System.Text;
16
17 namespace System {
18
19         public static partial class Console {
20
21                 class NSLogWriter : TextWriter {
22                         [DllImport ("__Internal", CharSet=CharSet.Unicode)]
23                         extern static void monotouch_log (string s);
24
25                         [DllImport ("/usr/lib/libSystem.dylib")]
26                         extern static /* ssize_t */ IntPtr write (int fd, byte [] buffer, /* size_t */ IntPtr n);
27                         
28                         StringBuilder sb;
29                         
30                         public NSLogWriter ()
31                         {
32                                 sb = new StringBuilder ();
33                         }
34                         
35                         public override System.Text.Encoding Encoding {
36                                 get { return System.Text.Encoding.UTF8; }
37                         }
38
39                         static void direct_write_to_stdout (string s)
40                         {
41                                 byte [] b = Encoding.Default.GetBytes (s);
42                                 var len = (IntPtr) b.Length;
43                                 while ((int) write (1, b, len) == -1 && Marshal.GetLastWin32Error () == /* EINTR*/ 4)
44                                         ;
45                         }
46                         
47                         public override void Flush ()
48                         {
49                                 string s = sb.ToString ();
50                                 try {
51                                         monotouch_log (s);
52                                 }
53                                 catch (Exception) {
54                                         try {
55                                                 direct_write_to_stdout (s);
56                                                 direct_write_to_stdout (Environment.NewLine);
57                                         } catch (Exception){}
58                                 }
59                                 sb.Length = 0;
60                         }
61                         
62                         // minimum to override - see http://msdn.microsoft.com/en-us/library/system.io.textwriter.aspx
63                         public override void Write (char value)
64                         {
65                                 try {
66                                         sb.Append (value);
67                                 }
68                                 catch (Exception) {
69                                 }
70                         }
71                         
72                         // optimization (to avoid concatening chars)
73                         public override void Write (string value)
74                         {
75                                 try {
76                                         sb.Append (value);
77                                         if (value != null && value.Length >= CoreNewLine.Length && EndsWithNewLine (value))
78                                                 Flush ();
79                                 }
80                                 catch (Exception) {
81                                 }
82                         }
83                         
84                         bool EndsWithNewLine (string value)
85                         {
86                                 for (int i = 0, v = value.Length - CoreNewLine.Length; i < CoreNewLine.Length; ++i, ++v) {
87                                         if (value [v] != CoreNewLine [i])
88                                                 return false;
89                                 }
90                                 
91                                 return true;
92                         }
93                         
94                         public override void WriteLine ()
95                         {
96                                 try {
97                                         Flush ();
98                                 }
99                                 catch (Exception) {
100                                 }
101                         }
102                 }
103         }
104 }
105
106 #endif