GBytes: A new type for an immutable set of bytes.
[platform/upstream/glib.git] / glib / gbytes.c
1 /*
2  * Copyright © 2009, 2010 Codethink Limited
3  * Copyright © 2011 Collabora Ltd.
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the licence, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18  * Boston, MA 02111-1307, USA.
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
36 #include <string.h>
37
38 /**
39  * GBytes:
40  *
41  * A simple refcounted data type representing an immutable byte sequence
42  * from an unspecified origin.
43  *
44  * The purpose of a #GBytes is to keep the memory region that it holds
45  * alive for as long as anyone holds a reference to the bytes.  When
46  * the last reference count is dropped, the memory is released. Multiple
47  * unrelated callers can use byte data in the #GBytes without coordinating
48  * their activities, resting assured that the byte data will not change or
49  * move while they hold a reference.
50  *
51  * A #GBytes can come from many different origins that may have
52  * different procedures for freeing the memory region.  Examples are
53  * memory from g_malloc(), from memory slices, from a #GMappedFile or
54  * memory from other allocators.
55  *
56  * #GBytes work well as keys in #GHashTable. Use g_bytes_equal() and
57  * g_bytes_hash() as parameters to g_hash_table_new() or g_hash_table_new_full().
58  * #GBytes can also be used as keys in a #GTree by passing the g_bytes_compare()
59  * function to g_tree_new().
60  *
61  * The data pointed to by this bytes must not be modified. For a mutable
62  * array of bytes see #GByteArray. Use g_bytes_unref_to_array() to create a
63  * mutable array for a #GBytes sequence. To create an immutable #GBytes from
64  * a mutable #GByteArray, use the g_byte_array_free_to_bytes() function.
65  *
66  * Since: 2.32
67  **/
68
69 struct _GBytes
70 {
71   gconstpointer data;
72   gsize size;
73   gint ref_count;
74   GDestroyNotify free_func;
75   gpointer user_data;
76 };
77
78 /**
79  * g_bytes_new:
80  * @data: (array length=size): the data to be used for the bytes
81  * @size: the size of @data
82  *
83  * Creates a new #GBytes from @data.
84  *
85  * @data is copied.
86  *
87  * Returns: (transfer full): a new #GBytes
88  *
89  * Since: 2.32
90  */
91 GBytes *
92 g_bytes_new (gconstpointer data,
93              gsize         size)
94 {
95   return g_bytes_new_take (g_memdup (data, size), size);
96 }
97
98 /**
99  * g_bytes_new_take:
100  * @data: (transfer full) (array length=size): the data to be used for the bytes
101  * @size: the size of @data
102  *
103  * Creates a new #GBytes from @data.
104  *
105  * After this call, @data belongs to the bytes and may no longer be
106  * modified by the caller.  g_free() will be called on @data when the
107  * bytes is no longer in use. Because of this @data must have been created by
108  * a call to g_malloc(), g_malloc0() or g_realloc() or by one of the many
109  * functions that wrap these calls (such as g_new(), g_strdup(), etc).
110  *
111  * For creating #GBytes with memory from other allocators, see
112  * g_bytes_new_with_free_func().
113  *
114  * Returns: (transfer full): a new #GBytes
115  *
116  * Since: 2.32
117  */
118 GBytes *
119 g_bytes_new_take (gpointer data,
120                   gsize    size)
121 {
122   return g_bytes_new_with_free_func (data, size, g_free, data);
123 }
124
125
126 /**
127  * g_bytes_new_static:
128  * @data: (array length=size): the data to be used for the bytes
129  * @size: the size of @data
130  *
131  * Creates a new #GBytes from static data.
132  *
133  * @data must be static (ie: never modified or freed).
134  *
135  * Returns: (transfer full): a new #GBytes
136  *
137  * Since: 2.32
138  */
139 GBytes *
140 g_bytes_new_static (gconstpointer data,
141                     gsize         size)
142 {
143   return g_bytes_new_with_free_func (data, size, NULL, NULL);
144 }
145
146 /**
147  * g_bytes_new_with_free_func:
148  * @data: (array length=size): the data to be used for the bytes
149  * @size: the size of @data
150  * @free_func: the function to call to release the data
151  * @user_data: data to pass to @free_func
152  *
153  * Creates a #GBytes from @data.
154  *
155  * When the last reference is dropped, @free_func will be called with the
156  * @user_data argument.
157  *
158  * @data must not be modified after this call is made until @free_func has
159  * been called to indicate that the bytes is no longer in use.
160  *
161  * Returns: (transfer full): a new #GBytes
162  *
163  * Since: 2.32
164  */
165 GBytes *
166 g_bytes_new_with_free_func (gconstpointer  data,
167                             gsize          size,
168                             GDestroyNotify free_func,
169                             gpointer       user_data)
170 {
171   GBytes *bytes;
172
173   bytes = g_slice_new (GBytes);
174   bytes->data = data;
175   bytes->size = size;
176   bytes->free_func = free_func;
177   bytes->user_data = user_data;
178   bytes->ref_count = 1;
179
180   return (GBytes *)bytes;
181 }
182
183 /**
184  * g_bytes_new_from_bytes:
185  * @bytes: a #GBytes
186  * @offset: offset which subsection starts at
187  * @length: length of subsection
188  *
189  * Creates a #GBytes which is a subsection of another #GBytes. The @offset +
190  * @length may not be longer than the size of @bytes.
191  *
192  * A reference to @bytes will be held by the newly created #GBytes until
193  * the byte data is no longer needed.
194  *
195  * Returns: (transfer full): a new #GBytes
196  *
197  * Since: 2.32
198  */
199 GBytes *
200 g_bytes_new_from_bytes (GBytes  *bytes,
201                         gsize    offset,
202                         gsize    length)
203 {
204   g_return_val_if_fail (bytes != NULL, NULL);
205   g_return_val_if_fail (offset <= bytes->size, NULL);
206   g_return_val_if_fail (offset + length <= bytes->size, NULL);
207
208   return g_bytes_new_with_free_func ((gchar *)bytes->data + offset, length,
209                                      (GDestroyNotify)g_bytes_unref, g_bytes_ref (bytes));
210 }
211
212 /**
213  * g_bytes_get_data:
214  * @bytes: a #GBytes
215  *
216  * Get the byte data in the #GBytes. This data should not be modified.
217  *
218  * This function will always return the same pointer for a given #GBytes.
219  *
220  * Returns: a pointer to the byte data
221  *
222  * Since: 2.32
223  */
224 gconstpointer
225 g_bytes_get_data (GBytes *bytes)
226 {
227   g_return_val_if_fail (bytes != NULL, NULL);
228   return bytes->data;
229 }
230
231 /**
232  * g_bytes_get_size:
233  * @bytes: a #GBytes
234  *
235  * Get the size of the byte data in the #GBytes.
236  *
237  * This function will always return the same value for a given #GBytes.
238  *
239  * Returns: the size
240  *
241  * Since: 2.32
242  */
243 gsize
244 g_bytes_get_size (GBytes *bytes)
245 {
246   g_return_val_if_fail (bytes != NULL, 0);
247   return bytes->size;
248 }
249
250
251 /**
252  * g_bytes_ref:
253  * @bytes: a #GBytes
254  *
255  * Increase the reference count on @bytes.
256  *
257  * Returns: the #GBytes
258  *
259  * Since: 2.32
260  */
261 GBytes *
262 g_bytes_ref (GBytes *bytes)
263 {
264   g_return_val_if_fail (bytes != NULL, NULL);
265
266   g_atomic_int_inc (&bytes->ref_count);
267
268   return bytes;
269 }
270
271 /**
272  * g_bytes_unref:
273  * @bytes: (allow-none): a #GBytes
274  *
275  * Releases a reference on @bytes.  This may result in the bytes being
276  * freed.
277  *
278  * Since: 2.32
279  */
280 void
281 g_bytes_unref (GBytes *bytes)
282 {
283   if (bytes == NULL)
284     return;
285
286   if (g_atomic_int_dec_and_test (&bytes->ref_count))
287     {
288       if (bytes->free_func != NULL)
289         bytes->free_func (bytes->user_data);
290       g_slice_free (GBytes, bytes);
291     }
292 }
293
294 /**
295  * g_bytes_equal:
296  * @bytes1: (type GLib.Bytes): a pointer to a #GBytes
297  * @bytes2: (type GLib.Bytes): a pointer to a #GBytes to compare with @bytes1
298  *
299  * Compares the two #GBytes values being pointed to and returns
300  * %TRUE if they are equal.
301  *
302  * This function can be passed to g_hash_table_new() as the @key_equal_func
303  * parameter, when using non-%NULL #GBytes pointers as keys in a #GHashTable.
304  *
305  * Returns: %TRUE if the two keys match.
306  *
307  * Since: 2.32
308  */
309 gboolean
310 g_bytes_equal (gconstpointer bytes1,
311                gconstpointer bytes2)
312 {
313   const GBytes *b1 = bytes1;
314   const GBytes *b2 = bytes2;
315
316   g_return_val_if_fail (bytes1 != NULL, FALSE);
317   g_return_val_if_fail (bytes2 != NULL, FALSE);
318
319   return b1->size == b2->size &&
320          memcmp (b1->data, b2->data, b1->size) == 0;
321 }
322
323 /**
324  * g_bytes_hash:
325  * @bytes: (type GLib.Bytes): a pointer to a #GBytes key
326  *
327  * Creates an integer hash code for the byte data in the #GBytes.
328  *
329  * This function can be passed to g_hash_table_new() as the @key_equal_func
330  * parameter, when using non-%NULL #GBytes pointers as keys in a #GHashTable.
331  *
332  * Returns: a hash value corresponding to the key.
333  *
334  * Since: 2.32
335  */
336 guint
337 g_bytes_hash (gconstpointer bytes)
338 {
339   const GBytes *a = bytes;
340   const signed char *p, *e;
341   guint32 h = 5381;
342
343   g_return_val_if_fail (bytes != NULL, 0);
344
345   for (p = (signed char *)a->data, e = (signed char *)a->data + a->size; p != e; p++)
346     h = (h << 5) + h + *p;
347
348   return h;
349 }
350
351 /**
352  * g_bytes_compare:
353  * @bytes1: (type GLib.Bytes): a pointer to a #GBytes
354  * @bytes2: (type GLib.Bytes): a pointer to a #GBytes to compare with @bytes1
355  *
356  * Compares the two #GBytes values.
357  *
358  * This function can be used to sort GBytes instances in lexographical order.
359  *
360  * Returns: a negative value if bytes2 is lesser, a positive value if bytes2 is
361  *          greater, and zero if bytes2 is equal to bytes1
362  *
363  * Since: 2.32
364  */
365 gint
366 g_bytes_compare (gconstpointer bytes1,
367                  gconstpointer bytes2)
368 {
369   const GBytes *b1 = bytes1;
370   const GBytes *b2 = bytes2;
371   gint ret;
372
373   g_return_val_if_fail (bytes1 != NULL, 0);
374   g_return_val_if_fail (bytes2 != NULL, 0);
375
376   ret = memcmp (b1->data, b2->data, MIN (b1->size, b2->size));
377   if (ret == 0 && b1->size != b2->size)
378       ret = b1->size < b2->size ? -1 : 1;
379   return ret;
380 }
381
382 static gpointer
383 try_steal_and_unref (GBytes         *bytes,
384                      GDestroyNotify  free_func,
385                      gsize          *size)
386 {
387   gpointer result;
388
389   if (bytes->free_func != free_func)
390     return NULL;
391
392   /* Are we the only reference? */
393   if (g_atomic_int_get (&bytes->ref_count) == 1)
394     {
395       *size = bytes->size;
396       result = (gpointer)bytes->data;
397       g_slice_free (GBytes, bytes);
398       return result;
399     }
400
401   return NULL;
402 }
403
404
405 /**
406  * g_bytes_unref_to_data:
407  * @bytes: (transfer full): a #GBytes
408  * @size: location to place the length of the returned data
409  *
410  * Unreferences the bytes, and returns a pointer the same byte data
411  * contents.
412  *
413  * As an optimization, the byte data is returned without copying if this was
414  * the last reference to bytes and bytes was created with g_bytes_new(),
415  * g_bytes_new_take() or g_byte_array_free_to_bytes(). In all other cases the
416  * data is copied.
417  *
418  * Returns: (transfer full): a pointer to the same byte data, which should
419  *          be freed with g_free()
420  *
421  * Since: 2.32
422  */
423 gpointer
424 g_bytes_unref_to_data (GBytes *bytes,
425                        gsize  *size)
426 {
427   gpointer result;
428
429   g_return_val_if_fail (bytes != NULL, NULL);
430   g_return_val_if_fail (size != NULL, NULL);
431
432   /*
433    * Optimal path: if this is was the last reference, then we can return
434    * the data from this GBytes without copying.
435    */
436
437   result = try_steal_and_unref (bytes, g_free, size);
438   if (result == NULL)
439     {
440       /*
441        * Copy: Non g_malloc (or compatible) allocator, or static memory,
442        * so we have to copy, and then unref.
443        */
444       result = g_memdup (bytes->data, bytes->size);
445       *size = bytes->size;
446       g_bytes_unref (bytes);
447     }
448
449   return result;
450 }
451
452 /**
453  * g_bytes_unref_to_array:
454  * @bytes: (transfer full): a #GBytes
455  *
456  * Unreferences the bytes, and returns a new mutable #GByteArray containing
457  * the same byte data.
458  *
459  * As an optimization, the byte data is transferred to the array without copying
460  * if this was the last reference to bytes and bytes was created with
461  * g_bytes_new(), g_bytes_new_take() or g_byte_array_free_to_bytes(). In all
462  * other cases the data is copied.
463  *
464  * Returns: (transfer full): a new mutable #GByteArray containing the same byte data
465  *
466  * Since: 2.32
467  */
468 GByteArray *
469 g_bytes_unref_to_array (GBytes *bytes)
470 {
471   gpointer data;
472   gsize size;
473
474   g_return_val_if_fail (bytes != NULL, NULL);
475
476   data = g_bytes_unref_to_data (bytes, &size);
477   return g_byte_array_new_take (data, size);
478 }