Mercurial > projects > ldc
diff 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 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tango/tango/io/Print.d Fri Jan 11 17:57:40 2008 +0100 @@ -0,0 +1,332 @@ +/******************************************************************************* + + copyright: Copyright (c) 2007 Kris Bell. All rights reserved + + license: BSD style: $(LICENSE) + + version: Feb 2007: Separated from Stdout + + author: Kris + +*******************************************************************************/ + +module tango.io.Print; + +private import tango.io.model.IBuffer, + tango.io.model.IConduit; + +private import tango.text.convert.Layout; + +/******************************************************************************* + + A bridge between a Layout instance and a Buffer. This is used for + the Stdout & Stderr globals, but can be used for general purpose + buffer-formatting as desired. The Template type 'T' dictates the + text arrangement within the target buffer ~ one of char, wchar or + dchar (utf8, utf16, or utf32). + + Print exposes this style of usage: + --- + auto print = new Print!(char) (...); + + print ("hello"); => hello + print (1); => 1 + print (3.14); => 3.14 + print ('b'); => b + print (1, 2, 3); => 1, 2, 3 + print ("abc", 1, 2, 3); => abc, 1, 2, 3 + print ("abc", 1, 2) ("foo"); => abc, 1, 2foo + print ("abc") ("def") (3.14); => abcdef3.14 + + print.format ("abc {}", 1); => abc 1 + print.format ("abc {}:{}", 1, 2); => abc 1:2 + print.format ("abc {1}:{0}", 1, 2); => abc 2:1 + print.format ("abc ", 1); => abc + --- + + Note that the last example does not throw an exception. There + are several use-cases where dropping an argument is legitimate, + so we're currently not enforcing any particular trap mechanism. + + Flushing the output is achieved through the flush() method, or + via an empty pair of parens: + --- + print ("hello world") (); + print ("hello world").flush; + + print.format ("hello {}", "world") (); + print.format ("hello {}", "world").flush; + --- + + Special character sequences, such as "\n", are written directly to + the output without any translation (though an output-filter could + be inserted to perform translation as required). Platform-specific + newlines are generated instead via the newline() method, which also + flushes the output when configured to do so: + --- + print ("hello ") ("world").newline; + print.format ("hello {}", "world").newline; + print.formatln ("hello {}", "world"); + --- + + The format() method supports the range of formatting options + exposed by tango.text.convert.Layout and extensions thereof; + including the full I18N extensions where configured in that + manner. To create a French instance of Print: + --- + import tango.text.locale.Locale; + + auto locale = new Locale (Culture.getCulture ("fr-FR")); + auto print = new Print!(char) (locale, ...); + --- + + Note that Print is *not* intended to be thread-safe. Use either + tango.util.log.Trace or the standard logging facilities in order + to enable atomic console I/O + +*******************************************************************************/ + +class Print(T) : OutputStream +{ + private T[] eol; + private OutputStream output; + private Layout!(T) convert; + private bool flushLines; + + public alias print opCall; + + version (Win32) + private const T[] Eol = "\r\n"; + else + private const T[] Eol = "\n"; + + /********************************************************************** + + Construct a Print instance, tying the provided stream + to a layout formatter + + **********************************************************************/ + + this (Layout!(T) convert, OutputStream output, T[] eol = Eol) + { + assert (convert); + assert (output); + + this.eol = eol; + this.output = output; + this.convert = convert; + } + + /********************************************************************** + + Layout using the provided formatting specification + + **********************************************************************/ + + final Print format (T[] fmt, ...) + { + convert (&sink, _arguments, _argptr, fmt); + return this; + } + + /********************************************************************** + + Layout using the provided formatting specification + + **********************************************************************/ + + final Print formatln (T[] fmt, ...) + { + convert (&sink, _arguments, _argptr, fmt); + return newline; + } + + /********************************************************************** + + Unformatted layout, with commas inserted between args. + Currently supports a maximum of 24 arguments + + **********************************************************************/ + + final Print print (...) + { + static T[] slice = "{}, {}, {}, {}, {}, {}, {}, {}, " + "{}, {}, {}, {}, {}, {}, {}, {}, " + "{}, {}, {}, {}, {}, {}, {}, {}, "; + + assert (_arguments.length <= slice.length/4, "Print :: too many arguments"); + + if (_arguments.length is 0) + output.flush; + else + convert (&sink, _arguments, _argptr, slice[0 .. _arguments.length * 4 - 2]); + + return this; + } + + /*********************************************************************** + + Output a newline and optionally flush + + ***********************************************************************/ + + final Print newline () + { + output.write (eol); + if (flushLines) + output.flush; + return this; + } + + /********************************************************************** + + Control implicit flushing of newline(), where true enables + flushing. An explicit flush() will always flush the output. + + **********************************************************************/ + + final Print flush (bool yes) + { + flushLines = yes; + return this; + } + + /********************************************************************** + + Return the associated output stream + + **********************************************************************/ + + final OutputStream stream () + { + return output; + } + + /********************************************************************** + + Set the associated output stream + + **********************************************************************/ + + final Print stream (OutputStream output) + { + this.output = output; + return this; + } + + /********************************************************************** + + Return the associated Layout + + **********************************************************************/ + + final Layout!(T) layout () + { + return convert; + } + + /********************************************************************** + + Set the associated Layout + + **********************************************************************/ + + final Print layout (Layout!(T) layout) + { + convert = layout; + return this; + } + + /********************************************************************** + + Sink for passing to the formatter + + **********************************************************************/ + + private final uint sink (T[] s) + { + return output.write (s); + } + + /**********************************************************************/ + /********************* OutputStream Interface *************************/ + /**********************************************************************/ + + + /*********************************************************************** + + Return the host conduit + + ***********************************************************************/ + + IConduit conduit () + { + return output.conduit; + } + + /*********************************************************************** + + Write to conduit from a source array. The provided src + content will be written to the conduit. + + Returns the number of bytes written from src, which may + be less than the quantity provided + + ***********************************************************************/ + + uint write (void[] src) + { + return output.write (src); + } + + /********************************************************************** + + Flush the output stream + + **********************************************************************/ + + final OutputStream flush () + { + output.flush; + return this; + } + + /*********************************************************************** + + Transfer the content of another conduit to this one. Returns + a reference to this class, and throws IOException on failure. + + ***********************************************************************/ + + OutputStream copy (InputStream src) + { + output.copy (src); + return this; + } + + /*********************************************************************** + + Close the output + + ***********************************************************************/ + + void close () + { + output.close; + } +} + + +debug (Print) +{ + import tango.io.GrowBuffer; + import tango.text.convert.Layout; + + void main() + { + auto print = new Print!(char) (new Layout!(char), new GrowBuffer); + + for (int i=0;i < 1000; i++) + print(i).newline; + } +}