15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/shared_impl/array_writer.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/shared_impl/ppapi_globals.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/shared_impl/resource.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/shared_impl/resource_tracker.h"
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ppapi/shared_impl/var.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ppapi/shared_impl/var_tracker.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace ppapi {
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)ArrayWriter::ArrayWriter() { Reset(); }
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ArrayWriter::ArrayWriter(const PP_ArrayOutput& output)
20a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    : pp_array_output_(output) {}
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)ArrayWriter::~ArrayWriter() {}
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ArrayWriter::Reset() {
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pp_array_output_.GetDataBuffer = NULL;
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pp_array_output_.user_data = NULL;
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ArrayWriter::StoreResourceVector(
30a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const std::vector<scoped_refptr<Resource> >& input) {
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Always call the alloc function, even on 0 array size.
32a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  void* dest =
33a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      pp_array_output_.GetDataBuffer(pp_array_output_.user_data,
34a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                     static_cast<uint32_t>(input.size()),
35a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                     sizeof(PP_Resource));
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Regardless of success, we clear the output to prevent future calls on
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // this same output object.
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Reset();
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (input.empty())
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;  // Allow plugin to return NULL on 0 elements.
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!dest)
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Convert to PP_Resources.
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PP_Resource* dest_resources = static_cast<PP_Resource*>(dest);
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < input.size(); i++)
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dest_resources[i] = input[i]->GetReference();
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ArrayWriter::StoreResourceVector(const std::vector<PP_Resource>& input) {
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Always call the alloc function, even on 0 array size.
55a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  void* dest =
56a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      pp_array_output_.GetDataBuffer(pp_array_output_.user_data,
57a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                     static_cast<uint32_t>(input.size()),
58a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                     sizeof(PP_Resource));
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Regardless of success, we clear the output to prevent future calls on
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // this same output object.
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Reset();
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (input.empty())
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;  // Allow plugin to return NULL on 0 elements.
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!dest) {
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Free the resources.
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (size_t i = 0; i < input.size(); i++)
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      PpapiGlobals::Get()->GetResourceTracker()->ReleaseResource(input[i]);
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::copy(input.begin(), input.end(), static_cast<PP_Resource*>(dest));
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool ArrayWriter::StoreVarVector(
78a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const std::vector<scoped_refptr<Var> >& input) {
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Always call the alloc function, even on 0 array size.
80a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  void* dest =
81a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      pp_array_output_.GetDataBuffer(pp_array_output_.user_data,
82a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                     static_cast<uint32_t>(input.size()),
83a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                     sizeof(PP_Var));
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Regardless of success, we clear the output to prevent future calls on
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // this same output object.
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Reset();
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (input.empty())
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return true;  // Allow plugin to return NULL on 0 elements.
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!dest)
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Convert to PP_Vars.
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PP_Var* dest_vars = static_cast<PP_Var*>(dest);
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (size_t i = 0; i < input.size(); i++)
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    dest_vars[i] = input[i]->GetPPVar();
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool ArrayWriter::StoreVarVector(const std::vector<PP_Var>& input) {
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Always call the alloc function, even on 0 array size.
103a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  void* dest =
104a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      pp_array_output_.GetDataBuffer(pp_array_output_.user_data,
105a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                     static_cast<uint32_t>(input.size()),
106a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                     sizeof(PP_Var));
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Regardless of success, we clear the output to prevent future calls on
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // this same output object.
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Reset();
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (input.empty())
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return true;  // Allow plugin to return NULL on 0 elements.
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!dest) {
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Free the vars.
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for (size_t i = 0; i < input.size(); i++)
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      PpapiGlobals::Get()->GetVarTracker()->ReleaseVar(input[i]);
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::copy(input.begin(), input.end(), static_cast<PP_Var*>(dest));
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace ppapi
126