• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #define LOG_TAG "Udmf"
16 #include "udmf.h"
17 #include "udmf_err_code.h"
18 #include "data_provider_impl.h"
19 #include "udmf_client.h"
20 #include "securec.h"
21 #include "udmf_capi_common.h"
22 #include "int_wrapper.h"
23 #include "string_wrapper.h"
24 #include "unified_meta.h"
25 #include "udmf_meta.h"
26 #include "logger.h"
27 #include "plain_text.h"
28 #include "link.h"
29 #include "html.h"
30 #include "system_defined_appitem.h"
31 #include "application_defined_record.h"
32 #include "system_defined_pixelmap.h"
33 #include "file.h"
34 #include "audio.h"
35 #include "folder.h"
36 #include "image.h"
37 #include "video.h"
38 
39 using namespace OHOS::UDMF;
40 
41 static constexpr uint64_t MAX_RECORDS_COUNT = 4 * 1024 * 1024;
42 static constexpr uint64_t MAX_KEY_STRING_LEN = 1 * 1024 * 1024;
43 static const std::map<std::string, UDType> FILE_TYPES = {
44     { UDMF_META_GENERAL_FILE, UDType::FILE },
45     { UDMF_META_AUDIO, UDType::AUDIO },
46     { UDMF_META_FOLDER, UDType::FOLDER },
47     { UDMF_META_IMAGE, UDType::IMAGE },
48     { UDMF_META_VIDEO, UDType::VIDEO }
49 };
50 
DestroyStringArray(char ** & bufArray,unsigned int & count)51 static void DestroyStringArray(char**& bufArray, unsigned int& count)
52 {
53     if (bufArray == nullptr) {
54         return;
55     }
56     for (unsigned int i = 0; i < count; i++) {
57         if (bufArray[i] != nullptr) {
58             delete[] bufArray[i];
59             bufArray[i] = nullptr;
60         }
61     }
62     delete[] bufArray;
63     bufArray = nullptr;
64     count = 0;
65 }
66 
DestroyUnifiedRecordArray(OH_UdmfRecord ** & records,unsigned int & count)67 static void DestroyUnifiedRecordArray(OH_UdmfRecord**& records, unsigned int& count)
68 {
69     if (records == nullptr) {
70         return;
71     }
72     for (unsigned int i = 0; i < count; i++) {
73         if (records[i] != nullptr) {
74             delete records[i];
75             records[i] = nullptr;
76         }
77     }
78     delete[] records;
79     records = nullptr;
80     count = 0;
81 }
82 
StrVectorToTypesArray(const std::vector<std::string> & strVector)83 static char** StrVectorToTypesArray(const std::vector<std::string>& strVector)
84 {
85     unsigned int vectorSize = strVector.size();
86     if (vectorSize == 0 || vectorSize > MAX_RECORDS_COUNT) {
87         return nullptr;
88     }
89     char** typesArray = new (std::nothrow) char* [vectorSize];
90     if (typesArray == nullptr) {
91         LOG_ERROR(UDMF_CAPI, "create types array failed!");
92         return nullptr;
93     }
94     for (unsigned int i = 0; i < vectorSize; ++i) {
95         unsigned int strLen = strVector[i].length() + 1;
96         if (strLen > MAX_KEY_STRING_LEN) {
97             LOG_INFO(UDMF_CAPI, "string exceeds maximum length, length is %{public}d", strLen);
98             DestroyStringArray(typesArray, vectorSize);
99             return nullptr;
100         }
101         typesArray[i] = new (std::nothrow) char[strLen];
102         if (typesArray[i] == nullptr ||
103             (strcpy_s(typesArray[i], strLen, strVector[i].c_str())) != EOK) {
104             LOG_ERROR(UDMF_CAPI, "string copy failed");
105             DestroyStringArray(typesArray, vectorSize);
106             return nullptr;
107         }
108     }
109     return typesArray;
110 }
111 
CreateUnifiedDataRecordsArray(OH_UdmfData * unifiedData,std::vector<std::shared_ptr<UnifiedRecord>> & records)112 static OH_UdmfRecord** CreateUnifiedDataRecordsArray(OH_UdmfData* unifiedData,
113                                                      std::vector<std::shared_ptr<UnifiedRecord>>& records)
114 {
115     unsigned int size = static_cast<unsigned int>(records.size());
116     if (unifiedData == nullptr || size == 0 || size > MAX_RECORDS_COUNT) {
117         return nullptr;
118     }
119     OH_UdmfRecord** result = new (std::nothrow) OH_UdmfRecord* [size] { nullptr };
120     if (result == nullptr) {
121         return nullptr;
122     }
123     for (unsigned int i = 0; i < size; i++) {
124         result[i] = new (std::nothrow) OH_UdmfRecord;
125         if (result[i] == nullptr) {
126             DestroyUnifiedRecordArray(result, size);
127             return nullptr;
128         }
129         result[i]->record_ = records[i];
130     }
131     unifiedData->records = result;
132     unifiedData->recordsCount = size;
133     return unifiedData->records;
134 }
135 
IsUnifiedDataValid(OH_UdmfData * data)136 static bool IsUnifiedDataValid(OH_UdmfData* data)
137 {
138     return data != nullptr && data->unifiedData_ != nullptr &&
139            data->cid == NdkStructId::UDMF_UNIFIED_DATA_STRUCT_ID;
140 }
141 
IsUnifiedRecordValid(OH_UdmfRecord * record)142 static bool IsUnifiedRecordValid(OH_UdmfRecord* record)
143 {
144     return record != nullptr && record->record_ != nullptr &&
145            record->cid == NdkStructId::UDMF_UNIFIED_RECORD_STRUCT_ID;
146 }
147 
IsUnifiedPropertiesValid(OH_UdmfProperty * properties)148 static bool IsUnifiedPropertiesValid(OH_UdmfProperty* properties)
149 {
150     return properties != nullptr && properties->properties_ != nullptr &&
151            properties->cid == NdkStructId::UDMF_UNIFIED_DATA_PROPERTIES_ID;
152 }
153 
AddFileUriTypeIfContains(std::vector<std::string> & types)154 static void AddFileUriTypeIfContains(std::vector<std::string>& types)
155 {
156     for (auto type : types) {
157         if (FILE_TYPES.find(type) != FILE_TYPES.end()) {
158             types.push_back(UDMF_META_GENERAL_FILE_URI);
159             break;
160         }
161     }
162     return;
163 }
164 
OH_UdmfData_Create()165 OH_UdmfData* OH_UdmfData_Create()
166 {
167     OH_UdmfData* data = new (std::nothrow) OH_UdmfData;
168     if (data == nullptr) {
169         return nullptr;
170     }
171     data->unifiedData_ = std::make_shared<UnifiedData>();
172     return data;
173 }
174 
OH_UdmfData_Destroy(OH_UdmfData * data)175 void OH_UdmfData_Destroy(OH_UdmfData* data)
176 {
177     if (data == nullptr) {
178         return;
179     }
180     DestroyStringArray(data->typesArray, data->typesCount);
181     DestroyUnifiedRecordArray(data->records, data->recordsCount);
182     delete data;
183 }
184 
OH_UdmfData_AddRecord(OH_UdmfData * unifiedData,OH_UdmfRecord * record)185 int OH_UdmfData_AddRecord(OH_UdmfData* unifiedData, OH_UdmfRecord* record)
186 {
187     if (!IsUnifiedDataValid(unifiedData) || !IsUnifiedRecordValid(record)) {
188         return UDMF_E_INVALID_PARAM;
189     }
190     unifiedData->unifiedData_->AddRecord(record->record_);
191     return UDMF_E_OK;
192 }
193 
OH_UdmfData_HasType(OH_UdmfData * unifiedData,const char * type)194 bool OH_UdmfData_HasType(OH_UdmfData* unifiedData, const char* type)
195 {
196     return IsUnifiedDataValid(unifiedData) && type != nullptr && unifiedData->unifiedData_->HasTypeInEntries(type);
197 }
198 
OH_UdmfData_GetTypes(OH_UdmfData * unifiedData,unsigned int * count)199 char** OH_UdmfData_GetTypes(OH_UdmfData* unifiedData, unsigned int* count)
200 {
201     if (!IsUnifiedDataValid(unifiedData) || count == nullptr) {
202         return nullptr;
203     }
204     std::lock_guard<std::mutex> lock(unifiedData->mutex);
205     if (unifiedData->typesArray != nullptr) {
206         LOG_DEBUG(UDMF_CAPI, "return cache value");
207         *count = unifiedData->typesCount;
208         return unifiedData->typesArray;
209     }
210     std::vector<std::string> typeLabels = unifiedData->unifiedData_->GetEntriesTypes();
211     AddFileUriTypeIfContains(typeLabels);
212     unifiedData->typesArray = StrVectorToTypesArray(typeLabels);
213     unifiedData->typesArray == nullptr ? unifiedData->typesCount = 0 : unifiedData->typesCount = typeLabels.size();
214     *count = unifiedData->typesCount;
215     return unifiedData->typesArray;
216 }
217 
OH_UdmfRecord_GetTypes(OH_UdmfRecord * record,unsigned int * count)218 char** OH_UdmfRecord_GetTypes(OH_UdmfRecord* record, unsigned int* count)
219 {
220     if (!IsUnifiedRecordValid(record) || count == nullptr) {
221         return nullptr;
222     }
223     std::lock_guard<std::mutex> lock(record->mutex);
224     if (record->typesArray != nullptr) {
225         LOG_DEBUG(UDMF_CAPI, "return cache value");
226         *count = record->typesCount;
227         return record->typesArray;
228     }
229     auto types = record->record_->GetUtdIds();
230     std::vector<std::string> typeLabels {types.begin(), types.end()};
231     AddFileUriTypeIfContains(typeLabels);
232     record->typesArray = StrVectorToTypesArray(typeLabels);
233     record->typesArray == nullptr ? record->typesCount = 0 : record->typesCount = typeLabels.size();
234     *count = record->typesCount;
235     return record->typesArray;
236 }
237 
OH_UdmfData_GetRecords(OH_UdmfData * unifiedData,unsigned int * count)238 OH_UdmfRecord** OH_UdmfData_GetRecords(OH_UdmfData* unifiedData, unsigned int* count)
239 {
240     if (!IsUnifiedDataValid(unifiedData) || count == nullptr) {
241         return nullptr;
242     }
243     std::lock_guard<std::mutex> lock(unifiedData->mutex);
244     if (unifiedData->records != nullptr) {
245         LOG_DEBUG(UDMF_CAPI, "return cache value");
246         *count = unifiedData->recordsCount;
247         return unifiedData->records;
248     }
249     std::vector<std::shared_ptr<UnifiedRecord>> records = unifiedData->unifiedData_->GetRecords();
250     CreateUnifiedDataRecordsArray(unifiedData, records);
251     *count = unifiedData->recordsCount;
252     return unifiedData->records;
253 }
254 
GetFirstPlainText(OH_UdmfRecord ** records,unsigned int recordCount,OH_UdsPlainText * plainText)255 static int GetFirstPlainText(OH_UdmfRecord **records, unsigned int recordCount, OH_UdsPlainText* plainText)
256 {
257     int ret = UDMF_ERR;
258     if (records == nullptr || recordCount == 0) {
259         return ret;
260     }
261     for (unsigned int i = 0; i < recordCount; i++) {
262         const char *type = OH_UdsPlainText_GetType(plainText);
263         if (type == nullptr || !records[i]->record_->HasType(type)) {
264             continue;
265         }
266         ret = OH_UdmfRecord_GetPlainText(records[i], plainText);
267         if (ret == UDMF_E_OK) {
268             return ret;
269         }
270     }
271     return ret;
272 }
273 
GetFirstHtml(OH_UdmfRecord ** records,unsigned int recordCount,OH_UdsHtml * html)274 static int GetFirstHtml(OH_UdmfRecord **records, unsigned int recordCount, OH_UdsHtml* html)
275 {
276     int ret = UDMF_ERR;
277     if (records == nullptr || recordCount == 0) {
278         return ret;
279     }
280     for (unsigned int i = 0; i < recordCount; i++) {
281         const char *type = OH_UdsHtml_GetType(html);
282         if (type == nullptr || !records[i]->record_->HasType(type)) {
283             continue;
284         }
285         ret = OH_UdmfRecord_GetHtml(records[i], html);
286         if (ret == UDMF_E_OK) {
287             return ret;
288         }
289     }
290     return ret;
291 }
292 
OH_UdmfData_GetPrimaryPlainText(OH_UdmfData * data,OH_UdsPlainText * plainText)293 int OH_UdmfData_GetPrimaryPlainText(OH_UdmfData* data, OH_UdsPlainText* plainText)
294 {
295     if (!IsUnifiedDataValid(data) || IsInvalidUdsObjectPtr(plainText, UDS_PLAIN_TEXT_STRUCT_ID)) {
296         return UDMF_E_INVALID_PARAM;
297     }
298     std::lock_guard<std::mutex> lock(data->mutex);
299     if (data->records == nullptr) {
300         LOG_DEBUG(UDMF_CAPI, "no cache value");
301         std::vector<std::shared_ptr<UnifiedRecord>> records = data->unifiedData_->GetRecords();
302         CreateUnifiedDataRecordsArray(data, records);
303     }
304 
305     return GetFirstPlainText(data->records, data->recordsCount, plainText);
306 }
307 
OH_UdmfData_GetPrimaryHtml(OH_UdmfData * data,OH_UdsHtml * html)308 int OH_UdmfData_GetPrimaryHtml(OH_UdmfData* data, OH_UdsHtml* html)
309 {
310     if (!IsUnifiedDataValid(data) || IsInvalidUdsObjectPtr(html, UDS_HTML_STRUCT_ID)) {
311         return UDMF_E_INVALID_PARAM;
312     }
313     std::lock_guard<std::mutex> lock(data->mutex);
314     if (data->records == nullptr) {
315         LOG_DEBUG(UDMF_CAPI, "no cache value");
316         std::vector<std::shared_ptr<UnifiedRecord>> records = data->unifiedData_->GetRecords();
317         CreateUnifiedDataRecordsArray(data, records);
318     }
319 
320     return GetFirstHtml(data->records, data->recordsCount, html);
321 }
322 
OH_UdmfData_GetRecordCount(OH_UdmfData * data)323 int OH_UdmfData_GetRecordCount(OH_UdmfData *data)
324 {
325     if (!IsUnifiedDataValid(data)) {
326         return 0;
327     }
328     std::lock_guard<std::mutex> lock(data->mutex);
329     if (data->records == nullptr) {
330         LOG_DEBUG(UDMF_CAPI, "no cache value");
331         std::vector<std::shared_ptr<UnifiedRecord>> records = data->unifiedData_->GetRecords();
332         CreateUnifiedDataRecordsArray(data, records);
333     }
334     return static_cast<int>(data->recordsCount);
335 }
336 
OH_UdmfData_GetRecord(OH_UdmfData * data,unsigned int index)337 OH_UdmfRecord* OH_UdmfData_GetRecord(OH_UdmfData* data, unsigned int index)
338 {
339     if (!IsUnifiedDataValid(data) || index < 0) {
340         return nullptr;
341     }
342     std::lock_guard<std::mutex> lock(data->mutex);
343     if (data->records == nullptr) {
344         LOG_DEBUG(UDMF_CAPI, "no cache value");
345         std::vector<std::shared_ptr<UnifiedRecord>> records = data->unifiedData_->GetRecords();
346         CreateUnifiedDataRecordsArray(data, records);
347     }
348     if (index >= data->recordsCount || data->records == nullptr) {
349         return nullptr;
350     }
351     return data->records[index];
352 }
353 
OH_UdmfData_IsLocal(OH_UdmfData * data)354 bool OH_UdmfData_IsLocal(OH_UdmfData* data)
355 {
356     if (!IsUnifiedDataValid(data) || data->unifiedData_->GetProperties() == nullptr) {
357         return true;
358     }
359     bool isRemote = data->unifiedData_->GetProperties()->isRemote;
360     return !isRemote;
361 }
362 
OH_Udmf_GetUnifiedData(const char * key,Udmf_Intention intention,OH_UdmfData * data)363 int OH_Udmf_GetUnifiedData(const char* key, Udmf_Intention intention, OH_UdmfData* data)
364 {
365     if (!IsUnifiedDataValid(data) || key == nullptr) {
366         return UDMF_E_INVALID_PARAM;
367     }
368     Intention queryOptIntent;
369     switch (intention) {
370         case UDMF_INTENTION_DRAG:
371             queryOptIntent = Intention::UD_INTENTION_DRAG;
372             break;
373         default:
374             return UDMF_E_INVALID_PARAM;
375     }
376     QueryOption query = {.key = std::string(key), .intention = queryOptIntent};
377     if (UdmfClient::GetInstance().GetData(query, *(data->unifiedData_)) != E_OK) {
378         LOG_ERROR(UDMF_CAPI, "get data error");
379         return UDMF_ERR;
380     }
381     return UDMF_E_OK;
382 }
383 
OH_Udmf_SetUnifiedData(Udmf_Intention intention,OH_UdmfData * unifiedData,char * key,unsigned int keyLen)384 int OH_Udmf_SetUnifiedData(Udmf_Intention intention, OH_UdmfData* unifiedData, char* key, unsigned int keyLen)
385 {
386     if (!IsUnifiedDataValid(unifiedData) || key == nullptr || keyLen < UDMF_KEY_BUFFER_LEN) {
387         return UDMF_E_INVALID_PARAM;
388     }
389     enum Intention customOptIntent;
390     switch (intention) {
391         case UDMF_INTENTION_DRAG:
392             customOptIntent = Intention::UD_INTENTION_DRAG;
393             break;
394         default:
395             return UDMF_E_INVALID_PARAM;
396     }
397     CustomOption option = {.intention = customOptIntent};
398     std::string keyStr;
399     if ((UdmfClient::GetInstance().SetData(option, *(unifiedData->unifiedData_), keyStr)) != E_OK) {
400         LOG_ERROR(UDMF_CAPI, "set data error");
401         return UDMF_ERR;
402     }
403     if (strcpy_s(key, keyLen, keyStr.c_str()) != EOK) {
404         LOG_INFO(UDMF_CAPI, "string copy failed");
405         return UDMF_ERR;
406     }
407     return UDMF_E_OK;
408 }
409 
OH_UdmfRecord_Create()410 OH_UdmfRecord* OH_UdmfRecord_Create()
411 {
412     OH_UdmfRecord* record = new (std::nothrow) OH_UdmfRecord;
413     if (record == nullptr) {
414         return nullptr;
415     }
416     record->record_ = std::make_shared<UnifiedRecord>();
417     return record;
418 }
419 
OH_UdmfRecord_Destroy(OH_UdmfRecord * record)420 void OH_UdmfRecord_Destroy(OH_UdmfRecord* record)
421 {
422     if (record == nullptr) {
423         return;
424     }
425     if (record->recordData != nullptr) {
426         delete[] record->recordData;
427         record->recordData = nullptr;
428     }
429     DestroyStringArray(record->typesArray, record->typesCount);
430     delete record;
431 }
432 
OH_UdmfRecord_AddGeneralEntry(OH_UdmfRecord * record,const char * typeId,const unsigned char * entry,unsigned int count)433 int OH_UdmfRecord_AddGeneralEntry(OH_UdmfRecord* record, const char* typeId,
434                                   const unsigned char* entry, unsigned int count)
435 {
436     if (!IsUnifiedRecordValid(record) || typeId == nullptr || entry == nullptr || count == 0 ||
437         count > MAX_GENERAL_ENTRY_SIZE || strlen(typeId) > MAX_KEY_STRING_LEN) {
438         return UDMF_E_INVALID_PARAM;
439     }
440     std::vector<uint8_t> recordValue(entry, entry + count);
441     if (record->record_->GetType() == UD_BUTT) {
442         record->record_ = std::make_shared<ApplicationDefinedRecord>(APPLICATION_DEFINED_RECORD, recordValue);
443         record->record_->SetUtdId(typeId);
444     } else {
445         record->record_->AddEntry(typeId, std::move(recordValue));
446     }
447     record->recordDataLen = count;
448     return UDMF_E_OK;
449 }
450 
GetValueFromUdsArrayBuffer(OH_UdmfRecord * record,const char * typeId,ValueType value)451 static int GetValueFromUdsArrayBuffer(OH_UdmfRecord *record, const char *typeId, ValueType value)
452 {
453     if (!std::holds_alternative<std::shared_ptr<Object>>(value)) {
454         LOG_ERROR(UDMF_CAPI, "valueType is not object sptr!");
455         return UDMF_ERR;
456     }
457     OH_UdsArrayBuffer *buffer = OH_UdsArrayBuffer_Create();
458     buffer->obj = std::get<std::shared_ptr<Object>>(value);
459 
460     int ret = OH_UdsArrayBuffer_GetData(buffer, &record->recordData, &record->recordDataLen);
461     if (ret != UDMF_E_OK) {
462         LOG_ERROR(UDMF_CAPI, "get data from buffer failed. ret: %{public}d", ret);
463         OH_UdsArrayBuffer_Destroy(buffer);
464         return ret;
465     }
466     record->lastType = const_cast<char*>(typeId);
467     return UDMF_E_OK;
468 }
469 
GetValueFromUint8Array(OH_UdmfRecord * record,const char * typeId,ValueType value)470 static int GetValueFromUint8Array(OH_UdmfRecord *record, const char *typeId, ValueType value)
471 {
472     auto recordValue = std::get_if<std::vector<uint8_t>>(&value);
473     if (recordValue == nullptr) {
474         return UDMF_ERR;
475     }
476     record->recordDataLen = recordValue->size();
477     if (record->recordDataLen > MAX_GENERAL_ENTRY_SIZE) {
478         LOG_INFO(UDMF_CAPI, "data size exceeds maximum size");
479         return UDMF_ERR;
480     }
481     record->recordData = new (std::nothrow) unsigned char[record->recordDataLen];
482     if (record->recordData == nullptr) {
483         return UDMF_ERR;
484     }
485     auto err = memcpy_s(record->recordData, record->recordDataLen, recordValue->data(), record->recordDataLen);
486     if (err != EOK) {
487         LOG_ERROR(UDMF_CAPI, "memcpy error! type:%{public}s", typeId);
488         return UDMF_ERR;
489     }
490     record->lastType = const_cast<char*>(typeId);
491     return UDMF_E_OK;
492 }
493 
OH_UdmfRecord_GetGeneralEntry(OH_UdmfRecord * record,const char * typeId,unsigned char ** entry,unsigned int * count)494 int OH_UdmfRecord_GetGeneralEntry(OH_UdmfRecord* record, const char* typeId, unsigned char** entry, unsigned int* count)
495 {
496     if (!IsUnifiedRecordValid(record) || typeId == nullptr || entry == nullptr || count == nullptr) {
497         return UDMF_E_INVALID_PARAM;
498     }
499 
500     std::lock_guard<std::mutex> lock(record->mutex);
501     if (!record->record_->HasType(typeId)) {
502         LOG_ERROR(UDMF_CAPI, "no type:%{public}s", typeId);
503         return UDMF_E_INVALID_PARAM;
504     }
505     if (record->lastType == typeId && record->recordData != nullptr) {
506         LOG_DEBUG(UDMF_CAPI, "return cache value");
507         *entry = record->recordData;
508         *count = record->recordDataLen;
509         return UDMF_E_OK;
510     }
511 
512     auto value = record->record_->GetEntry(typeId);
513 
514     int result = UDMF_ERR;
515     if (std::holds_alternative<std::shared_ptr<Object>>(value)) {
516         result = GetValueFromUdsArrayBuffer(record, typeId, value);
517     } else if (std::holds_alternative<std::vector<uint8_t>>(value)) {
518         result = GetValueFromUint8Array(record, typeId, value);
519     } else {
520         LOG_ERROR(UDMF_CAPI, "Not contains right data type.");
521     }
522     if (result != UDMF_E_OK) {
523         LOG_ERROR(UDMF_CAPI, "Get value from valueType failed. typeId: %{public}s, result: %{public}d", typeId, result);
524         return result;
525     }
526     *count = record->recordDataLen;
527     *entry = record->recordData;
528     return UDMF_E_OK;
529 }
530 
531 template<typename T>
AddUds(OH_UdmfRecord * record,UdsObject * udsObject,UDType type)532 void AddUds(OH_UdmfRecord* record, UdsObject* udsObject, UDType type)
533 {
534     if (record->record_->GetType() == UD_BUTT) {
535         record->record_ = std::make_shared<T>(type, udsObject->obj);
536     } else {
537         record->record_->AddEntry(UtdUtils::GetUtdIdFromUtdEnum(type), udsObject->obj);
538     }
539 }
540 
OH_UdmfRecord_AddPlainText(OH_UdmfRecord * record,OH_UdsPlainText * plainText)541 int OH_UdmfRecord_AddPlainText(OH_UdmfRecord* record, OH_UdsPlainText* plainText)
542 {
543     if (!IsUnifiedRecordValid(record) || IsInvalidUdsObjectPtr(plainText, UDS_PLAIN_TEXT_STRUCT_ID)) {
544         return UDMF_E_INVALID_PARAM;
545     }
546     AddUds<PlainText>(record, plainText, PLAIN_TEXT);
547     return UDMF_E_OK;
548 }
549 
OH_UdmfRecord_AddHyperlink(OH_UdmfRecord * record,OH_UdsHyperlink * hyperlink)550 int OH_UdmfRecord_AddHyperlink(OH_UdmfRecord* record, OH_UdsHyperlink* hyperlink)
551 {
552     if (!IsUnifiedRecordValid(record) || IsInvalidUdsObjectPtr(hyperlink, UDS_HYPERLINK_STRUCT_ID)) {
553         return UDMF_E_INVALID_PARAM;
554     }
555     AddUds<Link>(record, hyperlink, HYPERLINK);
556     return UDMF_E_OK;
557 }
558 
OH_UdmfRecord_AddHtml(OH_UdmfRecord * record,OH_UdsHtml * html)559 int OH_UdmfRecord_AddHtml(OH_UdmfRecord* record, OH_UdsHtml* html)
560 {
561     if (!IsUnifiedRecordValid(record) || IsInvalidUdsObjectPtr(html, UDS_HTML_STRUCT_ID)) {
562         return UDMF_E_INVALID_PARAM;
563     }
564     AddUds<Html>(record, html, HTML);
565     return UDMF_E_OK;
566 }
567 
OH_UdmfRecord_AddAppItem(OH_UdmfRecord * record,OH_UdsAppItem * appItem)568 int OH_UdmfRecord_AddAppItem(OH_UdmfRecord* record, OH_UdsAppItem* appItem)
569 {
570     if (!IsUnifiedRecordValid(record) || IsInvalidUdsObjectPtr(appItem, UDS_APP_ITEM_STRUCT_ID)) {
571         return UDMF_E_INVALID_PARAM;
572     }
573     AddUds<SystemDefinedAppItem>(record, appItem, SYSTEM_DEFINED_APP_ITEM);
574     return UDMF_E_OK;
575 }
576 
OH_UdmfRecord_AddFileUri(OH_UdmfRecord * record,OH_UdsFileUri * fileUri)577 int OH_UdmfRecord_AddFileUri(OH_UdmfRecord* record, OH_UdsFileUri* fileUri)
578 {
579     if (!IsUnifiedRecordValid(record) || IsInvalidUdsObjectPtr(fileUri, UDS_FILE_URI_STRUCT_ID)) {
580         return UDMF_E_INVALID_PARAM;
581     }
582     std::string* fileType = std::get_if<std::string>(&(fileUri->obj->value_[FILE_TYPE]));
583     if (fileType == nullptr) {
584         return UDMF_ERR;
585     }
586     int32_t utdId = UtdUtils::GetUtdEnumFromUtdId(*fileType);
587     switch (utdId) {
588         case UDType::FILE:
589             AddUds<File>(record, fileUri, UDType::FILE);
590             break;
591         case UDType::AUDIO:
592             AddUds<Audio>(record, fileUri, UDType::AUDIO);
593             break;
594         case UDType::FOLDER:
595             AddUds<Folder>(record, fileUri, UDType::FOLDER);
596             break;
597         case UDType::IMAGE:
598             AddUds<Image>(record, fileUri, UDType::IMAGE);
599             break;
600         case UDType::VIDEO:
601             AddUds<Video>(record, fileUri, UDType::VIDEO);
602             break;
603         default:
604             AddUds<UnifiedRecord>(record, fileUri, UDType::FILE_URI);
605     }
606     return UDMF_E_OK;
607 }
608 
OH_UdmfRecord_AddPixelMap(OH_UdmfRecord * record,OH_UdsPixelMap * pixelMap)609 int OH_UdmfRecord_AddPixelMap(OH_UdmfRecord* record, OH_UdsPixelMap* pixelMap)
610 {
611     if (!IsUnifiedRecordValid(record) || IsInvalidUdsObjectPtr(pixelMap, UDS_PIXEL_MAP_STRUCT_ID)) {
612         return UDMF_E_INVALID_PARAM;
613     }
614     AddUds<SystemDefinedPixelMap>(record, pixelMap, UDType::SYSTEM_DEFINED_PIXEL_MAP);
615     return UDMF_E_OK;
616 }
617 
GetUds(OH_UdmfRecord * record,UdsObject * udsObject,UDType type)618 int GetUds(OH_UdmfRecord* record, UdsObject* udsObject, UDType type)
619 {
620     record->record_->InitObject();
621     auto value = record->record_->GetEntry(UtdUtils::GetUtdIdFromUtdEnum(type));
622     if (!std::holds_alternative<std::shared_ptr<Object>>(value)) {
623         return UDMF_ERR;
624     }
625     udsObject->obj = std::get<std::shared_ptr<Object>>(value);
626     return UDMF_E_OK;
627 }
628 
OH_UdmfRecord_AddArrayBuffer(OH_UdmfRecord * record,const char * type,OH_UdsArrayBuffer * buffer)629 int OH_UdmfRecord_AddArrayBuffer(OH_UdmfRecord* record, const char* type, OH_UdsArrayBuffer* buffer)
630 {
631     if (!IsUnifiedRecordValid(record) || type == nullptr || strlen(type) > MAX_KEY_STRING_LEN ||
632         IsInvalidUdsObjectPtr(buffer, UDS_ARRAY_BUFFER_STRUCT_ID)) {
633         return UDMF_E_INVALID_PARAM;
634     }
635     unsigned char *entry;
636     unsigned int size;
637     int ret = OH_UdsArrayBuffer_GetData(buffer, &entry, &size);
638     if (ret != UDMF_E_OK) {
639         return UDMF_E_INVALID_PARAM;
640     }
641     buffer->obj->value_[UNIFORM_DATA_TYPE] = type;
642     return OH_UdmfRecord_AddGeneralEntry(record, type, entry, size);
643 }
644 
OH_UdmfRecord_AddContentForm(OH_UdmfRecord * record,OH_UdsContentForm * contentForm)645 int OH_UdmfRecord_AddContentForm(OH_UdmfRecord* record, OH_UdsContentForm* contentForm)
646 {
647     if (!IsUnifiedRecordValid(record) || IsInvalidUdsObjectPtr(contentForm, UDS_CONTENT_FORM_STRUCT_ID)) {
648         return UDMF_E_INVALID_PARAM;
649     }
650     AddUds<UnifiedRecord>(record, contentForm, UDType::CONTENT_FORM);
651     return UDMF_E_OK;
652 }
653 
OH_UdmfRecord_GetPlainText(OH_UdmfRecord * record,OH_UdsPlainText * plainText)654 int OH_UdmfRecord_GetPlainText(OH_UdmfRecord* record, OH_UdsPlainText* plainText)
655 {
656     if (!IsUnifiedRecordValid(record) || IsInvalidUdsObjectPtr(plainText, UDS_PLAIN_TEXT_STRUCT_ID)) {
657         return UDMF_E_INVALID_PARAM;
658     }
659     return GetUds(record, plainText, PLAIN_TEXT);
660 }
661 
OH_UdmfRecord_GetHyperlink(OH_UdmfRecord * record,OH_UdsHyperlink * hyperlink)662 int OH_UdmfRecord_GetHyperlink(OH_UdmfRecord* record, OH_UdsHyperlink* hyperlink)
663 {
664     if (!IsUnifiedRecordValid(record) || IsInvalidUdsObjectPtr(hyperlink, UDS_HYPERLINK_STRUCT_ID)) {
665         return UDMF_E_INVALID_PARAM;
666     }
667     return GetUds(record, hyperlink, HYPERLINK);
668 }
669 
OH_UdmfRecord_GetHtml(OH_UdmfRecord * record,OH_UdsHtml * html)670 int OH_UdmfRecord_GetHtml(OH_UdmfRecord* record, OH_UdsHtml* html)
671 {
672     if (!IsUnifiedRecordValid(record) || IsInvalidUdsObjectPtr(html, UDS_HTML_STRUCT_ID)) {
673         return UDMF_E_INVALID_PARAM;
674     }
675     return GetUds(record, html, HTML);
676 }
677 
OH_UdmfRecord_GetAppItem(OH_UdmfRecord * record,OH_UdsAppItem * appItem)678 int OH_UdmfRecord_GetAppItem(OH_UdmfRecord* record, OH_UdsAppItem* appItem)
679 {
680     if (!IsUnifiedRecordValid(record) || IsInvalidUdsObjectPtr(appItem, UDS_APP_ITEM_STRUCT_ID)) {
681         return UDMF_E_INVALID_PARAM;
682     }
683     return GetUds(record, appItem, SYSTEM_DEFINED_APP_ITEM);
684 }
685 
OH_UdmfRecord_GetFileUri(OH_UdmfRecord * record,OH_UdsFileUri * fileUri)686 int OH_UdmfRecord_GetFileUri(OH_UdmfRecord* record, OH_UdsFileUri* fileUri)
687 {
688     if (!IsUnifiedRecordValid(record) || IsInvalidUdsObjectPtr(fileUri, UDS_FILE_URI_STRUCT_ID)) {
689         return UDMF_E_INVALID_PARAM;
690     }
691     if (GetUds(record, fileUri, UDType::FILE_URI) == UDMF_E_OK) {
692         return UDMF_E_OK;
693     }
694     for (auto fileType : FILE_TYPES) {
695         int ret = GetUds(record, fileUri, fileType.second);
696         if (ret == UDMF_E_OK) {
697             fileUri->obj->value_[UNIFORM_DATA_TYPE] = UDMF_META_GENERAL_FILE_URI;
698             fileUri->obj->value_[FILE_TYPE] = UtdUtils::GetUtdIdFromUtdEnum(fileType.second);
699             return UDMF_E_OK;
700         }
701     }
702     LOG_ERROR(UDMF_CAPI, "could't find file uri");
703     return UDMF_E_INVALID_PARAM;
704 }
705 
OH_UdmfRecord_GetPixelMap(OH_UdmfRecord * record,OH_UdsPixelMap * pixelMap)706 int OH_UdmfRecord_GetPixelMap(OH_UdmfRecord* record, OH_UdsPixelMap* pixelMap)
707 {
708     if (!IsUnifiedRecordValid(record) || IsInvalidUdsObjectPtr(pixelMap, UDS_PIXEL_MAP_STRUCT_ID)) {
709         return UDMF_E_INVALID_PARAM;
710     }
711     return GetUds(record, pixelMap, UDType::SYSTEM_DEFINED_PIXEL_MAP);
712 }
713 
OH_UdmfRecord_GetArrayBuffer(OH_UdmfRecord * record,const char * type,OH_UdsArrayBuffer * buffer)714 int OH_UdmfRecord_GetArrayBuffer(OH_UdmfRecord* record, const char* type, OH_UdsArrayBuffer* buffer)
715 {
716     unsigned int size = 0;
717     unsigned char *entry;
718     int ret = OH_UdmfRecord_GetGeneralEntry(record, type, &entry, &size);
719     if (ret != UDMF_E_OK) {
720         LOG_ERROR(UDMF_CAPI, "OH_UdmfRecord_GetGeneralEntry ret: %{public}d.", ret);
721         return ret;
722     }
723     return OH_UdsArrayBuffer_SetData(buffer, entry, size);
724 }
725 
OH_UdmfRecord_GetContentForm(OH_UdmfRecord * record,OH_UdsContentForm * contentForm)726 int OH_UdmfRecord_GetContentForm(OH_UdmfRecord* record, OH_UdsContentForm* contentForm)
727 {
728     if (!IsUnifiedRecordValid(record) || IsInvalidUdsObjectPtr(contentForm, UDS_CONTENT_FORM_STRUCT_ID)) {
729         return UDMF_E_INVALID_PARAM;
730     }
731     return GetUds(record, contentForm, UDType::CONTENT_FORM);
732 }
733 
OH_UdmfProperty_Create(OH_UdmfData * data)734 OH_UdmfProperty* OH_UdmfProperty_Create(OH_UdmfData* data)
735 {
736     if (!IsUnifiedDataValid(data)) {
737         return nullptr;
738     }
739     OH_UdmfProperty* properties = new (std::nothrow) OH_UdmfProperty;
740     if (properties == nullptr) {
741         return nullptr;
742     }
743     properties->properties_ = data->unifiedData_->GetProperties();
744     return properties;
745 }
746 
OH_UdmfProperty_Destroy(OH_UdmfProperty * properties)747 void OH_UdmfProperty_Destroy(OH_UdmfProperty* properties)
748 {
749     if (properties != nullptr) {
750         delete properties;
751     }
752 }
753 
OH_UdmfProperty_GetTag(OH_UdmfProperty * properties)754 const char* OH_UdmfProperty_GetTag(OH_UdmfProperty* properties)
755 {
756     if (!IsUnifiedPropertiesValid(properties)) {
757         return nullptr;
758     }
759     return properties->properties_->tag.c_str();
760 }
761 
OH_UdmfProperty_GetTimestamp(OH_UdmfProperty * properties)762 int64_t OH_UdmfProperty_GetTimestamp(OH_UdmfProperty* properties)
763 {
764     if (!IsUnifiedPropertiesValid(properties)) {
765         return -1;
766     }
767     return properties->properties_->timestamp;
768 }
769 
OH_UdmfProperty_GetShareOption(OH_UdmfProperty * properties)770 Udmf_ShareOption OH_UdmfProperty_GetShareOption(OH_UdmfProperty* properties)
771 {
772     if (!IsUnifiedPropertiesValid(properties)) {
773         return Udmf_ShareOption::SHARE_OPTIONS_INVALID;
774     }
775     switch (properties->properties_->shareOptions) {
776         case ShareOptions::IN_APP:
777             return Udmf_ShareOption::SHARE_OPTIONS_IN_APP;
778         case ShareOptions::CROSS_APP:
779         case ShareOptions::CROSS_DEVICE:
780             return Udmf_ShareOption::SHARE_OPTIONS_CROSS_APP;
781         default:
782             return Udmf_ShareOption::SHARE_OPTIONS_INVALID;
783     }
784 }
785 
OH_UdmfProperty_GetExtrasIntParam(OH_UdmfProperty * properties,const char * key,const int defaultValue)786 int OH_UdmfProperty_GetExtrasIntParam(OH_UdmfProperty* properties, const char* key, const int defaultValue)
787 {
788     return (IsUnifiedPropertiesValid(properties) && key != nullptr) ?
789            properties->properties_->extras.GetIntParam(key, defaultValue) : defaultValue;
790 }
791 
OH_UdmfProperty_GetExtrasStringParam(OH_UdmfProperty * properties,const char * key)792 const char* OH_UdmfProperty_GetExtrasStringParam(OH_UdmfProperty* properties, const char* key)
793 {
794     if (!IsUnifiedPropertiesValid(properties) || key == nullptr) {
795         return nullptr;
796     }
797     properties->extraStr = properties->properties_->extras.GetStringParam(key);
798     return properties->extraStr.c_str();
799 }
800 
OH_UdmfProperty_SetTag(OH_UdmfProperty * properties,const char * tag)801 int OH_UdmfProperty_SetTag(OH_UdmfProperty* properties, const char* tag)
802 {
803     if (!IsUnifiedPropertiesValid(properties) || tag == nullptr) {
804         return UDMF_E_INVALID_PARAM;
805     }
806     properties->properties_->tag = tag;
807     return UDMF_E_OK;
808 }
809 
OH_UdmfProperty_SetShareOption(OH_UdmfProperty * properties,Udmf_ShareOption option)810 int OH_UdmfProperty_SetShareOption(OH_UdmfProperty* properties, Udmf_ShareOption option)
811 {
812     if (!IsUnifiedPropertiesValid(properties)) {
813         return UDMF_E_INVALID_PARAM;
814     }
815     std::lock_guard<std::mutex> lock(properties->mutex);
816     switch (option) {
817         case Udmf_ShareOption::SHARE_OPTIONS_IN_APP:
818             properties->properties_->shareOptions = ShareOptions::IN_APP;
819             break;
820         case Udmf_ShareOption::SHARE_OPTIONS_CROSS_APP:
821             properties->properties_->shareOptions = ShareOptions::CROSS_APP;
822             break;
823         default:
824             return UDMF_E_INVALID_PARAM;
825     }
826     return UDMF_E_OK;
827 }
828 
OH_UdmfProperty_SetExtrasIntParam(OH_UdmfProperty * properties,const char * key,int param)829 int OH_UdmfProperty_SetExtrasIntParam(OH_UdmfProperty* properties, const char* key, int param)
830 {
831     if (!IsUnifiedPropertiesValid(properties) || key == nullptr) {
832         return UDMF_E_INVALID_PARAM;
833     }
834     std::lock_guard<std::mutex> lock(properties->mutex);
835     properties->properties_->extras.SetParam(key, OHOS::AAFwk::Integer::Box(param));
836     return UDMF_E_OK;
837 }
838 
OH_UdmfProperty_SetExtrasStringParam(OH_UdmfProperty * properties,const char * key,const char * param)839 int OH_UdmfProperty_SetExtrasStringParam(OH_UdmfProperty* properties, const char* key, const char* param)
840 {
841     if (!IsUnifiedPropertiesValid(properties) || key == nullptr || param == nullptr) {
842         return UDMF_E_INVALID_PARAM;
843     }
844     std::lock_guard<std::mutex> lock(properties->mutex);
845     properties->properties_->extras.SetParam(key, OHOS::AAFwk::String::Box(param));
846     return UDMF_E_OK;
847 }
848 
OH_UdmfRecordProvider_Create()849 OH_UdmfRecordProvider* OH_UdmfRecordProvider_Create()
850 {
851     OH_UdmfRecordProvider* provider = new (std::nothrow) OH_UdmfRecordProvider();
852     if (provider == nullptr) {
853         LOG_ERROR(UDMF_CAPI, "allocate OH_UdmfRecordProvider memory fail");
854     }
855     return provider;
856 }
857 
OH_UdmfRecordProvider_Destroy(OH_UdmfRecordProvider * provider)858 int OH_UdmfRecordProvider_Destroy(OH_UdmfRecordProvider* provider)
859 {
860     if (provider == nullptr) {
861         return UDMF_E_INVALID_PARAM;
862     }
863     if (provider->context != nullptr && provider->finalize != nullptr) {
864         (provider->finalize)(provider->context);
865         LOG_INFO(UDMF_CAPI, "free context finished");
866     }
867     delete provider;
868     return UDMF_E_OK;
869 }
870 
OH_UdmfRecordProvider_SetData(OH_UdmfRecordProvider * provider,void * context,const OH_UdmfRecordProvider_GetData callback,const UdmfData_Finalize finalize)871 int OH_UdmfRecordProvider_SetData(OH_UdmfRecordProvider* provider, void* context,
872     const OH_UdmfRecordProvider_GetData callback, const UdmfData_Finalize finalize)
873 {
874     if (provider == nullptr || callback == nullptr) {
875         return UDMF_E_INVALID_PARAM;
876     }
877     provider->callback = callback;
878     if (context != nullptr && finalize == nullptr) {
879         LOG_ERROR(UDMF_CAPI, "finalize function is null when context not null");
880         return UDMF_E_INVALID_PARAM;
881     }
882     provider->context = context;
883     provider->finalize = finalize;
884     return UDMF_E_OK;
885 }
886 
OH_UdmfRecord_SetProvider(OH_UdmfRecord * record,const char * const * types,unsigned int count,OH_UdmfRecordProvider * provider)887 int OH_UdmfRecord_SetProvider(OH_UdmfRecord* record, const char* const* types, unsigned int count,
888     OH_UdmfRecordProvider* provider)
889 {
890     if (!IsUnifiedRecordValid(record) || types == nullptr || count == 0 || provider == nullptr) {
891         return UDMF_E_INVALID_PARAM;
892     }
893     std::shared_ptr<DataProviderImpl> providerBox = std::make_shared<DataProviderImpl>();
894     providerBox->SetInnerProvider(provider);
895     std::vector<std::string> udTypes;
896     std::set<std::string> udTypeSet;
897     for (unsigned int i = 0; i < count; ++i) {
898         if (types[i] == nullptr) {
899             LOG_ERROR(UDMF_CAPI, "The type with index %{public}d is empty", i);
900             continue;
901         }
902         if (udTypeSet.count(types[i]) == 0) {
903             udTypeSet.emplace(types[i]);
904             udTypes.emplace_back(types[i]);
905         }
906     }
907     record->record_->SetEntryGetter(udTypes, providerBox);
908     return UDMF_E_OK;
909 }
910 
OH_UdmfProgressInfo_GetProgress(OH_Udmf_ProgressInfo * progressInfo)911 int OH_UdmfProgressInfo_GetProgress(OH_Udmf_ProgressInfo* progressInfo)
912 {
913     return progressInfo->progress;
914 }
915 
OH_UdmfProgressInfo_GetStatus(OH_Udmf_ProgressInfo * progressInfo)916 int OH_UdmfProgressInfo_GetStatus(OH_Udmf_ProgressInfo* progressInfo)
917 {
918     return progressInfo->status;
919 }
920 
OH_UdmfGetDataParams_Create()921 OH_UdmfGetDataParams* OH_UdmfGetDataParams_Create()
922 {
923     OH_UdmfGetDataParams *params =  new (std::nothrow) OH_UdmfGetDataParams();
924     if (params == nullptr) {
925         LOG_ERROR(UDMF_CAPI, "allocate OH_UdmfGetDataParams memory fail");
926         return nullptr;
927     }
928     return params;
929 }
930 
OH_UdmfGetDataParams_Destroy(OH_UdmfGetDataParams * pThis)931 void OH_UdmfGetDataParams_Destroy(OH_UdmfGetDataParams* pThis)
932 {
933     if (pThis == nullptr) {
934         return;
935     }
936     delete pThis;
937 }
938 
OH_UdmfGetDataParams_SetDestUri(OH_UdmfGetDataParams * params,const char * destUri)939 void OH_UdmfGetDataParams_SetDestUri(OH_UdmfGetDataParams* params, const char* destUri)
940 {
941     if (destUri == nullptr) {
942         return;
943     }
944     params->destUri = std::string(destUri);
945 }
946 
OH_UdmfGetDataParams_SetFileConflictOptions(OH_UdmfGetDataParams * params,const Udmf_FileConflictOptions options)947 void OH_UdmfGetDataParams_SetFileConflictOptions(OH_UdmfGetDataParams* params, const Udmf_FileConflictOptions options)
948 {
949     if (params == nullptr) {
950         return;
951     }
952     params->fileConflictOptions = options;
953 }
954 
OH_UdmfGetDataParams_SetProgressIndicator(OH_UdmfGetDataParams * params,const Udmf_ProgressIndicator progressIndicator)955 void OH_UdmfGetDataParams_SetProgressIndicator(OH_UdmfGetDataParams* params,
956     const Udmf_ProgressIndicator progressIndicator)
957 {
958     if (params == nullptr) {
959         return;
960     }
961     params->progressIndicator = progressIndicator;
962 }
963 
OH_UdmfGetDataParams_SetDataProgressListener(OH_UdmfGetDataParams * params,const OH_Udmf_DataProgressListener dataProgressListener)964 void OH_UdmfGetDataParams_SetDataProgressListener(OH_UdmfGetDataParams* params,
965     const OH_Udmf_DataProgressListener dataProgressListener)
966 {
967     if (params == nullptr) {
968         return;
969     }
970     params->dataProgressListener = dataProgressListener;
971 }