• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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