Skip to content

Commit c2ac6b0

Browse files
authored
fear: add TypedArray and Dataview (#28)
1 parent 84c245d commit c2ac6b0

11 files changed

Lines changed: 739 additions & 3 deletions

File tree

examples/basic/index.d.ts

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,3 +298,54 @@ export declare function get_arraybuffer(arraybuffer: ArrayBuffer): number;
298298
export declare function get_arraybuffer_as_string(
299299
arraybuffer: ArrayBuffer
300300
): string;
301+
302+
// ============== TypedArray Functions ==============
303+
304+
/**
305+
* Creates a Uint8Array with 4 bytes: [1, 2, 3, 4]
306+
* @returns The created typed array
307+
*/
308+
export declare function create_uint8_typedarray(): Uint8Array;
309+
310+
/**
311+
* Gets the length of a Uint8Array
312+
* @param array - The typed array
313+
* @returns The element count
314+
*/
315+
export declare function get_uint8_typedarray_length(array: Uint8Array): number;
316+
317+
/**
318+
* Sums all items in a Float32Array
319+
* @param array - The typed array
320+
* @returns The sum of all elements
321+
*/
322+
export declare function sum_float32_typedarray(array: Float32Array): number;
323+
324+
// ============== DataView Functions ==============
325+
326+
/**
327+
* Creates a DataView with 4 bytes initialized to 0x78, 0x56, 0x34, 0x12
328+
* @returns The created data view
329+
*/
330+
export declare function create_dataview(): DataView;
331+
332+
/**
333+
* Gets the byte length of a DataView
334+
* @param view - The data view
335+
* @returns The byte length
336+
*/
337+
export declare function get_dataview_length(view: DataView): number;
338+
339+
/**
340+
* Gets the first byte of a DataView
341+
* @param view - The data view
342+
* @returns The first byte, or 0 if empty
343+
*/
344+
export declare function get_dataview_first_byte(view: DataView): number;
345+
346+
/**
347+
* Reads the first 4 bytes of a DataView as a little-endian uint32
348+
* @param view - The data view
349+
* @returns The uint32 value
350+
*/
351+
export declare function get_dataview_uint32_le(view: DataView): number;

examples/basic/src/dataview.zig

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
const napi = @import("napi");
2+
3+
pub fn create_dataview(env: napi.Env) !napi.DataView {
4+
var view = try napi.DataView.New(env, 4);
5+
try view.setUint32(0, 0x12345678, true);
6+
return view;
7+
}
8+
9+
pub fn get_dataview_length(view: napi.DataView) usize {
10+
return view.byteLength();
11+
}
12+
13+
pub fn get_dataview_first_byte(view: napi.DataView) u8 {
14+
if (view.byteLength() == 0) {
15+
return 0;
16+
}
17+
return view.asConstSlice()[0];
18+
}
19+
20+
pub fn get_dataview_uint32_le(view: napi.DataView) !u32 {
21+
return try view.getUint32(0, true);
22+
}

examples/basic/src/hello.zig

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ const class = @import("class.zig");
1212
const log = @import("log/log.zig");
1313
const buffer = @import("buffer.zig");
1414
const arraybuffer = @import("arraybuffer.zig");
15+
const typedarray = @import("typedarray.zig");
16+
const dataview = @import("dataview.zig");
1517

1618
pub const test_i32 = number.test_i32;
1719
pub const test_f32 = number.test_f32;
@@ -56,6 +58,15 @@ pub const create_arraybuffer = arraybuffer.create_arraybuffer;
5658
pub const get_arraybuffer = arraybuffer.get_arraybuffer;
5759
pub const get_arraybuffer_as_string = arraybuffer.get_arraybuffer_as_string;
5860

61+
pub const create_uint8_typedarray = typedarray.create_uint8_typedarray;
62+
pub const get_uint8_typedarray_length = typedarray.get_uint8_typedarray_length;
63+
pub const sum_float32_typedarray = typedarray.sum_float32_typedarray;
64+
65+
pub const create_dataview = dataview.create_dataview;
66+
pub const get_dataview_length = dataview.get_dataview_length;
67+
pub const get_dataview_first_byte = dataview.get_dataview_first_byte;
68+
pub const get_dataview_uint32_le = dataview.get_dataview_uint32_le;
69+
5970
comptime {
6071
napi.NODE_API_MODULE("hello", @This());
6172
}

examples/basic/src/typedarray.zig

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
const napi = @import("napi");
2+
3+
pub fn create_uint8_typedarray(env: napi.Env) !napi.Uint8Array {
4+
return napi.Uint8Array.copy(env, &[_]u8{ 1, 2, 3, 4 });
5+
}
6+
7+
pub fn get_uint8_typedarray_length(array: napi.Uint8Array) usize {
8+
return array.length();
9+
}
10+
11+
pub fn sum_float32_typedarray(array: napi.Float32Array) f32 {
12+
var sum: f32 = 0;
13+
for (array.asConstSlice()) |item| {
14+
sum += item;
15+
}
16+
return sum;
17+
}

harmony_example/entry/src/main/cpp/types/libhello/Index.d.ts

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -274,4 +274,55 @@ export declare function get_buffer(buffer: ArrayBuffer): number;
274274
* @param buffer - The buffer
275275
* @returns The buffer as a string
276276
*/
277-
export declare function get_buffer_as_string(buffer: ArrayBuffer): string;
277+
export declare function get_buffer_as_string(buffer: ArrayBuffer): string;
278+
279+
// ============== TypedArray Functions ==============
280+
281+
/**
282+
* Creates a Uint8Array with 4 bytes: [1, 2, 3, 4]
283+
* @returns The created typed array
284+
*/
285+
export declare function create_uint8_typedarray(): Uint8Array;
286+
287+
/**
288+
* Gets the length of a Uint8Array
289+
* @param array - The typed array
290+
* @returns The element count
291+
*/
292+
export declare function get_uint8_typedarray_length(array: Uint8Array): number;
293+
294+
/**
295+
* Sums all items in a Float32Array
296+
* @param array - The typed array
297+
* @returns The sum of all elements
298+
*/
299+
export declare function sum_float32_typedarray(array: Float32Array): number;
300+
301+
// ============== DataView Functions ==============
302+
303+
/**
304+
* Creates a DataView with 4 bytes initialized to 0x78, 0x56, 0x34, 0x12
305+
* @returns The created data view
306+
*/
307+
export declare function create_dataview(): DataView;
308+
309+
/**
310+
* Gets the byte length of a DataView
311+
* @param view - The data view
312+
* @returns The byte length
313+
*/
314+
export declare function get_dataview_length(view: DataView): number;
315+
316+
/**
317+
* Gets the first byte of a DataView
318+
* @param view - The data view
319+
* @returns The first byte, or 0 if empty
320+
*/
321+
export declare function get_dataview_first_byte(view: DataView): number;
322+
323+
/**
324+
* Reads the first 4 bytes of a DataView as a little-endian uint32
325+
* @param view - The data view
326+
* @returns The uint32 value
327+
*/
328+
export declare function get_dataview_uint32_le(view: DataView): number;

src/napi.zig

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ const thread_safe_function = @import("./napi/wrapper/thread_safe_function.zig");
99
const class = @import("./napi/wrapper/class.zig");
1010
const buffer = @import("./napi/wrapper/buffer.zig");
1111
const arraybuffer = @import("./napi/wrapper/arraybuffer.zig");
12+
const typedarray = @import("./napi/wrapper/typedarray.zig");
13+
const dataview = @import("./napi/wrapper/dataview.zig");
1214

1315
pub const napi_sys = @import("napi-sys");
1416
pub const Env = env.Env;
@@ -36,6 +38,18 @@ pub const Class = class.Class;
3638
pub const ClassWithoutInit = class.ClassWithoutInit;
3739
pub const Buffer = buffer.Buffer;
3840
pub const ArrayBuffer = arraybuffer.ArrayBuffer;
41+
pub const TypedArray = typedarray.TypedArray;
42+
pub const Int8Array = typedarray.Int8Array;
43+
pub const Uint8Array = typedarray.Uint8Array;
44+
pub const Int16Array = typedarray.Int16Array;
45+
pub const Uint16Array = typedarray.Uint16Array;
46+
pub const Int32Array = typedarray.Int32Array;
47+
pub const Uint32Array = typedarray.Uint32Array;
48+
pub const Float32Array = typedarray.Float32Array;
49+
pub const Float64Array = typedarray.Float64Array;
50+
pub const BigInt64Array = typedarray.BigInt64Array;
51+
pub const BigUint64Array = typedarray.BigUint64Array;
52+
pub const DataView = dataview.DataView;
3953

4054
pub const NODE_API_MODULE = module.NODE_API_MODULE;
4155
pub const NODE_API_MODULE_WITH_INIT = module.NODE_API_MODULE_WITH_INIT;

src/napi/util/helper.zig

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,14 @@ pub fn isThreadSafeFunction(comptime T: type) bool {
8484
return false;
8585
}
8686

87+
pub fn isTypedArray(comptime T: type) bool {
88+
return @hasDecl(T, "is_napi_typedarray");
89+
}
90+
91+
pub fn isDataView(comptime T: type) bool {
92+
return @hasDecl(T, "is_napi_dataview");
93+
}
94+
8795
pub fn isArrayList(comptime T: type) bool {
8896
const info = @typeInfo(T);
8997
if (info != .@"struct") {

src/napi/util/napi.zig

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,13 @@ const ThreadSafeFunction = @import("../wrapper/thread_safe_function.zig").Thread
99
const class = @import("../wrapper/class.zig");
1010
const Buffer = @import("../wrapper/buffer.zig").Buffer;
1111
const ArrayBuffer = @import("../wrapper/arraybuffer.zig").ArrayBuffer;
12+
const DataView = @import("../wrapper/dataview.zig").DataView;
1213

1314
pub const Napi = struct {
1415
pub fn from_napi_value(env: napi.napi_env, raw: napi.napi_value, comptime T: type) T {
1516
const infos = @typeInfo(T);
1617
switch (T) {
17-
NapiValue.BigInt, NapiValue.Number, NapiValue.String, NapiValue.Object, NapiValue.Promise, NapiValue.Array, NapiValue.Undefined, NapiValue.Null, Buffer, ArrayBuffer => {
18+
NapiValue.BigInt, NapiValue.Number, NapiValue.String, NapiValue.Object, NapiValue.Promise, NapiValue.Array, NapiValue.Undefined, NapiValue.Null, Buffer, ArrayBuffer, DataView => {
1819
return T.from_raw(env, raw);
1920
},
2021
else => {
@@ -91,6 +92,12 @@ pub const Napi = struct {
9192
}
9293
return Function(args_type, return_type).from_raw(env, raw);
9394
}
95+
if (comptime helper.isTypedArray(T)) {
96+
return T.from_raw(env, raw);
97+
}
98+
if (comptime helper.isDataView(T)) {
99+
return T.from_raw(env, raw);
100+
}
94101

95102
if (comptime helper.isTuple(T)) {
96103
return NapiValue.Array.from_napi_value(env, raw, T);
@@ -136,7 +143,7 @@ pub const Napi = struct {
136143
const infos = @typeInfo(value_type);
137144

138145
switch (value_type) {
139-
NapiValue.BigInt, NapiValue.Bool, NapiValue.Number, NapiValue.String, NapiValue.Object, NapiValue.Promise, NapiValue.Array, NapiValue.Undefined, NapiValue.Null, Buffer, ArrayBuffer => {
146+
NapiValue.BigInt, NapiValue.Bool, NapiValue.Number, NapiValue.String, NapiValue.Object, NapiValue.Promise, NapiValue.Array, NapiValue.Undefined, NapiValue.Null, Buffer, ArrayBuffer, DataView => {
140147
return value.raw;
141148
},
142149
// If value is already a napi_value, return it directly
@@ -194,9 +201,15 @@ pub const Napi = struct {
194201
if (comptime helper.isNapiFunction(value_type)) {
195202
return value.raw;
196203
}
204+
if (comptime helper.isTypedArray(value_type)) {
205+
return value.raw;
206+
}
197207
if (comptime helper.isThreadSafeFunction(value_type)) {
198208
@compileError("ThreadSafeFunction is not supported for to_napi_value");
199209
}
210+
if (comptime helper.isDataView(value_type)) {
211+
return value.raw;
212+
}
200213
if (comptime helper.isTuple(value_type)) {
201214
const array = try NapiValue.Array.New(Env.from_raw(env), value);
202215
return array.raw;

0 commit comments

Comments
 (0)