• 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 "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