non-packed user iterator

This commit is contained in:
Motiejus Jakštys 2022-02-20 14:13:06 +02:00 committed by Motiejus Jakštys
parent f2434e3d3c
commit 91849c128f

View File

@ -111,17 +111,15 @@ pub const UserReader = struct {
const shellIndexProto = fn (u6) []const u8; const shellIndexProto = fn (u6) []const u8;
blob: []u8, blob: []u8,
shellIndex: shellIndexProto,
const PackedEntry = struct { pub const PackedEntry = struct {
packed_user: *PackedUser, packed_user: *PackedUser,
blob: []const u8, blob: []const u8,
}; };
pub fn init(blob: []u8, shellIndex: shellIndexProto) UserReader { pub fn init(blob: []u8) UserReader {
return UserReader{ return UserReader{
.blob = blob, .blob = blob,
.shellIndex = shellIndex,
}; };
} }
@ -132,18 +130,14 @@ pub const UserReader = struct {
pub fn next(it: *PackedIterator) ?PackedEntry { pub fn next(it: *PackedIterator) ?PackedEntry {
if (it.index == it.ur.blob.len) return null; if (it.index == it.ur.blob.len) return null;
assert(it.index < it.ur.blob.len); assert(it.index < it.ur.blob.len);
const endUser = it.index + PackedUserSize; const endUser = it.index + PackedUserSize;
var packedUser = std.mem.bytesAsValue( var packedUser = std.mem.bytesAsValue(
PackedUser, PackedUser,
it.ur.blob[it.index..endUser][0..PackedUserSize], it.ur.blob[it.index..endUser][0..PackedUserSize],
); );
const startBlob = endUser + 1; const startBlob = endUser + 1;
const endBlob = startBlob + packedUser.blobLength(); const endBlob = startBlob + packedUser.blobLength();
it.index = pad.roundUp(usize, PackedUserAlignmentBits, endBlob + 1); it.index = pad.roundUp(usize, PackedUserAlignmentBits, endBlob + 1);
return PackedEntry{ return PackedEntry{
.packed_user = packedUser, .packed_user = packedUser,
.blob = it.ur.blob[startBlob..endBlob], .blob = it.ur.blob[startBlob..endBlob],
@ -154,6 +148,53 @@ pub const UserReader = struct {
pub fn packedIterator(self: *UserReader) PackedIterator { pub fn packedIterator(self: *UserReader) PackedIterator {
return .{ .ur = self }; return .{ .ur = self };
} }
pub const Iterator = struct {
pit: *PackedIterator,
shellIndex: shellIndexProto,
pub fn next(it: *Iterator) ?User {
const entry = it.next() orelse return null;
const home = entry.blob[0..entry.packed_user.home_len];
var name: []const u8 = undefined;
var pos: usize = undefined;
//var name_start: usize = 0;
//var name_end: usize = 0;
if (entry.packed_user.name_is_a_suffix) {
const name_start = entry.packed_user.home_len - entry.packed_user.name_len;
name = entry.blob[name_start..entry.packed_user.home_len];
pos = entry.packed_user.home_len + 1;
} else {
const name_start = entry.packed_user.home_len + 1;
name = entry.blob[name_start .. name_start + entry.packed_user.name_len];
pos = name_start + entry.packed_user.name_len + 1;
}
var shell: []const u8 = undefined;
if (entry.packed_user.shell_here) {
shell = entry.blob[pos .. pos + entry.packed_user.shell_len_or_idx];
pos += entry.packed_user.shell_len_or_idx + 1;
} else {
shell = it.shellIndex(entry.packed_user.shell_len_or_idx);
}
return User{
.uid = entry.packed_user.uid,
.gid = entry.packed_user.gid,
.name = undefined,
.home = home,
};
}
};
pub fn iterator(self: *UserReader, shellIndex: shellIndexProto) Iterator {
return .{
.pit = self.packedIterator(),
.shellIndex = shellIndex,
};
}
}; };
const testing = std.testing; const testing = std.testing;
@ -206,7 +247,7 @@ test "construct PackedUser blob" {
try writer.appendUser(user); try writer.appendUser(user);
} }
var rd = UserReader.init(buf.items, testShell); var rd = UserReader.init(buf.items);
var it = rd.packedIterator(); var it = rd.packedIterator();
var i: u32 = 0; var i: u32 = 0;
while (it.next()) |entry| : (i += 1) { while (it.next()) |entry| : (i += 1) {