Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(421)

Side by Side Diff: ppapi/shared_impl/var_value_conversions.cc

Issue 12387073: Add PPB_VarDictionary_Dev support - part 1. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Use correct base branch. Created 7 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "ppapi/shared_impl/var_value_conversions.h"
6
7 #include <algorithm>
8 #include <limits>
9 #include <vector>
10
11 #include "base/logging.h"
12 #include "base/memory/ref_counted.h"
13 #include "base/memory/scoped_ptr.h"
14 #include "base/values.h"
15 #include "ppapi/c/pp_bool.h"
16 #include "ppapi/c/pp_stdint.h"
17 #include "ppapi/shared_impl/dictionary_var.h"
18 #include "ppapi/shared_impl/ppapi_globals.h"
19 #include "ppapi/shared_impl/scoped_pp_var.h"
20 #include "ppapi/shared_impl/var.h"
21 #include "ppapi/shared_impl/var_tracker.h"
22
23 namespace ppapi {
24
25 namespace {
26
27 base::Value* CreateValueFromVarImpl(const PP_Var& var,
28 std::vector<int64_t>* parent_ids) {
29 switch (var.type) {
30 case PP_VARTYPE_UNDEFINED: {
31 return NULL;
32 }
33 case PP_VARTYPE_NULL: {
34 return base::Value::CreateNullValue();
35 }
36 case PP_VARTYPE_BOOL: {
37 return new base::FundamentalValue(PP_ToBool(var.value.as_bool));
38 }
39 case PP_VARTYPE_INT32: {
40 return new base::FundamentalValue(var.value.as_int);
41 }
42 case PP_VARTYPE_DOUBLE: {
43 return new base::FundamentalValue(var.value.as_double);
44 }
45 case PP_VARTYPE_STRING: {
46 StringVar* string_var = StringVar::FromPPVar(var);
47 if (!string_var)
48 return NULL;
49 return new base::StringValue(string_var->value());
50 }
51 case PP_VARTYPE_OBJECT: {
52 return NULL;
53 }
54 case PP_VARTYPE_ARRAY: {
55 if (std::find(parent_ids->begin(), parent_ids->end(), var.value.as_id) !=
56 parent_ids->end()) {
dmichael (off chromium) 2013/03/05 22:01:03 So the conversion is O(n^2). You could drop it to
yzshen1 2013/03/14 05:38:21 Done. I changed it to a set. (I think it should b
dmichael (off chromium) 2013/03/15 17:35:48 O(n^2) worst-case for a line of Object->Child->Chi
yzshen1 2013/03/15 22:56:49 Right. That is true.
57 // A circular reference is found.
58 return NULL;
59 }
60
61 scoped_ptr<base::ListValue> list_value(new base::ListValue());
62 parent_ids->push_back(var.value.as_id);
63
64 // TODO(yzshen): Implement it once array var is supported.
65
66 parent_ids->pop_back();
67 return list_value.release();
68 }
69 case PP_VARTYPE_DICTIONARY: {
70 if (std::find(parent_ids->begin(), parent_ids->end(), var.value.as_id) !=
71 parent_ids->end()) {
72 // A circular reference is found.
73 return NULL;
74 }
75
76 DictionaryVar* dict_var = DictionaryVar::FromPPVar(var);
77 if (!dict_var)
78 return NULL;
79
80 scoped_ptr<base::DictionaryValue> dict_value(new base::DictionaryValue());
81 parent_ids->push_back(var.value.as_id);
82
83 for (DictionaryVar::KeyValueMap::const_iterator iter =
84 dict_var->key_value_map().begin();
85 iter != dict_var->key_value_map().end(); ++iter) {
86 base::Value* value = CreateValueFromVarImpl(iter->second.get(),
87 parent_ids);
dmichael (off chromium) 2013/03/05 22:01:03 If a plugin creates a really deep object, they can
yzshen1 2013/03/14 05:38:21 Yeah, this is a good idea. Thanks! On 2013/03/05 2
88 if (!value) {
89 parent_ids->pop_back();
90 return NULL;
91 }
92
93 dict_value->SetWithoutPathExpansion(iter->first, value);
94 }
95
96 parent_ids->pop_back();
97 return dict_value.release();
98 }
99 case PP_VARTYPE_ARRAY_BUFFER: {
100 ArrayBufferVar* array_buffer = ArrayBufferVar::FromPPVar(var);
101 if (!array_buffer)
102 return NULL;
103
104 base::BinaryValue* binary_value =
105 base::BinaryValue::CreateWithCopiedBuffer(
106 static_cast<const char*>(array_buffer->Map()),
107 array_buffer->ByteLength());
108 array_buffer->Unmap();
109 return binary_value;
110 }
111 }
112 NOTREACHED();
113 return NULL;
114 }
115
116 } // namespace
117
118 base::Value* CreateValueFromVar(const PP_Var& var) {
119 std::vector<int64_t> parent_ids;
120 base::Value* result = CreateValueFromVarImpl(var, &parent_ids);
121 DCHECK(parent_ids.empty());
122 return result;
123 }
124
125 PP_Var CreateVarFromValue(const base::Value& value) {
126 switch (value.GetType()) {
127 case base::Value::TYPE_NULL: {
128 return PP_MakeNull();
129 }
130 case base::Value::TYPE_BOOLEAN: {
131 bool result = false;
132 if (value.GetAsBoolean(&result))
133 return PP_MakeBool(PP_FromBool(result));
134 else
135 return PP_MakeUndefined();
136 }
137 case base::Value::TYPE_INTEGER: {
138 int result = 0;
139 if (value.GetAsInteger(&result))
140 return PP_MakeInt32(result);
141 else
142 return PP_MakeUndefined();
143 }
144 case base::Value::TYPE_DOUBLE: {
145 double result = 0;
146 if (value.GetAsDouble(&result))
147 return PP_MakeDouble(result);
148 else
149 return PP_MakeUndefined();
150 }
151 case base::Value::TYPE_STRING: {
152 std::string result;
153 if (value.GetAsString(&result))
154 return StringVar::StringToPPVar(result);
155 else
156 return PP_MakeUndefined();
157 }
158 case base::Value::TYPE_BINARY: {
dmichael (off chromium) 2013/03/05 22:01:03 nit: It might be nice to order these cases the sam
yzshen1 2013/03/14 05:38:21 I ordered them according to the enum type definiti
159 const base::BinaryValue& binary_value =
160 static_cast<const base::BinaryValue&>(value);
161
162 size_t size = binary_value.GetSize();
163 if (size > std::numeric_limits<uint32>::max())
164 return PP_MakeUndefined();
165
166 return PpapiGlobals::Get()->GetVarTracker()->MakeArrayBufferPPVar(
167 static_cast<uint32>(size), binary_value.GetBuffer());
168 }
169 case base::Value::TYPE_DICTIONARY: {
170 const base::DictionaryValue& dict_value =
171 static_cast<const base::DictionaryValue&>(value);
172
173 scoped_refptr<DictionaryVar> dict_var(new DictionaryVar());
174
175 for (base::DictionaryValue::Iterator iter(dict_value); !iter.IsAtEnd();
dmichael (off chromium) 2013/03/05 22:01:03 nit: I prefer each statement in the for to be on i
yzshen1 2013/03/14 05:38:21 Done.
176 iter.Advance()) {
177 ScopedPPVar child_var(ScopedPPVar::PassRef(),
178 CreateVarFromValue(iter.value()));
179 if (child_var.get().type == PP_VARTYPE_UNDEFINED ||
180 !dict_var->SetWithStringKey(iter.key(), child_var.get())) {
181 return PP_MakeUndefined();
182 }
183 }
184
185 return dict_var->GetPPVar();
186 }
187 case base::Value::TYPE_LIST: {
188 // TODO(yzshen): Add support once array var is supported.
189 return PP_MakeUndefined();
190 }
191 }
192 NOTREACHED();
193 return PP_MakeUndefined();
194 }
195
196 } // namespace ppapi
197
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698