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 : * ***** BEGIN LICENSE BLOCK *****
4 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 : *
6 : * The contents of this file are subject to the Mozilla Public License Version
7 : * 1.1 (the "License"); you may not use this file except in compliance with
8 : * the License. You may obtain a copy of the License at
9 : * http://www.mozilla.org/MPL/
10 : *
11 : * Software distributed under the License is distributed on an "AS IS" basis,
12 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13 : * for the specific language governing rights and limitations under the
14 : * License.
15 : *
16 : * The Original Code is Oracle Corporation code.
17 : *
18 : * The Initial Developer of the Original Code is
19 : * Oracle Corporation
20 : * Portions created by the Initial Developer are Copyright (C) 2004
21 : * the Initial Developer. All Rights Reserved.
22 : *
23 : * Contributor(s):
24 : * Vladimir Vukicevic <vladimir.vukicevic@oracle.com>
25 : * Shawn Wilsher <me@shawnwilsher.com>
26 : *
27 : * Alternatively, the contents of this file may be used under the terms of
28 : * either the GNU General Public License Version 2 or later (the "GPL"), or
29 : * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
30 : * in which case the provisions of the GPL or the LGPL are applicable instead
31 : * of those above. If you wish to allow use of your version of this file only
32 : * under the terms of either the GPL or the LGPL, and not to allow others to
33 : * use your version of this file under the terms of the MPL, indicate your
34 : * decision by deleting the provisions above and replace them with the notice
35 : * and other provisions required by the GPL or the LGPL. If you do not delete
36 : * the provisions above, a recipient may use your version of this file under
37 : * the terms of any one of the MPL, the GPL or the LGPL.
38 : *
39 : * ***** END LICENSE BLOCK ***** */
40 :
41 : #include "nsMemory.h"
42 : #include "nsString.h"
43 :
44 : #include "mozStorageStatementRow.h"
45 : #include "mozStorageStatement.h"
46 :
47 : #include "jsapi.h"
48 :
49 : namespace mozilla {
50 : namespace storage {
51 :
52 : ////////////////////////////////////////////////////////////////////////////////
53 : //// StatementRow
54 :
55 2673 : StatementRow::StatementRow(Statement *aStatement)
56 2673 : : mStatement(aStatement)
57 : {
58 2673 : }
59 :
60 82864 : NS_IMPL_ISUPPORTS2(
61 : StatementRow,
62 : mozIStorageStatementRow,
63 : nsIXPCScriptable
64 : )
65 :
66 : ////////////////////////////////////////////////////////////////////////////////
67 : //// nsIXPCScriptable
68 :
69 : #define XPC_MAP_CLASSNAME StatementRow
70 : #define XPC_MAP_QUOTED_CLASSNAME "StatementRow"
71 : #define XPC_MAP_WANT_GETPROPERTY
72 : #define XPC_MAP_WANT_NEWRESOLVE
73 : #define XPC_MAP_FLAGS nsIXPCScriptable::ALLOW_PROP_MODS_DURING_RESOLVE
74 : #include "xpc_map_end.h"
75 :
76 : NS_IMETHODIMP
77 64321 : StatementRow::GetProperty(nsIXPConnectWrappedNative *aWrapper,
78 : JSContext *aCtx,
79 : JSObject *aScopeObj,
80 : jsid aId,
81 : jsval *_vp,
82 : bool *_retval)
83 : {
84 64321 : NS_ENSURE_TRUE(mStatement, NS_ERROR_NOT_INITIALIZED);
85 :
86 64321 : if (JSID_IS_STRING(aId)) {
87 128642 : ::JSAutoByteString idBytes(aCtx, JSID_TO_STRING(aId));
88 64321 : NS_ENSURE_TRUE(!!idBytes, NS_ERROR_OUT_OF_MEMORY);
89 128642 : nsDependentCString jsid(idBytes.ptr());
90 :
91 : PRUint32 idx;
92 64321 : nsresult rv = mStatement->GetColumnIndex(jsid, &idx);
93 64321 : NS_ENSURE_SUCCESS(rv, rv);
94 : PRInt32 type;
95 64320 : rv = mStatement->GetTypeOfIndex(idx, &type);
96 64320 : NS_ENSURE_SUCCESS(rv, rv);
97 :
98 64320 : if (type == mozIStorageValueArray::VALUE_TYPE_INTEGER ||
99 : type == mozIStorageValueArray::VALUE_TYPE_FLOAT) {
100 : double dval;
101 29615 : rv = mStatement->GetDouble(idx, &dval);
102 29615 : NS_ENSURE_SUCCESS(rv, rv);
103 29615 : if (!::JS_NewNumberValue(aCtx, dval, _vp)) {
104 0 : *_retval = false;
105 0 : return NS_OK;
106 29615 : }
107 : }
108 34705 : else if (type == mozIStorageValueArray::VALUE_TYPE_TEXT) {
109 : PRUint32 bytes;
110 : const jschar *sval = reinterpret_cast<const jschar *>(
111 : static_cast<mozIStorageStatement *>(mStatement)->
112 24637 : AsSharedWString(idx, &bytes)
113 24637 : );
114 24637 : JSString *str = ::JS_NewUCStringCopyN(aCtx, sval, bytes / 2);
115 24637 : if (!str) {
116 0 : *_retval = false;
117 0 : return NS_OK;
118 : }
119 24637 : *_vp = STRING_TO_JSVAL(str);
120 : }
121 10068 : else if (type == mozIStorageValueArray::VALUE_TYPE_BLOB) {
122 : PRUint32 length;
123 : const PRUint8 *blob = static_cast<mozIStorageStatement *>(mStatement)->
124 0 : AsSharedBlob(idx, &length);
125 0 : JSObject *obj = ::JS_NewArrayObject(aCtx, length, nsnull);
126 0 : if (!obj) {
127 0 : *_retval = false;
128 0 : return NS_OK;
129 : }
130 0 : *_vp = OBJECT_TO_JSVAL(obj);
131 :
132 : // Copy the blob over to the JS array.
133 0 : for (PRUint32 i = 0; i < length; i++) {
134 0 : jsval val = INT_TO_JSVAL(blob[i]);
135 0 : if (!::JS_SetElement(aCtx, aScopeObj, i, &val)) {
136 0 : *_retval = false;
137 0 : return NS_OK;
138 : }
139 : }
140 : }
141 10068 : else if (type == mozIStorageValueArray::VALUE_TYPE_NULL) {
142 10068 : *_vp = JSVAL_NULL;
143 : }
144 : else {
145 0 : NS_ERROR("unknown column type returned, what's going on?");
146 : }
147 : }
148 :
149 64320 : return NS_OK;
150 : }
151 :
152 : NS_IMETHODIMP
153 20833 : StatementRow::NewResolve(nsIXPConnectWrappedNative *aWrapper,
154 : JSContext *aCtx,
155 : JSObject *aScopeObj,
156 : jsid aId,
157 : PRUint32 aFlags,
158 : JSObject **_objp,
159 : bool *_retval)
160 : {
161 20833 : NS_ENSURE_TRUE(mStatement, NS_ERROR_NOT_INITIALIZED);
162 : // We do not throw at any point after this because we want to allow the
163 : // prototype chain to be checked for the property.
164 :
165 20833 : if (JSID_IS_STRING(aId)) {
166 41666 : ::JSAutoByteString idBytes(aCtx, JSID_TO_STRING(aId));
167 20833 : NS_ENSURE_TRUE(!!idBytes, NS_ERROR_OUT_OF_MEMORY);
168 41666 : nsDependentCString name(idBytes.ptr());
169 :
170 : PRUint32 idx;
171 20833 : nsresult rv = mStatement->GetColumnIndex(name, &idx);
172 20833 : if (NS_FAILED(rv)) {
173 : // It's highly likely that the name doesn't exist, so let the JS engine
174 : // check the prototype chain and throw if that doesn't have the property
175 : // either.
176 2 : *_objp = NULL;
177 2 : return NS_OK;
178 : }
179 :
180 : *_retval = ::JS_DefinePropertyById(aCtx, aScopeObj, aId, JSVAL_VOID,
181 20831 : nsnull, nsnull, 0);
182 20831 : *_objp = aScopeObj;
183 20831 : return NS_OK;
184 : }
185 :
186 0 : return NS_OK;
187 : }
188 :
189 : } // namespace storage
190 : } // namescape mozilla
|