• 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 "vcard_contact.h"
16 
17 #include <numeric>
18 
19 #include "telephony_errors.h"
20 #include "telephony_log_wrapper.h"
21 #include "vcard_configuration.h"
22 #include "vcard_utils.h"
23 #include "locale_config.h"
24 
25 namespace OHOS {
26 namespace Telephony {
27 std::mutex mutex_;
Init()28 void VCardContact::Init() {}
29 
AddRawData(std::shared_ptr<VCardRawData> rawData,int32_t & errorCode)30 void VCardContact::AddRawData(std::shared_ptr<VCardRawData> rawData, int32_t &errorCode)
31 {
32     if (rawData == nullptr) {
33         return;
34     }
35     std::string name;
36     std::string rawValue;
37     std::string byte;
38     std::vector<std::string> values;
39     std::vector<std::string> groups;
40     std::map<std::string, std::vector<std::string>> parasMap;
41     name = rawData->GetName();
42     rawValue = rawData->GetRawValue();
43     byte = rawData->GetByte();
44     values = rawData->GetValue();
45     groups = rawData->GetGroup();
46     parasMap = rawData->GetParasMap();
47     if (values.size() == 0 && byte.empty()) {
48         return;
49     }
50     std::string propValue = (values.size() != 0) ? VCardUtils::TrimListToString(values) : "";
51     AddDatas(name, rawValue, byte, values, propValue, groups, parasMap);
52 }
53 
AddDatas(std::string name,std::string rawValue,std::string byte,std::vector<std::string> values,std::string propValue,std::vector<std::string> groups,std::map<std::string,std::vector<std::string>> parasMap)54 void VCardContact::AddDatas(std::string name, std::string rawValue, std::string byte, std::vector<std::string> values,
55     std::string propValue, std::vector<std::string> groups, std::map<std::string, std::vector<std::string>> parasMap)
56 {
57     std::lock_guard<std::mutex> lock(mutex_);
58     if (name == VCARD_TYPE_VERSION) {
59         vCardType_ = rawValue;
60     } else if (name == VCARD_TYPE_FN || name == VCARD_TYPE_NAME || name == VCARD_TYPE_N ||
61                name == VCARD_TYPE_SORT_STRING || name == VCARD_TYPE_X_PHONETIC_FIRST_NAME ||
62                name == VCARD_TYPE_X_PHONETIC_LAST_NAME || name == VCARD_TYPE_X_PHONETIC_MIDDLE_NAME ||
63                name == VCARD_TYPE_X_PHONETIC) {
64         AddNameData(name, rawValue, values, parasMap, propValue);
65     } else if (name == VCARD_TYPE_NICKNAME) {
66         HandleNickName(propValue);
67     } else if (name == VCARD_TYPE_SOUND) {
68         AddSoundDatas(rawValue, propValue, values, parasMap);
69     } else if (name == VCARD_TYPE_ADR) {
70         AddPostalDatas(rawValue, propValue, values, parasMap);
71     } else if (name == VCARD_TYPE_EMAIL) {
72         AddEmailsData(rawValue, propValue, values, parasMap);
73     } else if (name == VCARD_TYPE_ORG) {
74         AddOrganizationsData(rawValue, propValue, values, parasMap);
75     } else if (name == VCARD_TYPE_TITLE) {
76         HandleTitleValue((parasMap.size() != 0) ? propValue : rawValue);
77     } else if (name == VCARD_TYPE_PHOTO || name == VCARD_TYPE_LOGO) {
78         AddPhotoDatas(byte, rawValue, propValue, values, parasMap);
79     } else if (name == VCARD_TYPE_TEL) {
80         AddPhonesData(rawValue, propValue, values, parasMap);
81     }
82     AddOtherDatas(name, rawValue, byte, values, propValue, groups, parasMap);
83 }
84 
AddOtherDatas(std::string name,std::string rawValue,std::string byte,std::vector<std::string> values,std::string propValue,std::vector<std::string> groups,std::map<std::string,std::vector<std::string>> parasMap)85 void VCardContact::AddOtherDatas(std::string name, std::string rawValue, std::string byte,
86     std::vector<std::string> values, std::string propValue, std::vector<std::string> groups,
87     std::map<std::string, std::vector<std::string>> parasMap)
88 {
89     if (name == VCARD_TYPE_X_SKYPE_PSTNNUMBER) {
90         AddSkypePstnNumDatas(propValue, parasMap);
91     } else if (name == VCARD_TYPE_NOTE) {
92         AddNote((parasMap.size() != 0) ? propValue : rawValue);
93     } else if (name == VCARD_TYPE_URL) {
94         AddWebSiteDatas(rawValue, propValue, values, parasMap);
95     } else if (name == VCARD_TYPE_BDAY) {
96         AddBirthdayDatas(rawValue);
97     } else if (name == VCARD_TYPE_ANNIVERSARY) {
98         AddAnniversaryDatas(propValue);
99     } else if (name == VCARD_TYPE_IMPP) {
100         AddImppDatas(propValue, parasMap);
101     } else if (name == VCARD_TYPE_X_SIP) {
102         AddSipData(rawValue, parasMap, propValue);
103     } else if (name == VCARD_TYPE_X_OHOS_CUSTOM || name == VCARD_TYPE_X_MOBILE_CUSTOM) {
104         AddCustom(rawValue, parasMap, propValue);
105     }
106     AddRemainDatas(name, rawValue, values, propValue, parasMap);
107 }
108 
AddRemainDatas(std::string name,std::string rawValue,std::vector<std::string> values,std::string propValue,std::map<std::string,std::vector<std::string>> parasMap)109 void VCardContact::AddRemainDatas(std::string name, std::string rawValue, std::vector<std::string> values,
110     std::string propValue, std::map<std::string, std::vector<std::string>> parasMap)
111 {
112     if (name == VCARD_TYPE_X_AIM || name == VCARD_TYPE_X_MSN || name == VCARD_TYPE_X_YAHOO ||
113         name == VCARD_TYPE_X_ICQ || name == VCARD_TYPE_X_JABBER || name == VCARD_TYPE_X_QQ ||
114         name == VCARD_TYPE_X_SKYPE_USERNAME || name == VCARD_TYPE_X_HUANLIAO) {
115         AddIms(name, rawValue, propValue, values, parasMap);
116     } else if (name == VCARD_TYPE_X_GROUP) {
117         AddGroups(rawValue);
118     } else if (name == VCARD_PARAM_TYPE_UID) {
119         AddUID(rawValue);
120     }
121 }
122 
HasValidNameData()123 bool VCardContact::HasValidNameData()
124 {
125     return !nameData_->GetPrefix().empty() ||
126            !nameData_->GetFamily().empty() ||
127            !nameData_->GetMiddle().empty() ||
128            !nameData_->GetSuffix().empty() ||
129            !nameData_->GetFormatted().empty() ||
130            !nameData_->GetSort().empty() ||
131            !nameData_->GetPhoneticFamily().empty() ||
132            !nameData_->GetPhoneticGiven().empty() ||
133            !nameData_->GetPhoneticMiddle().empty() ||
134            !nameData_->GetDisplayName().empty();
135 }
136 
CheckNameExist()137 void VCardContact::CheckNameExist()
138 {
139     if (nameData_ == nullptr) {
140         return;
141     }
142     if (HasValidNameData()) {
143         return;
144     }
145     for (auto data : phones_) {
146         if (data != nullptr && !data->GetNumber().empty()) {
147             TELEPHONY_LOGW("no name, replace phone as name");
148             nameData_->setDispalyName(data->GetNumber());
149             return;
150         }
151     }
152     for (auto data : emails_) {
153         if (data != nullptr && !data->GetAddress().empty()) {
154             TELEPHONY_LOGW("no name, replace email as name");
155             nameData_->setDispalyName(data->GetAddress());
156             return;
157         }
158     }
159     for (auto data : organizations_) {
160         if (data != nullptr && !data->GetCompany().empty()) {
161             TELEPHONY_LOGW("no name, replace company as name");
162             nameData_->setDispalyName(data->GetCompany());
163             return;
164         }
165     }
166 }
167 
BuildContactData(int32_t rawId,std::vector<DataShare::DataShareValuesBucket> & contactDataValues)168 int32_t VCardContact::BuildContactData(int32_t rawId, std::vector<DataShare::DataShareValuesBucket> &contactDataValues)
169 {
170     if (nameData_ != nullptr && nameData_->GetDisplayName().empty()) {
171         UpdateDisplayName();
172         CheckNameExist();
173     }
174     BuildValuesBucket(rawId, contactDataValues, nameData_);
175     if (!birthday_->GetBirthday().empty()) {
176         BuildValuesBucket(rawId, contactDataValues, birthday_);
177     }
178     if (!anniversary_->GetAnniversary().empty()) {
179         BuildValuesBucket(rawId, contactDataValues, anniversary_);
180     }
181     BuildValuesBuckets(rawId, contactDataValues, phones_);
182     BuildValuesBuckets(rawId, contactDataValues, emails_);
183     BuildValuesBuckets(rawId, contactDataValues, postals_);
184     BuildValuesBuckets(rawId, contactDataValues, organizations_);
185     BuildValuesBuckets(rawId, contactDataValues, ims_);
186     BuildValuesBuckets(rawId, contactDataValues, photos_);
187     BuildValuesBuckets(rawId, contactDataValues, websites_);
188     BuildValuesBuckets(rawId, contactDataValues, sips_);
189     BuildValuesBuckets(rawId, contactDataValues, nicknames_);
190     BuildValuesBuckets(rawId, contactDataValues, notes_);
191     BuildValuesBuckets(rawId, contactDataValues, relations_);
192     BuildValuesBuckets(rawId, contactDataValues, events_);
193     BuildValuesBuckets(rawId, contactDataValues, groups_);
194     return TELEPHONY_SUCCESS;
195 }
196 
BuildRawContactDataDisplayName(DataShare::DataShareValuesBucket & rawContactDataValue)197 void VCardContact::BuildRawContactDataDisplayName(DataShare::DataShareValuesBucket &rawContactDataValue)
198 {
199     UpdateDisplayName();
200     CheckNameExist();
201     if (nameData_ == nullptr) {
202         return;
203     }
204     rawContactDataValue.Put(RawContact::DISPLAY_NAME, nameData_->GetDisplayName());
205 }
206 
BuildValuesBucket(int32_t rawId,std::vector<DataShare::DataShareValuesBucket> & contactDataValues,std::shared_ptr<VCardContactData> contactData)207 void VCardContact::BuildValuesBucket(int32_t rawId, std::vector<DataShare::DataShareValuesBucket> &contactDataValues,
208     std::shared_ptr<VCardContactData> contactData)
209 {
210     if (contactData == nullptr) {
211         return;
212     }
213     OHOS::DataShare::DataShareValuesBucket valuesBucket;
214     valuesBucket.Put(ContactData::RAW_CONTACT_ID, std::to_string(rawId));
215     contactData->BuildValuesBucket(valuesBucket);
216     contactDataValues.push_back(valuesBucket);
217 }
218 
219 template<typename T>
BuildValuesBuckets(int32_t rawId,std::vector<DataShare::DataShareValuesBucket> & contactDataValues,std::vector<std::shared_ptr<T>> & contactDatas)220 void VCardContact::BuildValuesBuckets(int32_t rawId, std::vector<DataShare::DataShareValuesBucket> &contactDataValues,
221     std::vector<std::shared_ptr<T>> &contactDatas)
222 {
223     for (auto data : contactDatas) {
224         BuildValuesBucket(rawId, contactDataValues, data);
225     }
226 }
227 
BuildContact(std::shared_ptr<DataShare::DataShareResultSet> resultSet)228 int32_t VCardContact::BuildContact(std::shared_ptr<DataShare::DataShareResultSet> resultSet)
229 {
230     std::lock_guard<std::mutex> lock(mutex_);
231     if (resultSet == nullptr) {
232         return TELEPHONY_ERROR;
233     }
234     int32_t resultSetNum = resultSet->GoToFirstRow();
235     while (resultSetNum == 0) {
236         BuildOneData(resultSet);
237         resultSetNum = resultSet->GoToNextRow();
238     }
239     return TELEPHONY_SUCCESS;
240 }
241 
BuildOneData(std::shared_ptr<DataShare::DataShareResultSet> resultSet)242 int32_t VCardContact::BuildOneData(std::shared_ptr<DataShare::DataShareResultSet> resultSet)
243 {
244     if (resultSet == nullptr) {
245         return TELEPHONY_ERROR;
246     }
247     int typeId = 0;
248     int columnIndexType = 0;
249     resultSet->GetColumnIndex(ContactData::TYPE_ID, columnIndexType);
250     resultSet->GetInt(columnIndexType, typeId);
251     switch (typeId) {
252         case TypeId::NAME: {
253             BuildData(resultSet, names_);
254             return TELEPHONY_SUCCESS;
255         }
256         case TypeId::PHONE: {
257             BuildData(resultSet, phones_);
258             return TELEPHONY_SUCCESS;
259         }
260         case TypeId::RELATION: {
261             BuildData(resultSet, relations_);
262             return TELEPHONY_SUCCESS;
263         }
264         case TypeId::IM: {
265             BuildData(resultSet, ims_);
266             return TELEPHONY_SUCCESS;
267         }
268         case TypeId::SIP_ADDRESS: {
269             BuildData(resultSet, sips_);
270             return TELEPHONY_SUCCESS;
271         }
272         default:
273             break;
274     }
275     return BuildOtherData(typeId, resultSet);
276 }
277 
BuildOtherData(int32_t typeId,std::shared_ptr<DataShare::DataShareResultSet> resultSet)278 int32_t VCardContact::BuildOtherData(int32_t typeId, std::shared_ptr<DataShare::DataShareResultSet> resultSet)
279 {
280     switch (typeId) {
281         case TypeId::NICKNAME: {
282             BuildData(resultSet, nicknames_);
283             return TELEPHONY_SUCCESS;
284         }
285         case TypeId::EMAIL: {
286             BuildData(resultSet, emails_);
287             return TELEPHONY_SUCCESS;
288         }
289         case TypeId::POSTAL_ADDRESS: {
290             BuildData(resultSet, postals_);
291             return TELEPHONY_SUCCESS;
292         }
293         case TypeId::ORGANIZATION: {
294             BuildData(resultSet, organizations_);
295             return TELEPHONY_SUCCESS;
296         }
297         case TypeId::WEBSITE: {
298             BuildData(resultSet, websites_);
299             return TELEPHONY_SUCCESS;
300         }
301         case TypeId::PHOTO: {
302             BuildData(resultSet, photos_);
303             return TELEPHONY_SUCCESS;
304         }
305         case TypeId::NOTE: {
306             BuildData(resultSet, notes_);
307             return TELEPHONY_SUCCESS;
308         }
309         case TypeId::CONTACT_EVENT: {
310             BuildData(resultSet, events_);
311             return TELEPHONY_SUCCESS;
312         }
313         case TypeId::GROUP: {
314             BuildData(resultSet, groups_);
315             return TELEPHONY_SUCCESS;
316         }
317         default:
318             break;
319     }
320     return TELEPHONY_SUCCESS;
321 }
322 
323 template<typename T>
BuildData(std::shared_ptr<DataShare::DataShareResultSet> resultSet,std::vector<std::shared_ptr<T>> & contactDatas)324 void VCardContact::BuildData(
325     std::shared_ptr<DataShare::DataShareResultSet> resultSet, std::vector<std::shared_ptr<T>> &contactDatas)
326 {
327     auto data = std::make_shared<T>();
328     data->BuildData(resultSet);
329     contactDatas.push_back(data);
330 }
331 
GetNameData()332 std::shared_ptr<VCardNameData> VCardContact::GetNameData()
333 {
334     return nameData_;
335 }
336 
GetNames()337 std::vector<std::shared_ptr<VCardNameData>> VCardContact::GetNames()
338 {
339     return names_;
340 }
341 
GetRelations()342 std::vector<std::shared_ptr<VCardRelationData>> VCardContact::GetRelations()
343 {
344     return relations_;
345 }
346 
GetIms()347 std::vector<std::shared_ptr<VCardImData>> VCardContact::GetIms()
348 {
349     return ims_;
350 }
351 
GetSips()352 std::vector<std::shared_ptr<VCardSipData>> VCardContact::GetSips()
353 {
354     return sips_;
355 }
356 
GetPhones()357 std::vector<std::shared_ptr<VCardPhoneData>> VCardContact::GetPhones()
358 {
359     return phones_;
360 }
361 
GetOrganizations()362 std::vector<std::shared_ptr<VCardOrganizationData>> VCardContact::GetOrganizations()
363 {
364     return organizations_;
365 }
366 
GetWebsites()367 std::vector<std::shared_ptr<VCardWebsiteData>> VCardContact::GetWebsites()
368 {
369     return websites_;
370 }
371 
GetPhotos()372 std::vector<std::shared_ptr<VCardPhotoData>> VCardContact::GetPhotos()
373 {
374     return photos_;
375 }
376 
GetEmails()377 std::vector<std::shared_ptr<VCardEmailData>> VCardContact::GetEmails()
378 {
379     return emails_;
380 }
381 
GetNicknames()382 std::vector<std::shared_ptr<VCardNicknameData>> VCardContact::GetNicknames()
383 {
384     return nicknames_;
385 }
386 
GetPostalDatas()387 std::vector<std::shared_ptr<VCardPostalData>> VCardContact::GetPostalDatas()
388 {
389     return postals_;
390 }
391 
GetEventDatas()392 std::vector<std::shared_ptr<VCardEventData>> VCardContact::GetEventDatas()
393 {
394     return events_;
395 }
396 
GetNotes()397 std::vector<std::shared_ptr<VCardNoteData>> VCardContact::GetNotes()
398 {
399     return notes_;
400 }
401 
GetBirthdays()402 std::shared_ptr<VCardBirthdayData> VCardContact::GetBirthdays()
403 {
404     return birthday_;
405 }
406 
GetGroups()407 std::vector<std::shared_ptr<VCardGroupData>> VCardContact::GetGroups()
408 {
409     return groups_;
410 }
411 
HandleName(std::vector<std::string> values,std::map<std::string,std::vector<std::string>> parasMap)412 void VCardContact::HandleName(std::vector<std::string> values, std::map<std::string, std::vector<std::string>> parasMap)
413 {
414     if (nameData_ == nullptr) {
415         return;
416     }
417     int32_t size = static_cast<int32_t>(values.size());
418     if (values.empty() || size == 0) {
419         return;
420     }
421     if (size > N_MAX_VALUE_SIZE) {
422         size = N_MAX_VALUE_SIZE;
423     }
424     switch (size) {
425         case SIZE_FIVE:
426             nameData_->SetSuffix(values[N_SUFFIX_VALUE_INDEX]);
427             [[fallthrough]]; // fall_through
428         case SIZE_FOUR:
429             nameData_->SetPrefix(values[N_PREFIX_VALUE_INDEX]);
430             [[fallthrough]]; // fall_through
431         case SIZE_THREE:
432             nameData_->SetMiddle(values[N_MIDDLE_VALUE_INDEX]);
433             [[fallthrough]]; // fall_through
434         case SIZE_TWO:
435             nameData_->SetGiven(values[N_GIVEN_VALUE_INDEX]);
436             [[fallthrough]]; // fall_through
437         default:
438             nameData_->SetFamily(values[N_FAMILY_VALUE_INDEX]);
439             break;
440     }
441 }
442 
HandleSortAsName(std::map<std::string,std::vector<std::string>> parasMap)443 void VCardContact::HandleSortAsName(std::map<std::string, std::vector<std::string>> parasMap)
444 {
445     if (nameData_ == nullptr) {
446         return;
447     }
448     if (vCardType_ == VERSION_30 &&
449         !(nameData_->GetPhoneticFamily().empty() && nameData_->GetPhoneticMiddle().empty() &&
450             nameData_->GetPhoneticGiven().empty())) {
451         return;
452     }
453     std::vector<std::string> sortAsList;
454     std::map<std::string, std::vector<std::string>>::iterator it = parasMap.find(VCARD_PARAM_SORT_AS);
455     if (it == parasMap.end()) {
456         return;
457     } else {
458         sortAsList = it->second;
459     }
460 
461     if (sortAsList.size() > 0) {
462         std::vector<std::string> sortNames = VCardUtils::ConstructListFromValue(sortAsList[0], vCardType_);
463         int32_t size = static_cast<int32_t>(sortNames.size());
464         if (size > SORT_NAME_MAX_VALUE_SIZE) {
465             size = SORT_NAME_MAX_VALUE_SIZE;
466         }
467         switch (size) {
468             case SIZE_THREE:
469                 nameData_->SetPhoneticMiddle(sortNames[PHONETIC_MIDDLE_VALUE_INDEX]);
470                 [[fallthrough]]; // fall_through
471             case SIZE_TWO:
472                 nameData_->SetPhoneticGiven(sortNames[PHONETIC_GIVEN_VALUE_INDEX]);
473                 [[fallthrough]]; // fall_through
474             default:
475                 nameData_->SetPhoneticFamily(sortNames[PHONETIC_FAMILY_VALUE_INDEX]);
476                 break;
477         }
478     }
479 }
480 
HandleNickName(std::string nickName)481 void VCardContact::HandleNickName(std::string nickName)
482 {
483     std::shared_ptr<VCardNicknameData> nn = std::make_shared<VCardNicknameData>();
484     nn->SetNickName(nickName);
485     nicknames_.push_back(nn);
486 }
487 
HandlePhoneticNameFromSound(std::vector<std::string> elems)488 void VCardContact::HandlePhoneticNameFromSound(std::vector<std::string> elems)
489 {
490     if (nameData_ == nullptr) {
491         return;
492     }
493     if (nameData_->GetPhoneticFamily().empty() && nameData_->GetPhoneticMiddle().empty() &&
494         nameData_->GetPhoneticGiven().empty()) {
495         return;
496     }
497     int32_t size = static_cast<int32_t>(elems.size());
498     if (elems.empty() || size == 0) {
499         return;
500     }
501     size = (size > PHONE_NAME_SOUND_MAX_VALUE_SIZE) ? PHONE_NAME_SOUND_MAX_VALUE_SIZE : size;
502     if (elems[0].length() > 0) {
503         bool onlyFirstElemIsNonEmpty = true;
504         for (int32_t i = 1; i < size; i++) {
505             if (elems[i].length() > 0) {
506                 onlyFirstElemIsNonEmpty = false;
507                 break;
508             }
509         }
510         if (onlyFirstElemIsNonEmpty) {
511             std::vector<std::string> namesArray = VCardUtils::Split(elems[VALUE_INDEX_ZERO], " ");
512             int32_t nameArrayLength = static_cast<int32_t>(namesArray.size());
513             if (nameArrayLength == VALUE_LEN_THREE) {
514                 nameData_->SetPhoneticFamily(namesArray[VALUE_INDEX_ZERO]);
515                 nameData_->SetPhoneticMiddle(namesArray[VALUE_INDEX_ONE]);
516                 nameData_->SetPhoneticGiven(namesArray[VALUE_INDEX_TWO]);
517             } else if (nameArrayLength == VALUE_LEN_TWO) {
518                 nameData_->SetPhoneticFamily(namesArray[VALUE_INDEX_ZERO]);
519                 nameData_->SetPhoneticGiven(namesArray[VALUE_INDEX_ONE]);
520             } else {
521                 nameData_->SetPhoneticGiven(elems[VALUE_INDEX_ZERO]);
522             }
523             return;
524         }
525     }
526     switch (size) {
527         case SIZE_THREE:
528             nameData_->SetPhoneticMiddle(elems[VALUE_INDEX_TWO]);
529             break;
530         case SIZE_TWO:
531             nameData_->SetPhoneticGiven(elems[VALUE_INDEX_ONE]);
532             break;
533         default:
534             nameData_->SetPhoneticFamily(elems[VALUE_INDEX_ZERO]);
535             break;
536     }
537 }
538 
AddPostal(int32_t type,std::vector<std::string> propValueList,std::string label,bool isPrimary)539 void VCardContact::AddPostal(int32_t type, std::vector<std::string> propValueList, std::string label, bool isPrimary)
540 {
541     std::shared_ptr<VCardPostalData> pd = std::make_shared<VCardPostalData>();
542     pd->InitPostalData(propValueList, type, label);
543     postals_.push_back(pd);
544 }
545 
AddEmail(int32_t type,std::string data,std::string label,std::string displayname,bool isPrimary)546 void VCardContact::AddEmail(int32_t type, std::string data, std::string label, std::string displayname, bool isPrimary)
547 {
548     std::shared_ptr<VCardEmailData> ed = std::make_shared<VCardEmailData>();
549     ed->InitEmailData(data, std::to_string(type), label, displayname);
550     emails_.push_back(ed);
551 }
552 
HandleOrgValue(int32_t type,std::vector<std::string> orgList,std::map<std::string,std::vector<std::string>> paramMap,bool isPrimary)553 void VCardContact::HandleOrgValue(int32_t type, std::vector<std::string> orgList,
554     std::map<std::string, std::vector<std::string>> paramMap, bool isPrimary)
555 {
556     std::string phoneticName = BuildSinglePhoneticNameFromSortAsParam(paramMap);
557 
558     std::string organizationName;
559     std::string departmentName;
560     int32_t size = static_cast<int32_t>(orgList.size());
561     switch (size) {
562         case SIZE_ZERO:
563             organizationName = "";
564             departmentName = "";
565             break;
566         case SIZE_ONE:
567             organizationName = orgList[0];
568             departmentName = "";
569             break;
570         default:
571             organizationName = orgList[0];
572             std::string builder;
573             for (int32_t i = 1; i < size; i++) {
574                 if (i > 1) {
575                     builder += " ";
576                 }
577                 builder += orgList[i];
578             }
579             departmentName = builder;
580             break;
581     }
582 
583     if (organizations_.empty()) {
584         AddNewOrganization(organizationName, departmentName, "", "", phoneticName, type, isPrimary);
585         return;
586     }
587 
588     for (std::shared_ptr<VCardOrganizationData> organizationData : organizations_) {
589         if (organizationData == nullptr) {
590             return;
591         }
592         if (organizationData->GetOrganization().empty() && organizationData->GetDepartmentName().empty()) {
593             organizationData->SetOrganization(organizationName);
594             organizationData->SetDepartmentName(departmentName);
595             return;
596         }
597     }
598 
599     AddNewOrganization(organizationName, departmentName, "", "", phoneticName, type, isPrimary);
600 }
601 
BuildSinglePhoneticNameFromSortAsParam(std::map<std::string,std::vector<std::string>> paramMap)602 std::string VCardContact::BuildSinglePhoneticNameFromSortAsParam(
603     std::map<std::string, std::vector<std::string>> paramMap)
604 {
605     std::vector<std::string> sortAsList;
606     std::map<std::string, std::vector<std::string>>::iterator it = paramMap.find(VCARD_PARAM_SORT_AS);
607     if (it == paramMap.end()) {
608         TELEPHONY_LOGE("Map does not contain this key, %{public}s", VCARD_PARAM_SORT_AS);
609         return "";
610     } else {
611         sortAsList = it->second;
612     }
613     if (!sortAsList.empty()) {
614         std::vector<std::string> sortNames = VCardUtils::ConstructListFromValue(sortAsList.at(0), vCardType_);
615         std::string init = "";
616         std::string builder = std::accumulate(sortNames.begin(), sortNames.end(), init);
617         return builder;
618     } else {
619         return "";
620     }
621 }
622 
AddNewOrganization(std::string organizationName,std::string departmentName,std::string company,std::string titleName,std::string phoneticName,int32_t type,bool isPrimary)623 void VCardContact::AddNewOrganization(std::string organizationName, std::string departmentName, std::string company,
624     std::string titleName, std::string phoneticName, int32_t type, bool isPrimary)
625 {
626     std::shared_ptr<VCardOrganizationData> od = std::make_shared<VCardOrganizationData>();
627     od->InitOrganizationData(organizationName, departmentName, company, titleName, phoneticName, type);
628     organizations_.push_back(od);
629 }
630 
HandleTitleValue(std::string title)631 void VCardContact::HandleTitleValue(std::string title)
632 {
633     if (organizations_.empty()) {
634         AddNewOrganization("", "", "", title, "", VALUE_INDEX_ONE, false);
635         return;
636     }
637     for (std::shared_ptr<VCardOrganizationData> organizationData : organizations_) {
638         if (organizationData == nullptr) {
639             return;
640         }
641         if (organizationData->GetTitle().empty()) {
642             organizationData->SetTitle(title);
643             return;
644         }
645     }
646     AddNewOrganization("", "", "", title, "", VALUE_INDEX_ONE, false);
647 }
648 
AddPhotoBytes(std::string formatName,std::string photoBytes,bool isPrimary)649 void VCardContact::AddPhotoBytes(std::string formatName, std::string photoBytes, bool isPrimary)
650 {
651     std::shared_ptr<VCardPhotoData> pd = std::make_shared<VCardPhotoData>();
652     pd->InitPhotoData(formatName, photoBytes);
653     photos_.push_back(pd);
654 }
655 
HandleSipCase(std::string propValue,std::vector<std::string> typeCollection)656 void VCardContact::HandleSipCase(std::string propValue, std::vector<std::string> typeCollection)
657 {
658     if (propValue.empty()) {
659         return;
660     }
661     if (VCardUtils::StartWith(propValue, "sip:")) {
662         propValue = propValue.substr(VALUE_INDEX_FOUR);
663         if (propValue.length() == 0) {
664             return;
665         }
666     }
667     int32_t type = -1;
668     std::string label;
669     bool isPrimary = false;
670     if (!typeCollection.empty()) {
671         for (std::string typeStringOrg : typeCollection) {
672             std::string typeStringUpperCase = VCardUtils::ToUpper(typeStringOrg);
673             if (typeStringUpperCase == VCARD_PARAM_TYPE_PREF) {
674                 isPrimary = true;
675             } else if (typeStringUpperCase == VCARD_PARAM_TYPE_HOME) {
676                 type = static_cast<int32_t>(SipType::SIP_HOME);
677             } else if (typeStringUpperCase == VCARD_PARAM_TYPE_WORK) {
678                 type = static_cast<int32_t>(SipType::SIP_WORK);
679             } else if (type < 0) {
680                 label = (VCardUtils::StartWith(typeStringUpperCase, "X-")) ? typeStringOrg.substr(VALUE_INDEX_TWO)
681                                                                            : typeStringOrg;
682                 type = static_cast<int32_t>(SipType::CUSTOM_LABEL);
683             } else {
684                 TELEPHONY_LOGI("No need to do anything");
685             }
686         }
687     }
688     if (type < 0) {
689         type = static_cast<int32_t>(SipType::SIP_OTHER);
690     }
691     AddSip(propValue, type, label, isPrimary);
692 }
693 
AddPhone(int32_t type,std::string data,std::string label,bool isPrimary)694 void VCardContact::AddPhone(int32_t type, std::string data, std::string label, bool isPrimary)
695 {
696     std::string builder;
697     std::string trimmed = data;
698     std::string formattedNumber;
699     if (type == static_cast<int32_t>(PhoneVcType::NUM_PAGER) ||
700         VCardConfiguration::RefrainPhoneNumberFormatting(VCardUtils::VcardtypeToInt(vCardType_))) {
701         formattedNumber = trimmed;
702     } else {
703         bool hasPauseOrWait = false;
704         std::size_t length = trimmed.length();
705         for (std::size_t i = 0; i < length; i++) {
706             char ch = trimmed[i];
707             if (ch == 'p' || ch == 'P') {
708                 builder += ',';
709                 hasPauseOrWait = true;
710             } else if (ch == 'w' || ch == 'W') {
711                 builder += ';';
712                 hasPauseOrWait = true;
713             } else if (((ch >= '0' && ch <= '9') || ch == '*' || ch == '#') || (i == 0 && ch == '+')) {
714                 builder += ch;
715             } else {
716                 TELEPHONY_LOGI("No need to do anything");
717             }
718         }
719         if (!hasPauseOrWait) {
720             formattedNumber = VCardUtils::FormatNumber(builder);
721         } else {
722             formattedNumber = builder;
723         }
724     }
725     std::shared_ptr<VCardPhoneData> object = std::make_shared<VCardPhoneData>();
726     object->InitPhoneData(formattedNumber, type, label, isPrimary);
727     phones_.push_back(object);
728 }
729 
AddSip(std::string sipData,int32_t type,std::string label,bool isPrimary)730 void VCardContact::AddSip(std::string sipData, int32_t type, std::string label, bool isPrimary)
731 {
732     std::shared_ptr<VCardSipData> object = std::make_shared<VCardSipData>();
733     object->InitSipData(sipData, type, label);
734     sips_.push_back(object);
735 }
736 
AddNote(const std::string note)737 void VCardContact::AddNote(const std::string note)
738 {
739     std::shared_ptr<VCardNoteData> object = std::make_shared<VCardNoteData>();
740     object->InitNoteData(note);
741     notes_.push_back(object);
742 }
743 
AddIms(std::string name,std::string rawValue,std::string propValue,std::vector<std::string> values,std::map<std::string,std::vector<std::string>> parasMap)744 void VCardContact::AddIms(std::string name, std::string rawValue, std::string propValue,
745     std::vector<std::string> values, std::map<std::string, std::vector<std::string>> parasMap)
746 {
747     int32_t labeId = VCardUtils::GetLabelIdFromImType(name);
748     std::shared_ptr<VCardImData> object = std::make_shared<VCardImData>();
749     std::vector<std::string> valueList = GetValueListFromParasMap(rawValue, propValue, parasMap);
750     for (std::string value : valueList) {
751         object->SetAddress(value);
752     }
753     if (object->GetAddress().empty()) {
754         object->SetAddress(rawValue);
755     }
756     object->SetLabelId(std::to_string(labeId));
757     ims_.push_back(object);
758 }
759 
AddNameData(std::string name,std::string rawValue,std::vector<std::string> values,std::map<std::string,std::vector<std::string>> parasMap,std::string propValue)760 void VCardContact::AddNameData(std::string name, std::string rawValue, std::vector<std::string> values,
761     std::map<std::string, std::vector<std::string>> parasMap, std::string propValue)
762 {
763     if (nameData_ == nullptr) {
764         return;
765     }
766     if (name == VCARD_TYPE_FN) {
767         nameData_->setDispalyName((values.size() != 0) ? values[0] : "");
768     } else if (name == VCARD_TYPE_N) {
769         HandleSortAsName(parasMap);
770         HandleName(values, parasMap);
771     } else if (name == VCARD_TYPE_NAME) {
772         if (nameData_->GetFormatted().empty()) {
773             nameData_->SetFormatted(propValue);
774         }
775     } else if (name == VCARD_TYPE_SORT_STRING) {
776         nameData_->setSort(propValue);
777     } else if (name == VCARD_TYPE_X_PHONETIC_FIRST_NAME) {
778         std::vector<std::string> valueList = GetValueListFromParasMap(rawValue, propValue, parasMap);
779         nameData_->SetPhoneticGiven((valueList.size() != 0) ? valueList[0] : "");
780     } else if (name == VCARD_TYPE_X_PHONETIC_MIDDLE_NAME) {
781         std::vector<std::string> valueList = GetValueListFromParasMap(rawValue, propValue, parasMap);
782         nameData_->SetPhoneticMiddle((valueList.size() != 0) ? valueList[0] : "");
783     } else if (name == VCARD_TYPE_X_PHONETIC_LAST_NAME) {
784         std::vector<std::string> valueList = GetValueListFromParasMap(rawValue, propValue, parasMap);
785         nameData_->SetPhoneticFamily((valueList.size() != 0) ? valueList[0] : "");
786     } else if (name == VCARD_TYPE_X_PHONETIC) {
787         std::vector<std::string> valueList = GetValueListFromParasMap(rawValue, propValue, parasMap);
788         nameData_->SetPhoneticName((valueList.size() != 0) ? valueList[0] : "");
789     } else {
790         TELEPHONY_LOGI("No need to do anything");
791     }
792 }
793 
AddCustom(std::string rawValue,std::map<std::string,std::vector<std::string>> parasMap,std::string propValue)794 void VCardContact::AddCustom(
795     std::string rawValue, std::map<std::string, std::vector<std::string>> parasMap, std::string propValue)
796 {
797     std::vector<std::string> values = GetValueListFromParasMap(rawValue, propValue, parasMap);
798     std::string type = (values.size() != 0) ? values[0] : "";
799     if (type == TypeData::NICKNAME) {
800         std::shared_ptr<VCardNicknameData> object = std::make_shared<VCardNicknameData>();
801         int i = 0;
802         for (std::string value : values) {
803             if (i == SIZE_ONE) {
804                 object->SetNickName(value);
805                 break;
806             }
807             i++;
808         }
809         nicknames_.push_back(object);
810     } else if (type == TypeData::RELATION || type == VCARD_TYPE_X_MOBILE_RELATION) {
811         std::shared_ptr<VCardRelationData> object = std::make_shared<VCardRelationData>();
812         int i = 0;
813         for (std::string value : values) {
814             if (i == SIZE_ONE) {
815                 object->SetRelationName(value);
816             } else if (i == SIZE_TWO) {
817                 value = value == std::to_string(VALUE_INDEX_ZERO) ?
818                     std::to_string(static_cast<int32_t>(RelationType::CUSTOM_LABEL)) : value;
819                 object->SetLabelId(value);
820             } else if (i == SIZE_THREE) {
821                 object->SetLabelName(value);
822                 break;
823             }
824             i++;
825         }
826         relations_.push_back(object);
827     } else if (type == TypeData::CONTACT_EVENT || type == VCARD_TYPE_X_MOBILE_EVENTS) {
828         std::shared_ptr<VCardEventData> object = std::make_shared<VCardEventData>();
829         int i = 0;
830         for (std::string value : values) {
831             if (i == SIZE_ONE) {
832                 object->SetEventDate(value);
833             } else if (i == SIZE_TWO) {
834                 value = ConvertHarmonyEvents(type, value);
835                 object->SetLabelId(value);
836             } else if (i == SIZE_THREE) {
837                 object->SetLabelName(value);
838                 break;
839             }
840             i++;
841         }
842         events_.push_back(object);
843     }
844 }
845 
ConvertHarmonyEvents(std::string type,std::string value)846 std::string VCardContact::ConvertHarmonyEvents(std::string type, std::string value)
847 {
848     if (type != VCARD_TYPE_X_MOBILE_EVENTS) {
849         return value;
850     }
851     std::string convertedValue = value;
852     if (value == std::to_string(static_cast<int32_t>(EventHM4Type::EVENT_HM4_ANNIVERSARY))) {
853         convertedValue = std::to_string(static_cast<int32_t>(EventType::EVENT_ANNIVERSARY));
854     }
855     if (value == std::to_string(static_cast<int32_t>(EventHM4Type::EVENT_HM4_OTHER))) {
856         convertedValue = std::to_string(static_cast<int32_t>(EventType::EVENT_OTHER));
857     }
858     if (value == std::to_string(static_cast<int32_t>(EventHM4Type::EVENT_HM4_LUNAR_BIRTHDAY))) {
859         convertedValue = std::to_string(static_cast<int32_t>(EventType::EVENT_LUNAR_BIRTHDAY));
860     }
861     return convertedValue;
862 }
863 
SetSip(std::string rawValue,std::map<std::string,std::vector<std::string>> parasMap,std::string propValue)864 void VCardContact::SetSip(
865     std::string rawValue, std::map<std::string, std::vector<std::string>> parasMap, std::string propValue)
866 {
867     std::map<std::string, std::vector<std::string>>::iterator it = parasMap.find(VCARD_PARAM_TYPE);
868     if (it == parasMap.end()) {
869         TELEPHONY_LOGE("Map does not contain this key, %{public}s", VCARD_PARAM_TYPE);
870         std::shared_ptr<VCardSipData> object = std::make_shared<VCardSipData>();
871         std::vector<std::string> values = VCardUtils::Split(propValue, ";");
872         for (size_t i = 0; i < values.size(); i++) {
873             if (i == SIZE_ZERO) {
874                 std::vector<std::string> address = VCardUtils::Split(values[i], ":");
875                 object->SetAddress((address.size() >= SIZE_TWO) ? address[1] : "");
876             } else if (i == SIZE_ONE) {
877                 object->SetLabelId(values[i]);
878             } else if (i == SIZE_TWO) {
879                 object->SetLabelName(values[i]);
880                 break;
881             }
882         }
883         sips_.push_back(object);
884     } else {
885         std::vector<std::string> typeCollection;
886         typeCollection = it->second;
887         HandleSipCase(propValue, typeCollection);
888     }
889 }
890 
AddSipData(std::string rawValue,std::map<std::string,std::vector<std::string>> parasMap,std::string propValue)891 void VCardContact::AddSipData(
892     std::string rawValue, std::map<std::string, std::vector<std::string>> parasMap, std::string propValue)
893 {
894     if (parasMap.size() != 0 && !propValue.empty()) {
895         SetSip(rawValue, parasMap, propValue);
896         return;
897     }
898     std::shared_ptr<VCardSipData> object = std::make_shared<VCardSipData>();
899     std::vector<std::string> values = VCardUtils::Split(rawValue, ";");
900     for (size_t i = 0; i < values.size(); i++) {
901         if (i == SIZE_ZERO) {
902             std::vector<std::string> address = VCardUtils::Split(values[i], ":");
903             object->SetAddress((address.size() >= SIZE_TWO) ? address[1] : "");
904         }
905         if (i == SIZE_ONE) {
906             object->SetLabelId(values[i]);
907         }
908         if (i == SIZE_TWO) {
909             object->SetLabelName(values[i]);
910         }
911     }
912     sips_.push_back(object);
913 }
914 
AddPhonesData(std::string rawValue,std::string propValue,std::vector<std::string> values,std::map<std::string,std::vector<std::string>> parasMap)915 void VCardContact::AddPhonesData(std::string rawValue, std::string propValue, std::vector<std::string> values,
916     std::map<std::string, std::vector<std::string>> parasMap)
917 {
918     std::string phoneNumber;
919     bool isSip = false;
920     if (vCardType_ == VERSION_40) {
921         if (VCardUtils::StartWith(propValue, "sip:")) {
922             isSip = true;
923         } else if (VCardUtils::StartWith(propValue, "tel:")) {
924             phoneNumber = propValue.substr(VALUE_INDEX_FOUR);
925         } else {
926             phoneNumber = propValue;
927         }
928     } else {
929         phoneNumber = rawValue;
930     }
931     if (isSip) {
932         std::vector<std::string> typeCollection;
933         std::map<std::string, std::vector<std::string>>::iterator it = parasMap.find(VCARD_PARAM_TYPE);
934         if (it == parasMap.end()) {
935             TELEPHONY_LOGE("Map does not contain this key, %{public}s", VCARD_PARAM_TYPE);
936             return;
937         } else {
938             typeCollection = it->second;
939         }
940         HandleSipCase(propValue, typeCollection);
941     } else {
942         HandlePhoneCase(phoneNumber, rawValue, propValue, values, parasMap);
943     }
944 }
945 
HandlePhoneCase(std::string phoneNumber,std::string rawValue,std::string propValue,std::vector<std::string> values,std::map<std::string,std::vector<std::string>> parasMap)946 void VCardContact::HandlePhoneCase(std::string phoneNumber, std::string rawValue, std::string propValue,
947     std::vector<std::string> values, std::map<std::string, std::vector<std::string>> parasMap)
948 {
949     std::vector<std::string> typeCollection = {};
950     std::map<std::string, std::vector<std::string>>::iterator it = parasMap.find(VCARD_PARAM_TYPE);
951     if (it != parasMap.end()) {
952         typeCollection = it->second;
953     }
954     std::tuple<int32_t, std::string> result(NUM_MINUS_ONE, "-1");
955     VCardUtils::GetPhoneTypeFromStrings(typeCollection, phoneNumber, result);
956     int32_t type = NUM_MINUS_ONE;
957     std::string label;
958     if (std::get<0>(result) != NUM_MINUS_ONE && std::get<1>(result) == "-1") {
959         type = std::get<0>(result);
960         label = "";
961     } else if (std::get<0>(result) == NUM_MINUS_ONE && std::get<1>(result) != "-1") {
962         type = static_cast<int32_t>(PhoneVcType::CUSTOM_LABEL);
963         label = std::get<1>(result);
964     }
965     bool isPrimary = false;
966     bool contains = false;
967     if (std::find(typeCollection.begin(), typeCollection.end(), VCARD_PARAM_TYPE_PREF) != typeCollection.end()) {
968         contains = true;
969     }
970     if (!typeCollection.empty() && contains) {
971         isPrimary = true;
972     }
973     AddPhone(type, phoneNumber, label, isPrimary);
974 }
975 
AddOrganizationsData(std::string rawValue,std::string propValue,std::vector<std::string> values,std::map<std::string,std::vector<std::string>> parasMap)976 void VCardContact::AddOrganizationsData(std::string rawValue, std::string propValue, std::vector<std::string> values,
977     std::map<std::string, std::vector<std::string>> parasMap)
978 {
979     int32_t type = SIZE_ONE;
980     bool isPrimary = false;
981     if (parasMap.size() != 0) {
982         std::map<std::string, std::vector<std::string>>::iterator it = parasMap.find(VCARD_PARAM_TYPE);
983         if (it == parasMap.end()) {
984             TELEPHONY_LOGE("Map does not contain this key, %{public}s", VCARD_PARAM_TYPE);
985             AddNewOrganization("", "", propValue, "", "", type, isPrimary);
986         } else {
987             HandleOrgValue(type, values, parasMap, isPrimary);
988         }
989     } else {
990         AddNewOrganization("", "", rawValue, "", "", type, isPrimary);
991     }
992 }
993 
AddEmailsData(std::string rawValue,std::string propValue,std::vector<std::string> values,std::map<std::string,std::vector<std::string>> parasMap)994 void VCardContact::AddEmailsData(std::string rawValue, std::string propValue, std::vector<std::string> values,
995     std::map<std::string, std::vector<std::string>> parasMap)
996 {
997     int32_t type = NUM_MINUS_ONE;
998     std::string label = "";
999     bool isPrimary = false;
1000     std::vector<std::string> typeCollection;
1001     std::map<std::string, std::vector<std::string>>::iterator it = parasMap.find(VCARD_PARAM_TYPE);
1002     if (it == parasMap.end()) {
1003         TELEPHONY_LOGI("Map does not contain this key, %{public}s, use OTHER type", VCARD_PARAM_TYPE);
1004         // contains no type info will fallback to OTHER type
1005     } else {
1006         typeCollection = it->second;
1007     }
1008     if (!typeCollection.empty()) {
1009         for (std::string typeStringOrg : typeCollection) {
1010             std::string typeStringUpperCase = VCardUtils::ToUpper(typeStringOrg);
1011             if (typeStringUpperCase == VCARD_PARAM_TYPE_PREF) {
1012                 isPrimary = true;
1013             } else if (typeStringUpperCase == VCARD_PARAM_TYPE_HOME) {
1014                 type = static_cast<int32_t>(EmailType::EMAIL_HOME);
1015             } else if (typeStringUpperCase == VCARD_PARAM_TYPE_WORK) {
1016                 type = static_cast<int32_t>(EmailType::EMAIL_WORK);
1017             } else if (typeStringUpperCase == VCARD_PARAM_TYPE_CELL) {
1018                 type = VALUE_INDEX_FOUR;
1019             } else if (type < 0) {
1020                 label = (VCardUtils::StartWith(typeStringUpperCase, "X-")) ? typeStringOrg.substr(VALUE_INDEX_TWO)
1021                                                                            : typeStringOrg;
1022                 type = static_cast<int32_t>(EmailType::CUSTOM_LABEL);
1023             } else {
1024                 TELEPHONY_LOGI("No need to do anything");
1025             }
1026         }
1027     }
1028     if (type < 0) {
1029         type = static_cast<int32_t>(EmailType::EMAIL_OTHER);
1030     }
1031     std::map<std::string, std::vector<std::string>>::iterator itCharset = parasMap.find(VCARD_PARAM_CHARSET);
1032     std::map<std::string, std::vector<std::string>>::iterator itEncoding = parasMap.find(VCARD_PARAM_ENCODING);
1033     std::vector<std::string> valueList =
1034         VCardUtils::Split(((itCharset != parasMap.end() && itEncoding != parasMap.end()) ? propValue : rawValue), ";");
1035     std::string address = (valueList.size() != 0) ? valueList[0] : "";
1036     std::string displayname = (valueList.size() >= SIZE_TWO) ? valueList[1] : "";
1037     AddEmail(type, address, label, displayname, isPrimary);
1038 }
1039 
AddPostalDatas(std::string rawValue,std::string propValue,std::vector<std::string> values,std::map<std::string,std::vector<std::string>> parasMap)1040 void VCardContact::AddPostalDatas(std::string rawValue, std::string propValue, std::vector<std::string> values,
1041     std::map<std::string, std::vector<std::string>> parasMap)
1042 {
1043     bool valueIsAllEmpty = true;
1044     for (std::string value : values) {
1045         if (!value.empty()) {
1046             valueIsAllEmpty = false;
1047             break;
1048         }
1049     }
1050     if (valueIsAllEmpty) {
1051         return;
1052     }
1053     int32_t type = -1;
1054     std::string label = "";
1055     bool isPrimary = false;
1056     std::vector<std::string> typeCollection;
1057     std::map<std::string, std::vector<std::string>>::iterator it = parasMap.find(VCARD_PARAM_TYPE);
1058     if (it == parasMap.end()) {
1059         TELEPHONY_LOGI("Map does not contain this key, %{public}s, use OTHER type", VCARD_PARAM_TYPE);
1060         // contains no type info will fallback to OTHER type
1061     } else {
1062         typeCollection = it->second;
1063     }
1064     for (std::string typeStringOrg : typeCollection) {
1065         std::string typeStringUpperCase = VCardUtils::ToUpper(typeStringOrg);
1066         if (typeStringUpperCase == VCARD_PARAM_TYPE_PREF) {
1067             isPrimary = true;
1068         } else if (typeStringUpperCase == VCARD_PARAM_TYPE_HOME) {
1069             type = static_cast<int32_t>(PostalType::ADDR_HOME);
1070             label = "";
1071         } else if (typeStringUpperCase == VCARD_PARAM_TYPE_WORK ||
1072                    typeStringUpperCase == VCARD_PARAM_EXTRA_TYPE_COMPANY) {
1073             type = static_cast<int32_t>(PostalType::ADDR_WORK);
1074             label = "";
1075         } else if (typeStringUpperCase == VCARD_PARAM_ADR_TYPE_PARCEL ||
1076                    typeStringUpperCase == VCARD_PARAM_ADR_TYPE_DOM ||
1077                    typeStringUpperCase == VCARD_PARAM_ADR_TYPE_INTL) {
1078             // We do not have any appropriate way to store this information.
1079         } else if (type < 0) {
1080             type = static_cast<int32_t>(PostalType::CUSTOM_LABEL);
1081             label = (VCardUtils::StartWith(typeStringUpperCase, "X-")) ? typeStringOrg.substr(VALUE_INDEX_TWO)
1082                                                                        : typeStringOrg;
1083             if (VCardUtils::ToUpper(label) == VCARD_PARAM_ADR_EXTRA_TYPE_OTHER) {
1084                 type = static_cast<int32_t>(PostalType::ADDR_OTHER);
1085                 label = "";
1086             }
1087         } else {
1088             TELEPHONY_LOGI("No need to do anything");
1089         }
1090     }
1091     AddPostal(type < 0 ? static_cast<int32_t>(PostalType::ADDR_OTHER) : type, values, label, isPrimary);
1092 }
1093 
AddSoundDatas(std::string rawValue,std::string propValue,std::vector<std::string> values,std::map<std::string,std::vector<std::string>> parasMap)1094 void VCardContact::AddSoundDatas(std::string rawValue, std::string propValue, std::vector<std::string> values,
1095     std::map<std::string, std::vector<std::string>> parasMap)
1096 {
1097     std::vector<std::string> typeList;
1098     std::map<std::string, std::vector<std::string>>::iterator it = parasMap.find(VCARD_PARAM_TYPE);
1099     if (it == parasMap.end()) {
1100         TELEPHONY_LOGE("Map does not contain this key, %{public}s", VCARD_PARAM_TYPE);
1101         return;
1102     } else {
1103         typeList = it->second;
1104     }
1105     bool contains = false;
1106     if (std::find(typeList.begin(), typeList.end(), VCARD_PARAM_X_IRMC_N) != typeList.end()) {
1107         contains = true;
1108     }
1109     if (typeList.size() > 0 && contains) {
1110         std::vector<std::string> phoneticNameList = VCardUtils::ConstructListFromValue(propValue, vCardType_);
1111         HandlePhoneticNameFromSound(phoneticNameList);
1112     }
1113 }
1114 
AddPhotoDatas(std::string byte,std::string rawValue,std::string propValue,std::vector<std::string> values,std::map<std::string,std::vector<std::string>> parasMap)1115 void VCardContact::AddPhotoDatas(std::string byte, std::string rawValue, std::string propValue,
1116     std::vector<std::string> values, std::map<std::string, std::vector<std::string>> parasMap)
1117 {
1118     std::vector<std::string> typeList;
1119     std::map<std::string, std::vector<std::string>>::iterator it = parasMap.find(VCARD_PARAM_TYPE);
1120     if (it == parasMap.end()) {
1121         TELEPHONY_LOGE("Map does not contain this key, %{public}s", VCARD_PARAM_TYPE);
1122         return;
1123     } else {
1124         typeList = it->second;
1125     }
1126     std::string formatName;
1127     bool isPrimary = false;
1128     if (!typeList.empty()) {
1129         for (std::string typeValue : typeList) {
1130             if (typeValue == VCARD_PARAM_TYPE_PREF) {
1131                 isPrimary = true;
1132             } else if (formatName.empty()) {
1133                 formatName = typeValue;
1134             } else {
1135                 TELEPHONY_LOGI("No need to do anything");
1136             }
1137         }
1138     }
1139     AddPhotoBytes(formatName, byte, isPrimary);
1140 }
1141 
AddSkypePstnNumDatas(std::string propValue,std::map<std::string,std::vector<std::string>> parasMap)1142 void VCardContact::AddSkypePstnNumDatas(std::string propValue, std::map<std::string, std::vector<std::string>> parasMap)
1143 {
1144     std::vector<std::string> typeCollection;
1145     std::map<std::string, std::vector<std::string>>::iterator it = parasMap.find(VCARD_PARAM_TYPE);
1146     if (it == parasMap.end()) {
1147         TELEPHONY_LOGE("Map does not contain this key, %{public}s", VCARD_PARAM_TYPE);
1148         return;
1149     } else {
1150         typeCollection = it->second;
1151     }
1152     int32_t type = static_cast<int32_t>(PhoneVcType::NUM_OTHER);
1153     bool isPrimary = false;
1154     if (std::find(typeCollection.begin(), typeCollection.end(), VCARD_PARAM_TYPE_PREF) != typeCollection.end()) {
1155         isPrimary = true;
1156     }
1157     AddPhone(type, propValue, "", isPrimary);
1158 }
1159 
AddWebSiteDatas(std::string rawValue,std::string propValue,std::vector<std::string> values,std::map<std::string,std::vector<std::string>> parasMap)1160 void VCardContact::AddWebSiteDatas(std::string rawValue, std::string propValue, std::vector<std::string> values,
1161     std::map<std::string, std::vector<std::string>> parasMap)
1162 {
1163     std::shared_ptr<VCardWebsiteData> object = std::make_shared<VCardWebsiteData>();
1164     std::vector<std::string> valueList = VCardUtils::Split((parasMap.size() != 0) ? propValue : rawValue, ";");
1165     object->InitWebsite((valueList.size() > SIZE_ZERO) ? valueList[VALUE_INDEX_ZERO] : "");
1166     object->SetLabelId((valueList.size() > SIZE_ONE) ? valueList[VALUE_INDEX_ONE] : "");
1167     object->SetLabelName((valueList.size() > SIZE_TWO) ? valueList[VALUE_INDEX_TWO] : "");
1168     websites_.push_back(object);
1169 }
1170 
AddBirthdayDatas(std::string rawValue)1171 void VCardContact::AddBirthdayDatas(std::string rawValue)
1172 {
1173     std::shared_ptr<VCardBirthdayData> object = std::make_shared<VCardBirthdayData>();
1174     object->InitBirthdayData(rawValue);
1175     birthday_ = object;
1176 }
1177 
AddAnniversaryDatas(std::string propValue)1178 void VCardContact::AddAnniversaryDatas(std::string propValue)
1179 {
1180     std::shared_ptr<VCardAnniversaryData> object = std::make_shared<VCardAnniversaryData>();
1181     object->InitAnniversaryData(propValue);
1182     anniversary_ = object;
1183 }
1184 
AddImppDatas(std::string propValue,std::map<std::string,std::vector<std::string>> parasMap)1185 void VCardContact::AddImppDatas(std::string propValue, std::map<std::string, std::vector<std::string>> parasMap)
1186 {
1187     if (VCardUtils::StartWith(propValue, "sip:")) {
1188         std::vector<std::string> typeCollection;
1189         std::map<std::string, std::vector<std::string>>::iterator it = parasMap.find(VCARD_PARAM_TYPE);
1190         if (it == parasMap.end()) {
1191             TELEPHONY_LOGE("Map does not contain this key, %{public}s", VCARD_PARAM_TYPE);
1192             return;
1193         } else {
1194             typeCollection = it->second;
1195         }
1196         HandleSipCase(propValue, typeCollection);
1197     }
1198 }
1199 
AddGroups(std::string rawValue)1200 void VCardContact::AddGroups(std::string rawValue)
1201 {
1202     std::shared_ptr<VCardGroupData> object = std::make_shared<VCardGroupData>();
1203     object->SetGroupName(rawValue);
1204     int groupId = VCardRdbHelper::QueryGroupId(rawValue);
1205     if (groupId < 0) {
1206         TELEPHONY_LOGE("query group Id for %{public}s failed", rawValue.c_str());
1207         return;
1208     }
1209     object->SetGroupId(groupId);
1210     groups_.push_back(object);
1211 }
1212 
AddUID(std::string rawValue)1213 void VCardContact::AddUID(std::string rawValue)
1214 {
1215     std::shared_ptr<VCardUidData> object = std::make_shared<VCardUidData>();
1216     object->SetUid(rawValue);
1217     uid_ = object;
1218 }
1219 
GetUid()1220 std::string VCardContact::GetUid()
1221 {
1222     return (uid_ != nullptr) ? uid_->GetUid() : "";
1223 }
1224 
GetValueListFromParasMap(std::string rawValue,std::string propValue,std::map<std::string,std::vector<std::string>> parasMap)1225 std::vector<std::string> VCardContact::GetValueListFromParasMap(
1226     std::string rawValue, std::string propValue, std::map<std::string, std::vector<std::string>> parasMap)
1227 {
1228     return VCardUtils::Split(((parasMap.size() == 0) ? rawValue : propValue), ";");
1229 }
1230 
1231 struct RawNameInfo {
1232     std::string prefix;
1233     std::string given;
1234     std::string middle;
1235     std::string family;
1236     std::string suffix;
1237 };
1238 
1239 struct DisplayNameInfo {
1240     std::string prefix;
1241     std::string firstPart;
1242     std::string secondPart;
1243     std::string thirdPart;
1244     std::string suffix;
1245 };
1246 
1247 /**
1248 * Concatenates parts of a full name inserting spaces and commas as specified.
1249 *
1250 * @param isUseSpace true: use space; false: not use
1251 * @param isUseCommaAfterFirstPart true: use comma after first part name; false: not use
1252 * @param isUseCommaAfterThirdPart true: use comma after third part name; false: not use
1253 * @return concatenated full name
1254 */
ConcatenateDisplayName(const DisplayNameInfo & displayNameInfo,bool isUseSpace,bool isUseCommaAfterFirstPart,bool isUseCommaAfterThirdPart)1255 std::string ConcatenateDisplayName(const DisplayNameInfo &displayNameInfo, bool isUseSpace,
1256     bool isUseCommaAfterFirstPart, bool isUseCommaAfterThirdPart)
1257 {
1258     DisplayNameInfo tmpDisplayNameInfo = displayNameInfo;
1259     VCardUtils::Trim(tmpDisplayNameInfo.prefix);
1260     VCardUtils::Trim(tmpDisplayNameInfo.firstPart);
1261     VCardUtils::Trim(tmpDisplayNameInfo.secondPart);
1262     VCardUtils::Trim(tmpDisplayNameInfo.thirdPart);
1263     VCardUtils::Trim(tmpDisplayNameInfo.suffix);
1264 
1265     std::string displayName = "";
1266     if (!tmpDisplayNameInfo.prefix.empty()) {
1267         displayName += tmpDisplayNameInfo.prefix;
1268     }
1269 
1270     if (!tmpDisplayNameInfo.firstPart.empty()) {
1271         if (!displayName.empty()) {
1272             displayName += ' ';
1273         }
1274         displayName += tmpDisplayNameInfo.firstPart;
1275     }
1276 
1277     if (!tmpDisplayNameInfo.secondPart.empty()) {
1278         if (!displayName.empty()) {
1279             if (isUseCommaAfterFirstPart) {
1280                 displayName += ',';
1281             }
1282             if (isUseSpace) {
1283                 displayName += ' ';
1284             }
1285         }
1286         displayName += tmpDisplayNameInfo.secondPart;
1287     }
1288 
1289     if (!tmpDisplayNameInfo.thirdPart.empty()) {
1290         if (!displayName.empty()) {
1291             if (isUseSpace) {
1292                 displayName += ' ';
1293             }
1294         }
1295         displayName += tmpDisplayNameInfo.thirdPart;
1296     }
1297 
1298     if (!tmpDisplayNameInfo.suffix.empty()) {
1299         if (!displayName.empty()) {
1300             if (isUseCommaAfterThirdPart) {
1301                 displayName += ',';
1302             }
1303             if (isUseSpace) {
1304                 displayName += ' ';
1305             }
1306         }
1307         displayName += tmpDisplayNameInfo.suffix;
1308     }
1309 
1310     return displayName;
1311 }
1312 
GenerateDisplayName(const std::string & language,const RawNameInfo & rawNameInfo)1313 std::string GenerateDisplayName(const std::string &language, const RawNameInfo &rawNameInfo)
1314 {
1315     DisplayNameInfo displayNameInfo = {
1316         .prefix = rawNameInfo.prefix,
1317         .firstPart = rawNameInfo.family,
1318         .secondPart = rawNameInfo.middle,
1319         .thirdPart = rawNameInfo.given,
1320         .suffix = rawNameInfo.suffix,
1321     };
1322 
1323     // zh-Hant: traditional Chinese, zh-Hans: simplified Chinese, ko: Korean
1324     if (language == "zh-Hant" || language == "zh-Hans" || language == "ko") {
1325         return ConcatenateDisplayName(displayNameInfo, false, false, false);
1326     } else if (language == "ja") { // ja: Japanese
1327         return ConcatenateDisplayName(displayNameInfo, true, false, false);
1328     } else {
1329         displayNameInfo.firstPart = rawNameInfo.given;
1330         displayNameInfo.thirdPart = rawNameInfo.family;
1331         return ConcatenateDisplayName(displayNameInfo, true, false, true);
1332     }
1333 }
1334 
UpdateDisplayName()1335 void VCardContact::UpdateDisplayName()
1336 {
1337     if (nameData_ == nullptr) {
1338         return;
1339     }
1340 
1341     RawNameInfo rawNameInfo = {
1342         .prefix = nameData_->GetPrefix(),
1343         .given = nameData_->GetGiven(),
1344         .middle = nameData_->GetMiddle(),
1345         .family = nameData_->GetFamily(),
1346         .suffix = nameData_->GetSuffix(),
1347     };
1348     auto language = Global::I18n::LocaleConfig::GetSystemLanguage();
1349     std::string displayName = GenerateDisplayName(language, rawNameInfo);
1350     if (displayName.empty()) {
1351         return;
1352     }
1353     TELEPHONY_LOGI("do UpdateDisplayName, language: %{public}s", language.c_str());
1354     nameData_->setDispalyName(displayName);
1355 }
1356 
1357 } // namespace Telephony
1358 } // namespace OHOS
1359