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

Side by Side Diff: ppapi/proxy/raw_var_data.cc

Issue 13887007: Introduce RawVarData and associated classes for serializing PP_Vars (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 8 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/proxy/raw_var_data.h"
6
7 #include "base/stl_util.h"
8 #include "ipc/ipc_message.h"
9 #include "ppapi/proxy/ppapi_param_traits.h"
10 #include "ppapi/shared_impl/array_var.h"
11 #include "ppapi/shared_impl/dictionary_var.h"
12 #include "ppapi/shared_impl/ppapi_globals.h"
13 #include "ppapi/shared_impl/scoped_pp_var.h"
14 #include "ppapi/shared_impl/var.h"
15 #include "ppapi/shared_impl/var_graph.h"
16 #include "ppapi/shared_impl/var_tracker.h"
17
18 namespace ppapi {
19 namespace proxy {
20
21 namespace {
22
23 // When sending array buffers, if the size is over 256K, we use shared
24 // memory instead of sending the data over IPC. Light testing suggests
25 // shared memory is much faster for 256K and larger messages.
26 static const uint32 kMinimumArrayBufferSizeForShmem = 256 * 1024;
27
28 RawVarData* CreateRawVarData(const PP_Var& var,
29 const VarGraph* graph,
dmichael (off chromium) 2013/04/12 22:40:38 Why not const&?
30 PP_Instance instance) {
31 switch (var.type) {
32 case PP_VARTYPE_UNDEFINED:
33 case PP_VARTYPE_NULL:
34 case PP_VARTYPE_BOOL:
35 case PP_VARTYPE_INT32:
36 case PP_VARTYPE_DOUBLE:
37 return new BasicRawVarData(var);
38 case PP_VARTYPE_STRING:
39 return new StringRawVarData(var);
40 case PP_VARTYPE_ARRAY_BUFFER:
41 return new ArrayBufferRawVarData(var, instance);
42 case PP_VARTYPE_ARRAY:
43 return new ArrayRawVarData(var, *graph);
44 case PP_VARTYPE_DICTIONARY:
45 return new DictionaryRawVarData(var, *graph);
46 case PP_VARTYPE_OBJECT:
47 NOTREACHED();
48 return NULL;
49 }
50 NOTREACHED();
51 return NULL;
52 }
53
54 PP_Var ReferenceToVar(const RawVarData::VarReference& ref,
dmichael (off chromium) 2013/04/12 22:40:38 "Reference" is a little overloaded, given these ar
raymes 2013/04/14 16:32:57 This has all been removed now.
55 const std::vector<PP_Var>& graph) {
56 PP_Var var = ref.var;
57 if (VarTracker::IsVarTypeRefcounted(var.type)) {
58 if (!ref.valid_var_ref) {
59 var.value.as_id = 0;
60 } else {
61 if (graph.size() <= ref.ref_id) {
62 NOTREACHED();
63 return PP_MakeUndefined();
64 }
65 var.value.as_id = graph[ref.ref_id].value.as_id;
66 }
67 }
68 return var;
69 }
70
71 RawVarData::VarReference VarToReference(const PP_Var& var,
72 const VarGraph& graph) {
73 RawVarData::VarReference result;
dmichael (off chromium) 2013/04/12 22:40:38 Given VarReference has no default constructor, eve
raymes 2013/04/14 16:32:57 "
74 result.var = var;
75 if (VarTracker::IsVarTypeRefcounted(var.type)) {
76 std::map<int64_t, size_t>::const_iterator iterator =
77 graph.id_map.find(var.value.as_id);
78 if (iterator == graph.id_map.end()) {
79 result.valid_var_ref = false;
80 return result;
81 }
82 result.ref_id = iterator->second;
83 }
84 return result;
85 }
86
87 PP_Var MakeInvalidRef(PP_VarType type) {
dmichael (off chromium) 2013/04/12 22:40:38 I don't think we should even serialize invalid var
raymes 2013/04/14 16:32:57 Done - this is all removed.
88 DCHECK(VarTracker::IsVarTypeRefcounted(type));
89 PP_Var result;
90 result.type = type;
91 result.value.as_id = 0;
92 return result;
93 }
94
95 void WriteVarReference(IPC::Message* m,
96 const HandleWriter handle_writer,
97 const RawVarData::VarReference& var_reference) {
98 if (!VarTracker::IsVarTypeRefcounted(var_reference.var.type)) {
99 BasicRawVarData(var_reference.var).Write(m, handle_writer);
100 } else {
101 m->WriteInt(var_reference.var.type);
102 m->WriteBool(var_reference.valid_var_ref);
103 m->WriteUInt32(var_reference.ref_id);
104 }
105 }
106
107 bool ReadVarReference(const IPC::Message* m,
108 PickleIterator* iter,
109 RawVarData::VarReference* result_out) {
110 RawVarData::VarReference result;
111 int32_t type;
112 if (!m->ReadInt(iter, &type))
113 return false;
114 result.var.type = static_cast<PP_VarType>(type);
115 if (!VarTracker::IsVarTypeRefcounted(result.var.type)) {
116 scoped_ptr<BasicRawVarData> data(
117 BasicRawVarData::Read(result.var.type, m, iter));
118 result.var = data->CreatePPVar(0);
119 } else {
120 if (!m->ReadBool(iter, &result.valid_var_ref))
121 return false;
122 if (!m->ReadUInt32(iter, &result.ref_id))
123 return false;
124 }
125 *result_out = result;
126 return true;
127 }
128
129 void DefaultHandleWriter(IPC::Message* m, const SerializedHandle& handle) {
130 IPC::ParamTraits<SerializedHandle>::Write(m, handle);
131 }
132
133 } // namespace
134
135 // RawVarDataGraph ------------------------------------------------------------
136 RawVarDataGraph::RawVarDataGraph() {
137 }
138
139 RawVarDataGraph::~RawVarDataGraph() {
140 }
141
142 RawVarDataGraph::RawVarDataGraph(const PP_Var& var, PP_Instance instance) {
143 if (PpapiGlobals::Get()->GetVarTracker()->GetVar(var) == NULL) {
144 // If the node is a primitive value, just create a single raw var data.
145 data_.push_back(CreateRawVarData(var, NULL, instance));
dmichael (off chromium) 2013/04/12 22:40:38 Why do you need the if at all? (Notes to self: Loo
raymes 2013/04/14 16:32:57 I changed the way this works, hopefully it is clea
146 } else {
147 VarGraph graph;
148 bool success = VarGraph::Create(var, &graph);
149 if (!success) {
150 NOTREACHED();
151 return;
152 }
153
154 for (size_t i = 0; i < graph.nodes.size(); ++i)
155 data_.push_back(CreateRawVarData(var, &graph, instance));
156 }
157 }
158
159 PP_Var RawVarDataGraph::CreatePPVar(PP_Instance instance) {
160 // Create and initialize each node in the graph.
161 std::vector<PP_Var> graph;
162 for (size_t i = 0; i < data_.size(); ++i)
163 graph.push_back(data_[i]->CreatePPVar(instance));
164 for (size_t i = 0; i < data_.size(); ++i)
165 data_[i]->InitPPVar(graph[i], graph);
dmichael (off chromium) 2013/04/12 22:40:38 I found InitPPVar a bit confusing as a name. Maybe
raymes 2013/04/14 16:32:57 See my reply in the header. I changed the name as
166 // The first element is the root.
167 return graph[0];
168 }
169
170 void RawVarDataGraph::Write(IPC::Message* m,
171 const HandleWriter& handle_writer) {
172 // Write the size, followed by each node in the graph.
173 m->WriteInt(data_.size());
174 for (size_t i = 0; i < data_.size(); ++i)
175 data_[i]->Write(m, handle_writer);
176 }
177
178 void RawVarDataGraph::Write(IPC::Message* m) {
179 Write(m, base::Bind(&DefaultHandleWriter));
180 }
181
182 // static
183 scoped_ptr<RawVarDataGraph> RawVarDataGraph::Read(const IPC::Message* m,
184 PickleIterator* iter) {
185 scoped_ptr<RawVarDataGraph> result(new RawVarDataGraph);
186 int32_t size = 0;
187 if (!m->ReadInt(iter, &size))
188 return scoped_ptr<RawVarDataGraph>();
189 for (int32_t i = 0; i < size; ++i) {
190 int32_t type;
191 if (!m->ReadInt(iter, &type))
192 return scoped_ptr<RawVarDataGraph>();
193 PP_VarType var_type = static_cast<PP_VarType>(type);
194 switch (var_type) {
195 case PP_VARTYPE_UNDEFINED:
196 case PP_VARTYPE_NULL:
197 case PP_VARTYPE_BOOL:
198 case PP_VARTYPE_INT32:
199 case PP_VARTYPE_DOUBLE:
200 result->data_.push_back(BasicRawVarData::Read(var_type, m, iter));
dmichael (off chromium) 2013/04/12 22:40:38 Random idea, not sure how hard this is... It woul
raymes 2013/04/14 16:32:57 I think that's a good idea. Done.
201 break;
202 case PP_VARTYPE_STRING:
203 result->data_.push_back(StringRawVarData::Read(var_type, m, iter));
204 break;
205 case PP_VARTYPE_ARRAY:
206 result->data_.push_back(ArrayRawVarData::Read(var_type, m, iter));
207 break;
208 case PP_VARTYPE_DICTIONARY:
209 result->data_.push_back(DictionaryRawVarData::Read(var_type, m, iter));
210 break;
211 case PP_VARTYPE_ARRAY_BUFFER:
212 result->data_.push_back(ArrayBufferRawVarData::Read(var_type, m, iter));
213 break;
214 case PP_VARTYPE_OBJECT:
215 NOTREACHED();
216 scoped_ptr<RawVarDataGraph>();
217 }
218 }
219 return result.Pass();
220 }
221
222 // BasicRawVarData -------------------------------------------------------------
223 BasicRawVarData::BasicRawVarData(const PP_Var& var) : var_(var) {
224 }
225
226 BasicRawVarData::~BasicRawVarData() {
227 }
228
229 PP_Var BasicRawVarData::CreatePPVar(PP_Instance instance) {
230 return var_;
231 }
232
233 void BasicRawVarData::InitPPVar(const PP_Var& var,
234 const std::vector<PP_Var>& graph) {
235 }
236
237 void BasicRawVarData::Write(
238 IPC::Message* m,
239 const HandleWriter& handle_writer) {
240 m->WriteInt(static_cast<int>(var_.type));
241 switch (var_.type) {
242 case PP_VARTYPE_UNDEFINED:
243 case PP_VARTYPE_NULL:
244 // These don't need any data associated with them other than the type we
245 // just serialized.
246 break;
247 case PP_VARTYPE_BOOL:
248 m->WriteBool(PP_ToBool(var_.value.as_bool));
249 break;
250 case PP_VARTYPE_INT32:
251 m->WriteInt(var_.value.as_int);
252 break;
253 case PP_VARTYPE_DOUBLE:
254 IPC::ParamTraits<double>::Write(m, var_.value.as_double);
255 break;
256 default:
257 NOTREACHED();
258 }
259 }
260
261 // static
262 BasicRawVarData* BasicRawVarData::Read(PP_VarType type,
263 const IPC::Message* m,
264 PickleIterator* iter) {
265 PP_Var result;
266 result.type = type;
267 switch (type) {
268 case PP_VARTYPE_UNDEFINED:
269 case PP_VARTYPE_NULL:
270 // These don't have any data associated with them other than the type we
271 // just serialized.
272 break;
273 case PP_VARTYPE_BOOL: {
274 bool bool_value;
275 if (!m->ReadBool(iter, &bool_value))
276 return NULL;
277 result.value.as_bool = PP_FromBool(bool_value);
278 break;
279 }
280 case PP_VARTYPE_INT32:
281 if (!m->ReadInt(iter, &result.value.as_int))
282 return NULL;
283 break;
284 case PP_VARTYPE_DOUBLE:
285 if (!IPC::ParamTraits<double>::Read(m, iter, &result.value.as_double))
286 return NULL;
287 break;
288 default:
289 NOTREACHED();
290 return NULL;
291 }
292 return new BasicRawVarData(result);
293 }
294
295 // StringRawVarData ------------------------------------------------------------
296 StringRawVarData::StringRawVarData(const PP_Var& var) : valid_var_ref_(true) {
297 DCHECK(var.type == PP_VARTYPE_STRING);
298 StringVar* string_var = StringVar::FromPPVar(var);
299 if (!string_var)
300 valid_var_ref_ = false;
301 else
302 data_ = *string_var->ptr();
dmichael (off chromium) 2013/04/12 22:40:38 It's worth thinking about if there are ways to red
raymes 2013/04/14 16:32:57 I haven't yet addressed any of these comments rela
303 }
304
305 StringRawVarData::~StringRawVarData() {
306 }
307
308 PP_Var StringRawVarData::CreatePPVar(PP_Instance instance) {
309 if (!valid_var_ref_)
310 return MakeInvalidRef(PP_VARTYPE_STRING);
311 return StringVar::StringToPPVar(data_);
dmichael (off chromium) 2013/04/12 22:40:38 I think you should use StringVar::SwapValidatedUTF
raymes 2013/04/14 16:32:57 "
312 }
313
314 void StringRawVarData::InitPPVar(const PP_Var& var,
315 const std::vector<PP_Var>& graph) {
316 }
317
318 void StringRawVarData::Write(IPC::Message* m,
319 const HandleWriter& handle_writer) {
320 m->WriteInt(PP_VARTYPE_STRING);
dmichael (off chromium) 2013/04/12 22:40:38 It feels a little odd that the Write virtual funct
raymes 2013/04/14 16:32:57 Done.
321 m->WriteBool(valid_var_ref_);
322 if (valid_var_ref_)
323 m->WriteString(data_);
324 }
325
326 // static
327 StringRawVarData* StringRawVarData::Read(PP_VarType type,
328 const IPC::Message* m,
329 PickleIterator* iter) {
330 bool valid_var_ref;
331 std::string data;
332 if (!m->ReadBool(iter, &valid_var_ref))
333 return NULL;
334 if (valid_var_ref) {
335 if (!m->ReadString(iter, &data))
336 return NULL;
337 }
338 return new StringRawVarData(valid_var_ref, data);
dmichael (off chromium) 2013/04/12 22:40:38 I can't see where this constructor is actually imp
raymes 2013/04/14 16:32:57 "
339 }
340
341 // ArrayBufferRawVarData -------------------------------------------------------
342 ArrayBufferRawVarData::ArrayBufferRawVarData(const PP_Var& var,
343 PP_Instance instance)
344 : valid_var_ref_(true) {
345 DCHECK(var.type == PP_VARTYPE_ARRAY_BUFFER);
346 ArrayBufferVar* buffer_var = ArrayBufferVar::FromPPVar(var);
347 if (!buffer_var) {
348 valid_var_ref_ = false;
349 } else {
350 bool using_shmem = false;
351 if (buffer_var->ByteLength() >= kMinimumArrayBufferSizeForShmem &&
352 instance != 0) {
353 int host_handle_id;
354 base::SharedMemoryHandle plugin_handle;
355 using_shmem = buffer_var->CopyToNewShmem(instance,
356 &host_handle_id,
357 &plugin_handle);
358 if (using_shmem) {
359 if (host_shm_handle_id_ != -1) {
360 DCHECK(!base::SharedMemory::IsHandleValid(plugin_handle));
361 DCHECK(PpapiGlobals::Get()->IsPluginGlobals());
362 type_ = ARRAY_BUFFER_SHMEM_HOST;
363 host_shm_handle_id_ = host_handle_id;
364 } else {
365 DCHECK(base::SharedMemory::IsHandleValid(plugin_handle));
366 DCHECK(PpapiGlobals::Get()->IsHostGlobals());
367 type_ = ARRAY_BUFFER_SHMEM_PLUGIN;
368 plugin_shm_handle_ = SerializedHandle(plugin_handle,
369 buffer_var->ByteLength());
370 }
371 }
372 }
373 if (!using_shmem) {
374 type_ = ARRAY_BUFFER_NO_SHMEM;
375 data_ = std::string(static_cast<const char*>(buffer_var->Map()),
376 buffer_var->ByteLength());
dmichael (off chromium) 2013/04/12 22:40:38 Same comment as for String... seems like we could
raymes 2013/04/14 16:32:57 "
377 }
378 }
379 }
380
381 ArrayBufferRawVarData::ArrayBufferRawVarData(bool valid_var_ref,
382 ShmemType type)
383 : valid_var_ref_(valid_var_ref),
384 type_(type) {
385 }
386
387 ArrayBufferRawVarData::~ArrayBufferRawVarData() {
388 }
389
390 PP_Var ArrayBufferRawVarData::CreatePPVar(PP_Instance instance) {
391 if (!valid_var_ref_)
392 return MakeInvalidRef(PP_VARTYPE_ARRAY_BUFFER);
393 PP_Var result = PP_MakeUndefined();
394 switch (type_) {
395 case ARRAY_BUFFER_SHMEM_HOST: {
396 base::SharedMemoryHandle host_handle;
397 uint32 size_in_bytes;
398 bool ok = PpapiGlobals::Get()->GetVarTracker()->
399 StopTrackingSharedMemoryHandle(host_shm_handle_id_,
400 instance,
401 &host_handle,
402 &size_in_bytes);
403 if (ok) {
404 result = PpapiGlobals::Get()->GetVarTracker()->MakeArrayBufferPPVar(
405 size_in_bytes, host_handle);
406 } else {
407 LOG(ERROR) << "Couldn't find array buffer id: " << host_shm_handle_id_;
408 return PP_MakeUndefined();
409 }
410 break;
411 }
412 case ARRAY_BUFFER_SHMEM_PLUGIN: {
413 result = PpapiGlobals::Get()->GetVarTracker()->MakeArrayBufferPPVar(
414 plugin_shm_handle_.size(),
415 plugin_shm_handle_.shmem());
416 break;
417 }
418 case ARRAY_BUFFER_NO_SHMEM: {
419 result = PpapiGlobals::Get()->GetVarTracker()->MakeArrayBufferPPVar(
420 static_cast<uint32>(data_.size()), data_.data());
dmichael (off chromium) 2013/04/12 22:40:38 On the plugin side, if data_ is a vector<uint8_t>,
raymes 2013/04/14 16:32:57 "
421 break;
422 }
423 default:
424 NOTREACHED();
425 return PP_MakeUndefined();
426 }
427 DCHECK(result.type == PP_VARTYPE_ARRAY_BUFFER);
428 return result;
429 }
430
431 void ArrayBufferRawVarData::InitPPVar(const PP_Var& var,
432 const std::vector<PP_Var>& graph) {
433 }
434
435 void ArrayBufferRawVarData::Write(
436 IPC::Message* m,
437 const HandleWriter& handle_writer) {
438 m->WriteInt(PP_VARTYPE_ARRAY_BUFFER);
439 m->WriteBool(valid_var_ref_);
440 if (!valid_var_ref_)
441 return;
442 m->WriteInt(type_);
443 switch (type_) {
444 case ARRAY_BUFFER_SHMEM_HOST:
445 m->WriteInt(host_shm_handle_id_);
446 break;
447 case ARRAY_BUFFER_SHMEM_PLUGIN:
448 handle_writer.Run(m, plugin_shm_handle_);
449 break;
450 case ARRAY_BUFFER_NO_SHMEM:
451 m->WriteString(data_);
452 break;
453 }
454 }
455
456 // static
457 ArrayBufferRawVarData* ArrayBufferRawVarData::Read(PP_VarType type,
458 const IPC::Message* m,
459 PickleIterator* iter) {
460 bool valid_var_ref;
461 if (!m->ReadBool(iter, &valid_var_ref))
462 return NULL;
463 if (!valid_var_ref)
464 return new ArrayBufferRawVarData(false, ARRAY_BUFFER_NO_SHMEM);
465 int shmem_type;
466 if (!m->ReadInt(iter, &shmem_type))
467 return NULL;
468 scoped_ptr<ArrayBufferRawVarData> result(
469 new ArrayBufferRawVarData(true, static_cast<ShmemType>(shmem_type)));
470 switch (static_cast<ShmemType>(shmem_type)) {
471 case ARRAY_BUFFER_SHMEM_HOST:
472 if (!m->ReadInt(iter, &result->host_shm_handle_id_))
473 return NULL;
474 break;
475 case ARRAY_BUFFER_SHMEM_PLUGIN:
476 if (!IPC::ParamTraits<SerializedHandle>::Read(
477 m, iter, &result->plugin_shm_handle_)) {
478 return NULL;
479 }
480 break;
481 case ARRAY_BUFFER_NO_SHMEM:
482 if (!m->ReadString(iter, &result->data_))
483 return NULL;
484 default:
485 NOTREACHED();
486 return NULL;
487 }
488 return result.release();
489 }
490
491 // ArrayRawVarData -------------------------------------------------------------
492 ArrayRawVarData::ArrayRawVarData(const PP_Var& var, const VarGraph& graph)
493 : valid_var_ref_(true) {
494 DCHECK(var.type == PP_VARTYPE_ARRAY);
495 ArrayVar* array_var = ArrayVar::FromPPVar(var);
496 if (!array_var) {
497 valid_var_ref_ = false;
498 } else {
499 for (ArrayVar::ElementVector::const_iterator iter =
500 array_var->elements().begin();
501 iter != array_var->elements().end();
502 ++iter) {
503 data_.push_back(VarToReference(iter->get(), graph));
dmichael (off chromium) 2013/04/12 22:40:38 It seems strange to me that you have two different
raymes1 2013/04/12 23:21:38 Sort of. The VarGraph gives you 2 things: 1) The t
dmichael (off chromium) 2013/04/15 17:40:04 It looks like you figured out how to avoid the two
504 }
505 }
506 }
507
508 ArrayRawVarData::ArrayRawVarData(bool valid_var_ref,
509 const std::vector<VarReference>& data)
510 : valid_var_ref_(valid_var_ref),
511 data_(data) {
512 }
513
514 ArrayRawVarData::~ArrayRawVarData() {
515 }
516
517 PP_Var ArrayRawVarData::CreatePPVar(PP_Instance instance) {
518 if (!valid_var_ref_)
519 return MakeInvalidRef(PP_VARTYPE_ARRAY);
520 return (new ArrayVar())->GetPPVar();
521 }
522
523 void ArrayRawVarData::InitPPVar(const PP_Var& var,
524 const std::vector<PP_Var>& graph) {
525 if (var.type != PP_VARTYPE_ARRAY) {
526 NOTREACHED();
527 return;
528 }
529 ArrayVar* array_var = ArrayVar::FromPPVar(var);
530 DCHECK(array_var->elements().empty());
531 for (size_t i = 0; i < data_.size(); ++i) {
532 array_var->elements().push_back(ScopedPPVar(
533 ReferenceToVar(data_[i], graph)));
534 }
535 }
536
537 void ArrayRawVarData::Write(IPC::Message* m,
538 const HandleWriter& handle_writer) {
539 m->WriteInt(PP_VARTYPE_ARRAY);
540 m->WriteBool(valid_var_ref_);
541 if (!valid_var_ref_)
542 return;
543 m->WriteInt(data_.size());
544 for (size_t i = 0; i < data_.size(); ++i)
545 WriteVarReference(m, handle_writer, data_[i]);
546 }
547
548 // static
549 ArrayRawVarData* ArrayRawVarData::Read(PP_VarType type,
550 const IPC::Message* m,
551 PickleIterator* iter) {
552 bool valid_var_ref;
553 std::vector<VarReference> data;
554 if (!m->ReadBool(iter, &valid_var_ref))
555 return NULL;
556 if (valid_var_ref) {
557 VarReference current;
558 if (!ReadVarReference(m, iter, &current))
559 return NULL;
560 data.push_back(current);
561 }
562 return new ArrayRawVarData(valid_var_ref, data);
563 }
564
565 // DictionaryRawVarData --------------------------------------------------------
566 DictionaryRawVarData::DictionaryRawVarData(const PP_Var& var,
567 const VarGraph& graph)
568 : valid_var_ref_(true) {
569 DCHECK(var.type == PP_VARTYPE_DICTIONARY);
570 DictionaryVar* dict_var = DictionaryVar::FromPPVar(var);
571 if (!dict_var) {
572 valid_var_ref_ = false;
573 } else {
574 for (DictionaryVar::KeyValueMap::const_iterator iter =
575 dict_var->key_value_map().begin();
576 iter != dict_var->key_value_map().end();
577 ++iter) {
578 std::pair<std::string, VarReference> reference;
579 reference.first = iter->first;
580 reference.second = VarToReference(iter->second.get(), graph);
581 data_.push_back(reference);
582 }
583 }
584 }
585
586 DictionaryRawVarData::DictionaryRawVarData(
587 bool valid_var_ref,
588 const std::vector<std::pair<std::string, VarReference> >& data)
589 : valid_var_ref_(valid_var_ref),
590 data_(data) {
591 }
592
593 DictionaryRawVarData::~DictionaryRawVarData() {
594 }
595
596 PP_Var DictionaryRawVarData::CreatePPVar(PP_Instance instance) {
597 if (!valid_var_ref_)
598 return MakeInvalidRef(PP_VARTYPE_DICTIONARY);
599 return (new DictionaryVar())->GetPPVar();
600 }
601
602 void DictionaryRawVarData::InitPPVar(const PP_Var& var,
603 const std::vector<PP_Var>& graph) {
604 if (var.type != PP_VARTYPE_DICTIONARY) {
605 NOTREACHED();
606 return;
607 }
608 DictionaryVar* dictionary_var = DictionaryVar::FromPPVar(var);
609 DCHECK(dictionary_var->key_value_map().empty());
610 for (size_t i = 0; i < data_.size(); ++i) {
611 PP_Var value = ReferenceToVar(data_[i].second, graph);
612 dictionary_var->Set(StringVar::StringToPPVar(data_[i].first), value);
613 }
614 }
615
616 void DictionaryRawVarData::Write(
617 IPC::Message* m,
618 const HandleWriter& handle_writer) {
619 m->WriteInt(PP_VARTYPE_DICTIONARY);
620 m->WriteBool(valid_var_ref_);
621 if (!valid_var_ref_)
622 return;
623 m->WriteInt(data_.size());
624 for (size_t i = 0; i < data_.size(); ++i) {
625 m->WriteString(data_[i].first);
626 WriteVarReference(m, handle_writer, data_[i].second);
627 }
628 }
629
630 // static
631 DictionaryRawVarData* DictionaryRawVarData::Read(PP_VarType type,
632 const IPC::Message* m,
633 PickleIterator* iter) {
634 bool valid_var_ref;
635 std::vector<std::pair<std::string, VarReference> > data;
636 if (!m->ReadBool(iter, &valid_var_ref))
637 return NULL;
638 if (valid_var_ref) {
639 std::string key;
640 VarReference value;
641 if (!m->ReadString(iter, &key))
642 return NULL;
643 if (!ReadVarReference(m, iter, &value))
644 return NULL;
645 data.push_back(make_pair(key, value));
646 }
647 return new DictionaryRawVarData(valid_var_ref, data);
648 }
649
650 } // namespace proxy
651 } // namespace ppapi
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698