OLD | NEW |
| (Empty) |
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "webkit/activex_shim/npn_scripting.h" | |
6 | |
7 #include "base/logging.h" | |
8 #include "base/string_util.h" | |
9 #include "webkit/activex_shim/npp_impl.h" | |
10 | |
11 namespace activex_shim { | |
12 | |
13 NPNScriptableObject::NPNScriptableObject() : npp_(NULL), object_(NULL) { | |
14 } | |
15 | |
16 NPNScriptableObject::NPNScriptableObject(NPP npp, NPObject* object) | |
17 : npp_(npp), | |
18 object_(object) { | |
19 } | |
20 | |
21 NPNScriptableObject::NPNScriptableObject(NPNScriptableObject& object) | |
22 : npp_(object.npp_), | |
23 object_(object.object_) { | |
24 if (object_) | |
25 g_browser->retainobject(object_); | |
26 } | |
27 | |
28 NPNScriptableObject::~NPNScriptableObject() { | |
29 Release(); | |
30 } | |
31 | |
32 NPNScriptableObject& NPNScriptableObject::operator=( | |
33 NPNScriptableObject& object) { | |
34 if (this == &object) | |
35 return *this; | |
36 if (object_) | |
37 g_browser->releaseobject(object_); | |
38 npp_ = object.npp_; | |
39 object_ = object.object_; | |
40 if (object_) | |
41 g_browser->retainobject(object_); | |
42 return *this; | |
43 } | |
44 | |
45 void NPNScriptableObject::Init(NPP npp, NPObject* object) { | |
46 Release(); | |
47 npp_ = npp; | |
48 object_ = object; | |
49 } | |
50 | |
51 void NPNScriptableObject::Release() { | |
52 if (object_) { | |
53 g_browser->releaseobject(object_); | |
54 object_ = NULL; | |
55 } | |
56 npp_ = NULL; | |
57 } | |
58 | |
59 bool NPNScriptableObject::HasProperty(const std::string& name) { | |
60 if (!IsValid()) | |
61 return false; | |
62 NPIdentifier id = g_browser->getstringidentifier(name.c_str()); | |
63 bool res = g_browser->hasproperty(npp_, object_, id); | |
64 // How do we release id since it's coming from the browser? the answer is | |
65 // we never release them. See implementation of NPN_GetStringIdentifier | |
66 // in npruntime.cpp. | |
67 return res; | |
68 } | |
69 | |
70 bool NPNScriptableObject::GetProperty(const std::string& name, NPVariant* ret) { | |
71 if (!IsValid()) | |
72 return false; | |
73 NPIdentifier id = g_browser->getstringidentifier(name.c_str()); | |
74 return g_browser->getproperty(npp_, object_, id, ret); | |
75 } | |
76 | |
77 bool NPNScriptableObject::SetProperty(const std::string& name, | |
78 const NPVariant& val) { | |
79 if (!IsValid()) | |
80 return false; | |
81 NPIdentifier id = g_browser->getstringidentifier(name.c_str()); | |
82 return g_browser->setproperty(npp_, object_, id, &val); | |
83 } | |
84 | |
85 NPNScriptableObject NPNScriptableObject::GetObjectProperty( | |
86 const std::string& name, | |
87 bool* succeeded) { | |
88 NPNScriptableObject res; | |
89 if (succeeded) | |
90 *succeeded = false; | |
91 NPVariant var; | |
92 if (!GetProperty(name, &var)) | |
93 return res; | |
94 if (var.type == NPVariantType_Object) { | |
95 res.Init(npp_, var.value.objectValue); | |
96 // From now, the object should have reference count as 1. We shall not | |
97 // release the variant cause it will release the object. | |
98 if (succeeded) | |
99 *succeeded = true; | |
100 } else { | |
101 g_browser->releasevariantvalue(&var); | |
102 } | |
103 return res; | |
104 } | |
105 | |
106 std::wstring NPNScriptableObject::GetStringProperty(const std::string& name, | |
107 bool* succeeded) { | |
108 std::wstring res; | |
109 if (succeeded) | |
110 *succeeded = false; | |
111 NPVariant var; | |
112 if (!GetProperty(name, &var)) | |
113 return res; | |
114 if (var.type == NPVariantType_String) { | |
115 std::string tmp(var.value.stringValue.UTF8Characters, | |
116 var.value.stringValue.UTF8Length); | |
117 res = UTF8ToWide(tmp.c_str()); | |
118 if (succeeded) | |
119 *succeeded = true; | |
120 } | |
121 // We've made a copy of the string. Thus we should release the variant in | |
122 // any case. | |
123 g_browser->releasevariantvalue(&var); | |
124 return res; | |
125 } | |
126 | |
127 bool NPNScriptableObject::SetStringProperty(const std::string& name, | |
128 const std::wstring& val) { | |
129 NPVariantWrap var; | |
130 var.SetString(val); | |
131 return SetProperty(name, var); | |
132 } | |
133 | |
134 bool NPNScriptableObject::Invoke(const std::string& name, | |
135 const char* format, ...) { | |
136 if (!IsValid()) | |
137 return false; | |
138 NPIdentifier id = g_browser->getstringidentifier(name.c_str()); | |
139 std::vector<NPVariantWrap> args; | |
140 va_list argptr; | |
141 va_start(argptr, format); | |
142 for (const char* p = format; *p; ++p) { | |
143 char c = *p; | |
144 DCHECK(c == '%' && *(p + 1) != 0); | |
145 if (c != '%' || *(p + 1) == 0) | |
146 continue; | |
147 ++p; | |
148 c = *p; | |
149 NPVariantWrap var; | |
150 switch(c) { | |
151 case 's': { | |
152 // String | |
153 wchar_t *s = va_arg(argptr, wchar_t*); | |
154 var.SetString(s); | |
155 break; | |
156 } | |
157 case 'd': { | |
158 // String | |
159 int n = va_arg(argptr, int); | |
160 var.SetInt(n); | |
161 break; | |
162 } | |
163 default: { | |
164 DCHECK(false); | |
165 break; | |
166 } | |
167 } | |
168 args.push_back(var); | |
169 } | |
170 NPVariant ret; | |
171 ret.type = NPVariantType_Void; | |
172 bool res = false; | |
173 if (args.size()) | |
174 res = g_browser->invoke(npp_, object_, id, &args[0], | |
175 static_cast<unsigned int>(args.size()), &ret); | |
176 else | |
177 res = g_browser->invoke(npp_, object_, id, NULL, 0, &ret); | |
178 | |
179 g_browser->releasevariantvalue(&ret); | |
180 return res; | |
181 } | |
182 | |
183 NPVariantWrap::NPVariantWrap() { | |
184 type = NPVariantType_Void; | |
185 } | |
186 | |
187 NPVariantWrap::NPVariantWrap(const NPVariantWrap& v) { | |
188 type = NPVariantType_Void; | |
189 Copy(v); | |
190 } | |
191 | |
192 NPVariantWrap::~NPVariantWrap() { | |
193 Release(); | |
194 } | |
195 | |
196 NPVariantWrap& NPVariantWrap::operator=(const NPVariantWrap& v) { | |
197 if (this != &v) | |
198 Copy(v); | |
199 return *this; | |
200 } | |
201 | |
202 void NPVariantWrap::Copy(const NPVariant& v) { | |
203 if (this == &v) | |
204 return; | |
205 Release(); | |
206 switch(v.type) { | |
207 case NPVariantType_Void: | |
208 break; | |
209 case NPVariantType_Null: | |
210 break; | |
211 case NPVariantType_Bool: | |
212 value.boolValue = v.value.boolValue; | |
213 break; | |
214 case NPVariantType_Int32: | |
215 value.intValue = v.value.intValue; | |
216 break; | |
217 case NPVariantType_Double: | |
218 value.doubleValue = v.value.doubleValue; | |
219 break; | |
220 case NPVariantType_String: | |
221 SetUTF8String(v.value.stringValue.UTF8Characters, | |
222 v.value.stringValue.UTF8Length); | |
223 break; | |
224 case NPVariantType_Object: | |
225 g_browser->retainobject(v.value.objectValue); | |
226 value.objectValue = v.value.objectValue; | |
227 break; | |
228 default: | |
229 DCHECK(false); | |
230 break; | |
231 } | |
232 type = v.type; | |
233 } | |
234 | |
235 void NPVariantWrap::Release() { | |
236 if (type == NPVariantType_String) { | |
237 delete[] value.stringValue.UTF8Characters; | |
238 } else if (type == NPVariantType_Object) { | |
239 g_browser->releaseobject(value.objectValue); | |
240 } | |
241 type = NPVariantType_Void; | |
242 } | |
243 | |
244 void NPVariantWrap::SetBool(bool val) { | |
245 Release(); | |
246 value.boolValue = val; | |
247 type = NPVariantType_Bool; | |
248 } | |
249 | |
250 void NPVariantWrap::SetInt(int val) { | |
251 Release(); | |
252 value.intValue = val; | |
253 type = NPVariantType_Int32; | |
254 } | |
255 | |
256 void NPVariantWrap::SetUTF8String(const NPUTF8* p, unsigned int size) { | |
257 Release(); | |
258 value.stringValue.UTF8Characters = new char[size + 1]; | |
259 memcpy(const_cast<NPUTF8*>(value.stringValue.UTF8Characters), | |
260 p, size + 1); | |
261 value.stringValue.UTF8Length = size; | |
262 type = NPVariantType_String; | |
263 } | |
264 | |
265 void NPVariantWrap::SetString(const std::wstring& val) { | |
266 std::string s = WideToUTF8(val); | |
267 SetUTF8String(s.c_str(), static_cast<unsigned int>(s.size())); | |
268 } | |
269 | |
270 } // namespace activex_shim | |
OLD | NEW |