Chromium Code Reviews| 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 |