|
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 #include "nsError.h" |
|
8 #include "nsMemory.h" |
|
9 #include "nsString.h" |
|
10 |
|
11 #include "mozStoragePrivateHelpers.h" |
|
12 #include "mozStorageArgValueArray.h" |
|
13 |
|
14 namespace mozilla { |
|
15 namespace storage { |
|
16 |
|
17 //////////////////////////////////////////////////////////////////////////////// |
|
18 //// ArgValueArray |
|
19 |
|
20 ArgValueArray::ArgValueArray(int32_t aArgc, |
|
21 sqlite3_value **aArgv) |
|
22 : mArgc(aArgc) |
|
23 , mArgv(aArgv) |
|
24 { |
|
25 } |
|
26 |
|
27 NS_IMPL_ISUPPORTS( |
|
28 ArgValueArray, |
|
29 mozIStorageValueArray |
|
30 ) |
|
31 |
|
32 //////////////////////////////////////////////////////////////////////////////// |
|
33 //// mozIStorageValueArray |
|
34 |
|
35 NS_IMETHODIMP |
|
36 ArgValueArray::GetNumEntries(uint32_t *_size) |
|
37 { |
|
38 *_size = mArgc; |
|
39 return NS_OK; |
|
40 } |
|
41 |
|
42 NS_IMETHODIMP |
|
43 ArgValueArray::GetTypeOfIndex(uint32_t aIndex, |
|
44 int32_t *_type) |
|
45 { |
|
46 ENSURE_INDEX_VALUE(aIndex, mArgc); |
|
47 |
|
48 int t = ::sqlite3_value_type(mArgv[aIndex]); |
|
49 switch (t) { |
|
50 case SQLITE_INTEGER: |
|
51 *_type = VALUE_TYPE_INTEGER; |
|
52 break; |
|
53 case SQLITE_FLOAT: |
|
54 *_type = VALUE_TYPE_FLOAT; |
|
55 break; |
|
56 case SQLITE_TEXT: |
|
57 *_type = VALUE_TYPE_TEXT; |
|
58 break; |
|
59 case SQLITE_BLOB: |
|
60 *_type = VALUE_TYPE_BLOB; |
|
61 break; |
|
62 case SQLITE_NULL: |
|
63 *_type = VALUE_TYPE_NULL; |
|
64 break; |
|
65 default: |
|
66 return NS_ERROR_FAILURE; |
|
67 } |
|
68 |
|
69 return NS_OK; |
|
70 } |
|
71 |
|
72 NS_IMETHODIMP |
|
73 ArgValueArray::GetInt32(uint32_t aIndex, |
|
74 int32_t *_value) |
|
75 { |
|
76 ENSURE_INDEX_VALUE(aIndex, mArgc); |
|
77 |
|
78 *_value = ::sqlite3_value_int(mArgv[aIndex]); |
|
79 return NS_OK; |
|
80 } |
|
81 |
|
82 NS_IMETHODIMP |
|
83 ArgValueArray::GetInt64(uint32_t aIndex, |
|
84 int64_t *_value) |
|
85 { |
|
86 ENSURE_INDEX_VALUE(aIndex, mArgc); |
|
87 |
|
88 *_value = ::sqlite3_value_int64(mArgv[aIndex]); |
|
89 return NS_OK; |
|
90 } |
|
91 |
|
92 NS_IMETHODIMP |
|
93 ArgValueArray::GetDouble(uint32_t aIndex, |
|
94 double *_value) |
|
95 { |
|
96 ENSURE_INDEX_VALUE(aIndex, mArgc); |
|
97 |
|
98 *_value = ::sqlite3_value_double(mArgv[aIndex]); |
|
99 return NS_OK; |
|
100 } |
|
101 |
|
102 NS_IMETHODIMP |
|
103 ArgValueArray::GetUTF8String(uint32_t aIndex, |
|
104 nsACString &_value) |
|
105 { |
|
106 ENSURE_INDEX_VALUE(aIndex, mArgc); |
|
107 |
|
108 if (::sqlite3_value_type(mArgv[aIndex]) == SQLITE_NULL) { |
|
109 // NULL columns should have IsVoid set to distinguish them from an empty |
|
110 // string. |
|
111 _value.Truncate(0); |
|
112 _value.SetIsVoid(true); |
|
113 } |
|
114 else { |
|
115 _value.Assign(reinterpret_cast<const char *>(::sqlite3_value_text(mArgv[aIndex])), |
|
116 ::sqlite3_value_bytes(mArgv[aIndex])); |
|
117 } |
|
118 return NS_OK; |
|
119 } |
|
120 |
|
121 NS_IMETHODIMP |
|
122 ArgValueArray::GetString(uint32_t aIndex, |
|
123 nsAString &_value) |
|
124 { |
|
125 ENSURE_INDEX_VALUE(aIndex, mArgc); |
|
126 |
|
127 if (::sqlite3_value_type(mArgv[aIndex]) == SQLITE_NULL) { |
|
128 // NULL columns should have IsVoid set to distinguish them from an empty |
|
129 // string. |
|
130 _value.Truncate(0); |
|
131 _value.SetIsVoid(true); |
|
132 } else { |
|
133 _value.Assign(static_cast<const char16_t *>(::sqlite3_value_text16(mArgv[aIndex])), |
|
134 ::sqlite3_value_bytes16(mArgv[aIndex]) / 2); |
|
135 } |
|
136 return NS_OK; |
|
137 } |
|
138 |
|
139 NS_IMETHODIMP |
|
140 ArgValueArray::GetBlob(uint32_t aIndex, |
|
141 uint32_t *_size, |
|
142 uint8_t **_blob) |
|
143 { |
|
144 ENSURE_INDEX_VALUE(aIndex, mArgc); |
|
145 |
|
146 int size = ::sqlite3_value_bytes(mArgv[aIndex]); |
|
147 void *blob = nsMemory::Clone(::sqlite3_value_blob(mArgv[aIndex]), size); |
|
148 NS_ENSURE_TRUE(blob, NS_ERROR_OUT_OF_MEMORY); |
|
149 |
|
150 *_blob = static_cast<uint8_t *>(blob); |
|
151 *_size = size; |
|
152 return NS_OK; |
|
153 } |
|
154 |
|
155 NS_IMETHODIMP |
|
156 ArgValueArray::GetIsNull(uint32_t aIndex, |
|
157 bool *_isNull) |
|
158 { |
|
159 // GetTypeOfIndex will check aIndex for us, so we don't have to. |
|
160 int32_t type; |
|
161 nsresult rv = GetTypeOfIndex(aIndex, &type); |
|
162 NS_ENSURE_SUCCESS(rv, rv); |
|
163 |
|
164 *_isNull = (type == VALUE_TYPE_NULL); |
|
165 return NS_OK; |
|
166 } |
|
167 |
|
168 NS_IMETHODIMP |
|
169 ArgValueArray::GetSharedUTF8String(uint32_t aIndex, |
|
170 uint32_t *_length, |
|
171 const char **_string) |
|
172 { |
|
173 if (_length) |
|
174 *_length = ::sqlite3_value_bytes(mArgv[aIndex]); |
|
175 |
|
176 *_string = reinterpret_cast<const char *>(::sqlite3_value_text(mArgv[aIndex])); |
|
177 return NS_OK; |
|
178 } |
|
179 |
|
180 NS_IMETHODIMP |
|
181 ArgValueArray::GetSharedString(uint32_t aIndex, |
|
182 uint32_t *_length, |
|
183 const char16_t **_string) |
|
184 { |
|
185 if (_length) |
|
186 *_length = ::sqlite3_value_bytes(mArgv[aIndex]); |
|
187 |
|
188 *_string = static_cast<const char16_t *>(::sqlite3_value_text16(mArgv[aIndex])); |
|
189 return NS_OK; |
|
190 } |
|
191 |
|
192 NS_IMETHODIMP |
|
193 ArgValueArray::GetSharedBlob(uint32_t aIndex, |
|
194 uint32_t *_size, |
|
195 const uint8_t **_blob) |
|
196 { |
|
197 *_size = ::sqlite3_value_bytes(mArgv[aIndex]); |
|
198 *_blob = static_cast<const uint8_t *>(::sqlite3_value_blob(mArgv[aIndex])); |
|
199 return NS_OK; |
|
200 } |
|
201 |
|
202 } // namespace storage |
|
203 } // namespace mozilla |