• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #include <cctype>
16 #include <filesystem>
17 #include "cpp/src/phonenumbers/phonenumber.h"
18 #include "cpp/src/phonenumbers/shortnumberinfo.h"
19 #include "cpp/src/phonenumbers/phonenumberutil.h"
20 #include "libxml/globals.h"
21 #include "libxml/tree.h"
22 #include "libxml/xmlstring.h"
23 #include "matched_number_info.h"
24 #include "phone_number_rule.h"
25 #include "utils.h"
26 
27 namespace OHOS {
28 namespace Global {
29 namespace I18n {
30 using i18n::phonenumbers::PhoneNumber;
31 using i18n::phonenumbers::PhoneNumberUtil;
32 using i18n::phonenumbers::ShortNumberInfo;
33 
34 std::string PhoneNumberRule::xmlCommonPath = "/system/usr/ohos_locale_config/phonenumber/common.xml";
35 
PhoneNumberRule(std::string & country)36 PhoneNumberRule::PhoneNumberRule(std::string& country)
37 {
38     xmlPath = "/system/usr/ohos_locale_config/phonenumber/" + country + ".xml";
39     isFixed = true;
40     if (!std::filesystem::exists(xmlPath)) {
41         isFixed = false;
42     }
43     this->commonExit = false;
44     this->country = country;
45 }
46 
~PhoneNumberRule()47 PhoneNumberRule::~PhoneNumberRule()
48 {
49     FreePointer(negativeRules);
50     FreePointer(positiveRules);
51     FreePointer(borderRules);
52     FreePointer(codesRules);
53     FreePointer(findRules);
54 }
55 
FreePointer(std::vector<RegexRule * > & ruleList)56 void PhoneNumberRule::FreePointer(std::vector<RegexRule*> &ruleList)
57 {
58     std::vector<RegexRule*>::iterator iter;
59     for (iter = ruleList.begin(); iter != ruleList.end(); ++iter) {
60         if (*iter != nullptr) {
61             delete *iter;
62         }
63         *iter = nullptr;
64     }
65     ruleList.clear();
66 }
67 
Init()68 void PhoneNumberRule::Init()
69 {
70     if (isFixed) {
71         InitRule(xmlPath);
72     }
73     InitRule(xmlCommonPath);
74 }
75 
76 // Load the rules of the corresponding country
InitRule(std::string & xmlPath)77 void PhoneNumberRule::InitRule(std::string& xmlPath)
78 {
79     if (!CheckTzDataFilePath(xmlPath)) {
80         return;
81     }
82     xmlKeepBlanksDefault(0);
83     xmlDocPtr doc = xmlParseFile(xmlPath.c_str());
84     if (doc == nullptr) return;
85     xmlNodePtr root = xmlDocGetRootElement(doc);
86     xmlNodePtr cur = root->xmlChildrenNode;
87     while (cur != nullptr) {
88         std::string category = reinterpret_cast<const char*>(cur->name);
89         xmlNodePtr rule = cur->xmlChildrenNode;
90         while (rule != nullptr && !xmlStrcmp(rule->name, reinterpret_cast<const xmlChar*>("rule"))) {
91             xmlNodePtr value = rule->xmlChildrenNode;
92             std::string insensitive = reinterpret_cast<char*>(xmlNodeGetContent(value));
93             value = value->next;
94             if (category == "common_exit") {
95                 commonExit = (insensitive == "True");
96                 break;
97             }
98             std::string type = reinterpret_cast<char*>(xmlNodeGetContent(value));
99             value = value->next;
100             std::string valid = reinterpret_cast<char*>(xmlNodeGetContent(value));
101             value = value->next;
102             std::string handle = reinterpret_cast<char*>(xmlNodeGetContent(value));
103             icu::UnicodeString content = "";
104             while (value->next != nullptr && !xmlStrcmp(value->next->name,
105                 reinterpret_cast<const xmlChar*>("content"))) {
106                 value = value->next;
107                 xmlChar* contentPtr = xmlNodeGetContent(value);
108                 icu::UnicodeString tempContent = reinterpret_cast<char*>(contentPtr);
109                 content += tempContent;
110                 xmlFree(contentPtr);
111             }
112             SetRules(category, content, valid, handle, insensitive, type);
113             rule = rule->next;
114         }
115         cur = cur->next;
116     }
117     xmlFreeDoc(doc);
118 }
119 
SetRules(std::string & category,icu::UnicodeString & content,std::string & valid,std::string & handle,std::string & insensitive,std::string & type)120 void PhoneNumberRule::SetRules(std::string& category, icu::UnicodeString& content, std::string& valid,
121     std::string& handle, std::string& insensitive, std::string& type)
122 {
123     if (category == "negative" || (category == "common" && commonExit)) {
124         negativeRules.push_back(new RegexRule(content, valid, handle, insensitive, type));
125     } else if (category == "positive") {
126         positiveRules.push_back(new RegexRule(content, valid, handle, insensitive, type));
127     } else if (category == "border") {
128         borderRules.push_back(new RegexRule(content, valid, handle, insensitive, type));
129     } else if (category == "codes") {
130         codesRules.push_back(new RegexRule(content, valid, handle, insensitive, type));
131     } else if (category == "find_number") {
132         findRules.push_back(new RegexRule(content, valid, handle, insensitive, type));
133     }
134 }
135 
GetBorderRules()136 std::vector<RegexRule*> PhoneNumberRule::GetBorderRules()
137 {
138     return borderRules;
139 }
140 
GetCodesRules()141 std::vector<RegexRule*> PhoneNumberRule::GetCodesRules()
142 {
143     return codesRules;
144 }
145 
GetPositiveRules()146 std::vector<RegexRule*> PhoneNumberRule::GetPositiveRules()
147 {
148     return positiveRules;
149 }
150 
GetNegativeRules()151 std::vector<RegexRule*> PhoneNumberRule::GetNegativeRules()
152 {
153     return negativeRules;
154 }
155 
GetFindRules()156 std::vector<RegexRule*> PhoneNumberRule::GetFindRules()
157 {
158     return findRules;
159 }
160 } // namespace I18n
161 } // namespace Global
162 } // namespace OHOS