| 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 |