/src/pango/subprojects/glib/gio/gfileattribute.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* GIO - GLib Input, Output and Streaming Library |
2 | | * |
3 | | * Copyright (C) 2006-2007 Red Hat, Inc. |
4 | | * |
5 | | * SPDX-License-Identifier: LGPL-2.1-or-later |
6 | | * |
7 | | * This library is free software; you can redistribute it and/or |
8 | | * modify it under the terms of the GNU Lesser General Public |
9 | | * License as published by the Free Software Foundation; either |
10 | | * version 2.1 of the License, or (at your option) any later version. |
11 | | * |
12 | | * This library is distributed in the hope that it will be useful, |
13 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
15 | | * Lesser General Public License for more details. |
16 | | * |
17 | | * You should have received a copy of the GNU Lesser General |
18 | | * Public License along with this library; if not, see <http://www.gnu.org/licenses/>. |
19 | | * |
20 | | * Author: Alexander Larsson <alexl@redhat.com> |
21 | | */ |
22 | | |
23 | | #include "config.h" |
24 | | |
25 | | #include <string.h> |
26 | | |
27 | | #include "gfileattribute.h" |
28 | | #include "gfileattribute-priv.h" |
29 | | #include <glib-object.h> |
30 | | #include "glibintl.h" |
31 | | |
32 | | |
33 | | /** |
34 | | * _g_file_attribute_value_free: |
35 | | * @attr: a #GFileAttributeValue. |
36 | | * |
37 | | * Frees the memory used by @attr. |
38 | | * |
39 | | **/ |
40 | | void |
41 | | _g_file_attribute_value_free (GFileAttributeValue *attr) |
42 | 0 | { |
43 | 0 | g_return_if_fail (attr != NULL); |
44 | | |
45 | 0 | _g_file_attribute_value_clear (attr); |
46 | 0 | g_free (attr); |
47 | 0 | } |
48 | | |
49 | | /** |
50 | | * _g_file_attribute_value_clear: |
51 | | * @attr: a #GFileAttributeValue. |
52 | | * |
53 | | * Clears the value of @attr and sets its type to |
54 | | * %G_FILE_ATTRIBUTE_TYPE_INVALID. |
55 | | * |
56 | | **/ |
57 | | void |
58 | | _g_file_attribute_value_clear (GFileAttributeValue *attr) |
59 | 0 | { |
60 | 0 | g_return_if_fail (attr != NULL); |
61 | | |
62 | 0 | if (attr->type == G_FILE_ATTRIBUTE_TYPE_STRING || |
63 | 0 | attr->type == G_FILE_ATTRIBUTE_TYPE_BYTE_STRING) |
64 | 0 | g_free (attr->u.string); |
65 | |
|
66 | 0 | if (attr->type == G_FILE_ATTRIBUTE_TYPE_STRINGV) |
67 | 0 | g_strfreev (attr->u.stringv); |
68 | |
|
69 | 0 | if (attr->type == G_FILE_ATTRIBUTE_TYPE_OBJECT && |
70 | 0 | attr->u.obj != NULL) |
71 | 0 | g_object_unref (attr->u.obj); |
72 | |
|
73 | 0 | attr->type = G_FILE_ATTRIBUTE_TYPE_INVALID; |
74 | 0 | } |
75 | | |
76 | | /** |
77 | | * g_file_attribute_value_set: |
78 | | * @attr: a #GFileAttributeValue to set the value in. |
79 | | * @new_value: a #GFileAttributeValue to get the value from. |
80 | | * |
81 | | * Sets an attribute's value from another attribute. |
82 | | **/ |
83 | | void |
84 | | _g_file_attribute_value_set (GFileAttributeValue *attr, |
85 | | const GFileAttributeValue *new_value) |
86 | 0 | { |
87 | 0 | g_return_if_fail (attr != NULL); |
88 | 0 | g_return_if_fail (new_value != NULL); |
89 | | |
90 | 0 | _g_file_attribute_value_clear (attr); |
91 | 0 | *attr = *new_value; |
92 | |
|
93 | 0 | if (attr->type == G_FILE_ATTRIBUTE_TYPE_STRING || |
94 | 0 | attr->type == G_FILE_ATTRIBUTE_TYPE_BYTE_STRING) |
95 | 0 | attr->u.string = g_strdup (attr->u.string); |
96 | |
|
97 | 0 | if (attr->type == G_FILE_ATTRIBUTE_TYPE_STRINGV) |
98 | 0 | attr->u.stringv = g_strdupv (attr->u.stringv); |
99 | |
|
100 | 0 | if (attr->type == G_FILE_ATTRIBUTE_TYPE_OBJECT && |
101 | 0 | attr->u.obj != NULL) |
102 | 0 | g_object_ref (attr->u.obj); |
103 | 0 | } |
104 | | |
105 | | /** |
106 | | * _g_file_attribute_value_new: |
107 | | * |
108 | | * Creates a new file attribute. |
109 | | * |
110 | | * Returns: a #GFileAttributeValue. |
111 | | **/ |
112 | | GFileAttributeValue * |
113 | | _g_file_attribute_value_new (void) |
114 | 0 | { |
115 | 0 | GFileAttributeValue *attr; |
116 | |
|
117 | 0 | attr = g_new (GFileAttributeValue, 1); |
118 | 0 | attr->type = G_FILE_ATTRIBUTE_TYPE_INVALID; |
119 | 0 | return attr; |
120 | 0 | } |
121 | | |
122 | | gpointer |
123 | | _g_file_attribute_value_peek_as_pointer (GFileAttributeValue *attr) |
124 | 0 | { |
125 | 0 | switch (attr->type) { |
126 | 0 | case G_FILE_ATTRIBUTE_TYPE_STRING: |
127 | 0 | case G_FILE_ATTRIBUTE_TYPE_BYTE_STRING: |
128 | 0 | return attr->u.string; |
129 | 0 | case G_FILE_ATTRIBUTE_TYPE_STRINGV: |
130 | 0 | return attr->u.stringv; |
131 | 0 | case G_FILE_ATTRIBUTE_TYPE_OBJECT: |
132 | 0 | return attr->u.obj; |
133 | 0 | default: |
134 | 0 | return (gpointer) &attr->u; |
135 | 0 | } |
136 | 0 | } |
137 | | |
138 | | /** |
139 | | * g_file_attribute_value_dup: |
140 | | * @other: a #GFileAttributeValue to duplicate. |
141 | | * |
142 | | * Duplicates a file attribute. |
143 | | * |
144 | | * Returns: a duplicate of the @other. |
145 | | **/ |
146 | | GFileAttributeValue * |
147 | | _g_file_attribute_value_dup (const GFileAttributeValue *other) |
148 | 0 | { |
149 | 0 | GFileAttributeValue *attr; |
150 | |
|
151 | 0 | g_return_val_if_fail (other != NULL, NULL); |
152 | | |
153 | 0 | attr = g_new (GFileAttributeValue, 1); |
154 | 0 | attr->type = G_FILE_ATTRIBUTE_TYPE_INVALID; |
155 | 0 | _g_file_attribute_value_set (attr, other); |
156 | 0 | return attr; |
157 | 0 | } |
158 | | |
159 | | G_DEFINE_BOXED_TYPE (GFileAttributeInfoList, g_file_attribute_info_list, |
160 | | g_file_attribute_info_list_dup, |
161 | | g_file_attribute_info_list_unref) |
162 | | |
163 | | static gboolean |
164 | | valid_char (char c) |
165 | 0 | { |
166 | 0 | return c >= 32 && c <= 126 && c != '\\'; |
167 | 0 | } |
168 | | |
169 | | static char * |
170 | | escape_byte_string (const char *str) |
171 | 0 | { |
172 | 0 | size_t i, len; |
173 | 0 | int num_invalid; |
174 | 0 | char *escaped_val, *p; |
175 | 0 | unsigned char c; |
176 | 0 | const char hex_digits[] = "0123456789abcdef"; |
177 | |
|
178 | 0 | len = strlen (str); |
179 | |
|
180 | 0 | num_invalid = 0; |
181 | 0 | for (i = 0; i < len; i++) |
182 | 0 | { |
183 | 0 | if (!valid_char (str[i])) |
184 | 0 | num_invalid++; |
185 | 0 | } |
186 | |
|
187 | 0 | if (num_invalid == 0) |
188 | 0 | return g_strdup (str); |
189 | 0 | else |
190 | 0 | { |
191 | 0 | escaped_val = g_malloc (len + num_invalid*3 + 1); |
192 | |
|
193 | 0 | p = escaped_val; |
194 | 0 | for (i = 0; i < len; i++) |
195 | 0 | { |
196 | 0 | c = str[i]; |
197 | 0 | if (valid_char (c)) |
198 | 0 | *p++ = c; |
199 | 0 | else |
200 | 0 | { |
201 | 0 | *p++ = '\\'; |
202 | 0 | *p++ = 'x'; |
203 | 0 | *p++ = hex_digits[(c >> 4) & 0xf]; |
204 | 0 | *p++ = hex_digits[c & 0xf]; |
205 | 0 | } |
206 | 0 | } |
207 | 0 | *p++ = 0; |
208 | 0 | return escaped_val; |
209 | 0 | } |
210 | 0 | } |
211 | | |
212 | | /** |
213 | | * _g_file_attribute_value_as_string: |
214 | | * @attr: a #GFileAttributeValue. |
215 | | * |
216 | | * Converts a #GFileAttributeValue to a string for display. |
217 | | * The returned string should be freed when no longer needed. |
218 | | * |
219 | | * Returns: a string from the @attr, %NULL on error, or "<invalid>" |
220 | | * if @attr is of type %G_FILE_ATTRIBUTE_TYPE_INVALID. |
221 | | */ |
222 | | char * |
223 | | _g_file_attribute_value_as_string (const GFileAttributeValue *attr) |
224 | 0 | { |
225 | 0 | GString *s; |
226 | 0 | int i; |
227 | 0 | char *str; |
228 | |
|
229 | 0 | g_return_val_if_fail (attr != NULL, NULL); |
230 | | |
231 | 0 | switch (attr->type) |
232 | 0 | { |
233 | 0 | case G_FILE_ATTRIBUTE_TYPE_STRING: |
234 | 0 | str = g_strdup (attr->u.string); |
235 | 0 | break; |
236 | 0 | case G_FILE_ATTRIBUTE_TYPE_STRINGV: |
237 | 0 | s = g_string_new ("["); |
238 | 0 | for (i = 0; attr->u.stringv[i] != NULL; i++) |
239 | 0 | { |
240 | 0 | g_string_append (s, attr->u.stringv[i]); |
241 | 0 | if (attr->u.stringv[i+1] != NULL) |
242 | 0 | g_string_append (s, ", "); |
243 | 0 | } |
244 | 0 | g_string_append (s, "]"); |
245 | 0 | str = g_string_free (s, FALSE); |
246 | 0 | break; |
247 | 0 | case G_FILE_ATTRIBUTE_TYPE_BYTE_STRING: |
248 | 0 | str = escape_byte_string (attr->u.string); |
249 | 0 | break; |
250 | 0 | case G_FILE_ATTRIBUTE_TYPE_BOOLEAN: |
251 | 0 | str = g_strdup_printf ("%s", attr->u.boolean?"TRUE":"FALSE"); |
252 | 0 | break; |
253 | 0 | case G_FILE_ATTRIBUTE_TYPE_UINT32: |
254 | 0 | str = g_strdup_printf ("%u", (unsigned int)attr->u.uint32); |
255 | 0 | break; |
256 | 0 | case G_FILE_ATTRIBUTE_TYPE_INT32: |
257 | 0 | str = g_strdup_printf ("%i", (int)attr->u.int32); |
258 | 0 | break; |
259 | 0 | case G_FILE_ATTRIBUTE_TYPE_UINT64: |
260 | 0 | str = g_strdup_printf ("%"G_GUINT64_FORMAT, attr->u.uint64); |
261 | 0 | break; |
262 | 0 | case G_FILE_ATTRIBUTE_TYPE_INT64: |
263 | 0 | str = g_strdup_printf ("%"G_GINT64_FORMAT, attr->u.int64); |
264 | 0 | break; |
265 | 0 | case G_FILE_ATTRIBUTE_TYPE_OBJECT: |
266 | 0 | str = g_strdup_printf ("%s:%p", g_type_name_from_instance |
267 | 0 | ((GTypeInstance *) attr->u.obj), |
268 | 0 | attr->u.obj); |
269 | 0 | break; |
270 | 0 | case G_FILE_ATTRIBUTE_TYPE_INVALID: |
271 | 0 | str = g_strdup ("<unset>"); |
272 | 0 | break; |
273 | 0 | default: |
274 | 0 | g_warning ("Invalid type in GFileInfo attribute"); |
275 | 0 | str = g_strdup ("<invalid>"); |
276 | 0 | break; |
277 | 0 | } |
278 | | |
279 | 0 | return str; |
280 | 0 | } |
281 | | |
282 | | /** |
283 | | * _g_file_attribute_value_get_string: |
284 | | * @attr: a #GFileAttributeValue. |
285 | | * |
286 | | * Gets the string from a file attribute value. If the value is not the |
287 | | * right type then %NULL will be returned. |
288 | | * |
289 | | * Returns: the UTF-8 string value contained within the attribute, or %NULL. |
290 | | */ |
291 | | const char * |
292 | | _g_file_attribute_value_get_string (const GFileAttributeValue *attr) |
293 | 0 | { |
294 | 0 | if (attr == NULL) |
295 | 0 | return NULL; |
296 | | |
297 | 0 | g_return_val_if_fail (attr->type == G_FILE_ATTRIBUTE_TYPE_STRING, NULL); |
298 | | |
299 | 0 | return attr->u.string; |
300 | 0 | } |
301 | | |
302 | | /** |
303 | | * _g_file_attribute_value_get_byte_string: |
304 | | * @attr: a #GFileAttributeValue. |
305 | | * |
306 | | * Gets the byte string from a file attribute value. If the value is not the |
307 | | * right type then %NULL will be returned. |
308 | | * |
309 | | * Returns: the byte string contained within the attribute or %NULL. |
310 | | */ |
311 | | const char * |
312 | | _g_file_attribute_value_get_byte_string (const GFileAttributeValue *attr) |
313 | 0 | { |
314 | 0 | if (attr == NULL) |
315 | 0 | return NULL; |
316 | | |
317 | 0 | g_return_val_if_fail (attr->type == G_FILE_ATTRIBUTE_TYPE_BYTE_STRING, NULL); |
318 | | |
319 | 0 | return attr->u.string; |
320 | 0 | } |
321 | | |
322 | | char ** |
323 | | _g_file_attribute_value_get_stringv (const GFileAttributeValue *attr) |
324 | 0 | { |
325 | 0 | if (attr == NULL) |
326 | 0 | return NULL; |
327 | | |
328 | 0 | g_return_val_if_fail (attr->type == G_FILE_ATTRIBUTE_TYPE_STRINGV, NULL); |
329 | | |
330 | 0 | return attr->u.stringv; |
331 | 0 | } |
332 | | |
333 | | /** |
334 | | * _g_file_attribute_value_get_boolean: |
335 | | * @attr: a #GFileAttributeValue. |
336 | | * |
337 | | * Gets the boolean value from a file attribute value. If the value is not the |
338 | | * right type then %FALSE will be returned. |
339 | | * |
340 | | * Returns: the boolean value contained within the attribute, or %FALSE. |
341 | | */ |
342 | | gboolean |
343 | | _g_file_attribute_value_get_boolean (const GFileAttributeValue *attr) |
344 | 0 | { |
345 | 0 | if (attr == NULL) |
346 | 0 | return FALSE; |
347 | | |
348 | 0 | g_return_val_if_fail (attr->type == G_FILE_ATTRIBUTE_TYPE_BOOLEAN, FALSE); |
349 | | |
350 | 0 | return attr->u.boolean; |
351 | 0 | } |
352 | | |
353 | | /** |
354 | | * _g_file_attribute_value_get_uint32: |
355 | | * @attr: a #GFileAttributeValue. |
356 | | * |
357 | | * Gets the unsigned 32-bit integer from a file attribute value. If the value |
358 | | * is not the right type then 0 will be returned. |
359 | | * |
360 | | * Returns: the unsigned 32-bit integer from the attribute, or 0. |
361 | | */ |
362 | | guint32 |
363 | | _g_file_attribute_value_get_uint32 (const GFileAttributeValue *attr) |
364 | 0 | { |
365 | 0 | if (attr == NULL) |
366 | 0 | return 0; |
367 | | |
368 | 0 | g_return_val_if_fail (attr->type == G_FILE_ATTRIBUTE_TYPE_UINT32, 0); |
369 | | |
370 | 0 | return attr->u.uint32; |
371 | 0 | } |
372 | | |
373 | | /** |
374 | | * _g_file_attribute_value_get_int32: |
375 | | * @attr: a #GFileAttributeValue. |
376 | | * |
377 | | * Gets the signed 32-bit integer from a file attribute value. If the value |
378 | | * is not the right type then 0 will be returned. |
379 | | * |
380 | | * Returns: the signed 32-bit integer from the attribute, or 0. |
381 | | */ |
382 | | gint32 |
383 | | _g_file_attribute_value_get_int32 (const GFileAttributeValue *attr) |
384 | 0 | { |
385 | 0 | if (attr == NULL) |
386 | 0 | return 0; |
387 | | |
388 | 0 | g_return_val_if_fail (attr->type == G_FILE_ATTRIBUTE_TYPE_INT32, 0); |
389 | | |
390 | 0 | return attr->u.int32; |
391 | 0 | } |
392 | | |
393 | | /** |
394 | | * _g_file_attribute_value_get_uint64: |
395 | | * @attr: a #GFileAttributeValue. |
396 | | * |
397 | | * Gets the unsigned 64-bit integer from a file attribute value. If the value |
398 | | * is not the right type then 0 will be returned. |
399 | | * |
400 | | * Returns: the unsigned 64-bit integer from the attribute, or 0. |
401 | | */ |
402 | | guint64 |
403 | | _g_file_attribute_value_get_uint64 (const GFileAttributeValue *attr) |
404 | 0 | { |
405 | 0 | if (attr == NULL) |
406 | 0 | return 0; |
407 | | |
408 | 0 | g_return_val_if_fail (attr->type == G_FILE_ATTRIBUTE_TYPE_UINT64, 0); |
409 | | |
410 | 0 | return attr->u.uint64; |
411 | 0 | } |
412 | | |
413 | | /** |
414 | | * _g_file_attribute_value_get_int64: |
415 | | * @attr: a #GFileAttributeValue. |
416 | | * |
417 | | * Gets the signed 64-bit integer from a file attribute value. If the value |
418 | | * is not the right type then 0 will be returned. |
419 | | * |
420 | | * Returns: the signed 64-bit integer from the attribute, or 0. |
421 | | */ |
422 | | gint64 |
423 | | _g_file_attribute_value_get_int64 (const GFileAttributeValue *attr) |
424 | 0 | { |
425 | 0 | if (attr == NULL) |
426 | 0 | return 0; |
427 | | |
428 | 0 | g_return_val_if_fail (attr->type == G_FILE_ATTRIBUTE_TYPE_INT64, 0); |
429 | | |
430 | 0 | return attr->u.int64; |
431 | 0 | } |
432 | | |
433 | | /** |
434 | | * _g_file_attribute_value_get_object: |
435 | | * @attr: a #GFileAttributeValue. |
436 | | * |
437 | | * Gets the GObject from a file attribute value. If the value |
438 | | * is not the right type then %NULL will be returned. |
439 | | * |
440 | | * Returns: the GObject from the attribute, or %NULL. |
441 | | **/ |
442 | | GObject * |
443 | | _g_file_attribute_value_get_object (const GFileAttributeValue *attr) |
444 | 0 | { |
445 | 0 | if (attr == NULL) |
446 | 0 | return NULL; |
447 | | |
448 | 0 | g_return_val_if_fail (attr->type == G_FILE_ATTRIBUTE_TYPE_OBJECT, NULL); |
449 | | |
450 | 0 | return attr->u.obj; |
451 | 0 | } |
452 | | |
453 | | |
454 | | void |
455 | | _g_file_attribute_value_set_from_pointer (GFileAttributeValue *value, |
456 | | GFileAttributeType type, |
457 | | gpointer value_p, |
458 | | gboolean dup) |
459 | 0 | { |
460 | 0 | _g_file_attribute_value_clear (value); |
461 | 0 | value->type = type; |
462 | 0 | switch (type) |
463 | 0 | { |
464 | 0 | case G_FILE_ATTRIBUTE_TYPE_STRING: |
465 | 0 | case G_FILE_ATTRIBUTE_TYPE_BYTE_STRING: |
466 | 0 | if (dup) |
467 | 0 | value->u.string = g_strdup (value_p); |
468 | 0 | else |
469 | 0 | value->u.string = value_p; |
470 | 0 | break; |
471 | | |
472 | 0 | case G_FILE_ATTRIBUTE_TYPE_STRINGV: |
473 | 0 | if (dup) |
474 | 0 | value->u.stringv = g_strdupv (value_p); |
475 | 0 | else |
476 | 0 | value->u.stringv = value_p; |
477 | 0 | break; |
478 | | |
479 | 0 | case G_FILE_ATTRIBUTE_TYPE_OBJECT: |
480 | 0 | if (dup) |
481 | 0 | value->u.obj = g_object_ref (value_p); |
482 | 0 | else |
483 | 0 | value->u.obj = value_p; |
484 | 0 | break; |
485 | | |
486 | 0 | case G_FILE_ATTRIBUTE_TYPE_BOOLEAN: |
487 | 0 | value->u.boolean = *(gboolean *)value_p; |
488 | 0 | break; |
489 | | |
490 | 0 | case G_FILE_ATTRIBUTE_TYPE_UINT32: |
491 | 0 | value->u.uint32 = *(guint32 *)value_p; |
492 | 0 | break; |
493 | | |
494 | 0 | case G_FILE_ATTRIBUTE_TYPE_INT32: |
495 | 0 | value->u.int32 = *(gint32 *)value_p; |
496 | 0 | break; |
497 | | |
498 | 0 | case G_FILE_ATTRIBUTE_TYPE_UINT64: |
499 | 0 | value->u.uint64 = *(guint64 *)value_p; |
500 | 0 | break; |
501 | | |
502 | 0 | case G_FILE_ATTRIBUTE_TYPE_INT64: |
503 | 0 | value->u.int64 = *(gint64 *)value_p; |
504 | 0 | break; |
505 | | |
506 | 0 | case G_FILE_ATTRIBUTE_TYPE_INVALID: |
507 | 0 | break; |
508 | | |
509 | 0 | default: |
510 | 0 | g_warning ("Unknown type specified in g_file_info_set_attribute"); |
511 | 0 | break; |
512 | 0 | } |
513 | 0 | } |
514 | | |
515 | | /** |
516 | | * _g_file_attribute_value_set_string: |
517 | | * @attr: a #GFileAttributeValue. |
518 | | * @string: a UTF-8 string to set within the type. |
519 | | * |
520 | | * Sets the attribute value to a given UTF-8 string. |
521 | | */ |
522 | | void |
523 | | _g_file_attribute_value_set_string (GFileAttributeValue *attr, |
524 | | const char *string) |
525 | 0 | { |
526 | 0 | g_return_if_fail (attr != NULL); |
527 | 0 | g_return_if_fail (string != NULL); |
528 | | |
529 | 0 | _g_file_attribute_value_clear (attr); |
530 | 0 | attr->type = G_FILE_ATTRIBUTE_TYPE_STRING; |
531 | 0 | attr->u.string = g_strdup (string); |
532 | 0 | } |
533 | | |
534 | | /** |
535 | | * _g_file_attribute_value_set_byte_string: |
536 | | * @attr: a #GFileAttributeValue. |
537 | | * @string: a byte string to set within the type. |
538 | | * |
539 | | * Sets the attribute value to a given byte string. |
540 | | */ |
541 | | void |
542 | | _g_file_attribute_value_set_byte_string (GFileAttributeValue *attr, |
543 | | const char *string) |
544 | 0 | { |
545 | 0 | g_return_if_fail (attr != NULL); |
546 | 0 | g_return_if_fail (string != NULL); |
547 | | |
548 | 0 | _g_file_attribute_value_clear (attr); |
549 | 0 | attr->type = G_FILE_ATTRIBUTE_TYPE_BYTE_STRING; |
550 | 0 | attr->u.string = g_strdup (string); |
551 | 0 | } |
552 | | |
553 | | void |
554 | | _g_file_attribute_value_set_stringv (GFileAttributeValue *attr, |
555 | | char **value) |
556 | 0 | { |
557 | 0 | g_return_if_fail (attr != NULL); |
558 | 0 | g_return_if_fail (value != NULL); |
559 | | |
560 | 0 | _g_file_attribute_value_clear (attr); |
561 | 0 | attr->type = G_FILE_ATTRIBUTE_TYPE_STRINGV; |
562 | 0 | attr->u.stringv = g_strdupv (value); |
563 | 0 | } |
564 | | |
565 | | |
566 | | /** |
567 | | * _g_file_attribute_value_set_boolean: |
568 | | * @attr: a #GFileAttributeValue. |
569 | | * @value: a #gboolean to set within the type. |
570 | | * |
571 | | * Sets the attribute value to the given boolean value. |
572 | | */ |
573 | | void |
574 | | _g_file_attribute_value_set_boolean (GFileAttributeValue *attr, |
575 | | gboolean value) |
576 | 0 | { |
577 | 0 | g_return_if_fail (attr != NULL); |
578 | | |
579 | 0 | _g_file_attribute_value_clear (attr); |
580 | 0 | attr->type = G_FILE_ATTRIBUTE_TYPE_BOOLEAN; |
581 | 0 | attr->u.boolean = !!value; |
582 | 0 | } |
583 | | |
584 | | /** |
585 | | * _g_file_attribute_value_set_uint32: |
586 | | * @attr: a #GFileAttributeValue. |
587 | | * @value: a #guint32 to set within the type. |
588 | | * |
589 | | * Sets the attribute value to the given unsigned 32-bit integer. |
590 | | */ |
591 | | void |
592 | | _g_file_attribute_value_set_uint32 (GFileAttributeValue *attr, |
593 | | guint32 value) |
594 | 0 | { |
595 | 0 | g_return_if_fail (attr != NULL); |
596 | | |
597 | 0 | _g_file_attribute_value_clear (attr); |
598 | 0 | attr->type = G_FILE_ATTRIBUTE_TYPE_UINT32; |
599 | 0 | attr->u.uint32 = value; |
600 | 0 | } |
601 | | |
602 | | /** |
603 | | * _g_file_attribute_value_set_int32: |
604 | | * @attr: a #GFileAttributeValue. |
605 | | * @value: a #gint32 to set within the type. |
606 | | * |
607 | | * Sets the attribute value to the given signed 32-bit integer. |
608 | | */ |
609 | | void |
610 | | _g_file_attribute_value_set_int32 (GFileAttributeValue *attr, |
611 | | gint32 value) |
612 | 0 | { |
613 | 0 | g_return_if_fail (attr != NULL); |
614 | | |
615 | 0 | _g_file_attribute_value_clear (attr); |
616 | 0 | attr->type = G_FILE_ATTRIBUTE_TYPE_INT32; |
617 | 0 | attr->u.int32 = value; |
618 | 0 | } |
619 | | |
620 | | /** |
621 | | * _g_file_attribute_value_set_uint64: |
622 | | * @attr: a #GFileAttributeValue. |
623 | | * @value: a #guint64 to set within the type. |
624 | | * |
625 | | * Sets the attribute value to a given unsigned 64-bit integer. |
626 | | */ |
627 | | void |
628 | | _g_file_attribute_value_set_uint64 (GFileAttributeValue *attr, |
629 | | guint64 value) |
630 | 0 | { |
631 | 0 | g_return_if_fail (attr != NULL); |
632 | | |
633 | 0 | _g_file_attribute_value_clear (attr); |
634 | 0 | attr->type = G_FILE_ATTRIBUTE_TYPE_UINT64; |
635 | 0 | attr->u.uint64 = value; |
636 | 0 | } |
637 | | |
638 | | /** |
639 | | * _g_file_attribute_value_set_int64: |
640 | | * @attr: a #GFileAttributeValue. |
641 | | * @value: a #gint64 to set within the type. |
642 | | * |
643 | | * Sets the attribute value to a given signed 64-bit integer. |
644 | | */ |
645 | | void |
646 | | _g_file_attribute_value_set_int64 (GFileAttributeValue *attr, |
647 | | gint64 value) |
648 | 0 | { |
649 | 0 | g_return_if_fail (attr != NULL); |
650 | | |
651 | 0 | _g_file_attribute_value_clear (attr); |
652 | 0 | attr->type = G_FILE_ATTRIBUTE_TYPE_INT64; |
653 | 0 | attr->u.int64 = value; |
654 | 0 | } |
655 | | |
656 | | /** |
657 | | * _g_file_attribute_value_set_object: |
658 | | * @attr: a #GFileAttributeValue. |
659 | | * @obj: a #GObject. |
660 | | * |
661 | | * Sets the attribute to contain the value @obj. |
662 | | * The @attr references the GObject internally. |
663 | | */ |
664 | | void |
665 | | _g_file_attribute_value_set_object (GFileAttributeValue *attr, |
666 | | GObject *obj) |
667 | 0 | { |
668 | 0 | g_return_if_fail (attr != NULL); |
669 | 0 | g_return_if_fail (obj != NULL); |
670 | | |
671 | 0 | _g_file_attribute_value_clear (attr); |
672 | 0 | attr->type = G_FILE_ATTRIBUTE_TYPE_OBJECT; |
673 | 0 | attr->u.obj = g_object_ref (obj); |
674 | 0 | } |
675 | | |
676 | | typedef struct { |
677 | | GFileAttributeInfoList public; |
678 | | GArray *array; |
679 | | int ref_count; |
680 | | } GFileAttributeInfoListPriv; |
681 | | |
682 | | static void |
683 | | list_update_public (GFileAttributeInfoListPriv *priv) |
684 | 0 | { |
685 | 0 | priv->public.infos = (GFileAttributeInfo *)priv->array->data; |
686 | 0 | priv->public.n_infos = priv->array->len; |
687 | 0 | } |
688 | | |
689 | | /** |
690 | | * g_file_attribute_info_list_new: |
691 | | * |
692 | | * Creates a new file attribute info list. |
693 | | * |
694 | | * Returns: a #GFileAttributeInfoList. |
695 | | */ |
696 | | GFileAttributeInfoList * |
697 | | g_file_attribute_info_list_new (void) |
698 | 0 | { |
699 | 0 | GFileAttributeInfoListPriv *priv; |
700 | |
|
701 | 0 | priv = g_new0 (GFileAttributeInfoListPriv, 1); |
702 | |
|
703 | 0 | priv->ref_count = 1; |
704 | 0 | priv->array = g_array_new (TRUE, FALSE, sizeof (GFileAttributeInfo)); |
705 | |
|
706 | 0 | list_update_public (priv); |
707 | |
|
708 | 0 | return (GFileAttributeInfoList *)priv; |
709 | 0 | } |
710 | | |
711 | | /** |
712 | | * g_file_attribute_info_list_dup: |
713 | | * @list: a #GFileAttributeInfoList to duplicate. |
714 | | * |
715 | | * Makes a duplicate of a file attribute info list. |
716 | | * |
717 | | * Returns: a copy of the given @list. |
718 | | */ |
719 | | GFileAttributeInfoList * |
720 | | g_file_attribute_info_list_dup (GFileAttributeInfoList *list) |
721 | 0 | { |
722 | 0 | GFileAttributeInfoListPriv *new; |
723 | 0 | int i; |
724 | |
|
725 | 0 | g_return_val_if_fail (list != NULL, NULL); |
726 | | |
727 | 0 | new = g_new0 (GFileAttributeInfoListPriv, 1); |
728 | 0 | new->ref_count = 1; |
729 | 0 | new->array = g_array_new (TRUE, FALSE, sizeof (GFileAttributeInfo)); |
730 | |
|
731 | 0 | g_array_set_size (new->array, list->n_infos); |
732 | 0 | list_update_public (new); |
733 | 0 | for (i = 0; i < list->n_infos; i++) |
734 | 0 | { |
735 | 0 | new->public.infos[i].name = g_strdup (list->infos[i].name); |
736 | 0 | new->public.infos[i].type = list->infos[i].type; |
737 | 0 | new->public.infos[i].flags = list->infos[i].flags; |
738 | 0 | } |
739 | |
|
740 | 0 | return (GFileAttributeInfoList *)new; |
741 | 0 | } |
742 | | |
743 | | /** |
744 | | * g_file_attribute_info_list_ref: |
745 | | * @list: a #GFileAttributeInfoList to reference. |
746 | | * |
747 | | * References a file attribute info list. |
748 | | * |
749 | | * Returns: #GFileAttributeInfoList or %NULL on error. |
750 | | */ |
751 | | GFileAttributeInfoList * |
752 | | g_file_attribute_info_list_ref (GFileAttributeInfoList *list) |
753 | 0 | { |
754 | 0 | GFileAttributeInfoListPriv *priv = (GFileAttributeInfoListPriv *)list; |
755 | 0 | int old_ref_count; |
756 | |
|
757 | 0 | g_return_val_if_fail (list != NULL, NULL); |
758 | | |
759 | 0 | old_ref_count = g_atomic_int_add (&priv->ref_count, 1); |
760 | 0 | g_return_val_if_fail (old_ref_count > 0, NULL); |
761 | | |
762 | 0 | return list; |
763 | 0 | } |
764 | | |
765 | | /** |
766 | | * g_file_attribute_info_list_unref: |
767 | | * @list: The #GFileAttributeInfoList to unreference. |
768 | | * |
769 | | * Removes a reference from the given @list. If the reference count |
770 | | * falls to zero, the @list is deleted. |
771 | | */ |
772 | | void |
773 | | g_file_attribute_info_list_unref (GFileAttributeInfoList *list) |
774 | 0 | { |
775 | 0 | GFileAttributeInfoListPriv *priv = (GFileAttributeInfoListPriv *)list; |
776 | 0 | int i; |
777 | |
|
778 | 0 | g_return_if_fail (list != NULL); |
779 | 0 | g_return_if_fail (priv->ref_count > 0); |
780 | | |
781 | 0 | if (g_atomic_int_dec_and_test (&priv->ref_count)) |
782 | 0 | { |
783 | 0 | for (i = 0; i < list->n_infos; i++) |
784 | 0 | g_free (list->infos[i].name); |
785 | 0 | g_array_free (priv->array, TRUE); |
786 | 0 | g_free (list); |
787 | 0 | } |
788 | 0 | } |
789 | | |
790 | | static int |
791 | | g_file_attribute_info_list_bsearch (GFileAttributeInfoList *list, |
792 | | const char *name) |
793 | 0 | { |
794 | 0 | int start, end, mid; |
795 | |
|
796 | 0 | start = 0; |
797 | 0 | end = list->n_infos; |
798 | |
|
799 | 0 | while (start != end) |
800 | 0 | { |
801 | 0 | mid = start + (end - start) / 2; |
802 | |
|
803 | 0 | if (strcmp (name, list->infos[mid].name) < 0) |
804 | 0 | end = mid; |
805 | 0 | else if (strcmp (name, list->infos[mid].name) > 0) |
806 | 0 | start = mid + 1; |
807 | 0 | else |
808 | 0 | return mid; |
809 | 0 | } |
810 | 0 | return start; |
811 | 0 | } |
812 | | |
813 | | /** |
814 | | * g_file_attribute_info_list_lookup: |
815 | | * @list: a #GFileAttributeInfoList. |
816 | | * @name: the name of the attribute to look up. |
817 | | * |
818 | | * Gets the file attribute with the name @name from @list. |
819 | | * |
820 | | * Returns: a #GFileAttributeInfo for the @name, or %NULL if an |
821 | | * attribute isn't found. |
822 | | */ |
823 | | const GFileAttributeInfo * |
824 | | g_file_attribute_info_list_lookup (GFileAttributeInfoList *list, |
825 | | const char *name) |
826 | 0 | { |
827 | 0 | int i; |
828 | |
|
829 | 0 | g_return_val_if_fail (list != NULL, NULL); |
830 | 0 | g_return_val_if_fail (name != NULL, NULL); |
831 | | |
832 | 0 | i = g_file_attribute_info_list_bsearch (list, name); |
833 | |
|
834 | 0 | if (i < list->n_infos && strcmp (list->infos[i].name, name) == 0) |
835 | 0 | return &list->infos[i]; |
836 | | |
837 | 0 | return NULL; |
838 | 0 | } |
839 | | |
840 | | /** |
841 | | * g_file_attribute_info_list_add: |
842 | | * @list: a #GFileAttributeInfoList. |
843 | | * @name: the name of the attribute to add. |
844 | | * @type: the #GFileAttributeType for the attribute. |
845 | | * @flags: #GFileAttributeInfoFlags for the attribute. |
846 | | * |
847 | | * Adds a new attribute with @name to the @list, setting |
848 | | * its @type and @flags. |
849 | | */ |
850 | | void |
851 | | g_file_attribute_info_list_add (GFileAttributeInfoList *list, |
852 | | const char *name, |
853 | | GFileAttributeType type, |
854 | | GFileAttributeInfoFlags flags) |
855 | 0 | { |
856 | 0 | GFileAttributeInfoListPriv *priv = (GFileAttributeInfoListPriv *)list; |
857 | 0 | GFileAttributeInfo info; |
858 | 0 | int i; |
859 | |
|
860 | 0 | g_return_if_fail (list != NULL); |
861 | 0 | g_return_if_fail (name != NULL); |
862 | | |
863 | 0 | i = g_file_attribute_info_list_bsearch (list, name); |
864 | |
|
865 | 0 | if (i < list->n_infos && strcmp (list->infos[i].name, name) == 0) |
866 | 0 | { |
867 | 0 | list->infos[i].type = type; |
868 | 0 | return; |
869 | 0 | } |
870 | | |
871 | 0 | info.name = g_strdup (name); |
872 | 0 | info.type = type; |
873 | 0 | info.flags = flags; |
874 | 0 | g_array_insert_vals (priv->array, i, &info, 1); |
875 | |
|
876 | 0 | list_update_public (priv); |
877 | 0 | } |