mirror of
				https://gitlab.gnome.org/GNOME/glib.git
				synced 2025-11-01 00:42:16 +01:00 
			
		
		
		
	gbookmarkfile: Add copy function
GBookmarkFile has everything for being introspectable, but it lacks a GType, because it can't be copied. So provide a copy function that deeply copies all the bookmark structures. Add tests for this.
This commit is contained in:
		
				
					committed by
					
						 Philip Withnall
						Philip Withnall
					
				
			
			
				
	
			
			
			
						parent
						
							5f604460ef
						
					
				
				
					commit
					2e8375daa0
				
			| @@ -2152,6 +2152,7 @@ GBookmarkFile | ||||
| G_BOOKMARK_FILE_ERROR | ||||
| GBookmarkFileError | ||||
| g_bookmark_file_new | ||||
| g_bookmark_file_copy | ||||
| g_bookmark_file_free | ||||
| g_bookmark_file_load_from_file | ||||
| g_bookmark_file_load_from_data | ||||
|   | ||||
| @@ -287,6 +287,24 @@ bookmark_app_info_free (BookmarkAppInfo *app_info) | ||||
|   g_slice_free (BookmarkAppInfo, app_info); | ||||
| } | ||||
|  | ||||
| static BookmarkAppInfo * | ||||
| bookmark_app_info_copy (BookmarkAppInfo *app_info) | ||||
| { | ||||
|   BookmarkAppInfo *copy; | ||||
|  | ||||
|   if (!app_info) | ||||
|     return NULL; | ||||
|  | ||||
|   copy = bookmark_app_info_new (app_info->name); | ||||
|   copy->count = app_info->count; | ||||
|   copy->exec = g_strdup (app_info->exec); | ||||
|  | ||||
|   if (app_info->stamp) | ||||
|     copy->stamp = g_date_time_ref (app_info->stamp); | ||||
|  | ||||
|   return copy; | ||||
| } | ||||
|  | ||||
| static gchar * | ||||
| bookmark_app_info_dump (BookmarkAppInfo *app_info) | ||||
| { | ||||
| @@ -382,6 +400,37 @@ bookmark_metadata_free (BookmarkMetadata *metadata) | ||||
|   g_slice_free (BookmarkMetadata, metadata); | ||||
| } | ||||
|  | ||||
| static BookmarkMetadata * | ||||
| bookmark_metadata_copy (BookmarkMetadata *metadata) | ||||
| { | ||||
|   BookmarkMetadata *copy; | ||||
|   GList *l; | ||||
|  | ||||
|   if (!metadata) | ||||
|     return NULL; | ||||
|  | ||||
|   copy = bookmark_metadata_new (); | ||||
|   copy->is_private = metadata->is_private; | ||||
|   copy->mime_type = g_strdup (metadata->mime_type); | ||||
|   copy->icon_href = g_strdup (metadata->icon_href); | ||||
|   copy->icon_mime = g_strdup (metadata->icon_mime); | ||||
|  | ||||
|   copy->groups = g_list_copy_deep (metadata->groups, (GCopyFunc) g_strdup, NULL); | ||||
|   copy->applications = | ||||
|     g_list_copy_deep (metadata->applications, (GCopyFunc) bookmark_app_info_copy, NULL); | ||||
|  | ||||
|   for (l = copy->applications; l; l = l->next) | ||||
|     { | ||||
|       BookmarkAppInfo *app_info = l->data; | ||||
|       g_hash_table_insert (copy->apps_by_name, app_info->name, app_info); | ||||
|     } | ||||
|  | ||||
|   g_assert (g_hash_table_size (copy->apps_by_name) == | ||||
|             g_hash_table_size (metadata->apps_by_name)); | ||||
|  | ||||
|   return copy; | ||||
| } | ||||
|  | ||||
| static gchar * | ||||
| bookmark_metadata_dump (BookmarkMetadata *metadata) | ||||
| { | ||||
| @@ -556,6 +605,31 @@ bookmark_item_free (BookmarkItem *item) | ||||
|   g_slice_free (BookmarkItem, item); | ||||
| } | ||||
|  | ||||
| static BookmarkItem * | ||||
| bookmark_item_copy (BookmarkItem *item) | ||||
| { | ||||
|   BookmarkItem* copy; | ||||
|  | ||||
|   if (!item) | ||||
|     return NULL; | ||||
|  | ||||
|   copy = bookmark_item_new (item->uri); | ||||
|  | ||||
|   copy->title = g_strdup (item->title); | ||||
|   copy->description = g_strdup (item->description); | ||||
|  | ||||
|   copy->metadata = bookmark_metadata_copy (item->metadata); | ||||
|  | ||||
|   if (item->added) | ||||
|     copy->added = g_date_time_ref (item->added); | ||||
|   if (item->modified) | ||||
|     copy->modified = g_date_time_ref (item->modified); | ||||
|   if (item->visited) | ||||
|     copy->visited = g_date_time_ref (item->visited); | ||||
|  | ||||
|   return copy; | ||||
| } | ||||
|  | ||||
| static void | ||||
| bookmark_item_touch_modified (BookmarkItem *item) | ||||
| { | ||||
| @@ -709,12 +783,7 @@ g_bookmark_file_clear (GBookmarkFile *bookmark) | ||||
|   g_list_free_full (bookmark->items, (GDestroyNotify) bookmark_item_free); | ||||
|   bookmark->items = NULL; | ||||
|  | ||||
|   if (bookmark->items_by_uri) | ||||
|     { | ||||
|       g_hash_table_destroy (bookmark->items_by_uri); | ||||
|  | ||||
|       bookmark->items_by_uri = NULL; | ||||
|     } | ||||
|   g_clear_pointer (&bookmark->items_by_uri, g_hash_table_unref); | ||||
| } | ||||
|  | ||||
| struct _ParseData | ||||
| @@ -1684,6 +1753,42 @@ g_bookmark_file_new (void) | ||||
|   return bookmark; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * g_bookmark_file_copy: | ||||
|  * @bookmark: A #GBookmarkFile | ||||
|  * | ||||
|  * Deeply copies a @bookmark #GBookmarkFile object to a new one. | ||||
|  * | ||||
|  * Returns: (transfer full): the copy of @bookmark. Use | ||||
|  *   g_bookmark_free() when finished using it. | ||||
|  * | ||||
|  * Since: 2.76 | ||||
|  */ | ||||
| GBookmarkFile * | ||||
| g_bookmark_file_copy (GBookmarkFile *bookmark) | ||||
| { | ||||
|   GBookmarkFile *copy; | ||||
|   GList *l; | ||||
|  | ||||
|   g_return_val_if_fail (bookmark != NULL, NULL); | ||||
|  | ||||
|   copy = g_bookmark_file_new (); | ||||
|   copy->title = g_strdup (bookmark->title); | ||||
|   copy->description = g_strdup (bookmark->description); | ||||
|   copy->items = g_list_copy_deep (bookmark->items, (GCopyFunc) bookmark_item_copy, NULL); | ||||
|  | ||||
|   for (l = copy->items; l; l = l->next) | ||||
|     { | ||||
|       BookmarkItem *item = l->data; | ||||
|       g_hash_table_insert (copy->items_by_uri, item->uri, item); | ||||
|     } | ||||
|  | ||||
|   g_assert (g_hash_table_size (copy->items_by_uri) == | ||||
|             g_hash_table_size (bookmark->items_by_uri)); | ||||
|  | ||||
|   return copy; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * g_bookmark_file_free: | ||||
|  * @bookmark: a #GBookmarkFile | ||||
|   | ||||
| @@ -84,6 +84,9 @@ GBookmarkFile *g_bookmark_file_new                 (void); | ||||
| GLIB_AVAILABLE_IN_ALL | ||||
| void           g_bookmark_file_free                (GBookmarkFile  *bookmark); | ||||
|  | ||||
| GLIB_AVAILABLE_IN_2_76 | ||||
| GBookmarkFile *g_bookmark_file_copy                (GBookmarkFile  *bookmark); | ||||
|  | ||||
| GLIB_AVAILABLE_IN_ALL | ||||
| gboolean       g_bookmark_file_load_from_file      (GBookmarkFile  *bookmark, | ||||
| 						    const gchar    *filename, | ||||
|   | ||||
| @@ -1245,6 +1245,99 @@ test_file (gconstpointer d) | ||||
|   g_assert_true (success == (strstr (filename, "fail") == NULL)); | ||||
| } | ||||
|  | ||||
| static void | ||||
| test_file_copy (gconstpointer d) | ||||
| { | ||||
|   const gchar *filename = d; | ||||
|   GBookmarkFile *bookmark_file; | ||||
|   GBookmarkFile *copy; | ||||
|   gboolean success; | ||||
|   gchar *data; | ||||
|   gchar *copy_data; | ||||
|   gsize length; | ||||
|   gsize copy_length; | ||||
|   GError *error = NULL; | ||||
|  | ||||
|   bookmark_file = g_bookmark_file_new (); | ||||
|   g_assert_nonnull (bookmark_file); | ||||
|  | ||||
|   success = test_load (bookmark_file, filename); | ||||
|   g_assert_true (success == (strstr (filename, "fail") == NULL)); | ||||
|  | ||||
|   copy = g_bookmark_file_copy (bookmark_file); | ||||
|   g_assert_nonnull (copy); | ||||
|  | ||||
|   if (g_str_has_suffix (filename, "fail-08.xbel") || | ||||
|       g_str_has_suffix (filename, "fail-06.xbel") || | ||||
|       g_str_has_suffix (filename, "fail-07.xbel") || | ||||
|       g_str_has_suffix (filename, "fail-09.xbel") || | ||||
|       g_str_has_suffix (filename, "fail-10.xbel") || | ||||
|       g_str_has_suffix (filename, "fail-11.xbel") || | ||||
|       g_str_has_suffix (filename, "fail-39.xbel")) | ||||
|     { | ||||
|       g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING, | ||||
|                              "*no registered applications*skipping*"); | ||||
|       g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING, | ||||
|                              "*no registered applications*skipping*"); | ||||
|     } | ||||
|  | ||||
|   data = g_bookmark_file_to_data (bookmark_file, &length, &error); | ||||
|   g_assert_no_error (error); | ||||
|  | ||||
|   copy_data = g_bookmark_file_to_data (copy, ©_length, &error); | ||||
|   g_assert_no_error (error); | ||||
|  | ||||
|   g_test_assert_expected_messages (); | ||||
|  | ||||
|   g_assert_cmpuint (length, ==, copy_length); | ||||
|   g_assert_cmpstr (data, ==, copy_data); | ||||
|  | ||||
|   if (success) | ||||
|     { | ||||
|       GBookmarkFile *modified_copy; | ||||
|       gchar *modified_data; | ||||
|       gchar *modified_copy_data; | ||||
|       gsize modified_length; | ||||
|       gsize modified_copy_length; | ||||
|  | ||||
|       test_modify (bookmark_file); | ||||
|       test_modify (copy); | ||||
|  | ||||
|       modified_data = g_bookmark_file_to_data (bookmark_file, | ||||
|                                                &modified_length, | ||||
|                                                &error); | ||||
|       g_assert_no_error (error); | ||||
|  | ||||
|       modified_copy_data = g_bookmark_file_to_data (copy, | ||||
|                                                     &modified_copy_length, | ||||
|                                                     &error); | ||||
|       g_assert_no_error (error); | ||||
|  | ||||
|       g_assert_cmpstr (data, !=, modified_data); | ||||
|       g_assert_cmpstr (copy_data, !=, modified_copy_data); | ||||
|  | ||||
|       g_free (modified_copy_data); | ||||
|       modified_copy = g_bookmark_file_copy (bookmark_file); | ||||
|       modified_copy_data = g_bookmark_file_to_data (modified_copy, | ||||
|                                                     &modified_copy_length, | ||||
|                                                     &error); | ||||
|       g_assert_no_error (error); | ||||
|  | ||||
|       g_assert_cmpuint (modified_length, ==, modified_copy_length); | ||||
|       g_assert_cmpstr (modified_data, ==, modified_copy_data); | ||||
|  | ||||
|       g_free (modified_data); | ||||
|       g_free (modified_copy_data); | ||||
|       g_bookmark_file_free (modified_copy); | ||||
|     } | ||||
|  | ||||
|   g_bookmark_file_free (bookmark_file); | ||||
|   g_bookmark_file_free (copy); | ||||
|  | ||||
|   g_free (data); | ||||
|   g_free (copy_data); | ||||
| } | ||||
|  | ||||
| int | ||||
| main (int argc, char *argv[]) | ||||
| { | ||||
| @@ -1275,12 +1368,17 @@ main (int argc, char *argv[]) | ||||
|   g_assert_no_error (error); | ||||
|   while ((name = g_dir_read_name (dir)) != NULL) | ||||
|     { | ||||
|       gchar *filename; | ||||
|       if (!g_str_has_suffix (name, ".xbel")) | ||||
|         continue; | ||||
|  | ||||
|       filename = g_test_build_filename (G_TEST_DIST, "bookmarks", name, NULL); | ||||
|  | ||||
|       path = g_strdup_printf ("/bookmarks/parse/%s", name); | ||||
|       g_test_add_data_func_full (path, g_test_build_filename (G_TEST_DIST, "bookmarks", name, NULL), | ||||
|                                  test_file, g_free); | ||||
|       g_test_add_data_func_full (path, filename, test_file, g_free); | ||||
|       g_free (path); | ||||
|       path = g_strdup_printf ("/bookmarks/copy/%s", name); | ||||
|       g_test_add_data_func_full (path, g_strdup (filename), test_file_copy, g_free); | ||||
|       g_free (path); | ||||
|     } | ||||
|   g_dir_close (dir); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user