Branch data Line data Source code
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 : 0 : _g_file_attribute_value_free (GFileAttributeValue *attr)
42 : : {
43 : 0 : g_return_if_fail (attr != NULL);
44 : :
45 : 0 : _g_file_attribute_value_clear (attr);
46 : 0 : g_free (attr);
47 : : }
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 : 12245 : _g_file_attribute_value_clear (GFileAttributeValue *attr)
59 : : {
60 : 12245 : g_return_if_fail (attr != NULL);
61 : :
62 : 12245 : if (attr->type == G_FILE_ATTRIBUTE_TYPE_STRING ||
63 : 11126 : attr->type == G_FILE_ATTRIBUTE_TYPE_BYTE_STRING)
64 : 1651 : g_free (attr->u.string);
65 : :
66 : 12245 : if (attr->type == G_FILE_ATTRIBUTE_TYPE_STRINGV)
67 : 0 : g_strfreev (attr->u.stringv);
68 : :
69 : 12245 : if (attr->type == G_FILE_ATTRIBUTE_TYPE_OBJECT &&
70 : 152 : attr->u.obj != NULL)
71 : 152 : g_object_unref (attr->u.obj);
72 : :
73 : 12245 : attr->type = G_FILE_ATTRIBUTE_TYPE_INVALID;
74 : : }
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 : 8 : _g_file_attribute_value_set (GFileAttributeValue *attr,
85 : : const GFileAttributeValue *new_value)
86 : : {
87 : 8 : g_return_if_fail (attr != NULL);
88 : 8 : g_return_if_fail (new_value != NULL);
89 : :
90 : 8 : _g_file_attribute_value_clear (attr);
91 : 8 : *attr = *new_value;
92 : :
93 : 8 : if (attr->type == G_FILE_ATTRIBUTE_TYPE_STRING ||
94 : 6 : attr->type == G_FILE_ATTRIBUTE_TYPE_BYTE_STRING)
95 : 8 : attr->u.string = g_strdup (attr->u.string);
96 : :
97 : 8 : if (attr->type == G_FILE_ATTRIBUTE_TYPE_STRINGV)
98 : 0 : attr->u.stringv = g_strdupv (attr->u.stringv);
99 : :
100 : 8 : if (attr->type == G_FILE_ATTRIBUTE_TYPE_OBJECT &&
101 : 0 : attr->u.obj != NULL)
102 : 0 : g_object_ref (attr->u.obj);
103 : : }
104 : :
105 : : /**
106 : : * _g_file_attribute_value_new:
107 : : *
108 : : * Creates a new file attribute.
109 : : *
110 : : * Returns: a #GFileAttributeValue.
111 : : **/
112 : : GFileAttributeValue *
113 : 0 : _g_file_attribute_value_new (void)
114 : : {
115 : : GFileAttributeValue *attr;
116 : :
117 : 0 : attr = g_new (GFileAttributeValue, 1);
118 : 0 : attr->type = G_FILE_ATTRIBUTE_TYPE_INVALID;
119 : 0 : return attr;
120 : : }
121 : :
122 : : gpointer
123 : 44 : _g_file_attribute_value_peek_as_pointer (GFileAttributeValue *attr)
124 : : {
125 : 44 : switch (attr->type) {
126 : 10 : case G_FILE_ATTRIBUTE_TYPE_STRING:
127 : : case G_FILE_ATTRIBUTE_TYPE_BYTE_STRING:
128 : 10 : 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 : 34 : default:
134 : 34 : return (gpointer) &attr->u;
135 : : }
136 : : }
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 : 0 : _g_file_attribute_value_dup (const GFileAttributeValue *other)
148 : : {
149 : : 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 : : }
158 : :
159 : 4 : 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 : 0 : valid_char (char c)
165 : : {
166 : 0 : return c >= 32 && c <= 126 && c != '\\';
167 : : }
168 : :
169 : : static char *
170 : 0 : escape_byte_string (const char *str)
171 : : {
172 : : size_t i, len;
173 : : int num_invalid;
174 : : char *escaped_val, *p;
175 : : 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 : : {
183 : 0 : if (!valid_char (str[i]))
184 : 0 : num_invalid++;
185 : : }
186 : :
187 : 0 : if (num_invalid == 0)
188 : 0 : return g_strdup (str);
189 : : else
190 : : {
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 : : {
196 : 0 : c = str[i];
197 : 0 : if (valid_char (c))
198 : 0 : *p++ = c;
199 : : else
200 : : {
201 : 0 : *p++ = '\\';
202 : 0 : *p++ = 'x';
203 : 0 : *p++ = hex_digits[(c >> 4) & 0xf];
204 : 0 : *p++ = hex_digits[c & 0xf];
205 : : }
206 : : }
207 : 0 : *p++ = 0;
208 : 0 : return escaped_val;
209 : : }
210 : : }
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 : 1 : _g_file_attribute_value_as_string (const GFileAttributeValue *attr)
224 : : {
225 : : GString *s;
226 : : int i;
227 : : char *str;
228 : :
229 : 1 : g_return_val_if_fail (attr != NULL, NULL);
230 : :
231 : 1 : switch (attr->type)
232 : : {
233 : 1 : case G_FILE_ATTRIBUTE_TYPE_STRING:
234 : 1 : str = g_strdup (attr->u.string);
235 : 1 : 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 : : {
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 : : }
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 : : }
278 : :
279 : 1 : return str;
280 : : }
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 : 208 : _g_file_attribute_value_get_string (const GFileAttributeValue *attr)
293 : : {
294 : 208 : if (attr == NULL)
295 : 4 : return NULL;
296 : :
297 : 204 : g_return_val_if_fail (attr->type == G_FILE_ATTRIBUTE_TYPE_STRING, NULL);
298 : :
299 : 204 : return attr->u.string;
300 : : }
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 : 284 : _g_file_attribute_value_get_byte_string (const GFileAttributeValue *attr)
313 : : {
314 : 284 : if (attr == NULL)
315 : 0 : return NULL;
316 : :
317 : 284 : g_return_val_if_fail (attr->type == G_FILE_ATTRIBUTE_TYPE_BYTE_STRING, NULL);
318 : :
319 : 284 : return attr->u.string;
320 : : }
321 : :
322 : : char **
323 : 0 : _g_file_attribute_value_get_stringv (const GFileAttributeValue *attr)
324 : : {
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 : : }
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 : 234 : _g_file_attribute_value_get_boolean (const GFileAttributeValue *attr)
344 : : {
345 : 234 : if (attr == NULL)
346 : 0 : return FALSE;
347 : :
348 : 234 : g_return_val_if_fail (attr->type == G_FILE_ATTRIBUTE_TYPE_BOOLEAN, FALSE);
349 : :
350 : 234 : return attr->u.boolean;
351 : : }
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 : 714 : _g_file_attribute_value_get_uint32 (const GFileAttributeValue *attr)
364 : : {
365 : 714 : if (attr == NULL)
366 : 3 : return 0;
367 : :
368 : 711 : g_return_val_if_fail (attr->type == G_FILE_ATTRIBUTE_TYPE_UINT32, 0);
369 : :
370 : 711 : return attr->u.uint32;
371 : : }
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 : 0 : _g_file_attribute_value_get_int32 (const GFileAttributeValue *attr)
384 : : {
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 : : }
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 : 184 : _g_file_attribute_value_get_uint64 (const GFileAttributeValue *attr)
404 : : {
405 : 184 : if (attr == NULL)
406 : 4 : return 0;
407 : :
408 : 180 : g_return_val_if_fail (attr->type == G_FILE_ATTRIBUTE_TYPE_UINT64, 0);
409 : :
410 : 180 : return attr->u.uint64;
411 : : }
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 : 0 : _g_file_attribute_value_get_int64 (const GFileAttributeValue *attr)
424 : : {
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 : : }
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 : 0 : _g_file_attribute_value_get_object (const GFileAttributeValue *attr)
444 : : {
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 : : }
452 : :
453 : :
454 : : void
455 : 191 : _g_file_attribute_value_set_from_pointer (GFileAttributeValue *value,
456 : : GFileAttributeType type,
457 : : gpointer value_p,
458 : : gboolean dup)
459 : : {
460 : 191 : _g_file_attribute_value_clear (value);
461 : 191 : value->type = type;
462 : 191 : switch (type)
463 : : {
464 : 10 : case G_FILE_ATTRIBUTE_TYPE_STRING:
465 : : case G_FILE_ATTRIBUTE_TYPE_BYTE_STRING:
466 : 10 : if (dup)
467 : 0 : value->u.string = g_strdup (value_p);
468 : : else
469 : 10 : value->u.string = value_p;
470 : 10 : break;
471 : :
472 : 0 : case G_FILE_ATTRIBUTE_TYPE_STRINGV:
473 : 0 : if (dup)
474 : 0 : value->u.stringv = g_strdupv (value_p);
475 : : 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 : : 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 : 146 : case G_FILE_ATTRIBUTE_TYPE_UINT32:
491 : 146 : value->u.uint32 = *(guint32 *)value_p;
492 : 146 : break;
493 : :
494 : 0 : case G_FILE_ATTRIBUTE_TYPE_INT32:
495 : 0 : value->u.int32 = *(gint32 *)value_p;
496 : 0 : break;
497 : :
498 : 34 : case G_FILE_ATTRIBUTE_TYPE_UINT64:
499 : 34 : value->u.uint64 = *(guint64 *)value_p;
500 : 34 : break;
501 : :
502 : 0 : case G_FILE_ATTRIBUTE_TYPE_INT64:
503 : 0 : value->u.int64 = *(gint64 *)value_p;
504 : 0 : break;
505 : :
506 : 1 : case G_FILE_ATTRIBUTE_TYPE_INVALID:
507 : 1 : break;
508 : :
509 : 0 : default:
510 : 0 : g_warning ("Unknown type specified in g_file_info_set_attribute");
511 : 0 : break;
512 : : }
513 : 191 : }
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 : 1117 : _g_file_attribute_value_set_string (GFileAttributeValue *attr,
524 : : const char *string)
525 : : {
526 : 1117 : g_return_if_fail (attr != NULL);
527 : 1117 : g_return_if_fail (string != NULL);
528 : :
529 : 1117 : _g_file_attribute_value_clear (attr);
530 : 1117 : attr->type = G_FILE_ATTRIBUTE_TYPE_STRING;
531 : 1117 : attr->u.string = g_strdup (string);
532 : : }
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 : 530 : _g_file_attribute_value_set_byte_string (GFileAttributeValue *attr,
543 : : const char *string)
544 : : {
545 : 530 : g_return_if_fail (attr != NULL);
546 : 530 : g_return_if_fail (string != NULL);
547 : :
548 : 530 : _g_file_attribute_value_clear (attr);
549 : 530 : attr->type = G_FILE_ATTRIBUTE_TYPE_BYTE_STRING;
550 : 530 : attr->u.string = g_strdup (string);
551 : : }
552 : :
553 : : void
554 : 0 : _g_file_attribute_value_set_stringv (GFileAttributeValue *attr,
555 : : char **value)
556 : : {
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 : : }
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 : 1183 : _g_file_attribute_value_set_boolean (GFileAttributeValue *attr,
575 : : gboolean value)
576 : : {
577 : 1183 : g_return_if_fail (attr != NULL);
578 : :
579 : 1183 : _g_file_attribute_value_clear (attr);
580 : 1183 : attr->type = G_FILE_ATTRIBUTE_TYPE_BOOLEAN;
581 : 1183 : attr->u.boolean = !!value;
582 : : }
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 : 2270 : _g_file_attribute_value_set_uint32 (GFileAttributeValue *attr,
593 : : guint32 value)
594 : : {
595 : 2270 : g_return_if_fail (attr != NULL);
596 : :
597 : 2270 : _g_file_attribute_value_clear (attr);
598 : 2270 : attr->type = G_FILE_ATTRIBUTE_TYPE_UINT32;
599 : 2270 : attr->u.uint32 = value;
600 : : }
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 : 1 : _g_file_attribute_value_set_int32 (GFileAttributeValue *attr,
611 : : gint32 value)
612 : : {
613 : 1 : g_return_if_fail (attr != NULL);
614 : :
615 : 1 : _g_file_attribute_value_clear (attr);
616 : 1 : attr->type = G_FILE_ATTRIBUTE_TYPE_INT32;
617 : 1 : attr->u.int32 = value;
618 : : }
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 : 913 : _g_file_attribute_value_set_uint64 (GFileAttributeValue *attr,
629 : : guint64 value)
630 : : {
631 : 913 : g_return_if_fail (attr != NULL);
632 : :
633 : 913 : _g_file_attribute_value_clear (attr);
634 : 913 : attr->type = G_FILE_ATTRIBUTE_TYPE_UINT64;
635 : 913 : attr->u.uint64 = value;
636 : : }
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 : 0 : _g_file_attribute_value_set_int64 (GFileAttributeValue *attr,
647 : : gint64 value)
648 : : {
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 : : }
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 : 152 : _g_file_attribute_value_set_object (GFileAttributeValue *attr,
666 : : GObject *obj)
667 : : {
668 : 152 : g_return_if_fail (attr != NULL);
669 : 152 : g_return_if_fail (obj != NULL);
670 : :
671 : 152 : _g_file_attribute_value_clear (attr);
672 : 152 : attr->type = G_FILE_ATTRIBUTE_TYPE_OBJECT;
673 : 152 : attr->u.obj = g_object_ref (obj);
674 : : }
675 : :
676 : : typedef struct {
677 : : GFileAttributeInfoList public;
678 : : GArray *array;
679 : : int ref_count;
680 : : } GFileAttributeInfoListPriv;
681 : :
682 : : static void
683 : 385 : list_update_public (GFileAttributeInfoListPriv *priv)
684 : : {
685 : 385 : priv->public.infos = (GFileAttributeInfo *)priv->array->data;
686 : 385 : priv->public.n_infos = priv->array->len;
687 : 385 : }
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 : 39 : g_file_attribute_info_list_new (void)
698 : : {
699 : : GFileAttributeInfoListPriv *priv;
700 : :
701 : 39 : priv = g_new0 (GFileAttributeInfoListPriv, 1);
702 : :
703 : 39 : priv->ref_count = 1;
704 : 39 : priv->array = g_array_new (TRUE, FALSE, sizeof (GFileAttributeInfo));
705 : :
706 : 39 : list_update_public (priv);
707 : :
708 : 39 : return (GFileAttributeInfoList *)priv;
709 : : }
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 : 0 : g_file_attribute_info_list_dup (GFileAttributeInfoList *list)
721 : : {
722 : : GFileAttributeInfoListPriv *new;
723 : : 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 : : {
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 : : }
739 : :
740 : 0 : return (GFileAttributeInfoList *)new;
741 : : }
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 : 144 : g_file_attribute_info_list_ref (GFileAttributeInfoList *list)
753 : : {
754 : 144 : GFileAttributeInfoListPriv *priv = (GFileAttributeInfoListPriv *)list;
755 : : int old_ref_count;
756 : :
757 : 144 : g_return_val_if_fail (list != NULL, NULL);
758 : :
759 : 144 : old_ref_count = g_atomic_int_add (&priv->ref_count, 1);
760 : 144 : g_return_val_if_fail (old_ref_count > 0, NULL);
761 : :
762 : 144 : return list;
763 : : }
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 : 144 : g_file_attribute_info_list_unref (GFileAttributeInfoList *list)
774 : : {
775 : 144 : GFileAttributeInfoListPriv *priv = (GFileAttributeInfoListPriv *)list;
776 : : int i;
777 : :
778 : 144 : g_return_if_fail (list != NULL);
779 : 144 : g_return_if_fail (priv->ref_count > 0);
780 : :
781 : 144 : if (g_atomic_int_dec_and_test (&priv->ref_count))
782 : : {
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 : : }
788 : : }
789 : :
790 : : static int
791 : 346 : g_file_attribute_info_list_bsearch (GFileAttributeInfoList *list,
792 : : const char *name)
793 : : {
794 : : int start, end, mid;
795 : :
796 : 346 : start = 0;
797 : 346 : end = list->n_infos;
798 : :
799 : 1097 : while (start != end)
800 : : {
801 : 751 : mid = start + (end - start) / 2;
802 : :
803 : 751 : if (strcmp (name, list->infos[mid].name) < 0)
804 : 476 : end = mid;
805 : 275 : else if (strcmp (name, list->infos[mid].name) > 0)
806 : 275 : start = mid + 1;
807 : : else
808 : 0 : return mid;
809 : : }
810 : 346 : return start;
811 : : }
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 : 0 : g_file_attribute_info_list_lookup (GFileAttributeInfoList *list,
825 : : const char *name)
826 : : {
827 : : 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 : : }
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 : 346 : g_file_attribute_info_list_add (GFileAttributeInfoList *list,
852 : : const char *name,
853 : : GFileAttributeType type,
854 : : GFileAttributeInfoFlags flags)
855 : : {
856 : 346 : GFileAttributeInfoListPriv *priv = (GFileAttributeInfoListPriv *)list;
857 : : GFileAttributeInfo info;
858 : : int i;
859 : :
860 : 346 : g_return_if_fail (list != NULL);
861 : 346 : g_return_if_fail (name != NULL);
862 : :
863 : 346 : i = g_file_attribute_info_list_bsearch (list, name);
864 : :
865 : 346 : if (i < list->n_infos && strcmp (list->infos[i].name, name) == 0)
866 : : {
867 : 0 : list->infos[i].type = type;
868 : 0 : return;
869 : : }
870 : :
871 : 346 : info.name = g_strdup (name);
872 : 346 : info.type = type;
873 : 346 : info.flags = flags;
874 : 346 : g_array_insert_vals (priv->array, i, &info, 1);
875 : :
876 : 346 : list_update_public (priv);
877 : : }
|