A poolable string builder (aka string buffer) for Zig
0

Configure Feed

Select the types of activity you want to include in your feed.

ability to reset while maintaining any allocated dynamic memory

Karl Seguin (Jun 24, 2023, 9:01 PM +0800) af01e2e0 f55f0d9e

+27 -9
+1 -1
src/pool.zig
··· 69 69 } 70 70 71 71 pub fn release(self: *Pool, sb: *StringBuilder) void { 72 - sb.reset(); 72 + sb.reset(true); 73 73 self.mutex.lock(); 74 74 75 75 var builders = self.builders;
+26 -8
src/string_builder.zig
··· 50 50 } 51 51 } 52 52 53 - pub fn reset(self: *StringBuilder) void { 53 + pub fn reset(self: *StringBuilder, clear_dynamic: bool) void { 54 54 self.pos = 0; 55 - if (self.dynamic) |dyn| { 56 - (self._da orelse self._a).free(dyn); 57 - self.dynamic = null; 58 - self.buf = self.static; 55 + if (clear_dynamic) { 56 + if (self.dynamic) |dyn| { 57 + (self._da orelse self._a).free(dyn); 58 + self.dynamic = null; 59 + self.buf = self.static; 60 + } 61 + self._da = null; 59 62 } 60 - self._da = null; 61 63 } 62 64 63 65 pub fn len(self: StringBuilder) usize { ··· 201 203 try t.expectEqual(492, sb.len()); 202 204 try t.expectString("over 9000!!!!If you were to run this code, you'd almost certainly see a segmentation fault (aka, segfault). We create a Response which involves creating an ArenaAllocator and from that, an Allocator. This allocator is then used to format our string. For the purpose of this example, we create a 2nd response and immediately free it. We need this for the same reason that warning1 in our first example printed an almost ok value: we want to re-initialize the memory in our init function stack.", sb.string()); 203 205 204 - sb.reset(); 206 + sb.reset(true); 205 207 } 206 208 } 207 209 ··· 227 229 try t.expectString("hello w", sb.string()); 228 230 } 229 231 232 + test "reset without clear" { 233 + var sb = try StringBuilder.init(t.allocator, 5); 234 + defer sb.deinit(); 235 + 236 + 237 + 238 + try sb.write("hello world!1"); 239 + try t.expectString("hello world!1", sb.string()); 240 + 241 + sb.reset(false); 242 + try t.expectEqual(0, sb.len()); 243 + try t.expectEqual(false, sb.dynamic == null); 244 + try sb.write("over 9000"); 245 + try sb.write("over 9000"); 246 + } 247 + 230 248 test "fuzz" { 231 249 var control = std.ArrayList(u8).init(t.allocator); 232 250 defer control.deinit(); ··· 249 267 try control.appendSlice(input); 250 268 try t.expectString(control.items, sb.string()); 251 269 } 252 - sb.reset(); 270 + sb.reset(true); 253 271 control.clearRetainingCapacity(); 254 272 _ = arena.reset(.free_all); 255 273 }