[glibmm] Gio::File: Add measure_disk_usage() and measure_disk_usage_async().



commit 2b715e511f01f1dac742016f356c6866c4616a36
Author: Murray Cumming <murrayc murrayc com>
Date:   Fri Sep 20 10:27:40 2013 +0200

    Gio::File: Add measure_disk_usage() and measure_disk_usage_async().
    
    * gio/src/file.[hg|ccg]: Wrap g_file_measure_disk_usage(),
      g_file_measure_disk_usage_async() and
      g_file_measure_disk_usage_finish(), based on the copy() and
      copy_async() methods, which also have 2 slots.
    * tools/m4/convert_glib.m4: Add a conversion for guint64&.

 gio/src/file.ccg         |   91 +++++++++++++++++++++++++++++++++++++++++--
 gio/src/file.hg          |   96 ++++++++++++++++++++++++++++++++++++++++++++++
 tools/m4/convert_glib.m4 |    1 +
 3 files changed, 183 insertions(+), 5 deletions(-)
---
diff --git a/gio/src/file.ccg b/gio/src/file.ccg
index 0e7548a..cdd31e6 100644
--- a/gio/src/file.ccg
+++ b/gio/src/file.ccg
@@ -28,6 +28,7 @@ namespace
 {
 
 typedef std::pair<Gio::File::SlotFileProgress*, Gio::SlotAsyncReady*> CopySlots;
+typedef std::pair<Gio::File::SlotFileMeasureProgress*, Gio::SlotAsyncReady*> MeasureSlots;
 typedef std::pair<Gio::File::SlotReadMore*, Gio::SlotAsyncReady*> LoadPartialSlots;
 
 static void
@@ -53,7 +54,7 @@ SignalProxy_file_progress_callback(goffset current_num_bytes,
 // the slot is packed in a pair. The operation is assumed to be finished
 // after the callback is triggered, so we delete that pair here.
 static void
-SignalProxy_file_ready_callback(GObject*, GAsyncResult* res, void* data)
+SignalProxy_file_copy_async_callback(GObject*, GAsyncResult* res, void* data)
 {
   CopySlots* slot_pair = static_cast<CopySlots*>(data);
   Gio::SlotAsyncReady* the_slot = slot_pair->second;
@@ -76,6 +77,34 @@ SignalProxy_file_ready_callback(GObject*, GAsyncResult* res, void* data)
   delete slot_pair;
 }
 
+
+// Same as SignalProxy_async_callback, except that this one knows that
+// the slot is packed in a pair. The operation is assumed to be finished
+// after the callback is triggered, so we delete that pair here.
+static void
+SignalProxy_file_measure_async_callback(GObject*, GAsyncResult* res, void* data)
+{
+  MeasureSlots* slot_pair = static_cast<MeasureSlots*>(data);
+  Gio::SlotAsyncReady* the_slot = slot_pair->second;
+
+  try
+  {
+    if(*the_slot)
+    {
+      Glib::RefPtr<Gio::AsyncResult> result = Glib::wrap(res, true /* take copy */);
+      (*the_slot)(result);
+    }
+  }
+  catch(...)
+  {
+    Glib::exception_handlers_invoke();
+  }
+
+  delete the_slot;
+  delete slot_pair->first; // progress slot
+  delete slot_pair;
+}
+
 static gboolean
 SignalProxy_load_partial_contents_read_more_callback(const char* file_contents, goffset file_size, gpointer 
data)
 {
@@ -122,6 +151,27 @@ SignalProxy_load_partial_contents_ready_callback(GObject*, GAsyncResult* res, vo
   delete slot_pair;
 }
 
+static void
+SignalProxy_file_measure_progress_callback(gboolean reporting,
+  guint64  current_size,
+  guint64  num_dirs,
+  guint64  num_files,
+  gpointer data)
+{
+  Gio::File::SlotFileMeasureProgress* the_slot = static_cast<Gio::File::SlotFileMeasureProgress*>(data);
+
+  try
+  {
+
+    (*the_slot)(reporting, current_size, num_dirs, num_files);
+
+  }
+  catch(...)
+  {
+    Glib::exception_handlers_invoke();
+  }
+}
+
 } // anonymous namespace
 
 namespace Gio {
@@ -662,7 +712,7 @@ File::copy_async(const Glib::RefPtr<File>& destination,
                  int io_priority)
 {
   // Create a new pair which will hold copies of passed slots.
-  // This will be deleted in the SignalProxy_file_ready_callback() callback
+  // This will be deleted in the SignalProxy_file_copy_async_callback() callback
   CopySlots* slots = new CopySlots();
   SlotFileProgress* slot_progress_copy = new SlotFileProgress(slot_progress);
   SlotAsyncReady* slot_ready_copy = new SlotAsyncReady(slot_ready);
@@ -677,7 +727,7 @@ File::copy_async(const Glib::RefPtr<File>& destination,
                     Glib::unwrap(cancellable),
                     &SignalProxy_file_progress_callback,
                     slot_progress_copy,
-                    &SignalProxy_file_ready_callback,
+                    &SignalProxy_file_copy_async_callback,
                     slots);
 }
 
@@ -712,7 +762,7 @@ File::copy_async(const Glib::RefPtr<File>& destination,
                  int io_priority)
 {
   // Create a new pair which will hold copies of passed slots.
-  // This will be deleted in the SignalProxy_file_ready_callback() callback
+  // This will be deleted in the SignalProxy_file_copy_async_callback() callback
   CopySlots* slots = new CopySlots();
   SlotFileProgress* slot_progress_copy = new SlotFileProgress(slot_progress);
   SlotAsyncReady* slot_ready_copy = new SlotAsyncReady(slot_ready);
@@ -727,7 +777,7 @@ File::copy_async(const Glib::RefPtr<File>& destination,
                     0,
                     &SignalProxy_file_progress_callback,
                     slot_progress_copy,
-                    &SignalProxy_file_ready_callback,
+                    &SignalProxy_file_copy_async_callback,
                     slots);
 }
 
@@ -1510,6 +1560,37 @@ Glib::RefPtr<FileMonitor> File::monitor(FileMonitorFlags flags)
   return retvalue;
 }
 
+
+void File::measure_disk_usage(const Glib::RefPtr<Cancellable>& cancellable, const SlotFileMeasureProgress& 
slot_progress, guint64& disk_usage, guint64& num_dirs, guint64& num_files, FileMeasureFlags flags)
+{
+  GError* gerror = 0;
+  g_file_measure_disk_usage(gobj(), ((GFileMeasureFlags)(flags)),
+    const_cast<GCancellable*>(Glib::unwrap(cancellable)),
+    &SignalProxy_file_measure_progress_callback, const_cast<SlotFileMeasureProgress*>(&slot_progress),
+    &disk_usage, &num_dirs, &num_files, &(gerror));
+  if(gerror)
+    ::Glib::Error::throw_exception(gerror);
+}
+
+void File::measure_disk_usage_async(const SlotAsyncReady& slot_ready, const Glib::RefPtr<Cancellable>& 
cancellable, const SlotFileMeasureProgress& slot_progress, FileMeasureFlags flags, int io_priority)
+{
+  // Create a new pair which will hold copies of passed slots.
+  // This will be deleted in the SignalProxy_file_measure_async_callback() callback
+  MeasureSlots* slots = new MeasureSlots();
+  SlotFileMeasureProgress* slot_progress_copy = new SlotFileMeasureProgress(slot_progress);
+  SlotAsyncReady* slot_ready_copy = new SlotAsyncReady(slot_ready);
+
+  slots->first = slot_progress_copy;
+  slots->second = slot_ready_copy;
+
+  g_file_measure_disk_usage_async(gobj(),
+    ((GFileMeasureFlags)(flags)),
+    io_priority,
+    const_cast<GCancellable*>(Glib::unwrap(cancellable)),
+    &SignalProxy_file_measure_progress_callback, const_cast<SlotFileMeasureProgress*>(&slot_progress),
+    &SignalProxy_file_measure_async_callback, slots);
+}
+
 void File::start_mountable(const SlotAsyncReady& slot, const Glib::RefPtr<Cancellable>& cancellable, const 
Glib::RefPtr<MountOperation>& start_operation, DriveStartFlags flags)
 {
   // Create a copy of the slot.
diff --git a/gio/src/file.hg b/gio/src/file.hg
index 2281ed0..55591e2 100644
--- a/gio/src/file.hg
+++ b/gio/src/file.hg
@@ -55,6 +55,7 @@ _WRAP_ENUM(FileQueryInfoFlags, GFileQueryInfoFlags, NO_GTYPE)
 _WRAP_ENUM(FileCreateFlags, GFileCreateFlags, NO_GTYPE)
 _WRAP_ENUM(FileCopyFlags, GFileCopyFlags, NO_GTYPE)
 _WRAP_ENUM(FileMonitorFlags, GFileMonitorFlags, NO_GTYPE)
+_WRAP_ENUM(FileMeasureFlags, GFileMeasureFlags, NO_GTYPE)
 
 
 /** File and directory handling.
@@ -1767,6 +1768,101 @@ public:
   Glib::RefPtr<FileMonitor> monitor(FileMonitorFlags flags = FILE_MONITOR_NONE);
   _IGNORE(g_file_monitor)
 
+
+ /** This slot type is used by measure_disk_usage() to make
+  * periodic progress reports when measuring the amount of disk spaced
+  * used by a directory.
+  *
+  * These calls are made on a best-effort basis and not all types of
+  * GFile will support them.  At the minimum, however, one call will
+  * always be made immediately.
+  *
+  * In the case that there is no support, @a reporting will be set to
+  * false (and the other values undefined) and no further calls will be
+  * made.  Otherwise, the @a reporting will be true and the other values
+  * all-zeros during the first (immediate) call.  In this way, you can
+  * know which type of progress UI to show without a delay.
+  *
+  * For measure_disk_usage() the callback is made directly.  For
+  * measure_disk_usage_async() the callback is made via the
+  * default main context of the calling thread (ie: the same way that the
+  * final async result would be reported).
+  *
+  * @a current_size is in the same units as requested by the operation (see
+  * FILE_DISK_USAGE_APPARENT_SIZE).
+  *
+  * The frequency of the updates is implementation defined, but is
+  * ideally about once every 200ms.
+  *
+  * The last progress callback may or may not be equal to the final
+  * result.  Always check the async result to get the final value.
+  *
+  * For instance,
+  * void on_file_measure_progress(bool reporting, guint64 current_size, guint64 num_dirs, guint64 num_files);
+  *
+  * @param reporting true if more reports will come.
+  * @param current_size The current cumulative size measurement.
+  * @param num_dirs The number of directories visited so far.
+  * @param num_files The number of non-directory files encountered.
+  *
+  * @newin{2,38}
+  */
+ typedef sigc::slot<void, bool, guint64, guint64, guint64> SlotFileMeasureProgress;
+
+  //We do not use the {callback} syntax with _WRAP_METHOD here, because it expects to use user_data rather 
than progress_data.
+  //We ignore the gboolean result, because we throw an exception if it is false.
+  /** Recursively measures the disk usage of the file.
+   *
+   * This is essentially an analog of the '<literal>du</literal>' command,
+   * but it also reports the number of directories and non-directory files
+   * encountered (including things like symbolic links).
+   *
+   * By default, errors are only reported against the toplevel file
+   * itself.  Errors found while recursing are silently ignored, unless
+   * FILE_DISK_USAGE_REPORT_ALL_ERRORS is given in @a flags.
+   *
+   * The returned size, @a disk_usage, is in bytes and should be formatted
+   * with g_format_size() in order to get something reasonable for showing
+   * in a user interface.
+   *
+   * @a slot_progress can be given to request periodic progress updates while scanning.
+   * See the documentation for SlotFileMeasureProgress for information about when and how the
+   * callback will be invoked.
+   *
+   * The operation can be cancelled by triggering the cancellable object from another thread.
+   * If the operation was cancelled, a Gio::Error with CANCELLED will be thrown.
+   *
+   * @param cancellable A Cancellable object which can be used to cancel the operation
+   * @param progress_callback A SlotFileMeasureProgress to call periodically while scanning.
+   * @param disk_usage The number of bytes of disk space used.
+   * @param num_dirs The number of directories encountered.
+   * @param num_files The number of non-directories encountered.
+   * @param flags Set of FileMeasureFlags.
+   */
+  void measure_disk_usage(const Glib::RefPtr<Cancellable>& cancellable, const SlotFileMeasureProgress& 
slot_progress, guint64& disk_usage, guint64& num_dirs, guint64& num_files, FileMeasureFlags flags = 
FILE_MEASURE_NONE);
+  _IGNORE(g_file_measure_disk_usage)
+
+  /** Recursively measures the disk usage of the file.
+   *
+   * This is the asynchronous version of measure_disk_usage().  See
+   * there for more information.
+   *
+   * When the operation is finished, @a slot_ready will be called.
+   * You can then call measure_disk_usage_finish() to get the result of the operation.
+   *
+   * @param slot_ready A SlotAsyncReady to call when the request is satisfied
+   * @param cancellable A Cancellable object which can be used to cancel the operation
+   * @param slot_progress The callback slot to be called with progress information
+   * @param flags Set of FileMeasureFlags
+   * @param io_priority The I/O priority of the request
+   */
+  void measure_disk_usage_async(const SlotAsyncReady& slot_ready, const Glib::RefPtr<Cancellable>& 
cancellable, const SlotFileMeasureProgress& slot, FileMeasureFlags flags = FILE_MEASURE_NONE, int io_priority 
= Glib::PRIORITY_DEFAULT);
+  _IGNORE(g_file_measure_disk_usage_async)
+
+  _WRAP_METHOD(bool measure_disk_usage_finish(const Glib::RefPtr<AsyncResult>& result, guint64& disk_usage, 
guint64& num_dirs, guint64& num_files), g_file_measure_disk_usage_finish, errthrow)
+
+
+
  //TODO: The documentation for these start/stop/poll_mountable functions needs to be improved once we've 
figured out what they do and what the C documentation means. murrayc.
 
  /** Starts a file of type Mountable.
diff --git a/tools/m4/convert_glib.m4 b/tools/m4/convert_glib.m4
index 67fb4ce..5df0a27 100644
--- a/tools/m4/convert_glib.m4
+++ b/tools/m4/convert_glib.m4
@@ -46,6 +46,7 @@ _CONVERSION(`bool&',`gboolean*',`(($2) &($3))')
 _CONVERSION(`int&',`gint*',`&($3)')
 _CONVERSION(`gint*',`int&',`*($3)')
 _CONVERSION(`guint&',`guint*',`&($3)')
+_CONVERSION(`guint64&',`guint64*',`&($3)')
 _CONVERSION(`double&',`gdouble*',`&($3)')
 _CONVERSION(`float&',`gfloat*',`&($3)')
 _CONVERSION(`gchar**',`char**',`$3')



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]