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 "DataHandler"
16
17 #include "data_handler.h"
18 #include "log_print.h"
19 #include "tlv_object.h"
20 #include "tlv_util.h"
21
22 namespace OHOS::UDMF {
23 constexpr const char *UD_KEY_SEPARATOR = "/";
24 constexpr const char *UD_KEY_ENTRY_SEPARATOR = "#";
25
MarshalToEntries(const UnifiedData & unifiedData,std::vector<Entry> & entries)26 Status DataHandler::MarshalToEntries(const UnifiedData &unifiedData, std::vector<Entry> &entries)
27 {
28 std::string unifiedKey = unifiedData.GetRuntime()->key.GetUnifiedKey();
29 std::vector<uint8_t> runtimeBytes;
30 auto runtimeTlv = TLVObject(runtimeBytes);
31 if (!TLVUtil::Writing(*unifiedData.GetRuntime(), runtimeTlv, TAG::TAG_RUNTIME)) {
32 ZLOGE("Marshall runtime info failed, dataPrefix: %{public}s.", unifiedKey.c_str());
33 return E_WRITE_PARCEL_ERROR;
34 }
35 std::vector<uint8_t> udKeyBytes = { unifiedKey.begin(), unifiedKey.end() };
36 Entry entry = { udKeyBytes, runtimeBytes };
37 entries.emplace_back(entry);
38 return BuildEntries(unifiedData.GetRecords(), unifiedKey, entries);
39 }
40
UnmarshalEntries(const std::string & key,const std::vector<Entry> & entries,UnifiedData & unifiedData)41 Status DataHandler::UnmarshalEntries(const std::string &key, const std::vector<Entry> &entries,
42 UnifiedData &unifiedData)
43 {
44 std::map<std::string, std::shared_ptr<UnifiedRecord>> records;
45 std::map<std::string, std::map<std::string, ValueType>> innerEntries;
46 auto status = UnmarshalEntryItem(unifiedData, entries, key, records, innerEntries);
47 if (status != E_OK) {
48 ZLOGE("UnmarshalEntryItem failed.");
49 return status;
50 }
51 for (auto &[entryKey, entryValue] : innerEntries) {
52 auto idx = entryKey.rfind(UD_KEY_ENTRY_SEPARATOR);
53 std::string recordKey = entryKey.substr(0, idx);
54 std::string entryUtdId = entryKey.substr(idx + 1);
55 if (records.find(recordKey) != records.end() && entryValue.find(entryUtdId) != entryValue.end()) {
56 records[recordKey]->AddEntry(entryUtdId, std::move(entryValue[entryUtdId]));
57 }
58 }
59 return E_OK;
60 }
61
UnmarshalEntryItem(UnifiedData & unifiedData,const std::vector<Entry> & entries,const std::string & key,std::map<std::string,std::shared_ptr<UnifiedRecord>> & records,std::map<std::string,std::map<std::string,ValueType>> & innerEntries)62 Status DataHandler::UnmarshalEntryItem(UnifiedData &unifiedData, const std::vector<Entry> &entries,
63 const std::string &key, std::map<std::string, std::shared_ptr<UnifiedRecord>> &records,
64 std::map<std::string, std::map<std::string, ValueType>> &innerEntries)
65 {
66 for (const auto &entry : entries) {
67 std::string keyStr = { entry.key.begin(), entry.key.end() };
68 auto data = TLVObject(const_cast<std::vector<uint8_t> &>(entry.value));
69 if (keyStr == key) {
70 Runtime runtime;
71 if (!TLVUtil::ReadTlv(runtime, data, TAG::TAG_RUNTIME)) {
72 ZLOGE("Unmarshall runtime info failed.");
73 return E_READ_PARCEL_ERROR;
74 }
75 unifiedData.SetRuntime(runtime);
76 continue;
77 }
78 auto isStartWithKey = keyStr.find(key) == 0;
79 if (!isStartWithKey) {
80 continue;
81 }
82 auto isEntryItem = keyStr.rfind(UD_KEY_ENTRY_SEPARATOR) != std::string::npos;
83 if (isStartWithKey && !isEntryItem) {
84 std::shared_ptr<UnifiedRecord> record;
85 if (!TLVUtil::ReadTlv(record, data, TAG::TAG_UNIFIED_RECORD)) {
86 ZLOGE("Unmarshall unified record failed.");
87 return E_READ_PARCEL_ERROR;
88 }
89 unifiedData.AddRecord(record);
90 records.emplace(keyStr, record);
91 continue;
92 }
93 if (isStartWithKey && isEntryItem) {
94 std::shared_ptr<std::map<std::string, ValueType>> entryRead =
95 std::make_shared<std::map<std::string, ValueType>>();
96 if (!TLVUtil::ReadTlv(entryRead, data, TAG::TAG_INNER_ENTRIES)) {
97 ZLOGE("Unmarshall inner entry failed.");
98 return E_READ_PARCEL_ERROR;
99 }
100 innerEntries.emplace(keyStr, std::move(*entryRead));
101 }
102 }
103 return E_OK;
104 }
105
BuildEntries(const std::vector<std::shared_ptr<UnifiedRecord>> & records,const std::string & unifiedKey,std::vector<Entry> & entries)106 Status DataHandler::BuildEntries(const std::vector<std::shared_ptr<UnifiedRecord>> &records,
107 const std::string &unifiedKey, std::vector<Entry> &entries)
108 {
109 for (const auto &record : records) {
110 std::string recordKey = unifiedKey + UD_KEY_SEPARATOR + record->GetUid();
111 auto recordEntries = record->GetInnerEntries();
112 for (auto &recordEntry : *recordEntries) {
113 std::string key = recordKey + UD_KEY_ENTRY_SEPARATOR + recordEntry.first;
114 std::vector<uint8_t> entryBytes;
115 auto entryTlv = TLVObject(entryBytes);
116 const std::shared_ptr<std::map<std::string, ValueType>> entryMap =
117 std::make_shared<std::map<std::string, ValueType>>();
118 entryMap->insert_or_assign(recordEntry.first, recordEntry.second);
119 if (!TLVUtil::Writing(entryMap, entryTlv, TAG::TAG_INNER_ENTRIES)) {
120 ZLOGI("Marshall inner entry failed.");
121 return E_WRITE_PARCEL_ERROR;
122 }
123 std::vector<uint8_t> keyBytes = { key.begin(), key.end() };
124 Entry entry = { keyBytes, entryBytes };
125 entries.emplace_back(entry);
126 }
127 recordEntries->clear();
128 std::vector<uint8_t> recordBytes;
129 auto recordTlv = TLVObject(recordBytes);
130 if (!TLVUtil::Writing(record, recordTlv, TAG::TAG_UNIFIED_RECORD)) {
131 ZLOGI("Marshall unified record failed.");
132 return E_WRITE_PARCEL_ERROR;
133 }
134 std::vector<uint8_t> keyBytes = { recordKey.begin(), recordKey.end() };
135 Entry entry = { keyBytes, recordBytes };
136 entries.emplace_back(entry);
137 }
138 return E_OK;
139 }
140 } // namespace UDMF::OHOS