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