1// Copyright (c) 2011 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/cpp/private/var_private.h"
6
7#include "ppapi/c/dev/ppb_memory_dev.h"
8#include "ppapi/c/dev/ppb_var_deprecated.h"
9#include "ppapi/cpp/instance_handle.h"
10#include "ppapi/cpp/private/instance_private.h"
11#include "ppapi/cpp/logging.h"
12#include "ppapi/cpp/module_impl.h"
13#include "ppapi/cpp/dev/scriptable_object_deprecated.h"
14
15namespace pp {
16
17namespace {
18
19template <> const char* interface_name<PPB_Var_Deprecated>() {
20  return PPB_VAR_DEPRECATED_INTERFACE;
21}
22
23}  // namespace
24
25using namespace deprecated;
26
27VarPrivate::VarPrivate(const InstanceHandle& instance,
28                       ScriptableObject* object) {
29  if (has_interface<PPB_Var_Deprecated>()) {
30    var_ = get_interface<PPB_Var_Deprecated>()->CreateObject(
31        instance.pp_instance(), object->GetClass(), object);
32  } else {
33    var_.type = PP_VARTYPE_NULL;
34    var_.padding = 0;
35  }
36  is_managed_ = true;
37}
38
39ScriptableObject* VarPrivate::AsScriptableObject() const {
40  if (!is_object()) {
41    PP_NOTREACHED();
42  } else if (has_interface<PPB_Var_Deprecated>()) {
43    void* object = NULL;
44    if (get_interface<PPB_Var_Deprecated>()->IsInstanceOf(
45        var_, ScriptableObject::GetClass(), &object)) {
46      return reinterpret_cast<ScriptableObject*>(object);
47    }
48  }
49  return NULL;
50}
51
52bool VarPrivate::HasProperty(const Var& name, Var* exception) const {
53  if (!has_interface<PPB_Var_Deprecated>())
54    return false;
55  return get_interface<PPB_Var_Deprecated>()->HasProperty(
56      var_, name.pp_var(), OutException(exception).get());
57}
58
59bool VarPrivate::HasMethod(const Var& name, Var* exception) const {
60  if (!has_interface<PPB_Var_Deprecated>())
61    return false;
62  return get_interface<PPB_Var_Deprecated>()->HasMethod(
63      var_, name.pp_var(), OutException(exception).get());
64}
65
66VarPrivate VarPrivate::GetProperty(const Var& name, Var* exception) const {
67  if (!has_interface<PPB_Var_Deprecated>())
68    return Var();
69  return Var(PassRef(), get_interface<PPB_Var_Deprecated>()->GetProperty(
70      var_, name.pp_var(), OutException(exception).get()));
71}
72
73void VarPrivate::GetAllPropertyNames(std::vector<Var>* properties,
74                                     Var* exception) const {
75  if (!has_interface<PPB_Var_Deprecated>())
76    return;
77  PP_Var* props = NULL;
78  uint32_t prop_count = 0;
79  get_interface<PPB_Var_Deprecated>()->GetAllPropertyNames(
80      var_, &prop_count, &props, OutException(exception).get());
81  if (!prop_count)
82    return;
83  properties->resize(prop_count);
84  for (uint32_t i = 0; i < prop_count; ++i) {
85    Var temp(PassRef(), props[i]);
86    (*properties)[i] = temp;
87  }
88  const PPB_Memory_Dev* memory_if = static_cast<const PPB_Memory_Dev*>(
89      pp::Module::Get()->GetBrowserInterface(PPB_MEMORY_DEV_INTERFACE));
90  memory_if->MemFree(props);
91}
92
93void VarPrivate::SetProperty(const Var& name, const Var& value,
94                             Var* exception) {
95  if (!has_interface<PPB_Var_Deprecated>())
96    return;
97  get_interface<PPB_Var_Deprecated>()->SetProperty(
98      var_, name.pp_var(), value.pp_var(), OutException(exception).get());
99}
100
101void VarPrivate::RemoveProperty(const Var& name, Var* exception) {
102  if (!has_interface<PPB_Var_Deprecated>())
103    return;
104  get_interface<PPB_Var_Deprecated>()->RemoveProperty(
105      var_, name.pp_var(), OutException(exception).get());
106}
107
108VarPrivate VarPrivate::Call(const Var& method_name, uint32_t argc, Var* argv,
109                            Var* exception) {
110  if (!has_interface<PPB_Var_Deprecated>())
111    return Var();
112  if (argc > 0) {
113    std::vector<PP_Var> args;
114    args.reserve(argc);
115    for (size_t i = 0; i < argc; i++)
116      args.push_back(argv[i].pp_var());
117    return Var(PassRef(), get_interface<PPB_Var_Deprecated>()->Call(
118        var_, method_name.pp_var(), argc, &args[0],
119        OutException(exception).get()));
120  } else {
121    // Don't try to get the address of a vector if it's empty.
122    return Var(PassRef(), get_interface<PPB_Var_Deprecated>()->Call(
123        var_, method_name.pp_var(), 0, NULL,
124        OutException(exception).get()));
125  }
126}
127
128VarPrivate VarPrivate::Construct(uint32_t argc, Var* argv,
129                                 Var* exception) const {
130  if (!has_interface<PPB_Var_Deprecated>())
131    return Var();
132  if (argc > 0) {
133    std::vector<PP_Var> args;
134    args.reserve(argc);
135    for (size_t i = 0; i < argc; i++)
136      args.push_back(argv[i].pp_var());
137    return Var(PassRef(), get_interface<PPB_Var_Deprecated>()->Construct(
138        var_, argc, &args[0], OutException(exception).get()));
139  } else {
140    // Don't try to get the address of a vector if it's empty.
141    return Var(PassRef(), get_interface<PPB_Var_Deprecated>()->Construct(
142        var_, 0, NULL, OutException(exception).get()));
143  }
144}
145
146VarPrivate VarPrivate::Call(const Var& method_name, Var* exception) {
147  if (!has_interface<PPB_Var_Deprecated>())
148    return Var();
149  return Var(PassRef(), get_interface<PPB_Var_Deprecated>()->Call(
150      var_, method_name.pp_var(), 0, NULL, OutException(exception).get()));
151}
152
153VarPrivate VarPrivate::Call(const Var& method_name, const Var& arg1,
154                            Var* exception) {
155  if (!has_interface<PPB_Var_Deprecated>())
156    return Var();
157  PP_Var args[1] = {arg1.pp_var()};
158  return Var(PassRef(), get_interface<PPB_Var_Deprecated>()->Call(
159      var_, method_name.pp_var(), 1, args, OutException(exception).get()));
160}
161
162VarPrivate VarPrivate::Call(const Var& method_name, const Var& arg1,
163                            const Var& arg2, Var* exception) {
164  if (!has_interface<PPB_Var_Deprecated>())
165    return Var();
166  PP_Var args[2] = {arg1.pp_var(), arg2.pp_var()};
167  return Var(PassRef(), get_interface<PPB_Var_Deprecated>()->Call(
168      var_, method_name.pp_var(), 2, args, OutException(exception).get()));
169}
170
171VarPrivate VarPrivate::Call(const Var& method_name, const Var& arg1,
172                            const Var& arg2, const Var& arg3, Var* exception) {
173  if (!has_interface<PPB_Var_Deprecated>())
174    return Var();
175  PP_Var args[3] = {arg1.pp_var(), arg2.pp_var(), arg3.pp_var()};
176  return Var(PassRef(), get_interface<PPB_Var_Deprecated>()->Call(
177      var_, method_name.pp_var(), 3, args, OutException(exception).get()));
178}
179
180VarPrivate VarPrivate::Call(const Var& method_name, const Var& arg1,
181                            const Var& arg2, const Var& arg3, const Var& arg4,
182                            Var* exception) {
183  if (!has_interface<PPB_Var_Deprecated>())
184    return Var();
185  PP_Var args[4] = {arg1.pp_var(), arg2.pp_var(), arg3.pp_var(), arg4.pp_var()};
186  return Var(PassRef(), get_interface<PPB_Var_Deprecated>()->Call(
187      var_, method_name.pp_var(), 4, args, OutException(exception).get()));
188}
189
190}  // namespace pp
191