1#include <stdlib.h>
2#include <string.h>
3#include <node_api.h>
4#include "../../js-native-api/common.h"
5
6static const char theText[] =
7    "Lorem ipsum dolor sit amet, consectetur adipiscing elit.";
8
9static int deleterCallCount = 0;
10static void deleteTheText(napi_env env, void* data, void* finalize_hint) {
11  NODE_API_ASSERT_RETURN_VOID(
12      env, data != NULL && strcmp(data, theText) == 0, "invalid data");
13  (void)finalize_hint;
14  free(data);
15  deleterCallCount++;
16}
17
18static void noopDeleter(napi_env env, void* data, void* finalize_hint) {
19  NODE_API_ASSERT_RETURN_VOID(
20      env, data != NULL && strcmp(data, theText) == 0, "invalid data");
21  (void)finalize_hint;
22  deleterCallCount++;
23}
24
25static napi_value newBuffer(napi_env env, napi_callback_info info) {
26  napi_value theBuffer;
27  char* theCopy;
28  const unsigned int kBufferSize = sizeof(theText);
29
30  NODE_API_CALL(env,
31      napi_create_buffer(
32          env, sizeof(theText), (void**)(&theCopy), &theBuffer));
33  NODE_API_ASSERT(env, theCopy, "Failed to copy static text for newBuffer");
34  memcpy(theCopy, theText, kBufferSize);
35
36  return theBuffer;
37}
38
39static napi_value newExternalBuffer(napi_env env, napi_callback_info info) {
40  napi_value theBuffer;
41  char* theCopy = strdup(theText);
42  NODE_API_ASSERT(
43      env, theCopy, "Failed to copy static text for newExternalBuffer");
44  NODE_API_CALL(env,
45      napi_create_external_buffer(
46          env, sizeof(theText), theCopy, deleteTheText,
47          NULL /* finalize_hint */, &theBuffer));
48
49  return theBuffer;
50}
51
52static napi_value getDeleterCallCount(napi_env env, napi_callback_info info) {
53  napi_value callCount;
54  NODE_API_CALL(env, napi_create_int32(env, deleterCallCount, &callCount));
55  return callCount;
56}
57
58static napi_value copyBuffer(napi_env env, napi_callback_info info) {
59  napi_value theBuffer;
60  NODE_API_CALL(env, napi_create_buffer_copy(
61      env, sizeof(theText), theText, NULL, &theBuffer));
62  return theBuffer;
63}
64
65static napi_value bufferHasInstance(napi_env env, napi_callback_info info) {
66  size_t argc = 1;
67  napi_value args[1];
68  NODE_API_CALL(env, napi_get_cb_info(env, info, &argc, args, NULL, NULL));
69  NODE_API_ASSERT(env, argc == 1, "Wrong number of arguments");
70  napi_value theBuffer = args[0];
71  bool hasInstance;
72  napi_valuetype theType;
73  NODE_API_CALL(env, napi_typeof(env, theBuffer, &theType));
74  NODE_API_ASSERT(env,
75      theType == napi_object, "bufferHasInstance: instance is not an object");
76  NODE_API_CALL(env, napi_is_buffer(env, theBuffer, &hasInstance));
77  NODE_API_ASSERT(env, hasInstance, "bufferHasInstance: instance is not a buffer");
78  napi_value returnValue;
79  NODE_API_CALL(env, napi_get_boolean(env, hasInstance, &returnValue));
80  return returnValue;
81}
82
83static napi_value bufferInfo(napi_env env, napi_callback_info info) {
84  size_t argc = 1;
85  napi_value args[1];
86  NODE_API_CALL(env, napi_get_cb_info(env, info, &argc, args, NULL, NULL));
87  NODE_API_ASSERT(env, argc == 1, "Wrong number of arguments");
88  napi_value theBuffer = args[0];
89  char *bufferData;
90  napi_value returnValue;
91  size_t bufferLength;
92  NODE_API_CALL(env,
93      napi_get_buffer_info(
94          env, theBuffer, (void**)(&bufferData), &bufferLength));
95  NODE_API_CALL(env, napi_get_boolean(env,
96      !strcmp(bufferData, theText) && bufferLength == sizeof(theText),
97      &returnValue));
98  return returnValue;
99}
100
101static napi_value staticBuffer(napi_env env, napi_callback_info info) {
102  napi_value theBuffer;
103  NODE_API_CALL(env,
104      napi_create_external_buffer(
105          env, sizeof(theText), (void*)theText, noopDeleter,
106          NULL /* finalize_hint */, &theBuffer));
107  return theBuffer;
108}
109
110static napi_value Init(napi_env env, napi_value exports) {
111  napi_value theValue;
112
113  NODE_API_CALL(env,
114      napi_create_string_utf8(env, theText, sizeof(theText), &theValue));
115  NODE_API_CALL(env,
116      napi_set_named_property(env, exports, "theText", theValue));
117
118  napi_property_descriptor methods[] = {
119      DECLARE_NODE_API_PROPERTY("newBuffer", newBuffer),
120      DECLARE_NODE_API_PROPERTY("newExternalBuffer", newExternalBuffer),
121      DECLARE_NODE_API_PROPERTY("getDeleterCallCount", getDeleterCallCount),
122      DECLARE_NODE_API_PROPERTY("copyBuffer", copyBuffer),
123      DECLARE_NODE_API_PROPERTY("bufferHasInstance", bufferHasInstance),
124      DECLARE_NODE_API_PROPERTY("bufferInfo", bufferInfo),
125      DECLARE_NODE_API_PROPERTY("staticBuffer", staticBuffer),
126  };
127
128  NODE_API_CALL(env, napi_define_properties(
129      env, exports, sizeof(methods) / sizeof(methods[0]), methods));
130
131  return exports;
132}
133
134NAPI_MODULE(NODE_GYP_MODULE_NAME, Init)
135