1 /**
2  * Locale.d
3  * Information of a locale.
4  * Author: knt.roh
5  * License: Public Domain
6  */
7 module java.nonstandard.Locale;
8 
9 import java.lang.String;
10 import java.lang.util : implMissing;
11 
12 version(Tango){
13     private import tango.text.locale.Core;
14 } else { // Phobos
15     private import std.conv;
16     private import std.exception;
17 
18     version (Windows) {
19         private import core.stdc..string;
20         private import core.sys.windows.windows;
21         private bool W_VERSION;
22         static this() {
23             W_VERSION = GetVersion < 0x80000000;
24         }
25         private extern (Windows) {
26             enum LCID : DWORD {
27                 /// The default locale for the user or process.
28                 LOCALE_USER_DEFAULT     = 0x0400,
29             }
30             enum LCTYPE : DWORD {
31                 /// ISO639 language name.
32                 LOCALE_SISO639LANGNAME  = 0x0059,
33                 /// ISO3166 country name.
34                 LOCALE_SISO3166CTRYNAME = 0x005A
35             }
36             /// Retrieves information about a locale specified by identifier.
37             /// See_Also: GetLocaleInfo Function (Windows)
38             ///           (http://msdn.microsoft.com/en-us/library/dd318101%28VS.85%29.aspx)
39             INT GetLocaleInfoW(
40                 LCID Locale,
41                 LCTYPE LCType,
42                 LPWSTR lpLCData,
43                 INT cchData
44             );
45             /// ditto
46             INT GetLocaleInfoA(
47                 LCID Locale,
48                 LCTYPE LCType,
49                 LPCSTR lpLCData,
50                 INT cchData
51             );
52         }
53         /// A purpose of this templete is switch of W or A in Windows.
54         private String caltureNameImpl(Char, alias GetLocalInfo)() {
55             INT len;
56             Char[] res;
57             Char[] buf;
58             len = GetLocalInfo(LCID.LOCALE_USER_DEFAULT,
59                 LCTYPE.LOCALE_SISO639LANGNAME, null, 0);
60             enforce(len, new Exception("LOCALE_SISO639LANGNAME (len)", __FILE__, __LINE__));
61             buf.length = len;
62             len = GetLocalInfo(LCID.LOCALE_USER_DEFAULT,
63                 LCTYPE.LOCALE_SISO639LANGNAME, buf.ptr, cast(INT)buf.length);
64             enforce(len, new Exception("LOCALE_SISO639LANGNAME", __FILE__, __LINE__));
65             res ~= buf[0 .. len - 1];
66             res ~= '-';
67             len = GetLocalInfo(LCID.LOCALE_USER_DEFAULT,
68                 LCTYPE.LOCALE_SISO3166CTRYNAME, null, 0);
69             enforce(len, new Exception("LOCALE_SISO3166CTRYNAME (len)", __FILE__, __LINE__));
70             buf.length = len;
71             len = GetLocalInfo(LCID.LOCALE_USER_DEFAULT,
72                 LCTYPE.LOCALE_SISO3166CTRYNAME, buf.ptr, cast(INT)buf.length);
73             enforce(len, new Exception("LOCALE_SISO3166CTRYNAME", __FILE__, __LINE__));
74             res ~= buf[0 .. len - 1];
75             return to!(String)(res);
76         }
77     } else version (Posix) {
78         private import std.process : environment;
79         private import std..string : indexOf, replace;
80     }
81 }
82 /// Get a omitted calture name. for example: "en-US"
83 String caltureName() {
84     version(Tango){
85         return Culture.current.name;
86     } else { // Phobos
87         version (Windows) {
88             if (W_VERSION) {
89                 return caltureNameImpl!(wchar, GetLocaleInfoW)();
90             } else {
91                 return caltureNameImpl!(char, GetLocaleInfoA)();
92             }
93         } else version (Posix) {
94             // LC_ALL is override to settings of all category.
95             // This is undefined in almost case.
96             String res = .environment.get("LC_ALL", "");
97             if (!res || !res.length) {
98                 // LANG is basic Locale setting.
99                 // A settings of each category override this. 
100                 res = .environment.get("LANG", "");
101             }
102             ptrdiff_t dot = .indexOf(res, '.');
103             if (dot != -1) res = res[0 .. dot];
104             return .replace(res, "_", "-");
105         } else {
106             static assert(0);
107         }
108     }
109 }