2 * Copyright (C) 2010 Google Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above
11 * copyright notice, this list of conditions and the following disclaimer
12 * in the documentation and/or other materials provided with the
14 * * Neither the name of Google Inc. nor the names of its
15 * contributors may be used to endorse or promote products derived from
16 * this software without specific prior written permission.
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 #include "CppVariant.h"
34 #include "WebBindings.h"
36 #include <wtf/Assertions.h>
37 #include <wtf/StringExtras.h>
39 using namespace WebKit;
42 CppVariant::CppVariant()
44 type = NPVariantType_Null;
47 // Note that Set() performs a deep copy, which is necessary to safely
48 // call FreeData() on the value in the destructor.
49 CppVariant::CppVariant(const CppVariant& original)
51 type = NPVariantType_Null;
55 // See comment for copy constructor, above.
56 CppVariant& CppVariant::operator=(const CppVariant& original)
58 if (&original != this)
63 CppVariant::~CppVariant()
68 void CppVariant::freeData()
70 WebBindings::releaseVariantValue(this);
73 bool CppVariant::isEqual(const CppVariant& other) const
75 if (type != other.type)
79 case NPVariantType_Bool:
80 return (value.boolValue == other.value.boolValue);
81 case NPVariantType_Int32:
82 return (value.intValue == other.value.intValue);
83 case NPVariantType_Double:
84 return (value.doubleValue == other.value.doubleValue);
85 case NPVariantType_String: {
86 const NPString *this_value = &value.stringValue;
87 const NPString *other_value = &other.value.stringValue;
88 uint32_t len = this_value->UTF8Length;
89 return len == other_value->UTF8Length
90 && !strncmp(this_value->UTF8Characters,
91 other_value->UTF8Characters, len);
93 case NPVariantType_Null:
94 case NPVariantType_Void:
96 case NPVariantType_Object: {
97 NPObject* thisValue = value.objectValue;
98 NPObject* otherValue = other.value.objectValue;
99 return thisValue->_class == otherValue->_class
100 && thisValue->referenceCount == otherValue->referenceCount;
106 void CppVariant::copyToNPVariant(NPVariant* result) const
110 case NPVariantType_Bool:
111 result->value.boolValue = value.boolValue;
113 case NPVariantType_Int32:
114 result->value.intValue = value.intValue;
116 case NPVariantType_Double:
117 result->value.doubleValue = value.doubleValue;
119 case NPVariantType_String:
120 WebBindings::initializeVariantWithStringCopy(result, &value.stringValue);
122 case NPVariantType_Null:
123 case NPVariantType_Void:
126 case NPVariantType_Object:
127 result->type = NPVariantType_Object;
128 result->value.objectValue = WebBindings::retainObject(value.objectValue);
133 void CppVariant::set(const NPVariant& newValue)
136 switch (newValue.type) {
137 case NPVariantType_Bool:
138 set(newValue.value.boolValue);
140 case NPVariantType_Int32:
141 set(newValue.value.intValue);
143 case NPVariantType_Double:
144 set(newValue.value.doubleValue);
146 case NPVariantType_String:
147 set(newValue.value.stringValue);
149 case NPVariantType_Null:
150 case NPVariantType_Void:
151 type = newValue.type;
153 case NPVariantType_Object:
154 set(newValue.value.objectValue);
159 void CppVariant::setNull()
162 type = NPVariantType_Null;
165 void CppVariant::set(bool newValue)
168 type = NPVariantType_Bool;
169 value.boolValue = newValue;
172 void CppVariant::set(int32_t newValue)
175 type = NPVariantType_Int32;
176 value.intValue = newValue;
179 void CppVariant::set(double newValue)
182 type = NPVariantType_Double;
183 value.doubleValue = newValue;
186 // The newValue must be a null-terminated string.
187 void CppVariant::set(const char* newValue)
190 type = NPVariantType_String;
191 NPString newString = {newValue,
192 static_cast<uint32_t>(strlen(newValue))};
193 WebBindings::initializeVariantWithStringCopy(this, &newString);
196 void CppVariant::set(const string& newValue)
199 type = NPVariantType_String;
200 NPString newString = {newValue.data(),
201 static_cast<uint32_t>(newValue.size())};
202 WebBindings::initializeVariantWithStringCopy(this, &newString);
205 void CppVariant::set(const NPString& newValue)
208 type = NPVariantType_String;
209 WebBindings::initializeVariantWithStringCopy(this, &newValue);
212 void CppVariant::set(NPObject* newValue)
215 type = NPVariantType_Object;
216 value.objectValue = WebBindings::retainObject(newValue);
219 string CppVariant::toString() const
222 return string(value.stringValue.UTF8Characters,
223 value.stringValue.UTF8Length);
226 int32_t CppVariant::toInt32() const
229 return value.intValue;
231 return static_cast<int32_t>(value.doubleValue);
232 ASSERT_NOT_REACHED();
236 double CppVariant::toDouble() const
239 return static_cast<double>(value.intValue);
241 return value.doubleValue;
242 ASSERT_NOT_REACHED();
246 bool CppVariant::toBoolean() const
249 return value.boolValue;
252 Vector<string> CppVariant::toStringVector() const
256 Vector<string> stringVector;
257 NPObject* npValue = value.objectValue;
258 NPIdentifier lengthId = WebBindings::getStringIdentifier("length");
260 if (!WebBindings::hasProperty(0, npValue, lengthId))
263 NPVariant lengthValue;
264 if (!WebBindings::getProperty(0, npValue, lengthId, &lengthValue))
268 // The length is a double in some cases.
269 if (NPVARIANT_IS_DOUBLE(lengthValue))
270 length = static_cast<int>(NPVARIANT_TO_DOUBLE(lengthValue));
271 else if (NPVARIANT_IS_INT32(lengthValue))
272 length = NPVARIANT_TO_INT32(lengthValue);
273 WebBindings::releaseVariantValue(&lengthValue);
275 // For sanity, only allow 100 items.
276 length = min(100, length);
277 for (int i = 0; i < length; ++i) {
278 // Get each of the items.
279 char indexInChar[20]; // Enough size to store 32-bit integer
280 snprintf(indexInChar, 20, "%d", i);
281 string index(indexInChar);
282 NPIdentifier indexId = WebBindings::getStringIdentifier(index.c_str());
283 if (!WebBindings::hasProperty(0, npValue, indexId))
285 NPVariant indexValue;
286 if (!WebBindings::getProperty(0, npValue, indexId, &indexValue))
288 if (NPVARIANT_IS_STRING(indexValue)) {
289 string item(NPVARIANT_TO_STRING(indexValue).UTF8Characters,
290 NPVARIANT_TO_STRING(indexValue).UTF8Length);
291 stringVector.append(item);
293 WebBindings::releaseVariantValue(&indexValue);
298 bool CppVariant::invoke(const string& method, const CppVariant* arguments,
299 uint32_t argumentCount, CppVariant& result) const
302 NPIdentifier methodName = WebBindings::getStringIdentifier(method.c_str());
303 NPObject* npObject = value.objectValue;
304 if (!WebBindings::hasMethod(0, npObject, methodName))
307 bool status = WebBindings::invoke(0, npObject, methodName, arguments, argumentCount, &r);