| 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 | } |