diff options
Diffstat (limited to 'src/bun.js/node/buffer.zig')
-rw-r--r-- | src/bun.js/node/buffer.zig | 121 |
1 files changed, 64 insertions, 57 deletions
diff --git a/src/bun.js/node/buffer.zig b/src/bun.js/node/buffer.zig index 412c61722..541079a0b 100644 --- a/src/bun.js/node/buffer.zig +++ b/src/bun.js/node/buffer.zig @@ -17,78 +17,85 @@ pub const BufferVectorized = struct { extern fn memset_pattern16(b: *anyopaque, pattern16: *const anyopaque, len: usize) void; pub fn fill( - globalObject: *JSGlobalObject, - this: *JSC.ArrayBuffer, str: *JSC.ZigString, - start: u32, - end: u32, + buf_ptr: [*]u8, + fill_length: usize, encoding: JSC.Node.Encoding, ) callconv(.C) void { - const allocator = JSC.VirtualMachine.vm.allocator; - var stack_fallback = std.heap.stackFallback(512, allocator); - var stack_fallback_allocator = stack_fallback.get(); - var input_string = str.toSlice(stack_fallback_allocator); - if (input_string.len == 0) return; + if (str.len == 0) return; - defer input_string.deinit(); + var buf = buf_ptr[0..fill_length]; - var buf = this.slice()[start..end]; + const written = switch (encoding) { + JSC.Node.Encoding.utf8 => if (str.is16Bit()) + JSC.WebCore.Encoder.writeU16(str.utf16SliceAligned().ptr, str.utf16SliceAligned().len, buf.ptr, buf.len, JSC.Node.Encoding.utf8) + else + JSC.WebCore.Encoder.writeU8(str.slice().ptr, str.slice().len, buf.ptr, buf.len, JSC.Node.Encoding.utf8), + JSC.Node.Encoding.ascii => if (str.is16Bit()) + JSC.WebCore.Encoder.writeU16(str.utf16SliceAligned().ptr, str.utf16SliceAligned().len, buf.ptr, buf.len, JSC.Node.Encoding.ascii) + else + JSC.WebCore.Encoder.writeU8(str.slice().ptr, str.slice().len, buf.ptr, buf.len, JSC.Node.Encoding.ascii), + JSC.Node.Encoding.latin1 => if (str.is16Bit()) + JSC.WebCore.Encoder.writeU16(str.utf16SliceAligned().ptr, str.utf16SliceAligned().len, buf.ptr, buf.len, JSC.Node.Encoding.latin1) + else + JSC.WebCore.Encoder.writeU8(str.slice().ptr, str.slice().len, buf.ptr, buf.len, JSC.Node.Encoding.latin1), + JSC.Node.Encoding.buffer => if (str.is16Bit()) + JSC.WebCore.Encoder.writeU16(str.utf16SliceAligned().ptr, str.utf16SliceAligned().len, buf.ptr, buf.len, JSC.Node.Encoding.buffer) + else + JSC.WebCore.Encoder.writeU8(str.slice().ptr, str.slice().len, buf.ptr, buf.len, JSC.Node.Encoding.buffer), + JSC.Node.Encoding.utf16le, + JSC.Node.Encoding.ucs2, + => if (str.is16Bit()) + JSC.WebCore.Encoder.writeU16(str.utf16SliceAligned().ptr, str.utf16SliceAligned().len, buf.ptr, buf.len, JSC.Node.Encoding.utf16le) + else + JSC.WebCore.Encoder.writeU8(str.slice().ptr, str.slice().len, buf.ptr, buf.len, JSC.Node.Encoding.utf16le), + JSC.Node.Encoding.base64 => if (str.is16Bit()) + JSC.WebCore.Encoder.writeU16(str.utf16SliceAligned().ptr, str.utf16SliceAligned().len, buf.ptr, buf.len, JSC.Node.Encoding.base64) + else + JSC.WebCore.Encoder.writeU8(str.slice().ptr, str.slice().len, buf.ptr, buf.len, JSC.Node.Encoding.base64), + JSC.Node.Encoding.base64url => if (str.is16Bit()) + JSC.WebCore.Encoder.writeU16(str.utf16SliceAligned().ptr, str.utf16SliceAligned().len, buf.ptr, buf.len, JSC.Node.Encoding.base64url) + else + JSC.WebCore.Encoder.writeU8(str.slice().ptr, str.slice().len, buf.ptr, buf.len, JSC.Node.Encoding.base64url), + JSC.Node.Encoding.hex => if (str.is16Bit()) + JSC.WebCore.Encoder.writeU16(str.utf16SliceAligned().ptr, str.utf16SliceAligned().len, buf.ptr, buf.len, JSC.Node.Encoding.hex) + else + JSC.WebCore.Encoder.writeU8(str.slice().ptr, str.slice().len, buf.ptr, buf.len, JSC.Node.Encoding.hex), + }; - var slice = input_string.slice(); - switch (encoding) { - JSC.Node.Encoding.utf8, - JSC.Node.Encoding.ascii, - JSC.Node.Encoding.latin1, - JSC.Node.Encoding.buffer, - => { - switch (slice.len) { - 0 => unreachable, - 1 => { - @memset(buf.ptr, slice[0], 1); - return; - }, - 2...16 => { - if (comptime Environment.isMac) { - var pattern: [16]u8 = undefined; - var remain: []u8 = pattern[0..]; - - while (remain.len > 0) { - for (slice[0..]) |a| { - remain[0] = a; - remain = remain[1..]; - } - } - - memset_pattern16(buf.ptr, &pattern, buf.len); - return; - } - }, - else => {}, - } + if (written <= 0) { + return; + } - var in_there = @minimum(slice.len, buf.len); - @memcpy(buf.ptr, slice.ptr, in_there); - if (in_there < slice.len) { - return; - } + var contents = buf[0..@intCast(usize, written)]; + buf = buf[@intCast(usize, written)..]; - // var ptr = buf.ptr + @as(usize, start) + slice.len; + if (contents.len == 1) { + @memset(buf.ptr, contents[0], buf.len); + return; + } - // const fill_length = @as(usize, end) - @as(usize, start); + const minimum_contents = contents; + while (buf.len >= contents.len) { + const min_len = @minimum(contents.len, buf.len); + std.mem.copy(u8, buf[0..min_len], contents[0..min_len]); + if (buf.len <= contents.len) { + break; + } + buf = buf[min_len..]; + contents.len *= 2; + } - // // while (in_there < fill_length - in_there) { - // // std.mem.copy(ptr) - // // ptr += in_there; - // // in_there *= 2; - // // } - }, - else => {}, + while (buf.len > 0) { + const to_fill = @minimum(minimum_contents.len, buf.len); + std.mem.copy(u8, buf[0..to_fill], minimum_contents[0..to_fill]); + buf = buf[to_fill..]; } } }; comptime { if (!JSC.is_bindgen) { - @export(BufferVectorized, .{ .name = "Bun__Buffer__fill" }); + @export(BufferVectorized.fill, .{ .name = "Bun__Buffer_fill" }); } } |