1 // Copyright (c) 2012 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.
5 // This file contains definitions for CppVariant.
8 #include "base/logging.h"
9 #include "base/strings/string_util.h"
10 #include "base/strings/stringprintf.h"
11 #include "base/strings/utf_string_conversions.h"
12 #include "third_party/WebKit/public/web/WebBindings.h"
13 #include "webkit/renderer/cpp_variant.h"
15 using blink::WebBindings
;
17 namespace webkit_glue
{
19 CppVariant::CppVariant() {
20 type
= NPVariantType_Null
;
23 // Note that Set() performs a deep copy, which is necessary to safely
24 // call FreeData() on the value in the destructor.
25 CppVariant::CppVariant(const CppVariant
& original
) {
26 type
= NPVariantType_Null
;
30 // See comment for copy constructor, above.
31 CppVariant
& CppVariant::operator=(const CppVariant
& original
) {
32 if (&original
!= this)
37 CppVariant::~CppVariant() {
41 void CppVariant::FreeData() {
42 WebBindings::releaseVariantValue(this);
45 bool CppVariant::isEqual(const CppVariant
& other
) const {
46 if (type
!= other
.type
)
50 case NPVariantType_Bool
: {
51 return (value
.boolValue
== other
.value
.boolValue
);
53 case NPVariantType_Int32
: {
54 return (value
.intValue
== other
.value
.intValue
);
56 case NPVariantType_Double
: {
57 return (value
.doubleValue
== other
.value
.doubleValue
);
59 case NPVariantType_String
: {
60 const NPString
*this_value
= &value
.stringValue
;
61 const NPString
*other_value
= &other
.value
.stringValue
;
62 uint32_t len
= this_value
->UTF8Length
;
63 return (len
== other_value
->UTF8Length
&&
64 !strncmp(this_value
->UTF8Characters
, other_value
->UTF8Characters
,
67 case NPVariantType_Null
:
68 case NPVariantType_Void
: {
71 case NPVariantType_Object
: {
72 NPObject
*this_value
= value
.objectValue
;
73 NPObject
*other_value
= other
.value
.objectValue
;
74 return (this_value
->_class
== other_value
->_class
&&
75 this_value
->referenceCount
== other_value
->referenceCount
);
81 void CppVariant::CopyToNPVariant(NPVariant
* result
) const {
84 case NPVariantType_Bool
:
85 result
->value
.boolValue
= value
.boolValue
;
87 case NPVariantType_Int32
:
88 result
->value
.intValue
= value
.intValue
;
90 case NPVariantType_Double
:
91 result
->value
.doubleValue
= value
.doubleValue
;
93 case NPVariantType_String
:
94 WebBindings::initializeVariantWithStringCopy(result
, &value
.stringValue
);
96 case NPVariantType_Null
:
97 case NPVariantType_Void
:
100 case NPVariantType_Object
:
101 result
->type
= NPVariantType_Object
;
102 result
->value
.objectValue
= WebBindings::retainObject(value
.objectValue
);
107 void CppVariant::Set(const NPVariant
& new_value
) {
109 switch (new_value
.type
) {
110 case NPVariantType_Bool
:
111 Set(new_value
.value
.boolValue
);
113 case NPVariantType_Int32
:
114 Set(new_value
.value
.intValue
);
116 case NPVariantType_Double
:
117 Set(new_value
.value
.doubleValue
);
119 case NPVariantType_String
:
120 Set(new_value
.value
.stringValue
);
122 case NPVariantType_Null
:
123 case NPVariantType_Void
:
124 type
= new_value
.type
;
126 case NPVariantType_Object
:
127 Set(new_value
.value
.objectValue
);
132 void CppVariant::SetNull() {
134 type
= NPVariantType_Null
;
137 void CppVariant::Set(bool new_value
) {
139 type
= NPVariantType_Bool
;
140 value
.boolValue
= new_value
;
143 void CppVariant::Set(int32_t new_value
) {
145 type
= NPVariantType_Int32
;
146 value
.intValue
= new_value
;
149 void CppVariant::Set(double new_value
) {
151 type
= NPVariantType_Double
;
152 value
.doubleValue
= new_value
;
155 // The new_value must be a null-terminated string.
156 void CppVariant::Set(const char* new_value
) {
158 type
= NPVariantType_String
;
159 NPString new_string
= {new_value
,
160 static_cast<uint32_t>(strlen(new_value
))};
161 WebBindings::initializeVariantWithStringCopy(this, &new_string
);
164 void CppVariant::Set(const std::string
& new_value
) {
166 type
= NPVariantType_String
;
167 NPString new_string
= {new_value
.data(),
168 static_cast<uint32_t>(new_value
.size())};
169 WebBindings::initializeVariantWithStringCopy(this, &new_string
);
171 void CppVariant::Set(const NPString
& new_value
) {
173 type
= NPVariantType_String
;
174 WebBindings::initializeVariantWithStringCopy(this, &new_value
);
177 void CppVariant::Set(NPObject
* new_value
) {
179 type
= NPVariantType_Object
;
180 value
.objectValue
= WebBindings::retainObject(new_value
);
183 std::string
CppVariant::ToString() const {
185 return std::string(value
.stringValue
.UTF8Characters
,
186 value
.stringValue
.UTF8Length
);
189 int32_t CppVariant::ToInt32() const {
191 return value
.intValue
;
192 } else if (isDouble()) {
193 return static_cast<int32_t>(value
.doubleValue
);
200 double CppVariant::ToDouble() const {
202 return static_cast<double>(value
.intValue
);
203 } else if (isDouble()) {
204 return value
.doubleValue
;
211 bool CppVariant::ToBoolean() const {
213 return value
.boolValue
;
216 std::vector
<CppVariant
> CppVariant::ToVector() const {
218 std::vector
<CppVariant
> vector
;
219 NPObject
* np_value
= value
.objectValue
;
220 NPIdentifier length_id
= WebBindings::getStringIdentifier("length");
222 if (WebBindings::hasProperty(NULL
, np_value
, length_id
)) {
223 CppVariant length_value
;
224 if (WebBindings::getProperty(NULL
, np_value
, length_id
, &length_value
)) {
226 // The length is a double in some cases.
227 if (NPVARIANT_IS_DOUBLE(length_value
))
228 length
= static_cast<int>(NPVARIANT_TO_DOUBLE(length_value
));
229 else if (NPVARIANT_IS_INT32(length_value
))
230 length
= NPVARIANT_TO_INT32(length_value
);
234 // For sanity, only allow 60000 items.
235 length
= std::min(60000, length
);
236 for (int i
= 0; i
< length
; ++i
) {
237 // Get each of the items.
238 NPIdentifier index
= WebBindings::getIntIdentifier(i
);
239 if (WebBindings::hasProperty(NULL
, np_value
, index
)) {
240 CppVariant index_value
;
241 if (WebBindings::getProperty(NULL
, np_value
, index
, &index_value
))
242 vector
.push_back(index_value
);
252 bool CppVariant::Invoke(const std::string
& method
, const CppVariant
* args
,
253 uint32 arg_count
, CppVariant
& result
) const {
255 NPIdentifier method_name
= WebBindings::getStringIdentifier(method
.c_str());
256 NPObject
* np_object
= value
.objectValue
;
257 if (WebBindings::hasMethod(NULL
, np_object
, method_name
)) {
260 WebBindings::invoke(NULL
, np_object
, method_name
, args
, arg_count
, &r
);
268 } // namespace webkit_glue