/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- * vim: sw=2 ts=2 et lcs=trail\:.,tab\:>~ : * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ // Note: we are already in the namepace mozilla::storage // Note 2: whoever #includes this file must provide implementations of // sqlite3_T_* prior. //////////////////////////////////////////////////////////////////////////////// //// variantToSQLiteT Implementation template int variantToSQLiteT(T aObj, nsIVariant* aValue) { // Allow to return nullptr not wrapped to nsIVariant for speed. if (!aValue) return sqlite3_T_null(aObj); uint16_t valueType = aValue->GetDataType(); switch (valueType) { case nsIDataType::VTYPE_INT8: case nsIDataType::VTYPE_INT16: case nsIDataType::VTYPE_INT32: case nsIDataType::VTYPE_UINT8: case nsIDataType::VTYPE_UINT16: { int32_t value; nsresult rv = aValue->GetAsInt32(&value); NS_ENSURE_SUCCESS(rv, SQLITE_MISMATCH); return sqlite3_T_int(aObj, value); } case nsIDataType::VTYPE_UINT32: // Try to preserve full range case nsIDataType::VTYPE_INT64: // Data loss possible, but there is no unsigned types in SQLite case nsIDataType::VTYPE_UINT64: { int64_t value; nsresult rv = aValue->GetAsInt64(&value); NS_ENSURE_SUCCESS(rv, SQLITE_MISMATCH); return sqlite3_T_int64(aObj, value); } case nsIDataType::VTYPE_FLOAT: case nsIDataType::VTYPE_DOUBLE: { double value; nsresult rv = aValue->GetAsDouble(&value); NS_ENSURE_SUCCESS(rv, SQLITE_MISMATCH); return sqlite3_T_double(aObj, value); } case nsIDataType::VTYPE_BOOL: { bool value; nsresult rv = aValue->GetAsBool(&value); NS_ENSURE_SUCCESS(rv, SQLITE_MISMATCH); return sqlite3_T_int(aObj, value ? 1 : 0); } case nsIDataType::VTYPE_CHAR: case nsIDataType::VTYPE_CHAR_STR: case nsIDataType::VTYPE_STRING_SIZE_IS: case nsIDataType::VTYPE_UTF8STRING: case nsIDataType::VTYPE_CSTRING: { nsAutoCString value; // GetAsAUTF8String should never perform conversion when coming from // 8-bit string types, and thus can accept strings with arbitrary encoding // (including UTF8 and ASCII). nsresult rv = aValue->GetAsAUTF8String(value); NS_ENSURE_SUCCESS(rv, SQLITE_MISMATCH); return sqlite3_T_text(aObj, value); } case nsIDataType::VTYPE_WCHAR: case nsIDataType::VTYPE_WCHAR_STR: case nsIDataType::VTYPE_WSTRING_SIZE_IS: case nsIDataType::VTYPE_ASTRING: { nsAutoString value; // GetAsAString does proper conversion to UCS2 from all string-like types. // It can be used universally without problems (unless someone implements // their own variant, but that's their problem). nsresult rv = aValue->GetAsAString(value); NS_ENSURE_SUCCESS(rv, SQLITE_MISMATCH); return sqlite3_T_text16(aObj, value); } case nsIDataType::VTYPE_VOID: case nsIDataType::VTYPE_EMPTY: case nsIDataType::VTYPE_EMPTY_ARRAY: return sqlite3_T_null(aObj); case nsIDataType::VTYPE_ARRAY: { uint16_t arrayType; nsIID iid; uint32_t count; void* data; nsresult rv = aValue->GetAsArray(&arrayType, &iid, &count, &data); NS_ENSURE_SUCCESS(rv, SQLITE_MISMATCH); if (arrayType == nsIDataType::VTYPE_UINT8) { // The function should free the array accordingly! return sqlite3_T_blob(aObj, data, count); } // Empty array is handled as NULL. if (count == 0) { return sqlite3_T_null(aObj); } if (arrayType == nsIDataType::VTYPE_INT32 || arrayType == nsIDataType::VTYPE_INT64) { return sqlite3_T_array(aObj, data, count, CARRAY_INT64); } if (arrayType == nsIDataType::VTYPE_FLOAT || arrayType == nsIDataType::VTYPE_DOUBLE) { return sqlite3_T_array(aObj, data, count, CARRAY_DOUBLE); } if (arrayType == nsIDataType::VTYPE_UTF8STRING) { return sqlite3_T_array(aObj, data, count, CARRAY_TEXT); } MOZ_DIAGNOSTIC_CRASH("Unsupported type in Storage bound array"); // Technically this could leak with certain data types, but somebody was // being incautious passing us this anyway. free(data); return SQLITE_MISMATCH; } // Maybe, it'll be possible to convert these // in future too. case nsIDataType::VTYPE_ID: case nsIDataType::VTYPE_INTERFACE: case nsIDataType::VTYPE_INTERFACE_IS: default: return SQLITE_MISMATCH; } return SQLITE_OK; }