constructing header
This commit is contained in:
parent
bb3577f7b3
commit
f4012c8694
|
@ -95,11 +95,11 @@ const Corpus = struct {
|
|||
defer baseAllocator.free(user2groups);
|
||||
mem.set(ArrayListUnmanaged(u32), user2groups, ArrayListUnmanaged(u32){});
|
||||
|
||||
for (groups.items(.members)) |group_members, i| {
|
||||
var members = try allocator.alloc(u32, group_members.count());
|
||||
for (groups.items(.members)) |groupmembers, i| {
|
||||
var members = try allocator.alloc(u32, groupmembers.count());
|
||||
members.len = 0;
|
||||
|
||||
var it = group_members.iterator();
|
||||
var it = groupmembers.iterator();
|
||||
while (it.next()) |memberName| {
|
||||
if (name2user.get(memberName.*)) |user_idx| {
|
||||
members.len += 1;
|
||||
|
@ -148,7 +148,7 @@ pub fn shellSections(
|
|||
return popcon.toOwnedSections(max_shells);
|
||||
}
|
||||
|
||||
pub const UserGids = struct {
|
||||
pub const AdditionalGids = struct {
|
||||
// user index -> offset in blob
|
||||
idx2offset: []const u64,
|
||||
// compressed user gids blob. A blob contains N <= users.len items,
|
||||
|
@ -158,7 +158,7 @@ pub const UserGids = struct {
|
|||
// ... and the gid list is delta-compressed.
|
||||
blob: []const u8,
|
||||
|
||||
pub fn deinit(self: *UserGids, allocator: Allocator) void {
|
||||
pub fn deinit(self: *AdditionalGids, allocator: Allocator) void {
|
||||
allocator.free(self.idx2offset);
|
||||
allocator.free(self.blob);
|
||||
self.* = undefined;
|
||||
|
@ -168,7 +168,7 @@ pub const UserGids = struct {
|
|||
pub fn userGids(
|
||||
allocator: Allocator,
|
||||
corpus: *const Corpus,
|
||||
) error{ OutOfMemory, Overflow }!UserGids {
|
||||
) error{ OutOfMemory, Overflow }!AdditionalGids {
|
||||
var blob = ArrayList(u8).init(allocator);
|
||||
errdefer blob.deinit();
|
||||
var idx2offset = try allocator.alloc(u64, corpus.users.len);
|
||||
|
@ -198,13 +198,15 @@ pub fn userGids(
|
|||
try compress.appendUvarint(&blob, gid);
|
||||
}
|
||||
|
||||
return UserGids{
|
||||
return AdditionalGids{
|
||||
.idx2offset = idx2offset,
|
||||
.blob = blob.toOwnedSlice(),
|
||||
};
|
||||
}
|
||||
|
||||
pub const UsersSection = struct {
|
||||
// number of users in this section
|
||||
len: u32,
|
||||
// user index -> offset in blob
|
||||
idx2offset: []const u32,
|
||||
blob: []const u8,
|
||||
|
@ -219,7 +221,7 @@ pub const UsersSection = struct {
|
|||
pub fn usersSection(
|
||||
allocator: Allocator,
|
||||
corpus: *const Corpus,
|
||||
gids: *const UserGids,
|
||||
gids: *const AdditionalGids,
|
||||
shells: *const ShellSections,
|
||||
) error{ OutOfMemory, Overflow, InvalidRecord }!UsersSection {
|
||||
var idx2offset = try allocator.alloc(u32, corpus.users.len);
|
||||
|
@ -244,6 +246,7 @@ pub fn usersSection(
|
|||
try pad.arrayList(&blob, PackedUser.alignment_bits);
|
||||
}
|
||||
return UsersSection{
|
||||
.len = @intCast(u32, corpus.users.len),
|
||||
.idx2offset = idx2offset,
|
||||
.blob = blob.toOwnedSlice(),
|
||||
};
|
||||
|
@ -303,6 +306,8 @@ pub fn groupMembers(
|
|||
}
|
||||
|
||||
pub const GroupsSection = struct {
|
||||
// number of groups in this section
|
||||
len: u32,
|
||||
// group index -> offset in blob
|
||||
idx2offset: []const u32,
|
||||
blob: []const u8,
|
||||
|
@ -342,6 +347,7 @@ pub fn groupsSection(
|
|||
}
|
||||
|
||||
return GroupsSection{
|
||||
.len = @intCast(u32, corpus.groups.len),
|
||||
.idx2offset = idx2offset,
|
||||
.blob = blob.toOwnedSlice(),
|
||||
};
|
||||
|
@ -416,8 +422,8 @@ pub const AllSections = struct {
|
|||
users: UsersSection,
|
||||
shell_sections: ShellSections,
|
||||
shell_reader: ShellReader,
|
||||
user_gids: UserGids,
|
||||
group_members: GroupMembers,
|
||||
additional_gids: AdditionalGids,
|
||||
groupmembers: GroupMembers,
|
||||
groups: GroupsSection,
|
||||
idx_gid2group: []const u32,
|
||||
idx_groupname2group: []const u32,
|
||||
|
@ -449,16 +455,16 @@ pub const AllSections = struct {
|
|||
var shell_sections = try shellSections(allocator, corpus);
|
||||
errdefer shell_sections.deinit();
|
||||
|
||||
var user_gids = try userGids(allocator, corpus);
|
||||
errdefer user_gids.deinit(allocator);
|
||||
var additional_gids = try userGids(allocator, corpus);
|
||||
errdefer additional_gids.deinit(allocator);
|
||||
|
||||
var users = try usersSection(allocator, corpus, &user_gids, &shell_sections);
|
||||
var users = try usersSection(allocator, corpus, &additional_gids, &shell_sections);
|
||||
errdefer users.deinit(allocator);
|
||||
|
||||
var group_members = try groupMembers(allocator, corpus, users.idx2offset);
|
||||
errdefer group_members.deinit(allocator);
|
||||
var groupmembers = try groupMembers(allocator, corpus, users.idx2offset);
|
||||
errdefer groupmembers.deinit(allocator);
|
||||
|
||||
var groups = try groupsSection(allocator, corpus, group_members.idx2offset);
|
||||
var groups = try groupsSection(allocator, corpus, groupmembers.idx2offset);
|
||||
errdefer groups.deinit(allocator);
|
||||
|
||||
var idx_gid2group = try bdzIdx(u32, allocator, bdz_gid, gids, groups.idx2offset);
|
||||
|
@ -474,18 +480,18 @@ pub const AllSections = struct {
|
|||
errdefer allocator.free(idx_name2user);
|
||||
|
||||
const header = Header{
|
||||
.nblocks_shell_blob = undefined,
|
||||
.num_shells = undefined,
|
||||
.num_groups = undefined,
|
||||
.num_users = undefined,
|
||||
.nblocks_bdz_gid = undefined,
|
||||
.nblocks_bdz_groupname = undefined,
|
||||
.nblocks_bdz_uid = undefined,
|
||||
.nblocks_bdz_username = undefined,
|
||||
.nblocks_groups = undefined,
|
||||
.nblocks_users = undefined,
|
||||
.nblocks_groupmembers = undefined,
|
||||
.nblocks_additional_gids = undefined,
|
||||
.nblocks_shell_blob = nblocks(u8, shell_sections.blob.constSlice()),
|
||||
.num_shells = shell_sections.len,
|
||||
.num_groups = groups.len,
|
||||
.num_users = users.len,
|
||||
.nblocks_bdz_gid = nblocks(u32, bdz_gid),
|
||||
.nblocks_bdz_groupname = nblocks(u32, bdz_groupname),
|
||||
.nblocks_bdz_uid = nblocks(u32, bdz_uid),
|
||||
.nblocks_bdz_username = nblocks(u32, bdz_username),
|
||||
.nblocks_groups = nblocks(u64, groups.blob),
|
||||
.nblocks_users = nblocks(u64, users.blob),
|
||||
.nblocks_groupmembers = nblocks(u64, groupmembers.blob),
|
||||
.nblocks_additional_gids = nblocks(u64, additional_gids.blob),
|
||||
};
|
||||
|
||||
return AllSections{
|
||||
|
@ -499,9 +505,9 @@ pub const AllSections = struct {
|
|||
mem.sliceAsBytes(shell_sections.index.constSlice()),
|
||||
mem.sliceAsBytes(shell_sections.blob.constSlice()),
|
||||
),
|
||||
.user_gids = user_gids,
|
||||
.additional_gids = additional_gids,
|
||||
.users = users,
|
||||
.group_members = group_members,
|
||||
.groupmembers = groupmembers,
|
||||
.groups = groups,
|
||||
.idx_gid2group = idx_gid2group,
|
||||
.idx_groupname2group = idx_groupname2group,
|
||||
|
@ -517,9 +523,9 @@ pub const AllSections = struct {
|
|||
self.allocator.free(self.bdz_uid);
|
||||
self.allocator.free(self.bdz_username);
|
||||
self.shell_sections.deinit();
|
||||
self.user_gids.deinit(self.allocator);
|
||||
self.additional_gids.deinit(self.allocator);
|
||||
self.users.deinit(self.allocator);
|
||||
self.group_members.deinit(self.allocator);
|
||||
self.groupmembers.deinit(self.allocator);
|
||||
self.groups.deinit(self.allocator);
|
||||
self.allocator.free(self.idx_gid2group);
|
||||
self.allocator.free(self.idx_groupname2group);
|
||||
|
@ -657,10 +663,10 @@ test "test groups, group members and users" {
|
|||
var sections = try AllSections.init(allocator, &corpus);
|
||||
defer sections.deinit();
|
||||
|
||||
const blob = sections.group_members.blob;
|
||||
const blob = sections.groupmembers.blob;
|
||||
var i: usize = 0;
|
||||
while (i < corpus.groups.len) : (i += 1) {
|
||||
const offset = sections.group_members.idx2offset[i];
|
||||
const offset = sections.groupmembers.idx2offset[i];
|
||||
var vit = try compress.VarintSliceIterator(blob[offset..]);
|
||||
var it = compress.DeltaDecompressionIterator(&vit);
|
||||
for (corpus.group2users[i]) |user_idx| {
|
||||
|
@ -690,18 +696,18 @@ test "userGids" {
|
|||
var corpus = try testCorpus(allocator);
|
||||
defer corpus.deinit();
|
||||
|
||||
var user_gids = try userGids(allocator, &corpus);
|
||||
defer user_gids.deinit(allocator);
|
||||
var additional_gids = try userGids(allocator, &corpus);
|
||||
defer additional_gids.deinit(allocator);
|
||||
|
||||
var user_idx: usize = 0;
|
||||
while (user_idx < corpus.users.len) : (user_idx += 1) {
|
||||
const groups = corpus.user2groups[user_idx];
|
||||
const offset = user_gids.idx2offset[user_idx];
|
||||
const offset = additional_gids.idx2offset[user_idx];
|
||||
if (groups.len == 0) {
|
||||
try testing.expect(offset == 0);
|
||||
continue;
|
||||
}
|
||||
var vit = try compress.VarintSliceIterator(user_gids.blob[offset..]);
|
||||
var vit = try compress.VarintSliceIterator(additional_gids.blob[offset..]);
|
||||
var it = compress.DeltaDecompressionIterator(&vit);
|
||||
try testing.expectEqual(it.remaining(), groups.len);
|
||||
var i: u64 = 0;
|
||||
|
|
|
@ -38,6 +38,8 @@ pub const ShellWriter = struct {
|
|||
};
|
||||
|
||||
pub const ShellSections = struct {
|
||||
// len is the number of shells in this section.
|
||||
len: u8,
|
||||
// index points the i'th shell to it's offset in blob. The last
|
||||
// byte of the i'th shell is index[i+1].
|
||||
index: BoundedArray(u16, max_shells),
|
||||
|
@ -55,6 +57,7 @@ pub const ShellWriter = struct {
|
|||
shells: BoundedArray([]const u8, max_shells),
|
||||
) error{ Overflow, OutOfMemory }!ShellSections {
|
||||
var self = ShellSections{
|
||||
.len = @intCast(u8, shells.len),
|
||||
.index = try BoundedArray(u16, max_shells).init(shells.len),
|
||||
.blob = try BoundedArray(u8, (max_shells + 1) * max_shell_len).init(0),
|
||||
.shell2idx = StringHashMap(u8).init(allocator),
|
||||
|
|
Loading…
Reference in New Issue