* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "securec.h"
#include "contacts_utils.h"
using namespace OHOS;
using namespace OHOS::ContactsFfi;
using namespace OHOS::DataShare;
namespace OHOS {
namespace ContactsFfi {
bool allocBucket(ValuesBucket* b, size_t total, int32_t *errCode)
{
if (*errCode != SUCCESS) {
return false;
}
if (total > 0) {
b->size = total;
b->key = (char**) malloc(total * sizeof(char*));
if (b->key == nullptr) {
*errCode = ERROR;
b->freeContent();
return false;
}
b->value = (struct CValueType*) malloc(total * sizeof(struct CValueType));
if (b->value == nullptr) {
*errCode = ERROR;
b->freeContent();
return false;
} else {
b->value->tag = static_cast<int>(DataType::TYPE_NULL);
b->value->string = nullptr;
}
}
return true;
}
DataShareValuesBucket convertToDataShareVB(ValuesBucket vb)
{
uint64_t size = vb.size;
DataShareValuesBucket dsvb = DataShareValuesBucket();
for (uint64_t i = 0; i < size; i++) {
switch (vb.value[i].tag) {
case DataShareValueObjectType::TYPE_STRING: {
DataShareValueObject valueObject = DataShareValueObject(std::string(vb.value[i].string));
std::string keyStr = vb.key[i];
dsvb.Put(keyStr, valueObject);
break;
}
case DataShareValueObjectType::TYPE_INT: {
DataShareValueObject valueObject = DataShareValueObject(vb.value[i].integer);
std::string keyStr = vb.key[i];
dsvb.Put(keyStr, valueObject);
break;
}
default: {
std::string keyStr = vb.key[i];
HILOG_ERROR("VB unsupported value type is %{public}d for key = %{public}s",
vb.value[i].tag, keyStr.c_str());
dsvb.Put(vb.key[i], DataShareValueObject());
break;
}
}
}
return dsvb;
}
void PutQuickSearchKey(std::shared_ptr<DataShareResultSet> &resultSet,
std::map<int, std::string> &quickSearchMap, int contactIdValue)
{
std::string quickSearchValue = "";
std::string quickSearchKey = "quick_search_key";
int columnIndex = 0;
resultSet->GetColumnIndex(quickSearchKey, columnIndex);
resultSet->GetString(columnIndex, quickSearchValue);
if (quickSearchMap.count(contactIdValue) <= 0) {
quickSearchMap.insert(std::pair<int, std::string>(contactIdValue, quickSearchValue));
}
}
std::vector<ValuesBucket>& GetResultMapValue(std::map<int, std::vector<ValuesBucket>> &resultSetMap, int contactId)
{
std::map<int, std::vector<ValuesBucket>>::iterator it = resultSetMap.find(contactId);
if (it == resultSetMap.end()) {
std::vector<ValuesBucket> contactData = std::vector<ValuesBucket>();
resultSetMap.insert(std::pair<int, std::vector<ValuesBucket>>(contactId, contactData));
it = resultSetMap.find(contactId);
}
return it->second;
}
void copyBucket(ValuesBucket* dst, int dstIdx, ValuesBucket &src)
{
dst[dstIdx].key = src.key;
dst[dstIdx].value = src.value;
dst[dstIdx].size = src.size;
}
char* TransformFromString(std::string &str, int32_t* errCode)
{
size_t len = str.size() + 1;
char* retValue = static_cast<char *>(malloc(len));
if (retValue == nullptr) {
*errCode = ERROR;
return nullptr;
}
*errCode = memcpy_s(retValue, len, str.c_str(), len);
if (*errCode != SUCCESS) {
free(retValue);
retValue = nullptr;
}
return retValue;
}
ValuesBucket allocBucketData(std::vector<KeyWithValueType> &bucketData, int32_t *errCode)
{
struct ValuesBucket b;
size_t total = bucketData.size();
if (total > 0) {
if (!allocBucket(&b, total, errCode)) {
return b;
}
b.size = 0;
for (size_t i = 0; i < total; i++) {
bucketData[i].allocToBucket(&b, 0, i, errCode);
if (*errCode != SUCCESS) {
b.freeContent();
return b;
} else {
b.size = b.size + 1;
}
}
}
return b;
}
ValuesBucket singleStringAsValueBucket(std::string contentType, std::string value, int32_t *errCode)
{
std::vector<KeyWithValueType> bucketData;
bucketData.push_back(KeyWithValueType("content_type", contentType));
bucketData.push_back(KeyWithValueType("detail_info", value));
return allocBucketData(bucketData, errCode);
}
void PutResultValue(std::vector<KeyWithValueType> &bucket, std::string contentStoreKey,
std::shared_ptr<DataShareResultSet> &resultSet, std::string contentLoadKey)
{
int columnIndex = 0;
resultSet->GetColumnIndex(contentLoadKey, columnIndex);
DataType columnType;
resultSet->GetDataType(columnIndex, columnType);
if (columnType == DataType::TYPE_STRING) {
std::string stringValue;
resultSet->GetString(columnIndex, stringValue);
bucket.push_back(KeyWithValueType(contentStoreKey, stringValue));
} else if (columnType == DataType::TYPE_INTEGER) {
int intValue = 0;
resultSet->GetInt(columnIndex, intValue);
bucket.push_back(KeyWithValueType(contentStoreKey, (int64_t) intValue));
} else if (columnType == DataType::TYPE_FLOAT) {
double doubleValue = 0;
resultSet->GetDouble(columnIndex, doubleValue);
bucket.push_back(KeyWithValueType(contentStoreKey, doubleValue));
} else if (columnType != DataType::TYPE_NULL) {
HILOG_ERROR("PutResultValue unsupported columnType for key %{public}s is %{public}d",
contentLoadKey.c_str(), columnType);
}
}
void PutResultValue(std::vector<KeyWithValueType> &bucket,
std::shared_ptr<DataShareResultSet> &resultSet, std::string contentKey)
{
PutResultValue(bucket, contentKey, resultSet, contentKey);
}
* @brief Converting resultset of a query to Email data ValuesBucket
*/
ValuesBucket resultSetAsEmail(std::shared_ptr<DataShareResultSet> &resultSet, int32_t *errCode)
{
std::vector<KeyWithValueType> bucketData;
bucketData.push_back(KeyWithValueType("content_type", "email"));
PutResultValue(bucketData, resultSet, "detail_info");
PutResultValue(bucketData, resultSet, "alias_detail_info");
PutResultValue(bucketData, resultSet, "custom_data");
PutResultValue(bucketData, resultSet, "extend7");
return allocBucketData(bucketData, errCode);
}
* @brief Converting resultset of a query to Name data ValuesBucket
*/
ValuesBucket resultSetAsName(std::shared_ptr<DataShareResultSet> &resultSet, int32_t *errCode)
{
std::vector<KeyWithValueType> bucketData;
bucketData.push_back(KeyWithValueType("content_type", "name"));
PutResultValue(bucketData, resultSet, "detail_info");
PutResultValue(bucketData, resultSet, "alpha_name");
PutResultValue(bucketData, resultSet, "other_lan_last_name");
PutResultValue(bucketData, resultSet, "other_lan_first_name");
PutResultValue(bucketData, resultSet, "family_name");
PutResultValue(bucketData, resultSet, "middle_name_phonetic");
PutResultValue(bucketData, resultSet, "given_name");
PutResultValue(bucketData, resultSet, "given_name_phonetic");
PutResultValue(bucketData, resultSet, "phonetic_name");
return allocBucketData(bucketData, errCode);
}
* @brief Converting resultset of a query to Portrait data ValuesBucket
*/
ValuesBucket resultSetAsPortrait(std::shared_ptr<DataShareResultSet> &resultSet, int32_t *errCode)
{
std::vector<KeyWithValueType> bucketData;
bucketData.push_back(KeyWithValueType("content_type", "photo"));
PutResultValue(bucketData, resultSet, "detail_info");
return allocBucketData(bucketData, errCode);
}
* @brief Converting resultset of a query to Event data ValuesBucket
*/
ValuesBucket resultSetAsEvent(std::shared_ptr<DataShareResultSet> &resultSet, int32_t *errCode)
{
std::vector<KeyWithValueType> bucketData;
bucketData.push_back(KeyWithValueType("content_type", "contact_event"));
PutResultValue(bucketData, resultSet, "detail_info");
PutResultValue(bucketData, resultSet, "custom_data");
PutResultValue(bucketData, resultSet, "extend7");
return allocBucketData(bucketData, errCode);
}
* @brief Converting resultset of a query to Group data ValuesBucket
*/
ValuesBucket resultSetAsGroup(std::shared_ptr<DataShareResultSet> &resultSet, int32_t *errCode)
{
std::vector<KeyWithValueType> bucketData;
bucketData.push_back(KeyWithValueType("content_type", "group_membership"));
PutResultValue(bucketData, resultSet, "detail_info");
PutResultValue(bucketData, resultSet, "group_name");
return allocBucketData(bucketData, errCode);
}
* @brief Converting resultset of a query to ImAddress data ValuesBucket
*/
ValuesBucket resultSetAsImAddress(std::shared_ptr<DataShareResultSet> &resultSet, int32_t *errCode)
{
std::vector<KeyWithValueType> bucketData;
bucketData.push_back(KeyWithValueType("content_type", "im"));
PutResultValue(bucketData, resultSet, "detail_info");
PutResultValue(bucketData, resultSet, "custom_data");
PutResultValue(bucketData, resultSet, "extend7");
return allocBucketData(bucketData, errCode);
}
* @brief Converting resultset of a query to PhoneNumber data ValuesBucket
*/
ValuesBucket resultSetAsPhone(std::shared_ptr<DataShareResultSet> &resultSet, int32_t *errCode)
{
std::vector<KeyWithValueType> bucketData;
bucketData.push_back(KeyWithValueType("content_type", "phone"));
PutResultValue(bucketData, resultSet, "detail_info");
PutResultValue(bucketData, resultSet, "custom_data");
PutResultValue(bucketData, resultSet, "extend7");
return allocBucketData(bucketData, errCode);
}
* @brief Converting resultset of a query to PostalAddress data ValuesBucket
*/
ValuesBucket resultSetAsPostAddress(std::shared_ptr<DataShareResultSet> &resultSet, int32_t *errCode)
{
std::vector<KeyWithValueType> bucketData;
bucketData.push_back(KeyWithValueType("content_type", "postal_address"));
PutResultValue(bucketData, resultSet, "detail_info");
PutResultValue(bucketData, resultSet, "neighborhood");
PutResultValue(bucketData, resultSet, "pobox");
PutResultValue(bucketData, resultSet, "postcode");
PutResultValue(bucketData, resultSet, "region");
PutResultValue(bucketData, resultSet, "street");
PutResultValue(bucketData, resultSet, "city");
PutResultValue(bucketData, resultSet, "country");
PutResultValue(bucketData, resultSet, "custom_data");
PutResultValue(bucketData, resultSet, "extend7");
return allocBucketData(bucketData, errCode);
}
* @brief Converting resultset of a query to Relation data ValuesBucket
*/
ValuesBucket resultSetAsRelation(std::shared_ptr<DataShareResultSet> &resultSet, int32_t *errCode)
{
std::vector<KeyWithValueType> bucketData;
bucketData.push_back(KeyWithValueType("content_type", "relation"));
PutResultValue(bucketData, resultSet, "detail_info");
PutResultValue(bucketData, resultSet, "custom_data");
PutResultValue(bucketData, resultSet, "extend7");
return allocBucketData(bucketData, errCode);
}
* @brief Converting resultset of a query to SipAddress data ValuesBucket
*/
ValuesBucket resultSetAsSipAddress(std::shared_ptr<DataShareResultSet> &resultSet, int32_t *errCode)
{
std::vector<KeyWithValueType> bucketData;
bucketData.push_back(KeyWithValueType("content_type", "sip_address"));
PutResultValue(bucketData, resultSet, "detail_info");
PutResultValue(bucketData, resultSet, "custom_data");
PutResultValue(bucketData, resultSet, "extend7");
return allocBucketData(bucketData, errCode);
}
* @brief Converting resultset of a query to Website data ValuesBucket
*/
ValuesBucket resultSetAsWebsite(std::shared_ptr<DataShareResultSet> &resultSet, int32_t *errCode)
{
std::vector<KeyWithValueType> bucketData;
bucketData.push_back(KeyWithValueType("content_type", "website"));
PutResultValue(bucketData, resultSet, "detail_info");
return allocBucketData(bucketData, errCode);
}
* @brief Converting resultset of a query to Nickname data ValuesBucket
*/
ValuesBucket resultSetAsNickname(std::shared_ptr<DataShareResultSet> &resultSet, int32_t *errCode)
{
std::vector<KeyWithValueType> bucketData;
bucketData.push_back(KeyWithValueType("content_type", "nickname"));
PutResultValue(bucketData, resultSet, "detail_info");
return allocBucketData(bucketData, errCode);
}
* @brief Converting resultset of a query to Note data ValuesBucket
*/
ValuesBucket resultSetAsNote(std::shared_ptr<DataShareResultSet> &resultSet, int32_t *errCode)
{
std::vector<KeyWithValueType> bucketData;
bucketData.push_back(KeyWithValueType("content_type", "note"));
PutResultValue(bucketData, resultSet, "detail_info");
return allocBucketData(bucketData, errCode);
}
* @brief Converting resultset of a query to Organization data ValuesBucket
*/
ValuesBucket resultSetAsOrganization(std::shared_ptr<DataShareResultSet> &resultSet, int32_t *errCode)
{
std::vector<KeyWithValueType> bucketData;
bucketData.push_back(KeyWithValueType("content_type", "organization"));
PutResultValue(bucketData, resultSet, "detail_info");
PutResultValue(bucketData, resultSet, "position");
return allocBucketData(bucketData, errCode);
}
* @brief Converting resultset of a query to one of contact's ValuesBucket
*/
void addResultSetAsValuesBucket(std::vector<ValuesBucket> &contactData,
std::shared_ptr<DataShareResultSet> &resultSet, int32_t *errCode)
{
int typeIdValue = 0;
std::string typeId = "type_id";
int columnIndexType = 0;
resultSet->GetColumnIndex(typeId, columnIndexType);
resultSet->GetInt(columnIndexType, typeIdValue);
switch (typeIdValue) {
case EMAIL: contactData.push_back(resultSetAsEmail(resultSet, errCode)); return;
case NAME: contactData.push_back(resultSetAsName(resultSet, errCode)); return;
case PHOTO: contactData.push_back(resultSetAsPortrait(resultSet, errCode)); return;
case CONTACT_EVENT: contactData.push_back(resultSetAsEvent(resultSet, errCode)); return;
case GROUP_MEMBERSHIP: contactData.push_back(resultSetAsGroup(resultSet, errCode)); return;
case IM: contactData.push_back(resultSetAsImAddress(resultSet, errCode)); return;
case PHONE: contactData.push_back(resultSetAsPhone(resultSet, errCode)); return;
case POSTAL_ADDRESS: contactData.push_back(resultSetAsPostAddress(resultSet, errCode)); return;
case RELATION: contactData.push_back(resultSetAsRelation(resultSet, errCode)); return;
case SIP_ADDRESS: contactData.push_back(resultSetAsSipAddress(resultSet, errCode)); return;
case WEBSITE: contactData.push_back(resultSetAsWebsite(resultSet, errCode)); return;
case NICKNAME: contactData.push_back(resultSetAsNickname(resultSet, errCode)); return;
case NOTE: contactData.push_back(resultSetAsNote(resultSet, errCode)); return;
case ORGANIZATION: contactData.push_back(resultSetAsOrganization(resultSet, errCode)); return;
default: return;
}
}
bool allocateDataForContact(ContactsData* allContacts, int contactIndex, ContactInfo contactInfo, int32_t *errCode)
{
int bucketIndex = 0;
ValuesBucket idBucket = singleStringAsValueBucket("id", std::to_string(contactInfo.contactId), errCode);
if (*errCode != SUCCESS) {
free(allContacts->contactsData[contactIndex].data);
allContacts->contactsData[contactIndex].bucketCount = 0;
allContacts->contactsData[contactIndex].data = nullptr;
return false;
}
ValuesBucket searchKeyBucket = singleStringAsValueBucket("key", contactInfo.searchKey, errCode);
if (*errCode != SUCCESS) {
idBucket.freeContent();
free(allContacts->contactsData[contactIndex].data);
allContacts->contactsData[contactIndex].bucketCount = 0;
allContacts->contactsData[contactIndex].data = nullptr;
return false;
}
copyBucket(allContacts->contactsData[contactIndex].data, bucketIndex, idBucket);
bucketIndex++;
copyBucket(allContacts->contactsData[contactIndex].data, bucketIndex, searchKeyBucket);
bucketIndex++;
for (std::vector<ValuesBucket>::size_type i = 0; i < contactInfo.contactDataVector.size(); i++, bucketIndex++) {
copyBucket(allContacts->contactsData[contactIndex].data, bucketIndex, contactInfo.contactDataVector[i]);
}
return true;
}
void releaseRresultSetMapBuckets(std::map<int, std::vector<ValuesBucket>> resultSetMap)
{
std::map<int, std::vector<ValuesBucket>>::iterator it;
for (it = resultSetMap.begin(); it != resultSetMap.end(); it++) {
std::vector<ValuesBucket> contactDataVector = it->second;
for (std::vector<ValuesBucket>::size_type i = 0; i < contactDataVector.size(); i++) {
ValuesBucket bucket = contactDataVector[i];
bucket.freeContent();
}
}
}
ContactsData* allocContactsDataHeader(size_t totalContacts, int32_t *errCode)
{
ContactsData* allContacts = (struct ContactsData*) malloc(sizeof(struct ContactsData));
if (allContacts == nullptr) {
HILOG_ERROR("ContactUtils::allocCollectedContacts fail to mem alloc");
*errCode = ERROR;
return nullptr;
}
if (totalContacts == 0 || totalContacts > MAX_CONTACTS) {
free(allContacts);
return nullptr;
}
allContacts->contactsData = (ContactData*) malloc(totalContacts * sizeof(ContactData));
if (allContacts->contactsData == nullptr) {
free(allContacts);
HILOG_ERROR("ContactUtils::allocCollectedContacts fail to mem alloc");
*errCode = ERROR;
return nullptr;
}
allContacts->contactsCount = totalContacts;
return allContacts;
}
void allocSingleContact(ContactsData* allContacts, int contactIndex,
std::pair<const int, std::vector<ValuesBucket>> &entry,
std::map<int, std::string> &quickSearchMap, int32_t *errCode)
{
if (*errCode != SUCCESS) {
allContacts->contactsData[contactIndex].bucketCount = 0;
allContacts->contactsData[contactIndex].data = nullptr;
return;
}
int contactId = entry.first;
std::vector<ValuesBucket> contactDataVector = entry.second;
auto searchIt = quickSearchMap.find(contactId);
if (searchIt == quickSearchMap.end()) {
HILOG_ERROR("ContactUtils::allocSingleContact quickSearchKey not found for contactId %{public}d", contactId);
*errCode = ERROR;
allContacts->contactsData[contactIndex].bucketCount = 0;
allContacts->contactsData[contactIndex].data = nullptr;
return;
}
std::string searchKey = searchIt->second;
size_t totalBuckets = 2 + contactDataVector.size();
allContacts->contactsData[contactIndex].bucketCount = totalBuckets;
allContacts->contactsData[contactIndex].data =
(struct ValuesBucket*) malloc(totalBuckets * sizeof(struct ValuesBucket));
if (allContacts->contactsData[contactIndex].data == nullptr) {
*errCode = ERROR;
return;
}
ContactInfo contactInfo;
contactInfo.contactId = contactId;
contactInfo.searchKey = searchKey;
contactInfo.contactDataVector = contactDataVector;
allocateDataForContact(allContacts, contactIndex, contactInfo, errCode);
}
ContactsData* allocCollectedContacts(std::map<int, std::vector<ValuesBucket>> &resultSetMap,
std::map<int, std::string> &quickSearchMap, int32_t *errCode)
{
ContactsData* allContacts = allocContactsDataHeader(resultSetMap.size(), errCode);
if (allContacts == nullptr) {
return nullptr;
}
int contactIndex = 0;
for (auto it = resultSetMap.begin(); it != resultSetMap.end(); it++, contactIndex++) {
allocSingleContact(allContacts, contactIndex, *it, quickSearchMap, errCode);
}
if (*errCode == SUCCESS) {
return allContacts;
}
allContacts->freeContent();
free(allContacts);
releaseRresultSetMapBuckets(resultSetMap);
return nullptr;
}
ContactsData* parseResultSetForContacts(std::shared_ptr<DataShareResultSet> &resultSet, int32_t *errCode)
{
if (resultSet == nullptr) {
HILOG_ERROR("ContactUtils::parseResultSetForContacts resultSet is nullptr");
return nullptr;
}
int rowCount = 0;
resultSet->GetRowCount(rowCount);
HILOG_INFO("parseResultSetForContacts GetRowCount is %{public}d", rowCount);
if (rowCount == 0) {
resultSet->Close();
return nullptr;
}
std::map<int, std::vector<ValuesBucket>> resultSetMap;
std::map<int, std::string> quickSearchMap;
int resultSetNum = resultSet->GoToFirstRow();
while (resultSetNum == 0) {
int contactIdValue = 0;
std::string contactIdKey = "contact_id";
int contactIndex = 0;
resultSet->GetColumnIndex(contactIdKey, contactIndex);
resultSet->GetInt(contactIndex, contactIdValue);
std::vector<ValuesBucket>& contactData = GetResultMapValue(resultSetMap, contactIdValue);
PutQuickSearchKey(resultSet, quickSearchMap, contactIdValue);
addResultSetAsValuesBucket(contactData, resultSet, errCode);
if (*errCode != SUCCESS) {
HILOG_ERROR("ContactUtils::parseResultSetForContacts fail to mem alloc");
break;
}
resultSetNum = resultSet->GoToNextRow();
}
resultSet->Close();
if (*errCode != SUCCESS) {
std::map<int, std::vector<ValuesBucket>>::iterator it;
for (it = resultSetMap.begin(); it != resultSetMap.end(); it++) {
std::vector<ValuesBucket> contactDataVector = it->second;
for (std::vector<ValuesBucket>::size_type i = 0; i < contactDataVector.size(); i++) {
ValuesBucket bucket = contactDataVector[i];
bucket.freeContent();
}
}
return nullptr;
}
return allocCollectedContacts(resultSetMap, quickSearchMap, errCode);
}
* @brief Converting resultset of a query to Group data ValuesBucket
*/
void resultSetAsGroup(ValuesBucket* groups, int idx, std::shared_ptr<DataShareResultSet> &resultSet, int32_t *errCode)
{
std::vector<KeyWithValueType> bucketData;
PutResultValue(bucketData, "detail_info", resultSet, "id");
PutResultValue(bucketData, "group_name", resultSet, "group_name");
ValuesBucket bucket = allocBucketData(bucketData, errCode);
if (*errCode != SUCCESS) {
HILOG_ERROR("ContactUtils::resultSetAsGroup fail to mem alloc");
} else {
copyBucket(groups, idx, bucket);
}
}
* @brief Converting resultset of a query to Holder data ValuesBucket
*/
void resultSetAsHolder(ValuesBucket* holders, int idx, std::shared_ptr<DataShareResultSet> &resultSet,
int32_t *errCode)
{
std::vector<KeyWithValueType> bucketData;
PutResultValue(bucketData, "detail_info", resultSet, "account_name");
PutResultValue(bucketData, "custom_data", resultSet, "account_type");
PutResultValue(bucketData, "extend7", resultSet, "id");
ValuesBucket bucket = allocBucketData(bucketData, errCode);
if (*errCode != SUCCESS) {
HILOG_ERROR("ContactUtils::resultSetAsHolder fail to mem alloc");
} else {
copyBucket(holders, idx, bucket);
}
}
GroupsData* parseResultSetForGroups(std::shared_ptr<DataShareResultSet> &resultSet, int32_t *errCode)
{
if (resultSet == nullptr) {
HILOG_ERROR("ContactUtils::parseResultSetForGroups resultSet is nullptr");
return nullptr;
}
int totalGroups = 0;
resultSet->GetRowCount(totalGroups);
HILOG_INFO("parseResultSetForGroups GetRowCount is %{public}d", totalGroups);
if (totalGroups <= 0) {
return nullptr;
}
GroupsData* allGroups = (GroupsData*) malloc(sizeof(GroupsData));
if (allGroups == nullptr) {
HILOG_ERROR("ContactUtils::parseResultSetForGroups fail to mem alloc");
*errCode = ERROR;
return nullptr;
}
allGroups->data = (struct ValuesBucket*) malloc(totalGroups * sizeof(struct ValuesBucket));
if (allGroups->data == nullptr) {
free(allGroups);
HILOG_ERROR("ContactUtils::parseResultSetForGroups fail to mem alloc");
*errCode = ERROR;
return NULL;
}
allGroups->bucketCount = static_cast<uint64_t>(totalGroups);
int resultSetNum = resultSet->GoToFirstRow();
int count = 0;
while (resultSetNum == 0) {
resultSetAsGroup(allGroups->data, count, resultSet, errCode);
if (*errCode != SUCCESS) {
break;
}
resultSetNum = resultSet->GoToNextRow();
count++;
}
resultSet->Close();
if (*errCode != SUCCESS) {
allGroups->freeContent();
free(allGroups);
allGroups = nullptr;
}
return allGroups;
}
HoldersData* parseResultSetForHolders(std::shared_ptr<DataShareResultSet> &resultSet, int32_t *errCode)
{
if (resultSet == nullptr) {
HILOG_ERROR("ContactUtils::parseResultSetForHolders resultSet is nullptr");
return nullptr;
}
int totalHolders = 0;
resultSet->GetRowCount(totalHolders);
HILOG_INFO("parseResultSetForHolders GetRowCount is %{public}d", totalHolders);
if (totalHolders <= 0) {
return nullptr;
}
HoldersData* allHolders = (HoldersData*) malloc(sizeof(HoldersData));
if (allHolders == nullptr) {
HILOG_ERROR("ContactUtils::parseResultSetForHolders fail to mem alloc");
*errCode = ERROR;
return nullptr;
}
allHolders->data = (struct ValuesBucket*) malloc(totalHolders * sizeof(struct ValuesBucket));
if (allHolders->data == nullptr) {
free(allHolders);
HILOG_ERROR("ContactUtils::parseResultSetForHolders fail to mem alloc");
*errCode = ERROR;
return nullptr;
}
allHolders->bucketCount = static_cast<uint64_t>(totalHolders);
int resultSetNum = resultSet->GoToFirstRow();
int count = 0;
while (resultSetNum == 0) {
resultSetAsHolder(allHolders->data, count, resultSet, errCode);
if (*errCode != SUCCESS) {
break;
}
resultSetNum = resultSet->GoToNextRow();
count++;
}
resultSet->Close();
if (*errCode != SUCCESS) {
allHolders->freeContent();
free(allHolders);
allHolders = nullptr;
}
return allHolders;
}
}
}