aboutsummaryrefslogtreecommitdiff
path: root/src/string_joiner.zig
diff options
context:
space:
mode:
authorGravatar Jarred Sumner <jarred@jarredsumner.com> 2022-03-13 06:08:10 -0700
committerGravatar Jarred Sumner <jarred@jarredsumner.com> 2022-03-13 06:08:10 -0700
commitf4504292cfd1e11bc6b4879a8b184aa6b842c8cb (patch)
tree2e0bb0f4596e739b37f76512dbc641f6102d8bcd /src/string_joiner.zig
parent6d71749c703d0061885230438ce5e46838700c59 (diff)
downloadbun-f4504292cfd1e11bc6b4879a8b184aa6b842c8cb.tar.gz
bun-f4504292cfd1e11bc6b4879a8b184aa6b842c8cb.tar.zst
bun-f4504292cfd1e11bc6b4879a8b184aa6b842c8cb.zip
[bun.js] Implement `Blob`
Diffstat (limited to 'src/string_joiner.zig')
-rw-r--r--src/string_joiner.zig37
1 files changed, 26 insertions, 11 deletions
diff --git a/src/string_joiner.zig b/src/string_joiner.zig
index d49c32867..03d63364e 100644
--- a/src/string_joiner.zig
+++ b/src/string_joiner.zig
@@ -21,27 +21,35 @@ const Joinable = struct {
last_byte: u8 = 0,
len: usize = 0,
+use_pool: bool = true,
+node_allocator: std.mem.Allocator = undefined,
head: ?*Joinable.Pool.Node = null,
tail: ?*Joinable.Pool.Node = null,
pub fn done(this: *Joiner, allocator: std.mem.Allocator) ![]u8 {
- var slice = try allocator.alloc(u8, this.cap);
+ if (this.head == null) {
+ var out: []u8 = &[_]u8{};
+ return out;
+ }
+
+ var slice = try allocator.alloc(u8, this.len);
var remaining = slice;
var el_ = this.head;
while (el_) |join| {
- const to_join = join.data.slice[join.offset..];
+ const to_join = join.data.slice[join.data.offset..];
@memcpy(remaining.ptr, to_join.ptr, to_join.len);
- remaining = remaining[to_join.len..];
+ remaining = remaining[@minimum(remaining.len, to_join.len)..];
var prev = join;
el_ = join.next;
if (prev.data.needs_deinit) {
- prev.data.allocator.free(join.data.slice);
+ prev.data.allocator.free(prev.data.slice);
prev.data = Joinable{};
}
- prev.release();
+
+ if (this.use_pool) prev.release();
}
return slice[0 .. slice.len - remaining.len];
@@ -60,12 +68,19 @@ pub fn append(this: *Joiner, slice: string, offset: u32, allocator: ?std.mem.All
const data = slice[offset..];
this.len += @truncate(u32, data.len);
- var new_tail = Joinable.Pool.get(default_allocator);
- new_tail.data = Joinable{
- .offset = offset,
- .allocator = allocator orelse undefined,
- .needs_deinit = allocator != null,
- .slice = slice,
+ var new_tail = if (this.use_pool)
+ Joinable.Pool.get(default_allocator)
+ else
+ (this.node_allocator.create(Joinable.Pool.Node) catch unreachable);
+
+ new_tail.* = .{
+ .allocator = default_allocator,
+ .data = Joinable{
+ .offset = @truncate(u31, offset),
+ .allocator = allocator orelse undefined,
+ .needs_deinit = allocator != null,
+ .slice = slice,
+ },
};
var tail = this.tail orelse {