diff options
author | Murray Cumming <murrayc@murrayc.com> | 2013-09-20 10:27:40 +0200 |
---|---|---|
committer | Murray Cumming <murrayc@murrayc.com> | 2013-09-20 10:45:22 +0200 |
commit | 2b715e511f01f1dac742016f356c6866c4616a36 (patch) | |
tree | 5ba212602716a998ca2d73156c4e9ccb877691c8 /gio | |
parent | 9f5f3bb3bcabc538175607c1ac570ca6c7dbfcf6 (diff) | |
download | glibmm-2b715e511f01f1dac742016f356c6866c4616a36.tar.gz |
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&.
Diffstat (limited to 'gio')
-rw-r--r-- | gio/src/file.ccg | 91 | ||||
-rw-r--r-- | gio/src/file.hg | 96 |
2 files changed, 182 insertions, 5 deletions
diff --git a/gio/src/file.ccg b/gio/src/file.ccg index 0e7548a0..cdd31e6b 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 2281ed09..55591e25 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. |