1 /*
2  * Copyright (c) 2021 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 "value_object.h"
17 
18 #include <iostream>
19 #include <limits>
20 #include <sstream>
21 
22 #include "rdb_errno.h"
23 #include "sqlite_utils.h"
24 namespace OHOS {
25 namespace NativeRdb {
ValueObject()26 ValueObject::ValueObject()
27 {
28 }
29 
ValueObject(Type val)30 ValueObject::ValueObject(Type val) noexcept : value(std::move(val))
31 {
32 }
33 
ValueObject(ValueObject && val)34 ValueObject::ValueObject(ValueObject &&val) noexcept
35 {
36     if (this == &val) {
37         return;
38     }
39     value = std::move(val.value);
40 }
41 
ValueObject(const ValueObject & val)42 ValueObject::ValueObject(const ValueObject &val)
43 {
44     if (this == &val) {
45         return;
46     }
47     value = val.value;
48 }
49 
~ValueObject()50 ValueObject::~ValueObject()
51 {
52 }
53 
ValueObject(int val)54 ValueObject::ValueObject(int val) : value(static_cast<int64_t>(val))
55 {
56 }
57 
ValueObject(int64_t val)58 ValueObject::ValueObject(int64_t val) : value(val)
59 {
60 }
61 
ValueObject(double val)62 ValueObject::ValueObject(double val) : value(val)
63 {
64 }
65 
ValueObject(bool val)66 ValueObject::ValueObject(bool val) : value(val)
67 {
68 }
69 
ValueObject(std::string val)70 ValueObject::ValueObject(std::string val) : value(std::move(val))
71 {
72 }
73 
ValueObject(const char * val)74 ValueObject::ValueObject(const char *val) : ValueObject(std::string(val))
75 {
76 }
77 
ValueObject(const std::vector<uint8_t> & val)78 ValueObject::ValueObject(const std::vector<uint8_t> &val) : value(val)
79 {
80 }
81 
ValueObject(ValueObject::Asset val)82 ValueObject::ValueObject(ValueObject::Asset val) : value(std::move(val))
83 {
84 }
85 
ValueObject(ValueObject::Assets val)86 ValueObject::ValueObject(ValueObject::Assets val) : value(std::move(val))
87 {
88 }
89 
ValueObject(ValueObject::BigInt val)90 ValueObject::ValueObject(ValueObject::BigInt val) : value(std::move(val))
91 {
92 }
93 
ValueObject(ValueObject::FloatVector val)94 ValueObject::ValueObject(ValueObject::FloatVector val) : value(std::move(val))
95 {
96 }
97 
operator =(ValueObject && val)98 ValueObject &ValueObject::operator=(ValueObject &&val) noexcept
99 {
100     if (this == &val) {
101         return *this;
102     }
103     value = std::move(val.value);
104     return *this;
105 }
106 
operator =(const ValueObject & val)107 ValueObject &ValueObject::operator=(const ValueObject &val)
108 {
109     if (this == &val) {
110         return *this;
111     }
112     value = val.value;
113     return *this;
114 }
115 
GetType() const116 ValueObjectType ValueObject::GetType() const
117 {
118     return ValueObjectType(value.index());
119 }
120 
GetInt(int & val) const121 int ValueObject::GetInt(int &val) const
122 {
123     int64_t value = 0;
124     auto ret = Get(value);
125     val = value;
126     return ret;
127 }
128 
GetLong(int64_t & val) const129 int ValueObject::GetLong(int64_t &val) const
130 {
131     return Get(val);
132 }
133 
GetDouble(double & val) const134 int ValueObject::GetDouble(double &val) const
135 {
136     return Get(val);
137 }
138 
GetBool(bool & val) const139 int ValueObject::GetBool(bool &val) const
140 {
141     return Get(val);
142 }
143 
GetString(std::string & val) const144 int ValueObject::GetString(std::string &val) const
145 {
146     if (Get(val) == E_OK) {
147         return E_OK;
148     }
149 
150     double ftmp;
151     if (Get(ftmp) == E_OK) {
152         val = std::to_string(ftmp);
153         return E_OK;
154     }
155 
156     int64_t itmp;
157     if (Get(itmp) == E_OK) {
158         val = std::to_string(itmp);
159         return E_OK;
160     }
161 
162     bool btmp;
163     if (Get(btmp) == 0) {
164         val = std::to_string(btmp);
165         return E_OK;
166     }
167     return E_INVALID_OBJECT_TYPE;
168 }
169 
GetBlob(std::vector<uint8_t> & val) const170 int ValueObject::GetBlob(std::vector<uint8_t> &val) const
171 {
172     return Get(val);
173 }
174 
GetAsset(Asset & val) const175 int ValueObject::GetAsset(Asset &val) const
176 {
177     return Get(val);
178 }
179 
GetAssets(Assets & val) const180 int ValueObject::GetAssets(Assets &val) const
181 {
182     return Get(val);
183 }
184 
185 ValueObject::operator int() const
186 {
187     return static_cast<int>(operator int64_t());
188 }
189 
190 ValueObject::operator int64_t() const
191 {
192     int64_t val = 0L;
193     int type = value.index();
194     if (type == ValueObject::TYPE_INT) {
195         val = std::get<int64_t>(value);
196     } else if (type == ValueObject::TYPE_DOUBLE) {
197         val = int64_t(std::get<double>(value));
198     } else if (type == ValueObject::TYPE_BOOL) {
199         val = std::get<bool>(value);
200     } else if (type == ValueObject::TYPE_STRING) {
201         auto temp = std::get<std::string>(value);
202         val = temp.empty() ? 0L : int64_t(strtoll(temp.c_str(), nullptr, 0));
203     }
204     return val;
205 }
206 
207 ValueObject::operator double() const
208 {
209     double val = 0.0L;
210     size_t type = value.index();
211     if (type == ValueObject::TYPE_INT) {
212         val = double(std::get<int64_t>(value));
213     } else if (type == ValueObject::TYPE_DOUBLE) {
214         val = std::get<double>(value);
215     } else if (type == ValueObject::TYPE_BOOL) {
216         val = std::get<bool>(value);
217     } else if (type == ValueObject::TYPE_STRING) {
218         auto temp = std::get<std::string>(value);
219         val = temp.empty() ? 0.0 : double(strtod(temp.c_str(), nullptr));
220     }
221     return val;
222 }
223 
224 ValueObject::operator bool() const
225 {
226     bool val = false;
227     int type = value.index();
228     if (type == ValueObject::TYPE_INT) {
229         val = std::get<int64_t>(value) != 0;
230     } else if (type == ValueObject::TYPE_DOUBLE) {
231         val = static_cast<int64_t>(std::get<double>(value)) != 0;
232     } else if (type == ValueObject::TYPE_BOOL) {
233         val = std::get<bool>(value);
234     } else if (type == ValueObject::TYPE_STRING) {
235         auto temp = std::get<std::string>(value);
236         val = (temp == "true" || temp != "0");
237     }
238     return val;
239 }
240 
GetPrecision(double val)241 static int32_t GetPrecision(double val)
242 {
243     int max = std::numeric_limits<double>::max_digits10;
244     int precision = 0;
245     val = val - int64_t(val);
246     for (int i = 0; i < max; ++i) {
247         // Loop to multiply the decimal part of val by 10 until it is no longer a decimal
248         val *= 10;
249         if (int64_t(val) > 0) {
250             precision = i + 1;
251         }
252         val -= int64_t(val);
253     }
254     return precision;
255 }
256 
257 ValueObject::operator std::string() const
258 {
259     std::string val;
260     int type = static_cast<int>(value.index());
261     if (type == ValueObject::TYPE_INT) {
262         auto temp = std::get<int64_t>(value);
263         val = std::to_string(temp);
264     } else if (type == ValueObject::TYPE_BOOL) {
265         val = std::get<bool>(value) ? "1" : "0";
266     } else if (type == ValueObject::TYPE_DOUBLE) {
267         double temp = std::get<double>(value);
268         std::ostringstream os;
269         os.setf(std::ios::fixed);
270         os.precision(GetPrecision(temp));
271         if (os << temp) {
272             val = os.str();
273         }
274     } else if (type == ValueObject::TYPE_STRING) {
275         val = std::get<std::string>(value);
276     }
277     return val;
278 }
279 
280 ValueObject::operator Blob() const
281 {
282     Blob val;
283     int type = static_cast<int>(value.index());
284     if (type == ValueObject::TYPE_BLOB) {
285         val = std::get<std::vector<uint8_t>>(value);
286     } else if (type == ValueObject::TYPE_STRING) {
287         auto temp = std::get<std::string>(value);
288         val.assign(temp.begin(), temp.end());
289     }
290     return val;
291 }
292 
293 ValueObject::operator Asset() const
294 {
295     auto val = std::get_if<Asset>(&value);
296     if (val == nullptr) {
297         return {};
298     }
299     return *val;
300 }
301 
302 ValueObject::operator Assets() const
303 {
304     auto val = std::get_if<Assets>(&value);
305     if (val == nullptr) {
306         return {};
307     }
308     return *val;
309 }
310 
311 ValueObject::operator FloatVector() const
312 {
313     auto val = std::get_if<FloatVector>(&value);
314     if (val == nullptr) {
315         return {};
316     }
317     return *val;
318 }
319 
320 ValueObject::operator BigInt() const
321 {
322     auto val = std::get_if<BigInt>(&value);
323     if (val == nullptr) {
324         return {};
325     }
326     return *val;
327 }
328 
GetVecs(FloatVector & val) const329 int ValueObject::GetVecs(FloatVector &val) const
330 {
331     return Get(val);
332 }
333 
334 template<class T>
Get(T & output) const335 int ValueObject::Get(T &output) const
336 {
337     const T *v = std::get_if<T>(&value);
338     if (v == nullptr) {
339         return E_INVALID_OBJECT_TYPE;
340     }
341     output = static_cast<T>(*v);
342     return E_OK;
343 }
344 
operator <(const ValueObject & rhs) const345 bool ValueObject::operator<(const ValueObject &rhs) const
346 {
347     if (GetType() != rhs.GetType()) {
348         return GetType() < rhs.GetType();
349     }
350 
351     bool result = true;
352     switch (GetType()) {
353         case TYPE_NULL:
354             result = false;
355             break;
356         case TYPE_INT:
357             result = int64_t(*this) < int64_t(rhs);
358             break;
359         case TYPE_DOUBLE:
360             result = double(*this) < double(rhs);
361             break;
362         case TYPE_STRING:
363             result = std::string(*this) < std::string(rhs);
364             break;
365         case TYPE_BOOL:
366             result = bool(*this) < bool(rhs);
367             break;
368         case TYPE_BLOB:
369             result = Blob(*this) < Blob(rhs);
370             break;
371         case TYPE_ASSET:
372             result = Asset(*this) < Asset(rhs);
373             break;
374         case TYPE_ASSETS:
375             result = Assets(*this) < Assets(rhs);
376             break;
377         case TYPE_VECS:
378             result = FloatVector(*this) < FloatVector(rhs);
379             break;
380         case TYPE_BIGINT:
381             result = BigInt(*this) < BigInt(rhs);
382             break;
383         default:
384             break;
385     }
386     return result;
387 }
388 
operator ==(const ValueObject & rhs) const389 bool ValueObject::operator==(const ValueObject &rhs) const
390 {
391     return !(rhs < *this || *this < rhs);
392 }
393 
operator !=(const ValueObject & rhs) const394 bool ValueObject::operator!=(const ValueObject &rhs) const
395 {
396     return (rhs < *this || *this < rhs);
397 }
398 } // namespace NativeRdb
399 } // namespace OHOS
400