/
githubmirror
/
libxmlb
Обзор
Документация
Войти
/
githubmirror
/
libxmlb
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/xb-builder-source-ctx.c
241 строка
7 KB
Richard Hughes
trivial: Use %zx format specifier for gsize values
26 июн 2026, 16:21
26 июн 2026, 16:21
dc48200
Код
Авторство
О чём код?
/* * Copyright 2018 Richard Hughes <richard@hughsie.com> * * SPDX-License-Identifier: LGPL-2.1-or-later */ #define G_LOG_DOMAIN "XbSilo" #include "config.h" #include <gio/gio.h> #include "xb-builder-source-ctx-private.h" #include "xb-common-private.h" typedef struct { GFile *file; GInputStream *istream; gchar *basename; gchar *content_type; } XbBuilderSourceCtxPrivate; G_DEFINE_TYPE_WITH_PRIVATE(XbBuilderSourceCtx, xb_builder_source_ctx, G_TYPE_OBJECT) #define GET_PRIVATE(o) (xb_builder_source_ctx_get_instance_private(o)) /** * xb_builder_source_ctx_get_stream: * @self: a #XbBuilderSourceCtx * * Returns the input stream currently being processed. * * Returns: (transfer none): a #GInputStream * * Since: 0.1.7 **/ GInputStream * xb_builder_source_ctx_get_stream(XbBuilderSourceCtx *self) { XbBuilderSourceCtxPrivate *priv = GET_PRIVATE(self); g_return_val_if_fail(XB_IS_BUILDER_SOURCE_CTX(self), NULL); return priv->istream; } static GBytes * _g_input_stream_read_bytes_in_chunks(GInputStream *stream, gsize count, gsize chunk_sz, GCancellable *cancellable, GError **error) { g_autofree guint8 *tmp = NULL; g_autoptr(GByteArray) buf = g_byte_array_new(); g_return_val_if_fail(G_IS_INPUT_STREAM(stream), NULL); g_return_val_if_fail(count > 0, NULL); g_return_val_if_fail(chunk_sz > 0, NULL); g_return_val_if_fail(error == NULL || *error == NULL, NULL); /* read from stream in chunks */ tmp = g_malloc(chunk_sz); while (TRUE) { gssize sz; sz = g_input_stream_read(stream, tmp, chunk_sz, NULL, error); if (sz == 0) break; if (sz < 0) return NULL; g_byte_array_append(buf, tmp, sz); if (buf->len > count) { g_set_error(error, G_IO_ERROR, G_IO_ERROR_FAILED, "cannot read from fd: 0x%x > 0x%zx", buf->len, count); return NULL; } } return g_byte_array_free_to_bytes(g_steal_pointer(&buf)); } /** * xb_builder_source_ctx_get_bytes: * @self: a #XbBuilderSourceCtx * @cancellable: a #GCancellable, or %NULL * @error: the #GError, or %NULL * * Returns the data currently being processed. * * If the #XbBuilderSourceCtx is backed by a file, the returned #GBytes may be * memory-mapped, and the backing file must not be modified until the #GBytes is * destroyed. * * Returns: (transfer full): a #GBytes * * Since: 0.1.7 **/ GBytes * xb_builder_source_ctx_get_bytes(XbBuilderSourceCtx *self, GCancellable *cancellable, GError **error) { XbBuilderSourceCtxPrivate *priv = GET_PRIVATE(self); g_return_val_if_fail(XB_IS_BUILDER_SOURCE_CTX(self), NULL); g_return_val_if_fail(cancellable == NULL || G_IS_CANCELLABLE(cancellable), NULL); g_return_val_if_fail(error == NULL || *error == NULL, NULL); /* Try mmap()ing the file first, as that avoids buffer allocation. * Note that this imposes the restriction that the backing file must not * be modified during the lifetime of the returned #GBytes. */ if (priv->file != NULL) { g_autoptr(GMappedFile) mapped_file = NULL; g_autofree gchar *filename = g_file_get_path(priv->file); mapped_file = g_mapped_file_new(filename, FALSE, NULL); if (mapped_file != NULL) return g_mapped_file_get_bytes(mapped_file); } return _g_input_stream_read_bytes_in_chunks(priv->istream, 128 * 1024 * 1024, /* 128Mb */ 32 * 1024, /* 32Kb */ cancellable, error); } /** * xb_builder_source_ctx_get_filename: * @self: a #XbBuilderSourceCtx * * Returns the basename of the file currently being processed. * * Returns: (transfer none) (nullable): a basename, or %NULL if unset * * Since: 0.1.7 **/ const gchar * xb_builder_source_ctx_get_filename(XbBuilderSourceCtx *self) { XbBuilderSourceCtxPrivate *priv = GET_PRIVATE(self); g_return_val_if_fail(XB_IS_BUILDER_SOURCE_CTX(self), NULL); return priv->basename; } /** * xb_builder_source_ctx_get_content_type: * @self: a #XbBuilderSourceCtx * @cancellable: a #GCancellable, or %NULL * @error: the #GError, or %NULL * * Returns the content type of the input stream currently being * processed. * * Returns: (transfer full): a content type (e.g. `application/x-desktop`), or %NULL on error * * Since: 0.1.7 **/ gchar * xb_builder_source_ctx_get_content_type(XbBuilderSourceCtx *self, GCancellable *cancellable, GError **error) { XbBuilderSourceCtxPrivate *priv = GET_PRIVATE(self); gsize bufsz = 0; guchar buf[4096] = {0x00}; g_return_val_if_fail(XB_IS_BUILDER_SOURCE_CTX(self), NULL); if (G_IS_SEEKABLE(priv->istream)) { if (!g_input_stream_read_all(priv->istream, buf, sizeof(buf), &bufsz, cancellable, error)) return NULL; if (!g_seekable_seek(G_SEEKABLE(priv->istream), 0, G_SEEK_SET, cancellable, error)) return NULL; } if (bufsz > 0) return xb_content_type_guess(priv->basename, buf, bufsz); return xb_content_type_guess(priv->basename, NULL, 0); } /* private */ void xb_builder_source_ctx_set_filename(XbBuilderSourceCtx *self, const gchar *basename) { XbBuilderSourceCtxPrivate *priv = GET_PRIVATE(self); g_return_if_fail(XB_IS_BUILDER_SOURCE_CTX(self)); g_return_if_fail(basename != NULL); g_free(priv->basename); priv->basename = g_strdup(basename); } static void xb_builder_source_ctx_init(XbBuilderSourceCtx *self) { } static void xb_builder_source_ctx_finalize(GObject *obj) { XbBuilderSourceCtx *self = XB_BUILDER_SOURCE_CTX(obj); XbBuilderSourceCtxPrivate *priv = GET_PRIVATE(self); g_free(priv->basename); g_object_unref(priv->istream); g_clear_object(&priv->file); G_OBJECT_CLASS(xb_builder_source_ctx_parent_class)->finalize(obj); } static void xb_builder_source_ctx_class_init(XbBuilderSourceCtxClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS(klass); object_class->finalize = xb_builder_source_ctx_finalize; } /** * xb_builder_source_ctx_new: * @file: (transfer none) (nullable): Path to the file which contains the source, * or %NULL if the source is not directly loadable from disk * @istream: (transfer none): Input stream to load the source from * * Creates a new builder source_ctx. * * Returns: (transfer full): a new #XbBuilderSourceCtx * * Since: 0.1.7 **/ XbBuilderSourceCtx * xb_builder_source_ctx_new(GFile *file, GInputStream *istream) { XbBuilderSourceCtx *self = g_object_new(XB_TYPE_BUILDER_SOURCE_CTX, NULL); XbBuilderSourceCtxPrivate *priv = GET_PRIVATE(self); g_return_val_if_fail(file == NULL || G_IS_FILE(file), NULL); g_return_val_if_fail(G_IS_INPUT_STREAM(istream), NULL); priv->file = (file != NULL) ? g_object_ref(file) : NULL; priv->istream = g_object_ref(istream); return self; }