[gnome-software/1296-calculate-app-space-usage-for-download-context-tile: 1/3] gs-utils: Introduce gs_utils_get_file_size()
- From: Milan Crha <mcrha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-software/1296-calculate-app-space-usage-for-download-context-tile: 1/3] gs-utils: Introduce gs_utils_get_file_size()
- Date: Thu, 29 Jul 2021 09:19:32 +0000 (UTC)
commit 3d6a7dd1238aa94c94a7912149171fc8eda46de1
Author: Milan Crha <mcrha redhat com>
Date: Thu Jul 29 11:15:45 2021 +0200
gs-utils: Introduce gs_utils_get_file_size()
A function, which helps to get a file or a directory size.
lib/gs-utils.c | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
lib/gs-utils.h | 23 ++++++++++++++++++
2 files changed, 96 insertions(+)
---
diff --git a/lib/gs-utils.c b/lib/gs-utils.c
index a09a2a00c..d17ba07e4 100644
--- a/lib/gs-utils.c
+++ b/lib/gs-utils.c
@@ -1435,4 +1435,77 @@ gs_utils_pixbuf_blur (GdkPixbuf *src, guint radius, guint iterations)
gs_pixbuf_blur_private (src, tmp, radius, div_kernel_size);
}
+/**
+ * gs_utils_get_file_size:
+ * @filename: a file name to get the size of; it can be a file or a directory
+ * @include_func: (nullable) (scope call): optional callback to limit what files to count
+ * @user_data: user data passed to the @include_func
+ * @cancellable: (nullable): an optional #GCancellable or %NULL
+ *
+ * Gets the size of the file or a directory identified by @filename.
+ *
+ * When the @include_func is not %NULL, it can limit which files are included
+ * in the resulting size. When it's %NULL, all files and subdirectories) are included.
+ *
+ * Returns: disk size of the @filename; or 0 when not found
+ *
+ * Since: 41
+ **/
+guint64
+gs_utils_get_file_size (const gchar *filename,
+ GsFileSizeIncludeFunc include_func,
+ gpointer user_data,
+ GCancellable *cancellable)
+{
+ guint64 size = 0;
+
+ g_return_val_if_fail (filename != NULL, 0);
+
+ if (g_file_test (filename, G_FILE_TEST_IS_DIR)) {
+ GSList *dirs_to_do = NULL;
+ gsize base_len = strlen (filename);
+
+ if (!g_str_has_suffix (filename, G_DIR_SEPARATOR_S))
+ base_len++;
+
+ dirs_to_do = g_slist_prepend (dirs_to_do, g_strdup (filename));
+ while (dirs_to_do != NULL && !g_cancellable_is_cancelled (cancellable)) {
+ g_autofree gchar *path = dirs_to_do->data;
+ g_autoptr(GDir) dir = NULL;
+
+ dirs_to_do = g_slist_remove (dirs_to_do, path);
+
+ dir = g_dir_open (path, 0, NULL);
+ if (dir) {
+ const gchar *name;
+ while (name = g_dir_read_name (dir), name != NULL &&
!g_cancellable_is_cancelled (cancellable)) {
+ g_autofree gchar *full_path = g_build_filename (path, name, NULL);
+ GStatBuf st;
+
+ if (g_stat (full_path, &st) == 0 && (include_func == NULL ||
+ include_func (full_path + base_len,
+ S_ISLNK (st.st_mode) ? G_FILE_TEST_IS_SYMLINK :
+ S_ISDIR (st.st_mode) ? G_FILE_TEST_IS_DIR :
+ G_FILE_TEST_IS_REGULAR,
+ user_data))) {
+ if (S_ISDIR (st.st_mode)) {
+ dirs_to_do = g_slist_prepend (dirs_to_do,
g_steal_pointer (&full_path));
+ } else {
+ size += st.st_size;
+ }
+ }
+ }
+ }
+ }
+ g_slist_free_full (dirs_to_do, g_free);
+ } else {
+ GStatBuf st;
+
+ if (g_stat (filename, &st) == 0)
+ size = st.st_size;
+ }
+
+ return size;
+}
+
/* vim: set noexpandtab: */
diff --git a/lib/gs-utils.h b/lib/gs-utils.h
index 2a4402999..39685c9a1 100644
--- a/lib/gs-utils.h
+++ b/lib/gs-utils.h
@@ -106,6 +106,29 @@ void gs_utils_pixbuf_blur (GdkPixbuf *src,
guint radius,
guint iterations);
+/**
+ * GsFileSizeIncludeFunc:
+ * @filename: file name to check
+ * @file_kind: the file kind, one of #GFileTest enums
+ * @user_data: a user data passed to the gs_utils_get_file_size()
+ *
+ * Check whether include the @filename in the size calculation.
+ * The @filename is a relative path to the file name passed to
+ * the GsFileSizeIncludeFunc.
+ *
+ * Returns: Whether to include the @filename in the size calculation
+ *
+ * Since: 41
+ **/
+typedef gboolean (*GsFileSizeIncludeFunc) (const gchar *filename,
+ GFileTest file_kind,
+ gpointer user_data);
+
+guint64 gs_utils_get_file_size (const gchar *filename,
+ GsFileSizeIncludeFunc include_func,
+ gpointer user_data,
+ GCancellable *cancellable);
+
#if !GLIB_CHECK_VERSION(2, 64, 0)
typedef void GsMainContextPusher;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]