pub const ext = @import("ext.zig");
const gck = @This();

const std = @import("std");
const compat = @import("compat");
const gio = @import("gio2");
const gobject = @import("gobject2");
const glib = @import("glib2");
const gmodule = @import("gmodule2");
/// Can be used to enumerate through PKCS`@"11"` objects. It will automatically
/// create sessions as necessary.
///
/// Use `modulesEnumerateObjects` or `modulesEnumerateUri` to
/// create an enumerator. To get the objects, use `Enumerator.next` or
/// `Enumerator.nextAsync` functions.
pub const Enumerator = extern struct {
    pub const Parent = gobject.Object;
    pub const Implements = [_]type{};
    pub const Class = gck.EnumeratorClass;
    f_parent: gobject.Object,
    f_pv: ?*gck.EnumeratorPrivate,
    f_reserved: [2]*anyopaque,

    pub const virtual_methods = struct {};

    pub const properties = struct {
        /// Chained enumerator, which will be enumerated when this enumerator
        /// has enumerated all its objects.
        pub const chained = struct {
            pub const name = "chained";

            pub const Type = ?*gck.Enumerator;
        };

        /// Interaction object used to ask the user for pins when opening
        /// sessions. Used if the session_options of the enumerator have
        /// `GCK_SESSION_LOGIN_USER`
        pub const interaction = struct {
            pub const name = "interaction";

            pub const Type = ?*gio.TlsInteraction;
        };

        /// The type of objects that are created by the enumerator. Must be
        /// GckObject or derived from it.
        pub const object_type = struct {
            pub const name = "object-type";

            pub const Type = usize;
        };
    };

    pub const signals = struct {};

    /// Get the enumerator that will be run after all objects from this one
    /// are seen.
    extern fn gck_enumerator_get_chained(p_self: *Enumerator) ?*gck.Enumerator;
    pub const getChained = gck_enumerator_get_chained;

    /// Get the interaction used when a pin is needed
    extern fn gck_enumerator_get_interaction(p_self: *Enumerator) ?*gio.TlsInteraction;
    pub const getInteraction = gck_enumerator_get_interaction;

    /// Get the type of objects created by this enumerator. The type will always
    /// either be `gck.Object` or derived from it.
    extern fn gck_enumerator_get_object_type(p_self: *Enumerator) usize;
    pub const getObjectType = gck_enumerator_get_object_type;

    /// Get the next object in the enumerator, or `NULL` if there are no more objects.
    ///
    /// `NULL` is also returned if the function fails. Use the `error` to determine
    /// whether a failure occurred or not.
    extern fn gck_enumerator_next(p_self: *Enumerator, p_cancellable: ?*gio.Cancellable, p_error: ?*?*glib.Error) ?*gck.Object;
    pub const next = gck_enumerator_next;

    /// Get the next set of objects from the enumerator. This operation completes
    /// asynchronously.The maximum number of objects can be specified with
    /// `max_objects`. If -1 is specified, then all the remaining objects will be
    /// enumerated.
    extern fn gck_enumerator_next_async(p_self: *Enumerator, p_max_objects: c_int, p_cancellable: ?*gio.Cancellable, p_callback: ?gio.AsyncReadyCallback, p_user_data: ?*anyopaque) void;
    pub const nextAsync = gck_enumerator_next_async;

    /// Complete an operation to enumerate next objects.
    ///
    /// `NULL` is also returned if the function fails. Use the `error` to determine
    /// whether a failure occurred or not.
    extern fn gck_enumerator_next_finish(p_self: *Enumerator, p_result: *gio.AsyncResult, p_error: ?*?*glib.Error) ?*glib.List;
    pub const nextFinish = gck_enumerator_next_finish;

    /// Get the next set of objects from the enumerator. The maximum number of
    /// objects can be specified with `max_objects`. If -1 is specified, then all
    /// the remaining objects will be returned.
    ///
    /// `NULL` is also returned if the function fails. Use the `error` to determine
    /// whether a failure occurred or not.
    extern fn gck_enumerator_next_n(p_self: *Enumerator, p_max_objects: c_int, p_cancellable: ?*gio.Cancellable, p_error: ?*?*glib.Error) ?*glib.List;
    pub const nextN = gck_enumerator_next_n;

    /// Set a chained enumerator that will be run after all objects from this one
    /// are seen.
    extern fn gck_enumerator_set_chained(p_self: *Enumerator, p_chained: ?*gck.Enumerator) void;
    pub const setChained = gck_enumerator_set_chained;

    /// Set the interaction used when a pin is needed
    extern fn gck_enumerator_set_interaction(p_self: *Enumerator, p_interaction: ?*gio.TlsInteraction) void;
    pub const setInteraction = gck_enumerator_set_interaction;

    /// Set the type of objects to be created by this enumerator. The type must
    /// always be either `gck.Object` or derived from it.
    ///
    /// If the `gck.ObjectCache` interface is implemented on the derived class
    /// and the default_types class field is set, then the enumerator will retrieve
    /// attributes for each object.
    extern fn gck_enumerator_set_object_type(p_self: *Enumerator, p_object_type: usize) void;
    pub const setObjectType = gck_enumerator_set_object_type;

    /// Set the type of objects to be created by this enumerator. The type must
    /// always be either `gck.Object` or derived from it.
    ///
    /// If `attr_types` and `attr_count` are non-NULL and non-zero respectively,
    /// then the `gck.ObjectCache` interface is expected to be implemented on the
    /// derived class, then the enumerator will retrieve attributes for each object.
    extern fn gck_enumerator_set_object_type_full(p_self: *Enumerator, p_object_type: usize, p_attr_types: [*]const c_ulong, p_attr_count: c_int) void;
    pub const setObjectTypeFull = gck_enumerator_set_object_type_full;

    extern fn gck_enumerator_get_type() usize;
    pub const getGObjectType = gck_enumerator_get_type;

    extern fn g_object_ref(p_self: *gck.Enumerator) void;
    pub const ref = g_object_ref;

    extern fn g_object_unref(p_self: *gck.Enumerator) void;
    pub const unref = g_object_unref;

    pub fn as(p_instance: *Enumerator, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// Holds a loaded PKCS`@"11"` module. A PKCS`@"11"` module is a shared library.
///
/// You can load and initialize a PKCS`@"11"` module with the
/// `Module.initialize` call. If you already have a loaded and
/// initialized module that you'd like to use with the various Gck functions,
/// then you can use `Module.new`.
pub const Module = extern struct {
    pub const Parent = gobject.Object;
    pub const Implements = [_]type{};
    pub const Class = gck.ModuleClass;
    f_parent: gobject.Object,
    f_pv: ?*gck.ModulePrivate,
    f_reserved: [4]*anyopaque,

    pub const virtual_methods = struct {
        pub const authenticate_object = struct {
            pub fn call(p_class: anytype, p_self: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_object: *gck.Object, p_label: [*:0]u8, p_password: *[*:0]u8) c_int {
                return gobject.ext.as(Module.Class, p_class).f_authenticate_object.?(gobject.ext.as(Module, p_self), p_object, p_label, p_password);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_self: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_object: *gck.Object, p_label: [*:0]u8, p_password: *[*:0]u8) callconv(.c) c_int) void {
                gobject.ext.as(Module.Class, p_class).f_authenticate_object = @ptrCast(p_implementation);
            }
        };

        pub const authenticate_slot = struct {
            pub fn call(p_class: anytype, p_self: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_slot: *gck.Slot, p_label: [*:0]u8, p_password: *[*:0]u8) c_int {
                return gobject.ext.as(Module.Class, p_class).f_authenticate_slot.?(gobject.ext.as(Module, p_self), p_slot, p_label, p_password);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_self: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_slot: *gck.Slot, p_label: [*:0]u8, p_password: *[*:0]u8) callconv(.c) c_int) void {
                gobject.ext.as(Module.Class, p_class).f_authenticate_slot = @ptrCast(p_implementation);
            }
        };
    };

    pub const properties = struct {
        /// The raw PKCS&num;11 function list for the module.
        ///
        /// This points to a CK_FUNCTION_LIST structure.
        pub const functions = struct {
            pub const name = "functions";

            pub const Type = ?*anyopaque;
        };

        /// The PKCS&num;11 module file path.
        ///
        /// This may be set to NULL if this object was created from an already
        /// initialized module via the `gck.Module.new` function.
        pub const path = struct {
            pub const name = "path";

            pub const Type = ?[*:0]u8;
        };
    };

    pub const signals = struct {
        /// Use `gck.Session.setInteraction` instead of connecting to this signal.
        pub const authenticate_object = struct {
            pub const name = "authenticate-object";

            pub fn connect(p_instance: anytype, comptime P_Data: type, p_callback: *const fn (@TypeOf(p_instance), p_object: *gck.Object, p_label: [*:0]u8, p_password: ?*anyopaque, P_Data) callconv(.c) c_int, p_data: P_Data, p_options: gobject.ext.ConnectSignalOptions(P_Data)) c_ulong {
                return gobject.signalConnectClosureById(
                    @ptrCast(@alignCast(gobject.ext.as(Module, p_instance))),
                    gobject.signalLookup("authenticate-object", Module.getGObjectType()),
                    glib.quarkFromString(p_options.detail orelse null),
                    gobject.CClosure.new(@ptrCast(p_callback), p_data, @ptrCast(p_options.destroyData)),
                    @intFromBool(p_options.after),
                );
            }
        };

        /// Use `gck.Session.setInteraction` instead of connecting to this signal.
        pub const authenticate_slot = struct {
            pub const name = "authenticate-slot";

            pub fn connect(p_instance: anytype, comptime P_Data: type, p_callback: *const fn (@TypeOf(p_instance), p_slot: *gck.Slot, p_string: [*:0]u8, p_password: ?*anyopaque, P_Data) callconv(.c) c_int, p_data: P_Data, p_options: gobject.ext.ConnectSignalOptions(P_Data)) c_ulong {
                return gobject.signalConnectClosureById(
                    @ptrCast(@alignCast(gobject.ext.as(Module, p_instance))),
                    gobject.signalLookup("authenticate-slot", Module.getGObjectType()),
                    glib.quarkFromString(p_options.detail orelse null),
                    gobject.CClosure.new(@ptrCast(p_callback), p_data, @ptrCast(p_options.destroyData)),
                    @intFromBool(p_options.after),
                );
            }
        };
    };

    /// Load and initialize a PKCS`@"11"` module represented by a GckModule object.
    extern fn gck_module_initialize(p_path: [*:0]const u8, p_cancellable: ?*gio.Cancellable, p_error: ?*?*glib.Error) ?*gck.Module;
    pub const initialize = gck_module_initialize;

    /// Asynchronously load and initialize a PKCS`@"11"` module represented by a
    /// `Module` object.
    extern fn gck_module_initialize_async(p_path: [*:0]const u8, p_cancellable: ?*gio.Cancellable, p_callback: ?gio.AsyncReadyCallback, p_user_data: ?*anyopaque) void;
    pub const initializeAsync = gck_module_initialize_async;

    /// Finishes the asynchronous initialize operation.
    extern fn gck_module_initialize_finish(p_result: *gio.AsyncResult, p_error: ?*?*glib.Error) ?*gck.Module;
    pub const initializeFinish = gck_module_initialize_finish;

    /// Create a `Module` representing a PKCS`@"11"` module. It is assumed that
    /// this the module is already initialized. In addition it will not be
    /// finalized when complete.
    extern fn gck_module_new(p_funcs: *anyopaque) *gck.Module;
    pub const new = gck_module_new;

    /// Checks equality of two modules. Two GckModule objects can point to the same
    /// underlying PKCS`@"11"` module.
    extern fn gck_module_equal(p_module1: *const Module, p_module2: *const gck.Module) c_int;
    pub const equal = gck_module_equal;

    /// Get the PKCS`@"11"` function list for the module.
    extern fn gck_module_get_functions(p_self: *Module) *anyopaque;
    pub const getFunctions = gck_module_get_functions;

    /// Get the info about a PKCS`@"11"` module.
    extern fn gck_module_get_info(p_self: *Module) *gck.ModuleInfo;
    pub const getInfo = gck_module_get_info;

    /// Get the file path of this module. This may not be an absolute path, and
    /// usually reflects the path passed to `Module.initialize`.
    extern fn gck_module_get_path(p_self: *Module) [*:0]const u8;
    pub const getPath = gck_module_get_path;

    /// Get the GckSlot objects for a given module.
    extern fn gck_module_get_slots(p_self: *Module, p_token_present: c_int) *glib.List;
    pub const getSlots = gck_module_get_slots;

    /// Create a hash value for the GckModule.
    ///
    /// This function is intended for easily hashing a `Module` to add to
    /// a `glib.HashTable` or similar data structure.
    extern fn gck_module_hash(p_module: *const Module) c_uint;
    pub const hash = gck_module_hash;

    /// Check whether the PKCS`@"11"` URI matches the module
    extern fn gck_module_match(p_self: *Module, p_uri: *gck.UriData) c_int;
    pub const match = gck_module_match;

    extern fn gck_module_get_type() usize;
    pub const getGObjectType = gck_module_get_type;

    extern fn g_object_ref(p_self: *gck.Module) void;
    pub const ref = g_object_ref;

    extern fn g_object_unref(p_self: *gck.Module) void;
    pub const unref = g_object_unref;

    pub fn as(p_instance: *Module, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// Holds a handle to a PKCS11 object such as a key or certificate. Token
/// objects are stored on the token persistently. Others are transient and are
/// called session objects.
pub const Object = extern struct {
    pub const Parent = gobject.Object;
    pub const Implements = [_]type{};
    pub const Class = gck.ObjectClass;
    f_parent: gobject.Object,
    f_pv: ?*gck.ObjectPrivate,
    f_reserved: [4]*anyopaque,

    pub const virtual_methods = struct {};

    pub const properties = struct {
        /// The raw PKCS11 handle for this object.
        pub const handle = struct {
            pub const name = "handle";

            pub const Type = c_ulong;
        };

        /// The GckModule that this object belongs to.
        pub const module = struct {
            pub const name = "module";

            pub const Type = ?*gck.Module;
        };

        /// The PKCS11 session to make calls on when this object needs to
        /// perform operations on itself.
        ///
        /// If this is NULL then a new session is opened for each operation,
        /// such as `gck.Object.get`, `gck.Object.set` or `gck.Object.destroy`.
        pub const session = struct {
            pub const name = "session";

            pub const Type = ?*gck.Session;
        };
    };

    pub const signals = struct {};

    /// Initialize a GckObject from a raw PKCS`@"11"` handle. Normally you would use
    /// `Session.createObject` or `Session.findObjects` to access
    /// objects.
    extern fn gck_object_from_handle(p_session: *gck.Session, p_object_handle: c_ulong) *gck.Object;
    pub const fromHandle = gck_object_from_handle;

    /// Lookup attributes in the cache, or retrieve them from the object if necessary.
    ///
    /// If `object` is a `gck.ObjectCache` then this will lookup the attributes there
    /// first if available, otherwise will read them from the object and update
    /// the cache.
    ///
    /// If `object` is not a `gck.ObjectCache`, then the attributes will simply be
    /// read from the object.
    ///
    /// This may block, use the asynchronous version when this is not desirable
    extern fn gck_object_cache_lookup(p_object: *Object, p_attr_types: [*]const c_ulong, p_n_attr_types: c_int, p_cancellable: ?*gio.Cancellable, p_error: ?*?*glib.Error) ?*gck.Attributes;
    pub const cacheLookup = gck_object_cache_lookup;

    /// Lookup attributes in the cache, or retrieve them from the object if necessary.
    ///
    /// If `object` is a `gck.ObjectCache` then this will lookup the attributes there
    /// first if available, otherwise will read them from the object and update
    /// the cache.
    ///
    /// If `object` is not a `gck.ObjectCache`, then the attributes will simply be
    /// read from the object.
    ///
    /// This will return immediately and complete asynchronously
    extern fn gck_object_cache_lookup_async(p_object: *Object, p_attr_types: [*]const c_ulong, p_n_attr_types: c_int, p_cancellable: ?*gio.Cancellable, p_callback: ?gio.AsyncReadyCallback, p_user_data: ?*anyopaque) void;
    pub const cacheLookupAsync = gck_object_cache_lookup_async;

    /// Complete an operation to lookup attributes in the cache or retrieve them
    /// from the object if necessary.
    extern fn gck_object_cache_lookup_finish(p_object: *Object, p_result: *gio.AsyncResult, p_error: ?*?*glib.Error) ?*gck.Attributes;
    pub const cacheLookupFinish = gck_object_cache_lookup_finish;

    /// Destroy a PKCS`@"11"` object, deleting it from storage or the session.
    /// This call may block for an indefinite period.
    extern fn gck_object_destroy(p_self: *Object, p_cancellable: ?*gio.Cancellable, p_error: ?*?*glib.Error) c_int;
    pub const destroy = gck_object_destroy;

    /// Destroy a PKCS`@"11"` object, deleting it from storage or the session.
    /// This call will return immediately and complete asynchronously.
    extern fn gck_object_destroy_async(p_self: *Object, p_cancellable: ?*gio.Cancellable, p_callback: ?gio.AsyncReadyCallback, p_user_data: ?*anyopaque) void;
    pub const destroyAsync = gck_object_destroy_async;

    /// Get the status of the operation to destroy a PKCS`@"11"` object, begun with
    /// `gck.Object.destroyAsync`.
    extern fn gck_object_destroy_finish(p_self: *Object, p_result: *gio.AsyncResult, p_error: ?*?*glib.Error) c_int;
    pub const destroyFinish = gck_object_destroy_finish;

    /// Checks equality of two objects. Two GckObject objects can point to the same
    /// underlying PKCS`@"11"` object.
    extern fn gck_object_equal(p_object1: *const Object, p_object2: *const gck.Object) c_int;
    pub const equal = gck_object_equal;

    /// Get the specified attributes from the object. This call may
    /// block for an indefinite period.
    extern fn gck_object_get(p_self: *Object, p_cancellable: ?*gio.Cancellable, p_error: **glib.Error, ...) *gck.Attributes;
    pub const get = gck_object_get;

    /// Get the specified attributes from the object. The attributes will be cleared
    /// of their current values, and new attributes will be stored. The attributes
    /// should not be accessed in any way except for referencing and unreferencing
    /// them until `gck.Object.getFinish` is called.
    ///
    /// This call returns immediately and completes asynchronously.
    extern fn gck_object_get_async(p_self: *Object, p_attr_types: [*]const c_ulong, p_n_attr_types: c_uint, p_cancellable: ?*gio.Cancellable, p_callback: ?gio.AsyncReadyCallback, p_user_data: ?*anyopaque) void;
    pub const getAsync = gck_object_get_async;

    /// Get the data for the specified attribute from the object. For convenience
    /// the returned data has a null terminator.
    ///
    /// This call may block for an indefinite period.
    extern fn gck_object_get_data(p_self: *Object, p_attr_type: c_ulong, p_cancellable: ?*gio.Cancellable, p_n_data: *usize, p_error: ?*?*glib.Error) ?[*]u8;
    pub const getData = gck_object_get_data;

    /// Get the data for the specified attribute from the object.
    ///
    /// This call will return immediately and complete asynchronously.
    extern fn gck_object_get_data_async(p_self: *Object, p_attr_type: c_ulong, p_allocator: gck.Allocator, p_cancellable: ?*gio.Cancellable, p_callback: ?gio.AsyncReadyCallback, p_user_data: ?*anyopaque) void;
    pub const getDataAsync = gck_object_get_data_async;

    /// Get the result of an operation to get attribute data from
    /// an object. For convenience the returned data has an extra null terminator,
    /// not included in the returned length.
    extern fn gck_object_get_data_finish(p_self: *Object, p_result: *gio.AsyncResult, p_n_data: *usize, p_error: ?*?*glib.Error) ?[*]u8;
    pub const getDataFinish = gck_object_get_data_finish;

    /// Get the data for the specified attribute from the object. For convenience
    /// the returned data has an extra null terminator, not included in the returned length.
    ///
    /// This call may block for an indefinite period.
    extern fn gck_object_get_data_full(p_self: *Object, p_attr_type: c_ulong, p_allocator: gck.Allocator, p_cancellable: ?*gio.Cancellable, p_n_data: *usize, p_error: ?*?*glib.Error) ?[*]u8;
    pub const getDataFull = gck_object_get_data_full;

    /// Get the result of a get operation and return specified attributes from
    /// the object.
    ///
    /// No extra references are added to the returned attributes pointer.
    extern fn gck_object_get_finish(p_self: *Object, p_result: *gio.AsyncResult, p_error: ?*?*glib.Error) ?*gck.Attributes;
    pub const getFinish = gck_object_get_finish;

    /// Get the specified attributes from the object. This call may
    /// block for an indefinite period.
    ///
    /// No extra references are added to the returned attributes pointer.
    /// During this call you may not access the attributes in any way.
    extern fn gck_object_get_full(p_self: *Object, p_attr_types: [*]const c_ulong, p_n_attr_types: c_uint, p_cancellable: ?*gio.Cancellable, p_error: ?*?*glib.Error) ?*gck.Attributes;
    pub const getFull = gck_object_get_full;

    /// Get the raw PKCS`@"11"` handle of a GckObject.
    extern fn gck_object_get_handle(p_self: *Object) c_ulong;
    pub const getHandle = gck_object_get_handle;

    /// Get the PKCS`@"11"` module to which this object belongs.
    extern fn gck_object_get_module(p_self: *Object) *gck.Module;
    pub const getModule = gck_object_get_module;

    /// Get the PKCS`@"11"` session assigned to make calls on when operating
    /// on this object.
    ///
    /// This will only return a session if it was set explitly on this
    /// object. By default an object will open and close sessions
    /// appropriate for its calls.
    extern fn gck_object_get_session(p_self: *Object) *gck.Session;
    pub const getSession = gck_object_get_session;

    /// Get an attribute template from the object. The attr_type must be for
    /// an attribute which returns a template.
    ///
    /// This call may block for an indefinite period.
    extern fn gck_object_get_template(p_self: *Object, p_attr_type: c_ulong, p_cancellable: ?*gio.Cancellable, p_error: ?*?*glib.Error) ?*gck.Attributes;
    pub const getTemplate = gck_object_get_template;

    /// Get an attribute template from the object. The `attr_type` must be for
    /// an attribute which returns a template.
    ///
    /// This call will return immediately and complete asynchronously.
    extern fn gck_object_get_template_async(p_self: *Object, p_attr_type: c_ulong, p_cancellable: ?*gio.Cancellable, p_callback: ?gio.AsyncReadyCallback, p_user_data: ?*anyopaque) void;
    pub const getTemplateAsync = gck_object_get_template_async;

    /// Get the result of an operation to get attribute template from
    /// an object.
    extern fn gck_object_get_template_finish(p_self: *Object, p_result: *gio.AsyncResult, p_error: ?*?*glib.Error) ?*gck.Attributes;
    pub const getTemplateFinish = gck_object_get_template_finish;

    /// Create a hash value for the GckObject.
    ///
    /// This function is intended for easily hashing a GckObject to add to
    /// a GHashTable or similar data structure.
    extern fn gck_object_hash(p_object: *const Object) c_uint;
    pub const hash = gck_object_hash;

    /// Set PKCS`@"11"` attributes on an object. This call may block for an indefinite period.
    ///
    /// If the `attrs` `gck.Attributes` is floating, it is consumed.
    extern fn gck_object_set(p_self: *Object, p_attrs: *gck.Attributes, p_cancellable: ?*gio.Cancellable, p_error: ?*?*glib.Error) c_int;
    pub const set = gck_object_set;

    /// Set PKCS`@"11"` attributes on an object. This call will return
    /// immediately and completes asynchronously.
    ///
    /// If the `attrs` `gck.Attributes` is floating, it is consumed.
    extern fn gck_object_set_async(p_self: *Object, p_attrs: *gck.Attributes, p_cancellable: ?*gio.Cancellable, p_callback: ?gio.AsyncReadyCallback, p_user_data: ?*anyopaque) void;
    pub const setAsync = gck_object_set_async;

    /// Get the status of the operation to set attributes on a PKCS`@"11"` object,
    /// begun with `gck.Object.setAsync`.
    extern fn gck_object_set_finish(p_self: *Object, p_result: *gio.AsyncResult, p_error: ?*?*glib.Error) c_int;
    pub const setFinish = gck_object_set_finish;

    /// Set an attribute template on the object. The attr_type must be for
    /// an attribute which contains a template.
    ///
    /// If the `attrs` `gck.Attributes` is floating, it is consumed.
    ///
    /// This call may block for an indefinite period.
    extern fn gck_object_set_template(p_self: *Object, p_attr_type: c_ulong, p_attrs: *gck.Attributes, p_cancellable: ?*gio.Cancellable, p_error: ?*?*glib.Error) c_int;
    pub const setTemplate = gck_object_set_template;

    /// Set an attribute template on the object. The attr_type must be for
    /// an attribute which contains a template.
    ///
    /// If the `attrs` `gck.Attributes` is floating, it is consumed.
    ///
    /// This call will return immediately and complete asynchronously.
    extern fn gck_object_set_template_async(p_self: *Object, p_attr_type: c_ulong, p_attrs: *gck.Attributes, p_cancellable: ?*gio.Cancellable, p_callback: ?gio.AsyncReadyCallback, p_user_data: ?*anyopaque) void;
    pub const setTemplateAsync = gck_object_set_template_async;

    /// Get the result of an operation to set attribute template on
    /// an object.
    extern fn gck_object_set_template_finish(p_self: *Object, p_result: *gio.AsyncResult, p_error: ?*?*glib.Error) c_int;
    pub const setTemplateFinish = gck_object_set_template_finish;

    extern fn gck_object_get_type() usize;
    pub const getGObjectType = gck_object_get_type;

    extern fn g_object_ref(p_self: *gck.Object) void;
    pub const ref = g_object_ref;

    extern fn g_object_unref(p_self: *gck.Object) void;
    pub const unref = g_object_unref;

    pub fn as(p_instance: *Object, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// Represents a password which is requested of the user.
///
/// This is used in conjuction with `gio.TlsInteraction`. `GckPassword` is
/// a `gio.TlsPassword` which contains additional information about which
/// PKCS`@"11"` token or key the password is being requested for.
pub const Password = extern struct {
    pub const Parent = gio.TlsPassword;
    pub const Implements = [_]type{};
    pub const Class = gck.PasswordClass;
    f_parent: gio.TlsPassword,
    f_pv: ?*gck.PasswordPrivate,
    f_reserved: [4]*anyopaque,

    pub const virtual_methods = struct {};

    pub const properties = struct {
        /// The PKCS`@"11"` key that the password is being requested for. If this
        /// is set then the GckPassword:token property will be `NULL`
        pub const key = struct {
            pub const name = "key";

            pub const Type = ?*gck.Object;
        };

        /// The PKCS`@"11"` module that is requesting the password
        pub const module = struct {
            pub const name = "module";

            pub const Type = ?*gck.Module;
        };

        /// The PKCS`@"11"` token the password is for, if this is set then
        /// the GckPassword:object property will be `NULL`
        pub const token = struct {
            pub const name = "token";

            pub const Type = ?*gck.Slot;
        };
    };

    pub const signals = struct {};

    /// If the password request is to unlock a PKCS`@"11"` key, then this is the
    /// the object representing that key.
    extern fn gck_password_get_key(p_self: *Password) *gck.Object;
    pub const getKey = gck_password_get_key;

    /// Get the PKCS`@"11"` module that is requesting the password.
    extern fn gck_password_get_module(p_self: *Password) *gck.Module;
    pub const getModule = gck_password_get_module;

    /// If the password request is to unlock a PKCS`@"11"` token, then this is the
    /// slot containing that token.
    extern fn gck_password_get_token(p_self: *Password) *gck.Slot;
    pub const getToken = gck_password_get_token;

    extern fn gck_password_get_type() usize;
    pub const getGObjectType = gck_password_get_type;

    extern fn g_object_ref(p_self: *gck.Password) void;
    pub const ref = g_object_ref;

    extern fn g_object_unref(p_self: *gck.Password) void;
    pub const unref = g_object_unref;

    pub fn as(p_instance: *Password, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// Represents an open PKCS11 session.
///
/// Before performing any PKCS11 operations, a session must be opened. This is
/// analogous to an open database handle, or a file handle.
pub const Session = extern struct {
    pub const Parent = gobject.Object;
    pub const Implements = [_]type{ gio.AsyncInitable, gio.Initable };
    pub const Class = gck.SessionClass;
    f_parent: gobject.Object,
    f_pv: ?*gck.SessionPrivate,
    f_reserved: [4]*anyopaque,

    pub const virtual_methods = struct {
        pub const discard_handle = struct {
            pub fn call(p_class: anytype, p_session: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_handle: c_ulong) c_int {
                return gobject.ext.as(Session.Class, p_class).f_discard_handle.?(gobject.ext.as(Session, p_session), p_handle);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_session: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_handle: c_ulong) callconv(.c) c_int) void {
                gobject.ext.as(Session.Class, p_class).f_discard_handle = @ptrCast(p_implementation);
            }
        };
    };

    pub const properties = struct {
        /// Raw PKCS`@"11"` application data used to open the PKCS`@"11"` session.
        pub const app_data = struct {
            pub const name = "app-data";

            pub const Type = ?*anyopaque;
        };

        /// The raw CK_SESSION_HANDLE handle of this session.
        pub const handle = struct {
            pub const name = "handle";

            pub const Type = c_ulong;
        };

        /// Interaction object used to ask the user for pins when opening
        /// sessions. Used if the session_options of the enumerator have
        /// `GCK_SESSION_LOGIN_USER`
        pub const interaction = struct {
            pub const name = "interaction";

            pub const Type = ?*gio.TlsInteraction;
        };

        /// The GckModule that this session is opened on.
        pub const module = struct {
            pub const name = "module";

            pub const Type = ?*gck.Module;
        };

        /// Raw PKCS`@"11"` flags used to open the PKCS`@"11"` session.
        pub const opening_flags = struct {
            pub const name = "opening-flags";

            pub const Type = c_ulong;
        };

        /// The options this session was opened with.
        pub const options = struct {
            pub const name = "options";

            pub const Type = gck.SessionOptions;
        };

        /// The GckSlot this session is opened on.
        pub const slot = struct {
            pub const name = "slot";

            pub const Type = ?*gck.Slot;
        };
    };

    pub const signals = struct {
        /// When a GckSession is being disposed of it emits this signal to allow
        /// a session pool to pick up the handle and keep it around.
        ///
        /// If no signal handler claims the handle, then it is closed.
        pub const discard_handle = struct {
            pub const name = "discard-handle";

            pub fn connect(p_instance: anytype, comptime P_Data: type, p_callback: *const fn (@TypeOf(p_instance), p_handle: c_ulong, P_Data) callconv(.c) c_int, p_data: P_Data, p_options: gobject.ext.ConnectSignalOptions(P_Data)) c_ulong {
                return gobject.signalConnectClosureById(
                    @ptrCast(@alignCast(gobject.ext.as(Session, p_instance))),
                    gobject.signalLookup("discard-handle", Session.getGObjectType()),
                    glib.quarkFromString(p_options.detail orelse null),
                    gobject.CClosure.new(@ptrCast(p_callback), p_data, @ptrCast(p_options.destroyData)),
                    @intFromBool(p_options.after),
                );
            }
        };
    };

    /// Initialize a session object from a raw PKCS`@"11"` session handle.
    /// Usually one would use the `Slot.openSession` function to
    /// create a session.
    extern fn gck_session_from_handle(p_slot: *gck.Slot, p_session_handle: c_ulong, p_options: gck.SessionOptions) *gck.Session;
    pub const fromHandle = gck_session_from_handle;

    /// Open a session on the slot. This call may block for an indefinite period.
    extern fn gck_session_open(p_slot: *gck.Slot, p_options: gck.SessionOptions, p_interaction: ?*gio.TlsInteraction, p_cancellable: ?*gio.Cancellable, p_error: ?*?*glib.Error) ?*gck.Session;
    pub const open = gck_session_open;

    /// Open a session on the slot. This call will return immediately and complete
    /// asynchronously.
    extern fn gck_session_open_async(p_slot: *gck.Slot, p_options: gck.SessionOptions, p_interaction: ?*gio.TlsInteraction, p_cancellable: ?*gio.Cancellable, p_callback: ?gio.AsyncReadyCallback, p_user_data: ?*anyopaque) void;
    pub const openAsync = gck_session_open_async;

    /// Get the result of an open session operation.
    extern fn gck_session_open_finish(p_result: *gio.AsyncResult, p_error: ?*?*glib.Error) ?*gck.Session;
    pub const openFinish = gck_session_open_finish;

    /// Create a new PKCS`@"11"` object. This call may block for an
    /// indefinite period.
    ///
    /// If the `attrs` `gck.Attributes` is floating, it is consumed.
    extern fn gck_session_create_object(p_self: *Session, p_attrs: *gck.Attributes, p_cancellable: ?*gio.Cancellable, p_error: ?*?*glib.Error) ?*gck.Object;
    pub const createObject = gck_session_create_object;

    /// Create a new PKCS`@"11"` object. This call will return immediately
    /// and complete asynchronously.
    ///
    /// If `attrs` is a floating reference, it is consumed.
    extern fn gck_session_create_object_async(p_self: *Session, p_attrs: *gck.Attributes, p_cancellable: ?*gio.Cancellable, p_callback: ?gio.AsyncReadyCallback, p_user_data: ?*anyopaque) void;
    pub const createObjectAsync = gck_session_create_object_async;

    /// Get the result of creating a new PKCS`@"11"` object.
    extern fn gck_session_create_object_finish(p_self: *Session, p_result: *gio.AsyncResult, p_error: ?*?*glib.Error) ?*gck.Object;
    pub const createObjectFinish = gck_session_create_object_finish;

    /// Decrypt data in a mechanism specific manner. This call may
    /// block for an indefinite period.
    extern fn gck_session_decrypt(p_self: *Session, p_key: *gck.Object, p_mech_type: c_ulong, p_input: [*]const u8, p_n_input: usize, p_n_result: *usize, p_cancellable: ?*gio.Cancellable, p_error: ?*?*glib.Error) ?[*]u8;
    pub const decrypt = gck_session_decrypt;

    /// Decrypt data in a mechanism specific manner. This call will
    /// return immediately and complete asynchronously.
    extern fn gck_session_decrypt_async(p_self: *Session, p_key: *gck.Object, p_mechanism: *gck.Mechanism, p_input: [*]const u8, p_n_input: usize, p_cancellable: ?*gio.Cancellable, p_callback: ?gio.AsyncReadyCallback, p_user_data: ?*anyopaque) void;
    pub const decryptAsync = gck_session_decrypt_async;

    /// Get the result of an decryption operation.
    extern fn gck_session_decrypt_finish(p_self: *Session, p_result: *gio.AsyncResult, p_n_result: *usize, p_error: ?*?*glib.Error) ?[*]u8;
    pub const decryptFinish = gck_session_decrypt_finish;

    /// Decrypt data in a mechanism specific manner. This call may
    /// block for an indefinite period.
    extern fn gck_session_decrypt_full(p_self: *Session, p_key: *gck.Object, p_mechanism: *gck.Mechanism, p_input: [*]const u8, p_n_input: usize, p_n_result: *usize, p_cancellable: ?*gio.Cancellable, p_error: ?*?*glib.Error) ?[*]u8;
    pub const decryptFull = gck_session_decrypt_full;

    /// Derive a key from another key. This call may block for an
    /// indefinite period.
    ///
    /// If the `attrs` `gck.Attributes` is floating, it is consumed.
    extern fn gck_session_derive_key(p_self: *Session, p_base: *gck.Object, p_mech_type: c_ulong, p_attrs: *gck.Attributes, p_cancellable: ?*gio.Cancellable, p_error: ?*?*glib.Error) ?*gck.Object;
    pub const deriveKey = gck_session_derive_key;

    /// Derive a key from another key. This call will
    /// return immediately and complete asynchronously.
    ///
    /// If the `attrs` `gck.Attributes` is floating, it is consumed.
    extern fn gck_session_derive_key_async(p_self: *Session, p_base: *gck.Object, p_mechanism: *gck.Mechanism, p_attrs: *gck.Attributes, p_cancellable: ?*gio.Cancellable, p_callback: ?gio.AsyncReadyCallback, p_user_data: ?*anyopaque) void;
    pub const deriveKeyAsync = gck_session_derive_key_async;

    /// Get the result of a derive key operation.
    extern fn gck_session_derive_key_finish(p_self: *Session, p_result: *gio.AsyncResult, p_error: ?*?*glib.Error) ?*gck.Object;
    pub const deriveKeyFinish = gck_session_derive_key_finish;

    /// Derive a key from another key. This call may block for an
    /// indefinite period.
    ///
    /// If the `attrs` `gck.Attributes` is floating, it is consumed.
    extern fn gck_session_derive_key_full(p_self: *Session, p_base: *gck.Object, p_mechanism: *gck.Mechanism, p_attrs: *gck.Attributes, p_cancellable: ?*gio.Cancellable, p_error: ?*?*glib.Error) ?*gck.Object;
    pub const deriveKeyFull = gck_session_derive_key_full;

    /// Encrypt data in a mechanism specific manner. This call may
    /// block for an indefinite period.
    extern fn gck_session_encrypt(p_self: *Session, p_key: *gck.Object, p_mech_type: c_ulong, p_input: [*]const u8, p_n_input: usize, p_n_result: *usize, p_cancellable: ?*gio.Cancellable, p_error: ?*?*glib.Error) ?[*]u8;
    pub const encrypt = gck_session_encrypt;

    /// Encrypt data in a mechanism specific manner. This call will
    /// return immediately and complete asynchronously.
    extern fn gck_session_encrypt_async(p_self: *Session, p_key: *gck.Object, p_mechanism: *gck.Mechanism, p_input: [*]const u8, p_n_input: usize, p_cancellable: ?*gio.Cancellable, p_callback: ?gio.AsyncReadyCallback, p_user_data: ?*anyopaque) void;
    pub const encryptAsync = gck_session_encrypt_async;

    /// Get the result of an encryption operation.
    extern fn gck_session_encrypt_finish(p_self: *Session, p_result: *gio.AsyncResult, p_n_result: *usize, p_error: ?*?*glib.Error) ?[*]u8;
    pub const encryptFinish = gck_session_encrypt_finish;

    /// Encrypt data in a mechanism specific manner. This call may
    /// block for an indefinite period.
    extern fn gck_session_encrypt_full(p_self: *Session, p_key: *gck.Object, p_mechanism: *gck.Mechanism, p_input: [*]const u8, p_n_input: usize, p_n_result: *usize, p_cancellable: ?*gio.Cancellable, p_error: ?*?*glib.Error) ?[*]u8;
    pub const encryptFull = gck_session_encrypt_full;

    /// Setup an enumerator for listing matching objects available via this session.
    ///
    /// If `match` is a floating reference, it is consumed.
    ///
    /// This call will not block but will return an enumerator immediately.
    extern fn gck_session_enumerate_objects(p_self: *Session, p_match: *gck.Attributes) *gck.Enumerator;
    pub const enumerateObjects = gck_session_enumerate_objects;

    /// Find the objects matching the passed attributes. This call may
    /// block for an indefinite period.
    ///
    /// If `match` is a floating reference, it is consumed.
    extern fn gck_session_find_handles(p_self: *Session, p_match: *gck.Attributes, p_cancellable: ?*gio.Cancellable, p_n_handles: *c_ulong, p_error: ?*?*glib.Error) ?[*]c_ulong;
    pub const findHandles = gck_session_find_handles;

    /// Find the objects matching the passed attributes. This call will
    /// return immediately and complete asynchronously.
    ///
    /// If `match` is a floating reference, it is consumed.
    extern fn gck_session_find_handles_async(p_self: *Session, p_match: *gck.Attributes, p_cancellable: ?*gio.Cancellable, p_callback: ?gio.AsyncReadyCallback, p_user_data: ?*anyopaque) void;
    pub const findHandlesAsync = gck_session_find_handles_async;

    /// Get the result of a find handles operation.
    extern fn gck_session_find_handles_finish(p_self: *Session, p_result: *gio.AsyncResult, p_n_handles: *c_ulong, p_error: ?*?*glib.Error) ?[*]c_ulong;
    pub const findHandlesFinish = gck_session_find_handles_finish;

    /// Find the objects matching the passed attributes. This call may
    /// block for an indefinite period.
    ///
    /// If `match` is a floating reference, it is consumed.
    extern fn gck_session_find_objects(p_self: *Session, p_match: *gck.Attributes, p_cancellable: ?*gio.Cancellable, p_error: ?*?*glib.Error) ?*glib.List;
    pub const findObjects = gck_session_find_objects;

    /// Find the objects matching the passed attributes. This call will
    /// return immediately and complete asynchronously.
    ///
    /// If the `match` `gck.Attributes` is floating, it is consumed.
    extern fn gck_session_find_objects_async(p_self: *Session, p_match: *gck.Attributes, p_cancellable: ?*gio.Cancellable, p_callback: ?gio.AsyncReadyCallback, p_user_data: ?*anyopaque) void;
    pub const findObjectsAsync = gck_session_find_objects_async;

    /// Get the result of a find operation.
    extern fn gck_session_find_objects_finish(p_self: *Session, p_result: *gio.AsyncResult, p_error: ?*?*glib.Error) ?*glib.List;
    pub const findObjectsFinish = gck_session_find_objects_finish;

    /// Generate a new key pair of public and private keys. This call may block for
    /// an indefinite period.
    ///
    /// If `public_attrs` and/or `private_attrs` is a floating reference, it is
    /// consumed.
    extern fn gck_session_generate_key_pair(p_self: *Session, p_mech_type: c_ulong, p_public_attrs: *gck.Attributes, p_private_attrs: *gck.Attributes, p_public_key: ?**gck.Object, p_private_key: ?**gck.Object, p_cancellable: ?*gio.Cancellable, p_error: ?*?*glib.Error) c_int;
    pub const generateKeyPair = gck_session_generate_key_pair;

    /// Generate a new key pair of public and private keys. This call will
    /// return immediately and complete asynchronously.
    ///
    /// If `public_attrs` and/or `private_attrs` is a floating reference, it is
    /// consumed.
    extern fn gck_session_generate_key_pair_async(p_self: *Session, p_mechanism: *gck.Mechanism, p_public_attrs: *gck.Attributes, p_private_attrs: *gck.Attributes, p_cancellable: ?*gio.Cancellable, p_callback: ?gio.AsyncReadyCallback, p_user_data: ?*anyopaque) void;
    pub const generateKeyPairAsync = gck_session_generate_key_pair_async;

    /// Get the result of a generate key pair operation.
    extern fn gck_session_generate_key_pair_finish(p_self: *Session, p_result: *gio.AsyncResult, p_public_key: ?**gck.Object, p_private_key: ?**gck.Object, p_error: ?*?*glib.Error) c_int;
    pub const generateKeyPairFinish = gck_session_generate_key_pair_finish;

    /// Generate a new key pair of public and private keys. This call may block for an
    /// indefinite period.
    ///
    /// If `public_attrs` and/or `private_attrs` is a floating reference, it is
    /// consumed.
    extern fn gck_session_generate_key_pair_full(p_self: *Session, p_mechanism: *gck.Mechanism, p_public_attrs: *gck.Attributes, p_private_attrs: *gck.Attributes, p_public_key: ?**gck.Object, p_private_key: ?**gck.Object, p_cancellable: ?*gio.Cancellable, p_error: ?*?*glib.Error) c_int;
    pub const generateKeyPairFull = gck_session_generate_key_pair_full;

    /// Get the raw PKCS`@"11"` session handle from a session object.
    extern fn gck_session_get_handle(p_self: *Session) c_ulong;
    pub const getHandle = gck_session_get_handle;

    /// Get information about the session.
    extern fn gck_session_get_info(p_self: *Session) *gck.SessionInfo;
    pub const getInfo = gck_session_get_info;

    /// Get the interaction object set on this session, which is used to prompt
    /// for pins and the like.
    extern fn gck_session_get_interaction(p_self: *Session) ?*gio.TlsInteraction;
    pub const getInteraction = gck_session_get_interaction;

    /// Get the PKCS`@"11"` module to which this session belongs.
    extern fn gck_session_get_module(p_self: *Session) *gck.Module;
    pub const getModule = gck_session_get_module;

    /// Get the options this session was opened with.
    extern fn gck_session_get_options(p_self: *Session) gck.SessionOptions;
    pub const getOptions = gck_session_get_options;

    /// Get the PKCS`@"11"` slot to which this session belongs.
    extern fn gck_session_get_slot(p_self: *Session) *gck.Slot;
    pub const getSlot = gck_session_get_slot;

    /// Get the session state. The state is the various PKCS`@"11"` CKS_XXX flags.
    extern fn gck_session_get_state(p_self: *Session) c_ulong;
    pub const getState = gck_session_get_state;

    /// Initialize the user's pin on this slot that this session is opened on.
    /// According to the PKCS`@"11"` standards, the session must be logged in with
    /// the CKU_SO user type.
    ///
    /// This call may block for an indefinite period.
    extern fn gck_session_init_pin(p_self: *Session, p_pin: ?[*]const u8, p_n_pin: usize, p_cancellable: ?*gio.Cancellable, p_error: ?*?*glib.Error) c_int;
    pub const initPin = gck_session_init_pin;

    /// Initialize the user's pin on this slot that this session is opened on.
    /// According to the PKCS`@"11"` standards, the session must be logged in with
    /// the `CKU_SO` user type.
    ///
    /// This call will return immediately and completes asynchronously.
    extern fn gck_session_init_pin_async(p_self: *Session, p_pin: ?[*]const u8, p_n_pin: usize, p_cancellable: ?*gio.Cancellable, p_callback: ?gio.AsyncReadyCallback, p_user_data: ?*anyopaque) void;
    pub const initPinAsync = gck_session_init_pin_async;

    /// Get the result of initializing a user's PIN.
    extern fn gck_session_init_pin_finish(p_self: *Session, p_result: *gio.AsyncResult, p_error: ?*?*glib.Error) c_int;
    pub const initPinFinish = gck_session_init_pin_finish;

    /// Login the user on the session. This call may block for
    /// an indefinite period.
    extern fn gck_session_login(p_self: *Session, p_user_type: c_ulong, p_pin: ?[*]const u8, p_n_pin: usize, p_cancellable: ?*gio.Cancellable, p_error: ?*?*glib.Error) c_int;
    pub const login = gck_session_login;

    /// Login the user on the session. This call will return
    /// immediately and completes asynchronously.
    extern fn gck_session_login_async(p_self: *Session, p_user_type: c_ulong, p_pin: ?[*]const u8, p_n_pin: usize, p_cancellable: ?*gio.Cancellable, p_callback: ?gio.AsyncReadyCallback, p_user_data: ?*anyopaque) void;
    pub const loginAsync = gck_session_login_async;

    /// Get the result of a login operation.
    extern fn gck_session_login_finish(p_self: *Session, p_result: *gio.AsyncResult, p_error: ?*?*glib.Error) c_int;
    pub const loginFinish = gck_session_login_finish;

    /// Login the user on the session requesting the password interactively
    /// when necessary. This call may block for an indefinite period.
    extern fn gck_session_login_interactive(p_self: *Session, p_user_type: c_ulong, p_interaction: ?*gio.TlsInteraction, p_cancellable: ?*gio.Cancellable, p_error: ?*?*glib.Error) c_int;
    pub const loginInteractive = gck_session_login_interactive;

    /// Login the user on the session prompting for passwords interactively when
    /// necessary. This call will return immediately and completes asynchronously.
    extern fn gck_session_login_interactive_async(p_self: *Session, p_user_type: c_ulong, p_interaction: ?*gio.TlsInteraction, p_cancellable: ?*gio.Cancellable, p_callback: ?gio.AsyncReadyCallback, p_user_data: ?*anyopaque) void;
    pub const loginInteractiveAsync = gck_session_login_interactive_async;

    /// Get the result of a login operation.
    extern fn gck_session_login_interactive_finish(p_self: *Session, p_result: *gio.AsyncResult, p_error: ?*?*glib.Error) c_int;
    pub const loginInteractiveFinish = gck_session_login_interactive_finish;

    /// Log out of the session. This call may block for an indefinite period.
    extern fn gck_session_logout(p_self: *Session, p_cancellable: ?*gio.Cancellable, p_error: ?*?*glib.Error) c_int;
    pub const logout = gck_session_logout;

    /// Log out of the session. This call returns immediately and completes
    /// asynchronously.
    extern fn gck_session_logout_async(p_self: *Session, p_cancellable: ?*gio.Cancellable, p_callback: ?gio.AsyncReadyCallback, p_user_data: ?*anyopaque) void;
    pub const logoutAsync = gck_session_logout_async;

    /// Get the result of logging out of a session.
    extern fn gck_session_logout_finish(p_self: *Session, p_result: *gio.AsyncResult, p_error: ?*?*glib.Error) c_int;
    pub const logoutFinish = gck_session_logout_finish;

    /// Set the interaction object on this session, which is used to prompt for
    /// pins and the like.
    extern fn gck_session_set_interaction(p_self: *Session, p_interaction: ?*gio.TlsInteraction) void;
    pub const setInteraction = gck_session_set_interaction;

    /// Change the user's pin on this slot that this session is opened on.
    ///
    /// This call may block for an indefinite period.
    extern fn gck_session_set_pin(p_self: *Session, p_old_pin: ?[*]const u8, p_n_old_pin: usize, p_new_pin: ?[*]const u8, p_n_new_pin: usize, p_cancellable: ?*gio.Cancellable, p_error: ?*?*glib.Error) c_int;
    pub const setPin = gck_session_set_pin;

    /// Change the user's pin on this slot that this session is opened on.
    ///
    /// This call will return immediately and completes asynchronously.
    extern fn gck_session_set_pin_async(p_self: *Session, p_old_pin: ?[*]const u8, p_n_old_pin: usize, p_new_pin: ?[*]const u8, p_n_new_pin: usize, p_cancellable: ?*gio.Cancellable, p_callback: ?gio.AsyncReadyCallback, p_user_data: ?*anyopaque) void;
    pub const setPinAsync = gck_session_set_pin_async;

    /// Get the result of changing a user's PIN.
    extern fn gck_session_set_pin_finish(p_self: *Session, p_result: *gio.AsyncResult, p_error: ?*?*glib.Error) c_int;
    pub const setPinFinish = gck_session_set_pin_finish;

    /// Sign data in a mechanism specific manner. This call may
    /// block for an indefinite period.
    extern fn gck_session_sign(p_self: *Session, p_key: *gck.Object, p_mech_type: c_ulong, p_input: [*]const u8, p_n_input: usize, p_n_result: *usize, p_cancellable: ?*gio.Cancellable, p_error: ?*?*glib.Error) ?[*]u8;
    pub const sign = gck_session_sign;

    /// Sign data in a mechanism specific manner. This call will
    /// return immediately and complete asynchronously.
    extern fn gck_session_sign_async(p_self: *Session, p_key: *gck.Object, p_mechanism: *gck.Mechanism, p_input: [*]const u8, p_n_input: usize, p_cancellable: ?*gio.Cancellable, p_callback: ?gio.AsyncReadyCallback, p_user_data: ?*anyopaque) void;
    pub const signAsync = gck_session_sign_async;

    /// Get the result of an signing operation.
    extern fn gck_session_sign_finish(p_self: *Session, p_result: *gio.AsyncResult, p_n_result: *usize, p_error: ?*?*glib.Error) ?[*]u8;
    pub const signFinish = gck_session_sign_finish;

    /// Sign data in a mechanism specific manner. This call may
    /// block for an indefinite period.
    extern fn gck_session_sign_full(p_self: *Session, p_key: *gck.Object, p_mechanism: *gck.Mechanism, p_input: [*]const u8, p_n_input: usize, p_n_result: *usize, p_cancellable: ?*gio.Cancellable, p_error: ?*?*glib.Error) ?*u8;
    pub const signFull = gck_session_sign_full;

    /// Unwrap a key from a byte stream. This call may block for an
    /// indefinite period.
    ///
    /// If `attrs` is a floating reference, it is consumed.
    extern fn gck_session_unwrap_key(p_self: *Session, p_wrapper: *gck.Object, p_mech_type: c_ulong, p_input: [*]const u8, p_n_input: usize, p_attrs: *gck.Attributes, p_cancellable: ?*gio.Cancellable, p_error: ?*?*glib.Error) ?*gck.Object;
    pub const unwrapKey = gck_session_unwrap_key;

    /// Unwrap a key from a byte stream. This call will
    /// return immediately and complete asynchronously.
    ///
    /// If `attrs` is a floating reference, it is consumed.
    extern fn gck_session_unwrap_key_async(p_self: *Session, p_wrapper: *gck.Object, p_mechanism: *gck.Mechanism, p_input: [*]const u8, p_n_input: usize, p_attrs: *gck.Attributes, p_cancellable: ?*gio.Cancellable, p_callback: ?gio.AsyncReadyCallback, p_user_data: ?*anyopaque) void;
    pub const unwrapKeyAsync = gck_session_unwrap_key_async;

    /// Get the result of a unwrap key operation.
    extern fn gck_session_unwrap_key_finish(p_self: *Session, p_result: *gio.AsyncResult, p_error: ?*?*glib.Error) ?*gck.Object;
    pub const unwrapKeyFinish = gck_session_unwrap_key_finish;

    /// Unwrap a key from a byte stream. This call may block for an
    /// indefinite period.
    ///
    /// If `attrs` is a floating reference, it is consumed.
    extern fn gck_session_unwrap_key_full(p_self: *Session, p_wrapper: *gck.Object, p_mechanism: *gck.Mechanism, p_input: [*]const u8, p_n_input: usize, p_attrs: *gck.Attributes, p_cancellable: ?*gio.Cancellable, p_error: ?*?*glib.Error) ?*gck.Object;
    pub const unwrapKeyFull = gck_session_unwrap_key_full;

    /// Verify data in a mechanism specific manner. This call may
    /// block for an indefinite period.
    extern fn gck_session_verify(p_self: *Session, p_key: *gck.Object, p_mech_type: c_ulong, p_input: [*]const u8, p_n_input: usize, p_signature: [*]const u8, p_n_signature: usize, p_cancellable: ?*gio.Cancellable, p_error: ?*?*glib.Error) c_int;
    pub const verify = gck_session_verify;

    /// Verify data in a mechanism specific manner. This call returns
    /// immediately and completes asynchronously.
    extern fn gck_session_verify_async(p_self: *Session, p_key: *gck.Object, p_mechanism: *gck.Mechanism, p_input: [*]const u8, p_n_input: usize, p_signature: [*]const u8, p_n_signature: usize, p_cancellable: ?*gio.Cancellable, p_callback: ?gio.AsyncReadyCallback, p_user_data: ?*anyopaque) void;
    pub const verifyAsync = gck_session_verify_async;

    /// Get the result of an verify operation.
    extern fn gck_session_verify_finish(p_self: *Session, p_result: *gio.AsyncResult, p_error: ?*?*glib.Error) c_int;
    pub const verifyFinish = gck_session_verify_finish;

    /// Verify data in a mechanism specific manner. This call may
    /// block for an indefinite period.
    extern fn gck_session_verify_full(p_self: *Session, p_key: *gck.Object, p_mechanism: *gck.Mechanism, p_input: [*]const u8, p_n_input: usize, p_signature: [*]const u8, p_n_signature: usize, p_cancellable: ?*gio.Cancellable, p_error: ?*?*glib.Error) c_int;
    pub const verifyFull = gck_session_verify_full;

    /// Wrap a key into a byte stream. This call may block for an
    /// indefinite period.
    extern fn gck_session_wrap_key(p_self: *Session, p_wrapper: *gck.Object, p_mech_type: c_ulong, p_wrapped: *gck.Object, p_n_result: *usize, p_cancellable: ?*gio.Cancellable, p_error: ?*?*glib.Error) ?[*]u8;
    pub const wrapKey = gck_session_wrap_key;

    /// Wrap a key into a byte stream. This call will
    /// return immediately and complete asynchronously.
    extern fn gck_session_wrap_key_async(p_self: *Session, p_wrapper: *gck.Object, p_mechanism: *gck.Mechanism, p_wrapped: *gck.Object, p_cancellable: ?*gio.Cancellable, p_callback: ?gio.AsyncReadyCallback, p_user_data: ?*anyopaque) void;
    pub const wrapKeyAsync = gck_session_wrap_key_async;

    /// Get the result of a wrap key operation.
    extern fn gck_session_wrap_key_finish(p_self: *Session, p_result: *gio.AsyncResult, p_n_result: *usize, p_error: ?*?*glib.Error) ?[*]u8;
    pub const wrapKeyFinish = gck_session_wrap_key_finish;

    /// Wrap a key into a byte stream. This call may block for an
    /// indefinite period.
    extern fn gck_session_wrap_key_full(p_self: *Session, p_wrapper: *gck.Object, p_mechanism: *gck.Mechanism, p_wrapped: *gck.Object, p_n_result: *usize, p_cancellable: ?*gio.Cancellable, p_error: ?*?*glib.Error) ?[*]u8;
    pub const wrapKeyFull = gck_session_wrap_key_full;

    extern fn gck_session_get_type() usize;
    pub const getGObjectType = gck_session_get_type;

    extern fn g_object_ref(p_self: *gck.Session) void;
    pub const ref = g_object_ref;

    extern fn g_object_unref(p_self: *gck.Session) void;
    pub const unref = g_object_unref;

    pub fn as(p_instance: *Session, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// Represents a PKCS`@"11"` slot that can contain a token.
///
/// A PKCS`@"11"` slot can contain a token. As an example, a slot might be a card
/// reader, and the token the card. If the PKCS`@"11"` module is not a hardware
/// driver, often the slot and token are equivalent.
pub const Slot = extern struct {
    pub const Parent = gobject.Object;
    pub const Implements = [_]type{};
    pub const Class = gck.SlotClass;
    f_parent: gobject.Object,
    f_pv: ?*gck.SlotPrivate,
    f_reserved: [4]*anyopaque,

    pub const virtual_methods = struct {};

    pub const properties = struct {
        /// The raw CK_SLOT_ID handle of this slot.
        pub const handle = struct {
            pub const name = "handle";

            pub const Type = c_ulong;
        };

        /// The PKCS11 object that this slot is a part of.
        pub const module = struct {
            pub const name = "module";

            pub const Type = ?*gck.Module;
        };
    };

    pub const signals = struct {};

    /// Create a new GckSlot object for a raw PKCS`@"11"` handle.
    extern fn gck_slot_from_handle(p_module: *gck.Module, p_slot_id: c_ulong) *gck.Slot;
    pub const fromHandle = gck_slot_from_handle;

    /// Setup an enumerator for listing matching objects on the slot.
    ///
    /// If the `match` `gck.Attributes` is floating, it is consumed.
    ///
    /// This call will not block but will return an enumerator immediately.
    extern fn gck_slot_enumerate_objects(p_self: *Slot, p_match: *gck.Attributes, p_options: gck.SessionOptions) *gck.Enumerator;
    pub const enumerateObjects = gck_slot_enumerate_objects;

    /// Checks equality of two slots. Two GckSlot objects can point to the same
    /// underlying PKCS`@"11"` slot.
    extern fn gck_slot_equal(p_slot1: *const Slot, p_slot2: *const gck.Slot) c_int;
    pub const equal = gck_slot_equal;

    /// Get the raw PKCS`@"11"` handle of a slot.
    extern fn gck_slot_get_handle(p_self: *Slot) c_ulong;
    pub const getHandle = gck_slot_get_handle;

    /// Get the information for this slot.
    extern fn gck_slot_get_info(p_self: *Slot) *gck.SlotInfo;
    pub const getInfo = gck_slot_get_info;

    /// Get information for the specified mechanism.
    extern fn gck_slot_get_mechanism_info(p_self: *Slot, p_mech_type: c_ulong) *gck.MechanismInfo;
    pub const getMechanismInfo = gck_slot_get_mechanism_info;

    /// Get the available mechanisms for this slot.
    extern fn gck_slot_get_mechanisms(p_self: *Slot) *glib.Array;
    pub const getMechanisms = gck_slot_get_mechanisms;

    /// Get the module that this slot is on.
    extern fn gck_slot_get_module(p_self: *Slot) *gck.Module;
    pub const getModule = gck_slot_get_module;

    /// Get the token information for this slot.
    extern fn gck_slot_get_token_info(p_self: *Slot) *gck.TokenInfo;
    pub const getTokenInfo = gck_slot_get_token_info;

    /// Check if the PKCS11 slot has the given flags.
    extern fn gck_slot_has_flags(p_self: *Slot, p_flags: c_ulong) c_int;
    pub const hasFlags = gck_slot_has_flags;

    /// Create a hash value for the GckSlot.
    ///
    /// This function is intended for easily hashing a GckSlot to add to
    /// a GHashTable or similar data structure.
    extern fn gck_slot_hash(p_slot: *const Slot) c_uint;
    pub const hash = gck_slot_hash;

    /// Check whether the PKCS`@"11"` URI matches the slot
    extern fn gck_slot_match(p_self: *Slot, p_uri: *gck.UriData) c_int;
    pub const match = gck_slot_match;

    /// Open a session on the slot. If the 'auto reuse' setting is set,
    /// then this may be a recycled session with the same flags.
    ///
    /// This call may block for an indefinite period.
    extern fn gck_slot_open_session(p_self: *Slot, p_options: gck.SessionOptions, p_cancellable: ?*gio.Cancellable, p_error: ?*?*glib.Error) ?*gck.Session;
    pub const openSession = gck_slot_open_session;

    /// Open a session on the slot. If the 'auto reuse' setting is set,
    /// then this may be a recycled session with the same flags.
    ///
    /// This call will return immediately and complete asynchronously.
    extern fn gck_slot_open_session_async(p_self: *Slot, p_options: gck.SessionOptions, p_cancellable: ?*gio.Cancellable, p_callback: ?gio.AsyncReadyCallback, p_user_data: ?*anyopaque) void;
    pub const openSessionAsync = gck_slot_open_session_async;

    /// Get the result of an open session operation. If the 'auto reuse' setting is set,
    /// then this may be a recycled session with the same flags.
    extern fn gck_slot_open_session_finish(p_self: *Slot, p_result: *gio.AsyncResult, p_error: ?*?*glib.Error) ?*gck.Session;
    pub const openSessionFinish = gck_slot_open_session_finish;

    /// Open a session on the slot. If the 'auto reuse' setting is set,
    /// then this may be a recycled session with the same flags.
    ///
    /// This call may block for an indefinite period.
    extern fn gck_slot_open_session_full(p_self: *Slot, p_options: gck.SessionOptions, p_pkcs11_flags: c_ulong, p_app_data: ?*anyopaque, p_notify: *anyopaque, p_cancellable: ?*gio.Cancellable, p_error: ?*?*glib.Error) ?*gck.Session;
    pub const openSessionFull = gck_slot_open_session_full;

    /// Open a session on the slot. If the 'auto reuse' setting is set,
    /// then this may be a recycled session with the same flags.
    ///
    /// This call will return immediately and complete asynchronously.
    extern fn gck_slot_open_session_full_async(p_self: *Slot, p_options: gck.SessionOptions, p_pkcs11_flags: c_ulong, p_app_data: ?*anyopaque, p_notify: *anyopaque, p_cancellable: ?*gio.Cancellable, p_callback: ?gio.AsyncReadyCallback, p_user_data: ?*anyopaque) void;
    pub const openSessionFullAsync = gck_slot_open_session_full_async;

    extern fn gck_slot_get_type() usize;
    pub const getGObjectType = gck_slot_get_type;

    extern fn g_object_ref(p_self: *gck.Slot) void;
    pub const ref = g_object_ref;

    extern fn g_object_unref(p_self: *gck.Slot) void;
    pub const unref = g_object_unref;

    pub fn as(p_instance: *Slot, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// An interface implemented by derived classes of `Object` to indicate
/// which attributes they'd like an enumerator to retrieve.
///
/// These attributes are then cached on the object and can be retrieved through
/// the `ObjectCache.properties.attributes` property.
pub const ObjectCache = opaque {
    pub const Prerequisites = [_]type{gck.Object};
    pub const Iface = gck.ObjectCacheIface;
    pub const virtual_methods = struct {
        /// Adds the attributes to the set cached on this object. If an attribute is
        /// already present in the cache it will be overridden by this value.
        ///
        /// This will be done in a thread-safe manner.
        ///
        /// If the `attrs` `gck.Attributes` is floating, it is consumed.
        pub const fill = struct {
            pub fn call(p_class: anytype, p_object: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_attrs: *gck.Attributes) void {
                return gobject.ext.as(ObjectCache.Iface, p_class).f_fill.?(gobject.ext.as(ObjectCache, p_object), p_attrs);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_object: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_attrs: *gck.Attributes) callconv(.c) void) void {
                gobject.ext.as(ObjectCache.Iface, p_class).f_fill = @ptrCast(p_implementation);
            }
        };
    };

    pub const properties = struct {
        /// The attributes cached on this object.
        pub const attributes = struct {
            pub const name = "attributes";

            pub const Type = ?*gck.Attributes;
        };
    };

    pub const signals = struct {};

    /// Adds the attributes to the set cached on this object. If an attribute is
    /// already present in the cache it will be overridden by this value.
    ///
    /// This will be done in a thread-safe manner.
    ///
    /// If the `attrs` `gck.Attributes` is floating, it is consumed.
    extern fn gck_object_cache_fill(p_object: *ObjectCache, p_attrs: *gck.Attributes) void;
    pub const fill = gck_object_cache_fill;

    /// Gets the attributes cached on this object.
    extern fn gck_object_cache_get_attributes(p_object: *ObjectCache) ?*gck.Attributes;
    pub const getAttributes = gck_object_cache_get_attributes;

    /// Sets the attributes cached on this object.
    ///
    /// If the `attrs` `gck.Attributes` is floating, it is consumed.
    extern fn gck_object_cache_set_attributes(p_object: *ObjectCache, p_attrs: ?*gck.Attributes) void;
    pub const setAttributes = gck_object_cache_set_attributes;

    /// Update the object cache with given attributes. If an attribute already
    /// exists in the cache, it will be updated, and if it doesn't it will be added.
    ///
    /// This may block, use the asynchronous version when this is not desirable
    extern fn gck_object_cache_update(p_object: *ObjectCache, p_attr_types: [*]const c_ulong, p_n_attr_types: c_int, p_cancellable: ?*gio.Cancellable, p_error: ?*?*glib.Error) c_int;
    pub const update = gck_object_cache_update;

    /// Update the object cache with given attributes. If an attribute already
    /// exists in the cache, it will be updated, and if it doesn't it will be added.
    ///
    /// This call will return immediately and complete asynchronously.
    extern fn gck_object_cache_update_async(p_object: *ObjectCache, p_attr_types: [*]const c_ulong, p_n_attr_types: c_int, p_cancellable: ?*gio.Cancellable, p_callback: ?gio.AsyncReadyCallback, p_user_data: ?*anyopaque) void;
    pub const updateAsync = gck_object_cache_update_async;

    /// Complete an asynchronous operation to update the object cache with given
    /// attributes.
    extern fn gck_object_cache_update_finish(p_object: *ObjectCache, p_result: *gio.AsyncResult, p_error: ?*?*glib.Error) c_int;
    pub const updateFinish = gck_object_cache_update_finish;

    extern fn gck_object_cache_get_type() usize;
    pub const getGObjectType = gck_object_cache_get_type;

    extern fn g_object_ref(p_self: *gck.ObjectCache) void;
    pub const ref = g_object_ref;

    extern fn g_object_unref(p_self: *gck.ObjectCache) void;
    pub const unref = g_object_unref;

    pub fn as(p_instance: *ObjectCache, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// This structure represents a PKCS`@"11"` `CK_ATTRIBUTE`. These attributes contain
/// information about a PKCS`@"11"` object. Use `Object.get` or
/// `Object.set` to set and attributes on an object.
///
/// Although you are free to allocate a `GckAttribute` in your own code, no
/// functions in this library will operate on such an attribute.
pub const Attribute = extern struct {
    /// The attribute type, such as `CKA_LABEL`.
    f_type: c_ulong,
    /// The value of the attribute. May be `NULL`.
    f_value: ?[*]u8,
    /// The length of the attribute. May be `INVALID` if the
    /// attribute is invalid.
    f_length: c_ulong,

    /// Create a new PKCS`@"11"` attribute. The value will be copied
    /// into the new attribute.
    extern fn gck_attribute_new(p_attr_type: c_ulong, p_value: *const u8, p_length: usize) *gck.Attribute;
    pub const new = gck_attribute_new;

    /// Initialize a PKCS`@"11"` attribute to boolean. This will result
    /// in a CK_BBOOL attribute from the PKCS`@"11"` specs.
    extern fn gck_attribute_new_boolean(p_attr_type: c_ulong, p_value: c_int) *gck.Attribute;
    pub const newBoolean = gck_attribute_new_boolean;

    /// Initialize a PKCS`@"11"` attribute to a date. This will result
    /// in a CK_DATE attribute from the PKCS`@"11"` specs.
    extern fn gck_attribute_new_date(p_attr_type: c_ulong, p_value: *const glib.Date) *gck.Attribute;
    pub const newDate = gck_attribute_new_date;

    /// Create a new PKCS`@"11"` attribute with empty data.
    extern fn gck_attribute_new_empty(p_attr_type: c_ulong) *gck.Attribute;
    pub const newEmpty = gck_attribute_new_empty;

    /// Create a new PKCS`@"11"` attribute as 'invalid' or 'not found'
    /// state. Specifically this sets the value length to (CK_ULONG)-1
    /// as specified in the PKCS`@"11"` specification.
    extern fn gck_attribute_new_invalid(p_attr_type: c_ulong) *gck.Attribute;
    pub const newInvalid = gck_attribute_new_invalid;

    /// Initialize a PKCS`@"11"` attribute to a string. This will result
    /// in an attribute containing the text, but not the null terminator.
    /// The text in the attribute will be of the same encoding as you pass
    /// to this function.
    extern fn gck_attribute_new_string(p_attr_type: c_ulong, p_value: [*:0]const u8) *gck.Attribute;
    pub const newString = gck_attribute_new_string;

    /// Initialize a PKCS`@"11"` attribute to a unsigned long. This will result
    /// in a `CK_ULONG` attribute from the PKCS`@"11"` specs.
    extern fn gck_attribute_new_ulong(p_attr_type: c_ulong, p_value: c_ulong) *gck.Attribute;
    pub const newUlong = gck_attribute_new_ulong;

    /// Clear allocated memory held by a `gck.Attribute`.
    ///
    /// This attribute must have been allocated by a Gck library function, or
    /// the results of this method are undefined.
    ///
    /// The type of the attribute will remain set.
    extern fn gck_attribute_clear(p_attr: *Attribute) void;
    pub const clear = gck_attribute_clear;

    /// Dump the specified attribute using `glib.printerr`.
    extern fn gck_attribute_dump(p_attr: *const Attribute) void;
    pub const dump = gck_attribute_dump;

    /// Duplicate the PKCS`@"11"` attribute. All value memory is
    /// also copied.
    ///
    /// The `attr` must have been allocated or initialized by a Gck function or
    /// the results of this function are undefined.
    extern fn gck_attribute_dup(p_attr: *const Attribute) *gck.Attribute;
    pub const dup = gck_attribute_dup;

    /// Compare two attributes. Useful with <code>GHashTable</code>.
    extern fn gck_attribute_equal(p_attr1: *const Attribute, p_attr2: *const gck.Attribute) c_int;
    pub const equal = gck_attribute_equal;

    /// Free an attribute and its allocated memory. These is usually
    /// used with attributes that are allocated by `Attribute.new`
    /// or a similar function.
    extern fn gck_attribute_free(p_attr: *Attribute) void;
    pub const free = gck_attribute_free;

    /// Get the CK_BBOOL of a PKCS`@"11"` attribute. No conversion
    /// is performed. It is an error to pass an attribute to this
    /// function unless you're know it's supposed to contain a
    /// boolean value.
    extern fn gck_attribute_get_boolean(p_attr: *const Attribute) c_int;
    pub const getBoolean = gck_attribute_get_boolean;

    /// Get the raw value in the attribute.
    ///
    /// This is useful from scripting languages. C callers will generally
    /// access the `gck.Attribute` struct directly.
    ///
    /// This function will `NULL` if the attribute contains empty or invalid
    /// data. The returned data must not be modified and is only valid
    /// as long as this `attribute`.
    extern fn gck_attribute_get_data(p_attr: *const Attribute, p_length: *usize) [*]const u8;
    pub const getData = gck_attribute_get_data;

    /// Get the CK_DATE of a PKCS`@"11"` attribute. No
    /// conversion is performed. It is an error to pass an attribute
    /// to this function unless you're know it's supposed to contain
    /// a value of the right type.
    extern fn gck_attribute_get_date(p_attr: *const Attribute, p_value: *glib.Date) void;
    pub const getDate = gck_attribute_get_date;

    /// Get the string value of a PKCS`@"11"` attribute. No
    /// conversion is performed. It is an error to pass an attribute
    /// to this function unless you're know it's supposed to contain
    /// a value of the right type.
    extern fn gck_attribute_get_string(p_attr: *const Attribute) ?[*:0]u8;
    pub const getString = gck_attribute_get_string;

    /// Get the CK_ULONG value of a PKCS`@"11"` attribute. No
    /// conversion is performed. It is an error to pass an attribute
    /// to this function unless you're know it's supposed to contain
    /// a value of the right type.
    extern fn gck_attribute_get_ulong(p_attr: *const Attribute) c_ulong;
    pub const getUlong = gck_attribute_get_ulong;

    /// Hash an attribute for use in <code>GHashTable</code> keys.
    extern fn gck_attribute_hash(p_attr: *const Attribute) c_uint;
    pub const hash = gck_attribute_hash;

    /// Initialize a PKCS`@"11"` attribute. This copies the value memory
    /// into an internal buffer.
    ///
    /// When done with the attribute you should use `Attribute.clear`
    /// to free the internal memory.
    extern fn gck_attribute_init(p_attr: *Attribute, p_attr_type: c_ulong, p_value: [*]const u8, p_length: usize) void;
    pub const init = gck_attribute_init;

    /// Initialize a PKCS`@"11"` attribute to boolean. This will result
    /// in a CK_BBOOL attribute from the PKCS`@"11"` specs.
    ///
    /// When done with the attribute you should use `Attribute.clear`
    /// to free the internal memory.
    extern fn gck_attribute_init_boolean(p_attr: *Attribute, p_attr_type: c_ulong, p_value: c_int) void;
    pub const initBoolean = gck_attribute_init_boolean;

    /// Initialize a PKCS`@"11"` attribute as a copy of another attribute.
    /// This copies the value memory as well.
    ///
    /// When done with the copied attribute you should use
    /// `Attribute.clear` to free the internal memory.
    extern fn gck_attribute_init_copy(p_dest: *Attribute, p_src: *const gck.Attribute) void;
    pub const initCopy = gck_attribute_init_copy;

    /// Initialize a PKCS`@"11"` attribute to a date. This will result
    /// in a CK_DATE attribute from the PKCS`@"11"` specs.
    ///
    /// When done with the attribute you should use `Attribute.clear`
    /// to free the internal memory.
    extern fn gck_attribute_init_date(p_attr: *Attribute, p_attr_type: c_ulong, p_value: *const glib.Date) void;
    pub const initDate = gck_attribute_init_date;

    /// Initialize a PKCS`@"11"` attribute to an empty state. The attribute
    /// type will be set, but no data will be set.
    ///
    /// When done with the attribute you should use `Attribute.clear`
    /// to free the internal memory.
    extern fn gck_attribute_init_empty(p_attr: *Attribute, p_attr_type: c_ulong) void;
    pub const initEmpty = gck_attribute_init_empty;

    /// Initialize a PKCS`@"11"` attribute to an 'invalid' or 'not found'
    /// state. Specifically this sets the value length to (CK_ULONG)-1
    /// as specified in the PKCS`@"11"` specification.
    ///
    /// When done with the attribute you should use `Attribute.clear`
    /// to free the internal memory.
    extern fn gck_attribute_init_invalid(p_attr: *Attribute, p_attr_type: c_ulong) void;
    pub const initInvalid = gck_attribute_init_invalid;

    /// Initialize a PKCS`@"11"` attribute to a string. This will result
    /// in an attribute containing the text, but not the null terminator.
    /// The text in the attribute will be of the same encoding as you pass
    /// to this function.
    ///
    /// When done with the attribute you should use `Attribute.clear`
    /// to free the internal memory.
    extern fn gck_attribute_init_string(p_attr: *Attribute, p_attr_type: c_ulong, p_value: [*:0]const u8) void;
    pub const initString = gck_attribute_init_string;

    /// Initialize a PKCS`@"11"` attribute to a unsigned long. This will result
    /// in a CK_ULONG attribute from the PKCS`@"11"` specs.
    ///
    /// When done with the attribute you should use `Attribute.clear`
    /// to free the internal memory.
    extern fn gck_attribute_init_ulong(p_attr: *Attribute, p_attr_type: c_ulong, p_value: c_ulong) void;
    pub const initUlong = gck_attribute_init_ulong;

    /// Check if the PKCS`@"11"` attribute represents 'invalid' or 'not found'
    /// according to the PKCS`@"11"` spec. That is, having length
    /// of (CK_ULONG)-1.
    extern fn gck_attribute_is_invalid(p_attr: *const Attribute) c_int;
    pub const isInvalid = gck_attribute_is_invalid;

    extern fn gck_attribute_get_type() usize;
    pub const getGObjectType = gck_attribute_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// A set of `Attribute` structures.
///
/// These attributes contain information about a PKCS11 object. Use
/// `Object.get` or `Object.set` to set and retrieve attributes on
/// an object.
pub const Attributes = opaque {
    /// Create a new empty `GckAttributes` array.
    ///
    /// The returned set of attributes is floating, and should either be passed to
    /// another gck library function which consumes this floating reference, or if
    /// you wish to keep these attributes around you should ref them with
    /// `gck.Attributes.refSink` and unref them later with `gck.Attributes.unref`.
    extern fn gck_attributes_new(p_reserved: c_ulong) *gck.Attributes;
    pub const new = gck_attributes_new;

    /// Creates an GckAttributes array with empty attributes
    ///
    /// Terminate the argument list with `INVALID`.
    ///
    /// The returned set of attributes is floating, and should either be passed to
    /// another gck library function which consumes this floating reference, or if
    /// you wish to keep these attributes around you should ref them with
    /// `gck.Attributes.refSink` and unref them later with `gck.Attributes.unref`.
    extern fn gck_attributes_new_empty(p_first_type: c_ulong, ...) *gck.Attributes;
    pub const newEmpty = gck_attributes_new_empty;

    /// Get attribute at the specified index in the attribute array.
    ///
    /// Use `Attributes.count` to determine how many attributes are
    /// in the array.
    extern fn gck_attributes_at(p_attrs: *Attributes, p_index: c_uint) *const gck.Attribute;
    pub const at = gck_attributes_at;

    /// Check whether the attributes contain a certain attribute.
    extern fn gck_attributes_contains(p_attrs: *Attributes, p_match: *const gck.Attribute) c_int;
    pub const contains = gck_attributes_contains;

    /// Get the number of attributes in this attribute array.
    extern fn gck_attributes_count(p_attrs: *Attributes) c_ulong;
    pub const count = gck_attributes_count;

    /// Dump the attributes using `glib.printerr`.
    extern fn gck_attributes_dump(p_attrs: *Attributes) void;
    pub const dump = gck_attributes_dump;

    /// Find an attribute with the specified type in the array.
    extern fn gck_attributes_find(p_attrs: *Attributes, p_attr_type: c_ulong) *const gck.Attribute;
    pub const find = gck_attributes_find;

    /// Find an attribute with the specified type in the array.
    ///
    /// The attribute (if found) must be of the right size to store
    /// a boolean value (ie: CK_BBOOL). If the attribute is marked invalid
    /// then it will be treated as not found.
    extern fn gck_attributes_find_boolean(p_attrs: *Attributes, p_attr_type: c_ulong, p_value: *c_int) c_int;
    pub const findBoolean = gck_attributes_find_boolean;

    /// Find an attribute with the specified type in the array.
    ///
    /// The attribute (if found) must be of the right size to store
    /// a date value (ie: CK_DATE). If the attribute is marked invalid
    /// then it will be treated as not found.
    extern fn gck_attributes_find_date(p_attrs: *Attributes, p_attr_type: c_ulong, p_value: *glib.Date) c_int;
    pub const findDate = gck_attributes_find_date;

    /// Find an attribute with the specified type in the array.
    ///
    /// If the attribute is marked invalid then it will be treated as not found.
    /// The resulting string will be null-terminated, and must be freed by the caller
    /// using `glib.free`.
    extern fn gck_attributes_find_string(p_attrs: *Attributes, p_attr_type: c_ulong, p_value: *[*:0]u8) c_int;
    pub const findString = gck_attributes_find_string;

    /// Find an attribute with the specified type in the array.
    ///
    /// The attribute (if found) must be of the right size to store
    /// a unsigned long value (ie: CK_ULONG). If the attribute is marked invalid
    /// then it will be treated as not found.
    extern fn gck_attributes_find_ulong(p_attrs: *Attributes, p_attr_type: c_ulong, p_value: *c_ulong) c_int;
    pub const findUlong = gck_attributes_find_ulong;

    /// Reference this attributes array.
    extern fn gck_attributes_ref(p_attrs: *Attributes) *gck.Attributes;
    pub const ref = gck_attributes_ref;

    /// `gck.Attributes` uses a floating reference count system. `Builder.end`
    /// and `Attributes.newEmpty` both return floating references.
    ///
    /// Calling this function on a `GckAttributes` with a floating
    /// reference will convert the floating reference into a full reference.
    /// Calling this function on a non-floating `GckAttributes` results
    /// in an additional normal reference being added.
    ///
    /// In other words, if the `attrs` is floating, then this call "assumes
    /// ownership" of the floating reference, converting it to a normal
    /// reference.  If the `attrs` is not floating, then this call adds a
    /// new normal reference increasing the reference count by one.
    ///
    /// All Gck library functions that assume ownership of floating references
    /// are documented as such. Essentially any Gck function that performs
    /// an operation using a `gck.Attributes` argument rather than operating on the
    /// attributes themselves, will accept a floating reference.
    extern fn gck_attributes_ref_sink(p_attrs: *Attributes) *gck.Attributes;
    pub const refSink = gck_attributes_ref_sink;

    /// Print out attributes to a string in aform that's useful for debugging
    /// or logging.
    ///
    /// The format of the string returned may change in the future.
    extern fn gck_attributes_to_string(p_attrs: *Attributes) [*:0]u8;
    pub const toString = gck_attributes_to_string;

    /// Unreference this attribute array.
    ///
    /// When all outstanding references are gone, the array will be freed.
    extern fn gck_attributes_unref(p_attrs: ?*Attributes) void;
    pub const unref = gck_attributes_unref;

    extern fn gck_attributes_get_type() usize;
    pub const getGObjectType = gck_attributes_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// A builder for a set of attributes. Add attributes to a builder, and then use
/// `Builder.end` to get the completed `Attributes`.
///
/// The fields of `gck.Builder` are private and not to be accessed directly.
pub const Builder = extern struct {
    f_x: [16]usize,

    /// Unreferences a builder. If this was the last reference then the builder
    /// is freed.
    ///
    /// It is an error to use this function on builders that were allocated on the
    /// stack.
    extern fn gck_builder_unref(p_builder: ?*anyopaque) void;
    pub const unref = gck_builder_unref;

    /// Create a new `GckBuilder` not allocated on the stack, so it can be shared
    /// across a single scope, and referenced / unreferenced.
    ///
    /// Normally a `GckBuilder` is created on the stack, and simply initialized.
    ///
    /// If the `GCK_BUILDER_SECURE_MEMORY` flag is specified then non-pageable memory
    /// will be used for the various values of the attributes in the builder
    extern fn gck_builder_new(p_flags: gck.BuilderFlags) *gck.Builder;
    pub const new = gck_builder_new;

    /// Add all the `attrs` attributes to the builder. The attributes are added
    /// uncondititionally whether or not attributes with the same types already
    /// exist in the builder.
    ///
    /// As an optimization, the attribute memory values are automatically shared
    /// between the attributes and the builder.
    extern fn gck_builder_add_all(p_builder: *Builder, p_attrs: *gck.Attributes) void;
    pub const addAll = gck_builder_add_all;

    /// Add an attribute to the builder. The attribute is added unconditionally whether
    /// or not an attribute with the same type already exists on the builder.
    ///
    /// The `attr` attribute must have been created or owned by the Gck library.
    /// If you call this function on an arbitrary `GckAttribute` that is allocated on
    /// the stack or elsewhere, then this will result in undefined behavior.
    ///
    /// As an optimization, the attribute memory value is automatically shared
    /// between the attribute and the builder.
    extern fn gck_builder_add_attribute(p_builder: *Builder, p_attr: *const gck.Attribute) void;
    pub const addAttribute = gck_builder_add_attribute;

    /// Add a new attribute to the builder for the boolean `value`.
    /// Unconditionally adds a new attribute, even if one with the same `attr_type`
    /// already exists.
    extern fn gck_builder_add_boolean(p_builder: *Builder, p_attr_type: c_ulong, p_value: c_int) void;
    pub const addBoolean = gck_builder_add_boolean;

    /// Add a new attribute to the builder with an arbitrary value. Unconditionally
    /// adds a new attribute, even if one with the same `attr_type` already exists.
    ///
    /// The memory in `value` is copied by the builder.
    ///
    /// `NULL` may be specified for the `value` argument, in which case an empty
    /// attribute is created. `INVALID` may be specified for the length, in
    /// which case an invalid attribute is created in the PKCS`@"11"` style.
    extern fn gck_builder_add_data(p_builder: *Builder, p_attr_type: c_ulong, p_value: ?[*]const u8, p_length: usize) void;
    pub const addData = gck_builder_add_data;

    /// Add a new attribute to the builder for the date `value`.
    /// Unconditionally adds a new attribute, even if one with the same `attr_type`
    /// already exists.
    extern fn gck_builder_add_date(p_builder: *Builder, p_attr_type: c_ulong, p_value: *const glib.Date) void;
    pub const addDate = gck_builder_add_date;

    /// Add a new attribute to the builder that is empty. Unconditionally
    /// adds a new attribute, even if one with the same `attr_type` already exists.
    extern fn gck_builder_add_empty(p_builder: *Builder, p_attr_type: c_ulong) void;
    pub const addEmpty = gck_builder_add_empty;

    /// Add the attributes in `attrs` to the builder, with the exception of those
    /// in the argument list. The attributes are added uncondititionally whether or
    /// not attributes with the same types already exist in the builder.
    ///
    /// The variable arguments must be unsigned longs.
    ///
    /// ```c
    /// // Add all attributes in attrs except CKA_CLASS to the builder
    /// gck_builder_add_except (builder, attrs, CKA_CLASS, GCK_INVALID);
    /// ```
    ///
    /// As an optimization, the attribute memory values are automatically shared
    /// between the attributes and the builder.
    extern fn gck_builder_add_except(p_builder: *Builder, p_attrs: *gck.Attributes, p_except_type: c_ulong, ...) void;
    pub const addExcept = gck_builder_add_except;

    /// Add the attributes in `attrs` to the builder, with the exception of those
    /// whose types are specified in `except_types`. The attributes are added
    /// uncondititionally whether or not attributes with the same types already
    /// exist in the builder.
    ///
    /// ```c
    /// // Add all attributes in attrs except CKA_CLASS to the builder
    /// unsigned long except_types[] = { CKA_CLASS };
    /// gck_builder_add_exceptv (builder, attrs, except_types, 1);
    /// ```
    ///
    /// As an optimization, the attribute memory values are automatically shared
    /// between the attributes and the builder.
    extern fn gck_builder_add_exceptv(p_builder: *Builder, p_attrs: *gck.Attributes, p_except_types: [*]const c_ulong, p_n_except_types: c_uint) void;
    pub const addExceptv = gck_builder_add_exceptv;

    /// Add a new attribute to the builder that is invalid in the PKCS`@"11"` sense.
    /// Unconditionally adds a new attribute, even if one with the same `attr_type`
    /// already exists.
    extern fn gck_builder_add_invalid(p_builder: *Builder, p_attr_type: c_ulong) void;
    pub const addInvalid = gck_builder_add_invalid;

    /// Add the attributes specified in the argument list from `attrs` to the
    /// builder. The attributes are added uncondititionally whether or not
    /// attributes with the same types already exist in the builder.
    ///
    /// The variable arguments must be unsigned longs.
    ///
    /// ```c
    /// // Add the CKA_ID and CKA_CLASS attributes from attrs to builder
    /// gck_builder_add_only (builder, attrs, CKA_ID, CKA_CLASS, GCK_INVALID);
    /// ```
    ///
    /// As an optimization, the attribute memory values are automatically shared
    /// between the attributes and the builder.
    extern fn gck_builder_add_only(p_builder: *Builder, p_attrs: *gck.Attributes, p_only_type: c_ulong, ...) void;
    pub const addOnly = gck_builder_add_only;

    /// Add the attributes with the types in `only_types` from `attrs` to the
    /// builder. The attributes are added uncondititionally whether or not
    /// attributes with the same types already exist in the builder.
    ///
    /// ```c
    /// // Add the CKA_ID and CKA_CLASS attributes from attrs to builder
    /// gulong only[] = { CKA_ID, CKA_CLASS };
    /// gck_builder_add_onlyv (builder, attrs, only, 2);
    /// ```
    ///
    /// As an optimization, the attribute memory values are automatically shared
    /// between the attributes and the builder.
    extern fn gck_builder_add_onlyv(p_builder: *Builder, p_attrs: *gck.Attributes, p_only_types: [*]const c_ulong, p_n_only_types: c_uint) void;
    pub const addOnlyv = gck_builder_add_onlyv;

    /// Add a new attribute to the builder for the string `value` or `NULL`.
    /// Unconditionally adds a new attribute, even if one with the same `attr_type`
    /// already exists.
    extern fn gck_builder_add_string(p_builder: *Builder, p_attr_type: c_ulong, p_value: ?[*:0]const u8) void;
    pub const addString = gck_builder_add_string;

    /// Add a new attribute to the builder for the unsigned long `value`.
    /// Unconditionally adds a new attribute, even if one with the same `attr_type`
    /// already exists.
    extern fn gck_builder_add_ulong(p_builder: *Builder, p_attr_type: c_ulong, p_value: c_ulong) void;
    pub const addUlong = gck_builder_add_ulong;

    /// Clear the builder and release all allocated memory. The builder may be used
    /// again to build another set of attributes after this function call.
    ///
    /// If memory is shared between this builder and other attributes, then that
    /// memory is only freed when both of them are cleared or unreferenced.
    extern fn gck_builder_clear(p_builder: *Builder) void;
    pub const clear = gck_builder_clear;

    /// Make a copy of the builder and its state. The new builder is allocated
    /// with `Builder.new` and should be freed with `gck.builderUnref`.
    ///
    /// Attribute value memory is automatically shared between the two builders,
    /// and is only freed when both are gone.
    extern fn gck_builder_copy(p_builder: *Builder) *gck.Builder;
    pub const copy = gck_builder_copy;

    /// Complete the `gck.Builder`, and return the attributes contained in the builder.
    /// The `gck.Builder` will be cleared after this function call, and it is no
    /// longer necessary to use `Builder.clear` on it, although it is also
    /// permitted. The builder may be used again to build another set of attributes
    /// after this function call.
    ///
    /// The returned set of attributes is floating, and should either be passed to
    /// another gck library function which consumes this floating reference, or if
    /// you wish to keep these attributes around you should ref them with
    /// `gck.Attributes.refSink` and unref them later with `gck.Attributes.unref`.
    extern fn gck_builder_end(p_builder: *Builder) *gck.Attributes;
    pub const end = gck_builder_end;

    /// Find an attribute in the builder. Both valid and invalid attributes (in
    /// the PKCS`@"11"` sense) are returned. If multiple attributes exist for the given
    /// attribute type, then the first one is returned.
    ///
    /// The returned `Attribute` is owned by the builder and may not be
    /// modified in any way. It is only valid until another attribute is added to or
    /// set on the builder, or until the builder is cleared or unreferenced.
    extern fn gck_builder_find(p_builder: *Builder, p_attr_type: c_ulong) *const gck.Attribute;
    pub const find = gck_builder_find;

    /// Find a boolean attribute in the builder that has the type `attr_type`, is
    /// of the correct boolean size, and is not invalid in the PKCS`@"11"` sense.
    /// If multiple attributes exist for the given attribute type, then the first\
    /// one is returned.
    extern fn gck_builder_find_boolean(p_builder: *Builder, p_attr_type: c_ulong, p_value: *c_int) c_int;
    pub const findBoolean = gck_builder_find_boolean;

    /// Find a date attribute in the builder that has the type `attr_type`, is of
    /// the correct date size, and is not invalid in the PKCS`@"11"` sense.
    /// If multiple attributes exist for the given attribute type, then the first
    /// one is returned.
    extern fn gck_builder_find_date(p_builder: *Builder, p_attr_type: c_ulong, p_value: *glib.Date) c_int;
    pub const findDate = gck_builder_find_date;

    /// Find a string attribute in the builder that has the type `attr_type`, has a
    /// non `NULL` value pointer, and is not invalid in the PKCS`@"11"` sense.
    /// If multiple attributes exist for the given attribute type, then the first
    /// one is returned.
    extern fn gck_builder_find_string(p_builder: *Builder, p_attr_type: c_ulong, p_value: *[*:0]u8) c_int;
    pub const findString = gck_builder_find_string;

    /// Find a unsigned long attribute in the builder that has the type `attr_type`,
    /// is of the correct unsigned long size, and is not invalid in the PKCS`@"11"` sense.
    /// If multiple attributes exist for the given attribute type, then the first
    /// one is returned.
    extern fn gck_builder_find_ulong(p_builder: *Builder, p_attr_type: c_ulong, p_value: *c_ulong) c_int;
    pub const findUlong = gck_builder_find_ulong;

    /// Initialize a stack allocated builder, with the default flags.
    ///
    /// This is equivalent to initializing a builder variable with the
    /// `GCK_BUILDER_INIT` constant, or setting it to zeroed memory.
    ///
    /// ```c
    /// // Equivalent ways of initializing a GckBuilder
    /// GckBuilder builder = GCK_BUILDER_INIT;
    /// GckBuilder builder2;
    /// GckBuilder builder3;
    ///
    /// gck_builder_init (&builder2);
    ///
    /// memset (&builder3, 0, sizeof (builder3));
    /// ```
    extern fn gck_builder_init(p_builder: *Builder) void;
    pub const init = gck_builder_init;

    /// Initialize a stack allocated builder, with the appropriate flags.
    ///
    /// If the `GCK_BUILDER_SECURE_MEMORY` flag is specified then non-pageable memory
    /// will be used for the various values of the attributes in the builder
    extern fn gck_builder_init_full(p_builder: *Builder, p_flags: gck.BuilderFlags) void;
    pub const initFull = gck_builder_init_full;

    /// Add a reference to a builder that was created with `Builder.new`. The
    /// builder must later be unreferenced again with `gck.builderUnref`.
    ///
    /// It is an error to use this function on builders that were allocated on the
    /// stack.
    extern fn gck_builder_ref(p_builder: *Builder) *gck.Builder;
    pub const ref = gck_builder_ref;

    /// Set all the `attrs` attributes to the builder. If any attributes with the
    /// same types are already present in the builder, then those attributes are
    /// changed to the new values.
    ///
    /// As an optimization, the attribute memory values are automatically shared
    /// between the attributes and the builder.
    extern fn gck_builder_set_all(p_builder: *Builder, p_attrs: *gck.Attributes) void;
    pub const setAll = gck_builder_set_all;

    /// Set an attribute on the builder for the boolean `value`.
    /// If an attribute with `attr_type` already exists in the builder then it is
    /// changed to the new value, otherwise an attribute is added.
    extern fn gck_builder_set_boolean(p_builder: *Builder, p_attr_type: c_ulong, p_value: c_int) void;
    pub const setBoolean = gck_builder_set_boolean;

    /// Set a new attribute to the builder with an arbitrary value. If an attribute
    /// with `attr_type` already exists in the builder then it is changed to the new
    /// value, otherwise an attribute is added.
    ///
    /// The memory in `value` is copied by the builder.
    ///
    /// `NULL` may be specified for the `value` argument, in which case an empty
    /// attribute is created. `INVALID` may be specified for the length, in
    /// which case an invalid attribute is created in the PKCS`@"11"` style.
    extern fn gck_builder_set_data(p_builder: *Builder, p_attr_type: c_ulong, p_value: ?[*]const u8, p_length: usize) void;
    pub const setData = gck_builder_set_data;

    /// Set an attribute on the builder for the date `value`.
    /// If an attribute with `attr_type` already exists in the builder then it is
    /// changed to the new value, otherwise an attribute is added.
    extern fn gck_builder_set_date(p_builder: *Builder, p_attr_type: c_ulong, p_value: *const glib.Date) void;
    pub const setDate = gck_builder_set_date;

    /// Set an attribute on the builder that is empty. If an attribute
    /// with `attr_type` already exists in the builder then it is changed to the new
    /// value, otherwise an attribute is added.
    extern fn gck_builder_set_empty(p_builder: *Builder, p_attr_type: c_ulong) void;
    pub const setEmpty = gck_builder_set_empty;

    /// Set an attribute on the builder that is invalid in the PKCS`@"11"` sense.
    /// If an attribute with `attr_type` already exists in the builder then it is
    /// changed to the new value, otherwise an attribute is added.
    extern fn gck_builder_set_invalid(p_builder: *Builder, p_attr_type: c_ulong) void;
    pub const setInvalid = gck_builder_set_invalid;

    /// Set an attribute on the builder for the string `value` or `NULL`.
    /// If an attribute with `attr_type` already exists in the builder then it is
    /// changed to the new value, otherwise an attribute is added.
    extern fn gck_builder_set_string(p_builder: *Builder, p_attr_type: c_ulong, p_value: [*:0]const u8) void;
    pub const setString = gck_builder_set_string;

    /// Set an attribute on the builder for the unsigned long `value`.
    /// If an attribute with `attr_type` already exists in the builder then it is
    /// changed to the new value, otherwise an attribute is added.
    extern fn gck_builder_set_ulong(p_builder: *Builder, p_attr_type: c_ulong, p_value: c_ulong) void;
    pub const setUlong = gck_builder_set_ulong;

    /// Take the attributes that have been built in the `gck.Builder`. The builder
    /// will no longer contain any attributes after this function call.
    ///
    /// The returned set of attributes is a full reference, not floating.
    extern fn gck_builder_steal(p_builder: *Builder) *gck.Attributes;
    pub const steal = gck_builder_steal;

    /// Add a new attribute to the builder with an arbitrary value. Unconditionally
    /// adds a new attribute, even if one with the same `attr_type` already exists.
    ///
    /// Ownership of the `value` memory is taken by the builder, may be reallocated,
    /// and is eventually freed with `glib.free`. The memory must have been allocated
    /// using the standard GLib memory allocation routines.
    ///
    /// `NULL` may be specified for the `value` argument, in which case an empty
    /// attribute is created. `INVALID` may be specified for the length, in
    /// which case an invalid attribute is created in the PKCS`@"11"` style.
    extern fn gck_builder_take_data(p_builder: *Builder, p_attr_type: c_ulong, p_value: ?[*]u8, p_length: usize) void;
    pub const takeData = gck_builder_take_data;

    extern fn gck_builder_get_type() usize;
    pub const getGObjectType = gck_builder_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

pub const EnumeratorClass = extern struct {
    pub const Instance = gck.Enumerator;

    f_parent: gobject.ObjectClass,
    f_reserved: [2]*anyopaque,

    pub fn as(p_instance: *EnumeratorClass, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

pub const EnumeratorPrivate = opaque {
    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// Represents a mechanism used with crypto operations.
pub const Mechanism = extern struct {
    /// The mechanism type
    f_type: c_ulong,
    /// Mechanism specific data.
    f_parameter: ?*const anyopaque,
    /// Length of mechanism specific data.
    f_n_parameter: c_ulong,

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// Represents information about a PKCS11 mechanism.
///
/// This is analogous to a CK_MECHANISM_INFO structure.
///
/// When you're done with this structure it should be released with
/// `gck.MechanismInfo.free`.
pub const MechanismInfo = extern struct {
    /// The minimum key size that can be used with this mechanism.
    f_min_key_size: c_ulong,
    /// The maximum key size that can be used with this mechanism.
    f_max_key_size: c_ulong,
    /// Various PKCS11 flags that apply to this mechanism.
    f_flags: c_ulong,

    /// Make a copy of the mechanism info.
    extern fn gck_mechanism_info_copy(p_mech_info: *MechanismInfo) *gck.MechanismInfo;
    pub const copy = gck_mechanism_info_copy;

    /// Free the GckMechanismInfo and associated resources.
    extern fn gck_mechanism_info_free(p_mech_info: *MechanismInfo) void;
    pub const free = gck_mechanism_info_free;

    extern fn gck_mechanism_info_get_type() usize;
    pub const getGObjectType = gck_mechanism_info_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

pub const ModuleClass = extern struct {
    pub const Instance = gck.Module;

    f_parent: gobject.ObjectClass,
    f_authenticate_slot: ?*const fn (p_self: *gck.Module, p_slot: *gck.Slot, p_label: [*:0]u8, p_password: *[*:0]u8) callconv(.c) c_int,
    f_authenticate_object: ?*const fn (p_self: *gck.Module, p_object: *gck.Object, p_label: [*:0]u8, p_password: *[*:0]u8) callconv(.c) c_int,
    f_reserved: [8]*anyopaque,

    pub fn as(p_instance: *ModuleClass, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// Holds information about the PKCS`@"11"` module.
///
/// This structure corresponds to `CK_MODULE_INFO` in the PKCS`@"11"` standard. The
/// strings are `NULL` terminated for easier use.
///
/// Use `gck.ModuleInfo.free` to release this structure when done with it.
pub const ModuleInfo = extern struct {
    /// The major version of the module.
    f_pkcs11_version_major: u8,
    /// The minor version of the module.
    f_pkcs11_version_minor: u8,
    /// The module manufacturer.
    f_manufacturer_id: ?[*:0]u8,
    /// The module PKCS&num;11 flags.
    f_flags: c_ulong,
    /// The module description.
    f_library_description: ?[*:0]u8,
    /// The major version of the library.
    f_library_version_major: u8,
    /// The minor version of the library.
    f_library_version_minor: u8,

    /// Make a copy of the module info.
    extern fn gck_module_info_copy(p_module_info: *ModuleInfo) *gck.ModuleInfo;
    pub const copy = gck_module_info_copy;

    /// Free a GckModuleInfo structure.
    extern fn gck_module_info_free(p_module_info: *ModuleInfo) void;
    pub const free = gck_module_info_free;

    extern fn gck_module_info_get_type() usize;
    pub const getGObjectType = gck_module_info_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

pub const ModulePrivate = opaque {
    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// Interface for `ObjectCache`. If the `default_types` field is
/// implemented by a implementing class, then that will be used by a
/// `Enumerator` which has been setup using
/// `Enumerator.setObjectType`
///
/// The implementation for `populate` should add the attributes to the
/// cache. It must be thread safe.
pub const ObjectCacheIface = extern struct {
    pub const Instance = gck.ObjectCache;

    /// parent interface
    f_interface: gobject.TypeInterface,
    /// attribute types that an
    ///                   enumerator should retrieve
    f_default_types: ?[*]const c_ulong,
    /// number of attribute types to be retrieved
    f_n_default_types: c_int,
    /// virtual method to add attributes to the cache
    f_fill: ?*const fn (p_object: *gck.ObjectCache, p_attrs: *gck.Attributes) callconv(.c) void,
    f_reserved: [6]*anyopaque,

    pub fn as(p_instance: *ObjectCacheIface, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// The class for a `Object`.
///
/// If the `attribute_types` field is set by a derived class, then the a
/// `gck.Enumerator` which has been setup using `Enumerator.setObjectType`
/// with this derived type will retrieve these attributes when enumerating. In
/// this case the class must implement an 'attributes' property of boxed type
/// `GCK_TYPE_ATTRIBUTES`.
pub const ObjectClass = extern struct {
    pub const Instance = gck.Object;

    /// derived from this
    f_parent: gobject.ObjectClass,
    f_reserved: [8]*anyopaque,

    pub fn as(p_instance: *ObjectClass, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

pub const ObjectPrivate = opaque {
    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// The class struct for `Password`.
pub const PasswordClass = extern struct {
    pub const Instance = gck.Password;

    /// parent class
    f_parent: gio.TlsPasswordClass,
    f_reserved: [4]*anyopaque,

    pub fn as(p_instance: *PasswordClass, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

pub const PasswordPrivate = opaque {
    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

pub const SessionClass = extern struct {
    pub const Instance = gck.Session;

    f_parent: gobject.ObjectClass,
    f_discard_handle: ?*const fn (p_session: *gck.Session, p_handle: c_ulong) callconv(.c) c_int,
    f_reserved: [8]*anyopaque,

    pub fn as(p_instance: *SessionClass, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// Information about the session. This is analogous to a CK_SESSION_INFO structure.
///
/// When done with this structure, release it using `gck.SessionInfo.free`.
pub const SessionInfo = extern struct {
    /// The handle of the PKCS11 slot that this session is opened on.
    f_slot_id: c_ulong,
    /// The user login state of the session.
    f_state: c_ulong,
    /// Various PKCS11 flags.
    f_flags: c_ulong,
    /// The last device error that occurred from an operation on this session.
    f_device_error: c_ulong,

    /// Make a new copy of a session info structure.
    extern fn gck_session_info_copy(p_session_info: *SessionInfo) *gck.SessionInfo;
    pub const copy = gck_session_info_copy;

    /// Free the GckSessionInfo structure and all associated memory.
    extern fn gck_session_info_free(p_session_info: *SessionInfo) void;
    pub const free = gck_session_info_free;

    extern fn gck_session_info_get_type() usize;
    pub const getGObjectType = gck_session_info_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

pub const SessionPrivate = opaque {
    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

pub const SlotClass = extern struct {
    pub const Instance = gck.Slot;

    f_parent: gobject.ObjectClass,
    f_reserved: [9]*anyopaque,

    pub fn as(p_instance: *SlotClass, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// Represents information about a PKCS11 slot.
///
/// This is analogous to a CK_SLOT_INFO structure, but the
/// strings are far more usable.
///
/// When you're done with this structure it should be released with
/// `gck.SlotInfo.free`.
pub const SlotInfo = extern struct {
    /// Description of the slot.
    f_slot_description: ?[*:0]u8,
    /// The manufacturer of this slot.
    f_manufacturer_id: ?[*:0]u8,
    /// Various PKCS11 flags that apply to this slot.
    f_flags: c_ulong,
    /// The major version of the hardware.
    f_hardware_version_major: u8,
    /// The minor version of the hardware.
    f_hardware_version_minor: u8,
    /// The major version of the firmware.
    f_firmware_version_major: u8,
    /// The minor version of the firmware.
    f_firmware_version_minor: u8,

    /// Make a copy of the slot info.
    extern fn gck_slot_info_copy(p_slot_info: *SlotInfo) *gck.SlotInfo;
    pub const copy = gck_slot_info_copy;

    /// Free the GckSlotInfo and associated resources.
    extern fn gck_slot_info_free(p_slot_info: *SlotInfo) void;
    pub const free = gck_slot_info_free;

    extern fn gck_slot_info_get_type() usize;
    pub const getGObjectType = gck_slot_info_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

pub const SlotPrivate = opaque {
    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// Represents information about a PKCS11 token.
///
/// This is analogous to a CK_TOKEN_INFO structure, but the
/// strings are far more usable.
///
/// When you're done with this structure it should be released with
/// `gck.TokenInfo.free`.
pub const TokenInfo = extern struct {
    /// The displayable token label.
    f_label: ?[*:0]u8,
    /// The manufacturer of this slot.
    f_manufacturer_id: ?[*:0]u8,
    /// The token model number as a string.
    f_model: ?[*:0]u8,
    /// The token serial number as a string.
    f_serial_number: ?[*:0]u8,
    /// Various PKCS11 flags that apply to this token.
    f_flags: c_ulong,
    /// The maximum number of sessions allowed on this token.
    f_max_session_count: c_long,
    /// The number of sessions open on this token.
    f_session_count: c_long,
    /// The maximum number of read/write sessions allowed on this token.
    f_max_rw_session_count: c_long,
    /// The number of sessions open on this token.
    f_rw_session_count: c_long,
    /// The maximum length of a PIN for locking this token.
    f_max_pin_len: c_long,
    /// The minimum length of a PIN for locking this token.
    f_min_pin_len: c_long,
    /// The total amount of memory on this token for storing public objects.
    f_total_public_memory: c_long,
    /// The available amount of memory on this token for storing public objects.
    f_free_public_memory: c_long,
    /// The total amount of memory on this token for storing private objects.
    f_total_private_memory: c_long,
    /// The available amount of memory on this token for storing private objects.
    f_free_private_memory: c_long,
    /// The major version of the hardware.
    f_hardware_version_major: u8,
    /// The minor version of the hardware.
    f_hardware_version_minor: u8,
    /// The major version of the firmware.
    f_firmware_version_major: u8,
    /// The minor version of the firmware.
    f_firmware_version_minor: u8,
    /// If the token has a hardware clock, this is set to the number of seconds since the epoch.
    f_utc_time: i64,

    /// Make a copy of the token info.
    extern fn gck_token_info_copy(p_token_info: *TokenInfo) *gck.TokenInfo;
    pub const copy = gck_token_info_copy;

    /// Free the GckTokenInfo and associated resources.
    extern fn gck_token_info_free(p_token_info: *TokenInfo) void;
    pub const free = gck_token_info_free;

    extern fn gck_token_info_get_type() usize;
    pub const getGObjectType = gck_token_info_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// Information about the contents of a PKCS`@"11"` URI. Various fields may be `NULL`
/// depending on the context that the URI was parsed for.
///
/// Since PKCS`@"11"` URIs represent a set which results from the intersections of
/// all of the URI parts, if `any_recognized` is set to `TRUE` then usually the URI
/// should be treated as not matching anything.
pub const UriData = extern struct {
    /// whether any parts of the PKCS`@"11"` URI were unsupported or unrecognized.
    f_any_unrecognized: c_int,
    /// information about the PKCS`@"11"` modules matching the URI.
    f_module_info: ?*gck.ModuleInfo,
    /// information about the PKCS`@"11"` tokens matching the URI.
    f_token_info: ?*gck.TokenInfo,
    /// information about the PKCS`@"11"` objects matching the URI.
    f_attributes: ?*gck.Attributes,
    f_dummy: [4]*anyopaque,

    /// Allocate a new GckUriData structure. None of the fields
    /// will be set.
    extern fn gck_uri_data_new() *gck.UriData;
    pub const new = gck_uri_data_new;

    /// Copy a `gck.UriData`
    extern fn gck_uri_data_copy(p_uri_data: *UriData) *gck.UriData;
    pub const copy = gck_uri_data_copy;

    /// Free a `gck.UriData`.
    extern fn gck_uri_data_free(p_uri_data: *UriData) void;
    pub const free = gck_uri_data_free;

    extern fn gck_uri_data_get_type() usize;
    pub const getGObjectType = gck_uri_data_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// Flags to be used with a `Builder.initFull` and `Builder.new`.
pub const BuilderFlags = enum(c_int) {
    none = 0,
    secure_memory = 1,
    _,

    extern fn gck_builder_flags_get_type() usize;
    pub const getGObjectType = gck_builder_flags_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// Various error codes. All the `CKR_XXX` error codes from PKCS`@"11"` are also
/// relevant error codes.
///
/// Note that errors are returned as `glib.Error` structures. The `code`
/// member of the error then contains the raw PKCS`@"11"` `CK_RV` result value.
pub const Error = enum(c_int) {
    problem = -951891199,
    _,

    extern fn gck_error_get_quark() glib.Quark;
    pub const getQuark = gck_error_get_quark;

    extern fn gck_error_get_type() usize;
    pub const getGObjectType = gck_error_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// Various error codes used with PKCS`@"11"` URIs
pub const UriError = enum(c_int) {
    bad_scheme = 1,
    bad_encoding = 2,
    bad_syntax = 3,
    bad_version = 4,
    not_found = 5,
    _,

    extern fn gck_uri_error_get_quark() glib.Quark;
    pub const getQuark = gck_uri_error_get_quark;

    extern fn gck_uri_error_get_type() usize;
    pub const getGObjectType = gck_uri_error_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// Options for creating sessions.
pub const SessionOptions = packed struct(c_uint) {
    _padding0: bool = false,
    read_write: bool = false,
    login_user: bool = false,
    authenticate: bool = false,
    _padding4: bool = false,
    _padding5: bool = false,
    _padding6: bool = false,
    _padding7: bool = false,
    _padding8: bool = false,
    _padding9: bool = false,
    _padding10: bool = false,
    _padding11: bool = false,
    _padding12: bool = false,
    _padding13: bool = false,
    _padding14: bool = false,
    _padding15: bool = false,
    _padding16: bool = false,
    _padding17: bool = false,
    _padding18: bool = false,
    _padding19: bool = false,
    _padding20: bool = false,
    _padding21: bool = false,
    _padding22: bool = false,
    _padding23: bool = false,
    _padding24: bool = false,
    _padding25: bool = false,
    _padding26: bool = false,
    _padding27: bool = false,
    _padding28: bool = false,
    _padding29: bool = false,
    _padding30: bool = false,
    _padding31: bool = false,

    pub const flags_read_only: SessionOptions = @bitCast(@as(c_uint, 0));
    pub const flags_read_write: SessionOptions = @bitCast(@as(c_uint, 2));
    pub const flags_login_user: SessionOptions = @bitCast(@as(c_uint, 4));
    pub const flags_authenticate: SessionOptions = @bitCast(@as(c_uint, 8));
    extern fn gck_session_options_get_type() usize;
    pub const getGObjectType = gck_session_options_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// Which parts of the PKCS`@"11"` URI will be parsed or formatted. These can be
/// combined.
pub const UriFlags = packed struct(c_uint) {
    _padding0: bool = false,
    for_object: bool = false,
    for_token: bool = false,
    for_module: bool = false,
    with_version: bool = false,
    _padding5: bool = false,
    _padding6: bool = false,
    _padding7: bool = false,
    _padding8: bool = false,
    _padding9: bool = false,
    _padding10: bool = false,
    _padding11: bool = false,
    _padding12: bool = false,
    _padding13: bool = false,
    _padding14: bool = false,
    _padding15: bool = false,
    _padding16: bool = false,
    _padding17: bool = false,
    _padding18: bool = false,
    _padding19: bool = false,
    _padding20: bool = false,
    _padding21: bool = false,
    _padding22: bool = false,
    _padding23: bool = false,
    _padding24: bool = false,
    _padding25: bool = false,
    _padding26: bool = false,
    _padding27: bool = false,
    _padding28: bool = false,
    _padding29: bool = false,
    _padding30: bool = false,
    _padding31: bool = false,

    pub const flags_for_object: UriFlags = @bitCast(@as(c_uint, 2));
    pub const flags_for_token: UriFlags = @bitCast(@as(c_uint, 4));
    pub const flags_for_module: UriFlags = @bitCast(@as(c_uint, 8));
    pub const flags_with_version: UriFlags = @bitCast(@as(c_uint, 16));
    pub const flags_for_any: UriFlags = @bitCast(@as(c_uint, 65535));
    extern fn gck_uri_flags_get_type() usize;
    pub const getGObjectType = gck_uri_flags_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

extern fn gck_list_get_boxed_type() usize;
pub const listGetBoxedType = gck_list_get_boxed_type;

/// Copy a list of GObject based pointers. All objects
/// in the list will be reffed and the list will be copied.
extern fn gck_list_ref_copy(p_reflist: *glib.List) *glib.List;
pub const listRefCopy = gck_list_ref_copy;

/// Free a list of GObject based pointers. All objects in the list
/// will be unreffed and then the list itself will be freed.
extern fn gck_list_unref_free(p_reflist: *glib.List) void;
pub const listUnrefFree = gck_list_unref_free;

/// Check whether all the mechanism types are in the list.
///
/// The arguments should be a list of CKM_XXX mechanism types. The last argument
/// should be GCK_INVALID.
extern fn gck_mechanisms_check(p_mechanisms: *glib.Array, ...) c_int;
pub const mechanismsCheck = gck_mechanisms_check;

/// Get a message for a PKCS`@"11"` return value or error code. Do not
/// pass `CKR_OK` or other non-errors to this function.
extern fn gck_message_from_rv(p_rv: c_ulong) [*:0]const u8;
pub const messageFromRv = gck_message_from_rv;

/// Setup an enumerator for listing matching objects on the modules.
///
/// This call will not block but will return an enumerator immediately.
///
/// If the `attrs` `Attributes` is floating, it is consumed.
extern fn gck_modules_enumerate_objects(p_modules: *glib.List, p_attrs: *gck.Attributes, p_session_options: gck.SessionOptions) *gck.Enumerator;
pub const modulesEnumerateObjects = gck_modules_enumerate_objects;

/// Enumerate objects that match a URI.
///
/// This call will not block. Use the `Enumerator` functions in order to
/// get at the actual objects that match.
extern fn gck_modules_enumerate_uri(p_modules: *glib.List, p_uri: [*:0]const u8, p_session_options: gck.SessionOptions, p_error: ?*?*glib.Error) ?*gck.Enumerator;
pub const modulesEnumerateUri = gck_modules_enumerate_uri;

/// Get a list of slots for across all of the modules.
extern fn gck_modules_get_slots(p_modules: *glib.List, p_token_present: c_int) *glib.List;
pub const modulesGetSlots = gck_modules_get_slots;

/// Load and initialize all the registered modules.
extern fn gck_modules_initialize_registered(p_cancellable: ?*gio.Cancellable, p_error: ?*?*glib.Error) ?*glib.List;
pub const modulesInitializeRegistered = gck_modules_initialize_registered;

/// Load and initialize all the registered modules asynchronously.
extern fn gck_modules_initialize_registered_async(p_cancellable: ?*gio.Cancellable, p_callback: ?gio.AsyncReadyCallback, p_user_data: ?*anyopaque) void;
pub const modulesInitializeRegisteredAsync = gck_modules_initialize_registered_async;

/// Finishes the asynchronous operation to initialize the registered
/// PKCS`@"11"` modules.
extern fn gck_modules_initialize_registered_finish(p_result: *gio.AsyncResult, p_error: ?*?*glib.Error) ?*glib.List;
pub const modulesInitializeRegisteredFinish = gck_modules_initialize_registered_finish;

/// Find an object that matches a URI.
///
/// This call can block. Use `modulesEnumerateUri` for a non-blocking
/// version.
extern fn gck_modules_object_for_uri(p_modules: *glib.List, p_uri: [*:0]const u8, p_session_options: gck.SessionOptions, p_error: ?*?*glib.Error) ?*gck.Object;
pub const modulesObjectForUri = gck_modules_object_for_uri;

/// Find objects that match a URI.
///
/// This call can block. Use `modulesEnumerateUri` for a non-blocking
/// version.
extern fn gck_modules_objects_for_uri(p_modules: *glib.List, p_uri: [*:0]const u8, p_session_options: gck.SessionOptions, p_error: ?*?*glib.Error) ?*glib.List;
pub const modulesObjectsForUri = gck_modules_objects_for_uri;

/// Lookup a token that matches the URI.
extern fn gck_modules_token_for_uri(p_modules: *glib.List, p_uri: [*:0]const u8, p_error: ?*?*glib.Error) ?*gck.Slot;
pub const modulesTokenForUri = gck_modules_token_for_uri;

/// Lookup a token that matches the URI.
extern fn gck_modules_tokens_for_uri(p_modules: *glib.List, p_uri: [*:0]const u8, p_error: ?*?*glib.Error) ?*glib.List;
pub const modulesTokensForUri = gck_modules_tokens_for_uri;

/// Initialize a list of GckObject from raw PKCS`@"11"` handles. The handles argument must contain
/// contiguous CK_OBJECT_HANDLE handles in an array.
extern fn gck_objects_from_handle_array(p_session: *gck.Session, p_object_handles: [*]c_ulong, p_n_object_handles: c_ulong) *glib.List;
pub const objectsFromHandleArray = gck_objects_from_handle_array;

/// Setup an enumerator for listing matching objects on the slots.
///
/// If the `match` `gck.Attributes` is floating, it is consumed.
///
/// This call will not block but will return an enumerator immediately.
extern fn gck_slots_enumerate_objects(p_slots: *glib.List, p_match: *gck.Attributes, p_options: gck.SessionOptions) *gck.Enumerator;
pub const slotsEnumerateObjects = gck_slots_enumerate_objects;

/// Create a string from a set of PKCS`@"11"` characters. This is
/// similar to `glib.strndup`, except for that it also strips trailing
/// spaces. These space padded strings are often used in PKCS`@"11"`
/// structures.
///
/// If the space padded string is filled with null characters then
/// this function will return `NULL`.
extern fn gck_string_from_chars(p_data: *const u8, p_max: usize) [*:0]u8;
pub const stringFromChars = gck_string_from_chars;

/// Create a space padded PKCS`@"11"` string from a null terminated string.
/// The string must be shorter than the buffer or `FALSE` will be
/// returned.
///
/// If a `NULL` string is passed, then the space padded string will be
/// set to zero characters.
extern fn gck_string_to_chars(p_data: *u8, p_max: usize, p_string: [*:0]const u8) c_int;
pub const stringToChars = gck_string_to_chars;

/// Build a PKCS`@"11"` URI. The various parts relevant to the flags
/// specified will be used to build the URI.
extern fn gck_uri_build(p_uri_data: *gck.UriData, p_flags: gck.UriFlags) [*:0]u8;
pub const uriBuild = gck_uri_build;

/// Parse a PKCS`@"11"` URI for use in a given context.
///
/// The result will contain the fields that are relevant for
/// the given context. See `gck.UriData`  for more info.
/// Other fields will be set to `NULL`.
extern fn gck_uri_parse(p_string: [*:0]const u8, p_flags: gck.UriFlags, p_error: ?*?*glib.Error) ?*gck.UriData;
pub const uriParse = gck_uri_parse;

/// Convert `CK_BBOOL` type memory to a boolean.
extern fn gck_value_to_boolean(p_value: [*]const u8, p_length: usize, p_result: *c_int) c_int;
pub const valueToBoolean = gck_value_to_boolean;

/// Convert `CK_ULONG` type memory to a boolean.
extern fn gck_value_to_ulong(p_value: [*]const u8, p_length: usize, p_result: *c_ulong) c_int;
pub const valueToUlong = gck_value_to_ulong;

/// An allocator used to allocate data for the attributes in this
/// `Attributes` set.
///
/// This is a function that acts like g_realloc. Specifically it frees when length is
/// set to zero, it allocates when data is set to `NULL`, and it reallocates when both
/// are valid.
pub const Allocator = *const fn (p_data: ?*anyopaque, p_length: usize) callconv(.c) ?*anyopaque;

/// Used as a terminator at the end of variable argument lists.
pub const INVALID = -1;
/// The major version number of the Gck library.
pub const MAJOR_VERSION = 1;
/// The micro version number of the Gck library.
pub const MICRO_VERSION = 0;
/// The minor version number of the Gck library.
pub const MINOR_VERSION = 0;
/// The URI will match specific version of modules. To be used as a GckUriFlags argument.
pub const URI_FOR_MODULE_WITH_VERSION = 24;
/// The URI will match objects on a specific token. To be used as a GckUriFlags argument.
pub const URI_FOR_OBJECT_ON_TOKEN = 6;
/// The token inserted into a device with a specific module.
pub const URI_FOR_OBJECT_ON_TOKEN_AND_MODULE = 8;
/// Custom PKCS`@"11"` errors that originate from the gck library, are
/// based at this error code.
pub const VENDOR_CODE = 1195592448;

test {
    @setEvalBranchQuota(100_000);
    std.testing.refAllDecls(@This());
    std.testing.refAllDecls(ext);
}
