| Index: ppapi/shared_impl/var_value_conversions.cc
|
| diff --git a/ppapi/shared_impl/var_value_conversions.cc b/ppapi/shared_impl/var_value_conversions.cc
|
| index 605a984b238d5661ebddb0407f99bcefaf610533..52595218b3d77a68e07610eed06c0b13a6fa23c8 100644
|
| --- a/ppapi/shared_impl/var_value_conversions.cc
|
| +++ b/ppapi/shared_impl/var_value_conversions.cc
|
| @@ -14,6 +14,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"
|
| @@ -39,6 +40,28 @@ class VarNodeBase : public base::RefCounted<VarNodeBase> {
|
| virtual ~VarNodeBase() {}
|
| };
|
|
|
| +class ArrayVarNode : public VarNodeBase {
|
| + public:
|
| + ArrayVarNode(int64_t in_var_id, const ArrayVar* array_var)
|
| + : var_id(in_var_id),
|
| + next(array_var->elements().begin()),
|
| + end(array_var->elements().end()),
|
| + list_value(new base::ListValue()) {
|
| + }
|
| +
|
| + virtual bool IsArrayVar() const OVERRIDE {
|
| + return true;
|
| + }
|
| +
|
| + int64_t var_id;
|
| + ArrayVar::ElementVector::const_iterator next;
|
| + ArrayVar::ElementVector::const_iterator end;
|
| + scoped_ptr<base::ListValue> list_value;
|
| +
|
| + private:
|
| + virtual ~ArrayVarNode() {}
|
| +};
|
| +
|
| class DictionaryVarNode : public VarNodeBase {
|
| public:
|
| DictionaryVarNode(int64_t in_var_id, const DictionaryVar* dict_var)
|
| @@ -77,6 +100,27 @@ class ValueNodeBase : public base::RefCounted<ValueNodeBase> {
|
| virtual ~ValueNodeBase() {}
|
| };
|
|
|
| +class ListValueNode : public ValueNodeBase {
|
| + public:
|
| + explicit ListValueNode(const base::ListValue& list_value)
|
| + : next(list_value.begin()),
|
| + end(list_value.end()),
|
| + array_var(new ArrayVar()) {
|
| + array_var->elements().reserve(list_value.GetSize());
|
| + }
|
| +
|
| + virtual bool IsListValue() const OVERRIDE {
|
| + return true;
|
| + }
|
| +
|
| + base::ListValue::const_iterator next;
|
| + base::ListValue::const_iterator end;
|
| + scoped_refptr<ArrayVar> array_var;
|
| +
|
| + private:
|
| + virtual ~ListValueNode() {}
|
| +};
|
| +
|
| class DictionaryValueNode : public ValueNodeBase {
|
| public:
|
| explicit DictionaryValueNode(const base::DictionaryValue& dict_value)
|
| @@ -135,8 +179,19 @@ bool CreateValueFromVarHelper(const PP_Var& var,
|
| return false;
|
| }
|
| case PP_VARTYPE_ARRAY: {
|
| - // TODO(yzshen): Implement it once array var is supported.
|
| - return false;
|
| + if (parent_ids->find(var.value.as_id) != parent_ids->end()) {
|
| + // A circular reference is found.
|
| + return false;
|
| + }
|
| +
|
| + ArrayVar* array_var = ArrayVar::FromPPVar(var);
|
| + if (!array_var)
|
| + return false;
|
| +
|
| +
|
| + parent_ids->insert(var.value.as_id);
|
| + state->push(new ArrayVarNode(var.value.as_id, array_var));
|
| + return true;
|
| }
|
| case PP_VARTYPE_DICTIONARY: {
|
| if (parent_ids->find(var.value.as_id) != parent_ids->end()) {
|
| @@ -241,8 +296,9 @@ bool CreateVarFromValueHelper(
|
| return true;
|
| }
|
| case base::Value::TYPE_LIST: {
|
| - // TODO(yzshen): Add support once array var is supported.
|
| - return false;
|
| + state->push(new ListValueNode(
|
| + static_cast<const base::ListValue&>(value)));
|
| + return true;
|
| }
|
| }
|
| NOTREACHED();
|
| @@ -287,6 +343,22 @@ base::Value* CreateValueFromVar(const PP_Var& var) {
|
| continue;
|
| }
|
| }
|
| + } else if (state.top()->IsArrayVar()) {
|
| + scoped_refptr<ArrayVarNode> top(
|
| + static_cast<ArrayVarNode*>(state.top().get()));
|
| +
|
| + if (current_value.get())
|
| + top->list_value->Append(current_value.release());
|
| +
|
| + if (top->next == top->end) {
|
| + current_value.reset(top->list_value.release());
|
| + parent_ids.erase(top->var_id);
|
| + state.pop();
|
| + continue;
|
| + } else {
|
| + current_var = top->next->get();
|
| + ++top->next;
|
| + }
|
| } else {
|
| NOTREACHED();
|
| return NULL;
|
| @@ -333,6 +405,22 @@ PP_Var CreateVarFromValue(const base::Value& value) {
|
| current_value = &top->iter.value();
|
| top->iter.Advance();
|
| }
|
| + } else if (state.top()->IsListValue()) {
|
| + scoped_refptr<ListValueNode> top(
|
| + static_cast<ListValueNode*>(state.top().get()));
|
| +
|
| + if (current_var.get().type != PP_VARTYPE_UNDEFINED)
|
| + top->array_var->elements().push_back(current_var);
|
| + current_var = PP_MakeUndefined();
|
| + if (top->next == top->end) {
|
| + current_var = ScopedPPVar(ScopedPPVar::PassRef(),
|
| + top->array_var->GetPPVar());
|
| + state.pop();
|
| + continue;
|
| + } else {
|
| + current_value = *top->next;
|
| + ++top->next;
|
| + }
|
| } else {
|
| NOTREACHED();
|
| return PP_MakeUndefined();
|
|
|