diff options
| author | Andrew Kelley <superjoe30@gmail.com> | 2017-02-28 03:07:11 -0500 |
|---|---|---|
| committer | Andrew Kelley <superjoe30@gmail.com> | 2017-02-28 03:07:11 -0500 |
| commit | 9eb29e81f956080b358a79d3567204f656350620 (patch) | |
| tree | 112ce872d3e8150cb7e624d314385fc058c6f50d /std | |
| parent | 1195994880b6a83e61807381df2721ac5256e876 (diff) | |
| download | zig-9eb29e81f956080b358a79d3567204f656350620.tar.gz zig-9eb29e81f956080b358a79d3567204f656350620.zip | |
rename CBuf to Buffer0 and some minor std API changes
Diffstat (limited to 'std')
| -rw-r--r-- | std/cstr.zig | 107 | ||||
| -rw-r--r-- | std/debug.zig | 6 | ||||
| -rw-r--r-- | std/io.zig | 18 | ||||
| -rw-r--r-- | std/list.zig | 23 |
4 files changed, 98 insertions, 56 deletions
diff --git a/std/cstr.zig b/std/cstr.zig index cf1c020ccd..a34f3155c2 100644 --- a/std/cstr.zig +++ b/std/cstr.zig @@ -34,131 +34,142 @@ pub fn toSlice(str: &u8) -> []u8 { /// A buffer that allocates memory and maintains a null byte at the end. -pub const CBuf = struct { +pub const Buffer0 = struct { list: List(u8), /// Must deinitialize with deinit. - pub fn initEmpty(allocator: &Allocator) -> %CBuf { - var self = CBuf { - .list = List(u8).init(allocator), - }; - %return self.resize(0); - return self; + pub fn initEmpty(allocator: &Allocator) -> %Buffer0 { + return initSize(allocator, 0); } /// Must deinitialize with deinit. - pub fn initFromMem(allocator: &Allocator, m: []const u8) -> %CBuf { - var self = CBuf { - .list = List(u8).init(allocator), - }; - %return self.resize(m.len); + pub fn initFromMem(allocator: &Allocator, m: []const u8) -> %Buffer0 { + var self = %return initSize(allocator, m.len); mem.copy(u8, self.list.items, m); return self; } /// Must deinitialize with deinit. - pub fn initFromCStr(allocator: &Allocator, s: &const u8) -> %CBuf { - return CBuf.initFromMem(allocator, s[0...strlen(s)]); + pub fn initFromCStr(allocator: &Allocator, s: &const u8) -> %Buffer0 { + return Buffer0.initFromMem(allocator, s[0...strlen(s)]); } /// Must deinitialize with deinit. - pub fn initFromCBuf(cbuf: &const CBuf) -> %CBuf { - return CBuf.initFromMem(cbuf.list.allocator, cbuf.list.items[0...cbuf.len()]); + pub fn initFromOther(cbuf: &const Buffer0) -> %Buffer0 { + return Buffer0.initFromMem(cbuf.list.allocator, cbuf.list.items[0...cbuf.len()]); } /// Must deinitialize with deinit. - pub fn initFromSlice(other: &const CBuf, start: usize, end: usize) -> %CBuf { - return CBuf.initFromMem(other.list.allocator, other.list.items[start...end]); + pub fn initFromSlice(other: &const Buffer0, start: usize, end: usize) -> %Buffer0 { + return Buffer0.initFromMem(other.list.allocator, other.list.items[start...end]); + } + + /// Must deinitialize with deinit. + pub fn initSize(allocator: &Allocator, size: usize) -> %Buffer0 { + var self = Buffer0 { + .list = List(u8).init(allocator), + }; + %return self.resize(size); + return self; } - pub fn deinit(self: &CBuf) { + pub fn deinit(self: &Buffer0) { self.list.deinit(); } - pub fn resize(self: &CBuf, new_len: usize) -> %void { + pub fn toSlice(self: &Buffer0) -> []u8 { + return self.list.toSlice()[0...self.len()]; + } + + pub fn toSliceConst(self: &const Buffer0) -> []const u8 { + return self.list.toSliceConst()[0...self.len()]; + } + + pub fn resize(self: &Buffer0, new_len: usize) -> %void { %return self.list.resize(new_len + 1); self.list.items[self.len()] = 0; } - pub fn len(self: &const CBuf) -> usize { + pub fn len(self: &const Buffer0) -> usize { return self.list.len - 1; } - pub fn appendMem(self: &CBuf, m: []const u8) -> %void { + pub fn appendMem(self: &Buffer0, m: []const u8) -> %void { const old_len = self.len(); %return self.resize(old_len + m.len); - mem.copy(u8, self.list.items[old_len...], m); + mem.copy(u8, self.list.toSlice()[old_len...], m); } - pub fn appendCStr(self: &CBuf, s: &const u8) -> %void { + pub fn appendOther(self: &Buffer0, other: &const Buffer0) -> %void { + return self.appendMem(other.toSliceConst()); + } + + pub fn appendCStr(self: &Buffer0, s: &const u8) -> %void { self.appendMem(s[0...strlen(s)]) } - pub fn appendChar(self: &CBuf, c: u8) -> %void { + pub fn appendByte(self: &Buffer0, byte: u8) -> %void { %return self.resize(self.len() + 1); - self.list.items[self.len() - 1] = c; + self.list.items[self.len() - 1] = byte; } - pub fn eqlMem(self: &const CBuf, m: []const u8) -> bool { + pub fn eqlMem(self: &const Buffer0, m: []const u8) -> bool { if (self.len() != m.len) return false; return mem.cmp(u8, self.list.items[0...m.len], m) == mem.Cmp.Equal; } - pub fn eqlCStr(self: &const CBuf, s: &const u8) -> bool { + pub fn eqlCStr(self: &const Buffer0, s: &const u8) -> bool { self.eqlMem(s[0...strlen(s)]) } - pub fn eqlCBuf(self: &const CBuf, other: &const CBuf) -> bool { + pub fn eqlOther(self: &const Buffer0, other: &const Buffer0) -> bool { self.eqlMem(other.list.items[0...other.len()]) } - pub fn startsWithMem(self: &const CBuf, m: []const u8) -> bool { + pub fn startsWithMem(self: &const Buffer0, m: []const u8) -> bool { if (self.len() < m.len) return false; return mem.cmp(u8, self.list.items[0...m.len], m) == mem.Cmp.Equal; } - pub fn startsWithCBuf(self: &const CBuf, other: &const CBuf) -> bool { + pub fn startsWithOther(self: &const Buffer0, other: &const Buffer0) -> bool { self.startsWithMem(other.list.items[0...other.len()]) } - pub fn startsWithCStr(self: &const CBuf, s: &const u8) -> bool { + pub fn startsWithCStr(self: &const Buffer0, s: &const u8) -> bool { self.startsWithMem(s[0...strlen(s)]) } }; -fn testSimpleCBuf() { +fn testSimpleBuffer0() { @setFnTest(this); - var buf = %%CBuf.initEmpty(&debug.global_allocator); + var buf = %%Buffer0.initEmpty(&debug.global_allocator); assert(buf.len() == 0); %%buf.appendCStr(c"hello"); - %%buf.appendChar(' '); + %%buf.appendByte(' '); %%buf.appendMem("world"); assert(buf.eqlCStr(c"hello world")); assert(buf.eqlMem("hello world")); + assert(mem.eql(u8, buf.toSliceConst(), "hello world")); - var buf2 = %%CBuf.initFromCBuf(&buf); - assert(buf.eqlCBuf(&buf2)); + var buf2 = %%Buffer0.initFromOther(&buf); + assert(buf.eqlOther(&buf2)); assert(buf.startsWithMem("hell")); assert(buf.startsWithCStr(c"hell")); %%buf2.resize(4); - assert(buf.startsWithCBuf(&buf2)); + assert(buf.startsWithOther(&buf2)); } -// TODO do this without globals - -fn testCompileTimeStrCmp() { +fn testCStrFns() { @setFnTest(this); - assert(test_compile_time_str_cmp_result); + comptime testCStrFnsImpl(); + testCStrFnsImpl(); } -const test_compile_time_str_cmp_result = (cmp(c"aoeu", c"aoez") == -1); - -fn testCompileTimeStrLen() { - @setFnTest(this); - assert(test_comptime_str_len_result); +fn testCStrFnsImpl() { + assert(cmp(c"aoeu", c"aoez") == -1); + assert(len(c"123456789") == 9); } -const test_comptime_str_len_result = (len(c"123456789") == 9); diff --git a/std/debug.zig b/std/debug.zig index 2d30f2b540..d03f22b4c9 100644 --- a/std/debug.zig +++ b/std/debug.zig @@ -164,7 +164,7 @@ const Die = struct { }; fn getAttr(self: &const Die, id: u64) -> ?&const FormValue { - for (self.attrs.toSlice()) |*attr| { + for (self.attrs.toSliceConst()) |*attr| { if (attr.id == id) return &attr.value; } @@ -362,7 +362,7 @@ fn getAbbrevTable(st: &ElfStackTrace, abbrev_offset: u64) -> %&const AbbrevTable } fn getAbbrevTableEntry(abbrev_table: &const AbbrevTable, abbrev_code: u64) -> ?&const AbbrevTableEntry { - for (abbrev_table.toSlice()) |*table_entry| { + for (abbrev_table.toSliceConst()) |*table_entry| { if (table_entry.abbrev_code == abbrev_code) return table_entry; } @@ -379,7 +379,7 @@ fn parseDie(in_stream: &io.InStream, abbrev_table: &const AbbrevTable, is_64: bo .attrs = List(Die.Attr).init(&global_allocator), }; %return result.attrs.resize(table_entry.attrs.len); - for (table_entry.attrs.toSlice()) |attr, i| { + for (table_entry.attrs.toSliceConst()) |attr, i| { result.attrs.items[i] = Die.Attr { .id = attr.attr_id, .value = %return parseFormValue(in_stream, attr.form_id, is_64), diff --git a/std/io.zig b/std/io.zig index 73736f0adb..6f3b63f387 100644 --- a/std/io.zig +++ b/std/io.zig @@ -10,6 +10,7 @@ const debug = @import("debug.zig"); const assert = debug.assert; const os = @import("os.zig"); const mem = @import("mem.zig"); +const Buffer0 = @import("cstr.zig").Buffer0; pub const stdin_fileno = 0; pub const stdout_fileno = 1; @@ -486,6 +487,23 @@ pub const InStream = struct { return usize(stat.size); } + + pub fn readAll(is: &InStream, buf: &Buffer0) -> %void { + %return buf.resize(buffer_size); + + var actual_buf_len: usize = 0; + while (true) { + const dest_slice = buf.toSlice()[actual_buf_len...]; + const bytes_read = %return is.read(dest_slice); + actual_buf_len += bytes_read; + + if (bytes_read != dest_slice.len) { + return buf.resize(actual_buf_len); + } + + %return buf.resize(actual_buf_len + buffer_size); + } + } }; pub fn parseUnsigned(comptime T: type, buf: []const u8, radix: u8) -> %T { diff --git a/std/list.zig b/std/list.zig index c79505ef50..7758bd596b 100644 --- a/std/list.zig +++ b/std/list.zig @@ -7,6 +7,9 @@ pub fn List(comptime T: type) -> type{ struct { const Self = this; + /// Use toSlice instead of slicing this directly, because if you don't + /// specify the end position of the slice, this will potentially give + /// you uninitialized memory. items: []T, len: usize, allocator: &Allocator, @@ -23,15 +26,17 @@ pub fn List(comptime T: type) -> type{ l.allocator.free(l.items); } - pub fn toSlice(l: &const Self) -> []const T { + pub fn toSlice(l: &Self) -> []T { + return l.items[0...l.len]; + } + + pub fn toSliceConst(l: &const Self) -> []const T { return l.items[0...l.len]; } pub fn append(l: &Self, item: T) -> %void { - const new_length = l.len + 1; - %return l.ensureCapacity(new_length); - l.items[l.len] = item; - l.len = new_length; + const new_item_ptr = %return l.addOne(); + *new_item_ptr = item; } pub fn resize(l: &Self, new_len: usize) -> %void { @@ -48,6 +53,14 @@ pub fn List(comptime T: type) -> type{ } l.items = %return l.allocator.realloc(T, l.items, better_capacity); } + + pub fn addOne(l: &Self) -> %&T { + const new_length = l.len + 1; + %return l.ensureCapacity(new_length); + const result = &l.items[l.len]; + l.len = new_length; + return result; + } } } |
