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