• 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 
16 #include "relational_store_utils.h"
17 #include "native_log.h"
18 #include "rdb_store.h"
19 
20 const int64_t UI64TOUI8 = 8;
21 const int64_t BITNUMOFUI64 = 64;
22 
23 namespace OHOS {
24 namespace Relational {
ToCCryptoParam(CryptoParam param)25     OHOS::NativeRdb::RdbStoreConfig::CryptoParam ToCCryptoParam(CryptoParam param)
26     {
27         auto cryptoParam = OHOS::NativeRdb::RdbStoreConfig::CryptoParam();
28         cryptoParam.iterNum = param.iterNum;
29         cryptoParam.encryptAlgo = param.encryptAlgo;
30         cryptoParam.hmacAlgo = param.hmacAlgo;
31         cryptoParam.kdfAlgo = param.kdfAlgo;
32         cryptoParam.cryptoPageSize = param.cryptoPageSize;
33         cryptoParam.encryptKey_ = CArrUI8ToVector(param.encryptKey);
34         return cryptoParam;
35     }
36 
MallocCString(const std::string & origin)37     char* MallocCString(const std::string& origin)
38     {
39         if (origin.empty()) {
40             return nullptr;
41         }
42         auto len = origin.length() + 1;
43         char* res = static_cast<char*>(malloc(sizeof(char) * len));
44         if (res == nullptr) {
45             return nullptr;
46         }
47         return std::char_traits<char>::copy(res, origin.c_str(), len);
48     }
49 
ValueTypeToValueObjectBlob(const ValueType & value)50     NativeRdb::ValueObject ValueTypeToValueObjectBlob(const ValueType& value)
51     {
52         std::vector<uint8_t> blob = std::vector<uint8_t>();
53         if (value.Uint8Array.head == nullptr) {
54             return NativeRdb::ValueObject(blob);
55         }
56         for (int64_t j = 0; j < value.Uint8Array.size; j++) {
57             blob.push_back(value.Uint8Array.head[j]);
58         }
59         return NativeRdb::ValueObject(blob);
60     }
61 
ValueTypeToValueObjectAsset(const ValueType & value)62     NativeRdb::ValueObject ValueTypeToValueObjectAsset(const ValueType& value)
63     {
64         std::string modifyTime = value.asset.modifyTime;
65         std::string size = value.asset.size;
66         NativeRdb::ValueObject::Asset asset = {
67             .status = value.asset.status,
68             .name = value.asset.name,
69             .uri = value.asset.uri,
70             .createTime = value.asset.createTime,
71             .modifyTime = modifyTime,
72             .size = size,
73             .hash = modifyTime + "_" + size,
74             .path = value.asset.path
75         };
76         return NativeRdb::ValueObject(asset);
77     }
78 
ValueTypeToValueObjectAssets(const ValueType & value)79     NativeRdb::ValueObject ValueTypeToValueObjectAssets(const ValueType& value)
80     {
81         std::vector<NativeRdb::ValueObject::Asset> assets = std::vector<NativeRdb::ValueObject::Asset>();
82         if (value.assets.head == nullptr) {
83             return assets;
84         }
85         for (int64_t j = 0; j < value.assets.size; j++) {
86             Asset asset = value.assets.head[j];
87             std::string modifyTime = asset.modifyTime;
88             std::string size = asset.size;
89             NativeRdb::ValueObject::Asset nativeAsset = {
90                 .status = asset.status,
91                 .name = asset.name,
92                 .uri = asset.uri,
93                 .createTime = asset.createTime,
94                 .modifyTime = modifyTime,
95                 .size = size,
96                 .hash = modifyTime + "_" + size,
97                 .path = asset.path
98             };
99             assets.push_back(nativeAsset);
100         }
101         return NativeRdb::ValueObject(assets);
102     }
103 
ValueTypeToValueObject(const ValueType & value)104     NativeRdb::ValueObject ValueTypeToValueObject(const ValueType& value)
105     {
106         NativeRdb::ValueObject valueObject;
107         switch (value.tag) {
108             case TYPE_NULL: {
109                 valueObject = NativeRdb::ValueObject();
110                 break;
111             }
112             case TYPE_INT: {
113                 valueObject = NativeRdb::ValueObject(value.integer);
114                 break;
115             }
116             case TYPE_DOU: {
117                 valueObject = NativeRdb::ValueObject(value.dou);
118                 break;
119             }
120             case TYPE_STR: {
121                 if (value.string == nullptr) {
122                     LOGE("string value is nullptr");
123                     break;
124                 }
125                 valueObject = NativeRdb::ValueObject(value.string);
126                 break;
127             }
128             case TYPE_BOOL: {
129                 valueObject = NativeRdb::ValueObject(value.boolean);
130                 break;
131             }
132             case TYPE_BLOB: {
133                 valueObject = ValueTypeToValueObjectBlob(value);
134                 break;
135             }
136             case TYPE_ASSET: {
137                 valueObject = ValueTypeToValueObjectAsset(value);
138                 break;
139             }
140             case TYPE_ASSETS: {
141                 valueObject = ValueTypeToValueObjectAssets(value);
142                 break;
143             }
144             default:
145                 valueObject = NativeRdb::ValueObject();
146                 break;
147         }
148         return valueObject;
149     }
150 
ValueTypeExToValueObjectBlob(const ValueTypeEx & value)151     NativeRdb::ValueObject ValueTypeExToValueObjectBlob(const ValueTypeEx& value)
152     {
153         std::vector<uint8_t> blob = std::vector<uint8_t>();
154         if (value.uint8Array.head == nullptr) {
155             LOGE("the array head is nullptr");
156             return NativeRdb::ValueObject(blob);
157         }
158         for (int64_t j = 0; j < value.uint8Array.size; j++) {
159             blob.push_back(value.uint8Array.head[j]);
160         }
161         return NativeRdb::ValueObject(blob);
162     }
163 
ValueTypeExToValueObjectAsset(const ValueTypeEx & value)164     NativeRdb::ValueObject ValueTypeExToValueObjectAsset(const ValueTypeEx& value)
165     {
166         std::string modifyTime = value.asset.modifyTime;
167         std::string size = value.asset.size;
168         NativeRdb::ValueObject::Asset asset = {
169             .status = value.asset.status,
170             .name = value.asset.name,
171             .uri = value.asset.uri,
172             .createTime = value.asset.createTime,
173             .modifyTime = modifyTime,
174             .size = size,
175             .hash = modifyTime + "_" + size,
176             .path = value.asset.path
177         };
178         return NativeRdb::ValueObject(asset);
179     }
180 
ValueTypeExToValueObjectAssets(const ValueTypeEx & value)181     NativeRdb::ValueObject ValueTypeExToValueObjectAssets(const ValueTypeEx& value)
182     {
183         std::vector<NativeRdb::ValueObject::Asset> assets = std::vector<NativeRdb::ValueObject::Asset>();
184         if (value.assets.head == nullptr) {
185             LOGE("the assets head is nullptr");
186             return NativeRdb::ValueObject(assets);
187         }
188         for (int64_t j = 0; j < value.assets.size; j++) {
189             Asset asset = value.assets.head[j];
190             std::string modifyTime = asset.modifyTime;
191             std::string size = asset.size;
192             NativeRdb::ValueObject::Asset nativeAsset = {
193                 .status = asset.status,
194                 .name = asset.name,
195                 .uri = asset.uri,
196                 .createTime = asset.createTime,
197                 .modifyTime = modifyTime,
198                 .size = size,
199                 .hash = modifyTime + "_" + size,
200                 .path = asset.path
201             };
202             assets.push_back(nativeAsset);
203         }
204         return NativeRdb::ValueObject(assets);
205     }
206 
ValueTypeExToValueObjectFloatArr(const ValueTypeEx & value)207     NativeRdb::ValueObject ValueTypeExToValueObjectFloatArr(const ValueTypeEx& value)
208     {
209         std::vector<float> arr = std::vector<float>();
210         if (value.floatArray.head == nullptr) {
211             LOGE("the floatArray head is nullptr");
212             return NativeRdb::ValueObject(arr);
213         }
214         for (int64_t j = 0; j < value.floatArray.size; j++) {
215             arr.push_back(value.floatArray.head[j]);
216         }
217         return NativeRdb::ValueObject(arr);
218     }
219 
ValueTypeExToValueObjectBigInt(const ValueTypeEx & value)220     NativeRdb::ValueObject ValueTypeExToValueObjectBigInt(const ValueTypeEx& value)
221     {
222         std::vector<uint64_t> arr = std::vector<uint64_t>();
223         int64_t firstSize = (value.bigInt.value.size % UI64TOUI8 == 0) ? UI64TOUI8 :
224             (value.bigInt.value.size % UI64TOUI8);
225         for (int64_t i = 0; i < ((value.bigInt.value.size + UI64TOUI8 - 1) / UI64TOUI8); i++) {
226             uint64_t tempValue = 0;
227             if (i == 0) {
228                 for (int64_t j = 0; j < firstSize; j++) {
229                     tempValue |=
230                         (static_cast<uint64_t>(value.bigInt.value.head[j]) << (UI64TOUI8 * (firstSize -j - 1)));
231                 }
232             } else {
233                 for (int64_t j = 0; j < UI64TOUI8; j++) {
234                     tempValue |=
235                         (static_cast<uint64_t>(value.bigInt.value.head[UI64TOUI8 * (i - 1) + firstSize + j]) <<
236                         (UI64TOUI8 * ((value.bigInt.value.size - (UI64TOUI8 * (i - 1) + firstSize + j) - 1) %
237                         UI64TOUI8)));
238                 }
239             }
240             arr.push_back(tempValue);
241         }
242         return NativeRdb::ValueObject(NativeRdb::ValueObject::BigInt(static_cast<int32_t>(value.bigInt.sign),
243             std::move(arr)));
244     }
245 
ValueTypeExToValueObject(const ValueTypeEx & value)246     NativeRdb::ValueObject ValueTypeExToValueObject(const ValueTypeEx& value)
247     {
248         NativeRdb::ValueObject valueObject;
249         switch (value.tag) {
250             case TYPE_NULL: {
251                 valueObject = NativeRdb::ValueObject();
252                 break;
253             }
254             case TYPE_INT: {
255                 valueObject = NativeRdb::ValueObject(value.integer);
256                 break;
257             }
258             case TYPE_DOU: {
259                 valueObject = NativeRdb::ValueObject(value.dou);
260                 break;
261             }
262             case TYPE_STR: {
263                 valueObject = NativeRdb::ValueObject(value.string);
264                 break;
265             }
266             case TYPE_BOOL: {
267                 valueObject = NativeRdb::ValueObject(value.boolean);
268                 break;
269             }
270             case TYPE_BLOB: {
271                 valueObject = ValueTypeExToValueObjectBlob(value);
272                 break;
273             }
274             case TYPE_ASSET: {
275                 valueObject = ValueTypeExToValueObjectAsset(value);
276                 break;
277             }
278             case TYPE_ASSETS: {
279                 valueObject = ValueTypeExToValueObjectAssets(value);
280                 break;
281             }
282             case TYPE_FLOATARR: {
283                 valueObject = ValueTypeExToValueObjectFloatArr(value);
284                 break;
285             }
286             case TYPE_BIGINT: {
287                 valueObject = ValueTypeExToValueObjectBigInt(value);
288                 break;
289             }
290             default:
291                 valueObject = NativeRdb::ValueObject();
292                 break;
293         }
294         return valueObject;
295     }
296 
ValueObjectToValueTypeAsset(const NativeRdb::ValueObject & object)297     ValueType ValueObjectToValueTypeAsset(const NativeRdb::ValueObject& object)
298     {
299         NativeRdb::ValueObject::Asset val;
300         object.GetAsset(val);
301         Asset asset = Asset {
302             .name = MallocCString(val.name),
303             .uri = MallocCString(val.uri),
304             .path = MallocCString(val.path),
305             .createTime = MallocCString(val.createTime),
306             .modifyTime = MallocCString(val.modifyTime),
307             .size = MallocCString(val.size),
308             .status = val.status
309         };
310         return ValueType {.asset = asset, .tag = TYPE_ASSET};
311     }
312 
ValueObjectToValueTypeAssets(const NativeRdb::ValueObject & object)313     ValueType ValueObjectToValueTypeAssets(const NativeRdb::ValueObject& object)
314     {
315         NativeRdb::ValueObject::Assets val;
316         object.GetAssets(val);
317         if (val.size() == 0) {
318             return ValueType {.assets = Assets{nullptr, -1}, .tag = TYPE_ASSETS};
319         }
320         Assets assets = Assets {.head = static_cast<Asset*>(malloc(val.size() * sizeof(Asset))), .size = val.size()};
321         if (assets.head == nullptr) {
322             return ValueType {.assets = Assets{nullptr, -1}, .tag = TYPE_ASSETS};
323         }
324         for (std::size_t i = 0; i < val.size(); i++) {
325             assets.head[i] = Asset {
326                 .name = MallocCString(val[i].name),
327                 .uri = MallocCString(val[i].uri),
328                 .path = MallocCString(val[i].path),
329                 .createTime = MallocCString(val[i].createTime),
330                 .modifyTime = MallocCString(val[i].modifyTime),
331                 .size = MallocCString(val[i].size),
332                 .status = static_cast<int32_t>(val[i].status)
333             };
334         }
335         return ValueType {.assets = assets, .tag = TYPE_ASSETS};
336     }
337 
ValueObjectToValueType(const NativeRdb::ValueObject & object)338     ValueType ValueObjectToValueType(const NativeRdb::ValueObject& object)
339     {
340         switch (object.GetType()) {
341             case NativeRdb::ValueObject::TYPE_NULL:
342                 return ValueType {.tag = TYPE_NULL};
343             case NativeRdb::ValueObject::TYPE_INT: {
344                 int64_t val;
345                 object.GetLong(val);
346                 return ValueType {.integer = val, .tag = TYPE_INT};
347             }
348             case NativeRdb::ValueObject::TYPE_DOUBLE: {
349                 double val;
350                 object.GetDouble(val);
351                 return ValueType {.dou = val, .tag = TYPE_DOU};
352             }
353             case NativeRdb::ValueObject::TYPE_STRING: {
354                 std::string val;
355                 object.GetString(val);
356                 return ValueType {.string = MallocCString(val), .tag = TYPE_STR};
357             }
358             case NativeRdb::ValueObject::TYPE_BOOL: {
359                 bool val;
360                 object.GetBool(val);
361                 return ValueType {.boolean = val, .tag = TYPE_BOOL};
362             }
363             case NativeRdb::ValueObject::TYPE_BLOB: {
364                 std::vector<uint8_t> val;
365                 object.GetBlob(val);
366                 if (val.size() == 0) {
367                     return ValueType {.Uint8Array = CArrUI8 {nullptr, -1}, .tag = TYPE_BLOB};
368                 }
369                 CArrUI8 arr = CArrUI8 {.head = static_cast<uint8_t*>(malloc(val.size() * sizeof(uint8_t))),
370                     .size = val.size()};
371                 if (arr.head == nullptr) {
372                     return ValueType {.Uint8Array = CArrUI8 {nullptr, -1}, .tag = TYPE_BLOB};
373                 }
374                 return ValueType {.Uint8Array = arr, .tag = TYPE_BLOB};
375             }
376             case NativeRdb::ValueObject::TYPE_ASSET: {
377                 return ValueObjectToValueTypeAsset(object);
378             }
379             case NativeRdb::ValueObject::TYPE_ASSETS: {
380                 return ValueObjectToValueTypeAssets(object);
381             }
382             case NativeRdb::ValueObject::TYPE_BUTT:
383                 return ValueType {.tag = 128};
384             default:
385                 return ValueType {.tag = TYPE_NULL};
386         }
387     }
388 
ValueObjectToValueTypeExBlob(const NativeRdb::ValueObject & object)389     ValueTypeEx ValueObjectToValueTypeExBlob(const NativeRdb::ValueObject& object)
390     {
391         std::vector<uint8_t> val = static_cast<std::vector<uint8_t>>(object);
392         auto size = val.size();
393         if (size == 0) {
394             return ValueTypeEx {.uint8Array = CArrUI8 {nullptr, ERROR_VALUE}, .tag = TYPE_BLOB};
395         }
396         CArrUI8 arr = CArrUI8 {.head = static_cast<uint8_t*>(malloc(size * sizeof(uint8_t))),
397             .size = size};
398         if (arr.head == nullptr) {
399             return ValueTypeEx {.uint8Array = CArrUI8 {nullptr, ERROR_VALUE}, .tag = TYPE_BLOB};
400         }
401         for (size_t i = 0; i < size; i++) {
402             arr.head[i] = val[i];
403         }
404         return ValueTypeEx {.uint8Array = arr, .tag = TYPE_BLOB};
405     }
406 
ValueObjectToValueTypeExAsset(const NativeRdb::ValueObject & object)407     ValueTypeEx ValueObjectToValueTypeExAsset(const NativeRdb::ValueObject& object)
408     {
409         NativeRdb::ValueObject::Asset val = static_cast<NativeRdb::ValueObject::Asset>(object);
410         Asset asset = Asset {
411             .name = MallocCString(val.name),
412             .uri = MallocCString(val.uri),
413             .path = MallocCString(val.path),
414             .createTime = MallocCString(val.createTime),
415             .modifyTime = MallocCString(val.modifyTime),
416             .size = MallocCString(val.size),
417             .status = val.status
418         };
419         return ValueTypeEx {.asset = asset, .tag = TYPE_ASSET};
420     }
421 
ValueObjectToValueTypeExAssets(const NativeRdb::ValueObject & object)422     ValueTypeEx ValueObjectToValueTypeExAssets(const NativeRdb::ValueObject& object)
423     {
424         NativeRdb::ValueObject::Assets val = static_cast<NativeRdb::ValueObject::Assets>(object);
425         if (val.size() == 0) {
426             return ValueTypeEx {.assets = Assets{nullptr, ERROR_VALUE}, .tag = TYPE_ASSETS};
427         }
428         Assets assets = Assets {.head = static_cast<Asset*>(malloc(val.size() * sizeof(Asset))), .size = val.size()};
429         if (assets.head == nullptr) {
430             return ValueTypeEx {.assets = Assets{nullptr, ERROR_VALUE}, .tag = TYPE_ASSETS};
431         }
432         for (std::size_t i = 0; i < val.size(); i++) {
433             assets.head[i] = Asset {
434                 .name = MallocCString(val[i].name),
435                 .uri = MallocCString(val[i].uri),
436                 .path = MallocCString(val[i].path),
437                 .createTime = MallocCString(val[i].createTime),
438                 .modifyTime = MallocCString(val[i].modifyTime),
439                 .size = MallocCString(val[i].size),
440                 .status = static_cast<int32_t>(val[i].status)
441             };
442         }
443         return ValueTypeEx {.assets = assets, .tag = TYPE_ASSETS};
444     }
445 
ValueObjectToValueTypeExFloatArray(const NativeRdb::ValueObject & object)446     ValueTypeEx ValueObjectToValueTypeExFloatArray(const NativeRdb::ValueObject& object)
447     {
448         std::vector<float> val = static_cast<std::vector<float>>(object);
449         auto size = val.size();
450         if (size == 0) {
451             return ValueTypeEx {.floatArray = CArrFloat {nullptr, ERROR_VALUE}, .tag = TYPE_FLOATARR};
452         }
453         CArrFloat arr = CArrFloat {.head = static_cast<float*>(malloc(size * sizeof(float))),
454             .size = size};
455         if (arr.head == nullptr) {
456             return ValueTypeEx {.floatArray = CArrFloat {nullptr, ERROR_VALUE}, .tag = TYPE_FLOATARR};
457         }
458         for (size_t i = 0; i < size; i++) {
459             arr.head[i] = val[i];
460         }
461         return ValueTypeEx {.floatArray = arr, .tag = TYPE_FLOATARR};
462     }
463 
ValueObjectToValueTypeExBigInt(const NativeRdb::ValueObject & object)464     ValueTypeEx ValueObjectToValueTypeExBigInt(const NativeRdb::ValueObject& object)
465     {
466         NativeRdb::ValueObject::BigInt bigInt = static_cast<NativeRdb::ValueObject::BigInt>(object);
467         int32_t sign = bigInt.Sign();
468         std::vector<uint64_t> value = bigInt.Value();
469         size_t size = value.size();
470         if (size == 0) {
471             return ValueTypeEx {.bigInt = BigInt {CArrUI8 {nullptr, ERROR_VALUE}, ERROR_VALUE}, .tag = TYPE_BIGINT};
472         }
473         uint8_t *head = static_cast<uint8_t*>(calloc(UI64TOUI8 * size, sizeof(uint8_t)));
474         if (head == nullptr) {
475             return ValueTypeEx {.bigInt = BigInt {CArrUI8 {nullptr, ERROR_VALUE}, ERROR_VALUE}, .tag = TYPE_BIGINT};
476         }
477         for (size_t i = 0; i < size; i++) {
478             for (size_t j = 0; j < UI64TOUI8; j++) {
479                 head[UI64TOUI8 * i + j] |= (value[i] >> (BITNUMOFUI64 - (UI64TOUI8 * (j + 1))));
480             }
481         }
482         return ValueTypeEx {.bigInt = BigInt {CArrUI8 {head, UI64TOUI8 * size}, sign}, .tag = TYPE_BIGINT};
483     }
484 
ValueObjectToValueTypeEx(const NativeRdb::ValueObject & object)485     ValueTypeEx ValueObjectToValueTypeEx(const NativeRdb::ValueObject& object)
486     {
487         switch (object.GetType()) {
488             case NativeRdb::ValueObject::TYPE_NULL:
489                 return ValueTypeEx {.tag = TYPE_NULL};
490             case NativeRdb::ValueObject::TYPE_INT: {
491                 return ValueTypeEx {.integer = static_cast<int64_t>(object), .tag = TYPE_INT};
492             }
493             case NativeRdb::ValueObject::TYPE_DOUBLE: {
494                 return ValueTypeEx {.dou = static_cast<double>(object), .tag = TYPE_DOU};
495             }
496             case NativeRdb::ValueObject::TYPE_STRING: {
497                 return ValueTypeEx {.string = MallocCString(static_cast<std::string>(object)), .tag = TYPE_STR};
498             }
499             case NativeRdb::ValueObject::TYPE_BOOL: {
500                 return ValueTypeEx {.boolean = static_cast<bool>(object), .tag = TYPE_BOOL};
501             }
502             case NativeRdb::ValueObject::TYPE_BLOB: {
503                 return ValueObjectToValueTypeExBlob(object);
504             }
505             case NativeRdb::ValueObject::TYPE_ASSET: {
506                 return ValueObjectToValueTypeExAsset(object);
507             }
508             case NativeRdb::ValueObject::TYPE_ASSETS: {
509                 return ValueObjectToValueTypeExAssets(object);
510             }
511             case NativeRdb::ValueObject::TYPE_VECS: {
512                 return ValueObjectToValueTypeExFloatArray(object);
513             }
514             case NativeRdb::ValueObject::TYPE_BIGINT: {
515                 return ValueObjectToValueTypeExBigInt(object);
516             }
517             case NativeRdb::ValueObject::TYPE_BUTT:
518                 return ValueTypeEx {.tag = 128};
519             default:
520                 return ValueTypeEx {.tag = TYPE_NULL};
521         }
522     }
523 
VectorToCArrStr(const std::vector<std::string> & devices)524     CArrStr VectorToCArrStr(const std::vector<std::string> &devices)
525     {
526         CArrStr cArrStr{0};
527         if (devices.size() == 0) {
528             return cArrStr;
529         }
530         cArrStr.head = static_cast<char**>(malloc(sizeof(char*) * devices.size()));
531         if (cArrStr.head == nullptr) {
532             return cArrStr;
533         }
534         for (size_t i = 0; i < devices.size(); i++) {
535             cArrStr.head[i] = MallocCString(devices[i]);
536         }
537         cArrStr.size = static_cast<int64_t>(devices.size());
538         return cArrStr;
539     }
540 
CArrStrToVector(CArrStr carr)541     std::vector<std::string> CArrStrToVector(CArrStr carr)
542     {
543         std::vector<std::string> arr;
544         for (int i = 0; i < carr.size; i++) {
545             if (carr.head[i] != nullptr) {
546                 arr.push_back(carr.head[i]);
547             } else {
548                 arr.push_back(std::string());
549             }
550         }
551         return arr;
552     }
553 
CArrUI8ToVector(CArrUI8 carr)554     std::vector<uint8_t> CArrUI8ToVector(CArrUI8 carr)
555     {
556         std::vector<std::uint8_t> arr;
557         for (int i = 0; i < carr.size; i++) {
558             arr.push_back(carr.head[i]);
559         }
560         return arr;
561     }
562 
RetPRIKeyTypeToVariant(RetPRIKeyType & value)563     std::variant<std::monostate, std::string, int64_t, double> RetPRIKeyTypeToVariant(RetPRIKeyType &value)
564     {
565         switch (value.tag) {
566             case NativeRdb::ValueObject::TYPE_INT:
567                 return std::variant<std::monostate, std::string, int64_t, double>(value.integer);
568             case NativeRdb::ValueObject::TYPE_DOUBLE:
569                 return std::variant<std::monostate, std::string, int64_t, double>(value.dou);
570             case NativeRdb::ValueObject::TYPE_STRING:
571                 return std::variant<std::monostate, std::string, int64_t, double>(value.string);
572             default:
573                 return std::variant<std::monostate, std::string, int64_t, double>(0);
574         }
575     }
576 
VariantToRetPRIKeyType(const std::variant<std::monostate,std::string,int64_t,double> & value)577     RetPRIKeyType VariantToRetPRIKeyType(const std::variant<std::monostate, std::string, int64_t, double> &value)
578     {
579         if (std::holds_alternative<int64_t>(value)) {
580             return RetPRIKeyType{ .integer = std::get<int64_t>(value), .dou = 0.0,
581                 .string = nullptr, .tag = NativeRdb::ValueObject::TYPE_INT };
582         } else if (std::holds_alternative<double>(value)) {
583             return RetPRIKeyType{ .integer = 0, .dou = std::get<double>(value),
584                 .string = nullptr, .tag = NativeRdb::ValueObject::TYPE_DOUBLE };
585         } else if (std::holds_alternative<std::string>(value)) {
586             return RetPRIKeyType{ .integer = 0, .dou = 0.0,
587                 .string = MallocCString(std::get<std::string>(value)), .tag = NativeRdb::ValueObject::TYPE_STRING };
588         } else {
589             return RetPRIKeyType{0};
590         }
591     }
592 
CArrPRIKeyTypeToPRIKeyArray(CArrPRIKeyType & cPrimaryKeys)593     std::vector<NativeRdb::RdbStore::PRIKey> CArrPRIKeyTypeToPRIKeyArray(CArrPRIKeyType &cPrimaryKeys)
594     {
595         std::vector<NativeRdb::RdbStore::PRIKey> res = std::vector<NativeRdb::RdbStore::PRIKey>();
596         for (int64_t i = 0; i < cPrimaryKeys.size; i++) {
597             res.push_back(RetPRIKeyTypeToVariant(cPrimaryKeys.head[i]));
598         }
599         return res;
600     }
601 
MapToModifyTime(std::map<NativeRdb::RdbStore::PRIKey,NativeRdb::RdbStore::Date> & map,int32_t & errCode)602     ModifyTime MapToModifyTime(std::map<NativeRdb::RdbStore::PRIKey, NativeRdb::RdbStore::Date> &map, int32_t &errCode)
603     {
604         ModifyTime modifyTime{0};
605         modifyTime.size = static_cast<int64_t>(map.size());
606         if (modifyTime.size == 0) {
607             return ModifyTime{0};
608         }
609         modifyTime.key = static_cast<RetPRIKeyType*>(malloc(sizeof(RetPRIKeyType) * modifyTime.size));
610         modifyTime.value = static_cast<uint64_t*>(malloc(sizeof(uint64_t) * modifyTime.size));
611         if (modifyTime.key == nullptr || modifyTime.value == nullptr) {
612             free(modifyTime.key);
613             free(modifyTime.value);
614             errCode = -1;
615             return ModifyTime{0};
616         }
617         int64_t index = 0;
618         for (auto it = map.begin(); it != map.end(); ++it) {
619             modifyTime.key[index] = VariantToRetPRIKeyType(it->first);
620             modifyTime.value[index] = static_cast<uint64_t>((it->second).date);
621             index++;
622         }
623         return modifyTime;
624     }
625 
VectorToCArrPRIKeyType(std::vector<DistributedRdb::RdbStoreObserver::PrimaryKey> arr)626     CArrPRIKeyType VectorToCArrPRIKeyType(std::vector<DistributedRdb::RdbStoreObserver::PrimaryKey> arr)
627     {
628         CArrPRIKeyType types{0};
629         if (arr.size() == 0) {
630             return types;
631         }
632         types.head = static_cast<RetPRIKeyType*>(malloc(sizeof(RetPRIKeyType) * arr.size()));
633         if (types.head == nullptr) {
634             return types;
635         }
636         for (size_t i = 0; i < arr.size(); i++) {
637             types.head[i] = VariantToRetPRIKeyType(arr[i]);
638         }
639         types.size = static_cast<int64_t>(arr.size());
640         return types;
641     }
642 
ToRetChangeInfo(const DistributedRdb::Origin & origin,DistributedRdb::RdbStoreObserver::ChangeInfo::iterator info)643     RetChangeInfo ToRetChangeInfo(const DistributedRdb::Origin &origin,
644         DistributedRdb::RdbStoreObserver::ChangeInfo::iterator info)
645     {
646         RetChangeInfo retInfo{0};
647         retInfo.table = MallocCString(info->first);
648         retInfo.type = origin.dataType;
649         retInfo.inserted = VectorToCArrPRIKeyType(info->
650             second[DistributedRdb::RdbStoreObserver::ChangeType::CHG_TYPE_INSERT]);
651         retInfo.updated = VectorToCArrPRIKeyType(info->
652             second[DistributedRdb::RdbStoreObserver::ChangeType::CHG_TYPE_UPDATE]);
653         retInfo.deleted = VectorToCArrPRIKeyType(info->
654             second[DistributedRdb::RdbStoreObserver::ChangeType::CHG_TYPE_DELETE]);
655         return retInfo;
656     }
657 
ToCArrRetChangeInfo(const DistributedRdb::Origin & origin,const DistributedRdb::RdbStoreObserver::PrimaryFields & fields,DistributedRdb::RdbStoreObserver::ChangeInfo && changeInfo)658     CArrRetChangeInfo ToCArrRetChangeInfo(const DistributedRdb::Origin &origin,
659         const DistributedRdb::RdbStoreObserver::PrimaryFields &fields,
660         DistributedRdb::RdbStoreObserver::ChangeInfo &&changeInfo)
661     {
662         CArrRetChangeInfo infos{0};
663         if (changeInfo.size() == 0) {
664             return infos;
665         }
666         infos.head = static_cast<RetChangeInfo*>(malloc(sizeof(RetChangeInfo) * changeInfo.size()));
667         if (infos.head == nullptr) {
668             return CArrRetChangeInfo{0};
669         }
670         int64_t index = 0;
671         for (auto it = changeInfo.begin(); it != changeInfo.end(); ++it) {
672             infos.head[index] = ToRetChangeInfo(origin, it);
673             index++;
674         }
675         infos.size = static_cast<int64_t>(changeInfo.size());
676         return infos;
677     }
678 
ToStatistic(DistributedRdb::Statistic statistic)679     CStatistic ToStatistic(DistributedRdb::Statistic statistic)
680     {
681         return CStatistic{ .total = statistic.total, .successful = statistic.success,
682             .failed = statistic.failed, .remained = statistic.untreated };
683     }
684 
ToCTableDetails(DistributedRdb::TableDetail detail)685     CTableDetails ToCTableDetails(DistributedRdb::TableDetail detail)
686     {
687         return CTableDetails{ .upload = ToStatistic(detail.upload), .download = ToStatistic(detail.download) };
688     }
689 
ToCDetails(DistributedRdb::TableDetails details)690     CDetails ToCDetails(DistributedRdb::TableDetails details)
691     {
692         if (details.size() == 0) {
693             return CDetails{0};
694         }
695         char** key = static_cast<char**>(malloc(sizeof(char*) * details.size()));
696         CTableDetails* value = static_cast<CTableDetails*>(malloc(sizeof(CTableDetails) * details.size()));
697         if (key == nullptr || value == nullptr) {
698             free(key);
699             free(value);
700             return CDetails{0};
701         }
702         int64_t index = 0;
703         for (auto it = details.begin(); it != details.end(); ++it) {
704             key[index] = MallocCString(it->first);
705             value[index] = ToCTableDetails(it->second);
706             index++;
707         }
708         return CDetails{ .key = key, .value = value, .size = details.size() };
709     }
710 
ToCProgressDetails(const DistributedRdb::Details & details)711     CProgressDetails ToCProgressDetails(const  DistributedRdb::Details &details)
712     {
713         if (details.empty()) {
714             return CProgressDetails{0};
715         }
716         DistributedRdb::ProgressDetail detail = details.begin() ->second;
717         return CProgressDetails{ .schedule = detail.progress, .code = detail.code,
718             .details = ToCDetails(detail.details) };
719     }
720 }
721 }