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 #define LOG_TAG "DataValue"
16
17 #include "oh_data_value.h"
18 #include "oh_data_define.h"
19 #include "relational_store_error_code.h"
20 #include "relational_asset.h"
21 #include "logger.h"
22
23 using namespace OHOS::RdbNdk;
24 using namespace OHOS::NativeRdb;
25
26 constexpr int32_t TO_OH_TYPE[] = {
27 OH_ColumnType::TYPE_NULL,
28 OH_ColumnType::TYPE_INT64,
29 OH_ColumnType::TYPE_REAL,
30 OH_ColumnType::TYPE_TEXT,
31 OH_ColumnType::TYPE_INT64,
32 OH_ColumnType::TYPE_BLOB,
33 OH_ColumnType::TYPE_ASSET,
34 OH_ColumnType::TYPE_ASSETS,
35 OH_ColumnType::TYPE_FLOAT_VECTOR,
36 OH_ColumnType::TYPE_UNLIMITED_INT,
37 };
38
39 static constexpr int32_t TO_OH_TYPE_SIZE = sizeof(TO_OH_TYPE) / sizeof(TO_OH_TYPE[0]);
40
CheckValueType(const OH_Data_Value * value,int32_t type)41 static int CheckValueType(const OH_Data_Value *value, int32_t type)
42 {
43 if (value == nullptr || !value->IsValid()) {
44 return RDB_E_INVALID_ARGS;
45 }
46 int32_t valueType = value->value_.GetType();
47 if (valueType == ValueObject::TYPE_NULL && type == ValueObject::TYPE_NULL) {
48 return RDB_OK;
49 }
50 if (valueType == ValueObject::TYPE_NULL) {
51 LOG_ERROR("type mismatch, value type is null, get type=%{public}d", type);
52 return RDB_E_DATA_TYPE_NULL;
53 }
54 if (valueType != type) {
55 LOG_ERROR("type mismatch, value type=%{public}d, get type=%{public}d", valueType, type);
56 return RDB_E_TYPE_MISMATCH;
57 }
58 return RDB_OK;
59 }
60
OH_Value_Create(void)61 OH_Data_Value *OH_Value_Create(void)
62 {
63 OH_Data_Value *value = new (std::nothrow) OH_Data_Value;
64 if (value == nullptr) {
65 return nullptr;
66 }
67 return value;
68 }
69
OH_Value_Destroy(OH_Data_Value * value)70 int OH_Value_Destroy(OH_Data_Value *value)
71 {
72 if (value == nullptr || !value->IsValid()) {
73 return RDB_E_INVALID_ARGS;
74 }
75 delete value;
76 return RDB_OK;
77 }
78
OH_Value_PutNull(OH_Data_Value * value)79 int OH_Value_PutNull(OH_Data_Value *value)
80 {
81 if (value == nullptr || !value->IsValid()) {
82 return RDB_E_INVALID_ARGS;
83 }
84 value->value_.value = ValueObject::Nil{};
85 return RDB_OK;
86 }
87
OH_Value_PutInt(OH_Data_Value * value,int64_t val)88 int OH_Value_PutInt(OH_Data_Value *value, int64_t val)
89 {
90 if (value == nullptr || !value->IsValid()) {
91 return RDB_E_INVALID_ARGS;
92 }
93 value->value_.value = val;
94 return RDB_OK;
95 }
96
OH_Value_PutReal(OH_Data_Value * value,double val)97 int OH_Value_PutReal(OH_Data_Value *value, double val)
98 {
99 if (value == nullptr || !value->IsValid()) {
100 return RDB_E_INVALID_ARGS;
101 }
102 value->value_.value = val;
103 return RDB_OK;
104 }
105
OH_Value_PutText(OH_Data_Value * value,const char * val)106 int OH_Value_PutText(OH_Data_Value *value, const char *val)
107 {
108 if (value == nullptr || !value->IsValid()) {
109 return RDB_E_INVALID_ARGS;
110 }
111 value->value_.value = std::string(val);
112 return RDB_OK;
113 }
114
OH_Value_PutBlob(OH_Data_Value * value,const unsigned char * val,size_t length)115 int OH_Value_PutBlob(OH_Data_Value *value, const unsigned char *val, size_t length)
116 {
117 if (value == nullptr || !value->IsValid() || val == nullptr) {
118 return RDB_E_INVALID_ARGS;
119 }
120 value->value_.value = std::vector<uint8_t>{ val, val + length };
121 return RDB_OK;
122 }
123
OH_Value_PutAsset(OH_Data_Value * value,const Data_Asset * val)124 int OH_Value_PutAsset(OH_Data_Value *value, const Data_Asset *val)
125 {
126 if (value == nullptr || !value->IsValid() || val == nullptr) {
127 return RDB_E_INVALID_ARGS;
128 }
129 value->value_.value = val->asset_;
130 return RDB_OK;
131 }
132
OH_Value_PutAssets(OH_Data_Value * value,const Data_Asset * const * val,size_t length)133 int OH_Value_PutAssets(OH_Data_Value *value, const Data_Asset * const * val, size_t length)
134 {
135 if (value == nullptr || !value->IsValid() || val == nullptr || length == 0) {
136 return RDB_E_INVALID_ARGS;
137 }
138 ValueObject::Assets assets;
139 for (size_t i = 0; i < length; i++) {
140 if (val[i] != nullptr) {
141 assets.push_back(val[i]->asset_);
142 }
143 }
144 value->value_.value = assets;
145 return RDB_OK;
146 }
147
OH_Value_PutFloatVector(OH_Data_Value * value,const float * val,size_t length)148 int OH_Value_PutFloatVector(OH_Data_Value *value, const float *val, size_t length)
149 {
150 if (value == nullptr || !value->IsValid() || val == nullptr) {
151 return RDB_E_INVALID_ARGS;
152 }
153 std::vector<float> valVec = std::vector<float>{ val, val + length };
154 value->value_.value = valVec;
155 return RDB_OK;
156 }
157
OH_Value_PutUnlimitedInt(OH_Data_Value * value,int sign,const uint64_t * trueForm,size_t length)158 int OH_Value_PutUnlimitedInt(OH_Data_Value *value, int sign, const uint64_t *trueForm, size_t length)
159 {
160 if (value == nullptr || !value->IsValid() || (sign != 0 && sign != 1) || trueForm == nullptr) {
161 return RDB_E_INVALID_ARGS;
162 }
163 ValueObject::BigInt bigNumber(sign, {trueForm, trueForm + length});
164 value->value_.value = bigNumber;
165 return RDB_OK;
166 }
167
OH_Value_GetType(OH_Data_Value * value,OH_ColumnType * type)168 int OH_Value_GetType(OH_Data_Value *value, OH_ColumnType *type)
169 {
170 if (value == nullptr || !value->IsValid() || type == nullptr) {
171 return RDB_E_INVALID_ARGS;
172 }
173 auto valueType = value->value_.GetType();
174 if (valueType < TO_OH_TYPE_SIZE) {
175 *type = static_cast<OH_ColumnType>(TO_OH_TYPE[valueType]);
176 return RDB_OK;
177 }
178 return RDB_E_INVALID_ARGS;
179 }
180
OH_Value_IsNull(OH_Data_Value * value,bool * val)181 int OH_Value_IsNull(OH_Data_Value *value, bool *val)
182 {
183 if (value == nullptr || !value->IsValid() || val == nullptr) {
184 return RDB_E_INVALID_ARGS;
185 }
186 *val = (value->value_.GetType() == ValueObject::TYPE_NULL);
187 return RDB_OK;
188 }
189
OH_Value_GetInt(OH_Data_Value * value,int64_t * val)190 int OH_Value_GetInt(OH_Data_Value *value, int64_t *val)
191 {
192 if (val == nullptr) {
193 return RDB_E_INVALID_ARGS;
194 }
195 int checkRet = CheckValueType(value, ValueObject::TYPE_INT);
196 if (checkRet != RDB_OK) {
197 return checkRet;
198 }
199 *val = value->value_;
200 return RDB_OK;
201 }
202
OH_Value_GetReal(OH_Data_Value * value,double * val)203 int OH_Value_GetReal(OH_Data_Value *value, double *val)
204 {
205 if (val == nullptr) {
206 return RDB_E_INVALID_ARGS;
207 }
208 int checkRet = CheckValueType(value, ValueObject::TYPE_DOUBLE);
209 if (checkRet != RDB_OK) {
210 return checkRet;
211 }
212 *val = value->value_;
213 return RDB_OK;
214 }
215
OH_Value_GetText(OH_Data_Value * value,const char ** val)216 int OH_Value_GetText(OH_Data_Value *value, const char **val)
217 {
218 if (val == nullptr) {
219 return RDB_E_INVALID_ARGS;
220 }
221 int checkRet = CheckValueType(value, ValueObject::TYPE_STRING);
222 if (checkRet != RDB_OK) {
223 return checkRet;
224 }
225 auto actualValue = std::get_if<std::string>(&value->value_.value);
226 if (actualValue == nullptr) {
227 return RDB_E_TYPE_MISMATCH;
228 }
229 *val = actualValue->c_str();
230 return RDB_OK;
231 }
232
OH_Value_GetBlob(OH_Data_Value * value,const uint8_t ** val,size_t * length)233 int OH_Value_GetBlob(OH_Data_Value *value, const uint8_t **val, size_t *length)
234 {
235 if (val == nullptr || length == nullptr) {
236 return RDB_E_INVALID_ARGS;
237 }
238 int checkRet = CheckValueType(value, ValueObject::TYPE_BLOB);
239 if (checkRet != RDB_OK) {
240 return checkRet;
241 }
242 auto actualValue = std::get_if<std::vector<uint8_t>>(&value->value_.value);
243 if (actualValue == nullptr) {
244 return RDB_E_TYPE_MISMATCH;
245 }
246 *val = actualValue->data();
247 *length = actualValue->size();
248 return RDB_OK;
249 }
250
OH_Value_GetAsset(OH_Data_Value * value,Data_Asset * val)251 int OH_Value_GetAsset(OH_Data_Value *value, Data_Asset *val)
252 {
253 if (val == nullptr) {
254 return RDB_E_INVALID_ARGS;
255 }
256 int checkRet = CheckValueType(value, ValueObject::TYPE_ASSET);
257 if (checkRet != RDB_OK) {
258 return checkRet;
259 }
260 val->asset_ = std::get<ValueObject::Asset>(value->value_.value);
261 return RDB_OK;
262 }
263
OH_Value_GetAssetsCount(OH_Data_Value * value,size_t * size)264 int OH_Value_GetAssetsCount(OH_Data_Value *value, size_t *size)
265 {
266 if (size == nullptr) {
267 return RDB_E_INVALID_ARGS;
268 }
269 int checkRet = CheckValueType(value, ValueObject::TYPE_ASSETS);
270 if (checkRet != RDB_OK) {
271 return checkRet;
272 }
273 *size = std::get<ValueObject::Assets>(value->value_.value).size();
274 return RDB_OK;
275 }
276
OH_Value_GetAssets(OH_Data_Value * value,Data_Asset ** val,size_t inLen,size_t * outLen)277 int OH_Value_GetAssets(OH_Data_Value *value, Data_Asset **val, size_t inLen, size_t *outLen)
278 {
279 if (val == nullptr || outLen == nullptr) {
280 return RDB_E_INVALID_ARGS;
281 }
282 int checkRet = CheckValueType(value, ValueObject::TYPE_ASSETS);
283 if (checkRet != RDB_OK) {
284 return checkRet;
285 }
286 for (size_t i = 0; i < inLen; i++) {
287 if (val[i] == nullptr || val[i]->cid != DATA_ASSET_V0) {
288 return RDB_E_INVALID_ARGS;
289 }
290 }
291
292 auto asserts = std::get<ValueObject::Assets>(value->value_.value);
293 *outLen = 0;
294 for (size_t i = 0; i < inLen && i < asserts.size(); i++) {
295 if (val[i] != nullptr) {
296 val[i]->asset_ = asserts[i];
297 (*outLen)++;
298 }
299 }
300 return RDB_OK;
301 }
302
OH_Value_GetFloatVectorCount(OH_Data_Value * value,size_t * length)303 int OH_Value_GetFloatVectorCount(OH_Data_Value *value, size_t *length)
304 {
305 if (length == nullptr) {
306 return RDB_E_INVALID_ARGS;
307 }
308 int checkRet = CheckValueType(value, ValueObject::TYPE_VECS);
309 if (checkRet != RDB_OK) {
310 return checkRet;
311 }
312 *length = std::get<ValueObject::FloatVector>(value->value_.value).size();
313 return RDB_OK;
314 }
315
OH_Value_GetFloatVector(OH_Data_Value * value,float * val,size_t inLen,size_t * outLen)316 int OH_Value_GetFloatVector(OH_Data_Value *value, float *val, size_t inLen, size_t *outLen)
317 {
318 if (val == nullptr || inLen == 0 || outLen == nullptr) {
319 return RDB_E_INVALID_ARGS;
320 }
321 int checkRet = CheckValueType(value, ValueObject::TYPE_VECS);
322 if (checkRet != RDB_OK) {
323 return checkRet;
324 }
325 auto floatVec = std::get<ValueObject::FloatVector>(value->value_.value);
326 *outLen = 0;
327 for (size_t i = 0; i < floatVec.size() && i < inLen; i++) {
328 val[i] = floatVec[i];
329 (*outLen)++;
330 }
331 return RDB_OK;
332 }
333
OH_Value_GetUnlimitedIntBand(OH_Data_Value * value,size_t * length)334 int OH_Value_GetUnlimitedIntBand(OH_Data_Value *value, size_t *length)
335 {
336 if (length == nullptr) {
337 return RDB_E_INVALID_ARGS;
338 }
339 int checkRet = CheckValueType(value, ValueObject::TYPE_BIGINT);
340 if (checkRet != RDB_OK) {
341 return checkRet;
342 }
343 *length = std::get<ValueObject::BigInt>(value->value_.value).Size();
344 return RDB_OK;
345 }
346
OH_Value_GetUnlimitedInt(OH_Data_Value * value,int * sign,uint64_t * trueForm,size_t inLen,size_t * outLen)347 int OH_Value_GetUnlimitedInt(OH_Data_Value *value, int *sign, uint64_t *trueForm, size_t inLen, size_t *outLen)
348 {
349 if (sign == nullptr || trueForm == nullptr || inLen == 0 || outLen == nullptr) {
350 return RDB_E_INVALID_ARGS;
351 }
352 int checkRet = CheckValueType(value, ValueObject::TYPE_BIGINT);
353 if (checkRet != RDB_OK) {
354 return checkRet;
355 }
356 auto bigInt = std::get<ValueObject::BigInt>(value->value_.value);
357 if (inLen < bigInt.Size()) {
358 return RDB_E_INVALID_ARGS;
359 }
360 auto numVec = bigInt.Value();
361 *outLen = 0;
362 for (size_t i = 0; i < numVec.size(); i++) {
363 trueForm[i] = numVec[i];
364 (*outLen)++;
365 }
366 *sign = bigInt.Sign();
367 return RDB_OK;
368 }
369
IsValid() const370 bool OH_Data_Value::IsValid() const
371 {
372 return id == OH_VALUE_ID;
373 }