authorgravatar for hello@nektro.netMeghan Denny <hello@nektro.net> 2023-10-12 23:57:00 -07:00
committergravatar for hello@nektro.netMeghan Denny <hello@nektro.net> 2023-10-12 23:57:00 -07:00
log19d5e8bfcc1a053184ca9647afbefb41cbc206cc
tree875ec2432f5eb131de96b2b31edf8048e8309eb3
parent8570068896254aa160278e6a552a0124e675f69d

AnyReader: add readAllAlloc


1 files changed, 36 insertions(+), 0 deletions(-)

src/lib.zig+36
......@@ -752,4 +752,40 @@ pub const AnyReader = struct {
752752 }
753753 return index;
754754 }
755
756 pub fn readAllAlloc(self: AnyReader, allocator: std.mem.Allocator, max_size: usize) ![]u8 {
757 var array_list = std.ArrayList(u8).init(allocator);
758 defer array_list.deinit();
759 try self.readAllArrayList(&array_list, max_size);
760 return try array_list.toOwnedSlice();
761 }
762
763 pub fn readAllArrayList(self: AnyReader, array_list: *std.ArrayList(u8), max_append_size: usize) !void {
764 return self.readAllArrayListAligned(null, array_list, max_append_size);
765 }
766
767 pub fn readAllArrayListAligned(self: AnyReader, comptime alignment: ?u29, array_list: *std.ArrayListAligned(u8, alignment), max_append_size: usize) !void {
768 try array_list.ensureTotalCapacity(@min(max_append_size, 4096));
769 const original_len = array_list.items.len;
770 var start_index: usize = original_len;
771 while (true) {
772 array_list.expandToCapacity();
773 const dest_slice = array_list.items[start_index..];
774 const bytes_read = try self.readAll(dest_slice);
775 start_index += bytes_read;
776
777 if (start_index - original_len > max_append_size) {
778 array_list.shrinkAndFree(original_len + max_append_size);
779 return error.StreamTooLong;
780 }
781
782 if (bytes_read != dest_slice.len) {
783 array_list.shrinkAndFree(start_index);
784 return;
785 }
786
787 // This will trigger ArrayList to expand superlinearly at whatever its growth rate is.
788 try array_list.ensureTotalCapacity(start_index + 1);
789 }
790 }
755791};