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