hythmbox-2.98/lib/rb-async-copy.c

No issues found

  1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
  2  *
  3  *  Copyright (C) 2012  Jonathan Matthew  <jonathan@d14n.org>
  4  *
  5  *  This program is free software; you can redistribute it and/or modify
  6  *  it under the terms of the GNU General Public License as published by
  7  *  the Free Software Foundation; either version 2 of the License, or
  8  *  (at your option) any later version.
  9  *
 10  *  The Rhythmbox authors hereby grant permission for non-GPL compatible
 11  *  GStreamer plugins to be used and distributed together with GStreamer
 12  *  and Rhythmbox. This permission is above and beyond the permissions granted
 13  *  by the GPL license by which Rhythmbox is covered. If you modify this code
 14  *  you may extend this exception to your version of the code, but you are not
 15  *  obligated to do so. If you do not wish to do so, delete this exception
 16  *  statement from your version.
 17  *
 18  *  This program is distributed in the hope that it will be useful,
 19  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 20  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 21  *  GNU General Public License for more details.
 22  *
 23  *  You should have received a copy of the GNU General Public License
 24  *  along with this program; if not, write to the Free Software
 25  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA.
 26  *
 27  */
 28 
 29 #include "config.h"
 30 
 31 #include <lib/rb-async-copy.h>
 32 #include <lib/rb-debug.h>
 33 
 34 /**
 35  * SECTION:rb-async-copy
 36  * @short_description: performs asynchronous file copies (like g_file_copy_async)
 37  *
 38  */
 39 
 40 
 41 static void rb_async_copy_class_init (RBAsyncCopyClass *klass);
 42 static void rb_async_copy_init (RBAsyncCopy *copy);
 43 
 44 struct _RBAsyncCopyPrivate
 45 {
 46 	GError *error;
 47 	GCancellable *cancel;
 48 
 49 	GFile *src;
 50 	GFile *dest;
 51 
 52 	RBAsyncCopyCallback callback;
 53 	gpointer callback_data;
 54 	GDestroyNotify destroy_data;
 55 
 56 	RBAsyncCopyProgressCallback progress;
 57 	gpointer progress_data;
 58 	GDestroyNotify destroy_progress_data;
 59 };
 60 
 61 G_DEFINE_TYPE (RBAsyncCopy, rb_async_copy, G_TYPE_OBJECT);
 62 
 63 static void
 64 progress_cb (goffset current_num_bytes, goffset total_bytes, gpointer data)
 65 {
 66 	RBAsyncCopy *copy = RB_ASYNC_COPY (data);
 67 
 68 	if (copy->priv->progress)
 69 		copy->priv->progress (copy, current_num_bytes, total_bytes, copy->priv->progress_data);
 70 }
 71 
 72 static void
 73 copy_cb (GObject *src, GAsyncResult *res, gpointer data)
 74 {
 75 	RBAsyncCopy *copy = RB_ASYNC_COPY (data);
 76 	gboolean result;
 77 
 78 	result = g_file_copy_finish (G_FILE (src), res, &copy->priv->error);
 79 
 80 	rb_debug ("copy finished: %s", (result == FALSE) ? copy->priv->error->message : "ok");
 81 	copy->priv->callback (copy, result, copy->priv->callback_data);
 82 }
 83 
 84 /**
 85  * rb_async_copy_start:
 86  * @copy: a #RBAsyncCopy
 87  * @src: source URI
 88  * @dest: destination URI
 89  * @callback: completion callback
 90  * @user_data: data for completion callback
 91  * @destroy_data: destroy function for user_data
 92  *
 93  * Starts copying @src to @dest, calling @callback on completion or error.
 94  */
 95 void
 96 rb_async_copy_start (RBAsyncCopy *copy,
 97 		     const char *src,
 98 		     const char *dest,
 99 		     RBAsyncCopyCallback callback,
100 		     gpointer user_data,
101 		     GDestroyNotify destroy_data)
102 {
103 	g_assert (copy->priv->src == NULL);
104 
105 	copy->priv->cancel = g_cancellable_new ();
106 
107 	copy->priv->callback = callback;
108 	copy->priv->callback_data = user_data;
109 	copy->priv->destroy_data = destroy_data;
110 
111 	copy->priv->src = g_file_new_for_commandline_arg (src);
112 	copy->priv->dest = g_file_new_for_commandline_arg (dest);
113 
114 	g_file_copy_async (copy->priv->src,
115 			   copy->priv->dest,
116 			   G_FILE_COPY_NONE,
117 			   G_PRIORITY_DEFAULT,
118 			   copy->priv->cancel,
119 			   progress_cb,
120 			   copy,
121 			   copy_cb,
122 			   copy);
123 }
124 
125 /**
126  * rb_async_copy_cancel:
127  * @copy: a #RBAsyncCopy
128  *
129  * Cancels the loading operation, ensuring that the callback
130  * will not be called again.
131  */
132 void
133 rb_async_copy_cancel (RBAsyncCopy *copy)
134 {
135 	g_cancellable_cancel (copy->priv->cancel);
136 }
137 
138 /**
139  * rb_async_copy_set_callback:
140  * @copy: a #RBAsyncCopy
141  * @callback: the progress callback
142  * @user_data: data to pass to the callback
143  * @destroy_data: function to call to destroy user_data
144  *
145  * Sets the progress callback for the copy.  The callback will
146  * be called periodically while the copy is proceeding.
147  */
148 void
149 rb_async_copy_set_progress (RBAsyncCopy *copy,
150 			    RBAsyncCopyProgressCallback callback,
151 			    gpointer user_data,
152 			    GDestroyNotify destroy_data)
153 {
154 	g_assert (copy->priv->progress == NULL);
155 	g_assert (copy->priv->src == NULL);
156 
157 	copy->priv->progress = callback;
158 	copy->priv->progress_data = user_data;
159 	copy->priv->destroy_progress_data = destroy_data;
160 }
161 
162 /**
163  * rb_async_copy_get_error:
164  * @copy: a #RBAsyncCopy
165  *
166  * If an error has occurred that prevents the copy from proceeding,
167  * this function will return a #GError, otherwise NULL.
168  *
169  * Return value: copy error or NULL
170  */
171 GError *
172 rb_async_copy_get_error (RBAsyncCopy *copy)
173 {
174 	if (copy->priv->error)
175 		return g_error_copy (copy->priv->error);
176 	return NULL;
177 }
178 
179 /**
180  * rb_async_copy_new:
181  *
182  * Creates and returns a new #RBAsyncCopy instance.
183  *
184  * Return value: #RBAsyncCopy instance
185  */
186 RBAsyncCopy *
187 rb_async_copy_new (void)
188 {
189 	return RB_ASYNC_COPY (g_object_new (RB_TYPE_ASYNC_COPY, NULL));
190 }
191 
192 static void
193 impl_finalize (GObject *object)
194 {
195 	RBAsyncCopy *copy = RB_ASYNC_COPY (object);
196 
197 	g_clear_error (&copy->priv->error);
198 
199 	if (copy->priv->cancel) {
200 		g_object_unref (copy->priv->cancel);
201 		copy->priv->cancel = NULL;
202 	}
203 
204 	if (copy->priv->src) {
205 		g_object_unref (copy->priv->src);
206 		copy->priv->src = NULL;
207 	}
208 	if (copy->priv->dest) {
209 		g_object_unref (copy->priv->dest);
210 		copy->priv->dest = NULL;
211 	}
212 
213 	if (copy->priv->destroy_data) {
214 		copy->priv->destroy_data (copy->priv->callback_data);
215 	}
216 	if (copy->priv->destroy_progress_data) {
217 		copy->priv->destroy_progress_data (copy->priv->progress_data);
218 	}
219 
220 	G_OBJECT_CLASS (rb_async_copy_parent_class)->finalize (object);
221 }
222 
223 static void
224 rb_async_copy_init (RBAsyncCopy *copy)
225 {
226 	copy->priv = G_TYPE_INSTANCE_GET_PRIVATE (copy, RB_TYPE_ASYNC_COPY, RBAsyncCopyPrivate);
227 }
228 
229 static void
230 rb_async_copy_class_init (RBAsyncCopyClass *klass)
231 {
232 	GObjectClass *object_class = G_OBJECT_CLASS (klass);
233 
234 	object_class->finalize = impl_finalize;
235 
236 	g_type_class_add_private (klass, sizeof (RBAsyncCopyPrivate));
237 }