const std = @import("std"); /// Read-only memory mapping of a whole file. Used by the ai library loaders /// to expose model tensor data without copying it. /// /// Built on the `std.Io` interface, so it works on every platform Io supports /// (POSIX and Windows alike). The mapping is released by `deinit`; ownership /// of the raw bytes can be transferred out once via `release`, after which /// `deinit` becomes a no-op (the receiver owns unmapping). pub const MappedFile = struct { inner: std.Io.File.MemoryMap, file: std.Io.File, io: std.Io, released: bool = false, /// Transfers ownership of the mapped bytes to the caller: from this point /// on, `deinit` will not unmap. The receiver must eventually munmap (the /// VM wraps these bytes in a refcounted MapOwner). pub fn release(self: *MappedFile) []align(std.heap.page_size_min) u8 { self.released = true; return self.inner.memory; } pub fn deinit(self: *MappedFile) void { if (self.released) return; self.released = true; self.inner.destroy(self.io); self.file.close(self.io); } }; pub const Error = error{ FileOpenFailed, EmptyFile, MmapFailed, }; /// Maps `path` read-only. Release with `deinit`, or transfer the bytes with /// `release`. pub fn mapFile(io: std.Io, path: []const u8) Error!MappedFile { const file = std.Io.Dir.cwd().openFile(io, path, .{}) catch return error.FileOpenFailed; errdefer file.close(io); const st = file.stat(io) catch return error.MmapFailed; if (st.size == 0) return error.EmptyFile; const inner = std.Io.File.MemoryMap.create(io, file, .{ .len = @intCast(st.size), // Read-only view: model files are never modified through mappings. .protection = .{ .read = true, .write = false }, }) catch return error.MmapFailed; return .{ .inner = inner, .file = file, .io = io }; }