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