blob: e1b998d66b3819b370d93d112616229b05e53112 (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
|
//
// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
//
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#ifndef NOMINMAX
# define NOMINMAX
#endif
#include "lcid.hpp"
#include <boost/locale/util/locale_data.hpp>
#include <boost/thread/locks.hpp>
#include <boost/thread/mutex.hpp>
#include <map>
#include <sstream>
#include <string.h>
#include <string>
#include <windows.h>
namespace boost { namespace locale { namespace impl_win {
typedef std::map<std::string, unsigned> table_type;
static table_type* volatile table = 0;
boost::mutex& lcid_table_mutex()
{
static boost::mutex m;
return m;
}
table_type& real_lcid_table()
{
static table_type real_table;
return real_table;
}
BOOL CALLBACK proc(char* s)
{
table_type& tbl = real_lcid_table();
try {
std::istringstream ss;
ss.str(s);
ss >> std::hex;
unsigned lcid;
ss >> lcid;
if(ss.fail() || !ss.eof())
return FALSE;
char iso_639_lang[16];
char iso_3166_country[16];
if(GetLocaleInfoA(lcid, LOCALE_SISO639LANGNAME, iso_639_lang, sizeof(iso_639_lang)) == 0)
return FALSE;
std::string lc_name = iso_639_lang;
if(GetLocaleInfoA(lcid, LOCALE_SISO3166CTRYNAME, iso_3166_country, sizeof(iso_3166_country)) != 0) {
lc_name += "_";
lc_name += iso_3166_country;
}
const auto p = tbl.find(lc_name);
if(p != tbl.end()) {
if(p->second > lcid)
p->second = lcid;
} else
tbl[lc_name] = lcid;
} catch(...) {
tbl.clear();
return FALSE;
}
return TRUE;
}
const table_type& get_ready_lcid_table()
{
if(table)
return *table;
else {
boost::unique_lock<boost::mutex> lock(lcid_table_mutex());
if(table)
return *table;
EnumSystemLocalesA(proc, LCID_INSTALLED);
table = &real_lcid_table();
return *table;
}
}
unsigned locale_to_lcid(const std::string& locale_name)
{
if(locale_name.empty())
return LOCALE_USER_DEFAULT;
boost::locale::util::locale_data d;
d.parse(locale_name);
std::string id = d.language();
if(!d.country().empty())
id += "_" + d.country();
if(!d.variant().empty())
id += "@" + d.variant();
const table_type& tbl = get_ready_lcid_table();
const auto p = tbl.find(id);
return (p != tbl.end()) ? p->second : 0;
}
}}} // namespace boost::locale::impl_win
|