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 #ifndef CONTACTS_UTILS_H 17 #define CONTACTS_UTILS_H 18 19 #include <cstdint> 20 #include "errors.h" 21 22 #include "hilog_wrapper_api.h" 23 #include "data_share_predicates_utils.h" 24 #include "datashare_result_set.h" 25 #include "datashare_values_bucket.h" 26 27 namespace OHOS { 28 namespace ContactsFfi { 29 30 constexpr int MAX_CONTACTS = 1024 * 1024; 31 32 const std::string CONTACTS_DATA_URI = "datashare:///com.ohos.contactsdataability"; 33 34 // contactsData type 35 constexpr int EMAIL = 1; 36 constexpr int IM = 2; 37 constexpr int NICKNAME = 3; 38 constexpr int ORGANIZATION = 4; 39 constexpr int PHONE = 5; 40 constexpr int NAME = 6; 41 constexpr int POSTAL_ADDRESS = 7; 42 constexpr int PHOTO = 8; 43 constexpr int GROUP_MEMBERSHIP = 9; 44 constexpr int NOTE = 10; 45 constexpr int CONTACT_EVENT = 11; 46 constexpr int WEBSITE = 12; 47 constexpr int RELATION = 13; 48 constexpr int CONTACT_MISC = 14; 49 constexpr int HICALL_DEVICE = 15; 50 constexpr int CAMCARD = 16; 51 constexpr int SIP_ADDRESS = 17; 52 53 constexpr int ERROR = -1; 54 constexpr int SUCCESS = 0; 55 56 constexpr int PERMISSION_ERROR = 201; 57 constexpr int PARAMETER_ERROR = 401; 58 59 struct ValuesBucket { 60 char** key = nullptr; 61 DataShare::CValueType* value = nullptr; 62 uint64_t size = 0; 63 freeContentValuesBucket64 void freeContent() 65 { 66 bool hasKey = key != nullptr; 67 bool hasValue = value != nullptr; 68 for (uint64_t i = 0; i < size; i++) { 69 if (hasKey) { 70 free(key[i]); 71 key[i] = nullptr; 72 } 73 if (hasValue && 74 value[i].tag == OHOS::DataShare::DataShareValueObjectType::TYPE_STRING) { 75 free(value[i].string); 76 value[i].string = nullptr; 77 } 78 } 79 80 free(key); 81 key = nullptr; 82 83 free(value); 84 value = nullptr; 85 86 size = 0; 87 } 88 }; 89 90 using RawContact = ValuesBucket; 91 92 struct Buckets { 93 ValuesBucket* data = nullptr; 94 uint64_t bucketCount = 0; 95 freeContentBuckets96 void freeContent() 97 { 98 if (data != nullptr) { 99 for (uint64_t b = 0; b < bucketCount; b++) { 100 ValuesBucket bucket = data[b]; 101 bucket.freeContent(); 102 } 103 free(data); 104 data = nullptr; 105 bucketCount = 0; 106 } 107 } 108 }; 109 using ContactData = Buckets; 110 using GroupsData = Buckets; 111 using HoldersData = Buckets; 112 113 114 struct ContactsData { 115 ContactData* contactsData = nullptr; 116 uint64_t contactsCount = 0; 117 freeContentContactsData118 void freeContent() 119 { 120 if (contactsData != nullptr) { 121 for (uint64_t i = 0; i < contactsCount; i++) { 122 ContactData contactData = contactsData[i]; 123 contactData.freeContent(); 124 } 125 free(contactsData); 126 contactsData = nullptr; 127 contactsCount = 0; 128 } 129 } 130 }; 131 132 char* TransformFromString(std::string &str, int32_t* errCode); 133 134 // this is a pair of key and a kind of DataShare::CValueType but with std::string string 135 struct KeyWithValueType { 136 std::string key; 137 int64_t integer = 0; 138 double dou = 0.0; 139 std::string string; 140 uint8_t tag = static_cast<int>(DataShare::DataType::TYPE_NULL); 141 KeyWithValueTypeKeyWithValueType142 KeyWithValueType(std::string k, int64_t v) 143 { 144 this->key = k; 145 this->integer = v; 146 this->tag = static_cast<int>(DataShare::DataType::TYPE_INTEGER); 147 } 148 KeyWithValueTypeKeyWithValueType149 KeyWithValueType(std::string k, double v) 150 { 151 this->key = k; 152 this->dou = v; 153 this->tag = static_cast<int>(DataShare::DataType::TYPE_FLOAT); 154 } 155 KeyWithValueTypeKeyWithValueType156 KeyWithValueType(std::string k, std::string v) 157 { 158 this->key = k; 159 this->string = v; 160 this->tag = static_cast<int>(DataShare::DataType::TYPE_STRING); 161 } 162 allocToBucketKeyWithValueType163 int32_t allocToBucket(ValuesBucket* dst, int dstIdx, int idx, int32_t *errCode) 164 { 165 dst[dstIdx].key[idx] = TransformFromString(this->key, errCode); 166 if (*errCode != SUCCESS) { 167 return *errCode; 168 } 169 dst[dstIdx].value[idx].tag = this->tag; 170 if (this->tag == static_cast<int>(DataShare::DataType::TYPE_INTEGER)) { 171 dst[dstIdx].value[idx].integer = this->integer; 172 } else if (this->tag == static_cast<int>(DataShare::DataType::TYPE_FLOAT)) { 173 dst[dstIdx].value[idx].dou = this->dou; 174 } else { 175 std::string str = ""; 176 if (this->tag == static_cast<int>(DataShare::DataType::TYPE_STRING)) { 177 str = this->string; 178 } else { // put empty string for unsupported tag 179 HILOG_ERROR("allocToBucket: for key %{public}s has tag %{public}d", this->key.c_str(), this->tag); 180 } 181 dst[dstIdx].value[idx].string = TransformFromString(str, errCode); 182 if (*errCode != SUCCESS) { 183 free(dst[dstIdx].key[idx]); 184 return *errCode; 185 } 186 } 187 return SUCCESS; 188 } 189 }; 190 191 OHOS::DataShare::DataShareValuesBucket convertToDataShareVB(OHOS::ContactsFfi::ValuesBucket vb); 192 193 ContactsData* parseResultSetForContacts(std::shared_ptr<OHOS::DataShare::DataShareResultSet> &resultSet, 194 int32_t *errCode); 195 196 GroupsData* parseResultSetForGroups(std::shared_ptr<OHOS::DataShare::DataShareResultSet> &resultSet, int32_t *errCode); 197 198 HoldersData* parseResultSetForHolders(std::shared_ptr<OHOS::DataShare::DataShareResultSet> &resultSet, 199 int32_t *errCode); 200 201 } // namespace ContactsFfi 202 } // namespace OHOS 203 204 #endif // CONTACTS_UTILS_H 205