variantToSQLiteT_impl.h (4759B)
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- 2 * vim: sw=2 ts=2 et lcs=trail\:.,tab\:>~ : 3 * This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 // Note: we are already in the namepace mozilla::storage 8 9 // Note 2: whoever #includes this file must provide implementations of 10 // sqlite3_T_* prior. 11 12 //////////////////////////////////////////////////////////////////////////////// 13 //// variantToSQLiteT Implementation 14 15 template <typename T> 16 int variantToSQLiteT(T aObj, nsIVariant* aValue) { 17 // Allow to return nullptr not wrapped to nsIVariant for speed. 18 if (!aValue) return sqlite3_T_null(aObj); 19 20 uint16_t valueType = aValue->GetDataType(); 21 switch (valueType) { 22 case nsIDataType::VTYPE_INT8: 23 case nsIDataType::VTYPE_INT16: 24 case nsIDataType::VTYPE_INT32: 25 case nsIDataType::VTYPE_UINT8: 26 case nsIDataType::VTYPE_UINT16: { 27 int32_t value; 28 nsresult rv = aValue->GetAsInt32(&value); 29 NS_ENSURE_SUCCESS(rv, SQLITE_MISMATCH); 30 return sqlite3_T_int(aObj, value); 31 } 32 case nsIDataType::VTYPE_UINT32: // Try to preserve full range 33 case nsIDataType::VTYPE_INT64: 34 // Data loss possible, but there is no unsigned types in SQLite 35 case nsIDataType::VTYPE_UINT64: { 36 int64_t value; 37 nsresult rv = aValue->GetAsInt64(&value); 38 NS_ENSURE_SUCCESS(rv, SQLITE_MISMATCH); 39 return sqlite3_T_int64(aObj, value); 40 } 41 case nsIDataType::VTYPE_FLOAT: 42 case nsIDataType::VTYPE_DOUBLE: { 43 double value; 44 nsresult rv = aValue->GetAsDouble(&value); 45 NS_ENSURE_SUCCESS(rv, SQLITE_MISMATCH); 46 return sqlite3_T_double(aObj, value); 47 } 48 case nsIDataType::VTYPE_BOOL: { 49 bool value; 50 nsresult rv = aValue->GetAsBool(&value); 51 NS_ENSURE_SUCCESS(rv, SQLITE_MISMATCH); 52 return sqlite3_T_int(aObj, value ? 1 : 0); 53 } 54 case nsIDataType::VTYPE_CHAR: 55 case nsIDataType::VTYPE_CHAR_STR: 56 case nsIDataType::VTYPE_STRING_SIZE_IS: 57 case nsIDataType::VTYPE_UTF8STRING: 58 case nsIDataType::VTYPE_CSTRING: { 59 nsAutoCString value; 60 // GetAsAUTF8String should never perform conversion when coming from 61 // 8-bit string types, and thus can accept strings with arbitrary encoding 62 // (including UTF8 and ASCII). 63 nsresult rv = aValue->GetAsAUTF8String(value); 64 NS_ENSURE_SUCCESS(rv, SQLITE_MISMATCH); 65 return sqlite3_T_text(aObj, value); 66 } 67 case nsIDataType::VTYPE_WCHAR: 68 case nsIDataType::VTYPE_WCHAR_STR: 69 case nsIDataType::VTYPE_WSTRING_SIZE_IS: 70 case nsIDataType::VTYPE_ASTRING: { 71 nsAutoString value; 72 // GetAsAString does proper conversion to UCS2 from all string-like types. 73 // It can be used universally without problems (unless someone implements 74 // their own variant, but that's their problem). 75 nsresult rv = aValue->GetAsAString(value); 76 NS_ENSURE_SUCCESS(rv, SQLITE_MISMATCH); 77 return sqlite3_T_text16(aObj, value); 78 } 79 case nsIDataType::VTYPE_VOID: 80 case nsIDataType::VTYPE_EMPTY: 81 case nsIDataType::VTYPE_EMPTY_ARRAY: 82 return sqlite3_T_null(aObj); 83 case nsIDataType::VTYPE_ARRAY: { 84 uint16_t arrayType; 85 nsIID iid; 86 uint32_t count; 87 void* data; 88 nsresult rv = aValue->GetAsArray(&arrayType, &iid, &count, &data); 89 NS_ENSURE_SUCCESS(rv, SQLITE_MISMATCH); 90 if (arrayType == nsIDataType::VTYPE_UINT8) { 91 // The function should free the array accordingly! 92 return sqlite3_T_blob(aObj, data, count); 93 } 94 // Empty array is handled as NULL. 95 if (count == 0) { 96 return sqlite3_T_null(aObj); 97 } 98 if (arrayType == nsIDataType::VTYPE_INT32 || 99 arrayType == nsIDataType::VTYPE_INT64) { 100 return sqlite3_T_array(aObj, data, count, CARRAY_INT64); 101 } 102 if (arrayType == nsIDataType::VTYPE_FLOAT || 103 arrayType == nsIDataType::VTYPE_DOUBLE) { 104 return sqlite3_T_array(aObj, data, count, CARRAY_DOUBLE); 105 } 106 if (arrayType == nsIDataType::VTYPE_UTF8STRING) { 107 return sqlite3_T_array(aObj, data, count, CARRAY_TEXT); 108 } 109 110 MOZ_DIAGNOSTIC_CRASH("Unsupported type in Storage bound array"); 111 // Technically this could leak with certain data types, but somebody was 112 // being incautious passing us this anyway. 113 free(data); 114 return SQLITE_MISMATCH; 115 } 116 // Maybe, it'll be possible to convert these 117 // in future too. 118 case nsIDataType::VTYPE_ID: 119 case nsIDataType::VTYPE_INTERFACE: 120 case nsIDataType::VTYPE_INTERFACE_IS: 121 default: 122 return SQLITE_MISMATCH; 123 } 124 return SQLITE_OK; 125 }