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