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_ffi.h"
18 #include "unified_record_impl.h"
19 
20 #include <cstdlib>
21 #include <string>
22 #include <variant>
23 #include <vector>
24 #include <map>
25 #include <iomanip>
26 #include "ffi_remote_data.h"
27 
28 #include "plain_text.h"
29 #include "html.h"
30 #include "link.h"
31 #include "image.h"
32 #include "pixel_map_impl.h"
33 #include "pixel_map.h"
34 
35 #include "video.h"
36 #include "audio.h"
37 #include "folder.h"
38 #include "system_defined_appitem.h"
39 #include "system_defined_form.h"
40 #include "system_defined_pixelmap.h"
41 #include "application_defined_record.h"
42 #include "utils.h"
43 
44 using namespace OHOS::FFI;
45 using namespace OHOS::UDMF;
46 
47 namespace OHOS {
48 namespace UDMF {
VectorToByteArray(std::vector<uint8_t> bytes)49     static CArrUI8 VectorToByteArray(std::vector<uint8_t> bytes)
50     {
51         if (bytes.size() == 0) {
52             return CArrUI8{};
53         }
54         uint8_t *head = static_cast<uint8_t *>(malloc(bytes.size() * sizeof(uint8_t)));
55         if (head == nullptr) {
56             return CArrUI8{};
57         }
58         for (unsigned long i = 0; i < bytes.size(); i++) {
59             head[i] = bytes[i];
60         }
61         CArrUI8 byteArray = {head, bytes.size()};
62         return byteArray;
63     }
64 
ValueType2CJValueType(ValueType value)65     CJValueType CUnifiedRecord::ValueType2CJValueType(ValueType value)
66     {
67         CJValueType cjvalue;
68         if (std::holds_alternative<std::monostate>(value)) {
69             cjvalue.tag = UNDEFINED;
70         } else if (std::holds_alternative<nullptr_t>(value)) {
71             cjvalue.tag = NULLTAG;
72         } else if (auto p = std::get_if<int32_t>(&value)) {
73             cjvalue.integer32 = *p;
74             cjvalue.tag = INTEGER32;
75         } else if (auto p = std::get_if<int64_t>(&value)) {
76             cjvalue.integer64 = *p;
77             cjvalue.tag = INTEGER64;
78         } else if (auto p = std::get_if<double>(&value)) {
79             cjvalue.dou = *p;
80             cjvalue.tag = DOUBLE;
81         } else if (auto p = std::get_if<bool>(&value)) {
82             cjvalue.boolean = *p;
83             cjvalue.tag = BOOLEAN;
84         } else if (auto p = std::get_if<std::string>(&value)) {
85             cjvalue.string = Utils::MallocCString(*p);
86             cjvalue.tag = STRING;
87         } else if (auto p = std::get_if<std::vector<uint8_t>>(&value)) {
88             cjvalue.byteArray = VectorToByteArray(*p);
89             cjvalue.tag = BYTEARRAY;
90         } else if (auto p = std::get_if<std::shared_ptr<OHOS::Media::PixelMap>>(&value)) {
91             cjvalue.pixelMapId = this->pixelMapId_;
92             cjvalue.tag = PIXELMAP;
93         }
94 
95         return cjvalue;
96     }
97 
CJValueType2ValueType(CJValueType cjvalue)98     ValueType CUnifiedRecord::CJValueType2ValueType(CJValueType cjvalue)
99     {
100         ValueType value;
101         switch (cjvalue.tag) {
102             case INTEGER32:
103                 value = cjvalue.integer32;
104                 break;
105             case INTEGER64:
106                 value = cjvalue.integer64;
107                 break;
108             case DOUBLE:
109                 value = cjvalue.dou;
110                 break;
111             case BOOLEAN:
112                 value = cjvalue.boolean;
113                 break;
114             case STRING:
115                 value = cjvalue.string;
116                 break;
117             case BYTEARRAY: {
118                 std::vector<uint8_t> bytes = std::vector<uint8_t>();
119                 for (int64_t i = 0; i < cjvalue.byteArray.size; i++) {
120                     bytes.push_back(cjvalue.byteArray.head[i]);
121                 }
122                 value = bytes;
123                 break;
124             }
125 
126             case PIXELMAP: {
127                 auto instance = FFIData::GetData<OHOS::Media::PixelMapImpl>(cjvalue.pixelMapId);
128                 if (instance == nullptr) {
129                     value = -1;
130                     break;
131                 }
132                 value = instance->GetRealPixelMap();
133                 break;
134             }
135 
136             case NULLTAG: {
137                 value = nullptr;
138                 break;
139             }
140 
141             case UNDEFINED: {
142                 value = std::monostate();
143                 break;
144             }
145 
146             default:
147                 value = -1;
148                 break;
149         }
150 
151         return value;
152     }
153 
CUnifiedRecord()154     CUnifiedRecord::CUnifiedRecord()
155     {
156         unifiedRecord_ = std::make_shared<UnifiedRecord>();
157     }
158 
CUnifiedRecord(const char *type, CJValueType cjvalue)159     CUnifiedRecord::CUnifiedRecord(const char *type, CJValueType cjvalue)
160     {
161         UDType utdType = APPLICATION_DEFINED_RECORD;
162         if (UtdUtils::IsValidUtdId(type)) {
163             utdType = static_cast<UDType>(UtdUtils::GetUtdEnumFromUtdId(type));
164         }
165         ValueType value = CJValueType2ValueType(cjvalue);
166         if (cjvalue.tag == PIXELMAP) {
167             this->pixelMapId_ = cjvalue.pixelMapId;
168         }
169         std::map<UDType, std::function<std::shared_ptr<UnifiedRecord>(UDType, ValueType)>> constructors = {
170             {TEXT, [](UDType type, ValueType value) { return std::make_shared<Text>(type, value); }},
171             {PLAIN_TEXT, [](UDType type, ValueType value) { return std::make_shared<PlainText>(type, value); }},
172             {HTML, [](UDType type, ValueType value) { return std::make_shared<Html>(type, value); }},
173             {HYPERLINK, [](UDType type, ValueType value) { return std::make_shared<Link>(type, value); }},
174             {FILE, [](UDType type, ValueType value) { return std::make_shared<File>(type, value); }},
175             {IMAGE, [](UDType type, ValueType value) { return std::make_shared<Image>(type, value); }},
176             {VIDEO, [](UDType type, ValueType value) { return std::make_shared<Video>(type, value); }},
177             {AUDIO, [](UDType type, ValueType value) { return std::make_shared<Audio>(type, value); }},
178             {FOLDER, [](UDType type, ValueType value) { return std::make_shared<Folder>(type, value); }},
179             {SYSTEM_DEFINED_RECORD, [](UDType type, ValueType value)
180                 { return std::make_shared<SystemDefinedRecord>(type, value); }},
181             {SYSTEM_DEFINED_APP_ITEM, [](UDType type, ValueType value)
182                 { return std::make_shared<SystemDefinedAppItem>(type, value); }},
183             {SYSTEM_DEFINED_FORM, [](UDType type, ValueType value)
184                 { return std::make_shared<SystemDefinedForm>(type, value); }},
185             {SYSTEM_DEFINED_PIXEL_MAP, [](UDType type, ValueType value)
186                 { return std::make_shared<SystemDefinedPixelMap>(type, value); }},
187             {APPLICATION_DEFINED_RECORD, [](UDType type, ValueType value)
188                 { return std::make_shared<ApplicationDefinedRecord>(type, value); }},
189         };
190         auto constructor = constructors.find(utdType);
191         if (constructor == constructors.end()) {
192             unifiedRecord_ = std::make_shared<UnifiedRecord>(utdType, value);
193             return;
194         }
195         unifiedRecord_ = constructor->second(utdType, value);
196     }
197 
GetType()198     char *CUnifiedRecord::GetType()
199     {
200         std::string ret = UtdUtils::GetUtdIdFromUtdEnum(this->unifiedRecord_->GetType());
201         return Utils::MallocCString(ret);
202     }
203 
GetValue()204     CJValueType CUnifiedRecord::GetValue()
205     {
206         ValueType value = this->unifiedRecord_->GetValue();
207         CJValueType cjvalue = ValueType2CJValueType(value);
208         return cjvalue;
209     }
210 
GetUnifiedRecord() const211     const std::shared_ptr<UDMF::UnifiedRecord> &CUnifiedRecord::GetUnifiedRecord() const
212     {
213         return unifiedRecord_;
214     }
215 }
216 }
217