OLD | NEW |
---|---|
(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, ¤t)) | |
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 | |
OLD | NEW |