1 #include <js_native_api.h>
2 #include <string.h>
3 #include <stdlib.h>
4 #include "../common.h"
5
Multiply(napi_env env,napi_callback_info info)6 static napi_value Multiply(napi_env env, napi_callback_info info) {
7 size_t argc = 2;
8 napi_value args[2];
9 NODE_API_CALL(env, napi_get_cb_info(env, info, &argc, args, NULL, NULL));
10
11 NODE_API_ASSERT(env, argc == 2, "Wrong number of arguments");
12
13 napi_valuetype valuetype0;
14 NODE_API_CALL(env, napi_typeof(env, args[0], &valuetype0));
15
16 NODE_API_ASSERT(env, valuetype0 == napi_object,
17 "Wrong type of arguments. Expects a typed array as first argument.");
18
19 napi_value input_array = args[0];
20 bool is_typedarray;
21 NODE_API_CALL(env, napi_is_typedarray(env, input_array, &is_typedarray));
22
23 NODE_API_ASSERT(env, is_typedarray,
24 "Wrong type of arguments. Expects a typed array as first argument.");
25
26 napi_valuetype valuetype1;
27 NODE_API_CALL(env, napi_typeof(env, args[1], &valuetype1));
28
29 NODE_API_ASSERT(env, valuetype1 == napi_number,
30 "Wrong type of arguments. Expects a number as second argument.");
31
32 double multiplier;
33 NODE_API_CALL(env, napi_get_value_double(env, args[1], &multiplier));
34
35 napi_typedarray_type type;
36 napi_value input_buffer;
37 size_t byte_offset;
38 size_t i, length;
39 NODE_API_CALL(env, napi_get_typedarray_info(
40 env, input_array, &type, &length, NULL, &input_buffer, &byte_offset));
41
42 void* data;
43 size_t byte_length;
44 NODE_API_CALL(env, napi_get_arraybuffer_info(
45 env, input_buffer, &data, &byte_length));
46
47 napi_value output_buffer;
48 void* output_ptr = NULL;
49 NODE_API_CALL(env, napi_create_arraybuffer(
50 env, byte_length, &output_ptr, &output_buffer));
51
52 napi_value output_array;
53 NODE_API_CALL(env, napi_create_typedarray(
54 env, type, length, output_buffer, byte_offset, &output_array));
55
56 if (type == napi_uint8_array) {
57 uint8_t* input_bytes = (uint8_t*)(data) + byte_offset;
58 uint8_t* output_bytes = (uint8_t*)(output_ptr);
59 for (i = 0; i < length; i++) {
60 output_bytes[i] = (uint8_t)(input_bytes[i] * multiplier);
61 }
62 } else if (type == napi_float64_array) {
63 double* input_doubles = (double*)((uint8_t*)(data) + byte_offset);
64 double* output_doubles = (double*)(output_ptr);
65 for (i = 0; i < length; i++) {
66 output_doubles[i] = input_doubles[i] * multiplier;
67 }
68 } else {
69 napi_throw_error(env, NULL,
70 "Typed array was of a type not expected by test.");
71 return NULL;
72 }
73
74 return output_array;
75 }
76
FinalizeCallback(napi_env env,void * finalize_data,void * finalize_hint)77 static void FinalizeCallback(napi_env env,
78 void* finalize_data,
79 void* finalize_hint)
80 {
81 free(finalize_data);
82 }
83
External(napi_env env,napi_callback_info info)84 static napi_value External(napi_env env, napi_callback_info info) {
85 const uint8_t nElem = 3;
86 int8_t* externalData = malloc(nElem*sizeof(int8_t));
87 externalData[0] = 0;
88 externalData[1] = 1;
89 externalData[2] = 2;
90
91 napi_value output_buffer;
92 NODE_API_CALL(env, napi_create_external_arraybuffer(
93 env,
94 externalData,
95 nElem*sizeof(int8_t),
96 FinalizeCallback,
97 NULL, // finalize_hint
98 &output_buffer));
99
100 napi_value output_array;
101 NODE_API_CALL(env, napi_create_typedarray(env,
102 napi_int8_array,
103 nElem,
104 output_buffer,
105 0,
106 &output_array));
107
108 return output_array;
109 }
110
111
NullArrayBuffer(napi_env env,napi_callback_info info)112 static napi_value NullArrayBuffer(napi_env env, napi_callback_info info) {
113 static void* data = NULL;
114 napi_value arraybuffer;
115 NODE_API_CALL(env,
116 napi_create_external_arraybuffer(env, data, 0, NULL, NULL, &arraybuffer));
117 return arraybuffer;
118 }
119
CreateTypedArray(napi_env env,napi_callback_info info)120 static napi_value CreateTypedArray(napi_env env, napi_callback_info info) {
121 size_t argc = 4;
122 napi_value args[4];
123 NODE_API_CALL(env, napi_get_cb_info(env, info, &argc, args, NULL, NULL));
124
125 NODE_API_ASSERT(env, argc == 2 || argc == 4, "Wrong number of arguments");
126
127 napi_value input_array = args[0];
128 napi_valuetype valuetype0;
129 NODE_API_CALL(env, napi_typeof(env, input_array, &valuetype0));
130
131 NODE_API_ASSERT(env, valuetype0 == napi_object,
132 "Wrong type of arguments. Expects a typed array as first argument.");
133
134 bool is_typedarray;
135 NODE_API_CALL(env, napi_is_typedarray(env, input_array, &is_typedarray));
136
137 NODE_API_ASSERT(env, is_typedarray,
138 "Wrong type of arguments. Expects a typed array as first argument.");
139
140 napi_valuetype valuetype1;
141 napi_value input_buffer = args[1];
142 NODE_API_CALL(env, napi_typeof(env, input_buffer, &valuetype1));
143
144 NODE_API_ASSERT(env, valuetype1 == napi_object,
145 "Wrong type of arguments. Expects an array buffer as second argument.");
146
147 bool is_arraybuffer;
148 NODE_API_CALL(env, napi_is_arraybuffer(env, input_buffer, &is_arraybuffer));
149
150 NODE_API_ASSERT(env, is_arraybuffer,
151 "Wrong type of arguments. Expects an array buffer as second argument.");
152
153 napi_typedarray_type type;
154 napi_value in_array_buffer;
155 size_t byte_offset;
156 size_t length;
157 NODE_API_CALL(env, napi_get_typedarray_info(
158 env, input_array, &type, &length, NULL, &in_array_buffer, &byte_offset));
159
160 if (argc == 4) {
161 napi_valuetype valuetype2;
162 NODE_API_CALL(env, napi_typeof(env, args[2], &valuetype2));
163
164 NODE_API_ASSERT(env, valuetype2 == napi_number,
165 "Wrong type of arguments. Expects a number as third argument.");
166
167 uint32_t uint32_length;
168 NODE_API_CALL(env, napi_get_value_uint32(env, args[2], &uint32_length));
169 length = uint32_length;
170
171 napi_valuetype valuetype3;
172 NODE_API_CALL(env, napi_typeof(env, args[3], &valuetype3));
173
174 NODE_API_ASSERT(env, valuetype3 == napi_number,
175 "Wrong type of arguments. Expects a number as third argument.");
176
177 uint32_t uint32_byte_offset;
178 NODE_API_CALL(env, napi_get_value_uint32(env, args[3], &uint32_byte_offset));
179 byte_offset = uint32_byte_offset;
180 }
181
182 napi_value output_array;
183 NODE_API_CALL(env, napi_create_typedarray(
184 env, type, length, input_buffer, byte_offset, &output_array));
185
186 return output_array;
187 }
188
Detach(napi_env env,napi_callback_info info)189 static napi_value Detach(napi_env env, napi_callback_info info) {
190 size_t argc = 1;
191 napi_value args[1];
192 NODE_API_CALL(env, napi_get_cb_info(env, info, &argc, args, NULL, NULL));
193 NODE_API_ASSERT(env, argc == 1, "Wrong number of arguments.");
194
195 bool is_typedarray;
196 NODE_API_CALL(env, napi_is_typedarray(env, args[0], &is_typedarray));
197 NODE_API_ASSERT(
198 env, is_typedarray,
199 "Wrong type of arguments. Expects a typedarray as first argument.");
200
201 napi_value arraybuffer;
202 NODE_API_CALL(env,
203 napi_get_typedarray_info(
204 env, args[0], NULL, NULL, NULL, &arraybuffer, NULL));
205 NODE_API_CALL(env, napi_detach_arraybuffer(env, arraybuffer));
206
207 return NULL;
208 }
209
IsDetached(napi_env env,napi_callback_info info)210 static napi_value IsDetached(napi_env env, napi_callback_info info) {
211 size_t argc = 1;
212 napi_value args[1];
213 NODE_API_CALL(env, napi_get_cb_info(env, info, &argc, args, NULL, NULL));
214 NODE_API_ASSERT(env, argc == 1, "Wrong number of arguments.");
215
216 napi_value array_buffer = args[0];
217 bool is_arraybuffer;
218 NODE_API_CALL(env, napi_is_arraybuffer(env, array_buffer, &is_arraybuffer));
219 NODE_API_ASSERT(env, is_arraybuffer,
220 "Wrong type of arguments. Expects an array buffer as first argument.");
221
222 bool is_detached;
223 NODE_API_CALL(env,
224 napi_is_detached_arraybuffer(env, array_buffer, &is_detached));
225
226 napi_value result;
227 NODE_API_CALL(env, napi_get_boolean(env, is_detached, &result));
228
229 return result;
230 }
231
232 EXTERN_C_START
Init(napi_env env,napi_value exports)233 napi_value Init(napi_env env, napi_value exports) {
234 napi_property_descriptor descriptors[] = {
235 DECLARE_NODE_API_PROPERTY("Multiply", Multiply),
236 DECLARE_NODE_API_PROPERTY("External", External),
237 DECLARE_NODE_API_PROPERTY("NullArrayBuffer", NullArrayBuffer),
238 DECLARE_NODE_API_PROPERTY("CreateTypedArray", CreateTypedArray),
239 DECLARE_NODE_API_PROPERTY("Detach", Detach),
240 DECLARE_NODE_API_PROPERTY("IsDetached", IsDetached),
241 };
242
243 NODE_API_CALL(env, napi_define_properties(
244 env, exports, sizeof(descriptors) / sizeof(*descriptors), descriptors));
245
246 return exports;
247 }
248 EXTERN_C_END
249