Make ncval-annotate and ncval-stubout executable
[nativeclient.git] / npapi_plugin / srpc / ret_array.cc
blob4d14f6b190bf02c99859eb184a8f674920a6b903
1 /*
2 * Copyright 2008, Google Inc.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met:
8 *
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * * Redistributions in binary form must reproduce the above
12 * copyright notice, this list of conditions and the following disclaimer
13 * in the documentation and/or other materials provided with the
14 * distribution.
15 * * Neither the name of Google Inc. nor the names of its
16 * contributors may be used to endorse or promote products derived from
17 * this software without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 #include <stdlib.h>
34 #include <string.h>
35 #include "native_client/npapi_plugin/srpc/plugin.h"
36 #include "native_client/npapi_plugin/srpc/ret_array.h"
37 #include "native_client/npapi_plugin/srpc/utility.h"
39 // TODO: this whole module should probably be replaced by
40 // a call to javascript eval to create an array object.
42 namespace nacl_srpc {
44 // Utility function to force to canonical integer NPIdentifiers.
45 static bool IsIntegerIdentifier(NPIdentifier ident);
46 static NPIdentifier ForceToIntegerIdent(NPIdentifier ident);
48 // Class variable definitions.
49 int RetArray::number_alive = 0;
51 // RetArray defines no methods.
52 bool RetArray::HasMethod(NPObject *obj, NPIdentifier name) {
53 dprintf(("RetArray::HasMethod(%p, %s)\n", obj, IdentToString(name)));
55 return false;
58 bool RetArray::Invoke(NPObject *obj,
59 NPIdentifier name,
60 const NPVariant *args,
61 uint32_t arg_count,
62 NPVariant *result) {
63 dprintf(("RetArray::Invoke(%p, %s, %d)\n",
64 obj, IdentToString(name), arg_count));
66 return false;
69 // RetArray defines a "length" property and one int property for
70 // each valid subscript [0..length-1].
71 bool RetArray::HasProperty(NPObject *obj, NPIdentifier name) {
72 RetArray* retarray = reinterpret_cast<RetArray*>(obj);
74 dprintf(("RetArray::HasProperty(%p, %s)\n", obj, IdentToString(name)));
76 if (Plugin::kLengthIdent == name) {
77 return true;
79 if (IsIntegerIdentifier(name)) {
80 name = ForceToIntegerIdent(name);
81 for (int i = 0; i < retarray->property_count_; ++i) {
82 if (name == retarray->properties_[i]) {
83 return true;
87 return false;
90 bool RetArray::GetProperty(NPObject *obj,
91 NPIdentifier name,
92 NPVariant *variant) {
93 RetArray* retarray = reinterpret_cast<RetArray*>(obj);
95 dprintf(("RetArray::GetProperty(%p, %s)\n", obj, IdentToString(name)));
97 if (Plugin::kLengthIdent == name) {
98 INT32_TO_NPVARIANT(retarray->property_count_, *variant);
99 return true;
101 name = ForceToIntegerIdent(name);
102 for (int i = 0; i < retarray->property_count_; ++i) {
103 if (name == retarray->properties_[i]) {
104 if (NPVARIANT_IS_STRING(retarray->values_[i])) {
105 NPString value_string = NPVARIANT_TO_STRING(retarray->values_[i]);
106 char* retstring =
107 reinterpret_cast<char*>(NPN_MemAlloc(value_string.utf8length));
108 memcpy(retstring, value_string.utf8characters, value_string.utf8length);
109 STRINGN_TO_NPVARIANT(retstring, value_string.utf8length, *variant);
110 } else if (NPVARIANT_IS_OBJECT(retarray->values_[i])) {
111 NPObject* prop = NPVARIANT_TO_OBJECT(retarray->values_[i]);
112 NPN_RetainObject(prop);
113 *variant = retarray->values_[i];
114 } else {
115 *variant = retarray->values_[i];
117 return true;
120 return false;
123 bool RetArray::SetProperty(NPObject *obj,
124 NPIdentifier name,
125 const NPVariant *variant) {
126 dprintf(("RetArray::SetProperty(%p, %s, %p)\n",
127 obj, IdentToString(name), variant));
129 return false;
132 RetArray* RetArray::New(Plugin* plugin, int property_count) {
133 dprintf(("RetArray::New(%p, %d)\n", plugin, property_count));
135 static NPClass retArrayClass = {
136 NP_CLASS_STRUCT_VERSION,
137 Allocate,
138 Deallocate,
139 Invalidate,
140 HasMethod,
141 Invoke,
143 HasProperty,
144 GetProperty,
145 SetProperty,
148 RetArray* retarray =
149 reinterpret_cast<RetArray*>(NPN_CreateObject(plugin->npp(),
150 &retArrayClass));
152 retarray->plugin_ = plugin;
153 retarray->property_count_ = property_count;
154 if (property_count > 0) {
155 // Allocate a vector of identifiers for integers [0,property_count).
156 retarray->properties_ = new NPIdentifier[property_count];
157 // Allocate a vector for the values mapped to.
158 retarray->values_ = new NPVariant[property_count];
159 for (int i = 0; i < property_count; ++i) {
160 retarray->properties_[i] = NPN_GetIntIdentifier(i);
161 // VOID represents JavaScript's undefined.
162 VOID_TO_NPVARIANT(retarray->values_[i]);
164 } else {
165 retarray->properties_ = NULL;
166 retarray->values_ = NULL;
169 return retarray;
172 NPObject *RetArray::Allocate(NPP npp, NPClass *theClass) {
173 dprintf(("RetArray::Allocate(%d)\n", ++number_alive));
175 return new RetArray(npp);
178 void RetArray::Deallocate(NPObject *obj) {
179 RetArray* retarray = reinterpret_cast<RetArray*>(obj);
181 dprintf(("RetArray::Deallocate(%p, %d)\n", obj, --number_alive));
183 if (retarray->property_count_ > 0) {
184 for (int i = 0; i < retarray->property_count_; ++i) {
185 dprintf(("Deallocate(%p): releasing %d -- \n", retarray, i));
186 NPN_ReleaseVariantValue(&retarray->values_[i]);
188 delete retarray->properties_;
189 delete retarray->values_;
191 delete reinterpret_cast<RetArray*>(obj);
194 void RetArray::Invalidate(NPObject *obj) {
195 RetArray* retarray = reinterpret_cast<RetArray*>(obj);
197 dprintf(("RetArray::Invalidate(%p)\n", obj));
199 // After invalidation, the browser does not respect reference counting,
200 // so we shut down here what we can and prevent attempts to shut down
201 // other linked structures in Deallocate.
203 if (retarray->property_count_ > 0) {
204 delete retarray->properties_;
205 retarray->properties_ = 0;
206 delete retarray->values_;
207 retarray->values_ = 0;
208 retarray->property_count_ = 0;
210 retarray->plugin_ = NULL;
213 RetArray::RetArray(NPP npp) : npp_(npp) {
214 dprintf(("RetArray::RetArray(%p)\n", this));
217 RetArray::~RetArray() {
218 dprintf(("RetArray::~RetArray(%p)\n", this));
221 // Force an identifier to a canonical integer NPIdentifier. This is
222 // needed because Safari likes to index by using character string names.
223 static bool IsIntegerIdentifier(NPIdentifier ident) {
224 if (NPN_IdentifierIsString(ident)) {
225 char* string = NPN_UTF8FromIdentifier(ident);
226 for (char* p = string; '\0' != *p; ++p) {
227 if (*p < '0' || *p > '9') {
228 return false;
231 return true;
232 } else {
233 return true;
237 static NPIdentifier ForceToIntegerIdent(NPIdentifier ident) {
238 if (NPN_IdentifierIsString(ident)) {
239 const char* str = NPN_UTF8FromIdentifier(ident);
240 int index = atoi(str);
241 return NPN_GetIntIdentifier(index);
242 } else {
243 return ident;
247 } // namespace nacl_srpc