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()26ValueObject::ValueObject() 27 { 28 } 29 ValueObject(Type val)30ValueObject::ValueObject(Type val) noexcept : value(std::move(val)) 31 { 32 } 33 ValueObject(ValueObject && val)34ValueObject::ValueObject(ValueObject &&val) noexcept 35 { 36 if (this == &val) { 37 return; 38 } 39 value = std::move(val.value); 40 } 41 ValueObject(const ValueObject & val)42ValueObject::ValueObject(const ValueObject &val) 43 { 44 if (this == &val) { 45 return; 46 } 47 value = val.value; 48 } 49 ~ValueObject()50ValueObject::~ValueObject() 51 { 52 } 53 ValueObject(int val)54ValueObject::ValueObject(int val) : value(static_cast<int64_t>(val)) 55 { 56 } 57 ValueObject(int64_t val)58ValueObject::ValueObject(int64_t val) : value(val) 59 { 60 } 61 ValueObject(double val)62ValueObject::ValueObject(double val) : value(val) 63 { 64 } 65 ValueObject(bool val)66ValueObject::ValueObject(bool val) : value(val) 67 { 68 } 69 ValueObject(std::string val)70ValueObject::ValueObject(std::string val) : value(std::move(val)) 71 { 72 } 73 ValueObject(const char * val)74ValueObject::ValueObject(const char *val) : ValueObject(std::string(val)) 75 { 76 } 77 ValueObject(const std::vector<uint8_t> & val)78ValueObject::ValueObject(const std::vector<uint8_t> &val) : value(val) 79 { 80 } 81 ValueObject(ValueObject::Asset val)82ValueObject::ValueObject(ValueObject::Asset val) : value(std::move(val)) 83 { 84 } 85 ValueObject(ValueObject::Assets val)86ValueObject::ValueObject(ValueObject::Assets val) : value(std::move(val)) 87 { 88 } 89 ValueObject(ValueObject::BigInt val)90ValueObject::ValueObject(ValueObject::BigInt val) : value(std::move(val)) 91 { 92 } 93 ValueObject(ValueObject::FloatVector val)94ValueObject::ValueObject(ValueObject::FloatVector val) : value(std::move(val)) 95 { 96 } 97 operator =(ValueObject && val)98ValueObject &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)107ValueObject &ValueObject::operator=(const ValueObject &val) 108 { 109 if (this == &val) { 110 return *this; 111 } 112 value = val.value; 113 return *this; 114 } 115 GetType() const116ValueObjectType ValueObject::GetType() const 117 { 118 return ValueObjectType(value.index()); 119 } 120 GetInt(int & val) const121int 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) const129int ValueObject::GetLong(int64_t &val) const 130 { 131 return Get(val); 132 } 133 GetDouble(double & val) const134int ValueObject::GetDouble(double &val) const 135 { 136 return Get(val); 137 } 138 GetBool(bool & val) const139int ValueObject::GetBool(bool &val) const 140 { 141 return Get(val); 142 } 143 GetString(std::string & val) const144int 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) const170int ValueObject::GetBlob(std::vector<uint8_t> &val) const 171 { 172 return Get(val); 173 } 174 GetAsset(Asset & val) const175int ValueObject::GetAsset(Asset &val) const 176 { 177 return Get(val); 178 } 179 GetAssets(Assets & val) const180int 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)241static 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) const329int ValueObject::GetVecs(FloatVector &val) const 330 { 331 return Get(val); 332 } 333 334 template<class T> Get(T & output) const335int 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) const345bool 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) const389bool ValueObject::operator==(const ValueObject &rhs) const 390 { 391 return !(rhs < *this || *this < rhs); 392 } 393 operator !=(const ValueObject & rhs) const394bool ValueObject::operator!=(const ValueObject &rhs) const 395 { 396 return (rhs < *this || *this < rhs); 397 } 398 } // namespace NativeRdb 399 } // namespace OHOS 400