1// Copyright (c) 2012 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/shared_impl/array_writer.h"
6
7#include <algorithm>
8
9#include "ppapi/shared_impl/ppapi_globals.h"
10#include "ppapi/shared_impl/resource.h"
11#include "ppapi/shared_impl/resource_tracker.h"
12#include "ppapi/shared_impl/var.h"
13#include "ppapi/shared_impl/var_tracker.h"
14
15namespace ppapi {
16
17ArrayWriter::ArrayWriter() { Reset(); }
18
19ArrayWriter::ArrayWriter(const PP_ArrayOutput& output)
20    : pp_array_output_(output) {}
21
22ArrayWriter::~ArrayWriter() {}
23
24void ArrayWriter::Reset() {
25  pp_array_output_.GetDataBuffer = NULL;
26  pp_array_output_.user_data = NULL;
27}
28
29bool ArrayWriter::StoreResourceVector(
30    const std::vector<scoped_refptr<Resource> >& input) {
31  // Always call the alloc function, even on 0 array size.
32  void* dest =
33      pp_array_output_.GetDataBuffer(pp_array_output_.user_data,
34                                     static_cast<uint32_t>(input.size()),
35                                     sizeof(PP_Resource));
36
37  // Regardless of success, we clear the output to prevent future calls on
38  // this same output object.
39  Reset();
40
41  if (input.empty())
42    return true;  // Allow plugin to return NULL on 0 elements.
43  if (!dest)
44    return false;
45
46  // Convert to PP_Resources.
47  PP_Resource* dest_resources = static_cast<PP_Resource*>(dest);
48  for (size_t i = 0; i < input.size(); i++)
49    dest_resources[i] = input[i]->GetReference();
50  return true;
51}
52
53bool ArrayWriter::StoreResourceVector(const std::vector<PP_Resource>& input) {
54  // Always call the alloc function, even on 0 array size.
55  void* dest =
56      pp_array_output_.GetDataBuffer(pp_array_output_.user_data,
57                                     static_cast<uint32_t>(input.size()),
58                                     sizeof(PP_Resource));
59
60  // Regardless of success, we clear the output to prevent future calls on
61  // this same output object.
62  Reset();
63
64  if (input.empty())
65    return true;  // Allow plugin to return NULL on 0 elements.
66  if (!dest) {
67    // Free the resources.
68    for (size_t i = 0; i < input.size(); i++)
69      PpapiGlobals::Get()->GetResourceTracker()->ReleaseResource(input[i]);
70    return false;
71  }
72
73  std::copy(input.begin(), input.end(), static_cast<PP_Resource*>(dest));
74  return true;
75}
76
77bool ArrayWriter::StoreVarVector(
78    const std::vector<scoped_refptr<Var> >& input) {
79  // Always call the alloc function, even on 0 array size.
80  void* dest =
81      pp_array_output_.GetDataBuffer(pp_array_output_.user_data,
82                                     static_cast<uint32_t>(input.size()),
83                                     sizeof(PP_Var));
84
85  // Regardless of success, we clear the output to prevent future calls on
86  // this same output object.
87  Reset();
88
89  if (input.empty())
90    return true;  // Allow plugin to return NULL on 0 elements.
91  if (!dest)
92    return false;
93
94  // Convert to PP_Vars.
95  PP_Var* dest_vars = static_cast<PP_Var*>(dest);
96  for (size_t i = 0; i < input.size(); i++)
97    dest_vars[i] = input[i]->GetPPVar();
98  return true;
99}
100
101bool ArrayWriter::StoreVarVector(const std::vector<PP_Var>& input) {
102  // Always call the alloc function, even on 0 array size.
103  void* dest =
104      pp_array_output_.GetDataBuffer(pp_array_output_.user_data,
105                                     static_cast<uint32_t>(input.size()),
106                                     sizeof(PP_Var));
107
108  // Regardless of success, we clear the output to prevent future calls on
109  // this same output object.
110  Reset();
111
112  if (input.empty())
113    return true;  // Allow plugin to return NULL on 0 elements.
114  if (!dest) {
115    // Free the vars.
116    for (size_t i = 0; i < input.size(); i++)
117      PpapiGlobals::Get()->GetVarTracker()->ReleaseVar(input[i]);
118    return false;
119  }
120
121  std::copy(input.begin(), input.end(), static_cast<PP_Var*>(dest));
122  return true;
123}
124
125}  // namespace ppapi
126