File: LogcatTextWriter.cs

package info (click to toggle)
mono 6.8.0.105%2Bdfsg-3.3
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 1,284,512 kB
  • sloc: cs: 11,172,132; xml: 2,850,069; ansic: 671,653; cpp: 122,091; perl: 59,366; javascript: 30,841; asm: 22,168; makefile: 20,093; sh: 15,020; python: 4,827; pascal: 925; sql: 859; sed: 16; php: 1
file content (102 lines) | stat: -rw-r--r-- 2,201 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
#if MONODROID

using System;
using System.IO;
using System.Text;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

using Mono;

namespace System.IO {

	class LogcatTextWriter : TextWriter {

		const string LibLog = "/system/lib/liblog.so";
		const string LibLog64 = "/system/lib64/liblog.so";

		readonly byte[] appname;

		TextWriter stdout;
		StringBuilder line = new StringBuilder ();

		public LogcatTextWriter (string appname, TextWriter stdout)
		{
			this.appname = Encoding.UTF8.GetBytes (appname + '\0');
			this.stdout = stdout;
		}

		public override Encoding Encoding {
			get {return Encoding.UTF8;}
		}

		public override void Write (string s)
		{
			if (s != null)
				foreach (char c in s)
					Write (c);
		}

		public override void Write (char value)
		{
			if (value == '\n')
				WriteLine ();
			else
				line.Append (value);
		}

		public override void WriteLine ()
		{
			var o = line.ToString ();
			line.Clear ();

			Log (o);
			stdout.WriteLine (o);
		}

		void Log (string message)
		{
			const int buffer_size = 512;

			unsafe {
				if (Encoding.UTF8.GetByteCount (message) < buffer_size) {
					try {
						fixed (char *b_message = message) {
							byte* buffer = stackalloc byte[buffer_size];
							int written = Encoding.UTF8.GetBytes (b_message, message.Length, buffer, buffer_size - 1);
							buffer [written] = (byte)'\0';

							Log (buffer);
						}

						return;
					} catch (ArgumentException) {
						/* It might be due to a failure to encode a character, or due to a smaller than necessary buffer. In the
						* secode case, we want to fallback to simply allocating on the heap. */
					}
				}

				using (SafeStringMarshal str = new SafeStringMarshal(message)) {
					Log ((byte*) str.Value);
				}
			}
		}

		unsafe void Log (byte* b_message)
		{
			fixed (byte *b_appname = appname) {
				Log (b_appname, 1 << 5 /* G_LOG_LEVEL_MESSAGE */, b_message);
			}
		}

		public static bool IsRunningOnAndroid ()
		{
			return File.Exists (LibLog) || File.Exists (LibLog64);
		}

		[MethodImpl(MethodImplOptions.InternalCall)]
		static unsafe extern void Log (byte *appname, int level, byte *message);
	}
}

#endif  // MONODROID