1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/storage/src/variantToSQLiteT_impl.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,127 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- 1.5 + * vim: sw=2 ts=2 et lcs=trail\:.,tab\:>~ : 1.6 + * This Source Code Form is subject to the terms of the Mozilla Public 1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.9 + 1.10 +// Note: we are already in the namepace mozilla::storage 1.11 + 1.12 +// Note 2: whoever #includes this file must provide implementations of 1.13 +// sqlite3_T_* prior. 1.14 + 1.15 +//////////////////////////////////////////////////////////////////////////////// 1.16 +//// variantToSQLiteT Implementation 1.17 + 1.18 +template <typename T> 1.19 +int 1.20 +variantToSQLiteT(T aObj, 1.21 + nsIVariant *aValue) 1.22 +{ 1.23 + // Allow to return nullptr not wrapped to nsIVariant for speed. 1.24 + if (!aValue) 1.25 + return sqlite3_T_null(aObj); 1.26 + 1.27 + uint16_t type; 1.28 + (void)aValue->GetDataType(&type); 1.29 + switch (type) { 1.30 + case nsIDataType::VTYPE_INT8: 1.31 + case nsIDataType::VTYPE_INT16: 1.32 + case nsIDataType::VTYPE_INT32: 1.33 + case nsIDataType::VTYPE_UINT8: 1.34 + case nsIDataType::VTYPE_UINT16: 1.35 + { 1.36 + int32_t value; 1.37 + nsresult rv = aValue->GetAsInt32(&value); 1.38 + NS_ENSURE_SUCCESS(rv, SQLITE_MISMATCH); 1.39 + return sqlite3_T_int(aObj, value); 1.40 + } 1.41 + case nsIDataType::VTYPE_UINT32: // Try to preserve full range 1.42 + case nsIDataType::VTYPE_INT64: 1.43 + // Data loss possible, but there is no unsigned types in SQLite 1.44 + case nsIDataType::VTYPE_UINT64: 1.45 + { 1.46 + int64_t value; 1.47 + nsresult rv = aValue->GetAsInt64(&value); 1.48 + NS_ENSURE_SUCCESS(rv, SQLITE_MISMATCH); 1.49 + return sqlite3_T_int64(aObj, value); 1.50 + } 1.51 + case nsIDataType::VTYPE_FLOAT: 1.52 + case nsIDataType::VTYPE_DOUBLE: 1.53 + { 1.54 + double value; 1.55 + nsresult rv = aValue->GetAsDouble(&value); 1.56 + NS_ENSURE_SUCCESS(rv, SQLITE_MISMATCH); 1.57 + return sqlite3_T_double(aObj, value); 1.58 + } 1.59 + case nsIDataType::VTYPE_BOOL: 1.60 + { 1.61 + bool value; 1.62 + nsresult rv = aValue->GetAsBool(&value); 1.63 + NS_ENSURE_SUCCESS(rv, SQLITE_MISMATCH); 1.64 + return sqlite3_T_int(aObj, value ? 1 : 0); 1.65 + } 1.66 + case nsIDataType::VTYPE_CHAR: 1.67 + case nsIDataType::VTYPE_CHAR_STR: 1.68 + case nsIDataType::VTYPE_STRING_SIZE_IS: 1.69 + case nsIDataType::VTYPE_UTF8STRING: 1.70 + case nsIDataType::VTYPE_CSTRING: 1.71 + { 1.72 + nsAutoCString value; 1.73 + // GetAsAUTF8String should never perform conversion when coming from 1.74 + // 8-bit string types, and thus can accept strings with arbitrary encoding 1.75 + // (including UTF8 and ASCII). 1.76 + nsresult rv = aValue->GetAsAUTF8String(value); 1.77 + NS_ENSURE_SUCCESS(rv, SQLITE_MISMATCH); 1.78 + return sqlite3_T_text(aObj, value); 1.79 + } 1.80 + case nsIDataType::VTYPE_WCHAR: 1.81 + case nsIDataType::VTYPE_DOMSTRING: 1.82 + case nsIDataType::VTYPE_WCHAR_STR: 1.83 + case nsIDataType::VTYPE_WSTRING_SIZE_IS: 1.84 + case nsIDataType::VTYPE_ASTRING: 1.85 + { 1.86 + nsAutoString value; 1.87 + // GetAsAString does proper conversion to UCS2 from all string-like types. 1.88 + // It can be used universally without problems (unless someone implements 1.89 + // their own variant, but that's their problem). 1.90 + nsresult rv = aValue->GetAsAString(value); 1.91 + NS_ENSURE_SUCCESS(rv, SQLITE_MISMATCH); 1.92 + return sqlite3_T_text16(aObj, value); 1.93 + } 1.94 + case nsIDataType::VTYPE_VOID: 1.95 + case nsIDataType::VTYPE_EMPTY: 1.96 + case nsIDataType::VTYPE_EMPTY_ARRAY: 1.97 + return sqlite3_T_null(aObj); 1.98 + case nsIDataType::VTYPE_ARRAY: 1.99 + { 1.100 + uint16_t type; 1.101 + nsIID iid; 1.102 + uint32_t count; 1.103 + void *data; 1.104 + nsresult rv = aValue->GetAsArray(&type, &iid, &count, &data); 1.105 + NS_ENSURE_SUCCESS(rv, SQLITE_MISMATCH); 1.106 + 1.107 + // Check to make sure it's a supported type. 1.108 + NS_ASSERTION(type == nsIDataType::VTYPE_UINT8, 1.109 + "Invalid type passed! You may leak!"); 1.110 + if (type != nsIDataType::VTYPE_UINT8) { 1.111 + // Technically this could leak with certain data types, but somebody was 1.112 + // being stupid passing us this anyway. 1.113 + NS_Free(data); 1.114 + return SQLITE_MISMATCH; 1.115 + } 1.116 + 1.117 + // Finally do our thing. The function should free the array accordingly! 1.118 + int rc = sqlite3_T_blob(aObj, data, count); 1.119 + return rc; 1.120 + } 1.121 + // Maybe, it'll be possible to convert these 1.122 + // in future too. 1.123 + case nsIDataType::VTYPE_ID: 1.124 + case nsIDataType::VTYPE_INTERFACE: 1.125 + case nsIDataType::VTYPE_INTERFACE_IS: 1.126 + default: 1.127 + return SQLITE_MISMATCH; 1.128 + } 1.129 + return SQLITE_OK; 1.130 +}