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