• 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_util.h"
20 
21 namespace OHOS::UDMF {
22 constexpr const char *UD_KEY_SEPARATOR = "/";
23 constexpr const char *UD_KEY_ENTRY_SEPARATOR = "#";
24 constexpr const char *UD_KEY_PROPERTIES_SEPARATOR = "#properties";
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("Runtime info marshalling failed:%{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     std::string propsKey = unifiedData.GetRuntime()->key.GetKeyCommonPrefix() + UD_KEY_PROPERTIES_SEPARATOR;
39     std::vector<uint8_t> propsBytes;
40     auto propsTlv = TLVObject(propsBytes);
41     if (!TLVUtil::Writing(*unifiedData.GetProperties(), propsTlv, TAG::TAG_PROPERTIES)) {
42         ZLOGE("Properties info marshalling failed:%{public}s", propsKey.c_str());
43         return E_WRITE_PARCEL_ERROR;
44     }
45     std::vector<uint8_t> propsKeyBytes = { propsKey.begin(), propsKey.end() };
46     Entry propsEntry = { propsKeyBytes, propsBytes };
47     entries.emplace_back(std::move(propsEntry));
48     return BuildEntries(unifiedData.GetRecords(), unifiedKey, entries);
49 }
50 
UnmarshalEntries(const std::string & key,const std::vector<Entry> & entries,UnifiedData & unifiedData)51 Status DataHandler::UnmarshalEntries(const std::string &key, const std::vector<Entry> &entries,
52     UnifiedData &unifiedData)
53 {
54     std::map<std::string, std::shared_ptr<UnifiedRecord>> records;
55     std::map<std::string, std::map<std::string, ValueType>> innerEntries;
56     auto status = UnmarshalEntryItem(unifiedData, entries, key, records, innerEntries);
57     if (status != E_OK) {
58         ZLOGE("UnmarshalEntryItem failed.");
59         return status;
60     }
61     for (auto &[entryKey, entryValue] : innerEntries) {
62         auto idx = entryKey.rfind(UD_KEY_ENTRY_SEPARATOR);
63         std::string recordKey = entryKey.substr(0, idx);
64         std::string entryUtdId = entryKey.substr(idx + 1);
65         if (records.find(recordKey) != records.end() && entryValue.find(entryUtdId) != entryValue.end()) {
66             records[recordKey]->AddEntry(entryUtdId, std::move(entryValue[entryUtdId]));
67         }
68     }
69     return E_OK;
70 }
71 
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)72 Status DataHandler::UnmarshalEntryItem(UnifiedData &unifiedData, const std::vector<Entry> &entries,
73     const std::string &key, std::map<std::string, std::shared_ptr<UnifiedRecord>> &records,
74     std::map<std::string, std::map<std::string, ValueType>> &innerEntries)
75 {
76     for (const auto &entry : entries) {
77         std::string keyStr = { entry.key.begin(), entry.key.end() };
78         auto data = TLVObject(const_cast<std::vector<uint8_t> &>(entry.value));
79         if (keyStr == key) {
80             Runtime runtime;
81             if (!TLVUtil::ReadTlv(runtime, data, TAG::TAG_RUNTIME)) {
82                 ZLOGE("Unmarshall runtime info failed.");
83                 return E_READ_PARCEL_ERROR;
84             }
85             unifiedData.SetRuntime(runtime);
86             continue;
87         }
88         auto isStartWithKey = keyStr.find(key) == 0;
89         std::string propsKey = UnifiedKey(key).GetKeyCommonPrefix() + UD_KEY_PROPERTIES_SEPARATOR;
90         if (!isStartWithKey && (keyStr == propsKey)) {
91             std::shared_ptr<UnifiedDataProperties> properties;
92             if (!TLVUtil::ReadTlv(properties, data, TAG::TAG_PROPERTIES)) {
93                 ZLOGE("Unmarshall unified properties failed.");
94                 return E_READ_PARCEL_ERROR;
95             }
96             unifiedData.SetProperties(std::move(properties));
97             continue;
98         }
99         auto isEntryItem = keyStr.rfind(UD_KEY_ENTRY_SEPARATOR) != std::string::npos;
100         if (isStartWithKey && !isEntryItem) {
101             std::shared_ptr<UnifiedRecord> record;
102             if (!TLVUtil::ReadTlv(record, data, TAG::TAG_UNIFIED_RECORD)) {
103                 ZLOGE("Unmarshall unified record failed.");
104                 return E_READ_PARCEL_ERROR;
105             }
106             unifiedData.AddRecord(record);
107             records.emplace(keyStr, record);
108             continue;
109         }
110         if (isStartWithKey && isEntryItem) {
111             std::shared_ptr<std::map<std::string, ValueType>> entryRead =
112                 std::make_shared<std::map<std::string, ValueType>>();
113             if (!TLVUtil::ReadTlv(entryRead, data, TAG::TAG_INNER_ENTRIES)) {
114                 ZLOGE("Unmarshall inner entry failed.");
115                 return E_READ_PARCEL_ERROR;
116             }
117             innerEntries.emplace(keyStr, std::move(*entryRead));
118         }
119     }
120     return E_OK;
121 }
122 
BuildEntries(const std::vector<std::shared_ptr<UnifiedRecord>> & records,const std::string & unifiedKey,std::vector<Entry> & entries)123 Status DataHandler::BuildEntries(const std::vector<std::shared_ptr<UnifiedRecord>> &records,
124     const std::string &unifiedKey, std::vector<Entry> &entries)
125 {
126     for (const auto &record : records) {
127         std::string recordKey = unifiedKey + UD_KEY_SEPARATOR + record->GetUid();
128         auto recordEntries = record->GetInnerEntries();
129         for (auto &recordEntry : *recordEntries) {
130             std::string key = recordKey + UD_KEY_ENTRY_SEPARATOR + recordEntry.first;
131             std::vector<uint8_t> entryBytes;
132             auto entryTlv = TLVObject(entryBytes);
133             const std::shared_ptr<std::map<std::string, ValueType>> entryMap =
134                 std::make_shared<std::map<std::string, ValueType>>();
135             entryMap->insert_or_assign(recordEntry.first, recordEntry.second);
136             if (!TLVUtil::Writing(entryMap, entryTlv, TAG::TAG_INNER_ENTRIES)) {
137                 ZLOGI("Marshall inner entry failed.");
138                 return E_WRITE_PARCEL_ERROR;
139             }
140             std::vector<uint8_t> keyBytes = { key.begin(), key.end() };
141             Entry entry = { keyBytes, entryBytes };
142             entries.emplace_back(entry);
143         }
144         recordEntries->clear();
145         std::vector<uint8_t> recordBytes;
146         auto recordTlv = TLVObject(recordBytes);
147         if (!TLVUtil::Writing(record, recordTlv, TAG::TAG_UNIFIED_RECORD)) {
148             ZLOGI("Marshall unified record failed.");
149             return E_WRITE_PARCEL_ERROR;
150         }
151         std::vector<uint8_t> keyBytes = { recordKey.begin(), recordKey.end() };
152         Entry entry = { keyBytes, recordBytes };
153         entries.emplace_back(entry);
154     }
155     return E_OK;
156 }
157 } // namespace UDMF::OHOS