|
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 |
|
17 variantToSQLiteT(T aObj, |
|
18 nsIVariant *aValue) |
|
19 { |
|
20 // Allow to return nullptr not wrapped to nsIVariant for speed. |
|
21 if (!aValue) |
|
22 return sqlite3_T_null(aObj); |
|
23 |
|
24 uint16_t type; |
|
25 (void)aValue->GetDataType(&type); |
|
26 switch (type) { |
|
27 case nsIDataType::VTYPE_INT8: |
|
28 case nsIDataType::VTYPE_INT16: |
|
29 case nsIDataType::VTYPE_INT32: |
|
30 case nsIDataType::VTYPE_UINT8: |
|
31 case nsIDataType::VTYPE_UINT16: |
|
32 { |
|
33 int32_t value; |
|
34 nsresult rv = aValue->GetAsInt32(&value); |
|
35 NS_ENSURE_SUCCESS(rv, SQLITE_MISMATCH); |
|
36 return sqlite3_T_int(aObj, value); |
|
37 } |
|
38 case nsIDataType::VTYPE_UINT32: // Try to preserve full range |
|
39 case nsIDataType::VTYPE_INT64: |
|
40 // Data loss possible, but there is no unsigned types in SQLite |
|
41 case nsIDataType::VTYPE_UINT64: |
|
42 { |
|
43 int64_t value; |
|
44 nsresult rv = aValue->GetAsInt64(&value); |
|
45 NS_ENSURE_SUCCESS(rv, SQLITE_MISMATCH); |
|
46 return sqlite3_T_int64(aObj, value); |
|
47 } |
|
48 case nsIDataType::VTYPE_FLOAT: |
|
49 case nsIDataType::VTYPE_DOUBLE: |
|
50 { |
|
51 double value; |
|
52 nsresult rv = aValue->GetAsDouble(&value); |
|
53 NS_ENSURE_SUCCESS(rv, SQLITE_MISMATCH); |
|
54 return sqlite3_T_double(aObj, value); |
|
55 } |
|
56 case nsIDataType::VTYPE_BOOL: |
|
57 { |
|
58 bool value; |
|
59 nsresult rv = aValue->GetAsBool(&value); |
|
60 NS_ENSURE_SUCCESS(rv, SQLITE_MISMATCH); |
|
61 return sqlite3_T_int(aObj, value ? 1 : 0); |
|
62 } |
|
63 case nsIDataType::VTYPE_CHAR: |
|
64 case nsIDataType::VTYPE_CHAR_STR: |
|
65 case nsIDataType::VTYPE_STRING_SIZE_IS: |
|
66 case nsIDataType::VTYPE_UTF8STRING: |
|
67 case nsIDataType::VTYPE_CSTRING: |
|
68 { |
|
69 nsAutoCString value; |
|
70 // GetAsAUTF8String should never perform conversion when coming from |
|
71 // 8-bit string types, and thus can accept strings with arbitrary encoding |
|
72 // (including UTF8 and ASCII). |
|
73 nsresult rv = aValue->GetAsAUTF8String(value); |
|
74 NS_ENSURE_SUCCESS(rv, SQLITE_MISMATCH); |
|
75 return sqlite3_T_text(aObj, value); |
|
76 } |
|
77 case nsIDataType::VTYPE_WCHAR: |
|
78 case nsIDataType::VTYPE_DOMSTRING: |
|
79 case nsIDataType::VTYPE_WCHAR_STR: |
|
80 case nsIDataType::VTYPE_WSTRING_SIZE_IS: |
|
81 case nsIDataType::VTYPE_ASTRING: |
|
82 { |
|
83 nsAutoString value; |
|
84 // GetAsAString does proper conversion to UCS2 from all string-like types. |
|
85 // It can be used universally without problems (unless someone implements |
|
86 // their own variant, but that's their problem). |
|
87 nsresult rv = aValue->GetAsAString(value); |
|
88 NS_ENSURE_SUCCESS(rv, SQLITE_MISMATCH); |
|
89 return sqlite3_T_text16(aObj, value); |
|
90 } |
|
91 case nsIDataType::VTYPE_VOID: |
|
92 case nsIDataType::VTYPE_EMPTY: |
|
93 case nsIDataType::VTYPE_EMPTY_ARRAY: |
|
94 return sqlite3_T_null(aObj); |
|
95 case nsIDataType::VTYPE_ARRAY: |
|
96 { |
|
97 uint16_t type; |
|
98 nsIID iid; |
|
99 uint32_t count; |
|
100 void *data; |
|
101 nsresult rv = aValue->GetAsArray(&type, &iid, &count, &data); |
|
102 NS_ENSURE_SUCCESS(rv, SQLITE_MISMATCH); |
|
103 |
|
104 // Check to make sure it's a supported type. |
|
105 NS_ASSERTION(type == nsIDataType::VTYPE_UINT8, |
|
106 "Invalid type passed! You may leak!"); |
|
107 if (type != nsIDataType::VTYPE_UINT8) { |
|
108 // Technically this could leak with certain data types, but somebody was |
|
109 // being stupid passing us this anyway. |
|
110 NS_Free(data); |
|
111 return SQLITE_MISMATCH; |
|
112 } |
|
113 |
|
114 // Finally do our thing. The function should free the array accordingly! |
|
115 int rc = sqlite3_T_blob(aObj, data, count); |
|
116 return rc; |
|
117 } |
|
118 // Maybe, it'll be possible to convert these |
|
119 // in future too. |
|
120 case nsIDataType::VTYPE_ID: |
|
121 case nsIDataType::VTYPE_INTERFACE: |
|
122 case nsIDataType::VTYPE_INTERFACE_IS: |
|
123 default: |
|
124 return SQLITE_MISMATCH; |
|
125 } |
|
126 return SQLITE_OK; |
|
127 } |