diff --git a/ppapi/api/dev/ppb_var_array_dev.idl b/ppapi/api/dev/ppb_var_array_dev.idl
new file mode 100644
index 000000000000..78db3b0e9cb3
--- /dev/null
+++ b/ppapi/api/dev/ppb_var_array_dev.idl
@@ -0,0 +1,76 @@
+/* Copyright (c) 2013 The Chromium Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/**
+ * This file defines the PPB_VarArray_Dev
struct providing
+ * a way to interact with array vars.
+ */
+
+label Chrome {
+ M27 = 0.1
+};
+
+[macro="PPB_VAR_ARRAY_DEV_INTERFACE"]
+interface PPB_VarArray_Dev {
+ /**
+ * Creates an array var, i.e., a PP_Var
with type set to
+ * PP_VARTYPE_ARRAY
. The array length is set to 0.
+ *
+ * @return An empty array var, whose reference count is set to 1 on behalf of
+ * the caller.
+ */
+ PP_Var Create();
+
+ /**
+ * Gets an element from the array.
+ *
+ * @param[in] array An array var.
+ * @param[in] index An index indicating which element to return.
+ *
+ * @return The element at the specified position. The reference count is
+ * incremented on behalf of the caller. If index
is larger than
+ * or equal to the array length, an undefined var is returned.
+ */
+ PP_Var Get([in] PP_Var array, [in] uint32_t index);
+
+ /**
+ * Sets the value of an element in the array.
+ *
+ * @param[in] array An array var.
+ * @param[in] index An index indicating which element to modify. If
+ * index
is larger than or equal to the array length, the length
+ * is updated to be index
+ 1. Any position in the array that
+ * hasn't been set before is set to undefined, i.e., PP_Var
of
+ * type PP_VARTYPE_UNDEFINED
.
+ * @param[in] value The value to set. The array holds a reference to it on
+ * success.
+ *
+ * @return A PP_Bool
indicating whether the operation succeeds.
+ */
+ PP_Bool Set([in] PP_Var array, [in] uint32_t index, [in] PP_Var value);
+
+ /**
+ * Gets the array length.
+ *
+ * @param[in] array An array var.
+ *
+ * @return The array length.
+ */
+ uint32_t GetLength([in] PP_Var array);
+
+ /**
+ * Sets the array length.
+ *
+ * @param[in] array An array var.
+ * @param[in] length The new array length. If length
is smaller
+ * than its current value, the array is truncated to the new length; any
+ * elements that no longer fit are removed. If length
is larger
+ * than its current value, undefined vars are appended to increase the array
+ * to the specified length.
+ *
+ * @return A PP_Bool
indicating whether the operation succeeds.
+ */
+ PP_Bool SetLength([in] PP_Var array, [in] uint32_t length);
+};
diff --git a/ppapi/c/dev/ppb_var_array_dev.h b/ppapi/c/dev/ppb_var_array_dev.h
new file mode 100644
index 000000000000..3ce07fb88e5b
--- /dev/null
+++ b/ppapi/c/dev/ppb_var_array_dev.h
@@ -0,0 +1,94 @@
+/* Copyright (c) 2013 The Chromium Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/* From dev/ppb_var_array_dev.idl modified Thu Mar 14 13:41:46 2013. */
+
+#ifndef PPAPI_C_DEV_PPB_VAR_ARRAY_DEV_H_
+#define PPAPI_C_DEV_PPB_VAR_ARRAY_DEV_H_
+
+#include "ppapi/c/pp_bool.h"
+#include "ppapi/c/pp_macros.h"
+#include "ppapi/c/pp_stdint.h"
+#include "ppapi/c/pp_var.h"
+
+#define PPB_VAR_ARRAY_DEV_INTERFACE_0_1 "PPB_VarArray(Dev);0.1"
+#define PPB_VAR_ARRAY_DEV_INTERFACE PPB_VAR_ARRAY_DEV_INTERFACE_0_1
+
+/**
+ * @file
+ * This file defines the PPB_VarArray_Dev
struct providing
+ * a way to interact with array vars.
+ */
+
+
+/**
+ * @addtogroup Interfaces
+ * @{
+ */
+struct PPB_VarArray_Dev_0_1 {
+ /**
+ * Creates an array var, i.e., a PP_Var
with type set to
+ * PP_VARTYPE_ARRAY
. The array length is set to 0.
+ *
+ * @return An empty array var, whose reference count is set to 1 on behalf of
+ * the caller.
+ */
+ struct PP_Var (*Create)(void);
+ /**
+ * Gets an element from the array.
+ *
+ * @param[in] array An array var.
+ * @param[in] index An index indicating which element to return.
+ *
+ * @return The element at the specified position. The reference count is
+ * incremented on behalf of the caller. If index
is larger than
+ * or equal to the array length, an undefined var is returned.
+ */
+ struct PP_Var (*Get)(struct PP_Var array, uint32_t index);
+ /**
+ * Sets the value of an element in the array.
+ *
+ * @param[in] array An array var.
+ * @param[in] index An index indicating which element to modify. If
+ * index
is larger than or equal to the array length, the length
+ * is updated to be index
+ 1. Any position in the array that
+ * hasn't been set before is set to undefined, i.e., PP_Var
of
+ * type PP_VARTYPE_UNDEFINED
.
+ * @param[in] value The value to set. The array holds a reference to it on
+ * success.
+ *
+ * @return A PP_Bool
indicating whether the operation succeeds.
+ */
+ PP_Bool (*Set)(struct PP_Var array, uint32_t index, struct PP_Var value);
+ /**
+ * Gets the array length.
+ *
+ * @param[in] array An array var.
+ *
+ * @return The array length.
+ */
+ uint32_t (*GetLength)(struct PP_Var array);
+ /**
+ * Sets the array length.
+ *
+ * @param[in] array An array var.
+ * @param[in] length The new array length. If length
is smaller
+ * than its current value, the array is truncated to the new length; any
+ * elements that no longer fit are removed. If length
is larger
+ * than its current value, undefined vars are appended to increase the array
+ * to the specified length.
+ *
+ * @return A PP_Bool
indicating whether the operation succeeds.
+ */
+ PP_Bool (*SetLength)(struct PP_Var array, uint32_t length);
+};
+
+typedef struct PPB_VarArray_Dev_0_1 PPB_VarArray_Dev;
+/**
+ * @}
+ */
+
+#endif /* PPAPI_C_DEV_PPB_VAR_ARRAY_DEV_H_ */
+
diff --git a/ppapi/cpp/dev/var_array_dev.cc b/ppapi/cpp/dev/var_array_dev.cc
new file mode 100644
index 000000000000..91a1d5adf140
--- /dev/null
+++ b/ppapi/cpp/dev/var_array_dev.cc
@@ -0,0 +1,87 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ppapi/cpp/dev/var_array_dev.h"
+
+#include "ppapi/c/dev/ppb_var_array_dev.h"
+#include "ppapi/cpp/logging.h"
+#include "ppapi/cpp/module_impl.h"
+
+namespace pp {
+
+namespace {
+
+template <> const char* interface_name() {
+ return PPB_VAR_ARRAY_DEV_INTERFACE_0_1;
+}
+
+} // namespace
+
+VarArray_Dev::VarArray_Dev() : Var(Null()) {
+ if (has_interface())
+ var_ = get_interface()->Create();
+ else
+ PP_NOTREACHED();
+}
+
+VarArray_Dev::VarArray_Dev(const Var& var) : Var(var) {
+ if (!var.is_array()) {
+ PP_NOTREACHED();
+
+ // This takes care of releasing the reference that this object holds.
+ Var::operator=(Var(Null()));
+ }
+}
+
+VarArray_Dev::VarArray_Dev(const VarArray_Dev& other) : Var(other) {
+}
+
+VarArray_Dev::~VarArray_Dev() {
+}
+
+VarArray_Dev& VarArray_Dev::operator=(const VarArray_Dev& other) {
+ Var::operator=(other);
+ return *this;
+}
+
+Var& VarArray_Dev::operator=(const Var& other) {
+ if (other.is_array()) {
+ Var::operator=(other);
+ } else {
+ PP_NOTREACHED();
+ Var::operator=(Var(Null()));
+ }
+ return *this;
+}
+
+Var VarArray_Dev::Get(uint32_t index) const {
+ if (!has_interface())
+ return Var();
+
+ return Var(PASS_REF, get_interface()->Get(var_, index));
+}
+
+PP_Bool VarArray_Dev::Set(uint32_t index, const Var& value) {
+ if (!has_interface())
+ return PP_FALSE;
+
+ return get_interface()->Set(var_, index,
+ value.pp_var());
+}
+
+uint32_t VarArray_Dev::GetLength() const {
+ if (!has_interface())
+ return 0;
+
+ return get_interface()->GetLength(var_);
+}
+
+PP_Bool VarArray_Dev::SetLength(uint32_t length) {
+ if (!has_interface())
+ return PP_FALSE;
+
+ return get_interface()->SetLength(var_, length);
+}
+
+} // namespace pp
diff --git a/ppapi/cpp/dev/var_array_dev.h b/ppapi/cpp/dev/var_array_dev.h
new file mode 100644
index 000000000000..e11bd0a6699a
--- /dev/null
+++ b/ppapi/cpp/dev/var_array_dev.h
@@ -0,0 +1,84 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_CPP_DEV_VAR_ARRAY_DEV_H_
+#define PPAPI_CPP_DEV_VAR_ARRAY_DEV_H_
+
+#include "ppapi/c/pp_bool.h"
+#include "ppapi/c/pp_stdint.h"
+#include "ppapi/cpp/var.h"
+
+/// @file
+/// This file defines the API for interacting with array vars.
+
+namespace pp {
+
+class VarArray_Dev : public Var {
+ public:
+ /// Constructs a new array var.
+ VarArray_Dev();
+
+ /// Contructs a VarArray_Dev
given a var for which is_array() is
+ /// true. This will refer to the same array var, but allow you to access
+ /// methods specific to arrays.
+ ///
+ /// @param[in] var An array var.
+ explicit VarArray_Dev(const Var& var);
+
+ /// Copy constructor.
+ VarArray_Dev(const VarArray_Dev& other);
+
+ virtual ~VarArray_Dev();
+
+ /// Assignment operator.
+ VarArray_Dev& operator=(const VarArray_Dev& other);
+
+ /// The Var
assignment operator is overridden here so that we can
+ /// check for assigning a non-array var to a VarArray_Dev
.
+ ///
+ /// @param[in] other The array var to be assigned.
+ ///
+ /// @return The resulting VarArray_Dev
(as a Var
&).
+ virtual Var& operator=(const Var& other);
+
+ /// Gets an element from the array.
+ ///
+ /// @param[in] index An index indicating which element to return.
+ ///
+ /// @return The element at the specified position. If index
is
+ /// larger than or equal to the array length, an undefined var is returned.
+ Var Get(uint32_t index) const;
+
+ /// Sets the value of an element in the array.
+ ///
+ /// @param[in] index An index indicating which element to modify. If
+ /// index
is larger than or equal to the array length, the length
+ /// is updated to be index
+ 1. Any position in the array that
+ /// hasn't been set before is set to undefined, i.e., PP_Var
of
+ /// type PP_VARTYPE_UNDEFINED
.
+ /// @param[in] value The value to set.
+ ///
+ /// @return A PP_Bool
indicating whether the operation succeeds.
+ PP_Bool Set(uint32_t index, const Var& value);
+
+ /// Gets the array length.
+ ///
+ /// @return The array length.
+ uint32_t GetLength() const;
+
+ /// Sets the array length.
+ ///
+ /// @param[in] length The new array length. If length
is smaller
+ /// than its current value, the array is truncated to the new length; any
+ /// elements that no longer fit are removed. If length
is larger
+ /// than its current value, undefined vars are appended to increase the array
+ /// to the specified length.
+ ///
+ /// @return A PP_Bool
indicating whether the operation succeeds.
+ PP_Bool SetLength(uint32_t length);
+};
+
+} // namespace pp
+
+#endif // PPAPI_CPP_DEV_VAR_ARRAY_DEV_H_
diff --git a/ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_shim.c b/ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_shim.c
index 17772070a185..ec71ae44bf96 100644
--- a/ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_shim.c
+++ b/ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_shim.c
@@ -28,6 +28,7 @@
#include "ppapi/c/dev/ppb_trace_event_dev.h"
#include "ppapi/c/dev/ppb_truetype_font_dev.h"
#include "ppapi/c/dev/ppb_url_util_dev.h"
+#include "ppapi/c/dev/ppb_var_array_dev.h"
#include "ppapi/c/dev/ppb_var_dictionary_dev.h"
#include "ppapi/c/dev/ppb_video_capture_dev.h"
#include "ppapi/c/dev/ppb_video_decoder_dev.h"
@@ -210,6 +211,7 @@ static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_TextInput_Dev_0_2;
static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_Trace_Event_Dev_0_1;
static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_TrueTypeFont_Dev_0_1;
static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_URLUtil_Dev_0_6;
+static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_VarArray_Dev_0_1;
static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_VarDictionary_Dev_0_1;
static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_VideoCapture_Dev_0_2;
static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_VideoCapture_Dev_0_3;
@@ -2087,6 +2089,40 @@ struct PP_Var Pnacl_M17_PPB_URLUtil_Dev_GetPluginInstanceURL(PP_Instance instanc
/* End wrapper methods for PPB_URLUtil_Dev_0_6 */
+/* Begin wrapper methods for PPB_VarArray_Dev_0_1 */
+
+static __attribute__((pnaclcall))
+struct PP_Var Pnacl_M27_PPB_VarArray_Dev_Create(void) {
+ const struct PPB_VarArray_Dev_0_1 *iface = Pnacl_WrapperInfo_PPB_VarArray_Dev_0_1.real_iface;
+ return iface->Create();
+}
+
+static __attribute__((pnaclcall))
+struct PP_Var Pnacl_M27_PPB_VarArray_Dev_Get(struct PP_Var array, uint32_t index) {
+ const struct PPB_VarArray_Dev_0_1 *iface = Pnacl_WrapperInfo_PPB_VarArray_Dev_0_1.real_iface;
+ return iface->Get(array, index);
+}
+
+static __attribute__((pnaclcall))
+PP_Bool Pnacl_M27_PPB_VarArray_Dev_Set(struct PP_Var array, uint32_t index, struct PP_Var value) {
+ const struct PPB_VarArray_Dev_0_1 *iface = Pnacl_WrapperInfo_PPB_VarArray_Dev_0_1.real_iface;
+ return iface->Set(array, index, value);
+}
+
+static __attribute__((pnaclcall))
+uint32_t Pnacl_M27_PPB_VarArray_Dev_GetLength(struct PP_Var array) {
+ const struct PPB_VarArray_Dev_0_1 *iface = Pnacl_WrapperInfo_PPB_VarArray_Dev_0_1.real_iface;
+ return iface->GetLength(array);
+}
+
+static __attribute__((pnaclcall))
+PP_Bool Pnacl_M27_PPB_VarArray_Dev_SetLength(struct PP_Var array, uint32_t length) {
+ const struct PPB_VarArray_Dev_0_1 *iface = Pnacl_WrapperInfo_PPB_VarArray_Dev_0_1.real_iface;
+ return iface->SetLength(array, length);
+}
+
+/* End wrapper methods for PPB_VarArray_Dev_0_1 */
+
/* Begin wrapper methods for PPB_VarDictionary_Dev_0_1 */
static __attribute__((pnaclcall))
@@ -4222,6 +4258,14 @@ struct PPB_URLUtil_Dev_0_6 Pnacl_Wrappers_PPB_URLUtil_Dev_0_6 = {
.GetPluginInstanceURL = (struct PP_Var (*)(PP_Instance instance, struct PP_URLComponents_Dev* components))&Pnacl_M17_PPB_URLUtil_Dev_GetPluginInstanceURL
};
+struct PPB_VarArray_Dev_0_1 Pnacl_Wrappers_PPB_VarArray_Dev_0_1 = {
+ .Create = (struct PP_Var (*)(void))&Pnacl_M27_PPB_VarArray_Dev_Create,
+ .Get = (struct PP_Var (*)(struct PP_Var array, uint32_t index))&Pnacl_M27_PPB_VarArray_Dev_Get,
+ .Set = (PP_Bool (*)(struct PP_Var array, uint32_t index, struct PP_Var value))&Pnacl_M27_PPB_VarArray_Dev_Set,
+ .GetLength = (uint32_t (*)(struct PP_Var array))&Pnacl_M27_PPB_VarArray_Dev_GetLength,
+ .SetLength = (PP_Bool (*)(struct PP_Var array, uint32_t length))&Pnacl_M27_PPB_VarArray_Dev_SetLength
+};
+
struct PPB_VarDictionary_Dev_0_1 Pnacl_Wrappers_PPB_VarDictionary_Dev_0_1 = {
.Create = (struct PP_Var (*)(void))&Pnacl_M27_PPB_VarDictionary_Dev_Create,
.Get = (struct PP_Var (*)(struct PP_Var dict, struct PP_Var key))&Pnacl_M27_PPB_VarDictionary_Dev_Get,
@@ -5105,6 +5149,12 @@ static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_URLUtil_Dev_0_6 = {
.real_iface = NULL
};
+static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_VarArray_Dev_0_1 = {
+ .iface_macro = PPB_VAR_ARRAY_DEV_INTERFACE_0_1,
+ .wrapped_iface = (void *) &Pnacl_Wrappers_PPB_VarArray_Dev_0_1,
+ .real_iface = NULL
+};
+
static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_VarDictionary_Dev_0_1 = {
.iface_macro = PPB_VAR_DICTIONARY_DEV_INTERFACE_0_1,
.wrapped_iface = (void *) &Pnacl_Wrappers_PPB_VarDictionary_Dev_0_1,
@@ -5546,6 +5596,7 @@ static struct __PnaclWrapperInfo *s_ppb_wrappers[] = {
&Pnacl_WrapperInfo_PPB_Trace_Event_Dev_0_1,
&Pnacl_WrapperInfo_PPB_TrueTypeFont_Dev_0_1,
&Pnacl_WrapperInfo_PPB_URLUtil_Dev_0_6,
+ &Pnacl_WrapperInfo_PPB_VarArray_Dev_0_1,
&Pnacl_WrapperInfo_PPB_VarDictionary_Dev_0_1,
&Pnacl_WrapperInfo_PPB_VideoCapture_Dev_0_2,
&Pnacl_WrapperInfo_PPB_VideoCapture_Dev_0_3,
diff --git a/ppapi/ppapi_shared.gypi b/ppapi/ppapi_shared.gypi
index 699ef084007f..f55adeae8a88 100644
--- a/ppapi/ppapi_shared.gypi
+++ b/ppapi/ppapi_shared.gypi
@@ -20,6 +20,8 @@
# This part is shared between the targets defined below.
['ppapi_shared_target==1', {
'sources': [
+ 'shared_impl/array_var.cc',
+ 'shared_impl/array_var.h',
'shared_impl/array_writer.cc',
'shared_impl/array_writer.h',
'shared_impl/callback_tracker.cc',
@@ -233,6 +235,7 @@
'thunk/ppb_url_response_info_api.h',
'thunk/ppb_url_response_info_thunk.cc',
'thunk/ppb_url_util_thunk.cc',
+ 'thunk/ppb_var_array_thunk.cc',
'thunk/ppb_var_dictionary_thunk.cc',
'thunk/ppb_video_capture_api.h',
'thunk/ppb_video_capture_thunk.cc',
diff --git a/ppapi/ppapi_sources.gypi b/ppapi/ppapi_sources.gypi
index 73e7a3f3dd58..b70f6d70281f 100644
--- a/ppapi/ppapi_sources.gypi
+++ b/ppapi/ppapi_sources.gypi
@@ -77,6 +77,7 @@
'c/dev/ppb_text_input_dev.h',
'c/dev/ppb_truetype_font_dev.h',
'c/dev/ppb_url_util_dev.h',
+ 'c/dev/ppb_var_array_dev.h',
'c/dev/ppb_var_dictionary_dev.h',
'c/dev/ppb_video_decoder_dev.h',
'c/dev/ppb_widget_dev.h',
@@ -244,6 +245,8 @@
'cpp/dev/truetype_font_dev.h',
'cpp/dev/url_util_dev.cc',
'cpp/dev/url_util_dev.h',
+ 'cpp/dev/var_array_dev.cc',
+ 'cpp/dev/var_array_dev.h',
'cpp/dev/var_dictionary_dev.cc',
'cpp/dev/var_dictionary_dev.h',
'cpp/dev/video_capture_client_dev.cc',
diff --git a/ppapi/proxy/interface_list.cc b/ppapi/proxy/interface_list.cc
index 63af5df65e18..ac8a6d41c169 100644
--- a/ppapi/proxy/interface_list.cc
+++ b/ppapi/proxy/interface_list.cc
@@ -27,6 +27,7 @@
#include "ppapi/c/dev/ppb_trace_event_dev.h"
#include "ppapi/c/dev/ppb_truetype_font_dev.h"
#include "ppapi/c/dev/ppb_url_util_dev.h"
+#include "ppapi/c/dev/ppb_var_array_dev.h"
#include "ppapi/c/dev/ppb_var_deprecated.h"
#include "ppapi/c/dev/ppb_var_dictionary_dev.h"
#include "ppapi/c/dev/ppb_video_capture_dev.h"
diff --git a/ppapi/shared_impl/array_var.cc b/ppapi/shared_impl/array_var.cc
new file mode 100644
index 000000000000..def1bb57e0e7
--- /dev/null
+++ b/ppapi/shared_impl/array_var.cc
@@ -0,0 +1,83 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ppapi/shared_impl/array_var.h"
+
+#include
+
+#include "base/logging.h"
+#include "base/memory/ref_counted.h"
+#include "ppapi/shared_impl/ppapi_globals.h"
+#include "ppapi/shared_impl/var_tracker.h"
+
+namespace ppapi {
+
+ArrayVar::ArrayVar() {
+}
+
+ArrayVar::~ArrayVar() {
+}
+
+// static
+ArrayVar* ArrayVar::FromPPVar(const PP_Var& var) {
+ if (var.type != PP_VARTYPE_ARRAY)
+ return NULL;
+
+ scoped_refptr var_object(
+ PpapiGlobals::Get()->GetVarTracker()->GetVar(var));
+ if (!var_object.get())
+ return NULL;
+ return var_object->AsArrayVar();
+}
+
+ArrayVar* ArrayVar::AsArrayVar() {
+ return this;
+}
+
+PP_VarType ArrayVar::GetType() const {
+ return PP_VARTYPE_ARRAY;
+}
+
+PP_Var ArrayVar::Get(uint32_t index) const {
+ if (index >= elements_.size())
+ return PP_MakeUndefined();
+
+ const PP_Var& element = elements_[index].get();
+ if (PpapiGlobals::Get()->GetVarTracker()->AddRefVar(element))
+ return element;
+ else
+ return PP_MakeUndefined();
+}
+
+PP_Bool ArrayVar::Set(uint32_t index, const PP_Var& value) {
+ if (index == std::numeric_limits::max())
+ return PP_FALSE;
+
+ if (index >= elements_.size()) {
+ // Insert ScopedPPVars of type PP_VARTYPE_UNDEFINED to reach the new size
+ // (index + 1).
+ elements_.resize(index + 1);
+ }
+
+ elements_[index] = value;
+ return PP_TRUE;
+}
+
+uint32_t ArrayVar::GetLength() const {
+ if (elements_.size() > std::numeric_limits::max()) {
+ CHECK(false);
+ return 0;
+ }
+
+ return static_cast(elements_.size());
+}
+
+PP_Bool ArrayVar::SetLength(uint32_t length) {
+ // If |length| is larger than the current size, ScopedPPVars of type
+ // PP_VARTYPE_UNDEFINED will be inserted to reach the new length.
+ elements_.resize(length);
+ return PP_TRUE;
+}
+
+} // namespace ppapi
diff --git a/ppapi/shared_impl/array_var.h b/ppapi/shared_impl/array_var.h
new file mode 100644
index 000000000000..1214d87500c3
--- /dev/null
+++ b/ppapi/shared_impl/array_var.h
@@ -0,0 +1,59 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_SHARED_IMPL_ARRAY_VAR_H_
+#define PPAPI_SHARED_IMPL_ARRAY_VAR_H_
+
+#include
+
+#include "base/basictypes.h"
+#include "base/compiler_specific.h"
+#include "ppapi/c/pp_var.h"
+#include "ppapi/shared_impl/ppapi_shared_export.h"
+#include "ppapi/shared_impl/scoped_pp_var.h"
+#include "ppapi/shared_impl/var.h"
+
+namespace ppapi {
+
+class PPAPI_SHARED_EXPORT ArrayVar : public Var {
+ public:
+ typedef std::vector ElementVector;
+
+ ArrayVar();
+
+ // Helper function that converts a PP_Var to an ArrayVar. This will return
+ // NULL if the PP_Var is not of type PP_VARTYPE_ARRAY or the array cannot be
+ // found from the var tracker.
+ static ArrayVar* FromPPVar(const PP_Var& var);
+
+ // Var overrides.
+ virtual ArrayVar* AsArrayVar() OVERRIDE;
+ virtual PP_VarType GetType() const OVERRIDE;
+
+ // The returned PP_Var has had a ref added on behalf of the caller.
+ PP_Var Get(uint32_t index) const;
+ PP_Bool Set(uint32_t index, const PP_Var& value);
+ uint32_t GetLength() const;
+ PP_Bool SetLength(uint32_t length);
+
+ const ElementVector& elements() const {
+ return elements_;
+ }
+
+ ElementVector& elements() {
+ return elements_;
+ }
+
+ protected:
+ virtual ~ArrayVar();
+
+ private:
+ ElementVector elements_;
+
+ DISALLOW_COPY_AND_ASSIGN(ArrayVar);
+};
+
+} // namespace ppapi
+
+#endif // PPAPI_SHARED_IMPL_ARRAY_VAR_H_
diff --git a/ppapi/shared_impl/dictionary_var.cc b/ppapi/shared_impl/dictionary_var.cc
index 9bfebb94fcce..f7af7d9355d8 100644
--- a/ppapi/shared_impl/dictionary_var.cc
+++ b/ppapi/shared_impl/dictionary_var.cc
@@ -6,6 +6,7 @@
#include "base/memory/ref_counted.h"
#include "base/string_util.h"
+#include "ppapi/shared_impl/array_var.h"
#include "ppapi/shared_impl/ppapi_globals.h"
#include "ppapi/shared_impl/var_tracker.h"
@@ -81,8 +82,16 @@ PP_Bool DictionaryVar::HasKey(const PP_Var& key) const {
}
PP_Var DictionaryVar::GetKeys() const {
- // TODO(yzshen): Implement once array PP_Var is supported.
- return PP_MakeNull();
+ scoped_refptr array_var(new ArrayVar());
+ array_var->elements().reserve(key_value_map_.size());
+
+ for (KeyValueMap::const_iterator iter = key_value_map_.begin();
+ iter != key_value_map_.end(); ++iter) {
+ array_var->elements().push_back(
+ ScopedPPVar(ScopedPPVar::PassRef(),
+ StringVar::StringToPPVar(iter->first)));
+ }
+ return array_var->GetPPVar();
}
bool DictionaryVar::SetWithStringKey(const std::string& utf8_key,
diff --git a/ppapi/shared_impl/var.cc b/ppapi/shared_impl/var.cc
index 8870e3e7a7fe..0aff5837fe9a 100644
--- a/ppapi/shared_impl/var.cc
+++ b/ppapi/shared_impl/var.cc
@@ -83,6 +83,10 @@ ProxyObjectVar* Var::AsProxyObjectVar() {
return NULL;
}
+ArrayVar* Var::AsArrayVar() {
+ return NULL;
+}
+
DictionaryVar* Var::AsDictionaryVar() {
return NULL;
}
diff --git a/ppapi/shared_impl/var.h b/ppapi/shared_impl/var.h
index 76654b425b3c..d5e33d5872f2 100644
--- a/ppapi/shared_impl/var.h
+++ b/ppapi/shared_impl/var.h
@@ -15,6 +15,7 @@
namespace ppapi {
class ArrayBufferVar;
+class ArrayVar;
class DictionaryVar;
class NPObjectVar;
class ProxyObjectVar;
@@ -35,6 +36,7 @@ class PPAPI_SHARED_EXPORT Var : public base::RefCounted {
virtual ArrayBufferVar* AsArrayBufferVar();
virtual NPObjectVar* AsNPObjectVar();
virtual ProxyObjectVar* AsProxyObjectVar();
+ virtual ArrayVar* AsArrayVar();
virtual DictionaryVar* AsDictionaryVar();
// Creates a PP_Var corresponding to this object. The return value will have
diff --git a/ppapi/shared_impl/var_value_conversions.cc b/ppapi/shared_impl/var_value_conversions.cc
index a54c7263f005..614002a5eae4 100644
--- a/ppapi/shared_impl/var_value_conversions.cc
+++ b/ppapi/shared_impl/var_value_conversions.cc
@@ -15,6 +15,7 @@
#include "base/values.h"
#include "ppapi/c/pp_bool.h"
#include "ppapi/c/pp_stdint.h"
+#include "ppapi/shared_impl/array_var.h"
#include "ppapi/shared_impl/dictionary_var.h"
#include "ppapi/shared_impl/ppapi_globals.h"
#include "ppapi/shared_impl/scoped_pp_var.h"
@@ -98,8 +99,14 @@ bool CreateValueFromVarHelper(const std::set& parent_ids,
return false;
}
case PP_VARTYPE_ARRAY: {
- // TODO(yzshen): Implement it once array var is supported.
- return false;
+ if (ContainsKey(parent_ids, var.value.as_id)) {
+ // A circular reference is found.
+ return false;
+ }
+
+ value->reset(new base::ListValue());
+ state->push(VarNode(var, value->get()));
+ return true;
}
case PP_VARTYPE_DICTIONARY: {
if (ContainsKey(parent_ids, var.value.as_id)) {
@@ -200,8 +207,10 @@ bool CreateVarFromValueHelper(const base::Value& value,
return true;
}
case base::Value::TYPE_LIST: {
- // TODO(yzshen): Add support once array var is supported.
- return false;
+ scoped_refptr array_var(new ArrayVar());
+ *var = ScopedPPVar(ScopedPPVar::PassRef(), array_var->GetPPVar());
+ state->push(ValueNode(var->get(), &value));
+ return true;
}
}
NOTREACHED();
@@ -252,6 +261,29 @@ base::Value* CreateValueFromVar(const PP_Var& var) {
dict_value->SetWithoutPathExpansion(iter->first, child_value.release());
}
+ } else if (top.var.type == PP_VARTYPE_ARRAY) {
+ parent_ids.insert(top.var.value.as_id);
+ top.sentinel = true;
+
+ ArrayVar* array_var = ArrayVar::FromPPVar(top.var);
+ if (!array_var)
+ return NULL;
+
+ DCHECK(top.value->GetType() == base::Value::TYPE_LIST);
+ base::ListValue* list_value = static_cast(top.value);
+
+ for (ArrayVar::ElementVector::const_iterator iter =
+ array_var->elements().begin();
+ iter != array_var->elements().end();
+ ++iter) {
+ scoped_ptr child_value;
+ if (!CreateValueFromVarHelper(parent_ids, iter->get(), &child_value,
+ &state)) {
+ return NULL;
+ }
+
+ list_value->Append(child_value.release());
+ }
} else {
NOTREACHED();
return NULL;
@@ -286,6 +318,20 @@ PP_Var CreateVarFromValue(const base::Value& value) {
return PP_MakeUndefined();
}
}
+ } else if (top.value->GetType() == base::Value::TYPE_LIST) {
+ const base::ListValue* list_value =
+ static_cast(top.value);
+ ArrayVar* array_var = ArrayVar::FromPPVar(top.var);
+ DCHECK(array_var);
+ for (base::ListValue::const_iterator iter = list_value->begin();
+ iter != list_value->end();
+ ++iter) {
+ ScopedPPVar child_var;
+ if (!CreateVarFromValueHelper(**iter, &child_var, &state))
+ return PP_MakeUndefined();
+
+ array_var->elements().push_back(child_var);
+ }
} else {
NOTREACHED();
return PP_MakeUndefined();
diff --git a/ppapi/shared_impl/var_value_conversions_unittest.cc b/ppapi/shared_impl/var_value_conversions_unittest.cc
index d9a276992afa..8dd2c427812a 100644
--- a/ppapi/shared_impl/var_value_conversions_unittest.cc
+++ b/ppapi/shared_impl/var_value_conversions_unittest.cc
@@ -13,6 +13,7 @@
#include "base/values.h"
#include "ppapi/c/pp_bool.h"
#include "ppapi/c/pp_var.h"
+#include "ppapi/shared_impl/array_var.h"
#include "ppapi/shared_impl/dictionary_var.h"
#include "ppapi/shared_impl/ppapi_globals.h"
#include "ppapi/shared_impl/proxy_lock.h"
@@ -94,8 +95,22 @@ bool Equals(const base::Value& value, const PP_Var& var) {
return non_undefined_count == dict_value.size();
}
case base::Value::TYPE_LIST: {
- // TODO(yzshen): add support once array var is supported.
- return false;
+ const base::ListValue& list_value =
+ static_cast(value);
+ ArrayVar* array_var = ArrayVar::FromPPVar(var);
+ if (!array_var || list_value.GetSize() != array_var->elements().size())
+ return false;
+
+ base::ListValue::const_iterator value_iter = list_value.begin();
+ ArrayVar::ElementVector::const_iterator var_iter =
+ array_var->elements().begin();
+ for (; value_iter != list_value.end() &&
+ var_iter != array_var->elements().end();
+ ++value_iter, ++var_iter) {
+ if (!Equals(**value_iter, var_iter->get()))
+ return false;
+ }
+ return true;
}
}
NOTREACHED();
@@ -127,22 +142,22 @@ class VarValueConversionsTest : public testing::Test {
TEST_F(VarValueConversionsTest, CreateValueFromVar) {
{
// Var holding a ref to itself is not a valid input.
- scoped_refptr dict_var_1(new DictionaryVar());
- ScopedPPVar var_1(ScopedPPVar::PassRef(), dict_var_1->GetPPVar());
- scoped_refptr dict_var_2(new DictionaryVar());
- ScopedPPVar var_2(ScopedPPVar::PassRef(), dict_var_2->GetPPVar());
+ scoped_refptr dict_var(new DictionaryVar());
+ ScopedPPVar var_1(ScopedPPVar::PassRef(), dict_var->GetPPVar());
+ scoped_refptr array_var(new ArrayVar());
+ ScopedPPVar var_2(ScopedPPVar::PassRef(), array_var->GetPPVar());
- ASSERT_TRUE(dict_var_1->SetWithStringKey("key_1", var_2.get()));
+ ASSERT_TRUE(dict_var->SetWithStringKey("key_1", var_2.get()));
scoped_ptr value(CreateValueFromVar(var_1.get()));
ASSERT_TRUE(value.get());
- ASSERT_TRUE(dict_var_2->SetWithStringKey("key_2", var_1.get()));
+ ASSERT_TRUE(array_var->Set(0, var_1.get()));
value.reset(CreateValueFromVar(var_1.get()));
ASSERT_EQ(NULL, value.get());
// Make sure |var_1| doesn't indirectly hold a ref to itself, otherwise it
// is leaked.
- dict_var_1->DeleteWithStringKey("key_1");
+ dict_var->DeleteWithStringKey("key_1");
}
// Vars of null or undefined type are converted to null values.
@@ -156,6 +171,16 @@ TEST_F(VarValueConversionsTest, CreateValueFromVar) {
ASSERT_TRUE(Equals(*value, PP_MakeUndefined()));
}
+ {
+ // Test empty dictionary.
+ scoped_refptr dict_var(new DictionaryVar());
+ ScopedPPVar var(ScopedPPVar::PassRef(), dict_var->GetPPVar());
+
+ scoped_ptr value(CreateValueFromVar(var.get()));
+ ASSERT_TRUE(value.get());
+ ASSERT_TRUE(Equals(*value, var.get()));
+ }
+
{
// Key-value pairs whose value is undefined are ignored.
scoped_refptr dict_var(new DictionaryVar());
@@ -187,12 +212,29 @@ TEST_F(VarValueConversionsTest, CreateValueFromVar) {
ASSERT_TRUE(Equals(*value, dict_pp_var_1.get()));
}
+ {
+ // Test basic cases for array.
+ scoped_refptr array_var(new ArrayVar());
+ ScopedPPVar var(ScopedPPVar::PassRef(), array_var->GetPPVar());
+
+ scoped_ptr value(CreateValueFromVar(var.get()));
+ ASSERT_TRUE(value.get());
+ ASSERT_TRUE(Equals(*value, var.get()));
+
+ ASSERT_TRUE(array_var->Set(0, PP_MakeDouble(1)));
+ value.reset(CreateValueFromVar(var.get()));
+ ASSERT_TRUE(value.get());
+ ASSERT_TRUE(Equals(*value, var.get()));
+ }
+
{
// Test more complex inputs.
scoped_refptr dict_var_1(new DictionaryVar());
ScopedPPVar dict_pp_var_1(ScopedPPVar::PassRef(), dict_var_1->GetPPVar());
scoped_refptr dict_var_2(new DictionaryVar());
ScopedPPVar dict_pp_var_2(ScopedPPVar::PassRef(), dict_var_2->GetPPVar());
+ scoped_refptr array_var(new ArrayVar());
+ ScopedPPVar array_pp_var(ScopedPPVar::PassRef(), array_var->GetPPVar());
scoped_refptr string_var(new StringVar("string_value"));
ScopedPPVar string_pp_var(ScopedPPVar::PassRef(), string_var->GetPPVar());
@@ -204,8 +246,11 @@ TEST_F(VarValueConversionsTest, CreateValueFromVar) {
ASSERT_TRUE(dict_var_2->SetWithStringKey("undefined_key",
PP_MakeUndefined()));
ASSERT_TRUE(dict_var_2->SetWithStringKey("double_key", PP_MakeDouble(1)));
- ASSERT_TRUE(dict_var_2->SetWithStringKey("int_key", PP_MakeInt32(2)));
- ASSERT_TRUE(dict_var_2->SetWithStringKey("bool_key", PP_MakeBool(PP_TRUE)));
+ ASSERT_TRUE(dict_var_2->SetWithStringKey("array_key", array_pp_var.get()));
+
+ ASSERT_TRUE(array_var->Set(0, PP_MakeInt32(2)));
+ ASSERT_TRUE(array_var->Set(1, PP_MakeBool(PP_TRUE)));
+ ASSERT_TRUE(array_var->SetLength(4));
scoped_ptr value(CreateValueFromVar(dict_pp_var_1.get()));
ASSERT_TRUE(value.get());
@@ -227,15 +272,45 @@ TEST_F(VarValueConversionsTest, CreateValueFromVar) {
}
TEST_F(VarValueConversionsTest, CreateVarFromValue) {
- base::DictionaryValue dict_value;
- dict_value.Set("null_key", base::Value::CreateNullValue());
- dict_value.SetString("string_key", "string_value");
- dict_value.SetDouble("dict_key.double_key", 1);
- dict_value.SetInteger("dict_key.int_key", 2);
- dict_value.SetBoolean("dict_key.bool_key", true);
-
- ScopedPPVar var(ScopedPPVar::PassRef(), CreateVarFromValue(dict_value));
- ASSERT_TRUE(Equals(dict_value, var.get()));
+ {
+ // Test basic cases for dictionary.
+ base::DictionaryValue dict_value;
+ ScopedPPVar var(ScopedPPVar::PassRef(), CreateVarFromValue(dict_value));
+ ASSERT_TRUE(Equals(dict_value, var.get()));
+
+ dict_value.SetInteger("int_key", 1);
+ var = ScopedPPVar(ScopedPPVar::PassRef(), CreateVarFromValue(dict_value));
+ ASSERT_TRUE(Equals(dict_value, var.get()));
+ }
+
+ {
+ // Test basic cases for array.
+ base::ListValue list_value;
+ ScopedPPVar var(ScopedPPVar::PassRef(), CreateVarFromValue(list_value));
+ ASSERT_TRUE(Equals(list_value, var.get()));
+
+ list_value.AppendInteger(1);
+ var = ScopedPPVar(ScopedPPVar::PassRef(), CreateVarFromValue(list_value));
+ ASSERT_TRUE(Equals(list_value, var.get()));
+ }
+
+ {
+ // Test more complex inputs.
+ base::DictionaryValue dict_value;
+ dict_value.Set("null_key", base::Value::CreateNullValue());
+ dict_value.SetString("string_key", "string_value");
+ dict_value.SetDouble("dict_key.double_key", 1);
+
+ scoped_ptr list_value(new base::ListValue());
+ list_value->AppendInteger(2);
+ list_value->AppendBoolean(true);
+ list_value->Append(base::Value::CreateNullValue());
+
+ dict_value.Set("dict_key.array_key", list_value.release());
+
+ ScopedPPVar var(ScopedPPVar::PassRef(), CreateVarFromValue(dict_value));
+ ASSERT_TRUE(Equals(dict_value, var.get()));
+ }
}
} // namespace ppapi
diff --git a/ppapi/tests/all_c_includes.h b/ppapi/tests/all_c_includes.h
index 1f004d9ef0f2..7dc99ae7eedd 100644
--- a/ppapi/tests/all_c_includes.h
+++ b/ppapi/tests/all_c_includes.h
@@ -31,6 +31,7 @@
#include "ppapi/c/dev/ppb_trace_event_dev.h"
#include "ppapi/c/dev/ppb_truetype_font_dev.h"
#include "ppapi/c/dev/ppb_url_util_dev.h"
+#include "ppapi/c/dev/ppb_var_array_dev.h"
#include "ppapi/c/dev/ppb_var_deprecated.h"
#include "ppapi/c/dev/ppb_var_dictionary_dev.h"
#include "ppapi/c/dev/ppb_video_decoder_dev.h"
diff --git a/ppapi/tests/all_cpp_includes.h b/ppapi/tests/all_cpp_includes.h
index 6f643ad79ab6..deabeaaea107 100644
--- a/ppapi/tests/all_cpp_includes.h
+++ b/ppapi/tests/all_cpp_includes.h
@@ -29,6 +29,7 @@
#include "ppapi/cpp/dev/selection_dev.h"
#include "ppapi/cpp/dev/text_input_dev.h"
#include "ppapi/cpp/dev/url_util_dev.h"
+#include "ppapi/cpp/dev/var_array_dev.h"
#include "ppapi/cpp/dev/var_dictionary_dev.h"
#include "ppapi/cpp/dev/video_decoder_dev.h"
#include "ppapi/cpp/dev/view_dev.h"
diff --git a/ppapi/thunk/interfaces_ppb_public_dev.h b/ppapi/thunk/interfaces_ppb_public_dev.h
index 27f3b9c3f090..90d00c569989 100644
--- a/ppapi/thunk/interfaces_ppb_public_dev.h
+++ b/ppapi/thunk/interfaces_ppb_public_dev.h
@@ -30,6 +30,7 @@ PROXIED_IFACE(PPB_Instance, PPB_TEXTINPUT_DEV_INTERFACE_0_2,
PPB_TextInput_Dev_0_2)
PROXIED_IFACE(NoAPIName, PPB_TRUETYPEFONT_DEV_INTERFACE_0_1,
PPB_TrueTypeFont_Dev_0_1)
+PROXIED_IFACE(NoAPIName, PPB_VAR_ARRAY_DEV_INTERFACE_0_1, PPB_VarArray_Dev_0_1)
PROXIED_IFACE(NoAPIName, PPB_VAR_DICTIONARY_DEV_INTERFACE_0_1,
PPB_VarDictionary_Dev_0_1)
PROXIED_IFACE(NoAPIName, PPB_VIEW_DEV_INTERFACE_0_1,
diff --git a/ppapi/thunk/ppb_var_array_thunk.cc b/ppapi/thunk/ppb_var_array_thunk.cc
new file mode 100644
index 000000000000..7321424d2994
--- /dev/null
+++ b/ppapi/thunk/ppb_var_array_thunk.cc
@@ -0,0 +1,74 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ppapi/c/dev/ppb_var_array_dev.h"
+#include "ppapi/shared_impl/array_var.h"
+#include "ppapi/shared_impl/proxy_lock.h"
+#include "ppapi/thunk/thunk.h"
+
+namespace ppapi {
+namespace thunk {
+
+namespace {
+
+PP_Var Create() {
+ ProxyAutoLock lock;
+
+ // Var tracker will hold a reference to this object.
+ ArrayVar* var = new ArrayVar();
+ return var->GetPPVar();
+}
+
+PP_Var Get(PP_Var array, uint32_t index) {
+ ProxyAutoLock lock;
+
+ ArrayVar* array_var = ArrayVar::FromPPVar(array);
+ if (!array_var)
+ return PP_MakeUndefined();
+ return array_var->Get(index);
+}
+
+PP_Bool Set(PP_Var array, uint32_t index, PP_Var value) {
+ ProxyAutoLock lock;
+
+ ArrayVar* array_var = ArrayVar::FromPPVar(array);
+ if (!array_var)
+ return PP_FALSE;
+ return array_var->Set(index, value);
+}
+
+uint32_t GetLength(PP_Var array) {
+ ProxyAutoLock lock;
+
+ ArrayVar* array_var = ArrayVar::FromPPVar(array);
+ if (!array_var)
+ return 0;
+ return array_var->GetLength();
+}
+
+PP_Bool SetLength(PP_Var array, uint32_t length) {
+ ProxyAutoLock lock;
+
+ ArrayVar* array_var = ArrayVar::FromPPVar(array);
+ if (!array_var)
+ return PP_FALSE;
+ return array_var->SetLength(length);
+}
+
+const PPB_VarArray_Dev_0_1 g_ppb_vararray_0_1_thunk = {
+ &Create,
+ &Get,
+ &Set,
+ &GetLength,
+ &SetLength
+};
+
+} // namespace
+
+const PPB_VarArray_Dev_0_1* GetPPB_VarArray_Dev_0_1_Thunk() {
+ return &g_ppb_vararray_0_1_thunk;
+}
+
+} // namespace thunk
+} // namespace ppapi
diff --git a/webkit/plugins/ppapi/plugin_module.cc b/webkit/plugins/ppapi/plugin_module.cc
index 4a9735c38b1c..81eec42aa31d 100644
--- a/webkit/plugins/ppapi/plugin_module.cc
+++ b/webkit/plugins/ppapi/plugin_module.cc
@@ -35,6 +35,7 @@
#include "ppapi/c/dev/ppb_trace_event_dev.h"
#include "ppapi/c/dev/ppb_truetype_font_dev.h"
#include "ppapi/c/dev/ppb_url_util_dev.h"
+#include "ppapi/c/dev/ppb_var_array_dev.h"
#include "ppapi/c/dev/ppb_var_deprecated.h"
#include "ppapi/c/dev/ppb_var_dictionary_dev.h"
#include "ppapi/c/dev/ppb_video_capture_dev.h"