172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file.
4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// This file contains definitions for CppVariant.
6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <limits>
872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "third_party/WebKit/Source/WebKit/chromium/public/WebBindings.h"
9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "webkit/glue/cpp_variant.h"
10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/logging.h"
11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/string_util.h"
123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/stringprintf.h"
13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/utf_string_conversions.h"
14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
15c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing WebKit::WebBindings;
16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
17c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochCppVariant::CppVariant() {
18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  type = NPVariantType_Null;
19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Note that Set() performs a deep copy, which is necessary to safely
22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// call FreeData() on the value in the destructor.
23c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochCppVariant::CppVariant(const CppVariant& original) {
24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  type = NPVariantType_Null;
25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Set(original);
26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// See comment for copy constructor, above.
29c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochCppVariant& CppVariant::operator=(const CppVariant& original) {
30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (&original != this)
31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    Set(original);
32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return *this;
33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
35c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochCppVariant::~CppVariant() {
36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  FreeData();
37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid CppVariant::FreeData() {
40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  WebBindings::releaseVariantValue(this);
41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool CppVariant::isEqual(const CppVariant& other) const {
44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (type != other.type)
45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return false;
46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  switch (type) {
48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case NPVariantType_Bool: {
49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      return (value.boolValue == other.value.boolValue);
50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case NPVariantType_Int32: {
52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      return (value.intValue == other.value.intValue);
53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case NPVariantType_Double: {
55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      return (value.doubleValue == other.value.doubleValue);
56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case NPVariantType_String: {
58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      const NPString *this_value = &value.stringValue;
59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      const NPString *other_value = &other.value.stringValue;
60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      uint32_t len = this_value->UTF8Length;
61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      return (len == other_value->UTF8Length &&
62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch              !strncmp(this_value->UTF8Characters, other_value->UTF8Characters,
63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                       len));
64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case NPVariantType_Null:
66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case NPVariantType_Void: {
67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      return true;
68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case NPVariantType_Object: {
70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NPObject *this_value = value.objectValue;
71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NPObject *other_value = other.value.objectValue;
72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      return (this_value->_class == other_value->_class &&
73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch              this_value->referenceCount == other_value->referenceCount);
74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return false;
77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid CppVariant::CopyToNPVariant(NPVariant* result) const {
80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  result->type = type;
81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  switch (type) {
82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case NPVariantType_Bool:
83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      result->value.boolValue = value.boolValue;
84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      break;
85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case NPVariantType_Int32:
86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      result->value.intValue = value.intValue;
87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      break;
88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case NPVariantType_Double:
89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      result->value.doubleValue = value.doubleValue;
90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      break;
91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case NPVariantType_String:
92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      WebBindings::initializeVariantWithStringCopy(result, &value.stringValue);
93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      break;
94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case NPVariantType_Null:
95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case NPVariantType_Void:
96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // Nothing to set.
97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      break;
98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case NPVariantType_Object:
99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      result->type = NPVariantType_Object;
100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      result->value.objectValue = WebBindings::retainObject(value.objectValue);
101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      break;
102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid CppVariant::Set(const NPVariant& new_value) {
106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  FreeData();
107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  switch (new_value.type) {
108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case NPVariantType_Bool:
109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      Set(new_value.value.boolValue);
110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      break;
111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case NPVariantType_Int32:
112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      Set(new_value.value.intValue);
113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      break;
114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case NPVariantType_Double:
115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      Set(new_value.value.doubleValue);
116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      break;
117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case NPVariantType_String:
118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      Set(new_value.value.stringValue);
119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      break;
120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case NPVariantType_Null:
121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case NPVariantType_Void:
122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      type = new_value.type;
123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      break;
124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case NPVariantType_Object:
125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      Set(new_value.value.objectValue);
126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      break;
127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid CppVariant::SetNull() {
131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  FreeData();
132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  type = NPVariantType_Null;
133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid CppVariant::Set(bool new_value) {
136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  FreeData();
137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  type = NPVariantType_Bool;
138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  value.boolValue = new_value;
139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid CppVariant::Set(int32_t new_value) {
142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  FreeData();
143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  type = NPVariantType_Int32;
144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  value.intValue = new_value;
145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid CppVariant::Set(double new_value) {
148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  FreeData();
149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  type = NPVariantType_Double;
150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  value.doubleValue = new_value;
151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// The new_value must be a null-terminated string.
154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid CppVariant::Set(const char* new_value) {
155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  FreeData();
156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  type = NPVariantType_String;
157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  NPString new_string = {new_value,
158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                         static_cast<uint32_t>(strlen(new_value))};
159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  WebBindings::initializeVariantWithStringCopy(this, &new_string);
160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid CppVariant::Set(const std::string& new_value) {
163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  FreeData();
164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  type = NPVariantType_String;
165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  NPString new_string = {new_value.data(),
166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                         static_cast<uint32_t>(new_value.size())};
167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  WebBindings::initializeVariantWithStringCopy(this, &new_string);
168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid CppVariant::Set(const NPString& new_value) {
170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  FreeData();
171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  type = NPVariantType_String;
172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  WebBindings::initializeVariantWithStringCopy(this, &new_value);
173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid CppVariant::Set(NPObject* new_value) {
176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  FreeData();
177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  type = NPVariantType_Object;
178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  value.objectValue = WebBindings::retainObject(new_value);
179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstd::string CppVariant::ToString() const {
182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(isString());
183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return std::string(value.stringValue.UTF8Characters,
184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                     value.stringValue.UTF8Length);
185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochint32_t CppVariant::ToInt32() const {
188c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (isInt32()) {
189c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return value.intValue;
190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else if (isDouble()) {
191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return static_cast<int32_t>(value.doubleValue);
192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else {
193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    NOTREACHED();
194c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return 0;
195c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
196c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
197c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
198c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochdouble CppVariant::ToDouble() const {
199c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (isInt32()) {
200c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return static_cast<double>(value.intValue);
201c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else if (isDouble()) {
202c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return value.doubleValue;
203c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else {
204c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    NOTREACHED();
205c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return 0.0;
206c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
207c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
208c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool CppVariant::ToBoolean() const {
210c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(isBool());
211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return value.boolValue;
212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
21472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenstd::vector<CppVariant> CppVariant::ToVector() const {
215c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(isObject());
21672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  std::vector<CppVariant> vector;
217c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  NPObject* np_value = value.objectValue;
218c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  NPIdentifier length_id = WebBindings::getStringIdentifier("length");
219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
220c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (WebBindings::hasProperty(NULL, np_value, length_id)) {
22172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    CppVariant length_value;
222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (WebBindings::getProperty(NULL, np_value, length_id, &length_value)) {
223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      int length = 0;
224c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // The length is a double in some cases.
225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      if (NPVARIANT_IS_DOUBLE(length_value))
226c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        length = static_cast<int>(NPVARIANT_TO_DOUBLE(length_value));
227c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      else if (NPVARIANT_IS_INT32(length_value))
228c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        length = NPVARIANT_TO_INT32(length_value);
22972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      else
23072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        NOTREACHED();
231c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      // For sanity, only allow 60000 items.
2333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      length = std::min(60000, length);
234c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      for (int i = 0; i < length; ++i) {
235c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        // Get each of the items.
23672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        NPIdentifier index = WebBindings::getIntIdentifier(i);
23772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        if (WebBindings::hasProperty(NULL, np_value, index)) {
23872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen          CppVariant index_value;
23972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen          if (WebBindings::getProperty(NULL, np_value, index, &index_value))
24072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen            vector.push_back(index_value);
241c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        }
242c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      }
243c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
24472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  } else {
24572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    NOTREACHED();
246c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
24772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  return vector;
248c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
249c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
250c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool CppVariant::Invoke(const std::string& method, const CppVariant* args,
251c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                        uint32 arg_count, CppVariant& result) const {
252c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(isObject());
253c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  NPIdentifier method_name = WebBindings::getStringIdentifier(method.c_str());
254c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  NPObject* np_object = value.objectValue;
255c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (WebBindings::hasMethod(NULL, np_object, method_name)) {
256c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    NPVariant r;
257c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    bool status = WebBindings::invoke(NULL, np_object, method_name, args, arg_count, &r);
258c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    result.Set(r);
259c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return status;
260c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else {
261c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return false;
262c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
263c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
264