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"