16 | | void locale_data::parse(std::string const &locale_name) |
17 | | { |
18 | | language = "C"; |
19 | | country.clear(); |
20 | | variant.clear(); |
21 | | encoding = "us-ascii"; |
22 | | utf8=false; |
23 | | parse_from_lang(locale_name); |
24 | | } |
25 | | |
26 | | void locale_data::parse_from_lang(std::string const &locale_name) |
27 | | { |
28 | | size_t end = locale_name.find_first_of("-_@."); |
29 | | std::string tmp = locale_name.substr(0,end); |
30 | | if(tmp.empty()) |
31 | | return; |
32 | | for(unsigned i=0;i<tmp.size();i++) { |
33 | | if('A' <= tmp[i] && tmp[i]<='Z') |
34 | | tmp[i]=tmp[i]-'A'+'a'; |
35 | | else if(tmp[i] < 'a' && 'z' < tmp[i]) |
36 | | return; |
37 | | } |
38 | | language = tmp; |
39 | | if(end >= locale_name.size()) |
40 | | return; |
41 | | |
42 | | if(locale_name[end] == '-' || locale_name[end]=='_') { |
43 | | parse_from_country(locale_name.substr(end+1)); |
44 | | } |
45 | | else if(locale_name[end] == '.') { |
46 | | parse_from_encoding(locale_name.substr(end+1)); |
47 | | } |
48 | | else if(locale_name[end] == '@') { |
49 | | parse_from_variant(locale_name.substr(end+1)); |
50 | | } |
51 | | } |
52 | | |
53 | | void locale_data::parse_from_country(std::string const &locale_name) |
| 17 | struct name_state |
55 | | size_t end = locale_name.find_first_of("@."); |
56 | | std::string tmp = locale_name.substr(0,end); |
57 | | if(tmp.empty()) |
58 | | return; |
59 | | for(unsigned i=0;i<tmp.size();i++) { |
60 | | if('a' <= tmp[i] && tmp[i]<='a') |
61 | | tmp[i]=tmp[i]-'a'+'A'; |
62 | | else if(tmp[i] < 'A' && 'Z' < tmp[i]) |
63 | | return; |
64 | | } |
65 | | |
66 | | country = tmp; |
67 | | |
68 | | if(end >= locale_name.size()) |
69 | | return; |
70 | | else if(locale_name[end] == '.') { |
71 | | parse_from_encoding(locale_name.substr(end+1)); |
72 | | } |
73 | | else if(locale_name[end] == '@') { |
74 | | parse_from_variant(locale_name.substr(end+1)); |
| 19 | name_state(int _order = -1, std::string* _section = 0, bool _upper = false) |
| 20 | : order(_order), section(_section), upper(_upper) |
| 21 | { |
90 | | utf8 = conv::impl::normalize_encoding(encoding.c_str()) == "utf8"; |
91 | | |
92 | | if(end >= locale_name.size()) |
93 | | return; |
94 | | |
95 | | if(locale_name[end] == '@') { |
96 | | parse_from_variant(locale_name.substr(end+1)); |
97 | | } |
98 | | } |
99 | | |
100 | | void locale_data::parse_from_variant(std::string const &locale_name) |
101 | | { |
102 | | variant = locale_name; |
103 | | for(unsigned i=0;i<variant.size();i++) { |
104 | | if('A' <= variant[i] && variant[i]<='Z') |
105 | | variant[i]=variant[i]-'A'+'a'; |
| 36 | std::map<char,name_state> states; |
| 37 | states[ 0 ]=name_state(0,&language,false); |
| 38 | states['_']=name_state(1,&country,true); |
| 39 | states['.']=name_state(2,&encoding,false); |
| 40 | states['@']=name_state(3,&variant,false); |
| 41 | |
| 42 | name_state* state=&states[0]; |
| 43 | |
| 44 | for(unsigned i=0;i<locale_name.size();i++) |
| 45 | { |
| 46 | char c=locale_name[i]; |
| 47 | |
| 48 | if(states.find(c) != states.end() && states[c].order > state->order) |
| 49 | { |
| 50 | state=&states[c]; |
| 51 | } |
| 52 | else |
| 53 | { |
| 54 | if(isalpha(c)) |
| 55 | *state->section+=(state->upper) ? toupper(c) : tolower(c); |
| 56 | else |
| 57 | *state->section+=c; |
| 58 | } |