File: addon_data.cc

package info (click to toggle)
node-addon-api 8.3.1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 2,248 kB
  • sloc: cpp: 15,431; javascript: 5,631; ansic: 157; makefile: 7
file content (98 lines) | stat: -rw-r--r-- 3,397 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
#if (NAPI_VERSION > 5)
#include <stdio.h>
#include "napi.h"
#include "test_helper.h"

// An overly elaborate way to get/set a boolean stored in the instance data:
// 0. The constructor for JS `VerboseIndicator` instances, which have a private
//    member named "verbose", is stored in the instance data.
// 1. Add a property named "verbose" onto exports served by a getter/setter.
// 2. The getter returns an object of type VerboseIndicator, which itself has a
//    property named "verbose", also served by a getter/setter:
//    * The getter returns a boolean, indicating whether "verbose" is set.
//    * The setter sets "verbose" on the instance data.
// 3. The setter sets "verbose" on the instance data.

class Addon {
 public:
  class VerboseIndicator : public Napi::ObjectWrap<VerboseIndicator> {
   public:
    VerboseIndicator(const Napi::CallbackInfo& info)
        : Napi::ObjectWrap<VerboseIndicator>(info) {
      info.This().As<Napi::Object>()["verbose"] = Napi::Boolean::New(
          info.Env(), info.Env().GetInstanceData<Addon>()->verbose);
    }

    Napi::Value Getter(const Napi::CallbackInfo& info) {
      return Napi::Boolean::New(info.Env(),
                                info.Env().GetInstanceData<Addon>()->verbose);
    }

    void Setter(const Napi::CallbackInfo& info, const Napi::Value& val) {
      info.Env().GetInstanceData<Addon>()->verbose = val.As<Napi::Boolean>();
    }

    static Napi::FunctionReference Init(Napi::Env env) {
      return Napi::Persistent(DefineClass(
          env,
          "VerboseIndicator",
          {InstanceAccessor<&VerboseIndicator::Getter,
                            &VerboseIndicator::Setter>("verbose")}));
    }
  };

  static Napi::Value Getter(const Napi::CallbackInfo& info) {
    return MaybeUnwrap(
        info.Env().GetInstanceData<Addon>()->VerboseIndicator.New({}));
  }

  static void Setter(const Napi::CallbackInfo& info) {
    info.Env().GetInstanceData<Addon>()->verbose = info[0].As<Napi::Boolean>();
  }

  Addon(Napi::Env env) : VerboseIndicator(VerboseIndicator::Init(env)) {}
  ~Addon() {
    if (verbose) {
      fprintf(stderr, "addon_data: Addon::~Addon\n");
    }
  }

  static void DeleteAddon(Napi::Env, Addon* addon, uint32_t* hint) {
    delete addon;
    fprintf(stderr, "hint: %u\n", *hint);
    delete hint;
  }

  static Napi::Object Init(Napi::Env env, Napi::Value jshint) {
    if (!jshint.IsNumber()) {
      NAPI_THROW(Napi::Error::New(env, "Expected number"), Napi::Object());
    }
    uint32_t hint = jshint.As<Napi::Number>();
    if (hint == 0)
      env.SetInstanceData(new Addon(env));
    else
      env.SetInstanceData<Addon, uint32_t, DeleteAddon>(new Addon(env),
                                                        new uint32_t(hint));
    Napi::Object result = Napi::Object::New(env);
    result.DefineProperties({
        Napi::PropertyDescriptor::Accessor<Getter, Setter>("verbose"),
    });

    return result;
  }

 private:
  bool verbose = false;
  Napi::FunctionReference VerboseIndicator;
};

// We use an addon factory so we can cover both the case where there is an
// instance data hint and the case where there isn't.
static Napi::Value AddonFactory(const Napi::CallbackInfo& info) {
  return Addon::Init(info.Env(), info[0]);
}

Napi::Object InitAddonData(Napi::Env env) {
  return Napi::Function::New(env, AddonFactory);
}
#endif  // (NAPI_VERSION > 5)