1c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file.
4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// This file contains the definition for CppBindingExample, which is used in
6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// cpp_bound_class_unittest.
7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "cpp_binding_example.h"
9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace {
11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass PropertyCallbackExample : public CppBoundClass::PropertyCallback {
13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual bool GetValue(CppVariant* value) {
15c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    value->Set(value_);
16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return true;
17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual bool SetValue(const CppVariant& value) {
20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    value_.Set(value);
21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return true;
22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private:
25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CppVariant value_;
26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
30c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochCppBindingExample::CppBindingExample() {
31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Map properties.  It's recommended, but not required, that the JavaScript
32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // names (used as the keys in this map) match the names of the member
33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // variables exposed through those names.
34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  BindProperty("my_value", &my_value);
35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  BindProperty("my_other_value", &my_other_value);
36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Bind property with a callback.
38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  BindProperty("my_value_with_callback", new PropertyCallbackExample());
39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Bind property with a getter callback.
40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  BindProperty("same", &CppBindingExample::same);
41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Map methods.  See comment above about names.
43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  BindMethod("echoValue", &CppBindingExample::echoValue);
44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  BindMethod("echoType",  &CppBindingExample::echoType);
45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  BindMethod("plus",      &CppBindingExample::plus);
46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The fallback method is called when a nonexistent method is called on an
48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // object. If none is specified, calling a nonexistent method causes an
49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // exception to be thrown and the JavaScript execution is stopped.
50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  BindFallbackMethod(&CppBindingExample::fallbackMethod);
51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  my_value.Set(10);
53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  my_other_value.Set("Reinitialized!");
54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid CppBindingExample::echoValue(const CppArgumentList& args,
57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                  CppVariant* result) {
58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (args.size() < 1) {
59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    result->SetNull();
60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  result->Set(args[0]);
63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid CppBindingExample::echoType(const CppArgumentList& args,
66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                 CppVariant* result) {
67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (args.size() < 1) {
68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    result->SetNull();
69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Note that if args[0] is a string, the following assignment implicitly
72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // makes a copy of that string, which may have an undesirable impact on
73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // performance.
74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CppVariant arg1 = args[0];
75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (arg1.isBool())
76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    result->Set(true);
77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  else if (arg1.isInt32())
78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    result->Set(7);
79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  else if (arg1.isDouble())
80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    result->Set(3.14159);
81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  else if (arg1.isString())
82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    result->Set("Success!");
83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid CppBindingExample::plus(const CppArgumentList& args,
86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                             CppVariant* result) {
87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (args.size() < 2) {
88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    result->SetNull();
89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CppVariant arg1 = args[0];
93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CppVariant arg2 = args[1];
94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!arg1.isNumber() || !arg2.isNumber()) {
96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    result->SetNull();
97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The value of a CppVariant may be read directly from its NPVariant struct.
101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // (However, it should only be set using one of the Set() functions.)
102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  double sum = 0.;
103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (arg1.isDouble())
104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    sum += arg1.value.doubleValue;
105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  else if (arg1.isInt32())
106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    sum += arg1.value.intValue;
107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (arg2.isDouble())
109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    sum += arg2.value.doubleValue;
110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  else if (arg2.isInt32())
111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    sum += arg2.value.intValue;
112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  result->Set(sum);
114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid CppBindingExample::same(CppVariant* result) {
117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  result->Set(42);
118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid CppBindingExample::fallbackMethod(const CppArgumentList& args,
121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                       CppVariant* result) {
122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  printf("Error: unknown JavaScript method invoked.\n");
123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
124