split calculation of lengths and offsets
This commit is contained in:
parent
65b0fa774d
commit
601b1b4a6e
86
src/DB.zig
86
src/DB.zig
@ -204,39 +204,73 @@ pub fn iov(self: *const DB) BoundedArray(os.iovec_const, DB_fields.len * 2) {
|
||||
return result;
|
||||
}
|
||||
|
||||
pub fn fromBytes(buf: []align(8) const u8) InvalidHeader!DB {
|
||||
const header = try Header.fromBytes(buf[0..@sizeOf(Header)]);
|
||||
// At first the tuple below had field names too, but moved it to comments,
|
||||
// because it segfaulted. https://github.com/ziglang/zig/issues/3915 and
|
||||
// https://paste.sr.ht/~motiejus/2830736e796801517c1fa8639be6615cd56ada27
|
||||
const lengths = .{
|
||||
header.nblocks_bdz_gid, // bdz_gid
|
||||
header.nblocks_bdz_groupname, // bdz_groupname
|
||||
header.nblocks_bdz_uid, // bdz_uid
|
||||
header.nblocks_bdz_username, // bdz_username
|
||||
nblocks_n(u32, header.num_groups * 4), // idx_gid2group
|
||||
nblocks_n(u32, header.num_groups * 4), // idx_groupname2group
|
||||
nblocks_n(u32, header.num_users * 4), // idx_uid2user
|
||||
nblocks_n(u32, header.num_users * 4), // idx_name2user
|
||||
nblocks_n(u16, header.num_shells * 2), // shell_index
|
||||
header.nblocks_shell_blob, // shell_blob
|
||||
header.nblocks_groups, // groups
|
||||
header.nblocks_users, // users
|
||||
header.nblocks_groupmembers, // groupmembers
|
||||
header.nblocks_additional_gids, // additional_gids
|
||||
};
|
||||
const DBNumbers = struct {
|
||||
header: u64,
|
||||
bdz_gid: u64,
|
||||
bdz_groupname: u64,
|
||||
bdz_uid: u64,
|
||||
bdz_username: u64,
|
||||
idx_gid2group: u64,
|
||||
idx_groupname2group: u64,
|
||||
idx_uid2user: u64,
|
||||
idx_name2user: u64,
|
||||
shell_index: u64,
|
||||
shell_blob: u64,
|
||||
groups: u64,
|
||||
users: u64,
|
||||
groupmembers: u64,
|
||||
additional_gids: u64,
|
||||
};
|
||||
|
||||
var result: DB = undefined;
|
||||
result.header = header;
|
||||
// in blocks
|
||||
fn fieldLengths(header: *const Header) DBNumbers {
|
||||
return DBNumbers{
|
||||
.header = undefined,
|
||||
.bdz_gid = header.nblocks_bdz_gid,
|
||||
.bdz_groupname = header.nblocks_bdz_groupname,
|
||||
.bdz_uid = header.nblocks_bdz_uid,
|
||||
.bdz_username = header.nblocks_bdz_username,
|
||||
.idx_gid2group = nblocks_n(u32, header.num_groups * 4),
|
||||
.idx_groupname2group = nblocks_n(u32, header.num_groups * 4),
|
||||
.idx_uid2user = nblocks_n(u32, header.num_users * 4),
|
||||
.idx_name2user = nblocks_n(u32, header.num_users * 4),
|
||||
.shell_index = nblocks_n(u16, header.num_shells * 2),
|
||||
.shell_blob = header.nblocks_shell_blob,
|
||||
.groups = header.nblocks_groups,
|
||||
.users = header.nblocks_users,
|
||||
.groupmembers = header.nblocks_groupmembers,
|
||||
.additional_gids = header.nblocks_additional_gids,
|
||||
};
|
||||
}
|
||||
|
||||
// in blocks
|
||||
fn fieldOffsets(lengths: DBNumbers) DBNumbers {
|
||||
var result: DBNumbers = undefined;
|
||||
result.header = 0;
|
||||
var offset = comptime nblocks_n(u64, @sizeOf(Header));
|
||||
comptime assert(mem.eql(u8, DB_fields[0].name, "header"));
|
||||
inline for (DB_fields[1..]) |field, i| {
|
||||
const start = offset << section_length_bits;
|
||||
const end = (offset + lengths[i]) << section_length_bits;
|
||||
comptime assert(mem.eql(u8, field.name, meta.fields(DBNumbers)[i + 1].name));
|
||||
@field(result, field.name) = offset;
|
||||
offset += @field(lengths, field.name);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
pub fn fromBytes(buf: []align(8) const u8) InvalidHeader!DB {
|
||||
const header = try Header.fromBytes(buf[0..@sizeOf(Header)]);
|
||||
const lengths = fieldLengths(header);
|
||||
const offsets = fieldOffsets(lengths);
|
||||
|
||||
var result: DB = undefined;
|
||||
result.header = header;
|
||||
inline for (DB_fields[1..]) |field| {
|
||||
const start_block = @field(offsets, field.name);
|
||||
const end = (start_block + @field(lengths, field.name)) << section_length_bits;
|
||||
const start = start_block << section_length_bits;
|
||||
const slice_type = meta.Child(field.field_type);
|
||||
const value = mem.bytesAsSlice(slice_type, buf[start..end]);
|
||||
@field(result, field.name) = value;
|
||||
offset += lengths[i];
|
||||
}
|
||||
|
||||
return result;
|
||||
|
Loading…
Reference in New Issue
Block a user