/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2022 Richard Hughes * * SPDX-License-Identifier: LGPL-2.1+ */ /** * SECTION:gusb-device-event * @short_description: An event that happened to a GUsbDevice. */ #include "config.h" #include "gusb-device-event-private.h" #include "gusb-json-common.h" struct _GUsbDeviceEvent { GObject parent_instance; gchar *id; gint status; gint rc; GBytes *bytes; }; G_DEFINE_TYPE(GUsbDeviceEvent, g_usb_device_event, G_TYPE_OBJECT) static void g_usb_device_event_finalize(GObject *object) { GUsbDeviceEvent *self = G_USB_DEVICE_EVENT(object); g_free(self->id); if (self->bytes != NULL) g_bytes_unref(self->bytes); G_OBJECT_CLASS(g_usb_device_event_parent_class)->finalize(object); } static void g_usb_device_event_class_init(GUsbDeviceEventClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS(klass); object_class->finalize = g_usb_device_event_finalize; } static void g_usb_device_event_init(GUsbDeviceEvent *self) { } gboolean _g_usb_device_event_load(GUsbDeviceEvent *self, JsonObject *json_object, GError **error) { const gchar *str; g_return_val_if_fail(G_USB_IS_DEVICE_EVENT(self), FALSE); g_return_val_if_fail(json_object != NULL, FALSE); g_return_val_if_fail(error == NULL || *error == NULL, -1); /* optional properties */ self->id = g_strdup(json_object_get_string_member_with_default(json_object, "Id", NULL)); self->status = json_object_get_int_member_with_default(json_object, "Status", LIBUSB_TRANSFER_COMPLETED); self->rc = json_object_get_int_member_with_default(json_object, "Error", LIBUSB_SUCCESS); /* extra data */ str = json_object_get_string_member_with_default(json_object, "Data", NULL); if (str != NULL) { gsize bufsz = 0; g_autofree guchar *buf = g_base64_decode(str, &bufsz); self->bytes = g_bytes_new_take(g_steal_pointer(&buf), bufsz); } /* success */ return TRUE; } gboolean _g_usb_device_event_save(GUsbDeviceEvent *self, JsonBuilder *json_builder, GError **error) { g_return_val_if_fail(G_USB_IS_DEVICE_EVENT(self), FALSE); g_return_val_if_fail(json_builder != NULL, FALSE); g_return_val_if_fail(error == NULL || *error == NULL, FALSE); /* start */ json_builder_begin_object(json_builder); if (self->id != NULL) { json_builder_set_member_name(json_builder, "Id"); json_builder_add_string_value(json_builder, self->id); } if (self->status != LIBUSB_TRANSFER_COMPLETED) { json_builder_set_member_name(json_builder, "Status"); json_builder_add_int_value(json_builder, self->status); } if (self->rc != LIBUSB_SUCCESS) { json_builder_set_member_name(json_builder, "Error"); json_builder_add_int_value(json_builder, self->rc); } if (self->bytes != NULL) { g_autofree gchar *str = g_base64_encode(g_bytes_get_data(self->bytes, NULL), g_bytes_get_size(self->bytes)); json_builder_set_member_name(json_builder, "Data"); json_builder_add_string_value(json_builder, str); } /* success */ json_builder_end_object(json_builder); return TRUE; } /** * _g_usb_device_event_new: * @id: a cache key * * Return value: a new #GUsbDeviceEvent object. * * Since: 0.4.0 **/ GUsbDeviceEvent * _g_usb_device_event_new(const gchar *id) { GUsbDeviceEvent *self; self = g_object_new(G_USB_TYPE_DEVICE_EVENT, NULL); self->id = g_strdup(id); return G_USB_DEVICE_EVENT(self); } /** * g_usb_device_event_get_id: * @self: a #GUsbDeviceEvent * * Gets the event ID. * * Return value: string, or %NULL * * Since: 0.4.0 **/ const gchar * g_usb_device_event_get_id(GUsbDeviceEvent *self) { g_return_val_if_fail(G_USB_IS_DEVICE_EVENT(self), NULL); return self->id; } /** * g_usb_device_event_get_status: * @self: a #GUsbDeviceEvent * * Gets any status data from the event. * * Return value: a `enum libusb_transfer_status`, or -1 for failure * * Since: 0.4.0 **/ gint g_usb_device_event_get_status(GUsbDeviceEvent *self) { g_return_val_if_fail(G_USB_IS_DEVICE_EVENT(self), -1); return self->status; } /** * _g_usb_device_event_set_status: * @self: a #GUsbDeviceEvent * @status: `enum libusb_transfer_status` * * Set the status of the event, e.g. `LIBUSB_TRANSFER_COMPLETED`. * * Since: 0.4.0 **/ void _g_usb_device_event_set_status(GUsbDeviceEvent *self, gint status) { g_return_if_fail(G_USB_IS_DEVICE_EVENT(self)); self->status = status; } /** * g_usb_device_event_get_rc: * @self: a #GUsbDeviceEvent * * Gets any return code from the event. * * Return value: a `enum libusb_error` * * Since: 0.4.5 **/ gint g_usb_device_event_get_rc(GUsbDeviceEvent *self) { g_return_val_if_fail(G_USB_IS_DEVICE_EVENT(self), LIBUSB_ERROR_OTHER); return self->rc; } /** * _g_usb_device_event_set_rc: * @self: a #GUsbDeviceEvent * @status: `enum libusb_error` * * Set the return code of the event, e.g. `LIBUSB_ERROR_TIMEOUT`. * * Since: 0.4.5 **/ void _g_usb_device_event_set_rc(GUsbDeviceEvent *self, gint rc) { g_return_if_fail(G_USB_IS_DEVICE_EVENT(self)); g_return_if_fail(rc <= 0); self->rc = rc; } /** * g_usb_device_event_get_bytes: * @self: a #GUsbDeviceEvent * * Gets any bytes data from the event. * * Return value: (transfer none): a #GBytes, or %NULL * * Since: 0.4.0 **/ GBytes * g_usb_device_event_get_bytes(GUsbDeviceEvent *self) { g_return_val_if_fail(G_USB_IS_DEVICE_EVENT(self), NULL); return self->bytes; } /** * g_usb_device_event_set_bytes: * @self: a #GUsbDeviceEvent * @bytes: a #GBytes * * Set the bytes data to the event. * * Since: 0.4.0 **/ void g_usb_device_event_set_bytes(GUsbDeviceEvent *self, GBytes *bytes) { g_return_if_fail(G_USB_IS_DEVICE_EVENT(self)); g_return_if_fail(bytes != NULL); if (self->bytes != NULL) g_bytes_unref(self->bytes); self->bytes = g_bytes_ref(bytes); } void _g_usb_device_event_set_bytes_raw(GUsbDeviceEvent *self, gconstpointer buf, gsize bufsz) { g_return_if_fail(G_USB_IS_DEVICE_EVENT(self)); g_return_if_fail(buf != NULL); if (self->bytes != NULL) g_bytes_unref(self->bytes); self->bytes = g_bytes_new(buf, bufsz); }