From 831af0ca3758a75afc338bd79d76977860607ce1 Mon Sep 17 00:00:00 2001 From: Karl Seguin Date: Mon, 28 Sep 2026 06:46:27 +0800 Subject: [PATCH] cleanup code, re-use new helper --- src/browser/js/String.zig | 52 ++++++--------------- src/browser/webapi/encoding/TextEncoder.zig | 8 ++-- 2 files changed, 17 insertions(+), 43 deletions(-) diff --git a/src/browser/js/String.zig b/src/browser/js/String.zig index ab8c00507..081fd29d8 100644 --- a/src/browser/js/String.zig +++ b/src/browser/js/String.zig @@ -59,13 +59,9 @@ pub fn toSliceWithAlloc(self: String, allocator: Allocator) ![]u8 { } fn _toSlice(self: String, comptime null_terminate: bool, allocator: Allocator) !(if (null_terminate) [:0]u8 else []u8) { - const local = self.local; - const handle = self.handle; - const isolate = local.isolate.handle; - - const l = v8.v8__String__Utf8Length(handle, isolate); - const buf = try (if (comptime null_terminate) allocator.allocSentinel(u8, @intCast(l), 0) else allocator.alloc(u8, @intCast(l))); - const n = v8.v8__String__WriteUtf8(handle, isolate, buf.ptr, buf.len, v8.WRITE_REPLACE_INVALID_UTF8, null); + const l = self.len(); + const buf = try (if (comptime null_terminate) allocator.allocSentinel(u8, l, 0) else allocator.alloc(u8, l)); + const n = self.writeUtf8(buf, null); if (comptime lp.IS_DEBUG) { std.debug.assert(n == l); } @@ -80,14 +76,11 @@ pub fn toSSO(self: String, comptime global: bool) !(if (global) lp.String.Global return self.toSSOWithAlloc(self.local.call_arena); } pub fn toSSOWithAlloc(self: String, allocator: Allocator) !lp.String { - const handle = self.handle; - const isolate = self.local.isolate.handle; - - const l: usize = @intCast(v8.v8__String__Utf8Length(handle, isolate)); + const l = self.len(); if (l <= 12) { var content: [12]u8 = undefined; - const n = v8.v8__String__WriteUtf8(handle, isolate, &content[0], content.len, v8.WRITE_REPLACE_INVALID_UTF8, null); + const n = self.writeUtf8(&content, null); if (comptime lp.IS_DEBUG) { std.debug.assert(n == l); } @@ -103,7 +96,7 @@ pub fn toSSOWithAlloc(self: String, allocator: Allocator) !lp.String { } const buf = try allocator.alloc(u8, l); - const n = v8.v8__String__WriteUtf8(handle, isolate, buf.ptr, buf.len, v8.WRITE_REPLACE_INVALID_UTF8, null); + const n = self.writeUtf8(buf, null); if (comptime lp.IS_DEBUG) { std.debug.assert(n == l); } @@ -116,15 +109,11 @@ pub fn toSSOWithAlloc(self: String, allocator: Allocator) !lp.String { } pub fn format(self: String, writer: *std.Io.Writer) !void { - const local = self.local; - const handle = self.handle; - const isolate = local.isolate.handle; - var small: [1024]u8 = undefined; - const l = v8.v8__String__Utf8Length(handle, isolate); - var buf = if (l < 1024) &small else local.call_arena.alloc(u8, @intCast(l)) catch return error.WriteFailed; + const l = self.len(); + const buf = if (l < 1024) &small else self.local.call_arena.alloc(u8, l) catch return error.WriteFailed; - const n = v8.v8__String__WriteUtf8(handle, isolate, buf.ptr, buf.len, v8.WRITE_REPLACE_INVALID_UTF8, null); + const n = self.writeUtf8(buf, null); return writer.writeAll(buf[0..n]); } @@ -154,22 +143,9 @@ pub fn toOneByteSlice(self: String, allocator: Allocator) ![]u8 { return buf; } -pub fn writeUtf8( - self: String, - dest: []u8, - flags: enum(c_uint) { - none = v8.WRITE_NONE, - null_terminate = v8.WRITE_NULL_TERMINATE, - replace_invalid_utf8 = v8.WRITE_REPLACE_INVALID_UTF8, - }, - processed_characters_len: ?*usize, -) usize { - return v8.v8__String__WriteUtf8( - self.handle, - self.local.isolate.handle, - dest.ptr, - dest.len, - @intFromEnum(flags), - processed_characters_len, - ); +// Encodes into `dest`, stopping before any code point that doesn't fit and +// replacing lone surrogates with U+FFFD. Returns the bytes written; +// `processed` receives the UTF-16 code units consumed. +pub fn writeUtf8(self: String, dest: []u8, processed: ?*usize) usize { + return v8.v8__String__WriteUtf8(self.handle, self.local.isolate.handle, dest.ptr, dest.len, v8.WRITE_REPLACE_INVALID_UTF8, processed); } diff --git a/src/browser/webapi/encoding/TextEncoder.zig b/src/browser/webapi/encoding/TextEncoder.zig index 812cec5e7..5a2e112f8 100644 --- a/src/browser/webapi/encoding/TextEncoder.zig +++ b/src/browser/webapi/encoding/TextEncoder.zig @@ -1,4 +1,4 @@ -// Copyright (C) 2023-2026 Lightpanda (Selecy SAS) +// Copyright (C) 2023-2026 Lightpanda (Selecy SAS) // // Francis Bouvier // Pierre Tachoire @@ -16,9 +16,7 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . -const std = @import("std"); const js = @import("../../js/js.zig"); -const v8 = js.v8; const TextEncoder = @This(); _pad: bool = false, @@ -42,7 +40,7 @@ pub fn encode(_: *const TextEncoder, v_: ?js.Value, exec: *const js.Execution) ! const array = local.createTypedArray(.uint8, source.len()); const slice = array.slice(); - _ = source.writeUtf8(slice, .replace_invalid_utf8, null); + _ = source.writeUtf8(slice, null); return .{ .local = local, .handle = array.handle }; } @@ -69,7 +67,7 @@ pub fn encodeInto(_: *const TextEncoder, source_: js.Value, destination_: js.Val // V8 encodes straight into the destination, never writing a partial // sequence, and replaces lone surrogates as the USVString conversion would. var read: usize = 0; - const written = source.writeUtf8(dest, .replace_invalid_utf8, &read); + const written = source.writeUtf8(dest, &read); return .{ .read = read, .written = written }; }