• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 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 
16 #include "raw_data_parser.h"
17 
18 #include <chrono>
19 
20 #include "multi_platform_endian.h"
21 
22 namespace OHOS::NativeRdb {
ParserRawData(const uint8_t * data,size_t length,Asset & asset)23 size_t RawDataParser::ParserRawData(const uint8_t *data, size_t length, Asset &asset)
24 {
25     size_t used = 0;
26     uint16_t size = 0;
27 
28     if (sizeof(ASSET_MAGIC) > length - used) {
29         return 0;
30     }
31     std::vector<uint8_t> alignData;
32     alignData.assign(data, data + sizeof(ASSET_MAGIC));
33     used += sizeof(ASSET_MAGIC);
34     auto hostMagicWord = Endian::LeToH(*(reinterpret_cast<decltype(&ASSET_MAGIC)>(alignData.data())));
35     if (hostMagicWord != ASSET_MAGIC) {
36         return 0;
37     }
38 
39     if (sizeof(size) > length - used) {
40         return 0;
41     }
42     alignData.assign(data + used, data + used + sizeof(size));
43     used += sizeof(size);
44     size = Endian::LeToH(*(reinterpret_cast<decltype(&size)>(alignData.data())));
45     if (size > length - used) {
46         return 0;
47     }
48     auto rawData = std::string(reinterpret_cast<const char *>(&data[used]), size);
49     InnerAsset innerAsset = InnerAsset(asset);
50     if (!innerAsset.Unmarshall(rawData)) {
51         return 0;
52     }
53     used += size;
54     return used;
55 }
56 
ParserRawData(const uint8_t * data,size_t length,Assets & assets)57 size_t RawDataParser::ParserRawData(const uint8_t *data, size_t length, Assets &assets)
58 {
59     size_t used = 0;
60     uint16_t num = 0;
61 
62     if (sizeof(ASSETS_MAGIC) > length - used) {
63         return 0;
64     }
65     std::vector<uint8_t> alignData;
66     alignData.assign(data, data + sizeof (ASSETS_MAGIC));
67     used += sizeof (ASSETS_MAGIC);
68     auto hostMagicWord = Endian::LeToH(*(reinterpret_cast<decltype(&ASSETS_MAGIC)>(alignData.data())));
69     if (hostMagicWord != ASSETS_MAGIC) {
70         return 0;
71     }
72 
73     if (sizeof(num) > length - used) {
74         return 0;
75     }
76     alignData.assign(data, data + sizeof(num));
77     num = Endian::LeToH(*(reinterpret_cast<decltype(&num)>(alignData.data())));
78     used += sizeof(num);
79     uint16_t count = 0;
80     while (used < length && count < num) {
81         Asset asset;
82         auto dataLen = ParserRawData(&data[used], length - used, asset);
83         if (dataLen == 0) {
84             break;
85         }
86         used += dataLen;
87         assets.push_back(std::move(asset));
88         count++;
89     }
90     return used;
91 }
92 
PackageRawData(const Asset & asset)93 std::vector<uint8_t> RawDataParser::PackageRawData(const Asset &asset)
94 {
95     std::vector<uint8_t> rawData;
96     InnerAsset innerAsset(const_cast<Asset &>(asset));
97     auto data = Serializable::Marshall(innerAsset);
98     uint16_t size = Endian::HToLe((uint16_t)data.length());
99     auto leMagic = Endian::HToLe(ASSET_MAGIC);
100     auto magicU8 = reinterpret_cast<uint8_t *>(const_cast<uint32_t *>(&leMagic));
101     rawData.insert(rawData.end(), magicU8, magicU8 + sizeof(ASSET_MAGIC));
102     rawData.insert(rawData.end(), reinterpret_cast<uint8_t *>(&size),
103         reinterpret_cast<uint8_t *>(&size) + sizeof(size));
104     rawData.insert(rawData.end(), data.begin(), data.end());
105     return rawData;
106 }
107 
PackageRawData(const Assets & assets)108 std::vector<uint8_t> RawDataParser::PackageRawData(const Assets &assets)
109 {
110     std::vector<uint8_t> rawData;
111     uint16_t num = uint16_t(assets.size());
112     auto leMagic = Endian::HToLe(ASSETS_MAGIC);
113     auto magicU8 = reinterpret_cast<uint8_t *>(const_cast<uint32_t *>(&leMagic));
114     rawData.insert(rawData.end(), magicU8, magicU8 + sizeof(ASSETS_MAGIC));
115     rawData.insert(rawData.end(), reinterpret_cast<uint8_t *>(&num), reinterpret_cast<uint8_t *>(&num) + sizeof(num));
116     for (auto &asset : assets) {
117         auto data = PackageRawData(asset);
118         rawData.insert(rawData.end(), data.begin(), data.end());
119     }
120     return rawData;
121 }
122 
ParserRawData(const uint8_t * data,size_t length,std::map<std::string,Asset> & assets)123 size_t RawDataParser::ParserRawData(const uint8_t *data, size_t length, std::map<std::string, Asset> &assets)
124 {
125     Assets res;
126     auto used = ParserRawData(data, length, res);
127     auto it = res.begin();
128     while (it != res.end()) {
129         assets.insert({ it->name, *it });
130         it++;
131     }
132     return used;
133 }
134 
PackageRawData(const std::map<std::string,Asset> & assets)135 std::vector<uint8_t> RawDataParser::PackageRawData(const std::map<std::string, Asset> &assets)
136 {
137     Assets res;
138     for (auto asset : assets) {
139         res.push_back(asset.second);
140     }
141     return PackageRawData(res);
142 }
143 
Marshal(Serializable::json & node) const144 bool RawDataParser::InnerAsset::Marshal(Serializable::json &node) const
145 {
146     SetValue(node[GET_NAME(version)], asset_.version);
147     SetValue(node[GET_NAME(expiresTime)], asset_.expiresTime);
148     SetValue(node[GET_NAME(id)], asset_.id);
149     SetValue(node[GET_NAME(name)], asset_.name);
150     SetValue(node[GET_NAME(uri)], asset_.uri);
151     SetValue(node[GET_NAME(createTime)], asset_.createTime);
152     SetValue(node[GET_NAME(modifyTime)], asset_.modifyTime);
153     SetValue(node[GET_NAME(size)], asset_.size);
154     SetValue(node[GET_NAME(hash)], asset_.hash);
155     SetValue(node[GET_NAME(path)], asset_.path);
156     SetValue(node[GET_NAME(status)], asset_.status);
157     return true;
158 }
Unmarshal(const Serializable::json & node)159 bool RawDataParser::InnerAsset::Unmarshal(const Serializable::json &node)
160 {
161     bool ret = true;
162     ret = GetValue(node, GET_NAME(version), asset_.version) && ret;
163     ret = GetValue(node, GET_NAME(expiresTime), asset_.expiresTime) && ret;
164     ret = GetValue(node, GET_NAME(id), asset_.id) && ret;
165     ret = GetValue(node, GET_NAME(name), asset_.name) && ret;
166     ret = GetValue(node, GET_NAME(uri), asset_.uri) && ret;
167     ret = GetValue(node, GET_NAME(createTime), asset_.createTime) && ret;
168     ret = GetValue(node, GET_NAME(modifyTime), asset_.modifyTime) && ret;
169     ret = GetValue(node, GET_NAME(size), asset_.size) && ret;
170     ret = GetValue(node, GET_NAME(hash), asset_.hash) && ret;
171     ret = GetValue(node, GET_NAME(path), asset_.path) && ret;
172     ret = GetValue(node, GET_NAME(status), asset_.status) && ret;
173     if (asset_.status == AssetValue::STATUS_DOWNLOADING &&
174         asset_.expiresTime < static_cast<uint64_t>(std::chrono::system_clock::now().time_since_epoch().count())) {
175         asset_.status = AssetValue::STATUS_ABNORMAL;
176     }
177     return ret;
178 }
179 } // namespace OHOS::NativeRdb