Line data Source code
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 "nsMemory.h"
8 : #include "nsString.h"
9 :
10 : #include "mozStorageStatementRow.h"
11 : #include "mozStorageStatement.h"
12 :
13 : #include "jsapi.h"
14 :
15 : #include "xpc_make_class.h"
16 :
17 : namespace mozilla {
18 : namespace storage {
19 :
20 : ////////////////////////////////////////////////////////////////////////////////
21 : //// StatementRow
22 :
23 0 : StatementRow::StatementRow(Statement *aStatement)
24 0 : : mStatement(aStatement)
25 : {
26 0 : }
27 :
28 0 : NS_IMPL_ISUPPORTS(
29 : StatementRow,
30 : mozIStorageStatementRow,
31 : nsIXPCScriptable
32 : )
33 :
34 : ////////////////////////////////////////////////////////////////////////////////
35 : //// nsIXPCScriptable
36 :
37 : #define XPC_MAP_CLASSNAME StatementRow
38 : #define XPC_MAP_QUOTED_CLASSNAME "StatementRow"
39 : #define XPC_MAP_FLAGS (XPC_SCRIPTABLE_WANT_GETPROPERTY | \
40 : XPC_SCRIPTABLE_WANT_RESOLVE | \
41 : XPC_SCRIPTABLE_ALLOW_PROP_MODS_DURING_RESOLVE)
42 : #include "xpc_map_end.h"
43 :
44 : NS_IMETHODIMP
45 0 : StatementRow::GetProperty(nsIXPConnectWrappedNative *aWrapper,
46 : JSContext *aCtx,
47 : JSObject *aScopeObj,
48 : jsid aId,
49 : JS::Value *_vp,
50 : bool *_retval)
51 : {
52 0 : NS_ENSURE_TRUE(mStatement, NS_ERROR_NOT_INITIALIZED);
53 :
54 0 : JS::RootedObject scope(aCtx, aScopeObj);
55 0 : if (JSID_IS_STRING(aId)) {
56 0 : ::JSAutoByteString idBytes(aCtx, JSID_TO_STRING(aId));
57 0 : NS_ENSURE_TRUE(!!idBytes, NS_ERROR_OUT_OF_MEMORY);
58 0 : nsDependentCString jsid(idBytes.ptr());
59 :
60 : uint32_t idx;
61 0 : nsresult rv = mStatement->GetColumnIndex(jsid, &idx);
62 0 : NS_ENSURE_SUCCESS(rv, rv);
63 : int32_t type;
64 0 : rv = mStatement->GetTypeOfIndex(idx, &type);
65 0 : NS_ENSURE_SUCCESS(rv, rv);
66 :
67 0 : if (type == mozIStorageValueArray::VALUE_TYPE_INTEGER ||
68 0 : type == mozIStorageValueArray::VALUE_TYPE_FLOAT) {
69 : double dval;
70 0 : rv = mStatement->GetDouble(idx, &dval);
71 0 : NS_ENSURE_SUCCESS(rv, rv);
72 0 : *_vp = ::JS_NumberValue(dval);
73 : }
74 0 : else if (type == mozIStorageValueArray::VALUE_TYPE_TEXT) {
75 : uint32_t bytes;
76 0 : const char16_t *sval = reinterpret_cast<const char16_t *>(
77 0 : static_cast<mozIStorageStatement *>(mStatement)->
78 : AsSharedWString(idx, &bytes)
79 0 : );
80 0 : JSString *str = ::JS_NewUCStringCopyN(aCtx, sval, bytes / 2);
81 0 : if (!str) {
82 0 : *_retval = false;
83 0 : return NS_OK;
84 : }
85 0 : _vp->setString(str);
86 : }
87 0 : else if (type == mozIStorageValueArray::VALUE_TYPE_BLOB) {
88 : uint32_t length;
89 0 : const uint8_t *blob = static_cast<mozIStorageStatement *>(mStatement)->
90 0 : AsSharedBlob(idx, &length);
91 0 : JSObject *obj = ::JS_NewArrayObject(aCtx, length);
92 0 : if (!obj) {
93 0 : *_retval = false;
94 0 : return NS_OK;
95 : }
96 0 : _vp->setObject(*obj);
97 :
98 : // Copy the blob over to the JS array.
99 0 : for (uint32_t i = 0; i < length; i++) {
100 0 : if (!::JS_DefineElement(aCtx, scope, i, blob[i], JSPROP_ENUMERATE)) {
101 0 : *_retval = false;
102 0 : return NS_OK;
103 : }
104 : }
105 : }
106 0 : else if (type == mozIStorageValueArray::VALUE_TYPE_NULL) {
107 0 : _vp->setNull();
108 : }
109 : else {
110 0 : NS_ERROR("unknown column type returned, what's going on?");
111 : }
112 : }
113 :
114 0 : return NS_OK;
115 : }
116 :
117 : NS_IMETHODIMP
118 0 : StatementRow::Resolve(nsIXPConnectWrappedNative *aWrapper,
119 : JSContext *aCtx,
120 : JSObject *aScopeObj,
121 : jsid aId,
122 : bool *aResolvedp,
123 : bool *_retval)
124 : {
125 0 : JS::Rooted<JSObject*> scopeObj(aCtx, aScopeObj);
126 :
127 0 : NS_ENSURE_TRUE(mStatement, NS_ERROR_NOT_INITIALIZED);
128 : // We do not throw at any point after this because we want to allow the
129 : // prototype chain to be checked for the property.
130 :
131 0 : if (JSID_IS_STRING(aId)) {
132 0 : ::JSAutoByteString idBytes(aCtx, JSID_TO_STRING(aId));
133 0 : NS_ENSURE_TRUE(!!idBytes, NS_ERROR_OUT_OF_MEMORY);
134 0 : nsDependentCString name(idBytes.ptr());
135 :
136 : uint32_t idx;
137 0 : nsresult rv = mStatement->GetColumnIndex(name, &idx);
138 0 : if (NS_FAILED(rv)) {
139 : // It's highly likely that the name doesn't exist, so let the JS engine
140 : // check the prototype chain and throw if that doesn't have the property
141 : // either.
142 0 : *aResolvedp = false;
143 0 : return NS_OK;
144 : }
145 :
146 0 : JS::Rooted<jsid> id(aCtx, aId);
147 0 : *_retval = ::JS_DefinePropertyById(aCtx, scopeObj, id, JS::UndefinedHandleValue,
148 : JSPROP_RESOLVING);
149 0 : *aResolvedp = true;
150 0 : return NS_OK;
151 : }
152 :
153 0 : return NS_OK;
154 : }
155 :
156 : } // namespace storage
157 : } // namespace mozilla
|