89 lines
2.7 KiB
Zig
89 lines
2.7 KiB
Zig
const std = @import("std");
|
|
const mem = std.mem;
|
|
|
|
const err = @import("libvirt-error.zig");
|
|
|
|
// Helper struct for allocating null-terminated strings
|
|
pub const String = struct {
|
|
allocator: mem.Allocator,
|
|
slice: []u8,
|
|
str: [:0]const u8,
|
|
|
|
pub fn init(allocator: mem.Allocator, in_str: []const u8) !String {
|
|
const str = try allocator.alloc(u8, in_str.len + 1);
|
|
@memcpy(str[0..in_str.len], in_str);
|
|
str[str.len - 1] = 0;
|
|
return .{
|
|
.allocator = allocator,
|
|
.slice = str,
|
|
.str = @ptrCast(str),
|
|
};
|
|
}
|
|
pub fn deinit(self: *const String) void {
|
|
self.allocator.free(self.slice);
|
|
}
|
|
};
|
|
|
|
fn string(str: [*c]const u8) []const u8 {
|
|
return mem.span(str);
|
|
}
|
|
|
|
fn intFromFlags(comptime T: type, flags: []const T) c_uint {
|
|
var flags_int: c_uint = 0;
|
|
for (flags) |f| flags_int |= @intFromEnum(f);
|
|
return flags_int;
|
|
}
|
|
|
|
fn Iterator(comptime T: type, comptime Ptr: type, comptime freeFn: *const fn (Ptr) callconv(.C) c_int) type {
|
|
return struct {
|
|
allocator: mem.Allocator,
|
|
list: [*]Ptr,
|
|
num: c_int,
|
|
curr: usize,
|
|
|
|
pub fn init(
|
|
comptime PP: type, // Parent Pointer
|
|
comptime P: type, // Parent
|
|
comptime F: type, // Flags
|
|
parent: *const P,
|
|
flags: []const F,
|
|
allocator: mem.Allocator,
|
|
initFn: *const fn (?*PP, [*c][*c]Ptr, c_uint) callconv(.C) c_int,
|
|
) !Self {
|
|
var list: [*]Ptr = undefined;
|
|
const num = initFn(parent.ptr, @ptrCast(&list), intFromFlags(F, flags));
|
|
return if (num < 0) err.handleError() else .{
|
|
.allocator = allocator,
|
|
.list = list,
|
|
.num = num,
|
|
.curr = 0,
|
|
};
|
|
}
|
|
pub fn deinit(self: *Self) void {
|
|
var i: usize = 0;
|
|
while (i < self.num) : (i += 1) _ = freeFn(self.list[i]);
|
|
}
|
|
pub fn first(self: *Self) T {
|
|
self.curr = 0;
|
|
// return .{ .ptr = self.list[self.curr], .arena = heap.ArenaAllocator.init(self.allocator) };
|
|
return T.init(self.list[self.curr], self.allocator);
|
|
}
|
|
pub fn next(self: *Self) ?T {
|
|
if (self.curr >= self.num) return null;
|
|
const ptr = self.list[self.curr];
|
|
self.curr += 1;
|
|
// return .{ .ptr = ptr, .arena = heap.ArenaAllocator.init(self.allocator) };
|
|
return T.init(ptr, self.allocator);
|
|
}
|
|
const Self = @This();
|
|
};
|
|
}
|
|
|
|
fn numOf(
|
|
comptime P: type,
|
|
ptr: P,
|
|
fnPtr: *const fn (P) callconv(.C) c_int,
|
|
) !u32 {
|
|
const num = fnPtr(ptr);
|
|
return if (num < 0) err.handleError() else @intCast(num);
|
|
}
|