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