diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2020-04-01 13:44:19 -0400 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2020-04-01 13:44:19 -0400 |
| commit | c2e8788259efd33995e151ace355cb5896cc8a85 (patch) | |
| tree | 7962a47dd9df3976a7aa8c8c5ad754d27dd55ba4 /lib/std/buffer.zig | |
| parent | e8a1e2a1d8f2903d5951339f7d3e0dbdfc85704c (diff) | |
| parent | 2e806682f451efd26bef0486ddd980ab60de0fa1 (diff) | |
| download | zig-c2e8788259efd33995e151ace355cb5896cc8a85.tar.gz zig-c2e8788259efd33995e151ace355cb5896cc8a85.zip | |
Merge branch 'daurnimator-less-buffer'
closes #4665
Diffstat (limited to 'lib/std/buffer.zig')
| -rw-r--r-- | lib/std/buffer.zig | 218 |
1 files changed, 0 insertions, 218 deletions
diff --git a/lib/std/buffer.zig b/lib/std/buffer.zig deleted file mode 100644 index 7971820770..0000000000 --- a/lib/std/buffer.zig +++ /dev/null @@ -1,218 +0,0 @@ -const std = @import("std.zig"); -const debug = std.debug; -const mem = std.mem; -const Allocator = mem.Allocator; -const assert = debug.assert; -const testing = std.testing; -const ArrayList = std.ArrayList; - -/// A buffer that allocates memory and maintains a null byte at the end. -pub const Buffer = struct { - list: ArrayList(u8), - - /// Must deinitialize with deinit. - pub fn init(allocator: *Allocator, m: []const u8) !Buffer { - var self = try initSize(allocator, m.len); - mem.copy(u8, self.list.items, m); - return self; - } - - /// Initialize memory to size bytes of undefined values. - /// Must deinitialize with deinit. - pub fn initSize(allocator: *Allocator, size: usize) !Buffer { - var self = initNull(allocator); - try self.resize(size); - return self; - } - - /// Initialize with capacity to hold at least num bytes. - /// Must deinitialize with deinit. - pub fn initCapacity(allocator: *Allocator, num: usize) !Buffer { - var self = Buffer{ .list = try ArrayList(u8).initCapacity(allocator, num + 1) }; - self.list.appendAssumeCapacity(0); - return self; - } - - /// Must deinitialize with deinit. - /// None of the other operations are valid until you do one of these: - /// * ::replaceContents - /// * ::resize - pub fn initNull(allocator: *Allocator) Buffer { - return Buffer{ .list = ArrayList(u8).init(allocator) }; - } - - /// Must deinitialize with deinit. - pub fn initFromBuffer(buffer: Buffer) !Buffer { - return Buffer.init(buffer.list.allocator, buffer.span()); - } - - /// Buffer takes ownership of the passed in slice. The slice must have been - /// allocated with `allocator`. - /// Must deinitialize with deinit. - pub fn fromOwnedSlice(allocator: *Allocator, slice: []u8) !Buffer { - var self = Buffer{ .list = ArrayList(u8).fromOwnedSlice(allocator, slice) }; - try self.list.append(0); - return self; - } - - /// The caller owns the returned memory. The Buffer becomes null and - /// is safe to `deinit`. - pub fn toOwnedSlice(self: *Buffer) [:0]u8 { - const allocator = self.list.allocator; - const result = self.list.toOwnedSlice(); - self.* = initNull(allocator); - return result[0 .. result.len - 1 :0]; - } - - pub fn allocPrint(allocator: *Allocator, comptime format: []const u8, args: var) !Buffer { - const size = std.math.cast(usize, std.fmt.count(format, args)) catch |err| switch (err) { - error.Overflow => return error.OutOfMemory, - }; - var self = try Buffer.initSize(allocator, size); - assert((std.fmt.bufPrint(self.list.items, format, args) catch unreachable).len == size); - return self; - } - - pub fn deinit(self: *Buffer) void { - self.list.deinit(); - } - - pub fn span(self: var) @TypeOf(self.list.items[0 .. self.list.len - 1 :0]) { - return self.list.span()[0..self.len() :0]; - } - - pub const toSlice = @compileError("deprecated; use span()"); - pub const toSliceConst = @compileError("deprecated; use span()"); - - pub fn shrink(self: *Buffer, new_len: usize) void { - assert(new_len <= self.len()); - self.list.shrink(new_len + 1); - self.list.items[self.len()] = 0; - } - - pub fn resize(self: *Buffer, new_len: usize) !void { - try self.list.resize(new_len + 1); - self.list.items[self.len()] = 0; - } - - pub fn isNull(self: Buffer) bool { - return self.list.len == 0; - } - - pub fn len(self: Buffer) usize { - return self.list.len - 1; - } - - pub fn capacity(self: Buffer) usize { - return if (self.list.items.len > 0) - self.list.items.len - 1 - else - 0; - } - - pub fn append(self: *Buffer, m: []const u8) !void { - const old_len = self.len(); - try self.resize(old_len + m.len); - mem.copy(u8, self.list.span()[old_len..], m); - } - - pub fn appendByte(self: *Buffer, byte: u8) !void { - const old_len = self.len(); - try self.resize(old_len + 1); - self.list.span()[old_len] = byte; - } - - pub fn eql(self: Buffer, m: []const u8) bool { - return mem.eql(u8, self.span(), m); - } - - pub fn startsWith(self: Buffer, m: []const u8) bool { - if (self.len() < m.len) return false; - return mem.eql(u8, self.list.items[0..m.len], m); - } - - pub fn endsWith(self: Buffer, m: []const u8) bool { - const l = self.len(); - if (l < m.len) return false; - const start = l - m.len; - return mem.eql(u8, self.list.items[start..l], m); - } - - pub fn replaceContents(self: *Buffer, m: []const u8) !void { - try self.resize(m.len); - mem.copy(u8, self.list.span(), m); - } - - pub fn outStream(self: *Buffer) std.io.OutStream(*Buffer, error{OutOfMemory}, appendWrite) { - return .{ .context = self }; - } - - /// Same as `append` except it returns the number of bytes written, which is always the same - /// as `m.len`. The purpose of this function existing is to match `std.io.OutStream` API. - pub fn appendWrite(self: *Buffer, m: []const u8) !usize { - try self.append(m); - return m.len; - } -}; - -test "simple Buffer" { - var buf = try Buffer.init(testing.allocator, ""); - defer buf.deinit(); - - testing.expect(buf.len() == 0); - try buf.append("hello"); - try buf.append(" "); - try buf.append("world"); - testing.expect(buf.eql("hello world")); - testing.expect(mem.eql(u8, mem.spanZ(buf.span().ptr), buf.span())); - - var buf2 = try Buffer.initFromBuffer(buf); - defer buf2.deinit(); - testing.expect(buf.eql(buf2.span())); - - testing.expect(buf.startsWith("hell")); - testing.expect(buf.endsWith("orld")); - - try buf2.resize(4); - testing.expect(buf.startsWith(buf2.span())); -} - -test "Buffer.initSize" { - var buf = try Buffer.initSize(testing.allocator, 3); - defer buf.deinit(); - testing.expect(buf.len() == 3); - try buf.append("hello"); - testing.expect(mem.eql(u8, buf.span()[3..], "hello")); -} - -test "Buffer.initCapacity" { - var buf = try Buffer.initCapacity(testing.allocator, 10); - defer buf.deinit(); - testing.expect(buf.len() == 0); - testing.expect(buf.capacity() >= 10); - const old_cap = buf.capacity(); - try buf.append("hello"); - testing.expect(buf.len() == 5); - testing.expect(buf.capacity() == old_cap); - testing.expect(mem.eql(u8, buf.span(), "hello")); -} - -test "Buffer.print" { - var buf = try Buffer.init(testing.allocator, ""); - defer buf.deinit(); - - try buf.outStream().print("Hello {} the {}", .{ 2, "world" }); - testing.expect(buf.eql("Hello 2 the world")); -} - -test "Buffer.outStream" { - var buffer = try Buffer.initSize(testing.allocator, 0); - defer buffer.deinit(); - const buf_stream = buffer.outStream(); - - const x: i32 = 42; - const y: i32 = 1234; - try buf_stream.print("x: {}\ny: {}\n", .{ x, y }); - - testing.expect(mem.eql(u8, buffer.span(), "x: 42\ny: 1234\n")); -} |
