1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/storage/src/mozStorageStatementRow.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,154 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- 1.5 + * vim: sw=2 ts=2 et lcs=trail\:.,tab\:>~ : 1.6 + * This Source Code Form is subject to the terms of the Mozilla Public 1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.9 + 1.10 +#include "nsMemory.h" 1.11 +#include "nsString.h" 1.12 + 1.13 +#include "mozStorageStatementRow.h" 1.14 +#include "mozStorageStatement.h" 1.15 + 1.16 +#include "jsapi.h" 1.17 + 1.18 +namespace mozilla { 1.19 +namespace storage { 1.20 + 1.21 +//////////////////////////////////////////////////////////////////////////////// 1.22 +//// StatementRow 1.23 + 1.24 +StatementRow::StatementRow(Statement *aStatement) 1.25 +: mStatement(aStatement) 1.26 +{ 1.27 +} 1.28 + 1.29 +NS_IMPL_ISUPPORTS( 1.30 + StatementRow, 1.31 + mozIStorageStatementRow, 1.32 + nsIXPCScriptable 1.33 +) 1.34 + 1.35 +//////////////////////////////////////////////////////////////////////////////// 1.36 +//// nsIXPCScriptable 1.37 + 1.38 +#define XPC_MAP_CLASSNAME StatementRow 1.39 +#define XPC_MAP_QUOTED_CLASSNAME "StatementRow" 1.40 +#define XPC_MAP_WANT_GETPROPERTY 1.41 +#define XPC_MAP_WANT_NEWRESOLVE 1.42 +#define XPC_MAP_FLAGS nsIXPCScriptable::ALLOW_PROP_MODS_DURING_RESOLVE 1.43 +#include "xpc_map_end.h" 1.44 + 1.45 +NS_IMETHODIMP 1.46 +StatementRow::GetProperty(nsIXPConnectWrappedNative *aWrapper, 1.47 + JSContext *aCtx, 1.48 + JSObject *aScopeObj, 1.49 + jsid aId, 1.50 + jsval *_vp, 1.51 + bool *_retval) 1.52 +{ 1.53 + NS_ENSURE_TRUE(mStatement, NS_ERROR_NOT_INITIALIZED); 1.54 + 1.55 + JS::RootedObject scope(aCtx, aScopeObj); 1.56 + if (JSID_IS_STRING(aId)) { 1.57 + ::JSAutoByteString idBytes(aCtx, JSID_TO_STRING(aId)); 1.58 + NS_ENSURE_TRUE(!!idBytes, NS_ERROR_OUT_OF_MEMORY); 1.59 + nsDependentCString jsid(idBytes.ptr()); 1.60 + 1.61 + uint32_t idx; 1.62 + nsresult rv = mStatement->GetColumnIndex(jsid, &idx); 1.63 + NS_ENSURE_SUCCESS(rv, rv); 1.64 + int32_t type; 1.65 + rv = mStatement->GetTypeOfIndex(idx, &type); 1.66 + NS_ENSURE_SUCCESS(rv, rv); 1.67 + 1.68 + if (type == mozIStorageValueArray::VALUE_TYPE_INTEGER || 1.69 + type == mozIStorageValueArray::VALUE_TYPE_FLOAT) { 1.70 + double dval; 1.71 + rv = mStatement->GetDouble(idx, &dval); 1.72 + NS_ENSURE_SUCCESS(rv, rv); 1.73 + *_vp = ::JS_NumberValue(dval); 1.74 + } 1.75 + else if (type == mozIStorageValueArray::VALUE_TYPE_TEXT) { 1.76 + uint32_t bytes; 1.77 + const jschar *sval = reinterpret_cast<const jschar *>( 1.78 + static_cast<mozIStorageStatement *>(mStatement)-> 1.79 + AsSharedWString(idx, &bytes) 1.80 + ); 1.81 + JSString *str = ::JS_NewUCStringCopyN(aCtx, sval, bytes / 2); 1.82 + if (!str) { 1.83 + *_retval = false; 1.84 + return NS_OK; 1.85 + } 1.86 + *_vp = STRING_TO_JSVAL(str); 1.87 + } 1.88 + else if (type == mozIStorageValueArray::VALUE_TYPE_BLOB) { 1.89 + uint32_t length; 1.90 + const uint8_t *blob = static_cast<mozIStorageStatement *>(mStatement)-> 1.91 + AsSharedBlob(idx, &length); 1.92 + JSObject *obj = ::JS_NewArrayObject(aCtx, length); 1.93 + if (!obj) { 1.94 + *_retval = false; 1.95 + return NS_OK; 1.96 + } 1.97 + *_vp = OBJECT_TO_JSVAL(obj); 1.98 + 1.99 + // Copy the blob over to the JS array. 1.100 + for (uint32_t i = 0; i < length; i++) { 1.101 + if (!::JS_SetElement(aCtx, scope, i, blob[i])) { 1.102 + *_retval = false; 1.103 + return NS_OK; 1.104 + } 1.105 + } 1.106 + } 1.107 + else if (type == mozIStorageValueArray::VALUE_TYPE_NULL) { 1.108 + *_vp = JSVAL_NULL; 1.109 + } 1.110 + else { 1.111 + NS_ERROR("unknown column type returned, what's going on?"); 1.112 + } 1.113 + } 1.114 + 1.115 + return NS_OK; 1.116 +} 1.117 + 1.118 +NS_IMETHODIMP 1.119 +StatementRow::NewResolve(nsIXPConnectWrappedNative *aWrapper, 1.120 + JSContext *aCtx, 1.121 + JSObject *aScopeObj, 1.122 + jsid aId, 1.123 + JSObject **_objp, 1.124 + bool *_retval) 1.125 +{ 1.126 + JS::Rooted<JSObject*> scopeObj(aCtx, aScopeObj); 1.127 + 1.128 + NS_ENSURE_TRUE(mStatement, NS_ERROR_NOT_INITIALIZED); 1.129 + // We do not throw at any point after this because we want to allow the 1.130 + // prototype chain to be checked for the property. 1.131 + 1.132 + if (JSID_IS_STRING(aId)) { 1.133 + ::JSAutoByteString idBytes(aCtx, JSID_TO_STRING(aId)); 1.134 + NS_ENSURE_TRUE(!!idBytes, NS_ERROR_OUT_OF_MEMORY); 1.135 + nsDependentCString name(idBytes.ptr()); 1.136 + 1.137 + uint32_t idx; 1.138 + nsresult rv = mStatement->GetColumnIndex(name, &idx); 1.139 + if (NS_FAILED(rv)) { 1.140 + // It's highly likely that the name doesn't exist, so let the JS engine 1.141 + // check the prototype chain and throw if that doesn't have the property 1.142 + // either. 1.143 + *_objp = nullptr; 1.144 + return NS_OK; 1.145 + } 1.146 + 1.147 + *_retval = ::JS_DefinePropertyById(aCtx, scopeObj, aId, JSVAL_VOID, 1.148 + nullptr, nullptr, 0); 1.149 + *_objp = scopeObj; 1.150 + return NS_OK; 1.151 + } 1.152 + 1.153 + return NS_OK; 1.154 +} 1.155 + 1.156 +} // namespace storage 1.157 +} // namescape mozilla