root/trunk/tango/scrapple/io/filter/RawCoutFilter.d

Revision 40, 4.4 kB (checked in by flithm, 9 months ago)

Add module line to RawCoutFilter?

Line 
1 /*******************************************************************************
2
3    a capturing filter on Stdout and Stderr to disable Unicode translation on
4    console output
5
6    Win32 code ripped off of Tango's (0.98 RC2) Console.Conduit, changed to use
7    WriteConsoleA
8   
9    Posix code from DeviceConduit   
10
11    Examples:
12
13    ---
14    import tango.io.Console;
15    import tango.stdc.stdio;
16
17    void main() {
18            fputs("C: a-\xe4-b\n", stdout);
19            fflush(stdout);
20            Cout.buffer.append("D: a-\xe4-b\r\n");
21            Cout.buffer.flush();
22    }
23    ---
24   
25    Expected output:
26    ---
27    C: a-X-b
28    D: a-X-b
29    ---
30
31    Where X is some special character whose precise appearance, I think, depends
32    on locale settings. On my computer it's õ. Anyway, what I get in cmd.exe is:
33    ---
34    C: a-X-b
35    D: a--b
36    ---
37   
38    This is a Raw Cout filter to fix this issue.
39   
40 ********************************************************************************/
41
42 module tango.scrapple.io.RawCoutFilter;
43
44 class RawCoutFilter(bool stderr) : OutputFilter {
45 private:
46         void error() {
47                 throw new IOException("RawCoutFilter error: "~SysError.lastMsg);
48         }
49
50         typeof(Stdout.stream()) superArgs() {
51                 return stderr ? Stderr.stream : Stdout.stream;
52         }
53
54         version (Win32) {
55                 HANDLE handle;
56                 bool redirected;
57
58                 public this() {
59                         reopen();
60
61                         super(superArgs());
62                 }
63
64                 void reopen() {
65                         // stderr is -12, stdout is -11
66                         handle = GetStdHandle(-cast(DWORD)stderr - 11);
67
68                         if (handle is null) {
69                                 handle = CreateFileA(
70                                         "CONOUT$",
71                                         GENERIC_READ | GENERIC_WRITE,
72                                         FILE_SHARE_READ | FILE_SHARE_WRITE,
73                                         null,
74                                         OPEN_EXISTING,
75                                         0,
76                                         cast(HANDLE)0
77                                 );
78
79                                 if (handle is null)
80                                         error();
81                         }
82
83                         DWORD dummy;
84                         redirected = !GetConsoleMode(handle, &dummy);
85                 }
86
87                 public override size_t write(void[] src) {
88                         if (redirected) {
89                                 DWORD written;
90
91                                 if (!WriteFile(handle, src.ptr, src.length, &written, null))
92                                         error();
93
94                                 return written;
95                         } else {
96                                 DWORD i = src.length;
97
98                                 if (i == 0)
99                                         return 0;
100
101                 auto p = src.ptr;
102                 auto end = src.ptr + i;
103                                 for (; p < end; p += i) {
104                                         if (
105                                                 !WriteConsoleA(
106                                                         handle,
107                                                         p,
108                                                         min(end - p, 32 * 1024),
109                                                         &i,
110                                                         null
111                                                 )
112                                         )
113                                                 error();
114                                 }
115
116                                 return src.length;
117                         }
118                 }
119         } else { // Posix
120
121                 // stdout is 1, stderr is 2
122                 const int handle = cast(int)stderr + 1;
123
124                 public this() {
125                         super(superArgs());
126                 }
127
128                 public override size_t write(void[] src) {
129                         ptrdiff_t written = posix.write(handle, src.ptr, src.length);
130                         if (written < 0)
131                                 error();
132                         return written;
133                 }
134         }
135 }
Note: See TracBrowser for help on using the browser.