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