1 /*******************************************************************************
2 
3         copyright:      Copyright (c) 2007 Kris. All rights reserved
4 
5         license:        BSD style: $(LICENSE)
6 
7         version:        Feb 2007: Initial release
8 
9         author:         Kris
10 
11         This is the Tango I18N gateway, which extends the basic Layout
12         module with support for cuture- and region-specific formatting
13         of numerics, date, time, and currency.
14 
15         Use as a standalone formatter in the same manner as Layout, or
16         combine with other entities such as Stdout. To enable a French
17         Stdout, do the following:
18         ---
19         Stdout.layout = new Locale (Culture.getCulture ("fr-FR"));
20         ---
21         
22         Note that Stdout is a shared entity, so every usage of it will
23         be affected by the above example. For applications supporting 
24         multiple regions create multiple Locale instances instead, and 
25         cache them in an appropriate manner.
26 
27         In addition to region-specific currency, date and time, Locale
28         adds more sophisticated formatting option than Layout provides: 
29         numeric digit placement using '#' formatting, for example, is 
30         supported by Locale - along with placement of '$', '-', and '.'
31         regional-specifics.
32 
33         Locale is currently utf8 only. Support for both Utf16 and utf32 
34         may be enabled at a later time
35 
36 ******************************************************************************/
37 
38 module tango.text.locale.Locale;
39 
40 private import tango.text.locale.Core,
41                tango.text.locale.Convert;
42 
43 private import tango.time.Time;
44 
45 private import tango.text.convert.Layout;
46 
47 public  import tango.text.locale.Core : Culture;
48 
49 /*******************************************************************************
50 
51         Locale-enabled wrapper around tango.text.convert.Layout
52 
53 *******************************************************************************/
54 
55 public class Locale : Layout!(char)
56 {
57         private DateTimeFormat  dateFormat;
58         private NumberFormat    numberFormat;
59 
60         /**********************************************************************
61 
62         **********************************************************************/
63 
64         this (IFormatService formatService = null)
65         {
66                 numberFormat = NumberFormat.getInstance (formatService);
67                 dateFormat = DateTimeFormat.getInstance (formatService);
68         }
69 
70         /***********************************************************************
71 
72         ***********************************************************************/
73 
74         protected override char[] unknown (char[] output, const(char)[] format, const(TypeInfo) type, Arg p)
75         {
76                 switch (type.classinfo.name[9])
77                        {
78                             // Special case for Time.
79                        case TypeCode.STRUCT:
80                             if (type is typeid(Time))
81                                 return formatDateTime (output, *cast(Time*) p, format, dateFormat);
82                        /* Bad dup */
83                        return (cast()type).toString().dup; /* Cast courtesy of D2 */
84 
85                        default:
86                             break;
87                        }
88 
89                 return "{unhandled argument type: ".dup ~ (cast()type).toString() ~ '}'; /* Cast courtesy of D2 */
90         }
91 
92         /**********************************************************************
93 
94         **********************************************************************/
95 
96         protected override char[] integer (char[] output, long v, const(char)[] alt, ulong mask=ulong.max, const(char)[] format=null)
97         {
98                 return formatInteger (output, v, alt, numberFormat);
99         }
100 
101         /**********************************************************************
102 
103         **********************************************************************/
104 
105         protected override char[] floater (char[] output, real v, const(char)[] format)
106         {
107                 return formatDouble (output, v, format, numberFormat);
108         }
109 }
110 
111 
112 /*******************************************************************************
113 
114 *******************************************************************************/
115 
116 debug (Locale)
117 {
118         import tango.io.Console;
119         import tango.time.WallClock;
120 
121         void main ()
122         {
123                 auto layout = new Locale (Culture.getCulture ("fr-FR"));
124 
125                 Cout (layout ("{:D}", WallClock.now)) ();
126         }
127 }