~ubuntu-branches/ubuntu/quantal/evolution-data-server/quantal

« back to all changes in this revision

Viewing changes to libedataserver/e-data-server-util.c

  • Committer: Package Import Robot
  • Author(s): Mathieu Trudel-Lapierre
  • Date: 2012-07-03 22:41:23 UTC
  • mfrom: (1.1.100)
  • Revision ID: package-import@ubuntu.com-20120703224123-90dydkyfyvff8s0s
Tags: 3.5.3.1-0ubuntu1
* New upstream release 3.5.3.1.
* debian/control:
  - Drop libgconf2-dev from Build-Depends.
  - Bump versions for glib, goa, and libsoup in Build-Depends.
  - Add a Build-Depends on libgcr-3-dev (>= 3.4)
  - Rename packages following upstream SONAME changes.
  - Add Depends on libgnome-keyring-dev to libedataserver1.2-dev.
* debian/rules:
  - Update mkshlibs arguments for libcamel-1.2-38 instead of -33; as it was
    renamed in control due to the soname change.
  - Strip out -Bsymbolic-functions from LDFLAGS.
* Renamed install files in debian/:
  - libcamel-1.2-33.install => libcamel-1.2-38.install
  - libebackend-1.2-2.install => libebackend-1.2-4.install
  - libebook-1.2-13.install => libebook-1.2-17.install
  - libecal-1.2-11.install => libecal-1.2-15.install
  - libedata-book-1.2-13.install => libedata-book-1.2-15.install
  - libedata-cal-1.2-15.install => libedata-cal-1.2-18.install
  - libedataserver-1.2-16.install => libedataserver-1.2-17.install
  - libedataserverui-3.0-1.install => libedataserverui-3.0-4.install
* debian/patches/google_tests_fpic.patch: build tests with -fPIC; otherwise
  build fails.

Show diffs side-by-side

added added

removed removed

Lines of Context:
124
124
}
125
125
 
126
126
/**
 
127
 * e_util_strdup_strip:
 
128
 * @string: (allow-none): a string value, or %NULL
 
129
 *
 
130
 * Duplicates @string and strips off any leading or trailing whitespace.
 
131
 * The resulting string is returned unless it is empty or %NULL, in which
 
132
 * case the function returns %NULL.
 
133
 *
 
134
 * Free the returned string with g_free().
 
135
 *
 
136
 * Returns: a newly-allocated, stripped copy of @string, or %NULL
 
137
 *
 
138
 * Since: 3.6
 
139
 **/
 
140
gchar *
 
141
e_util_strdup_strip (const gchar *string)
 
142
{
 
143
        gchar *duplicate;
 
144
 
 
145
        duplicate = g_strdup (string);
 
146
        if (duplicate != NULL) {
 
147
                g_strstrip (duplicate);
 
148
                if (*duplicate == '\0') {
 
149
                        g_free (duplicate);
 
150
                        duplicate = NULL;
 
151
                }
 
152
        }
 
153
 
 
154
        return duplicate;
 
155
}
 
156
 
 
157
/**
127
158
 * e_util_strstrcase:
128
159
 * @haystack: The string to search in.
129
160
 * @needle: The string to search for.
796
827
 
797
828
/**
798
829
 * e_util_slist_to_strv:
799
 
 * @strings: a #GSList of strings (const gchar *)
 
830
 * @strings: (element-type utf8): a #GSList of strings (const gchar *)
800
831
 *
801
832
 * Convert list of strings into NULL-terminates array of strings.
802
833
 *
803
 
 * Returns: (transfer full): Newly allocated NULL-terminated array of strings.
 
834
 * Returns: (transfer full): Newly allocated %NULL-terminated array of strings.
804
835
 * Returned pointer should be freed with g_strfreev().
805
836
 *
806
837
 * Note: Pair function for this is e_util_strv_to_slist().
834
865
 *
835
866
 * Convert NULL-terminated array of strings to a list of strings.
836
867
 *
837
 
 * Returns: (transfer full): Newly allocated #GSList of newly allocated strings.
838
 
 * Returned pointer should be freed with e_util_free_string_slist().
 
868
 * Returns: (transfer full) (element-type utf8): Newly allocated #GSList of
 
869
 * newly allocated strings. The returned pointer should be freed with
 
870
 * e_util_free_string_slist().
839
871
 *
840
872
 * Note: Pair function for this is e_util_slist_to_strv().
841
873
 *
859
891
 
860
892
/**
861
893
 * e_util_copy_string_slist:
862
 
 * @copy_to: Where to copy; can be NULL
863
 
 * @strings: GSList of strings to be copied
864
 
 *
865
 
 * Copies GSList of strings at the end of @copy_to.
866
 
 *
867
 
 * Returns: (transfer full): New head of @copy_to.
 
894
 * @copy_to: (element-type utf8) (allow-none): Where to copy; can be %NULL
 
895
 * @strings: (element-type utf8): #GSList of strings to be copied
 
896
 *
 
897
 * Copies #GSList of strings at the end of @copy_to.
 
898
 *
 
899
 * Returns: (transfer full) (element-type utf8): New head of @copy_to.
868
900
 * Returned pointer can be freed with e_util_free_string_slist().
869
901
 *
870
902
 * Since: 3.4
889
921
 
890
922
/**
891
923
 * e_util_copy_object_slist:
892
 
 * @copy_to: Where to copy; can be NULL
893
 
 * @objects: GSList of GObject-s to be copied
894
 
 *
895
 
 * Copies GSList of GObject-s at the end of @copy_to.
896
 
 *
897
 
 * Returns: (transfer full): New head of @copy_to.
 
924
 * @copy_to: (element-type GObject) (allow-none): Where to copy; can be %NULL
 
925
 * @objects: (element-type GObject): #GSList of #GObject<!-- -->s to be copied
 
926
 *
 
927
 * Copies #GSList of #GObject<!-- -->s at the end of @copy_to.
 
928
 *
 
929
 * Returns: (transfer full) (element-type GObject): New head of @copy_to.
898
930
 * Returned pointer can be freed with e_util_free_object_slist().
899
931
 *
900
932
 * Since: 3.4
919
951
 
920
952
/**
921
953
 * e_util_free_string_slist:
922
 
 * @strings: a #GSList of strings (gchar *)
 
954
 * @strings: (element-type utf8): a #GSList of strings (gchar *)
923
955
 *
924
956
 * Frees memory previously allocated by e_util_strv_to_slist().
925
957
 *
933
965
 
934
966
/**
935
967
 * e_util_free_object_slist:
936
 
 * @objects: a #GSList of #GObject-s
 
968
 * @objects: (element-type GObject): a #GSList of #GObject<!-- -->s
937
969
 *
938
970
 * Calls g_object_unref() on each member of @objects and then frees
939
971
 * also @objects itself.
947
979
}
948
980
 
949
981
/**
 
982
 * e_util_free_nullable_object_slist:
 
983
 * @objects: (element-type GObject): a #GSList of nullable #GObject<!-- -->s
 
984
 *
 
985
 * Calls g_object_unref() on each member of @objects if non-%NULL and then frees
 
986
 * also @objects itself.
 
987
 *
 
988
 * Since: 3.6
 
989
 **/
 
990
void
 
991
e_util_free_nullable_object_slist (GSList *objects)
 
992
{
 
993
        const GSList *l;
 
994
        for (l = objects; l; l = l->next) {
 
995
                if (l->data)
 
996
                        g_object_unref (l->data);
 
997
        }
 
998
        g_slist_free (objects);
 
999
}
 
1000
 
 
1001
/* Helper for e_file_recursive_delete() */
 
1002
static void
 
1003
file_recursive_delete_thread (GSimpleAsyncResult *simple,
 
1004
                              GObject *object,
 
1005
                              GCancellable *cancellable)
 
1006
{
 
1007
        GError *error = NULL;
 
1008
 
 
1009
        e_file_recursive_delete_sync (G_FILE (object), cancellable, &error);
 
1010
 
 
1011
        if (error != NULL)
 
1012
                g_simple_async_result_take_error (simple, error);
 
1013
}
 
1014
 
 
1015
/**
 
1016
 * e_file_recursive_delete_sync:
 
1017
 * @file: a #GFile to delete
 
1018
 * @cancellable: optional #GCancellable object, or %NULL
 
1019
 * @error: return location for a #GError, or %NULL
 
1020
 *
 
1021
 * Deletes @file.  If @file is a directory, its contents are deleted
 
1022
 * recursively before @file itself is deleted.  The recursive delete
 
1023
 * operation will stop on the first error.
 
1024
 *
 
1025
 * If @cancellable is not %NULL, then the operation can be cancelled
 
1026
 * by triggering the cancellable object from another thread.  If the
 
1027
 * operation was cancelled, the error #G_IO_ERROR_CANCELLED will be
 
1028
 * returned.
 
1029
 *
 
1030
 * Returns: %TRUE if the file was deleted, %FALSE otherwise
 
1031
 *
 
1032
 * Since: 3.6
 
1033
 **/
 
1034
gboolean
 
1035
e_file_recursive_delete_sync (GFile *file,
 
1036
                              GCancellable *cancellable,
 
1037
                              GError **error)
 
1038
{
 
1039
        GFileEnumerator *file_enumerator;
 
1040
        GFileInfo *file_info;
 
1041
        GFileType file_type;
 
1042
        gboolean success = TRUE;
 
1043
        GError *local_error = NULL;
 
1044
 
 
1045
        g_return_val_if_fail (G_IS_FILE (file), FALSE);
 
1046
 
 
1047
        file_type = g_file_query_file_type (
 
1048
                file, G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, cancellable);
 
1049
 
 
1050
        /* If this is not a directory, delete like normal. */
 
1051
        if (file_type != G_FILE_TYPE_DIRECTORY)
 
1052
                return g_file_delete (file, cancellable, error);
 
1053
 
 
1054
        /* Note, G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS is critical here
 
1055
         * so we only delete files inside the directory being deleted. */
 
1056
        file_enumerator = g_file_enumerate_children (
 
1057
                file, G_FILE_ATTRIBUTE_STANDARD_NAME,
 
1058
                G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
 
1059
                cancellable, error);
 
1060
 
 
1061
        if (file_enumerator == NULL)
 
1062
                return FALSE;
 
1063
 
 
1064
        file_info = g_file_enumerator_next_file (
 
1065
                file_enumerator, cancellable, &local_error);
 
1066
 
 
1067
        while (file_info != NULL) {
 
1068
                GFile *child;
 
1069
                const gchar *name;
 
1070
 
 
1071
                name = g_file_info_get_name (file_info);
 
1072
 
 
1073
                /* Here's the recursive part. */
 
1074
                child = g_file_get_child (file, name);
 
1075
                success = e_file_recursive_delete_sync (
 
1076
                        child, cancellable, error);
 
1077
                g_object_unref (child);
 
1078
 
 
1079
                g_object_unref (file_info);
 
1080
 
 
1081
                if (!success)
 
1082
                        break;
 
1083
 
 
1084
                file_info = g_file_enumerator_next_file (
 
1085
                        file_enumerator, cancellable, &local_error);
 
1086
        }
 
1087
 
 
1088
        if (local_error != NULL) {
 
1089
                g_propagate_error (error, local_error);
 
1090
                success = FALSE;
 
1091
        }
 
1092
 
 
1093
        g_object_unref (file_enumerator);
 
1094
 
 
1095
        if (!success)
 
1096
                return FALSE;
 
1097
 
 
1098
        /* The directory should be empty now. */
 
1099
        return g_file_delete (file, cancellable, error);
 
1100
}
 
1101
 
 
1102
/**
 
1103
 * e_file_recursive_delete:
 
1104
 * @file: a #GFile to delete
 
1105
 * @io_priority: the I/O priority of the request
 
1106
 * @cancellable: optional #GCancellable object, or %NULL
 
1107
 * @callback: a #GAsyncReadyCallback to call when the request is satisfied
 
1108
 * @user_data: data to pass to the callback function
 
1109
 *
 
1110
 * Asynchronously deletes @file.  If @file is a directory, its contents
 
1111
 * are deleted recursively before @file itself is deleted.  The recursive
 
1112
 * delete operation will stop on the first error.
 
1113
 *
 
1114
 * If @cancellable is not %NULL, then the operation can be cancelled
 
1115
 * by triggering the cancellable object before the operation finishes.
 
1116
 *
 
1117
 * When the operation is finished, @callback will be called.  You can then
 
1118
 * call e_file_recursive_delete_finish() to get the result of the operation.
 
1119
 *
 
1120
 * Since: 3.6
 
1121
 **/
 
1122
void
 
1123
e_file_recursive_delete (GFile *file,
 
1124
                         gint io_priority,
 
1125
                         GCancellable *cancellable,
 
1126
                         GAsyncReadyCallback callback,
 
1127
                         gpointer user_data)
 
1128
{
 
1129
        GSimpleAsyncResult *simple;
 
1130
 
 
1131
        g_return_if_fail (G_IS_FILE (file));
 
1132
 
 
1133
        simple = g_simple_async_result_new (
 
1134
                G_OBJECT (file), callback, user_data,
 
1135
                e_file_recursive_delete);
 
1136
 
 
1137
        g_simple_async_result_set_check_cancellable (simple, cancellable);
 
1138
 
 
1139
        g_simple_async_result_run_in_thread (
 
1140
                simple, file_recursive_delete_thread,
 
1141
                io_priority, cancellable);
 
1142
 
 
1143
        g_object_unref (simple);
 
1144
}
 
1145
 
 
1146
/**
 
1147
 * e_file_recursive_delete_finish:
 
1148
 * @file: a #GFile to delete
 
1149
 * @result: a #GAsyncResult
 
1150
 * @error: return location for a #GError, or %NULL
 
1151
 *
 
1152
 * Finishes the operation started with e_file_recursive_delete().
 
1153
 *
 
1154
 * If the operation was cancelled, the error #G_IO_ERROR_CANCELLED will be
 
1155
 * returned.
 
1156
 *
 
1157
 * Returns: %TRUE if the file was deleted, %FALSE otherwise
 
1158
 *
 
1159
 * Since: 3.6
 
1160
 **/
 
1161
gboolean
 
1162
e_file_recursive_delete_finish (GFile *file,
 
1163
                                GAsyncResult *result,
 
1164
                                GError **error)
 
1165
{
 
1166
        GSimpleAsyncResult *simple;
 
1167
 
 
1168
        g_return_val_if_fail (
 
1169
                g_simple_async_result_is_valid (
 
1170
                result, G_OBJECT (file), e_file_recursive_delete), FALSE);
 
1171
 
 
1172
        simple = G_SIMPLE_ASYNC_RESULT (result);
 
1173
 
 
1174
        /* Assume success unless a GError is set. */
 
1175
        return !g_simple_async_result_propagate_error (simple, error);
 
1176
}
 
1177
 
 
1178
/**
950
1179
 * e_binding_transform_enum_value_to_nick:
951
1180
 * @binding: a #GBinding
952
1181
 * @source_value: a #GValue whose type is derived from #G_TYPE_ENUM
1024
1253
        return success;
1025
1254
}
1026
1255
 
 
1256
/**
 
1257
 * EAsyncClosure:
 
1258
 *
 
1259
 * #EAsyncClosure provides a simple way to run an asynchronous function
 
1260
 * synchronously without blocking a running #GMainLoop or using threads.
 
1261
 *
 
1262
 * 1) Create an #EAsyncClosure with e_async_closure_new().
 
1263
 *
 
1264
 * 2) Call the asynchronous function passing e_async_closure_callback() as
 
1265
 *    the #GAsyncReadyCallback argument and the #EAsyncClosure as the data
 
1266
 *    argument.
 
1267
 *
 
1268
 * 3) Call e_async_closure_wait() and collect the #GAsyncResult.
 
1269
 *
 
1270
 * 4) Call the corresponding asynchronous "finish" function, passing the
 
1271
 *    #GAsyncResult returned by e_async_closure_wait().
 
1272
 *
 
1273
 * 5) If needed, repeat steps 2-4 for additional asynchronous functions
 
1274
 *    using the same #EAsyncClosure.
 
1275
 *
 
1276
 * 6) Finally, free the #EAsyncClosure with e_async_closure_free().
 
1277
 *
 
1278
 * Since: 3.6
 
1279
 **/
 
1280
struct _EAsyncClosure {
 
1281
        GMainLoop *loop;
 
1282
        GMainContext *context;
 
1283
        GAsyncResult *result;
 
1284
};
 
1285
 
 
1286
/**
 
1287
 * e_async_closure_new:
 
1288
 *
 
1289
 * Creates a new #EAsyncClosure for use with asynchronous functions.
 
1290
 *
 
1291
 * Returns: a new #EAsyncClosure
 
1292
 *
 
1293
 * Since: 3.6
 
1294
 **/
 
1295
EAsyncClosure *
 
1296
e_async_closure_new (void)
 
1297
{
 
1298
        EAsyncClosure *closure;
 
1299
 
 
1300
        closure = g_slice_new0 (EAsyncClosure);
 
1301
        closure->context = g_main_context_new ();
 
1302
        closure->loop = g_main_loop_new (closure->context, FALSE);
 
1303
 
 
1304
        g_main_context_push_thread_default (closure->context);
 
1305
 
 
1306
        return closure;
 
1307
}
 
1308
 
 
1309
/**
 
1310
 * e_async_closure_wait:
 
1311
 * @closure: an #EAsyncClosure
 
1312
 *
 
1313
 * Call this function immediately after starting an asynchronous operation.
 
1314
 * The function waits for the asynchronous operation to complete and returns
 
1315
 * its #GAsyncResult to be passed to the operation's "finish" function.
 
1316
 *
 
1317
 * This function can be called repeatedly on the same #EAsyncClosure to
 
1318
 * easily string together multiple asynchronous operations.
 
1319
 *
 
1320
 * Returns: (transfer none): a #GAsyncResult which is owned by the closure
 
1321
 *
 
1322
 * Since: 3.6
 
1323
 **/
 
1324
GAsyncResult *
 
1325
e_async_closure_wait (EAsyncClosure *closure)
 
1326
{
 
1327
        g_return_val_if_fail (closure != NULL, NULL);
 
1328
 
 
1329
        g_main_loop_run (closure->loop);
 
1330
 
 
1331
        return closure->result;
 
1332
}
 
1333
 
 
1334
/**
 
1335
 * e_async_closure_free:
 
1336
 * @closure: an #EAsyncClosure
 
1337
 *
 
1338
 * Frees the @closure and the resources it holds.
 
1339
 *
 
1340
 * Since: 3.6
 
1341
 **/
 
1342
void
 
1343
e_async_closure_free (EAsyncClosure *closure)
 
1344
{
 
1345
        g_return_if_fail (closure != NULL);
 
1346
 
 
1347
        g_main_context_pop_thread_default (closure->context);
 
1348
 
 
1349
        g_main_loop_unref (closure->loop);
 
1350
        g_main_context_unref (closure->context);
 
1351
 
 
1352
        if (closure->result != NULL)
 
1353
                g_object_unref (closure->result);
 
1354
 
 
1355
        g_slice_free (EAsyncClosure, closure);
 
1356
}
 
1357
 
 
1358
/**
 
1359
 * e_async_closure_callback:
 
1360
 * @object: a #GObject
 
1361
 * @result: a #GAsyncResult
 
1362
 * @closure: an #EAsyncClosure
 
1363
 *
 
1364
 * Pass this function as the #GAsyncReadyCallback argument of an asynchronous
 
1365
 * function, and the #EAsyncClosure as the data argument.
 
1366
 *
 
1367
 * This causes e_async_closure_wait() to terminate and return @result.
 
1368
 *
 
1369
 * Since: 3.6
 
1370
 **/
 
1371
void
 
1372
e_async_closure_callback (GObject *object,
 
1373
                          GAsyncResult *result,
 
1374
                          gpointer closure)
 
1375
{
 
1376
        EAsyncClosure *real_closure;
 
1377
 
 
1378
        g_return_if_fail (G_IS_OBJECT (object));
 
1379
        g_return_if_fail (G_IS_ASYNC_RESULT (result));
 
1380
        g_return_if_fail (closure != NULL);
 
1381
 
 
1382
        real_closure = closure;
 
1383
 
 
1384
        /* Replace any previous result. */
 
1385
        if (real_closure->result != NULL)
 
1386
                g_object_unref (real_closure->result);
 
1387
        real_closure->result = g_object_ref (result);
 
1388
 
 
1389
        g_main_loop_quit (real_closure->loop);
 
1390
}
 
1391
 
1027
1392
#ifdef G_OS_WIN32
1028
1393
 
1029
1394
#include <windows.h>