blob: 67542e6c6bc06e9c1f0ace859b65c4314f52b480 [file] [log] [blame]
//
// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#define BOOST_LOCALE_SOURCE
#include "lcid.hpp"
#include <string.h>
#include <string>
#include <sstream>
#include <map>
#include "../util/locale_data.hpp"
#ifndef NOMINMAX
#define NOMINMAX
#endif
#include <windows.h>
#include <boost/thread/mutex.hpp>
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 table;
return 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;
}
table_type::iterator 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;
}
table_type const &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(std::string const &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;
}
table_type const &tbl = get_ready_lcid_table();
table_type::const_iterator p = tbl.find(id);
unsigned lcid = 0;
if(p!=tbl.end())
lcid = p->second;
return lcid;
}
} // impl_win
} // locale
} // boost
// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4