* in the gio library, for those.)
*
* For space-efficiency, the #GVariant serialisation format does not
- * automatically include the variant's type or endianness, which must
- * either be implied from context (such as knowledge that a particular
- * file format always contains a little-endian %G_VARIANT_TYPE_VARIANT)
- * or supplied out-of-band (for instance, a type and/or endianness
+ * automatically include the variant's length, type or endianness,
+ * which must either be implied from context (such as knowledge that a
+ * particular file format always contains a little-endian
+ * %G_VARIANT_TYPE_VARIANT which occupies the whole length of the file)
+ * or supplied out-of-band (for instance, a length, type and/or endianness
* indicator could be placed at the beginning of a file, network message
* or network stream).
*
*
* This is the memory that is used for storing GVariant data in
* serialised form. This is what would be sent over the network or
- * what would end up on disk.
+ * what would end up on disk, not counting any indicator of the
+ * endianness, or of the length or type of the top-level variant.
*
* The amount of memory required to store a boolean is 1 byte. 16,
- * 32 and 64 bit integers and double precision floating point numbers
+ * 32 and 64 bit integers and floating point numbers
* use their "natural" size. Strings (including object path and
* signature strings) are stored with a nul terminator, and as such
* use the length of the string plus 1 byte.
}
/* the constructors and accessors for byte, int{16,32,64}, handles and
- * doubles all look pretty much exactly the same, so we reduce
+ * floats all look pretty much exactly the same, so we reduce
* copy/pasting here.
*/
#define NUMERIC_TYPE(TYPE, type, ctype) \
NUMERIC_TYPE (HANDLE, handle, gint32)
/**
+ * g_variant_new_float:
+ * @value: a #gfloat floating point value
+ *
+ * Creates a new float #GVariant instance.
+ *
+ * Returns: (transfer none): a floating reference to a new float #GVariant instance
+ *
+ * Since: 2.44
+ **/
+/**
+ * g_variant_get_float:
+ * @value: a float #GVariant instance
+ *
+ * Returns the single precision floating point value of @value.
+ *
+ * It is an error to call this function with a @value of any type
+ * other than %G_VARIANT_TYPE_FLOAT.
+ *
+ * Returns: a #gfloat
+ *
+ * Since: 2.44
+ **/
+NUMERIC_TYPE (FLOAT, float, gfloat)
+
+/**
* g_variant_new_double:
* @value: a #gdouble floating point value
*
* - %G_VARIANT_TYPE_BOOLEAN: #guchar (not #gboolean!)
* - %G_VARIANT_TYPE_BYTE: #guchar
* - %G_VARIANT_TYPE_HANDLE: #guint32
+ * - %G_VARIANT_TYPE_FLOAT: #gfloat
* - %G_VARIANT_TYPE_DOUBLE: #gdouble
*
* For example, if calling this function for an array of 32-bit integers,
* @G_VARIANT_CLASS_INT64: The #GVariant is a signed 64 bit integer.
* @G_VARIANT_CLASS_UINT64: The #GVariant is an unsigned 64 bit integer.
* @G_VARIANT_CLASS_HANDLE: The #GVariant is a file handle index.
+ * @G_VARIANT_CLASS_FLOAT: The #GVariant is a single precision floating
+ * point value.
* @G_VARIANT_CLASS_DOUBLE: The #GVariant is a double precision floating
* point value.
* @G_VARIANT_CLASS_STRING: The #GVariant is a normal string.
g_variant_get_uint64 (value));
break;
+ case G_VARIANT_CLASS_FLOAT:
+ {
+ gchar buffer[100];
+ gint i;
+
+ g_ascii_dtostr (buffer, sizeof buffer, g_variant_get_float (value));
+
+ for (i = 0; buffer[i]; i++)
+ if (buffer[i] == '.' || buffer[i] == 'e' ||
+ buffer[i] == 'n' || buffer[i] == 'N')
+ break;
+
+ /* if there is no '.' or 'e' in the float then add one */
+ if (buffer[i] == '\0')
+ {
+ buffer[i++] = '.';
+ buffer[i++] = '0';
+ buffer[i++] = '\0';
+ }
+
+ if (type_annotate)
+ g_string_append (string, "float ");
+ g_string_append (string, buffer);
+ }
+ break;
+
case G_VARIANT_CLASS_DOUBLE:
{
gchar buffer[100];
case G_VARIANT_CLASS_INT32:
case G_VARIANT_CLASS_UINT32:
case G_VARIANT_CLASS_HANDLE:
+ case G_VARIANT_CLASS_FLOAT:
{
const guint *ptr;
* two values that have types that are not exactly equal. For example,
* you cannot compare a 32-bit signed integer with a 32-bit unsigned
* integer. Also note that this function is not particularly
- * well-behaved when it comes to comparison of doubles; in particular,
+ * well-behaved when it comes to comparison of floats; in particular,
* the handling of incomparable values (ie: NaN) is undefined.
*
* If you only require an equality comparison, g_variant_equal() is more
return (a_val == b_val) ? 0 : (a_val > b_val) ? 1 : -1;
}
+ case G_VARIANT_CLASS_FLOAT:
+ {
+ gfloat a_val = g_variant_get_float (a);
+ gfloat b_val = g_variant_get_float (b);
+
+ return (a_val == b_val) ? 0 : (a_val > b_val) ? 1 : -1;
+ }
+
case G_VARIANT_CLASS_DOUBLE:
{
gdouble a_val = g_variant_get_double (a);
/* GVariantDict {{{1 */
/**
- * GVariantDict: (skip)
+ * GVariantDict:
*
* #GVariantDict is a mutable interface to #GVariant dictionaries.
*
*
* ## Using a stack-allocated GVariantDict
*
- * |[
+ * |[<!-- language="C" -->
* GVariant *
* add_to_count (GVariant *orig,
* GError **error)
*
* ## Using heap-allocated GVariantDict
*
- * |[
+ * |[<!-- language="C" -->
* GVariant *
* add_to_count (GVariant *orig,
* GError **error)
switch (next_char())
{
case 'b': case 'y': case 'n': case 'q': case 'i': case 'u':
- case 'x': case 't': case 'h': case 'd': case 's': case 'o':
- case 'g': case 'v': case '*': case '?': case 'r':
+ case 'x': case 't': case 'h': case 'f': case 'd': case 's':
+ case 'o': case 'g': case 'v': case '*': case '?': case 'r':
break;
case 'm':
va_arg (*app, guint64);
return;
+ case 'f':
case 'd':
va_arg (*app, gdouble);
return;
case 'h':
return g_variant_new_handle (va_arg (*app, gint));
+ case 'f':
+ return g_variant_new_float (va_arg (*app, gdouble));
+
case 'd':
return g_variant_new_double (va_arg (*app, gdouble));
/* The code below assumes this */
G_STATIC_ASSERT (sizeof (gboolean) == sizeof (guint32));
+G_STATIC_ASSERT (sizeof (gfloat) == sizeof (guint32));
G_STATIC_ASSERT (sizeof (gdouble) == sizeof (guint64));
static void
*(gint32 *) ptr = g_variant_get_handle (value);
return;
+ case 'f':
+ *(gfloat *) ptr = g_variant_get_float (value);
+ return;
+
case 'd':
*(gdouble *) ptr = g_variant_get_double (value);
return;
case 'u':
case 'h':
case 'b':
+ case 'f':
*(guint32 *) ptr = 0;
return;
* specified in @format_string. This can be achieved by casting them. See
* the [GVariant varargs documentation][gvariant-varargs].
*
- * |[
+ * |[<!-- language="C" -->
* MyFlags some_flags = FLAG_ONE | FLAG_TWO;
* const gchar *some_strings[] = { "a", "b", "c", NULL };
* GVariant *new_variant;
case G_VARIANT_CLASS_HANDLE:
return g_variant_new_handle (g_variant_get_handle (value));
+ case G_VARIANT_CLASS_FLOAT:
+ return g_variant_new_float (g_variant_get_float (value));
+
case G_VARIANT_CLASS_DOUBLE:
return g_variant_new_double (g_variant_get_double (value));
* Performs a byteswapping operation on the contents of @value. The
* result is that all multi-byte numeric data contained in @value is
* byteswapped. That includes 16, 32, and 64bit signed and unsigned
- * integers as well as file handles and double precision floating point
- * values.
+ * integers as well as file handles and floating point values.
*
* This function is an identity mapping on any value that does not
* contain multi-byte numeric data. That include strings, booleans,