Fixed crash during saving certificate.
[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,
47                                                 RECORD_TYPE_LANGUAGE))
48     {
49         ++token;
50     } else {
51         return false;
52     }
53
54     if (token == parts.end()) {
55         return true;
56     }
57     if (WrtDB::GlobalDAOReadOnly::IsValidSubTag(*token, RECORD_TYPE_EXTLANG)) {
58         ++token;
59     }
60
61     if (token == parts.end()) {
62         return true;
63     }
64     if (WrtDB::GlobalDAOReadOnly::IsValidSubTag(*token, RECORD_TYPE_SCRIPT)) {
65         ++token;
66     }
67
68     if (token == parts.end()) {
69         return true;
70     }
71     if (WrtDB::GlobalDAOReadOnly::IsValidSubTag(*token, RECORD_TYPE_REGION)) {
72         ++token;
73     }
74
75     if (token == parts.end()) {
76         return true;
77     }
78     while (token != parts.end()) {
79         if (WrtDB::GlobalDAOReadOnly::IsValidSubTag(
80                 *token, RECORD_TYPE_VARIANT))
81         {
82             ++token;
83         } else {
84             break;
85         }
86     }
87
88     //'u' - unicode extension - only one BCP47 extension is registered.
89     //TODO: unicode extension should be also validated (l.wrzosek)
90     if (token == parts.end()) {
91         return true;
92     }
93     if (*token == L"u") {
94         ++token;
95         bool one_or_more = false;
96         while (token != parts.end() &&
97                token->size() > 1 &&
98                token->size() <= 8)
99         {
100             one_or_more = true;
101             ++token;
102         }
103         if (!one_or_more) {
104             return false;
105         }
106     }
107
108     //'x' - privateuse
109     if (token == parts.end()) {
110         return true;
111     }
112     if (*token == L"x") {
113         ++token;
114         bool one_or_more = false;
115         while (token != parts.end() &&
116                !token->empty() &&
117                token->size() <= 8)
118         {
119             one_or_more = true;
120             ++token;
121         }
122         if (!one_or_more) {
123             return false;
124         }
125     }
126
127     if (token == parts.end()) {
128         return true;
129     }
130
131     //Try private use now:
132     token = parts.begin();
133     if (*token == L"x") {
134         ++token;
135         bool one_or_more = false;
136         while (token != parts.end() &&
137                !token->empty() &&
138                token->size() <= 8)
139         {
140             one_or_more = true;
141             ++token;
142         }
143         return one_or_more;
144     }
145
146     //grandfathered is always rejected
147     return false;
148 }
149
150 #define TEST_LANG(str, cond) \
151     if (LanguageSubtagRstTreeSingleton::Instance(). \
152             ValidateLanguageTag(str) == cond) { \
153         LogDebug("Good validate status for lang: " << str); \
154     } else { \
155         LogError("Wrong validate status for lang: " << str \
156                                                     << ", should be " << cond); \
157     }
158
159 void LanguageSubtagRstTree::Initialize()
160 {
161     /* Temporarily added unit test. Commented out due to performance drop.
162      * TEST_LANG("zh", true);
163      * TEST_LANG("esx-al", true);
164      * TEST_LANG("zh-Hant", true);
165      * TEST_LANG("zh-Hant-CN", true);
166      * TEST_LANG("zh-Hant-CN-x-private1-private2", true);
167      * TEST_LANG("plxxx", false);
168      * TEST_LANG("pl-x-private111", false);
169      * TEST_LANG("x-private1", false); //do not support pure private ones
170      * TEST_LANG("x-private22", false);
171      * TEST_LANG("i-private22", false); //do not support i-*
172      */
173 }
174
175 #undef TEST_LANG