1 /*
2 * Copyright (c) 2024 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
16 #include <dirent.h>
17 #include <fcntl.h>
18 #include <stdlib.h>
19 #include <unistd.h>
20 #include "update_metadata.h"
21
22 namespace i18n {
23 namespace phonenumbers {
24
25 const std::string UpdateMetadata::METADATA_NAME = "/system/etc/icu_tzdata/i18n/MetadataInfo";
26 const std::string UpdateMetadata::SHORT_METADATA_TYPE = "short";
27 const std::string UpdateMetadata::PHONE_METADATA_TYPE = "phone";
28 const std::string UpdateMetadata::ALTERNATE_METADATA_TYPE = "alter";
29 const std::string UpdateMetadata::REGION_CODE_NONGEO = "001";
30 PhoneMetadataCollection* UpdateMetadata::phoneMetadataCollection = nullptr;
31 std::map<std::string, PhoneMetadata>* UpdateMetadata::shortMetadata = new std::map<std::string, PhoneMetadata>();
32 std::map<std::string, PhoneMetadata>* UpdateMetadata::regionMetadata = new std::map<std::string, PhoneMetadata>();
33 std::map<int, PhoneMetadata>* UpdateMetadata::countryMetadata = new std::map<int, PhoneMetadata>();
34 std::map<int, PhoneMetadata>* UpdateMetadata::alterMetadata = new std::map<int, PhoneMetadata>();
35
UpdateShortNumber(scoped_ptr<std::map<std::string,PhoneMetadata>> & metadataMap)36 void UpdateMetadata::UpdateShortNumber(scoped_ptr<std::map<std::string, PhoneMetadata>>& metadataMap)
37 {
38 for (auto it = shortMetadata->begin(); it != shortMetadata->end(); it++) {
39 std::string code = it->first;
40 PhoneMetadata phoneMetadata = it->second;
41 if (metadataMap->find(code) != metadataMap->end()) {
42 metadataMap->at(code) = phoneMetadata;
43 } else {
44 metadataMap->insert(std::make_pair(code, phoneMetadata));
45 }
46 }
47 }
48
UpdatePhoneNumber(scoped_ptr<std::map<int,PhoneMetadata>> & countryMetadataMap,scoped_ptr<std::map<std::string,PhoneMetadata>> & regionMetadataMap)49 void UpdateMetadata::UpdatePhoneNumber(scoped_ptr<std::map<int, PhoneMetadata>>& countryMetadataMap,
50 scoped_ptr<std::map<std::string, PhoneMetadata>>& regionMetadataMap)
51 {
52 for (auto it = regionMetadata->begin(); it != regionMetadata->end(); it++) {
53 std::string code = it->first;
54 PhoneMetadata phoneMetadata = it->second;
55 if (regionMetadataMap->find(code) != regionMetadataMap->end()) {
56 regionMetadataMap->at(code) = phoneMetadata;
57 } else {
58 regionMetadataMap->insert(std::make_pair(code, phoneMetadata));
59 }
60 }
61 for (auto it = countryMetadata->begin(); it != countryMetadata->end(); it++) {
62 int code = it->first;
63 PhoneMetadata phoneMetadata = it->second;
64 if (countryMetadataMap->find(code) != countryMetadataMap->end()) {
65 countryMetadataMap->at(code) = phoneMetadata;
66 } else {
67 countryMetadataMap->insert(std::make_pair(code, phoneMetadata));
68 }
69 }
70 }
71
UpdateAlternateFormat(std::map<int,const PhoneMetadata * > & metadataMap)72 void UpdateMetadata::UpdateAlternateFormat(std::map<int, const PhoneMetadata*>& metadataMap)
73 {
74 for (auto it = alterMetadata->begin(); it != alterMetadata->end(); it++) {
75 int code = it->first;
76 if (metadataMap.find(code) != metadataMap.end()) {
77 metadataMap.at(code) = &(it->second);
78 } else {
79 metadataMap.insert(std::make_pair(code, &(it->second)));
80 }
81
82 }
83 }
84
LoadUpdatedMetadata(int fd)85 void UpdateMetadata::LoadUpdatedMetadata(int fd)
86 {
87 if (phoneMetadataCollection != nullptr) {
88 return;
89 }
90 if (fd == -1) {
91 return;
92 }
93 phoneMetadataCollection = new PhoneMetadataCollection();
94 phoneMetadataCollection->ParseFromFileDescriptor(fd);
95 for (google::protobuf::RepeatedPtrField<PhoneMetadata>::const_iterator it = phoneMetadataCollection->metadata().begin();
96 it != phoneMetadataCollection->metadata().end(); ++it) {
97
98 std::string mdyRegionCode = it->id();
99 std::string type = mdyRegionCode.substr(0, PHONE_METADATA_TYPE.length());
100 std::string regionCode = mdyRegionCode.substr(PHONE_METADATA_TYPE.length());
101 int countryCode = it->country_code();
102 PhoneMetadata phoneMetadata = *it;
103 phoneMetadata.set_id(regionCode);
104 if (type == SHORT_METADATA_TYPE) {
105 shortMetadata->insert(std::make_pair(regionCode, phoneMetadata));
106 } else if (type == PHONE_METADATA_TYPE) {
107 if (regionCode != REGION_CODE_NONGEO) {
108 regionMetadata->insert(std::make_pair(regionCode, phoneMetadata));
109 } else {
110 countryMetadata->insert(std::make_pair(countryCode, phoneMetadata));
111 }
112 } else if (type == ALTERNATE_METADATA_TYPE) {
113 alterMetadata->insert(std::make_pair(countryCode, phoneMetadata));
114 }
115 }
116 }
117 } // namespace phonenumbers
118 } // namespace i18n
119