wip group clone/new
This commit is contained in:
parent
3447fce9f7
commit
a655d8a88a
@ -203,10 +203,10 @@ pub fn testCorpus(allocator: Allocator) !Corpus {
|
||||
.shell = "/usr/sbin/nologin",
|
||||
} };
|
||||
|
||||
var members0 = &[_:null]?[:0]const u8{"root"};
|
||||
var members1 = &[_:null]?[:0]const u8{"vidmantas"};
|
||||
var members2 = &[_:null]?[:0]const u8{ "svc-bar", "vidmantas" };
|
||||
var members3 = &[_:null]?[:0]const u8{ "svc-bar", "Name" ** 8, "vidmantas", "root" };
|
||||
var members0 = &[_:null]?[*:0]const u8{"root"};
|
||||
var members1 = &[_:null]?[*:0]const u8{"vidmantas"};
|
||||
var members2 = &[_:null]?[*:0]const u8{ "svc-bar", "vidmantas" };
|
||||
var members3 = &[_:null]?[*:0]const u8{ "svc-bar", "Name" ** 8, "vidmantas", "root" };
|
||||
|
||||
const groups = [_]Group{
|
||||
Group{ .gid = 0, .name = "root", .members = members0 },
|
||||
|
@ -260,7 +260,7 @@ fn groupMemberNames(
|
||||
buf.len += name.len + 1;
|
||||
mem.copy(u8, buf[old_len..], name);
|
||||
buf[buf.len - 1] = 0;
|
||||
result[i] = buf[old_len..buf.len];
|
||||
result[i] = buf[old_len..buf.len :0];
|
||||
}
|
||||
return GroupMemberNames{ .arr = result };
|
||||
}
|
||||
@ -432,10 +432,10 @@ fn groupMembers(
|
||||
error.NotSorted => unreachable,
|
||||
};
|
||||
const total_members_len = blk: {
|
||||
var sum: u32 = 0;
|
||||
var sum: usize = 0;
|
||||
for (members) |user_idx|
|
||||
sum += @intCast(u32, corpus.users.get(user_idx).name.len);
|
||||
break :blk sum;
|
||||
sum += corpus.users.get(user_idx).name.len;
|
||||
break :blk @intCast(u32, sum);
|
||||
};
|
||||
try compress.appendUvarint(&blob, total_members_len);
|
||||
try compress.appendUvarint(&blob, members.len);
|
||||
|
@ -11,34 +11,57 @@ name: [:0]const u8,
|
||||
// https://github.com/ziglang/zig/issues/7517.
|
||||
// members[members.len] is always null for cloned groups. Once the bug
|
||||
// in the compiler is fixed, we should update the return type here.
|
||||
members: []const ?[:0]const u8,
|
||||
members: [:null]const ?[*:0]const u8,
|
||||
|
||||
pub fn clone(self: *const Group, allocator: Allocator) Allocator.Error!Group {
|
||||
var members = try allocator.alloc(?[:0]const u8, self.members.len + 1);
|
||||
errdefer allocator.free(members);
|
||||
members.len = self.members.len + 1;
|
||||
// storage of name + members
|
||||
_buf: []const u8,
|
||||
|
||||
for (self.members) |member, i| {
|
||||
members[i] = try allocator.dupeZ(u8, member.?);
|
||||
errdefer allocator.free(members[i]);
|
||||
pub fn new(
|
||||
allocator: Allocator,
|
||||
gid: u32,
|
||||
name: []const u8,
|
||||
members: []const []const u8,
|
||||
) error{OutOfMemory}!Group {
|
||||
const buf_len = blk: {
|
||||
var sum: usize = 0;
|
||||
for (members) |member| sum += member.len;
|
||||
break :blk @intCast(u32, sum);
|
||||
};
|
||||
_ = buf_len;
|
||||
_ = allocator;
|
||||
_ = gid;
|
||||
_ = name;
|
||||
_ = members;
|
||||
return error.OutOfMemory;
|
||||
}
|
||||
|
||||
pub fn clone(self: *const Group, allocator: Allocator) error{OutOfMemory}!Group {
|
||||
var members = try allocator.allocSentinel(?[*:0]const u8, self.members.len, null);
|
||||
errdefer allocator.free(members);
|
||||
|
||||
var buf = try allocator.alloc(u8, self._buf.len);
|
||||
errdefer allocator.free(buf);
|
||||
mem.copy(u8, buf, self._buf);
|
||||
|
||||
const our_begin = @ptrToInt(members.ptr);
|
||||
const their_begin = @ptrToInt(self.members.ptr);
|
||||
for (self.members) |*name_ptr, i| {
|
||||
const offset = @ptrToInt(name_ptr) - their_begin;
|
||||
members[i] = @intToPtr([*:0]const u8, our_begin + offset);
|
||||
}
|
||||
// workaround to include a null value at the end, even for
|
||||
// non-sentinel-terminated slice type.
|
||||
members[self.members.len] = null;
|
||||
members.len = self.members.len;
|
||||
|
||||
return Group{
|
||||
.gid = self.gid,
|
||||
.name = try allocator.dupeZ(u8, self.name),
|
||||
.members = members,
|
||||
.name = buf[0..self.name.len],
|
||||
.members = members[0.. :null],
|
||||
._buf = buf,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn deinit(self: *Group, allocator: Allocator) void {
|
||||
allocator.free(self.name);
|
||||
for (self.members) |member| {
|
||||
allocator.free(member.?);
|
||||
}
|
||||
if (self.members[0]) |firstmember|
|
||||
allocator.free(firstmember);
|
||||
allocator.free(self.members);
|
||||
self.* = undefined;
|
||||
}
|
||||
@ -47,13 +70,13 @@ const testing = std.testing;
|
||||
|
||||
test "Group.clone" {
|
||||
// TODO: how to do this on stack?
|
||||
var member1 = try testing.allocator.dupeZ(u8, "member1");
|
||||
var member1 = mem.sliceTo(try testing.allocator.dupeZ(u8, "member1"), 0);
|
||||
defer testing.allocator.free(member1);
|
||||
|
||||
var group = Group{
|
||||
.gid = 1,
|
||||
.name = "foo",
|
||||
.members = &[_:null]?[:0]const u8{ member1, "member2" },
|
||||
.members = &[_:null]?[*:0]const u8{ member1, "member2" },
|
||||
};
|
||||
|
||||
var cloned = try group.clone(testing.allocator);
|
||||
@ -64,5 +87,5 @@ test "Group.clone" {
|
||||
member1[0] = 'x';
|
||||
try testing.expectEqual(cloned.gid, 1);
|
||||
try testing.expectEqualSlices(u8, cloned.name, "foo");
|
||||
try testing.expectEqualSlices(u8, cloned.members[0].?, "member1");
|
||||
//try testing.expectEqualSlices(u8, @as([*:0]const u8, cloned.members[0].?), "member1");
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user