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

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

Issue 12388083: Add PPB_VarArray_Dev support - part 1. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . 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
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "ppapi/shared_impl/var_value_conversions.h" 5 #include "ppapi/shared_impl/var_value_conversions.h"
6 6
7 #include <limits> 7 #include <limits>
8 #include <set> 8 #include <set>
9 #include <stack> 9 #include <stack>
10 10
11 #include "base/logging.h" 11 #include "base/logging.h"
12 #include "base/memory/ref_counted.h" 12 #include "base/memory/ref_counted.h"
13 #include "base/memory/scoped_ptr.h" 13 #include "base/memory/scoped_ptr.h"
14 #include "base/values.h" 14 #include "base/values.h"
15 #include "ppapi/c/pp_bool.h" 15 #include "ppapi/c/pp_bool.h"
16 #include "ppapi/c/pp_stdint.h" 16 #include "ppapi/c/pp_stdint.h"
17 #include "ppapi/shared_impl/array_var.h"
17 #include "ppapi/shared_impl/dictionary_var.h" 18 #include "ppapi/shared_impl/dictionary_var.h"
18 #include "ppapi/shared_impl/ppapi_globals.h" 19 #include "ppapi/shared_impl/ppapi_globals.h"
19 #include "ppapi/shared_impl/scoped_pp_var.h" 20 #include "ppapi/shared_impl/scoped_pp_var.h"
20 #include "ppapi/shared_impl/var.h" 21 #include "ppapi/shared_impl/var.h"
21 #include "ppapi/shared_impl/var_tracker.h" 22 #include "ppapi/shared_impl/var_tracker.h"
22 23
23 namespace ppapi { 24 namespace ppapi {
24 25
25 namespace { 26 namespace {
26 27
27 // In CreateValueFromVar(), a stack is used to keep track of conversion progress 28 // In CreateValueFromVar(), a stack is used to keep track of conversion progress
28 // of array and dictionary vars. VarNodeBase is the base class of stack 29 // of array and dictionary vars. VarNodeBase is the base class of stack
29 // elements. 30 // elements.
30 class VarNodeBase : public base::RefCounted<VarNodeBase> { 31 class VarNodeBase : public base::RefCounted<VarNodeBase> {
31 public: 32 public:
32 virtual bool IsArrayVar() const { return false; } 33 virtual bool IsArrayVar() const { return false; }
33 virtual bool IsDictionaryVar() const { return false; } 34 virtual bool IsDictionaryVar() const { return false; }
34 35
35 protected: 36 protected:
36 friend class base::RefCounted<VarNodeBase>; 37 friend class base::RefCounted<VarNodeBase>;
37 38
38 VarNodeBase() {} 39 VarNodeBase() {}
39 virtual ~VarNodeBase() {} 40 virtual ~VarNodeBase() {}
40 }; 41 };
41 42
43 class ArrayVarNode : public VarNodeBase {
44 public:
45 ArrayVarNode(int64_t in_var_id, const ArrayVar* array_var)
46 : var_id(in_var_id),
47 next(array_var->elements().begin()),
48 end(array_var->elements().end()),
49 list_value(new base::ListValue()) {
50 }
51
52 virtual bool IsArrayVar() const OVERRIDE {
53 return true;
54 }
55
56 int64_t var_id;
57 ArrayVar::ElementVector::const_iterator next;
58 ArrayVar::ElementVector::const_iterator end;
59 scoped_ptr<base::ListValue> list_value;
60
61 private:
62 virtual ~ArrayVarNode() {}
63 };
64
42 class DictionaryVarNode : public VarNodeBase { 65 class DictionaryVarNode : public VarNodeBase {
43 public: 66 public:
44 DictionaryVarNode(int64_t in_var_id, const DictionaryVar* dict_var) 67 DictionaryVarNode(int64_t in_var_id, const DictionaryVar* dict_var)
45 : var_id(in_var_id), 68 : var_id(in_var_id),
46 next(dict_var->key_value_map().begin()), 69 next(dict_var->key_value_map().begin()),
47 end(dict_var->key_value_map().end()), 70 end(dict_var->key_value_map().end()),
48 dict_value(new base::DictionaryValue()) { 71 dict_value(new base::DictionaryValue()) {
49 } 72 }
50 73
51 virtual bool IsDictionaryVar() const OVERRIDE { 74 virtual bool IsDictionaryVar() const OVERRIDE {
(...skipping 18 matching lines...) Expand all
70 virtual bool IsListValue() const { return false; } 93 virtual bool IsListValue() const { return false; }
71 virtual bool IsDictionaryValue() const { return false; } 94 virtual bool IsDictionaryValue() const { return false; }
72 95
73 protected: 96 protected:
74 friend class base::RefCounted<ValueNodeBase>; 97 friend class base::RefCounted<ValueNodeBase>;
75 98
76 ValueNodeBase() {} 99 ValueNodeBase() {}
77 virtual ~ValueNodeBase() {} 100 virtual ~ValueNodeBase() {}
78 }; 101 };
79 102
103 class ListValueNode : public ValueNodeBase {
104 public:
105 explicit ListValueNode(const base::ListValue& list_value)
106 : next(list_value.begin()),
107 end(list_value.end()),
108 array_var(new ArrayVar()) {
109 array_var->elements().reserve(list_value.GetSize());
110 }
111
112 virtual bool IsListValue() const OVERRIDE {
113 return true;
114 }
115
116 base::ListValue::const_iterator next;
117 base::ListValue::const_iterator end;
118 scoped_refptr<ArrayVar> array_var;
119
120 private:
121 virtual ~ListValueNode() {}
122 };
123
80 class DictionaryValueNode : public ValueNodeBase { 124 class DictionaryValueNode : public ValueNodeBase {
81 public: 125 public:
82 explicit DictionaryValueNode(const base::DictionaryValue& dict_value) 126 explicit DictionaryValueNode(const base::DictionaryValue& dict_value)
83 : iter(dict_value), 127 : iter(dict_value),
84 dict_var(new DictionaryVar()) { 128 dict_var(new DictionaryVar()) {
85 } 129 }
86 130
87 virtual bool IsDictionaryValue() const OVERRIDE { 131 virtual bool IsDictionaryValue() const OVERRIDE {
88 return true; 132 return true;
89 } 133 }
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
128 if (!string_var) 172 if (!string_var)
129 return false; 173 return false;
130 174
131 value->reset(new base::StringValue(string_var->value())); 175 value->reset(new base::StringValue(string_var->value()));
132 return true; 176 return true;
133 } 177 }
134 case PP_VARTYPE_OBJECT: { 178 case PP_VARTYPE_OBJECT: {
135 return false; 179 return false;
136 } 180 }
137 case PP_VARTYPE_ARRAY: { 181 case PP_VARTYPE_ARRAY: {
138 // TODO(yzshen): Implement it once array var is supported. 182 if (parent_ids->find(var.value.as_id) != parent_ids->end()) {
139 return false; 183 // A circular reference is found.
184 return false;
185 }
186
187 ArrayVar* array_var = ArrayVar::FromPPVar(var);
188 if (!array_var)
189 return false;
190
191
192 parent_ids->insert(var.value.as_id);
193 state->push(new ArrayVarNode(var.value.as_id, array_var));
194 return true;
140 } 195 }
141 case PP_VARTYPE_DICTIONARY: { 196 case PP_VARTYPE_DICTIONARY: {
142 if (parent_ids->find(var.value.as_id) != parent_ids->end()) { 197 if (parent_ids->find(var.value.as_id) != parent_ids->end()) {
143 // A circular reference is found. 198 // A circular reference is found.
144 return false; 199 return false;
145 } 200 }
146 201
147 DictionaryVar* dict_var = DictionaryVar::FromPPVar(var); 202 DictionaryVar* dict_var = DictionaryVar::FromPPVar(var);
148 if (!dict_var) 203 if (!dict_var)
149 return false; 204 return false;
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
234 return true; 289 return true;
235 } 290 }
236 return false; 291 return false;
237 } 292 }
238 case base::Value::TYPE_DICTIONARY: { 293 case base::Value::TYPE_DICTIONARY: {
239 state->push(new DictionaryValueNode( 294 state->push(new DictionaryValueNode(
240 static_cast<const base::DictionaryValue&>(value))); 295 static_cast<const base::DictionaryValue&>(value)));
241 return true; 296 return true;
242 } 297 }
243 case base::Value::TYPE_LIST: { 298 case base::Value::TYPE_LIST: {
244 // TODO(yzshen): Add support once array var is supported. 299 state->push(new ListValueNode(
245 return false; 300 static_cast<const base::ListValue&>(value)));
301 return true;
246 } 302 }
247 } 303 }
248 NOTREACHED(); 304 NOTREACHED();
249 return false; 305 return false;
250 } 306 }
251 307
252 } // namespace 308 } // namespace
253 309
254 base::Value* CreateValueFromVar(const PP_Var& var) { 310 base::Value* CreateValueFromVar(const PP_Var& var) {
255 // Used to detect circular references. 311 // Used to detect circular references.
(...skipping 24 matching lines...) Expand all
280 top->current_key = top->next->first; 336 top->current_key = top->next->first;
281 current_var = top->next->second.get(); 337 current_var = top->next->second.get();
282 ++top->next; 338 ++top->next;
283 339
284 // Ignore the key-value pair if the value is undefined. 340 // Ignore the key-value pair if the value is undefined.
285 if (current_var.type == PP_VARTYPE_UNDEFINED) { 341 if (current_var.type == PP_VARTYPE_UNDEFINED) {
286 top->current_key.clear(); 342 top->current_key.clear();
287 continue; 343 continue;
288 } 344 }
289 } 345 }
346 } else if (state.top()->IsArrayVar()) {
347 scoped_refptr<ArrayVarNode> top(
348 static_cast<ArrayVarNode*>(state.top().get()));
349
350 if (current_value.get())
351 top->list_value->Append(current_value.release());
352
353 if (top->next == top->end) {
354 current_value.reset(top->list_value.release());
355 parent_ids.erase(top->var_id);
356 state.pop();
357 continue;
358 } else {
359 current_var = top->next->get();
360 ++top->next;
361 }
290 } else { 362 } else {
291 NOTREACHED(); 363 NOTREACHED();
292 return NULL; 364 return NULL;
293 } 365 }
294 366
295 DCHECK(!current_value.get()); 367 DCHECK(!current_value.get());
296 if (!CreateValueFromVarHelper(current_var, &current_value, &parent_ids, 368 if (!CreateValueFromVarHelper(current_var, &current_value, &parent_ids,
297 &state)) { 369 &state)) {
298 return NULL; 370 return NULL;
299 } 371 }
(...skipping 26 matching lines...) Expand all
326 if (top->iter.IsAtEnd()) { 398 if (top->iter.IsAtEnd()) {
327 current_var = ScopedPPVar(ScopedPPVar::PassRef(), 399 current_var = ScopedPPVar(ScopedPPVar::PassRef(),
328 top->dict_var->GetPPVar()); 400 top->dict_var->GetPPVar());
329 state.pop(); 401 state.pop();
330 continue; 402 continue;
331 } else { 403 } else {
332 top->current_key = top->iter.key(); 404 top->current_key = top->iter.key();
333 current_value = &top->iter.value(); 405 current_value = &top->iter.value();
334 top->iter.Advance(); 406 top->iter.Advance();
335 } 407 }
408 } else if (state.top()->IsListValue()) {
409 scoped_refptr<ListValueNode> top(
410 static_cast<ListValueNode*>(state.top().get()));
411
412 if (current_var.get().type != PP_VARTYPE_UNDEFINED)
413 top->array_var->elements().push_back(current_var);
414 current_var = PP_MakeUndefined();
415 if (top->next == top->end) {
416 current_var = ScopedPPVar(ScopedPPVar::PassRef(),
417 top->array_var->GetPPVar());
418 state.pop();
419 continue;
420 } else {
421 current_value = *top->next;
422 ++top->next;
423 }
336 } else { 424 } else {
337 NOTREACHED(); 425 NOTREACHED();
338 return PP_MakeUndefined(); 426 return PP_MakeUndefined();
339 } 427 }
340 428
341 DCHECK(current_var.get().type == PP_VARTYPE_UNDEFINED); 429 DCHECK(current_var.get().type == PP_VARTYPE_UNDEFINED);
342 if (!CreateVarFromValueHelper(*current_value, &current_var, &state)) 430 if (!CreateVarFromValueHelper(*current_value, &current_var, &state))
343 return PP_MakeUndefined(); 431 return PP_MakeUndefined();
344 }; 432 };
345 433
346 return current_var.Release(); 434 return current_var.Release();
347 } 435 }
348 } // namespace ppapi 436 } // namespace ppapi
349 437
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698