unicode: Update to unicode 7.0.0
[platform/upstream/glib.git] / glib / gvariant-core.c
index 6d1e2b3..a9f5d94 100644 (file)
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  */
 
+#include "config.h"
+
 #include <glib/gvariant-core.h>
 
 #include <glib/gvariant-serialiser.h>
 #include <glib/gtestutils.h>
 #include <glib/gbitlock.h>
 #include <glib/gatomic.h>
-#include <glib/gbufferprivate.h>
+#include <glib/gbytes.h>
 #include <glib/gslice.h>
 #include <glib/gmem.h>
 #include <string.h>
@@ -61,7 +61,7 @@ struct _GVariant
   {
     struct
     {
-      GBuffer *buffer;
+      GBytes *bytes;
       gconstpointer data;
     } serialised;
 
@@ -133,16 +133,16 @@ struct _GVariant
  *                never be changed.  It is therefore valid to access
  *                them without holding a lock.
  *
- *     .buffer: the #GBuffer that contains the memory pointed to by
+ *     .bytes:  the #GBytes that contains the memory pointed to by
  *              .data, or %NULL if .data is %NULL.  In the event that
  *              the instance was deserialised from another instance,
- *              then the buffer will be shared by both of them.  When
+ *              then the bytes will be shared by both of them.  When
  *              the instance is freed, this reference must be released
- *              with g_buffer_unref().
+ *              with g_bytes_unref().
  *
  *     .data: the serialised data (of size 'size') of the instance.
  *            This pointer should not be freed or modified in any way.
- *            #GBuffer is responsible for memory management.
+ *            #GBytes is responsible for memory management.
  *
  *            This pointer may be %NULL in two cases:
  *
@@ -438,7 +438,7 @@ g_variant_ensure_serialised (GVariant *value)
 
   if (~value->state & STATE_SERIALISED)
     {
-      GBuffer *buffer;
+      GBytes *bytes;
       gpointer data;
 
       g_variant_ensure_size (value);
@@ -447,9 +447,9 @@ g_variant_ensure_serialised (GVariant *value)
 
       g_variant_release_children (value);
 
-      buffer = g_buffer_new_take_data (data, value->size);
-      value->contents.serialised.data = buffer->data;
-      value->contents.serialised.buffer = buffer;
+      bytes = g_bytes_new_take (data, value->size);
+      value->contents.serialised.data = g_bytes_get_data (bytes, NULL);
+      value->contents.serialised.bytes = bytes;
       value->state |= STATE_SERIALISED;
     }
 }
@@ -484,25 +484,26 @@ g_variant_alloc (const GVariantType *type,
   return value;
 }
 
-/* -- internal -- */
-/* < internal >
- * g_variant_new_from_buffer:
+/**
+ * g_variant_new_from_bytes:
  * @type: a #GVariantType
- * @buffer: a #GBuffer
- * @trusted: if the contents of @buffer are trusted
+ * @bytes: a #GBytes
+ * @trusted: if the contents of @bytes are trusted
  *
  * Constructs a new serialised-mode #GVariant instance.  This is the
  * inner interface for creation of new serialised values that gets
  * called from various functions in gvariant.c.
  *
- * A reference is taken on @buffer.
+ * A reference is taken on @bytes.
  *
- * Returns: a new #GVariant with a floating reference
+ * Returns: (transfer none): a new #GVariant with a floating reference
+ *
+ * Since: 2.36
  */
 GVariant *
-g_variant_new_from_buffer (const GVariantType *type,
-                           GBuffer            *buffer,
-                           gboolean            trusted)
+g_variant_new_from_bytes (const GVariantType *type,
+                          GBytes             *bytes,
+                          gboolean            trusted)
 {
   GVariant *value;
   guint alignment;
@@ -510,14 +511,14 @@ g_variant_new_from_buffer (const GVariantType *type,
 
   value = g_variant_alloc (type, TRUE, trusted);
 
-  value->contents.serialised.buffer = g_buffer_ref (buffer);
+  value->contents.serialised.bytes = g_bytes_ref (bytes);
 
   g_variant_type_info_query (value->type_info,
                              &alignment, &size);
 
-  if (size && buffer->size != size)
+  if (size && g_bytes_get_size (bytes) != size)
     {
-      /* Creating a fixed-sized GVariant with a buffer of the wrong
+      /* Creating a fixed-sized GVariant with a bytes of the wrong
        * size.
        *
        * We should do the equivalent of pulling a fixed-sized child out
@@ -529,13 +530,14 @@ g_variant_new_from_buffer (const GVariantType *type,
     }
   else
     {
-      value->contents.serialised.data = buffer->data;
-      value->size = buffer->size;
+      value->contents.serialised.data = g_bytes_get_data (bytes, &value->size);
     }
 
   return value;
 }
 
+/* -- internal -- */
+
 /* < internal >
  * g_variant_new_from_children:
  * @type: a #GVariantType
@@ -619,6 +621,9 @@ g_variant_is_trusted (GVariant *value)
 void
 g_variant_unref (GVariant *value)
 {
+  g_return_if_fail (value != NULL);
+  g_return_if_fail (value->ref_count > 0);
+
   if (g_atomic_int_dec_and_test (&value->ref_count))
     {
       if G_UNLIKELY (value->state & STATE_LOCKED)
@@ -630,7 +635,7 @@ g_variant_unref (GVariant *value)
       g_variant_type_info_unref (value->type_info);
 
       if (value->state & STATE_SERIALISED)
-        g_buffer_unref (value->contents.serialised.buffer);
+        g_bytes_unref (value->contents.serialised.bytes);
       else
         g_variant_release_children (value);
 
@@ -652,6 +657,9 @@ g_variant_unref (GVariant *value)
 GVariant *
 g_variant_ref (GVariant *value)
 {
+  g_return_val_if_fail (value != NULL, NULL);
+  g_return_val_if_fail (value->ref_count > 0, NULL);
+
   g_atomic_int_inc (&value->ref_count);
 
   return value;
@@ -662,7 +670,7 @@ g_variant_ref (GVariant *value)
  * @value: a #GVariant
  *
  * #GVariant uses a floating reference count system.  All functions with
- * names starting with <literal>g_variant_new_</literal> return floating
+ * names starting with `g_variant_new_` return floating
  * references.
  *
  * Calling g_variant_ref_sink() on a #GVariant with a floating reference
@@ -691,6 +699,9 @@ g_variant_ref (GVariant *value)
 GVariant *
 g_variant_ref_sink (GVariant *value)
 {
+  g_return_val_if_fail (value != NULL, NULL);
+  g_return_val_if_fail (value->ref_count > 0, NULL);
+
   g_variant_lock (value);
 
   if (~value->state & STATE_FLOATING)
@@ -746,6 +757,7 @@ GVariant *
 g_variant_take_ref (GVariant *value)
 {
   g_return_val_if_fail (value != NULL, NULL);
+  g_return_val_if_fail (value->ref_count > 0, NULL);
 
   g_atomic_int_and (&value->state, ~STATE_FLOATING);
 
@@ -832,7 +844,7 @@ g_variant_get_size (GVariant *value)
  * serialised data, you must know the type of the #GVariant, and (if the
  * machine might be different) the endianness of the machine that stored
  * it. As a result, file formats or network messages that incorporate
- * serialised #GVariant<!---->s must include this information either
+ * serialised #GVariants must include this information either
  * implicitly (for instance "the file always contains a
  * %G_VARIANT_TYPE_VARIANT and it is always in little-endian order") or
  * explicitly (by storing the type and/or endianness in addition to the
@@ -853,6 +865,43 @@ g_variant_get_data (GVariant *value)
 }
 
 /**
+ * g_variant_get_data_as_bytes:
+ * @value: a #GVariant
+ *
+ * Returns a pointer to the serialised form of a #GVariant instance.
+ * The semantics of this function are exactly the same as
+ * g_variant_get_data(), except that the returned #GBytes holds
+ * a reference to the variant data.
+ *
+ * Returns: (transfer full): A new #GBytes representing the variant data
+ *
+ * Since: 2.36
+ */ 
+GBytes *
+g_variant_get_data_as_bytes (GVariant *value)
+{
+  const gchar *bytes_data;
+  const gchar *data;
+  gsize bytes_size;
+  gsize size;
+
+  g_variant_lock (value);
+  g_variant_ensure_serialised (value);
+  g_variant_unlock (value);
+
+  bytes_data = g_bytes_get_data (value->contents.serialised.bytes, &bytes_size);
+  data = value->contents.serialised.data;
+  size = value->size;
+
+  if (data == bytes_data && size == bytes_size)
+    return g_bytes_ref (value->contents.serialised.bytes);
+  else
+    return g_bytes_new_from_bytes (value->contents.serialised.bytes,
+                                   data - bytes_data, size);
+}
+
+
+/**
  * g_variant_n_children:
  * @value: a container #GVariant
  *
@@ -963,8 +1012,8 @@ g_variant_get_child_value (GVariant *value,
                    STATE_SERIALISED;
     child->size = s_child.size;
     child->ref_count = 1;
-    child->contents.serialised.buffer =
-      g_buffer_ref (value->contents.serialised.buffer);
+    child->contents.serialised.bytes =
+      g_bytes_ref (value->contents.serialised.bytes);
     child->contents.serialised.data = s_child.data;
 
     return child;