Branch data Line data Source code
1 : : /*
2 : : * Copyright © 2009, 2010 Codethink Limited
3 : : * Copyright © 2011 Collabora Ltd.
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 Public
18 : : * License along with this library; if not, see <http://www.gnu.org/licenses/>.
19 : : *
20 : : * Author: Ryan Lortie <desrt@desrt.ca>
21 : : * Stef Walter <stefw@collabora.co.uk>
22 : : */
23 : :
24 : : #include "config.h"
25 : :
26 : : #include "gbytes.h"
27 : :
28 : : #include <glib/garray.h>
29 : : #include <glib/gstrfuncs.h>
30 : : #include <glib/gatomic.h>
31 : : #include <glib/gslice.h>
32 : : #include <glib/gtestutils.h>
33 : : #include <glib/gmem.h>
34 : : #include <glib/gmessages.h>
35 : : #include <glib/grefcount.h>
36 : :
37 : : #include <string.h>
38 : :
39 : : /**
40 : : * GBytes:
41 : : *
42 : : * A simple refcounted data type representing an immutable sequence of zero or
43 : : * more bytes from an unspecified origin.
44 : : *
45 : : * The purpose of a #GBytes is to keep the memory region that it holds
46 : : * alive for as long as anyone holds a reference to the bytes. When
47 : : * the last reference count is dropped, the memory is released. Multiple
48 : : * unrelated callers can use byte data in the #GBytes without coordinating
49 : : * their activities, resting assured that the byte data will not change or
50 : : * move while they hold a reference.
51 : : *
52 : : * A #GBytes can come from many different origins that may have
53 : : * different procedures for freeing the memory region. Examples are
54 : : * memory from g_malloc(), from memory slices, from a #GMappedFile or
55 : : * memory from other allocators.
56 : : *
57 : : * #GBytes work well as keys in #GHashTable. Use g_bytes_equal() and
58 : : * g_bytes_hash() as parameters to g_hash_table_new() or g_hash_table_new_full().
59 : : * #GBytes can also be used as keys in a #GTree by passing the g_bytes_compare()
60 : : * function to g_tree_new().
61 : : *
62 : : * The data pointed to by this bytes must not be modified. For a mutable
63 : : * array of bytes see #GByteArray. Use g_bytes_unref_to_array() to create a
64 : : * mutable array for a #GBytes sequence. To create an immutable #GBytes from
65 : : * a mutable #GByteArray, use the g_byte_array_free_to_bytes() function.
66 : : *
67 : : * Since: 2.32
68 : : **/
69 : :
70 : : /* Keep in sync with glib/tests/bytes.c */
71 : : struct _GBytes
72 : : {
73 : : gconstpointer data; /* may be NULL iff (size == 0) */
74 : : gsize size; /* may be 0 */
75 : : gatomicrefcount ref_count;
76 : : GDestroyNotify free_func;
77 : : gpointer user_data;
78 : : };
79 : :
80 : : /**
81 : : * g_bytes_new:
82 : : * @data: (transfer none) (array length=size) (element-type guint8) (nullable):
83 : : * the data to be used for the bytes
84 : : * @size: the size of @data
85 : : *
86 : : * Creates a new #GBytes from @data.
87 : : *
88 : : * @data is copied. If @size is 0, @data may be %NULL.
89 : : *
90 : : * Returns: (transfer full): a new #GBytes
91 : : *
92 : : * Since: 2.32
93 : : */
94 : : GBytes *
95 : 2841595 : g_bytes_new (gconstpointer data,
96 : : gsize size)
97 : : {
98 : 2841595 : g_return_val_if_fail (data != NULL || size == 0, NULL);
99 : :
100 : 2841595 : return g_bytes_new_take (g_memdup2 (data, size), size);
101 : : }
102 : :
103 : : /**
104 : : * g_bytes_new_take:
105 : : * @data: (transfer full) (array length=size) (element-type guint8) (nullable):
106 : : * the data to be used for the bytes
107 : : * @size: the size of @data
108 : : *
109 : : * Creates a new #GBytes from @data.
110 : : *
111 : : * After this call, @data belongs to the #GBytes and may no longer be
112 : : * modified by the caller. The memory of @data has to be dynamically
113 : : * allocated and will eventually be freed with g_free().
114 : : *
115 : : * For creating #GBytes with memory from other allocators, see
116 : : * g_bytes_new_with_free_func().
117 : : *
118 : : * @data may be %NULL if @size is 0.
119 : : *
120 : : * Returns: (transfer full): a new #GBytes
121 : : *
122 : : * Since: 2.32
123 : : */
124 : : GBytes *
125 : 2852635 : g_bytes_new_take (gpointer data,
126 : : gsize size)
127 : : {
128 : 2852635 : return g_bytes_new_with_free_func (data, size, g_free, data);
129 : : }
130 : :
131 : :
132 : : /**
133 : : * g_bytes_new_static: (skip)
134 : : * @data: (transfer full) (array length=size) (element-type guint8) (nullable):
135 : : * the data to be used for the bytes
136 : : * @size: the size of @data
137 : : *
138 : : * Creates a new #GBytes from static data.
139 : : *
140 : : * @data must be static (ie: never modified or freed). It may be %NULL if @size
141 : : * is 0.
142 : : *
143 : : * Returns: (transfer full): a new #GBytes
144 : : *
145 : : * Since: 2.32
146 : : */
147 : : GBytes *
148 : 1725 : g_bytes_new_static (gconstpointer data,
149 : : gsize size)
150 : : {
151 : 1725 : return g_bytes_new_with_free_func (data, size, NULL, NULL);
152 : : }
153 : :
154 : : /**
155 : : * g_bytes_new_with_free_func: (skip)
156 : : * @data: (array length=size) (element-type guint8) (nullable):
157 : : * the data to be used for the bytes
158 : : * @size: the size of @data
159 : : * @free_func: the function to call to release the data
160 : : * @user_data: data to pass to @free_func
161 : : *
162 : : * Creates a #GBytes from @data.
163 : : *
164 : : * When the last reference is dropped, @free_func will be called with the
165 : : * @user_data argument.
166 : : *
167 : : * @data must not be modified after this call is made until @free_func has
168 : : * been called to indicate that the bytes is no longer in use.
169 : : *
170 : : * @data may be %NULL if @size is 0.
171 : : *
172 : : * Returns: (transfer full): a new #GBytes
173 : : *
174 : : * Since: 2.32
175 : : */
176 : : GBytes *
177 : 2872271 : g_bytes_new_with_free_func (gconstpointer data,
178 : : gsize size,
179 : : GDestroyNotify free_func,
180 : : gpointer user_data)
181 : : {
182 : : GBytes *bytes;
183 : :
184 : 2872271 : g_return_val_if_fail (data != NULL || size == 0, NULL);
185 : :
186 : 2872271 : bytes = g_slice_new (GBytes);
187 : 2872271 : bytes->data = data;
188 : 2872271 : bytes->size = size;
189 : 2872271 : bytes->free_func = free_func;
190 : 2872271 : bytes->user_data = user_data;
191 : 2872271 : g_atomic_ref_count_init (&bytes->ref_count);
192 : :
193 : 2872271 : return (GBytes *)bytes;
194 : : }
195 : :
196 : : /**
197 : : * g_bytes_new_from_bytes:
198 : : * @bytes: a #GBytes
199 : : * @offset: offset which subsection starts at
200 : : * @length: length of subsection
201 : : *
202 : : * Creates a #GBytes which is a subsection of another #GBytes. The @offset +
203 : : * @length may not be longer than the size of @bytes.
204 : : *
205 : : * A reference to @bytes will be held by the newly created #GBytes until
206 : : * the byte data is no longer needed.
207 : : *
208 : : * Since 2.56, if @offset is 0 and @length matches the size of @bytes, then
209 : : * @bytes will be returned with the reference count incremented by 1. If @bytes
210 : : * is a slice of another #GBytes, then the resulting #GBytes will reference
211 : : * the same #GBytes instead of @bytes. This allows consumers to simplify the
212 : : * usage of #GBytes when asynchronously writing to streams.
213 : : *
214 : : * Returns: (transfer full): a new #GBytes
215 : : *
216 : : * Since: 2.32
217 : : */
218 : : GBytes *
219 : 449 : g_bytes_new_from_bytes (GBytes *bytes,
220 : : gsize offset,
221 : : gsize length)
222 : : {
223 : : gchar *base;
224 : :
225 : : /* Note that length may be 0. */
226 : 449 : g_return_val_if_fail (bytes != NULL, NULL);
227 : 449 : g_return_val_if_fail (offset <= bytes->size, NULL);
228 : 449 : g_return_val_if_fail (offset + length <= bytes->size, NULL);
229 : :
230 : : /* Avoid an extra GBytes if all bytes were requested */
231 [ + + + + ]: 449 : if (offset == 0 && length == bytes->size)
232 : 1 : return g_bytes_ref (bytes);
233 : :
234 : 448 : base = (gchar *)bytes->data + offset;
235 : :
236 : : /* Avoid referencing intermediate GBytes. In practice, this should
237 : : * only loop once.
238 : : */
239 [ + + ]: 450 : while (bytes->free_func == (gpointer)g_bytes_unref)
240 : 2 : bytes = bytes->user_data;
241 : :
242 : 448 : g_return_val_if_fail (bytes != NULL, NULL);
243 : 448 : g_return_val_if_fail (base >= (gchar *)bytes->data, NULL);
244 : 448 : g_return_val_if_fail (base <= (gchar *)bytes->data + bytes->size, NULL);
245 : 448 : g_return_val_if_fail (base + length <= (gchar *)bytes->data + bytes->size, NULL);
246 : :
247 : 448 : return g_bytes_new_with_free_func (base, length,
248 : 448 : (GDestroyNotify)g_bytes_unref, g_bytes_ref (bytes));
249 : : }
250 : :
251 : : /**
252 : : * g_bytes_get_data:
253 : : * @bytes: a #GBytes
254 : : * @size: (out) (optional): location to return size of byte data
255 : : *
256 : : * Get the byte data in the #GBytes. This data should not be modified.
257 : : *
258 : : * This function will always return the same pointer for a given #GBytes.
259 : : *
260 : : * %NULL may be returned if @size is 0. This is not guaranteed, as the #GBytes
261 : : * may represent an empty string with @data non-%NULL and @size as 0. %NULL will
262 : : * not be returned if @size is non-zero.
263 : : *
264 : : * Returns: (transfer none) (array length=size) (element-type guint8) (nullable):
265 : : * a pointer to the byte data, or %NULL
266 : : *
267 : : * Since: 2.32
268 : : */
269 : : gconstpointer
270 : 6265988 : g_bytes_get_data (GBytes *bytes,
271 : : gsize *size)
272 : : {
273 : 6265988 : g_return_val_if_fail (bytes != NULL, NULL);
274 [ + + ]: 6265988 : if (size)
275 : 6255721 : *size = bytes->size;
276 : 6265988 : return bytes->data;
277 : : }
278 : :
279 : : /**
280 : : * g_bytes_get_size:
281 : : * @bytes: a #GBytes
282 : : *
283 : : * Get the size of the byte data in the #GBytes.
284 : : *
285 : : * This function will always return the same value for a given #GBytes.
286 : : *
287 : : * Returns: the size
288 : : *
289 : : * Since: 2.32
290 : : */
291 : : gsize
292 : 1076490 : g_bytes_get_size (GBytes *bytes)
293 : : {
294 : 1076490 : g_return_val_if_fail (bytes != NULL, 0);
295 : 1076490 : return bytes->size;
296 : : }
297 : :
298 : :
299 : : /**
300 : : * g_bytes_ref:
301 : : * @bytes: a #GBytes
302 : : *
303 : : * Increase the reference count on @bytes.
304 : : *
305 : : * Returns: the #GBytes
306 : : *
307 : : * Since: 2.32
308 : : */
309 : : GBytes *
310 : 4616292 : g_bytes_ref (GBytes *bytes)
311 : : {
312 : 4616292 : g_return_val_if_fail (bytes != NULL, NULL);
313 : :
314 : 4616292 : g_atomic_ref_count_inc (&bytes->ref_count);
315 : :
316 : 4616292 : return bytes;
317 : : }
318 : :
319 : : /**
320 : : * g_bytes_unref:
321 : : * @bytes: (nullable): a #GBytes
322 : : *
323 : : * Releases a reference on @bytes. This may result in the bytes being
324 : : * freed. If @bytes is %NULL, it will return immediately.
325 : : *
326 : : * Since: 2.32
327 : : */
328 : : void
329 : 7487497 : g_bytes_unref (GBytes *bytes)
330 : : {
331 [ + + ]: 7487497 : if (bytes == NULL)
332 : 2 : return;
333 : :
334 [ + + ]: 7487495 : if (g_atomic_ref_count_dec (&bytes->ref_count))
335 : : {
336 [ + + ]: 2871207 : if (bytes->free_func != NULL)
337 : 2869412 : bytes->free_func (bytes->user_data);
338 : 2871207 : g_slice_free (GBytes, bytes);
339 : : }
340 : : }
341 : :
342 : : /**
343 : : * g_bytes_equal:
344 : : * @bytes1: (type GLib.Bytes): a pointer to a #GBytes
345 : : * @bytes2: (type GLib.Bytes): a pointer to a #GBytes to compare with @bytes1
346 : : *
347 : : * Compares the two #GBytes values being pointed to and returns
348 : : * %TRUE if they are equal.
349 : : *
350 : : * This function can be passed to g_hash_table_new() as the @key_equal_func
351 : : * parameter, when using non-%NULL #GBytes pointers as keys in a #GHashTable.
352 : : *
353 : : * Returns: %TRUE if the two keys match.
354 : : *
355 : : * Since: 2.32
356 : : */
357 : : gboolean
358 : 13 : g_bytes_equal (gconstpointer bytes1,
359 : : gconstpointer bytes2)
360 : : {
361 : 13 : const GBytes *b1 = bytes1;
362 : 13 : const GBytes *b2 = bytes2;
363 : :
364 : 13 : g_return_val_if_fail (bytes1 != NULL, FALSE);
365 : 13 : g_return_val_if_fail (bytes2 != NULL, FALSE);
366 : :
367 [ + + ]: 23 : return b1->size == b2->size &&
368 [ + + + + ]: 10 : (b1->size == 0 || memcmp (b1->data, b2->data, b1->size) == 0);
369 : : }
370 : :
371 : : /**
372 : : * g_bytes_hash:
373 : : * @bytes: (type GLib.Bytes): a pointer to a #GBytes key
374 : : *
375 : : * Creates an integer hash code for the byte data in the #GBytes.
376 : : *
377 : : * This function can be passed to g_hash_table_new() as the @key_hash_func
378 : : * parameter, when using non-%NULL #GBytes pointers as keys in a #GHashTable.
379 : : *
380 : : * Returns: a hash value corresponding to the key.
381 : : *
382 : : * Since: 2.32
383 : : */
384 : : guint
385 : 6 : g_bytes_hash (gconstpointer bytes)
386 : : {
387 : 6 : const GBytes *a = bytes;
388 : : const signed char *p, *e;
389 : 6 : guint32 h = 5381;
390 : :
391 : 6 : g_return_val_if_fail (bytes != NULL, 0);
392 : :
393 [ + + ]: 90 : for (p = (signed char *)a->data, e = (signed char *)a->data + a->size; p != e; p++)
394 : 84 : h = (h << 5) + h + *p;
395 : :
396 : 6 : return h;
397 : : }
398 : :
399 : : /**
400 : : * g_bytes_compare:
401 : : * @bytes1: (type GLib.Bytes): a pointer to a #GBytes
402 : : * @bytes2: (type GLib.Bytes): a pointer to a #GBytes to compare with @bytes1
403 : : *
404 : : * Compares the two #GBytes values.
405 : : *
406 : : * This function can be used to sort GBytes instances in lexicographical order.
407 : : *
408 : : * If @bytes1 and @bytes2 have different length but the shorter one is a
409 : : * prefix of the longer one then the shorter one is considered to be less than
410 : : * the longer one. Otherwise the first byte where both differ is used for
411 : : * comparison. If @bytes1 has a smaller value at that position it is
412 : : * considered less, otherwise greater than @bytes2.
413 : : *
414 : : * Returns: a negative value if @bytes1 is less than @bytes2, a positive value
415 : : * if @bytes1 is greater than @bytes2, and zero if @bytes1 is equal to
416 : : * @bytes2
417 : : *
418 : : *
419 : : * Since: 2.32
420 : : */
421 : : gint
422 : 6 : g_bytes_compare (gconstpointer bytes1,
423 : : gconstpointer bytes2)
424 : : {
425 : 6 : const GBytes *b1 = bytes1;
426 : 6 : const GBytes *b2 = bytes2;
427 : : gint ret;
428 : :
429 : 6 : g_return_val_if_fail (bytes1 != NULL, 0);
430 : 6 : g_return_val_if_fail (bytes2 != NULL, 0);
431 : :
432 : 6 : ret = memcmp (b1->data, b2->data, MIN (b1->size, b2->size));
433 [ + + + + ]: 6 : if (ret == 0 && b1->size != b2->size)
434 [ + + ]: 2 : ret = b1->size < b2->size ? -1 : 1;
435 : 6 : return ret;
436 : : }
437 : :
438 : : static gpointer
439 : 9 : try_steal_and_unref (GBytes *bytes,
440 : : GDestroyNotify free_func,
441 : : gsize *size)
442 : : {
443 : : gpointer result;
444 : :
445 [ + + + + ]: 9 : if (bytes->free_func != free_func || bytes->data == NULL ||
446 [ - + ]: 5 : bytes->user_data != bytes->data)
447 : 4 : return NULL;
448 : :
449 : : /* Are we the only reference? */
450 [ + + ]: 5 : if (g_atomic_ref_count_compare (&bytes->ref_count, 1))
451 : : {
452 : 3 : *size = bytes->size;
453 : 3 : result = (gpointer)bytes->data;
454 : 3 : g_slice_free (GBytes, bytes);
455 : 3 : return result;
456 : : }
457 : :
458 : 2 : return NULL;
459 : : }
460 : :
461 : :
462 : : /**
463 : : * g_bytes_unref_to_data:
464 : : * @bytes: (transfer full): a #GBytes
465 : : * @size: (out): location to place the length of the returned data
466 : : *
467 : : * Unreferences the bytes, and returns a pointer the same byte data
468 : : * contents.
469 : : *
470 : : * As an optimization, the byte data is returned without copying if this was
471 : : * the last reference to bytes and bytes was created with g_bytes_new(),
472 : : * g_bytes_new_take() or g_byte_array_free_to_bytes(). In all other cases the
473 : : * data is copied.
474 : : *
475 : : * Returns: (transfer full) (array length=size) (element-type guint8)
476 : : * (not nullable): a pointer to the same byte data, which should be
477 : : * freed with g_free()
478 : : *
479 : : * Since: 2.32
480 : : */
481 : : gpointer
482 : 9 : g_bytes_unref_to_data (GBytes *bytes,
483 : : gsize *size)
484 : : {
485 : : gpointer result;
486 : :
487 : 9 : g_return_val_if_fail (bytes != NULL, NULL);
488 : 9 : g_return_val_if_fail (size != NULL, NULL);
489 : :
490 : : /*
491 : : * Optimal path: if this is was the last reference, then we can return
492 : : * the data from this GBytes without copying.
493 : : */
494 : :
495 : 9 : result = try_steal_and_unref (bytes, g_free, size);
496 [ + + ]: 9 : if (result == NULL)
497 : : {
498 : : /*
499 : : * Copy: Non g_malloc (or compatible) allocator, or static memory,
500 : : * so we have to copy, and then unref.
501 : : */
502 : 6 : result = g_memdup2 (bytes->data, bytes->size);
503 : 6 : *size = bytes->size;
504 : 6 : g_bytes_unref (bytes);
505 : : }
506 : :
507 : 9 : return result;
508 : : }
509 : :
510 : : /**
511 : : * g_bytes_unref_to_array:
512 : : * @bytes: (transfer full): a #GBytes
513 : : *
514 : : * Unreferences the bytes, and returns a new mutable #GByteArray containing
515 : : * the same byte data.
516 : : *
517 : : * As an optimization, the byte data is transferred to the array without copying
518 : : * if this was the last reference to bytes and bytes was created with
519 : : * g_bytes_new(), g_bytes_new_take() or g_byte_array_free_to_bytes(). In all
520 : : * other cases the data is copied.
521 : : *
522 : : * Do not use it if @bytes contains more than %G_MAXUINT
523 : : * bytes. #GByteArray stores the length of its data in #guint, which
524 : : * may be shorter than #gsize, that @bytes is using.
525 : : *
526 : : * Returns: (transfer full): a new mutable #GByteArray containing the same byte data
527 : : *
528 : : * Since: 2.32
529 : : */
530 : : GByteArray *
531 : 4 : g_bytes_unref_to_array (GBytes *bytes)
532 : : {
533 : : gpointer data;
534 : : gsize size;
535 : :
536 : 4 : g_return_val_if_fail (bytes != NULL, NULL);
537 : :
538 : 4 : data = g_bytes_unref_to_data (bytes, &size);
539 : 4 : return g_byte_array_new_take (data, size);
540 : : }
541 : :
542 : : /**
543 : : * g_bytes_get_region:
544 : : * @bytes: a #GBytes
545 : : * @element_size: a non-zero element size
546 : : * @offset: an offset to the start of the region within the @bytes
547 : : * @n_elements: the number of elements in the region
548 : : *
549 : : * Gets a pointer to a region in @bytes.
550 : : *
551 : : * The region starts at @offset many bytes from the start of the data
552 : : * and contains @n_elements many elements of @element_size size.
553 : : *
554 : : * @n_elements may be zero, but @element_size must always be non-zero.
555 : : * Ideally, @element_size is a static constant (eg: sizeof a struct).
556 : : *
557 : : * This function does careful bounds checking (including checking for
558 : : * arithmetic overflows) and returns a non-%NULL pointer if the
559 : : * specified region lies entirely within the @bytes. If the region is
560 : : * in some way out of range, or if an overflow has occurred, then %NULL
561 : : * is returned.
562 : : *
563 : : * Note: it is possible to have a valid zero-size region. In this case,
564 : : * the returned pointer will be equal to the base pointer of the data of
565 : : * @bytes, plus @offset. This will be non-%NULL except for the case
566 : : * where @bytes itself was a zero-sized region. Since it is unlikely
567 : : * that you will be using this function to check for a zero-sized region
568 : : * in a zero-sized @bytes, %NULL effectively always means "error".
569 : : *
570 : : * Returns: (nullable): the requested region, or %NULL in case of an error
571 : : *
572 : : * Since: 2.70
573 : : */
574 : : gconstpointer
575 : 10 : g_bytes_get_region (GBytes *bytes,
576 : : gsize element_size,
577 : : gsize offset,
578 : : gsize n_elements)
579 : : {
580 : : gsize total_size;
581 : : gsize end_offset;
582 : :
583 : 10 : g_return_val_if_fail (element_size > 0, NULL);
584 : :
585 : : /* No other assertion checks here. If something is wrong then we will
586 : : * simply crash (via NULL dereference or divide-by-zero).
587 : : */
588 : :
589 [ + + ]: 10 : if (!g_size_checked_mul (&total_size, element_size, n_elements))
590 : 2 : return NULL;
591 : :
592 [ + + ]: 8 : if (!g_size_checked_add (&end_offset, offset, total_size))
593 : 2 : return NULL;
594 : :
595 : : /* We now have:
596 : : *
597 : : * 0 <= offset <= end_offset
598 : : *
599 : : * So we need only check that end_offset is within the range of the
600 : : * size of @bytes and we're good to go.
601 : : */
602 : :
603 [ + + ]: 6 : if (end_offset > bytes->size)
604 : 3 : return NULL;
605 : :
606 : : /* We now have:
607 : : *
608 : : * 0 <= offset <= end_offset <= bytes->size
609 : : */
610 : :
611 : 3 : return ((guchar *) bytes->data) + offset;
612 : : }
|