michael@0: /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- michael@0: * vim: sw=2 ts=2 et lcs=trail\:.,tab\:>~ : michael@0: * This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #include "nsMemory.h" michael@0: #include "nsString.h" michael@0: #include "nsCOMPtr.h" michael@0: michael@0: #include "jsapi.h" michael@0: michael@0: #include "mozStoragePrivateHelpers.h" michael@0: #include "mozStorageAsyncStatement.h" michael@0: #include "mozStorageAsyncStatementParams.h" michael@0: #include "mozIStorageStatement.h" michael@0: michael@0: namespace mozilla { michael@0: namespace storage { michael@0: michael@0: //////////////////////////////////////////////////////////////////////////////// michael@0: //// AsyncStatementParams michael@0: michael@0: AsyncStatementParams::AsyncStatementParams(AsyncStatement *aStatement) michael@0: : mStatement(aStatement) michael@0: { michael@0: NS_ASSERTION(mStatement != nullptr, "mStatement is null"); michael@0: } michael@0: michael@0: NS_IMPL_ISUPPORTS( michael@0: AsyncStatementParams michael@0: , mozIStorageStatementParams michael@0: , nsIXPCScriptable michael@0: ) michael@0: michael@0: //////////////////////////////////////////////////////////////////////////////// michael@0: //// nsIXPCScriptable michael@0: michael@0: #define XPC_MAP_CLASSNAME AsyncStatementParams michael@0: #define XPC_MAP_QUOTED_CLASSNAME "AsyncStatementParams" michael@0: #define XPC_MAP_WANT_SETPROPERTY michael@0: #define XPC_MAP_WANT_NEWRESOLVE michael@0: #define XPC_MAP_FLAGS nsIXPCScriptable::ALLOW_PROP_MODS_DURING_RESOLVE michael@0: #include "xpc_map_end.h" michael@0: michael@0: NS_IMETHODIMP michael@0: AsyncStatementParams::SetProperty( michael@0: nsIXPConnectWrappedNative *aWrapper, michael@0: JSContext *aCtx, michael@0: JSObject *aScopeObj, michael@0: jsid aId, michael@0: JS::Value *_vp, michael@0: bool *_retval michael@0: ) michael@0: { michael@0: NS_ENSURE_TRUE(mStatement, NS_ERROR_NOT_INITIALIZED); michael@0: michael@0: if (JSID_IS_INT(aId)) { michael@0: int idx = JSID_TO_INT(aId); michael@0: michael@0: nsCOMPtr variant(convertJSValToVariant(aCtx, *_vp)); michael@0: NS_ENSURE_TRUE(variant, NS_ERROR_UNEXPECTED); michael@0: nsresult rv = mStatement->BindByIndex(idx, variant); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: } michael@0: else if (JSID_IS_STRING(aId)) { michael@0: JSString *str = JSID_TO_STRING(aId); michael@0: size_t length; michael@0: const jschar *chars = JS_GetInternedStringCharsAndLength(str, &length); michael@0: NS_ConvertUTF16toUTF8 name(chars, length); michael@0: michael@0: nsCOMPtr variant(convertJSValToVariant(aCtx, *_vp)); michael@0: NS_ENSURE_TRUE(variant, NS_ERROR_UNEXPECTED); michael@0: nsresult rv = mStatement->BindByName(name, variant); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: } michael@0: else { michael@0: return NS_ERROR_INVALID_ARG; michael@0: } michael@0: michael@0: *_retval = true; michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: AsyncStatementParams::NewResolve( michael@0: nsIXPConnectWrappedNative *aWrapper, michael@0: JSContext *aCtx, michael@0: JSObject *aScopeObj, michael@0: jsid aId, michael@0: JSObject **_objp, michael@0: bool *_retval michael@0: ) michael@0: { michael@0: JS::Rooted scopeObj(aCtx, aScopeObj); michael@0: michael@0: NS_ENSURE_TRUE(mStatement, NS_ERROR_NOT_INITIALIZED); michael@0: // We do not throw at any point after this because we want to allow the michael@0: // prototype chain to be checked for the property. michael@0: michael@0: bool resolved = false; michael@0: bool ok = true; michael@0: if (JSID_IS_INT(aId)) { michael@0: uint32_t idx = JSID_TO_INT(aId); michael@0: // All indexes are good because we don't know how many parameters there michael@0: // really are. michael@0: ok = ::JS_DefineElement(aCtx, scopeObj, idx, JSVAL_VOID, nullptr, michael@0: nullptr, 0); michael@0: resolved = true; michael@0: } michael@0: else if (JSID_IS_STRING(aId)) { michael@0: // We are unable to tell if there's a parameter with this name and so michael@0: // we must assume that there is. This screws the rest of the prototype michael@0: // chain, but people really shouldn't be depending on this anyways. michael@0: ok = ::JS_DefinePropertyById(aCtx, scopeObj, aId, JSVAL_VOID, nullptr, michael@0: nullptr, 0); michael@0: resolved = true; michael@0: } michael@0: michael@0: *_retval = ok; michael@0: *_objp = resolved && ok ? scopeObj.get() : nullptr; michael@0: return NS_OK; michael@0: } michael@0: michael@0: } // namespace storage michael@0: } // namespace mozilla