Mercurial > projects > ldc
comparison tango/tango/io/Print.d @ 132:1700239cab2e trunk
[svn r136] MAJOR UNSTABLE UPDATE!!!
Initial commit after moving to Tango instead of Phobos.
Lots of bugfixes...
This build is not suitable for most things.
author | lindquist |
---|---|
date | Fri, 11 Jan 2008 17:57:40 +0100 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
131:5825d48b27d1 | 132:1700239cab2e |
---|---|
1 /******************************************************************************* | |
2 | |
3 copyright: Copyright (c) 2007 Kris Bell. All rights reserved | |
4 | |
5 license: BSD style: $(LICENSE) | |
6 | |
7 version: Feb 2007: Separated from Stdout | |
8 | |
9 author: Kris | |
10 | |
11 *******************************************************************************/ | |
12 | |
13 module tango.io.Print; | |
14 | |
15 private import tango.io.model.IBuffer, | |
16 tango.io.model.IConduit; | |
17 | |
18 private import tango.text.convert.Layout; | |
19 | |
20 /******************************************************************************* | |
21 | |
22 A bridge between a Layout instance and a Buffer. This is used for | |
23 the Stdout & Stderr globals, but can be used for general purpose | |
24 buffer-formatting as desired. The Template type 'T' dictates the | |
25 text arrangement within the target buffer ~ one of char, wchar or | |
26 dchar (utf8, utf16, or utf32). | |
27 | |
28 Print exposes this style of usage: | |
29 --- | |
30 auto print = new Print!(char) (...); | |
31 | |
32 print ("hello"); => hello | |
33 print (1); => 1 | |
34 print (3.14); => 3.14 | |
35 print ('b'); => b | |
36 print (1, 2, 3); => 1, 2, 3 | |
37 print ("abc", 1, 2, 3); => abc, 1, 2, 3 | |
38 print ("abc", 1, 2) ("foo"); => abc, 1, 2foo | |
39 print ("abc") ("def") (3.14); => abcdef3.14 | |
40 | |
41 print.format ("abc {}", 1); => abc 1 | |
42 print.format ("abc {}:{}", 1, 2); => abc 1:2 | |
43 print.format ("abc {1}:{0}", 1, 2); => abc 2:1 | |
44 print.format ("abc ", 1); => abc | |
45 --- | |
46 | |
47 Note that the last example does not throw an exception. There | |
48 are several use-cases where dropping an argument is legitimate, | |
49 so we're currently not enforcing any particular trap mechanism. | |
50 | |
51 Flushing the output is achieved through the flush() method, or | |
52 via an empty pair of parens: | |
53 --- | |
54 print ("hello world") (); | |
55 print ("hello world").flush; | |
56 | |
57 print.format ("hello {}", "world") (); | |
58 print.format ("hello {}", "world").flush; | |
59 --- | |
60 | |
61 Special character sequences, such as "\n", are written directly to | |
62 the output without any translation (though an output-filter could | |
63 be inserted to perform translation as required). Platform-specific | |
64 newlines are generated instead via the newline() method, which also | |
65 flushes the output when configured to do so: | |
66 --- | |
67 print ("hello ") ("world").newline; | |
68 print.format ("hello {}", "world").newline; | |
69 print.formatln ("hello {}", "world"); | |
70 --- | |
71 | |
72 The format() method supports the range of formatting options | |
73 exposed by tango.text.convert.Layout and extensions thereof; | |
74 including the full I18N extensions where configured in that | |
75 manner. To create a French instance of Print: | |
76 --- | |
77 import tango.text.locale.Locale; | |
78 | |
79 auto locale = new Locale (Culture.getCulture ("fr-FR")); | |
80 auto print = new Print!(char) (locale, ...); | |
81 --- | |
82 | |
83 Note that Print is *not* intended to be thread-safe. Use either | |
84 tango.util.log.Trace or the standard logging facilities in order | |
85 to enable atomic console I/O | |
86 | |
87 *******************************************************************************/ | |
88 | |
89 class Print(T) : OutputStream | |
90 { | |
91 private T[] eol; | |
92 private OutputStream output; | |
93 private Layout!(T) convert; | |
94 private bool flushLines; | |
95 | |
96 public alias print opCall; | |
97 | |
98 version (Win32) | |
99 private const T[] Eol = "\r\n"; | |
100 else | |
101 private const T[] Eol = "\n"; | |
102 | |
103 /********************************************************************** | |
104 | |
105 Construct a Print instance, tying the provided stream | |
106 to a layout formatter | |
107 | |
108 **********************************************************************/ | |
109 | |
110 this (Layout!(T) convert, OutputStream output, T[] eol = Eol) | |
111 { | |
112 assert (convert); | |
113 assert (output); | |
114 | |
115 this.eol = eol; | |
116 this.output = output; | |
117 this.convert = convert; | |
118 } | |
119 | |
120 /********************************************************************** | |
121 | |
122 Layout using the provided formatting specification | |
123 | |
124 **********************************************************************/ | |
125 | |
126 final Print format (T[] fmt, ...) | |
127 { | |
128 convert (&sink, _arguments, _argptr, fmt); | |
129 return this; | |
130 } | |
131 | |
132 /********************************************************************** | |
133 | |
134 Layout using the provided formatting specification | |
135 | |
136 **********************************************************************/ | |
137 | |
138 final Print formatln (T[] fmt, ...) | |
139 { | |
140 convert (&sink, _arguments, _argptr, fmt); | |
141 return newline; | |
142 } | |
143 | |
144 /********************************************************************** | |
145 | |
146 Unformatted layout, with commas inserted between args. | |
147 Currently supports a maximum of 24 arguments | |
148 | |
149 **********************************************************************/ | |
150 | |
151 final Print print (...) | |
152 { | |
153 static T[] slice = "{}, {}, {}, {}, {}, {}, {}, {}, " | |
154 "{}, {}, {}, {}, {}, {}, {}, {}, " | |
155 "{}, {}, {}, {}, {}, {}, {}, {}, "; | |
156 | |
157 assert (_arguments.length <= slice.length/4, "Print :: too many arguments"); | |
158 | |
159 if (_arguments.length is 0) | |
160 output.flush; | |
161 else | |
162 convert (&sink, _arguments, _argptr, slice[0 .. _arguments.length * 4 - 2]); | |
163 | |
164 return this; | |
165 } | |
166 | |
167 /*********************************************************************** | |
168 | |
169 Output a newline and optionally flush | |
170 | |
171 ***********************************************************************/ | |
172 | |
173 final Print newline () | |
174 { | |
175 output.write (eol); | |
176 if (flushLines) | |
177 output.flush; | |
178 return this; | |
179 } | |
180 | |
181 /********************************************************************** | |
182 | |
183 Control implicit flushing of newline(), where true enables | |
184 flushing. An explicit flush() will always flush the output. | |
185 | |
186 **********************************************************************/ | |
187 | |
188 final Print flush (bool yes) | |
189 { | |
190 flushLines = yes; | |
191 return this; | |
192 } | |
193 | |
194 /********************************************************************** | |
195 | |
196 Return the associated output stream | |
197 | |
198 **********************************************************************/ | |
199 | |
200 final OutputStream stream () | |
201 { | |
202 return output; | |
203 } | |
204 | |
205 /********************************************************************** | |
206 | |
207 Set the associated output stream | |
208 | |
209 **********************************************************************/ | |
210 | |
211 final Print stream (OutputStream output) | |
212 { | |
213 this.output = output; | |
214 return this; | |
215 } | |
216 | |
217 /********************************************************************** | |
218 | |
219 Return the associated Layout | |
220 | |
221 **********************************************************************/ | |
222 | |
223 final Layout!(T) layout () | |
224 { | |
225 return convert; | |
226 } | |
227 | |
228 /********************************************************************** | |
229 | |
230 Set the associated Layout | |
231 | |
232 **********************************************************************/ | |
233 | |
234 final Print layout (Layout!(T) layout) | |
235 { | |
236 convert = layout; | |
237 return this; | |
238 } | |
239 | |
240 /********************************************************************** | |
241 | |
242 Sink for passing to the formatter | |
243 | |
244 **********************************************************************/ | |
245 | |
246 private final uint sink (T[] s) | |
247 { | |
248 return output.write (s); | |
249 } | |
250 | |
251 /**********************************************************************/ | |
252 /********************* OutputStream Interface *************************/ | |
253 /**********************************************************************/ | |
254 | |
255 | |
256 /*********************************************************************** | |
257 | |
258 Return the host conduit | |
259 | |
260 ***********************************************************************/ | |
261 | |
262 IConduit conduit () | |
263 { | |
264 return output.conduit; | |
265 } | |
266 | |
267 /*********************************************************************** | |
268 | |
269 Write to conduit from a source array. The provided src | |
270 content will be written to the conduit. | |
271 | |
272 Returns the number of bytes written from src, which may | |
273 be less than the quantity provided | |
274 | |
275 ***********************************************************************/ | |
276 | |
277 uint write (void[] src) | |
278 { | |
279 return output.write (src); | |
280 } | |
281 | |
282 /********************************************************************** | |
283 | |
284 Flush the output stream | |
285 | |
286 **********************************************************************/ | |
287 | |
288 final OutputStream flush () | |
289 { | |
290 output.flush; | |
291 return this; | |
292 } | |
293 | |
294 /*********************************************************************** | |
295 | |
296 Transfer the content of another conduit to this one. Returns | |
297 a reference to this class, and throws IOException on failure. | |
298 | |
299 ***********************************************************************/ | |
300 | |
301 OutputStream copy (InputStream src) | |
302 { | |
303 output.copy (src); | |
304 return this; | |
305 } | |
306 | |
307 /*********************************************************************** | |
308 | |
309 Close the output | |
310 | |
311 ***********************************************************************/ | |
312 | |
313 void close () | |
314 { | |
315 output.close; | |
316 } | |
317 } | |
318 | |
319 | |
320 debug (Print) | |
321 { | |
322 import tango.io.GrowBuffer; | |
323 import tango.text.convert.Layout; | |
324 | |
325 void main() | |
326 { | |
327 auto print = new Print!(char) (new Layout!(char), new GrowBuffer); | |
328 | |
329 for (int i=0;i < 1000; i++) | |
330 print(i).newline; | |
331 } | |
332 } |