tizen beta release
[framework/web/wrt-installer.git] / src / wrt-installer / language_subtag_rst_tree.cpp
1 /*
2  * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  *    Licensed under the Apache License, Version 2.0 (the "License");
5  *    you may not use this file except in compliance with the License.
6  *    You may obtain a copy of the License at
7  *
8  *        http://www.apache.org/licenses/LICENSE-2.0
9  *
10  *    Unless required by applicable law or agreed to in writing, software
11  *    distributed under the License is distributed on an "AS IS" BASIS,
12  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  *    See the License for the specific language governing permissions and
14  *    limitations under the License.
15  */
16 /**
17  * @file    language_subtag_rst_tree.cpp
18  * @author  Lukasz Wrzosek (l.wrzosek@samsung.com)
19  * @version 1.0
20  */
21 #include <language_subtag_rst_tree.h>
22 #include <dpl/log/log.h>
23 #include <dpl/db/orm.h>
24 #include <dpl/string.h>
25 #include <dpl/wrt-dao-ro/global_dao_read_only.h>
26 #include <iterator>
27 #include <vector>
28 #include <ctype.h>
29 #include <dpl/singleton_impl.h>
30 IMPLEMENT_SINGLETON(LanguageSubtagRstTree)
31
32 bool LanguageSubtagRstTree::ValidateLanguageTag(const std::string &tag_input)
33 {
34     std::string tag = tag_input;
35     std::transform(tag.begin(), tag.end(), tag.begin(), &tolower);
36
37     std::vector<DPL::String> parts;
38     DPL::Tokenize(DPL::FromUTF8String(tag),
39                   '-',
40                   std::back_inserter(parts),
41                   false);
42     std::vector<DPL::String>::iterator token = parts.begin();
43     if (token == parts.end()) {
44         return false;
45     }
46     if (WrtDB::GlobalDAOReadOnly::IsValidSubTag(*token, RECORD_TYPE_LANGUAGE)) {
47         ++token;
48     } else {
49         return false;
50     }
51
52     if (token == parts.end()) {
53         return true;
54     }
55     if (WrtDB::GlobalDAOReadOnly::IsValidSubTag(*token, RECORD_TYPE_EXTLANG)) {
56         ++token;
57     }
58
59     if (token == parts.end()) {
60         return true;
61     }
62     if (WrtDB::GlobalDAOReadOnly::IsValidSubTag(*token, RECORD_TYPE_SCRIPT)) {
63         ++token;
64     }
65
66     if (token == parts.end()) {
67         return true;
68     }
69     if (WrtDB::GlobalDAOReadOnly::IsValidSubTag(*token, RECORD_TYPE_REGION)) {
70         ++token;
71     }
72
73     if (token == parts.end()) {
74         return true;
75     }
76     while (token != parts.end()) {
77         if (WrtDB::GlobalDAOReadOnly::IsValidSubTag(
78                 *token, RECORD_TYPE_VARIANT))
79         {
80             ++token;
81         } else {
82             break;
83         }
84     }
85
86     //'u' - unicode extension - only one BCP47 extension is registered.
87     //TODO: unicode extension should be also validated (l.wrzosek)
88     if (token == parts.end()) {
89         return true;
90     }
91     if (*token == L"u") {
92         ++token;
93         bool one_or_more = false;
94         while (token != parts.end() &&
95                token->size() > 1 &&
96                token->size() <= 8) {
97             one_or_more = true;
98             ++token;
99         }
100         if (!one_or_more) {
101             return false;
102         }
103     }
104
105     //'x' - privateuse
106     if (token == parts.end()) {
107         return true;
108     }
109     if (*token == L"x") {
110         ++token;
111         bool one_or_more = false;
112         while (token != parts.end() &&
113                !token->empty() &&
114                token->size() <= 8) {
115             one_or_more = true;
116             ++token;
117         }
118         if (!one_or_more) {
119             return false;
120         }
121     }
122
123     if (token == parts.end()) {
124         return true;
125     }
126
127     //Try private use now:
128     token = parts.begin();
129     if (*token == L"x") {
130         ++token;
131         bool one_or_more = false;
132         while (token != parts.end() &&
133                !token->empty() &&
134                token->size() <= 8) {
135             one_or_more = true;
136             ++token;
137         }
138         return one_or_more;
139     }
140
141     //grandfathered is always rejected
142     return false;
143 }
144
145 #define TEST_LANG(str, cond) \
146     if (LanguageSubtagRstTreeSingleton::Instance().\
147         ValidateLanguageTag(str) == cond) {\
148         LogDebug("Good validate status for lang: " << str);\
149     } else {\
150         LogError("Wrong validate status for lang: " << str\
151                  << ", should be " << cond);\
152     }
153
154 void LanguageSubtagRstTree::Initialize()
155 {
156     /* Temporarily added unit test. Commented out due to performance drop.
157     TEST_LANG("zh", true);
158     TEST_LANG("esx-al", true);
159     TEST_LANG("zh-Hant", true);
160     TEST_LANG("zh-Hant-CN", true);
161     TEST_LANG("zh-Hant-CN-x-private1-private2", true);
162     TEST_LANG("plxxx", false);
163     TEST_LANG("pl-x-private111", false);
164     TEST_LANG("x-private1", false); //do not support pure private ones
165     TEST_LANG("x-private22", false);
166     TEST_LANG("i-private22", false); //do not support i-*
167     */
168 }
169
170 #undef TEST_LANG