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