mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-09-27 17:52:58 +02:00
GVariant: add support for single precision floats
Add a new type 'f' to correspond to single precision floating point values. This type was never added to D-Bus for two reasons: 1) there is no benefit to using float rather than doubles as parameters for RPC 2) classically, you shouldn't move bulk data over D-Bus Now that we've decided that we want to use D-Bus for bulk data transfers, it makes a good deal of sense to want to send an array of floats or an array of fixed-sized tuples containing floats. https://bugzilla.gnome.org/show_bug.cgi?id=740897
This commit is contained in:
@@ -224,6 +224,7 @@
|
|||||||
<literal>handle</literal>,
|
<literal>handle</literal>,
|
||||||
<literal>int64</literal>,
|
<literal>int64</literal>,
|
||||||
<literal>uint64</literal>,
|
<literal>uint64</literal>,
|
||||||
|
<literal>float</literal>,
|
||||||
<literal>double</literal>,
|
<literal>double</literal>,
|
||||||
<literal>string</literal>,
|
<literal>string</literal>,
|
||||||
<literal>objectpath</literal>,
|
<literal>objectpath</literal>,
|
||||||
@@ -534,9 +535,9 @@
|
|||||||
Type keywords can be seen as more verbose (and more legible) versions of a common subset of the type codes.
|
Type keywords can be seen as more verbose (and more legible) versions of a common subset of the type codes.
|
||||||
The type keywords <literal>boolean</literal>, <literal>byte</literal>, <literal>int16</literal>,
|
The type keywords <literal>boolean</literal>, <literal>byte</literal>, <literal>int16</literal>,
|
||||||
<literal>uint16</literal>, <literal>int32</literal>, <literal>uint32</literal>, <literal>handle</literal>,
|
<literal>uint16</literal>, <literal>int32</literal>, <literal>uint32</literal>, <literal>handle</literal>,
|
||||||
<literal>int64</literal>, <literal>uint64</literal>, <literal>double</literal>, <literal>string</literal>,
|
<literal>int64</literal>, <literal>uint64</literal>, <literal>float</literal>, <literal>double</literal>,
|
||||||
<literal>objectpath</literal> and literal <literal>signature</literal> are each exactly equivalent to their
|
<literal>string</literal>, <literal>objectpath</literal> and literal <literal>signature</literal> are each
|
||||||
corresponding type code.
|
exactly equivalent to their corresponding type code.
|
||||||
</para>
|
</para>
|
||||||
<para>
|
<para>
|
||||||
Type codes are an <literal>@</literal> ("at" sign) followed by a definite GVariant type string. Some
|
Type codes are an <literal>@</literal> ("at" sign) followed by a definite GVariant type string. Some
|
||||||
|
@@ -455,7 +455,13 @@ pattern_coalesce (const gchar *left,
|
|||||||
(*one)++;
|
(*one)++;
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (**one == 'N' && strchr ("ynqiuxthd", **the_other))
|
else if (**one == 'N' && strchr ("ynqiuxthfd", **the_other))
|
||||||
|
{
|
||||||
|
*out++ = *(*the_other)++;
|
||||||
|
(*one)++;
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (**one == 'D' && (**the_other == 'f' || **the_other == 'd'))
|
||||||
{
|
{
|
||||||
*out++ = *(*the_other)++;
|
*out++ = *(*the_other)++;
|
||||||
(*one)++;
|
(*one)++;
|
||||||
@@ -616,6 +622,10 @@ ast_resolve (AST *ast,
|
|||||||
pattern[j++] = 'i';
|
pattern[j++] = 'i';
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'D':
|
||||||
|
pattern[j++] = 'd';
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
pattern[j++] = pattern[i];
|
pattern[j++] = pattern[i];
|
||||||
break;
|
break;
|
||||||
@@ -1246,7 +1256,7 @@ dictionary_get_pattern (AST *ast,
|
|||||||
/* the basic types,
|
/* the basic types,
|
||||||
* plus undetermined number type and undetermined string type.
|
* plus undetermined number type and undetermined string type.
|
||||||
*/
|
*/
|
||||||
if (!strchr ("bynqiuxthdsogNS", key_char))
|
if (!strchr ("bynqiuxthfdsogNDS", key_char))
|
||||||
{
|
{
|
||||||
ast_set_error (ast, error, NULL,
|
ast_set_error (ast, error, NULL,
|
||||||
G_VARIANT_PARSE_ERROR_BASIC_TYPE_EXPECTED,
|
G_VARIANT_PARSE_ERROR_BASIC_TYPE_EXPECTED,
|
||||||
@@ -1792,7 +1802,7 @@ number_get_pattern (AST *ast,
|
|||||||
(!g_str_has_prefix (number->token, "0x") && strchr (number->token, 'e')) ||
|
(!g_str_has_prefix (number->token, "0x") && strchr (number->token, 'e')) ||
|
||||||
strstr (number->token, "inf") ||
|
strstr (number->token, "inf") ||
|
||||||
strstr (number->token, "nan"))
|
strstr (number->token, "nan"))
|
||||||
return g_strdup ("Md");
|
return g_strdup ("MD");
|
||||||
|
|
||||||
return g_strdup ("MN");
|
return g_strdup ("MN");
|
||||||
}
|
}
|
||||||
@@ -1817,17 +1827,16 @@ number_get_value (AST *ast,
|
|||||||
Number *number = (Number *) ast;
|
Number *number = (Number *) ast;
|
||||||
const gchar *token;
|
const gchar *token;
|
||||||
gboolean negative;
|
gboolean negative;
|
||||||
gboolean floating;
|
|
||||||
guint64 abs_val;
|
guint64 abs_val;
|
||||||
gdouble dbl_val;
|
gdouble dbl_val;
|
||||||
|
gchar typechar;
|
||||||
gchar *end;
|
gchar *end;
|
||||||
|
|
||||||
|
typechar = *g_variant_type_peek_string (type);
|
||||||
token = number->token;
|
token = number->token;
|
||||||
|
|
||||||
if (g_variant_type_equal (type, G_VARIANT_TYPE_DOUBLE))
|
if (typechar == 'f' || typechar == 'd')
|
||||||
{
|
{
|
||||||
floating = TRUE;
|
|
||||||
|
|
||||||
errno = 0;
|
errno = 0;
|
||||||
dbl_val = g_ascii_strtod (token, &end);
|
dbl_val = g_ascii_strtod (token, &end);
|
||||||
if (dbl_val != 0.0 && errno == ERANGE)
|
if (dbl_val != 0.0 && errno == ERANGE)
|
||||||
@@ -1844,7 +1853,6 @@ number_get_value (AST *ast,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
floating = FALSE;
|
|
||||||
negative = token[0] == '-';
|
negative = token[0] == '-';
|
||||||
if (token[0] == '-')
|
if (token[0] == '-')
|
||||||
token++;
|
token++;
|
||||||
@@ -1880,10 +1888,7 @@ number_get_value (AST *ast,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (floating)
|
switch (typechar)
|
||||||
return g_variant_new_double (dbl_val);
|
|
||||||
|
|
||||||
switch (*g_variant_type_peek_string (type))
|
|
||||||
{
|
{
|
||||||
case 'y':
|
case 'y':
|
||||||
if (negative || abs_val > G_MAXUINT8)
|
if (negative || abs_val > G_MAXUINT8)
|
||||||
@@ -1925,6 +1930,12 @@ number_get_value (AST *ast,
|
|||||||
return number_overflow (ast, type, error);
|
return number_overflow (ast, type, error);
|
||||||
return g_variant_new_handle (negative ? -abs_val : abs_val);
|
return g_variant_new_handle (negative ? -abs_val : abs_val);
|
||||||
|
|
||||||
|
case 'f':
|
||||||
|
return g_variant_new_float (dbl_val);
|
||||||
|
|
||||||
|
case 'd':
|
||||||
|
return g_variant_new_double (dbl_val);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return ast_type_error (ast, type, error);
|
return ast_type_error (ast, type, error);
|
||||||
}
|
}
|
||||||
@@ -2210,6 +2221,9 @@ typedecl_parse (TokenStream *stream,
|
|||||||
else if (token_stream_consume (stream, "uint64"))
|
else if (token_stream_consume (stream, "uint64"))
|
||||||
type = g_variant_type_copy (G_VARIANT_TYPE_UINT64);
|
type = g_variant_type_copy (G_VARIANT_TYPE_UINT64);
|
||||||
|
|
||||||
|
else if (token_stream_consume (stream, "float"))
|
||||||
|
type = g_variant_type_copy (G_VARIANT_TYPE_FLOAT);
|
||||||
|
|
||||||
else if (token_stream_consume (stream, "double"))
|
else if (token_stream_consume (stream, "double"))
|
||||||
type = g_variant_type_copy (G_VARIANT_TYPE_DOUBLE);
|
type = g_variant_type_copy (G_VARIANT_TYPE_DOUBLE);
|
||||||
|
|
||||||
|
@@ -112,7 +112,7 @@
|
|||||||
* endianness, or of the length or type of the top-level variant.
|
* 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,
|
* 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
|
* use their "natural" size. Strings (including object path and
|
||||||
* signature strings) are stored with a nul terminator, and as such
|
* signature strings) are stored with a nul terminator, and as such
|
||||||
* use the length of the string plus 1 byte.
|
* use the length of the string plus 1 byte.
|
||||||
@@ -342,7 +342,7 @@ g_variant_get_boolean (GVariant *value)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* the constructors and accessors for byte, int{16,32,64}, handles and
|
/* 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.
|
* copy/pasting here.
|
||||||
*/
|
*/
|
||||||
#define NUMERIC_TYPE(TYPE, type, ctype) \
|
#define NUMERIC_TYPE(TYPE, type, ctype) \
|
||||||
@@ -566,6 +566,31 @@ NUMERIC_TYPE (UINT64, uint64, guint64)
|
|||||||
**/
|
**/
|
||||||
NUMERIC_TYPE (HANDLE, handle, gint32)
|
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:
|
* g_variant_new_double:
|
||||||
* @value: a #gdouble floating point value
|
* @value: a #gdouble floating point value
|
||||||
@@ -1081,6 +1106,7 @@ g_variant_lookup_value (GVariant *dictionary,
|
|||||||
* - %G_VARIANT_TYPE_BOOLEAN: #guchar (not #gboolean!)
|
* - %G_VARIANT_TYPE_BOOLEAN: #guchar (not #gboolean!)
|
||||||
* - %G_VARIANT_TYPE_BYTE: #guchar
|
* - %G_VARIANT_TYPE_BYTE: #guchar
|
||||||
* - %G_VARIANT_TYPE_HANDLE: #guint32
|
* - %G_VARIANT_TYPE_HANDLE: #guint32
|
||||||
|
* - %G_VARIANT_TYPE_FLOAT: #gfloat
|
||||||
* - %G_VARIANT_TYPE_DOUBLE: #gdouble
|
* - %G_VARIANT_TYPE_DOUBLE: #gdouble
|
||||||
*
|
*
|
||||||
* For example, if calling this function for an array of 32-bit integers,
|
* For example, if calling this function for an array of 32-bit integers,
|
||||||
@@ -2113,6 +2139,8 @@ g_variant_is_container (GVariant *value)
|
|||||||
* @G_VARIANT_CLASS_INT64: The #GVariant is a signed 64 bit integer.
|
* @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_UINT64: The #GVariant is an unsigned 64 bit integer.
|
||||||
* @G_VARIANT_CLASS_HANDLE: The #GVariant is a file handle index.
|
* @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
|
* @G_VARIANT_CLASS_DOUBLE: The #GVariant is a double precision floating
|
||||||
* point value.
|
* point value.
|
||||||
* @G_VARIANT_CLASS_STRING: The #GVariant is a normal string.
|
* @G_VARIANT_CLASS_STRING: The #GVariant is a normal string.
|
||||||
@@ -2516,6 +2544,32 @@ g_variant_print_string (GVariant *value,
|
|||||||
g_variant_get_uint64 (value));
|
g_variant_get_uint64 (value));
|
||||||
break;
|
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:
|
case G_VARIANT_CLASS_DOUBLE:
|
||||||
{
|
{
|
||||||
gchar buffer[100];
|
gchar buffer[100];
|
||||||
@@ -2640,6 +2694,7 @@ g_variant_hash (gconstpointer value_)
|
|||||||
case G_VARIANT_CLASS_INT32:
|
case G_VARIANT_CLASS_INT32:
|
||||||
case G_VARIANT_CLASS_UINT32:
|
case G_VARIANT_CLASS_UINT32:
|
||||||
case G_VARIANT_CLASS_HANDLE:
|
case G_VARIANT_CLASS_HANDLE:
|
||||||
|
case G_VARIANT_CLASS_FLOAT:
|
||||||
{
|
{
|
||||||
const guint *ptr;
|
const guint *ptr;
|
||||||
|
|
||||||
@@ -2759,7 +2814,7 @@ g_variant_equal (gconstpointer one,
|
|||||||
* two values that have types that are not exactly equal. For example,
|
* 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
|
* you cannot compare a 32-bit signed integer with a 32-bit unsigned
|
||||||
* integer. Also note that this function is not particularly
|
* 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.
|
* the handling of incomparable values (ie: NaN) is undefined.
|
||||||
*
|
*
|
||||||
* If you only require an equality comparison, g_variant_equal() is more
|
* If you only require an equality comparison, g_variant_equal() is more
|
||||||
@@ -2830,6 +2885,14 @@ g_variant_compare (gconstpointer one,
|
|||||||
return (a_val == b_val) ? 0 : (a_val > b_val) ? 1 : -1;
|
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:
|
case G_VARIANT_CLASS_DOUBLE:
|
||||||
{
|
{
|
||||||
gdouble a_val = g_variant_get_double (a);
|
gdouble a_val = g_variant_get_double (a);
|
||||||
@@ -4165,8 +4228,8 @@ g_variant_format_string_scan (const gchar *string,
|
|||||||
switch (next_char())
|
switch (next_char())
|
||||||
{
|
{
|
||||||
case 'b': case 'y': case 'n': case 'q': case 'i': case 'u':
|
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 'x': case 't': case 'h': case 'f': case 'd': case 's':
|
||||||
case 'g': case 'v': case '*': case '?': case 'r':
|
case 'o': case 'g': case 'v': case '*': case '?': case 'r':
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'm':
|
case 'm':
|
||||||
@@ -4829,6 +4892,7 @@ g_variant_valist_skip_leaf (const gchar **str,
|
|||||||
va_arg (*app, guint64);
|
va_arg (*app, guint64);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
case 'f':
|
||||||
case 'd':
|
case 'd':
|
||||||
va_arg (*app, gdouble);
|
va_arg (*app, gdouble);
|
||||||
return;
|
return;
|
||||||
@@ -4874,6 +4938,9 @@ g_variant_valist_new_leaf (const gchar **str,
|
|||||||
case 'h':
|
case 'h':
|
||||||
return g_variant_new_handle (va_arg (*app, gint));
|
return g_variant_new_handle (va_arg (*app, gint));
|
||||||
|
|
||||||
|
case 'f':
|
||||||
|
return g_variant_new_float (va_arg (*app, gdouble));
|
||||||
|
|
||||||
case 'd':
|
case 'd':
|
||||||
return g_variant_new_double (va_arg (*app, gdouble));
|
return g_variant_new_double (va_arg (*app, gdouble));
|
||||||
|
|
||||||
@@ -4884,6 +4951,7 @@ g_variant_valist_new_leaf (const gchar **str,
|
|||||||
|
|
||||||
/* The code below assumes this */
|
/* The code below assumes this */
|
||||||
G_STATIC_ASSERT (sizeof (gboolean) == sizeof (guint32));
|
G_STATIC_ASSERT (sizeof (gboolean) == sizeof (guint32));
|
||||||
|
G_STATIC_ASSERT (sizeof (gfloat) == sizeof (guint32));
|
||||||
G_STATIC_ASSERT (sizeof (gdouble) == sizeof (guint64));
|
G_STATIC_ASSERT (sizeof (gdouble) == sizeof (guint64));
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -4957,6 +5025,10 @@ g_variant_valist_get_leaf (const gchar **str,
|
|||||||
*(gint32 *) ptr = g_variant_get_handle (value);
|
*(gint32 *) ptr = g_variant_get_handle (value);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
case 'f':
|
||||||
|
*(gfloat *) ptr = g_variant_get_float (value);
|
||||||
|
return;
|
||||||
|
|
||||||
case 'd':
|
case 'd':
|
||||||
*(gdouble *) ptr = g_variant_get_double (value);
|
*(gdouble *) ptr = g_variant_get_double (value);
|
||||||
return;
|
return;
|
||||||
@@ -4979,6 +5051,7 @@ g_variant_valist_get_leaf (const gchar **str,
|
|||||||
case 'u':
|
case 'u':
|
||||||
case 'h':
|
case 'h':
|
||||||
case 'b':
|
case 'b':
|
||||||
|
case 'f':
|
||||||
*(guint32 *) ptr = 0;
|
*(guint32 *) ptr = 0;
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -5698,6 +5771,9 @@ g_variant_deep_copy (GVariant *value)
|
|||||||
case G_VARIANT_CLASS_HANDLE:
|
case G_VARIANT_CLASS_HANDLE:
|
||||||
return g_variant_new_handle (g_variant_get_handle (value));
|
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:
|
case G_VARIANT_CLASS_DOUBLE:
|
||||||
return g_variant_new_double (g_variant_get_double (value));
|
return g_variant_new_double (g_variant_get_double (value));
|
||||||
|
|
||||||
@@ -5760,8 +5836,7 @@ g_variant_get_normal_form (GVariant *value)
|
|||||||
* Performs a byteswapping operation on the contents of @value. The
|
* Performs a byteswapping operation on the contents of @value. The
|
||||||
* result is that all multi-byte numeric data contained in @value is
|
* result is that all multi-byte numeric data contained in @value is
|
||||||
* byteswapped. That includes 16, 32, and 64bit signed and unsigned
|
* byteswapped. That includes 16, 32, and 64bit signed and unsigned
|
||||||
* integers as well as file handles and double precision floating point
|
* integers as well as file handles and floating point values.
|
||||||
* values.
|
|
||||||
*
|
*
|
||||||
* This function is an identity mapping on any value that does not
|
* This function is an identity mapping on any value that does not
|
||||||
* contain multi-byte numeric data. That include strings, booleans,
|
* contain multi-byte numeric data. That include strings, booleans,
|
||||||
|
@@ -44,6 +44,7 @@ typedef enum
|
|||||||
G_VARIANT_CLASS_INT64 = 'x',
|
G_VARIANT_CLASS_INT64 = 'x',
|
||||||
G_VARIANT_CLASS_UINT64 = 't',
|
G_VARIANT_CLASS_UINT64 = 't',
|
||||||
G_VARIANT_CLASS_HANDLE = 'h',
|
G_VARIANT_CLASS_HANDLE = 'h',
|
||||||
|
G_VARIANT_CLASS_FLOAT = 'f',
|
||||||
G_VARIANT_CLASS_DOUBLE = 'd',
|
G_VARIANT_CLASS_DOUBLE = 'd',
|
||||||
G_VARIANT_CLASS_STRING = 's',
|
G_VARIANT_CLASS_STRING = 's',
|
||||||
G_VARIANT_CLASS_OBJECT_PATH = 'o',
|
G_VARIANT_CLASS_OBJECT_PATH = 'o',
|
||||||
@@ -95,6 +96,8 @@ GLIB_AVAILABLE_IN_ALL
|
|||||||
GVariant * g_variant_new_uint64 (guint64 value);
|
GVariant * g_variant_new_uint64 (guint64 value);
|
||||||
GLIB_AVAILABLE_IN_ALL
|
GLIB_AVAILABLE_IN_ALL
|
||||||
GVariant * g_variant_new_handle (gint32 value);
|
GVariant * g_variant_new_handle (gint32 value);
|
||||||
|
GLIB_AVAILABLE_IN_2_44
|
||||||
|
GVariant * g_variant_new_float (gfloat value);
|
||||||
GLIB_AVAILABLE_IN_ALL
|
GLIB_AVAILABLE_IN_ALL
|
||||||
GVariant * g_variant_new_double (gdouble value);
|
GVariant * g_variant_new_double (gdouble value);
|
||||||
GLIB_AVAILABLE_IN_ALL
|
GLIB_AVAILABLE_IN_ALL
|
||||||
@@ -148,6 +151,8 @@ GLIB_AVAILABLE_IN_ALL
|
|||||||
guint64 g_variant_get_uint64 (GVariant *value);
|
guint64 g_variant_get_uint64 (GVariant *value);
|
||||||
GLIB_AVAILABLE_IN_ALL
|
GLIB_AVAILABLE_IN_ALL
|
||||||
gint32 g_variant_get_handle (GVariant *value);
|
gint32 g_variant_get_handle (GVariant *value);
|
||||||
|
GLIB_AVAILABLE_IN_2_44
|
||||||
|
gfloat g_variant_get_float (GVariant *value);
|
||||||
GLIB_AVAILABLE_IN_ALL
|
GLIB_AVAILABLE_IN_ALL
|
||||||
gdouble g_variant_get_double (GVariant *value);
|
gdouble g_variant_get_double (GVariant *value);
|
||||||
GLIB_AVAILABLE_IN_ALL
|
GLIB_AVAILABLE_IN_ALL
|
||||||
|
@@ -110,7 +110,7 @@
|
|||||||
* A basic type string describes a basic type (as per
|
* A basic type string describes a basic type (as per
|
||||||
* g_variant_type_is_basic()) and is always a single character in length.
|
* g_variant_type_is_basic()) and is always a single character in length.
|
||||||
* The valid basic type strings are "b", "y", "n", "q", "i", "u", "x", "t",
|
* The valid basic type strings are "b", "y", "n", "q", "i", "u", "x", "t",
|
||||||
* "h", "d", "s", "o", "g" and "?".
|
* "h", "f", "d", "s", "o", "g" and "?".
|
||||||
*
|
*
|
||||||
* The above definition is recursive to arbitrary depth. "aaaaai" and
|
* The above definition is recursive to arbitrary depth. "aaaaai" and
|
||||||
* "(ui(nq((y)))s)" are both valid type strings, as is
|
* "(ui(nq((y)))s)" are both valid type strings, as is
|
||||||
@@ -128,6 +128,8 @@
|
|||||||
* - `h`: the type string of %G_VARIANT_TYPE_HANDLE; a signed 32 bit value
|
* - `h`: the type string of %G_VARIANT_TYPE_HANDLE; a signed 32 bit value
|
||||||
* that, by convention, is used as an index into an array of file
|
* that, by convention, is used as an index into an array of file
|
||||||
* descriptors that are sent alongside a D-Bus message.
|
* descriptors that are sent alongside a D-Bus message.
|
||||||
|
* - `f`: the type string of %G_VARIANT_TYPE_FLOAT; a single precision
|
||||||
|
* floating point value.
|
||||||
* - `d`: the type string of %G_VARIANT_TYPE_DOUBLE; a double precision
|
* - `d`: the type string of %G_VARIANT_TYPE_DOUBLE; a double precision
|
||||||
* floating point value.
|
* floating point value.
|
||||||
* - `s`: the type string of %G_VARIANT_TYPE_STRING; a string.
|
* - `s`: the type string of %G_VARIANT_TYPE_STRING; a string.
|
||||||
@@ -240,7 +242,7 @@ g_variant_type_string_scan (const gchar *string,
|
|||||||
|
|
||||||
case '{':
|
case '{':
|
||||||
if (string == limit || *string == '\0' || /* { */
|
if (string == limit || *string == '\0' || /* { */
|
||||||
!strchr ("bynqihuxtdsog?", *string++) || /* key */
|
!strchr ("bynqihuxtfdsog?", *string++) || /* key */
|
||||||
!g_variant_type_string_scan (string, limit, &string) || /* value */
|
!g_variant_type_string_scan (string, limit, &string) || /* value */
|
||||||
string == limit || *string++ != '}') /* } */
|
string == limit || *string++ != '}') /* } */
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@@ -252,7 +254,7 @@ g_variant_type_string_scan (const gchar *string,
|
|||||||
|
|
||||||
case 'b': case 'y': case 'n': case 'q': case 'i': case 'u':
|
case 'b': case 'y': case 'n': case 'q': case 'i': case 'u':
|
||||||
case 'x': case 't': case 'd': case 's': case 'o': case 'g':
|
case 'x': case 't': case 'd': case 's': case 'o': case 'g':
|
||||||
case 'v': case 'r': case '*': case '?': case 'h':
|
case 'v': case 'r': case '*': case '?': case 'h': case 'f':
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -533,8 +535,8 @@ g_variant_type_is_container (const GVariantType *type)
|
|||||||
*
|
*
|
||||||
* Determines if the given @type is a basic type.
|
* Determines if the given @type is a basic type.
|
||||||
*
|
*
|
||||||
* Basic types are booleans, bytes, integers, doubles, strings, object
|
* Basic types are booleans, bytes, integers, floats, doubles, strings,
|
||||||
* paths and signatures.
|
* object paths and signatures.
|
||||||
*
|
*
|
||||||
* Only a basic type may be used as the key of a dictionary entry.
|
* Only a basic type may be used as the key of a dictionary entry.
|
||||||
*
|
*
|
||||||
@@ -564,6 +566,7 @@ g_variant_type_is_basic (const GVariantType *type)
|
|||||||
case 'u':
|
case 'u':
|
||||||
case 't':
|
case 't':
|
||||||
case 'x':
|
case 'x':
|
||||||
|
case 'f':
|
||||||
case 'd':
|
case 'd':
|
||||||
case 's':
|
case 's':
|
||||||
case 'o':
|
case 'o':
|
||||||
|
@@ -103,6 +103,15 @@ typedef struct _GVariantType GVariantType;
|
|||||||
**/
|
**/
|
||||||
#define G_VARIANT_TYPE_UINT64 ((const GVariantType *) "t")
|
#define G_VARIANT_TYPE_UINT64 ((const GVariantType *) "t")
|
||||||
|
|
||||||
|
/**
|
||||||
|
* G_VARIANT_TYPE_FLOAT:
|
||||||
|
*
|
||||||
|
* The type of a single precision IEEE754 floating point number. You
|
||||||
|
* can store a number as large as 3.40e38 in these (plus and minus) but
|
||||||
|
* there are some gaps on the way.
|
||||||
|
**/
|
||||||
|
#define G_VARIANT_TYPE_FLOAT ((const GVariantType *) "f")
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* G_VARIANT_TYPE_DOUBLE:
|
* G_VARIANT_TYPE_DOUBLE:
|
||||||
*
|
*
|
||||||
|
@@ -115,7 +115,7 @@ static const GVariantTypeInfo g_variant_type_info_basic_table[24] = {
|
|||||||
/* 'c' */ { not_a_type },
|
/* 'c' */ { not_a_type },
|
||||||
/* 'd' */ { fixed_aligned(8) }, /* double */
|
/* 'd' */ { fixed_aligned(8) }, /* double */
|
||||||
/* 'e' */ { not_a_type },
|
/* 'e' */ { not_a_type },
|
||||||
/* 'f' */ { not_a_type },
|
/* 'f' */ { fixed_aligned(4) }, /* float */
|
||||||
/* 'g' */ { unaligned }, /* signature string */
|
/* 'g' */ { unaligned }, /* signature string */
|
||||||
/* 'h' */ { fixed_aligned(4) }, /* file handle (int32) */
|
/* 'h' */ { fixed_aligned(4) }, /* file handle (int32) */
|
||||||
/* 'i' */ { fixed_aligned(4) }, /* int32 */
|
/* 'i' */ { fixed_aligned(4) }, /* int32 */
|
||||||
@@ -147,7 +147,7 @@ static const GVariantTypeInfo g_variant_type_info_basic_table[24] = {
|
|||||||
* GVariantTypeInfo itself, we save a bunch of relocations.
|
* GVariantTypeInfo itself, we save a bunch of relocations.
|
||||||
*/
|
*/
|
||||||
static const char g_variant_type_info_basic_chars[24][2] = {
|
static const char g_variant_type_info_basic_chars[24][2] = {
|
||||||
"b", " ", "d", " ", " ", "g", "h", "i", " ", " ", " ", " ",
|
"b", " ", "d", " ", "f", "g", "h", "i", " ", " ", " ", " ",
|
||||||
"n", "o", " ", "q", " ", "s", "t", "u", "v", " ", "x", "y"
|
"n", "o", " ", "q", " ", "s", "t", "u", "v", " ", "x", "y"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -19,10 +19,10 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
|
|
||||||
#define BASIC "bynqiuxthdsog?"
|
#define BASIC "bynqiuxthfdsog?"
|
||||||
#define N_BASIC (G_N_ELEMENTS (BASIC) - 1)
|
#define N_BASIC (G_N_ELEMENTS (BASIC) - 1)
|
||||||
|
|
||||||
#define INVALIDS "cefjklpwz&@^$"
|
#define INVALIDS "cejklpwz&@^$"
|
||||||
#define N_INVALIDS (G_N_ELEMENTS (INVALIDS) - 1)
|
#define N_INVALIDS (G_N_ELEMENTS (INVALIDS) - 1)
|
||||||
|
|
||||||
/* see comment in gvariant-serialiser.c about this madness.
|
/* see comment in gvariant-serialiser.c about this madness.
|
||||||
@@ -82,6 +82,8 @@ append_type_string (GString *string,
|
|||||||
return g_variant_type_copy (G_VARIANT_TYPE_UINT64);
|
return g_variant_type_copy (G_VARIANT_TYPE_UINT64);
|
||||||
case 'h':
|
case 'h':
|
||||||
return g_variant_type_copy (G_VARIANT_TYPE_HANDLE);
|
return g_variant_type_copy (G_VARIANT_TYPE_HANDLE);
|
||||||
|
case 'f':
|
||||||
|
return g_variant_type_copy (G_VARIANT_TYPE_FLOAT);
|
||||||
case 'd':
|
case 'd':
|
||||||
return g_variant_type_copy (G_VARIANT_TYPE_DOUBLE);
|
return g_variant_type_copy (G_VARIANT_TYPE_DOUBLE);
|
||||||
case 's':
|
case 's':
|
||||||
@@ -451,6 +453,8 @@ describe_type (const GVariantType *type)
|
|||||||
result = g_strdup ("t");
|
result = g_strdup ("t");
|
||||||
else if (g_variant_type_equal (type, G_VARIANT_TYPE_HANDLE))
|
else if (g_variant_type_equal (type, G_VARIANT_TYPE_HANDLE))
|
||||||
result = g_strdup ("h");
|
result = g_strdup ("h");
|
||||||
|
else if (g_variant_type_equal (type, G_VARIANT_TYPE_FLOAT))
|
||||||
|
result = g_strdup ("f");
|
||||||
else if (g_variant_type_equal (type, G_VARIANT_TYPE_DOUBLE))
|
else if (g_variant_type_equal (type, G_VARIANT_TYPE_DOUBLE))
|
||||||
result = g_strdup ("d");
|
result = g_strdup ("d");
|
||||||
else if (g_variant_type_equal (type, G_VARIANT_TYPE_STRING))
|
else if (g_variant_type_equal (type, G_VARIANT_TYPE_STRING))
|
||||||
@@ -754,6 +758,7 @@ calculate_type_info (const GVariantType *type,
|
|||||||
|
|
||||||
else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT32) ||
|
else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT32) ||
|
||||||
g_variant_type_equal (type, G_VARIANT_TYPE_UINT32) ||
|
g_variant_type_equal (type, G_VARIANT_TYPE_UINT32) ||
|
||||||
|
g_variant_type_equal (type, G_VARIANT_TYPE_FLOAT) ||
|
||||||
g_variant_type_equal (type, G_VARIANT_TYPE_HANDLE))
|
g_variant_type_equal (type, G_VARIANT_TYPE_HANDLE))
|
||||||
{
|
{
|
||||||
al = fs = 4;
|
al = fs = 4;
|
||||||
@@ -1885,6 +1890,7 @@ struct _TreeInstance
|
|||||||
|
|
||||||
union {
|
union {
|
||||||
guint64 integer;
|
guint64 integer;
|
||||||
|
gfloat single;
|
||||||
gdouble floating;
|
gdouble floating;
|
||||||
gchar string[200];
|
gchar string[200];
|
||||||
} data;
|
} data;
|
||||||
@@ -1999,6 +2005,11 @@ tree_instance_new (const GVariantType *type,
|
|||||||
instance->data_size = 8;
|
instance->data_size = 8;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'f':
|
||||||
|
instance->data.single = g_test_rand_double ();
|
||||||
|
instance->data_size = 4;
|
||||||
|
break;
|
||||||
|
|
||||||
case 'd':
|
case 'd':
|
||||||
instance->data.floating = g_test_rand_double ();
|
instance->data.floating = g_test_rand_double ();
|
||||||
instance->data_size = 8;
|
instance->data_size = 8;
|
||||||
@@ -2437,6 +2448,10 @@ tree_instance_get_gvariant (TreeInstance *tree)
|
|||||||
result = g_variant_new_handle (tree->data.integer);
|
result = g_variant_new_handle (tree->data.integer);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'f':
|
||||||
|
result = g_variant_new_float (tree->data.single);
|
||||||
|
break;
|
||||||
|
|
||||||
case 'd':
|
case 'd':
|
||||||
result = g_variant_new_double (tree->data.floating);
|
result = g_variant_new_double (tree->data.floating);
|
||||||
break;
|
break;
|
||||||
@@ -2577,6 +2592,13 @@ tree_instance_check_gvariant (TreeInstance *tree,
|
|||||||
case 'h':
|
case 'h':
|
||||||
return g_variant_get_handle (value) == (gint32) tree->data.integer;
|
return g_variant_get_handle (value) == (gint32) tree->data.integer;
|
||||||
|
|
||||||
|
case 'f':
|
||||||
|
{
|
||||||
|
gfloat floating = g_variant_get_float (value);
|
||||||
|
|
||||||
|
return memcmp (&floating, &tree->data.single, sizeof floating) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
case 'd':
|
case 'd':
|
||||||
{
|
{
|
||||||
gdouble floating = g_variant_get_double (value);
|
gdouble floating = g_variant_get_double (value);
|
||||||
@@ -3664,6 +3686,7 @@ test_gv_byteswap (void)
|
|||||||
static void
|
static void
|
||||||
test_parser (void)
|
test_parser (void)
|
||||||
{
|
{
|
||||||
|
GError *error = NULL;
|
||||||
TreeInstance *tree;
|
TreeInstance *tree;
|
||||||
GVariant *parsed;
|
GVariant *parsed;
|
||||||
GVariant *value;
|
GVariant *value;
|
||||||
@@ -3677,15 +3700,18 @@ test_parser (void)
|
|||||||
pt = g_variant_print (value, TRUE);
|
pt = g_variant_print (value, TRUE);
|
||||||
p = g_variant_print (value, FALSE);
|
p = g_variant_print (value, FALSE);
|
||||||
|
|
||||||
parsed = g_variant_parse (NULL, pt, NULL, NULL, NULL);
|
parsed = g_variant_parse (NULL, pt, NULL, NULL, &error);
|
||||||
|
g_assert_no_error (error);
|
||||||
res = g_variant_print (parsed, FALSE);
|
res = g_variant_print (parsed, FALSE);
|
||||||
|
if (!strstr (pt, "float")) /* FIXME: need reliable round-trip for floats */
|
||||||
g_assert_cmpstr (p, ==, res);
|
g_assert_cmpstr (p, ==, res);
|
||||||
g_variant_unref (parsed);
|
g_variant_unref (parsed);
|
||||||
g_free (res);
|
g_free (res);
|
||||||
|
|
||||||
parsed = g_variant_parse (g_variant_get_type (value), p,
|
parsed = g_variant_parse (g_variant_get_type (value), p, NULL, NULL, &error);
|
||||||
NULL, NULL, NULL);
|
g_assert_no_error (error);
|
||||||
res = g_variant_print (parsed, TRUE);
|
res = g_variant_print (parsed, TRUE);
|
||||||
|
if (!strstr (pt, "float")) /* FIXME: need reliable round-trip for floats */
|
||||||
g_assert_cmpstr (pt, ==, res);
|
g_assert_cmpstr (pt, ==, res);
|
||||||
g_variant_unref (parsed);
|
g_variant_unref (parsed);
|
||||||
g_free (res);
|
g_free (res);
|
||||||
|
Reference in New Issue
Block a user