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>int64</literal>,
|
||||
<literal>uint64</literal>,
|
||||
<literal>float</literal>,
|
||||
<literal>double</literal>,
|
||||
<literal>string</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.
|
||||
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>int64</literal>, <literal>uint64</literal>, <literal>double</literal>, <literal>string</literal>,
|
||||
<literal>objectpath</literal> and literal <literal>signature</literal> are each exactly equivalent to their
|
||||
corresponding type code.
|
||||
<literal>int64</literal>, <literal>uint64</literal>, <literal>float</literal>, <literal>double</literal>,
|
||||
<literal>string</literal>, <literal>objectpath</literal> and literal <literal>signature</literal> are each
|
||||
exactly equivalent to their corresponding type code.
|
||||
</para>
|
||||
<para>
|
||||
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)++;
|
||||
}
|
||||
|
||||
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)++;
|
||||
(*one)++;
|
||||
@@ -616,6 +622,10 @@ ast_resolve (AST *ast,
|
||||
pattern[j++] = 'i';
|
||||
break;
|
||||
|
||||
case 'D':
|
||||
pattern[j++] = 'd';
|
||||
break;
|
||||
|
||||
default:
|
||||
pattern[j++] = pattern[i];
|
||||
break;
|
||||
@@ -1246,7 +1256,7 @@ dictionary_get_pattern (AST *ast,
|
||||
/* the basic types,
|
||||
* plus undetermined number type and undetermined string type.
|
||||
*/
|
||||
if (!strchr ("bynqiuxthdsogNS", key_char))
|
||||
if (!strchr ("bynqiuxthfdsogNDS", key_char))
|
||||
{
|
||||
ast_set_error (ast, error, NULL,
|
||||
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')) ||
|
||||
strstr (number->token, "inf") ||
|
||||
strstr (number->token, "nan"))
|
||||
return g_strdup ("Md");
|
||||
return g_strdup ("MD");
|
||||
|
||||
return g_strdup ("MN");
|
||||
}
|
||||
@@ -1817,17 +1827,16 @@ number_get_value (AST *ast,
|
||||
Number *number = (Number *) ast;
|
||||
const gchar *token;
|
||||
gboolean negative;
|
||||
gboolean floating;
|
||||
guint64 abs_val;
|
||||
gdouble dbl_val;
|
||||
gchar typechar;
|
||||
gchar *end;
|
||||
|
||||
typechar = *g_variant_type_peek_string (type);
|
||||
token = number->token;
|
||||
|
||||
if (g_variant_type_equal (type, G_VARIANT_TYPE_DOUBLE))
|
||||
if (typechar == 'f' || typechar == 'd')
|
||||
{
|
||||
floating = TRUE;
|
||||
|
||||
errno = 0;
|
||||
dbl_val = g_ascii_strtod (token, &end);
|
||||
if (dbl_val != 0.0 && errno == ERANGE)
|
||||
@@ -1844,7 +1853,6 @@ number_get_value (AST *ast,
|
||||
}
|
||||
else
|
||||
{
|
||||
floating = FALSE;
|
||||
negative = token[0] == '-';
|
||||
if (token[0] == '-')
|
||||
token++;
|
||||
@@ -1880,10 +1888,7 @@ number_get_value (AST *ast,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (floating)
|
||||
return g_variant_new_double (dbl_val);
|
||||
|
||||
switch (*g_variant_type_peek_string (type))
|
||||
switch (typechar)
|
||||
{
|
||||
case 'y':
|
||||
if (negative || abs_val > G_MAXUINT8)
|
||||
@@ -1925,6 +1930,12 @@ number_get_value (AST *ast,
|
||||
return number_overflow (ast, type, error);
|
||||
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:
|
||||
return ast_type_error (ast, type, error);
|
||||
}
|
||||
@@ -2210,6 +2221,9 @@ typedecl_parse (TokenStream *stream,
|
||||
else if (token_stream_consume (stream, "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"))
|
||||
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.
|
||||
*
|
||||
* 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.
|
||||
@@ -342,7 +342,7 @@ g_variant_get_boolean (GVariant *value)
|
||||
}
|
||||
|
||||
/* 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) \
|
||||
@@ -566,6 +566,31 @@ NUMERIC_TYPE (UINT64, uint64, guint64)
|
||||
**/
|
||||
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
|
||||
@@ -1081,6 +1106,7 @@ g_variant_lookup_value (GVariant *dictionary,
|
||||
* - %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,
|
||||
@@ -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_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.
|
||||
@@ -2516,6 +2544,32 @@ g_variant_print_string (GVariant *value,
|
||||
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];
|
||||
@@ -2640,6 +2694,7 @@ g_variant_hash (gconstpointer value_)
|
||||
case G_VARIANT_CLASS_INT32:
|
||||
case G_VARIANT_CLASS_UINT32:
|
||||
case G_VARIANT_CLASS_HANDLE:
|
||||
case G_VARIANT_CLASS_FLOAT:
|
||||
{
|
||||
const guint *ptr;
|
||||
|
||||
@@ -2759,7 +2814,7 @@ g_variant_equal (gconstpointer one,
|
||||
* 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
|
||||
@@ -2830,6 +2885,14 @@ g_variant_compare (gconstpointer one,
|
||||
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);
|
||||
@@ -4165,8 +4228,8 @@ g_variant_format_string_scan (const gchar *string,
|
||||
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':
|
||||
@@ -4829,6 +4892,7 @@ g_variant_valist_skip_leaf (const gchar **str,
|
||||
va_arg (*app, guint64);
|
||||
return;
|
||||
|
||||
case 'f':
|
||||
case 'd':
|
||||
va_arg (*app, gdouble);
|
||||
return;
|
||||
@@ -4874,6 +4938,9 @@ g_variant_valist_new_leaf (const gchar **str,
|
||||
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));
|
||||
|
||||
@@ -4884,6 +4951,7 @@ g_variant_valist_new_leaf (const gchar **str,
|
||||
|
||||
/* 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
|
||||
@@ -4957,6 +5025,10 @@ g_variant_valist_get_leaf (const gchar **str,
|
||||
*(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;
|
||||
@@ -4979,6 +5051,7 @@ g_variant_valist_get_leaf (const gchar **str,
|
||||
case 'u':
|
||||
case 'h':
|
||||
case 'b':
|
||||
case 'f':
|
||||
*(guint32 *) ptr = 0;
|
||||
return;
|
||||
|
||||
@@ -5698,6 +5771,9 @@ g_variant_deep_copy (GVariant *value)
|
||||
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));
|
||||
|
||||
@@ -5760,8 +5836,7 @@ g_variant_get_normal_form (GVariant *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,
|
||||
|
@@ -44,6 +44,7 @@ typedef enum
|
||||
G_VARIANT_CLASS_INT64 = 'x',
|
||||
G_VARIANT_CLASS_UINT64 = 't',
|
||||
G_VARIANT_CLASS_HANDLE = 'h',
|
||||
G_VARIANT_CLASS_FLOAT = 'f',
|
||||
G_VARIANT_CLASS_DOUBLE = 'd',
|
||||
G_VARIANT_CLASS_STRING = 's',
|
||||
G_VARIANT_CLASS_OBJECT_PATH = 'o',
|
||||
@@ -95,6 +96,8 @@ GLIB_AVAILABLE_IN_ALL
|
||||
GVariant * g_variant_new_uint64 (guint64 value);
|
||||
GLIB_AVAILABLE_IN_ALL
|
||||
GVariant * g_variant_new_handle (gint32 value);
|
||||
GLIB_AVAILABLE_IN_2_44
|
||||
GVariant * g_variant_new_float (gfloat value);
|
||||
GLIB_AVAILABLE_IN_ALL
|
||||
GVariant * g_variant_new_double (gdouble value);
|
||||
GLIB_AVAILABLE_IN_ALL
|
||||
@@ -148,6 +151,8 @@ GLIB_AVAILABLE_IN_ALL
|
||||
guint64 g_variant_get_uint64 (GVariant *value);
|
||||
GLIB_AVAILABLE_IN_ALL
|
||||
gint32 g_variant_get_handle (GVariant *value);
|
||||
GLIB_AVAILABLE_IN_2_44
|
||||
gfloat g_variant_get_float (GVariant *value);
|
||||
GLIB_AVAILABLE_IN_ALL
|
||||
gdouble g_variant_get_double (GVariant *value);
|
||||
GLIB_AVAILABLE_IN_ALL
|
||||
|
@@ -110,7 +110,7 @@
|
||||
* A basic type string describes a basic type (as per
|
||||
* 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",
|
||||
* "h", "d", "s", "o", "g" and "?".
|
||||
* "h", "f", "d", "s", "o", "g" and "?".
|
||||
*
|
||||
* The above definition is recursive to arbitrary depth. "aaaaai" and
|
||||
* "(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
|
||||
* that, by convention, is used as an index into an array of file
|
||||
* 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
|
||||
* floating point value.
|
||||
* - `s`: the type string of %G_VARIANT_TYPE_STRING; a string.
|
||||
@@ -240,7 +242,7 @@ g_variant_type_string_scan (const gchar *string,
|
||||
|
||||
case '{':
|
||||
if (string == limit || *string == '\0' || /* { */
|
||||
!strchr ("bynqihuxtdsog?", *string++) || /* key */
|
||||
!strchr ("bynqihuxtfdsog?", *string++) || /* key */
|
||||
!g_variant_type_string_scan (string, limit, &string) || /* value */
|
||||
string == limit || *string++ != '}') /* } */
|
||||
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 '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;
|
||||
|
||||
default:
|
||||
@@ -533,8 +535,8 @@ g_variant_type_is_container (const GVariantType *type)
|
||||
*
|
||||
* Determines if the given @type is a basic type.
|
||||
*
|
||||
* Basic types are booleans, bytes, integers, doubles, strings, object
|
||||
* paths and signatures.
|
||||
* Basic types are booleans, bytes, integers, floats, doubles, strings,
|
||||
* object paths and signatures.
|
||||
*
|
||||
* 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 't':
|
||||
case 'x':
|
||||
case 'f':
|
||||
case 'd':
|
||||
case 's':
|
||||
case 'o':
|
||||
|
@@ -103,6 +103,15 @@ typedef struct _GVariantType GVariantType;
|
||||
**/
|
||||
#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:
|
||||
*
|
||||
|
@@ -115,7 +115,7 @@ static const GVariantTypeInfo g_variant_type_info_basic_table[24] = {
|
||||
/* 'c' */ { not_a_type },
|
||||
/* 'd' */ { fixed_aligned(8) }, /* double */
|
||||
/* 'e' */ { not_a_type },
|
||||
/* 'f' */ { not_a_type },
|
||||
/* 'f' */ { fixed_aligned(4) }, /* float */
|
||||
/* 'g' */ { unaligned }, /* signature string */
|
||||
/* 'h' */ { fixed_aligned(4) }, /* file handle (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.
|
||||
*/
|
||||
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"
|
||||
};
|
||||
|
||||
|
@@ -19,10 +19,10 @@
|
||||
#include <stdlib.h>
|
||||
#include <glib.h>
|
||||
|
||||
#define BASIC "bynqiuxthdsog?"
|
||||
#define BASIC "bynqiuxthfdsog?"
|
||||
#define N_BASIC (G_N_ELEMENTS (BASIC) - 1)
|
||||
|
||||
#define INVALIDS "cefjklpwz&@^$"
|
||||
#define INVALIDS "cejklpwz&@^$"
|
||||
#define N_INVALIDS (G_N_ELEMENTS (INVALIDS) - 1)
|
||||
|
||||
/* 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);
|
||||
case 'h':
|
||||
return g_variant_type_copy (G_VARIANT_TYPE_HANDLE);
|
||||
case 'f':
|
||||
return g_variant_type_copy (G_VARIANT_TYPE_FLOAT);
|
||||
case 'd':
|
||||
return g_variant_type_copy (G_VARIANT_TYPE_DOUBLE);
|
||||
case 's':
|
||||
@@ -451,6 +453,8 @@ describe_type (const GVariantType *type)
|
||||
result = g_strdup ("t");
|
||||
else if (g_variant_type_equal (type, G_VARIANT_TYPE_HANDLE))
|
||||
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))
|
||||
result = g_strdup ("d");
|
||||
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) ||
|
||||
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))
|
||||
{
|
||||
al = fs = 4;
|
||||
@@ -1885,6 +1890,7 @@ struct _TreeInstance
|
||||
|
||||
union {
|
||||
guint64 integer;
|
||||
gfloat single;
|
||||
gdouble floating;
|
||||
gchar string[200];
|
||||
} data;
|
||||
@@ -1999,6 +2005,11 @@ tree_instance_new (const GVariantType *type,
|
||||
instance->data_size = 8;
|
||||
break;
|
||||
|
||||
case 'f':
|
||||
instance->data.single = g_test_rand_double ();
|
||||
instance->data_size = 4;
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
instance->data.floating = g_test_rand_double ();
|
||||
instance->data_size = 8;
|
||||
@@ -2437,6 +2448,10 @@ tree_instance_get_gvariant (TreeInstance *tree)
|
||||
result = g_variant_new_handle (tree->data.integer);
|
||||
break;
|
||||
|
||||
case 'f':
|
||||
result = g_variant_new_float (tree->data.single);
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
result = g_variant_new_double (tree->data.floating);
|
||||
break;
|
||||
@@ -2577,6 +2592,13 @@ tree_instance_check_gvariant (TreeInstance *tree,
|
||||
case 'h':
|
||||
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':
|
||||
{
|
||||
gdouble floating = g_variant_get_double (value);
|
||||
@@ -3664,6 +3686,7 @@ test_gv_byteswap (void)
|
||||
static void
|
||||
test_parser (void)
|
||||
{
|
||||
GError *error = NULL;
|
||||
TreeInstance *tree;
|
||||
GVariant *parsed;
|
||||
GVariant *value;
|
||||
@@ -3677,15 +3700,18 @@ test_parser (void)
|
||||
pt = g_variant_print (value, TRUE);
|
||||
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);
|
||||
if (!strstr (pt, "float")) /* FIXME: need reliable round-trip for floats */
|
||||
g_assert_cmpstr (p, ==, res);
|
||||
g_variant_unref (parsed);
|
||||
g_free (res);
|
||||
|
||||
parsed = g_variant_parse (g_variant_get_type (value), p,
|
||||
NULL, NULL, NULL);
|
||||
parsed = g_variant_parse (g_variant_get_type (value), p, NULL, NULL, &error);
|
||||
g_assert_no_error (error);
|
||||
res = g_variant_print (parsed, TRUE);
|
||||
if (!strstr (pt, "float")) /* FIXME: need reliable round-trip for floats */
|
||||
g_assert_cmpstr (pt, ==, res);
|
||||
g_variant_unref (parsed);
|
||||
g_free (res);
|
||||
|
Reference in New Issue
Block a user