diff options
author | 2022-03-04 00:20:22 -0800 | |
---|---|---|
committer | 2022-03-04 00:20:22 -0800 | |
commit | 51fbbea1d3dc2b610fe5fe525229e56b581e5c8a (patch) | |
tree | c75e063c4eb7c99737fbf7a5a2014f9546e2e218 /src/string_mutable.zig | |
parent | 696710fd7aedee6054947aab002aaa853e9ee731 (diff) | |
download | bun-51fbbea1d3dc2b610fe5fe525229e56b581e5c8a.tar.gz bun-51fbbea1d3dc2b610fe5fe525229e56b581e5c8a.tar.zst bun-51fbbea1d3dc2b610fe5fe525229e56b581e5c8a.zip |
upgrade zigjarred/upgrade-zig-2
Diffstat (limited to 'src/string_mutable.zig')
-rw-r--r-- | src/string_mutable.zig | 70 |
1 files changed, 66 insertions, 4 deletions
diff --git a/src/string_mutable.zig b/src/string_mutable.zig index ad9765a26..e8a46af9b 100644 --- a/src/string_mutable.zig +++ b/src/string_mutable.zig @@ -39,13 +39,15 @@ pub const MutableString = struct { return bytes.len; } - pub fn writeAll(self: *MutableString, bytes: string) !usize { - try self.list.appendSlice(self.allocator, bytes); - return self.list.items.len; + pub fn bufferedWriter(self: *MutableString) BufferedWriter { + return BufferedWriter{ .context = self }; } pub fn init(allocator: std.mem.Allocator, capacity: usize) !MutableString { - return MutableString{ .allocator = allocator, .list = try std.ArrayListUnmanaged(u8).initCapacity(allocator, capacity) }; + return MutableString{ .allocator = allocator, .list = if (capacity > 0) + try std.ArrayListUnmanaged(u8).initCapacity(allocator, capacity) + else + std.ArrayListUnmanaged(u8){} }; } pub fn initCopy(allocator: std.mem.Allocator, str: anytype) !MutableString { @@ -223,6 +225,54 @@ pub const MutableString = struct { pub fn eql(self: *MutableString, other: anytype) bool { return std.mem.eql(u8, self.list.items, other); } + + pub const BufferedWriter = struct { + context: *MutableString, + buffer: [max]u8 = undefined, + pos: usize = 0, + + const max = 2048; + + pub const Writer = std.io.Writer(*BufferedWriter, anyerror, BufferedWriter.writeAll); + + inline fn remain(this: *BufferedWriter) []u8 { + return this.buffer[this.pos..]; + } + + pub fn flush(this: *BufferedWriter) !void { + _ = try this.context.writeAll(this.buffer[0..this.pos]); + this.pos = 0; + } + + pub fn writeAll(this: *BufferedWriter, bytes: []const u8) anyerror!usize { + var pending = bytes; + + if (pending.len >= max) { + try this.flush(); + try this.context.append(pending); + return pending.len; + } + + if (pending.len > 0) { + if (pending.len + this.pos > max) { + try this.flush(); + } + @memcpy(this.remain().ptr, pending.ptr, pending.len); + this.pos += pending.len; + } + + return pending.len; + } + + pub fn writer(this: *BufferedWriter) BufferedWriter.Writer { + return BufferedWriter.Writer{ .context = this }; + } + }; + + pub fn writeAll(self: *MutableString, bytes: string) !usize { + try self.list.appendSlice(self.allocator, bytes); + return bytes.len; + } }; test "MutableString" { @@ -238,3 +288,15 @@ test "MutableString.ensureValidIdentifier" { try std.testing.expectEqualStrings("jquery", try MutableString.ensureValidIdentifier("jquery", alloc)); try std.testing.expectEqualStrings("jquery_foo", try MutableString.ensureValidIdentifier("jquery😋foo", alloc)); } + +test "MutableString BufferedWriter" { + const alloc = std.heap.page_allocator; + + var str = try MutableString.init(alloc, 0); + var buffered_writer = str.bufferedWriter(); + var writer = buffered_writer.writer(); + try writer.writeAll("hello world hello world hello world hello world hello world hello world"); + try writer.context.flush(); + str = writer.context.context.*; + try std.testing.expectEqualStrings("hello world hello world hello world hello world hello world hello world", str.toOwnedSlice()); +} |