• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 
2 /*
3  * Copyright (c) 2024 Huawei Device Co., Ltd.
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "unified_record_impl.h"
18 
19 #include <cstdlib>
20 #include <iomanip>
21 #include <map>
22 #include <string>
23 #include <variant>
24 #include <vector>
25 
26 #include "ffi_remote_data.h"
27 #include "securec.h"
28 #include "unified_record_ffi.h"
29 
30 #include "application_defined_record.h"
31 #include "audio.h"
32 #include "folder.h"
33 #include "html.h"
34 #include "image.h"
35 #include "link.h"
36 #include "pixel_map_impl.h"
37 #include "pixel_map.h"
38 #include "plain_text.h"
39 #include "system_defined_appitem.h"
40 #include "system_defined_form.h"
41 #include "system_defined_pixelmap.h"
42 #include "utils.h"
43 #include "video.h"
44 
45 using namespace OHOS::FFI;
46 using namespace OHOS::UDMF;
47 
48 namespace OHOS {
49 namespace UDMF {
VectorToByteArray(std::vector<uint8_t> bytes)50 static CArrUI8 VectorToByteArray(std::vector<uint8_t> bytes)
51 {
52     if (bytes.size() == 0) {
53         return CArrUI8 {};
54     }
55     uint8_t *head = static_cast<uint8_t*>(malloc(bytes.size() * sizeof(uint8_t)));
56     if (head == nullptr) {
57         return CArrUI8 {};
58     }
59     for (size_t i = 0; i < bytes.size(); i++) {
60         head[i] = bytes[i];
61     }
62     CArrUI8 byteArray = {head, bytes.size()};
63     return byteArray;
64 }
65 
ValueType2CJValueType(ValueType value)66 CJValueType CUnifiedRecord::ValueType2CJValueType(ValueType value)
67 {
68     CJValueType cjvalue;
69     if (std::holds_alternative<std::monostate>(value)) {
70         cjvalue.tag = UNDEFINED;
71     } else if (std::holds_alternative<nullptr_t>(value)) {
72         cjvalue.tag = NULLTAG;
73     } else if (auto p = std::get_if<int32_t>(&value)) {
74         cjvalue.integer32 = *p;
75         cjvalue.tag = INTEGER32;
76     } else if (auto p = std::get_if<int64_t>(&value)) {
77         cjvalue.integer64 = *p;
78         cjvalue.tag = INTEGER64;
79     } else if (auto p = std::get_if<double>(&value)) {
80         cjvalue.dou = *p;
81         cjvalue.tag = DOUBLE;
82     } else if (auto p = std::get_if<bool>(&value)) {
83         cjvalue.boolean = *p;
84         cjvalue.tag = BOOLEAN;
85     } else if (auto p = std::get_if<std::string>(&value)) {
86         cjvalue.string = Utils::MallocCString(*p);
87         cjvalue.tag = STRING;
88     } else if (auto p = std::get_if<std::vector<uint8_t>>(&value)) {
89         cjvalue.byteArray = VectorToByteArray(*p);
90         cjvalue.tag = BYTEARRAY;
91     } else if (auto p = std::get_if<std::shared_ptr<OHOS::Media::PixelMap>>(&value)) {
92         cjvalue.pixelMapId = this->pixelMapId_;
93         cjvalue.tag = PIXELMAP;
94     }
95 
96     return cjvalue;
97 }
98 
CJValueType2ValueType(CJValueType cjvalue)99 ValueType CUnifiedRecord::CJValueType2ValueType(CJValueType cjvalue)
100 {
101     ValueType value;
102     switch (cjvalue.tag) {
103         case INTEGER32:
104             value = cjvalue.integer32;
105             break;
106         case INTEGER64:
107             value = cjvalue.integer64;
108             break;
109         case DOUBLE:
110             value = cjvalue.dou;
111             break;
112         case BOOLEAN:
113             value = cjvalue.boolean;
114             break;
115         case STRING:
116             value = cjvalue.string;
117             break;
118         case BYTEARRAY: {
119             std::vector<uint8_t> bytes = std::vector<uint8_t>();
120             for (int64_t i = 0; i < cjvalue.byteArray.size; i++) {
121                 bytes.push_back(cjvalue.byteArray.head[i]);
122             }
123             value = bytes;
124             break;
125         }
126 
127         case PIXELMAP: {
128             auto instance = FFIData::GetData<OHOS::Media::PixelMapImpl>(cjvalue.pixelMapId);
129             if (instance == nullptr) {
130                 value = -1;
131                 break;
132             }
133             value = instance->GetRealPixelMap();
134             break;
135         }
136 
137         case NULLTAG: {
138             value = nullptr;
139             break;
140         }
141 
142         case UNDEFINED: {
143             value = std::monostate();
144             break;
145         }
146 
147         default:
148             value = -1;
149             break;
150     }
151 
152     return value;
153 }
154 
CUnifiedRecord()155 CUnifiedRecord::CUnifiedRecord()
156 {
157     unifiedRecord_ = std::make_shared<UnifiedRecord>();
158 }
159 
CUnifiedRecord(const char * type)160 CUnifiedRecord::CUnifiedRecord(const char *type)
161 {
162     UDType utdType = APPLICATION_DEFINED_RECORD;
163     if (UtdUtils::IsValidUtdId(type)) {
164         utdType = static_cast<UDType>(UtdUtils::GetUtdEnumFromUtdId(type));
165     }
166     static const std::map<UDType, std::function<std::shared_ptr<UnifiedRecord>()>> constructors = {
167         {TEXT, []() { return std::make_shared<Text>(); }},
168         {PLAIN_TEXT, []() { return std::make_shared<PlainText>(); }},
169         {HTML, []() { return std::make_shared<Html>(); }},
170         {HYPERLINK, []() { return std::make_shared<Link>(); }},
171         {FILE, []() { return std::make_shared<File>(); }},
172         {IMAGE, []() { return std::make_shared<Image>(); }},
173         {VIDEO, []() { return std::make_shared<Video>(); }},
174         {AUDIO, []() { return std::make_shared<Audio>(); }},
175         {FOLDER, []() { return std::make_shared<Folder>(); }},
176         {SYSTEM_DEFINED_RECORD, []()
177             { return std::make_shared<SystemDefinedRecord>(); }},
178         {SYSTEM_DEFINED_APP_ITEM, []()
179             { return std::make_shared<SystemDefinedAppItem>(); }},
180         {SYSTEM_DEFINED_FORM, []()
181             { return std::make_shared<SystemDefinedForm>(); }},
182         {SYSTEM_DEFINED_PIXEL_MAP, []()
183             { return std::make_shared<SystemDefinedPixelMap>(); }},
184         {APPLICATION_DEFINED_RECORD, []()
185             { return std::make_shared<ApplicationDefinedRecord>(); }},
186     };
187     auto constructor = constructors.find(utdType);
188     if (constructor == constructors.end()) {
189         unifiedRecord_ = std::make_shared<UnifiedRecord>(utdType);
190         return;
191     }
192     unifiedRecord_ = constructor->second();
193 }
194 
CUnifiedRecord(const char * type,CJValueType cjvalue)195 CUnifiedRecord::CUnifiedRecord(const char *type, CJValueType cjvalue)
196 {
197     UDType utdType = APPLICATION_DEFINED_RECORD;
198     if (UtdUtils::IsValidUtdId(type)) {
199         utdType = static_cast<UDType>(UtdUtils::GetUtdEnumFromUtdId(type));
200     }
201     ValueType value = CJValueType2ValueType(cjvalue);
202     if (cjvalue.tag == PIXELMAP) {
203         this->pixelMapId_ = cjvalue.pixelMapId;
204     }
205     static const std::map<UDType, std::function<std::shared_ptr<UnifiedRecord>(UDType, ValueType)>> constructors = {
206         {TEXT, [](UDType type, ValueType value) { return std::make_shared<Text>(type, value); }},
207         {PLAIN_TEXT, [](UDType type, ValueType value) { return std::make_shared<PlainText>(type, value); }},
208         {HTML, [](UDType type, ValueType value) { return std::make_shared<Html>(type, value); }},
209         {HYPERLINK, [](UDType type, ValueType value) { return std::make_shared<Link>(type, value); }},
210         {FILE, [](UDType type, ValueType value) { return std::make_shared<File>(type, value); }},
211         {IMAGE, [](UDType type, ValueType value) { return std::make_shared<Image>(type, value); }},
212         {VIDEO, [](UDType type, ValueType value) { return std::make_shared<Video>(type, value); }},
213         {AUDIO, [](UDType type, ValueType value) { return std::make_shared<Audio>(type, value); }},
214         {FOLDER, [](UDType type, ValueType value) { return std::make_shared<Folder>(type, value); }},
215         {SYSTEM_DEFINED_RECORD, [](UDType type, ValueType value)
216             { return std::make_shared<SystemDefinedRecord>(type, value); }},
217         {SYSTEM_DEFINED_APP_ITEM, [](UDType type, ValueType value)
218             { return std::make_shared<SystemDefinedAppItem>(type, value); }},
219         {SYSTEM_DEFINED_FORM, [](UDType type, ValueType value)
220             { return std::make_shared<SystemDefinedForm>(type, value); }},
221         {SYSTEM_DEFINED_PIXEL_MAP, [](UDType type, ValueType value)
222             { return std::make_shared<SystemDefinedPixelMap>(type, value); }},
223         {APPLICATION_DEFINED_RECORD, [](UDType type, ValueType value)
224             { return std::make_shared<ApplicationDefinedRecord>(type, value); }},
225     };
226     auto constructor = constructors.find(utdType);
227     if (constructor == constructors.end()) {
228         unifiedRecord_ = std::make_shared<UnifiedRecord>(utdType, value);
229         return;
230     }
231     unifiedRecord_ = constructor->second(utdType, value);
232 }
233 
GetType()234 char *CUnifiedRecord::GetType()
235 {
236     std::string ret = UtdUtils::GetUtdIdFromUtdEnum(this->unifiedRecord_->GetType());
237     return Utils::MallocCString(ret);
238 }
239 
GetValue()240 CJValueType CUnifiedRecord::GetValue()
241 {
242     ValueType value = this->unifiedRecord_->GetValue();
243     CJValueType cjvalue = ValueType2CJValueType(value);
244     return cjvalue;
245 }
246 
GetUnifiedRecord() const247 const std::shared_ptr<UDMF::UnifiedRecord> &CUnifiedRecord::GetUnifiedRecord() const
248 {
249     return unifiedRecord_;
250 }
251 
GetFileUri()252 char *CUnifiedRecord::GetFileUri()
253 {
254     std::shared_ptr<UDMF::File> resFile = std::reinterpret_pointer_cast<UDMF::File>(this->unifiedRecord_);
255     std::string res = resFile->GetUri();
256     return Utils::MallocCString(res);
257 }
258 
SetFileUri(const char * uri)259 void CUnifiedRecord::SetFileUri(const char *uri)
260 {
261     std::shared_ptr<UDMF::File> resFile = std::reinterpret_pointer_cast<UDMF::File>(this->unifiedRecord_);
262     resFile->SetUri(uri);
263 }
264 
GetFileDetails()265 CRecord CUnifiedRecord::GetFileDetails()
266 {
267     CRecord ret = { .keys = { .head = nullptr, .size = 0 }, .values = { .head = nullptr, .size = 0 } };
268     std::shared_ptr<UDMF::File> resFile = std::reinterpret_pointer_cast<UDMF::File>(this->unifiedRecord_);
269     OHOS::UDMF::UDDetails resDetails = resFile->GetDetails();
270     std::map<std::string, std::string> params;
271     for (auto it : resDetails) {
272         if (std::holds_alternative<std::string>(it.second)) {
273             const std::string &strValue = std::get<std::string>(it.second);
274             params.emplace(it.first, strValue);
275         }
276     }
277     char **keysHead = static_cast<char**>(malloc(sizeof(char*) * params.size()));
278     if (keysHead == nullptr) {
279         return ret;
280     }
281     char **valuesHead = static_cast<char**>(malloc(sizeof(char*) * params.size()));
282     if (valuesHead == nullptr) {
283         free(keysHead);
284         return ret;
285     }
286     int64_t i = 0;
287     for (auto &param : params) {
288         keysHead[i] = CreateCStringFromString(param.first);
289         valuesHead[i] = CreateCStringFromString(param.second);
290         i++;
291     }
292     ret.keys.size = static_cast<int64_t>(params.size());
293     ret.keys.head = keysHead;
294     ret.values.size = static_cast<int64_t>(params.size());
295     ret.values.head = valuesHead;
296     return ret;
297 }
298 
SetFileDetails(const std::map<std::string,std::string> & details)299 void CUnifiedRecord::SetFileDetails(const std::map<std::string, std::string> &details)
300 {
301     std::shared_ptr<UDMF::File> resFile = std::reinterpret_pointer_cast<UDMF::File>(this->unifiedRecord_);
302     OHOS::UDMF::UDDetails udDetails;
303     for (auto &param : details) {
304         udDetails[param.first] = param.second;
305     }
306     resFile->SetDetails(udDetails);
307 }
308 
GetImageUri()309 char *CUnifiedRecord::GetImageUri()
310 {
311     std::shared_ptr<UDMF::Image> resImage = std::reinterpret_pointer_cast<UDMF::Image>(this->unifiedRecord_);
312     std::string res = resImage->GetUri();
313     return Utils::MallocCString(res);
314 }
315 
SetImageUri(const char * uri)316 void CUnifiedRecord::SetImageUri(const char *uri)
317 {
318     std::shared_ptr<UDMF::Image> resImage = std::reinterpret_pointer_cast<UDMF::Image>(this->unifiedRecord_);
319     resImage->SetUri(uri);
320 }
321 
GetVideoUri()322 char *CUnifiedRecord::GetVideoUri()
323 {
324     std::shared_ptr<UDMF::Video> resVideo = std::reinterpret_pointer_cast<UDMF::Video>(this->unifiedRecord_);
325     std::string res = resVideo->GetUri();
326     return Utils::MallocCString(res);
327 }
328 
SetVideoUri(const char * uri)329 void CUnifiedRecord::SetVideoUri(const char *uri)
330 {
331     std::shared_ptr<UDMF::Video> resVideo = std::reinterpret_pointer_cast<UDMF::Video>(this->unifiedRecord_);
332     resVideo->SetUri(uri);
333 }
334 
GetTextDetails()335 CRecord CUnifiedRecord::GetTextDetails()
336 {
337     CRecord ret = { .keys = { .head = nullptr, .size = 0 }, .values = { .head = nullptr, .size = 0 } };
338     std::shared_ptr<UDMF::Text> resText = std::reinterpret_pointer_cast<UDMF::Text>(this->unifiedRecord_);
339     OHOS::UDMF::UDDetails resDetails = resText->GetDetails();
340     std::map<std::string, std::string> params;
341     for (auto it : resDetails) {
342         if (std::holds_alternative<std::string>(it.second)) {
343             const std::string &strValue = std::get<std::string>(it.second);
344             params.emplace(it.first, strValue);
345         }
346     }
347     char **keysHead = static_cast<char**>(malloc(sizeof(char*) * params.size()));
348     if (keysHead == nullptr) {
349         return ret;
350     }
351     char **valuesHead = static_cast<char**>(malloc(sizeof(char*) * params.size()));
352     if (valuesHead == nullptr) {
353         free(keysHead);
354         return ret;
355     }
356     int64_t i = 0;
357     for (auto &param : params) {
358         keysHead[i] = CreateCStringFromString(param.first);
359         valuesHead[i] = CreateCStringFromString(param.second);
360         i++;
361     }
362     ret.keys.size = static_cast<int64_t>(params.size());
363     ret.keys.head = keysHead;
364     ret.values.size = static_cast<int64_t>(params.size());
365     ret.values.head = valuesHead;
366     return ret;
367 }
368 
SetTextDetails(const std::map<std::string,std::string> & details)369 void CUnifiedRecord::SetTextDetails(const std::map<std::string, std::string> &details)
370 {
371     std::shared_ptr<UDMF::Text> resText = std::reinterpret_pointer_cast<UDMF::Text>(this->unifiedRecord_);
372     OHOS::UDMF::UDDetails udDetails;
373     for (auto &param : details) {
374         udDetails[param.first] = param.second;
375     }
376     resText->SetDetails(udDetails);
377 }
378 
GetHyperLinkUrl()379 char *CUnifiedRecord::GetHyperLinkUrl()
380 {
381     std::shared_ptr<UDMF::Link> resLink = std::reinterpret_pointer_cast<UDMF::Link>(this->unifiedRecord_);
382     std::string res = resLink->GetUrl();
383     return Utils::MallocCString(res);
384 }
385 
SetHyperLinkUrl(const char * url)386 void CUnifiedRecord::SetHyperLinkUrl(const char *url)
387 {
388     std::shared_ptr<UDMF::Link> resLink = std::reinterpret_pointer_cast<UDMF::Link>(this->unifiedRecord_);
389     resLink->SetUrl(url);
390 }
391 
GetHyperLinkDescription()392 char *CUnifiedRecord::GetHyperLinkDescription()
393 {
394     std::shared_ptr<UDMF::Link> resLink = std::reinterpret_pointer_cast<UDMF::Link>(this->unifiedRecord_);
395     std::string res = resLink->GetDescription();
396     return Utils::MallocCString(res);
397 }
398 
SetHyperLinkDescription(const char * description)399 void CUnifiedRecord::SetHyperLinkDescription(const char *description)
400 {
401     std::shared_ptr<UDMF::Link> resLink = std::reinterpret_pointer_cast<UDMF::Link>(this->unifiedRecord_);
402     resLink->SetDescription(description);
403 }
404 
GetPlainTextContent()405 char *CUnifiedRecord::GetPlainTextContent()
406 {
407     std::shared_ptr<UDMF::PlainText> resText = std::reinterpret_pointer_cast<UDMF::PlainText>(this->unifiedRecord_);
408     std::string res = resText->GetContent();
409     return Utils::MallocCString(res);
410 }
411 
SetPlainTextContent(const char * text)412 void CUnifiedRecord::SetPlainTextContent(const char *text)
413 {
414     std::shared_ptr<UDMF::PlainText> resText = std::reinterpret_pointer_cast<UDMF::PlainText>(this->unifiedRecord_);
415     resText->SetContent(text);
416 }
417 
GetPlainTextAbstract()418 char *CUnifiedRecord::GetPlainTextAbstract()
419 {
420     std::shared_ptr<UDMF::PlainText> resText = std::reinterpret_pointer_cast<UDMF::PlainText>(this->unifiedRecord_);
421     std::string res = resText->GetAbstract();
422     return Utils::MallocCString(res);
423 }
424 
SetPlainTextAbstract(const char * abstr)425 void CUnifiedRecord::SetPlainTextAbstract(const char *abstr)
426 {
427     std::shared_ptr<UDMF::PlainText> resText = std::reinterpret_pointer_cast<UDMF::PlainText>(this->unifiedRecord_);
428     resText->SetAbstract(abstr);
429 }
430 
CreateCStringFromString(const std::string & source)431 char *CreateCStringFromString(const std::string &source)
432 {
433     if (source.size() == 0) {
434         return nullptr;
435     }
436     size_t length = source.size() + 1;
437     auto res = static_cast<char*>(malloc(length));
438     if (res == nullptr) {
439         return nullptr;
440     }
441     if (strcpy_s(res, length, source.c_str()) != 0) {
442         free(res);
443         return nullptr;
444     }
445     return res;
446 }
447 } // namespace UDMF
448 } // namespace OHOS
449