Zig 0.17.0-dev (Split by item)

This is an example of documentation generated by ZigDoc, an alternative to Zig's built-in Auto Doc feature. See also examples in other modes/formats. The project being documented here (as the example) is the Zig library itself.

LoadCommandIterator

macho.LoadCommandIterator
pub const LoadCommandIterator = struct

File

lib/std/macho.zig:1916

Code

pub const LoadCommandIterator = struct {
    next_index: usize,
    ncmds: usize,
    r: std.Io.Reader,

    pub const LoadCommand = struct {
        hdr: load_command,
        data: []const u8,

        pub fn cast(lc: LoadCommand, comptime Cmd: type) ?Cmd {
            if (lc.data.len < @sizeOf(Cmd)) return null;
            const ptr: *align(1) const Cmd = @ptrCast(lc.data.ptr);
            var cmd = ptr.*;
            if (builtin.cpu.arch.endian() != .little) std.mem.byteSwapAllFields(Cmd, &cmd);
            return cmd;
        }

        /// Asserts LoadCommand is of type segment_command_64.
        /// If the native endian is not `.little`, the `section_64` values must be byte-swapped by the caller.
        pub fn getSections(lc: LoadCommand) []align(1) const section_64 {
            const segment_lc = lc.cast(segment_command_64).?;
            const sects_ptr: [*]align(1) const section_64 = @ptrCast(lc.data[@sizeOf(segment_command_64)..]);
            return sects_ptr[0..segment_lc.nsects];
        }

        /// Asserts LoadCommand is of type dylib_command.
        pub fn getDylibPathName(lc: LoadCommand) []const u8 {
            const dylib_lc = lc.cast(dylib_command).?;
            return mem.sliceTo(lc.data[dylib_lc.dylib.name..], 0);
        }

        /// Asserts LoadCommand is of type rpath_command.
        pub fn getRpathPathName(lc: LoadCommand) []const u8 {
            const rpath_lc = lc.cast(rpath_command).?;
            return mem.sliceTo(lc.data[rpath_lc.path..], 0);
        }

        /// Asserts LoadCommand is of type build_version_command.
        /// If the native endian is not `.little`, the `build_tool_version` values must be byte-swapped by the caller.
        pub fn getBuildVersionTools(lc: LoadCommand) []align(1) const build_tool_version {
            const build_lc = lc.cast(build_version_command).?;
            const tools_ptr: [*]align(1) const build_tool_version = @ptrCast(lc.data[@sizeOf(build_version_command)..]);
            return tools_ptr[0..build_lc.ntools];
        }
    };

    pub fn next(it: *LoadCommandIterator) error{InvalidMachO}!?LoadCommand {
        if (it.next_index >= it.ncmds) return null;

        const hdr = it.r.peekStruct(load_command, .little) catch |err| switch (err) {
            error.ReadFailed => unreachable,
            error.EndOfStream => return error.InvalidMachO,
        };
        const data = it.r.take(hdr.cmdsize) catch |err| switch (err) {
            error.ReadFailed => unreachable,
            error.EndOfStream => return error.InvalidMachO,
        };

        it.next_index += 1;
        return .{ .hdr = hdr, .data = data };
    }

    pub fn init(hdr: *const mach_header_64, cmds_buf_overlong: []const u8) error{InvalidMachO}!LoadCommandIterator {
        if (cmds_buf_overlong.len < hdr.sizeofcmds) return error.InvalidMachO;
        if (hdr.ncmds > 0 and hdr.sizeofcmds < @sizeOf(load_command)) return error.InvalidMachO;
        const cmds_buf = cmds_buf_overlong[0..hdr.sizeofcmds];
        return .{
            .next_index = 0,
            .ncmds = hdr.ncmds,
            .r = .fixed(cmds_buf),
        };
    }
}