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