Download Reference Manual
The Developer's Library for D
About Wiki Forums Source Search Contact

root/trunk/tango/io/Print.d

Revision 3544, 10.8 kB (checked in by kris, 6 months ago)

Merged GrowBuffer? module into Buffer module

  • Property svn:mime-type set to text/x-dsrc
  • Property svn:eol-style set to native
Line 
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.Buffer;
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 }
Note: See TracBrowser for help on using the browser.