Bug 899135 - Drop buffers in ScriptProcessorNode instead of buffering them when the...
[gecko.git] / storage / src / mozStorageStatementParams.cpp
blobcc9562f1eebd1ae41364fbf417389df7a0d2bcd3
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/. */
7 #include "nsMemory.h"
8 #include "nsString.h"
10 #include "mozStoragePrivateHelpers.h"
11 #include "mozStorageStatementParams.h"
12 #include "mozIStorageStatement.h"
14 namespace mozilla {
15 namespace storage {
17 ////////////////////////////////////////////////////////////////////////////////
18 //// StatementParams
20 StatementParams::StatementParams(mozIStorageStatement *aStatement) :
21 mStatement(aStatement)
23 NS_ASSERTION(mStatement != nullptr, "mStatement is null");
24 (void)mStatement->GetParameterCount(&mParamCount);
27 NS_IMPL_ISUPPORTS2(
28 StatementParams,
29 mozIStorageStatementParams,
30 nsIXPCScriptable
33 ////////////////////////////////////////////////////////////////////////////////
34 //// nsIXPCScriptable
36 #define XPC_MAP_CLASSNAME StatementParams
37 #define XPC_MAP_QUOTED_CLASSNAME "StatementParams"
38 #define XPC_MAP_WANT_SETPROPERTY
39 #define XPC_MAP_WANT_NEWENUMERATE
40 #define XPC_MAP_WANT_NEWRESOLVE
41 #define XPC_MAP_FLAGS nsIXPCScriptable::ALLOW_PROP_MODS_DURING_RESOLVE
42 #include "xpc_map_end.h"
44 NS_IMETHODIMP
45 StatementParams::SetProperty(nsIXPConnectWrappedNative *aWrapper,
46 JSContext *aCtx,
47 JSObject *aScopeObj,
48 jsid aId,
49 jsval *_vp,
50 bool *_retval)
52 NS_ENSURE_TRUE(mStatement, NS_ERROR_NOT_INITIALIZED);
54 if (JSID_IS_INT(aId)) {
55 int idx = JSID_TO_INT(aId);
57 nsCOMPtr<nsIVariant> variant(convertJSValToVariant(aCtx, *_vp));
58 NS_ENSURE_TRUE(variant, NS_ERROR_UNEXPECTED);
59 nsresult rv = mStatement->BindByIndex(idx, variant);
60 NS_ENSURE_SUCCESS(rv, rv);
62 else if (JSID_IS_STRING(aId)) {
63 JSString *str = JSID_TO_STRING(aId);
64 size_t length;
65 const jschar *chars = JS_GetStringCharsAndLength(aCtx, str, &length);
66 NS_ENSURE_TRUE(chars, NS_ERROR_UNEXPECTED);
67 NS_ConvertUTF16toUTF8 name(chars, length);
69 // check to see if there's a parameter with this name
70 nsCOMPtr<nsIVariant> variant(convertJSValToVariant(aCtx, *_vp));
71 NS_ENSURE_TRUE(variant, NS_ERROR_UNEXPECTED);
72 nsresult rv = mStatement->BindByName(name, variant);
73 NS_ENSURE_SUCCESS(rv, rv);
75 else {
76 return NS_ERROR_INVALID_ARG;
79 *_retval = true;
80 return NS_OK;
83 NS_IMETHODIMP
84 StatementParams::NewEnumerate(nsIXPConnectWrappedNative *aWrapper,
85 JSContext *aCtx,
86 JSObject *aScopeObj,
87 uint32_t aEnumOp,
88 jsval *_statep,
89 jsid *_idp,
90 bool *_retval)
92 NS_ENSURE_TRUE(mStatement, NS_ERROR_NOT_INITIALIZED);
94 switch (aEnumOp) {
95 case JSENUMERATE_INIT:
96 case JSENUMERATE_INIT_ALL:
98 // Start our internal index at zero.
99 *_statep = JSVAL_ZERO;
101 // And set our length, if needed.
102 if (_idp)
103 *_idp = INT_TO_JSID(mParamCount);
105 break;
107 case JSENUMERATE_NEXT:
109 NS_ASSERTION(*_statep != JSVAL_NULL, "Internal state is null!");
111 // Make sure we are in range first.
112 uint32_t index = static_cast<uint32_t>(JSVAL_TO_INT(*_statep));
113 if (index >= mParamCount) {
114 *_statep = JSVAL_NULL;
115 return NS_OK;
118 // Get the name of our parameter.
119 nsAutoCString name;
120 nsresult rv = mStatement->GetParameterName(index, name);
121 NS_ENSURE_SUCCESS(rv, rv);
123 // But drop the first character, which is going to be a ':'.
124 JSString *jsname = ::JS_NewStringCopyN(aCtx, &(name.get()[1]),
125 name.Length() - 1);
126 NS_ENSURE_TRUE(jsname, NS_ERROR_OUT_OF_MEMORY);
128 // Set our name.
129 if (!::JS_ValueToId(aCtx, STRING_TO_JSVAL(jsname), _idp)) {
130 *_retval = false;
131 return NS_OK;
134 // And increment our index.
135 *_statep = INT_TO_JSVAL(++index);
137 break;
139 case JSENUMERATE_DESTROY:
141 // Clear our state.
142 *_statep = JSVAL_NULL;
144 break;
148 return NS_OK;
151 NS_IMETHODIMP
152 StatementParams::NewResolve(nsIXPConnectWrappedNative *aWrapper,
153 JSContext *aCtx,
154 JSObject *aScopeObj,
155 jsid aId,
156 uint32_t aFlags,
157 JSObject **_objp,
158 bool *_retval)
160 NS_ENSURE_TRUE(mStatement, NS_ERROR_NOT_INITIALIZED);
161 // We do not throw at any point after this unless our index is out of range
162 // because we want to allow the prototype chain to be checked for the
163 // property.
165 JS::RootedObject scope(aCtx, aScopeObj);
166 JS::RootedId id(aCtx, aId);
167 bool resolved = false;
168 bool ok = true;
169 if (JSID_IS_INT(id)) {
170 uint32_t idx = JSID_TO_INT(id);
172 // Ensure that our index is within range. We do not care about the
173 // prototype chain being checked here.
174 if (idx >= mParamCount)
175 return NS_ERROR_INVALID_ARG;
177 ok = ::JS_DefineElement(aCtx, scope, idx, JSVAL_VOID, nullptr,
178 nullptr, JSPROP_ENUMERATE);
179 resolved = true;
181 else if (JSID_IS_STRING(id)) {
182 JSString *str = JSID_TO_STRING(id);
183 size_t nameLength;
184 const jschar *nameChars = JS_GetStringCharsAndLength(aCtx, str, &nameLength);
185 NS_ENSURE_TRUE(nameChars, NS_ERROR_UNEXPECTED);
187 // Check to see if there's a parameter with this name, and if not, let
188 // the rest of the prototype chain be checked.
189 NS_ConvertUTF16toUTF8 name(nameChars, nameLength);
190 uint32_t idx;
191 nsresult rv = mStatement->GetParameterIndex(name, &idx);
192 if (NS_SUCCEEDED(rv)) {
193 ok = ::JS_DefinePropertyById(aCtx, scope, id, JSVAL_VOID, nullptr,
194 nullptr, JSPROP_ENUMERATE);
195 resolved = true;
199 *_retval = ok;
200 *_objp = resolved && ok ? scope.get() : nullptr;
201 return NS_OK;
204 } // namespace storage
205 } // namespace mozilla